Subversion Repositories Kolibri OS

Rev

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