Home Page  







Archives Index

5th March 2002


Joe Griffin


(This article was first published in the ICPUG Journal May/June 1988 issue.
Permission from Joe Griffin to republish on the Internet has been received.)

the only replacement for an 8032 is another 8032!


A printer is arguably the most important peripheral you can attach to your PET. Until you have a means of obtaining hard copy, the uses to which the machine can be put are severely limited.

In my previous article, I mentioned that the peripherals for the PET were quite a long time coming. As a result of this a number of firms offered their own printers for use with Commodore machines. This trend has continued throughout the industry, with a large number of alternatives being offered for all makes. In this article, I shall concentrate mainly on dot-matrix printers, though much will also be relevant to daisywheel units.


In Commodore BASIC, there are commands to address any IEEE bus device (disks, printers, etc.) whereas with various other BASICs, there is are means to directly address the printer. For example in IBM BASIC, to list a program to the screen, one types 'LIST'; to list to the printer the command is 'LLIST'. Similarly for printing, 'PRINT' goes to the screen and 'LPRINT' to the printer. With Commodore machines, the system is more complicated but does allow (in my opinion) greater versatility in programs. The procedure is as follows:

1) Open a communications channel to the printer. This statement needs to know two main pieces of information: a channel number, and the device number (printers are usually device 4 on the IEEE bus). A simple analogy is with telephones: to install a telephone iine requires a knowledge of the line number and where it actually goes.

The command is (for example);

OPEN 2,4 (channel 2 opened to device number 4)

With some printers, there is a need to open what is known as a 'secondary address' to the printer (as will be explained later). In this case the command syntax is:

OPEN 2,4,7 (channel 4 to device 2 with sa=7)

2) Send information down the line to the printer. The telephone analogy still holds: to ring our Editor, I simply use his number, I don't need to know where his house is.

Here, two options are available:

By redirection:

CMD 2 (tells PET to use channel 2 for all output)
PRINT" something or other" (will go to printer)
PRINT#2 (used to "unlisten" printer, ie cancel redirection)
or directly PRINT#2, "summat else or other"

3) Drop the line to the printer:


The PET can effectively be told to redirect all output to the required channel until instructed otherwise. This is of particular value when a block of printing is being done all at one time and the option is required to print it to the screen or the printer. If the printing is contained in a subroutine, repeated calls can be made with various redirection as required.

10 rem redirect output to printer
20 open 2, 4: rem open printer
30 input "output to screen, printer or exit (s/p/x) ";dv$
40 if dv$= x" then 80
50 if dv$="s" then gosub 100:goto 30:rem print and return
60 if dv$= p then cmd 2:gosub 100:print#2:goto 30:rem redirect
61 rem note print#2 command to cancel redirection
70 goto 30:rem catch errors
80 close 2: rem shutdown printer
90 end
100 print "Hello there everyone!"
110 print "more stuff" etc.
199 print "last line of this lot"
200 return

Altematively, output can be directed specifically to the appropriate channel. This is of most use when the program is required to output to both screen and printer at the same time.

10 rem output to printer and screen
20 open 2,4: rem open printer
30 print "This line goes to the Screen"
40 print#2, "But THIS one goes to the Printer"
50 print#2, "This line also goes to the Printer"
60 print "and this goes to the screen"
70 close 2: rem drop line to printer
80 end


Over the years Commodore have produced (or had produced for them) a number of alternative printers. The original 2022 and 2023 printers were slow and noisy just like modern daisywheels!). They were superseded by the 4022 (an Epson-based unit of few features but good reliability). The 8ooo series were accompanied by the 8024 (fortunately a short-lived unit - built like a tank) and the 8026 & 8027 Olympia daisywheels (slow - 16 chars/sec). Later came the superb 8023 (later still it became the 1361) and the 6400 and 8300 daisy wheels. These latter two were lovely machines - we had a 6400 going spare at work and I managed to persuade the powers-that-be that it's best home was my office. On the night before I acquired it, it (and the entire floor where it was stored) was destroyed in a fire - a sad loss!

The various daisywheel units were capable (as is my DPS 1101) of very high quality work and had the standard full range of features. The 8024 dot matrix was a very heavy-duty machine, not altogether suited to the PET range as it lacked one of the main features of the other CBM dot-matrix machines without having the variety of features found on third-party printers. Unlike all the other CBM matrix units it was unable to print the entire PET character set, including graphics symbols.

In general the CBM dot-matrix units have few features, they can print reversed and double (or treble, quadruple etc) width characters. A 'user defined character' can be defined and printed (only one at a time though) and the number of lines/page and lines/inch can be adjusted, all through the use of secondary addresses. It is also possible to define and use a format for printing (rather like the 'print using' command on other machines, but not so versatile). On the 8023, secondary addresses can also be used to set the printer into a condensed pitch (17 cpi) or 'pseudo letter quality' mode (more 'pseudo' than 'letter quality'!). There are at least two variants of 8023 ROM (I have two different versions in my office). These differ in the secondary address used to reset the printer. The early 8023 uses sa10, the later one 16.

