Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3520 clevermous 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6
 
7
 
8
;
9
; Formatted Debug Output (FDO)
10
; Copyright (c) 2005-2006, mike.dld
11
; Created: 2005-01-29, Changed: 2006-11-10
12
;
13
; For questions and bug reports, mail to mike.dld@gmail.com
14
;
15
; Available format specifiers are: %s, %d, %u, %x (with partial width support)
16
;
17
 
18
; to be defined:
19
;   __DEBUG__ equ 1
20
;   __DEBUG_LEVEL__ equ 5
21
 
22
macro debug_func name {
23
 if used name
24
  name@of@func equ name
25
}
26
 
27
macro debug_beginf {
28
 align 4
29
 name@of@func:
30
}
31
 
32
debug_endf fix end if
33
 
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
  \}
45
}
46
 
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 
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
106
}
107
 
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
 \}
118
}
119
 
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 
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
172
}
173
 
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
 \}
184
}
185
 
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 
194
   if ~_hex eq eax
195
        mov     eax, _hex
196
   end if
197
        mov     edx, 8
198
  else if _hex in 
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 
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
230
}
231
 
232
;-----------------------------------------------------------------------------
233
 
234
debug_func fdo_debug_outchar
235
debug_beginf
236
        pushad
237
        movzx   ebx, al
238
        mov     eax, 1
239
;        mov     ecx,sys_msg_board
240
;        call    ecx ; sys_msg_board
241
        stdcall SysMsgBoardChar
242
        popad
243
        ret
244
debug_endf
245
 
246
debug_func fdo_debug_outstr
247
debug_beginf
248
        mov     eax, 1
249
  .l1:
250
        dec     esi
251
        js      .l2
252
        movzx   ebx, byte[edx]
253
        or      bl, bl
254
        jz      .l2
255
;        mov     ecx,sys_msg_board
256
;        call    ecx ; sys_msg_board
257
        stdcall SysMsgBoardChar
258
        inc     edx
259
        jmp     .l1
260
  .l2:
261
        ret
262
debug_endf
263
 
264
debug_func fdo_debug_outdec
265
debug_beginf
266
        or      cl, cl
267
        jz      @f
268
        or      eax, eax
269
        jns     @f
270
        neg     eax
271
        push    eax
272
        mov     al, '-'
273
        call    fdo_debug_outchar
274
        pop     eax
275
    @@:
276
        push    10
277
        pop     ecx
278
        push    -'0'
279
  .l1:
280
        xor     edx, edx
281
        div     ecx
282
        push    edx
283
        test    eax, eax
284
        jnz     .l1
285
  .l2:
286
        pop     eax
287
        add     al, '0'
288
        jz      .l3
289
        call    fdo_debug_outchar
290
        jmp     .l2
291
  .l3:
292
        ret
293
debug_endf
294
 
295
debug_func fdo_debug_outhex
296
  __fdo_hexdigits db '0123456789ABCDEF'
297
debug_beginf
298
        mov     cl, dl
299
        neg     cl
300
        add     cl, 8
301
        shl     cl, 2
302
        rol     eax, cl
303
  .l1:
304
        rol     eax, 4
305
        push    eax
306
        and     eax, 0x0000000F
307
        mov     al, [__fdo_hexdigits+eax]
308
        call    fdo_debug_outchar
309
        pop     eax
310
        dec     edx
311
        jnz     .l1
312
        ret
313
debug_endf
314
 
315
;-----------------------------------------------------------------------------
316
 
317
macro DEBUGF _level,_format,[_arg] {
318
 common
319
 if __DEBUG__ = 1 & _level >= __DEBUG_LEVEL__
320
  local ..f1,f2,a1,a2,c1,c2,c3,..lbl
321
  _debug_str_ equ __debug_str_ # a1
322
  a1 = 0
323
  c2 = 0
324
  c3 = 0
325
  f2 = 0
326
  repeat ..lbl-..f1
327
   virtual at 0
328
    db _format,0,0
329
    load c1 word from %-1
330
   end virtual
331
   if c1 = '%s'
332
    virtual at 0
333
     db _format,0,0
334
     store word 0 at %-1
335
     load c1 from f2-c2
336
    end virtual
337
    if c1 <> 0
338
     DEBUGS 0,_debug_str_+f2-c2
339
    end if
340
    c2 = c2 + 1
341
    f2 = %+1
342
    DEBUGF_HELPER S,a1,0,_arg
343
   else if c1 = '%x'
344
    virtual at 0
345
     db _format,0,0
346
     store word 0 at %-1
347
     load c1 from f2-c2
348
    end virtual
349
    if c1 <> 0
350
     DEBUGS 0,_debug_str_+f2-c2
351
    end if
352
    c2 = c2 + 1
353
    f2 = %+1
354
    DEBUGF_HELPER H,a1,0,_arg
355
   else if c1 = '%d' | c1 = '%u'
356
    local c4
357
    if c1 = '%d'
358
     c4 = 1
359
    else
360
     c4 = 0
361
    end if
362
    virtual at 0
363
     db _format,0,0
364
     store word 0 at %-1
365
     load c1 from f2-c2
366
    end virtual
367
    if c1 <> 0
368
     DEBUGS 0,_debug_str_+f2-c2
369
    end if
370
    c2 = c2 + 1
371
    f2 = %+1
372
    DEBUGF_HELPER D,a1,c4,_arg
373
   else if c1 = '\n'
374
    c3 = c3 + 1
375
   end if
376
  end repeat
377
  virtual at 0
378
   db _format,0,0
379
   load c1 from f2-c2
380
  end virtual
381
  if (c1<>0)&(f2<>..lbl-..f1-1)
382
   DEBUGS 0,_debug_str_+f2-c2
383
  end if
384
  virtual at 0
385
   ..f1 db _format,0
386
   ..lbl:
387
   __debug_strings equ __debug_strings,_debug_str_,<_format>,..lbl-..f1-1-c2-c3
388
  end virtual
389
 end if
390
}
391
 
392
macro __include_debug_strings dummy,[_id,_fmt,_len] {
393
 common
394
  local c1,a1,a2
395
 forward
396
  if defined _len & ~_len eq
397
   _id:
398
   a1 = 0
399
   a2 = 0
400
   repeat _len
401
    virtual at 0
402
     db _fmt,0,0
403
     load c1 word from %+a2-1
404
    end virtual
405
    if (c1='%s')|(c1='%x')|(c1='%d')|(c1='%u')
406
     db 0
407
     a2 = a2 + 1
408
    else if (c1='\n')
409
     dw $0A0D
410
     a1 = a1 + 1
411
     a2 = a2 + 1
412
    else
413
     db c1 and 0x0FF
414
    end if
415
   end repeat
416
   db 0
417
  end if
418
}
419
 
420
macro DEBUGF_HELPER _letter,_num,_sign,[_arg] {
421
 common
422
  local num
423
  num = 0
424
 forward
425
  if num = _num
426
   DEBUG#_letter _sign,_arg
427
  end if
428
  num = num+1
429
 common
430
  _num = _num+1
431
}
432
 
433
macro include_debug_strings {
434
 if __DEBUG__ = 1
435
  match dbg_str,__debug_strings \{
436
   __include_debug_strings dbg_str
437
  \}
438
 end if
439
}