DOS Device Drivers
Frank Whaley
frank at sagan.UUCP
Sun Jan 26 15:55:07 AEST 1986
As promised in net.micro.pc, here is a package which will allow you to
develop DOS Device Drivers with Lattice C.
The package include the following files:
driver.doc The (sparse) documentation
driver.h The only header file
driver.lib.uu The uuencoded library (described in the docs)
hdr.asm A prototype device driver header
makemon.bat A batch file which will make the MON driver
mhdr.asm The specific device driver header for MON
mono.c The actual driver source
----
...Frank Whaley, MicroPro Product Development
UUCP: {decvax!decwrl | ucbvax}!dual!
{hplabs | glacier}!well!
seismo!lll-crg!
ihnp4!ptsfa!
pyramid!micropro!sagan!frank
ARPA: micropro!sagan!frank at lll-crg.ARPA
"I'm told there are better programs [than WordStar],
but I'm also told there are better alphabets."
--William F. Buckley Jr.
-----------cut here----------cut here----------cut here----------
#!/bin/sh
#
# This is a shell archive. Remove anything before the "!/bin/sh"
# line above and run the rest of this file through the "sh" command
# (as "sh yourfile"), or use the "unshar" program.
#
echo x - driver.doc
sed 's/^X//' >driver.doc <<'*-*-END-of-driver.doc-*-*'
X Installable Device Drivers in C
X
X
XThis document is intended to describe a method for using Lattice
XC (small model) to develop Installable Device Drivers for MS-DOS.
XAdditionally, a number of C functions (provided in library
Xformat) are defined.
X
XInstallable Device Drivers are created by first writing the
Xfunctions to be supported, then linking these functions with the
XDriver Header. A prototype header file is provided in the file
XHDR.ASM. Note that two data items (the Attribute and Name/unit
Xfields) must be filled in with information specific to your
Xdriver before this file will assemble properly.
X
XThe driver header file assumes the existence of the following
Xfunctions (stubs are provided in the DRIVER.LIB library file),
Xwhich perform the various operations described in the Installable
XDevice Drivers chapter of the DOS Reference Manual:
X
X Init()
X MediaCheck()
X BuildBPB()
X IoCtlIn()
X Input()
X ndInput()
X InputStatus()
X InputFlush()
X Output()
X OutVerify()
X OutStatus()
X OutFlush()
X IoCtlOut()
X DevOpen()
X DevClose()
X RemMedia()
X
XA sample character device driver is included in this package,
Xwhich allows for a device named "MON". Outputting to this device
Xwill cause characters to appear on the IBMPC monochrome screen.
XStudy of the file MONO.C should reveal the details of this
Ximplementation.
X
X Questions or comments on this package may be directed to:
X
X Frank Whaley
X 7211 Camino Colegio
X Rohnert Park, CA 94928
X
XThrough the balance of this document, the pseudo-type "Addr" is
Xused to describe a long integer value (32-bits) which is used to
Xdescribe a memory address. Note that the Segment:Offset
Xaddressing method used in the 8086 family of processors causes
Xthis data type to be incompatible with true long integers. The
Xfollowing definition is assumed:
X
X typedef long Addr;
X
X
XAddr EndAddr();
X
X EndAddr() returns the driver's ending address, as required
X by the Init function call.
X
X
XAddr Dword(ptr)
X char *ptr;
X
X Dword() converts a 16-bit pointer (into the driver's data
X segment) to a 32-bit pointer.
X
X
Xint CopyB(from, to, len)
X Addr from,
X to;
X int len;
X
X CopyB() copies a section of memory "len" bytes in length
X from the area whose address is "from" to the area whose
X address is "to". Note that this code assumes that the
X memory sections do not overlap and that a forward copy is
X correct. This function returns the number of bytes copied.
X
X
Xint CopyW(from, to, len)
X Addr from,
X to;
X int len;
X
X CopyW() copies a section of memory "len" words in length
X from the area whose address is "from" to the area whose
X address is "to". Note that this code assumes that the
X memory sections do not overlap and that a forward copy is
X correct. This function returns the number of words copied.
X
Xchar InB(port)
X int port;
X
X InB() inputs and returns a byte from the hardware port
X described by "port".
X
X
Xint InW(port)
X int port;
X
X InW() inputs and returns a word from the hardware port
X described by "port".
X
X
Xchar OutB(byte, port)
X char byte;
X int port;
X
X OutB() outputs the byte "byte" to the hardware port
X described by "port". This function returns the output byte.
X
X
Xint OutW(word, port)
X int word,
X port;
X
X OutW() outputs the word "word" to the hardware port
X described by "port". This function returns the output word.
X
X
Xchar PeekB(addr)
X Addr addr;
X
X PeekB() returns the byte value found at the absolute address
X given by "addr".
X
X
Xint PeekW(addr)
X Addr addr;
X
X PeekW() returns the word value found at the absolute address
X given by "addr".
X
Xchar PokeB(val, addr)
X char val;
X Addr addr;
X
X PokeB() stores the value "val" into the absolute byte
X address given by "addr". This function returns "val".
X
X
Xint PokeW(val, addr)
X int val;
X Addr addr;
X
X PokeW() stores the value "val" into the absolute word
X address given by "addr". This function returns "val".
X
X
Xint SetB(start, len, byte)
X Addr start;
X int len;
X char byte;
X
X SetB() initializes a section of memory "len" bytes in
X length, beginning with the address given by "start", to the
X value "byte". This function returns the number of bytes
X set.
X
X
Xint SetW(start, len, word)
X Addr start;
X int len,
X word;
X
X SetW() initializes a section of memory "len" words in
X length, beginning with the address given by "start", to the
X value "word". This function returns the number of words
X set.
*-*-END-of-driver.doc-*-*
echo x - driver.h
sed 's/^X//' >driver.h <<'*-*-END-of-driver.h-*-*'
X/*
X * driver.h -> Device Driver Header File
X */
X
X
X/*
X * Status Word Bits
X */
X
X#define Error 0x8000
X#define Busy 0x0100
X#define Done 0x0080
X
X
X/*
X * Media Descriptor Byte Bits
X */
X
X#define TwoSided 1
X#define EightSector 2
X#define Removable 4
X
X
X/*
X * Error Return Codes
X */
X
X#define WriteProtect 0
X#define UnknownUnit 1
X#define DeviceNotReady 2
X#define UnknownCommand 3
X#define crcError 4
X#define BadLength 5
X#define SeekError 6
X#define UnknownMedia 7
X#define SectorNotFound 8
X#define NoPaper 9
X#define WriteFault 10
X#define ReadFault 11
X#define GeneralFailure 12
X
X
Xtypedef long Addr;
X
X
X/*
X * structures
X */
X
Xtypedef struct
X {
X char Length; /* Request Header length */
X char Unit; /* Unit Code */
X char Command; /* Command Code */
X int Status; /* Status */
X char reserved[8]; /* DOS Reserved Area */
X }
X Request;
X
Xtypedef struct
X {
X Request InitReq; /* Request Header */
X char nUnits; /* number of units */
X Addr EndAddr; /* Ending Address */
X Addr BPBarray; /* ptr to BPB array */
X }
X InitParms;
X
Xtypedef struct
X {
X Request MediaReq; /* Request Header */
X char MediaDesc; /* Media Descriptor */
X char ReturnCode; /* Return Code */
X }
X MediaParms;
X
Xtypedef struct
X {
X Request BPBReq; /* Request Header */
X char MediaDesc; /* Media Descriptor */
X Addr Transfer; /* Transfer Address */
X Addr BPBTable; /* ptr to BPB table */
X }
X BPBParms;
X
Xtypedef struct
X {
X Request InOutReq; /* Request Header */
X char MediaDesc; /* Media Descriptor */
X Addr Transfer; /* Transfer Address */
X int Count; /* Byte/Sector Count */
X int Start; /* Starting Sector Number */
X }
X InOutParms;
X
Xtypedef struct
X {
X Request ndInputReq; /* Request Header */
X char Byte; /* Byte Read From Device */
X }
X ndInputParms;
X
Xtypedef struct
X {
X Request StatusReq; /* Request Header */
X }
X StatusParms;
X
Xtypedef struct
X {
X Request FlushReq; /* Request Header */
X }
X FlushParms;
X
Xtypedef struct
X {
X int BytesPerSector;
X char SecsPerAllocUnit;
X int ReservedSectors;
X char FATCount;
X int RootDirEntries;
X int SectorsPerLogical;
X char MediaDesc;
X int SecsPerFAT;
X }
X BPB;
X
Xtypedef struct
X {
X char BootJump[3];
X char Name[8];
X BPB BootBPB;
X int SecsPerTrack;
X int HeadCount;
X int HiddenCount;
X }
X BootSector;
X
X
X/*
X * externals
X */
X
Xextern Request ReqHdr; /* current Request Header */
X
Xextern int CopyB(); /* copy bytes */
Xextern int CopyW(); /* copy words */
Xextern Addr Dword(); /* converts ptr to DWORD */
Xextern Addr EndAddr(); /* returns Ending Address */
Xextern char InB(); /* input byte */
Xextern int InW(); /* input word */
Xextern char OutB(); /* output byte */
Xextern int OutW(); /* output word */
Xextern char PeekB(); /* get byte from Addr */
Xextern int PeekW(); /* get word from Addr */
Xextern char PokeB(); /* put byte to Addr */
Xextern int PokeW(); /* put word to Addr */
Xextern int SetB(); /* set bytes */
Xextern int SetW(); /* set words */
X
X/*
X * END of driver.h
X */
*-*-END-of-driver.h-*-*
echo x - driver.lib.uu
sed 's/^X//' >driver.lib.uu <<'*-*-END-of-driver.lib.uu-*-*'
Xbegin 0777 driver.lib
XM\/T! $ (
XM
XM
XM
XM
XM
XM
XM
XM
XM
XM
XM -" !@ $24Y)5$*6)0 !$1!5$$&1$=23U50!414
XM04E,!E!'4D]54 104D]'!%1!24R0F < : @(!])@' &@ 0" ?*8!P H
XM$0 &!@$;F < : !P8!ZYH& /_ ?\"7)H& 7_ _\$5HP) 9215%(1%(
XMGZ 5 , ,<& (P> #'!@ '#0)P; ,0" @$!#@#$!!0! L0( @$!
XM$ #$# (! 0, VY + #!$E.250 JB@( '0
XM
XM
XM
XM
XM
XM
XM ( * A-141)04-(
XM13Z6&@ !$1!5$$&1$=23U50!E!'4D]54 104D]'/)@' &@ (" ?28!P H
XM!P %!0$GF at 0 _\!7YH$ 3_ EV,"0 &4D512$12 )^@"P " #'!@ X'#
XM/YP( ,0" @$! P"/D \ ((345$24%#2$4 GB@( '0
XM
XM
XM
XM
XM
XM
XM
XM
XM @ H "$)524Q$0E!"*I8: $1$%4009$1U)/55 &4$=23U50!%!2
XM3T<\F < : @(!])@' "@' 4% 2>:! #_P%?F at 0 !/\"78P) 9215%(
XM1%( GZ + ( ,<& #@<,_G @ Q (" 0$# (^0#P @A"54E,1$)00@
XM !.* @ =
XM
XM
XM
XM
XM
XM
XM
XM " "0 '24]#5$Q)3EZ6&@ !$1!5$$&
XM1$=23U50!E!'4D]54 104D]'/)@' &@ (" ?28!P H!P %!0$GF at 0 _\!
XM7YH$ 3_ EV,"0 &4D512$12 )^@"P " #'!@ X'#/YP( ,0" @$! P"/
XMD X ('24]#5$Q)3@ $>* @ =
XM
XM
XM
XM
XM
XM
XM
XM ( ' 5)
XM3E!55.26&@ !$1!5$$&1$=23U50!E!'4D]54 104D]'/)@' &@ (" ?28
XM!P H!P %!0$GF at 0 _\!7YH$ 3_ EV,"0 &4D512$12 )^@"P " #'!@
XM X'#/YP( ,0" @$! P"/D P (%24Y0550 #-B@( '0
XM
XM
XM
XM
XM
XM
XM
XM
XM @ D !TY$24Y0551.EAH 1$051!!D1'4D]54 901U)/
XM55 $4%)/1SR8!P!H " @'TF < * < !04!)YH$ /_ 5^:! $_P)=C D
XM!E)%44A$4@"?H L @ QP8 .!PS^<" #$ @(! 0, CY . "!TY$24Y0
XM550 WB@( '0
XM
XM
XM
XM
XM
XM
XM
XM " "@ (24Y055135$'VEAH
XM 1$051!!D1'4D]54 901U)/55 $4%)/1SR8!P!H " @'TF < * < !04!
XM)YH$ /_ 5^:! $_P)=C D !E)%44A$4@"?H L @ QP8 .!PS^<" #$
XM @(! 0, CY / ""$E.4%544U1! WXH" !T
XM
XM
XM
XM
XM
XM
XM
XM
XM ( * A)3E!55$9,5?>6&@ !$1!5$$&1$=23U50!E!'4D]54 104D]'/)@'
XM &@ (" ?28!P H!P %!0$GF at 0 _\!7YH$ 3_ EV,"0 &4D512$12 )^@
XM"P " #'!@ X'#/YP( ,0" @$! P"/D \ ((24Y0551&3%4 #@B@(
XM '0
XM
XM
XM
XM
XM
XM
XM
XM @ @ !D]55%!55(&6&@ !$1!5$$&1$=23U50
XM!E!'4D]54 104D]'/)@' &@ (" ?28!P H!P %!0$GF at 0 _\!7YH$ 3_
XM EV,"0 &4D512$12 )^@"P " #'!@ X'#/YP( ,0" @$! P"/D T (&
XM3U544%54 :HH" !T
XM
XM
XM
XM
XM
XM
XM
XM " "@ (3U545D52
XM24;ZEAH 1$051!!D1'4D]54 901U)/55 $4%)/1SR8!P!H " @'TF <
XM* < !04!)YH$ /_ 5^:! $_P)=C D !E)%44A$4@"?H L @ QP8 .!
XMPS^<" #$ @(! 0, CY / ""$]55%9%4DE& XXH" !T
XM
XM
XM
XM
XM
XM
XM
XM
XM ( * A/55135$%45>66&@ !$1!5$$&1$=23U50!E!'4D]54 10
XM4D]'/)@' &@ (" ?28!P H!P %!0$GF at 0 _\!7YH$ 3_ EV,"0 &4D51
XM2$12 )^@"P " #'!@ X'#/YP( ,0" @$! P"/D \ ((3U544U1!5%4
XM #.B@( '0
XM
XM
XM
XM
XM
XM
XM
XM @ H "$]55$9,55-(])8: $1$%4
XM009$1U)/55 &4$=23U50!%!23T<\F < : @(!])@' "@' 4% 2>:! #
XM_P%?F at 0 !/\"78P) 9215%(1%( GZ + ( ,<& #@<,_G @ Q (" 0$#
XM (^0#P @A/551&3%532 -V* @ =
XM
XM
XM
XM
XM
XM
XM
XM " "@ (
XM24]#5$Q/553[EAH 1$051!!D1'4D]54 901U)/55 $4%)/1SR8!P!H "
XM @'TF < * < !04!)YH$ /_ 5^:! $_P)=C D !E)%44A$4@"?H L @
XMQP8 .!PS^<" #$ @(! 0, CY / ""$E/0U1,3U54 Y(H" !T
XM
XM
XM
XM
XM
XM
XM
XM
XM ( ) =$159/4$5.7Y8: $1$%4009$1U)/55 &4$=2
XM3U50!%!23T<\F < : @(!])@' "@' 4% 2>:! #_P%?F at 0 !/\"78P)
XM 9215%(1%( GZ + ( ,<& #@<,_G @ Q (" 0$# (^0#@ @=$159/
XM4$5. 2(H" !T
XM
XM
XM
XM
XM
XM
XM
XM @ H "$1%5D-,3U-%&98:
XM $1$%4009$1U)/55 &4$=23U50!%!23T<\F < : @(!])@' "@' 4%
XM 2>:! #_P%?F at 0 !/\"78P) 9215%(1%( GZ + ( ,<& #@<,_G @
XMQ (" 0$# (^0#P @A$159#3$]310 ** @ =
XM
XM
XM
XM
XM
XM
XM
XM
XM " "@ (4D5-345$24$JEAH 1$051!!D1'4D]54 901U)/55 $4%)/1SR8
XM!P!H " @'TF < * < !04!)YH$ /_ 5^:! $_P)=C D !E)%44A$4@"?
XMH L @ QP8 !P\*<" #$ @(! 0, CY / ""%)%34U%1$E! $XH"
XM !T
XM
XM
XM
XM
XM
XM
XM
XM ( ) =%3D1!1$12?I8@ $1$%4009$1U)/
XM55 %1%1!24P&4$=23U50!%!23T?#F < : ! (!\I@' "@& 8& 2::! #
XM_P%?F at 0 !?\"7* * ( +L (S8PW*<!@#$ 10! 8.0#@ @=%3D1!1$12
XM 9XH" !T
XM
XM
XM
XM
XM
XM
XM
XM @ < !4173U)$
XM])8. &4$=23U50!%!23T<]F < * @ P,!*IH$ +_ 6"@# ! "+W(M?
XM HS8P]F0# 05$5T]21 -Z* @ =
XM
XM
XM
XM
XM
XM
XM
XM
XM
XM " !P %0T]064+WE at X 901U)/55 $4%)/1SV8!P H%0 # P$=
XMF at 0 O\!8* 9 $ (O<'@:+1PK$?P;%=P*+R/SSI <?PXF0# 05#3U!9
XM0@ .&* @ =
XM
XM
XM
XM
XM
XM
XM
XM
XM ( ' 5#3U!95^*6#@ !E!'4D]5
XM4 104D]'/9@' "@5 ,# 1V:! "_P%@H!D 0 B]P>!HM'"L1_!L5W HO(
XM_/.E!Q_#B) , !!4-/4%E7 S(H" !T
XM
XM
XM
XM
XM
XM
XM
XM
XM @ 4
XM TE.0I^6#@ !E!'4D]54 104D]'/9@' "@) ,# 2F:! "_P%@H T 0
XMB]R+5P+L,N3#0I * ! TE.0@ (F* @ =
XM
XM
XM
XM
XM
XM
XM
XM
XM
XM " !0 #24Y7BI8. &4$=23U50!%!23T<]F < * <
XM P,!*YH$ +_ 6"@"P ! "+W(M7 NW#69 * ! TE.5P '2* @ =
XM
XM
XM
XM
XM
XM
XM
XM
XM
XM ( & 1/551"/)8. &
XM4$=23U50!%!23T<]F < * P P,!)IH$ +_ 6"@$ ! "+W(I' HM7!.XR
XMY,-HD L $$3U540@ ":* @ =
XM
XM
XM
XM
XM
XM
XM
XM
XM
XM @ 8 !$]55%<GE at X 901U)/55 $4%)/1SV8!P H"@ # P$HF at 0 O\!
XM8* . $ (O<BT<"BU<$[\-^D L $$3U545P !&* @ =
XM
XM
XM
XM
XM
XM
XM
XM
XM
XM " !P %4$5%2T(-E at X 901U)/55 $4%)/
XM1SV8!P H# # P$FF at 0 O\!8* 0 $ (O<'L5? HH',N0?PQN0# 050
XM145+0@ />* @ =
XM
XM
XM
XM
XM
XM
XM
XM
XM ( ' 50145+
XM5_B6#@ !E!'4D]54 104D]'/9@' "@* ,# 2B:! "_P%@H X 0 B]P>
XMQ5\"BP<?PS*0# 050145+5P .** @ =
XM
XM
XM
XM
XM
XM
XM
XM
XM
XM @ < !5!/2T5" Y8. &4$=23U50!%!23T<]F < * \ P,!
XM(YH$ +_ 6"@$P ! "+W(S:BT<"Q5\$B >.VL/)D P $%4$]+14( #M
XMB@( '0
XM
XM
XM
XM
XM
XM
XM
XM
XM " !P %4$]+15?NE at X 901U)/
XM55 $4%)/1SV8!P H#P # P$CF at 0 O\!8* 3 $ (O<C-J+1P+%7P2)!X[:
XMP\B0# 0503TM%5P -B* @ =
XM
XM
XM
XM
XM
XM
XM
XM
XM ( &
XM 13151"2)8. &4$=23U50!%!23T<]F < *!8 P,!')H$ +_ 6"@&@ !
XM "+W(I'"(M/!L1_ OSSJHS8CL"+1P;#^I + !!%-%5$( RB@( '0
XM
XM
XM
XM
XM
XM
XM
XM
XM
XM @ 8 !%-%5%<SE at X 901U)/55 $4%)/1SV8!P H
XM%@ # P$<F at 0 O\!8* : $ (O<BT<(BT\&Q'\"_/.KC-B.P(M'!L/XD L
XM $$4T545P !V* @ =
XM
XM
XM
XM
XM
XM
XM
XM
XM #Q_0$
XM
XM
XM
XM
XM
XM
XM
XM
XM
XM
XM
XM $0!W/% X ")9&6 at H2&1"?5]LEP"' @8TS)9(> +4P35'&;"$1%
XM5D-,3U-%#P !T1%5D]014X. 5$5T]21!( TE.0A4 TE.5Q8 !TE/0U1,
XM24X$ A)3T-43$]55 T =.1$E.4%54!@ $3U540A< A/551&3%532 P
XM A/551615))1 at H 1/5517& !%-%5$(= $4T545QX 9#3U!90B$3
XM )1$560TQ/4T4A#P &1%=/4D0A$@ !$E.0B$5 %24Y)5"$! 9)3E!5
XM5"$% )24]#5$Q/550A#0 )345$24%#2$4A @ %3U540B$7 E/551&3%53
XM2"$, E/551615))1B$* 90145+0B$9 &4$]+14(A&P !5-%5$(A'0
XM
XM
XM
XM
XM 5RY3890 K7@ 6XYG- ALVP ?D JHR:?
XMJ!V(&80 3SI%F1-R2[<(0E5)3$1"4$(# %0T]064(3 5#3U!95Q0 !T5.
XM1$%$1%(1 1)3DE4 0 !4E.4%54!0 (24Y0551&3%4( (24Y055135$$'
XM (345$24%#2$4" &3U544%54"0 "$]55%-40515"P !5!%14M"&0 %
XM4$5%2U<: 503TM%0AL !5!/2T57' (4D5-345$24$0 )0E5)3$1"4$(A
XM P &0T]065<A% "$1%5D]014XA#@ "$5.1$%$1%(A$0 "4E.4%541DQ5
XM(0@ "4E.4%544U1!(0< !$E.5R$6 (24]#5$Q)3B$$ (3D1)3E!55"$&
XM '3U544%54(0D "4]55%-40515(0L !4]55%<A& &4$5%2U<A&@ !E!/
XM2T57(1P E214U-141)02$0 531517(1X
XM
XM
XF
X
Xend
*-*-END-of-driver.lib.uu-*-*
echo x - hdr.asm
sed 's/^X//' >hdr.asm <<'*-*-END-of-hdr.asm-*-*'
X PAGE 60, 132
XTITLE HDR 22-Feb-85 Device Driver Header |
X
X;-----------------------------------------------------------------------|
X; |
X; Device Driver Library |
X; Device Driver Header |
X; |
X;-----------------------------------------------------------------------|
X; REVISION HISTORY |
X; |
X; Number DD-MMM-YY WHO WHY |
X;-------|---------------|-----------------------|-----------------------|
X; 0.0 | 22-Feb-85 | Frank Whaley | Initial Release |
X;-----------------------------------------------------------------------|
X
X PAGE
X;-----------------------------------------------------------------------|
X; Equates |
X;-----------------------------------------------------------------------|
X
XStkSiz EQU 2048 ; local stack size
X
X PAGE
X;-----------------------------------------------------------------------|
X; Group Selection |
X;-----------------------------------------------------------------------|
X
XPGROUP Group PROG, TAIL
XDGROUP Group DATA, DTAIL
X
XPROG Segment Para Public 'PROG'
XPROG EndS
X
XDATA Segment Para Public 'DATA' ; define first
XDATA EndS
X
X Assume CS:PROG, DS:DATA, ES:DATA, SS:DATA
X
X PAGE
X;-----------------------------------------------------------------------|
X; Program Segment |
X;-----------------------------------------------------------------------|
X
XPROG Segment Para Public 'PROG'
X
X Extrn Init:Near, MediaChe:Near, BuildBPB:Near
X Extrn IoCtlIn:Near, Input:Near, ndInput:Near
X Extrn InputSta:Near, InputFlu:Near, Output:Near
X Extrn OutVerif:Near, OutStatu:Near, OutFlush:Near
X Extrn IoCtlOut:Near, DevOpen:Near, DevClose:Near
X Extrn RemMedia:Near
X
X ORG 0
X
XHDR Proc Far
X
X;-----------------------------------------------------------------------|
X; Device Header |
X;-----------------------------------------------------------------------|
X
X DD -1 ; -> next device
X DW theAttribute ; you must enter attribute field
X DW Strategy ; -> device strategy
X DW Interrupt ; -> device interrupt
X DB theName ; you must put something here
X
X;-----------------------------------------------------------------------|
X; Code Segment Variables |
X;-----------------------------------------------------------------------|
X
XRHptr DD (?) ; -> Request Header
XssEntry DW (?) ; entry SS
XspEntry DW (?) ; entry SP
X
X PAGE
X;-----------------------------------------------------------------------|
X; Device Strategy |
X; |
X; ENTRY : ES:BX -> Request Header |
X; |
X; EXIT : Request Header copied to ReqHdr |
X; all registers preserved |
X; |
X;-----------------------------------------------------------------------|
X
XStrategy:
X
X MOV Word Ptr CS:RHptr,BX ; save request header ptr
X MOV Word Ptr CS:RHptr + 2,ES
X
X PUSHF ; (+1) save the world
X PUSH ES ; (+2)
X PUSH DS ; (+3)
X PUSH SI ; (+4)
X PUSH DI ; (+5)
X PUSH CX ; (+6)
X PUSH BX ; (+7)
X
X MOV SI,BX
X MOV BX,ES
X MOV DS,BX ; DS:SI -> Request Header
X
X MOV BX,Offset PGROUP:TAIL
X MOV CL,4
X SHR BX,CL
X MOV CX,CS
X ADD BX,CX
X MOV ES,BX
X MOV DI,Offset DGROUP:ReqHdr ; ES:DI -> ReqHdr
X
X CLD
X XOR CH,CH
X MOV CL,[SI]
X REP MOVSB ; copy Request Header
X
X POP BX ; (+6) restore
X POP CX ; (+5)
X POP DI ; (+4)
X POP SI ; (+3)
X POP DS ; (+2)
X POP ES ; (+1)
X POPF ; (+0)
X RET
X
X PAGE
X;-----------------------------------------------------------------------|
X; Device Interrupt |
X; |
X; ENTRY : anything |
X; |
X; EXIT : all registers preserved |
X; |
X;-----------------------------------------------------------------------|
X
XInterrupt:
X
X PUSH DS ; (+1) save the world
X PUSH ES ; (+2)
X PUSH AX ; (+3)
X PUSH BX ; (+4)
X PUSH CX ; (+5)
X PUSH DX ; (+6)
X PUSH SI ; (+7)
X PUSH DI ; (+8)
X PUSH BP ; (+9)
X
X MOV CS:ssEntry,SS ; save entry SS
X MOV CS:spEntry,SP ; and SP
X
X MOV AX,Offset PGROUP:TAIL ; set our DS, SS, BP, and SP
X MOV CL,4
X SHR AX,CL
X MOV CX,CS
X ADD AX,CX
X MOV BX,Offset DGROUP:MyStack
X MOV DS,AX
X MOV ES,AX
X MOV SS,AX
X MOV SP,BX
X MOV BP,BX
X
X ;
X ; call our function
X ;
X MOV AL,ReqHdr + 2 ; AL = Command Code
X SHL AL,1
X CBW
X MOV SI,Offset DGROUP:FuncTab
X ADD SI,AX
X CALL Word Ptr [SI]
X
X ;
X ; copy back Request Header
X ;
X LES DI,RHptr ; ES:DI -> original space
X MOV SI,Offset DGROUP:ReqHdr ; DS:SI -> our (updated) copy
X CLD
X XOR CH,CH
X MOV CL,[SI]
X REP MOVSB ; copy Request Header
X
X MOV SS,CS:ssEntry ; restore original stuff
X MOV SP,CS:spEntry
X
X POP BP ; (+8) restore
X POP DI ; (+7)
X POP SI ; (+6)
X POP DX ; (+5)
X POP CX ; (+4)
X POP BX ; (+3)
X POP AX ; (+2)
X POP ES ; (+1)
X POP DS ; (+0)
X RET
X
XHDR EndP
X
XPROG EndS
X
XTAIL Segment Public 'PROG' ; for finding end of code segment
XTAIL EndS
X
X PAGE
X;-----------------------------------------------------------------------|
X; Data Segment |
X;-----------------------------------------------------------------------|
X
XDATA Segment Para Public 'DATA'
X
X Public ReqHdr
X
X DB StkSiz DUP (?) ; our stack, overflows into code
XMyStack Label Word
X
XFuncTab Label Word
X DW Offset PGROUP:Init
X DW Offset PGROUP:MediaChe
X DW Offset PGROUP:BuildBPB
X DW Offset PGROUP:IoCtlIn
X DW Offset PGROUP:Input
X DW Offset PGROUP:ndInput
X DW Offset PGROUP:InputSta
X DW Offset PGROUP:InputFlu
X DW Offset PGROUP:Output
X DW Offset PGROUP:OutVerif
X DW Offset PGROUP:OutStatu
X DW Offset PGROUP:OutFlush
X DW Offset PGROUP:IoCtlOut
X DW Offset PGROUP:DevOpen
X DW Offset PGROUP:DevClose
X DW Offset PGROUP:RemMedia
X
XReqHdr DB 256 DUP (?) ; copy of Request Header
X
XDATA EndS
X
XDTAIL Segment Public 'DATA' ; for finding end of data segment
XDTAIL EndS
X
X END HDR ; of hdr.asm
*-*-END-of-hdr.asm-*-*
echo x - makemon.bat
sed 's/^X//' >makemon.bat <<'*-*-END-of-makemon.bat-*-*'
Xlc1 mono
Xlc2 mono -v
Xmasm mhdr/s;
Xlink mhdr+mono,mono,nul,driver
Xdel mono.obj
Xdel mhdr.obj
Xexe2bin mono.exe mono.sys
Xdel mono.exe
*-*-END-of-makemon.bat-*-*
echo x - mhdr.asm
sed 's/^X//' >mhdr.asm <<'*-*-END-of-mhdr.asm-*-*'
X PAGE 60, 132
XTITLE HDR 22-Feb-85 Device Driver Header |
X
X;-----------------------------------------------------------------------|
X; |
X; Device Driver Library |
X; Device Driver Header |
X; |
X;-----------------------------------------------------------------------|
X; REVISION HISTORY |
X; |
X; Number DD-MMM-YY WHO WHY |
X;-------|---------------|-----------------------|-----------------------|
X; 0.0 | 22-Feb-85 | Frank Whaley | Initial Release |
X;-----------------------------------------------------------------------|
X
X PAGE
X;-----------------------------------------------------------------------|
X; Equates |
X;-----------------------------------------------------------------------|
X
XStkSiz EQU 256 ; local stack size
X
X PAGE
X;-----------------------------------------------------------------------|
X; Group Selection |
X;-----------------------------------------------------------------------|
X
XPGROUP Group PROG, TAIL
XDGROUP Group DATA, DTAIL
X
XPROG Segment Para Public 'PROG'
XPROG EndS
X
XDATA Segment Para Public 'DATA' ; define first
XDATA EndS
X
X Assume CS:PROG, DS:DATA, ES:DATA, SS:DATA
X
X PAGE
X;-----------------------------------------------------------------------|
X; Program Segment |
X;-----------------------------------------------------------------------|
X
XPROG Segment Para Public 'PROG'
X
X Extrn Init:Near, MediaChe:Near, BuildBPB:Near
X Extrn IoCtlIn:Near, Input:Near, ndInput:Near
X Extrn InputSta:Near, InputFlu:Near, Output:Near
X Extrn OutVerif:Near, OutStatu:Near, OutFlush:Near
X Extrn IoCtlOut:Near, DevOpen:Near, DevClose:Near
X Extrn RemMedia:Near
X
X ORG 0
X
XHDR Proc Far
X
X;-----------------------------------------------------------------------|
X; Device Header |
X;-----------------------------------------------------------------------|
X
X DD -1 ; -> next device
X DW 8000H ; character only device
X DW Strategy ; -> device strategy
X DW Interrupt ; -> device interrupt
X DB "MON " ; mono
X
X;-----------------------------------------------------------------------|
X; Code Segment Variables |
X;-----------------------------------------------------------------------|
X
XRHptr DD (?) ; -> Request Header
XssEntry DW (?) ; entry SS
XspEntry DW (?) ; entry SP
X
X PAGE
X;-----------------------------------------------------------------------|
X; Device Strategy |
X; |
X; ENTRY : ES:BX -> Request Header |
X; |
X; EXIT : Request Header copied to ReqHdr |
X; all registers preserved |
X; |
X;-----------------------------------------------------------------------|
X
XStrategy:
X
X MOV Word Ptr CS:RHptr,BX ; save request header ptr
X MOV Word Ptr CS:RHptr + 2,ES
X
X PUSHF ; (+1) save the world
X PUSH ES ; (+2)
X PUSH DS ; (+3)
X PUSH SI ; (+4)
X PUSH DI ; (+5)
X PUSH CX ; (+6)
X PUSH BX ; (+7)
X
X MOV SI,BX
X MOV BX,ES
X MOV DS,BX ; DS:SI -> Request Header
X
X MOV BX,Offset PGROUP:TAIL
X MOV CL,4
X SHR BX,CL
X MOV CX,CS
X ADD BX,CX
X MOV ES,BX
X MOV DI,Offset DGROUP:ReqHdr ; ES:DI -> ReqHdr
X
X CLD
X XOR CH,CH
X MOV CL,[SI]
X REP MOVSB ; copy Request Header
X
X POP BX ; (+6) restore
X POP CX ; (+5)
X POP DI ; (+4)
X POP SI ; (+3)
X POP DS ; (+2)
X POP ES ; (+1)
X POPF ; (+0)
X RET
X
X PAGE
X;-----------------------------------------------------------------------|
X; Device Interrupt |
X; |
X; ENTRY : anything |
X; |
X; EXIT : all registers preserved |
X; |
X;-----------------------------------------------------------------------|
X
XInterrupt:
X
X PUSH DS ; (+1) save the world
X PUSH ES ; (+2)
X PUSH AX ; (+3)
X PUSH BX ; (+4)
X PUSH CX ; (+5)
X PUSH DX ; (+6)
X PUSH SI ; (+7)
X PUSH DI ; (+8)
X PUSH BP ; (+9)
X
X MOV CS:ssEntry,SS ; save entry SS
X MOV CS:spEntry,SP ; and SP
X
X MOV AX,Offset PGROUP:TAIL ; set our DS, SS, BP, and SP
X MOV CL,4
X SHR AX,CL
X MOV CX,CS
X ADD AX,CX
X MOV BX,Offset DGROUP:MyStack
X MOV DS,AX
X MOV ES,AX
X MOV SS,AX
X MOV SP,BX
X MOV BP,BX
X
X ;
X ; call our function
X ;
X MOV AL,ReqHdr + 2 ; AL = Command Code
X SHL AL,1
X CBW
X MOV SI,Offset DGROUP:FuncTab
X ADD SI,AX
X CALL Word Ptr [SI]
X
X ;
X ; copy back Request Header
X ;
X LES DI,RHptr ; ES:DI -> original space
X MOV SI,Offset DGROUP:ReqHdr ; DS:SI -> our (updated) copy
X CLD
X XOR CH,CH
X MOV CL,[SI]
X REP MOVSB ; copy Request Header
X
X MOV SS,CS:ssEntry ; restore original stuff
X MOV SP,CS:spEntry
X
X POP BP ; (+8) restore
X POP DI ; (+7)
X POP SI ; (+6)
X POP DX ; (+5)
X POP CX ; (+4)
X POP BX ; (+3)
X POP AX ; (+2)
X POP ES ; (+1)
X POP DS ; (+0)
X RET
X
XHDR EndP
X
XPROG EndS
X
XTAIL Segment Public 'PROG' ; for finding end of code segment
XTAIL EndS
X
X PAGE
X;-----------------------------------------------------------------------|
X; Data Segment |
X;-----------------------------------------------------------------------|
X
XDATA Segment Para Public 'DATA'
X
X Public ReqHdr
X
X DB StkSiz DUP (?) ; our stack, overflows into code
XMyStack Label Word
X
XFuncTab Label Word
X DW Offset PGROUP:Init
X DW Offset PGROUP:MediaChe
X DW Offset PGROUP:BuildBPB
X DW Offset PGROUP:IoCtlIn
X DW Offset PGROUP:Input
X DW Offset PGROUP:ndInput
X DW Offset PGROUP:InputSta
X DW Offset PGROUP:InputFlu
X DW Offset PGROUP:Output
X DW Offset PGROUP:OutVerif
X DW Offset PGROUP:OutStatu
X DW Offset PGROUP:OutFlush
X DW Offset PGROUP:IoCtlOut
X DW Offset PGROUP:DevOpen
X DW Offset PGROUP:DevClose
X DW Offset PGROUP:RemMedia
X
XReqHdr DB 256 DUP (?) ; copy of Request Header
X
XDATA EndS
X
XDTAIL Segment Public 'DATA' ; for finding end of data segment
XDTAIL EndS
X
X END HDR ; of mhdr.asm
*-*-END-of-mhdr.asm-*-*
echo x - mono.c
sed 's/^X//' >mono.c <<'*-*-END-of-mono.c-*-*'
X/*
X * monochrome device driver
X */
X
X#include "driver.h"
X
X#define VidSeg 0xB0000000 /* addr of monochrome video RAM */
X#define Attr 0x0700 /* video attribute mask */
X#define Blank (Attr + ' ') /* a blank */
X
Xchar row, /* current row number */
X col; /* current column number */
X
Xlong VidAddr; /* -> current display character */
X
X
XInit()
X {
X cls();
X
X ((InitParms *)&ReqHdr)->EndAddr = EndAddr();
X ReqHdr.Status = Done;
X }
X
X
XOutput()
X {
X InOutParms *iop; /* our pointer */
X long ta; /* -> transfer addr */
X int ctr; /* byte count */
X char c;
X
X iop = (InOutParms *)&ReqHdr;
X ta = iop->Transfer;
X ctr = iop->Count;
X
X while (ctr--)
X switch (c = PeekB(ta))
X {
X case '\r' :
X doCR();
X break;
X
X case '\n' :
X doLF();
X break;
X
X case '\b' :
X doBS();
X break;
X
X case '\t' :
X doHT();
X break;
X
X case 0x1A :
X cls();
X break;
X
X default :
X putone(c);
X break;
X }
X
X ReqHdr.Status = Done;
X }
X
X
XOutVerify()
X {
X Output();
X }
X
X
XOutStatus()
X {
X ReqHdr.Status = Done;
X }
X
X
XOutFlush()
X {
X ReqHdr.Status = Done;
X }
X
X
Xstatic cls()
X {
X SetW(VidSeg, 2000, Blank); /* clear the screen */
X
X row = col = 0;
X VidAddr = VidSeg;
X }
X
X
Xstatic ScrollUp()
X {
X CopyW(VidSeg + 160, VidSeg, 1920); /* move up */
X
X SetW(VidSeg + 3840, 80, Blank); /* clear last line */
X
X VidAddr -= 160;
X row = 24;
X }
X
X
Xstatic doCR()
X {
X VidAddr -= (col << 1);
X col = 0;
X }
X
X
Xstatic doLF()
X {
X VidAddr += 160;
X if (++row > 24)
X ScrollUp();
X }
X
X
Xstatic doBS()
X {
X if (col)
X {
X --col;
X VidAddr -= 2;
X }
X }
X
X
Xstatic doHT()
X {
X while (col & 7)
X putone(' ');
X }
X
X
Xstatic putone(c)
X char c;
X {
X PokeW(Attr + c, VidAddr);
X VidAddr += 2;
X
X if (++col > 79)
X {
X col = 0;
X doLF();
X }
X }
*-*-END-of-mono.c-*-*
exit
--
...Frank Whaley, MicroPro Product Development
UUCP: {decvax!decwrl | ucbvax}!dual!
{hplabs | glacier}!well!
seismo!lll-crg!
ihnp4!ptsfa!
pyramid!micropro!sagan!frank
ARPA: micropro!sagan!frank at lll-crg.ARPA
"I'm told there are better programs [than WordStar],
but I'm also told there are better alphabets."
--William F. Buckley Jr.
More information about the Comp.sources.unix
mailing list