fast rs232 routines

Started by hannenz, February 25, 2008, 04:06 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

hannenz

hi. i am in search for some sources for fast rs232 routines. Desterm for example provides 9600 baud on my unexpanded c128 with a simple rs232 interface; i read in comp.sys.cbm that 19.2, 28.4 and even 57.6Kbps can be done (the latter only with blanked screen etc...) with NO special hardware, e.g. UART.
but i did not find any code examples
we all know that the kernal routines are crap. they don't even get me 2400 baud reliably, so i a looking for some code to or explanations on how to program such fast rs232 routines. 9600 would be cool, all above even better ;)

Andrew Wiskow

With a standard user port RS-232 interface, 9600 baud is the limit.  For faster speeds, you need one of the expansion port interfaces (e.g., SwiftLink, Turbo/232, etc.).

-Andrew
Cottonwood BBS & Cottonwood II
http://cottonwood.servebbs.com

hannenz

ok, 9600 would be fine.... but does anybody have some lines of code or a link for me please...!

BigDumbDinosaur

#3
Quote from: hannenz on February 25, 2008, 04:06 AM
i read in comp.sys.cbm that 19.2, 28.4 and even 57.6Kbps can be done (the latter only with blanked screen etc...) with NO special hardware, e.g. UART.  but i did not find any code examples

Gee!  I wonder why you "did not find any code examples"?  Did I tell you about my ocean-front property in Saskatchewan?  If you believe that one, then you'll believe the one about the C-128 that does 57.6 Kb/sec in software.   >:D

Lessee...the 8N1 format requires ten bits per byte sent or received.  With no ACIA to do the grunt work, the C-128 has to process the data stream entirely in software.  Since CIA #2 is involved, that means processing will be done with NMIs, 63,360 of them per second for continuous input and another 57,600 per second for continuous output—this level of performance is called CBAT (continuous bi-directional asynchronous transmission) and is routine with modern hardware.  In other words, assuming you expect CBAT performance without error, that poor 8502 is going to be interrupted 120,960 times per second.  With me so far?  It gets better!

All NMOS versions of the 6502 have an average interrupt latency of eight clock cycles.  Oh, how about saving the .A, .X and .Y registers?  Kind of important you say?  That will cost you 13 more clock cycles, please.  Therefore, 21 clock cycles or 10.5 microseconds at 2 MHz mode will be consumed before we even get to the point where we can tend to the serial data flow.  An additional 22 clock cycles will be required to restore .A, .X and .Y, and execute RTI to end the interrupt.  Therefore, 43 clock cycles will be lost to overhead at each interrupt.

At 57.6 Kb/sec CBAT you have this not-so-little problem: a total of 5,201,280 clock cycles will be expended just processing all those pesky interrupts.  The processor only has 2,000,000 cycles available per second.  Any questions?

Quote
we all know that the kernal routines are crap. they don't even get me 2400 baud reliably, so i a looking for some code to or explanations on how to program such fast rs232 routines. 9600 would be cool, all above even better ;)

Although the kernel RS-232 code is not bug-free or particularly efficient, it is only partly to blame for errors.  Many CIAs have a hardware defect in which if the interrupt control register is read a few clock cycles  before a timer B interrupt is about to occur, the interrupt will never come.  The result will be a gross error on input processing, resulting in garbage.

Bottom line is, don't believe all the BS you read on the Internet.  You want 19.2 Kb/sec or higher, use an ACIA.
x86?  We ain't got no x86.  We don't need no stinking x86!

hannenz

#4
Well, I just refer to this post in comp.sys.cbm:
http://groups.google.com/group/comp.sys.cbm/browse_thread/thread/149ca871f7dc7762/daee67f8619cbb37?lnk=gst&q=c128+rsr232+9600#daee67f8619cbb37

i don't know if it's true or not, and i think that there must be other tricks involved than using the NMI for RS232 input/ output. They talk about Over5 in this discussion which is known to be able to do much more than 9600 baud transmissions with no special hardware.
Quote
Over5

