DEADSOFTWARE

boot0: add alternative method to get memory size for older machines
[bmbb.git] / Boot486 / boot0.S
index 21608cbc66d797064902c57826ca8fb215702b46..efc93c93af85ff4de898bc4409353cf0df509c57 100644 (file)
 .set BootDiskDxAdr, 0x7e06
 .set BootDiskCxAdr, 0x7e08
 .set MemoryMapAdr, 0x7e0A
-.set ImageBase, 0x1000000
+.set ImageBase, 0x100000
 
 # =========================================================================== #
 # Stage 1
 # =========================================================================== #
 
-.code16
 _start:
+
+.code16
 stage1:
 # 1. Setup canonical %cs:%eip, segment registers %ds, %es, %fs, %gs, %ss and stack %sp
        cli
@@ -41,10 +42,10 @@ stage1:
 
        mov %dx, BootDiskAdr
        call mapmem
+       sti
 
 # 2. Enable A20 gate
-       call enable_A20
-       sti
+       call enableA20
 
 # 3. Reset disk controller (%dl and %dh initialized by bios) and read Kernel into buffer
        movl $(kernel_code_end - kernel_code_start), KernelSizeAdr
@@ -130,30 +131,67 @@ print:
 .code16
 mapmem:
        pusha
+
        movl $0, MemoryMapAdr
        xor %ebx, %ebx
        mov $(MemoryMapAdr + 4), %di
-       mapmem__loop:
-               mov $0xe820, %eax
-               mov $20, %ecx
-               mov $0x0534D4150, %edx
-               int $0x15
-               jc mapmem__failed
-               cmp %edx, %eax
-               jne mapmem__failed
-               cmp $0, %ebx
-               je mapmem__done
-               add $20, %di
-               incl MemoryMapAdr
-               jmp mapmem__loop
-       mapmem__done:
-               popa
-               ret # <============
-       mapmem__failed:
-               mov $msg_mapmem_failed, %si
-               call print
-               cli
-               hlt
+
+mapmem_loop:
+       mov $0xe820, %eax
+       mov $20, %ecx
+       mov $0x0534D4150, %edx
+       int $0x15
+       jc mapmem_method_88
+       cmp %edx, %eax
+       jne mapmem_method_88
+       cmp $0, %ebx
+       je mapmem_done
+       add $20, %di
+       incl MemoryMapAdr
+       jmp mapmem_loop
+
+mapmem_method_88:
+       #####
+       ### function:
+       ###   int 0x15 + %ah = 0x88
+       ### input:
+       ###   none
+       ### output:
+       ###   cf clear:
+       ###     %ax = available memory starting at 0x100000 in KB
+       ###   cf set:
+       ###     %ah = error code
+       ### note:
+       ###   some bioses do not clear cf, do it manually
+        #####
+
+       movl $1,        (MemoryMapAdr + 0)  # num
+       movl $0x100000, (MemoryMapAdr + 4)  # base (low)
+       movl $0,        (MemoryMapAdr + 8)  # base (high)
+       movl $0,        (MemoryMapAdr + 12) # len (low)
+       movl $0,        (MemoryMapAdr + 16) # len (high)
+       movl $1,        (MemoryMapAdr + 20) # type
+
+        clc
+       mov $0x88, %ah
+       int $0x15
+       jc mapmem_failed
+       test %ax, %ax
+       je mapmem_failed
+       movzx %ax, %eax
+       shl $10, %eax
+       movl %eax, (MemoryMapAdr + 12) # len (low)
+       #jmp mapmem_done
+
+mapmem_done:
+       popa
+       ret # <============
+
+mapmem_failed:
+       mov $msg_mapmem_failed, %si
+       call print
+       cli
+       hlt
 
 # =========================================================================== #
 # Convert LBA to CHS
@@ -263,161 +301,39 @@ readsectors__success:
        ret
 
 # =========================================================================== #
-# Check that A20 Gate is enabled
-#   output: set zero flag if disabled
-#   restore: %ds %es
+# Enable A20 Line
 # =========================================================================== #
 
 .code16
-check_A20:
-       push %ds
-       push %es
-#      push %ax
-#      push %di
-#      push %si
-
-       xor %ax, %ax
-       mov %ax, %es
-
-       not %ax
-       mov %ax, %ds
-
-       mov $0x0500, %di
-       mov $0x0510, %si
-
-       mov %es:0(%di), %al
-       push %ax
-
-       mov %ds:0(%si), %al
-       push %ax
-
-       movb $0x00, %es:0(%di)
-       movb $0xff, %ds:0(%si)
-
-       cmpb $0xff, %es:0(%di)
-
-       pop %ax
-       mov %es:0(%di), %al
-
-       pop %ax
-       mov %es:0(%di), %al
-
-       mov $0, %ax
-
-       je check_A20__exit
-
-       mov $1, %ax
-
-check_A20__exit:
-#      pop %si
-#      pop %di
-#      pop %ax
-       pop %es
-       pop %ds
-       or %al, %al
-       ret
-
-# =========================================================================== #
-# Enable A20 Gate
-# =========================================================================== #
-
-enable_A20:
-       /* First check */
-       call check_A20
-       jnz enable_A20__success
-
-       /* BIOS method */
-       mov $0x2401, %ax
-       int $0x15
-
-       call check_A20
-       jnz enable_A20__success
-
-       /* Keyboard method 1 */
-       mov $0xd0, %al
-       out %al, $0x64
-
-       call check_A20
-       jnz enable_A20__success
-
-       /* Keyboard method 2 */
-/*
-#      cli
-       
-       call enable_A20__wait1
-       mov $0xad, %al
-       out %al, $0x64
 
-       call enable_A20__wait1
-       mov $0xd0, %al
-       out %al, $0x64
-
-       enable_A20__wait2:
+enableA20:
+       cli
+       xor %cx, %cx
+enableA20_1:
+       inc %cx
+       jz enableA20_3
        in $0x64, %al
-       test $1, %al
-       jz enable_A20__wait2
-
-       in $0x60, %al
-       push %eax
-
-       call enable_A20__wait1
+       test $0x2, %al
+       jnz enableA20_1
        mov $0xd1, %al
        out %al, $0x64
-
-       call enable_A20__wait1
-       pop %eax
-       or $2, %al
-       out %al, $0x64
-
-       call enable_A20__wait1
-       mov $0xae, %al
-       out %al, $0x64
-
-       call enable_A20__wait1
-#      sti
-
-#      call check_A20
-#      jnz enable_A20__success
-*/
-
-       /* Control port A method */
-       mov $1, %al
-       out %al, $0x92
-
-       call check_A20
-       jnz enable_A20__success
-
-       /* Fast method */
-       in $0xee, %al
-
-       call check_A20
-       jnz enable_A20__success
-
-       mov $msg_a20_failed, %si
-       call print
-#      cli
-#      hlt
-
-enable_A20__success:
-       ret
-
-/*
-enable_A20__wait1:
+enableA20_2:
        in $0x64, %al
-       test $2, %al
-       jnz enable_A20__wait1
+       test $0x2, %al
+       jnz enableA20_2
+       mov $0xdf, %al
+       out %al, $0x60
+enableA20_3:
+       sti
        ret
-*/
 
 # =========================================================================== #
 # =========================================================================== #
 # =========================================================================== #
 
 msg_mapmem_failed: .asciz "1"
-msg_a20_failed: .asciz "2"
 msg_chs_error: .asciz "3"
 msg_kernel_read_failed: .asciz "4"
-
 msg_protected_mode: .asciz ">5"
 
 current_sector: