A0 01 84 97 88 84 9E 84 9F B1 FB F0 20 A4 9F 91 FD C6 97 D0 10 A6 FF CA F0
05 C8 91 FD D0 F8 84 9F A5 FF 85 97 E6 9E A4 9E E6 9F D0 DC A4 9F 91 FD 60
これは位置に依存しないサブルーチンで、$fb
/ の入力文字列(0で終わるC文字列)$fc
へのポインタ、$fd
/ の出力バッファへのポインタ、$fe
およびのcount(n
)を必要とし$ff
ます。単純なインデックスを使用するため、8ビットアーキテクチャにより、最大出力長が255文字(+ 0バイト)に制限されています。
説明(コメント付きの分解):
.rep:
A0 01 LDY #$01 ; init counter to next repetition sequence
84 97 STY $97
88 DEY ; init read and write index
84 9E STY $9E ; (read)
84 9F STY $9F ; (write)
.rep_loop:
B1 FB LDA ($FB),Y ; read next character
F0 20 BEQ .rep_done ; 0 -> finished
A4 9F LDY $9F ; load write index
91 FD STA ($FD),Y ; write next character
C6 97 DEC $97 ; decrement counter to nex rep. seq.
D0 10 BNE .rep_next ; not reached yet -> next iteration
A6 FF LDX $FF ; load repetition counter
.rep_seqloop:
CA DEX ; and decrement
F0 05 BEQ .rep_seqdone ; if 0, no more repetitions
C8 INY ; increment write index
91 FD STA ($FD),Y ; write character
D0 F8 BNE .rep_seqloop ; and repeat for this sequence
.rep_seqdone:
84 9F STY $9F ; store back write index
A5 FF LDA $FF ; re-init counter to next ...
85 97 STA $97 ; ... repetition sequence
.rep_next:
E6 9E INC $9E ; increment read index
A4 9E LDY $9E ; load read index
E6 9F INC $9F ; increment write index
D0 DC BNE .rep_loop ; jump back (main loop)
.rep_done:
A4 9F LDY $9F ; load write index
91 FD STA ($FD),Y ; and write terminating0-byte there
60 RTS ; done.
それを使用したC64マシンコードプログラムの例:
これは、このルーチンを使用したC64用のca65スタイルのアセンブラーのプログラムです(としてインポートされますrep
)。
REP_IN = $fb
REP_IN_L = $fb
REP_IN_H = $fc
REP_OUT = $fd
REP_OUT_L = $fd
REP_OUT_H = $fe
REP_N = $ff
.import rep
.segment "LDADDR"
.word $c000
.code
jsr $aefd ; consume comma
jsr $ad9e ; evaluate expression
sta REP_IN_L ; store string length
jsr $b6a3 ; free string
ldy #$00 ; loop over string
readloop: cpy REP_IN_L ; end of string?
beq termstr ; then jump to 0-terminate string
lda ($22),y ; read next character
sta in,y ; store in input buffer
iny ; next
bne readloop
termstr: lda #$00 ; load 0 byte
sta in,y ; store in input buffer
jsr $b79b ; read 8bit unsigned int
stx REP_N ; store in `n`
lda #<in ; (
sta REP_IN_L ; store pointer to
lda #>in ; to input string
sta REP_IN_H ; )
lda #<out ; (
sta REP_OUT_L ; store pointer to
lda #>out ; output buffer
sta REP_OUT_H ; )
jsr rep ; call function
ldy #$00 ; output result
outloop: lda out,y
beq done
jsr $ffd2
iny
bne outloop
done: rts
.bss
in: .res $100
out: .res $100
オンラインデモ
使用法: sys49152,"[s]",[n]
、例えばsys49152,"Hello, World!",3
重要:プログラムがディスクからロードされた場合(オンラインデモのように)、new
最初にコマンドを発行してください!これは、マシンプログラムをロードするとC64 BASICポインターが一部破壊されるために必要です。
s
を文字配列として取得できますか?