DISA-Z Disassembler

Developer(s): Ray Kingsley
Date: 1983
Type: Program
Platform(s): TS 1000

DISA-Z is a Z80 disassembler written in BASIC that reads machine code from memory and prints human-readable mnemonics to a printer. It supports the full Z80 instruction set including all prefix bytes: CB (bit operations), DD (IX-indexed), FD (IY-indexed), and ED (extended instructions), as well as relative jump target resolution. A configuration flag at line 190 (`TS2=0` or `TS2=1`) switches hex digit output between the ZX81/TS1000 and TS2068 character sets, since the two platforms place A–F at different character code offsets. The program uses octal decomposition of opcodes (breaking each byte into two 3-bit fields and one further subdivision) to classify and decode instructions, a technique that mirrors the Z80’s own internal opcode structure. Output is sent via LPRINT and includes the address, raw hex bytes, and mnemonic for each instruction.


Program Analysis

Program Structure

The program is organised as a collection of subroutines branched to from a main loop starting at line 3500. After an INPUT J to set the start address, the loop at lines 3520–3700 repeatedly disassembles one instruction, prints it, and advances. The top-level flow per instruction is:

  1. Clear state variables (DD, FD, CB) and the hex string H$ (lines 3520–3580).
  2. Format the address via GOSUB 350 (address hexer).
  3. Determine instruction length via GOSUB 420 (lines 430–960).
  4. Peek and hex-format each byte of the instruction (lines 3630–3660).
  5. Generate the mnemonic string via GOSUB 970 (lines 970–3410).
  6. Send the completed line to the printer with LPRINT H$.

Platform Switch

Line 190 sets TS2=0 for ZX81/TS1000 or TS2=1 for TS2068. The constant NCOD (line 200) evaluates to either 28 (ZX81, where digit characters start at code 28) or 48 (TS2068, standard ASCII). The hex formatter at line 330 uses NCOD+Y+7*(Y>9)*TS2 to select the correct character code for A–F, compensating for the gap between digit and letter character codes on each platform.

Opcode Decoding via Octal Decomposition

The subroutine at line 230 decomposes an opcode byte into octal fields. It finds K (the top 2 bits, 0–3), then extracts C (bits 5–3, the middle octet) and T (bits 2–0, the low triad). This directly mirrors the Z80 designers’ own encoding scheme, where the three octal digits of an opcode determine its instruction group, register operand, and operation type respectively.

Instruction Length Calculation

Before disassembling mnemonics, the program must know how many bytes the instruction occupies so it can fetch operand bytes. The subroutine at line 420 handles prefix chaining: DD (0xDD) and FD (0xFD) prefixes call a helper (line 480) that peeks the next byte without permanently advancing the pointer, and recursively re-evaluates. The length is built up in variable L, with separate paths for:

  • CB-prefixed bit instructions (line 550 → line 940)
  • ED-prefixed extended instructions (lines 560–700)
  • Unprefixed main-table instructions (lines 710–910)

The helper at line 920 handles two-byte operands (adding 2 to L) and line 940 adds 1 for single-byte operands; line 950 always adds 1 for the opcode itself.

Hex Formatting

The byte hexer (lines 300–340) peeks address J and appends two hex characters to H$. The address hexer (lines 360–410) calls the byte hexer twice for high and low bytes of a 16-bit address and appends a space. Operand bytes embedded in H$ at fixed character positions are later extracted by substring references such as H$(8 TO 9) (low byte) and H$(10 TO 11) (high byte), allowing the mnemonic builders to reuse already-formatted hex data without re-peeking memory.

Mnemonic Generation

The mnemonic subroutine (line 970) pads H$ to at least 14 characters, then dispatches by opcode group. Lookup tables stored as compact strings are used throughout:

VariableContentsUsage
O$ADDADCSUBSBCANDXOROR CP ALU operation names (3 chars each)
D$BCDEHLSPAFIXIY16-bit register pair names (2 chars each)
R$BCDEHLXA8-bit register names (1 char each)
E$NZZ NCC POPEP M Condition code names (2 chars each)
F$RLCARRCARLA RRA DAA CPL SCF CCF Misc. first-group mnemonics (4 chars each)
B$BITRESSETCB-group bit instruction names (3 chars each)
C$RSLRC ALCB shift/rotate sub-field characters
G$LDCPINOTED block instruction base names (2 chars each)

Index Register Substitution

