add lookup table to make okvs_nth O(1)

This commit is contained in:
4am 2021-11-16 13:34:57 -05:00
parent b379bba34c
commit cdaeb336f2
32 changed files with 97 additions and 77 deletions

View File

@ -25,10 +25,14 @@ dhgrlog=$(< "$3")
echo "!word $(wc -l < "$records")") > "$1"
# make temp assembly source file that represents the binary OKVS data structure
source=$(mktemp)
(echo "*=0" # dummy program counter for assembler
echo "!le16 $(wc -l <"$records"), 0" # OKVS header
#source=$(mktemp)
source=build/search.a
(echo '*=$6000'
echo "!le16 $(wc -l <"$records")" # OKVS header
echo "!word KeyLookup"
count=0
while IFS="=" read -r key value; do
count=$((count+1))
dhgr=$(echo "$key" | cut -c3) # 'has DHGR title screen' flag (0 or 1)
cheat=$(echo "$key" | cut -c4) # 'cheat category' (0..5)
key=$(echo "$key" | cut -d"," -f2)
@ -42,6 +46,7 @@ source=$(mktemp)
offset=$(echo "$offset" | awk -F, '/^'"$key"',/ { print $2 }')
size=$(echo "$size" | awk -F, '/^'"$key"',/ { print $3 }')
echo "!byte ${#key}+${#value}+10" # OKVS record length
echo "Key${count}"
echo "!byte ${#key}" # OKVS key length
echo "!text \"$key\"" # OKVS key (filename)
echo "!byte ${#value}" # OKVS value length
@ -50,7 +55,12 @@ source=$(mktemp)
echo "!byte $((dhgr*128))+$cheat"
echo "!be24 $offset"
echo "!le16 $size"
done < "$records") > "$source"
done < "$records"
echo "KeyLookup"
for i in $(seq $count); do
echo "!word Key$i"
done
) > "$source"
# assemble temp source file into binary OKVS data structure, then output that
out=$(mktemp)
@ -59,5 +69,5 @@ cat "$out"
# clean up
rm "$out"
rm "$source"
#rm "$source"
rm "$records"

View File

@ -3,37 +3,12 @@
LAUNCHER.SYSTEM=Type(FF),AuxType(2000),Access(C3)
TOTAL.DATA=Type(06),AuxType(0000),Access(C3)
TOTAL.IDX=Type(06),AuxType(0000),Access(C3)
PREFS.CONF=Type(04),AuxType(BD00),Access(C3)
ATTRACT.IDX=Type(06),AuxType(6000),Access(C3)
MINIATTRACT.IDX=Type(06),AuxType(6000),Access(C3)
FX.IDX=Type(06),AuxType(6000),Access(C3)
DFX.IDX=Type(06),AuxType(6000),Access(C3)
GAMEHELP.IDX=Type(06),AuxType(6000),Access(C3)
SLIDESHOW.IDX=Type(06),AuxType(4000),Access(C3)
PRELAUNCH.IDX=Type(06),AuxType(6000),Access(C3)
ARTWORK.IDX=Type(06),AuxType(2000),Access(C3)
HGR0.IDX=Type(06),AuxType(4000),Access(C3)
HGR1.IDX=Type(06),AuxType(4000),Access(C3)
HGR2.IDX=Type(06),AuxType(4000),Access(C3)
HGR3.IDX=Type(06),AuxType(4000),Access(C3)
HGR4.IDX=Type(06),AuxType(4000),Access(C3)
HGR5.IDX=Type(06),AuxType(4000),Access(C3)
HGR6.IDX=Type(06),AuxType(4000),Access(C3)
DHGR.IDX=Type(06),AuxType(4000),Access(C3)
GR.IDX=Type(06),AuxType(4600),Access(C3)
SEARCH00.IDX=Type(06),AuxType(6000),Access(C3)
SEARCH01.IDX=Type(06),AuxType(6000),Access(C3)
SEARCH10.IDX=Type(06),AuxType(6000),Access(C3)
SEARCH11.IDX=Type(06),AuxType(6000),Access(C3)
CACHE00.IDX=Type(06),AuxType(A000),Access(C3)
CACHE01.IDX=Type(06),AuxType(A000),Access(C3)
CACHE10.IDX=Type(06),AuxType(A000),Access(C3)
CACHE11.IDX=Type(06),AuxType(A000),Access(C3)
PREFS.CONF=Type(04),AuxType(0000),Access(C3)
COVER=Type(06),AuxType(2000),Access(C3)
TITLE=Type(06),AuxType(2000),Access(C3)
HELP=Type(06),AuxType(2000),Access(C3)
CREDITS=Type(06),AuxType(6000),Access(C3)
HELPTEXT=Type(06),AuxType(6000),Access(C3)
CREDITS=Type(06),AuxType(0800),Access(C3)
HELPTEXT=Type(06),AuxType(0800),Access(C3)
DECRUNCH=Type(06),AuxType(0200),Access(C3)
JOYSTICK=Type(06),AuxType(0800),Access(C3)
Finder.Data=Type(C9),AuxType(0000),Access(E7)

