Desensamblador

Descripción del contenido de la página

Desensamblador de Z80 escrito en Sinclair BASIC.

Etiquetas:

Este sencillo desensamblador para ZX Spectrum pertenece al baúl de los recuerdos (y de los experimentos) de 1985, aunque su primera versión, que no conservo, es de un año antes.

Se puede definir una dirección virtual diferente de la real; y la salida puede dirigirse a la impresora.

Pantallazos

Pantalla de inicio:

Inicio

Ejemplo del final del desensamblado de la ROM de la ZX Spectrum, hasta el primer comando RET:

Resultado

Código fuente

   1 REM DESENSAMBLADOR
   2 REM Copyright (C) 1984,1985 Marcos Cruz (http://programandala.net)
   3 REM Licencia/Permesilo/License: http://programandala.net/lp
   4 REM 1984-09 V.1
   5 REM 1985-07 V.2
  10 GO SUB VAL "500"
  20 POKE VAL "23617",CODE " GO TO ": CLOSE #VAL "2": PRINT #SGN PI;"PULSA UNA TECLA": PAUSE PI-PI: CLS : INPUT "DIRECCION REAL="; LINE H$: INPUT "DIRECCION VIRTUAL="; LINE V$: IF V$="" THEN LET V$=H$
  25 IF H$(SGN PI)="#" THEN LET DIR=PI-PI: FOR C=LEN H$ TO 2 STEP VAL "-1": LET DIR=DIR+(CODE H$(C)-CODE "0"-(VAL "7"*(CODE H$(C)>CODE "@")))*VAL "16"^(LEN H$-C): NEXT C: GO TO 35
  30 LET DIR=VAL H$
  35 IF V$(SGN PI)="#" THEN LET POS=PI-PI: FOR C=LEN V$ TO 2 STEP VAL "-1": LET POS=POS+(CODE V$(C)-CODE "0"-(VAL "7"*(CODE V$(C)>CODE "@")))*VAL "16"^(LEN V$-C): NEXT C: GO TO 50
  40 LET POS=VAL V$
  50 INPUT "PARAR AL ENCONTRAR RET "; LINE H$: LET RUT=H$="S": INPUT "IMPRESORA "; LINE H$: LET IMP=H$="S": IF IMP THEN OPEN #VAL "2","P"
  60 POKE 23692,255: LET B=PEEK DIR: IF B=203 THEN GO TO RUTC
  70 IF B=221 THEN LET P$="IX": GO TO RUTD
  80 IF B=237 THEN GO TO RUTE
  90 IF B=253 THEN LET P$="IX": GO TO RUTD
 100 GO TO RUTN
 110 IF INKEY$=" STOP " THEN LET DAT2=PI-PI: GO TO VAL "20"
 120 IF INKEY$=" " THEN GO TO 120
 130 LET DIR=DIR+SUM: LET POS=POS+SUM: GO TO 60
 170 LET H$=""
 180 LET H$=H$+A$(INT (N/16)+1)+A$(N-INT (N/16)*16+1): RETURN
 190 LET N=INT (NN/256): GO SUB HEXN: LET N=NN-INT (NN/256)*256: GO SUB HEXN+10:IF DAT THEN LET DEC=NN: LET DAT2=1: LET DAT=0
 195 RETURN
 200 FOR L=1 TO LEN T$: IF T$(L)="/" THEN LET T$=T$( TO L-1)+"#"+H$+T$(L+1 TO ):GO TO PRINT
 210 NEXT L
 220 LET NN=POS: GO SUB HEXNN: LET L$=H$: LET H$="": FOR C=DIR TO DIR+SUM-1: LET N=PEEK C: GO SUB HEXN+10: NEXT C: IF IMP THEN PRINT TAB (25-LEN STR$ POS);POS;" ";
 225 PRINT "#";L$;" ";H$;B$(LEN H$ TO );T$;: IF IMP AND DAT2 THEN PRINT ";  ";DEC: LET DAT2=0: GO TO 228
 227 PRINT
 228 IF B-1=201 THEN IF RUT THEN GO TO 20
 229 GO TO 110
 230 LET B=B+1: IF N$(B,1)>"2" THEN LET SUM=1: LET T$=N$(B): GO TO PRINT
 240 IF N$(B,1)="1" THEN LET N=PEEK (DIR+1): GO SUB HEXN: LET SUM=2: LET T$=N$(B,2 TO ): GO TO PRINTD
 250 IF N$(B,1)="2" THEN LET DAT=1: LET NN=PEEK (DIR+1)+256*PEEK (DIR+2): GO SUB HEXNN: LET SUM=3: LET T$=N$(B,2 TO ): GO TO PRINTD
 260 LET B=PEEK (DIR+1): LET SUM=2: IF B>191 THEN LET T$=C$(10)+CHR$ INT ((B-192)/8+48)+","+C$(19+(B-(192+INT ((B-192)/8+1)*8))): GO TO PRINT
 270 IF B>127 THEN LET T$=C$(9)+CHR$ INT ((B-128)/8+48)+","+C$(19+(B-(128+INT ((B-128)/8+1)*8))): GO TO PRINT
 280 IF B>63 THEN LET T$=C$(8)+CHR$ INT ((B-64)/8+48)+","+C$(19+(B-(64+INT (((B-64)/8)+1)*8))): GO TO PRINT
 290 IF B>55 THEN LET T$=C$(7)+C$(19+(B-(56+INT ((B-56)/8+1)*8))): GO TO PRINT
 300 IF B>39 THEN LET T$=C$(6)+C$(19+(B-(40+INT ((B-40)/8+1)*8))): GO TO PRINT
 310 IF B>31 THEN LET T$=C$(5)+C$(19+(B-(32+INT ((B-32)/8+1)*8))): GO TO PRINT
 320 IF B>23 THEN LET T$=C$(4)+C$(19+(B-(24+INT ((B-24)/8+1)*8))): GO TO PRINT
 330 IF B>15 THEN LET T$=C$(3)+C$(19+(B-(16+INT ((B-16)/8+1)*8))): GO TO PRINT
 340 IF B>7 THEN LET T$=C$(2)+C$(19+(B-(8+INT ((B-8)/8+1)*8))): GO TO PRINT
 350 LET T$=C$(1)+C$(19+(B-INT ((B/8)+1)*8)): GO TO PRINT
 360 LET EA=1: LET EZ=39: LET P=DIR+1: LET B=PEEK P: IF B=203 THEN LET EA=40: LET EZ=70: LET P=DIR+3
 370 FOR C=EA TO EZ: IF PEEK P=D(C) THEN GO TO 390*(D(C)<>54)+790*(D(C)=54)
 380 NEXT C: LET C=C-1
 390 LET T$=D$(C,2 TO ): IF D$(C,1)>"2" THEN LET T$=D$(C): LET SUM=2: GO TO 420:GO TO PRINT
 400 IF D$(C,1)="1" THEN LET N=PEEK (DIR+2): GO SUB HEXN: LET SUM=3+(PEEK (DIR+2)=203): GO TO 420
 410 IF D$(C,1)="2" THEN LET N=PEEK (DIR+2)+256*PEEK (DIR+3): GO SUB HEXNN: LET SUM=4
 420 FOR C=1 TO LEN T$: IF T$(C)="*" THEN LET T$=T$( TO C-1)+P$+T$(C+1 TO ):
 430 NEXT C: GO TO PRINTD
 440 LET N=PEEK (DIR+1): GO SUB HEXN: LET T$="LD ("+P$+"+"+H$+"),": LET N=PEEK (DIR+2): GO SUB HEXN: LET T$=T$+H$: GO TO PRINT
 450 LET B=PEEK (DIR+1): FOR C=1 TO 54: IF E(C)=B THEN GO TO 470
 460 NEXT C: LET C=C-1
 470 IF E$(C,1)>"2" THEN LET T$=E$(C): GO TO PRINT
 480 IF E$(C,1)="1" THEN LET T$=E$(C,2 TO ): LET SUM=3: LET N=PEEK (DIR+2): GO SUB HEXN: GO TO PRINTD
 490 IF E$(C,1)="2" THEN LET DAT=1: LET T$=E$(C,2 TO ): LET SUM=4: LET NN=PEEK (DIR+2)+256*PEEK (DIR+3): GO SUB HEXNN: GO TO PRINTD
 500 LET DAT=PI-PI: LET DAT2=DAT: PAPER VAL "7": BORDER VAL "7": INK PI-PI: CLS : PRINT INVERSE SGN PI;"DESENSAMBLADOR"'' INVERSE PI-PI;"POR_MARCOS_CRUZ"'"SEPTIEMBRE_DE_1984"'"JULIO_DE_1985"''"INTRODUCE_LA_DIRECCION_DE"'"COMIENZO_CON_'#'_DELANTE_SI_ES"'"H
EXADECIMAL"
 510 PRINT '"ESPACIO => PAUSA"'"SYMBOL SHIFHT+A => PARAR";AT VAL "21",PI-PI; INVERSE SGN PI;"ESPERA POR FAVOR"
 520 POKE VAL "23658",VAL "8": LET B$="        ": LET PRINT=CODE " BRIGHT ": LET PRINTD=CODE ">=": LET RUTE=VAL "450": LET RUTD=VAL "360": LET RUTC=VAL "260": LET RUTN=CODE " NEW ": LET HEXN=CODE "SCREEN$ ": LET HEXNN=CODE "PEEK ": LET A$="0123456789ABCDE
F"
 530 DIM N$(VAL "256",VAL "11"): DIM C$(VAL "18",VAL "4"): DIM D$(CODE "F",VAL "13"): DIM D(CODE "F"): DIM E$(CODE "6",VAL "10"): DIM E(CODE "6")
 540 FOR N=SGN PI TO VAL "256": READ N$(N): NEXT N: FOR N=SGN PI TO VAL "18": READ C$(N): NEXT N: FOR N=SGN PI TO CODE "F": READ D$(N): NEXT N: FOR N=SGN PI TO CODE "F": READ D(N): NEXT N: FOR N=SGN PI TO CODE "6": READ E$(N): NEXT N: FOR N=SGN PI TO CODE
 "6": READ E(N): NEXT N
 550 RETURN
 560 DATA "NOP","2LD BC,/","LD (BC),A","INC BC","INC B","DEC B","1LD B,/","RLCA","EX AF,AF'","ADD HL,BC","LD A,(BC)","DEC BC","INC C","DEC C","1LD C,/","RRCA","1DJNZ /","2LD DE,/","LD (DE),A","INC DE","INC D","DEC D","1LD D,/","RLA","1JR /","ADD HL,DE","L
D A,(DE)","DEC DE","INC E","DEC E","1LD E,/","RRA","1JR NZ,/","2LD HL,/","2LD (/),HL","INC HL","INC H","DEC H"
 570 DATA "1LD H,/","DAA","1JR Z,/","ADD HL,HL","2LD HL,(/)","DEC HL","INC L","DEC L","1LD L,/","CPL","1JR NC,/","2LD SP,/","2LD (/),A","INC SP","INC (HL)","DEC (HL)","1LD (HL),/","SCF","1JR C,/","ADD HL,SP","2LD A,(/)","DEC SP","INC A","DEC A","1LD A,/",
"CCF","LD B,B","LD B,C","LD B,D","LD B,E","LD B,H","LD B,L","LD B,(HL)","LD B,A","LD C,B","LD C,C","LD C,D","LD C,E","LD C,H","LD C,L","LD C,(HL)","LD C,A"
 580 DATA "LD D,B","LD D,C","LD D,D","LD D,E","LD D,H","LD D,L","LD D,(HL)","LD D,A","LD E,B","LD E,C","LD E,D","LD E,E","LD E,H","LD E,L","LD E,(HL)","LD E,A","LD H,B","LD H,C","LD H,D","LD H,E","LD H,H","LD H,L","LD H,(HL)","LD H,A","LD L,B","LD L,C","L
D L,D","LD L,E","LD L,H","LD L,L","LD L,(HL)","LD L,A","LD (HL),B","LD (HL),C","LD (HL),D","LD (HL),E","LD (HL),H","LD (HL),L","HALT","LD (HL),A","LD A,B","LD A,C","LD A,D","LD A,E","LD A,H","LD A,L","LD A,(HL)","LD A,A"
 590 DATA "ADD A,B","ADD A,C","ADD A,D","ADD A,E","ADD A,H","ADD A,L","ADD A,(HL)","ADD A,A","ADC A,B","ADC A,C","ADC A,D","ADC A,E","ADC A,H","ADC A,L","ADC A,(HL)","ADC A,A","SUB B","SUB C","SUB D","SUB E","SUB H","SUB L","SUB (HL)","SUB A","SBC A,B","S
BC A,C","SBC A,D","SBC A,E","SBC A,H","SBC A,L","SBC A,(HL)","SBC A,A","AND B","AND C","AND D","AND E","AND H","AND L","AND (HL)","AND A","XOR B","XOR C","XOR D","XOR E","XOR H","XOR L","XOR (HL)","XOR A","OR B","OR C","OR D","OR E","OR H","OR L","OR (HL)
","OR A","CP B","CP C","CP D","CP E","CP H","CP L","CP (HL)","CP A"
 600 DATA "RET NZ","POP BC","2JP NZ,/","2JP /","2CALL NZ,/","PUSH BC","1ADD A,/","RST 00","RET Z","RET"+CHR$ 13+";","2JP Z,/","","2CALL Z,/","2CALL /","1ADC A,/","RST 08","RET NC","POP DE","2JP NC,/","1OUT (/),A","2CALL NC,/","PUSH DE","1SUB /","RST 10","
RET C","EXX","2JP C,/","1IN A,(/)","2CALL C,/","","1SBC A,/","RST 18","RET PO","POP HL","2JP PO,/","EX (SP),HL","2CALL PO,/","PUSH HL","1AND /","RST 20","RET PE","JP (HL)","2JP PE,/","EX DE,HL","2CALL PE,/","","1XOR /","RST 28","RET P","POP AF","2JP P,/",
"DI"
 610 DATA "2CALL P,/","PUSH AF","1OR /","RST 30","RET M","LD SP,HL","2JP M,/","EI","2CALL M,/","","1CP /","RST 38"
 620 DATA "RLC","RRC","RL","RR","SLA","SRA","SRL","BIT","RES","SET","B","C","D","E","H","L","(HL)","A"
 630 DATA "ADD *,BC","ADD *,DE","2LD *,/","2LD (/),*","INC *","ADD *,*","2LD *,(/)","DEC *","1INC (*+/)","1DEC (*+/)","","ADD *,SP","1LD B,(*+/)","1LD C,(*+/)","1LD D,(*+/)","1LD E,(*+/)","1LD H,(*+/)","1LD L,(*+/)","1LD (*+/),B","1LD (*+/),C","1LD (*+/),
D","1LD (*+/),E","1LD (*+/),H","1LD (*+/),L","1LD (*+/),A","1LD A,(*+/)"
 640 DATA "1ADD A,(*+/)","1ADC A,(*+/)","1SUB A,(*+/)","1SBC A,(*+/)","1AND (*+/)","1XOR (*+/)","1OR (*+/)","1CP (*+/)","POP *","EX (SP),*","PUSH *","JP (*)","LD SP,*","1RLC (*+/)","1RRC (*+/)","1RL (*+/)","1RR (*+/)","1SLA (*+/)","1SRA (*+/)","1SRL (*+/)
","1BIT 0,(*+/)","1BIT 1,(*+/)","1BIT 2,(*+/)","1BIT 3,(*+/)","1BIT 4,(*+/)","1BIT 5,(*+/)","1BIT 6,(*+/)","1BIT 7,(*+/)"
 650 DATA "1RES 0,(*+/)","1RES 1,(*+/)","1RES 2,(*+/)","1RES 3,(*+/)","1RES 4,(*+/)","1RES 5,(*+/)","1RES 6,(*+/)","1RES 7,(*+/)","1SET 0,(*+/)","1SET 1,(*+/)","1SET 2,(*+/)","1SET 3,(*+/)","1SET 4,(*+/)","1SET 5,(*+/)","1SET 6,(*+/)","1SET 7,(*+/)"
 660 DATA 9,25,33,34,35,41,42,43,52,53,54,57,70,78,86,94,102,110,112,113,114,115,116,117,119,126,134,142,150,158,166,174,182,190,225,227,229,233,249,6,14,22,30,38,46,62,70,78,86,94,102,110,118,126,134,142,150,158,166,174,182,190,198,206,214,222,230,238,24
6,254
 670 DATA "IN B,(C)","OUT (C),B","SBC HL,BC","2LD (/),BC","NEG","RETN","IM 0","LD I,A","IN C,(C)","OUT (C),C","ADC HL,BC","2LD BC,(/)","RETI","IN D,(C)","OUT (C),D","SBC HL,DE","2LD (/),DE","IM 1","LD A,I","IN E,(C)","OUT (C),E","ADC HL,DE","2LD DE,(/)","
IM 2","IN H,(C)","OUT (C),H","SBC HL,HL","RRD","IN L,(C)","OUT (C),L"
 680 DATA "ADC HL,HL","RLD","SBC HL,SP","2LD (/),SP","IN A,(C)","OUT (C),A","ADC HL,SP","2LD SP,(/)","LDI","CPI","INI","OUTI","LDD","CPD","IND","OUTD","LDIR","CPDIR","INIR","OTIR","LDDR","CPDR","INDR","OTDR"
 690 DATA 64,65,66,67,68,69,70,71,72,73,74,75,77,80,81,82,83,86,87,88,89,90,91,94,96,97,98,103,104,105,106,111,114,115,120,121,122,123,160,161,162,163,168,169,170,171,128,129,130,131,136,137,138,139
 700 CLEAR : SAVE "D-ENSAMBLA" LINE 1: RUN

Ejemplo de resultado

El código desensamblado puede desviarse a la impresora. El resultado tiene este aspecto:

 0 #0000 F3       DI
 1 #0001 AF       XOR A
 2 #0002 11FFFF   LD DE,#FFFF   ;  65535
 5 #0005 C3CB11   JP #11CB      ;  4555
 8 #0008 2A5D5C   LD HL,(#5C5D) ;  23645
11 #000B 225F5C   LD (#5C5F),HL ;  23647
14 #000E 1843     JR #43
16 #0010 C3F215   JP #15F2      ;  5618
19 #0013 FF       RST 38
20 #0014 FF       RST 38
21 #0015 FF       RST 38
22 #0016 FF       RST 38
23 #0017 FF       RST 38
24 #0018 2A5D5C   LD HL,(#5C5D) ;  23645
27 #001B 7E       LD A,(HL)
28 #001C CD7D00   CALL #007D    ;  125
31 #001F D0       RET NC
32 #0020 CD7400   CALL #0074    ;  116
35 #0023 18F7     JR #F7
37 #0025 FF       RST 38
38 #0026 FF       RST 38
39 #0027 FF       RST 38
40 #0028 C35B33   JP #335B      ;  13147
43 #002B FF       RST 38
44 #002C FF       RST 38
45 #002D FF       RST 38
46 #002E FF       RST 38
47 #002F FF       RST 38
48 #0030 C5       PUSH BC
49 #0031 2A615C   LD HL,(#5C61) ;  23649
52 #0034 E5       PUSH HL
53 #0035 C39E16   JP #169E      ;  5790
56 #0038 F5       PUSH AF
57 #0039 E5       PUSH HL
58 #003A 2A785C   LD HL,(#5C78) ;  23672
61 #003D 23       INC HL
62 #003E 22785C   LD (#5C78),HL ;  23672
65 #0041 7C       LD A,H
66 #0042 B5       OR L
67 #0043 2003     JR NZ,#03
69 #0045 FD3440   INC (IX+#40)
72 #0048 C5       PUSH BC
73 #0049 D5       PUSH DE
74 #004A CD6E38   CALL #386E    ;  14446
77 #004D D1       POP DE
78 #004E C1       POP BC
79 #004F E1       POP HL
80 #0050 F1       POP AF
81 #0051 FB       EI
82 #0052 C9       RET
;      

Descargas