home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / delayd.zip / delay.asm next >
Assembly Source File  |  1993-08-09  |  10KB  |  374 lines

  1.      PAGE    64,132
  2.     TITLE    DELAY - device driver for timed delay on startup
  3.     NAME    DELAY
  4.     .286
  5. ;
  6. ; Description:
  7. ;    OS/2 device driver for providing timed delay during startup
  8. ;    Takes a single mandatory argument: the required delay in
  9. ;    minutes and/or seconds.If only minutes are supplied,
  10. ;    they must be followed by a colon. An optional second argument
  11. ;    is treated as a message and output to the screen. 
  12. ;    Examples:
  13. ;        DEVICE=C:\DELAY.SYS 2:30
  14. ;        DEVICE=C:\DELAY.SYS 150
  15. ;        DEVICE=C:\DELAY.SYS 3: Please wait...network loading
  16. ;
  17. ; OS/2 versions supported:
  18. ;    1.3
  19. ;    2.x
  20. ;
  21. ; Version:
  22. ;    1.5
  23. ;
  24. ; Date:
  25. ;    8th August 1993
  26. ;
  27. ; Author:
  28. ;    R D Eager
  29. ;
  30. ; History:
  31. ;    1.0    Initial version using DosSleep
  32. ;    1.1    Revised version using DevHlp timer calls
  33. ;    1.2    Fixed crash if zero delay given
  34. ;    1.3    Removed stray STOSB instruction corrupting other code
  35. ;        (thanks to Carol Anne Ogdin)
  36. ;    1.4    Fixed problem parsing certain time values
  37. ;    1.5    Fixed problem corrupting memory with times >= 1 minute
  38. ;
  39. ; Copyright and License:
  40. ;
  41. ; This Software and its documentation are Copyright, 1993 by the Author:
  42. ;            Bob Eager
  43. ;            5 Bognor Drive
  44. ;            Herne Bay
  45. ;            United Kingdom
  46. ;            CT6 8QP
  47. ;
  48. ;            rde@ukc.ac.uk    (USENET)
  49. ;            100016,2770      (CompuServe)
  50. ;
  51. ; License is granted to User to duplicate and disseminate this software
  52. ; product, and to use on one computer running OS/2, PROVIDED user agrees to
  53. ; 1) hold Author free of any and all liability for any consequences of use
  54. ; of the Software, 2) copy this DELAY.DOC file and retain it with any copy
  55. ; of DELAY.SYS copied to any medium, and 3) not charge any other person or
  56. ; organization for such copies.  Use of this product on more than one
  57. ; computer in an organization may be separately negotiated by contacting
  58. ; the Author, above.
  59. ;
  60.     .XLIST
  61.     INCLUDE    DEVHLP.INC
  62.     INCLUDE    DEVSYM.INC
  63.     .LIST
  64. ;
  65. ; Constants
  66. ;
  67. STDOUT        EQU    1        ; Standard output handle
  68. ;
  69. MAXMES        EQU    100        ; Maximum length of user message
  70. MAXSEC        EQU    1800        ; Maximum delay in seconds (30 mins)
  71. ;
  72. TAB        EQU    09H        ; Tab character
  73. CR        EQU    0DH        ; Carriage return
  74. LF        EQU    0AH        ; Linefeed
  75. ;
  76. ; External references
  77. ;
  78.     EXTRN    DosWrite:FAR
  79. ;
  80.     SUBTTL    Data areas
  81.     PAGE+
  82. ;
  83. DGROUP    GROUP    _DATA
  84. ;
  85. _DATA    SEGMENT    WORD PUBLIC 'DATA'
  86. ;
  87. ; Device driver header
  88. ;
  89. HEADER    DD    -1            ; Link to next device driver
  90.     DW    1000000010000000B    ; Device attributes:
  91. ;        |     |||_______________;  function level 001
  92. ;        |_______________________;  character device
  93.     DW    OFFSET STRATEGY        ; Strategy entry point
  94.     DW    0            ; IDC entry point - not used
  95.     DB    'DELAY$$$'        ; Device name
  96.     DB    8 DUP (0)        ; Reserved
  97. ;
  98. DevHlp    DD    ?            ; Entry point to DevHlp
  99. COUNT    DW    ?            ; Holds timer count (seconds)
  100. WLEN    DW    ?            ; Receives DosWrite length
  101. MAREA    DB    (MAXMES+1) DUP (0)    ; Optional message area
  102. ;
  103. MES1    DB    'DELAY driver - invalid argument'
  104. MES2    DB    CR,LF,0
  105. ;
  106.     DB    '*** Copyright (C) R D Eager  1993 ***'
  107. ;
  108. _DATA    ENDS
  109. ;
  110.     SUBTTL    Main code
  111.     PAGE+
  112. ;
  113. _TEXT    SEGMENT    WORD PUBLIC 'CODE'
  114. ;
  115.     ASSUME    CS:_TEXT,DS:DGROUP,ES:NOTHING
  116. ;
  117. ; Strategy entry point; ES:BX points to the request packet
  118. ;
  119. ; We support only initialise (of course) and deinstall. Deinstall allows multiple
  120. ; calls to load this driver, thus providing multiple delays within CONFIG.SYS.
  121. ; If deinstall were not provided, only the first load would succeed.
  122. ;
  123. STRATEGY    PROC    FAR
  124. ;
  125.     MOV    AL,ES:[BX].ReqFunc    ; get function code
  126.     CMP    AL,CMDInit        ; initialise function?
  127.     JE    STRA10            ; j if so
  128.     CMP    AL,CMDDeInstall        ; deinstall function?
  129.     JE    STRA20            ; j if so
  130.     MOV    AX,8103H        ; error and done status, unknown command
  131.     JMP    SHORT STRA30        ; use common exit code
  132. ;
  133. STRA10:    CALL    INIT            ; do the initialisation
  134.     JMP    SHORT STRA30        ; common exit
  135. ;
  136. STRA20:    MOV    AX,0100H        ; done status - deinstall OK
  137. ;
  138. STRA30:    MOV    ES:[BX].ReqStat,AX    ; store status in request packet
  139.     RET                ; return to system
  140. ;
  141. STRATEGY    ENDP
  142. ;
  143.     SUBTTL    Initialisation code
  144.     PAGE+
  145. ;
  146. ; Initialisation code. All of this code is present only during initialisation;
  147. ; none of the driver data is used after that time either.
  148. ;
  149. ; ES:BX points to the request packet.
  150. ; Status is returned in AX.
  151. ;
  152. INIT    PROC    NEAR
  153. ;
  154. ; Process the INIT arguments
  155. ;
  156.     PUSH    ES            ; save request packet segment for later
  157.     PUSH    DS            ; save data segment for later
  158. ;
  159.     MOV    AX,WORD PTR ES:[BX].InitDevHlp
  160.                     ; offset of DevHlp entry point
  161.     MOV    WORD PTR DevHlp,AX    ; save it
  162.     MOV    AX,WORD PTR ES:[BX].InitDevHlp+2
  163.                     ; segment of DevHlp entry point
  164.     MOV    WORD PTR DevHlp+2,AX    ; save it
  165.     MOV    SI,WORD PTR ES:[BX].InitParms
  166.                     ; offset of INIT arguments
  167.     MOV    DS,WORD PTR ES:[BX].InitParms+2
  168.                     ; segment of INIT arguments
  169.     XOR    CX,CX            ; clear 16 bit delay value (seconds)
  170.     CLD                ; autoincrement
  171. ;
  172. INIT10:    LODSB                ; skip leading whitespace
  173.     CMP    AL,' '
  174.     JE    INIT10
  175.     CMP    AL,TAB
  176.     JE    INIT10
  177.     DEC    SI            ; back to first non-space
  178. ;
  179. INIT15:    LODSB                ; skip filename
  180.     CMP    AL,' '
  181.     JE    SHORT INIT20        ; found next separator
  182.     CMP    AL,TAB
  183.     JE    SHORT INIT20        ; found next separator
  184.     CMP    AL,0            ; found terminator?
  185.     JE    SHORT INIT30        ; j if so
  186.     JMP    INIT15            ; else keep looking
  187. ;
  188. INIT20:    LODSB                ; strip separating whitespace
  189.     CMP    AL,' '
  190.     JE    INIT20
  191.     CMP    AL,TAB
  192.     JE    INIT20
  193. ;
  194. INIT30:    DEC    SI            ; back to first non-space
  195.     XOR    BP,BP            ; initial minutes value
  196. ;
  197. ; We are now at the start of the argument proper
  198. ;
  199. INIT40:    LODSB                ; get next character
  200.     OR    AL,AL            ; end of argument?
  201.     JZ    INIT60            ; j if so
  202.     CMP    AL,':'            ; minutes separator?
  203.     JNE    INIT50            ; j if not
  204.     IMUL    CX,60            ; convert to seconds    
  205.     JNO    INIT45            ; j if not too big
  206.     JMP    INIT90            ; else error
  207. ;
  208. INIT45:    MOV    BP,CX            ; save minutes for later
  209.     XOR    CX,CX            ; reinitialise for seconds
  210.     JMP    INIT40
  211. ;
  212. INIT50:    CMP    AL,' '            ; separator?
  213.     JE    INIT54            ; go to accumulate message
  214.     CMP    AL,TAB            ; separator?
  215.     JE    INIT54            ; go to accumulate message
  216.     CMP    AL,'0'            ; check for valid digit
  217.     JNB    INIT51            ; j if valid
  218.     JMP    INIT90            ; else error
  219. ;
  220. INIT51:    CMP    AL,'9'
  221.     JNA    INIT52            ; j if in range
  222.     JMP    INIT90            ; else error
  223. ;
  224. INIT52:    SUB    AL,'0'            ; get value
  225.     CBW                ; make word
  226.     IMUL    CX,10            ; multiply up...
  227.     JO    INIT90            ; j if too big
  228.     ADD    CX,AX            ; ...and add in
  229.     JO    INIT90            ; j if too big
  230.     JMP    INIT40            ; see if more to do
  231. ;
  232. ; Combine minutes and seconds for complete time value
  233. ;
  234. INIT54:    ADD    CX,BP            ; retrieve minutes part
  235.     JO    INIT90            ; j if too big
  236. ;
  237. ; A further separator was found. Use rest of line as a message.
  238. ;
  239. INIT55:    LODSB                ; skip whitespace
  240.     CMP    AL,' '
  241.     JE    INIT55
  242.     CMP    AL,TAB
  243.     JE    INIT55
  244.     DEC    SI            ; back to first non-space
  245.     POP    ES            ; get data segment
  246.     PUSH    ES            ; save it again
  247.     PUSH    CX            ; save delay value
  248.     MOV    CX,MAXMES        ; maximum length
  249.     MOV    DI,OFFSET MAREA        ; where to put it
  250. ;
  251. INIT56:    LODSB                ; get next message byte
  252.     STOSB                ; save it
  253.     OR    AL,AL            ; end?
  254.     JZ    INIT57            ; j if so
  255.     LOOP    INIT56            ; else keep copying unless full
  256. ;
  257. INIT57:    POP    CX            ; recover delay value
  258. ;
  259. ; End of argument. CX contains the required delay in seconds.
  260. ;
  261. INIT60:    CMP    CX,MAXSEC        ; in range?
  262.     JA    INIT90            ; j if not
  263.     POP    DS            ; recover data segment
  264.     POP    ES            ; recover request packet segment
  265. ;
  266.     CMP    MAREA,0            ; any additional message?
  267.     JE    INIT65            ; j if not
  268.     MOV    AX,OFFSET MAREA
  269.     CALL    DOSOUT            ; else display it
  270.     MOV    AX,OFFSET MES2        ; message tail
  271.     CALL    DOSOUT            ; display it
  272. ;
  273. INIT65:    OR    CX,CX            ; zero delay?
  274.     JZ    INIT69            ; j if so - skip timer
  275. ;
  276. ; Register timer routine to be called once per second
  277. ;
  278.     PUSH    BX            ; save request header pointer
  279.     MOV    COUNT,CX        ; save delay in memory for timer
  280.     MOV    AX,OFFSET TIMER        ; set up for DevHlp call
  281.     MOV    BX,32            ; ticks per second
  282.     MOV    DL,DevHlp_TickCount    ; required function
  283.     CALL    DevHlp            ; register once-per-second timer
  284. ;
  285. ; Wait for timer to count down to zero
  286. ;
  287. INIT66:    MOV    AX,COUNT        ; get current value
  288.     CMP    AX,0            ; test it
  289.     JG    INIT66            ; test > 0 in case goes negative
  290. ;
  291. ; Deregister timer routine
  292. ;
  293.     MOV    AX,OFFSET TIMER        ; set up for DevHlp call
  294.     MOV    DL,DevHlp_ResetTimer    ; required function
  295.     CALL    DevHlp
  296.     POP    BX            ; recover request header pointer
  297. ;
  298. INIT69:    MOV    WORD PTR ES:[BX].InitEcode,OFFSET _TEXT:INIT
  299.                     ; truncate code segment
  300.     MOV    WORD PTR ES:[BX].InitEdata,0
  301.                     ; lose data segment
  302.     MOV    AX,0100H        ; done status
  303.     RET
  304. ;
  305. ; Invalid argument detected
  306. ;
  307. INIT90:    POP    DS            ; recover data segment
  308.     POP    ES            ; recover request packet segment
  309.     MOV    AX,OFFSET MES1        ; error message
  310.     CALL    DOSOUT            ; display it
  311.     MOV    WORD PTR ES:[BX].InitEcode,0
  312.                     ; lose code segment
  313.     MOV    WORD PTR ES:[BX].InitEdata,0
  314.                     ; lose data segment
  315.     MOV    AX,810CH        ; error/done/general failure
  316.     RET
  317. ;
  318. INIT    ENDP
  319. ;
  320.     SUBTTL    Timer handler
  321.     PAGE+
  322. ;
  323. ; Timer routine; called once per second while awaiting time expiry
  324. ;
  325. TIMER    PROC    FAR
  326.     DEC    COUNT            ; count down by one second
  327.     RET
  328. TIMER    ENDP
  329. ;
  330.     SUBTTL    Output message
  331.     PAGE+
  332. ;
  333. ; Routine to output a string to the screen.
  334. ;
  335. ; Inputs:
  336. ;    AX    - offset of zero terminated message
  337. ;
  338. ; Outputs:
  339. ;    AX    - not preserved
  340. ;
  341. DOSOUT    PROC    NEAR
  342. ;
  343.     PUSH    DI            ; save DI
  344.     PUSH    CX            ; save CX
  345.     PUSH    ES            ; save ES
  346.     PUSH    AX            ; save message offset
  347.     PUSH    DS            ; copy DS...
  348.     POP    ES            ; ...to ES
  349.     MOV    DI,AX            ; ES:DI point to message
  350.     XOR    AL,AL            ; set AL=0 for scan value
  351.     MOV    CX,100            ; just a large value
  352.     REPNZ    SCASB            ; scan for zero byte
  353.     POP    AX            ; recover message offset
  354.     POP    ES            ; recover ES
  355.     POP    CX            ; recover CX
  356.     SUB    DI,AX            ; get size to DI
  357.     DEC    DI            ; adjust
  358.     PUSH    STDOUT            ; standard output handle
  359.     PUSH    DS            ; segment of message
  360.     PUSH    AX            ; offset of message
  361.     PUSH    DI            ; length of message
  362.     PUSH    DS            ; segment for length written
  363.     PUSH    OFFSET DGROUP:WLEN    ; offset for length written
  364.     CALL    DosWrite        ; write message
  365.     POP    DI            ; recover DI
  366. ;
  367.     RET
  368. ;
  369. DOSOUT    ENDP
  370. ;
  371. _TEXT    ENDS
  372. ;
  373.     END
  374.