Subversion Repositories Kolibri OS

Rev

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

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