Well, unreal is simple real mode with 4GB segments. None of recent processors have real real mode; they emulate them by special 64k GDT entries. If you change that entries, you'll have unreal mode.
For real mode, it's a bit difficult: you have to fill up PIC registers correct real mode values, and GDT with correct entries.
Protmode code segment:
db 66h, 0eah, Back, RealCS
Real Mode segment (RealCS):
Back:
cli
mov ax, RealDS ; switch back to real mode
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
mov eax, CR0
and al, not 9
mov CR0, eax
jmp far RealSeg, realcs ; load real mode segment into cs
realcs: xor ax, ax
mov ss, ax
mov sp, 1000h
call RestoreIDT
call RestorePIC
RestoreIDT uses lidt to load previously saved state into idt register.
RestoreIDT Proc
lidt Real_IDT_Value
ret
RestoreIDT Endp
RestorePIC does the same:
RestorePIC Proc
push ax dx
mov dx, 0870h ; IRQ -> int 08h, 70h
call SetPIC
mov al, Old_Mask0 ; restore old values
out 21h, al
mov al, Old_Mask1
out 0a1h, al
in al, 60h ; read from keyboard to desire PIC
pop dx ax
ret
RestorePIC Endp
The SetPIC procedure:
SetPIC Proc
; reallocation of IRQ 0-7. hardware interrupts
mov al, 10001b ; ICW1 Bit 0: in PC ICW4 required too
out 20h, al
mov al, dh ; ICW2: new base address of master IRQs
out 21h, al
mov al, 100b ; ICW3: master+slave: irq 2
out 21h, al
mov al, 1 ; ICW4: Bit 0: indicates 8086 mode
out 21h, al ; Bit 1: EOI (0=non automatic)
; IRQ 8-15. hardware interrupts
mov al, 10001b ; ICW1
out 0a0h, al
mov al, dl ; ICW2: new address of slave IRQs
out 0a1h, al
mov al, 10b ; ICW3: master+slave: irq 9
out 0a1h, al
mov al, 1 ; ICW4
out 0a1h, al
ret
SetPIC Endp
That's all
Turdus, developer os OS/42