cc65 and RS232 User Port Serial

Basic and Machine Language

Moderator: Moderators

Bobbi
Vic 20 Afficionado
Posts: 347
Joined: Thu Oct 13, 2016 11:35 am
Location: Toronto
Occupation: Programmer

cc65 and RS232 User Port Serial

Postby Bobbi » Tue Dec 13, 2016 11:56 am

Anyone here who knows about the state of the support for RS232 serial on VIC-20 in cc65?

More specifically, I am trying to read the library source code to see how the 256 byte send and receive buffers are allocated (and make sure they are not trashing memory that I care about!)

Bobbi
Vic 20 Afficionado
Posts: 347
Joined: Thu Oct 13, 2016 11:35 am
Location: Toronto
Occupation: Programmer

Re: cc65 and RS232 User Port Serial

Postby Bobbi » Tue Dec 13, 2016 12:05 pm

And I think my conclusion is that the VIC-20 falls back to the generic CBM handlers which are just a thin wrapper around the Kernal functions. So it is 512 bytes "at the top of memory" according to the PRG.

User avatar
Mike
Herr VC
Posts: 2993
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: cc65 and RS232 User Port Serial

Postby Mike » Tue Dec 13, 2016 12:48 pm

You can put the send and receive buffers at another (possibly more convenient) place by predefining the pointers in $F7/$F8 and $F9/$FA to a non-0 value *before* the first call to OPEN2,... That also prevents the re-allocation of BASIC memory with the accompanying CLR.

That does not specifically apply to cc65 usage, of course. :)

Bobbi
Vic 20 Afficionado
Posts: 347
Joined: Thu Oct 13, 2016 11:35 am
Location: Toronto
Occupation: Programmer

Re: cc65 and RS232 User Port Serial

Postby Bobbi » Tue Dec 13, 2016 12:49 pm

Thank you Mike! That is the info I was looking for!

Bobbi
Vic 20 Afficionado
Posts: 347
Joined: Thu Oct 13, 2016 11:35 am
Location: Toronto
Occupation: Programmer

Re: cc65 and RS232 User Port Serial

Postby Bobbi » Sat Dec 17, 2016 2:44 pm

I have been looking into the issue of the broken RS232 flow control in the kernal. In particular I am picking through the annotated disassembly someone helpfully posted here a while back (srowe maybe?) I have attached it for convenience.

One error is at line 11635 in routine RSNXTBYT where the status of VIA2 is checked instead of VIA1 (ooops!). This code is part of the transmit NMI routine entered at RSNXTBIT (line 11547). In my particular case I am concerned about receive overruns, not transmit overruns so this ooopsie doesn't affect my application (for now.)

There is the same mistake again at line 12875 in routine OPENRS. As far as I can tell the intent of this code is to bail out of the OPENRS call if DSR is not present. This doesn't seem to be a big deal, because it is in OPENRS rather than in the receive routines (although maybe I am missing another code path that comes through here ...)

The other error is at line 15114 in READST. The code inadvertantly tramples on the RS232 status word so READST already returns ST = 0. On the face of it it looks like one should be able to avoid this particular issue by not calling READST, but instead examining location 0x297 (RSSTAT) directly.

It looks to me like the code in RSINBYTE (line 11767) sets RSSTAT in a reasonable way.

I modified my C code to check location 0x0297 after reading each byte, but it always seems to have value zero so perhaps the kernal code is never setting it in the read routine.

Here is my scenario. I request a file of around 30KB via HTTP using the WiModem. The entire file should fit in the WiModem's buffer, that I believe is 64K. I then trickle that to the VIC20 at 300 baud. I really think my code should be able to keep up with 30 chars per sec (and infact I know it can work at 1200 baud, at least for a bit) but it seems I am dropping characters. When I feed the same parsing code with a file downloaded on the PC it runs fine, but when I use the data via RS232 I usually end up with corrupt data at some point. The only way I can see this happening is if the VIC-20 sometimes is unable to handle incoming data for a short period and / or interrupts are disabled long enough to miss an incoming bit. The question is, can I set some bit in the pseudo-control register to force the WiModem to 'pause' its transmission. If I can do just that I am sure I can brute force some kind of working flow control so I don't drop characters ...

