Contents of the DEVICES.DOC file
The DeviceS program, besides having a more gaudy display, takes a
different approach to finding and presenting the Device Chain. A
typical approach is to find the NUL device as the first device in
the chain and present the devices in the order of the chain until
the device at the end of the chain. The resulting addresses make
it appear that the NUL device is off in a segment of its own and
that devices added by Config.Sys are loaded ahead of the standard
DOS devices. We wanted the devices in the order that they occupy
memory. The DOS Devices should start with CON, end with NUL and
be followed by any Config.Sys loaded devices in the order loaded
rather than the order of the chain.
Certain remarks seemed appropriate even when only translating the
Device Attribute word. The decision as to what remarks would be
useful and meaningful consumed hours of planning time and may not
be over yet. In case you choose to comment, the criteria were:
No remark should restate the obvious.
Any remark should help a normal user.
Here is my screen as an example:
Tue May 30, 1989 14:20 d:\work>devices
Address Strat Inter Attr Type Device Name Remarks
0070 014E 03CD 03D8 8013 Character CON Replaced Device
0070 0160 03CD 03DE 8000 Character AUX
0070 0172 03CD 03F2 8000 Character PRN
0070 0184 03CD 0410 8008 Character CLOCK$ System Date/Time
0070 0196 03CD 0416 0840 Block Drives A - F Mappable Drives
0070 01A8 03CD 03F2 8000 Character LPT1
0070 01BA 03CD 03DE 8000 Character COM1
0070 01CC 03CD 03FC 8000 Character LPT2
0070 01DE 03CD 0406 8000 Character LPT3
0070 01F0 03CD 03E8 8000 Character COM2
0070 2D08 14C6 14CC 8004 Character NUL
0A27 0000 0036 0041 8000 Character EMMXXXX0 Expanded Mem Mgr
0C8D 0000 277B 2786 8013 Character CON
0C8D 001C 277B 2786 8000 Character FCON
14FA 0000 0012 0021 2800 Block Drive G
1529 0000 0017 0022 4000 Block Drive H
1579 0000 0017 0022 4000 Block Drive I
15C9 0000 0030 003B C000 Character 4DOSSTAK
To those who would argue that "System Date/Time" for CLOCK$ and
"Expanded Mem Mgr" violate the first rule we offer two thoughts
that show that the decisions are not easy. The Clock Device is
NOT guaranteed to have a name as obvious as "CLOCK$". A device
that replaces it could have ANY name. "EMMXXXX0" certainly does
identify the Expanded Memory Manager device to most of us but we
let rule 2 overcome the doubts caused by rule 1.
Much of what could be said about Disk Drives was accomplished by
identifying the Drive Letter(s). The User already knows which of
these drives take removable media and what capacities and whether
any of them are RAM drives. If my system was part of a network,
then "NetWork" would appear as the "Name". Additional remarks to
the network line await your input. If your system uses HI-MEM by
Microsoft as an Extended Memory Manager, it will be identified.
Also, those character devices which report "busy" when accessed
through IOCTL will show "Busy Rpt" giving you many remarks.
DeviceS.DOC - Page 1
Examining the DeviceS.ASM code will answer most questions about
what has been included and how it has been accomplished. If you
are interested in programming be sure to see the DevSort code.
The TurboPower Device.EXE program was patterned after Dev.EXE by
Chris J. Dunford. Looking at the first 10 DeviceS.ASM code lines
you will see a pattern variation at the outset. We look for the
CON device first in order to scan the appropriate segment for the
NUL device. In the DevFind PROCedure, the header for NUL fills
level 1 of the DevS data array. The data for all devices is then
stored at subsequent levels until the end of the chain. With 32
levels (counting the 0 level which will be used when sorting) and
the large stack for overflow, there should be no catastrophes.
Anyone with 32 or more devices please let us know, however!
While data from the device header is being stored, the attribute
word is also interpreted for remarks. You'll see most of that
from the DoName: label to the end of the DevLine PROCedure. The
possible Block devices include NetWorks as well as disk drives.
In the case of disk drives, the number of Units is stored for
future interpretation as drive letters.
Upon return to the Main PROCedure, the program ends with an error
message and ErrorLevel if NO devices were entered into the array.
Otherwise the Heading Line is displayed. The ShowMsg PROCedure
is the one that interprets Units into drive letters and so we'll
save it for review last.
Novice programmers were invited to examine and use the DevSort
PROCedure earlier. The algorithm can be coded in any language.
The "Sinking Bubble Sort" was developed for teaching because a
"bubble sort" can be explained with only two hands whereas the
more efficient algorithms require sophisticated demonstration
aids that often overwhelm student programmers. The "Sinking
Bubble Sort" is only a little harder to explain and is much more
efficient. The "bubble sort" must process the array as many
times (minus 1) as there are members in the array. The "Sinking"
technique raises "Bubble Sort" efficiency so that no perceptible
time is taken with as few as 32 members.
Imagine that the array to be sorted is an apartment house which
assigns each floor according to the value of the furniture. The
furniture is initially moved to the next available level starting
with the ground floor. No intermediate floors are left vacant.
The furniture on each floor is tagged with a value. The basement
floor is reserved for temporary storage and the floors above the
top floor that is used are sealed off with an infinite furniture
value tag. The movers aren't very smart but they can compare two
values and they sure can move furniture!
In the "Sinking Bubble Sort", the movers know two limits. They
know that the first floor is level 1 and they know the number of
the top level. In fact, their freight elevator won't go past the
highest level occupied with furniture. They know that if they
get all the furniture in value order from the Ground level to the
Top floor, their work will be done.
There are 61 lines in the DevSort PROCedure. In the first five,
the movers advance from their Basement and when they find that
the next floor to examine is ABOVE the Top floor of furniture,
they go to the 59th line of DevSort from which they end their day
by returning to the Basement.
DeviceS.DOC - Page 2
Checking the middle lines of code, you will see labels for "sink,
down and done". They mark the test for, end of and start of
"sinking" points. See how the movers get to the DSsink: label.
While working from the Ground to Top floor, the movers check the
furniture value tags. If the value of the tag which they read on
the floor that they are working is less than the one which they
find on the floor above, they can advance without any moving to
the floor above UNLESS that floor is sealed off. If all of the
furniture was initially stored in order of value from the ground
to top floors, their day's work would consist only of checking
tags and NO moving.
Now let's get real. DeviceS has two possibilities. If your
system has no devices installed by Config.Sys, then NUL will
chain to CON and, each in turn and in order, will chain to your
last DOS device. (That device, by the way, will be the highest
COM device which your DOS version supports. My screen example
shows COM2 for the DOS 3.2 version. Your DOS 3.3 version might
In this first possibility, all devices are in order except for
the NUL device. As the movers examine the NUL furniture and CON
furniture tags, they realize that the NUL furniture must move to
the second floor in place of the CON furniture. To accomplish
this, they first move the CON furniture to the Basement (as done
by DevSort lines 13 - 19) and after moving the NUL furniture to
the old CON floor (20 -24), they move the CON furniture from the
basement to floor #1 (lines 25 - 29). Noting that they are on
the Ground floor, they see that there is NO sinking to do and
therefore advance to floor #2.
Floor #2 contains the NUL furniture which has a higher value than
the AUX furniture on level 3. They take the AUX furniture to the
basement, move the NUL furniture to floor #3 and then bring the
AUX furniture to floor #2 just vacated by moving NUL to floor #3.
Now on floor #2, they compare the AUX furniture to CON and since
CON is lower priced, they recover their place (still on floor 2 -
at DSdone:) and advance to Floor #3.
Guess what? Guess what? Guess what? etc... The NUL furniture,
being higher priced, replaces all the other devices furniture
until it is on the top floor. Sinking down each time finds that
each device below NUL is already in proper order... This simple
situation is unusual. I doubt that it applies to your DeviceS.
If Config.Sys has loaded any devices, they will chain from NUL
and the FIRST Config.Sys device loaded will chain to the DOS CON
device. In other words, NUL will be out of order at the top as
in the simple case, but it will be followed by the LAST device in
memory and ALL others out of order until reaching CON.
When the movers go to work on this mess they will find NUL to be
properly located below the LAST device in memory. After that,
the floor #2 (last device) will begin to move upward in floors.
As it moves up, the devices loaded after NUL will move down until
the first floors contain the NUL furniture followed by all of the
Config.Sys loaded devices' furniture in memory order. The next
floor, at that point will contain the CON device furniture. Not
only will it be replaced by the LAST device furniture, but, the
sink routine will really begin to operate at full power. Once
the CON device furniture is moved below the last device furniture
the DSdown: comparison will find that it is also lower than each
of the other devices in turn until it has reached Ground level.
DeviceS.DOC - Page 3
This sequence of sinking will repeat until the last COM device is
sunk below the NUL device and above all other DOS devices.
When the "Sinking Bubble Sort" goes into the sink mode, it does
exactly the same thing that it does in the conventional rising
mode except that it does it top down instead of bottom up. The
sink mode moves furniture from the current position down as far
as the Ground floor, if necessary to insure that furniture values
are in ascending order. In the conventional "bubble sort" there
is repetition of the bottom to top exchange until the ordering of
furniture is completed. The need to go back and start from that
Ground floor position is eliminated by "sinking" any out-of-order
value when it is first encountered.
Sinking has two conditions that will stop the movers exchange of
furniture from a lower out-of-order position through the basement
to the current "sink" position in exchange for the furniture at
that position. The primary condition is that the furniture
at the two levels is already in order. The absolute stopper is
that the lower level is the basement. Whenever data is moved in
computer memory, it is only a copy that is moved. The original
remains until over-written by the exchange. When completed, the
sort routine will have left a copy of the last moved furniture in
the basement. If you run DeviceS.EXE in a debugger, a set of NUL
device furniture will be found to remain in the basement as well
as at the proper level when the sort is complete.
Two little auxiliary routines, "SI2BX" and the 3 "AX2ASCh" parts
provide means to copy either characters or ASCII representations
of numbers into the DevS array. These routines are ubiquitous in
assembly language programs. The AX2ASCh trio are nearly the same
as used by Chris J. Dunford in his Dev.EXE program. Nobody has a
copyright on such common routines and you are free to use both or
either in any program that will benefit from them.
ShowMsg Proc is quite specialized. The last part of it from the
label SMnext: to ShowMsg EndP simply makes a double call to BIOS
routines to display each character by "teletype" in the same way
that TYPE at the DOS prompt does except that it initializes the
space that will be used by each character to the attribute that
is appropriate for where it is in a line of text. The NOT Found
device header error message and heading line will be underlined
for mono video or black and white on color but the data lines are
displayed in white on blue for the first 48 characters and white
on red for the last 17.
The special part of ShowMsg occurs only for lines NOT starting
with a space. These record lines MAY contain the data for block
disk drive devices. If this is the case, then the Units number
is converted to a drive letter. SMproc: decides if this is to be
done. SMmore: begins by looking for the next drive letter in the
"Kind" string. The first drive device will start with "A:" and
the letters will increment depending on the number of Units. In
my screen example, the first Disk Device is a Zenith driver that
controls two floppies and four hard disk partitions. Even if you
had only 1 floppy drive and 1 hard disk partition, it would still
reserve letters "A:" and "B:" for floppies and "C: - F:" for your
hard drive partitions. So Units = 6 becomes (count 'em) drives
"A - F". Updating the 2nd word of FlgS to 6 readies the string
so that "G" is the next drive, etc.
DeviceS.DOC - Page 4
by Tom Gilbert's Heart&Mind