diff options
Diffstat (limited to 'src-68k')
| -rw-r--r-- | src-68k/echo.68k | 165 | ||||
| -rw-r--r-- | src-68k/esf.68k | 43 |
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. ;---------------------------------------------------------------------------- |
