From 4f89601053c53dbf9e7a9c9e99d43adac882a2b0 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Sat, 28 Dec 2019 18:04:19 -0500 Subject: [PATCH] pt3_lib: update the detection code --- pt3_lib/Makefile | 2 +- pt3_lib/pt3_lib_mockingboard_detect.s | 196 ++++++++++++++++++ ...ngboard.s => pt3_lib_mockingboard_setup.s} | 130 +----------- pt3_lib/pt3_test.s | 20 +- pt3_lib/zp.inc | 6 +- 5 files changed, 219 insertions(+), 135 deletions(-) create mode 100644 pt3_lib/pt3_lib_mockingboard_detect.s rename pt3_lib/{pt3_lib_mockingboard.s => pt3_lib_mockingboard_setup.s} (64%) diff --git a/pt3_lib/Makefile b/pt3_lib/Makefile index 4c1c5f1b..6f16cde5 100644 --- a/pt3_lib/Makefile +++ b/pt3_lib/Makefile @@ -23,7 +23,7 @@ PT3_TEST: pt3_test.o pt3_test.o: pt3_test.s \ pt3_lib_init.s pt3_lib_core.s pt3_lib_irq_handler.s \ - pt3_lib_mockingboard.s \ + pt3_lib_mockingboard_detect.s pt3_lib_mockingboard_setup.s \ interrupt_handler.s zp.inc ca65 -o pt3_test.o pt3_test.s -l pt3_test.lst # diff --git a/pt3_lib/pt3_lib_mockingboard_detect.s b/pt3_lib/pt3_lib_mockingboard_detect.s new file mode 100644 index 00000000..a5cff3e9 --- /dev/null +++ b/pt3_lib/pt3_lib_mockingboard_detect.s @@ -0,0 +1,196 @@ +;=================================================================== +; code to detect mockingboard +;=================================================================== +; this isn't always easy +; my inclination is to just assume slot #4 but that isn't always realistic + +; code below based on "hw.mockingboard.a" from "Total Replay" + +;license:MIT +; By Andrew Roughan +; in the style of 4am for Total Replay +; +; Mockingboard support functions +; + +;------------------------------------------------------------------------------ +; HasMockingboard +; detect Mockingboard card by searching for 6522 timers across all slots +; 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 +; +; in: none +; accelerators should be off +; out: C set if Mockingboard found in any slot +; if card was found, X = #$Cn where n is the slot number of the card +; C clear if no Mockingboard found +; other flags clobbered +; zp $85-$87 clobbered +; A/Y clobbered +;------------------------------------------------------------------------------ + +mockingboard_detect: + lda #$00 + sta MB_ADDR_L + ldx #$C7 ; start at slot #7 +mb_slot_loop: + stx MB_ADDR_H + ldy #$04 ; 6522 #1 $Cx04 + jsr mb_timer_check + bne mb_next_slot + ldy #$84 ; 6522 #2 $Cx84 + jsr mb_timer_check + bne mb_next_slot +mb_found: + sec ; found + rts + +mb_next_slot: + dex + cpx #$C0 + bne mb_slot_loop + + clc ; not found + rts + +mb_timer_check: + lda (MB_ADDR_L),Y ; read 6522 timer low byte + sta MB_VALUE + lda (MB_ADDR_L),Y ; second time + sec + sbc MB_VALUE + cmp #$F8 ; looking for (-)8 cycles between reads + beq mb_timer_check_done + cmp #$F7 ; FastChip //e clock is different +mb_timer_check_done: + rts + + + +.if 0 + + + ;======================================= + ; Detect a Mockingboard card + ;======================================= + ; Based on code from the French Touch "Pure Noise" Demo + ; Attempts to time an instruction sequence with a 6522 + ; + ; If found, puts in bMB + ; MB_ADDRL:MB_ADDRH has address of Mockingboard + ; returns X=0 if not found, X=1 if found + +mockingboard_detect: + lda #0 + sta MB_ADDRL + +mb_detect_loop: ; self-modifying + lda #$07 ; we start in slot 7 ($C7) and go down to 0 ($C0) + ora #$C0 ; make it start with C + sta MB_ADDRH + ldy #04 ; $CX04 + ldx #02 ; 2 tries? +mb_check_cycle_loop: + lda (MB_ADDRL),Y ; timer 6522 (Low Order Counter) + ; count down + sta PT3_TEMP ; 3 cycles + lda (MB_ADDRL),Y ; + 5 cycles = 8 cycles + ; between the two accesses to the timer + sec + sbc PT3_TEMP ; subtract to see if we had 8 cycles + cmp #$f8 ; -8 + bne mb_not_in_this_slot + dex ; decrement, try one more time + bne mb_check_cycle_loop ; loop detection + inx ; Mockingboard found (X=1) +done_mb_detect: + ;stx bMB ; store result to bMB + rts ; return + +mb_not_in_this_slot: + dec mb_detect_loop+1 ; decrement the "slot" (self_modify) + bne mb_detect_loop ; loop down to one + ldx #00 + beq done_mb_detect + +;alternative MB detection from Nox Archaist +; lda #$04 +; sta MB_ADDRL +; ldx #$c7 +; +;find_mb: +; stx MB_ADDRH +; +; ;detect sound I +; +; sec +; ldy #$00 +; lda (MB_ADDRL), y +; sbc (MB_ADDRL), y +; cmp #$05 +; beq found_mb +; dex +; cpx #$c0 +; bne find_mb +; ldx #$00 ;no mockingboard found +; rts +; +;found_mb: +; ldx #$01 ;mockingboard found +; rts +; +; ;optionally detect sound II +; +; sec +; ldy #$80 +; lda (MB_ADDRL), y +; sbc (MB_ADDRL), y +; cmp #$05 +; beq found_mb + + + ;======================================= + ; 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 PT3_TEMP ; 3 cycles + lda (MB_ADDRL),Y ; + 5 cycles = 8 cycles + ; between the two accesses to the timer + sec + sbc PT3_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 + + + +.endif diff --git a/pt3_lib/pt3_lib_mockingboard.s b/pt3_lib/pt3_lib_mockingboard_setup.s similarity index 64% rename from pt3_lib/pt3_lib_mockingboard.s rename to pt3_lib/pt3_lib_mockingboard_setup.s index 0e9547b4..ce0af33b 100644 --- a/pt3_lib/pt3_lib_mockingboard.s +++ b/pt3_lib/pt3_lib_mockingboard_setup.s @@ -121,129 +121,11 @@ clear_ay_left_loop: bpl clear_ay_left_loop rts - ;======================================= - ; Detect a Mockingboard card - ;======================================= - ; Based on code from the French Touch "Pure Noise" Demo - ; Attempts to time an instruction sequence with a 6522 - ; - ; If found, puts in bMB - ; MB_ADDRL:MB_ADDRH has address of Mockingboard - ; returns X=0 if not found, X=1 if found - -mockingboard_detect: - lda #0 - sta MB_ADDRL - -mb_detect_loop: ; self-modifying - lda #$07 ; we start in slot 7 ($C7) and go down to 0 ($C0) - ora #$C0 ; make it start with C - sta MB_ADDRH - ldy #04 ; $CX04 - ldx #02 ; 2 tries? -mb_check_cycle_loop: - lda (MB_ADDRL),Y ; timer 6522 (Low Order Counter) - ; count down - sta PT3_TEMP ; 3 cycles - lda (MB_ADDRL),Y ; + 5 cycles = 8 cycles - ; between the two accesses to the timer - sec - sbc PT3_TEMP ; subtract to see if we had 8 cycles - cmp #$f8 ; -8 - bne mb_not_in_this_slot - dex ; decrement, try one more time - bne mb_check_cycle_loop ; loop detection - inx ; Mockingboard found (X=1) -done_mb_detect: - ;stx bMB ; store result to bMB - rts ; return - -mb_not_in_this_slot: - dec mb_detect_loop+1 ; decrement the "slot" (self_modify) - bne mb_detect_loop ; loop down to one - ldx #00 - beq done_mb_detect - -;alternative MB detection from Nox Archaist -; lda #$04 -; sta MB_ADDRL -; ldx #$c7 -; -;find_mb: -; stx MB_ADDRH -; -; ;detect sound I -; -; sec -; ldy #$00 -; lda (MB_ADDRL), y -; sbc (MB_ADDRL), y -; cmp #$05 -; beq found_mb -; dex -; cpx #$c0 -; bne find_mb -; ldx #$00 ;no mockingboard found -; rts -; -;found_mb: -; ldx #$01 ;mockingboard found -; rts -; -; ;optionally detect sound II -; -; sec -; ldy #$80 -; lda (MB_ADDRL), y -; sbc (MB_ADDRL), y -; cmp #$05 -; beq found_mb - - - ;======================================= - ; 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 PT3_TEMP ; 3 cycles - lda (MB_ADDRL),Y ; + 5 cycles = 8 cycles - ; between the two accesses to the timer - sec - sbc PT3_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 - ;============================= ; Setup ;============================= -pt3_setup_interrupt: +mockingboard_setup_interrupt: ;=========================== ; Check for Apple IIc @@ -300,6 +182,11 @@ done_apple_detect: ; Enable 50Hz clock on 6522 ;============================ + ; 4fe7 / 1e6 = .020s, 50Hz + + ; 9c40 / 1e6 = .040s, 25Hz + ; 411a / 1e6 = .016s, 60Hz + sei ; disable interrupts just in case lda #$40 ; Continuous interrupts, don't touch PB7 @@ -318,9 +205,4 @@ done_apple_detect: ; load both values into counter ; clear interrupt and start counting - ; 4fe7 / 1e6 = .020s, 50Hz - rts - - - diff --git a/pt3_lib/pt3_test.s b/pt3_lib/pt3_test.s index dfd7e929..ae4e15d2 100644 --- a/pt3_lib/pt3_test.s +++ b/pt3_lib/pt3_test.s @@ -42,9 +42,8 @@ pt3_setup: jsr print_mockingboard_detect - jsr mockingboard_detect_slot4 ; call detection routine - cpx #$1 - beq mockingboard_found + jsr mockingboard_detect ; call detection routine + bcs mockingboard_found jsr print_mocking_notfound ;jmp forever_loop @@ -53,6 +52,11 @@ pt3_setup: mockingboard_found: + lda MB_ADDR_H + sec + sbc #$10 + sta found_message+11 + jsr print_mocking_found setup_interrupt: @@ -61,7 +65,7 @@ setup_interrupt: ;======================== jsr mockingboard_init - jsr pt3_setup_interrupt + jsr mockingboard_setup_interrupt ;============================ ; Init the Mockingboard @@ -149,9 +153,9 @@ done_found_message: ;========= ; strings ;========= -mocking_message: .asciiz "LOOKING FOR MOCKINGBOARD IN SLOT #4" +mocking_message: .asciiz "LOOKING FOR MOCKINGBOARD: " not_message: .byte "NOT " -found_message: .asciiz "FOUND" +found_message: .asciiz "FOUND SLOT#4" @@ -165,9 +169,11 @@ found_message: .asciiz "FOUND" .include "pt3_lib_core.s" .include "pt3_lib_init.s" -.include "pt3_lib_mockingboard.s" +.include "pt3_lib_mockingboard_setup.s" +.include "pt3_lib_mockingboard_detect.s" .include "interrupt_handler.s" + ;============= ; include song ;============= diff --git a/pt3_lib/zp.inc b/pt3_lib/zp.inc index d4bf1606..425ac293 100644 --- a/pt3_lib/zp.inc +++ b/pt3_lib/zp.inc @@ -25,9 +25,9 @@ SAMPLE_L = $82 SAMPLE_H = $83 LOOP = $84 -MB_VALUE = $85 -MB_ADDRL = $86 -MB_ADDRH = $87 +MB_ADDR_L = $85 +MB_ADDR_H = $86 +MB_VALUE = $87 DONE_PLAYING = $88 DONE_SONG = $89 PT3_TEMP = $8A