Login

Subversion Repositories NedoOS

Rev

Rev 731 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

filterhandler_vol
        ld a,e
        sub 1+15 ;"f" (1="0", 2="1"...)
        ld e,a ;vol "f" = +0, "g" = +1...
filtervolume
;ix=from=to
;e=volume shift (+-15)
        ld a,(ix+chn.volume)
        add a,e
        jp po,filtervolumeq ;no signed overflow
        rla
        sbc a,a ;a=0 for negative overflow, a=255 for positive overflow
        xor 0x80 ;a=-128 for negative overflow, a=127 for positive overflow
filtervolumeq        
        ld (ix+chn.volume),a
        ret

filterhandler_noise
;TODO
        ret
filternoise
;ix=from=to
;e=noise shift (+-15)
        ld a,(ix+chn.noisefrq)
        add a,e
        jp po,filternoiseq ;no signed overflow
        rla
        sbc a,a ;a=0 for negative overflow, a=255 for positive overflow
        xor 0x80 ;a=-128 for negative overflow, a=127 for positive overflow
filternoiseq
        ld (ix+chn.noisefrq),a
        ret

filterhandler_echo
;TODO
        ret

filterhandler_vib
;TODO
        ret
filtertone
;ix=from=to
;de=tone shift (+-4095)
        ld a,(ix+chn.tonefrq)
        add a,e
        ld e,a
        ld a,(ix+chn.tonefrq+1)
        adc a,d
        ld d,a
        jp p,$+6
         ld de,0
        ld (ix+chn.tonefrq),e
        ld (ix+chn.tonefrq+1),d
        ret

filterhandler_env
;TODO
filterenv
;ix=from=to
;de=env shift
        ld a,(ix+chn.envfrq)
        add a,e
        ld e,a
        ld a,(ix+chn.envfrq+1)
        adc a,d
        ld d,a
        jp p,$+6
         ld de,0
        ld (ix+chn.envfrq),e
        ld (ix+chn.envfrq+1),d
        ret

mixchn
;iy=from1=to
;ix=from2
;в release должен быть понижен приоритет канала
;если в from1 есть огибающая, то игнорируем from1, если его KEEPME <= чем у from2
;т.к. огибающую должен перекрывать тональник!!!
        ;bit MASKBIT_E,(iy+chn.masks)
        ;jr nz,mixchn_keep2
;если в from1 есть шум, то игнорируем from2, если его KEEPME <= чем у from1
        ;bit MASKBIT_N,(iy+chn.masks)
        ;jr nz,mixchn_keep1
;если в from2 дырка, то берём from1
        bit MASKBIT_HOLE,(ix+chn.masks)
        ret nz;jr nz,mixchn_keep1_ok
;если в from1 дырка, то берём from2
        bit MASKBIT_HOLE,(iy+chn.masks)
        jr nz,mixchn_keep2_ok
;берём самый громкий по тональнику
;TODO низкие ноты не считать громкими
        ld a,(ix+chn.volume)
         bit MASKBIT_E,(ix+chn.masks)
         jr z,$+4
         ld a,12 ;E играет на уровне 11, C на уровне 13, T-E играет громко!!! TODO
        add a,(ix+chn.keepme)
        add a,0x80
        ld e,a
        ld a,(iy+chn.volume)
         bit MASKBIT_E,(iy+chn.masks)
         jr z,$+4
         ld a,12 ;E играет на уровне 11, C на уровне 13, T-E играет громко!!! TODO
        add a,(iy+chn.keepme)
        add a,0x80
        cp e
        jr c,mixchn_keep2_ok
mixchn_keep1
        ;ld a,(iy+chn.keepme)
        ;cp (ix+chn.keepme)
        ;ret nc ;при равенстве keepme оставляем from1
        ;jr c,mixchn_keep2_ok
        bit MASKBIT_OUTERENV,(ix+chn.masks)
        jr nz,mixchn_keep2outerenv
        ret
mixchn_keep2
        ;ld a,(ix+chn.keepme)
        ;cp (iy+chn.keepme)
        ;jr c,mixchn_keep1 ;при равенстве keepme оставляем from2
        bit MASKBIT_OUTERENV,(ix+chn.masks)
        jr nz,mixchn_keep1outerenv
mixchn_keep2_ok
        push ix
        pop hl
        push iy
        pop de
        ld bc,chn.note_in;chn
        ldir
        ret
mixchn_keep1outerenv
        ld a,(ix+chn.envfrq)
        ld (iy+chn.envfrq),a
        ld a,(ix+chn.envfrq+1)
        ld (iy+chn.envfrq+1),a
        ret
mixchn_keep2outerenv
        push ix
        pop hl
        push iy
        pop de
        ld bc,chn.note_in;chn
        ldir
        ld a,(iy+chn.envfrq)
        ld (ix+chn.envfrq),a
        ld a,(iy+chn.envfrq+1)
        ld (ix+chn.envfrq+1),a
        ret

