aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README5
-rw-r--r--built/massive-crash.binbin0 -> 4864 bytes
-rw-r--r--src-z80/core/bgm.z8033
-rw-r--r--src-z80/core/sfx.z8034
-rw-r--r--src-z80/core/vars.z803
-rw-r--r--src-z80/player/fm.z80108
-rw-r--r--src-z80/player/freq.z802
7 files changed, 102 insertions, 83 deletions
diff --git a/README b/README
index 122c26c..2172920 100644
--- a/README
+++ b/README
@@ -43,6 +43,11 @@ How to build:
Available builds:
+ built/echo-massive-crash.bin
+ Massive Echo crasher o_o; Two tunes screw up if played repeatedly, two
+ tunes outright crash the entire system. This only happens on real
+ hardware, *not* in emulators. FML.
+
built/echo-timer-version-a.bin
Timer test. Both timers get reloaded each time they're fired.
built/echo-timer-version-b.bin
diff --git a/built/massive-crash.bin b/built/massive-crash.bin
new file mode 100644
index 0000000..ae74673
--- /dev/null
+++ b/built/massive-crash.bin
Binary files differ
diff --git a/src-z80/core/bgm.z80 b/src-z80/core/bgm.z80
index f69235d..eac10d9 100644
--- a/src-z80/core/bgm.z80
+++ b/src-z80/core/bgm.z80
@@ -73,6 +73,7 @@ ProcessBGM:
ld d, (hl)
ex de, hl
+ProcessBGMSkip:
ProcessBGMRun:
PollPCM ; Fetch next event
call GetParam
@@ -163,9 +164,7 @@ ProcessBGMSkip1: ; This is where we land after a locked event
inc c
.nobankskip1:
-ProcessBGMSkip: ; This is where we land after a locked event
- PollPCM ; without parameters
-
+ PollPCM
jp ProcessBGMRun ; Keep processing
;****************************************************************************
@@ -210,39 +209,51 @@ ClearBGM:
or a
call z, StopPCM
+;----------------------------------------------------------------------------
+
ld b, 4 ; Mute all non-locked PSG channels
ld de, RAM_PSGData+48
ld hl, RAM_Locked+11
.mutepsg:
PollPCM
+
ld a, (hl)
or a
- jr nz, .nopsgmute
+ jp nz, .nopsgmute
xor a
ld (de), a
.nopsgmute:
PollPCM
+
ld a, e
sub 16
ld e, a
+
dec l
djnz .mutepsg
+;----------------------------------------------------------------------------
+
ld b, 8 ; Mute all non-locked FM channels
.mutefm:
PollPCM
- ld a, (hl)
+
+ ld a, (hl) ; Check if channel is locked
or a
- jr nz, .nofmmute
+ jp nz, .nofmmute
+
PollPCM
- dec b
- ld (ix+0), $28
- ld (ix+1), b
- inc b
-.nofmmute:
+
+ ld a, b ; Kill FM channel
+ dec a
+ call KillFM
+
+.nofmmute: ; Go for next channel
dec l
djnz .mutefm
+;----------------------------------------------------------------------------
+
ret ; End of subroutine
;****************************************************************************
diff --git a/src-z80/core/sfx.z80 b/src-z80/core/sfx.z80
index c778776..0a7d1e8 100644
--- a/src-z80/core/sfx.z80
+++ b/src-z80/core/sfx.z80
@@ -276,25 +276,9 @@ ClearSFX:
ld a, b ; Kill ADSR
call KillFM
- ;PollPCM
-
- ;ld hl, RAM_BGMFMVol ; Restore BGM FM volume
- ;ld a, b
- ;add l
- ;ld l, a
- ;ld c, (hl)
- ;ld a, l
- ;add 8
- ;ld l, a
- ;ld (hl), c
-
PollPCM
- ;ld a, l ; Restore BGM FM instrument
- ;sub 8*2
- ;ld l, a
-
- ld hl, RAM_BGMFMInstr
+ ld hl, RAM_BGMFMInstr ; Restore BGM FM instrument
ld a, b
add l
ld l, a
@@ -309,6 +293,22 @@ ClearSFX:
pop de
pop bc
+ ;PollPCM
+
+ ;ld a, l
+ ;add 8
+ ;ld l, a
+
+ ;ld hl, RAM_BGMFMVol ; Restore BGM FM volume
+ ;ld a, b
+ ;add l
+ ;ld l, a
+ ;ld c, (hl)
+ ;ld a, l
+ ;add 8
+ ;ld l, a
+ ;ld (hl), c
+
PollPCM
inc b
.fmfree:
diff --git a/src-z80/core/vars.z80 b/src-z80/core/vars.z80
index 3496845..64a1dde 100644
--- a/src-z80/core/vars.z80
+++ b/src-z80/core/vars.z80
@@ -15,7 +15,8 @@ RAM_PSGData: ds 4*16 ; PSG envelope data
RAM_BGMFMInstr: ds 8 ; FM instruments used by BGM
RAM_BGMFMVol: ds 8 ; FM volumes used by BGM
-;RAM_FMVolume: ds 8 ; Volume of each FM channel
+
+RAM_FMVolume: ds 8 ; Volume of each FM channel
RAM_FMData: ds 8*5 ; FM info (for volume handling)
; ds 8*1 ... Register $B0
diff --git a/src-z80/player/fm.z80 b/src-z80/player/fm.z80
index c492b91..c075f99 100644
--- a/src-z80/player/fm.z80
+++ b/src-z80/player/fm.z80
@@ -4,30 +4,32 @@
;****************************************************************************
NoteOnFMSFX:
+ and $07 ; Get channel number
call NoteOnFM ; We're just a wrapper
jp ProcessSFXRun ; End of subroutine
NoteOnFMBGM:
+ and $07 ; Get channel number
ld b, a
PollPCM
- push hl
+ push hl ; Check if channel is free
ld a, b
- and $07 ; Check if channel is free
- ld hl, RAM_Locked
- add l
+ ld h, RAM_Locked>>8
+ add RAM_Locked&$FF
ld l, a
ld a, (hl)
pop hl
or a
jp nz, ProcessBGMSkip1 ; Don't play if locked
+
+ PollPCM
ld a, b
call NoteOnFM ; We're just a wrapper
jp ProcessBGMRun ; End of subroutine
NoteOnFM:
- and $07 ; Get channel ID
ld (ix+0), $28 ; Note off
ld (ix+1), a
@@ -100,18 +102,20 @@ NoteOnFM:
;****************************************************************************
NoteOffFMSFX:
+ and $07 ; Get channel ID
call NoteOffFM ; We're just a wrapper
jp ProcessSFXRun ; End of subroutine
NoteOffFMBGM:
+ and $07 ; Get channel ID
+
ld b, a
PollPCM
ld a, b
- push hl
- and $07 ; Check if channel is free
- ld hl, RAM_Locked
- add l
+ push hl ; Check if channel is free
+ ld h, RAM_Locked>>8
+ add RAM_Locked&$FF
ld l, a
ld a, (hl)
pop hl
@@ -123,9 +127,9 @@ NoteOffFMBGM:
jp ProcessBGMRun ; End of subroutine
NoteOffFM:
- and $07 ; Get channel ID
ld (ix+0), $28 ; Note off
ld (ix+1), a
+
ret ; End of subroutine
;****************************************************************************
@@ -144,8 +148,8 @@ SetNoteFMBGM:
push hl
and $07 ; Check if channel is free
- ld hl, RAM_Locked
- add l
+ ld h, RAM_Locked>>8
+ add RAM_Locked&$FF
ld l, a
ld a, (hl)
pop hl
@@ -180,18 +184,15 @@ SetNoteFM:
ld e, a
PollPCM
-
ld (iy+0), e ; Load high byte
ld (iy+1), b
- PollPCM ; Load low byte
- call GetParam
+ call GetParam ; Load low byte
PollPCM
ld a, e
sub 4
ld e, a
-
ld (iy+0), e
ld (iy+1), b
@@ -205,26 +206,31 @@ SetNoteFM:
;****************************************************************************
LoadFMSFX:
+ and $07 ; Get channel ID
call LoadFMEvent ; We're just a wrapper
jp ProcessSFXRun ; End of subroutine
LoadFMBGM:
and $07 ; Get channel ID
+
ld b, a
PollPCM
push de
push bc
ld a, b
- ld de, RAM_BGMFMInstr ; Store instrument ID
- add e
+
+ ld de, RAM_BGMFMInstr ; Where to keep instrument ID for BGM
+ add e ; (used when unlocking channels)
ld e, a
- PollPCM
+
+ PollPCM ; Store instrument ID
call GetParam
PollPCM
ex de, hl
ld (hl), b
ex de, hl
+
ld e, c
pop bc
ld c, e
@@ -232,10 +238,10 @@ LoadFMBGM:
PollPCM
- push hl ; Check if channel is free
- ld hl, RAM_Locked
+ push hl ; Check if channel is free
ld a, b
- add l
+ ld h, RAM_Locked>>8
+ add RAM_Locked&$FF
ld l, a
ld a, (hl)
pop hl
@@ -244,8 +250,7 @@ LoadFMBGM:
PollPCM
- ld a, b
- and $07
+ ld a, b ; Get back the instrument ID
push hl
ld hl, RAM_BGMFMInstr
add l
@@ -253,23 +258,21 @@ LoadFMBGM:
ld b, (hl)
pop hl
- push af
+ ex af, af'
PollPCM
- pop af
+ ex af, af'
call LoadFMDirect ; We're just a wrapper
jp ProcessBGMRun ; End of subroutine
LoadFMEvent:
- and $07 ; Get channel ID
-
ex af, af'
PollPCM
call GetParam ; Get instrument ID
PollPCM
ex af, af'
+
LoadFMDirect:
-
push af
and $04 ; Determine which port to write
rrca
@@ -333,9 +336,14 @@ LoadFMDirect:
call KillFM
ld a, b
- ld de, RAM_FMData ; Get address of FM data
+ ;ld de, RAM_FMData ; Get address of FM data
+ ;and $07
+ ;add e
+ ;ld e, a
+
and $07
- add e
+ ld d, RAM_FMData>>8
+ add RAM_FMData&$FF
ld e, a
push af
@@ -577,9 +585,6 @@ SetFMVolLoad:
jr c, .noop1
ld a, (hl)
add b
- ;cp $7F
- ;jr c, .notooloud1
- ;ld a, $7F
jp p, .notooloud1
ld a, $7F
.notooloud1:
@@ -600,9 +605,6 @@ SetFMVolLoad:
jr c, .noop2
ld a, (hl)
add b
- ;cp $7F
- ;jr c, .notooloud2
- ;ld a, $7F
jp p, .notooloud2
ld a, $7F
.notooloud2:
@@ -623,9 +625,6 @@ SetFMVolLoad:
jr c, .noop3
ld a, (hl)
add b
- ;cp $7F
- ;jr c, .notooloud3
- ;ld a, $7F
jp p, .notooloud3
ld a, $7F
.notooloud3:
@@ -643,9 +642,6 @@ SetFMVolLoad:
ld l, a
ld a, (hl) ; Process operator #4
add b
- ;cp $7F
- ;jr c, .notooloud4
- ;ld a, $7F
jp p, .notooloud4
ld a, $7F
.notooloud4:
@@ -691,8 +687,7 @@ SetFMParam:
ld b, a
PollPCM
- ;ld iyh, $40 ; Determine which port to write
- ld a, b
+ ld a, b ; Determine which port to write
and $04
rrca
ld iyl, a
@@ -752,12 +747,18 @@ LockChannelFM:
;****************************************************************************
KillFM:
- push af
+ and $07 ; Trim non-channel bits
+
+ push hl
push de
+ push af
- and $03 ; Load dummy FM instrument
+ ld (ix+0), $28 ; Note off
+ ld (ix+1), a
+
+ and $03 ; Load dummy FM instrument
add $40
- ld c, 6
+ ld d, 6
ld hl, DummyFMInstr
.loaddummy:
ex af, af'
@@ -779,19 +780,20 @@ KillFM:
add 4
inc l
- dec c
+ dec d
jp nz, .loaddummy
- pop de
PollPCM
pop af
-
- ld c, a ; Reset ADSR
+
+ ld d, a ; Reset ADSR
or $F0
ld (ix+0), $28
ld (ix+1), a
ld (ix+0), $28
- ld (ix+1), c
+ ld (ix+1), d
+ pop de
+ pop hl
PollPCM
ret ; End of subroutine
diff --git a/src-z80/player/freq.z80 b/src-z80/player/freq.z80
index a469c0b..0b529de 100644
--- a/src-z80/player/freq.z80
+++ b/src-z80/player/freq.z80
@@ -101,5 +101,5 @@ DummyFMInstr:
db $1F ; $50..$5C
db $1F ; $60..$6C
db $1F ; $70..$7C
- db $0F ; $80..$8C
+ db $FF ; $80..$8C
db $00 ; $90..$9C