Over5 is a c64/vic20 < - > Amiga/Pc/Unix-box transferring program. It supports serial transfer at 38400 bps using only a RS-232 level converter (like the VIC-1011A RS232C or the Handic V24 interface) and a 3-line standard nullmodem cable. NO special serialport chips needed!

I don't know how Over5 does it, but i think it must be something like polling the userport directly with everything else (Kernal, Interrupts etc.) disabled - or something like that.
I know that the Over5 source is available and i had a look at it - but that seems a bit to "oversized" and too much specialized for my purposes.

I'd be glad to have a working replacement for the Kernal-RS232 routines which can cope with 9600 baud (in 2MHz/ 80 col mode of course). Desterm proves that it is possible. I have a proper vt100 emulation at 9600 baud when logging into my linux machine and i would like to have that "stand-alone" in own programs.
So I might better ask: Is there any chance to get a copy of the Desterm source??


BigDumbDinosaur

Quote from: hannenz on February 25, 2008, 07:30 PM
Well, I just refer to this post in comp.sys.cbm:
http://groups.google.com/group/comp.sys.cbm/browse_thread/thread/149ca871f7dc7762/daee67f8619cbb37?lnk=gst&q=c128+rsr232+9600#daee67f8619cbb37

i don't know if it's true or not, and i think that there must be other tricks involved than using the NMI for RS232 input/ output. They talk about Over5 in this discussion which is known to be able to do much more than 9600 baud transmissions with no special hardware.
Quote
Over5

Over5 is a c64/vic20 < - > Amiga/Pc/Unix-box transferring program. It supports serial transfer at 38400 bps using only a RS-232 level converter (like the VIC-1011A RS232C or the Handic V24 interface) and a 3-line standard nullmodem cable. NO special serialport chips needed!

I don't know how Over5 does it, but i think it must be something like polling the userport directly with everything else (Kernal, Interrupts etc.) disabled - or something like that.
I know that the Over5 source is available and i had a look at it - but that seems a bit to "oversized" and too much specialized for my purposes.

They don't do it.  The reality is that none of these claims has ever been supported by actual testing under CBAT conditions.  Even at a paltry 2400 bps CBAT, a lot of time is spent processing in software.  At 9600, the 128 would be spending nearly 75 percent of the available processing time servicing RS-232 CBAT.  As I said, don't believe all the BS you read on the newsgroup forums.

Quote
I'd be glad to have a working replacement for the Kernal-RS232 routines which can cope with 9600 baud (in 2MHz/ 80 col mode of course). Desterm proves that it is possible. I have a proper vt100 emulation at 9600 baud when logging into my linux machine and i would like to have that "stand-alone" in own programs.

You got something against ACIAs?  <Grin>

Quote
So I might better ask: Is there any chance to get a copy of the Desterm source??

Why not see if you can work out your own RS-232 drivers?  It would be very...er...enlightening, especially in trying to work around CIA ICR bugs.
x86?  We ain't got no x86.  We don't need no stinking x86!

brain

I can verify that you can do 38400 through the user port at 8N1.  Over5 can be downloaded and tested to verify my claim. 

CBAT is possible by:

turn off VIC-II
spin on the CIA bits looking for the start bit.
When found, send your own start bit and nop for start bit time.
pick up first bit, send first bit, and nop for full bit time.
repeat for 8 times.
send stop bit and watch stop bit.

save byte in register and load new value for sending.

repeat process.

Note that, while you can do 38400 CBAT in this mode, you can do nothing else.  No DMA, no VIC, no IEC, nothing.

Thus, it won't work as a general purpose KERNAL replacement.

With the Daniel Dallmann UP9600 interface, 9600 is possible in the 64 and I think 19200 is possible in the C128 in fast mode.  Daniel's interface works by using the CIA shift registers to send all 8 data bits in constant time without NMIs, reducing the NMIs per byte by 7.  CBAT operation is assured at that speed.

Don't believe everything you read from forum posters who say it can;t be done, either.  In this case, c.s.c. and Over5 are correct.

Jim

BigDumbDinosaur

Quote from: brain on February 26, 2008, 06:31 AM
I can verify that you can do 38400 through the user port at 8N1.  Over5 can be downloaded and tested to verify my claim.

