Login

Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download | RSS feed

;Vortex Tracker II v1.0 PT3 player for MSX
;Adapted by Alfonso D. C. aka Dioniso <dioniso072@yahoo.es>
;09-Jan-05
;From:
;Vortex Tracker II v1.0 PT3 player for ZX Spectrum
;(c)2004 S.V.Bulba <vorobey@mail.khstu.ru> http://bulba.at.kz

;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)
        module VTPL
START:
        LD HL,outputBuffer      ;Address of PT3 module
        JR INIT         ;START+3
        JP PLAY         ;START+5
        JR MUTE         ;START+8
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

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)
MUTE:   XOR A
        LD H,A
        LD L,A
        LD (AYREGS+AR_AmplA),A
        LD (AYREGS+AR_AmplB),HL
        JP ROUT_A0

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)
        LD (L3),A
        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 XH,8

L2:     SRL B
        RR C
L3:     .db $19 ;AND A or NOP
        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 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
        JR NC,M1
        DEC L
        LD E,L
        XOR A
M1:      LD (M2),A

        LD IX,VT_+16
        LD C,$10

INITV2:  PUSH HL

        ADD HL,DE
        EX DE,HL
        SBC HL,HL

INITV1:  LD A,L
M2:      .db $7D
        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
SamPtrs: .equ $+1
        LD HL,$2121
        ADD HL,DE
        LD E,(HL)
        INC HL
        LD D,(HL)
MODADDR: .equ $+1
        LD HL,$2121
        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)
        LD (PrNote+1),A
        LD L,(IX-12+CHNPRM_CrTnSl)
        LD H,(IX-12+CHNPRM_CrTnSl+1)
        LD (PrSlide+1),HL

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

PD_RES: LD (PDSP_+1),SP
        LD SP,IX
        LD H,A
        LD L,A
        PUSH HL
        PUSH HL
        PUSH HL
        PUSH HL
        PUSH HL
        PUSH HL
PDSP_:  LD SP,$3131

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
PrNote: LD A,$3E
        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)
Version: .equ $+1
        LD A,$3E
        CP 6
        JR C,OLDPRTM ;Old 3xxx for PT v3.5-
PrSlide:        LD DE,$1111
        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
OrnPtrs:        .equ $+1
        LD HL,$2121
        ADD HL,DE
        LD E,(HL)
        INC HL
        LD D,(HL)
MDADDR2:        .equ $+1
        LD HL,$2121
        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
        LD (CSP_+1),SP
        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
CSP_:   LD SP,$3131
        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

PLAY:    XOR A
        LD (AddToEn),A
        LD (AYREGS+AR_Mixer),A
        DEC A
        LD (AYREGS+AR_EnvTp),A
        LD HL,DelyCnt
        DEC (HL)
        JR NZ,PL2
        LD HL,ChanA+CHNPRM_NtSkCn
        DEC (HL)
        JR NZ,PL1B
AdInPtA:        .equ $+1
        LD BC,$0101
        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
LPosPtr:        .equ $+1
        LD HL,$2121
        LD A,(HL)
        INC A
PLNLP:  LD (CrPsPtr),HL
        DEC A
        ADD A,A
        LD E,A
        RL D
PatsPtr:        .equ $+1
        LD HL,$2121
        ADD HL,DE
        LD DE,(MODADDR)
        LD (PSP_+1),SP
        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
PSP_:   LD SP,$3131
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
AdInPtB:        .equ $+1
        LD BC,$0101
        CALL PTDECOD
        LD (AdInPtB),BC

PL1C:   LD HL,ChanC+CHNPRM_NtSkCn
        DEC (HL)
        JR NZ,PL1D
        LD IX,ChanC+12
AdInPtC:        .equ $+1
        LD BC,$0101
        CALL PTDECOD
        LD (AdInPtC),BC

Delay:  .equ $+1
PL1D:   LD A,$3E
        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

AddToEn: .equ $+1
        LD A,$3E
        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
Env_Del:        .equ $+1
        LD A,$3E
        LD (HL),A
ESldAdd:        .equ $+1
        LD HL,$2121
        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 $06EC*2/256,$06EC*2
        .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 $066D*2/256,$066D*2
        .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 $0704*2/256,$0704*2
        .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 $07E0*2/256,$07E0*2
        .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

VAR0END:        .equ VT_+16 ;INIT zeroes from VARS to VAR0END-1

VARSEND: .equ $
        endmodule
;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.