Subversion Repositories Kolibri OS

Rev

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

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