2022-03-26

Voiding the warranty on a 1993 Minitel 2 to run arbitrary firmware

In a previous post I wrote about using a Minitel 1b as a serial terminal. In this post I'm going to look at modifications I made to a Minitel 2 so that it can run arbitrary firmware from an EPROM. If you speak French, or are happy with automatic translation, then Jean-François Del Nero's post on the workings of the Minitel 2 is a good place to start. At the end of this post I will be running his Minitel 2 demo firmware on my Minitel 2. 

He plays some neat tricks with the Minitel's character-based video to fake up graphics like this:

Inside the Minitel there are two boards: one dedicated to the input power and handling the CRT (that's the vertical board on the left) and a motherboard with the 8051-based CPU, modem, video controller, etc. Since CRTs use high voltages and there are some big capacitors on that board I'm staying away from it for the entirety of this hack.

Dude, where's my EPROM?

Here's the motherboard of my Minitel 2. I've marked up the major chips. If you take a look at Del Nero's post you'll see that he replaces the EPROM containing the standard Minitel firmware with his own code. But, alas, my Minitel doesn't have an EPROM at all!


But you can see the place where a 40 pin socket would have been had this model used an external EPROM. In my Minitel, the firmware (with code name BV9 written on the top of the chip in the same as the BV9 on Del Nero's actual EPROM; I guess by the time mine was built they were pretty confident about the firmware) has been burnt directly into the microcontroller CPU. 

I thought for a while that I might be stuck, but careful examination of the PCB showed that all of the traces were in place for that socket.


And reading the CPU's datasheet showed that whether it executed code from the internal ROM or external ROM was dependent on the state of the EA pin on the CPU. 


Looking at the motherboard I could see that EA is pulled to Vcc via the resistor 3401 and wire 9045. Since I'm obsessed with double-checking things I went back and looked at Del Nero's motherboard and that resistor and wire are in place. Hmm. What's pulling EA down to Vss then? 

Luckily, another Minitel fanatic whose Minitel 2 posted a picture of the reverse side of their motherboard.


On that motherboard there's a surface mount, zero ohm resistor (i.e. a wire) that connects EA to Vss (it's still connected to Vcc as well but through a resistor).

OK, so it seems pretty obvious to me that if I removed the solder pads from where the 40 pin socket was meant to go, added a socket, burnt a suitable EPROM and pulled EA down to Vss I'd be able to run external firmware on EPROM.

A small matter of soldering


First step, was add a socket:


The next step was to pull down EA. I choose (unnecessarily) to cut 9045 and separate the Vcc and EA lines. I was originally planning to use Vcc for something else. If you do this then you could just connect 9045 to Vss and be done with it. 

Making the EPROM


Then I took Del Nero's firmware from GitHub and burnt it onto a suitable EPROM. The Minitel uses a shared address/data bus and thus the EPROM needs to latch the address and so "standard" EPROMs don't work. Luckily, the 87C257 is readily available and programmable using my Dataman S4.

I wrote a couple of tools to perform the Dataman S4 checksum and to turn a binary file into an Intel HEX format for the Dataman. Del Nero's file is demo_minitel.bin and I first checksummed it so that later I could double check on the Dataman.

target/debug/s4checksum < /tmp/demo_minitel.bin
00289F61

Next up, I converted it to an Intel HEX file.

cat /tmp/demo_minitel.bin | target/debug/bin2intel > /tmp/demo_minitel.hex

And then uploaded it to the Dataman S4 via miniterm.py. There are a lot more details of operating the Dataman S4 in my previous post.

--- Available ports:
---  1: /dev/cu.BLTH         'n/a'
---  2: /dev/cu.Bluetooth-Incoming-Port 'n/a'
---  3: /dev/cu.URT1         'n/a'
---  4: /dev/cu.URT2         'n/a'
---  5: /dev/cu.usbserial-1460 u'USB-Serial Controller D'
--- Enter port index or full name: 5
--- Miniterm on /dev/cu.usbserial-1460  9600,8,N,1 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
 
--- Enter new encoding name [UTF-8]: ASCII
--- serial input encoding: ASCII
--- serial output encoding: ASCII
 
--- Settings: /dev/cu.usbserial-1460  9600,8,N,1
--- RTS: active    DTR: active    BREAK: inactive
--- CTS: inactive  DSR: inactive  RI: inactive  CD: inactive
--- software flow control: inactive
--- hardware flow control: active
--- serial input encoding: ASCII
--- serial output encoding: ASCII
--- EOL: CRLF
--- filters: default
>RECEIVE INTEL   
--- File to upload: /tmp/demo_minitel.hex
--- Sending file /tmp/demo_minitel.hex ---
.........................................................................................
--- File /tmp/demo_minitel.hex sent ---
 
EOF 07FFF
>CHECKSUM RAM
00000,07FFF 
SUM = 00289F61
>

The Dataman needs to know the PROM type which you select through the PROM button.


And naturally you need to insert a blank EPROM.


Good news is that the checksum of the uploaded file matched the checksum of the binary file. Next step was to burn a blank 87C257. First made sure it was burnable.

>PRETEST 87C257
 00000-07FFF=00000
BLANK ROM
>

Then hit the BURN button on the Dataman S4 and let it do its thing.


Finally, checksum the EPROM itself to make sure its correct.

>CHECKSUM RAM
00000,07FFF 
SUM = 00289F61
>CHKSUM 87C257
SUM = 00289F61

Looks good, so I popped it in the Minitel, used a wire to pull EA down to Vss and switched it on. Amazingly, it worked first time.

It's alive!


Do not operate the Minitel with the case open, there are nasty voltages on that CRT. I always slipped the cover back on before doing this, but here's what it looks like with the EPROM in situ:


And here's what that firmware does. 


And, uh, sorry France Telecom I think I might have voided the warranty.


Next time, I'll start writing my own firmware using the Dataman's emulation mode and see what writing for this machine is like. One quirk is that the 8k of RAM is accessible to the video controller and not the CPU. Well, not directly, you can access it through the video controller... can I get this machine to run BASIC-52?

And I'll add a small switch to the Minitel so the user can choose internal ROM (original) firmware or external (custom) firmware.

2022-03-20

Using a Minitel 1B as a serial terminal

So you've got your hands on a late 1980s Minitel 1B (or something slightly later) and then you realize that the entire Minitel network shut down in 2012. What do you do? Well, obviously, you recall that the Minitel 1B (and other later models) have two modes of operation: using the modem to connect to the Minitel service or as a serial terminal via the "peri-informatique" port. With the latter you can use the entire thing as a serial terminal and connect it to something (such as a Raspberry Pi) and browse the web.

Note: there are other interesting modes (such as peer-to-peer Minitels) but I won't go into that here.

The peri-informatique port on the back of the Minitel is a five pin DIN socket which supports open collector TTL logic levels with up to 4,800 baud serial (later models supported faster transmission).


The pinout (note the ordering!) is pin 1 (RX), pin 2 (0V reference), pin 3 (TX), pin 4 (ready) and pin 5 (8.5V at 1A). With just three pins (1, 2, 4) it's pretty easy to put together a cable that turns the Minitel into a serial terminal.

And since the Minitel has an ASCII mode it'll work pretty well outside of its original Videotex format with the right combination of keys. It's important to have a Minitel with the FNCT key because it controls a lot of settings.

Note: if you speak French you can just skip the rest of my explanation and go and read Un minitel comme terminal linux USB. Partie 1 : Hardware because in this post I build and try out precisely what that blog recommends.


A simple test


A quick way to test that your Minitel is happy being in peri-informatique mode is to connect TX to RX in the DIN socket and see if characters get echoed to the screen. I did this with a small piece of paper clip connecting pin 1 (RX) to pin 3 (TX).


By default the peri-informatique port is active and so anything typed is sent out of it, and anything received is displayed. I like to set the display mode to US ASCII with FNCT+T followed by A (if you want a French version of ASCII use FNCT+T followed by F).

If you start typing you should see everything you type twice: once because you typed it and the Minitel echoed it and once because it got sent and receive through the piece of paperclip. To turn off local echo and just see what went from TX to RX, it's FNCT+T then E.

Assuming that worked then you're in good shape to turn this simple serial port into something that can be plugged into USB. For that you'll need a USB-to-serial adapter, three resistors, one transistor and a plug for the DIN socket.


USB-to-Minitel Cable


Before getting to the USB part of the connection it's worth taking an excursion through the details of the Minitel's serial port. The official documentation describes it as "compatible with TTL open collector" logic and gives the following constraints:


Firstly, we learn that logic level 0 is below 0.4V and logic level 1 is above 2.5V (and below 15V). If you look at the RX diagram on the top left you can see that when receiving a logic 1 (voltage greater than 2.5V) current may flow from the Minitel and should be below 150uA. You might be asking yourself why the receive signal would be a current source. That's standard TTL logic style.

In TTL logic inputs are typically the emitter of a transistor. Here's a simplified TTL NAND gate. Notice how the inputs are emitters in a special double-emitter transistor.


Imagine the case where A and B are tied to ground (logic 0): current will flow through VT1 across the base-emitter junction and therefore out A and B. So, an input is a current source when driven low.

OK, great, but what does the Minitel actually implement since there are no TTL logic gates on the PCB anywhere near the serial port. I ran across a Minitel schematic on line that has the serial port circruit. Here's just the RX and TX part.

The TX part is the simplest. If the processor is transmitting a 1 then the 4069 hex inverter drives the base of the transistor low which means the transistor is off and the TX port floats. This is why in Pila's USB-to-Minitel connector they pull the TX line to 5V using a resistor:


If the processor wants to send a 0 then the base of the transistor T03 is pulled to 5V and so the transistor conducts (as the base-emitter of the NPN transistor is forward biased). This means the TX line is pulled low (via the transistor) and current flows into the Minitel. Nothing special there.

RX is a whole other kettle of fish. Not a transistor in sight but three resistors and two diodes. The two hex inverters serve to make sure that whatever signal they are presented with they bring it back to clear logic levels. We'll ignore them.

I am using EasyEDA to diagram and simulate.

Receiving 0

Let's first imagine the scenario where we are transmitting a 0 into the Minitel and pull the RX line low. This looks like:




V1 is the system power (5V), V2 is the voltage source for whatever is connected to the Minitel's serial port. XMM4 measures the voltage presented to the two inverters.

So, with S1 set to pull the RX input to ground the inverters get 1.165V which they will interpret is low. Great. But why 1.165V?

Let's go component by component. D4 is reverse biased and therefore doesn't conduct and does nothing. D3 is forward biased and so current flows through D3/R3 to the RX pin. So, when the Minitel receives data it may source current.

R1 and R2 form a voltage divider which creates precisely 1.165V and also current can flow through them too.

Receiving 1

When receiving a 1 the RX line needs to be set between 2.5V and 15V according to the documentation. Let's analyze some different voltages presented on RX. 


We'll start with 2.5V. This is very similar to the 0 case above. D4 does nothing, current flows through D3/R3 out the RX pin and R1/R2 form a voltage divider this time giving a voltage of 3.082V. The inverters see that as high and all is well.


How about 15V? Things are slightly different. D3/R3 does nothing as the diode is reverse biased. D4 is now forward biased and conducts, clamping the voltage presented to 5V + the diode forward voltage (which is about 0.5V). If you check the datasheet of the 4069 inverter it says that its input voltage can be Vdd + 0.5V so that diode keeps voltages in range.

There's no equivalent diode clamping negative voltages, which is a little odd as the 4069 will only accept down to -0.5V. Perhaps it's unnecessary because negative voltages are illegal in France or something.

Finally, what happens if you just let the RX input float and don't connect it at all? This is important for Pila's design. It works fine because R4 pulls up the output to 5V.


Great, so Pila's design makes total sense and works in the real world.

You'd think the story would end there but I couldn't read the value of R01 in the scan of the schematic so figured I'd go look at the actual motherboard and find that resistor. At this point I discovered that my Minitel didn't correspond to the schematic at all. At first I thought I spied the resistors and diodes here:


But that's a 220k resistor not 270k and careful following of the traces (under ultraviolet light for clarity) revealed that the RX circuit is:


A classic PNP switch. Pull it down to turn the transistor on, pull it up or leave it floating otherwise. The TX line is very similar to the schematic. 

So, finally, I have satisfied myself that Pila's design makes sense.

Narrator: he could have just built the thing and not obsessed over it.

Using the USB-to-Minitel cable


So, I built the thing and here it is:


You could read all about it on Pila's blog but there's a male DIN connector which I've stuffed all the components inside and a USB to serial converter. Pila suggests opening the connector to verify the colours of the connectors so that RX and TX don't get confused. I am very grateful to the person who laid out the tiny PCB inside the USB connector for labelling everything:


I managed to stuff the transistor and three resistors inside the DIN plug itself as Pila suggests. Tight fit and a bit of heatshrink for insulation.


Once done I tried talking to the Minitel using Python miniterm.py (usually my tool of choice for stuff like this) and saw the following on screen:


If you instantly recognize that the reason a, d, g, h, h, m, n, ... are appearing as blocks is because I've got the wrong number of bits set for the serial transmission then you are a giant nerd. The Minitel is expecting 7 bits plus even parity. Since the top bit for all those characters is 0 for some of the letters the parity will be "correct" but for those characters which have an odd number of 1s in their binary version the parity is wrong and the Minitel displays a white rectangle.

To really use the Minitel as a terminal I plugged it into a Raspberry Pi and it appeared as /dev/ttyUSB0:

stty -F /dev/ttyUSB0 1200 istrip cs7 parenb -parodd brkint  \
ignpar icrnl ixon ixany opost onlcr cread hupcl isig icanon \
echo echoe echok

On the Minitel you can change the baud rate with FNCT-P. Followed by 4 you get 4,800 baud; followed by 1 you get 1,200 baud. 

And it works. To test it I visited jgc.org using lynx:


In the discussion about this post on Hacker News, a reader pointed to their very detailed description of how to use the same cable to turn the Minitel into a really useable terminal with Linux. Worth reading.

2022-03-15

Resurrecting a Dataman S4 PROM programmer

The Dataman S4 is a lovely piece of 90s' kit: a PROM programmer and emulator launched in 1992. I recently bought one from a seller on eBay and needed to resurrect it. It was in perfect working order but needed a little awakening to get it going. Happily, Dataman are still around, still provide online support for the S4 and still sell accessories for it.


With a little work I have a fully functional S4 and recently used it to burn new firmware for a Minitel 2 (that also dates from 1992), but that's another story.


The Dataman S4 seller helpfully included a note saying "You probably want to change the batteries as they are the originals". Yay. 30 year old NiCd batteries! But my first step was to see if the batteries in it worked at all. 

Plugging in the charger... nothing happened. Happily, Dataman tells you exactly how to reset the S4 to kickstart charging. Those instructions worked great and soon the S4 was working.


I changed the CR2032 for a new one since this device had not been used for years. Although the S4 worked fine with the original batteries I decided it needed a new lease on life and went out to buy new NiCds.

Oh wait, the 2006 EU Battery Directive makes batteries containing cadmium really hard to buy. But luckily, Dataman sells a replacement pack which they quickly shipped to me in Portugal (they have instructions on how to replace the pack).

So, new batteries and the S4 was ready to rumble.



Well, almost. 

The S4 needs to be loaded with a library of PROM types that it knows about so that it can emulate or burn them. And long dead S4s have no library loaded (hence the message NO LIBRARY LOADED on screen). To load the library you need to have a PROM with the library on it, put it in the ZIF socket and tell the S4 to copy it.

But I didn't have a PROM, so I needed to download the library image and burn it into a PROM, and then load it into the S4 as above. But how do you burn the PROM without the PROM-burning-library? Well, the S4 knows how to burn a 27256 whatever state its in. This is all explained clearly in the manual and in the notes when you download the library image. (You can also upload the library via the RS/232 port using their Windows software, but I'd rather not use Windows if I can avoid it... looking at you LEGO and your poor support for non-Windows).

