PROTRACKER372 JP PTTFC H

From MSX MUSIC WIKI
Jump to: navigation, search

pttfc C��BK�L�б

ssg=0 ;в компиляторе пока не поддерживается
;TODO begin&end только в одном канале
newtfm=1 ;0=revision A, 1=revision C

       IFN ?tfcinclude
;IMER=#5B5B
IMTAB=#BE00
       ENDIF 
       IF0 newtfm-1
statuschip0=%11111000
statuschip1=%11111001
       ELSE 
       IF0 newtfm-2 ;US031DX
statuschip0=%11111110
statuschip1=%11111111
       ELSE ;newtfm=0
statuschip0=%11111100
statuschip1=%11111101
       ENDIF 
       ENDIF 

        MACRO WaitStatus
       IFN newtfm-2
       ;OUT (C),D ;statuschip0/1
        INF 
        JP M,$-2
       ENDIF 
        ENDM 

       ;не нужен?
        MACRO ssgprewait
        WaitStatus
        ENDM 

       ;или этот не нужен?
        MACRO ssgpostwait
        WaitStatus
        ENDM 

       IFN ?tfcinclude
        MACRO HALTER
        LOCAL 
        PUSH DE,HL
        LD HL,23672
        LD DE,3095;0
        LD A,(HL)
         DEC DE ;INC
         CP (HL)
        JP Z,$-2 ;23t
       ;DE=(Tframe-Tplayer)/30
       ;если >30000t
           ;(т.е. осталось < номинала), то левота
       ;LD HL,304  ;7000t
       ;LD HL,435  ;10000t
       ;LD HL,652  ;15000t
        LD HL,1739 ;40000t
       ;LD HL,2174 ;50000t
       ;LD HL,3043 ;70000t
        OR A
        SBC HL,DE ;CY: DE>HL
       JC halterskip
        LD HL,sum
        LD A,(HL)
        ADD A,E
        LD (HL),A
        INC HL
        LD A,(HL)
        ADC A,D
        LD (HL),A
        INC HL
        LD A,(HL)
        ADC A,0
        LD (HL),A
        INC HL
        LD A,(HL)
        ADC A,0
        LD (HL),A
        LD HL,(min)
        OR A
        SBC HL,DE ;CY: old min <
        JC $+6
        LD (min),DE
        LD HL,(max)
        OR A
        SBC HL,DE ;NC: old max >=
        JNC $+6
        LD (max),DE
        LD HL,(frames)
        INC HL
        LD (frames),HL
        JR halterQ
halterskip
        LD HL,0
        LD A,(HL)
        ADD A,E
        LD (HL),A
        INC HL
        LD A,(HL)
        ADC A,D
        LD (HL),A
        INC HL
        LD A,(HL)
        ADC A,0
        LD (HL),A
        INC HL
        LD A,(HL)
        ADC A,0
        LD (HL),A
        LD HL,(min)
        OR A
        SBC HL,DE ;CY: old min <
        JC $+6
        LD (0),DE
        LD HL,(max)
        OR A
        SBC HL,DE ;NC: old max >=
        JNC $+6
        LD (0),DE
        LD HL,(badframes)
        INC HL
        LD (badframes),HL
halterQ
        POP HL,DE
        ENDL 
        ENDM 

        ORG #6000
begin
GO
        LD SP,#6000
GOFREE
        LD (QUITSP),SP
        IM 1

        LD HL,#4000
        LD DE,#4001
        LD BC,6911
        LD (HL),L
        LDIR 
        LD A,#46
        LD (PR88col),A
        LD DE,#4000
        LD HL,tTITLE
        CALL PRMSG
        LD DE,#4060
        CALL PRMSG
        LD DE,#40C0
        CALL PRMSG
        LD HL,tfmmuz
       IFN ssg
        LD BC,#32
       ELSE 
        LD BC,#22
       ENDIF 
        ADD HL,BC
        LD A,7
        LD (PR88col),A
        LD DE,#4020
        CALL PRMSG
        LD DE,#4080
        CALL PRMSG
        LD DE,#40E0
        CALL PRMSG

        EI 
        HALT 
        LD HL,IMTAB
        LD BC,256
        LD D,H,E,B
        LD (HL),IMER
        LD A,H
        LDIR 
        LD I,A
        IM 2

        LD HL,tfmmuz
        CALL tfmini
        HALT 
       ;wait 1000t - не мин и не макс
        LD B,1000/13
        DJNZ $
