some cosmetix in asm; more comments
[bz80asm.git] / labman.zas
blob2a36d206faf45a177c6188361e767732acd40363
1 ; label manager
3 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4 LABMAN_INIT:
5   ld    hl,(LABMAN_FIRST_LABEL)
6   ld    (hl),0
7   ret
9 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11 ;; find a label
13 ;; IN:
14 ;;   IY: text input buffer
15 ;; OUT:
16 ;;   IY: text input buffer after the label
17 ;;   HL: points to label data area
18 ;;   CARRY RESET
19 ;;  OR:
20 ;;   IY: original
21 ;;   HL: points after the last label
22 ;;   CARRY SET
23 ;; AF is dead, other registers are preserved
25 labman_find:
26   ld    (.saved_iy),iy
27   ld    hl,(LABMAN_FIRST_LABEL)
28 .labman_loop:
29   ld    a,(hl)
30   or    a
31   jr    z,.not_found
32   ; check name
33   ld    iy,0    ; patched above
34 .saved_iy equ $-2
35 .check_loop:
36   ld    a,(hl)
37   and   #7F
38   cp    (iy)
39   jr    nz,.skip_label
40   inc   iy
41   bit   7,(hl)
42   inc   hl
43   jr    z,.check_loop
44   jr    .check_test_iy_end
45   ; check failed, skip label
46 .skip_label:
47   ld    a,(hl)
48   inc   hl
49   or    a
50   jr    nz,.skip_label
51 .skip_label_data_area:
52   ; skip value
53   inc   hl
54   inc   hl
55   ; skip pass flag
56   inc   hl
57   jr    .labman_loop
59 .check_test_iy_end:
60   ld    a,(iy)
61   call  isIdChar
62   ; if ok, carry is set (non-id char)
63   ; inverse it for correct return result
64   ccf
65   ret   nc
66   jr    .skip_label_data_area
68 .not_found:
69   ld    iy,(.saved_iy)
70   scf
71   ret
74 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
76 ;;  this is called by the driver to define a new label
78 ;; IN:
79 ;;   IY: text input buffer
80 ;; OUT:
81 ;;   IY: text input buffer after the label
83 LABMAN_DEFINE_LABEL:
84   ld    a,0
85   ld    (LABMAN_NEW_LABEL_FLAG),a
86   call  labman_find
87   jr    c,LABMAN_FIND_LABEL_create_new_label
88   ; existing label: check if it is a forward reference
89   inc   hl
90   inc   hl
91   ld    a,(hl)
92   inc   a
93   jr    z,.fwd_label
94   ld    a,BZ80ASM.EXPR_ERR_DUPLICATE_LABEL
95   jp    BZ80ASM.PARSE_EXPR_ERROR_A
96 .fwd_label:
97   ; reset "forward" flag
98   ld    (hl),a
99   ; set value (PC)
100   dec   hl
101   dec   hl
102   ld    de,(BZ80ASM.PC)
103   ld    (hl),e
104   inc   hl
105   ld    (hl),d
106   ret
109 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
111 ;; find a label
112 ;; see full documentation in "bz80asm.zas"
114 ;; IN:
115 ;;   IY: text input buffer
116 ;; OUT:
117 ;;   IY: text input buffer after the label
118 ;;   HL: label value
119 ;;   CARRY FLAG: set if label wasn't found
120 ;;               expression parser will bomb out in this case
122 LABMAN_FIND_LABEL:
123   ld    a,#FF
124   ld    (LABMAN_NEW_LABEL_FLAG),a
126   call  labman_find
127   jr    c,.create_new_label
128   ; old label, return value
129   ld    e,(hl)
130   inc   hl
131   ld    d,(hl)
132   ex    de,hl
133   ret
135 @LABMAN_FIND_LABEL_create_new_label:
136 .create_new_label:
137   ld    a,(iy)
138   call  isAlpha
139   jr    nc,.good_start
140   cp    '_'
141   jr    nc,.good_start
142   cp    '.'
143   scf
144   ret   nz
145   ld    a,EXPR_ERR_NO_LOCAL_LABELS_YET
146   jp    BZ80ASM.PARSE_EXPR_ERROR_A
148 .good_start:
149   push  hl      ; we'll use this later to print a name
150   ; HL points to the memory where our new label should be put
151   ; copy label name there
152 .idloop:
153   ld    a,(iy)
154   call  isIdChar
155   jr    c,.idend
156   ld    (hl),a
157   inc   hl
158   inc   iy
159   jr    .idloop
160 .idend:
161   ; mark name end
162   dec   hl
163   set   7,(hl)
164   ; move to data area
165   inc   hl
166   ; assign new value
167   ld    de,(BZ80ASM.PC)
168   ld    (hl),e
169   inc   hl
170   ld    (hl),d
171   inc   hl
172   ; set "forward reference" flag
173   ld    (hl),#FF
174 @LABMAN_NEW_LABEL_FLAG equ $01
175   ; put zero to mark new label area end
176   inc   hl
177   ld    (hl),0
179   ; now print new label
180   ld    hl,msg_newlabel
181   call  printstr
182   pop   hl
183 .prloop:
184   ld    a,(hl)
185   and   #7F
186   call  EMIT
187   bit   7,(hl)
188   inc   hl
189   jr    z,.prloop
190   ld    a,'>'
191   call  EMIT
192   ld    a,13
193   call  EMIT
195   ; return new value
196   ld    hl,(BZ80ASM.PC)
197   ; reset carry (just to be sure)
198   or    a
199   ret
201 msg_newlabel: defx "NEWLABEL:<"
204 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
205 ;; check if A is an alpha char
206 ;; carry set: not an alpha char
208 isAlpha:
209   cp    'a'
210   jr    c,.notlower
211   cp    'z'+1
212   jr    nc,.notlower
213   or    a
214   ret
215 .notlower:
216   cp    'A'
217   ret   c
218   cp    'Z'+1
219   ccf
220   ret
222 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
223 ;; check if A is a decimal digit
224 ;; carry set: not a digit char
226 isDigit:
227   cp    '0'
228   ret   c
229   cp    '9'+1
230   ccf
231   ret
233 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
234 ;; check if A is a valid identifier char (including digits)
235 ;; carry set: not an id char
237 isIdChar:
238   call  isAlpha
239   ret   nc
240   call  isDigit
241   ret   nc
242   cp    '_'
243   jr    z,.goodchar
244   cp    '$'
245   jr    z,.goodchar
246   scf
247   ret
248 .goodchar:
249   or    a
250   ret