270 lines
5.6 KiB
NASM
270 lines
5.6 KiB
NASM
; -----------------------------------------------------------------------
|
|
;
|
|
; Copyright 2010 Gene Cumm
|
|
;
|
|
; Portions from diskstart.inc:
|
|
; Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
|
|
; Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
|
|
;
|
|
; This program is free software; you can redistribute it and/or modify
|
|
; it under the terms of the GNU General Public License as published by
|
|
; the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
|
; Boston MA 02110-1301, USA; either version 2 of the License, or
|
|
; (at your option) any later version; incorporated herein by reference.
|
|
;
|
|
; -----------------------------------------------------------------------
|
|
|
|
;
|
|
; geodsp1s.asm
|
|
;
|
|
; Display geometry translation info for diagnosing misconceptions
|
|
; 1 sector variant
|
|
;
|
|
; nasm -Ox -f bin -o geodsp.bin -l geodsp.lst geodsp.asm
|
|
;
|
|
; nasm -Ox -f elf -o geodsp.o -l geodsp.lst geodsp.asm
|
|
; ld -m elf_i386 -T syslinux.ld -M -o geodsp.elf geodsp.o > geodsp.map
|
|
; objcopy -O binary geodsp.elf geodsp.raw
|
|
;
|
|
; # OF=/dev/sdb
|
|
; # dd if=core/geodsp.bin of=$OF
|
|
; # dd skip=1 seek=1 if=../dbg/lba-img/lba-img.bin of=$OF
|
|
; # eject $OF
|
|
; # dd count=$() if=/dev/zero of=$OF
|
|
;
|
|
; # OF=geo-2.255.63.i
|
|
; # (dd if=core/geodsp.bin; dd skip=1 if=../dbg/lba-img/lba-img.bin; dd count=$((2*255*63 - 256*63 - 1)) if=/dev/zero )|dd of=$OF
|
|
; # OF=geo-20.16.63.i
|
|
; # (dd if=core/geodsp.bin; dd skip=1 if=../dbg/lba-img/lba-img.bin; dd count=$((40*16*63 - 256*63 - 1)) if=/dev/zero )|dd of=$OF
|
|
;
|
|
|
|
%include "macros.inc"
|
|
; %include "layout.inc"
|
|
|
|
; global STACK_LEN, STACK_TOP, STACK_BASE
|
|
; STACK_LEN equ 4096
|
|
STACK_TOP equ 7c00h
|
|
; STACK_BASE equ STACK_TOP - STACK_LEN
|
|
|
|
StackBuf equ STACK_TOP-44-92 ; Start the stack here (grow down - 4K)
|
|
DriveNumber equ StackBuf-4 ; Drive number
|
|
m_CHS0 equ 00534843h ;'CHS',0
|
|
m_EDD0 equ 00444445h ;'EDD',0
|
|
m_EDD_SP equ 20444445h ;'EDD '
|
|
retry_count equ 16
|
|
dbuf equ 8000h
|
|
int13_ret equ 7e00h
|
|
|
|
|
|
|
|
; extern real_mode_seg
|
|
; section .real_mode write nobits align=65536
|
|
; global core_real_mode
|
|
; core_real_mode resb 65536
|
|
; extern xfer_buf_seg
|
|
; section .xfer_buf write nobits align=65536
|
|
; global core_xfer_buf
|
|
; core_xfer_buf resb 65536
|
|
|
|
section .text
|
|
org STACK_TOP
|
|
|
|
|
|
global _start
|
|
bootsec equ $
|
|
_start:
|
|
; In case we want to pull more of the standard diskstart stuff in
|
|
; jmp short start ; 2 bytes
|
|
; nop ; 1 byte
|
|
start:
|
|
cli
|
|
cld
|
|
xor cx,cx
|
|
mov ss,cx
|
|
mov sp,StackBuf-2 ; Just below BSS (-2 for alignment)
|
|
push dx ; Save drive number (in DL)
|
|
; Kill everything else and let the BIOS sort it out later
|
|
mov es,cx
|
|
mov ds,cx
|
|
sti
|
|
|
|
get_geo: ; DL and ES ready
|
|
mov ah,08h
|
|
mov di,0
|
|
int 13h
|
|
write_geo:
|
|
jc .bad_geo
|
|
mov si,s_chs
|
|
call writestr_early
|
|
call write_chs
|
|
call crlf
|
|
jmp short .done
|
|
.bad_geo:
|
|
.done:
|
|
|
|
mov bx,dbuf
|
|
get_h1c: ; 0,1,1
|
|
mov cx,0001h
|
|
mov dh,01h
|
|
call getonesec_chs
|
|
call write_chs_lba
|
|
get_c1c: ; 1,0,1
|
|
mov cx,0101h
|
|
mov dh,00h
|
|
call getonesec_chs
|
|
call write_chs_lba
|
|
|
|
;
|
|
; Do we have EBIOS (EDD)?
|
|
;
|
|
edd:
|
|
.check:
|
|
mov bx,55AAh
|
|
mov ah,41h ; EDD existence query
|
|
mov dl,[DriveNumber]
|
|
int 13h
|
|
jc .noedd
|
|
cmp bx,0AA55h
|
|
jne .noedd
|
|
test cl,1 ; Extended disk access functionality set
|
|
jz .noedd
|
|
;
|
|
; We have EDD support...
|
|
;
|
|
mov bx,dbuf
|
|
xor edx,edx
|
|
mov dword [s_chs],m_EDD_SP
|
|
.get_lba63:
|
|
mov eax,63 ; Same length as mov al,64; movzx eax,al
|
|
call getonesec_ebios
|
|
jc .bad_edd ;read error
|
|
call write_edd_lba
|
|
.get_lba16065:
|
|
mov eax,16065
|
|
call getonesec_ebios
|
|
jc .bad_edd ;read error
|
|
call write_edd_lba
|
|
.good_edd:
|
|
mov dword [s_type],m_EDD0
|
|
.bad_edd:
|
|
.noedd:
|
|
.end:
|
|
|
|
write_final_type:
|
|
mov si,s_typespec
|
|
call writestr_early
|
|
|
|
jmp short kaboom
|
|
|
|
;
|
|
; getonesec_ebios:
|
|
;
|
|
; getonesec implementation for EBIOS (EDD)
|
|
;
|
|
getonesec_ebios:
|
|
mov cx,retry_count
|
|
.retry:
|
|
; Form DAPA on stack
|
|
push edx
|
|
push eax
|
|
push es
|
|
push bx
|
|
push word 1
|
|
push word 16
|
|
mov si,sp
|
|
pushad
|
|
mov ah,42h ; Extended Read
|
|
call xint13
|
|
popad
|
|
lea sp,[si+16] ; Remove DAPA
|
|
jc .error
|
|
ret
|
|
|
|
.error:
|
|
; Some systems seem to get "stuck" in an error state when
|
|
; using EBIOS. Doesn't happen when using CBIOS, which is
|
|
; good, since some other systems get timeout failures
|
|
; waiting for the floppy disk to spin up.
|
|
|
|
pushad ; Try resetting the device
|
|
xor ax,ax
|
|
call xint13
|
|
popad
|
|
loop .retry ; CX-- and jump if not zero
|
|
|
|
; Total failure.
|
|
stc
|
|
ret
|
|
|
|
;
|
|
; getonesec_chs:
|
|
;
|
|
; CX,DH specifies CHS address
|
|
;
|
|
getonesec_chs: ; We could use an xchg and get a loop
|
|
; mov cx,retry_count
|
|
.retry:
|
|
pushad
|
|
mov ax,0201h ; Read one sector
|
|
call xint13
|
|
popad
|
|
jc .error
|
|
ret
|
|
|
|
.error:
|
|
; loop .retry
|
|
; Fall through to disk_error
|
|
;
|
|
; kaboom: write a message and bail out.
|
|
;
|
|
global kaboom
|
|
disk_error:
|
|
kaboom:
|
|
.patch:
|
|
mov si,bailmsg
|
|
call writestr_early
|
|
xor eax,eax
|
|
.again: int 16h ; Wait for keypress
|
|
; NB: replaced by int 18h if
|
|
; chosen at install time..
|
|
int 19h ; And try once more to boot...
|
|
.norge: hlt ; If int 19h returned; this is the end
|
|
jmp short .norge
|
|
|
|
;
|
|
; INT 13h wrapper function
|
|
;
|
|
xint13:
|
|
mov dl,[DriveNumber]
|
|
int 13h
|
|
mov [int13_ret],ax
|
|
ret
|
|
|
|
;
|
|
;
|
|
; writestr_early: write a null-terminated string to the console
|
|
; This assumes we're on page 0. This is only used for early
|
|
; messages, so it should be OK.
|
|
;
|
|
writestr_early:
|
|
pushad
|
|
.loop: lodsb
|
|
and al,al
|
|
jz .return
|
|
call writechr
|
|
jmp short .loop
|
|
.return: popad
|
|
ret
|
|
|
|
%include "geodsplib.inc"
|
|
bailmsg equ s_end
|
|
|
|
; This fails if the boot sector overflowsg
|
|
zb 1BEh-($-$$)
|
|
|
|
ptable zb 40h ; Partition table
|
|
|
|
bootsignature dw 0xAA55
|
|
|
|
sector_2:
|