aboutsummaryrefslogtreecommitdiff
path: root/src-z80/core/sfx.z80
diff options
context:
space:
mode:
authorJavier Degirolmo2011-10-07 12:17:54 -0300
committerJavier Degirolmo2011-10-07 12:17:54 -0300
commit178968cc2fc4c32fb918ebb4ccd24d78b64cd73f (patch)
treed8cb1d39bd1991258ffe45b4bcc498b0443e4b35 /src-z80/core/sfx.z80
Initial upload, Echo 0.8 UNSTABLE VERSION
Diffstat (limited to 'src-z80/core/sfx.z80')
-rw-r--r--src-z80/core/sfx.z80316
1 files changed, 316 insertions, 0 deletions
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