aboutsummaryrefslogtreecommitdiff
path: root/src-z80/player/pcm (copia).z80
diff options
context:
space:
mode:
authorsik2018-01-22 19:19:19 -0300
committersik2018-01-22 19:19:19 -0300
commit8fdf49b8e53fd3063ccc2eb51c49c3b6e4d073bb (patch)
treeaddb91518f99d4df76986d3e282e41cd6baf077e /src-z80/player/pcm (copia).z80
parenta2f67fbe8fe6b27f661e70ce2b6b75c17cd1fe54 (diff)
Echo 1.6 release... kind of a mess, will clean up in further commits I guess
Diffstat (limited to 'src-z80/player/pcm (copia).z80')
-rw-r--r--src-z80/player/pcm (copia).z80236
1 files changed, 236 insertions, 0 deletions
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