MCLOADER

This file is part of CATS Library Tape 3, and Long Island Sinclair Timex (LIST) User Group Library Tape #2.2. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 2068

MCLOADER is a machine code entry utility that accepts decimal byte values one at a time and POKEs them into memory starting at a user-specified or automatically calculated address near RAMTOP. The program uses a string array `B$` to buffer entered bytes so they can be reviewed in groups of eight after entry. A running checksum is accumulated and displayed after all bytes are entered, providing a basic integrity check. The tool reads RAMTOP from system variables at addresses 23730–23731 and, if necessary, lowers it via CLEAR to make room for the incoming code. After entry, it prints the exact SAVE…CODE command needed to preserve the loaded machine code to tape.


Program Analysis

Program Structure

The program is organized into a main entry flow and several distinct subroutine-like blocks accessed via GO TO:

  • Lines 10–45: Setup — prompts for byte count, dimensions the buffer array, and checks/adjusts RAMTOP.
  • Lines 50–80: Determines start address — either user-supplied or auto-calculated as 65368-N.
  • Lines 85–174: Main entry loop — POKEs each byte, accumulates checksum, then branches to review or list mode.
  • Lines 1000–1010: Standalone RAMTOP display utility (not called from the main flow; appears to be a debugging aid reachable only by direct RUN 1000).
  • Lines 2000–2030: List mode — prints a user-specified number of bytes from the top of memory.
  • Lines 3000–3030: Review mode — dumps all buffered byte strings from B$.
  • Line 5000: Common exit — prints the SAVE command with the correct address and length.

Memory Layout and RAMTOP Handling

The program reads RAMTOP from the system variables at addresses 23730 (low byte) and 23731 (high byte), combining them as PEEK 23730 + 256*PEEK 23731. It computes available space above the current program/variable area as 65367 - PEEK 23730 - 256*PEEK 23731 and compares it to N. If there is insufficient room, it prints a warning and instructs the user to hit ENTER, then uses CLEAR 65367-N to lower RAMTOP before halting with STOP. The user must then RUN again to proceed with the newly lowered RAMTOP — a two-pass bootstrapping approach necessitated by the fact that CLEAR and subsequent re-entry cannot easily be automated without a self-modifying loop.

The default start address S = 65368 - N places the code block immediately above RAMTOP at the conventional top-of-RAM location. Note that RAMTOP itself is the byte at address PEEK 23730 + 256*PEEK 23731, so +1 in the final SAVE line correctly gives the first byte above it.

Input Buffering with DIM B$

DIM B$(N,4) at line 42 allocates a two-dimensional string array: N rows of 4 characters each. Each entered decimal string (up to “255”) is stored in B$(I) after being POKEd. This allows the review section (lines 3000–3020) to reprint all entered values without re-reading memory. However, storing the decimal strings rather than the byte values means the review output shows the original typed text, not a formatted hex or decimal column dump.

Key BASIC Idioms and Techniques

  • Checksum accumulation: SUM at line 85 is initialized to zero and incremented by VAL C$ at line 140, yielding a simple additive checksum over all entered bytes. No modular reduction is applied, so SUM can grow large for many bytes.
  • Address display during entry: Line 100 uses PRINT INK 3; S+I-1; to display the current target address in a distinct color before the INPUT on the next line, giving visual context without disturbing the input prompt layout.
  • TAB formatting: Line 120 uses TAB (10-LEN C$) to right-align the entered value — a neat trick to create a consistent column width for 1-, 2-, or 3-digit decimal numbers.
  • PAUSE 4E4: Line 45 uses scientific notation (4E4 = 40000) for the pause duration — a common space-saving idiom. At line 172, PAUSE 0 is not used; instead, an INPUT drives the pause.

Notable Anomalies and Bugs

LocationIssue
Line 42DIM B$(N,4) is executed before the RAMTOP check at line 45. If N is large, the array itself may consume significant RAM before the check can fire, potentially causing an out-of-memory error prior to the guard condition.
Lines 2000–2020The list mode asks “HOW MANY BYTES?” and iterates FOR J=B TO 1 STEP -1, printing 65368-J and its PEEK. This always reads from 65368-B to 65367, ignoring the user’s chosen start address S. If the user chose a non-default start address, the listing may not correspond to the entered code.
Line 115LET B$(I)=C$ stores the raw input. Because B$ columns are 4 wide and BASIC pads with spaces, review output at line 3010 will include trailing spaces between values, making the group display harder to read.
Lines 1000–1010This block is unreachable from the normal program flow — no GO TO 1000 exists. It appears to be a utility snippet left in for manual invocation.
Line 2030 / 3030Each review/list block ends with a GO TO 5000 then an unreachable STOP. The STOP statements are dead code but harmless.

Save Command Generation

Line 5000 prints the exact tape-save command the user needs to type: SAVE "XXX" CODE address, N, substituting the computed start address (PEEK 23730 + 256*PEEK 23731 + 1) and byte count (N). The +1 correctly adjusts from the RAMTOP pointer (which points to the last byte of the BASIC area) to the first byte of the machine code block. This self-documenting approach removes the burden of remembering addresses after a potentially lengthy entry session.

Content

Appears On

Capital Area Timex Sinclair User Group’s Library Tape.

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   10 REM ***********************
   20 REM MCLOADER
   30 REM ***********************
   40 INPUT "HOW MANY BYTES OF MC?";N
   42 DIM B$(N,4)
   45 IF 65367-PEEK 23730-256*PEEK 23731<N THEN PRINT "RAMTOP BEING LOWERED TO ";65367-N: PRINT "HIT ENTER THEN ""RUN"" TO CONTINUE": PAUSE 4E4: CLEAR 65367-N: STOP 
   50 INPUT "ANY SPECIFIC STARTING ADDRESS? (Y/N)";A$
   60 IF A$="Y" THEN INPUT "ENTER STARTING ADDRESS ";S: GO TO 80
   70 LET S=65368-N
   80 PRINT "INPUT CODE (DEC) FOR EA ADDR"
   85 LET SUM=0
   90 FOR I=1 TO N
  100 PRINT INK 3;S+I-1;
  110 INPUT C$
  115 LET B$(I)=C$
  120 PRINT TAB (10-LEN C$);C$
  130 POKE (S+I-1),VAL C$
  140 LET SUM=SUM+VAL C$
  150 NEXT I
  160 PRINT 
  170 PRINT "CHECKSUM= ";SUM
  172 INPUT "REVIEW CODE IN GROUPS OF 8? (Y/N)";Z$: IF Z$="Y" THEN GO TO 3000
  174 GO TO 2000
  200 STOP 
 1000 PRINT "RAMTOP IS AT ";PEEK 23730+256*PEEK 23731
 1010 STOP 
 2000 INPUT "LIST HOW MANY BYTES?";B
 2002 CLS 
 2005 FOR J=B TO 1 STEP -1
 2010 PRINT 65368-J,PEEK (65368-J)
 2020 NEXT J
 2025 GO TO 5000
 2030 STOP 
 2035 REM 
 3000 CLS 
 3005 FOR J=1 TO N
 3010 PRINT B$(J);
 3020 NEXT J
 3025 GO TO 5000
 3030 STOP 
 5000 PRINT AT 20,0;"TO SAVE CODE"'"TYPE: SAVE""XXX""CODE ";PEEK 23730+256*PEEK 23731+1;",";N

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

People

No people associated with this content.

Scroll to Top