MTOS

This file is part of and CATS Library Tape 6. Download the collection to get this file.
Developer(s): T. G. Morley
Date: 198x
Type: Program
Platform(s): TS 2068

MTOS (Multi-Task Operating System) is a BASIC-based utility shell that allows multiple programs to coexist in memory simultaneously, providing a menu-driven interface for loading, saving, and managing code segments. The system uses direct memory POKEs to the system variables at addresses 23635–23638 to redirect BASIC’s program pointer, effectively switching between resident programs without clearing RAM. A lookup table stored in string variables maps menu entries to their start addresses, with each entry occupying exactly 10 characters in the name string and 2 bytes in the address table. The suite includes sub-utilities for hexadecimal and decimal memory entry, UDG (User Defined Graphics) design, line location scanning, an lprint driver loader, and a hex/decimal converter. The MERGE command is exploited to load additional BASIC programs into the upper portion of memory, and ON ERR / RESET constructs are used extensively for error trapping and system control flow.


Program Analysis

Overall Architecture

MTOS is a shell system that maintains multiple BASIC programs in memory simultaneously. Rather than clearing and reloading programs, it manipulates the system variable that points to the start of the BASIC program area (addresses 23635–23636) so the interpreter “sees” whichever resident program the user selects. The main menu module (lines 1–9999 of the first section) acts as a dispatcher; the remaining sections are the individual utilities that live above it in RAM.

Program Structure

The listing is composed of several logically distinct modules, each with its own line-number space starting near line 1 or 5:

  • Main menu / shell (lines 1–9999): splash screen, menu display, program dispatch, MERGE integration, and the save-MTOS utility.
  • Line location scanner (lines 200–242 / standalone 5–100): walks raw memory to print BASIC line numbers and their addresses.
  • SaveMTOS (lines 300–350): saves the whole system to tape with optional verify.
  • Dec Enter (standalone, lines 5–120): interactive decimal byte entry into any memory location.
  • Hex Enter (standalone, lines 5–120 + 400–1060): interactive hexadecimal byte entry.
  • UDG Designer (standalone, lines 1–4140): 8×8 pixel grid editor that POKEs UDG slots via USR l$.
  • HexDecHex converter (standalone, lines 2–1410): bidirectional hex/decimal converter using a lookup string.
  • HexDecEnter (standalone, lines 7–2001): combined hex/decimal memory entry with runtime switching.
  • Instructions (standalone, lines 1–9997): plain-text help screen.

Program Pointer Manipulation

The core trick of MTOS is redirecting the BASIC interpreter to a different resident program. The address of the target program’s first line is written into system variables 23635 (LSB) and 23636 (MSB), then a GO TO 1 effectively restarts BASIC at that new location. Dispatch in line 49 reads the target address from the in-memory table and performs this switch:

49 LET nlp=PEEK t+PEEK (t+1)*256: ... POKE 23635,lsb: POKE 23636,msb: GO TO 1

The MERGE integration (lines 99–116) similarly saves and restores the program-end pointer (23627–23628) so the newly merged program’s start address can be stored in the dispatch table.

In-Memory Dispatch Tables

Two parallel tables are maintained in POKEd memory immediately after a REM or at a computed base address derived from PEEK 23637+PEEK 23638*256+9:

  • m / m$: a 180-character name table, 10 characters per slot (18 entries), used for menu display.
  • r / r$: a 2-byte-per-slot address table holding the actual start addresses of each resident program.
  • g: a single-byte counter recording how many programs are currently registered.

The base addresses are calculated at runtime from the PROG system variable so that the tables float with the program in memory.

Error Trapping as Control Flow

The ON ERR GO TO 9998 idiom appears throughout every module. Line 9998 implements a soft reset loop:

9998 FOR t=1 TO 50: NEXT t: ON ERR RESET: PAUSE 1: ON ERR GO TO 9998: RANDOMIZE USR 26715: GO TO 4

This catches any runtime error and returns control to the main menu. ON ERR RESET clears the error trap before the RANDOMIZE USR 26715 call (which executes machine code), preventing an error loop if the USR call itself fails.

Machine Code Usage