In CBAT mode on a machine that is usable as data is flowing at that speed?  I don't think so!

Quote
CBAT is possible by:

turn off VIC-II
spin on the CIA bits looking for the start bit.
When found, send your own start bit and nop for start bit time.
pick up first bit, send first bit, and nop for full bit time.
repeat for 8 times.
send stop bit and watch stop bit.

save byte in register and load new value for sending.

repeat process.

Note that, while you can do 38400 CBAT in this mode, you can do nothing else.  No DMA, no VIC, no IEC, nothing.

You've described a useless "solution," that is, a programming exercise in futility.

Quote
Thus, it won't work as a general purpose KERNAL replacement.

Talk about an understatement!  As I said, the machine is useless under those conditions.

Quote
With the Daniel Dallmann UP9600 interface, 9600 is possible in the 64 and I think 19200 is possible in the C128 in fast mode.  Daniel's interface works by using the CIA shift registers to send all 8 data bits in constant time without NMIs, reducing the NMIs per byte by 7.  CBAT operation is assured at that speed.

Of course, except it isn't the standard Commodore serial interface anymore, eh?  I seem to recall that Mr. Hannenz said that he didn't want to go through all that trouble.

Quote
Don't believe everything you read from forum posters who say it can't be done, either.  In this case, c.s.c. and Over5 are correct.

If you carefully reread my reply you will also see that I specifically referred to attaining 57.6 Kb/sec using strictly kernal-like, interrupt-driven code with no external hardware kludges.  If one is going to go through that sort of trouble, one might as well as use a real ACIA.
x86?  We ain't got no x86.  We don't need no stinking x86!

brain

Quote from: BigDumbDinosaur on February 26, 2008, 09:28 AM
You've described a useless "solution," that is, a programming exercise in futility.
It is most definitely useful.  X-developers can use such a routine to quickly dload working code into the 64.  All you have to do is set a byte or flag that branches out of this loop.

Quote
Of course, except it isn't the standard Commodore serial interface anymore, eh?  I seem to recall that Mr. Hannenz said that he didn't want to go through all that trouble.
UP9600 requires only 2 additional wires, and many current "standard" CBM serial interfaces (EZ232 and Fotios' version) have jumpers or switches so no wiring is needed.
Quote
If you carefully reread my reply you will also see that I specifically referred to attaining 57.6 Kb/sec using strictly kernal-like, interrupt-driven code with no external hardware kludges.  If one is going to go through that sort of trouble, one might as well as use a real ACIA.
In your first email, you provided some math showing why a simplistic NMI based solution will top out above 4800 bps CBAT.
In your second email, you claim Over5 does not do what it does

Nowhere do I see the stipulations you now refer to.  I would not call the UP9600 changes "kludges".  The OP wanted to know about >2400bps using a simple interface, and UP9600 is a good general purpose option, Over5 is a good special purpose transfer solution.

Let the OP decide what is "useless". 

Jim

hannenz

i found these routines in the transactor magazine, providing kernal-replacement for up to 2400 baud (error-free):
http://cbm.csbruce.com/~csbruce/cbm/transactor/v9/i3/j1.html
i just had a short look at the article but i think that with the right timer values, it should be easiliy possible to drive them up to 9600 baud in 2Mhz mode, or what do you think?!
just for the understanding: is rs232 recieve/ send as easy as:
read/ write bits from/ to $dd01 at the right time (where "right time" is the critical part as well as synchronizing read and send to each other) ?? or what did i miss. And how is the Start-Bit detected? sorry but i have never done anything on the Userport before, so my question might be a bit silly but i hope someone will clear ihis up for me... thanks.

brain

As BDD noted, those routines are IRQ intensive, and at 9600, even at 2MHz, you'll be swamped with IRQ requests and the latency associated with them.

If you want to do 9600 reliably, you need to use the Daniel Dallmann routines, which ease up on the IRQ requirements.

In general, you are correct for transmit.  For receive, the user port has a IRQ line on it, which the rs232 interface uses to determine the start bit.  From there, it's just timing.

If you plan to use the transactor routines, look online for the Fuzzy Fox mods to those routines.  Fuzzy FOx added parity and other things to the routines.

Jim

hannenz

thanks!
in fact i played a bit with the transactor routines today; i'll have a look if i can find these "FuzzyFox" mods....
to get back to the 9600 issue: will it be hard or impossible ? ;)
it must be possible since Desterm allows 9600 with a standard interface while doing reliable recieves and sends, e.g. Terminal emulation, so....
let's see if i find the time to dive deeper into that topic... although serial netwroking is a bit outdated having RR-Net /FB-Net and friends available today... but still it is fascinating in some way. And using the Userport keeps my expandion port free for the REU, which is quite important for me, so for small file transfers/ terminal emulation into my linux box this serial approach seems to be quite suited to my needs...
i am planning to do a vt100 terminal emulation in Power-C with xmodem (maybe y/ zmodem) file transfers, so i can easily exchange files from my PC to the Power-C shell. The emulation won't be perfect vt100 but some close to it and is 70% finished but at 1200 baud max at the moment (kernal routines), so i look if i can get a bit faster still.

