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
Il s'agit d'un sous-programme indépendant de la position qui attend un pointeur sur la chaîne d'entrée (terminée par 0, aka chaîne C) dans $fb
/ $fc
, un pointeur sur le tampon de sortie dans $fd
/ $fe
et le nombre (n
) dans $ff
. Il utilise une indexation simple, il est donc limité à une longueur de sortie maximale de 255 caractères (+ 0 octet) en raison de l'architecture 8 bits.
Explication (démontage commenté):
.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.
Exemple de programme de code machine C64 l'utilisant :
Il s'agit d'un programme en assembleur de style ca65 pour le C64 utilisant cette routine (importé en tant que 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
Démo en ligne
Utilisation:, sys49152,"[s]",[n]
par exemplesys49152,"Hello, World!",3
Important: Si le programme a été chargé à partir du disque (comme dans la démo en ligne), lancez d'abord une new
commande! Cela est nécessaire car le chargement d'un programme machine met à la corbeille certains pointeurs C64 BASIC.
s
comme un tableau de caractères?