; GMD-X1 VER.4.10 ; 89/11/01 08:44PM ORG $F000 @KEYON.COUNT EQU 0 @KEYOFF.COUNT EQU 2 @COUNT.SWITCH EQU 4 @KEY EQU 5 @LFO.SPEED EQU 6 @LFO.PMD EQU 7 @LFO.PMS EQU 8 @LFO.DELAY EQU 10 @LFO.SPEEDCOUNT EQU 11 @LFO.PMDCOUNT EQU 12 @LFO.PMSWORK EQU 13 @LFO.DELAYCOUNT EQU 15 @PORTAMENTO EQU 16 @VOLUME EQU 18 @CHANNEL.MASK EQU 19 @MUSIC.DATA.ADR EQU 20 @KEYON.DEF EQU 22 @KEYOFF.DEF EQU 24 @FADE.VOL EQU 26 @FADE.VOL.END EQU 27 @FADE.SPEED EQU 28 @FADE.SPEEDCOUNT EQU 29 @FREQNO EQU 30 @OPM.RL.FB.AL EQU 32 @OPM.OP1VOL EQU 33 @OPM.OP3VOL EQU 34 @OPM.OP2VOL EQU 35 @OPM.OP4VOL EQU 36 @OPM.DL.RR EQU 37 @OPM.DL.RR.3 EQU 38 @OPM.DL.RR.2 EQU 39 @OPM.DL.RR.4 EQU 40 @OPM.OPMASK EQU 41 @ATTACK.SWITCH EQU 42 @DETUNE EQU 43 @OCTERVE EQU 45 @LOOP.STACK.ADR EQU 46 @LOOP.STACK EQU 48 @NOISE.SWITCH EQU 56 @GOSUB.STACK.NO EQU 58 @GOSUB.STACK EQU 60 @ EQU 68 PROGRAM.START JP MUSIC.START JP MUSIC.STOP JP FADEOUT.COMMAND JP MUSIC.DATA.SET KILL.PATCH.1 JP TURBO.CHECK ; ; ; ; ; ; ; ; MUSIC.START DI LD A,TEMPO.120 LD (TEMPO.WORK),A CALL INT.ON LD BC,WORK.END-WORK.START-1 LD DE,WORK.START+1 LD HL,WORK.START LD (HL),0 LDIR CALL INITIALIZE JR INTERRUPT.START.1 ; ; ; ; ; ; ; ; INITIALIZE LD DE,WORK.START+@MUSIC.DATA.ADR LD HL,MML.START.ADR LD A,8 INITIALIZE. LDI LDI LD BC,WORK.STEP-2 EX DE,HL ADD HL,BC EX DE,HL DEC A JR NZ,INITIALIZE. LD IX,WORK.START LD B,8 INITIALIZE.1 LD HL,IX LD DE,@LOOP.STACK-1 ADD HL,DE LD (IX+@LOOP.STACK.ADR),L LD (IX+@LOOP.STACK.ADR+1),H LD (IX+@OCTERVE),4 XOR A LD (FADE.MASK),A INC A LD (IX+@COUNT.SWITCH),A LD (IX+@KEYON.COUNT),A LD (IX+@KEYON.COUNT+1),A LD DE,WORK.STEP ADD IX,DE DJNZ INITIALIZE.1 RET ; ; ; ; ; ; ; ; INTERRUPT.START DI INTERRUPT.START.1 LD (STACK.AREA),SP LD SP,STACK.AREA PUSH AF PUSH BC PUSH DE PUSH HL ; EXX EX AF,AF' PUSH AF ; PUSH BC ; PUSH DE ; PUSH HL ; EXX ; EX AF,AF' PUSH IX ; PUSH IY XOR A LD (MUSIC.CHANNEL),A LD IX,WORK.START ; CALL NOISE.CHANNEL.SET ; CHANNEL.LOOP LD HL,MUSIC.CHANNEL INC (HL) LD A,(HL) CP 9 JP Z,INTERRUPT.END CHANNEL.LOOP.1 DEC (IX+@KEYON.COUNT) JP NZ,SOFT.LFO DEC (IX+@KEYON.COUNT+1) JP NZ,SOFT.LFO COUNT.END DEC (IX+@COUNT.SWITCH) JP Z,MUSIC.NOTE.SET LD L,(IX+@KEYOFF.COUNT) LD H,(IX+@KEYOFF.COUNT+1) LD A,H AND L INC A JP Z,MUSIC.NOTE.SET CALL KEY.OFF LD (IX+@KEYON.COUNT),L LD (IX+@KEYON.COUNT+1),H JP CHANNEL.LOOP.1 ; SOFT.LFO LD A,(IX+@LFO.DELAYCOUNT) OR A JP Z,SOFT.LFO.1 DEC (IX+@LFO.DELAYCOUNT) JP PORTAMENTO SOFT.LFO.1 LD A,(IX+@PORTAMENTO+1) CP $80 JP NZ,PORTAMENTO LD A,(IX+@LFO.SPEEDCOUNT) ADD A,(IX+@LFO.SPEED) LD (IX+@LFO.SPEEDCOUNT),A JP NC,PORTAMENTO LD L,(IX+@FREQNO) LD H,(IX+@FREQNO+1) LD E,(IX+@LFO.PMSWORK) LD D,(IX+@LFO.PMSWORK+1) ADD HL,DE DEC (IX+@LFO.PMDCOUNT) JP NZ,PORTAMENTO.1.1 DEC DE LD A,E CPL LD (IX+@LFO.PMSWORK),A LD A,D CPL LD (IX+@LFO.PMSWORK+1),A LD A,(IX+@LFO.PMD) LD (IX+@LFO.PMDCOUNT),A JP PORTAMENTO.1.1 ; PORTAMENTO LD L,(IX+@FREQNO) LD H,(IX+@FREQNO+1) PORTAMENTO.1 LD A,(IX+@PORTAMENTO+1) CP $80 JP Z,PORTAMENTO.2 LD D,A LD E,(IX+@PORTAMENTO) ADD HL,DE PORTAMENTO.1.1 BIT 7,H LD A,(IX+@OCTERVE) LD DE,12*$100 JP Z,PORTAMENTO.1.1.2 PORTAMENTO.1.1.1 DEC A ADD HL,DE JP NC,PORTAMENTO.1.1.1 JP PORTAMENTO.1.1.3 PORTAMENTO.1.1.2 INC A OR A SBC HL,DE JP NC,PORTAMENTO.1.1.2 ADD HL,DE DEC A PORTAMENTO.1.1.3 LD (IX+@OCTERVE),A PORTAMENTO.2 LD (IX+@FREQNO),L LD (IX+@FREQNO+1),H CALL SEND.FREQ ; FADE LD C,(IX+@FADE.VOL) LD A,(IX+@FADE.SPEED) OR A JP Z,VOLUME.PUT ADD A,(IX+@FADE.SPEEDCOUNT) LD (IX+@FADE.SPEEDCOUNT),A JP NC,VOLUME.PUT LD A,(IX+@FADE.VOL.END) CP C JP Z,FADE.2 JP C,FADE.1 INC C JP FADE.3 FADE.1 DEC C JP FADE.3 FADE.2 LD (IX+@FADE.SPEED),0 JP VOLUME.PUT FADE.3 LD (IX+@FADE.VOL),C VOLUME.PUT LD A,(IX+@VOLUME) ADD A,C JP P,VOLUME.PUT.1 LD A,127 VOLUME.PUT.1 CALL SEND.VOLUME ; CHANNEL.LOOP.END LD BC,WORK.STEP ADD IX,BC JP CHANNEL.LOOP ; ; ; ; ; ; ; ; INTERRUPT.END ; POP IY POP IX ; EXX ; EX AF,AF' ; POP HL ; POP DE ; POP BC POP AF ; EXX EX AF,AF' POP HL POP DE POP BC POP AF LD SP,(STACK.AREA) EI RETI ; ; ; ; ; ; ; ; SEND.FREQ LD A,H LD E,0 CP 9:CCF:ADC A,E CP 6:CCF:ADC A,E CP 3:CCF:ADC A,E LD E,L LD D,A LD A,(IX+@OCTERVE) ADD A,A:ADD A,A:ADD A,A:ADD A,A:ADD A,12 ADD A,D LD D,A SEND.FREQ.2 LD A,(MUSIC.CHANNEL) DEC A ADD A,OPM.KEY.CODE CALL REG.WRITE.1 RET ; ; ; ; ; ; ; ; SEND.VOLUME LD B,A LD A,(MUSIC.CHANNEL) ADD A,OPM.OP4VOL-1 EX AF,AF' LD A,(IX+@OPM.OP4VOL) ADD A,B JP P,SEND.VOLUME.1 LD A,127 SEND.VOLUME.1 LD D,A EX AF,AF' PUSH BC CALL REG.WRITE POP BC EX AF,AF' LD A,(IX+@OPM.RL.FB.AL) AND 7 SUB 3 LD C,A RET C RET Z LD A,(IX+@OPM.OP2VOL) ADD A,B JP P,SEND.VOLUME.2 LD A,127 SEND.VOLUME.2 LD D,A EX AF,AF' SUB 8 PUSH BC CALL REG.WRITE POP BC EX AF,AF' DEC C RET Z LD A,(IX+@OPM.OP3VOL) ADD A,B JP P,SEND.VOLUME.3 LD A,127 SEND.VOLUME.3 LD D,A EX AF,AF' SUB 8 PUSH BC CALL REG.WRITE POP BC DEC C:DEC C:DEC C RET NZ EX AF,AF' LD A,(IX+@OPM.OP1VOL) ADD A,B JP P,SEND.VOLUME.4 LD A,127 SEND.VOLUME.4 LD D,A EX AF,AF' SUB 8 JP REG.WRITE ; ; ; ; ; ; ; ; REG.WRITE LD BC,$0701 PUSH DE REG.WRITE. IN D,(C) JP M,REG.WRITE. POP DE DEC C OUT (C),A INC C OUT (C),D RET REG.WRITE.1 LD BC,$0701 PUSH DE REG.WRITE.1. IN D,(C) JP M,REG.WRITE.1. POP DE DEC C OUT (C),A INC C OUT (C),D DEC C PUSH BC:POP BC:PUSH BC:POP BC:OR A:OR 0 ADD A,$08 OUT (C),A INC C OUT (C),E RET ; ; ; ; ; ; ; ; KEY.ON LD A,(IX+@KEY) OR A RET NZ LD A,(IX+@ATTACK.SWITCH) OR A JP Z,KEY.ON.1 LD A,(MUSIC.CHANNEL) ADD A,OPM.DL.RR-1+$18 LD D,$0F CALL REG.WRITE SUB 8 CALL REG.WRITE SUB 8 CALL REG.WRITE SUB 8 CALL REG.WRITE PUSH AF KEY.ON.1 XOR A LD (IX+@LFO.SPEEDCOUNT),A INC A LD (IX+@KEY),A LD A,(IX+@VOLUME) ADD A,(IX+@FADE.VOL) JP P,KEY.ON.2 LD A,127 KEY.ON.2 CALL SEND.VOLUME LD A,(IX+@LFO.PMD) SRL A LD (IX+@LFO.PMDCOUNT),A LD A,(IX+@LFO.PMS) LD (IX+@LFO.PMSWORK),A LD A,(IX+@LFO.PMS+1) LD (IX+@LFO.PMSWORK+1),A LD A,(IX+@LFO.DELAY) LD (IX+@LFO.DELAYCOUNT),A LD A,(IX+@ATTACK.SWITCH) OR A JP Z,KEY.ON.4 LD HL,IX LD DE,@OPM.DL.RR ADD HL,DE POP AF KEY.ON.3 LD D,(HL) CALL REG.WRITE INC HL ADD A,8 JP NC,KEY.ON.3 KEY.ON.4 LD A,(MUSIC.CHANNEL) ADD A,(IX+@OPM.OPMASK) DEC A LD D,A LD A,OPM.KEY CALL REG.WRITE RET ; ; ; ; ; ; ; ; KEY.OFF XOR A LD (IX+@KEY),A KEY.OFF.1 LD A,(MUSIC.CHANNEL) DEC A LD D,A LD A,OPM.KEY CALL REG.WRITE RET ; ; ; ; ; ; ; ; MUSIC.NOTE.SET LD L,(IX+@MUSIC.DATA.ADR) LD H,(IX+@MUSIC.DATA.ADR+1) NOTE.SET.LOOP LD A,(HL) INC HL SRL A JP C,ANOTHER.COM ; LD (IX+@PORTAMENTO+1),$80 LD (IX+@MUSIC.DATA.ADR),L LD (IX+@MUSIC.DATA.ADR+1),H CP 127 JP Z,REST.1 LD DE,IX LD HL,@KEYON.DEF ; LD BC,4 ADD HL,DE LDI:LDI:LDI:LDI NOTE.SET.LOOP.1 LD H,A LD L,0 LD E,(IX+@DETUNE) LD D,(IX+@DETUNE+1) ADD HL,DE LD A,H LD D,0 CP 12*4 JP C,NOTE.SET.LOOP.2 SET 2,D SUB 12*4 NOTE.SET.LOOP.2 CP 12*2 JP C,NOTE.SET.LOOP.3 SET 1,D SUB 12*2 NOTE.SET.LOOP.3 CP 12 JP C,NOTE.SET.LOOP.4 INC D SUB 12 NOTE.SET.LOOP.4 LD H,A LD (IX+@FREQNO),L LD (IX+@FREQNO+1),H ; INC D LD (IX+@OCTERVE),D CALL SEND.FREQ CALL KEY.ON LD (IX+@COUNT.SWITCH),2 JP CHANNEL.LOOP.END ; ; ; ; ; ; ; ; ANOTHER.COM CP 127 JP Z,REST CP 96 JP NC,ANOTHER.COM.1 LD DE,IX ; LD BC,4 LDI:LDI:LDI:LDI LD (IX+@MUSIC.DATA.ADR),L LD (IX+@MUSIC.DATA.ADR+1),H ; LD (IX+@PORTAMENTO+1),$80 JP NOTE.SET.LOOP.1 ; REST LD DE,IX ; LD BC,2 LDI:LDI LD (IX+@MUSIC.DATA.ADR),L LD (IX+@MUSIC.DATA.ADR+1),H LD (IX+@PORTAMENTO+1),$80 JP REST.2 REST.1 LD HL,@KEYON.DEF LD DE,IX ADD HL,DE LD E,(HL) INC HL LD D,(HL) INC HL LD C,(HL) INC HL LD B,(HL) EX DE,HL ADD HL,BC DEC H:DEC L LD (IX+@KEYON.COUNT),L LD (IX+@KEYON.COUNT+1),H REST.2 LD (IX+@COUNT.SWITCH),1 JP CHANNEL.LOOP.END ; ANOTHER.COM.1 PUSH HL SUB 96 ADD A,A LD E,A LD D,0 LD HL,COMMAND.JP.TABLE ADD HL,DE LD A,(HL) INC HL LD H,(HL) LD L,A JP (HL) COMMAND.JP.TABLE DW TONE.CHANGE.COM DW VOLUME.COM DW DEF.LENGTH.COM DW WRITE.REG.COM DW LOOP.END.COM DW LOOP.BREAK.COM DW SOFT.LFO.COM DW LFO.DELAY.COM DW LFO.SPEED.COM DW PORTAMENTO.COM DW TEMPO.COM DW DETUNE.COM DW NOISE.FREQ.COM DW NOISE.SWITCH.COM DW TOTAL.VOL.COM DW END.COM DW KEYOFF.COM DW SOFT.ENV.COM DW LOOP.START.COM DW PAN.COM DW GOSUB.COM DW RETURN.COM DW REL.DETUNE.COM DW REL.VOLUME.COM DW REL.NOISE.FREQ.COM DW RELEASE.SW.ON.COM DW RELEASE.SW.OFF.COM ; ; ; ; ; ; ; ; TONE.CHANGE.COM POP HL LD A,(MUSIC.CHANNEL) ADD A,OPM.DL.RR-1+$18 LD D,$0F CALL REG.WRITE SUB 8 CALL REG.WRITE SUB 8 CALL REG.WRITE SUB 8 CALL REG.WRITE LD E,(HL) INC HL LD D,(HL) PUSH HL LD HL,(MML.DATA.ADR) ADD HL,DE LD A,(MUSIC.CHANNEL) ADD A,OPM.RL.FB.AL-1 CALL TONE.WRITE LD (IX+@OPM.RL.FB.AL),D LD E,D ADD A,$10 CALL TONE.WRITE CALL TONE.WRITE CALL TONE.WRITE CALL TONE.WRITE CALL TONE.WRITE EX AF,AF' LD A,E:AND 7:LD E,A CP 7:LD D,0:JP NZ,TONE.CHANGE.COM.A:LD D,(IX+@VOLUME) TONE.CHANGE.COM.A CALL TONE.WRITE.:LD (IX+@OPM.OP1VOL),A LD A,E:CP 5:LD D,0:JP C,TONE.CHANGE.COM.B:LD D,(IX+@VOLUME) TONE.CHANGE.COM.B CALL TONE.WRITE.:LD (IX+@OPM.OP3VOL),A LD A,E:CP 4:LD D,0:JP C,TONE.CHANGE.COM.C:LD D,(IX+@VOLUME) TONE.CHANGE.COM.C CALL TONE.WRITE.:LD (IX+@OPM.OP2VOL),A LD A,E:LD D,(IX+@VOLUME) CALL TONE.WRITE.:LD (IX+@OPM.OP4VOL),A EX AF,AF' LD E,12 TONE.CHANGE.COM.1 CALL TONE.WRITE DEC E JP NZ,TONE.CHANGE.COM.1 CALL TONE.WRITE:LD (IX+@OPM.DL.RR),D CALL TONE.WRITE:LD (IX+@OPM.DL.RR+1),D CALL TONE.WRITE:LD (IX+@OPM.DL.RR+2),D CALL TONE.WRITE:LD (IX+@OPM.DL.RR+3),D LD D,(HL) LD (IX+@OPM.OPMASK),D INC HL AND 7 CP 0 JP NZ,TONE.CHANGE.COM.2 LD D,(HL) LD A,OPM.SPEED CALL REG.WRITE INC HL LD D,(HL) INC A CALL REG.WRITE INC HL LD D,(HL) CALL REG.WRITE INC HL LD D,(HL) ADD A,2 CALL REG.WRITE JP TONE.CHANGE.COM.3 TONE.CHANGE.COM.2 INC HL:INC HL:INC HL TONE.CHANGE.COM.3 INC HL LD D,(HL) LD A,(MUSIC.CHANNEL) CP 8 LD A,OPM.NOISE.CONTROL CALL Z,REG.WRITE POP HL INC HL JP NOTE.SET.LOOP TONE.WRITE LD D,(HL) INC HL CALL REG.WRITE ADD A,8 RET TONE.WRITE. LD A,(HL) ADD A,D LD D,A LD A,(HL) EX AF,AF' INC HL CALL REG.WRITE ADD A,8 EX AF,AF' RET ; VOLUME.COM POP HL LD A,(HL) INC HL LD (IX+@VOLUME),A JP NOTE.SET.LOOP ; REL.VOLUME.COM POP HL LD A,(IX+@VOLUME) ADD A,(HL) LD (IX+@VOLUME),A INC HL JP NOTE.SET.LOOP ; DEF.LENGTH.COM POP HL EX DE,HL LD HL,IX LD BC,@KEYON.DEF ADD HL,BC EX DE,HL ; LD BC,4 LDI:LDI:LDI:LDI JP NOTE.SET.LOOP ; WRITE.REG.COM POP HL LD A,(HL) INC HL LD D,(HL) INC HL CP 48 JP C,WRITE.REG.COM.1 CP 56 JP NC,WRITE.REG.COM.1 PUSH AF PUSH HL LD HL,WORK.START+@DETUNE SUB 48 JP Z,WRITE.REG.COM.LPEND PUSH DE LD DE,WORK.STEP WRITE.REG.COM.LOOP ADD HL,DE DEC A JP NZ,WRITE.REG.COM.LOOP POP DE WRITE.REG.COM.LPEND LD (HL),D INC HL LD (HL),0 POP HL POP AF WRITE.REG.COM.1 CALL REG.WRITE JP NOTE.SET.LOOP ; LOOP.END.COM POP HL LD E,(IX+@LOOP.STACK.ADR) LD D,(IX+@LOOP.STACK.ADR+1) LD A,(DE) OR A JP Z,LOOP.END.COM.1 DEC A LD (DE),A JP NZ,LOOP.END.COM.1 INC HL INC HL DEC DE LD (IX+@LOOP.STACK.ADR),E LD (IX+@LOOP.STACK.ADR+1),D JP NOTE.SET.LOOP LOOP.END.COM.1 LD E,(HL) INC HL LD D,(HL) EX DE,HL LD DE,(MML.DATA.ADR) ADD HL,DE JP NOTE.SET.LOOP ; LOOP.BREAK.COM POP HL LD E,(IX+@LOOP.STACK.ADR) LD D,(IX+@LOOP.STACK.ADR+1) LD A,(DE) DEC A JP Z,LOOP.BREAK.COM.1 INC HL INC HL JP NOTE.SET.LOOP LOOP.BREAK.COM.1 DEC DE LD (IX+@LOOP.STACK.ADR),E LD (IX+@LOOP.STACK.ADR+1),D LD E,(HL) INC HL LD D,(HL) EX DE,HL LD DE,(MML.DATA.ADR) ADD HL,DE JP NOTE.SET.LOOP ; LOOP.START.COM POP HL LD E,(IX+@LOOP.STACK.ADR) LD D,(IX+@LOOP.STACK.ADR+1) INC DE LD A,(HL) INC HL LD (DE),A LD (IX+@LOOP.STACK.ADR),E LD (IX+@LOOP.STACK.ADR+1),D JP NOTE.SET.LOOP ; SOFT.LFO.COM POP HL EX DE,HL LD HL,IX LD BC,@LFO.SPEED ADD HL,BC EX DE,HL ; LD BC,5 LDI:LDI:LDI:LDI:LDI JP NOTE.SET.LOOP ; LFO.DELAY.COM POP HL LD A,(HL) INC HL LD (IX+@LFO.DELAY),A JP NOTE.SET.LOOP ; LFO.SPEED.COM POP HL LD A,(HL) INC HL LD (IX+@LFO.SPEED),A JP NOTE.SET.LOOP ; PORTAMENTO.COM POP HL PUSH HL LD A,(HL) SRL A LD H,A LD L,0 LD E,(IX+@DETUNE) LD D,(IX+@DETUNE+1) ADD HL,DE LD A,H LD D,0 CP 12*4 JP C,PORTAMENTO.COM.2 SET 2,D SUB 12*4 PORTAMENTO.COM.2 CP 12*2 JP C,PORTAMENTO.COM.3 SET 1,D SUB 12*2 PORTAMENTO.COM.3 CP 12 JP C,PORTAMENTO.COM.4 INC D SUB 12 PORTAMENTO.COM.4 LD H,A LD (IX+@FREQNO),L LD (IX+@FREQNO+1),H ; INC D LD (IX+@OCTERVE),D CALL SEND.FREQ CALL KEY.ON POP HL INC HL LD C,(HL) INC HL LD B,(HL) INC HL LD E,(HL) INC HL LD D,(HL) INC HL LD (IX+@KEYON.COUNT),E LD (IX+@KEYON.COUNT+1),D LD (IX+@PORTAMENTO),C LD (IX+@PORTAMENTO+1),B LD (IX+@COUNT.SWITCH),1 LD (IX+@MUSIC.DATA.ADR),L LD (IX+@MUSIC.DATA.ADR+1),H JP CHANNEL.LOOP.END ; TEMPO.COM POP HL LD A,(HL) INC HL LD (TEMPO.WORK),A CALL INT.ON.1 JP NOTE.SET.LOOP ; DETUNE.COM POP HL LD A,(HL) INC HL LD (IX+@DETUNE),A LD A,(HL) INC HL LD (IX+@DETUNE+1),A JP NOTE.SET.LOOP ; REL.DETUNE.COM POP HL LD E,(HL) INC HL LD D,(HL) INC HL PUSH HL LD L,(IX+@DETUNE) LD H,(IX+@DETUNE+1) ADD HL,DE LD (IX+@DETUNE),L LD (IX+@DETUNE+1),H POP HL JP NOTE.SET.LOOP ; NOISE.FREQ.COM POP HL LD A,(HL) INC HL LD (NOISE.FREQ),A ADD A,$80 LD D,A LD A,OPM.NOISE.CONTROL CALL REG.WRITE JP NOTE.SET.LOOP ; REL.NOISE.FREQ.COM POP HL LD A,(NOISE.FREQ) ADD A,(HL) LD (NOISE.FREQ),A INC HL ADD A,$80 LD D,A LD A,OPM.NOISE.CONTROL CALL REG.WRITE JP NOTE.SET.LOOP ; NOISE.SWITCH.COM POP HL LD B,(HL) INC HL LD (IX+@NOISE.SWITCH),B RRC B LD A,(NOISE.FREQ) ADD A,B LD D,A LD A,OPM.NOISE.CONTROL CALL REG.WRITE JP NOTE.SET.LOOP ; TOTAL.VOL.COM POP HL LD A,(FADE.MASK) OR A JP NZ,TOTAL.VOL.COM.1 LD A,(HL) LD (IX+@FADE.SPEED),A INC HL LD A,(HL) LD (IX+@FADE.VOL),A INC HL LD A,(HL) LD (IX+@FADE.VOL.END),A INC HL LD (IX+@FADE.SPEEDCOUNT),0 JP NOTE.SET.LOOP TOTAL.VOL.COM.1 INC HL INC HL INC HL JP NOTE.SET.LOOP ; END.COM POP HL DEC HL LD (IX+@MUSIC.DATA.ADR),L LD (IX+@MUSIC.DATA.ADR+1),H ; LD A,$00 LD (IX+@KEYON.COUNT),0 LD (IX+@KEYON.COUNT+1),0 LD (IX+@COUNT.SWITCH),1 JP CHANNEL.LOOP.END ; KEYOFF.COM POP HL CALL KEY.OFF JP NOTE.SET.LOOP ; SOFT.ENV.COM POP HL JP NOTE.SET.LOOP ; GOSUB.COM LD HL,IX LD A,(IX+@GOSUB.STACK.NO) ADD A,2 LD (IX+@GOSUB.STACK.NO),A ADD A,@GOSUB.STACK-2 LD E,A LD D,0 ADD HL,DE POP DE INC DE INC DE LD (HL),E INC HL LD (HL),D EX DE,HL DEC HL DEC HL LD A,(HL) INC HL LD H,(HL) LD L,A LD DE,(MML.DATA.ADR) ADD HL,DE JP NOTE.SET.LOOP ; RETURN.COM LD HL,IX LD A,(IX+@GOSUB.STACK.NO) SUB 2 LD (IX+@GOSUB.STACK.NO),A ADD A,@GOSUB.STACK LD E,A LD D,0 ADD HL,DE POP DE LD E,(HL) INC HL LD D,(HL) EX DE,HL JP NOTE.SET.LOOP ; PAN.COM POP HL LD A,(HL) INC HL RRCA:RRCA LD B,A LD A,(IX+@OPM.RL.FB.AL) AND $3F ADD A,B LD D,A LD A,(MUSIC.CHANNEL) ADD A,OPM.RL.FB.AL-1 CALL REG.WRITE JP NOTE.SET.LOOP ; RELEASE.SW.ON.COM POP HL LD (IX+@ATTACK.SWITCH),1 JP NOTE.SET.LOOP ; RELEASE.SW.OFF.COM POP HL LD (IX+@ATTACK.SWITCH),0 JP NOTE.SET.LOOP ; ; ; ; ; ; ; ; INT.ON INTPAT1 LD BC,$0704 ;turbo = $1FA0 LD A,7 OUT (C),A LD A,32 OUT (C),A LD A,$58 ;INT VECTOR OUT (C),A LD HL,INTERRUPT.START LD ($005E),HL INT.ON.1 INTPAT2 LD BC,$0707 ;turbo = $1FA3 LD A,$C7 OUT (C),A LD A,(TEMPO.WORK) OUT (C),A RET ; INT.OFF LD A,3 INTPAT3 LD BC,$0707 ;turbo = $1FA0 OUT (C),A RET ; ; ; ; ; ; ; ; WORK.START #KEYON.COUNT DS 2*8 #KEYOFF.COUNT DS 2*8 #COUNT.SWITCH DS 1*8 #KEY DS 1*8 #LFO.SPEED DS 1*8 #LFO.PMD DS 1*8 #LFO.PMS DS 2*8 #LFO.DELAY DS 1*8 #LFO.SPEEDCOUNT DS 1*8 #LFO.PMDCOUNT DS 1*8 #LFO.PMSWORK DS 2*8 #LFO.DELAYCOUNT DS 1*8 #PORTAMENTO DS 2*8 #VOLUME DS 1*8 #CHANNEL.MASK DS 1*8 #MUSIC.DATA.ADR DS 2*8 #KEYON.DEF DS 2*8 #KEYOFF.DEF DS 2*8 #FADE.VOL DS 1*8 #FADE.VOL.END DS 1*8 #FADE.SPEED DS 1*8 #FADE.SPEEDCOUNT DS 1*8 #FREQNO DS 2*8 #OPM.RL.FB.AL DS 1*8 #OPM.OP1VOL DS 1*8 #OPM.OP3VOL DS 1*8 #OPM.OP2VOL DS 1*8 #OPM.OP4VOL DS 1*8 #OPM.DL.RR DS 1*8 #OPM.DL.RR.3 DS 1*8 #OPM.DL.RR.2 DS 1*8 #OPM.DL.RR.4 DS 1*8 #OPM.OPMASK DS 1*8 #ATTACK.SWITCH DS 1*8 #DETUNE DS 2*8 #OCTERVE DS 1*8 #LOOP.STACK.ADR DS 2*8 #LOOP.STACK DS 8*8 #NOISE.SWITCH DS 2*8 #GOSUB.STACK.NO DS 1*8 #GOSUB.STACK DS 8*8 WORK.END WORK.STEP EQU WORK.END-WORK.START/8 MUSIC.CHANNEL DS 1 NOISE.FREQ DS 1 NOISE.CHANNEL DS 1 NOISE.MASK DS 1 FADE.MASK DS 1 MML.START.ADR DS 2*8 TEMPO.WORK DS 1 TEMPO.120 EQU 100 MML.DATA.ADR DW 0 ; ; ; ; ; ; ; ; FADEOUT.COMMAND DI LD HL,FADE.MASK LD (HL),1 LD BC,WORK.STEP-2 LD HL,WORK.START+@FADE.VOL EXX LD B,8 EXX FADEOUT.COMMAND.1 LD (HL),D INC HL LD (HL),E INC HL LD (HL),A ADD HL,BC EXX DEC B EXX JR NZ,FADEOUT.COMMAND.1 EI RET ; ; ; ; ; ; ; ; MUSIC.DATA.SET ;IN DE=COMPILED MML-DATA ADR. LD (MML.DATA.ADR),DE LD A,8 LD BC,DE LD IX,DE LD DE,MML.START.ADR MUSIC.DATA.SET.1 LD L,(IX) LD H,(IX+1) INC IX:INC IX ADD HL,BC EX DE,HL LD (HL),E INC HL LD (HL),D INC HL EX DE,HL DEC A JR NZ,MUSIC.DATA.SET.1 JP MUSIC.START ; ; ; ; ; ; ; ; MUSIC.STOP DI LD A,OPM.DL.RR LD D,$FF MUSIC.STOP.1 CALL REG.WRITE INC A JR NZ,MUSIC.STOP.1 LD A,OPM.KEY LD D,7 MUSIC.STOP.2 CALL REG.WRITE DEC D JR NZ,MUSIC.STOP.2 CALL REG.WRITE JP INT.OFF ; ; ; ; ; ; ; ; ; ORG $F800 FREQ.DATA OPM.KEY EQU $08 OPM.NOISE.CONTROL EQU $0F OPM.SPEED EQU $18 OPM.AMD EQU $19 OPM.WAVEFORM EQU $1B OPM.RL.FB.AL EQU $20 OPM.KEY.CODE EQU $28 OPM.FRAC EQU $30 OPM.OP1VOL EQU $60 OPM.OP3VOL EQU $68 OPM.OP2VOL EQU $70 OPM.OP4VOL EQU $78 OPM.DL.RR EQU $E0 TONE.DATA.ADR EQU PROGRAM.START+$A00 DS 32 STACK.AREA DW 0 QUICK CALL INTERRUPT.START XOR A CALL $001B CP "Q"-$40 JP Z,QUICK RET ; ; ; ; ; ;INITIALIZE ONLY(BREAK IT AFTER USE) ROUTINE ; TURBO.CHECK LD HL,QUICK LD ($8B),HL ;QUICK LD HL,KILL.PATCH.1 LD (HL),$C9 LD BC,$1FA0 LD DE,$5A47 OUT (C),E OUT (C),D IN A,(C) CP D JP NZ,CTC.CHECK LD HL,$1FA0 LD (INTPAT1+1),HL LD L,$A3 LD (INTPAT2+1),HL LD (INTPAT3+1),HL RET CTC.CHECK LD BC,$0704 OUT (C),E OUT (C),D IN A,(C) CP D RET Z LD HL,PROGRAM.START LD B,4 LD HL,PROGRAM.START GMDOFF.LP LD (HL),A INC HL:INC HL:INC HL DJNZ GMDOFF.LP SCF RET