From a679ba38190bfed6ae150a12e819ad7527c495d1 Mon Sep 17 00:00:00 2001 From: sik Date: Sun, 5 Mar 2017 20:57:11 -0300 Subject: Upgrade! --- src-z80/build.z80 | 1 + src-z80/core/bgm.z80 | 6 ++ src-z80/core/direct.z80 | 30 ++++++++ src-z80/core/main.z80 | 35 ++++++++-- src-z80/core/sfx.z80 | 10 +++ src-z80/core/vars.z80 | 6 +- src-z80/player/fm.z80 | 179 ++++++++++++++++++++++++++++++++++++++++-------- src-z80/player/freq.z80 | 10 +++ src-z80/player/misc.z80 | 44 ++++++++++++ src-z80/player/pcm.z80 | 11 ++- src-z80/player/psg.z80 | 3 +- 11 files changed, 300 insertions(+), 35 deletions(-) create mode 100644 src-z80/core/direct.z80 (limited to 'src-z80') diff --git a/src-z80/build.z80 b/src-z80/build.z80 index 88932ac..1aaa709 100644 --- a/src-z80/build.z80 +++ b/src-z80/build.z80 @@ -2,6 +2,7 @@ include "src-z80/player/pcm.z80" include "src-z80/core/bgm.z80" include "src-z80/core/sfx.z80" + include "src-z80/core/direct.z80" include "src-z80/player/fm.z80" include "src-z80/player/psg.z80" include "src-z80/player/misc.z80" diff --git a/src-z80/core/bgm.z80 b/src-z80/core/bgm.z80 index 2f57a73..338a7a6 100644 --- a/src-z80/core/bgm.z80 +++ b/src-z80/core/bgm.z80 @@ -97,6 +97,8 @@ ResumeBGM: ;**************************************************************************** ; ProcessBGM ; Processes a tick for a BGM +;---------------------------------------------------------------------------- +; breaks: all ;**************************************************************************** ProcessBGM: @@ -153,6 +155,7 @@ ProcessBGMSkip: cp $FE jp z, SetDelayBGM ; Event $FE: set delay cp $FF +ProcessBGMEventFF: jp z, StopBGMEvent ; Event $FF: stop BGM cp $FC jp z, LoopBGM ; Event $FC: loop BGM @@ -192,8 +195,11 @@ ProcessBGMSkip: cp $F8 ; Events $F0-$F7: set FM parameters jp c, SetFMParamBGM + cp $FA ; Events $F8-$F9: set FM register + jp c, SetFMRegBGM PollPCM ; FFFFFFFFF bad event >:( +ProcessBGMEnd: jp StopBGMEvent ; End of subroutine ProcessBGMSkip2: ; This is where we land after a locked event diff --git a/src-z80/core/direct.z80 b/src-z80/core/direct.z80 new file mode 100644 index 0000000..d796ddf --- /dev/null +++ b/src-z80/core/direct.z80 @@ -0,0 +1,30 @@ +;**************************************************************************** +; ProcessDirect +; Processes the direct event stream. +;---------------------------------------------------------------------------- +; breaks: all +;**************************************************************************** + +ProcessDirect: + ld a, ($1F00) ; Are there even events to process? + inc a + ret z + + PollPCM + + ld hl, ProcessDirectEnd ; Override $FF event + ld (ProcessBGMEventFF+1), hl + + ld hl, $1F00 ; Where event data is stored + ld a, (RAM_LastBank) ; To avoid wasting time with bank + ld c, a ; switching + + jp ProcessBGMRun ; Start processing the event + +ProcessDirectEnd: + ld hl, StopBGMEvent ; Restore $FF event + ld (ProcessBGMEventFF+1), hl + ld a, $FF ; Reset the stream + ld ($1F00), a + + ret ; Return to the main loop diff --git a/src-z80/core/main.z80 b/src-z80/core/main.z80 index da323f4..4eb6e5a 100644 --- a/src-z80/core/main.z80 +++ b/src-z80/core/main.z80 @@ -90,6 +90,8 @@ EntryPoint: ;**************************************************************************** ; PollPCM ; Used to update PCM while not idle +;---------------------------------------------------------------------------- +; breaks: af ;**************************************************************************** PollPCM: macro @@ -154,21 +156,31 @@ IdleLoop: ;**************************************************************************** DoTick: - ld a, (ix+0) - bit 0, a - call nz, UpdatePCM +; ld a, (ix+0) +; bit 0, a +; call nz, UpdatePCM - ld (ix+0), $27 + PollPCM + + ld (ix+0), $27 ; Retrigger the timer ld (ix+1), $2F PollPCM + + ld a, ($1FF1) ; Refresh volume if needed + or a + call nz, RefreshVolume DoTick_SFX: ; Process SFXs jp DoTick_SFXSkip DoTick_SFXSkip: PollPCM + + call ProcessDirect ; Process direct events + PollPCM + DoTick_BGM: ; Process BGMs jp DoTick_BGMSkip DoTick_BGMSkip: @@ -257,6 +269,19 @@ LoadList: ;**************************************************************************** ; GetParam ; Subroutine for getting the parameter byte +;---------------------------------------------------------------------------- +; input c .... current bank +; input hl ... current address +;---------------------------------------------------------------------------- +; output b .... value +; output c .... new bank +; output hl ... new address +;---------------------------------------------------------------------------- +; breaks: af +;---------------------------------------------------------------------------- +; note: the C value gets incremented *only* when HL hits $0000 (this is +; relevant if you consider using it to fetch from Z80 RAM, which should +; never result in HL becoming $0000). ;**************************************************************************** GetParam: @@ -270,7 +295,7 @@ GetParam: BankSwitch pop hl .noswitchp: - ld b, (hl) ; Get volume + ld b, (hl) ; Get value inc l ; Get next address jp nz, .nonewbankp diff --git a/src-z80/core/sfx.z80 b/src-z80/core/sfx.z80 index 1c62873..4bca4c7 100644 --- a/src-z80/core/sfx.z80 +++ b/src-z80/core/sfx.z80 @@ -1,6 +1,8 @@ ;**************************************************************************** ; PlaySFX [command $02] ; Plays a SFX +;---------------------------------------------------------------------------- +; breaks: all ;**************************************************************************** PlaySFX: @@ -48,6 +50,8 @@ PlaySFX: ;**************************************************************************** ; ProcessSFX ; Processes a tick for a SFX +;---------------------------------------------------------------------------- +; breaks: all ;**************************************************************************** ProcessSFX: @@ -147,10 +151,14 @@ ProcessSFXRun: cp $F8 ; Events $F0-$F7: set FM parameters jp c, SetFMParamSFX + cp $FA ; Events $F8-$F9: set FM register + jp c, SetFMRegSFX ;**************************************************************************** ; StopSFX* [command $03, event $FF] ; Stops SFX playback +;---------------------------------------------------------------------------- +; breaks: all ;**************************************************************************** StopSFXEvent: @@ -186,6 +194,8 @@ StopSFX: ;**************************************************************************** ; ClearSFX ; Clears SFX resources +;---------------------------------------------------------------------------- +; breaks: all ;**************************************************************************** ClearSFX: diff --git a/src-z80/core/vars.z80 b/src-z80/core/vars.z80 index 959711b..cd7162d 100644 --- a/src-z80/core/vars.z80 +++ b/src-z80/core/vars.z80 @@ -17,6 +17,7 @@ RAM_BGMFMInstr: ds 8 ; FM instruments used by BGM RAM_BGMFMVol: ds 8 ; FM volumes used by BGM RAM_BGMFMPan: ds 8, $C0 ; FM panning used by BGM +RAM_FMVol: ds 8 ; FM volume of each channel RAM_FMData: ds 8*5 ; FM info (for volume handling) ; ds 8*1 ... Register $B0 ; ds 8*1 ... Register $40 @@ -25,6 +26,7 @@ RAM_FMData: ds 8*5 ; FM info (for volume handling) ; ds 8*1 ... Register $4C RAM_Locked: ds 12 ; Locked channels +RAM_PSGNote: ds 4 ; Current PSG notes RAM_LastBank: ds 1 ; Last accessed bank @@ -64,9 +66,11 @@ RAM_PointerList: equ $1C00 ; 68000 communication variables ;**************************************************************************** -RAM_Stack: equ $1FF0 ; Where stack starts +RAM_Stack: equ $1FE0 ; Where stack starts +RAM_GlobalVol: equ $1FE0 ; Global volume for all channels RAM_Status: equ $1FF0 ; Current playback status +RAM_RefreshVol: equ $1FF1 ; Set to refresh all volumes RAM_Command: equ $1FFF ; Command type RAM_ComAddr: equ $1FFD ; Command address parameter RAM_ComBank: equ $1FFC ; Command bank parameter diff --git a/src-z80/player/fm.z80 b/src-z80/player/fm.z80 index 558a01d..505e849 100644 --- a/src-z80/player/fm.z80 +++ b/src-z80/player/fm.z80 @@ -1,6 +1,12 @@ ;**************************************************************************** -; NoteOnFM +; NoteOnFM* [events $00~$07] ; Does a "note on" for a FM channel +;---------------------------------------------------------------------------- +; input a .... FM channel (bottom 3 bits) +; input c .... current bank +; input hl ... current address +;---------------------------------------------------------------------------- +; breaks: af, b ;**************************************************************************** NoteOnFMSFX: @@ -95,8 +101,14 @@ NoteOnFM: ret ; End of subroutine ;**************************************************************************** -; NoteOffFM +; NoteOffFM [events $10~$17] ; Does a "note off" for a FM channel +;---------------------------------------------------------------------------- +; input a .... FM channel (bottom 3 bits) +; input c .... current bank +; input hl ... current address +;---------------------------------------------------------------------------- +; breaks: af, b ;**************************************************************************** NoteOffFMSFX: @@ -129,8 +141,14 @@ NoteOffFM: ret ; End of subroutine ;**************************************************************************** -; SetFMNote* +; SetFMNote* [events $30~$37] ; Sets the note of a FM channel without "note on" +;---------------------------------------------------------------------------- +; input a .... FM channel (bottom 3 bits) +; input c .... current bank +; input hl ... current address +;---------------------------------------------------------------------------- +; breaks: af, b ;**************************************************************************** SetNoteFMSFX: @@ -200,8 +218,14 @@ SetNoteFM: ret ; End of subroutine ;**************************************************************************** -; LoadFM* +; LoadFM* [events $40~$47] ; Loads a FM instrument +;---------------------------------------------------------------------------- +; input a .... FM channel (bottom 3 bits) +; input c .... current bank +; input hl ... current address +;---------------------------------------------------------------------------- +; breaks: af, b ;**************************************************************************** LoadFMSFX: @@ -398,7 +422,9 @@ LoadFMDirect: pop hl pop de pop bc - ret + + ld b, 0 + jp SetFMVolLoad ;**************************************************************************** ; SetFMVol* @@ -475,6 +501,13 @@ SetFMVolLoad: and $07 ; Get channel ID + push af ; Store new FM volume + ld h, RAM_FMVol>>8 + add RAM_FMVol&$FF + ld l, a + ld (hl), b + pop af + push af ld h, RAM_FMData>>8 ; Get address of FM data add RAM_FMData&$FF @@ -483,6 +516,17 @@ SetFMVolLoad: ex af, af' PollPCM ex af, af' + + and $07 ; Get global volume + or $E0 + ld d, $1F + ld e, a + ex af, af' + ld a, (de) + ld d, a + + PollPCM + ex af, af' and $04 ; Determine which port to write rrca @@ -508,11 +552,13 @@ SetFMVolLoad: jr c, .noop1 ld (iy+0), c ld a, (hl) + add d + jp m, .tooquiet1 add b - cp $7F - jr c, .notooloud1 + jp p, .notooquiet1 +.tooquiet1: ld a, $7F -.notooloud1: +.notooquiet1: ld (iy+1), a .noop1: ld a, c @@ -529,11 +575,13 @@ SetFMVolLoad: jr c, .noop2 ld (iy+0), c ld a, (hl) + add d + jp m, .tooquiet2 add b - cp $7F - jr c, .notooloud2 + jp p, .notooquiet2 +.tooquiet2: ld a, $7F -.notooloud2: +.notooquiet2: ld (iy+1), a .noop2: ld a, c @@ -550,11 +598,13 @@ SetFMVolLoad: jr c, .noop3 ld (iy+0), c ld a, (hl) + add d + jp m, .tooquiet3 add b - cp $7F - jr c, .notooloud3 + jp p, .notooquiet3 +.tooquiet3: ld a, $7F -.notooloud3: +.notooquiet3: ld (iy+1), a .noop3: ld a, c @@ -568,11 +618,13 @@ SetFMVolLoad: ld l, a ld (iy+0), c ld a, (hl) ; Process operator #4 + add d + jp m, .tooquiet4 add b - cp $7F - jr c, .notooloud4 + jp p, .notooquiet4 +.tooquiet4: ld a, $7F -.notooloud4: +.notooquiet4: ld (iy+1), a PollPCM @@ -583,8 +635,17 @@ SetFMVolLoad: ret ; End of subroutine ;**************************************************************************** -; SetFMParam* +; SetFMParam* [events $F0-$F7] ; Sets the different parameters of a FM channel +;---------------------------------------------------------------------------- +; input c .... current bank +; input hl ... current address +;---------------------------------------------------------------------------- +; output b .... value +; output c .... new bank +; output hl ... new address +;---------------------------------------------------------------------------- +; breaks: af, b ;**************************************************************************** SetFMParamSFX: @@ -656,9 +717,63 @@ SetFMParamBGM: jp ProcessBGMRun ; End of subroutine +;**************************************************************************** +; SetFMReg* [events $F8-$F9] +; Changes a FM register +;---------------------------------------------------------------------------- +; input a .... YM2612 register bank (0 or 1, in bit 0) +; input c .... current bank +; input hl ... current address +;---------------------------------------------------------------------------- +; output b .... value +; output c .... new bank +; output hl ... new address +;---------------------------------------------------------------------------- +; breaks: af, b +;**************************************************************************** + +SetFMRegSFX: + call SetFMReg ; We're just a wrapper + jp ProcessSFXRun + +SetFMRegBGM: + call SetFMReg ; We're just a wrapper + jp ProcessBGMRun + +;---------------------------------------------------------------------------- + +SetFMReg: + and $01 ; Get port address + add a + ld iyl, a + + PollPCM ; Get parameters + call GetParam + push bc + PollPCM + call GetParam + PollPCM + ld a, b + pop bc + + ld (iy+0), b ; Write register + ld (iy+1), a + + ret ; End of subroutine + ;**************************************************************************** ; LockChannelFM [events $E0-$E7] ; Locks a FM channel +;---------------------------------------------------------------------------- +; input a ... FM channel (0..7, in bottom 3 bits) +; input c .... current bank +; input hl ... current address +;---------------------------------------------------------------------------- +; output b .... value +; output c .... new bank +; output hl ... new address +;---------------------------------------------------------------------------- +; breaks: af, iy ;**************************************************************************** LockChannelFM: @@ -694,6 +809,10 @@ LockChannelFM: ;**************************************************************************** ; KillFM ; Kills a FM channel +;---------------------------------------------------------------------------- +; input a ... FM channel (0..7, in bottom 3 bits) +;---------------------------------------------------------------------------- +; breaks: af, c, iy ;**************************************************************************** KillFM: @@ -720,20 +839,26 @@ KillFM: ld e, (hl) ld (iy+0), a - add 4 ld (iy+1), e - nop - ld (iy+0), a add 4 - ld (iy+1), e - nop + ex af, af' + PollPCM + ex af, af' ld (iy+0), a - add 4 ld (iy+1), e - nop + add 4 + ex af, af' + PollPCM + ex af, af' ld (iy+0), a + ld (iy+1), e add 4 + ex af, af' + PollPCM + ex af, af' + ld (iy+0), a ld (iy+1), e + add 4 inc l dec c @@ -743,7 +868,7 @@ KillFM: pop de PollPCM pop af - + ld c, a ; Cause the ADSR to reset or $F0 ld (ix+0), $28 @@ -752,7 +877,7 @@ KillFM: ld (ix+1), a ld (ix+0), $28 ld (ix+1), c - + PollPCM ret ; End of subroutine diff --git a/src-z80/player/freq.z80 b/src-z80/player/freq.z80 index beb8702..7f963e5 100644 --- a/src-z80/player/freq.z80 +++ b/src-z80/player/freq.z80 @@ -88,6 +88,16 @@ FMFreqTable: dw 810, 858, 910, 964 dw 1021, 1081, 1146, 1214 +;**************************************************************************** +; PSGShiftTable +; Semitone shifting table for PSG instruments +;**************************************************************************** + +PSGShiftTable: + db 0 + db 2, 4, 6, 8, 10, 12 + db -2, -4, -6, -8, -10, -12 + ;**************************************************************************** ; DummyFMInstr ; Dummy FM instrument to mute FM channels... diff --git a/src-z80/player/misc.z80 b/src-z80/player/misc.z80 index 36be250..dee980e 100644 --- a/src-z80/player/misc.z80 +++ b/src-z80/player/misc.z80 @@ -44,3 +44,47 @@ SetDelayShort: ld (hl), b ret ; End of subroutine + +;**************************************************************************** +; RefreshVolume +; Reloads the volume for all channels. +;---------------------------------------------------------------------------- +; breaks: all +;**************************************************************************** + +RefreshVolume: + ld hl, $1FF0 ; Update FM volume + ld de, RAM_FMVol + ld c, 8 +.fixfmvol: + ld a, (de) + ld b, (hl) + add b + jp p, .fixfmvolok + ld a, $7F +.fixfmvolok: + ld b, a + ld a, l + call SetFMVolLoad + inc l + inc e + dec c + jr nz, .fixfmvol + + ld hl, $1FE8 ; Update PSG volume + ld de, RAM_PSGData+1 + ld bc, $0410 +.fixpsgvol: + ld a, (hl) + ld (de), a + inc l + ld a, e + add a, c + ld e, a + PollPCM + djnz .fixpsgvol + + xor a ; Mark that volume was refreshed + ld ($1FF1), a + + ret ; End of subroutine diff --git a/src-z80/player/pcm.z80 b/src-z80/player/pcm.z80 index 2a484d4..99feb6d 100644 --- a/src-z80/player/pcm.z80 +++ b/src-z80/player/pcm.z80 @@ -1,6 +1,11 @@ ;**************************************************************************** -; PlayPCM* +; PlayPCM* [event $0C] ; Plays a PCM sample +;---------------------------------------------------------------------------- +; input c .... current bank +; input hl ... current address +;---------------------------------------------------------------------------- +; breaks: af, b ;**************************************************************************** PlayPCMSFX: @@ -18,6 +23,10 @@ PlayPCMBGM: jp ProcessBGMRun ; End of subroutine PlayPCM: + ld a, (RAM_GlobalVol+$0C) ; Are we allowed to play PCM? + or a + ret z + call GetParam ; Get sample ID ld a, b diff --git a/src-z80/player/psg.z80 b/src-z80/player/psg.z80 index f0c5a76..b88978c 100644 --- a/src-z80/player/psg.z80 +++ b/src-z80/player/psg.z80 @@ -46,7 +46,7 @@ UpdatePSG: cp $FF ; Loop envelope? jp z, .envloop - ld iyl, b ; Keep byte safe somewhere... + ld iyl, b ; Keep byte safe somewhere... PollPCM ex de, hl ; Store new address @@ -61,6 +61,7 @@ UpdatePSG: PollPCM db $FD,$7D ; ld a, iyl ; Mix envelope with volume + and $0F add b ld b, a -- cgit v1.2.3