Fasm: Fixed a bug when building programs with the length of the included file name...
[kolibrios.git] / drivers / fdo.inc
blobe4becd349c5845bff3fe948cc4edb9971eabff75
1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2 ;;                                                              ;;
3 ;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
4 ;; Distributed under terms of the GNU General Public License    ;;
5 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9 ; Formatted Debug Output (FDO)
10 ; Copyright (c) 2005-2006, mike.dld
11 ; Created: 2005-01-29, Changed: 2006-11-10
13 ; For questions and bug reports, mail to mike.dld@gmail.com
15 ; Available format specifiers are: %s, %d, %u, %x (with partial width support)
18 ; to be defined:
19 ;   __DEBUG__ equ 1
20 ;   __DEBUG_LEVEL__ equ 5
22 macro debug_func name {
23  if used name
24   name@of@func equ name
27 macro debug_beginf {
28  align 4
29  name@of@func:
32 debug_endf fix end if
34 macro DEBUGS _sign,[_str] {
35  common
36   local tp
37   tp equ 0
38   match _arg:_num,_str \{
39    DEBUGS_N _sign,_num,_arg
40    tp equ 1
41   \}
42   match =0 _arg,tp _str \{
43    DEBUGS_N _sign,,_arg
44   \}
47 macro DEBUGS_N _sign,_num,[_str] {
48  common
49   pushf
50   pushad
51   local ..str,..label,is_str
52   is_str = 0
53  forward
54   if _str eqtype ''
55    is_str = 1
56   end if
57  common
58   if is_str = 1
59    jmp ..label
60    ..str db _str,0
61    ..label:
62    add  esp,4*8+4
63    mov  edx,..str
64    sub  esp,4*8+4
65   else
66    mov  edx,_str
67   end if
68   if ~_num eq
69    if _num eqtype eax
70     if _num in <eax,ebx,ecx,edx,edi,ebp,esp>
71      mov esi,_num
72     else if ~_num eq esi
73      movzx esi,_num
74     end if
75    else if _num eqtype 0
76     mov esi,_num
77    else
78     local tp
79     tp equ 0
80     match [_arg],_num \{
81      mov esi,dword[_arg]
82      tp equ 1
83     \}
84     match =0 =dword[_arg],tp _num \{
85      mov esi,dword[_arg]
86      tp equ 1
87     \}
88     match =0 =word[_arg],tp _num \{
89      movzx esi,word[_arg]
90      tp equ 1
91     \}
92     match =0 =byte[_arg],tp _num \{
93      movzx esi,byte[_arg]
94      tp equ 1
95     \}
96     match =0,tp \{
97      'Error: specified string width is incorrect'
98     \}
99    end if
100   else
101    mov esi,0x7FFFFFFF
102   end if
103   call fdo_debug_outstr
104   popad
105   popf
108 macro DEBUGD _sign,_dec {
109  local tp
110  tp equ 0
111  match _arg:_num,_dec \{
112   DEBUGD_N _sign,_num,_arg
113   tp equ 1
114  \}
115  match =0 _arg,tp _dec \{
116   DEBUGD_N _sign,,_arg
117  \}
120 macro DEBUGD_N _sign,_num,_dec {
121  pushf
122  pushad
123  if (~_num eq)
124   if (_dec eqtype eax | _dec eqtype 0)
125    'Error: precision allowed only for in-memory variables'
126   end if
127   if (~_num in <1,2,4>)
128    if _sign
129     'Error: 1, 2 and 4 are only allowed for precision in %d'
130    else
131     'Error: 1, 2 and 4 are only allowed for precision in %u'
132    end if
133   end if
134  end if
135  if _dec eqtype eax
136   if _dec in <ebx,ecx,edx,esi,edi,ebp,esp>
137    mov eax,_dec
138   else if ~_dec eq eax
139    if _sign = 1
140     movsx eax,_dec
141    else
142     movzx eax,_dec
143    end if
144   end if
145  else if _dec eqtype 0
146   mov eax,_dec
147  else
148   add esp,4*8+4
149   if _num eq
150    mov eax,dword _dec
151   else if _num = 1
152    if _sign = 1
153     movsx eax,byte _dec
154    else
155     movzx eax,byte _dec
156    end if
157   else if _num = 2
158    if _sign = 1
159     movsx eax,word _dec
160    else
161     movzx eax,word _dec
162    end if
163   else
164    mov eax,dword _dec
165   end if
166   sub esp,4*8+4
167  end if
168  mov cl,_sign
169  call fdo_debug_outdec
170  popad
171  popf
174 macro DEBUGH _sign,_hex {
175  local tp
176  tp equ 0
177  match _arg:_num,_hex \{
178   DEBUGH_N _sign,_num,_arg
179   tp equ 1
180  \}
181  match =0 _arg,tp _hex \{
182   DEBUGH_N _sign,,_arg
183  \}
186 macro DEBUGH_N _sign,_num,_hex {
187  pushf
188  pushad
189  if (~_num eq) & (~_num in <1,2,3,4,5,6,7,8>)
190   'Error: 1..8 are only allowed for precision in %x'
191  end if
192  if _hex eqtype eax
193   if _hex in <eax,ebx,ecx,edx,esi,edi,ebp,esp>
194    if ~_hex eq eax
195     mov eax,_hex
196    end if
197    mov edx,8
198   else if _hex in <ax,bx,cx,dx,si,di,bp,sp>
199    if ~_hex eq ax
200     movzx eax,_hex
201    end if
202    if (_num eq)
203     mov edx,4
204    end if
205   else if _hex in <al,ah,bl,bh,cl,ch,dl,dh>
206    if ~_hex eq al
207     movzx eax,_hex
208    end if
209    if (_num eq)
210     mov edx,2
211    end if
212   end if
213  else if _hex eqtype 0
214   mov eax,_hex
215  else
216   add esp,4*8+4
217   mov eax,dword _hex
218   sub esp,4*8+4
219  end if
220  if ~_num eq
221   mov edx,_num
222  else
223   if ~_hex eqtype eax
224    mov edx,8
225   end if
226  end if
227  call fdo_debug_outhex
228  popad
229  popf
232 ;-----------------------------------------------------------------------------
234 debug_func fdo_debug_outchar
235 debug_beginf
236         pushad
237         movzx   ecx,al
238         mov     ebx,1
239 if defined SysMsgBoard._pe_import
240         invoke  SysMsgBoard
241 else
242         stdcall SysMsgBoard
243 end if
244         popad
245         ret
246 debug_endf
248 debug_func fdo_debug_outstr
249 debug_beginf
250         mov     ebx,1
251   .l1:  dec     esi
252         js      .l2
253         movzx   ecx,byte[edx]
254         or      cl,cl
255         jz      .l2
256 if defined SysMsgBoard._pe_import
257         invoke  SysMsgBoard
258 else
259         stdcall SysMsgBoard
260 end if
261         inc     edx
262         jmp     .l1
263   .l2:  ret
264 debug_endf
266 debug_func fdo_debug_outdec
267 debug_beginf
268         or      cl,cl
269         jz      @f
270         or      eax,eax
271         jns     @f
272         neg     eax
273         push    eax
274         mov     al,'-'
275         call    fdo_debug_outchar
276         pop     eax
277     @@: push    10
278         pop     ecx
279         push    -'0'
280   .l1:  xor     edx,edx
281         div     ecx
282         push    edx
283         test    eax,eax
284         jnz     .l1
285   .l2:  pop     eax
286         add     al,'0'
287         jz      .l3
288         call    fdo_debug_outchar
289         jmp     .l2
290   .l3:  ret
291 debug_endf
293 debug_func fdo_debug_outhex
294   __fdo_hexdigits db '0123456789ABCDEF'
295 debug_beginf
296         mov     cl,dl
297         neg     cl
298         add     cl,8
299         shl     cl,2
300         rol     eax,cl
301   .l1:  rol     eax,4
302         push    eax
303         and     eax,0x0000000F
304         mov     al,[__fdo_hexdigits+eax]
305         call    fdo_debug_outchar
306         pop     eax
307         dec     edx
308         jnz     .l1
309         ret
310 debug_endf
312 ;-----------------------------------------------------------------------------
314 macro DEBUGF _level,_format,[_arg] {
315  common
316  if __DEBUG__ = 1 & _level >= __DEBUG_LEVEL__
317   local ..f1,f2,a1,a2,c1,c2,c3,..lbl
318   _debug_str_ equ __debug_str_ # a1
319   a1 = 0
320   c2 = 0
321   c3 = 0
322   f2 = 0
323   repeat ..lbl-..f1
324    virtual at 0
325     db _format,0,0
326     load c1 word from %-1
327    end virtual
328    if c1 = '%s'
329     virtual at 0
330      db _format,0,0
331      store word 0 at %-1
332      load c1 from f2-c2
333     end virtual
334     if c1 <> 0
335      DEBUGS 0,_debug_str_+f2-c2
336     end if
337     c2 = c2 + 1
338     f2 = %+1
339     DEBUGF_HELPER S,a1,0,_arg
340    else if c1 = '%x'
341     virtual at 0
342      db _format,0,0
343      store word 0 at %-1
344      load c1 from f2-c2
345     end virtual
346     if c1 <> 0
347      DEBUGS 0,_debug_str_+f2-c2
348     end if
349     c2 = c2 + 1
350     f2 = %+1
351     DEBUGF_HELPER H,a1,0,_arg
352    else if c1 = '%d' | c1 = '%u'
353     local c4
354     if c1 = '%d'
355      c4 = 1
356     else
357      c4 = 0
358     end if
359     virtual at 0
360      db _format,0,0
361      store word 0 at %-1
362      load c1 from f2-c2
363     end virtual
364     if c1 <> 0
365      DEBUGS 0,_debug_str_+f2-c2
366     end if
367     c2 = c2 + 1
368     f2 = %+1
369     DEBUGF_HELPER D,a1,c4,_arg
370    else if c1 = '\n'
371     c3 = c3 + 1
372    end if
373   end repeat
374   virtual at 0
375    db _format,0,0
376    load c1 from f2-c2
377   end virtual
378   if (c1<>0)&(f2<>..lbl-..f1-1)
379    DEBUGS 0,_debug_str_+f2-c2
380   end if
381   virtual at 0
382    ..f1 db _format,0
383    ..lbl:
384    __debug_strings equ __debug_strings,_debug_str_,<_format>,..lbl-..f1-1-c2-c3
385   end virtual
386  end if
389 macro __include_debug_strings dummy,[_id,_fmt,_len] {
390  common
391   local c1,a1,a2
392  forward
393   if defined _len & ~_len eq
394    _id:
395    a1 = 0
396    a2 = 0
397    repeat _len
398     virtual at 0
399      db _fmt,0,0
400      load c1 word from %+a2-1
401     end virtual
402     if (c1='%s')|(c1='%x')|(c1='%d')|(c1='%u')
403      db 0
404      a2 = a2 + 1
405     else if (c1='\n')
406      dw $0A0D
407      a1 = a1 + 1
408      a2 = a2 + 1
409     else
410      db c1 and 0x0FF
411     end if
412    end repeat
413    db 0
414   end if
417 macro DEBUGF_HELPER _letter,_num,_sign,[_arg] {
418  common
419   local num
420   num = 0
421  forward
422   if num = _num
423    DEBUG#_letter _sign,_arg
424   end if
425   num = num+1
426  common
427   _num = _num+1
430 macro include_debug_strings {
431  if __DEBUG__ = 1
432   match dbg_str,__debug_strings \{
433    __include_debug_strings dbg_str
434   \}
435  end if