Subversion Repositories Kolibri OS

Rev

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