Subversion Repositories Kolibri OS

Rev

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

  1. ;
  2. ; Formatted Debug Output (FDO)
  3. ; Copyright (c) 2005-2006, mike.dld
  4. ; Created: 2005-01-29, Changed: 2006-11-10
  5. ;
  6. ; For questions and bug reports, mail to mike.dld@gmail.com
  7. ;
  8. ; Available format specifiers are: %s, %d, %u, %x (with partial width support)
  9. ;
  10.  
  11. ; to be defined:
  12. ;   __DEBUG__ equ 1
  13. ;   __DEBUG_LEVEL__ equ 5
  14.  
  15. _esp equ esp
  16.  
  17. macro put_board {
  18.         mcall   63
  19. }
  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.         mov     edx, ..str
  62.   else
  63. esp equ esp+4*8+4
  64.         mov     edx, _str
  65. esp equ _esp
  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. esp equ esp+4*8+4
  149.   if _num eq
  150.         mov     eax, dword _dec
  151.   else if _num = 1
  152.    if _sign = 1
  153.         movsx   eax, byte _dec
  154.    else
  155.         movzx   eax, byte _dec
  156.    end if
  157.   else if _num = 2
  158.    if _sign = 1
  159.         movsx   eax, word _dec
  160.    else
  161.         movzx   eax, word _dec
  162.    end if
  163.   else
  164.         mov     eax, dword _dec
  165.   end if
  166. esp equ _esp
  167. ;  sub esp,4*8+4
  168.  end if
  169.         mov     cl, _sign
  170.         call    fdo_debug_outdec
  171.         popad
  172.         popf
  173. }
  174.  
  175. macro DEBUGH _sign,_hex {
  176.  local tp
  177.  tp equ 0
  178.  match _arg:_num,_hex \{
  179.   DEBUGH_N _sign,_num,_arg
  180.   tp equ 1
  181.  \}
  182.  match =0 _arg,tp _hex \{
  183.   DEBUGH_N _sign,,_arg
  184.  \}
  185. }
  186.  
  187. macro DEBUGH_N _sign,_num,_hex {
  188.         pushf
  189.         pushad
  190.  if (~_num eq) & (~_num in <1,2,3,4,5,6,7,8>)
  191.   'Error: 1..8 are only allowed for precision in %x'
  192.  end if
  193.  if _hex eqtype eax
  194.   if _hex in <eax,ebx,ecx,edx,esi,edi,ebp,esp>
  195.    if ~_hex eq eax
  196.         mov     eax, _hex
  197.    end if
  198.         mov     edx, 8
  199.   else if _hex in <ax,bx,cx,dx,si,di,bp,sp>
  200.    if ~_hex eq ax
  201.         movzx   eax, _hex
  202.    end if
  203.    if (_num eq)
  204.         mov     edx, 4
  205.    end if
  206.   else if _hex in <al,ah,bl,bh,cl,ch,dl,dh>
  207.    if ~_hex eq al
  208.         movzx   eax, _hex
  209.    end if
  210.    if (_num eq)
  211.         mov     edx, 2
  212.    end if
  213.   end if
  214.  else if _hex eqtype 0
  215.         mov     eax, _hex
  216.  else
  217. ;  add esp,4*8+4
  218. esp equ esp+4*8+4
  219.         mov     eax, dword _hex
  220. esp equ _esp
  221. ;  sub esp,4*8+4
  222.  end if
  223.  if ~_num eq
  224.         mov     edx, _num
  225.  else
  226.   if ~_hex eqtype eax
  227.         mov     edx, 8
  228.   end if
  229.  end if
  230.         call    fdo_debug_outhex
  231.         popad
  232.         popf
  233. }
  234.  
  235. ;-----------------------------------------------------------------------------
  236.  
  237. debug_func fdo_debug_outchar
  238. debug_beginf
  239.         pushad
  240.         movzx   ecx, al
  241.         mov     ebx, 1
  242.         put_board
  243.         popad
  244.         ret
  245. debug_endf
  246.  
  247. debug_func fdo_debug_outstr
  248. debug_beginf
  249.         mov     ebx, 1
  250.   .l1:
  251.         dec     esi
  252.         js      .l2
  253.         movzx   ecx, byte[edx]
  254.         or      cl, cl
  255.         jz      .l2
  256.         put_board
  257.         inc     edx
  258.         jmp     .l1
  259.   .l2:
  260.         ret
  261. debug_endf
  262.  
  263. debug_func fdo_debug_outdec
  264. debug_beginf
  265.         or      cl, cl
  266.         jz      @f
  267.         or      eax, eax
  268.         jns     @f
  269.         neg     eax
  270.         push    eax
  271.         mov     al, '-'
  272.         call    fdo_debug_outchar
  273.         pop     eax
  274.     @@:
  275.         movi    ecx, 10
  276.         push    -'0'
  277.   .l1:
  278.         xor     edx, edx
  279.         div     ecx
  280.         push    edx
  281.         test    eax, eax
  282.         jnz     .l1
  283.   .l2:
  284.         pop     eax
  285.         add     al, '0'
  286.         jz      .l3
  287.         call    fdo_debug_outchar
  288.         jmp     .l2
  289.   .l3:
  290.         ret
  291. debug_endf
  292.  
  293. debug_func fdo_debug_outhex
  294.   __fdo_hexdigits db '0123456789ABCDEF'
  295. debug_beginf
  296.         mov     cl, dl
  297.         neg     cl
  298.         add     cl, 8
  299.         shl     cl, 2
  300.         rol     eax, cl
  301.   .l1:
  302.         rol     eax, 4
  303.         push    eax
  304.         and     eax, 0x0000000F
  305.         mov     al, [__fdo_hexdigits+eax]
  306.         call    fdo_debug_outchar
  307.         pop     eax
  308.         dec     edx
  309.         jnz     .l1
  310.         ret
  311. debug_endf
  312.  
  313. ;-----------------------------------------------------------------------------
  314.  
  315. macro DEBUGF _level,_format,[_arg] {
  316.  common
  317.  if __DEBUG__ = 1 & _level >= __DEBUG_LEVEL__
  318.   local ..f1,f2,a1,a2,c1,c2,c3,..lbl
  319.   _debug_str_ equ __debug_str_ # a1
  320.   a1 = 0
  321.   c2 = 0
  322.   c3 = 0
  323.   f2 = 0
  324.   repeat ..lbl-..f1
  325.    virtual at 0
  326.     db _format,0,0
  327.     load c1 word from %-1
  328.    end virtual
  329.    if c1 = '%s'
  330.     virtual at 0
  331.      db _format,0,0
  332.      store word 0 at %-1
  333.      load c1 from f2-c2
  334.     end virtual
  335.     if c1 <> 0
  336.      DEBUGS 0,_debug_str_+f2-c2
  337.     end if
  338.     c2 = c2 + 1
  339.     f2 = %+1
  340.     DEBUGF_HELPER S,a1,0,_arg
  341.    else if c1 = '%x'
  342.     virtual at 0
  343.      db _format,0,0
  344.      store word 0 at %-1
  345.      load c1 from f2-c2
  346.     end virtual
  347.     if c1 <> 0
  348.      DEBUGS 0,_debug_str_+f2-c2
  349.     end if
  350.     c2 = c2 + 1
  351.     f2 = %+1
  352.     DEBUGF_HELPER H,a1,0,_arg
  353.    else if c1 = '%d' | c1 = '%u'
  354.     local c4
  355.     if c1 = '%d'
  356.      c4 = 1
  357.     else
  358.      c4 = 0
  359.     end if
  360.     virtual at 0
  361.      db _format,0,0
  362.      store word 0 at %-1
  363.      load c1 from f2-c2
  364.     end virtual
  365.     if c1 <> 0
  366.      DEBUGS 0,_debug_str_+f2-c2
  367.     end if
  368.     c2 = c2 + 1
  369.     f2 = %+1
  370.     DEBUGF_HELPER D,a1,c4,_arg
  371.    else if c1 = '\n'
  372.     c3 = c3 + 1
  373.    end if
  374.   end repeat
  375.   virtual at 0
  376.    db _format,0,0
  377.    load c1 from f2-c2
  378.   end virtual
  379.   if (c1<>0)&(f2<>..lbl-..f1-1)
  380.    DEBUGS 0,_debug_str_+f2-c2
  381.   end if
  382.   virtual at 0
  383.    ..f1 db _format,0
  384.    ..lbl:
  385.    __debug_strings equ __debug_strings,_debug_str_,<_format>,..lbl-..f1-1-c2-c3
  386.   end virtual
  387.  end if
  388. }
  389.  
  390. macro DEBUGFG _level, _group, _format, [_arg] {
  391.  common
  392.   if _group eqtype
  393.    DEBUGF _level, _format,_arg
  394.   else
  395.    if _level >= _group
  396.     DEBUGF 999, _format,_arg
  397.    end if
  398.   end if
  399. }
  400.  
  401. macro __include_debug_strings dummy,[_id,_fmt,_len] {
  402.  common
  403.   local c1,a1,a2
  404.  forward
  405.   if defined _len & ~_len eq
  406.    _id:
  407.    a1 = 0
  408.    a2 = 0
  409.    repeat _len
  410.     virtual at 0
  411.      db _fmt,0,0
  412.      load c1 word from %+a2-1
  413.     end virtual
  414.     if (c1='%s')|(c1='%x')|(c1='%d')|(c1='%u')
  415.      db 0
  416.      a2 = a2 + 1
  417.     else if (c1='\n')
  418.      dw $0A0D
  419.      a1 = a1 + 1
  420.      a2 = a2 + 1
  421.     else
  422.      db c1 and 0x0FF
  423.     end if
  424.    end repeat
  425.    db 0
  426.   end if
  427. }
  428.  
  429. macro DEBUGF_HELPER _letter,_num,_sign,[_arg] {
  430.  common
  431.   local num
  432.   num = 0
  433.  forward
  434.   if num = _num
  435.    DEBUG#_letter _sign,_arg
  436.   end if
  437.   num = num+1
  438.  common
  439.   _num = _num+1
  440. }
  441.  
  442. macro include_debug_strings {
  443.  if __DEBUG__ = 1
  444.   match dbg_str,__debug_strings \{
  445.    __include_debug_strings dbg_str
  446.   \}
  447.  end if
  448. }
  449.