PDP-8 programs that manipulate text (e.g. TECO, WPS8, EDIT) use 7-bit ASCII encoding, storing one char per word and accepting the overhead of five unused bits per char. Scanning and searching text is difficult enough on any minicomputer; no one wasis willing to entertain the complications of doing so on packed text.
At least one program (WPS8) useduses the extra bits to encode character attributes such as bold, underline, etc.
For some storage devices, the characters were packedThis information on 3 chars to 2 words, but this was more a function of the storage device driver than of the application software/2 packing is taken from Doug Jones's excellent archive.
Files under the widely used OS/8 system consist of sequences of 256 word blocks. When used for text or other 8-bit data streams, each block holds 384 bytes. The standard 3/2 packing method wasis somewhat strange -- byte 1 wasis stored in the lo 8 bits of word 1, byte 2 in the lo 8 bits of word 2, and byte 3 in the high 4 bits of word 1 and the hi 4 bits of word 2. Failure to unpack correctly wouldcan produce the text with every 3rd char deleted.
+---+---+---+---+---+---+---+---+---+---+---+---+┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
word 1 |│ byte 3 hi 4b |│ byte 1 byte 1 |│
+---+---+---+---+---+---+---+---+---+---+---+---+├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
word 2 |│ byte 3 lo 4b |│ byte 2 byte 2 |│
+---+---+---+---+---+---+---+---+---+---+---+---+└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
Because most of the PDP-8 system software was originally developed for paper tape, the binary object code in *.BN files is stored in paper-tape image form using the above packing scheme.
This format was introduced by the authorauthors of the RX01 floppy disk handlerOS/8 utilities such as ABSLDR, and subsequent developers never found a reason to break compatibility.
PDP-8 programs that emit predefined messages almost always useduse the upper-case only 64 char TTY set, and storedstore them as two 6-bit chars per word.
OddTEXT with odd char count withappends one halfword of null padding:
TEXT @ERROR@
+-+-+-+-+-+-+-+-+-+-+-+-+┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
word 1 |│ E | │ R | │
+-+-+-+-+-+-+-+-+-+-+-+-+├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
word 2 |│ R | │ O | │
+-+-+-+-+-+-+-+-+-+-+-+-+├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
word 3 |│ R |0 0 0 0 0 0| │ 000000 │
+-+-+-+-+-+-+-+-+-+-+-+-+└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
EvenTEXT with even char count andappends no padding:
TEXT @STRING@
+-+-+-+-+-+-+-+-+-+-+-+-+┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
word 1 |│ S | │ T | │
+-+-+-+-+-+-+-+-+-+-+-+-+├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
word 2 |│ R | │ I | │
+-+-+-+-+-+-+-+-+-+-+-+-+├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
word 3 |│ N | │ G | │
+-+-+-+-+-+-+-+-+-+-+-+-+└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
OddTEXTZ with odd char count withappends a halfword zero terminator and no padding:
TEXTZ @ERROR@
+-+-+-+-+-+-+-+-+-+-+-+-+┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
word 1 |│ E | │ R | │
+-+-+-+-+-+-+-+-+-+-+-+-+├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
word 2 |│ R | │ O | │
+-+-+-+-+-+-+-+-+-+-+-+-+├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
word 3 |│ R |0 0 0 0 0 0| │ 000000 │
+-+-+-+-+-+-+-+-+-+-+-+-+└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
EvenTEXTZ with even char count withappends a zero terminator and null padding:
TEXTZ @STRING@
+-+-+-+-+-+-+-+-+-+-+-+-+┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
word 1 |│ S | │ T | │
+-+-+-+-+-+-+-+-+-+-+-+-+├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
word 2 |│ R | │ I | │
+-+-+-+-+-+-+-+-+-+-+-+-+├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
word 3 |│ N | │ G | │
+-+-+-+-+-+-+-+-+-+-+-+-+├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
word 4 |0│ 0 0 0 0 0|0 0 0 0000000 0 0| │ 000000 │
+-+-+-+-+-+-+-+-+-+-+-+-+└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
/ 7-BIT HELLO PROGRAM
* 200
JMS WRMSG
"H
"e
"l
"l
"o
",
"
"w
"o
"r
"l
"d
"!
0
HLT
JMP 200
/ WRITE MESSAGE TO CONSOLE
WRMSG, 0
WRLP, TAD I WRMSG / MESSAGE TEXT FOLLOWS CALL
ISZ WRMSG / BUMP RETURN ADDRESS
SNA / ZERO MARKS END OF MESSAGE
JMP WREX
JMS WRCHR
JMP WRLP
/
WREX, TAD K15 / CR
JMS WRCHR
TAD K12 / LF
JMS WRCHR
JMP I WRMSG
/
K15, 15
K12, 12
/ WRITE CHARACTER TO CONSOLE
WRCHR, 0
SKCFL TTY / SEND 7B CHAR TO CONSOLE
JMP .-1
WRSEQ TTY
CLA / SOME CONSOLES DO NOT CLEAR AC
JMP I WRCHR
/ 6-BIT HELLO PROGRAM
* 200
JMS WRMSG
TEXTZ @HELLO, WORLD!@
HLT
JMP 200
/ WRITE MESSAGE TO CONSOLE
/ CALLING SEQUENCE
/ ... AC MUST BE ZERO
/ JMS WRMSG
/ TEXTZ @MESSAGE@
/ ... NORMAL RETURN, AC == 0
/
WRMSG, 0
WRLP, TAD I WRMSG / MESSAGE TEXT FOLLOWS CALL
MQL / SAVE NEXT MESSAGE WORD IN MQ
ISZ WRMSG / BUMP RETURN ADDRESS
CLA MQA / EMIT HI 6B OF WORD
BSW
JMS WRHF
CLA MQA / EMIT LO 6B OF WORD
JMS WRHF
JMP WRLP
/
WRHF, 0
AND K77 / EXTRACT 6B PAL CHAR
SNA / ZERO MARKS END OF MESSAGE
JMP WREX
TAD K40 / CONVERT 6B PAL TO 7B ASCII
AND K77
TAD K40
JMS WRCHR
JMP I WRHF
/
WREX, TAD K15 / CR
JMS WRCHR
TAD K12 / LF
JMS WRCHR
JMP I WRMSG
/
K77, 77
K40, 40
K15, 15
K12, 12
/ WRITE CHARACTER TO CONSOLE
/ CALLING SEQUENCE
/ ... AC MUST CONTAIN 7B ASCII CHAR
/ JMS WRCHR
/ ... NORMAL RETURN, AC == 0
/
WRCHR, 0
SKCFL TTY / SEND 7B CHAR TO CONSOLE
JMP .-1
WRSEQ TTY
CLA / SOME CONSOLES DO NOT CLEAR AC
JMP I WRCHR
AnOne interesting exception
The authors of the PAL8 assembler managed to cram a 6-char symbol, a 2-bit type, two 1-bit boolean flags, and a 12-bit defined value into each 4-word symbol table entry. They did this by restricting the symbol character set to 36 chars plus a null terminator, and using radix encoding instead of concatenation.
Then the mapped values are stored 2 per word in radix-37 format, that is, hi-char * 37 + lo-char. Since the greatest char code is 36, the greatest value of a radix-37 pair is 36 * 37 + 36 = 1368 (octal 2530) which occupies only 11 bits. This leaves one bit available to store a boolean flag.
+---+---+---+---+---+---+---+---+---+---+---+---+┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
word 1 |│ type |│ char1*37+char2 (octal 045..1746) |│
+---+---+---+---+---+---+---+---+---+---+---+---+├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
word 2 |│ ? |│ char3*37+char4 (octal 0..2530) |│
+---+---+---+---+---+---+---+---+---+---+---+---+├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
word 3 |│ ? |│ char5*37+char6 (octal 0..2530) |│
+---+---+---+---+---+---+---+---+---+---+---+---+├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
word 4 |│ 12-bit dependent value |│
+---+---+---+---+---+---+---+---+---+---+---+---+└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
Recovery of the two characters from a radix-37 pair is slow, but this is done only once, when printing out the symbol table, and. Originally the program had only to keep up with a printer or teletype console.
I don't know if earlier editions of PAL used a looser packing. I have the source code is fast enoughfor only the OS/8 PAL8 assembler.