home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ddkx86v5.zip / DDKX86 / SRC / DEV / PRINTER / PRTHWIAT.ASM < prev    next >
Assembly Source File  |  1995-04-14  |  169KB  |  2,839 lines

  1. ;*DDK*************************************************************************/
  2. ;
  3. ; COPYRIGHT (C) Microsoft Corporation, 1989
  4. ; COPYRIGHT    Copyright (C) 1995 IBM Corporation
  5. ;
  6. ;    The following IBM OS/2 WARP source code is provided to you solely for
  7. ;    the purpose of assisting you in your development of OS/2 WARP device
  8. ;    drivers. You may use this code in accordance with the IBM License
  9. ;    Agreement provided in the IBM Device Driver Source Kit for OS/2. This
  10. ;    Copyright statement may not be removed.;
  11. ;*****************************************************************************/
  12.  
  13. ; SCCSID = @(#)prthwiat.asm     6.21 92/03/24
  14. ;/**********************************************************************
  15. ;/*                                                                    *
  16. ;/*                                                                    *
  17. ;/*                                                                    *
  18. ;/**********************************************************************
  19.  TITLE PRINTDD - PRINTER DEVICE DRIVER HARDWARE ROUTINES
  20.  NAME PRINTDD
  21. PAGE ,132
  22. .286C
  23.  
  24. ;***********************************************************************
  25. ; CODING CONVENTIONS
  26. ; all psuedo-ops, equates, documentation, publics, and externs are in uppercase.
  27. ; all code and data names are in lowercase.
  28. ;
  29. ; ROUTINES IN THIS MODULE:
  30. ;       INITIALPRT,HYBRID
  31. ;       PRTDEINSTALL
  32. ;       PRINTBLOCK
  33. ;       PRT_TRANSMIT
  34. ;       SEARCHANDSTEAL
  35. ;       eInt_1
  36. ;       eInt_2
  37. ;       eInt_3
  38. ;       PRTINT05
  39. ;       PRTINT07
  40. ;       STARTTIMER
  41. ;       STOPTIMER
  42. ;       PRTTIMGR
  43. ;       TIMERINTERRUPT
  44. ;       CHANGEIRQTOST
  45. ;       CHECKSTATUS
  46. ;       INTERRUPT
  47. ;       SENDCHAR
  48. ;       SENDTODEV
  49. ;       PRT_TIMEOUT_1
  50. ;       PRT_TIMEOUT_2
  51. ;       PRT_TIMEOUT_3
  52. ;       PRT_TIMEOUT
  53. ;       CLEANUP
  54. ;       PRTERP
  55. ;       GETSTATUS,HYBRID
  56. ;       PRTINIT
  57. ;       prtdeterminehardware
  58. ;       RM_PRT_RegisterResources
  59. ;       PARSECMDLINE
  60. ;
  61. ;       MODIFICATION HISTORY
  62. ;
  63. ;   87416       07/11/94   SLC (ChgTeam)   Added one line to proc interrupt
  64. ;                                          to disable interrupts in
  65. ;                                          interrupt01 before returning to
  66. ;                                          interrupt manager.
  67. ;
  68. ;***********************************************************************
  69.  
  70.         .XCREF
  71.         .XLIST
  72.         INCLUDE basemaca.inc            ; VARIOUS MACRO'S (BREAK, LJC, ETC.)
  73.         INCLUDE osmaca.inc
  74.         INCLUDE devsym.inc
  75.         INCLUDE devhlp.inc              ; DEFINITION OF DEVICE HELP CALLS.
  76.         INCLUDE struc.inc               ; STRUCTURED MACRO SUPPORT
  77.         INCLUDE infoseg.inc             ; STRUCTURES DEFINING THE INFOSEG
  78.         INCLUDE pvwxport.inc            ; PERFVIEW STRUCS AND EQUATES.
  79.         INCLUDE iniequ.inc              ; CONFIG.SYS DEFAULT EQUATES
  80.         INCLUDE iodelay.inc             ; IODELAY MACROS
  81.         .LIST
  82.         .CREF
  83.         INCLUDE prtdd.inc               ; PRINTER DEVICE DRIVER INCLUDE FILE
  84.         INCLUDE prtdd1.inc              ; PRINTER DEVICE DRIVER INCLUDE FILE
  85.         INCLUDE prtinit.inc             ; PRINTER DEVICE DRIVER INCLUDE FILE
  86.         INCLUDE prteisa.inc             ; EISA SUPPORT EQUATES
  87.  
  88. BREAK <DATA FOR THE PRINTER DEVICE DRIVER>
  89. ;/********************** START OF SPECIFICATIONS ***********************/
  90. ;/*                                                                    */
  91. ;/* SUBROUTINE NAME: PRTDATA                                           */
  92. ;/*                                                                    */
  93. ;/* DESCRIPTIVE NAME: PRINTER DEVICE DRIVER DATA DECLARATIONS          */
  94. ;/*                                                                    */
  95. ;/*********************** END OF SPECIFICATIONS ************************/
  96. DSEG    SEGMENT public  'data'
  97.  
  98.         EXTRN   glinfoseg:DWORD
  99.         EXTRN   dosvar:DWORD
  100.         EXTRN   device_help:DWORD
  101.         EXTRN   _Device_Help:DWORD
  102.         EXTRN   numofprts:BYTE
  103.         EXTRN   flags:BYTE
  104.         EXTRN   perprtarea:BYTE
  105.         EXTRN   moncache:BYTE
  106.         EXTRN   plptname:BYTE
  107.         PUBLIC  irq5index
  108.         PUBLIC  irq7owner
  109.         PUBLIC  timeoutval
  110.         PUBLIC  deinstallflg
  111.         PUBLIC  doserrors
  112.         PUBLIC  fIRQStolen
  113.                 EVEN
  114. irq5index       dw      ?               ; INDEX INTO PERPRTDATA AREA
  115. irq7owner       dw      ?               ; INDEX INTO PERPRTDATA AREA
  116. timeoutval      dw      ?               ; TIME OUT FOR 1 SECOND (TICKS)
  117. timercount      db      0               ; NUMBER OF TIMER TICKS SINCE IRQ
  118. fIRQStolen      db      0               ; FLAG SET TO 1 IF IRQ WAS STOLEN
  119. timerneeded     db      0               ; BIT 0 = 0 - TIMER NOT NEEDED FOR LPT1
  120.                                         ; BIT 0 = 1 - TIMER NEEDED FOR LPT1
  121.                                         ; BIT 1 = 0 - TIMER NOT NEEDED FOR LPT2
  122.                                         ; BIT 1 = 1 - TIMER NEEDED FOR LPT2
  123.                                         ; BIT 2 = 0 - TIMER NOT NEEDED FOR LPT3
  124.                                         ; BIT 2 = 1 - TIMER NEEDED FOR LPT3
  125. deinstallflg    db      0               ; DEVICES PDD NO LONGER SUPPORTS
  126.                                         ; 0 = LPT1, 1 = LPT2, 2 = LPT3
  127. bustype         dw      0               ; BUS TYPE 1=ISA, 2=EISA, and 4=MC
  128.                 EVEN
  129.                 ; index 0   2    4    6    8    10
  130. blksiz          dw      8, 32, 128, 256, 512, 1024      ; BURST RATE IN BYTES
  131. allowedpending  dw      1,  6,  32,  60, 118,  230      ; MAX OTHER IRQS PENDING
  132. nextindx        dw      0,  0,   2,   4,   0,    0      ; NEXT LOWER BURST RATE
  133. MAXBLKINDX      EQU     (allowedpending-blksiz-2)       ; MAX BURST RATE
  134.  
  135. blkindx         dw      MAXBLKINDX                      ; BURST RATE INDEX
  136. pendirq         dw      0                               ; PENDING IRQ COUNTER
  137.  
  138. doserrors       dw REQDONE,NOACCESS,PAPEROUTERR,WRITEFAULT
  139.  
  140. PUBLIC  data_block                      ; PERFVIEW DATA STRUCTURES
  141. data_block      LABEL   BYTE
  142. db_length       dw      DATA_BLOCK_LEN  ; DATA BLOCK TOTAL LENGTH IN BYTES
  143.                 dw      0               ; IDENTIFIER (ORDINAL)
  144.                 dd      0               ; INSTANCE ID/ GROUP ID
  145.                 dd      RPC_FL_16BIT    ; FLAGS
  146.                 dd      0               ; SEMAPHORE OR SEMAPHORE HANDLE
  147.                 dd      0               ; POINTER TO TIMER ADD FUNCTION
  148.                 dd      0               ; POINTER TO TIMER SUB FUNCTION
  149. DATA_BLOCK_LEN  EQU     $ - data_block  ; LENGTH OF DATA_BLOCK
  150.  
  151. prfvw_ctrs      dd      12 dup (0)      ; PERFVIEW PER DEVICE COUNTER AREA
  152.  
  153. PUBLIC  text_block
  154. text_block      LABEL   BYTE
  155.                 dd      TBH_VER_2_0_0_0 ; VERSION NUMBER
  156. ; TEXT BLOCK IDENTIFIER
  157.                 dw      0               ; BLOCK INSTANCE ID
  158.                 dw      0               ; BLOCK GROUP ID
  159. ; TEXT BLOCK GROUP NAME
  160.                 dd      0               ; FLAGS
  161.                 dw      0               ; SIZE
  162.                 dw      0               ; MESSAGE ID
  163.                 dw      OFFSET driver_name ; OFFSET OF DEVICE DRIVER NAME
  164.                 dw      SEG driver_name ; SEGMENT OF DEVICE DRIVER NAME
  165. ; TEXT BLOCK INSTANCE NAME
  166.                 dd      0               ; FLAGS
  167.                 dw      0               ; SIZE
  168.                 dw      0               ; MESSAGE ID
  169.                 dd      0               ; DEFAULT MESSAGE
  170.                 dd      0               ; MESSAGE FILE NAME
  171.                 dd      0               ; HELP FILE NAME
  172. tb_totalctrs    dd      0               ; NUMBER OF TIMERS AND COUNTERS
  173.                 dw      OFFSET name_block ; OFFSET OF NAME BLOCK
  174.                 dw      SEG name_block  ; SEGMENT OF NAME BLOCK
  175.  
  176. dataend         dw      OFFSET monbuffers ; PTR TO END OF RESIDENT DATA SEGMENT
  177.                                           ; ALL DATA AFTER THIS POINT IS
  178.                                           ; RELEASED AFTER INITIALIZATION
  179.  
  180. monbuffers      db      (MAXPRINTERS * 2) * MaxPBUFCount DUP (00H)
  181.  
  182. ;  ALL DATA AFTER THIS POINT IS RELEASED AFTER INITIALIZATION
  183.  
  184. NUMBER_TMRS_CTRS EQU    3               ; NUMBER OF TIMERS AND COUNTERS
  185.  
  186. str1            db      'LPT1 Write Requests',0
  187. str2            db      'LPT1 Write Time',0
  188. str3            db      'LPT1 Write Bytes',0
  189. str4            db      'LPT2 Write Requests',0
  190. str5            db      'LPT2 Write Time',0
  191. str6            db      'LPT2 Write Bytes',0
  192. str7            db      'LPT3 Write Requests',0
  193. str8            db      'LPT3 Write Time',0
  194. str9            db      'LPT3 Write Bytes',0
  195.  
  196. PUBLIC  name_block
  197. name_block      LABEL   BYTE
  198.                 dd      PVW_CT_CNT      ; NUMBER OF WRITES COUNTER
  199.                 dw      SIZE num_writes ; SIZE OF COUNTER
  200.                 dw      0
  201.                 dw      OFFSET str1     ; OFFSET OF COUNTER NAME
  202.                 dw      SEG str1        ; SEGMENT OF COUNTER NAME
  203.  
  204.                 dd      PVW_CT_TIMR     ; WRITE TIME COUNTER
  205.                 dw      SIZE TIMR       ; SIZE OF COUNTER
  206.                 dw      0
  207.                 dw      OFFSET str2     ; OFFSET OF COUNTER NAME
  208.                 dw      SEG str2        ; SEGMENT OF COUNTER NAME
  209.  
  210.                 dd      PVW_CT_CNT      ; NUMBER OF BYTES WRITTEN COUNTER
  211.                 dw      SIZE write_bytes ; SIZE OF COUNTER
  212.                 dw      0
  213.                 dw      OFFSET str3     ; OFFSET OF COUNTER NAME
  214.                 dw      SEG str3        ; SEGMENT OF COUNTER NAME
  215.  
  216.                 dd      PVW_CT_CNT      ; NUMBER OF WRITES COUNTER
  217.                 dw      SIZE num_writes ; SIZE OF COUNTER
  218.                 dw      0
  219.                 dw      OFFSET str4     ; OFFSET OF COUNTER NAME
  220.                 dw      SEG str4        ; SEGMENT OF COUNTER NAME
  221.  
  222.                 dd      PVW_CT_TIMR     ; WRITE TIME COUNTER
  223.                 dw      SIZE TIMR       ; SIZE OF COUNTER
  224.                 dw      0
  225.                 dw      OFFSET str5     ; OFFSET OF COUNTER NAME
  226.                 dw      SEG str5        ; SEGMENT OF COUNTER NAME
  227.  
  228.                 dd      PVW_CT_CNT      ; NUMBER OF BYTES WRITTEN COUNTER
  229.                 dw      SIZE write_bytes ; SIZE OF COUNTER
  230.                 dw      0
  231.                 dw      OFFSET str6     ; OFFSET OF COUNTER NAME
  232.                 dw      SEG str6        ; SEGMENT OF COUNTER NAME
  233.  
  234.                 dd      PVW_CT_CNT      ; NUMBER OF WRITES COUNTER
  235.                 dw      SIZE num_writes ; SIZE OF COUNTER
  236.                 dw      0
  237.                 dw      OFFSET str7     ; OFFSET OF COUNTER NAME
  238.                 dw      SEG str7        ; SEGMENT OF COUNTER NAME
  239.  
  240.                 dd      PVW_CT_TIMR     ; WRITE TIME COUNTER
  241.                 dw      SIZE TIMR       ; SIZE OF COUNTER
  242.                 dw      0
  243.                 dw      OFFSET str8     ; OFFSET OF COUNTER NAME
  244.                 dw      SEG str8        ; SEGMENT OF COUNTER NAME
  245.  
  246.                 dd      PVW_CT_CNT      ; NUMBER OF BYTES WRITTEN COUNTER
  247.                 dw      SIZE write_bytes ; SIZE OF COUNTER
  248.                 dw      0
  249.                 dw      OFFSET str9     ; OFFSET OF COUNTER NAME
  250.                 dw      SEG str9        ; SEGMENT OF COUNTER NAME
  251.  
  252. PUBLIC driver_name
  253. driver_name     db      'Parallel Port Device Driver',0
  254. ddname          db      'print01.sys',0
  255.  
  256. DSEG    ENDS
  257.  
  258. SWAPSEG SEGMENT PUBLIC  'code'
  259.         ASSUME  CS:SWAPSEG,DS:DSEG,ES:NOTHING,SS:NOTHING
  260.  
  261.         EXTRN   PLPTCMD_Entry:FAR
  262.  
  263. BREAK <INITAILIZE PRINTER>
  264. ;/********************** START OF SPECIFICATIONS ***********************/
  265. ;/*                                                                    */
  266. ;/* SUBROUTINE NAME: INITIALPRT                                        */
  267. ;/*                                                                    */
  268. ;/* DESCRIPTIVE NAME: INITIALIZE PRINTERS                              */
  269. ;/*                                                                    */
  270. ;/* FUNCTION: THE FUNCTION OF THIS ROUTINE IS TO INITIALIZE THE        */
  271. ;/*           PRINTER WHOSE DEVICE ADDRESS IS IN AX.                   */
  272. ;/*                                                                    */
  273. ;/* NOTES:                                                             */
  274. ;/*                                                                    */
  275. ;/* ENTRY POINT: INITIALPRT                                            */
  276. ;/*    LINKAGE : CALL NEAR OR FAR                                      */
  277. ;/*                                                                    */
  278. ;/* INPUT:     DX = 0FFH IF CALLED FROM PRTDD INITIALIZE ROUTINE.      */
  279. ;/*                                                                    */
  280. ;/* EXIT-NORMAL:   N/A                                                 */
  281. ;/*                                                                    */
  282. ;/* EXIT-ERROR:    N/A                                                 */
  283. ;/*                                                                    */
  284. ;/* INTERNAL REFERENCES:  getstatus                                    */
  285. ;/*    ROUTINES:                                                       */
  286. ;/*                                                                    */
  287. ;/* EXTERNAL REFERENCES:  DEVICE_HELP  ProcBlock                       */
  288. ;/*    ROUTINES:                                                       */
  289. ;/*                                                                    */
  290. ;/*********************** END OF SPECIFICATIONS ************************/
  291. Procedure initialprt,HYBRID
  292.         ASSUME  CS:SWAPSEG,DS:DSEG,ES:NOTHING,SS:NOTHING
  293.         SaveReg <cx,dx>                                 ; SAVE REGISTERS
  294.         mov     dx,[di].deviceaddr                      ; GET DEVICE ADDRESS
  295.         inc     dx
  296.         inc     dx                                      ; POINT TO CONTROL PORT
  297.         mov     al,INITLINELOW                          ; SET INIT LINE LOW
  298.         out     dx,al                                   ; SEND NEW CONTROL VALUE
  299.         mov     ax,INITLOOPCNT                          ; LOOP COUNT
  300. initprt:
  301.         dec     ax
  302.         jnz     initprt                                 ; LOOP UNTIL RESET DONE
  303.         mov     al,INITLINEHIGH                         ; SET INIT LINE HIGH
  304.         out     dx,al                                   ; SEND NEW CONTROL VALUE
  305.  
  306.         ; MUST WAIT UNTIL NOT BUSY BEFORE RETURNING TO USER OR USER'S NEXT
  307.         ; REQUEST WILL FAIL.
  308.  
  309.         pop     dx                                      ; GET DD INIT FLAG
  310.         push    dx
  311.  
  312.         test    [di].commonflags1,BOOTINIT              ; IS THIS BOOT TIME?
  313.         jnz     initprt2                                ; JUMP IF IT IS
  314.  
  315.         ; PROPRINTER RETURNS WITH NORMAL STATUS BUT NEXT PRINT REQUEST WILL FAIL
  316.         ; UNLESS THIS THREAD IS BLOCKED.
  317.  
  318.         mov     cx,BUSYRETRY                            ; LOOP CONTROL VARIABLE
  319. initprt1:
  320.         SaveReg <ax,bx,cx,dx,di>                        ; SAVE REGISTERS
  321.         mov     bx,[di].dosoffset                       ; OFF. OF THIS REQ BLK
  322.         inc     bx                                      ; MAKE BLOCK ID UNIQUE
  323.         mov     ax,[di].dosrqseg                        ; SEG. OF THIS REQ BLK
  324.         mov     cx,0FFH                                 ; TIME LIMIT LOW VALUE
  325.         mov     di,0                                    ; TIME LIMIT HIGH VALUE
  326.         mov     dh,BLOCKSLEEPNOTINT                     ; SLEEP NOTINTERRUPTIBLE
  327.         mov     dl,DevHlp_ProcBlock                     ; BLOCK FUNCTION
  328.         call    DWORD PTR [device_help]                 ; CALL DEVHLP TO BLOCK
  329.         RestoreReg <di,dx,cx,bx,ax>                     ; RESTORE REGISTERS
  330.         CALLFAR getstatus                               ; GET THE PORT STATUS
  331.         test    ah,NOTBUSY                              ; IF DEVICE NOT BUSY
  332.         jnz     initprt2                                ; THEN RETURN
  333.         loop    initprt1                                ; SEE IF NOT BUSY
  334. initprt2:
  335.         RestoreReg <dx,cx>                              ; RESTORE REGISTERS
  336.         ret
  337. EndProc initialprt
  338.  
  339. BREAK <PRINT DEVICE DRIVER DEINSTALL ROUTINE>
  340. ;/********************** START OF SPECIFICATIONS ***********************/
  341. ;/*                                                                    */
  342. ;/* SUBROUTINE NAME:  PRTDEINSTALL                                     */
  343. ;/*                                                                    */
  344. ;/* DESCRIPTIVE NAME:  PRINT DEVICE DRIVER DEINSTALL ROUTINE.          */
  345. ;/*                                                                    */
  346. ;/* FUNCTION:  THE FUNCTION OF THIS SUBROUTINE IS TO DEINSTALL THE     */
  347. ;/*            THE PRINTER DEVICE DRIVER ONE DEVICE AT A TIME.         */
  348. ;/*                                                                    */
  349. ;/* NOTES:  DEINSTALL COMES IN ONLY AT INIT TIME                       */
  350. ;/*         DEINSTALL OCCURS ON A DEVICE BASIS                         */
  351. ;/*         KERNEL INSURES NO MORE REQUESTS AFTER DEINSTALL            */
  352. ;/*         SPOOLER CANNOT BE ACTIVE YET                               */
  353. ;/*                                                                    */
  354. ;/* ENTRY POINT: PRTDEINSTALL                                          */
  355. ;/*    LINKAGE : CALL NEAR                                             */
  356. ;/*                                                                    */
  357. ;/* INPUT:     ES = VIRTUAL  SEGMENT OF REQUEST BLOCK                  */
  358. ;/*            BX = VIRTUAL  OFFSET OF REQUEST BLOCK                   */
  359. ;/*            DI = OFFSET TO APPROPRIATE PERPRTDATA AREA              */
  360. ;/*                                                                    */
  361. ;/* REGISTERS USED: ALL REGISTERS SAVED BY THE KERNEL                  */
  362. ;/*                                                                    */
  363. ;/* EXIT-NORMAL:  ES:[BX].PktStatus = REQDONE                          */
  364. ;/*                                                                    */
  365. ;/* EXIT-ERROR:   N/A                                                  */
  366. ;/*                                                                    */
  367. ;/* INTERNAL REFERENCES:  NONE                                         */
  368. ;/*    ROUTINES:                                                       */
  369. ;/*                                                                    */
  370. ;/* EXTERNAL REFERENCES:  DEVICE_HELP  RegisterPDD                     */
  371. ;/*    ROUTINES:                       FreeGDTSelector                 */
  372. ;/*                                                                    */
  373. ;/*********************** END OF SPECIFICATIONS ************************/
  374. Procedure prtdeinstall near
  375.         ASSUME  CS:SWAPSEG,DS:DSEG,ES:NOTHING,SS:NOTHING
  376.         cmp     [di].accessctr,0                        ; NO ONE ACCESSING PDD
  377.         je      prtdein1                                ; TRY TO DEINSTALL
  378.         mov     es:[bx].PktStatus,UNKNOWNCMD            ; ELSE REFUSE TO DEIN
  379.         jmp     SHORT prtdein3                          ; EXIT
  380.  
  381. prtdein1:
  382.         SaveReg  <bx,es>                                ; SAVE REGISTERS
  383.         mov     al,[di].deviceflag                      ; GET DEVICE FLAG
  384.         or      deinstallflg,al                         ; SET DEINSTALL FLAG
  385.         cmp     deinstallflg,DEINSTALLMSK               ; IF ALL DEV != DEINSTAL
  386.         jne     prtdein2                                ; THEN RETURN
  387.  
  388.         ; DEREGISTER THE PLPT'S VDD SERVICES ENTRY POINT WITH VLPT.
  389.  
  390.         push    di                                      ; SAVE PER PRT AREA
  391.         lea     si,plptname                             ; LOAD PLPT NAME
  392.         push    0
  393.         pop     es                                      ; MAKE NULL PTR
  394. .386
  395.         xor     edi,edi                                 ; MAKE NULL PTR
  396. .286
  397.         mov     dl,DevHlp_RegisterPDD                   ; REGISTERPDD FUNC
  398.         call    DWORD PTR [device_help]                 ; CALL DEVICE HELP
  399.         pop     di
  400.  
  401. prtdein2:
  402.         ; FREE GDT SELECTOR ALLOCATED AT DEVICE DRIVER INITIALIZATION TIME
  403.  
  404.         mov     ax,[di].gdtuserbuf                      ; GET GDT SELECTOR
  405.         mov     dl,DevHlp_FreeGDTSelector               ; FREE GDT SEL FUNC
  406.         call    DWORD PTR [device_help]                 ; CALL DEVICE HELP
  407.         mov     [di].gdtuserbuf,0                       ; CLEAR GDT SELECTOR
  408.  
  409.         ; FREE PRINTBUF GDT SELECTOR ALLOCATED AT DEVICE DRIVER INIT TIME
  410.  
  411.         mov     ax,[di].gdtprintbuf                     ; GET GDT SELECTOR
  412.         mov     dl,DevHlp_FreeGDTSelector               ; FREE GDT SEL FUNC
  413.         call    DWORD PTR [device_help]                 ; CALL DEVICE HELP
  414.         mov     [di].gdtprintbuf,0                      ; CLEAR GDT SELECTOR
  415.  
  416.         RestoreReg <es,bx>                              ; RESTORE REGISTERS
  417.  
  418.         mov     es:[bx].PktStatus,REQDONE               ; SET THE DONE BIT
  419. prtdein3:
  420.         ret
  421. EndProc prtdeinstall
  422.  
  423. SWAPSEG ENDS
  424.  
  425. CSEG    SEGMENT public  'code'
  426.         ASSUME  CS:CSEG,DS:DSEG,ES:NOTHING,SS:NOTHING
  427.  
  428.         EXTRN   sendmonerpkt:NEAR
  429.         EXTRN   eisainit:NEAR
  430.         EXTRN   prt_polling:NEAR
  431.         EXTRN   prt_timeout_polling:NEAR
  432.         EXTRN   _RM_PRT_CreateDriver:NEAR
  433.         EXTRN   _RM_PRT_DestroyDriver:NEAR
  434.         EXTRN   _RM_PRT_AllocPorts:NEAR
  435.         EXTRN   _RM_PRT_DeallocPorts:NEAR
  436.         EXTRN   _RM_PRT_AllocIRQ:NEAR
  437.         EXTRN   _RM_PRT_DeallocIRQ:NEAR
  438.         EXTRN   _RM_PRT_CreateAdapter:NEAR
  439.         EXTRN   _RM_PRT_DestroyAdapter:NEAR
  440.  
  441. BREAK <PRINT A BLOCK OF CHARACTERS>
  442. ;/********************** START OF SPECIFICATIONS ***********************/
  443. ;/*                                                                    */
  444. ;/* SUBROUTINE NAME:  PRINTBLOCK                                       */
  445. ;/*                                                                    */
  446. ;/* DESCRIPTIVE NAME:  Schedule a print block request.                 */
  447. ;/*                                                                    */
  448. ;/* FUNCTION:   This routine will throttle back PIO print requests     */
  449. ;/*             in order to improve mouse and keyboard usability when  */
  450. ;/*             printing is generating many interrupts.  Due to the    */
  451. ;/*             rotation of the 8259 programable interrupt controller, */
  452. ;/*             mouse and keyboard hardware interrupts have a lower    */
  453. ;/*             priority than the printer.                             */
  454. ;/*                                                                    */
  455. ;/* NOTES:                                                             */
  456. ;/*                                                                    */
  457. ;/* ENTRY POINT:                                                       */
  458. ;/*         LINKAGE:  printblock:near                                  */
  459. ;/*                   call printblock                                  */
  460. ;/*                                                                    */
  461. ;/* INPUT:  ES = Virtual segment of Kernel request block               */
  462. ;/*         BX = Virtual offset of Kernel request block                */
  463. ;/*      DS:DI = Offset to appropriate perprtdata area                 */
  464. ;/*      IOACTIVE FLAG OR MONPRINTING FLAG SET TO ON                   */
  465. ;/*                                                                    */
  466. ;/* EXIT-NORMAL:  ES:[BX] = Kernel Request Block                       */
  467. ;/*               DS:[DI] = Perprtdata area                            */
  468. ;/*               DS:[SI] = ABIOS Request Block                        */
  469. ;/*               ES:[BX].Pktstatus = filled in.                       */
  470. ;/*               ES:[BX].IOCount = filled in.                         */
  471. ;/*               IOACTIVE FLAG SET TO OFF                             */
  472. ;/*               CANMONPKT FLAG SET TO OFF                            */
  473. ;/*                                                                    */
  474. ;/* EXIT-ERROR:   See exit normal above.                               */
  475. ;/*                                                                    */
  476. ;/* EFFECTS:                                                           */
  477. ;/*                                                                    */
  478. ;/* INTERNAL REFERENCES:  prt_transmit                                 */
  479. ;/*    ROUTINES:          prt_polling                                  */
  480. ;/*                                                                    */
  481. ;/* EXTERNAL REFERENCES:  DEVICE_HELP  PhysToGDTSelector               */
  482. ;/*    ROUTINES:                       ProcBlock                       */
  483. ;/*                                                                    */
  484. ;/*********************** END OF SPECIFICATIONS ************************/
  485. Procedure printblock far
  486.         ASSUME  CS:CSEG,DS:DSEG,ES:NOTHING,SS:NOTHING
  487.         LocalVar        _IOCount,WORD                   ; COUNT TO TRANSMIT
  488.         LocalVar        _Printed,WORD                   ; COUNT PRINTED
  489.  
  490.         EnterProc
  491.  
  492.         test    [di].commonflags, USEPOLLING            ; USE POLLING?
  493.         jz      prtblk0                                 ; NO, USE INTS
  494.         call    prt_polling                             ; CALL POLL ROUTINE
  495.         jmp     prtblk6                                 ; AND RETURN
  496.  
  497. prtblk0:
  498.         mov     cx,es:[bx].IOCount
  499.         mov     _IOCount,cx                             ; SAVE COUNT TO TRANSMIT
  500.         mov     _Printed,0                              ; INITIALIZE PRT COUNT
  501.  
  502.         mov     [di].printbufoff,0                      ; SET OFFSET TO ZERO
  503.         push    bx                                      ; SAVE REGISTER
  504.         mov     ax,WORD PTR es:[bx].IOpData + 2         ; GET PHYS ADDR - HIGH
  505.         mov     bx,WORD PTR es:[bx].IOpData             ; GET PHYS ADDR - LOW
  506.         mov     si,[di].gdtprintbuf                     ; GET GDT SELECTOR
  507.         mov     dl,DevHlp_PhysToGDTSelector             ; CONVERT PHYS TO GDT
  508.         call    DWORD PTR [device_help]                 ; DO ADDRESS CONVERSION
  509.         pop     bx                                      ; RESTORE REGISTER
  510.  
  511. prtblk1:
  512.         mov     pendirq,0                               ; CLEAR PENDING IRQ CNT
  513.         mov     si,blkindx                              ; GET BURST RATE INDEX
  514.         mov     ax,blksiz[si]                           ; GET BURST RATE
  515.         cmp     es:[bx].IOCount,ax                      ; IF LENGTH <= BLKSIZ
  516.         jbe     prtblk2                                 ; NO LOW IRQ PREEMPTING
  517.         mov     es:[bx].IOCount,ax                      ; SET PREEMPT INTERVAL
  518.  
  519. prtblk2:
  520.         call    prt_transmit                            ; TRANSMIT BYTES
  521.  
  522.         mov     ax,pendirq                              ; GET PENDING IRQ COUNT
  523.         mov     si,blkindx                              ; GET BURST RATE INDEX
  524.         cmp     allowedpending[si],ax                   ; IF ALLOWED >= PENDING
  525.         jae     prtblk3                                 ; THEN INC BURST RATE
  526.         mov     si,nextindx[si]                         ; ELSE DEC BURST RATE
  527.         jmp     SHORT prtblk31
  528. prtblk3:
  529.         cmp     si,MAXBLKINDX                           ; IF MAX BURST RATE
  530.         je      prtblk32                                ; THEN DON'T INCREMENT
  531.         add     si,2                                    ; ELSE INC BURST RATE
  532. prtblk31:
  533.         mov     blkindx,si                              ; SAVE NEXT RATE INDEX
  534. prtblk32:
  535.  
  536.         mov     ax,es:[bx].IOCount                      ; GET PRINTED COUNT
  537.         add     _Printed,ax                             ; ADD PRINTED TO TOTAL
  538.  
  539.         add     [di].printbufoff,ax                     ; ADD PRINTED TO OFFSET
  540.  
  541.         mov     ax,_IOCount                             ; GET INITIAL COUNT
  542.         sub     ax,_Printed                             ; CALC REMAINING
  543.         jz      prtblk5                                 ; IF ZERO, EXIT
  544.  
  545.         cmp     es:[bx].PktStatus,REQDONE               ; ERROR?
  546.         jne     prtblk5                                 ; YES, EXIT
  547.  
  548.         mov     es:[bx].IOCount,ax                      ; MOVE REMAIN TO REQ PKT
  549.         mov     es:[bx].PktStatus,0                     ; RESET RETURN CODE
  550.  
  551.         ; COMPENSATE FOR HIGH HARDWARE INTERRUPT PRIORITY BY PREEMPTING
  552.         ; TIME SLICE AND ALLOWING MOUSE AND KEYBOARD TIME TO SERVICE.
  553.  
  554.         SaveReg <bx,di>                                 ; SAVE REGISTERS
  555.         mov     ax,es                                   ; REQ BLK SEG ADDRESS
  556.         inc     bx                                      ; UNIQUE BLOCK ID
  557.         mov     cx,1                                    ; TIME LIMIT LOW VALUE
  558.         mov     di,0                                    ; TIME LIMIT HIGH VALUE
  559.         mov     dh,BLOCKSLEEPNOTINT                     ; SLEEP NOTINTERRUPTIBLE
  560.         mov     dl,DevHlp_ProcBlock                     ; BLOCK FUNCTION
  561.         call    DWORD PTR [device_help]                 ; CALL DEVHLP TO BLOCK
  562.         RestoreReg <di,bx>                              ; RESTORE REGISTERS
  563.         jmp     SHORT prtblk1                           ; DO MORE PRINTING
  564.  
  565. prtblk5:
  566.         mov     ax,_Printed                             ; GET PRINTED COUNT
  567.         mov     es:[bx].IOCount,ax                      ; RETURN PRINTED COUNT
  568.  
  569. prtblk6:
  570.         and     [di].commonflags1,NOT CANMONPKT         ; TURN OFF CANCEL FLAG
  571.         LeaveProc
  572.         ret
  573. EndProc printblock
  574.  
  575. BREAK <TRANSMIT A BLOCK OF CHARACTERS>
  576. ;/********************** START OF SPECIFICATIONS ***********************/
  577. ;/*                                                                    */
  578. ;/* SUBROUTINE NAME:  PRT_TRANSMIT                                     */
  579. ;/*                                                                    */
  580. ;/* DESCRIPTIVE NAME:  TRANSMIT A BLOCK OF DATA ROUTINE                */
  581. ;/*                                                                    */
  582. ;/* FUNCTION: THE FUNCTION OF THIS SUBROUTINE IS TO PRINT A BLOCK      */
  583. ;/*           OF CHARACTERS. IT WILL ENABLE OR DISABLE THE INTERRUPT   */
  584. ;/*           AT THE PORT OF THE SPECIFIED DEVICE, SETUP THE WAITTIME  */
  585. ;/*           AND RESUME POINTERS IN THE PRINT REQUEST BLOCK AND CALL  */
  586. ;/*           SENDCHAR TO SEND THE FIRST CHARACTER.                    */
  587. ;/*                                                                    */
  588. ;/*                                                                    */
  589. ;/* NOTES:                                                             */
  590. ;/*                                                                    */
  591. ;/* ENTRY POINT:                                                       */
  592. ;/*         LINKAGE:  prt_transmit:near                                */
  593. ;/*                   call prt_transmit                                */
  594. ;/*                                                                    */
  595. ;/* INPUT:  ES = Virtual segment of Kernel request block               */
  596. ;/*         BX = Virtual offset of Kernel request block                */
  597. ;/*      DS:DI = Offset to appropriate perprtdata area                 */
  598. ;/*      IOACTIVE FLAG OR MONPRINTING FLAG SET TO ON                   */
  599. ;/*                                                                    */
  600. ;/* EXIT-NORMAL:  ES:[BX] = Kernel Request Block                       */
  601. ;/*               DS:[DI] = Perprtdata area                            */
  602. ;/*               ES:[BX].Pktstatus = filled in.                       */
  603. ;/*               ES:[BX].IOCount = filled in.                         */
  604. ;/*               IOACTIVE FLAG SET TO OFF                             */
  605. ;/*                                                                    */
  606. ;/* EXIT-ERROR:   See exit normal above.                               */
  607. ;/*                                                                    */
  608. ;/* EFFECTS:                                                           */
  609. ;/*                                                                    */
  610. ;/* INTERNAL REFERENCES:  sendchar                                     */
  611. ;/*    ROUTINES:          starttimer                                   */
  612. ;/*                       cleanup                                      */
  613. ;/*                       searchandsteal                               */
  614. ;/*                                                                    */
  615. ;/* EXTERNAL REFERENCES:  DEVICE_HELP  SetIRQ                          */
  616. ;/*    ROUTINES:                       TickCount                       */
  617. ;/*                                    ProcBlock                       */
  618. ;/*                                                                    */
  619. ;/*********************** END OF SPECIFICATIONS ************************/
  620. Procedure prt_transmit near
  621.         ASSUME  CS:CSEG,DS:DSEG,ES:NOTHING,SS:NOTHING
  622.         pvtimer 1                                       ; SUB FROM PFVW TIMER
  623.         mov     ax,es:[bx].IOcount                      ; INITIAL COUNT
  624.         mov     [di].initialcount,ax                    ; SAVE INITIALCOUNT
  625.         mov     [di].prtcount, 0                        ; CLEAR PRINTED COUNT
  626.  
  627.         ; TRY TO SET THE APPROPRIATE IRQ LEVEL.  IF IT FAILS, WE KNOW IT'S IN
  628.         ; USE AND WILL HAVE TO DRIVE THE DEVICE BY TIMER INTERRUPTS.
  629.  
  630.         test    [di].share_interrupt, INT_SHARING       ; INT SHARING SUPPORT?
  631.         jz      prtxmit2                                ; NO
  632.         xor     ch,ch                                   ; CLEAR HIGH BYTE
  633.         mov     cl,[di].intlevel                        ; SPECIFY INT LEVEL
  634.         jmp     short prtxmit3                          ; ALREADY HAVE THE IRQ
  635.  
  636. prtxmit2:
  637.         push    bx
  638.         mov     ax,[di].introutine                      ; OFF HARD INT HANDLER
  639.         xor     bh,bh                                   ; ZERO OUT BH
  640.         mov     bl,[di].intlevel                        ; HARD INT LEVEL NUMBER
  641.         mov     dh,0                                    ; LEVEL NOT SHARED
  642.         cli                                             ; DISABLE INTERRUPTS
  643.         mov     dl,DevHlp_SetIRQ                        ; ASSIGN HARDWARE INT
  644.         call    DWORD PTR [device_help]                 ; CALL DEVHLP
  645.         mov     [di].curintlevel,0                      ; ASSUME RUN OFF TIMER
  646.         mov     cx,bx
  647.         pop     bx
  648.         jc      prtxmit4                                ; IF IN-USE RUN ON TIMER
  649.  
  650. prtxmit3:
  651.         mov     [di].curintlevel,cl                     ; SAVE HARD INT LEVEL
  652.         cmp     cl,IRQ7INTNUM                           ; IF IRQ NOT IRQ 7
  653.         jne     prtxmit4                                ; THEN JUMP
  654.         mov     al,[di].deviceindex                     ; GET DEVICE INDEX
  655.         xor     ah,ah                                   ; ZERO OUT AH
  656.         mov     irq7owner,ax                            ; SET OWNER OF IRQ7
  657. prtxmit4:
  658.         sti                                             ; ENABLE INTERRUPTS
  659.         push    bx
  660.         mov     [di].timeoutctr,0                       ; CLEAR TIMEOUT CTR
  661.         mov     ax,[di].timeout_off                     ; TIMEOUT ENTRY POINT
  662.         mov     bx,timeoutval                           ; TIMEOUT IN TICKCOUNTS
  663.         mov     dl,DevHlp_TickCount                     ; CALL TIMER SERVICES
  664.         call    DWORD PTR [device_help]
  665.  
  666.         call    sendchar                                ; CHECK STATUS PORT AND
  667.         pop     bx                                      ; PRINT FIRST CHARACTER
  668.  
  669.         cmp     [di].curintlevel,0                      ; IF !RUNNING ON TIMER
  670.         jne     prtxmit41                               ; THEN WAIT FOR HARD INT
  671.         call    starttimer                              ; START THE TIMER
  672.  
  673. prtxmit41:
  674.         cli                                             ; DISABLE INTERRUPTS
  675.         test    es:[bx].PktStatus,REQDONE               ; IF REQUEST IS DONE
  676.         jnz     prtxmit5                                ; THEN EXIT
  677.         push    di                                      ; SAVE DI
  678.         mov     ax,es                                   ; REQ BLK SEG ADDRESS
  679.         inc     bx                                      ; UNIQUE BLOCK ID
  680.         mov     cx,BLOCKLOWVALUE                        ; -1 NEVER TIMEOUT
  681.         mov     di,BLOCKLOWVALUE                        ; -1 NEVER TIMEOUT
  682.         mov     dh,BLOCKSLEEPINT                        ; SLEEP INTERRUPTIBLE
  683.         mov     dl,DevHlp_ProcBlock                     ; PROCBLOCK FUNCTION
  684.         call    DWORD PTR [device_help]                 ; CALL DEVHLP
  685.         dec     bx                                      ; ADDRESS REQ BLOCK
  686.         pop     di                                      ; RESTORE DI
  687.         jc      prtxmit45                               ; UNUSUAL WAKEUP
  688.         jmp     prtxmit41                               ; RETEST DONE
  689.  
  690. prtxmit45:
  691.         mov     es:[bx].PktStatus,CHARIOINT             ; RETURN STATUS
  692.         call    cleanup                                 ; TERMINATE PRT REQ
  693. prtxmit5:
  694.         cmp     [di].curintlevel,IRQ7INTNUM             ; DID IRQ7 FINISH?
  695.         jne     prtxmit6                                ; YES, GIVE TO TIMER DEV
  696.         call    searchandsteal                          ; GIVE IRQ7 TO SYS TIMER
  697. prtxmit6:
  698.         sti                                             ; ENABLE INTERRUPTS
  699.         pvtimer                                         ; ADD TO PFVW TIMER/CTRS
  700.         ret
  701. EndProc prt_transmit
  702.  
  703. BREAK <SEARCH FOR TIMER AND GIVE IT THE IRQ>
  704. ;/********************** START OF SPECIFICATIONS ***********************/
  705. ;/*                                                                    */
  706. ;/* SUBROUTINE NAME: SEARCHANDSTEAL                                    */
  707. ;/*                                                                    */
  708. ;/* DESCRIPTIVE NAME: SEARCH FOR DEVICE ON TIMER, REPLACE WITH IRQ7.   */
  709. ;/*                                                                    */
  710. ;/* FUNCTION: THE FUNCTION OF THIS SUBROUTINE IS TO SEARCH FOR A       */
  711. ;/*           REQUEST RUNNING ON A DEVICE USING THE SYSTEM TIMER AND   */
  712. ;/*           TRANSFER IT TO RUN OFF OF IRQ7.                          */
  713. ;/*                                                                    */
  714. ;/* ENTRY POINT: SEARCHANDSTEAL                                        */
  715. ;/*    LINKAGE : CALL NEAR                                             */
  716. ;/*                                                                    */
  717. ;/* INPUT: NONE                                                        */
  718. ;/*                                                                    */
  719. ;/* EXIT-NORMAL:  REQ on system timer transfered to IRQ7               */
  720. ;/*                                                                    */
  721. ;/* EXIT-ERROR :  See EXIT-NORMAL above.                               */
  722. ;/*                                                                    */
  723. ;/* INTERNAL REFERENCES:  stoptimer                                    */
  724. ;/*    ROUTINES:          sendchar                                     */
  725. ;/*                                                                    */
  726. ;/* EXTERNAL REFERENCES:  DEVICE_HELP  SetIRQ                          */
  727. ;/*    ROUTINES:                                                       */
  728. ;/*                                                                    */
  729. ;/*********************** END OF SPECIFICATIONS ************************/
  730. Procedure searchandsteal near
  731.         ASSUME  CS:CSEG,DS:DSEG,ES:NOTHING,SS:NOTHING
  732.         pusha                                           ; SAVE REGESTERS
  733.         push    es                                      ; SAVE EXTRA SEGMENT
  734.         test    timerneeded,TIMERMASK                   ; IF TIMER RUNNING
  735.         jnz     srchandstl0                             ; CONTINUE
  736.         jmp     srchandstl5                             ; EXIT
  737.  
  738.         ; FIND DEVICE RUNNING OFF OF THE SYSTEM TIMER
  739.  
  740. srchandstl0:
  741.         mov     ax,1                                    ; SET AX = 1
  742.         xor     ch,ch                                   ; MAKE CH 0
  743.         mov     cl,numofprts                            ; # OF PARALLEL PORTS
  744.         mov     di,OFFSET perprtarea                    ; DI = START OF DATABASE
  745. srchandstl1:
  746.         test    timerneeded,al                          ; IF DEVICE USING TIMER
  747.         jnz     srchandstl3                             ; THEN FOUND DEVICE
  748.  
  749. srchandstl2:
  750.         add     di,SIZE printer_database                ; DX = SIZE OF ONE ENTRY
  751.         sal     al,1                                    ; CHECK NEXT DEVICE
  752.         loop    srchandstl1                             ; TRY NEXT DEVICE
  753.  
  754.         jcxz    srchandstl5                             ; IF CX=0, !FOUND, EXIT
  755. srchandstl3:
  756.         mov     ax,[di].initialcount                    ; GET INITIAL COUNT
  757.         cmp     ax,[di].prtcount                        ; IF NO BYTES REMAINING
  758.         je      srchandstl2                             ; THEN TRY NEXT DEVICE
  759.  
  760.         ; SETUP SYSTEM TIMER JOB TO RUN ON IRQ7
  761.  
  762.         cmp     [di].share_interrupt,INT_SHARING        ; IF INT SHARING
  763.         je      srchandstl4                             ; THEN DON'T SET AGAIN
  764.  
  765.         mov     ax,[di].introutine                      ; OFF HARD INT HANDLER
  766.         xor     bh,bh                                   ; ZERO OUT BH
  767.         mov     bl,[di].intlevel                        ; HARD INT LEVEL NUMBER
  768.         mov     dh,0                                    ; LEVEL NOT SHARED
  769.         mov     dl,DevHlp_SetIRQ                        ; ASSIGN HARDWARE INT
  770.         call    DWORD PTR [device_help]                 ; CALL DEVHLP
  771.         jc      srchandstl5                             ; IF ERROR, CAN'T SWITCH
  772.  
  773. srchandstl4:
  774.         mov     [di].curintlevel,IRQ7INTNUM             ; SET LEVEL TO IRQ7
  775.  
  776.         mov     al,[di].deviceindex                     ; GET DEVICE INDEX
  777.         xor     ah,ah                                   ; ZERO OUT AH
  778.         mov     irq7owner,ax                            ; SET OWNER OF IRQ7
  779.  
  780.         ; SHUT DOWN DEVICE ON SYSTEM TIMER AND RESTART IT ON HARDWARE
  781.         ; INTERRUPT LEVEL 7 (IRQ7)
  782.  
  783.         call    stoptimer                               ; STOP DEVICE ON TIMER
  784.         call    sendchar                                ; PRINT NEXT CHAR W IRQ7
  785.  
  786. srchandstl5:
  787.         pop     es                                      ; RESTORE EXTRA SEGMENT
  788.         popa                                            ; RESTORE REGESTERS
  789.         ret
  790. EndProc searchandsteal
  791.  
  792. BREAK <SHARED INTERRUPT HANDLERS>
  793. ;/********************** START OF SPECIFICATIONS ***********************/
  794. ;/*                                                                    */
  795. ;/* SOURCE FILE NAME:  eInt_1                                          */
  796. ;/*                    eInt_2                                          */
  797. ;/*                    eInt_3                                          */
  798. ;/*                                                                    */
  799. ;/* DESCRIPTIVE NAME:  Printer Hardware Interrupt Handlers for shared  */
  800. ;/*                    interrupts on an EISA system.                   */
  801. ;/*                                                                    */
  802. ;/* FUNCTION:  These routines are used as entry points to the          */
  803. ;/*            interrupt service routine when OS/2 is run on an EISA   */
  804. ;/*            system that is sharing the printer's interrupt line.    */
  805. ;/*            This "interrupt sharing" is TRUE hardware interrupt     */
  806. ;/*            sharing, by use of level triggered interrupt lines.     */
  807. ;/*            This allows the interrupt line to be shared between the */
  808. ;/*            printer and other non-printer devices that are          */
  809. ;/*            configured for the same interrupt line.  These entry    */
  810. ;/*            points will ONLY be used when the EISA configuration    */
  811. ;/*            information indicates that the printer's interrupt line */
  812. ;/*            is being shared.  Otherwise, the ISA compatible entry   */
  813. ;/*            points, PRTINT05 and PRTINT07 will be used.             */
  814. ;/*                                                                    */
  815. ;/* NOTE:   The Hardware Interrupt Manager saves all registers and     */
  816. ;/*         calls with interrupts enabled.  On exit, interrupts are    */
  817. ;/*         disabled to prevent nested interrupts after EOI.           */
  818. ;/*                                                                    */
  819. ;/* INPUT:  DS = setup to our data segment.                            */
  820. ;/*                                                                    */
  821. ;/* ENTRY POINT:  eInt_1, eInt_2, eInt_3                               */
  822. ;/*    LINKAGE :  CALL FAR                                             */
  823. ;/*                                                                    */
  824. ;/* EXIT-NORMAL:  Return to the hardware interrupt manager.            */
  825. ;/*                                                                    */
  826. ;/* EXIT-ERROR:   N/A                                                  */
  827. ;/*                                                                    */
  828. ;/* INTERNAL REFERENCES:  interrupt                                    */
  829. ;/*    ROUTINES:                                                       */
  830. ;/*                                                                    */
  831. ;/* EXTERNAL REFERENCES:  NONE                                         */
  832. ;/*    ROUTINES:                                                       */
  833. ;/*                                                                    */
  834. ;/*********************** END OF SPECIFICATIONS ************************/
  835. Procedure eInt_1 far
  836.         mov     di,OFFSET perprtarea                    ; FIRST PERPRTDATA AREA
  837.         mov     si, LPT1_INDEX                          ; SET-UP FOR INTERRUPT
  838.         test    [di].share_interrupt, INT_SHARING       ; SUPPORTS INT SHARING?
  839.         jz      eInt11                                  ; NO: GO PROCESS INT.
  840.         test    [di].commonflags,CHARACTER_OUT          ; HAS A CHAR BEEN SENT?
  841.         jz      eInt10                                  ; JUMP IF NO.
  842.         test    [di].commonflags1,PDDDIRACCESS          ; PDD HAS PORT ACCESS?
  843.         jz      eInt10                                  ; NO, IGNORE PORT
  844.         mov     dx, [di].deviceaddr                     ; DATA PORT
  845.         inc     dx                                      ; STATUS PORT
  846.         cli                                             ; INTS BACK OFF
  847.         in      al, dx                                  ; GET CURRENT STATUS
  848.         test    al, INT_PENDING                         ; OUR INTERRUPT?
  849.         jz      eInt11                                  ; Y: PROCESS IT
  850. eInt10:                                                 ; 
  851.         stc                                             ; N: SIGNAL KERNEL
  852.         ret                                             ;  AND RETURN
  853. eInt11:
  854.         call    interrupt                               ; PROCESS INTERRUPT
  855.         ret
  856. EndProc  eInt_1
  857.  
  858. Procedure eInt_2 far
  859.         mov     di,OFFSET perprtarea                    ; FIRST PERPRTDATA AREA
  860.         add     di, (SIZE printer_database * LPT2_INDEX); 2ND PERPRTDATA AREA
  861.         mov     si, LPT2_INDEX                          ; SET-UP FOR INTERRUPT
  862.         test    [di].share_interrupt, INT_SHARING       ; SUPPORTS INT SHARING?
  863.         jz      eInt21                                  ; NO: GO PROCESS INT.
  864.         test    [di].commonflags,CHARACTER_OUT          ; HAS A CHAR BEEN SENT?
  865.         jz      eInt20                                  ; JUMP IF NO.
  866.         test    [di].commonflags1,PDDDIRACCESS          ; PDD HAS PORT ACCESS?
  867.         jz      eInt20                                  ; NO, IGNORE PORT
  868.         mov     dx, [di].deviceaddr                     ; DATA PORT
  869.         inc     dx                                      ; STATUS PORT
  870.         cli                                             ; INTS BACK OFF
  871.         in      al, dx                                  ; GET CURRENT STATUS
  872.         test    al, INT_PENDING                         ; OUR INTERRUPT?
  873.         jz      eInt21                                  ; Y: PROCESS IT
  874. eInt20:                                                 ; 
  875.         stc                                             ; N: SIGNAL KERNEL
  876.         ret                                             ;  AND RETURN
  877. eInt21:
  878.         call    interrupt                               ; PROCESS INTERRUPT
  879.         ret
  880. EndProc  eInt_2
  881.  
  882. Procedure eInt_3 far
  883.         mov     di,OFFSET perprtarea                    ; FIRST PERPRTDATA AREA
  884.         add     di, (SIZE printer_database * LPT3_INDEX); 3RD PERPRTDATA AREA
  885.         mov     si, LPT3_INDEX                          ; SET-UP FOR INTERRUPT
  886.         test    [di].share_interrupt, INT_SHARING       ; SUPPORTS INT SHARING?
  887.         jz      eInt31                                  ; NO: GO PROCESS INT.
  888.         test    [di].commonflags,CHARACTER_OUT          ; HAS A CHAR BEEN SENT?
  889.         jz      eInt30                                  ; JUMP IF NO.
  890.         test    [di].commonflags1,PDDDIRACCESS          ; PDD HAS PORT ACCESS?
  891.         jz      eInt30                                  ; NO, IGNORE PORT
  892.         mov     dx, [di].deviceaddr                     ; DATA PORT
  893.         inc     dx                                      ; STATUS PORT
  894.         cli                                             ; INTS BACK OFF
  895.         in      al, dx                                  ; GET CURRENT STATUS
  896.         test    al, INT_PENDING                         ; INT PENDING?
  897.         jz      eInt31                                  ; Y: PROCESS IT
  898. eInt30:                                                 ; 
  899.         stc                                             ; N: SIGNAL KERNEL
  900.         ret                                             ;  AND RETURN
  901. eInt31:
  902.         call    interrupt                               ; PROCESS INTERRUPT
  903.         ret
  904. EndProc  eInt_3
  905.  
  906. BREAK <IRQ5 INTERRUPT HANDLER>
  907. ;/********************** START OF SPECIFICATIONS ***********************/
  908. ;/*                                                                    */
  909. ;/* SOURCE FILE NAME:  PRTINT05                                        */
  910. ;/*                                                                    */
  911. ;/* DESCRIPTIVE NAME:  Printer Hardware Interrupt Handler for IRQ5.    */
  912. ;/*                                                                    */
  913. ;/* FUNCTION:  The function of PRTINT05 is to set si to the device     */
  914. ;/*            index which caused the hardware interrupt on level 5.   */
  915. ;/*                                                                    */
  916. ;/* NOTE:   The Hardware Interrupt Manager saves all registers and     */
  917. ;/*         calls with interrupt disabled.  On exit, interrupts are    */
  918. ;/*         disabled to prevent nested interrupts after EOI.           */
  919. ;/*                                                                    */
  920. ;/* INPUT:  DS = setup to our data segment.                            */
  921. ;/*                                                                    */
  922. ;/* ENTRY POINT:  PRTINT05                                             */
  923. ;/*    LINKAGE :  CALL FAR                                             */
  924. ;/*                                                                    */
  925. ;/* EXIT-NORMAL:  Return to the hardware interrupt manager.            */
  926. ;/*                                                                    */
  927. ;/* EXIT-ERROR:   N/A                                                  */
  928. ;/*                                                                    */
  929. ;/* INTERNAL REFERENCES:  interrupt                                    */
  930. ;/*    ROUTINES:                                                       */
  931. ;/*                                                                    */
  932. ;/* EXTERNAL REFERENCES:  NONE                                         */
  933. ;/*    ROUTINES:                                                       */
  934. ;/*                                                                    */
  935. ;/*********************** END OF SPECIFICATIONS ************************/
  936. Procedure prtint05 far
  937.         ASSUME  CS:CSEG,DS:DSEG,ES:NOTHING,SS:NOTHING
  938.         mov     si,irq5index                            ; IND TO CURR OWNER IRQ5
  939.         call    interrupt                               ; CALL COMMON ROUTINE
  940.         ret
  941. EndProc prtint05
  942.  
  943. BREAK <IRQ7 INTERRUPT HANDLER>
  944. ;/********************** START OF SPECIFICATIONS ***********************/
  945. ;/*                                                                    */
  946. ;/* SOURCE FILE NAME:  PRTINT07                                        */
  947. ;/*                                                                    */
  948. ;/* DESCRIPTIVE NAME:  PRINTER HARDWARE INTERRUPT HANDLER FOR IRQ7.    */
  949. ;/*                                                                    */
  950. ;/* FUNCTION:  THE FUNCTION OF PRTINT07 IS TO SET SI TO THE DEVICE     */
  951. ;/*            INDEX WHICH CAUSED THE HARDWARE INTERRUPT ON LEVEL 7.   */
  952. ;/*                                                                    */
  953. ;/* NOTE:   The Hardware Interrupt Manager saves all registers and     */
  954. ;/*         calls with interrupt disabled.  On exit, interrupts are    */
  955. ;/*         disabled to prevent nested interrupts after EOI.           */
  956. ;/*                                                                    */
  957. ;/* INPUT:  DS = setup to our data segment.                            */
  958. ;/*                                                                    */
  959. ;/* ENTRY POINT:  PRTINT07                                             */
  960. ;/*    LINKAGE :  CALL FAR                                             */
  961. ;/*                                                                    */
  962. ;/* EXIT-NORMAL:  Return to the hardware interrupt manager.            */
  963. ;/*                                                                    */
  964. ;/* EXIT-ERROR:   N/A                                                  */
  965. ;/*                                                                    */
  966. ;/* INTERNAL REFERENCES:  interrupt                                    */
  967. ;/*    ROUTINES:                                                       */
  968. ;/*                                                                    */
  969. ;/* EXTERNAL REFERENCES:  NONE                                         */
  970. ;/*    ROUTINES:                                                       */
  971. ;/*                                                                    */
  972. ;/*********************** END OF SPECIFICATIONS ************************/
  973. Procedure prtint07 far
  974.         ASSUME  CS:CSEG,DS:DSEG,ES:NOTHING,SS:NOTHING
  975.         mov     si,irq7owner                            ; IND TO CURR OWNER IRQ7
  976.         mov     timercount,0                            ; CLEAR TIMER COUNTER
  977.         call    interrupt                               ; CALL COMMON ROUTINE
  978.         ret
  979. EndProc prtint07
  980.  
  981. BREAK <START A TIMER>
  982. ;/********************** START OF SPECIFICATIONS ***********************/
  983. ;/*                                                                    */
  984. ;/* SUBROUTINE NAME:  STARTTIMER                                       */
  985. ;/*                                                                    */
  986. ;/* DESCRIPTIVE NAME:  Printer Device Driver Start Timer Routine       */
  987. ;/*                                                                    */
  988. ;/* FUNCTION:  The function of this subroutine is to start a timer     */
  989. ;/*            manager to get invoked on each timer tick.  If the      */
  990. ;/*            timer manager is already started, this routine will not */
  991. ;/*            attempt to start it again.                              */
  992. ;/*                                                                    */
  993. ;/* NOTE:                                                              */
  994. ;/*        This routine is only called if the SetIRQ function call     */
  995. ;/*        fails in the printblock routine or if no hardware interrupt */
  996. ;/*        is assigned to this device.                                 */
  997. ;/*                                                                    */
  998. ;/* ENTRY POINT:  STARTTIMER                                           */
  999. ;/*    LINKAGE :  CALL NEAR                                            */
  1000. ;/*                                                                    */
  1001. ;/* INPUT:  di = offset to appropriate perprtdata area                 */
  1002. ;/*                                                                    */
  1003. ;/* EXIT-NORMAL: timerneeded = 001B LPT1 is running off of the timer.  */
  1004. ;/*                            010B LPT2 is running off of the timer.  */
  1005. ;/*                            100B LPT3 is running off of the timer.  */
  1006. ;/*              [di].prttime = reset running count of ticks           */
  1007. ;/*              [di].waittime = set maximum count of ticks to wait    */
  1008. ;/*                                                                    */
  1009. ;/* EXIT-ERROR :  See EXIT-NORMAL above.                               */
  1010. ;/*                                                                    */
  1011. ;/* INTERNAL REFERENCES:  NONE                                         */
  1012. ;/*    ROUTINES:                                                       */
  1013. ;/*                                                                    */
  1014. ;/* EXTERNAL REFERENCES:  DEVICE_HELP  SetTimer                        */
  1015. ;/*    ROUTINES:                                                       */
  1016. ;/*                                                                    */
  1017. ;/*********************** END OF SPECIFICATIONS ************************/
  1018. Procedure starttimer near
  1019.         ASSUME  CS:CSEG,DS:DSEG,ES:NOTHING,SS:NOTHING
  1020.         mov     [di].prttime,0                          ; RESET RUNNING COUNT
  1021.         mov     [di].waittime,MINWAITTIME               ; # OF TICKS TO WAIT
  1022.  
  1023.         test    timerneeded,TIMERMASK                   ; IF TIMERMGR PREV REG
  1024.         jnz     starttimer1                             ; THEN DON'T REREGISTER
  1025.  
  1026.         mov     ax,OFFSET prttimgr                      ; OFFSET PRT TIMER MGR
  1027.         mov     dl,DevHlp_SetTimer                      ; SET TIMER FUNCTION
  1028.         call    DWORD PTR [device_help]                 ; CALL DEVHLP
  1029. starttimer1:
  1030.         mov     al,[di].deviceflag                      ; GET DEVICE FLAG
  1031.         or      timerneeded,al                          ; DEVICE RUNS BY TIMER
  1032.         ret
  1033. EndProc starttimer
  1034.  
  1035. BREAK <STOP A TIMER>
  1036. ;/********************** START OF SPECIFICATIONS ***********************/
  1037. ;/*                                                                    */
  1038. ;/* SUBROUTINE NAME:  STOPTIMER                                        */
  1039. ;/*                                                                    */
  1040. ;/* DESCRIPTIVE NAME:  Printer Device Driver Stop Timer Routine        */
  1041. ;/*                                                                    */
  1042. ;/* FUNCTION:  The function of this subroutine is to stop a timer      */
  1043. ;/*            manager. If the timer manager is needed by another      */
  1044. ;/*            device, it will only deregister this request from       */
  1045. ;/*            running on the timer.                                   */
  1046. ;/*                                                                    */
  1047. ;/* NOTE:                                                              */
  1048. ;/*                                                                    */
  1049. ;/* ENTRY POINT:  STOPTIMER                                            */
  1050. ;/*    LINKAGE :  CALL NEAR                                            */
  1051. ;/*                                                                    */
  1052. ;/* INPUT:  di = offset to appropriate perprtdata area                 */
  1053. ;/*                                                                    */
  1054. ;/* EXIT-NORMAL: timerneeded = 001B LPT1 is running off of the timer.  */
  1055. ;/*                            010B LPT2 is running off of the timer.  */
  1056. ;/*                            100B LPT3 is running off of the timer.  */
  1057. ;/*                                                                    */
  1058. ;/* EXIT-ERROR :  See EXIT-NORMAL above.                               */
  1059. ;/*                                                                    */
  1060. ;/* INTERNAL REFERENCES:  NONE                                         */
  1061. ;/*    ROUTINES:                                                       */
  1062. ;/*                                                                    */
  1063. ;/* EXTERNAL REFERENCES:  DEVICE_HELP  ResetTimer                      */
  1064. ;/*    ROUTINES:                                                       */
  1065. ;/*                                                                    */
  1066. ;/*********************** END OF SPECIFICATIONS ************************/
  1067. Procedure stoptimer near
  1068.         ASSUME  CS:CSEG,DS:DSEG,ES:NOTHING,SS:NOTHING
  1069.         mov     al,[di].deviceflag                      ; GET DEVICE FLAG
  1070.         xor     al,0ffh                                 ; GET REVERSE BITMASK
  1071.         and     timerneeded,al                          ; SET FLAG OFF
  1072.         test    timerneeded,TIMERMASK                   ; IF PRT TIMERMGR NEEDED
  1073.         jnz     stoptimer1                              ; THEN DON'T DEREGISTER
  1074.  
  1075.         mov     ax,OFFSET prttimgr                      ; ELSE DEREGISTER TIMER
  1076.         mov     dl,DevHlp_ResetTimer                    ; TURN OFF TIMER
  1077.         call    DWORD PTR [device_help]                 ; CALL TIMER SERVICES
  1078.  
  1079. stoptimer1:
  1080.         ret
  1081. EndProc stoptimer
  1082.  
  1083. BREAK <PRINTER DEVICE DRIVER TIMER MANAGER>
  1084. ;/********************** START OF SPECIFICATIONS ***********************/
  1085. ;/*                                                                    */
  1086. ;/* MODULE NAME:  PRTTIMGR                                             */
  1087. ;/*                                                                    */
  1088. ;/* DESCRIPTIVE NAME:  Print timer manager                             */
  1089. ;/*                                                                    */
  1090. ;/* FUNCTION:  The function of this module is to call interrupt when   */
  1091. ;/*            the certain time interval has elasped.                  */
  1092. ;/*                                                                    */
  1093. ;/* NOTES:                                                             */
  1094. ;/*         It is the timer routine's responsibility to save and       */
  1095. ;/*         restore all registers used in the printer timer handler.   */
  1096. ;/*                                                                    */
  1097. ;/* ENTRY POINT: PRTTIMGR                                              */
  1098. ;/*    LINKAGE : CALL FAR                                              */
  1099. ;/*                                                                    */
  1100. ;/* INPUT:  DS = our data segment                                      */
  1101. ;/*         numofprts   = number of parallel ports installed.          */
  1102. ;/*         timerneeded = 001B LPT1 is running off of the timer.       */
  1103. ;/*                       010B LPT2 is running off of the timer.       */
  1104. ;/*                       100B LPT3 is running off of the timer.       */
  1105. ;/*         [DI].prttime = running count of ticks                      */
  1106. ;/*         [DI].waittime = # of ticks to wait                         */
  1107. ;/*                                                                    */
  1108. ;/* EXIT-NORMAL:  All registers are restored.                          */
  1109. ;/*               [DI].prttime = [di].prttime + 1 or                   */
  1110. ;/*               [di].prttime = 0 if prttime = waittime.              */
  1111. ;/*                                                                    */
  1112. ;/* EXIT-ERROR:  See EXIT-NORMAL above.                                */
  1113. ;/*                                                                    */
  1114. ;/* INTERNAL REFERENCES:  timerinterrupt                               */
  1115. ;/*    ROUTINES:                                                       */
  1116. ;/*                                                                    */
  1117. ;/* EXTERNAL REFERENCES:  NONE                                         */
  1118. ;/*    ROUTINES:                                                       */
  1119. ;/*                                                                    */
  1120. ;/*********************** END OF SPECIFICATIONS ************************/
  1121. Procedure prttimgr far
  1122.         ASSUME  CS:CSEG,DS:DSEG,ES:NOTHING,SS:NOTHING
  1123.         pusha                                           ; SAVE REGESTERS
  1124.         push    es                                      ; SAVE EXTRA SEGMENT
  1125.         test    timerneeded,TIMERMASK                   ; IF TIMER NOT REQUESTED
  1126.         jz      prttimgr3                               ; THEN EXIT
  1127.  
  1128.         mov     ax,1                                    ; SET AX = 1
  1129.         xor     ch,ch                                   ; MAKE CH 0
  1130.         mov     cl,numofprts                            ; # OF PARALLEL PORTS
  1131.         mov     di,OFFSET perprtarea                    ; DI = START OF DATABASE
  1132. prttimgr1:
  1133.         test    timerneeded,al                          ; IF DEV !NEEDS T. TICKS
  1134.         jz      prttimgr2                               ; THEN TRY NEXT DEVICE
  1135.  
  1136.         inc     [di].prttime                            ; ADD 1 TO TIMER COUNT
  1137.         mov     dx,[di].prttime                         ; DX = TIMER COUNT
  1138.         cmp     dx,[di].waittime                        ; IF TIMER IS < WAITTIME
  1139.         jb      prttimgr2                               ; THEN GET NEXT REQUEST
  1140.         SaveReg <ax,cx>                                 ; SAVE REGISTERS
  1141.  
  1142.         call    timerinterrupt                          ; HANDLE REQUEST
  1143.         mov     [di].prttime,0                          ; RESET RUNNING COUNT
  1144.  
  1145.         RestoreReg <cx,ax>                              ; RESTORE REGISTERS
  1146. prttimgr2:
  1147.         sal     al,1                                    ; CHECK NEXT DEVICE
  1148.         add     di,SIZE printer_database                ; DI -> NEXT DEVICE
  1149.         loop    prttimgr1                               ; TRY NEXT DEVICE
  1150. prttimgr3:
  1151.         pop     es                                      ; RESTORE EXTRA SEGMENT
  1152.         popa                                            ; RESTORE REGESTERS
  1153.         ret
  1154. EndProc prttimgr
  1155.  
  1156. BREAK <TIMER INTERRUPT HANDLER>
  1157. ;/********************** START OF SPECIFICATIONS ***********************/
  1158. ;/*                                                                    */
  1159. ;/* SUBROUTINE NAME:  TIMERINTERRUPT                                   */
  1160. ;/*                                                                    */
  1161. ;/* DESCRIPTIVE NAME:  Timer Interrupt Handler                         */
  1162. ;/*                                                                    */
  1163. ;/* FUNCTION:  The function of interrupt will be to perform the timer  */
  1164. ;/*            interrupt handler functions.                            */
  1165. ;/*                                                                    */
  1166. ;/* NOTE:   The Hardware Interrupt Manager saves all registers and     */
  1167. ;/*         calls with interrupts disabled.                            */
  1168. ;/*                                                                    */
  1169. ;/* ENTRY POINT:  TIMEINTERRUPT                                        */
  1170. ;/*    LINKAGE :  CALL NEAR                                            */
  1171. ;/*                                                                    */
  1172. ;/* INPUT:  DI = INDEX TO APPROPRIATE PERPRTDATA AREA                  */
  1173. ;/*                                                                    */
  1174. ;/* EXIT-NORMAL:                                                       */
  1175. ;/*                                                                    */
  1176. ;/* EXIT-ERROR :  See EXIT-NORMAL above.                               */
  1177. ;/*                                                                    */
  1178. ;/* INTERNAL REFERENCES:                                               */
  1179. ;/*    ROUTINES:  sendchar                                             */
  1180. ;/*               cleanup                                              */
  1181. ;/*               checkstatus                                          */
  1182. ;/*               changeirqtost                                        */
  1183. ;/*                                                                    */
  1184. ;/* EXTERNAL REFERENCES:                                               */
  1185. ;/*    ROUTINES:                                                       */
  1186. ;/*                                                                    */
  1187. ;/*********************** END OF SPECIFICATIONS ************************/
  1188. Procedure timerinterrupt near
  1189.         ASSUME  CS:CSEG,DS:DSEG,ES:NOTHING,SS:NOTHING
  1190.  
  1191.         test    [di].commonflags,MONPRINTING            ; IF MON PRINTING
  1192.         jnz     tinterrupt0                             ; CONTINUE
  1193.         test    [di].commonflags,IOACTIVE               ; IF I/O !ACTIVE
  1194.         jz      tinterrupt3                             ; THEN JUST RETURN
  1195.  
  1196. tinterrupt0:
  1197.         and     [di].commonflags,NOT CHARACTER_OUT      ; RESET CHAR SENT FLAG.
  1198.         mov     fIRQStolen,0                            ; CLEAR IRQ STOLEN FLAG
  1199.  
  1200.         ; I/O IS ACTIVE ON THIS DEVICE
  1201.  
  1202.         mov     ax,[di].initialcount                    ; GET INITIAL COUNT
  1203.         cmp     ax,[di].prtcount                        ; IF BYTES REMAINING
  1204.         jne     tinterrupt1                             ; THEN CONTINUE PRINTING
  1205.  
  1206.         ; COMPLETELY FINISHED PRINTING
  1207.  
  1208.         call    cleanup                                 ; CALL CLEANUP
  1209.         jmp     SHORT tinterrupt3                       ; RET TO HARD INT MGR
  1210.  
  1211.         ; NOT FINISHED PRINTING
  1212. tinterrupt1:
  1213.         inc     timercount                              ; INCREMENT TIMER COUNT
  1214.         cmp     timercount,TICKSTOWAIT                  ; CHECK IRQ STATUS?
  1215.         jbe     tinterrupt05                            ; IF NOT CONTINUE PRT.
  1216.  
  1217.         mov     timercount,0                            ; ZERO TIMER COUNT
  1218.         cli                                             ; DISABLE INTERRUPTS
  1219.         mov     al,IRQ7INTNUM
  1220.         call    checkstatus                             ; CHECK IRQ7 PORT STATUS
  1221.  
  1222.         cmp     al,0                                    ; IF AL = 0
  1223.         je      tinterrupt05                            ; THEN CONTINUE ON TIMER
  1224.         mov     fIRQStolen,1                            ; SET IRQ STOLEN FLAG
  1225.         call    changeirqtost                           ; ELSE GRAB IRQ
  1226.  
  1227. tinterrupt05:
  1228.         sti                                             ; ENABLE INTERRUPTS
  1229.  
  1230. tinterrupt2:
  1231.         call    sendchar                                ; PRINT NEXT CHAR
  1232.  
  1233. tinterrupt3:
  1234.         ret
  1235. EndProc timerinterrupt
  1236.  
  1237. BREAK <GRAB IRQ WHEN PRINTER NOT USED>
  1238. ;/********************** START OF SPECIFICATIONS ***********************/
  1239. ;/*                                                                    */
  1240. ;/* SUBROUTINE NAME:  CHANGEIRQTOST                                    */
  1241. ;/*                                                                    */
  1242. ;/* DESCRIPTIVE NAME:  Change IRQ job to ST and ST job to IRQ          */
  1243. ;/*                                                                    */
  1244. ;/* FUNCTION:  The function of this routine is to change the internal  */
  1245. ;/*            data structures of the print jobs to represent the      */
  1246. ;/*            change from IRQ to ST.                                  */
  1247. ;/*                                                                    */
  1248. ;/* ENTRY POINT:  CHANGEIRQTOST                                        */
  1249. ;/*    LINKAGE :  CALL NEAR                                            */
  1250. ;/*                                                                    */
  1251. ;/* INPUT:  DI = POINTER TO ST PERPRTDATA DATA                         */
  1252. ;/*                                                                    */
  1253. ;/* EXIT-NORMAL:  none                                                 */
  1254. ;/*                                                                    */
  1255. ;/* EXIT-ERROR :  See EXIT-NORMAL above.                               */
  1256. ;/*                                                                    */
  1257. ;/* INTERNAL REFERENCES:  starttimer                                   */
  1258. ;/*    ROUTINES:          stoptimer                                    */
  1259. ;/*                                                                    */
  1260. ;/* EXTERNAL REFERENCES:  NONE                                         */
  1261. ;/*    ROUTINES:                                                       */
  1262. ;/*                                                                    */
  1263. ;/*********************** END OF SPECIFICATIONS ************************/
  1264. Procedure changeirqtost near
  1265.         ASSUME  CS:CSEG,DS:DSEG,ES:NOTHING,SS:NOTHING
  1266.         push    bx                                      ; SAVE BX
  1267.         push    di                                      ; SAVE DI FOR ST JOB
  1268.  
  1269.         ; DI MUST BE INDEXED TO IRQ JOB AT THIS POINT!!!!!
  1270.         ; THEREFORE, THE FOLLOWING LOOP WILL SEARCH FOR THE
  1271.         ; IRQ JOB AND SET DI APPROPRIATELY
  1272.  
  1273.         xor     ch,ch                                   ; MAKE CH 0
  1274.         mov     cl,numofprts                            ; # OF PARALLEL PORTS
  1275.         mov     di,OFFSET perprtarea                    ; DI = START OF DATABASE
  1276. change0:
  1277.         cmp     [di].curintlevel,IRQ7INTNUM             ; IF DEV USING IRQ7
  1278.         je      change1                                 ; THEN HAVE DEVICE
  1279.         add     di,SIZE printer_database                ; DX = SIZE OF ONE ENTRY
  1280.         loop    change0                                 ; TRY NEXT DEVICE
  1281.  
  1282.         pop     di
  1283.         jmp     SHORT changeEND
  1284. change1:
  1285.         mov     [di].curintlevel,0                      ; CHANGE IRQ TO TIMER
  1286.         call    starttimer                              ; START THE TIMER
  1287.  
  1288.         ; DISABLE INTS AT OLD IRQ PORT
  1289.  
  1290.         mov     dx,[di].deviceaddr                      ; GET PORT ADDRESS
  1291.         inc     dx                                      ; POINT TO CONTROL PORT
  1292.         inc     dx                                      ; POINT TO CONTROL PORT
  1293.         mov     al,DISABLEINT                           ; DISABLE INT AT PORT
  1294.         out     dx,al                                   ; NEW CTRL VALUE
  1295.  
  1296.         ; If the interrupt line that was just disabled was level triggered (EISA
  1297.         ; systems have this option), then we need to clear any pending interrupt
  1298.         ; that occurred since the CLI at the top of this routine.  This can be
  1299.         ; done by reading the printer status port.  Doing this will cause the
  1300.         ; PIC to report a spurious interrupt to the CPU, but OS/2's kernel will
  1301.         ; handle this, and our interrupt service routine will not be called.
  1302.  
  1303.         mov     dx,[di].deviceaddr                      ; GET PORT ADDRESS
  1304.         inc     dx                                      ; POINT TO STATUS PORT
  1305.         in      al,dx                                   ; READ THE STATUS PORT
  1306.  
  1307. ;******************************************************************************
  1308. ;* NOW WE PROCESS THE ST JOB TO CONVERT IT TO THE IRQ                         *
  1309. ;******************************************************************************
  1310.  
  1311.         ; DI MUST BE INDEXED TO ST JOB AT THIS POINT!!!!!
  1312.  
  1313.         pop     di                                      ; RESTORE DI FOR ST JOB
  1314.  
  1315.         mov     [di].curintlevel,IRQ7INTNUM             ; CHANGE TIMER TO IRQ
  1316.  
  1317.         xor     ah,ah                                   ; ZERO AH
  1318.         mov     al,[di].deviceindex                     ; GET DEVICE INDEX
  1319.         mov     irq7owner,ax                            ; SET IRQ7 OWNER
  1320.  
  1321.         call    stoptimer                               ; STOP TIMER ON ST JOB
  1322. changeEND:
  1323.         pop     bx                                      ; RESTORE BX
  1324.         ret
  1325. EndProc changeirqtost
  1326.  
  1327. BREAK <PRINTER ERROR STATUS PROCESSING>
  1328. ;/********************** START OF SPECIFICATIONS ***********************/
  1329. ;/*                                                                    */
  1330. ;/* SUBROUTINE NAME: CHECKSTATUS                                       */
  1331. ;/*                                                                    */
  1332. ;/* DESCRIPTIVE NAME: ANALYZE STATUS FLAGS                             */
  1333. ;/*                                                                    */
  1334. ;/* FUNCTION: THE FUNCTION OF THIS SUBROUTINE IS TO ANALYZE THE STATUS */
  1335. ;/*           INFORMATION RETURNED FROM "GETSTATUS".                   */
  1336. ;/*                                                                    */
  1337. ;/* ENTRY POINT: CHECKSTATUS                                           */
  1338. ;/*    LINKAGE : CALL NEAR                                             */
  1339. ;/*                                                                    */
  1340. ;/* INPUT: al = interrupt level to check status on                     */
  1341. ;/*                                                                    */
  1342. ;/* EXIT-NORMAL:  al = 1 if ok to steal IRQ, 0 otherwise               */
  1343. ;/*                                                                    */
  1344. ;/* EXIT-ERROR :  See EXIT-NORMAL above.                               */
  1345. ;/*                                                                    */
  1346. ;/* INTERNAL REFERENCES:  getstatus                                    */
  1347. ;/*    ROUTINES:                                                       */
  1348. ;/*                                                                    */
  1349. ;/* EXTERNAL REFERENCES:  NONE                                         */
  1350. ;/*    ROUTINES:                                                       */
  1351. ;/*                                                                    */
  1352. ;/*********************** END OF SPECIFICATIONS ************************/
  1353. Procedure checkstatus near
  1354.         ASSUME  CS:CSEG,DS:DSEG,ES:NOTHING,SS:NOTHING
  1355.         push    di                                      ; SAVE ST INDEX
  1356.  
  1357.         ; SEARCH FOR IRQ JOB
  1358.  
  1359.         xor     ch,ch                                   ; MAKE CH 0
  1360.         mov     cl,numofprts                            ; # OF PARALLEL PORTS
  1361.         mov     di,OFFSET perprtarea                    ; DI = START OF DATABASE
  1362. checkstatus0:
  1363.         cmp     [di].curintlevel,al                     ; IF DEV USING IRQ7
  1364.         je      checkstatus1                            ; THEN FOUND IT!
  1365.         add     di,SIZE printer_database                ; DX = SIZE OF ONE ENTRY
  1366.         loop    checkstatus0                            ; TRY NEXT DEVICE
  1367.  
  1368.         jcxz    checkstatus2                            ; NOT OK, EXIT
  1369. checkstatus1:
  1370.         mov     ax,[di].initialcount                    ; GET INITIAL COUNT
  1371.         cmp     [di].prtcount,ax                        ; IF NONE REMAIN
  1372.         je      checkstatus2                            ; EXIT
  1373.         call    getstatus                               ; GET PORT STATUS (AH)
  1374.  
  1375.         xor     al,al                                   ; NO ERROR
  1376. ;*******************************************************************************
  1377. ;* B0 = NOT BUSY & PAPER OUT & SELECTED = !CABLED ON MONO / SERIAL ADAPTER #20 *
  1378. ;*******************************************************************************
  1379.         cmp     ah,0b0h
  1380.         jnz     cs1
  1381.         mov     al,1                                    ; SET SELECT ERROR
  1382.         jmp     SHORT checkstatus3
  1383. ;*******************************************************************************
  1384. ;* 38 = BUSY & PAPER OUT & SELECTED & I/O ERROR = OUT OF PAPER             #28 *
  1385. ;*******************************************************************************
  1386. cs1:
  1387.         cmp     ah,38h
  1388.         jnz     cs2
  1389.         mov     al,1                                    ; SET PAPER OUT ERROR
  1390.         jmp     SHORT checkstatus3
  1391. ;*******************************************************************************
  1392. ;* 30 = BUSY & PAPER OUT & SELECTED & NOT I/O ERROR = OUT OF PAPER         #28 *
  1393. ;*******************************************************************************
  1394. cs2:
  1395.         cmp     ah,30h
  1396.         jnz     cs3
  1397.         mov     al,1                                    ; SET PAPER OUT ERROR
  1398.         jmp     SHORT checkstatus3
  1399. ;*******************************************************************************
  1400. ;* 28 = BUSY & PAPER OUT & NOT SELECTED & I/O ERROR = OUT OF PAPER         #28 *
  1401. ;*******************************************************************************
  1402. cs3:
  1403.         cmp     ah,28h
  1404.         jnz     cs4
  1405.         mov     al,1                                    ; SET PAPER OUT ERROR
  1406.         jmp     SHORT checkstatus3
  1407. ;*******************************************************************************
  1408. ;* 18 = BUSY & I/O ERROR & SELECTED = OFF LINE                             #29 *
  1409. ;*******************************************************************************
  1410. cs4:
  1411.         cmp     ah,18h
  1412.         jnz     cs5
  1413.         mov     al,1                                    ; SET I/O ERROR
  1414.         jmp     SHORT checkstatus3
  1415. ;*******************************************************************************
  1416. ;* 10 = BUSY & SELECTED = NOT READY                                        #29 *
  1417. ;*******************************************************************************
  1418. cs5:
  1419.         cmp     ah,10h
  1420.         jnz     cs6
  1421.         mov     al,1                                    ; SET I/O ERROR
  1422.         jmp     SHORT checkstatus3
  1423. ;*******************************************************************************
  1424. ;* 08 = BUSY & I/O ERROR = OFF LINE                                        #29 *
  1425. ;*******************************************************************************
  1426. cs6:
  1427.         cmp     ah,08h
  1428.         jnz     cs7
  1429.         mov     al,1                                    ; SET I/O ERROR
  1430.         jmp     SHORT checkstatus3
  1431. ;*******************************************************************************
  1432. ;* 00 = BUSY & NOTHING ELSE = NOT READY                                    #29 *
  1433. ;*******************************************************************************
  1434. cs7:
  1435.         cmp     ah,00h
  1436.         jnz     cs8
  1437.         mov     al,1                                    ; SET I/O ERROR
  1438.         jmp     SHORT checkstatus3
  1439. ;*******************************************************************************
  1440. ;* 88 = NOT BUSY & I/O ERROR = POWERED OFF                                 #20 *
  1441. ;*******************************************************************************
  1442. cs8:
  1443.         cmp     ah,88h
  1444.         jnz     checkstatus2
  1445.         mov     al,1                                    ; SET SELECT ERROR
  1446.         jmp     SHORT checkstatus3
  1447.  
  1448. checkstatus2:
  1449.         mov     al,0
  1450.  
  1451. checkstatus3:
  1452.         pop     di                                      ; RESTORE ST INDEX
  1453.         ret
  1454. EndProc checkstatus
  1455.  
  1456. BREAK <HARDWARE INTERRUPT HANDLER>
  1457. ;/********************** START OF SPECIFICATIONS ***********************/
  1458. ;/*                                                                    */
  1459. ;/* SUBROUTINE NAME:  INTERRUPT                                        */
  1460. ;/*                                                                    */
  1461. ;/* DESCRIPTIVE NAME:  Hardware Interrupt Handler                      */
  1462. ;/*                                                                    */
  1463. ;/* FUNCTION:  The function of interrupt will be to perform the        */
  1464. ;/*            hardware interrupt handler functions.                   */
  1465. ;/*                                                                    */
  1466. ;/* NOTE:   The Hardware Interrupt Manager saves all registers and     */
  1467. ;/*         calls with interrupts enabled.  On exit, interrupts are    */
  1468. ;/*         disabled to prevent nested interrupts after EOI.           */
  1469. ;/*                                                                    */
  1470. ;/* ENTRY POINT:  INTERRUPT                                            */
  1471. ;/*    LINKAGE :  CALL NEAR                                            */
  1472. ;/*                                                                    */
  1473. ;/* INPUT:  SI = INDEX TO APPROPRIATE PERPRTDATA AREA                  */
  1474. ;/*                                                                    */
  1475. ;/* EXIT-NORMAL:  NC = TELL INT MGR, MY INT (HARDWARE INTS ONLY)       */
  1476. ;/*                                                                    */
  1477. ;/* EXIT-ERROR :  See EXIT-NORMAL above.                               */
  1478. ;/*                                                                    */
  1479. ;/* INTERNAL REFERENCES:  copynext                                     */
  1480. ;/*    ROUTINES:          sendchar                                     */
  1481. ;/*                       cleanup                                      */
  1482. ;/*                                                                    */
  1483. ;/* EXTERNAL REFERENCES:  DEVICE_HELP  EOI                             */
  1484. ;/*    ROUTINES:                                                       */
  1485. ;/*                                                                    */
  1486. ;/*********************** END OF SPECIFICATIONS ************************/
  1487. Procedure interrupt near
  1488.         ASSUME  CS:CSEG,DS:DSEG,ES:NOTHING,SS:NOTHING
  1489.         mov     di,OFFSET perprtarea                    ; FIRST PERPRTDATA AREA
  1490.         mov     ax,SIZE printer_database                ; SIZE OF PRT DATABASE
  1491.         mul     si                                      ; MULT BY DEVICE INDEX
  1492.         add     di,ax                                   ; INDEX INTO DEV AREA
  1493.  
  1494.         ; IF OTHER HARDWARE INTERRUPT PENDING IN THE SYSTEM, COUNT THESE TO
  1495.         ; DETERMINE WHEN TO STOP PRINTING AND ALLOW THESE LOWER PRIORITY
  1496.         ; INTERRUPTS TIME TO SERVICE.
  1497.  
  1498.         cli                                             ; DISABLE INTERRUPTS
  1499.         in      al,21h                                  ; GET 8259 MASTER IMR
  1500.         or      al,0E0h                                 ; MASK OFF IRQ7
  1501.         mov     ah,al                                   ; AH=MASTER IMR
  1502.         in      al,0a1h                                 ; GET 8259 SLAVE IMR
  1503.         not     ax                                      ; INVERT FOR ACTIVE IRQS
  1504.         mov     si,ax                                   ; SAVE ACTIVE IRQS
  1505.         mov     ax,0a0ah                                ; READ IRR CMD
  1506.         out     20h,al                                  ; TO 8259 MASTER
  1507.         DevIODelay <bx>                                 ; IO DELAY
  1508.         in      al,20h                                  ; GET 8259 MASTER IRR
  1509.         xchg    ah,al                                   ; SAVE MASTER IRR
  1510.         out     0a0h,al                                 ; READ IRR CMD TO SLAVE
  1511.         DevIODelay <bx>                                 ; IO DELAY
  1512.         in      al,0a0h                                 ; GET 8259 SLAVE IRR
  1513.         and     ax,si                                   ; ENABLED IRQS-REQS PEND
  1514.         jz      interrupt01                             ; JMP IF NO PENDING IRQS
  1515.         inc     pendirq                                 ; ELSE INC PENDING IRQ
  1516. interrupt01:
  1517.         sti                                             ; ENDABLE INTERRUPTS
  1518.  
  1519. ;/** START SPURIOUS TEST ***********************************************/
  1520. ;/*                                                                    */
  1521. ;/* THE FOLLOWING CODE WAS ADDED IN ORDER TO PROCESS SPURIOUS          */
  1522. ;/* INTERRUPTS.  WE ARE CURRENTLY GETTING SPURIOUS INTERRUPTS FROM THE */
  1523. ;/* NEW 3 MEG CARDS WITH SERIAL/PARALLEL PORTS AND FROM THE     "FIRST */
  1524. ;/* ISSUE" SERIAL/PARALLEL CARDS.  FUTURE ENHANCEMENTS TO THIS CODE    */
  1525. ;/* WOULD BE TO COUNT THE NUMBER OF SPURIOUS INTERRUPTS IN A GIVEN     */
  1526. ;/* AMOUNT OF TIME AND TO ALERT THE INTERRUPT MANAGER TO DISABLE THIS  */
  1527. ;/* LEVEL ALTOGETHER.  THIS WOULD ALLOW THE PRINTER DEVICE DRIVER TO   */
  1528. ;/* RUN FROM VIA THE TIMER OPERATION. THE CODE NOW REQUIRES THAT IN    */
  1529. ;/* ORDER FOR US TO RECOGNIZE THE INTERRUPT AS OURS, WE MUST HAVE SENT */
  1530. ;/* A CHARACTER OUT TO THE PRINTER.                                    */
  1531. ;/*                                                                    */
  1532. ;/**********************************************************************/
  1533.  
  1534.         test    [di].commonflags,CHARACTER_OUT          ; HAS A CHAR BEEN SENT?
  1535.         jnz     interrupt05                             ; JUMP IF YES.
  1536.  
  1537.         cmp     fIRQStolen,1                            ; IS THIS AN "OLD" INT
  1538.         je      interrupt3                              ; YES, EOI
  1539.  
  1540.         ; PRINT REQUEST, HAVE SETIRQ, PRINTER OFF, PRTRESTART SET, PRINTER ON
  1541.         ; MAY NOT HAVE SENT CHAR BUT LASER PRINTERS GENERATE IRQ WHEN TURNED ON
  1542.  
  1543.         test    [di].commonflags,PRTRESTART             ; REQUEST IN PROGRESS?
  1544.         jnz     interrupt05                             ; JUMP IF YES.
  1545.  
  1546.         stc                                             ; OTHERWISE, SET CARRY
  1547.         cli                                             ; DISABLE INTS 87416
  1548.         jmp     SHORT interrupt4                        ; AND RETURN.
  1549.  
  1550. interrupt05:
  1551.         and     [di].commonflags,NOT CHARACTER_OUT      ; RESET CHAR SENT FLAG.
  1552.  
  1553. ;/** END SPURIOUS TEST *************************************************/
  1554. ;/*                                                                    */
  1555. ;/**********************************************************************/
  1556.  
  1557.         test    [di].commonflags,MONPRINTING            ; IF !MON PRINTING
  1558.         jnz     interrupt0                              ; CONTINUE
  1559.         test    [di].commonflags,IOACTIVE               ; IF I/O !ACTIVE
  1560.         jz      interrupt3                              ; THEN JUST RETURN
  1561.  
  1562. interrupt0:
  1563.  
  1564.         ; I/O IS ACTIVE ON THIS DEVICE
  1565.  
  1566.         mov     ax,[di].initialcount                    ; GET INITIAL COUNT
  1567.         cmp     ax,[di].prtcount                        ; IF BYTES REMAIN
  1568.         jne     interrupt1                              ; THEN CONTINUE PRINTING
  1569.  
  1570.         ; COMPLETELY FINISHED PRINTING
  1571.  
  1572.         call    cleanup                                 ; CALL CLEANUP
  1573.         jmp     SHORT interrupt3                        ; RET TO HARD INT MGR
  1574.  
  1575. interrupt1:
  1576.         ;NOT FINISISHED PRINTING
  1577. ;/**********************************************************************/
  1578. ;/*     INTERRUPTS WILL BE ENABLED BY SENDCHAR ROUTINE                 */
  1579. ;/**********************************************************************/
  1580.         call    sendchar                                ; PRINT NEXT CHAR
  1581.  
  1582. interrupt3:
  1583.         cli                                             ; DONT ALLOW NESTED INTS
  1584.         mov     al,20h                                  ; NON SPECIFIC EOI
  1585.         out     20h,al                                  ; ISSUE EOI TO 8259
  1586.         clc                                             ; TELL INT MGR, MY INT
  1587. interrupt4:
  1588.         ret
  1589. EndProc interrupt
  1590.  
  1591. BREAK <PREPARE TO SEND A CHAR. TO A DEVICE>
  1592. ;/********************** START OF SPECIFICATIONS ***********************/
  1593. ;/*                                                                    */
  1594. ;/* SUBROUTINE NAME: SENDCHAR                                          */
  1595. ;/*                                                                    */
  1596. ;/* DESCRIPTIVE NAME: SEND CHARACTER ROUTINE                           */
  1597. ;/*                                                                    */
  1598. ;/* FUNCTION: THE FUNCTION OF THIS SUBROUTINE IS TO SEND A CHARACTER   */
  1599. ;/*           TO A DEVICE IF THAT DEVICE IS NOT IN ERROR.              */
  1600. ;/*                                                                    */
  1601. ;/* ENTRY POINT: SENDCHAR                                              */
  1602. ;/*    LINKAGE : CALL NEAR                                             */
  1603. ;/*                                                                    */
  1604. ;/* INPUT: DI = OFFSET TO APPROPRIATE PERPRTDATA AREA                  */
  1605. ;/*                                                                    */
  1606. ;/* EXIT-NORMAL:  [DI].cancelflags = filled in.                        */
  1607. ;/*               Interrupts are enabled.                              */
  1608. ;/*                                                                    */
  1609. ;/* EXIT-ERROR :  See EXIT-NORMAL above.                               */
  1610. ;/*                                                                    */
  1611. ;/* INTERNAL REFERENCES:  getstatus                                    */
  1612. ;/*    ROUTINES:          sendtodev                                    */
  1613. ;/*                                                                    */
  1614. ;/* EXTERNAL REFERENCES:  NONE                                         */
  1615. ;/*    ROUTINES:                                                       */
  1616. ;/*                                                                    */
  1617. ;/*********************** END OF SPECIFICATIONS ************************/
  1618. Procedure sendchar near
  1619.         ASSUME  CS:CSEG,DS:DSEG,ES:NOTHING,SS:NOTHING
  1620.         mov     cx,BUSYRETRY                            ; SET RETRY CNT
  1621.         .REPEAT
  1622.         call    getstatus                               ; GET DEVICE STATUS
  1623.         dec     cx                                      ; DECREMENT COUNT LOOP
  1624.         .UNTIL <BIT ah NZ NOTBUSY> OR                   ; UNTIL NOT BUSY OR
  1625.         .UNTIL CXZ                                      ; COUNT REACHES "0"
  1626.  
  1627.         SaveReg <es,bx>                                 ; SAVE REGISTERS
  1628.         mov     es,[di].gdtprintbuf                     ; GET USER BUF GDT SEL
  1629.         mov     bx,[di].printbufoff                     ; GET USER BUF OFFSET
  1630.         add     bx,[di].prtcount                        ; ADD PRINTED COUNT
  1631.  
  1632.         cmp     ah,NORMALSTAT                           ; IF NORMAL PORT STATUS
  1633.         je      sendchar1                               ; THEN SEND CHAR TO DEV
  1634.         cmp     ah,NOTBUSY                              ; IF ! DESELECTED
  1635.         jne     sendchar0                               ; THEN TRY TO RESTART
  1636.         cmp     BYTE PTR es:[bx],SELECT                 ; ELSEIF BYTE 1 = SELECT
  1637.         je      sendchar1                               ; THEN SEND CHAR TO DEV
  1638. sendchar0:
  1639.         or      [di].commonflags,PRTRESTART             ; ELSE SET RESTART FLAG
  1640.         mov     [di].cancelstatus,ah                    ; SAVE STATUS FLAGS
  1641.         jmp     SHORT sendchar2                         ; EXIT
  1642. sendchar1:
  1643.         and     [di].commonflags,NOT MONERRPKTSENT      ; CLEAR PKT SENT FLAG
  1644.         and     [di].commonflags,NOT PRTRESTART         ; CLEAR RESTART FLAG
  1645.         mov     [di].cancelstatus,CANNOERROR            ; CLEAR CANCEL STATUS
  1646.         mov     [di].cancelflags,CANNOERROR             ; SET NO ERROR
  1647.         mov     [di].timeoutctr,0                       ; RESET TIMEOUT COUNTER
  1648.         call    sendtodev                               ; SEND CHAR TO DEVICE
  1649. sendchar2:
  1650.         RestoreReg <bx,es>                              ; RESTORE REGISTERS
  1651.         sti                                             ; ENABLE INTERRUPTS
  1652.         ret
  1653. EndProc sendchar
  1654.  
  1655. BREAK <SEND A CHARACTER TO A DEVICE>
  1656. ;/********************** START OF SPECIFICATIONS ***********************/
  1657. ;/*                                                                    */
  1658. ;/* SUBROUTINE NAME: SENDTODEV                                         */
  1659. ;/*                                                                    */
  1660. ;/* DESCRIPTIVE NAME: SEND CHARACTER ROUTINE                           */
  1661. ;/*                                                                    */
  1662. ;/* FUNCTION: THE FUNCTION OF THIS SUBROUTINE IS TO SEND A CHARACTER   */
  1663. ;/*           TO A DEVICE.                                             */
  1664. ;/*                                                                    */
  1665. ;/* ENTRY POINT: SENDTODEV                                             */
  1666. ;/*    LINKAGE : CALL NEAR                                             */
  1667. ;/*                                                                    */
  1668. ;/* INPUT: DI = OFFSET TO APPROPRIATE PERPRTDATA AREA                  */
  1669. ;/*        DX = DATA PORT ADDRESS                                      */
  1670. ;/*        ES:BX = PTR TO APPROPRIATE DATA BUFFER                         */
  1671. ;/*                                                                    */
  1672. ;/* EXIT-NORMAL:  [di].prtcount = incremented by 1.                    */
  1673. ;/*               set CHARACTER_OUT in commonflags                     */
  1674. ;/*                                                                    */
  1675. ;/* EXIT-ERROR : N/A                                                   */
  1676. ;/*                                                                    */
  1677. ;/* INTERNAL REFERENCES:  NONE                                         */
  1678. ;/*    ROUTINES:                                                       */
  1679. ;/*                                                                    */
  1680. ;/* EXTERNAL REFERENCES:  NONE                                         */
  1681. ;/*    ROUTINES:                                                       */
  1682. ;/*                                                                    */
  1683. ;/*********************** END OF SPECIFICATIONS ************************/
  1684. Procedure sendtodev near
  1685.         ASSUME  CS:CSEG,DS:DSEG,ES:NOTHING,SS:NOTHING
  1686.         mov     al,BYTE PTR es:[bx]                     ; GET NEXT CHAR TO PRINT
  1687.         inc     [di].prtcount                           ; INC PRINTED COUNT
  1688.  
  1689.         cli                                             ; DISABLE INTERRUPTS
  1690.         or      [di].commonflags,CHARACTER_OUT          ; SET CHAR OUT FLAG
  1691.  
  1692.         out     dx,al                                   ; SEND DATA TO DATA PORT
  1693.         inc     dx                                      ; POINT TO CONTROL PORT
  1694.         inc     dx                                      ; POINT TO CONTROL PORT
  1695.         mov     al,STROBELOW                            ; SET STROBE LOW BIT
  1696.         cmp     [di].curintlevel,0                      ; IF !RUNNING ON TIMER
  1697.         jne     sendtodev1                              ; THEN IRQ ENABLE SET
  1698.         and     al,NOT IRQENABLEBIT                     ; ELSE NO IRQ ENABLE
  1699. sendtodev1:
  1700.         out     dx,al                                   ; STROBE >1us AND <5us
  1701.         DevIODelay <bx>                                 ; I/O DELAY - STR WIDTH
  1702.         DevIODelay <bx>                                 ; I/O DELAY - STR WIDTH
  1703.         mov     al,STROBEHIGH                           ; SET THE STROBE HIGH
  1704.         cmp     [di].curintlevel,0                      ; IF !RUNNING ON TIMER
  1705.         jne     sendtodev2                              ; THEN IRQ ENABLE SET
  1706.         and     al,NOT IRQENABLEBIT                     ; ELSE NO IRQ ENABLE
  1707. sendtodev2:
  1708.         out     dx,al                                   ; NEW CTRL VALUE TO PORT
  1709.         sti                                             ; ELSE ENABLE INTERRUPTS
  1710.         ret
  1711. EndProc sendtodev
  1712.  
  1713. BREAK <TIMEOUT ROUTINE FOR DEVICE LPT1>
  1714. ;/********************** START OF SPECIFICATIONS ***********************/
  1715. ;/*                                                                    */
  1716. ;/* SUBROUTINE NAME:  PRT_TIMEOUT_1                                    */
  1717. ;/*                                                                    */
  1718. ;/* DESCRIPTIVE NAME:  Timeout routine for LPT1                        */
  1719. ;/*                                                                    */
  1720. ;/* FUNCTION:   This routine calculates the index into the device data */
  1721. ;/*             area and calls the general timeout routine.  This      */
  1722. ;/*             routine is called by timer services once every second. */
  1723. ;/*                                                                    */
  1724. ;/* NOTES:  It is the timeout routine's responsibility to save and     */
  1725. ;/*         restore all registers used in the printer timeout handler. */
  1726. ;/*                                                                    */
  1727. ;/* ENTRY POINT:                                                       */
  1728. ;/*         LINKAGE:  prt_timeout_1:far                                */
  1729. ;/*                   call prt_timeout_1                               */
  1730. ;/*                                                                    */
  1731. ;/* INPUT:  DS = our data segment                                      */
  1732. ;/*                                                                    */
  1733. ;/* EXIT-NORMAL:  All registers are restored.                          */
  1734. ;/*                                                                    */
  1735. ;/* EXIT-ERROR:  See EXIT-NORMAL above.                                */
  1736. ;/*                                                                    */
  1737. ;/* INTERNAL REFERENCES:  prt_timeout                                  */
  1738. ;/*    ROUTINES:                                                       */
  1739. ;/*                                                                    */
  1740. ;/* EXTERNAL REFERENCES:  NONE                                         */
  1741. ;/*    ROUTINES:                                                       */
  1742. ;/*                                                                    */
  1743. ;/*********************** END OF SPECIFICATIONS ************************/
  1744. Procedure prt_timeout_1 far
  1745.         ASSUME  CS:CSEG,DS:DSEG,ES:NOTHING,SS:NOTHING
  1746.         pusha                                           ; SAVE ALL REGISTERS
  1747.         push    es                                      ; SAVE EXTRA SEGMENT
  1748.         mov     di,(LPT1_INDEX * SIZE printer_database) ; TIMEOUT DEVICE = LPT1
  1749.         call    prt_timeout                             ; GEN TIMEOUT ROUTINE
  1750.         pop     es                                      ; RESTORE EXTRA SEGMENT
  1751.         popa                                            ; RESTORE ALL REGISTERS
  1752.         ret                                             ; RET TO TIMER MANAGER
  1753. EndProc prt_timeout_1
  1754.  
  1755. BREAK <TIMEOUT ROUTINE FOR DEVICE LPT2>
  1756. ;/********************** START OF SPECIFICATIONS ***********************/
  1757. ;/*                                                                    */
  1758. ;/* SUBROUTINE NAME:  PRT_TIMEOUT_2                                    */
  1759. ;/*                                                                    */
  1760. ;/* DESCRIPTIVE NAME:  Timeout routine for LPT2                        */
  1761. ;/*                                                                    */
  1762. ;/* FUNCTION:   This routine calculates the index into the device data */
  1763. ;/*             area and calls the general timeout routine.  This      */
  1764. ;/*             routine is called by timer services once every second. */
  1765. ;/*                                                                    */
  1766. ;/* NOTES:  It is the timeout routine's responsibility to save and     */
  1767. ;/*         restore all registers used in the printer timeout handler. */
  1768. ;/*                                                                    */
  1769. ;/* ENTRY POINT:                                                       */
  1770. ;/*         LINKAGE:  prt_timeout_2:far                                */
  1771. ;/*                   call prt_timeout_2                               */
  1772. ;/*                                                                    */
  1773. ;/* INPUT:  DS = our data segment                                      */
  1774. ;/*                                                                    */
  1775. ;/* EXIT-NORMAL:  All registers are restored.                          */
  1776. ;/*                                                                    */
  1777. ;/* EXIT-ERROR:  See EXIT-NORMAL above.                                */
  1778. ;/*                                                                    */
  1779. ;/* INTERNAL REFERENCES:  prt_timeout                                  */
  1780. ;/*    ROUTINES:                                                       */
  1781. ;/*                                                                    */
  1782. ;/* EXTERNAL REFERENCES:  NONE                                         */
  1783. ;/*    ROUTINES:                                                       */
  1784. ;/*                                                                    */
  1785. ;/*********************** END OF SPECIFICATIONS ************************/
  1786. Procedure prt_timeout_2 far
  1787.         ASSUME  CS:CSEG,DS:DSEG,ES:NOTHING,SS:NOTHING
  1788.         pusha                                           ; SAVE ALL REGISTERS
  1789.         push    es                                      ; SAVE EXTRA SEGMENT
  1790.         mov     di,(LPT2_INDEX * SIZE printer_database) ; TIMEOUT DEVICE = LPT2
  1791.         call    prt_timeout                             ; GEN TIMEOUT ROUTINE
  1792.         pop     es                                      ; RESTORE EXTRA SEGMENT
  1793.         popa                                            ; RESTORE ALL REGISTERS
  1794.         ret                                             ; RET TO TIMER MANAGER
  1795. EndProc prt_timeout_2
  1796.  
  1797. BREAK <TIMEOUT ROUTINE FOR DEVICE LPT3>
  1798. ;/********************** START OF SPECIFICATIONS ***********************/
  1799. ;/*                                                                    */
  1800. ;/* SUBROUTINE NAME:  PRT_TIMEOUT_3                                    */
  1801. ;/*                                                                    */
  1802. ;/* DESCRIPTIVE NAME:  Timeout routine for LPT3                        */
  1803. ;/*                                                                    */
  1804. ;/* FUNCTION:   This routine calculates the index into the device data */
  1805. ;/*             area and calls the general timeout routine.  This      */
  1806. ;/*             routine is called by timer services once every second. */
  1807. ;/*                                                                    */
  1808. ;/* NOTES:  It is the timeout routine's responsibility to save and     */
  1809. ;/*         restore all registers used in the printer timeout handler. */
  1810. ;/*                                                                    */
  1811. ;/* ENTRY POINT:                                                       */
  1812. ;/*         LINKAGE:  prt_timeout_3:far                                */
  1813. ;/*                   call prt_timeout_3                               */
  1814. ;/*                                                                    */
  1815. ;/* INPUT:  DS = our data segment                                      */
  1816. ;/*                                                                    */
  1817. ;/* EXIT-NORMAL:  All registers are restored.                          */
  1818. ;/*                                                                    */
  1819. ;/* EXIT-ERROR:  See EXIT-NORMAL above.                                */
  1820. ;/*                                                                    */
  1821. ;/* INTERNAL REFERENCES:  prt_timeout                                  */
  1822. ;/*    ROUTINES:                                                       */
  1823. ;/*                                                                    */
  1824. ;/* EXTERNAL REFERENCES:  NONE                                         */
  1825. ;/*    ROUTINES:                                                       */
  1826. ;/*                                                                    */
  1827. ;/*********************** END OF SPECIFICATIONS ************************/
  1828. Procedure prt_timeout_3 far
  1829.         ASSUME  CS:CSEG,DS:DSEG,ES:NOTHING,SS:NOTHING
  1830.         pusha                                           ; SAVE ALL REGISTERS
  1831.         push    es                                      ; SAVE EXTRA SEGMENT
  1832.         mov     di,(LPT3_INDEX * SIZE printer_database) ; TIMEOUT DEVICE = LPT3
  1833.         call    prt_timeout                             ; GEN TIMEOUT ROUTINE
  1834.         pop     es                                      ; RESTORE EXTRA SEGMENT
  1835.         popa                                            ; RESTORE ALL REGISTERS
  1836.         ret                                             ; RET TO TIMER MANAGER
  1837. EndProc prt_timeout_3
  1838.  
  1839. BREAK <GENERAL TIMEOUT ROUTINE>
  1840. ;/********************** START OF SPECIFICATIONS ***********************/
  1841. ;/*                                                                    */
  1842. ;/* SUBROUTINE NAME:  PRT_TIMEOUT                                      */
  1843. ;/*                                                                    */
  1844. ;/* DESCRIPTIVE NAME:  The timeout entry point is used to cancel the   */
  1845. ;/*                    timed out print block request.                  */
  1846. ;/*                                                                    */
  1847. ;/* FUNCTION:  This routine is called 1 time a second.  It will count  */
  1848. ;/*            timeoutmax times to see if a timeout has occurred.      */
  1849. ;/*            If the restart flag is on, this routine will try to     */
  1850. ;/*            immediately restart the request otherwise if timeout    */
  1851. ;/*            equals timeoutmax, it will deregister the timeout       */
  1852. ;/*            handler from the Timer Manager, and will call the       */
  1853. ;/*            cleanup routine to cancel the request.  If infinite     */
  1854. ;/*            retry is set, this routine will try to restart the      */
  1855. ;/*            print request.                                          */
  1856. ;/*                                                                    */
  1857. ;/* NOTES:                                                             */
  1858. ;/*                                                                    */
  1859. ;/* ENTRY POINT:  PRT_TIMEOUT:NEAR                                     */
  1860. ;/*    LINKAGE:  CALL PRT_TIMEOUT                                      */
  1861. ;/*                                                                    */
  1862. ;/* INPUT:  DI = offset of device into perprtarea.                     */
  1863. ;/*         [DI].timeoutmax = maximum wait time in seconds before      */
  1864. ;/*                           canceling the print request.             */
  1865. ;/*         [DI].timeoutctr = counter maintained to reach timeoutmax   */
  1866. ;/*                                                                    */
  1867. ;/* EXIT-NORMAL:  [DI].cancelflags = CANIOERROR                        */
  1868. ;/*                                                                    */
  1869. ;/* EXIT-ERROR:  See EXIT-NORMAL above.                                */
  1870. ;/*                                                                    */
  1871. ;/* INTERNAL REFERENCES:  cleanup                                      */
  1872. ;/*    ROUTINES:          prterp                                       */
  1873. ;/*                       sendmonerpkt                                 */
  1874. ;/*                       sendchar                                     */
  1875. ;/*                                                                    */
  1876. ;/* EXTERNAL REFERENCES:  NONE                                         */
  1877. ;/*    ROUTINES:                                                       */
  1878. ;/*                                                                    */
  1879. ;/*********************** END OF SPECIFICATIONS ************************/
  1880. Procedure prt_timeout near
  1881.         ASSUME  CS:CSEG,DS:DSEG,ES:NOTHING,SS:NOTHING
  1882.         add     di,OFFSET perprtarea                    ; START OF PERPRTDATA
  1883.  
  1884.         test    [di].commonflags, USEPOLLING            ; USING POLLING?
  1885.         jz      prt_timeout_interrupts                  ; NO, USING INTERUPTS
  1886.         call    prt_timeout_polling                     ; YES, CALL POLLING FUNC
  1887.         jmp     prt_time_2                              ; AND EXIT
  1888.  
  1889. prt_timeout_interrupts:
  1890.         test    [di].commonflags1,CANMONPKT             ; CANCEL MON PRT REQ?
  1891.         jnz     prt_time_05                             ; YES
  1892.  
  1893.         inc     [di].timeoutctr                         ; INC CTR TO 20 SECONDS
  1894.         mov     ax,[di].timeoutmax                      ; GET TIMEOUT LIMIT
  1895.         cmp     [di].timeoutctr,ax                      ; IF !20 SECOND TIMEOUT
  1896.         jb      prt_time_1                              ; THEN TRY TO RESEND
  1897.  
  1898.         mov     [di].timeoutctr,0                       ; ELSE CLEAR THE COUNTER
  1899.         test    [di].commonflags,MONPRINTING            ; ERROR ON MON REQ?
  1900.         jz      prt_time_0                              ; NO
  1901.         test    [di].commonflags,MONERRPKTSENT          ; ERR PKT ALREADY SENT
  1902.         jnz     prt_time_0                              ; YES
  1903.         call    prterp                                  ; GET ERROR CODE
  1904.         call    sendmonerpkt                            ; SEND MON ERROR PKT
  1905. prt_time_0:
  1906.         or      [di].commonflags,PRTRESTART             ; ASSUME INF RETRY
  1907.         test    [di].commonflags,INFINRETRY             ; IF INF RETRY
  1908.         jnz     prt_time_1                              ; THEN PROC INF RETRY
  1909.         and     [di].commonflags,NOT PRTRESTART         ; ASSUMED WRONG, RESET
  1910. prt_time_05:
  1911.         call    prterp                                  ; GET CANCEL FLAGS
  1912.         call    cleanup                                 ; CLEANUP
  1913.         jmp     prt_time_2                              ; EXIT
  1914.  
  1915. prt_time_1:                                             ; THEN INFINITE RETRY
  1916.         cmp     [di].curintlevel,0                      ; IF !USING INTERRUPTS
  1917.         je      prt_time_2                              ; THEN USING TIMER, NOP
  1918.         test    [di].commonflags,PRTRESTART             ; ELSEIF RESTART IS OFF
  1919.         jz      prt_time_2                              ; THEN NO ERRORS, NOP
  1920.         call    sendchar                                ; ELSE INTS/ERRS RESTART
  1921. prt_time_2:
  1922.         ret
  1923. EndProc prt_timeout
  1924.  
  1925. BREAK <CLEANUP ROUTINE>
  1926. ;/********************** START OF SPECIFICATIONS ***********************/
  1927. ;/*                                                                    */
  1928. ;/* SUBROUTINE NAME:  CLEANUP ROUTINE                                  */
  1929. ;/*                                                                    */
  1930. ;/* DESCRIPTIVE NAME:  Print cleanup routine.                          */
  1931. ;/*                                                                    */
  1932. ;/* FUNCTION: THE FUNCTION OF THIS SUBROUTINE IS TO PERFORM THE        */
  1933. ;/*           CLEANUP WORK WHEN A REQUEST IS COMPLETED.  THIS ROUTINE  */
  1934. ;/*           RETURN INFORMATION IN THE REQUEST BLOCK AND ISSUES A     */
  1935. ;/*           DEVICE DONE ON THE REQUEST BLOCK.                        */
  1936. ;/*                                                                    */
  1937. ;/* NOTE:     SetIRQ done on printblock call and UnSetIRQ done on      */
  1938. ;/*           cleanup calls.  This allows sharing of IRQ5 and 7 on AT. */
  1939. ;/*                                                                    */
  1940. ;/* ENTRY POINT: CLEANUP                                               */
  1941. ;/*    LINKAGE : CALL NEAR                                             */
  1942. ;/*                                                                    */
  1943. ;/* INPUT: DI = offset to appropriate perprtdata area                  */
  1944. ;/*        [DI].cancelflags = filled in.                               */
  1945. ;/*                                                                    */
  1946. ;/* EXIT-NORMAL:                                                       */
  1947. ;/*                                                                    */
  1948. ;/* EXIT-ERROR :                                                       */
  1949. ;/*                                                                    */
  1950. ;/* INTERNAL REFERENCES:  stoptimer                                    */
  1951. ;/*    ROUTINES:                                                       */
  1952. ;/*                                                                    */
  1953. ;/* EXTERNAL REFERENCES:  DEVICE_HELP  ResetTimer                      */
  1954. ;/*    ROUTINES:                       UnSetIRQ                        */
  1955. ;/*                                    ProcRun                         */
  1956. ;/*                                                                    */
  1957. ;/*********************** END OF SPECIFICATIONS ************************/
  1958. Procedure cleanup near
  1959.         ASSUME  CS:CSEG,DS:DSEG,ES:NOTHING,SS:NOTHING
  1960.         mov     ax,[di].timeout_off                     ; TIMEOUT ENTRY POINT
  1961.         mov     dl,DevHlp_ResetTimer                    ; RESET TIMEOUT TIMER
  1962.         call    DWORD PTR [device_help]                 ; CALL TIMER SERVICES
  1963.  
  1964.         cmp     [di].curintlevel,0                      ; IF !RUNNING ON TIMER
  1965.         jne     cleanup1                                ; THEN RUNNING ON INTS
  1966.         call    stoptimer                               ; RESET DEVICE ON TIMER
  1967.         jmp     SHORT cleanup2
  1968.  
  1969. cleanup1:
  1970.         xor     bh,bh                                   ; MAKE BH ZERO
  1971.         mov     bl,[di].intlevel                        ; IRQ NUMBER 0-F
  1972.         mov     dl,DevHlp_UnSetIRQ                      ; UNSET IRQ AT 8259
  1973.         call    DWORD PTR [device_help]                 ; CALL HARD INT MGR
  1974.  
  1975.         mov     dx,[di].deviceaddr                      ; GET DEVICE ADDRESS
  1976.         inc     dx
  1977.         inc     dx                                      ; POINT TO CONTROL PORT
  1978.         mov     al,DISABLEINT                           ; DISABLE INT AT PORT
  1979.         out     dx,al                                   ; SEND NEW CTRL VALUE
  1980.  
  1981. cleanup2:
  1982.         mov     es,[di].dosrqseg                        ; ASSUME DOS REQUEST BLK
  1983.         mov     bx,[di].dosoffset                       ; ASSUME DOS REQUEST BLK
  1984.         test    [di].commonflags,MONPRINTING            ; IF !MONITOR REQUEST
  1985.         jz      cleanup3                                ; THEN ASSUMED CORRECTLY
  1986.         mov     es,[di].monseg                          ; MON REQUEST BLOCK
  1987.         mov     bx,[di].monoffset                       ; MON REQUEST BLOCK
  1988. cleanup3:
  1989.         cmp     es:[bx].PktCmd,CMDOUTPUT                ; IF COMMAND = WRITE
  1990.         je      cleanup4                                ; THEN RETURN PRT COUNT
  1991.         cmp     es:[bx].PktCmd,CMDOUTPUTV               ; IF COMMAND = WRITE/V
  1992.         jne     cleanup5                                ; THEN RETURN PRT COUNT
  1993. cleanup4:
  1994.         mov     dx,[di].prtcount                        ; GET COUNT PRINTED
  1995.  
  1996. ;/**********************************************************************/
  1997. ;/*                                                                    */
  1998. ;/* ANOTHER 3X BOX KLUGE - PTM 7095                                    */
  1999. ;/*                                                                    */
  2000. ;/**********************************************************************/
  2001. ;/*                                                                    */
  2002. ;/* THE FOLLOWING CODE IS REQUIRED TO FIX A SITUATION IN THE REAL MODE */
  2003. ;/* BOX CAUSED BY THE "COPY" AND "TYPE" COMMANDS WHICH ARE DIRECTED TO */
  2004. ;/* THE PRINTER.  THESE COMMANDS ISSUE CHARACTER REQUESTS ONE          */
  2005. ;/* CHARACTER AT A TIME.  IF THE PRINTER IS A BUFFERED DEVICE AND IT   */
  2006. ;/* IS TURNED OFF LINE, IT IS QUITE POSSIBLE THAT THE CHARACTER HAS    */
  2007. ;/* BEEN SENT TO THE PRINTER BUFFER BUT THE INTERRUPT WON'T BE         */
  2008. ;/* RECEIVED AND WE WILL TIME OUT.  THIS RESULTS IN AN ERROR BEING     */
  2009. ;/* RETURNED IN THE REQUEST PACKET BUT THE BYTE COUNT PRINTED IS THE   */
  2010. ;/* TOTAL BYTE COUNT REQUESTED.  THE HARD ERROR HANDLER GETS THE ERROR */
  2011. ;/* AND ALLOWS THE USER TO SELECT THE RETRY FUNCTION.  THIS CAUSES THE */
  2012. ;/* SAME CHARACTER TO BE SENT TO THE PRINTER WHEN IT IS PUT BACK ON    */
  2013. ;/* LINE AGAIN.                                                        */
  2014. ;/*                                                                    */
  2015. ;/* THE FOLLOWING CODE WILL CLEAR ANY ERROR STATUS SET BY OTHER PARTS  */
  2016. ;/* OF THE DEVICE DRIVER ONLY IF THE TOTAL NUMBER OF CHARS REQUESTED   */
  2017. ;/* HAVE BEEN SENT TO THE DEVICE.  THIS MEANS THAT THE REQUEST IS      */
  2018. ;/* COMPLETE.  THIS WAY, THE HARD ERROR HANDLER WON'T RE-ISSUE THE     */
  2019. ;/* REQUEST FOR THE SAME CHARACTER IF RETRY IS SELECTED.  THE HARD     */
  2020. ;/* ERROR HANDLER WON'T SEE THE ERROR FOR THIS CHARACTER.              */
  2021. ;/*                                                                    */
  2022. ;/**********************************************************************/
  2023.  
  2024.         cmp     [di].initialcount,dx                    ; IF BYTES REMAINING
  2025.         jne     cleanup45                               ; THEN MUST SET ERROR
  2026.         mov     [di].cancelflags,CANNOERROR             ; SET NO ERROR
  2027. cleanup45:
  2028.  
  2029. ;/**********************************************************************/
  2030. ;/*                                                                    */
  2031. ;/* END OF KLUGE.                                                      */
  2032. ;/*                                                                    */
  2033. ;/**********************************************************************/
  2034.  
  2035.         mov     es:[bx].IOcount,dx                      ; PUT COUNT IN REQ PKT
  2036. cleanup5:
  2037.         cmp     es:[bx].PktStatus,CHARIOINT             ; CTRL C PRESSED BY USER
  2038.         je      cleanup6                                ; YES, EXIT
  2039.  
  2040.         xor     ah,ah                                   ; ZERO OUT AH
  2041.         mov     al,[di].cancelflags                     ; GET CANCEL FLAGS
  2042.         mov     [di].cancelflags,0                      ; ZERO OUT CANCEL FLAGS
  2043.         mov     si,ax                                   ; GET ERROR CODE
  2044.         sal     si,1                                    ; GET WORD INDEX
  2045.         mov     ax,doserrors[si]                        ; GET ERROR CODE
  2046.         mov     es:[bx].PktStatus,ax                    ; PUT ERR. IN REQ.BLK
  2047.  
  2048.         mov     ax,es                                   ; BLOCK ID
  2049.         inc     bx                                      ; UNIQUE BLOCK ID
  2050.         mov     dl,DevHlp_ProcRun                       ; RUN PRINTBLOCK THREAD
  2051.         call    DWORD PTR [device_help]                 ; DEVICE HELP
  2052.         dec     bx                                      ; ADDRESS REQUEST BLOCK
  2053.  
  2054. cleanup6:
  2055.         ret
  2056. EndProc cleanup
  2057.  
  2058. BREAK <PRINTER ERROR STATUS PROCESSING>
  2059. ;/********************** START OF SPECIFICATIONS ***********************/
  2060. ;/*                                                                    */
  2061. ;/* SUBROUTINE NAME: PRTERP                                            */
  2062. ;/*                                                                    */
  2063. ;/* DESCRIPTIVE NAME: ANALYZE STATUS FLAGS                             */
  2064. ;/*                                                                    */
  2065. ;/* FUNCTION: THE FUNCTION OF THIS SUBROUTINE IS TO ANALYZE THE STATUS */
  2066. ;/*           INFORMATION RETURNED FROM "GETSTATUS" AND SAVED IN THE   */
  2067. ;/*           CANCELSTATUS BYTE.                                       */
  2068. ;/*                                                                    */
  2069. ;/* ENTRY POINT: PRTERP                                                */
  2070. ;/*    LINKAGE : CALL NEAR                                             */
  2071. ;/*                                                                    */
  2072. ;/* INPUT: DI = OFFSET TO APPROPRIATE PERPRTDATA AREA                  */
  2073. ;/*        AH = PRINTER STATUS                                         */
  2074. ;/*                                                                    */
  2075. ;/* EXIT-NORMAL:  [DI].cancelflags = filled in.                        */
  2076. ;/*                                                                    */
  2077. ;/* EXIT-ERROR :  See EXIT-NORMAL above.                               */
  2078. ;/*                                                                    */
  2079. ;/* INTERNAL REFERENCES:  getstatus                                    */
  2080. ;/*    ROUTINES:                                                       */
  2081. ;/*                                                                    */
  2082. ;/* EXTERNAL REFERENCES:  NONE                                         */
  2083. ;/*    ROUTINES:                                                       */
  2084. ;/*                                                                    */
  2085. ;/*********************** END OF SPECIFICATIONS ************************/
  2086. ;***********************************************************************
  2087. ;*                                                                     *
  2088. ;*      CHECK STATUS BITS AND TAKE APPROPRIATE ACTION.                 *
  2089. ;*      MESSAGES CURRENTLY ISSUED FOR ERROR CONDITIONS:                *
  2090. ;*                                                                     *
  2091. ;*      #20 = THE SYSTEM CANNOT FIND THE DEVICE SPECIFIED.             *
  2092. ;*                                                                     *
  2093. ;*      #28 = THE PRINTER IS OUT OF PAPER.                             *
  2094. ;*                                                                     *
  2095. ;*      #29 = THE SYSTEM CANNOT WRITE TO THE SPECIFIED DEVICE.         *
  2096. ;*                                                                     *
  2097. ;***********************************************************************
  2098. Procedure prterp near
  2099.         ASSUME  CS:CSEG,DS:DSEG,ES:NOTHING,SS:NOTHING
  2100.         mov     [di].cancelflags,CANNOERROR             ; CLEAR CANCEL FLAGS
  2101.         mov     ah,[di].cancelstatus                    ; GET STATUS FLAGS
  2102.         and     ah,ah                                   ; CHECK IF ZERO
  2103.         .IF     Z
  2104.           call    getstatus
  2105.           mov     [di].cancelstatus,ah                  ; SAVE CANCEL STATUS
  2106.         .ENDIF
  2107. ;*******************************************************************************
  2108. ;* B0 = NOT BUSY & PAPER OUT & SELECTED = !CABLED ON MONO / SERIAL ADAPTER #20 *
  2109. ;*******************************************************************************
  2110.         .IF <BIT ah NZ NOTBUSY> AND                     ; IF NOT BUSY AND
  2111.         .IF <BIT ah NZ PAPEROUT> AND                    ; IF PAPER OUT AND
  2112.         .IF <BIT ah NZ NOTSELECTED>                     ; IF SELECTED
  2113.           mov     [di].cancelflags,CANNOTSELECT         ; SET SELECT ERROR
  2114. ;*******************************************************************************
  2115. ;* 30 = BUSY & PAPER OUT & SELECTED & NOT I/O ERROR = OUT OF PAPER         #28 *
  2116. ;*******************************************************************************
  2117.         .ELSEIF <BIT ah Z NOTBUSY> AND                  ; IF BUSY AND
  2118.         .IF <BIT ah NZ PAPEROUT> AND                    ; IF PAPER OUT AND
  2119.         .IF <BIT ah NZ NOTSELECTED> AND                 ; IF SELECTED AND
  2120.         .IF <BIT ah Z IOERROR>                          ; IF NOT I/O ERROR
  2121.           mov     [di].cancelflags,CANPAPEROUT          ; SET PAPER OUT ERROR
  2122. ;*******************************************************************************
  2123. ;* 28 = BUSY & PAPER OUT & NOT SELECTED & I/O ERROR = OUT OF PAPER         #28 *
  2124. ;*******************************************************************************
  2125.         .ELSEIF <BIT ah Z NOTBUSY> AND                  ; IF BUSY AND
  2126.         .IF <BIT ah NZ PAPEROUT> AND                    ; IF PAPER OUT AND
  2127.         .IF <BIT ah Z NOTSELECTED> AND                  ; IF NOT SELECTED AND
  2128.         .IF <BIT ah NZ IOERROR>                         ; IF I/O ERROR
  2129.           mov     [di].cancelflags,CANPAPEROUT          ; SET PAPER OUT ERROR
  2130. ;*******************************************************************************
  2131. ;* 10 = BUSY & SELECTED = NOT READY                                        #29 *
  2132. ;*******************************************************************************
  2133.         .ELSEIF <BIT ah Z NOTBUSY> AND                  ; IF BUSY AND
  2134.         .IF <BIT ah NZ NOTSELECTED>                     ; IF SELECTED
  2135.           mov     [di].cancelflags,CANIOERROR           ; SET I/O ERROR
  2136. ;*******************************************************************************
  2137. ;* 08 = BUSY & I/O ERROR = OFF LINE                                        #29 *
  2138. ;*******************************************************************************
  2139.         .ELSEIF <BIT ah Z NOTBUSY> AND                  ; IF BUSY AND
  2140.         .IF <BIT ah NZ IOERROR>                         ; IF I/O ERROR
  2141.           mov     [di].cancelflags,CANIOERROR           ; SET I/O ERROR
  2142. ;*******************************************************************************
  2143. ;* 00 = BUSY & NOTHING ELSE = NOT READY                                    #29 *
  2144. ;*******************************************************************************
  2145.         .ELSEIF <ah EQ 0>                               ; IF ONLY BUSY
  2146.           mov     [di].cancelflags,CANIOERROR           ; SET I/O ERROR
  2147. ;*******************************************************************************
  2148. ;* 88 = NOT BUSY & I/O ERROR = POWERED OFF                                 #20 *
  2149. ;*******************************************************************************
  2150.         .ELSEIF <BIT ah NZ NOTBUSY> AND                 ; IF NOT BUSY AND
  2151.         .IF <BIT ah NZ IOERROR>                         ; IF I/O ERROR
  2152.           mov     [di].cancelflags,CANNOTSELECT         ; SET SELECT ERROR
  2153.         .ELSE                                           ; NOT A "SELECT" CHAR
  2154.           mov     [di].cancelflags,CANNOTSELECT         ; SET SELECT ERROR
  2155.         .ENDIF
  2156.         xor     ah,ah                                   ; ZERO OUT AH
  2157.         mov     [di].cancelstatus,ah                    ; SET STATUS FLAGS = 0
  2158.         RET
  2159. EndProc prterp
  2160.  
  2161. BREAK <GET STATUS OF SPECIFIED DEVICE>
  2162. ;/********************** START OF SPECIFICATIONS ***********************/
  2163. ;/*                                                                    */
  2164. ;/* SUBROUTINE NAME: GETSTATUS                                         */
  2165. ;/*                                                                    */
  2166. ;/* DESCRIPTIVE NAME: GET STATUS ROUTINE                               */
  2167. ;/*                                                                    */
  2168. ;/* FUNCTION: THE FUNCTION OF THIS SUBROUTINE IS TO RETURN THE STATUS  */
  2169. ;/*           OF THE REQUESTED DEVICE IN REGISTER AH.                  */
  2170. ;/*                                                                    */
  2171. ;/* NOTES:  DATA, STATUS, THEN CONTROL PORT.                           */
  2172. ;/*                                                                    */
  2173. ;/* ENTRY POINT: GETSTATUS                                             */
  2174. ;/*    LINKAGE : CALL NEAR OR FAR                                      */
  2175. ;/*                                                                    */
  2176. ;/* INPUT: DI = OFFSET TO APPROPRIATE PERPRTDATA AREA                  */
  2177. ;/*                                                                    */
  2178. ;/* EXIT-NORMAL:  AH = DEVICE STATUS, DX = DATA PORT ADDRESS           */
  2179. ;/*                                                                    */
  2180. ;/* EXIT-ERROR :  AH = DEVICE STATUS, DX = DATA PORT ADDRESS           */
  2181. ;/*                                                                    */
  2182. ;/* INTERNAL REFERENCES:  NONE                                         */
  2183. ;/*    ROUTINES:                                                       */
  2184. ;/*                                                                    */
  2185. ;/* EXTERNAL REFERENCES:  NONE                                         */
  2186. ;/*    ROUTINES:                                                       */
  2187. ;/*                                                                    */
  2188. ;/*********************** END OF SPECIFICATIONS ************************/
  2189. Procedure getstatus,HYBRID
  2190.         ASSUME  CS:CSEG,DS:DSEG,ES:NOTHING,SS:NOTHING
  2191.         mov     dx,[di].deviceaddr                      ; GET DEVICE ADDRESS
  2192.         inc     dx                                      ; POINT TO STATUS PORT
  2193.         in      al,dx                                   ; GET STATUS BYTE
  2194.         mov     ah,al                                   ; MOV STATUS INTO AH
  2195.         and     ah,UNUSEDBITS                           ; TURN OFF UNUSED BITS
  2196.         xor     ah,REVERSEBITS                          ; FLIP A COUPLE OF BITS
  2197.         dec     dx                                      ; RESET DX TO DATA ADDR
  2198.         ret
  2199. EndProc getstatus
  2200.  
  2201. ;  *** END OF RESIDENT CODE ***
  2202. ;  ALL CODE AFTER THIS POINT IS RELEASED AFTER INITIALIZATION
  2203. CODEEND EQU     $ - 1                                   ; USE LIMIT OF SEGMENT
  2204.  
  2205. BREAK <INITIALIZATION ROUTINE>
  2206. ;/*********************** END OF SPECIFICATIONS ************************/
  2207. ;/*                                                                    */
  2208. ;/* SUBROUTINE NAME:  PRTINIT                                          */
  2209. ;/*                                                                    */
  2210. ;/* DESCRIPTIVE NAME:  Initialize the printer device driver            */
  2211. ;/*                                                                    */
  2212. ;/* FUNCTION:  This routine is called to perform any parallel port     */
  2213. ;/*            device driver initialization.  This routine will be     */
  2214. ;/*            called once for each device header defined in the data  */
  2215. ;/*            segment.  All initialization is performed on the first  */
  2216. ;/*            call.                                                   */
  2217. ;/*                                                                    */
  2218. ;/* NOTES:                                                             */
  2219. ;/*                                                                    */
  2220. ;/* ENTRY POINT:                                                       */
  2221. ;/*         LINKAGE:  prtinit:NEAR                                     */
  2222. ;/*                   call prtinit                                     */
  2223. ;/*                                                                    */
  2224. ;/* INPUT:  ES = Virtual segment of kernel request block               */
  2225. ;/*         BX = Virtual offset of kernel request block                */
  2226. ;/*         DI = Offset to appropriate perprtdata area                 */
  2227. ;/*                                                                    */
  2228. ;/* EXIT-NORMAL:  Status field of Kernel Request Block is filled in.   */
  2229. ;/*               See the specific request in the CP/DOS OS and Util.  */
  2230. ;/*                 Functional Specification for other return values.  */
  2231. ;/*               timeoutval = # of ticks to wait for timeout          */
  2232. ;/*                                                                    */
  2233. ;/* EXIT-ERROR:  see EXIT-NORMAL above.                                */
  2234. ;/*                                                                    */
  2235. ;/* EFFECTS:                                                           */
  2236. ;/*                                                                    */
  2237. ;/* INTERNAL REFERENCES:  eisainit                                     */
  2238. ;/*    ROUTINES:          _RM_PRT_CreateDriver                         */
  2239. ;/*                       parsecmdline                                 */
  2240. ;/*                       RM_PRT_RegisterResources                     */
  2241. ;/*                       initialprt                                   */
  2242. ;/*                                                                    */
  2243. ;/* EXTERNAL REFERENCES:  DEVICE_HELP  GetDOSVar                       */
  2244. ;/*    ROUTINES:                       RegisterPDD                     */
  2245. ;/*                                    AllocGDTSelector                */
  2246. ;/*                                    VirtToPhys                      */
  2247. ;/*                                    RegisterPerfCtrs                */
  2248. ;/*                                                                    */
  2249. ;/*********************** END OF SPECIFICATIONS ************************/
  2250. Procedure prtinit far
  2251.         ASSUME  CS:CSEG,DS:DSEG,ES:NOTHING,SS:NOTHING
  2252.         SaveReg <es,bx>                                 ; SAVE REGISTERS
  2253.         test    flags,FIRSTINIT                         ; IF 1ST TIME THEN
  2254.         jz      prtinit0                                ; DO ONCE ONLY CODE
  2255.         jmp     prtinit1                                ; SKIP ONCE ONLY CODE
  2256.  
  2257.         ; INITIALIZATION CODE DONE ONCE ONLY (DONE DURING PRN INIT CALL)
  2258.         ; (FROM HERE TO PRTINIT1)
  2259.  
  2260. prtinit0:
  2261.         or      flags,FIRSTINIT                         ; SET FIRST INIT ON
  2262.  
  2263.         ; SAVE ADDRESS OF DEVHLP ROUTINE
  2264.  
  2265.         mov     ax,WORD PTR es:[bx].InitpEnd            ; OFFSET OF DEVHLP
  2266.         mov     WORD PTR device_help,ax                 ; OFFSET OF DEVHLP
  2267.         mov     WORD PTR _Device_Help,ax                ; OFFSET OF DEVHLP
  2268.         mov     ax,WORD PTR es:[bx].InitpEnd + 2        ; SEG OF DEVHLP
  2269.         mov     WORD PTR device_help + 2,ax             ; SEG OF DEVHLP
  2270.         mov     WORD PTR _Device_Help + 2,ax            ; SEG OF DEVHLP
  2271.  
  2272.         ; GET POINTER TO GLOBAL INFO SEG
  2273.  
  2274.         mov     al,GLOBINFOSEG                          ; GET VAR GLOBALINFOSEG
  2275.         mov     dl,DevHlp_GetDOSVar                     ; GET DOS VAR FUNCTION
  2276.         call    DWORD PTR [device_help]                 ; CALL DEVHLP
  2277.         mov     es,ax                                   ; AX:BX -> GLOBALINFOSEG
  2278.         mov     es,WORD PTR es:[bx]                     ; ES:BX -> ADDR/GLOBINFO
  2279.         xor     bx,bx
  2280.         mov     WORD PTR glinfoseg,bx                   ; GLOBAL INFOSEG OFF
  2281.         mov     WORD PTR glinfoseg + 2,es               ; GLOBAL INFOSEG SEG
  2282.         mov     bx,es:[bx].SIS_ClkIntrvl                ; GET TIMER INTERVAL
  2283.  
  2284.         xor     dx,dx
  2285.         mov     ax,10000                                ; MICROSEC TO SEC RULE
  2286.         div     bx                                      ; TICKS / MICROSEC
  2287.         mov     timeoutval,ax                           ; SAVE TICKS / SEC
  2288.  
  2289.         ; GET POINTER TO LOCAL INFO SEG
  2290.  
  2291.         mov     al,LOCINFOSEG                           ; GET VAR LOCAL INFOSEG
  2292.         mov     dl,DevHlp_GetDOSVar                     ; GET DOS VAR FUNCTION
  2293.         call    DWORD PTR [device_help]                 ; CALL DEVHLP
  2294.         mov     WORD PTR dosvar,bx                      ; OFF LOCAL INFOSEG
  2295.         mov     WORD PTR dosvar + 2,ax                  ; SEG LOCAL INFOSEG
  2296.  
  2297.         ; REGISTER THE PLPT'S VDD SERVICES ENTRY POINT WITH VLPT.
  2298.         ; THIS ENTRY POINT IS THE ROUTER FOR ALL THE IDC COMMUNICATIONS.
  2299.  
  2300.         push    di                                      ; SAVE PER PRT AREA
  2301.         lea     si,plptname                             ; LOAD PLPT NAME
  2302.         push    SWAPSEG                                 ; SETUP ES
  2303.         pop     es                                      ; 
  2304.         lea     di,PLPTCMD_Entry                        ; ES:DI -> PLPT ROUTER
  2305.         mov     dl,DevHlp_RegisterPDD                   ; REGISTERPDD FUNC
  2306.         call    DWORD PTR [device_help]                 ; CALL DEVICE HELP
  2307.         pop     di
  2308.  
  2309.         ; REGISTER DRIVER WITH RESOURCE MANAGER
  2310.  
  2311.         push    di                                      ; SAVE PERPRTDATA AREA
  2312.         push    ds                                      ; DRIVER NAME SEG
  2313.         lea     ax,ddname                               ; GET DRIVER NAME OFF
  2314.         push    ax                                      ; DRIVER NAME OFF
  2315.         call    _RM_PRT_CreateDriver                    ; REGISTER DRIVER
  2316.         add     sp,4                                    ; CLEAN UP STACK
  2317.         pop     di                                      ; RESTORE PERPRTDATA
  2318.  
  2319.         ; DETERMINE BUS TYPE
  2320.  
  2321.         mov     bustype,ISABUS                          ; ASSUME ISA BUS SYSTEM
  2322.         call    eisainit                                ; CHECK FOR EISA SYSTEM
  2323.         jc      prtinit0a                               ; ASSUMED CORRECT - ISA
  2324.         mov     bustype,EISABUS                         ; EISA BUS SYSTEM
  2325. prtinit0a:
  2326.  
  2327.         ; SET TIMEOUT ENTRY POINTS AND DEVICE INDICES
  2328.  
  2329.         RestoreReg <bx,es>                              ; RESTORE REGISTERS
  2330.         SaveReg <es,bx>                                 ; SAVE REGISTERS
  2331.         push    di                                      ; SAVE PERPRTAREA PTR
  2332.         les     bx,es:[bx].InitParms                    ; GET CONFIG.SYS PARMS
  2333.  
  2334.         mov     di,OFFSET perprtarea                    ; STARTING POINT
  2335.         mov     [di].deviceindex,LPT1_INDEX             ; INDEX FOR LPT1
  2336.         mov     [di].deviceflag,LPT1_FLAG               ; FLAG FOR LPT1
  2337.         mov     ax,es:[bx].LPT1BufSize                  ; GET LPT1 BUFFER SIZE
  2338.         mov     [di].configbufsize,ax                   ; SAVE LPT1 BUFFER SIZE
  2339.         mov     [di].prfvw_off,OFFSET prfvw_ctrs        ; START OF DEVICE CTRS
  2340.         mov     [di].timeout_off,OFFSET prt_timeout_1   ; LPT1 EPT
  2341.  
  2342.         add     di,SIZE printer_database
  2343.         mov     [di].deviceindex,LPT2_INDEX             ; INDEX FOR LPT2
  2344.         mov     [di].deviceflag,LPT2_FLAG               ; FLAG FOR LPT2
  2345.         mov     ax,es:[bx].LPT2BufSize                  ; GET LPT2 BUFFER SIZE
  2346.         mov     [di].configbufsize,ax                   ; SAVE LPT2 BUFFER SIZE
  2347.         mov     [di].prfvw_off,OFFSET prfvw_ctrs        ; START OF PERFVIEW CTRS
  2348.         add     [di].prfvw_off,SIZE prfvw_devarea       ; START OF DEVICE CTRS
  2349.         mov     [di].timeout_off,OFFSET prt_timeout_2   ; LPT2 EPT
  2350.  
  2351.         add     di,SIZE printer_database
  2352.         mov     [di].deviceindex,LPT3_INDEX             ; INDEX FOR LPT3
  2353.         mov     [di].deviceflag,LPT3_FLAG               ; FLAG FOR LPT3
  2354.         mov     ax,es:[bx].LPT3BufSize                  ; GET LPT3 BUFFER SIZE
  2355.         mov     [di].configbufsize,ax                   ; SAVE LPT3 BUFFER SIZE
  2356.         mov     [di].prfvw_off,OFFSET prfvw_ctrs        ; START OF PERFVIEW CTRS
  2357.         add     [di].prfvw_off,(2 * (SIZE prfvw_devarea)) ; START OF DEVICE CTRS
  2358.         mov     [di].timeout_off,OFFSET prt_timeout_3   ; LPT3 EPT
  2359.         pop     di                                      ; RESTORE PERPRTAREA PTR
  2360.         jmp     prtinit3                                ; EXIT
  2361.  
  2362.         ; PDD INITIALIZATION CODE FOR EACH PHYSICAL DEVICE (LPT1, LPT2, LPT3)
  2363.  
  2364. prtinit1:
  2365.         xor     ah,ah                                   ; CLEAR AH
  2366.         mov     al,[di].deviceindex                     ; GET ZERO BASED INDEX
  2367.         add     [di].signature+3,al                     ; PPDA SIGNATURE
  2368.  
  2369.         ; ALLOCATE GDT SELECTOR FOR SENDING DATA TO MONITORS
  2370.  
  2371.         SaveReg <ax,di>                                 ; SAVE REGISTERS
  2372.         push    ds
  2373.         pop     es
  2374.         lea     di,[di].gdtuserbuf                      ; ES:DI -> GDT
  2375.         mov     cx,1                                    ; ALLOCATE 1 SELECTOR
  2376.         mov     dl,DevHlp_AllocGDTSelector              ; ALLOC GDT SEL FUNC
  2377.         call    DWORD PTR [device_help]                 ; CALL DEVHLP
  2378.         RestoreReg <di,ax>                              ; RESTORE REGISTERS
  2379.         jnc     prtinit11                               ; IF NO ERROR, CONTINUE
  2380.         jmp     prtinit4                                ; IF ERROR, EXIT
  2381. prtinit11:
  2382.  
  2383.         ; ALLOCATE GDT SELECTOR FOR PRINTING
  2384.  
  2385.         SaveReg <ax,di>                                 ; SAVE REGISTERS
  2386.         lea     di,[di].gdtprintbuf                     ; ES:DI -> GDT
  2387.         mov     cx,1                                    ; ALLOCATE 1 SELECTOR
  2388.         mov     dl,DevHlp_AllocGDTSelector              ; ALLOC GDT SEL FUNC
  2389.         call    DWORD PTR [device_help]                 ; CALL DEVHLP
  2390.         RestoreReg <di,ax>                              ; RESTORE REGISTERS
  2391.         jnc     prtinit12                               ; IF NO ERROR, CONTINUE
  2392.         jmp     prtinit4                                ; IF ERROR, EXIT
  2393. prtinit12:
  2394.  
  2395.         ; SETUP POINTER TO CACHE TO BUFFER SMALL WRITE REQUESTS WITH THE
  2396.         ; SAME SFN. AT APPROPRIATE TIME, SEND PACKET TO MONITOR.
  2397.  
  2398.         imul    si,ax,SIZE mcache                       ; CALC OFF IN MON CACHE
  2399.         add     si,OFFSET moncache                      ; SI -> DEVICE MON CACHE
  2400.         mov     [di].cache_off,si                       ; SAVE MON CACHE OFFSET
  2401.  
  2402.         ; SETUP POINTER TO BUFFER TO CONTAIN MONITOR PACKET TO BE SENT
  2403.         ; TO MONITORS FOR THIS DEVICE.
  2404.  
  2405.         mov     cx,dataend                              ; GET CURRENT MBUF START
  2406.         mov     [di].tomonbuf_off,cx                    ; SAVE TO MON BUF OFFSET
  2407.         add     cx,[di].configbufsize                   ; CALC NEW MON BUF START
  2408.  
  2409.         ; SETUP POINTER TO BUFFER TO CONTAIN MONITOR PACKET TO BE RECEIVED
  2410.         ; FROM MONITORS FOR THIS DEVICE (MONITOR FINAL BUFFER).
  2411.  
  2412.         mov     [di].frommonbuf_off,cx                  ; SAVE FROM MON BUF OFF
  2413.         add     cx,[di].configbufsize                   ; CALC NEW MON BUF START
  2414.         mov     dataend,cx                              ; SET NEW DATA SEG END
  2415.  
  2416.         ; CONVERT VIRTUAL MONITOR FINAL BUFFER ADDRESS TO PHYSICAL ADDRESS
  2417.         ; AND SAVE IT FOR FUTURE MONITOR REQUESTS.
  2418.  
  2419.         mov     si,[di].frommonbuf_off                  ; DS:SI -> VIRT MON PKT
  2420.         lea     si,[si].frommonbuf                      ; DS:SI -> VIRT ADDR BUF
  2421.         mov     dl,DevHlp_VirtToPhys                    ; VIRTTOPHYS FUNCTION
  2422.         call    DWORD PTR [device_help]                 ; CALL DEVICE HELP
  2423.         jc      prtinit4                                ; IF ERROR, EXIT
  2424.         mov     [di].physbufoff,bx                      ; SAVE PHYS BUF OFF
  2425.         mov     [di].physbufseg,ax                      ; SAVE PHYS BUF SEG
  2426.  
  2427.         ; PARSE FOR COMMAND LINE PARAMETERS
  2428.  
  2429.         RestoreReg <bx,es>                              ; RESTORE REGISTERS
  2430.         SaveReg <es,bx>                                 ; SAVE REGISTERS
  2431.         call    ParseCmdLine                            ; PARSE CMD LINE PARMS
  2432.  
  2433.         ; DETERMINE HARDWARE CAPABILITIES
  2434.  
  2435.         call    prtdeterminehardware                    ; CHECK FOR HARDWARE
  2436.         jc      prtinit4                                ; IF ERROR, EXIT
  2437.  
  2438.         test    [di].commonflags1,PORTEXISTS            ; IF PORT DOESN'T EXIST
  2439.         jz      prtinit2                                ; THEN DON'T REGISTER
  2440.  
  2441.         ; REGISTER WITH RESOURCE MANAGER
  2442.  
  2443.         call    RM_PRT_RegisterResources                ; OBTAIN RESOURCES
  2444.         jc      prtinit4                                ; IF ERROR, EXIT
  2445.  
  2446.         ; INITIALIZE DEVICE
  2447.  
  2448.         or      [di].commonflags1,BOOTINIT              ; SET BOOTINIT FLAG
  2449.         CALLFAR initialprt                              ; INITIALIZE DEVICE
  2450.         and     [di].commonflags1,NOT BOOTINIT          ; RESET BOOTINIT FLAG
  2451.  
  2452.         ; ADD PER-DEVICE PERFVIEW COUNTERS
  2453.  
  2454.         add     db_length,SIZE prfvw_devarea            ; ADD DEV TO DATABLOCK
  2455.         add     WORD PTR tb_totalctrs,NUMBER_TMRS_CTRS  ; ADD DEV CTRS TO TOTAL
  2456. prtinit2:
  2457.         cmp     [di].deviceindex,LPT3_INDEX             ; IF DEVICE != LPT3
  2458.         jne     prtinit3                                ; THEN CONTINUE
  2459.  
  2460.         ; SET PERFVIEW TO POINT TO DATA STRUCTURES
  2461.  
  2462.         mov     si,SEG data_block                       ; SEGMENT OF DATA_BLOCK
  2463.         mov     ax,OFFSET data_block                    ; OFFSET OF DATA_BLOCK
  2464.         mov     di,SEG text_block                       ; SEGMENT OF TEXT_BLOCK
  2465.         mov     bx,OFFSET text_block                    ; OFFSET OF TEXT_BLOCK
  2466.         mov     cx,WORD PTR data_block.dbh_flFlags      ; GET FLAGS
  2467.         mov     dl,DevHlp_RegisterPerfCtrs              ; REGISTER PERFVIEW FUNC
  2468.         call    DWORD PTR [device_help]                 ; CALL DEVICE HELP
  2469.                                                         ; CY = ERROR, AX = CODE
  2470. prtinit3:
  2471.         RestoreReg <bx,es>                              ; RESTORE REGISTERS
  2472.  
  2473.         ; SET ENDING ADDRESS OF CODE AND DATA SEGMENT IN DOS REQUEST BLOCK
  2474.  
  2475.         mov     ax,dataend                              ; END OF DATA SEGMENT
  2476.         dec     ax                                      ; CONVERT TO LIMIT
  2477.         mov     WORD PTR es:[bx].InitpEnd+2,ax          ; END OF DATA SEGMENT
  2478.         mov     WORD PTR es:[bx].InitpEnd,OFFSET CODEEND ; END OF CODE SEGMENT
  2479.         mov     es:[bx].PktStatus,REQDONE               ; SET THE DONE BIT
  2480.         jmp     SHORT prtinit5                          ; EXIT
  2481.  
  2482. prtinit4:
  2483.         pop     bx
  2484.         pop     es
  2485.         mov     WORD PTR es:[bx].InitpEnd+2,0           ; END OF DATA SEGMENT
  2486.         mov     WORD PTR es:[bx].InitpEnd,0             ; END OF CODE SEGMENT
  2487.         mov     es:[bx].PktStatus,GENFAILURE            ; SET THE ERROR CODE
  2488.  
  2489. prtinit5:
  2490.         ret
  2491. EndProc prtinit
  2492.  
  2493. BREAK <DETERMINE HARDWARE ROUTINE>
  2494. ;/********************** START OF SPECIFICATIONS ***********************/
  2495. ;/*                                                                    */
  2496. ;/* SUBROUTINE NAME:  DETERMINE HARDWARE ROUTINE                       */
  2497. ;/*                                                                    */
  2498. ;/* DESCRIPTIVE NAME:  Determine parallel port hardware.               */
  2499. ;/*                                                                    */
  2500. ;/* FUNCTION:   This routine determines the parallel port hardware     */
  2501. ;/*             for ISA-bus systems and updates the perprtdata area    */
  2502. ;/*             accordingly.                                           */
  2503. ;/*                                                                    */
  2504. ;/* NOTES: This routine is called for each device initialized.         */
  2505. ;/*                                                                    */
  2506. ;/* ENTRY POINT:                                                       */
  2507. ;/*         LINKAGE:  prtdeterminehardware:NEAR                        */
  2508. ;/*                   call prtdeterminehardware                        */
  2509. ;/*                                                                    */
  2510. ;/* INPUT:  DS = Data segment                                          */
  2511. ;/*         DI = Offset to appropriate perprtdata area                 */
  2512. ;/*                                                                    */
  2513. ;/* EXIT-NORMAL: NC                                                    */
  2514. ;/*              [di].deviceaddr = base port address                   */
  2515. ;/*              numofprts incremented                                 */
  2516. ;/*              [di].commonflags1 |= PORTEXISTS                       */
  2517. ;/*              [di].introutine = hardware interrupt routine offset   */
  2518. ;/*              [di].intlevel = hardware interrupt level              */
  2519. ;/*                                                                    */
  2520. ;/* EXIT-ERROR:  CY                                                    */
  2521. ;/*                                                                    */
  2522. ;/* EFFECTS: irq5index                                                 */
  2523. ;/*                                                                    */
  2524. ;/* INTERNAL REFERENCES:  NONE                                         */
  2525. ;/*    ROUTINES:                                                       */
  2526. ;/*                                                                    */
  2527. ;/* EXTERNAL REFERENCES:  NONE                                         */
  2528. ;/*    ROUTINES:                                                       */
  2529. ;/*                                                                    */
  2530. ;/*********************** END OF SPECIFICATIONS ************************/
  2531. Procedure prtdeterminehardware near
  2532.         ASSUME  CS:CSEG,DS:DSEG,ES:NOTHING,SS:NOTHING
  2533.  
  2534.         test    bustype,EISABUS                         ; IF !EISA MACHINE
  2535.         jz      prtdethard1                             ; THEN CONTINUE SETUP
  2536.         cmp     [di].deviceaddr,0                       ; PORT EXIST?
  2537.         je      prtdethard5                             ; NO, EXIT
  2538.         or      [di].commonflags1,PORTEXISTS            ; SAVE PORT INSTALLED
  2539.         jmp     SHORT prtdethard5                       ; PREV SETUP, EISAINIT
  2540.  
  2541.         ; GET ADDRESSIBILITY TO BIOS ROM DATA AREA
  2542.  
  2543. prtdethard1:
  2544.         push    BIOSROMDATA                             ; SEG OF BIOS AREA
  2545.         pop     es                                      ; SEG OF BIOS AREA
  2546.         xor     bx,bx                                   ; OFF OF BIOS AREA
  2547.  
  2548.         sub     ah,ah                                   ; CLEAR AH
  2549.         mov     al,[di].deviceindex                     ; GET ZERO BASED INDEX
  2550.         mov     si,ax                                   ; PORT ADDRESS OFFSET
  2551.         sal     si,1                                    ; WORD ALIGN
  2552.         mov     ax,BIOSDATA.printer_adapt[si]           ; GET PORT ADDRESS
  2553.         mov     [di].deviceaddr,ax                      ; SAVE PORT ADDRESS
  2554.  
  2555.         or      ax,ax                                   ; IS PORT AVAILABLE?
  2556.         jz      prtdethard5                             ; NO, EXIT
  2557.  
  2558.         inc     numofprts                               ; # OF PRTS INSTALLED
  2559.         or      [di].commonflags1,PORTEXISTS            ; SAVE PORT INSTALLED
  2560.  
  2561.         cmp     ax,PORT278H                             ; IF DEV ADDR != 278H
  2562.         jne     prtdethard2                             ; THEN PROCEED
  2563.  
  2564.         ; SET UP DEVICE INFO FOR IRQ 5 (INT 0DH) PROCESSING
  2565.  
  2566.         mov     [di].introutine,OFFSET prtint05         ; OFFSET INT HANDLER
  2567.         mov     [di].intlevel,LEVEL5                    ; INTERRUPT LEVEL = 5
  2568.  
  2569.         xor     ah,ah                                   ; CLEAR AH
  2570.         mov     al,[di].deviceindex                     ; GET DEVICE INDEX
  2571.         mov     irq5index,ax                            ; INDEX OF IRQ5 DEV
  2572.         jmp     SHORT prtdethard5                       ; EXIT
  2573.  
  2574.         ; SET UP DEVICE INFO FOR IRQ 7 (INT 0FH) PROCESSING
  2575.  
  2576. prtdethard2:
  2577.         mov     [di].introutine,OFFSET prtint07         ; OFFSET INT HANDLER
  2578.         mov     [di].intlevel,LEVEL7                    ; INTERRUPT LEVEL = 7
  2579.         jmp     SHORT prtdethard5                       ; EXIT
  2580.  
  2581.         ; SET ERROR INDICATION
  2582. prtdethard4:
  2583.         stc                                             ; SET ERROR INDICATION
  2584.         jmp     SHORT prtdethard6                       ; EXIT
  2585.  
  2586.         ; SET SUCCESS INDICATION
  2587. prtdethard5:
  2588.         clc                                             ; SET SUCCESS INDICATION
  2589.  
  2590.         ; EXIT
  2591. prtdethard6:
  2592.         ret
  2593. EndProc prtdeterminehardware
  2594.  
  2595. BREAK <REGISTER RESOURCES ROUTINE>
  2596. ;/********************** START OF SPECIFICATIONS ***********************/
  2597. ;/*                                                                    */
  2598. ;/* SUBROUTINE NAME:  REGISTER RESOURCES WITH RESOURCE MANAGER ROUTINE */
  2599. ;/*                                                                    */
  2600. ;/* DESCRIPTIVE NAME:  Call resource manager with resources needed.    */
  2601. ;/*                                                                    */
  2602. ;/* FUNCTION:   This routine calls the resource manager with the       */
  2603. ;/*             resources required by the parallel port device driver. */
  2604. ;/*                                                                    */
  2605. ;/* NOTES: We currently cannot determine the DMA channel from ABIOS    */
  2606. ;/*        so we do not report it.  We must allocate the resources     */
  2607. ;/*        before we register the adapter.                             */
  2608. ;/*                                                                    */
  2609. ;/* ENTRY POINT:                                                       */
  2610. ;/*         LINKAGE:  RM_PRT_RegisterResources:NEAR                    */
  2611. ;/*                   call RM_PRT_RegisterResources                    */
  2612. ;/*                                                                    */
  2613. ;/* INPUT:  DS = Data segment                                          */
  2614. ;/*         DI = Offset to appropriate perprtdata area                 */
  2615. ;/*         [di].deviceaddr = base port address                        */
  2616. ;/*         [di].intlevel = hardware interrupt level                   */
  2617. ;/*         [di].deviceindex = adapter number (zero based)             */
  2618. ;/*         bustype = bus architecture (ISA, EISA, MC)                 */
  2619. ;/*                                                                    */
  2620. ;/* EXIT-NORMAL: NC                                                    */
  2621. ;/*                                                                    */
  2622. ;/* EXIT-ERROR:  CY                                                    */
  2623. ;/*                                                                    */
  2624. ;/* EFFECTS:                                                           */
  2625. ;/*                                                                    */
  2626. ;/* INTERNAL REFERENCES:  _RM_PRT_AllocPorts                           */
  2627. ;/*    ROUTINES:          _RM_PRT_AllocIRQ                             */
  2628. ;/*                       _RM_PRT_CreateAdapter                        */
  2629. ;/*                       _RM_PRT_DeallocPorts                         */
  2630. ;/*                       _RM_PRT_DeallocIRQ                           */
  2631. ;/*                                                                    */
  2632. ;/* EXTERNAL REFERENCES:  NONE                                         */
  2633. ;/*    ROUTINES:                                                       */
  2634. ;/*                                                                    */
  2635. ;/*********************** END OF SPECIFICATIONS ************************/
  2636. Procedure RM_PRT_RegisterResources near
  2637.         ASSUME  CS:CSEG,DS:DSEG,ES:NOTHING,SS:NOTHING
  2638.         pusha
  2639.         push    es
  2640.  
  2641.         ; OBTAIN CONFLICT-FREE PORT RESOURCES FROM RESOURCE MANAGER
  2642.  
  2643.         push    di                                      ; SAVE PERPRTDATA AREA
  2644.         push    [di].deviceaddr                         ; BASE PORT
  2645.         call    _RM_PRT_AllocPorts                      ; CLAIM PORTS
  2646.         add     sp,2                                    ; CLEAN UP STACK
  2647.         pop     di                                      ; RESTORE PERPRTDATA
  2648.         or      ax,ax                                   ; IF ERROR
  2649.         jnz     RM_PRT_Reg3                             ; EXIT
  2650.  
  2651.         ; OBTAIN CONFLICT-FREE IRQ RESOURCES FROM RESOURCE MANAGER
  2652.  
  2653.         test    [di].commonflags,USEPOLLING             ; IF USE POLLING
  2654.         jnz     RM_PRT_Reg0                             ; DON'T ALLOC IRQ
  2655.         push    di                                      ; SAVE PERPRTDATA AREA
  2656.         sub     ah,ah                                   ; CLEAR AH
  2657.         mov     al,[di].intlevel                        ; GET INTERRUPT LEVEL
  2658.         push    ax                                      ; INTERRUPT LEVEL
  2659.         push    bustype                                 ; BUS TYPE
  2660.         call    _RM_PRT_AllocIRQ                        ; CLAIM IRQ
  2661.         add     sp,4                                    ; CLEAN UP STACK
  2662.         pop     di                                      ; RESTORE PERPRTDATA
  2663.         or      ax,ax                                   ; IF ERROR
  2664.         jnz     RM_PRT_Reg2                             ; EXIT
  2665.  
  2666.         ; REGISTER ADAPTER AND RESOURCES WITH RESOURCE MANAGER
  2667.  
  2668. RM_PRT_Reg0:
  2669.         push    di                                      ; SAVE PERPRTDATA AREA
  2670.         sub     ah,ah                                   ; CLEAR AH
  2671.         mov     al,[di].deviceindex                     ; GET ADAPTER NUMBER
  2672.         push    ax                                      ; ADAPTER NUMBER
  2673.         push    bustype                                 ; BUS TYPE
  2674.         call    _RM_PRT_CreateAdapter                   ; REGISTER ADAPTER
  2675.         add     sp,4                                    ; CLEAN UP STACK
  2676.         pop     di                                      ; RESTORE PERPRTDATA
  2677.         or      ax,ax                                   ; IF NO ERROR
  2678.         jz      RM_PRT_Reg4                             ; EXIT
  2679.  
  2680.         ; IRQ ALLOCATED, DEALLOCATE IRQ
  2681. RM_PRT_Reg1:
  2682.         call    _RM_PRT_DeallocIRQ                      ; DEALLOC IRQ RESOURCE
  2683.  
  2684.         ; PORTS ALLOCATED, DEALLOCATE PORTS
  2685. RM_PRT_Reg2:
  2686.         call    _RM_PRT_DeallocPorts                    ; DEALLOC PORT RESOURCE
  2687.  
  2688.         ; SET ERROR INDICATION
  2689. RM_PRT_Reg3:
  2690.         stc                                             ; SET ERROR INDICATION
  2691.         jmp     SHORT RM_PRT_Reg5                       ; EXIT
  2692.  
  2693.         ; SET SUCCESS INDICATION
  2694. RM_PRT_Reg4:
  2695.         clc                                             ; SET SUCCESS INDICATION
  2696.  
  2697.         ; EXIT
  2698. RM_PRT_Reg5:
  2699.         pop     es
  2700.         popa                                            ; RESTORE REGISTERS
  2701.         ret
  2702. EndProc RM_PRT_RegisterResources
  2703.  
  2704. BREAK <PARSE COMMAND LINE ARGS>
  2705. ;/********************** START OF SPECIFICATIONS ***********************/
  2706. ;/*                                                                    */
  2707. ;/* SUBROUTINE NAME: ParseCmdLine                                      */
  2708. ;/*                                                                    */
  2709. ;/* DESCRIPTIVE NAME: PARSE COMMAND LINE ARGS                          */
  2710. ;/*                                                                    */
  2711. ;/* FUNCTION: THE PURPOSE OF THIS SUBROUTINE IS TO EXAMINE COMMAND     */
  2712. ;/*           LINE ARGS AND PERFORM APPROPRIATE ACTIONS.               */
  2713. ;/*                                                                    */
  2714. ;/* NOTES:  FOR COMPATIBILITY WITH PREVIOUS VERSIONS OF PRINT0?.SYS    */
  2715. ;/*         THE COMMAND LINE ARGS BEGIN IN THE ReqPacket:InitParms     */
  2716. ;/*         BUFFER OFFSET BY THE 3 WORDS THAT CONTAIN THE BUFSIZE      */
  2717. ;/*         VALUES (See prtinit.asm & prtinit.inc)                     */
  2718. ;/*                                                                    */
  2719. ;/*         CURRENTLY, THE CHECK FOR '/IRQ' IS VERY HARD CODED IN      */
  2720. ;/*         THIS ROUTINE SINCE WITH THE ONE ARG WE DONT WANT TO        */
  2721. ;/*         BLOAT PRINT0?.SYS WITH SOPHISTICATED PARSING CODE.         */
  2722. ;/*                                                                    */
  2723. ;/* COMMAND LINE ARGS SUPPORTED:                                       */
  2724. ;/*                                                                    */
  2725. ;/* None - directs the driver to use POLLING for printing rather than  */
  2726. ;/*        IRQs.                                                       */
  2727. ;/*                                                                    */
  2728. ;/* /IRQ - (Case insensitive) directs the driver to use IRQs for       */
  2729. ;/*        printing rather than polling.                               */
  2730. ;/*                                                                    */
  2731. ;/* ENTRY POINT: PARSECMDLINE                                          */
  2732. ;/*    LINKAGE : CALL NEAR                                             */
  2733. ;/*                                                                    */
  2734. ;/* INPUT: DI = OFFSET TO APPROPRIATE PERPRTDATA AREA                  */
  2735. ;/*        ES:BX = PTR TO KERNEL REQUEST PACKET                        */
  2736. ;/*                                                                    */
  2737. ;/* REGSITERS USED:  All registers preserved                           */
  2738. ;/*                                                                    */
  2739. ;/* EXIT-NORMAL:  [di].commonflags USEPOLLING BIT SET APPROPRIATELY    */
  2740. ;/*                                                                    */
  2741. ;/* EXIT-ERROR :  NO ERROR STATUS RETURNED                             */
  2742. ;/*                                                                    */
  2743. ;/* INTERNAL REFERENCES:  NONE                                         */
  2744. ;/*    ROUTINES:                                                       */
  2745. ;/*                                                                    */
  2746. ;/* EXTERNAL REFERENCES:  NONE                                         */
  2747. ;/*    ROUTINES:                                                       */
  2748. ;/*                                                                    */
  2749. ;/*********************** END OF SPECIFICATIONS ************************/
  2750. Procedure ParseCmdLine near
  2751.         ASSUME  CS:CSEG,DS:DSEG,ES:NOTHING,SS:NOTHING
  2752.  
  2753.         pusha                                           ; SAVE REGISTERS
  2754.         push    es                                      ; SAVE ES
  2755.  
  2756.         or      [di].commonflags, USEPOLLING            ; ASSUME POLLING
  2757.  
  2758.         mov     si, di                                  ; SAVE DI in SI
  2759.  
  2760.         cld                                             ; CLEAR DIRECTION FLAG
  2761.         les     bx, es:[bx].InitParms                   ; GET CONFIG.SYS PARMS
  2762.         lea     di, es:[bx].CmdLineParms                ; OFFSET PAST BUF SIZES
  2763.                                                         ; (SEE PRT_Parm_List
  2764.                                                         ; STRUC IN PRTINIT.INC)
  2765.  
  2766.         ;/***********************************************/
  2767.         ;/*                                             */
  2768.         ;/* ES:DI NOW POINTING AT COMMAND LINE ARGS,    */
  2769.         ;/*                                             */
  2770.         ;/* DO A VERY BRUTE FORCE SEARCH FOR "/IRQ"     */
  2771.         ;/* (CASE INSENSITIVE). FIRST, FIND THE "/".    */
  2772.         ;/*                                             */
  2773.         ;/***********************************************/
  2774.  
  2775.         mov     al, '/'                                 ; FIND FORWARD SLASH
  2776.         mov     cx, CMDLINE_ARGSIZE                     ; PRTINIT.INC EQU
  2777.         repne   scasb                                   ; LOOK FOR IT
  2778.         jnz     ParseCmdLine_Exit                       ; JUMP IF DIDNT FIND
  2779.  
  2780.         ;/***********************************************/
  2781.         ;/* FOUND THE '/', NOW ES:DI IS POINTING AT     */
  2782.         ;/* FIRST CHAR PAST THE '/'. LETS CHECK IF THE  */
  2783.         ;/* NEXT 3 CHARS ARE "IRQ" (CASE-INSENSITIVE)   */
  2784.         ;/***********************************************/
  2785.  
  2786.         ; CHECK FOR I or i
  2787.  
  2788.         cmp     byte ptr es:[di], 'I'                   ; IS IT 'I'?
  2789.         je      ParseCmdLine_CheckFor_R                 ; YES, CHECK NEXT CHAR
  2790.  
  2791.         cmp     byte ptr es:[di], 'i'                   ; IS IT 'i'?
  2792.         je      ParseCmdLine_CheckFor_R                 ; YES, CHECK NEXT CHAR
  2793.  
  2794.         jmp     short ParseCmdLine_Exit                 ; NO MATCH
  2795.  
  2796. ParseCmdLine_CheckFor_R:
  2797.  
  2798.         ; CHECK FOR R or r
  2799.  
  2800.         inc     di                                      ; POINT TO NEXT CHAR
  2801.         cmp     byte ptr es:[di], 'R'                   ; IS IT 'R'?
  2802.         je      ParseCmdLine_CheckFor_Q                 ; YES, CHECK NEXT CHAR
  2803.  
  2804.         cmp     byte ptr es:[di], 'r'                   ; IS IT 'r'?
  2805.         je      ParseCmdLine_CheckFor_Q                 ; YES, CHECK NEXT CHAR
  2806.  
  2807.         jmp     short ParseCmdLine_Exit                 ; NO MATCH
  2808.  
  2809. ParseCmdLine_CheckFor_Q:
  2810.  
  2811.         ; CHECK FOR Q or q
  2812.  
  2813.         inc     di                                      ; POINT TO NEXT CHAR
  2814.         cmp     byte ptr es:[di], 'Q'                   ; IS IT 'Q'?
  2815.         je      ParseCmdLine_Match                      ; YES, MATCH
  2816.  
  2817.         cmp     byte ptr es:[di], 'q'                   ; IS IT 'q'?
  2818.         je      ParseCmdLine_Match                      ; YES, MATCH
  2819.  
  2820.         jmp     short ParseCmdLine_Exit                 ; NO MATCH
  2821.  
  2822. ParseCmdLine_Match:
  2823.  
  2824.         ; FOUND "/IRQ" ON COMMAND LINE, DONT USE POLLING
  2825.  
  2826.         mov     di, si                                  ; RESTORE DI
  2827.         and     [di].commonflags, NOT USEPOLLING        ; RESET POLLING FLAG
  2828.  
  2829. ParseCmdLine_Exit:
  2830.  
  2831.         pop     es                                      ; RESTORE ES
  2832.         popa                                            ; RESTORE REGISTERS
  2833.  
  2834.         ret
  2835. EndProc ParseCmdLine
  2836.  
  2837. CSEG    ENDS
  2838.         END
  2839.