home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.os.msdos.programmer
- Path: sparky!uunet!cs.utexas.edu!torn!news.ccs.queensu.ca!slip207.telnet1.QueensU.CA!dmurdoch
- From: dmurdoch@mast.queensu.ca (Duncan Murdoch)
- Subject: Re: Causing the compter to stop from the config.sys file
- Message-ID: <dmurdoch.337.727832892@mast.queensu.ca>
- Lines: 172
- Sender: news@knot.ccs.queensu.ca (Netnews control)
- Organization: Queen's University
- References: <1993Jan21.231925.46627@kuhub.cc.ukans.edu> <1993Jan23.173306.1751@borland.com>
- Date: Sat, 23 Jan 1993 23:48:13 GMT
-
- In article <1993Jan23.173306.1751@borland.com> dave@borland.com (Dave) writes:
- >In article <1993Jan21.231925.46627@kuhub.cc.ukans.edu>
- >christos@kuhub.cc.ukans.edu writes:
-
- >> I was wondering if it is possible to cause a pause inside the
- >>config.sys file in a similar way we can do this in the autoexec.bat file.
- >>I would appreciate any relevant resposne....
-
- >Yes. Get DR DOS and you will be all set. The actual line you
- >would add could be as follows:
-
- >?REM
-
- It hardly seems worth getting DR DOS for such a tiny little utility. It
- took about an hour to write one in Turbo Pascal; the source code is below.
-
- I'll be uploading this to garbo.uwasa.fi; look for an announcement on comp.
- archives.msdos.announce (I expect it'll be called pausedev.zip, and should
- end up in /pc/turbopas, since it's more of a demonstration of how to write
- a device driver than a useful utility.)
-
- Compile it to PAUSEDEV.EXE, then put
-
- DEVICE=d:\path\PAUSEDEV.EXE
-
- into your CONFIG.SYS wherever you want a pause.
-
- Duncan Murdoch
- dmurdoch@mast.queensu.ca
-
- --------- PAUSEDEV.PAS -----------
- {$S-,F-} { Stack checking wouldn't work here, and we assume near calls
- }
- {$X+} { Extended syntax }
- {$M $1000,0,0} { We won't use the heap or stack. }
-
- program pausedev;
- { This program implements a PAUSE command either as DEVICE=PAUSEDEV.EXE
- or executed from the command line. }
-
- uses opint, { OPro interrupt services, needed for stack switching }
- crt; { Standard I/O unit that doesn't rely on DOS }
-
- procedure strategy_routine(bp:word); interrupt; forward;
- procedure interrupt_routine(bp:word); interrupt; forward;
- procedure call_Main_Block; forward;
-
- { This procedure must come first!!! }
-
- procedure header;
- assembler;
- asm
- dd $FFFFFFFF { next driver }
- dw $8000 { attributes of simple character device }
- dw offset strategy_routine
- dw offset interrupt_routine
- db 'PAUSE '
- end;
-
- const
- stDone = $100;
- stBusy = $200;
-
- cmInit = 0;
-
- device_driver : boolean = false;
-
- type
- request_header = record
- request_length : byte;
- subunit: byte;
- command_code : byte;
- status : word;
- reserved: array[1..8] of byte;
- num_units : byte;
- first_free : pointer;
- args : ^char;
- drive_num : byte;
- end;
-
- var
- local_stack : array[1..4000] of byte;
- end_of_stack : byte;
- request : ^request_header;
-
- procedure handler(var regs : intregisters);
- { This routine is called by the strategy routine, and handles all requests.
- The data segment is okay, and we're running on the local_stack so we've got
- plenty of space. Remember: the init sections haven't been called yet!
- }
- begin
- with request^ do
- begin
- case command_code of
- cmInit: begin
- device_driver := true;
- Call_Main_Block;
- first_free := ptr(cseg,0); { Release everything!! }
- status := stDone;
- end;
- else
- status := stBusy;
- end;
- end;
- end;
-
- procedure RetFar; assembler;
- { Replacement for the IRET code that ends the interrupt routines below }
- asm
- mov sp,bp
- pop bp
- pop es
- pop ds
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- retf
- end;
-
- procedure strategy_routine(bp:word);
- var
- regs : intregisters absolute bp;
- begin
- with regs do
- request := ptr(es,bx);
- RetFar;
- end;
-
- procedure interrupt_routine(bp:word);
- var
- regs : intregisters absolute bp;
- begin
- SwapStackandCallNear(Ofs(handler),@end_of_stack,regs);
- RetFar;
- end;
-
- procedure do_pause;
- begin
- while keypressed do readkey;
- writeln('Press any key to continue....');
- repeat until keypressed;
- end;
-
- procedure Ret_From_Main_Block; assembler; { Must have declaration just
- like Call_Main_Block }
- asm
- end;
-
- procedure Call_Main_Block; assembler; { Must come just before main
- entry point }
- asm
- db $eb, 6 { Jump over the Ret instruction
- and System init }
- end;
-
- begin
- do_pause;
-
- if Device_Driver then
- asm
- pop bp
- jmp Ret_From_Main_Block;
- end
- else
- halt;
-
- header; { This line is never reached, but it fools the linker
- so that everything is loaded properly. }
- end.
-