added disassembler module by John Kerr
[bz80asm.git] / main.zas
blobda4def919eb17d29f43e1776316d69eea0071002
1   $refopt alllabels
3   org   #8000
4   ent   main
6   include "bzasm80.zas"
8 csizestart = $
9   include "labman.zas"
10 csizeend = $
11 $printf "label manager size: %d", csizeend-csizestart
13 csizestart = $
14   include "output.zas"
15 csizeend = $
16 $printf "ouput system size: %d", csizeend-csizestart
18 csizestart = $
19   ;include "output_driver_std.zas"
20   include "output_driver_4x8.zas"
21 csizeend = $
22 $printf "printing driver size: %d", csizeend-csizestart
24 ; so they won't clutter symbol table
25 csizeend = -1
26 csizestart = -1
28   include "disz80.zas"
30 asmdest equ #C000
32 main:
33   call  emitInit
35   ; setup callbacks
36   ld    hl,expr_error_cb
37   ld    (BZ80ASM.EXPR_ERROR_CB),hl
39   ld    hl,expr_error_jrfar_cb
40   ld    (BZ80ASM.ASM_JR_TOO_FAR_CB),hl
42   ld    hl,LABMAN_FIND_LABEL
43   ld    (BZ80ASM.GETLABEL_CB),hl
45   call  LABMAN_INIT
47   di
48   ld    ix,asmdest
49   ;ld    ix,(BZ80ASM.PC)
50   ld    iy,strbuf
52 asmmore:
53   ; print line to assemble
54   $IF 0
55   push  iy
56 .dumploop:
57   ld    a,(iy)
58   or    a
59   jr    z,.dumpdone
60   cp    13
61   jr    z,.dumpdone
62   call  EMIT
63   inc   iy
64   jr    .dumploop
65 .dumpdone:
66   pop   iy
67   ld    a,13
68   call  EMIT
69   $ENDIF
71 doasm:
72   push  ix      ; save code destination
73   push  iy      ; we'll need it for listing
74 doasm_nopush:
75   ;call  EXPR_STACK_RESET
76   call  BZ80ASM.ASSEM
77   jp    c,list_and_error
78 doasm_done_line:
79   pop   bc
80   pop   de
81   call  ASM_LISTING
83 .skipnl:
84   ld    a,(iy)
85   inc   iy
86   cp    13
87   jr    z,.skipnl
88   cp    ':'
89   jr    z,.skipnl
90   cp    32
91   jr    z,.skipnl
92   dec   iy
93   or    a
94   jr    nz,asmmore
96   ; now disasm it
97   ld    hl,msg_disasm
98   call  printstrnl
100   ld    hl,OSWRCH
101   ld    (DISZ80.EMIT_CB),hl
103   push  ix
104   pop   de
105   ld    hl,asmdest
106 disloop:
107   ; HL: address to disasm
108   ; DE: end address
109   push  de
110   ex    de,hl
111   call  DISZ80.DISASM
112   ex    de,hl
113   ld    a,13
114   call  OSWRCH
115   pop   de
116   push  hl
117   or    a
118   sbc   hl,de
119   pop   hl
120   jr    c,disloop
121   ; done with disasm
123   ld    a,6
124   out   (#fe),a
125   jr    $
127 msg_disasm: defm 13,13,"--------",13,"DISASSEMBLY",13,"--------",13+#80
129 trylabel:
130   ld    hl,(BZ80ASM.PC)
131   call  LABMAN_DEFINE_LABEL
132   jr    c,bad_label_name_error
133   call  BZ80ASM.SKIP
134   ; if terminator, don't try to assemble more
135   jr    z,.linedone
136   jr    doasm_nopush
137 .linedone:
138   jr    doasm_done_line
139 .lineerr:
140   jr    list_and_error_no_label_check
143 bad_label_name_error:
144   ld    a,BZ80ASM.EXPR_ERR_INVALID_LABEL_NAME
145   jp    BZ80ASM.PARSE_EXPR_ERROR_A
147 list_and_error:
148   ; bad mnemonics?
149   ld    a,(BZ80ASM.ASM_BAD_B)
150   cp    255
151   jr    z,trylabel
153 list_and_error_no_label_check:
154   ld    hl,errline
155   call  printstrnl
156   push  iy
157   pop   hl    ; current position in text buffer
158   pop   de    ; initial position
159   ; calc length
160   or    a
161   sbc   hl,de
162   jr    z,.nothing
163   ; de: print from here
164   ; hl: length
165 .prloop:
166   ld    a,(de)
167   call  EMIT
168   inc   de
169   dec   hl
170   ld    a,h
171   or    l
172   jr    nz,.prloop
173   dec   de
174   ld    a,(de)
175   or    a
176   jr    z,.doneerrlist
177   cp    13
178   jr    z,.doneerrlist
179   inc   de
180   ld    a,'|'
181   call  EMIT
182 .nothing:
183   ld    a,(de)
184   call  EMIT
185   ld    a,(de)
186   inc   de
187   cp    13
188   jr    nz,.nothing
190 .doneerrlist:
191   ld    hl,errline
192   call  printstrnl
193   ;jp    error_syntax
194   di
195   ld    a,2
196   out   (#fe),a
197   jr    $
198 errline: defx "---------"
201 strbuf:
202   defm  "or   c",13
203   defm  "and  (hl)",13
204   defm  "exx",13
205   defm  "label cp  69",13
206   defm  "call 0BEEFh",13
207   defm  "jr   $",13
208   defm  "jr   label",13
209   defm  "djnz label3",13
210   defm  "ld   a,40+2",13
211   defm  "ld   b,44-2",13
212   defm  "ld   c,126/3",13
213   defm  "ld   e,427%10",13
214   defm  "ld   bc,2+3*5",13
215   defm  "ld   bc,0+(2+3)*5",13
216   defm  "ld   bc,[2+3]*5",13
217   defm  "ld   bc,(2+3)*5",13
218   defm  "label3 ld   hl,16384",13
219   defm  "ld   hl,#4001",13
220   defm  "ld   a,(ix-2)",13
221   defm  "ld   c,(ix)",13
222   defm  "ld   de,$1234",13
223   defm  "ld   bc,0x5b02",13
224   defm  "ld   a,0b1001",13
225   defm  "ld   a,%1010",13
226   defm  "ld   ix,-1234",13
227   defm  "ld   iy,-0x602a",13
228   defm  "cp   1<<3",13
229   defm  "cp   8>>2",13
230   defm  "cp   ~0-1",13
231   defm  "defb 7&$c,1|2,1|(3^1),1<<15",13
232   defm  "defw 1<<15",13
233   defm  "defm '012','34'",13
234   defb  0
236 dest: defs 64,0
239 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
241 ;; show listing
242 ;; extracted from assembler code, because we don't need it there
244 ;; IN:
245 ;;   IY: current position in text buffer
246 ;;   IX: current position in code buffer
247 ;;   BC: starting position in text buffer
248 ;;   DE: starting position in code buffer
249 ;; OUT:
250 ;;   IX, IY: unchanged
251 ;;   others are dead
253 ;COUNT:  defb  0  ;PRINT POSITION
254 ASM_LISTING:
255   ; calculate code length
256   push  ix
258   push  ix
259   pop   hl
260   or    a
261   sbc   hl,de
262   ld    (.codelen),hl
263   ld    (.codestart),de
265   ; calculate original PC
266   ex    de,hl
267   ld    hl,(BZ80ASM.PC)
268   or    a
269   sbc   hl,de
270   ; print original PC
271   push  hl
272   ld    a,h
273   call  HEX
274   pop   hl
275   ld    a,l
276   call  HEXSP
278   ; print code bytes (if there are any)
279   ld    de,(.codelen)
280   ld    a,d
281   or    a
282   jr    nz,.nocode
283   ; do not print code if more than 4 bytes (long strings and dbs)
284   or    e
285   jr    z,.nocode
286   ; do not print code if more than 4 bytes (long strings and dbs)
287   cp    5
288   jr    nc,.nocode
290   ; print hex bytes
291   ld    hl,(.codestart)
292 .cdumploop:
293   ld    a,(hl)
294   call  HEXSP
295   inc   hl
296   dec   e
297   jr    nz,.cdumploop
298   ; align printed code
299   ld    a,(.codelen)
300 .alignloop:
301   cp    a,4
302   jr    nc,.aligndone
303   ld    e,a
304   ld    a,32
305   call  EMIT
306   ld    a,32
307   call  EMIT
308   ld    a,32
309   call  EMIT
310   ld    a,e
311   inc   a
312   jr    .alignloop
313 .aligndone:
315 .nocode:
316   ; print source line, from BC to IY (exclusive)
317   ; calculate string length
318   push  iy
319   pop   hl
320   or    a
321   sbc   hl,bc
322   jr    z,.notextline
323 .textloop:
324   ld    a,(bc)
325   call  EMIT
326   inc   bc
327   dec   hl
328   ld    a,h
329   or    l
330   jr    nz,.textloop
331 .notextline:
332   ; print final CR
333   ld    a,13
334   call  EMIT
336   pop   ix
337   ret
339 .codelen: defw 0
340 .codestart: defw 0
343 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
345 ;; print byte in hex with the trailing space
347 HEXSP:
348   call  HEX
349   ld    a,' '
350   jr    OUTCH1
353 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
355 ;; print byte in hex
357 HEX:
358   push  af
359   rrca
360   rrca
361   rrca
362   rrca
363   call  HEXOUT
364   pop   af
365 HEXOUT:
366   and   0FH
367   add   a,90H
368   daa
369   adc   a,40H
370   daa
371 OUTCH1:
372   jp    EMIT
375 LABMAN_FIRST_LABEL: defw $+2