At this point I was deeply impressed by Dataman's printed documentation, online support response time, sales speed (took five days to get me the battery from the UK to Portugal including customs), and web-based resources.

So, off to buy some 27256 EPROMs from a seller in Portugal. With the 27256 in hand I needed to connect the S4 to my laptop. For this I used their USB-to-RS232 cable and it appeared on my Mac as /dev/cu.usbserial-1460.


By default the S4 speaks 9600 baud, 8 bits, no parity, one stop bit. I used miniterm.py to talk to it with hardware flow control enabled (CTRL-T R). Almost every button on the S4 has an equivalent command over RS/232 and these are all documented in the manual.  

To test that I could successfully talk to the S4,  I put a blank 27256 in the ZIF socket and asked the S4 to test it by typing PR (which magically turns into PRETEST 27256):

$ python miniterm.py 
 
--- Available ports:
---  1: /dev/cu.BLTH         'n/a'
---  2: /dev/cu.Bluetooth-Incoming-Port 'n/a'
---  3: /dev/cu.URT1         'n/a'
---  4: /dev/cu.URT2         'n/a'
---  5: /dev/cu.usbserial-1460 u'USB-Serial Controller D'
--- Enter port index or full name: 5
--- Miniterm on /dev/cu.usbserial-1460  9600,8,N,1 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
 
