1 ; This code is been found in a ZX Spectrum tool called UTILITY3 v1.3
3 ; set this to 0 to avoid dumping the address
4 DISZ80_DUMP_ADDRESS equ 1
5 ; set this to 0 to avoid dumping the code
11 ;; emit routine should preserve all registers except AF and HL
24 DISASM_USE_HEX_PREFIX equ 1
25 ; Einar Saukas' optimisation, cut 2 bytes
26 DISASM_EINAR_OPTIMISATION equ 1
28 ; ====================
29 ; DIS-Z80 was published in the SUBSET column of Personal Computer World 1987.
30 ; The routine disassembles a single Z80 instruction at address DE.
31 ; It is required to be followed by a routine called CHROP that outputs a
32 ; single ASCII character.
33 ; It was originally developed for CP/M on an Amstrad CPC128.
35 ; The original ORG was $0100. I have added $5000 to all addresses.
36 ; The stated aim was to write a Z80 disassembly routine in as short a space
37 ; as possible and, at just over 1K (1090 bytes), it is a rather incredible
40 ; The SUBSET editor David Barrow was able to trim only one byte from John
41 ; Kerr's compact code. I've forgotten where so there's a challenge.
43 ; k8: sadly, i had to add some mode code, so it is 1101 bytes now
44 ; (including `EMIT_CB` variable)
45 ; or 1099 bytes with Einar's optimisation ;-)
47 ; it is using 18 bytes on the stack as a temp buffer, so make sure
48 ; that you have enough stack space for the buffer, and for all other data
49 ; in practice, i guess that 32 bytes will be enough (if your emitter doesn't
53 ; DE: address to disasm from
55 ; DE: addres of the next instruction
57 ; ====================
60 $IF @DISZ80_DUMP_ADDRESS
223 $IF @DISZ80_DUMP_CODE
249 ;***********************
253 defb $04,$80,$2D,$C0,$BE
254 defb $FF,$F8,$06,$00,$33
255 defb $08,$38,$10,$35,$18
256 defb $3A,$20,$3F,$28,$40
262 defb $24,$07,$32,$0F,$37
263 defb $17,$31,$1F,$36,$27
264 defb $0D,$2F,$0B,$37,$3D
265 defb $3F,$06,$76,$14,$C9
266 defb $30,$D9,$12,$F3,$0F
267 defb $FB,$91,$72,$C6,$02
268 defb $CE,$01,$de,$bc,$02
269 defb $D6,$42,$E6,$03,$EE
270 defb $43,$F6,$25,$FE,$8C
271 defb $04,$08,$93,$01,$10
272 defb $10,$18,$9D,$af,$22
273 defb $A2,$FA,$2A,$A2,$A7
274 defb $32,$A2,$7A,$3A,$A2
275 defb $03,$C3,$1C,$CD,$85
276 defb $97,$D3,$AA,$79,$db
277 defb $9B,$5F,$E3,$93,$0E
278 defb $E9,$9C,$05,$EB,$93
279 defb $DF,$F9,$A2,$FF,$C0
280 defb $B6,$40,$A2,$FF,$F8
281 defb $76,$80,$02,$88,$01
282 defb $98,$bc,$06,$90,$42
283 defb $A0,$03,$A8,$43,$B0
284 defb $25,$B8,$8C,$FF,$C7
285 defb $0B,$04,$16,$05,$8E
286 defb $B2,$06,$A2,$20,$C0
287 defb $B0,$23,$C2,$1C,$C4
288 defb $85,$10,$C7,$BB,$FF
289 defb $CF,$D3,$01,$A2,$0D
290 defb $03,$16,$0B,$8E,$FD
291 defb $09,$82,$60,$C1,$2B
292 defb $C5,$AC,$FF,$E7,$21
293 defb $20,$9D,$FF,$EF,$E7
294 defb $02,$A2,$7E,$0A,$A2
299 defb $23,$45,$2F,$4D,$2E
300 defb $4E,$00,$67,$39,$6F
301 defb $34,$70,$00,$71,$00
302 defb $A0,$21,$A1,$0A,$A2
303 defb $1A,$A3,$29,$A8,$1F
304 defb $A9,$08,$AA,$18,$AB
305 defb $28,$B0,$20,$B1,$09
306 defb $B2,$19,$B3,$27,$B8
307 defb $1E,$B9,$07,$BA,$17
308 defb $BB,$A6,$FF,$C7,$B8
309 defb $40,$9B,$8B,$41,$AA
310 defb $FF,$CF,$FD,$42,$3C
311 defb $4A,$81,$AD,$43,$A2
312 defb $DA,$4B,$A2,$FF,$E7
313 defb $40,$46,$95,$FF,$F7
314 defb $C7,$47,$A2,$7C,$57
321 defb 'A','D','C'+$80 ; ADC
322 defb 'A','D','D'+$80 ; ADD
323 defb 'A','N','D'+$80 ; AND
324 defb 'B','I','T'+$80 ; BIT
325 defb 'C','A','L','L'+$80 ; CALL
326 defb 'C','C','F'+$80 ; CCF
327 defb 'C','P','D','R'+$80 ; CPDR
328 defb 'C','P','D'+$80 ; CPD
329 defb 'C','P','I','R'+$80 ; CPIR
330 defb 'C','P','I'+$80 ; CPI
331 defb 'C','P','L'+$80 ; CPL
332 defb 'C','P'+$80 ; CP
333 defb 'D','A','A'+$80 ; DAA
334 defb 'D','E','C'+$80 ; DEC
335 defb 'D','I'+$80 ; DI
336 defb 'D','J','N','Z'+$80 ; DJNZ
337 defb 'E','I'+$80 ; EI
338 defb 'E','X','X'+$80 ; EXX
339 defb 'E','X'+$80 ; EX
340 defb 'H','A','L','T'+$80 ; HALT
341 defb 'I','M'+$80 ; IM
342 defb 'I','N','C'+$80 ; INC
343 defb 'I','N','D','R'+$80 ; INDR
344 defb 'I','N','D'+$80 ; IND
345 defb 'I','N','I','R'+$80 ; INIR
346 defb 'I','N','I'+$80 ; INI
347 defb 'I','N'+$80 ; IN
348 defb 'J','P'+$80 ; JP
349 defb 'J','R'+$80 ; JR
350 defb 'L','D','D','R'+$80 ; LDDR
351 defb 'L','D','D'+$80 ; LDD
352 defb 'L','D','I','R'+$80 ; LDIR
353 defb 'L','D','I'+$80 ; LDI
354 defb 'L','D'+$80 ; LD
355 defb 'N','E','G'+$80 ; NEG
356 defb 'N','O','P'+$80 ; NOP
357 defb 'O','R'+$80 ; OR
358 defb 'O','T','D','R'+$80 ; OTDR
359 defb 'O','T','I','R'+$80 ; OTIR
360 defb 'O','U','T','D'+$80 ; OUTD
361 defb 'O','U','T','I'+$80 ; OUTI
362 defb 'O','U','T'+$80 ; OUT
363 defb 'P','O','P'+$80 ; POP
364 defb 'P','U','S','H'+$80 ; PUSH
365 defb 'R','E','S'+$80 ; RES
366 defb 'R','E','T','I'+$80 ; RETI
367 defb 'R','E','T','N'+$80 ; RETN
368 defb 'R','E','T'+$80 ; RET
369 defb 'R','L','A'+$80 ; RLA
370 defb 'R','L','C','A'+$80 ; RLCA
371 defb 'R','L','C'+$80 ; RLC
372 defb 'R','L','D'+$80 ; RLD
373 defb 'R','L'+$80 ; RL
374 defb 'R','R','A'+$80 ; RRA
375 defb 'R','R','C','A'+$80 ; RA
376 defb 'R','R','C'+$80 ; RRC
377 defb 'R','R','D'+$80 ; RRD
378 defb 'R','R'+$80 ; RR
379 defb 'R','S','T'+$80 ; RST
380 defb 'S','B','C'+$80 ; SBC
381 defb 'S','C','F'+$80 ; SCF
382 defb 'S','E','T'+$80 ; SET
383 defb 'S','L','A'+$80 ; SLA
384 defb 'S','R','A'+$80 ; SRA
385 defb 'S','R','L'+$80 ; SRL
386 defb 'S','U','B'+$80 ; SUB
387 defb 'X','O','R'+$80 ; XOR
462 $IF !DISASM_USE_HEX_PREFIX
474 $IF !DISASM_USE_HEX_PREFIX
545 $IF DISASM_USE_HEX_PREFIX
644 defb '(','C',')' +$80
648 defb 'A','F',',','A','F','\'' +$80
649 defb 'D','E',',','H','L' +$80
657 defb '(','S','P',')' +$80
671 ;********************
674 $IF !DISASM_USE_HEX_PREFIX
729 ; convert nibble (low 4 bits of A) to hexadecimal digit
731 ; OUT: A: digit ready to print
743 $IF DISASM_EINAR_OPTIMISATION
784 $IF @DISZ80_DUMP_CODE
791 $IF @DISZ80_DUMP_ADDRESS
798 $IF @DISZ80_DUMP_ADDRESS || @DISZ80_DUMP_CODE
820 ; -----------------------------------
821 ; End of John Kerr's DIS-Z80 routine.
822 ; -------------------------------------
823 dissizest = $-dissizest
824 $printf "disasm size: %d bytes", dissizest
825 dissizest = -1 ; so it won't clutter symbol table