I doubted I would be able to. Nothing like proving yourself wrong.
Managed to take the disassembled ROM code. Remove the offending BREAK routine and Border flicker.
Plato works perfectly.
So, I have not only had some C code published. I have now written a library/driver, with some assembly in it. Probably to be cleaned up and accepted by a compiler maintainer.
Still can't believe the silly buggers put a check on the break key in there, and a half check at that!!!
Did you miss me? Who am I kidding no one reads this, I will be lucky if Weebly is around when I am old and losing it. (When I will need to look back at these entries and remind myself of this time in my life.) I write for the enjoyment of it, like a graffiti artist spraying on a subway wall. This is me marking the world in some way.
So what have I been doing, well more Plato PLATO PLATO stuff on the speccy. Having refurbished the old machine, checked the Interface1 is "safe", made an RS232 lead up. What do you think I did. I loaded the PLATOTERM up and connected it to IRATA.ONLINE. Bloody worked first time, got the lead correct the code worked every thing went well. Up until I decided to write a note to claim dibs on 48K on-line. Pressed space and the program stopped. After a few repeated attempts, the pattern of the problem wasn't a coincidence. You have some room for doubts with a machine over 30 years old, an interface of similar age with no knowledge of history. Touching a Sinclair Spectrum and having it randomly crash is not unusual behaviour many people have been known to tape EVERY thing down on the table to prevent crashes.
Space on the old rubbery key 48K is a special key, it doubles as the BREAK key. Usually in combination with the Caps Shift key, to invoke the BREAK function. Looking at my modern keyboard its labelled as Pause, if you have one on your keyboard its probably dusty but in pristine condition. Its rarely used by most people, there is probably one person that will read this and say "I use it all the time". Great, what for?! Traditionally Break was the big red button for stopping programs that are executing. In today's multitasking multi threaded applications its a little difficult to know what you want to break! So knowing a little history, spotting the blanking (black ink on black paper) at the bottom of the screen it eventually clicked. Hitting space which I didn't need to do signing on, selecting menu items etc was causing the Break to fire.
OK so why do we get a break event on a 48K and not on the +3. Thom's cool head got me in to line, back to basics he sent over 2 programs. One a key code print program, easy press key get 0x## hex code for the key. The second program was a tiny terminal, basically read a key send the key check for RS232 inbound data. Nothing exciting about the key codes. Really didn't take long to find the fault was still present with the tiny terminal. In a way its nice to know the main PLATO application wasn't at fault. After some playing about with tiny terminal it became apparent the break key was detected if Space/Break was pressed during and RS232 operation. Having looked at the fairly empty library files and Z88DK dev team confirming what was suspected. The library files are just wrappers for the ROM code routines. Z88DK developers gave Thom a bunch of tricks to try and clear the keyboard buffers etc to avoid the problem. I suspected the problem would inevitably be the ROM code itself, based on gut/experience. (Sods law, Murphy's law its that one place we don't want the problem to be!) The tricks worked well enough that I managed to post a note. It went from 100% failure on pressing space to 1%, you have to try to break out but it can still happen.
Never expected to ever have a reason to look through the ROM disassembly of the spectrum. Surprising how the simplicity and almost beauty of assembly comes back to you. Nice to see comments in code to! Slapped boldly just before the bit banging of the line for data transmission, a call to check for "Break key". ...Sigh... Not a full check for break and Caps Shift, no just a quick cheeky check on the one key. Why would you do that?! From what I can tell, the RS232 port was only really intended for use with printers (back in the day serial printers were a thing). The ROM routines had been written with this in mind, hitting space/break would let you quickly stop a print job. The CPU bit bashing the port would lock the machine in to a fairly tight loop, this was the quick safety feature to stop printing. A design feature that would have stopped any one using basic for writing even a simple terminal application. If Clive Sinclair really wanted his machines to hit the Business market terminal applications would have been a big selling point. Granted there were modems devices sold, but a basic serial port enabled machine opens doors. Its impossible to know what was going through someones head at the time. May be the code was rushed known to be buggy so they just sold it as to be used for printing.
Looking at the disassembly of the IF1 ROM thankfully its well documented with comments. Finding the serial routines was not difficult, commenting them out wont be difficult. Getting the entry and exit conditions well that might take a little work.
One of the fun things about doing this sort of thing is leaving little Easter egg comments in the code. Some day it might snake its way upstream and sit in code that someone reads through looking for answers. It might just make someone smile at a time when they really need it! (P.S. Sorry if this code has screwed your project up!)
; OUT ($FE),A ; Change the border colour. - No Thanks Jetset Willy change the borders in program if wanted
Hard part is trying to get the ASM code to start and end as required so not to crash. I have a lot of crashing going on, which is nice because I am changing things and it is having an effect on the system. Keep at it and we will see how long this takes...
If you are still reading you are either interested or in need of sleep. The idea behind Thomas is actually a lot bigger and admirable. I actually can't help but agree with him. He is porting the PLATO terminal code, written in C to EVERY DAMN SYSTEM he can. ZX Spectrum, C64, MSX, IBM5150, ATARI ST, Amstrad CPC
Entry point requirements are low, at least low enough that most practical 80s home micros can make the grade. With the resurgence or yet continuing influx of people to the retro "thing", does it not make sense we should meet on a retro platform? Yes there are many other forms retro systems that could be used. IBM mainframe (oh IBM would freak over licensing), UNIX, Prestel and even BBS systems which are still going strong on TELNET. PLATO, has a slightly magical look. Computers depicted in old SCI-FI TV shows and Films, showed graphics that you wouldn't see on a home computer or on the office systems. PLATO hits this spot perfectly. The platform can even do interactive multiplayer games, don't go flipping the table thinking Doom on terminals. No no, pong, at a push a flight sim, an early dungeon crawler and countless board games (this is early tech pre 80s!). Talk and notes systems make for pre "Email and IIRC" replacements. Its all a bit quirky too, pre-dating most of the standards we take for granted these days. There is a need to learn some old new features, keys like "next", "data" and "back" none of them on your keyboard so key combos required. For content out of the box we are in luck, any one into computer history or general interest has several thousand teaching lessons to explore. I am not joking there is a tutorial on how to operate a nuclear reactor, this system found a market in teaching. Most of the content in there is common knowledge, but hasn't been seen by a wide audience.
What about the Rabbit hole?
Yep and BT phone jacks for serial ports didn't fly. So out with the soldering Iron and time to dig through a box to find the right bits. Retro computer systems are selling the lead above, gets you out of the BT jack problem. If you want to know how the pins should be connected check T.F.M. The lead got re-wired A LOT. So many undocumented features. Just the tip of the problems. No mention in the +3 Manual about the pins being labelled up DCE style, not DTE. Oh yeah remember DTE and DCE is a thing, every thing in general PC land has been DTE since we stopped using modems (well from what I have done in the last few years). That ain't a normal serial port in your Sinclair, its not got an RS232 chip behind it. Hasn't even got a buffer... It the AY chip being "Bit Banged" by the CPU as a software port. So enters the next problem. How is the serial port implemented in the software library in Z88DK. Having played with micro-controllers this isn't a new idea, but its functionality really depends on the code. It gets bad when you start reading source code, and following the references back to the project they borrowed from. So basically the code was lifted from another guys terminal program (credit you later fella). He used RTS/CTS signalling to flow control the serial link. This is actually very clever trick, as it means you don't lose data when the CPU isn't running the port. Also if you signal ready to receive you can expect the start bit to appear in about half a bits time. No start bit, no data stop messing with the port and get back to the program. Control of the serial port requires precise timing, well good enough still the interrupts need turning off while CPU does port stuff its really quite intensive work at 3.5Mhz. Bottom line if you get the lead wrong, you get nothing or crap on your terminal.
Given the order of the parts, the order of the story isn't matching is it? The terminal, oh the terminal. Thomas has done so much work on it, I can't fault him. He has built around being a portable application, that he ported to the ZX spectrum with Z88DK in under a week. OK most software houses couldn't port their application in a year (I don't know really, but the big guys screw up a lot). The code is designed for portability on some of the most unique hardware systems going. FUSE loosely supports serial ports for Interface 1 not +128K machines, and even then I haven't tried it as its all murky. Running the code on a +3 with made up cable and TCPSER, is pretty much first run pre-Alpha territory. Has anyone in the world ever actually tried this? There is nothing in WOS (World Of Spectum) archives. Fair to say "Dorothy we ain't in Kansas any more". So when I ran the terminal for the first time I wasn't really sure what to expect. Tapping a few keys and have nothing on screen move, was it a fault? The FUSE Spectranet version just connected and had a login prompt.
After a few messages back and forth with Thom, he filled me in on some details. I probably should have asked before I started, might have saved myself some time! But it was Exciting Yo I just wanted to get going! It should start up and act like a normal terminal, letting you type text on screen. Just like any other text terminal you would give ATDTirata.online:8005 to dial up. -hmm- tap tap tap... OK dialing when you can't type is an issue. There is no need to type if you run TCPSER with -i "&K3&DTDirata.online:8005". You might think this is in order, no the story isn't in order. If you set the baud rate wrong, you get crap on your terminal, Thom filled me in 1200 Baud default start point in his builds. If try DTR/DSR you get nothing or some random hang ups. If you get RTS/CTS wrong your terminal hangs. If you turn handshaking off you get crap on your terminal, YOU MUST USE RTS/CTS. If you don't get DCE DTE pin outs correct you uncross the crossed connections, so TX RX not being crossed your terminal hangs. Same applies to RTS/CTS! Oh thats DTR/CTS line on Spectrum, go back to DCE DTE pin outs and work out DTR is CTS and CTS is RTS.
Are you confused? A little? I was for several hours for several days.
Well throw in the last unexpected bug. Terminal appears to lock up in the first version of the terminal.
Yep f**kin' keyboard won't read. Debug ALL the above when you have that problem hidden in there. Technically its not true, keyboard will read for a few clock ticks between Serial port calls. When the serial port is called interrupts are turned off remember. So NO keyboard scanning, no scanning no key presses detected so back to the serial port checking. Gets even better, that little RTS/CTS clever trick. Well that can cause you to get stuck in the serial port code, which locks interrupts out for a long time like forever.
I haven't done much C programming in recent years, definitely a long time since looking at Assembler (no real need for either). Thankfully people comment code, or write it neatly and readable (nice work Thomas). Some how I seem to have returned to programming Rabbit hole again. After some silly ideas and thoughts I finally got down to it. Stuck some border colour painting a printf("") call in there and debugged the timing issue. Raster bars make a great sub for an oscilloscope to visualise program execution. Eventually I worked out the interrupts being off and the time when you could press a key was the problem. Dirty FOR loops on the keyboard routine in the Main(). Another FOR loop in the Else branch for checking for inbound serial data, so when not receiving data we scan the keyboard more. Finally a working terminal. Oh and if you started with turning up the Baud it didn't help (clue there).
With both Keyboard and RS232 port being implemented using software not hardware, terminal software enters into Real Time Systems world almost. Normally a keyboard buffer would catch your keys while you handle the comms, the serial buffer does the same as you read the keyboard buffer. Remove one or both and well, your expected behavior flies out the window. When there is little in the way of consolidated documentation covering the compiler and hardware implementation it's a sodding nightmare. Might explain why we didn't see a boom in terminal applications!
Final result. 9600 Baud, reasonably responsive terminal to keyboard and RX data using DCE to DTE null modem cable (straight not crossed) with RTS/CTS flow control. Probably the first +3 ever to connect to a PLATO system.
Whats the story with the story order?
This was actually the events over several nights. With one of the kids waking up at 2 in the morning every night for most of the week.
I bounced between the front room and the garage to re-solder the connectors. I completely missed out a bit where I spent several hours with one of the RTS/CTS leads broken and nothing worked.
The collection of faults in every part of the chain combined with no actual concrete documentation to fully explain any part of it just made a perfect storm. A random mashing of 360 degrees of problems not a simple start to end. Just like the story will you try to keep up.
Now I'am not saying there is "no documentation", or that any documentation is bad/poor/wrong. Each piece I looked at explained the serial port pin out for example in the context required for the application the document was about. Paul Farrow's Data Cable is actually what you want. He just doesn't mention DCE and DTE pin outs for ZX and PC but he doesn't need to! You just follow the pin out and build that lead to use his application. He comments on RTS/CTS handshaking in his data cable and it being used for reliable communication to a PC. There is no connection to the Z88DK library implementing RTS/CTS as MANDATORY. Z88DK doesn't document RTS/CTS as needed for the serial library, thankfully it is mentioned by Russell Marks ZFST terminal documentation. The source code comments refer to it as the source for their implementation. And he DOES mention it quite clearly!
Even the original +3 manual has a clue split over two pages in two tables. The Serial table (top left) might be what you look at. Stop, look at Auxiliary interface table (top right), you get pin and signal direction. OK there is actually an error TX is not PIN 5 it is PIN 2 check table left. RS232 Pin 3 RX OUT PIN 5 CTS OUT, then look at a DCE Pin table and things become rapidly apparent. But No mention of it being DCE pin layout, DTE in PCs has been my world so yeah not obvious. The serial port was also only really intended for printers, which probably explains the wacky choice of pin assignments. Having a set of handshaking pin DTR/DSR or RTS/CTS would help. Yeah the manual helped, but it also screwed you over. There are going to be people pointing at Amstrad for this, but I would be interested to find Toaster Racks manual, as big chunks of the Amstrad manuals are copied from the originals. Could be these typos and lacks documentation have carried on from pre-Amstrad.
Was it worth it? Bloody hell yes, and yes some more. I have learned more in this crazy stunt than I have in years. Kicked the dust off C programming, I didn't read assembler but did get in there at the comments. I got to write a message on an internet connected +3, a system I have had since childhood. Technically "my" first computer, Dad had a 48K but that was more his and I had ago once in a while. Probably the same way as I let my eldest son play on the NES, its mine but he can have a go.
Is this the end? No, I have promised documentation. I need to sit down and get more than a ramble blog together. Explaining the pin ports, that it is software serial and how Z88DK library works. This port is important, it actually hold a path to getting Spectrums online with minimal hardware. One serial cable to an internet connected system running TCPSER. It can be made really simple with some effort. While Ben's work at Bytedelight.com is also important getting spectranet hardware available to buy. Thomas bringing PLATO online and getting the terminal code to every platform. I think there is a little spot here to help, getting more people online with a simple RS232 connection. The more node on a network the more likely it will live. RS232 will get them in and if they want more Spectranet will be their next step.
If nothing else the note back from Thomas on PLATO was worth it. So in the voice of Arnold Schwarzenegger, "GET YOUR ASS TO PLATO, I'LL SEE YOU ONLINE"
Me, slightly crazy engineer type. Generalist in nature, hardware or software with nonspecialist skill set.