4cade/src/hw.mockingboard.a

285 lines
8.8 KiB
Plaintext
Raw Normal View History

;license:MIT
2023-01-06 19:36:12 +00:00
;(c) 2019-2022 by Andrew Roughan, qkumba, 4am, Tom Charlesworth, Rob Justice
;
; Mockingboard support functions
;
;------------------------------------------------------------------------------
2020-02-28 23:33:10 +00:00
; GetMockingboardStuff
; detect Mockingboard card by searching for 6522 timers across all slots 7->1
; access 6522 timers with deterministic cycle counts
;
; based on prior art in Mockingboard Developers Toolkit
; with optimisation from deater/french touch
; also takes into account FastChip //e clock difference
;
2020-03-05 17:38:53 +00:00
; in: A/Y contains address of callback to call if card was found
; (this will be called before the speech detection routine, and
; (zp$81 will contain the slot in form $Cx)
; /!\ ALL ACCELERATORS MUST BE OFF OR SET TO 1 MHZ
; out: if card was found, X = #$?n where n is the slot number of the card, otherwise #$00
2022-04-25 22:09:50 +00:00
; and bit 5 = 0 if Mockingboard Sound I found
; or bit 5 = 1 if Mockingboard Sound II or "A"-"D" found
; and bit 6 = 1 if SSI-263 speech chip found
; or bit 7 = 1 if SC-01 speech chip found
; flags clobbered
; zp $80-$82 clobbered
; A/Y clobbered
;------------------------------------------------------------------------------
2022-10-09 20:30:15 +00:00
2022-10-10 20:58:07 +00:00
MAGIC_Z80_LOCATION=$FFD
2022-10-09 20:30:15 +00:00
2020-02-28 23:33:10 +00:00
GetMockingboardStuff
2020-03-24 20:30:14 +00:00
+ST16 @callback+1
2022-10-09 20:30:15 +00:00
2022-11-09 23:36:58 +00:00
lda ROM_MACHINEID
cmp #$06
bne @not_iic
ldx ROM_MACHINE2C
bne @not_iic
2022-10-09 20:30:15 +00:00
; from mgcaret
; https://github.com/a2-4am/4cade/issues/483
; the Mockingboard init can accidentally enable the Softcard Z80
; and can crash the machine
2022-10-10 20:58:07 +00:00
; solved by loading a small Z80 routine at $0FFD (FFFDh in the Z80 space):
; $32 $00 $E4 $C3 FD FF which is
; NOP
2022-10-09 20:30:15 +00:00
; LD (E400h),A ; card is at $E400 due to memory translation
2022-10-10 20:58:07 +00:00
; JP FFFDh
2022-10-09 20:30:15 +00:00
; returns the system to 6502 mode and leaves it in the same state as the Z80 after RESET:
; ready to execute the instruction at 0000h (from the Z80 perspective)
ldx #5
- lda magic_z80_bytes, x
sta MAGIC_Z80_LOCATION, x
dex
bpl -
2022-11-09 23:36:58 +00:00
stx $C403 ; enable Mockingboard 4C support
2022-04-28 04:48:02 +00:00
stx $C404
@not_iic
lda #$00
sta $80
2020-02-28 23:33:10 +00:00
sta $82 ; type
ldx #$C1
@slotLoop
stx $81
ldy #$04 ; 6522 #1 $Cx04
2020-02-28 23:33:10 +00:00
jsr @timercheck
2020-07-27 03:35:42 +00:00
bcc @foundI
2020-02-28 23:33:10 +00:00
@nextSlot
inx
cpx #$C8
bne @slotLoop
ldx #$00 ; not found
rts
2020-02-28 23:33:10 +00:00
@foundI ; sound I or better
2020-03-05 17:38:53 +00:00
jsr @callback
2020-02-28 23:33:10 +00:00
ldy #$84 ; 6522 #2 $Cx84
jsr @timercheck
2020-07-27 03:35:42 +00:00
bcc @foundII
2020-02-28 23:33:10 +00:00
ldy #$0c
2020-05-13 17:24:35 +00:00
sty @mb_smc1 + 1
2020-02-28 23:33:10 +00:00
iny
2020-05-18 15:21:16 +00:00
sty @mb_smc10 + 1
2020-02-28 23:33:10 +00:00
iny
2020-05-13 17:24:35 +00:00
sty @mb_smc5 + 1
2020-05-18 15:21:16 +00:00
sty @mb_smc14 + 1
2020-08-09 05:19:54 +00:00
clc
2020-02-28 23:33:10 +00:00
2020-08-09 05:19:54 +00:00
+HIDE_NEXT_BYTE
2020-02-28 23:33:10 +00:00
@foundII ;stereo
2020-08-09 05:19:54 +00:00
sec
2020-02-28 23:33:10 +00:00
ror $82
lda $81
sta @mb_smc1 + 2
sta @mb_smc2 + 2
sta @mb_smc3 + 2
sta @mb_smc4 + 2
sta @mb_smc5 + 2
sta @mb_smc6 + 2
sta @mb_smc7 + 2
sta @mb_smc8 + 2
sta @mb_smc9 + 2
sta @mb_smc10 + 2
sta @mb_smc11 + 2
sta @mb_smc12 + 2
2020-05-18 15:21:16 +00:00
sta @mb_smc13 + 2
sta @mb_smc14 + 2
sta @mb_smc15 + 2
sta @mb_smc17 + 2
sta @mb_smc18 + 2
sta @mb_smc19 + 2
sta @mb_smc20 + 2
sta @mb_smc21 + 2
sta @mb_smc22 + 2
2020-02-28 23:33:10 +00:00
; detect speech - SSI263
2020-02-28 23:33:10 +00:00
sei
2020-07-27 03:35:42 +00:00
+READ_RAM2_WRITE_RAM2
lda #$40 ; setup NMI vector (rti)
2020-07-27 04:24:18 +00:00
sta $3fb
lda #$fb
sta $fffa
lda #3
sta $fffb
lda #<@mb_irq ; setup IRQ vector
2020-02-28 23:33:10 +00:00
sta $3fe
sta $fffe
lda #>@mb_irq
sta $3ff
sta $ffff
lda #$0c ; CB2 - input neg edge, CB1 neg edge, CA2 low output, CA1 neg edge
2020-05-13 17:24:35 +00:00
@mb_smc1
sta $c48c ; peripheral control register 6522#2
lda #$80 ; ctl=1
2020-05-13 17:24:35 +00:00
@mb_smc2
sta $c443 ; C = SSI reg 3, S/S I or A = 6522#1 ddr a
lda #$c0 ; duration=11 phoneme=000000 (pause)
2020-05-13 17:24:35 +00:00
@mb_smc3
sta $c440 ; C = SSI reg 0, S/S I or A = 6522#1 port b data
lda #$70 ; ctl=0 (A/R active - phoneme timing response)
2020-05-13 17:24:35 +00:00
@mb_smc4
sta $c443 ; C = SSI reg 3, S/S I or A = 6522#1 ddr a
lda #$82 ; enable CA1 interrupt
2020-05-13 17:24:35 +00:00
@mb_smc5
sta $c48e ; interrupt enable register 6522#2
2020-02-28 23:33:10 +00:00
ldx #$80 ; 0= ~650ms, 80 = ~325ms
2020-02-28 23:33:10 +00:00
ldy #0
sec
cli
@wait_irq
lda $80
2022-04-25 22:09:50 +00:00
bne +
2020-02-28 23:33:10 +00:00
iny
bne @wait_irq
inx
bne @wait_irq
2022-04-25 22:09:50 +00:00
clc
+ ror $82
; detect speech - SC-01
;based on S/S I demo dsk
;init sc-01 interface
lda #$ff
@mb_smc15
sta $c402 ; ddr portb - all outputs
lda #$b0 ; cb2 pulse output,cb1 pos edge
@mb_smc17
sta $c40c ; pcr
lda #$10 ; clear all interrupt flags
@mb_smc18
sta $c40d ; ifr
;output stop phoneme
lda #$3f ; stop
@mb_smc19
sta $c400 ; orb, write phoneme & pitch
ldx #$D0 ; wait ~120ms, stop takes 47ms
- lda #$10
@mb_smc20
bit $c40d ; ifr, check for cb1 interrupt flag
bne + ; flag set, we found one
iny
bne -
inx
bne -
2022-04-25 22:09:50 +00:00
beq @got_irq
@mb_smc21
+ sta $c40d ; ifr, clear flag
2020-08-26 02:17:38 +00:00
lda #$00 ; turn off cb2 pulse mode to disable false writes to sc01
@mb_smc22
sta $c40c ; pcr
2022-04-25 22:09:50 +00:00
sec ; found, we have an SC-01
ror $82
2022-04-25 22:09:50 +00:00
bne @ssI
2020-02-28 23:33:10 +00:00
@got_irq
sei
2022-04-25 22:09:50 +00:00
clc ; not found
2020-02-28 23:33:10 +00:00
ror $82
2020-05-13 17:24:35 +00:00
ldy #$ff
@mb_smc6
sty $c403 ; 6522#1 ddra
2020-05-13 17:24:35 +00:00
lda #7
@mb_smc7
sta $c402 ; 6522#1 ddrb
iny
sty $80
tya
sta ($80),y ; 6522#1 orb
lda #4
sta ($80),y ; 6522#1 orb
2022-04-25 22:09:50 +00:00
@ssI
2022-04-25 22:09:50 +00:00
ldy #$ff
2020-05-18 15:21:16 +00:00
@mb_smc8
sty $c483 ; 6522#2 ddra
lda #7
2020-05-18 15:21:16 +00:00
@mb_smc9
sta $c482 ; 6522#2 ddrb
2022-04-25 22:09:50 +00:00
lda #0
ldy #$80
sta ($80),y ; 6522#2 orb
lda #4
sta ($80),y ; 6522#2 orb
2020-05-13 17:24:35 +00:00
lda #7
2020-05-18 15:21:16 +00:00
and $81
2020-02-28 23:33:10 +00:00
ora $82
tax
lda #<Ignore
sta $fffe
lda #>Ignore
sta $ffff
2020-07-27 03:35:42 +00:00
+READ_ROM_NO_WRITE
2020-05-11 16:58:22 +00:00
2020-02-28 23:33:10 +00:00
rts ; found
@timercheck
sec
2020-02-28 23:33:10 +00:00
lda ($80),y ; read 6522 timer low byte
sbc ($80),y ; second time
2020-07-27 03:35:42 +00:00
sec
sbc #5 ; looking for 5 cycles between reads
cmp #2 ; or 6 cycles with the FastChip //e
rts
2020-02-28 23:33:10 +00:00
@mb_irq
lda #2 ; clear CA1 interrupt flag
2020-05-18 15:21:16 +00:00
@mb_smc10
sta $c48d ; interrupt flag register 6522#2
lda #$80 ; ctl=1
2020-05-18 15:21:16 +00:00
@mb_smc11
sta $c443 ; C = SSI reg 3, S/S I or A = 6522#1 ddr a
lda #0 ; duration=00 phoneme=000000 (pause)
2020-05-18 15:21:16 +00:00
@mb_smc12
sta $c440 ; C = SSI reg 0, S/S I or A = 6522#1 port b data
lda #$70 ; ctl=0 (A/R active - phoneme timing response)
2020-05-18 15:21:16 +00:00
@mb_smc13
sta $c443 ; C = SSI reg 3, S/S I or A = 6522#1 ddr a
sta $80 ; found
lda #2 ; disable CA1 interrupt
2020-05-18 15:21:16 +00:00
@mb_smc14
sta $c48e ; interrupt enable register 6522#2
2020-02-28 23:33:10 +00:00
lda $45
rti
2020-03-05 17:38:53 +00:00
@callback
jmp $FDFD ; SMC
2022-10-09 20:30:15 +00:00
magic_z80_bytes
2022-10-10 21:06:27 +00:00
!byte $32, $00, $E4, $C3, $FD, $FF