Multisort

Developer(s): Bob Malloy
Date: 198x
Type: Program
Platform(s): TS 2068

This program is a bubble sort routine designed to be merged into a larger “Multi Tape” catalog program, sorting tape program names and associated data alphabetically. It operates on three pre-existing arrays: the string array `t$` (program titles), the string array `n$` (program names), and the two-dimensional numeric array `c` (holding up to four numeric values per entry), with `n` representing the total item count. The sort compares entries from character position 18 onward in `t$`, allowing a fixed-width prefix to be ignored during comparison. A temporary 1×4 numeric array `d` is used as scratch space to swap rows of `c`, since ZX Spectrum BASIC does not support direct row assignment for 2D numeric arrays. Upon completion, execution jumps to line 5, which is the main menu of the “Multi Tape” parent program, and a tone is sounded to signal completion (referenced in the accompanying remarks).


Program Analysis

Program Structure

The routine spans lines 600–860 and is self-contained enough to be merged into a host program via the MERGE command. Line 600 is a title REM, and line 601 is an extended documentation REM explaining context, usage, and a notable performance caveat. The actual executable code runs from line 610 to line 860, ending with GO TO 5 to return control to the host program’s main menu.

Sorting Algorithm

The algorithm is a classic bubble sort (also known as a sinking sort). The outer loop variable m runs from 1 to x-1 (where x = n-1), and the inner loop variable l runs from 1 to x-m. Adjacent entries are compared at line 650; if already in order, execution skips to NEXT l at line 840. Otherwise, the swap block (lines 660–830) exchanges all three parallel data structures.

The comparison at line 650 uses a string slice — t$(l+1,18 TO ) vs t$(l,18 TO ) — meaning only the portion of each title string from character 18 onward is used for ordering. This implies the host program stores a fixed-width 17-character prefix (such as a tape or counter number) before the sortable program name.

Data Structures

The routine assumes three arrays already exist in the host program:

  • t$ — a 2D string array of program title strings; each row is one entry.
  • n$ — a 2D string array of program name strings, parallel to t$.
  • c — a 2D numeric array with at least n-1 rows and 4 columns, holding numeric metadata per entry.
  • n — a numeric variable holding the count of entries plus one (so x = n-1 is the actual count).

Temporary Array Workaround

Because BASIC does not allow direct row-to-row copying of a 2D numeric array in a single statement, the routine allocates a scratch array d(1,4) at line 620. This single-row, four-column array acts as a temporary register for swapping one row of c with another — a common idiom when dealing with parallel numeric arrays. The four elements are copied individually across lines 680–710 (into d), lines 740–770 (overwriting the source row), and lines 800–830 (writing d into the destination row).

Performance Characteristics

The author openly warns in the REM at line 601 that the sort can take “up to several hours.” This is expected for an interpreted BASIC bubble sort over a large dataset: worst-case complexity is O(n²) comparisons, each involving string slice operations and, for swaps, twelve individual array assignments. For a modest catalog of even a few dozen entries, this would be noticeably slow in interpreted BASIC.

Notable Techniques and Idioms

  • The IF ... THEN GO TO 840 pattern at line 650 is a standard BASIC short-circuit to skip the swap block, equivalent to a structured IF ... ELSE.
  • GO TO 5 at line 860 transfers control to the host program’s main menu — a non-local exit idiom common in merged BASIC modules.
  • The DIM d(1,4) at line 620 is re-executed on every call to the sort routine, which resets the scratch array. This is harmless but slightly wasteful.
  • The note to delete line 601 reflects the real memory pressure of large REM statements in interpreted BASIC, where each character of a REM consumes RAM.

Bugs and Anomalies

Line 860 jumps to GO TO 5, but no tone-sounding statement appears in the listed code, despite the REM at line 601 explicitly promising “It will sound a tone when it is done.” The tone is presumably generated elsewhere in the host “Multi Tape” program at or near line 5, or was omitted from this module.

The outer loop initializes x = n-1 and then iterates m from 1 to x-1, meaning a catalog with only one entry (n=2, x=1) would result in a FOR m=1 TO 0 loop that executes zero times — correct behavior, though an edge case.

Content

Appears On

The biggest LIST tape yet — play poker accompanied by chip-tune renditions of classic songs, diagnose illnesses with a Bayesian expert system, master Z80 opcodes with a quiz, or unscramble anagrams before the cauldron boils over. Four custom fonts included.

Related Products

Related Articles

Related Content

Image Gallery

Source Code

  600 REM "multi sort" A SORTing  routine  for "multi tape" by R W Malloy
  601 REM The following routine   was suggested by "ALPHASORT" BY R. CLOUGH which was on LIST Library tape 5. It will sort program names, without the need to enter them manualy, after you have used "multi tape"(see tape 5) to list the programs on a tape (or tapes). To load it simply MERGE it into "multi tape". To use it you can stop "multi tape" and enter GOTO 600. Or, if you are ambitious, you can insert it into the menu. It takes a very long time to work (up to several hours). It will sound a tone when it is done. NOTE!! Delete this line (601) to give the program more rooom.  
  610 LET x=n-1
  620 DIM d(1,4)
  630 FOR m=1 TO x-1
  640 FOR l=1 TO x-m
  650 IF t$(l+1,18 TO )>t$(l,18 TO ) THEN GO TO 840
  660 LET u$=t$(l+1)
  670 LET o$=n$(l+1)
  680 LET d(1,1)=c(l+1,1)
  690 LET d(1,2)=c(l+1,2)
  700 LET d(1,3)=c(l+1,3)
  710 LET d(1,4)=c(l+1,4)
  720 LET t$(l+1)=t$(l)
  730 LET n$(l+1)=n$(l)
  740 LET c(l+1,1)=c(l,1)
  750 LET c(l+1,2)=c(l,2)
  760 LET c(l+1,3)=c(l,3)
  770 LET c(l+1,4)=c(l,4)
  780 LET t$(l)=u$
  790 LET n$(l)=o$
  800 LET c(l,1)=d(1,1)
  810 LET c(l,2)=d(1,2)
  820 LET c(l,3)=d(1,3)
  830 LET c(l,4)=d(1,4)
  840 NEXT l
  850 NEXT m
  860 GO TO 5

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

Scroll to Top