Author: tkreuzer
Date: Wed Jun 8 18:48:34 2011
New Revision: 52150
URL:
http://svn.reactos.org/svn/reactos?rev=52150&view=rev
Log:
[ISOBOOT]
Add portable asm version of iso boot sector
Added:
trunk/reactos/boot/freeldr/bootsect/isoboot.S (with props)
Added: trunk/reactos/boot/freeldr/bootsect/isoboot.S
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/bootsect/isob…
==============================================================================
--- trunk/reactos/boot/freeldr/bootsect/isoboot.S (added)
+++ trunk/reactos/boot/freeldr/bootsect/isoboot.S [iso-8859-1] Wed Jun 8 18:48:34 2011
@@ -1,0 +1,1073 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Bootsector for ISO file system
+ * FILE:
+ * PURPOSE:
+ * PROGRAMMERS: ?
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <asm.inc>
+
+.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 */
+#define WAIT_FOR_KEY
+
+
+// ****************************************************************************
+// 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)
+resb Files, MAX_OPEN * open_file_t_size
+
+
+/******************************************************************************/
+
+
+start:
+ cli // Disable interrupts
+ xor ax, ax // ax = segment zero
+ mov ss, ax // Initialize stack segment
+ mov sp, start // Set up stack
+ 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
+#ifdef WAIT_FOR_KEY
+ 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
+ mov ax, word ptr ds:[trackbuf]
+ cmp ax, 0
+ je .boot_cdrom // no boot sector found (hopefully there are no weird bootsectors
which begin with 0)
+ pop ax
+
+ // Display the 'Press key' message and wait for a maximum of 5 seconds
+ call crlf
+ mov si, presskey_msg // si points to 'Press key' message
+ 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
+
+ mov si, dot_msg // print '.'
+ call writestr
+ dec byte ptr ds:[TimeoutCount] // decrement timeout counter
+ jz .boot_harddisk
+ jmp .next_second
+
+.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)
+#endif
+
+.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]
+ mov si, spec_packet
+ 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
+
+ mov bx, HEX(8000) // bx = load address
+ mov si, di // restore file pointer
+ mov cx, HEX(0FFFF) // load the whole file
+ call getfssec // get the whole file
+
+#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
+ push 0 // push segment (0x0000)
+ mov eax, dword ptr ds:[HEX(8000) + HEX(0A8)] // load the RVA of the EntryPoint
into eax
+ add eax, HEX(8000) // RVA -> VA
+ push ax // push offset
+ retf // Transfer control to ROSLDR
+
+
+//
+// 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
+ cmp cl, '\'
+ 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
+ mov byte ptr ds:[di-1], '\'
+
+ 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)
+ mov si, spec_packet
+ mov byte ptr ds:[si], 13 ; Size of buffer
+ int 13h
+ 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
+ mov si, isolinux_str
+ call writestr
+ pop si
+ call writestr
+ pop ax
+ ret
+
+//
+// crlf: Print a newline
+crlf:
+ mov si, crlf_msg
+ // 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
+ and al, 0Fh
+ 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:
+ mov si, dapa // Load up the DAPA
+ mov word ptr ds:[si+4], bx
+ mov bx, es
+ mov word ptr ds:[si+6], bx
+ 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
+ ret
+
+ // INT 13h with retry
+xint13:
+ mov byte ptr ds:[RetryCount], retry_count
+.try:
+ pushad
+ int 13h
+ 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
+ mov si, err_bootfailed
+ 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:
+ .asciz "\r\nLoading IsoBoot...\r\n"
+copyright_str:
+ .asciz " (C) 1994-2002 H. Peter Anvin\r\n"
+presskey_msg:
+ .asciz "Press any key to boot from CD"
+dot_msg:
+ .asciz "."
+
+#ifdef DEBUG_MESSAGES
+startup_msg:
+ .asciz "Startup, DL = '"
+spec_ok_msg:
+ .asciz "packet OK, drive = "
+secsize_msg:
+ .asciz "size appears to be "
+rootloc_msg:
+ .asciz "Root dir loc: "
+rootlen_msg:
+ .asciz "Root dir len: "
+rootsect_msg:
+ .asciz "Root dir len(sect): "
+fileloc_msg:
+ .asciz "SETUPLDR loc: "
+filelen_msg:
+ .asciz "SETUPLDR len: "
+filesect_msg:
+ .asciz "SETUPLDR len(sect): "
+findfail_msg:
+ .asciz "Failed to find file!"
+startldr_msg:
+ .asciz "Starting SETUPLDR.SYS"
+#endif
+
+spec_err_msg:
+ .asciz "Load spec failed, trying wing ...\r\n"
+maybe_msg:
+ .asciz "Found smth at drive = "
+alright_msg:
+ .asciz "might be ok, continuing...\r\n"
+nothing_msg:
+ .asciz "Failed locate CD-ROM; boot failed.\r\n"
+
+isolinux_str:
+ .asciz "IsoBoot: "
+crlf_msg:
+ .asciz "\r\n"
+diskerr_msg:
+ .asciz "Disk error "
+ondrive_str:
+ .asciz ", drive "
+
+err_bootfailed:
+ .asciz "\r\nfailed.."
+isolinux_dir:
+ .asciz "\\LOADER"
+no_dir_msg:
+ .asciz "LOADER dir not found.\r\n"
+isolinux_bin:
+ .asciz "SETUPLDR.SYS"
+no_isolinux_msg:
+ .asciz "SETUPLDR not found.\r\n"
+
+
+//
+// El Torito spec packet
+//
+.align 8
+spec_packet:
+ db HEX(13) // Size of packet
+sp_media:
+ db 0 // Media type
+sp_drive:
+ db 0 // Drive number
+sp_controller:
+ db 0 // Controller index
+sp_lba:
+ dd 0 // LBA for emulated disk image
+sp_devspec:
+ dw 0 // IDE/SCSI information
+sp_buffer:
+ dw 0 // User-provided buffer
+sp_loadseg:
+ dw 0 // Load segment
+sp_sectors:
+ dw 0 // Sector count
+sp_chs:
+ db 0,0,0 // Simulated CHS geometry
+sp_dummy:
+ db 0 // Scratch, safe to overwrite
+
+//
+// EBIOS drive parameter packet
+//
+.align 8
+drive_params:
+ dw 30 // Buffer size
+dp_flags:
+ dw 0 // Information flags
+dp_cyl:
+ dd 0 // Physical cylinders
+dp_head:
+ dd 0 // Physical heads
+dp_sec:
+ dd 0 // Physical sectors/track
+dp_totalsec:
+ dd 0,0 // Total sectors
+dp_secsize:
+ dw 0 // Bytes per sector
+dp_dpte:
+ dd 0 // Device Parameter Table
+dp_dpi_key:
+ dw 0 // 0BEDDh if rest valid
+dp_dpi_len:
+ db 0 // DPI len
+ db 0
+ dw 0
+dp_bus:
+ db 0,0,0,0 // Host bus type
+dp_interface:
+ db 0,0,0,0,0,0,0,0 // Interface type
+db_i_path:
+ dd 0,0 // Interface path
+db_d_path:
+ dd 0,0 // Device path
+ db 0
+db_dpi_csum:
+ db 0 // Checksum for DPI info
+
+//
+// EBIOS disk address packet
+//
+.align 8
+dapa:
+ dw 16 // Packet size
+.count:
+ dw 0 // Block count
+.off:
+ dw 0 // Offset of buffer
+.seg:
+ dw 0 // Segment of buffer
+.lba:
+ dd 0 // LBA (LSW)
+ dd 0 // LBA (MSW)
+
+.align 4
+MaxTransfer:
+ dw 2 //32 // Max sectors per transfer
+
+.org 2047 // Pad to file offset 2046
+.word 0aa55h // BootSector signature
+
+.endcode16
+
+END
Propchange: trunk/reactos/boot/freeldr/bootsect/isoboot.S
------------------------------------------------------------------------------
svn:eol-style = native