home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ddkx86v5.zip / DDKX86 / SRC / DEV / DASD / IBM / IBM2SCSI / DPRINTF.ASM next >
Encoding:
Assembly Source File  |  1995-04-14  |  16.0 KB  |  589 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. _TEXT    segment word public 'code'
  121.     assume    cs:_TEXT
  122.  
  123. _dprintf    proc    near
  124.         public    _dprintf
  125.  
  126.  
  127.         push    0        ; zero the delta to current pointer.
  128.  
  129.         push    bp        ; save our callers bp register.
  130.         mov    bp,sp        ; point to our stack frame.
  131.  
  132.         push    ds        ; save our callers ds register.
  133.         push    es        ; save our callers es register.
  134.         pusha            ; save all other caller registers.
  135.         pushf
  136.         cli
  137.  
  138.         lds    si,ss:[bp+s_string] ; point to the raw string.
  139.  
  140. dprintf_loop:    lodsb            ; pick up a byte of the string.
  141.  
  142.         or    al,al        ; is it the end of the string?
  143.         jnz    dprintf_more    ; no, go check for format control.
  144.  
  145.         popf
  146.         popa            ; restore all other caller registers.
  147.         pop    es        ; restore our callers es register.
  148.         pop    ds        ; restore our callers ds register.
  149.         pop    bp        ; restore our callers bp register.
  150.         add    sp,2        ; unstack s_ptr_delta.
  151.  
  152.  
  153.         ret            ; return to our caller.
  154.  
  155. dprintf_more:    cmp    al,'%'          ; no, is it the start of a format
  156.                     ; control sequence?
  157.         je    dprintf_type    ; yes, go see what type of sequence.
  158.         jmp    dprintf_put_ch    ; no, go display character and return.
  159.  
  160. dprintf_type:    lodsb            ; pick up a byte of the string.
  161.         cmp    al,'%'          ; is caller trying to display "%"?
  162.  
  163.         jne    dprintf_try_c    ; no, go see if it is a "c".
  164.  
  165.         mov    al,'%'          ; yes, go display it
  166.         jmp    dprintf_put_ch    ; and exit.
  167.  
  168. dprintf_try_c:    cmp    al,'c'          ; is it a string display?
  169.         jne    dprintf_try_s    ; no, go see if it is a "s".
  170.  
  171.         lea    bx,[bp]+s_ptrs           ; yes, pick up the
  172.         add    bx,ss:[bp+s_ptr_delta] ; corresponding
  173.         les    bx,ss:[bx]           ; pointer.
  174.         add    ss:[bp+s_ptr_delta],4  ; move down to next pointer.
  175.  
  176.         mov    al,es:[bx]    ; pick up a byte.
  177.         jmp    dprintf_put_ch    ; go display character and return.
  178.  
  179. dprintf_try_s:    cmp    al,'s'          ; is it a string display?
  180.         jne    dprintf_try_u    ; no, go see if it is a "u".
  181.  
  182.         lea    bx,[bp]+s_ptrs           ; yes, pick up the
  183.         add    bx,ss:[bp+s_ptr_delta] ; corresponding
  184.         les    bx,ss:[bx]           ; pointer.
  185.         add    ss:[bp+s_ptr_delta],4  ; move down to next pointer.
  186.  
  187. dprintf_next_s: mov    al,es:[bx]    ; pick up a byte.
  188.  
  189.         or    al,al        ; is it the end of the string?
  190.         jz    dprintf_loop    ; yes, go do next raw string byte.
  191.  
  192.         call    put_char    ; no, display the character.
  193.  
  194.         inc    bx        ; move down to the next character
  195.         jmp    dprintf_next_s    ; and go round again.
  196.  
  197. dprintf_try_u:    cmp    al,'u'          ; is it an unsigned short display?
  198.         jne    dprintf_try_x    ; no, go see if it is a "X".
  199.  
  200.         lea    bx,[bp]+s_ptrs           ; yes, pick up the
  201.         add    bx,ss:[bp+s_ptr_delta] ; corresponding
  202.         les    bx,ss:[bx]           ; pointer.
  203.         add    ss:[bp+s_ptr_delta],4  ; move down to next pointer.
  204.  
  205.         mov    ax,es:[bx]    ; pick up the word to display.
  206.  
  207.         xor    dx,dx        ; convert the
  208.         mov    cx, 10000
  209.         div    cx        ; ten thousands
  210. ;        div    word_10000    ; ten thousands
  211.         or    al,'0'          ; digit and
  212.         call    put_char    ; display it.
  213.  
  214.         mov    ax,dx        ; convert the
  215.         xor    dx,dx        ; thousands
  216.         mov    cx, 1000
  217.         div    cx        ; digit
  218. ;        div    word_1000    ; digit
  219.         or    al,'0'          ; and
  220.         call    put_char    ; display it.
  221.  
  222.         mov    ax,dx        ; convert the
  223.         xor    dx,dx        ; hundreds
  224.         mov    cx, 100
  225.         div    cx        ; digit
  226. ;        div    word_100    ; digit
  227.         or    al,'0'          ; and
  228.         call    put_char    ; display it.
  229.  
  230.         mov    ax,dx        ; convert the
  231.         xor    dx,dx        ; tens
  232.         mov    cx, 10
  233.         div    cx        ; digit
  234. ;        div    word_10     ; digit
  235.         or    al,'0'          ; and
  236.         call    put_char    ; display it.
  237.  
  238.         mov    al,dl        ; convert the units digit
  239.         or    al,'0'          ; and go display it
  240.         jmp    dprintf_put_ch    ; and return.
  241.  
  242. dprintf_try_x:    cmp    al,'x'          ; is it an unsigned short hex display?
  243.         jne    dprintf_try_lx    ; no, go see if it is a "lX".
  244.  
  245.         lea    bx,[bp]+s_ptrs           ; yes, pick up the
  246.         add    bx,ss:[bp+s_ptr_delta] ; corresponding
  247.         les    bx,ss:[bx]           ; pointer.
  248.         add    ss:[bp+s_ptr_delta],4  ; move down to next pointer.
  249.  
  250.         call    put_hex_word    ; convert and display the word.
  251.  
  252.         jmp    dprintf_loop    ; go do next raw string byte.
  253.  
  254. dprintf_try_lx: cmp    al,'l'          ; is it an unsigned long hex display?
  255.         jne    dprintf_try_p    ; no, go see if it is a "p".
  256.         lodsb            ; maybe, pick up a byte of the string.
  257.         cmp    al,'x'          ; is the second byte correct?
  258.         je    dprintf_do_lx    ; no, go report
  259.         jmp    dprintf_error    ; the error.
  260.  
  261. dprintf_do_lx:    lea    bx,[bp]+s_ptrs           ; yes, pick up the
  262.         add    bx,ss:[bp+s_ptr_delta] ; corresponding
  263.         les    bx,ss:[bx]           ; pointer.
  264.         add    ss:[bp+s_ptr_delta],4  ; move down to next pointer.
  265.  
  266.         add    bx,2        ; move down to the second word.
  267.         call    put_hex_word    ; convert and display the second word.
  268.         sub    bx,2        ; move back to the first word.
  269.         call    put_hex_word    ; convert and display the first word.
  270.  
  271.         jmp    dprintf_loop    ; go do next raw string byte.
  272.  
  273. dprintf_try_p:    cmp    al,'p'          ; is it a far pointer display?
  274.         jne    dprintf_try_w    ; no, go see if it is a "w".
  275.  
  276.         lea    bx,[bp]+s_ptrs           ; yes, pick up the
  277.         add    bx,ss:[bp+s_ptr_delta] ; corresponding pointer.
  278.         add    ss:[bp+s_ptr_delta],4  ; move down to next pointer.
  279.  
  280.         push    es        ; save the callers data selector.
  281.  
  282.         push    ss        ; set up the proper
  283.         pop    es        ; selector.
  284.  
  285.         add    bx,2        ; move down to the second word.
  286.         call    put_hex_word    ; convert and display the selector.
  287.         mov    al,':'          ; display
  288.         call    put_char    ; the ":".
  289.         sub    bx,2        ; move back to the first word.
  290.         call    put_hex_word    ; convert and display the offset.
  291.  
  292.         mov    al,' '          ; display
  293.         call    put_char    ; a couple
  294.         mov    al,' '          ; of
  295.         call    put_char    ; spaces.
  296.  
  297.         pop    es        ; recover the callers data selector.
  298.  
  299.         jmp    dprintf_loop    ; go do next raw string byte.
  300.  
  301. dprintf_try_w:    cmp    al,'w'          ; is it an immediate word display?
  302.         jne    dprintf_try_z    ; no, go see if it is a "z".
  303.  
  304.         lea    bx,[bp]+s_ptrs           ; yes, pick up the
  305.         add    bx,ss:[bp+s_ptr_delta] ; corresponding pointer.
  306.         add    ss:[bp+s_ptr_delta],2  ; move down to next pointer.
  307.  
  308.         push    es        ; save the callers data selector.
  309.  
  310.         push    ss        ; set up the proper
  311.         pop    es        ; selector.
  312.  
  313.         call    put_hex_word    ; convert and display the word.
  314.  
  315.         pop    es        ; recover the callers data selector.
  316.  
  317.         jmp    dprintf_loop    ; go do next raw string byte.
  318.  
  319. dprintf_try_z:    cmp    al,'z'          ; is it a memory dump display?
  320.         je    dprintf_do_z    ; no, go report
  321.         jmp    dprintf_error    ; the error.
  322.  
  323. dprintf_do_z:
  324.         lea    bx,[bp]+s_ptrs           ; yes, pick up the
  325.         add    bx,ss:[bp+s_ptr_delta] ; corresponding pointer.
  326.         add    ss:[bp+s_ptr_delta],6  ; move down to next pointer.
  327.  
  328.         mov    cx,ss:[bx+4]    ; pick up the repeat count.
  329.  
  330.         push    es        ; save the callers data selector.
  331.  
  332.         les    bx,ss:[bx]    ; point to the area to display.
  333.  
  334. dprintf_z_a:    mov    ax,es        ; pick up the selector to display.
  335.         xchg    ah,al        ; set up to process the first byte.
  336.         call    put_left_nib    ; display the first byte
  337.         call    put_right_nib    ; of the selector.
  338.         xchg    ah,al        ; set up to process the second byte.
  339.         call    put_left_nib    ; display the second byte
  340.         call    put_right_nib    ; of the selector.
  341.  
  342.         mov    al,':'          ; display a
  343.         call    put_char    ; colon.
  344.  
  345.         mov    ax,bx        ; pick up the offset to display.
  346.         xchg    ah,al        ; set up to process the first byte.
  347.         call    put_left_nib    ; display the first byte
  348.         call    put_right_nib    ; of the offset.
  349.         xchg    ah,al        ; set up to process the second byte.
  350.         call    put_left_nib    ; display the second byte
  351.         call    put_right_nib    ; of the offset.
  352.  
  353.         mov    al,' '          ; display
  354.         call    put_char    ; two
  355.         mov    al,' '          ; seperating
  356.         call    put_char    ; spaces.
  357.  
  358.         push    cx        ; save the repeat count for later.
  359.  
  360.         mov    dx,16*3+1    ; initialize the fill count.
  361.  
  362.         cmp    cx,16        ; are there more than 16 bytes left?
  363.         jbe    dprintf_z_b    ; yes, limit it to 16 bytes
  364.         mov    cx,16        ; for this line.
  365.  
  366. dprintf_z_b:    push    bx        ; save offset and display count
  367.         push    cx        ; for the character display.
  368.  
  369. dprintf_z_c:    mov    al,es:[bx]    ; pick up a byte to display.
  370.         call    put_hex_byte    ; display it in hex.
  371.  
  372.         mov    al,' '          ; set up to display a space.
  373.         cmp    dx,9*3+1    ; should it be a dash?
  374.         jne    dprintf_z_e    ; no, bypass changing it.
  375.         mov    al,'-'          ; yes, set up to display a dash.
  376. dprintf_z_e:    call    put_char    ; display the dash or space.
  377.  
  378.         sub    dx,3        ; down the fill count by one position.
  379.  
  380.         inc    bx        ; move down to the next byte.
  381.  
  382.         loop    dprintf_z_c    ; more to do? yes, go round again?
  383.  
  384.         mov    cx,dx        ; no, pick up remaining fill count.
  385.  
  386. dprintf_z_g:    mov    al,' '          ; display a
  387.         call    put_char    ; space.
  388.  
  389.         loop    dprintf_z_g    ; more to do? yes, go round again.
  390.  
  391.         pop    cx        ; recover the offset and
  392.         pop    bx        ; display count.
  393.  
  394. dprintf_z_i:    mov    al,'.'          ; set up to display a dot.
  395.  
  396.         mov    ah,es:[bx]    ; does the byte
  397.         cmp    ah,20h        ; contain a
  398.         jb    dprintf_z_k    ; valid ascii
  399.         cmp    ah,7fh        ; code?
  400.         ja    dprintf_z_k    ; no, go display the dot.
  401.  
  402.         xchg    al,ah        ; yes, set up to do byte's contents.
  403.  
  404. dprintf_z_k:    call    put_char    ; display a dot or the byte contents.
  405.  
  406.         inc    bx        ; move down to the next byte.
  407.  
  408.         loop    dprintf_z_i    ; more to do on this line?
  409.                     ; yes, go round again.
  410.  
  411.         pop    cx        ; no, recover the repeat count.
  412.  
  413.         sub    cx,16        ; down the repeat count by one line.
  414.  
  415.         jle    dprintf_z_z    ; more to do? no, go exit.
  416.  
  417.         mov    al,CAR_RET    ; perform
  418.         call    put_char    ; a
  419.         mov    al,LINE_FEED    ; new line
  420.         call    put_char    ; operation.
  421.  
  422.         jmp    dprintf_z_a    ; go round and display another line.
  423.  
  424. dprintf_z_z:    pop    es        ; recover the callers data selector.
  425.  
  426.         jmp    dprintf_loop    ; go do next raw string byte.
  427.  
  428. dprintf_error:    mov    ah,al        ; display
  429.         mov    al,'?'          ; an
  430.         call    put_char    ; eye
  431.         mov    al,'\'          ; catching
  432.         call    put_char    ; "invalid
  433.         mov    al,ah        ; format
  434.         call    put_char    ; control"
  435.         mov    al,'\'          ; message
  436.         call    put_char    ; and
  437.         mov    al,BELL     ; beep.
  438.  
  439. dprintf_put_ch: call    put_char    ; display the character.
  440.         jmp    dprintf_loop    ; go process next raw string byte.
  441.  
  442. _dprintf    endp
  443.  
  444. put_left_nib    proc    near
  445.  
  446.         push    ax        ; save the callers ax register.
  447.  
  448.         shr    al,4        ; convert the
  449.         add    al,'0'          ; left nibble
  450.         cmp    al,'9'          ; to an ascii
  451.         jbe    put_left_nib_a    ; hex
  452.         add    al,'A'-'9'-1    ; representation.
  453. put_left_nib_a: call    put_char    ; display the character.
  454.  
  455.         pop    ax        ; restore the callers ax register.
  456.  
  457.         ret            ; return to our caller.
  458.  
  459. put_left_nib    endp
  460.  
  461. put_right_nib    proc    near
  462.  
  463.         push    ax        ; save the callers ax register.
  464.  
  465.         and    al,0fh        ; convert the
  466.         add    al,'0'          ; right nibble
  467.         cmp    al,'9'          ; to an
  468.         jbe    put_rght_nib_a    ; ascii hex
  469.         add    al,'A'-'9'-1    ; representation.
  470. put_rght_nib_a: call    put_char    ; display the character.
  471.  
  472.         pop    ax        ; restore the callers ax register.
  473.  
  474.         ret            ; return to our caller
  475.  
  476. put_right_nib    endp
  477.  
  478. put_hex_byte    proc    near
  479.  
  480.         mov    al,es:[bx]    ; display the left nibble
  481.         call    put_left_nib    ; in ascii hex.
  482.  
  483.         mov    al,es:[bx]    ; display the right nibble
  484.         call    put_right_nib    ; in ascii hex.
  485.  
  486.         ret            ; return to our caller.
  487.  
  488. put_hex_byte    endp
  489.  
  490.  
  491. put_hex_word    proc    near
  492.  
  493.         inc    bx        ; set up to process second byte first.
  494.  
  495.         call    put_hex_byte    ; display the byte in hex.
  496.  
  497.         dec    bx        ; move back to the first byte.
  498.  
  499.         call    put_hex_byte    ; display the byte in hex.
  500.  
  501.         ret            ; return to our caller.
  502.  
  503. put_hex_word    endp
  504.  
  505.  
  506. ;         public  portadr
  507. ;portadr     dw     DEFAULT_PORT     ; change config.h to change this.
  508.                     ; use: com2=02f8H, com1=03f8H
  509.  
  510. IODelay Macro
  511.     local a
  512.     jmp a
  513. a:
  514. endm
  515.  
  516. PollC    PROC    NEAR
  517.     public    PollC
  518.  
  519. ;    mov    dx, cs:PortAdr
  520.     mov    dx, DEFAULT_PORT
  521.     add    dx, COM_LSR
  522.  
  523.     in    al,dx            ; get input status
  524. ;    IODelay
  525.  
  526.     and    al,1            ; is there a char in RECV buffer?
  527.     jz    plc1            ; no, go return empty
  528.  
  529. ;    mov    dx, cs:PortAdr
  530.     mov    dx, DEFAULT_PORT
  531.     add    dx, COM_DAT
  532.  
  533.     in    al,dx            ;      char out of buffer
  534. ;    IODelay
  535.  
  536.     and    al,07fh         ; strip off        parity crap
  537. plc1:    ret
  538. PollC    ENDP
  539.  
  540.  
  541. ;**    PUTC - output a single char to COM2 handling ^S
  542.  
  543.  
  544. put_char    proc    near
  545.         public    put_char
  546.  
  547.     push    dx
  548.     push    ax
  549.  
  550. ;    See if ^S
  551.  
  552.     call    PollC            ; is there a char at input
  553.     jz    pc2            ; no, go output our char
  554.     cmp    al,'S' - 'A' + 1    ; is it ^S?
  555.     jnz    pc2            ; no, go output our char
  556.  
  557. ;    Saw ^S.  Wait for and eat next char.
  558.  
  559. pc1:    call    PollC            ; look for next char
  560.     jz    pc1            ; no char, go look again
  561.     cmp    al,'S' - 'A' + 1    ; is it ^S again?
  562.     jz    pc1            ; yes, go look for something else
  563.  
  564. ;pc2:     mov     dx, cs:PortAdr
  565. pc2:    mov    dx, DEFAULT_PORT
  566.     add    dx, COM_LSR
  567.     in    al,dx
  568. ;    IODelay
  569.     test    al,020h
  570.     jz    pc2
  571.  
  572. ;    ready.    crank it out!
  573.  
  574. ;    mov    dx, cs:PortAdr
  575.     mov    dx, DEFAULT_PORT
  576.     add    dx, COM_DAT
  577.     pop    ax
  578.     out    dx,al
  579.  
  580.         pop    dx        ; restore the callers dx register.
  581.  
  582.     ret
  583.  
  584. put_char    endp
  585.  
  586. _TEXT    ends
  587.     end
  588.