Back to home page

DOS ain't dead

Forum index page

Log in | Register

Back to index page
Thread view  Board view
mbbrutman

Homepage

Washington, USA,
02.10.2023, 23:47
 

Device drivers: Changing the attribute word at install time? (Developers)

I'm writing my first device driver and I'd like it to run on DOS 2.1 and up without providing different versions. (I'm going to ignore DOS 4.x here.)

All of the documentation that I'm reading implies that the attribute word of the device header is read only. Except for the book "Writing MS-DOS Device Drivers" by Robert S. Lai, which talks about an advanced method where the install routine queries DOS and then modifies the attribute word based on what is needed.

For me I'm interested in bit 1 which indicates if 32 bit block addressing is available. This makes sense for DOS 5 but not for older versions of DOS.

Is modifying the attribute word a legitimate way to handle this? Do you know of any device drivers that do this? I suppose it works but that assumes that DOS evaluates it after the initialization routine, and I can't find anything that says when the attribute word is evaluated.


-Mike

glennmcc

Homepage E-mail

North Jackson, Ohio (USA),
03.10.2023, 03:43

@ mbbrutman
 

Device drivers: Changing the attribute word at install time?

> I'm writing my first device driver and I'd like it to run on DOS 2.1 and up
> without providing different versions. (I'm going to ignore DOS 4.x here.)
>

"When did MS-DOS 2.1 come out?

MS-DOS 2.1 was released in November 1983, designed for the IBM PCjr.
It introduced support for half-height disk drives and ROM cartridges."

Sheesh... And I thought I was messing with old-as-dirt stuff
by working with this circa 1997 P-II machine. ;-)

---
--
http://glennmcc.org/

mbbrutman

Homepage

Washington, USA,
03.10.2023, 20:21

@ mbbrutman
 

Device drivers: Changing the attribute word at install time?

I'm still looking for examples of device drivers that do this, but I found one sentence in the second edition of "Undocumented DOS" (Schulman) that confirms this is possible.

The sentence says the driver install routine is called first, and then the attributes are evaluated. Which makes sense as there is no need to worry about driver chains or attributes if the install routine in the driver errors out.

---
mTCP - TCP/IP apps for vintage DOS machines!
http://www.brutman.com/mTCP

ecm

Homepage E-mail

Düsseldorf, Germany,
03.10.2023, 20:56

@ mbbrutman
 

Device drivers: Changing the attribute word at install time?

> The sentence says the driver install routine is called first, and then the
> attributes are evaluated. Which makes sense as there is no need to worry
> about driver chains or attributes if the install routine in the driver
> errors out.

UPX sources indicate that "OpenDOS" wants the interrupt field untouched by the packer, that is it may read it before running the unpacker (strategy entrypoint).

https://github.com/upx/upx/blob/7f9d381c7b594ecf7d...f3c0f16527599/src/stub/src/i086-dos16.sys.S#L42

https://github.com/upx/upx/blob/7f9d381c7b594ecf7d...f3c0f16527599/src/stub/src/i086-dos16.exe.S#L34

section         DEVICEENTRY
                .long   -1
                .short  attribute
                .short  strategy        /* .sys header */
                .short  interrupt       /* opendos wants this field untouched */


Here's this part in EDR-DOS, an OpenDOS derivative: https://hg.pushbx.org/ecm/edrdos/file/e1dbcad5136e/drbio/config.a86#l556


        mov     ax,es:DH_STRATEGY[di]   ; Set up the STRATEGY Entry Point
        mov     strategy_off,ax
        mov     strategy_seg,es

        mov     ax,es:DH_INTERRUPT[di]  ; Set up the INTERRUPT Entry Point
        mov     interrupt_off,ax
        mov     interrupt_seg,es
        call    init_static_request


Evidently it does read both entrypoint offsets before calling the strategy during device initialisation.

---
l

mbbrutman

Homepage

Washington, USA,
03.10.2023, 21:26

@ ecm
 

Device drivers: Changing the attribute word at install time?

Interesting because I just looked at the MS DOS 2.0 source code on Github and it looks like it does not look at the attributes until after the driver init routine returns:

https://github.com/microsoft/MS-DOS/blob/master/v2.0/source/SYSINIT.ASM


The code you linked looks like it's a UPX device driver for whatever OpenDOS is. (I'm familiar with UPX as a command line program, not as a device driver.)

tkchia

Homepage