View File

@ -11,7 +11,7 @@
; ...unused...
; E000..E3FF - HGR font data
; ...unused...
; E8CA..FFEE - main program code
; E841..FFEE - main program code
; FFEF..FFF9 - API functions and global constants available for main program
; code, prelaunchers, transition effects, &c.
; (LoadFileDirect, Wait/UnwaitForVBL, MockingboardStuff, MachineStatus)

View File

@ -4,5 +4,5 @@
; This file is automatically generated
;
!byte 0
!be24 108539
!be24 111209
!le16 4186

View File

@ -4,5 +4,5 @@
; This file is automatically generated
;
!byte 0
!be24 61954
!be24 64624
!le16 5174

View File

@ -4,5 +4,5 @@
; This file is automatically generated
;
!byte 0
!be24 7472
!be24 8000
!le16 3580

View File

@ -4,5 +4,5 @@
; This file is automatically generated
;
!byte 0
!be24 19228
!be24 20332
!le16 3940

View File

@ -4,5 +4,5 @@
; This file is automatically generated
;
!byte 0
!be24 33845
!be24 35693
!le16 4615

View File

@ -4,5 +4,5 @@
; This file is automatically generated
;
!byte 0
!be24 50260
!be24 52930
!le16 5562

View File

@ -4,5 +4,5 @@
; This file is automatically generated
;
!byte 0
!be24 69274
!be24 71944
!le16 1242

View File

@ -4,5 +4,5 @@
; This file is automatically generated
;
!byte 0
!be24 107197
!be24 109867
!le16 1249

View File

@ -4,5 +4,5 @@
; This file is automatically generated
;
!byte 0
!be24 93345
!be24 96015
!le16 464

View File

@ -4,5 +4,5 @@
; This file is automatically generated
;
!byte 0
!be24 67128
!be24 69798
!le16 2146

View File

@ -4,5 +4,5 @@
; This file is automatically generated
;
!byte 0
!be24 70516
!be24 73186
!le16 6132

View File

@ -4,5 +4,5 @@
; This file is automatically generated
;
!byte 0
!be24 108446
!be24 111116
!le16 93

View File

@ -4,5 +4,5 @@
; This file is automatically generated
;
!byte 0
!be24 93809
!be24 96479
!le16 4364

View File

@ -4,5 +4,5 @@
; This file is automatically generated
;
!byte 0
!be24 98173
!be24 100843
!le16 1516

View File

@ -4,5 +4,5 @@
; This file is automatically generated
;
!byte 0
!be24 99689
!be24 102359
!le16 1031

View File

@ -4,5 +4,5 @@
; This file is automatically generated
;
!byte 0
!be24 100720
!be24 103390
!le16 3237

View File

@ -4,5 +4,5 @@
; This file is automatically generated
;
!byte 0
!be24 103957
!be24 106627
!le16 2694

View File

@ -4,5 +4,5 @@
; This file is automatically generated
;
!byte 0
!be24 106651
!be24 109321
!le16 441

View File

@ -4,5 +4,5 @@
; This file is automatically generated
;
!byte 0
!be24 107092
!be24 109762
!le16 105

View File

@ -4,5 +4,5 @@
; This file is automatically generated
;
!byte 0
!be24 81484
!be24 84154
!le16 6132

View File

@ -4,5 +4,5 @@
; This file is automatically generated
;
!byte 0
!be24 55822
!be24 58492
!le16 6132

View File

@ -5,4 +5,4 @@
;
!byte 0
!be24 0
!le16 7472
!le16 8000

View File

