Cassette Label Maker

This file is part of and ISTUG Public Domain Library 6. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 2068
Tags: Tape

This program is a cassette label maker utility that formats and prints centered text across four lines, with an optional “cut-out” title mode for shorter, decorative labels. It uses LPRINT to send output to a compatible printer, and TAB expressions like `TAB 16-(LEN A$/2)` to center each text string on a 32-column line. The `OUT 123,27` and `OUT 123,14` commands in line 500 send escape codes directly to the printer interface, likely to control formatting or character size for the cut-out section. Lines 560–600 handle machine code loading and saving: a binary block of 1080 bytes is stored at address 64456 and managed via direct POKEs to system variables, with the SAVE/VERIFY sequence at line 600 writing both the BASIC program and the code block to tape. The program loops to allow multiple copies, multiple titles, and restarts, with input validation enforcing maximum string lengths throughout.


Program Analysis

Program Structure

The program divides into several functional regions:

  1. Lines 10–170: Setup, screen formatting, and collection of four label text lines with length validation.
  2. Lines 180–220: On-screen preview with a correction loop using INKEY$ polling.
  3. Lines 230–370: Print loop — sends the standard four-line label to the printer X times, then offers to repeat or start over.
  4. Lines 380–490: “Cut-out” label branch — collects a shorter title (max 10 characters) plus two shorter support lines, displays them, then re-enters the preview/print flow.
  5. Lines 500–540: Cut-out LPRINT section — sends printer escape codes before printing the narrow title.
  6. Lines 560–600: Loader/saver block — manages a machine code binary at address 64456, POKEs system variables, loads the code from tape, and saves both BASIC and code back to tape with VERIFY.

Text Centering Idiom

Every PRINT and LPRINT line uses the expression TAB 16-(LEN x$/2) to center a string on a 32-column output. Since TAB takes an integer, strings with odd lengths are implicitly truncated by integer division, biasing the result one character to the right of true center. This is a common and compact Sinclair BASIC centering technique.

Input Validation

Each of the four main label lines and the cut-out lines are validated for maximum length before the program proceeds. The thresholds vary by section:

VariablePurposeMax LengthEnforced at
A$Title line31Line 30
B$Line 231Line 60
C$Line 331Line 90
D$Bottom line31Line 130
F$Cut-out title10Line 390
G$Cut-out line 220Line 440
H$Cut-out line 318Line 470

The main lines use >=32 (rejecting strings of exactly 32 characters), while the cut-out lines use >10, >20, and >18 respectively — a slight inconsistency in boundary style.

Printer Escape Codes

Line 500 uses OUT 123,27 followed by OUT 123,14 to send raw bytes to the printer port. Byte 27 is the ASCII ESC character, and byte 14 is the SO (Shift Out) control code, commonly used with Epson-compatible and ZX Printer-style interfaces to switch to double-width or condensed print mode for the decorative cut-out title. This direct port manipulation bypasses the LPRINT channel entirely for control purposes.

Notably, the cut-out title TAB expression in line 500 uses TAB 8-(LEN F$/2) rather than TAB 16-(LEN F$/2), consistent with the title being half-width (double-size characters occupy double the physical space).

INKEY$ Keypress Loop

Lines 200–210 implement a wait-for-keypress idiom: line 200 loops while INKEY$="" (no key held), then line 210 checks for "N". Because INKEY$ is evaluated twice in sequence, there is a small window where a very briefly pressed key could be missed between the two reads — a well-known timing subtlety in this pattern. A more robust approach would store INKEY$ in a variable.

Machine Code Block Management

Lines 560–600 form a self-contained loader/saver that is never called during normal label-making operation (line 590 jumps to line 10, and line 560 is only reachable by direct GO TO or as the auto-start line). Key operations include:

  • CLEAR 64455 — sets RAMTOP just below the code area.
  • POKEs to addresses 26703–26704 — these are the system variable PROMS (printer buffer pointer), redirecting LPRINT output to the machine code routine at 64461.
  • POKEs at 64456–64459 — initialize fields within the machine code data structure (likely a header or parameter block for the custom print driver).
  • LOAD "labelmkr C" CODE 64456,1111 — loads 1111 bytes, though line 600 saves only 1080 bytes, suggesting the load length is intentionally generous or was edited independently of the save.
  • Line 600 performs a chained SAVE + VERIFY for both the BASIC program (auto-starting at line 560) and the code block.

Notable Anomalies

  • Line 550 contains a bare STOP that is unreachable under normal execution flow — likely a leftover from development.
  • Line 270 re-checks E$ inside the print loop, but because E$ was set before the loop and is never changed within it, the branch is always consistent. The logic mirrors the screen-preview path at lines 160–170.
  • Lines 180 and 400 both use PRINT AT 20,0;,,,, — printing five empty items — to blank the bottom area of the screen before the CORRECT? prompt.
  • The comment in line 220 notes “14 spaces between quotes,” indicating the programmer manually counted spaces to clear the bottom-line prompt area before the copy-count input.

