This past week was spent mostly just adding new 386-opcodes. Then by Friday evening I had reached a point in the Trekmo code where it tries to write a string to the screen. The easiest way to write to the screen in a DOS program is to call a DOS INT21 AH=09: WRITE STRING TO STANDARD OUTPUT routine. The DOS functions can not be called while in protected mode, so the PMODE header provides wrapper functions that first switch the CPU to real mode, then call the DOS function, and then switch back to protected mode. These functions are called via protected mode INT 33 (which curiously in real mode is a mouse interrupt), by giving the actual real mode interrupt number in AL register. The register values that the real mode interrupt needs as parameters are stored into memory variables for the protected mode INT 33 handler. Here below is the debug output of the "putdosmsg" routine in Trekmo.
On Saturday morning I began working on the protected mode interrupt handling. The first step was to check the contents of the Interrupt Descriptor Table (IDT) that PMODE uses, to help me in understanding the behaviour of the code. Here below is the start of the IDT table. It shows for the first 19 interrupts the segment_selector
ffset of the interrupt handler, the [Present, Descriptor Privilege Level, Gate Size] values of the descriptor, and finally in parenthesis the type of the gate. All of the IDT table entries in PMODE seem to be of the Interrupt Gate type, and they all point to a USE32 code segment.
I followed the algorithm that DOSBox uses in it's protected mode interrupt handling, but left out most of the tests for priority levels and different gate types. I need to refactor this code later, but for now I just want to get the code to work in this simplified situation in the PMODE header. After a while I managed to get the code to jump properly to the protected mode interrupt handler. The interrupt handler switched first down to 16-bit protected mode, and only then back to real mode. I did not have support in DS2x86 yet for either of these mode changes, so it took me a while to add that. By Saturday evening the code progressed all the way into the real mode DOS interrupt, and printed the string to the DS2x86 DOS text screen!
That was enough work for Saturday, so that was a good place to stop coding for a while. I was pretty happy to get that far with the protected mode interrupt handling (which I had feared to be a very complex issue) just in one day. Today I have been continuing with the code after the real mode interrupt handling, which is pretty much the reverse of the real mode interrupt call. After the real mode interrupt handler returns, PMODE header first switches to 16-bit protected mode, then sets up the GDT and IDT tables again, switches to 32-bit protected mode, and then finally returns to my Trekmo code from the INT 33 handler. I just an hour ago coded the "IRET" handling for the last step, and thus this is where I am currently at.
The next thing I need to do is to add protected mode IRQ handling. Trekmo waits for two seconds after displaying that string, before switching to graphics mode. This two second delay needs a working timer interrupt in protected mode, so I can not progress further in Trekmo until I have coded the IRQ handling. It should be relatively similar to the INT handling, though, so hopefully implementing it will not be very difficult.
I have no graphics mode support in DS2x86 yet, so I need to start working on that as soon as I get the IRQ handling done. I also soon need to start implementing the modrm bytes of the 386 opcodes properly. So far I have only implemented the few modrm bytes that I have encountered (just like I did when starting work on DSx86), so the code will not run anything besides Trekmo yet. I also need to enhance my tester program to test the 386-opcodes as well, to be sure that I have not coded a lot of bugs in them. But it is nice to see some progress all the time.