Procedura playera dla edytora Arkos Tracker 2 (*.AKY)
uruchomienie:
LDY #.lo(Main_Subsong0_Linker) LDX #.hi(Main_Subsong0_Linker) JSR AKY_Init @ WAIT JSR AKY_Play JMP @- ICL 'AKYPlayer.asm' ICL 'SONG.AKY'
AKYPlayer SONARI & POKEY MAX (below)
; Arkos Tracker 2 / AKYPlayer - V1.0 (03.2021) - SONARI version ; CODE: xxl AYR EQU $D560 ; SONari AYD EQU $D561 ; SONari ZP EQU $80 AKY_RegisterBlock EQU ZP+0 ; word AKY_TOKEN EQU ZP+2 ; byte / doesn't have to be on ZP AKY_PtLinker EQU ZP+3 ; word AKY_PatternFrameCounter EQU ZP+5 ; word / doesn't have to be on ZP AKY_ChannelC1_WaitBeforeNextRegisterBlock EQU ZP+7 ; byte / keep order. / doesn't have to be on ZP AKY_ChannelC1_PtRegisterBlock EQU ZP+8 ; word / doesn't have to be on ZP AKY_ChannelC2_WaitBeforeNextRegisterBlock EQU ZP+10 ; byte / doesn't have to be on ZP AKY_ChannelC2_PtRegisterBlock EQU ZP+11 ; word / doesn't have to be on ZP AKY_ChannelC3_WaitBeforeNextRegisterBlock EQU ZP+13 ; byte / doesn't have to be on ZP AKY_ChannelC3_PtRegisterBlock EQU ZP+14 ; word / doesn't have to be on ZP AKY_ChannelC1_PtTrack EQU ZP+16 ; word ; keep order. AKY_ChannelC2_PtTrack EQU ZP+18 ; word AKY_ChannelC3_PtTrack EQU ZP+20 ; word AKY_ChannelC1_RegisterBlockLineState EQU ZP+22 ; byte / doesn't have to be on ZP . AKY_ChannelC2_RegisterBlockLineState EQU ZP+23 ; byte / doesn't have to be on ZP AKY_ChannelC3_RegisterBlockLineState EQU ZP+24 ; byte / doesn't have to be on ZP ; +0 - PLAY ; +3 - INIT JMP AKY_Play AKY_Init STY AKY_PtLinker STX AKY_PtLinker+1 LDX #$01 STX AKY_ChannelC1_RegisterBlockLineState STX AKY_ChannelC2_RegisterBlockLineState STX AKY_ChannelC3_RegisterBlockLineState STX AKY_PatternFrameCounter DEX STX AKY_PatternFrameCounter+1 RTS ; ===================================== AKY_Play LDA AKY_PatternFrameCounter BNE @+ DEC AKY_PatternFrameCounter+1 @ DEC AKY_PatternFrameCounter BNE @+ LDY AKY_PatternFrameCounter+1 BEQ AKY_PatternFrameCounter_Over @ JMP AKY_Channel1_WaitBeforeNextRegisterBlock AKY_PatternFrameCounter_Over LDA (AKY_PtLinker),Y STA AKY_PatternFrameCounter INY LDA (AKY_PtLinker),Y STA AKY_PatternFrameCounter+1 ORA AKY_PatternFrameCounter BNE AKY_LinkerNotEndSong INY ; 0000 - JMP LDA (AKY_PtLinker),Y TAX INY LDA (AKY_PtLinker),Y STA AKY_PtLinker+1 STX AKY_PtLinker LDY #$00 BEQ AKY_PatternFrameCounter_Over ; RELOADED AKY_LinkerNotEndSong @ INY LDA (AKY_PtLinker),Y STA AKY_ChannelC1_PtTrack-2,Y ; -2 CPY #$07 BCC @- TYA ; 7+c=1 +8 for 1xPSG ADC AKY_PtLinker STA AKY_PtLinker BCC @+ INC AKY_PtLinker+1 @ LDA #01 STA AKY_ChannelC1_WaitBeforeNextRegisterBlock STA AKY_ChannelC2_WaitBeforeNextRegisterBlock STA AKY_ChannelC3_WaitBeforeNextRegisterBlock ; ===================================== AKY_Channel1_WaitBeforeNextRegisterBlock DEC AKY_ChannelC1_WaitBeforeNextRegisterBlock BNE AKY_Channel1_RegisterBlock_Process LDA #$01 ;c=1 initial state STA AKY_ChannelC1_RegisterBlockLineState LDY #00 @ LDA (AKY_ChannelC1_PtTrack),Y STA AKY_ChannelC1_WaitBeforeNextRegisterBlock,Y INY CPY #$03 BCC @- LDA #$02 ; C=1 ADC AKY_ChannelC1_PtTrack ; +3 STA AKY_ChannelC1_PtTrack BCC AKY_Channel1_RegisterBlock_Process INC AKY_ChannelC1_PtTrack+1 AKY_Channel1_RegisterBlock_Process DEC AKY_ChannelC2_WaitBeforeNextRegisterBlock BNE AKY_Channel2_RegisterBlock_Process LDA #$01 ;c=1 initial state STA AKY_ChannelC2_RegisterBlockLineState LDY #00 @ LDA (AKY_ChannelC2_PtTrack),Y STA AKY_ChannelC2_WaitBeforeNextRegisterBlock,Y INY CPY #$03 BCC @- LDA #$02 ; C=1 ADC AKY_ChannelC2_PtTrack ; +3 STA AKY_ChannelC2_PtTrack BCC AKY_Channel2_RegisterBlock_Process INC AKY_ChannelC2_PtTrack+1 AKY_Channel2_RegisterBlock_Process DEC AKY_ChannelC3_WaitBeforeNextRegisterBlock BNE AKY_Channel3_RegisterBlock_Process LDA #$01 ;c=1 initial state STA AKY_ChannelC3_RegisterBlockLineState LDY #00 @ LDA (AKY_ChannelC3_PtTrack),Y STA AKY_ChannelC3_WaitBeforeNextRegisterBlock,Y INY CPY #$03 BCC @- LDA #$02 ; C=1 ADC AKY_ChannelC3_PtTrack ; +3 STA AKY_ChannelC3_PtTrack BCC AKY_Channel3_RegisterBlock_Process INC AKY_ChannelC3_PtTrack+1 AKY_Channel3_RegisterBlock_Process ; ===================================== LDA #$38 ; 0011 1000 STA AKY_MixerControlEnable LDX #$00 ;Channel 1 LDY #$00 LSR AKY_ChannelC1_RegisterBlockLineState JSR AKY_ReadRegisterBlock TYA CLC ADC AKY_RegisterBlock STA AKY_ChannelC1_PtRegisterBlock LDA AKY_RegisterBlock+1 ADC #$00 STA AKY_ChannelC1_PtRegisterBlock+1 INX ;Channel 2 LDY #$03 LSR AKY_ChannelC2_RegisterBlockLineState JSR AKY_ReadRegisterBlock TYA CLC ADC AKY_RegisterBlock STA AKY_ChannelC2_PtRegisterBlock LDA AKY_RegisterBlock+1 ADC #$00 STA AKY_ChannelC2_PtRegisterBlock+1 INX ;Channel 3 LDY #$06 LSR AKY_ChannelC3_RegisterBlockLineState JSR AKY_ReadRegisterBlock TYA CLC ADC AKY_RegisterBlock STA AKY_ChannelC3_PtRegisterBlock LDA AKY_RegisterBlock+1 ADC #$00 STA AKY_ChannelC3_PtRegisterBlock+1 LDA #$07 STA AYR LDA AKY_MixerControlEnable STA AYD LDA #$06 STA AYR LDA AKY_NoiseGeneratorControl STA AYD LDA #11 STA AYR LDA AKY_EnvelopePeriodControl STA AYD LDA #12 STA AYR LDA AKY_EnvelopePeriodControl+1 STA AYD LDA AKY_EnvelopeShapeControl CMP AKY_EnvelopeShapeControlOld BEQ @+ STA AKY_EnvelopeShapeControlOld LDX #13 STX AYR STA AYD @ RTS ; end ; ===================================== AKY_ReadRegisterBlock LDA AKY_ChannelC1_PtRegisterBlock,Y STA AKY_RegisterBlock LDA AKY_ChannelC1_PtRegisterBlock+1,Y STA AKY_RegisterBlock+1 LDY #$00 LDA (AKY_RegisterBlock),Y ; type ; 00 = no software no hardware. ; 01 = software only. ; 10 = hardware only. ; 11 = software and hardware. INY @ BCS @+ ; INITIAL STATE JMP AKY_RRB_NonInitialState @ LSR @ BCS AKY_RRB_IS_SoftwareOnlyOrSoftwareAndHardware LSR @ BCS AKY_RRB_IS_HardwareOnly ; ===================================== AKY_RRB_IS_NoSoftwareNoHardware ; 7 6 5 4 3 2 1 0 ; 0 v v v v n t t ; n = noise? ; v = volume LSR @ PHA BCC AKY_RRB_NIS_NoSoftwareNoHardware_ReadVolume LDA (AKY_RegisterBlock),Y STA AKY_NoiseGeneratorControl INY LDA AKY_MixerControlEnableNoise,X AND AKY_MixerControlEnable STA AKY_MixerControlEnable AKY_RRB_NIS_NoSoftwareNoHardware_ReadVolume LDA AKY_AmplitudeControl,X STA AYR PLA STA AYD LDA AKY_MixerControlEnableTone,X ORA AKY_MixerControlEnable STA AKY_MixerControlEnable RTS ; ===================================== AKY_RRB_IS_HardwareOnly ; 7 6 5 4 3 2 1 0 ; e e e e n r t t ; r = retrig? ; n = noise? ; e = envelope LSR @ BCC AKY_RRB_IS_HO_NoRetrig ROR AKY_EnvelopeShapeControlOld ; C=1 AKY_RRB_IS_HO_NoRetrig LSR @ PHA BCC AKY_RRB_IS_HO_NoNoise LDA (AKY_RegisterBlock),Y STA AKY_NoiseGeneratorControl INY LDA AKY_MixerControlEnableNoise,X AND AKY_MixerControlEnable STA AKY_MixerControlEnable AKY_RRB_IS_HO_NoNoise PLA STA AKY_EnvelopeShapeControl LDA (AKY_RegisterBlock),Y STA AKY_EnvelopePeriodControl INY LDA (AKY_RegisterBlock),Y STA AKY_EnvelopePeriodControl+1 INY LDA AKY_MixerControlEnableTone,X ORA AKY_MixerControlEnable STA AKY_MixerControlEnable LDA AKY_AmplitudeControl,X STA AYR LDA #$10 STA AYD RTS ; ===================================== AKY_RRB_IS_SoftwareOnlyOrSoftwareAndHardware LSR @ BCS AKY_RRB_IS_SoftwareAndHardware AKY_RRB_IS_SoftwareOnly ; 7 6 5 4 3 2 1 0 ; 0 v v v v n t t ; n = noise? ; v = volume. LSR @ PHA BCC AKY_RRB_IS_SoftwareOnly_NoNoise LDA (AKY_RegisterBlock),Y STA AKY_NoiseGeneratorControl INY LDA AKY_MixerControlEnableNoise,X AND AKY_MixerControlEnable STA AKY_MixerControlEnable AKY_RRB_IS_SoftwareOnly_NoNoise LDA AKY_AmplitudeControl,X STA AYR PLA STA AYD LDA AKY_ToneGeneratorControlL,X STA AYR LDA (AKY_RegisterBlock),Y STA AYD INY LDA AKY_ToneGeneratorControlH,X STA AYR LDA (AKY_RegisterBlock),Y STA AYD INY RTS ; ===================================== AKY_RRB_IS_SoftwareAndHardware ; 7 6 5 4 3 2 1 0 ; e e e e n r t t ; r = retrig? ; n = noise? ; e = envelope LSR @ BCC AKY_RRB_IS_SAH_NoRetrig ROR AKY_EnvelopeShapeControlOld ; C=1 AKY_RRB_IS_SAH_NoRetrig LSR @ PHA BCC AKY_RRB_IS_SAH_NoNoise LDA (AKY_RegisterBlock),Y STA AKY_NoiseGeneratorControl INY LDA AKY_MixerControlEnableNoise,X AND AKY_MixerControlEnable STA AKY_MixerControlEnable AKY_RRB_IS_SAH_NoNoise PLA STA AKY_EnvelopeShapeControl LDA AKY_ToneGeneratorControlL,X STA AYR LDA (AKY_RegisterBlock),Y STA AYD INY LDA AKY_ToneGeneratorControlH,X STA AYR LDA (AKY_RegisterBlock),Y STA AYD INY LDA AKY_AmplitudeControl,X STA AYR LDA #$10 STA AYD LDA (AKY_RegisterBlock),Y STA AKY_EnvelopePeriodControl INY LDA (AKY_RegisterBlock),Y STA AKY_EnvelopePeriodControl+1 INY RTS ; ===================================== AKY_RRB_NIS_NoSoftwareNoHardware_Loop LDA (AKY_RegisterBlock),Y PHA INY LDA (AKY_RegisterBlock),Y STA AKY_RegisterBlock+1 PLA STA AKY_RegisterBlock LDY #$00 LDA (AKY_RegisterBlock),Y INY ; ===================================== AKY_RRB_NonInitialState ; t = type. ; 00 = no software no hardware. ; 01 = software only. ; 10 = hardware only. ; 11 = software and hardware. LSR @ BCS AKY_RRB_NIS_SoftwareOnlyOrSoftwareAndHardware LSR @ BCC @+ JMP AKY_RRB_NIS_HardwareOnly @ AKY_RRB_NIS_NoSoftwareNoHardwareOrLoop ; 7 6 5 4 3 2 1 0 ; n vv vv vv vv v 0 0 ; l ; v = new volume? If 1, vv is the volume. If 0, the vv flags are used for the possible loop. ; l = loop? Only relevant if v = 0. ; n = noise? Always 0 in case of loop. STA AKY_TOKEN AND #$03 CMP #$02 ;%10 loop BEQ AKY_RRB_NIS_NoSoftwareNoHardware_Loop LDA AKY_MixerControlEnableTone,X ORA AKY_MixerControlEnable STA AKY_MixerControlEnable LSR AKY_TOKEN BCC AKY_RRB_NIS_NoVolume LDA AKY_AmplitudeControl,X STA AYR LDA AKY_TOKEN AND #$0F STA AYD AKY_RRB_NIS_NoVolume LDA AKY_TOKEN AND #%00010000 BNE @+ RTS @ LDA (AKY_RegisterBlock),Y STA AKY_NoiseGeneratorControl INY LDA AKY_MixerControlEnableNoise,X AND AKY_MixerControlEnable STA AKY_MixerControlEnable RTS ; ===================================== AKY_RRB_NIS_SoftwareOnlyOrSoftwareAndHardware LSR @ BCC @+ JMP AKY_RRB_NIS_SoftwareAndHardware @ AKY_RRB_NIS_SoftwareOnly ; 7 6 5 4 3 2 1 0 ; mspnoise lsp v v v v 0 1 ; v = volume. ; mspnoise = new Most Significant byte of Period AND/OR noise. ; lsp = new Most Significant byte of Period? STA AKY_TOKEN LDA AKY_AmplitudeControl,X STA AYR LDA AKY_TOKEN AND #$0F STA AYD LDA AKY_TOKEN AND #%00010000 BEQ AKY_RRB_NIS_SoftwareOnly_NoLSP LDA AKY_ToneGeneratorControlL,X STA AYR LDA (AKY_RegisterBlock),Y STA AYD INY AKY_RRB_NIS_SoftwareOnly_NoLSP LDA AKY_TOKEN AND #%00100000 BNE @+ RTS @ ; 76543210 ; in pppp ; i = isNoise? If yes, open the noise channel. ; n = new Noise? If !isNoise, 0. ; p = MSB of period (encoded regardless its usefulness) LDA AKY_ToneGeneratorControlH,X STA AYR LDA (AKY_RegisterBlock),Y INY STA AYD ; AND #$0F ASL @ BCS @+ RTS @ ASL @ ; C LDA AKY_MixerControlEnableNoise,X AND AKY_MixerControlEnable STA AKY_MixerControlEnable BCS @+ RTS @ LDA (AKY_RegisterBlock),Y STA AKY_NoiseGeneratorControl INY RTS ; ===================================== AKY_RRB_NIS_HardwareOnly ; 7 6 5 4 3 2 1 0 ; lsp msp nr e e e 1 0 ; e = envelope. ; msp = new Most Significant byte of Period? ; lsp = new Most Significant byte of Period? ; nr = new noise or retrig? ASL @ STA AKY_EnvelopeShapeControl ; AND #$0F b0=0? PHA LDA AKY_MixerControlEnableTone,X ORA AKY_MixerControlEnable STA AKY_MixerControlEnable LDA AKY_AmplitudeControl,X STA AYR LDA #$10 STA AYD PLA ASL @ ASL @ STA AKY_TOKEN BCC AKY_RRB_NIS_HardwareOnly_NoLSB LDA (AKY_RegisterBlock),Y STA AKY_EnvelopePeriodControl INY AKY_RRB_NIS_HardwareOnly_NoLSB ASL AKY_TOKEN BCC AKY_RRB_NIS_HardwareOnly_NoMSB LDA (AKY_RegisterBlock),Y STA AKY_EnvelopePeriodControl+1 INY AKY_RRB_NIS_HardwareOnly_NoMSB ASL AKY_TOKEN BCS AKY_RRB_NIS_Hardware_Shared_NoiseOrRetrig_AndStop RTS ; ===================================== AKY_RRB_NIS_SoftwareAndHardware ; 7 6 5 4 3 2 1 0 ; rn ne mssp lssp mshp lshp 1 1 ; lshp = new Less Significant byte of Hardware Period? ; mshp = new Most Significant byte of Hardware Period? ; lssp = new Less Significant byte of Software Period? ; mssp = new Most Significant byte of Software Period? ; ne = new envelope? ; rn = retrig or noise/new noise? STA AKY_TOKEN LDA AKY_AmplitudeControl,X STA AYR LDA #$10 STA AYD LSR AKY_TOKEN BCC AKY_RRB_NIS_SAHH_AfterLSBH LDA (AKY_RegisterBlock),Y STA AKY_EnvelopePeriodControl INY AKY_RRB_NIS_SAHH_AfterLSBH LSR AKY_TOKEN BCC AKY_RRB_NIS_SAHH_AfterMSBH LDA (AKY_RegisterBlock),Y STA AKY_EnvelopePeriodControl+1 INY AKY_RRB_NIS_SAHH_AfterMSBH LSR AKY_TOKEN BCC AKY_RRB_NIS_SAHH_AfterLSBS LDA AKY_ToneGeneratorControlL,X STA AYR LDA (AKY_RegisterBlock),Y STA AYD INY AKY_RRB_NIS_SAHH_AfterLSBS LSR AKY_TOKEN BCC AKY_RRB_NIS_SAHH_AfterMSBS LDA AKY_ToneGeneratorControlH,X STA AYR LDA (AKY_RegisterBlock),Y STA AYD INY AKY_RRB_NIS_SAHH_AfterMSBS LSR AKY_TOKEN BCC AKY_RRB_NIS_SAHH_AfterEnvelope LDA (AKY_RegisterBlock),Y STA AKY_EnvelopeShapeControl INY AKY_RRB_NIS_SAHH_AfterEnvelope LSR AKY_TOKEN BCS @+ RTS @ AKY_RRB_NIS_Hardware_Shared_NoiseOrRetrig_AndStop ;76543210 ;ooooonir ;r = retrig? ;i = isNoise? If yes, open the noise channel. ;n = new Noise? If !isNoise, 0. ;o = noise (>0). LDA (AKY_RegisterBlock),Y INY LSR @ BCC AKY_RRB_NIS_S_NOR_NoRetrig ROR AKY_EnvelopeShapeControlOld ; C=1 AKY_RRB_NIS_S_NOR_NoRetrig LSR @ BCS @+ RTS @ PHA LDA AKY_MixerControlEnableNoise,X AND AKY_MixerControlEnable STA AKY_MixerControlEnable PLA LSR @ BCS @+ RTS @ STA AKY_NoiseGeneratorControl RTS ; ===================================== AKY_NoiseGeneratorControl .byte $00 AKY_EnvelopePeriodControl .byte $00,$00 AKY_EnvelopeShapeControl .byte $00 AKY_EnvelopeShapeControlOld .byte $00 AKY_MixerControlEnable .byte $00 AKY_ToneGeneratorControlL .byte 0,2,4 AKY_ToneGeneratorControlH .byte 1,3,5 AKY_AmplitudeControl .byte 8,9,10 AKY_MixerControlEnableTone .byte $01,$02,$04 AKY_MixerControlEnableNoise .byte %11110111,%11101111,%11011111
POKEY MAX version:
; Arkos Tracker 2 / AKYPlayer - V1.0 (06.2021) - POKEYMAX version ; CODE: xxl POKEYMAX EQU $D2A0 ZP EQU $80 AKY_RegisterBlock EQU ZP+0 ; word AKY_TOKEN EQU ZP+2 ; byte / doesn't have to be on ZP AKY_PtLinker EQU ZP+3 ; word AKY_PatternFrameCounter EQU ZP+5 ; word / doesn't have to be on ZP AKY_ChannelC1_WaitBeforeNextRegisterBlock EQU ZP+7 ; byte / keep order. / doesn't have to be on ZP AKY_ChannelC1_PtRegisterBlock EQU ZP+8 ; word / doesn't have to be on ZP AKY_ChannelC2_WaitBeforeNextRegisterBlock EQU ZP+10 ; byte / doesn't have to be on ZP AKY_ChannelC2_PtRegisterBlock EQU ZP+11 ; word / doesn't have to be on ZP AKY_ChannelC3_WaitBeforeNextRegisterBlock EQU ZP+13 ; byte / doesn't have to be on ZP AKY_ChannelC3_PtRegisterBlock EQU ZP+14 ; word / doesn't have to be on ZP AKY_ChannelC1_PtTrack EQU ZP+16 ; word ; keep order. AKY_ChannelC2_PtTrack EQU ZP+18 ; word AKY_ChannelC3_PtTrack EQU ZP+20 ; word AKY_ChannelC1_RegisterBlockLineState EQU ZP+22 ; byte / doesn't have to be on ZP . AKY_ChannelC2_RegisterBlockLineState EQU ZP+23 ; byte / doesn't have to be on ZP AKY_ChannelC3_RegisterBlockLineState EQU ZP+24 ; byte / doesn't have to be on ZP ; +0 - PLAY ; +3 - INIT JMP AKY_Play AKY_Init STY AKY_PtLinker STX AKY_PtLinker+1 LDX #$01 STX AKY_ChannelC1_RegisterBlockLineState STX AKY_ChannelC2_RegisterBlockLineState STX AKY_ChannelC3_RegisterBlockLineState STX AKY_PatternFrameCounter DEX STX AKY_PatternFrameCounter+1 RTS ; ===================================== AKY_Play LDA AKY_PatternFrameCounter BNE @+ DEC AKY_PatternFrameCounter+1 @ DEC AKY_PatternFrameCounter BNE @+ LDY AKY_PatternFrameCounter+1 BEQ AKY_PatternFrameCounter_Over @ JMP AKY_Channel1_WaitBeforeNextRegisterBlock AKY_PatternFrameCounter_Over LDA (AKY_PtLinker),Y STA AKY_PatternFrameCounter INY LDA (AKY_PtLinker),Y STA AKY_PatternFrameCounter+1 ORA AKY_PatternFrameCounter BNE AKY_LinkerNotEndSong INY ; 0000 - JMP LDA (AKY_PtLinker),Y TAX INY LDA (AKY_PtLinker),Y STA AKY_PtLinker+1 STX AKY_PtLinker LDY #$00 BEQ AKY_PatternFrameCounter_Over ; RELOADED AKY_LinkerNotEndSong @ INY LDA (AKY_PtLinker),Y STA AKY_ChannelC1_PtTrack-2,Y ; -2 CPY #$07 BCC @- TYA ; 7+c=1 +8 for 1xPSG ADC AKY_PtLinker STA AKY_PtLinker BCC @+ INC AKY_PtLinker+1 @ LDA #01 STA AKY_ChannelC1_WaitBeforeNextRegisterBlock STA AKY_ChannelC2_WaitBeforeNextRegisterBlock STA AKY_ChannelC3_WaitBeforeNextRegisterBlock ; ===================================== AKY_Channel1_WaitBeforeNextRegisterBlock DEC AKY_ChannelC1_WaitBeforeNextRegisterBlock BNE AKY_Channel1_RegisterBlock_Process LDA #$01 ;c=1 initial state STA AKY_ChannelC1_RegisterBlockLineState LDY #00 @ LDA (AKY_ChannelC1_PtTrack),Y STA AKY_ChannelC1_WaitBeforeNextRegisterBlock,Y INY CPY #$03 BCC @- LDA #$02 ; C=1 ADC AKY_ChannelC1_PtTrack ; +3 STA AKY_ChannelC1_PtTrack BCC AKY_Channel1_RegisterBlock_Process INC AKY_ChannelC1_PtTrack+1 AKY_Channel1_RegisterBlock_Process DEC AKY_ChannelC2_WaitBeforeNextRegisterBlock BNE AKY_Channel2_RegisterBlock_Process LDA #$01 ;c=1 initial state STA AKY_ChannelC2_RegisterBlockLineState LDY #00 @ LDA (AKY_ChannelC2_PtTrack),Y STA AKY_ChannelC2_WaitBeforeNextRegisterBlock,Y INY CPY #$03 BCC @- LDA #$02 ; C=1 ADC AKY_ChannelC2_PtTrack ; +3 STA AKY_ChannelC2_PtTrack BCC AKY_Channel2_RegisterBlock_Process INC AKY_ChannelC2_PtTrack+1 AKY_Channel2_RegisterBlock_Process DEC AKY_ChannelC3_WaitBeforeNextRegisterBlock BNE AKY_Channel3_RegisterBlock_Process LDA #$01 ;c=1 initial state STA AKY_ChannelC3_RegisterBlockLineState LDY #00 @ LDA (AKY_ChannelC3_PtTrack),Y STA AKY_ChannelC3_WaitBeforeNextRegisterBlock,Y INY CPY #$03 BCC @- LDA #$02 ; C=1 ADC AKY_ChannelC3_PtTrack ; +3 STA AKY_ChannelC3_PtTrack BCC AKY_Channel3_RegisterBlock_Process INC AKY_ChannelC3_PtTrack+1 AKY_Channel3_RegisterBlock_Process ; ===================================== LDA #$38 ; 0011 1000 STA AKY_MixerControlEnable LDX #$00 ;Channel 1 LDY #$00 LSR AKY_ChannelC1_RegisterBlockLineState JSR AKY_ReadRegisterBlock TYA CLC ADC AKY_RegisterBlock STA AKY_ChannelC1_PtRegisterBlock LDA AKY_RegisterBlock+1 ADC #$00 STA AKY_ChannelC1_PtRegisterBlock+1 INX ;Channel 2 LDY #$03 LSR AKY_ChannelC2_RegisterBlockLineState JSR AKY_ReadRegisterBlock TYA CLC ADC AKY_RegisterBlock STA AKY_ChannelC2_PtRegisterBlock LDA AKY_RegisterBlock+1 ADC #$00 STA AKY_ChannelC2_PtRegisterBlock+1 INX ;Channel 3 LDY #$06 LSR AKY_ChannelC3_RegisterBlockLineState JSR AKY_ReadRegisterBlock TYA CLC ADC AKY_RegisterBlock STA AKY_ChannelC3_PtRegisterBlock LDA AKY_RegisterBlock+1 ADC #$00 STA AKY_ChannelC3_PtRegisterBlock+1 LDA AKY_MixerControlEnable STA POKEYMAX+7 LDA AKY_NoiseGeneratorControl STA POKEYMAX+6 LDA AKY_EnvelopePeriodControl STA POKEYMAX+11 LDA AKY_EnvelopePeriodControl+1 STA POKEYMAX+12 LDA AKY_EnvelopeShapeControl CMP AKY_EnvelopeShapeControlOld BEQ @+ STA AKY_EnvelopeShapeControlOld STA POKEYMAX+13 @ RTS ; end ; ===================================== AKY_ReadRegisterBlock LDA AKY_ChannelC1_PtRegisterBlock,Y STA AKY_RegisterBlock LDA AKY_ChannelC1_PtRegisterBlock+1,Y STA AKY_RegisterBlock+1 LDY #$00 LDA (AKY_RegisterBlock),Y ; type ; 00 = no software no hardware. ; 01 = software only. ; 10 = hardware only. ; 11 = software and hardware. INY BCS @+ ; INITIAL STATE JMP AKY_RRB_NonInitialState @ LSR @ BCS AKY_RRB_IS_SoftwareOnlyOrSoftwareAndHardware LSR @ BCS AKY_RRB_IS_HardwareOnly ; ===================================== AKY_RRB_IS_NoSoftwareNoHardware ; 7 6 5 4 3 2 1 0 ; 0 v v v v n t t ; n = noise? ; v = volume LSR @ PHA BCC AKY_RRB_NIS_NoSoftwareNoHardware_ReadVolume LDA (AKY_RegisterBlock),Y STA AKY_NoiseGeneratorControl INY LDA AKY_MixerControlEnableNoise,X AND AKY_MixerControlEnable STA AKY_MixerControlEnable AKY_RRB_NIS_NoSoftwareNoHardware_ReadVolume PLA STA POKEYMAX+8,X LDA AKY_MixerControlEnableTone,X ORA AKY_MixerControlEnable STA AKY_MixerControlEnable RTS ; ===================================== AKY_RRB_IS_HardwareOnly ; 7 6 5 4 3 2 1 0 ; e e e e n r t t ; r = retrig? ; n = noise? ; e = envelope LSR @ BCC AKY_RRB_IS_HO_NoRetrig ROR AKY_EnvelopeShapeControlOld ; C=1 AKY_RRB_IS_HO_NoRetrig LSR @ PHA BCC AKY_RRB_IS_HO_NoNoise LDA (AKY_RegisterBlock),Y STA AKY_NoiseGeneratorControl INY LDA AKY_MixerControlEnableNoise,X AND AKY_MixerControlEnable STA AKY_MixerControlEnable AKY_RRB_IS_HO_NoNoise PLA STA AKY_EnvelopeShapeControl LDA (AKY_RegisterBlock),Y STA AKY_EnvelopePeriodControl INY LDA (AKY_RegisterBlock),Y STA AKY_EnvelopePeriodControl+1 INY LDA AKY_MixerControlEnableTone,X ORA AKY_MixerControlEnable STA AKY_MixerControlEnable LDA #$10 STA POKEYMAX+8,X RTS ; ===================================== AKY_RRB_IS_SoftwareOnlyOrSoftwareAndHardware LSR @ BCS AKY_RRB_IS_SoftwareAndHardware AKY_RRB_IS_SoftwareOnly ; 7 6 5 4 3 2 1 0 ; 0 v v v v n t t ; n = noise? ; v = volume. LSR @ PHA BCC AKY_RRB_IS_SoftwareOnly_NoNoise LDA (AKY_RegisterBlock),Y STA AKY_NoiseGeneratorControl INY LDA AKY_MixerControlEnableNoise,X AND AKY_MixerControlEnable STA AKY_MixerControlEnable AKY_RRB_IS_SoftwareOnly_NoNoise PLA STA POKEYMAX+8,X LDA AKY_ToneGeneratorControlL,X STA AYR1+1 LDA (AKY_RegisterBlock),Y AYR1 STA POKEYMAX INY LDA AKY_ToneGeneratorControlH,X STA AYR2+1 LDA (AKY_RegisterBlock),Y AYR2 STA POKEYMAX INY RTS ; ===================================== AKY_RRB_IS_SoftwareAndHardware ; 7 6 5 4 3 2 1 0 ; e e e e n r t t ; r = retrig? ; n = noise? ; e = envelope LSR @ BCC AKY_RRB_IS_SAH_NoRetrig ROR AKY_EnvelopeShapeControlOld ; C=1 AKY_RRB_IS_SAH_NoRetrig LSR @ PHA BCC AKY_RRB_IS_SAH_NoNoise LDA (AKY_RegisterBlock),Y STA AKY_NoiseGeneratorControl INY LDA AKY_MixerControlEnableNoise,X AND AKY_MixerControlEnable STA AKY_MixerControlEnable AKY_RRB_IS_SAH_NoNoise PLA STA AKY_EnvelopeShapeControl LDA AKY_ToneGeneratorControlL,X STA AYR3+1 LDA (AKY_RegisterBlock),Y AYR3 STA POKEYMAX INY LDA AKY_ToneGeneratorControlH,X STA AYR4+1 LDA (AKY_RegisterBlock),Y AYR4 STA POKEYMAX INY LDA #$10 STA POKEYMAX+8,X LDA (AKY_RegisterBlock),Y STA AKY_EnvelopePeriodControl INY LDA (AKY_RegisterBlock),Y STA AKY_EnvelopePeriodControl+1 INY RTS ; ===================================== AKY_RRB_NIS_NoSoftwareNoHardware_Loop LDA (AKY_RegisterBlock),Y PHA INY LDA (AKY_RegisterBlock),Y STA AKY_RegisterBlock+1 PLA STA AKY_RegisterBlock LDY #$00 LDA (AKY_RegisterBlock),Y INY ; ===================================== AKY_RRB_NonInitialState ; t = type. ; 00 = no software no hardware. ; 01 = software only. ; 10 = hardware only. ; 11 = software and hardware. LSR @ BCS AKY_RRB_NIS_SoftwareOnlyOrSoftwareAndHardware LSR @ BCC @+ JMP AKY_RRB_NIS_HardwareOnly @ AKY_RRB_NIS_NoSoftwareNoHardwareOrLoop ; 7 6 5 4 3 2 1 0 ; n vv vv vv vv v 0 0 ; l ; v = new volume? If 1, vv is the volume. If 0, the vv flags are used for the possible loop. ; l = loop? Only relevant if v = 0. ; n = noise? Always 0 in case of loop. STA AKY_TOKEN AND #$03 CMP #$02 ;%10 loop BEQ AKY_RRB_NIS_NoSoftwareNoHardware_Loop LDA AKY_MixerControlEnableTone,X ORA AKY_MixerControlEnable STA AKY_MixerControlEnable LSR AKY_TOKEN BCC AKY_RRB_NIS_NoVolume LDA AKY_TOKEN AND #$0F STA POKEYMAX+8,X AKY_RRB_NIS_NoVolume LDA AKY_TOKEN AND #%00010000 BNE @+ RTS @ LDA (AKY_RegisterBlock),Y STA AKY_NoiseGeneratorControl INY LDA AKY_MixerControlEnableNoise,X AND AKY_MixerControlEnable STA AKY_MixerControlEnable RTS ; ===================================== AKY_RRB_NIS_SoftwareOnlyOrSoftwareAndHardware LSR @ BCC @+ JMP AKY_RRB_NIS_SoftwareAndHardware @ AKY_RRB_NIS_SoftwareOnly ; 7 6 5 4 3 2 1 0 ; mspnoise lsp v v v v 0 1 ; v = volume. ; mspnoise = new Most Significant byte of Period AND/OR noise. ; lsp = new Most Significant byte of Period? STA AKY_TOKEN LDA AKY_TOKEN AND #$0F STA POKEYMAX+8,X LDA AKY_TOKEN AND #%00010000 BEQ AKY_RRB_NIS_SoftwareOnly_NoLSP LDA AKY_ToneGeneratorControlL,X STA AYR5+1 LDA (AKY_RegisterBlock),Y AYR5 STA POKEYMAX INY AKY_RRB_NIS_SoftwareOnly_NoLSP LDA AKY_TOKEN AND #%00100000 BNE @+ RTS @ ; 76543210 ; in pppp ; i = isNoise? If yes, open the noise channel. ; n = new Noise? If !isNoise, 0. ; p = MSB of period (encoded regardless its usefulness) LDA AKY_ToneGeneratorControlH,X STA AYR6+1 LDA (AKY_RegisterBlock),Y INY AYR6 STA POKEYMAX ; AND #$0F ASL @ BCS @+ RTS @ ASL @ ; C LDA AKY_MixerControlEnableNoise,X AND AKY_MixerControlEnable STA AKY_MixerControlEnable BCS @+ RTS @ LDA (AKY_RegisterBlock),Y STA AKY_NoiseGeneratorControl INY RTS ; ===================================== AKY_RRB_NIS_HardwareOnly ; 7 6 5 4 3 2 1 0 ; lsp msp nr e e e 1 0 ; e = envelope. ; msp = new Most Significant byte of Period? ; lsp = new Most Significant byte of Period? ; nr = new noise or retrig? ASL @ STA AKY_EnvelopeShapeControl ; AND #$0F b0=0? PHA LDA AKY_MixerControlEnableTone,X ORA AKY_MixerControlEnable STA AKY_MixerControlEnable LDA #$10 STA POKEYMAX+8,X PLA ASL @ ASL @ STA AKY_TOKEN BCC AKY_RRB_NIS_HardwareOnly_NoLSB LDA (AKY_RegisterBlock),Y STA AKY_EnvelopePeriodControl INY AKY_RRB_NIS_HardwareOnly_NoLSB ASL AKY_TOKEN BCC AKY_RRB_NIS_HardwareOnly_NoMSB LDA (AKY_RegisterBlock),Y STA AKY_EnvelopePeriodControl+1 INY AKY_RRB_NIS_HardwareOnly_NoMSB ASL AKY_TOKEN BCS AKY_RRB_NIS_Hardware_Shared_NoiseOrRetrig_AndStop RTS ; ===================================== AKY_RRB_NIS_SoftwareAndHardware ; 7 6 5 4 3 2 1 0 ; rn ne mssp lssp mshp lshp 1 1 ; lshp = new Less Significant byte of Hardware Period? ; mshp = new Most Significant byte of Hardware Period? ; lssp = new Less Significant byte of Software Period? ; mssp = new Most Significant byte of Software Period? ; ne = new envelope? ; rn = retrig or noise/new noise? STA AKY_TOKEN LDA #$10 STA POKEYMAX+8,X LSR AKY_TOKEN BCC AKY_RRB_NIS_SAHH_AfterLSBH LDA (AKY_RegisterBlock),Y STA AKY_EnvelopePeriodControl INY AKY_RRB_NIS_SAHH_AfterLSBH LSR AKY_TOKEN BCC AKY_RRB_NIS_SAHH_AfterMSBH LDA (AKY_RegisterBlock),Y STA AKY_EnvelopePeriodControl+1 INY AKY_RRB_NIS_SAHH_AfterMSBH LSR AKY_TOKEN BCC AKY_RRB_NIS_SAHH_AfterLSBS LDA AKY_ToneGeneratorControlL,X STA AYR7+1 LDA (AKY_RegisterBlock),Y AYR7 STA POKEYMAX INY AKY_RRB_NIS_SAHH_AfterLSBS LSR AKY_TOKEN BCC AKY_RRB_NIS_SAHH_AfterMSBS LDA AKY_ToneGeneratorControlH,X STA AYR8+1 LDA (AKY_RegisterBlock),Y AYR8 STA POKEYMAX INY AKY_RRB_NIS_SAHH_AfterMSBS LSR AKY_TOKEN BCC AKY_RRB_NIS_SAHH_AfterEnvelope LDA (AKY_RegisterBlock),Y STA AKY_EnvelopeShapeControl INY AKY_RRB_NIS_SAHH_AfterEnvelope LSR AKY_TOKEN BCS @+ RTS @ AKY_RRB_NIS_Hardware_Shared_NoiseOrRetrig_AndStop ;76543210 ;ooooonir ;r = retrig? ;i = isNoise? If yes, open the noise channel. ;n = new Noise? If !isNoise, 0. ;o = noise (>0). LDA (AKY_RegisterBlock),Y INY LSR @ BCC AKY_RRB_NIS_S_NOR_NoRetrig ROR AKY_EnvelopeShapeControlOld ; C=1 AKY_RRB_NIS_S_NOR_NoRetrig LSR @ BCS @+ RTS @ PHA LDA AKY_MixerControlEnableNoise,X AND AKY_MixerControlEnable STA AKY_MixerControlEnable PLA LSR @ BCS @+ RTS @ STA AKY_NoiseGeneratorControl RTS ; ===================================== AKY_NoiseGeneratorControl .byte $00 AKY_EnvelopePeriodControl .byte $00,$00 AKY_EnvelopeShapeControl .byte $00 AKY_EnvelopeShapeControlOld .byte $00 AKY_MixerControlEnable .byte $00 AKY_ToneGeneratorControlL .byte $A0,$A2,$A4 AKY_ToneGeneratorControlH .byte $A1,$A3,$A5 AKY_MixerControlEnableTone .byte $01,$02,$04 AKY_MixerControlEnableNoise .byte %11110111,%11101111,%11011111