The subroutine at line 1170 checks the DD and FD flags. When neither is set, the “H” register slot (R$ position 6, labelled "X" internally) is replaced by (HL). When a prefix is active, the helper at line 1210 builds an (IX+d) or (IY+d) string by reading the displacement byte already formatted in H$(10 TO 11), neatly avoiding a second PEEK call.

Relative Jump Resolution

Lines 2180–2220 resolve JR and DJNZ target addresses. The displacement byte is read with PEEK (J-1) and sign-extended using the idiom (byte AND (byte<128)) + ((byte-256) AND (byte>127)), which converts an unsigned 0–255 value to a signed −128 to +127 integer without any bit-manipulation keywords. The absolute target address is then formatted as hex via the address hexer.

RST Instruction Formatting

Lines 1990–2010 compute the RST vector from octet field C: W=INT(C/2) gives the upper digit and 8*(C-2*W) the lower, producing values like RST 38 rather than the more conventional RST 38H. The result is decimal, not hex — a cosmetic anomaly compared to standard Z80 assembler notation.

ED-Prefix Block Instructions

Lines 2740–2840 handle the LDI, LDD, LDIR, LDDR, CPI, CPD, CPIR, CPDR, INI, IND, INIR, INDR, OUTI, OUTD, OTIR, and OTDR instructions by building suffixes: the I/D direction from the even/odd column, and the optional R repeat suffix from whether C>5.

Anomalies and Notes

  • Line 2510 has no handler for C=0 (opcode 0xC3 is caught earlier at line 830) or C=1 (handled by the T=1 path). The label at 2520 is missing from the listing — line 2520 does not appear, so there is a gap between 2510 and 2530 that skips no code but may confuse a reader.
  • Line 2100 outputs EX AF,AF" with a literal trailing double-quote character embedded in the string to represent the conventional AF' prime notation.
  • The OUT (C),0 undocumented ED instruction is not specifically handled; the C=7 column of the ED 0x70/0x78 row falls through silently.
  • The variable CB is set at line 3180 but never tested elsewhere in the listing — it appears to be a flag reserved for future use or a remnant from development.
  • The main loop at line 3700 uses GOTO 3520 (not 3510), so it does not re-prompt for an address; the disassembler runs continuously from the initial address without stopping.

Content

Appears On

One of the largest single-tape collections anywhere, with over 40 programs spanning flight planning, satellite tracking, hydrology, Forth programming, a 17-game mega-pack, and a complete calligraphic font renderer. A snapshot of a thriving Texas user group at its peak.
Assembled by Tim Ward from many sources. Contains programs 10051 – 10121.

Related Products

Related Articles

Disassembler for the TS2000, written and debugged on the 1000.

Related Content

Image Gallery

