Machine language disassembler in BASIC.
Appears on
Capital Area Timex Sinclair User Group’s Library Tape.
One of a series of library tapes. Programs on these tapes were renamed to a number series. This tape contained programs 20083 to 20120. These tapes were compiled by Tony Willing.
Source Code
0 REM RESET ROBERT GILDER 1984 5 REM 2068 DISASSEMBLER & MONITOR 10 LET ns=0: DIM s$(ns+1,8): LET s$(1)=CHR$ 0 20 GO TO 7500 30 DEF FN s(x)=CODE s$(x,7)+256*CODE s$(x,8) 100 GO SUB 7000 110 LET a$="ENTER to continue": GO SUB 9000 120 IF CODE s$(1) THEN GO TO 200 130 LET a$="Enter symbols?(Y/N)": GO SUB 9000: IF FN y() THEN GO SUB 7200: GO SUB 8300 200 LET a$="Hard copy (Y/N)?": GO SUB 9000: LET hc=2+FN y() 210 CLS 300 IF LEN INKEY$ THEN GO TO 300 305 LET a$="Enter start address:": GO SUB 9000: IF end THEN GO TO 20 310 GO SUB 8500: IF a<0 THEN GO TO 305 320 IF LEN INKEY$ THEN GO TO 320 330 PRINT #hc;"Addr Hex OP Operand/Notes"'' 340 FOR x=2 TO CODE s$(1)+1: LET xa=FN s(x): IF x>xa THEN NEXT x: LET xa=1e31 350 LET xs=x 400 REM Main loop 405 GO SUB 8000 410 IF LEN INKEY$ THEN GO TO 300 415 IF a>=xa THEN PRINT #hc;TAB 13;s$(xs TO 6);":": LET xs=xs+1: LET xa=1e31: IF xs<=CODE s$(1)+1 THEN LET xa=FN s(xs): GO TO 415 420 LET c=PEEK a: IF c=DD OR c=FD THEN GO SUB 8100 425 LET p$="BCDE"+e$+"AF": LET q$="BCDE"+e$+"SP": LET r$="BCDEHLMA" 430 IF c=CB THEN GO SUB 5000: GO TO 500 440 IF c=ED THEN GO SUB 6000: GO TO 500 450 GO SUB 8200 460 GO SUB 1000+g*1000 500 REM Print 510 LET h=a: GO SUB 9100: PRINT #hc;h$;" "; 520 FOR n=1 TO b: LET h=PEEK (a+n-1): GO SUB 9120: PRINT #hc;h$;: NEXT n 530 PRINT #hc;TAB 14;j$;TAB 19;k$;"," AND L$<>"";L$;" ";">" AND n$<>"";n$ 900 LET a=a+b 910 GO TO 400 1000 REM Group 00 1010 GO TO VAL "10201100120013001400140016001700"(t2*4+1 TO t2*4+4) 1020 LET i=9900: GO SUB 7300: IF t1<2 THEN RETURN 1050 LET b=b+1: LET h=a+2+FN p(a+1): GO SUB 9100: GO SUB 8450: LET n$=h$ 1060 RETURN 1100 IF t3 THEN LET j$="ADD": LET k$=e$: LET L$=FN p$(q$): RETURN 1120 LET j$="LD": LET k$=FN p$(q$): LET h=a+1+e: GO SUB 8400: LET L$=h$: RETURN 1200 LET i=9905: GO SUB 7300: IF t1<4 THEN RETURN 1220 LET h=a+1+e: GO SUB 8400 1230 IF t3 THEN LET L$=VAL$ L$: RETURN 1240 LET k$=VAL$ k$ 1250 RETURN 1300 LET j$=("DEC" AND t3)+("INC" AND (NOT t3)): LET k$=FN p$(q$): RETURN 1400 LET j$=("DEC" AND t2=5)+("INC" AND t2=4) 1420 LET k$=FN r$(t1): LET b=b+e 1430 RETURN 1600 LET j$="LD": LET k$=FN r$(t1): LET h=a+1+e*2: GO SUB 8600: LET b=b+e: LET L$=h$: RETURN 1700 LET i=9910: GO SUB 7300 1710 RETURN 2000 REM Group 01 2010 IF t1=6 AND t2=6 THEN LET j$="HALT": RETURN 2020 LET j$="LD" 2030 LET k$=FN r$(t1): LET L$=FN r$(t2) 2040 LET b=b+e 2050 RETURN 3000 REM Group 10 3010 LET k$=FN r$(t2): LET b=b+e 3100 LET i=9915: GO SUB 7300 3105 IF t1<4 AND t1<>2 THEN LET L$=k$: LET k$="A" 3110 RETURN 4000 REM Group 11 4010 GO TO 4100+t2*100 4020 LET j$="??": RETURN 4100 LET j$="RET": GO SUB 7400: RETURN 4200 IF t3 THEN LET i=9920: GO SUB 7300: RETURN 4210 LET j$="POP": LET k$=FN p$(p$): RETURN 4300 LET j$="JP": GO SUB 7400: LET h=a+1: GO SUB 8400: LET L$=h$: RETURN 4400 IF NOT t1 THEN LET h=a+1: GO SUB 8400 4410 IF t1=2 OR t1=3 THEN LET h=PEEK (a+1): GO SUB 9120: LET b=b+1 4420 LET i=9925: GO SUB 7300: RETURN 4500 LET j$="CALL": GO SUB 7400: LET h=a+1: GO SUB 8400: LET L$=h$: RETURN 4600 IF NOT t3 THEN LET j$="PUSH": LET k$=FN p$(p$): RETURN 4610 IF t1<>1 THEN GO TO 4020 4620 LET j$="CALL": LET h=a+1: GO SUB 8400: LET k$=h$: RETURN 4700 LET h=PEEK (a+1): GO SUB 9120: LET k$=h$: LET b=b+1: GO TO 3100 4800 LET j$="RST": LET h=t1*8: GO SUB 9120: LET k$=h$ 4810 RETURN 5000 REM CB Group 5010 LET b=b+1+e: LET c=PEEK (a+1+e*2): GO SUB 8200 5100 IF NOT g THEN LET i=9930: GO SUB 7300: LET k$=FN r$(t2): RETURN 5110 LET j$="BITRESSET"((g-1)*3+1 TO (g-1)*3+3) 5120 LET k$=CHR$ (t1+CODE "0") 5130 LET L$=FN r$(t2) 5140 RETURN 6000 REM ED group 6010 LET b=b+1: LET c=PEEK (a+1): GO SUB 8200 6020 IF g=2 THEN GO TO 6300 6030 IF g<>1 THEN LET j$="??": RETURN 6040 GO TO VAL "60506060607061006200621062206230"(t2*4+1 TO t2*4+4) 6050 LET j$="IN": LET L$="(C)": LET k$=FN r$(t1): RETURN 6060 LET j$="OUT": LET k$="(C)": LET L$=FN r$(t1): RETURN 6070 LET j$=("ADC" AND t3)+("SBC" AND (NOT t3)): LET k$=e$: LET L$=FN p$(q$): RETURN 6100 LET j$="LD": LET h=a+2: GO SUB 8400: LET h$="("+h$+")" 6120 LET k$=FN p$(q$): LET L$=h$ 6130 IF NOT t3 THEN LET L$=k$: LET k$=h$ 6140 RETURN 6200 LET j$="NEG": RETURN 6210 LET j$=("RETI" AND t1)+("RETN" AND (NOT t1)): RETURN 6220 LET j$="IM": LET k$=CHR$ (t1+CODE "0"): RETURN 6230 LET i=9935: GO SUB 7300 6240 RETURN 6300 RESTORE 9940+t2*10 6310 FOR x=1 TO t1-3: READ j$: NEXT x 6320 RETURN 7000 REM Initialize 7005 DEF FN r$(x)=(r$(x+1) AND r$(x+1)<>"M")+(FN i$(a+1+e) AND r$(x+1)="M") 7010 DEF FN p(x)=PEEK x-(256*(PEEK x>127)) 7015 DEF FN b$(x)=("+" AND FN p(x)>=0)+STR$ FN p(x) 7020 DEF FN i$(x)="("+e$+(FN b$(x) AND e)+")" 7025 DEF FN p$(x$)=x$(rp*2+1 TO rp*2+2) 7030 DEF FN y()=CHR$ CODE a$="Y" 7035 DEF FN n(x$)=(x$>="0" AND x$<="9") 7040 LET p$="BCDEHLAF": LET q$="BCDEHLSP": LET r$="BCDEHLMA" 7045 LET DD=VAL "221": LET FD=VAL "253" 7050 LET ED=VAL "237": LET CB=VAL "203" 7070 LET ramtop=1+PEEK 23730+256*PEEK 23731 7100 REM Instructions 7110 CLS : PRINT " *** 2068 DISASSEMBLER ***" 7130 PRINT '"All the values are shown in hex with the exception of relative offset value, which are shown indecimal(e.g. JR +19 or LD (IY-8),FF)." 7140 PRINT '"Addresses may be entered in hex (e.g. 43a2h) or decimal, or evencertain System Variable names, like RAMTOP." 7190 RETURN 7200 REM Enter symbol name 7210 LET a$="Load symbols from tape?": GO SUB 9000: IF FN y() THEN INPUT "Name:"; LINE a$: LOAD a$ DATA s$(): RETURN 7220 FOR s=2 TO ns+1 7230 LET a$="Enter symbol name:": GO SUB 9000: IF end THEN LET s=s-2: GO TO 7280 7240 LET s$(s, TO 6)=a$ 7250 LET a$="Enter address:": GO SUB 9000: IF end THEN GO TO 7250 7255 GO SUB 8500: IF a<0 THEN GO TO 7250 7260 LET s$(s,7 TO )=CHR$ (a-INT (a/256)*256)+CHR$ (INT (a/256)) 7270 PRINT s$(s, TO 6),a 7275 NEXT s: LET s=ns 7280 LET s$(1)=CHR$ s 7290 LET a$="Save symbols on tape?": GO SUB 9000: IF FN y() THEN INPUT "Name:"; LINE a$: SAVE a$ DATA s$() 7295 RETURN 7300 REM Create operand 7310 RESTORE i: READ n 7320 FOR x=1 TO t1+1 7330 READ j$: IF n=3 THEN READ k$,L$ 7340 NEXT x 7390 RETURN 7400 REM Condition codes 7410 RESTORE 9980: FOR x=1 TO t1+1: READ k$: NEXT x 7420 RETURN 7500 REM Machine Code Monitor-ZXMCOM 7501 REM ROBERT GILDER 1984 7505 LET e$="": GO SUB 8000: LET d=(LEN e$<>0): REM DISASM check 7510 LET ramtop=PEEK 23730+256*PEEK 23731+1: IF NOT d THEN LET s$=CHR$ 0: REM set ramtopvalue 7520 CLS : PRINT TAB 10;"MONITOR MENU"''" (1) Display memory in hex"'" (2) Enter hex machine code"'" (3) Alter memory" 7530 IF d THEN PRINT " (4) Disassemble memory" 7540 PRINT ''"Null Finish Program" 7550 LET a$="Enter your selection:": GO SUB 9000: IF end THEN STOP : GO TO 7520 7560 IF VAL a$<1 OR VAL a$>3+d THEN GO TO 7550 7570 CLS : GO TO VAL "7600770078000100"((VAL a$-1)*4+1 TO (VAL a$-1)*4+4) 7600 REM display memory 7610 IF LEN INKEY$ THEN GO TO 7610 7620 GO SUB 8700: IF end THEN GO TO 7500 7630 FOR a=a TO a+65535 STEP 8: LET h=a: GO SUB 9100: PRINT h$;" "; 7640 FOR b=a TO a+7: LET h=PEEK b: GO SUB 9120: PRINT h$;" ";: NEXT b 7650 PRINT : IF LEN INKEY$ THEN GO TO 7600 7660 NEXT a: GO TO 7500 7700 REM Enter machine code 7705 IF LEN INKEY$ THEN GO TO 7705 7710 GO SUB 8700: IF end THEN GO TO 7500 7715 PRINT AT 10,0;"Current address: ";a;"(";: LET h=a: GO SUB 9100: PRINT h$;")" 7720 LET a$="Enter hex: ": GO SUB 9000: IF end THEN GO TO 7500 7725 PRINT AT 21,0,, 7730 IF LEN a$<>INT (LEN a$/2)*2 THEN PRINT AT 21,0; FLASH 1;"LENGTH ERROR"; FLASH 0;" - re-enter": GO TO 7720 7735 FOR X=1 TO LEN a$-1 STEP 2: GO SUB 7900 7740 IF x1*16+x2>255 THEN PRINT AT 21,0; FLASH 1;"RANGE ERROR"; FLASH 0;" - re-enter remainder": GO TO 7715 7745 POKE a,x1*16+x2 7750 LET a=a+1 7755 NEXT x 7760 GO TO 7715 7800 REM Alter memory 7810 IF LEN INKEY$ THEN GO TO 7810 7820 GO SUB 8700: IF end THEN GO TO 7500 7830 LET h=a: GO SUB 9100: LET x$=h$: LET h=PEEK a: GO SUB 9120 7840 LET a$=x$+" "+h$+"-": GO SUB 9000: IF end THEN GO TO 7880 7850 IF a$="." THEN GO TO 7500 7860 IF LEN a$>2 THEN LET a$=a$( TO 2) 7870 LET x=1: GO SUB 7900: POKE a,x1*16+x2 7880 PRINT x$;" ";h$;"-";a$ 7890 LET a=a+1: GO TO 7830 7900 REM convert a$(x) to binary 7910 LET x1=CODE a$(x)-CODE "0"-7*(a$(x)>"9") 7920 LET x2=CODE a$(x+1)-CODE "0"-7*(a$(x+1)>"9") 7930 RETURN 8000 REM Reset defaults 8010 LET e$="HL" 8020 LET e=0: LET b=1 8030 LET j$="": LET k$="": LET L$="": LET h$="": LET n$="" 8040 RETURN 8090 RETURN : REM no disassembler present 8100 REM DD/FD opcode 8110 LET e$=("IX" AND c=DD)+("IY" AND c=FD) 8120 LET e=1: LET b=b+1 8130 LET c=PEEK (a+1) 8140 RETURN 8200 REM Split opcode 8210 LET g=INT (c/64): LET t1=INT (c/8)-g*8: LET t2=c-t1*8-g*64 8220 LET rp=INT (t1/2): LET t3=(rp*2<>t1) 8230 RETURN 8300 REM Sort symbols 8310 PRINT AT 21,0;"Sorting...." 8320 FOR x=2 TO CODE s$(1)+1: LET z=1: FOR y=2 TO CODE s$(1)-x+2 8330 IF FN s(y)>FN s(y+1) THEN LET x$=s$(y): LET s$(y)=s$(y+1): LET s$(y+1)=x$: LET z=0 8340 NEXT y: IF z THEN RETURN 8350 NEXT x 8360 RETURN 8400 REM Get address in h$ 8410 LET h=PEEK h+256*PEEK (h+1): GO SUB 9100 8420 LET b=b+2 8450 IF NOT CODE s$(1) THEN RETURN 8460 FOR x=2 TO CODE s$(1)+1 8470 IF h>FN s(x) THEN NEXT x: RETURN 8480 IF h=FN s(x) THEN LET h$=s$(x, TO 6) 8490 RETURN 8500 REM Create true address 8510 IF a$(LEN a$)="H" THEN LET a=0: FOR x=1 TO LEN a$-1: LET a=a*16+CODE a$(x)-CODE "0"-7*(a$(x)>"9"): NEXT x: RETURN 8520 FOR x=2 TO CODE s$(1)+1: IF a$=s$(x, TO LEN a$*(LEN a$<7)) THEN LET a=CODE s$(x,7)+256*CODE s$(x,8): RETURN 8530 RETURN 8540 LET a=-1: FOR x=1 TO LEN a$: IF a$(x)>="0" AND a$(x)<="9" THEN NEXT x: LET a=VAL a$ 8550 RETURN 8600 REM Byte value 8610 LET h=PEEK h: GO SUB 9120: LET b=b+1 8620 RETURN 8700 REM Start address 8710 LET a$="Enter start address:": GO SUB 9000: IF end THEN RETURN 8720 GO SUB 8500: IF a<0 THEN GO TO 8710 8730 RETURN 9000 REM Line input 9010 INPUT (a$+" "); LINE a$: LET end=NOT LEN a$ 9020 FOR x=1 TO LEN a$: LET a$(x)=CHR$ (CODE a$(x)-32*(a$(x)>="a")): NEXT x 9030 RETURN 9100 REM h$=hex$(h) 9110 LET h$=" ": GO TO 9130 9120 LET h$=" " 9130 LET h1=h: FOR x=LEN h$ TO 1 STEP -1: LET x1=h1-INT (h1/16)*16: LET h$(x)=CHR$ (x1+CODE "0"+7*(x1>9)): LET h1=INT (h1/16): NEXT x 9140 RETURN 9900 DATA 3,"NOP","","","EX","AF","AF","DJNZ",FN b$(a+1),"","JR",FN B$(a+1),"","JR","NZ",FN B$(a+1),"JR","Z",FN B$(a+1),"JR","NC",FN B$(a+1),"JR","C",FN B$(a+1) 9905 DATA 3,"LD","(BC)","A","LD","A","(BC)","LD","(DE)","A","LD","A","(DE)","LD","""(""+H$+"")""","HL","LD","HL","""(""+H$+"")""","LD","""(""+h$+"")""","A","LD","A","""(""+h$+"")""" 9910 DATA 1,"RLCA","RRCA","RLA","RRA","DAA","CPL","SCF","CCF" 9915 DATA 1,"ADD","ADC","SUB","SBC","AND","XOR","OR","CP" 9920 DATA 3,"??","","","RET","","","??","","","EXX","","","??","","","JP","("+E$+")","","??","","","LD","SP",E$ 9925 DATA 3,"JP",H$,"","??","","","OUT","("+H$+")","A","IN","A","("+H$+")","EX",E$,"(SP)","EX","DE",E$,"DI","","","EI","","" 9930 DATA 1,"RLC","RRC","RL","RR","SLA","SRA","??","SRL" 9935 DATA 3,"LD","I","A","LD","R","A","LD","A","I","LD","A","R","RRD","","","RLD","","" 9940 DATA "LDI","LDD","LDIR","LDDR" 9950 DATA "CPI","CPD","CPIR","CPDR" 9960 DATA "INI","IND","INIR","INDR" 9970 DATA "OUTI","OUTD","OTIR","OTDR" 9980 DATA "NZ","Z","NC","C","PO","PE","P","M" 9999 STOP