VOGONS


First post, by japheth

User metadata
Rank Newbie
Rank
Newbie

Hello,

there is a small bug in DosBox's support for int 21h, ax=4B01h. The stack pointer (SP) is modified once the new program has terminated. This isn't the case in other DOSes.

I don't know if any game is affected by this, probably not.

test case: http://www.japheth.de/Download/dbbug.zip

Reply 1 of 6, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

You can use something like that:

		/* Switch the psp's */
dos.psp(pspseg);
DOS_PSP newpsp(dos.psp());
dos.dta(RealMake(newpsp.GetSegment(),0x80));
real_writew(RealSeg(sssp-2),RealOff(sssp-2),0xffff);
block.exec.initsssp = sssp-2;
block.exec.initcsip = csip;

in dos_execute.cpp, should correct a part of the problem.
The rest seems bad return stack layout.

Reply 2 of 6, by japheth

User metadata
Rank Newbie
Rank
Newbie

> You can use something like that:

Thanks! However, AFAICS this modification affects the called program's stack only. The issue I was talking about is the value of SP of the caller.

EDIT:

this modification works:

	if (flags==LOAD) {
SaveRegisters(); /* added */
DOS_PSP callpsp(dos.psp());
/* Save the SS:SP on the PSP of calling program */
callpsp.SetStack(RealMakeSeg(ss,reg_sp));
reg_sp = reg_sp+18; /* added */
/* Switch the psp's */
dos.psp(pspseg);

but looks a bit strange, since a IRQ in the VM might destroy the register copy saved onto the stack.

Reply 5 of 6, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

but looks a bit strange, since a IRQ in the VM might destroy the register copy saved onto the stack.

Maybe trace the stack of msdos, if they skip the register saving completely.
In that case you'd remove the SaveRegs calls in int21/4b functions, and the
RestoreReg ones in int21/4c

Reply 6 of 6, by japheth

User metadata
Rank Newbie
Rank
Newbie
wd wrote:
Maybe trace the stack of msdos, if they skip the register saving completely. In that case you'd remove the SaveRegs calls in int […]
Show full quote

but looks a bit strange, since a IRQ in the VM might destroy the register copy saved onto the stack.

Maybe trace the stack of msdos, if they skip the register saving completely.
In that case you'd remove the SaveRegs calls in int21/4b functions, and the
RestoreReg ones in int21/4c

The register saving is - of course - done by MS-DOS. The important thing is that SS:SP isn't changed, that is, the calling application can push/pop registers it wants to preserve onto the stack across the call.