--- title: "Super-Cipher 2068 V3.1" id: 55042 type: "computer_media" slug: "super-cipher-2068-v3-1" url: "http://localhost/computer_media/super-cipher-2068-v3-1/" markdown_url: "http://localhost/computer_media/super-cipher-2068-v3-1.md" published_at: "2024-06-11T13:41:03+00:00" modified_at: "2026-03-30T21:45:52+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2019/02/20230809-041332.jpg" excerpt: "A password-driven cipher tool encodes and decodes secret messages using modular arithmetic, with tape save/load, printer output, and a multi-level sub-menu system." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" indiv: - name: "Imre Auersbacher" slug: "imre-auersbacher" taxonomy: "indiv" url: "http://localhost/indiv/imre-auersbacher/" genre: - name: "Entertainment" slug: "entertainment" taxonomy: "genre" url: "http://localhost/type/entertainment/" media_contents: - id: 55036 title: "TS-2068 Computer Programs" type: "computer_media" url: "http://localhost/computer_media/ts-2068-computer-programs/" media_type: "Program" programmers: - name: "Imre Auersbacher" slug: "imre-auersbacher" taxonomy: "indiv" url: "http://localhost/indiv/imre-auersbacher/" mediadate: "1985" images: - url: "http://localhost/wp-content/uploads/2024/06/SCR-20260330-mpee.png" media_type_tags: "Entertainment" --- # Super-Cipher 2068 V3.1 Super-Cipher 2068 V3.1 is a Vigenère-style text encryption and decryption program that accepts keyboard input character by character, applies a password-derived numeric key array, and encodes or decodes messages stored in a 2600-character string array. The cipher uses a modular arithmetic formula — `x – 91 * INT(x/91)` — to wrap encoded character values into a printable ASCII range, with the key array built from a combination of the password’s first, last, and current characters plus its length. Messages can be printed to a printer, saved to tape as a DATA array, or loaded back from tape for decoding. Two custom UDG characters (“a” and “b”) are defined at startup via POKEs into USR memory, used for menu selection indicators. *** ## Program Analysis ### Program Structure The program is organized into clearly separated functional blocks, entered via computed `GO TO` from the main menu. The entry point at line `9500` initializes UDGs and jumps to the main menu at line `200`. The four menu options dispatch via `GO TO 1000*l` (line `270`), directing to lines `1000`, `2000`, `3000`, and `4000`. - Lines `2–9`: Custom keyboard input subroutine (GO SUB 2) - Lines `20–50`: Encoding subroutine (GO SUB 20) - Lines `60–100`: Decoding subroutine (GO SUB 60) - Lines `110–160`: Password entry and key array generation (GO SUB 110) - Lines `200–270`: Main menu display and dispatch - Lines `1000–1410`: Option handlers (code on screen, printer, tape save, re-code, re-decode, sub-menu) - Lines `2000–2040`: Decode on screen - Lines `3000–3060`: Decode from tape - Lines `4000–4090`: Termination sequence - Lines `9500–9990`: Initialization and UDG setup ### Cipher Algorithm The password processing subroutine at line `110` builds a numeric array `z(t)` where `t` is the password length. For each position `z`, the key value is computed as: `x = CODE y$(1) + CODE y$(z) + CODE y$(t) + t - 32` then reduced modulo 91: `z(z) = x - 91*INT(x/91)`. This mixes the first character, current character, and last character of the password, making the key non-trivially derived from the password string. Encoding (subroutine at line `20`) applies: `x = z(y) + t + 9`, then wraps with `CHR$(x - 91*INT(x/91) + 32)`, where `t` is the code of the plaintext character. Decoding (subroutine at line `60`) reverses this: `x = t - z(y) - 42`, then adds 91 repeatedly until `x >= 31` via a loop at lines `85–90`, finally producing `CHR$(x+1)`. The asymmetry between the +9/+32 encoding offset and the -42/+1 decoding offset is notable and must be internally consistent for round-tripping. ### Custom Keyboard Input Subroutine Lines `2–9` implement a fully custom line-input routine. It uses `ON ERR GO TO 4` at line `2` to handle out-of-bounds errors when the message buffer `m$` fills. The subroutine supports: - ENTER (code 13): terminates input, stores the carriage return, and RETURNs - DELETE/backspace (code 12): moves back one character, prints a PAPER 6 space to visually erase, and decrements `l` - Code 0 (no key or SHIFT): ignored - All other characters: stored in `m$(l)`, displayed in PAPER 3 / INK 7, and `l` incremented The `POKE 23692,0` call resets the scroll counter, preventing the “scroll?” prompt from interrupting output. ### Message Storage The message is stored in a single `DIM m$(2600)` string declared at line `3`. The variable `l` tracks the current length of the typed message. The terminating carriage return (code 13) at `m$(l)` serves as the end-of-message sentinel, checked in both encode and decode loops at lines `35` and `75`. Tape operations use `SAVE x$ DATA m$()` and `LOAD x$ DATA m$()` (lines `1220`, `3045`), saving the full 2600-byte array regardless of message length. ### UDG Initialization Lines `9500–9600` define two custom UDG characters using a DATA block at line `9900`. Eight bytes each for UDGs “a” and “b” are POKEd into `USR "a"` and `USR "b"` via a loop. These characters are used at line `1075` and `250` as menu selection arrow/pointer graphics printed beside the chosen option. ### Termination Sequence Option 4 triggers an elaborate termination at lines `4000–4090`. It uses SOUND commands to produce tones, cycles through PAPER and BORDER colors in a loop (lines `4025–4030`), flashes the screen several times, prints a “Program Terminated” message, calls `DELETE 0,4000` (which attempts to delete line range 0–4000), and finally executes `NEW` to wipe all variables and program state. The `CLEAR` at line `4000` also clears all variables before the sound/visual sequence. ### Notable Techniques and Idioms - `ON ERR GO TO 4` and `ON ERR RESET` are used for error trapping — the former recovers from a buffer overflow, the latter clears the error handler on a clean RETURN from input. - Computed dispatch: `GO TO 1000*l` eliminates an explicit IF/THEN chain for the four main menu options. - `VAL "number"` is not used; line numbers are given as literals in GO TO/GO SUB statements. - `POKE 23658,0` disables CAPS LOCK before INPUT statements to ensure consistent case handling. - The sub-menu at line `1055` uses `GO SUB 1000+100*INT x` (line `1085`) for computed subroutine dispatch across options 1–4. - The scroll suppression `POKE 23692,0` is used in multiple places to prevent interactive scroll prompts during long output sequences. ### Potential Issues - At line `3060`, `PRINT m$( TO 672)` displays only the first 672 characters of a potentially 2600-character message before pausing, which may truncate longer decoded messages on screen. - The key-stream cycling at lines `30`/`70` resets `y=1` when `y > LEN y$`, but the increment of `y` happens after the check, meaning the last key byte is used once before wrapping — a standard Vigenère cycling pattern. - In the decode formula, line `80` uses uppercase `X` (`LET X=t-z(y)-42`) while subsequent lines reference lowercase `x` — on this platform, BASIC variable names are case-insensitive, so this is not a bug. - The `DELETE 0,4000` at line `4080` is a TS2068-specific command; its effect before `NEW` is largely cosmetic since `NEW` clears everything anyway. ## Source Code ``` 1 GO TO 9500 2 LET l=1: ON ERR GO TO 4 3 DIM m$(2600): POKE 23692,0 4 IF INKEY$<>"" THEN GO TO 4 5 IF INKEY$="" THEN GO TO 5 6 LET q$=INKEY$: IF CODE q$=13 THEN LET m$(l)=q$: ON ERR RESET : RETURN 7 IF CODE q$=12 THEN PRINT CHR$ 8;: LET l=l-1: PRINT PAPER 6;" ";CHR$ 8;: GO TO 4 8 IF CODE q$=0 THEN GO TO 4 9 LET m$(l)=q$: LET l=l+1: PRINT PAPER 3; INK 7;q$;: GO TO 4 20 CLS : PRINT PAPER 6;"Coded message --> ": PRINT : 22 LET y=1: POKE 23692,0 25 FOR z=1 TO LEN m$ 30 IF y>LEN y$ THEN LET y=1 35 LET t=CODE m$(z): IF t=13 THEN LET l=z-1: RETURN 40 LET x=z(y)+t+9 45 LET q$=CHR$ (x-91*INT (x/91)+32): LET m$(z)=q$: PRINT q$; 50 LET y=y+1: NEXT z: RETURN 60 CLS : PRINT PAPER 6;"Decoded Message --> ": PRINT : 62 LET y=1: POKE 23692,0 65 FOR z=1 TO LEN m$ 70 IF y>LEN y$ THEN LET y=1 75 LET t=CODE m$(z): IF t=13 THEN LET l=z-1: RETURN 80 LET X=t-z(y)-42 85 IF x>=31 THEN GO TO 95 90 LET x=x+91: GO TO 85 95 LET q$=CHR$ (x+1): LET m$(z)=q$: PRINT q$;: LET y=y+1 100 NEXT z: RETURN 110 PRINT : PRINT "Password? "; 120 INPUT y$: IF LEN y$<=1 THEN BEEP 0.6,-22: GO TO 120 125 PRINT FLASH 1;" Secret " 130: LET t=LEN y$: DIM z(t) 140 FOR z=1 TO t: LET x=CODE y$(1)+CODE y$(z)+CODE y$(t)+t-32 150 LET z(z)=x-91*INT (x/91) 160 NEXT z: PRINT : RETURN 200 BORDER 5: POKE 23658,0: PAPER 3: CLS : POKE 23609,10 210 PRINT PAPER 6;AT 2,3;"\:'\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\':";AT 3,3;"\: SUPER-CIPHER 2068 V3.1 \ :";AT 4,3;"\: \ :";AT 5,3;"\: \* 1985 I. AUERSBACHER \ :";AT 6,3;"\:.\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\.:" 220 PRINT PAPER 7;AT 9,12;" MENU "; PAPER 3;AT 10,12;"\''\''\''\''\''\''"; PAPER 7;AT 12,4;"1-Code a message on screen";AT 13,4;"2-Decode message on screen";AT 14,4;"3-Decode message from tape";AT 15,4;"4-Terminate the program "; PAPER 6;AT 21,3;"Please Choose Option (1-4)" 230 LET q$=INKEY$: IF q$="" THEN GO TO 230 240 LET l=CODE q$-48: IF (l<1)+(l>4) THEN BEEP 0.5,-15: BEEP 0.5,-20: GO TO 230 245 BEEP 0.05,25 250 PRINT INK 0;AT 11+l,1;CHR$ 144; INK 6;CHR$ 145: PAUSE 60 260 BEEP 0.04,20: BEEP 0.04,20 270 PAPER 7: GO TO 1000*l 1000 CLS : PRINT PAPER 6;" 1. Code Message on Screen " 1010 GO SUB 110: PRINT PAPER 6;"Enter Message-->": GO SUB 2 1020 GO SUB 20: PRINT 1030 PRINT : PRINT FLASH 1;" Coding Complete ": PRINT : PRINT 1040 PRINT PAPER 6;AT 21,3;"Press any key to continue" 1050 IF INKEY$="" THEN GO TO 1050 1055 BEEP 0.1,25: PAPER 3: CLS : PRINT PAPER 1; INK 7;AT 2,4;" Super-Cipher Sub-MENU " 1060 PRINT PAPER 7;AT 6,10;" Options "; PAPER 3;AT 7,10;"\''\''\''\''\''\''\''\''\''"; PAPER 7;AT 9,4;"1-Copy Message to Printer";AT 10,4;"2-Save Message to Tape ";AT 11,4;"3-Code to Higher Level ";AT 12,4;"4-Decode to Lower Level ";AT 13,4;"5-Return to Main Menu "; PAPER 6;AT 21,3;"Please Enter Option (1-5)" 1065 LET q$=INKEY$: IF q$="" THEN GO TO 1065 1070 LET x=CODE q$-48: IF (x<1)+(x>5) THEN BEEP 0.5,-15: BEEP 0.6,-20: GO TO 1065 1075 BEEP 0.05,25: PRINT INK 0;AT 8+x,1;CHR$ 144; INK 6;CHR$ 145 1080 PAUSE 60: PAPER 7: BEEP 0.05,22: IF x=5 THEN GO TO 200 1085 GO SUB 1000+100*INT x 1090 GO TO 1055 1100 LPRINT : LPRINT m$( TO l): LPRINT : LPRINT : RETURN 1200 CLS : PRINT PAPER 6;AT 2,2;"Name of this message file? " 1205 POKE 23658,0 1210 INPUT x$: IF LEN x$>10 OR x$="" THEN BEEP 1,-20: GO TO 1210 1215 PRINT " ";x$: POKE 23658,0 1220 SAVE x$ DATA m$() 1230 BEEP 0.1,22: PRINT AT 5,2;"File: "; PAPER 6;x$; PAPER 7;" Saved."; FLASH 1;AT 8,8;" Stop Recorder " 1240 PAUSE 500: RETURN 1300 CLS : GO SUB 110: GO SUB 20 1310 PRINT : PRINT : PRINT FLASH 1;" Coding Complete ": PRINT : PRINT : PAUSE 2000: RETURN 1400 CLS : GO SUB 110: GO SUB 60 1410 PRINT : PRINT : PRINT FLASH 1;" Decoding Complete ": PRINT : PRINT : PAUSE 2000: RETURN 2000 CLS : PRINT PAPER 6;" 2. Decode Message on Screen " 2010 GO SUB 110: PRINT PAPER 6;"Enter Message-->": GO SUB 2 2020 GO SUB 60: PRINT 2030 PRINT : PRINT FLASH 1;" Decoding Complete ": PRINT : PRINT 2040 GO TO 1040 3000 CLS : PRINT PAPER 6;" 3. Decode Message from Tape " 3010 GO SUB 110: PRINT "What is file name? ";: POKE 23658,0 3020 INPUT x$: IF LEN x$>10 OR x$="" THEN BEEP 1,-20: GO TO 3020 3030 PRINT x$: POKE 23658,0 3035 INPUT "Press ENTER & Start Recorder "; LINE q$ 3040 PRINT : PRINT FLASH 1;AT 6,2;" Loading ";x$;" " 3045 LOAD x$ DATA m$() 3050 BEEP 0.1,22: PRINT : PRINT FLASH 1;" Please Stop Recorder " 3060 PAUSE 300: CLS : PRINT m$( TO 672): PAUSE 120: GO TO 2020 4000 CLEAR : SOUND 7,62;8,15 4020 FOR l=40 TO 120: SOUND 0,l 4025 LET x=l-6*INT (l/6)+1 4028 PAPER x: BORDER 7-x: CLS 4030 PAUSE 1: NEXT l 4040 SOUND 6,6;7,7;8,16;9,16;10,16;12,56;13,8 4045 BORDER 0: PAPER 0: CLS 4050 PAUSE 30: BORDER 7: PAPER 7: CLS : PAUSE 30: BORDER 0 4055 PAPER 0: CLS : PAUSE 30 4058 BORDER 7: PAPER 7: CLS 4060 SOUND 8,0;9,0;10,0 4070 PRINT FLASH 1;AT 10,5;" Program Terminated " 4080 PRINT PAPER 6;AT 14,6;" Security Risk = 0 ": DELETE 0,4000 4090 PAUSE 300: NEW 9500 BEEP 0.05,22: BEEP 0.06,20: POKE 23609,10: POKE 23658,0 9600 RESTORE 9900: FOR l=0 TO 7: READ x,y: POKE USR "a"+l,x: POKE USR "b"+l,y: NEXT l: GO TO 200 9900 DATA 0,24,0,48,127,96,127,255,127,255,115,248,115,248,127,240 9990 SAVE "cipher2" LINE 9500 ```