>PRETEST 27256
BLANK ROM
>

Great, it's a BLANK ROM (which means no data on it and the S4 can burn it).

Next step is to upload the Intel HEX format file containing the library image. Which you do by typing RE (which turns into RECEIVE INTEL since the default file format will be Intel HEX). You then type CTRL-T CTRL-U to upload the file.

RECEIVE INTEL   
--- File to upload: HexE300.hex
--- Sending file HexE300.hex ---
..............................................................
--- File HexE300.hex sent ---
EOF 0FFFF
>

Here you can pause for a musical interlude as you listen to the sound of the Dataman S4 receiving a file.

At that point the library ROM image is in the RAM of the S4 and it's possible to check its validity with the CH command:

>CHECKSUM RAM
08000,0FFFF 
SUM = 002A0801

And happily the checksum 002A0801 matches that in the HexE300.txt file that comes with the HexE300.hex library image.

With the blank 27256 in the ZIF socket its time to burn the library image onto it. That's achieved with the BU command. Or by hitting the BURN key on the S4's keyboard. But before that you have to move the image down to memory location 00000 from 08000. That's because the default firmware in the S4 is very simple: it only handles the 27256 and has limited functionality.

So, prior to burning the 27256 I did a MOVE command to shift the image in RAM down to 00000. And then I hit BURN.


