From 178968cc2fc4c32fb918ebb4ccd24d78b64cd73f Mon Sep 17 00:00:00 2001 From: Javier Degirolmo Date: Fri, 7 Oct 2011 12:17:54 -0300 Subject: Initial upload, Echo 0.8 UNSTABLE VERSION --- src-z80/core/sfx.z80 | 316 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 316 insertions(+) create mode 100644 src-z80/core/sfx.z80 (limited to 'src-z80/core/sfx.z80') diff --git a/src-z80/core/sfx.z80 b/src-z80/core/sfx.z80 new file mode 100644 index 0000000..b7e26aa --- /dev/null +++ b/src-z80/core/sfx.z80 @@ -0,0 +1,316 @@ +;**************************************************************************** +; PlaySFX [command $02] +; Plays a SFX +;**************************************************************************** + +PlaySFX: + PollPCM + call ClearSFX ; Clear SFX resources + PollPCM + + ld a, (RAM_Status) ; Show SFX playback in Echo's status + or $01 + ld (RAM_Status), a + + PollPCM + + ld hl, RAM_ComBank ; Get command parameters + ld c, (hl) + inc l + ld e, (hl) + inc l + ld d, (hl) + + PollPCM + + xor a ; Command parsed + ld (RAM_Command), a + + ld hl, RAM_SFXData ; Set SFX as playing + ld (hl), $01 + inc l ; No delays! + ld (hl), $01 + inc l ; Store SFX start bank + ld (hl), c + inc l ; Store SFX start address (low) + ld (hl), e + inc l ; Store SFX start address (high) + ld (hl), d + + PollPCM + + ld hl, ProcessSFX ; Tell Echo to process SFX + ld (DoTick_SFX+1), hl + + PollPCM + jp IdleLoop ; End of subroutine + +;**************************************************************************** +; ProcessSFX +; Processes a tick for a SFX +;**************************************************************************** + +ProcessSFX: + PollPCM + + ld hl, RAM_SFXData+1 ; SFX data address + + ld a, (hl) ; Delaying? + dec a + jp z, .nodelay + ld (hl), a + + jp DoTick_SFXSkip ; End of subroutine + +.nodelay: + PollPCM + + inc l ; Get current address + ld c, (hl) + inc l + ld e, (hl) + inc l + ld d, (hl) + ex de, hl + +ProcessSFXRun: + PollPCM ; Fetch next event + call GetParam + PollPCM + + ld a, b ; Parse byte + + cp $08 + jp c, NoteOnFMSFX ; Events $00-$07: note on FM + cp $0B + jp c, NoteOnPSGSFX ; Events $08-$0A: note on PSG (square) + jp z, NoteOnNoiseSFX ; Event $0B: note on PSG (noise) + cp $0C + jp z, PlayPCMSFX ; Event $0C: note on PCM + + PollPCM + ld a, b + + cp $18 + jp c, NoteOffFMSFX ; Events $10-$17: note off FM + cp $1C + jp c, NoteOffPSGSFX ; Events $18-$1B: note off PSG + jp z, StopPCMSFX ; Event $1C: note off PCM + + PollPCM + ld a, b + + cp $FE + jp z, SetDelaySFX ; Event $FE: set delay + cp $FF + jp z, StopSFXEvent ; Event $FF: stop SFX + + PollPCM + ld a, b + + cp $28 + jp c, SetFMVolSFX ; Events $28-$2B: set FM volume + cp $2C + jp c, SetPSGVolSFX ; Events $28-$2B: set PSG volume + + PollPCM + ld a, b + + cp $38 + jp c, SetNoteFMSFX ; Events $30-$37: set FM note + cp $3B + jp c, SetNotePSGSFX ; Events $38-$3A: set PSG note (square) + jp z, SetNoteNoiseSFX ; Event $3B: set PSG note (noise) + + PollPCM + ld a, b + + cp $48 + jp c, LoadFMSFX ; Events $40-$47: load FM instrument + cp $4C + jp c, LoadPSGSFX ; Events $48-$4B: load PSG instrument + + PollPCM + ld a, b + + cp $E8 + jp c, LockChannelFM ; Events $E0-$E7: lock FM channel + cp $EC + jp c, LockChannelPSG ; Events $E8-$EB: lock PSG channel + jp z, LockChannelPCM ; Event $EC: lock PCM channel + + PollPCM + ld a, b + + cp $F8 ; Events $F0-$F7: set FM parameters + jp c, SetFMParamSFX + +;**************************************************************************** +; StopSFX* [command $03, event $FF] +; Stops SFX playback +;**************************************************************************** + +StopSFXEvent: + call StopSFX ; We're just a wrapper + jp DoTick_SFXSkip ; End of subroutine + +StopSFXCmd: + xor a ; Command parsed + ld (RAM_Command), a + call StopSFX ; We're just a wrapper + jp IdleLoop ; End of subroutine + +StopSFX: + PollPCM + + ld a, (RAM_Status) ; Hide SFX playback in Echo's status + and $FE + ld (RAM_Status), a + + PollPCM + + xor a ; Stop playback + ld (RAM_SFXPlaying), a + ld hl, DoTick_SFXSkip + ld (DoTick_SFX+1), hl + + PollPCM + call ClearSFX ; Clear SFX resources + + PollPCM + ret ; End of subroutine + +;**************************************************************************** +; ClearSFX +; Clears SFX resources +;**************************************************************************** + +ClearSFX: + ld a, (RAM_Locked+6) ; Stop PCM playback if needed + or a + call nz, StopPCM + +;---------------------------------------------------------------------------- + + ld b, 4 ; Look for locked PSG channels + ld de, RAM_Locked+11 +.unlockpsg: + + PollPCM + + ld a, (de) ; Check if this channel needs unlocking + or a + jr z, .psgfree + xor a + ld (de), a + + PollPCM + + ld a, b ; Restore BGM volume + rrca + rrca + rrca + rrca + dec a + ld h, RAM_PSGData>>8 + ld l, a + ld c, (hl) + sub 15 + ld l, a + ld (hl), c + + PollPCM + push de + + ld a, l ; Restore BGM envelope + add 8 + ld l, a + add 12-8 + ld e, a + ld d, h + + PollPCM + + ld a, (de) + ld (hl), a + inc l + inc e + ld a, (de) + ld (hl), a + inc l + inc e + ld a, (de) + ld (hl), a + + pop de + PollPCM + +.psgfree: + dec e ; Go for next PSG channel to unlock + djnz .unlockpsg + +;---------------------------------------------------------------------------- + + ld b, 8 ; Look for locked FM channels +.unlockfm: + + PollPCM + + ld a, (de) ; Check if this channel needs unlocking + or a + jp z, .fmfree + xor a + ld (de), a + + dec b ; Mute FM channel + ld (ix+0), $28 + ld (ix+1), b + + PollPCM + + ld a, b + and $04 ; Determine which port to write + rrca + ld iyl, a + + ld a, b ; Kill ADSR + call KillFM + + PollPCM + + ld hl, RAM_BGMFMVol ; Restore BGM FM volume + ld a, b + add l + ld l, a + ld c, (hl) + ld a, l + add 8 + ld l, a + ld (hl), c + + PollPCM + + ld a, l ; Restore BGM FM instrument + sub 8*2 + ld l, a + push bc + push de + push hl + ld a, b + ld b, (hl) + call LoadFMDirect + pop hl + pop de + pop bc + + PollPCM + inc b +.fmfree: + PollPCM + dec e ; Go for next FM channel to unlock + dec b + jp nz, .unlockfm + +;---------------------------------------------------------------------------- + + ret ; End of subroutine -- cgit v1.2.3