home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ddkx86v5.zip / DDKX86 / SRC / DEV / DASD / CDROM / ATAPI / DPRINTF.ASM < prev    next >
Encoding:
Assembly Source File  |  1995-04-14  |  16.1 KB  |  596 lines

  1. ;*DDK*************************************************************************/
  2. ;
  3. ; COPYRIGHT    Copyright (C) 1995 IBM Corporation
  4. ;
  5. ;    The following IBM OS/2 WARP source code is provided to you solely for
  6. ;    the purpose of assisting you in your development of OS/2 WARP device
  7. ;    drivers. You may use this code in accordance with the IBM License
  8. ;    Agreement provided in the IBM Device Driver Source Kit for OS/2. This
  9. ;    Copyright statement may not be removed.;
  10. ;*****************************************************************************/
  11. ;****************************************************************************
  12. ;*
  13. ;* dprintf - this routine displays information on the debug terminal. it
  14. ;*         provides limited formatting, which is a subset of c's printf
  15. ;*         function
  16. ;*
  17. ;*    calling sequence:    push selector for insert 'n'
  18. ;*                push offset for insert 'n'
  19. ;*                push selector for 'n-1'
  20. ;*                push offset for 'n-1'
  21. ;*                   ...
  22. ;*                push selector for second insert
  23. ;*                push offset for second insert
  24. ;*                push selector for first insert
  25. ;*                push offset for first insert
  26. ;*                push selector raw string
  27. ;*                push offset for raw string
  28. ;*                call dprintf
  29. ;*                add sp,4 + ('n' * 4)
  30. ;*
  31. ;*            for "%w", just push one word containing the data to
  32. ;*                  be displayed. make sure that the "add sp"
  33. ;*                  cleans the stack correctly.
  34. ;*
  35. ;*            for "%z", just the repeat count, then the selector
  36. ;*                  of the area to display, and then the offset.
  37. ;*                  make sure that the "add sp" cleans the stack
  38. ;*                  correctly.
  39. ;*
  40. ;*    formatting:    prior to being displayed, the raw string is formatted
  41. ;*            by scanning it for format control sequences. as each
  42. ;*            format control sequence is encountered, it is replaced
  43. ;*            by appropriately formatted text obtained from the
  44. ;*            corresponding pointer
  45. ;*
  46. ;*            the following format control sequences are supported:
  47. ;*
  48. ;*            %c -  the corresponding far ptr points to a byte
  49. ;*                  which replaces the "%c"
  50. ;*
  51. ;*            %u -  the corresponding far ptr points to a word
  52. ;*                  which is displayed as an unsigned decimal
  53. ;*                  integer, replacing the "%u"
  54. ;*
  55. ;*            %x -  the corresponding far ptr points to a word
  56. ;*                  which is displayed as upper case hex,
  57. ;*                  replacing the "%X"
  58. ;*
  59. ;*            %lx - the corresponding far ptr points to a double
  60. ;*                  word which is displayed as upper case hex,
  61. ;*                  replacing the "%X"
  62. ;*
  63. ;*            %s -  the corresponding far ptr points to a null
  64. ;*                  terminated string which is displayed unchanged,
  65. ;*                  replacing the "%s"
  66. ;*
  67. ;*            %p -  the corresponding far ptr is displayed as upper
  68. ;*                  case hex in the format "ssss:oooo"
  69. ;*
  70. ;*            %w -  the corresponding word is displayed as upper
  71. ;*                  case hex replacing the "%w". note that in this
  72. ;*                  case, only one word is pushed onto the stack
  73. ;*                  for the %w insert
  74. ;*
  75. ;*            %z -  using the corresponding repeat count and far
  76. ;*                  pointer, a memory dump is produced. note that
  77. ;*                  in this case the stack contains a repeat count
  78. ;*                  and a far pointer to the area to dump
  79. ;*
  80. ;*            %% -  the character "%" is displayed, replacing the
  81. ;*                  "%%"
  82. ;*
  83. ;*
  84.  
  85.  
  86. .286p
  87.  
  88.  
  89. COM1_PORT    EQU    03f8h
  90. COM2_PORT    EQU    02f8h
  91.  
  92.  
  93. DEFAULT_PORT    EQU    COM1_PORT
  94.  
  95. CAR_RET     EQU    0DH
  96. LINE_FEED    EQU    0AH
  97. BELL        EQU    07H
  98. COM_LSR     EQU    05H
  99. COM_DAT     EQU    00H
  100.  
  101.  
  102.  
  103. s_frame     struc
  104.  
  105. s_bp        dw    ?        ; callers bp.
  106. s_ptr_delta    dw    ?        ; delta (in bytes) to current pointer
  107.                     ; from first pointer.
  108. s_ret        dw    ?        ; callers ip.
  109. s_string    dd    ?        ; far pointer to raw string.
  110. s_ptrs        dd    ?        ; pointer to first variable.
  111.  
  112. s_frame     ends
  113.  
  114. ;word_10000     dw     10000
  115. ;word_1000     dw     1000
  116. ;word_100     dw     100
  117. ;word_10     dw     10
  118.  
  119.  
  120. _DATA           segment dword public 'DATA'
  121.  
  122.                 extrn  _ComPort:word
  123.  
  124. _DATA           ends
  125.  
  126.  
  127. _TEXT    segment dword public 'code'
  128.     assume    cs:_TEXT,ds:_DATA
  129.  
  130. _dprintf    proc    near
  131.         public    _dprintf
  132.  
  133.  
  134.         push    0        ; zero the delta to current pointer.
  135.  
  136.         push    bp        ; save our callers bp register.
  137.         mov    bp,sp        ; point to our stack frame.
  138.  
  139.         push    ds        ; save our callers ds register.
  140.         push    es        ; save our callers es register.
  141.         pusha            ; save all other caller registers.
  142.         pushf
  143.         cli
  144.  
  145.         lds    si,ss:[bp+s_string] ; point to the raw string.
  146.  
  147. dprintf_loop:    lodsb            ; pick up a byte of the string.
  148.  
  149.         or    al,al        ; is it the end of the string?
  150.         jnz    dprintf_more    ; no, go check for format control.
  151.  
  152.         popf
  153.         popa            ; restore all other caller registers.
  154.         pop    es        ; restore our callers es register.
  155.         pop    ds        ; restore our callers ds register.
  156.         pop    bp        ; restore our callers bp register.
  157.         add    sp,2        ; unstack s_ptr_delta.
  158.  
  159.         ret            ; return to our caller.
  160.  
  161. dprintf_more:    cmp    al,'%'          ; no, is it the start of a format
  162.                     ; control sequence?
  163.         je    dprintf_type    ; yes, go see what type of sequence.
  164.         jmp    dprintf_put_ch    ; no, go display character and return.
  165.  
  166. dprintf_type:    lodsb            ; pick up a byte of the string.
  167.         cmp    al,'%'          ; is caller trying to display "%"?
  168.  
  169.         jne    dprintf_try_c    ; no, go see if it is a "c".
  170.  
  171.         mov    al,'%'          ; yes, go display it
  172.         jmp    dprintf_put_ch    ; and exit.
  173.  
  174. dprintf_try_c:    cmp    al,'c'          ; is it a string display?
  175.         jne    dprintf_try_s    ; no, go see if it is a "s".
  176.  
  177.         lea    bx,[bp]+s_ptrs           ; yes, pick up the
  178.         add    bx,ss:[bp+s_ptr_delta] ; corresponding
  179.         les    bx,ss:[bx]           ; pointer.
  180.         add    ss:[bp+s_ptr_delta],4  ; move down to next pointer.
  181.  
  182.         mov    al,es:[bx]    ; pick up a byte.
  183.         jmp    dprintf_put_ch    ; go display character and return.
  184.  
  185. dprintf_try_s:    cmp    al,'s'          ; is it a string display?
  186.         jne    dprintf_try_u    ; no, go see if it is a "u".
  187.  
  188.         lea    bx,[bp]+s_ptrs           ; yes, pick up the
  189.         add    bx,ss:[bp+s_ptr_delta] ; corresponding
  190.         les    bx,ss:[bx]           ; pointer.
  191.         add    ss:[bp+s_ptr_delta],4  ; move down to next pointer.
  192.  
  193. dprintf_next_s: mov    al,es:[bx]    ; pick up a byte.
  194.  
  195.         or    al,al        ; is it the end of the string?
  196.         jz    dprintf_loop    ; yes, go do next raw string byte.
  197.  
  198.         call    put_char    ; no, display the character.
  199.  
  200.         inc    bx        ; move down to the next character
  201.         jmp    dprintf_next_s    ; and go round again.
  202.  
  203. dprintf_try_u:    cmp    al,'u'          ; is it an unsigned short display?
  204.         jne    dprintf_try_x    ; no, go see if it is a "X".
  205.  
  206.         lea    bx,[bp]+s_ptrs           ; yes, pick up the
  207.         add    bx,ss:[bp+s_ptr_delta] ; corresponding
  208.         les    bx,ss:[bx]           ; pointer.
  209.         add    ss:[bp+s_ptr_delta],4  ; move down to next pointer.
  210.  
  211.         mov    ax,es:[bx]    ; pick up the word to display.
  212.  
  213.         xor    dx,dx        ; convert the
  214.         mov    cx, 10000
  215.         div    cx        ; ten thousands
  216. ;        div    word_10000    ; ten thousands
  217.         or    al,'0'          ; digit and
  218.         call    put_char    ; display it.
  219.  
  220.         mov    ax,dx        ; convert the
  221.         xor    dx,dx        ; thousands
  222.         mov    cx, 1000
  223.         div    cx        ; digit
  224. ;        div    word_1000    ; digit
  225.         or    al,'0'          ; and
  226.         call    put_char    ; display it.
  227.  
  228.         mov    ax,dx        ; convert the
  229.         xor    dx,dx        ; hundreds
  230.         mov    cx, 100
  231.         div    cx        ; digit
  232. ;        div    word_100    ; digit
  233.         or    al,'0'          ; and
  234.         call    put_char    ; display it.
  235.  
  236.         mov    ax,dx        ; convert the
  237.         xor    dx,dx        ; tens
  238.         mov    cx, 10
  239.         div    cx        ; digit
  240. ;        div    word_10     ; digit
  241.         or    al,'0'          ; and
  242.         call    put_char    ; display it.
  243.  
  244.         mov    al,dl        ; convert the units digit
  245.         or    al,'0'          ; and go display it
  246.         jmp    dprintf_put_ch    ; and return.
  247.  
  248. dprintf_try_x:    cmp    al,'x'          ; is it an unsigned short hex display?
  249.         jne    dprintf_try_lx    ; no, go see if it is a "lX".
  250.  
  251.         lea    bx,[bp]+s_ptrs           ; yes, pick up the
  252.         add    bx,ss:[bp+s_ptr_delta] ; corresponding
  253.         les    bx,ss:[bx]           ; pointer.
  254.         add    ss:[bp+s_ptr_delta],4  ; move down to next pointer.
  255.  
  256.         call    put_hex_word    ; convert and display the word.
  257.  
  258.         jmp    dprintf_loop    ; go do next raw string byte.
  259.  
  260. dprintf_try_lx: cmp    al,'l'          ; is it an unsigned long hex display?
  261.         jne    dprintf_try_p    ; no, go see if it is a "p".
  262.         lodsb            ; maybe, pick up a byte of the string.
  263.         cmp    al,'x'          ; is the second byte correct?
  264.         je    dprintf_do_lx    ; no, go report
  265.         jmp    dprintf_error    ; the error.
  266.  
  267. dprintf_do_lx:    lea    bx,[bp]+s_ptrs           ; yes, pick up the
  268.         add    bx,ss:[bp+s_ptr_delta] ; corresponding
  269.         les    bx,ss:[bx]           ; pointer.
  270.         add    ss:[bp+s_ptr_delta],4  ; move down to next pointer.
  271.  
  272.         add    bx,2        ; move down to the second word.
  273.         call    put_hex_word    ; convert and display the second word.
  274.         sub    bx,2        ; move back to the first word.
  275.         call    put_hex_word    ; convert and display the first word.
  276.  
  277.         jmp    dprintf_loop    ; go do next raw string byte.
  278.  
  279. dprintf_try_p:    cmp    al,'p'          ; is it a far pointer display?
  280.         jne    dprintf_try_w    ; no, go see if it is a "w".
  281.  
  282.         lea    bx,[bp]+s_ptrs           ; yes, pick up the
  283.         add    bx,ss:[bp+s_ptr_delta] ; corresponding pointer.
  284.         add    ss:[bp+s_ptr_delta],4  ; move down to next pointer.
  285.  
  286.         push    es        ; save the callers data selector.
  287.  
  288.         push    ss        ; set up the proper
  289.         pop    es        ; selector.
  290.  
  291.         add    bx,2        ; move down to the second word.
  292.         call    put_hex_word    ; convert and display the selector.
  293.         mov    al,':'          ; display
  294.         call    put_char    ; the ":".
  295.         sub    bx,2        ; move back to the first word.
  296.         call    put_hex_word    ; convert and display the offset.
  297.  
  298.         mov    al,' '          ; display
  299.         call    put_char    ; a couple
  300.         mov    al,' '          ; of
  301.         call    put_char    ; spaces.
  302.  
  303.         pop    es        ; recover the callers data selector.
  304.  
  305.         jmp    dprintf_loop    ; go do next raw string byte.
  306.  
  307. dprintf_try_w:    cmp    al,'w'          ; is it an immediate word display?
  308.         jne    dprintf_try_z    ; no, go see if it is a "z".
  309.  
  310.         lea    bx,[bp]+s_ptrs           ; yes, pick up the
  311.         add    bx,ss:[bp+s_ptr_delta] ; corresponding pointer.
  312.         add    ss:[bp+s_ptr_delta],2  ; move down to next pointer.
  313.  
  314.         push    es        ; save the callers data selector.
  315.  
  316.         push    ss        ; set up the proper
  317.         pop    es        ; selector.
  318.  
  319.         call    put_hex_word    ; convert and display the word.
  320.  
  321.         pop    es        ; recover the callers data selector.
  322.  
  323.         jmp    dprintf_loop    ; go do next raw string byte.
  324.  
  325. dprintf_try_z:    cmp    al,'z'          ; is it a memory dump display?
  326.         je    dprintf_do_z    ; no, go report
  327.         jmp    dprintf_error    ; the error.
  328.  
  329. dprintf_do_z:
  330.         lea    bx,[bp]+s_ptrs           ; yes, pick up the
  331.         add    bx,ss:[bp+s_ptr_delta] ; corresponding pointer.
  332.         add    ss:[bp+s_ptr_delta],6  ; move down to next pointer.
  333.  
  334.         mov    cx,ss:[bx+4]    ; pick up the repeat count.
  335.  
  336.         push    es        ; save the callers data selector.
  337.  
  338.         les    bx,ss:[bx]    ; point to the area to display.
  339.  
  340. dprintf_z_a:    mov    ax,es        ; pick up the selector to display.
  341.         xchg    ah,al        ; set up to process the first byte.
  342.         call    put_left_nib    ; display the first byte
  343.         call    put_right_nib    ; of the selector.
  344.         xchg    ah,al        ; set up to process the second byte.
  345.         call    put_left_nib    ; display the second byte
  346.         call    put_right_nib    ; of the selector.
  347.  
  348.         mov    al,':'          ; display a
  349.         call    put_char    ; colon.
  350.  
  351.         mov    ax,bx        ; pick up the offset to display.
  352.         xchg    ah,al        ; set up to process the first byte.
  353.         call    put_left_nib    ; display the first byte
  354.         call    put_right_nib    ; of the offset.
  355.         xchg    ah,al        ; set up to process the second byte.
  356.         call    put_left_nib    ; display the second byte
  357.         call    put_right_nib    ; of the offset.
  358.  
  359.         mov    al,' '          ; display
  360.         call    put_char    ; two
  361.         mov    al,' '          ; seperating
  362.         call    put_char    ; spaces.
  363.  
  364.         push    cx        ; save the repeat count for later.
  365.  
  366.         mov    dx,16*3+1    ; initialize the fill count.
  367.  
  368.         cmp    cx,16        ; are there more than 16 bytes left?
  369.         jbe    dprintf_z_b    ; yes, limit it to 16 bytes
  370.         mov    cx,16        ; for this line.
  371.  
  372. dprintf_z_b:    push    bx        ; save offset and display count
  373.         push    cx        ; for the character display.
  374.  
  375. dprintf_z_c:    mov    al,es:[bx]    ; pick up a byte to display.
  376.         call    put_hex_byte    ; display it in hex.
  377.  
  378.         mov    al,' '          ; set up to display a space.
  379.         cmp    dx,9*3+1    ; should it be a dash?
  380.         jne    dprintf_z_e    ; no, bypass changing it.
  381.         mov    al,'-'          ; yes, set up to display a dash.
  382. dprintf_z_e:    call    put_char    ; display the dash or space.
  383.  
  384.         sub    dx,3        ; down the fill count by one position.
  385.  
  386.         inc    bx        ; move down to the next byte.
  387.  
  388.         loop    dprintf_z_c    ; more to do? yes, go round again?
  389.  
  390.         mov    cx,dx        ; no, pick up remaining fill count.
  391.  
  392. dprintf_z_g:    mov    al,' '          ; display a
  393.         call    put_char    ; space.
  394.  
  395.         loop    dprintf_z_g    ; more to do? yes, go round again.
  396.  
  397.         pop    cx        ; recover the offset and
  398.         pop    bx        ; display count.
  399.  
  400. dprintf_z_i:    mov    al,'.'          ; set up to display a dot.
  401.  
  402.         mov    ah,es:[bx]    ; does the byte
  403.         cmp    ah,20h        ; contain a
  404.         jb    dprintf_z_k    ; valid ascii
  405.         cmp    ah,7fh        ; code?
  406.         ja    dprintf_z_k    ; no, go display the dot.
  407.  
  408.         xchg    al,ah        ; yes, set up to do byte's contents.
  409.  
  410. dprintf_z_k:    call    put_char    ; display a dot or the byte contents.
  411.  
  412.         inc    bx        ; move down to the next byte.
  413.  
  414.         loop    dprintf_z_i    ; more to do on this line?
  415.                     ; yes, go round again.
  416.  
  417.         pop    cx        ; no, recover the repeat count.
  418.  
  419.         sub    cx,16        ; down the repeat count by one line.
  420.  
  421.         jle    dprintf_z_z    ; more to do? no, go exit.
  422.  
  423.         mov    al,CAR_RET    ; perform
  424.         call    put_char    ; a
  425.         mov    al,LINE_FEED    ; new line
  426.         call    put_char    ; operation.
  427.  
  428.         jmp    dprintf_z_a    ; go round and display another line.
  429.  
  430. dprintf_z_z:    pop    es        ; recover the callers data selector.
  431.  
  432.         jmp    dprintf_loop    ; go do next raw string byte.
  433.  
  434. dprintf_error:    mov    ah,al        ; display
  435.         mov    al,'?'          ; an
  436.         call    put_char    ; eye
  437.         mov    al,'\'          ; catching
  438.         call    put_char    ; "invalid
  439.         mov    al,ah        ; format
  440.         call    put_char    ; control"
  441.         mov    al,'\'          ; message
  442.         call    put_char    ; and
  443.         mov    al,BELL     ; beep.
  444.  
  445. dprintf_put_ch: call    put_char    ; display the character.
  446.         jmp    dprintf_loop    ; go process next raw string byte.
  447.  
  448. _dprintf    endp
  449.  
  450. put_left_nib    proc    near
  451.  
  452.         push    ax        ; save the callers ax register.
  453.  
  454.         shr    al,4        ; convert the
  455.         add    al,'0'          ; left nibble
  456.         cmp    al,'9'          ; to an ascii
  457.         jbe    put_left_nib_a    ; hex
  458.         add    al,'A'-'9'-1    ; representation.
  459. put_left_nib_a: call    put_char    ; display the character.
  460.  
  461.         pop    ax        ; restore the callers ax register.
  462.  
  463.         ret            ; return to our caller.
  464.  
  465. put_left_nib    endp
  466.  
  467. put_right_nib    proc    near
  468.  
  469.         push    ax        ; save the callers ax register.
  470.  
  471.         and    al,0fh        ; convert the
  472.         add    al,'0'          ; right nibble
  473.         cmp    al,'9'          ; to an
  474.         jbe    put_rght_nib_a    ; ascii hex
  475.         add    al,'A'-'9'-1    ; representation.
  476. put_rght_nib_a: call    put_char    ; display the character.
  477.  
  478.         pop    ax        ; restore the callers ax register.
  479.  
  480.         ret            ; return to our caller
  481.  
  482. put_right_nib    endp
  483.  
  484. put_hex_byte    proc    near
  485.  
  486.         mov    al,es:[bx]    ; display the left nibble
  487.         call    put_left_nib    ; in ascii hex.
  488.  
  489.         mov    al,es:[bx]    ; display the right nibble
  490.         call    put_right_nib    ; in ascii hex.
  491.  
  492.         ret            ; return to our caller.
  493.  
  494. put_hex_byte    endp
  495.  
  496.  
  497. put_hex_word    proc    near
  498.  
  499.         inc    bx        ; set up to process second byte first.
  500.  
  501.         call    put_hex_byte    ; display the byte in hex.
  502.  
  503.         dec    bx        ; move back to the first byte.
  504.  
  505.         call    put_hex_byte    ; display the byte in hex.
  506.  
  507.         ret            ; return to our caller.
  508.  
  509. put_hex_word    endp
  510.  
  511.  
  512. ;         public  portadr
  513. ;portadr     dw     DEFAULT_PORT     ; change config.h to change this.
  514.                     ; use: com2=02f8H, com1=03f8H
  515.  
  516. IODelay Macro
  517.     local a
  518.     jmp a
  519. a:
  520. endm
  521.  
  522. PollC    PROC    NEAR
  523.     public    PollC
  524.  
  525. ;    mov    dx, cs:PortAdr
  526.     mov    dx, _ComPort
  527.     add    dx, COM_LSR
  528.  
  529.     in    al,dx            ; get input status
  530. ;    IODelay
  531.  
  532.     and    al,1            ; is there a char in RECV buffer?
  533.     jz    plc1            ; no, go return empty
  534.  
  535. ;    mov    dx, cs:PortAdr
  536.     mov    dx, _ComPort
  537.     add    dx, COM_DAT
  538.  
  539.     in    al,dx            ;      char out of buffer
  540. ;    IODelay
  541.  
  542.     and    al,07fh         ; strip off        parity crap
  543. plc1:    ret
  544. PollC    ENDP
  545.  
  546.  
  547. ;**    PUTC - output a single char to COM2 handling ^S
  548.  
  549.  
  550. put_char    proc    near
  551.         public    put_char
  552.  
  553.     push    dx
  554.     push    ax
  555.  
  556. ;    See if ^S
  557.  
  558.     call    PollC            ; is there a char at input
  559.     jz    pc2            ; no, go output our char
  560.     cmp    al,'S' - 'A' + 1    ; is it ^S?
  561.     jnz    pc2            ; no, go output our char
  562.  
  563. ;    Saw ^S.  Wait for and eat next char.
  564.  
  565. pc1:    call    PollC            ; look for next char
  566.     jz    pc1            ; no char, go look again
  567.     cmp    al,'S' - 'A' + 1    ; is it ^S again?
  568.     jz    pc1            ; yes, go look for something else
  569.  
  570. ;pc2:     mov     dx, cs:PortAdr
  571. pc2:    mov    dx, _ComPort
  572.     add    dx, COM_LSR
  573.     in    al,dx
  574. ;    IODelay
  575.     test    al,020h
  576.     jz    pc2
  577.  
  578. ;    ready.    crank it out!
  579.  
  580. ;    mov    dx, cs:PortAdr
  581.     mov    dx, _ComPort
  582.     add    dx, COM_DAT
  583.     pop    ax
  584.     out    dx,al
  585.  
  586.         pop    dx        ; restore the callers dx register.
  587.  
  588.     ret
  589.  
  590. put_char    endp
  591.  
  592. _TEXT    ends
  593.     end
  594.  
  595.