;надо в дырке такое поведение:
;       ||
;      |||        
;|||||||||____
;т.е. в дырке ставим громкость 0 (а не маску !T!N)
rendchip
;ix=fromA
;hl=fromB
;de=fromC
;iy=chip
        push de ;fromC
        push hl ;fromB
        ld bc,0x00ff ;b=ретриггеры A,B,C ;c=masks: все выключены
        ld d,b ;текущий приоритет шума
        ld e,b ;текущий приоритет огибающей
        ld h,(iy+chip.envtype) ;бывший тип огибающей
        res retrigenvbit,h
        ld l,h

        xor a
        bit MASKBIT_HOLE,(ix+chn.masks)
        jr nz,rendchip_Anoenv
        ld a,(ix+chn.volume)
        cp 16
        jr c,$+7
         rla
         sbc a,a
         cpl
         and 15
        bit MASKBIT_E,(ix+chn.masks)
        jr z,rendchip_Anoenv
        ld e,(ix+chn.keepme) ;текущий приоритет огибающей
        ld a,(ix+chn.envfrq)
        ld (iy+chip.envfrq),a
        ld a,(ix+chn.envfrq+1)
        ld (iy+chip.envfrq+1),a
        ld l,(ix+chn.envtype) ;текущий тип огибающей
        ld a,16
rendchip_Anoenv
        ld (iy+chip.Avolume),a
        bit MASKBIT_T,(ix+chn.masks)
        jr z,rendchip_Anotone
        dec c ;res 0,c
        ld a,(ix+chn.tonefrq+1)
        cp 4096/256
        jr c,$+4
         ld a,-1 ;overflow
        ld (iy+chip.Atonefrq+1),a
        jr nc,$+5 ;overflow
         ld a,(ix+chn.tonefrq)
        ld (iy+chip.Atonefrq),a
        bit MASKBIT_RETRIGTONE,(ix+chn.masks)
        jr z,$+3
        inc b ;set 0,b сумма ретриггеров
rendchip_Anotone
        bit MASKBIT_N,(ix+chn.masks)
        jr z,rendchip_Anonoise
        res 3,c
        ld d,(ix+chn.keepme) ;текущий приоритет шума
        ld a,(ix+chn.noisefrq)
        cp 32
        jr c,$+5;7
         rla
         sbc a,a
         cpl
         ;and 31
        ld (iy+chip.noisefrq),a
rendchip_Anonoise

        pop ix ;fromB
        xor a
        bit MASKBIT_HOLE,(ix+chn.masks)
        jr nz,rendchip_Bnoenv
        ld a,(ix+chn.volume)
        cp 16
        jr c,$+7
         rla
         sbc a,a
         cpl
         and 15
        bit MASKBIT_E,(ix+chn.masks)
        jr z,rendchip_Bnoenv
        ld a,(ix+chn.keepme)
        cp e ;текущий приоритет огибающей
        jr c,rendchip_Buseenv
        ld e,a
        ld a,(ix+chn.envfrq)
        ld (iy+chip.envfrq),a
        ld a,(ix+chn.envfrq+1)
        ld (iy+chip.envfrq+1),a
        ld l,(ix+chn.envtype) ;текущий тип огибающей
rendchip_Buseenv
        ld a,16
rendchip_Bnoenv
        ld (iy+chip.Bvolume),a
        bit MASKBIT_T,(ix+chn.masks)
        jr z,rendchip_Bnotone
        res 1,c
        ld a,(ix+chn.tonefrq+1)
        cp 4096/256
        jr c,$+4
         ld a,-1 ;overflow
        ld (iy+chip.Btonefrq+1),a
        jr nc,$+5 ;overflow
         ld a,(ix+chn.tonefrq)
        ld (iy+chip.Btonefrq),a
        bit MASKBIT_RETRIGTONE,(ix+chn.masks)
        jr z,$+4
         set 1,b ;сумма ретриггеров
rendchip_Bnotone
        bit MASKBIT_N,(ix+chn.masks)
        jr z,rendchip_Bnonoise
        res 4,c
        ld a,(ix+chn.keepme)
        cp d ;текущий приоритет шума
        jr c,rendchip_Bnonoise
        ld d,a
        ld a,(ix+chn.noisefrq)
        cp 32
        jr c,$+5;7
         rla
         sbc a,a
         cpl
         ;and 31
        ld (iy+chip.noisefrq),a