RANDOMIZE USR 26715 appears in lines 300, 9998, and 9999. Address 26715 (0x6873) falls within the BASIC program area itself — specifically inside a REM statement at line 5010 in the lprint-driver section. That REM contains raw machine code bytes disguised as BASIC keyword tokens. The lprint driver loader (lines 5005–5030) copies 266 bytes from this REM to address 64256 (0xFB00) and patches several vectors to install it.

The UDG designer module also uses a REM at line 4001 to store machine code, relocated and used to patch the UDG base pointer at 23675–23676.

Hex/Decimal Conversion Technique

The hex-to-nibble conversion subroutine (lines 1010–1060 in several modules) iterates over two FOR loops — one for af (ASCII 97–102, subtract 87) and one for 09 (ASCII 48–57, subtract 48) — rather than using a lookup string, giving an explicit character classification. The HexDecHex module instead uses the string a$="0123456789abcdef" and indexes it with A$(L+1) for the reverse (decimal-to-hex) direction.

UDG Designer Details

The UDG editor collects an 8×8 binary grid of 0/1 keypresses into array a(8,8). It then converts each row to a byte by summing a(l,c)*2^x with x running from 7 down to 0, and POKEs the result into USR l$+n where l$ is the chosen letter (a–u). The splash screen for this module (line 4005) uses UDG characters \a through \g to display a logo built from the newly defined graphics, so the characters it shows depend on whatever was previously in the UDG area.

MERGE Exploitation

Line 116 executes MERGE "" followed by STOP. The MERGE command loads a BASIC program from tape and appends it above the current one in memory without clearing existing lines. The STOP prevents execution from falling through. After the merge, the user types GO TO 9999 to register the new program’s name and address in the dispatch tables. Line 103 reminds the user: “to complete merge—goto 9999”.

Key BASIC Idioms

  • PAUSE 0 followed by PEEK 23560 for non-blocking keypress detection (the last key pressed is stored in LAST K).
  • LET input=95: GO SUB input — storing a line number in a variable and using it as a GO SUB target (line 95 is the key-input subroutine).
  • MSB/LSB splitting via LET msb=INT(addr/256): LET lsb=addr-msb*256 appears in at least six places.
  • The GO TO VAL "number" pattern is used in line 49’s indirect dispatch via computed addresses.

Notable Bugs and Anomalies

  • In the HexDecHex module, variables B$, A, H$, and M are referenced with mixed case (e.g., B$ vs. b$, line 20 vs. line 18). BASIC is case-sensitive for variable names in this implementation, so these would be treated as distinct variables, likely causing incorrect behavior.
  • Line 1311 in HexDecHex opens a FOR t=1 TO 4 loop that has no body and no NEXT before the subsequent LET dec=... line, making the loop effectively a no-op but leaving the loop variable set to 1.
  • In the hex enter module, line 36 uses ENTER (code 13) as the correction key for backspace behavior, which is the opposite of the dec enter module (which uses the left-arrow/DELETE key, code 8) — inconsistent UX across the two similar tools.
  • Line 76 in the main menu’s name-entry routine reads IF t=LEN k$ THEN LET t=10 inside a FOR loop where t is also the loop variable — modifying the loop counter mid-loop to pad short names with the last character entered.

Content

Appears On

Capital Area Timex Sinclair User Group’s Library Tape.

Related Products

Related Articles

Related Content

Image Gallery

MTOS

