Re: Redirecting a DOS interrupt call out to Linux
Stas Sergeev <[email protected]>
| Newsgroups | org.kernel.vger.linux-msdos |
|---|---|
| Message-ID | <[email protected]> |
19.07.2013 19:58, Andrew Bird пишет:
> On Thursday 18 July 2013 23:49:41 Stas Sergeev wrote:
>> 18.07.2013 20:35, Andrew Bird (Sphere Systems) пишет:
>>> Hi all,
>>>
>>> I've been playing with the Dosemu source code with the hope of replacing
>>>
>>> an old TSR with a native Linux daemon. Currently a DOS app I have no
>>> source
>>> for makes an interrupt call to a TSR with data, the TSR works with it and
>>> the result is returned.
>>>
>>> I had in mind to replace it with something like this:
>>> 1/ Old DOS app makes call to interrupt
>>> 2/ New Dosemu interrupt handler that collects the data given to it by the
>>> DOS app and pushes it into a message queue on the host.
>>> 3/ A Linux daemon that reads the incoming message, does the processing and
>>> returns the result via a second message queue.
>>> 4/ The new Dosemu interrupt handler then reads the result from the second
>>> message queue, places it in memory and returns.
>>> 5/ The DOS app sees the result and is unaware of any difference.
>>>
>>> My first step was to hook in a new skeleton Dosemu interrupt handler, but
>>> it doesn't seem to be being called and the DOS app thinks the TSR is not
>>> installed. I'm using Dosemu 1.2.2 for historical reasons, but I expect
>>> the problem is similar on 1.4.0 etc.
>>>
>>> I figured all I'd need to do would be to add a new function to
>>> src/base/async/int.c and reference it.
>>>
>>> /* this is the handler for INT 76 calls from DOS to the test interface */
>>> int test_int (void) {
>>>
>>> ds_printf("INT76: we have been called\n");
>>> return 1;
>>>
>>> }
>>>
>>> /* add reference to it in setup_interrupts() */
>>> interrupt_function[0x76] = test_int;
>>>
>>> Can anybody tell me what I'm missing? How does the interrupt vector table
>>> get built?
>> Firstly, the interrupt handling is much different in 1.2
>> and 1.4. Secondly, you need to make sure the interrupt
>> vector points to BIOSSEG:INT_OFF(i) (see bios_setup() in setup.c)
>> and that no one have hooked it from DOS (or, at least, chains
>> it back to the original address).
>> Alternatively you can make dosemu to try and intercept the int0xNN
>> instruction. In this case you won't need to worry if someone have
>> hooked that vector under DOS. For that you will need to modify
>> the can_revector() function.
>> Note that this all applies to 1.4. I have no idea how 1.2 worked,
>> this was too long ago.
>> Additionally, curent git allows you to sleep inside the interrupt
>> handler of dosemu, while the DOS is still running. This will likely
>> allow you to do the thing within one interrupt call, instead of 2.
> Hi Stas,
> Thanks for the help. For the time being I've switched to latest git
> master whilst I experiment. It seems the reason the handler wasn't being
> called initially was that the DOS program was checking to see the memory
> location matched what it expected in the Interrupt table. If it wasn't correct
> then it just bailed out. Swapping the SETIVEC to match that address cured the
> problem for the DOS programs, but of course I need my interrupt routine to
> live there.
THat's why I suggested you to set it to BIOSSEG:INT_OFF(i).
This is exactly a hlt address, which will then call the handler
from interrupt_function[i][NO_REVECT].
> So it seems I can't use the normal Dosemu mechanisms for adding
> interrupts.
I don't think this is the right conclusion.
> I don't want to code my mods in assembler, as you can imagine.
> I noticed that the int33 mouse was doing something similar, so I added a
> little code to the bios.S assembler file, to just add a 'hlt' at the correct
> address. I've then modified the hlt handler to call my function just like
> int33_post(). Inside there I have a di_printf() and a fake_iret(), and it's
> being called fine now, I just have to add the function meat.
>
> Are there any downsides to this approach?
Aside from the redundant work you did - none.
Please do
git checkout devel
to get even more recent dosemu, and you'll find that even
int33 is no longer doing what you describe.
There is already a hlt at BIOSSEG:INT_OFF(i) which should
do what you need, and your interrupt vector was probably
initialized to NULL instead, so the DOS prog didn't want to
use it.
--
To unsubscribe from this list: send the line "unsubscribe linux-msdos" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html