pitch-dark/src/glue.zinfo.a

244 lines
6.7 KiB
Plaintext

;license:MIT
;(c) 2018 by 4am
;
; glue code to load and call ZINFO, the On Beyond Z-Machine! saved game parser
;
; Public functions
; - LoadSavedGameInfo
;
; Public variables
; - gSavedGamesStore
; - gSavedGamesSlotsInUse
;
; TODO move these to a ZINFO_MLI kind of separate file
zinfo_base = $2000
zinfo_maxslots = 8
name_offset = 0 ;1+37 bytes, a zero-length name is an empty record
time_offset = 42 ;1+8 bytes ("12:01 pm")
score_offset = 51 ;1+6 bytes (-12345)
moves_offset = 58 ;1+5 bytes (12345)
date_offset = 64 ;1+10 bytes ("10/10/2099")
zinfo_recordlen= 75 ;bytes
gSavedGamesStore
!word $FDFD ; set in LoadGameInfo
gSavedGamesSlotsInUse
!byte $FD ; set in LoadSavedGameInfo
;------------------------------------------------------------------------------
; LoadSavedGameInfo
; load ZINFO, call it with the current game, and parse the results
;
; in: current ProDOS prefix is the same as the PITCH.DARK file
; out: none
;------------------------------------------------------------------------------
LoadSavedGameInfo
jsr okvs_init
!word gSavedGamesStore
stz gSavedGamesSlotsInUse
jsr LoadFile ; load ZINFO.SYSTEM at $2000
!word kZINFOFilename
!word kSystemAddress
!word kProDOSFileBuffer
bcc +
jmp SoftBell
+ jsr SetStartupPathToCurrentVersionOfCurrentGame
jsr kSystemAddress ; call ZINFO (despite being a .SYSTEM program, it returns via RTS)
+LDADDR zinfo_base
+STAY ZPTR
ldx #0
@zParseLoop
+LDAY ZPTR
pha
phy
phx
jsr ResetPath
lda (ZPTR)
beq @branchToNextSlot ; no saved game in this slot
inc gSavedGamesSlotsInUse ; update number of slots in use (separate from length of store)
+LDAY ZPTR
jsr AddToPathWithHighBit ; add location information
ldx #0 ; count elements to print (there can be 0-3 of them)
jsr @queryTime
beq +
inx
+ jsr @queryScore
beq +
inx
+ jsr @queryMoves
beq +
inx
+ jsr @queryDate
beq +
inx
+ stx @tempX+1
plx
ply
pla
pha
phy
phx
+STAY ZPTR
@tempX ldx #0 ; self-modified
cpx #0 ; to allow branch-linking from above
@branchToNextSlot
beq @saveAndMoveToNextSlot; only location, nothing more to print
phx
+LDADDR kLeftParen
jsr AddToPathWithHighBit ; add ' ('
jsr @queryTime
beq @noTime
+LDAY ZPTR
jsr AddToPathWithHighBit ; add time information
; execution falls through here
plx
dex
beq @doneState
phx
+LDADDR kSlash
jsr AddToPathWithHighBit ; add '/' because we have more to print
@noTime
jsr @queryScore
beq @noScore
+LDAY ZPTR
jsr AddToPathWithHighBit ; add score information
; execution falls through here
plx
dex
beq @doneState
phx
+LDADDR kSlash
jsr AddToPathWithHighBit ; add '/' because we have more to print
@noScore
jsr @queryMoves
beq @noMoves
+LDAY ZPTR
jsr AddToPathWithHighBit ; add moves information
; execution falls through here
plx
dex
beq @doneState
phx
+LDADDR kSlash
jsr AddToPathWithHighBit ; add '/' because we have more to print
@noMoves
jsr @queryDate
beq @noDate
plx
+LDAY ZPTR
jsr AddToPathWithHighBit ; add date information
; execution falls through here
@noDate
@doneState
+LDADDR kRightParen
jsr AddToPathWithHighBit ; add ')'
+LDADDR kNullByte
jsr AddToPath ; add 0x00
; execution falls through here
@saveAndMoveToNextSlot
plx
phx
txa
ora #$30
sta kSlotNumber
lda gPathname
beq +
lda #9
+ sta kSlotName ; set length of key (0 if value is empty, otherwise 9)
jsr okvs_append ; add this key/value to saved games store (used by ResumeDialog)
!word gSavedGamesStore
!word kSlotName ; key = printable short label, or empty string if slot is unused
!word gPathname ; value = printable long label, or empty string if slot is unused
!byte 0
plx
ply
pla
clc
adc #zinfo_recordlen
bcc +
iny
+
+STAY ZPTR ; ZPTR -> start of next ZINFO record
inx
cpx #zinfo_maxslots
bcs +
jmp @zParseLoop
+ rts
@queryTime
lda ZPTR
clc
adc #time_offset-name_offset
sta ZPTR
bcc +
inc ZPTR+1
+ ; ZPTR -> ZINFO time field (length-prefixed string, may be empty string if no time)
lda (ZPTR)
rts
@queryScore
lda ZPTR
clc
adc #score_offset-time_offset
sta ZPTR
bcc +
inc ZPTR+1
+ ; ZPTR -> ZINFO score field (length-prefixed string, may be empty string if no score)
lda (ZPTR)
rts
@queryMoves
lda ZPTR
clc
adc #moves_offset-score_offset
sta ZPTR
bcc +
inc ZPTR+1
+ ; ZPTR -> ZINFO moves field (length-prefixed string, may be empty string if no moves)
lda (ZPTR)
rts
@queryDate
lda ZPTR
clc
adc #date_offset-moves_offset
sta ZPTR
bcc +
inc ZPTR+1
+ ; ZPTR -> ZINFO date field (length-prefixed string, may be empty string if no date)
lda (ZPTR)
rts
kZINFOFilename
!byte 12
!raw "ZINFO.SYSTEM"
kSlotName
!byte 9
!text " Slot "
kSlotNumber
!text "x:",0 ; ends with null byte on purpose
kLeftParen
!byte 2
!text " ("
kSlash
!byte 1
!text "/"
kRightParen
!byte 1
!text ")"
kNullByte
!byte 1,0