.include "routines/main.h" .section "qd16cmd" semifree /* processes commands from qd16 microcontroller. communicates using physical rom adresses $00:0000(ACK), $00:0001(CMD), $00:0000(DAT) check for open bus before processing any commands */ QD16CommandPoll: php sep #$20 lda.w Qd16Flags bit.b #%100 bne QD16CommandPollCancel ;cancel manual command polling if irq-com mode is enabled jsr QD16CommandHandler QD16CommandPollCancel: plp rts QD16CommandHandler: php rep #$31 lda.l QD16McCommand ;get data first(in case the mc is just about to steal the bus again) sta.b tmp lda.l QD16McHandshake ;has microcontroller disabled rom access for snes?(reading open bus returns differing values here) cmp.l QD16OpenBusMirror bne QD16OpenBus sep #$20 cmp.b #QD16McAck bne QD16OpenBus ;either open bus or the mc hasn't written any new command yet lda.b tmp bit.b #$f8 ;valid command present?(max number of commands is 8) bne QD16OpenBus ;if any of the upper 5 bits are set, command is invalid lda.b #QD16SnesAck sta.l $c00000 ;tell mc that data has been received ;handshake complete, process data rep #$31 lda.b tmp pha and.w #$7 ;8 commands max asl a tax pla jsr (QD16CmdLUT,x) ;execute command QD16OpenBus: plp rts QD16CmdLUT: .dw QD16GetBankCount .dw QD16EnableIrqCom .dw QD16UpdateLoadPercentage .dw QD16FadeOut .dw QD16DrawHeader .dw QD16CmdVoid .dw QD16CmdVoid .dw QD16CmdVoid QD16CmdVoid: rts ;this can be triggered by an explicit mc-command. apart from that, it's also triggered when mc reports bank 0 has been uploaded. QD16DrawHeader: rts QD16EnableIrqCom: rep #$31 lda.l QD16RamIrq ;did mc copy irq-vector to correct location in rom? cmp.l QD16RomIrq ; beq QD16EnableIrqVectorOk ;debug lda.w #$adba ;clear mc-ack, signalize error, don't enter irq-mode sta.l QD16McHandshake rts QD16EnableIrqVectorOk: sep #$20 lda.b #1 sta.w IrqRoutineNumber lda.b #%100 ora.w Qd16Flags sta.w Qd16Flags ;set "enable irq-com"-flag rts ;input:x,header position in bank QD16CheckHeaderValid: php sep #$20 lda.w Qd16Flags bit.b #%10 bne QD16CheckHeaderNoHirom ;skip header drawing if a valid header has been found before rep #$31 lda.l RomVectorReset ;reset vector bpl QD16CheckHeaderNoLorom lda.l RomHeaderMap ;rom map, lorom? lsr a bcs QD16CheckHeaderNoLorom lda.l RomHeaderSize ;rom size and.w #$ff cmp.w #$7 ;smaller than 4mbit? bcc QD16CheckHeaderNoLorom cmp.w #$e ;bigger than 64mbit? bcs QD16CheckHeaderNoLorom ldx.w #LoromOffset ;header found jsr QD16CheckTitle bcc QD16CheckHeaderNoLorom sep #$20 lda.b #%10 ora.w Qd16Flags sta.w Qd16Flags ;set "header found, title printed"-flag plp sec rts QD16CheckHeaderNoLorom: rep #$31 lda.l RomVectorReset+HiromOffset ;reset vector high byte bpl QD16CheckHeaderNoHirom lda.l RomHeaderMap+HiromOffset ;rom map, lorom? lsr a bcc QD16CheckHeaderNoHirom lda.l RomHeaderSize+HiromOffset ;rom size and.w #$ff cmp.w #$7 ;smaller than 4mbit? bcc QD16CheckHeaderNoHirom cmp.w #$e ;bigger than 64mbit? bcs QD16CheckHeaderNoHirom ldx.w #HiromOffset ;header found jsr QD16CheckTitle bcc QD16CheckHeaderNoHirom sep #$20 lda.b #%10 ora.w Qd16Flags sta.w Qd16Flags ;set "header found, title printed"-flag plp sec rts QD16CheckHeaderNoHirom: plp clc rts ;input:x,16bit:lo/hirom pointer. ;checks if bytes are within ranges $20-$7f and $a7-$df(kana) QD16CheckTitle: php phx sep #$20 ldy.w #0 QD16CheckTitleLoop: ;check if chars are in ASCII/kana range and return null if any invalid ones are found. lda.l RomHeaderTitle,x cmp.b #$20 bcc QD16CheckTitleVoid ;is bigger than $20 cmp.b #$df+1 bcs QD16CheckTitleVoid ;is between $20 and $df bpl QD16CheckTitleCharOk ;is between $80 and $df cmp.b #$a7 bcc QD16CheckTitleVoid ;is between $a7 and $df QD16CheckTitleCharOk: inx ;is between $a7 and $df or between $20 and $7f iny cpy.w #21 bne QD16CheckTitleLoop plx ;title is ok, ready to print plp sec rts QD16CheckTitleVoid: plx ;title is not present/contains bad chars plp clc rts QD16GetBankCount: sep #$20 xba sta.w QD16BankCount lda.b #%1 ora.w Qd16Flags sta.w Qd16Flags ;set "rom upload commenced"-flag rts QD16UpdateLoadPercentage: sep #$20 xba cmp.b #101 bcc QD16UpdateLoadPercentageNoOver lda.b #100 QD16UpdateLoadPercentageNoOver: cmp.w PercentageBuff beq QD16UpdateLoadPercentageNoUpdate sta.w PercentageBuff rep #$31 lda.w #2 ;print percentage bar jsr VwfCreateTextbox QD16UpdateLoadPercentageNoUpdate: sep #$20 lda.b #%1 ora.w Qd16Flags sta.w Qd16Flags ;set "rom upload commenced"-flag rts /* ? = loadstat 100 = bankcount */ QD16UpdateLoadstatus: sep #$20 xba sta.l $4202 ;current banks*100 lda.b #100 sta.l $4203 nop nop nop nop rep #$31 lda.l $4216 sta.l $4204 sep #$20 lda.w QD16BankCount ;divide by 100 sta.l $4206 nop ;wait some cycles for division to finish nop nop nop nop nop nop nop rep #$31 lda.l $4214 sta.w Qd16LoadProgress QD16DivErr: rts QD16Cmd2: rts QD16FadeOut: sep #$20 jsr PalEffectInit lda.b #13 jsr PalEffectCreate rts .ends