******************************** * MSXLaunch - An APMSX Program * * Selector * * by ballmerpeak * ******************************** LST OFF TYP $FF ORG $2000 * relocate from $2000 to $9000 LDY #11 ; #pgs to relocate to $9000 LDX #00 ]RELO1 LDA RSTART+3,X ]RELO2 STA $9000,X INX BNE ]RELO1 DEY BEQ RSTART INC ]RELO1+2 INC ]RELO2+2 JMP ]RELO1 RSTART JMP $9000 ORG $9000 LDA #$00 ; set up a reset vector for ourselves STA $3F2 LDA #$90 STA $3F3 EOR #$A5 STA $3F4 LDA PATHSET BNE RSC JSR SETPATH RSC LDA #OPATH STA OPARMS+2 LDA #00 ; more initializations for reset STA MSXSTAT STA SPEED JSR DOSLOAD JMP CONT DOSLOAD LDA #00 STA OREF STA RREF STA CREF JSR $BF00 DB $C8 DW OPARMS BCS DOSERRX LDA OREF STA RREF STA CREF LDA #00 STA RCNT STA RCNT+1 JSR $BF00 DB $CA DW RPARMS BCS DOSERRX JSR $BF00 DB $CC DW CPARMS RTS DOSERRX JMP DOSERR CONT JSR COUNT JSR DRAWUI JSR DRAWA ; draw the > indicator JSR READCONFIG LDX #02 LDA SPEED JSR REGSET ; initialize z80 speed LDA OFFSET BEQ C2 TAX ]SEEK TXA PHA JSR NEXT_MSXDIR PLA TAX DEX BNE ]SEEK C2 JSR DRAWPAGE KEYLOOP LDA $C000 BPL KEYLOOP STA $C010 AND #$7F CMP #'Q' BEQ QUITX CMP #$71 ; lowercase q BEQ QUITX CMP #'S' BEQ SETSLOTX CMP #$73 ; lowercase s BEQ SETSLOTX CMP #'Z' BEQ SETSPEEDX CMP #$7A ; lowercase z BEQ SETSPEEDX CMP #$0A ; down arrow BEQ DNARROWX CMP #$0B ; up arrow BEQ UPARROWX CMP #$0D BEQ ENTER CMP #'A BEQ TOGGLE CMP #$61 ; lowercase a BEQ TOGGLE JMP KEYLOOP DNARROWX JMP DNARROW UPARROWX JMP UPARROW SETSPEEDX JMP SETSPEED SETSLOTX JMP SETSLOT QUITX JMP QUIT TOGGLE JSR $300 LDA MSXSTAT BNE WASON INC MSXSTAT JMP T22 WASON DEC MSXSTAT T22 JSR DRAWMSX JMP KEYLOOP ENTER JSR RESET_MSXDIR LDA YPOS CLC ADC OFFSET TAX INX ]SEEK TXA PHA JSR NEXT_MSXDIR PLA TAX DEX BNE ]SEEK LDX #00 ]CPL LDA CURRENT_FILE,X BEQ DNCP STA DOSFILE+1,X INX JMP ]CPL DNCP STX DOSFILE LDA MSXSTAT ; stop msx if running BEQ MSXOK JSR $300 DEC MSXSTAT JSR DRAWMSX MSXOK LDX #00 LDA MFLAGS STA MAPPER JSR REGSET JSR DRAWBITS * LDX #07 ; register #07 * STA $C097 * JSR REGSET ; send reset signal LDA #BIOS STA OPARMS+2 JSR DOSLOAD LDA CURRENT_FILE2 BEQ NNM LDA #16 JMP NNM2 NNM LDA #$05 NNM2 LDX #1 JSR REGSET ; set page 5 LDA #DOSFILE STA OPARMS+2 JSR DOSLOAD LDA CURRENT_FILE2 BEQ LAUNCH LDX #00 ]XF TXA PHA CLC ADC #18 LDX #1 JSR REGSET PLA TAX PHA LDA EXTRA_FILES,X STA $00 LDA EXTRA_FILES+1,X STA $01 LDY #00 ]CPP LDA ($00),Y BEQ XC2 STA DOSFILE+1,Y INY JMP ]CPP XC2 CPY #00 BEQ NOMORE STY DOSFILE JSR DOSLOAD PLA TAX INX INX CPX #14 BNE ]XF NOMORE PLA LAUNCH LDA #00 JSR $300 INC MSXSTAT JSR DRAWMSX LDX #6 LDA #0 JSR REGSET ; generate int pulse JMP KEYLOOP LDA #OPATH STA OPARMS+2 JSR DOSLOAD JSR RESET_MSXDIR JMP KEYLOOP REGSET STA $C090,X RTS CARDSET STA $C100 RTS DNARROW LDA $C061 BMI PAGEDN LDA YPOS CMP #16 BEQ UARET PHA INC YPOS JSR DRAWA PLA JSR UNDRAW JMP KEYLOOP UARET JSR NEXT_MSXDIR BCC UAR2 CLC JMP KEYLOOP UAR2 INC OFFSET JSR SCROLLUP LDX #17 JSR DRAWTITLE JMP KEYLOOP PAGEDN LDA YPOS CMP #16 BEQ DPAGEDN LDX #16 STX YPOS PHA JSR DRAWA PLA JSR UNDRAW JMP KEYLOOP DPAGEDN LDA OFFSET CLC ADC #17 BCS TOOFAR CMP TOTAL2 BGE TOOFAR JSR DRAWPAGE DEX TXA CLC ADC OFFSET STA OFFSET JMP KEYLOOP TOOFAR LDA TOTAL2 STA OFFSET JMP DP3 UPARROW LDA $C061 BMI PAGEUP LDA YPOS BEQ DARET PHA DEC YPOS JSR DRAWA PLA JSR UNDRAW JMP KEYLOOP DARET LDA OFFSET BEQ DR2 DEC OFFSET JSR SCROLLDN JSR RESET_MSXDIR LDX OFFSET INX ]SEEK TXA PHA JSR NEXT_MSXDIR PLA TAX DEX BNE ]SEEK LDX #1 JSR DRAWTITLE LDX #16 ]SLP2 TXA PHA JSR NEXT_MSXDIR PLA TAX DEX BNE ]SLP2 DR2 JMP KEYLOOP PAGEUP LDA YPOS BEQ DPAGEUP LDX #00 STX YPOS PHA JSR DRAWA PLA JSR UNDRAW JMP KEYLOOP DPAGEUP LDA OFFSET SEC SBC #17 BCS DP1 LDA #00 DP1 STA OFFSET CLC DP3 JSR RESET_MSXDIR LDX OFFSET BEQ DP2 ]SEEK2 TXA PHA JSR NEXT_MSXDIR PLA TAX DEX BNE ]SEEK2 DP2 JSR DRAWPAGE JMP KEYLOOP DRAWA LDA YPOS TAX INX ; like inc a but 6502 TXA ASL TAX LDA TLOOK,X STA $00 LDA TLOOK+1,X STA $01 LDY #00 LDA #">" STA ($00),Y RTS UNDRAW TAX INX TXA ASL TAX LDA TLOOK,X STA $00 LDA TLOOK+1,X STA $01 LDY #00 LDA #"!" STA ($00),Y RTS * count total records COUNT LDA #00 STA TOTAL JSR RESET_MSXDIR CNT2 JSR NEXT_MSXDIR BCS CNT1 INC TOTAL JMP CNT2 CNT1 JSR RESET_MSXDIR LDA TOTAL SEC SBC #17 STA TOTAL2 RTS * A ProDOS error occurred DOSERR LDA #ERRDOS STA $05 JMP DRAWERR DRAWERR LDA #10 ASL PHA TAX LDA TLOOK,X CLC ADC #7 STA $00 LDA TLOOK+1,X STA $01 LDA #ERRBOX1 STA $03 JSR DRAWSTR PLA PHA TAX LDA TLOOK+2,X CLC ADC #7 STA $00 LDA TLOOK+3,X STA $01 LDA #ERRBOX2 STA $03 JSR DRAWSTR INC $00 INC $00 LDA $04 STA $02 LDA $05 STA $03 JSR DRAWSTR PLA PHA TAX LDA TLOOK+4,X CLC ADC #7 STA $00 LDA TLOOK+5,X STA $01 LDA #ERRBOX3 STA $03 JSR DRAWSTR PLA TAX LDA TLOOK+6,X CLC ADC #7 STA $00 LDA TLOOK+7,X STA $01 LDA #ERRBOX1 STA $03 JSR DRAWSTR ]ERW LDA $C000 BPL ]ERW STA $C010 JMP QUIT SETSPEED LDA SPEED TAX INX CPX #2 BEQ SET4 CPX #3 BEQ SET4 CPX #7 BGE SETW SETX STX SPEED JSR DRAWSPEED LDA MSXSTAT BEQ JUSTDO1 JSR $300 ; if msx was running, stop it first LDA SPEED ; then set the speed, then restart it LDX #2 JSR REGSET JSR $300 JUSTDO1 LDA SPEED LDX #2 JSR REGSET JMP KEYLOOP SET4 LDX #4 JMP SETX SETW LDX #0 JMP SETX SETSLOT LDA SLOT TAX INX CPX #8 BEQ SLOT1 STX SLOT ]SSS JSR DRAWSLOT JSR SETSL2 JMP KEYLOOP SETSL2 LDA SLOT ASL ASL ASL ASL CLC ADC #$80 STA REGSET+1 LDA #$A9 ; set up STA $Cx00 at $300 STA $300 LDA #$00 STA $301 LDA #$8D STA $302 LDA #$00 STA $303 LDA SLOT ORA #$C0 STA $304 LDA #$60 STA $305 RTS SLOT1 LDA #1 STA SLOT JMP ]SSS QUIT JSR $BF00 DB $65 DW QPARMS * Draw the UI * First, clear the screen DRAWUI LDX #00 SCR TXA PHA ASL TAX LDA TLOOK,X STA $00 LDA TLOOK+1,X STA $01 LDY #00 LDA #$A0 LN STA ($00),Y INY CPY #40 BNE LN PLA TAX INX CPX #24 BNE SCR * Next, draw bounding box around the screen LDA #'+'+128 STA $400 STA $400+39 STA $7D0 STA $7D0+39 STA $550 STA $550+39 LDA #'-'+128 LDX #01 TOP STA $400,X INX CPX #39 BNE TOP LDX #01 BOT STA $7D0,X INX CPX #39 BNE BOT LDX #01 DIV STA $550,X INX CPX #39 BNE DIV LDX #01 SIDES TXA PHA ASL TAX LDA TLOOK,X STA $00 LDA TLOOK+1,X STA $01 LDY #00 LDA #'!'+128 STA ($00),Y LDY #39 STA ($00),Y PLA TAX SKIP INX CPX #18 BEQ SKIP CPX #23 BNE SIDES * draw credits string at bottom LDA #$D3 STA $00 LDA #$07 STA $01 LDA #STR_CRED STA $03 JSR DRAWSTR * draw prompts LDA #$D2 STA $00 LDA #$06 STA $01 LDA #STR_MAPPER STA $03 JSR DRAWSTR LDA #$58 STA $00 LDA #$06 STA $01 LDA #STR_APMSX STA $03 JSR DRAWSTR LDA #$D4 STA $00 LDA #$05 STA $01 LDA #STR_Z80 STA $03 JSR DRAWSTR LDA #$EE STA $00 LDA #$05 STA $01 LDA #STR_SLOT STA $03 JSR DRAWSTR JSR DRAWSLOT JSR DRAWMSX JSR DRAWSPEED JSR DRAWBITS RTS * Draw current Mapper Bits DRAWBITS LDA MAPPER AND #01 BEQ NO_0 LDA #'0' STA $06DF JMP DRAW_1 NO_0 LDA #'0'+128 STA $06DF DRAW_1 LDA MAPPER AND #02 BEQ NO_1 LDA #'1' STA $06E0 JMP DRAW_2 NO_1 LDA #'1'+128 STA $06E0 DRAW_2 LDA MAPPER AND #04 BEQ NO_2 LDA #'2' STA $06E1 JMP DRAW_3 NO_2 LDA #'2'+128 STA $06E1 DRAW_3 LDA MAPPER AND #08 BEQ NO_3 LDA #'3' STA $06E2 JMP DRAW_4 NO_3 LDA #'3'+128 STA $06E2 DRAW_4 LDA MAPPER AND #16 BEQ NO_4 LDA #'4' STA $06E3 JMP DRAW_7 NO_4 LDA #'4'+128 STA $06E3 DRAW_7 LDA MAPPER AND #$80 BEQ NO_7 LDA #'7' STA $06E6 RTS NO_7 LDA #'7'+128 STA $06E6 RTS * Draw current MSX speed DRAWSPEED LDA #$DF STA $00 LDA #$05 STA $01 LDA SPEED ASL TAX LDA Z80OPTS,X STA $02 LDA Z80OPTS+1,X STA $03 JMP DRAWSTR * Draw current MSX status DRAWMSX LDA #$5F STA $00 LDA #$06 STA $01 LDA MSXSTAT BEQ STOPPED LDA #AP_RUN STA $03 JMP DRAWSTR STOPPED LDA #AP_STOP STA $03 JMP DRAWSTR * Draw current slot number DRAWSLOT LDA SLOT CLC ADC #48+128 STA $05EE+6 RTS * $(00) - output address * $(02) - string address DRAWSTR LDY #00 DRAWLP LDA ($02),Y BEQ DONE STA ($00),Y INY BNE DRAWLP DONE RTS * reset MSXDIR cursor to $1000 RESET_MSXDIR LDA #00 STA MSXCURSOR STA MSXINDEX LDA #$10 STA MSXCURSOR+1 RTS CONFIGERROR LDA #ERRCONF STA $05 JMP DRAWERR * read first (config) record from MSXDIR READCONFIG JSR RESET_MSXDIR LDA MSXCURSOR STA $00 LDA MSXCURSOR+1 STA $01 LDY #00 LDA ($00),Y CMP #'%' BNE CONFIGERROR INY INY LDA ($00),Y SBC #$30 STA SLOT INY INY LDA ($00),Y SBC #$30 STA MAPPER INY INY INY INY ; now at start of first filename TYA CLC ADC MSXCURSOR STA MSXCURSOR BCC CRET INC MSXCURSOR+1 CRET JSR DRAWSLOT JSR DRAWBITS JSR SETSL2 RTS * get next non-hidden MSXDIR file and clear carry * OR return with set carry flag cause nothing left NEXT_MSXDIR LDA MSXCURSOR STA $00 LDA MSXCURSOR+1 STA $01 LDY #00 LDA ($00),Y CMP #'!' ; if first char is ! that's end of file BNE NEOF ; else start copying infos JMP EOF NEOF CMP #'%' ; if we're on the config record, skip it BNE FCOPY ]SKIP INY LDA ($00),Y CMP #'!' BEQ EOF CMP #'^' BNE ]SKIP INY INY FCOPY LDA #CURRENT_FILE STA $03 JSR DIRCOPY ; copy current filename to cursor LDA #CURRENT_TITLE STA $03 JSR DIRCOPY ; copy current title to cursor LDA #00 STA CURRENT_FILE2 STA CURRENT_FILE3 STA CURRENT_FILE4 STA CURRENT_FILE5 STA CURRENT_FILE6 STA CURRENT_FILE7 STA CURRENT_FILE8 LDA #$01 STA MFLAGS LDA ($00),Y CMP #'^' BEQ NMRET LDA #$09 STA MFLAGS ; copy additional megarom parts LDX #00 ]MR LDA EXTRA_FILES,X STA $02 LDA EXTRA_FILES+1,X STA $03 INX INX TXA PHA JSR DIRCOPY PLA TAX LDA ($00),Y CMP #'^' BEQ NMRET CMP #'+' BEQ HPLUS JMP ]MR HPLUS LDA #$11 STA MFLAGS INY INY NMRET INY INY TYA CLC ADC MSXCURSOR STA MSXCURSOR BCC NMRET2 INC MSXCURSOR+1 CLC NMRET2 RTS EOF SEC RTS * preserve Y, $00/$01 DIRCOPY LDA $02 STA DCA+1 LDA $03 STA DCA+2 ]DC LDA ($00),Y CMP #$0D BEQ DCRET DCA STA CURRENT_FILE LDA DCA+1 CLC ADC #$01 STA DCA+1 BCC DC2 INC DCA+2 DC2 INY JMP ]DC DCRET INY LDA DCA+1 STA DCB+1 LDA DCA+2 STA DCB+2 LDA #00 DCB STA CURRENT_FILE RTS * draw last parsed title to screen * x = title number (0-17) DRAWTITLE TXA ASL TAX LDA TLOOK,X STA $00 LDA TLOOK+1,X STA $01 LDX #00 LDY #01 ]DTL LDA CURRENT_TITLE,X BEQ EOT ORA #$80 STA ($00),Y INX CPX #38 BEQ DTR INY JMP ]DTL EOT LDA #$A0 ]DSL STA ($00),Y INY CPY #39 BLT ]DSL DTR RTS * draw the current page of selections DRAWPAGE LDX #01 ]DLP TXA PHA JSR NEXT_MSXDIR PLA TAX BCS EARLY PHA JSR DRAWTITLE PLA TAX INX CPX #18 BLT ]DLP EARLY RTS * scroll the current selections up one line SCROLLUP LDX #1 ]SCU TXA PHA ASL TAX LDA TLOOK,X STA $02 LDA TLOOK+1,X STA $03 LDA TLOOK+2,X STA $00 LDA TLOOK+3,X STA $01 LDY #1 ]LNU LDA ($00),Y STA ($02),Y INY CPY #39 BNE ]LNU PLA TAX INX CPX #17 ; don't copy the divider line up, it flickers BNE ]SCU RTS * scroll the current selections down one line SCROLLDN LDX #16 ]SCD TXA PHA ASL TAX LDA TLOOK,X STA $00 LDA TLOOK+1,X STA $01 LDA TLOOK+2,X STA $02 LDA TLOOK+3,X STA $03 LDY #1 ]SDL LDA ($00),Y STA ($02),Y INY CPY #39 BNE ]SDL PLA TAX DEX BNE ]SCD RTS * look at $280 to see where we came from * then set ProDOS path if we can/have to * so we can find MSXDIR file SETPATH INC PATHSET ; don't bother doing this twice LDX #00 LDY #00 ]SP1 LDA $281,X CMP #'/' BNE SPP2 INY STX $00 SPP2 INX CPX $280 BNE ]SP1 * $00 has offset of last / and y has slash count CPY #00 BEQ SPRET ; just leave if no path info was found LDA $00 STA $280 ; cut $280 string down to just the prefix JSR $BF00 DB $C6 DW PPARMS BCC SPRET JMP DOSERR SPRET RTS * Yes I'm using a lookup table for text line starting addresses TLOOK DW $400 DW $480 DW $500 DW $580 DW $600 DW $680 DW $700 DW $780 DW $428 DW $4A8 DW $528 DW $5A8 DW $628 DW $6A8 DW $728 DW $7A8 DW $450 DW $4D0 DW $550 DW $5D0 DW $650 DW $6D0 DW $750 DW $7D0 * Parameters for ProDOS SET_PREFIX call PPARMS DB 1 DW $280 * Parameters for ProDOS QUIT call QPARMS DB 4 DB 0 DW 0 DB 0 DW 0 * Parameters for ProDOS OPEN call OPARMS DB 03 DW OPATH DW $9E00 ; $200 byte buffer for a sector OREF DB 00 OPATH STR 'MSXDIR' BIOS STR 'MSX.ROM' * Parameters for ProDOS READ call RPARMS DB 04 RREF DB 00 DW $1000 DW $FFFF RCNT DW $0000 * Parameters for ProDOS CLOSE call CPARMS DB 01 CREF DB 00 * UI Strings STR_Z80 DB 26 ASC "80 Speed:",00 STR_SLOT DB 19 ASC "lot:",00 STR_APMSX DB 1 ASC "PMSX:",00 STR_MAPPER ASC "Mapper Bits: 01234567",00 STR_CRED ASC " MSXLaunch 0.1b - ballmerpeak.org ",00 * Error strings ERRBOX1 ASC "+-------------------------+",00 ERRBOX2 ASC "! !",00 ERRBOX3 ASC "! Press Any Key To Quit !",00 ERRDOS ASC "ProDOS Error",00 ERRCONF ASC "Configuration Error",00 * Z80 Speed Option Strings Z80OPTS DW SPD_38MHZ ; 0 DW SPD_76MHZ ; 1 DW 0 ; 2 - not used DW 0 ; 3 - not used DW SPD_4MHZ ; 4 DW SPD_8MHZ ; 5 DW SPD_16MHZ ; 6 SPD_38MHZ ASC "3.58MHz",00 SPD_76MHZ ASC "7.16MHz",00 SPD_4MHZ ASC "4MHz ",00 SPD_8MHZ ASC "8MHz ",00 SPD_16MHZ ASC "16MHz ",00 * APMSX Options APMSXOPTS DW AP_RUN DW AP_STOP AP_RUN ASC "Running",00 AP_STOP ASC "Stopped",00 * Current Settings SLOT DB 01 MSXSTAT DB 00 SPEED DB 00 MAPPER DB 01 YPOS DB 00 ; 0-16 position of > selector OFFSET DB 00 ; 0-x scroll offset MFLAGS DB 00 ; mapper flags to set on launch TOTAL DB 00 ; total records TOTAL2 DB 00 ; total records - 1page PATHSET DB 00 ; 00 if prefix not set yet * MSXDIR cursor etc MSXCURSOR DW 0 ; iteration cursor: offset into msxdir MSXINDEX DB 0 ; title index 0-255 SCREEN_INDEX DB 0 ; screen top index 0-255 CURRENT_TITLE DS 81 ; "10 Yard Fight (198x)" CURRENT_FILE DS 17 ; "A10YARDF.MSX" DOSFILE DS 17 ; filename for prodos EXTRA_FILES DW CURRENT_FILE2 DW CURRENT_FILE3 DW CURRENT_FILE4 DW CURRENT_FILE5 DW CURRENT_FILE6 DW CURRENT_FILE7 DW CURRENT_FILE8 CURRENT_FILE2 DS 17 ; Mega-ROM parts 2-8 CURRENT_FILE3 DS 17 CURRENT_FILE4 DS 17 CURRENT_FILE5 DS 17 CURRENT_FILE6 DS 17 CURRENT_FILE7 DS 17 CURRENT_FILE8 DS 17 SAV MSXLAUNCH