Technically, the three common methods for storing text in a PDP-8 memory were: - two 6-bit chars per word, using the 64 glyph TTY character set - padded to 8-bit bytes, packed three bytes per two words - one char per word, accepting the overhead of four or five unused bits per char With a few rare exceptions, programs handle text for two reasons: - the program is intended to handle text as data - the program must emit predefined messages to the console, or as part of its output **One char per one word** 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 was willing to entertain the complications of doing so on packed text. At least one program (WPS8) used the extra bits to encode character attributes such as bold, underline, etc. **Three chars per two words** For some storage devices, the characters were packed 3 chars to 2 words, but this was more a function of the storage device driver than of the application software. The standard 3/2 packing method was somewhat strange -- byte 1 was 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 would produce the text with every 3rd char deleted. +---+---+---+---+---+---+---+---+---+---+---+---+ word 1 | byte 3 hi 4b | byte 1 | +---+---+---+---+---+---+---+---+---+---+---+---+ word 2 | byte 3 lo 4b | byte 2 | +---+---+---+---+---+---+---+---+---+---+---+---+ This format was introduced by the author of the RX01 floppy disk handler and subsequent developers never found a reason to break compatibility. **Two chars per one word** PDP-8 programs that emit predefined messages almost always used the upper-case only 64 char TTY set, and stored them as two 6-bit chars per word. The DEC PDP-8 assembler (PAL) (except the earliest editions) includes directives to pack literal strings. TEXT and TEXTZ both pack literal strings into two 6-bit chars per word; TEXTZ in addition appends a 6-bit zero terminator to the string before packing. Odd char count with null padding: TEXT @ERROR@ +-+-+-+-+-+-+-+-+-+-+-+-+ word 1 | E | R | +-+-+-+-+-+-+-+-+-+-+-+-+ word 2 | R | O | +-+-+-+-+-+-+-+-+-+-+-+-+ word 3 | R |0 0 0 0 0 0| +-+-+-+-+-+-+-+-+-+-+-+-+ Even char count and no padding: TEXT @STRING@ +-+-+-+-+-+-+-+-+-+-+-+-+ word 1 | S | T | +-+-+-+-+-+-+-+-+-+-+-+-+ word 2 | R | I | +-+-+-+-+-+-+-+-+-+-+-+-+ word 3 | N | G | +-+-+-+-+-+-+-+-+-+-+-+-+ Odd char count with zero terminator and no padding: TEXTZ @ERROR@ +-+-+-+-+-+-+-+-+-+-+-+-+ word 1 | E | R | +-+-+-+-+-+-+-+-+-+-+-+-+ word 2 | R | O | +-+-+-+-+-+-+-+-+-+-+-+-+ word 3 | R |0 0 0 0 0 0| +-+-+-+-+-+-+-+-+-+-+-+-+ Even char count with 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 0 0 0| +-+-+-+-+-+-+-+-+-+-+-+-+ A routine to write 7b ASCII messages to the console might occupy 20 words, while the corresponding routine to write 6b packed TTY messages would require 34 words. This means that unpacking 6b text consumes less total storage if you have more than about 28 characters of message in all. Here are a couple of "Hello, world!" programs using typical message dump subroutines: / 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