ORG $5000 PSGLASTCMD EQU $FF PSGSTEPDIVIDER EQU $FE PSGNOCHANGE EQU $FD ; Followed by one byte of counter. PSGBEGINLOOP_INFINITE EQU $FC ; NOT USED YET PSGBEGINLOOP_FINITE EQU $FB ; NOT USED YET PSGENDLOOP EQU $FA ; NOT USED YET ; $FFF8 IRQ Handler ; $FFF6 FIRQ Handler EXPORT SET_TIMER_HOOK EXPORT REMOVE_TIMER_HOOK EXPORT CAPTURE_PSG_ONESTEP EXPORT PSGDATAPTR EXPORT PSGENDPTR SET_TIMER_HOOK PSHS A,B,X,Y,U LEAU TIMERHOOK,PCR CMPU $FFF8 BEQ SET_TIMER_HOOK_DONE LDX $FFF8 STX DEFIRQADDR,PCR STU $FFF8 LEAX PSGDATA,PCR STX PSGDATAPTR,PCR STX PSGENDPTR,PCR LDA #PSGLASTCMD STA ,X STA LASTSTOREDCMD,PCR BSR READPSG SET_TIMER_HOOK_DONE PULS A,B,X,Y,U,PC REMOVE_TIMER_HOOK PSHS A,B,X,Y,U LDX DEFIRQADDR,PCR STX $FFF8 PULS A,B,X,Y,U,PC ; Read Reg0 to Reg0d to ,X READPSG LDA #0 READPSG_LOOP STA $FD0E ; PSG Register LDB #3 ; PSG Register Selection STB $FD0D CLRB ; PSG Register Selection end STB $FD0D ; Not sure if I can do CLR $FD0D LDB #1 ; PSG Register Read STB $FD0D LDB $FD0E STB ,X+ CLRB ; PSG Register Read end STB $FD0D ; Not sure if I can do CLR $FD0D ; By the way, Register Write is #2 INCA CMPA #13 BLE READPSG_LOOP RTS REGORDER FCB 0,1,2,3,4,5,6,7,8,9,$A,$D,$B,$C,$FF PUSHPSG LEAX NEWPSG,PCR LEAY LASTPSG,PCR LDA #16 PUSHPSGLOOP LDB ,X+ STB ,Y+ DECA BNE PUSHPSGLOOP RTS TIMERHOOK BSR CAPTURE_PSG_ONESTEP LDX DEFIRQADDR,PCR JMP ,X CAPTURE_PSG_ONESTEP PSHS A,B,X,Y,U,CC ORCC #$50 STA $FD0F LDX CALLCOUNTER,PCR LEAX 1,X STX CALLCOUNTER,PCR ; I really want to check if it is from PLAY command. ; But, if I read $FD03, flag looks to be cleared. ; LDA $FD03 ; BITA #4 ; BEQ NOT_A_TIMER ; ; LDX TIMERCOUNTER,PCR ; LEAX 1,X ; STX TIMERCOUNTER,PCR ; ;NOT_A_TIMER BSR PUSHPSG LEAX NEWPSG,PCR BSR READPSG LDX PSGENDPTR,PCR CLR REGIDX,PCR RECORDPSG_ONESTEP_LOOP LDA REGIDX,PCR LEAU REGORDER,PCR LDA A,U LEAU NEWPSG,PCR LEAY LASTPSG,PCR LDB A,U CMPB A,Y BEQ RECORDPSG_NOCHANGE STA ,X+ STA LASTSTOREDCMD,PCR STB ,X+ RECORDPSG_NOCHANGE INC REGIDX,PCR LDA REGIDX,PCR CMPA #13 BLE RECORDPSG_ONESTEP_LOOP CMPX PSGENDPTR,PCR BEQ RECORDPSG_NOCHANGE_FOR_THIS_STEP ; Some changes in this step. LDB #PSGSTEPDIVIDER STB ,X+ STB LASTSTOREDCMD,PCR LDB #PSGLASTCMD STB ,X STX PSGENDPTR,PCR BRA RECORDPSG_ENDSTEP RECORDPSG_NOCHANGE_FOR_THIS_STEP LDA #PSGNOCHANGE CMPA LASTSTOREDCMD,PCR BEQ RECORDPSG_INC_CTR LDB #PSGSTEPDIVIDER CMPB LASTSTOREDCMD,PCR BNE RECORDPSG_NOCHANGE_FOR_THIS_STEP_WRITE CMPB -1,X ; Just in case. Am I that a good programmer? BNE RECORDPSG_NOCHANGE_FOR_THIS_STEP_WRITE LEAX -1,X ; Cancel last divider. RECORDPSG_NOCHANGE_FOR_THIS_STEP_WRITE STA ,X+ STA LASTSTOREDCMD,PCR LDB #1 STB ,X+ LDB #PSGLASTCMD STB ,X STX PSGENDPTR,PCR BRA RECORDPSG_ENDSTEP RECORDPSG_INC_CTR LDA -1,X INCA BEQ RECORDPSG_INC_CTR_OVERFLOW STA -1,X BRA RECORDPSG_ENDSTEP RECORDPSG_INC_CTR_OVERFLOW LDA #PSGNOCHANGE STA ,X+ STA LASTSTOREDCMD,PCR LDB #1 STB ,X+ LDB #PSGLASTCMD STB ,X STX PSGENDPTR,PCR RECORDPSG_ENDSTEP ; To capture re-writing of the same value, ; Reset some registers. ; Do I need to reset these registers every time? ;LDB #$1F ;LDA #8 ;BSR WRITE_TO_PSG ;LDA #9 ;BSR WRITE_TO_PSG ;LDA #$0A ;BSR WRITE_TO_PSG ; If register 13(0x0D) is the trigger of the envelope, ; volume registers shouldn't have to be reset for every tone. ; Apparently it's good without re-recording the volume registers. ; If, writing to register 13(0x0D) is the trigger, ; do we need to record all writing to 0B and 0C? ; CLRB ; LDA #$0B ; BSR WRITE_TO_PSG ; LDA #$0C ; BSR WRITE_TO_PSG ; Looks like I don't need to re-assign 0B and 0C, either. LDB #$FF LDA #$0D BSR WRITE_TO_PSG LEAX NEWPSG,PCR LBSR READPSG LDA $FD0F PULS A,B,X,Y,U,CC,PC REGIDX FCB 0 DEFIRQADDR FDB 0 CALLCOUNTER FDB 0 TIMERCOUNTER FDB 0 TERMINATOR FDB $EEFF PSGDATAPTR FDB PSGDATA PSGENDPTR FDB PSGDATA LASTSTOREDCMD FCB 0 FDB $8182 NEWPSG RZB 16 FDB $8384 LASTPSG RZB 16 FDB $8586 WRITE_TO_PSG PSHS A,B STA $FD0E ; PSG Register LDA #3 ; PSG Register Selection STA $FD0D CLR $FD0D ; PSG Register Selection end STB $FD0E LDA #2 ; PSG Write STA $FD0D CLR $FD0D PULS A,B,PC ORG $8000 PSGDATA ; STORE TO URA_RAM