The single biggest virtue of the CBM printers is that they are compatible - you just plug them in and go. There is no need for a special interface and apart from learning how to obtain the correct variant of upper-case /graphics (graphics mode) or lower-case/upper-case (text mode) the printers are quite simple to operate.

As with the 40 column PETs, the CBM printers default to graphics mode. Just as any PET can switch between the two (POKE 59468,12 for graphics and POKE 59468,14 for text) so it is possible to switch the printer. However, here there is a difference: the printer can output lower case, upper case and graphics at the same time utilising a sort of 'shift function', using the cursor up/down keys.

To print a line of text containing both upper and lower case letters, the line should be prefxed with a cursor down character (CHR$(17)). The printer will return to normal graphics mode when it performs a carriage retum or en counters a cursor up character (CHR$(145)). In practice I never use the 8023 in this way. I prefer to initially set the printer into text mode, then use the cursor keys to obtain graphics symbols when needed. Try the following:

First, in direct mode, POKE 59468,14, to set the PET into text mode.

10 open 2,4:rem open printer
20 print#2, "This is Mixed UPPER and lower case text"
30 rem this should come out as upper case and graphics
40 rem the first character in the next set of quotes
50 rem should be a cursor down character
60 print#2, "[down] This is Mixed UPPER and lower case text"
70 close 2:rem this should come out as upper and lower case
80 open 3,4,7:rem sa = 7 sets text mode
90 print#3:rem action the sa 100 close 3
110 open 2,4:rem open printer
120 print#2, "This is Mixed UPPER and lower case text"
130 close 2:rem this should come out as upper and lower case
140 end


In addition to the CBM printers, there are a number of manufacturers who produce printers with a built-in 'PET Interface'. To a greater or lesser extent these provide some of the features of the Commodore printers. Commonly, the graphics characters and reverse field printing are available but many other features, obtained by secondary addresses, are not. Some of these printers may offer the worst of both worlds: being neither fully CBM compatible, nor allowing access to the full range of facilities found on the basic printer.


Most third-party printers come with a 'Centronics' input. For use with the PET, an interface is required. At the start, a number of Centronics interfaces were available via the User Port but these were not supported by software authors, who tended to stick with the standard IEEE bus for output. My knowledge of these user port interfaces is non-existent, so I will comment no further on them in this article.

Some manufacturers, such as Epson, provide a range of plug-in interface cards, both machine-specific and general. When I bought my Epson FX-80, I was advised to take the IEEE interface, rather than the so-called PET interface. The IEEE interface provides the appropriate connector on the printer but does not carry out any character conversion. There have been a number of interface leads available, which plug into the standard Centronics port on the printer and allow switching for ASCII or PETSCII code. These only convert codes, they do not provide the graphics characters of the CBM printers.

So why use a non-CBM printer? The reason I chose an Epson was the range of features available. On the CBM 4022, the choice is limited to 10 cpi, normal or reversed characters, expanded characters and variable line pitch. On the B023, there is additionally the choice of 17 cpi or 10 cpi 'pseudo letter quality'. On the Epson FX-80, reverse is not available. However some of the type styles which can be selected include: 10, 12 or 17 cpi, underlining, italics, bold, double strike, superscripts, subscripts and proportional spacing. All these are selected by sending a series of characters to the printer and in general changes can be made in mid-line if required.

The single biggest drawback of these printers is the need to use some form of conversion routine to get from PETSCII (on the PET) to true ASCII (for the printer). Many methods can be used.


Some (long) time ago Lee Allen published a routine in the ICPUG-SE News letter (Issue 15, Page 29) detailing a modification to the 'F' ROM which allowed true ASCII output to channel 5 of an IEEE device (unit 4 or greater). Whenever I am running BASIC on my 8096, I use a soft-loaded system which includes this modification. To obtain correct printing from the Epson, I 'OPEN 5,4' and the modified code handles the conversion. It would be possible to blow an EPROM with the new code but being a late machine mine has soldered-in ROMs, not socketted ones.


A long time ago I was given a text file stored as true ASCII, from somewhere I obtained the following method of conversion (I believe the idea came from "Compute!" or ~Compute!'s First Book of PET/CBM").

Set up a string array 255 characters long. Each element stores the ASCII code of the character whose PETSCII code has the vatue of that element's index. Eg PETSCII 'a' is CHR$(65); the ASCII value of 'a' is 97. Thus if the translation array is CR$,CR$(65)=CHR$(97).

When printing, for each character in turn obtain the PETSCII value N=ASC(...) then print CR$(N).

The full translation array is defined by:

100 dim cr$(255):' translation array
120 pet asci i to standard ascii
140 for i=Oto64:cr$(i )=chr$(i ) :next
150 for i=65to90:cr$(i)=chr$(i+32):next:rem lower case letters
160 for i=9lto95:cr$(i )=chr$(i ) :next
170 for i=96tol27:cr$(i)=cr$(i-64):next
180 for i=128tol92:cr$(i)=cr$(i-128):next 190 fori i =193to223: cr$ ( i ) =chr$ ( i -128): next: rem upper case
200 for i=224to255:cr$(i)=cr$(i-64):next . . .
230 open 2,4
240 op$= "Test String!" 250 for j=1 to len(op$) 260: print#2,ch$(asc(mi d$(op$, j , 1 ) ) );
270 next j:print#2

This method works for all BASICs, but is tediously slow. If the program is compiled then speed is reasonable but not brilliant.

Machine-code conversion Early in 1986 l was contacted by a member who had an 8032 and MX-80 printer. He wanted normal text output - a reasonable request. l wrote and supplied him with a short machine code routine for the job. The code lives in the first cassette buffer and when called (by SYS 634) it converts each byte in the named string into ASCII. To use it in a program only three things are needed.

1) Poke the code into the cassette buffer at the start of the program. 2) Place the text to be printed in a string, adding a null character 0P$= "This is a Mixed STRING" +""