rendchip_Bnonoise
       
        pop ix ;fromC
        xor a
        bit MASKBIT_HOLE,(ix+chn.masks)
        jr nz,rendchip_Cnoenv
        ld a,(ix+chn.volume)
        cp 16
        jr c,$+7
         rla
         sbc a,a
         cpl
         and 15
        bit MASKBIT_E,(ix+chn.masks)
        jr z,rendchip_Cnoenv
        ld a,(ix+chn.keepme)
        cp e ;текущий приоритет огибающей
        jr c,rendchip_Cuseenv
        ;ld e,a
        ld a,(ix+chn.envfrq)
        ld (iy+chip.envfrq),a
        ld a,(ix+chn.envfrq+1)
        ld (iy+chip.envfrq+1),a
        ld l,(ix+chn.envtype) ;текущий тип огибающей
rendchip_Cuseenv
        ld a,16
rendchip_Cnoenv
        ld (iy+chip.Cvolume),a
        bit MASKBIT_T,(ix+chn.masks)
        jr z,rendchip_Cnotone
        res 2,c
        ld a,(ix+chn.tonefrq+1)
        cp 4096/256
        jr c,$+4
         ld a,-1 ;overflow
        ld (iy+chip.Ctonefrq+1),a
        jr nc,$+5 ;overflow
         ld a,(ix+chn.tonefrq)
        ld (iy+chip.Ctonefrq),a
        bit MASKBIT_RETRIGTONE,(ix+chn.masks)
        jr z,$+4
         set 2,b ;сумма ретриггеров
rendchip_Cnotone
        bit MASKBIT_N,(ix+chn.masks)
        jr z,rendchip_Cnonoise
        res 5,c
        ld a,(ix+chn.keepme)
        cp d ;текущий приоритет шума
        jr c,rendchip_Cnonoise
        ;ld d,a
        ld a,(ix+chn.noisefrq)
        cp 32
        jr c,$+5;7
         rla
         sbc a,a
         cpl
         ;and 31
        ld (iy+chip.noisefrq),a
rendchip_Cnonoise

        ld (iy+chip.retriggers),b
        ld (iy+chip.masks),c
        ld a,l
        cp h ;несовпадение в том числе при retrigenvbit (в h он сброшен)
        jr z,$+4
         set retrigenvbit,a
        ld (iy+chip.envtype),a ;текущий тип огибающей
        ret

outchip
;hl=chip (байт флагов ретриггера (ABC) + 13 байт данных AY)
        xor a
        LD C,0xfd
        LD E,0xBF
        bit 0,(hl)
        jr z,outchip_noretrigA
        ld d,0
        ld b,0xff
        out (c),d
        ld b,e
        out (c),a
        inc d
        ld b,0xff
        out (c),d
        ld b,e
        out (c),a
outchip_noretrigA
        bit 1,(hl)
        jr z,outchip_noretrigB
        ld d,2
        ld b,0xff
        out (c),d
        ld b,e
        out (c),a
        inc d
        ld b,0xff
        out (c),d
        ld b,e
        out (c),a
outchip_noretrigB
        bit 2,(hl)
        jr z,outchip_noretrigC
        ld d,4
        ld b,0xff
        out (c),d
        ld b,e
        out (c),a
        inc d
        ld b,0xff
        out (c),d
        ld b,e
        out (c),a
outchip_noretrigC
        inc hl
        ;xor a
        ld d,0xff
       dup 12
        ld b,d;0xff
        OUT (C),a
        LD B,E
        OUTI
        inc a
       edup
        ld b,d;0xff
        OUT (C),a
        LD B,E
        OUTI
        bit retrigenvbit,(hl)
        ret z ;no env retrigger
        inc a
        ld b,d;0xff
        OUT (C),a
        LD B,E
        OUTI
        ret

setchip1
        ld a,0xff
        jr setchip_a
setchip0
        ld a,0xfe
setchip_a
        ld bc,0xfffd
        out (c),a
        ret
       
;Sample:
;256 masks (T,N,E,hole,outerenv,retrigtone, semitoneshiftpresent,tonefrqshiftpresent), одна из комбинаций означает loop (например, -1)
noisefrqpresent=1
envtypepresent=2
semitoneshiftpresent=6
tonefrqshiftpresent=7
;+-96 semitone shift (в потоке при наличии semitoneshiftpresent)
;+-96 env semitone shift (fair tone ratio guaranteed for 1:1, 3:4, 1:2, 1:4, 3:1, 5:2, 2:1, 3:2 + 4:1) (в потоке при наличии E)
;8*2 envtype + retrigenv (в потоке при наличии E)
;16 volume (в потоке при отсутствии E)
;+-4095 tonefrq shift (в потоке при наличии tonefrqshiftpresent)
;32 noisefrq (в потоке при наличии N)
;>1 >256 loop addrshift

playsample
        ld l,(ix+chn.smpcuraddr)
        ld h,(ix+chn.smpcuraddr+1)
