Search This Blog

Showing posts with label reverse. Show all posts
Showing posts with label reverse. Show all posts

Thursday, 25 March 2021

 Using a Thermal Printer Mechanism

 Using a Thermal Printer Mechanism

The Casio CP-10 is a neat calculator that has a thermal printer attached. The calculator also has a built-in clock and can do useful tasks such as printing this month's calendar. The date range is also useful as it ends in 2099. The printer is a small mechanism that take standard 38mm thermal paper. I found out that the mechanism is the same one that the FP-12 printer uses. This is a small printer that is designed to attach to a variety of calculators and pocket computers.

I bought a CP-10 to see if I could re-use the printer mechanism instead of the receipt printers that I have bought off ebay in the past. They are relatively expensive (over £20) whereas the CP-10 can be had for half the price, if the CP-10 is listed as non-working. Unfortunately the CP-10 has a NiCd battery pack, as the printer mechanism take a fair current when running and the pack is used to supply that. This means that a lot of CP-10s have suffered battery leakage and failed. This is what had happened to my example. After a brief attempt to revive it I cut off the printer mechanism and attached a blue pill and some extra circuitry.


There's seven transistors, one for each thermal element, and one transistor that drives the motor. There's an input for the home position switch as well. The mechanism has a tachometer output that gives a series of pulses as a magnet rotates near a coil. The magnet is attached to the motor, so this arrangement gives a reading of the motor speed. The pulse may also be used for dot timing. Unfortunately my mechanism seems to have a broken tachometer output. The coil reads 25M resistance, which is a bit high for a coil of wire. (I have since bought a second CP-10, this one shows signs of life and its coil reads 82R, so is much healthier). After trying my own tacho circuit, then copying the CP-10 circuit, then building a higher gain circuit with an op-amp I decided that the tacho output wasn't reliable enough to use. This may not be too much of a problem if the motor is run off a stable supply as the speed of the motor should be fixed. I should be able to time the motor moving from home position back to home position and scale the dot timings appropriately if need be.

The output from my working CP-10 is like this:


That's the calendar printout from the CP-10. The FP-12 has a print width of 20 characters, the CP-10 also seems to have a print width of 20 characters.

My first attempt at printing was a little more basic than a calculator. I turned the motor on and fired one element of the print head repeatedly:


This is a start, at least I'm getting dots. The motor drive also performs line feeds and the dots show that. The horizontal dots are the feed across the paper. the sloping dots are where the head is returning and the paper is being fed. After some work with the code, including adding a font table and using the input from the home switch, this is the output:


This is a test printout that is printing the parameters of the code that printed that section. I am also using 20 characters as the width here, simply because the mechanism is set up for it. There's a row at the top of the characters that is faint, I think this is to do with the ground wiring I have used.

There is also an interesting effect which is best shown in the lines of asterisks. They are darker on the right hand side of the line. I'm pretty sure this is down to the heating of the printhead as elements are turned on. Every time a dot is printed, the printhead warms up a bit. This means that to get an equivalent dot, you don't need to turn the element on quite as long the next time. In the printout above, I have a parameter called 'DEC_PERIOD' which controls part of my correction for this thermal heating effect. You can see that the second from bottom section has a DEC_PERIOD of 1 and the asterisks are darker to the right hand side of the line. The section above it has a DEC_PERIOD of 2 and the asterisks are printed more evenly.  The correction code counts the number of elements that have fired, accumulates those counts and uses them to create a 'temperature' for the printhead.  The DEC_PERIOD value controls the cooling of the printhead. This does lead to a working correction as can be seen above.

I think the CP-10 code must also be doing something similar, as the calendar printouts above show an even darkness across all the lines.

The CP-10 must also be correcting for supply voltage variations. It runs off four NiCd cells which will present a range of voltages to the motor and hence different speeds of printing. I have attached my working CP-10 to a power supply and varied the voltage. The time to print a line definitely changes, but the characters printed remain in the correct positions. The printout is fainter when the voltage is lower. The code could be using the tachometer signals from the mechanism. I can't do this but I could measure the time taken to print a blank line and use that to adjust the dot timings. Interestingly it appears that the CP-10 does print one blank line after it is powered on. I wonder if that is a timing line and the CP-10 is doing what I will probably have to do if I want to correct for voltage?

Next step? probably a PCB. But do I use a blue pill or STM32 chip? Given the size of the mechanism, a blue pill is a bit on the big side, so I think a chip would be better. The only problem is that there is quite a shortage of STM32s at the moment. I've got a few so that is probably OK.

There's a video here of the prototype:

 


 



Friday, 11 December 2020

Reverse Engineering at -17V and 200kHz

 

Warning: Rabbit Holes ahead


I have a Rockwell 920/3 calculator.

 

