chiptune_debug: no luck, but have minimal reproducer

This commit is contained in:
Vince Weaver 2018-06-13 17:09:56 -04:00
parent 058882cb54
commit fc6b3fd391
2 changed files with 291 additions and 68 deletions

View File

@ -26,4 +26,49 @@ always volume 12 still issue
fix clear accidentally wr r14 still issue fix clear accidentally wr r14 still issue
generate single tone FINE!!! generate single tone FINE!!!
only play first 16 notes still issue only play first 16 notes still issue
only change C-fine value still issue
only write val, not address still issue
use handshake-free porta/6522 still issue
Look at interrupt registers on 6522
Emulator: IFR=$C0 IER=$80, Actual: IFR=$C0,IER=$C0
For 6552-2 it is $00/$80 on both
Tried soldering so pin 18 (PB1) always high
still issue
Tried reading back value from AY-3-8910, always match.
Channel A and B now have glitches offset by 320ms?
Interrupt happens at 50Hz=20ms? 16 samples??!??
NOTE: Applewin Bugs
+ Doesn't support reading back AY-3-8910 (Always returns
last written value?)
+ IER doesn't show Timer1 enabled? (returns 80 rather than C0)
Now glitch happens exactly every 640ms (32 50Hz interrupts) when playing
pattern of 8 notes repeatedly
Remove other cards from machine to see if power issue
still issue
When down to writing 4 values,
$51,$3c,$32,$50, issue seems to often hit on
the 51->3C transition
Down to two values, still only hit on the 51->3c transition.
Sometimes everytime, sometimes every Xth time.
$51 by itself = fine
$3c by itself = fine
50/3c and 50/32 also have issues, but not quite the same
(Some, audio fading instead of glitch?)

View File

