VOGONS


First post, by 286developer

User metadata
Rank Newbie
Rank
Newbie

Hi! I'm trying to run a ROM file in Dosbox bypassing the shell.

The program was part of an old embedded system I have to emulate. It runs ok in real mode but there is a problem when switching to protected mode. It prepares correctly the memory to start running tasks but when it tries to jump to the first task, it fails.

I've been debuging the code and I've found the CPU_JMP method in the cpu.cpp file. There is a switch to test the descriptor type. The type read is 0x01 (DESC_286_TSS_A), but there is no branch for this kind of descriptor so it exits with the "JMP Illegal descriptor type" message.

Is this a missing feature in Dosbox? Which modifications should be made to make it run? How do the programs made for 80286 can run in Dosbox?

Thanks for your time

Reply 1 of 7, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

Is this a missing feature in Dosbox?

Right, there's no real task switching for the 286-style descriptors implemented.

Which modifications should be made to make it run?

Not sure, but you'd certainly have to implement some pieces in CPU_SwitchTask,
and add the missing case entry for CPU_JMP (easy part). You might run into other
problems after that, or not.

Reply 3 of 7, by 286developer

User metadata
Rank Newbie
Rank
Newbie

Thanks for your fast answer!

I've been making changes to the CPU_SwitchTask method. Basicaly I have commented the 'E_Exit("286 task switch")' lines and applied the same operations used in the 386 part but using non extended registers (I mean AX instead EAX, for example) and TSS_16 descriptors. I'm not using paging mechanisms as I'm trying to emulate a pure 286.

Up to now, the code is executing properly 😀

At least it runs protected tasks but I have to check if everything works fine.

Thanks for your support!

Reply 4 of 7, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

I've been making changes to the CPU_SwitchTask method. Basicaly I have commented the 'E_Exit("286 task switch")' lines and applied the same operations used in the 386 part but using non extended registers (I mean AX instead EAX, for example) and TSS_16 descriptors.

Yes that may be enough, i've checked the io protections and they already have
the correct 286/386 tss check there, but things like that may pop up elsewhere
and are hard to figure out.

Reply 5 of 7, by 286developer

User metadata
Rank Newbie
Rank
Newbie

Hi! I've modified the CPU_CALL method on the cpu.cpp file adding the DESC_286_TSS_A case on the DESC_386_TSS_A branch. This works fine for the type 0x01 descriptor.

Now I've found another problem: the DESC_TASK_GATE (0x05) descriptor. I have found a 0x9A opcode that uses this kind of descriptor and there is no "case" for it, so it throws an error ("CALL:Descriptor type DESC_TASK_GATE unsupported")

The 0x9A opcode is a CALL to direct intersegment via task gate, as specified on the 80286 manual.

Is this code implemented elsewhere? How should I treat this case to make it work?

Thanks in advance.

Reply 6 of 7, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

Is this code implemented elsewhere? How should I treat this case to make it work?

No it is not implemented, not sure how exactly CALLing a task gate would work
but you can start with the code for DESC_TASK_GATE in CPU_Interrupt() and
check differences in the intel/amd manuals and bochs sources.