Here some FASM code to digest:
Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; VideoModeInt - Uses interrupt 10h from real mode to change text modes
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
VideoModeInt:
pushad
push es
mov word [RealModeAX],ax
mov word [RealModeBX],bx
mov word [RealModeCX],cx
mov word [RealModeDX],dx
;; Need to save our stack stuff
mov eax,esp
mov [ProtectedModeStackPointer],eax
mov byte [RealModeError],0
call DisableAllIRQs ; Turn off every IRQ (bitmap is 0FFFFFFFFh or all off)
mov al,11h
out 020h,al
out 0A0h,al
mov al,08h
out 021h,al
mov al,070h
out 0A1h,al
mov al,4
out 021h,al
mov al,2
out 0A1h,al
mov al,1
out 021h,al
out 0A1h,al
jmp 28h:RealModeVGA
use16
RealModeVGA:
mov ax,30h
mov ds,ax
mov ss,ax
nop
mov bx,[RealModeCS]
push bx
lea bx,[DoVideoRealMode]
push bx
mov eax,cr0
and al,0xFE
mov cr0,eax
retf
DoVideoRealMode:
mov ax,cs ; Save CS to AX
mov ds,ax ; Put DS to CS
mov ax,[StackSegment] ; Save original stack segment to AX
mov ss,ax ; Replace original stack segment
mov ax,[StackPointer] ; Save the stack pointer to AX
movzx esp,ax ; and Replace original stack pointer (force 16 bit)
nop ; Take a CPU clock tick
mov es,ax ; Update ES with AX
mov fs,ax ; Update FS with AX
mov gs,ax ; Update GS with AX
;;;;;;;;;;;;;;;;;;;;;;;
;; Load real mode IDTR
;;;;;;;;;;;;;;;;;;;;;;;
lidt [RIDTR] ; Load original IVT from 0000:0000
push cs ; Put CS on stack
pop ds ; Put CS from stack to DS
push ds ; Save DS to the stack
pop es ; Update ES with DS from stack
mov al,0 ; Re-enable realmode IVT by turning on all IRQs
out 0A1h,al ; Updates lower 7 IRQs
out 021h,al ; Updates upper 8 IRQs
sti ; Re-enable interrupts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Now to do the real mode interrupt
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov ax,word [RealModeAX]
mov bx,word [RealModeBX]
mov cx,word [RealModeCX]
mov dx,word [RealModeDX]
int 10h
jnc .NoError
mov byte [RealModeError],1
.NoError:
mov word [RealModeAX],ax
mov word [RealModeBX],bx
mov word [RealModeCX],cx
mov word [RealModeDX],dx
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Going back to Protected Mode
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
cli ; Turn off interrupts
lgdt [GDTR] ; Load GDTR
lidt [IDTR] ; Load IDTR
mov eax,cr0
or al,1
mov cr0,eax
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Jump to Protected Mode
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
jmp 10h:ReturnToProtectedMode
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 32-bit Protected Mode
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
use32
ReturnToProtectedMode:
mov ax,18h
mov ds,ax
mov es,ax
nop
mov fs,ax
mov gs,ax
mov ax,08h
mov es,ax
mov ss,ax
mov eax,[ProtectedModeStackPointer]
mov esp,eax ; Re-establish our ESP
mov al,0FFh ; Disable realmode IVT by turning on all IRQs
out 0A1h,al ; Updates lower 7 IRQs
out 021h,al ; Updates upper 8 IRQs
call RemapPIC ; Remap to smiddyOS
call EnableAllIRQs ; Enabled already mapped IRQs
sti ; Turn them interrupts back oh, honky!
pop es
popad
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Data
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
RealModeError db 0
RealModeAX dw 0
RealModeBX dw 0
RealModeCX dw 0
RealModeDX dw 0
ProtectedModeStackPointer dd 0
Questions?