Subversion Repositories Kolibri OS

Rev

Rev 9715 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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