Subversion Repositories Kolibri OS

Rev

Rev 336 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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