;license:MIT ;(c) 2018-9 by 4am ; ; Functions to launch games and self-running demos ; ; Public functions ; - PlayGameFromSearch ; - PlayGameFromAttract ; - Prelaunch ; - Launch ; ; Public variables ; - 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) !zone { PlayGameFromSearch stx @gameIndex jsr okvs_nth !word gGamesListStore @gameIndex !byte $FD ; SMC jmp .Go PlayGameFromAttract jsr LoadAndParseAttractModeConf jsr okvs_nth ; get filename of current attract-mode module !word gAttractModeStore gCurrentAttractIndex !byte $FD ; set in MegaAttractMode +STAY @key jsr okvs_get !word gAttractModeStore @key !word $FDFD ; SMC +STAY PTR ldy #1 lda (PTR),y and #$0F bne @playFromSlideshow ; we reached here by pressing during a self-running demo, ; which means that @key points to the filename of the game we want to play +LDAY @key jmp .Go @playFromSlideshow ; we reached here by pressing during a slideshow ; gSlideshowStore is still in memory, and gCurrentlyVisibleSlideshowIndex ; is the index into gSlideshowStore of the picture that is being displayed jsr okvs_nth !word gSlideshowStore gCurrentlyVisibleSlideshowIndex !byte $FD ; set in HGRTitleCallback, HGRActionCallback, DHGRTitleCallback +STAY @sskey +STAY @sskey2 jsr okvs_get !word gGamesListStore @sskey !word $FDFD ; SMC bcs + +LDAY @sskey jmp .Go + ; if the key is not found, try getting the value of the current record ; from gSlideshowStore and using that instead ; (some games have multiple action screenshots, value points to the key in gGamesListStore) jsr okvs_get !word gSlideshowStore @sskey2 !word $FDFD ; SMC bcc .Go rts .Go +STAY PTR ldx #1 ; construct path to game's startup file sec ; which is always /X/game/game !byte $2c -- pha clc php ldy #0 lda (PTR), y tay iny sty @runlength+1 ldy #0 lda #'X' sta ProDOS_prefix+1 lda #'/' - inx sta ProDOS_prefix, x iny lda (PTR), y @runlength cpy #$D1 ; SMC bne - txa plp bcs -- stx ProDOS_prefix +LDADDR ProDOS_prefix jsr SetPath jsr LoadFile ; load the game startup file pla sta ProDOS_prefix ; set 'root' directory to the path part ; of the game startup file we just loaded ; so games can load other files without ; knowing which directory they're in ; execution falls through here Launch +READ_RAM2_WRITE_RAM2 ldx #1 - lda $100,x sta $DF00,x ; back up stack inx bne - tsx ; back up stack pointer stx $DF00 lda #$38 ; 'sec' opcode to tell |Reenter| to sta RestoreStackNextTime ; restore the stack and stack pointer ldx #(End_Prelaunch-Prelaunch-1) - lda Prelaunch,x ; copy pre-launch code to main memory sta $100,x dex bpl - ldx #(end_promote-promote-1) - lda promote,x ; copy ProDOS shim to main memory sta $bf00,x dex bpl - jmp $106 ; jump to pre-launch code ;------------------------------------------------------------------------------ ; Prelaunch ; code to set up and launch third-party code (either a self-running demo or ; an actual game) ; THIS IS NOT A FUNCTION. DO NOT CALL THIS DIRECTLY. ; must be run from main memory ; contains multiple entry points ; ; in: for first entry point, none ; for second entry point, the game must already be loaded in memory ; and ldrlo2/ldrhi2 must be the game entry point ; 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 then JMP |Reenter| ;------------------------------------------------------------------------------ Prelaunch ; entry point to return to launcher (used by self-running demos) lda $C088 jmp Reenter ; entry point to launch game (must be Prelaunch+6) +READ_ROM_NO_WRITE lda ldrlo2 ; set up game entry point in stack page ldy ldrhi2 ; (last load address - 1) sec sbc #$01 bcs + dey + +STAY $1FE ldx #0 ; wipe zero page txa - sta $00,x inx bne - lda #$65 ; Initialize 'random' seed. These are sta $4E ; arbitrary values. Some games like Pooyan lda #$02 ; require these to be non-zero. Ask me sta $4F ; how long that one took to debug. jsr $FE89 ; Initialize machine like a cold boot. jsr $FE93 ; Many games assume a 'clean slate' and jsr $FE84 ; rely on zero page values set by these sta $C000 ; ROM routines, sta $C002 ; e.g. Wavy Navy just prints out text via sta $C004 ; $FDED and expects it to work. Having it sta $C00C ; print all null characters is amusing, in sta $C00E ; a quiet way, but not really helpful. jsr $FB2F jsr $FC58 bit $C010 ldx #$FD ; Jump to game entry point via stack pop. txs rts End_Prelaunch }