diff options
| author | Javier Degirolmo | 2011-10-07 12:17:54 -0300 |
|---|---|---|
| committer | Javier Degirolmo | 2011-10-07 12:17:54 -0300 |
| commit | 178968cc2fc4c32fb918ebb4ccd24d78b64cd73f (patch) | |
| tree | d8cb1d39bd1991258ffe45b4bcc498b0443e4b35 /src-z80/core/bgm.z80 | |
Initial upload, Echo 0.8 UNSTABLE VERSION
Diffstat (limited to 'src-z80/core/bgm.z80')
| -rw-r--r-- | src-z80/core/bgm.z80 | 290 |
1 files changed, 290 insertions, 0 deletions
diff --git a/src-z80/core/bgm.z80 b/src-z80/core/bgm.z80 new file mode 100644 index 0000000..f69235d --- /dev/null +++ b/src-z80/core/bgm.z80 @@ -0,0 +1,290 @@ +;**************************************************************************** +; PlayBGM [command $04] +; Plays a BGM +;**************************************************************************** + +PlayBGM: + PollPCM + call ClearBGM ; Clear BGM resources + PollPCM + + ld a, (RAM_Status) ; Show BGM playback in Echo's status + or $02 + 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_BGMData ; Set BGM as playing + ld (hl), $01 + inc l ; No delays! + ld (hl), $01 + inc l ; Store BGM start bank + ld (hl), c + inc l ; Store BGM start address (low) + ld (hl), e + inc l ; Store BGM start address (high) + ld (hl), d + + PollPCM + + ld hl, ProcessBGM ; Tell Echo to process BGM + ld (DoTick_BGM+1), hl + + PollPCM + jp IdleLoop ; End of subroutine + +;**************************************************************************** +; ProcessBGM +; Processes a tick for a BGM +;**************************************************************************** + +ProcessBGM: + PollPCM + + ld hl, RAM_BGMData+1 ; BGM data address + + ld a, (hl) ; Delaying? + dec a + jp z, .nodelay + ld (hl), a + + jp DoTick_BGMSkip ; End of subroutine + +.nodelay: + PollPCM + + inc l + ld c, (hl) ; Get current address + inc l + ld e, (hl) + inc l + ld d, (hl) + ex de, hl + +ProcessBGMRun: + PollPCM ; Fetch next event + call GetParam + PollPCM + + ld a, b ; Parse byte + + cp $08 + jp c, NoteOnFMBGM ; Events $00-$07: note on FM + cp $0B + jp c, NoteOnPSGBGM ; Events $08-$0A: note on PSG (square) + jp z, NoteOnNoiseBGM ; Event $0B: note on PSG (noise) + cp $0C + jp z, PlayPCMBGM ; Event $0C: play PCM + + PollPCM + ld a, b + + cp $18 + jp c, NoteOffFMBGM ; Events $10-$17: note off FM + cp $1C + jp c, NoteOffPSGBGM ; Events $18-$1B: note off PSG + jp z, StopPCMBGM ; Event $1C: note off PCM + + PollPCM + ld a, b + + cp $FE + jp z, SetDelayBGM ; Event $FE: set delay + cp $FF + jp z, StopBGMEvent ; Event $FF: stop BGM + cp $FC + jp z, LoopBGM ; Event $FC: loop BGM + cp $FD + jp z, SetLoopBGM ; Event $FD: set loop point + + PollPCM + ld a, b + + cp $28 + jp c, SetFMVolBGM ; Events $28-$2B: set FM volume + cp $2C + jp c, SetPSGVolBGM ; Events $28-$2B: set PSG volume + + PollPCM + ld a, b + + cp $38 + jp c, SetNoteFMBGM ; Events $30-$37: set FM note + cp $3B + jp c, SetNotePSGBGM ; Events $38-$3A: set PSG note (square) + jp z, SetNoteNoiseBGM ; Event $3B: set PSG note (noise) + + PollPCM + ld a, b + + cp $48 + jp c, LoadFMBGM ; Events $40-$47: load FM instrument + cp $4C + jp c, LoadPSGBGM ; Events $48-$4B: load PSG instrument + + PollPCM + ld a, b + + cp $F8 ; Events $F0-$F7: set FM parameters + jp c, SetFMParamBGM + + PollPCM ; FFFFFFFFF bad event >:( + jp StopBGMEvent ; End of subroutine + +ProcessBGMSkip2: ; This is where we land after a locked event + PollPCM ; that had two bytes for the parameter + inc l ; Skip first byte + jp nz, .nobankskip2 + inc h + jp nz, .nobankskip2 + ld h, $80 + inc c +.nobankskip2: + +ProcessBGMSkip1: ; This is where we land after a locked event + PollPCM ; that had one byte for the parameter + inc l ; Skip byte + jp nz, .nobankskip1 + inc h + jp nz, .nobankskip1 + ld h, $80 + inc c +.nobankskip1: + +ProcessBGMSkip: ; This is where we land after a locked event + PollPCM ; without parameters + + jp ProcessBGMRun ; Keep processing + +;**************************************************************************** +; StopBGM* [command $05, event $FF] +; Stops BGM playback +;**************************************************************************** + +StopBGMEvent: + call StopBGM ; We're just a wrapper + jp DoTick_BGMSkip ; End of subroutine + +StopBGMCmd: + xor a ; Command parsed + ld (RAM_Command), a + call StopBGM ; We're just a wrapper + jp IdleLoop ; End of subroutine + +StopBGM: + ld a, (RAM_Status) ; Hide BGM playback in Echo's status + and $FD + ld (RAM_Status), a + + PollPCM + + call ClearBGM ; Clear BGM resources + PollPCM + + xor a ; Stop playback + ld (RAM_BGMPlaying), a + ld hl, DoTick_BGMSkip + ld (DoTick_BGM+1), hl + + ret ; End of subroutine + +;**************************************************************************** +; ClearBGM +; Clears BGM resources +;**************************************************************************** + +ClearBGM: + ld a, (RAM_Locked+6) ; Stop PCM playback if needed + or a + call z, StopPCM + + ld b, 4 ; Mute all non-locked PSG channels + ld de, RAM_PSGData+48 + ld hl, RAM_Locked+11 +.mutepsg: + PollPCM + ld a, (hl) + or a + jr nz, .nopsgmute + xor a + ld (de), a +.nopsgmute: + PollPCM + ld a, e + sub 16 + ld e, a + dec l + djnz .mutepsg + + ld b, 8 ; Mute all non-locked FM channels +.mutefm: + PollPCM + ld a, (hl) + or a + jr nz, .nofmmute + PollPCM + dec b + ld (ix+0), $28 + ld (ix+1), b + inc b +.nofmmute: + dec l + djnz .mutefm + + ret ; End of subroutine + +;**************************************************************************** +; LoopBGM [event $FC] +; Makes a BGM loop +;**************************************************************************** + +LoopBGM: + PollPCM + + ex de, hl ; Get looping address + inc l + ld c, (hl) + inc l + ld e, (hl) + inc l + ld d, (hl) + dec l + dec l + dec l + ex de, hl + + jp ProcessBGMRun ; End of subroutine + +;**************************************************************************** +; SetLoopBGM [event $FD] +; Sets the BGM loop point +;**************************************************************************** + +SetLoopBGM: + PollPCM + + ex de, hl + inc l ; Store loop point address + ld (hl), c + inc l + ld (hl), e + inc l + ld (hl), d + dec l + dec l + dec l + ex de, hl + + jp ProcessBGMRun ; End of subroutine |
