switch_to_rm:
mov eax,cr0 ; get CPU control register
; 286 will resume execution @ 0xF000:FFF0
; 386 will fall through.
lidt [reset_IDTR]
; restore real-mode compatible value
; * * * mandatory * * *
; real-mode interrupts are relocatable
; on the 386 via the IDT register!
and eax,0xfffffffe ; clear protected mode bit
mov cr0,eax ; now, the cpu is out of protected-mode
;----------------------------------------------------------------------------
xor eax,eax ; a convenient zero
mov cr3,eax ; Flush the TLB
;----------------------------------------------------------------------------
mov eax, 0x0000 ; zero segment for app16
;mov eax, 0x1000 ; zero segment for kernel
mov ds, ax
mov gs, ax
mov es, ax
mov cs, ax
nop ; flush prefetch queue
jmp app16_addr ; jump into real-mode application !!!!!!DOES NOT WORK!!!!!!!
nop ;
;----------------------------------------------------------------------------
reset_IDTR:
dw 0
dw 0
This part doesn't work properly as I always get a "triple fault", which resets the CPU but doesn't force the InstructionPointer to point to app16_addr, instead it points to the BIOS, which loads the MBR again at 0x7c00.