From 3aacf3d2cedfdeca49ceb57533389870bfc688a9 Mon Sep 17 00:00:00 2001 From: sik Date: Sun, 23 Jul 2017 03:20:35 -0300 Subject: Now with pausing and other niceties --- src-z80/player/fm.z80 | 30 ++++-- src-z80/player/misc.z80 | 55 ++++++++++ src-z80/player/pcm (copia).z80 | 236 +++++++++++++++++++++++++++++++++++++++++ src-z80/player/pcm.z80 | 197 +++++++++++++++++----------------- src-z80/player/psg.z80 | 6 +- 5 files changed, 419 insertions(+), 105 deletions(-) create mode 100644 src-z80/player/pcm (copia).z80 (limited to 'src-z80/player') diff --git a/src-z80/player/fm.z80 b/src-z80/player/fm.z80 index 505e849..d5d49ba 100644 --- a/src-z80/player/fm.z80 +++ b/src-z80/player/fm.z80 @@ -432,7 +432,13 @@ LoadFMDirect: ;**************************************************************************** SetFMVolSFX: - call SetFMVolSFXEvent ; We're just a wrapper + push af + PollPCM + call GetParam ; Get new volume + PollPCM + pop af + + call SetFMVolLoad ; We're just a wrapper jp ProcessSFXRun ; End of subroutine SetFMVolBGM: @@ -487,12 +493,21 @@ SetFMVolBGM: call SetFMVolLoad ; We're just a wrapper jp ProcessBGMRun ; End of subroutine -SetFMVolSFXEvent: - push af - PollPCM - call GetParam ; Get new volume - PollPCM - pop af +;---------------------------------------------------------------------------- +; input a = channel ID +; input b = new volume level +;---------------------------------------------------------------------------- + +SetFMVolTempLoad: + push bc + push de + push hl + jp SetFMVolDoIt + +;---------------------------------------------------------------------------- +; input a = channel ID (bottom 3 bits) +; input b = new volume level +;---------------------------------------------------------------------------- SetFMVolLoad: push bc @@ -508,6 +523,7 @@ SetFMVolLoad: ld (hl), b pop af +SetFMVolDoIt: push af ld h, RAM_FMData>>8 ; Get address of FM data add RAM_FMData&$FF diff --git a/src-z80/player/misc.z80 b/src-z80/player/misc.z80 index dee980e..56e11b4 100644 --- a/src-z80/player/misc.z80 +++ b/src-z80/player/misc.z80 @@ -1,6 +1,8 @@ ;**************************************************************************** ; SetDelay* [event $FE, events $D0-$DF] ; Adds a delay in playback +;---------------------------------------------------------------------------- +; breaks: c, de, hl ;**************************************************************************** SetDelaySFX: @@ -45,6 +47,58 @@ SetDelayShort: ret ; End of subroutine +;**************************************************************************** +; SetFlags [event $FA] +; Sets some of the flags. +;---------------------------------------------------------------------------- +; breaks: c, de, hl +;**************************************************************************** + +SetFlagsSFX: + call SetFlags + jp ProcessSFXRun + +SetFlagsBGM: + call SetFlags + jp ProcessBGMRun + +SetFlags: + PollPCM ; Get which flags to set + call GetParam + PollPCM + + ld a, (RAM_Flags) ; Set the flags + or b + ld (RAM_Flags), a + + ret ; End of subroutine + +;**************************************************************************** +; ClearFlags [event $FB] +; Clears some of the flags. +;---------------------------------------------------------------------------- +; breaks: c, de, hl +;**************************************************************************** + +ClearFlagsSFX: + call ClearFlags + jp ProcessSFXRun + +ClearFlagsBGM: + call ClearFlags + jp ProcessBGMRun + +ClearFlags: + PollPCM ; Get which flags to clear + call GetParam + PollPCM + + ld a, (RAM_Flags) ; Clear the flags + and b + ld (RAM_Flags), a + + ret ; End of subroutine + ;**************************************************************************** ; RefreshVolume ; Reloads the volume for all channels. @@ -69,6 +123,7 @@ RefreshVolume: inc l inc e dec c + PollPCM jr nz, .fixfmvol ld hl, $1FE8 ; Update PSG volume diff --git a/src-z80/player/pcm (copia).z80 b/src-z80/player/pcm (copia).z80 new file mode 100644 index 0000000..ae7b34a --- /dev/null +++ b/src-z80/player/pcm (copia).z80 @@ -0,0 +1,236 @@ +;**************************************************************************** +; UpdatePCM +; Updates PCM output upon a timer event +;**************************************************************************** + +UpdatePCM: + ret ; $C9 = RET = no PCM playback + ; $D0 = RET NC = PCM playback + + exx ; Switch to PCM registers + +.doagain: + ld (ix+0), $27 ; Acknowledge timer + ld (ix+1), $1F + + ld a, (hl) ; Fetch next sample + inc a ; Check if it's the end of the waveform + jr z, .stop + ld (ix+0), $2A ; Nope, send sample to YM2612 + ld (ix+1), a + + inc l ; Update buffer position + jr z, .reload ; Need to buffer more? + +.nopcm: + exx ; Switch to normal registers + ret ; End of subroutine + +.stop: + ld a, $C9 ; Stop playback + ld (UpdatePCM), a + ld (ix+0), $2A ; Turn off DAC + ld (ix+1), $80 + ld (ix+0), $2B + ld (ix+1), $00 + exx ; Switch to normal registers + ret ; End of subroutine + +.reload: + ld a, (RAM_LastBank) ; Bank switch if needed + cp c + jp z, .noswitchu + ld a, c + ld (RAM_LastBank), a + ld hl, $6000 + BankSwitch +.noswitchu: + + ld hl, RAM_PCMBuffer ; Load samples into the buffer + ld a, c + ex de, hl + + ldi + ldi + ldi + ldi + + ldi + ldi + ldi + ldi + + ldi + ldi + ldi + ldi + + ldi + ldi + ldi + ldi + + ex de, hl + ld c, a + + ld a, e + or a + jp nz, .nobankchg ; Update high bytes of address if needed + inc d + jp nz, .nobankchg + ld d, $80 + inc c +.nobankchg: + + ld l, RAM_PCMBuffer&$FF ; Go back to the beginning of the buffer + jp .doagain ; We took so long we should play the next + ; sample already ._.' + +;**************************************************************************** +; PlayPCM* [event $0C] +; Plays a PCM sample +;---------------------------------------------------------------------------- +; input c .... current bank +; input hl ... current address +;---------------------------------------------------------------------------- +; breaks: af, b +;**************************************************************************** + +PlayPCMSFX: + call PlayPCM ; We're just a wrapper + jp ProcessSFXRun ; End of subroutine + +PlayPCMBGM: + PollPCM + + ld a, (RAM_Locked+6) ; Check if channel is free + or a + jp nz, ProcessBGMSkip1 ; Don't play sample if locked + + call PlayPCM ; We're just a wrapper + 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 + exx ; We'll modify PCM data now + + ld h, RAM_PointerList>>8 ; Get offset in pointer list + ld l, a + + ld d, (hl) ; Get PCM address + inc h + ld e, (hl) + inc h + ld c, (hl) + + ld hl, $6000 ; Initial bank switch + ld a, c + ld (RAM_LastBank), a + BankSwitch + + ld h, RAM_PCMBuffer>>8 ; Set buffer where the sample starts + ld a, e + or $F0 + ld l, a + + ld b, l +.load1st: ; Copy initial samples into the buffer + ld a, (de) + ld (hl), a + inc e + inc l + jp nz, .load1st + ld l, b + + ld a, e ; Check if the sample should skip ahead + or a ; already + jp nz, .noskip1st + inc d + jp nz, .noskip1st + ld d, $80 + inc c +.noskip1st: + + exx ; Back to standard registers + ld a, $D0 ; Enable PCM playback + ld (UpdatePCM), a + + ld (ix+0), $2B ; Turn on DAC + ld (ix+1), $80 + ld (ix+0), $2A + ld (ix+1), $80 + + ret ; End of subroutine + +;**************************************************************************** +; StopPCM* +; Stops a PCM sample +;**************************************************************************** + +StopPCMSFX: + call StopPCM ; We're just a wrapper + jp ProcessSFXRun ; End of subroutine + +StopPCMBGM: + PollPCM + + ld a, (RAM_Locked+6) ; Check if channel is free + or a + jp nz, ProcessBGMRun ; Don't stop sample if locked + + call StopPCM ; We're just a wrapper + jp ProcessBGMRun ; End of subroutine + +StopPCM: + ld a, $C9 ; Stop PCM playback + ld (UpdatePCM), a + + ld (ix+0), $2B ; Disable DAC + ld (ix+1), $00 + + ret ; End of subroutine + +;**************************************************************************** +; LockChannelPCM [event $EC] +; Locks the PCM channel +;**************************************************************************** + +LockChannelPCM: + ld a, $01 ; Lock PCM channel + ld (RAM_Locked+6), a + + call StopPCM ; Stop PCM playback + jp ProcessSFXRun ; End of subroutine + +;**************************************************************************** +; SetPCMRate [command $07] +; Changes the sample rate of PCM +;**************************************************************************** + +SetPCMRate: + ld a, (RAM_ComBank) ; Get new rate + cpl + ld b, a + + xor a ; Parsed command already + ld (RAM_Command), a + + ld a, b ; Set high bits of timer + ld (ix+0), $24 + rrca + rrca + or $C0 + ld (ix+1), a + + ld a, b ; Set low bits of timer + ld (ix+0), $25 + and $03 + ld (ix+1), a + + jp IdleLoop ; End of subroutine diff --git a/src-z80/player/pcm.z80 b/src-z80/player/pcm.z80 index 99feb6d..2b7bcc4 100644 --- a/src-z80/player/pcm.z80 +++ b/src-z80/player/pcm.z80 @@ -1,100 +1,21 @@ -;**************************************************************************** -; PlayPCM* [event $0C] -; Plays a PCM sample -;---------------------------------------------------------------------------- -; input c .... current bank -; input hl ... current address -;---------------------------------------------------------------------------- -; breaks: af, b -;**************************************************************************** - -PlayPCMSFX: - call PlayPCM ; We're just a wrapper - jp ProcessSFXRun ; End of subroutine - -PlayPCMBGM: - PollPCM - - ld a, (RAM_Locked+6) ; Check if channel is free - or a - jp nz, ProcessBGMSkip1 ; Don't play sample if locked - - call PlayPCM ; We're just a wrapper - 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 - exx ; We'll modify PCM data now - - ld h, RAM_PointerList>>8 ; Get offset in pointer list - ld l, a - - ld d, (hl) ; Get PCM address - inc h - ld e, (hl) - inc h - ld c, (hl) - - ld hl, $6000 ; Initial bank switch - ld a, c - ld (RAM_LastBank), a - BankSwitch - - ld h, RAM_PCMBuffer>>8 ; Set buffer where the sample starts - ld a, e - or $F0 - ld l, a - - ld b, l -.load1st: ; Copy initial samples into the buffer - ld a, (de) - ld (hl), a - inc e - inc l - jp nz, .load1st - ld l, b - - ld a, e ; Check if the sample should skip ahead - or a ; already - jp nz, .noskip1st - inc d - jp nz, .noskip1st - ld d, $80 - inc c -.noskip1st: - - ;ld b, $01 ; Play PCM! - exx ; Back to standard registers - xor a ; Enable PCM playback - ld (UpdatePCM), a - - ld (ix+0), $2B ; Turn on DAC - ld (ix+1), $80 - ld (ix+0), $2A - ld (ix+1), $80 - - ret ; End of subroutine - ;**************************************************************************** ; UpdatePCM ; Updates PCM output upon a timer event ;**************************************************************************** UpdatePCM: - ret ; RET = no PCM playback - ; NOP = PCM playback + ret ; $C9 = RET = no PCM playback + ; $D0 = RET NC = PCM playback exx ; Switch to PCM registers .doagain: ld (ix+0), $27 ; Acknowledge timer ld (ix+1), $1F + ;push hl + ;ld hl, $1F27 + ;ld ($4000), hl + ;pop hl ld a, (hl) ; Fetch next sample inc a ; Check if it's the end of the waveform @@ -110,7 +31,9 @@ UpdatePCM: ret ; End of subroutine .stop: - ld b, $00 ; Stop playback +; ld b, $00 ; Stop playback + ld a, $C9 ; Stop playback + ld (UpdatePCM), a ld (ix+0), $2A ; Turn off DAC ld (ix+1), $80 ld (ix+0), $2B @@ -209,6 +132,88 @@ UpdatePCM: jp .doagain ; We took so long we should play the next ; sample already ._.' +;**************************************************************************** +; PlayPCM* [event $0C] +; Plays a PCM sample +;---------------------------------------------------------------------------- +; input c .... current bank +; input hl ... current address +;---------------------------------------------------------------------------- +; breaks: af, b +;**************************************************************************** + +PlayPCMSFX: + call PlayPCM ; We're just a wrapper + jp ProcessSFXRun ; End of subroutine + +PlayPCMBGM: + PollPCM + + ld a, (RAM_Locked+6) ; Check if channel is free + or a + jp nz, ProcessBGMSkip1 ; Don't play sample if locked + + call PlayPCM ; We're just a wrapper + 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 + exx ; We'll modify PCM data now + + ld h, RAM_PointerList>>8 ; Get offset in pointer list + ld l, a + + ld d, (hl) ; Get PCM address + inc h + ld e, (hl) + inc h + ld c, (hl) + + ld hl, $6000 ; Initial bank switch + ld a, c + ld (RAM_LastBank), a + BankSwitch + + ld h, RAM_PCMBuffer>>8 ; Set buffer where the sample starts + ld a, e + or $F0 + ld l, a + + ld b, l +.load1st: ; Copy initial samples into the buffer + ld a, (de) + ld (hl), a + inc e + inc l + jp nz, .load1st + ld l, b + + ld a, e ; Check if the sample should skip ahead + or a ; already + jp nz, .noskip1st + inc d + jp nz, .noskip1st + ld d, $80 + inc c +.noskip1st: + + exx ; Back to standard registers + ld a, $D0 ; Enable PCM playback + ld (UpdatePCM), a + + ld (ix+0), $2B ; Turn on DAC + ld (ix+1), $80 + ld (ix+0), $2A + ld (ix+1), $80 + + ret ; End of subroutine + ;**************************************************************************** ; StopPCM* ; Stops a PCM sample @@ -257,21 +262,21 @@ LockChannelPCM: SetPCMRate: ld a, (RAM_ComBank) ; Get new rate cpl - ld b, a - xor a ; Parsed command already - ld (RAM_Command), a - - ld a, b ; Set high bits of timer - ld (ix+0), $24 + ld b, a ; Set high bits of timer + ld hl, $4000 + ld (hl), $24 rrca rrca or $C0 - ld (ix+1), a + inc l + ld (hl), a ld a, b ; Set low bits of timer - ld (ix+0), $25 + dec l + ld (hl), $25 and $03 - ld (ix+1), a + inc l + ld (hl), a - jp IdleLoop ; End of subroutine + jp EndOfCommand ; End of subroutine diff --git a/src-z80/player/psg.z80 b/src-z80/player/psg.z80 index b88978c..6ddaae7 100644 --- a/src-z80/player/psg.z80 +++ b/src-z80/player/psg.z80 @@ -10,8 +10,10 @@ UpdatePSG: push bc ld a, (hl) ; Get channel volume - bit 7, a - jr nz, .noskip +; bit 7, a +; jr nz, .noskip + or a + jp m, .noskip ld b, $0F inc l jp .skip -- cgit v1.2.3