It's from about 1975, and is a pretty impressive beast. It's programmable and has 960 steps in its fully expanded form, a printer and a magnetic card reader/writer as well as a sixteen digit display. It can store data on cards as well as programs. The one I have (well the first one I got) ran the payroll at a large catalogue company in the UK. 

The card reader didn't work when I got it, which was a shame. I had several cards which had programs on them and I wanted to get them off the cards somehow. When a second calculator came up for sale I bought it. I swapped the card reader into my first machine and it worked. If you want to see it working there's a video here: 

 

I printed the programs and will look at transcribing them later. Of course when a third machine came up for sale I bought that as well. It turned out to be a 920/2 rather than a 920/3, which was a variant with less memory than the /3, but more than the base /1 model. Internally the machines have a common base board which comes with a small amount of RAM. This is one of them with some of my debug connections attached.


The architecture of the calculator is really what we would call a single board computer. There's a processor, RAM and ROM together with some general purpose IO (GPIO) devices. The processor is an early one, the Rockwell PPS-4, a four bit processor used in quite a few devices in the 1970s, notably calculators and pinball machines. It runs from a pretty non-standard, at least these days, -17V supply. It's negative logic so a zero is -17V and a one is 0V. Not something that can easily be attached to my logic analyser or even oscilloscope. The clock rate is one you don't see a lot these days: 200kHz. The second and third machines don't run at the moment, so I decided to have a go at fixing them. As it would be useful to know what the code was doing I decided to instrument the bus signals with a view to watching code execute and also hopefully build up a ROM dump. I could desolder the devices (all of which are in an uncommon 42 pin staggered QIP package) but then I'd need a ROM dump machine that runs at -17V. I may build one of these later if I can't dump all the ROM by bus capture on a working machine. If I run the machine through all of it's features while I have a scanner attached I should be able to slowly capture the contents of ROM. The executed parts anyway. i made a test circuit to see if I could get something working at -17V, the result is in this video:



That worked well, so I went on and made a PCB with enough inputs that I can capture the relevant signals to allow code execution flow to be examined. It turned out that a simple (and cheap, useful if I make a mistake at -17V) blue pill (STM32F103C8) had just enough GPIOs to handle the address bus (A/B in PPS-4 speak), data bus (or I/D bus), and bus control signals.

A datasheet for the PPS-4 is available on the web, and I found some example code in a patent. That gives me something to test my disassembler and any object code I find against as a sanity check. I f you look at the processor bus you find it is a bit of a monster, at least compared with something like the Z80. It is a multiplexed, interleaved two phase type of thing. There are four clock phases (my terminology). ROM addresses come out on the address bus in phase 1 while RAM or IO data is on the data bus. Then in phase 3 the RAM or IO address comes out on the address bus while the ROM data is on the data bus. This diagram from the datasheet should make things clearer:

No? If you look at it for about 10 minutes it starts to make sense. Yes, the processor has two clock inputs, at two frequencies and slightly out of phase with each other. There's a special IC just to generate these clock signals. You can see that de-soldering the ROM chips to read them is the easy bit. Once de-soldered you have to dump the ROMs using this bus arrangement, not forgetting that the logic levels are 0V and -17V.

What is useful about the bus scheme is the pair of 'bus clear' phases. It gives a simple handle on the bus phases when looking at traces. You'd have thought that was straightforward, but the PPS-4 throws another spanner in the works by inverting clock B and also inverting some (just some) of the data on the bus before it is used. Sometimes it inverts a nibble, sometimes a byte. A blank phase is a piece of driftwood to cling on to.

After some simple tests with the blue pill I ended up with a sketch that capture the bus signals as fast as it can manage. I added a pretrigger delay of a number of clock cycles from the reset signal going inactive so that the window of captured bus signals can be moved about with the aim of capturing the inital code execution. Hopefully this will provide some insight into why the board does not work.

 The bus traces look like this:

A:000 D:04 CLKA:0 CLKB:1 WOL:0 DO:0  - 0
A:000 D:00 CLKA:0 CLKB:1 WOL:0 DO:0  - 1
A:000 D:00 CLKA:0 CLKB:1 WOL:0 DO:0  - 2
A:000 D:00 CLKA:0 CLKB:1 WOL:0 DO:0  - 3

A:003 D:00 CLKA:0 CLKB:0 WOL:0 DO:0  - 0
A:003 D:00 CLKA:0 CLKB:0 WOL:0 DO:0  - 1
A:003 D:07 CLKA:1 CLKB:0 WOL:0 DO:0  - 2

A:000 D:0F CLKA:1 CLKB:1 WOL:0 DO:0  - 0
A:000 D:00 CLKA:1 CLKB:1 WOL:0 DO:0  - 1
A:000 D:00 CLKA:1 CLKB:1 WOL:0 DO:0  - 2
A:000 D:00 CLKA:1 CLKB:1 WOL:0 DO:0  - 3

