Subversion Repositories Kolibri OS

Rev

Rev 3614 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  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 <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
  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 <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
  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 <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
  230. }
  231.  
  232. ;-----------------------------------------------------------------------------
  233.  
  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
  247.  
  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
  265.  
  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
  292.  
  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
  311.  
  312. ;-----------------------------------------------------------------------------
  313.  
  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
  387. }
  388.  
  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
  415. }
  416.  
  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
  428. }
  429.  
  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
  436. }
  437.