aboutsummaryrefslogtreecommitdiff
path: root/src-z80/player/fm.z80
diff options
context:
space:
mode:
Diffstat (limited to 'src-z80/player/fm.z80')
-rw-r--r--src-z80/player/fm.z80230
1 files changed, 135 insertions, 95 deletions
diff --git a/src-z80/player/fm.z80 b/src-z80/player/fm.z80
index c075f99..fa86538 100644
--- a/src-z80/player/fm.z80
+++ b/src-z80/player/fm.z80
@@ -4,32 +4,30 @@
;****************************************************************************
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 ; Check if channel is free
+ push hl
ld a, b
- ld h, RAM_Locked>>8
- add RAM_Locked&$FF
+ and $07 ; Check if channel is free
+ ld hl, RAM_Locked
+ add l
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
@@ -102,20 +100,18 @@ 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 ; Check if channel is free
- ld h, RAM_Locked>>8
- add RAM_Locked&$FF
+ push hl
+ and $07 ; Check if channel is free
+ ld hl, RAM_Locked
+ add l
ld l, a
ld a, (hl)
pop hl
@@ -127,9 +123,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
;****************************************************************************
@@ -148,8 +144,8 @@ SetNoteFMBGM:
push hl
and $07 ; Check if channel is free
- ld h, RAM_Locked>>8
- add RAM_Locked&$FF
+ ld hl, RAM_Locked
+ add l
ld l, a
ld a, (hl)
pop hl
@@ -184,15 +180,18 @@ SetNoteFM:
ld e, a
PollPCM
+
ld (iy+0), e ; Load high byte
ld (iy+1), b
- call GetParam ; Load low byte
+ PollPCM ; Load low byte
+ call GetParam
PollPCM
ld a, e
sub 4
ld e, a
+
ld (iy+0), e
ld (iy+1), b
@@ -206,31 +205,33 @@ 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 ; Where to keep instrument ID for BGM
- add e ; (used when unlocking channels)
+ ld de, RAM_BGMFMInstr ; Store instrument ID
+ add e
ld e, a
-
- PollPCM ; Store instrument ID
+ PollPCM
call GetParam
PollPCM
ex de, hl
ld (hl), b
ex de, hl
+ ld a, e ; Reset volume
+ add 8
+ ld e, a
+ xor a
+ ld (de), a
+
ld e, c
pop bc
ld c, e
@@ -239,9 +240,9 @@ LoadFMBGM:
PollPCM
push hl ; Check if channel is free
+ ld hl, RAM_Locked
ld a, b
- ld h, RAM_Locked>>8
- add RAM_Locked&$FF
+ add l
ld l, a
ld a, (hl)
pop hl
@@ -250,7 +251,8 @@ LoadFMBGM:
PollPCM
- ld a, b ; Get back the instrument ID
+ ld a, b
+ and $07
push hl
ld hl, RAM_BGMFMInstr
add l
@@ -258,21 +260,23 @@ LoadFMBGM:
ld b, (hl)
pop hl
- ex af, af'
+ push af
PollPCM
- ex af, af'
+ pop 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
@@ -336,14 +340,9 @@ LoadFMDirect:
call KillFM
ld a, b
- ;ld de, RAM_FMData ; Get address of FM data
- ;and $07
- ;add e
- ;ld e, a
-
+ ld de, RAM_FMData ; Get address of FM data
and $07
- ld d, RAM_FMData>>8
- add RAM_FMData&$FF
+ add e
ld e, a
push af
@@ -362,9 +361,9 @@ LoadFMDirect:
ld (iy+1), b
ex af, af' ; Store $B0 register in FM data buffer
- ld a, b ; Also store it in the FM channel information
- ld (de), a ; table since we need it when changing the
- ld a, e ; FM channel volume
+ ld a, b
+ ld (de), a
+ ld a, e
add 8
ld e, a
PollPCM
@@ -378,37 +377,50 @@ LoadFMDirect:
ld (iy+0), a
ld b, (hl)
+ nop
ld (iy+1), b
add 4
inc l
+ nop
+
ld (iy+0), a
ld b, (hl)
+ nop
ld (iy+1), b
add 4
inc l
+ nop
+
ld (iy+0), a
ld b, (hl)
+ nop
ld (iy+1), b
add 4
inc l
+ nop
+
ld (iy+0), a
ld b, (hl)
+ nop
ld (iy+1), b
add 4
inc l
+ nop
ld b, 4 ; Write registers $40-$4C
-.reg40: ; Also store the registers in the FM channel
- ld c, a ; information field since we'll need them to
- push af ; set the FM channel volume
+.reg40:
+ ld c, a
+ push af
PollPCM
+
ld (iy+0), c
ld a, (hl)
- ld (iy+1), a
ld (de), a
+ ld (iy+1), a
ld a, e
add 8
ld e, a
+
pop af
add 4
inc l
@@ -416,33 +428,41 @@ LoadFMDirect:
ld b, 20/4 ; Write registers $50-$5C
.reg50:
- ld c, b
ex af, af'
PollPCM
ex af, af'
ld (iy+0), a
- ld b, (hl)
- ld (iy+1), b
+ ld c, (hl)
+ nop
+ ld (iy+1), c
add 4
inc l
+ nop
+
ld (iy+0), a
- ld b, (hl)
- ld (iy+1), b
+ ld c, (hl)
+ nop
+ ld (iy+1), c
add 4
inc l
+ nop
+
ld (iy+0), a
- ld b, (hl)
- ld (iy+1), b
+ ld c, (hl)
+ nop
+ ld (iy+1), c
add 4
inc l
+ nop
+
ld (iy+0), a
- ld b, (hl)
- ld (iy+1), b
+ ld c, (hl)
+ nop
+ ld (iy+1), c
add 4
-
inc l
- ld b, c
+
djnz .reg50
PollPCM
@@ -462,8 +482,6 @@ LoadFMDirect:
pop de
pop bc
ret
-
- ;jp SetFMVolLoad ; End of subroutine
;****************************************************************************
; SetFMVol*
@@ -483,8 +501,11 @@ SetFMVolBGM:
push de
push bc
ld a, b
- ld de, RAM_BGMFMVol ; Store BGM volume
- add e
+ ;ld de, RAM_BGMFMVol ; Store BGM volume
+ ;add e
+ ;ld e, a
+ ld d, RAM_BGMFMVol>>8
+ add RAM_BGMFMVol&$FF
ld e, a
PollPCM
call GetParam
@@ -523,41 +544,49 @@ SetFMVolBGM:
PollPCM
pop af
- call SetFMVolBGMEvent ; We're just a wrapper
+ ;call SetFMVolBGMEvent ; We're just a wrapper
+ call SetFMVolLoad ; We're just a wrapper
jp ProcessBGMRun ; End of subroutine
SetFMVolEvent:
- ex af, af'
+ push af
PollPCM
call GetParam ; Get new volume
PollPCM
- ex af, af'
+ pop af
SetFMVolBGMEvent:
- push bc
- push de
- push hl
+ ;push bc
+ ;push de
+ ;push hl
;ld hl, RAM_FMVolume ; Store new volume
;and $07
;add l
;ld l, a
;ld (hl), b
+
+SetFMVolLoad:
+ push bc
+ push de
+ push hl
- ;ld hl, RAM_FMData
+ and $07
+
+ ;ex af, af'
+ ;PollPCM
;ld a, l ; Get address of FM data
;add 8
;ld l, a
+ ;ex af, af'
push af
- ld hl, RAM_FMData ; Get address of FM data
- and $07
- add l
+ ld h, RAM_FMData>>8 ; Get address of FM data
+ add RAM_FMData&$FF
ld l, a
PollPCM
pop af
-SetFMVolLoad:
push af
and $04 ; Determine which port to write
rrca
@@ -569,8 +598,6 @@ SetFMVolLoad:
add $40
ld c, a
- ;PollPCM
-
ld a, (hl) ; Get algorithm
and $07
ld e, a
@@ -583,12 +610,13 @@ SetFMVolLoad:
ld a, e ; Process operator #1
cp $07
jr c, .noop1
+ ld (iy+0), c
ld a, (hl)
add b
- jp p, .notooloud1
+ cp $7F
+ jr c, .notooloud1
ld a, $7F
.notooloud1:
- ld (iy+0), c
ld (iy+1), a
.noop1:
ld a, c
@@ -603,12 +631,13 @@ SetFMVolLoad:
ld a, e ; Process operator #2
cp $05
jr c, .noop2
+ ld (iy+0), c
ld a, (hl)
add b
- jp p, .notooloud2
+ cp $7F
+ jr c, .notooloud2
ld a, $7F
.notooloud2:
- ld (iy+0), c
ld (iy+1), a
.noop2:
ld a, c
@@ -623,12 +652,13 @@ SetFMVolLoad:
ld a, e ; Process operator #3
cp $04
jr c, .noop3
+ ld (iy+0), c
ld a, (hl)
add b
- jp p, .notooloud3
+ cp $7F
+ jr c, .notooloud3
ld a, $7F
.notooloud3:
- ld (iy+0), c
ld (iy+1), a
.noop3:
ld a, c
@@ -640,12 +670,13 @@ SetFMVolLoad:
ld a, l
add 8
ld l, a
+ ld (iy+0), c
ld a, (hl) ; Process operator #4
add b
- jp p, .notooloud4
+ cp $7F
+ jr c, .notooloud4
ld a, $7F
.notooloud4:
- ld (iy+0), c
ld (iy+1), a
PollPCM
@@ -747,18 +778,24 @@ LockChannelFM:
;****************************************************************************
KillFM:
- and $07 ; Trim non-channel bits
+ and $07 ; Get channel ID
- push hl
- push de
push af
+ push de
+ push hl
- ld (ix+0), $28 ; Note off
+ ld c, a ; Determine to which port to write
+ and $04
+ rrca
+ ld iyl, a
+ ld a, c
+
+ ld (ix+0), $28 ; Stop current note (if any)
ld (ix+1), a
and $03 ; Load dummy FM instrument
add $40
- ld d, 6
+ ld c, 6
ld hl, DummyFMInstr
.loaddummy:
ex af, af'
@@ -767,33 +804,36 @@ KillFM:
ld e, (hl)
ld (iy+0), a
- ld (iy+1), e
add 4
- ld (iy+0), a
ld (iy+1), e
- add 4
+ nop
ld (iy+0), a
- ld (iy+1), e
add 4
+ ld (iy+1), e
+ nop
ld (iy+0), a
+ add 4
ld (iy+1), e
+ nop
+ ld (iy+0), a
add 4
+ ld (iy+1), e
inc l
- dec d
+ dec c
jp nz, .loaddummy
+ pop hl
+ pop de
PollPCM
pop af
-
- ld d, a ; Reset ADSR
+
+ ld c, a ; Reset ADSR
or $F0
ld (ix+0), $28
ld (ix+1), a
ld (ix+0), $28
- ld (ix+1), d
+ ld (ix+1), c
- pop de
- pop hl
PollPCM
ret ; End of subroutine