Cac*_*tus 4 assembly jit 6502 commodore
我发现PET的零页内存映射声称零页面地址范围$00C2..$00D9用于静态数据,例如http://www.classiccmp.org/dunfield/pet/petmem.txt说:
RIDATA 00C2 Cassette Temp (64#00AA) read flags: 0=scan,
1-15=count, $40=load, $80=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, $00 = 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
Run Code Online (Sandbox Code Playgroud)
但是,查看ROM反汇编,可以找到$00C2跳转地址的地方,例如http://www.zimmers.net/anonftp/pub/cbm/firmware/computers/pet/d/rom-1.html# C70A:
C70A 4C C2 00 JMP iC2
Run Code Online (Sandbox Code Playgroud)
看一下$00C2在启动PET之后开始的反汇编,我可以看到合理的代码:
.C:00c2 E6 C9 INC $C9
.C:00c4 D0 02 BNE $00C8
.C:00c6 E6 CA INC $CA
.C:00c8 AD 00 04 LDA $0400
.C:00cb C9 3A CMP #$3A
.C:00cd B0 0A BCS $00D9
.C:00cf C9 20 CMP #$20
.C:00d1 F0 EF BEQ $00C2
.C:00d3 38 SEC
.C:00d4 E9 30 SBC #$30
.C:00d6 38 SEC
.C:00d7 E9 D0 SBC #$D0
.C:00d9 60 RTS
Run Code Online (Sandbox Code Playgroud)
这个区域用的是什么?将此程序组装到此区域的代码在哪里?这段代码应该做什么?(这似乎是扫描开始在该地区$0400进行:和字符?)
它是BASIC解释器循环的一部分.它读取标记化BASIC程序的一个字节,如果是冒号或零字节则设置零标志,如果是数字则清除进位.您可以在地址C6B5的解释器循环的主要部分中看到它.
我不确定为什么这个例程被置于零页面.这是一个周期(或很少二)更快地使用LDA $0400过LDA ($C9),Y,但我不能看到它实际上做太大的区别.
我还应该注意,您正在查看的ROM反汇编似乎是针对BASIC 1.0 ROM,而您引用的内存映射是针对版本2.0和4.0.
以下是Sheldon Leemon 对Commodore 64的映射说的等效C64例程:
115-138 $ 73- $ 8A CHRGET
子程序:获取下一个BASIC文本字符...
CHRGET是BASIC用于读取文本字符的关键例程,例如正在解释的BASIC程序的文本.它被放置在零页面上以使例程运行得更快.由于它跟踪例程本身内正在读取的字符的地址,因此例程必须在RAM中才能更新该指针.指向当前正在读取的字节地址的指针实际上是LDA指令的操作数.当从CHRGET进入时,例程通过修改TXTPTR(122,$ 7A)处的操作数来递增指针,从而允许读取下一个字符.
在CHRGOT(121,$ 79)输入允许再次读取当前字符.CHRGET例程跳过空格,设置各种标志或状态寄存器(.P)以指示读取的字符是数字,语句终止符还是其他类型的字符,并在累加器(.A)中返回检索到的字符.
...
由于这是一个中心例程,下面给出了一个反汇编列表,以便更好地理解它的工作原理.
Run Code Online (Sandbox Code Playgroud)115 $73 CHRGET INC TXTPTR ; increment low byte of TXTPTR 117 $75 BNE CHRGOT ; if low byte isn't 0, skip next 119 $77 INC TXTPTR+1 ; increment high byte of TXTPTR 121 $79 CHRGOT LDA ; load byte from where TXTPTR points ; entry here does not update TXTPTR, ; allowing you to readl the old byte again 122 $7A TXTPTR $0207 ; pointer is really the LDA operand ; TXTPTR+1 points to 512-580 ($200-$250) ; when reading from the input buffer ; in direct mode 124 $7C POINTB CMP #$3A ; carry flag set if > ASCII numeral 9 126 $7E BCS EXIT ; character is not a numeral--exit 128 $80 CMP #$20 ; if it is an ASCII space... 130 $82 BEQ CHRGET ; ignore it and get next character 132 $84 SEC ; prepare to subtract 133 $85 SBC #$30 ; ASCII 0-9 are between 48-57 ($30-$39) 135 $87 SEC ; prepare to subtract again 136 $88 SBC #$D0 ; if < ASCII 0 (57, $39) then carry is set 138 $8A EXIT RTS ; carry is clear only for numeral on return累加器(.A寄存器)保存从例程退出时读取的字符.可以在退出时测试的状态寄存器(.P)位是:
如果字符是ASCII数字0-9,则进位清除.否则,携带套装.零设置仅在字符是语句终止符0或ASCII冒号58($ 3A)时设置.否则,清零.
| 归档时间: |
|
| 查看次数: |
626 次 |
| 最近记录: |