Loader V is a companion loader and dialing utility designed for use with the MTERM II terminal program. It provides a main menu offering three functions: launching MTERM, accessing a dialing menu of up to 20 stored phone numbers, and loading a text buffer from tape with configurable carriage-return handling. The auto-dialing routine directly controls modem hardware via OUT and IN instructions on port 119, generating DTMF-like pulses, monitoring for a carrier detect signal (IN value 133), and auto-repeating the dial sequence with an incrementing try counter. Phone numbers stored in DATA statements pair a label string with a number string beginning with “P” or “O” to encode pulse/tone dialing modes, with the POKE at address 24007+2 switching the dialing mode accordingly.
Program Analysis
Program Structure
The program is organized around a three-option main menu dispatched with a computed GO TO. Line 1 initializes variables, sets up the display, and prints the menu. Line 2 dispatches to line 20, 40, or 60 by multiplying the user’s choice by f (20). Line 3 is the shared input subroutine, called via GO SUB PI (PI truncates to 3, so this targets line 3). Lines 20–50 handle dialing, lines 60–61 handle buffer loading, and lines 100–119 hold the 20 DATA entries. Lines 9000–9500 are a save/bootstrap block.
Variable Initialization Idioms
All numeric constants are defined at startup using math expressions to avoid storing numeric literals directly in variables where possible:
o = SIN PI→ 0i = SGN PI→ 1b = i+i→ 2f = VAL "20"→ 20m = VAL "119"→ 119 (modem port)p = VAL "24007"→ 24007 (MTERM parameter address)n$→ title/banner string
GO SUB PI and GO TO PI*PI are used as compact ways to reference lines 3 and 9 respectively, exploiting the fact that BASIC truncates floating-point line targets. Similarly, GO SUB PI always calls the shared input routine at line 3.
Menu Dispatch
Line 2 uses GO TO VAL z$*f to jump to lines 20, 40, or 60 based on whether the user entered “1”, “2”, or “3”. The multiplication by f (20) maps choices to the correct line numbers. Input validation on line 1 uses RUN to restart if the choice is out of range.
Dialing Menu (Lines 40–50)
Line 40 reads all 20 DATA entries (labels “a”–”t”), printing them in a columned list. BRIGHT x-INT(x/b)*b alternates bright attribute on alternate entries for visual separation. After the user selects a letter, line 42 uses a RESTORE/FOR loop to skip through DATA pairs to retrieve the correct phone-number string into y$.
Line 43 contains the pulse/tone mode selection logic:
- If the number string starts with “E” (tone), a non-zero offset is added to
CODE "O"+CODE ","and POKEd top+b(address 24009). - If the number string starts with “O”, the length of the string is used instead.
- This encodes a dialing mode byte into MTERM’s parameter table.
Lines 44–45 strip non-digit characters from the number string into z$ for actual dialing. Line 46 displays a flashing “Dialing” status with the current try number t.
Hardware Modem Control
The dialing pulse loop (lines 47–48) operates directly on port 119 (m):
OUT m, VAL "31"asserts the modem off-hook line.- For each digit, a loop runs
ztimes (digit value; 0 is substituted asf/b= 10 for pulse dialing). - Inner loop outputs values 3 and 4 (
INT PIto 4) and then 1 and 2 to create the pulse waveform.
Line 49 polls IN m up to 1000 times looking for value 133 (carrier detect). On success it POKEs p+i (24008) with 1 to signal MTERM, beeps, and jumps to line 20 (which executes RESET and calls the USR routine to hand off to MTERM). On timeout, line 50 increments the try counter t and loops back to redial.
Buffer Load Routine (Lines 60–61)
Line 60 prompts for a filename and carriage-return mode (1=none, 2=each line, 3=each paragraph). Line 61 calls RANDOMIZE USR VAL "23780" before the LOAD — address 23780 is the standard TS2068/Spectrum ROM entry point for tape operations, used here to reset the tape system. It then performs LOAD n$ CODE VAL "29064" to load a code block to address 29064 (just above MTERM’s CLEAR address of 29063). The carriage-return mode digit from z$ is POKEd to address 24007 (p) for MTERM to read.
Save/Bootstrap Block (Lines 9000–9001)
Line 9000 saves the BASIC program itself with autostart at line 9001, then saves a 244-byte machine code block from address 23780, and a 7721-byte MTERM machine code block from address 54016. Line 9001 is the autostart entry: it loads both code blocks back, then DELETEs lines 9000–9499 to clean up before RUN at line 9500 restarts the main program.
Line 20 — MTERM Handoff
Line 20 executes ON ERR RESET followed by PRINT USR VAL "23817". Address 23817 is within the machine code block saved at 23780, acting as the entry point to transfer control to MTERM. The ON ERR RESET sets up error recovery before the USR call.
Notable Anomalies
- The DATA entries all contain placeholder values (
"Up to 17 letters!"and"P12345678901"), indicating this is a template listing meant to be customized by the user with real names and phone numbers. DIM y$(VAL "12")allocates a 12-character string, but phone number strings of length up to 17 are referenced — this may cause issues if the number string used from DATA exceeds the DIM size, though the DATA strings are read directly intoy$via READ which overrides the DIM.GO TO fon line 49 jumps to line 20, the MTERM handoff, on successful carrier detect — a compact use of the pre-initialized variable.
Content
Image Gallery
Source Code
1 ON ERR GO TO SGN PI: CLEAR VAL "29063": LET p=VAL "24007": LET f=VAL "20": LET m=VAL "119": DIM y$(VAL "12"): LET o=SIN PI: LET i=SGN PI: LET b=i+i: LET n$=" Loader V - \*1985 by K.A.Casby ": BORDER i: PAPER i: INK VAL "7": OUT m,o: CLS : PRINT n$''''''TAB PI*PI;"MAIN MENU:"'''TAB PI+PI;"1) RUN MTERM"''TAB PI+PI;"2) DIALING MENU"''TAB PI+PI;"3) LOAD BUFFER": GO SUB PI: IF LEN z$<>i OR z$<"1" OR z$>"3" THEN RUN
2 GO TO VAL z$*f
3 INPUT "Your Choice? "; LINE z$: RETURN
20 ON ERR RESET : PRINT USR VAL "23817"
40 LET t=i: CLS : RESTORE : PRINT n$: FOR x=CODE "a" TO CODE "t": READ z$,y$: PRINT CHR$ x;") ";z$;: LET y$(i)="-": PRINT TAB f;y$: BRIGHT x-INT (x/b)*b: NEXT x: PRINT "u) Dial a # not listed": GO SUB PI: IF z$<"a" OR z$>"u" THEN RUN
41 IF z$="u" THEN INPUT "Phone #? "; LINE y$: GO TO VAL "43"
42 RESTORE : FOR x=i TO b+b*(CODE z$-CODE "a"): READ y$: NEXT x
43 POKE p+b,CODE "O"+CODE ","*(CODE y$=CODE "E")+LEN y$*(CODE y$=CODE "O")
44 LET z$="": FOR x=i TO LEN y$: IF y$(x)>="0" AND y$(x)<="9" THEN LET z$=z$+y$(x)
45 OUT m,o: NEXT x: IF z$="" THEN RUN
46 BEEP VAL ".1",f: PRINT #o,;AT o,o; FLASH i;" Dialing - ";AT o,VAL "11"; OVER i;z$;" - Try#";t
47 OUT m,VAL "31": PAUSE VAL "60": FOR x=i TO LEN z$: LET z=VAL z$(x): IF z=o THEN LET z=f/b
48 PAUSE VAL "25": FOR d=i TO z: FOR e=INT PI TO VAL "4": OUT m,e: NEXT e: OUT m,i: OUT m,b: NEXT d: NEXT x
49 FOR x=i TO VAL "1e3": IF IN m=VAL "133" THEN OUT m,VAL "34": POKE p+i,i: BEEP i,f: GO TO f
50 NEXT x: OUT m,o: PAUSE VAL "99": LET t=t+i: GO TO VAL "46"
60 CLS : PRINT n$'''"Name of File: ";: INPUT "Filename? "; LINE n$: PRINT n$'''"Carriage returns:"''"1) None"'"2) Each line"'"3) Each paragraph": GO SUB PI: IF LEN z$<>i OR z$<"1" OR z$>"3" THEN RUN
61 PRINT AT PI+PI,VAL "18";z$'''''''"Insert tape containing:"''"'";n$;"' & press play!": RANDOMIZE USR VAL "23780": LOAD n$CODE VAL "29064": POKE p,VAL z$: PRINT : PRINT FLASH i;" LOAD complete, press any key! ": PAUSE o: RUN
100 DATA "Up to 17 letters!","P12345678901"
101 DATA "Up to 17 letters!","P12345678901"
102 DATA "Up to 17 letters!","P12345678901"
103 DATA "Up to 17 letters!","P12345678901"
104 DATA "Up to 17 letters!","P12345678901"
105 DATA "Up to 17 letters!","P12345678901"
106 DATA "Up to 17 letters!","P12345678901"
107 DATA "Up to 17 letters!","P12345678901"
108 DATA "Up to 17 letters!","P12345678901"
109 DATA "Up to 17 letters!","P12345678901"
110 DATA "Up to 17 letters!","P12345678901"
111 DATA "Up to 17 letters!","P12345678901"
112 DATA "Up to 17 letters!","P12345678901"
113 DATA "Up to 17 letters!","P12345678901"
114 DATA "Up to 17 letters!","P12345678901"
115 DATA "Up to 17 letters!","P12345678901"
116 DATA "Up to 17 letters!","P12345678901"
117 DATA "Up to 17 letters!","P12345678901"
118 DATA "Up to 17 letters!","P12345678901"
119 DATA "Up to 17 letters!","P12345678901"
9000 SAVE "Loader V" LINE VAL "9001": SAVE "Loader V"CODE VAL "23780",VAL "244": SAVE "Mterm"CODE VAL "54016",VAL "7721": STOP
9001 LOAD ""CODE : LOAD ""CODE : DELETE 9000,9499
9500 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.