HP Forums
Revealing the HP-82242A IR Printer Module - Printable Version

+- HP Forums (https://www.hpmuseum.org/forum)
+-- Forum: HP Calculators (and very old HP Computers) (/forum-3.html)
+--- Forum: General Forum (/forum-4.html)
+--- Thread: Revealing the HP-82242A IR Printer Module (/thread-21323.html)



Revealing the HP-82242A IR Printer Module - ThomasF - 02-19-2024 01:48 PM

Update: 2024-02-20 - Some small corrections in Blinky.pdf, i.e. info about some missing registers.

Some months ago, Andrew showed us all how a Raspberry Pico could be used to read the bus signals from a HP-41, and also how to inject data on the bus so that the Pico could both read and write to the calculator.
I quickly adopted his ideas and build myself a platform that I could use to test and develop code to be able to extend the calculator, and so far I have been able to:

Use multiple serial ports
With the help from Meindert I now use several virtual serial-ports over USB to my PC.
One is showing the command line interface (i.e to configure modules, start trace etc).
Another shows the disassembly trace, one for the printer output and another I use for my virtual wand.

Trace execution
Andrew also showed how to trace execution, which I extended further. I have included a complete disassembler (no symbols yet) so I can trace execution more or less in real-time. Since the buffer in the Pico is limited, I have added ”trace-breakpoint” support which allows me to start and stop tracing on any address in the address space, so I can e.g. disable trace in known loops (like waiting for key input). Using this I can trace for minutes without missing a single instruction.

Add any existing software module
In my Pico I have 16 MB of flash, so I can download a lot of modules, and from a command line tools plug and unplug the modules, specifying which port to put the module in.

Simulate Q-RAM
Any module can be marked as RAM, so I can use tools like the Zenrom to update code or write my own Mcode. Any modules can later be uploaded to the PC.

Virtual wand
As I have shown in a previous post, I added support for the HP-82153 hardware, so I could emulate the wand, i.e. sending barcode data from the Pico to the 41 bus just as the real wand would do.
Now I have also used one serial port for this, so I can ”scan” any barcode with my mouse on the PC which then sends the barcode data directly to the Pico and in to the 41 – so now it is very easy to send any program to the calculator – just as easy as with the real wand and paper barcodes but with the mouse on the PC display instead!

X-Function/X-Memory
The RAM is extended, so I can emulate the X-Memory. This RAM is saved in flash, so the data is persistent, and I can also have multiple banks with X-Memory, and swap between different banks.

And finally the Blinky …
To further test the capabilities of the Pico, I decided to try and emulate the IR-module (since I don't have one). As this module was undocumented, I started to analyze and comment the ROM code and from that I built up a model for the hardware parts of the module. With the help of Meindert, Mike and Christoph I was finally able to emulate the complete module. I have also added an IR-led to the Pico and can now print on the HP-82240A printer from my 41 - mission accomplished!

Where to go from here ...
The Pico I have supports LiPo battery, so the setup is portable (except the configuration which is done over USB (+tracing and Wand)).
So the next step could be to support WiFi and make it completely mobile.
There are also some other interesting projects in the pipe, so keep an eye open ... Wink

Thanks to ...
Meindert who has been very helpful! We have shared a lot of information regarding the Pico environment and he has also helped me with traces from an actual HP82242A.
Mike (who actually managed to emulate most of the module before me in his NutEm/PC) and Christoph (who used this in his V41 to add Blinky support) have also helped out to verify and find faults in my implementation. Christoph even found a fault when using the emulation together with the PPC-ROM, which later was verified by Meindert to be a real problem using a real HP82242A!
And of course Andrew who came up with the idea of using a Pico like this!

What else ...
To feedback to the community I include the ROM-listings that I have commented, and the findings I have done in the Blinky module (sorry for the formatting - it is a living document, and I hope to clean it up going forward).
With this information I hope anyone who is interested in the inner workings could use this as a start.
Please note that all comments are just my interpretation of the actual code, and that there might be both faults and mistakes, so use the information with a big pinch of salt …
Anyhow, my implementation works great, and the information has been proven to work in other implementations as well!
If you have any comments, or find any mistakes in mine, please let me know so I can update and share the documents!

Cheers,
Thomas


RE: Revealing the HP-82242A IR Printer Module - rprosperi - 02-19-2024 04:30 PM

Amazing stuff Thomas, thanks VERY MUCH for sharing the results of your curiosity and skills with the community. It has long been said among 41 fans that the last remaining big mystery was the inner-working of the Blinky, but now you've not only solved that mystery but also documented it in great detail, for others to learn and benefit from.

Thanks to you, Andrew, Christoph, Jean-Francois, Meindert and Mike, for earlier projects built upon here, and for their help in this important project!


RE: Revealing the HP-82242A IR Printer Module - ThomasF - 02-20-2024 07:12 AM

(02-19-2024 04:30 PM)rprosperi Wrote:  Amazing stuff Thomas, thanks VERY MUCH for sharing the results of your curiosity and skills with the community. It has long been said among 41 fans that the last remaining big mystery was the inner-working of the Blinky, but now you've not only solved that mystery but also documented it in great detail, for others to learn and benefit from.

Thanks to you, Andrew, Christoph, Jean-Francois, Meindert and Mike, for earlier projects built upon here, and for their help in this important project!

Thanks Bob!

It is so fun and inspiring to dig into this with the new possibilities that this opens up!
I still remember the days when we built MLDL's from scratch, getting the latest tools from PPCJ or TN, and now "everything" can be done in software ... Wink

I just made a small update to Blink.pdf above since I noticed that I had missed some info about some registers, and some other small corrections.

For anyone interesting in how the module works (with focus on the HW api), I recommend to check how TESTP is implemented.
When I started I thought that if I get TESTP to work, then everything would fall into place, and it did (at least to 98% Wink).
You will find the commented TESTP function in the second bank, starting at 0x6400.

Cheers,
Thomas


RE: Revealing the HP-82242A IR Printer Module - ThomasF - 03-12-2024 11:49 AM

Hi all,

The other day Meindert notified me of a small peculiar thing in the Blinky.
He noticed that after a print command, e.g. PRA, the module would turn on the CPU again after some seconds.

About 2 seconds after a single PRA, but up to almost 30 seconds for more than 20 consecutive calls to PRA.

He found this while tracing a real Blinky, and this did not happen on my emulated version, so something in the emulation was apparently missing!

This is how I think it works, what I did to solve it ...

When printing, the Blinky keeps track of how much has been printed, at least the number of linefeeds, since printing a full text line takes about the same time as a single line feed. If one calls another print-command directly after the first, this information must be kept between the two commands and so on.

This is mainly done by maintaining a timer that is incremented by a value corresponding to the delay added by each printing command.

When execution is done, this timer is decremented in the background and when reaching zero a service request is issued, the CPU wakes up and handles this.

The service request is done by pulling ISA high until the PWO line goes active, and the CPU starts running again. To know who called, the operating system goes through all modules, checking the last addresses in each ROM for a lookup table and calls any service routines it finds, and the module can do whatever it needs to do.
Note that the CPU has no information about who raised ISA and has to check every module in the system.

So I added a detection of light/deep sleep, as well as a background clock that could feed my emulated Blinky while the CPU was sleeping, and then pull ISA and kickstart the CPU when the timer expired.

This works fine now, so yet one step closer to a complete emulation and understanding of the Blinly Module!

Thanks goes to Meindert for being so observant when helping me with real Blinky traces!

---------------------------

One observation I made while looking through the available documentation on service request was in the excellent HP-41CX Programmer's Handbook where the following list is found which shows the services that are available to modules:

xFF4 Interrupt checked during Pause
xFF5 Interrupt checked if system flag 53 set
xFF6 Interrupt checked on wakeup /not ON key
xFF7 Interrupt checked when HP41 is turned off
xFF8 Interrupt checked just before CPU stops
xFF9 Interrupt checked on wakeup /ON key
xFFA Interrupt checked on MEMORY LOST

But, I think that the description of the FF8 service is misleading, it should be "when enter or leaving light sleep".
This service is called from light sleep wakeup logic, but also when going to light sleep.
Wakeup (xFF6 or xFF9) are related to when leaving deep sleep (i.e. turn on from display off).

Edit: I removed a question about a NPIC instruction, but found the answer Wink
I had misread the document and missed a part ... my fault ...
The instruction in question is used by e.g. the printer to report its status.


Cheers,
Thomas


RE: Revealing the HP-82242A IR Printer Module - ThomasF - 05-24-2024 09:38 AM

Hi all,

Edit 2024-05-27:
In the original list FI flag 5 is listed as ?EDAV and used by 82242.
It is not used by the module, but maybe this was replaced by FI 11.
I have interpreted FI 11 as TX buffer full, i.e. if not active, this could be treated as IR-led being available.

There has been some new findings and updates to the description of the Blinky module (HP82242A), and I would like to propose an update to the current (?) table of peripheral flags see message #6 here.

Flag 11 is currently listed as being used by the Time Module (82182A), but I have not found any references to this.
But this flag is used by the Blinky ROM to indicate that the transmit buffer is full (not to be mistaken for the "print buffer").
In the hardware there is room for up to two characters, one that is currently being transmitted, and one that is waiting in the register to be transmitted.
And while there is a character waiting in the register the FI flag 11 is set.

Flag 12 is also used by Blinky.
The flag is set to active when the timer is decremented to zero.
When transmitting characters, Blinky updates the timer and the value depends on both the current DELAY setting and the number of lines being printed, and the value is decremented (~8Hz) by an internal clock in the hardware.
When the value reaches zero, the FI flag 12 is activated.

An alternative name to flag 12 (opcode 36C) could be ?IRTM (IR-module TiMer).

It should be noted that only a selected peripheral should actually drive the FI bus signal (apart from FI 13), i.e. if both Time and Blinky modules are present, it is only the currently selected module that should drive FI when needed (this is to make sure that two modules shouldn't compete about the bus signal).
So even if e.g. the timer has elapsed in Blinky, but the module is not currently selected, then FI 12 is not active.
But any module can request service by setting FI flag 13 anytime.

Cheers,
Thomas

Code:
flag    test
num     opcode  device           mnem           expansion
----    ------  --------------   -----          ------------------------
0       3ac     82143A           ?PBSY          Printer BuSY
1       32c     82104A           ?CRDR          CaRD Reader
2       22c     82153A           ?WNDB          WaND Byte available
3       02c     none             ?PF 3
4       06c     none             ?PF 4
5       0ac     none             ?EDAV          Emitter Diode AVailable
6       16c     82160A           ?IFCR          InterFace Clear Received
7       2ac     82160A           ?SRQR          Service ReQuest Received
8       12c     82160A           ?FRAV          FRame AVailable
9       26c     82160A           ?FRNS          Frame Received Not as Sent
10      0ec     82160A           ?ORAV          Output Register AVailable
11      1ac     82242A           ?TXBF          TX Buffer Full
12      36c     82182A & 82242A  ?ALM or ?IRTM  ALarM | IR module TiMer
13      2ec     all              ?SERV          SERVice



RE: Revealing the HP-82242A IR Printer Module - brouhaha - 05-24-2024 10:28 AM

(05-24-2024 09:38 AM)ThomasF Wrote:  It should be noted that only a selected peripheral should actually drive the FI bus signal (apart from FI 13), i.e. if both Time and Blinky modules are present, it is only the currently selected module that should drive FI when needed (this is to make sure that two modules shouldn't compete about the bus signal).

Selected how? What specific condition would the module use to decide whether to drive FI? It could be that the IR module works that way, but I somewhat doubt that, as the other modules do not.

The Nut CPU precharges the FI line to the inactive state, and devices only drive to the active state, never the inactive state, so there is no electrical conflict if two devices share the same flag, with only one driving it active, and the other not. This is similar to "open collector" TTL, or "open drain" CMOS, but of the opposite polarity.

The same precharge is also done on ISA and DATA, though on those, the selected device drives both low and high. The precharge on those is used to guarantee that reading nonexistent ROM or registers reads all zeroes; without precharge the result could be unpredictable. The Nut uses instruction 000 as NOP, except that if a JSB goes to a 000, it is instead treated as a return. This is used so that the mainframe can call the service ROM, and ROM polling entries, even when the ROMs are not present (or a ROM poll entry uis empty)

In the Classic and Woodstock generation PMOS chips, even the ROM and register chips only drove outputs active, and never inactive, in the same way as the Nut FI. In PMOS, driving high with relatively normal-sized FETs works well, but relatively huge FETs are needed to drive low. They avoided needing the large FETs in the ROM/RAM/peripheral FETs by having only thr CPU drive those low. In CMOS (including the Nut), the transistor sizes needed are comparable for both high and low, so they didn't omit any, but for the deliberate choice on the FI line.

The time module alarm flag is documented in HP's timer chip ERS, which was leaked and is available from the usual archive sites. I have not studied the time module code to check for actual flag tests, but the VASM listing is available.

Thanks for the continued work on understanding Blinky, and sharing your findings!


RE: Revealing the HP-82242A IR Printer Module - Massimo Gnerucci - 05-24-2024 11:32 AM

The VASM documents the use of user flags 8-11.

P.131
Quote:C[11]= TIMER SCRATCH REGISTER B[11]= USER FLAGS 8-11



RE: Revealing the HP-82242A IR Printer Module - ThomasF - 05-24-2024 11:48 AM

(05-24-2024 10:28 AM)brouhaha Wrote:  
(05-24-2024 09:38 AM)ThomasF Wrote:  It should be noted that only a selected peripheral should actually drive the FI bus signal (apart from FI 13), i.e. if both Time and Blinky modules are present, it is only the currently selected module that should drive FI when needed (this is to make sure that two modules shouldn't compete about the bus signal).

Selected how? What specific condition would the module use to decide whether to drive FI? It could be that the IR module works that way, but I somewhat doubt that, as the other modules do not.

Hi Eric!

Thanks for your questions!

Yes, since we don't have any information about the module I should have added that this is based on my interpretation of debug logs etc when looking at both the real 82242 and while trying to implement Blinky on the Pico board.

Look e.g. at his trace (made by Meindert) from a real HP82242A in a HP41CX traced by the Pico board:
(First column (after the '.') is a cycle counter, followed by address, opcode, data (divided into fields), FI flags and then mnemonics)
Code:
.  5129  642A 15F - 0.0000000000.F.FF | FI ---C-  JC 43
.  5130  642B 264 - 0.0000000000.F.FF | FI ---C-  SELP 9
.  5131  642C 17C - 0.0000000000.F.FF | FI ---C-  17C FUNC (5)
.  5132  642D 0FC - 0.0000000000.F.FF | FI ---C-  0FC FUNC (3)
.  5133  642E 3BA - 0.0000000000.F.FF | FI -----  3BA READ (14)
.  5134  642F 005 - 0.0000000000.0.00 | FI -----  005 RTNCPU
.  5135  6430 358 - 0.0000000000.0.00 | FI -----  ST=C
.  5136  6431 04C - 0.0000000000.0.00 | FI -----  ?FSET 4
.  5137  6432 11F - 0.0000000000.0.00 | FI -----  JC 35
.  5138  6433 14C - 0.0000000000.0.00 | FI -----  ?FSET 6
.  5139  6434 10F - 0.0000000000.0.00 | FI -----  JC 33
.  5140  6435 264 - 0.0000000000.0.00 | FI -----  SELP 9
.  5141  6436 13C - 0.0000000000.0.00 | FI -----  13C  FUNC (4)
.  5142  6437 0BD - 0.0000000000.0.00 | FI -----  0BD  FUNC (2)
.  5143  6438 130 - 0.0000000000.0.00 | FI ---C-  LDI
.  5144  6439 031 - 0.0000000000.0.00 | FI ---C-  031
.  5145  643A 264 - 0.0000000000.0.00 | FI ---C-  SELP 9
.  5146  643B 2F9 - 0.0000000000.0.31 | FI ---C-  2F9  WRITE (11)
.  5147  643C 000 - 0.0000000000.0.31 | FI ---C-  NOP
.  5148  643D 1AC - 0.0000000000.0.31 | FI --BC-  ?FI 11
.  5149  643E 0BF - 0.0000000000.0.31 | FI ---C-  JC 23
.  5150  643F 226 - 0.0000000000.0.31 | FI ---C-  C=C+1 S&X
.  5151  6440 264 - 0.0000000000.0.31 | FI ---C-  SELP 9
.  5152  6441 2F9 - 0.0000000000.0.32 | FI ---C-  2F9  WRITE (11)
.  5153  6442 000 - 0.0000000000.0.32 | FI ---C-  NOP
.  5154  6443 1AC - 0.0000000000.0.32 | FI --BC-  ?FI 11
.  5155  6444 08B - 0.0000000000.0.32 | FI --BC-  JNC +17
.  5156  6445 264 - 0.0000000000.0.32 | FI --BC-  SELP 9
.  5157  6446 23D - 0.0000000000.0.32 | FI --BC-  23D  FUNC (8)
.  5158  6447 1AC - 0.0000000000.0.32 | FI --BC-  ?FI 11
.  5159  6448 06F - 0.0000000000.0.32 | FI -----  JC 13
.  5160  6449 36C - 0.0000000000.0.32 | FI -----  ?FI 12
.  5161  644A 05F - 0.0000000000.0.32 | FI -----  JC 11
.  5162  644B 130 - 0.0000000000.0.32 | FI -----  LDI
.  5163  644C 080 - 0.0000000000.0.32 | FI -----  080
.  5164  644D 264 - 0.0000000000.0.32 | FI -----  SELP 9
.  5165  644E 2B9 - 0.0000000000.0.80 | FI -----  2B9  WRITE (10)
.  5166  644F 130 - 0.0000000000.0.80 | FI --BC-  LDI
.  5167  6450 013 - 0.0000000000.0.80 | FI --B--  013
.  5168  6451 1AC - 0.0000000000.0.80 | FI --B--  ?FI 11

Between cycle 5133 and 5142 the timer flag is active, and so FI:12 should also be, but something hides it and enables it again.
Same with the buffer full flag, FI:11 (and FI:12) should be active between 5159 and 5165.
With this and other traces I have concluded that FUNC (5) and FUNC (8) (opcode 0x17C and 0x23D) both hides the FI flags (deselects the module), and at all times the SELP 9 (selecting the printer module) enables the FI flags again.

EDIT! It is not clear - but the logging causes a delay in the actual output of FI in the trace.
Look e.g. at 5158 - it looks like FI:11 is active, but the instruction (?FI 11) doesn't see the flag so carry is not set.
This trace is part of the TESTP function, and verifies that no flag (11 or 12) are visible after the FUNC 8 instruction, but should be active again at 5168, without any new characters being written to the output register.

This also is inline with the following comment (on page 110) from the HP document IC Specification:
Quote:All flags but Flag 13, should be driven by a device only if that device is selected. This convention promotes maximum use of FLAG without contention.

(05-24-2024 10:28 AM)brouhaha Wrote:  The Nut CPU precharges the FI line to the inactive state, and devices only drive to the active state, never the inactive state, so there is no electrical conflict if two devices share the same flag, with only one driving it active, and the other not. This is similar to "open collector" TTL, or "open drain" CMOS, but of the opposite polarity.

This would imply that if eg. the Time module have FI:12 active and Blinky is running, it would assume that the timer has elapsed and would start transmitting again before the waiting time is over - and maybe causing overflow in the printer - and visa versa.
If Time module is deselected and Blinky is running, it knows that FI:12 corresponds to the timer and nothing else.
Now that I have the possibility to trace the real hw, I should trace a Time module and see how it handles the FI:12 flag (if always active (when active) or sometimes hidden (e.g. when another peripheral is selected)).

(05-24-2024 10:28 AM)brouhaha Wrote:  The time module alarm flag is documented in HP's timer chip ERS, which was leaked and is available from the usual archive sites. I have not studied the time module code to check for actual flag tests, but the VASM listing is available.
Yes, that is how I searched for the usage of FI:11, but I only found the ALARM? instruction in the VASM, looking at FI:12.
The opcode for looking at FI:11 is not to be found there.

And in the same document (IC specification above) on the same page (110) the following information can be found:
Quote:Phineas uses Flags 12 and 13, Flag 13, as stated above, is
driven to request service whenever an alarm condition exists. Flag
12 is driven when the above condition is true and Phineas is
enabled.
And on page 114 the following is found:
Quote:To insure that Phineas is never
enabled at the same time as data storage, the CDADD instruction
will reset chip enable regardless of the data appearing at chip
address time,
So yes, I still assume that other modules releases any FI flags when the module is deselected/disabled (either by special instruction (as with Blinky) or another peripheral is selected).

(05-24-2024 10:28 AM)brouhaha Wrote:  Thanks for the continued work on understanding Blinky, and sharing your findings!
Thanks - hope to soon release a more complete and correct description covering our latest implementation!

Cheers,
Thomas


RE: Revealing the HP-82242A IR Printer Module - ThomasF - 05-24-2024 11:56 AM

(05-24-2024 11:32 AM)Massimo Gnerucci Wrote:  The VASM documents the use of user flags 8-11.

P.131
Quote:C[11]= TIMER SCRATCH REGISTER B[11]= USER FLAGS 8-11

Hi Massimo,

This is not the same flags.
These correspond to the internal flags in the NUT flag register.

The FI flags (bad name IMHO) is a serial bus, that can be driven low by any device on the bus.
This line is divided into 14 slots (0-13), and any devices can use this to signal states to the NUT CPU.
There are specific instruction (like ?FI 11) that will set the carry if the corresponding time-slot on the FI signal is driven low by the device.

Cheers,
Thomas


RE: Revealing the HP-82242A IR Printer Module - ThomasF - 05-27-2024 08:25 AM

Hi again,

Just updated the list above - FI 5 (?EDAV) is not (as indicated in the original list) used by the Blinky module (82242).

Cheers,
Thomas