First of all - the disclaimer:
I'm fairly new to assembly, both in general, and on the VIC-20. So I apologize in advance for any and all newbie/idiot misstakes. And I appreciate all help in improving my work.
* end disclaimer
I am working on a project where I want to connect a MIDI keyboard to a microcontroller. The microcontroller is connected to the VIC-20:s user port where I want the VIC 20 to pass on the data to the VIC sound registers. I use CB1 and CB2 for flow control and PORTB for the data. The communication is one-way, i.e. I use both CB1 and CB2 as inputs on the VIC. I use NMI:s to catch incoming data packets. A complete "data transmission" consists of one address byte and one data byte.
I have managed to get this working fairly well. I haven't done really extensive tests but playing the MIDI keyboard plays the intended notes on the intended channel. So far so good.
BUT - this is where I get into trouble : I want to incorporate more interrupt sources so I can add sound modulation. The first thing I want to try is to add Aleksi's 10-bit oscillator frequency resolution routine. I've tried it earlier when I had polling communication with the microcontroller (i.e. NOT on NMI) and that worked fine, apart from lost data packets which I want to avoid.
What happens is that the interrupts stop firing after a random amount of time. If I leave the interrupts for CB1 and CB2 untouched (i.e. I don't play the MIDI keyboard) the timer keeps ticking and the 10-bit sound NMI routine works. I guess I am missing/doing the ACK of the interrupt wrong? I added a BIT $9114 in the end of the NMI routine to get this result, if I don't the NMI will only fire once. I really only want to do the BIT $9114 when the interrupt fired is the timer interrupt (i.e. at the end of the 10-bit routine at $14C0).
I can't see what I'm doing wrong but when it comes to the VIA timers and how to acknowledge interrupts I'm obviously on thin ice.
Anyway - here is the complete and uncensored code. I am writing it on real hardware using my only tools available, which is a memory expansion and VIC Monitor.
Code: Select all
Memory Map
------------------------
$1300-1342 : setup
$1450-1465 : hextodec
$1470-148D : display NMI flags
$1490-14BF : Variables:
14B8..9..A..B..C..D..E..F = data table for 10-bit osc.
1499 = Flag for address byte received or not
$14C0-14DE: 10-bit routine
$1500-1535 : NMI handler
$1530 : endNMI
;-------------setup routine
;setup user port communication
1300 a9 00 lda #$00
1302 8d 99 14 sta $1499 ;Variable to flag whether an address byte has been received or not
1305 8d 12 91 sta $9112 ;Set Port B to in
1308 ad 1c 91 lda $911c
130b 29 0f and #$0f
130d 09 00 ora #$00
130f 8d 1c 91 sta $911c ;Configure VIA peripheral register for correct CB behaviour
;Clear screen and set foreground color
1312 20 5f e5 jsr $e55f ;Clear screen
1315 a9 02 lda #$02
1317 a2 ff ldx #$ff
1319 9d ff 93 sta $93ff,x ;Set foregroud color on first "half" of screen
131c ca dex
131d d0 fa bne $1319
131f ea nop
;Point NMI Vector to my NMI routine at $1500
1320 a9 00 lda #$00
1322 8d 18 03 sta $0318
1325 a9 15 lda #$15
1327 8d 19 03 sta $0319
;Setup 10-bit oscillator routine
132a a9 80 lda #$80
132c 8d 14 91 sta $9114
132f 85 fe sta $fe
1331 a2 05 ldx #$05
1333 8e 15 91 stx $9115
1336 a9 00 lda #$00
1338 95 f8 sta $f8,x
133a ca dex
133b 10 fb bpl $1338
;Enable NMI interrupts
133d a9 d8 lda #$d8 ;%11011000
133f 8d 1e 91 sta $911e
1342 60 rts
--------- end setup routine
;10 bit oscillator routine
14c0 asl $fe
14c2 bcc $14c6
14c4 e6 fe inc $fe
14c6 a2 02 ldx #$02
14c8 b4 fb ldy $fb,x
14ca b9 b8 14 lda $14b8,y
14cd b4 f8 ldy $f8,x
14cf 25 fe and $fe
14d1 f0 01 beq $14d4
14d3 c8 iny
14d4 98 tya
14d5 9d 0a 90 sta $900a,x
14d8 ca dex
14d9 10 ed bpl $14c8
14db 2c 14 91 bit $9114
14de 4c 30 15 jmp $1530 ;endnmi
;NMI routine
1500 48 pha
1501 98 tya
1502 48 pha
1503 8a txa
1504 48 pha
1505 ad 1d 91 lda $911d
1508 29 08 and #$08
150a f0 50 beq $155c
150c ad 1d 91 lda $911d
150f 29 10 and #$10
1511 f0 29 beq $153c
1513 ee 00 10 inc $1000
1516 ad 1d 91 lda $911d
1519 29 40 and #$40
151b f0 a3 beq $14c0
151d ea nop
151e ea nop
151f ea nop
1520 ea nop
1521 ea nop
1522 ea nop
1523 ea nop
1524 ea nop
1525 ea nop
1526 ea nop
1527 ea nop
1528 ea nop
1529 ea nop
152a ea nop
152b ea nop
152c ea nop
152d ea nop
152e ea nop
152f ea nop
1530 a9 00 bit $9114
nop
1535 68 pla
1536 aa tax
1537 68 pla
1538 a8 tay
1539 68 pla
153a 40 rti
;address byte received
153c ee 2c 10 inc $102c
153f ea nop
1540 ad 10 91 lda $9110
1543 ae 99 14 ldx $1499
1546 e0 00 cpx #$00
1548 d0 e6 bne $1530
154a 8d 97 14 sta $1497
154d a9 01 lda #$01
154f 8d 99 14 sta $1499
1552 4c 30 15 jmp $1530
;data byte received
155c ee 2d 10 inc $102d
155f ea nop
1560 ad 10 91 lda $9110
1563 ae 99 14 ldx $1499
1566 e0 01 cpx #$01 ;check that we have an address byte, otherwise toss the data and end NMI
1568 d0 c6 bne $1530
156a a2 00 ldx #$00
156c 8e 99 14 stx $1499
156f ae 97 14 ldx $1497
1572 e0 0a cpx #$0a
1574 d0 06 bne $157c
1576 8d 0a 90 sta $900a
1579 4c a1 15 jmp $15a1
157c e0 0b cpx #$0b
157e d0 06 bne $1586
1580 8d 0b 90 sta $900b
1583 4c a1 15 jmp $15a1
1586 e0 0c cpx #$0c
1588 d0 06 bne $1590
158a 8d 0c 90 sta $900c
158d 4c a1 15 jmp $15a1
1590 e0 0d cpx #$0d
1592 d0 06 bne $159a
1594 8d 0d 90 sta $900d
1597 4c a1 15 jmp $15a1
159a e0 0e cpx #$0e
159c d0 15 bne $15b3
159e 8d 0e 90 sta $900e
15a1 8e 95 14 stx $1495
15a4 20 50 14 jsr $1450
15a7 ae 95 14 ldx $1495
15aa 8d 16 10 sta $1016
15ad 8c 17 10 sty $1017
15b0 4c 30 15 jmp $1530
15b3 8e 95 14 stx $1495
15b6 20 50 14 jsr $1450
15b9 8d 58 10 sta $1058
15bc 8c 59 10 sty $1059
15bf ad 95 14 lda $1495
15c2 20 50 14 jsr $1450
15c5 8d 5a 10 sta $105a
15c8 8c 5b 10 sty $105b
15cb 4c 30 15 jmp $1530
;Hex to dec routine
1450 f8 sed
1451 aa tax
1452 29 0f and #$0f
1454 c9 0a cmp #$0a
1456 69 30 adc #$30
1458 a8 tay
1459 8a txa
145a 4a lsr a
145b 4a lsr a
145c 4a lsr a
145d 4a lsr a
145e c9 0a cmp #$0a
1460 69 30 adc #$30
1462 d8 cld
1463 60 rts
;display NMI flags routine
1470 a2 00 ldx #$00
1472 ad 1d 91 lda $911d
1475 0a asl a
1476 48 pha
1477 b0 08 bcs $1481
1479 a9 2d lda #$2d
147b 9d 0e 10 sta $100e,x
147e 4c 86 14 jmp $1486
1481 a9 2b lda #$2b
1483 9d 0e 10 sta $100e,x
1486 68 pla
1487 e8 inx
1488 e0 08 cpx #$08
148a d0 e9 bne $1475
148c 60 rts