Hello Guys,
Change AFX-PT3 replayer and just get a Replayer to AYFX only !!
I need of change this important routine in assembly made KdL.
The problem is which this routine it has a replayer of AYFX+PT3
for effect sound and also music in PSG. But unfortunately now for me
it is not more good.
Now I need of a new replayer and which work only for AYFX and stop !
Therefore: we would have to cut all the part of the routine that manage
the PT3, so that the same routine I occupies less space as possible on the RAM MSX.
I understand that to do this job, a bad job, but I can not do it alone,
so I ask any of you who have much more experience than me!
KdL Unfortunately, at this time is unwell, and can not help me right now!
Thanks in advance.......
Best Regards
AG.
Here under there is the routine to change.
;AFX-PT3 BASIC EXTENSION v0.4 by KdL 2008 ;======================================== ;Chaos Assembler version ; .org $c100 - 7 .db $fe .dw startProgram,endProgram,startProgram startProgram: jp resetldr ;PT3 push af push bc push de ld a,$01 ld (MUSIC_EN),a call PT3P.PLAY pop de pop bc pop af jp memBank1 ;SFX push af push bc push de ld e,$ff ld b,$00 ld c,b ;default volume (0) ld a,e call AYFX.PLAY ; ld b,5 ; halt ; djnz $-1 pop de pop bc pop af memBank1: push af ld a,1 ; switch to 16k memory bank1 out ($fe),a pop af ret memBank2: push af ld a,2 ; switch to 16k memory bank2 out ($fe),a pop af ret resetldr: ;VDP_DATA .equ $98 ;VDP_REGW .equ $99 ;VDP_STAT .equ $99 AYFX_RAM .equ $c000 ;sfx player vars (24 bytes) MUSIC_EN .equ $c020 ;music enable flag PT3P_RAM .equ $c021 ;pt3 player vars ;program code startAdr: call memBank2 di ; ld sp,$f800 ;music init ld hl,$a000 ;ld hl,musData call PT3P.INIT xor a ld (MUSIC_EN),a ;sfx init ld hl,$b000 ;ld hl,sfxData call AYFX.INIT ;setup interrupt handler xor a ld ($f3db),a ;switch off key-click ld a,$c3 ;jp opcode ld ($fd9f),a ld hl,intrProc ld ($fda0),hl ei call memBank1 ;main loop starts here mainLoop: ret ;main loop ends here ;go to basic ;frame interrupt handler intrProc: call memBank2 push af push bc push de push hl push ix push iy ld a,(MUSIC_EN) or a call nz,PT3P.PLAY call AYFX.FRAME pop iy pop ix pop hl pop de pop bc pop af call memBank1 ret ;------------------------------------------------------------------------------ ; .INCLUDE "ayfxplay.asm" ;------------------------------------------------------------------------------ ;MSX version of AYFX player ;by Shiru and AlCo, 2006-2007 ; ;Chaos Assembler version by KdL 2007 ; ;Init: ; ld hl,addr. of sfx bank (*.afb) ; call AYFX.INIT ; ;Call sfx: ; ld a,sfx number (0..255) ; ld c,relative volume (-15..15, 0=normal) ; call AYFX.PLAY ; ;On frame interrupt (every 1/50 sec, _after_ music player) ; call AYFX.FRAME ; MODULE AYFX ;AYFX_RAM .equ $ ;define it somethere, sfx player needs 24 bytes of RAM ; channels descriptors, 7 bytes per channel ; +0 (2) current addr. (channel is free, if MSB==$00) ; +2 (2) current play time ; +4 (1) sfx volume ; +5 (2) tone divider ; ... afxChDesc .equ AYFX_RAM ;ds 7*3 afxBnkAdr .equ afxChDesc+21;dw 0 curvolCHN .equ afxBnkAdr+2 ;db 0 AYFX.INIT: inc hl ld (afxBnkAdr),hl ;ñîõðàíÿåì àäðåñ òàáëèöû ñìåùåíèé ld hl,afxChDesc ;ïîìå÷àåì âñå êàíàëû êàê ïóñòûå ld bc,$1500 ld (hl),c inc hl djnz $-2 dec bc ld (afxChDesc+2),bc ld (afxChDesc+2+7),bc ld (afxChDesc+2+14),bc ret AYFX.FRAME: ld b,$03 ld ix,afxChDesc afxFrame0: push bc ld a,11 ld h,(ix+1) ;ñðàâíåíèå ñòàðøåãî áàéòà ;àäðåñà íà <11 cp h jp nc,afxFrame7 ;êàíàë íå èãðàåò, ïðîïóñêàåì ld l,(ix+0) ld e,(hl) ;áåð¸ì çíà÷åíèå èíôîðìàöèîííîãî áàéòà inc hl sub b ;âûáèðàåì ðåãèñòð ãðîìêîñòè: ld d,b ;(11-3=8, 11-2=9, 11-1=10) ld c,$a0 ;íà÷àëî âûâîäà çíà÷åíèÿ .db $FD,$61 ;ld iyh,c ;âûêë ãðîìêîñòè out (c),a ;âûáðàëè ðåãèñòð ãðîìêîñòè in a,($a2) cp 16 jr nc,$+4 sub 3;4 jr nc,$+3 xor a ld b,a ld a,e and $0f add a,(ix+4) ;ïðèìåíÿåì òåêóùóþ ãðîìêîñòü êàíàëà cp 15 jp m,$+5 ld a,15 or a jp p,$+4 xor a cp 13 ;ãðîìêóþ ÷àñòü ýôôåêòà íå ãëóøèì jr nc,curvON cp b jr c,curvOFF curvON: .db $FD,$26,$A1; ld iyh,$a1 ;âêë curvOFF: .db $FD,$4C ;ld c,iyh out (c),a ;ñîáñòâåííî âûâîä ãðîìêîñòè bit 5,e ;áóäåò èçìåíåíèå òîíà? jr z,afxFrame1 ;òîí íå èçìåíÿåòñÿ ld a,(hl) ld (ix+5),a inc hl ld a,(hl) ld (ix+6),a inc hl afxFrame1: ld a,3 ;âûáèðàåì ðåãèñòðû òîíà: sub d ;3-3=0, 3-2=1, 3-1=2 add a,a ;0*2=0, 1*2=2, 2*2=4 out ($a0),a ;âûâîäèì çíà÷åíèÿ òîíà .db $FD,$4C ;ld c,iyh ;$A0(off)/$A1(on) ld d,(ix+5) out (c),d inc a out ($a0),a ld d,(ix+6) out (c),d bit 6,e ;áóäåò èçìåíåíèå øóìà? jr z,afxFrame3 ;øóì íå èçìåíÿåòñÿ ld a,(hl) ;÷èòàåì çíà÷åíèå øóìà sub $20 jr c,afxFrame2 ;ìåíüøå $20, èãðàåì äàëüøå ld h,a ;èíà÷å êîíåö ýôôåêòà ld (ix+2),$fe ;äåëàåì âðåìÿ íàèáîëüøèì-1 ld (ix+3),$ff ld e,$90 ;âûêëþ÷àåì òîí è øóì â ìèêøåðå .db $FD,$26,$A1; ld iyh,$a1 ;÷òîáû òî÷íî âûêëþ÷èòü jr afxFrame3 afxFrame2: inc hl ld c,$a0 ;âûâîä çíà÷åíèÿ øóìà ld d,6 out (c),d .db $FD,$4C ;ld c,iyh ;$A0(off)/$A1(on) out (c),a afxFrame3: pop bc ;âîññòàíàâëèâàåì çíà÷åíèå öèêëà â B push bc inc b ;êîëè÷åñòâî ñäâèãîâ äëÿ ôëàãîâ TN (4..2) ld a,%01101111 ;ìàñêà äëÿ ôëàãîâ TN afxFrame4: rrc e ;ñäâèãàåì ôëàãè è ìàñêó rrca djnz afxFrame4 ld d,a ld a,7 out ($a0),a in a,($a2) xor e ;íàêëàäûâàåì ôëàãè êàíàëà and d xor e .db $FD,$4C ;ld c,iyh ;$A0(off)/$A1(on) out (c),a ;âûâîäèì îáðàòíî â ìèêøåð afxFrame5: ld c,(ix+2) ;óâåëè÷èâàåì ñ÷¸ò÷èê âðåìåíè ld b,(ix+3) inc bc ld (ix+2),c ld (ix+3),b ld (ix+0),l ;ñîõðàíÿåì èçìåíèâøèéñÿ àäðåñ ld (ix+1),h afxFrame7: ld bc,7 ;ïåðåõîäèì ê ñëåäóþùåìó êàíàëó add ix,bc pop bc dec b jp nz,afxFrame0 ret AYFX.PLAY: call memBank2 push bc ;ñîõðàíÿåì ãðîìêîñòü ld de,0 ;â de íàèáîëüøåå âðåìÿ ïðè ïîèñêå ld h,e ld l,a add hl,hl ld bc,(afxBnkAdr) ;àäðåñ òàáëèöû ñìåùåíèé ýôôåêòîâ add hl,bc ld c,(hl) inc hl ld b,(hl) add hl,bc ;àäðåñ ýôôåêòà ïîëó÷åí â hl push hl ;ñîõðàíÿåì àäðåñ ýôôåêòà íà ñòåêå ld hl,afxChDesc ;ïîèñê ïóñòîãî êàíàëà ld b,3 afxPlay0: inc hl inc hl ld a,(hl) ;ñðàâíèâàåì âðåìÿ êàíàëà ñ íàèáîëüøèì inc hl inc hl cp e jr c,afxPlay1 ld c,a ld a,(hl) cp d jr c,afxPlay1 ld e,c ;çàïîìèíàåì íàèáîëüøåå âðåìÿ ld d,a push hl ;çàïîìèíàåì àäðåñ êàíàëà +3 â ix pop ix afxPlay1: inc hl inc hl inc hl djnz afxPlay0 pop de ;çàáèðàåì àäðåñ ýôôåêòà èç ñòåêà ld (ix-4),e ;çàíîñèì â îïèñàòåëü êàíàëà ld (ix-3),d ld (ix-2),b ;çàíóëÿåì âðåìÿ çâó÷àíèÿ ld (ix-1),b pop bc ;çàáèðàåì ãðîìêîñòü ld (ix-0),c ;è çàíîñèì å¸ â îïèñàòåëü êàíàëà ret ;------------------------------------------------------------------------------ ; .INCLUDE "pt3.asm" ;------------------------------------------------------------------------------ ;DEFINE SELFMC ;enable self-modified code ;comment this define for ROM version ;to define addr. for vars use PT3P_RAM ;Vortex Tracker II v1.0 PT3 player for MSX ;Adapted by Alfonso D. C. aka Dioniso ;09-Jan-05 ;From: ;Vortex Tracker II v1.0 PT3 player for ZX Spectrum ;(c)2004 S.V.Bulba <a href="http://bulba.at.kz" title="http://bulba.at.kz">http://bulba.at.kz</a> ;Chaos Assembler version by KdL 2007 ;Release number Release: .equ '6' ;Features ;-------- ;-Can be compiled at any address (i.e. no need rounding .org ; address). ;-Variables (VARS) can be located at any address (not only after ;code block). ;-INIT subroutine detects module version and rightly generates ; both note and volume tables outside of code block (in VARS). ;-Two portamento (spc. command 3xxx) algorithms (depending of ; module version). ;-Any Tempo value are accepted (including Tempo=1 and Tempo=2). ;-Fully compatible with Ay_Emul PT3 player codes. ;-See also notes at the end of this source code. ;Limitations ;----------- ;-Can run in RAM only (self-modified code is used). ;Warning!!! PLAY subroutine can crash if no module are loaded ;into RAM or INIT subroutine was not called before. ;Call MUTE or INIT one more time to mute sound after stopping ;playing ;Entry and other points ;START initialization ;START+3 initialization with module address in HL ;START+5 play one quark ;START+8 mute ;START+10 setup and status flags ;START+11 pointer to current position value in PT3 module; ;After INIT (START+11) points to Postion0-1 (optimization) START: LD HL,MDLADDR ;Address of PT3 module JR PT3P.INIT ;START+3 JP PT3P.PLAY ;START+5 JR PT3P.MUTE ;START+8 #IFDEF SELFMC SETUP: .db 0 ;set bit0 to 1, if you want to play without looping ;bit7 is set each time, when loop point is passed CrPsPtr: .dw 0 #ENDIF ;Identifier .db "=VTII PT3 Player r.",Release,"=" CHECKLP: LD HL,SETUP SET 7,(HL) BIT 0,(HL) RET Z POP HL LD HL,DelyCnt INC (HL) LD HL,ChanA+CHNPRM_NtSkCn INC (HL) PT3P.MUTE: XOR A LD H,A LD L,A LD (AYREGS+AR_AmplA),A LD (AYREGS+AR_AmplB),HL JP ROUT_A0 PT3P.INIT: ;HL - AddressOfModule LD (MODADDR),HL LD (MDADDR2),HL PUSH HL LD DE,100 ADD HL,DE LD A,(HL) LD (Delay),A PUSH HL POP IX ADD HL,DE LD (CrPsPtr),HL LD E,(IX+102-100) ADD HL,DE INC HL LD (LPosPtr),HL POP DE LD L,(IX+103-100) LD H,(IX+104-100) ADD HL,DE LD (PatsPtr),HL LD HL,169 ADD HL,DE LD (OrnPtrs),HL LD HL,105 ADD HL,DE LD (SamPtrs),HL LD HL,SETUP RES 7,(HL) ;note table data depacker LD DE,T_PACK LD BC,T1_+(2*49)-1 TP_0: LD A,(DE) INC DE CP 15*2 JR NC,TP_1 LD H,A LD A,(DE) LD L,A INC DE JR TP_2 TP_1: PUSH DE LD D,0 LD E,A ADD HL,DE ADD HL,DE POP DE TP_2: LD A,H LD (BC),A DEC BC LD A,L LD (BC),A DEC BC SUB $F0 JR NZ,TP_0 LD HL,VARS LD (HL),A LD DE,VARS+1 LD BC,VAR0END-VARS-1 LDIR INC A LD (DelyCnt),A LD HL,$F001 ;H - CHNPRM_Volume, L - CHNPRM_NtSkCn LD (ChanA+CHNPRM_NtSkCn),HL LD (ChanB+CHNPRM_NtSkCn),HL LD (ChanC+CHNPRM_NtSkCn),HL LD HL,EMPTYSAMORN LD (AdInPtA),HL ;ptr to zero LD (ChanA+CHNPRM_OrnPtr),HL ;ornament 0 is "0,1,0" LD (ChanB+CHNPRM_OrnPtr),HL ;in all versions from LD (ChanC+CHNPRM_OrnPtr),HL ;3.xx to 3.6x and VTII LD (ChanA+CHNPRM_SamPtr),HL ;S1 There is no default LD (ChanB+CHNPRM_SamPtr),HL ;S2 sample in PT3, so, you LD (ChanC+CHNPRM_SamPtr),HL ;S3 can comment S1,2,3; see ;also EMPTYSAMORN comment LD A,(IX+13-100) ;EXTRACT VERSION NUMBER SUB $30 JR C,L20 CP 10 JR C,L21 L20: LD A,6 L21: LD (Version),A PUSH AF CP 4 LD A,(IX+99-100) ;TONE TABLE NUMBER RLA AND 7 ;NoteTableCreator (c) Ivan Roshin ;A - NoteTableNumber*2+VersionForNoteTable ;(xx1b - 3.xx..3.4r, xx0b - 3.4x..3.6x..VTII1.0) LD HL,NT_DATA PUSH DE LD D,B ADD A,A LD E,A ADD HL,DE LD E,(HL) INC HL SRL E SBC A,A AND $A7 ;$00 (NOP) or $A7 (AND A) #IFDEF SELFMC LD (L3),A #ELSE LD (REAL_BDSM),A #ENDIF EX DE,HL POP BC ;BC=T1_ ADD HL,BC LD A,(DE) LD BC,T_ ADD A,C LD C,A ADC A,B SUB C LD B,A PUSH BC LD DE,NT_ PUSH DE LD B,12 L1: PUSH BC LD C,(HL) INC HL PUSH HL LD B,(HL) PUSH DE EX DE,HL LD DE,23 .db $DD,$26,$08 ; LD IXH,8 ;was .db $DD,$26,$08 ;LD XH,8 #IFDEF SELFMC L2: SRL B RR C L3: .db $19 ;AND A or NOP #ELSE L2: ld a,(REAL_BDSM) or a jr nz,_CV0 srl b rr c jr _CV1 _CV0: srl b rr c and a _CV1: #ENDIF ;self-modified code is cool, isn't? LD A,C ADC A,D ;=ADC 0 LD (HL),A INC HL LD A,B ADC A,D LD (HL),A ADD HL,DE .db $DD,$25 ; DEC IXH ;was .db $DD,$25 ;DEC XH JR NZ,L2 POP DE INC DE INC DE POP HL INC HL POP BC DJNZ L1 POP HL POP DE LD A,E PUSH DE LD DE,TCOLD_1 CP E POP DE JR NZ,CORR_1 LD A,$FD LD (NT_+$2E),A CORR_1: LD A,(DE) AND A JR Z,TC_EXIT RRA PUSH AF ADD A,A LD C,A ADD HL,BC POP AF JR NC,CORR_2 DEC (HL) DEC (HL) CORR_2: INC (HL) AND A SBC HL,BC INC DE JR CORR_1 TC_EXIT: POP AF ;VolTableCreator (c) Ivan Roshin ;A - VersionForVolumeTable (0..4 - 3.xx..3.4x; ;5.. - 3.5x..3.6x..VTII1.0) CP 5 LD HL,$11 LD D,H LD E,H LD A,$17 ;rla JR NC,M1 DEC L LD E,L XOR A #IFDEF SELFMC M1: LD (M2),A #ELSE M1: LD (REAL_BDSM),A #ENDIF LD IX,VT_+16 LD C,$10 INITV2: PUSH HL ADD HL,DE EX DE,HL SBC HL,HL #IFDEF SELFMC INITV1: LD A,L M2: .db $7D ;rla or nop, see above #ELSE INITV1: ld a,(REAL_BDSM) or a ld a,l jr z,$+3 rla #ENDIF ;self-modified code rules again LD A,H ADC A,0 LD (IX),A INC IX ADD HL,DE INC C LD A,C AND 15 JR NZ,INITV1 POP HL LD A,E CP $77 JR NZ,M3 INC E M3: LD A,C AND A JR NZ,INITV2 JP ROUT_A0 ;pattern decoder PD_OrSm: LD (IX-12+CHNPRM_Env_En),0 CALL SETORN LD A,(BC) INC BC RRCA PD_SAM: ADD A,A PD_SAM_: LD E,A LD D,0 #IFDEF SELFMC SamPtrs: .equ $+1 LD HL,$2121 #ELSE LD HL,(SamPtrs) #ENDIF ADD HL,DE LD E,(HL) INC HL LD D,(HL) #IFDEF SELFMC MODADDR: .equ $+1 LD HL,$2121 #ELSE LD HL,(MODADDR) #ENDIF ADD HL,DE LD (IX-12+CHNPRM_SamPtr),L LD (IX-12+CHNPRM_SamPtr+1),H JR PD_LOOP PD_VOL: RLCA RLCA RLCA RLCA LD (IX-12+CHNPRM_Volume),A JR PD_LP2 PD_EOff: LD (IX-12+CHNPRM_Env_En),A LD (IX-12+CHNPRM_PsInOr),A JR PD_LP2 PD_SorE: DEC A JR NZ,PD_ENV LD A,(BC) INC BC LD (IX-12+CHNPRM_NNtSkp),A JR PD_LP2 PD_ENV: CALL SETENV JR PD_LP2 PD_ORN: CALL SETORN JR PD_LOOP PD_ESAM: LD (IX-12+CHNPRM_Env_En),A LD (IX-12+CHNPRM_PsInOr),A CALL NZ,SETENV LD A,(BC) INC BC JR PD_SAM_ PTDECOD: LD A,(IX-12+CHNPRM_Note) #IFDEF SELFMC LD (PrNote+1),A #ELSE LD (PrNote),A #ENDIF LD L,(IX-12+CHNPRM_CrTnSl) LD H,(IX-12+CHNPRM_CrTnSl+1) #IFDEF SELFMC LD (PrSlide+1),HL #ELSE LD (PrSlide),HL #ENDIF PD_LOOP: LD DE,$2010 PD_LP2: LD A,(BC) INC BC ADD A,E JR C,PD_OrSm ADD A,D JR Z,PD_FIN JR C,PD_SAM ADD A,E JR Z,PD_REL JR C,PD_VOL ADD A,E JR Z,PD_EOff JR C,PD_SorE ADD A,96 JR C,PD_NOTE ADD A,E JR C,PD_ORN ADD A,D JR C,PD_NOIS ADD A,E JR C,PD_ESAM ADD A,A LD E,A PUSH DE LD DE,$DF20 LD HL,SPCCOMS ADD HL,DE POP DE ADD HL,DE LD E,(HL) INC HL LD D,(HL) PUSH DE JR PD_LOOP PD_NOIS: LD (Ns_Base),A JR PD_LP2 PD_REL: RES 0,(IX-12+CHNPRM_Flags) JR PD_RES PD_NOTE: LD (IX-12+CHNPRM_Note),A SET 0,(IX-12+CHNPRM_Flags) XOR A #IFDEF SELFMC PD_RES: LD (PDSP_+1),SP #ELSE PD_RES: LD (PDSP_),SP #ENDIF LD SP,IX LD H,A LD L,A PUSH HL PUSH HL PUSH HL PUSH HL PUSH HL PUSH HL #IFDEF SELFMC PDSP_: LD SP,$3131 #ELSE LD SP,(PDSP_) #ENDIF PD_FIN: LD A,(IX-12+CHNPRM_NNtSkp) LD (IX-12+CHNPRM_NtSkCn),A RET C_PORTM: RES 2,(IX-12+CHNPRM_Flags) LD A,(BC) INC BC ;SKIP PRECALCULATED TONE DELTA (BECAUSE ;CANNOT BE RIGHT AFTER PT3 COMPILATION) INC BC INC BC LD (IX-12+CHNPRM_TnSlDl),A LD (IX-12+CHNPRM_TSlCnt),A LD DE,NT_ LD A,(IX-12+CHNPRM_Note) LD (IX-12+CHNPRM_SlToNt),A ADD A,A LD L,A LD H,0 ADD HL,DE LD A,(HL) INC HL LD H,(HL) LD L,A PUSH HL #IFDEF SELFMC PrNote: LD A,$3E #ELSE LD A,(PrNote) #ENDIF LD (IX-12+CHNPRM_Note),A ADD A,A LD L,A LD H,0 ADD HL,DE LD E,(HL) INC HL LD D,(HL) POP HL SBC HL,DE LD (IX-12+CHNPRM_TnDelt),L LD (IX-12+CHNPRM_TnDelt+1),H LD E,(IX-12+CHNPRM_CrTnSl) LD D,(IX-12+CHNPRM_CrTnSl+1) #IFDEF SELFMC Version: .equ 1 LD A,$3E #ELSE LD A,(Version) #ENDIF CP 6 JR C,OLDPRTM ;Old 3xxx for PT v3.5- #IFDEF SELFM PrSlide: LD DE,$1111 #ELSE LD DE,(PrSlide) #ENDIF LD (IX-12+CHNPRM_CrTnSl),E LD (IX-12+CHNPRM_CrTnSl+1),D OLDPRTM: LD A,(BC) ;SIGNED TONE STEP INC BC EX AF,AF' LD A,(BC) INC BC AND A JR Z,NOSIG EX DE,HL NOSIG: SBC HL,DE JP P,SET_STP CPL EX AF,AF' NEG EX AF,AF' SET_STP: LD (IX-12+CHNPRM_TSlStp+1),A EX AF,AF' LD (IX-12+CHNPRM_TSlStp),A LD (IX-12+CHNPRM_COnOff),0 RET C_GLISS: SET 2,(IX-12+CHNPRM_Flags) LD A,(BC) INC BC LD (IX-12+CHNPRM_TnSlDl),A LD (IX-12+CHNPRM_TSlCnt),A LD A,(BC) INC BC EX AF,AF' LD A,(BC) INC BC JR SET_STP C_SMPOS: LD A,(BC) INC BC LD (IX-12+CHNPRM_PsInSm),A RET C_ORPOS: LD A,(BC) INC BC LD (IX-12+CHNPRM_PsInOr),A RET C_VIBRT: LD A,(BC) INC BC LD (IX-12+CHNPRM_OnOffD),A LD (IX-12+CHNPRM_COnOff),A LD A,(BC) INC BC LD (IX-12+CHNPRM_OffOnD),A XOR A LD (IX-12+CHNPRM_TSlCnt),A LD (IX-12+CHNPRM_CrTnSl),A LD (IX-12+CHNPRM_CrTnSl+1),A RET C_ENGLS: LD A,(BC) INC BC LD (Env_Del),A LD (CurEDel),A LD A,(BC) INC BC LD L,A LD A,(BC) INC BC LD H,A LD (ESldAdd),HL RET C_DELAY: LD A,(BC) INC BC LD (Delay),A RET SETENV: LD (IX-12+CHNPRM_Env_En),E LD (AYREGS+AR_EnvTp),A LD A,(BC) INC BC LD H,A LD A,(BC) INC BC LD L,A LD (EnvBase),HL XOR A LD (IX-12+CHNPRM_PsInOr),A LD (CurEDel),A LD H,A LD L,A LD (CurESld),HL C_NOP: RET SETORN: ADD A,A LD E,A LD D,0 LD (IX-12+CHNPRM_PsInOr),D #IFDEF SELFMC OrnPtrs: .equ $+1 LD HL,$2121 #ELSE LD HL,(OrnPtrs) #ENDIF ADD HL,DE LD E,(HL) INC HL LD D,(HL) #IFDEF SELFMC MDADDR2: .equ $+1 LD HL,$2121 #ELSE LD HL,(MDADDR2) #ENDIF ADD HL,DE LD (IX-12+CHNPRM_OrnPtr),L LD (IX-12+CHNPRM_OrnPtr+1),H RET ;ALL 16 ADDRESSES TO PROTECT FROM BROKEN PT3 MODULES SPCCOMS: .dw C_NOP .dw C_GLISS .dw C_PORTM .dw C_SMPOS .dw C_ORPOS .dw C_VIBRT .dw C_NOP .dw C_NOP .dw C_ENGLS .dw C_DELAY .dw C_NOP .dw C_NOP .dw C_NOP .dw C_NOP .dw C_NOP .dw C_NOP CHREGS: XOR A LD (Ampl),A BIT 0,(IX+CHNPRM_Flags) PUSH HL JP Z,CH_EXIT #IFDEF SELFMC LD (CSP_+1),SP #ELSE LD (CSP_),SP #ENDIF LD L,(IX+CHNPRM_OrnPtr) LD H,(IX+CHNPRM_OrnPtr+1) LD SP,HL POP DE LD H,A LD A,(IX+CHNPRM_PsInOr) LD L,A ADD HL,SP INC A CP D JR C,CH_ORPS LD A,E CH_ORPS: LD (IX+CHNPRM_PsInOr),A LD A,(IX+CHNPRM_Note) ADD A,(HL) JP P,CH_NTP XOR A CH_NTP: CP 96 JR C,CH_NOK LD A,95 CH_NOK: ADD A,A EX AF,AF' LD L,(IX+CHNPRM_SamPtr) LD H,(IX+CHNPRM_SamPtr+1) LD SP,HL POP DE LD H,0 LD A,(IX+CHNPRM_PsInSm) LD B,A ADD A,A ADD A,A LD L,A ADD HL,SP LD SP,HL LD A,B INC A CP D JR C,CH_SMPS LD A,E CH_SMPS: LD (IX+CHNPRM_PsInSm),A POP BC POP HL LD E,(IX+CHNPRM_TnAcc) LD D,(IX+CHNPRM_TnAcc+1) ADD HL,DE BIT 6,B JR Z,CH_NOAC LD (IX+CHNPRM_TnAcc),L LD (IX+CHNPRM_TnAcc+1),H CH_NOAC: EX DE,HL EX AF,AF' LD L,A LD H,0 LD SP,NT_ ADD HL,SP LD SP,HL POP HL ADD HL,DE LD E,(IX+CHNPRM_CrTnSl) LD D,(IX+CHNPRM_CrTnSl+1) ADD HL,DE #IFDEF SELFMC CSP_: LD SP,$3131 #ELSE LD SP,(CSP_) #ENDIF EX (SP),HL XOR A OR (IX+CHNPRM_TSlCnt) JR Z,CH_AMP DEC (IX+CHNPRM_TSlCnt) JR NZ,CH_AMP LD A,(IX+CHNPRM_TnSlDl) LD (IX+CHNPRM_TSlCnt),A LD L,(IX+CHNPRM_TSlStp) LD H,(IX+CHNPRM_TSlStp+1) LD A,H ADD HL,DE LD (IX+CHNPRM_CrTnSl),L LD (IX+CHNPRM_CrTnSl+1),H BIT 2,(IX+CHNPRM_Flags) JR NZ,CH_AMP LD E,(IX+CHNPRM_TnDelt) LD D,(IX+CHNPRM_TnDelt+1) AND A JR Z,CH_STPP EX DE,HL CH_STPP: SBC HL,DE JP M,CH_AMP LD A,(IX+CHNPRM_SlToNt) LD (IX+CHNPRM_Note),A XOR A LD (IX+CHNPRM_TSlCnt),A LD (IX+CHNPRM_CrTnSl),A LD (IX+CHNPRM_CrTnSl+1),A CH_AMP: LD A,(IX+CHNPRM_CrAmSl) BIT 7,C JR Z,CH_NOAM BIT 6,C JR Z,CH_AMIN CP 15 JR Z,CH_NOAM INC A JR CH_SVAM CH_AMIN: CP -15 JR Z,CH_NOAM DEC A CH_SVAM: LD (IX+CHNPRM_CrAmSl),A CH_NOAM: LD L,A LD A,B AND 15 ADD A,L JP P,CH_APOS XOR A CH_APOS: CP 16 JR C,CH_VOL LD A,15 CH_VOL: OR (IX+CHNPRM_Volume) LD L,A LD H,0 LD DE,VT_ ADD HL,DE LD A,(HL) CH_ENV: BIT 0,C JR NZ,CH_NOEN OR (IX+CHNPRM_Env_En) CH_NOEN: LD (Ampl),A BIT 7,B LD A,C JR Z,NO_ENSL RLA RLA SRA A SRA A SRA A ADD A,(IX+CHNPRM_CrEnSl) ;SEE COMMENT BELOW BIT 5,B JR Z,NO_ENAC LD (IX+CHNPRM_CrEnSl),A NO_ENAC: LD HL,AddToEn ADD A,(HL) ;BUG IN PT3 - NEED WORD HERE. ;FIX IT IN NEXT VERSION? LD (HL),A JR CH_MIX NO_ENSL: RRA ADD A,(IX+CHNPRM_CrNsSl) LD (AddToNs),A BIT 5,B JR Z,CH_MIX LD (IX+CHNPRM_CrNsSl),A CH_MIX: LD A,B RRA AND $48 CH_EXIT: LD HL,AYREGS+AR_Mixer OR (HL) RRCA LD (HL),A POP HL XOR A OR (IX+CHNPRM_COnOff) RET Z DEC (IX+CHNPRM_COnOff) RET NZ XOR (IX+CHNPRM_Flags) LD (IX+CHNPRM_Flags),A RRA LD A,(IX+CHNPRM_OnOffD) JR C,CH_ONDL LD A,(IX+CHNPRM_OffOnD) CH_ONDL: LD (IX+CHNPRM_COnOff),A RET PT3P.PLAY: call memBank2 XOR A LD (AddToEn),A LD (AYREGS+AR_Mixer),A DEC A LD (AYREGS+AR_EnvTp),A LD HL,DelyCnt DEC (HL) #IFDEF SELFMC JR NZ,PL2 #ELSE JP NZ,PL2 #ENDIF LD HL,ChanA+CHNPRM_NtSkCn DEC (HL) JR NZ,PL1B #IFDEF SELFMC AdInPtA: .equ $+1 LD BC,$0101 #ELSE LD BC,(AdInPtA) #ENDIF LD A,(BC) AND A JR NZ,PL1A LD D,A LD (Ns_Base),A LD HL,(CrPsPtr) INC HL LD A,(HL) INC A JR NZ,PLNLP CALL CHECKLP #IFDEF SELFMC LPosPtr: .equ $+1 LD HL,$2121 #ELSE LD HL,(LPosPtr) #ENDIF LD A,(HL) INC A PLNLP: LD (CrPsPtr),HL DEC A ADD A,A LD E,A RL D #IFDEF SELFMC PatsPtr: .equ $+1 LD HL,$2121 #ELSE LD HL,(PatsPtr) #ENDIF ADD HL,DE LD DE,(MODADDR) #IFDEF SELFMC LD (PSP_+1),SP #ELSE LD (PSP_),SP #ENDIF LD SP,HL POP HL ADD HL,DE LD B,H LD C,L POP HL ADD HL,DE LD (AdInPtB),HL POP HL ADD HL,DE LD (AdInPtC),HL #IFDEF SELFMC PSP_: LD SP,$3131 #ELSE LD SP,(PSP_) #ENDIF PL1A: LD IX,ChanA+12 CALL PTDECOD LD (AdInPtA),BC PL1B: LD HL,ChanB+CHNPRM_NtSkCn DEC (HL) JR NZ,PL1C LD IX,ChanB+12 #IFDEF SELFMC AdInPtB: .equ $+1 LD BC,$0101 #ELSE LD BC,(AdInPtB) #ENDIF CALL PTDECOD LD (AdInPtB),BC PL1C: LD HL,ChanC+CHNPRM_NtSkCn DEC (HL) JR NZ,PL1D LD IX,ChanC+12 #IFDEF SELFMC AdInPtC: .equ $+1 LD BC,$0101 #ELSE LD BC,(AdInPtC) #ENDIF CALL PTDECOD LD (AdInPtC),BC #IFDEF SELFMC Delay: .equ $+1 PL1D: LD A,$3E #ELSE PL1D: LD A,(Delay) #ENDIF LD (DelyCnt),A PL2: LD IX,ChanA LD HL,(AYREGS+AR_TonA) CALL CHREGS LD (AYREGS+AR_TonA),HL LD A,(Ampl) LD (AYREGS+AR_AmplA),A LD IX,ChanB LD HL,(AYREGS+AR_TonB) CALL CHREGS LD (AYREGS+AR_TonB),HL LD A,(Ampl) LD (AYREGS+AR_AmplB),A LD IX,ChanC LD HL,(AYREGS+AR_TonC) CALL CHREGS ; LD A,(Ampl) ;Ampl = AYREGS+AR_AmplC ; LD (AYREGS+AR_AmplC),A LD (AYREGS+AR_TonC),HL LD HL,(Ns_Base_AddToNs) LD A,H ADD A,L LD (AYREGS+AR_Noise),A #IFDEF SELFMC AddToEn: .equ $+1 LD A,$3E #ELSE LD A,(AddToEn) #ENDIF LD E,A ADD A,A SBC A,A LD D,A LD HL,(EnvBase) ADD HL,DE LD DE,(CurESld) ADD HL,DE LD (AYREGS+AR_Env),HL XOR A LD HL,CurEDel OR (HL) JR Z,ROUT_A0 DEC (HL) JR NZ,ROUT #IFDEF SELFMC Env_Del: .equ $+1 LD A,$3E #ELSE LD A,(Env_Del) #ENDIF LD (HL),A #IFDEF SELFMC ESldAdd: .equ $+1 LD HL,$2121 #ELSE LD HL,(ESldAdd) #ENDIF ADD HL,DE LD (CurESld),HL ROUT: XOR A ROUT_A0: LD C,$A0 LD HL,AYREGS LOUT: OUT (C),A INC C OUTI DEC C INC A CP 13 JR NZ,LOUT OUT (C),A LD A,(HL) AND A RET M INC C OUT (C),A RET NT_DATA: .db (T_NEW_0-T1_)*2 .db TCNEW_0-T_ .db (T_OLD_0-T1_)*2+1 .db TCOLD_0-T_ .db (T_NEW_1-T1_)*2+1 .db TCNEW_1-T_ .db (T_OLD_1-T1_)*2+1 .db TCOLD_1-T_ .db (T_NEW_2-T1_)*2 .db TCNEW_2-T_ .db (T_OLD_2-T1_)*2 .db TCOLD_2-T_ .db (T_NEW_3-T1_)*2 .db TCNEW_3-T_ .db (T_OLD_3-T1_)*2 .db TCOLD_3-T_ T_: TCOLD_0: .db $00+1,$04+1,$08+1,$0A+1,$0C+1,$0E+1,$12+1,$14+1 .db $18+1,$24+1,$3C+1,0 TCOLD_1: .db $5C+1,0 TCOLD_2: .db $30+1,$36+1,$4C+1,$52+1,$5E+1,$70+1,$82,$8C,$9C .db $9E,$A0,$A6,$A8,$AA,$AC,$AE,$AE,0 TCNEW_3: .db $56+1 TCOLD_3: .db $1E+1,$22+1,$24+1,$28+1,$2C+1,$2E+1,$32+1,$BE+1,0 TCNEW_0: .db $1C+1,$20+1,$22+1,$26+1,$2A+1,$2C+1,$30+1,$54+1 .db $BC+1,$BE+1,0 TCNEW_1: .equ TCOLD_1 TCNEW_2: .db $1A+1,$20+1,$24+1,$28+1,$2A+1,$3A+1,$4C+1,$5E+1 .db $BA+1,$BC+1,$BE+1,0 EMPTYSAMORN: .equ $-1 .db 1,0,$90 ;delete $90 if you don't need default sample ;first 12 values of tone tables (packed) T_PACK: .db $0005,$0DD8 .db $0755-$06EC .db $07C5-$0755 .db $083B-$07C5 .db $08B8-$083B .db $093D-$08B8 .db $09CA-$093D .db $0A5F-$09CA .db $0AFC-$0A5F .db $0BA4-$0AFC .db $0C55-$0BA4 .db $0D10-$0C55 .db $0005,$0CDA .db $06CF-$066D .db $0737-$06CF .db $07A4-$0737 .db $0819-$07A4 .db $0894-$0819 .db $0917-$0894 .db $09A1-$0917 .db $0A33-$09A1 .db $0ACF-$0A33 .db $0B73-$0ACF .db $0C22-$0B73 .db $0CDA-$0C22 .db $0006,$0E08 .db $076E-$0704 .db $07E0-$076E .db $0858-$07E0 .db $08D6-$0858 .db $095C-$08D6 .db $09EC-$095C .db $0A82-$09EC .db $0B22-$0A82 .db $0BCC-$0B22 .db $0C80-$0BCC .db $0D3E-$0C80 .db $0006,$0FC0 .db $0858-$07E0 .db $08E0-$0858 .db $0960-$08E0 .db $09F0-$0960 .db $0A88-$09F0 .db $0B28-$0A88 .db $0BD8-$0B28 .db $0C80-$0BD8 .db $0D60-$0C80 .db $0E10-$0D60 .db $0EF8-$0E10 ;vars from here can be stripped ;you can move VARS to any other address VARS: ;ChannelsVars ;struc CHNPRM ;reset group CHNPRM_PsInOr: .equ 0 ;RESB 1 CHNPRM_PsInSm: .equ 1 ;RESB 1 CHNPRM_CrAmSl: .equ 2 ;RESB 1 CHNPRM_CrNsSl: .equ 3 ;RESB 1 CHNPRM_CrEnSl: .equ 4 ;RESB 1 CHNPRM_TSlCnt: .equ 5 ;RESB 1 CHNPRM_CrTnSl: .equ 6 ;RESW 1 CHNPRM_TnAcc: .equ 8 ;RESW 1 CHNPRM_COnOff: .equ 10 ;RESB 1 ;reset group CHNPRM_OnOffD: .equ 11 ;RESB 1 ;IX for PTDECOD here (+12) CHNPRM_OffOnD: .equ 12 ;RESB 1 CHNPRM_OrnPtr: .equ 13 ;RESW 1 CHNPRM_SamPtr: .equ 15 ;RESW 1 CHNPRM_NNtSkp: .equ 17 ;RESB 1 CHNPRM_Note: .equ 18 ;RESB 1 CHNPRM_SlToNt: .equ 19 ;RESB 1 CHNPRM_Env_En: .equ 20 ;RESB 1 CHNPRM_Flags: .equ 21 ;RESB 1 ;Enabled - 0,SimpleGliss - 2 CHNPRM_TnSlDl: .equ 22 ;RESB 1 CHNPRM_TSlStp: .equ 23 ;RESW 1 CHNPRM_TnDelt: .equ 25 ;RESW 1 CHNPRM_NtSkCn: .equ 27 ;RESB 1 CHNPRM_Volume: .equ 28 ;RESB 1 CHNPRM_Size .equ 29 ;RESB 1 ;endstruc ChanA: .ds CHNPRM_Size ChanB: .ds CHNPRM_Size ChanC: .ds CHNPRM_Size ;struc AR AR_TonA: .equ 0 ;RESW 1 AR_TonB: .equ 2 ;RESW 1 AR_TonC: .equ 4 ;RESW 1 AR_Noise: .equ 6 ;RESB 1 AR_Mixer: .equ 7 ;RESB 1 AR_AmplA: .equ 8 ;RESB 1 AR_AmplB: .equ 9 ;RESB 1 AR_AmplC: .equ 10 ;RESB 1 AR_Env: .equ 11 ;RESW 1 AR_EnvTp: .equ 13 ;RESB 1 ;endstruc ;GlobalVars DelyCnt: .db 0 CurESld: .dw 0 CurEDel: .db 0 Ns_Base_AddToNs: Ns_Base: .db 0 AddToNs: .db 0 AYREGS: VT_: .ds 256 ;CreatedVolumeTableAddress EnvBase: .equ VT_+14 T1_: .equ VT_+16 ;Tone tables data depacked here T_OLD_1: .equ T1_ T_OLD_2: .equ T_OLD_1+24 T_OLD_3: .equ T_OLD_2+24 T_OLD_0: .equ T_OLD_3+2 T_NEW_0: .equ T_OLD_0 T_NEW_1: .equ T_OLD_1 T_NEW_2: .equ T_NEW_0+24 T_NEW_3: .equ T_OLD_3 NT_: .ds 192 ;CreatedNoteTableAddress ;local var Ampl: .equ AYREGS+AR_AmplC ;local vars from self-modified code #IFNDEF SELFMC SamPtrs: .dw 0 MODADDR: .dw 0 MDADDR2: .dw 0 Version: .db 0 OrnPtrs: .dw 0 LPosPtr: .dw 0 PatsPtr: .dw 0 AdInPtA: .dw 0 AdInPtB: .dw 0 AdInPtC: .dw 0 Delay: .db 0 AddToEn: .db 0 Env_Del: .db 0 ESldAdd: .dw 0 PDSP_: .dw 0 PrNote: .db 0 PrSlide: .dw 0 CSP_: .dw 0 PSP_: .dw 0 REAL_BDSM: .db 0 SETUP: .db 0 ;set bit0 to 1, if you want to play without looping ;bit7 is set each time, when loop point is passed CrPsPtr: .dw 0 #ENDIF VAR0END: .equ VT_+16 ;INIT zeroes from VARS to VAR0END-1 VARSEND: .equ $ MDLADDR: .equ $ ;Place your song here. ;Release 0 steps: ;11.Sep.2004 - Note tables creator ;12.Sep.2004 - Volume tables creator; INIT subroutine ;13.Sep.2004 - Play counters, position counters ;14.Sep.2004 - Patterns decoder subroutine ;15.Sep.2004 - Resting (no code) ;16.Sep.2004 - CHREGS subroutine; global debugging; 1st stable ;version was born ;17.Sep.2004 - Debugging and optimization. First release! ;Release 1 steps: ;20.Sep.2004 - local vars moved to code (selfmodified code ;smaller and faster) ;22.Sep.2004 - added mute sound entry at START+8; position ;pointer moved to START+11; added setup and status byte at ;START+10 noloop mode and loop passed flags added ;Release 2 steps: ;28.Sep.2004 - Optimization: code around CHREGS's volume and ;vibrato faster now; zeroing PD_RES through stack; Ton and Ampl ;moved from channel vars to global ones; first position selector ;removed from INIT; optimization for packers(Ivan Roshin method) ;Release 3 steps: ;2.Oct.2004 - optimization in INIT and PD_LOOP (thanks to Ivan ;Roshin) ;4.Oct.2004 - load delay from (hl) in INIT (2 bytes shorter) ;5.Oct.2004 - optimization in PD_LOOP (->PD_LP2) ;7.Oct.2004 - swaping some commands for better packing ;Release 4 steps: ;9.Oct.2004 - optimization around LD HL,SPCCOMS (thanks to Ivan ;Roshin); in PTDECOD swapped BC and DE to optimize C_PORTM; ;removed sam and orn len and loop channel vars; CHREGS totally ;optimized ;Release 5 steps: ;11.Oct.2004 - PD_OrSm and C_PORTM optimized; Ivan Roshin's ;volume tables creator algorithm (51 bytes shorter than mine) ;12.Oct.2004 - Ivan Roshin's note tables creator algorithm (74 ;bytes shorter than mine) ;Release 6 steps: ;14.Oct.2004 - loop and next position calculations moved to INIT ;15.Oct.2004 - AdInPt moved to code ;19.Oct.2004 - Env_Del moved to code ;20.Oct.2004 - Version PUSH and POP (1 byte shorter, thanks to ;Ivan Roshin) ;22.Oct.2004 - Env_En moved from Flags' bit to byte (shorter and ;faster code) ;25.Oct.2004 - SETENV optimized ;29.Oct.2004 - Optimized around AddToEn (SBC A,A, thanks to Ivan ;Roshin) ;3.Nov.2004 - Note tables data was compressed; with depacker it ;is 9 bytes shorter than uncompressed (thanks to Ivan Roshin) ;4.Nov.2004 - default sample and ornament both are fixed now ;and placed into code block (6 bytes shorter) ;7.Nov.2004 - LD A,(Ns_Base):LD L,A changed to LD HL,(Ns_Base) ;(thanks to Dima Bystrov) ;9.Nov.2004 - Ns_Base and AddToNs are merged to Ns_Base_AddToNs; ;LD A,255 changed to DEC A (at start of PLAY); added ROUT_A0 ;12.Nov.2004 - NtSkCn&Volume are merged (8 bytes smaller init); ;LD BC,T1_ changed to PUSH DE...POP BC in note table creator ;19.Dec.2004 - NT_DATA reorganized (6 bytes shorter, thanks to ;Ivan Roshin); C_PORTM and C_GLISS are merged via SET_STP (48 ;tacts slower, but 8 bytes smaller, thanks to Ivan Roshin) ;09.Jan.2005 - Adapted to MSX by Alfonso D.C. a.k.a. Dioniso ;Notes: ;Pro Tracker 3.4r can not be detected by header, so PT3.4r tone ;tables realy used only for modules of 3.3 and older versions. ;------------------------------------------------------------------------------ .text "AFX-PT3.BIN v0.4 by KdL 2008" endProgram: .end