;playsample_go
;ix=chn
;в любом случае полностью определяет текущие значения полей chn:
;masks   BYTE ;T,N,E,hole,outerenv,retrigtone, semitoneshiftpresent,tonefrqshiftpresent (должен быть первым байтом строки в потоке)
;envtype BYTE (в потоке при наличии E, значения 8..15 (15 как 4, 9 как 1) + retrigenv) ;или volume  BYTE ;volume = 0..15 (в потоке при отсутствии E)
;noisefrq BYTE ;noise = 0..31 (в потоке при наличии N)
    ;keepme  BYTE ;priority for keep on top (bigger is more priority)
    ;envfrq  WORD
    ;tonefrq WORD
        ld b,(hl) ;masks
        inc hl
        ld (ix+chn.masks),b ;masks   BYTE ;T,N,E,hole,outerenv,retrigtone, semitoneshiftpresent,tonefrqshiftpresent (должен быть первым байтом строки в потоке)
        ld a,(ix+chn.note_in)

        ;bit semitoneshiftpresent,b
        ;jr z,playsample_nosemitoneshift
        add a,(hl)
        inc hl
        jp po,playsample_nosemitoneshift ;no signed overflow
        rla
        sbc a,a ;a=0 for negative overflow, a=255 for positive overflow
        xor 0x80 ;a=-128 for negative overflow, a=127 for positive overflow
playsample_nosemitoneshift

        bit envtypepresent,b
        jr z,playsample_noenvsemitoneshift
        add a,(hl) ;envsemitoneshift
        ld e,a
        ld d,tfrq/256
;cout env frq (use frq table)
        ld a,(de)
        ld c,a
        inc d
        ld a,(de)
        ;ld d,a
        ld (ix+chn.envfrq),c
        ld (ix+chn.envfrq+1),a;d
;count tone frq (TODO use ratio)
;временная затычка - частота тона по частотной таблице без envsemitoneshift
        ld a,e
        sub (hl)
        ld e,a
        ld a,(de)
        ld c,a
        dec d
        ld a,(de)
        ld e,a
        ld d,c
        ;ld a,(hl) ;envsemitoneshift

        inc hl
        ld a,(hl)
        inc hl
        ld (ix+chn.envtype),a ;envtype BYTE (в потоке при наличии E, значения 8..15 (15 как 4, 9 как 1) + retrigenvbit) ;тип огибающей без E не используется
        jr playsample_noenvsemitoneshiftq
playsample_noenvsemitoneshift
;count tone frq (use frq table)
        ld e,a
        ld d,tfrq/256
        ld a,(de)
        ld c,a
        inc d
        ld a,(de)
        ld d,a
        ld e,c ;de=tonefrq
       
         inc hl ;skip envsemitoneshift
        ld a,(hl)
        inc hl
         add a,(ix+chn.volume_in)
        ld (ix+chn.volume),a ;volume  BYTE ;volume = 0..15 ;громкость при E не используется
playsample_noenvsemitoneshiftq

        ;bit tonefrqshiftpresent,b
        ;jr z,playsample_notonefrqshift
        ld a,(hl)
        add a,e
        ld e,a
        inc hl
        ld a,(hl)
        adc a,d
        ld d,a ;correct tone frq
        inc hl
;playsample_notonefrqshift
       
        ;bit noisefrqpresent,b
        ;jr z,playsample_nonoisefrq
        ld a,(hl)
        inc hl
        ld (ix+chn.noisefrq),a ;noisefrq BYTE ;noise = 0..31 (в потоке при наличии N) ;noisefrq без N не используется
;playsample_nonoisefrq
        ld a,(ix+chn.keepme_in)
        ld (ix+chn.keepme),a ;keepme  BYTE ;priority for keep on top (bigger is more priority)

;out: hl=next line in sample
        ld a,(hl)
        inc a
        jr nz,playsample_noloop
        inc hl
        ld c,(hl)
        inc hl
        ld b,(hl)
        add hl,bc
playsample_noloop
        ld (ix+chn.smpcuraddr),l
        ld (ix+chn.smpcuraddr+1),h

;накапливать глисс и прибавить его к tonefrq (в будущем считать глисс и пр. параметры от времени?)
        ld a,(ix+chn.curgliss)
        add a,(ix+chn.glissspeed_in)
        ld (ix+chn.curgliss),a
        ld l,a
        ld a,(ix+chn.curgliss+1)
        adc a,(ix+chn.glissspeed_in+1)
        ld (ix+chn.curgliss+1),a
        ld h,a
        sra h
        rr l
        sra h
        rr l
        sra h
        rr l ;+-12.3
        add hl,de
        ld (ix+chn.tonefrq),l
        ld (ix+chn.tonefrq+1),h
        ret

shutay
        call setchip0
        call shut1ay
        call setchip1
shut1ay
        ld de,0x0e00
shutay0
        dec d
        ld bc,0xfffd
        out (c),d
        ld b,0xbf
        out (c),e
        jr nz,shutay0
        ret