A:003 D:1C CLKA:1 CLKB:0 WOL:0 DO:0  - 0
A:FFF D:1C CLKA:1 CLKB:0 WOL:0 DO:0  - 1 1C
A:FFF D:1C CLKA:1 CLKB:0 WOL:0 DO:0  - 2
A:6AB D:1C CLKA:0 CLKB:0 WOL:0 DO:0  - 3

 

You an see address 3 in the second block, that's a ROM address, and then in the fourth block the data from the ROM is put on the bus. The contents of the data bus when the ROM address is presented is the RAM or IO data from a previous IO or read instruction.

The captured data is copied to text files, one per pretrigger 'window'. A series of scripts extract the ROM information. This is sparse data, as obviously only ROM addresses that are either executed or accessed by instructions is captured. One key sequence is the startup code:

000     0x81       t 0x1
001     0x82       t 0x2
002     0x74       ldi 0xB
003     0x1C       iol 0x1E  
005     0x7E       ldi 0x1
006     0x1C       iol 0x1D  

The processor starts at address 000 when reset, so we have a sensible trace. The next instruction is a jump (t : transfer) from address 000 to address 001. This is a bit odd, but sort of makes sense. Then there's a jump from address 001 to address 002. Again, odd, but maybe the processor has to do some setup in the first instruction cycles, or the program counter gets 'finalised' or something by doing this. I did find some PPS4 code in a patent and the start of that looks like this:

     0000 81        T       #1                                                   
     *SET O/P TO ZERO                                                          
     0001 7F        LDI     0                                                    
     0002 10 0E   IOL     #E                                                   
     0004 7F        LDI     0                                                    
     0005 10 0D   IOL     #D                                                   
     0007 7F        LDI                                                          
     0008 10 07   IOL     1                                                    

There's the same jump instruction at 000, so we have another flag that we have a sensible trace. The second jump from 001 to 002 isn't there, though. I've not found an explanation of why they are there.

The IOL instruction sends a command to one of the GPIO chips. These aren't memory mapped or IO mapped but instead have hardwired device numbers. The IOL 0x1E sends command 0xE to device 1. This is setting up the keyboard/display scanning signals. I have traced enough signals on the PCB to determine the device numbers for the GPIO chips. I've called the PPS4 processor chip a processor up until now, but this isn't quite right. The chip does, in fact, have input and output ports. They aren't GPIO ports as they are fixed inputs or outputs. So the chip is close to being a microcontroller in some ways. The output port is used in the 920 to drive the demultiplexor that drives each display digit. The inputs are used to sense the keyboard matrix (the scan signals for the keyboard are the same scan signals used to drive the display digits).

Instruction Set

I'm familiar with the 8 bit processors, the Z80 and 6502 and the ARM instruction set. I've also programmed in PIC assembly, and Z8, and 6301, and 8086, and 8051, and 4 bit microcontrollers, and so on. But I was still a bit surprised when I saw some of the PPS-4 instruction. They seem to be from a time before people had worked out the rules. Here's an example, the load immediate instruction:


Ok, it's 4 bit, fair enough, and the immediate value is a nibble in the opcode, fine. Then you see on the right hand side that it refers to a note 3 lower on. Let's look at that:

Ok, so for these instructions (not all instructions), the nibble that is the immediate data is inverted in ROM and hence on the bus. Hmm, a bit odd, but a disassembler or assembler will handle that. Then you notice that a note is mentioned in the fourth box from the left. Is it referring to the same note 3? No it's not, it's this one it is pointing to:

 

Right, now we have some oddness. If you load the accumulator with 6 and then load it with 4, it ends up with the value 6. This struck me as downright bizarre when I first saw it, but after seeing some code and thinking about it it is useful. If you want to enter a routine with various different parameters then you can do this sort of thing:


Enter6    LDI 6

Enter7    LDI 7

Enter 8   LDI 8

           * Do something with A

          RTN

 

If you jump to Enter6 then the accumulator is loaded with 6, the next loads are ignored and you do something with 6. If you jump to Enter7 then the accumulator is loaded with 7 and the next load is ignored and you do something with 8. I can see how that could be useful.

This instruction:

 

shows the use that is made of data tables in ROM at the instruction level.

Next...

I now need to trace the code execution through to the loop it ends up in so I can maybe work out what isn't right... I also need to draw up a schematic. The PCBs are fairly low density so it probably isn't a massive job.


 Memory Expansion

An aside.The 920/2 has one plug-in memory expansion board, the 920/3 has two:


 Rather surprisingly the /2 RAM board has four RAM chips, the /3 boards have six chips each. Another surprise is that the two six chip boards in the /3 are different from each other. It looks to me that the connector pinouts on the cards are different, even though they carry the same amount of RAM. So rather than using the same PCB for both memory expansion configurations (part populating the 920/2 board), there are three different PCBs.