Subversion Repositories Kolibri OS

Rev

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