13 mov fs, ax ; this will store the original real mode segment
15 ; modify the return to real mode jump segment
16 mov [.jmpcs16 + 3], ax
21 ; check for VM86 and abort
33 ; calculate GDT linear address
37 mov [tmpsegbase], eax ; save segment base
41 ; set tmp segment bases to match the linear address of our current seg
45 mov word [gdt + 18h + 2], ax ; tmp pm code base
46 mov word [gdt + 20h + 2], ax ; tmp pm data base
47 mov word [gdt + 28h + 2], ax ; ret-to-realmode code
49 mov byte [gdt + 18h + 4], al
50 mov byte [gdt + 20h + 4], al
51 mov byte [gdt + 28h + 4], al
65 .pm: mov ax, 20h ; tmp data selector
68 mov ax, 10h ; dest data selector
83 jmp 42h:.loadcs16 ; 42 seg is modifed at the start (TODO)
93 str_errvm86 db 'Error: memory manager detected! Stop it and try again (e.g. emm386 off)',10,0
94 str_enterpm db 'Entering 32bit protected mode ...',10,0
101 call printstr ; print "Enable A20 line ... "
113 .done: mov si, .okstr
117 .infomsg db 'Enable A20 line:',0
118 .failstr db ' failed.',10,0
119 .okstr db ' success.',10,0
121 ; CF = 1 if A20 test fails (not enabled)
140 .done: mov [ds:si], dl
153 .info db ' fast ...',0
155 KBC_DATA_PORT equ 0x60
156 KBC_CMD_PORT equ 0x64
157 KBC_STATUS_PORT equ 0x64
158 KBC_CMD_WR_OUTPORT equ 0xd1
160 KBC_STAT_IN_FULL equ 2
166 mov al, KBC_CMD_WR_OUTPORT
170 out KBC_DATA_PORT, al
172 .info db ' kbd ...',0
175 in al, KBC_STATUS_PORT
176 and al, KBC_STAT_IN_FULL
184 cmp al, 10 ; check for line-feed and insert CR before it
199 enterpm dd 0xbad00d ; space for linear address for far jump to pmode
200 enterpm_sel dw 8 ; selector for far jump to protected mode
202 gdt_lim dw 47 ; GDT limit
203 gdt_base dd 0xbadf00d ; space for GDT linear address
206 gdt: ; 0: null segment
209 ; 1: code - 0/lim:4g, G:4k, 32bit, avl, pres|app, dpl:0, type:code/non-conf/rd
212 ; 2: data - 0/lim:4g, G:4k, 32bit, avl, pres|app, dpl:0, type:data/rw
215 ; 3: tmp code (will set base before entering pmode)
218 ; 4: tmp data (will set base before entering pmode)
221 ; 5: return to real-mode 16bit code segment
226 ; vi:set ts=8 sts=8 sw=8 ft=nasm: