aboutsummaryrefslogtreecommitdiff
path: root/src-z80/core
diff options
context:
space:
mode:
authorsik2017-07-23 03:20:35 -0300
committersik2017-07-23 03:20:35 -0300
commit3aacf3d2cedfdeca49ceb57533389870bfc688a9 (patch)
treea46d166fa9270700e8e159ca9ae455ac24472771 /src-z80/core
parenta679ba38190bfed6ae150a12e819ad7527c495d1 (diff)
Now with pausing and other niceties
Diffstat (limited to 'src-z80/core')
-rw-r--r--src-z80/core/bgm.z80185
-rw-r--r--src-z80/core/macro.z8041
-rw-r--r--src-z80/core/main.z80113
-rw-r--r--src-z80/core/sfx.z8048
-rw-r--r--src-z80/core/vars.z8018
5 files changed, 260 insertions, 145 deletions
diff --git a/src-z80/core/bgm.z80 b/src-z80/core/bgm.z80
index 338a7a6..b48d87a 100644
--- a/src-z80/core/bgm.z80
+++ b/src-z80/core/bgm.z80
@@ -25,13 +25,14 @@ PlayBGM:
PollPCM
- xor a ; Command parsed
- ld (RAM_Command), a
+ xor a ; Playing a BGM immediately unpauses playback
+ ld (RAM_Paused), a
+ inc a
ld hl, RAM_BGMData ; Set BGM as playing
- ld (hl), $01
+ ld (hl), a
inc l ; No delays!
- ld (hl), $01
+ ld (hl), a
inc l ; Store BGM start bank
ld (hl), c
inc l ; Store BGM start address (low)
@@ -44,55 +45,111 @@ PlayBGM:
ld hl, ProcessBGM ; Tell Echo to process BGM
ld (DoTick_BGM+1), hl
- jp IdleLoop ; End of subroutine
+ jp EndOfCommand ; End of subroutine
;****************************************************************************
-; ResumeBGM [command $06]
-; Resumes a stopped BGM
+; PauseBGM [command $08]
+; Pauses a playing BGM
;----------------------------------------------------------------------------
; breaks: all
;****************************************************************************
-ResumeBGM:
- xor a ; Command parsed
- ld (RAM_Command), a
+PauseBGM:
+ ld a, (RAM_BGMPlaying) ; Is BGM even playing?
+ or a
+ jp z, EndOfCommand
+
+ ld a, 1 ; Halt BGM playback
+ ld (RAM_Paused), a
;----------------------------------------------------------------------------
-
- ld b, 8 ; Restore all FM channels
- ld de, RAM_Locked+7
-.restorefm:
+ ld b, $7F ; Mute all FM channels
+ ld c, 7
+ ld hl, RAM_Locked+7
+.mutefm:
PollPCM
-
- ld a, (de) ; Check if this channel is locked
+ ld a, (hl)
or a
- jp nz, .fmlocked
-
+ jr nz, .nofmmute
+ ld a, c
+ call SetFMVolTempLoad
+.nofmmute:
PollPCM
+ dec l
+ dec c
+ jp p, .mutefm
- dec b ; Restore FM channel
- call RestoreFM
- inc b
-
-.fmlocked:
- dec e ; Go for next channel to restore
- dec b
- jp nz, .restorefm
+ ld b, 4 ; Mute all PSG channels
+ ld c, $0F
+ ld de, RAM_Locked+8
+ ld hl, RAM_PSGData
+.mutepsg:
+ PollPCM
+ ld a, (de)
+ or a
+ jr nz, .nopsgmute
+ ld a, (hl)
+ and $80
+ or c,
+ ld (hl), a
+.nopsgmute:
+ PollPCM
+ ld a, l
+ add 16
+ ld l, a
+ inc e
+ djnz .mutepsg
;----------------------------------------------------------------------------
- ld a, (RAM_Status) ; Show BGM playback in Echo's status
- or $02
- ld (RAM_Status), a
+ ld a, (RAM_Locked+6) ; Mute PCM channel
+ or a
+ call z, StopPCM
- ld hl, RAM_BGMData ; Set BGM as playing
- ld (hl), $01
+;----------------------------------------------------------------------------
+
+ jp EndOfCommand ; End of subroutine
+
+;****************************************************************************
+; ResumeBGM [command $06]
+; Resumes a stopped BGM
+;----------------------------------------------------------------------------
+; breaks: all
+;****************************************************************************
+
+ResumeBGM:
+ ld a, (RAM_BGMPlaying) ; Was BGM even playing?
+ or a
+ jp z, EndOfCommand
- ld hl, ProcessBGM ; Tell Echo to process BGM
- ld (DoTick_BGM+1), hl
+ xor a
+ ld (RAM_Paused), a ; Resume BGM playback
- jp IdleLoop ; End of subroutine
+ ld b, 4 ; Restore PSG channels
+ ld de, RAM_Locked+11
+ ld hl, RAM_PSGData+63
+.resumepsg:
+ PollPCM
+ ld c, (hl)
+ ld a, l
+ sub 15
+ ld l, a
+ ld a, (de)
+ or a
+ jr nz, .nopsgresume
+ ld a, (hl)
+ and $80
+ or c
+ ld (hl), a
+.nopsgresume:
+ PollPCM
+ dec l
+ dec e
+ djnz .resumepsg
+
+ call RefreshVolume ; Restore remaining channels
+ jp EndOfCommand ; End of subroutine
;****************************************************************************
; ProcessBGM
@@ -197,6 +254,9 @@ ProcessBGMEventFF:
jp c, SetFMParamBGM
cp $FA ; Events $F8-$F9: set FM register
jp c, SetFMRegBGM
+ jp z, SetFlagsBGM ; Events $FA-$FB: set/clear flags
+ cp $FB
+ jp z, ClearFlagsBGM
PollPCM ; FFFFFFFFF bad event >:(
ProcessBGMEnd:
@@ -234,10 +294,8 @@ StopBGMEvent:
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
+ jp EndOfCommand ; End of subroutine
StopBGM:
ld a, (RAM_Status) ; Hide BGM playback in Echo's status
@@ -271,7 +329,7 @@ ClearBGM:
ld b, 4 ; Reset all PSG channels
ld de, RAM_PSGData+48+15
ld hl, RAM_Locked+11
-.mutepsg:
+.killpsg:
PollPCM
ld (hl), $00 ; Reset BGM volume
@@ -282,22 +340,22 @@ ClearBGM:
ld a, (hl) ; Mute PSG channel if it isn't locked
or a
- jr nz, .nopsgmute
+ jr nz, .nopsgkill
xor a
ld (de), a
-.nopsgmute:
+.nopsgkill:
PollPCM
dec e
dec l
- djnz .mutepsg
+ djnz .killpsg
;----------------------------------------------------------------------------
ld b, 8 ; Reset all FM channels
ld de, RAM_BGMFMVol+7
-.resetfm:
+.killfm:
PollPCM
ld a, $7F ; Reset BGM volume
@@ -328,10 +386,10 @@ ClearBGM:
inc b
.nofmkill:
dec l
- djnz .resetfm
+ djnz .killfm
;----------------------------------------------------------------------------
-
+
ld hl, RAM_BGMFMPan ; Reset panning status (for restoring)
ld a, $C0
ld b, 8
@@ -339,6 +397,9 @@ ClearBGM:
ld (hl), a
inc l
djnz .initpanstat
+
+ xor a ; Reset flags
+ ld (RAM_Flags), a
ret ; End of subroutine
@@ -349,19 +410,11 @@ ClearBGM:
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
-
+
+ ld hl, (RAM_BGMLoopPoint+1) ; Get looping address
+ ld a, (RAM_BGMLoopPoint)
+ ld c, a
+
jp ProcessBGMRun ; End of subroutine
;****************************************************************************
@@ -371,17 +424,9 @@ LoopBGM:
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
-
+
+ ld a, c ; Store loop point address
+ ld (RAM_BGMLoopPoint), a
+ ld (RAM_BGMLoopPoint+1), hl
+
jp ProcessBGMRun ; End of subroutine
diff --git a/src-z80/core/macro.z80 b/src-z80/core/macro.z80
new file mode 100644
index 0000000..eedd527
--- /dev/null
+++ b/src-z80/core/macro.z80
@@ -0,0 +1,41 @@
+;****************************************************************************
+; PollPCM
+; Used to update PCM while not idle
+;----------------------------------------------------------------------------
+; breaks: af
+;****************************************************************************
+
+PollPCM: macro
+ ld a, ($4000)
+ rrca
+ rst $08
+ endm
+
+;****************************************************************************
+; BankSwitch
+; Switches into a new bank (won't update player status!)
+;----------------------------------------------------------------------------
+; input A .... New bank to switch into
+; input HL ... Must be $60xx
+;----------------------------------------------------------------------------
+; breaks ..... AF
+;****************************************************************************
+
+BankSwitch: macro
+ ld (hl), a
+ rrca
+ ld (hl), a
+ rrca
+ ld (hl), a
+ rrca
+ ld (hl), a
+ rrca
+ ld (hl), a
+ rrca
+ ld (hl), a
+ rrca
+ ld (hl), a
+ ld (hl), h
+ rrca
+ ld (hl), a
+ endm
diff --git a/src-z80/core/main.z80 b/src-z80/core/main.z80
index 4eb6e5a..387b879 100644
--- a/src-z80/core/main.z80
+++ b/src-z80/core/main.z80
@@ -4,10 +4,11 @@
;****************************************************************************
EntryPoint:
- ld sp, RAM_Stack ; Init stack
+ xor a ; Reset Echo status (we don't clear
+ ld (RAM_Status), a ; RAM_Command since Echo_Init fills in values
+ ld (RAM_Command2), a ; before Echo gets to run!)
- xor a ; Reset Echo status
- ld (RAM_Status), a
+ ld sp, RAM_Stack ; Init stack
ld hl, $7F11 ; Mute PSG
ld (hl), $9F
@@ -88,22 +89,11 @@ EntryPoint:
jp IdleLoop ; Go into idle loop
;****************************************************************************
-; PollPCM
-; Used to update PCM while not idle
-;----------------------------------------------------------------------------
-; breaks: af
-;****************************************************************************
-
-PollPCM: macro
- ld a, ($4000)
- rrca
- call c, UpdatePCM
- endm
-
-;****************************************************************************
; RunCommand
; Checks which command to run
;----------------------------------------------------------------------------
+; notes: doesn't return
+;----------------------------------------------------------------------------
; To-do: replace with pointer list?
;****************************************************************************
@@ -122,17 +112,36 @@ RunCommand:
jp z, ResumeBGM
dec a ; Command $07: set PCM rate
jp z, SetPCMRate
+ dec a ; Command $08: pause BGM
+ jp z, PauseBGM
PollPCM
- xor a ; Bad command, ignore >:(
- ld (RAM_Command), a
+ ; Bad command, ignore >:(
+
+;****************************************************************************
+; EndOfCommand
+; Cleans up when a command finishes
+;----------------------------------------------------------------------------
+; notes: doesn't return
+;****************************************************************************
+EndOfCommand:
+ ld hl, ($1FF8) ; Copy second slot into first
+ ld ($1FFC), hl
+ ld hl, ($1FFA)
+ ld ($1FFE), hl
+
+ xor a ; Free up second slot
+ ld (RAM_Command2), a
+
PollPCM
;****************************************************************************
; IdleLoop
; Loop that runs when not processing SFX or BGM
+;----------------------------------------------------------------------------
+; notes: doesn't return (d'oh)
;****************************************************************************
IdleLoop:
@@ -153,13 +162,11 @@ IdleLoop:
;****************************************************************************
; DoTick
; Called whenever a new tick triggers
+;----------------------------------------------------------------------------
+; notes: doesn't return
;****************************************************************************
DoTick:
-; ld a, (ix+0)
-; bit 0, a
-; call nz, UpdatePCM
-
PollPCM
ld (ix+0), $27 ; Retrigger the timer
@@ -181,6 +188,9 @@ DoTick_SFXSkip:
PollPCM
+ ld a, (RAM_Paused) ; BGMs are paused?
+ or a
+ jr nz, DoTick_BGMSkip
DoTick_BGM: ; Process BGMs
jp DoTick_BGMSkip
DoTick_BGMSkip:
@@ -195,57 +205,30 @@ DoTick_PSGSkip:
jp IdleLoop ; End of subroutine
;****************************************************************************
-; BankSwitch
-; Switches into a new bank (won't update player status!)
-;
-; input A .... New bank to switch into
-; input HL ... Must be $6000
-; breaks ..... AF
-;****************************************************************************
-
-BankSwitch: macro
- ld (hl), a
- rrca
- ld (hl), a
- rrca
- ld (hl), a
- rrca
- ld (hl), a
- rrca
- ld (hl), a
- rrca
- ld (hl), a
- rrca
- ld (hl), a
- ld (hl), h
- rrca
- ld (hl), a
- endm
-
-;****************************************************************************
; LoadList [command $01]
; Loads the pointer list
;****************************************************************************
LoadList:
- ld hl, RAM_ComBank ; Get command parameters
- ld c, (hl)
- inc l
- ld e, (hl)
- inc l
- ld d, (hl)
- ex de, hl
-
- xor a ; Command parsed
- ld (RAM_Command), a
+; ld hl, RAM_ComBank ; Get command parameters
+; ld c, (hl)
+; inc l
+; ld e, (hl)
+; inc l
+; ld d, (hl)
+; ex de, hl
+
+ ld hl, (RAM_ComAddr) ; Get command parameters
+ ld a, (RAM_ComBank)
+ ld c, a
ld de, RAM_PointerList ; Where the pointer list starts
-.loop:
+.loadloop:
call GetParam ; Get high byte address
ld a, b ; Is it the end of the list?
or a
- jp z, .end
+ jp z, .loadend
ld (de), a ; Store high byte address
inc d
@@ -261,10 +244,10 @@ LoadList:
dec d ; Go for next byte
dec d
inc e
- jp .loop
+ jp .loadloop
-.end:
- jp IdleLoop ; End of subroutine
+.loadend:
+ jp EndOfCommand ; End of subroutine
;****************************************************************************
; GetParam
diff --git a/src-z80/core/sfx.z80 b/src-z80/core/sfx.z80
index 4bca4c7..8c5e7dd 100644
--- a/src-z80/core/sfx.z80
+++ b/src-z80/core/sfx.z80
@@ -25,9 +25,6 @@ PlaySFX:
PollPCM
- xor a ; Command parsed
- ld (RAM_Command), a
-
ld hl, RAM_SFXData ; Set SFX as playing
ld (hl), $01
inc l ; No delays!
@@ -45,7 +42,7 @@ PlaySFX:
ld (DoTick_SFX+1), hl
PollPCM
- jp IdleLoop ; End of subroutine
+ jp EndOfCommand ; End of subroutine
;****************************************************************************
; ProcessSFX
@@ -153,6 +150,14 @@ ProcessSFXRun:
jp c, SetFMParamSFX
cp $FA ; Events $F8-$F9: set FM register
jp c, SetFMRegSFX
+ jp z, SetFlagsSFX ; Events $FA-$FB: set/clear flags
+ cp $FB
+ jp z, ClearFlagsSFX
+
+ cp $FC
+ jp z, LoopSFX ; Event $FC: loop SFX
+ cp $FD
+ jp z, SetLoopSFX ; Event $FD: set loop point
;****************************************************************************
; StopSFX* [command $03, event $FF]
@@ -166,10 +171,8 @@ StopSFXEvent:
jp DoTick_SFXSkip ; End of subroutine
StopSFXCmd:
- xor a ; Command parsed
- ld (RAM_Command), a
call StopSFX ; We're just a wrapper
- jp IdleLoop ; End of subroutine
+ jp EndOfCommand ; End of subroutine
StopSFX:
PollPCM
@@ -283,9 +286,36 @@ ClearSFX:
.fmfree:
dec e ; Go for next FM channel to unlock
- dec b
- jp nz, .unlockfm
+ djnz .unlockfm
;----------------------------------------------------------------------------
ret ; End of subroutine
+
+;****************************************************************************
+; LoopSFX [event $FC]
+; Makes a SFX loop
+;****************************************************************************
+
+LoopSFX:
+ PollPCM
+
+ ld hl, (RAM_SFXLoopPoint+1) ; Get looping address
+ ld a, (RAM_SFXLoopPoint)
+ ld c, a
+
+ jp ProcessSFXRun ; End of subroutine
+
+;****************************************************************************
+; SetLoopSFX [event $FD]
+; Sets the SFX loop point
+;****************************************************************************
+
+SetLoopSFX:
+ PollPCM
+
+ ld a, c ; Store loop point address
+ ld (RAM_SFXLoopPoint), a
+ ld (RAM_SFXLoopPoint+1), hl
+
+ jp ProcessSFXRun ; End of subroutine
diff --git a/src-z80/core/vars.z80 b/src-z80/core/vars.z80
index cd7162d..79e4a1d 100644
--- a/src-z80/core/vars.z80
+++ b/src-z80/core/vars.z80
@@ -42,13 +42,23 @@ RAM_SFXPlaying: ds 1 ; Set if a SFX is playing
RAM_SFXDelay: ds 1 ; How many ticks to wait
RAM_SFXBank: ds 1 ; Current SFX bank
RAM_SFXAddress: ds 2 ; Current SFX address
+RAM_SFXLoopPoint: ds 3 ; SFX loop point
+
+RAM_Paused: ds 1 ; Set if BGM stream is paused
+
+RAM_PCMBank1: db 1 ; (not implemented yet)
+RAM_PCMAddr1: dw 1 ; (not implemented yet)
+RAM_PCMBank2: db 1 ; (not implemented yet)
+RAM_PCMAddr2: dw 1 ; (not implemented yet)
RAM_Scratch: ds 32 ; Scratch bytes, may be useful when
; buffering to speed up to avoid bank
; switching conflicts
ds $F0-($&$FF), $FF
-RAM_PCMBuffer: ds 16 ; PCM buffer
+RAM_PCMBuffer: ds 0 ; PCM buffer
+RAM_PCMBuffer1: ds 8 ; (not implemented yet)
+RAM_PCMBuffer2: ds 8 ; (not implemented yet)
;****************************************************************************
; Pointer list starts being stored from here
@@ -71,6 +81,12 @@ RAM_Stack: equ $1FE0 ; Where stack starts
RAM_GlobalVol: equ $1FE0 ; Global volume for all channels
RAM_Status: equ $1FF0 ; Current playback status
RAM_RefreshVol: equ $1FF1 ; Set to refresh all volumes
+RAM_Flags: equ $1FF2 ; Track flags
+
RAM_Command: equ $1FFF ; Command type
RAM_ComAddr: equ $1FFD ; Command address parameter
RAM_ComBank: equ $1FFC ; Command bank parameter
+
+RAM_Command2: equ $1FFB ; (second slot for all the above)
+RAM_ComAddr2: equ $1FF9
+RAM_ComBank2: equ $1FF8