Any VIC-20 RS232 wizards out there? Perhaps I should put something in the code to keep an eye on how full the RS232 read buffer is. My guess is that I am overflowing the 256 bytes somehow.
Attachments
combined_ROMs.zip
(105.71 KiB) Downloaded 5 times

User avatar
Mike
Herr VC
Posts: 2993
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: cc65 and RS232 User Port Serial

Postby Mike » Sat Dec 17, 2016 3:17 pm

Bobbi wrote:Perhaps I should put something in the code to keep an eye on how full the RS232 read buffer is. My guess is that I am overflowing the 256 bytes somehow.

Here are two threads which might hint into the right direction: "Userport Serial programming nonsense" and "Closing an RS-232 channel". There, two pointers into the Tx circular FIFO buffer are explicitly mentioned: $029D and $029E. $029B and $029C serve the same function for the Rx buffer.

HTH,

Michael

Bobbi
Vic 20 Afficionado
Posts: 347
Joined: Thu Oct 13, 2016 11:35 am
Location: Toronto
Occupation: Programmer

Re: cc65 and RS232 User Port Serial

Postby Bobbi » Sat Dec 17, 2016 3:39 pm

I think the next step is to ignore the status and look at the RX buffer pointers ($029B and $029C) instead. At least that will confirm or disprove the hypothesis that the RX buffer is overflowing. It is always possible that my problems lie elsewhere.

Bobbi
Vic 20 Afficionado
Posts: 347
Joined: Thu Oct 13, 2016 11:35 am
Location: Toronto
Occupation: Programmer

Re: cc65 and RS232 User Port Serial

Postby Bobbi » Sat Dec 17, 2016 4:24 pm

Having put in some debug it is clear that I am not overflowing the RX buffer in normal operation at 300 baud. The peak usage is perhaps 30 characters (when I am printing a formatted RSS news article to the screen) and this rapidly drops back to zero once I start parsing again.

I guess I will repeat the experiment at 1200 baud to see how well my code keeps up.

However I think there is some subtle memory corruption going on somewhere. I don't recall if I ran the parsing code under Valgrind on Linux, but I will give this a go and see if I am scribbling on memory somewhere. Also, it is possible the RS232 buffers are trashing my variables, but I thought I was safe when I last checked.

Bobbi
Vic 20 Afficionado
Posts: 347
Joined: Thu Oct 13, 2016 11:35 am
Location: Toronto
Occupation: Programmer

Re: cc65 and RS232 User Port Serial

Postby Bobbi » Sun Dec 18, 2016 7:59 am

I found one obvious source of memory corruption (forgot to make the display buffer a more reasonable size for the VIC - was using 20K!!) I was occasionally trashing the RS232 buffers I suspect. Fixed that now and things work more predictably! Working on the higher baud rates now.

There should be a new release of the RSS Reader / CBC News App sometime today with some fixes!

User avatar
beamrider
Vic 20 Nerd
Posts: 825
Joined: Sun Oct 17, 2010 2:28 pm
Location: UK

Re: cc65 and RS232 User Port Serial

Postby beamrider » Sun Dec 18, 2016 10:04 am

Good work.. I'll give it a go when you release the next version...

Bobbi
Vic 20 Afficionado
Posts: 347
Joined: Thu Oct 13, 2016 11:35 am
Location: Toronto
Occupation: Programmer

Re: cc65 and RS232 User Port Serial

Postby Bobbi » Sun Dec 18, 2016 10:10 am

I am playing with it right now :)

