10 - Printer Setup, NOTIS Printing, and an Emulated Print-to-PDF Controller¶
This document has two halves:
- Part 1 (user guide, verified): how to set up the different printers, what printers are supported, and how to edit a small NOTIS-WP document and print it.
- Part 2 (engineering design): how to build an emulated printer in the RetroCore ND-100 emulator that looks like real hardware to SINTRAN and NOTIS, drains print jobs at full speed, and turns each completed job into a high-quality PDF - with the SINTRAN machine none the wiser.
Convention: [VERIFIED] = taken from an ND manual or a byte-verified carve in
this repo (cited). [DESIGN] = engineering proposal. [VERIFY] = a fact
from general knowledge that must be confirmed against a datasheet before you rely
on it. ASCII only; octal is written like 430 (octal) or 14o, hex like 0x0C.
Related docs: line-printer register spec
08-CDC-9380-LINE-PRINTER-INTERFACE.md;
carved spooler internals
07a-CARVED-INTERNALS-FINDINGS.md; terminal
aux-print 09-PRINTING-VIA-TERMINAL-AND-RETROTERM.md;
NOTIS printing ../../Reference-Manuals/Notis/NOTIS-PRINTING-AND-A4-PAGES.md.
PART 1 - USER GUIDE¶
1. What printers are supported [VERIFIED]¶
Two layers support printers: SINTRAN (the OS driver + spooler) and NOTIS (its own printer-definition table).
SINTRAN line-printer interface types (byte-verified in
../Devices/LINE-PRINTER-CONFIG-INSPECTION.md): 1 = DMA (Fujitsu),
2 = Parallel (CDC/DP, e.g. CDC 9380 at device 430), 3 = Serial. Plus
matrix/character printers on a terminal line (PRINTER) and the Versatec
plotter. See 02-HARDWARE-DEVICES.md.
NOTIS-WP supported printer models (from 10079K_NOTIS-WP.md; technology
classification corrected against web research - see the note below the table):
| Class | Models | Quality |
|---|---|---|
| Daisy-wheel | Data Products DP-55 (ND-235), Diablo 1610 / 1650 / 630, TEC-F10 | letter quality (best) |
| Matrix | Philips GP 300 L (ND-408/410/447), Epson MX-80 (ND-423), RX-80 (ND-224), HX-20 | NLQ / draft |
| Line printer | LINE-PRINTER / CDC 9380 (only ones that allow over-printing) |
draft, fast |
| Plotter (NOTIS-BG) | HP 7475A (ND-218, HP-GL), Philips ND-447/448, Versatec | vector / raster graphics |
Classification correction (web-verified): the Philips GP 300 / GP 300 L
(ND-408/410/447) is a 9-wire dot-matrix printer with an NLQ mode, not a
daisy-wheel - confirmed by NDWiki and by the fact that NOTIS-BG drove the Philips
for graphics (a daisy-wheel cannot print bit-image graphics). Earlier drafts of
this repo grouped it as daisy-wheel; the true letter-quality daisy-wheels in the
NOTIS list are the Data Products DP-55 (called a "Daisy wheel printer" in
10079K_NOTIS-WP.md line 935), the Diablo 1610/1650/630, and the TEC-F10.
No laser printer is supported by NOTIS-WP/TF (laser existed only via the separate NORTEXT phototypesetting product, which is not practical to emulate - see section 5.4). The highest-quality NOTIS text target is the Diablo-family daisy-wheel (letter quality; NOTIS-TF emits shadow-bold + font/pitch codes to it).
1.1 The real ND printer catalogue (from the ND library mirror) [VERIFIED]¶
Product numbers and models from E:\Dev\Ronny\mirror-sintran-com\mirror\library
(ND product-description sheets), grounding the models above in ND part numbers:
| ND no. | Model | Class |
|---|---|---|
| ND-232 (+233 feeder, 234 cover) | Diablo 1650 TEXT PRINTER, RS-232 - "word processor quality", proportional spacing, plotting, backward print, two-colour | daisy-wheel (the letter-quality target) |
| ND-424 (also ND-423) | Epson MX-80 | matrix |
| ND-408/410/447 | Philips GP 300 L | matrix (NLQ, multi-font) |
| ND-104701 / ND-103380 | Epson LX-80 | matrix |
| ND-110090 / ND-741259 | Epson LX-86 | matrix |
| ND-475 | GENICOM 3024 | matrix |
| ND-110278 | ND Matrix Printer ADP 515 | matrix |
| ND-616 CN (ND-12.043/044; fonts ND-211419) | ND 616 CN Printer (downloadable fonts) | matrix/colour |
| ND-460 TTP (ND-12.064) | ND Personal Printer 460 TTP | thermal-transfer personal |
| ND-433X | Line Printer, 1000 lpm | line |
| ND-452 | Line Printer | line |
| ND-110383 | ND Line Printer 815 BPA | line |
| ND-425X/426X/427X | TERMINET 340 (current-loop / parallel / RS-232) | line |
| ND-418X/419X | Tally 1612, 160 cps | matrix |
| ND-652 / ND-106520 | Versatec Controller (DMA) | electrostatic raster |
| ND-218 | HP 7475 plotter | vector plotter |
| ND-10644 ... ND-10885 | NORTEXT-100 Typesetter Output modules (Lasercomp, LN202, CG8400/8600, APS, Digiset, Metroset, AGFA P400, Harris 7450, Unisetter, Philips GP-300) | phototypesetter (NORTEXT only) |
Note the ND library has no "DIALOG"/"TELFIPS"/"ASTRID" printer product - those
WP-PRINTERS names are site logical names, not hardware (see section 5.0).
2. Setting up a printer [VERIFIED]¶
2.1 Central spooled printer (the normal case)¶
SINTRAN side (as user SYSTEM), see 03-CONFIGURATION.md:
- Bind a peripheral file to the printer's device number:
@SET-PERIPHERAL-FILE "LINE-PRINTER",5(device 5 = line printer 1). - Create extra versions so there are spooling files (buffers):
@CREATE-FILE LINE-PRINTER;10,0(1 real + 9 spooling files). - If it is a special-interface line printer, set its type in SINGEN
("Define printer type": 1 DMA / 2 Parallel / 3 Serial) or bind the spooling
index in the service program:
*SET-SPOOLING-DEVICE-NUMBER 1,5 Y Y Y. - Start the spooler:
@START-SPOOLING LINE-PRINTER.
NOTIS side: add the printer to the printer-definition text file
WP-PRINTERS:TEXT (columns: Printer Type | SINTRAN file name | Logical name
| Feed T/S/D | Default start | Font/Nationality), edited during INSTALL-WP.
Pick the default in NOTIS-WP Menu no. 4. The logical NOTIS name must map to
the SINTRAN peripheral/spooling file name.
2.2 Printer on the user's own terminal (local) [VERIFIED]¶
For a printer on the ND-NOTIS terminal auxiliary port:
- SINTRAN:
@SET-TERMINAL-FILE "EPSON"(routes to the terminal's printer port), and disable that line's login if it is a dedicated printer line (*REMOVE-FROM-BACKGROUND-TABLE <ldn>). - NOTIS: add the name (e.g.
EPSON, orTERMINAL) toWP-PRINTERS:TEXT.
Warning (from the manual): local terminal printing is unbuffered - "your terminal will hang unless you have a local printer". See 09-PRINTING-VIA-TERMINAL-AND-RETROTERM.md.
3. Edit a small document in NOTIS-WP and print it [VERIFIED]¶
@NOTIS-WP-ENG ; start the editor (terminal type must be 53)
; WP: appears at the Home position
; --- create and type a document ---
; press the down-arrow / HOME to reach the WORK AREA, then type:
^H1=My First Letter; ; a page header (print directive)
^JM;C; ; centre-justify the next lines
Dear Reader,
^JM;S; ; back to stretch (smooth right margin)
This is a small document written in NOTIS-WP on an ND-100.
It will be printed on the line printer.
; --- store it (Home command W) ---
; go to HOME position, type:
W "MY-LETTER" ; stores MY-LETTER:TEXT
; --- print it (PRINT key, or Home command O) ---
; the dialog:
DEVICE NAME: ; Enter = default printer, or type LINE-PRINTER
AREA: ; Enter = whole document
NO. OF COPIES:1 ; only honoured if the printer has a spooling file
PAGE LIST: ; Enter = all pages
FORMAT? Y ; Y = apply the ^ directives and menus
For a plain paginated document this is all you need - NOTIS-WP's own PRINT
formats it. For sophisticated layout (chapters, TOC, index) press SHIFT+PRINT
to run NOTIS-TF first, proof the :OUT file in Inspect mode, then print with
C. Either way the bytes end up at a SINTRAN spooling/peripheral file and the
SINTRAN spooler drives the printer.
PART 2 - EMULATED PRINT-TO-PDF CONTROLLER (DESIGN)¶
4. Goal and the transparency principle [DESIGN]¶
Build a device in the RetroCore ND-100 emulator that:
- presents itself on the ND bus exactly like a real ND printer controller, so SINTRAN's stock driver and NOTIS drive it with no modification and no knowledge that it is emulated;
- drains the print stream at full emulator speed (no mechanical delay), so a job that took minutes on real iron finishes in milliseconds;
- reconstructs each print job and renders it to a high-quality PDF, created only once the job is known complete, then saved atomically.
The ND machine sees a normal, always-ready printer. The PDF machinery lives entirely on the host side of the emulator and is invisible to SINTRAN.
5. Which printer to emulate, and why [DESIGN, backed by web research]¶
This section supersedes an earlier draft that led with the CDC 9380. After researching every printer NOTIS/SINTRAN documents (web sources cited in 5.5), the conclusion for highest quality is:
Emulate the Diablo 630 (630 ECS/API superset) as the primary target for letter-quality NOTIS-WP/TF text. Build one daisy-wheel decoder around the byte-verified Diablo 630 command set; expose the other daisy-wheels (Diablo 1610/1650, Qume, TEC-F10, DP-55) as profiles/flags on it. Keep the CDC 9380 line printer as the simple/fast fallback and the HP 7475A (HP-GL) as the NOTIS-BG graphics target. The phototypesetter tier is out of scope (5.4).
5.0 ND primary-source confirmation (from the ND library mirror)¶
The Norsk Data library mirror (E:\Dev\Ronny\mirror-sintran-com) settles the key
questions from ND's own product sheets:
- The ND letter-quality printer is the Diablo 1650, shipped as ND-232
("TEXT PRINTER, Diablo 1650 for RS 232 Interface",
mirror\library\libpdpi\ ND-232-B1-EN.pdf). Verbatim: it is built on "Diablo's field proven Model 1355/WP printer mechanism", produces "word processor quality" output that "can include two-colour printing and graphics", with selectable options for "true proportional spacing and right margin justification, plotting, backward printing, and remote diagnostics". Interface: RS-232-C, switchable 110/300/1200 baud, optional to 9600. (Accessories: ND-233 cut-sheet feeder, ND-234 acoustic cover.) This is direct ND confirmation of the section-5 recommendation: the target is the Diablo 1650 (ND-232) driven over serial with the Diablo command set (proportional spacing, plotting/HyPlot, backward-print, red/black - all in the section 7.2 table). Emulate that. - The ND-branded "DIALOG-15xx/16xx/17xx", "TELFIPS", "ASTRID" names are NOT ND
printer hardware. The mirror's comprehensive printer catalogue (see the list
in Part 1 section 1) contains no such product. As the NOTIS manual states,
the
WP-PRINTERSlogical names are site-chosen and "independent of the real Sintran-III file name", so these are example logical names in the sample printer-definition file, not distinct devices. ("DIALOG-1650" is most likely a site alias for the ND-232 Diablo 1650.) Do not try to emulate them as hardware - map the logical name to whichever real printer it points at.
5.1 Why Diablo 630 wins for text [research-backed]¶
- Highest text quality in the NOTIS set. It is letter-quality (era benchmark, "equivalent to an IBM Selectric"), whereas the line printer and the Epson/ Philips matrix printers are draft/NLQ.
- Richest positioning + formatting to reconstruct from. Full microspacing
(HMI = 1/120 inch, VMI = 1/48 inch), absolute horizontal/vertical tabs,
proportional spacing, half-line feeds for super/subscript, and WP attributes
(bold
ESC O, shadowESC W, auto-underlineESC E/ESC R). This is exactly the geometry a faithful high-quality PDF needs - see the full table in 7.2. - The de-facto industry standard. Diablo 630 is the letter-quality command
set; the whole daisy-wheel field either is it, descends from it, or offers a
"Diablo 630 mode" - including later HP/DEC/Apple/Kyocera laser printers. The
entire NOTIS daisy-wheel list (1610/1650, and the Diablo-ribbon/wheel-compatible
DP-55 and TEC-F10) shares the same
ESC US/ESC RScore, so one decoder covers all of them. - Best documented, with a head start. Full Diablo 630 API/SPI/HPRO5 manuals are on bitsavers/archive.org (byte tables verified), and an open-source Diab2PS translator already converts Diablo-630 streams to PostScript (auto-justify, center, underline, bold, shadow, H/V tabs, margins, microspacing, colour, backward printing). That is a near-perfect reference for our Diablo-630-to-PDF path.
- NOTIS formats natively for it. NOTIS-TF's
^BTshadow-bold and the WP attribute codes target the Diablo daisy-wheel; NOTIS-WP lists Diablo 1610/1650 as ND-supported and the K release note (line 970) says "The Diablo 630 printer will now be handled properly." So a real NOTIS stream to a Diablo is rich.
One caveat to honour: the base Diablo SPI set does not include the WP attributes (bold/shadow/underline) - those are the 630 ECS/API (Word-Processing) superset. A NOTIS-WP stream almost certainly uses the WP superset, so decode the ECS/API superset, not the bare SPI set.
5.2 The one-decoder-plus-profiles strategy [research-backed]¶
The daisy-wheels form one command family (signature: ESC US n HMI 1/120",
ESC RS n VMI 1/48"). Implement one Diablo-630-ECS decoder, then:
| Profile | Status | Notes |
|---|---|---|
| Diablo 630 ECS/API | codes byte-verified from primary manuals | the reference profile |
| Diablo 1610 / 1650 | same core, WP-attribute bytes less accessible | subsumed by the 630 superset |
| Qume Sprint | co-standard, feature-equal, programming manual not online | Diablo-630 profile + "Qume" flag; resolve divergences from a captured stream |
| TEC-F10 / C.Itoh | "Diablo-630-like" but treated as a separate entry in period software - diverges somewhere | Diablo-630 profile + "F10" flag; confirm from capture |
| Data Products DP-55 | ND calls it a daisy-wheel; no command manual found | Diablo-630 profile; confirm from capture |
Rule: wherever the online record is thin (Qume, F10, DP-55), a captured real NOTIS-WP byte-stream is the final authority - do not hard-code guessed codes. Mark such bytes UNVERIFIED until a capture or primary PDF confirms them.
5.3 The other device classes¶
- CDC 9380 line printer (device 430) - keep as the fast/simple fallback. Fully documented in this repo (doc 08), already emulated in RetroCore, SINTRAN-native, highest throughput, but text-only draft (fixed font; bold/ underline only via over-printing). Because we re-render, its output can still be made into a clean PDF - it just carries the least formatting information. Good first milestone; not the quality winner.
- HP 7475A / HP-GL (ND-218) - the graphics target for NOTIS-BG. The only inherently vector device: its stream reconstructs to crisp, resolution-independent vector PDF (lines, arcs, scalable stroked text, 6 pens). Fully documented standard. Use it when the job is a NOTIS-BG chart/plot, not WP text.
- Epson RX-80 / ESC/P - best-documented, graphics-capable, but draft. ESC/P is byte-for-byte public with bit-image graphics (60-240 dpi), but 9-pin draft quality. A reasonable secondary if you want one profile that handles both text and raster graphics; below Diablo for pure text quality.
- Versatec (603-606) - 200 dpi electrostatic raster, a "dumb bitmap sink"; easy to reconstruct mechanically but almost no command language.
- DIALOG-15xx/16xx/17xx, TELFIPS-300/700, ASTRID - resolved: not hardware.
The ND library mirror's full printer catalogue contains no such product; these
are site-chosen logical names in the
WP-PRINTERSsample file (see 5.0), not devices. Map each to the real printer it points at (e.g. DIALOG-1650 -> the ND-232 Diablo 1650) and emulate that.
5.4 The typesetting tier is out of scope [research-backed]¶
"If it's typesetting, even better" - unfortunately not feasible. The true typesetting tier (NORTEXT's phototypesetters: Monotype Lasercomp, Linotron 202, Compugraphic/Agfa) is not practical to emulate:
- Their host interfaces were proprietary and essentially undocumented - the canonical proof is the Linotron 202, which Bell Labs had to disassemble and reverse-engineer to drive (there was no published command language).
- There was no standard - each typesetter needed its own reverse-engineered binary driver (font-memory loads, CRT/laser deflection, film transport).
- Output is 1-bit film/photo-paper for platemaking, not text-with-metrics, so "to PDF" would mean building a RIP against an unknown input format.
So the daisy-wheel (Diablo 630/1650) tier is the realistic quality ceiling for a PDF-targeting emulator. (Also note: NOTIS-WP/TF never drove a phototypesetter anyway - NORTEXT was a separate ND-COMTEC product.)
ND primary-source confirmation: the ND library mirror's brochure "TYPESETTER
OUTPUT - NORTEXT-100 Typesetter output modules" (mirror\library\libpdpi\
ND-10644-A1-EN.pdf, ND COMTEC) confirms this exactly. It lists a separate
per-typesetter "output module" program for each machine - Monotype Lasercomp
(ND-10644), CG8400/CG8600 (ND-10820/21), Linotron LN202 German/Scandinavian
(ND-10822/10874), APS + APS Micro5 (ND-10823), Digiset T20/T40 (ND-10824/10880),
Metroset (ND-10825), AGFA P400 (ND-10875), Unisetter (ND-10876), Harris 7450
(ND-10882), and Philips GP-300 (ND-10885). Each "is adjusted to fit the
specialities of one certain typesetter" and converts NORTEXT-100 typographic
codes into that typesetter's format via example font/typesetter/conversion
tables. That is precisely the bespoke, per-device, undocumented-to-outsiders
model that makes the typesetter tier impractical to emulate - and it required the
NORTEXT-100 Editor (ND-10800), not NOTIS-WP. (Aside: the Philips GP-300 appears
here as a low-end NORTEXT proof/output device too - consistent with it being a
multi-font dot-matrix, not a daisy-wheel.)
5.5 Sources¶
Diablo 630 API/SPI/HPRO5 manuals (bitsavers/archive.org) + Diab2PS (github.com/wwarthen/Diab2PS); Diablo/Qume/daisy-wheel standard context (en.wikipedia.org/wiki/Diablo_630, /Qume); NEC Spinwriter + ESC/P + HP-GL references; Linotron 202 reverse-engineering (cs.princeton.edu/~bwk/202/); Compugraphic/Agfa (en.wikipedia.org/wiki/Compugraphic); ND rebadge/hardware list (ndwiki.org/wiki/Hardware_list). Full URL list is in the research notes; every escape byte in 7.2 is tagged with its verification level.
6. The controller interface and the "instant-ready" fast path [VERIFIED interface + DESIGN timing]¶
Emulate the CDC 9380 register block at device 430 (line printer 1; 434 for printer 2). Registers [VERIFIED, doc 08]:
| IOX | Reg | Dir | Function |
|---|---|---|---|
| 430 | 0 | read | Read Data (loopback, test only) |
| 431 | 1 | write | Write Data (one character into the buffer) |
| 432 | 2 | read | Read Status |
| 433 | 3 | write | Write Control |
Control word (write, IOX 433) bits: b0 int-on-ready, b1 int-on-error, b2 activate (print buffered char), b3 test, b4 device/interface clear. Status word (read, IOX 432) bits: b3 ready for transfer, b4 error, b5 not-ready, b6 out-of-paper, b11-12 band.
The performance rule [DESIGN]: a real line printer asserts "ready for
transfer" only after the mechanism has accepted the character (milliseconds per
char). The emulated controller must assert ready immediately and always -
never out-of-paper, never not-ready - and raise the level-10 "ready" interrupt on
the very next emulator tick after each activate. Consequences:
- SINTRAN's driver loop (
write data -> activate -> wait ready-interrupt -> next char, byte-verified in../Devices/LINE-PRINTER-CONFIG-INSPECTION.md) never stalls; the whole file is consumed as fast as the CPU can execute IOX. - Do not model real print speed. The only "device" work per character is appending one byte to a buffer (section 10), which is O(1).
If you ever need even less per-character overhead, emulate the DMA (Type 1) line-printer instead so SINTRAN hands whole buffers - but with instant-ready PIO the character path is already effectively free. Keep the status register truthful only for what SINTRAN checks (ready set, error clear, paper OK).
Transport depends on the target [DESIGN]. The register block above is the CDC
9380 parallel line printer (the simple/fast fallback, section 5.3). The
recommended Diablo 630 primary target is a serial device - SINTRAN drives
it as a Type-3 serial line printer (or as a serial printer on a terminal
line via WP-PRINTERS), so its controller is the async serial interface (data +
control/status registers of the 4/8 async controller, see
02-HARDWARE-DEVICES.md), not the 430 block. The
instant-ready principle is identical: assert transmit-ready every tick and
never assert busy, so the byte stream drains at full speed. Only the register
addresses/handshake differ; the capture + PDF pipeline (sections 8-11) is
transport-independent - it consumes the byte stream whichever controller
delivered it.
7. Control / escape codes the controller must understand¶
7.1 CDC 9380 line printer [VERIFIED, doc 08]¶
The controller does not itself need to interpret these for printing (it just buffers bytes), but the PDF reconstructor (section 9) must:
| Code (octal) | Meaning | PDF effect |
|---|---|---|
| 40-176 (printable ASCII) | character | place glyph at current column, advance |
| 11 (HT) | horizontal tab / space in CDC controller | advance to next column stop |
| 12 (LF) | line feed | next line, same column origin |
| 14 (FF) | form feed | end of page -> flush page, new page |
| 15 (CR) | carriage return | column := 0 (enables overprint of the same line) |
| 20-33 | VFU channels (LP9, form control) | vertical skip to a form channel; treat 20 as FF-like |
| 0-37 others | illegal, ignored by the interface | ignore |
Emphasis on this hardware is done by over-printing: print a line, CR, print
it again over the same positions (bold = double strike) or print underscores over
it (underline). The reconstructor detects "a glyph printed where one already
exists" and "underscore over a glyph" to synthesise bold and underline.
7.2 Diablo 630 ECS/API - the primary (letter-quality) decoder¶
This is the full command table for the recommended primary target (section 5),
sourced from the Diablo 630 API (90440-00A), SPI (90449-01A) and HPRO5 (90441-01A)
manuals on bitsavers/archive.org, cross-checked against the code-verified Diab2PS
decoder. ESC = 0x1B. Verification: [V] = read from a primary Diablo manual
or the code-verified decoder; [V-ECS] = Word-Processing/ECS superset (verify
the exact byte in the API PDF before shipping); [?] = lower confidence, confirm
before use. (n) = one following count/position byte (not an ASCII digit).
Motion and positioning - the core the PDF geometry depends on:
| Function | Bytes | Meaning | Ver |
|---|---|---|---|
| Set HMI (horizontal motion index) | ESC US (n) = 1B 1F n |
HMI = (n-1) x 1/120 inch | [V] |
| Set VMI (vertical motion index) | ESC RS (n) = 1B 1E n |
VMI = (n-1) x 1/48 inch | [V] |
| HMI from pitch switch | ESC S = 1B 53 |
cancel programmed HMI | [V] |
| Absolute horizontal tab | ESC HT (n) = 1B 09 n |
move to print column n | [V] |
| Absolute vertical tab | ESC VT (n) = 1B 0B n |
move to line n | [V] |
| Set / clear / clear-all H-tab | ESC 1 / ESC 8 / ESC 2 |
tab stop management | [V] |
| Left / right margin | ESC 9 / ESC 0 |
set at current column | [?] |
| Form length (lines/page) | ESC FF (n) = 1B 0C n |
1-126 | [V] |
| Proportional spacing on / off | ESC P / ESC Q = 1B 50 / 1B 51 |
PS carriage | [V] |
| Forward / backward print | ESC 5 / ESC 6 |
R-to-L printing | [V] |
Base ASCII controls and vertical specials:
| Function | Bytes | PDF effect | Ver |
|---|---|---|---|
| CR / LF / FF / BS | 0D / 0A / 0C / 08 | col:=0 / next line (one VMI) / page break / back one HMI | [V] |
| HT / VT | 09 / 0B | to preset horizontal / vertical tab stop | [V] |
| Microspace backspace 1/120" | ESC BS = 1B 08 |
fine back step (PS) | [V] |
| Reverse (negative) line feed | ESC LF = 1B 0A |
paper up one line | [V] |
| Half-line feed up (superscript) | ESC U = 1B 55 |
raise 1/2 line | [V] |
| Half-line feed down (subscript) | ESC D = 1B 44 |
lower 1/2 line | [V] |
Word-processing attributes (630 ECS/API superset - a NOTIS-WP stream will use these; the base SPI set does not have them):
| Function | Bytes | PDF effect | Ver |
|---|---|---|---|
| Auto-underline on / off | ESC E / ESC R = 1B 45 / 1B 52 |
underline run | [V-ECS] |
| Bold (double-strike) on | ESC O = 1B 4F |
bold (letter O, not zero) | [V-ECS] |
| Shadow print on | ESC W = 1B 57 |
heavier bold | [V-ECS] |
| Bold / shadow off | ESC & = 1B 26 |
end emphasis | [V-ECS] |
| Ribbon secondary (red) / primary (black) | ESC A / ESC B |
colour run (NOTIS-TF ^BT can use 2nd pass) | [V] |
| ECS glyph-row shift | SI / SO = 0F / 0E |
second wheel row (symbols/Greek/fractions) | [V] |
Reset / graphics:
| Function | Bytes | Note | Ver |
|---|---|---|---|
| Remote reset / initialise | ESC CR P = 1B 0D 50 |
~1 s to complete | [V] |
| HyPlot vector graphics on / off | ESC 3 / ESC 4 = 1B 33 / 1B 34 |
120x48 dot grid; BS/LF become fine steps. Diab2PS does NOT implement this - confirm in the API PDF | [?] |
The reconstructor maintains a cursor in HMI/VMI units, applies half-line feeds as baseline shifts (true super/subscript), tracks the attribute flags for bold/ shadow/underline, and uses proportional-spacing + microspacing to place glyphs at exact x positions - all of which map cleanly to positioned text runs in the PDF (section 9). This is why the Diablo path yields the highest-quality output.
Head start: the open-source Diab2PS (Diablo-630 -> PostScript) already decodes auto-justify, centre, underline, bold, shadow, H/V tabs, margins, microspacing, alternate colour and backward printing - use it as the reference implementation for the decoder + geometry, retargeted from PostScript to the PDF page model here.
7.3 What the printer does NOT see¶
NOTIS ^...; directives and NOTIS-TF macros are resolved before printing -
the device receives only plain characters + the device control codes above. So
the reconstructor never has to parse NOTIS directives.
8. Job lifecycle: new print, page breaks, completion [DESIGN]¶
This is the crux: at the IOX level there is no explicit "job start/end". Use a layered detector, most-authoritative signal first.
8.1 State machine¶
(no data, idle)
|
first IOX-431 write ----------> [JOB ACTIVE]
| | each data byte -> page model (sec 9)
| | FF / VFU-form -> close page, start new page
| |
| +-------------+-------------------------------+
| | completion trigger (whichever fires first): |
| | A. interface clear (control b4) |
| | B. spooler close snoop (optional, sec 8.3) |
| | C. idle timeout T after last byte |
| +-------------+-------------------------------+
| v
| [JOB COMPLETE] -> flush last page,
| render + save PDF (sec 9/11), reset
v |
(back to idle) <----------------+
8.2 The triggers [DESIGN]¶
- JOB START: transition idle -> active on the first
Write Data(IOX 431) after an idle period, or on the firstactivatecontrol word. Allocate a fresh page-model (do not create the PDF file yet). - PAGE BREAK:
FF(14o), or a VFU top-of-form channel (20o). Close the current page and begin a new one; a run of trailing blank pages is trimmed at finalize. - JOB COMPLETE - finalize on whichever fires first:
- A. Interface clear - SINTRAN writes control-word bit 4 (device/interface clear). The spooler may clear the interface between files; treat as an immediate, HW-authentic end-of-job. [VERIFY] whether the SINTRAN spooler actually issues clear at file boundaries (test by tracing IOX 433 between two queued files).
- C. Idle timeout - the robust, printer-independent fallback: if no byte
arrives for
Tafter the last byte (default T = 2000 ms [DESIGN], configurable) and the job has >= 1 page of content, finalize. This is exactly how host-side print-to-PDF spoolers decide a job ended. - Finalize on min(A, C) (and B if enabled). A trailing
FFthen idle is the normal end-of-file eject and is covered by C.
Idle-timeout note: because the emulated printer drains instantly, a whole file
arrives in a burst; the gap to the next queued file (SINTRAN dequeues the next
LSPOQ entry, opens it, starts the driver) is far longer than intra-file gaps,
so a modest T cleanly separates jobs. Tune T from a trace if needed.
8.3 Optional: authoritative boundaries by snooping the spooler [DESIGN, still transparent]¶
Because RetroCore sees all of SINTRAN's memory, it can observe (never signal) the byte-verified spooler to get exact, deterministic job boundaries and even the job's identity - completely invisibly to SINTRAN. From 07a-CARVED-INTERNALS-FINDINGS.md:
GetSpoolingEntry(MON 55, worker 106212B) dequeues the next queue entry - a clean job START signal, and the entry carries the file name / user / job name (fieldsSPFNA/SPUME/SPJNxoffLSPOQ=162122B) - perfect for naming the PDF.SPCLO(MON 40, worker 067572B) closes a spooling file - a clean job END.
Hooking a breakpoint/watch on these (emulator-side observation) gives 100% reliable start/end plus metadata, while the device still behaves like plain HW. Use this as the primary trigger when available, with the idle-timeout (8.2 C) as the fallback for direct (non-spooled) or terminal-file printing where these MON calls are not involved.
9. Page model and high-quality PDF rendering [DESIGN]¶
9.1 Page model¶
Represent each page as positioned glyph runs, not a bitmap:
- A page is a list of cells or runs:
(row, col, char, bold, underline, [xMicro, yMicro for daisy-wheel]). - Maintain a cursor
(col, row); printable char writes a cell and advances;CR-> col 0;LF-> row+1;HT-> next tab stop;FF-> close page. - Overprint detection (line printer): writing a printable char to an occupied
cell -> mark that cell bold (double strike); writing
_over a non-underscore glyph (or a glyph over_) -> mark underline. - For the daisy-wheel profile, use the HMI/VMI/half-line data to set sub-character
xMicro/yMicroand asuperscript/subscriptflag.
9.2 Geometry -> A4¶
- Page size: A4 by default (595 x 842 pt). Columns/lines per page come from
the stream: page length from the
FFcadence (and/or SINTRAN page length), and the character pitch from the printer/paper config. The CDC line printer is fixed pitch (typically 10 chars/inch, 6 lines/inch, up to 132 columns) - the exact cpi/lpi should be taken from theWP-PRINTERS"Font" column (e.g.8.0,11.7) or made configurable [VERIFY exact default cpi/lpi]. - Map
(row, col)to points using the chosen pitch and top/left margins so the page matches what NOTIS-TF laid out for A4 (its default geometry is tuned for A4 at 12 cpi - see the NOTIS doc).
9.3 Rendering for highest quality¶
- Emit vector text (real glyphs, not a rasterised bitmap) so output is crisp at any zoom and the PDF stays small.
- Embed a good monospaced font for faithful column alignment (a clean typewriter / Letter Gothic / a high-quality mono). Offer two style modes: a faithful look (mono, mimics the original) and a clean look; keep it configurable, default faithful.
- Bold -> bold font weight (or synthetic double-strike offset to mimic the daisy-wheel shadow). Underline -> drawn rule under the cell. Super/subscript (daisy-wheel) -> raised/lowered baseline at reduced size.
- Preserve exact horizontal positions from column index (and micro-spacing for daisy-wheel) so tables and justified text line up perfectly.
- Render at vector resolution (DPI-independent); if you also want a raster preview, 300+ DPI.
Use a PDF library that supports embedded fonts + precise text positioning; keep the renderer pure (page model in, PDF bytes out) so it is unit-testable.
10. Performance architecture [DESIGN]¶
Keep the emulation hot path O(1) and push all heavy work off-thread:
- IOX-431 write handler: append one byte to a lock-free/ring buffer and
return; assert ready immediately (section 6). No parsing, no allocation on the
hot path. Use a pooled buffer (
ArrayPool<byte>),Span<byte>slices - no LINQ, noforeachon the hot path (matches the RetroCore coding rules). - Consumer: a separate worker drains the ring buffer, runs the control-code state machine, and builds the page model. This decouples the ND CPU timing from parsing.
- PDF render: triggered only on JOB COMPLETE, run on a background task, off the emulation thread, so finalizing one job never stalls the next.
- Because the device is always-ready, a full document is accepted in a single fast burst; parsing + rendering happen afterwards without the ND machine waiting.
11. Finalize and save the PDF [DESIGN]¶
On JOB COMPLETE:
- Flush the current (last) page; trim trailing blank pages.
- Render all pages to PDF bytes (section 9).
- Name it deterministically: prefer the spooler-snoop metadata
(
SPFNAfile name +SPUMEuser + timestamp) if available (section 8.3); else a timestamp + sequence number. - Atomic save: write to a temp file,
fsync/flush, then rename into place, so a reader never sees a half-written PDF. - Reset the state machine to idle, release pooled buffers, ready for the next job.
12. Build order, verification, open items [DESIGN]¶
Recommended build order (milestone 1 is the fast fallback; the quality target is the Diablo 630):
- Fallback controller + always-ready fast path at device 430 (extend the
existing RetroCore CDC 9380). Prove SINTRAN
@COPY-FILE LINE-PRINTER,fileand@START-SPOOLINGdrain instantly. This validates the capture/lifecycle/PDF pipeline against a fully-verified device before adding the Diablo. - Capture + control-code state machine + page model. Unit-test with a known byte stream (chars, CR-overprint bold/underline, FF pages).
- PDF renderer (page model -> A4 vector PDF). Unit-test golden PDFs.
- Job lifecycle: idle-timeout completion first (portable), then add the interface-clear trigger, then the optional spooler snoop for authoritative boundaries + naming.
- Diablo 630 ECS decoder (the quality target) on a serial controller (section 6 transport note): implement the section 7.2 table (HMI/VMI, half-line super/subscript, bold/shadow/underline, proportional spacing), using Diab2PS as the reference. Add Qume/F10/DP-55/1610-1650 as profile flags.
- NOTIS end-to-end: edit a NOTIS-WP doc (Part 1 section 3), print to the emulated Diablo, confirm a faithful letter-quality A4 PDF (with real super/subscript and pitch). Capture the actual NOTIS-to-printer byte stream and reconcile any UNVERIFIED bytes against it - the capture is the final authority.
- (Optional) HP 7475A / HP-GL profile for NOTIS-BG graphics -> vector PDF.
Open items to verify before/while implementing:
- [VERIFY] exact default cpi/lpi and column count the SINTRAN/NOTIS print
path assumes (from the
WP-PRINTERS"Font" column, e.g.8.0/11.7, and/or a trace). - [VERIFY] whether the SINTRAN spooler issues interface-clear (control b4) between queued files (trace IOX 433) - affects the completion trigger.
- [VERIFY] the exact Diablo 630 bytes tagged [V-ECS]/[?] in section
7.2 (WP attributes, margins
ESC 9/ESC 0, HyPlotESC 3/ESC 4) against the API PDF and a captured NOTIS-to-Diablo stream, before hard-coding. - [VERIFY] what the ND-catalogue
DIALOG/TELFIPS/ASTRIDprinters actually are (section 5.3) before ever targeting one. - The generic line-printer driver code body and exact spooler close ordering are still open in 07a-CARVED-INTERNALS-FINDINGS.md (relevant if you rely on the snoop path).
Summary¶
- Setup / supported printers / edit-and-print: Part 1, all verified from the SINTRAN and NOTIS manuals (with the Philips-GP-300-is-matrix correction).
- For highest quality, emulate the Diablo 630 (630 ECS/API superset) - the letter-quality de-facto standard, richest text positioning (HMI 1/120", VMI 1/48", proportional spacing, half-line super/subscript, bold/shadow/underline), best-documented (primary manuals + the Diab2PS reference decoder), and the device NOTIS-TF formats natively for. One daisy-wheel decoder covers the whole family (Qume/F10/DP-55/1610-1650 as profiles). Use the CDC 9380 line printer as the simple/fast fallback and HP-GL (HP 7475A) for NOTIS-BG graphics.
- The phototypesetter tier is out of scope - proprietary, undocumented, film-output; the daisy-wheel is the realistic quality ceiling.
- Make the controller always-ready so jobs drain instantly; detect a new job on first data after idle (or the spooler-snoop MON 55 dequeue); detect completion via interface-clear / idle-timeout / spooler-snoop MON 40 close; then render the page model to a crisp A4 vector PDF and save it atomically - all invisible to SINTRAN/NOTIS.
- Wherever the online record is thin (Qume, F10, DP-55, the ND-branded units), a captured NOTIS byte-stream is the final authority - do not hard-code guessed codes.