Source Code

  10 REM ***********************               DISA-Z         
  20 REM ***********************         A Z80 DISASSEMBLER              FOR TS COMPUTERS
  30 REM ***********************
  40 REM ***********************         COPYRIGHT, 1983                 RAY KINGSLEY
  50 REM ***********************         RUN AND ENTER START             ADDRESS IN DECIMAL
  60 REM ***********************
  70 REM ***********************
  90 REM DATA STRINGS
 100 LET O$="ADDADCSUBSBCANDXOROR CP "
 110 LET D$="BCDEHLSPAFIXIY"
 120 LET B$="BITRESSET"
 130 LET C$="RSLRC AL"
 140 LET R$="BCDEHLXA"
 150 LET E$="NZZ NCC POPEP M "
 160 LET F$="RLCARRCARLA RRA DAA CPL SCF CCF "
 170 LET G$="LDCPINOT"
 180 REM FOR TS2068 SET TS2=1
 190 LET TS2=0
 200 LET NCOD=28+20*TS2
 220 GOTO 3500
 230 REM OCTAL DIGITS
 240 FOR K=0 TO 3
 250 IF X0>=K*64 AND X0<(K+1)*64 THEN LET X=X0-K*64
 260 NEXT K
 270 LET C=INT (X/8)
 280 LET T=X-C*8
 290 RETURN 
 295 REM BYTE HEXER
 300 LET X=PEEK J
 310 LET Y=INT (X/16)
 320 LET Z=X-Y*16
 330 LET H$=H$+CHR$ (NCOD+Y+7*(Y>9)*TS2)+CHR$ (NCOD+Z+7*(Z>9)*TS2)
 340 RETURN 
 350 REM ADDRESS HEXER
 360 LET X=INT (J/256)
 370 GOSUB 310
 380 LET X=J-256*X
 390 GOSUB 310
 400 LET H$=H$+" "
 410 RETURN 
 420 REM GET INSTRUCTION LENGTH
 430 LET L=0
 440 IF X<>221 AND X<>253 THEN GOTO 540
 450 IF L THEN RETURN 
 460 GOSUB 480
 470 GOTO 440
 480 LET L=1
 490 LET J=J+1
 500 GOSUB 300
 510 LET J=J-1
 520 LET H$=H$( TO LEN H$-2)
 530 RETURN 
 535 REM I-LENGTH FOR PREFIXES
 540 IF L THEN LET L=L+((X>51) AND (X<55) OR X=203)
 550 IF X=203 THEN GOTO 940
 560 IF X<>237 THEN GOTO 710
 570 GOSUB 480
 580 IF X<64 OR X>188 THEN RETURN 
 590 IF X<160 AND X>123 THEN RETURN 
 600 IF X<124 THEN GOTO 630
 610 IF X-INT (X/8)*8<5 THEN GOTO 950
 620 RETURN 
 630 IF X=78 OR X=102 OR X=110 OR X=112 OR X=113 OR X=118 OR X=119 THEN RETURN 
 640 LET W=X-67
 650 IF NOT (W-INT (W/8)*8) THEN GOTO 920
 660 LET W=X-76
 670 IF W>=0 AND NOT (W-INT (W/8)*8) THEN RETURN 
 680 LET W=X-85
 690 IF W>=0 AND NOT (W-INT (W/8)*8) THEN RETURN 
 700 GOTO 950
 705 REM WITHOUT PREFIXES
 710 IF X<64 OR X>191 THEN GOTO 740
 720 IF L THEN LET L=L+(X-8*INT (X/8)=6)
 730 GOTO 950
 740 IF X>191 THEN GOTO 830
 750 IF Z=1 THEN GOTO 920
 760 LET W=X-34
 770 IF W>=0 AND NOT (W-INT (W/8)*8) THEN GOTO 920
 780 LET W=X-6
 790 IF W>=0 AND NOT (W-INT (W/8)*8) THEN GOTO 940
 800 LET W=X-16
 810 IF W>=0 AND NOT (W-INT (W/8)*8) THEN GOTO 940
 820 GOTO 950
 830 IF X=195 OR X=205 THEN GOTO 920
 840 IF X=211 OR X=219 THEN GOTO 940
 850 LET W=X-194
 860 IF NOT (W-INT (W/8)*8) THEN GOTO 920
 870 LET W=W-2
 880 IF NOT (W-INT (W/8)*8) THEN GOTO 920
 890 LET W=W-2
 900 IF NOT (W-INT (W/8)*8) THEN GOTO 940
 910 GOTO 950
 920 IF L=2 THEN GOTO 940
 930 LET L=L+1
 940 LET L=L+1
 950 LET L=L+1
 960 RETURN 
 970 REM MNEMONICS
 980 LET H$=H$+" "
 990 IF LEN H$<14 THEN GOTO 980
 1000 IF X0=118 THEN GOTO 1290
 1010 GOSUB 230
 1020 IF X0<64 OR X0>191 THEN GOTO 1400
 1030 IF X0>127 THEN GOTO 1310
 1035 REM EIGHT-BIT REG LDS.
 1040 LET P$=R$(C+1)
 1050 LET Q$=R$(T+1)
 1060 IF P$="X" OR Q$="X" THEN GOSUB 1170
 1070 LET H$=H$+"LD "+P$+","+Q$
 1080 RETURN 
 1085 REM ADD POINTER REGS TO H$
 1090 IF NOT DD THEN GOTO 1120
 1100 LET H$=H$+"IX"
 1110 RETURN 
 1120 IF NOT FD THEN GOTO 1150
 1130 LET H$=H$+"IY"
 1140 RETURN 
 1150 LET H$=H$+"HL"
 1160 RETURN 
 1165 REM CHECK FOR FD OR DD
 1170 IF FD OR DD THEN GOTO 1210
 1180 IF P$="X" THEN LET P$="(HL)"
 1190 IF Q$="X" THEN LET Q$="(HL)"
 1200 RETURN 
 1205 REM ADD INDEX REGS TO H$
 1210 IF FD THEN LET W$="(IY+"
 1220 IF DD THEN LET W$="(IX+"
 1230 IF P$="X" THEN LET P$=W$+H$(10 TO 11)+")"
 1240 IF Q$="X" THEN LET Q$=W$+H$(10 TO 11)+")"
 1250 RETURN 
 1260 GOSUB 1170
 1270 LET H$=H$+P$+","+R$(1+T)
 1280 RETURN 
 1290 LET H$=H$+"HLT"
 1300 RETURN 
 1310 REM ARITH/LOGIC OPS
 1320 LET I=C*3+1
 1330 LET Q$=R$(T+1)
 1340 GOSUB 1170
 1350 LET I$=" "
 1360 IF I<7 OR I=10 THEN LET I$=" A,"
 1370 IF I>18 THEN LET I$=""
 1380 LET H$=H$+O$(I TO I+2)+I$+Q$
 1390 RETURN 
 1395 REM 1ST AND 4TH GROUPS
 1400 IF X0=203 THEN GOTO 3170
 1410 IF X0=253 OR X0=221 THEN GOTO 3420
 1420 IF X0>191 THEN GOTO 1570
 1425 REM 1ST GROUP
 1430 IF T=1 THEN GOTO 2020
 1440 IF T=3 THEN GOTO 2240
 1450 IF T=4 OR T=5 THEN GOTO 2300
 1460 IF T=2 THEN GOTO 2370
 1470 IF NOT T THEN GOTO 2080
 1480 IF T<>6 THEN GOTO 1540
 1490 LET Q$=R$(C+1)
 1500 GOSUB 1170
 1510 LET W=4*(FD OR DD)
 1520 LET H$=H$+"LD "+Q$+","+H$(8+W TO 9+W)
 1530 RETURN 
 1540 LET W=4*C+1
 1550 LET H$=H$+F$(W TO W+3)
 1560 RETURN 
 1570 REM DIRECT ARITHMETIC
 1580 IF T<>6 THEN GOTO 1660
 1590 LET I=3*C+1
 1600 LET I$=" "
 1610 IF I<7 OR I=10 THEN LET I$=" A,"
 1620 IF I>18 THEN LET I$=""
 1630 LET H$=H$+O$(I TO I+2)+I$
 1640 LET H$=H$+H$(8 TO 9)
 1650 RETURN 
 1660 REM 4TH GROUP
 1670 IF X0=237 THEN GOTO 2700
 1680 IF T=1 AND NOT (C-INT (C/2)*2) THEN GOTO 1920
 1690 IF T=7 THEN GOTO 1990
 1700 IF T=5 AND NOT (C-INT (C/2)*2) THEN GOTO 1940
 1710 LET FL=0
 1720 IF X0=205 OR T=4 THEN GOSUB 1830
 1730 IF X0=195 OR T=2 THEN GOSUB 1800
 1740 IF X0=201 OR NOT T THEN GOSUB 1870
 1750 IF NOT T OR T=2 OR T=4 THEN GOSUB 1890
 1760 IF T=3 AND NOT FL THEN GOTO 2510
 1770 IF T=1 AND NOT FL THEN GOTO 2610
 1780 IF FL THEN GOSUB 1850
 1790 RETURN 
 1795 REM MAIN CONDITIONALS
 1800 LET H$=H$+"JP "
 1810 LET FL=1
 1820 RETURN 
 1830 LET H$=H$+"CALL "
 1840 GOTO 1810
 1850 LET H$=H$+H$(10 TO 11)+H$(8 TO 9)
 1860 RETURN 
 1870 LET H$=H$+"RET "
 1880 GOTO 1810
 1890 LET H$=H$+E$(2*C+1 TO 2*(C+1))
 1900 IF NOT (C=1 OR C=3 OR C>5) THEN LET H$=H$+" "
 1910 RETURN 
 1915 REM GROUP 4:C EVEN,T=1 OR 5
 1920 LET H$=H$+"POP "
 1930 GOTO 1950
 1940 LET H$=H$+"PUSH "
 1950 IF C=6 THEN LET C=8
 1960 IF C=4 THEN LET C=C+6*(FD OR DD)
 1970 LET H$=H$+D$(1+C TO 2+C)
 1980 RETURN 
 1985 REM GROUP 4:T=7
 1990 LET W=INT (C/2)
 2000 LET H$=H$+"RST "+STR$ (W)+STR$ (8*(C-2*W))
 2010 RETURN 
 2020 REM GROUP 1:T=1
 2030 IF C-2*INT (C/2) THEN GOTO 2060
 2040 LET H$=H$+"LD "+D$(C+1 TO C+2)+","
 2050 GOTO 1850
 2060 LET H$=H$+"ADD HL,"+D$(C TO C+1)
 2070 RETURN 
 2080 REM GROUP 1:T=0 (JRS)
 2090 IF C=0 THEN LET H$=H$+"NOP"
 2100 IF C=1 THEN LET H$=H$+"EX AF,AF"""
 2110 IF C=2 THEN LET H$=H$+"DJNZ"
 2120 IF C>1 THEN GOTO 2140
 2130 RETURN 
 2140 IF C>2 THEN LET H$=H$+"JR "
 2150 LET W=C*2-7
 2160 IF C>3 THEN LET H$=H$+E$(W TO W+1)
 2170 IF NOT (C-2*INT (C/2)) THEN LET H$=H$+" "
 2180 LET W=(PEEK (J-1) AND (PEEK (J-1)<128))+((PEEK (J-1)-256) AND (PEEK (J-1)>127))
 2190 LET J0=J
 2200 LET J=J+W
 2210 GOSUB 350
 2220 LET J=J0
 2230 RETURN 
 2240 REM GROUP 1:T=3
 2250 LET Q$="INC "
 2260 IF C-2*INT (C/2) THEN LET Q$="DEC "
 2270 LET W=2*INT (C/2)+1
 2280 LET H$=H$+Q$+D$(W TO W+1)
 2290 RETURN 
 2300 REM GROUP 1:T=4 OR 5
 2310 LET Q$=R$(C+1)
 2320 GOSUB 1170
 2330 LET P$="INC "
 2340 IF T-2*INT (T/2) THEN LET P$="DEC "
 2350 LET H$=H$+P$+Q$
 2360 RETURN 
 2370 REM GROUP 1:T=2
 2380 LET H$=H$+"LD "
 2390 IF NOT (C-2*INT (C/2)) THEN GOTO 2460
 2400 IF C=5 THEN GOSUB 1090
 2410 IF C=5 THEN GOTO 2430
 2420 LET H$=H$+"A"
 2430 IF C>3 THEN LET H$=H$+",("+H$(10 TO 11)+H$(8 TO 9)+")"
 2440 IF C<4 THEN LET H$=H$+",("+D$(C TO C+1)+")"
 2450 RETURN 
 2460 IF C<4 THEN LET H$=H$+"("+D$(C+1 TO C+2)+"),"
 2470 IF C>3 THEN LET H$=H$+"("+H$(10 TO 11)+H$(8 TO 9)+"),"
 2480 IF C=4 THEN GOTO 1090
 2490 LET H$=H$+"A"
 2500 RETURN 
 2510 REM GROUP 4:T=3
 2530 IF C=2 THEN LET H$=H$+"OUT "+H$(8 TO 9)+",A"
 2540 IF C=3 THEN LET H$=H$+"IN A,"+H$(8 TO 9)
 2550 IF C=4 THEN LET H$=H$+"EX(SP),HL"
 2560 IF C=5 THEN LET H$=H$+"EX DE,HL"
 2580 IF C=6 THEN LET H$=H$+"DI"
 2590 IF C=7 THEN LET H$=H$+"EI"
 2600 RETURN 
 2610 REM GROUP 4:T=1
 2620 IF C=3 THEN LET H$=H$+"EXX"
 2630 IF C=5 THEN LET H$=H$+"JP("
 2640 IF C=7 THEN LET H$=H$+"LD SP,"
 2650 IF C<5 THEN RETURN 
 2660 GOSUB 1090
 2670 IF C=7 THEN RETURN 
 2680 LET H$=H$+")"
 2690 RETURN 
 2700 REM ED PREFIXES TO 3610
 2710 IF L=1 THEN GOTO 3460
 2720 LET X0=PEEK (J-L+1)
 2730 GOSUB 230
 2740 IF X0<160 OR X0>187 THEN GOTO 2850
 2750 IF T>3 THEN RETURN 
 2760 IF T=3 AND C<6 THEN LET Q$="OUT"
 2770 IF T=3 AND C<6 THEN GOTO 2800
 2780 LET W=2*T+1
 2790 LET Q$=G$(W TO W+1)
 2800 IF (C-2*INT (C/2)) THEN LET Q$=Q$+"D"
 2810 IF NOT (C-2*INT (C/2)) THEN LET Q$=Q$+"I"
 2820 IF C>5 THEN LET Q$=Q$+"R"
 2830 LET H$=H$+Q$
 2840 RETURN 
 2850 IF X0<64 OR X0>123 THEN RETURN 
 2860 IF T>1 THEN GOTO 2910
 2870 LET Q$=R$(C+1)
 2880 IF T THEN LET H$=H$+"OUT(C),"+Q$
 2890 IF NOT T THEN LET H$=H$+"IN "+Q$+",(C)"
 2900 RETURN 
 2910 LET W=INT (C/2)
 2920 IF T<>2 THEN GOTO 2960
 2930 IF C-2*W THEN LET H$=H$+"ADD HL,"+D$(2*W+1 TO 2*W+2)
 2940 IF NOT (C-2*W) THEN LET H$=H$+"SBC HL,"+D$(2*W+1 TO 2*W+2)
 2950 RETURN 
 2960 IF T<>3 THEN GOTO 3020
 2970 IF C-2*W THEN GOTO 3000
 2980 LET H$=H$+"LD("+H$(12 TO 13)+H$(10 TO 11)+"),"+D$(2*W+1 TO 2*W+2)
 2990 RETURN 
 3000 LET H$=H$+"LD "+D$(2*W+1 TO 2*W+2)+",("+H$(12 TO 13)+H$(10 TO 11)+")"
 3010 RETURN 
 3020 IF T<>7 THEN GOTO 3120
 3030 IF C>3 THEN GOTO 3090
 3040 IF C=2*W THEN LET Q$="I"
 3050 IF C<>2*W THEN LET Q$="R"
 3060 IF C>1 THEN LET H$=H$+"LD A,"+Q$
 3070 IF C<2 THEN LET H$=H$+"LD "+Q$+",A"
 3080 RETURN 
 3090 IF C=4 THEN LET H$=H$+"RRD"
 3100 IF C=5 THEN LET H$=H$+"RLD"
 3110 RETURN 
 3120 IF T=6 AND C<4 AND C<>1 THEN LET H$=H$+"IM "+STR$ ((C>0)*(C-1))
 3130 IF X0=68 THEN LET H$=H$+"NEG"
 3140 IF X0=69 THEN LET H$=H$+"RETN"
 3150 IF X0=77 THEN LET H$=H$+"RETI"
 3160 RETURN 
 3170 REM BIT OPS
 3180 LET CB=1
 3190 LET X0=PEEK (J-1)
 3200 LET W=INT (X0/64)
 3210 LET X0=X0-W*64
 3220 IF W THEN GOTO 3350
 3230 LET B1=1+INT (X0/32)
 3240 LET B2=INT (X0/16)
 3250 LET X0=X0-B2*16
 3260 LET B3=INT (X0/8)+3
 3270 LET B2=B2+5
 3280 LET X0=1+X0-(B3-3)*8
 3290 LET Q$=R$(X0)
 3300 GOSUB 1170
 3310 LET H$=H$+C$(B1)+C$(B3)+C$(B2)
 3320 IF B2<>6 THEN LET H$=H$+" "
 3330 LET H$=H$+Q$
 3340 RETURN 
 3350 LET W=3*W-2
 3360 LET D=INT (X0/8)
 3370 LET X0=X0-D*8+1
 3380 LET Q$=R$(X0)
 3390 GOSUB 1170
 3400 LET H$=H$+B$(W TO W+2)+" "+STR$ (D)+","+Q$
 3410 RETURN 
 3420 REM FD,DD PREFIXES
 3430 LET DD=X0=221
 3440 LET FD=X0=253
 3450 IF L>1 THEN GOTO 3480
 3460 LET H$=H$+"DATA"
 3470 RETURN 
 3480 LET X0=PEEK (J-L+1)
 3490 GOTO 1000
 3500 REM MAIN LOOP
 3510 INPUT J
 3520 LET H$=""
 3530 LET P$=H$
 3540 LET Q$=H$
 3550 LET DD=0
 3560 LET FD=DD
 3570 LET CB=DD
 3580 GOSUB 350
 3590 GOSUB 300
 3600 GOSUB 420
 3610 LET H$=H$( TO LEN H$-2)
 3620 LET X0=PEEK J
 3630 FOR K=1 TO L
 3640 GOSUB 300
 3650 LET J=J+1
 3660 NEXT K
 3670 GOSUB 970
 3680 LPRINT H$
 3700 GOTO 3520
 3710 SAVE "1008%3"
 3720 LIST 

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

Scroll to Top