TP-10 Thermal Printer
I have recently been working with the PC-3 / PC-8 and PC-2 printers. I wrote a banner program for the PC-8 using far less memory than one might expect such a program to take. This was necessary because of the less than 1.5KB of RAM available for user programs and variables.
The result was a success. The PC-8 uses a printer for which replacement thermal paper is abundantly available and cheap. However, the paper size is only 2.25” wide. The PC-2 uses a plotter mechanism for which pens are very expensive to replace. I have not used that printer all that much due to the expense of the pens.
I recently recapped a TRS-80 Model 100, I wanted a bigger printer that could be used with the Model 100 that was of a similar vintage. And, I wanted a printer that was thermal, so that I do not need to worry about pens or ink cartridges that are either impossible to find or expensive to replace.
I saw a TP-10 thermal printer on eBay and couldn’t pass it up. It uses 4 1/8” thermal paper and has a 600 baud serial interface. It can not only do text, but graphics as well.
One of the challenges with this printer is the 4 1/8” thermal paper. It is not a common size. However, if you look hard enough, you’ll find sellers both on and off eBay who sell odd sizes of thermal paper on occasion.
This printer was originally marketed for the MC-10 computer released in 1983, but could also be used with the TRS-80 computers.
However, in theory, any computer which can send bytes out at 600 baud serial would work with it. More specifically, the format is 600 baud, 1 start bit, no parity, and 2 stop bits.
Initial Inspection
Whenever buying anything from eBay (or anywhere else for that matter), you really do not know what condition the item is in, other than what you see in the pictures. Just because an item comes with the box and packing material, does not mean the item is new, and it might need servicing (recapping for example) or cleaning.
The printer I got came with a roll of paper and the inside of the unit was clean.
The feed rollers were still good and the gearing including the worm gear for the print head needed some silicone lubricant. I used a food grade version safe for plastics.
I loaded the paper that came with the unit and performed a self test. This is done by holding the line feed button while powering on.
Keeping in mind the paper I’m using is as old as the printer itself, the result was fairly good.
Now that I know the printer worked, I proceeded with connecting it to something to experiment with its capabilities.
Serial Port Connection
The TP-10 has a 4 pin din connector for the serial input. I didn’t have any of these handy, so I ordered a 4 pin to 4 pin cable on Amazon.
I tend to order male to male cables because they’re inexpensive and you get two ends to use if you cut the cable in half. This way I can use one for the DB9 connector and I have a spare for use in the future if needed.
The data and ground pins are wired to the TX Data and GND pins on the DB9 serial connection to the computer. However, I also connected the status pin (2) from the TP-10 to the CTS input pin the DB9 serial connector. More on this later.
I used my preferred DB9 connector type for the other end of the cable. This allows me to connect the printer to any DB9 serial port, including the Model 100 (with a 25 pin to 9 pin cable). I could also connect the printer to a PC for example.
These are not the least expensive connector option but it is easier to use these for trial and error wiring until I get it right.
The final wiring that worked:
TP-10 Pin 2 (Status) -> DB9 Pin 8 (CTS)
TP-10 Pin 3 (GND) -> DB9 Pin 5 (GND)
TP-10 Pin 4 (Data) -> DB9 Pin 3 (TX Data)
Printing with the Model 100
The Model 100 has both a parallel port and an RS-232 serial port. All of the built in printing support on the Model 100 uses the parallel port. Using a serial printer will require some workarounds. One thought I had was to use a cheap programmable device to wire up a parallel to serial adapter, perhaps a future project.
I tested my cable by connecting the TP-10 to the RS-232 port on the Model 100 and using the built in TELCOM program.
I set the communication mode to “48N2D” using the STAT command (600 baud 8,N,2) and began typing on the keyboard. As I typed, the letters appeared on the thermal paper. Success!
BASIC Troubles
Printing a string to the serial port with BASIC didn’t work so well. I ended up with garbled characters and erratic results.
10 OPEN "COM:48N2D" FOR OUTPUT AS 1
20 INPUT "TEXT TO PRINT";T$
30 PRINT #1,T$
40 GOTO 20
I suspected buffer overflow was occurring in the TP-10. To test the data coming from the Model 100, I connected it to my PC and opened a PuTTY terminal with the same communication parameters. I was able to see the strings printed from BASIC without issues. This meant that the Model 100 was not the issue, it was the printer.
I then tried making my own print subroutine to print one character at a time to the COM port. If I added a large delay between characters, no issues occurred in the TP-10. However, the printing was painfully slow. If I decreased the delay to speed up the printing, I got mixed results – some characters would be missed, some garbled. It was not very reliable.
500 M = LEN(Z$)
510 FOR N = 1 TO M
515 V$ = MID$(Z$,N,1)
520 PRINT #1,V$;
527 GOSUB 600
530 NEXT N
540 PRINT #1,CHR$(13);
560 GOSUB 600
570 RETURN
REM DELAY
600 FOR O = 1 TO 100
610 NEXT O
620 RETURN
This gets more complicated when printing strings longer than 32 characters, as there will be a long period when the printer cannot accept bytes while the carriage is returning back to the left.
Buffer Overflow in the TP-10
The TP-10 has a status line which is held low when it is not ready to accept a byte of data on its serial port. From the user guide, it hints that it really doesn’t have a byte buffer at all. Shortly after the first byte’s start bit is received, the TP-10 pulls the status line low:
Further, it appears from the diagram, that even after the last bit is received, there’s a delay before it can accept the next byte. I suspect this is due to the delay caused by the print head and/or the two stop bits being defined in the communications requirement.
In order to print successfully to the TP-10 as fast as possible without buffer overflows would be to monitor the status line and wait for it to return back high before sending the next byte.
This can be done if we use the CTS input line on our computer’s RS-232 input. This is why I connected the status line from the TP-10 to the CTS line on the RS-232 connector.
Modified Printing Approach
Because of the buffer overflow problem when using the built in BASIC print function, I needed a custom method to send strings to the printer.
I needed a function which would send a byte, wait for CTS to return to high, then send the next byte and so on.
Luckily the Model 100 supports INP and OUTP for reading from and writing to the CPU ports. For example, I would be able to read the CTS line and wait for a state change to proceed with the next byte:
REM STRING TO PRINT IS Z$
500 M = LEN(Z$)
510 FOR N = 1 TO M
515 V$ = MID$(Z$,N,1)
520 PRINT #1,V$;
525 GOSUB 600
530 NEXT N
540 PRINT #1,CHR$(13);
560 GOSUB 600
570 RETURN
REM READ CTS BIT AND RETURN WHEN LOW (INVERTED)
600 O = 0 : O = INP(187) AND 16
610 IF O = 0 THEN RETURN
620 GOTO 600
Port 0xBB (187) has the RTS and CTS bits from the UART. Note that the CTS bit from this port is inverted. The CTS bit is bit 4. When CTS is high (printer is ready for data), the CTS bit in this register is low.
Note that in line 600, I have an unnecessary “O = 0” statement. This adds a bit of a delay before reading port 187, and avoiding a loop where the printer is not ready until the 2nd read of this port in the loop. The symptom of this delay is the print head not having a “smooth” run over each line to print.
Now that I have a working solution for printing a string of bytes to the TP-10, I can simply use these subroutines to print a string in place of the built in PRINT command in BASIC.
The PC-8 Banner Program Converted
I converted the PC-8 banner program that I wrote so that it would run on the Model 100. Very little of the program needed updating besides a few conventions for variables and the modified printing approach.
The first pass was a success!
The banner program for the PC-8 was working within a width of 24 characters on the printer. Since the bitmap font data I created is 7 pixels wide, a multiplication factor of 3 with a few characters of padding on either side worked well for the PC-8.
However, I now have a 32 character width to use. A multiplication factor of 4 was used in this first version for the Model 100. To balance the aspect ratio, I added another duplicate row to be printed per row in the font.
Memory is Less of a Concern
For the Model 100, I have much more memory to work with, 32KB worth. However, keeping programs as small as possible without convoluting the code too much is prudent. After all, there may be more than 1 program or other documents on the Model 100, so 32KB isn’t always as much as it seems.
However, in the spirit of doing as much as possible with vintage hardware, I chose to push the banner program to the next level.
TP-10 Printing Modes
The TP-10 has 3 different printing modes. The default is 32 characters wide, supporting its ASCII character set:
Note that we have upper and lower case character capability, unlike the PC-8.
When printing in this default mode, the font is 5 x 7, and each character is 1.8mm x 2.4mm on paper.
The next mode the TP-10 supports is “elongated” mode, which is merely a stretched version of the ASCII 5 x 7 character mode. In this mode the character font is 10 x 7, and 3.6mm x 2.4mm on paper. To enable this mode, you send printer control codes (first 27 then 14). Of course with this mode, you will get half the number of characters per line, 16.
The last mode the TP-10 supports is “graphic” mode, which is 7 x 12 with a size of 2.4mm x 4.2mm on paper.
The printer needs two lines to print each graphic character, so the printer will print the top half of each graphic character, then at the next automatic “wrap around” or carriage return & line feed control character received (ASCII code 13), it will print the second half of those characters.
In order to test this mode, I modified the banner program to use these character sequences for graphics mode rather than X’s:
Note that this mode requires 2 lines for the full characters and dimensions noted on paper.
Other Control Codes
The TP-10 supports a carriage return by itself (ASCII code 26), useful for underlining or strikeout for example. It also supports line feed by itself (ASCII code 10), for optimized skipping of white space, and a single character carriage return and line feed operation (ASCII code 13).
ASCII code 28 (along with 2 more bytes) instructs the TP-10 to print a character a repeated number of times. After sending byte value 28, the next byte is the number of times to print the character, the next byte is the character to print. This could be useful for underlining, or strikeout, or large segments of any repeating character.
PC-8 Banner Program Upgraded
Since we have a few more modes available on the TP-10 compared to the PC-8 printer, the mode with the best output is the graphics mode.
In order to take advantage of this mode and not have to modify the banner program too much, I chose to simply add the graphics character control codes in place of the X’s.
The output is better in graphics mode. The printout contrast is far greater than using X’s or other ASCII characters.
Final Thoughts
I set out to find a thermal printer for the Model 100 from the same vintage, and found the TP-10. This is a great little printer which is quite capable of printing not only text, but graphics. Although the paper size (4 1/8″) is a bit hard to find these days, I managed to stock up on a supply that will last awhile. Of course I could always buy a larger width roll and cut it if needed.
Connecting it to the Model 100 and getting it to work was a success! Using the banner program as an example of a comparison between this and the PC-8 illustrates the similarities and the differences between the two platforms.
The banner program has since been modified to peek into the built-in font bitmap in the Model 100’s ROM. This saved quite a bit of RAM and increased the number of characters supported. Perhaps a future enhancement by rounding off the edges of the printed letters using more of the graphics characters available would be interesting to do. Perhaps another option would be to invert the printout,by simply swapping X$ and Y$ with a user prompt.
One item left would be to write a BASIC program that will print a text document to the TP-10.
Program Listing
Below is the listing for the banner program. I have updated the listing with the improved version which reads the character bitmap data from ROM. I posted an article on this here. Note the REM statements should be ignored or removed.
LCD 5x7 FONT IN ROM STARTS AT 0x7711
INIT AND LOOP THROUGH EACH CHAR IN STRING TO PRINT FOR BANNER
100 CLEAR : OPEN "COM:48N2D" FOR OUTPUT AS 1
110 X$ = CHR$(143) + CHR$(159) : X$ = X$ + X$
120 Y$ = CHR$(128) + CHR$(144) : Y$ = Y$ + Y$
130 INPUT “Banner Text”;T$
140 PRINT #1,CHR$(26);
150 L = LEN(T$)
160 FOR C = 1 TO L
READ TO LOCATION IN DATA ARRAY FOR CURRENT CHAR BITMAP
170 E$ = MID$(T$,C,1)
180 K = ASC(E$) : A = 30646
190 A = A + ((K - 65) * 5)
200 B = PEEK(A)
READ EACH ROW IN BITMAP FOR THIS CHAR
300 FOR D = 1 TO 5
305 Z$ = " " : G = 64
310 FOR F = 1 TO 7
320 H = B AND G : IF H = 0 THEN GOTO 340
330 Z$ = Z$ + X$ : GOTO 350
340 Z$ = Z$ + Y$
350 G = G / 2 : NEXT F
PRINT THIS LINE TO PRINTER
400 GOSUB 500 : GOSUB 500 : GOSUB 500
410 A = A + 1 : B = PEEK(A) : NEXT D
420 Z$ = CHR$(13) + CHR$(13) : GOSUB 500
425 NEXT C
430 END
STRING TO PRINT IS Z$, ONE CHAR AT A TIME, THEN CR/LF CONTROL TO PRINTER
500 M = LEN(Z$)
510 FOR N = 1 TO M
520 PRINT #1,MID$(Z$,N,1);
527 GOSUB 600
530 NEXT N
540 PRINT #1,CHR$(13);
560 GOSUB 600
570 RETURN
READ CTS BIT AND RETURN WHEN LOW (INVERTED)
600 O = 0 : O = INP(187) AND 16
610 IF O = 0 THEN RETURN
620 GOTO 600