Content

Appears On

Library tape of the Indiana Sinclair Timex User’s Group.

Related Products

Related Articles

Related Content

Image Gallery

Cassette Label Maker

Source Code

   10 BORDER 2: PAPER 6: POKE 23658,8: POKE 23609,60
   20 CLS : INPUT "PROGRAM TITLE:  ";A$
   30 IF LEN A$>=32 THEN GO TO 10
   40 PRINT TAB 16-(LEN A$/2);A$
   50 INPUT "LINE #2 INFO: ";B$
   60 IF LEN B$>=32 THEN GO TO 50
   70 PRINT TAB 16-(LEN B$/2);B$
   80 INPUT "LINE #3 INFO: ";C$
   90 IF LEN C$>=32 THEN GO TO 80
  100 PRINT TAB 16-(LEN C$/2);C$
  110 PRINT : PRINT : PRINT : PRINT : PRINT 
  120 INPUT "BOTTOM LINE #4: ";D$
  130 IF LEN D$>=32 THEN GO TO 120
  140 PRINT TAB 16-(LEN D$/2);D$
  150 PRINT AT 21,4; FLASH 1;"CUT OUT PRINTED (Y / N)": INPUT E$
  160 IF E$="N" THEN GO TO 180
  170 IF E$="Y" THEN GO TO 380
  180 PRINT AT 20,0,,,,
  190 PRINT OVER 1;AT 21,8; FLASH 1;"CORRECT? (/N)"
  200 IF INKEY$="" THEN GO TO 200
  210 IF INKEY$="N" THEN GO TO 20
  220 PRINT AT 21,8;"             ": INPUT "NUMBER OF COPIES :";X: REM 14 spaces between quotes
  230 FOR I=1 TO X
  240 LPRINT TAB 16-(LEN A$/2);A$
  250 LPRINT TAB 16-(LEN B$/2);B$
  260 LPRINT TAB 16-(LEN C$/2);C$
  270 IF E$="N" THEN GO TO 290
  280 IF E$="Y" THEN GO TO 500
  290 LPRINT : LPRINT : LPRINT : LPRINT : LPRINT 
  300 LPRINT TAB 16-(LEN D$/2);D$
  310 LPRINT : LPRINT 
  320 NEXT I
  330 INPUT "MORE? (Y/N): ";X$
  340 IF X$="Y" THEN GO TO 220
  350 INPUT "ANOTHER TITLE? (Y/N): ";X$
  360 IF X$="Y" THEN GO TO 20
  370 CLS : PRINT AT 10,8;"(WORK COMPLETED)": STOP 
  380 PRINT AT 20,0;"""CUT-OUT"" TITLE : 10 LETTERS MAX";AT 21,0;"X1234567890X                  ": INPUT F$
  390 IF LEN F$>10 THEN GO TO 380
  400 PRINT AT 20,0,,,,
  410 PRINT AT 3,0;"    "
  420 PRINT TAB 16-(LEN F$/2);F$
  430 INPUT "2nd LINE: ";G$
  440 IF LEN G$>20 THEN GO TO 430
  450 PRINT TAB 16-(LEN G$/2);G$
  460 INPUT "3rd LINE: ";H$
  470 IF LEN H$>18 THEN GO TO 460
  480 PRINT TAB 16-(LEN H$/2);H$
  490 GO TO 180
  500 LPRINT : OUT 123,27: OUT 123,14: LPRINT TAB 8-(LEN F$/2);F$
  510 LPRINT TAB 16-(LEN G$/2);G$
  520 LPRINT TAB 16-(LEN H$/2);H$
  530 LPRINT 
  540 GO TO 300
  550 STOP 
  560 CLEAR 64455: LET PRINTORG=64461: POKE 26704,INT (PRINTORG/256): POKE 26703,PRINTORG-(INT (PRINTORG/256))*256: POKE 64456,1: POKE 64458,0: POKE 64457,0: POKE 64459,79
  570 BORDER 2: CLS : PRINT INK 2;AT 8,0;"L O A D I N G   T H E    C O D E",,,,,,,,;TAB 7;" PLAY THE RECORDER ": LOAD "labelmkr C"CODE 64456,1111
  580 POKE 64463,0: POKE 64464,0: POKE 64465,0
  590 GO TO 10
  600 SAVE "LabelMkr" LINE 560: SAVE "labelmkr C"CODE 64456,1080: BEEP .5,10: PRINT #1;AT 0,5;"***REWIND THE TAPE***": PRINT #1;AT 1,5;"***PLAY TO VERIFY***": VERIFY "": VERIFY ""CODE 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

People

No people associated with this content.

Scroll to Top