Subversion Repositories Kolibri OS

Rev

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