PROTRACKER372 PTSPLAY H

From MSX MUSIC WIKI
Jump to: navigation, search

PTSPlay C��3w�x{�

 ;Universal PT2'n'PT3 Turbo Sound player for ZX Spectrum
 ;2004-2007 S.V.Bulba <vorobey@mail.khstu.ru>
 ;http://bulba.untergrund.net/ (http://bulba.at.kz/)
 
 Release="0"
 
 ;read SjAsm or ZXAsm version source for comments.
 
 ;Conditional assembly
 ;1) Current position counters at (Vars1+0) and (Vars2+0)
 CurPosCounter=0
 ;2) Allow channels allocation bits at (START+10)
 ACBBAC=0
 ;3) Allow loop checking and disabling
 LoopChecker=0
 ;4) Insert official identificator
 IFN ?Id
 Id=1
 ENDIF 
 ;5) Set IY for correct return to ZX Basic
 IFN ?Basic
 Basic=0
 ENDIF 
 
        ;ORG #C000
 
 TonA=0
 TonB=2
 TonC=4
 Noise=6
 Mixer=7
 AmplA=8
 AmplB=9
 AmplC=10
 Env=11
 EnvTp=13
 
 ;ChannelsVars
        ;STRUCT  CHP
 ;reset group
 PsInOr=0
 PsInSm=1
 CrAmSl=2
 CrNsSl=3
 CrEnSl=4
 TSlCnt=5
 CrTnSl=6
 TnAcc=8
 COnOff=10
 ;reset group
 
 OnOffD=11
 
 ;IX for PTDECOD here (+12)
 OffOnD=12
 OrnPtr=13
 SamPtr=15
 NNtSkp=17
 Note=18
 SlToNt=19
 Env_En=20
 Flags=21
  ;Enabled - 0, SimpleGliss - 2
 TnSlDl=22
 TSlStp=23
 TnDelt=25
 NtSkCn=27
 Volume=28
        ;ENDS
 CHP=29
 
        ;STRUCT  VRS
 
 CurPos=0
 PosSub=1
 
 ModNum=2 ;bit0: ChipNum
              ;bit1: 1-reversed patterns order (AlCo TS)
 ChanA=3
 ChanB=ChanA+CHP
 ChanC=ChanB+CHP
 
 ;GlobalVars
 MODADDR=ChanC+CHP
 OrnPtrs=MODADDR+2
 SamPtrs=MODADDR+4
 PatsPtr=MODADDR+6
 AdInPtA=MODADDR+8
 AdInPtB=MODADDR+10
 AdInPtC=MODADDR+12
 CrPsPtr=MODADDR+14
 LPosPtr=MODADDR+16
 Delay=MODADDR+18
 DelyCnt=MODADDR+19
 ESldAdd=MODADDR+20
 CurESld=MODADDR+22
 Env_Del=MODADDR+24
 CurEDel=MODADDR+25
 Ns_Base=MODADDR+26
 AddToNs=MODADDR+27
 AddToEn=MODADDR+28
 EnvBase=MODADDR+29
 AYREGS=MODADDR+31
        ;ENDS
 VRS=AYREGS+14
 
 START
         LD HL,MDLADDR ;DE - address of 2nd module for TS
         JR INIT
         JP PLAY
         JR MUTE
 SETUP   DB 0
 
         IFN Id
         DB "=UniPT2/PT3/TS-Player r.",Release,"="
         ENDIF 
 
         IFN LoopChecker
 CHECKLP LD HL,SETUP
         BIT 0,(IY-100+ModNum)
         JR Z,CHL1
         SET 6,(HL)
         JR CHL2
 CHL1    SET 7,(HL)
 CHL2    BIT 0,(HL)
         RET Z
         POP HL
         INC (IY-100+DelyCnt)
         INC (IY-100+ChanA+NtSkCn)
         XOR A
         LD (IY-100+AYREGS+AmplA),A
         LD (IY-100+AYREGS+AmplB),A
         LD (IY-100+AYREGS+AmplC),A
         RET 
         ENDIF 
 
 MUTE    XOR A
         LD H,A
         LD L,A
         LD (VARS1+AYREGS+AmplA),A
         LD (VARS1+AYREGS+AmplB),HL
         LD (VARS2+AYREGS+AmplA),A
         LD (VARS2+AYREGS+AmplB),HL
         JP ROUT
 
 INIT
 ;HL - AddressOfModule
 ;DE - AddresOf2ndModule
         PUSH DE
         PUSH HL
         LD HL,VARS
         LD (HL),0
         LD DE,VARS+1
         LD BC,VAR0END-VARS-1
         LDIR 
         INC HL
         LD (VARS1+AdInPtA),HL ;ptr to zero
         LD (VARS2+AdInPtA),HL
 
         POP HL
         LD IY,VARS1+100
         LD A,(START+10)
         AND 2
         JP NZ,I_PT2
 
         CALL INITPT3
         LD HL,#1F18 ;(e_-SamCnv-2)*256+#18 ;ALASM :(
         LD (SamCnv),HL
         LD A,#BA
         LD (OrnCP),A
         LD (SamCP),A
         LD A,#7B
         LD (OrnLD),A
         LD (SamLD),A
         LD A,#87
         LD (SamClc2),A
         POP HL
         ;Use version and ton table of 1st module
         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 ;VolTable version
         CP 4
         LD A,(IX+99-100) ;TONE TABLE NUMBER
         RLA 
         AND 7
         PUSH AF ;NoteTable number
 
         LD IY,VARS2+100
         LD A,(START+10)
         AND 48
         JR Z,NOTS
         CP 16
         JR Z,TwoPT3s
         LD A,(Version)
         CP 7
         JR C,NOTS
         LD A,(IX+98-100) ;ALCO TS MARKER
         CP #20
         JR Z,NOTS
         LD HL,VARS1
         LD DE,VARS2
         LD BC,VRS
         LDIR 
         SET 1,(IY-100+ModNum)
         LD C,A
         ADD A,A
         ADD A,C
         SUB 2
         LD (TSSub),A
         JR AlCoTS_
 TwoPT3s CALL INITPT3
 AlCoTS_ LD A,1
         LD (is_ts),A
         SET 0,(IY-100+ModNum)
 
 NOTS    LD BC,PT3PD
         LD HL,0
         LD DE,PT3EMPTYORN
         JR INITCOMMON
 
 I_PT2   CALL INITPT2
         LD HL,#51CB
         LD (SamCnv),HL
         LD A,#BB
         LD (OrnCP),A
         LD (SamCP),A
         LD A,#7A
         LD (OrnLD),A
         LD (SamLD),A
         LD A,#80
         LD (SamClc2),A
         POP HL
         LD A,5
         LD (Version),A
         PUSH AF
         LD A,2
         PUSH AF
 
         LD A,(START+10)
         AND 48
         JR Z,NOTS2
 
         LD IY,VARS2+100
         LD A,1
         LD (is_ts),A
         SET 0,(IY-100+ModNum)
         CALL INITPT2
 
 NOTS2   LD BC,PT2PD
         LD HL,#8687
         LD DE,PT2EMPTYORN
 
 INITCOMMON
 
         IFN Basic
         LD IY,#5C3A
         ENDIF 
 
         LD (PTDEC),BC
         LD (PsCalc),HL
         PUSH DE
 
 ;note table data depacker
 ;(c) Ivan Roshin
         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 #F8*2
         JR NZ,TP_0
 
         INC A
         LD (VARS1+DelyCnt),A
         LD (VARS2+DelyCnt),A
         LD HL,#F001 ;H - Volume, L - NtSkCn
         LD (VARS1+ChanA+NtSkCn),HL
         LD (VARS1+ChanB+NtSkCn),HL
         LD (VARS1+ChanC+NtSkCn),HL
         LD (VARS2+ChanA+NtSkCn),HL
         LD (VARS2+ChanB+NtSkCn),HL
         LD (VARS2+ChanC+NtSkCn),HL
         POP HL
         LD (VARS1+ChanA+OrnPtr),HL
         LD (VARS1+ChanB+OrnPtr),HL
         LD (VARS1+ChanC+OrnPtr),HL
         LD (VARS2+ChanA+OrnPtr),HL
         LD (VARS2+ChanB+OrnPtr),HL
         LD (VARS2+ChanC+OrnPtr),HL
 
         POP AF
 
 ;NoteTableCreator (c) Ivan Roshin
 ;A - NoteTableNumber*2+VersionForNoteTable
 ;(xx1b - 3.xx..3.4r, xx0b - 3.4x..3.6x..VTII1.0)
 
         LD HL,NT_DATA
         LD D,0
         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
         LD BC,T1_
         ADD HL,BC
 
         LD A,(DE)
         ADD A,T_
         LD C,A
         ADC A,'T_
         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
         LD HX,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
         DEC HX
         JR NZ,L2
 
         POP DE
         INC DE
         INC DE
         POP HL
         INC HL
         POP BC
         DJNZ L1
 
         POP HL
         POP DE
 
         LD A,E
         CP TCOLD_1
         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.. - 2.x,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,#F
 INITV2  PUSH HL
 
         ADD HL,DE
         EX DE,HL
         SBC HL,HL
 
         LD B,#10
 INITV1  LD A,L
 M2      DB #7D
         LD A,H
         ADC A,0
         LD (IX),A
         INC IX
         ADD HL,DE
         DJNZ INITV1
 
         POP HL
         LD A,E
         CP #77
         JR NZ,M3
         INC E
 M3      DEC C
         JR NZ,INITV2
 
         JP ROUT
 
 INITPT3 CALL SETMDAD
         PUSH HL
         LD DE,100
         ADD HL,DE
         LD A,(HL)
         LD (IY-100+Delay),A
         PUSH HL
         POP IX
         ADD HL,DE
         CALL SETCPPT
         LD E,(IX+102-100)
         INC HL
 
         IFN CurPosCounter
         LD (IY-100+PosSub),L
         ENDIF 
 
         ADD HL,DE
         CALL SETLPPT
         POP DE
         LD L,(IX+103-100)
         LD H,(IX+104-100)
         ADD HL,DE
         CALL SETPTPT
         LD HL,169
         ADD HL,DE
         CALL SETORPT
         LD HL,105
         ADD HL,DE
 
 SETSMPT LD (IY-100+SamPtrs),L
         LD (IY-100+SamPtrs+1),H
         RET 
 
 INITPT2 LD A,(HL)
         LD (IY-100+Delay),A
         PUSH HL
         PUSH HL
         PUSH HL
         INC HL
         INC HL
         LD A,(HL)
         INC HL
         CALL SETSMPT
         LD E,(HL)
         INC HL
         LD D,(HL)
         POP HL
         AND A
         SBC HL,DE
         CALL SETMDAD
         POP HL
         LD DE,67
         ADD HL,DE
         CALL SETORPT
         LD E,32
         ADD HL,DE
         LD C,(HL)
         INC HL
         LD B,(HL)
         LD E,30
         ADD HL,DE
         CALL SETCPPT
         LD E,A
         INC HL
 
         IFN CurPosCounter
         LD (IY-100+PosSub),L
         ENDIF 
 
         ADD HL,DE
         CALL SETLPPT
         POP HL
         ADD HL,BC
 
 SETPTPT LD (IY-100+PatsPtr),L
         LD (IY-100+PatsPtr+1),H
         RET 
 
 SETMDAD LD (IY-100+MODADDR),L
         LD (IY-100+MODADDR+1),H
         RET 
 
 SETORPT LD (IY-100+OrnPtrs),L
         LD (IY-100+OrnPtrs+1),H
         RET 
 
 SETCPPT LD (IY-100+CrPsPtr),L
         LD (IY-100+CrPsPtr+1),H
         RET 
 
 SETLPPT LD (IY-100+LPosPtr),L
         LD (IY-100+LPosPtr+1),H
         RET 
 
 SETENBS LD (IY-100+EnvBase),L
         LD (IY-100+EnvBase+1),H
         RET 
 
 SETESLD LD (IY-100+CurESld),L
         LD (IY-100+CurESld+1),H
         RET 
 
 GETIX   PUSH IY
         POP IX
         ADD IX,DE
         RET 
 
 PTDECOD CALL GETIX
 PTDEC=$+1
         JP #C3C3
 
 ;PT2 pattern decoder
 PD2_SAM CALL SETSAM
         JR PD2_LOOP
 
 PD2_EOff LD (IX-12+Env_En),A
         JR PD2_LOOP
 
 PD2_ENV LD (IX-12+Env_En),16
         LD (IY-100+AYREGS+EnvTp),A
         LD A,(BC)
         INC BC
         LD L,A
         LD A,(BC)
         INC BC
         LD H,A
         CALL SETENBS
         JR PD2_LOOP
 
 PD2_ORN CALL SETORN
         JR PD2_LOOP
 
 PD2_SKIP INC A
         LD (IX-12+NNtSkp),A
         JR PD2_LOOP
 
 PD2_VOL RRCA 
         RRCA 
         RRCA 
         RRCA 
         LD (IX-12+Volume),A
         JR PD2_LOOP
 
 PD2_DEL CALL C_DELAY
         JR PD2_LOOP
 
 PD2_GLIS SET 2,(IX-12+Flags)
         INC A
         LD (IX-12+TnSlDl),A
         LD (IX-12+TSlCnt),A
         LD A,(BC)
         INC BC
         LD (IX-12+TSlStp),A
         ADD A,A
         SBC A,A
         LD (IX-12+TSlStp+1),A
         SCF 
         JR PD2_LP2
 
 PT2PD   AND A
 
 PD2_LP2 EXA 
 
 PD2_LOOP LD A,(BC)
         INC BC
         ADD A,#20
         JR Z,PD2_REL
         JR C,PD2_SAM
         ADD A,96
         JR C,PD2_NOTE
         INC A
         JR Z,PD2_EOff
         ADD A,15
         JP Z,PD_FIN
         JR C,PD2_ENV
         ADD A,#10
         JR C,PD2_ORN
         ADD A,#40
         JR C,PD2_SKIP
         ADD A,#10
         JR C,PD2_VOL
         INC A
         JR Z,PD2_DEL
         INC A
         JR Z,PD2_GLIS
         INC A
         JR Z,PD2_PORT
         INC A
         JR Z,PD2_STOP
         LD A,(BC)
         INC BC
         LD (IX-12+CrNsSl),A
         JR PD2_LOOP
 
 PD2_PORT RES 2,(IX-12+Flags)
         LD A,(BC)
         INC BC
         INC BC ;ignoring precalc delta to right sound
         INC BC
         SCF 
         JR PD2_LP2
 
 PD2_STOP LD (IX-12+TSlCnt),A
         JR PD2_LOOP
 
 PD2_REL LD (IX-12+Flags),A
         JR PD2_EXIT
 
 PD2_NOTE LD L,A
         LD A,(IX-12+Note)
         LD (PrNote+1),A
         LD (IX-12+Note),L
         XOR A
         LD (IX-12+TSlCnt),A
         SET 0,(IX-12+Flags)
         EXA 
         JR NC,NOGLIS2
         BIT 2,(IX-12+Flags)
         JR NZ,NOPORT2
         LD (LoStep),A
         ADD A,A
         SBC A,A
         EXA 
         LD H,A
         LD L,A
         INC A
         CALL SETPORT
 NOPORT2 LD (IX-12+TSlCnt),1
 NOGLIS2 XOR A
 
 
 PD2_EXIT LD (IX-12+PsInSm),A
         LD (IX-12+PsInOr),A
         LD (IX-12+CrTnSl),A
         LD (IX-12+CrTnSl+1),A
         JP PD_FIN
 
 ;PT3 pattern decoder
 PD_OrSm LD (IX-12+Env_En),0
         CALL SETORN
 PD_SAM_ LD A,(BC)
         INC BC
         RRCA 
 
 PD_SAM  CALL SETSAM
         JR PD_LOOP
 
 PD_VOL  RRCA 
         RRCA 
         RRCA 
         RRCA 
         LD (IX-12+Volume),A
         JR PD_LP2
 
 PD_EOff LD (IX-12+Env_En),A
         LD (IX-12+PsInOr),A
         JR PD_LP2
 
 PD_SorE DEC A
         JR NZ,PD_ENV
         LD A,(BC)
         INC BC
         LD (IX-12+NNtSkp),A
         JR PD_LP2
 
 PD_ENV  CALL SETENV
         JR PD_LP2
 
 PD_ORN  CALL SETORN
         JR PD_LOOP
 
 PD_ESAM LD (IX-12+Env_En),A
         LD (IX-12+PsInOr),A
         CALL NZ,SETENV
         JR PD_SAM_
 
 PT3PD   LD A,(IX-12+Note)
         LD (PrNote+1),A
         LD L,(IX-12+CrTnSl)
         LD H,(IX-12+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
         LD HL,SPCCOMS+#FF20-#2000
         ADD HL,DE
         LD E,(HL)
         INC HL
         LD D,(HL)
         PUSH DE
         JR PD_LOOP
 
 PD_NOIS LD (IY-100+Ns_Base),A
         JR PD_LP2
 
 PD_REL  RES 0,(IX-12+Flags)
         JR PD_RES
 
 PD_NOTE LD (IX-12+Note),A
         SET 0,(IX-12+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+NNtSkp)
         LD (IX-12+NtSkCn),A
         RET 
 
 C_PORTM LD A,(BC)
         INC BC
 ;SKIP PRECALCULATED TONE DELTA (BECAUSE
 ;CANNOT BE RIGHT AFTER PT3 COMPILATION)
         INC BC
         INC BC
         EXA 
         LD A,(BC) ;SIGNED TONE STEP
         INC BC
         LD (LoStep),A
         LD A,(BC)
         INC BC
         AND A
         EXA 
         LD L,(IX-12+CrTnSl)
         LD H,(IX-12+CrTnSl+1)
 
 ;Set portamento variables
 ;A - Delay; A' - Hi(Step); ZF' - (A'=0); HL - CrTnSl
 
 SETPORT RES 2,(IX-12+Flags)
         LD (IX-12+TnSlDl),A
         LD (IX-12+TSlCnt),A
         PUSH HL
         LD DE,NT_
         LD A,(IX-12+Note)
         LD (IX-12+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+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+TnDelt),L
         LD (IX-12+TnDelt+1),H
         POP DE
 Version=$+1
         LD A,#3E
         CP 6
         JR C,OLDPRTM ;Old 3xxx for PT v3.5-
 PrSlide LD DE,#1111
         LD (IX-12+CrTnSl),E
         LD (IX-12+CrTnSl+1),D
 LoStep=$+1
 OLDPRTM LD A,#3E
         EXA 
         JR Z,NOSIG
         EX DE,HL
 NOSIG   SBC HL,DE
         JP P,SET_STP
         CPL 
         EXA 
         NEG 
         EXA 
 SET_STP LD (IX-12+TSlStp+1),A
         EXA 
         LD (IX-12+TSlStp),A
         LD (IX-12+COnOff),0
         RET 
 
 C_GLISS SET 2,(IX-12+Flags)
         LD A,(BC)
         INC BC
         LD (IX-12+TnSlDl),A
         AND A
         JR NZ,GL36
         LD A,(Version) ;AlCo PT3.7+
         CP 7
         SBC A,A
         INC A
 GL36    LD (IX-12+TSlCnt),A
         LD A,(BC)
         INC BC
         EXA 
         LD A,(BC)
         INC BC
         JR SET_STP
 
 C_SMPOS LD A,(BC)
         INC BC
         LD (IX-12+PsInSm),A
         RET 
 
 C_ORPOS LD A,(BC)
         INC BC
         LD (IX-12+PsInOr),A
         RET 
 
 C_VIBRT LD A,(BC)
         INC BC
         LD (IX-12+OnOffD),A
         LD (IX-12+COnOff),A
         LD A,(BC)
         INC BC
         LD (IX-12+OffOnD),A
         XOR A
         LD (IX-12+TSlCnt),A
         LD (IX-12+CrTnSl),A
         LD (IX-12+CrTnSl+1),A
         RET 
 
 C_ENGLS LD A,(BC)
         INC BC
         LD (IY-100+Env_Del),A
         LD (IY-100+CurEDel),A
         LD A,(BC)
         INC BC
         LD L,A
         LD A,(BC)
         INC BC
         LD H,A
         LD (IY-100+ESldAdd),L
         LD (IY-100+ESldAdd+1),H
         RET 
 
 C_DELAY LD A,(BC)
         INC BC
         LD (IY-100+Delay),A
         LD HL,VARS2+ModNum ;if AlCo_TS
         BIT 1,(HL)
         RET Z
         LD (VARS1+Delay),A
         LD (VARS1+DelyCnt),A
         LD (VARS2+Delay),A
         RET 
 
 SETENV  LD (IX-12+Env_En),E
         LD (IY-100+AYREGS+EnvTp),A
         LD A,(BC)
         INC BC
         LD H,A
         LD A,(BC)
         INC BC
         LD L,A
         CALL SETENBS
         XOR A
         LD (IX-12+PsInOr),A
         LD (IY-100+CurEDel),A
         LD H,A
         LD L,A
         JP SETESLD
 
 SETORN  ADD A,A
         LD E,A
         LD D,0
         LD (IX-12+PsInOr),D
         LD L,(IY-100+OrnPtrs)
         LD H,(IY-100+OrnPtrs+1)
         ADD HL,DE
         LD E,(HL)
         INC HL
         LD D,(HL)
         LD L,(IY-100+MODADDR)
         LD H,(IY-100+MODADDR+1)
         ADD HL,DE
         LD (IX-12+OrnPtr),L
         LD (IX-12+OrnPtr+1),H
 C_NOP   RET 
 
 SETSAM  ADD A,A
         LD E,A
         LD D,0
         LD L,(IY-100+SamPtrs);
         LD H,(IY-100+SamPtrs+1);
         ADD HL,DE
         LD E,(HL)
         INC HL
         LD D,(HL)
         LD L,(IY-100+MODADDR)
         LD H,(IY-100+MODADDR+1)
         ADD HL,DE
         LD (IX-12+SamPtr),L
         LD (IX-12+SamPtr+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  CALL GETIX
         XOR A
         LD (Ampl),A
         BIT 0,(IX+Flags)
         PUSH HL
         JP Z,CH_EXIT
         LD (CSP_+1),SP
         LD L,(IX+OrnPtr)
         LD H,(IX+OrnPtr+1)
         LD SP,HL
         POP DE
         LD H,A
         LD A,(IX+PsInOr)
         LD L,A
         ADD HL,SP
         INC A
                 ;PT2    PT3
 OrnCP   INC A   ;CP E   CP D
         JR C,CH_ORPS
 OrnLD   DB 1    ;LD A,D LD A,E
 CH_ORPS LD (IX+PsInOr),A
         LD A,(IX+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
         EXA 
         LD L,(IX+SamPtr)
         LD H,(IX+SamPtr+1)
         LD SP,HL
         POP DE
         LD H,0
         LD A,(IX+PsInSm)
         LD B,A
         ADD A,A
 SamClc2 ADD A,A ;or ADD A,B for PT2
         LD L,A
         ADD HL,SP
         LD SP,HL
         LD A,B
         INC A
                 ;PT2    PT3
 SamCP   INC A   ;CP E   CP D
         JR C,CH_SMPS
 SamLD   DB 1    ;LD A,D LD A,E
 CH_SMPS LD (IX+PsInSm),A
         POP BC
         POP HL
 
 ;Convert PT2 sample to PT3
                 ;PT2            PT3
 SamCnv  POP HL  ;BIT 2,C        JR e_
         POP HL
         LD H,B
         JR NZ,$+8
         EX DE,HL
         AND A
         SBC HL,HL
         SBC HL,DE
         LD D,C
         RR C
         SBC A,A
         CPL 
         AND #3E
         RR C
         RR B
         AND C
         LD C,A
         LD A,B
         RRA 
         RRA 
         RR D
         RRA 
         AND #9F
         LD B,A
 
 e_      LD E,(IX+TnAcc)
         LD D,(IX+TnAcc+1)
         ADD HL,DE
         BIT 6,B
         JR Z,CH_NOAC
         LD (IX+TnAcc),L
         LD (IX+TnAcc+1),H
 CH_NOAC EX DE,HL
         EXA 
         ADD A,NT_
         LD L,A
         ADC A,'NT_
         SUB L
         LD H,A
         LD SP,HL
         POP HL
         ADD HL,DE
         LD E,(IX+CrTnSl)
         LD D,(IX+CrTnSl+1)
         ADD HL,DE
 CSP_    LD SP,#3131
         EX (SP),HL
         XOR A
         OR (IX+TSlCnt)
         JR Z,CH_AMP
         DEC (IX+TSlCnt)
         JR NZ,CH_AMP
         LD A,(IX+TnSlDl)
         LD (IX+TSlCnt),A
         LD L,(IX+TSlStp)
         LD H,(IX+TSlStp+1)
         LD A,H
         ADD HL,DE
         LD (IX+CrTnSl),L
         LD (IX+CrTnSl+1),H
         BIT 2,(IX+Flags)
         JR NZ,CH_AMP
         LD E,(IX+TnDelt)
         LD D,(IX+TnDelt+1)
         AND A
         JR Z,CH_STPP
         EX DE,HL
 CH_STPP SBC HL,DE
         JP M,CH_AMP
         LD A,(IX+SlToNt)
         LD (IX+Note),A
         XOR A
         LD (IX+TSlCnt),A
         LD (IX+CrTnSl),A
         LD (IX+CrTnSl+1),A
 CH_AMP  LD A,(IX+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+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+Volume)
         ADD A,VT_
         LD L,A
         ADC A,'VT_
         SUB L
         LD H,A
         LD A,(HL)
 CH_ENV  BIT 0,C
         JR NZ,CH_NOEN
         OR (IX+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+CrEnSl) ;SEE COMMENT BELOW
         BIT 5,B
         JR Z,NO_ENAC
         LD (IX+CrEnSl),A
 NO_ENAC ADD A,(IY-100+AddToEn) ;BUG IN PT3 - NEED WORD HERE
         LD (IY-100+AddToEn),A
         JR CH_MIX
 NO_ENSL RRA 
         ADD A,(IX+CrNsSl)
         LD (IY-100+AddToNs),A
         BIT 5,B
         JR Z,CH_MIX
         LD (IX+CrNsSl),A
 CH_MIX  LD A,B
         RRA 
         AND #48
 CH_EXIT OR (IY-100+AYREGS+Mixer)
         RRCA 
         LD (IY-100+AYREGS+Mixer),A
         POP HL
         XOR A
         OR (IX+COnOff)
         RET Z
         DEC (IX+COnOff)
         RET NZ
         XOR (IX+Flags)
         LD (IX+Flags),A
         RRA 
         LD A,(IX+OnOffD)
         JR C,CH_ONDL
         LD A,(IX+OffOnD)
 CH_ONDL LD (IX+COnOff),A
         RET 
 
 PLAY_   XOR A
         LD (IY-100+AddToEn),A
         LD (IY-100+AYREGS+Mixer),A
         DEC A
         LD (IY-100+AYREGS+EnvTp),A
         DEC (IY-100+DelyCnt)
         JP NZ,PL2
         DEC (IY-100+ChanA+NtSkCn)
         JR NZ,PL1B
         LD C,(IY-100+AdInPtA)
         LD B,(IY-100+AdInPtA+1)
         LD A,(BC)
         AND A
         JR NZ,PL1A
         LD D,A
         LD (IY-100+Ns_Base),A
         LD L,(IY-100+CrPsPtr)
         LD H,(IY-100+CrPsPtr+1)
         INC HL
         LD A,(HL)
         INC A
         JR NZ,PLNLP
 
         IFN LoopChecker
         CALL CHECKLP
         ENDIF 
 
         LD L,(IY-100+LPosPtr)
         LD H,(IY-100+LPosPtr+1)
         LD A,(HL)
         INC A
 PLNLP   CALL SETCPPT
         DEC A
         BIT 1,(IY-100+ModNum)
         JR Z,NoAlCo
 TSSub=$+1
         SUB #D6
         CPL 
 NoAlCo
                 ;PT2            PT3
 PsCalc  DEC A   ;ADD A,A        NOP
         DEC A   ;ADD A,(HL)     NOP
         ADD A,A
         LD E,A
         RL D
 
         IFN CurPosCounter
         LD A,L
         SUB (IY-100+PosSub)
         LD (IY-100+CurPos),A
         ENDIF 
 
         LD L,(IY-100+PatsPtr)
         LD H,(IY-100+PatsPtr+1)
         ADD HL,DE
         LD E,(IY-100+MODADDR)
         LD D,(IY-100+MODADDR+1)
         LD (PSP_+1),SP
         LD SP,HL
         POP HL
         ADD HL,DE
         LD B,H
         LD C,L
         POP HL
         ADD HL,DE
         LD (IY-100+AdInPtB),L
         LD (IY-100+AdInPtB+1),H
         POP HL
         ADD HL,DE
         LD (IY-100+AdInPtC),L
         LD (IY-100+AdInPtC+1),H
 PSP_    LD SP,#3131
 PL1A    LD DE,ChanA+12-100
         CALL PTDECOD
         LD (IY-100+AdInPtA),C
         LD (IY-100+AdInPtA+1),B
 
 PL1B    DEC (IY-100+ChanB+NtSkCn)
         JR NZ,PL1C
         LD DE,ChanB+12-100
         LD C,(IY-100+AdInPtB)
         LD B,(IY-100+AdInPtB+1)
         CALL PTDECOD
         LD (IY-100+AdInPtB),C
         LD (IY-100+AdInPtB+1),B
 
 PL1C    DEC (IY-100+ChanC+NtSkCn)
         JR NZ,PL1D
         LD DE,ChanC+12-100
         LD C,(IY-100+AdInPtC)
         LD B,(IY-100+AdInPtC+1)
         CALL PTDECOD
         LD (IY-100+AdInPtC),C
         LD (IY-100+AdInPtC+1),B
 
 PL1D    LD A,(IY-100+Delay)
         LD (IY-100+DelyCnt),A
 
 PL2     LD DE,ChanA-100
         LD L,(IY-100+AYREGS+TonA)
         LD H,(IY-100+AYREGS+TonA+1)
         CALL CHREGS
         LD (IY-100+AYREGS+TonA),L
         LD (IY-100+AYREGS+TonA+1),H
 Ampl=$+1
         LD A,#3E
         LD (IY-100+AYREGS+AmplA),A
         LD DE,ChanB-100
         LD L,(IY-100+AYREGS+TonB)
         LD H,(IY-100+AYREGS+TonB+1)
         CALL CHREGS
         LD (IY-100+AYREGS+TonB),L
         LD (IY-100+AYREGS+TonB+1),H
         LD A,(Ampl)
         LD (IY-100+AYREGS+AmplB),A
         LD DE,ChanC-100
         LD L,(IY-100+AYREGS+TonC)
         LD H,(IY-100+AYREGS+TonC+1)
         CALL CHREGS
         LD (IY-100+AYREGS+TonC),L
         LD (IY-100+AYREGS+TonC+1),H
         LD A,(Ampl)
         LD (IY-100+AYREGS+AmplC),A
 
         LD A,(IY-100+Ns_Base)
         ADD A,(IY-100+AddToNs)
         LD (IY-100+AYREGS+Noise),A
 
         LD A,(IY-100+AddToEn)
         LD E,A
         ADD A,A
         SBC A,A
         LD D,A
         LD L,(IY-100+EnvBase)
         LD H,(IY-100+EnvBase+1)
         ADD HL,DE
         LD E,(IY-100+CurESld)
         LD D,(IY-100+CurESld+1)
         ADD HL,DE
         LD (IY-100+AYREGS+Env),L
         LD (IY-100+AYREGS+Env+1),H
 
         XOR A
         OR (IY-100+CurEDel)
         RET Z
         DEC (IY-100+CurEDel)
         RET NZ
         LD A,(IY-100+Env_Del)
         LD (IY-100+CurEDel),A
         LD L,(IY-100+ESldAdd)
         LD H,(IY-100+ESldAdd+1)
         ADD HL,DE
         JP SETESLD
 
 PLAY    LD IY,VARS1+100
         CALL PLAY_
         LD A,(is_ts)
         AND A
         JR Z,PL_nts
         LD IY,VARS2+100
         CALL PLAY_
 PL_nts
         IFN Basic
         LD IY,#5C3A
         ENDIF 
 
 ROUT    LD BC,#FFFD
         LD A,(is_ts)
         AND A
         JR Z,r_nts
         IF0 ?ONtfm
         LD L,#F9
         OUT (C),L
         ELSE 
         OUT (C),B
         ENDIF 
 r_nts   EXA 
 
         IFN ACBBAC
         LD IX,VARS1+AYREGS
         ELSE 
         LD HL,VARS1+AYREGS
         ENDIF 
 
         CALL ROUT_
         EXA 
         RET Z
         LD B,D
         IF0 ?ONtfm
         LD A,#F8
         ELSE 
         CPL 
         ENDIF 
         OUT (C),A
 
         IFN ACBBAC
         LD IX,VARS2+AYREGS
         ELSE 
         LD HL,VARS2+AYREGS
         ENDIF 
 
 ROUT_
         IFN ACBBAC
         LD A,(SETUP)
         AND 12
         JR Z,ABC
         ADD A,CHTABLE
         LD E,A
         ADC A,'CHTABLE
         SUB E
         LD D,A
         LD B,0
         PUSH IX
         POP HL
         LD A,(DE)
         INC DE
         LD C,A
         ADD HL,BC
         LD A,(IX+TonB)
         LD C,(HL)
         LD (IX+TonB),C
         LD (HL),A
         INC HL
         LD A,(IX+TonB+1)
         LD C,(HL)
         LD (IX+TonB+1),C
         LD (HL),A
         LD A,(DE)
         INC DE
         LD C,A
         ADD HL,BC
         LD A,(IX+AmplB)
         LD C,(HL)
         LD (IX+AmplB),C
         LD (HL),A
         LD A,(DE)
         INC DE
         LD (RxCA1),A
         XOR 8
         LD (RxCA2),A
         LD A,(DE)
         AND (IX+Mixer)
         LD E,A
         LD A,(IX+Mixer)
 RxCA1   DB #E6
         AND %010010
         OR E
         LD E,A
         LD A,(IX+Mixer)
         AND %010010
 RxCA2   OR E
         OR E
         LD (IX+Mixer),A
 ABC
         ENDIF 
 
         XOR A
         LD DE,#FFBF
 
         IFN ACBBAC
         LD BC,#FFFD
         PUSH IX
         POP HL
         ENDIF 
 
 LOUT
        IF0 ?ONtfm
         INF 
         JP M,$-2
        ENDIF 
         OUT (C),A
        IF0 ?ONtfm
         INF 
         JP M,$-2
        ENDIF 
         LD B,E
         OUTI 
         LD B,D
         INC A
         CP 13
         JR NZ,LOUT
        IF0 ?ONtfm
         INF 
         JP M,$-2
        ENDIF 
         OUT (C),A
         LD A,(HL)
         AND A
         RET M
        IF0 ?ONtfm
         INF 
         JP M,$-2
        ENDIF 
         LD B,E
         OUT (C),A
         RET 
 
         IFN ACBBAC
 CHTABLE=$-4
         DB 4,5,15,%001001,0,7,7,%100100
         ENDIF 
 
 ;Stupid ALASM limitations
 NT_DATA DB 50*2 ;(T_NEW_0-T1_)*2
         DB TCNEW_0-T_
         DB 50*2+1 ;(T_OLD_0-T1_)*2+1
         DB TCOLD_0-T_
         DB 0*2+1 ;(T_NEW_1-T1_)*2+1
         DB TCNEW_1-T_
         DB 0*2+1 ;(T_OLD_1-T1_)*2+1
         DB TCOLD_1-T_
         DB 74*2;(T_NEW_2-T1_)*2
         DB TCNEW_2-T_
         DB 24*2 ;(T_OLD_2-T1_)*2
         DB TCOLD_2-T_
         DB 48*2 ;(T_NEW_3-T1_)*2
         DB TCNEW_3-T_
         DB 48*2 ;(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=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
 
 PT3EMPTYORN=$-1
         DB 1,0
 
 ;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
 
         DISPLAY $
 
 ;vars from here can be stripped
 ;you can move VARS to any other address
 
 VARS
 
 is_ts   DB 0
 
 VARS1   DS VRS
 VARS2   DS VRS
 
 VT_=$-16
         DS 256-16 ;CreatedVolumeTableAddress
 
 T1_=VT_+16 ;Tone tables data depacked here
 
 T_OLD_1=T1_
 T_OLD_2=T_OLD_1+24
 T_OLD_3=T_OLD_2+24
 T_OLD_0=T_OLD_3+2
 T_NEW_0=T_OLD_0
 T_NEW_1=T_OLD_1
 T_NEW_2=T_NEW_0+24
 T_NEW_3=T_OLD_3
 
 PT2EMPTYORN=VT_+31 ;1,0,0 sequence
 
 NT_     DS 192 ;CreatedNoteTableAddress
 
 VAR0END=VT_+16 ;INIT zeroes from VARS to VAR0END-1
 
 VARSEND=$
 
 MDLADDR=$
 
         DISPLAY $
 
 ,LOUT
        IF0 ?ONtfm
         INF 
         JP M,$-2
        ENDIF 
         OUT (C),A
         LD A,(HL)
         AND A
         RET M
        IF0 ?ONtfm
         INF 
         JP M,$-2
        ENDIF 
         LD