@ -4,5 +4,5 @@
; This file is automatically generated
;
!byte 0
!be24 11052
!le16 8176
!be24 11580
!le16 8752

View File

@ -4,5 +4,5 @@
; This file is automatically generated
;
!byte 0
!be24 23168
!le16 10677
!be24 24272
!le16 11421

View File

@ -4,5 +4,5 @@
; This file is automatically generated
;
!byte 0
!be24 38460
!le16 11800
!be24 40308
!le16 12622

View File

@ -4,5 +4,5 @@
; This file is automatically generated
;
!byte 0
!be24 76648
!be24 79318
!le16 4836

View File

@ -4,5 +4,5 @@
; This file is automatically generated
;
!byte 0
!be24 87616
!be24 90286
!le16 5729

View File

@ -17,12 +17,15 @@
; Call init() once. Call it again to reset the store to 0 records.
;
; Records are maintained in a singly linked list, so most functions are O(n).
; len() is O(1) though.
; len() is always O(1). okvs_nth() can be O(1) if some other code produces
; a key lookup table and stores its address in the 'free space pointer
; after last record' field in the header.
;
; Record count is stored as a word, so a store can hold 65535 records.
;
; Keys and values are length-prefixed strings (Pascal style), so max length
; of any single key or value is 255 bytes.
; of any single key or value is 255 bytes. Record length is stored as a byte
; that includes itself, so the maximum data length of a record is 254 bytes.
;
; Keys are case-sensitive. Lookups are an exact byte-for-byte comparison.
;
@ -31,6 +34,10 @@
; size of a record is stored, so stores are easily relocatable. There is no
; overflow protection because this is assembly.
;
; There is an append() function but it has been separated out of this version
; because it is only used once during program startup, so it does not need
; to persist in LC RAM.
;
; There is no sort() function.
;
; There is no delete() function.
@ -38,11 +45,16 @@
; Keys can be duplicated, but get() and find() will always return the first
; match.
;
; Records can technically have more fields than key and value, but callers
; are on their own for navigating inside the record. If you have a pointer
; to one length-prefixed field (including key or value), okvs_next_field()
; will find the start of the next field.
;
; Structures:
;
; Store
; +0 number of records (word)
; +2 free space pointer after last record (word)
; +2 free space pointer after last record (word) or $0000
; +4 Record
; ...Record...
; ...Record...
@ -218,19 +230,45 @@ okvs_next
; $WINDEX = record index
; out: A/Y = lo/hi address of nth key
; $WINDEX preserved
; X = 0
; Z = 0
; all other flags clobbered
; $PTR clobbered
;------------------------------------------------------------------------------
okvs_nth
jsr GetStoreAddressFromAY
; PTR -> store
jsr incptr4
; PTR -> first record
jsr GetStoreAddressFromAY ; PTR -> store
+LD16 WINDEX
+ST16 SAVE
jmp @next
jsr incptr2 ; PTR -> store+2
ldy #1
lda (PTR), y
beq @slowpath ; if no key lookup table, iterate through store
pha ; otherwise look up key address and return it
dey
lda (PTR), y
sta PTR
pla
sta PTR+1 ; PTR -> key lookup table
asl SAVE
rol SAVE+1 ; SAVE = WINDEX*2 (16-bit)
lda SAVE
clc
adc PTR
bcc +
clc
inc PTR+1
+ sta PTR
lda SAVE+1
adc PTR+1
sta PTR+1 ; PTR -> nth record key lookup table
lda (PTR), y
pha
iny
lda (PTR), y
tay
pla ; A/Y -> nth key in store
rts
@slowpath
jsr incptr2 ; PTR -> first record
bne @next ; always branches
- jsr stepptr
@next
lda SAVE
@ -243,7 +281,6 @@ okvs_nth
bne -
jsr incptr
+LD16 PTR
ldx #0
rts
;------------------------------------------------------------------------------

View File

@ -104,8 +104,6 @@ PREFRTS rts
; gGlobalPrefsStore must be initialized (this is done in 4cade.init)
; out: A/Y = address of pref value
; $WINDEX = index of pref value in passed store
; (if OKVS parameter is 0, no validation occurs and X=0 and Z=1 on exit,
; some callers rely on this behavior, so don't change it!)
; PARAM clobbered
; PTR clobbered
; SRC clobbered