;license:MIT ;(c) 2018-9 by 4am ; !cpu 6502 !to "build/LAUNCHER.SYSTEM",plain *=$2000 !ifndef RELBASE { RELBASE=$2000 } !source "src/constants.a" ; no code in these !source "src/macros.a" ; first-run initialization, relocates code to language card and jumps ; to |Reenter| !source "src/4cade.init.a" FirstMover !pseudopc RELBASE { ;------------------------------------------------------------------------------ ; 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: none ; out: see above ;------------------------------------------------------------------------------ Reenter cld cli jsr SwitchToBank2 jsr CloseHandles ; close any open handles to restore ProRWTS jsr SaveOrRestoreScreenHoles ; restore original screen hole contents ldx #5 - lda ResetVector,x ; copy reentry wrapper to bottom of stack sta $100,x ; (used as reset vector because ][+ always dex ; switches to ROM on Ctrl-Reset) bpl - inx stx $3F2 ; page 3 reset vector to ($100) inx stx $3F3 ldx #$A4 stx $3F4 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 #$F1 - lda $DF00,x ; restore stack sta $100,x inx bne - ldx $DFF0 ; restore stack pointer txs SwitchToBank1 +READ_RAM1_WRITE_RAM1 rts ; and return to caller ResetVector ; 6 bytes, copied to $100 +READ_RAM1_NO_WRITE jmp Reenter ; these routines will only be called after relocating to language card !source "src/ui.search.mode.a" !source "src/ui.browse.mode.a" !source "src/ui.overlay.a" !source "src/ui.offscreen.a" !source "src/ui.credits.a" !source "src/ui.attract.mode.a" !source "src/ui.attract.hgr.a" !source "src/ui.attract.dhgr.a" !source "src/ui.attract.shr.a" !source "src/ui.attract.gr.a" !source "src/ui.cheats.a" !source "src/prodos.path.a" !source "src/glue.launch.a" !source "src/glue.prorwts2.a" !source "src/okvs.a" !source "src/wait.a" !source "src/textrank.a" !source "src/parse.common.a" !source "src/parse.prefs.a" !source "src/glue.font.a" ; add new files above here so ui.common stays last !source "src/ui.common.a" gAttractModeStore gFXStore gDFXStore !word $6000 gSlideshowStore !word $0800 gGlobalPrefsStore !word $D100 gGamesListStore !word $FDFD ; SMC SwitchToBank2 +READ_RAM2_WRITE_RAM2 rts !word Reenter ; NMI vector ($FFFA-B) !word Reenter ; reset vector ($FFFC-D) !word Reenter ; IRQ vector ($FFFE-F) } LastMover !pseudopc $D600 { !source "src/ui.font.data.a" !source "src/ui.font.a" !source "src/prodos.impl.a" LCRAM2_END = * !if * > $DFEF { !error "code is too large: ends at ", * } } EvenLasterMover !if RELBASE = $2000 { !ifdef PASS2 { } else { ;PASS2 !set PASS2=1 !warn "LCRAM2 ends at ", LCRAM2_END !warn "RELBASE = ", $10000 - (LastMover - FirstMover) } }