<commit_before>;
; boot2.nasm
;

ORG 0x800
BITS 16

start:
    mov esp, 0x80000 ;Setup stack

    ; Let user know Boot2 has successfully loaded
    mov si, bootWelcome
    call Print

    ; Turn on A20
    call FlipA20
    jnc .A20success
    mov si, error_A20
    call Print
    jmp Hang
.A20success:

    ; Detect Memory
    call DetectUpperMemory
    jnc .MemSuccess
    mov si, error_memory
    call Print
    jmp Hang
.MemSuccess:

    ; Load GDT
    call LoadGDT
    jnc .GDTSuccess
    mov si, error_GDT
    call Print
    jmp Hang
.GDTSuccess:

    ; Enter Protected Mode
    jmp EnterProtected ;After entering protected, will jump to start_32

Hang:
    cli
    hlt
    jmp Hang

Print:
    ; Prints message to screen
    ;  Store string pointer in SI
    ;  String must be null-terminated
    ;  Does not check if message will run off bottom of screen

    mov bl, 0Fh ; White on Black
    mov cx, 1
    mov dh, [.CurrentLine]
    xor dl, dl
    xor bh, bh
.print_loop:
    ; Set cursor position
    mov ah, 02h
    int 10h

    ; Write Character
    mov ah, 09h
    mov al, [si]
    int 10h

    inc si
    inc dl
    cmp dl, 80
    jne .checknull
    inc dh
    xor dl, dl
.checknull:
    cmp byte [si], 0
    jne .print_loop

    inc dh
    mov [.CurrentLine], dh
    ret
.CurrentLine db 0

FlipA20:
    ; Sets the A20 gate using the BiOS interrupt
    ;  No input
    ;  Carry flag set on error. BiOS errorcode in AH.
    mov ax, 0x2401
    int 15h ;BiOS will already set carry flag on error and set AH.
    ret

DetectUpperMemory:
    ; Detect Upper Memory using BiOS interrupt
    ;  No input
    ;  Stores memory list at 0x1000 (up to 0x2000)
    ;  Carry flag set on error, BiOS errorcode in AH.

    ; Initialization
    xor ebx, ebx
    mov edx, 0x534D4150
    mov eax, 0xE820
    mov ecx, 0x18 ;24 bytes
    xor bp, bp ;Entry count
    mov di, 0x30000 ;Buffer
    clc

    ; First Call
    int 0x15
    jc .failMem
    cmp eax, 0x534D4150
    jne .failMem

    ; Subsequent Calls
.call_e820:
    mov eax, 0xe820
    mov ecx, 0x18
    inc bp
    add di, 0x18
    int 0x15
    jc .done

.done:
    clc
    ret

.failMem:
    stc
    ret

LoadGDT:
    ; Sets up a temporary GDT before (necessary before entering protected mode)
    ;  Sets carry flag if error (should never happen)
    lgdt [gdt_desc]
    clc<commit_msg>Bootloader now correctly loads memory map<commit_after>;
; boot2.nasm
;

ORG 0x800
BITS 16

start:
    mov esp, 0x80000 ;Setup stack

    ; Let user know Boot2 has successfully loaded
    mov si, bootWelcome
    call Print

    ; Turn on A20
    call FlipA20
    jnc .A20success
    mov si, error_A20
    call Print
    jmp Hang
.A20success:

    ; Detect Memory
    call DetectUpperMemory
    jnc .MemSuccess
    mov si, error_memory
    call Print
    jmp Hang
.MemSuccess:

    ; Load GDT
    call LoadGDT
    jnc .GDTSuccess
    mov si, error_GDT
    call Print
    jmp Hang
.GDTSuccess:

    ; Enter Protected Mode
    jmp EnterProtected ;After entering protected, will jump to start_32

Hang:
    cli
    hlt
    jmp Hang

Print:
    ; Prints message to screen
    ;  Store string pointer in SI
    ;  String must be null-terminated
    ;  Does not check if message will run off bottom of screen

    mov bl, 0Fh ; White on Black
    mov cx, 1
    mov dh, [.CurrentLine]
    xor dl, dl
    xor bh, bh
.print_loop:
    ; Set cursor position
    mov ah, 02h
    int 10h

    ; Write Character
    mov ah, 09h
    mov al, [si]
    int 10h

    inc si
    inc dl
    cmp dl, 80
    jne .checknull
    inc dh
    xor dl, dl
.checknull:
    cmp byte [si], 0
    jne .print_loop

    inc dh
    mov [.CurrentLine], dh
    ret
.CurrentLine db 0

FlipA20:
    ; Sets the A20 gate using the BiOS interrupt
    ;  No input
    ;  Carry flag set on error. BiOS errorcode in AH.
    mov ax, 0x2401
    int 15h ;BiOS will already set carry flag on error and set AH.
    ret

DetectUpperMemory:
    ; Detect Upper Memory using e820 BIOS call
    ;  No input
    ;  Stores memory list at 0x30000 (not past 0x40000)
    ; Carry flag set on error, BIOS errorcode in AH

    ; Initialization
    xor ebx, ebx
    mov ax, 0x3000
    mov es, ax
    xor di, di

.call_e820:
    ; Set registers (assume these are trashed)
    mov edx, 0x534D4150 ; Magic Number
    mov eax, 0xe820 ; BIOS code
    mov ecx, 24 ; Always ask for 24 bytes

    ; Zero where memory map should go
    mov dword [es:di],    0
    mov dword [es:di+4],  0
    mov dword [es:di+8],  0
    mov dword [es:di+12], 0
    mov dword [es:di+16], 0
    mov dword [es:di+20], 1 ; Ensure valid ACPI code

    ; Clear Carry Flag
    clc

    ; Make BIOS call
    int 15h

    ; If carry flag is set, function is done
    ;  (this could be an error, eax must be checked)
    jc .done

    ; If EBX == 0, function completed successfully
    test ebx, ebx
    je .done

    ; Make sure the count is not too large
    add di, 24
    cmp bp, 1300
    jg .large

    ; Do it again
    jmp .call_e820

.large:
    ; Set "too large" flag
    mov eax, [0x38000]
    or eax, 0x1
    mov [0x38000], eax

    ; return as "success" (let kernel deal with it)
    clc
    ;jmp .done ; Let it fall through

.done:
    ; If eax == Magic, function exited successfully
    cmp eax, 0x534D4150
    jne .fail
    clc
    ret

.fail:
    ; Error code will already be in ah from BIOS
    ; Call count will be in bp
    stc
    ret

LoadGDT:
    ; Sets up a temporary GDT before (necessary before entering protected mode)
    ;  Sets carry flag if error (should never happen)
    lgdt [gdt_desc]
    clc
{'fraction_non_alphanumeric': 0.05680388279705195, 'fraction_numerical': 0.04476002157109473, 'mean_word_length': 2.0723357261181667, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6134071', 'n_tokens_mistral': 2194, 'n_tokens_neox': 1932, 'n_words': 782}