aboutsummaryrefslogtreecommitdiff
path: root/src-68k
diff options
context:
space:
mode:
Diffstat (limited to 'src-68k')
-rw-r--r--src-68k/echo.68k165
-rw-r--r--src-68k/esf.68k43
2 files changed, 203 insertions, 5 deletions
diff --git a/src-68k/echo.68k b/src-68k/echo.68k
index 9304247..f10695a 100644
--- a/src-68k/echo.68k
+++ b/src-68k/echo.68k
@@ -192,11 +192,40 @@ Echo_StopBGM:
; Resumes BGM playback
;****************************************************************************
-Echo_ResumeBGM:
- move.w d0, -(sp) ; Save register
- move.b #$06, d0 ; Command $06 = resume BGM
- bsr Echo_SendCommand ; Send command to Echo
- move.w (sp)+, d0 ; Restore register
+;Echo_ResumeBGM:
+; move.w d0, -(sp) ; Save register
+; move.b #$06, d0 ; Command $06 = resume BGM
+; bsr Echo_SendCommand ; Send command to Echo
+; move.w (sp)+, d0 ; Restore register
+; rts ; End of subroutine
+
+;****************************************************************************
+; Echo_PlayDirect
+; Injects events into the BGM stream for the next tick.
+;
+; input a0.l ... Pointer to stream data
+;****************************************************************************
+
+Echo_PlayDirect:
+ Echo_Z80Request ; We need the Z80 bus
+ movem.l d0-d1/a0-a1, -(sp) ; Save registers
+
+ lea ($A01F00), a1 ; Skip any pending events
+ moveq #-1, d1
+@Skip:
+ cmp.b (a1), d1
+ beq.s @Load
+ addq.w #1, a1
+ bra.s @Skip
+
+@Load: ; Copy stream into the direct buffer
+ move.b (a0)+, d0
+ move.b d0, (a1)+
+ cmp.b d1, d0
+ bne.s @Load
+
+ movem.l (sp)+, d0-d1/a0-a1 ; Restore registers
+ Echo_Z80Release ; We're done with the Z80 bus
rts ; End of subroutine
;****************************************************************************
@@ -215,12 +244,112 @@ Echo_SetPCMRate:
rts ; End of subroutine
;****************************************************************************
+; Echo_SetVolume
+; Changes the global volume for every channel.
+;
+; input d0.b ... New volume (0 = quietest, 255 = loudest)
+;****************************************************************************
+
+Echo_SetVolume:
+ Echo_Z80Request ; We need the Z80 bus
+ movem.l d0-d1/a0-a1, -(sp) ; Save registers
+
+ lea @FMTable(pc), a0 ; Determine FM volume
+ moveq #0, d1
+ move.b d0, d1
+ lsr.b #2, d1
+ move.b (a0,d1.w), d1
+
+ lea ($A01FE0), a1 ; Copy new FM volume values
+ move.b d1, (a1)+ ; FM channel 0
+ move.b d1, (a1)+ ; FM channel 1
+ move.b d1, (a1)+ ; FM channel 2
+ move.b d1, (a1)+ ; FM channel 3
+ move.b d1, (a1)+ ; FM channel 4
+ move.b d1, (a1)+ ; FM channel 5
+ move.b d1, (a1)+ ; FM channel 6
+ move.b d1, (a1)+ ; FM channel 7
+
+ lea @PSGTable(pc), a0 ; Determine PSG volume
+ moveq #0, d1
+ move.b d0, d1
+ lsr.b #2, d1
+ move.b (a0,d1.w), d1
+
+ ; Copy new PSG values
+ move.b d1, (a1)+ ; PSG channel 0
+ move.b d1, (a1)+ ; PSG channel 1
+ move.b d1, (a1)+ ; PSG channel 2
+ move.b d1, (a1)+ ; PSG channel 3
+
+ cmp.b #$40, d0 ; Determine whether PCM should be enabled
+ shs d1 ; (we do an heuristic for enabling PCM
+ and.b #1, d1 ; based on the volume value)
+ move.b d1, (a1)+
+
+ move.b #1, ($A01FF1) ; Tell Echo to update the volume levels
+
+ movem.l (sp)+, d0-d1/a0-a1 ; Restore registers
+ Echo_Z80Release ; We're done with the Z80 bus
+ rts ; End of subroutine
+
+;----------------------------------------------------------------------------
+
+@FMTable:
+ dc.b $7F,$7B,$77,$73,$70,$6C,$68,$65,$61,$5E,$5A,$57,$54,$50,$4D,$4A
+ dc.b $47,$44,$41,$3F,$3C,$39,$36,$34,$31,$2F,$2D,$2A,$28,$26,$24,$22
+ dc.b $20,$1E,$1C,$1A,$18,$16,$15,$13,$12,$10,$0F,$0D,$0C,$0B,$0A,$09
+ dc.b $08,$07,$06,$05,$04,$04,$03,$02,$02,$01,$01,$01,$00,$00,$00,$00
+
+@PSGTable:
+ dc.b $0F,$0F,$0E,$0E,$0D,$0D,$0C,$0C,$0B,$0B,$0B,$0A,$0A,$0A,$09,$09
+ dc.b $08,$08,$08,$07,$07,$07,$06,$06,$06,$06,$05,$05,$05,$04,$04,$04
+ dc.b $04,$03,$03,$03,$03,$03,$02,$02,$02,$02,$02,$02,$01,$01,$01,$01
+ dc.b $01,$01,$01,$01,$01,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+
+;****************************************************************************
+; Echo_SetVolumeEx
+; Changes the global volume for each individual channel.
+;
+; input a0.l ... Pointer to 13 bytes
+; 8 bytes with FM volumes (0..127)
+; 4 bytes with PSG volumes (0..15)
+; 1 byte with PCM toggle (0/1)
+;****************************************************************************
+
+Echo_SetVolumeEx:
+ Echo_Z80Request ; We need the Z80 bus
+ movem.l a0-a1, -(sp) ; Save registers
+
+ lea ($A01FE0), a1 ; Copy new volume values
+ move.b (a0)+, (a1)+ ; FM channel 0
+ move.b (a0)+, (a1)+ ; FM channel 1
+ move.b (a0)+, (a1)+ ; FM channel 2
+ move.b (a0)+, (a1)+ ; FM channel 3
+ move.b (a0)+, (a1)+ ; FM channel 4
+ move.b (a0)+, (a1)+ ; FM channel 5
+ move.b (a0)+, (a1)+ ; FM channel 6
+ move.b (a0)+, (a1)+ ; FM channel 7
+ move.b (a0)+, (a1)+ ; PSG channel 0
+ move.b (a0)+, (a1)+ ; PSG channel 1
+ move.b (a0)+, (a1)+ ; PSG channel 2
+ move.b (a0)+, (a1)+ ; PSG channel 3
+ move.b (a0)+, (a1)+ ; PCM channel toggle
+
+ move.b #1, ($A01FF1) ; Tell Echo to update the volume levels
+
+ movem.l (sp)+, a0-a1 ; Restore registers
+ Echo_Z80Release ; We're done with the Z80 bus
+ rts ; End of subroutine
+
+;****************************************************************************
; Echo_GetStatus
; Gets the current status of Echo
;
; output d0.w ... Echo status
; Bit #0: SFX is playing
; Bit #1: BGM is playing
+; Bit #14: direct events not played
; Bit #15: command still not parsed
;****************************************************************************
@@ -228,10 +357,17 @@ Echo_GetStatus:
moveq #0, d0
Echo_Z80Request ; We need the Z80 bus
move.b ($A01FF0), d0 ; Get the status flags
+
tst.b ($A01FFF) ; Check if command still has to be parsed
beq.s @NotBusy ; Any commands left to be parsed?
bset.l #15, d0 ; If so, set the relevant flag
@NotBusy:
+
+ cmpi.b #$FF, ($A01F00) ; Check if the direct buffer is empty
+ beq.s @DirectEmpty ; Any direct events still to be played?
+ bset.l #14, d0 ; If so, set the relevant flag
+@DirectEmpty:
+
Echo_Z80Release ; Let the Z80 go!
rts ; End of subroutine
@@ -292,6 +428,25 @@ Echo_Init:
move.b (a0)+, (a1)+ ; Copy byte into Z80 RAM
dbf d0, @LoadLoop ; Go for next byte
+ moveq #0, d0 ; Set default global volumes
+ lea ($A01FE0), a0
+ move.b d0, (a0)+
+ move.b d0, (a0)+
+ move.b d0, (a0)+
+ move.b d0, (a0)+
+ move.b d0, (a0)+
+ move.b d0, (a0)+
+ move.b d0, (a0)+
+ move.b d0, (a0)+
+ move.b d0, (a0)+
+ move.b d0, (a0)+
+ move.b d0, (a0)+
+ move.b d0, (a0)+
+ move.b #1, (a0)+
+ move.b d0, ($A01FF1)
+
+ move.b #$FF, ($A01F00) ; No direct events to execute
+
Echo_Z80Reset ; Now reset for real
Echo_Z80Release ; Let the Z80 go!
diff --git a/src-68k/esf.68k b/src-68k/esf.68k
index fdaa55e..fc8dacc 100644
--- a/src-68k/esf.68k
+++ b/src-68k/esf.68k
@@ -45,6 +45,15 @@ ESF_FMFREQ_10 equ ESF_FMFREQ_AS
ESF_FMFREQ_11 equ ESF_FMFREQ_B
;****************************************************************************
+; Panning values
+;****************************************************************************
+
+ESF_PAN_OFF: equ $00 ; Mute
+ESF_PAN_L: equ $80 ; Left speaker only
+ESF_PAN_R: equ $40 ; Right speaker only
+ESF_PAN_LR: equ $C0 ; Both speakers
+
+;****************************************************************************
; ESF_NoteOn
; Start playing a note.
;----------------------------------------------------------------------------
@@ -166,6 +175,40 @@ ESF_Lock macro
endm
;****************************************************************************
+; ESF_SetPan
+; Set the panning of a FM channel.
+;----------------------------------------------------------------------------
+; Format:
+; ESF_SetPan channel, panning
+;----------------------------------------------------------------------------
+; param channel ... channel to modify
+; param panning ... panning (see ESF_PAN_*)
+;****************************************************************************
+
+ESF_SetPan macro
+ dc.b $F0+(\1)
+ dc.b (\2)
+ endm
+
+;****************************************************************************
+; ESF_SetFMReg
+; Set a FM register directly.
+;----------------------------------------------------------------------------
+; Format:
+; ESF_SetFMReg bank, register, value
+;----------------------------------------------------------------------------
+; param bank ....... YM2612 bank (0 or 1)
+; param register ... register to modify
+; param value ...... value to write
+;****************************************************************************
+
+ESF_SetFMReg macro
+ dc.b $F8+(\1)
+ dc.b (\2)
+ dc.b (\3)
+ endm
+
+;****************************************************************************
; ESF_Delay
; Stop event.
;----------------------------------------------------------------------------