4

私が見つけた PET のゼロページ メモリ マップは、ゼロ ページ アドレス範囲$00C2..$00D9が静的データに使用されていると主張しています

 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

$00C2ただし、ROM の逆アセンブルを見ると、アドレスがジャンプする場所を見つけることができます。 C70A :

 C70A  4C C2 00             JMP iC2       

$00C2PET の起動後に始まる逆アセンブリを見ると、合理的なコードが表示されます。

.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

このエリアは何に使われていますか?このプログラムをこの領域にアセンブルするコードはどこにありますか? このコードは何をするためのものですか? $0400( for:と の文字から始まる領域をスキャンしているように見えますか?)

4

2 に答える 2

7

これは、BASIC インタープリター ループの一部です。トークン化された BASIC プログラムの 1 バイトを読み取り、コロンまたはゼロ バイトの場合はゼロ フラグを設定し、数値の場合はキャリーをクリアします。アドレス C6B5のインタプリタ ループの主要部分で使用されていることがわかります。

このルーチンがゼロ ページに配置された理由はわかりません。よりも 1 サイクル (またはまれに 2) 高速ですLDA $0400LDA ($C9),Y、実際に大きな違いがあるとは思えません。

また、参照しているメモリ マップはバージョン 2.0 および 4.0 用であるのに対し、参照している ROM 逆アセンブリは BASIC 1.0 ROM 用のように見えることにも注意してください。

Sheldon LeemonによるMapping the Commodore 64は、同等の C64 ルーチンについて次のように述べています。

115-138 $73-$8A CHRGET
サブルーチン: 次の BASIC テキスト文字の取得

...

CHRGET は、解釈されている BASIC プログラムのテキストなど、テキスト文字を読み取るために BASIC が使用する重要なルーチンです。ルーチンの実行を高速化するために、ゼロ ページに配置されます。ルーチン内で読み取られる文字のアドレスを追跡するため、ルーチンはそのポインタを更新するために RAM に存在する必要があります。現在読み取られているバイトのアドレスへのポインターは、実際には LDA 命令のオペランドです。CHRGET から入ると、ルーチンは TXTPTR (122, $7A) でオペランドを変更することによってポインターをインクリメントし、次の文字を読み取ることができるようにします。

CHRGOT (121, $79) に入力すると、現在の文字を再度読み取ることができます。CHRGET ルーチンは、スペースをスキップし、さまざまなフラグまたはステータス レジスタ (.P) を設定して、読み取った文字が数字、ステートメント ターミネータ、またはその他の種類の文字であったかどうかを示し、取得した文字をアキュムレータ (.A) に返します。 .

...

これは非常に中心的なルーチンであるため、どのように機能するかをよりよく理解できるように、逆アセンブリのリストを以下に示します。

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) の場合にのみ設定します。そうでなければ、ゼロクリア。

于 2015-08-07T14:41:14.837 に答える
4

これは自己変更コードです。 に埋め込まれたポインターに注意して$C9ください。そのソースは at$E0B4にあり、コード at によってゼロ ページにコピーされます$E0E5

実際にテキストをスキャンし、現在の文字を分類しているようです。ZF文字がスペースならセットCF、数字ならクリア。そのため、文字列を数値に変換するのに便利なようですが、それは単なる推測です。

更新: このコードを使用するルーチンの例は にあり$C863ます。文字列から数値への変換を行っていることは確かですresult = result * 10 + (current_char - '0')。ループで計算するパターンを認識することができます。

于 2015-08-07T14:02:04.057 に答える