Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Welcome to the new platform of Programmer's Heaven! We apologize for the inconvenience caused, if you visited us from a broken link of the previous version. The main reason to move to a new platform is to provide more effective and collaborative experience to you all. Please feel free to experience the new platform and use its exciting features. Contact us for any issue that you need to get clarified. We are more than happy to help you.

Virtualize I/O In DOS

BretBret Posts: 114Member
This may be an unreasonably tall order, but here goes.

I'm trying to figure out a way to virtualize (trap) I/O requests in "real" DOS. It seems the only way to do it may be using INT 2Fh, Function 4A15h with MS's EMM386.EXE (excerpt from Ralf Brown's Interrupt List below).

Has anybody ever tried to trap I/O requests, either this way or any other way, and have some sample code to go along with it? Any other ideas on approaches that might work?

[code]
***************

INT 2F - MS EMM386.EXE v4.46+ - INSTALL I/O VIRTUALIZATION HANDLER
AX = 4A15h
BX = 0000h (function number)
DX = starting I/O address
EDX high word = ending I/O address
CX = number of ports to trap
DS:SI -> I/O dispatch table (see #02815)
DI = size of client's code and data (size of DS segment which must be
made available to I/O dispatch function in protected mode)
Return: CF clear if successful
CF set on error
Notes: this interface is only available in virtual-86 mode; the I/O handlers
will be called in protected mode
only ports 0100h-FFFFh may be trapped; EMM386 reserved ports 0000h-
00FFh

Format of EMM386 I/O dispatch table [array]:
Offset Size Description (Table 02815)
00h WORD I/O port number
02h WORD offset of I/O handler for port (see #02816)

(Table 02816)
Values EMM386 I/O dispatch function is called with:
CX = Ring0 code selector for I/O handler's segment
DS = Ring0 data selector for I/O handler's segment (alias of CS)
EDX = faulting I/O address
ECX = direction (00000008h for byte output, 00000000h for byte input)
(reportedly 00h for byte/word input, 04h for byte/word output
under DOS 6.22 EMM386)
EAX = data in/out
Return: (via FAR RET)
CF clear if I/O access successfully virtualized
CF set if access not virtualized (default handler will be called to
perform the I/O)
BUG: 32-bit I/O on trapped ports hangs the DOS 6.22 EMM386

***************
[/code]

Comments

  • jeffleydajeffleyda Posts: 390Member
    I'm pretty dumb with this stuff, but it's always been something I've wanted to play with too. Do IRC, the I/O access map is essentially just a large bitfield inside the CPU, and this emm386 function is merely providing access to it? That's actually kinda cool-I didn't even know this function existed.

    Obviously it's possible to do it w/o emm386, since soft-ice is able to trap I/O and it's incompatible with emm386. It does put the cpu into it's own protected mode though.

    So, sorry that I don't have any help for you, but just wanted to tell you that there's at least someone else who is interested in the subject at hand.




  • BretBret Posts: 114Member
    : I'm pretty dumb with this stuff, but it's always been something I've
    : wanted to play with too. Do IRC, the I/O access map is essentially
    : just a large bitfield inside the CPU, and this emm386 function is
    : merely providing access to it? That's actually kinda cool-I didn't
    : even know this function existed.
    :
    : Obviously it's possible to do it w/o emm386, since soft-ice is able
    : to trap I/O and it's incompatible with emm386. It does put the cpu
    : into it's own protected mode though.
    :
    : So, sorry that I don't have any help for you, but just wanted to
    : tell you that there's at least someone else who is interested in the
    : subject at hand.

    I'll follow this up with some posts as I get things figured out. Scouring some VERY old usenet posts I managed to find some resources that look promising.
  • BretBret Posts: 114Member
    : : I'm pretty dumb with this stuff, but it's always been something I've
    : : wanted to play with too. Do IRC, the I/O access map is essentially
    : : just a large bitfield inside the CPU, and this emm386 function is
    : : merely providing access to it? That's actually kinda cool-I didn't
    : : even know this function existed.
    : :
    : : Obviously it's possible to do it w/o emm386, since soft-ice is able
    : : to trap I/O and it's incompatible with emm386. It does put the cpu
    : : into it's own protected mode though.
    : :
    : : So, sorry that I don't have any help for you, but just wanted to
    : : tell you that there's at least someone else who is interested in the
    : : subject at hand.
    :
    : I'll follow this up with some posts as I get things figured out.
    : Scouring some VERY old usenet posts I managed to find some resources
    : that look promising.

    I've found a good resource, and possibly the only valid resource that may exist for this. He is Bob Smith, one of the founders of Qualitas (the makers of 386MAX). His current e-mail address is bsmith@sudleyplace.com. He sent the the attached Zip file with some source code and comments. In the Zip file, I renamed the executable file IOTrap.Com to IOTrap.Co_ so that I could upload it here.

    The main thing of interest is the IOTrap.Txt file, which explains some problems with the interface, its implementation in EMM386, and the documentation. Microsoft provided a specification on MSDN many years ago (I haven't been able to find it), which is the basis for what's in the RBIL excerpt above (which is both incomplete and incorrect). Apparently, Qualitas tried to get Microsoft to update and correct the spec and EMM386, to no avail. I think 386MAX implemented an improved version of the spec (based on what I see in the Zip file), but don't have a copy of 386MAX to verify any of it. I believe that EMM386 and 386MAX are the only memory managers to implement the function at all.

    I can tell you that it does in fact work. I've been doing some experimentation with a joystick emulator, and it seems to work fine so far (I'm testing with EMM386 version 4.48, which comes with DOS 6.20). At first, I couldn't get it to work at all. As it turns out, I was testing the function by single-stepping through with a debugger, which doesn't seem to work. I think it has something to do with the INT 03's that the debugger sticks in memory to do the single-stepping. After I stopped single-stepping and just let the program run, it started working like it was supposed to (this isn't the first time I've had a program react differently in a debugger than it does in real life). Also, FYI, the IOTRAP.COM program in the Zip file crashes on my computer, and I think it might be for the same reason (it contains INT 03's in it).

    A few very interesting things to note (I found them very interesting, anyway). The EMM386 implementation only works correctly with byte-level I/O (IN AL,DX and OUT DX,AL). If you try to virtualize a word access (IN AX,DX), EMM386 just does a CBW on the value in AL. It doesn't return the AH that you told it to. Dword accesses (IN EAX,DX) crash the computer. Also, the I/O virtualization code is called in 16-bit protected mode, not 32-bit protected mode as you might expect on a 32-bit processor. And, the virtualization does not get "passed though" to Windows if you run Windows after setting up Virtual I/O (though it would seem logical that it should).

    I'll need to experiment some more, but if it keeps working like it has so far, I think I'll be using this function a lot.
  • BretBret Posts: 114Member
    : I'm pretty dumb with this stuff, but it's always been something I've
    : wanted to play with too. Do IRC, the I/O access map is essentially
    : just a large bitfield inside the CPU, and this emm386 function is
    : merely providing access to it? That's actually kinda cool-I didn't
    : even know this function existed.
    :
    : Obviously it's possible to do it w/o emm386, since soft-ice is able
    : to trap I/O and it's incompatible with emm386. It does put the cpu
    : into it's own protected mode though.
    :
    : So, sorry that I don't have any help for you, but just wanted to
    : tell you that there's at least someone else who is interested in the
    : subject at hand.

    Just a side note regarding Soft-ICE. I can't speak to it for sure, but based on the literature I've seen so far (not directly from Soft-ICE, since I've never used it), I think they use the Pentium Debug registers to trap I/O. Intel introduced the Debug Registers with Pentium-class CPU's, and one of the things you can do with them is Trap I/O. From my understanding (not verified in any way), there are 4 available Debug Registers, and each one can be associated with a single I/O port. Ergo, you can trap a maximum of 4 ports at the same time. The EMM386 virtualization spec allows many more than 4 ports to be trapped at the same time. In addition, I think the code associated with the Debug Registers must be called in 32-bit protected mode, which isn't possible to do from "real" DOS (it requires a virtualized DOS environment).

    Again, that's my understanding based on some literature I've seen, with no actual experience. I could be completely wrong. Anybody who knows better is welcome to either disagree or confirm this.
  • jeffleydajeffleyda Posts: 390Member
    Amazing stuff bret, thank you for sharing all this info. Having the ability to trap I/O in DOS could lead me to converting my ancient AC97 audio player into something that could do soundblaster emulation. Things could get really interesting from there. If only I had another lifetime of hours to spend working on such a thing.

    ---

    I've used s-ice on a 486 and could have sworn that it can trap on I/O instructions, but it's been long enough that I don't recall the results. I've still got the 486 beasty set up in my basement, so I'll give that a shot in the near future and report back here just to clarify the thread.






  • BretBret Posts: 114Member
    : Amazing stuff bret, thank you for sharing all this info. Having the
    : ability to trap I/O in DOS could lead me to converting my ancient
    : AC97 audio player into something that could do soundblaster
    : emulation. Things could get really interesting from there. If only
    : I had another lifetime of hours to spend working on such a thing.
    :
    : ---
    :
    : I've used s-ice on a 486 and could have sworn that it can trap on
    : I/O instructions, but it's been long enough that I don't recall the
    : results. I've still got the 486 beasty set up in my basement, so
    : I'll give that a shot in the near future and report back here just
    : to clarify the thread.

    Being able to virtualize I/O in DOS opens up all kinds of possibilities with Joysticks, Sound/MIDI, Serial, Parallel, Ethernet, etc., that is normally only possible with something like Windoze. Too bad EMM386 doesn't allow ports below 100h to be trapped, or you could also do things with Keyboards and PS/2 Mice. Like you said, it would be nice to have another lifetime's worth of hours to spend on this stuff.
Sign In or Register to comment.