home *** CD-ROM | disk | FTP | other *** search
/ Piper's Pit BBS/FTP: ibm 0020 - 0029 / ibm0020-0029 / ibm0028.tar / ibm0028 / GRLF-C-2.ZIP / GFUNC / PARINT.ASM < prev    next >
Encoding:
Assembly Source File  |  1990-05-30  |  14.5 KB  |  616 lines

  1.         page    58,132
  2. ;/*
  3. ;** parint.asm
  4. ;** contains: PrBufC(), stopprt(), strtprt(), testprt()
  5. ;*/
  6.  
  7.         include model.h
  8.         include prologue.h
  9.  
  10. DOSCALL     equ    21h            ;Dos: call software interrupt number
  11. DOSGETVECTOR    equ    35h            ;Dos: Get Interrupt vector function number
  12. DOSSETVECTOR    equ    25h            ;Dos: Set Interrupt vector
  13.  
  14.  
  15. ;==>--    PARINT is the structure that holds the state information for
  16. ;    a parallel port.
  17. ;
  18. PARINT    struc
  19.     StatusBits  dw        ?            ;Status of channel
  20.     BaseIOPAR   dw        ?            ;Base I/O Address for LPT
  21.     IntNum        dw        ?            ;Interrupt Number
  22.     PrevVector  dd        ?            ;Previous value for interrupt vector
  23.     PrevBase2   dw        ?            ;Previous value for interrupt enable port
  24.     Irq8259     dw        ?            ;Interrupt # in 8259
  25.     Prev8259    dw        ?            ;Previous 8259 bit
  26.     IOAdd8259   dw        ?            ;I/O address of 8259
  27.     pBufSize    dw        ?            ;Size of buffer
  28.     pBufCount   dw        ?            ;Number of characters currently in buffer
  29.     pBufHead    dw        ?            ;Offset into buffer for head
  30.     pBufTail    dw        ?            ;Offset into buffer for tail
  31.     pBuffer     dw        ptrsize dup(?)    ;points to actual buffer
  32. PARINT    ends
  33.  
  34. PARBUFFERFULL    equ    -800            ;buffer is full error
  35.  
  36.     ifdef    LATTICE
  37. ;==>--    Define bits in the StatusBits member (Lattice)
  38. ;
  39. BUFFEREMPTY    equ    1000000000000000b    ;Buffer is empty
  40. BUFFERFULL    equ    0100000000000000b    ;Buffer is full
  41. INTSRUNNING    equ    0010000000000000b    ;Interrupts are running
  42. INTSENABLED    equ    0001000000000000b    ;Interrupts enabled
  43.     else
  44. ;==>--    Define bits in the StatusBits member (non-Lattice)
  45. ;
  46. BUFFEREMPTY    equ    0000000000000001b    ;Buffer is empty
  47. BUFFERFULL    equ    0000000000000010b    ;Buffer is full
  48. INTSRUNNING    equ    0000000000000100b    ;Interrupts are running
  49. INTSENABLED    equ    0000000000001000b    ;Interrupts enabled
  50.     endif
  51.  
  52. ;==>--    Bits for the parallel control port
  53. ;
  54. PARSTROBE    equ    00000001b        ;Parallel strobe bit (active low)
  55. PARAUTOFEED    equ    00000010b        ;Auto feed bit (active low)
  56. PARINITPRINTER    equ    00000100b        ;Initialize printer bit
  57. PARSELECTINPUT    equ    00001000b        ;Select bit (active low)
  58. PARIRQENABLE    equ    00010000b        ;Interrupt enable bit
  59.  
  60.  
  61.         dseg    dparint
  62.  
  63.         if    _LDATA
  64. printerstruct    dd    0            ;32 bit pointer to PARINT
  65.         else
  66. printerstruct    dw    0            ;16 bit pointer to PARINT
  67.         endif
  68.  
  69.         endds
  70.  
  71.         pseg    cparint
  72.  
  73. ;==>--    The StrobePrinter macro creates the strobe signal for the printer.
  74. ;    The assumption is made that upon entry the DX register contains the
  75. ;    address of the parallel control port.
  76. ;
  77. StrobePrinter    macro
  78.         mov    al,PARIRQENABLE+PARSELECTINPUT+PARINITPRINTER+PARSTROBE
  79.         out    dx,al
  80.         jmp    short $+2        ;delay
  81.         jmp    short $+2        ;  "
  82.         jmp    short $+2        ;
  83.         xor    al,PARSTROBE
  84.         out    dx,al
  85.         endm
  86.  
  87.  
  88.  
  89. ;/*
  90. ;**  int
  91. ;** PrBufC(PARINT *p,unsigned char character)
  92. ;**
  93. ;** ARGUMENT(s)
  94. ;**    p        -    Points to PARINT structure returned from
  95. ;**                OpenPrinter().
  96. ;**
  97. ;**    character    -    Character to be put in the printer buffer.
  98. ;**
  99. ;**
  100. ;** DESCRIPTION
  101. ;**  Puts a character in the printer buffer.
  102. ;**
  103. ;**
  104. ;** RETURNS
  105. ;**  0 if successful, else:
  106. ;**
  107. ;**    PARBUFFERFULL
  108. ;**
  109. ;** AUTHOR
  110. ;**  ""   Thu 17-Nov-1988    11:50:48
  111. ;**   Copyright (C)1988-1990 Greenleaf Software Inc. All Rights Reserved.
  112. ;**
  113. ;** MODIFICATIONS
  114. ;**
  115. ;*/
  116.         cproc    PrBufC
  117.         push    es
  118.         if    _LDATA
  119.          push    ds
  120.          lds    si,parm1_    ;DS:SI points to PARINT
  121.          mov    al,parm3_    ;AL = character
  122.         else
  123.          mov    si,parm1_    ;DS:SI points to PARINT
  124.          mov    al,parm2_    ;AL = character
  125.         endif
  126.         test    [si+StatusBits],BUFFERFULL
  127.         jz    bufnotfull
  128.         mov    ax,PARBUFFERFULL
  129.         jmp    short prbufcex
  130. bufnotfull:    lea    di,[si+pBufSize]
  131.         cli
  132.         call    insert            ;insert character in buffer
  133.         jnz    notful2         ;if buffer did not go full jump
  134.         or    [si+StatusBits],BUFFERFULL ;set bit that says buffer is full
  135. notful2:    sti
  136.         xor    ax,ax            ;assume success
  137.         test    [si+StatusBits],BUFFEREMPTY ;did we put character in empty buffer?
  138.         jz    prbufcex        ;if not jump out
  139.         and    [si+StatusBits],not BUFFEREMPTY ;else say buffer not now empty
  140.         test    [si+StatusBits],INTSENABLED
  141.         jz    prbufcex            ;if ints not enabled get out
  142.         test    [si+StatusBits],INTSRUNNING
  143.         jnz    prbufcex
  144.         mov    dx,[si+BaseIOPAR]    ;see if printer is ready
  145.         inc    dx
  146.         in    al,dx
  147.         test    al,80h            ;is printer ready for character
  148.         jz    prbufcex
  149.         lea    di,[si+pBufSize]
  150.         cli
  151.         call    remove            ;remove character from buffer
  152.         jnz    notempt1        ;see if it went empty
  153.         or    [si+StatusBits],BUFFEREMPTY
  154. notempt1:    or    [si+StatusBits],INTSRUNNING
  155.         sti
  156.         mov    dx,[si+BaseIOPAR]    ;DX = base address of Parallel port
  157.         out    dx,al            ;output character to port
  158.         inc    dx
  159.         inc    dx
  160.         jmp    short $+2
  161.         jmp    short $+2
  162.         StrobePrinter
  163.         xor    ax,ax            ;indicate success
  164. prbufcex:
  165.         if    _LDATA
  166.          pop    ds
  167.         endif
  168.         pop    es
  169.         cproce
  170.  
  171. ;/*
  172. ;**  void
  173. ;** stopprt(PARINT *p)
  174. ;**
  175. ;** ARGUMENT(s)
  176. ;**     p     -     points to PARINT structure to stop
  177. ;**
  178. ;**
  179. ;** DESCRIPTION
  180. ;**  Halts printer output, does not remove characters from buffer,
  181. ;**  does not disable interrupt system.
  182. ;**
  183. ;** RETURNS
  184. ;**  void
  185. ;**
  186. ;** AUTHOR
  187. ;**  ""   Fri 18-Nov-1988    11:11:41
  188. ;**   Copyright (C)1988-1990 Greenleaf Software Inc. All Rights Reserved.
  189. ;**
  190. ;** MODIFICATIONS
  191. ;**
  192. ;*/
  193.         cproc    stopprt
  194.         if    _LDATA
  195.          push    ds
  196.          lds    si,parm1_
  197.         else
  198.          mov    si,parm1_
  199.         endif
  200.         and    [si+StatusBits],not INTSRUNNING+INTSENABLED
  201.         if    _LDATA
  202.          pop    ds
  203.         endif
  204.         cproce
  205.  
  206. ;/*
  207. ;**  void
  208. ;** _closepar(PARINT *p)
  209. ;**
  210. ;** ARGUMENT(s)
  211. ;**     p     -     points to PARINT structure to close
  212. ;**
  213. ;** DESCRIPTION
  214. ;**  Restores modes set in parallel port and 8259 and interrupt
  215. ;**  vectors to their pre-opened condition.  This function should
  216. ;**  only be called by the ClosePrinter() function.
  217. ;**
  218. ;** RETURNS
  219. ;**  void
  220. ;**
  221. ;** AUTHOR
  222. ;**  ""   Thu 17-Nov-1988    11:11:06
  223. ;**   Copyright (C)1988-1990 Greenleaf Software Inc. All Rights Reserved.
  224. ;**
  225. ;** MODIFICATIONS
  226. ;**
  227. ;*/
  228.         cproc    _closepar,,_closepa
  229.         push    es
  230.         push    ds
  231.         if    _LDATA
  232.          lds    si,parm1_
  233.         else
  234.          mov    si,parm1_
  235.         endif
  236.         mov    dx,[si+BaseIOPAR]    ;CX = base I/O address for port
  237.         add    dx,2            ;DX = IRQ enable port
  238.         mov    al,byte ptr [si+PrevBase2] ;Restore parallel port
  239.         out    dx,al            ;to it's pre-open setting
  240.         mov    cx,[si+Irq8259]
  241.         mov    ax,1
  242.         shl    al,cl
  243.         mov    cx,ax
  244.         mov    dx,[si+IOAdd8259]    ;DX=Base I/O Address of 8259
  245.         inc    dx
  246.         in    al,dx
  247.         jmp    short $+2
  248.         or    al,cl            ;assume previously disabled
  249.         test    [si+Prev8259],cx    ;check assumption
  250.         jnz    rs8259            ;if assumption correct
  251.         xor    al,cl            ;else reverse assumption
  252. rs8259:     out    dx,al            ;restore to previous state
  253.         push    ds            ;now restore the interrupt vector
  254.         mov    al,byte ptr [si+IntNum] ;Interrupt Vector #
  255.         lds    dx,[si+PrevVector]    ;DS:DX = old value
  256.         mov    ah,DOSSETVECTOR
  257.         int    DOSCALL
  258.         pop    ds
  259.         pop    ds
  260.         pop    es
  261.         cproce
  262.  
  263.  
  264. ;/*
  265. ;**  void
  266. ;** strtprt(PARINT *p)
  267. ;**
  268. ;** ARGUMENT(s)
  269. ;**     p     -     points to PARINT structure to start
  270. ;**
  271. ;**
  272. ;** DESCRIPTION
  273. ;**  Re-starts printer output, assume printer has been halted with
  274. ;**  StopPrinter().
  275. ;**
  276. ;** RETURNS
  277. ;**  void
  278. ;**
  279. ;** AUTHOR
  280. ;**  "" Fri 18-Nov-1988 11:11:41
  281. ;**   Copyright (C)1988-1990 Greenleaf Software Inc. All Rights Reserved.
  282. ;**
  283. ;** MODIFICATIONS
  284. ;**
  285. ;*/
  286.         cproc    strtprt
  287.         if    _LDATA
  288.          push    ds
  289.          lds    si,parm1_
  290.         else
  291.          mov    si,parm1_
  292.         endif
  293.         or    [si+StatusBits],INTSENABLED
  294.         test    [si+StatusBits],INTSRUNNING    ;are they running
  295.         jnz    startexit            ;if so leave
  296.         mov    dx,[si+BaseIOPAR]    ;see if printer is ready
  297.         inc    dx
  298.         in    al,dx
  299.         test    al,80h            ;is printer ready for character
  300.         jz    startexit
  301.         lea    di,[si+pBufSize]
  302.         cli
  303.         call    remove            ;remove character from buffer
  304.         jnz    stnotempt1        ;see if it went empty
  305.         or    [si+StatusBits],BUFFEREMPTY
  306. stnotempt1:    or    [si+StatusBits],INTSRUNNING
  307.         sti
  308.         mov    dx,[si+BaseIOPAR]    ;DX = base address of Parallel port
  309.         out    dx,al            ;output character to port
  310.         inc    dx
  311. stloop1:    in    al,dx
  312.         test    al,80h
  313.         jz    stloop1
  314.         inc    dx
  315.         StrobePrinter
  316. startexit:
  317.         if    _LDATA
  318.          pop    ds
  319.         endif
  320.         cproce
  321.  
  322.  
  323.  
  324. ;/*
  325. ;**  void
  326. ;** _setpari(PARINT *p)
  327. ;**
  328. ;** ARGUMENT(s)
  329. ;**    p    -    points to PARINT structure to setup
  330. ;**
  331. ;** DESCRIPTION
  332. ;**  Enables interrupt mode operation for a parallel device as described
  333. ;**  in a PARINT structure.  This function should only be called by the
  334. ;**  OpenPrinter() function.
  335. ;**
  336. ;** RETURNS
  337. ;**  void
  338. ;**
  339. ;** AUTHOR
  340. ;**  ""   Wed 16-Nov-1988    09:42:30
  341. ;**   Copyright (C)1988-1990 Greenleaf Software Inc. All Rights Reserved.
  342. ;**
  343. ;** MODIFICATIONS
  344. ;**
  345. ;*/
  346.         cproc    _setpari
  347.         push    es
  348.         push    ds
  349.         if    _LDATA
  350.          les    si,parm1_
  351.          mov    word ptr printerstruct,si
  352.          mov    word ptr printerstruct+2,es
  353.          mov    ax,es
  354.          mov    ds,ax            ;DS:SI points to structure
  355.         else
  356.          mov    si,parm1_
  357.          mov    printerstruct,si    ;DS:SI points to structure
  358.         endif
  359.         mov    ah,DOSGETVECTOR
  360.         mov    al,byte ptr [si+IntNum] ;Get current value of vector
  361.         int    DOSCALL         ;to ES:BX
  362.         mov    word ptr [si+PrevVector],bx
  363.         mov    word ptr [si+PrevVector+2],es
  364.         push    ds            ;now set the vector of our handler
  365.         mov    ah,DOSSETVECTOR
  366.         mov    al,byte ptr [si+IntNum]
  367.         mov    bx,cs
  368.         mov    ds,bx
  369.         mov    dx,offset IRQ7Routine    ;set new vector to DS:DX
  370.         int    DOSCALL
  371.         pop    ds            ;Get DS back
  372.         mov    dx,[si+BaseIOPAR]    ;CX = base I/O address for port
  373.         add    dx,2            ;DX = IRQ enable port
  374.         in    al,dx            ;read current value
  375.         mov    byte ptr [si+PrevBase2],al ;and save in structure
  376.         mov    al,PARIRQENABLE+PARSELECTINPUT+PARINITPRINTER
  377.         jmp    short _fpf
  378. _fpf:        out    dx,al            ;enable interrupts on parallel port
  379.         mov    cx,[si+Irq8259]     ;get 8259 enable bit
  380.         mov    al,1
  381.         shl    al,cl            ;shift 1 bit into position
  382.         not    al            ;ones complement it
  383.         mov    cl,al            ;save in cl
  384.         mov    dx,[si+IOAdd8259]    ;dx=8259 base
  385.         inc    dx
  386.         in    al,dx
  387.         jmp    short _fpf2
  388. _fpf2:        xor    ah,ah
  389.         mov    [si+Prev8259],ax
  390.         and    al,cl            ;enable correct bit
  391.         out    dx,al            ;in 8259
  392.         pop    ds
  393.         pop    es
  394.         cproce
  395.  
  396.  
  397. ;/*
  398. ;**  unsigned char
  399. ;** testprt(PARINT *p)
  400. ;**
  401. ;** ARGUMENT(s)
  402. ;**    p    -    points to PARINT structure
  403. ;**
  404. ;** DESCRIPTION
  405. ;**  Gets the hardware status of the printer.
  406. ;**
  407. ;**
  408. ;** RETURNS
  409. ;**
  410. ;**    Bit        Meaning
  411. ;**     7        Busy
  412. ;**     6        Ack
  413. ;**     5        Out of paper
  414. ;**     4        Select
  415. ;**     3        Error
  416. ;**
  417. ;** AUTHOR
  418. ;**  ""   Fri 18-Nov-1988    12:07:30
  419. ;**   Copyright (C)1988-1990 Greenleaf Software Inc. All Rights Reserved.
  420. ;**
  421. ;** MODIFICATIONS
  422. ;**
  423. ;*/
  424.         cproc    testprt
  425.         if    _LDATA
  426.          push    ds
  427.          lds    si,parm1_
  428.         else
  429.          mov    si,parm1_
  430.         endif
  431.         mov    dx,[si+BaseIOPAR]    ;get port # to DX
  432.         inc    dx
  433.         in    al,dx
  434.         and    al,0f8h         ;mask unused bits
  435.         xor    ah,ah
  436.         if    _LDATA
  437.          pop    ds
  438.         endif
  439.         cproce
  440.  
  441. ;/*
  442. ;** DESCRIPTION
  443. ;**  Interrupt routine for IRQ #7 (printer).  Saves all registers and
  444. ;**  points DS:SI to the PARINT data structure which contains state
  445. ;**  information for the parallel port using IRQ 7.
  446. ;**
  447. ;** AUTHOR
  448. ;**  ""   Wed 16-Nov-1988    09:55:13
  449. ;**   Copyright (C)1988-1990 Greenleaf Software Inc. All Rights Reserved.
  450. ;**
  451. ;** MODIFICATIONS
  452. ;**
  453. ;*/
  454. IRQ7Routine    proc    far
  455.         sti
  456.         push    ax
  457.         push    dx
  458.         push    es
  459.         push    ds
  460.         push    bx
  461.         push    cx
  462.         push    si
  463.         push    di
  464.         ifdef    TURBOC
  465.          if    _HUGE
  466.           mov    ax,_dparint_DATA
  467.          else
  468.           mov    ax,DGROUP
  469.          endif
  470.         else
  471.          ifndef AZTEC
  472.           mov    ax,DGROUP
  473.          else
  474.           mov    ax,dataseg
  475.          endif
  476.         endif
  477.         mov    ds,ax
  478.         if    _LDATA
  479.          lds    si,printerstruct
  480.         else
  481.          mov    si,printerstruct
  482.         endif
  483.         cld
  484.         call    ProcessIRQ
  485.         mov    dx,[si+IOAdd8259]    ;Load registers for 8259 EOI
  486.         mov    al,20h
  487.         pop    di
  488.         pop    si
  489.         pop    cx
  490.         pop    bx
  491.         pop    ds
  492.         pop    es
  493.         cli
  494.         out    dx,al            ;re-enable 8259
  495.         pop    dx
  496.         pop    ax
  497.         iret
  498. IRQ7Routine    endp
  499.  
  500.  
  501. ;==>--    Arrive here with DS:SI pointing to a PARINT data structure
  502. ;
  503. ProcessIRQ    proc    near
  504.         mov    dx,[si+BaseIOPAR]    ;read status port to clear
  505.         inc    dx            ;interrupt condition
  506.         in    al,dx
  507.         test    [si+StatusBits],INTSENABLED
  508.         jz    stopirq
  509.         test    [si+StatusBits],BUFFEREMPTY
  510.         jz    IRQbufnotempty        ;if buffer not empty continue
  511. stopirq:    and    [si+StatusBits],not INTSRUNNING
  512.         jmp    short IRQExit
  513. IRQbufnotempty: lea    di,[si+pBufSize]
  514.         call    remove            ;remove character from buffer
  515.         jnz    didnotgoempty        ;if buffer did not go empty take jump
  516.         or    [si+StatusBits],BUFFEREMPTY
  517. didnotgoempty:    and    [si+StatusBits],not BUFFERFULL ;cannot be full now
  518.         mov    dx,[si+BaseIOPAR]    ;get base of parallel port
  519.         out    dx,al            ;send character to printer
  520.         jmp    short $+2
  521.         jmp    short $+2
  522.         inc    dx
  523.         inc    dx
  524.         StrobePrinter
  525. IRQExit:    ret
  526. ProcessIRQ    endp
  527.  
  528.  
  529. ;==>--    Offsets for the insert & remove routines
  530. ;
  531. BSIZE    equ    0
  532. COUNT    equ    2
  533. HEAD    equ    4
  534. TAIL    equ    6
  535. BUFFER    equ    8
  536.  
  537. ;==>--    insert character is to be called with ds:di pointing to the
  538. ;    size variable, upon return the Zero flag being set indicates
  539. ;    that the buffer is NOW FULL. When the buffer is full do not call
  540. ;    this routine again, until there is space for another character.
  541. ;    Call with character in AL.  This routine does not test for a
  542. ;    full buffer before inserting, only after inserting.
  543. ;
  544. insert        proc    near                   ;DS:DX points to beginning
  545.         push    si
  546.         if    _LDATA
  547.          push    es
  548.          les    si,[di+BUFFER]            ;es:si points to base of array
  549.         else
  550.          mov    si,[di+BUFFER]            ;ds:si points to base of array
  551.         endif
  552.         inc    word ptr [di+COUNT]        ;bump counter
  553.         mov    bx,[di+TAIL]            ;read the tail
  554.         mov    dx,bx
  555.         inc    dx                ;advance the tail for next
  556.         mov    cx,[di+BSIZE]            ;get size of buffer to cx
  557.         cmp    dx,cx                ;check for wrap
  558.         jb    inwrap                ;if no wrap take jump
  559.         xor    dx,dx                ;reset subscript to 0
  560. inwrap:     mov    [di+TAIL],dx            ;save updated tail
  561.         if    _LDATA
  562.          mov    es:[si+bx],al            ;save character via ES:SI
  563.         else
  564.          mov    [si+bx],al            ;save character via DS:SI
  565.         endif
  566.         jmp    short inend
  567. inend:        cmp    dx,[di+HEAD]            ;see if buffer full
  568.         if    _LDATA
  569.          pop    es
  570.         endif
  571.         pop    si
  572.         ret
  573. insert        endp
  574.  
  575. ;==>--    remove character is to be called with ds:di pointing to the
  576. ;    size variable, upon return the Zero flag being set indicates
  577. ;    that the buffer is NOW EMPTY. When the buffer is empty DO NOT call
  578. ;    this routine again, until there is another character to remove.
  579. ;    Returns with character in AL.  This routine does not test for an
  580. ;    empty buffer before removing, only after removing.
  581. ;
  582. remove        proc    near
  583.         push    si
  584.         if    _LDATA
  585.          push     es
  586.          les     si,[di+BUFFER]          ;es:si=base of buffer
  587.         else
  588.          mov     si,[di+BUFFER]          ;ds:si=base of buffer
  589.         endif
  590.         dec    word ptr [di+COUNT]        ;decrement counter
  591.         mov    bx,[di+HEAD]            ;read the head
  592.         mov    dx,bx
  593.         inc    dx
  594.         mov    cx,[di+BSIZE]            ;get size of buffer to cx
  595.         cmp    dx,cx                ;check for wrap
  596.         jb    rewrap                ;if no wrap take jump
  597.         xor    dx,dx                ;reset subscript to 0
  598. rewrap:     mov    [di+HEAD],dx            ;save updated head
  599.         xor    ah,ah
  600.         if    _LDATA
  601.          mov    al,es:[si+bx]            ;remove character via ES:SI
  602.         else
  603.          mov    al,[si+bx]            ;remove character via DS:SI
  604.         endif
  605.         jmp    short reend
  606. reend:        cmp    dx,[di+TAIL]            ;see if buffer empty
  607.         if    _LDATA
  608.          pop    es
  609.         endif
  610.         pop    si
  611.         ret
  612. remove        endp
  613.  
  614.         endps
  615.         end
  616.