awik wrote:alexfru wrote:If you're still interested in virtual 8086 mode,
I am, but first I need to get the PM entry and exit right. In fact, I don't need only to get it right, I need to *understand* it as fully as I can.
It's not secret information. See sections "9.9.1 Switching to Protected Mode" and "9.9.2 Switching Back to Real-Address Mode" of "Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 3 (3A & 3B): System Programming Guide".
I encourage you to read those sections and all relevant sections of the manual as well. Don't be shy to use your PDF reader's search function to find and learn more about each unfamiliar term or register.
awik wrote:In addition, I need to understand how to reflect interrupts to real or V86 mode.
See "CHAPTER 17 8086 Emulation" of the same manual.
awik wrote:
I did. It is shorter than I expected. But I don't understand it as good as I need to.
I moved #GP and IRQ handling into separate tasks. They are invoked as nested/linked tasks, that is, they preempt whatever the current task happens to be (usually the v86 task) to handle #GP or an IRQ. It's a bit easier/cleaner to read/write fields in a TSS than somewhere on the stack. In particular, it's easier to set up virtual 8086 mode in a task than on the stack.
Even though these #GP and IRQ handler tasks "return" (with iretd), they are still tasks and their subsequent invocation starts them where they left off last time, that is, after iretd, which is why you can see loops in _isr_20_wrapper ... _isr_2F_wrapper and _isr_0D_wrapper.
gpf_handler() and irq_handler() reflect the various int instructions (int3, int n, into) and IRQs for handling back into the v86 task.
gpf_handler() also intercepts calls to BIOS int 15h function 87h to copy memory and handles them by itself. It makes himem.sys work (the original handler of int 15h function 87h would try to enter protected mode and fail).
awik wrote:In a debugger, I tried reading from port 0x70, and it came back with value 0x0C. If the port is not readable, shouldn't I get 0xFF (bus float?)?
I'm afraid, there's no guarantee for a port that's not supposed to be read to read as anything specific, even if you have reasonable expectations as to how it may be implemented. Much like undefined behavior in C/C++.