Source Code

    1 REM >VS\>h<>-
    2 LET t$="\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'                              \.'\.'       **** M T O S ****      \.'\.'                              \.'\.'              by              \.'\.'          T.G.Morley          \.'\.'                              \.'\.'           \* 8/7/84           \.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'"
    3 CLS : PRINT t$: PAUSE 150
    4 POKE 23730,251: POKE 23731,255: ON ERR GO TO 9998: CLS : GO SUB 5: GO TO 15
    5 LET m=PEEK 23637+PEEK 23638*256+9
    6 LET m$="merge-----linloc----savemtos--printprog-lprintfivedecenter--hexenter--bin-------hexdechex-hexdecentrdirections----------------------------------------------------------------------"
    7 LET r=PEEK 23637+PEEK 23638*256+9
    8 LET r$="\ppcs\ .udw5z\*\n\ .\:.n\d\ :\l--------------"
    9 LET g=PEEK 23637+PEEK 23638*256+9
   10 LET g$="": RETURN 
   15 LET t=r+PEEK g*2-2: IF PEEK t+PEEK (t+1)*256>=PEEK 23627+PEEK 23628*256-136 THEN GO SUB 85: POKE g,PEEK g-1: GO TO 4
   18 CLS : PRINT AT 0,9;"**** mtos ****"'TAB 12;"utilities": LET t=1: LET l=8: LET c=1
   20 FOR x=1 TO 18
   21 IF x=10 THEN LET l=8: LET c=16
   22 PRINT AT l,c;x;" ";m$(t TO t+9): LET t=t+10: LET l=l+1: NEXT x: PRINT AT 4,1;"enter choice"''TAB 14;: LET j=0: LET k$=""
   27 PAUSE 0
   28 LET j=PEEK 23560: IF j=13 AND k$="" THEN GO TO 4
   30 IF j=13 THEN GO TO 44
   32 IF j<48 OR j>57 THEN GO TO 4
   41 PRINT CHR$ j;: LET k$=k$+CHR$ j: IF LEN k$=2 THEN GO TO 44
   42 GO TO 27
   45 LET j=VAL k$: IF j>PEEK g THEN GO TO 4
   49 LET t=r+j*2-2: LET nlp=PEEK t+PEEK (t+1)*256: ON ERR RESET : LET msb=INT (nlp/256): LET lsb=nlp-msb*256: POKE 23635,lsb: POKE 23636,msb: GO TO 1
   50 CLS : PRINT AT 9,5;"enter program name"''TAB 11;: LET j=0: LET k$=""
   53 PAUSE 0
   55 LET j=PEEK 23560: IF j=13 AND k$="" THEN RETURN 
   56 IF j=13 THEN GO TO 70
   58 IF j<97 OR j>122 THEN GO TO 50
   60 PRINT CHR$ j;: LET k$=k$+CHR$ j: IF LEN k$=10 THEN GO TO 70
   62 GO TO 53
   70 LET p=m+PEEK g*10-10: FOR t=1 TO 10: POKE p,CODE k$(t): LET p=p+1
   76 IF t=LEN k$ THEN LET t=10
   80 NEXT t: RETURN 
   90 LET t=m+PEEK g*10-10: FOR p=t TO t+9: POKE p,45: NEXT p: LET t=r+PEEK g*2-2: FOR p=t TO t+1: POKE p,45: NEXT p: RETURN 
   99 POKE r,PEEK 23637: POKE r+1,PEEK 23638: PAUSE 0
  100 CLS : PRINT TAB 9;"**** merge ****"'''"load your program"''"or"''"shift break to enter code"
  103 PRINT AT 18,0;"to complete merge---goto 9999"
  105 POKE g,PEEK g+1
  107 LET t=PEEK 23627+PEEK 23628*256-136
  109 LET msb=INT (t/256): LET lsb=t-msb*256
  110 POKE 23635,lsb: POKE 23636,msb
  111 LET t=r+PEEK g*2-2
  112 POKE t,lsb: POKE (t+1),msb 
  116 MERGE "": STOP 
  200 { GO TO 9998: CLS : PRINT "    **** line location ****": INPUT "start ?";s: LET v=PEEK 23627+PEEK 23628*256-2
  205 IF s<26710 THEN LET s=26710
  210 FOR t=s TO v
  212 IF PEEK t<>13 THEN NEXT t
  213 LET t=t+1
  220 PRINT t;"  ";PEEK t*256+PEEK (t+1)
  230 LET t=t+(PEEK (t+2)+PEEK (t+3)*256)+2
  240 NEXT t
  241 PRINT '"press a key": PAUSE 0
  242 GO TO 9998
  300 RANDOMIZE USR 26715: GO TO 301
  301 ON ERR GO TO 335
  302 CLS : PRINT TAB 7;"**** savemtos ****"
  308 SAVE "mtos" LINE 1
  310 PRINT AT 8,7;"verify ??? ---(y/n)"
  320 PAUSE 0
  325 IF PEEK 23560=110 THEN GO TO 335
  330 IF PEEK 23560=121 THEN PRINT AT 8,7;"     start tape    ": VERIFY "": BEEP 1,10: PRINT AT 8,12;"press a key": PAUSE 0: CLS : PRINT AT 8,12;"verified   ": GO TO 9998
  333 GO TO 310
  335 FOR t=1 TO 10: BEEP .1,5: BEEP .1,10: NEXT t: PRINT AT 8,7;"not verified       "''TAB 8;"press a key": PAUSE 0
  350 GO TO 9998
    5 ON ERR GO TO 9998
   10 CLS : INPUT "start loc";a$: LET s=VAL a$
   11 IF s<=26710 THEN LET s=26709: GO TO 16
   15 IF PEEK s<>13 THEN LET s=s+1: GO TO 15
   16 LET s=s+1: PRINT s'PEEK (s+1)+PEEK s*256;
   20 FOR t=s+3 TO 65535
   22 IF PEEK t=14 THEN LET t=t+5: NEXT t
   23 IF PEEK t=13 THEN IF t+1>=PEEK 23627+PEEK 23628*256 THEN PRINT ''t+1,"end": STOP 
   25 IF PEEK t=13 THEN PRINT ''t+1'PEEK (t+2)+PEEK (t+1)*256;: LET t=t+3: NEXT t
   29 IF PEEK t<32 THEN NEXT t
   30 PRINT CHR$ PEEK t;: NEXT t
  100 FOR t=26710 TO 65535: PRINT t,PEEK t: NEXT t
 5005 CLS : POKE 23730,0: POKE 23731,251: PRINT AT 8,0;"loading lprint driver": LET d=PEEK 23637+PEEK 23638*256+5
 5010 REM - PRINT : CLS RETURN  LET STEP OUT CLS STEP BEEP CLS <> RETURN USR LET G: CLS RETURN COPY (PI(=2 CLS <>> OR STEP OUT CLS STEP THEN CLS STR$ STEP BEEP CLS : CLS LN  GO SUB CODE 2 CLS <>x RETURN (Z RETURN  >zN RETURN (] RETURN RETURN RETURN 0<>> COPY SAVE > POKE RETURN  CIRCLE RETURN STICK (( RETURN FREE ($ RETURN {8 RETURN \  0 CLEAR THEN f(8 RETURN RND0> STEP OUT CLS STEP THEN CLS STEP BEEP CLS <> VERIFY RND STEP E<>> STEP OUT CLS >CODE 2 CLS <>: CLS W THEN /_> MERGE STEP OUT CLS STEP THEN CLS MOVE STEP BEEP CLS : CLS INT >=SQR >= REM : CLS W: CLS INT TO \p CLS <>: CLS <2 CLS <>O STEP  8 CAT \* THEN O( CAT \s THEN g( OR RETURN STR$ zCOS  STOP CAT ABS y OPEN #\* FLASH \*<>
 5030 FOR t=64256 TO 64256+265: POKE t,PEEK d: LET d=d+1: NEXT t: POKE 26703,4: POKE 26704,251: POKE 64256,1: POKE 64257,0: POKE 64258,0: POKE 64259,77: POKE 64422,0: POKE 64423,0: POKE 64424,0: CLS : PRINT AT 8,0;"lprint driver loaded": GO TO 9998
    5 CLS : ON ERR GO TO 9998
    7 GO SUB 97
    8 LET input=95: LET a$=""
   10 PRINT AT 2,8;"enter start loc ";
   11 GO SUB input: PRINT k$;: LET a$=a$+k$: IF CODE k$<48 OR CODE k$>57 THEN GO TO 1
   12 IF LEN a$<5 THEN GO TO 11
   14 LET loc=VAL a$: LET sloc=loc
   26 GO SUB 97
   28 PRINT AT 5,3;"enter dec ?": LET lin=7: LET col=0
   30 PRINT AT 5,14;"   ": PRINT AT 5,14;: LET a$="": LET k$=""
   32 GO SUB input
   33 PRINT k$;
   34 IF CODE k$=8 THEN GO SUB 100: PRINT AT lin,col;"   ": GO TO 30
   36 IF CODE k$=13 THEN GO TO 80
   37 IF CODE k$>47 AND CODE k$<58 THEN GO TO 50
   38 GO TO 30
   50 LET a$=a$+k$
   55 IF LEN a$<3 THEN GO TO 32
   80 IF a$="" THEN GO TO 30
   81 IF VAL a$>255 THEN GO TO 30
   83 PRINT AT lin,col;a$
   84 LET col=col+4
   85 IF col=32 THEN LET lin=lin+1: LET col=0
   86 IF lin=10 THEN PRINT "check code----press a key ": PAUSE 0: LET lin=7: LET col=0: CLS : GO TO 26
   90 POKE loc,VAL a$: LET loc=loc+1
   91 LET t$="  start       end        bytes"
   92 PRINT AT 2,0;t$'"  ";sloc;TAB 13;loc;TAB 25;loc-sloc;"   "
   93 GO TO 30
   95 PAUSE 0: LET k$=CHR$ PEEK 23560: RETURN 
   97 CLS : PRINT TAB 5;"**** dec enter ****": PRINT AT 21,0;"correction ??? press left arrow": RETURN 
  100 LET col=col-4
  102 IF col=-4 THEN LET col=28: LET lin=lin-1
  105 IF lin<7 THEN LET lin=7: LET col=0: POKE loc,0: RETURN 
  106 POKE loc,0: LET loc=loc-1
  120 RETURN 
    5 ON ERR GO TO 9998
    7 GO SUB 97
    8 LET input=95: LET a$=""
   10 PRINT AT 2,8;"enter start loc ";
   11 GO SUB input: PRINT k$;: LET a$=a$+k$: IF CODE k$<48 OR CODE k$>57 THEN GO TO 1
   12 IF LEN a$<5 THEN GO TO 11
   14 LET loc=VAL a$: LET sloc=loc: LET lin=7: LET col=0
   26 GO SUB 97
   28 PRINT AT 5,3;"enter hex ?"
   30 PRINT AT 5,14;"   ": PRINT AT 5,14;: LET a$="": LET k$=""
   35 GO SUB input: PRINT k$;:
   36 IF CODE k$=13 THEN GO SUB 100: PRINT AT lin,col;"  ": GO TO 30
   37 IF CODE k$>47 AND CODE k$<58 OR CODE k$>96 AND CODE k$<103 THEN GO TO 39
   38 GO TO 30
   39 LET a$=a$+k$: IF LEN a$<2 THEN GO TO 35
   40 GO SUB 400
   80 PRINT AT lin,col;a$
   82 LET col=col+4
   84 IF col=32 THEN LET lin=lin+1: LET col=0
   86 IF lin=21 THEN PRINT "check code----press a key ": PAUSE 0: LET lin=7: LET col=0: CLS : GO TO 26
   90 POKE loc,dec: LET loc=loc+1
   91 LET t$="  start       end        bytes"
   92 PRINT AT 2,0;t$'"  ";sloc;TAB 13;loc;TAB 25;loc-sloc;"    "
   93 GO TO 30
   95 PAUSE 0: LET k$=CHR$ PEEK 23560: RETURN 
   97 CLS : PRINT TAB 5;"**** hex enter ****": PRINT AT 21,0;"correction ??? press enter"
  100 LET col=col-4
  102 IF col=-4 THEN LET col=28: LET lin=lin-1
  105 IF lin<7 THEN LET lin=7: LET col=0: POKE loc,0: RETURN 
  106 POKE loc,0: LET loc=loc-1
  120 RETURN 
  510 LET h=CODE a$(1): LET t=h: GO SUB 1000: LET h=t
  520 LET e=CODE a$(2): LET t=e: GO SUB 1000: LET e=t
  551 LET dec=h*16+e: RETURN 
 1010 FOR c=97 TO 102
 1020 IF t=c THEN LET t=c-87: RETURN 
 1030 NEXT c
 1040 FOR c=48 TO 57
 1050 IF t=c THEN LET t=t-48: RETURN 
 1055 NEXT c
 1060 PAUSE 0: GO TO 1
    1 ON ERR GO TO 9998: CLS : GO TO 4000
    2 DIM a(8,8): LET sw=0: LET b=0: LET a$=""
    3 LET Z$="                                                              "
    4 LET a$="99999999"
    5 FOR t=5 TO 12: PRINT AT t,1;a$: NEXT t
    7 PRINT AT 11,13;"save UDGs ????(y/n)"'''TAB 13;"menu ???? (m)": PAUSE 0
    8 IF PEEK 23560=121 THEN GO TO 4100
    9 IF PEEK 23560=109 THEN GO TO 9999
   10 PRINT AT 11,13;"                   "
   12 FOR t=5 TO 12: PRINT AT t,1;a$: NEXT t
   15 PRINT AT 16,1;"press 1 or 0": PRINT : PRINT : PRINT "to correct press 5"
   18 LET l=5: LET x=26710
   20 FOR t=1 TO 8
   30 LET a$=INKEY$: IF a$="" THEN GO TO 30
   32 IF a$<>"0" AND a$<>"1" AND a$<>"5" THEN GO TO 30
   33 IF a$="5" THEN LET t=t-1: GO SUB 100: PRINT AT l,t;"5": PAUSE 30: GO TO 30
   38 PRINT AT l,t;a$
   39 IF a$="0" THEN PRINT AT l,t;"'"
   50 LET a(l-4,t)=VAL a$
   55 PAUSE 30
   60 NEXT t
   70 LET l=l+1: LET t=1
   72 IF l=13 THEN PRINT : PRINT : GO TO 1000
   75 GO TO 20
  100 IF t<1 THEN LET l=l-1: LET t=t+8
  110 IF l<5 THEN LET l=5: LET t=1
  120 RETURN 
 1000 PRINT AT 16,1;"press letter": PRINT AT 19,0;"                  "
 1007 IF INKEY$="" THEN GO TO 1007
 1008 LET l$=INKEY$: IF CODE l$<97 OR CODE l$>117 THEN GO TO 1007
 1009 PRINT AT 16,1;"            ": PRINT AT 11,13;"I'm working on ";l$;"  ": LET x=7: LET b=0: LET n=0
 1010 FOR l=1 TO 8
 1020 FOR c=1 TO 8
 1030 LET b=b+a(l,c)*2^(x): LET x=x-1
 1040 NEXT c
 1045 POKE USR l$+n,b: LET b=0: LET x=7: LET n=n+1
 1050 NEXT l
 1060 CLS : PRINT AT 11,15;"GRAPHICS ";l$;"  O.K."
 1065 PRINT AT 0,0;: FOR t=144 TO 159: PRINT CHR$ t;" ";: NEXT t
 1066 FOR t=97 TO 112: PRINT CHR$ t;" ";: NEXT t
 1067 FOR t=160 TO 164: PRINT CHR$ t;" ";: NEXT t
 1068 PRINT AT 3,0;: FOR t=113 TO 117: PRINT CHR$ t;" ";: NEXT t
 1070 GO TO 2
 4000 LET udg=PEEK 23637+PEEK 23638*256+5
 4001 REM COPY COPY USR USR USR USR COPY COPY DRAW RETURN RETURN DRAW NOT READ NEXT FLASH CAT <=NOT NOT <fNOT NOT COPY COPY NOT DRAW RETURN NOT RETURN DRAW TO AND NOT \ 'NOT f<BB FREE BBB>>BB<---------------
 4002 LET msb=INT (udg/256): LET lsb=udg-msb*256
 4003 POKE 23675,lsb: POKE 23676,msb
 4005 LET b$="\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.                              \'.\'.       \a\b                     \'.\'.       \a\b \c \d \e \f \g 'ESE      \'.\'.                              \'.\'.              by              \'.\'.          T.G.Morley          \'.\'.           \* 4/4/84           \'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'.\'."
 4006 PRINT b$
 4007 POKE 23675,88: POKE 23676,255
 4050 PAUSE 200: CLS : GO TO 1065
 4100 CLS : SAVE "bin"CODE 65367,168
 4115 CLS : GO TO 4000
 4120 CLS : PRINT AT 8,8;"let tape run"
 4121 PAUSE 50
 4130 LOAD "bin"CODE 65367,168
 4140 GO TO 1
    2 ON ERR GO TO 9998
    5 CLS : PRINT TAB 8;"****hexdechex****"''"press enter for hex/dec switch"'"enter m for menu"
   10 LET a$="0123456789abcdef": PRINT TAB 6;"DEC"
   11 PAUSE 0: LET q=PEEK 23560: PRINT #1;AT 0,0;"      ": IF q=13 THEN GO TO 20
   12 IF q=109 THEN GO TO 9998
   15 IF q<48 OR q>57 THEN GO TO 11
   18 LET b$=b$+CHR$ q: PRINT #1;AT 0,0;b$;: GO TO 11
   20 IF B$="" THEN GO TO 1120
   25 IF B$="m" THEN GO TO 9998
   27 LET a=VAL b$
   28 IF a>65535 THEN LET b$="": GO TO 11
   30 IF A<10 THEN PRINT A;TAB 6;"dec = hex ";A: LET b$="": GO TO 11
   40 LET h$=""
   50 IF A=0 THEN PRINT B$;TAB 6;"dec = hex ";H$: LET b$="": GO TO 11
   60 LET M=INT (A/16): LET L=A-16*M: LET H$=A$(L+1)+H$: LET A=M: GO TO 50
 1130 PRINT TAB 6;"HEX"
 1140 INPUT "";a$
 1145 IF a$="" THEN GO TO 10
 1150 IF LEN a$>4 THEN LET a$="": GO TO 1140
 1160 IF LEN a$=3 THEN LET b$="0": LET a$=b$+a$
 1170 IF LEN a$=2 THEN LET c$="00": LET a$=c$+a$
 1180 IF LEN a$=1 THEN LET d$="000": LET a$=d$+a$
 1181 FOR t=1 TO 4
 1182 IF CODE a$(t)>102 OR CODE a$(t)<48 THEN GO TO 1140
 1183 IF CODE a$(t)>57 AND CODE a$(t)<97 THEN GO TO 1140
 1184 NEXT t
 1200 LET h=CODE a$(1)
 1210 LET x=h: GO SUB 1350
 1220 LET h=x
 1230 LET e=CODE a$(2)
 1240 LET x=e: GO SUB 1350
 1250 LET e=x
 1260 LET s=CODE a$(3)
 1270 LET x=s: GO SUB 1350
 1280 LET s=x
 1290 LET d=CODE a$(4)
 1300 LET x=d: GO SUB 1350
 1310 LET d=x
 1311 FOR t=1 TO 4:
 1320 LET dec=h*4096+e*256+s*16+d: PRINT a$;TAB 6;"hex = dec ";dec
 1340 GO TO 1140
 1350 IF x>96 AND x<103 THEN LET x=x-87: RETURN 
 1410 IF x>47 AND x<58 THEN LET x=x-48: RETURN 
    7 GO SUB 97
    8 LET dec=0: LET input=95: LET z$="": LET hex=510: LET hexx=1010: LET corect=100: LET d10=601: LET dentr=600: LET hentr=97
   10 PRINT AT 2,8;"enter start loc ";
   11 GO SUB input: PRINT k$;: LET z$=z$+k$: IF CODE k$<48 OR CODE k$>57 THEN GO TO 1
   12 IF LEN z$<5 THEN GO TO 11
   14 LET loc=VAL z$: LET sloc=loc: LET lin=7: LET col=0
   15 PRINT AT 7,5;"enter","1 hex"'',"2 dec": GO SUB input: IF CODE k$<49 OR CODE k$>50 THEN GO TO 15
   16 LET hld=VAL k$: GO SUB 97
   18 IF hld=2 THEN  PRINT AT 5,5;"enter dec": GO TO 30
   26 REM GO SUB hentr
   28 PRINT AT 5,5;"enter hex ?"
   30 LET z$="": LET k$=""
   35 GO SUB input
   36 IF CODE k$=8 THEN GO SUB 100: PRINT AT lin,col;"   ": BEEP .05,10: GO TO 30
   37 IF CODE k$=13 AND z$="" THEN GO TO 30
   38 IF CODE k$=9 THEN GO SUB 2000: GO TO 18
   39 IF CODE k$=13 THEN GO TO 80
   40 IF CODE k$>47 AND CODE k$<58 OR CODE k$>96 AND CODE k$<103 THEN GO TO 45
   43 GO TO 30
   45 IF hld=2 THEN GO SUB 601: IF LEN z$<3 THEN GO TO 35
   47 IF dec>255 THEN GO TO 30
   48 IF hld=2 THEN GO TO 80
   49 LET z$=z$+k$: IF LEN z$<2 THEN GO TO 35
   51 GO SUB 400
   80 BEEP .05,10
   81 PRINT AT lin,col;z$
   82 LET col=col+4
   84 IF col=32 THEN LET lin=lin+1: LET col=0
   86 IF lin=21 THEN PRINT "check code----press a key      ": BEEP 3,10: PAUSE 0: LET lin=7: LET col=0: CLS : GO TO 26
   90 POKE loc,dec: LET loc=loc+1
   91 LET t$="  start       end        bytes"
   92 PRINT AT 2,0;t$'"  ";sloc;TAB 13;loc;TAB 25;loc-sloc;"    "
   93 GO TO 30
   95 PAUSE 0: LET k$=CHR$ PEEK 23560: RETURN 
   98 CLS : PRINT TAB 5;"**** hexdecenter ****": PRINT AT 20,0;"correction ??? press left arrow"'"hexdec switch  press right arrow": RETURN 
  100 LET col=col-4
  102 IF col=-4 THEN LET col=28: LET lin=lin-1
  105 IF lin<7 THEN LET lin=7: LET col=0: POKE loc,0: RETURN 
  106 POKE loc,0: LET loc=loc-1
  120 RETURN 
  510 LET h=CODE z$(1): LET t=h: GO SUB 1000: LET h=t
  520 LET e=CODE z$(2): LET t=e: GO SUB 1000: LET e=t
  551 LET dec=h*16+e: RETURN 
  601 LET z$=z$+k$: LET dec=VAL z$: RETURN 
 1010 FOR c=97 TO 102
 1020 IF t=c THEN LET t=c-87: RETURN 
 1030 NEXT c
 1040 FOR c=48 TO 57
 1050 IF t=c THEN LET t=t-48: RETURN 
 1055 NEXT c
 1060 CLS : FOR t=60000 TO 64000: PRINT t,PEEK t: NEXT t
 2000 IF hld=2 THEN LET hld=1: RETURN 
 2001 IF hld=1 THEN LET hld=2: RETURN 
    1 ON ERR GO TO 9998: CLS 
   10 PRINT "INSTRUCTIONS"''"1..to load or enter code select"'"   merge on the menu.most of"'"   your work is done from merge."
   20 PRINT '"2..while you are in merge you"'"   may work on the program as if"'"   it were the only one in the"'"   machine."
   30 PRINT '"3..after the merge is completed"'"   you can call up other"'"   utilites and still bring up"'"   the last program on the menu"'"   to work on"
   40 PRINT '"4..to delete a program or group"'"   of programs call up the"'"   lowest then (DELETE ,9996"'"   ENTER) and (GOTO 9998 ENTER)."
   50 PRINT '"5..to change the last menu entry"'"   (GOTO 9999 ENTER) and enter a"'"   name as long or longer"
   60 PRINT '"6..(SHIFT BREAK) will goto menu,"'"   holding (SHIFT BREAK) will"'"   break to basic"
   70 PRINT '"7,,the rest is up to your"'"   imagination --- enjoy"
   80 PRINT '"8..C.A.T.S members only may use"'"   this copy of MTOS without"'"   copyright infringment"
   81 PRINT '''''''
 1000 PAUSE 0: STOP 
 9997 GO TO 1
 9998 FOR t=1 TO 50: NEXT t: ON ERR RESET : PAUSE 1: ON ERR GO TO 9998: RANDOMIZE USR 26715: GO TO  4
 9999 RANDOMIZE USR 26715: GO SUB 5: GO SUB 50: GO TO  4

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

Scroll to Top