home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PROGRAMS / UTILS / LASER / NEWPRN.ZIP / NEWPRN.ASM < prev    next >
Encoding:
Assembly Source File  |  1987-06-15  |  16.6 KB  |  612 lines

  1. page    58,132
  2. title    NEWPRN     Copyright (c) 1986,87 COMPAQ Computer Corp.
  3. ;******************************************************************************
  4. ;
  5. ;   Name:    NEWPRN
  6. ;
  7. ;   Group:    DRIVER
  8. ;
  9. ;   Revision:    1.10
  10. ;
  11. ;   Date:    June 15, 1987
  12. ;
  13. ;   Author:    M P Vaughan
  14. ;
  15. ;******************************************************************************
  16. ;
  17. ;  Changes:
  18. ;
  19. ;    DATE     REVISION            DESCRIPTION
  20. ;  --------   --------     ------------------------------------------------------
  21. ;  12/15/86    1.00     Original.  Adapted from PRINTER.ASM from REV F 386
  22. ;             system ROM for installation as the INT 17h function for
  23. ;             386.
  24. ;   6/15/87    1.10     Shorten delay for recovery, and insert printer busy
  25. ;             test in wait_milli. MPV
  26. ;******************************************************************************
  27. ;
  28. ;  Functional Description:
  29. ;
  30. ;    This module replaces INT 17h for the 386. This is all of the parallel
  31. ;    printer functions.  It is a patch for use with high capacity
  32. ;    printers such as the HP Laserjet.  The delays for the original INT 17h
  33. ;    function sent the routine off into a 1ms delay to wait for the printer
  34. ;    to become ready after it was busy.  This routine inserts a check for
  35. ;    printer busy (prn_busy) within the 1ms delay routine.  If the printer
  36. ;    becomes ready while still in the wait routine, PRN_BUSY will force an
  37. ;    exit to print the routine.  This lowers the delay when a full 1ms is
  38. ;    not required for delay.
  39. ;
  40. ;            jmp     $+2     ;  Changed to the following
  41. ;            jmp     $+2     ;
  42. ;            ______________________
  43. ;
  44. ;            call    delay
  45. ;             .          .
  46. ;             .          .
  47. ;             .          .
  48. ;        delay   proc    near
  49. ;            push    cx
  50. ;            mov     cx,0Fh
  51. ;        this_one:
  52. ;            loop    this_one
  53. ;            pop     cx
  54. ;            ret
  55. ;        delay   endp
  56. ;
  57. ;******************************************************************************
  58. ;
  59. ;******************************************************************************
  60. ;
  61. ;  Equates
  62. ;
  63. ;******************************************************************************
  64. ;
  65. STANDARDOUT    equ    01h
  66. LSR        equ    5        ;    line status register
  67. DOS        equ    21h
  68. ;
  69. ;******************************************************************************
  70. ;
  71. ;  Externals
  72. ;
  73. ;******************************************************************************
  74. ;
  75.     extrn    prntbase:word        ;    printer base addrs table
  76.     extrn    printtmo:byte        ;    table of timeout values
  77.     extrn    ram400:byte        ;    ram segment
  78.  
  79.  
  80. page
  81. ;
  82. dev    segment byte public 'DEV'
  83.     assume    cs:dev,ds:seg ram400
  84. ;
  85. ;******************************************************************************
  86. ;
  87. ;    dev_head
  88. ;
  89. ;******************************************************************************
  90. ;
  91.     org    000h            ; Devices have no psp, so start at 0h
  92. ;
  93. devhead label    word
  94.     dw    -1, -1            ; Pointer to next device - must be set
  95.                     ; to -1
  96.     dw    8000h            ; Attributes - this is a char device
  97.     dw    strategy        ; pointer to device strategy entry pt.
  98.     dw    entry            ; pointer to device interrupt entry pt.
  99.     db    'newprn  '              ; Character device name field
  100. ;
  101. ;******************************************************************************
  102. ;
  103. ;        Command Jump Tables
  104. ;
  105. devtbl    label    word
  106.     dw    dev$init
  107.     dw    exit            ; Block device only
  108.     dw    exit            ; Block device only
  109.     dw    exit            ; IOCNTL input
  110.     dw    exit            ; Input (read)
  111.     dw    exit            ; Non-destructive input no wait (Char)
  112.     dw    exit            ; Input status (char only)
  113.     dw    exit            ; Input flush (char only)
  114.     dw    exit            ; Output (write)
  115.     dw    exit            ; Output (write) with verify
  116.     dw    exit            ; Output status (char only)
  117.     dw    exit            ; Output flush (char only)
  118.     dw    exit            ; IOCNTL output
  119.  
  120. page
  121. ;******************************************************************************
  122. ;
  123. ;        Device entry point
  124. ;
  125. ;            Strategy
  126. ;
  127. ptrsav    dd    0
  128. ;
  129. stratp    proc    far
  130. ;
  131. strategy:
  132.     mov    word ptr [ptrsav],bx
  133.     mov    word ptr [ptrsav+2],es
  134.     ret
  135. stratp    endp
  136. ;
  137. ;******************************************************************************
  138. ;
  139. ;        Main entry point
  140.  
  141. cmdlen    =   0                ; Command Length
  142. unit    =   1                ; Unit number
  143. cmdcode =   2                ; Command Code
  144. status    =   3                ; Status
  145. reservd =   5                ; 8 bytes reserved
  146. unitnum =   13                ; unit number of device
  147. brk_add =   14                ; Break address (transfer address)
  148.  
  149.  
  150. entry:
  151.     push    ax
  152.     push    bx
  153.     pushf
  154.     lds    bx,cs:[ptrsav]        ; Pointer to request header
  155.     mov    al,byte ptr [bx].cmdcode
  156.     cmp    al,0            ; Is the command initialize?
  157.     jne    exit            ; N: Exit - there are no other fctns
  158.     jmp    dev$init        ; Y: Do initialization - install the
  159.                     ;    new keyboard buffer.
  160. page
  161. ;******************************************************************************
  162. ;
  163. ;        Exit - this is the exit routine for this driver.
  164. ;
  165. exitp    proc    far
  166. exit:
  167.     popf
  168.     pop    bx
  169.     pop    ax
  170.     ret
  171. exitp    endp
  172. ;
  173. ;******************************************************************************
  174. page
  175. ;******************************************************************************
  176. ;******************************************************************************
  177. ;
  178. ;        Replacement INT 17h function.
  179. ;
  180. ;******************************************************************************
  181. ;
  182. ;
  183. ;
  184. ;
  185. ;******************************************************************************
  186. ;
  187. ;   Name:    printer - Printer Routine  INT 17
  188. ;
  189. ;   Group:    ROM
  190. ;
  191. ;   Revision:    A
  192. ;
  193. ;   Date:    May 25, 1986
  194. ;
  195. ;   Author:    Lance Pontiff
  196. ;
  197. ;******************************************************************************
  198. ;
  199. ;  CHANGES:
  200. ;
  201. ;    DATE     REVISION            DESCRIPTION
  202. ;  --------   --------     ------------------------------------------------------
  203. ;  05/25/86   original     Adapted from DeskPro 286 Rev E ROM.
  204. ;
  205. ;******************************************************************************
  206.  
  207.     page
  208. ;******************************************************************************
  209. ;
  210. ;  FUNCTIONAL DESCRIPTION:
  211. ;
  212. ;          Interrupt 17 -- printer output
  213. ;
  214. ;        (AH)  =  0  Routine will print the character in (AL).
  215. ;                Returns the printer status in (AH). Bit 0 set
  216. ;                to a 1 if character could not be printed.
  217. ;        (AH)  =  1  Initializes the printer port.
  218. ;                Returns with the printer status in (AH).
  219. ;        (AH)  =  2  Returns with the printer status in (AH).
  220. ;
  221. ;                BITS    FUNCTION
  222. ;                ------   ---------------------------------
  223. ;                  7      READY
  224. ;                  6      ACKNOWLEDGE
  225. ;                  5      OUT OF PAPER
  226. ;                  4      SELECTED
  227. ;
  228. ;                  3      I/O ERROR
  229. ;                  2
  230. ;                  1
  231. ;                  0      TIME OUT
  232. ;
  233. ;        (DX)        Set to printer to be used (0, 1, 2).
  234. ;
  235. ;******************************************************************************
  236.  
  237.     page
  238. ;
  239. ;  Publics
  240. ;
  241.  
  242. printer proc    near            ;    printer i/o routine
  243.     sti                ;    enable interrupts
  244.     push    bx            ;    save registers
  245.     push    cx            ;
  246.     push    dx            ;
  247.     push    si            ;    save index register
  248.     push    ds            ;    save segment registers
  249.     mov    bx,seg ram400        ;    setup ds register ...
  250.     mov    ds,bx            ;    to point to bios ram
  251. ;
  252. ;    Setup dx to point to printer by
  253. ;    indexing printer base table by printer number
  254. ;
  255.     and    dx,3            ;    force 0,1,2,3 only
  256.     mov    si,dx
  257.     mov    bl,[printtmo+si]    ;    bl=timeout interval
  258.     shl    si,1            ;    make word index
  259.     mov    dx,[prntbase+si]    ;    dx = printer base
  260.     or    dx,dx            ;   Q:    printer base of zero?
  261. ;    jz    print_ret        ;    Y: ignore if zero
  262.     jz    _leave            ; Y: Exit - print_ret is too far so do
  263. ;                         an intermediate jump (MPV 1.1)
  264. ;    Check ah register and go to correct routine
  265. ;
  266. ;        ah = 0        print character
  267. ;        ah = 1        initialize printer
  268. ;        ah = 2        status
  269. ;
  270.     push    ax            ;    save character
  271.     test    ah,ah            ;   Q:    print char?
  272.     jz    print_it        ;    Y:
  273.     dec    ah            ;   Q:    initialize printer?
  274.     jz    print_init        ;    Y:
  275.     dec    ah            ;   Q:    get printer status?
  276.     jz    print_stat        ;    Y:
  277.     pop    ax            ;    N: ignore call
  278. _leave:
  279.     jmp    short print_ret
  280.  
  281.  
  282.     page
  283. ;******************************************************************************
  284. ;    Print a character routine
  285. ;
  286. ;    Outputs character to 8 bit register
  287. ;    Checks busy and waits if needed
  288. ;    Strobes character into printer
  289. ;    Then goes to status
  290. ;
  291. ;    ENTRY - AL = character
  292. ;        BL = timeout value (0.780 sec per count)
  293. ;        DX = printer base i/o address
  294. ;    EXIT -    BH = status
  295. ;------------------------------------------------------------------------------
  296. print_it:
  297.     out    dx,al            ;    output ascii to printer
  298.     inc    dx            ;    point to status to check busy
  299.     jmp    $+2
  300.     jmp    $+2            ; Allow for recovery time
  301.  
  302. ;    call    delay            ;    allow recovery time
  303.     in    al,dx            ;    get printer status
  304.     and    al,0f8h         ;   Q:    printer ready?
  305.     js    prtchr            ;    Y: go strobe data
  306.     push    ax            ;    N: protect ax
  307.     mov    ax,90feh        ;    printer Device Wait
  308.     clc                ;    default = ROM timeout
  309.     int    15h            ;   Q:    Device Wait performed?
  310.     pop    ax            ;    restore ax
  311.     jc    timeout         ;    Y:
  312. a_count:
  313.     mov    cx,780            ;    wait 1 milliseconds 780 times
  314. normal_to:
  315.     push    bx            ;    N: protect bx
  316.     mov    bx,1            ;    wait 10 milliseconds
  317.     call    wait_milli        ;
  318.     pop    bx            ;    restore bx
  319.     in    al,dx            ;    al = printer status
  320.     and    al,0f8h         ;   Q:    printer ready?
  321.     js    prtchr            ;    Y: go strobe character
  322.     loop    normal_to        ;    N: keep waiting
  323.     dec    bl            ;   Q:    finished all counts?
  324.     jnz    a_count         ;    N:
  325. timeout:                ;    Y:
  326.     jmp    $+2            ; Allow for recovery time
  327.     jmp    $+2
  328.  
  329. ;    call    delay            ;    allow recovery time
  330.     in    al,dx            ;    get printer status
  331.     and    al,0f8h         ;   Q:    printer still busy?
  332.     js    prtchr            ;    N: go strobe character
  333.     or    al,1            ;    Y: set time out bit
  334.     jmp    short print_exit    ;    exit & post status
  335. prtchr:
  336.     inc    dx            ;    strobe status
  337.     in    al,dx            ;    read current settings
  338.     and    al,1eh            ;
  339.     or    al,01h            ;    set strobe bit
  340.     jmp    $+2            ; Allow for recovery time
  341.     jmp    $+2
  342.  
  343. ;    call    delay            ;    allow recovery time
  344.     out    dx,al            ;    turn strobe on
  345.     and    al,1eh            ;    turn strobe off
  346.     jmp    short print_inits    ;
  347.  
  348.     page
  349. ;******************************************************************************
  350. ;    Initialize printer
  351. ;
  352. ;    ENTRY - DX = printer i/o base address
  353. ;    EXIT -    BH = status
  354. ;------------------------------------------------------------------------------
  355. print_init:
  356.     inc    dx            ;    get address of init bit
  357.     inc    dx            ;
  358.     mov    al,8            ;    initialize latch to slctn
  359.     jmp    $+2            ; Allow for recovery time
  360.     jmp    $+2
  361.  
  362. ;    call    delay            ;    allow recovery time
  363.     out    dx,al            ;    'init' line low, select high
  364.     mov    bx,5            ;    assert init 5 ms per centronics
  365.     call    wait_milli        ;    wait 5 milliseconds
  366.     or    al,4            ;    set 'init' bit high
  367. print_inits:
  368.     jmp    $+2            ; Allow for recovery time
  369.     jmp    $+2
  370.  
  371. ;    call    delay            ;    allow recovery time
  372.     out    dx,al            ;
  373.     dec    dx            ;    get current status
  374.     dec    dx            ;    point to printer i/o base
  375.                     ;    fall into 'print_stat'
  376.  
  377.     page
  378. ;******************************************************************************
  379. ;    Status
  380. ;
  381. ;    ENTRY - DX = printer i/o base address
  382. ;    EXIT -    AL = status
  383. ;------------------------------------------------------------------------------
  384. print_stat:
  385.     inc    dx            ;    point to status
  386.     jmp    $+2            ; Allow for recovery time
  387.     jmp    $+2
  388.  
  389. ;    call    delay            ;    allow recovery time
  390.     in    al,dx            ;    input status
  391.     and    al,0f8h         ;    mask unwanted bits
  392.                     ;    fall into 'print_exit'
  393.  
  394. ;*****************************************************************************
  395. ;    ENTRY - AL = masked status from port
  396. ;    EXIT -    AH = status
  397. ;------------------------------------------------------------------------------
  398. print_exit:
  399.     xor    al,48h            ;    invert sense of ack and err
  400.     mov    bh,al            ;    temp = al
  401.     pop    ax            ;    restore al, in particular
  402.     mov    ah,bh            ;    ah = temp
  403. print_ret:
  404.     pop    ds            ;    restore segment registers
  405.     pop    si            ;    restore index registers
  406.     pop    dx            ;    restore registers
  407.     pop    cx            ;
  408.     pop    bx            ;
  409.     iret                ;    *** RETURN ***
  410. printer endp
  411.  
  412.     include pop_f.mac        ; Macro to simulate POPF instruction.
  413.  
  414.     public    wait_milli        ; Wait # of milliseconds in BX.
  415. ;
  416. COUNTS_MILLI    =    1192*2        ; System timer counts per millisecond.
  417. K16    DW    16            ; ROM constant for hex conversions.
  418.  
  419.  
  420. ;    Equates
  421. ;
  422.     include asciidef.equ        ; ASCII defs.
  423. ;
  424.     include ppi_def.equ        ; 8255 PPI equates.
  425. ;
  426.     include cnt_def.equ        ; 8253 counter-timer equates.
  427. ;
  428.     include vdu_def.equ        ; VDU equates.
  429. ;
  430. ;******************************************************************************
  431. ;
  432. ;    Delay Routines:
  433. ;
  434. ;    NOTE: These routines has been modified for the 286-based products
  435. ;          to be processor-speed independent.  Note that this routine
  436. ;          assumes that stack is available.    Stack is needed to do POPF
  437. ;          equivalent.
  438. ;
  439. ;    REG.USED: BX
  440. ;******************************************************************************
  441. ;
  442. ;    This routine delays the number of milliseconds specified in BX.
  443. ;
  444. wait_milli    proc    near
  445.     push    bp            ; Save BP for caller.
  446.     push    ax            ; Save AX for caller.
  447.     push    cx            ; Save CX for caller.
  448.     call    delay_ms_sp        ; Use routine with stack.
  449.     pop    cx            ;
  450.     pop    ax            ;
  451.     pop    bp            ;
  452.     ret                ; *** RETURN ***
  453. wait_milli    endp
  454. ;
  455.     page
  456. ;******************************************************************************
  457. ;
  458. ;    DELAY_MS_SP - Routine to delay 1 millisecond per count in BX.
  459. ;
  460. ;        ENTRY - BX = # of Milliseconds
  461. ;            BP = Return address
  462. ;
  463. ;        EXIT -    None
  464. ;
  465. ;    NOTE: This routine has been modified for the 286-based products
  466. ;          to be processor-speed independent.  It assumes that the stack
  467. ;          is available so that it can run the POP_F macro to preserve
  468. ;          interrupt status the same as the caller.
  469. ;
  470. ;    REG.USED: AX, BX, CX, BP
  471. ;******************************************************************************
  472. delay_ms_sp   proc near         ;
  473.     mov    cx,bx            ; cx= number of milliseconds
  474. rd_ini_count:                ;
  475.     pushf                ;
  476.     cli                ;;;
  477.     mov    al,LATCH_CNT0        ;;; Latch count for system timer.
  478.     out    cnt_mode,al        ;;;
  479.     in    al,cnt_0        ;;; Read low byte first.
  480.     mov    ah,al            ;;;
  481.     jmp    $+2            ;;;
  482.     jmp    $+2            ;;;
  483.     in    al,cnt_0        ;;; Read high byte.
  484.     pop_f                ;;;
  485.     xchg    al,ah            ;   Get bytes in the right order.
  486.     mov    bx,ax            ;   Save BX=initial count.
  487. rd_count:                ;
  488.     call    prn_busy        ; Q: Is the printer ready? (MPV 1.1)
  489.     js    _exit            ;  Y: Exit and print it.
  490.     pushf                ;  N: Delay a little longer. (MPV 1.1)
  491.     cli                ;;;
  492.     mov    al,LATCH_CNT0        ;;; Latch count for system timer.
  493.     out    cnt_mode,al        ;;;
  494.     jmp    $+2            ;;;
  495.     jmp    $+2            ;;;
  496.     jmp    $+2            ;;;
  497.     in    al,cnt_0        ;;; Read low byte of count.
  498.     mov    ah,al            ;;;
  499.     jmp    $+2            ;;;
  500.     jmp    $+2            ;;;
  501.     in    al,cnt_0        ;;; Read high byte of count.
  502.     pop_f                ;
  503.     xchg    al,ah            ;   Get bytes in the right order.
  504.     push    bx            ;   Save initial timer count.
  505.     sub    bx,ax            ;   Initial count - Current count.
  506.     cmp    bx,COUNTS_MILLI     ;  Q: Reached desired count ?
  507.     pop    bx            ;   Restore initial timer count.
  508.     jb    rd_count        ;   No, keep reading count.
  509.     loop    rd_ini_count        ;   Yes, do more milliseconds.
  510. _exit:
  511.     ret                ;
  512. delay_ms_sp endp            ;
  513.     page
  514. ;
  515. delay    proc    near
  516. ;     mov     cx,0Fh     ; (MPV 1.1)
  517. ;this_one:            ; (MPV 1.1)
  518. ;     loop     this_one   ; (MPV 1.1)
  519.     ret
  520. dummy    dt  ?            ; (MPV 1.1)
  521. delay    endp
  522.  
  523. prn_busy    proc    near    ; (MPV 1.1)
  524.     push    ax
  525.     in    al,dx            ;    al = printer status
  526.     and    al,0f8h         ;   Q:    printer ready?
  527.     pop    ax
  528.     ret            ; (MPV 1.1)
  529. prn_busy    endp
  530. ;
  531. ;
  532. ;
  533. ;******************************************************************************
  534. ;******************************************************************************
  535. page
  536. ;******************************************************************************
  537. ;******************************************************************************
  538. ;
  539. ;    dev$init - this installs the driver.
  540. ;
  541. ;******************************************************************************
  542. ;        Start NEWPRN.SYS - save registers first, then install the new
  543. ;    interrupt service routine.
  544. ;******************************************************************************
  545.  
  546. dev$init:
  547.     push    ax
  548.     push    bx
  549.     push    cx
  550.     push    dx
  551.     push    si
  552.     push    di
  553.     push    bp
  554.     push    ds
  555.     push    es
  556.     pushf
  557.  
  558. ;
  559. page
  560. ;******************************************************************************
  561. ;        Set up a new INT 17h handler
  562. ;******************************************************************************
  563. install:
  564.  
  565.     assume    ds:dev
  566.     mov    ax,cs
  567.     mov    ds,ax
  568. ;
  569.     mov    dx,offset printer    ; Set new INT 17h interrupt
  570.     mov    ax,2517h
  571.     int    DOS
  572. ;
  573.  
  574. ;******************************************************************************
  575. ;        All done, print install message and prepare to exit.
  576. ;******************************************************************************
  577.  
  578.     mov    dx,offset i_msg
  579.     mov    ah,09h
  580.     int    DOS
  581. ;
  582.     lds    bx,cs:[ptrsav]
  583.     mov    word ptr [bx].brk_add, offset cs:dev$init
  584.     mov    word ptr [bx].status, 10h
  585.     mov    [bx].brk_add+2,cs
  586. ;
  587. _done:
  588.     popf
  589.     pop    es
  590.     pop    ds
  591.     pop    bp
  592.     pop    di
  593.     pop    si
  594.     pop    dx
  595.     pop    cx
  596.     pop    bx
  597.     pop    ax
  598.     jmp    exit
  599.  
  600. page
  601. ;******************************************************************************
  602. ;                 Installation messages
  603. ;******************************************************************************
  604.  
  605. i_msg    db    CR,LF,'   NEWPRN.SYS V1.10 Installed'
  606.     db    CR,LF,'(C) Copyright COMPAQ Computer Corp. 1987'
  607.     db    CR,LF
  608.     db    '$'
  609. ;
  610. dev    ends
  611.     end
  612.