LOOP
        HALTER
nehalt
        LD A,2
        OUT (-2),A
        CALL tfm
        LD A,0
        OUT (-2),A
        LD A,#7F
        IN A,(-2)
        RRA 
JP_JPC  JP   LOOP
QUIT
QUITSP=$+1
        LD SP,0
        CALL tfmshut
        LD B,D
        WaitStatus
        LD A,#FF ;выкл. FM
        OUT (C),A
       IM 1
        LD HL,(min)
        CALL MUL23
        LD DE,#5000
        CALL PR12345
        LD HL,(max)
        CALL MUL23
        LD DE,#5020
        CALL PR12345
        LD HL,(sum)
        LD DE,(sum+2)
        LD BC,(frames)
        CALL DIV3216
        CALL MUL23
        LD DE,#5040
        CALL PR12345
        LD HL,(frames)
        LD DE,#5060
        CALL PR12345
        LD HL,(badframes)
        LD DE,#5080
PR12345
        LD BC,10000
        CALL PRDIG
        LD BC,1000
        CALL PRDIG
        LD BC,100
        CALL PRDIG
        LD C,10
        CALL PRDIG
        LD C,1
PRDIG
        LD A,"0"-1
        OR A
        INC A
        SBC HL,BC
        JNC $-3
        ADD HL,BC
PR88
       PUSH HL
        ADD A,A
        LD L,A
        LD H,15
        ADD HL,HL
        ADD HL,HL
       PUSH DE
        DUP 8
        LD A,(HL),(DE),A
        INC L,D
        EDUP 
        ORG $-1
        LD A,D
        RRA 
        RRA 
        RRA 
        AND 3
        ADD A,88
        LD D,A
PR88col=$+1
        LD A,0
        LD (DE),A
       POP DE
        INC E
       POP HL
        RET NZ
        LD A,D
        ADD A,8
        LD D,A
        RET 
PRCR
        LD A,E
        AND #E0
        ADD A,32
        LD E,A
        RET NC
        LD A,D
        ADD A,8
        LD D,A
        RET 
PRCRMSG
        INC HL ;skip LF
        CALL PRCR
PRMSG
        LD A,(HL)
        INC HL
        OR A
        RET Z
        CP 13
        JZ PRCRMSG
        CALL PR88
        JR PRMSG

MUL23
        LD B,H,C,L
        ADD HL,HL
        ADD HL,BC ;3
        ADD HL,HL
        ADD HL,HL
        ADD HL,HL ;24
        SBC HL,BC ;23
        RET 

DIV3216
;DEHL/BC -> HL
        LD A,B
        OR C
        JNZ $+3
        INC BC
        LD IX,-1
DIV32160
        INC IX
        OR A
        SBC HL,BC
        JNC $+3
        DEC DE
        BIT 7,D
        JZ DIV32160
        PUSH IX
        POP HL
        RET 
tTITLE
        DB "Track name:",0
        DB "Author:",0
        DB "Message:",0
       ENDIF 
tfmplayer
tfmini
        EXD 
        LD HL,9
        ADD HL,DE
        LD A,(HL)
        INC HL
        CP 50
        LD A,201
        JZ $+4
        LD A,62
        LD (tfm60hz),A
        EXX 
        LD HL,tfminitab
       IFN ssg
        LD BC,#14FD
       ELSE 
        LD BC,#06FD
       ENDIF 
tfmini0
        LD DE,tfminiHL
        LDI 
        LDI 
        EXX 
        LD A,(HL)
        INC HL
        PUSH HL
        LD H,(HL)
        LD L,A
        ADD HL,DE
