p3xplayer-sjasmplus
PT3 extreme player
Syntax is for sjasmplus.
; ProTracker3 Extreme (P3X) player for ZX Spectrum ; Copyright (c) 2004, 2007 S.V.Bulba <vorobey@mail.khstu.ru> ; http://bulba.untergrund.net (http://bulba.at.kz) ; Formatted by Gasman for Pasmo and optimized by Cheveron ; variables are 541 bytes long and follow the player ; music is in ProTracker3.6 format (minus the 100 byte header) ; sjasmplus adaptation by z00m^SinDiKAT, 2013. device zxspectrum128 org 32768 demo: ld hl,music-100 di call p3x_init demoloop: ei halt call play jr demoloop jr mute setup: db 0 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+CHP_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 p3x_init: ld (modaddr+1),hl ld (mdaddr2+1),hl push hl ld de,100 add hl,de ld a,(hl) ld (p3x_delay+1),a push hl pop ix add hl,de ld (CrPsPtr+1),hl ld e,(ix+2) add hl,de inc hl ld (LPosPtr+1),hl pop de ld l,(ix+3) ld h,(ix+4) add hl,de ld (PatsPtr+1),hl ld hl,$a9 add hl,de ld (OrnPtrs+1),hl ld hl,$69 add hl,de ld (SamPtrs+1),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 $1e 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 lc091h: 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 ld (ChanA+CHP_NtSkCn),hl ld (ChanB+CHP_NtSkCn),hl ld (ChanC+CHP_NtSkCn),hl ld hl,emptysamorn ld (AdInPtA+1),hl ld (ChanA+CHP_OrnPtr),hl ld (ChanB+CHP_OrnPtr),hl ld (ChanC+CHP_OrnPtr),hl ; select tone table! ; ld a, 1 ; 1.7734 Mhz AY (128) ld a, 2 ; 1.75Mhz AY (Pentagon) 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 add hl,bc ld a,(de) add a,low (T_) ld c,a adc a,T_/256 sub c ld b,a push bc ld de,NT_ push de ld b,$0c l1: push bc ld c,(hl) inc hl push hl ld b,(hl) push de ex de,hl ld de,$17 ld xh,8 l2: srl b rr c l3: add hl,de ; will be replaced by AND A or NOP apparently ld a,c adc a,d ld (hl),a inc hl ld a,b adc a,d ld (hl),a add hl,de 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 cp low (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.. - 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 p3x_initv2: push hl add hl,de ex de,hl sbc hl,hl p3x_initv1: ld a,l m2: ld a,l ld a,h adc a,0 ld (ix+0),a inc ix add hl,de inc c ld a,c and $0f jr nz,p3x_initv1 pop hl ld a,e cp $77 jr nz,m3 inc e m3: ld a,c and a jr nz,p3x_initv2 jp rout_a0 ; pattern decoder PD_OrSm: ld (ix+8),0 call setorn ld a,(bc) inc bc rrca pd_sam: add a,a pd_sam_: ; lc19dh ld e,a ld d,0 SamPtrs: ld hl,$2121 add hl,de ld e,(hl) inc hl ld d,(hl) modaddr: ld hl,$2121 add hl,de ld (ix+3),l ld (ix+4),h jr pd_loop pd_vol: rlca rlca rlca rlca ld (ix+$10),a jr pd_lp2 pd_eoff: ld (ix+8),a ld (ix-$0c),a jr pd_lp2 pd_SorE: dec a jr nz,pd_env ld a,(bc) inc bc ld (ix+5),a jr pd_lp2 pd_env: call setenv jr pd_lp2 pd_orn: call setorn jr pd_loop pd_esam: ld (ix+8),a ld (ix-$0c),a call nz,setenv ld a,(bc) inc bc jr pd_sam_ ptdecod: ld a,(ix+6) ld (PrNote+1),a ld l,(ix-6) ld h,(ix-5) 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,$60 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-$20e0 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+9) jr pd_res pd_note: ld (ix+6),a set 0,(ix+9) 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+5) ld (ix+$0f),a ret c_portm: res 2,(ix+9) ld a,(bc) inc bc inc bc inc bc ld (ix+$0a),a ld (ix-7),a ld de,NT_ ld a,(ix+6) ld (ix+7),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+6),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+$0d),l ld (ix+$0e),h ld e,(ix-6) ld d,(ix-5) PrSlide: ld de,$1111 ld (ix-6),e ld (ix-5),d ld a,(bc) 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+$0c),a ex af,af' ld (ix+$0b),a ld (ix-2),0 ret c_gliss: set 2,(ix+9) ld a,(bc) inc bc ld (ix+$0a),a and a jr nz,gl36 ld a,6; P3X version is always PT3.6 cp 7 sbc a,a inc a gl36: ld (ix-7),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-$0b),a ret c_orpos: ld a,(bc) inc bc ld (ix-$0c),a ret c_vibrt: ld a,(bc) inc bc ld (ix-1),a ld (ix-2),a ld a,(bc) inc bc ld (ix+0),a xor a ld (ix-7),a ld (ix-6),a ld (ix-5),a ret c_engls: ld a,(bc) inc bc ld (env_del+1),a ld (CurEDel),a ld a,(bc) inc bc ld l,a ld a,(bc) inc bc ld h,a ld (ESldAdd+1),hl ret c_p3x_delay: ld a,(bc) inc bc ld (p3x_delay+1),a ld (DelyCnt),a ; bugfix by Lee_dC ret setenv: ld (ix+8),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-$0c),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-$0c),d OrnPtrs: ld hl,$2121 add hl,de ld e,(hl) inc hl ld d,(hl) mdaddr2: ld hl,$2121 add hl,de ld (ix+1),l ld (ix+2),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_p3x_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+$15) push hl jp z,ch_exit ld (csp_+1),sp ld l,(ix+$0d) ld h,(ix+$0e) ld sp,hl pop de ld h,a ld a,(ix+0) ld l,a add hl,sp inc a cp d jr c,ch_orps ld a,e ch_orps: ld (ix+0),a ld a,(ix+$12) add a,(hl) jp p,ch_ntp xor a ch_ntp: cp $60 jr c,ch_nok ld a,$5f ch_nok: add a,a ex af,af' ld l,(ix+$0f) ld h,(ix+$10) ld sp,hl pop de ld h,0 ld a,(ix+1) 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+1),a pop bc pop hl ld e,(ix+8) ld d,(ix+9) add hl,de bit 6,b jr z,ch_noac ld (ix+8),l ld (ix+9),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+6) ld d,(ix+7) add hl,de csp_: ld sp,$3131 ex (sp),hl xor a or (ix+5) jr z,ch_amp dec (ix+5) jr nz,ch_amp ld a,(ix+$16) ld (ix+5),a ld l,(ix+$17) ld h,(ix+$18) ld a,h add hl,de ld (ix+6),l ld (ix+7),h bit 2,(ix+$15) jr nz,ch_amp ld e,(ix+$19) ld d,(ix+$1a) and a jr z,ch_stpp ex de,hl ch_stpp: sbc hl,de jp m,ch_amp ld a,(ix+$13) ld (ix+$12),a xor a ld (ix+5),a ld (ix+6),a ld (ix+7),a ch_amp: ld a,(ix+2) bit 7,c jr z,ch_noam bit 6,c jr z,ch_amin cp $0f jr z,ch_noam inc a jr ch_svam ch_amin: cp $f1 jr z,ch_noam dec a ch_svam: ld (ix+2),a ch_noam: ld l,a ld a,b and $0f add a,l jp p,ch_apos xor a ch_apos: cp $10 jr c,ch_vol ld a,$0f ch_vol: or (ix+$1c) 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+$14) 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+4) bit 5,b jr z,no_enac ld (ix+4),a no_enac: ld hl,AddToEn+1 add a,(hl) ld (hl),a jr ch_mix no_ensl: rra add a,(ix+3) ld (AddToNs),a bit 5,b jr z,ch_mix ld (ix+3),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+$0a) ret z dec (ix+$0a) ret nz xor (ix+$15) ld (ix+$15),a rra ld a,(ix+$0b) jr c,ch_ondl ld a,(ix+$0c) ch_ondl: ld (ix+$0a),a ret play: xor a ld (AddToEn+1),a ld (AYREGS+AR_Mixer),a dec a ld (AYREGS+AR_EnvTp),a ld hl,DelyCnt dec (hl) jr nz,pl2 ld hl,ChanA+CHP_NtSkCn dec (hl) jr nz,pl1b AdInPtA: 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: ld hl,$2121 ld a,(hl) inc a plnlp: ld (CrPsPtr),hl dec a add a,a ld e,a rl d PatsPtr: ld hl,$2121 add hl,de ld de,(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 (AdInPtB+1),hl pop hl add hl,de ld (AdInPtC+1),hl psp_: ld sp,$3131 pl1a: ld ix,ChanA+12 call ptdecod ld (AdInPtA+1),bc pl1b: ld hl,ChanB+CHP_NtSkCn dec (hl) jr nz,pl1c ld ix,ChanB+12 AdInPtB: ld bc,$0101 call ptdecod ld (AdInPtB+1),bc pl1c: ld hl,ChanC+CHP_NtSkCn dec (hl) jr nz,pl1d ld ix,ChanC+12 AdInPtC: ld bc,$0101 call ptdecod ld (AdInPtC+1),bc pl1d: p3x_delay: 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 (AYREGS+AR_TonC),hl ld hl,(ns_base_AddToNs) ld a,h add a,l ld (AYREGS+AR_Noise),a AddToEn: 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: ld a,$3e ld (hl),a ESldAdd: ld hl,$2121 add hl,de ld (CurESld),hl rout: xor a rout_a0: ld de,$FFBF ld bc,$FFFD ld hl,AYREGS lout: out (c),a ld b,e outi ld b,d inc a cp $0d jr nz,lout out (c),a ld a,(hl) and a ret m ld b,e 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 low ($06EC*2/256),low ($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,low ($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,low ($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,low ($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 ; channel data offsets CHP_PsInOr equ 0 CHP_PsInSm equ 1 CHP_CrAmSl equ 2 CHP_CrNsSl equ 3 CHP_CrEnSl equ 4 CHP_TSlCnt equ 5 CHP_CrTnSl equ 6 CHP_TnAcc equ 8 CHP_COnOff equ 10 CHP_OnOffD equ 11 ;IX for PTDECOD here (+12) CHP_OffOnD equ 12 CHP_OrnPtr equ 13 CHP_SamPtr equ 15 CHP_NNtSkp equ 17 CHP_Note equ 18 CHP_SlToNt equ 19 CHP_Env_En equ 20 CHP_Flags equ 21 ;Enabled - 0,SimpleGliss - 2 CHP_TnSlDl equ 22 CHP_TSlStp equ 23 CHP_TnDelt equ 25 CHP_NtSkCn equ 27 CHP_Volume equ 28 vars ChanA ds 29 ChanB ds 29 ChanC ds 29 ;GlobalVars DelyCnt DB 0 CurESld DW 0 CurEDel DB 0 ns_base_AddToNs ns_base DB 0 AddToNs DB 0 AR_TonA equ 0;word 1 AR_TonB equ 2;word 1 AR_TonC equ 4;word 1 AR_Noise equ 6;byte 1 AR_Mixer equ 7;byte 1 AR_AmplA equ 8;byte 1 AR_AmplB equ 9;byte 1 AR_AmplC equ 10;byte 1 AR_Env equ 11;word 1 AR_EnvTp equ 13;byte 1 AR_Size equ 14 AYREGS equ $ VT_ DB "VOLUME TABLE" DS 244 ;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_ DB "NOTE TABLE" DS 182 ;CreatedNoteTableAddress ;local var Ampl EQU AYREGS+AR_AmplC VAR0END EQU VT_+16 ;p3x_init zeroes from VARS to VAR0END-1 VARSEND EQU $ MDLADDR EQU $ music incbin "music.pt3",100 ; ProTracker3.6 excluding 100 byte header savesna "p3x.sna",demo
Navigation: general . math . graphic . sound . system . other . back to start
p3xplayer-sjasmplus.txt · Last modified: 2017/02/16 13:29 by darkbyte