Cybernoid/Common/MB-Macros.a

475 lines
7.7 KiB
Plaintext

SPECTRUM128_STEREO = 1 ; L = A+Bx0.5, R = C'+B'x0.5
DUAL_MONO = 0 ; L = A+B+C, R=A'+B'+C'
USE_PHASOR = 1
!macro MB_Init1 .RegSongNum {
; Pre: A = Song# [0..NUM_SONGS-1]
; Post: .RegSongNum = Song#
;
jmp .skip_data
nSongNum: !byte 0 ; Song#
nFrameNum: !byte 0,0,0 ; Minute:Second:FrameNum (@ 50Hz)
;
nMaskA: !byte 0 ; Voice-A mask (0=enable)
nMaskB: !byte 0 ; Voice-B mask (0=enable)
nMaskC: !byte 0 ; Voice-C mask (0=enable)
;
nAttA: !byte 0 ; Attenuation of Voice-A
nAttB: !byte 1 ; Attenuation of Voice-B : B Volume / 2 (logarithmic, so: if (B) B--)
nAttC: !byte 0 ; Attenuation of Voice-C
;
pAYRegValues: !word AYRegValues ; For VU-meter
;
.skip_data:
lda nSongNum
cmp #NUM_SONGS
bcc SongNumOK
lda #255 ; Uninit
sta nSongNum
SongNumOK:
;
lda nMBBaseHi
beq FindMB
; Need to disable Timer1 IRQ before:
; . Scanning for MB card
; . Saving ZPBlock
lda #1<<6
MB0: sta CARD_BASE+SY6522_IER+SY6522_A_PH_BASE ; Disable Timer1 IRQ
FindMB:
;----------------------------------
+SaveRegs ZPBlock
jsr SF_GetMBSlot
bne GotMBSlot
; MB not found!
jmp InitExit2
GotMBSlot:
; Setup correct address in IRQ handler code:
!if SPECTRUM128_STEREO {
stx MBx1+2
stx MBx2+2
stx MBx3+2
stx MBx4+2
}
!if DUAL_MONO {
stx MB1+2
stx MB1b+2
stx MB2+2
stx MB2b+2
stx MB3+2
stx MB3b+2
stx MB4+2
stx MB4b+2
stx MB5+2
stx MB5b+2
stx MB6+2
stx MB6b+2
}
stx MB0+2
stx MB7+2
stx nMBBaseHi
;
!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
}
ldy #SY6522_DDRB+SY6522_A_PH_BASE
sta (MBBase),y
ldy #SY6522_DDRB+SY6522_B_BASE
sta (MBBase),y
lda #$ff
ldy #SY6522_DDRA+SY6522_A_PH_BASE
sta (MBBase),y
ldy #SY6522_DDRA+SY6522_B_BASE
sta (MBBase),y
lda #AY_RESET ; Phasor chip-select b4:3=%00 (so select both AY's)
ldy #SY6522_ORB+SY6522_A_PH_BASE
sta (MBBase),y
ldy #SY6522_ORB+SY6522_B_BASE
sta (MBBase),y
ldx nSongNum
cpx #255
bne NotFini
jmp InitExit
NotFini:
lda SongTbl,x
sta .RegSongNum
}
;--------------------------------------
!macro MB_Init2 {
lda #0
sta nFrameNum+0
sta nFrameNum+1
sta nFrameNum+2
; Setup Timer1 IRQ to trigger at 50Hz
; Apple NTSC CLK = 1.022727 MHz, so set Timer1=0x4fe7
sei
lda #$e7
ldy #SY6522_TIMER1L_COUNTER+SY6522_A_PH_BASE
sta (MBBase),y
lda #$4f
ldy #SY6522_TIMER1H_COUNTER+SY6522_A_PH_BASE
sta (MBBase),y
lda #1<<6
ldy #SY6522_ACR+SY6522_A_PH_BASE
sta (MBBase),y ; Free running timer
lda #1<<7 | 1<<6
ldy #SY6522_IER+SY6522_A_PH_BASE
sta (MBBase),y ; Enable Timer1 IRQ
lda #<Interrupt ; ADDR_L
sta IRQL
lda #>Interrupt ; ADDR_H
sta IRQH
InitExit:
cli
+SaveRegs Z80Block
InitExit2:
+RestoreRegs ZPBlock
}
;--------------------------------------
!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:
!macro SF_UpdateAY {
SF_SelectReg:
MBx1: sta CARD_BASE+SY6522_ORA,x
lda #AY_LATCH | PHASOR_CS_MASK
bne .l675e
SF_WriteReg:
MBx2: sta CARD_BASE+SY6522_ORA,x
lda #AY_WRITE | PHASOR_CS_MASK
bne .l675e
SF_ChipReset:
lda #AY_RESET | PHASOR_CS_MASK
.l675e:
MBx3: sta CARD_BASE+SY6522_ORB,x
lda #AY_INACTIVE | PHASOR_CS_MASK
MBx4: sta CARD_BASE+SY6522_ORB,x
rts
}
;--------------------------------------
!if SPECTRUM128_STEREO {
; L = A+Bx0.5, R = C'+B'x0.5
;
!macro MB_WriteAYRegs .ay_regs_base {
; Enable SLOTXROM while accessing MB regs
lda SW_SLOTXROM_R
pha
bpl .ay_init ; branch if b7=0 (enabled)
sta SW_SLOTXROM_ENA
.ay_init:
ldy #$0D
.ay_loop:
lda .ay_regs_base,y
cpy #AY_ENABLE
bne .ay_cont
tax ; Save AY_ENABLE
ora #AY_DIS_C
sta .ay0_regs,y
txa ; Restore AY_ENABLE
ora #AY_DIS_A
sta .ay1_regs,y
dey
bpl .ay_loop ; branch always taken
;
.ay_cont:
sta .ay0_regs,y
sta .ay1_regs,y
dey
bpl .ay_loop
;
; Post processing
AYPostProc:
lda #0
sta .ay1_regs+AY_AVOL
sta .ay0_regs+AY_CVOL
;
; Attenuate AVOL
; lda .ay_regs_base+AY_AVOL
; and #AY_AMPLITUDE_MODE
; bne + ; don't attenuate if amp.mode=envelope (Cybernoid doesn't use envelopes)
lda .ay_regs_base+AY_AVOL
sec
sbc nAttA
bpl .ay_set_a_vol
lda #0
.ay_set_a_vol
sta .ay0_regs+AY_AVOL
+
;
; Attenuate BVOL
; lda .ay_regs_base+AY_BVOL
; and #AY_AMPLITUDE_MODE
; bne + ; don't attenuate if amp.mode=envelope (Cybernoid doesn't use envelopes)
lda .ay_regs_base+AY_BVOL
sec
sbc nAttB
bpl .ay_set_b_vol
lda #0
.ay_set_b_vol
sta .ay0_regs+AY_BVOL
sta .ay1_regs+AY_BVOL
+
;
; Attenuate CVOL
; lda .ay_regs_base+AY_CVOL
; and #AY_AMPLITUDE_MODE
; bne + ; don't attenuate if amp.mode=envelope (Cybernoid doesn't use envelopes)
lda .ay_regs_base+AY_CVOL
sec
sbc nAttC
bpl .ay_set_c_vol
lda #0
.ay_set_c_vol
sta .ay1_regs+AY_CVOL
+
;
; User disable A/B/C
.ay_chk_maska:
lda nMaskA
beq .ay_chk_maskb
lda #0
sta .ay0_regs+AY_AVOL
lda .ay0_regs+AY_ENABLE
ora #AY_DIS_A
sta .ay0_regs+AY_ENABLE
.ay_chk_maskb:
lda nMaskB
beq .ay_chk_maskc
lda #0
sta .ay0_regs+AY_BVOL
sta .ay1_regs+AY_BVOL
lda .ay0_regs+AY_ENABLE
ora #AY_DIS_B
sta .ay0_regs+AY_ENABLE
lda .ay1_regs+AY_ENABLE
ora #AY_DIS_B
sta .ay1_regs+AY_ENABLE
.ay_chk_maskc:
lda nMaskC
beq .ay_chk_mask_done
lda #0
sta .ay1_regs+AY_CVOL
lda .ay1_regs+AY_ENABLE
ora #AY_DIS_C
sta .ay1_regs+AY_ENABLE
.ay_chk_mask_done:
;
ldx #SY6522_A_PH_BASE ; Works for both MB & Phasor modes
ldy #$0D
.sf_loop0: tya
jsr SF_SelectReg
lda .ay0_regs,y
jsr SF_WriteReg
dey
bpl .sf_loop0
;
ldx #SY6522_B_BASE
ldy #$0D
.sf_loop1: tya
jsr SF_SelectReg
lda .ay1_regs,y
jsr SF_WriteReg
dey
bpl .sf_loop1
; Disable SLOTXROM if necessary
pla
bpl .ay_done ; branch if b7=0 (enabled)
sta SW_SLOTXROM_DIS
bmi .ay_done ; branch always taken
;--------------
.ay0_regs: !fill 14,0
.ay1_regs: !fill 14,0
+SF_UpdateAY
;--------------
.ay_done:
}
} ; !if SPECTRUM128_STEREO
;------------------
!if DUAL_MONO {
; L = A+B+C, R=A'+B'+C'
;
!macro MB_WriteAYRegs .ay_regs_base {
; Enable SLOTXROM while accessing MB regs
lda SW_SLOTXROM_R
pha
bpl .ay_init ; branch if b7=0 (enabled)
sta SW_SLOTXROM_ENA
.ay_init:
ldy #$0D
lda #<.ay_regs_base
sta TmpL
lda #>.ay_regs_base
sta TmpH
.ay_loop:
; Select AY reg
MB1: sty CARD_BASE+SY6522_ORA+SY6522_A_PH_BASE
MB1b: sty CARD_BASE+SY6522_ORA+$80
lda #$07 ; LATCH
MB2: sta CARD_BASE+SY6522_ORB+SY6522_A_PH_BASE
MB2b: sta CARD_BASE+SY6522_ORB+$80
lda #$04 ; INACTIVE
MB3: sta CARD_BASE+SY6522_ORB+SY6522_A_PH_BASE
MB3b: sta CARD_BASE+SY6522_ORB+$80
; Write AY reg
lda (TmpL),y
MB4: sta CARD_BASE+SY6522_ORA+SY6522_A_PH_BASE
MB4b: sta CARD_BASE+SY6522_ORA+$80
lda #$06 ; WRITE
MB5: sta CARD_BASE+SY6522_ORB+SY6522_A_PH_BASE
MB5b: sta CARD_BASE+SY6522_ORB+$80
lda #$04 ; INACTIVE
MB6: sta CARD_BASE+SY6522_ORB+SY6522_A_PH_BASE
MB6b: sta CARD_BASE+SY6522_ORB+$80
dey
bpl .ay_loop
; Disable SLOTXROM if necessary
pla
bpl .ay_done ; branch if b7=0 (enabled)
sta SW_SLOTXROM_DIS
.ay_done:
}
} ; !if DUAL_MONO
;--------------------------------------
!macro MB_ISR .isr_main {
; Pre:
; 6502 has pushed P
; Apple ROM has stored A to $45 (not Apple //e ROM!)
;
txa
pha
tya
pha
+SaveRegs ZPBlock
+RestoreRegs Z80Block
jsr .isr_main
+SaveRegs Z80Block
+RestoreRegs ZPBlock
lda #1<<6
MB7:
sta CARD_BASE+SY6522_IFR+SY6522_A_PH_BASE ; Clear Timer1 IRQ flag
pla
tay
pla
tax
lda $45
rti
}