tfminiHL=$+1
        LD (0),HL
        POP HL
        INC HL
        EXX 
        DJNZ tfmini0
        XOR A
        LD (blkcntA),A
        LD (blkcntB),A
        LD (blkcntC),A
        LD (blkcntD),A
        LD (blkcntE),A
        LD (blkcntF),A
       IFN ssg
        LD (blkcntT0),A
        LD (blkcntTA),A
        LD (blkcntMA),A
        LD (blkcntTB),A
        LD (blkcntMB),A
        LD (blkcntTC),A
        LD (blkcntMC),A
        LD (blkcntT1),A
        LD (blkcntTD),A
        LD (blkcntMD),A
        LD (blkcntTE),A
        LD (blkcntME),A
        LD (blkcntTF),A
        LD (blkcntMF),A
       ENDIF 
        DEC A
        LD (skipA),A
        LD (skipB),A
        LD (skipC),A
        LD (skipD),A
        LD (skipE),A
        LD (skipF),A
       IFN ssg
        LD (skipT0),A
        LD (skipTA),A
        LD (skipMA),A
        LD (skipTB),A
        LD (skipMB),A
        LD (skipTC),A
        LD (skipMC),A
        LD (skipT1),A
        LD (skipTD),A
        LD (skipMD),A
        LD (skipTE),A
        LD (skipME),A
        LD (skipTF),A
        LD (skipMF),A
       ENDIF 
tfmshut
        LD DE,#FFBF
        LD C,#FD
        CALL selChip0
        CALL tfminiPP
        CALL selChip1
        CALL tfminiPP
        LD B,D
        OUT (C),D ;fm off
        RET 
tfminiPP
        XOR A
        EXA 
        LD A,#0D ;SSG
regClrS CALL WRITEREG
        DEC A
        JP P,regClrS
        LD A,#B3
regClrZ CP #4F
        JR NZ,$+4
        LD A,#3F ;skip TL, чтобы не было щелчка
        CALL WRITEREG
        DEC A
        CP #30
        JR NC,regClrZ
        LD A,#0F ;max speed
        EXA 
        LD A,#8F ;RR
regClrR CALL WRITEREG
        DEC A
        JP M,regClrR
      ; LD A,#F0
      ; EXA
      ; LD A,#28 ;key
      ; CALL WRITEREG ;key on A
      ; EXA
      ; INC A ;#F1
      ; EXA
      ; CALL WRITEREG ;key on B
      ; EXA
      ; INC A ;#F2
      ; EXA
      ; CALL WRITEREG ;key on C
        XOR A
        EXA 
        LD A,#28 ;key
        CALL WRITEREG ;key off A
        EXA 
        INC A ;#01
        EXA 
        CALL WRITEREG ;key off B
        EXA 
        INC A ;#02
        EXA 
        CALL WRITEREG ;key off C
        DEC A ;#27 ;channel 3 mode
        CALL WRITEREG ;normal mode

        LD A,#7F ;тишина
        EXA 
        LD A,#4F ;TL
regClrT CALL WRITEREG
        DEC A
        CP #40
        JR NC,regClrT
       ;LD A,#2F      ;любое
       ;EXA
        LD A,#2F
        CALL WRITEREG ;без этого частота левая
       ;LD A,#2D      ;любое
       ;EXA
        LD A,#2D
       ;без этого частота левая
WRITEREG
;A=REG
;A'=VALUE
        LD B,D
        WaitStatus
        OUT (C),A ;reg
        EXA 
        WaitStatus
        LD B,E
        OUT (C),A ;value
        EXA 
        RET 
tfminitab
        DW addrA
        DW addrB
        DW addrC
        DW addrD
        DW addrE
        DW addrF
       IFN ssg
        DW addrT0
        DW addrTA
        DW addrMA
        DW addrTB
        DW addrMB
        DW addrTC
        DW addrMC
        DW addrT1
        DW addrTD
        DW addrMD
        DW addrTE
        DW addrME
        DW addrTF
        DW addrMF
       ENDIF 
selChip0
        LD A,statuschip0
        LD B,D
        OUT (C),A
        RET 

selChip1
        LD A,statuschip1
        LD B,D
        OUT (C),A
        RET 

OUTA
        PUSH BC
        LD BC,32765
        OUT (C),A
        POP BC
        RET 

tfm
        LD DE,#FFBF
        LD C,#FD
        LD B,D
        LD A,statuschip0
        OUT (C),A
        CALL tfmA
        CALL tfmB
        CALL tfmC
        LD B,D
        LD A,statuschip1
        OUT (C),A
        CALL tfmD
        CALL tfmE
        CALL tfmF
       ;SSG
       ;CALL SSG
       ;
tfm60hz
cnt60=$+1
        LD A,6
        DEC A
        JNZ $+4
        LD A,6
        LD (cnt60),A
        JZ tfm
        RET 

        MACRO TestKeyOff
        LOCAL 
        JP P,noffX
        EXA 
        LD B,D ;%11111xxx
        LD A,#28
        WaitStatus
        OUT (C),A
       IF0 \0
        XOR A
       ELSE 
        LD A,\0
       ENDIF 
        WaitStatus
        LD B,E ;#BF
        OUT (C),A
        EXA 
