home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 11 Util
/
11-Util.zip
/
delayd.zip
/
delay.asm
next >
Wrap
Assembly Source File
|
1993-08-09
|
10KB
|
374 lines
PAGE 64,132
TITLE DELAY - device driver for timed delay on startup
NAME DELAY
.286
;
; Description:
; OS/2 device driver for providing timed delay during startup
; Takes a single mandatory argument: the required delay in
; minutes and/or seconds.If only minutes are supplied,
; they must be followed by a colon. An optional second argument
; is treated as a message and output to the screen.
; Examples:
; DEVICE=C:\DELAY.SYS 2:30
; DEVICE=C:\DELAY.SYS 150
; DEVICE=C:\DELAY.SYS 3: Please wait...network loading
;
; OS/2 versions supported:
; 1.3
; 2.x
;
; Version:
; 1.5
;
; Date:
; 8th August 1993
;
; Author:
; R D Eager
;
; History:
; 1.0 Initial version using DosSleep
; 1.1 Revised version using DevHlp timer calls
; 1.2 Fixed crash if zero delay given
; 1.3 Removed stray STOSB instruction corrupting other code
; (thanks to Carol Anne Ogdin)
; 1.4 Fixed problem parsing certain time values
; 1.5 Fixed problem corrupting memory with times >= 1 minute
;
; Copyright and License:
;
; This Software and its documentation are Copyright, 1993 by the Author:
; Bob Eager
; 5 Bognor Drive
; Herne Bay
; United Kingdom
; CT6 8QP
;
; rde@ukc.ac.uk (USENET)
; 100016,2770 (CompuServe)
;
; License is granted to User to duplicate and disseminate this software
; product, and to use on one computer running OS/2, PROVIDED user agrees to
; 1) hold Author free of any and all liability for any consequences of use
; of the Software, 2) copy this DELAY.DOC file and retain it with any copy
; of DELAY.SYS copied to any medium, and 3) not charge any other person or
; organization for such copies. Use of this product on more than one
; computer in an organization may be separately negotiated by contacting
; the Author, above.
;
.XLIST
INCLUDE DEVHLP.INC
INCLUDE DEVSYM.INC
.LIST
;
; Constants
;
STDOUT EQU 1 ; Standard output handle
;
MAXMES EQU 100 ; Maximum length of user message
MAXSEC EQU 1800 ; Maximum delay in seconds (30 mins)
;
TAB EQU 09H ; Tab character
CR EQU 0DH ; Carriage return
LF EQU 0AH ; Linefeed
;
; External references
;
EXTRN DosWrite:FAR
;
SUBTTL Data areas
PAGE+
;
DGROUP GROUP _DATA
;
_DATA SEGMENT WORD PUBLIC 'DATA'
;
; Device driver header
;
HEADER DD -1 ; Link to next device driver
DW 1000000010000000B ; Device attributes:
; | |||_______________; function level 001
; |_______________________; character device
DW OFFSET STRATEGY ; Strategy entry point
DW 0 ; IDC entry point - not used
DB 'DELAY$$$' ; Device name
DB 8 DUP (0) ; Reserved
;
DevHlp DD ? ; Entry point to DevHlp
COUNT DW ? ; Holds timer count (seconds)
WLEN DW ? ; Receives DosWrite length
MAREA DB (MAXMES+1) DUP (0) ; Optional message area
;
MES1 DB 'DELAY driver - invalid argument'
MES2 DB CR,LF,0
;
DB '*** Copyright (C) R D Eager 1993 ***'
;
_DATA ENDS
;
SUBTTL Main code
PAGE+
;
_TEXT SEGMENT WORD PUBLIC 'CODE'
;
ASSUME CS:_TEXT,DS:DGROUP,ES:NOTHING
;
; Strategy entry point; ES:BX points to the request packet
;
; We support only initialise (of course) and deinstall. Deinstall allows multiple
; calls to load this driver, thus providing multiple delays within CONFIG.SYS.
; If deinstall were not provided, only the first load would succeed.
;
STRATEGY PROC FAR
;
MOV AL,ES:[BX].ReqFunc ; get function code
CMP AL,CMDInit ; initialise function?
JE STRA10 ; j if so
CMP AL,CMDDeInstall ; deinstall function?
JE STRA20 ; j if so
MOV AX,8103H ; error and done status, unknown command
JMP SHORT STRA30 ; use common exit code
;
STRA10: CALL INIT ; do the initialisation
JMP SHORT STRA30 ; common exit
;
STRA20: MOV AX,0100H ; done status - deinstall OK
;
STRA30: MOV ES:[BX].ReqStat,AX ; store status in request packet
RET ; return to system
;
STRATEGY ENDP
;
SUBTTL Initialisation code
PAGE+
;
; Initialisation code. All of this code is present only during initialisation;
; none of the driver data is used after that time either.
;
; ES:BX points to the request packet.
; Status is returned in AX.
;
INIT PROC NEAR
;
; Process the INIT arguments
;
PUSH ES ; save request packet segment for later
PUSH DS ; save data segment for later
;
MOV AX,WORD PTR ES:[BX].InitDevHlp
; offset of DevHlp entry point
MOV WORD PTR DevHlp,AX ; save it
MOV AX,WORD PTR ES:[BX].InitDevHlp+2
; segment of DevHlp entry point
MOV WORD PTR DevHlp+2,AX ; save it
MOV SI,WORD PTR ES:[BX].InitParms
; offset of INIT arguments
MOV DS,WORD PTR ES:[BX].InitParms+2
; segment of INIT arguments
XOR CX,CX ; clear 16 bit delay value (seconds)
CLD ; autoincrement
;
INIT10: LODSB ; skip leading whitespace
CMP AL,' '
JE INIT10
CMP AL,TAB
JE INIT10
DEC SI ; back to first non-space
;
INIT15: LODSB ; skip filename
CMP AL,' '
JE SHORT INIT20 ; found next separator
CMP AL,TAB
JE SHORT INIT20 ; found next separator
CMP AL,0 ; found terminator?
JE SHORT INIT30 ; j if so
JMP INIT15 ; else keep looking
;
INIT20: LODSB ; strip separating whitespace
CMP AL,' '
JE INIT20
CMP AL,TAB
JE INIT20
;
INIT30: DEC SI ; back to first non-space
XOR BP,BP ; initial minutes value
;
; We are now at the start of the argument proper
;
INIT40: LODSB ; get next character
OR AL,AL ; end of argument?
JZ INIT60 ; j if so
CMP AL,':' ; minutes separator?
JNE INIT50 ; j if not
IMUL CX,60 ; convert to seconds
JNO INIT45 ; j if not too big
JMP INIT90 ; else error
;
INIT45: MOV BP,CX ; save minutes for later
XOR CX,CX ; reinitialise for seconds
JMP INIT40
;
INIT50: CMP AL,' ' ; separator?
JE INIT54 ; go to accumulate message
CMP AL,TAB ; separator?
JE INIT54 ; go to accumulate message
CMP AL,'0' ; check for valid digit
JNB INIT51 ; j if valid
JMP INIT90 ; else error
;
INIT51: CMP AL,'9'
JNA INIT52 ; j if in range
JMP INIT90 ; else error
;
INIT52: SUB AL,'0' ; get value
CBW ; make word
IMUL CX,10 ; multiply up...
JO INIT90 ; j if too big
ADD CX,AX ; ...and add in
JO INIT90 ; j if too big
JMP INIT40 ; see if more to do
;
; Combine minutes and seconds for complete time value
;
INIT54: ADD CX,BP ; retrieve minutes part
JO INIT90 ; j if too big
;
; A further separator was found. Use rest of line as a message.
;
INIT55: LODSB ; skip whitespace
CMP AL,' '
JE INIT55
CMP AL,TAB
JE INIT55
DEC SI ; back to first non-space
POP ES ; get data segment
PUSH ES ; save it again
PUSH CX ; save delay value
MOV CX,MAXMES ; maximum length
MOV DI,OFFSET MAREA ; where to put it
;
INIT56: LODSB ; get next message byte
STOSB ; save it
OR AL,AL ; end?
JZ INIT57 ; j if so
LOOP INIT56 ; else keep copying unless full
;
INIT57: POP CX ; recover delay value
;
; End of argument. CX contains the required delay in seconds.
;
INIT60: CMP CX,MAXSEC ; in range?
JA INIT90 ; j if not
POP DS ; recover data segment
POP ES ; recover request packet segment
;
CMP MAREA,0 ; any additional message?
JE INIT65 ; j if not
MOV AX,OFFSET MAREA
CALL DOSOUT ; else display it
MOV AX,OFFSET MES2 ; message tail
CALL DOSOUT ; display it
;
INIT65: OR CX,CX ; zero delay?
JZ INIT69 ; j if so - skip timer
;
; Register timer routine to be called once per second
;
PUSH BX ; save request header pointer
MOV COUNT,CX ; save delay in memory for timer
MOV AX,OFFSET TIMER ; set up for DevHlp call
MOV BX,32 ; ticks per second
MOV DL,DevHlp_TickCount ; required function
CALL DevHlp ; register once-per-second timer
;
; Wait for timer to count down to zero
;
INIT66: MOV AX,COUNT ; get current value
CMP AX,0 ; test it
JG INIT66 ; test > 0 in case goes negative
;
; Deregister timer routine
;
MOV AX,OFFSET TIMER ; set up for DevHlp call
MOV DL,DevHlp_ResetTimer ; required function
CALL DevHlp
POP BX ; recover request header pointer
;
INIT69: MOV WORD PTR ES:[BX].InitEcode,OFFSET _TEXT:INIT
; truncate code segment
MOV WORD PTR ES:[BX].InitEdata,0
; lose data segment
MOV AX,0100H ; done status
RET
;
; Invalid argument detected
;
INIT90: POP DS ; recover data segment
POP ES ; recover request packet segment
MOV AX,OFFSET MES1 ; error message
CALL DOSOUT ; display it
MOV WORD PTR ES:[BX].InitEcode,0
; lose code segment
MOV WORD PTR ES:[BX].InitEdata,0
; lose data segment
MOV AX,810CH ; error/done/general failure
RET
;
INIT ENDP
;
SUBTTL Timer handler
PAGE+
;
; Timer routine; called once per second while awaiting time expiry
;
TIMER PROC FAR
DEC COUNT ; count down by one second
RET
TIMER ENDP
;
SUBTTL Output message
PAGE+
;
; Routine to output a string to the screen.
;
; Inputs:
; AX - offset of zero terminated message
;
; Outputs:
; AX - not preserved
;
DOSOUT PROC NEAR
;
PUSH DI ; save DI
PUSH CX ; save CX
PUSH ES ; save ES
PUSH AX ; save message offset
PUSH DS ; copy DS...
POP ES ; ...to ES
MOV DI,AX ; ES:DI point to message
XOR AL,AL ; set AL=0 for scan value
MOV CX,100 ; just a large value
REPNZ SCASB ; scan for zero byte
POP AX ; recover message offset
POP ES ; recover ES
POP CX ; recover CX
SUB DI,AX ; get size to DI
DEC DI ; adjust
PUSH STDOUT ; standard output handle
PUSH DS ; segment of message
PUSH AX ; offset of message
PUSH DI ; length of message
PUSH DS ; segment for length written
PUSH OFFSET DGROUP:WLEN ; offset for length written
CALL DosWrite ; write message
POP DI ; recover DI
;
RET
;
DOSOUT ENDP
;
_TEXT ENDS
;
END