Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

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