noffX
        ENDL 
        ENDM 

        MACRO TestFreq
        LOCAL 
        RRA 
        JNC nofrqX
        EXA 
        LD B,D ;%11111xxx
        LD A,#A4+\1
        WaitStatus
        OUT (C),A
       LD A,(HL)
       INC HL
       LD (tfmhigh\0),A
        WaitStatus
        LD B,E ;#BF
       OUT (C),A
        LD B,D ;%11111xxx
        LD A,#A0+\1
        WaitStatus
        OUT (C),A
       LD A,(HL)
       INC HL
       LD (tfmlow\0),A
        WaitStatus
        LD B,E ;#BF
       OUT (C),A
        EXA 
nofrqX
        ENDL 
        ENDM 

        MACRO TestOutRegs
        LOCAL 
        AND #1F
        CALL NZ,regsX
        ENDL 
        ENDM 

        MACRO KeyOn
        LD B,D ;%11111xxx
        LD A,#28
        WaitStatus
        OUT (C),A
        LD A,#F0+\0
        WaitStatus
        LD B,E ;#BF
        OUT (C),A
        ENDM 

;%11111111,-disp8 = данные кадра лежат по смещению -disp8
;%111ttttt = skip 32..2 frames
;%110ddddd = slide d-16
;%11010000,frames,-disp16 = repeat block (skips = 1 frame)
;%10111111,-disp16 = данные кадра лежат по смещению -disp16
;%10NNNNNf = keyoff,[freq,]0..30 regs, keyon
;%01111111 = end
;%01111110 = begin
;%01NNNNNf = keyoff,[freq,]0..31 regs
;%00NNNNNf =        [freq,]0..30 regs
bb=%01111110
be=%01111111
        MACRO MacroTFM
block\0
        LD A,(HL) ;N frames
                  ;1 now, N-1 later
                  ;skip command is used as 1 frame
        INC HL
        LD (blkcnt\0),A
        LD B,(HL)
        INC HL
        LD C,(HL) ;disp
        INC HL
        LD (blkretaddr\0),HL
        ADD HL,BC
        LD C,#FD
        JP tfmframe\0
OLDfar\0
        LD B,(HL)
        INC HL
OLDnear\0
        LD C,(HL)
        INC HL
        PUSH HL
        ADD HL,BC
        LD C,#FD
        CALL tfmframe\0
        POP HL
        LD (addr\0),HL
        RET 
HLskiper\0
        JZ OLDfar\0
        CP %11100000
        JC slide\0
        LD B,A
        CP #FF
        JZ OLDnear\0
        LD (addr\0),HL
skiper\0 LD (skip\0),A
        RET 
slide\0
       ;A=-64..-33
        ADD A,48
       ;A=-16..15
        JZ block\0
tfmlow\0=$+1
        ADD A,0
        LD (tfmlow\0),A
        LD (addr\0),HL
        LD B,D ;%11111xxx
tfmhigh\0=$+2
        LD HL,#A4+\1
        WaitStatus
        OUT (C),L
        WaitStatus
        LD B,E ;#BF
       OUT (C),H
        LD B,D ;%11111xxx
        LD L,#A0+\1
        WaitStatus
        OUT (C),L
        WaitStatus
        LD B,E ;#BF
       OUT (C),A
        RET 

begin\0
        LD (loopaddr\0),HL
        JP tfmframe\0
end\0
loopaddr\0=$+1
        LD HL,0
        JP tfmframe\0
tfm\0
skip\0=$+1
        LD A,-1
        INC A
        JNZ skiper\0
addr\0=$+1
        LD HL,0
blkcnt\0=$+1
        OR 0
        JZ tfmframe\0
        DEC A
        LD (blkcnt\0),A
        JNZ tfmframe\0
blkretaddr\0=$+1
        LD HL,0
tfmframe\0
        LD A,(HL)
        INC HL
        CP bb
        JZ begin\0
        CP be
        JZ end\0
        CP E ;#BF
        JNC HLskiper\0
        TestKeyOff \1
        OR A
        PUSH AF
        TestFreq \0,\1
        TestOutRegs
        LD (addr\0),HL
        POP AF
        RET P
        KeyOn \1
        RET 
        ENDM 