03.10.2023, 21:32

@ mbbrutman
 

Device drivers: Changing the attribute word at install time?

Hello mbbrutman,

> The code you linked looks like it's a UPX device driver for whatever
> OpenDOS is. (I'm familiar with UPX as a command line program, not as a
> device driver.)

UPX can apparently compress device drivers for MS-DOS; and the code is (part of?) the decompressor stub for device drivers.

(For the decompressor to work, the compressed device driver must be able to be processed by the OS as a device driver in its own right, so the unpacker stub must take that into account...)

Thank you!

---
https://gitlab.com/tkchia · https://codeberg.org/tkchia · 😴 "MOV AX,0D500H+CMOS_REG_D+NMI"

mbbrutman

Homepage

Washington, USA,
03.10.2023, 22:48

@ tkchia
 

Device drivers: Changing the attribute word at install time?

tkchia,

Thank you, that makes more sense. If I understand it correctly, the device driver is compressed except for the unpacker, which should run when DOS calls the device driver init routine.

In that case the attribute word is still in the same location and can be modified by the unpacker installer routine.

It sounds like the comment about OpenDOS above is specific to OpenDOS, and not a general limitation of MS or PC DOS.

tom

Homepage

Germany (West),
04.10.2023, 23:43

@ tkchia
 

Device drivers: Changing the attribute word at install time?

> Hello mbbrutman,
>
> > The code you linked looks like it's a UPX device driver for whatever
> > OpenDOS is. (I'm familiar with UPX as a command line program, not as a
> > device driver.)
>
> UPX can apparently compress device drivers for MS-DOS; and the code is
> (part of?) the decompressor stub for device drivers.

yes. UPX can compress device drivers, and even dual .EXE and device drivers.

background: early versions of HIMEM were a dual .EXE and device driver.
you could load it as DEVICE=HIMEM.EXE, but also for command line like
HIMEM /T
would run a regression test. Japeth removed this later on, but this is as HIMEM started.

however dual mode EXE/DRIVER executables could only by compressed by my own, non
public, compression program (EXEPACK). so I (as the original master HIMEM author)
compressed HIMEM.EXE with my proprietary program and published it in this binary form. but nobody else was able to produce the same (compressed) binary.

Bart Oldeman was annoyed by that, 'reengineered' my code and integrated it into UPX.

fine with me.

tkchia

Homepage

03.10.2023, 21:28

@ mbbrutman
 

Device drivers: Changing the attribute word at install time?

Hello mbbrutman, hello ecm,

> For me I'm interested in bit 1 which indicates if 32 bit block addressing
> is available. This makes sense for DOS 5 but not for older versions of
> DOS.

What happens if you set attribute bit 1 unconditionally?

As far as I can tell from Microsoft's source code release (https://github.com/microsoft/MS-DOS), it seems that MS-DOS 2.x only cares about bit 1 for character devices — in which case it says whether the device is the default stdout. Perhaps you could simply set bit 1 for a block device driver and get away with it.

Thank you!

---
https://gitlab.com/tkchia · https://codeberg.org/tkchia · 😴 "MOV AX,0D500H+CMOS_REG_D+NMI"

mbbrutman

Homepage

Washington, USA,
03.10.2023, 22:51

@ tkchia
 

Device drivers: Changing the attribute word at install time?

> Hello mbbrutman, hello ecm,
>
> What happens if you set attribute bit 1 unconditionally?
>
> As far as I can tell from Microsoft's source code release
> (https://github.com/microsoft/MS-DOS), it seems that MS-DOS 2.x only cares
> about bit 1 for character devices — in which case it says whether the
> device is the default stdout. Perhaps you could simply set bit 1 for a
> block device driver and get away with it.
>
> Thank you!

I could set the bits and hope that the older versions of DOS ignores what it does not like, but the professional programmer in me says that relying on undocumented behavior is probably not a great idea. Debugging these things is difficult already.

If PC DOS an MS DOS only evaluate the attribute bits after the init routine runs (as the books suggest) then I have a solution - update the attribute bits at init time. Otherwise it's safer to do separate versions of the device driver for DOS 2, 3, and 5/6.

bretjohn

Homepage E-mail

Rio Rancho, NM,
06.10.2023, 21:35

@ mbbrutman
 

Device drivers: Changing the attribute word at install time?

Unless you actually need the device driver to be installed by DOS at bootup for some reason, you can also manually insert the driver into the device driver chain. Essentially, this makes it a TSR instead of a device driver so you can do things like uninstalling it if you want to or detecting the DOS version while you install so you can configure the attributes however you want.

I do this on some of my programs, both for character and block devices. But to be fair, I've never tried it with really early versions of DOS (like 2.x) but I think it would be possible to do there also.

mbbrutman

Homepage

Washington, USA,
07.10.2023, 20:42

@ bretjohn
 

Device drivers: Changing the attribute word at install time?

> Unless you actually need the device driver to be installed by DOS at bootup
> for some reason, you can also manually insert the driver into the device
> driver chain. Essentially, this makes it a TSR instead of a device driver
> so you can do things like uninstalling it if you want to or detecting the
> DOS version while you install so you can configure the attributes however
> you want.
>
> I do this on some of my programs, both for character and block devices.
> But to be fair, I've never tried it with really early versions of DOS (like
> 2.x) but I think it would be possible to do there also.

