For reference, here's the current code (which does both HW and xon/xoff simultaneously, as the host does xon/xoff, and the hardware can do rts/cts). /** * PLATOTerm64 - A PLATO Terminal for the Commodore 64 * Based on Steve Peltz's PAD * * Author: Thomas Cherryhomes <thom.cherryhomes at gmail dot com> * * io.c - Input/output functions (serial/ethernet) (c64 specific) */ #include <cbm.h> #include <c64.h> #include <peekpoke.h> #include <stdint.h> #include <stdbool.h> #include <string.h> #include "../io.h" #include <serial.h> #include "../config.h" extern uint8_t xoff_enabled; extern ConfigInfo config; extern uint8_t (*io_serial_buffer_size)(void); extern void (*io_recv_serial_flow_off)(void); extern void (*io_recv_serial_flow_on)(void); void io_recv_serial_flow_off_user_port(void); void io_recv_serial_flow_on_user_port(void); uint8_t io_serial_buffer_size_user_port(void); void io_recv_serial_flow_off_swiftlink(void); void io_recv_serial_flow_on_swiftlink(void); uint8_t io_serial_buffer_size_swiftlink(void); /** * io_init_funcptrs() - Set up I/O function pointers */ void io_init_funcptrs(void) { POKE(0xD020,0); if (strcmp(config.driver_ser,CONFIG_SERIAL_DRIVER_UP2400)==0) { POKE(0xD020,2); io_serial_buffer_size=io_serial_buffer_size_user_port; io_recv_serial_flow_off=io_recv_serial_flow_off_user_port; io_recv_serial_flow_on=io_recv_serial_flow_on_user_port; } else if (strcmp(config.driver_ser,CONFIG_SERIAL_DRIVER_SWIFTLINK)==0) { POKE(0xD020,3); io_serial_buffer_size=io_serial_buffer_size_swiftlink; io_recv_serial_flow_off=io_recv_serial_flow_off_swiftlink; io_recv_serial_flow_on=io_recv_serial_flow_on_swiftlink; } } /** * io_send_byte(b) - Send specified byte out */ void io_send_byte(uint8_t b) { ser_put(b); } /********* USER PORT *****************************/ /** * Return the serial buffer size */ uint8_t io_serial_buffer_size_user_port(void) { return PEEK(0x29B)-PEEK(0x29C)&0xff; } /** * io_recv_serial_flow_off() - Tell modem to stop receiving. */ void io_recv_serial_flow_off_user_port(void) { // for now, assume user port. POKE(0xD020,0); xoff_enabled=true; POKE(0xDD01,PEEK(0xDD01)&~0x02); } /** * io_recv_serial_flow_on() - Tell modem to stop receiving. */ void io_recv_serial_flow_on_user_port(void) { // For now, assume user port. POKE(0xD020,14); xoff_enabled=false; POKE(0xDD01,PEEK(0xDD01)|0x02); } /************** SWIFTLINK ***********************/ /** * Return the serial buffer size */ uint8_t io_serial_buffer_size_swiftlink(void) { return PEEK(0xF9)-PEEK(0xF8); } /** * io_recv_serial_flow_off() - Tell modem to stop receiving. */ void io_recv_serial_flow_off_swiftlink(void) { io_send_byte(0x13); xoff_enabled=true; } /** * io_recv_serial_flow_on() - Tell modem to stop receiving. */ void io_recv_serial_flow_on_swiftlink(void) { io_send_byte(0x11); xoff_enabled=false; } -Thom On Sun, Jul 29, 2018 at 4:25 PM <afachat@gmx.de> wrote: > On Sonntag, 29. Juli 2018 17:42:56 CEST Ed Spittles wrote: > > Oops, I'm in too deep to help there - hopefully I've helped to clarify > the > > situation. My guess would be yes, the NMI service routine is a good place > > to act early in checking buffer space and turning off the sender, but > yes, > > it's very critical code and you'd need to find the right place to do that > > work, and that might be difficult. > > Usually you should set the handshake when you receive the byte and find > too > little space left, i.e. in the IRQ/NMI. After all this is the place where > it > fills up. > > To make it faster, you only need to _stop_ the PC sending in the NMI. Make > the > PC start again you can do in the normal routine that reads from the > buffer. > Reading from the buffer is the only place where you free some space in the > buffer, and can thus decide to let the PC send again. > > (Note: make sure your code does not have any race condition, like setting > the > handshake line from NMI and at the same time resetting from IRQ, as this > could > lead to bad results. Usually only change the handshake line when > freespace(buffer) < LOWWATER in the NMI, and when freespace(buffer) > > HIGHWATER in the read routine, where LOWWATER < HIGHWATER.) > > Hope this helps (sorry it's late here) > > André > > > > > > > Ed > > > > > > On 29 July 2018 at 17:06, Thom Cherryhomes <thom.cherryhomes@gmail.com> > > > > wrote: > > > Yes, I am currently doing this in the main-line code, checking the > size of > > > the ring buffer, and if it passes a given threshold, it asserts bit 1 > of > > > $DD01, continues to process the now draining buffer, and toggles the > line > > > when it's ready for more data... > > > > > > This has worked, up until yesterday, when it's now clear that I am > > > spending too much time plotting text (that's a whole other matter), > and I > > > am trying to get back that reliability while I try to either find help > to > > > get the text routines fixed, OR ultimately work them out myself...but > now > > > I > > > am wondering if moving the buffer check and the handshaking into the > NMI > > > handler for the bit banging serial driver will give me the temporary > > > stability I need to make this work? > > > > > > -Thom > > > > > > On Sun, Jul 29, 2018 at 11:00 AM Ed Spittles <ed.spittles@gmail.com> > > > > > > wrote: > > >> To be clear on the directions, then, it's the 8-bit client which is > > >> receiving data, has got too much, or nearly too much, and would like > to > > >> tell the upstream host to stop sending? > > >> > > >> I've seen that same situation using the BBC Micro's serial port and > > >> connecting to a PC. The Acorn OS has a buffer threshold parameter, > and I > > >> found I needed to adjust it. That is, the BBC needs to maintain a lot > of > > >> space in the buffer, and as soon as it has less then 50 bytes it tells > > >> the > > >> PC to stop sending. The reason is that the PC can take its time to > > >> respond > > >> to the request to go quiet, and many more bytes may arrive. > > >> http://beebwiki.mdfs.net/OSBYTE_%26CB > > >> > > >> Others have seen the same, and set the free space to 100 bytes: > > >> https://stardot.org./forums/viewtopic.php?p=58297#p58297 > > >> although I see they still report problems. > > >> > > >> It's crucial to have the right cable connections, and a suitably > > >> cooperative serial port behaviour on the PC. It might even depend on > the > > >> responsiveness of the PC OS. > > >> > > >> Ed > > >> > > >> > > >> On 29 July 2018 at 16:45, Thom Cherryhomes < > thom.cherryhomes@gmail.com> > > >> > > >> wrote: > > >>> Am barrelling through PLATOTerm, and I've found that checking the > > >>> receive buffer in the main-line code and asserting flow control there > > >>> doesn't seem to be 100% effective in dealing with what still looks > like > > >>> some buffer overrun. > > >>> > > >>> Given this code here: > > >>> https://github.com/nanoflite/c64-up2400-cc65 > > >>> > > >>> Would adding a buffer overflow check and asserting bit 1 of $DD01 to > > >>> assert hardware flow control work? I'm asking because I know this > code > > >>> is > > >>> _very_ timing sensitive, and I am not very familiar with the user > port > > >>> serial machinery. > > > >Received on 2018-07-30 01:00:05
Archive generated by hypermail 2.2.0.