regsX
        LD B,D ;%11111xxx
        WaitStatus
        OUTI   ;reg
        WaitStatus
        LD B,E ;#BF
        OUTI   ;value
        DEC A
        JNZ regsX ;в turbo JR=JP
        RET 

        MacroTFM A,0
        MacroTFM B,1
        MacroTFM C,2
        MacroTFM D,0
        MacroTFM E,1
        MacroTFM F,2
       IFN ssg
SSG
        LD D,32
        LD A,(ssgmaskA)
        LD E,A
        CALL ssgT0
        CALL ssgTA
        CALL ssgMA
        CALL ssgTB
        CALL ssgMB
        CALL ssgTC
        CALL ssgMC
        LD A,E
        LD (ssgmaskA),A
        LD BC,#FFFD
        LD DE,#FFBF
        LD A,statuschip0
        OUT (C),A
        LD HL,ssglowA
        CALL OUTSSG

        LD D,32
        LD A,(ssgmaskD)
        LD E,A
        CALL ssgT1
        CALL ssgTD
        CALL ssgMD
        CALL ssgTE
        CALL ssgME
        CALL ssgTF
        CALL ssgMF
        LD A,E
        LD (ssgmaskD),A
        LD BC,#FFFD
        LD DE,#FFBF
        LD A,statuschip1
        OUT (C),A
        LD HL,ssglowD
OUTSSG
       DUP 13
        LD B,D ;%11111xxx
        ssgprewait
        OUT (C),L ;reg
        ssgpostwait
        LD B,E ;#BF
        OUTI   ;value
       EDUP 
        LD A,(HL)
        OR A
        RET Z
        LD B,D
        ssgprewait
        OUT (C),L
        ssgpostwait
        LD B,E
        OUT (C),A
        LD (HL),0
        RET 

;tone channel:
;1  1  1  HIGHTONE5   - set hightone, read lowtone
;1  1  0  N, disp16   - LZ
;1  0  1  N, disp8    - LZ
;1  0  0  SKIP5       - skip 32..1 frames
;0  dTONE7            - tone+=(dTONE7-64)
;begin=#A0
;end=#C0

        MACRO ToneSSG
farT\0
        LD B,(HL)
        INC HL
nearT\0
        LD C,(HL)
        INC HL
                  ;A = N frames
                  ;1 now, N-1 later
                  ;skip command is used as 1 frame
        LD (blkcntT\0),A
        LD (blkretaddrT\0),HL
        ADD HL,BC
        JP frameT\0
markT\0
        ADD A,D
        JC sethighT\0
        ADD A,D
        JZ endT\0
        JC farT\0
        LD B,-1
        ADD A,D
        JZ beginT\0
        JC nearT\0
        LD (addrT\0),HL
skiperT\0 LD (skipT\0),A
        RET 

beginT\0
        LD (loopaddrT\0),HL
        JP frameT\0
endT\0
loopaddrT\0=$+1
        LD HL,0
        JP frameT\0
ssgT\0
skipT\0=$+1
        LD A,-1
        INC A
        JNZ skiperT\0
addrT\0=$+1
        LD HL,0
blkcntT\0=$+1
        OR 0
        JZ frameT\0
        DEC A
        LD (blkcntT\0),A
        JNZ frameT\0
blkretaddrT\0=$+1
        LD HL,0
frameT\0
        LD A,(HL)
        INC HL
        OR A
        JP M,markT\0
        SUB 64
       ;A=-63..63
        LD (addrT\0),HL
        LD HL,ssglow\0
        ADD A,(HL)
        LD (HL),A
        RET 
sethighT\0
        LD (ssghigh\0),A
        LD A,(HL)
        INC HL
        LD (ssglow\0),A
        LD (addrT\0),HL
        RET 
        ENDM 

;NM=TM=0 is incompatible with volume set
;mask channel:
;1  1  1  NOISE5      - set noise, continue
;1  1  0  N, disp16   - LZ
;1  0  1  N, disp8    - LZ
;1  0  0  SKIP5       - skip 32..1 frames
;0  TM NM ...
         ;0  v3 v2 v1 v0 - env OFF (this byte to vol reg)
         ;1  1  e2 e1 e0 - ini env (type 8..F),
                          ;env ON (this byte to vol reg)
         ;1  0  ?  ?  ?  - env ON (this byte to vol reg)