One final check is to checksum the newly burnt 27256 to make sure it's got the right image on it. That can be achieved with the green SUM button.


And so, after having changed the batteries and prepared a library ROM it's time to load that library into the S4 and it'll be fully restored. I like to label things as gifts to my future self.


That's as simple as pressing the LIB button.


And here it is, my Dataman S4, in all its glory. Now where's that Minitel?











2022-03-05

The "Roman Holiday" teleprinter code

Some years ago I wrote about the Morse code heard at the very start of the first episode of the TV series Downton Abbey. That Morse turned out to be very relevant to the story. A nice Easter Egg. 

Watching the 1953 Gregory Peck and Audrey Hepburn film Roman Holiday, I wondered about a shot of teleprinter tape and what was written on it. Was it an Easter Egg relevant to the story?


We're meant to understand that this is part of a message saying that the Princess Ann (played by Audrey Hepburn) has been taken ill and can't attend her scheduled events. Of course, she is, in fact, on her "Roman holiday" with Joe Bradley (Gregory Peck).

But what's actually on the tape? Being a nerd I transcribed all I could read and got the following:

    0       0     0       0             0         0   0       0             0
            0   0         0     0             0           0   0 0 0 0
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
    0 0 0     0 0 0 0 0     0   0 0   0   0   0 0   0 0     0
0       0 0           0 0                       0     0 0 0         0 0 0 0 0
  0 0     0 0           0 0   0     0 0     0   0       0       0 0 0 0 0 0

Using the International Telegraph Alphabet No. 2 (ITA2) we can decode that into the letters and symbols being typed or transmitted.


The first character is a Carriage Return, after that it reads: 

RTY NOW IS NOW TI TRE TIME FOR ALLGOOOD

Almost certainly someone was asked to type "NOW IS THE TIME FOR ALL GOOD MEN TO COME TO THE AID OF THE PARTY" on the teleprinter and didn't do a very good job given the repetitions and typos.

Ironic, since that phrase was commonly used as a test of typing ability, and nothing to do with errant princesses.