Commodore PET BASIC assemble starting from $00C2 是什么?
What does the Commodore PET BASIC assemble starting from $00C2?
我发现的 PET 零页内存映射声称零页地址范围[=14=]C2..[=14=]D9
用于静态数据,例如http://www.classiccmp.org/dunfield/pet/petmem.txt 说:
RIDATA 00C2 Cassette Temp (64#00AA) read flags: 0=scan,
1-15=count, =load, =end of tape marker
RIPRTY 00C3 Cassette Short Cnt (64#00AB): counter of seconds
before tape write / checksum
PNT 00C4-00C5 Pointer: Current Screen Line Address
PNTR 00C6 Cursor Column on Current Line
SAL 00C7-00C8 Pointer: Tape Buffer/ Screen Scrolling
EAL 00C9-00CA Tape End Addresses/End of Program
CMP0 00CB-00CC Tape Timing Constants
QTSW 00CD Flag: Editor in Quote Mode, [=11=] = NO
BITTS 00CE Cassette Temp (64#00B4): Tape read timer flag
=IRQ enabled for Timer 1
00CF End of tape read
00D0 Read character error
FNLEN 00D1 Length of Current File Name
LA 00D2 Current Logical File Number
SA 00D3 Current Secondary Address
FA 00D4 Current Device Number
LNMX 00D5 Physical Screen Line Length
00D5 4.80: right side of window
TAPE1 00D6-00D7 Pointer: Start of Tape Buffer
TBLX 00D8 Current Cursor Physical Line Number
DATAX 00D9 Current Character to Print
然而,查看ROM反汇编,可以找到地址[=15=]C2
被跳转到的地方,例如http://www.zimmers.net/anonftp/pub/cbm/firmware/computers/pet/d/rom-1.html#C70A :
C70A 4C C2 00 JMP iC2
在启动 PET 后查看从 [=15=]C2
开始的反汇编,我可以看到看起来合理的代码:
.C:00c2 E6 C9 INC $C9
.C:00c4 D0 02 BNE [=13=]C8
.C:00c6 E6 CA INC $CA
.C:00c8 AD 00 04 LDA 00
.C:00cb C9 3A CMP #A
.C:00cd B0 0A BCS [=13=]D9
.C:00cf C9 20 CMP #
.C:00d1 F0 EF BEQ [=13=]C2
.C:00d3 38 SEC
.C:00d4 E9 30 SBC #
.C:00d6 38 SEC
.C:00d7 E9 D0 SBC #$D0
.C:00d9 60 RTS
这个区域是做什么用的?将这个程序组装到这个区域的代码在哪里?这段代码应该做什么? (好像是在00
开始的区域扫描:
和
个字符?)
它是自修改代码,请注意 $C9
处的嵌入指针。它的源代码位于 $E0B4
,并通过 $E0E5
.
的代码复制到零页
看来确实是扫描文本,对当前字符进行分类。如果字符是space,它将设置ZF
,如果是数字,CF
将被清除。因此它似乎对将字符串转换为数字很有用,但这只是一个猜测。
更新:使用此代码的示例例程位于 $C863
。它肯定在做一些字符串到数字的转换,你可以识别循环计算 result = result * 10 + (current_char - '0')
的模式。
它是 BASIC 解释器循环的一部分。它读取标记化 BASIC 程序的一个字节,如果它是冒号或零字节则设置零标志,如果它是数字则清除进位。您可以在 address C6B5.
的解释器循环的主要部分中看到它的使用
我不确定为什么将此例程放在零页中。使用 LDA 00
比 LDA ($C9),Y
快一个(或很少两个)循环,但我看不出它实际上有多大区别。
我还应该注意到,您正在查看的 ROM 反汇编似乎是针对 BASIC 1.0 ROM,而您引用的内存映射是针对版本 2.0 和 4.0。
以下是 Sheldon Leemon Mapping the Commodore 64 对等效 C64 例程的描述:
115-138 -A CHRGET
Subroutine: Get Next BASIC Text Character
...
CHRGET is a crucial routine which BASIC uses to read text characters,
such as the text of the BASIC program which is being interpreted. It
is placed on zero page to make the routine run faster. Since it keeps
track of the address of the character being read within the routine
itself, the routine must be in RAM in order to update that pointer.
The pointer to the address of the byte currently being read is really
the operand of a LDA instruction. When entered from CHRGET, the
routine increments the pointer by modifying the operand at TXTPTR
(122, A), thus allowing the next character to be read.
Entry at CHRGOT (121, ) allows the current character to be read
again. The CHRGET routine skips spaces, sets the various flags or the
status register (.P) to indicate whether the character read was a
digit, statement terminator, or other type of character, and returns
with the retrieved character in the Accumulator (.A).
...
As this is such a central routine, a disassembly listing is given
below to provide a better understanding of how it works.
115 CHRGET INC TXTPTR ; increment low byte of TXTPTR
117 BNE CHRGOT ; if low byte isn't 0, skip next
119 INC TXTPTR+1 ; increment high byte of TXTPTR
121 CHRGOT LDA ; load byte from where TXTPTR points
; entry here does not update TXTPTR,
; allowing you to readl the old byte again
122 A TXTPTR 07 ; pointer is really the LDA operand
; TXTPTR+1 points to 512-580 (0-0)
; when reading from the input buffer
; in direct mode
124 C POINTB CMP #A ; carry flag set if > ASCII numeral 9
126 E BCS EXIT ; character is not a numeral--exit
128 CMP # ; if it is an ASCII space...
130 BEQ CHRGET ; ignore it and get next character
132 SEC ; prepare to subtract
133 SBC # ; ASCII 0-9 are between 48-57 (-)
135 SEC ; prepare to subtract again
136 SBC #$D0 ; if < ASCII 0 (57, ) then carry is set
138 A EXIT RTS ; carry is clear only for numeral on return
The Accumulator (.A register) holds the character that was read on
exit from the routine. Status register (.P) bits which can be tested
for on exit are:
Carry Clear if the character was an ASCII digit 0-9. Carry Set,
otherwise. Zero Set only if the character was a statement terminator
0 or an ASCII colon, 58 (A). Otherwise, Zero Clear.
我发现的 PET 零页内存映射声称零页地址范围[=14=]C2..[=14=]D9
用于静态数据,例如http://www.classiccmp.org/dunfield/pet/petmem.txt 说:
RIDATA 00C2 Cassette Temp (64#00AA) read flags: 0=scan,
1-15=count, =load, =end of tape marker
RIPRTY 00C3 Cassette Short Cnt (64#00AB): counter of seconds
before tape write / checksum
PNT 00C4-00C5 Pointer: Current Screen Line Address
PNTR 00C6 Cursor Column on Current Line
SAL 00C7-00C8 Pointer: Tape Buffer/ Screen Scrolling
EAL 00C9-00CA Tape End Addresses/End of Program
CMP0 00CB-00CC Tape Timing Constants
QTSW 00CD Flag: Editor in Quote Mode, [=11=] = NO
BITTS 00CE Cassette Temp (64#00B4): Tape read timer flag
=IRQ enabled for Timer 1
00CF End of tape read
00D0 Read character error
FNLEN 00D1 Length of Current File Name
LA 00D2 Current Logical File Number
SA 00D3 Current Secondary Address
FA 00D4 Current Device Number
LNMX 00D5 Physical Screen Line Length
00D5 4.80: right side of window
TAPE1 00D6-00D7 Pointer: Start of Tape Buffer
TBLX 00D8 Current Cursor Physical Line Number
DATAX 00D9 Current Character to Print
然而,查看ROM反汇编,可以找到地址[=15=]C2
被跳转到的地方,例如http://www.zimmers.net/anonftp/pub/cbm/firmware/computers/pet/d/rom-1.html#C70A :
C70A 4C C2 00 JMP iC2
在启动 PET 后查看从 [=15=]C2
开始的反汇编,我可以看到看起来合理的代码:
.C:00c2 E6 C9 INC $C9
.C:00c4 D0 02 BNE [=13=]C8
.C:00c6 E6 CA INC $CA
.C:00c8 AD 00 04 LDA 00
.C:00cb C9 3A CMP #A
.C:00cd B0 0A BCS [=13=]D9
.C:00cf C9 20 CMP #
.C:00d1 F0 EF BEQ [=13=]C2
.C:00d3 38 SEC
.C:00d4 E9 30 SBC #
.C:00d6 38 SEC
.C:00d7 E9 D0 SBC #$D0
.C:00d9 60 RTS
这个区域是做什么用的?将这个程序组装到这个区域的代码在哪里?这段代码应该做什么? (好像是在00
开始的区域扫描:
和个字符?)
它是自修改代码,请注意 $C9
处的嵌入指针。它的源代码位于 $E0B4
,并通过 $E0E5
.
看来确实是扫描文本,对当前字符进行分类。如果字符是space,它将设置ZF
,如果是数字,CF
将被清除。因此它似乎对将字符串转换为数字很有用,但这只是一个猜测。
更新:使用此代码的示例例程位于 $C863
。它肯定在做一些字符串到数字的转换,你可以识别循环计算 result = result * 10 + (current_char - '0')
的模式。
它是 BASIC 解释器循环的一部分。它读取标记化 BASIC 程序的一个字节,如果它是冒号或零字节则设置零标志,如果它是数字则清除进位。您可以在 address C6B5.
的解释器循环的主要部分中看到它的使用我不确定为什么将此例程放在零页中。使用 LDA 00
比 LDA ($C9),Y
快一个(或很少两个)循环,但我看不出它实际上有多大区别。
我还应该注意到,您正在查看的 ROM 反汇编似乎是针对 BASIC 1.0 ROM,而您引用的内存映射是针对版本 2.0 和 4.0。
以下是 Sheldon Leemon Mapping the Commodore 64 对等效 C64 例程的描述:
115-138 -A CHRGET
Subroutine: Get Next BASIC Text Character...
CHRGET is a crucial routine which BASIC uses to read text characters, such as the text of the BASIC program which is being interpreted. It is placed on zero page to make the routine run faster. Since it keeps track of the address of the character being read within the routine itself, the routine must be in RAM in order to update that pointer. The pointer to the address of the byte currently being read is really the operand of a LDA instruction. When entered from CHRGET, the routine increments the pointer by modifying the operand at TXTPTR (122, A), thus allowing the next character to be read.
Entry at CHRGOT (121, ) allows the current character to be read again. The CHRGET routine skips spaces, sets the various flags or the status register (.P) to indicate whether the character read was a digit, statement terminator, or other type of character, and returns with the retrieved character in the Accumulator (.A).
...
As this is such a central routine, a disassembly listing is given below to provide a better understanding of how it works.
115 CHRGET INC TXTPTR ; increment low byte of TXTPTR 117 BNE CHRGOT ; if low byte isn't 0, skip next 119 INC TXTPTR+1 ; increment high byte of TXTPTR 121 CHRGOT LDA ; load byte from where TXTPTR points ; entry here does not update TXTPTR, ; allowing you to readl the old byte again 122 A TXTPTR 07 ; pointer is really the LDA operand ; TXTPTR+1 points to 512-580 (0-0) ; when reading from the input buffer ; in direct mode 124 C POINTB CMP #A ; carry flag set if > ASCII numeral 9 126 E BCS EXIT ; character is not a numeral--exit 128 CMP # ; if it is an ASCII space... 130 BEQ CHRGET ; ignore it and get next character 132 SEC ; prepare to subtract 133 SBC # ; ASCII 0-9 are between 48-57 (-) 135 SEC ; prepare to subtract again 136 SBC #$D0 ; if < ASCII 0 (57, ) then carry is set 138 A EXIT RTS ; carry is clear only for numeral on return
The Accumulator (.A register) holds the character that was read on exit from the routine. Status register (.P) bits which can be tested for on exit are:
Carry Clear if the character was an ASCII digit 0-9. Carry Set, otherwise. Zero Set only if the character was a statement terminator 0 or an ASCII colon, 58 (A). Otherwise, Zero Clear.