Fixes for Cybernoid1:

. Ultimately switched from MB(1MHz clock) to Phasor(2MHz clock) for less noisy playback.
. Fixed a bug in Cmd_00 where HL was loaded with the wrong value.
. Fixed bugs where (DE) was referencing $00nn Spectrum ROM values.
. Fixed initial state to mirror the Cybernoid game (not the AY player binary).
This commit is contained in:
tomcw 2020-09-20 11:50:15 +01:00
parent 7218584326
commit 57b5ea265a
3 changed files with 131 additions and 71 deletions

View File

@ -1,6 +1,7 @@
SPECTRUM128_STEREO = 1 ; L = A+Bx0.5, R = C'+B'x0.5 SPECTRUM128_STEREO = 1 ; L = A+Bx0.5, R = C'+B'x0.5
DUAL_MONO = 0 ; L = A+B+C, R=A'+B'+C' DUAL_MONO = 0 ; L = A+B+C, R=A'+B'+C'
USE_PHASOR = 1
!macro MB_Init1 .RegSongNum { !macro MB_Init1 .RegSongNum {
@ -18,7 +19,7 @@ nMaskB: !byte 0 ; Voice-B mask (0=enable)
nMaskC: !byte 0 ; Voice-C mask (0=enable) nMaskC: !byte 0 ; Voice-C mask (0=enable)
; ;
nAttA: !byte 0 ; Attenuation of Voice-A nAttA: !byte 0 ; Attenuation of Voice-A
nAttB: !byte 1 ; Attenuation of Voice-B : B Volume / 2 (logarithmic, so: if (A) A--) nAttB: !byte 1 ; Attenuation of Voice-B : B Volume / 2 (logarithmic, so: if (B) B--)
nAttC: !byte 0 ; Attenuation of Voice-C nAttC: !byte 0 ; Attenuation of Voice-C
; ;
pAYRegValues: !word AYRegValues ; For VU-meter pAYRegValues: !word AYRegValues ; For VU-meter
@ -43,7 +44,7 @@ SongNumOK:
; . Saving ZPBlock ; . Saving ZPBlock
lda #1<<6 lda #1<<6
MB0: sta CARD_BASE+SY6522_IER ; Disable Timer1 IRQ MB0: sta CARD_BASE+SY6522_IER+SY6522_A_PH_BASE ; Disable Timer1 IRQ
FindMB: FindMB:
@ -89,22 +90,38 @@ GotMBSlot:
; ;
!if USE_PHASOR { ; Phasor 2MHz mode
lda MBBaseH
asl
asl
asl
asl ; slot * 16
clc
adc #PH_PHASOR
tax
lda $c080,x
}
!if USE_PHASOR {
lda #$1f ; Phasor has 2 extra chip-select bits (b4:3)
}else{
lda #$07 lda #$07
ldy #SY6522_DDRB }
ldy #SY6522_DDRB+SY6522_A_PH_BASE
sta (MBBase),y sta (MBBase),y
ldy #SY6522_DDRB+$80 ldy #SY6522_DDRB+SY6522_B_BASE
sta (MBBase),y sta (MBBase),y
lda #$ff lda #$ff
ldy #SY6522_DDRA ldy #SY6522_DDRA+SY6522_A_PH_BASE
sta (MBBase),y sta (MBBase),y
ldy #SY6522_DDRA+$80 ldy #SY6522_DDRA+SY6522_B_BASE
sta (MBBase),y sta (MBBase),y
lda #AY_RESET lda #AY_RESET ; Phasor chip-select b4:3=%00 (so select both AY's)
ldy #SY6522_ORB ldy #SY6522_ORB+SY6522_A_PH_BASE
sta (MBBase),y sta (MBBase),y
ldy #SY6522_ORB+$80 ldy #SY6522_ORB+SY6522_B_BASE
sta (MBBase),y sta (MBBase),y
ldx nSongNum ldx nSongNum
@ -127,23 +144,23 @@ NotFini:
sta nFrameNum+2 sta nFrameNum+2
; Setup Timer1 IRQ to trigger at 50Hz ; Setup Timer1 IRQ to trigger at 50Hz
; Apple CLK = 1.022727 MHz, so set Timer1=0x4fe7 ; Apple NTSC CLK = 1.022727 MHz, so set Timer1=0x4fe7
sei sei
lda #$e7 lda #$e7
ldy #SY6522_TIMER1L_COUNTER ldy #SY6522_TIMER1L_COUNTER+SY6522_A_PH_BASE
sta (MBBase),y sta (MBBase),y
lda #$4f lda #$4f
ldy #SY6522_TIMER1H_COUNTER ldy #SY6522_TIMER1H_COUNTER+SY6522_A_PH_BASE
sta (MBBase),y sta (MBBase),y
lda #1<<6 lda #1<<6
ldy #SY6522_ACR ldy #SY6522_ACR+SY6522_A_PH_BASE
sta (MBBase),y ; Free running timer sta (MBBase),y ; Free running timer
lda #1<<7 | 1<<6 lda #1<<7 | 1<<6
ldy #SY6522_IER ldy #SY6522_IER+SY6522_A_PH_BASE
sta (MBBase),y ; Enable Timer1 IRQ sta (MBBase),y ; Enable Timer1 IRQ
lda #<Interrupt ; ADDR_L lda #<Interrupt ; ADDR_L
@ -162,26 +179,31 @@ InitExit2:
;-------------------------------------- ;--------------------------------------
!macro SF_UpdateAY { !if USE_PHASOR {
PHASOR_CS_MASK = %10000 ; Phasor: b4=1 (don't select), b3=0 (select)
} else {
PHASOR_CS_MASK = 0
}
; Skyfox's routine to update AY regs: ; Skyfox's routine to update AY regs:
!macro SF_UpdateAY {
SF_SelectReg: SF_SelectReg:
MBx1: sta CARD_BASE+SY6522_ORA,x MBx1: sta CARD_BASE+SY6522_ORA,x
lda #AY_LATCH lda #AY_LATCH | PHASOR_CS_MASK
bne .l675e bne .l675e
SF_WriteReg: SF_WriteReg:
MBx2: sta CARD_BASE+SY6522_ORA,x MBx2: sta CARD_BASE+SY6522_ORA,x
lda #AY_WRITE lda #AY_WRITE | PHASOR_CS_MASK
bne .l675e bne .l675e
SF_ChipReset: SF_ChipReset:
lda #AY_RESET lda #AY_RESET | PHASOR_CS_MASK
.l675e: .l675e:
MBx3: sta CARD_BASE+SY6522_ORB,x MBx3: sta CARD_BASE+SY6522_ORB,x
lda #AY_INACTIVE lda #AY_INACTIVE | PHASOR_CS_MASK
MBx4: sta CARD_BASE+SY6522_ORB,x MBx4: sta CARD_BASE+SY6522_ORB,x
rts rts
} }
@ -238,9 +260,9 @@ AYPostProc:
; ;
; Attenuate AVOL ; Attenuate AVOL
lda .ay_regs_base+AY_AVOL ; lda .ay_regs_base+AY_AVOL
and #AY_AMPLITUDE_MODE ; and #AY_AMPLITUDE_MODE
bne + ; don't attenuate if amp.mode=envelope ; bne + ; don't attenuate if amp.mode=envelope (Cybernoid doesn't use envelopes)
lda .ay_regs_base+AY_AVOL lda .ay_regs_base+AY_AVOL
sec sec
sbc nAttA sbc nAttA
@ -253,9 +275,9 @@ AYPostProc:
; ;
; Attenuate BVOL ; Attenuate BVOL
lda .ay_regs_base+AY_BVOL ; lda .ay_regs_base+AY_BVOL
and #AY_AMPLITUDE_MODE ; and #AY_AMPLITUDE_MODE
bne + ; don't attenuate if amp.mode=envelope ; bne + ; don't attenuate if amp.mode=envelope (Cybernoid doesn't use envelopes)
lda .ay_regs_base+AY_BVOL lda .ay_regs_base+AY_BVOL
sec sec
sbc nAttB sbc nAttB
@ -269,9 +291,9 @@ AYPostProc:
; ;
; Attenuate CVOL ; Attenuate CVOL
lda .ay_regs_base+AY_CVOL ; lda .ay_regs_base+AY_CVOL
and #AY_AMPLITUDE_MODE ; and #AY_AMPLITUDE_MODE
bne + ; don't attenuate if amp.mode=envelope ; bne + ; don't attenuate if amp.mode=envelope (Cybernoid doesn't use envelopes)
lda .ay_regs_base+AY_CVOL lda .ay_regs_base+AY_CVOL
sec sec
sbc nAttC sbc nAttC
@ -323,7 +345,7 @@ AYPostProc:
; ;
ldx #0 ldx #SY6522_A_PH_BASE ; Works for both MB & Phasor modes
ldy #$0D ldy #$0D
.sf_loop0: tya .sf_loop0: tya
jsr SF_SelectReg jsr SF_SelectReg
@ -334,7 +356,7 @@ AYPostProc:
; ;
ldx #$80 ldx #SY6522_B_BASE
ldy #$0D ldy #$0D
.sf_loop1: tya .sf_loop1: tya
jsr SF_SelectReg jsr SF_SelectReg
@ -385,24 +407,24 @@ AYPostProc:
.ay_loop: .ay_loop:
; Select AY reg ; Select AY reg
MB1: sty CARD_BASE+SY6522_ORA MB1: sty CARD_BASE+SY6522_ORA+SY6522_A_PH_BASE
MB1b: sty CARD_BASE+SY6522_ORA+$80 MB1b: sty CARD_BASE+SY6522_ORA+$80
lda #$07 ; LATCH lda #$07 ; LATCH
MB2: sta CARD_BASE+SY6522_ORB MB2: sta CARD_BASE+SY6522_ORB+SY6522_A_PH_BASE
MB2b: sta CARD_BASE+SY6522_ORB+$80 MB2b: sta CARD_BASE+SY6522_ORB+$80
lda #$04 ; INACTIVE lda #$04 ; INACTIVE
MB3: sta CARD_BASE+SY6522_ORB MB3: sta CARD_BASE+SY6522_ORB+SY6522_A_PH_BASE
MB3b: sta CARD_BASE+SY6522_ORB+$80 MB3b: sta CARD_BASE+SY6522_ORB+$80
; Write AY reg ; Write AY reg
lda (TmpL),y lda (TmpL),y
MB4: sta CARD_BASE+SY6522_ORA MB4: sta CARD_BASE+SY6522_ORA+SY6522_A_PH_BASE
MB4b: sta CARD_BASE+SY6522_ORA+$80 MB4b: sta CARD_BASE+SY6522_ORA+$80
lda #$06 ; WRITE lda #$06 ; WRITE
MB5: sta CARD_BASE+SY6522_ORB MB5: sta CARD_BASE+SY6522_ORB+SY6522_A_PH_BASE
MB5b: sta CARD_BASE+SY6522_ORB+$80 MB5b: sta CARD_BASE+SY6522_ORB+$80
lda #$04 ; INACTIVE lda #$04 ; INACTIVE
MB6: sta CARD_BASE+SY6522_ORB MB6: sta CARD_BASE+SY6522_ORB+SY6522_A_PH_BASE
MB6b: sta CARD_BASE+SY6522_ORB+$80 MB6b: sta CARD_BASE+SY6522_ORB+$80
dey dey
@ -440,7 +462,7 @@ MB6b: sta CARD_BASE+SY6522_ORB+$80
lda #1<<6 lda #1<<6
MB7: MB7:
sta CARD_BASE+SY6522_IFR ; Clear Timer1 IRQ flag sta CARD_BASE+SY6522_IFR+SY6522_A_PH_BASE ; Clear Timer1 IRQ flag
pla pla
tay tay

View File

@ -2,6 +2,10 @@
CARD_BASE = $C100 CARD_BASE = $C100
SY6522_A_BASE = $00
SY6522_A_PH_BASE = $10 ; Phasor mode (this is common to both MB & Phasor modes)
SY6522_B_BASE = $80
SY6522_ORB = 0 SY6522_ORB = 0
SY6522_ORA = 1 SY6522_ORA = 1
SY6522_DDRB = 2 SY6522_DDRB = 2
@ -29,6 +33,7 @@ AY_EFINE = 11
AY_ECOARSE = 12 AY_ECOARSE = 12
AY_ESHAPE = 13 AY_ESHAPE = 13
AY_NOISE_MASK = $1f ; valid bits of AY_NOISEPER
AY_AMPLITUDE_MODE = $10 ; b4 of AY_xVOL (0=fixed, 1=envelope) AY_AMPLITUDE_MODE = $10 ; b4 of AY_xVOL (0=fixed, 1=envelope)
AY_ENA_A = %110110 ; Enable A (Noise & Tone) AY_ENA_A = %110110 ; Enable A (Noise & Tone)
@ -44,4 +49,9 @@ AY_RESET = 0
AY_INACTIVE = 4 AY_INACTIVE = 4
AY_READ = 5 AY_READ = 5
AY_WRITE = 6 AY_WRITE = 6
AY_LATCH = 7 AY_LATCH = 7
; Phasor mode
PH_MOCKINGBOARD = 8
PH_PHASOR = $D
PH_ECHOPLUS = $F

View File

@ -415,7 +415,7 @@ lf0f3: ; Cmd_F0
;-------------------------------------- ;--------------------------------------
lf492 = lf40a + ($f492-$f40a) lf492 = $28b2
lf0f9: ; Cmd_E2 lf0f9: ; Cmd_E2
; Pseudo random number generator ; Pseudo random number generator
@ -459,7 +459,7 @@ lf0f9_SMC_h:
lf111: ; Cmd_E3 lf111: ; Cmd_E3
lf111_SMC: lf111_SMC:
lda #$05 lda #$2a
sta RegA sta RegA
;-------------------------------------- ;--------------------------------------
@ -545,7 +545,7 @@ lf116: ; Cmd_00
bne lf156 bne lf156
; ld hl,(0f212h) ; ld hl,(0f212h)
+LDW_INDIRECT RegHL, lf1f6 ; HL = A-freq +LDW_INDIRECT RegHL, lf212
; ld (0f20ah),hl ; ld (0f20ah),hl
+LDW_INDIRECT lf20a, RegHL +LDW_INDIRECT lf20a, RegHL
@ -734,7 +734,7 @@ lf1b1:
jsr lf1c9 jsr lf1c9
; ld hl,0f1fch ; ld hl,0f1fch
+LDW RegHL, lf1fc +LDW RegHL, lf1fc ; lf1fc = AYRegValues.NOISEPER
; ld a,(hl) ; ld a,(hl)
+LD_REG_INDIRECT RegA, RegHL +LD_REG_INDIRECT RegA, RegHL
@ -758,13 +758,13 @@ lf1b1:
+RET_C +RET_C
; inc hl ; inc hl
+INCW RegHL +INCW RegHL ; lf1fd = AYRegValues.ENABLE
; ld a,(hl) ; ld a,(hl)
+LD_REG_INDIRECT RegA, RegHL +LD_REG_INDIRECT RegA, RegHL
; or 38h ; or 38h
ora #$38 ora #$38 ; ENABLE |= 0x38 (disable noise CBA)
sta RegA sta RegA
; ld (hl),a ; ld (hl),a
@ -791,8 +791,15 @@ lf1c9:
; inc (hl) ; inc (hl)
+INC_INDIRECT RegHL +INC_INDIRECT RegHL
lda RegD ; $00nn?
bne +
lda #$f3 ; 48K ROM $0000
sta RegA
bne ++ ; branch always
+
; ld a,(de) ; ld a,(de)
+LD_REG_INDIRECT RegA, RegDE +LD_REG_INDIRECT RegA, RegDE
++
; sub (hl) ; sub (hl)
+SUB_INDIRECT RegHL +SUB_INDIRECT RegHL
@ -813,8 +820,15 @@ lf1c9:
; inc de ; inc de
+INCW RegDE +INCW RegDE
lda RegD ; $00nn?
bne +
lda #$af ; 48K ROM $0001
sta RegA
bne ++ ; branch always
+
; ld a,(de) ; ld a,(de)
+LD_REG_INDIRECT RegA, RegDE +LD_REG_INDIRECT RegA, RegDE
++
; ld c,a ; ld c,a
+LD RegC, RegA +LD RegC, RegA
@ -828,8 +842,15 @@ lf1c9:
; inc (hl) ; inc (hl)
+INC_INDIRECT RegHL +INC_INDIRECT RegHL
lda RegD ; $00nn?
bne +
lda #$11 ; 48K ROM $0003
sta RegA
bne ++ ; branch always
+
; ld a,(de) ; ld a,(de)
+LD_REG_INDIRECT RegA, RegDE +LD_REG_INDIRECT RegA, RegDE
++
; sub (hl) ; sub (hl)
+SUB_INDIRECT RegHL +SUB_INDIRECT RegHL
@ -902,11 +923,11 @@ SF_Detect:
ldx #7 ldx #7
.SlotNext: .SlotNext:
ldy #$00+SY6522_TIMER1L_COUNTER ldy #SY6522_TIMER1L_COUNTER+SY6522_A_PH_BASE
jsr SF_GetTimerL jsr SF_GetTimerL
bne .SlotLoop bne .SlotLoop
ldy #$80+SY6522_TIMER1L_COUNTER ldy #SY6522_TIMER1L_COUNTER+SY6522_B_BASE
jsr SF_GetTimerL jsr SF_GetTimerL
beq .SlotDone beq .SlotDone
@ -961,63 +982,67 @@ SongTbl: !byte 01 ; 0: (AY: Title/In-game)
; AY regs [0..$D] ; AY regs [0..$D]
AYRegValues: AYRegValues:
lf1f6: !word 0 ; A period lf1f6: !word $01a8 ; A period
lf1f8: !word 0 ; B period lf1f8: !word 0 ; B period
lf1fa: !word 0 ; C period lf1fa: !word 0 ; C period
lf1fc: !byte 0 ; Noise period lf1fc: !byte $2f ; Noise period
lf1fd: !byte 0 ; Enable lf1fd: !byte $3f ; Enable
lf1fe: !byte 0 ; A volume lf1fe: !byte 0 ; A volume
lf1ff: !byte 0 ; B volume lf1ff: !byte 0 ; B volume
lf200: !byte 0 ; C volume lf200: !byte 0 ; C volume
lf201: !word 0 ; Envelope period lf201: !word $0064 ; Envelope period (not used)
lf203: !byte 0 ; Envelope shape lf203: !byte $0a ; Envelope shape (not used)
;-------------------------------------- ;--------------------------------------
lf204: !word 0 ; Tone period lf204: !word 0 ; Tone period
lf206: !word 0 lf206: !word $014a
!word 0 !word $000a
;-------------------------------------- ;--------------------------------------
lf20a: !word 0 lf20a: !word 0
!word $0004
!word 0 !word 0
!word 0 !word $0012
!word 0
lf212: !word 0 lf212: !word 0
;-------------------------------------- ;--------------------------------------
!macro MUSIC_DATA_ADDR .addr {
!word lf40a + (.addr - $f40a)
}
; Voice-A struct ; Voice-A struct
lf214: !byte 0 lf214: !byte 0
!byte 2
!byte 0 !byte 0
!byte 0 !byte 0
!byte 0 +MUSIC_DATA_ADDR $f41b
!word 0 +MUSIC_DATA_ADDR $f471
!word 0
!byte 0 !byte 0
!byte 0 !byte 0
!byte 0 !byte 0
!byte 0 !byte 0
!word 0 +MUSIC_DATA_ADDR $f418
!word 0 +MUSIC_DATA_ADDR $f471
lf224: !byte 0 lf224: !byte 0
!byte 0 !byte $0a
!word 0 +MUSIC_DATA_ADDR $f65e
!word 0 +MUSIC_DATA_ADDR $f575
!word 0 +MUSIC_DATA_ADDR $f56f
!byte 0 !byte 7
!byte 0 !byte 0
!byte $08 ; 001000 - Disable A (Noise) !byte $08 ; 001000 - Disable A (Noise)
!byte $36 ; 110110 - Enable A (Noise & Tone) !byte $36 ; 110110 - Enable A (Noise & Tone)
!word lf1fe ; &VolA !word lf1fe ; &VolA
!byte $12
!byte 0 !byte 0
!byte 0 !byte $10
!byte 0 !byte $29
!byte 0 !byte 1
!byte 0
;-------------------------------------- ;--------------------------------------
@ -1086,7 +1111,8 @@ lf26a: !byte 0
;-------------------------------------- ;--------------------------------------
;lf27d: ;lf27d:
!fill 17,0 ; ? !byte $2a
!fill 16,0 ; ?
;-------------------------------------- ;--------------------------------------
@ -1101,7 +1127,9 @@ lf28e:
; . Envelopes are not used, so no E-Periods to convert ; . Envelopes are not used, so no E-Periods to convert
!macro ZX2MB .period { !macro ZX2MB .period {
!word .period*10227/17734 ; !word .period*10227/17734 ; Mockingboard 1MHz ((NTSC:14.3181818e6 / 14) / 100)
!word .period*20358/17734 ; Phasor 2MHz ((PAL:14.25045e6 / 7) / 100)
; !word .period
} }
+ZX2MB $0000 +ZX2MB $0000