10 REM **************** 20 REM Z80 Disassembler 30 REM **************** 40 REM COPYRIGHT (C) Victor Tolomei 1979 ALL RIGHTS RESERVED 50 REM Appreciation goes to Lou Rivas for his suggestions on enhancements. 60 REM Modified for AMSTRAD NC100 by Bruce Harris. 1993 70 REM 80 REM Modified for more comfort, ad string search, banking and fix some 90 REM bugs by H.-J. Boehling 25.04.1998 e-mail: 101.107378@germanynet.de 100 REM http:/www.germany.net/teilnehmer/101,107378/index.htm 110 REM Start DISASM (this program) only by running DISTART ! 120 REM 130 REM Downloaded from Tim's Amstrad NC Users' Site 140 REM http://www.ncus.org.uk 150 REM 160 REM ===== Set Variables ============== 170 CLEAR 180 FILE$=""K=0:ZEILEN=7:PLAY=1:REM Number of screenlines, sound on 190 HE$ = "0123456789ABCDEF": PRO$ = "\|/-":STADR=0:EDADR=65535:SEARCH$="Test" 200 BUFF$="***":BANK$="********":BANK=&41 210 Z80$="**************** Z80 DISASSEMBLER ******************************" 220 DIM EX$(7), C0$(7), CX$(5), R$(7), D1$(3), D2$(3), D3$(3), D4$(3) 230 DIM A0$(3), A1$(3), T2$(3), JM$(5), CN$(7) 240 FOR I = 0 TO 7: READ EX$(I): NEXT I 250 DATA "ADD A,","ADC A,","SUB ","SBC A,","AND " 260 DATA "XOR ","OR ","CP " 270 FOR I = 0 TO 7: READ C0$(I): NEXT I 280 DATA "RLC","RRC","RL ","RR ","SLA","SRA","?","SRL" 290 CX$(0) = "BIT": CX$(1) = "RES": CX$(2) = "SET" 300 FOR I = 0 TO 7: READ R$(I): NEXT I 310 DATA "B","C","D","E","H","L","(HL)","A" 320 FOR I = 0 TO 3: READ D1$(I), D2$(I), D3$(I), D4$(I): NEXT I 330 DATA "BC","BC","BC","BC", "DE","DE","DE","DE" 340 DATA "HL","IX","IY","HL", "SP","SP","SP","AF" 350 FOR I = 0 TO 3: READ A0$(I): NEXT: FOR I = 0 TO 3: READ A1$(I): NEXT I 360 DATA "LD","CP","IN","OUT", "I","D","IR","DR" 370 FOR I = 0 TO 3: READ T2$(I): NEXT I 380 DATA "DAA","CPL","SCF","CCF" 390 FOR I = 0 TO 5: READ JM$(I): NEXT I 400 DATA "DJNZ ","JR ","JR NZ","JR Z","JR NC","JR C" 410 FOR I = 0 TO 7: READ CN$(I): NEXT I 420 DATA "NZ","Z","NC","C","PO","PE","P","M" 430 REM ===== Input ====================== 440 ON ERROR GOTO 3480 450 CLS: PRINT TAB(0,0)"***";BUFF$;"*";BANK$;Z80$:PRINT: LI = 0 460 IF BUFF$="-O-"THEN PRINT#K,CHR$(13) 470 PRINT"(D)isassemble (M)emory dump (S)earch (B)ank (O)utput (E)nd";TAB(65)":? ";:JOB$=GET$:PRINT JOB$ 480 IF JOB$ = "D" OR JOB$ = "d" THEN 570 490 IF JOB$ = "M" OR JOB$ = "m" THEN 570 500 IF JOB$ = "S" OR JOB$ = "s" THEN 550 510 IF JOB$ = "B" OR JOB$ = "b" THEN 3120 520 IF JOB$ = "O" OR JOB$ = "o" THEN 3340 530 IF JOB$ = "E" OR JOB$ = "e" THEN 3570 540 GOTO 430 550 PRINT"Enter ASCII-string to search";TAB(40)"(Return = ";SEARCH$;")";:INPUT TAB(65)":";IN$ 560 IF IN$="" THEN 570 ELSE SEARCH$=IN$ 570 PRINT"Enter hex address to start";TAB(40)"(Return = ";~STADR;")";:INPUT TAB(65)":"; IN$ 580 GOSUB 2170: IF DEZ = -1 THEN 570 590 IF DEZ = -2 THEN 600 ELSE STADR = DEZ 600 PRINT"Enter hex address to stop";TAB(40)"(Return = ";~EDADR;")";:INPUT TAB(65)":"; IN$ 610 GOSUB 2170: IF DEZ = -1 THEN 600 620 IF DEZ = -2 THEN 630 ELSE EDADR = DEZ 630 IF EDADR < STADR THEN ADR = EDADR: EDADR = STADR: STADR = ADR ELSE ADR = STADR: REM swap if necessary 640 PRINT 650 IF JOB$="M" OR JOB$="m"THEN 2720 660 IF JOB$="S" OR JOB$="s"THEN 2840 670 REM ===== DISASSEMBLER =============== 680 GOSUB 2370: GOSUB 3420: ON G + 1 GOTO 790, 750, 780, 690 690 IF O <> 203 THEN 1100 700 GOSUB 3420: IZ$ = R$(R) 710 IF G > 0 THEN 740 720 IF F = 6 THEN 2010 730 I$ = C0$(F) + " " + IZ$: GOTO 2020 740 I$ = CX$(G - 1) + " " + STR$(F) + "," + IZ$: GOTO 2020 750 IF O <> 118 THEN 770 760 I$ = "HALT": GOTO 2020 770 I$ = "LD " + R$(F) + "," + R$(R): GOTO 2020 780 I$ = EX$(F) + R$(R): GOTO 2020 790 IF R <> 6 THEN 820 800 I$ = "LD " + R$(F) + "," 810 GOSUB 3420: I$ = I$ + D$: GOTO 2020 820 IF R <> 1 THEN 870 830 IF FL THEN 860 840 I$ = "LD " + D1$(INT(F / 2)) + "," 850 GOSUB 3420: X$ = D$: GOSUB 3420: I$ = I$ + D$ + X$: GOTO 2020 860 I$ = "ADD HL," + D1$(INT(F / 2)): GOTO 2020 870 IF R <> 3 THEN 900 880 I$ = "INC": IF FL THEN I$ = "DEC" 890 I$ = I$ + " " + D1$(INT(F / 2)): GOTO 2020 900 IF R <> 4 AND R <> 5 THEN 930 910 I$ = "INC": IF R = 5 THEN I$ = "DEC" 920 I$ = I$ + " " + R$(F): GOTO 2020 930 IF R <> 2 THEN 1010 940 IF O <> 42 AND O <> 34 THEN 990 950 X$ = "HL" 960 F2 = FL: GOSUB 3420: Y$ = D$: GOSUB 3420: Y$ = "(" + D$ + Y$ + ")": FL = F2 970 IF FL = 0 THEN D$ = Y$: Y$ = X$: X$ = D$ 980 I$ = "LD " + X$ + "," + Y$: GOTO 2020 990 X$ = "A": IF F >= 6 THEN 960 1000 Y$ = "(" + D1$(F / 2) + ")": GOTO 970 1010 IF R <> 7 THEN 1060 1020 IF F > 3 THEN 1050 1030 IF F < 2 THEN I$ = C0$(F) + "A": GOTO 2020 1040 I$ = LEFT$(C0$(F), 2) + "A": GOTO 2020 1050 I$ = T2$(F - 4): GOTO 2020 1060 IF O = 0 THEN I$ = "NOP": GOTO 2020 1070 IF O = 8 THEN I$ = "EX AF,AF'": GOTO 2020 1080 I$ = JM$(F - 2): IF F > 3 THEN I$ = I$ + "," 1090 GOSUB 3420: I$ = I$ + D$ + " ": I$ = LEFT$(I$, 11): GOSUB 2330: GOTO 2020 1100 IF O = 221 THEN 1490 1110 IF O = 237 THEN 1650 1120 IF O = 253 THEN 2000 1130 IF O = 195 OR O = 233 OR O = 205 OR O = 201 THEN 1300 1140 IF R <> 1 AND R <> 5 THEN 1210 1150 IF FL THEN 1190 1160 IF R = 1 THEN X$ = "POP " 1170 IF R = 5 THEN X$ = "PUSH" 1180 I$ = X$ + " " + D4$(INT(F / 2)): GOTO 2020 1190 IF O = 217 THEN I$ = "EXX": GOTO 2020 1200 IF O = 249 THEN I$ = "LD SP,HL": GOTO 2020 1210 IF R <> 6 THEN 1230 1220 F2 = F: GOSUB 3420: F = F2: I$ = EX$(F) + D$: GOTO 2020 1230 IF R <> 2 THEN 1260 1240 I$ = "JP " 1250 I$ = I$ + CN$(F) + ",": GOTO 850 1260 IF R <> 0 THEN 1280 1270 I$ = "RET " + CN$(F): GOTO 2020 1280 IF R <> 4 THEN 1370 1290 I$ = "CALL ": GOTO 1250 1300 IF O <> 195 THEN 1320 1310 I$ = "JP ": GOTO 850 1320 IF O <> 205 THEN 1340 1330 I$ = "CALL ": GOTO 850 1340 IF O = 233 THEN I$ = "JP (HL)" 1350 IF O = 201 THEN I$ = "RET" 1360 GOTO 2020 1370 IF R <> 7 THEN 1390 1380 BI = F * 8: GOSUB 2300: I$ = "RST " + D$: GOTO 2020 1390 IF O <> 211 THEN 1420 1400 GOSUB 3420: I$ = "OUT (" 1410 I$ = I$ + D$ + "),A": GOTO 2020 1420 IF O = 227 THEN I$ = "EX (SP),HL": GOTO 2020 1430 IF O <> 219 THEN 1450 1440 GOSUB 3420: I$ = "IN A,(": I$ = I$ + D$ + ")": GOTO 2020 1450 IF O = 235 THEN I$ = "EX DE,HL" 1460 IF O = 243 THEN I$ = "DI" 1470 IF O = 251 THEN I$ = "EI" 1480 GOTO 2020 1490 X$ = "X" 1500 GOSUB 3420 1510 IF G <> 1 THEN 1590 1520 IF R = 6 THEN 1550 1530 R2 = R: GOSUB 3420: I$ = "LD (I" + X$ + "+" + D$ + ")," + R$(R2) 1540 GOTO 2020 1550 IF F = 6 THEN 2010 1560 I$ = "LD " + R$(F) + ",(I" 1570 I$ = I$ + X$ + "+": GOSUB 3420 1580 I$ = I$ + D$ + ")": GOTO 2020 1590 IF O <> 54 THEN 1620 1600 I$ = "LD (I" + X$ + "+" 1610 GOSUB 3420: I$ = I$ + D$ + "),": GOSUB 3420: I$ = I$ + D$: GOTO 2020 1620 IF G <> 2 THEN 2400 1630 IF R <> 6 THEN 2400 1640 E = F: GOSUB 3420: I$ = EX$(E) + "(I" + X$ + "+" + D$ + ")": GOTO 2020 1650 GOSUB 3420: IF G <> 1 THEN 1990 1660 IF R <> 7 THEN 1760 1670 IF F > 3 THEN 1730 1680 I$ = "LD ": ON F + 1 GOTO 1690, 1700, 1710, 1720 1690 I$ = I$ + "I,A": GOTO 2020 1700 I$ = I$ + "R,A": GOTO 2020 1710 I$ = I$ + "A,I": GOTO 2020 1720 I$ = I$ + "A,R": GOTO 2020 1730 ON F - 3 GOTO 1740, 1750, 2010, 2010 1740 I$ = "RRD": GOTO 2020 1750 I$ = "RLD": GOTO 2020 1760 IF R <> 3 THEN 1790 1770 IF F = 4 OR F = 5 THEN 2010 1780 X$ = D1$(INT(F / 2)): GOTO 960 1790 IF R <> 4 THEN 1820 1800 IF O <> 68 THEN 2010 1810 I$ = "NEG": GOTO 2020 1820 IF R <> 2 THEN 1860 1830 I$ = "ADC": IF FL THEN 1850 1840 I$ = "SBC" 1850 I$ = I$ + " HL," + D1$(INT(F / 2)): GOTO 2020 1860 IF R <> 5 THEN 1910 1870 I$ = "": IF O = 69 THEN I$ = "RETN" 1880 IF O = 77 THEN I$ = "RETI" 1890 IF I$ = "" THEN 2010 1900 GOTO 2020 1910 IF R <> 1 THEN 1930 1920 I$ = "OUT (C)," + R$(F): GOTO 2020 1930 IF R <> 0 THEN 1950 1940 I$ = "IN " + R$(F) + ",(C)": GOTO 2020 1950 I$ = "": IF F = 0 THEN I$ = "IM0" 1960 IF F = 2 THEN I$ = "IM1" 1970 IF F = 3 THEN I$ = "IM2" 1980 GOTO 1890 1990 IF G <> 2 THEN 2010 2000 X$ = "Y": GOTO 1500 2010 I$ = "??? " + STR$(O) 2020 REM ----- Disassembling Output ------- 2030 PRINT M$; TAB(20); I$; TAB(42); P$: IN = IN + 1 2040 IF BUFF$="-O-" THEN PRINT#K,M$+STRING$((17-LEN(M$))," ")+I$+STRING$((21-LEN(I$))," ")+P$ 2050 LI = LI + 1: IF LI = ZEILEN THEN LI = 0:PRINT"-MORE-";:IN$ = GET$:PRINT 2060 IF IN$ = "n" OR IN$ = "N" THEN 2080 2070 IF ADR <= EDADR THEN 680: REM Weiter 2080 PRINT "Instructions: "; IN; " "; 2090 IF BUFF$="-O-" THEN PRINT#K,CHR$(13)+"Instructions: "+STR$(IN) 2100 PRINT "Bytes: "; ADR - STADR 2110 IF BUFF$="-O-" THEN PRINT#K,CHR$(13)+"Bytes : "+STR$(ADR - STADR) 2120 PRINT"-NEXT-";:IN$ = GET$: GOTO 430 2130 REM ===== Subroutines ================ 2140 REM ----- 2150 G = INT(by / 64): TE = by - G * 64: F = INT(TE / 8): R = TE - F * 8 2160 FL = F - INT(F / 2) * 2: RETURN 2170 REM ----- Check hex convert to dez --- 2180 DEZ = 0: LG = LEN(IN$): IF LG > 4 THEN DEZ = -1: RETURN 2190 IF IN$ = "" THEN DEZ = -2: RETURN 2200 FOR I = 1 TO LG: B$ = MID$(IN$, I, 1) 2210 IF (B$ >= "0" AND B$ <= "9") OR (B$ >= "A" AND B$ <= "F") OR (B$ >= "a" AND B$ <= "f") THEN 2230 2220 DEZ = -1: I = LG: GOTO 2270: REM Fehler 2230 J = ASC(B$) - 48 2240 IF J > 9 THEN J = J - 7 2250 IF J > 15 THEN J = J - 32 2260 DEZ = DEZ * 16 + J 2270 NEXT 2280 RETURN 2290 REM ----- 2300 IH = INT(BI / 16): IL = BI - IH * 16 2310 D$ = MID$(HE$, IH + 1, 1) + MID$(HE$, IL + 1, 1) 2320 RETURN 2330 DS = O + ADR: IF O > 127 THEN DS = O + ADR - 256 2340 BI = INT(DS / 256): GOSUB 2300: I$ = I$ + " (" + D$ 2350 BI = DS - BI * 256: GOSUB 2300: I$ = I$ + D$ + ")" 2360 RETURN 2370 P$ = "": BI = INT(ADR / 256): GOSUB 2300 2380 M$ = D$: BI = ADR - BI * 256: GOSUB 2300: M$ = M$ + D$ + ":" 2390 RETURN 2400 IF G <> 3 THEN 2510 2410 IF O <> 203 THEN 2440 2420 GOSUB 3420: IZ$ = "(I" + X$ + "+" + D$ + ")": GOSUB 3420 2430 GOTO 710 2440 I$ = "": IF O = 225 THEN I$ = "POP I" + X$ 2450 IF O = 227 THEN I$ = "EX (SP),I" + X$ 2460 IF O = 229 THEN I$ = "PUSH I" + X$ 2470 IF O = 233 THEN I$ = "JP (I" + X$ + ")" 2480 IF O = 249 THEN I$ = "LD SP,I" + X$ 2490 IF I$ = "" THEN 2010 2500 GOTO 2020 2510 IF R <> 1 THEN 2570 2520 IF FL = 0 THEN 2550 2530 Y$ = D2$(INT((F - 1) / 2)): IF X$ = "Y" THEN Y$ = D3$(INT((F - 1) / 2)) 2540 I$ = "ADD I" + X$ + "," + Y$: GOTO 2020 2550 I$ = "LD I" + X$ + "," 2560 GOTO 850 2570 IF R = 0 THEN 2010 2580 IF R <> 2 THEN 2640 2590 IF O <> 34 AND O <> 42 THEN 2010 2600 P = O: GOSUB 3420: Y$ = D$: GOSUB 3420 2610 IF P = 34 THEN I$ = "LD (" + D$ + Y$ + "),I" + X$ 2620 IF P = 42 THEN I$ = "LD I" + X$ + ",(" + D$ + Y$ + ")" 2630 GOTO 2020 2640 IF R <> 3 THEN 2680 2650 I$ = "": IF O = 35 THEN I$ = "INC I" + X$ 2660 IF O = 43 THEN I$ = "DEC I" + X$ 2670 GOTO 1890 2680 IF O <> 52 AND O <> 53 THEN 2010 2690 I$ = "IN": IF O = 53 THEN I$ = "DE" 2700 I$ = I$ + "C (I" 2710 GOTO 1570 2720 REM ===== ASCII-Output ============== 2730 I$ = "": GOSUB 2370: PRT$=M$: M$ = "" 2740 P$ = "": GOSUB 3420 2750 Z$ = CHR$(O): IF O < 32 THEN Z$ = " " 2760 I$ = I$ + Z$: IF LEN(I$) < 16 THEN 2740 2770 PRT$=PRT$+M$ 2780 PRINT PRT$;TAB(53);CHR$(179); I$ 2790 IF BUFF$="-O-" THEN PRINT#K,PRT$+STRING$((53-LEN(PRT$))," ")+CHR$(179)+I$ 2800 IF ADR > EDADR THEN 2100 2810 LI = LI + 1: IF LI = ZEILEN THEN LI = 0:PRINT"-MORE-";:IN$ = GET$:PRINT 2820 IF IN$ = "n" OR IN$ = "N" THEN 2100 2830 GOTO 2730 2840 REM ===== ASCII-Search =============== 2850 CLS:PRINT TAB(0,0)"***";BUFF$;"*";BANK$;Z80$: PRINT 2860 PRT$="Searching for ASCII-string -"+SEARCH$+"- from hex adress -"+STR$~(STADR)+"- to -"+STR$~(EDADR)+"-"+CHR$(13) 2870 PRINT PRT$ 2880 IF BUFF$="-O-" THEN PRINT#K,PRT$ 2890 REM ----- Search first letter -------- 2900 SEARCH = ASC(SEARCH$): REST = LEN(SEARCH$): J = 0 2910 J1=J1+1:IF J1= 10 THEN J1=0:J = J + 1: PRINT TAB(1,0) MID$(PRO$, J, 1): IF J = 4 THEN J = 0 2920 FOUND = 0: IF ?(ADR) = SEARCH THEN GOSUB 2990 2930 IF FOUND = 1 THEN 3060 2940 ADR = ADR + 1: IF ADR <= EDADR THEN 2910 2950 PRINT TAB(1,0)"*":IF PLAY=1 THEN FOR I=65 TO 1 STEP -4: SOUND 1,1,I,1:NEXT 2960 PRT$="String not found (any more)!":PRINT TAB(0,5) PRT$ 2970 IF BUFF$="-O-"THEN PRINT#K,CHR$(13)+PRT$ 2980 GOTO 2120 2990 REM ----- Search rest of hole string - 3000 FOUND = 1: IF REST = 1 THEN RETURN 3010 FOR I = 2 TO REST 3020 IF ?(ADR + I - 1) = ASC(MID$(SEARCH$, I, 1)) THEN 3040 3030 FOUND = 0: I = REST: REM Not found 3040 NEXT 3050 RETURN 3060 REM ----- String found --------------- 3070 PRINT TAB(1,0)"*":IF PLAY=1 THEN FOR I=1 TO 65 STEP 4:SOUND 1,1,I,1:NEXT 3080 PRT$="String found ad hex adress :":PRINT TAB(0,3);PRT$;~ADR 3090 IF BUFF$="-O-"THEN PRINT#K,PRT$+STR$~(ADR) 3100 INPUT "-MORE- "; IN$: IF IN$ = "N" OR IN$ = "n" THEN 430 3110 GOTO 2940 3120 REM ===== Banking ==================== 3130 PRINT"Banking R(A)M, R(O)M, or (C)ard ROM";TAB(40)"(Return = off)";:INPUT TAB(65)":";IN$ 3140 IF IN$ = "A" OR IN$ = "a" THEN 3180 3150 IF IN$ = "O" OR IN$ = "o" THEN 3230 3160 IF IN$ = "C" OR IN$ = "c" THEN 3280 3170 IF IN$ = "" THEN 3330 ELSE 3120 3180 REM ----- RAM Banking ---------------- 3190 PRINT"Which RAM block to &4000-&7FFF ?";TAB(40)"(0-3, Return = off)";:INPUT TAB(65)":";IN$ 3200 GOSUB 2170: IF DEZ= -2 THEN 3330 3210 IF DEZ<0 OR DEZ>3 THEN 3190 3220 BANK=DEZ+&40:BANK$="-RAM :"+STR$(DEZ)+"-":GOTO 430 3230 REM ----- ROM Banking ---------------- 3240 PRINT"Which ROM block to &4000-&7FFF ?";TAB(40)"(0-&F, Return = off)";:INPUT TAB(65)":";IN$ 3250 GOSUB 2170: IF DEZ= -2 THEN 3330 3260 IF DEZ<0 OR DEZ>15 THEN 3240 3270 BANK=DEZ:BANK$="-ROM :"+STR$~(BANK)+"-":GOTO 430 3280 REM ----- Card RAM Banking ----------- 3290 PRINT"Which Card RAM block to &4000-&7FFF ?";TAB(40)"(0-&3F, Return = off)";:INPUT TAB(65)":";IN$ 3300 GOSUB 2170: IF DEZ= -2 THEN 3330 3310 IF DEZ<0 OR DEZ>63 THEN 3280 3320 BANK=DEZ+&80:BANK$="-Card:"+STR$~(DEZ)+"-":GOTO 430 3330 BANK=&41:BANK$="********": GOTO 430 3340 REM ===== Buffer-file toggle ========= 3350 IF BUFF$="-O-" THEN 3400 3360 INPUT"Enter name for buffer-file";TAB(40);"(Return = DISASM.TXT)";TAB(65);":";FILE$ 3370 IF FILE$="" THEN FILE$="DISASM.TXT" 3380 K=OPENOUT(FILE$):ZEILEN=0:BUFF$="-O-" 3390 GOTO 430 3400 BUFF$="***":ZEILEN=7:CLOSE#K:K=0:FILE$="" 3410 GOTO 430 3420 REM ----- Read memory data ----------- 3430 ZQ = ADR: IF ADR > 32767 THEN ZQ = ADR - 65536 3440 PUT &11,BANK:O = ?(ZQ):PUT &11,&41: BI = O: GOSUB 2300: by = O: GOSUB 2140 3450 M$ = M$ + " " + D$: ADR = ADR + 1: IF O < 33 OR O > 127 THEN P$ = P$ + "." 3460 IF O > 32 AND O < 128 THEN P$ = P$ + CHR$(O) 3470 RETURN 3480 REM ===== Error-handling ============= 3490 IF ERR = 17 GOTO 430 3500 REPORT 3510 IF ERR = 190 GOTO 430 3520 IF ERR = 196 GOTO 3360 3530 IF ERR = 198 THEN CLOSE#K:FILE$="":GOTO 430 3540 IF ERR = 200 THEN FILE$="":GOTO 430 3550 IF ERR = 202 THEN CLOSE#K:FILE$="":GOTO 430 3560 PRINT:PRINT:PRINT "Error ";ERR;" - ";:REPORT:PRINT" at line ";ERL:PRINT:IN$=GET$ 3570 PRINT CHR$(12):IF K>0 THEN CLOSE#K 3580 END