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/isoboot.S?rev=52150&view=auto
==============================================================================
--- 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


Reply via email to