;begin=#A0
;end=#C0

        MACRO MaskSSG
farM\0
        LD B,(HL)
        INC HL
nearM\0
        LD C,(HL)
        INC HL
                  ;A = N frames
                  ;1 now, N-1 later
                  ;skip command is used as 1 frame
        LD (blkcntM\0),A
        LD (blkretaddrM\0),HL
        ADD HL,BC
        JP frameM\0
markM\0
        ADD A,D
        JC setnoiseM\0
        ADD A,D
        JZ endM\0
        JC farM\0
        LD B,-1
        ADD A,D
        JZ beginM\0
        JC nearM\0
        LD (addrM\0),HL
skiperM\0 LD (skipM\0),A
        RET 

beginM\0
        LD (loopaddrM\0),HL
        JP frameM\0
endM\0
loopaddrM\0=$+1
        LD HL,0
        JP frameM\0
ssgM\0
skipM\0=$+1
        LD A,-1
        INC A
        JNZ skiperM\0
addrM\0=$+1
        LD HL,0
blkcntM\0=$+1
        OR 0
        JZ frameM\0
        DEC A
        LD (blkcntM\0),A
        JNZ frameM\0
blkretaddrM\0=$+1
        LD HL,0
frameM\0
        LD A,(HL)
        INC HL
        OR A
        JP M,markM\0
        LD (addrM\0),HL
        LD (ssgvol\0),A
        BIT 4,A
        JZ nenvM\0
        BIT 3,A
        JZ nenvM\0
        LD (ssgenv\0),A
nenvM\0
        RLA 
        RLA 
        JNC $+4
        SET \1+3,E ;noisemask (3,4,5) OFF
        RLA 
        RET NC
        SET \1,E ;tonemask (0,1,2) OFF
        RET 
setnoiseM\0
        LD (ssgnoise\0),A
        JP frameM\0
        ENDM 

ToneSSG 0
ToneSSG A
MaskSSG A,0
ToneSSG B
MaskSSG B,1
ToneSSG C
MaskSSG C,2
ToneSSG 1
ToneSSG D
MaskSSG D,0
ToneSSG E
MaskSSG E,1
ToneSSG F
MaskSSG F,2

        DS .(-$)
ssglowA DB 0
ssghighA DB 0
ssglowB DB 0
ssghighB DB 0
ssglowC DB 0
ssghighC DB 0
ssgnoiseA
ssgnoiseB
ssgnoiseC DB 0
ssgmaskA
ssgmaskB
ssgmaskC DB 0
ssgvolA DB 0
ssgvolB DB 0
ssgvolC DB 0
ssglow0 DB 0
ssghigh0 DB 0
ssgenvA
ssgenvB
ssgenvC DB 0
        DS .(-$)
ssglowD DB 0
ssghighD DB 0
ssglowE DB 0
ssghighE DB 0
ssglowF DB 0
ssghighF DB 0
ssgnoiseD
ssgnoiseE
ssgnoiseF DB 0
ssgmaskD
ssgmaskE
ssgmaskF DB 0
ssgvolD DB 0
ssgvolE DB 0
ssgvolF DB 0
ssglow1 DB 0
ssghigh1 DB 0
ssgenvD
ssgenvE
ssgenvF DB 0
       ENDIF ;ssg
       DISPLAY "player size=",$-tfmplayer
       IFN ?tfcinclude
min     DW -1
max     DW 0
sum     DS 4
frames  DW 0
badframes  DW 0

       ;ORG #C000
tfmmuz
        INCBIN "t*.t"
DISPLAY $
       ;ORG IMER
        DS .(-$)
        DS '$
IMER
        PUSH AF
        INC (IY+62)
        POP AF
        EI 
        RET 
end
        ORG #5CDD
        DB "ducktaleB"
        INCLUDE "B:m2hr*",#C0
        ORG $
        CALL 8026
        JP NC,nenado
        LD A,218 ;JPC
        LD (JP_JPC),A
        JP GOFREE
       ENDIF 
drT\0),HL
        RET 
        ENDM 

;NM=TM=0 is incompatible with volume set
;mask channel:
;1  1  1  NOISE5      - set noise, continue
;1  1  0  N, disp16   - LZ
;1  0  1  N, disp8    - L