Interesting! Is it really as simple as inserting the device driver in the chain? I suspect some things like DOS telling you your starting unit number get missed, so you have to compute that yourself. I'm also assuming that are putting it last (first?) in the chain (the same way that DOS does it) so that you don't disturb drive ordering.

bretjohn

Homepage E-mail

Rio Rancho, NM,
09.10.2023, 19:17

@ mbbrutman
 

Device drivers: Changing the attribute word at install time?

> Interesting! Is it really as simple as inserting the device driver in the
> chain?

For a character device, it really is as simple as inserting in the chain. It's not trivial, but is pretty simple. It also doesn't work with some Virtual Machines (like DOSBox and its extensions) since their DOS is not really DOS.

BTW, the way to find the device driver chain is to locate the DOS List of Lists and the NUL device header is stored in the LOL (not a pointer to the NUL device header, the actual NUL device header is stored there). NUL is always the first device driver in the chain.

For a block device, you need to do more than just insert the device into the chain. You also need to insert information into other DOS tables as well, including the Drive Parameter Block (DPB) and Current Directory Structure (CDS) tables.

> I suspect some things like DOS telling you your starting unit
> number get missed, so you have to compute that yourself.

Exactly. You need to manually store all the correct information into the various tables (in addition to the device driver chain) which includes pointers back and forth between the various tables.

If you let DOS load the block driver via CONFIG.SYS, it does all of that for you but you also have no control over how DOS assigns the drive letters (and not all DOS's do it the same way).

> I'm also assuming
> that are putting it last (first?) in the chain (the same way that DOS does
> it) so that you don't disturb drive ordering.

No, it really doesn't matter where it ends up in the chain since you have pointers back and forth between the various tables. E.g., in the table that contains information about the drive letters, DOS creates the table the size based on your LASTDRIVE setting (which can be up to 32 entries in MS-DOS 7). If a drive letter is unused, that particular table entry is empty. You can fill in any of the empty entries with your information, which means you can use any unused driver letter you want (as long as LASTDRIVE was set properly). DOS assigns letters from the bottom up, but you don't necessarily need to do it that way if you don't want to.

For some sample code, you can use my USBDRIVE program or the FreeDOS DEVLOAD program.

As with character devices, of course, it doesn't work with VM's like DOSBox but does work with VM's that use a "real" DOS.

mbbrutman

Homepage

Washington, USA,
02.11.2023, 19:39

@ bretjohn
 

Device drivers: Changing the attribute word at install time?

Following up to the original question ...

I did what tkchia suggested (just setting the bit unconditionally) at DOS 2.1 did not care about it. Trying to set the bits dynamically at install time is probably overkill.

I'll make sure DOS 3.x isn't offended. Assuming it is not, the simpler solution wins.

---
mTCP - TCP/IP apps for vintage DOS machines!
http://www.brutman.com/mTCP

Rugxulo

Homepage

Usono,
23.11.2023, 22:15

@ mbbrutman
 

Device drivers: Changing the attribute word at install time?

Back when you originally mentioned this, I wanted to point you to a particular article, in the vain attempt to help, but I couldn't find the link.

Writing MS-DOS Device Drivers (Marcus Johnson, Dr. Dobbs, 01 Dec 1990)

Back to index page
Thread view  Board view
22049 Postings in 2034 Threads, 396 registered users, 69 users online (0 registered, 69 guests)
DOS ain't dead | Admin contact
RSS Feed
powered by my little forum