pt3_lib: update the detection code

This commit is contained in:
Vince Weaver 2019-12-28 18:04:19 -05:00
parent d0c87370c8
commit 4f89601053
5 changed files with 219 additions and 135 deletions

View File

@ -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
#

View File

@ -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

View File

@ -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

View File

@ -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
;=============

View File

@ -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