-
A line display and connecting to a computer for the first time
a day ago • 0 commentsOne issue that I've already noticed is that most typing has to be done blind.
This is because the Alphacom can't print character-by-character, just a whole line at a time. (You need to rasterise your line and send 8 pixel lines. The paper transport is one-way. Plus you can't actually see the line being printed, it's covered until the paper scrolls up.)
This is project creep but I think this is an enhancement that will make the project much more usable. I started to think about adding a single-line display so that you can see what you've typed. I've played with various displays for the RC2014 over the years, but one in particular feels right for this project.
A few years ago, Spencer designed a bubble LED display. It's hard to do LED displays justice in a photo but these displays are beautiful and period-appropriate for what I'm doing. The HP 5082-7400 is an early 7-segment LED display packaged as groups of four. The module has two of these for eight characters.
![]()
A 7-segment display won't display an entire character set perfectly with uppercase, lowercase and all the symbols and punctuation, but it'll display them well enough to see what you've typed before you hit return.
At the time I wrote a code 'toolbox' for this module and so it didn't take long to incorporate this into my application.
I had to add another buffer to cache the characters that have been typed (the existing line buffer is a pixel buffer for the printer and therefore stores the characters as bitmaps). I was already planning to switch to a character buffer anyway to enable word-wrapping and make things like backspaces a bit easier. Writing to the printer pixel buffer only needs to happen before sending that data.
Since the display only has eight characters, it needs to scroll horizontally as you type. This works great, here's a quick demo:
So far I've had a modern terminal emulator plugged into this, so that I can type both ways. It was time to try plugging in an(other) RC2014 and see what happens when they're connected serial <-> serial.![]()
Here's my RC2014 Picasso plugged in. Fun fact: This series of RC2014s has a header marked 'keyboard' which is actually another FTDI header but with the rx and tx switched. This allows a very neat connection with a straight-through FTDI extension.
I don't yet have my terminal application in ROM, meaning that I had to first connect to my Mac's terminal emulator and send and start the program in the usual way, before some fairly sketchy swopping of the serial leads to plug in the Picasso. (It currently boots to SCM. I optimistically thought I might even be able to type and run some assembly.) That worked... to a point... but the results weren't an unmitigated success.
![]()
There are some garbage characters - possibly escape sequences or non-printing characters. It's trivial to sort those things out. More importantly there are a lot of dropped characters, particularly when the computer sends multiple lines. I think this is because interrupts have to be disabled while we're sending a line of characters to the printer. I do have an idea that may at least help with that. The worst case scenario is that I can only run programs that are written with this teleprinter in mind. ie for each line of characters written, pause to allow the printer to print.
Rome wasn't built in a day.
-
Working serial
08/25/2026 at 20:00 • 0 commentsI now have serial working on this project.
It's the third major piece in the puzzle. I had procrastinated on this part because I'm a little scared of serial on the RC2014.
I know how it all works, I've dealt with it in other projects, notably my TMSEMU and my MIDI module (the latter handles serial in and out from the MIDI ports as well as the usual terminal connections). But I still find it confusing.
I needn't have been worried. I've already done the work in my MIDI mk2 module and so it was more of a copy / paste exercise.
It sets up interrupts on the 6850 (SCM, the monitor I use on this 32k RC2014, doesn't use interrupts) and installs an interrupt handler that buffers the incoming data.
Now the keyboard scanning routine, which is just done in the main loop, sends a character out to the serial chip when one is typed.
Half the battle is working out how you're going to develop/test this stuff.
I've been working with this RC2014 hooked up to my Mac's Terminal as usual (that's necessary to load the program - eventually it'll be in ROM but while I'm developing I'm loading each new build of the program into RAM in the usual way).
So with this running, I now have the world's worst messenger. Anything I type into my Terminal emulator on the big computer comes out of the Alphacom (after a carriage return) and anything I type on the MSX keyboard appears in the terminal emulator.
The title of this log is 'Working serial' and what that means is that 20% of the work is done and now we're embarking on the harder 80% - finding and fixing all of the problems or things that haven't been taken into account ...
![]()
... such as line-wrapping; the printer needs to print a line and clear the line buffer after 32 characters if no carriage return has been received. (We won't get into word-wrapping at this point, although that shouldn't be too tricky).
![]()
That's better! As you can see it took a few tries!
The printing routine disables interrupts (for timing reasons). So when you reach 32 characters in the line buffer, the printer's going to fire up and print the line - ignoring interrupts from the 6850 while it's working. I expected this to mean the odd lost character or two, but so far that doesn't seem to happen. If it does, then I may have to make calls to the interrupt service routine during those delays in the printer code.
I guess after a little more testing, it'll be time to build this for a ROM and connect this to a (nother) RC2014 to see it actually working as intended.
-
Progress with keyboard scanning and printing
08/23/2026 at 23:36 • 0 commentsHaving proven the concept, the next step is the hard work of knocking the code into shape and I've put a lot of hours into that this week.
(I do it all myself, I've never used any kind of AI help. This is a hobby. I love coding.)
This application has several aspects. I don't know yet how it'll all be structured (buffering, interrupts, that kind of thing) and I haven't thought about the serial i/o yet. I've first focussed on the keyboard scanning and the printing.
Key scanning and mapping
I probably mentioned earlier that I'd be using MSX BIOS code for the keyboard scanning. Actually scanning a keyboard row is really simple, there's very little to it. This is the only part that's straight from the MSX:
![]()
The rest is my own. That's obviously called from a larger chunk of code which loops for the number of keyboard rows (9) and handles the raw data, and then an even larger chunk turns the raw key into an ascii value.
We 'just know' how a keyboard works and don't really think about it. But there are many rules. For example, a 'caps lock' flag needs to be toggled each time the caps key is pressed down. The caps lock LED, which the MSX keyboard can have, is under computer control. A shift flag needs to be set if the shift key is pressed down, and reset when it's released. A letter character needs to be capitalised if the caps lock or shift key is flagged, and other keys need to produce a symbol depending on the state of the shift flag.
I spent some time on the logic for detecting a new key being pressed. When you're typing at speed, you often 'overlap' keys - the new one goes down a fraction before the previous one goes up - and so there's some xor'ing and and'ing to do with previous value and new value to detect a change and then find whether that change is a key up or key down. I've handled button pressing before, but to get this working as smoothly as anyone would expect a keyboard to respond today took some work.
The key mapping on an MSX (defined in early '80s) is surprisingly close to today's keyboards. The MSX allows for various keyboard standards, but because this code will be used within this one project, I don't really need to worry about that, but I've defined it like this for easy future changes
![]()
These are the keyboard matrix rows and bits, and these arrays make it easy for my code to do the lookup (in C, these would be two dimensional arrays, referenced by keyboard row and bit number).
One interesting point to note is that this map has them in alphabetical order. You can tell that the person who wrote this wasn't the same one who'd be laying out the tracks on the keyboard pcb!
Eventually I could detect key presses, turn all letters and symbols into their ascii value, with caps lock and shift working and send those characters to the console:![]()
Printing
I was very chuffed when I first had Rob's code printing out the RC2014 logo, if a little messy.
Text had printed out really nicely when using the ZX81. However, after writing some routines to copy character bitmap data into a buffer and send that to the printer using Rob's code, things didn't look quite so good:
![]()
To cut a long story short, the difference turned out to be the speed of the computer. The RC2014 is running at 7.4 Mhz, around twice as fast as the ZX81. The successful 'Hello World' at the bottom of the above photo was printed with the same code, but with the computer's clock halved to 3.7Mhz. At this speed, the RC2014 logo looks a lot better:
![]()
That's not a permanent solution because I'd like my teleprinter to send/receive serial at 115200 (which I almost always use on my RC2014s) and that requires 7.4Mhz clock. I don't want to get into dual clocks.
The code does check the status of the printer and wait for it to be ready before sending a line or a pixel, so in theory the speed of the computer shouldn't matter. But it seems that at the faster speeds, you can jump in ahead of it saying that it's not ready. Or maybe you can't read that status bit on this printer as per the ZX printer which this is supposed to be compatible with. Either way, the timing is important here and we need to compensate for this computer's faster clock.
Rob had already handled this in the outer 'print a line of pixels' loop but not in the inner 'send a pixel' loop.
It took a little bit of experimentation to find the magic number for the smaller pixel delay (too much was nearly as bad as too little) but once dialled in, text started printing very nicely with the computer running at the full clock speed.
![]()
Finally for this log, I wanted to put the keyboard scanning and the line printing routines into a single program and link them so that a carriage return would send a line of typed characters to the printer. Here it is:
Obviously the keyboard won't be sending directly to the printer in the final project, this is just a test. But this is an important milestone and I'm really happy to see this working. It gives a taste of how the finished project will look and feel and I like it.
-
Proof of concept: driving the printer and scanning the keyboard
08/21/2026 at 09:04 • 0 commentsFirst catch your rabbit.
Or in this case, first excavate the Alphacom printer from the attic and make sure it still works.
![]()
First test is to plug it into a ZX81 as intended and use the LPRINT and LLIST command to send something to the printer. The printer wants a 24V AC supply. I've previously cobbled together an adaptor so that I can use an Acorn Electron brick. This is allegedly 19V AC, which seems close enough and does work.
![]()
The second test was to build Rob's code and print the RC2014 logo. Thanks to Rob for his Alphacom / RC2014 interface, which allows you to choose a specific port (when connected to a Sinclair computer, the Aplhacom responds on any port where A2 is low).
This took longer than it should, partly because I'm using a different compiler to Rob and had to fiddle with his code a little. But in the end, this printed out. Yes, it looks a little messy, but so does Rob's! He says that this is related to the way he scaled and converted the image.![]()
Then I wanted to test whether I could read the MSX keyboard. This wasn't as straightforward as it could have been. I've already built my own MSX PPI module (Programmable Peripheral Interface - for interfacing with the keyboard and doing a few other MSX things. It provides ports for scanning the keyboard). I eventually found the MSX BIOS code which actually does the scanning - specifically a routine that you send a row number and get a value back.
![]()
The big problem here is that the RC2014 serial module doesn't decode its port numbers fully ($80 and $81) and clashes with the ports that my PPI module uses ($A8, A9, AA, AB). So the first thing I had to do was to modify my serial module and tighten up the port decoding (specifically taking A5 into account, which is the difference between $8x and $Ax).
![]()
With that done, it wasn't too difficult to scan a single row repeatedly and output the result to my digital i/o and see lights coming on when I pressed keys 0-7.
So now I have working code for an RC2014 classic that can send data to the printer and scan a mechanical keyboard. I've shown that Rob's Alphacom interface module and my PPI module both do what I need. There's now a lot of coding to do.