Here is the interesting thing. I seem to be getting corrupt XML data from time to time (basically all I know is that the tag I was looking for was never seen, but it should have been there in a well-formed file, and I don't have the issue if I load the XML file from disk.) This happens a little bit at 300 baud, more at 600 and a lot at 1200 baud.

I naively supposed my code was too slow, but I can easily parse XML at 1200 baud (just tested it this morning) and I can also confirm that the RS232 RX buffer is never exceeding 20 characters at 300 baud (and always <100 at 1200 baud) so I am not dropping characters by letting the buffer overflow. I am coming to the conclusion that the modem is dropping the characters under some situations. Maybe I am wrong and I am doing something daft though - wouldn't be the first time!

Bobbi
Vic 20 Afficionado
Posts: 347
Joined: Thu Oct 13, 2016 11:35 am
Location: Toronto
Occupation: Programmer

Re: cc65 and RS232 User Port Serial

Postby Bobbi » Sun Dec 18, 2016 10:39 am

OK - I posted a new release of the CBC News App / RSS Reader to the other thread (v0.2). You can have a play with it if you like.

Bobbi
Vic 20 Afficionado
Posts: 347
Joined: Thu Oct 13, 2016 11:35 am
Location: Toronto
Occupation: Programmer

Re: cc65 and RS232 User Port Serial

Postby Bobbi » Sun Dec 18, 2016 2:05 pm

Here is something interesting. The PRG refers to some sort of interlock between IEC (disk access) and RS232 since they both use the VIAs. However it is very vague about the implications of this.

I have been playing around in cc65, and it seems to me that it is basically not possible to read bytes over RS232 and write them to disk at the same time. One would have to buffer everything in memory and write it out after the serial connection is closed, I guess.

In the following code fragment, if I try to write a character to disk file (logical file 8) then it trashes variable 'c' which is not even passed to cbm_write()! If on the other hand I write the character to RS232, 'c' is not trashed.

Any ideas folks?

Code: Select all

c = cbm_open(1, 2, 3, rs232filename);                                   
if (c != 240) { // Net says 240 is a reasonable result!                 
    puts("Can't open RS232");                                       
    return;                                                         
}
c = cbm_open(8, 8, CBM_WRITE, "@:rss.xml,p");                           
if (c != 0) {                                                           
    printf("Can't open file (%d)\n", c);                           
    return;                                                         
}
for(;;) {
    ret = cbm_read(1, &c, 1);
    if (ret == 0) {
        continue;
    }
    if (ret == -1) {
        break;
    }
    cbm_write(8, "a", 1); // With this line value of c gets trashed!!!!!!
    //cbm_write(1, "a", 1); // With this line all is well!!!!
}
cbm_close(1);
cbm_close(8);

Bobbi
Vic 20 Afficionado
Posts: 347
Joined: Thu Oct 13, 2016 11:35 am
Location: Toronto
Occupation: Programmer

Re: cc65 and RS232 User Port Serial

Postby Bobbi » Sun Dec 18, 2016 5:38 pm

I have been trying to debug the issue with the apparently corrupt XML and I have yet to totally get to the bottom of it. However in the process I have worked out that using cc65's putchar() routine is causing me lots of trouble. It seems to be very easy to get the Commodore console into a sulky state where characters no longer show up (even though I know they are being received and processed.) I am having much better luck just poking characters into video memory. (For example, printing a quote mark (") to the console using putchar() puts it in quotes mode, as if I were typing interactively.)

Bobbi
Vic 20 Afficionado
Posts: 347
Joined: Thu Oct 13, 2016 11:35 am
Location: Toronto
Occupation: Programmer

Re: cc65 and RS232 User Port Serial

Postby Bobbi » Sun Dec 18, 2016 8:20 pm

Yes! I can finally parse RSS at 1200 baud. The key was to stop using the CBM kernal I/O - if I use the conio routines from cc65, it works way way better than using putchar() and friends. Go figure!?

I will make a new release of the RSS reader with support for speeds up to 1200 baud in due course. However first I need to clean up the output routines and implement some form of scrolling - it's all very crude at the moment, but it is working!!


Return to “Programming”

Who is online

Users browsing this forum: No registered users and 1 guest