aboutsummaryrefslogtreecommitdiff
path: root/src-z80
diff options
context:
space:
mode:
authorsik2017-03-05 20:57:11 -0300
committersik2017-03-05 20:57:11 -0300
commita679ba38190bfed6ae150a12e819ad7527c495d1 (patch)
treeea4b189bce2732032998027f5dbcb75a1c0eea1d /src-z80
parent2ad500e6d8a24ca09cbfc6618aea9c1cd3cc0e93 (diff)
Upgrade!
Diffstat (limited to 'src-z80')
-rw-r--r--src-z80/build.z801
-rw-r--r--src-z80/core/bgm.z806
-rw-r--r--src-z80/core/direct.z8030
-rw-r--r--src-z80/core/main.z8035
-rw-r--r--src-z80/core/sfx.z8010
-rw-r--r--src-z80/core/vars.z806
-rw-r--r--src-z80/player/fm.z80179
-rw-r--r--src-z80/player/freq.z8010
-rw-r--r--src-z80/player/misc.z8044
-rw-r--r--src-z80/player/pcm.z8011
-rw-r--r--src-z80/player/psg.z803
11 files changed, 300 insertions, 35 deletions
diff --git a/src-z80/build.z80 b/src-z80/build.z80
index 88932ac..1aaa709 100644
--- a/src-z80/build.z80
+++ b/src-z80/build.z80
@@ -2,6 +2,7 @@
include "src-z80/player/pcm.z80"
include "src-z80/core/bgm.z80"
include "src-z80/core/sfx.z80"
+ include "src-z80/core/direct.z80"
include "src-z80/player/fm.z80"
include "src-z80/player/psg.z80"
include "src-z80/player/misc.z80"
diff --git a/src-z80/core/bgm.z80 b/src-z80/core/bgm.z80
index 2f57a73..338a7a6 100644
--- a/src-z80/core/bgm.z80
+++ b/src-z80/core/bgm.z80
@@ -97,6 +97,8 @@ ResumeBGM:
;****************************************************************************
; ProcessBGM
; Processes a tick for a BGM
+;----------------------------------------------------------------------------
+; breaks: all
;****************************************************************************
ProcessBGM:
@@ -153,6 +155,7 @@ ProcessBGMSkip:
cp $FE
jp z, SetDelayBGM ; Event $FE: set delay
cp $FF
+ProcessBGMEventFF:
jp z, StopBGMEvent ; Event $FF: stop BGM
cp $FC
jp z, LoopBGM ; Event $FC: loop BGM
@@ -192,8 +195,11 @@ ProcessBGMSkip:
cp $F8 ; Events $F0-$F7: set FM parameters
jp c, SetFMParamBGM
+ cp $FA ; Events $F8-$F9: set FM register
+ jp c, SetFMRegBGM
PollPCM ; FFFFFFFFF bad event >:(
+ProcessBGMEnd:
jp StopBGMEvent ; End of subroutine
ProcessBGMSkip2: ; This is where we land after a locked event
diff --git a/src-z80/core/direct.z80 b/src-z80/core/direct.z80
new file mode 100644
index 0000000..d796ddf
--- /dev/null
+++ b/src-z80/core/direct.z80
@@ -0,0 +1,30 @@
+;****************************************************************************
+; ProcessDirect
+; Processes the direct event stream.
+;----------------------------------------------------------------------------
+; breaks: all
+;****************************************************************************
+
+ProcessDirect:
+ ld a, ($1F00) ; Are there even events to process?
+ inc a
+ ret z
+
+ PollPCM
+
+ ld hl, ProcessDirectEnd ; Override $FF event
+ ld (ProcessBGMEventFF+1), hl
+
+ ld hl, $1F00 ; Where event data is stored
+ ld a, (RAM_LastBank) ; To avoid wasting time with bank
+ ld c, a ; switching
+
+ jp ProcessBGMRun ; Start processing the event
+
+ProcessDirectEnd:
+ ld hl, StopBGMEvent ; Restore $FF event
+ ld (ProcessBGMEventFF+1), hl
+ ld a, $FF ; Reset the stream
+ ld ($1F00), a
+
+ ret ; Return to the main loop
diff --git a/src-z80/core/main.z80 b/src-z80/core/main.z80
index da323f4..4eb6e5a 100644
--- a/src-z80/core/main.z80
+++ b/src-z80/core/main.z80
@@ -90,6 +90,8 @@ EntryPoint:
;****************************************************************************
; PollPCM
; Used to update PCM while not idle
+;----------------------------------------------------------------------------
+; breaks: af
;****************************************************************************
PollPCM: macro
@@ -154,21 +156,31 @@ IdleLoop:
;****************************************************************************
DoTick:
- ld a, (ix+0)
- bit 0, a
- call nz, UpdatePCM
+; ld a, (ix+0)
+; bit 0, a
+; call nz, UpdatePCM
- ld (ix+0), $27
+ PollPCM
+
+ ld (ix+0), $27 ; Retrigger the timer
ld (ix+1), $2F
PollPCM
+
+ ld a, ($1FF1) ; Refresh volume if needed
+ or a
+ call nz, RefreshVolume
DoTick_SFX: ; Process SFXs
jp DoTick_SFXSkip
DoTick_SFXSkip:
PollPCM
+
+ call ProcessDirect ; Process direct events
+ PollPCM
+
DoTick_BGM: ; Process BGMs
jp DoTick_BGMSkip
DoTick_BGMSkip:
@@ -257,6 +269,19 @@ LoadList:
;****************************************************************************
; GetParam
; Subroutine for getting the parameter byte
+;----------------------------------------------------------------------------
+; input c .... current bank
+; input hl ... current address
+;----------------------------------------------------------------------------
+; output b .... value
+; output c .... new bank
+; output hl ... new address
+;----------------------------------------------------------------------------
+; breaks: af
+;----------------------------------------------------------------------------
+; note: the C value gets incremented *only* when HL hits $0000 (this is
+; relevant if you consider using it to fetch from Z80 RAM, which should
+; never result in HL becoming $0000).
;****************************************************************************
GetParam:
@@ -270,7 +295,7 @@ GetParam:
BankSwitch
pop hl
.noswitchp:
- ld b, (hl) ; Get volume
+ ld b, (hl) ; Get value
inc l ; Get next address
jp nz, .nonewbankp
diff --git a/src-z80/core/sfx.z80 b/src-z80/core/sfx.z80
index 1c62873..4bca4c7 100644
--- a/src-z80/core/sfx.z80
+++ b/src-z80/core/sfx.z80
@@ -1,6 +1,8 @@
;****************************************************************************
; PlaySFX [command $02]
; Plays a SFX
+;----------------------------------------------------------------------------
+; breaks: all
;****************************************************************************
PlaySFX:
@@ -48,6 +50,8 @@ PlaySFX:
;****************************************************************************
; ProcessSFX
; Processes a tick for a SFX
+;----------------------------------------------------------------------------
+; breaks: all
;****************************************************************************
ProcessSFX:
@@ -147,10 +151,14 @@ ProcessSFXRun:
cp $F8 ; Events $F0-$F7: set FM parameters
jp c, SetFMParamSFX
+ cp $FA ; Events $F8-$F9: set FM register
+ jp c, SetFMRegSFX
;****************************************************************************
; StopSFX* [command $03, event $FF]
; Stops SFX playback
+;----------------------------------------------------------------------------
+; breaks: all
;****************************************************************************
StopSFXEvent:
@@ -186,6 +194,8 @@ StopSFX:
;****************************************************************************
; ClearSFX
; Clears SFX resources
+;----------------------------------------------------------------------------
+; breaks: all
;****************************************************************************
ClearSFX:
diff --git a/src-z80/core/vars.z80 b/src-z80/core/vars.z80
index 959711b..cd7162d 100644
--- a/src-z80/core/vars.z80
+++ b/src-z80/core/vars.z80
@@ -17,6 +17,7 @@ RAM_BGMFMInstr: ds 8 ; FM instruments used by BGM
RAM_BGMFMVol: ds 8 ; FM volumes used by BGM
RAM_BGMFMPan: ds 8, $C0 ; FM panning used by BGM
+RAM_FMVol: ds 8 ; FM volume of each channel
RAM_FMData: ds 8*5 ; FM info (for volume handling)
; ds 8*1 ... Register $B0
; ds 8*1 ... Register $40
@@ -25,6 +26,7 @@ RAM_FMData: ds 8*5 ; FM info (for volume handling)
; ds 8*1 ... Register $4C
RAM_Locked: ds 12 ; Locked channels
+RAM_PSGNote: ds 4 ; Current PSG notes
RAM_LastBank: ds 1 ; Last accessed bank
@@ -64,9 +66,11 @@ RAM_PointerList: equ $1C00
; 68000 communication variables
;****************************************************************************
-RAM_Stack: equ $1FF0 ; Where stack starts
+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_Command: equ $1FFF ; Command type
RAM_ComAddr: equ $1FFD ; Command address parameter
RAM_ComBank: equ $1FFC ; Command bank parameter
diff --git a/src-z80/player/fm.z80 b/src-z80/player/fm.z80
index 558a01d..505e849 100644
--- a/src-z80/player/fm.z80
+++ b/src-z80/player/fm.z80
@@ -1,6 +1,12 @@
;****************************************************************************
-; NoteOnFM
+; NoteOnFM* [events $00~$07]
; Does a "note on" for a FM channel
+;----------------------------------------------------------------------------
+; input a .... FM channel (bottom 3 bits)
+; input c .... current bank
+; input hl ... current address
+;----------------------------------------------------------------------------
+; breaks: af, b
;****************************************************************************
NoteOnFMSFX:
@@ -95,8 +101,14 @@ NoteOnFM:
ret ; End of subroutine
;****************************************************************************
-; NoteOffFM
+; NoteOffFM [events $10~$17]
; Does a "note off" for a FM channel
+;----------------------------------------------------------------------------
+; input a .... FM channel (bottom 3 bits)
+; input c .... current bank
+; input hl ... current address
+;----------------------------------------------------------------------------
+; breaks: af, b
;****************************************************************************
NoteOffFMSFX:
@@ -129,8 +141,14 @@ NoteOffFM:
ret ; End of subroutine
;****************************************************************************
-; SetFMNote*
+; SetFMNote* [events $30~$37]
; Sets the note of a FM channel without "note on"
+;----------------------------------------------------------------------------
+; input a .... FM channel (bottom 3 bits)
+; input c .... current bank
+; input hl ... current address
+;----------------------------------------------------------------------------
+; breaks: af, b
;****************************************************************************
SetNoteFMSFX:
@@ -200,8 +218,14 @@ SetNoteFM:
ret ; End of subroutine
;****************************************************************************
-; LoadFM*
+; LoadFM* [events $40~$47]
; Loads a FM instrument
+;----------------------------------------------------------------------------
+; input a .... FM channel (bottom 3 bits)
+; input c .... current bank
+; input hl ... current address
+;----------------------------------------------------------------------------
+; breaks: af, b
;****************************************************************************
LoadFMSFX:
@@ -398,7 +422,9 @@ LoadFMDirect:
pop hl
pop de
pop bc
- ret
+
+ ld b, 0
+ jp SetFMVolLoad
;****************************************************************************
; SetFMVol*
@@ -475,6 +501,13 @@ SetFMVolLoad:
and $07 ; Get channel ID
+ push af ; Store new FM volume
+ ld h, RAM_FMVol>>8
+ add RAM_FMVol&$FF
+ ld l, a
+ ld (hl), b
+ pop af
+
push af
ld h, RAM_FMData>>8 ; Get address of FM data
add RAM_FMData&$FF
@@ -483,6 +516,17 @@ SetFMVolLoad:
ex af, af'
PollPCM
ex af, af'
+
+ and $07 ; Get global volume
+ or $E0
+ ld d, $1F
+ ld e, a
+ ex af, af'
+ ld a, (de)
+ ld d, a
+
+ PollPCM
+ ex af, af'
and $04 ; Determine which port to write
rrca
@@ -508,11 +552,13 @@ SetFMVolLoad:
jr c, .noop1
ld (iy+0), c
ld a, (hl)
+ add d
+ jp m, .tooquiet1
add b
- cp $7F
- jr c, .notooloud1
+ jp p, .notooquiet1
+.tooquiet1:
ld a, $7F
-.notooloud1:
+.notooquiet1:
ld (iy+1), a
.noop1:
ld a, c
@@ -529,11 +575,13 @@ SetFMVolLoad:
jr c, .noop2
ld (iy+0), c
ld a, (hl)
+ add d
+ jp m, .tooquiet2
add b
- cp $7F
- jr c, .notooloud2
+ jp p, .notooquiet2
+.tooquiet2:
ld a, $7F
-.notooloud2:
+.notooquiet2:
ld (iy+1), a
.noop2:
ld a, c
@@ -550,11 +598,13 @@ SetFMVolLoad:
jr c, .noop3
ld (iy+0), c
ld a, (hl)
+ add d
+ jp m, .tooquiet3
add b
- cp $7F
- jr c, .notooloud3
+ jp p, .notooquiet3
+.tooquiet3:
ld a, $7F
-.notooloud3:
+.notooquiet3:
ld (iy+1), a
.noop3:
ld a, c
@@ -568,11 +618,13 @@ SetFMVolLoad:
ld l, a
ld (iy+0), c
ld a, (hl) ; Process operator #4
+ add d
+ jp m, .tooquiet4
add b
- cp $7F
- jr c, .notooloud4
+ jp p, .notooquiet4
+.tooquiet4:
ld a, $7F
-.notooloud4:
+.notooquiet4:
ld (iy+1), a
PollPCM
@@ -583,8 +635,17 @@ SetFMVolLoad:
ret ; End of subroutine
;****************************************************************************
-; SetFMParam*
+; SetFMParam* [events $F0-$F7]
; Sets the different parameters of a FM channel
+;----------------------------------------------------------------------------
+; input c .... current bank
+; input hl ... current address
+;----------------------------------------------------------------------------
+; output b .... value
+; output c .... new bank
+; output hl ... new address
+;----------------------------------------------------------------------------
+; breaks: af, b
;****************************************************************************
SetFMParamSFX:
@@ -657,8 +718,62 @@ SetFMParamBGM:
jp ProcessBGMRun ; End of subroutine
;****************************************************************************
+; SetFMReg* [events $F8-$F9]
+; Changes a FM register
+;----------------------------------------------------------------------------
+; input a .... YM2612 register bank (0 or 1, in bit 0)
+; input c .... current bank
+; input hl ... current address
+;----------------------------------------------------------------------------
+; output b .... value
+; output c .... new bank
+; output hl ... new address
+;----------------------------------------------------------------------------
+; breaks: af, b
+;****************************************************************************
+
+SetFMRegSFX:
+ call SetFMReg ; We're just a wrapper
+ jp ProcessSFXRun
+
+SetFMRegBGM:
+ call SetFMReg ; We're just a wrapper
+ jp ProcessBGMRun
+
+;----------------------------------------------------------------------------
+
+SetFMReg:
+ and $01 ; Get port address
+ add a
+ ld iyl, a
+
+ PollPCM ; Get parameters
+ call GetParam
+ push bc
+ PollPCM
+ call GetParam
+ PollPCM
+ ld a, b
+ pop bc
+
+ ld (iy+0), b ; Write register
+ ld (iy+1), a
+
+ ret ; End of subroutine
+
+;****************************************************************************
; LockChannelFM [events $E0-$E7]
; Locks a FM channel
+;----------------------------------------------------------------------------
+; input a ... FM channel (0..7, in bottom 3 bits)
+; input c .... current bank
+; input hl ... current address
+;----------------------------------------------------------------------------
+; output b .... value
+; output c .... new bank
+; output hl ... new address
+;----------------------------------------------------------------------------
+; breaks: af, iy
;****************************************************************************
LockChannelFM:
@@ -694,6 +809,10 @@ LockChannelFM:
;****************************************************************************
; KillFM
; Kills a FM channel
+;----------------------------------------------------------------------------
+; input a ... FM channel (0..7, in bottom 3 bits)
+;----------------------------------------------------------------------------
+; breaks: af, c, iy
;****************************************************************************
KillFM:
@@ -720,20 +839,26 @@ KillFM:
ld e, (hl)
ld (iy+0), a
- add 4
ld (iy+1), e
- nop
- ld (iy+0), a
add 4
- ld (iy+1), e
- nop
+ ex af, af'
+ PollPCM
+ ex af, af'
ld (iy+0), a
- add 4
ld (iy+1), e
- nop
+ add 4
+ ex af, af'
+ PollPCM
+ ex af, af'
ld (iy+0), a
+ ld (iy+1), e
add 4
+ ex af, af'
+ PollPCM
+ ex af, af'
+ ld (iy+0), a
ld (iy+1), e
+ add 4
inc l
dec c
@@ -743,7 +868,7 @@ KillFM:
pop de
PollPCM
pop af
-
+
ld c, a ; Cause the ADSR to reset
or $F0
ld (ix+0), $28
@@ -752,7 +877,7 @@ KillFM:
ld (ix+1), a
ld (ix+0), $28
ld (ix+1), c
-
+
PollPCM
ret ; End of subroutine
diff --git a/src-z80/player/freq.z80 b/src-z80/player/freq.z80
index beb8702..7f963e5 100644
--- a/src-z80/player/freq.z80
+++ b/src-z80/player/freq.z80
@@ -89,6 +89,16 @@ FMFreqTable:
dw 1021, 1081, 1146, 1214
;****************************************************************************
+; PSGShiftTable
+; Semitone shifting table for PSG instruments
+;****************************************************************************
+
+PSGShiftTable:
+ db 0
+ db 2, 4, 6, 8, 10, 12
+ db -2, -4, -6, -8, -10, -12
+
+;****************************************************************************
; DummyFMInstr
; Dummy FM instrument to mute FM channels...
;
diff --git a/src-z80/player/misc.z80 b/src-z80/player/misc.z80
index 36be250..dee980e 100644
--- a/src-z80/player/misc.z80
+++ b/src-z80/player/misc.z80
@@ -44,3 +44,47 @@ SetDelayShort:
ld (hl), b
ret ; End of subroutine
+
+;****************************************************************************
+; RefreshVolume
+; Reloads the volume for all channels.
+;----------------------------------------------------------------------------
+; breaks: all
+;****************************************************************************
+
+RefreshVolume:
+ ld hl, $1FF0 ; Update FM volume
+ ld de, RAM_FMVol
+ ld c, 8
+.fixfmvol:
+ ld a, (de)
+ ld b, (hl)
+ add b
+ jp p, .fixfmvolok
+ ld a, $7F
+.fixfmvolok:
+ ld b, a
+ ld a, l
+ call SetFMVolLoad
+ inc l
+ inc e
+ dec c
+ jr nz, .fixfmvol
+
+ ld hl, $1FE8 ; Update PSG volume
+ ld de, RAM_PSGData+1
+ ld bc, $0410
+.fixpsgvol:
+ ld a, (hl)
+ ld (de), a
+ inc l
+ ld a, e
+ add a, c
+ ld e, a
+ PollPCM
+ djnz .fixpsgvol
+
+ xor a ; Mark that volume was refreshed
+ ld ($1FF1), a
+
+ ret ; End of subroutine
diff --git a/src-z80/player/pcm.z80 b/src-z80/player/pcm.z80
index 2a484d4..99feb6d 100644
--- a/src-z80/player/pcm.z80
+++ b/src-z80/player/pcm.z80
@@ -1,6 +1,11 @@
;****************************************************************************
-; PlayPCM*
+; PlayPCM* [event $0C]
; Plays a PCM sample
+;----------------------------------------------------------------------------
+; input c .... current bank
+; input hl ... current address
+;----------------------------------------------------------------------------
+; breaks: af, b
;****************************************************************************
PlayPCMSFX:
@@ -18,6 +23,10 @@ PlayPCMBGM:
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
diff --git a/src-z80/player/psg.z80 b/src-z80/player/psg.z80
index f0c5a76..b88978c 100644
--- a/src-z80/player/psg.z80
+++ b/src-z80/player/psg.z80
@@ -46,7 +46,7 @@ UpdatePSG:
cp $FF ; Loop envelope?
jp z, .envloop
- ld iyl, b ; Keep byte safe somewhere...
+ ld iyl, b ; Keep byte safe somewhere...
PollPCM
ex de, hl ; Store new address
@@ -61,6 +61,7 @@ UpdatePSG:
PollPCM
db $FD,$7D ; ld a, iyl ; Mix envelope with volume
+ and $0F
add b
ld b, a