--- title: "DISA Z" id: 71004 type: "computer_media" slug: "disa-z" url: "http://localhost/computer_media/disa-z/" markdown_url: "http://localhost/computer_media/disa-z.md" published_at: "2026-08-26T01:27:13+00:00" modified_at: "2026-08-26T01:29:01+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2026/08/disa-z.png" alt: "DISA Z screen" excerpt: "This pure BASIC Z80 disassembler decodes every prefix group—CB, DD, ED, FD—and prints assembly mnemonics from any memory address you supply." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" indiv: - name: "Algis Gedris" slug: "algis-gedris" taxonomy: "indiv" url: "http://localhost/indiv/algis-gedris/" genre: - name: "Machine Language" slug: "machine-language" taxonomy: "genre" url: "http://localhost/type/machine-language/" - name: "Programming" slug: "programming" taxonomy: "genre" url: "http://localhost/type/programming/" media_type: "Program" programmers: - name: "Algis Gedris" slug: "algis-gedris" taxonomy: "indiv" url: "http://localhost/indiv/algis-gedris/" download_url: "https://archive.org/download/timex-sinclair-software-archive/DISA%20Z%20%281983%29%28Gedris%2C%20Algis%29%28TS2068%29%28US%29%28Program%29.zip" mediadate: "1983" images: - url: "http://localhost/wp-content/uploads/2026/08/disa-z.png" alt: "DISA Z screen" media_type_tags: "Machine Language, Programming" --- # DISA Z DISA Z is a Z80 disassembler written in BASIC that decodes machine code bytes stored in memory and prints human-readable assembly mnemonics. The program accepts a decimal start address, then reads and decodes opcodes including all prefixed instruction groups: DD (IX), FD (IY), ED (extended), and CB (bit operations). It handles multi-byte instructions by computing instruction length before fetching operand bytes, and formats 16-bit addresses in big-endian hex by swapping high and low byte pairs. A configurable variable `TS2` at line 160 adjusts the hex character offset (`NCOD`) to accommodate different character code mappings between the TS1000 and TS2068 models. The main loop uses `POKE 23692,255` to suppress the automatic scroll prompt, allowing continuous output without user intervention. *** ## Program Analysis ### Program Structure The program is organized as a collection of BASIC subroutines dispatched from a main loop beginning at line 3560. After prompting for a start address, the loop at lines 3580–3760 repeatedly fetches an instruction, computes its length, formats a hex dump string, decodes the mnemonic, prints the result, and advances to the next instruction. Control never exits this loop during normal operation; line 3770 (`STOP`) is unreachable in practice. | Line range | Purpose | | --- | --- | | 10–50 | REM header block | | 60–140 | Data string initialization (mnemonic tables) | | 150–180 | Platform selection and branch to main loop | | 190–250 | Octal digit decoder subroutine | | 260–380 | Hex formatting subroutines (byte and address) | | 390–950 | Instruction length calculator | | 960–3220 | Mnemonic decoder (unprefixed + CB + ED groups) | | 3230–3470 | CB-prefixed (bit/rotate/shift) instruction decoder | | 3480–3550 | DD/FD (IX/IY) prefix handler | | 3560–3780 | Main input/display loop | ### Platform Adaptation via TS2 Flag Line 160 sets `TS2=1`, and line 170 computes `NCOD=28+20*TS2`, giving 48 for TS2068 (ASCII ‘0’) or 28 for TS1000. This offset is used in line 300 when building the hex string: `CHR$(NCOD+Y+7*(Y>9)*TS2)`. On the TS1000 the character set places digits at code 28; on the TS2068 they follow ASCII. The expression `7*(Y>9)*TS2` adds 7 for A–F only on the TS2068 model, bridging the gap between ‘9’ and ‘A’ in ASCII. ### Mnemonic Data Encoding Rather than storing one string per mnemonic, the program packs related mnemonics into fixed-width substrings within shared data strings, then slices them by computed index. This approach saves significant memory. - `O$` (line 70): 8 arithmetic/logic ops, 3 characters each — ADD, ADC, SUB, SBC, AND, XOR, OR, CP - `D$` (line 80): register-pair names, 2 characters each — BC, DE, HL, SP, AF, IX, IY - `B$` (line 90): BIT, RES, SET — 3 characters each - `C$` (line 100): rotate/shift direction qualifiers - `R$` (line 110): single-character register names B, C, D, E, H, L, X (placeholder for (HL)), A - `E$` (line 120): condition codes, 2 characters each — NZ, Z, NC, C, PO, PE, P, M - `F$` (line 130): miscellaneous group-0/group-3 single-byte ops (RLCA, RRCA, RLA, RRA, DAA, CPL, SCF, CCF), 4 characters each - `G$` (line 140): block instruction roots — LD, CP, IN, OT ### Instruction Length Calculation The subroutine at lines 390–950 determines how many bytes the current instruction occupies before any decoding begins. It initializes `L=0` and increments it based on opcode class. Prefix bytes (DD=221, FD=253) cause a recursive-style re-entry via the `GO TO 410` loop at line 440. The ED prefix (237) triggers a separate path at line 540 that classifies the following byte to decide whether a 2-byte operand follows. CB prefix (203) always yields a 2-byte instruction body (plus any preceding prefix). Unprefixed opcodes in the range 64–191 (LD r,r block) take 1 byte; operand-bearing opcodes in the first and fourth groups are detected by modular arithmetic on the octal decomposition. ### Octal Decomposition Idiom The Z80 instruction set is most naturally described in octal. The subroutine at lines 190–250 decomposes an opcode `X0` into three fields: the high octal digit pair `K` (0–3, the “group”), the middle octal digit `C` (0–7), and the low octal digit `T` (0–7). This decomposition is used throughout the decoder, e.g. group 1 (64–127) are LD r,r; group 2 (128–191) are arithmetic/logic on registers; group 3 (192–255) contains calls, jumps, and miscellaneous ops. The modulo-8 test used in many conditional branches is expressed as `NOT (W - INT(W/8)*8)`, which is true when `W` is a multiple of 8, equivalent to `W MOD 8 = 0`. ### Hex String Construction and Address Formatting The program builds a fixed-width display string `H$` that holds the address, hex bytes, and mnemonic in a single concatenated string. The address hexer (lines 320–380) calls the byte hexer (lines 260–310) twice — first for the high byte, then for the low byte — placing them in big-endian print order. For 16-bit address operands embedded in instructions, the decoder retrieves them as `H$(10 TO 11)+H$(8 TO 9)`, swapping the two hex-byte pairs back to little-endian Z80 format. Line 3670 strips the last two characters of `H$` after the initial address hex call, removing the byte that was PEEKed purely to test for prefix status but should not appear in the opcode dump at that position. ### Index Register Substitution When an IX or IY prefix is active (`DD` or `FD` flags set), the placeholder register `"X"` in `P$` or `Q$` is replaced by an indexed address string such as `"(IX+nn)"` at lines 1240–1280. The displacement byte `nn` is read directly from the pre-built hex string at positions 10–11. Without a prefix, `"X"` becomes `"(HL)"` (lines 1200–1210). ### Scroll Suppression Line 3750 executes `POKE 23692,255` each iteration. Address 23692 is the system variable `SCRCT` (scroll counter), which normally halts output and prompts “scroll?” after a screenful of lines. Poking 255 resets the counter to its maximum, effectively disabling the pause and allowing the disassembly to scroll continuously. ### Notable Bugs and Anomalies - Line 3080 contains `IF T<>7 THEN GO TO 3180`, but the ED-prefix decoder at lines 2760–3220 never routes execution to line 3080 — the `T=7` case is not reachable from the preceding branch structure, so LD A,I / LD A,R / LD I,A / LD R,A / RRD / RLD decode is dead code in practice (only lines 3090–3170 are ever reached via line 3080 if it were called). The correct dispatcher for T=7 would need an explicit check after line 3070. - The `EX AF,AF'` mnemonic at line 2180 is rendered as `EX AF,AF"` due to BASIC string quoting — the closing single-quote of the alternate register notation cannot be represented inside a BASIC string literal and is approximated with a double-quote. This is a display inaccuracy rather than a functional bug. - Lines 2540–2570 handle certain LD (rr),A and LD A,(rr) forms. The branch for `C=4` at line 2560 falls through to `GO TO 1100`, which appends a pointer register name but does not add the surrounding parentheses or comma, potentially producing malformed output for the `LD (nn),HL` class of instructions when no IX/IY prefix is active. ## Source Code ``` 10 REM *********************** DISA Z 20 REM *********************** A Z80 DISASSEMBLER FOR TS COMPUTERS 30 REM *********************** COPYRIGHT,1983 ALGIS GEDRIS 40 REM *********************** RUN AND ENTER START ADDRESS IN DECIMAL 50 REM *********************** 60 REM DATA STRINGS 70 LET O$="ADDADCSUBSBCANDXOROR CP " 80 LET D$="BCDEHLSPAFIXIY" 90 LET B$="BITRESSET" 100 LET C$="RSLRC AL" 110 LET R$="BCDEHLXA" 120 LET E$="NZZ NCC POPEP M " 130 LET F$="RLCARRCARLA RRA DAA CPL SCF CCF " 140 LET G$="LDCPINOT" 150 REM FOR TS2000 SET TS2=1 160 LET TS2=1 170 LET NCOD=28+20*TS2 180 GO TO 3560 190 REM OCTAL DIGITS 200 FOR K=0 TO 3 210 IF X0 >=K*64 AND X0<(K+1)*64 THEN LET X=X0-K*64 220 NEXT K 230 LET C= INT (X/8) 240 LET T=X-C*8 250 RETURN 260 REM BYTE HEXER 270 LET X= PEEK J 280 LET Y= INT (X/16) 290 LET Z=X-Y*16 300 LET H$=H$+ CHR$ (NCOD+Y+7*(Y>9)*TS2)+ CHR$ (NCOD+Z+7*(Z>9)*TS2) 310 RETURN 320 REM ADDRESS HEXER 330 LET X= INT (J/256) 340 GO SUB 280 350 LET X=J-256*X 360 GO SUB 280 370 LET H$=H$+" " 380 RETURN 390 REM GET INSTRUCTION LENGTH 400 LET L=0 410 IF X <>221 AND X <>253 THEN GO TO 520 420 IF L THEN RETURN 430 GO SUB 450 440 GO TO 410 450 LET L=1 460 LET J=J+1 470 GO SUB 270 480 LET J=J-1 490 LET H$=H$( TO LEN H$-2) 500 RETURN 510 REM I-LENGTH FOR PREFIXES 520 IF L THEN LET L=L+((X>51) AND (X<55) OR X=203) 530 IF X=203 THEN GO TO 930 540 IF X <>237 THEN GO TO 700 550 GO SUB 450 560 IF X<64 OR X>188 THEN RETURN 570 IF X<160 AND X>123 THEN RETURN 580 IF X<124 THEN GO TO 610 590 IF X- INT (X/8)*8<5 THEN GO TO 940 600 RETURN 610 IF X=78 OR X=102 OR X=110 OR X=112 OR X=113 OR X=118 OR X=119 THEN RETURN 620 LET W=X-67 630 IF NOT (W- INT (W/8)*8) THEN GO TO 910 640 LET W=X-76 650 IF W >=0 AND NOT (W- INT (W/8)*8) THEN RETURN 660 LET W=X-85 670 IF W >=0 AND NOT (W- INT (W/8)*8) THEN RETURN 680 GO TO 940 690 REM WITHOUT PREFIXES 700 IF X<64 OR X>191 THEN GO TO 730 710 IF L THEN LET L=L+(X-8* INT (X/8)=6) 720 GO TO 940 730 IF X>191 THEN GO TO 820 740 IF Z=1 THEN GO TO 910 750 LET W=X-34 760 IF W >=0 AND NOT (W- INT (W/8)*8) THEN GO TO 910 770 LET W=X-6 780 IF W >=0 AND NOT (W- INT (W/8)*8) THEN GO TO 930 790 LET W=X-16 800 IF W >=0 AND NOT (W- INT (W/8)*8) THEN GO TO 930 810 GO TO 940 820 IF X=195 OR X=205 THEN GO TO 910 830 IF X=211 OR X=219 THEN GO TO 930 840 LET W=X-194 850 IF NOT (W- INT (W/8)*8) THEN GO TO 910 860 LET W=W-2 870 IF NOT (W- INT (W/8)*8) THEN GO TO 910 880 LET W=W-2 890 IF NOT (W- INT (W/8)*8) THEN GO TO 930 900 GO TO 940 910 IF L=2 THEN GO TO 930 920 LET L=L+1 930 LET L=L+1 940 LET L=L+1 950 RETURN 960 REM MNEMONICS 970 LET H$=H$+" " 980 IF LEN H$<14 THEN GO TO 970 990 IF X0=118 THEN GO TO 1320 1000 GO SUB 190 1010 IF X0<64 OR X0>191 THEN GO TO 1440 1020 IF X0>127 THEN GO TO 1340 1030 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 GO SUB 1190 1070 LET H$=H$+"LD "+P$+","+Q$ 1080 RETURN 1090 REM ADD POINTER REGS TO H$ 1100 IF NOT DD THEN GO TO 1130 1110 LET H$=H$+"IX" 1120 RETURN 1130 IF NOT FD THEN GO TO 1160 1140 LET H$=H$+"IY" 1150 RETURN 1160 LET H$=H$+"HL" 1170 RETURN 1180 REM CHECK FOR FD OR DD 1190 IF FD OR DD THEN GO TO 1240 1200 IF P$="X" THEN LET P$="(HL)" 1210 IF Q$="X" THEN LET Q$="(HL)" 1220 RETURN 1230 REM ADD INDEX REGS TO H$ 1240 IF FD THEN LET W$="(IY+" 1250 IF DD THEN LET W$="(IX+" 1260 IF P$="X" THEN LET P$=W$+H$(10 TO 11)+")" 1270 IF Q$="X" THEN LET Q$=W$+H$(10 TO 11)+")" 1280 RETURN 1290 GO SUB 1190 1300 LET H$=H$+P$+","+R$(1+T) 1310 RETURN 1320 LET H$=H$+"HLT" 1330 RETURN 1340 REM ARITH/LOGIC OPS 1350 LET I=C*3+1 1360 LET Q$=R$(T+1) 1370 GO SUB 1190 1380 LET I$=" " 1390 IF I<7 OR I=10 THEN LET I$=" A," 1400 IF I>18 THEN LET I$="" 1410 LET H$=H$+O$(1 TO I+2)+I$+Q$ 1420 RETURN 1430 REM 1ST AND 4TH GROUPS 1440 IF X0=203 THEN GO TO 3230 1450 IF X0=253 OR X0=221 THEN GO TO 3480 1460 IF X0>191 THEN GO TO 1620 1470 REM 1ST GROUP 1480 IF T=1 THEN GO TO 2100 1490 IF T=3 THEN GO TO 2320 1500 IF T=4 OR T=5 THEN GO TO 2380 1510 IF T=2 THEN GO TO 2450 1520 IF NOT T THEN GO TO 2160 1530 IF T <>6 THEN GO TO 1590 1540 LET Q$=R$(C+1) 1550 GO SUB 1190 1560 LET W=4*(FD OR DD) 1570 LET H$=H$+"LD "+Q$+","+H$(8+W TO 9+W) 1580 RETURN 1590 LET W=4*C+1 1600 LET H$=H$+F$(W TO W+3) 1610 RETURN 1620 REM DIRECT ARITHMETIC 1630 IF T <>6 THEN GO TO 1710 1640 LET I=3*C+1 1650 LET I$=" " 1660 IF I<7 OR I=10 THEN LET I$=" A," 1670 IF I>18 THEN LET I$="" 1680 LET H$=H$+O$(I TO I+2)+I$ 1690 LET H$=H$+H$(8 TO 9) 1700 RETURN 1710 REM 4TH GROUP 1720 IF X0=237 THEN GO TO 2760 1730 IF T=1 AND NOT (C- INT (C/2)*2) THEN GO TO 1990 1740 IF T=7 THEN GO TO 2070 1750 IF T=5 AND NOT (C- INT (C/2)*2) THEN GO TO 2010 1760 LET FL=0 1770 IF X0=205 OR T=4 THEN GO SUB 1890 1780 IF X0=195 OR T=2 THEN GO SUB 1860 1790 IF X0=201 OR NOT T THEN GO SUB 1930 1800 IF NOT T OR T=2 OR T=4 THEN GO SUB 1950 1810 IF T=3 AND NOT FL THEN GO TO 2590 1820 IF T=1 AND NOT FL THEN GO TO 2670 1830 IF FL THEN GO SUB 1910 1840 RETURN 1850 REM MAIN CONDITIONALS 1860 LET H$=H$+"JP " 1870 LET FL=1 1880 RETURN 1890 LET H$=H$+"CALL " 1900 GO TO 1870 1910 LET H$=H$+H$(10 TO 11)+H$(8 TO 9) 1920 RETURN 1930 LET H$=H$+"RET " 1940 GO TO 1870 1950 LET H$=H$+E$(2*C+1 TO 2*(C+1)) 1960 IF NOT (C=1 OR C=3 OR C>5) THEN LET H$=H$+" " 1970 RETURN 1980 REM GROUP 4/C EVEN,T=1 OR 5 1990 LET H$=H$+"POP " 2000 GO TO 2020 2010 LET H$=H$+"PUSH " 2020 IF C=6 THEN LET C=8 2030 IF C=4 THEN LET C=C+6*(FD OR DD) 2040 LET H$=H$+D$(1+C TO 2+C) 2050 RETURN 2060 REM GROUP 4/T=7 2070 LET W= INT (C/2) 2080 LET H$=H$+"RST "+ STR$ (W)+ STR$ (8*(C-2*W)) 2090 RETURN 2100 REM GROUP 1/T=1 2110 IF C-2* INT (C/2) THEN GO TO 2140 2120 LET H$=H$+"LD "+D$(C+1 TO C+2)+"," 2130 GO TO 1910 2140 LET H$=H$+"ADD HL,"+D$(C TO C+1) 2150 RETURN 2160 REM GROUP 1/T=0 (JRS) 2170 IF C=0 THEN LET H$=H$+"NOP" 2180 IF C=1 THEN LET H$=H$+"EX AF,AF""" 2190 IF C=2 THEN LET H$=H$+"DJNZ" 2200 IF C>1 THEN GO TO 2220 2210 RETURN 2220 IF C>2 THEN LET H$=H$+"JR " 2230 LET W=C*2-7 2240 IF C>3 THEN LET H$=H$+E$(W TO W+1) 2250 IF NOT (C-2* INT (C/2)) THEN LET H$=H$+" " 2260 LET W=(PEEK (J-1) AND (PEEK (J-1)<128))+((PEEK (J-1)-256) AND (PEEK (J-1)>127)) 2270 LET J0=J 2280 LET J=J+W 2290 GO SUB 320 2300 LET J=J0 2310 RETURN 2320 REM GROUP 1/T=3 2330 LET Q$="INC " 2340 IF C-2* INT (C/2) THEN LET Q$="DEC " 2350 LET W=2* INT (C/2)+1 2360 LET H$=H$+Q$+D$(W TO W+1) 2370 RETURN 2380 REM GROUP 1/T=4 OR 5 2390 LET Q$=R$(C+1) 2400 GO SUB 1190 2410 LET P$="INC " 2420 IF T-2* INT (T/2) THEN LET P$="DEC " 2430 LET H$=H$+P$+Q$ 2440 RETURN 2450 REM GROUP 1/T=2 2460 LET H$=H$+"LD " 2470 IF NOT (C-2* INT (C/2)) THEN GO TO 2540 2480 IF C=5 THEN GO SUB 1100 2490 IF C=5 THEN GO TO 2510 2500 LET H$=H$+"A" 2510 IF C>3 THEN LET H$=H$+",("+H$(10 TO 11)+H$(8 TO 9)+")" 2520 IF C<4 THEN LET H$=H$+",("+D$(C TO C+1)+")" 2530 RETURN 2540 IF C>4 THEN LET H$=H$+"("+D$(C+1 TO C+2)+")," 2550 IF C>3 THEN LET H$=H$+"("+H$(10 TO 11)+H$(8 TO 9)+")," 2560 IF C=4 THEN GO TO 1100 2570 LET H$=H$+"A" 2580 RETURN 2590 REM GROUP 4/T=3 2600 IF C=2 THEN LET H$=H$+"OUT"+H$(8 TO 9)+",A" 2610 IF C=3 THEN LET H$=H$+"IN A,"+H$(8 TO 9) 2620 IF C=4 THEN LET H$=H$+"EX(SP),HL" 2630 IF C=5 THEN LET H$=H$+"EX DE,HL" 2640 IF C=6 THEN LET H$=H$+"DI" 2650 IF C=7 THEN LET H$=H$+"EI" 2660 RETURN 2670 REM GROUP 4/T=1 2680 IF C=3 THEN LET H$=H$+"EXX" 2690 IF C=5 THEN LET H$=H$+"JP(" 2700 IF C=7 THEN LET H$=H$+"LD SP," 2710 IF C<5 THEN RETURN 2720 GO SUB 1100 2730 IF C=7 THEN RETURN 2740 LET H$=H$+")" 2750 RETURN 2760 REM ED PREFIXES TO 3610 2770 IF L=1 THEN GO TO 3520 2780 LET X0= PEEK (J-L+1) 2790 GO SUB 190 2800 IF X0<160 OR X0>187 THEN GO TO 2910 2810 IF T>3 THEN RETURN 2820 IF T=3 AND C<6 THEN LET Q$="OUT" 2830 IF T=3 AND C<6 THEN GO TO 2860 2840 LET W=2*T+1 2850 LET Q$=G$(W TO W+1) 2860 IF (C-2* INT (C/2)) THEN LET Q$=Q$+"D" 2870 IF NOT (C-2* INT (C/2)) THEN LET Q$=Q$+"I" 2880 IF C>5 THEN LET Q$=Q$+"R" 2890 LET H$=H$+Q$ 2900 RETURN 2910 IF X0<64 OR X0>123 THEN RETURN 2920 IF T>1 THEN GO TO 2970 2930 LET Q$=R$(C+1) 2940 IF T THEN LET H$=H$+"OUT(C),"+Q$ 2950 IF NOT T THEN LET H$=H$+"IN "+Q$+",(C)" 2960 RETURN 2970 LET W= INT (C/2) 2980 IF T <>2 THEN GO TO 3020 2990 IF C-2*W THEN LET H$=H$+"ADC HL,"+D$(2*W+1 TO 2*W+2) 3000 IF NOT (C-2*W) THEN LET H$=H$+"SBC HL,"+D$(2*W+1 TO 2*W+2) 3010 RETURN 3020 IF T <>3 THEN GO TO 3180 3030 IF C-2*W THEN GO TO 3060 3040 LET H$=H$+"LD("+H$(12 TO 13)+H$(10 TO 11)+"),"+D$(2*W+1 TO 2*W+2) 3050 RETURN 3060 LET H$=H$+"LD "+D$(2*W+1 TO 2*W+2)+",("+H$(12 TO 13)+H$(10 TO 11)+")" 3070 RETURN 3080 IF T <>7 THEN GO TO 3180 3090 IF C>3 THEN GO TO 3150 3100 IF C=2*W THEN LET Q$="I" 3110 IF C <>2*W THEN LET Q$="R" 3120 IF C>1 THEN LET H$=H$+"LD A,"+Q$ 3130 IF C<2 THEN LET H$=H$+"LD "+Q$+",A" 3140 RETURN 3150 IF C=4 THEN LET H$=H$+"RRD" 3160 IF C=5 THEN LET H$=H$+"RLD" 3170 RETURN 3180 IF T=6 AND C<4 AND C <>1 THEN LET H$=H$+"IM "+ STR$ ((C>0)*(C-1)) 3190 IF X0=68 THEN LET H$=H$+"NEG" 3200 IF X0=69 THEN LET H$=H$+"RETN" 3210 IF X0=77 THEN LET H$=H$+"RETI" 3220 RETURN 3230 REM BIT OPS 3240 LET CB=1 3250 LET X0= PEEK (J-1) 3260 LET W= INT (X0/64) 3270 LET X0=X0-W*64 3280 IF W THEN GO TO 3410 3290 LET B1=1+ INT (X0/32) 3300 LET B2= INT (X0/16) 3310 LET X0=X0-B2*16 3320 LET B3= INT (X0/8)+3 3330 LET B2=B2+5 3340 LET X0=1+X0-(B3-3)*8 3350 LET Q$=R$(X0) 3360 GO SUB 1190 3370 LET H$=H$+C$(B1)+C$(B3)+C$(B2) 3380 IF B2 <>6 THEN LET H$=H$+" " 3390 LET H$=H$+Q$ 3400 RETURN 3410 LET W=3*W-2 3420 LET D= INT (X0/8) 3430 LET X0=X0-D*8+1 3440 LET Q$=R$(X0) 3450 GO SUB 1190 3460 LET H$=H$+B$(W TO W+2)+" "+ STR$ (D)+","+Q$ 3470 RETURN 3480 REM FD,DD PREFIXES 3490 LET DD=X0=221 3500 LET FD=X0=253 3510 IF L>1 THEN GO TO 3540 3520 LET H$=H$+"DATA" 3530 RETURN 3540 LET X0= PEEK (J-L+1) 3550 GO TO 990 3560 REM MAIN LOOP 3570 INPUT "START LINE NUMBER ";J 3580 LET H$="" 3590 LET P$=H$ 3600 LET Q$=H$ 3610 LET DD=0 3620 LET FD=DD 3630 LET CB=DD 3640 GO SUB 320 3650 GO SUB 270 3660 GO SUB 390 3670 LET H$=H$( TO LEN H$-2) 3680 LET X0= PEEK J 3690 FOR K=1 TO L 3700 GO SUB 270 3710 LET J=J+1 3720 NEXT K 3730 GO SUB 960 3740 PRINT H$ 3750 POKE 23692,255 3760 GO TO 3580 3770 STOP 3780 SAVE "DISA Z" LINE 10 ```