diff --git a/mode7_demo/Makefile b/mode7_demo/Makefile index f0eafaa0..2854f4b9 100644 --- a/mode7_demo/Makefile +++ b/mode7_demo/Makefile @@ -42,7 +42,7 @@ mode7_demo.o: mode7_demo.s mode7_demo_backgrounds.inc sprites.inc \ ../asm_routines/gr_fade.s \ ../asm_routines/gr_copy.s \ ../asm_routines/gr_scroll.s \ - ../asm_routines/mockingboard_a.s \ + mockingboard.s \ credits.s mode7.s rasterbars.s starfield_demo.s \ interrupt_handler.s \ zp.inc diff --git a/mode7_demo/mockingboard.s b/mode7_demo/mockingboard.s new file mode 100644 index 00000000..e09d0b05 --- /dev/null +++ b/mode7_demo/mockingboard.s @@ -0,0 +1,162 @@ +; Mockingboad programming: +; + Has two 6522 I/O chips connected to two AY-3-8910 chips +; + Optionally has some speech chips controlled via the outport on the AY +; + Often in slot 4 +; TODO: how to auto-detect? +; References used: +; http://macgui.com/usenet/?group=2&id=8366 +; 6522 Data Sheet +; AY-3-8910 Data Sheet + +;======================== +; Mockingboard card +; Essentially two 6522s hooked to the Apple II bus +; Connected to AY-3-8910 chips +; PA0-PA7 on 6522 connected to DA0-DA7 on AY +; PB0 on 6522 connected to BC1 +; PB1 on 6522 connected to BDIR +; PB2 on 6522 connected to RESET + + +; left speaker +MOCK_6522_ORB1 EQU $C400 ; 6522 #1 port b data +MOCK_6522_ORA1 EQU $C401 ; 6522 #1 port a data +MOCK_6522_DDRB1 EQU $C402 ; 6522 #1 data direction port B +MOCK_6522_DDRA1 EQU $C403 ; 6522 #1 data direction port A + +; right speaker +MOCK_6522_ORB2 EQU $C480 ; 6522 #2 port b data +MOCK_6522_ORA2 EQU $C481 ; 6522 #2 port a data +MOCK_6522_DDRB2 EQU $C482 ; 6522 #2 data direction port B +MOCK_6522_DDRA2 EQU $C483 ; 6522 #2 data direction port A + +; AY-3-8910 commands on port B +; RESET BDIR BC1 +MOCK_AY_RESET EQU $0 ; 0 0 0 +MOCK_AY_INACTIVE EQU $4 ; 1 0 0 +MOCK_AY_READ EQU $5 ; 1 0 1 +MOCK_AY_WRITE EQU $6 ; 1 1 0 +MOCK_AY_LATCH_ADDR EQU $7 ; 1 1 1 + + + ;======================== + ; Mockingboard Init + ;======================== + ; Initialize the 6522s + ; set the data direction for all pins of PortA/PortB to be output + +mockingboard_init: + lda #$ff ; all output (1) + sta MOCK_6522_DDRB1 + sta MOCK_6522_DDRA1 + sta MOCK_6522_DDRB2 + sta MOCK_6522_DDRA2 + rts + + ;====================== + ; Reset Left AY-3-8910 + ;====================== +reset_ay_both: + lda #MOCK_AY_RESET + sta MOCK_6522_ORB1 + lda #MOCK_AY_INACTIVE + sta MOCK_6522_ORB1 + + ;====================== + ; Reset Right AY-3-8910 + ;====================== +;reset_ay_right: + lda #MOCK_AY_RESET + sta MOCK_6522_ORB2 + lda #MOCK_AY_INACTIVE + sta MOCK_6522_ORB2 + rts + + +; Write sequence +; Inactive -> Latch Address -> Inactive -> Write Data -> Inactive + + ;========================================= + ; Write Right/Left to save value AY-3-8910 + ;========================================= + ; register in X + ; value in MB_VALUE + +write_ay_both: + ; address + stx MOCK_6522_ORA1 ; put address on PA1 ; 3 + stx MOCK_6522_ORA2 ; put address on PA2 ; 3 + lda #MOCK_AY_LATCH_ADDR ; latch_address on PB1 ; 2 + sta MOCK_6522_ORB1 ; latch_address on PB1 ; 3 + sta MOCK_6522_ORB2 ; latch_address on PB2 ; 3 + lda #MOCK_AY_INACTIVE ; go inactive ; 2 + sta MOCK_6522_ORB1 ; 3 + sta MOCK_6522_ORB2 ; 3 + + ; value + lda MB_VALUE ; 3 + sta MOCK_6522_ORA1 ; put value on PA1 ; 3 + sta MOCK_6522_ORA2 ; put value on PA2 ; 3 + lda #MOCK_AY_WRITE ; ; 2 + sta MOCK_6522_ORB1 ; write on PB1 ; 3 + sta MOCK_6522_ORB2 ; write on PB2 ; 3 + lda #MOCK_AY_INACTIVE ; go inactive ; 2 + sta MOCK_6522_ORB1 ; 3 + sta MOCK_6522_ORB2 ; 3 + + rts ; 6 + ;=========== + ; 53 + ;======================================= + ; clear ay -- clear all 14 AY registers + ; should silence the card + ;======================================= +clear_ay_both: + ldx #14 + lda #0 + sta MB_VALUE +clear_ay_left_loop: + jsr write_ay_both + dex + bpl clear_ay_left_loop + rts + + ;======================================= + ; Detect a Mockingboard card in Slot4 + ;======================================= + ; Based on code from the French Touch "Pure Noise" Demo + ; Attempts to time an instruction sequence with a 6522 + ; + ; MB_ADDRL:MB_ADDRH has address of Mockingboard + ; returns X=0 if not found, X=1 if found + +mockingboard_detect_slot4: + lda #0 + sta MB_ADDRL + +mb4_detect_loop: ; self-modifying + lda #$04 ; we're only looking in Slot 4 + ora #$C0 ; make it start with C + sta MB_ADDRH + ldy #04 ; $CX04 + ldx #02 ; 2 tries? +mb4_check_cycle_loop: + lda (MB_ADDRL),Y ; timer 6522 (Low Order Counter) + ; count down + sta TEMP ; 3 cycles + lda (MB_ADDRL),Y ; + 5 cycles = 8 cycles + ; between the two accesses to the timer + sec + sbc TEMP ; subtract to see if we had 8 cycles + cmp #$f8 ; -8 + bne mb4_not_in_this_slot + dex ; decrement, try one more time + bne mb4_check_cycle_loop ; loop detection + inx ; Mockingboard found (X=1) +done_mb4_detect: + rts ; return + +mb4_not_in_this_slot: + ldx #00 + beq done_mb4_detect + diff --git a/mode7_demo/mode7_demo.s b/mode7_demo/mode7_demo.s index d75d60ae..d68281a7 100644 --- a/mode7_demo/mode7_demo.s +++ b/mode7_demo/mode7_demo.s @@ -32,28 +32,23 @@ start: lda $ACD5 ; $ad,$d5,$ac sta $0,X ; $95,$00 - ;================================ - ; Mockingboard detect - ;================================ - - jsr mockingboard_detect_slot4 ; call detection routine - stx MB_DETECTED - beq mockingboard_setup_done - - ;================================ ; one-time setup ;================================ ; Initialize the 2kB of multiply lookup tables jsr init_multiply_tables + ;================================ + ; Mockingboard detect + ;================================ + + jsr mockingboard_detect_slot4 ; call detection routine + stx MB_DETECTED ;================================ ; Mockingboard start ;================================ - - mockingboard_setup: sei ; disable interrupts just in case @@ -99,6 +94,9 @@ mockingboard_setup: ; Start Playing ;============================ main_loop: + lda MB_DETECTED + beq mockingboard_setup_done + lda #0 sta DONE_PLAYING sta WHICH_CHUNK @@ -330,7 +328,7 @@ title_routine: .include "rasterbars.s" .include "starfield_demo.s" -.include "../asm_routines/mockingboard_a.s" +.include "mockingboard.s" .include "credits.s" .include "interrupt_handler.s"