;**********************************************************
;NASM Assembler Project File
BITS 16			    ;Set code generation to 16 bit mode

SEGMENT .text		;Main code segment
                    
global start                           ;define entry point
start:

    cli                                 ;disable enterupts while switching to PMODE

    mov   ax,1000h
    mov   ds,ax

    lgdt  [gdt_desc]                     ; Load the GDT descriptor

    mov   eax, cr0                        ; Copy the contents of CR0 into EAX
    or    eax, 1                           ; Set bit 0
    mov   cr0, eax                        ; Copy the contents of EAX into CR0

    jmp   08h:clear_pipe                  ; Jump to code segment, offset clear_pipe


BITS 32			                    ;Set code generation to 32 bit mode
;**********************************************************
;     Purpose: setup segment selectors for protected mode, call kernel
clear_pipe:
        mov ax, 10h             ; stack segment identifyer
        mov ss, ax              ; Move a valid data segment into the stack segment register
        mov esp, 090000h        ; Move the stack pointer to 090000h

        mov ax, 20h             ; data segment identifyer
        mov es, ax              ; Move a valid data segment into the es segment register

        mov ax, 18h             ; video segment identifyer
        mov ds, ax              ; Move a valid video segment into the ds segment register
                                ;   writing to video RAM w/o interupts
    
vid_out1:                       ;confirm we are in 32-bit protected-mode w/ ouput
        mov   ax,0001h
        extern ax_vid_32
        call  ax_vid_32

        extern main       ;eventually we call kernel here!
        call   main

vid_out2:                       ;confirm we returned from main
        mov   ax,0003h
        call  ax_vid_32
        
hang:
        jmp hang                ; Loop, self-jump


SEGMENT .data		;Initialised data segment

gdt:                    ; Address for the GDT

gdt_null:               ; Null Segment
        dd 0
        dd 0

gdt_code:               ; Code segment, read/execute, nonconforming
        dw 0FFFFh
        dw 0
        db 01h
        db 10011010b
        db 11001111b
        db 0

gdt_stack:              ; stack segment, read/write, expand down
        dw 0FFFFh
        dw 0
        db 00h
        db 10010010b
        db 11001111b
        db 0

gdt_color_video:        ; Color Video segment, read/write, expand down
        dw 0FA0h
        dw 8000h
        db 0Bh
        db 10010010b
        db 01000000b
        db 0

gdt_data:               ; data segment, read/write, expand down
        dw 0FFFFh
        dw 0000h
        db 01h
        db 10010010b
        db 01000000b
        db 0
        
gdt_end:                ; Used to calculate the size of the GDT

gdt_desc:                       ; The GDT descriptor
        dw gdt_end - gdt - 1    ; Limit (size)
        dd 10000h + gdt         ; Address of the GDT

SEGMENT .bss	  ;Uninitialised data segment
