backup and restore stack, refactor Reenter

This commit is contained in:
4am 2019-06-23 14:24:09 -04:00
parent b7387d19f9
commit 971e7a6606
8 changed files with 145 additions and 117 deletions

View File

@ -12,56 +12,56 @@ RELBASE=$2000
!source "src/constants.a"
!source "src/macros.a"
; first-run initialization, relocates code to language card and continues from Main
; first-run initialization, relocates code to language card and jumps
; to |Reenter|
!source "src/4cade.init.a"
FirstMover
!pseudopc RELBASE {
Reenter ; self-running demos should call this to exit back to 4cade
;------------------------------------------------------------------------------
; Reenter
; This is the primary entry point for returning to the launcher from anywhere.
; - Self-running demos call this when the user presses a key or when the demo
; cycles ends naturally.
; - It is set as the reset vector, so the user can play a game then press
; Ctrl-Reset to return to the launcher and choose another.
; - It also functions as a reset vector while the launcher is running.
; - It is also called on program startup, after the first-run initialization.
;
; When execution reaches this point, we may have previously backed up the stack
; and stack pointer, in which case it is now our job to restore it and return
; to the caller. This allows magic like 'JSR PlayGame' then continuing once the
; JSR returns.
;
; If there is no stack to restore, this exits via SearchMode.
;
; in: no parameters
; out: see above
;------------------------------------------------------------------------------
Reenter
cld
cli
+READ_RAM2_WRITE_RAM2
jsr CloseHandles ; close any open handles to restore ProRWTS state to original
jsr CloseHandles ; close any open handles to restore ProRWTS
; (also switches to LC RAM bank 1)
jsr SaveScreenHoles ; restore screen hole contents from saved copy
Main
ldx #$FF
txs
ldx #5
- lda Prelaunch,x ; copy reset vector code (switches to LC RAM and jumps to |Reenter|)
jsr SaveOrRestoreScreenHoles ; restore original screen hole contents
RestoreStackNextTime
clc ; SMC
bcc SearchMode ; not an unconditional branch because code
; might change the 'clc' just before it
; If we fall through to here, it's because we backed up the stack and
; stack pointer and wanted this routine to restore it and return to
; caller.
lda #$18 ; reset to 'clc' opcode so we don't try to
sta RestoreStackNextTime ; restore the same stack twice
ldx #1
- lda $DF00,x ; restore stack
sta $100,x
dex
bpl -
inx
stx $3F2 ; set up reset vectors
inx
stx $3F3
txa
eor #$A5
sta $3F4
jsr BlankHGR
@loop
lda $C000
cmp #$8D
bne +
jsr Play
+ cmp #$9B
bne +
lda Mode
eor #$80
sta Mode
+
bit $C010
bit Mode
bpl +
jsr MegaAttractMode
jmp @loop
+
jsr SearchMode
jmp @loop
Mode
!byte $00
bne -
ldx $DF00 ; restore stack pointer
txs
rts
; these routines will only be called after relocating to language card
!source "src/ui.search.mode.a"
@ -80,6 +80,7 @@ Mode
!source "src/parse.games.a"
!source "src/ui.sound.a"
!source "src/ui.font.a"
Mode !byte $00
gGlobalPrefsStore
!word $D000 ; address of first okvs store
!word Reenter ; NMI vector ($FFFA-B)

View File

@ -76,7 +76,7 @@ ProRWTSBuffer
OneTimeSetup
lda MachineStatus
sta oldstatus
jsr SaveScreenHoles ; save initial copy of screen hole content
jsr SaveOrRestoreScreenHoles ; save initial copy of screen hole content
lda #$91
sta holepatch ; enable restoring of copy from now on
lda hddopendir+1 ; save current directory as 'root'
@ -107,10 +107,55 @@ OneTimeSetup
!word gGamesListStore
!word ldrlo2 ; (ldrlo2) points to last load address, so $8000
jsr okvs_len
!word gGamesListStore
sta SAVE
; calculate and update visible game count (3-digit decimal number as ASCII string)
ldy #0
@outer
lda #0
pha
@inner
lda SAVE
cmp kPowersOfTen,y
bcc @digitDone
sbc kPowersOfTen,y
sta SAVE
lda SAVE+1
sbc #0
sta SAVE+1
pla
adc #0
pha
jmp @inner
@digitDone
pla
ora #$30
sta UILine2_GameCount,y
iny
cpy #$03
bcc @outer
bit $C010 ; clear keyboard strobe so we don't mistakenly think we just tried to run something
jmp Main ; continue execution from LC RAM bank
ldx #5
- lda Prelaunch,x ; copy reentry wrapper to bottom of stack
sta $100,x ; (many self-running demos use this)
dex
bpl -
inx
stx $3F2 ; page 3 reset vector to ($100)
inx
stx $3F3
ldx #$A4
stx $3F4
jmp $100 ; continue execution from LC RAM bank
kGameListConfFile
!byte 10
!text "GAMES.CONF"
kPowersOfTen
!byte 100
!byte 10
!byte 1

View File

@ -14,7 +14,8 @@
; D000..D3FF - ProRWTS data
; D400..D5FF - ProRWTS code
; D600..D9FF - HGR font data
; DA00..DFFF - unused
; DA00..DEFF - unused
; DF00..DFFF - backup of stack during self-running demos
;------------------------------------------------------------------------------
; soft switches

View File

@ -4,26 +4,23 @@
; Functions to launch games and self-running demos
;
; Public functions
; - Launch
; - PlayGameFromSearch
; - PlayGameFromAttract
;
; Public variables
; - SelectedIndex ; [byte] numeric index in gGamesStore of currently selected game in search mode
; - gCurrentAttractIndex ; [byte] numeric index in gAttractModeStore of current Mega-Attract Module
; - gCurrentlyVisibleSlideshowIndex ; [byte] numeric index in gSlideshowStore of currently visible slideshow picture
; (only valid during slideshows, not updated once a key is pressed)
Play
lda Mode
bmi @playFromAttract
@playFromSearch
lda SelectedIndex
sta @selectedIndex
PlayGameFromSearch
jsr okvs_nth
!word gGamesListStore
@selectedIndex
SelectedIndex
!byte $FD ; SMC
jmp Go
@playFromAttract
PlayGameFromAttract
+LDADDR kAttractModeConfFile
jsr SetPath
jsr LoadFile ; load attract-mode configuration file at $8000
@ -114,6 +111,17 @@ Go
sta ProDOS_prefix
copy_prelaunch
+READ_RAM2_WRITE_RAM2
ldx #1
- lda $100,x
sta $DF00,x ; backup stack
inx
bne -
tsx ; backup stack pointer
stx $DF00
lda #$38 ; 'sec' opcode
sta RestoreStackNextTime ; tell |Reenter| to restore stack
ldx #(End_Prelaunch-Prelaunch-1)
- lda Prelaunch,x ; copy pre-launch code to main memory
sta $100,x
@ -136,7 +144,7 @@ copy_prelaunch
; in: none
; out: exits via JMP (ldrlo2), which is expected to exit via JMP |Prelaunch|
; (not here, but wherever it was copied to in main memory) or by
; manually enabling LC RAM bank 1 then JMP |Reenter|
; manually enabling LC RAM then JMP |Reenter|
;------------------------------------------------------------------------------
Prelaunch ; this runs from main memory
; entry point used by some self-running demos

View File

@ -355,7 +355,7 @@ ProDOS_prefix=$bfd0
end_promote
;------------------------------------------------------------------------------
; SaveScreenHoles
; SaveOrRestoreScreenHoles
; preserve screen hole contents across demo execution
; to avoid crashing later on disk access
;
@ -364,7 +364,7 @@ end_promote
; all registers clobbered
;------------------------------------------------------------------------------
SaveScreenHoles
SaveOrRestoreScreenHoles
lda #4
sta namhi
ldx #0

View File

@ -9,7 +9,6 @@
; Public variables
; - InputLength
; - InputBuffer
; - SelectedIndex
; - MatchCount
; - BestMatchScore
; - BestMatchIndex
@ -28,8 +27,6 @@ InputLength
!byte 0
InputBuffer
!text " "
SelectedIndex
!byte $FF
MatchCount
!byte 0
BestMatchScore

View File

@ -26,6 +26,8 @@
; memory, unused portions of the stack page, all registers, all flags)
;------------------------------------------------------------------------------
MegaAttractMode
jsr BlankHGR
+LDADDR kAttractModeConfFile
jsr SetPath
jsr LoadFile ; load attract-mode configuration file at $8000
@ -86,10 +88,15 @@ gAttractIndex
jsr @RunNextAttractModule
lda $C000
bmi +
bpl @jmpattract
cmp #$8D
bne @jmpsearch
jsr PlayGameFromAttract
; execution falls through here
@jmpattract
jmp MegaAttractMode
+
rts
@jmpsearch
jmp SearchMode
@RunNextAttractModule
ldy #1
@ -127,7 +134,7 @@ gAttractIndex
+LOAD_FILE_IMM @key
jsr SaveScreenHoles ; save screen hole contents in case game changes them
jsr SaveOrRestoreScreenHoles ; save screen hole contents in case game changes them
jmp copy_prelaunch
@NotDemo ; slideshow module or screenshot

