some cosmetix in asm; more comments
[bz80asm.git] / disz80.zas
blob9ded2a7f6208d2584f9a8299ddc9b13973edc7b1
1 ;  This code is been found in a ZX Spectrum tool called UTILITY3 v1.3
2   MODULE DISZ80
3 dissizest = $
5 ;; emit routine should preserve all registers except AF and HL
6 EMIT_CB: defw 0
8 CHROP:
9   push  hl
10   ld    hl,CHROP_RET
11   push  hl
12   ld    hl,(EMIT_CB)
13   jp    (hl)
14 CHROP_RET:
15   pop   hl
16   ret
18 DISASM_USE_HEX_PREFIX equ 1
19 ; Einar Saukas' optimisation, cut 2 bytes
20 DISASM_EINAR_OPTIMISATION equ 1
22 ; ====================
23 ; DIS-Z80 was published in the SUBSET column of Personal Computer World 1987.
24 ; The routine disassembles a single Z80 instruction at address DE.
25 ; It is required to be followed by a routine called CHROP that outputs a
26 ; single ASCII character.
27 ; It was originally developed for CP/M on an Amstrad CPC128.
29 ; The original ORG was $0100. I have added $5000 to all addresses.
30 ; The stated aim was to write a Z80 disassembly routine in as short a space
31 ; as possible and, at just over 1K (1090 bytes), it is a rather incredible
32 ; program.
34 ; The SUBSET editor David Barrow was able to trim only one byte from John
35 ; Kerr's compact code. I've forgotten where so there's a challenge.
37 ; k8: sadly, i had to add some mode code, so it is 1101 bytes now
38 ; (including `EMIT_CB` variable)
39 ; or 1099 bytes with Einar's optimisation ;-)
41 ; IN:
42 ;   DE: address to disasm from
43 ; OUT:
44 ;   DE: addres of the next instruction
45 ;   IX,HL,BC,AF: dead
46 ; ====================
48 DISASM:
49   call  ADRSP
50   ld    bc,$0900
51   ld    hl,$2020
53 BUFFER:
54   push  hl
55   djnz  BUFFER
56   ld    h,b
57   ld    l,c
58   add   hl,sp
60   push  bc
61   ex    (sp),ix
62   push  bc
63   push  bc
64   add   ix,sp
66   push  hl
67   ld    hl,GROUP3
69 TRYNDX:
70   call  FETCH
72   ld    b,c
73   cp    $ED
74   jr    z,CONFLG
76   inc   b
77   cp    $DD
78   jr    z,CONFLG
80   inc   b
81   cp    $FD
82   jr    nz,NOTNDX
84 CONFLG:
85   ld    (ix+1),b
86   inc   b
87   djnz  TRYNDX
89   jr    NXBYTE
91 NOTNDX:
92   ld    c,a
93   ld    a,(ix+1)
94   or    a
95   jr    z,NODISP
97   ld    a,c
98   cp    $CB
99   jr    z,GETDIS
101   and   $44
102   cp    4
103   jr    z,GETDIS
105   ld    a,c
106   and   $C0
107   cp    $40
108   jr    nz,NODISP
110 GETDIS:
111   call  FETCH
112   ld    (ix+2),a
114 NODISP:
115   ld    hl,GROUP1
116   ld    a,c
117   cp    $CB
118   jr    nz,NEWMSK
120   ld    hl,GROUP2
122 NXBYTE:
123   call  FETCH
124   ld    c,a
126 NEWMSK:
127   ld    a,(hl)
128   or    a
129   jr    z,TABEND
131   and   c
132   inc   hl
134 NEWMOD:
135   ld    b,(hl)
136   inc   hl
137   inc   b
138   jr    z,NEWMSK
140 TRYMAT:
141   cp    (hl)
142   inc   hl
143   jr    z,GETNDX
145   bit   7,(hl)
146   inc   hl
147   jr    z,TRYMAT
149   jr    NEWMOD
151 GETNDX:
152   ld    a,(hl)
153   and   $7F
154   dec   b
156 TABEND:
157   pop   hl
158   push  de
159   push  hl
161   ex    de,hl
162   ld    hl,MONICS
163   call  XTRACT
165   pop   hl
166   ld    de,5
167   add   hl,de
168   pop   de
170   ld    a,b
171   and   $F0
172   jr    z,SECOND
174   rra
175   rra
176   rra
177   rra
178   push  bc
180   ld    b,a
181   ld    a,c
182   call  OPRND1
184   pop   bc
185   ld    a,b
186   and   $0F
187   jr    z,OPDONE
189   ld    (hl),44     ;,
190   inc   hl
192 SECOND:
193   ld    a,b
194   and   $0F
196   ld    b,a
197   ld    a,c
198   call  nz,OPRND2
200 OPDONE:
201   ld    a,3
202   sub   (ix+0)
204   pop   hl
205   pop   hl
206   pop   ix
208   jr    c,OUTEXT
210   inc   a
211   ld    b,a
212   add   a,b
213   add   a,b
214   ld    b,a
216 SPACES:
217   ld    a,$20
218   call  CHROP
219   djnz  SPACES
221 OUTEXT:
222   ld  b,18
224 PUTOUT:
225   dec   sp
226   pop   hl
227   ld    a,h
228   call  CHROP
229   djnz  PUTOUT
231   ret
234 ;***********************
236 GROUP2:
237   defb  $C0,$36,$40
238   defb  $04,$80,$2D,$C0,$BE
239   defb  $FF,$F8,$06,$00,$33
240   defb  $08,$38,$10,$35,$18
241   defb  $3A,$20,$3F,$28,$40
242   defb  $30,$00,$38,$C1
245 GROUP1:
246   defb  $FF,$00,$00
247   defb  $24,$07,$32,$0F,$37
248   defb  $17,$31,$1F,$36,$27
249   defb  $0D,$2F,$0B,$37,$3D
250   defb  $3F,$06,$76,$14,$C9
251   defb  $30,$D9,$12,$F3,$0F
252   defb  $FB,$91,$72,$C6,$02
253   defb  $CE,$01,$de,$bc,$02
254   defb  $D6,$42,$E6,$03,$EE
255   defb  $43,$F6,$25,$FE,$8C
256   defb  $04,$08,$93,$01,$10
257   defb  $10,$18,$9D,$af,$22
258   defb  $A2,$FA,$2A,$A2,$A7
259   defb  $32,$A2,$7A,$3A,$A2
260   defb  $03,$C3,$1C,$CD,$85
261   defb  $97,$D3,$AA,$79,$db
262   defb  $9B,$5F,$E3,$93,$0E
263   defb  $E9,$9C,$05,$EB,$93
264   defb  $DF,$F9,$A2,$FF,$C0
265   defb  $B6,$40,$A2,$FF,$F8
266   defb  $76,$80,$02,$88,$01
267   defb  $98,$bc,$06,$90,$42
268   defb  $A0,$03,$A8,$43,$B0
269   defb  $25,$B8,$8C,$FF,$C7
270   defb  $0B,$04,$16,$05,$8E
271   defb  $B2,$06,$A2,$20,$C0
272   defb  $B0,$23,$C2,$1C,$C4
273   defb  $85,$10,$C7,$BB,$FF
274   defb  $CF,$D3,$01,$A2,$0D
275   defb  $03,$16,$0B,$8E,$FD
276   defb  $09,$82,$60,$C1,$2B
277   defb  $C5,$AC,$FF,$E7,$21
278   defb  $20,$9D,$FF,$EF,$E7
279   defb  $02,$A2,$7E,$0A,$A2
282 GROUP3:
283   defb  $FF,$00,$44
284   defb  $23,$45,$2F,$4D,$2E
285   defb  $4E,$00,$67,$39,$6F
286   defb  $34,$70,$00,$71,$00
287   defb  $A0,$21,$A1,$0A,$A2
288   defb  $1A,$A3,$29,$A8,$1F
289   defb  $A9,$08,$AA,$18,$AB
290   defb  $28,$B0,$20,$B1,$09
291   defb  $B2,$19,$B3,$27,$B8
292   defb  $1E,$B9,$07,$BA,$17
293   defb  $BB,$A6,$FF,$C7,$B8
294   defb  $40,$9B,$8B,$41,$AA
295   defb  $FF,$CF,$FD,$42,$3C
296   defb  $4A,$81,$AD,$43,$A2
297   defb  $DA,$4B,$A2,$FF,$E7
298   defb  $40,$46,$95,$FF,$F7
299   defb  $C7,$47,$A2,$7C,$57
300   defb  $A2,$FF,$00
302 ;_______________
304 MONICS:
305   defb  $BF
306   defb  'A','D','C'+$80     ; ADC
307   defb  'A','D','D'+$80     ; ADD
308   defb  'A','N','D'+$80     ; AND
309   defb  'B','I','T'+$80     ; BIT
310   defb  'C','A','L','L'+$80 ; CALL
311   defb  'C','C','F'+$80     ; CCF
312   defb  'C','P','D','R'+$80 ; CPDR
313   defb  'C','P','D'+$80     ; CPD
314   defb  'C','P','I','R'+$80 ; CPIR
315   defb  'C','P','I'+$80     ; CPI
316   defb  'C','P','L'+$80     ; CPL
317   defb  'C','P'+$80       ; CP
318   defb  'D','A','A'+$80     ; DAA
319   defb  'D','E','C'+$80     ; DEC
320   defb  'D','I'+$80       ; DI
321   defb  'D','J','N','Z'+$80 ; DJNZ
322   defb  'E','I'+$80       ; EI
323   defb  'E','X','X'+$80     ; EXX
324   defb  'E','X'+$80       ; EX
325   defb  'H','A','L','T'+$80 ; HALT
326   defb  'I','M'+$80       ; IM
327   defb  'I','N','C'+$80     ; INC
328   defb  'I','N','D','R'+$80 ; INDR
329   defb  'I','N','D'+$80     ; IND
330   defb  'I','N','I','R'+$80 ; INIR
331   defb  'I','N','I'+$80     ; INI
332   defb  'I','N'+$80       ; IN
333   defb  'J','P'+$80       ; JP
334   defb  'J','R'+$80       ; JR
335   defb  'L','D','D','R'+$80 ; LDDR
336   defb  'L','D','D'+$80     ; LDD
337   defb  'L','D','I','R'+$80 ; LDIR
338   defb  'L','D','I'+$80     ; LDI
339   defb  'L','D'+$80       ; LD
340   defb  'N','E','G'+$80     ; NEG
341   defb  'N','O','P'+$80     ; NOP
342   defb  'O','R'+$80       ; OR
343   defb  'O','T','D','R'+$80 ; OTDR
344   defb  'O','T','I','R'+$80 ; OTIR
345   defb  'O','U','T','D'+$80 ; OUTD
346   defb  'O','U','T','I'+$80 ; OUTI
347   defb  'O','U','T'+$80     ; OUT
348   defb  'P','O','P'+$80     ; POP
349   defb  'P','U','S','H'+$80 ; PUSH
350   defb  'R','E','S'+$80     ; RES
351   defb  'R','E','T','I'+$80 ; RETI
352   defb  'R','E','T','N'+$80 ; RETN
353   defb  'R','E','T'+$80     ; RET
354   defb  'R','L','A'+$80     ; RLA
355   defb  'R','L','C','A'+$80 ; RLCA
356   defb  'R','L','C'+$80     ; RLC
357   defb  'R','L','D'+$80     ; RLD
358   defb  'R','L'+$80       ; RL
359   defb  'R','R','A'+$80     ; RRA
360   defb  'R','R','C','A'+$80 ; RA
361   defb  'R','R','C'+$80     ; RRC
362   defb  'R','R','D'+$80     ; RRD
363   defb  'R','R'+$80       ; RR
364   defb  'R','S','T'+$80     ; RST
365   defb  'S','B','C'+$80     ; SBC
366   defb  'S','C','F'+$80     ; SCF
367   defb  'S','E','T'+$80     ; SET
368   defb  'S','L','A'+$80     ; SLA
369   defb  'S','R','A'+$80     ; SRA
370   defb  'S','R','L'+$80     ; SRL
371   defb  'S','U','B'+$80     ; SUB
372   defb  'X','O','R'+$80     ; XOR
376 ;*****************
378 OPRND1:
379   djnz  CONDIT
381 RSTADR:
382   and   $38
383   jr    DA
385 OPRND2:
386   djnz  DAT8
388 RELADR:
389   call  FETCH
390   ld    c,a
391   rla
392   sbc   a,a
393   ld    b,a
394   ex    de,hl
395   push  hl
396   add   hl,bc
397   jr    DHL
399 CONDIT:
400   rra
401   rra
402   rra
403   djnz  BITNUM
405   bit   4,a
406   jr    nz,ABS
408   and   3
410 ABS:
411   and   7
412   add   a,$14
413   jr    PS1
415 DAT8:
416   djnz  DAT16
419   call  FETCH
420   jr    DA
422 BITNUM:
423   djnz  INTMOD
424   and   7
427   ld    c,a
428   sub   a
429   jr    DAC
431 DAT16:
432   djnz  EXAF
434 D16:
435   call  FETCH
436   ld    c,a
437   call  FETCH
439 DAC:
440   ex    de,hl
441   push  hl
442   ld    h,a
443   ld    l,c
445 DHL:
446   push  hl
447   $IF !DISASM_USE_HEX_PREFIX
448   ld    c,$F8
449   $ELSE
450   or    a
451   $ENDIF
452   call  CONVHL
453   pop   hl
454   ld    bc,$000A
455   or    a
456   sbc   hl,bc
457   pop   hl
458   ex    de,hl
459   $IF !DISASM_USE_HEX_PREFIX
460   ret   c
462   ; hex suffix
463   ld    (hl),'H'
464   inc   hl
465   $ENDIF
466   ret
468 INTMOD:
469   djnz  STKTOP
470   and   3
471   add   a,$1C
473 PS1:
474   jr    PS3
476 STKTOP:
477   ld    c,$13
478   dec   b
479   jr    z,PS2
481 REG16P:
482   djnz  COMMON
483   rra
484   and   3
485   cp    3
486   jr    nz,RX
488   dec   a
489   jr    RNX
491 EXAF:
492   ld    c,$0A
493   dec   b
494   jr    z,PS2
496 EXDE:
497   inc   c
498   dec   b
499   jr    z,PS2
501 REG8S:
502   djnz  ACCUM
505   and   7
506   cp    6
507   jr    nz,PS3
509   ld    (hl),'('
510   inc   hl
511   call  REGX
512   ld    a,(ix+2)
513   or    a
514   jr    z,RP
516   ld    (hl),43     ;+
517   rlca
518   rrca
519   jr    nc,POS
521   ld    (hl),45     ;-
522   neg
524 POS:
525   inc   hl
526   ex    de,hl
527   push  hl
528   ld    h,b
529   ld    l,a
530   $IF DISASM_USE_HEX_PREFIX
531   ld    c,$FB
532   else
533   scf
534   $ENDIF
535   call  CONVHL
536   pop   hl
537   ex    de,hl
538   jr    RP
540 ACCUM:
541   rra
542   rra
543   rra
545 COMMON:
546   ld    c,7
547   dec   b
548   jr    z,PS2
550 PORTC:
551   dec   c
552   djnz  IDAT8
554 PS2:
555   ld    a,c
556 PS3:
557   jr    PS4
559 IDAT8:
560   djnz  IDAT16
561   ld    (hl),'('
562   inc   hl
563   call  D8
564   jr    RP
566 IDAT16:
567   djnz  REG8
568   ld    (hl),'('
569   inc   hl
570   call  D16
571   jr    RP
573 REG8:
574   dec   b
575   jr    z,R8
577 IPAREF:
578   djnz  REG16
579   and   9
580   jr    PS4
582 REG16:
583   rra
584   djnz  IREG16
586 R16:
587   and   3
589   cp    2
590   jr    z,REGX
592 RNX:
593   add   a,$0C
594   jr    PS4
596 IREG16:
597   djnz  REGX
598   ld    (hl),'('
599   inc   hl
600   call  R16
603   ld    (hl),')'
604   inc   hl
605   ret
607 REGX:
608   ld    a,(ix+1)
609   add   a,$10
611 PS4:
612   ex    de,hl
613   push  hl
614   ld    hl,RGSTRS
615   call  XTRACT
616   pop   hl
617   ex    de,hl
618   ret
620 ;*************
622 RGSTRS:
623   defb  'B'       +$80
624   defb  'C'             +$80
625   defb  'D'             +$80
626   defb  'E'             +$80
627   defb  'H'             +$80
628   defb  'L'             +$80
629   defb  '(','C',')'       +$80
630   defb  'A'             +$80
631   defb  'I'             +$80
632   defb  'R'             +$80
633   defb  'A','F',',','A','F','\''    +$80
634   defb  'D','E',',','H','L'       +$80
635   defb  'B','C'                 +$80
636   defb  'D','E'                 +$80
637   defb  'A','F'                 +$80
638   defb  'S','P'                 +$80
639   defb  'H','L'                 +$80
640   defb  'I','X'                 +$80
641   defb  'I','Y'                 +$80
642   defb  '(','S','P',')'           +$80
643   defb  'N','Z'                 +$80
644   defb  'Z'                   +$80
645   defb  'N','C'                 +$80
646   defb  'C'                   +$80
647   defb  'P','O'                 +$80
648   defb  'P','E'                 +$80
649   defb  'P'                   +$80
650   defb  'M'                   +$80
651   defb  '0'           +$80
652   defb  '?'           +$80
653   defb  '1'           +$80
654   defb  '2'           +$80
656 ;********************
658 CONVHL:
659 $IF !DISASM_USE_HEX_PREFIX
660   sub   a
662 CVHL1:
663   push  af
664   sub   a
665   ld    b,16
667 CVHL2:
668   add   a,c
669   jr    c,CVHL3
670   sub   c
672 CVHL3:
673   adc   hl,hl
674   rla
675   djnz  CVHL2
677   jr    nz,CVHL1
679   cp    10
680   inc   b
681   jr    nc,CVHL1
683 CVHL4:
684   cp  10
685   sbc   a,$69
686   daa
687   ld    (de),a
688   inc   de
689   pop   af
690   jr    nz,CVHL4
692   ret
693 $ELSE
694   ld    a,'#'
695   ld    (de),a
696   inc   de
697   jr    c,.CVHL_BYTE
699   ld    a,h
700   call  .print_byte
702 .CVHL_BYTE:
703   ld    a,l
705 .print_byte:
706   push  af
707   rrca
708   rrca
709   rrca
710   rrca
711   call  .print_nibble
712   pop   af
713 .print_nibble:
714 ; convert nibble (low 4 bits of A) to hexadecimal digit
715 ; IN: A: nibble
716 ; OUT: A: digit ready to print
717   and   a,#0F
718   cp    a,10
719   sbc   a,#69
720   daa
721   ld    (de),a
722   inc   de
723   ret
724 $ENDIF
726 ;****************
728 $IF DISASM_EINAR_OPTIMISATION
729 SKIP:
730   bit   7,(hl)
731   inc   hl
732   jr    z,SKIP
733   dec   a
734 XTRACT:
735   or    a
736   jr    nz,SKIP
738 $ELSE
740 XTRACT:
741   or    a
742   jr    z,COPY
743 SKIP:
744   bit   7,(hl)
745   inc   hl
746   jr    z,SKIP
747   dec   a
748   jr    nz,SKIP
749 $ENDIF
751 COPY:
752   ld    a,(hl)
753   rlca
754   srl   a
755   ld    (de),a
757   inc   de
758   inc   hl
759   jr    nc,COPY
761   ret
763 ;*******************
765 FETCH:
766   ld    a,(de)
767   inc   de
768   inc   (ix+0)
769   push  af
770   call  BYTSP
771   pop   af
772   ret
774 ADRSP:
775   ld    a,d
776   call  BYTOP
777   ld    a,e
779 BYTSP:
780   call  BYTOP
781   ld    a,$20
782   jp    CHROP
784 BYTOP:
785   push  af
786   rra
787   rra
788   rra
789   rra
790   call  HEXOP
791   pop   af
793 HEXOP:
794   and   $0F
795   cp    10
796   sbc   a,$69
797   daa
798   jp    CHROP
799 ; -----------------------------------
800 ; End of John Kerr's DIS-Z80 routine.
801 ; -------------------------------------
802 dissizest = $-dissizest
803 $printf "disasm size: %d bytes", dissizest
804 dissizest = -1  ; so it won't clutter symbol table
806   ENDMODULE DISZ80