2018-08-30 20:30:58 +00:00
|
|
|
;license:MIT
|
2021-10-08 06:28:11 +00:00
|
|
|
;(c) 2018-2021 by 4am & qkumba
|
2018-08-30 20:30:58 +00:00
|
|
|
;
|
2020-03-24 20:30:14 +00:00
|
|
|
; Ordered key/value store (6502 compatible)(256+ records compatible)
|
2018-08-30 20:30:58 +00:00
|
|
|
;
|
|
|
|
; Public functions
|
|
|
|
; - okvs_init(address) reset (required)
|
|
|
|
; - okvs_len(address) get number of keys
|
|
|
|
; - okvs_update(address, key, value) update key/value pair
|
|
|
|
; - okvs_get(address, key) get value by key lookup
|
2020-03-18 16:08:39 +00:00
|
|
|
; - okvs_find(address, key) get key by key lookup
|
2018-08-30 20:30:58 +00:00
|
|
|
; - okvs_nth(address, n) get key by numeric index
|
2019-09-16 16:36:10 +00:00
|
|
|
; - okvs_next(address, n) get next key by numeric index
|
2018-08-30 20:30:58 +00:00
|
|
|
; - okvs_iter(address, callback) iterate through keys
|
|
|
|
; - okvs_iter_values(address, callback) iterate through values
|
|
|
|
;
|
2020-03-24 20:30:14 +00:00
|
|
|
; Call init() once. Call it again to reset the store to 0 records.
|
2018-08-30 20:30:58 +00:00
|
|
|
;
|
2020-03-24 20:30:14 +00:00
|
|
|
; Records are maintained in a singly linked list, so most functions are O(n).
|
2021-10-28 05:26:02 +00:00
|
|
|
; len() is O(1) though.
|
2018-08-30 20:30:58 +00:00
|
|
|
;
|
2020-03-24 20:30:14 +00:00
|
|
|
; Record count is stored as a word, so a store can hold 65535 records.
|
2018-08-30 20:30:58 +00:00
|
|
|
;
|
|
|
|
; Keys and values are length-prefixed strings (Pascal style), so max length
|
|
|
|
; of any single key or value is 255 bytes.
|
|
|
|
;
|
|
|
|
; Keys are case-sensitive. Lookups are an exact byte-for-byte comparison.
|
|
|
|
;
|
|
|
|
; All functions take the starting address of the store's data buffer in
|
2021-10-02 01:09:19 +00:00
|
|
|
; memory, so there can be multiple independent stores at one time. Only the
|
2021-10-28 05:26:02 +00:00
|
|
|
; size of a record is stored, so stores are easily relocatable. There is no
|
|
|
|
; overflow protection because this is assembly.
|
2018-08-30 20:30:58 +00:00
|
|
|
;
|
|
|
|
; There is no sort() function.
|
|
|
|
;
|
|
|
|
; There is no delete() function.
|
|
|
|
;
|
2021-10-28 05:26:02 +00:00
|
|
|
; Keys can be duplicated, but get() and find() will always return the first
|
|
|
|
; match.
|
2018-08-30 20:30:58 +00:00
|
|
|
;
|
|
|
|
; Structures:
|
|
|
|
;
|
|
|
|
; Store
|
2020-03-24 20:30:14 +00:00
|
|
|
; +0 number of records (word)
|
|
|
|
; +2 free space pointer after last record (word)
|
|
|
|
; +4 Record
|
2018-08-30 20:30:58 +00:00
|
|
|
; ...Record...
|
|
|
|
; ...Record...
|
|
|
|
;
|
|
|
|
; Record
|
2021-10-02 01:09:19 +00:00
|
|
|
; +0 record length (including this field)
|
|
|
|
; +1 key length
|
|
|
|
; +2 key
|
2018-08-30 20:30:58 +00:00
|
|
|
; +K+2 value length (actual length, not max length)
|
|
|
|
; +K+3 value
|
|
|
|
; ... filler bytes up to value max length (set at append() time)
|
|
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
; okvs_init
|
|
|
|
;
|
2019-09-20 23:46:46 +00:00
|
|
|
; in: A/Y = handle to storage space
|
2018-08-30 20:30:58 +00:00
|
|
|
; out: $00/$01 clobbered
|
|
|
|
; $02/$03 clobbered
|
2019-09-10 13:50:08 +00:00
|
|
|
; all registers clobbered
|
2018-08-30 20:30:58 +00:00
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
okvs_init
|
2019-09-20 23:46:46 +00:00
|
|
|
jsr GetStoreAddressFromAY
|
2019-09-10 13:37:19 +00:00
|
|
|
; PTR -> store
|
|
|
|
; Y = 0
|
2018-08-30 20:30:58 +00:00
|
|
|
tya
|
2020-03-24 20:30:14 +00:00
|
|
|
sta (PTR),y ; set number of keys in store to 0 (word)
|
|
|
|
iny
|
|
|
|
sta (PTR),y
|
2019-09-10 05:46:21 +00:00
|
|
|
|
2020-03-24 20:30:14 +00:00
|
|
|
iny ; set next-free-space pointer to store + 4
|
2019-09-10 05:46:21 +00:00
|
|
|
ldx PTR+1
|
|
|
|
lda PTR
|
|
|
|
clc
|
2020-03-24 20:30:14 +00:00
|
|
|
adc #$04
|
2019-09-10 05:46:21 +00:00
|
|
|
bcc +
|
|
|
|
inx
|
2019-09-10 13:37:19 +00:00
|
|
|
+ sta (PTR),y
|
2019-09-10 05:46:21 +00:00
|
|
|
iny
|
|
|
|
txa
|
|
|
|
sta (PTR),y
|
2018-08-30 20:30:58 +00:00
|
|
|
rts
|
|
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
; okvs_len
|
2021-10-14 19:08:50 +00:00
|
|
|
; okvs_len_imm
|
2018-08-30 20:30:58 +00:00
|
|
|
;
|
2019-09-20 23:42:26 +00:00
|
|
|
; in: A/Y = handle to storage space
|
2020-03-24 20:30:14 +00:00
|
|
|
; out: $WCOUNT contains number of keys in this store
|
2019-09-20 23:42:26 +00:00
|
|
|
; X preserved
|
2020-03-24 20:30:14 +00:00
|
|
|
; A, Y clobbered
|
2021-10-14 19:08:50 +00:00
|
|
|
; Z set if no keys
|
2018-08-30 20:30:58 +00:00
|
|
|
; $00/$01 clobbered
|
|
|
|
; $02/$03 clobbered
|
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
okvs_len
|
2019-09-20 23:42:26 +00:00
|
|
|
jsr GetStoreAddressFromAY
|
2019-09-10 13:37:19 +00:00
|
|
|
; PTR -> store
|
|
|
|
; Y = 0
|
2021-10-14 19:08:50 +00:00
|
|
|
okvs_len_imm
|
2020-03-24 20:30:14 +00:00
|
|
|
lda (PTR), y ; get number of keys in store (word)
|
|
|
|
sta WCOUNT
|
|
|
|
iny
|
|
|
|
lda (PTR), y
|
|
|
|
sta WCOUNT+1
|
2021-10-14 19:08:50 +00:00
|
|
|
ora WCOUNT
|
2018-08-30 20:30:58 +00:00
|
|
|
rts
|
|
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
2020-03-18 16:08:39 +00:00
|
|
|
; okvs_find / okvs_get
|
2018-08-30 20:30:58 +00:00
|
|
|
;
|
|
|
|
; in: stack contains 4 bytes of parameters:
|
|
|
|
; +1 [word] handle to storage space
|
|
|
|
; +3 [word] address of key
|
2020-03-18 16:08:39 +00:00
|
|
|
; out: if C clear, record was found
|
|
|
|
; A/Y = lo/hi address of key (okvs_find) or value (okvs_get)
|
2020-03-24 20:30:14 +00:00
|
|
|
; $WINDEX = index of found record (word)
|
2020-11-09 20:22:38 +00:00
|
|
|
; if C set, keyrecord was not found and X/Y are clobbered, A=0
|
2018-08-30 20:30:58 +00:00
|
|
|
; all other flags clobbered
|
|
|
|
; $00/$01 clobbered
|
|
|
|
; $02/$03 clobbered
|
|
|
|
; $04/$05 clobbered
|
|
|
|
;------------------------------------------------------------------------------
|
2020-03-18 16:08:39 +00:00
|
|
|
okvs_find
|
|
|
|
lda #$60
|
|
|
|
+HIDE_NEXT_2_BYTES
|
2018-08-30 20:30:58 +00:00
|
|
|
okvs_get
|
2020-03-18 16:08:39 +00:00
|
|
|
lda #$EA
|
|
|
|
sta @maybeGetValue
|
2018-08-30 20:30:58 +00:00
|
|
|
+PARAMS_ON_STACK 4
|
2019-09-10 13:37:19 +00:00
|
|
|
jsr GetStoreAddress
|
|
|
|
; PTR -> store
|
|
|
|
; Y = 0
|
2021-10-14 19:08:50 +00:00
|
|
|
jsr okvs_len_imm
|
2018-08-30 20:30:58 +00:00
|
|
|
beq @fail ; no keys, fail immediately
|
2020-03-24 20:30:14 +00:00
|
|
|
jsr incptr4
|
2019-09-10 05:46:21 +00:00
|
|
|
; PTR -> first record
|
2019-11-27 21:51:43 +00:00
|
|
|
+LDPARAMPTR 3, SRC ; SRC -> key we want to find
|
2018-08-30 20:30:58 +00:00
|
|
|
ldy #0
|
2020-03-24 20:30:14 +00:00
|
|
|
sty WINDEX
|
|
|
|
sty WINDEX+1
|
2018-08-30 20:30:58 +00:00
|
|
|
lda (SRC),y
|
|
|
|
tay
|
|
|
|
iny
|
2019-09-22 02:18:33 +00:00
|
|
|
sty KEYLEN
|
2018-08-30 20:30:58 +00:00
|
|
|
@matchRecordLoop
|
2020-11-09 20:22:38 +00:00
|
|
|
+LD16 PTR
|
2021-10-02 01:09:19 +00:00
|
|
|
tax
|
|
|
|
inx
|
|
|
|
bne +
|
|
|
|
iny
|
|
|
|
+ stx DEST ; DEST -> key of this record
|
|
|
|
sty DEST+1
|
2020-11-09 20:22:38 +00:00
|
|
|
ldy #0
|
2018-08-30 20:30:58 +00:00
|
|
|
@matchKeyLoop
|
|
|
|
lda (SRC),y
|
|
|
|
cmp (DEST),y
|
|
|
|
bne @next
|
|
|
|
iny
|
2019-10-10 01:02:46 +00:00
|
|
|
KEYLEN = *+1
|
|
|
|
cpy #$D1 ; SMC
|
2018-08-30 20:30:58 +00:00
|
|
|
bne @matchKeyLoop
|
2020-03-24 20:30:14 +00:00
|
|
|
+LD16 DEST
|
2018-08-30 20:30:58 +00:00
|
|
|
clc
|
2020-03-18 16:08:39 +00:00
|
|
|
@maybeGetValue
|
|
|
|
brk ; SMC
|
2021-11-09 17:41:15 +00:00
|
|
|
jsr okvs_next_field
|
2020-03-24 20:30:14 +00:00
|
|
|
+LD16 PTR
|
2018-08-30 20:30:58 +00:00
|
|
|
clc
|
2020-03-18 16:08:39 +00:00
|
|
|
rts
|
2021-10-02 01:09:19 +00:00
|
|
|
@next jsr stepptr ; PTR -> next record
|
2020-03-24 20:30:14 +00:00
|
|
|
inc WINDEX
|
|
|
|
bne +
|
|
|
|
inc WINDEX+1
|
|
|
|
+
|
|
|
|
lda WINDEX
|
|
|
|
cmp WCOUNT
|
|
|
|
bne @matchRecordLoop
|
|
|
|
lda WINDEX+1
|
2020-11-09 20:22:38 +00:00
|
|
|
eor WCOUNT+1
|
2018-08-30 20:30:58 +00:00
|
|
|
bne @matchRecordLoop
|
|
|
|
@fail sec
|
|
|
|
rts
|
|
|
|
|
2019-09-16 16:36:10 +00:00
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
; okvs_next
|
|
|
|
; get (N+1)th key, with wraparound
|
|
|
|
;
|
|
|
|
; in: A/Y = handle to storage space
|
2020-03-24 20:30:14 +00:00
|
|
|
; $WINDEX = record index (word)
|
|
|
|
; out: A/Y = lo/hi address of ($WINDEX+1)th key, or first key if $WINDEX was the last record
|
|
|
|
; $WINDEX = record index of next record
|
2019-09-20 23:42:26 +00:00
|
|
|
; see okvs_nth for other exit conditions
|
2019-09-16 16:36:10 +00:00
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
okvs_next
|
2020-03-24 20:30:14 +00:00
|
|
|
+ST16 PARAM
|
|
|
|
inc WINDEX
|
|
|
|
bne +
|
|
|
|
inc WINDEX+1
|
|
|
|
+
|
2019-09-16 16:36:10 +00:00
|
|
|
jsr okvs_len
|
2020-03-24 20:30:14 +00:00
|
|
|
+LD16 WINDEX
|
2021-10-13 22:58:26 +00:00
|
|
|
+CMP16ADDR_NE WCOUNT, +
|
2020-03-24 20:30:14 +00:00
|
|
|
sta WINDEX
|
|
|
|
sta WINDEX+1
|
2019-09-23 17:14:27 +00:00
|
|
|
+
|
2020-03-24 20:30:14 +00:00
|
|
|
+LD16 PARAM
|
2019-10-08 17:19:20 +00:00
|
|
|
; /!\ execution falls through here to okvs_nth
|
2019-09-20 23:27:16 +00:00
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
; okvs_nth
|
|
|
|
; get (N)th key
|
|
|
|
;
|
|
|
|
; in: A/Y = handle to storage space
|
2020-03-24 20:30:14 +00:00
|
|
|
; $WINDEX = record index
|
2019-09-20 23:27:16 +00:00
|
|
|
; out: A/Y = lo/hi address of nth key
|
2020-03-24 20:30:14 +00:00
|
|
|
; $WINDEX preserved
|
|
|
|
; X = 0
|
2019-09-20 23:27:16 +00:00
|
|
|
; Z = 0
|
|
|
|
; all other flags clobbered
|
2020-03-24 20:30:14 +00:00
|
|
|
; $PTR clobbered
|
2019-09-20 23:27:16 +00:00
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
okvs_nth
|
|
|
|
jsr GetStoreAddressFromAY
|
|
|
|
; PTR -> store
|
2020-03-24 20:30:14 +00:00
|
|
|
jsr incptr4
|
2019-09-20 23:27:16 +00:00
|
|
|
; PTR -> first record
|
2020-03-24 20:30:14 +00:00
|
|
|
+LD16 WINDEX
|
|
|
|
+ST16 SAVE
|
|
|
|
jmp @next
|
2021-10-02 01:09:19 +00:00
|
|
|
- jsr stepptr
|
2020-03-24 20:30:14 +00:00
|
|
|
@next
|
|
|
|
lda SAVE
|
2020-11-09 20:22:38 +00:00
|
|
|
dec SAVE
|
|
|
|
tay
|
2019-09-20 23:27:16 +00:00
|
|
|
bne -
|
2020-03-24 20:30:14 +00:00
|
|
|
lda SAVE+1
|
2020-11-09 20:22:38 +00:00
|
|
|
dec SAVE+1
|
|
|
|
tay
|
2020-03-24 20:30:14 +00:00
|
|
|
bne -
|
2021-10-02 01:09:19 +00:00
|
|
|
jsr incptr
|
2020-03-24 20:30:14 +00:00
|
|
|
+LD16 PTR
|
|
|
|
ldx #0
|
2019-09-16 16:36:10 +00:00
|
|
|
rts
|
|
|
|
|
2018-08-30 20:30:58 +00:00
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
; okvs_update
|
|
|
|
;
|
|
|
|
; in: stack contains 6 bytes of parameters:
|
|
|
|
; +1 [word] handle to storage space
|
|
|
|
; +3 [word] address of key
|
|
|
|
; +5 [word] address of new value
|
|
|
|
; out: if C clear, key was found and value was updated
|
|
|
|
; if C set, key was not found
|
|
|
|
; all registers are clobbered
|
|
|
|
; all other flags clobbered
|
|
|
|
; $00/$01 clobbered
|
|
|
|
; $02/$03 clobbered
|
|
|
|
; $04/$05 clobbered
|
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
okvs_update
|
|
|
|
+PARAMS_ON_STACK 6
|
|
|
|
ldy #6
|
|
|
|
lda (PARAM),y
|
|
|
|
sta SAVE+1
|
|
|
|
dey
|
|
|
|
lda (PARAM),y
|
|
|
|
sta SAVE
|
|
|
|
dey
|
|
|
|
- lda (PARAM),y
|
|
|
|
sta @getparams,y
|
|
|
|
dey
|
|
|
|
bne -
|
|
|
|
jsr okvs_get
|
|
|
|
@getparams=*-1
|
|
|
|
!word $FDFD ; SMC
|
|
|
|
!word $FDFD ; SMC
|
|
|
|
bcs @exit
|
2020-03-24 20:30:14 +00:00
|
|
|
+ST16 DEST
|
2018-08-30 20:30:58 +00:00
|
|
|
ldy #0
|
|
|
|
lda (SAVE),y
|
|
|
|
tay
|
|
|
|
- lda (SAVE),y
|
|
|
|
sta (DEST),y
|
|
|
|
dey
|
|
|
|
cpy #$FF
|
|
|
|
bne -
|
|
|
|
clc
|
|
|
|
@exit rts
|
|
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
2019-09-10 04:54:52 +00:00
|
|
|
; okvs_iter / okvs_iter_values
|
2018-08-30 20:30:58 +00:00
|
|
|
;
|
|
|
|
; in: stack contains 4 bytes of parameters:
|
|
|
|
; +1 [word] handle to storage space
|
|
|
|
; +3 [word] address of callback
|
|
|
|
; out: <callback> will be called for each record in the store, in order, with
|
2020-03-24 20:30:14 +00:00
|
|
|
; $WINDEX = numeric index of record (word)
|
2019-09-10 04:54:52 +00:00
|
|
|
; A/Y = address of key or value (depends on which entry point you call)
|
2018-08-30 20:30:58 +00:00
|
|
|
; all registers are clobbered
|
2019-10-08 17:39:06 +00:00
|
|
|
; Z=1
|
|
|
|
; all other flags clobbered
|
2019-09-22 02:18:33 +00:00
|
|
|
; PARAM clobbered
|
|
|
|
; PTR clobbered
|
2020-03-24 20:30:14 +00:00
|
|
|
; WINDEX clobbered
|
|
|
|
; WCOUNT clobbered
|
2018-08-30 20:30:58 +00:00
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
okvs_iter
|
2019-09-10 13:37:19 +00:00
|
|
|
lda #$D0 ; 'BNE' opcode
|
2019-09-10 04:54:52 +00:00
|
|
|
+HIDE_NEXT_2_BYTES
|
2018-08-30 20:30:58 +00:00
|
|
|
okvs_iter_values
|
2019-09-10 13:37:19 +00:00
|
|
|
lda #$24 ; 'BIT' opcode
|
2019-09-10 04:54:52 +00:00
|
|
|
sta @branch
|
2018-08-30 20:30:58 +00:00
|
|
|
+PARAMS_ON_STACK 4
|
2019-09-10 13:37:19 +00:00
|
|
|
jsr GetStoreAddress
|
|
|
|
; PTR -> store
|
|
|
|
; Y = 0
|
2021-10-14 19:08:50 +00:00
|
|
|
jsr okvs_len_imm
|
2018-08-30 20:30:58 +00:00
|
|
|
beq @exit ; no keys, exit immediately
|
2021-10-13 22:58:26 +00:00
|
|
|
+LDPARAMPTR 3, @callback
|
2020-03-24 20:30:14 +00:00
|
|
|
jsr incptr4
|
2019-09-10 05:46:21 +00:00
|
|
|
; PTR -> first record
|
2020-03-24 20:30:14 +00:00
|
|
|
lda #0
|
|
|
|
sta WINDEX
|
|
|
|
sta WINDEX+1
|
2019-09-10 04:54:52 +00:00
|
|
|
@loop
|
2021-10-02 01:09:19 +00:00
|
|
|
lda #1 ; for iter, skip length = 1
|
2019-09-10 13:37:19 +00:00
|
|
|
@branch bne + ; SMC (iter_values puts a BIT here, so no branch)
|
2021-10-02 01:09:19 +00:00
|
|
|
; for iter_values, skip length = length(key) + 1 + 1
|
|
|
|
tay ;;ldy #1
|
2018-08-30 20:30:58 +00:00
|
|
|
lda (PTR),y ; A = length of key
|
|
|
|
clc
|
2021-10-02 01:09:19 +00:00
|
|
|
adc #2 ; skip over record length (1 byte) + key length (1 byte)
|
2019-09-22 03:00:05 +00:00
|
|
|
+ sta @skiplen
|
2020-03-24 20:30:14 +00:00
|
|
|
lda WCOUNT+1 ; save WCOUNT on stack
|
|
|
|
pha
|
|
|
|
lda WCOUNT
|
|
|
|
pha
|
|
|
|
lda WINDEX+1 ; save WINDEX on stack
|
|
|
|
pha
|
|
|
|
lda WINDEX
|
|
|
|
pha
|
2018-08-30 20:30:58 +00:00
|
|
|
lda PTR+1
|
|
|
|
tay
|
|
|
|
pha
|
|
|
|
lda PTR
|
2020-03-24 20:30:14 +00:00
|
|
|
pha ; save PTR on stack
|
2018-08-30 20:30:58 +00:00
|
|
|
clc
|
2019-09-22 03:00:05 +00:00
|
|
|
@skiplen=*+1
|
|
|
|
adc #$FD ; SMC skip over pointer (and possibly key)
|
2018-08-30 20:30:58 +00:00
|
|
|
bcc +
|
|
|
|
iny ; A/Y -> value
|
|
|
|
+
|
|
|
|
@callback=*+1
|
|
|
|
jsr $FDFD ; SMC
|
|
|
|
pla
|
|
|
|
sta PTR
|
|
|
|
pla
|
|
|
|
sta PTR+1 ; restore PTR from stack
|
|
|
|
pla
|
2020-03-24 20:30:14 +00:00
|
|
|
sta WINDEX
|
|
|
|
pla
|
|
|
|
sta WINDEX+1
|
|
|
|
pla
|
|
|
|
sta WCOUNT
|
|
|
|
pla
|
|
|
|
sta WCOUNT+1
|
2021-10-02 01:09:19 +00:00
|
|
|
jsr stepptr ; PTR -> next record
|
2020-03-24 20:30:14 +00:00
|
|
|
inc WINDEX
|
|
|
|
bne +
|
|
|
|
inc WINDEX+1
|
|
|
|
+
|
|
|
|
lda WINDEX
|
|
|
|
cmp WCOUNT
|
|
|
|
bne @loop
|
|
|
|
lda WINDEX+1
|
|
|
|
cmp WCOUNT+1
|
2018-08-30 20:30:58 +00:00
|
|
|
bne @loop
|
|
|
|
@exit rts
|
|
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
; internal functions
|
|
|
|
|
2021-11-09 17:41:15 +00:00
|
|
|
okvs_next_field
|
2021-10-13 22:58:26 +00:00
|
|
|
; out: Y = 0
|
2021-10-02 01:09:19 +00:00
|
|
|
+ST16 PTR
|
2021-11-09 17:41:15 +00:00
|
|
|
okvs_next_field_PTR_is_already_set
|
2021-10-02 01:09:19 +00:00
|
|
|
jsr stepptr
|
|
|
|
bne incptr
|
|
|
|
|
2020-03-24 20:30:14 +00:00
|
|
|
incptr4 jsr incptr2
|
2019-09-10 13:20:32 +00:00
|
|
|
incptr2 jsr incptr
|
2018-08-30 20:30:58 +00:00
|
|
|
incptr
|
2019-09-24 00:01:42 +00:00
|
|
|
; preserves A, X, and Y
|
|
|
|
inc PTR
|
2018-08-30 20:30:58 +00:00
|
|
|
bne +
|
|
|
|
inc PTR+1
|
|
|
|
+ rts
|
|
|
|
|
2019-09-20 23:27:16 +00:00
|
|
|
GetStoreAddressFromAY
|
2020-03-24 20:30:14 +00:00
|
|
|
+ST16 PTR
|
2019-09-20 23:27:16 +00:00
|
|
|
jmp derefptr
|
|
|
|
|
2019-09-10 13:37:19 +00:00
|
|
|
GetStoreAddress
|
|
|
|
; in: PARAM = address of stack params (any PARAMS_ON_STACK macro will do this)
|
|
|
|
; out: PTR = address of store (always the first parameter on stack)
|
2018-08-30 20:30:58 +00:00
|
|
|
; preserves X
|
|
|
|
ldy #1
|
|
|
|
lda (PARAM),y
|
|
|
|
sta PTR
|
|
|
|
iny
|
|
|
|
lda (PARAM),y
|
|
|
|
sta PTR+1 ; PTR -> first parameter on stack
|
|
|
|
; execution falls through here
|
|
|
|
derefptr
|
2019-09-10 13:37:19 +00:00
|
|
|
; out: Y = 0
|
|
|
|
; preserves X
|
|
|
|
ldy #1
|
2018-08-30 20:30:58 +00:00
|
|
|
lda (PTR),y
|
|
|
|
pha
|
2019-09-10 13:37:19 +00:00
|
|
|
dey
|
2018-08-30 20:30:58 +00:00
|
|
|
lda (PTR),y
|
|
|
|
sta PTR
|
2019-09-10 13:37:19 +00:00
|
|
|
pla
|
|
|
|
sta PTR+1
|
2018-08-30 20:30:58 +00:00
|
|
|
rts
|
2021-10-02 01:09:19 +00:00
|
|
|
|
|
|
|
stepptr
|
|
|
|
; out: Y = 0
|
|
|
|
; preserves X
|
|
|
|
ldy #0
|
|
|
|
lda (PTR),y
|
|
|
|
clc
|
|
|
|
adc PTR
|
|
|
|
sta PTR
|
|
|
|
bcc +
|
|
|
|
inc PTR+1
|
|
|
|
+ rts
|