public inbox for linux-msdos@vger.kernel.org
 help / color / mirror / Atom feed
* Redirecting a DOS interrupt call out to Linux
@ 2013-07-18 16:35 Andrew Bird (Sphere Systems)
  2013-07-18 19:49 ` Stas Sergeev
  0 siblings, 1 reply; 4+ messages in thread
From: Andrew Bird (Sphere Systems) @ 2013-07-18 16:35 UTC (permalink / raw)
  To: linux-msdos

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?

Thanks,


Andrew



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Redirecting a DOS interrupt call out to Linux
  2013-07-18 16:35 Redirecting a DOS interrupt call out to Linux Andrew Bird (Sphere Systems)
@ 2013-07-18 19:49 ` Stas Sergeev
  2013-07-19 15:58   ` Andrew Bird
  0 siblings, 1 reply; 4+ messages in thread
From: Stas Sergeev @ 2013-07-18 19:49 UTC (permalink / raw)
  To: Andrew Bird (Sphere Systems); +Cc: linux-msdos

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.
--
To unsubscribe from this list: send the line "unsubscribe linux-msdos" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Redirecting a DOS interrupt call out to Linux
  2013-07-18 19:49 ` Stas Sergeev
@ 2013-07-19 15:58   ` Andrew Bird
  2013-07-19 20:26     ` Stas Sergeev
  0 siblings, 1 reply; 4+ messages in thread
From: Andrew Bird @ 2013-07-19 15:58 UTC (permalink / raw)
  To: Stas Sergeev; +Cc: linux-msdos

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. So it seems I can't use the normal Dosemu mechanisms for adding 
interrupts. 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?

Best regards,

Andrew 
--
To unsubscribe from this list: send the line "unsubscribe linux-msdos" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Redirecting a DOS interrupt call out to Linux
  2013-07-19 15:58   ` Andrew Bird
@ 2013-07-19 20:26     ` Stas Sergeev
  0 siblings, 0 replies; 4+ messages in thread
From: Stas Sergeev @ 2013-07-19 20:26 UTC (permalink / raw)
  To: Andrew Bird; +Cc: linux-msdos

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 majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2013-07-19 20:26 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-07-18 16:35 Redirecting a DOS interrupt call out to Linux Andrew Bird (Sphere Systems)
2013-07-18 19:49 ` Stas Sergeev
2013-07-19 15:58   ` Andrew Bird
2013-07-19 20:26     ` Stas Sergeev

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox