Monday 20 September 2021

6502 : Xmodem Fights Back



 Previous I have been pleased to be able to (1) download a file to RAM and (2) use xmodem to transfer a program and then run it. I was very pleased with both results and felt that I had cracked xmodem.  The good feeling didn't last long.

Download speed

I wanted to get started on testing my C programs and they use the terminal working at 19.2k baud whereas my download testing has been conducted at 9600 baud.   The C program displayed some garbled characters when the speed was reduced to 9.6k and in general my programs work at 19.2k so I need to standardise my transfers on 19.2k.

Increase clock speed

Unfortunately, when I changed to 19.2k my xmodem downloads appeared to complete but would not run as they were losing characters.  My thoughts turned to flow control or increasing the clock speed.  RTS/CTS flow control didn't seem to work last time I tried it and I don't really need my Nano slow testing capability so adding the 1MHz clock chip is the way to go.  

Changing over to the clock chip simply requires connecting 5V, GND and the clock output to 6502.  After doing this nothing was displayed on the terminal screen with a simple program which outputs a message.  I find I need to put a 255 cycle delay loop between each character output to the terminal.  I tried RTS/CTS flow control but it made no difference.

A short while later I discovered, on the 6502 site forum that the 65C51 has a design error which means that flow control doesn't work


 The easiest workaround is the method I chose; to insert a delay.

Spurious Interrupts

With the transmission speed fixed, I returned to testing xmodem downloads.  Unfortunately matters became worse.  The 6502 appeared to randomly restart itself during or after downloads.  I guessed that the system was getting interrupts, causing it to jump to the reset vector.  So far I have only covered Ben's interrupt tutorials and haven't set anything up.  The 6502 has an NMI pin (connected to 5V) and an IRQ pin connected to the 6522 VIA CA1 pin.    I set up small code snippets which displayed a message on the terminal when one of the interrupts occurred and configured the NMI and IRQ vectors accordingly.

As expected the IRQ vector was used each time a spurious interrupt occurred.  This happened even when the IRQ pin was held high.  The 6502 provides a BRK instruction (opcode $00) which also causes an interrupt to the IRQ vector.  When an interrupt occurs, the interrupt return address and process status register byte are written to the stack.  Initially my code to test BRK would not return to continue the program when an RTI (return from interrupt) instruction was encountered.  I found in an article that compilers need to treat BRK as a 2 byte opcode to jump back to the correct address but they only reserve 1 byte ($00) which means the program returns to the wrong address.  I corrected this by adding NOP after BRK and RTI then works fine.


I spent some time writing interrupt code which saves the type of interrupt, return address and interrupt count to page zero variables so that I can print out interrupt details.  A separate subroutine can print this information out to the LCD on request.   For debugging spurious interrupts we only need capture a single interrupt so the interrupt processor has an option to print details within the interrupt and not return to the program.

With the capability to determine spurious interrupt details in place we are now more prepared to continue debugging xmodem.