example driver: show current pass number
[bz80asm.git] / main.zas
blobcec7d8d9b73b68f0acd47ddac8886f880633ff7a
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
49   ; two-pass assemling
50 asm_another_pass:
51   ld    hl,msg_pass_header
52   call  printstr
53   ld    a,(LABMAN_PASS)
54   add   '0'+1
55   call  EMIT
56   ld    hl,msg_pass_footer
57   call  printstrnl
59   ld    ix,asmdest
60   ld    (BZ80ASM.PC),ix
61   ld    iy,strbuf
63 asmmore:
64   ; print line to assemble
65   $IF 0
66   push  iy
67 .dumploop:
68   ld    a,(iy)
69   or    a
70   jr    z,.dumpdone
71   cp    13
72   jr    z,.dumpdone
73   call  EMIT
74   inc   iy
75   jr    .dumploop
76 .dumpdone:
77   pop   iy
78   ld    a,13
79   call  EMIT
80   $ENDIF
82 doasm:
83   push  ix      ; save code destination
84   push  iy      ; we'll need it for listing
85 doasm_nopush:
86   call  BZ80ASM.ASSEM
87   jp    c,list_and_error
88 doasm_done_line:
89   ; DE is code length here
90   pop   bc      ; text starting position
91   pop   hl      ; code starting position
92   call  ASM_LISTING
94   ; check for line terminator
95   ; actually, anything except ':' is line terminator here
96   ; 0 terminates the whole buffer
97   ld    a,(iy)
98   inc   iy
99   or    a
100   jr    z,.bufferdone
101   cp    ':'
102   jr    z,asmmore
103   dec   iy
104 .skip_line:
105   ; skip current line
106   ld    a,(iy)
107   inc   iy
108   or    a
109   jr    z,.bufferdone
110   cp    13
111   jr    nz,.skip_line
112   ; check for buffer termination again
113   ; this pasta sux
114   ld    a,(iy)
115   or    a
116   jr    nz,asmmore
117 .bufferdone:
119   ; advance pass
120   call  LABMAN_ADVANCE_PASS
121   cp    2
122   jr    c,asm_another_pass
124   ; now disasm it
125   ld    hl,msg_disasm
126   call  printstrnl
128   ld    hl,OSWRCH
129   ld    (DISZ80.EMIT_CB),hl
131   push  ix
132   pop   de
133   ld    hl,asmdest
134 disloop:
135   ; HL: address to disasm
136   ; DE: end address
137   push  de
138   ex    de,hl
139   call  DISZ80.DISASM
140   ex    de,hl
141   ld    a,13
142   call  OSWRCH
143   pop   de
144   push  hl
145   or    a
146   sbc   hl,de
147   pop   hl
148   jr    c,disloop
149   ; done with disasm
151   ld    a,6
152   out   (#fe),a
153   jr    $
155 msg_disasm: defm 13,13,"--------",13,"DISASSEMBLY",13,"--------",13+#80
157 trylabel:
158   ld    hl,(BZ80ASM.PC)
159   call  LABMAN_DEFINE_LABEL
160   jr    c,bad_label_name_error
161   call  BZ80ASM.SKIP
162   ; if terminator, don't try to assemble more
163   jr    z,.linedone
164   jp    doasm_nopush
165 .linedone:
166   jp    doasm_done_line
167 .lineerr:
168   jr    list_and_error_no_label_check
171 bad_label_name_error:
172   ld    a,BZ80ASM.EXPR_ERR_INVALID_LABEL_NAME
173   jp    BZ80ASM.PARSE_EXPR_ERROR_A
175 list_and_error:
176   ; bad mnemonics?
177   ld    a,(BZ80ASM.ASM_BAD_B)
178   cp    255
179   jr    z,trylabel
181 list_and_error_no_label_check:
182   ld    hl,errline
183   call  printstrnl
184   push  iy
185   pop   hl    ; current position in text buffer
186   pop   de    ; initial position
187   ; calc length
188   or    a
189   sbc   hl,de
190   jr    z,.nothing
191   ; de: print from here
192   ; hl: length
193 .prloop:
194   ld    a,(de)
195   call  EMIT
196   inc   de
197   dec   hl
198   ld    a,h
199   or    l
200   jr    nz,.prloop
201   dec   de
202   ld    a,(de)
203   or    a
204   jr    z,.doneerrlist
205   cp    13
206   jr    z,.doneerrlist
207   inc   de
208   ld    a,'|'
209   call  EMIT
210 .nothing:
211   ld    a,(de)
212   call  EMIT
213   ld    a,(de)
214   inc   de
215   cp    13
216   jr    nz,.nothing
218 .doneerrlist:
219   ld    hl,errline
220   call  printstrnl
221   ;jp    error_syntax
222   di
223   ld    a,2
224   out   (#fe),a
225   jr    $
226 errline: defx "---------"
229 msg_pass_header:
230   defm "***************",13
231   defx "*** PASS #"
232 msg_pass_footer:
233   defm " ***",13
234   defx "***************"
236 strbuf:
237   defm  "or   c:inc a ; comment",13
238   defm  "and  (hl)",13
239   defm  "exx",13
240   defm  "label cp  69",13
241   defm  "call 0BEEFh",13
242   defm  "jr   $",13
243   defm  "jr   label",13
244   defm  "djnz label3",13
245   defm  "ld   a,40+2",13
246   defm  "ld   b,44-2",13
247   defm  "ld   c,126/3",13
248   defm  "ld   e,427%10",13
249   defm  "ld   bc,2+3*5",13
250   defm  "ld   bc,0+(2+3)*5",13
251   defm  "ld   bc,[2+3]*5",13
252   defm  "ld   bc,(2+3)*5",13
253   defm  "label3 ld   hl,16384",13
254   defm  "ld   hl,#4001",13
255   defm  "ld   a,(ix-2)",13
256   defm  "ld   c,(ix)",13
257   defm  "ld   de,$1234",13
258   defm  "ld   bc,0x5b02",13
259   defm  "ld   a,0b1001",13
260   defm  "ld   a,%1010",13
261   defm  "ld   ix,-1234",13
262   defm  "ld   iy,-0x602a",13
263   defm  "cp   1<<3",13
264   defm  "cp   8>>2",13
265   defm  "cp   ~0-1",13
266   defm  "defb 7&$c,1|2,1|(3^1),1<<15",13
267   defm  "defw 1<<15",13
268   defm  "defm '012','34'",13
269   defb  0
271 dest: defs 64,0
274 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
276 ;; show listing
277 ;; extracted from assembler code, because we don't need it there
279 ;; IN:
280 ;;   IY: current position in text buffer
281 ;;   IX: current position in code buffer
282 ;;   BC: starting position in text buffer
283 ;;   HL: starting position in code buffer
284 ;;   DE: code length
285 ;; OUT:
286 ;;   IX, IY: unchanged
287 ;;   others are dead
289 ;COUNT:  defb  0  ;PRINT POSITION
290 ASM_LISTING:
291   ld    a,d
292   or    e
293   ret   z   ; no code -- nothing to do
295   push  ix
297   ld    (.codelen),de
298   ld    (.codestart),hl
300   ; calculate original PC
301   ld    hl,(BZ80ASM.PC)
302   or    a
303   sbc   hl,de
304   ; print original PC
305   push  hl
306   ld    a,h
307   call  HEX
308   pop   hl
309   ld    a,l
310   call  HEXSP
312   ; print code bytes (if there are any)
313   ld    de,(.codelen)
314   ld    a,d
315   or    a
316   jr    nz,.nocode
317   ; do not print code if more than 4 bytes (long strings and dbs)
318   or    e
319   jr    z,.nocode
320   ; do not print code if more than 4 bytes (long strings and dbs)
321   cp    5
322   jr    nc,.nocode
324   ; print hex bytes
325   ld    hl,(.codestart)
326 .cdumploop:
327   ld    a,(hl)
328   call  HEXSP
329   inc   hl
330   dec   e
331   jr    nz,.cdumploop
332   ; align printed code
333   ld    a,(.codelen)
334 .alignloop:
335   cp    a,4
336   jr    nc,.aligndone
337   ld    e,a
338   ld    a,32
339   call  EMIT
340   ld    a,32
341   call  EMIT
342   ld    a,32
343   call  EMIT
344   ld    a,e
345   inc   a
346   jr    .alignloop
347 .aligndone:
349 .nocode:
350   ; print source line, from BC to IY (exclusive)
351   ; calculate string length
352   push  iy
353   pop   hl
354   or    a
355   sbc   hl,bc
356   jr    z,.notextline
357 .textloop:
358   ld    a,(bc)
359   call  EMIT
360   inc   bc
361   dec   hl
362   ld    a,h
363   or    l
364   jr    nz,.textloop
365 .notextline:
366   ; print final CR
367   ld    a,13
368   call  EMIT
370   pop   ix
371   ret
373 .codelen: defw 0
374 .codestart: defw 0
377 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
379 ;; print byte in hex with the trailing space
381 HEXSP:
382   call  HEX
383   ld    a,' '
384   jr    OUTCH1
387 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
389 ;; print byte in hex
391 HEX:
392   push  af
393   rrca
394   rrca
395   rrca
396   rrca
397   call  HEXOUT
398   pop   af
399 HEXOUT:
400   and   0FH
401   add   a,90H
402   daa
403   adc   a,40H
404   daa
405 OUTCH1:
406   jp    EMIT
409 LABMAN_FIRST_LABEL: defw $+2