Subversion Repositories Kolibri OS

Rev

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