fumbling my way into 65C02 assembly

grommile

New Member
Nov 24, 2019
17
7
3
Northampton, UK
As a starting point for beginning to grok 65C02 assembly (my only prior assembly experience is things like "drive a UART on x86" and "modify the very early startup code of a PowerPC SBC's boot ROM", which are not particularly helpful as a reference point for "how do I 6502?"), I wrote this short "skip over spaces in an input buffer" subroutine.

My questions are:
  1. Will it do what the comments say I think it will?
  2. Is the approach at least vaguely conventional?
  3. Would a 65(C)02 assembly programmer actually expect a subroutine like this to save/restore A and Y?
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; skip_space (SKPSPC)
;
; INPUTS:
; RAM @ $300: buffer
; RAM @ $80: input index to start from
; OUTPUTS:
; carry flag: set for buffer exhausted, clear for buffer not exhausted
; RAM @ $80: index of following nonspace
;
.PC02 ;; compile for 65C02
INPUT_BUF=$300
INPUT_IDX=$80
INPUT_MAXBYTES=80

.proc skip_space
phy ;; save y to stack
pha ;; save a to stack
ldy INPUT_IDX ;; load current index into y
dey ;; decrement y to make writing loop correctly simpler
L1:
iny ;; increment y
tya ;; copy index into accumulator
cmp #INPUT_MAXBYTES ;; compare to max tokens
bcs DONE ;; stop parsing if index has reached max
lda INPUT_BUF,y ;; load byte from token buffer
cmp #$20 ;; compare to (PET|A)SCII SPACE
beq L1 ;; loop if equal
FOUND: ;; convenience label for readability
clc ;; clear carry because we didn't exhaust buffer
DONE:
sty INPUT_IDX ;; update index after search complete
ply ;; restore y from stack
pla ;; restore a from stack
rts ;; return
.endproc
 

Wertyloo

Member
Sep 15, 2019
76
11
8
some footnote:
the iny-tya-cmp# part can be done iny-cpy# way
it is a generally good idea to NOT MOVE the indexregs. values if its not a absolutely necess.y on any 6502[or other 8bit low number of indexreg.] cpu
use the aprop. indexreg-manipulate-opcode if you can
 

BruceMcF

Active Member
May 19, 2019
205
63
28
As a starting point for beginning to grok 65C02 assembly (my only prior assembly experience is things like "drive a UART on x86" and "modify the very early startup code of a PowerPC SBC's boot ROM", which are not particularly helpful as a reference point for "how do I 6502?"), I wrote this short "skip over spaces in an input buffer" subroutine.

My questions are:
1. Will it do what the comments say I think it will?
I guess so. I never say for sure unless I assemble it and test it.

2. Is the approach at least vaguely conventional?
Pretty much. The other way ... jumping out of the loop on match and incrementing at the end would also be common.

3. Would a 65(C)02 assembly programmer actually expect a subroutine like this to save/restore A and Y?
Probably not. More often it is just documented that registers are used. In probably more cases than otherwise, the last value in A won't need to be retained, saving 7 cycles.

Indeed, the reason to use Y rather than X for this would typically be because in the context of the main application you benefit from preserving X more often than Y, so PHY/PLY would be needed less often than PHX/PLX.

Note that it would be more general purpose if the starting index value is passed in X or Y and the result returned in X or Y.

Also note that if you are doing this for the CX16, it's $00-$7F that is available in the zero page for applications, if the graphical calls are not being made, $00/$01 and $22-$7F otherwise, and the golden ram is $400-$7FF. If testing in VICE's xcpu64 for it's 65C02 compatibility, $FB, $FC, $FD and $FE are free without interfering with Basic, and $C000-$CFFF is golden ram.