View Single Post
Old 27th Jul 2019, 3:54 pm   #25
julie_m
Dekatron
 
Join Date: May 2008
Location: Derby, UK.
Posts: 7,735
Default Re: Fun with 6502 Assembler

If you have a number of pointers stored in Zero Page, each representing the base address of a fixed-size record up to 256 bytes, you probably use something like
Code:
LDA (pcb),Y
to read out an individual record, as Y varies from 0 to the length of the record -1, and then update the pointer to read the next record. Here pcb is a location in ZP, short for "packed co-ordinate base"; pcb and pcb+1 are the pointer to a series of packed co-ordinate pairs in memory. After unpacking the co-ordinates (12 + 12 = 24 bits = 3 bytes), we have four bytes to store at a location pointed to by the value in acb and acb+1 (short for "absolute co-ordinate base).

Now to move on to the next vertex, we need to add 3 to value stored at pcb and pcb+1; and we need to add 4 to the value stored at acb and acb+1. Naïvely, we might write
Code:
.next_vertex
CLC
LDA pcb
ADC #3
STA pcb
LDA pcb+1
ADC #0
STA pcb+1
CLC
LDA acb
ADC #4
STA acb
LDA acb+1
ADC #0
STA acb+1
RTS
That's 27 bytes. We probably can omit the second CLC, because we are not expecting the address to overflow the bounds of memory. But we can save even more by making use of the X register, and fall-through:
Code:
.next_vertex
LDX #pcb
CLC
JSR add_three
LDX #acb
.add_four
SEC \ this will add an extra one
.add_three
LDA #3
.add_A_X
ADC 0,X
STA 0,X
LDA #0
ADC 1,X
STA 1,X
RTS
This takes five bytes less space and also exposes two more general-purpose subroutines: one which can be used to advance any similar Zero Page pointer given in X by 4 bytes, and another which advances the pointer by an amount given in A, plus an extra 1 if C is set. (Not doing the CLC in the subroutine allows us to take advantage of 3 and 4 being exactly 1 apart.)

Note that we don't need to increase X to deal with the high byte; we just offset from 1 instead.

Other pointers at different addresses in ZP probably will have different record sizes; so we just need a construct like
Code:
.next_shape
LDX #shp \ shape pointer
LDA #23 \ each "shape" record is 23 bytes long
CLC
BCC add_A_X \ saves over JSR followed by RTS
for each of them. Here, the base address of the list of packed vertex co-ordinates (which will go into pcb and pcb+1) is obtained from a "shape" record which is actually 23 bytes long. After we have stepped through all the vertexes in a shape, unpacking their co-ordinates into a buffer, we can move on to the next shape.
__________________
If I have seen further than others, it is because I was standing on a pile of failed experiments.
julie_m is offline