[bits 16]
[org 0]




start:
   mov ax,cs
   mov ds,ax
   mov es,ax

   mov ah,03
   mov bh,0
   int 10h

; DEBUG
   mov ax,0xb800            ; Load gs to point to video memory
   mov gs,ax        ; We intend to display a brown A in real mode
   mov word [gs:0],0x641   ; display
   cli              ; Clear or disable interrupts
   lgdt[gdtr]       ; Load GDT
   mov eax,cr0      ; The lsb of cr0 is the protected mode bit
   ;or al,0x01       ; Set protected mode bit
   or al,0x00       ; Set protected mode bit
   mov cr0,eax      ; Mov modified word to the control register

;loop:
;mov al,'Z'
;mov ah,0eh
;int 10h
;jmp loop

   jmp codesel:go_pm

bits 32
go_pm :
   mov ax,datasel
   mov ds,ax           ; Initialise ds & es to data segment
   mov es,ax
   mov ax,videosel             ; Initialise gs to video memory
   mov gs,ax
   mov word [gs:0],0x741 ; Display white A in protected mode

   mov esp, stack + STACKSIZE         ; set up the stack
   push eax                            ; Multiboot magic number
   push ebx                            ; Multiboot info structure

;loop:jmp loop

;loop:
;mov al,'+'
;mov ah,0eh
;int 10h
;jmp loop

   mov eax,cr0
   and al,0feh
   mov cr0,eax

   ;db 0eah
   ;dw rmode
   ;dw Code
   ;jmp short rmode

[BITS 16]
rmode: 
   clc
   sti

   mov ax,cs
   mov ds,ax
   mov es,ax
   mov ax,0x7000
   mov ss,ax       ; stack segment initialisation
   mov sp,ss

   jmp 0x1000:0

gdtr :
   dw gdt_end-gdt-1      ; Length of the gdt
   dd gdt                      ; physical address of gdt
gdt :
nullsel equ $-gdt           ; $->current location,so nullsel = 0h
gdt0 :                 ; Null descriptor,as per convention gdt0 is 0
   dd 0                ; Each gdt entry is 8 bytes, so at 08h it is CS
   dd 0                      ; In all the segment descriptor is 64 bits
codesel equ $-gdt              ; This is 8h,ie 2nd descriptor in gdt
code_gdt :                     ; Code descriptor 4Gb flat segment at 0000:0000h
   dw 0x0ffff          ; Limit 4Gb  bits 0-15 of segment descriptor
   dw 0x0000           ; Base 0h bits 16-31 of segment descriptor (sd)
   db 0x00                  ; Base addr of seg 16-23 of 32bit addr,32-39 of sd
   db 0x09a            ; P,DPL(2),S,TYPE(3),A->Present bit 1,Descriptor                                ; privilege level 0-3,Segment descriptor
   db 0x0cf            ; Upper 4 bits G,D,0,AVL ->1 segment len is page                                              ; granular, 1 default opera
                              ; Lower nibble bits 16-19 of segment limit
   db 0x00             ; Base addr of seg 24-31 of 32bit addr,56-63 of sd
datasel equ $-gdt              ; ie 10h, beginning of next 8 bytes for data sd
data_gdt :                     ; Data descriptor 4Gb flat seg at 0000:0000h
   dw 0x0ffff          ; Limit 4Gb
   dw 0x0000           ; Base 0000:0000h
   db 0x00             ; Descriptor format same as above
   db 0x092
   db 0x0cf
   db 0x00
videosel equ $-gdt             ; ie 18h,next gdt entry
   dw 3999             ; Limit 80*25*2-1
   dw 0x8000           ; Base 0xb8000
   db 0x0b
   db 0x92             ; present,ring 0,data,expand-up,writable
   db 0x00             ; byte granularity 16 bit
   db 0x00
gdt_end :

STACKSIZE equ 1024 * 16

stack: resb STACKSIZE
