The problem is that the VIA chip generates interrupts every 5 clock cycles. And, I'm not sure why this is happening. According to the documentation I have here via the VIA datasheet and all, I should *just* be getting an interrupt due to the CB2 line going low. CB2 is verified to be high -- it should not be generating IRQs, let alone IRQs this often.
The only thing I can think of is that it is related to the timers, BUT, again, I did NOT set the timer interrupt enable bits at all, so they should be quiet.
Any ideas?
(Note: the LDA+2 and STA+2 are forms which forces ACME to generate 2-byte absolute addresses. This is required since I relocate the direct-page, and therefore cannot use direct page to access the VIA registers. It's a heck of a lot easier to type than LDA $0000+VIA_PB, or STA $0000+VIA_IER.)
Code: Select all
;
; echo-server.a
; Kestrel Release 1p1
;
; Copyright (c) 2005 Samuel A. Falvo II
; See LICENSE.txt for more details
;
!to "echo-server.b"
!src "65816.i"
!src "via.i"
!src "spi.i"
* = $FC00
!src "spi.a"
RxBuffer = $00 ; pointer to start of receive buffer
RxLength = $02 ; length of data received
PacketReceived = $04 ; -1 if packet has been received
__start:
; Establish runtime environment
clc
xce
rep #P_MX
!al
!rl
ldx #$E1FF
txs
lda #$E000
pha
pld
; Initialize the SPI bus
lda #$E200 ; Initialize the receiver's buffer area
sta RxBuffer
sep #P_MX
!as
!rs
lda #SPIM_OUTPUTS-SPIF_CLK ; Initialize SPI pins, sets idle bus device
sta+2 VIA_PB ; Setting PB first eliminates glitches
ora #SPIF_CLK
sta+2 VIA_DDRB
lda #VIA_IERF_SET | VIA_IERF_CB2
sta+2 VIA_IER
lda+2 VIA_PB ; Clear any pending interrupt, just in case
; Wait for a connection request from the client
Again:
stz PacketReceived
cli ; unlike x86, this *enables* interrupts
wait: ; busy-wait on a flag until interrupt
lda PacketReceived
beq wait
sti ; Prevents spurious interrupts
jsr EchoPacket ; RxBuffer/Length are valid now
jmp Again
EchoPacket:
clc ; Somehow, tell engineer that we got here.
xce
sec
xce
jmp EchoPacket
;
; IRQ handler -- this is invoked whenever the ATN# signal goes low from
; the SPI slave. Note that ATN# is attached to CB2 of the VIA chip, and
; is therefore able to generate interrupts. This allows us to handle an
; in-coming packet at any time.
;
__IRQ:
pha
phx
phy
php
sep #P_MX
!as
!rs
lda+2 VIA_IFR
and #VIA_IFRF_CB2 ; We only accept SPI-generated IRQs at the moment
beq spurious
lda+2 VIA_PB ; Acknowledge the interrupt
jsr ObtainPacket
spurious:
plp
ply
plx
pla
rti
ObtainPacket:
lda PacketReceived ; Ouch! We should never get a packet overrun
ora PacketReceived+1
bne Overrun
ldy #$00
lda #7
jsr SPI_SelectDevice
.rxLoop:
jsr SPI_ReceiveByte_Async
sta (RxBuffer),y
iny
cmp #$00
bne .rxLoop
.rxDone:
sty RxLength
stz RxLength+1
dec PacketReceived ; Huston, we have a packet.
dec PacketReceived+1
Overrun:
lda #15
jmp SPI_SelectDevice
* = $FEFC ; native-mode vectors
!word __start, __IRQ
* = $FFFC ; emulation-mode vectors
!word __start, __IRQ