View File

@ -1,7 +1,7 @@
;license:MIT
;(c) 2018 by 4am
;
; Search Mode - incrementally search game catalog
; Search Mode - UI to search game catalog, see game assets, and launch games
;
; Public functions
; - SearchMode
@ -20,14 +20,14 @@ InputDispatchTable
!word OnLaunch
SearchMode
jsr Home
lda #0
sta OffscreenPage
sta InputLength
jsr _UpdateGameCount
jsr OnInputChanged ; draw default UI on HGR page 1
ldx #0
stx OffscreenPage
dex
stx SelectedIndex ; no game selected
txs
jsr Home ; clear screen
lda #$FF
jsr OnInputChanged ; draw UI on HGR page 1, set $C054
bit $C052
bit $C057
bit $C050
@ -110,18 +110,18 @@ InputDispatch
sta @j+2
pla ; restore key pressed
@j jsr $FDFD ; SMC
jmp _SearchModeInputLoop
bcc +
jmp SearchMode
+ jmp _SearchModeInputLoop
OnClear
bit $C010
ldx InputLength
bne +
jsr _CoverFade
pla ; Esc with no input exits search mode
pla ; and switches to attract mode
rts
+ ldx #0
jsr _CoverFade ; Esc with no input switches to
jmp MegaAttractMode ; mega-attract mode
+ ldx #0 ; Esc with input clears the input
stx InputLength
bit $C010
jmp OnInputChanged
OnBack
@ -137,9 +137,11 @@ OnLaunch
ldx SelectedIndex
cpx #$FF
beq +
pla ; Return exits search mode
pla ; and launches game
+ rts
jsr PlayGameFromSearch
sec ; tell caller to redraw UI
rts
+ clc
rts
OnSearch
ldx InputLength
@ -172,7 +174,9 @@ OnInputChanged
jsr _LoadCoverOffscreen
jsr _DrawSearchBarOffscreen
jmp _ShowOtherPage
jsr _ShowOtherPage
clc
rts
@findMatchingTitle
jsr ResetTextRank
@ -304,41 +308,6 @@ _ShowOtherPage
+ bit $C054 ; show page 1
rts
_UpdateGameCount
jsr okvs_len
!word gGamesListStore
sta SAVE
ldy #0
@outer
lda #0
pha
@inner
lda SAVE
cmp @powersOfTen,y
bcc @digitDone
sbc @powersOfTen,y
sta SAVE
lda SAVE+1
sbc #0
sta SAVE+1
pla
adc #0
pha
jmp @inner
@digitDone
pla
ora #$30
sta UILine2_GameCount,y
iny
cpy #$03
bcc @outer
rts
@powersOfTen
!byte 100
!byte 10
!byte 1
_ResetInputTimeout
; clobbers X, preserves A/Y
ldx #$16