2011-06-08 18:48:34 +00:00
|
|
|
/*
|
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS Bootsector for ISO file system
|
|
|
|
* FILE:
|
|
|
|
* PURPOSE:
|
|
|
|
* PROGRAMMERS: ?
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
|
|
|
|
#include <asm.inc>
|
2011-06-18 17:19:28 +00:00
|
|
|
#include "../freeldr/include/arch/pc/x86common.h"
|
2011-06-08 18:48:34 +00:00
|
|
|
|
|
|
|
.code16
|
|
|
|
|
|
|
|
// ****************************************************************************
|
|
|
|
//
|
|
|
|
// isolinux.asm
|
|
|
|
//
|
|
|
|
// A program to boot Linux kernels off a CD-ROM using the El Torito
|
|
|
|
// boot standard in "no emulation" mode, making the entire filesystem
|
|
|
|
// available. It is based on the SYSLINUX boot loader for MS-DOS
|
|
|
|
// floppies.
|
|
|
|
//
|
|
|
|
// Copyright (C) 1994-2001 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., 675 Mass Ave, Cambridge MA 02139,
|
|
|
|
// USA; either version 2 of the License, or (at your option) any later
|
|
|
|
// version; incorporated herein by reference.
|
|
|
|
//
|
|
|
|
// ****************************************************************************
|
|
|
|
//
|
|
|
|
// THIS FILE IS A MODIFIED VERSION OF ISOLINUX.ASM
|
|
|
|
// MODIFICATION DONE BY MICHAEL K TER LOUW
|
|
|
|
// LAST UPDATED 3-9-2002
|
|
|
|
// SEE "COPYING" FOR INFORMATION ABOUT THE LICENSE THAT APPLIES TO THIS RELEASE
|
|
|
|
//
|
|
|
|
// ****************************************************************************
|
|
|
|
//
|
|
|
|
// This file is a modified version of ISOLINUX.ASM.
|
|
|
|
// Modification done by Eric Kohl
|
|
|
|
// Last update 04-25-2002
|
|
|
|
//
|
|
|
|
// ****************************************************************************
|
|
|
|
|
|
|
|
//#define DEBUG_MESSAGES /* Uncomment to get debugging messages */
|
2011-06-09 13:56:44 +00:00
|
|
|
#ifndef ROS_REGTEST
|
2011-06-08 18:48:34 +00:00
|
|
|
#define WAIT_FOR_KEY
|
2011-06-09 13:56:44 +00:00
|
|
|
#endif
|
2011-06-08 18:48:34 +00:00
|
|
|
|
|
|
|
// ****************************************************************************
|
|
|
|
// BEGIN THE BIOS/CODE/DATA SEGMENT
|
|
|
|
// ****************************************************************************
|
|
|
|
serial_base = HEX(0400) // Base addresses for 4 serial ports (4 words)
|
|
|
|
BIOS_fbm = HEX(0413) // Free Base Memory (kilobytes) (1 word)
|
|
|
|
BIOS_timer = HEX(046C) // Timer ticks (1 word)
|
|
|
|
BIOS_magic = HEX(0472) // BIOS reset magic (1 word)
|
|
|
|
BIOS_vidrows = HEX(0484) // Number of screen rows (1 byte)
|
|
|
|
|
|
|
|
// Memory below this point is reserved for the BIOS and the MBR
|
|
|
|
trackbuf = HEX(1000) // Track buffer goes here (8192 bytes)
|
|
|
|
trackbufsize = 8192 // trackbuf ends at 3000h
|
|
|
|
|
|
|
|
// struct open_file_t
|
|
|
|
file_sector = 0 // Sector pointer (0 = structure free)
|
|
|
|
file_left = 4 // Number of sectors left
|
|
|
|
|
|
|
|
//struct dir_t
|
|
|
|
dir_lba = 0 // Directory start (LBA)
|
|
|
|
dir_len = 4 // Length in bytes
|
|
|
|
dir_clust = 8 // Length in clusters
|
|
|
|
|
|
|
|
#define dir_t_size 12
|
|
|
|
#define open_file_t_size 8
|
|
|
|
|
|
|
|
MAX_OPEN_LG2 = 2 // log2(Max number of open files)
|
|
|
|
MAX_OPEN = 4
|
|
|
|
SECTORSIZE_LG2 = 11 // 2048 bytes/sector (El Torito requirement)
|
|
|
|
SECTORSIZE = 2048
|
|
|
|
retry_count = 6 // How patient are we with the BIOS?
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
absolute HEX(5000) // Here we keep our BSS stuff
|
|
|
|
|
|
|
|
resb DriveNo, 1 // CD-ROM BIOS drive number (BYTE)
|
|
|
|
resb DiskError, 1 // Error code for disk I/O (BYTE)
|
|
|
|
resb RetryCount, 1 // Used for disk access retries (BYTE)
|
|
|
|
resb TimeoutCount, 1 // Timeout counter (BYTE)
|
|
|
|
resb ISOFlags, 1 // Flags for ISO directory search (BYTE)
|
|
|
|
resb RootDir, dir_t_size // Root directory (dir_t_size BYTES)
|
|
|
|
resb CurDir, dir_t_size // Current directory (dir_t_size BYTES)
|
|
|
|
resb ISOFileName, 64 // ISO filename canonicalization buffer
|
|
|
|
resb ISOFileNameEnd, 1
|
|
|
|
|
|
|
|
//align open_file_t_size
|
|
|
|
absolute HEX(5060)
|
2011-06-09 11:23:01 +00:00
|
|
|
resb Files, (MAX_OPEN * open_file_t_size)
|
2011-06-08 18:48:34 +00:00
|
|
|
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
start:
|
|
|
|
cli // Disable interrupts
|
|
|
|
xor ax, ax // ax = segment zero
|
|
|
|
mov ss, ax // Initialize stack segment
|
2011-06-09 11:23:01 +00:00
|
|
|
mov sp, offset start // Set up stack
|
2011-06-08 18:48:34 +00:00
|
|
|
mov ds, ax // Initialize other segment registers
|
|
|
|
mov es, ax
|
|
|
|
mov fs, ax
|
|
|
|
mov gs, ax
|
|
|
|
sti // Enable interrupts
|
|
|
|
cld // Increment pointers
|
|
|
|
|
|
|
|
mov cx, 2048 / 4 // Copy the bootsector
|
|
|
|
mov si, HEX(7C00) // from 0000:7C00
|
|
|
|
mov di, HEX(7000) // to 0000:7000
|
|
|
|
rep movsd // copy the program
|
|
|
|
|
|
|
|
ljmp16 0, relocate // jump into relocated code
|
|
|
|
|
|
|
|
relocate:
|
|
|
|
#ifdef DEBUG_MESSAGES
|
|
|
|
// Display the banner and copyright
|
|
|
|
mov si, offset isolinux_banner // si points to hello message
|
|
|
|
call writestr // display the message
|
|
|
|
mov si, offset copyright_str
|
|
|
|
call writestr
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Make sure the keyboard buffer is empty
|
|
|
|
call pollchar_and_empty
|
|
|
|
|
|
|
|
// Check for MBR on harddisk
|
|
|
|
pusha
|
|
|
|
mov ax, HEX(0201)
|
|
|
|
mov dx, HEX(0080)
|
|
|
|
mov cx, HEX(0001)
|
|
|
|
mov bx, trackbuf
|
|
|
|
int HEX(13)
|
|
|
|
popa
|
|
|
|
jc .boot_cdrom // could not read hdd
|
|
|
|
|
|
|
|
push ax
|
2011-10-15 13:42:43 +00:00
|
|
|
#ifdef ROS_REGTEST // this change is taken from the original isobtrt.asm
|
|
|
|
mov ax, word ptr ds:[trackbuf+510]
|
|
|
|
#else
|
2011-06-08 18:48:34 +00:00
|
|
|
mov ax, word ptr ds:[trackbuf]
|
2011-10-15 13:42:43 +00:00
|
|
|
#endif
|
2011-06-08 18:48:34 +00:00
|
|
|
cmp ax, 0
|
|
|
|
je .boot_cdrom // no boot sector found (hopefully there are no weird bootsectors which begin with 0)
|
|
|
|
pop ax
|
|
|
|
|
2011-06-09 13:56:44 +00:00
|
|
|
#ifdef WAIT_FOR_KEY
|
2011-06-08 18:48:34 +00:00
|
|
|
// Display the 'Press key' message and wait for a maximum of 5 seconds
|
|
|
|
call crlf
|
2011-06-09 11:23:01 +00:00
|
|
|
mov si, offset presskey_msg // si points to 'Press key' message
|
2011-06-08 18:48:34 +00:00
|
|
|
call writestr // display the message
|
|
|
|
|
|
|
|
mov byte ptr ds:[TimeoutCount], 5
|
|
|
|
.next_second:
|
|
|
|
mov eax, ds:[BIOS_timer] // load current tick counter
|
|
|
|
add eax, 19
|
|
|
|
|
|
|
|
.poll_again:
|
|
|
|
call pollchar_and_empty
|
|
|
|
jnz .boot_cdrom
|
|
|
|
|
|
|
|
mov ebx, ds:[BIOS_timer]
|
|
|
|
cmp eax, ebx
|
|
|
|
jnz .poll_again
|
|
|
|
|
2011-06-09 11:23:01 +00:00
|
|
|
mov si, offset dot_msg // print '.'
|
2011-06-08 18:48:34 +00:00
|
|
|
call writestr
|
|
|
|
dec byte ptr ds:[TimeoutCount] // decrement timeout counter
|
|
|
|
jz .boot_harddisk
|
|
|
|
jmp .next_second
|
2011-06-09 13:56:44 +00:00
|
|
|
#endif
|
2011-06-08 18:48:34 +00:00
|
|
|
|
|
|
|
.boot_harddisk:
|
|
|
|
call crlf
|
|
|
|
|
|
|
|
// Boot first harddisk (drive 0x80)
|
|
|
|
mov ax, HEX(0201)
|
|
|
|
mov dx, HEX(0080)
|
|
|
|
mov cx, HEX(0001)
|
|
|
|
mov bx, HEX(7C00)
|
|
|
|
int HEX(13)
|
|
|
|
jnc .go_hd
|
|
|
|
jmp kaboom
|
|
|
|
.go_hd:
|
|
|
|
mov ax, cs
|
|
|
|
mov ds, ax
|
|
|
|
mov es, ax
|
|
|
|
mov fs, ax
|
|
|
|
mov gs, ax
|
|
|
|
mov dx, HEX(0080)
|
|
|
|
|
|
|
|
ljmp16 0, HEX(7C00)
|
|
|
|
|
|
|
|
.boot_cdrom:
|
|
|
|
#ifdef WAIT_FOR_KEY
|
|
|
|
call crlf
|
|
|
|
call crlf
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Save and display the boot drive number
|
|
|
|
mov byte ptr ds:[DriveNo], dl
|
|
|
|
#ifdef DEBUG_MESSAGES
|
|
|
|
mov si, offset startup_msg
|
|
|
|
call writemsg
|
|
|
|
mov al, dl
|
|
|
|
call writehex2
|
|
|
|
call crlf
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Now figure out what we're actually doing
|
|
|
|
// Note: use passed-in DL value rather than 7Fh because
|
|
|
|
// at least some BIOSes will get the wrong value otherwise
|
|
|
|
mov ax, HEX(4B01) // Get disk emulation status
|
|
|
|
mov dl, byte ptr ds:[DriveNo]
|
2011-06-09 11:23:01 +00:00
|
|
|
mov si, offset spec_packet
|
2011-06-08 18:48:34 +00:00
|
|
|
int HEX(13)
|
|
|
|
jc spec_query_failed // Shouldn't happen (BIOS bug)
|
|
|
|
mov dl, byte ptr ds:[DriveNo]
|
|
|
|
cmp byte ptr ds:[sp_drive], dl // Should contain the drive number
|
|
|
|
jne spec_query_failed
|
|
|
|
|
|
|
|
#ifdef DEBUG_MESSAGES
|
|
|
|
mov si, offset spec_ok_msg
|
|
|
|
call writemsg
|
|
|
|
mov al, byte ptr ds:[sp_drive]
|
|
|
|
call writehex2
|
|
|
|
call crlf
|
|
|
|
#endif
|
|
|
|
|
|
|
|
found_drive:
|
|
|
|
// Get drive information
|
|
|
|
mov ah, HEX(48)
|
|
|
|
mov dl, byte ptr ds:[DriveNo]
|
|
|
|
mov si, offset drive_params
|
|
|
|
int HEX(13)
|
|
|
|
jnc params_ok
|
|
|
|
|
|
|
|
// mov si, nosecsize_msg No use in reporting this
|
|
|
|
// call writemsg
|
|
|
|
|
|
|
|
params_ok:
|
|
|
|
// Check for the sector size (should be 2048, but
|
|
|
|
// some BIOSes apparently think we're 512-byte media)
|
|
|
|
//
|
|
|
|
// FIX: We need to check what the proper behaviour
|
|
|
|
// is for getlinsec when the BIOS thinks the sector
|
|
|
|
// size is 512!!! For that, we need such a BIOS, though...
|
|
|
|
#ifdef DEBUG_MESSAGES
|
|
|
|
mov si, offset secsize_msg
|
|
|
|
call writemsg
|
|
|
|
mov ax, word ptr ds:[dp_secsize]
|
|
|
|
call writehex4
|
|
|
|
call crlf
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// Clear Files structures
|
|
|
|
//
|
|
|
|
mov di, Files
|
|
|
|
mov cx, (MAX_OPEN*open_file_t_size)/4
|
|
|
|
xor eax, eax
|
|
|
|
rep stosd
|
|
|
|
|
|
|
|
//
|
|
|
|
// Now, we need to sniff out the actual filesystem data structures.
|
|
|
|
// mkisofs gave us a pointer to the primary volume descriptor
|
|
|
|
// (which will be at 16 only for a single-session disk!); from the PVD
|
|
|
|
// we should be able to find the rest of what we need to know.
|
|
|
|
//
|
|
|
|
get_fs_structures:
|
|
|
|
mov eax, 16 // Primary Volume Descriptor (sector 16)
|
|
|
|
mov bx, trackbuf
|
|
|
|
call getonesec
|
|
|
|
|
|
|
|
mov eax, dword ptr ds:[trackbuf+156+2]
|
|
|
|
mov dword ptr ds:[RootDir+dir_lba],eax
|
|
|
|
mov dword ptr ds:[CurDir+dir_lba],eax
|
|
|
|
#ifdef DEBUG_MESSAGES
|
|
|
|
mov si, offset rootloc_msg
|
|
|
|
call writemsg
|
|
|
|
call writehex8
|
|
|
|
call crlf
|
|
|
|
#endif
|
|
|
|
|
|
|
|
mov eax, dword ptr ds:[trackbuf+156+10]
|
|
|
|
mov dword ptr ds:[RootDir+dir_len],eax
|
|
|
|
mov dword ptr ds:[CurDir+dir_len],eax
|
|
|
|
#ifdef DEBUG_MESSAGES
|
|
|
|
mov si, offset rootlen_msg
|
|
|
|
call writemsg
|
|
|
|
call writehex8
|
|
|
|
call crlf
|
|
|
|
#endif
|
|
|
|
add eax,SECTORSIZE-1
|
|
|
|
shr eax,SECTORSIZE_LG2
|
|
|
|
mov dword ptr ds:[RootDir+dir_clust],eax
|
|
|
|
mov dword ptr ds:[CurDir+dir_clust],eax
|
|
|
|
#ifdef DEBUG_MESSAGES
|
|
|
|
mov si, offset rootsect_msg
|
|
|
|
call writemsg
|
|
|
|
call writehex8
|
|
|
|
call crlf
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Look for the "REACTOS" directory, and if found,
|
|
|
|
// make it the current directory instead of the root
|
|
|
|
// directory.
|
|
|
|
mov di, offset isolinux_dir
|
|
|
|
mov al, 2 // Search for a directory
|
|
|
|
call searchdir_iso
|
|
|
|
jnz .dir_found
|
|
|
|
mov si, offset no_dir_msg
|
|
|
|
call writemsg
|
|
|
|
jmp kaboom
|
|
|
|
|
|
|
|
.dir_found:
|
|
|
|
mov dword ptr ds:[CurDir+dir_len],eax
|
|
|
|
mov eax, dword ptr ds:[si+file_left]
|
|
|
|
mov dword ptr ds:[CurDir+dir_clust],eax
|
|
|
|
xor eax,eax // Free this file pointer entry
|
|
|
|
xchg eax,dword ptr ds:[si+file_sector]
|
|
|
|
mov dword ptr ds:[CurDir+dir_lba],eax
|
|
|
|
|
|
|
|
|
|
|
|
mov di, offset isolinux_bin // di points to Isolinux filename
|
|
|
|
call searchdir // look for the file
|
|
|
|
jnz .isolinux_opened // got the file
|
|
|
|
mov si, offset no_isolinux_msg // si points to error message
|
|
|
|
call writemsg // display the message
|
|
|
|
jmp kaboom // fail boot
|
|
|
|
|
|
|
|
.isolinux_opened:
|
|
|
|
mov di, si // save file pointer
|
|
|
|
|
|
|
|
#ifdef DEBUG_MESSAGES
|
|
|
|
mov si, offset filelen_msg
|
|
|
|
call writemsg
|
|
|
|
call writehex8
|
|
|
|
call crlf
|
|
|
|
#endif
|
|
|
|
|
|
|
|
mov ecx, eax // calculate sector count
|
|
|
|
shr ecx, 11
|
|
|
|
test eax, HEX(7FF)
|
|
|
|
jz .full_sector
|
|
|
|
inc ecx
|
|
|
|
.full_sector:
|
|
|
|
|
|
|
|
#ifdef DEBUG_MESSAGES
|
|
|
|
mov eax, ecx
|
|
|
|
mov si, offset filesect_msg
|
|
|
|
call writemsg
|
|
|
|
call writehex8
|
|
|
|
call crlf
|
|
|
|
#endif
|
|
|
|
|
2011-07-30 20:34:55 +00:00
|
|
|
// use high segment, as some bios can fail, when offset is too big
|
|
|
|
mov bx, FREELDR_BASE / 16 // es = load segment
|
|
|
|
mov es, bx
|
|
|
|
xor ebx, ebx // bx = load offset
|
2011-06-08 18:48:34 +00:00
|
|
|
mov si, di // restore file pointer
|
2011-07-30 20:34:55 +00:00
|
|
|
mov cx, HEX(0FFFF) // load the whole file
|
|
|
|
call getfssec // get the whole file
|
2011-06-08 18:48:34 +00:00
|
|
|
|
|
|
|
#ifdef DEBUG_MESSAGES
|
|
|
|
mov si, offset startldr_msg
|
|
|
|
call writemsg
|
|
|
|
call crlf
|
|
|
|
#endif
|
|
|
|
|
|
|
|
mov dl, byte ptr ds:[DriveNo] // dl = boot drive
|
|
|
|
mov dh, 0 // dh = boot partition
|
|
|
|
|
2011-06-12 21:21:47 +00:00
|
|
|
/* Transfer execution to the bootloader */
|
2011-06-18 17:19:28 +00:00
|
|
|
ljmp16 0, FREELDR_BASE
|
2011-06-08 18:48:34 +00:00
|
|
|
|
|
|
|
//
|
|
|
|
// searchdir:
|
|
|
|
//
|
|
|
|
// Open a file
|
|
|
|
//
|
|
|
|
// On entry:
|
|
|
|
// DS:DI = filename
|
|
|
|
// If successful:
|
|
|
|
// ZF clear
|
|
|
|
// SI = file pointer
|
|
|
|
// DX:AX or EAX = file length in bytes
|
|
|
|
// If unsuccessful
|
|
|
|
// ZF set
|
|
|
|
//
|
|
|
|
|
|
|
|
//
|
|
|
|
// searchdir_iso is a special entry point for ISOLINUX only. In addition
|
|
|
|
// to the above, searchdir_iso passes a file flag mask in AL. This is useful
|
|
|
|
// for searching for directories.
|
|
|
|
//
|
|
|
|
alloc_failure:
|
|
|
|
xor ax,ax // ZF <- 1
|
|
|
|
ret
|
|
|
|
|
|
|
|
searchdir:
|
|
|
|
xor al, al
|
|
|
|
searchdir_iso:
|
|
|
|
mov byte ptr ds:[ISOFlags],al
|
|
|
|
call allocate_file // Temporary file structure for directory
|
|
|
|
jnz alloc_failure
|
|
|
|
push es
|
|
|
|
push ds
|
|
|
|
pop es // ES = DS
|
|
|
|
mov si, offset CurDir
|
|
|
|
cmp byte ptr ds:[di], 92 //'\' // If filename begins with slash
|
|
|
|
jne .not_rooted
|
|
|
|
inc di // Skip leading slash
|
|
|
|
mov si, offset RootDir // Reference root directory instead
|
|
|
|
.not_rooted:
|
|
|
|
mov eax, dword ptr ds:[si+dir_clust]
|
|
|
|
mov dword ptr ds:[bx+file_left],eax
|
|
|
|
mov eax,dword ptr ds:[si+dir_lba]
|
|
|
|
mov dword ptr ds:[bx+file_sector],eax
|
|
|
|
mov edx,dword ptr ds:[si+dir_len]
|
|
|
|
|
|
|
|
.look_for_slash:
|
|
|
|
mov ax,di
|
|
|
|
.scan:
|
|
|
|
mov cl, byte ptr ds:[di]
|
|
|
|
inc di
|
|
|
|
and cl,cl
|
|
|
|
jz .isfile
|
2011-06-09 11:23:01 +00:00
|
|
|
cmp cl, 92 // '\'
|
2011-06-08 18:48:34 +00:00
|
|
|
jne .scan
|
|
|
|
mov byte ptr ds:[di-1], 0 // Terminate at directory name
|
|
|
|
mov cl,2 // Search for directory
|
|
|
|
xchg cl, byte ptr ds:[ISOFlags]
|
|
|
|
push di
|
|
|
|
push cx
|
|
|
|
push offset .resume // Where to "return" to
|
|
|
|
push es
|
|
|
|
.isfile:
|
|
|
|
xchg ax,di
|
|
|
|
|
|
|
|
.getsome:
|
|
|
|
// Get a chunk of the directory
|
|
|
|
mov si,trackbuf
|
|
|
|
pushad
|
|
|
|
xchg bx,si
|
|
|
|
mov cx,1 // load one sector
|
|
|
|
call getfssec
|
|
|
|
popad
|
|
|
|
|
|
|
|
.compare:
|
|
|
|
movzx eax, byte ptr ds:[si] // Length of directory entry
|
|
|
|
cmp al, 33
|
|
|
|
jb .next_sector
|
|
|
|
mov cl, byte ptr ds:[si+25]
|
|
|
|
xor cl, byte ptr ds:[ISOFlags]
|
|
|
|
test cl, HEX(8E) // Unwanted file attributes!
|
|
|
|
jnz .not_file
|
|
|
|
pusha
|
|
|
|
movzx cx, byte ptr ds:[si+32] // File identifier length
|
|
|
|
add si, 33 // File identifier offset
|
|
|
|
call iso_compare_names
|
|
|
|
popa
|
|
|
|
je .success
|
|
|
|
.not_file:
|
|
|
|
sub edx, eax // Decrease bytes left
|
|
|
|
jbe .failure
|
|
|
|
add si, ax // Advance pointer
|
|
|
|
|
|
|
|
.check_overrun:
|
|
|
|
// Did we finish the buffer?
|
|
|
|
cmp si, trackbuf+trackbufsize
|
|
|
|
jb .compare // No, keep going
|
|
|
|
|
|
|
|
jmp .getsome // Get some more directory
|
|
|
|
|
|
|
|
.next_sector:
|
|
|
|
// Advance to the beginning of next sector
|
|
|
|
lea ax, [si+SECTORSIZE-1]
|
|
|
|
and ax, not (SECTORSIZE-1)
|
|
|
|
sub ax, si
|
|
|
|
jmp .not_file // We still need to do length checks
|
|
|
|
|
|
|
|
.failure:
|
|
|
|
#ifdef DEBUG_MESSAGES
|
|
|
|
mov si, offset findfail_msg
|
|
|
|
call writemsg
|
|
|
|
call crlf
|
|
|
|
#endif
|
|
|
|
xor eax, eax // ZF = 1
|
|
|
|
mov dword ptr ds:[bx+file_sector], eax
|
|
|
|
pop es
|
|
|
|
ret
|
|
|
|
|
|
|
|
.success:
|
|
|
|
mov eax, dword ptr ds:[si+2] // Location of extent
|
|
|
|
mov dword ptr ds:[bx+file_sector], eax
|
|
|
|
mov eax, dword ptr ds:[si+10] // Data length
|
|
|
|
push eax
|
|
|
|
add eax, SECTORSIZE-1
|
|
|
|
shr eax, SECTORSIZE_LG2
|
|
|
|
mov dword ptr ds:[bx+file_left], eax
|
|
|
|
pop eax
|
|
|
|
mov edx, eax
|
|
|
|
shr edx, 16
|
|
|
|
and bx, bx // ZF = 0
|
|
|
|
mov si, bx
|
|
|
|
pop es
|
|
|
|
ret
|
|
|
|
|
|
|
|
.resume:
|
|
|
|
// We get here if we were only doing part of a lookup
|
|
|
|
// This relies on the fact that .success returns bx == si
|
|
|
|
xchg edx, eax // Directory length in edx
|
|
|
|
pop cx // Old ISOFlags
|
|
|
|
pop di // Next filename pointer
|
|
|
|
|
|
|
|
// restore the backslash in the filename
|
2011-06-09 11:23:01 +00:00
|
|
|
mov byte ptr ds:[di-1], 92 // '\'
|
2011-06-08 18:48:34 +00:00
|
|
|
|
|
|
|
mov byte ptr ds:[ISOFlags], cl // Restore the flags
|
|
|
|
jz .failure // Did we fail? If so fail for real!
|
|
|
|
jmp .look_for_slash // Otherwise, next level
|
|
|
|
|
|
|
|
//
|
|
|
|
// allocate_file: Allocate a file structure
|
|
|
|
//
|
|
|
|
// If successful:
|
|
|
|
// ZF set
|
|
|
|
// BX = file pointer
|
|
|
|
// In unsuccessful:
|
|
|
|
// ZF clear
|
|
|
|
//
|
|
|
|
allocate_file:
|
|
|
|
push cx
|
|
|
|
mov bx, Files
|
|
|
|
mov cx, MAX_OPEN
|
|
|
|
.check:
|
|
|
|
cmp dword ptr ds:[bx], 0
|
|
|
|
je .found
|
|
|
|
add bx, open_file_t_size // ZF = 0
|
|
|
|
loop .check
|
|
|
|
// ZF = 0 if we fell out of the loop
|
|
|
|
.found:
|
|
|
|
pop cx
|
|
|
|
ret
|
|
|
|
|
|
|
|
//
|
|
|
|
// iso_compare_names:
|
|
|
|
// Compare the names DS:SI and DS:DI and report if they are
|
|
|
|
// equal from an ISO 9660 perspective. SI is the name from
|
|
|
|
// the filesystem; CX indicates its length, and ';' terminates.
|
|
|
|
// DI is expected to end with a null.
|
|
|
|
//
|
|
|
|
// Note: clobbers AX, CX, SI, DI; assumes DS == ES == base segment
|
|
|
|
//
|
|
|
|
iso_compare_names:
|
|
|
|
// First, terminate and canonicalize input filename
|
|
|
|
push di
|
|
|
|
mov di, offset ISOFileName
|
|
|
|
.canon_loop:
|
|
|
|
jcxz .canon_end
|
|
|
|
lodsb
|
|
|
|
dec cx
|
|
|
|
cmp al, ';'
|
|
|
|
je .canon_end
|
|
|
|
and al, al
|
|
|
|
je .canon_end
|
|
|
|
stosb
|
|
|
|
cmp di, offset ISOFileNameEnd-1 // Guard against buffer overrun
|
|
|
|
jb .canon_loop
|
|
|
|
.canon_end:
|
|
|
|
cmp di, ISOFileName
|
|
|
|
jbe .canon_done
|
|
|
|
cmp byte ptr ds:[di-1], '.' // Remove terminal dots
|
|
|
|
jne .canon_done
|
|
|
|
dec di
|
|
|
|
jmp short .canon_end
|
|
|
|
.canon_done:
|
|
|
|
mov byte ptr ds:[di], 0 // Null-terminate string
|
|
|
|
pop di
|
|
|
|
mov si, ISOFileName
|
|
|
|
.compare2:
|
|
|
|
lodsb
|
|
|
|
mov ah, byte ptr ds:[di]
|
|
|
|
inc di
|
|
|
|
and ax, ax
|
|
|
|
jz .success2 // End of string for both
|
|
|
|
and al, al // Is either one end of string?
|
|
|
|
jz .failure2 // If so, failure
|
|
|
|
and ah, ah
|
|
|
|
jz .failure2
|
|
|
|
or ax, HEX(2020) // Convert to lower case
|
|
|
|
cmp al, ah
|
|
|
|
je .compare2
|
|
|
|
.failure2:
|
|
|
|
and ax, ax // ZF = 0 (at least one will be nonzero)
|
|
|
|
.success2:
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// getfssec: Get multiple clusters from a file, given the file pointer.
|
|
|
|
//
|
|
|
|
// On entry:
|
|
|
|
// ES:BX -> Buffer
|
|
|
|
// SI -> File pointer
|
|
|
|
// CX -> Cluster count; 0FFFFh = until end of file
|
|
|
|
// On exit:
|
|
|
|
// SI -> File pointer (or 0 on EOF)
|
|
|
|
// CF = 1 -> Hit EOF
|
|
|
|
//
|
|
|
|
getfssec:
|
|
|
|
cmp cx, word ptr ds:[si+file_left]
|
|
|
|
jna .ok_size
|
|
|
|
mov cx, word ptr ds:[si+file_left]
|
|
|
|
|
|
|
|
.ok_size:
|
|
|
|
mov bp, cx
|
|
|
|
push cx
|
|
|
|
push si
|
|
|
|
mov eax, dword ptr ds:[si+file_sector]
|
|
|
|
call getlinsec
|
|
|
|
xor ecx, ecx
|
|
|
|
pop si
|
|
|
|
pop cx
|
|
|
|
|
|
|
|
add dword ptr ds:[si+file_sector], ecx
|
|
|
|
sub dword ptr ds:[si+file_left], ecx
|
|
|
|
ja .not_eof // CF = 0
|
|
|
|
|
|
|
|
xor ecx, ecx
|
|
|
|
mov dword ptr ds:[si+file_sector], ecx // Mark as unused
|
|
|
|
xor si,si
|
|
|
|
stc
|
|
|
|
|
|
|
|
.not_eof:
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
// INT 13h, AX=4B01h, DL=<passed in value> failed.
|
|
|
|
// Try to scan the entire 80h-FFh from the end.
|
|
|
|
spec_query_failed:
|
|
|
|
mov si, offset spec_err_msg
|
|
|
|
call writemsg
|
|
|
|
|
|
|
|
mov dl, HEX(0FF)
|
|
|
|
.test_loop:
|
|
|
|
pusha
|
|
|
|
mov ax, HEX(4B01)
|
2011-06-09 11:23:01 +00:00
|
|
|
mov si, offset spec_packet
|
|
|
|
mov byte ptr ds:[si], 13 // Size of buffer
|
|
|
|
int HEX(13)
|
2011-06-08 18:48:34 +00:00
|
|
|
popa
|
|
|
|
jc .still_broken
|
|
|
|
|
|
|
|
mov si, offset maybe_msg
|
|
|
|
call writemsg
|
|
|
|
mov al, dl
|
|
|
|
call writehex2
|
|
|
|
call crlf
|
|
|
|
|
|
|
|
cmp byte ptr ds:[sp_drive], dl
|
|
|
|
jne .maybe_broken
|
|
|
|
|
|
|
|
// Okay, good enough...
|
|
|
|
mov si, offset alright_msg
|
|
|
|
call writemsg
|
|
|
|
mov byte ptr ds:[DriveNo], dl
|
|
|
|
.found_drive:
|
|
|
|
jmp found_drive
|
|
|
|
|
|
|
|
// Award BIOS 4.51 apparently passes garbage in sp_drive,
|
|
|
|
// but if this was the drive number originally passed in
|
|
|
|
// DL then consider it "good enough"
|
|
|
|
.maybe_broken:
|
|
|
|
cmp byte ptr ds:[DriveNo], dl
|
|
|
|
je .found_drive
|
|
|
|
|
|
|
|
.still_broken:
|
|
|
|
dec dx
|
|
|
|
cmp dl, HEX(80)
|
|
|
|
jnb .test_loop
|
|
|
|
|
|
|
|
fatal_error:
|
|
|
|
mov si, offset nothing_msg
|
|
|
|
call writemsg
|
|
|
|
|
|
|
|
.norge:
|
|
|
|
jmp .norge
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Information message (DS:SI) output
|
|
|
|
// Prefix with "isolinux: "
|
|
|
|
writemsg:
|
|
|
|
push ax
|
|
|
|
push si
|
2011-06-09 11:23:01 +00:00
|
|
|
mov si, offset isolinux_str
|
2011-06-08 18:48:34 +00:00
|
|
|
call writestr
|
|
|
|
pop si
|
|
|
|
call writestr
|
|
|
|
pop ax
|
|
|
|
ret
|
|
|
|
|
|
|
|
//
|
|
|
|
// crlf: Print a newline
|
|
|
|
crlf:
|
2011-06-09 11:23:01 +00:00
|
|
|
mov si, offset crlf_msg
|
2011-06-08 18:48:34 +00:00
|
|
|
// Fall through
|
|
|
|
|
|
|
|
//
|
|
|
|
// writestr: write a null-terminated string to the console, saving
|
|
|
|
// registers on entry.
|
|
|
|
//
|
|
|
|
writestr:
|
|
|
|
pushfd
|
|
|
|
pushad
|
|
|
|
writestr_top:
|
|
|
|
lodsb
|
|
|
|
and al, al
|
|
|
|
jz writestr_end
|
|
|
|
call writechr
|
|
|
|
jmp short writestr_top
|
|
|
|
writestr_end:
|
|
|
|
popad
|
|
|
|
popfd
|
|
|
|
ret
|
|
|
|
|
|
|
|
//
|
|
|
|
// writehex[248]: Write a hex number in (AL, AX, EAX) to the console
|
|
|
|
//
|
|
|
|
writehex2:
|
|
|
|
pushfd
|
|
|
|
pushad
|
|
|
|
shl eax, 24
|
|
|
|
mov cx, 2
|
|
|
|
jmp short writehex_common
|
|
|
|
writehex4:
|
|
|
|
pushfd
|
|
|
|
pushad
|
|
|
|
shl eax, 16
|
|
|
|
mov cx, 4
|
|
|
|
jmp short writehex_common
|
|
|
|
writehex8:
|
|
|
|
pushfd
|
|
|
|
pushad
|
|
|
|
mov cx, 8
|
|
|
|
writehex_common:
|
|
|
|
.loop:
|
|
|
|
rol eax, 4
|
|
|
|
push eax
|
2011-06-09 11:23:01 +00:00
|
|
|
and al, HEX(0F)
|
2011-06-08 18:48:34 +00:00
|
|
|
cmp al, 10
|
|
|
|
jae .high
|
|
|
|
.low:
|
|
|
|
add al, '0'
|
|
|
|
jmp short .ischar
|
|
|
|
.high:
|
|
|
|
add al, 'A'-10
|
|
|
|
.ischar:
|
|
|
|
call writechr
|
|
|
|
pop eax
|
|
|
|
loop .loop
|
|
|
|
popad
|
|
|
|
popfd
|
|
|
|
ret
|
|
|
|
|
|
|
|
//
|
|
|
|
// writechr: Write a character to the screen. There is a more "sophisticated"
|
|
|
|
// version of this in the subsequent code, so we patch the pointer
|
|
|
|
// when appropriate.
|
|
|
|
writechr:
|
|
|
|
pushfd
|
|
|
|
pushad
|
|
|
|
mov ah, HEX(0E)
|
|
|
|
xor bx, bx
|
|
|
|
int HEX(10)
|
|
|
|
popad
|
|
|
|
popfd
|
|
|
|
ret
|
|
|
|
|
|
|
|
//
|
|
|
|
// Get one sector. Convenience entry point.
|
|
|
|
//
|
|
|
|
getonesec:
|
|
|
|
mov bp, 1
|
|
|
|
// Fall through to getlinsec
|
|
|
|
|
|
|
|
//
|
|
|
|
// Get linear sectors - EBIOS LBA addressing, 2048-byte sectors.
|
|
|
|
//
|
|
|
|
// Note that we can't always do this as a single request, because at least
|
|
|
|
// Phoenix BIOSes has a 127-sector limit. To be on the safe side, stick
|
|
|
|
// to 32 sectors (64K) per request.
|
|
|
|
//
|
|
|
|
// Input:
|
|
|
|
// EAX - Linear sector number
|
|
|
|
// ES:BX - Target buffer
|
|
|
|
// BP - Sector count
|
|
|
|
//
|
|
|
|
getlinsec:
|
2011-10-15 13:42:43 +00:00
|
|
|
push es // save es, we reset it later to 0
|
|
|
|
|
2011-06-09 11:23:01 +00:00
|
|
|
mov si, offset dapa // Load up the DAPA
|
2011-06-08 18:48:34 +00:00
|
|
|
mov word ptr ds:[si+4], bx
|
|
|
|
mov bx, es
|
|
|
|
mov word ptr ds:[si+6], bx
|
2011-10-15 13:42:43 +00:00
|
|
|
xor bx, bx // reset es to 0, some bioses (KVM) require that
|
|
|
|
mov es, bx
|
2011-06-08 18:48:34 +00:00
|
|
|
mov dword ptr ds:[si+8], eax
|
|
|
|
.loop2:
|
|
|
|
push bp // Sectors left
|
|
|
|
cmp bp, word ptr ds:[MaxTransfer]
|
|
|
|
jbe .bp_ok
|
|
|
|
mov bp, word ptr ds:[MaxTransfer]
|
|
|
|
.bp_ok:
|
|
|
|
mov word ptr ds:[si+2], bp
|
|
|
|
push si
|
|
|
|
mov dl, byte ptr ds:[DriveNo]
|
|
|
|
mov ah, HEX(42) // Extended Read
|
|
|
|
call xint13
|
|
|
|
pop si
|
|
|
|
pop bp
|
|
|
|
movzx eax,word ptr ds:[si+2] // Sectors we read
|
|
|
|
add dword ptr ds:[si+8], eax // Advance sector pointer
|
|
|
|
sub bp, ax // Sectors left
|
|
|
|
shl ax, SECTORSIZE_LG2-4 // 2048-byte sectors -> segment
|
|
|
|
add word ptr ds:[si+6], ax // Advance buffer pointer
|
|
|
|
and bp, bp
|
|
|
|
jnz .loop2
|
|
|
|
mov eax, dword ptr ds:[si+8] // Next sector
|
2011-10-15 13:42:43 +00:00
|
|
|
|
|
|
|
pop es
|
2011-06-08 18:48:34 +00:00
|
|
|
ret
|
|
|
|
|
|
|
|
// INT 13h with retry
|
|
|
|
xint13:
|
|
|
|
mov byte ptr ds:[RetryCount], retry_count
|
|
|
|
.try:
|
|
|
|
pushad
|
2011-06-09 11:23:01 +00:00
|
|
|
int HEX(13)
|
2011-06-08 18:48:34 +00:00
|
|
|
jc .error
|
|
|
|
add sp, 8*4 // Clean up stack
|
|
|
|
ret
|
|
|
|
.error:
|
|
|
|
mov byte ptr ds:[DiskError], ah // Save error code
|
|
|
|
popad
|
|
|
|
dec byte ptr ds:[RetryCount]
|
|
|
|
jz .real_error
|
|
|
|
push ax
|
|
|
|
mov al, byte ptr ds:[RetryCount]
|
|
|
|
mov ah, byte ptr ds:[dapa+2] // Sector transfer count
|
|
|
|
cmp al,2 // Only 2 attempts left
|
|
|
|
ja .nodanger
|
|
|
|
mov ah,1 // Drop transfer size to 1
|
|
|
|
jmp short .setsize
|
|
|
|
.nodanger:
|
|
|
|
cmp al, retry_count-2
|
|
|
|
ja .again // First time, just try again
|
|
|
|
shr ah,1 // Otherwise, try to reduce
|
|
|
|
adc ah,0 // the max transfer size, but not to 0
|
|
|
|
.setsize:
|
|
|
|
mov byte ptr ds:[MaxTransfer],ah
|
|
|
|
mov byte ptr ds:[dapa+2],ah
|
|
|
|
.again:
|
|
|
|
pop ax
|
|
|
|
jmp .try
|
|
|
|
|
|
|
|
.real_error:
|
|
|
|
mov si, offset diskerr_msg
|
|
|
|
call writemsg
|
|
|
|
mov al, byte ptr ds:[DiskError]
|
|
|
|
call writehex2
|
|
|
|
mov si, offset ondrive_str
|
|
|
|
call writestr
|
|
|
|
mov al, dl
|
|
|
|
call writehex2
|
|
|
|
call crlf
|
|
|
|
// Fall through to kaboom
|
|
|
|
|
|
|
|
//
|
|
|
|
// kaboom: write a message and bail out. Wait for a user keypress,
|
|
|
|
// then do a hard reboot.
|
|
|
|
//
|
|
|
|
kaboom:
|
|
|
|
mov ax, cs
|
|
|
|
mov ds, ax
|
|
|
|
mov es, ax
|
|
|
|
mov fs, ax
|
|
|
|
mov gs, ax
|
|
|
|
sti
|
2011-06-09 11:23:01 +00:00
|
|
|
mov si, offset err_bootfailed
|
2011-06-08 18:48:34 +00:00
|
|
|
call writestr
|
|
|
|
xor ax, ax // Wait for keypress
|
|
|
|
int HEX(16)
|
|
|
|
cli
|
|
|
|
mov word ptr ds:[BIOS_magic], 0 // Cold reboot
|
|
|
|
ljmp16 HEX(0F000), HEX(0FFF0) // Reset vector address
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// pollchar_and_empty: check if we have an input character pending (ZF = 0) and empty the input buffer afterwards
|
|
|
|
//
|
|
|
|
pollchar_and_empty:
|
|
|
|
pushad
|
|
|
|
mov ah, 1 // Did the user press a key?
|
|
|
|
int HEX(16)
|
|
|
|
jz .end // No, then we're done
|
|
|
|
mov ah, 0 // Otherwise empty the buffer by reading it
|
|
|
|
int HEX(16)
|
|
|
|
.end:
|
|
|
|
popad
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
isolinux_banner:
|
2011-06-18 14:50:24 +00:00
|
|
|
.ascii CR, LF, "Loading IsoBoot...", CR, LF, NUL
|
2011-06-08 18:48:34 +00:00
|
|
|
copyright_str:
|
2011-06-18 14:50:24 +00:00
|
|
|
.ascii " (C) 1994-2002 H. Peter Anvin", CR, LF, NUL
|
2011-06-08 18:48:34 +00:00
|
|
|
presskey_msg:
|
2011-06-18 14:50:24 +00:00
|
|
|
.ascii "Press any key to boot from CD", NUL
|
2011-06-08 18:48:34 +00:00
|
|
|
dot_msg:
|
2011-06-18 14:50:24 +00:00
|
|
|
.ascii ".", NUL
|
2011-06-08 18:48:34 +00:00
|
|
|
|
|
|
|
#ifdef DEBUG_MESSAGES
|
|
|
|
startup_msg:
|
2011-06-18 14:50:24 +00:00
|
|
|
.ascii "Startup, DL = '", NUL
|
2011-06-08 18:48:34 +00:00
|
|
|
spec_ok_msg:
|
2011-06-18 14:50:24 +00:00
|
|
|
.ascii "packet OK, drive = ", NUL
|
2011-06-08 18:48:34 +00:00
|
|
|
secsize_msg:
|
2011-06-18 14:50:24 +00:00
|
|
|
.ascii "size appears to be ", NUL
|
2011-06-08 18:48:34 +00:00
|
|
|
rootloc_msg:
|
2011-06-18 14:50:24 +00:00
|
|
|
.ascii "Root dir loc: ", NUL
|
2011-06-08 18:48:34 +00:00
|
|
|
rootlen_msg:
|
2011-06-18 14:50:24 +00:00
|
|
|
.ascii "Root dir len: ", NUL
|
2011-06-08 18:48:34 +00:00
|
|
|
rootsect_msg:
|
2011-06-18 14:50:24 +00:00
|
|
|
.ascii "Root dir len(sect): ", NUL
|
2011-06-08 18:48:34 +00:00
|
|
|
fileloc_msg:
|
2011-06-18 14:50:24 +00:00
|
|
|
.ascii "SETUPLDR loc: ", NUL
|
2011-06-08 18:48:34 +00:00
|
|
|
filelen_msg:
|
2011-06-18 14:50:24 +00:00
|
|
|
.ascii "SETUPLDR len: ", NUL
|
2011-06-08 18:48:34 +00:00
|
|
|
filesect_msg:
|
2011-06-18 14:50:24 +00:00
|
|
|
.ascii "SETUPLDR len(sect): ", NUL
|
2011-06-08 18:48:34 +00:00
|
|
|
findfail_msg:
|
2011-06-18 14:50:24 +00:00
|
|
|
.ascii "Failed to find file!", NUL
|
2011-06-08 18:48:34 +00:00
|
|
|
startldr_msg:
|
2011-06-18 14:50:24 +00:00
|
|
|
.ascii "Starting SETUPLDR.SYS", NUL
|
2011-06-08 18:48:34 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
spec_err_msg:
|
2011-06-18 14:50:24 +00:00
|
|
|
.ascii "Load spec failed, trying wing ...", CR, LF, NUL
|
2011-06-08 18:48:34 +00:00
|
|
|
maybe_msg:
|
2011-06-18 14:50:24 +00:00
|
|
|
.ascii "Found smth at drive = ", NUL
|
2011-06-08 18:48:34 +00:00
|
|
|
alright_msg:
|
2011-06-18 14:50:24 +00:00
|
|
|
.ascii "might be ok, continuing...", CR, LF, NUL
|
2011-06-08 18:48:34 +00:00
|
|
|
nothing_msg:
|
2011-06-18 14:50:24 +00:00
|
|
|
.ascii "Failed locate CD-ROM; boot failed.", CR, LF, NUL
|
2011-06-08 18:48:34 +00:00
|
|
|
|
|
|
|
isolinux_str:
|
2011-06-18 14:50:24 +00:00
|
|
|
.ascii "IsoBoot: ", NUL
|
2011-06-08 18:48:34 +00:00
|
|
|
crlf_msg:
|
2011-06-18 14:50:24 +00:00
|
|
|
.ascii CR, LF, NUL
|
2011-06-08 18:48:34 +00:00
|
|
|
diskerr_msg:
|
2011-06-18 14:50:24 +00:00
|
|
|
.ascii "Disk error ", NUL
|
2011-06-08 18:48:34 +00:00
|
|
|
ondrive_str:
|
2011-06-18 14:50:24 +00:00
|
|
|
.ascii ", drive ", NUL
|
2011-06-08 18:48:34 +00:00
|
|
|
|
|
|
|
err_bootfailed:
|
2011-06-18 14:50:24 +00:00
|
|
|
.ascii CR, LF, "failed..", NUL
|
2011-06-08 18:48:34 +00:00
|
|
|
isolinux_dir:
|
2011-06-18 14:50:24 +00:00
|
|
|
.ascii "\\LOADER", NUL
|
2011-06-08 18:48:34 +00:00
|
|
|
no_dir_msg:
|
2011-06-18 14:50:24 +00:00
|
|
|
.ascii "LOADER dir not found.", CR, LF, NUL
|
2011-06-08 18:48:34 +00:00
|
|
|
isolinux_bin:
|
2011-06-18 14:50:24 +00:00
|
|
|
.ascii "SETUPLDR.SYS", NUL
|
2011-06-08 18:48:34 +00:00
|
|
|
no_isolinux_msg:
|
2011-06-18 14:50:24 +00:00
|
|
|
.ascii "SETUPLDR not found.", CR, LF, NUL
|
2011-06-08 18:48:34 +00:00
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// El Torito spec packet
|
|
|
|
//
|
|
|
|
.align 8
|
|
|
|
spec_packet:
|
2011-06-09 11:23:01 +00:00
|
|
|
.byte HEX(13) // Size of packet
|
2011-06-08 18:48:34 +00:00
|
|
|
sp_media:
|
2011-06-09 11:23:01 +00:00
|
|
|
.byte 0 // Media type
|
2011-06-08 18:48:34 +00:00
|
|
|
sp_drive:
|
2011-06-09 11:23:01 +00:00
|
|
|
.byte 0 // Drive number
|
2011-06-08 18:48:34 +00:00
|
|
|
sp_controller:
|
2011-06-09 11:23:01 +00:00
|
|
|
.byte 0 // Controller index
|
2011-06-08 18:48:34 +00:00
|
|
|
sp_lba:
|
2011-06-09 11:23:01 +00:00
|
|
|
.long 0 // LBA for emulated disk image
|
2011-06-08 18:48:34 +00:00
|
|
|
sp_devspec:
|
2011-06-09 11:23:01 +00:00
|
|
|
.word 0 // IDE/SCSI information
|
2011-06-08 18:48:34 +00:00
|
|
|
sp_buffer:
|
2011-06-09 11:23:01 +00:00
|
|
|
.word 0 // User-provided buffer
|
2011-06-08 18:48:34 +00:00
|
|
|
sp_loadseg:
|
2011-06-09 11:23:01 +00:00
|
|
|
.word 0 // Load segment
|
2011-06-08 18:48:34 +00:00
|
|
|
sp_sectors:
|
2011-06-09 11:23:01 +00:00
|
|
|
.word 0 // Sector count
|
2011-06-08 18:48:34 +00:00
|
|
|
sp_chs:
|
2011-06-09 11:23:01 +00:00
|
|
|
.byte 0,0,0 // Simulated CHS geometry
|
2011-06-08 18:48:34 +00:00
|
|
|
sp_dummy:
|
2011-06-09 11:23:01 +00:00
|
|
|
.byte 0 // Scratch, safe to overwrite
|
2011-06-08 18:48:34 +00:00
|
|
|
|
|
|
|
//
|
|
|
|
// EBIOS drive parameter packet
|
|
|
|
//
|
|
|
|
.align 8
|
|
|
|
drive_params:
|
2011-06-09 11:23:01 +00:00
|
|
|
.word 30 // Buffer size
|
2011-06-08 18:48:34 +00:00
|
|
|
dp_flags:
|
2011-06-09 11:23:01 +00:00
|
|
|
.word 0 // Information flags
|
2011-06-08 18:48:34 +00:00
|
|
|
dp_cyl:
|
2011-06-09 11:23:01 +00:00
|
|
|
.long 0 // Physical cylinders
|
2011-06-08 18:48:34 +00:00
|
|
|
dp_head:
|
2011-06-09 11:23:01 +00:00
|
|
|
.long 0 // Physical heads
|
2011-06-08 18:48:34 +00:00
|
|
|
dp_sec:
|
2011-06-09 11:23:01 +00:00
|
|
|
.long 0 // Physical sectors/track
|
2011-06-08 18:48:34 +00:00
|
|
|
dp_totalsec:
|
2011-06-09 11:23:01 +00:00
|
|
|
.long 0,0 // Total sectors
|
2011-06-08 18:48:34 +00:00
|
|
|
dp_secsize:
|
2011-06-09 11:23:01 +00:00
|
|
|
.word 0 // Bytes per sector
|
2011-06-08 18:48:34 +00:00
|
|
|
dp_dpte:
|
2011-06-09 11:23:01 +00:00
|
|
|
.long 0 // Device Parameter Table
|
2011-06-08 18:48:34 +00:00
|
|
|
dp_dpi_key:
|
2011-06-09 11:23:01 +00:00
|
|
|
.word 0 // 0BEDDh if rest valid
|
2011-06-08 18:48:34 +00:00
|
|
|
dp_dpi_len:
|
2011-06-09 11:23:01 +00:00
|
|
|
.byte 0 // DPI len
|
|
|
|
.byte 0
|
|
|
|
.word 0
|
2011-06-08 18:48:34 +00:00
|
|
|
dp_bus:
|
2011-06-09 11:23:01 +00:00
|
|
|
.byte 0,0,0,0 // Host bus type
|
2011-06-08 18:48:34 +00:00
|
|
|
dp_interface:
|
2011-06-09 11:23:01 +00:00
|
|
|
.byte 0,0,0,0,0,0,0,0 // Interface type
|
2011-06-08 18:48:34 +00:00
|
|
|
db_i_path:
|
2011-06-09 11:23:01 +00:00
|
|
|
.long 0,0 // Interface path
|
2011-06-08 18:48:34 +00:00
|
|
|
db_d_path:
|
2011-06-09 11:23:01 +00:00
|
|
|
.long 0,0 // Device path
|
|
|
|
.byte 0
|
2011-06-08 18:48:34 +00:00
|
|
|
db_dpi_csum:
|
2011-06-09 11:23:01 +00:00
|
|
|
.byte 0 // Checksum for DPI info
|
2011-06-08 18:48:34 +00:00
|
|
|
|
|
|
|
//
|
|
|
|
// EBIOS disk address packet
|
|
|
|
//
|
|
|
|
.align 8
|
|
|
|
dapa:
|
2011-06-09 11:23:01 +00:00
|
|
|
.word 16 // Packet size
|
2011-06-08 18:48:34 +00:00
|
|
|
.count:
|
2011-06-09 11:23:01 +00:00
|
|
|
.word 0 // Block count
|
2011-06-08 18:48:34 +00:00
|
|
|
.off:
|
2011-06-09 11:23:01 +00:00
|
|
|
.word 0 // Offset of buffer
|
2011-06-08 18:48:34 +00:00
|
|
|
.seg:
|
2011-06-09 11:23:01 +00:00
|
|
|
.word 0 // Segment of buffer
|
2011-06-08 18:48:34 +00:00
|
|
|
.lba:
|
2011-06-09 11:23:01 +00:00
|
|
|
.long 0 // LBA (LSW)
|
|
|
|
.long 0 // LBA (MSW)
|
2011-06-08 18:48:34 +00:00
|
|
|
|
|
|
|
.align 4
|
|
|
|
MaxTransfer:
|
2011-06-09 11:23:01 +00:00
|
|
|
.word 2 //32 // Max sectors per transfer
|
2011-06-08 18:48:34 +00:00
|
|
|
|
2011-06-09 11:23:01 +00:00
|
|
|
.org 2046 // Pad to file offset 2046
|
|
|
|
.word HEX(0aa55) // BootSector signature
|
2011-06-08 18:48:34 +00:00
|
|
|
|
|
|
|
.endcode16
|
|
|
|
|
|
|
|
END
|