The null at the end ensures that the string is placed in high memory. Without it, the actual line of code would be altered.

3) Call the routine and print the string.

SYS 634,0P$:PRINT#2,0P$

The code for BASIC 4 is as given here.

100 rem dsave "@asc-buffer/n",dl:? ds$
110 rem
120 rem routine to convert a string to true ascii
130 rem joe griffin (icpug) 20/mar/88
140 rem this routine resides in the first cassette buffer
150 rem 160 rem it is safest to add a null to the string, to avoid corruptions
170 rem
180 rem sys 634,xx$ will locate the string and convert it to true ascii
190 rem you may then output this string to your ascii printer and
200 rem the string will be printed with the correct case used.
201 rem
202 rem for basic 2 replace values as follow:
203 rem 270 data ..., 248, 205, ...........................
204 rem 350 data ..., ..., ..., 3, 206, ...................
205 rem 390 data ..., ..., ..., 32, 247, ...................
210 rem rem to change to the second cassette buffer
211 rem 240 for i= 826 to 978:read da:cs=cs+da: poke i,da:next
212 rem 510 sys 826,b$:' converts string of petscii to true ascii
213 rem 560 sys 826,tt$
220 rem
221 rem and replace values as follow:
222 rem 270 data ..., ..., ..., ..., ..., ..., ..., ..., 114, 3
223 rem 300 data ..., ..., ..., ..., ..., 147, 3, .... .... ...
224 rem 380 data ..., ..., ..., 181, 3, .... .... .... .... ...
225 rem
226 rem checksum in line 250 will need changing as well
227 rem
230 cs=0
240 for i= 634 to 786:read da:cs=cs+da: poke i,da:next
250 if cs<>18351 then print "checksum error":stop
260 rem
270 data 32, 245, 190, 160, 0, 177, 119, 141, 178, 2
280 data 230, 119, 208, 2, 230, 120, 177, 119, 201, 36
290 data 208, 4, 169, 0, 240, 6, 230, 119, 208, 2
300 data 230, 120, 9, 128, 141, 211, 2, 230, 119, 208
310 data 2, 230, 120, 165, 42, 133, 1, 165, 43, 133
320 data 2, 160, 0, 177, 1, 201, 0, 240, 26, 165
330 data 1, 24, 105, 7, 133, 1, 144, 2, 230, 2
340 data 165, 2, 197, 45, 144, 231, 165, 1, 197, 44
350 data 144, 225, 76, 0, 191, 200, 177, 1, 201, 0
360 data 208, 223, 160, 2, 177, 1, 153, 134, 0, 200
370 data 192, 6, 208, 246, 165, 136, 240, 14, 160, 0
380 data 177, 137, 32, 245, 2, 145, 137, 200, 196, 136
390 data 208, 244, 96, 32, 182, 193, 176, 16, 201, 161
400 data 144, 18, 201, 193, 144, 12, 201, 219, 144, 10
410 data 201, 223, 176, 6,. 9, 32, 208, 2, 41, 31
420 data 41, 127, 96
430 rem
440 b$="aAbBcCdDeE123456!' #$%& String of UPPEP and lower Case !!!"
450 :
460 b$=b$+"":a$=b$+"":rem add nulls to prevent changing program bytes
470 print "Original":print a$:printb$ :print:rem show original strings
480 :
490 open 4,4:print#4,"0riginal":print#4,a$:print#4,b$
500 :
510 sys 634,b$:rem converts string of petscii to true ascii
520 :
530 print "Converted":printa$:printb$:print:rem show converted string
540 print#4, "Converted": print#4, a$: print#4, b$
550 tt$= NOTE This Line will be CORRUPTED as NO Null Added
560 sys 634,tt$
570 pri nt#4,tt$ :print#4,a$ :print#4,b$
580 close 4
590 end

After running the program once, line 550 will be corrupted, by being converted to ASCII, within the program code. If a null is added to the end of the line, this will not occur.

The same technique can be used with a Petspeed compiled program, though here the string does not need to be declared initially, as Petspeed has fixed variable addresses.