-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 895b3eb
Showing
83 changed files
with
4,824 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# IDE | ||
.idea/ | ||
target/ | ||
*.iml | ||
|
||
# Compiled class file | ||
*.class | ||
|
||
# Log file | ||
*.log | ||
Hp8224-Image.png | ||
Hp8224-Text.txt | ||
|
||
# Package Files # | ||
*.jar | ||
*.war | ||
*.nar | ||
*.ear | ||
*.zip | ||
*.tar.gz | ||
*.rar | ||
|
||
# Mac OS | ||
**/.DS_Store |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
# hp82240 | ||
|
||
# General | ||
|
||
The Java based HP 82240 is a command line printer simulator for the Hewlett Packard HP-82240A/B | ||
infrared printer. It will decode printer commands received via a serial port, and produce | ||
a text and a bitmap file. | ||
|
||
The printer commands are text strings, escape sequences and line feeds, encoded in a character | ||
set as defined by HP. See [Printer Character Sets](documentation/charactersets/charactersets.md) | ||
for details. | ||
|
||
Note that the simulator does not understand the raw infrared pulses generated by the | ||
HP calculators. It needs special hardware (see below) that interprets these pulses and | ||
converts them into bytes. | ||
|
||
The output of the simulator consists of two files: | ||
* `Hp8224-Text.txt`: Any text that was sent to the printer, converted from the HP character set into UTF-8. | ||
* `Hp8224-Image.png`: Text and graphics as they would look on the printer paper. | ||
|
||
To illustrate, see the actual printer on the left, and the generated bitmap file on the right: | ||
|
||
| Printer | Simulated Output | | ||
|-------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------| | ||
| <img src="documentation/pictures/HP82240A.jpg" width="320" alt="HP 82240A printer"> | <img src="documentation/pictures/HPSelfTestFromSimulator.png" width="320" align="top" alt="Self Test"> | | ||
|
||
More examples are available [here](documentation/examples.md) and | ||
[here](documentation/validation/validation.md). | ||
|
||
# Acknowledgements | ||
* Thanks to <a href="http://hp.giesselink.com/">Christoph Gießelink</a>: He develops | ||
a Windows based simulator of the HP printers 82240A/B and 82143A. The bitmaps for the | ||
printer characters directly come from this simulator (See | ||
<a href="https://www.hpcalc.org/details/7386">hpcalc.org</a> | ||
for the full source code) | ||
* Thanks to [Martin Hepperle](https://www.mh-aerotools.de): He developed the first | ||
"Red Eye" reader, see "Hardware" section below. | ||
* Thanks to [Meindert Kuipers](https://www.hpmuseum.org/forum/user-215.html): His version | ||
of the "Red Eye" receiver is the one that I am using. | ||
* Thanks to Christian Vogel; His [avr-redeye](https://github.com/vogelchr/avr-redeye) project allowed me to send any print commands | ||
that I like to my real HP 82240A printer and observe its behaviour. | ||
|
||
# Installation | ||
Copy the `hp82240.jar` file to a convenient location. Make sure to have a Java 17 or higher | ||
runtime available on your system. Then, start the simulator with: | ||
`java -jar hp82240.jar [-p=comport]` | ||
This will start the simulator and open the com port for reading. Any existing output files | ||
(`Hp8224-Text.txt` and `Hp8224-Image.png`) will be overwritten on application startup. | ||
When you are done with your session stop the simulator with `Ctrl-C`. Save away the output | ||
files for later use. | ||
If you omit the com port, the simulator will attempt to auto-detect the correct port. | ||
|
||
## Quick testing | ||
For some quick testing, the simulator can work with input files. To produce a self test, | ||
one can use this: `java -jar hp82240.jar -i selftest.yaml`. The files are the same ones as used | ||
in the Red Eye sender (see below). The file format is not explicitly documented, but should | ||
be self explanatory when looking at the provided samples. | ||
|
||
## Receiver Hardware | ||
To receive the infrared pulses from an actual calculator, and convert this data to a serial stream, | ||
special hardware is required. I built a receiver based on | ||
[this](https://www.hpmuseum.org/forum/thread-14858.html) guideline, which in turn is a | ||
modified version of | ||
[this](https://www.mh-aerotools.de/hp/red-eye/HP-IR%20Receiver%20with%20Arduino.pdf) | ||
guideline. | ||
|
||
# Comparison with other simulators | ||
This simulator is currently limited in functionality, supporting only the HP 82240A/B printer, | ||
and lacking a graphical user interface. Its main advantage is that it runs on all platforms | ||
supporting a Java 17 or higher runtime, including ARM devices such as the Raspberry Pi. | ||
|
||
# Validation on a real HP82240A printer | ||
To [validate](documentation/validation/validation.md) and compare any output generated by | ||
this simulator with the output from a real | ||
HP 82240A printer, one needs to be able to send very specific strings / graphic codes to | ||
the printer. The real calculators are only of limited use here, because their firmware | ||
prevents certain issues to happen. For example, lines that are too long (longer than the | ||
printers buffer) get Line Feeds added by the firmware. | ||
|
||
Therefore, a tool has been developed that allows to send any sequence of bytes that one wants | ||
to a serial port. On this serial port a piece of hardware is required that generates the | ||
"Red Eye" pulses that the printer understands. | ||
|
||
## Sender Hardware | ||
|
||
I am using this project with an Arduino clone and a simple IR diode: | ||
[avr-redeye](https://github.com/vogelchr/avr-redeye). The project is a few years old, but it works perfectly right out of | ||
the box. Note that you can't use the Arduino IDE to compile / send, because this is pure | ||
C code and not an Arduino sketch. On the Mac I installed two tools: | ||
* `brew install avrdude` | ||
* `brew install avr-gcc` | ||
|
||
I had to slightly adapt the `PROGRAMMER_DUDE` part of the `Makefile` | ||
to | ||
`PROGRAMMER_DUDE = -P/dev/cu.usbmodem4101 -carduino -b57600`, and then it worked right away. | ||
|
||
For the first test I used a genuine Arduino Uno, and found that this device sends spurious | ||
bytes (`0xF0`) when the serial port gets closed (which happens automatically at the end of | ||
the application). So if you see strange characters on your printer, try with a different | ||
type of Arduino. Here is the device that I am using now: | ||
|
||
<img src="documentation/pictures/Sender.jpg" alt="IR Sender"> | ||
|
||
## Sending print commands | ||
|
||
The tool is invoked as follows: | ||
`java -cp hp82240.jar ch.erzberger.emulation.sender.RedEyeSender`. It will then tell you | ||
the necessary parameters. Some sample files are provided in the | ||
`documentation/sampleoutput` directory. | ||
|
||
|
||
# Stdin, Stdout | ||
The simulator can read from Stdin instead of from a serial port. Use this if you have e.g. | ||
an emulator of a calculator that sends print output to Stdout. To test, use the RedEyeSender, | ||
sending to StdOut: | ||
`java -cp hp82240.jar ch.erzberger.emulation.sender.RedEyeSender -p=stdout -i=selftest.yaml | java -jar hp82240.jar -p stdin` | ||
|
||
# License | ||
HP82240 - A Java based HP 82240A/B Printer Simulator | ||
Copyright (C) 2023 Martin Erzberger. | ||
|
||
This program is free software; you can redistribute it and/or modify it under the terms | ||
of the GNU General Public License Version 2 or any later version, as published by the Free | ||
Software Foundation. |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# Aspect Ratio and Pixel Dimensions | ||
|
||
## The HP 82240A Printer | ||
|
||
The HP 82240A printer has somewhat oval / rectangular pixels, because it is an analog device. Also, | ||
horizontal neighbouring pixels tend to bleed over because the printer head can't cool down quickly enough. | ||
|
||
This is how the printout looks under a microscope: | ||
|
||
<img src="HP82240a.jpg" width="160"> | ||
|
||
## Digital pixels | ||
|
||
Digital pixels are abstractions that only become visible when shown on a device, or printed out on | ||
a computer printer. How these pixels are represented differs from device to device, and from application | ||
to application. Here are just three examples of the same letter "i". | ||
|
||
| Quick View | Preview | Laser | | ||
|---------------------------------------|-------------------------------------|------------------------------------------| | ||
| <img src="QuickView.png" width="200"> | <img src="Preview.png" width="200"> | <img src="Laserprinter.jpg" width="200"> | | ||
|
||
The laser-printer shows the closest result, because the aspect ratio is actually correct. Unlike the | ||
HP printer, the vertical pixels merge together, though. | ||
|
||
## One pixel per pixel, or many? | ||
|
||
Because the original HP 82240a pixels are not perfect squares, the simulated printer output might look | ||
different from the original. One can deal with this in two ways: | ||
1. Use multiple pixels to assemble small ovals, and then use one oval for each printer pixel. For absolutely | ||
perfect results, one would need different ovals, depending on the neighbouring pixels. | ||
2. Use one pixel per printer pixel, and define at least the correct aspect ratio in the file's metadata. | ||
|
||
Option one gives the closest look to the original, at the cost of increasing the file size significantly, and of | ||
limiting the flexibility in using the resulting file. Because there is no universally "better" option, | ||
it would be best to support both options and have the user decide. | ||
|
||
For now, only option two is supported, though. The rest of this document explains how the aspect ratio and the | ||
pixel density have been determined. | ||
|
||
## Figuring out the pixel dimensions of the HP 84440a printer | ||
|
||
First, we print a perfect 166 x 166 pixel rectangle, using the file [dimensions.yaml](../sampleoutput/dimensions.yaml). | ||
|
||
The printed output can then be measured, and the resulting width/height is: | ||
* Width: 46.1mm, which is 92dpi horizontal resolution | ||
* Heigth: 55.2mm, which is 76dpi vertical resolution | ||
|
||
These dpi values are written into the `png` output file as metadata. As one can see above, the laser-printer | ||
uses the annotation to correct the aspect ratio of the printout. | ||
|
||
So far I found no application or browser that will correct the aspect when displaying the image on screen. | ||
Please let me know if the left picture (from the simulator) looks the same as the right one | ||
(from the HP 82240a printer). | ||
|
||
| Simulator | HP 82240a | | ||
|---------------------------------------|---------------------------------------| | ||
| <img src="Rectangle.png" width="300"> | <img src="Rectangle.jpg" width="300"> | |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
# Printer Character Sets | ||
|
||
## Acknowledgment | ||
Creating a bitmap character set is tedious work. It needs to be assembled dot by dot | ||
from enlarged original printouts. Luckily, I did not have to do this. The bitmaps | ||
are copied from [Christoph Gießelink's](http://hp.giesselink.com/) simulator, available | ||
[here](www.hpcalc.org/details/7386). | ||
|
||
I performed my own validation with enlarged printouts, and found a number of differences | ||
in the HP 82240A's Roman 8 character set (e.g. in the number "3", or the letter "J"). | ||
These have been changed to match the original printer. | ||
TODO: Validate the two HP82240B character sets. | ||
|
||
## HP Modified Roman 8 Character Set | ||
The original HP 82240A printer uses a modified HP Roman 8 character set. See | ||
[Wikipedia](https://en.wikipedia.org/wiki/HP_Roman#Modified_Roman-8) for details. | ||
The successor HP82240B also supports this character set, in order to be compatible | ||
with the A model. Even though the B model supports the same charset, it is rendered | ||
quite differently. For example, all capital letters haven been shortened by one row | ||
compared to the A model. | ||
|
||
## RPL Character Set | ||
The newer HP 82240B model additionally supports the "RPL" character set, see | ||
[Wikipedia](https://en.wikipedia.org/wiki/RPL_character_set). This character set is used by HP calculators that came after the HP 28, | ||
such as the HP 48 or 50 series. | ||
This character set is enabled with `ESC-0xF9` and disabled with `ESC-0xF8`. | ||
The "A" model ignores this escape sequence. | ||
|
||
## Examples (generated by the simulator) | ||
|
||
| HP 82240A Roman 8 | HP 82240B Roman 8 | HP 82240B RPL | | ||
|---------------------------------------------|---------------------------------------------|------------------------------------------| | ||
| <img src="HP82240A-Roman8.png" width="300"> | <img src="HP82240B-Roman8.png" width="300"> | <img src="HP82240B-RPL.png" width="300"> | | ||
|
||
## FOCAL character set | ||
The FOCAL character set (see [Wikipedia](https://en.wikipedia.org/wiki/FOCAL_character_set)) is | ||
used by the HP 41C calculator and its printer, the HP 82143A. It contains 128 characters. | ||
The simulator does not currently support this printer. The character set is part of the | ||
class "HpPrinterFonts", but it's not currently in use. The bitmaps for the characters were | ||
converted from the original printer ROM, see the `CharRomToJavaArray.java` file for more details. | ||
|
||
| Focal Characterset | | ||
|-----------------------------------| | ||
| <img src="Focal.png" width="300"> | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# Example outputs | ||
## Screenshot from an HP 50g calculator | ||
The HP50g calculator can send a screenshot to the printer. For this to work, the | ||
print output must be directed to infrared ("Mode", "Flags": Number 34 must be "Print via IR"). | ||
To print, press "APPS", "2", "Enter", "3", "Enter". | ||
All of the output is sent in graphics mode, even if it appears to be text or numbers. | ||
|
||
|Calculator|Printer Output|Simulator Output| | ||
|-|-|-| | ||
|<img src="pictures/HP50g.jpg" width="340">|<img src="pictures/ScreenshotFromPrinter.jpg" width="640">|<img src="pictures/ScreenshotFromSimulator.png" width="640">| | ||
|
||
## Self test | ||
The printer can perform a self test. This is initiated by holding the paper feed key while | ||
turning on the printer, or by sending ESC + 0xFE to the printer. The self test is emulated | ||
as well, and will output both a text file and a png file. The text file is in UTF-8 and | ||
contains all of the printer's characters. | ||
|
||
|Printer Output|Simulated Output| | ||
|-|-| | ||
|<img src="pictures/HPSelfTestFromPrinter.jpg" width="640">|<img src="pictures/HPSelfTestFromSimulator.png" width="644">| | ||
|
||
This is the emulated self test output in text form: | ||
[SelfTest.txt](pictures/SelfTest.txt) | ||
|
||
## HP 41C Printing | ||
The original printer for the HP 41C calculator is the HP 82143A. This printer is connected via | ||
cable to one of the expansion slots. The connector also contains the printer commands | ||
in ROM, such as `PRA` or `PRPLOT` (see below). This printer supports 128 characters, numbered | ||
from 0 to 127. | ||
|
||
The HP 82240A came later, and contains a different character set. It has printable characters | ||
from 32 up to 255. To print to this printer, an IR emitting diode is needed, which is plugged | ||
into an expansion slot of the HP 41C (the HP 82242A module). Just like with the 82143A | ||
printer, this module contains the printer ROM. | ||
|
||
Even though the newer printer has more printable characters, the older printer still has | ||
about 15 characters that do not exist on the newer printer. The ROM takes care of some things: | ||
* It translates the 82143A character codes into equivalent 82240A codes | ||
* It converts the flag for double wide into escape sequences | ||
* For three of the not existing characters (up and down arrow, and diamond), it transparently | ||
uses the 82240A graphic mode to generate the output. This routine seems to be buggy, | ||
though, because if a full line of 32 characters is printed, the last two do not print | ||
correctly. | ||
* The other unsupported characters are replaced with a `¤` character. | ||
|
||
## PRPLOT | ||
The [HP 82143A printer manual](https://literature.hpcalc.org/community/hp82143a-oh-en.pdf) | ||
explains how to use the interactive plotting function of the printer ROM. The interesting | ||
part is that the printer ROM of the DM41X uses a mix of text and graphics output, | ||
because it simulates non existing characters via graphics mode (see paragraph above). | ||
This is the text output: [Prplot-Wiggle.txt](pictures/Prplot-Wiggle.txt). Note that it misses | ||
the down arrow on the second line, because this arrow is generated in graphics mode. The | ||
right arrow on line 3 is visible though, because this arrow is part of the character set | ||
of the 82240A printer. | ||
|
||
The simulated output is here: | ||
<img src="pictures/Prplot-Wiggle.png" width="320"> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# Facts about the HP 82240A printer | ||
## Paper and Print head | ||
* One line (head movement) has 166 columns and is 8 pixels high. | ||
* Lines are printed directly adjacent, i.e. in graphics mode, 100% of the paper can be covered | ||
* One character box is 5x8 dots. Usually the bottom row is not filled, so that the rows look separated. | ||
* Some characters use the bottom row, e.g. "g" or other chars with descenders. | ||
* Left and right of a character a blank column is printed, except left- and rightmost column. | ||
* 24 chars fit on a line (22 times 7 plus 2 times 6). | ||
* Underline mode fills the bottom row, no matter what (also space between chars and graphics mode). | ||
* Double wide prints each column twice, no matter what (chars, space between chars, graphics bytes) | ||
* 12 double wide chars fit on one line (10 times 14 plus 2 times 12), leaving two pixels empty at the end | ||
|
||
### Questions | ||
* Can the 2 pixels be filled after 12 double wide chars? | ||
* If 2 pixels are inserted in-between, will the last char print or overflow? | ||
* Will a char overflow in total, or will it be vertically split? | ||
|
||
## Buffer | ||
* Print buffer is 200 bytes | ||
* Printing will start (and the buffer starts to drain) when a line feed is received | ||
* After max. 1.8 seconds the line is printed and the buffer for the line is empty | ||
* Once the buffer overflows, this happens: | ||
* As soon as space is available, a special "overflow" marker is put into the buffer | ||
* After this, everything is thrown away until a linefeed is received. | ||
|
||
### Questions | ||
* Some sort of special character is printed when the buffer overflows. How does it look? | ||
* What happens if >200 chars are sent without a line feed? There is no room for the special overflow char. | ||
* Does the linefeed itself count against the 200 bytes? | ||
|
||
# Timing | ||
* One byte needs 12.82 Milliseconds to transmit (roughly 78 bytes / sec). | ||
* A full line of graphics (166) will need 2.13 Seconds, i.e. more than the printer needs to print. | ||
* One line of regular text needs 308 Milliseconds to transmit, and 1.8 Seconds to print. Even with | ||
line feeds after 24 chars, the buffer will eventually overflow. | ||
|
||
### Questions | ||
* Can graphics lines really be sent at full speed? Note: The Arduino also has a limited buffer, and | ||
with 115200 bits/sec this buffer can easily overflow. |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
|
||
PLOT OF WIGGLE | ||
X <UNITS= 1.> | ||
Y <UNITS= 1.> → | ||
-1.10 1.10 | ||
0.00 | ||
----------------- | ||
0. × | ||
10. × | ||
20. × | ||
30. × | ||
40. × | ||
50. × | ||
60. × | ||
70. × | ||
80. × | ||
90. × | ||
100. × | ||
110. × | ||
120. × | ||
130. × | ||
140. × | ||
150. × | ||
160. × | ||
170. × | ||
180. × | ||
190. × | ||
200. × | ||
210. × | ||
220. × | ||
230. × | ||
240. × | ||
250.× | ||
260.× | ||
270.× | ||
280.× | ||
290.× | ||
300. × | ||
310. × | ||
320. × | ||
330. × | ||
340. × | ||
350. × | ||
360. × |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.