home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ddkx86v5.zip / DDKX86 / SRC / DEV / PRINTER / PRTCOMMN.ASM < prev    next >
Assembly Source File  |  1995-04-14  |  26KB  |  483 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. ; SCCSID = @(#)prtcommn.asm     6.21 92/03/24
  13. ;/**********************************************************************
  14. ;/*                                                                    *
  15. ;/*                                                                    *
  16. ;/*                                                                    *
  17. ;/**********************************************************************
  18.  TITLE PRINTDD - PRINTER DEVICE DRIVER COMMON ROUTINES
  19.  NAME PRINTDD
  20. PAGE ,132
  21. .286C
  22.  
  23. ;***********************************************************************
  24. ; CODING CONVENTIONS
  25. ; all psuedo-ops, equates, documentation, publics, and externs are in uppercase.
  26. ; all code and data names are in lowercase.
  27. ;
  28. ; ROUTINES IN THIS MODULE:
  29. ;       PRT_POLLING
  30. ;       PRT_TIMEOUT_POLLING
  31. ;***********************************************************************
  32.  
  33.         .XCREF
  34.         .XLIST
  35.         INCLUDE basemaca.inc            ; VARIOUS MACRO'S (BREAK, LJC, ETC.)
  36.         INCLUDE osmaca.inc
  37.         INCLUDE devsym.inc
  38.         INCLUDE devhlp.inc              ; DEFINITION OF DEVICE HELP CALLS.
  39.         INCLUDE infoseg.inc             ; STRUCTURES DEFINING THE INFOSEG
  40.         INCLUDE iodelay.inc             ; IODELAY MACROS
  41.         INCLUDE proc.inc                ; INFOSEG EQUATES
  42.         .LIST
  43.         .CREF
  44.         INCLUDE prtdd.inc               ; PRINTER DEVICE DRIVER INCLUDE FILE
  45.  
  46. BREAK <DATA FOR THE PRINTER DEVICE DRIVER>
  47. ;/********************** START OF SPECIFICATIONS ***********************/
  48. ;/*                                                                    */
  49. ;/* SUBROUTINE NAME: PRTDATA                                           */
  50. ;/*                                                                    */
  51. ;/* DESCRIPTIVE NAME: PRINTER DEVICE DRIVER DATA DECLARATIONS          */
  52. ;/*                                                                    */
  53. ;/*********************** END OF SPECIFICATIONS ************************/
  54. DSEG    SEGMENT public  'data'
  55.  
  56.         EXTRN   doserrors:WORD
  57.         EXTRN   device_help:DWORD
  58.         EXTRN   perprtarea:BYTE
  59.         EXTRN   timeoutval:WORD
  60.  
  61. DSEG    ENDS
  62.  
  63.         EXTRNFAR prtreqdirect
  64.         EXTRNFAR prtreldirect
  65.  
  66. CSEG    SEGMENT public  'code'
  67.         ASSUME  CS:CSEG,DS:DSEG,ES:NOTHING,SS:NOTHING
  68.  
  69.         EXTRN    prterp:NEAR
  70.  
  71. BREAK <PRINT A BLOCK OF CHARACTERS USING POLLING>
  72. ;/********************** START OF SPECIFICATIONS ***********************/
  73. ;/*                                                                    */
  74. ;/* SUBROUTINE NAME:  PRT_POLLING                                      */
  75. ;/*                                                                    */
  76. ;/* DESCRIPTIVE NAME:  Print a block of characters using polling       */
  77. ;/*                                                                    */
  78. ;/* FUNCTION:   This routine uses polling to print a block of          */
  79. ;/*             characters in an attempt to provide maximum throughput */
  80. ;/*             in a quiescent system. A polling scheme is employed    */
  81. ;/*             over interrupts because printer interrupts can occur   */
  82. ;/*             at such a high rate the overhead in setting up the     */
  83. ;/*             interrupt context for each character becomes           */
  84. ;/*             significant. Also, other lower-priority interrupts     */
  85. ;/*             like the mouse and keyboard get "starved", resulting   */
  86. ;/*             in a slooooowwww user interface during printing.       */
  87. ;/*                                                                    */
  88. ;/*             Our polling loop would also cause problems since       */
  89. ;/*             (as a device driver task thread) it cant be preempted, */
  90. ;/*             but we will use the Yield flag to implement            */
  91. ;/*             a sort of demand-driven multi-tasking, as follows:     */
  92. ;/*                                                                    */
  93. ;/*             The Yield flag is checked after each attempt to output */
  94. ;/*             a char and if set a Yield will be performed so that    */
  95. ;/*             other threads in the system get a chance to run.       */
  96. ;/*             This should (hopefully) prevent the system from        */
  97. ;/*             emulating a slug during printing.                      */
  98. ;/*                                                                    */
  99. ;/*             A very general C "psuedo-code" depiction               */
  100. ;/*             of the algoriothm is as follows:                       */
  101. ;/*                                                                    */
  102. ;/*             prt_polling()                                          */
  103. ;/*             {                                                      */
  104. ;/*                SetTimeout();                                       */
  105. ;/*                                                                    */
  106. ;/*                port  = perprtdata.deviceaddr;                      */
  107. ;/*                count = ReqBlk.IOCount;                             */
  108. ;/*                ReqBlk.PktStatus = DEVDONE | SUCCESS;               */
  109. ;/*                                                                    */
  110. ;/*                for( i = 0; i < count; i++)                         */
  111. ;/*                {                                                   */
  112. ;/*                    if (PrtNotBusy)                                 */
  113. ;/*                    {                                               */
  114. ;/*                        PrintChar(port);                            */
  115. ;/*                        ResetTimeOut():                             */
  116. ;/*                    }                                               */
  117. ;/*                                                                    */
  118. ;/*                    if (YieldFlagSet)                               */
  119. ;/*                    {                                               */
  120. ;/*                        Yield();                                    */
  121. ;/*                    }                                               */
  122. ;/*                                                                    */
  123. ;/*                    if (DeniedAccess)                               */
  124. ;/*                    {                                               */
  125. ;/*                        PrtRelDirect(reqpkt, perprtdata);           */
  126. ;/*                        PrtReqDirect(reqpkt, perprtdata);           */
  127. ;/*                    }                                               */
  128. ;/*                                                                    */
  129. ;/*                    if (TimeOut)                                    */
  130. ;/*                    {                                               */
  131. ;/*                        ReqBlk.PktStatus = DEVDONE | ERROR;         */
  132. ;/*                        break;                                      */
  133. ;/*                    }                                               */
  134. ;/*                                                                    */
  135. ;/*                    if (CancelFlagSet)                              */
  136. ;/*                    {                                               */
  137. ;/*                        ReqBlk.PktStatus = DEVDONE | ERROR;         */
  138. ;/*                        break;                                      */
  139. ;/*                    }                                               */
  140. ;/*                }                                                   */
  141. ;/*                ReqBlk.IOCount = i;                                 */
  142. ;/*            }                                                       */
  143. ;/*                                                                    */
  144. ;/* NOTES:                                                             */
  145. ;/*                                                                    */
  146. ;/* ENTRY POINT:                                                       */
  147. ;/*         LINKAGE:  prt_polling:near                                 */
  148. ;/*                   call prt_polling                                 */
  149. ;/*                                                                    */
  150. ;/* INPUT:  ES = Virtual segment of Kernel request block               */
  151. ;/*         BX = Virtual offset of Kernel request block                */
  152. ;/*         DS:DI = Offset to appropriate perprtdata area              */
  153. ;/*                                                                    */
  154. ;/* EXIT-NORMAL:  ES:[BX] = Kernel Request Block                       */
  155. ;/*               DS:[DI] = Perprtdata area                            */
  156. ;/*               ES:[BX].Pktstatus = filled in.                       */
  157. ;/*               ES:[BX].IOCount = filled in.                         */
  158. ;/*                                                                    */
  159. ;/* EXIT-ERROR:   See exit normal above.                               */
  160. ;/*                                                                    */
  161. ;/* EFFECTS:                                                           */
  162. ;/*                                                                    */
  163. ;/* INTERNAL REFERENCES:  getstatus                                    */
  164. ;/*    ROUTINES:          prterp                                       */
  165. ;/*                                                                    */
  166. ;/* EXTERNAL REFERENCES:  DEVICE_HELP  PhyToGDTSelector                */
  167. ;/*    ROUTINES:                       TickCount                       */
  168. ;/*                                                                    */
  169. ;/*********************** END OF SPECIFICATIONS ************************/
  170. Procedure prt_polling near
  171.         ASSUME  CS:CSEG,DS:DSEG,ES:NOTHING,SS:NOTHING
  172.  
  173.         SaveReg <es,bx,di>                              ; SAVE REGISTERS
  174.  
  175.         ;/**************************************/
  176.         ;/* GET ADDRESSIBILITY TO USER BUFFER  */
  177.         ;/**************************************/
  178.  
  179.         mov     cx, es:[bx].IOcount                     ; GET USER BUF LENGTH
  180.         mov     ax, WORD PTR es:[bx].IOpData + 2        ; GET PHYS ADDR - HIGH
  181.         mov     bx, WORD PTR es:[bx].IOpData            ; GET PHYS ADDR - LOW
  182.         mov     si, [di].gdtprintbuf                    ; GET GDT SELECTOR
  183.         mov     dl, DevHlp_PhysToGDTSelector            ; CONVERT PHYS TO GDT
  184.         call    DWORD PTR [device_help]                 ; DO ADDRESS CONVERSION
  185.  
  186.         RestoreReg <di,bx,es>                           ; RESTORE REGISTERS
  187.  
  188.         ;/**************************************/
  189.         ;/* START THE TIMEOUT COUNTER          */
  190.         ;/**************************************/
  191.  
  192.         SaveReg <es,bx,di>                              ; SAVE REGISTERS
  193.  
  194.         and     [di].commonflags1, NOT TIMEDOUT         ; SET TIMEOUT FLAG OFF
  195.         mov     [di].timeoutctr, 0                      ; CLEAR TIMEOUT CTR
  196.         mov     ax, [di].timeout_off                    ; TIMEOUT ENTRY POINT
  197.         mov     bx, timeoutval                          ; TIMEOUT IN TICKCOUNTS
  198.         mov     dl, DevHlp_TickCount                    ; CALL TIMER SERVICES
  199.         call    DWORD PTR [device_help]
  200.  
  201.         RestoreReg <di,bx,es>                           ; RESTORE REGISTERS
  202.  
  203.         ;/***************************************/
  204.         ;/* INIT OFFSET INTO PRINT BUFFER       */
  205.         ;/***************************************/
  206.  
  207.         mov     si, 0                                   ; POINT SI TO FIRST CHAR
  208.  
  209.         ;/*********************************************/
  210.         ;/* REGISTERS NOW CONTAIN:                    */
  211.         ;/*                                           */
  212.         ;/* si = offset to block ([di].gdtprintbuf)   */
  213.         ;/* di = perprtarea                           */
  214.         ;/* es:bx = request packet                    */
  215.         ;/*********************************************/
  216.  
  217.  
  218. ;/*******************************************************/
  219. ;/* T O P   O F   P R I N T   L O O P --------->        */
  220. ;/*******************************************************/
  221.  
  222.  
  223. prt_polling_1:
  224.  
  225.         ;/***********************************************/
  226.         ;/* CHECK FOR NOT BUSY AT PARALLEL STATUS PORT. */
  227.         ;/* TRY 20H TIMES TO GIVE PRINTER A CHANCE      */
  228.         ;/* BEFORE CHECKING YIELD & OTHER FLAGS         */
  229.         ;/***********************************************/
  230.  
  231.         mov     cx, BUSYRETRY                           ; LOAD LOOP COONTER
  232.         mov     dx, [di].deviceaddr                     ; GET DEVICE ADDRESS
  233.         inc     dx                                      ; POINT TO STATUS PORT
  234.  
  235. prt_polling_11:
  236.  
  237.         in      al, dx                                  ; GET STATUS BYTE
  238.  
  239.         test    al, NOTBUSY                             ; PRINTER NOTBUSY?
  240.         jnz     prt_polling_12                          ; YES, GO PRINT CHAR -->
  241.  
  242.         loop    prt_polling_11                          ; BUSY, TRY AGAIN ...
  243.  
  244.         jmp     short prt_polling_2                     ; UNLESS TRIED BUSYRETRY
  245.                                                         ; TIMES, GO CHECK FLAGS
  246.  
  247. prt_polling_12:
  248.  
  249.         ;/***********************************************/
  250.         ;/* NOTBUSY, SEND CHAR TO PARALLEL DATA PORT    */
  251.         ;/***********************************************/
  252.  
  253.         ;/***********************************************/
  254.         ;/* FIRST, GET CHAR FROM BUFFER (LODSB INC's SI)*/
  255.         ;/***********************************************/
  256.  
  257.         push    ds                                      ; SAVE OUR DS
  258.         mov     ds, [di].gdtprintbuf                    ; GET SELECTOR
  259.         lodsb                                           ; AL = DS:SI (SI INC'D)
  260.         pop     ds                                      ; RESTORE OUR DS
  261.  
  262.         ; NOTE: DX SHOULD STILL HAVE STATUS PORT VALUE FROM BEING SET ABOVE
  263.  
  264.         dec     dx                                      ; RESET DX TO DATA ADDR
  265.         out     dx, al                                  ; SEND CHAR TO DATA PORT
  266.  
  267.         DevIODelay <cx>                                 ; I/O DELAY - DATA SETUP
  268.  
  269.         ;/***********************************************/
  270.         ;/* STROBE CONTROL PORT TO SEND BYTE TO DEVICE  */
  271.         ;/***********************************************/
  272.  
  273.         ; STROBE HIGH
  274.  
  275.         cli                                             ; DISABLE INTERRUPTS
  276.         mov     al, 0Dh                                 ; SET THE STROBE HIGH
  277.         add     dx, 2                                   ; DX <= CONTROL PORT
  278.         out     dx, al                                  ; STROBE HIGH
  279.  
  280.         DevIODelay <cx>                                 ; I/O DELAY - STR WIDTH
  281.         DevIODelay <cx>  ;RV - 101898 -                 ; I/O DELAY - STR WIDTH
  282.  
  283.         ; GET THE NOTBUSY BIT STATUS IN AH (NOTBUSY SHOULD BE 0)
  284.  
  285.         dec     dx                                      ; DX <= STATUS PORT
  286.         in      al, dx                                  ; READ STATUS
  287.         mov     ah, al                                  ; SAVE STATUS IN AH
  288.  
  289.         DevIODelay <cx>                                 ; I/O DELAY - STR WIDTH
  290.  
  291.         ; STROBE LOW
  292.  
  293.         inc     dx                                      ; DX <= CONTROL PORT
  294.         mov     al, 0Ch                                 ; SET THE STROBE LOW
  295.         out     dx, al                                  ; SEND NEW CONTROL BYTE
  296.         sti                                             ; RE-ENABLE INTS
  297.  
  298.         mov     [di].timeoutctr, 0                      ; CLEAR TIMEOUT CTR
  299.         and     [di].commonflags1, NOT TIMEDOUT         ; SET TIMEOUT FLAG OFF
  300.  
  301. prt_polling_2:
  302.  
  303.         ;/***********************************************/
  304.         ;/* CHECK YIELD & TIMEOUT FLAGS:                */
  305.         ;/***********************************************/
  306.  
  307.         ;/***********************************************************/
  308.         ;/*                                                         */
  309.         ;/* CHECK YIELD FLAG                                        */
  310.         ;/*                                                         */
  311.         ;/* Since we're in a tight polling loop printing a          */
  312.         ;/* block of chars at STRATEGY task time we will employ     */
  313.         ;/* some cooperative multi-tasking.  We do this by checking */
  314.         ;/* the kernel YIELD flag which tells us if any threads of  */
  315.         ;/* equal or greater priority to ours want to run.  If so,  */
  316.         ;/* we graciously use DevHelp_Yield in deference to the     */
  317.         ;/* hungry thread. If other threads aren't too demanding    */
  318.         ;/* we should seldom yield (maximizing print performance).  */
  319.         ;/*                                                         */
  320.         ;/***********************************************************/
  321.  
  322.         SaveReg <es,bx,di,si>                           ; SAVE REGISTERS
  323.  
  324.         mov     al, YIELDFLAG                           ; GET YIELDFLAG ADDR
  325.         mov     dl, DevHlp_GetDOSVar                    ; GET DOS VAR FUNCTION
  326.         call    DWORD PTR [device_help]                 ; CALL DEVHLP
  327.         mov     es,ax                                   ; ES:BX -> YIELD FLAG
  328.         test    BYTE PTR es:[bx], 0FFh                  ; YIELD FLAG SET?
  329.         jz      prt_polling_3                           ; NO, GO CHECK TIMEOUT
  330.  
  331.         ;/*******************************************/
  332.         ;/* YIELD FLAG SET, GIVE IT UP OTHER THREAD */
  333.         ;/*******************************************/
  334.  
  335.         mov     dl, DevHlp_Yield                        ; YIELD FUNCTION
  336.         call    DWORD PTR [device_help]                 ; CALL DEVHLP
  337.         sti                                             ; ENABLE INTS (IN CASE)
  338.  
  339. prt_polling_3:
  340.  
  341.         RestoreReg <si,di,bx,es>                        ; RESTORE REGISTERS
  342.  
  343.         ;/***********************************************************/
  344.         ;/* Sharing the parallel port between each write request    */
  345.         ;/* does not provide sufficient usability when large buffers*/
  346.         ;/* of data are passed. The parallel port device driver must*/
  347.         ;/* release access to the parallel port when other device   */
  348.         ;/* drivers request and are denied access to the hardware.  */
  349.         ;/***********************************************************/
  350.  
  351.         test    [di].commonflags1,DENIEDACCESS          ; DRIVER DENIED ACCESS?
  352.         jz      prt_polling_31                          ; NO
  353.         CALLFAR prtreldirect                            ; YES, RELEASE ACCESS
  354.         CALLFAR prtreqdirect                            ; WAIT THEN REQ ACCESS
  355. prt_polling_31:
  356.  
  357.         ;/***************************************/
  358.         ;/* CHECK FOR TIMEOUT & MONPRT CANCEL   */
  359.         ;/***************************************/
  360.  
  361.         test    [di].commonflags1, TIMEDOUT             ; IS TIMEDOUT FLAG SET?
  362.         jnz     prt_polling_4                           ; YES, TIMEOUT ---->
  363.  
  364.         test    [di].commonflags1,CANMONPKT             ; CANCEL MON PRT REQ?
  365.         jnz     prt_polling_4                           ; YES, LEAVE ---->
  366.  
  367.         ;/***************************************/
  368.         ;/* CHECK FOR LAST CHAR PRINTED         */
  369.         ;/***************************************/
  370.         cmp     si, es:[bx].IOCount                     ; SI >= IOCount
  371.         jae     prt_polling_5                           ; YES, GOOD EXIT --->
  372.  
  373.         jmp     prt_polling_1                           ; NO, GO FOR NEXT CHAR
  374.  
  375. ;/*******************************************************/
  376. ;/* B O T T O M   O F   P R I N T    L O O P ---------> */
  377. ;/*******************************************************/
  378.  
  379. ;/***************************************/
  380. ;/* E X I T   C O D E   F O L L O W S:  */
  381. ;/***************************************/
  382.  
  383. prt_polling_4:
  384.         ;/***********************************************/
  385.         ;/* GET HERE IF TIMED OUT  OR MONITOR CANCELED  */
  386.         ;/***********************************************/
  387.  
  388.         push    si                                      ; SAVE PRINTED COUNT
  389.         call    prterp                                  ; SET ERROR CODE
  390.         pop     si                                      ; RESTORE PRINTED COUNT
  391.         jmp     short prt_polling_6                     ; AND GO CLEANUP/LEAVE
  392.  
  393. prt_polling_5:
  394.         ;/***************************************/
  395.         ;/* ALL CHARS PRINTED, SET GOOD STATUS  */
  396.         ;/***************************************/
  397.  
  398.         mov     [di].cancelflags, CANNOERROR            ; CLEAR CANCEL FLAGS
  399.  
  400. prt_polling_6:
  401.  
  402.         ;/***********************/
  403.         ;/* CLEANUP AND EXIT    */
  404.         ;/***********************/
  405.  
  406.         mov     es:[bx].IOcount, si                     ; PUT COUNT IN REQ PKT
  407.  
  408.         mov     ax,[di].timeout_off                     ; TIMEOUT ENTRY POINT
  409.         mov     dl,DevHlp_ResetTimer                    ; RESET TIMEOUT TIMER
  410.         call    DWORD PTR [device_help]                 ; CALL TIMER SERVICES
  411.  
  412.         xor     ah, ah                                  ; ZERO OUT AH
  413.         mov     al, [di].cancelflags                    ; GET CANCEL FLAGS
  414.         mov     [di].cancelflags, 0                     ; ZERO OUT CANCEL FLAGS
  415.         mov     si, ax                                  ; GET ERROR CODE
  416.         sal     si, 1                                   ; GET WORD INDEX
  417.         mov     ax, doserrors[si]                       ; GET ERROR CODE
  418.         mov     es:[bx].PktStatus, ax                   ; PUT RC IN REQ PKT
  419.  
  420.         ret                                             ; RETURN
  421. EndProc prt_polling
  422.  
  423. BREAK <GENERAL TIMEOUT ROUTINE>
  424. ;/********************** START OF SPECIFICATIONS ***********************/
  425. ;/*                                                                    */
  426. ;/* SUBROUTINE NAME:  PRT_TIMEOUT_POLLING                              */
  427. ;/*                                                                    */
  428. ;/* DESCRIPTIVE NAME:  Timeout Interrupt routine for polling.          */
  429. ;/*                                                                    */
  430. ;/* FUNCTION:  This routine is called 1 time per second by prt_timeout */
  431. ;/*            in either print01 or print02.sys when polling is used.  */
  432. ;/*            The polling timeout processing is common to both        */
  433. ;/*            print01 & print02 hence its inclusion in prtcommm.asm.  */
  434. ;/*                                                                    */
  435. ;/*            For polling timeout processing a special bit is set     */
  436. ;/*            in commonflags1 is set when a timeout is detected.      */
  437. ;/*            The bit is checked for in the body of the prt_polling   */
  438. ;/*            function and if set prt_polling exits.                  */
  439. ;/*                                                                    */
  440. ;/* ENTRY POINT:  prt_timeout_polling                                  */
  441. ;/*    LINKAGE:  CALL NEAR                                             */
  442. ;/*                   call prt_timeout                                 */
  443. ;/*                                                                    */
  444. ;/* INPUT:  DI = offset of device into perprtarea.                     */
  445. ;/*         [DI].timeoutmax = maximum wait time in seconds before      */
  446. ;/*                           canceling the print request.             */
  447. ;/*         [DI].timeoutctr = counter maintained to reach timeoutmax   */
  448. ;/*                                                                    */
  449. ;/* EXIT-NORMAL:  timeoutctr = incremented by 1, If = MAX, reset to 0  */
  450. ;/*               TIMEDOUT flag is set in commonflags1                 */
  451. ;/*                                                                    */
  452. ;/* EXIT-ERROR:  See EXIT-NORMAL above.                                */
  453. ;/*                                                                    */
  454. ;/* INTERNAL REFERENCES:  NONE                                         */
  455. ;/*    ROUTINES:                                                       */
  456. ;/*                                                                    */
  457. ;/* EXTERNAL REFERENCES:  NONE                                         */
  458. ;/*    ROUTINES:                                                       */
  459. ;/*                                                                    */
  460. ;/*********************** END OF SPECIFICATIONS ************************/
  461. Procedure prt_timeout_polling near
  462.         ASSUME  CS:CSEG,DS:DSEG,ES:NOTHING,SS:NOTHING
  463.  
  464.         inc     [di].timeoutctr                         ; INC TIMEOUT COUNTER
  465.         mov     ax, [di].timeoutmax                     ; GET TIMEOUT LIMIT
  466.         cmp     [di].timeoutctr, ax                     ; IF CTR >= LIMIT
  467.         jae     prt_timeout_polling_1                   ; THEN PERFORM TIMEOUT
  468.         jmp     prt_timeout_polling_ret                 ; ELSE EXIT
  469.  
  470. prt_timeout_polling_1:
  471.         mov     [di].timeoutctr, 0                      ; RESET TIMEOUT CTR
  472.         test    [di].commonflags,INFINRETRY             ; IF INFINITE RETRY
  473.         jnz     prt_timeout_polling_ret                 ; THEN WAIT LONGER
  474.  
  475.         or      [di].commonflags1, TIMEDOUT             ; SET TIMEOUT FLAG
  476.  
  477. prt_timeout_polling_ret:
  478.         ret
  479. EndProc prt_timeout_polling
  480.  
  481. CSEG    ENDS
  482.         END
  483.