Bi-Directional User Port Code
Posted: Tue Nov 28, 2023 9:48 am
I'm trying to grasp the general theory behind bi-directional asynchronous communication with the VIC-20 user port. Obviously, I know it can be done because VICmodem exists. So far, all of my serial port projects have involved either output from the VIC or input from another source into the VIC, or either by use of a manual switch.
I've read the VIC-20 Programmer's Reference Guide section on the user port a bunch of times. It breaks the user port operation into several Peripheral Control Register (PCR) modes, each of which is either an input or output mode.
For output, I'm using the Handshake Output Mode (p. 231). When I write to the port, CB2 goes low in this mode. My receiving device (Arduino) is listening for that, and when CB2 goes low, it reads the data lines, does whatever with them, and then sets CB1 high then low. This transition causes the CB2 to go high again, and now both parties know that we're ready for another byte of data to go out.
For input, I'm using the Interrupt Input mode (p. 231). When the Arduino has set the data lines appropriately, it sets CB2 from high to low, which sets the CB2 interrupt flag on the VIC-20 and fires an interrupt. My software on the VIC-20 checks the interrupt for the CB2 flag and, if set, reads the port and does whatever. Reading the port clears the CB2 flag, and we're ready for another byte of data to come in.
I'm usually using all 8 data lines. I know that I can use the DDR to divide them up into, say, four in/four out, then shift them into useful bytes. My confusion (or ignorance?) lies in the apparent mutual exclusivity in the PCR modes.
The only solution that comes to mind is that I might normally use the interrupt mode, and then switch over to the Handshake Output Mode when sending data, switching back to input mode when acknowledged or timed out. But then, data can't be received via interrupt while the sending is in progress (CB2 interrupt is disabled). This seems (to me) to nullify the advantage of dividing up the DDR. I feel like I need a "CB3" line!
TLDR; Does anyone have any sample code that does bi-directional in/out with the user port? Or, if not that, then a description of the theory of such communication, so I can piece it together?
I've read the VIC-20 Programmer's Reference Guide section on the user port a bunch of times. It breaks the user port operation into several Peripheral Control Register (PCR) modes, each of which is either an input or output mode.
For output, I'm using the Handshake Output Mode (p. 231). When I write to the port, CB2 goes low in this mode. My receiving device (Arduino) is listening for that, and when CB2 goes low, it reads the data lines, does whatever with them, and then sets CB1 high then low. This transition causes the CB2 to go high again, and now both parties know that we're ready for another byte of data to go out.
For input, I'm using the Interrupt Input mode (p. 231). When the Arduino has set the data lines appropriately, it sets CB2 from high to low, which sets the CB2 interrupt flag on the VIC-20 and fires an interrupt. My software on the VIC-20 checks the interrupt for the CB2 flag and, if set, reads the port and does whatever. Reading the port clears the CB2 flag, and we're ready for another byte of data to come in.
I'm usually using all 8 data lines. I know that I can use the DDR to divide them up into, say, four in/four out, then shift them into useful bytes. My confusion (or ignorance?) lies in the apparent mutual exclusivity in the PCR modes.
The only solution that comes to mind is that I might normally use the interrupt mode, and then switch over to the Handshake Output Mode when sending data, switching back to input mode when acknowledged or timed out. But then, data can't be received via interrupt while the sending is in progress (CB2 interrupt is disabled). This seems (to me) to nullify the advantage of dividing up the DDR. I feel like I need a "CB3" line!
TLDR; Does anyone have any sample code that does bi-directional in/out with the user port? Or, if not that, then a description of the theory of such communication, so I can piece it together?