hannenz

i just wondered:
when doing any timing, i can
a) use the cia timer, which runs always at 1MHz: Question: is this 985248.4 Hz (PAL) and 1.02..... Hz (NTSC) or just exactly 1000000 Hz???
b) count instruction cycles. Question: When in 2 MHz mode, can i just divide the clock required cycles per instruction by two, e.g. a NOP taking 1 cycle?? or is there more to be considered...?!

i am still looking forward to get reliable 9600 CBAT in 2MHz, or at least 4800 with no special hardware and i am sure i can do it ;) - i just wonder why there doesn't exist any routines, since serial comm. was one of the main programming tasks back in the 80's on the c128 and it is known and stated everywhere that an unexpanded c128 can go up to at least 4800, propably 9600... )

(i do own a "dallmann" 9600 interface, but this one doesn't like my c128 since it locks up the 1571 as well as the 1581 as soon as it is attached, for some reason. it does work in c64 mode, though - having the same drives connected - )

brain

The CIA timer runs at system clock speed, so .985... and 1.02... MHz are the correct values.
You can count instruction cycles, though that means you will be in your RS232 CBAT code during the entire receive/xmit time.

Jim

hannenz

i am aware of this, yes (that the code has to be into rx/tx all the time when counting cycles) and of course this is surely not the most preferable way but i am in testing and trying now, so i just wondered. And even if i use the timer and if i shoud decide to use NMI, i still will have to know how much cycles (time) has been gone by execuing  then NMI handler's overhead to set the timer correctly.
so, cycle times in 2MHz mode are just halfed, is that right?

hydrophilic

Cycle timing in 2MHz is a bit tricky.  Basicly, the cycle time is 1/2, unless the instruction access an I/O register.  Then for whatever cycle(s) of the instruction access I/O, the time will slow down to 1MHz.

For example,

NOP = 1/2*2 = 1 cycle
LDA $1000 = 1/2*4 = 2 cycle
LDA $DD01 = 1/2*3 + 1 = 2.5 cycle
INC $1000 = 1/2*6 = 3 cycle
INC $DD01 = 1/2*3 + 3 = 4.5 cycle

I hope that makes since because it gets worse.  If the 1MHz clock is in-phase with the 2MHz clock at the time of I/O access, then the above is correct.  If the 2MHz is out-of-phase, then an extra 2MHz cycle delay is needed (an extra 0.5 cycles of 1MHz).

And that is not all.  During DRAM refresh which occurs every raster (even with VIC disabled), the CPU will slow down to 1MHz for 5 cycles.  So basically you get 59 fast cycles + and 5 slow cycles per raster, or 123 cycles/raster, approximately (note I used 64 cycle average for raster; I think the actual values are 63 for PAL and 65 for NTSC).

If you're totally confused, you're not alone.  I think it's the main reason VICE was without 2MHz for so many years.

hannenz

OMG!!!!

thanks for clarifying but that ist in fact too tricky to do serious timing with it. i'll stick to the cia timers instead, i think...