Agree about the commenting. It definitely helps. I do comment thoroughly. And to be honest when posting my issues here I don't really expect people to solve them for me. Just explaining them helps a lot then you guys point out any really boneheaded mistakes and give me lots of other things I should think of.
It takes me a long time to debug because 1. I am still learning as I go and 2. I only change one thing at a time. I've learned changing too many things at once can really mess you up!
But here's the latest. I probably didn't make it clear but I am using interrupt driven receive but doing polled transmit. The transmit just waits until the transmit data register is empty in a loop then it puts in the byte to transmit.
It's doing this whenever the machine wants to output to the screen (via my serial driven display board).
The receive is working off interrupts. I only enable that when I am loading. The Basic code though is echoing whatever is received to the screen as it's being received.
I think what was happening was the two were clashing. To test this I now don't send anything to the screen when receiving serial data in load mode. Instead I enabled the local echo on the ACIA.
This is now working well. I get almost no errors now. Although if I send it a lot of data really fast something else stops working and my keyboard scanning breaks!
So what I think I need to do is change the transmit to be interrupt driven too so the serial is properly interrupt driven full duplex. This is how the ISR looks now.
Code:
; =============================================================================
; ISR
; =============================================================================
ISR:
SEI ; Disable interrupts.
BIT acia1_s ; Check the status register (loads bit 7 into N and bit 6 into V).
BMI ACIA_Interrupt ; Result negative (bit 7 set) so service ACIA.
CLI ; Re-enable interrupts.
RTI
; =============================================================================
; ACIA Interrupt.
; =============================================================================
ACIA_Interrupt:
PHA ; Store A.
TXA ; Store X.
PHA
LDA acia1_s ; Get the contents of the ACIA's status register. Reading it clears the interrupt.
STA IO ; Display on the LEDs.
AND #%00000111 ; Check for error conditions (lower 3 bits of status).
BNE ACIA_Interrupt_Error ; If there was any error go report it.
LDX acia1_wr_ptr ; Start with A containing the byte to put in the buffer.
LDA acia1_d ; Get the data from the ACIA.
STA acia1_rx_buffer, X ; Get the pointer value and store the data where it says
INC acia1_wr_ptr ; then increment the pointer for the next write.
; JSR ACIA_Buffer_Diff ; Now see how full the buffer is.
; CMP #$F0 ; If it has less than 240 bytes unread
; BCC ACIA_Interrupt_Done ; just exit the ISR here.
JMP ACIA_Interrupt_Done
ACIA_Interrupt_Error:
JSR Beep
LDA acia1_d ; Get the data from the ACIA to clear the error.
ACIA_Interrupt_Done:
PLA ; Retrieve X.
TAX
PLA ; Retrieve A.
RTI
Simon