@ -4,6 +4,45 @@
MB_CHUNK_OFFSET = $94 MB_CHUNK_OFFSET = $94
MB_VALUE = $91 MB_VALUE = $91
; left speaker
MOCK_6522_1_ORB = $C400 ; 6522 #1 port b data
MOCK_6522_1_ORA = $C401 ; 6522 #1 port a data
MOCK_6522_1_DDRB = $C402 ; 6522 #1 data direction port B
MOCK_6522_1_DDRA = $C403 ; 6522 #1 data direction port A
MOCK_6522_1_T1C_L = $C404 ; 6522 #1 Low-order counter
MOCK_6522_1_T1C_H = $C405 ; 6522 #1 High-order counter
MOCK_6522_1_T1L_L = $C406 ; 6522 #1 Low-order latch
MOCK_6522_1_T1L_H = $C407 ; 6522 #1 High-order latch
MOCK_6522_1_T2C_L = $C408 ; 6522 #1 Timer2 Low-order Latch/Counter
MOCK_6522_1_T2C_H = $C409 ; 6522 #1 Timer2 High-order Latch/Counter
MOCK_6522_1_SR = $C40A ; 6522 #1 Shift Register
MOCK_6522_1_ACR = $C40B ; 6522 #1 Auxiliary Control Register
MOCK_6522_1_PCR = $C40C ; 6522 #1 Peripheral Control Register
MOCK_6522_1_IFR = $C40D ; 6522 #1 Interrupt Flag Register
MOCK_6522_1_IER = $C40E ; 6522 #1 Interrupt Enable Register
MOCK_6522_1_ORAN = $C40F ; 6522 #1 port a data, no handshake
; right speaker
MOCK_6522_2_ORB = $C480 ; 6522 #2 port b data
MOCK_6522_2_ORA = $C481 ; 6522 #2 port a data
MOCK_6522_2_DDRB = $C482 ; 6522 #2 data direction port B
MOCK_6522_2_DDRA = $C483 ; 6522 #2 data direction port A
MOCK_6522_2_T1C_L = $C484 ; 6522 #2 Low-order counter
MOCK_6522_2_T1C_H = $C485 ; 6522 #2 High-order counter
MOCK_6522_2_T1L_L = $C486 ; 6522 #2 Low-order latch
MOCK_6522_2_T1L_H = $C487 ; 6522 #2 High-order latch
MOCK_6522_2_T2C_L = $C488 ; 6522 #2 Timer2 Low-order Latch/Counter
MOCK_6522_2_T2C_H = $C489 ; 6522 #2 Timer2 High-order Latch/Counter
MOCK_6522_2_SR = $C48A ; 6522 #2 Shift Register
MOCK_6522_2_ACR = $C48B ; 6522 #2 Auxiliary Control Register
MOCK_6522_2_PCR = $C48C ; 6522 #2 Peripheral Control Register
MOCK_6522_2_IFR = $C48D ; 6522 #2 Interrupt Flag Register
MOCK_6522_2_IER = $C48E ; 6522 #2 Interrupt Enable Register
MOCK_6522_2_ORAN = $C48F ; 6522 #2 port a data, no handshake
;========================= ;=========================
; Init Variables ; Init Variables
;========================= ;=========================
@ -36,26 +75,54 @@ MB_VALUE = $91
sei ; disable interrupts just in case sei ; disable interrupts just in case
lda #$40 ; Continuous interrupts, don't touch PB7 lda #$40 ; Continuous interrupts, don't touch PB7
sta $C40B ; ACR register sta MOCK_6522_1_ACR ; ACR register
lda #$7F ; clear all interrupt flags lda #$7F ; clear all interrupt flags
sta $C40E ; IER register (interrupt enable) sta MOCK_6522_1_IER ; IER register (interrupt enable)
lda #$C0 lda #$C0
sta $C40D ; IFR: 1100, enable interrupt on timer one oflow sta MOCK_6522_1_IFR ; IFR: 1100 0000
sta $C40E ; IER: 1100, enable timer one interrupt ; clear timer interrupt in flag register
; should we try to clear all?
sta MOCK_6522_1_IER ; IER: 1100 0000, enable timer1 interrupt
lda #$E7 lda #$E7
sta $C404 ; write into low-order latch sta MOCK_6522_1_T1C_L ; write into low-order latch
lda #$4f lda #$4f
sta $C405 ; write into high-order latch, sta MOCK_6522_1_T1C_H ; write into high-order latch,
; load both values into counter ; load both values into counter
; clear interrupt and start counting ; clear interrupt and start counting
; 4fe7 / 1e6 = .020s, 50Hz ; 4fe7 / 1e6 = .020s, 50Hz
;==================
; load first song
;==================
;=========================
; Setup initial conditions
;=========================
; 5: C CHANNEL COARSE
; ldx #5
; lda #$0 ; always 0
; sta MB_VALUE
; jsr write_ay_both
; 7: ENABLE
ldx #7
lda #$38 ; noise disabled, ABC enabled
sta MB_VALUE
jsr write_ay_both
; 10: C Amplitude
ldx #10
lda #$c ; always volume 12
sta MB_VALUE
jsr write_ay_both
; 4: C CHANNEL FINE
ldx #4
lda #$51
sta MB_VALUE
jsr write_ay_both
;============================ ;============================
@ -78,17 +145,6 @@ main_loop:
;routines ;routines
;========= ;=========
; left speaker
MOCK_6522_ORB1 = $C400 ; 6522 #1 port b data
MOCK_6522_ORA1 = $C401 ; 6522 #1 port a data
MOCK_6522_DDRB1 = $C402 ; 6522 #1 data direction port B
MOCK_6522_DDRA1 = $C403 ; 6522 #1 data direction port A
; right speaker
MOCK_6522_ORB2 = $C480 ; 6522 #2 port b data
MOCK_6522_ORA2 = $C481 ; 6522 #2 port a data
MOCK_6522_DDRB2 = $C482 ; 6522 #2 data direction port B
MOCK_6522_DDRA2 = $C483 ; 6522 #2 data direction port A
; AY-3-8910 commands on port B ; AY-3-8910 commands on port B
; RESET BDIR BC1 ; RESET BDIR BC1
@ -106,11 +162,16 @@ MOCK_AY_LATCH_ADDR = $7 ; 1 1 1
; set the data direction for all pins of PortA/PortB to be output ; set the data direction for all pins of PortA/PortB to be output
mockingboard_init: mockingboard_init:
lda #$ff ; all output (1) lda #$ff ; all 8 pins output (1), portA
sta MOCK_6522_DDRB1
sta MOCK_6522_DDRA1 sta MOCK_6522_1_DDRA
sta MOCK_6522_DDRB2 sta MOCK_6522_2_DDRA
sta MOCK_6522_DDRA2 ; only 3 pins output (1), port B
lda #$7
sta MOCK_6522_1_DDRB
sta MOCK_6522_2_DDRB
rts rts
reset_ay_both: reset_ay_both:
@ -119,18 +180,18 @@ reset_ay_both:
;====================== ;======================
reset_ay_left: reset_ay_left:
lda #MOCK_AY_RESET lda #MOCK_AY_RESET
sta MOCK_6522_ORB1 sta MOCK_6522_1_ORB
lda #MOCK_AY_INACTIVE lda #MOCK_AY_INACTIVE
sta MOCK_6522_ORB1 sta MOCK_6522_1_ORB
;====================== ;======================
; Reset Right AY-3-8910 ; Reset Right AY-3-8910
;====================== ;======================
reset_ay_right: reset_ay_right:
lda #MOCK_AY_RESET lda #MOCK_AY_RESET
sta MOCK_6522_ORB2 sta MOCK_6522_2_ORB
lda #MOCK_AY_INACTIVE lda #MOCK_AY_INACTIVE
sta MOCK_6522_ORB2 sta MOCK_6522_2_ORB
rts rts
@ -144,30 +205,77 @@ reset_ay_right:
; value in MB_VALUE ; value in MB_VALUE
write_ay_both: write_ay_both:
; address
stx MOCK_6522_ORA1 ; put address on PA1 ; 3 write_ay_address:
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 ; value
lda MB_VALUE ; 3 lda #$ff
sta MOCK_6522_ORA1 ; put value on PA1 ; 3 sta MOCK_6522_1_DDRA
sta MOCK_6522_ORA2 ; put value on PA2 ; 3
lda #MOCK_AY_WRITE ; ; 2 ; address
sta MOCK_6522_ORB1 ; write on PB1 ; 3 stx MOCK_6522_1_ORA ; put address on PA1 ; 3
sta MOCK_6522_ORB2 ; write on PB2 ; 3 stx MOCK_6522_2_ORA ; put address on PA2 ; 3
lda #MOCK_AY_LATCH_ADDR ; latch_address on PB1 ; 2
sta MOCK_6522_1_ORB ; latch_address on PB1 ; 3
sta MOCK_6522_2_ORB ; latch_address on PB2 ; 3
lda #MOCK_AY_INACTIVE ; go inactive ; 2 lda #MOCK_AY_INACTIVE ; go inactive ; 2
sta MOCK_6522_ORB1 ; 3 sta MOCK_6522_1_ORB ; 3
sta MOCK_6522_ORB2 ; 3 sta MOCK_6522_2_ORB ; 3
write_ay_value:
; value
lda #$ff
sta MOCK_6522_1_DDRA
lda MB_VALUE ; 3
sta MOCK_6522_1_ORA ; put value on PA1 ; 3
sta MOCK_6522_2_ORA ; put value on PA2 ; 3
lda #MOCK_AY_WRITE ; ; 2
sta MOCK_6522_1_ORB ; write on PB1 ; 3
sta MOCK_6522_2_ORB ; write on PB2 ; 3
lda #MOCK_AY_INACTIVE ; go inactive ; 2
sta MOCK_6522_1_ORB ; 3
sta MOCK_6522_2_ORB ; 3
rts ; 6 rts ; 6
;=========== ;===========
; 53 ; 53
read_ay_both:
; value
lda #$ff
sta MOCK_6522_1_DDRA
; address
stx MOCK_6522_1_ORA ; put address on PA1 ; 3
lda #MOCK_AY_LATCH_ADDR ; latch_address on PB1 ; 2
sta MOCK_6522_1_ORB ; latch_address on PB1 ; 3
lda #MOCK_AY_INACTIVE ; go inactive ; 2
sta MOCK_6522_1_ORB ; 3
read_ay_value:
; value
lda #$0
sta MOCK_6522_1_DDRA
lda #MOCK_AY_READ ; ; 2
sta MOCK_6522_1_ORB ; read on PB1 ; 3
ldy MOCK_6522_1_ORA ; read value
lda #MOCK_AY_INACTIVE ; go inactive ; 2
sta MOCK_6522_1_ORB ; 3
tya
rts ; 6
;======================================= ;=======================================
; clear ay -- clear all 14 AY registers ; clear ay -- clear all 14 AY registers
; should silence the card ; should silence the card
@ -196,7 +304,72 @@ interrupt_handler:
pha ; save A ; 3 pha ; save A ; 3
; Should we save X and Y too? ; Should we save X and Y too?
bit $C404 ; clear 6522 interrupt by reading T1C-L ; 4 .if 0
lda MOCK_6522_1_IFR
tay
and #$f
clc
adc #'0'+$80
sta $401
tya
lsr
lsr
lsr
lsr
clc
adc #'0'+$80
sta $400
lda MOCK_6522_1_IER
tay
and #$f
clc
adc #'0'+$80
sta $403
tya
lsr
lsr
lsr
lsr
clc
adc #'0'+$80
sta $402
lda MOCK_6522_2_IFR
tay
and #$f
clc
adc #'0'+$80
sta $407
tya
lsr
lsr
lsr
lsr
clc
adc #'0'+$80
sta $406
lda MOCK_6522_2_IER
tay
and #$f
clc
adc #'0'+$80
sta $409
tya
lsr
lsr
lsr
lsr
clc
adc #'0'+$80
sta $408
.endif
bit MOCK_6522_1_T1C_L ; clear 6522 interrupt by
; reading T1C-L ; 4
mb_play_music: mb_play_music:
@ -213,34 +386,32 @@ mb_write_frame:
; 4: C CHANNEL FINE ; 4: C CHANNEL FINE
ldx #4
; lda #$51
lda c_fine,Y lda c_fine,Y
sta MB_VALUE sta MB_VALUE
jsr write_ay_both sta expected+4
; 5: C CHANNEL COARSE ldx #4
ldx #5
lda #$0 ; always 0
sta MB_VALUE
jsr write_ay_both jsr write_ay_both
; jsr write_ay_value
; 7: ENABLE ; read out all of AY registers and see if match expected
ldx #7 ldx #0
lda #$38 ; noise disabled, ABC enabled loop:
sta MB_VALUE jsr read_ay_both
jsr write_ay_both cmp expected,X
beq good
; 10: C Amplitude brk
ldx #10
lda #$c ; always volume 12 good:
sta MB_VALUE inx
jsr write_ay_both cpx #14
bne loop
increment_offset: increment_offset:
inc MB_CHUNK_OFFSET ; increment offset inc MB_CHUNK_OFFSET ; increment offset
lda MB_CHUNK_OFFSET lda MB_CHUNK_OFFSET
and #$f and #$1
sta MB_CHUNK_OFFSET sta MB_CHUNK_OFFSET
done_interrupt: done_interrupt:
@ -250,10 +421,17 @@ done_interrupt:
expected: ; 0 1 2 3 4 5 6 7 8 9 10 11 12 13
.byte $00,$00,$00,$00, $00,$00,$00,$38, $00,$00,$0c,$00, $00,$00
; 4: C fine ; 4: C fine
c_fine: c_fine:
.byte $51,$3c,$32,$50,$3d,$32,$50,$3c, $33,$50,$3c,$32,$51,$3c,$32,$50 ;.byte $51,$3c,$32,$50, $3d,$32,$50,$3c, $33,$50,$3c,$32,$51,$3c,$32,$50
.byte $50,$32,$32,$50, $3d,$32,$50,$3c, $33,$50,$3c,$32,$51,$3c,$32,$50