[haiku-development] mbrstub.asm for boot menu

;
; Haiku-OS Boot
; MBR Stub - The stub is used if boot menu is unnecessary
; Must be compiled as DOS COM
; Copyright (C) 2008 Ruslan Nikolaev
;
    .MODEL TINY
    .CODE
    .486
    ORG 7C00h                   ; BIOS loads the sector to this address
disk_addr_packet EQU 7A00h
drive_params EQU 7B00h
; Entry point
start:
    cli                         ; disable interrupts
    xor dh,dh                   ; DH = 0 (clear higher word of DH just in case)
    jmp 0h,mbrstub_init
; Partition sector (offset 0x8)
partition_sector DD 0,0
; Initialization
mbrstub_init:
    xor ax,ax
    mov ds,ax                   ; DS = 0h
    mov ah,30h
    mov ss,ax                   ; SS = 3000h
    mov es,ax                   ; ES = 3000h
    mov sp,7000h                ; SP = 7000h
    sti                         ; enable interrupts
    mov cx,100h                 ; copy 2x256 bytes
    mov si,7C00h                ; SI = 7C00h
    mov di,si                   ; DI = 7C00h
    cld
    rep movsw
    mov ds,ax                   ; set DS = 3000h
    jmp 3000h, mbrstub_main
; Program
mbrstub_main:
    test dx,80h
    jnz @F
    mov dx,80h                  ; fix BIOS bug
@@: mov ax,4100h                ; EDD installation check
    mov bx,55AAh
    push dx
    int 13h
    pop dx                      ; keep DX
    cmp bx,0AA55h
    jne edd_error
    mov si,drive_params
    mov WORD PTR [si],1Ah       ; size of the buffer
    mov WORD PTR [si+18h],100h  ; put 512-bytes as a sector size (just in case)
    mov WORD PTR [si+2h],0h     ; flags (reset just in case)
    mov ax,4800h                ; EDD get drive parameters
    push dx
    int 13h
    mov ax,[si+18h]
    mov bx,ax                   ; keep sector size here
    add ax,511                  ; always read at least 512 bytes
    xor dx,dx
    div bx                      ; AX = number of blocks to transfer
    pop dx                      ; restore DX
    mov si,disk_addr_packet
    mov WORD PTR [si],10h       ; size of the packet + reserved byte
    mov [si+2h],ax              ; put number of blocks to transfer
    xor ax,ax
    mov [si+6h],ax              ; transfer buffer (SEGMENT) = 0h
    mov WORD PTR [si+4h],7C00h  ; transfer buffer (OFFSET) = 7C00h
    mov eax,[partition_sector]
    mov [si+8h],eax
    mov eax,[partition_sector+4]
    mov [si+0Ch],eax
    mov ax,4200h                ; EDD read
    push dx
    int 13h
    pop dx
    test ah,ah
    jnz read_error
; Jump to the partition loader
    cli                         ; disable interrupts
    xor ax,ax
    mov es,ax                   ; ES = 0
    mov ds,ax                   ; DS = 0
    mov ss,ax                   ; SS = 0
    sti                         ; enable interrupts
    jmp 0h,7C00h
; EDD error
edd_error:
    mov si,OFFSET edd_error_string
    mov cx,edd_error_string_len
    jmp print_error
edd_error_string DB "ERROR: EDD does not work."
edd_error_string_len EQU $ - edd_error_string
; Read error
read_error:
    mov si,OFFSET read_error_string
    mov cx,edd_error_string_len
    jmp print_error
read_error_string DB "ERROR: boot fault."
read_error_string_len EQU $ - read_error_string
; Error (SI: string, CX: length)
print_error:
    cld            ; DF = 0 (do it all the time; just in case)
    lodsb
    mov ah,0Eh     ; print in teletype mode
    mov bx,0003h   ; bh: page, bl: attribute (light grey)
    int 10h
    loop print_error
@@: jmp @B         ; halt the system
; ---------------------------
; Should not exceed 256 bytes
; ---------------------------
; Reserved area
    ORG start+1B8h ; adjust PC
    DB 70 DUP(?)   ; MBR table
    DW 55AAh       ; MBR signature
    END start



      

Other related posts:

  • » [haiku-development] mbrstub.asm for boot menu - R Nikolaev