VOGONS


First post, by tomaswoj

User metadata
Rank Newbie
Rank
Newbie

Im getting an CPU GRP5 Illegal call 7 on executing "MOUNT C something" in [autoexec] in dosbox.conf.

Im trying to debug it, but frankly dont know how dosbox runs internal commands like MOUNT.COM or MEM.COM. From what i have learned, in the dos_programs.cpp those commands are simple function handles being somehow pluged into the dos shell. But on the other hand, tracing the code to the point of DOS_Shell::Execute() I can see that invokation of those commands goes through the very same loop (DOSBOX_RunMachine/NormalLoop) as any other executable (realy binary executable). Is that true ??

I mean - i dont see the link between MOUNT.COM in autoexec and invokation of MOUNT handler 🙁. Does it go through 'usual' CPU registers/callbacks/interrupts?

Reply 2 of 28, by tomaswoj

User metadata
Rank Newbie
Rank
Newbie

System specs: UIQ3 SDK/Symbian C++, so that brings a problem with potential debug output (except what i plugged into the code myself in terms of Symbian SDK debug statements).

Im trying to startup a dosbox with simple dosbox conf containing:

[autoexec]
dir
echo "test test"
MEM
echo "abracadabra"

And it fails (PANIC Alloc in Symbian emu) on MEM (or MOUNT, if I use it in the dosbox.conf above), on SDL output screen it says - Exit to Error: CPU GRP5 Illegal call 7.

So now im trying to debug - what exact line of code make it a failure ( or a sequence of operations). And my confusion is - that MOUNT operation is an internal command, but i dont see a clear link in the code from DOS_Shell::Execute(...) to MOUNT handler (C++ function).

My suspicion is that the magic happens inside the CPU loop:
DoCommand -> Execute() -> Callback_RunRealInt(0x21) -> loop()

and inside there is some CallBack_Handler that finds out from file_name/call_back registration that it is an 'internal program' - and then runs it as a regular C++ function (its handler). But its just my suspicion, and i would like if possible to confirm that 😀

Reply 3 of 28, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

check out src\misc\programs.cpp, especially PROGRAMS_MakeFile()
and the exe_block[] struct which contains the code that is run when that
.com/exe file is executed.
The callback will issue the run() function of the respective program.

Can you debug the dosbox executable? (gdb or whatever)
Can you add logging? (LOG_MSG)

Reply 4 of 28, by tomaswoj

User metadata
Rank Newbie
Rank
Newbie

I got some logging already.

In general the story starts at the line with prognem: MMCM (its truncated MEM.COM). The lines before are just dosinit stuff.

Markers in the log:
444 - inside the normal loop (dosbox.cpp, normal_loop)
445 - inside the normal loop, just in while(1)
444 - increase ticks: self descriptive, in increase ticks section
446 - inside the while(1), inside the if(PIC_RunQueue()) section
inside the normal loop: <ret> - code after cpudecoder
I'm in normal loop callback handler: <ret> - before handler
I'm in normal loop callback handler: <ret_handler> - handler result
I'm in normal loop callback handler: <100+ret> -after handler

So it seems after invoking MEM.COM from autoexec.bat im looping several times through the loop/handler and at some point - in some loop i got error from cpudecoder. - the abovementioned CPU: GRP5: Illegall call 7.

Reply 5 of 28, by tomaswoj

User metadata
Rank Newbie
Rank
Newbie

Ahhh, yes, the attachement.

Attachments

  • Filename
    epoc.log
    File size
    35.28 KiB
    Downloads
    796 downloads
    File comment
    Homemade log from dosbox.cpp running MEM.COM on Symbian UIQ3 SDK emulator.
    File license
    Fair use/fair dealing exception

Reply 7 of 28, by tomaswoj

User metadata
Rank Newbie
Rank
Newbie

An extract of corresponding code (to epoc.log) - may help in analysis 😀:

static Bitu Normal_Loop(void) {
Bits ret;
#ifdef UIQ3DEB
_LIT(KMsgDebug,"I'm in normal loop: %d");
RDebug::Print(KMsgDebug,444);
#endif
while (1) {
#ifdef UIQ3DEB
RDebug::Print(KMsgDebug,445);
#endif
if (PIC_RunQueue()) {
#ifdef UIQ3DEB
RDebug::Print(KMsgDebug,446);
#endif
ret=(*cpudecoder)();
#ifdef UIQ3DEB
RDebug::Print(KMsgDebug,ret);
#endif
if (ret<0) return 1;
if (ret>0) {
#ifdef UIQ3DEB
_LIT(KMsgDebug2,"I'm in normal loop callback handler: %d");
RDebug::Print(KMsgDebug2,ret);
#endif
Bitu blah=(*CallBack_Handlers[ret])();
#ifdef UIQ3DEB
RDebug::Print(KMsgDebug2,blah);
#endif
if (blah) return blah;
#ifdef UIQ3DEB
RDebug::Print(KMsgDebug2,ret+100);
#endif
}
#if C_DEBUG
if (DEBUG_ExitLoop()) return 0;
#endif
} else {
GFX_Events();
if (ticksRemain>0) {
TIMER_AddTick();
ticksRemain--;
} else goto increaseticks;
}
}
increaseticks:
#ifdef UIQ3DEB
_LIT(KMsgDebug3,"I'm in normal loop - increase ticks: %d");
RDebug::Print(KMsgDebug3,444);
#endif
i

Reply 8 of 28, by tomaswoj

User metadata
Rank Newbie
Rank
Newbie

I did some additional debugging stuff and im simply stuck 🙁. It seems that in normal (i took win32 dosbox/nofpu/no dynrec/normal core) reference scenario the flow is as follows:
- invokation of mem.com from shell will trigger (in dosbox.com, cpu loop):
-- DOSInt21 handler (35) with reg_ah set to 75 (DOS execute)
-- then DOS Int21 handler (35) with reg_ah set to 74 (mem segment resize)
-- after that i will get into callback handler for internal command (5),
-- then program handler for MEM.COM and voila.

On the UIQ3 SDK emulator im getting this flow:
- DOSInt21 handler (35) with reg_ah set to 75 (DOS Execute) - so far so good,
- then DOSInt21 handler (35) with reg_ag set to 250 (!!!) - and then it all goes bananas 🙁.

It seems that something happens after im back from 75 (DOS execute) handler in DOSInt21, but what - this is simply beyond my current debug skills 🙁.

If this is something in core_normal deeply inside of it, then i dont see much chance to progress with this issue....

Reply 9 of 28, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

Next time please use hex values as decimals are hard to read (for me...).

Can you set up a build with the debugger enabled? If not things are way
trickier, you'll have to use some external debugger to trace dosbox code.

When the dos exec successfully returns (debug DOS_Execute() for this)
verify that the cs:ip values are correct (reg_eip, SegValue(cs) if you're
using LOG_MSG).
Then trace the normal core loop which should execute what's in the exe_block
and which should modify the according registers.

Most likely the exec fails and you'll run into rubbish.

Reply 12 of 28, by Qbix

User metadata
Rank DOSBox Author
Rank
DOSBox Author

nope. I doubt that dosbox is doing something wrong as it works
on psp and other handheld devices (n80, pocketpc)

Water flows down the stream
How to ask questions the smart way!

Reply 13 of 28, by kolijoco

User metadata
Rank Newbie
Rank
Newbie

but i wanna play EOB1 on my nokia, and i haven't found an s60 dosbox yet, so i'm making my own ;-)

managed to trace this a bit further...
the accident happens in DOS_Execute() called by the first int21 to load 'mount.com' code.
the load from the virtual file and its transfer to memory are successful (all 20 bytes check out :-),
however a bit down in

/* Setup a psp */
if (flags!=OVERLAY) {
// Create psp after closing exe, to avoid...
SetupPSP(pspseg,memsize,envseg); // <-------- this one
SetupCMDLine(pspseg,block);
};

the SetupPSP call (actually the psp.MakeNew(memsize); call within) corrupts the first DWORD of the loaded code

so when later on the cseip reaches the int21 (which is supposed to do some mm), ax is not set (as the code for that was corrupted).

ideas?

thanks

Reply 14 of 28, by Qbix

User metadata
Rank DOSBox Author
Rank
DOSBox Author

you are using 0.72 sourcecode right ?
Older versions might have problems with alligned memory.

Water flows down the stream
How to ask questions the smart way!

Reply 18 of 28, by Qbix

User metadata
Rank DOSBox Author
Rank
DOSBox Author

don't set it to zero. don't define it at all. You could ask the n80 porter for assistance. pupnik.de is his site.

Water flows down the stream
How to ask questions the smart way!

Reply 19 of 28, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

As Qbix says it has to be undefined, respective check for memory functions:

#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY)

If this still doesn't help:
please put some logging into DOS_PSP::MakeNew, like what sizeof(sPSP)
is and stuff like that, also removing some of the sSave calls to see which
one actually does the overwriting.