]> git.saurik.com Git - apple/boot.git/commitdiff
boot-93.tar.gz mac-os-x-102 mac-os-x-1021 mac-os-x-1022 mac-os-x-1023 mac-os-x-1024 mac-os-x-1025 mac-os-x-1026 mac-os-x-1027 mac-os-x-1028 mac-os-x-1028g5 v93
authorApple <opensource@apple.com>
Wed, 10 Jul 2002 00:50:52 +0000 (00:50 +0000)
committerApple <opensource@apple.com>
Wed, 10 Jul 2002 00:50:52 +0000 (00:50 +0000)
84 files changed:
Makefile
gen/Makefile
gen/libsa/Makefile
gen/libsaio/disk.c
gen/libsaio/ufs_byteorder.c
gen/libsaio/ufs_byteorder.h
gen/rcz/Makefile
gen/rcz/rcz.c
gen/rcz/rcz_compress_mem.c
gen/rcz/rcz_decompress_mem.c
i386/Makefile
i386/boot0/boot0.s
i386/boot1/boot1.s
i386/boot2/Makefile
i386/boot2/appleClut8.h [new file with mode: 0644]
i386/boot2/boot.c
i386/boot2/boot.h
i386/boot2/boot2.s
i386/boot2/drivers.c
i386/boot2/graphics.c
i386/boot2/happy_screen.h [new file with mode: 0644]
i386/boot2/options.c [new file with mode: 0644]
i386/boot2/prompt.c
i386/libsa/Makefile
i386/libsa/bswap.c [deleted file]
i386/libsa/libsa.h
i386/libsa/memory.h
i386/libsa/string.c
i386/libsaio/Makefile
i386/libsaio/appleClut8.h [deleted file]
i386/libsaio/asm.s
i386/libsaio/bios.h
i386/libsaio/bios.s
i386/libsaio/biosfn.c
i386/libsaio/bootstruct.c
i386/libsaio/cache.c
i386/libsaio/cache.h [deleted file]
i386/libsaio/console.c
i386/libsaio/disk.c
i386/libsaio/fdisk.h [new file with mode: 0644]
i386/libsaio/gets.c [deleted file]
i386/libsaio/hfs.c [new file with mode: 0644]
i386/libsaio/hfs_CaseTables.h [new file with mode: 0644]
i386/libsaio/hfs_compare.c [new file with mode: 0644]
i386/libsaio/legacy/PCI.h [deleted file]
i386/libsaio/legacy/asm.h [deleted file]
i386/libsaio/legacy/disk.h [deleted file]
i386/libsaio/legacy/fdisk.h [deleted file]
i386/libsaio/libsaio.h
i386/libsaio/load.c
i386/libsaio/misc.c
i386/libsaio/nbp.c
i386/libsaio/nbp.h [deleted file]
i386/libsaio/old/bios_old.s [deleted file]
i386/libsaio/old/shmalloc.c [deleted file]
i386/libsaio/old/stringTable.h.00 [deleted file]
i386/libsaio/old/stringTableNew.c [deleted file]
i386/libsaio/pci.c
i386/libsaio/pci.h
i386/libsaio/saio.h [deleted file]
i386/libsaio/saio_internal.h
i386/libsaio/saio_types.h
i386/libsaio/sl.h [new file with mode: 0644]
i386/libsaio/stringTable.c
i386/libsaio/sys.c
i386/libsaio/table.c
i386/libsaio/ufs.c [new file with mode: 0644]
i386/libsaio/ufs_byteorder.c
i386/libsaio/ufs_byteorder.h
i386/libsaio/vbe.c
i386/libsaio/vbe.h
i386/libsaio/vga.c [deleted file]
i386/libsaio/vga.h [deleted file]
i386/nasm/Makefile
i386/nasm/assemble.c
i386/rcz/Makefile
i386/rcz/rcz_compress_mem.c
i386/rcz/rcz_decompress_mem.c
i386/testmodule/install/install.module [deleted file]
i386/testmodule/test.module [deleted file]
i386/tests/sizeof [deleted file]
i386/util/Makefile
i386/util/dumptiff [deleted file]
i386/util/tif_packbits.c

index 0724682157b4f883cfecdfc98980f3368ff6fc00..fe88a53ace033ff1d4cd8de12f86265eff4435a0 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ export USE_APPLE_PB_SUPPORT = all
 
 #      Makefile for kernel booter
 
-# CFLAGS       = -O $(MORECPP) -arch i386 -g -munaligned-text
+# CFLAGS       = -O $(MORECPP) -arch i386 -g 
 DEFINES=
 CONFIG = hd
 LIBDIR = libsa
index b9ce995fc717589cd4059d52f1ff046f12ceb35c..2d2f67d871d31d01a432fab1556ceda034c783d6 100644 (file)
@@ -3,7 +3,7 @@
 #  Machine-independent code
 #
 
-#CFLAGS        = -O $(MORECPP) -arch i386 -g -munaligned-text
+#CFLAGS        = -O $(MORECPP) -arch i386 -g
 DEFINES=
 CONFIG = hd
 LIBDIR = libsa
index 20c0a10c7f942c28048c881a72cf08310959fc13..dd6b61a9e1a5c48f966dd53f1fc4ba6229e85896 100644 (file)
@@ -6,7 +6,7 @@ UTILDIR = ../util
 INSTALL_MI_DIR = $(DSTROOT)/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders/machdep/machine
 
 DEBUG = -O
-CFLAGS = $(DEBUG) $(MORECPP) -arch i386 -g -Wmost -Wno-precomp -munaligned-text
+CFLAGS = $(DEBUG) $(MORECPP) -arch i386 -g -Wmost -Wno-precomp
 DEFINES=
 CONFIG = hd
 INC = -I. -I$(SYMROOT) -I$(UTILDIR)
index 77bbba04e380d7f43278f50a57e36b87b6336ba9..9f99c83cd0005948d16877479bc7ad012fb68781 100644 (file)
@@ -47,8 +47,8 @@
 #define DRIVER_PRIVATE
 
 #import "sys/types.h"
-#import <bsd/dev/disk.h>
-#import <bsd/dev/i386/disk.h>
+#import <dev/disk.h>
+#import <dev/i386/disk.h>
 #import "libsaio.h"
 #import "memory.h"
 
index 45640aad2412008e07b3015bbfffd90ba2f43c78..ab906323184a6ea4e9a623f376395ccf43c8101d 100644 (file)
  * All rights reserved.
  */
 
-#import <bsd/sys/types.h>
-#import <bsd/sys/param.h>
-#import <bsd/sys/vnode.h>
-#import <bsd/ufs/fsdir.h>
+#import <sys/types.h>
+#import <sys/param.h>
+#import <sys/vnode.h>
+#import <ufs/fsdir.h>
 #import <architecture/byte_order.h>
 #import "ufs_byteorder.h"
 #import "libsaio.h"
index 7ee6dcf3a68730277c87c7729c5affb0a5da56c3..ed353f7e3a509d66e1674020fcd9d7f170cbf720 100644 (file)
  * 8 Jul 1992 Brian Pinkerton at NeXT
  *      Created.
  */
-#import <bsd/sys/disktab.h>
-#import <bsd/sys/vnode.h>
-#import <bsd/sys/buf.h>
-#import <bsd/dev/disk.h>
-#import <bsd/ufs/fs.h>
-#import <bsd/ufs/inode.h>
+#import <sys/disktab.h>
+#import <sys/vnode.h>
+#import <sys/buf.h>
+#import <dev/disk.h>
+#import <ufs/fs.h>
+#import <ufs/inode.h>
 
 void byte_swap_ints(int *array, int count);
 void byte_swap_shorts(short *array, int count);
index 077094e4aab07a76540e5cd158c901aebe080608..308c033d4d280ea75e8b9638fae822b17b3b6346 100644 (file)
@@ -8,7 +8,7 @@ USRBIN = $(DSTROOT)/usr/bin
 INSTALLDIR = $(DSTROOT)/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders/standalone
 
 DEBUG = -O
-CFLAGS = $(DEBUG) $(MORECPP) $(RC_CFLAGS) -g -Wmost -Wno-precomp -traditional-cpp
+CFLAGS = $(DEBUG) $(MORECPP) $(RC_CFLAGS) -g -Wmost -Werror
 DEFINES=
 CONFIG = hd
 INC = -I. -I$(SYMROOT) -I$(UTILDIR) -I$(LIBSADIR)
index e3c15a166d25311c73876908b3f10c475a9aabea..6155f0cb424a7dfaa9d0cc3f55430f26b762fa40 100644 (file)
@@ -22,6 +22,7 @@
  * @APPLE_LICENSE_HEADER_END@
  */
 #import <stdio.h>
+#import <stdlib.h>
 #import <mach/mach.h>
 #import <mach/mach_error.h>
 #import <mach/mach_traps.h>
@@ -40,12 +41,12 @@ usage(void)
     exit(1);
 }
 
-main(int argc, char *argv[])
+int main(int argc, char *argv[])
 {
     char *infile = NULL, *outfile = NULL;
     int compress = 0;
     int verbose = 0;
-    FILE *inf, *outf;
+    FILE *inf, *outf = NULL;
     unsigned char *inbuf, *outbuf;
     unsigned long length, total;
     kern_return_t ret;
@@ -113,7 +114,7 @@ main(int argc, char *argv[])
        }
 
        fseek(inf,0,2); length = ftell(inf); rewind(inf);
-       if ((ret = map_fd(fileno(inf), 0, &inbuf, TRUE, length)) != KERN_SUCCESS) {
+       if ((ret = map_fd(fileno(inf), 0, (vm_address_t *)&inbuf, TRUE, length)) != KERN_SUCCESS) {
            mach_error("map_fd", ret);  
            exit(1);
        }
@@ -123,7 +124,7 @@ main(int argc, char *argv[])
        if (verbose)
            fprintf(stderr, "%ld %ld\nCompression ratio: %f\n", length, total, total/(1.0*length));
        fclose(inf);
-       vm_deallocate(mach_task_self(), inbuf, length);
+       vm_deallocate(mach_task_self(), (vm_address_t)inbuf, length);
        fclose(outf);
     } else {
        unsigned char *ptr;
@@ -149,7 +150,7 @@ main(int argc, char *argv[])
                }
        }
        fseek(inf,0,2); length = ftell(inf); rewind(inf);
-       if ((ret = map_fd(fileno(inf), 0, &inbuf, TRUE, length)) != KERN_SUCCESS) {
+       if ((ret = map_fd(fileno(inf), 0, (vm_address_t *)&inbuf, TRUE, length)) != KERN_SUCCESS) {
            mach_error("map_fd", ret);  
            exit(1);
        }
@@ -171,7 +172,7 @@ main(int argc, char *argv[])
        if (verbose)
            fprintf(stderr, "%ld %ld\nCompression ratio: %f\n", length, total, total/(1.0*length));
        fclose(inf);
-       vm_deallocate(mach_task_self(), inbuf, length);
+       vm_deallocate(mach_task_self(), (vm_address_t)inbuf, length);
        fclose(outf);
     }
     exit(0);
index af4470416d49b3fd33aee035720ad38ff4079d0e..56a58c206ef3f60ad944aea0952591a5569f0bd1 100644 (file)
@@ -44,9 +44,9 @@ rcz_compress_memory(
 ) 
 /* Returns actual number of bytes emitted as compressed stream 'out.' */
 {
-    unsigned int c, ct, j, jmatch, jabove, match;
-    unsigned int data[32], version;
-    unsigned int word, token, tokenct, total;
+    unsigned int c, ct, j, jmatch = 0, jabove, match;
+    unsigned int data[32];
+    unsigned int word, token, tokenct;
     unsigned char *outorigin = out;
 
 /* First, put version number into stream. */
index b5a3f86dc411d606c5d7b14099659bf6313d033d..e223f492b6a3634214ae28871357b5917dc1c4aa 100644 (file)
@@ -46,7 +46,6 @@ rcz_decompress_memory(unsigned char *in, unsigned char *out)
     unsigned int c, j, k, jmatch, jabove;
     unsigned int length, even_length, word, token, version;
     unsigned char *outorigin = out;
-    int *a, *b;
 
     version = *in++;
     version = (version<<8) | (*in++);
index a05daf6627a1584457c57a51b8649e2056dda6a3..88b7ee30c06be64d4ad847ccb64a669865dc0c7a 100644 (file)
@@ -2,7 +2,7 @@
 #      Makefile for i386 boot program
 #      define FLOPPY and SMALL using DEFINES macro as necessary
 
-CFLAGS = -O $(MORECPP) -arch i386 -g -mi386:unaligned-text -static
+CFLAGS = -O $(MORECPP) -arch i386 -g -static
 DEFINES=
 CONFIG = hd
 LIBDIR = libsa
index dcf9c843bbc58e1923066690516c63d083159762..f1eb72ed999698bf4de2ceee612e17ced99d45ca 100644 (file)
 ; responsibility is to locate the booter partition, load the
 ; booter into memory, and jump to the booter's entry point.
 ; The booter partition can be a primary or a logical partition.
-; But the booter partition must reside within the 8GB limit
-; imposed by CHS addressing + translation.
 ; 
 ; This boot loader can be placed at any of the following places:
-; * Master Boot Record (MBR)
-; * Boot sector of an extended partition
-; * Boot sector of a primary partition
-; * Boot sector of a logical partition
+; 1. Master Boot Record (MBR)
+; 2. Boot sector of an extended partition
+; 3. Boot sector of a primary partition
+; 4. Boot sector of a logical partition
 ;
 ; In order to coexist with a fdisk partition table (64 bytes), and
 ; leave room for a two byte signature (0xAA55) in the end, boot0 is
 ; restricted to 446 bytes (512 - 64 - 2). If boot0 did not have to
-; live in the MBR, then we would have 510 bytes to play with.
+; live in the MBR, then we would have 510 bytes to work with.
 ;
-; boot0 is always loaded by the BIOS or another first level booter
-; to 0:7C00h.
+; boot0 is always loaded by the BIOS or another booter to 0:7C00h.
 ;
 ; This code is written for the NASM assembler.
 ;   nasm boot0.s -o boot0
 
-;--------------------------------------------------------------------------
-; Constants.
 
-DEBUG           EQU  0                  ; enable debugging output
+;
+; Set to 1 to enable obscure debug messages.
+;
+DEBUG                EQU  0
+
+;
+; Set to 1 to support loading the booter (boot2) from a
+; logical partition.
+;
+EXT_PART_SUPPORT     EQU  1
+
+;
+; Various constants.
+;
+kBoot0Segment        EQU  0x0000
+kBoot0Stack          EQU  0xFFF0        ; boot0 stack pointer
+kBoot0LoadAddr       EQU  0x7C00        ; boot0 load address
+kBoot0RelocAddr      EQU  0xE000        ; boot0 relocated address
+
+kMBRBuffer           EQU  0x1000        ; MBR buffer address
+kExtBuffer           EQU  0x1200        ; EXT boot block buffer address
 
-BOOTSEG         EQU  0x0                ; our sole segment
-BOOTSP          EQU  0xFFF0             ; stack pointer
-BOOTLOAD        EQU  0x7C00             ; booter load address
-BOOTRELOC       EQU  0xE000             ; booter is relocated here
-BOOTSIG         EQU  0xAA55             ; booter signature
+kPartTableOffset     EQU  0x1be
+kMBRPartTable        EQU  kMBRBuffer + kPartTableOffset
+kExtPartTable        EQU  kExtBuffer + kPartTableOffset
 
-BOOT2_SIZE      EQU  88                 ; load this many blocks for boot2
-BOOT2_ADDR      EQU  0x3000             ; where to load boot2
+kBoot2Sectors        EQU  112           ; sectors to load for boot2
+kBoot2Address        EQU  0x0000        ; boot2 load address
+kBoot2Segment        EQU  0x2000        ; boot2 load segment
 
-DRIVE_NUM       EQU  0x80               ; "C" drive
-SECTOR_BYTES    EQU  512                ; sector size in bytes
+kSectorBytes         EQU  512           ; sector size in bytes
+kBootSignature       EQU  0xAA55        ; boot sector signature
 
-BUF_MBR         EQU  0x1000             ; memory buffer for MBR
-BUF_EXT         EQU  0x1200             ; memory buffer for extended partition
+kPartCount           EQU  4             ; number of paritions per table
+kPartTypeBoot        EQU  0xab          ; boot2 partition type
+kPartTypeExtDOS      EQU  0x05          ; DOS extended partition type
+kPartTypeExtWin      EQU  0x0f          ; Windows extended partition type
+kPartTypeExtLinux    EQU  0x85          ; Linux extended partition type
 
-TABLE_MAIN      EQU  BUF_MBR + 0x1be    ; location of main partition table
-TABLE_EXT       EQU  BUF_EXT + 0x1be    ; location of ext partition table
-ENTRY_SIZE      EQU  16                 ; size of each fdisk partition entry
-TYPE_BOOT       EQU  0xab               ; partition type we are looking for
-TYPE_EXT        EQU  0x05               ; extended partition type
-TYPE_EXT_1      EQU  0x0f               ; Windows extended partition
-TYPE_EXT_2      EQU  0x85               ; Linux extended partition
-EXT_LEVELS_MAX  EQU  128                ; max extended partition levels
+%ifdef FLOPPY
+kDriveNumber         EQU  0x00
+%else
+kDriveNumber         EQU  0x80
+%endif
+
+;
+; In memory variables.
+;
+ebios_lba       dd   0   ; starting LBA of the intial extended partition.
+read_func       dw   0   ; pointer to the LBA or CHS read function
 
-; Disk parameters gathered through INT13/F8 call.
 ;
-max_sectors     db   0                  ; number of sectors per track
-max_heads       db   0                  ; number of heads
+; Format of fdisk partition entry.
+;
+; The symbol 'part_size' is automatically defined as an `EQU'
+; giving the size of the structure.
+;
+           struc part
+.bootid:   resb 1      ; bootable or not 
+.head:     resb 1      ; starting head, sector, cylinder
+.sect:     resb 1      ;
+.cyl:      resb 1      ;
+.type:     resb 1      ; partition type
+.endhead   resb 1      ; ending head, sector, cylinder
+.endsect:  resb 1      ;
+.endcyl:   resb 1      ;
+.lba:      resd 1      ; starting lba
+.sectors   resd 1      ; size in sectors
+           endstruc
 
-; Parameters to our load function.
 ;
-chs_cx          dw   0                  ; cx register for INT13/F2 call
-chs_dx          dw   0                  ; dx register for INT13/F2 call
+; Macros.
+;
+%macro DebugCharMacro 1
+    mov   al, %1
+    call  print_char
+%endmacro
 
+%if DEBUG
+%define DebugChar(x)  DebugCharMacro x
+%else
+%define DebugChar(x)
+%endif
 
 ;--------------------------------------------------------------------------
 ; Start of text segment.
 
     SEGMENT .text
 
-    ORG     0xE000              ; must match BOOTRELOC
+    ORG     0xE000                  ; must match kBoot0RelocAddr
 
 ;--------------------------------------------------------------------------
-; Loaded at 0:7c00h.
+; Boot code is loaded at 0:7C00h.
 ;
 start
-    ; Set up the stack to grow down from BOOTSEG:BOOTSP.
+    ;
+    ; Set up the stack to grow down from kBoot0Segment:kBoot0Stack.
     ; Interrupts should be off while the stack is being manipulated.
     ;
-    cli                         ; interrupts off
-    mov     ax, BOOTSEG         ;
-    mov     ss, ax              ; ss <- BOOTSEG
-    mov     sp, BOOTSP          ; sp <- BOOTSP
-    sti                         ; reenable interrupts
+    cli                             ; interrupts off
+    xor     ax, ax                  ; zero ax
+    mov     ss, ax                  ; ss <- 0
+    mov     sp, kBoot0Stack         ; sp <- top of stack
+    sti                             ; reenable interrupts
+
+    mov     es, ax                  ; es <- 0
+    mov     ds, ax                  ; ds <- 0
 
-    ; Relocate the booter code from DS:SI to ES:DI,
-    ; or from 0:7C00h to BOOTSEG:BOOTRELOC.
     ;
-    mov     es, ax              ; es <- BOOTSEG
-    xor     ax, ax
-    mov     ds, ax              ; ds <- 0
-    mov     si, BOOTLOAD        ; si <- BOOTLOAD (source)
-    mov     di, BOOTRELOC       ; di <- BOOTRELOC (destination)
+    ; Relocate boot0 code.
     ;
-    cld                         ; auto-increment SI and/or DI registers
-    mov     cx, 256             ; copy 256 words (512 bytes)
-    repnz   movsw               ; repeat string move (word) operation
+    mov     si, kBoot0LoadAddr      ; si <- source
+    mov     di, kBoot0RelocAddr     ; di <- destination
+    ;
+    cld                             ; auto-increment SI and/or DI registers
+    mov     cx, kSectorBytes/2      ; copy 256 words
+    repnz   movsw                   ; repeat string move (word) operation
 
     ; Code relocated, jump to start_reloc in relocated location.
     ;
-    jmp     BOOTSEG:start_reloc
+    jmp     0:start_reloc
 
 ;--------------------------------------------------------------------------
 ; Start execution from the relocated location.
 ;
-start_reloc
-    mov     ax, BOOTSEG
-    mov     ds, ax              ; ds <- BOOTSEG
+start_reloc:
+
+    DebugChar('>')
 
-    mov     al, '='             ; indicate execution start
-    call    putchar
+    mov     dl, kDriveNumber        ; starting BIOS drive number
+
+.loop:
+
+%if DEBUG
+    mov     al, dl
+    call    print_hex
+%endif
 
-    ; Get disk parameters (CHS) using INT13/F8 call.
     ;
-    mov     dl, DRIVE_NUM       ; boot drive is drive C
-    mov     ah, 8               ; Read Disk Driver Parameter function
-    int     0x13
-    and     cl, 0x3f            ; sectors/track
-    mov     [max_sectors], cl
-    mov     [max_heads], dh
-    jc      error
-
-    mov     al, '>'             ; indicate INT13/F8 success
-    call    putchar
-
-    ; Since this code may not always reside in the MBR, we will always
-    ; start by loading the MBR to BUF_MBR.
-    ;
-    mov     WORD [chs_cx], 0x0001       ; cyl = 0, sect = 1
-    mov     BYTE [chs_dx + 1], 0        ; head = 0
-    xor     cx, cx                      ; skip 0 sectors
-    mov     ax, 1                       ; read 1 sector
-    mov     bx, BUF_MBR                 ; load buffer
+    ; Clear various flags in memory.
+    ;
+    xor     eax, eax
+    mov     [ebios_lba], eax            ; clear EBIOS LBA offset
+    mov     WORD [read_func], read_chs  ; assume CHS support
+
+    ;
+    ; Since this code may not always reside in the MBR, always start by
+    ; loading the MBR to kMBRBuffer.
+    ;
+    mov     al, 1                   ; load one sector
+    xor     bx, bx
+    mov     es, bx                  ; MBR load segment = 0
+    mov     bx, kMBRBuffer          ; MBR load address
+    mov     si, bx                  ; pointer to fake partition entry
+    mov     WORD [si], 0x0000       ; CHS DX: head = 0
+    mov     WORD [si + 2], 0x0001   ; CHS CX: cylinder = 0, sector = 1
+
     call    load
-    jc      error
+    jc      .next_drive             ; MBR load error
 
-    mov     di, TABLE_MAIN              ; argument for find_booter
-    cmp     WORD [di + 64], BOOTSIG     ; correct signature found?
-    jne     error                       ; Oops! no signature!
-    mov     bl, TYPE_BOOT               ; look for this partition type
-    mov     bh, 0                       ; initial nesting level is 0
-    call    find_booter
+    ;
+    ; Check if EBIOS is supported for this hard drive.
+    ;
+    mov     ah, 0x41                ; Function 0x41
+    mov     bx, 0x55AA              ; check signature
+;   mov     dl, kDriveNumber        ; Drive number
+    int     0x13
 
-error
-    mov     si, load_error
-    call    message
-hang_1
-    jmp     hang_1
+    ;
+    ; If successful, the return values are as follows:
+    ;
+    ; carry = 0
+    ; ah    = major version of EBIOS extensions (0x21 = version 1.1)
+    ; al    = altered
+    ; bx    = 0xAA55
+    ; cx    = support bits. bit 0 must be set for function 0x42.
+    ;
+    jc      .ebios_check_done
+    cmp     bx, 0xAA55              ; check BX = 0xAA55
+    jnz     .ebios_check_done
+    test    cl, 0x01                ; check enhanced drive read support
+    mov     WORD [read_func], read_lba  ; use read_lba for reads
+    DebugChar('E')                  ; EBIOS supported
+.ebios_check_done:
+
+    ;
+    ; Look for the booter partition in the MBR partition table,
+    ; which is at offset kMBRPartTable.
+    ;
+    mov     di, kMBRPartTable       ; pointer to partition table
+    mov     ah, 0                   ; initial nesting level is 0
+    call    find_boot               ; will not return on success
+
+.next_drive:
+    inc     dl                      ; next drive number
+    test    dl, 0x4                 ; went through all 4 drives?
+    jz      .loop                   ; not yet, loop again
+
+    mov     si, boot_error_str
+    call    print_string
+
+hang:
+    jmp     SHORT hang
 
 ;--------------------------------------------------------------------------
-; Locate the booter partition and load the booter.
+; Find the boot partition and load the booter from the partition.
 ;
 ; Arguments:
-;   di - pointer to fdisk partition table.
-;   bl - partition type to look for.
+;   AH = recursion nesting level
+;   DL = drive number (0x80 + unit number)
+;   DI = pointer to fdisk partition table.
 ;
-; The following registers are modified:
-;   ax, bh
+; Clobber list:
+;   AX, BX, EBP
 ;
-find_booter
-    push    cx
+find_boot:
+    push    cx                      ; preserve CX and SI
     push    si
 
-    mov     si, di              ; si <- pointer to partition table
-    mov     cx, 4               ; 4 partition entries per table
-
-find_booter_pri
     ;
-    ; Hunt for a fdisk partition type that matches the value in bl.
+    ; Check for boot block signature 0xAA55 following the 4 partition
+    ; entries.
     ;
-%IF DEBUG
-    mov     al, bh              ; log partition type seen
-    call    putspace
-    mov     al, [si + 4]
-    call    display_byte
-%ENDIF
-
-    cmp     BYTE [si + 4], bl   ; Is this the booter partition?
-    je      load_booter         ; yes, load the booter
+    cmp     WORD [di + part_size * kPartCount], kBootSignature
+    jne     .exit                   ; boot signature not found
 
-    add     si, ENTRY_SIZE      ; si <- next partition entry
-    loop    find_booter_pri     ; loop while cx is not zero
+    mov     si, di                  ; make SI a pointer to partition table
+    mov     cx, kPartCount          ; number of partition entries per table
 
-    ; No primary (or perhaps logical) booter partition found in the
-    ; current partition table. Restart and look for extended partitions.
+.loop:
     ;
-    mov     si, di              ; si <- pointer to partition table
-    mov     cx, 4               ; 4 partition entries per table
+    ; First scan through the partition table looking for the boot
+    ; partition. Postpone walking the extended partition chain for
+    ; the second pass. Do not merge the two without changing the
+    ; buffering scheme used to store extended partition tables.
+    ;
+%if DEBUG
+    mov     al, ah                  ; indent based on nesting level
+    call    print_spaces
+    mov     al, [si + part.type]    ; print partition type
+    call    print_hex
+%endif
+
+    cmp     BYTE [si + part.type], kPartTypeBoot
+    jne     .continue
 
-find_booter_ext
     ;
-    ; Look for extended partition entries in the partition table.
+    ; Found boot partition, read boot2 image to memory.
     ;
-%IF DEBUG
-    mov     al, bh              ; log partition type seen
-    call    putspace
-    mov     al, 'E'
-    call    putchar
-    mov     al, [si + 4]
-    call    display_byte
-%ENDIF
+    mov     al, kBoot2Sectors
+    mov     bx, kBoot2Segment
+    mov     es, bx
+    mov     bx, kBoot2Address
+    call    load                    ; will not return on success
+    jc      .continue               ; load error, keep looking?
 
-    cmp     BYTE [si + 4], TYPE_EXT     ; Is this an extended partition?
-    je      find_booter_ext_2           ; yes, load its partition table
+    ;
+    ; Jump to boot2. The drive number is already in register DL.
+    ;
+    ; The first sector loaded from the disk is reserved for the boot
+    ; block (boot0), adjust the jump location by adding a sector offset.
+    ;
+    jmp     kBoot2Segment:kBoot2Address + kSectorBytes
 
-    cmp     BYTE [si + 4], TYPE_EXT_1   ; Is this an extended partition?
-    je      find_booter_ext_2           ; yes, load its partition table
-       
-    cmp     BYTE [si + 4], TYPE_EXT_2   ; Is this an extended partition?
-    je      find_booter_ext_2           ; yes, load its partition table
+.continue:
+    add     si, part_size           ; advance SI to next partition entry
+    loop    .loop                   ; loop through all partition entries
 
-find_booter_ext_1
+%if EXT_PART_SUPPORT
     ;
-    ; si is not pointing to an extended partition entry,
-    ; try the next entry in the partition table.
+    ; No primary (or logical) boot partition found in the current
+    ; partition table. Restart and look for extended partitions.
     ;
-    add     si, ENTRY_SIZE      ; si <- next partition entry
-    loop    find_booter_ext     ; loop while cx is not zero
+    mov     si, di                  ; make SI a pointer to partition table
+    mov     cx, kPartCount          ; number of partition entries per table
 
-    jmp     find_booter_end     ; give up
+.ext_loop:
 
-find_booter_ext_2
-    cmp     bh, EXT_LEVELS_MAX
-    ja      find_booter_end     ; in too deep!
+    mov     al, [si + part.type]    ; AL <- partition type
 
-    inc     bh                  ; increment nesting level counter
+    cmp     al, kPartTypeExtDOS     ; Extended DOS
+    je      .ext_load
 
-    ; Prepare the arguments for the load function call to
-    ; load the extended partition table into memory.
-    ; Note that si points to the extended partition entry.
-    ;
-    mov     ax, [si]            ; DH/DL
-    mov     [chs_dx], ax
-    mov     ax, [si + 2]        ; CH/CL
-    mov     [chs_cx], ax
-    pusha
-    xor     cx, cx              ; skip 0 sectors
-    mov     ax, 1               ; read 1 sector
-    mov     bx, BUF_EXT         ; load to BUF_EXT
-    call    load
-    popa
+    cmp     al, kPartTypeExtWin     ; Extended Windows(95)
+    je      .ext_load
 
-    jc      find_booter_ext_3   ; bail out if load failed
+    cmp     al, kPartTypeExtLinux   ; Extended Linux
+    je      .ext_load
 
-    mov     di, TABLE_EXT       ; di <- pointer to new partition table
-    cmp     WORD [di + 64], BOOTSIG
-    jne     find_booter_ext_3   ; OhOh! no signature!
+.ext_continue:
+    ;
+    ; Advance si to the next partition entry in the extended
+    ; partition table.
+    ;
+    add     si, part_size           ; advance SI to next partition entry
+    loop    .ext_loop               ; loop through all partition entries
+    jmp     .exit                   ; boot partition not found
 
-    call    find_booter         ; recursion...
+.ext_load:
+    ;
+    ; Setup the arguments for the load function call to bring the
+    ; extended partition table into memory.
+    ; Remember that SI points to the extended partition entry.
+    ;
+    mov     al, 1                   ; read 1 sector
+    xor     bx, bx
+    mov     es, bx                  ; es = 0
+    mov     bx, kExtBuffer          ; load extended boot sector
+    call    load
+    jc      .ext_continue           ; load error
 
-find_booter_ext_3
-    dec     bh                  ; decrement nesting level counter
+    ;
+    ; The LBA address of all extended partitions is relative based
+    ; on the LBA address of the extended partition in the MBR, or
+    ; the extended partition at the head of the chain. Thus it is
+    ; necessary to save the LBA address of the first extended partition.
+    ;
+    or      ah, ah
+    jnz     .ext_find_boot
+    mov     ebp, [si + part.lba]
+    mov     [ebios_lba], ebp
+
+.ext_find_boot:
+    ;
+    ; Call find_boot recursively to scan through the extended partition
+    ; table. Load DI with a pointer to the extended table in memory.
+    ;
+    inc     ah                      ; increment recursion level
+    mov     di, kExtPartTable       ; partition table pointer
+    call    find_boot               ; recursion...
+    ;dec    ah
 
-    ; If we got here, then we know there isn't a booter
-    ; partition linked from this partition entry.
+    ;
+    ; Since there is an "unwritten" rule that limits each partition table
+    ; to have 0 or 1 extended partitions, there is no point in looking for
+    ; any additional extended partition entries at this point. There is no
+    ; boot partition linked beyond the extended partition that was loaded
+    ; above.
+    ;
 
-    test    bh, bh              ; if we are at level 0, then
-    jz      find_booter_ext_1   ; look for next extended partition entry
+%endif ; EXT_PART_SUPPORT
 
-find_booter_end
+.exit:
+    ;
+    ; Boot partition not found. Giving up.
+    ;
     pop     si
     pop     cx
     ret
 
 ;--------------------------------------------------------------------------
-; Yeah! Found the booter partition. The first sector in this partition
-; is reserved for the boot sector code (us). So load the booter
-; starting from the second sector in the partition, then jump to the
-; start of the booter.
-;
-load_booter
-    mov     ax, [si]            ; DH/DL
-    mov     [chs_dx], ax
-    mov     ax, [si + 2]        ; CH/CL
-    mov     [chs_cx], ax
-
-    mov     cx, 1               ; skip the initial boot sector
-    mov     ax, BOOT2_SIZE      ; read BOOT2_SIZE sectors
-    mov     bx, BOOT2_ADDR      ; where to place boot2 code
-    call    load                ; load it...
-
-    xor     edx, edx            ; argument for boot2 (hard drive boot)
-    jmp     BOOTSEG:BOOT2_ADDR  ; there is no going back now!
-
-;--------------------------------------------------------------------------
-; Load sectors from disk using INT13/F2 call. The sectors are loaded
-; one sector at a time to avoid any BIOS bugs, and eliminate
-; complexities with crossing track boundaries, and other gotchas.
+; load - Load one or more sectors from a partition.
 ;
 ; Arguments:
-;   cx - number of sectors to skip
-;   ax - number of sectors to read
-;   bx - pointer to the memory buffer (must not cross a segment boundary)
-;   [chs_cx][chs_dx] - CHS starting position
+;   AL = number of 512-byte sectors to read.
+;   ES:BX = pointer to where the sectors should be stored.
+;   DL = drive number (0x80 + unit number)
+;   SI = pointer to the partition entry.
 ;
 ; Returns:
-;   CF = 0  success
-;   CF = 1  error
-;
-; The caller must save any registers it needs.
-;
-load
-    jcxz    load_sectors
-    call    next_sector         ; [chs_cx][chs_dx] <- next sector
-    loop    load
-
-load_sectors
-    mov     cx, ax              ; cx <- number of sectors to read
-
-load_loop
-    call    read_sector         ; load a single sector
-    jc      load_exit           ; abort if carry flag is set
-    add     bx, SECTOR_BYTES    ; increment buffer pointer
-    call    next_sector         ; [chs_cx][chs_dx] <- next sector
-    loop    load_loop
-    clc                         ; successful exit
-load_exit
+;   CF = 0 success
+;        1 error
+;
+load:
+    push    cx
+    mov     cx, 5                   ; number of times to retry
+
+.loop:
+    call    [read_func]             ; call either read_chs or read_lba
+    jnc     .exit                   ; load success
+    loop    .loop                   ; retry on error
+
+.exit:
+    pop     cx
     ret
 
 ;--------------------------------------------------------------------------
-; Read a single sector from the hard disk.
+; read_chs - Read sectors from a partition using CHS addressing.
 ;
 ; Arguments:
-;   [chs_cx][chs_dx] - CHS starting position
-;   bx - pointer to the sector memory buffer
-;        (must not cross a segment boundary)
+;   AL = number of 512-byte sectors to read.
+;   ES:BX = pointer to where the sectors should be stored.
+;   DL = drive number (0x80 + unit number)
+;   SI = pointer to the partition entry.
 ;
 ; Returns:
-;   CF = 0  success
-;   CF = 1  error
-;
-; Caller's cx register is preserved.
+;   CF = 0 success
+;        1 error
 ;
-read_sector
-    push    cx
-    mov     cx, 5               ; try 5 times to read the sector
-
-read_sector_1
-    mov     bp, cx              ; save cx
+read_chs:
+    pusha                           ; save all registers
 
-    mov     cx, [chs_cx]
-    mov     dx, [chs_dx]
-    mov     dl, DRIVE_NUM       ; drive number
-    mov     ax, 0x0201          ; Func 2, read 1 sector
-    int     0x13                ; read sector
-    jnc     read_sector_ok      ; CF = 0 indicates success
-
-    mov     al, '*'             ; sector read error indicator
-    call    putchar
+    ;
+    ; Read the CHS start values from the partition entry.
+    ;
+    mov     dh, [ si + part.head ]  ; drive head
+    mov     cx, [ si + part.sect ]  ; drive sector + cylinder
 
-    xor     ax, ax              ; Reset the drive and retry the read
-    int     0x13
+    ;
+    ; INT13 Func 2 - Read Disk Sectors
+    ;
+    ; Arguments:
+    ;   AH    = 2
+    ;   AL    = number of sectors to read
+    ;   CH    = lowest 8 bits of the 10-bit cylinder number
+    ;   CL    = bits 6 & 7: cylinder number bits 8 and 9
+    ;           bits 0 - 5: starting sector number (1-63)
+    ;   DH    = starting head number (0 to 255)
+    ;   DL    = drive number (80h + drive unit)
+    ;   es:bx = pointer where to place sectors read from disk
+    ;
+    ; Returns:
+    ;   AH    = return status (sucess is 0)
+    ;   AL    = burst error length if ah=0x11 (ECC corrected)
+    ;   carry = 0 success
+    ;           1 error
+    ;
+;   mov     dl, kDriveNumber
+    mov     ah, 0x02                ; Func 2
+    int     0x13                    ; INT 13
+    jnc     .exit
 
-    mov     cx, bp
-    loop    read_sector_1       ; retry while cx is not zero
+    DebugChar('e')                  ; indicate INT13/F2 error
 
-    stc                         ; set carry flag to indicate error
-    pop     cx
-    ret
+    ;
+    ; Issue a disk reset on error.
+    ; Should this be changed to Func 0xD to skip the diskette controller
+    ; reset?
+    ;
+    xor     ax, ax                  ; Func 0
+    int     0x13                    ; INT 13
+    stc                             ; set carry to indicate error
 
-read_sector_ok
-    mov     al, '.'             ; successful sector read indicator
-    call    putchar
-    clc                         ; success, clear carry flag
-    pop     cx
+.exit:
+    popa
     ret
 
 ;--------------------------------------------------------------------------
-; Given the current CHS position stored in [chs_cx][chs_dx], update
-; it so that the value in [chs_cx][chs_dx] points to the following
-; sector.
+; read_lba - Read sectors from a partition using LBA addressing.
 ;
 ; Arguments:
-;   [chs_cx][chs_dx] - CHS position
-;
-;   [max_sectors] and [max_heads] must be valid.
+;   AL = number of 512-byte sectors to read (valid from 1-127).
+;   ES:BX = pointer to where the sectors should be stored.
+;   DL = drive number (0x80 + unit number)
+;   SI = pointer to the partition entry.
 ;
-; Caller's ax and bx registers are preserved.
+; Returns:
+;   CF = 0 success
+;        1 error
 ;
-next_sector
-    push    ax
-    push    bx
+read_lba:
+    pusha                           ; save all registers
+    mov     bp, sp                  ; save current SP
 
-    ; Extract the CHS values from the packed register values in memory.
     ;
-    mov     al, [chs_cx]
-    and     al, 0x3f            ; al <- sector number (1-63)
+    ; Create the Disk Address Packet structure for the
+    ; INT13/F42 (Extended Read Sectors) on the stack.
+    ;
 
-    mov     bx, [chs_cx]
-    rol     bl, 2
-    ror     bx, 8
-    and     bx, 0x03ff          ; bx <- cylinder number
+    ; push    DWORD 0               ; offset 12, upper 32-bit LBA
+    push    ds                      ; For sake of saving memory,
+    push    ds                      ; push DS register, which is 0.
 
-    mov     ah, [chs_dx + 1]    ; ah <- head number
+    mov     ecx, [ebios_lba]        ; offset 8, lower 32-bit LBA
+    add     ecx, [si + part.lba]
+    push    ecx
 
-    inc     al                  ; Increment CHS by one sector.
-    cmp     al, [max_sectors]
-    jbe     next_sector_done
+    push    es                      ; offset 6, memory segment
 
-    inc     ah
-    cmp     ah, [max_heads]
-    jbe     next_sector_new_head
+    push    bx                      ; offset 4, memory offset
 
-    inc     bx
+    xor     ah, ah                  ; offset 3, must be 0
+    push    ax                      ; offset 2, number of sectors
 
-next_sector_new_cyl
-    xor     ah, ah              ; head number starts at 0
+    push    WORD 16                 ; offset 0-1, packet size
 
-next_sector_new_head
-    mov     al, 1               ; sector number starts at 1
+    ;
+    ; INT13 Func 42 - Extended Read Sectors
+    ;
+    ; Arguments:
+    ;   AH    = 0x42
+    ;   DL    = drive number (80h + drive unit)
+    ;   DS:SI = pointer to Disk Address Packet
+    ;
+    ; Returns:
+    ;   AH    = return status (sucess is 0)
+    ;   carry = 0 success
+    ;           1 error
+    ;
+    ; Packet offset 2 indicates the number of sectors read
+    ; successfully.
+    ;
+;   mov     dl, kDriveNumber
+    mov     si, sp
+    mov     ah, 0x42
+    int     0x13
+
+    jnc     .exit
 
-next_sector_done
-    ; Reassemble the CHS values back into the packed representation
-    ; in memory.
+    DebugChar('E')                  ; indicate INT13/F42 error
+
+    ;
+    ; Issue a disk reset on error.
+    ; Should this be changed to Func 0xD to skip the diskette controller
+    ; reset?
     ;
-    mov     [chs_cx + 1], bl    ; lower 8-bits of the 10-bit cylinder
-    ror     bh, 2
-    or      bh, al
-    mov     [chs_cx], bh        ; cylinder & sector number
-    mov     [chs_dx + 1], ah    ; head number
+    xor     ax, ax                  ; Func 0
+    int     0x13                    ; INT 13
+    stc                             ; set carry to indicate error
 
-    pop     bx
-    pop     ax
+.exit:
+    mov     sp, bp                  ; restore SP
+    popa
     ret
 
 ;--------------------------------------------------------------------------
 ; Write a string to the console.
 ;
 ; Arguments:
-;   ds:si   pointer to a NULL terminated string.
-;
-; The following registers are modified:
-;   ax, bx, si
-;
-message
-    mov     bx, 1               ; bh=0, bl=1 (blue)
-    cld                         ; increment SI after each lodsb call
-message_loop
-    lodsb                       ; load a byte from DS:SI into al
-    cmp     al, 0               ; Is it a NULL?
-    je      message_done        ; yes, all done
-    mov     ah, 0xE             ; bios INT10 Func 0xE
-    int     0x10                ; bios display a byte in tty mode
-    jmp     short message_loop
-message_done
+;   DS:SI   pointer to a NULL terminated string.
+;
+; Clobber list:
+;   AX, BX, SI
+;
+print_string
+    mov     bx, 1                   ; BH=0, BL=1 (blue)
+    cld                             ; increment SI after each lodsb call
+.loop
+    lodsb                           ; load a byte from DS:SI into AL
+    cmp     al, 0                   ; Is it a NULL?
+    je      .exit                   ; yes, all done
+    mov     ah, 0xE                 ; INT10 Func 0xE
+    int     0x10                    ; display byte in tty mode
+    jmp     short .loop
+.exit
     ret
 
+%if DEBUG
+
 ;--------------------------------------------------------------------------
 ; Write a ASCII character to the console.
 ;
 ; Arguments:
-;   al   contains the ASCII character printed.
-;
-putchar
-    push    bx
-    mov     bx, 1               ; bh=0, bl=1 (blue)
-    mov     ah, 0x0e            ; bios int 10, function 0xe
-    int     0x10                ; bios display a byte in tty mode
-    pop     bx
-    ret
-
-%IF DEBUG
-;==========================================================================
-; DEBUG FUNCTION START
+;   AL = ASCII character.
 ;
-; If DEBUG is set to 1, this booter will become too large for the MBR,
-; but it will still be less than 510 bytes, which is fine for a partition's
-; boot sector.
-;==========================================================================
+print_char
+    pusha
+    mov     bx, 1                   ; BH=0, BL=1 (blue)
+    mov     ah, 0x0e                ; bios INT 10, Function 0xE
+    int     0x10                    ; display byte in tty mode
+    popa
+    ret
 
 ;--------------------------------------------------------------------------
 ; Write a variable number of spaces to the console.
 ;
 ; Arguments:
-;   al   number to spaces to display
+;   AL = number to spaces.
 ;
-putspace
-    push    cx
+print_spaces:
+    pusha
     xor     cx, cx
-    mov     cl, al              ; use cx as the loop counter
-    mov     al, ' '             ; character to print
-putspace_loop
-    jcxz    putspace_done
-    call    putchar
-    loop    putspace_loop
-putspace_done
-    pop     cx
+    mov     cl, al                  ; use CX as the loop counter
+    mov     al, ' '                 ; character to print
+.loop:
+    jcxz    .exit
+    call    print_char
+    loop    .loop
+.exit:
+    popa
     ret
 
 ;--------------------------------------------------------------------------
-; Write the hex byte value to the console.
+; Write the byte value to the console in hex.
 ;
 ; Arguments:
-;   al   contains the byte to be displayed. e.g. if al is 0x3f, then 3F
-;        will be displayed on screen.
+;   AL = Value to be displayed in hex.
 ;
-display_byte
+print_hex:
     push    ax
     ror     al, 4
-    call    display_nibble      ; display upper nibble
+    call    print_nibble            ; display upper nibble
     pop     ax
-    call    display_nibble      ; display lower nibble
-    ;
-    mov     ax, 10              ; display carriage return
-    call    putchar
-    mov     ax, 13
-    call    putchar
+    call    print_nibble            ; display lower nibble
+
+    mov     al, 10                  ; carriage return
+    call    print_char
+    mov     al, 13
+    call    print_char
     ret
 
-display_nibble
+print_nibble:
     and     al, 0x0f
     add     al, '0'
     cmp     al, '9'
-    jna     display_nibble_1
+    jna     .print_ascii
     add     al, 'A' - '9' - 1
-display_nibble_1
-    call    putchar
+.print_ascii:
+    call    print_char
     ret
 
-;==========================================================================
-; DEBUG FUNCTION END
-;==========================================================================
-%ENDIF
+%endif ; DEBUG
 
 ;--------------------------------------------------------------------------
 ; NULL terminated strings.
 ;
-load_error   db  10, 13, 'Load Error', 0
+boot_error_str   db  10, 13, 'Boot Error', 0
 
 ;--------------------------------------------------------------------------
 ; Pad the rest of the 512 byte sized booter with zeroes. The last
@@ -558,10 +660,31 @@ load_error   db  10, 13, 'Load Error', 0
 ; that the 'times' argument is negative.
 
 pad_boot
-       times 446-($-$$) db 0
+    times 446-($-$$) db 0
+
+%ifdef FLOPPY
+;--------------------------------------------------------------------------
+; Put fake partition entries for the bootable floppy image
+;
+part1bootid     db    0x80          ; first partition active
+part1head       db    0x00          ; head #
+part1sect       db    0x02          ; sector # (low 6 bits)
+part1cyl        db    0x00          ; cylinder # (+ high 2 bits of above)
+part1systid     db    0xab          ; Apple boot partition
+times   3       db    0x00          ; ignore head/cyl/sect #'s
+part1relsect    dd    0x00000001    ; start at sector 1
+part1numsect    dd    0x00000080    ; 64K for booter
+part2bootid     db    0x00          ; not active
+times   3       db    0x00          ; ignore head/cyl/sect #'s
+part2systid     db    0xa8          ; Apple UFS partition
+times   3       db    0x00          ; ignore head/cyl/sect #'s
+part2relsect    dd    0x00000082    ; start after booter
+; part2numsect  dd    0x00000abe    ; 1.44MB - 65K
+part2numsect    dd    0x000015fe    ; 2.88MB - 65K
+%endif
 
 pad_table_and_sig
     times 510-($-$$) db 0
-    dw BOOTSIG
+    dw    kBootSignature
 
     END
index 6e0cbbbfea96056bb6d34622e9273a9a1722dc9b..8af950e80a38f6c25628b42341270ddecf1aab82 100644 (file)
@@ -46,6 +46,7 @@
 ; This code is written for the NASM assembler.
 ;   nasm boot0.s -o boot0
 
+
 ;--------------------------------------------------------------------------
 ; Constants.
 
@@ -59,13 +60,14 @@ BOOTLOAD        EQU  0x7C00             ; booter load address
 BOOTRELOC       EQU  0xE000             ; booter is relocated here
 BOOTSIG         EQU  0xAA55             ; booter signature
 
-BOOT2_SIZE      EQU  88                 ; load this many blocks for boot2
-BOOT2_ADDR      EQU  0x3000             ; where to load boot2
+BOOT2_SIZE      EQU  112                ; load this many blocks for boot2
+BOOT2_ADDR      EQU  0x0200             ; where to load boot2
+BOOT2_SEG       EQU  0x2000
 
 %IF BOOTDEV = FLOPPY
-DRIVE_NUM       EQU  FLOPPY               ; floppy drive
+DRIVE_NUM       EQU  FLOPPY             ; floppy drive
 %ELSE
-DRIVE_NUM       EQU  HDISK                ; "C" drive
+DRIVE_NUM       EQU  HDISK              ; "C" drive
 %ENDIF
 SECTOR_BYTES    EQU  512                ; sector size in bytes
 
@@ -106,8 +108,8 @@ start
     ; or from 0:7C00h to BOOTSEG:BOOTRELOC.
     ;
     mov     es, ax              ; es <- BOOTSEG
-    xor     ax, ax
-    mov     ds, ax              ; ds <- 0
+    mov     ds, ax              ; ds <- BOOTSEG
+
     mov     si, BOOTLOAD        ; si <- BOOTLOAD (source)
     mov     di, BOOTRELOC       ; di <- BOOTRELOC (destination)
     ;
@@ -123,9 +125,6 @@ start
 ; Start execution from the relocated location.
 ;
 start_reloc
-    mov     ax, BOOTSEG
-    mov     ds, ax              ; ds <- BOOTSEG
-
     mov     al, '='             ; indicate execution start
     call    putchar
 
@@ -142,9 +141,6 @@ start_reloc
     mov     al, '>'             ; indicate INT13/F8 success
     call    putchar
 
-    mov     ax, BOOTSEG                         ; es <- BOOTSEG        
-    mov     es, ax 
-
     ; Since this code may not always reside in the MBR, we will always
     ; start by loading the MBR to BUF_MBR.
     ;
@@ -227,7 +223,7 @@ find_booter_ext
 
     cmp     BYTE [si + 4], TYPE_EXT_1   ; Is this an extended partition?
     je      find_booter_ext_2           ; yes, load its partition table
-       
+
     cmp     BYTE [si + 4], TYPE_EXT_2   ; Is this an extended partition?
     je      find_booter_ext_2           ; yes, load its partition table
 
@@ -298,14 +294,15 @@ load_booter
 
     mov     cx, 1               ; skip the initial boot sector
     mov     ax, BOOT2_SIZE      ; read BOOT2_SIZE sectors
+    mov     bx, BOOT2_SEG
+    mov     es, bx
     mov     bx, BOOT2_ADDR      ; where to place boot2 code
     call    load                ; load it...
 
-    xor     edx, edx            ; argument for boot2 (hard drive boot)
-%IF BOOTDEV = FLOPPY
-    inc     edx                 ; floppy is dev 1
-%ENDIF
-    jmp     BOOTSEG:BOOT2_ADDR  ; there is no going back now!
+    xor     edx, edx
+    mov     dl, DRIVE_NUM       ; argument for boot2
+
+    jmp     BOOT2_SEG:BOOT2_ADDR  ; there is no going back now!
 
 ;--------------------------------------------------------------------------
 ; Load sectors from disk using INT13/F2 call. The sectors are loaded
@@ -347,8 +344,8 @@ load_exit
 ;
 ; Arguments:
 ;   [chs_cx][chs_dx] - CHS starting position
-;   bx - pointer to the sector memory buffer
-;        (must not cross a segment boundary)
+;   es:bx - pointer to the sector memory buffer
+;           (must not cross a segment boundary)
 ;
 ; Returns:
 ;   CF = 0  success
@@ -570,27 +567,27 @@ load_error   db  10, 13, 'Load Error', 0
 ; that the 'times' argument is negative.
 
 pad_boot
-       times 446-($-$$) db 0
+    times 446-($-$$) db 0
 
 %IF BOOTDEV = FLOPPY
 ;--------------------------------------------------------------------------
 ; Put fake partition entries for the bootable floppy image
 ;
-part1bootid    db            0x80      ; first partition active
-part1head      db            0x00      ; head #
-part1sect      db            0x02      ; sector # (low 6 bits)
-part1cyl       db            0x00      ; cylinder # (+ high 2 bits of above)
-part1systid    db            0xab      ; Apple boot partition
-times  3       db            0x00      ; ignore head/cyl/sect #'s
-part1relsect   dd      0x00000001      ; start at sector 1
-part1numsect   dd      0x00000058      ; 44K for booter
-part2bootid    db            0x00      ; not active
-times  3       db            0x00      ; ignore head/cyl/sect #'s
-part2systid    db            0xa8      ; Apple UFS partition
-times  3       db            0x00      ; ignore head/cyl/sect #'s
-part2relsect   dd      0x0000005a      ; start after booter
-; part2numsect dd      0x00000ae6      ; 1.44MB - 45K
-part2numsect   dd      0x00001626      ; 2.88MB - 45K
+part1bootid     db        0x80  ; first partition active
+part1head       db        0x00  ; head #
+part1sect       db        0x02  ; sector # (low 6 bits)
+part1cyl        db        0x00  ; cylinder # (+ high 2 bits of above)
+part1systid     db        0xab  ; Apple boot partition
+times   3       db        0x00  ; ignore head/cyl/sect #'s
+part1relsect    dd  0x00000001  ; start at sector 1
+part1numsect    dd  0x00000080  ; 64K for booter
+part2bootid     db        0x00  ; not active
+times   3       db        0x00  ; ignore head/cyl/sect #'s
+part2systid     db        0xa8  ; Apple UFS partition
+times   3       db        0x00  ; ignore head/cyl/sect #'s
+part2relsect    dd  0x00000082  ; start after booter
+; part2numsect  dd  0x00000abe  ; 1.44MB - 65K
+part2numsect    dd  0x000015fe  ; 2.88MB - 65K
 %ENDIF
 
 pad_table_and_sig
index 337443825995217433474c85bfb3c55f4d608516..8bfefb02589169fe748224ac5d036481c346c267 100644 (file)
@@ -6,8 +6,8 @@ DIR = boot2
 include ../MakePaths.dir
 
 OPTIM = -Os
-CFLAGS = $(RC_CFLAGS) $(OPTIM) $(MORECPP) -arch i386 -g -Wmost -Wno-precomp \
-    -munaligned-text -DSAIO_INTERNAL_USER -static -traditional-cpp
+CFLAGS = $(RC_CFLAGS) $(OPTIM) $(MORECPP) -arch i386 -g -Wmost -Werror \
+          -fno-builtin -DSAIO_INTERNAL_USER -static
 DEFINES=
 CONFIG = hd
 SYMDIR = $(SYMROOT)
@@ -32,19 +32,19 @@ VPATH = $(OBJROOT):$(SYMROOT)
 
 # The ordering is important;
 # boot2.o must be first.
-OBJS = boot2.o boot.o graphics.o drivers.o prompt.o
+OBJS = boot2.o boot.o graphics.o drivers.o prompt.o options.o
 # button.o browser.o scrollbar.o == NOTYET     
 
 UTILDIR = ../util
 SFILES = boot2.s
-CFILES = boot.c graphics.c drivers.c prompt.c
+CFILES = boot.c graphics.c drivers.c prompt.c options.c
 HFILES = boot.h
 OTHERFILES = Makefile
 ALLSRC = $(FOREIGNSRC) $(FOREIGNBIN) $(SFILES) $(CFILES) \
        $(HFILES) $(OTHERFILES)
 DIRS_NEEDED = $(OBJROOT) $(SYMROOT)
-BOOT2ADDR = 3000
-MAXBOOTSIZE = 45056
+BOOT2ADDR = 20200
+MAXBOOTSIZE = 65024
 
 all: $(DIRS_NEEDED) boot
 
diff --git a/i386/boot2/appleClut8.h b/i386/boot2/appleClut8.h
new file mode 100644 (file)
index 0000000..7e7ddff
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef __BOOT2_APPLECLUT8_H
+#define __BOOT2_APPLECLUT8_H
+
+static const unsigned char appleClut8[ 256 * 3 ] =
+{
+       0xff,0xff,0xff, 0xfe,0xfe,0xfe, 0xfd,0xfd,0xfd, 0xb8,0x27,0x2b,
+       0xfc,0xfc,0xfc, 0xff,0xff,0x00, 0xfa,0xfa,0xfa, 0xf9,0xf9,0xf9,
+       0xf8,0xf8,0xf8, 0xf7,0xf7,0xf7, 0xf6,0xf6,0xf6, 0xf5,0xf5,0xf5,
+       0xf4,0xf4,0xf4, 0xf2,0xf2,0xf2, 0xf1,0xf1,0xf1, 0x00,0x00,0x00,
+       0xef,0xef,0xef, 0xee,0xee,0xee, 0xed,0xed,0xed, 0xeb,0xeb,0xeb,
+       0xe8,0xe8,0xe8, 0xe7,0xe7,0xe7, 0xc9,0x38,0x3e, 0xe5,0xe5,0xe5,
+       0xff,0x00,0xff, 0xfb,0xfb,0xfb, 0xde,0x6c,0x72, 0xe0,0xe0,0xe0,
+       0xe8,0x86,0x90, 0xde,0xde,0xde, 0xdd,0xdd,0xdd, 0xd3,0x7e,0x8d,
+       0xd9,0xd9,0xd9, 0xf3,0x96,0xa6, 0xb1,0x1c,0x39, 0xff,0x00,0x00,
+       0xbe,0x5e,0x72, 0xd3,0xd3,0xd3, 0xc6,0x2e,0x67, 0xd1,0xd1,0xd1,
+       0xa3,0x06,0x45, 0xce,0xce,0xce, 0xcc,0xcc,0xff, 0xcc,0xcc,0xcc,
+       0xc6,0x8f,0xa7, 0xe1,0xd3,0xd9, 0xce,0x9e,0xb4, 0xca,0xca,0xca,
+       0xbf,0x3f,0x7d, 0xc9,0xc9,0xc9, 0xf4,0x89,0xbe, 0xc6,0xc6,0xc6,
+       0xd6,0x51,0x97, 0xc9,0x2c,0x84, 0x96,0x1a,0x6a, 0xc2,0xc2,0xc2,
+       0xf3,0x6f,0xc6, 0xe5,0x4c,0xbb, 0xb7,0x5a,0x9c, 0xbf,0xbf,0xbf,
+       0xbe,0xbe,0xbe, 0xbd,0xbd,0xbd, 0xb8,0x21,0xa2, 0xd3,0x44,0xc0,
+       0xc2,0x66,0xb7, 0xf4,0x66,0xe6, 0xfc,0x73,0xfd, 0xb9,0xb9,0xb9,
+       0xea,0xdf,0xea, 0xd4,0x71,0xd5, 0xf9,0x8b,0xff, 0xf5,0xad,0xff,
+       0xbc,0x92,0xc2, 0xc7,0x4f,0xd9, 0xa0,0x44,0xaf, 0xc8,0x8c,0xd5,
+       0xd7,0x74,0xf7, 0xb4,0xb4,0xb4, 0xda,0x95,0xf9, 0xed,0xcb,0xff,
+       0xb2,0xb2,0xb2, 0xa1,0x61,0xd7, 0xb2,0x85,0xe2, 0x59,0x26,0x9c,
+       0x7c,0x51,0xcc, 0xb0,0xb0,0xb0, 0xb4,0x8e,0xfc, 0xd5,0xc0,0xff,
+       0x5d,0x32,0xcc, 0x7b,0x5c,0xe5, 0xc0,0xb0,0xfd, 0x60,0x53,0xad,
+       0x12,0x0c,0x7e, 0x2e,0x29,0x99, 0x79,0x78,0xe9, 0x5b,0x5c,0xd0,
+       0x69,0x6a,0xcc, 0x93,0x94,0xf8, 0x92,0x92,0xc3, 0x41,0x44,0xba,
+       0xa8,0xab,0xff, 0xa3,0xa3,0xa3, 0xdb,0xdd,0xea, 0x31,0x49,0xaa,
+       0x70,0x8f,0xf9, 0x48,0x66,0xc1, 0x5c,0x7e,0xe9, 0xe2,0xe5,0xeb,
+       0xb0,0xcd,0xff, 0x6c,0x89,0xb7, 0x34,0x65,0xaf, 0x8c,0xb9,0xff,
+       0x37,0x79,0xd4, 0x5a,0x99,0xea, 0x0e,0x4c,0x95, 0x79,0xb9,0xff,
+       0x8a,0xa3,0xbc, 0x20,0x61,0x9d, 0x8f,0xae,0xca, 0x0a,0x60,0xa8,
+       0x3f,0x94,0xd9, 0x63,0xb5,0xf9, 0xe2,0xe8,0xed, 0x28,0x6a,0x99,
+       0x55,0xb2,0xe7, 0x32,0x89,0xa9, 0xcf,0xda,0xde, 0x29,0xa1,0xc7,
+       0x86,0xa9,0xb4, 0x00,0x5f,0x79, 0x0c,0x77,0x8e, 0x12,0x8f,0xab,
+       0x41,0xba,0xd5, 0x24,0x82,0x83, 0x2c,0xc4,0xc3, 0x1a,0xab,0xa6,
+       0x4b,0xa8,0xa2, 0x0a,0x93,0x85, 0x0d,0xa5,0x96, 0x26,0xbc,0xac,
+       0x04,0x81,0x72, 0x19,0xb3,0x86, 0x29,0xc1,0x94, 0x21,0x9c,0x71,
+       0x02,0x8c,0x50, 0x35,0xd0,0x89, 0x46,0xa5,0x76, 0x02,0x7d,0x39,
+       0x29,0xc9,0x71, 0x57,0xd6,0x8f, 0xa2,0xb5,0xaa, 0x01,0x88,0x2a,
+       0x74,0xbe,0x8a, 0x19,0xb6,0x47, 0x2d,0xc6,0x51, 0x38,0xde,0x5d,
+       0x4c,0xf4,0x6f, 0x91,0x9c,0x93, 0x00,0x8e,0x19, 0x10,0xaf,0x28,
+       0xe3,0xe3,0xe3, 0x08,0xa1,0x1a, 0x59,0xc2,0x61, 0xf0,0xf0,0xf0,
+       0x8f,0x9c,0x90, 0x23,0xce,0x2a, 0x12,0xba,0x17, 0x01,0x8a,0x02,
+       0x03,0x9a,0x02, 0x40,0xe4,0x40, 0x08,0xb2,0x05, 0x13,0xcc,0x0f,
+       0x36,0xd7,0x32, 0x28,0xe9,0x1f, 0x53,0xfb,0x4c, 0x6f,0xaf,0x6a,
+       0x71,0xe0,0x67, 0x32,0xc0,0x12, 0x29,0xa5,0x08, 0x5c,0xdd,0x35,
+       0x00,0xff,0xff, 0x63,0xc8,0x45, 0x86,0xfd,0x5b, 0x71,0xf6,0x39,
+       0x55,0xcc,0x15, 0x00,0xff,0x00, 0x90,0xca,0x6e, 0x43,0xa7,0x01,
+       0x8d,0xe4,0x37, 0xb3,0xf0,0x64, 0x85,0x8e,0x7a, 0xb0,0xfa,0x4d,
+       0xd6,0xd6,0xd6, 0x88,0xd0,0x1a, 0x6a,0xa7,0x03, 0x98,0xbf,0x41,
+       0xcd,0xf8,0x51, 0x94,0xa4,0x55, 0x91,0xb0,0x0a, 0xda,0xf1,0x3c,
+       0xba,0xca,0x53, 0xb9,0xc3,0x28, 0xb1,0xba,0x12, 0xd2,0xd9,0x26,
+       0xe8,0xec,0x2d, 0x98,0x96,0x02, 0xad,0xad,0x5c, 0xe2,0xd8,0x38,
+       0xd9,0xc4,0x38, 0xa8,0x9a,0x50, 0x00,0x00,0xff, 0xbe,0xae,0x5e,
+       0x9a,0x98,0x8e, 0xac,0x8d,0x0d, 0xc5,0xa0,0x2b, 0xdb,0xb5,0x48,
+       0xdd,0x00,0x00, 0x9c,0x6d,0x03, 0xd4,0xa8,0x47, 0xb7,0x71,0x17,
+       0xdc,0xa1,0x5a, 0xb9,0x9c,0x7c, 0xb4,0xab,0xa2, 0x9e,0x4b,0x01,
+       0xc8,0x78,0x35, 0xd2,0x8d,0x51, 0xad,0x52,0x0f, 0x00,0xbb,0x00,
+       0xb2,0x66,0x38, 0xb1,0xa6,0x9f, 0xb1,0x87,0x6f, 0xa4,0x34,0x03,
+       0xee,0x9e,0x85, 0xc9,0x73,0x5a, 0xe6,0x94,0x7c, 0xa9,0x22,0x06,
+       0xdb,0x87,0x74, 0xb0,0x2e,0x15, 0xb7,0x5a,0x50, 0xb2,0x42,0x3b,
+       0xcd,0x73,0x6e, 0xd9,0x58,0x58, 0xac,0xac,0xac, 0xa0,0xa0,0xa0,
+       0x9a,0x9a,0x9a, 0x92,0x92,0x92, 0x8e,0x8e,0x8e, 0xbb,0xbb,0xbb,
+       0x81,0x81,0x81, 0x88,0x88,0x88, 0x77,0x77,0x77, 0x55,0x55,0x55,
+       0x44,0x44,0x44, 0x22,0x22,0x22, 0x7b,0x7b,0x7b, 0x00,0x00,0x00
+};
+
+#endif /* !__BOOT2_APPLECLUT8_H */
index 72f1be522c6994eb2ad581ac25632b7e7939bb52..368acab0b1584061f09255053081a7f7c28a02f2 100644 (file)
  * Completely reworked by Sam Streeper (sam_s@NeXT.com)
  * Reworked again by Curtis Galloway (galloway@NeXT.com)
  */
-#include "libsa.h"
-#include "memory.h"
-#include "saio.h"
-#include "libsaio.h"
-#include "kernBootStruct.h"
+
 #include "boot.h"
-#include "nbp.h"
 
 /*
  * The user asked for boot graphics.
  */
-static BOOL gWantBootGraphics = NO;
-
-/*
- * The device that the booter was loaded from.
- */
-int    gBootDev;
+BOOL gBootGraphics = NO;
+int  gBIOSDev;
+long gBootMode = kBootModeNormal;
 
-extern char * gFilename;
-extern BOOL   sysConfigValid;
-extern char   bootPrompt[];
-extern BOOL   errors;
-extern BOOL   gVerboseMode;
-extern BOOL   gSilentBoot;
-
-/*
- * Prototypes.
- */
-static void getBootString();
+static BOOL gUnloadPXEOnExit = 0;
 
 /*
  * How long to wait (in seconds) to load the
  * kernel after displaying the "boot:" prompt.
  */
-#define kBootTimeout  10
+#define kBootErrorTimeout 5
 
 //==========================================================================
 // Zero the BSS.
 
-static void
-zeroBSS()
+static void zeroBSS()
 {
     extern char _DATA__bss__begin, _DATA__bss__end;
     extern char _DATA__common__begin, _DATA__common__end;
@@ -103,8 +84,7 @@ zeroBSS()
 //==========================================================================
 // execKernel - Load the kernel image (mach-o) and jump to its entry point.
 
-static int
-execKernel(int fd)
+static int execKernel(int fd)
 {
     register KERNBOOTSTRUCT * kbp = kernBootStruct;
     static struct mach_header head;
@@ -117,8 +97,7 @@ execKernel(int fd)
 
     kbp->kaddr = kbp->ksize = 0;
 
-    ret = loadprog( kbp->kernDev,
-                    fd,
+    ret = loadprog( kbp->kernDev, fd,
                     &head,
                     &kernelEntry,
                     (char **) &kbp->kaddr,
@@ -129,18 +108,18 @@ execKernel(int fd)
     if ( ret != 0 )
         return ret;
 
-    // Load boot drivers from the specifed root.
+    // Load boot drivers from the specifed root path.
 
     LoadDrivers("/");
     clearActivityIndicator();
 
-    if (errors) {
+    if (gErrors) {
         printf("Errors encountered while starting up the computer.\n");
-        printf("Pausing %d seconds...\n", kBootTimeout);
-        sleep(kBootTimeout);
+        printf("Pausing %d seconds...\n", kBootErrorTimeout);
+        sleep(kBootErrorTimeout);
     }
 
-    message("Starting Darwin/x86", 0);
+    printf("Starting Darwin/x86");
 
     turnOffFloppy();
 
@@ -153,24 +132,22 @@ execKernel(int fd)
 
        // Cleanup the PXE base code.
 
-       if ( gBootDev == kBootDevNetwork )
+       if ( gUnloadPXEOnExit )
     {
                if ( (ret = nbpUnloadBaseCode()) != nbpStatusSuccess )
         {
-               printf("nbpUnloadBaseCode error %d\n", (int) ret); sleep(2);
+               printf("nbpUnloadBaseCode error %d\n", (int) ret);
+            sleep(2);
         }
     }
 
-    // Switch to graphics mode just before starting the kernel.
+    // Switch to desired video mode just before starting the kernel.
 
-    if ( gWantBootGraphics )
-    {
-        setMode(GRAPHICS_MODE);
-    }
+    setVideoMode( gBootGraphics ? GRAPHICS_MODE : TEXT_MODE );
 
     // Jump to kernel's entry point. There's no going back now.
 
-    startprog(kernelEntry);
+    startprog( kernelEntry );
 
     // Not reached
 
@@ -178,37 +155,39 @@ execKernel(int fd)
 }
 
 //==========================================================================
-// Scan and record the system's PCI bus information.
+// Scan and record the system's hardware information.
 
 static void scanHardware()
 {
-extern int  ReadPCIBusInfo(PCI_bus_info_t *);
-extern void PCI_Bus_Init(PCI_bus_info_t *);
+    extern int  ReadPCIBusInfo(PCI_bus_info_t *);
+    extern void PCI_Bus_Init(PCI_bus_info_t *);
 
     ReadPCIBusInfo( &kernBootStruct->pciInfo );
-    PCI_Bus_Init( &kernBootStruct->pciInfo );
+    
+    //
+    // Initialize PCI matching support in the booter.
+    // Not used, commented out to minimize code size.
+    //
+    // PCI_Bus_Init( &kernBootStruct->pciInfo );
 }
 
 //==========================================================================
-// The 'main' function for the booter. This function is called by the
-// assembly routine init(), which is in turn called by boot1 or by
-// NBP.
+// The 'main' function for the booter. Called by boot0 when booting
+// from a block device, or by the network booter.
 //
 // arguments:
-//   bootdev - Value passed from boot1/NBP to specify the device
-//             that the booter was loaded from. See boot.h for the list
-//             of allowable values.
+//   biosdev - Value passed from boot1/NBP to specify the device
+//             that the booter was loaded from.
 //
-// If bootdev is kBootDevNetwork, then this function will return if
+// If biosdev is kBIOSDevNetwork, then this function will return if
 // booting was unsuccessful. This allows the PXE firmware to try the
-// next bootable device on its list. If bootdev is not kBootDevNetwork,
-// this function will not return control back to the caller.
+// next boot device on its list.
 
-void
-boot(int bootdev)
+void boot(int biosdev)
 {
     register KERNBOOTSTRUCT * kbp = kernBootStruct;
     int      fd;
+    int      status;
 
     zeroBSS();
 
@@ -216,25 +195,40 @@ boot(int bootdev)
 
     enableA20();
 
-    // Remember the device that the booter was loaded from.
+    // Set reminder to unload the PXE base code. Neglect to unload
+    // the base code will result in a hang or kernel panic.
+
+    if ( BIOS_DEV_TYPE(biosdev) == kBIOSDevTypeNetwork )
+        gUnloadPXEOnExit = 1;
+
+#if 0
+    gUnloadPXEOnExit = 1;
+    biosdev  = 0x80;
+#endif
 
-    gBootDev = bootdev;
+    // Record the device that the booter was loaded from.
+
+    gBIOSDev = biosdev & kBIOSDevMask;
 
     // Initialize boot info structure.
 
-    initKernBootStruct();
+    initKernBootStruct( gBIOSDev );
 
     // Setup VGA text mode.
+    // Not sure if it is safe to call setVideoMode() before the
+    // config table has been loaded. Call video_mode() instead.
 
-    setMode(TEXT_MODE);
+       video_mode( 2 );  // 80x25 mono text mode.
 
     // Scan hardware configuration.
 
     scanHardware();
 
-    // Display boot prompt.
+    // Display banner and show hardware info.
 
-    printf( bootPrompt, kbp->convmem, kbp->extmem, kBootTimeout );
+    setCursorPosition( 0, 0, 0 );
+    printf( bootBanner, kbp->convmem, kbp->extmem );
+    printVBEInfo();
 
     // Parse args, load and start kernel.
 
@@ -243,64 +237,18 @@ boot(int bootdev)
         // Initialize globals.
 
         sysConfigValid = 0;
-        errors         = 0;
-
-        // Make sure we are in VGA text mode.
-
-        setMode(TEXT_MODE);
-
-        // Set up kbp->kernDev to reflect the boot device.
-
-        if ( bootdev == kBootDevHardDisk )
-        {
-            if (kbp->numIDEs > 0)
-            {
-                kbp->kernDev = DEV_HD;
-            }
-            else
-            {
-                kbp->kernDev = DEV_SD;
-            }
-        }
-        else if ( bootdev == kBootDevFloppyDisk )
-        {
-            kbp->kernDev = DEV_FLOPPY;
-        }
-        else
-        {
-            kbp->kernDev = DEV_EN;
-        }
-        flushdev();
+        gErrors        = 0;
 
-        // Display boot prompt and get user supplied boot string.
-
-        getBootString();
-
-        if ( bootdev != kBootDevNetwork )
-        {
-            // To force loading config file off same device as kernel,
-            // open kernel file to force device change if necessary.
-
-            fd = open(kbp->bootFile, 0);
-            if (fd >= 0) close(fd);
-        }
-
-        if ( sysConfigValid == 0 )
-        {
-            if (kbp->kernDev == DEV_EN)
-                break;      // return control back to PXE
-            else
-                continue;   // keep looping
-        }
+        getBootOptions();
+        status = processBootOptions();
+        if ( status ==  1 ) break;
+        if ( status == -1 ) continue;
 
         // Found and loaded a config file. Proceed with boot.
 
-        gWantBootGraphics = getBoolForKey( kBootGraphicsKey );
-        gSilentBoot       = getBoolForKey( kQuietBootKey );
-
-        message("Loading Darwin/x86", 0);
+        printf("Loading Darwin/x86\n");
 
-        if ( (fd = openfile(kbp->bootFile, 0)) >= 0 )
+        if ( (fd = openfile( kbp->bootFile, 0 )) >= 0 )
         {
             execKernel(fd);  // will not return on success
         }
@@ -308,184 +256,21 @@ boot(int bootdev)
         {
             error("Can't find %s\n", kbp->bootFile);
 
-            if ( bootdev == kBootDevFloppyDisk )
+            if ( BIOS_DEV_TYPE(gBIOSDev) == kBIOSDevTypeFloppy )
             {
                 // floppy in drive, but failed to load kernel.
-                bootdev = kBootDevHardDisk;
-                message("Couldn't start up the computer using this "
-                        "floppy disk.", 0);
+                gBIOSDev = kBIOSDevTypeHardDrive;
+                initKernBootStruct( gBIOSDev );
+                printf("Attempt to load from hard drive.");
             }
-            else if ( bootdev == kBootDevNetwork )
+            else if ( BIOS_DEV_TYPE(gBIOSDev) == kBIOSDevTypeNetwork )
             {
-                break;   // Return control back to PXE.
+                // Return control back to PXE. Don't unload PXE base code.
+                gUnloadPXEOnExit = 0;
+                break;
             }
         }
     } /* while(1) */
-}
-
-//==========================================================================
-// Skip spaces/tabs characters.
-
-static inline void
-skipblanks(char ** cp) 
-{
-    while ( **(cp) == ' ' || **(cp) == '\t' )
-        ++(*cp);
-}
-
-//==========================================================================
-// Load the help file and display the file contents on the screen.
-
-static void showHelp()
-{
-#define BOOT_DIR_DISK       "/usr/standalone/i386/"
-#define BOOT_DIR_NET        ""
-#define makeFilePath(x) \
-    (gBootDev == kBootDevNetwork) ? BOOT_DIR_NET x : BOOT_DIR_DISK x
-
-    int    fd;
-    char * help = makeFilePath("BootHelp.txt");
-
-    if ( (fd = open(help, 0)) >= 0 )
-    {
-        char * buffer = malloc( file_size(fd) );
-        read(fd, buffer, file_size(fd) - 1);
-        close(fd);
-        printf("%s", buffer);
-        free(buffer);
-    }
-}
-
-//==========================================================================
-// Returns 1 if the string pointed by 'cp' contains an user-specified
-// kernel image file name. Used by getBootString() function.
-
-static int
-containsKernelName(const char * cp)
-{
-    register char c;
-
-    skipblanks(&cp);
-
-    // Convert char to lower case.
-
-    c = *cp | 0x20;
-
-    // Must start with a letter or a '/'.
-
-    if ( (c < 'a' || c > 'z') && ( c != '/' ) )
-        return 0;
-
-    // Keep consuming characters until we hit a separator.
-
-    while ( *cp && (*cp != '=') && (*cp != ' ') && (*cp != '\t') )
-        cp++;
-
-    // Only SPACE or TAB separator is accepted.
-    // Reject everything else.
-
-    if (*cp == '=')
-        return 0;
-
-    return 1;
-}
-
-//==========================================================================
-// Display the "boot:" prompt and copies the user supplied string to
-// kernBootStruct->bootString. The kernel image file name is written
-// to kernBootStruct->bootFile.
-
-static void
-getBootString()
-{
-    char         line[BOOT_STRING_LEN];
-    char *       cp;
-    char *       val;
-    int          count;
-    static int   timeout = kBootTimeout;
-
-    do {
-        line[0] = '\0';
-        cp      = &line[0];
-
-        // If there were errors, don't timeout on boot prompt since
-        // the same error is likely to occur again.
-
-        if ( errors ) timeout = 0;
-        errors = 0;
-
-        // Print the boot prompt and wait a few seconds for user input.
-
-        printf("\n");
-        count = Gets(line, sizeof(line), timeout, "boot: ", "");
-        flushdev();
-
-        // If something was typed, don't use automatic boot again.
-        // The boot: prompt will not timeout and go away until
-        // the user hits the return key.
-
-        if ( count ) timeout = 0;
-
-        skipblanks(&cp);
-
-        // If user typed '?', then display the usage message.
-
-        if ( *cp == '?' )
-        {
-            showHelp();
-            continue;
-        }
-
-        // Load config table file specified by the user, or fallback
-        // to the default one.
-
-        val = 0;
-        getValueForBootKey(cp, "config", &val, &count);
-        loadSystemConfig(val, count);
-        if ( !sysConfigValid )
-            continue;
-    }
-    while ( 0 );
-
-    // Did the user specify a kernel file name at the boot prompt?
-
-    if ( containsKernelName(cp) == 0 )
-    {
-        // User did not type a kernel image file name on the boot prompt.
-        // This is fine, read the default kernel file name from the
-        // config table.
-
-        if ( getValueForKey(kKernelNameKey, &val, &count) )
-        {
-            strncpy(kernBootStruct->bootFile, val, count);
-        }
-    }
-    else
-    {
-        // Get the kernel name from the user-supplied boot string,
-        // and copy the name to the buffer provided.
-
-        char * namep = kernBootStruct->bootFile;
-
-        while ( *cp && !(*cp == ' ' || *cp == '\t') )
-            *namep++ = *cp++;
-
-        *namep = '\0';
-    }
-
-    // Verbose flag specified.
-
-    gVerboseMode = getValueForBootKey(cp, "-v", &val, &count);
-
-    // Save the boot string in kernBootStruct->bootString.
-
-    if ( getValueForKey(kKernelFlagsKey, &val, &count) && count )
-    {
-        strncpy( kernBootStruct->bootString, val, count );
-    }
-    if ( strlen(cp) )
-    {
-        strcat(kernBootStruct->bootString, " ");
-        strcat(kernBootStruct->bootString, cp);
-    }
+    
+    if (gUnloadPXEOnExit) nbpUnloadBaseCode();
 }
index c33859154cad8d0a2ccf8cdc4074f329cc8f2fed..851c5371021a4bb66fd67bd1ddf5a37c369e68b5 100644 (file)
 #ifndef __BOOT2_BOOT_H
 #define __BOOT2_BOOT_H
 
+#include "libsaio.h"
+
 /*
  * Keys used in system Default.table / Instance0.table
  */
 #define kGraphicsModeKey    "Graphics Mode"
+#define kTextModeKey        "Text Mode"
 #define kBootGraphicsKey    "Boot Graphics"
 #define kQuietBootKey       "Quiet Boot"
 #define kKernelFlagsKey     "Kernel Flags"
 #define kKernelNameKey      "Kernel"
 
-/*
- * Possible values for the bootdev argument passed to boot().
- */
-enum {
-       kBootDevHardDisk = 0,
-       kBootDevFloppyDisk,
-       kBootDevNetwork
-};
-
 /*
  * A global set by boot() to record the device that the booter
  * was loaded from.
  */
-extern int gBootDev;
+extern int  gBIOSDev;
+extern BOOL gBootGraphics;
+extern long gBootMode;
+extern BOOL sysConfigValid;
+extern char bootBanner[];
+extern char bootPrompt[];
+
+// Boot Modes
+enum {
+    kBootModeNormal = 0,
+    kBootModeSafe,
+    kBootModeSecure
+};
 
 /*
  * graphics.c
  */
-extern void message(char * str, int centered);
-extern void setMode(int mode);
-extern int  currentMode();
+extern void printVBEInfo();
+extern void setVideoMode(int mode);
+extern int  getVideoMode();
 extern void spinActivityIndicator();
 extern void clearActivityIndicator();
 
@@ -67,4 +73,10 @@ extern void clearActivityIndicator();
  */
 extern long LoadDrivers(char * dirSpec);
 
+/*
+ * options.c
+ */
+extern void getBootOptions();
+extern int  processBootOptions();
+
 #endif /* !__BOOT2_BOOT_H */
index ec1657258f22a6fb629b9ab13da12a9d538d122e..ab6389b682a7e473f149fb13c0b098c20038f440 100644 (file)
 #define data32  .byte 0x66
 #define retf    .byte 0xcb
 
-
     .file "boot2.s"
 
+    .data
+
+EXPORT(_chainbootdev)  .byte 0x80
+EXPORT(_chainbootflag) .byte 0x00
+
 .text
 
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -81,6 +85,9 @@ LABEL(boot2)
     pushl   %edx                # bootdev
     call    _boot
 
+    testb   $0xff, _chainbootflag
+    jnz     start_chain_boot    # Jump to a foreign booter
+
     call    __prot_to_real      # Back to real mode.
 
     data32
@@ -96,3 +103,22 @@ LABEL(boot2)
 
     retf                        # Hardcode a far return
 
+start_chain_boot:
+    xorl    %edx, %edx
+    movb    _chainbootdev, %dl  # Setup DL with the BIOS device number
+
+    call    __prot_to_real      # Back to real mode.
+
+    data32
+    call    __switch_stack      # Restore original stack
+    
+    pop     %es                 # Restore original ES and DS
+    pop     %ds
+    popl    %edi                # Restore all general purpose registers
+    popl    %esi                # except EAX.
+    popl    %ebp
+    popl    %ebx
+    popl    %ecx
+
+    data32
+    ljmp    $0, $0x7c00         # Jump to boot code already in memory
index e95053a4c8f65a831171638ef349d9a831bbc2c8..e335f4ea0e458b8194f077a9b78528f1bbc107cd 100644 (file)
  *  DRI: Josh de Cesare
  */
 
-#include "libsaio.h"
-#include "memory.h"
-#include "kernBootStruct.h"
-#include "nbp.h"
+#include "sl.h"
 #include "boot.h"
 
 enum {
@@ -107,10 +104,15 @@ struct DriversPackage {
 };
 typedef struct DriversPackage DriversPackage;
 
+enum {
+  kCFBundleType2,
+  kCFBundleType3
+};
+
 static long FileLoadDrivers(char *dirSpec, long plugin);
 static long NetLoadDrivers(char *dirSpec);
 static long LoadDriverMKext(char *fileSpec);
-static long LoadDriverPList(char *dirSpec, char *name);
+static long LoadDriverPList(char *dirSpec, char *name, long bundleType);
 static long LoadMatchedModules(void);
 static long MatchPersonalities(void);
 static long MatchLibraries(void);
@@ -138,41 +140,15 @@ static TagPtr    gPersonalityHead, gPersonalityTail;
 static char *    gExtensionsSpec;
 static char *    gDriverSpec;
 static char *    gFileSpec;
+static char *    gTempSpec;
+static char *    gFileName;
 
 //==========================================================================
 // BootX shim functions.
 
-#include <ufs/ufs/dir.h>
-
-#define kLoadAddr     TFTP_ADDR
-#define kLoadSize     TFTP_LEN
-
 #define kPageSize     4096
 #define RoundPage(x)  ((((unsigned)(x)) + kPageSize - 1) & ~(kPageSize - 1))
 
-static long
-LoadFile( char * fileSpec )
-{
-    unsigned long count = TFTP_LEN;
-    unsigned long addr  = TFTP_ADDR;
-
-       if ( gBootDev == kBootDevNetwork )
-    {
-        if ( nbpTFTPReadFile(fileSpec, &count, addr) != nbpStatusSuccess )
-            return -1;
-    }
-    else
-    {
-        int fd = open( fileSpec, 0 );
-        if ( fd < 0 )
-            return -1;
-
-        count = read( fd, (char *) addr, count );
-        close(fd);
-    }
-    return count;
-}
-
 static long  gImageFirstBootXAddr;
 static long  gImageLastKernelAddr;
 
@@ -183,7 +159,7 @@ AllocateBootXMemory( long size )
   
        if ( addr < gImageLastKernelAddr ) return 0;
 
-    bzero(addr, size);
+    bzero((void *)addr, size);
 
        gImageFirstBootXAddr = addr;
   
@@ -224,76 +200,14 @@ AllocateMemoryRange(char * rangeName, long start, long length, long type)
     return 0;
 }
 
-// Map BootX file types to UFS file types defined in ufs/ufs/dir.h.
-
-enum {
-       kUnknownFileType    = DT_UNKNOWN,
-       kFlatFileType       = DT_REG,
-       kDirectoryFileType  = DT_DIR,
-       kLinkFileType       = DT_LNK
-};
-
-static long 
-GetFileInfo( char * dirSpec, char * name, long * flags, long * time )
-{
-    struct dirstuff * dir;
-    struct direct *   entry = 0;
-
-    dir = opendir(dirSpec);
-    if ( dir )
-    {
-        while (( entry = readdir(dir) ))
-        {
-            if ( strcmp( entry->d_name, name ) == 0 )
-            {
-                *flags = entry->d_type;
-                *time  = 0;
-                break;
-            }
-        }
-        closedir(dir);
-    }
-    return ( entry ) ? 0 : -1;
-}
-
 // Map BootX types to boot counterparts.
 
-#define gBootFileType    gBootDev
+#define gBootFileType    BIOS_DEV_TYPE(gBIOSDev)
 enum {
-    kNetworkDeviceType = kBootDevNetwork,
-    kBlockDeviceType   = kBootDevHardDisk
+    kNetworkDeviceType = kBIOSDevTypeNetwork,
+    kBlockDeviceType   = kBIOSDevTypeHardDrive
 };
 
-static struct dirstuff *
-OpenDir( char * dirSpec )
-{
-    return opendir(dirSpec);
-}
-
-static void
-CloseDir( struct dirstuff * dirStuff )
-{
-    closedir(dirStuff);
-}
-
-static long
-GetDirEntry( struct dirstuff * dir, long * dirIndex, char ** name, 
-             long * flags, long * time)
-{
-    if ( dir )
-    {
-        struct direct * entry = readdir(dir);
-    
-        if ( entry )
-        {
-            *name  = entry->d_name;
-            *flags = entry->d_type;
-            *time  = 0;
-            return 0;
-        }
-    }
-    return (-1);
-}
 
 static long
 InitDriverSupport()
@@ -301,9 +215,11 @@ InitDriverSupport()
     gExtensionsSpec = (char *) malloc( 4096 );
     gDriverSpec     = (char *) malloc( 4096 );
     gFileSpec       = (char *) malloc( 4096 );
+    gTempSpec       = (char *) malloc( 4096 );
+    gFileName       = (char *) malloc( 4096 );
 
-    if ( !gExtensionsSpec || !gDriverSpec || !gFileSpec )
-        stop( "InitDriverSupport error" );
+    if ( !gExtensionsSpec || !gDriverSpec || !gFileSpec || !gTempSpec || !gFileName )
+        stop("InitDriverSupport error");
 
     gImageLastKernelAddr = RoundPage( kernBootStruct->kaddr +
                                       kernBootStruct->ksize );
@@ -368,7 +284,7 @@ long LoadDrivers( char * dirSpec )
 #endif
 
     MatchPersonalities();
-  
+
     MatchLibraries();
 
     LoadMatchedModules();
@@ -382,19 +298,19 @@ long LoadDrivers( char * dirSpec )
 static long
 FileLoadDrivers( char * dirSpec, long plugin )
 {
-    long   ret, length, index, flags, time;
-    char * name;
-    struct dirstuff * dir;
+    long         ret, length, index, flags, time, bundleType;
+    const char * name;
 
     if ( !plugin )
     {
         long time2;
 
         ret = GetFileInfo(dirSpec, "Extensions.mkext", &flags, &time);
-        if ((ret == 0) && (flags == kFlatFileType))
+        if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeFlat))
         {
             ret = GetFileInfo(dirSpec, "Extensions", &flags, &time2);
-            if ((ret != 0) || (flags == kDirectoryFileType) || (time > time2))
+            if ((ret != 0) || ((flags & kFileTypeMask) != kFileTypeDirectory) ||
+                (((gBootMode & kBootModeSafe) == 0) && (time > time2)))
             {
                 sprintf(gDriverSpec, "%sExtensions.mkext", dirSpec);
                 verbose("LoadDrivers: Loading from [%s]\n", gDriverSpec);
@@ -407,26 +323,32 @@ FileLoadDrivers( char * dirSpec, long plugin )
 
     verbose("LoadDrivers: Loading from [%s]\n", dirSpec);
 
-    // INTEL addition
-    dir = OpenDir( dirSpec );
-
     index = 0;
     while (1) {
-        // INTEL modification
-        ret = GetDirEntry(dir, &index, &name, &flags, &time);
+        ret = GetDirEntry(dirSpec, &index, &name, &flags, &time);
         if (ret == -1) break;
 
         // Make sure this is a directory.
-        if (flags != kDirectoryFileType) continue;
+        if ((flags & kFileTypeMask) != kFileTypeDirectory) continue;
         
         // Make sure this is a kext.
         length = strlen(name);
         if (strcmp(name + length - 5, ".kext")) continue;
 
+        // Save the file name.
+        strcpy(gFileName, name);
+    
+        // Determine the bundle type.
+        sprintf(gTempSpec, "%s/%s", dirSpec, gFileName);
+        ret = GetFileInfo(gTempSpec, "Contents", &flags, &time);
+        if (ret == 0) bundleType = kCFBundleType2;
+        else bundleType = kCFBundleType3;
+
         if (!plugin)
-            sprintf(gDriverSpec, "%s/%s/Contents/PlugIns", dirSpec, name);
+            sprintf(gDriverSpec, "%s/%s/%sPlugIns", dirSpec, gFileName,
+                    (bundleType == kCFBundleType2) ? "Contents/" : "");
 
-        ret = LoadDriverPList(dirSpec, name);
+        ret = LoadDriverPList(dirSpec, gFileName, bundleType);
         if (ret != 0)
         {
             // printf("LoadDrivers: failed\n");
@@ -436,9 +358,6 @@ FileLoadDrivers( char * dirSpec, long plugin )
             ret = FileLoadDrivers(gDriverSpec, 1);
     }
 
-    // INTEL addition
-    if ( dir ) CloseDir( dir );
-    
     return 0;
 }
 
@@ -488,7 +407,7 @@ LoadDriverMKext( char * fileSpec )
     char             segName[32];
     DriversPackage * package = (DriversPackage *)kLoadAddr;
 
-#define GetPackageElement(e)     bswap32(package-> ## e)
+#define GetPackageElement(e)     NXSwapBigLongToHost(package->e)
 
     // Load the MKext.
     if (LoadFile(fileSpec) == -1) return -1;
@@ -522,7 +441,7 @@ LoadDriverMKext( char * fileSpec )
 // LoadDriverPList
 
 static long
-LoadDriverPList( char * dirSpec, char * name )
+LoadDriverPList( char * dirSpec, char * name, long bundleType )
 {
     long      length, driverPathLength;
     ModulePtr module;
@@ -534,7 +453,8 @@ LoadDriverPList( char * dirSpec, char * name )
     do {
         // Save the driver path.
         
-        sprintf(gFileSpec, "%s/%s/Contents/MacOS/", dirSpec, name);
+        sprintf(gFileSpec, "%s/%s/%s", dirSpec, name,
+                (bundleType == kCFBundleType2) ? "Contents/MacOS/" : "");
         driverPathLength = strlen(gFileSpec);
 
         tmpDriverPath = malloc(driverPathLength + 1);
@@ -544,7 +464,8 @@ LoadDriverPList( char * dirSpec, char * name )
   
         // Construct the file spec to the plist, then load it.
 
-        sprintf(gFileSpec, "%s/%s/Contents/Info.plist", dirSpec, name);
+        sprintf(gFileSpec, "%s/%s/%sInfo.plist", dirSpec, name,
+                (bundleType == kCFBundleType2) ? "Contents/" : "");
 
         length = LoadFile(gFileSpec);
         if (length == -1) break;
index db91fe503e44178941b30c2a7f663459be560b60..da3fb64cbe35514791d1e2a2f2da7a6d3028ac46 100644 (file)
  * All rights reserved.
  */
 
-#include "libsaio.h"
 #include "boot.h"
 #include "vbe.h"
-#include "kernBootStruct.h"
-
-#define CHAR_W         8
-#define CHAR_W_SHIFT   3
-#define CHAR_H         16
-#define CHAR_H_SHIFT   4
-#define BYTE_SHIFT     3
-#define NCOLS          (screen_width / CHAR_W)
-#define NROWS          (screen_height / CHAR_H)
-#define SCREEN_W       (screen_width)
-#define SCREEN_H       (screen_height)
+#include "appleClut8.h"
+#include "happy_screen.h"
 
 /*
- * Forward declarations.
+ * for spinning disk
  */
-static int convert_vbe_mode(char * mode_name, int * mode);
-BOOL gSilentBoot;
+static int currentIndicator = 0;
+
+static unsigned long lookUpCLUTIndex( unsigned char index,
+                                      unsigned char depth );
+
+static void drawColorRectangle( unsigned short x,
+                                unsigned short y,
+                                unsigned short width,
+                                unsigned short height,
+                                unsigned char  colorIndex );
+
+static void drawDataRectangle( unsigned short  x,
+                               unsigned short  y,
+                               unsigned short  width,
+                               unsigned short  height,
+                               unsigned char * data );
+
+#define VIDEO(x) (kernBootStruct->video.v_ ## x)
+
 
 //==========================================================================
-// Display a (optionally centered) text message.
+// printVBEInfo
 
-void
-message(char * str, int centered)
+void printVBEInfo()
+{
+    VBEInfoBlock vbeInfo;
+    int          err;
+
+    // Fetch VBE Controller Info.
+
+    bzero( &vbeInfo, sizeof(vbeInfo) );
+    err = getVBEInfo( &vbeInfo );
+    if ( err != errSuccess )
+        return;
+
+    // Check presence of VESA signature.
+
+    if ( strncmp( vbeInfo.VESASignature, "VESA", 4 ) )
+        return;
+
+    // Announce controller properties.
+
+    printf("VESA v%d.%d %dMB (%s)\n",
+           vbeInfo.VESAVersion >> 8,
+           vbeInfo.VESAVersion & 0xf,
+           vbeInfo.TotalMemory / 16,
+           VBEDecodeFP(const char *, vbeInfo.OEMStringPtr) );
+}
+
+//==========================================================================
+// getVESAModeWithProperties
+//
+// Return the VESA mode that matches the properties specified.
+// If a mode is not found, then return the "best" available mode.
+
+static unsigned short
+getVESAModeWithProperties( unsigned short     width,
+                           unsigned short     height,
+                           unsigned char      bitsPerPixel,
+                           unsigned short     attributesSet,
+                           unsigned short     attributesClear,
+                           VBEModeInfoBlock * outModeInfo )
 {
-       register int x;
+    VBEInfoBlock     vbeInfo;
+    unsigned short * modePtr;
+       VBEModeInfoBlock modeInfo;
+    unsigned char    modeBitsPerPixel;
+    unsigned short   matchedMode = modeEndOfList;
+    int              err;
+
+    // Clear output mode info.
 
-       x = (NCOLS - strlen(str)) >> 1;
+    bzero( outModeInfo, sizeof(*outModeInfo) );
 
-       if ( currentMode() == TEXT_MODE )
+    // Get VBE controller info containing the list of supported modes.
+
+    bzero( &vbeInfo, sizeof(vbeInfo) );
+    err = getVBEInfo( &vbeInfo );
+    if ( err != errSuccess )
+    {
+        return modeEndOfList;
+    }
+
+    // Loop through the mode list, and find the matching mode.
+
+    for ( modePtr = VBEDecodeFP( unsigned short *, vbeInfo.VideoModePtr );
+          *modePtr != modeEndOfList; modePtr++ )
     {
-           if (centered)
+        // Get mode information.
+
+        bzero( &modeInfo, sizeof(modeInfo) );
+        err = getVBEModeInfo( *modePtr, &modeInfo );
+        if ( err != errSuccess )
         {
-            while(x--) printf(" ");
+            continue;
         }
-           printf("%s\n", str);
-       }
+
+#if 0   // debug
+        printf("Mode %x: %dx%dx%d mm:%d attr:%x\n",
+               *modePtr, modeInfo.XResolution, modeInfo.YResolution,
+               modeInfo.BitsPerPixel, modeInfo.MemoryModel,
+               modeInfo.ModeAttributes);
+#endif
+
+        // Filter out unwanted modes based on mode attributes.
+
+        if ( ( ( modeInfo.ModeAttributes & attributesSet ) != attributesSet )
+        ||   ( ( modeInfo.ModeAttributes & attributesClear ) != 0 ) )
+        {
+            continue;
+        }
+
+        // Pixel depth in bits.
+
+        modeBitsPerPixel = modeInfo.BitsPerPixel;
+
+        if ( ( modeBitsPerPixel == 4 ) && ( modeInfo.MemoryModel == 0 ) )
+        {
+            // Text mode, 16 colors.
+        }
+        else if ( ( modeBitsPerPixel == 8 ) && ( modeInfo.MemoryModel == 4 ) )
+        {
+            // Packed pixel, 256 colors.
+        }
+        else if ( ( ( modeBitsPerPixel == 16 ) || ( modeBitsPerPixel == 15 ) )
+        &&   ( modeInfo.MemoryModel   == 6 )
+        &&   ( modeInfo.RedMaskSize   == 5 )
+        &&   ( modeInfo.GreenMaskSize == 5 )
+        &&   ( modeInfo.BlueMaskSize  == 5 ) )
+        {
+            // Direct color, 16 bpp (1:5:5:5).
+            modeInfo.BitsPerPixel = modeBitsPerPixel = 16;
+        }
+        else if ( ( modeBitsPerPixel == 32 )
+        &&   ( modeInfo.MemoryModel   == 6 )
+        &&   ( modeInfo.RedMaskSize   == 8 )
+        &&   ( modeInfo.GreenMaskSize == 8 )
+        &&   ( modeInfo.BlueMaskSize  == 8 ) )
+        {
+            // Direct color, 32 bpp (8:8:8:8).
+        }
+        else
+        {
+            continue; // Not a supported mode.
+        }
+
+        // Modes larger than the specified dimensions are skipped.
+
+        if ( ( modeInfo.XResolution > width  ) ||
+             ( modeInfo.YResolution > height ) )
+        {
+            continue;
+        }
+
+        // Perfect match, we're done looking.
+
+        if ( ( modeInfo.XResolution == width  ) &&
+             ( modeInfo.YResolution == height ) &&
+             ( modeBitsPerPixel     == bitsPerPixel ) )
+        {
+            matchedMode = *modePtr;
+            bcopy( &modeInfo, outModeInfo, sizeof(modeInfo) );
+            break;
+        }
+
+        // Save the next "best" mode in case a perfect match
+        // is not found.
+
+        if ( ( modeInfo.XResolution >= outModeInfo->XResolution  ) &&
+             ( modeInfo.YResolution >= outModeInfo->YResolution  ) &&
+             ( modeBitsPerPixel     >= outModeInfo->BitsPerPixel ) )
+        {
+            matchedMode = *modePtr;
+            bcopy( &modeInfo, outModeInfo, sizeof(modeInfo) );
+        }
+    }
+
+    return matchedMode;
 }
 
-/*
- * for spinning disk
- */
-static int currentIndicator = 0;
+//==========================================================================
+// setupPalette
+
+static void setupPalette( VBEPalette * p, const unsigned char * g )
+{
+    int             i;
+    unsigned char * source = (unsigned char *) g;
+
+    for (i = 0; i < 256; i++)
+    {
+        (*p)[i] = 0;
+        (*p)[i] |= ((unsigned long)((*source++) >> 2)) << 16;   // Red
+        (*p)[i] |= ((unsigned long)((*source++) >> 2)) << 8;    // Green
+        (*p)[i] |= ((unsigned long)((*source++) >> 2));         // Blue
+    }
+}
 
 //==========================================================================
-// Set the screen mode: TEXT_MODE or GRAPHICS_MODE
+// setVESAGraphicsMode
 
-void
-setMode(int mode)
+static int
+setVESAGraphicsMode( unsigned short width,
+                     unsigned short height,
+                     unsigned char  bitsPerPixel )
 {
-       unsigned int vmode;
-       char *       vmode_name;
-    int          err = errSuccess;
+    VBEModeInfoBlock  minfo;
+    unsigned short    mode;
+    int               err = errFuncNotSupported;
+
+    do {
+        mode = getVESAModeWithProperties( width, height, bitsPerPixel,
+                                          maColorModeBit             |
+                                          maModeIsSupportedBit       |
+                                          maGraphicsModeBit          |
+                                          maLinearFrameBufferAvailBit,
+                                          0,
+                                          &minfo );
+        if ( mode == modeEndOfList )
+        {
+            break;
+        }
+
+        // Set the mode.
+
+        err = setVBEMode( mode | kLinearFrameBufferBit );
+        if ( err != errSuccess )
+        {
+            break;
+        }
+
+        // Set 8-bit color palette.
+
+        if ( minfo.BitsPerPixel == 8 )
+        {
+            VBEPalette palette;
+            setupPalette( &palette, appleClut8 );
+            if ((err = setVBEPalette(palette)) != errSuccess)
+            {
+                break;
+            }
+        }
+
+        // Is this required for buggy Video BIOS implementations?
+        // On which adapter?
+
+        if ( minfo.BytesPerScanline == 0 )
+             minfo.BytesPerScanline = ( minfo.XResolution *
+                                        minfo.BitsPerPixel ) >> 3;
 
-    if ( currentMode() == mode ) return;
+        // Update KernBootStruct using info provided by the selected
+        // VESA mode.
 
-    if ( mode == GRAPHICS_MODE &&
-        (vmode_name = newStringForKey(kGraphicsModeKey)) != 0)
+        kernBootStruct->graphicsMode     = GRAPHICS_MODE;
+        kernBootStruct->video.v_width    = minfo.XResolution;
+        kernBootStruct->video.v_height   = minfo.YResolution;
+        kernBootStruct->video.v_depth    = minfo.BitsPerPixel;
+        kernBootStruct->video.v_rowBytes = minfo.BytesPerScanline;
+        kernBootStruct->video.v_baseAddr = VBEMakeUInt32(minfo.PhysBasePtr);
+    }
+    while ( 0 );
+
+    if ( err == errSuccess )
     {
-        // Set to the graphics mode specified in the config table file,
-        // enable linear frame buffer mode, and update kernBootStruct.
+        char  * happyScreen;
+        short * happyScreen16;
+        long  * happyScreen32;
+        long    cnt, x, y;
+  
+        // Fill the background to white (same as BootX).
 
-        if ( convert_vbe_mode(vmode_name, &vmode) == 0 )
-            vmode = mode1024x768x256;   /* default mode */
+        drawColorRectangle( 0, 0, minfo.XResolution, minfo.YResolution,
+                            0x00 /* color index */ );
 
-        err = set_linear_video_mode(vmode);
+        // Prepare the data for the happy mac.
 
-        if ( err == errSuccess )
+        switch ( VIDEO(depth) )
         {
-            kernBootStruct->graphicsMode     = GRAPHICS_MODE;
-            kernBootStruct->video.v_display  = gSilentBoot;
-            kernBootStruct->video.v_baseAddr = (unsigned long) frame_buffer;
-            kernBootStruct->video.v_width    = SCREEN_W;
-            kernBootStruct->video.v_height   = SCREEN_H;
-            kernBootStruct->video.v_depth    = bits_per_pixel;
-            kernBootStruct->video.v_rowBytes = (screen_rowbytes == 0) ? 
-                (SCREEN_W * bits_per_pixel) >> BYTE_SHIFT : screen_rowbytes;
+            case 16 :
+                happyScreen16 = malloc(kHappyScreenWidth * kHappyScreenHeight * 2);
+                for (cnt = 0; cnt < (kHappyScreenWidth * kHappyScreenHeight); cnt++)
+                    happyScreen16[cnt] = lookUpCLUTIndex(gHappyScreenPict[cnt], 16);
+                happyScreen = (char *) happyScreen16;
+                break;
+
+            case 32 :
+                happyScreen32 = malloc(kHappyScreenWidth * kHappyScreenHeight * 4);
+                for (cnt = 0; cnt < (kHappyScreenWidth * kHappyScreenHeight); cnt++)
+                    happyScreen32[cnt] = lookUpCLUTIndex(gHappyScreenPict[cnt], 32);
+                happyScreen = (char *) happyScreen32;
+                break;
+
+            default :
+                happyScreen = (char *) gHappyScreenPict;
+                break;
         }
 
-        free(vmode_name);
+        x = ( VIDEO(width) - kHappyScreenWidth ) / 2;
+        y = ( VIDEO(height) - kHappyScreenHeight ) / 2 + kHappyScreenOffset;
+
+        // Draw the happy mac in the center of the display.
+
+        drawDataRectangle( x, y, kHappyScreenWidth, kHappyScreenHeight,
+                           happyScreen );
+       }
+
+    return err;
+}
+
+//==========================================================================
+// LookUpCLUTIndex
+
+static unsigned long lookUpCLUTIndex( unsigned char index,
+                                      unsigned char depth )
+{
+       long result, red, green, blue;
+  
+       red   = appleClut8[index * 3 + 0];
+       green = appleClut8[index * 3 + 1];
+       blue  = appleClut8[index * 3 + 2];
+
+       switch (depth) {
+        case 16 :
+            result = ((red   & 0xF8) << 7) | 
+                     ((green & 0xF8) << 2) |
+                     ((blue  & 0xF8) >> 3);
+            result |= (result << 16);
+            break;
+
+        case 32 :
+            result = (red << 16) | (green << 8) | blue;
+            break;
+
+        default :
+            result = index | (index << 8);
+            result |= (result << 16);
+            break;
     }
-    
-    if ( (mode == TEXT_MODE) || (err != errSuccess) )
+
+       return result;
+}
+
+//==========================================================================
+// drawColorRectangle
+
+static void * stosl(void * dst, long val, long len)
+{
+    asm( "rep; stosl"
+       : "=c" (len), "=D" (dst)
+       : "0" (len), "1" (dst), "a" (val)
+       : "memory" );
+
+    return dst;
+}
+
+static void drawColorRectangle( unsigned short x,
+                                unsigned short y,
+                                unsigned short width,
+                                unsigned short height,
+                                unsigned char  colorIndex )
+{
+    long   pixelBytes;
+    long   color = lookUpCLUTIndex( colorIndex, VIDEO(depth) );
+    char * vram;
+
+    pixelBytes = VIDEO(depth) / 8;
+    vram       = (char *) VIDEO(baseAddr) +
+                 VIDEO(rowBytes) * y + pixelBytes * x;
+
+    while ( height-- )
     {
-        video_mode(2);  // 80x25 text mode
-
-        kernBootStruct->graphicsMode     = TEXT_MODE;
-        kernBootStruct->video.v_display  = 0;
-        kernBootStruct->video.v_baseAddr = (unsigned long) 0xb8000;
-        kernBootStruct->video.v_width    = 80;
-        kernBootStruct->video.v_height   = 25;
-        kernBootStruct->video.v_depth    = 8;
-        kernBootStruct->video.v_rowBytes = 0x8000;
+        int rem = ( pixelBytes * width ) % 4;
+        if ( rem ) bcopy( &color, vram, rem );
+        stosl( vram + rem, color, pixelBytes * width / 4 );
+        vram += VIDEO(rowBytes);
     }
+}
 
-       currentIndicator = 0;
+//==========================================================================
+// drawDataRectangle
+
+static void drawDataRectangle( unsigned short  x,
+                               unsigned short  y,
+                               unsigned short  width,
+                               unsigned short  height,
+                               unsigned char * data )
+{
+    long   pixelBytes = VIDEO(depth) / 8;
+    char * vram       = (char *) VIDEO(baseAddr) +
+                        VIDEO(rowBytes) * y + pixelBytes * x;
+
+    while ( height-- )
+    {
+        bcopy( data, vram, width * pixelBytes );
+        vram += VIDEO(rowBytes);
+        data += width * pixelBytes;
+    }
 }
 
 //==========================================================================
-// Return the current screen mode, TEXT_MODE or GRAPHICS_MODE.
+// setVESATextMode
 
-int currentMode(void)
+static int
+setVESATextMode( unsigned short cols,
+                 unsigned short rows,
+                 unsigned char  bitsPerPixel )
 {
-    return kernBootStruct->graphicsMode;
+    VBEModeInfoBlock  minfo;
+    unsigned short    mode = modeEndOfList;
+
+    if ( (cols != 80) || (rows != 25) )  // not 80x25 mode
+    {
+        mode = getVESAModeWithProperties( cols, rows, bitsPerPixel,
+                                          maColorModeBit |
+                                          maModeIsSupportedBit,
+                                          maGraphicsModeBit,
+                                          &minfo );
+    }
+
+    if ( ( mode == modeEndOfList ) || ( setVBEMode(mode) != errSuccess ) )
+    {
+        video_mode( 2 );  // VGA BIOS, 80x25 text mode.
+        minfo.XResolution = 80;
+        minfo.YResolution = 25;
+    }
+
+    // Update KernBootStruct using info provided by the selected
+    // VESA mode.
+
+    kernBootStruct->graphicsMode     = TEXT_MODE;
+    kernBootStruct->video.v_baseAddr = 0xb8000;
+    kernBootStruct->video.v_width    = minfo.XResolution;
+    kernBootStruct->video.v_height   = minfo.YResolution;
+    kernBootStruct->video.v_depth    = 8;
+    kernBootStruct->video.v_rowBytes = 0x8000;
+
+    return errSuccess;  // always return success
 }
 
 //==========================================================================
-// Convert from a string describing a graphics mode, to a VGA mode number.
-
-typedef struct {
-    char mode_name[15];
-    int  mode_val;
-} mode_table_t;
-
-mode_table_t mode_table[] = {
-    { "640x400x256",   mode640x400x256   },
-    { "640x480x256",   mode640x480x256   },
-    { "800x600x16",    mode800x600x16    },
-    { "800x600x256",   mode800x600x256   },
-    { "1024x768x16",   mode1024x768x16   },
-    { "1024x768x256",  mode1024x768x256  },
-    { "1280x1024x16",  mode1280x1024x16  },
-    { "1280x1024x256", mode1280x1024x256 },
-    { "640x480x555",   mode640x480x555   },
-    { "640x480x888",   mode640x480x888   },
-    { "800x600x555",   mode800x600x555   },
-    { "800x600x888",   mode800x600x888   },
-    { "1024x768x555",  mode1024x768x555  },
-    { "1024x768x888",  mode1024x768x888  },
-    { "1280x1024x555", mode1280x1024x555 },
-    { "1280x1024x888", mode1280x1024x888 },
-    { "", 0 }
-};
-
-int convert_vbe_mode(char * mode_name, int * mode)
+// getNumberArrayFromProperty
+
+static int
+getNumberArrayFromProperty( const char *  propKey,
+                            unsigned long numbers[],
+                            unsigned long maxArrayCount )
 {
-    mode_table_t * mtp = mode_table;
+       char * propStr;
+    int    count = 0;
 
-    if (mode_name == 0 || *mode_name == 0)
-        return 0;
+#define _isdigit(c) ((c) >= '0' && (c) <= '9')
 
-    while ( *mtp->mode_name )
+    propStr = newStringForKey( (char *) propKey );
+    if ( propStr )
     {
-        if (strcmp(mtp->mode_name, mode_name) == 0)
+        char * delimiter = propStr;
+
+        while ( count < maxArrayCount && *propStr != '\0' )
         {
-               *mode =  mtp->mode_val;
-               return 1;
+            unsigned long val = strtoul( propStr, &delimiter, 10 );
+            if ( propStr != delimiter )
+            {
+                numbers[count++] = val;
+                propStr = delimiter;
+            }
+            while ( ( *propStr != '\0' ) && !_isdigit(*propStr) )
+                propStr++;
         }
-        mtp++;
+
+        free( propStr );
     }
-    return 0;
+
+    return count;
+}
+
+//==========================================================================
+// setVideoMode
+//
+// Set the video mode to TEXT_MODE or GRAPHICS_MODE.
+
+void
+setVideoMode( int mode )
+{
+    unsigned long params[3];
+    int           count;
+    int           err = errSuccess;
+
+    if ( mode == GRAPHICS_MODE )
+    {
+        count = getNumberArrayFromProperty( kGraphicsModeKey, params, 3 );
+        if ( count < 3 )
+        {
+            params[0] = 1024;  // Default graphics mode is 1024x768x16.
+            params[1] = 768;
+            params[2] = 16;
+        }
+
+        // Map from pixel format to bits per pixel.
+
+        if ( params[2] == 256 ) params[2] = 8;
+        if ( params[2] == 555 ) params[2] = 16;
+        if ( params[2] == 888 ) params[2] = 32;
+
+        err = setVESAGraphicsMode( params[0], params[1], params[2] );
+        if ( err == errSuccess )
+        {
+            // If this boolean is set to true, then the console driver
+            // in the kernel will show the animated color wheel on the
+            // upper left corner.
+
+            kernBootStruct->video.v_display = !gVerboseMode;
+        }
+    }
+
+    if ( (mode == TEXT_MODE) || (err != errSuccess) )
+    {
+        count = getNumberArrayFromProperty( kTextModeKey, params, 2 );
+        if ( count < 2 )
+        {
+            params[0] = 80;  // Default text mode is 80x25.
+            params[1] = 25;
+        }
+
+        setVESATextMode( params[0], params[1], 4 );
+        kernBootStruct->video.v_display = 0;
+    }
+
+       currentIndicator = 0;
+}
+
+//==========================================================================
+// Return the current video mode, TEXT_MODE or GRAPHICS_MODE.
+
+int getVideoMode(void)
+{
+    return kernBootStruct->graphicsMode;
 }
 
 //==========================================================================
@@ -202,7 +592,7 @@ spinActivityIndicator( void )
     else
         lastTickTime = currentTickTime;
        
-    if ( currentMode() == TEXT_MODE )
+    if ( getVideoMode() == TEXT_MODE )
     {
         string[0] = indicator[currentIndicator];
         printf(string);
@@ -214,7 +604,7 @@ spinActivityIndicator( void )
 void
 clearActivityIndicator( void )
 {
-    if ( currentMode() == TEXT_MODE )
+    if ( getVideoMode() == TEXT_MODE )
     {
         printf(" \b");
     }
diff --git a/i386/boot2/happy_screen.h b/i386/boot2/happy_screen.h
new file mode 100644 (file)
index 0000000..81f875d
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License").  You may not use this file except in compliance with the
+ * License.  Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
+ * 
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ *  happy_screen.h - Picture displayed a the beginning of the boot process
+ *
+ *  Copyright (c) 2002 Apple Computer, Inc.
+ *
+ *  DRI: Josh de Cesare
+ */
+
+#define kHappyScreenWidth   (52)
+#define kHappyScreenHeight  (44)
+#define kHappyScreenOffset  (-44)
+
+static const unsigned char gHappyScreenPict[] =
+{
+       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+       0x00,0x00,0x12,0x27,0xf7,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0xf7,0x27,0x12,0x00,0x00,
+       0x00,0x12,0x37,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x37,0x12,0x00,
+       0x00,0x27,0x50,0x43,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x43,0x50,0x27,0x00,
+       0x00,0xf7,0x50,0x20,0xa3,0x33,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x33,0xa3,0x20,0x50,0xf7,0x00,
+       0x00,0x50,0x50,0x00,0x33,0x33,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x33,0x33,0x00,0x50,0x50,0x00,
+       0x00,0x50,0x50,0x00,0x4d,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x4d,0x00,0x50,0x50,0x00,
+       0x00,0x50,0x50,0x00,0x4d,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x4d,0x00,0x50,0x50,0x00,
+       0x00,0x50,0x50,0x00,0x4d,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x4d,0x00,0x50,0x50,0x00,
+       0x00,0x50,0x50,0x00,0x4d,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x4d,0x00,0x50,0x50,0x00,
+       0x00,0x50,0x50,0x00,0x4d,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x4d,0x00,0x50,0x50,0x00,
+       0x00,0x50,0x50,0x00,0x4d,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x4d,0x00,0x50,0x50,0x00,
+       0x00,0x50,0x50,0x00,0x4d,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x4d,0x00,0x50,0x50,0x00,
+       0x00,0x50,0x50,0x00,0x4d,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x4d,0x00,0x50,0x50,0x00,
+       0x00,0x50,0x50,0x00,0x4d,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x4d,0x00,0x50,0x50,0x00,
+       0x00,0x50,0x50,0x00,0x4d,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x19,0x37,0x3c,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x19,0x37,0x3c,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x4d,0x00,0x50,0x50,0x00,
+       0x00,0x50,0x50,0x00,0x4d,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa3,0x55,0x55,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa3,0x55,0x55,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x4d,0x00,0x50,0x50,0x00,
+       0x00,0x50,0x50,0x00,0x4d,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0b,0x4d,0x50,0x0d,0x00,0x00,0x00,0x12,0x33,0x09,0x00,0x00,0x00,0x00,0x0b,0x4d,0x50,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x4d,0x00,0x50,0x50,0x00,
+       0x00,0x50,0x50,0x00,0x4d,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x15,0x01,0x00,0x00,0x07,0x4d,0x1e,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x15,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x4d,0x00,0x50,0x50,0x00,
+       0x00,0x50,0x50,0x00,0x4d,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1e,0x50,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x4d,0x00,0x50,0x50,0x00,
+       0x00,0x50,0x50,0x00,0x4d,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2f,0x4d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x4d,0x00,0x50,0x50,0x00,
+       0x00,0x50,0x50,0x00,0x4d,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x4d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x4d,0x00,0x50,0x50,0x00,
+       0x00,0x50,0x50,0x00,0x4d,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2f,0x50,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x4d,0x00,0x50,0x50,0x00,
+       0x00,0x50,0x50,0x00,0x4d,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x29,0x50,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x4d,0x00,0x50,0x50,0x00,
+       0x00,0x50,0x50,0x00,0x4d,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1d,0x50,0x37,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x4d,0x00,0x50,0x50,0x00,
+       0x00,0x50,0x50,0x00,0x4d,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0xc0,0x27,0x17,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x4d,0x00,0x50,0x50,0x00,
+       0x00,0x50,0x50,0x00,0x4d,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x4d,0x00,0x50,0x50,0x00,
+       0x00,0x50,0x50,0x00,0x4d,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x31,0x50,0x1b,0x00,0x00,0x00,0x00,0x00,0x00,0x1b,0x50,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x4d,0x00,0x50,0x50,0x00,
+       0x00,0x50,0x50,0x00,0x4d,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1e,0x50,0x33,0xa3,0x00,0x00,0x00,0x00,0xa3,0x33,0x50,0x1e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x4d,0x00,0x50,0x50,0x00,
+       0x00,0x50,0x50,0x00,0x4d,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0a,0x2f,0x50,0x33,0x1b,0x0a,0x0a,0x1b,0x33,0x50,0x2f,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x4d,0x00,0x50,0x50,0x00,
+       0x00,0x50,0x50,0x00,0x4d,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11,0x2f,0x50,0x50,0x50,0x50,0x50,0x50,0x2f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x4d,0x00,0x50,0x50,0x00,
+       0x00,0x50,0x50,0x00,0x4d,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0a,0x1e,0x31,0x43,0x43,0x31,0x1e,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x4d,0x00,0x50,0x50,0x00,
+       0x00,0x50,0x50,0x00,0x4d,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x4d,0x00,0x50,0x50,0x00,
+       0x00,0x50,0x50,0x00,0x4d,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x4d,0x00,0x50,0x50,0x00,
+       0x00,0x50,0x50,0x00,0x4d,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x4d,0x00,0x50,0x50,0x00,
+       0x00,0x50,0x50,0x00,0x4d,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x4d,0x00,0x50,0x50,0x00,
+       0x00,0x50,0x50,0x00,0x4d,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x4d,0x00,0x50,0x50,0x00,
+       0x00,0x50,0x50,0x00,0x4d,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x4d,0x00,0x50,0x50,0x00,
+       0x00,0x50,0x50,0x00,0x33,0x33,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x33,0x33,0x00,0x50,0x50,0x00,
+       0x00,0x50,0x50,0x20,0xa3,0x33,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x33,0xa3,0x20,0x50,0x50,0x00,
+       0x00,0x27,0x50,0x43,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x43,0x50,0x27,0x00,
+       0x00,0x12,0x37,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x37,0x12,0x00,
+       0x00,0x00,0x12,0x27,0xf7,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0xf7,0x27,0x12,0x00,0x00,
+       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+};
diff --git a/i386/boot2/options.c b/i386/boot2/options.c
new file mode 100644 (file)
index 0000000..b48f091
--- /dev/null
@@ -0,0 +1,636 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#include "boot.h"
+#include "fdisk.h"
+
+enum {
+    kReturnKey     = 0x0d,
+    kEscapeKey     = 0x1b,
+    kBackspaceKey  = 0x08,
+    kASCIIKeyMask  = 0x7f
+};
+
+enum {
+    kMenuTopRow    = 5,
+    kMenuMaxItems  = 6,
+    kScreenLastRow = 24
+};
+
+static BVRef gBootVolume = 0;
+
+static void showHelp();
+
+//==========================================================================
+
+enum {
+    kCursorTypeHidden    = 0x0100,
+    kCursorTypeUnderline = 0x0607
+};
+
+typedef struct {
+    int x;
+    int y;
+    int type;
+} CursorState;
+
+static void changeCursor( int col, int row, int type, CursorState * cs )
+{
+    if (cs) getCursorPositionAndType( &cs->x, &cs->y, &cs->type );
+    setCursorType( type );
+    setCursorPosition( col, row, 0 );
+}
+
+static void moveCursor( int col, int row )
+{
+    setCursorPosition( col, row, 0 );
+}
+
+static void restoreCursor( const CursorState * cs )
+{
+    setCursorPosition( cs->x, cs->y, 0 );
+    setCursorType( cs->type );
+}
+
+//==========================================================================
+
+static void flushKeyboardBuffer()
+{
+    while ( readKeyboardStatus() ) getc();
+}
+
+//==========================================================================
+
+static int countdown( const char * msg, int row, int timeout )
+{
+    int time;
+    int ch  = 0;
+    int col = strlen(msg) + 1;
+
+    flushKeyboardBuffer();
+
+    moveCursor( 0, row );
+    printf(msg);
+
+    for ( time = time18(), timeout++; timeout; )
+    {
+        if (ch = readKeyboardStatus())
+            break;
+
+        if ( time18() >= time )
+        {
+            time += 18;
+            timeout--;
+            moveCursor( col, row );
+            printf("(%d) ", timeout);
+        }
+    }
+
+    flushKeyboardBuffer();
+
+    return ch;
+}
+
+//==========================================================================
+
+static char   gBootArgs[BOOT_STRING_LEN];
+static char * gBootArgsPtr = gBootArgs;
+static char * gBootArgsEnd = gBootArgs + BOOT_STRING_LEN - 1;
+
+static void clearBootArgs()
+{
+    gBootArgsPtr = gBootArgs;
+    memset( gBootArgs, '\0', BOOT_STRING_LEN );
+}
+
+//==========================================================================
+
+static void showBootPrompt( int row, BOOL visible )
+{
+    extern char bootPrompt[];
+
+    changeCursor( 0, row, kCursorTypeUnderline, 0 );    
+    clearScreenRows( row, kScreenLastRow );
+    clearBootArgs();
+
+    if ( visible )
+    {
+        printf( bootPrompt );
+    }
+    else
+    {
+        printf("Press Return to start up the foreign OS. ");
+    }
+}
+
+//==========================================================================
+
+static void updateBootArgs( int key )
+{
+    key &= kASCIIKeyMask;
+
+    switch ( key )
+    {
+        case kBackspaceKey:
+            if ( gBootArgsPtr > gBootArgs )
+            {
+                int x, y, t;
+                getCursorPositionAndType( &x, &y, &t );
+                if ( x == 0 && y )
+                {
+                    x = 80; y--;
+                }
+                if (x) x--;
+                setCursorPosition( x, y, 0 );
+                putca(' ', 0x07, 1);
+                *gBootArgsPtr-- = '\0';
+            }
+            break;
+
+        default:
+            if ( key >= ' ' && gBootArgsPtr < gBootArgsEnd)
+            {
+                putchar(key);  // echo to screen
+                *gBootArgsPtr++ = key;
+            }
+            break;
+    }
+}
+
+//==========================================================================
+
+typedef struct {
+    char   name[80];
+    void * param;
+} MenuItem;
+
+static const MenuItem * gMenuItems = NULL;
+static int   gMenuItemCount;
+static int   gMenuRow;
+static int   gMenuHeight;
+static int   gMenuTop;
+static int   gMenuBottom;
+static int   gMenuSelection;
+
+static void printMenuItem( const MenuItem * item, int highlight )
+{
+    printf("  ");
+
+    if ( highlight )
+        putca(' ', 0x70, strlen(item->name) + 4);
+    else
+        putca(' ', 0x07, 40);
+
+    printf("  %40s\n", item->name);
+}
+
+//==========================================================================
+
+static void showMenu( const MenuItem * items, int count,
+                      int selection, int row, int height )
+{
+    int         i;
+    CursorState cursorState;
+
+    if ( items == NULL || count == 0 ) return;
+
+    // head and tail points to the start and the end of the list.
+    // top and bottom points to the first and last visible items
+    // in the menu window.
+
+    gMenuItems     = items;
+    gMenuRow       = row;
+    gMenuHeight    = height;
+    gMenuItemCount = count;
+    gMenuTop       = 0;
+    gMenuBottom    = min( count, height ) - 1;
+    gMenuSelection = selection;
+
+    // If the selected item is not visible, shift the list down.
+
+    if ( gMenuSelection > gMenuBottom )
+    {
+        gMenuTop += ( gMenuSelection - gMenuBottom );
+        gMenuBottom = gMenuSelection;
+    }
+
+    // Draw the visible items.
+
+    changeCursor( 0, row, kCursorTypeHidden, &cursorState );
+
+    for ( i = gMenuTop; i <= gMenuBottom; i++ )
+    {
+        printMenuItem( &items[i], (i == gMenuSelection) );
+    }
+
+    restoreCursor( &cursorState );
+}
+
+//==========================================================================
+
+static int updateMenu( int key, void ** paramPtr )
+{
+    int moved = 0;
+
+    union {
+        struct {
+            unsigned int
+                selectionUp   : 1,
+                selectionDown : 1,
+                scrollUp      : 1,
+                scrollDown    : 1;
+        } f;
+        unsigned int w;
+    } draw = {{0}};
+
+    if ( NULL == gMenuItems ) return 0;
+
+    // Look at the scan code.
+
+    switch ( key )
+    {
+        case 0x4800:  // Up Arrow
+            if ( gMenuSelection != gMenuTop )
+                draw.f.selectionUp = 1;
+            else if ( gMenuTop > 0 )
+                draw.f.scrollDown = 1;
+            break;
+
+        case 0x5000:  // Down Arrow
+            if ( gMenuSelection != gMenuBottom )
+                draw.f.selectionDown = 1;
+            else if ( gMenuBottom < (gMenuItemCount - 1) ) 
+                draw.f.scrollUp = 1;
+            break;
+    }
+
+    if ( draw.w )
+    {
+        if ( draw.f.scrollUp )
+        {
+            scollPage(0, gMenuRow, 40, gMenuRow + gMenuHeight - 1, 0x07, 1, 1);
+            gMenuTop++; gMenuBottom++;
+            draw.f.selectionDown = 1;
+        }
+
+        if ( draw.f.scrollDown )
+        {
+            scollPage(0, gMenuRow, 40, gMenuRow + gMenuHeight - 1, 0x07, 1, -1);
+            gMenuTop--; gMenuBottom--;
+            draw.f.selectionUp = 1;
+        }
+
+        if ( draw.f.selectionUp || draw.f.selectionDown )
+        {
+            CursorState cursorState;
+
+            // Set cursor at current position, and clear inverse video.
+
+            changeCursor( 0, gMenuRow + gMenuSelection - gMenuTop,
+                          kCursorTypeHidden, &cursorState );
+
+            printMenuItem( &gMenuItems[gMenuSelection], 0 );
+
+            if ( draw.f.selectionUp ) gMenuSelection--;
+            else                      gMenuSelection++;
+
+            moveCursor( 0, gMenuRow + gMenuSelection - gMenuTop );
+
+            printMenuItem( &gMenuItems[gMenuSelection], 1 );
+
+            restoreCursor( &cursorState );
+        }
+
+        *paramPtr = gMenuItems[gMenuSelection].param;        
+        moved = 1;
+    }
+
+    return moved;
+}
+
+//==========================================================================
+
+static void skipblanks( const char ** cpp ) 
+{
+    while ( **(cpp) == ' ' || **(cpp) == '\t' ) ++(*cpp);
+}
+
+//==========================================================================
+
+static const char * extractKernelName( char ** cpp )
+{
+    char * kn = *cpp;
+    char * cp = *cpp;
+    char   c;
+
+    // Convert char to lower case.
+
+    c = *cp | 0x20;
+
+    // Must start with a letter or a '/'.
+
+    if ( (c < 'a' || c > 'z') && ( c != '/' ) )
+        return 0;
+
+    // Keep consuming characters until we hit a separator.
+
+    while ( *cp && (*cp != '=') && (*cp != ' ') && (*cp != '\t') )
+        cp++;
+
+    // Only SPACE or TAB separator is accepted.
+    // Reject everything else.
+
+    if (*cp == '=')
+        return 0;
+
+    // Overwrite the separator, and move the pointer past
+    // the kernel name.
+
+    if (*cp != '\0') *cp++ = '\0';
+    *cpp = cp;
+
+    return kn;
+}
+
+//==========================================================================
+
+void getBootOptions()
+{
+    int     i;
+    int     key;
+    int     selectIndex = 0;
+    int     bvCount;
+    int     nextRow;
+    BVRef   bvr;
+    BVRef   bvChain;
+    BVRef   menuBVR;
+    BOOL    showPrompt, newShowPrompt;
+    MenuItem *  menuItems = NULL;
+    static BOOL firstRun  = YES;
+
+    clearBootArgs();
+    clearScreenRows( kMenuTopRow, kScreenLastRow );
+    changeCursor( 0, kMenuTopRow, kCursorTypeUnderline, 0 );
+    printf("Scanning device %x...", gBIOSDev);
+
+    // Get a list of bootable volumes on the device.
+
+    bvChain = scanBootVolumes( gBIOSDev, &bvCount );
+    gBootVolume = menuBVR = selectBootVolume( bvChain );
+
+#if 0
+    // When booting from CD (via HD emulation), default to hard
+    // drive boot when possible. 
+
+    if ( gBootVolume->part_type == FDISK_BOOTER &&
+         gBootVolume->biosdev   == 0x80 )
+    {
+        // Scan the original device 0x80 that has been displaced
+        // by the CD-ROM.
+
+        BVRef hd_bvr = selectBootVolume(scanBootVolumes(0x81, 0));
+        if ( hd_bvr->flags & kBVFlagNativeBoot )
+        {
+            int key = countdown("Press C to start up from CD-ROM.",
+                                kMenuTopRow, 5);
+            
+            if ( (key & 0x5f) != 'c' )
+            {
+                gBootVolume = hd_bvr;
+                gBIOSDev = hd_bvr->biosdev;
+                initKernBootStruct( gBIOSDev );
+                goto done;
+            }
+        }
+    }
+#endif
+
+    // Allow user to override default setting.
+
+    if ( firstRun &&
+         countdown("Press any key to enter startup options.",
+                   kMenuTopRow, 3) == 0 )
+    {
+        goto done;
+    }
+
+    if ( bvCount )
+    {
+        // Allocate memory for an array of menu items.
+
+        menuItems = (MenuItem *) malloc( sizeof(MenuItem) * bvCount );
+        if ( menuItems == NULL ) goto done;
+
+        // Associate a menu item for each BVRef.
+
+        for ( bvr = bvChain, i = bvCount - 1, selectIndex = 0;
+              bvr; bvr = bvr->next, i-- )
+        {
+            getBootVolumeDescription( bvr, menuItems[i].name, 80 );
+            menuItems[i].param = (void *) bvr;
+            if ( bvr == menuBVR ) selectIndex = i;
+        }
+    }
+
+    // Clear screen and hide the blinking cursor.
+
+    clearScreenRows( kMenuTopRow, kMenuTopRow + 2 );
+    changeCursor( 0, kMenuTopRow, kCursorTypeHidden, 0 );
+    nextRow = kMenuTopRow;
+    showPrompt = YES;
+
+    // Show the menu.
+
+    if ( bvCount )
+    {
+        printf("Use \30\31 keys to select the startup volume.");
+        showMenu( menuItems, bvCount, selectIndex, kMenuTopRow + 2, kMenuMaxItems );
+        nextRow += min( bvCount, kMenuMaxItems ) + 3;
+    }
+
+    // Show the boot prompt.
+
+    showPrompt = (bvCount == 0) || (menuBVR->flags & kBVFlagNativeBoot);
+    showBootPrompt( nextRow, showPrompt );
+
+    do {
+        key = getc();
+
+        updateMenu( key, (void **) &menuBVR );
+
+        newShowPrompt = (bvCount == 0) ||
+                        (menuBVR->flags & kBVFlagNativeBoot);
+
+        if ( newShowPrompt != showPrompt )
+        {
+            showPrompt = newShowPrompt;
+            showBootPrompt( nextRow, showPrompt );
+        }
+        if ( showPrompt ) updateBootArgs( key );
+
+        switch ( key & kASCIIKeyMask )
+        {
+            case kReturnKey:
+                if ( *gBootArgs == '?' )
+                {
+                    showHelp(); key = 0;
+                    showBootPrompt( nextRow, showPrompt );
+                    break;
+                }
+                gBootVolume = menuBVR;
+                break;
+
+            case kEscapeKey:
+                clearBootArgs();
+                break;
+
+            default:
+                key = 0;
+        }
+    }
+    while ( 0 == key );
+
+done:
+    firstRun = NO;
+
+    clearScreenRows( kMenuTopRow, kScreenLastRow );
+    changeCursor( 0, kMenuTopRow, kCursorTypeUnderline, 0 );
+
+    if ( menuItems ) free(menuItems);
+}
+
+//==========================================================================
+
+extern unsigned char chainbootdev;
+extern unsigned char chainbootflag;
+
+int processBootOptions()
+{
+    KERNBOOTSTRUCT * kbp = kernBootStruct;
+    const char *     cp  = gBootArgs;
+    const char *     val = 0;
+    const char *     kernel;
+    int              cnt;
+
+    skipblanks( &cp );
+
+    // Update the unit and partition number.
+
+    if ( gBootVolume )
+    {
+        if ( gBootVolume->flags & kBVFlagForeignBoot )
+        {
+            readBootSector( gBootVolume->biosdev, gBootVolume->part_boff,
+                            (void *) 0x7c00 );
+
+            //
+            // Setup edx, and signal intention to chain load the
+            // foreign booter.
+            //
+
+            chainbootdev  = gBootVolume->biosdev;
+            chainbootflag = 1;
+
+            return 1;
+        }
+
+        kbp->kernDev &= ~((B_UNITMASK << B_UNITSHIFT ) |
+                          (B_PARTITIONMASK << B_PARTITIONSHIFT));
+
+        kbp->kernDev |= MAKEKERNDEV(    0,
+                        /* unit */      BIOS_DEV_UNIT(gBootVolume->biosdev),
+                        /* partition */ gBootVolume->part_no );
+    }
+
+    // Load config table specified by the user, or use the default.
+
+    getValueForBootKey( cp, "config", &val, &cnt );
+    loadSystemConfig(val, cnt);
+    if ( !sysConfigValid ) return -1;
+
+    // Use the kernel name specified by the user, or fetch the name
+    // in the config table.
+
+    if (( kernel = extractKernelName((char **)&cp) ))
+    {
+        strcpy( kbp->bootFile, kernel );
+    }
+    else
+    {
+        if ( getValueForKey( kKernelNameKey, &val, &cnt ) )
+            strncpy( kbp->bootFile, val, cnt );
+    }
+
+    // Store the merged kernel flags and boot args.
+
+    getValueForKey( kKernelFlagsKey, &val, &cnt );
+    if ( (strlen(cp) + 1 + cnt) < BOOT_STRING_LEN )
+    {
+        if (cnt) strncpy(kbp->bootString, val, cnt);
+        sprintf(&kbp->bootString[cnt], "%s%s", cnt ? " " : "", cp);
+    }
+
+    gVerboseMode = getValueForKey( "-v", &val, &cnt ) ||
+                   getValueForKey( "-s", &val, &cnt );
+
+    gBootGraphics = getBoolForKey( kBootGraphicsKey );
+
+    gBootMode = ( getValueForKey( "-f", &val, &cnt ) ) ?
+                kBootModeSafe : kBootModeNormal;
+
+    return 0;
+}
+
+//==========================================================================
+// Load the help file and display the file contents on the screen.
+
+static void showHelp()
+{
+#define BOOT_HELP_PATH  "/usr/standalone/i386/BootHelp.txt"
+
+    int  fd;
+
+    if ( (fd = open(BOOT_HELP_PATH, 0)) >= 0 )
+    {
+        char * buffer;
+
+        // Activate and clear page 1
+        // Perhaps this should be loaded only once?
+
+        setActiveDisplayPage(1);
+        clearScreenRows(0, 24);
+        setCursorPosition( 0, 0, 1 );
+        
+        buffer = malloc( file_size(fd) );
+        read(fd, buffer, file_size(fd) - 1);
+        close(fd);
+        printf("%s", buffer);
+        free(buffer);
+        
+        // Wait for a keystroke and return to page 0.
+
+        getc();
+        setActiveDisplayPage(0);
+    }
+}
index 4c3eb03c3baba7bc34349c38d7a897571bc0b649..cf2ea4d16688f77ebe2a3f39de042a81646b8d6c 100644 (file)
 
 #include "vers.h"
 
-char bootPrompt[] = "\n\nDarwin/x86 boot v" I386BOOT_VERSION "\n"
-                    "%dK conventional / %dK extended memory\n\n"
-                    "Darwin/x86 will start up in %d seconds, or you can:\n"
-                    "  Type -v and press Return to start up Darwin/x86 with "
-                    "diagnostic messages\n"
-                    "  Type ? and press Return to learn about advanced startup "
-                    "options\n"
-                    "  Type any other character to stop Darwin/x86 from "
-                    "starting up automatically\n";
+char bootBanner[] = "\nDarwin/x86 boot v" I386BOOT_VERSION "\n"
+                    "%dK conventional / %dK extended memory\n";
+
+char bootPrompt[] =
+    "Press Return to start up Darwin/x86 with no options, or you can:\n"
+    "  Type -v and press Return to start up with diagnostic messages\n"
+    "  Type ? and press Return to learn about advanced startup options\n\n"
+    "boot: ";
index fbf2c0f45587cfd18b1357cc6223e708c83893bb..0f65de17619918ea2b507f22dbca385a80d68c8e 100644 (file)
@@ -7,8 +7,8 @@ INSTALL_SA_DIR = $(DSTROOT)/System/Library/Frameworks/System.framework/Versions/
 INSTALL_MD_DIR = $(DSTROOT)/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders/machdep/i386
 
 OPTIM = -Os
-CFLAGS = $(RC_CFLAGS) $(OPTIM) $(MORECPP) -arch i386 -g -Wmost -Wno-precomp \
-       -munaligned-text -static -traditional-cpp
+CFLAGS = $(RC_CFLAGS) $(OPTIM) $(MORECPP) -arch i386 -g -Wmost -Werror \
+             -fno-builtin -static
 
 INC = -I. -I$(SYMROOT) -I$(UTILDIR)
 ifneq "" "$(wildcard /bin/mkdirs)"
@@ -25,12 +25,12 @@ VPATH = $(OBJROOT):$(SYMROOT)
 
 SA_OBJS = prf.o printf.o zalloc.o \
        string.o strtol.o error.o \
-       setjmp.o qsort.o bswap.o
+       setjmp.o qsort.o
 
 SFILES = setjmp.s
 CFILES = prf.c printf.c zalloc.c \
        string.c strtol.c error.c \
-       qsort.c bswap.c
+       qsort.c
 HFILES = memory.h
 EXPORTED_HFILES = libsa.h kernBootStruct.h memory.h
 INSTALLED_SA_HFILES = libsa.h
diff --git a/i386/libsa/bswap.c b/i386/libsa/bswap.c
deleted file mode 100644 (file)
index 48baf4b..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License").  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include "libsa.h"
-
-unsigned long bswap32( unsigned long data )
-{
-    __asm__ volatile("bswap %0"
-                     : "=r" (data)
-                     : "0"  (data));
-    return data;
-}
index a88097dee266b0654f80445afabdef606abf3172..f162c846f449cce903d0f608744b0a98ccc6a093 100644 (file)
  * string.c
  */
 #ifndef bcopy
-extern void   bcopy(const void * src, void * dst, int len);
+extern void   bcopy(const void * src, void * dst, size_t len);
 #endif
 
 #ifndef bzero
-extern void   bzero(void * dst, int len);
+extern void   bzero(void * dst, size_t len);
 #endif
 
 extern void * memset(void * dst, int c, size_t n);
@@ -49,7 +49,8 @@ extern int    strncmp(const char * s1, const char * s2, size_t n);
 extern char * strcpy(char * s1, const char * s2);
 extern char * strncpy(char * s1, const char * s2, size_t n);
 extern int    atoi(const char * str);
-extern int    ptol(char * str);
+extern int    ptol(const char * str);
+extern int    strlen(const char * str);
 extern char * strcat(char * s1, const char * s2);
 extern char * strncat(char * s1, const char * s2, size_t n);
 
@@ -66,30 +67,20 @@ extern char * strerror(int errnum);
 /*
  * strtol.c
  */
-extern long strtol(const char * nptr,
-                   char **      endptr,
-                   int          base);
-
-extern unsigned long strtoul(const char * nptr,
-                             char **      endptr,
-                             int          base);
+extern long strtol(const char * nptr, char ** endptr, int base);
+extern unsigned long strtoul(const char * nptr, char ** endptr, int base);
 
 /*
  * prf.c
  */
-extern void prf(const char * fmt,
-                va_list      ap,
-                void         (*putfn_p)(),
-                void *       putfn_arg);
+extern void prf(const char * fmt, va_list ap, void (*putfn_p)(),
+                void * putfn_arg);
 
 /*
  * printf.c
  */
 extern int sprintf(char *s, const char * format, ...);
-extern int slvprintf(char *       buffer,
-                     int          len,
-                     const char * fmt,
-                     va_list      arg);
+extern int slvprintf(char * buffer, int len, const char * fmt, va_list arg);
 
 /*
  * zalloc.c
@@ -103,11 +94,6 @@ extern void * realloc(void * ptr, size_t size);
  * getsegbyname.c
  */
 extern struct segment_command *
-       getsegbynamefromheader(struct mach_header * mhp, char * segname);
-
-/*
- * bswap.c
- */
-extern unsigned long bswap32( unsigned long data );
+       getsegbynamefromheader(struct mach_header * mhp, char * segname);
 
 #endif /* !__BOOT_LIBSA_H */
index ee658946d8fb16da2dbba6f309868b33259292c4..7eed3eacef09319baa4e9427325e726c27cd25c6 100644 (file)
 
 /* Memory addresses used by booter and friends */
 
+#define BASE_SEG          0x2000
+#define STACK_SEG         0x3000
+#define STACK_OFS         0xFFF0      // stack pointer
+
+#define BOOT2_SEG         BASE_SEG
+#define BOOT2_OFS         0x0200      // 512 byte disk sector offset
+
+#define BIOS_ADDR         0x0C00      // BIOS disk I/O buffer
+#define BIOS_LEN          0x2400      // 9K
+
 /* These are all "virtual" addresses...
  * which are physical addresses plus MEMBASE.
  */
-#define MEMBASE             0x0
-#define BASE_SEG            0x0
-
-#define BIOS_ADDR           0x000C00    // BIOS buffer
-#define BIOS_LEN            0x002400    // 9k
-#define BOOTER_LOAD_ADDR    0x003000    // loaded here for compat.
-#define BOOTER_ADDR         0x003000    // start of booter code
-#define BOOTER_LEN          0x00B000
-#define STACK_ADDR          0x00FFF0
-#define BOOTSTRUCT_ADDR     0x011000    // it's slightly smaller
-#define BOOTSTRUCT_LEN      0x00F000
-#define RLD_ADDR            0x030000    // not used
-#define RLD_LEN             0x070000
-#define VIDEO_ADDR          0x0A0000    // unusable space
-#define VIDEO_LEN           0x060000
-#define KERNEL_ADDR         0x100000    // 14Mb kernel + drivers
-#define KERNEL_LEN          0xe00000
-#define ZALLOC_ADDR         0xf00000    // 1Mb for zalloc
-#define ZALLOC_LEN          0x100000
-#define TFTP_ADDR           0x1000000   // 8Mb download buffer
-#define TFTP_LEN            0x800000
-
-/* These are physical values */
-
-#define CONVENTIONAL_LEN    0x0A0000      // 640k
-#define EXTENDED_ADDR       0x100000      // 1024k
-#define KERNEL_BOOT_ADDR    KERNEL_ADDR   // load at 1Mb
-
-#define ptov(paddr) ((paddr) - MEMBASE)
-#define vtop(vaddr) ((vaddr) + MEMBASE)
+#define ADDR32(seg, ofs)  (((seg) << 4 ) + (ofs))
+
+#define MEMBASE           0x0
+
+#define BOOTSTRUCT_ADDR   0x011000    // it's slightly smaller
+#define BOOTSTRUCT_LEN    0x00F000
+
+#define BASE_ADDR         ADDR32(BASE_SEG, 0)
+#define BOOT2_ADDR        ADDR32(BOOT2_SEG, BOOT2_OFS)
+
+#define VIDEO_ADDR        0x0A0000    // unusable space
+#define VIDEO_LEN         0x060000
+
+#define KERNEL_ADDR       0x100000    // 15M kernel + drivers
+#define KERNEL_LEN        0xF00000
+
+#define ZALLOC_ADDR       0x1000000   // 4M zalloc area
+#define ZALLOC_LEN        0x400000
+
+#define LOAD_ADDR         0x01400000  // File download buffer
+#define LOAD_LEN          0x800000    // Max file size
+
+#define TFTP_ADDR         LOAD_ADDR   // tftp download buffer
+#define TFTP_LEN          LOAD_LEN
+
+#define kLoadAddr         LOAD_ADDR
+#define kLoadSize         LOAD_LEN
+
+#define CONVENTIONAL_LEN  0x0A0000    // 640k
+#define EXTENDED_ADDR     0x100000    // 1024k
+
+#define ptov(paddr)       ((paddr) - MEMBASE)
+#define vtop(vaddr)       ((vaddr) + MEMBASE)
+
+/*
+ * Extract segment/offset from a linear address.
+ */
+#define OFFSET16(addr)    ((addr) - BASE_ADDR)
+#define OFFSET(addr)      ((addr) & 0xFFFF)
+#define SEGMENT(addr)     (((addr) & 0xF0000) >> 4)
+
+/*
+ * We need a minimum of 32MB of system memory.
+ */
+#define MIN_SYS_MEM_KB  (32 * 1024)
 
 /*
- * Limits to the size of various things...
+ * The number of descriptor entries in the GDT.
  */
+#define NGDTENT   7
 
 /*
- * We need a minimum of 24Mb of system memory.
+ * The total size of the GDT in bytes.
+ * Each descriptor entry require 8 bytes.
  */
-#define MIN_SYS_MEM_KB  (24 * 1024)
+#define GDTLIMIT  ( NGDTENT * 8 )
 
 #endif /* !__BOOT_MEMORY_H */
index b423aca462d2dfc5d957d3ecf0f57f8ce22c8a5e..2d76e4e8de184529197d4b3011dd0163370f92fa 100644 (file)
@@ -45,12 +45,12 @@ void * memcpy(void * dst, const void * src, size_t len)
     return dst;
 }
 
-void bcopy(const void * src, void * dst, int len)
+void bcopy(const void * src, void * dst, size_t len)
 {
        memcpy(dst, src, len);
 }
 
-void bzero(void * dst, int len)
+void bzero(void * dst, size_t len)
 {
     memset(dst, 0, len);
 }
@@ -108,7 +108,7 @@ strncpy(char * s1, const char * s2, size_t n)
 }
 
 int
-ptol(char *str)
+ptol(const char *str)
 {
        register int c = *str;
 
index 550acbff77db0838f48f04bfb8f58b9d8bdf5cab..079c6a0c5a355874e2952587ff103ca9a7df742e 100644 (file)
@@ -8,9 +8,9 @@ INSTALLDIR = $(DSTROOT)/System/Library/Frameworks/System.framework/Versions/B/Pr
 SYMROOT=
 
 OPTIM = -Os
-CFLAGS = $(RC_CFLAGS) $(OPTIM) $(MORECPP) -arch i386 -g -Wmost -Wno-precomp \
-    -D__ARCHITECTURE__=\"i386\" -DSAIO_INTERNAL_USER -munaligned-text -static \
-       -traditional-cpp -DRCZ_COMPRESSED_FILE_SUPPORT
+CFLAGS = $(RC_CFLAGS) $(OPTIM) $(MORECPP) -arch i386 -g -Wmost -Werror \
+    -D__ARCHITECTURE__=\"i386\" -DSAIO_INTERNAL_USER -fno-builtin -static \
+        -DRCZ_COMPRESSED_FILE_SUPPORT
 DEFINES=
 CONFIG = hd
 INC = -I../rcz -I. -I$(SYMROOT) -I$(UTILDIR) -I$(LIBSADIR) -I/System/Library/Frameworks/System.framework/PrivateHeaders
@@ -26,11 +26,11 @@ LIBS=
 
 VPATH = $(OBJROOT):$(SYMROOT)
 
-SAIO_OBJS = table.o asm.o biosfn.o misc.o gets.o \
-       vga.o disk.o sys.o cache.o \
-       ufs_byteorder.o bootstruct.o \
-       stringTable.o load.o \
-       bios.o pci.o vbe.o nbp.o
+SAIO_OBJS = table.o asm.o bios.o biosfn.o \
+       disk.o sys.o cache.o bootstruct.o \
+       ufs.o ufs_byteorder.o \
+       stringTable.o load.o misc.o \
+       vbe.o nbp.o hfs.o hfs_compare.o
 
 SAIO_EXTERN_OBJS = console.o
 
diff --git a/i386/libsaio/appleClut8.h b/i386/libsaio/appleClut8.h
deleted file mode 100644 (file)
index e608d18..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License").  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#ifndef __LIBSAIO_APPLECLUT8_H
-#define __LIBSAIO_APPLECLUT8_H
-
-static const unsigned char appleClut8[ 256 * 3 ] = {
-
-       0x00,0x00,0x00, 0xFF,0xFF,0xCC, 0xFF,0xFF,0x99, 0xFF,0xFF,0x66,
-       0xFF,0xFF,0x33, 0xFF,0xFF,0x00, 0xFF,0xCC,0xFF, 0xFF,0xCC,0xCC,
-       0xFF,0xCC,0x99, 0xFF,0xCC,0x66, 0xFF,0xCC,0x33, 0xFF,0xCC,0x00,
-       0xFF,0x99,0xFF, 0xFF,0x99,0xCC, 0xFF,0x99,0x99, 0xFF,0x99,0x66,
-       0xFF,0x99,0x33, 0xFF,0x99,0x00, 0xFF,0x66,0xFF, 0xFF,0x66,0xCC,
-       0xFF,0x66,0x99, 0xFF,0x66,0x66, 0xFF,0x66,0x33, 0xFF,0x66,0x00,
-       0xFF,0x33,0xFF, 0xFF,0x33,0xCC, 0xFF,0x33,0x99, 0xFF,0x33,0x66,
-       0xFF,0x33,0x33, 0xFF,0x33,0x00, 0xFF,0x00,0xFF, 0xFF,0x00,0xCC,
-       0xFF,0x00,0x99, 0xFF,0x00,0x66, 0xFF,0x00,0x33, 0xFF,0x00,0x00,
-       0xCC,0xFF,0xFF, 0xCC,0xFF,0xCC, 0xCC,0xFF,0x99, 0xCC,0xFF,0x66,
-       0xCC,0xFF,0x33, 0xCC,0xFF,0x00, 0xCC,0xCC,0xFF, 0xCC,0xCC,0xCC,
-       0xCC,0xCC,0x99, 0xCC,0xCC,0x66, 0xCC,0xCC,0x33, 0xCC,0xCC,0x00,
-       0xCC,0x99,0xFF, 0xCC,0x99,0xCC, 0xCC,0x99,0x99, 0xCC,0x99,0x66,
-       0xCC,0x99,0x33, 0xCC,0x99,0x00, 0xCC,0x66,0xFF, 0xCC,0x66,0xCC,
-       0xCC,0x66,0x99, 0xCC,0x66,0x66, 0xCC,0x66,0x33, 0xCC,0x66,0x00,
-       0xCC,0x33,0xFF, 0xCC,0x33,0xCC, 0xCC,0x33,0x99, 0xCC,0x33,0x66,
-
-
-       0xCC,0x33,0x33, 0xCC,0x33,0x00, 0xCC,0x00,0xFF, 0xCC,0x00,0xCC,
-       0xCC,0x00,0x99, 0xCC,0x00,0x66, 0xCC,0x00,0x33, 0xCC,0x00,0x00,
-       0x99,0xFF,0xFF, 0x99,0xFF,0xCC, 0x99,0xFF,0x99, 0x99,0xFF,0x66,
-       0x99,0xFF,0x33, 0x99,0xFF,0x00, 0x99,0xCC,0xFF, 0x99,0xCC,0xCC,
-       0x99,0xCC,0x99, 0x99,0xCC,0x66, 0x99,0xCC,0x33, 0x99,0xCC,0x00,
-       0x99,0x99,0xFF, 0x99,0x99,0xCC, 0x99,0x99,0x99, 0x99,0x99,0x66,
-       0x99,0x99,0x33, 0x99,0x99,0x00, 0x99,0x66,0xFF, 0x99,0x66,0xCC,
-       0x99,0x66,0x99, 0x99,0x66,0x66, 0x99,0x66,0x33, 0x99,0x66,0x00,
-       0x99,0x33,0xFF, 0x99,0x33,0xCC, 0x99,0x33,0x99, 0x99,0x33,0x66,
-       0x99,0x33,0x33, 0x99,0x33,0x00, 0x99,0x00,0xFF, 0x99,0x00,0xCC,
-       0x99,0x00,0x99, 0x99,0x00,0x66, 0x99,0x00,0x33, 0x99,0x00,0x00,
-       0x66,0xFF,0xFF, 0x66,0xFF,0xCC, 0x66,0xFF,0x99, 0x66,0xFF,0x66,
-       0x66,0xFF,0x33, 0x66,0xFF,0x00, 0x66,0xCC,0xFF, 0x66,0xCC,0xCC,
-       0x66,0xCC,0x99, 0x66,0xCC,0x66, 0x66,0xCC,0x33, 0x66,0xCC,0x00,
-       0x66,0x99,0xFF, 0x66,0x99,0xCC, 0x66,0x99,0x99, 0x66,0x99,0x66,
-       0x66,0x99,0x33, 0x66,0x99,0x00, 0x66,0x66,0xFF, 0x66,0x66,0xCC,
-       0x66,0x66,0x99, 0x66,0x66,0x66, 0x66,0x66,0x33, 0x66,0x66,0x00,
-
-
-       0x66,0x33,0xFF, 0x66,0x33,0xCC, 0x66,0x33,0x99, 0x66,0x33,0x66,
-       0x66,0x33,0x33, 0x66,0x33,0x00, 0x66,0x00,0xFF, 0x66,0x00,0xCC,
-       0x66,0x00,0x99, 0x66,0x00,0x66, 0x66,0x00,0x33, 0x66,0x00,0x00,
-       0x33,0xFF,0xFF, 0x33,0xFF,0xCC, 0x33,0xFF,0x99, 0x33,0xFF,0x66,
-       0x33,0xFF,0x33, 0x33,0xFF,0x00, 0x33,0xCC,0xFF, 0x33,0xCC,0xCC,
-       0x33,0xCC,0x99, 0x33,0xCC,0x66, 0x33,0xCC,0x33, 0x33,0xCC,0x00,
-       0x33,0x99,0xFF, 0x33,0x99,0xCC, 0x33,0x99,0x99, 0x33,0x99,0x66,
-       0x33,0x99,0x33, 0x33,0x99,0x00, 0x33,0x66,0xFF, 0x33,0x66,0xCC,
-       0x33,0x66,0x99, 0x33,0x66,0x66, 0x33,0x66,0x33, 0x33,0x66,0x00,
-       0x33,0x33,0xFF, 0x33,0x33,0xCC, 0x33,0x33,0x99, 0x33,0x33,0x66,
-       0x33,0x33,0x33, 0x33,0x33,0x00, 0x33,0x00,0xFF, 0x33,0x00,0xCC,
-       0x33,0x00,0x99, 0x33,0x00,0x66, 0x33,0x00,0x33, 0x33,0x00,0x00,
-       0x00,0xFF,0xFF, 0x00,0xFF,0xCC, 0x00,0xFF,0x99, 0x00,0xFF,0x66,
-       0x00,0xFF,0x33, 0x00,0xFF,0x00, 0x00,0xCC,0xFF, 0x00,0xCC,0xCC,
-       0x00,0xCC,0x99, 0x00,0xCC,0x66, 0x00,0xCC,0x33, 0x00,0xCC,0x00,
-       0x00,0x99,0xFF, 0x00,0x99,0xCC, 0x00,0x99,0x99, 0x00,0x99,0x66,
-
-
-       0x00,0x99,0x33, 0x00,0x99,0x00, 0x00,0x66,0xFF, 0x00,0x66,0xCC,
-       0x00,0x66,0x99, 0x00,0x66,0x66, 0x00,0x66,0x33, 0x00,0x66,0x00,
-       0x00,0x33,0xFF, 0x00,0x33,0xCC, 0x00,0x33,0x99, 0x00,0x33,0x66,
-       0x00,0x33,0x33, 0x00,0x33,0x00, 0x00,0x00,0xFF, 0x00,0x00,0xCC,
-       0x00,0x00,0x99, 0x00,0x00,0x66, 0x00,0x00,0x33, 0xEE,0x00,0x00,
-       0xDD,0x00,0x00, 0xBB,0x00,0x00, 0xAA,0x00,0x00, 0x88,0x00,0x00,
-       0x77,0x00,0x00, 0x55,0x00,0x00, 0x44,0x00,0x00, 0x22,0x00,0x00,
-       0x11,0x00,0x00, 0x00,0xEE,0x00, 0x00,0xDD,0x00, 0x00,0xBB,0x00,
-       0x00,0xAA,0x00, 0x00,0x88,0x00, 0x00,0x77,0x00, 0x00,0x55,0x00,
-       0x00,0x44,0x00, 0x00,0x22,0x00, 0x00,0x11,0x00, 0x00,0x00,0xEE,
-       0x00,0x00,0xDD, 0x00,0x00,0xBB, 0x00,0x00,0xAA, 0x00,0x00,0x88,
-       0x00,0x00,0x77, 0x00,0x00,0x55, 0x00,0x00,0x44, 0x00,0x00,0x22,
-       0x00,0x00,0x11, 0xEE,0xEE,0xEE, 0xDD,0xDD,0xDD, 0xBB,0xBB,0xBB,
-       0xAA,0xAA,0xAA, 0x88,0x88,0x88, 0x77,0x77,0x77, 0x55,0x55,0x55,
-       0x44,0x44,0x44, 0x22,0x22,0x22, 0x11,0x11,0x11, 0xFF,0xFF,0xFF
-};
-
-#endif /* !__LIBSAIO_APPLECLUT8_H */
index ede3dfaa6b440ade58c0433714b2dd12dd082bcd..2b27ffd480e24131009e7fdaa6566fd6e0dfa7cf 100644 (file)
 /*
  * HISTORY
  * $Log: asm.s,v $
+ * Revision 1.3  2002/07/09 14:06:21  jliu
+ * Merging changes from PR-2954224 branch in boot/i386.
+ *
+ * Revision 1.2.30.1  2002/07/05 16:24:51  jliu
+ * Merged UFS/HFS/HFS+ filesystem support from BootX.
+ * Moved boot2 load address due to increased size. boot0/boot1 also changed.
+ * Updated boot graphics and CLUT.
+ * Added support to chain load foreign booters.
+ * Fixed param passing bug in network loader.
+ * Misc cleanup in libsaio.
+ *
  * Revision 1.2  2000/05/23 23:01:11  lindak
  * Merged PR-2309530 into Kodiak (liu i386 booter: does not support label-less
  * ufs partitions)
  * Import of boot-25 (~mwatson)
  *
  * Revision 2.1.1.2  90//03//22  17:59:50  rvb
- *     Added _sp() => where is the stack at. [kupfer]
+ *  Added _sp() => where is the stack at. [kupfer]
  * 
  * Revision 2.1.1.1  90//02//09  17:25:04  rvb
- *     Add Intel copyright
- *     [90//02//09            rvb]
+ *  Add Intel copyright
+ *  [90//02//09            rvb]
  * 
  */
 
 
     .file "asm.s"
 
-BOOTSEG     =   BASE_SEG
+CR0_PE_ON  = 0x1
+CR0_PE_OFF = 0x7ffffffe
 
-CR0_PE_ON   =   0x1
-CR0_PE_OFF  =   0xfffffffe
+STACK32_BASE = ADDR32(STACK_SEG, 0)
+STACK16_SEG  = STACK_SEG
+CODE32_BASE  = ADDR32(BASE_SEG, 0)
+CODE16_SEG   = BASE_SEG
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// Pointer to 6-bytes in memory that contains the base address and the limit
+// (size of GDT table in bytes) of the GDT. The LGDT is the only instruction
+// that directly loads a linear address (not a segment relative address) and
+// a limit in protected mode.
 
 .globl _Gdtr
     .data
-    .align 2,0x90
+    .align 2, 0x90
 _Gdtr:
-    .word 0x2F
-//  .long _Gdt+4096
+    .word GDTLIMIT
     .long vtop(_Gdt)
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 // Data area for __switch_stack.
 //
-save_sp: .long  STACK_ADDR
-save_ss: .long  0
-
+save_sp: .long  STACK_OFS
+save_ss: .long  STACK_SEG
 
     .text
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 // real_to_prot()
-//  transfer from real mode to protected mode.
-//  preserves all registers except eax
+//
+// Transfer from real mode to protected mode.
+// Preserves all registers except EAX.
 //
 LABEL(__real_to_prot)
-    // guarantee that interrupt is disabled when in prot mode
+
+    // Interrupts are disabled in protected mode.
+
     cli
 
-    addr32                    // load the gdtr
+    // Load the Global Descriptor Table Register (GDTR).
+
+    addr32
     data32
-    lgdt    _Gdtr
+    lgdt    OFFSET16(_Gdtr)
 
-    // set the PE bit of CR0 to go to protected mode
+    // Enter protected mode by setting the PE bit in CR0.
 
     mov     %cr0, %eax
     data32
     or      $CR0_PE_ON, %eax
-    mov     %eax, %cr0 
+    mov     %eax, %cr0
 
-    // make intrasegment jump to flush the processor pipeline and
-    // reload CS register
+    // Make intrasegment jump to flush the processor pipeline and
+    // reload CS register.
 
     data32
     ljmp    $0x08, $xprot
 
 xprot:
     // we are in USE32 mode now
-    // set up the protected mode segment registers : DS, SS, ES
+    // set up the protected mode segment registers : DS, SS, ES, FS, GS
 
     mov     $0x10, %eax
     movw    %ax, %ds
     movw    %ax, %ss
     movw    %ax, %es
+    movw    %ax, %fs
+    movw    %ax, %gs
+
+    // Convert STACK_SEG:SP to 32-bit linear stack pointer.
 
-    xorl    %eax, %eax        // clear garbage from upper word of esp
-    movw    %sp, %ax
+    movzwl  %sp, %eax
+    addl    $STACK32_BASE, %eax
     movl    %eax, %esp
 
+    // Convert STACK_SEG:BP to 32-bit linear base pointer.
+
+    movzwl  %bp, %eax
+    addl    $STACK32_BASE, %eax
+    movl    %eax, %ebp
+
+    // Modify the caller's return address on the stack from
+    // segment offset to linear address.
+
+    popl    %eax
+    addl    $CODE32_BASE, %eax
+    pushl   %eax
+
     ret
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 // prot_to_real()
-//  transfer from protected mode to real mode
-//  preserves all registers except eax
+//
+// Transfer from protected mode to real mode.
+// Preserves all registers except EAX.
 // 
 LABEL(__prot_to_real)
 
+    // Set up segment registers appropriate for real mode.
+
+    movw    $0x30, %ax
+    movw    %ax, %ds
+    movw    %ax, %es
+    movw    %ax, %fs
+    movw    %ax, %gs
+    movw    %ax, %ss
+
     ljmp    $0x18, $x16       // change to USE16 mode
 
 x16:
@@ -168,74 +218,65 @@ x16:
     // and reload CS register
 
     data32
-    ljmp    $BOOTSEG, $xreal
+    ljmp    $CODE16_SEG, $xreal - CODE32_BASE
 
 xreal:
     // we are in real mode now
-    // set up the real mode segment registers : DS, SS, ES
+    // set up the real mode segment registers : DS, DS, ES, FS, GS
 
     movw    %cs, %ax
     movw    %ax, %ds
-    movw    %ax, %ss
     movw    %ax, %es
+    movw    %ax, %fs
+    movw    %ax, %gs
+
+    // load stack segment register SS.
 
     data32
-    ret
+    movl    $STACK16_SEG, %eax
+    movw    %ax, %ss
 
-#if defined(DEFINE_INLINE_FUNCTIONS)
+    // clear top 16-bits of ESP and EBP.
 
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-// outb(port, byte)
-//
-LABEL(_outb)
-    push    %ebp
-    mov     %esp, %ebp
-    push    %edx
+    data32
+    movzwl  %sp, %esp
+    data32
+    movzwl  %bp, %ebp
 
-    movw    8(%ebp), %dx
-    movb    12(%ebp), %al
-    outb    %al, %dx
+    // Modify caller's return address on the stack
+    // from linear address to segment offset.
 
-    pop     %edx
-    pop     %ebp
-    ret
+    data32
+    popl    %eax
+    data32
+    movzwl  %ax, %eax
+    data32
+    pushl   %eax
 
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-// inb(port)
-//
-LABEL(_inb)
-    push    %ebp
-    mov     %esp, %ebp
-    push    %edx
+    // Reenable maskable interrupts.
 
-    movw    8(%ebp), %dx
-    subw    %ax, %ax
-    inb     %dx, %al
+    sti
 
-    pop     %edx
-    pop     %ebp
+    data32
     ret
 
-#endif /* DEFINE_INLINE_FUNCTIONS */
-
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 // halt()
 //
 LABEL(_halt)
-//  call    _getchar
     hlt
     jmp     _halt
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 // startprog(phyaddr)
-// Start the program on protected mode where phyaddr is the entry point
+// Start the program on protected mode where phyaddr is the entry point.
 //
 LABEL(_startprog)
     push    %ebp
     mov     %esp, %ebp
 
-    mov     0x8(%ebp), %ecx     // entry offset 
-    mov     $0x28, %ebx     // segment
+    mov     0x8(%ebp), %ecx  // entry offset 
+    mov     $0x28, %ebx      // segment
     push    %ebx
     push    %ecx
 
@@ -255,89 +296,92 @@ LABEL(__sp)
     ret
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-// Returns the current stack pointer.
+// Returns the current frame pointer.
 //
 LABEL(__bp)
     mov %ebp, %eax
     ret
 
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-# Switch stack.
-# Switches between registers SS:SP and memory save_ss:save_sp.
-# Call this function from real mode only!!!
-#
-# AX, DI, and SI are modified.
-#
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// switch_stack()
+//
+// Switches stack pointer between SS:SP and memory save_ss:save_sp.
+// Call this function from real mode only!!!
+//
+// AX, DI, and SI are clobbered.
+//
 LABEL(__switch_stack)
-       popl    %eax                            # save return address
-       popl    %edi                            # discard upper 16-bit
-       
-       data32
-       addr32
-       movl    save_ss, %esi           # copy new SS to ESI
-
-       data32
-       addr32
-       movl    save_sp, %edi           # copy new SP to EDI
-       
-       addr32
-       mov             %ss, save_ss            # save current SS
-       
-       data32
-       addr32
-       movl    %esp, save_sp           # Save current SP
-       
-       cli
-       mov             %si, %ss                        # Perform stack switch
-       mov             %di, %sp
-       sti
-       
-       pushl   %eax                            # push IP of caller onto the new stack
-       
-       xorl    %eax, %eax
-       xorl    %esi, %esi
-       xorl    %edi, %edi
-
-       ret
-
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-# Issue a request to the network loader.
-#
+    popl    %eax                # save return address
+    popl    %edi                # discard upper 16-bit
+
+    data32
+    addr32
+    movl    OFFSET16(save_ss), %esi   # new SS to SI
+
+    data32
+    addr32
+    movl    OFFSET16(save_sp), %edi   # new SP to DI
+
+    addr32
+    mov     %ss, OFFSET16(save_ss)    # save current SS to memory
+
+    data32
+    addr32
+    movl    %esp, OFFSET16(save_sp)   # save current SP to memory
+
+    cli
+    mov     %si, %ss            # switch stack
+    mov     %di, %sp
+    sti
+
+    pushl   %eax                # push IP of caller onto the new stack
+
+    xorl    %eax, %eax
+    xorl    %esi, %esi
+    xorl    %edi, %edi
+
+    ret
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// loader()
+//
+// Issue a request to the network loader.
+//
 LABEL(_loader)
-       enter   $0, $0  
-       pushal
+    enter   $0, $0
+    pushal
+
+    #
+    # Pass a far pointer to the command structure
+    # to the INT call through DX:CX.
+    #
+    # The command code is in BX.
+    #
+
+    movw     8(%ebp), %bx       #  8[EBP] = command code
+    movw    12(%ebp), %cx       # 12[EBP] = command structure offset
+    movw    14(%ebp), %dx       # 14[EBP] = command structure segment
 
-       #
-       # Pass a far pointer to the command structure
-       # to the INT call through DI:CX.
-       #
-       # The command code is in BX.
-       #
+    call    __prot_to_real      # Revert to real mode
 
-       movw    8(%ebp), %bx            # 8[EBP]  = command code
-       movw    12(%ebp), %cx           # 12[EBP] = command structure offset
-       movw    14(%ebp), %di           # 14[EBP] = command structure segment
+    ###### Real Mode Begin ######
 
-       call    __prot_to_real          # Revert to real mode
+    data32
+    call    __switch_stack      # Switch to NBP stack
 
-       ###### Real Mode Begin ######
+    int     $0x2b               # Call NBP
 
-       data32
-       call    __switch_stack          # Switch to NBP stack
+    data32
+    call    __switch_stack      # Restore stack
 
-       int             $0x2b                           # Call NBP
+    data32
+    call    __real_to_prot      # Back to protected mode
 
-       data32
-       call    __switch_stack          # Restore stack
+    ###### Real Mode End ######
 
-       data32
-       call    __real_to_prot          # Back to protected mode        
-       
-       ###### Real Mode End ######
-       
-       popal
-       leave
-       ret
+    popal
+    leave
+    ret
 
 #if 0
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
index 3878b87ac0ef4336b81e91d7eb428cabaca0cf8a..d99bafdb5a5e5426ea135420540e65d3bcbf1d1e 100644 (file)
@@ -70,4 +70,8 @@ typedef struct {
     machineFlags_t    flags;
 } biosBuf_t;
 
+#define EBIOS_FIXED_DISK_ACCESS   0x01
+#define EBIOS_ENHANCED_DRIVE_INFO 0x04
+extern unsigned char uses_ebios[];
+
 #endif /* !__LIBSAIO_BIOS_H */
index 4be6b70a249a5e558cc98fe10d25498d4d46cae7..9654a12fba59f624fc19e512715b053ad36447f0 100644 (file)
  * Harness for calling real-mode BIOS functions.
  */
 
-#include "legacy/asm.h"
-
-#define data32 .byte 0x66
-#define addr32 .byte 0x67
-
-#define O_INT  0
-#define O_EAX  4
-#define O_EBX  8
-#define O_ECX  12
-#define O_EDX  16
-#define O_EDI  20
-#define O_ESI  24
-#define O_EBP  28
-#define O_CS   32
-#define O_DS   34
-#define O_ES   36
-#define O_FLG  38
+#include <architecture/i386/asm_help.h>
+#include "memory.h"
+
+#define data32  .byte 0x66
+#define addr32  .byte 0x67
+
+#define O_INT   0
+#define O_EAX   4
+#define O_EBX   8
+#define O_ECX   12
+#define O_EDX   16
+#define O_EDI   20
+#define O_ESI   24
+#define O_EBP   28
+#define O_CS    32
+#define O_DS    34
+#define O_ES    36
+#define O_FLG   38
 
 .data
-       .lcomm save_eax,  4,2
-       .lcomm save_edx,  4,2
-       .lcomm save_es,   2,1
-       .lcomm save_flag, 2,1
-       .lcomm new_eax,   4,2
-       .lcomm new_edx,   4,2
-       .lcomm new_es,    2,1
+    .lcomm save_eax,  4,2
+    .lcomm save_edx,  4,2
+    .lcomm save_es,   2,1
+    .lcomm save_flag, 2,1
+    .lcomm new_eax,   4,2
+    .lcomm new_edx,   4,2
+    .lcomm new_es,    2,1
 
 .text
 
  * Call real-mode BIOS INT functions.
  *
  */
-ENTRY(bios)
-       enter   $0,$0
-       pushal
-       
-       movl    8(%ebp), %edx           // address of save area
-       movb    O_INT(%edx), %al        // save int number
-       movb    %al, do_int+1
-       
-       movl    O_EBX(%edx), %ebx
-       movl    O_ECX(%edx), %ecx
-       movl    O_EDI(%edx), %edi
-       movl    O_ESI(%edx), %esi
-       movl    O_EBP(%edx), %ebp
-       movl    %edx, save_edx
-       movl    O_EAX(%edx), %eax
-       movl    %eax, new_eax
-       movl    O_EDX(%edx), %eax
-       movl    %eax, new_edx
-       movw    O_ES(%edx),  %ax
-       movl    %ax, new_es
-
-       call    EXT(_prot_to_real)
-       
-       data32
-       addr32
-       mov     new_eax, %eax
-       data32
-       addr32
-       mov     new_edx, %edx
-       data32
-       addr32
-       mov     new_es, %es
+LABEL(_bios)
+    enter   $0, $0
+    pushal
+
+    movl    8(%ebp), %edx       // address of save area
+    movb    O_INT(%edx), %al    // save int number
+    movb    %al, do_int+1
+
+    movl    O_EBX(%edx), %ebx
+    movl    O_ECX(%edx), %ecx
+    movl    O_EDI(%edx), %edi
+    movl    O_ESI(%edx), %esi
+    movl    O_EBP(%edx), %ebp
+    movl    %edx, save_edx
+    movl    O_EAX(%edx), %eax
+    movl    %eax, new_eax
+    movl    O_EDX(%edx), %eax
+    movl    %eax, new_edx
+    movw    O_ES(%edx),  %ax
+    movl    %ax, new_es
+
+    call    __prot_to_real
+
+    data32
+    addr32
+    mov     OFFSET16(new_eax), %eax
+    data32
+    addr32
+    mov     OFFSET16(new_edx), %edx
+    data32
+    addr32
+    mov     OFFSET16(new_es), %es
 
 do_int:
-       int     $0x00
-       pushf
-       data32
-       addr32
-       movl    %eax, save_eax
-       popl    %eax                        // actually pop %ax
-       addr32
-       movl    %eax, save_flag         // actually movw
-       mov     %es, %ax
-       addr32
-       movl    %eax, save_es           // actually movw
-       data32
-       call    EXT(_real_to_prot)
-       
-       movl    %edx, new_edx           // save new edx before clobbering
-       movl    save_edx, %edx
-       movl    new_edx, %eax           // now move it into buffer
-       movl    %eax, O_EDX(%edx)
-       movl    save_eax, %eax
-       movl    %eax, O_EAX(%edx)
-       movw    save_es, %ax
-       movw    %ax, O_ES(%edx)
-       movw    save_flag, %ax
-       movw    %ax, O_FLG(%edx)
-       movl    %ebx, O_EBX(%edx)
-       movl    %ecx, O_ECX(%edx)
-       movl    %edi, O_EDI(%edx)
-       movl    %esi, O_ESI(%edx)
-       movl    %ebp, O_EBP(%edx)
-       
-       popal
-       leave
-       
-       ret
-       
+    int     $0x00
+    pushf
+    data32
+    addr32
+    movl    %eax, OFFSET16(save_eax)
+    popl    %eax                         // actually pop %ax
+    addr32
+    movl    %eax, OFFSET16(save_flag)  // actually movw
+    mov     %es, %ax
+    addr32
+    movl    %eax, OFFSET16(save_es)    // actually movw
+    data32
+    call    __real_to_prot
+
+    movl    %edx, new_edx       // save new edx before clobbering
+    movl    save_edx, %edx
+    movl    new_edx, %eax       // now move it into buffer
+    movl    %eax, O_EDX(%edx)
+    movl    save_eax, %eax
+    movl    %eax, O_EAX(%edx)
+    movw    save_es, %ax
+    movw    %ax, O_ES(%edx)
+    movw    save_flag, %ax
+    movw    %ax, O_FLG(%edx)
+    movl    %ebx, O_EBX(%edx)
+    movl    %ecx, O_ECX(%edx)
+    movl    %edi, O_EDI(%edx)
+    movl    %esi, O_ESI(%edx)
+    movl    %ebp, O_EBP(%edx)
+
+    popal
+    leave
+
+    ret
+
 /*============================================================================
  * Determines the total system memory size using various BIOS Int 15 calls.
  *
  */
-ENTRY(get_memsize)
-       enter   $0, $0                          # create frame pointer (32 bit operand/stack)
-       pushal                                          # save all registers
-
-       movl    8(%ebp), %ebx           # push input structure pointer to stack
-       pushl   %ebx
-
-       call    EXT(_prot_to_real)      # switch to real mode
-
-       ##################################################################
-       # In real mode.
-       # Do not forget the opcode overrides, since the assembler
-       # does not know we have made a transition to 16-bit operation.
-       ##################################################################
-
-       data32
-       movl    $0xE801, %eax           # Get memory size
-       clc
-       int             $0x15
-       data32
-       jnc             getmsz_e801
-
-       data32
-       movl    $0xDA88, %eax           # Get memory size
-       clc
-       int             $0x15
-       data32
-       jnc             getmsz_da88
-
-       movb    $0x8A, %ah                      # Get memory size
-       clc
-       int             $0x15
-       data32
-       jnc             getmsz_8a
-
-       movb    $0x88, %ah                      # Get memory size
-       clc
-       int             $0x15
-       data32
-       jnc             getmsz_88
-
-       xorl    %edx, %edx                      # Error, cannot get memory size
-       xorl    %eax, %eax
+LABEL(_get_memsize)
+    enter   $0, $0              # create frame pointer (32 bit operand/stack)
+    pushal                      # save all registers
+
+    movl    8(%ebp), %ebx       # push input structure pointer to stack
+    pushl   %ebx
+
+    call    __prot_to_real      # switch to real mode
+
+    ##################################################################
+    # In real mode.
+    # Do not forget the opcode overrides, since the assembler
+    # does not know we have made a transition to 16-bit operation.
+    ##################################################################
+
+    data32
+    movl    $0xE801, %eax       # Get memory size
+    clc
+    int     $0x15
+    data32
+    jnc     getmsz_e801
+
+    data32
+    movl    $0xDA88, %eax       # Get memory size
+    clc
+    int     $0x15
+    data32
+    jnc     getmsz_da88
+
+    movb    $0x8A, %ah          # Get memory size
+    clc
+    int     $0x15
+    data32
+    jnc     getmsz_8a
+
+    movb    $0x88, %ah          # Get memory size
+    clc
+    int     $0x15
+    data32
+    jnc     getmsz_88
+
+    xorl    %edx, %edx          # Error, cannot get memory size
+    xorl    %eax, %eax
 
 getmsz_done:
-       data32
-       addr32
-       pushl   %eax                            # Push EAX to 32-bit stack
+    data32
+    addr32
+    pushl   %eax                # Push EAX to 32-bit stack
 
-       data32
-       call    EXT(_real_to_prot)  # Back to protected mode. EAX is modified.
+    data32
+    call    __real_to_prot      # Back to protected mode. EAX is modified.
 
-       ##################################################################
-       # Back to protected mode.
-       ##################################################################
+    ##################################################################
+    # Back to protected mode.
+    ##################################################################
 
-       popl    %eax                            # Pop EAX from stack
-       popl    %ebx                            # Pop pointer to register structure
+    popl    %eax                # Pop EAX from stack
+    popl    %ebx                # Pop pointer to register structure
 
-       # Copy the result to the input structure pointed to by a pointer
-       # which is on top of the stack. Write register EAX and EDX to the
-       # structure.
+    # Copy the result to the input structure pointed to by a pointer
+    # which is on top of the stack. Write register EAX and EDX to the
+    # structure.
 
-       movl    %eax, O_EAX(%ebx)
-       movl    %edx, O_EDX(%ebx)
+    movl    %eax, O_EAX(%ebx)
+    movl    %edx, O_EDX(%ebx)
 
-       popal                                           # restore all registers
-       leave                                           # undo enter operator
-       ret
+    popal                       # restore all registers
+    leave                       # undo enter operator
+    ret
 
 getmsz_88:
-       orl             %eax, %eax
-       data32
-       jz              getmsz_64m
-       xorl    %edx, %edx
+    orl     %eax, %eax
+    data32
+    jz      getmsz_64m
+    xorl    %edx, %edx
 
 getmsz_8a:
-       data32
-       movl    $1024, %ebx                     # Add in 1M
-       addl    %ebx, %eax
-       adcl    $0, %edx
-       data32
-       jmp             getmsz_done
+    data32
+    movl    $1024, %ebx         # Add in 1M
+    addl    %ebx, %eax
+    adcl    $0, %edx
+    data32
+    jmp     getmsz_done
 
 getmsz_64m:
-       data32
-       movl    $1, %edx
-       xorl    %eax, %eax
-       data32
-       jmp             getmsz_done
+    data32
+    movl    $1, %edx
+    xorl    %eax, %eax
+    data32
+    jmp     getmsz_done
 
 getmsz_da88:
-       xor             %dh, %dh
-       movb    %cl, %dl
-       movl    %ebx, %eax
-       data32
-       jmp             getmsz_8a
+    xor     %dh, %dh
+    movb    %cl, %dl
+    movl    %ebx, %eax
+    data32
+    jmp     getmsz_8a
 
 getmsz_e801:
-       xorl    %edx, %edx
-       orl             %ebx, %ebx
-       data32
-       jz              getmsz_88
-
-       data32
-       movl    $64, %eax
-       mul             %ebx
-
-       data32
-       movl    $16384, %ebx
-       addl    %ebx, %eax
-       adcl    $0, %edx
-
-       data32
-       jmp             getmsz_done
+    xorl    %edx, %edx
+    orl     %ebx, %ebx
+    data32
+    jz      getmsz_88
+
+    data32
+    movl    $64, %eax
+    mul     %ebx
+
+    data32
+    movl    $16384, %ebx
+    addl    %ebx, %eax
+    adcl    $0, %edx
+
+    data32
+    jmp     getmsz_done
index ff0d3a3950b55b6a611fa62c994932379cb30f35..8af9bbea36dddf6055539c696f0cd2e3160a22b5 100644 (file)
@@ -27,8 +27,6 @@
  */
 
 #include "libsaio.h"
-#include "memory.h"
-#include "kernBootStruct.h"
 
 static biosBuf_t bb;
 unsigned char uses_ebios[8] = {0, 0, 0, 0, 0, 0, 0, 0};
@@ -47,9 +45,9 @@ int readKeyboardStatus(void)
     bb.eax.r.h = 0x01;
     bios(&bb);
     if (bb.flags.zf) {
-       return 0;
+        return 0;
     } else {
-       return bb.eax.rr;
+        return bb.eax.rr;
     }
 }
 
@@ -64,11 +62,11 @@ int readKeyboardShiftFlags(void)
 unsigned int time18(void)
 {
     union {
-       struct {
-           unsigned int low:16;
-           unsigned int high:16;
-       } s;
-       unsigned int i;
+        struct {
+            unsigned int low:16;
+            unsigned int high:16;
+        } s;
+        unsigned int i;
     } time;
     
     bb.intno = 0x1a;
@@ -119,26 +117,26 @@ int biosread(int dev, int cyl, int head, int sec, int num)
     int i;
 
     bb.intno = 0x13;
-    sec += 1;                  /* sector numbers start at 1 */
+    sec += 1;  /* sector numbers start at 1 */
     
     for (i=0;;) {
-       bb.ecx.r.h = cyl;
-       bb.ecx.r.l = ((cyl & 0x300) >> 2) | (sec & 0x3F);
-       bb.edx.r.h = head;
-       bb.edx.r.l = dev;
-       bb.eax.r.l = num;
-       bb.ebx.rr = ptov(BIOS_ADDR);
-       bb.es = ((unsigned long)&i & 0xffff0000) >> 4;
-    
-       bb.eax.r.h = 0x02;
-       bios(&bb);
+        bb.ecx.r.h = cyl;
+        bb.ecx.r.l = ((cyl & 0x300) >> 2) | (sec & 0x3F);
+        bb.edx.r.h = head;
+        bb.edx.r.l = dev;
+        bb.eax.r.l = num;
+        bb.ebx.rr  = OFFSET(ptov(BIOS_ADDR));
+        bb.es      = SEGMENT(ptov(BIOS_ADDR));
+
+        bb.eax.r.h = 0x02;
+        bios(&bb);
 
-       if ((bb.eax.r.h == 0x00) || (i++ >= 5))
-           break;
+        if ((bb.eax.r.h == 0x00) || (i++ >= 5))
+            break;
 
-       /* reset disk subsystem and try again */
-       bb.eax.r.h = 0x00;
-       bios(&bb);
+        /* reset disk subsystem and try again */
+        bb.eax.r.h = 0x00;
+        bios(&bb);
     }
     return bb.eax.r.h;
 }
@@ -146,24 +144,28 @@ int biosread(int dev, int cyl, int head, int sec, int num)
 int ebiosread(int dev, long sec, int count)
 {
     int i;
-    struct {
-        unsigned char size;
-        unsigned char reserved;
-        unsigned char numblocks;
-        unsigned char reserved2;
-        unsigned int buffer;
-        unsigned long long startblock;
+    static struct {
+        unsigned char  size;
+        unsigned char  reserved;
+        unsigned char  numblocks;
+        unsigned char  reserved2;
+        unsigned short bufferOffset;
+        unsigned short bufferSegment;
+        unsigned long  long startblock;
     } addrpacket = {0};
     addrpacket.size = sizeof(addrpacket);
 
     for (i=0;;) {
-        bb.intno = 0x13;
+        bb.intno   = 0x13;
         bb.eax.r.h = 0x42;
         bb.edx.r.l = dev;
-        bb.esi.rr = ((unsigned)&addrpacket & 0xffff);
-        addrpacket.numblocks = count;
-        addrpacket.buffer = ptov(BIOS_ADDR);
-        addrpacket.startblock = sec;
+        bb.esi.rr  = OFFSET((unsigned)&addrpacket);
+        bb.ds      = SEGMENT((unsigned)&addrpacket);
+        addrpacket.reserved = addrpacket.reserved2 = 0;
+        addrpacket.numblocks     = count;
+        addrpacket.bufferOffset  = OFFSET(ptov(BIOS_ADDR));
+        addrpacket.bufferSegment = SEGMENT(ptov(BIOS_ADDR));
+        addrpacket.startblock    = sec;
         bios(&bb);
         if ((bb.eax.r.h == 0x00) || (i++ >= 5))
             break;
@@ -178,16 +180,27 @@ int ebiosread(int dev, long sec, int count)
 void putc(int ch)
 {
     bb.intno = 0x10;
-    bb.ebx.r.h = 0x00;         /* background black */
-    bb.ebx.r.l = 0x0F;         /* foreground white */
+    bb.ebx.r.h = 0x00;  /* background black */
+    bb.ebx.r.l = 0x0F;  /* foreground white */
     bb.eax.r.h = 0x0e;
     bb.eax.r.l = ch;
     bios(&bb);
 }
 
+void putca(int ch, int attr, int repeat)
+{
+    bb.intno   = 0x10;
+    bb.ebx.r.h = 0x00;   /* page number */
+    bb.ebx.r.l = attr;   /* attribute   */
+    bb.eax.r.h = 0x9;
+    bb.eax.r.l = ch;
+    bb.ecx.rx  = repeat; /* repeat count */ 
+    bios(&bb);
+}
+
 unsigned int get_diskinfo(int drive)
 {
-    struct {
+    static struct {
         unsigned short size;
         unsigned short flags;
         unsigned long cylinders;
@@ -200,23 +213,23 @@ unsigned int get_diskinfo(int drive)
     unsigned char useEbios = 0;
 
     union {
-       compact_diskinfo_t di;
-       unsigned int ui;
+        compact_diskinfo_t di;
+        unsigned int ui;
     } ret;
     static int maxhd = 0;
 
     ret.ui = 0;
     if (maxhd == 0) {
-       bb.intno = 0x13;
-       bb.eax.r.h = 0x08;
-       bb.edx.r.l = 0x80;
-       bios(&bb);
-       if (bb.flags.cf == 0)
-           maxhd = 0x7f + bb.edx.r.l;
+        bb.intno = 0x13;
+        bb.eax.r.h = 0x08;
+        bb.edx.r.l = 0x80;
+        bios(&bb);
+        if (bb.flags.cf == 0)
+            maxhd = 0x7f + bb.edx.r.l;
     };
 
     if (drive > maxhd)
-       return 0;
+        return 0;
 
     /* Check drive for EBIOS support. */
     bb.intno = 0x13;
@@ -225,16 +238,21 @@ unsigned int get_diskinfo(int drive)
     bb.ebx.rr = 0x55aa;
     bios(&bb);
     if(bb.ebx.rr == 0xaa55 && bb.flags.cf == 0) {
+        /* Get flags for supported operations. */
+        useEbios = bb.ecx.r.l;
+    }
 
+    if (useEbios & EBIOS_ENHANCED_DRIVE_INFO) {
         /* Get EBIOS drive info. */
         ebios.size = 26;
         bb.intno = 0x13;
         bb.eax.r.h = 0x48;
         bb.edx.r.l = drive;
-        bb.esi.rr = ((unsigned)&ebios & 0xffff);
+        bb.esi.rr = OFFSET((unsigned)&ebios);
+        bb.ds     = SEGMENT((unsigned)&ebios);
         bios(&bb);
-        if(bb.flags.cf == 0 && ebios.cylinders != 0) {
-            useEbios = 1;
+        if(bb.flags.cf != 0) {
+            useEbios = 0;
         }
     }
 
@@ -249,7 +267,7 @@ unsigned int get_diskinfo(int drive)
 
         hds = bb.edx.r.h;
         sec = bb.ecx.r.l & 0x3F;
-        if(useEbios) {
+        if(useEbios & EBIOS_ENHANCED_DRIVE_INFO) {
             cyl = (ebios.total_sectors / ((hds + 1) * sec)) - 1;
         }
         else {
@@ -263,18 +281,75 @@ unsigned int get_diskinfo(int drive)
     return ret.ui;
 }
 
-void setCursorPosition(int x, int y)
+void setCursorPosition(int x, int y, int page)
 {
     bb.intno = 0x10;
     bb.eax.r.h = 0x02;
-    bb.ebx.r.h = 0x00;         /* page 0 for graphics */
+    bb.ebx.r.h = page;  /* page 0 for graphics */
     bb.edx.r.l = x;
     bb.edx.r.h = y;
     bios(&bb);
 }
 
+void setCursorType(int type)
+{
+    bb.intno   = 0x10;
+    bb.eax.r.h = 0x01;
+    bb.ecx.rr  = type;
+    bios(&bb);
+}
+
+void getCursorPositionAndType(int * x, int * y, int * type)
+{
+    bb.intno   = 0x10;
+    bb.eax.r.h = 0x03;
+    bios(&bb);
+    *x = bb.edx.r.l;
+    *y = bb.edx.r.h;
+    *type = bb.ecx.rr;
+}
+
+void scollPage(int x1, int y1, int x2, int y2, int attr, int rows, int dir)
+{
+    bb.intno   = 0x10;
+    bb.eax.r.h = (dir > 0) ? 0x06 : 0x07;
+    bb.eax.r.l = rows;
+    bb.ebx.r.h = attr;
+    bb.ecx.r.h = y1;
+    bb.ecx.r.l = x1;
+    bb.edx.r.h = y2;
+    bb.edx.r.l = x2;
+    bios(&bb);
+}
+
+void clearScreenRows( int y1, int y2 )
+{
+    scollPage( 0, y1, 80 - 1, y2, 0x07, y2 - y1 + 1, 1 );
+}
+
+void setActiveDisplayPage( int page )
+{
+    bb.intno   = 0x10;
+    bb.eax.r.h = 5;
+    bb.eax.r.l = page;
+    bios(&bb);
+}
+
 #if DEBUG
 
+int terminateDiskEmulation()
+{
+    static char cd_spec[0x12];
+
+    bb.intno   = 0x13;
+    bb.eax.r.h = 0x4b;
+    bb.eax.r.l = 0;     // subfunc: terminate emulation    
+    bb.esi.rr  = OFFSET((unsigned)&cd_spec);
+    bb.ds      = SEGMENT((unsigned)&cd_spec);
+    bios(&bb);
+    return bb.eax.r.h;
+}
+
 int readDriveParameters(int drive, struct driveParameters *dp)
 {
     bb.intno = 0x13;
@@ -282,20 +357,20 @@ int readDriveParameters(int drive, struct driveParameters *dp)
     bb.eax.r.h = 0x08;
     bios(&bb);
     if (bb.eax.r.h == 0) {
-       dp->heads = bb.edx.r.h;
-       dp->sectors = bb.ecx.r.l & 0x3F;
-       dp->cylinders = bb.ecx.r.h | ((bb.ecx.r.l & 0xC0) << 2);
-       dp->totalDrives = bb.edx.r.l;
+        dp->heads = bb.edx.r.h;
+        dp->sectors = bb.ecx.r.l & 0x3F;
+        dp->cylinders = bb.ecx.r.h | ((bb.ecx.r.l & 0xC0) << 2);
+        dp->totalDrives = bb.edx.r.l;
     } else {
-       bzero(dp, sizeof(*dp));
+        bzero(dp, sizeof(*dp));
     }
     return bb.eax.r.h;
 
 }
 #endif
 
-#define APM_INTNO      0x15
-#define APM_INTCODE    0x53
+#define APM_INTNO   0x15
+#define APM_INTCODE 0x53
 
 int
 APMPresent(void)
@@ -308,13 +383,13 @@ APMPresent(void)
     bb.ebx.rr = 0x0000;
     bios(&bb);
     if ((bb.flags.cf == 0) &&
-       (bb.ebx.r.h == 'P') &&
-       (bb.ebx.r.l == 'M')) {
-           /* Success */
-           kbp->apmConfig.major_vers = bb.eax.r.h;
-           kbp->apmConfig.minor_vers = bb.eax.r.l;
-           kbp->apmConfig.flags.data = bb.ecx.rr;
-           return 1;
+        (bb.ebx.r.h == 'P') &&
+        (bb.ebx.r.l == 'M')) {
+        /* Success */
+        kbp->apmConfig.major_vers = bb.eax.r.h;
+        kbp->apmConfig.minor_vers = bb.eax.r.l;
+        kbp->apmConfig.flags.data = bb.ecx.rr;
+        return 1;
     }
     return 0;
 }
@@ -330,39 +405,39 @@ APMConnect32(void)
     bb.ebx.rr = 0x0000;
     bios(&bb);
     if (bb.flags.cf == 0) {
-       /* Success */
-       kbp->apmConfig.cs32_base = (bb.eax.rr) << 4;
-       kbp->apmConfig.entry_offset = bb.ebx.rx;
-       kbp->apmConfig.cs16_base = (bb.ecx.rr) << 4;
-       kbp->apmConfig.ds_base = (bb.edx.rr) << 4;
-       if (kbp->apmConfig.major_vers >= 1 &&
-           kbp->apmConfig.minor_vers >= 1) {
-               kbp->apmConfig.cs_length = bb.esi.rr;
-               kbp->apmConfig.ds_length = bb.edi.rr;
-       } else {
-               kbp->apmConfig.cs_length = 
-                   kbp->apmConfig.ds_length = 64 * 1024;
-       }
-       kbp->apmConfig.connected = 1;
-       return 1;
+        /* Success */
+        kbp->apmConfig.cs32_base = (bb.eax.rr) << 4;
+        kbp->apmConfig.entry_offset = bb.ebx.rx;
+        kbp->apmConfig.cs16_base = (bb.ecx.rr) << 4;
+        kbp->apmConfig.ds_base = (bb.edx.rr) << 4;
+        if (kbp->apmConfig.major_vers >= 1 &&
+            kbp->apmConfig.minor_vers >= 1) {
+            kbp->apmConfig.cs_length = bb.esi.rr;
+            kbp->apmConfig.ds_length = bb.edi.rr;
+        } else {
+            kbp->apmConfig.cs_length = 
+                kbp->apmConfig.ds_length = 64 * 1024;
+        }
+        kbp->apmConfig.connected = 1;
+        return 1;
     }
     return 0;
 }
 
-#ifdef EISA_SUPPORT  // turn off for now since there isn't enough room
+#ifdef EISA_SUPPORT
 BOOL
 eisa_present(
     void
 )
 {
-    static BOOL        checked;
-    static BOOL        isEISA;
+    static BOOL checked;
+    static BOOL isEISA;
 
     if (!checked) {
-       if (strncmp((char *)0xfffd9, "EISA", 4) == 0)
-           isEISA = TRUE;
-           
-       checked = TRUE;
+        if (strncmp((char *)0xfffd9, "EISA", 4) == 0)
+            isEISA = TRUE;
+
+        checked = TRUE;
     }
     
     return (isEISA);
@@ -372,20 +447,20 @@ int
 ReadEISASlotInfo(EISA_slot_info_t *ep, int slot)
 {
     union {
-       struct {
-           unsigned char       char2h  :2;
-           unsigned char       char1   :5;
-           unsigned char       char3   :5;
-           unsigned char       char2l  :3;
-           unsigned char       d2      :4;
-           unsigned char       d1      :4;
-           unsigned char       d4      :4;
-           unsigned char       d3      :4;
-       } s;
-       unsigned char data[4];
+        struct {
+            unsigned char char2h :2;
+            unsigned char char1  :5;
+            unsigned char char3  :5;
+            unsigned char char2l :3;
+            unsigned char d2     :4;
+            unsigned char d1     :4;
+            unsigned char d4     :4;
+            unsigned char d3     :4;
+        } s;
+        unsigned char data[4];
     } u;
     static char hex[0x10] = "0123456789ABCDEF";
-       
+
     
     bb.intno = 0x15;
     bb.eax.r.h = 0xd8;
@@ -393,7 +468,7 @@ ReadEISASlotInfo(EISA_slot_info_t *ep, int slot)
     bb.ecx.r.l = slot;
     bios(&bb);
     if (bb.flags.cf)
-       return bb.eax.r.h;
+        return bb.eax.r.h;
     ep->u_ID.d = bb.eax.r.l;
     ep->configMajor = bb.ebx.r.h;
     ep->configMinor = bb.ebx.r.l;
@@ -430,12 +505,12 @@ ReadEISAFuncInfo(EISA_func_info_t *ep, int slot, int function)
     bb.esi.rr = (unsigned int)ep->data;
     bios(&bb);
     if (bb.eax.r.h == 0) {
-       ep->slot = slot;
-       ep->function = function;
+        ep->slot = slot;
+        ep->function = function;
     }
     return bb.eax.r.h;
 }
-#endif
+#endif /* EISA_SUPPORT */
 
 #define PCI_SIGNATURE 0x20494350  /* "PCI " */
 
@@ -447,12 +522,12 @@ ReadPCIBusInfo(PCI_bus_info_t *pp)
     bb.eax.r.l = 0x01;
     bios(&bb);
     if ((bb.eax.r.h == 0) && (bb.edx.rx == PCI_SIGNATURE)) {
-       pp->BIOSPresent = 1;
-       pp->u_bus.d = bb.eax.r.l;
-       pp->majorVersion = bb.ebx.r.h;
-       pp->minorVersion = bb.ebx.r.l;
-       pp->maxBusNum = bb.ecx.r.l;
-       return 0;
+        pp->BIOSPresent = 1;
+        pp->u_bus.d = bb.eax.r.l;
+        pp->majorVersion = bb.ebx.r.h;
+        pp->minorVersion = bb.ebx.r.l;
+        pp->maxBusNum = bb.ecx.r.l;
+        return 0;
     }
     return -1;
 }
index c4e545bbef81795caa2703bd1edb88685fb6dcdd..667f7c07f05161d80b00277660053dc260f594bd 100644 (file)
@@ -26,9 +26,7 @@
  * All rights reserved.
  */
 
-#include "io_inline.h"
 #include "libsaio.h"
-#include "kernBootStruct.h"
 
 // CMOS access ports in I/O space.
 //
@@ -40,8 +38,7 @@
  * Returns the number of active ATA drives since these will increment the
  * bios device numbers of SCSI drives.
  */
-static int
-countIDEDisks()
+static int countIDEDisks()
 {
     int            count = 0;
     unsigned short hdtype;
@@ -84,20 +81,29 @@ countIDEDisks()
 
 KERNBOOTSTRUCT * kernBootStruct = (KERNBOOTSTRUCT *) KERNSTRUCT_ADDR;
 
-void
-initKernBootStruct()
+void initKernBootStruct( int biosdev )
 {
+    static int init_done = 0;
     unsigned char i;
 
-    bzero( (char *) kernBootStruct, sizeof(*kernBootStruct) );    
+    if ( !init_done )
+    {
+        bzero( (char *) kernBootStruct, sizeof(*kernBootStruct) );    
     
-    // Get size of conventional memory.
-
-    kernBootStruct->convmem = memsize(0);
-
-    // Get size of extended memory.
-
-    kernBootStruct->extmem  = memsize(1);    
+        // Get size of conventional memory.
+    
+        kernBootStruct->convmem = memsize(0);
+    
+        // Get size of extended memory.
+    
+        kernBootStruct->extmem  = memsize(1);
+    
+        kernBootStruct->magicCookie  = KERNBOOTMAGIC;
+        kernBootStruct->configEnd    = kernBootStruct->config;
+        kernBootStruct->graphicsMode = TEXT_MODE;
+        
+        init_done = 1;
+    }
 
     // Get number of ATA devices.
 
@@ -110,7 +116,15 @@ initKernBootStruct()
         kernBootStruct->diskInfo[i] = get_diskinfo(0x80 + i);
     }
 
-    kernBootStruct->magicCookie  = KERNBOOTMAGIC;
-    kernBootStruct->configEnd    = kernBootStruct->config;
-    kernBootStruct->graphicsMode = GRAPHICS_MODE;
+    // Update kernDev from biosdev.
+
+    switch ( BIOS_DEV_TYPE( biosdev ) )
+    {
+        case kBIOSDevTypeNetwork:
+            kernBootStruct->kernDev = B_TYPE(DEV_EN); break;
+        case kBIOSDevTypeHardDrive:
+            kernBootStruct->kernDev = B_TYPE(DEV_HD); break;
+        case kBIOSDevTypeFloppy:
+            kernBootStruct->kernDev = B_TYPE(DEV_FD); break;
+    }
 }
index 6ead4d65b2e050c37e5256f3538e4dfb4f5aeaad..4528dc5479006f35d4b220c0e2c331aa7414cf82 100644 (file)
 /*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
- * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License").  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License").  You may not use this file except in compliance with the
+ * License.  Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
  * 
- * The Original Code and all software distributed under the License are
+ * This Original Code and all software distributed under the License are
  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
  * License for the specific language governing rights and limitations
  * under the License.
  * 
  * @APPLE_LICENSE_HEADER_END@
  */
-/* cache */
+/*
+ *  cache.c - A simple cache for file systems meta-data.
+ *
+ *  Copyright (c) 2000 Apple Computer, Inc.
+ *
+ *  DRI: Josh de Cesare
+ */
 
-#include "cache.h"
-#include "libsa.h"
+#include <sl.h>
+// #include <fs.h>
 
-cache_t *cacheInit(
-    int nitems,
-    int item_size
-)
-{
-    cache_t *cp;
-    item_size += sizeof(item_t);
-    cp = (cache_t *)malloc(sizeof(cache_t) + nitems * item_size);
-    cp->nitems = nitems;
-    cp->item_size = item_size;
-    return cp;
-}
+struct CacheEntry {
+  CICell    ih;
+  long      time;
+  long long offset;
+};
+typedef struct CacheEntry CacheEntry;
 
-/*
- * Either find an item in the cache, or find where it should go.
- * Returns 1 if found, 0 if not found.
- * This function assumes that if you find an empty slot, you will use it;
- * therefore, empty slots returned are marked valid.
- */
-int cacheFind(
-    cache_t *cp,
-    int key1,
-    int key2,
-    char **ip
-)
+#define kCacheSize            (0x100000)
+#define kCacheMinBlockSize    (0x200)
+#define kCacheMaxBlockSize    (0x4000)
+#define kCacheMaxEntries      (kCacheSize / kCacheMinBlockSize)
+
+static CICell     gCacheIH;
+static long       gCacheBlockSize;
+static long       gCacheNumEntries;
+static long       gCacheTime;
+
+#ifdef __i386__
+static CacheEntry *gCacheEntries;
+static char       *gCacheBuffer;
+#else
+static CacheEntry gCacheEntries[kCacheMaxEntries];
+static char       gCacheBuffer[kCacheSize];
+#endif
+
+unsigned long     gCacheHits;
+unsigned long     gCacheMisses;
+unsigned long     gCacheEvicts;
+
+void CacheInit( CICell ih, long blockSize )
 {
-    item_t *iip, *min_p;
-    int i,j;
+#ifdef __i386__
+    if ((ih == gCacheIH) && (blockSize == gCacheBlockSize))
+        return;
+#endif
+
+    if ((blockSize  < kCacheMinBlockSize) ||
+        (blockSize >= kCacheMaxBlockSize))
+        return;
+
+    gCacheBlockSize = blockSize;
+    gCacheNumEntries = kCacheSize / gCacheBlockSize;
+    gCacheTime = 0;
     
-    for(i=j=0, iip = min_p = (item_t *)cp->storage; i < cp->nitems; i++) {
-       if (iip->referenced && (iip->key1 == key1) && (iip->key2 == key2)) {
-           *ip = iip->storage;
-           if (iip->referenced < 65535)
-               iip->referenced++;
-           return 1;
-       }
-       if (iip->referenced < min_p->referenced) {
-           min_p = iip;
-           j = i;
-       }
-       iip = (item_t *)((char *)iip + cp->item_size);
+    gCacheHits = 0;
+    gCacheMisses = 0;
+    gCacheEvicts = 0;
+
+    gCacheIH = ih;
+
+#ifdef __i386__
+    if (!gCacheBuffer) gCacheBuffer = (char *) malloc(kCacheSize);
+    if (!gCacheEntries) gCacheEntries = (CacheEntry *) malloc(kCacheMaxEntries * sizeof(CacheEntry));
+    if ( !gCacheBuffer || !gCacheEntries )
+    {
+        gCacheIH = 0;  // invalidate cache
+        return;
     }
-    *ip = min_p->storage;
-    min_p->referenced = 1;
-    min_p->key1 = key1;
-    min_p->key2 = key2;
-    return 0;
+#endif
+
+    bzero(gCacheEntries, kCacheMaxEntries * sizeof(CacheEntry));
 }
 
-/*
- * Flush the cache.
- */
-void cacheFlush(
-    cache_t *cp
-)
+long CacheRead( CICell ih, char * buffer, long long offset,
+                   long length, long cache )
 {
-    int i;
-    item_t *ip;
-    
-    if (cp == 0)
-       return;
-    for(i=0, ip = (item_t *)cp->storage; i < cp->nitems; i++) {
-       ip->referenced = 0;
-       ip = (item_t *)((char *)ip + cp->item_size);
+       long       cnt, oldestEntry = 0, oldestTime, loadCache = 0;
+       CacheEntry *entry;
+
+    // See if the data can be cached.
+    if (cache && (gCacheIH == ih) && (length == gCacheBlockSize)) {
+        // Look for the data in the cache.
+        for (cnt = 0; cnt < gCacheNumEntries; cnt++) {
+            entry = &gCacheEntries[cnt];
+            if ((entry->ih == ih) && (entry->offset == offset)) {
+                entry->time = ++gCacheTime;
+                break;
+            }
+        }
+
+        // If the data was found copy it to the caller.
+        if (cnt != gCacheNumEntries) {
+            bcopy(gCacheBuffer + cnt * gCacheBlockSize, buffer, gCacheBlockSize);
+            gCacheHits++;
+            return gCacheBlockSize;
+        }
+
+        // Could not find the data in the cache.
+        loadCache = 1;
     }
+
+    // Read the data from the disk.
+    Seek(ih, offset);
+    Read(ih, (long)buffer, length);
+    if (cache) gCacheMisses++;
+
+    // Put the data from the disk in the cache if needed.
+    if (loadCache) {
+        // Find a free entry.
+        oldestTime = gCacheTime;
+        for (cnt = 0; cnt < gCacheNumEntries; cnt++) {
+            entry = &gCacheEntries[cnt];
+
+            // Found a free entry.
+            if (entry->ih == 0) break;
+        
+            if (entry->time < oldestTime) {
+                oldestTime = entry->time;
+                oldestEntry = cnt;
+            }
+        }
+
+        // If no free entry was found, use the oldest.
+        if (cnt == gCacheNumEntries) {
+            cnt = oldestEntry;
+            gCacheEvicts++;
+        }
+
+        // Copy the data from disk to the new entry.
+        entry = &gCacheEntries[cnt];
+        entry->ih = ih;
+        entry->time = ++gCacheTime;
+        entry->offset = offset;
+        bcopy(buffer, gCacheBuffer + cnt * gCacheBlockSize, gCacheBlockSize);
+    }
+
+    return length;
 }
diff --git a/i386/libsaio/cache.h b/i386/libsaio/cache.h
deleted file mode 100644 (file)
index 01b51d9..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License").  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#ifndef __LIBSAIO_CACHE_H
-#define __LIBSAIO_CACHE_H
-
-typedef struct cache_item {
-    unsigned int       referenced;
-    int                        key1, key2;
-    char               storage[0];
-} item_t;
-
-typedef struct cache {
-    int                        nitems;
-    int                        item_size;
-    char               storage[0];
-} cache_t;
-
-extern cache_t *cacheInit(
-    int nitems,
-    int item_size
-);
-
-extern int cacheFind(
-    cache_t *cp,
-    int key1,
-    int key2,
-    char **ip
-);
-
-extern void cacheFlush(
-    cache_t *cp
-);
-
-#endif /* !__LIBSAIO_CACHE_H */
index 53de5a00b1fb6cf076ef6da41681477bd1c38352..9f3555cd36700cd9479b420b5cee916a1da575d8 100644 (file)
@@ -47,7 +47,7 @@
 #include "libsaio.h"
 
 BOOL gVerboseMode;
-BOOL errors;
+BOOL gErrors;
 
 /*
  * write one character to console
@@ -117,7 +117,7 @@ int verbose(const char * fmt, ...)
 int error(const char * fmt, ...)
 {
     va_list ap;
-    errors = YES;
+    gErrors = YES;
     va_start(ap, fmt);
     prf(fmt, ap, putchar, 0);
     va_end(ap);
index b08678df17c755583328275a3bdad0f4abd54bb0..7c70cf8465a412faebca4e6dd643163393ffbe18 100644 (file)
  * All rights reserved.
  */
 
-#define DRIVER_PRIVATE
-
-#include "sys/types.h"
-#include "legacy/disk.h"
-#include "legacy/fdisk.h"
 #include "libsaio.h"
-#include "memory.h"
-
-/*
- * Type and constant definitions.
- */
-typedef struct disk_blk0   boot_sector;
-#define BOOT_SIGNATURE     DISK_SIGNATURE
-#define PART_TYPE_EXT      0x05
-#define PART_TYPE_APPLE    0xa8
-#define UFS_FRONT_PORCH    0
-
-#if            DEBUG
-#define DPRINT(x)       { printf x; }
-#define DSPRINT(x)      { printf x; sleep(1); }
-#else
-#define DPRINT(x)
-#define DSPRINT(x)
-#endif
-
-/*
- * Function prototypes.
- */
-extern void   spinActivityIndicator();
-static void   diskActivityHook();
-static int    Biosread(int biosdev, int secno);
-static struct fdisk_part * find_partition(u_int8_t type,
-                                          u_int8_t biosdev,
-                                          BOOL     mba);
+#include "fdisk.h"
 
 /*
  * diskinfo unpacking.
  */
-#define SPT(di)         ((di) & 0xff)
-#define HEADS(di)       ((((di)>>8) & 0xff) + 1)
-#define SPC(di)         (SPT(di) * HEADS(di))
-#define BPS             512     /* sector size of the device */
-#define N_CACHE_SECS    (BIOS_LEN / BPS)
+#define SPT(di)          ((di) & 0xff)
+#define HEADS(di)        ((((di)>>8) & 0xff) + 1)
+#define SPC(di)          (SPT(di) * HEADS(di))
 
-/*
- * Stores the geometry of the disk in order to
- * perform LBA to CHS translation for non EBIOS calls.
- */
-static struct diskinfo {
-    int spt;            /* sectors per track */
-    int spc;            /* sectors per cylinder */
-} diskinfo;
-
-/*
- * Globals variables.
- */
-int     label_secsize = BPS;
-char *  b[NBUFS];
-daddr_t blknos[NBUFS];
-struct  iob iob[NFILES];
+#define BPS              512     /* sector size of the device */
+#define N_CACHE_SECS     (BIOS_LEN / BPS)
+#define UFS_FRONT_PORCH  0
 
 /*
- * intbuf points to the start of the sector cache. BIOS calls will
- * store the sectors read into this memory area. If cache_valid
- * is TRUE, then intbuf contents are valid. Otherwise, ignore the
- * cache and read from disk.
+ * trackbuf points to the start of the track cache. Biosread()
+ * will store the sectors read from disk to this memory area.
  *
- * biosbuf points to a sector within the sector cache.
+ * biosbuf points to a sector within the track cache, and is
+ * updated by Biosread().
  */
-static char * const intbuf = (char *)ptov(BIOS_ADDR);
-static BOOL   cache_valid  = FALSE;
-static char * biosbuf;
+static const char * const trackbuf = (char *) ptov(BIOS_ADDR);
+static const char * biosbuf;
 
-/*==========================================================================
- * 
+/*
+ * Map a disk drive to bootable volumes contained within.
  */
-void
-devopen(char * name, struct iob * io)
-{
-    static int          last_biosdev = -1;
-    static daddr_t      last_offset  = 0;
+struct DiskBVMap {
+    int                biosdev;  // BIOS device number (unique)
+    BVRef              bvr;      // chain of boot volumes on the disk
+    int                bvrcnt;   // number of boot volumes
+    struct DiskBVMap * next;     // linkage to next mapping
+};
 
-    struct fdisk_part * part;
-    long                di;
+static struct DiskBVMap * gDiskBVMap  = NULL;
+static struct disk_blk0 * gBootSector = NULL;
 
-    io->i_error = 0;
-    io->dirbuf_blkno = -1;
+extern long HFSInitPartition(CICell ih);
+extern long HFSLoadFile(CICell ih, char * filePath);
+extern long HFSGetDirEntry(CICell ih, char * dirPath, long * dirIndex,
+                           char ** name, long * flags, long * time);
 
-    // Use cached values if possible.
-    //
-    if (io->biosdev == last_biosdev) {
-        io->i_boff = last_offset;
-        return;
-    }
+extern long UFSInitPartition(CICell ih);
+extern long UFSLoadFile(CICell ih, char * filePath);
+extern long UFSGetDirEntry(CICell ih, char * dirPath, long * dirIndex,
+                           char ** name, long * flags, long * time);
 
-    // initialize disk parameters -- spt and spc
-    // must do this before doing reads from the device.
+extern void spinActivityIndicator();
 
-    di = get_diskinfo(io->biosdev);
-    if (di == 0) {
-        io->i_error = ENXIO;
-        return;
-    }
+static void getVolumeDescription(BVRef bvr, char * str, long strMaxLen);
 
-    diskinfo.spt = SPT(di);
-    diskinfo.spc = diskinfo.spt * HEADS(di);
-
-    // FIXME - io->partition is ignored. Doesn't make sense anymore.
-    //         we also don't overwrite the 'name' argument.
-    //         Whats special about "$LBL" ?
-
-    part = find_partition(PART_TYPE_APPLE, io->biosdev, FALSE);
-    if (part == NULL) {
-        io->i_error = EIO;
-        DSPRINT(("Unable to find partition: IO error\n"));
-    } else {
-        last_offset  = io->i_boff = part->relsect + UFS_FRONT_PORCH/BPS;
-        last_biosdev = io->biosdev;
-        DSPRINT(("partition offset: %x\n", io->i_boff));
-    }
-}
+//==========================================================================
 
-/*==========================================================================
- * 
- */
-void devflush()
+static int getDiskGeometry( int biosdev, int * spt, int * spc )
 {
-    cache_valid = FALSE;   // invalidate the sector cache (intbuf)
-}
-
-/*==========================================================================
- * 
- */
-int devread(struct iob * io)
-{
-    long      sector;
-    int       offset;
-//  int       dev;
-
-    io->i_flgs |= F_RDDATA;
+    static int cached_biosdev = -1;
+    static int cached_spt = 0;
+    static int cached_spc = 0;
+    
+    if ( biosdev != cached_biosdev )
+    {
+        long di = get_diskinfo(biosdev);
+        if (di == 0) return (-1); // BIOS call error
 
-    io->i_error = 0;        // assume the best
+        cached_spt = SPT(di);
+        cached_spc = cached_spt * HEADS(di);
 
-//  dev = io->i_ino.i_dev;
+        DEBUG_DISK(("%s: %d sectors, %d heads\n",
+                    __FUNCTION__, cached_spt, (int)HEADS(di)));
+    }
 
-    sector = io->i_bn * (label_secsize/BPS);
+    *spt = cached_spt;
+    *spc = cached_spc;
 
-    for (offset = 0; offset < io->i_cc; offset += BPS) {
+    return 0;
+}
 
-        io->i_error = Biosread(io->biosdev, sector);
-        if (io->i_error)
-            return (-1);
+//==========================================================================
+// Maps (E)BIOS return codes to message strings.
 
-        /* copy 1 sector from the internal buffer biosbuf into buf */
-        bcopy(biosbuf, &io->i_ma[offset], BPS);
+struct NamedValue {
+    unsigned char value;
+    const char *  name;
+};
 
-        sector++;
-    }
+static const char * getNameForValue( const struct NamedValue * nameTable,
+                                     unsigned char value )
+{
+    const struct NamedValue * np;
 
-    io->i_flgs &= ~F_TYPEMASK;
+    for ( np = nameTable; np->value; np++)
+        if (np->value == value)
+            return np->name;
 
-    return (io->i_cc);
+    return NULL;
 }
 
-/*==========================================================================
- * Maps (E)BIOS return codes to message strings.
- */
-struct bios_error_info {
-    int          errno;
-    const char * string;
-};
-
 #define ECC_CORRECTED_ERR 0x11
 
-static struct bios_error_info bios_errors[] = {
-    {0x10, "Media error"},
-    {0x11, "Corrected ECC error"},
-    {0x20, "Controller or device error"},
-    {0x40, "Seek failed"},
-    {0x80, "Device timeout"},
-    {0xAA, "Drive not ready"},
-    {0x00, 0}
+static const struct NamedValue bios_errors[] = {
+    { 0x10, "Media error"                },
+    { 0x11, "Corrected ECC error"        },
+    { 0x20, "Controller or device error" },
+    { 0x40, "Seek failed"                },
+    { 0x80, "Device timeout"             },
+    { 0xAA, "Drive not ready"            },
+    { 0x00, 0                            }
 };
 
-static const char *
-bios_error(int errno)
+static const char * bios_error(int errnum)
 {
-    struct bios_error_info * bp;
-    
-    for (bp = bios_errors; bp->errno; bp++) {
-        if (bp->errno == errno)
-            return bp->string;
-    }
-    return "Error 0x%02x";   // No string, print error code only
+    static char  errorstr[] = "Error 0x00";
+    const char * errname;
+
+    errname = getNameForValue( bios_errors, errnum );
+    if ( errname ) return errname;
+
+    sprintf(errorstr, "Error 0x%02x", errnum);
+    return errorstr;   // No string, print error code only
 }
 
-/*==========================================================================
- * Use BIOS INT13 calls to read the sector specified. This function will
- * also perform read-ahead to cache a few subsequent sector to the sector
- * cache.
- *
- * The fields in diskinfo structure must be filled in before calling this
- * function.
- *
- * Return:
- *   Return code from INT13/F2 or INT13/F42 call. If operation was
- *   successful, 0 is returned.
- *
- */
-static int
-Biosread(int biosdev, int secno)
+//==========================================================================
+// Use BIOS INT13 calls to read the sector specified. This function will
+// also perform read-ahead to cache a few subsequent sector to the sector
+// cache.
+// 
+// Return:
+//   0 on success, or an error code from INT13/F2 or INT13/F42 BIOS call.
+
+static int Biosread( int biosdev, unsigned int secno )
 {
-    static int xbiosdev, xcyl, xhead, xsec, xnsecs;
-    
-    extern unsigned char uses_ebios[];
+    static int xbiosdev, xcyl, xhead;
+    static unsigned int xsec, xnsecs;
+    static BOOL cache_valid = FALSE;
 
-    int  rc;
+    int  rc = -1;
     int  cyl, head, sec;
     int  spt, spc;
     int  tries = 0;
 
-    DSPRINT(("Biosread %d \n", secno));
+    // DEBUG_DISK(("Biosread dev %x sec %d \n", biosdev, secno));
 
     // To read the disk sectors, use EBIOS if we can. Otherwise,
     // revert to the standard BIOS calls.
-    //
-    if ((biosdev >= BIOS_DEV_HD) && uses_ebios[biosdev - BIOS_DEV_HD]) {
+
+    if ((biosdev >= kBIOSDevTypeHardDrive) &&
+        (uses_ebios[biosdev - kBIOSDevTypeHardDrive] & EBIOS_FIXED_DISK_ACCESS))
+    {
         if (cache_valid &&
             (biosdev == xbiosdev) &&
             (secno >= xsec) &&
             (secno < (xsec + xnsecs)))
         {
-            biosbuf = intbuf + (BPS * (secno - xsec));
+            biosbuf = trackbuf + (BPS * (secno - xsec));
             return 0;
         }
 
         xnsecs = N_CACHE_SECS;
         xsec   = secno;
+        cache_valid = FALSE;
 
         while ((rc = ebiosread(biosdev, secno, xnsecs)) && (++tries < 5))
         {
             if (rc == ECC_CORRECTED_ERR) {
                 /* Ignore corrected ECC errors */
+                rc = 0;
                 break;
             }
             error("  EBIOS read error: %s\n", bios_error(rc), rc);
@@ -294,10 +217,8 @@ Biosread(int biosdev, int secno)
             sleep(1);
         }
     }
-    else {
-        spt = diskinfo.spt;    // From previous INT13/F8 call.
-        spc = diskinfo.spc;
-
+    else if ( getDiskGeometry(biosdev, &spt, &spc) == 0 )
+    {
         cyl  = secno / spc;
         head = (secno % spc) / spt;
         sec  = secno % spt;
@@ -309,24 +230,26 @@ Biosread(int biosdev, int secno)
             (sec >= xsec) &&
             (sec < (xsec + xnsecs)))
         {
-            // this sector is in intbuf cache
-            biosbuf = intbuf + (BPS * (sec - xsec));
+            // this sector is in trackbuf cache
+            biosbuf = trackbuf + (BPS * (sec - xsec));
             return 0;
         }
 
         // Cache up to a track worth of sectors, but do not cross a
         // track boundary.
-        //
+
         xcyl   = cyl;
         xhead  = head;
         xsec   = sec;
         xnsecs = ((sec + N_CACHE_SECS) > spt) ? (spt - sec) : N_CACHE_SECS;
+        cache_valid = FALSE;
 
         while ((rc = biosread(biosdev, cyl, head, sec, xnsecs)) &&
                (++tries < 5))
         {
             if (rc == ECC_CORRECTED_ERR) {
                 /* Ignore corrected ECC errors */
+                rc = 0;
                 break;
             }
             error("  BIOS read error: %s\n", bios_error(rc), rc);
@@ -337,162 +260,388 @@ Biosread(int biosdev, int secno)
     }
 
     // If the BIOS reported success, mark the sector cache as valid.
-    //
+
     if (rc == 0) {
         cache_valid = TRUE;
     }
-    biosbuf  = intbuf;
+    biosbuf  = trackbuf;
     xbiosdev = biosdev;
     
-    diskActivityHook();
+    spinActivityIndicator();
 
     return rc;
 }
 
-/*==========================================================================
- * Replace this function if you want to change
- * the way disk activity is indicated to the user.
- */
-void
-diskActivityHook(void)
+//==========================================================================
+
+static int readBytes( int biosdev, unsigned int blkno,
+                      unsigned int byteCount, void * buffer )
 {
-    spinActivityIndicator();
+
+    char * cbuf = (char *) buffer;
+    int    error;
+    int    copy_len;
+
+    DEBUG_DISK(("%s: dev %x block %x [%d] -> 0x%x...", __FUNCTION__,
+                biosdev, blkno, byteCount, (unsigned)cbuf));
+
+    for ( ; byteCount; cbuf += BPS, blkno++ )
+    {
+        error = Biosread( biosdev, blkno );
+        if ( error )
+        {
+            DEBUG_DISK(("error\n"));
+            return (-1);
+        }
+
+        copy_len = (byteCount > BPS) ? BPS : byteCount;
+        bcopy( biosbuf, cbuf, copy_len );
+        byteCount -= copy_len;
+    }
+
+    DEBUG_DISK(("done\n"));
+
+    return 0;    
 }
 
-/*==========================================================================
- * Returns YES if the partition type specified is an extended fdisk
- * partition.
- */
-static BOOL
-isExtendedPartition(u_int8_t type)
+//==========================================================================
+
+static int isExtendedFDiskPartition( const struct fdisk_part * part )
 {
-       int i;
-
-       u_int8_t extended_partitions[] = {
-               0x05,   /* Extended */
-               0x0f,   /* Win95 extended */
-               0x85,   /* Linux extended */
-       };
-
-       for (i = 0;
-                i < sizeof(extended_partitions)/sizeof(extended_partitions[0]);
-                i++)
-       {
-               if (extended_partitions[i] == type)
-                       return YES;
-       }
-       return NO;
+    static unsigned char extParts[] =
+    {
+        0x05,   /* Extended */
+        0x0f,   /* Win95 extended */
+        0x85,   /* Linux extended */
+    };
+
+    int i;
+
+    for (i = 0; i < sizeof(extParts)/sizeof(extParts[0]); i++)
+    {
+        if (extParts[i] == part->systid) return 1;
+    }
+    return 0;
 }
 
-/*==========================================================================
- * Traverse the fdisk partition tables on disk until a partition is found
- * that matches the specified type.
- *
- * Arguments:
- *   type    - Partition type to search for (e.g. 0xa7 for NeXTSTEP).
- *   biosdev - BIOS device unit. 0x80 and up for hard-drive.
- *   mba     - If true, the partition found must be marked active.
- *
- * Return:
- *   A pointer to the matching partition entry in biosbuf memory.
- *   Note that the starting LBA field in the partition entry is
- *   modified to contain the absolute sector address, rather than
- *   the relative address.
- *   A NULL is returned if a match is not found.
- *
- * There are certain fdisk rules that allows us to simplify the search.
- *
- * - There can be 0-1 extended partition entry in any partition table.
- * - In the MBR, there can be 0-4 primary partitions entries.
- * - In the extended partition, there can be 0-1 logical partition entry.
- *
- */
-struct fdisk_part *
-find_partition(u_int8_t type, u_int8_t biosdev, BOOL mba)
+//==========================================================================
+
+static int getNextFDiskPartition( int biosdev, int * partno,
+                                  const struct fdisk_part ** outPart )
 {
-#define MAX_ITERATIONS  128
+    static int                 sBiosdev = -1;
+    static int                 sNextPartNo;
+    static unsigned int        sExtBase;
+    static unsigned int        sExtDepth;
+    static struct fdisk_part * sExtPart;
+    struct fdisk_part *        part;
+
+    if ( sBiosdev != biosdev || *partno < 0 )
+    {
+        // Fetch MBR.
+        if ( readBootSector( biosdev, DISK_BLK0, 0 ) ) return 0;
+
+        sBiosdev    = biosdev;
+        sNextPartNo = 0;
+        sExtBase    = 0;
+        sExtDepth   = 0;
+        sExtPart    = NULL;
+    }
 
-    static u_int32_t    iter = 0;
-    static u_int32_t    offset_root;
-    static u_int32_t    offset;
+    while (1)
+    {
+        part  = NULL;
 
-    int                 n;
-    int                 rc;
-    boot_sector *       bootsect;
-    struct fdisk_part * match = 0;
-    struct fdisk_part * parts;
+        if ( sNextPartNo < FDISK_NPART )
+        {
+            part = (struct fdisk_part *) gBootSector->parts[sNextPartNo];
+        }
+        else if ( sExtPart )
+        {
+            unsigned int blkno = sExtPart->relsect + sExtBase;
 
-    if (iter == 0) {
-        if (rc = Biosread(biosdev, 0))  // Read MBR at sector zero.
-            return 0;
-        offset = 0;
+            // Save the block offset of the first extended partition.
+
+            if ( sExtDepth == 0 ) sExtBase = sExtPart->relsect;
+
+            // Load extended partition table.
+
+            if ( readBootSector( biosdev, blkno, 0 ) == 0 )
+            {
+                sNextPartNo = 0;
+                sExtDepth++;
+                sExtPart = NULL;
+                continue;
+            }
+        }
+
+        if ( part == NULL ) break;  // Reached end of partition chain.
+
+        // Advance to next partition number.
+
+        sNextPartNo++;
+
+        // Assume at most one extended partition per table.
+
+        if ( isExtendedFDiskPartition(part) )
+        {
+            sExtPart = part;
+            continue;
+        }
+
+        // Skip empty slots.
+
+        if ( part->systid == 0x00 )
+        {
+            continue;
+        }
+
+        // Change relative offset to an absolute offset.
+
+        part->relsect += sExtBase;
+
+        *outPart = part;
+        *partno  = sExtDepth ? (sExtDepth + 4) : sNextPartNo;
+
+        break;
     }
 
-    bootsect = (boot_sector *) biosbuf;
-    if (bootsect->signature != BOOT_SIGNATURE)
-        return 0;
+    return (part != NULL);
+}
+
+//==========================================================================
 
-    // Find a primary or a logical partition that matches the partition
-    // type specified.
-    //
-    for (n = 0, parts = (struct fdisk_part *) bootsect->parts;
-         n < 4;
-         n++, parts++)
+static BVRef newFDiskBVRef( int biosdev, int partno, unsigned int blkoff,
+                            const struct fdisk_part * part,
+                            FSInit initFunc, FSLoadFile loadFunc,
+                            FSGetDirEntry getdirFunc, int probe )
+{
+    BVRef bvr = (BVRef) malloc( sizeof(*bvr) );
+    if ( bvr )
     {
-        DSPRINT(("fdisk: [%d] %02x\n", iter, parts->systid));
+        bzero(bvr, sizeof(*bvr));
 
-        if (mba && ((parts->bootid & 0x80) == 0))
-            continue;
+        bvr->biosdev        = biosdev;
+        bvr->part_no        = partno;
+        bvr->part_boff      = blkoff;
+        bvr->part_type      = part->systid;
+        bvr->fs_loadfile    = loadFunc;
+        bvr->fs_getdirentry = getdirFunc;
+        bvr->description    = getVolumeDescription;
+
+        if ( part->bootid & FDISK_ACTIVE )
+            bvr->flags |= kBVFlagPrimary;
+
+        // Probe the filesystem.
+
+        if ( initFunc )
+        {
+            bvr->flags |= kBVFlagNativeBoot;
 
-        if (parts->systid == type) {
-            //
-            // Found it!!!
-            // Make the relsect field (LBA starting sector) absolute by
-            // adding in the offset.
-            //
-            parts->relsect += offset;
+            if ( probe && initFunc( bvr ) != 0 )
+            {
+                // filesystem probe failed.
 
-                       DSPRINT(("Found: %x (%d)\n", parts->relsect, parts->numsect));
+                DEBUG_DISK(("%s: failed probe on dev %x part %d\n",
+                            __FUNCTION__, biosdev, partno));
 
-            return parts;
+                free(bvr);
+                bvr = NULL;
+            }
+        }
+        else if ( readBootSector( biosdev, blkoff, (void *)0x7e00 ) == 0 )
+        {
+            bvr->flags |= kBVFlagForeignBoot;
+        }
+        else
+        {
+            free(bvr);
+            bvr = NULL;
         }
     }
+    return bvr;
+}
 
-    // Find if there is an extended partition entry that points to
-    // an extended partition table. Note that we only allow up to
-    // one extended partition per partition table.
-    //
-    for (n = 0, parts = (struct fdisk_part *) bootsect->parts;
-         n < 4;
-         n++, parts++)
-    {
-        DSPRINT(("fdisk: [E%d] %02x\n", iter, parts->systid));
+//==========================================================================
+
+BVRef diskScanBootVolumes( int biosdev, int * countPtr )
+{
+    const struct fdisk_part * part;
+    struct DiskBVMap *        map;
+    int                       partno  = -1;
+    BVRef                     bvr;
+    BVRef                     booterUFS = NULL;
+    int                       spc, spt;
 
-        if (isExtendedPartition(parts->systid))
+    do {
+        // Find an existing mapping for this device.
+
+        for ( map = gDiskBVMap; map; map = map->next )
         {
-            if (iter > MAX_ITERATIONS)  // limit recursion depth
-                return 0;
+            if ( biosdev == map->biosdev ) break;
+        }
+        if ( map ) break;
 
-            if (iter == 0)
-                offset = offset_root = parts->relsect;
-            else
-                offset = parts->relsect + offset_root;
+        // Create a new mapping.
 
-            iter++;
+        map = (struct DiskBVMap *) malloc( sizeof(*map) );
+        if ( map )
+        {
+            map->biosdev = biosdev;
+            map->bvr     = NULL;
+            map->bvrcnt  = 0;
+            map->next    = gDiskBVMap;
+            gDiskBVMap   = map;
 
-            // Load extended partition table.
-            //
-            if (((rc = Biosread(biosdev, offset)) == 0) &&
-                (bootsect->signature == BOOT_SIGNATURE))
+            // Create a record for each partition found on the disk.
+
+            while ( getNextFDiskPartition( biosdev, &partno, &part ) )
             {
-                match = find_partition(type, biosdev, mba);
+                DEBUG_DISK(("%s: part %d [%x]\n", __FUNCTION__,
+                            partno, part->systid));
+
+                bvr = 0;
+
+                switch ( part->systid )
+                {
+                    case FDISK_UFS:
+                        bvr = newFDiskBVRef(
+                                      biosdev, partno,
+                                      part->relsect + UFS_FRONT_PORCH/BPS,
+                                      part,
+                                      UFSInitPartition,
+                                      UFSLoadFile,
+                                      UFSGetDirEntry,
+                                      0 );
+                        break;
+
+                    case FDISK_HFS:
+                        bvr = newFDiskBVRef(
+                                      biosdev, partno,
+                                      part->relsect,
+                                      part,
+                                      HFSInitPartition,
+                                      HFSLoadFile,
+                                      HFSGetDirEntry,
+                                      0 );
+                        break;
+
+                    case FDISK_BOOTER:
+                        if (getDiskGeometry(biosdev, &spt, &spc) != 0)
+                            break;
+
+                        booterUFS = newFDiskBVRef(
+                                      biosdev, partno,
+                                      ((part->relsect + spc - 1) / spc) * spc,
+                                      part,
+                                      UFSInitPartition,
+                                      UFSLoadFile,
+                                      UFSGetDirEntry,
+                                      0 );
+                        break;
+
+                    default:
+                        bvr = newFDiskBVRef(
+                                      biosdev, partno,
+                                      part->relsect,
+                                      part,
+                                      0, 0, 0, 0 );
+                        break;
+                }
+
+                if ( bvr )
+                {
+                    bvr->next = map->bvr;
+                    map->bvr  = bvr;
+                    map->bvrcnt++;
+                }
             }
-            
-            iter--;
 
-            break;
+            // Booting from a CD with an UFS filesystem embedded
+            // in a booter partition.
+
+            if ( booterUFS )
+            {
+                if ( map->bvrcnt == 0 )
+                {
+                    map->bvr = booterUFS;
+                    map->bvrcnt++;
+                }
+                else free( booterUFS );
+            }
+        }
+    } while (0);
+
+    if (countPtr) *countPtr = map ? map->bvrcnt : 0;
+
+    return map ? map->bvr : NULL;
+}
+
+//==========================================================================
+
+static const struct NamedValue fdiskTypes[] =
+{
+    { 0x07,         "Windows NTFS"   },
+    { 0x0c,         "Windows FAT32"  },
+    { 0x83,         "Linux"          },
+    { FDISK_UFS,    "Apple UFS"      },
+    { FDISK_HFS,    "Apple HFS"      },
+    { FDISK_BOOTER, "Apple Boot/UFS" },
+    { 0x00,         0                }  /* must be last */
+};
+
+static void getVolumeDescription( BVRef bvr, char * str, long strMaxLen )
+{
+    unsigned char type = (unsigned char) bvr->part_type;
+    const char * name = getNameForValue( fdiskTypes, type );
+
+    if ( name )
+        sprintf( str, "hd(%d,%d) %s",
+                 BIOS_DEV_UNIT(bvr->biosdev), bvr->part_no, name );
+    else
+        sprintf( str, "hd(%d,%d) TYPE %02x",
+                 BIOS_DEV_UNIT(bvr->biosdev), bvr->part_no, type );
+}
+
+//==========================================================================
+
+int readBootSector( int biosdev, unsigned int secno, void * buffer )
+{
+    struct disk_blk0 * bootSector = (struct disk_blk0 *) buffer;
+    int                error;
+
+    if ( bootSector == NULL )
+    {
+        if ( gBootSector == NULL )
+        {
+            gBootSector = (struct disk_blk0 *) malloc(sizeof(*gBootSector));
+            if ( gBootSector == NULL ) return -1;
         }
+        bootSector = gBootSector;
     }
-    
-    return match;
+
+    error = readBytes( biosdev, secno, BPS, bootSector );
+    if ( error || bootSector->signature != DISK_SIGNATURE )
+        return -1;
+
+    return 0;
+}
+
+//==========================================================================
+// Handle seek request from filesystem modules.
+
+void diskSeek( BVRef bvr, long long position )
+{
+    bvr->fs_boff = position / BPS;
+}
+
+//==========================================================================
+// Handle read request from filesystem modules.
+
+int diskRead( BVRef bvr, long addr, long length )
+{
+    return readBytes( bvr->biosdev,
+                      bvr->fs_boff + bvr->part_boff,
+                      length,
+                      (void *) addr );
 }
diff --git a/i386/libsaio/fdisk.h b/i386/libsaio/fdisk.h
new file mode 100644 (file)
index 0000000..6805024
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992 NeXT Computer, Inc.
+ *
+ * IBM PC disk partitioning data structures.
+ *
+ * HISTORY
+ *
+ * 8 July 1992 David E. Bohman at NeXT
+ *    Created.
+ */
+#ifndef __LIBSAIO_FDISK_H
+#define __LIBSAIO_FDISK_H
+
+#define DISK_BLK0       0       /* blkno of boot block */
+#define DISK_BLK0SZ     512     /* size of boot block */
+#define DISK_BOOTSZ     446     /* size of boot code in boot block */
+#define DISK_SIGNATURE  0xAA55  /* signature of the boot record */
+#define FDISK_NPART     4       /* number of entries in fdisk table */
+#define FDISK_ACTIVE    0x80    /* indicator of active partition */
+#define FDISK_NEXTNAME  0xA7    /* indicator of NeXT partition */
+#define FDISK_DOS12     0x01    /* 12-bit fat < 10MB dos partition */
+#define FDISK_DOS16S    0x04    /* 16-bit fat < 32MB dos partition */
+#define FDISK_DOSEXT    0x05    /* extended dos partition */
+#define FDISK_DOS16B    0x06    /* 16-bit fat >= 32MB dos partition */
+#define FDISK_UFS       0xa8    /* Apple UFS partition */
+#define FDISK_HFS       0xaf    /* Apple HFS partition */
+#define FDISK_BOOTER    0xab    /* Apple booter partition */
+
+/*
+ * Format of fdisk partion entry (if present).
+ */
+struct fdisk_part {
+    unsigned char    bootid;    /* bootable or not */
+    unsigned char    beghead;   /* begining head, sector, cylinder */
+    unsigned char    begsect;   /* begcyl is a 10-bit number */
+    unsigned char    begcyl;    /* High 2 bits are in begsect */
+    unsigned char    systid;    /* OS type */
+    unsigned char    endhead;   /* ending head, sector, cylinder */
+    unsigned char    endsect;   /* endcyl is a 10-bit number */
+    unsigned char    endcyl;    /* High 2 bits are in endsect */
+    unsigned long    relsect;   /* partion physical offset on disk */
+    unsigned long    numsect;   /* number of sectors in partition */
+};
+
+/*
+ * Format of boot block.
+ */
+struct disk_blk0 {
+    unsigned char    bootcode[DISK_BOOTSZ];
+    unsigned char    parts[FDISK_NPART][sizeof (struct fdisk_part)];
+    unsigned short   signature;
+};
+
+#endif /* !__LIBSAIO_FDISK_H */
diff --git a/i386/libsaio/gets.c b/i386/libsaio/gets.c
deleted file mode 100644 (file)
index a47c70f..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License").  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright 1993, NeXT Computer Inc.
- * All rights reserved.
- */
-
-#include "libsaio.h"
-
-int gets( char * buf, int len )
-{
-       char *lp = buf, *end = buf + len - 1;
-       int c;
-
-       flushdev();             // XXX
-
-       for (;;) {
-               c = getchar() & 0x7f;
-               if (c < ' ' && c != '\n' && c != '\b') c = 0;
-               if (c == 0x7f) c = '\b';
-
-               switch(c)
-        {
-            case '\0':
-                continue;
-            case '\n':
-                *lp++ = '\0';
-                putchar('\n');
-                return 1;
-            case '\b':
-                if (lp > buf) {
-                    lp--;
-                    putchar('\b');
-                    putchar(' ');
-                    putchar('\b');
-                }
-                continue;
-            default:
-                if (lp < end)
-                    *lp++ = c;
-                else
-                {
-                    putchar('\b');
-                    putchar(' ');
-                    putchar('\b');
-                    putchar('\007');
-                }
-        }
-       }
-}
-
-/*
- * Return a string in buf if typing has begun within timeout units.
- */
-int 
-Gets( char * buf,
-      int    len,
-      int    timeout,
-      char * prompt,
-      char * message )
-{
-       int     ch = 0;
-       int     next_second;
-
-       flushdev();  // XXX
-
-       printf("%s", prompt);
-
-       if (message)
-           printf("%s", message);
-
-       if (timeout)
-    {          
-           for ( next_second = time18() + 18; timeout; )
-        {
-            if (ch = readKeyboardStatus())
-            {
-                break;
-            }
-            if ( time18() >= next_second )
-            {
-                next_second += 18;
-                timeout--;
-            }
-        }
-    
-        if (ch == 0)
-        {
-            printf("\n");
-            return 0;
-        }
-       }
-       return ( gets(buf, len) );
-}
diff --git a/i386/libsaio/hfs.c b/i386/libsaio/hfs.c
new file mode 100644 (file)
index 0000000..939d208
--- /dev/null
@@ -0,0 +1,884 @@
+/*
+ * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License").  You may not use this file except in compliance with the
+ * License.  Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
+ * 
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ *  hfs.c - File System Module for HFS and HFS+.
+ *
+ *  Copyright (c) 1999-2002 Apple Computer, Inc.
+ *
+ *  DRI: Josh de Cesare
+ */
+
+#include <sl.h>
+#include <hfs/hfs_format.h>
+
+#define kBlockSize (0x200)
+
+#define kMDBBaseOffset (2 * kBlockSize)
+
+#define kBTreeCatalog (0)
+#define kBTreeExtents (1)
+
+#ifdef __i386__
+
+static CICell                  gCurrentIH;
+static long long               gAllocationOffset;
+static long                    gIsHFSPlus;
+static long                    gBlockSize;
+static long                    gCacheBlockSize;
+static char                    *gBTreeHeaderBuffer;
+static BTHeaderRec             *gBTHeaders[2];
+static char                    *gHFSMdbVib;
+static HFSMasterDirectoryBlock *gHFSMDB;
+static char                    *gHFSPlusHeader;
+static HFSPlusVolumeHeader     *gHFSPlus;
+static char                    *gLinkTemp;
+static char                    *gTempStr;
+
+#else  /* !__i386__ */
+
+static CICell                  gCurrentIH;
+static long long               gAllocationOffset;
+static long                    gIsHFSPlus;
+static long                    gBlockSize;
+static long                    gCacheBlockSize;
+static char                    gBTreeHeaderBuffer[512];
+static BTHeaderRec             *gBTHeaders[2];
+static char                    gHFSMdbVib[kBlockSize];
+static HFSMasterDirectoryBlock *gHFSMDB =(HFSMasterDirectoryBlock*)gHFSMdbVib;
+static char                    gHFSPlusHeader[kBlockSize];
+static HFSPlusVolumeHeader     *gHFSPlus =(HFSPlusVolumeHeader*)gHFSPlusHeader;
+static char                    gLinkTemp[64];
+
+#endif /* !__i386__ */
+
+static long ReadFile(void *file, long *length);
+static long GetCatalogEntryInfo(void *entry, long *flags, long *time);
+static long ResolvePathToCatalogEntry(char *filePath, long *flags,
+                void *entry, long dirID, long *dirIndex);
+
+static long GetCatalogEntry(long *dirIndex, char **name,
+                long *flags, long *time);
+static long ReadCatalogEntry(char *fileName, long dirID, void *entry,
+                long *dirIndex);
+static long ReadExtentsEntry(long fileID, long startBlock, void *entry);
+
+static long ReadBTreeEntry(long btree, void *key, char *entry, long *dirIndex);
+static void GetBTreeRecord(long index, char *nodeBuffer, long nodeSize,
+                char **key, char **data);
+
+static long ReadExtent(char *extent, long extentSize, long extentFile,
+                long offset, long size, void *buffer, long cache);
+
+static long GetExtentStart(void *extents, long index);
+static long GetExtentSize(void *extents, long index);
+
+static long CompareHFSCatalogKeys(void *key, void *testKey);
+static long CompareHFSPlusCatalogKeys(void *key, void *testKey);
+static long CompareHFSExtentsKeys(void *key, void *testKey);
+static long CompareHFSPlusExtentsKeys(void *key, void *testKey);
+
+extern long FastRelString(char *str1, char *str2);
+extern long FastUnicodeCompare(u_int16_t *uniStr1, u_int32_t len1,
+                u_int16_t *uniStr2, u_int32_t len2);
+extern void utf_encodestr(const u_int16_t *ucsp, int ucslen,
+                u_int8_t *utf8p, u_int32_t bufsize);
+extern void utf_decodestr(const u_int8_t *utf8p, u_int16_t *ucsp,
+                u_int16_t *ucslen, u_int32_t bufsize);
+
+
+long HFSInitPartition(CICell ih)
+{
+    long extentSize, extentFile, nodeSize;
+    void *extent;
+
+    if (ih == gCurrentIH) {
+#ifdef __i386__
+        CacheInit(ih, gCacheBlockSize);
+#endif
+        return 0;
+    }
+
+    verbose("HFSInitPartition: %x\n", ih);
+
+#ifdef __i386__
+    if (!gTempStr) gTempStr = (char *)malloc(4096);
+    if (!gLinkTemp) gLinkTemp = (char *)malloc(64);
+    if (!gBTreeHeaderBuffer) gBTreeHeaderBuffer = (char *)malloc(512);
+    if (!gHFSMdbVib) {
+        gHFSMdbVib = (char *)malloc(kBlockSize);
+        gHFSMDB = (HFSMasterDirectoryBlock *)gHFSMdbVib;
+    }
+    if (!gHFSPlusHeader) {
+        gHFSPlusHeader = (char *)malloc(kBlockSize);
+        gHFSPlus = (HFSPlusVolumeHeader *)gHFSPlusHeader;
+    }
+    if (!gTempStr || !gLinkTemp || !gBTreeHeaderBuffer ||
+        !gHFSMdbVib || !gHFSPlusHeader) return -1;
+#endif /* __i386__ */
+
+    gAllocationOffset = 0;
+    gIsHFSPlus = 0;
+    gBTHeaders[0] = 0;
+    gBTHeaders[1] = 0;
+
+    // Look for the HFS MDB
+    Seek(ih, kMDBBaseOffset);
+    Read(ih, (long)gHFSMdbVib, kBlockSize);
+
+    if ( SWAP_BE16(gHFSMDB->drSigWord) == kHFSSigWord ) {
+        gAllocationOffset = SWAP_BE16(gHFSMDB->drAlBlSt) * kBlockSize;
+
+        // See if it is HFSPlus
+        if (SWAP_BE16(gHFSMDB->drEmbedSigWord) != kHFSPlusSigWord) {
+            // Normal HFS;
+            gCacheBlockSize = gBlockSize = SWAP_BE32(gHFSMDB->drAlBlkSiz);
+            CacheInit(ih, gCacheBlockSize);
+            gCurrentIH = ih;
+
+            // Get the Catalog BTree node size.
+            extent     = (HFSExtentDescriptor *)&gHFSMDB->drCTExtRec;
+            extentSize = SWAP_BE32(gHFSMDB->drCTFlSize);
+            extentFile = kHFSCatalogFileID;
+            ReadExtent(extent, extentSize, extentFile, 0, 256,
+                       gBTreeHeaderBuffer + kBTreeCatalog * 256, 0);
+
+            nodeSize = SWAP_BE16(((BTHeaderRec *)(gBTreeHeaderBuffer + kBTreeCatalog * 256 + 
+                                 sizeof(BTNodeDescriptor)))->nodeSize);
+
+            // If the BTree node size is larger than the block size, reset the cache.
+            if (nodeSize > gBlockSize) {
+                gCacheBlockSize = nodeSize;
+                CacheInit(ih, gCacheBlockSize);
+            }
+
+            return 0;
+        }
+
+        // Calculate the offset to the embeded HFSPlus volume.
+        gAllocationOffset += (long long)SWAP_BE16(gHFSMDB->drEmbedExtent.startBlock) *
+                                        SWAP_BE32(gHFSMDB->drAlBlkSiz);
+    }
+
+    // Look for the HFSPlus Header
+    Seek(ih, gAllocationOffset + kMDBBaseOffset);
+    Read(ih, (long)gHFSPlusHeader, kBlockSize);
+
+    // Not a HFS[+] volume.
+    if (SWAP_BE16(gHFSPlus->signature) != kHFSPlusSigWord) return -1;
+
+    gIsHFSPlus = 1;
+    gCacheBlockSize = gBlockSize = SWAP_BE32(gHFSPlus->blockSize);
+    CacheInit(ih, gCacheBlockSize);
+    gCurrentIH = ih;
+
+    // Get the Catalog BTree node size.
+    extent     = &gHFSPlus->catalogFile.extents;
+    extentSize = SWAP_BE64(gHFSPlus->catalogFile.logicalSize);
+    extentFile = kHFSCatalogFileID;
+
+    ReadExtent(extent, extentSize, extentFile, 0, 256,
+               gBTreeHeaderBuffer + kBTreeCatalog * 256, 0);
+
+    nodeSize = SWAP_BE16(((BTHeaderRec *)(gBTreeHeaderBuffer + kBTreeCatalog * 256 +
+                         sizeof(BTNodeDescriptor)))->nodeSize);
+
+    // If the BTree node size is larger than the block size, reset the cache.
+    if (nodeSize > gBlockSize) {
+        gCacheBlockSize = nodeSize;
+        CacheInit(ih, gCacheBlockSize);
+    }
+
+    return 0;
+}
+
+long HFSLoadFile(CICell ih, char * filePath)
+{
+    char entry[512];
+    long dirID, result, length, flags;
+
+    if (HFSInitPartition(ih) == -1) return -1;
+
+    verbose("Loading HFS%s file: [%s] from %x.\n",
+            (gIsHFSPlus ? "+" : ""), filePath, ih);
+
+    dirID = kHFSRootFolderID;
+    // Skip a lead '\'.  Start in the system folder if there are two.
+    if (filePath[0] == '/') {
+        if (filePath[1] == '/') {
+            if (gIsHFSPlus) dirID = SWAP_BE32(((long *)gHFSPlus->finderInfo)[5]);
+            else dirID = SWAP_BE32(gHFSMDB->drFndrInfo[5]);
+            if (dirID == 0) return -1;
+            filePath++;
+        }
+        filePath++;
+    }
+
+    result = ResolvePathToCatalogEntry(filePath, &flags, entry, dirID, 0);
+    if ((result == -1) || ((flags & kFileTypeMask) != kFileTypeFlat)) return -1;
+
+#if 0 // Not yet for Intel. System.config/Default.table will fail this check.
+    // Check file owner and permissions.
+    if (flags & (kOwnerNotRoot | kPermGroupWrite | kPermOtherWrite)) return -1;
+#endif
+
+    result = ReadFile(entry, &length);
+    if (result == -1) return -1;
+
+    return length;
+}
+
+long HFSGetDirEntry(CICell ih, char * dirPath, long * dirIndex, char ** name,
+                    long * flags, long * time)
+{
+    char entry[512];
+    long dirID, dirFlags;
+
+    if (HFSInitPartition(ih) == -1) return -1;
+
+    if (*dirIndex == -1) return -1;
+
+    dirID = kHFSRootFolderID;
+    // Skip a lead '\'.  Start in the system folder if there are two.
+    if (dirPath[0] == '/') {
+        if (dirPath[1] == '/') {
+            if (gIsHFSPlus) dirID = SWAP_BE32(((long *)gHFSPlus->finderInfo)[5]);
+            else dirID = SWAP_BE32(gHFSMDB->drFndrInfo[5]);
+            if (dirID == 0) return -1;
+            dirPath++;
+        }
+        dirPath++;
+    }
+
+    if (*dirIndex == 0) {
+        ResolvePathToCatalogEntry(dirPath, &dirFlags, entry, dirID, dirIndex);
+        if (*dirIndex == 0) *dirIndex = -1;
+        if ((dirFlags & kFileTypeMask) != kFileTypeUnknown) return -1;
+    }
+
+    GetCatalogEntry(dirIndex, name, flags, time);
+    if (*dirIndex == 0) *dirIndex = -1;
+    if ((*flags & kFileTypeMask) == kFileTypeUnknown) return -1;
+
+    return 0;
+}
+
+// Private Functions
+
+static long ReadFile(void * file, long * length)
+{
+    void               *extents;
+    long               fileID;
+    HFSCatalogFile     *hfsFile     = file;
+    HFSPlusCatalogFile *hfsPlusFile = file;
+
+    if (gIsHFSPlus) {
+        fileID  = SWAP_BE32(hfsPlusFile->fileID);
+        *length = SWAP_BE64(hfsPlusFile->dataFork.logicalSize);
+        extents = &hfsPlusFile->dataFork.extents;
+    } else {
+        fileID  = SWAP_BE32(hfsFile->fileID);
+        *length = SWAP_BE32(hfsFile->dataLogicalSize);
+        extents = &hfsFile->dataExtents;
+    }
+
+    if (*length > kLoadSize) {
+        printf("File is too large.\n");
+        return -1;
+    }
+
+#ifdef __i386__
+    *length = ReadExtent((char *)extents, *length, fileID,
+                         0, *length, (char *)gFSLoadAddress, 0);
+#else
+    *length = ReadExtent((char *)extents, *length, fileID,
+                         0, *length, (char *)kLoadAddr, 0);
+#endif
+
+    return 0;
+}
+
+static long GetCatalogEntryInfo(void * entry, long * flags, long * time)
+{
+    long tmpTime = 0;
+
+    // Get information about the file.
+    
+    switch ( SWAP_BE16(*(short *)entry) )
+    {
+        case kHFSFolderRecord           :
+            *flags = kFileTypeDirectory;
+            tmpTime = SWAP_BE32(((HFSCatalogFolder *)entry)->modifyDate);
+            break;
+
+        case kHFSPlusFolderRecord       :
+            *flags = kFileTypeDirectory |
+                     (SWAP_BE16(((HFSPlusCatalogFolder *)entry)->bsdInfo.fileMode) & kPermMask);
+            if (SWAP_BE32(((HFSPlusCatalogFolder *)entry)->bsdInfo.ownerID) != 0)
+                *flags |= kOwnerNotRoot;
+            tmpTime = SWAP_BE32(((HFSPlusCatalogFolder *)entry)->contentModDate);
+            break;
+
+        case kHFSFileRecord             :
+            *flags = kFileTypeFlat;
+            tmpTime = SWAP_BE32(((HFSCatalogFile *)entry)->modifyDate);
+            break;
+
+        case kHFSPlusFileRecord         :
+            *flags = kFileTypeFlat |
+                     (SWAP_BE16(((HFSPlusCatalogFile *)entry)->bsdInfo.fileMode) & kPermMask);
+            if (SWAP_BE32(((HFSPlusCatalogFile *)entry)->bsdInfo.ownerID) != 0)
+                *flags |= kOwnerNotRoot;
+            tmpTime = SWAP_BE32(((HFSPlusCatalogFile *)entry)->contentModDate);
+            break;
+
+        case kHFSFileThreadRecord       :
+        case kHFSPlusFileThreadRecord   :
+        case kHFSFolderThreadRecord     :
+        case kHFSPlusFolderThreadRecord :
+            *flags = kFileTypeUnknown;
+            tmpTime = 0;
+            break;
+    }
+
+    if (time != 0) {
+        // Convert base time from 1904 to 1970.
+        *time = tmpTime - 2082844800;
+    }
+
+    return 0;
+}
+
+static long ResolvePathToCatalogEntry(char * filePath, long * flags,
+                                      void * entry, long dirID, long * dirIndex)
+{
+    char                 *restPath;
+    long                 result, cnt, subFolderID, tmpDirIndex;
+    HFSPlusCatalogFile   *hfsPlusFile;
+
+    // Copy the file name to gTempStr
+    cnt = 0;
+    while ((filePath[cnt] != '/') && (filePath[cnt] != '\0')) cnt++;
+    strncpy(gTempStr, filePath, cnt);
+
+    // Move restPath to the right place.
+    if (filePath[cnt] != '\0') cnt++;
+    restPath = filePath + cnt;
+
+    // gTempStr is a name in the current Dir.
+    // restPath is the rest of the path if any.
+
+    result = ReadCatalogEntry(gTempStr, dirID, entry, dirIndex);
+    if (result == -1) return -1;
+
+    GetCatalogEntryInfo(entry, flags, 0);
+
+    if ((*flags & kFileTypeMask) == kFileTypeDirectory) {
+        if (gIsHFSPlus)
+            subFolderID = SWAP_BE32(((HFSPlusCatalogFolder *)entry)->folderID);
+        else
+            subFolderID = SWAP_BE32(((HFSCatalogFolder *)entry)->folderID);
+
+        result = ResolvePathToCatalogEntry(restPath, flags, entry,
+                                           subFolderID, dirIndex);
+    }
+
+    if (gIsHFSPlus && ((*flags & kFileTypeMask) == kFileTypeFlat)) {
+        hfsPlusFile = (HFSPlusCatalogFile *)entry;
+        if ((SWAP_BE32(hfsPlusFile->userInfo.fdType) == kHardLinkFileType) &&
+            (SWAP_BE32(hfsPlusFile->userInfo.fdCreator) == kHFSPlusCreator)) {
+                sprintf(gLinkTemp, "%s/%s%ld", HFSPLUSMETADATAFOLDER,
+                        HFS_INODE_PREFIX, SWAP_BE32(hfsPlusFile->bsdInfo.special.iNodeNum));
+                result = ResolvePathToCatalogEntry(gLinkTemp, flags, entry,
+                                                   kHFSRootFolderID, &tmpDirIndex);
+        }
+    }
+
+    return result;
+}
+
+static long GetCatalogEntry(long * dirIndex, char ** name,
+                            long * flags, long * time)
+{
+    long              extentSize, nodeSize, curNode, index;
+    void              *extent;
+    char              *nodeBuf, *testKey, *entry;
+    BTNodeDescriptor  *node;
+
+    if (gIsHFSPlus) {
+        extent     = &gHFSPlus->catalogFile.extents;
+        extentSize = SWAP_BE64(gHFSPlus->catalogFile.logicalSize);
+    } else {
+        extent     = (HFSExtentDescriptor *)&gHFSMDB->drCTExtRec;
+        extentSize = SWAP_BE32(gHFSMDB->drCTFlSize);
+    }
+
+    nodeSize = SWAP_BE16(gBTHeaders[kBTreeCatalog]->nodeSize);
+    nodeBuf  = (char *)malloc(nodeSize);
+    node     = (BTNodeDescriptor *)nodeBuf;
+
+    index   = *dirIndex % nodeSize;
+    curNode = *dirIndex / nodeSize;
+
+    // Read the BTree node and get the record for index.
+    ReadExtent(extent, extentSize, kHFSCatalogFileID,
+               curNode * nodeSize, nodeSize, nodeBuf, 1);
+    GetBTreeRecord(index, nodeBuf, nodeSize, &testKey, &entry);
+
+    GetCatalogEntryInfo(entry, flags, time);
+
+    // Get the file name.
+    if (gIsHFSPlus) {
+        utf_encodestr(((HFSPlusCatalogKey *)testKey)->nodeName.unicode,
+                      SWAP_BE16(((HFSPlusCatalogKey *)testKey)->nodeName.length),
+                      gTempStr, 256);
+    } else {
+        strncpy(gTempStr,
+                &((HFSCatalogKey *)testKey)->nodeName[1],
+                 ((HFSCatalogKey *)testKey)->nodeName[0]);
+    }
+    *name = gTempStr;
+
+    // Update dirIndex.
+    index++;
+    if (index == SWAP_BE16(node->numRecords)) {
+        index = 0;
+        curNode = SWAP_BE32(node->fLink);
+    }
+    *dirIndex = curNode * nodeSize + index;
+
+    free(nodeBuf);
+
+    return 0;
+}
+
+static long ReadCatalogEntry(char * fileName, long dirID,
+                             void * entry,    long * dirIndex)
+{
+    long              length;
+    char              key[sizeof(HFSPlusCatalogKey)];
+    HFSCatalogKey     *hfsKey     = (HFSCatalogKey *)key;
+    HFSPlusCatalogKey *hfsPlusKey = (HFSPlusCatalogKey *)key;
+  
+    // Make the catalog key.
+    if ( gIsHFSPlus )
+    {
+        hfsPlusKey->parentID = SWAP_BE32(dirID);
+        length = strlen(fileName);
+        if (length > 255) length = 255;
+        utf_decodestr(fileName, hfsPlusKey->nodeName.unicode,
+                      &(hfsPlusKey->nodeName.length), 512);
+    } else {
+        hfsKey->parentID = SWAP_BE32(dirID);
+        length = strlen(fileName);
+        if (length > 31) length = 31;
+        hfsKey->nodeName[0] = length;
+        strncpy(hfsKey->nodeName + 1, fileName, length);
+    }
+
+    return ReadBTreeEntry(kBTreeCatalog, &key, entry, dirIndex);
+}
+
+static long ReadExtentsEntry(long fileID, long startBlock, void * entry)
+{
+    char             key[sizeof(HFSPlusExtentKey)];
+    HFSExtentKey     *hfsKey     = (HFSExtentKey *)key;
+    HFSPlusExtentKey *hfsPlusKey = (HFSPlusExtentKey *)key;
+
+    // Make the extents key.
+    if (gIsHFSPlus) {
+        hfsPlusKey->forkType   = 0;
+        hfsPlusKey->fileID     = SWAP_BE32(fileID);
+        hfsPlusKey->startBlock = SWAP_BE32(startBlock);
+    } else {
+        hfsKey->forkType   = 0;
+        hfsKey->fileID     = SWAP_BE32(fileID);
+        hfsKey->startBlock = SWAP_BE16(startBlock);
+    }
+
+    return ReadBTreeEntry(kBTreeExtents, &key, entry, 0);
+}
+
+static long ReadBTreeEntry(long btree, void * key, char * entry, long * dirIndex)
+{
+    long             extentSize;
+    void             *extent;
+    short            extentFile;
+    char             *nodeBuf;
+    BTNodeDescriptor *node;
+    long             nodeSize, result = 0, entrySize = 0;
+    long             curNode, index = 0, lowerBound, upperBound;
+    char             *testKey, *recordData;
+
+    // Figure out which tree is being looked at.
+    if (btree == kBTreeCatalog) {
+        if (gIsHFSPlus) {
+            extent     = &gHFSPlus->catalogFile.extents;
+            extentSize = SWAP_BE64(gHFSPlus->catalogFile.logicalSize);
+        } else {
+            extent     = (HFSExtentDescriptor *)&gHFSMDB->drCTExtRec;
+            extentSize = SWAP_BE32(gHFSMDB->drCTFlSize);
+        }
+        extentFile = kHFSCatalogFileID;
+    } else {
+        if (gIsHFSPlus) {
+            extent     = &gHFSPlus->extentsFile.extents;
+            extentSize = SWAP_BE64(gHFSPlus->extentsFile.logicalSize);
+        } else {
+            extent     = (HFSExtentDescriptor *)&gHFSMDB->drXTExtRec;
+            extentSize = SWAP_BE32(gHFSMDB->drXTFlSize);
+        }
+        extentFile = kHFSExtentsFileID;
+    }
+
+    // Read the BTree Header if needed.
+    if (gBTHeaders[btree] == 0) {
+        ReadExtent(extent, extentSize, extentFile, 0, 256,
+                   gBTreeHeaderBuffer + btree * 256, 0);
+        gBTHeaders[btree] = (BTHeaderRec *)(gBTreeHeaderBuffer + btree * 256 +
+                                            sizeof(BTNodeDescriptor));
+    }
+
+    curNode  = SWAP_BE32(gBTHeaders[btree]->rootNode);
+    nodeSize = SWAP_BE16(gBTHeaders[btree]->nodeSize);
+    nodeBuf  = (char *)malloc(nodeSize);
+    node     = (BTNodeDescriptor *)nodeBuf;
+
+    while (1) {
+        // Read the current node.
+        ReadExtent(extent, extentSize, extentFile,
+                   curNode * nodeSize, nodeSize, nodeBuf, 1);
+    
+        // Find the matching key.
+        lowerBound = 0;
+        upperBound = SWAP_BE16(node->numRecords) - 1;
+        while (lowerBound <= upperBound) {
+            index = (lowerBound + upperBound) / 2;
+
+            GetBTreeRecord(index, nodeBuf, nodeSize, &testKey, &recordData);
+
+            if (gIsHFSPlus) {
+                if (btree == kBTreeCatalog) {
+                    result = CompareHFSPlusCatalogKeys(key, testKey);
+                } else {
+                    result = CompareHFSPlusExtentsKeys(key, testKey);
+                }
+            } else {
+                if (btree == kBTreeCatalog) {
+                    result = CompareHFSCatalogKeys(key, testKey);
+                } else {
+                    result = CompareHFSExtentsKeys(key, testKey);
+                }
+            }
+      
+            if (result < 0) upperBound = index - 1;        // search < trial
+            else if (result > 0) lowerBound = index + 1;   // search > trial
+            else break;                                    // search = trial
+        }
+    
+        if (result < 0) {
+            index = upperBound;
+            GetBTreeRecord(index, nodeBuf, nodeSize, &testKey, &recordData);
+        }
+    
+        // Found the closest key... Recurse on it if this is an index node.
+        if (node->kind == kBTIndexNode) {
+            curNode = SWAP_BE32( *((long *)recordData) );
+        } else break;
+    }
+  
+    // Return error if the file was not found.
+    if (result != 0) { free(nodeBuf); return -1; }
+
+    if (btree == kBTreeCatalog) {
+        switch (SWAP_BE16(*(short *)recordData)) {
+            case kHFSFolderRecord           : entrySize = 70;  break;
+            case kHFSFileRecord             : entrySize = 102; break;
+            case kHFSFolderThreadRecord     : entrySize = 46;  break;
+            case kHFSFileThreadRecord       : entrySize = 46;  break;
+            case kHFSPlusFolderRecord       : entrySize = 88;  break;
+            case kHFSPlusFileRecord         : entrySize = 248; break;
+            case kHFSPlusFolderThreadRecord : entrySize = 264; break;
+            case kHFSPlusFileThreadRecord   : entrySize = 264; break;
+        }
+    } else {
+        if (gIsHFSPlus) entrySize = sizeof(HFSPlusExtentRecord);
+        else entrySize = sizeof(HFSExtentRecord);
+    }
+  
+    bcopy(recordData, entry, entrySize);
+
+    // Update dirIndex.
+    if (dirIndex != 0) {
+        index++;
+        if (index == SWAP_BE16(node->numRecords)) {
+            index = 0;
+            curNode = SWAP_BE32(node->fLink);
+        }
+        *dirIndex = curNode * nodeSize + index;
+    }
+  
+    free(nodeBuf);
+  
+    return 0;
+}
+
+static void GetBTreeRecord(long index, char * nodeBuffer, long nodeSize,
+                           char ** key, char ** data)
+{
+    long keySize;
+    long recordOffset;
+  
+    recordOffset = SWAP_BE16(*((short *)(nodeBuffer + (nodeSize - 2 * index - 2))));
+    *key = nodeBuffer + recordOffset;
+    if (gIsHFSPlus) {
+        keySize = SWAP_BE16(*(short *)*key);
+        *data = *key + 2 + keySize;
+    } else {
+        keySize = **key;
+        *data = *key + 2 + keySize - (keySize & 1);
+    }
+}
+
+static long ReadExtent(char * extent, long extentSize,
+                       long extentFile, long offset, long size,
+                       void * buffer, long cache)
+{
+    long      lastOffset, blockNumber, countedBlocks = 0;
+    long      nextExtent = 0, sizeRead = 0, readSize;
+    long      nextExtentBlock, currentExtentBlock = 0;
+    long long readOffset;
+    long      extentDensity, sizeofExtent, currentExtentSize;
+    char      *currentExtent, *extentBuffer = 0, *bufferPos = buffer;
+
+    if (offset >= extentSize) return 0;
+
+    if (gIsHFSPlus) {
+        extentDensity = kHFSPlusExtentDensity;
+        sizeofExtent  = sizeof(HFSPlusExtentDescriptor);
+    } else {
+        extentDensity = kHFSExtentDensity;
+        sizeofExtent  = sizeof(HFSExtentDescriptor);
+    }
+
+    lastOffset = offset + size;
+    while (offset < lastOffset) {
+        blockNumber = offset / gBlockSize;
+
+        // Find the extent for the offset.
+        for (; ; nextExtent++) {
+            if (nextExtent < extentDensity) {
+                if ((countedBlocks+GetExtentSize(extent, nextExtent)-1)<blockNumber) {
+                    countedBlocks += GetExtentSize(extent, nextExtent);
+                    continue;
+                }
+
+                currentExtent = extent + nextExtent * sizeofExtent;
+                break;
+            }
+
+            if (extentBuffer == 0) {
+                extentBuffer = malloc(sizeofExtent * extentDensity);
+                if (extentBuffer == 0) return -1;
+            }
+
+            nextExtentBlock = nextExtent / extentDensity;
+            if (currentExtentBlock != nextExtentBlock) {
+                ReadExtentsEntry(extentFile, countedBlocks, extentBuffer);
+                currentExtentBlock = nextExtentBlock;
+            }
+
+            currentExtentSize = GetExtentSize(extentBuffer, nextExtent % extentDensity);
+
+            if ((countedBlocks + currentExtentSize - 1) >= blockNumber) {
+                currentExtent = extentBuffer + sizeofExtent * (nextExtent % extentDensity);
+                break;
+            }
+      
+            countedBlocks += currentExtentSize;
+        }
+
+        readOffset = ((blockNumber - countedBlocks) * gBlockSize) +
+                     (offset % gBlockSize);
+    
+        readSize = GetExtentSize(currentExtent, 0) * gBlockSize - readOffset;
+        if (readSize > (size - sizeRead)) readSize = size - sizeRead;
+
+        readOffset += (long long)GetExtentStart(currentExtent, 0) * gBlockSize;
+    
+        CacheRead(gCurrentIH, bufferPos, gAllocationOffset + readOffset,
+                  readSize, cache);
+
+        sizeRead += readSize;
+        offset += readSize;
+        bufferPos += readSize;
+    }
+
+    if (extentBuffer) free(extentBuffer);
+
+    return sizeRead;
+}
+
+static long GetExtentStart(void * extents, long index)
+{
+    long                    start;
+    HFSExtentDescriptor     *hfsExtents     = extents;
+    HFSPlusExtentDescriptor *hfsPlusExtents = extents;
+
+    if (gIsHFSPlus) start = SWAP_BE32(hfsPlusExtents[index].startBlock);
+    else start = SWAP_BE16(hfsExtents[index].startBlock);
+
+    return start;
+}
+
+static long GetExtentSize(void * extents, long index)
+{
+    long                    size;
+    HFSExtentDescriptor     *hfsExtents     = extents;
+    HFSPlusExtentDescriptor *hfsPlusExtents = extents;
+  
+    if (gIsHFSPlus) size = SWAP_BE32(hfsPlusExtents[index].blockCount);
+    else size = SWAP_BE16(hfsExtents[index].blockCount);
+
+    return size;
+}
+
+static long CompareHFSCatalogKeys(void * key, void * testKey)
+{
+    HFSCatalogKey *searchKey, *trialKey;
+    long          result, searchParentID, trialParentID;
+
+    searchKey = key;
+    trialKey  = testKey;
+
+    searchParentID = SWAP_BE32(searchKey->parentID);
+    trialParentID  = SWAP_BE32(trialKey->parentID);
+
+    // parent dirID is unsigned
+    if (searchParentID > trialParentID)      result = 1;
+    else if (searchParentID < trialParentID) result = -1;
+    else {
+        // parent dirID's are equal, compare names
+        result = FastRelString(searchKey->nodeName, trialKey->nodeName);
+    }
+
+    return result;
+}
+
+static long CompareHFSPlusCatalogKeys(void * key, void * testKey)
+{
+    HFSPlusCatalogKey *searchKey, *trialKey;
+    long              result, searchParentID, trialParentID;
+  
+    searchKey = key;
+    trialKey  = testKey;
+  
+    searchParentID = SWAP_BE32(searchKey->parentID);
+    trialParentID  = SWAP_BE32(trialKey->parentID);
+
+    // parent dirID is unsigned
+    if (searchParentID > trialParentID)      result = 1;
+    else if (searchParentID < trialParentID) result = -1;
+    else {
+        // parent dirID's are equal, compare names
+        if ((searchKey->nodeName.length == 0) || (trialKey->nodeName.length == 0))
+            result = searchKey->nodeName.length - trialKey->nodeName.length;
+        else
+            result = FastUnicodeCompare(&searchKey->nodeName.unicode[0],
+                                        SWAP_BE16(searchKey->nodeName.length),
+                                        &trialKey->nodeName.unicode[0],
+                                        SWAP_BE16(trialKey->nodeName.length));
+    }
+
+    return result;
+}
+
+static long CompareHFSExtentsKeys(void * key, void * testKey)
+{
+    HFSExtentKey *searchKey, *trialKey;
+    long         result;
+  
+    searchKey = key;
+    trialKey  = testKey;
+  
+    // assume searchKey < trialKey
+    result = -1;            
+
+    if (searchKey->fileID == trialKey->fileID) {
+        // FileNum's are equal; compare fork types
+        if (searchKey->forkType == trialKey->forkType) {
+            // Fork types are equal; compare allocation block number
+            if (searchKey->startBlock == trialKey->startBlock) {
+                // Everything is equal
+                result = 0;
+            } else {
+                // Allocation block numbers differ; determine sign
+                if (SWAP_BE16(searchKey->startBlock) > SWAP_BE16(trialKey->startBlock))
+                    result = 1;
+            }
+        } else {
+            // Fork types differ; determine sign
+            if (searchKey->forkType > trialKey->forkType) result = 1;
+        }
+    } else {
+        // FileNums differ; determine sign
+        if (SWAP_BE32(searchKey->fileID) > SWAP_BE32(trialKey->fileID))
+            result = 1;
+    }
+
+    return result;
+}
+
+static long CompareHFSPlusExtentsKeys(void * key, void * testKey)
+{
+    HFSPlusExtentKey *searchKey, *trialKey;
+    long             result;
+  
+    searchKey = key;
+    trialKey  = testKey;
+  
+    // assume searchKey < trialKey
+    result = -1;            
+  
+    if (searchKey->fileID == trialKey->fileID) {
+        // FileNum's are equal; compare fork types
+        if (searchKey->forkType == trialKey->forkType) {
+            // Fork types are equal; compare allocation block number
+            if (searchKey->startBlock == trialKey->startBlock) {
+                // Everything is equal
+                result = 0;
+            } else {
+                // Allocation block numbers differ; determine sign
+                if (SWAP_BE32(searchKey->startBlock) > SWAP_BE32(trialKey->startBlock))
+                    result = 1;
+            }
+        } else {
+            // Fork types differ; determine sign
+            if (searchKey->forkType > trialKey->forkType) result = 1;
+        }
+    } else {
+        // FileNums differ; determine sign
+        if (SWAP_BE32(searchKey->fileID) > SWAP_BE32(trialKey->fileID))
+            result = 1;
+    }
+
+    return result;
+}
diff --git a/i386/libsaio/hfs_CaseTables.h b/i386/libsaio/hfs_CaseTables.h
new file mode 100644 (file)
index 0000000..d4691b6
--- /dev/null
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License").  You may not use this file except in compliance with the
+ * License.  Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
+ * 
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+       File:   CaseTables.h
+*/
+
+
+/*     The lower case table consists of a 256-entry high-byte table followed by some number of
+       256-entry subtables. The high-byte table contains either an offset to the subtable for
+       characters with that high byte or zero, which means that there are no case mappings or
+       ignored characters in that block. Ignored characters are mapped to zero.
+ */
+
+u_int16_t gLowerCaseTable[] = {
+
+       // High-byte indices ( == 0 iff no case mapping and no ignorables )
+
+       /* 0 */ 0x0100, 0x0200, 0x0000, 0x0300, 0x0400, 0x0500, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       /* 1 */ 0x0600, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       /* 2 */ 0x0700, 0x0800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       /* 3 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       /* 4 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       /* 5 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       /* 6 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       /* 7 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       /* 8 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       /* 9 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       /* A */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       /* B */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       /* C */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       /* D */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       /* E */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       /* F */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0900, 0x0A00,
+
+       // Table 1 (for high byte 0x00)
+
+       /* 0 */ 0xFFFF, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
+       /* 1 */ 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
+       /* 2 */ 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
+       /* 3 */ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
+       /* 4 */ 0x0040, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
+       /* 5 */ 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
+       /* 6 */ 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
+       /* 7 */ 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
+       /* 8 */ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+       /* 9 */ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+       /* A */ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+       /* B */ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
+       /* C */ 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00E6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
+       /* D */ 0x00F0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 0x00F8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00FE, 0x00DF,
+       /* E */ 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
+       /* F */ 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF,
+
+       // Table 2 (for high byte 0x01)
+
+       /* 0 */ 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, 0x0107, 0x0108, 0x0109, 0x010A, 0x010B, 0x010C, 0x010D, 0x010E, 0x010F,
+       /* 1 */ 0x0111, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116, 0x0117, 0x0118, 0x0119, 0x011A, 0x011B, 0x011C, 0x011D, 0x011E, 0x011F,
+       /* 2 */ 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0127, 0x0127, 0x0128, 0x0129, 0x012A, 0x012B, 0x012C, 0x012D, 0x012E, 0x012F,
+       /* 3 */ 0x0130, 0x0131, 0x0133, 0x0133, 0x0134, 0x0135, 0x0136, 0x0137, 0x0138, 0x0139, 0x013A, 0x013B, 0x013C, 0x013D, 0x013E, 0x0140,
+       /* 4 */ 0x0140, 0x0142, 0x0142, 0x0143, 0x0144, 0x0145, 0x0146, 0x0147, 0x0148, 0x0149, 0x014B, 0x014B, 0x014C, 0x014D, 0x014E, 0x014F,
+       /* 5 */ 0x0150, 0x0151, 0x0153, 0x0153, 0x0154, 0x0155, 0x0156, 0x0157, 0x0158, 0x0159, 0x015A, 0x015B, 0x015C, 0x015D, 0x015E, 0x015F,
+       /* 6 */ 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165, 0x0167, 0x0167, 0x0168, 0x0169, 0x016A, 0x016B, 0x016C, 0x016D, 0x016E, 0x016F,
+       /* 7 */ 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175, 0x0176, 0x0177, 0x0178, 0x0179, 0x017A, 0x017B, 0x017C, 0x017D, 0x017E, 0x017F,
+       /* 8 */ 0x0180, 0x0253, 0x0183, 0x0183, 0x0185, 0x0185, 0x0254, 0x0188, 0x0188, 0x0256, 0x0257, 0x018C, 0x018C, 0x018D, 0x01DD, 0x0259,
+       /* 9 */ 0x025B, 0x0192, 0x0192, 0x0260, 0x0263, 0x0195, 0x0269, 0x0268, 0x0199, 0x0199, 0x019A, 0x019B, 0x026F, 0x0272, 0x019E, 0x0275,
+       /* A */ 0x01A0, 0x01A1, 0x01A3, 0x01A3, 0x01A5, 0x01A5, 0x01A6, 0x01A8, 0x01A8, 0x0283, 0x01AA, 0x01AB, 0x01AD, 0x01AD, 0x0288, 0x01AF,
+       /* B */ 0x01B0, 0x028A, 0x028B, 0x01B4, 0x01B4, 0x01B6, 0x01B6, 0x0292, 0x01B9, 0x01B9, 0x01BA, 0x01BB, 0x01BD, 0x01BD, 0x01BE, 0x01BF,
+       /* C */ 0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C6, 0x01C6, 0x01C6, 0x01C9, 0x01C9, 0x01C9, 0x01CC, 0x01CC, 0x01CC, 0x01CD, 0x01CE, 0x01CF,
+       /* D */ 0x01D0, 0x01D1, 0x01D2, 0x01D3, 0x01D4, 0x01D5, 0x01D6, 0x01D7, 0x01D8, 0x01D9, 0x01DA, 0x01DB, 0x01DC, 0x01DD, 0x01DE, 0x01DF,
+       /* E */ 0x01E0, 0x01E1, 0x01E2, 0x01E3, 0x01E5, 0x01E5, 0x01E6, 0x01E7, 0x01E8, 0x01E9, 0x01EA, 0x01EB, 0x01EC, 0x01ED, 0x01EE, 0x01EF,
+       /* F */ 0x01F0, 0x01F3, 0x01F3, 0x01F3, 0x01F4, 0x01F5, 0x01F6, 0x01F7, 0x01F8, 0x01F9, 0x01FA, 0x01FB, 0x01FC, 0x01FD, 0x01FE, 0x01FF,
+
+       // Table 3 (for high byte 0x03)
+
+       /* 0 */ 0x0300, 0x0301, 0x0302, 0x0303, 0x0304, 0x0305, 0x0306, 0x0307, 0x0308, 0x0309, 0x030A, 0x030B, 0x030C, 0x030D, 0x030E, 0x030F,
+       /* 1 */ 0x0310, 0x0311, 0x0312, 0x0313, 0x0314, 0x0315, 0x0316, 0x0317, 0x0318, 0x0319, 0x031A, 0x031B, 0x031C, 0x031D, 0x031E, 0x031F,
+       /* 2 */ 0x0320, 0x0321, 0x0322, 0x0323, 0x0324, 0x0325, 0x0326, 0x0327, 0x0328, 0x0329, 0x032A, 0x032B, 0x032C, 0x032D, 0x032E, 0x032F,
+       /* 3 */ 0x0330, 0x0331, 0x0332, 0x0333, 0x0334, 0x0335, 0x0336, 0x0337, 0x0338, 0x0339, 0x033A, 0x033B, 0x033C, 0x033D, 0x033E, 0x033F,
+       /* 4 */ 0x0340, 0x0341, 0x0342, 0x0343, 0x0344, 0x0345, 0x0346, 0x0347, 0x0348, 0x0349, 0x034A, 0x034B, 0x034C, 0x034D, 0x034E, 0x034F,
+       /* 5 */ 0x0350, 0x0351, 0x0352, 0x0353, 0x0354, 0x0355, 0x0356, 0x0357, 0x0358, 0x0359, 0x035A, 0x035B, 0x035C, 0x035D, 0x035E, 0x035F,
+       /* 6 */ 0x0360, 0x0361, 0x0362, 0x0363, 0x0364, 0x0365, 0x0366, 0x0367, 0x0368, 0x0369, 0x036A, 0x036B, 0x036C, 0x036D, 0x036E, 0x036F,
+       /* 7 */ 0x0370, 0x0371, 0x0372, 0x0373, 0x0374, 0x0375, 0x0376, 0x0377, 0x0378, 0x0379, 0x037A, 0x037B, 0x037C, 0x037D, 0x037E, 0x037F,
+       /* 8 */ 0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0386, 0x0387, 0x0388, 0x0389, 0x038A, 0x038B, 0x038C, 0x038D, 0x038E, 0x038F,
+       /* 9 */ 0x0390, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
+       /* A */ 0x03C0, 0x03C1, 0x03A2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
+       /* B */ 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
+       /* C */ 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x03CF,
+       /* D */ 0x03D0, 0x03D1, 0x03D2, 0x03D3, 0x03D4, 0x03D5, 0x03D6, 0x03D7, 0x03D8, 0x03D9, 0x03DA, 0x03DB, 0x03DC, 0x03DD, 0x03DE, 0x03DF,
+       /* E */ 0x03E0, 0x03E1, 0x03E3, 0x03E3, 0x03E5, 0x03E5, 0x03E7, 0x03E7, 0x03E9, 0x03E9, 0x03EB, 0x03EB, 0x03ED, 0x03ED, 0x03EF, 0x03EF,
+       /* F */ 0x03F0, 0x03F1, 0x03F2, 0x03F3, 0x03F4, 0x03F5, 0x03F6, 0x03F7, 0x03F8, 0x03F9, 0x03FA, 0x03FB, 0x03FC, 0x03FD, 0x03FE, 0x03FF,
+
+       // Table 4 (for high byte 0x04)
+
+       /* 0 */ 0x0400, 0x0401, 0x0452, 0x0403, 0x0454, 0x0455, 0x0456, 0x0407, 0x0458, 0x0459, 0x045A, 0x045B, 0x040C, 0x040D, 0x040E, 0x045F,
+       /* 1 */ 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0419, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
+       /* 2 */ 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
+       /* 3 */ 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
+       /* 4 */ 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
+       /* 5 */ 0x0450, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, 0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x045D, 0x045E, 0x045F,
+       /* 6 */ 0x0461, 0x0461, 0x0463, 0x0463, 0x0465, 0x0465, 0x0467, 0x0467, 0x0469, 0x0469, 0x046B, 0x046B, 0x046D, 0x046D, 0x046F, 0x046F,
+       /* 7 */ 0x0471, 0x0471, 0x0473, 0x0473, 0x0475, 0x0475, 0x0476, 0x0477, 0x0479, 0x0479, 0x047B, 0x047B, 0x047D, 0x047D, 0x047F, 0x047F,
+       /* 8 */ 0x0481, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x0487, 0x0488, 0x0489, 0x048A, 0x048B, 0x048C, 0x048D, 0x048E, 0x048F,
+       /* 9 */ 0x0491, 0x0491, 0x0493, 0x0493, 0x0495, 0x0495, 0x0497, 0x0497, 0x0499, 0x0499, 0x049B, 0x049B, 0x049D, 0x049D, 0x049F, 0x049F,
+       /* A */ 0x04A1, 0x04A1, 0x04A3, 0x04A3, 0x04A5, 0x04A5, 0x04A7, 0x04A7, 0x04A9, 0x04A9, 0x04AB, 0x04AB, 0x04AD, 0x04AD, 0x04AF, 0x04AF,
+       /* B */ 0x04B1, 0x04B1, 0x04B3, 0x04B3, 0x04B5, 0x04B5, 0x04B7, 0x04B7, 0x04B9, 0x04B9, 0x04BB, 0x04BB, 0x04BD, 0x04BD, 0x04BF, 0x04BF,
+       /* C */ 0x04C0, 0x04C1, 0x04C2, 0x04C4, 0x04C4, 0x04C5, 0x04C6, 0x04C8, 0x04C8, 0x04C9, 0x04CA, 0x04CC, 0x04CC, 0x04CD, 0x04CE, 0x04CF,
+       /* D */ 0x04D0, 0x04D1, 0x04D2, 0x04D3, 0x04D4, 0x04D5, 0x04D6, 0x04D7, 0x04D8, 0x04D9, 0x04DA, 0x04DB, 0x04DC, 0x04DD, 0x04DE, 0x04DF,
+       /* E */ 0x04E0, 0x04E1, 0x04E2, 0x04E3, 0x04E4, 0x04E5, 0x04E6, 0x04E7, 0x04E8, 0x04E9, 0x04EA, 0x04EB, 0x04EC, 0x04ED, 0x04EE, 0x04EF,
+       /* F */ 0x04F0, 0x04F1, 0x04F2, 0x04F3, 0x04F4, 0x04F5, 0x04F6, 0x04F7, 0x04F8, 0x04F9, 0x04FA, 0x04FB, 0x04FC, 0x04FD, 0x04FE, 0x04FF,
+
+       // Table 5 (for high byte 0x05)
+
+       /* 0 */ 0x0500, 0x0501, 0x0502, 0x0503, 0x0504, 0x0505, 0x0506, 0x0507, 0x0508, 0x0509, 0x050A, 0x050B, 0x050C, 0x050D, 0x050E, 0x050F,
+       /* 1 */ 0x0510, 0x0511, 0x0512, 0x0513, 0x0514, 0x0515, 0x0516, 0x0517, 0x0518, 0x0519, 0x051A, 0x051B, 0x051C, 0x051D, 0x051E, 0x051F,
+       /* 2 */ 0x0520, 0x0521, 0x0522, 0x0523, 0x0524, 0x0525, 0x0526, 0x0527, 0x0528, 0x0529, 0x052A, 0x052B, 0x052C, 0x052D, 0x052E, 0x052F,
+       /* 3 */ 0x0530, 0x0561, 0x0562, 0x0563, 0x0564, 0x0565, 0x0566, 0x0567, 0x0568, 0x0569, 0x056A, 0x056B, 0x056C, 0x056D, 0x056E, 0x056F,
+       /* 4 */ 0x0570, 0x0571, 0x0572, 0x0573, 0x0574, 0x0575, 0x0576, 0x0577, 0x0578, 0x0579, 0x057A, 0x057B, 0x057C, 0x057D, 0x057E, 0x057F,
+       /* 5 */ 0x0580, 0x0581, 0x0582, 0x0583, 0x0584, 0x0585, 0x0586, 0x0557, 0x0558, 0x0559, 0x055A, 0x055B, 0x055C, 0x055D, 0x055E, 0x055F,
+       /* 6 */ 0x0560, 0x0561, 0x0562, 0x0563, 0x0564, 0x0565, 0x0566, 0x0567, 0x0568, 0x0569, 0x056A, 0x056B, 0x056C, 0x056D, 0x056E, 0x056F,
+       /* 7 */ 0x0570, 0x0571, 0x0572, 0x0573, 0x0574, 0x0575, 0x0576, 0x0577, 0x0578, 0x0579, 0x057A, 0x057B, 0x057C, 0x057D, 0x057E, 0x057F,
+       /* 8 */ 0x0580, 0x0581, 0x0582, 0x0583, 0x0584, 0x0585, 0x0586, 0x0587, 0x0588, 0x0589, 0x058A, 0x058B, 0x058C, 0x058D, 0x058E, 0x058F,
+       /* 9 */ 0x0590, 0x0591, 0x0592, 0x0593, 0x0594, 0x0595, 0x0596, 0x0597, 0x0598, 0x0599, 0x059A, 0x059B, 0x059C, 0x059D, 0x059E, 0x059F,
+       /* A */ 0x05A0, 0x05A1, 0x05A2, 0x05A3, 0x05A4, 0x05A5, 0x05A6, 0x05A7, 0x05A8, 0x05A9, 0x05AA, 0x05AB, 0x05AC, 0x05AD, 0x05AE, 0x05AF,
+       /* B */ 0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7, 0x05B8, 0x05B9, 0x05BA, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF,
+       /* C */ 0x05C0, 0x05C1, 0x05C2, 0x05C3, 0x05C4, 0x05C5, 0x05C6, 0x05C7, 0x05C8, 0x05C9, 0x05CA, 0x05CB, 0x05CC, 0x05CD, 0x05CE, 0x05CF,
+       /* D */ 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
+       /* E */ 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x05EB, 0x05EC, 0x05ED, 0x05EE, 0x05EF,
+       /* F */ 0x05F0, 0x05F1, 0x05F2, 0x05F3, 0x05F4, 0x05F5, 0x05F6, 0x05F7, 0x05F8, 0x05F9, 0x05FA, 0x05FB, 0x05FC, 0x05FD, 0x05FE, 0x05FF,
+
+       // Table 6 (for high byte 0x10)
+
+       /* 0 */ 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 0x1008, 0x1009, 0x100A, 0x100B, 0x100C, 0x100D, 0x100E, 0x100F,
+       /* 1 */ 0x1010, 0x1011, 0x1012, 0x1013, 0x1014, 0x1015, 0x1016, 0x1017, 0x1018, 0x1019, 0x101A, 0x101B, 0x101C, 0x101D, 0x101E, 0x101F,
+       /* 2 */ 0x1020, 0x1021, 0x1022, 0x1023, 0x1024, 0x1025, 0x1026, 0x1027, 0x1028, 0x1029, 0x102A, 0x102B, 0x102C, 0x102D, 0x102E, 0x102F,
+       /* 3 */ 0x1030, 0x1031, 0x1032, 0x1033, 0x1034, 0x1035, 0x1036, 0x1037, 0x1038, 0x1039, 0x103A, 0x103B, 0x103C, 0x103D, 0x103E, 0x103F,
+       /* 4 */ 0x1040, 0x1041, 0x1042, 0x1043, 0x1044, 0x1045, 0x1046, 0x1047, 0x1048, 0x1049, 0x104A, 0x104B, 0x104C, 0x104D, 0x104E, 0x104F,
+       /* 5 */ 0x1050, 0x1051, 0x1052, 0x1053, 0x1054, 0x1055, 0x1056, 0x1057, 0x1058, 0x1059, 0x105A, 0x105B, 0x105C, 0x105D, 0x105E, 0x105F,
+       /* 6 */ 0x1060, 0x1061, 0x1062, 0x1063, 0x1064, 0x1065, 0x1066, 0x1067, 0x1068, 0x1069, 0x106A, 0x106B, 0x106C, 0x106D, 0x106E, 0x106F,
+       /* 7 */ 0x1070, 0x1071, 0x1072, 0x1073, 0x1074, 0x1075, 0x1076, 0x1077, 0x1078, 0x1079, 0x107A, 0x107B, 0x107C, 0x107D, 0x107E, 0x107F,
+       /* 8 */ 0x1080, 0x1081, 0x1082, 0x1083, 0x1084, 0x1085, 0x1086, 0x1087, 0x1088, 0x1089, 0x108A, 0x108B, 0x108C, 0x108D, 0x108E, 0x108F,
+       /* 9 */ 0x1090, 0x1091, 0x1092, 0x1093, 0x1094, 0x1095, 0x1096, 0x1097, 0x1098, 0x1099, 0x109A, 0x109B, 0x109C, 0x109D, 0x109E, 0x109F,
+       /* A */ 0x10D0, 0x10D1, 0x10D2, 0x10D3, 0x10D4, 0x10D5, 0x10D6, 0x10D7, 0x10D8, 0x10D9, 0x10DA, 0x10DB, 0x10DC, 0x10DD, 0x10DE, 0x10DF,
+       /* B */ 0x10E0, 0x10E1, 0x10E2, 0x10E3, 0x10E4, 0x10E5, 0x10E6, 0x10E7, 0x10E8, 0x10E9, 0x10EA, 0x10EB, 0x10EC, 0x10ED, 0x10EE, 0x10EF,
+       /* C */ 0x10F0, 0x10F1, 0x10F2, 0x10F3, 0x10F4, 0x10F5, 0x10C6, 0x10C7, 0x10C8, 0x10C9, 0x10CA, 0x10CB, 0x10CC, 0x10CD, 0x10CE, 0x10CF,
+       /* D */ 0x10D0, 0x10D1, 0x10D2, 0x10D3, 0x10D4, 0x10D5, 0x10D6, 0x10D7, 0x10D8, 0x10D9, 0x10DA, 0x10DB, 0x10DC, 0x10DD, 0x10DE, 0x10DF,
+       /* E */ 0x10E0, 0x10E1, 0x10E2, 0x10E3, 0x10E4, 0x10E5, 0x10E6, 0x10E7, 0x10E8, 0x10E9, 0x10EA, 0x10EB, 0x10EC, 0x10ED, 0x10EE, 0x10EF,
+       /* F */ 0x10F0, 0x10F1, 0x10F2, 0x10F3, 0x10F4, 0x10F5, 0x10F6, 0x10F7, 0x10F8, 0x10F9, 0x10FA, 0x10FB, 0x10FC, 0x10FD, 0x10FE, 0x10FF,
+
+       // Table 7 (for high byte 0x20)
+
+       /* 0 */ 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x200B, 0x0000, 0x0000, 0x0000, 0x0000,
+       /* 1 */ 0x2010, 0x2011, 0x2012, 0x2013, 0x2014, 0x2015, 0x2016, 0x2017, 0x2018, 0x2019, 0x201A, 0x201B, 0x201C, 0x201D, 0x201E, 0x201F,
+       /* 2 */ 0x2020, 0x2021, 0x2022, 0x2023, 0x2024, 0x2025, 0x2026, 0x2027, 0x2028, 0x2029, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x202F,
+       /* 3 */ 0x2030, 0x2031, 0x2032, 0x2033, 0x2034, 0x2035, 0x2036, 0x2037, 0x2038, 0x2039, 0x203A, 0x203B, 0x203C, 0x203D, 0x203E, 0x203F,
+       /* 4 */ 0x2040, 0x2041, 0x2042, 0x2043, 0x2044, 0x2045, 0x2046, 0x2047, 0x2048, 0x2049, 0x204A, 0x204B, 0x204C, 0x204D, 0x204E, 0x204F,
+       /* 5 */ 0x2050, 0x2051, 0x2052, 0x2053, 0x2054, 0x2055, 0x2056, 0x2057, 0x2058, 0x2059, 0x205A, 0x205B, 0x205C, 0x205D, 0x205E, 0x205F,
+       /* 6 */ 0x2060, 0x2061, 0x2062, 0x2063, 0x2064, 0x2065, 0x2066, 0x2067, 0x2068, 0x2069, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       /* 7 */ 0x2070, 0x2071, 0x2072, 0x2073, 0x2074, 0x2075, 0x2076, 0x2077, 0x2078, 0x2079, 0x207A, 0x207B, 0x207C, 0x207D, 0x207E, 0x207F,
+       /* 8 */ 0x2080, 0x2081, 0x2082, 0x2083, 0x2084, 0x2085, 0x2086, 0x2087, 0x2088, 0x2089, 0x208A, 0x208B, 0x208C, 0x208D, 0x208E, 0x208F,
+       /* 9 */ 0x2090, 0x2091, 0x2092, 0x2093, 0x2094, 0x2095, 0x2096, 0x2097, 0x2098, 0x2099, 0x209A, 0x209B, 0x209C, 0x209D, 0x209E, 0x209F,
+       /* A */ 0x20A0, 0x20A1, 0x20A2, 0x20A3, 0x20A4, 0x20A5, 0x20A6, 0x20A7, 0x20A8, 0x20A9, 0x20AA, 0x20AB, 0x20AC, 0x20AD, 0x20AE, 0x20AF,
+       /* B */ 0x20B0, 0x20B1, 0x20B2, 0x20B3, 0x20B4, 0x20B5, 0x20B6, 0x20B7, 0x20B8, 0x20B9, 0x20BA, 0x20BB, 0x20BC, 0x20BD, 0x20BE, 0x20BF,
+       /* C */ 0x20C0, 0x20C1, 0x20C2, 0x20C3, 0x20C4, 0x20C5, 0x20C6, 0x20C7, 0x20C8, 0x20C9, 0x20CA, 0x20CB, 0x20CC, 0x20CD, 0x20CE, 0x20CF,
+       /* D */ 0x20D0, 0x20D1, 0x20D2, 0x20D3, 0x20D4, 0x20D5, 0x20D6, 0x20D7, 0x20D8, 0x20D9, 0x20DA, 0x20DB, 0x20DC, 0x20DD, 0x20DE, 0x20DF,
+       /* E */ 0x20E0, 0x20E1, 0x20E2, 0x20E3, 0x20E4, 0x20E5, 0x20E6, 0x20E7, 0x20E8, 0x20E9, 0x20EA, 0x20EB, 0x20EC, 0x20ED, 0x20EE, 0x20EF,
+       /* F */ 0x20F0, 0x20F1, 0x20F2, 0x20F3, 0x20F4, 0x20F5, 0x20F6, 0x20F7, 0x20F8, 0x20F9, 0x20FA, 0x20FB, 0x20FC, 0x20FD, 0x20FE, 0x20FF,
+
+       // Table 8 (for high byte 0x21)
+
+       /* 0 */ 0x2100, 0x2101, 0x2102, 0x2103, 0x2104, 0x2105, 0x2106, 0x2107, 0x2108, 0x2109, 0x210A, 0x210B, 0x210C, 0x210D, 0x210E, 0x210F,
+       /* 1 */ 0x2110, 0x2111, 0x2112, 0x2113, 0x2114, 0x2115, 0x2116, 0x2117, 0x2118, 0x2119, 0x211A, 0x211B, 0x211C, 0x211D, 0x211E, 0x211F,
+       /* 2 */ 0x2120, 0x2121, 0x2122, 0x2123, 0x2124, 0x2125, 0x2126, 0x2127, 0x2128, 0x2129, 0x212A, 0x212B, 0x212C, 0x212D, 0x212E, 0x212F,
+       /* 3 */ 0x2130, 0x2131, 0x2132, 0x2133, 0x2134, 0x2135, 0x2136, 0x2137, 0x2138, 0x2139, 0x213A, 0x213B, 0x213C, 0x213D, 0x213E, 0x213F,
+       /* 4 */ 0x2140, 0x2141, 0x2142, 0x2143, 0x2144, 0x2145, 0x2146, 0x2147, 0x2148, 0x2149, 0x214A, 0x214B, 0x214C, 0x214D, 0x214E, 0x214F,
+       /* 5 */ 0x2150, 0x2151, 0x2152, 0x2153, 0x2154, 0x2155, 0x2156, 0x2157, 0x2158, 0x2159, 0x215A, 0x215B, 0x215C, 0x215D, 0x215E, 0x215F,
+       /* 6 */ 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F,
+       /* 7 */ 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F,
+       /* 8 */ 0x2180, 0x2181, 0x2182, 0x2183, 0x2184, 0x2185, 0x2186, 0x2187, 0x2188, 0x2189, 0x218A, 0x218B, 0x218C, 0x218D, 0x218E, 0x218F,
+       /* 9 */ 0x2190, 0x2191, 0x2192, 0x2193, 0x2194, 0x2195, 0x2196, 0x2197, 0x2198, 0x2199, 0x219A, 0x219B, 0x219C, 0x219D, 0x219E, 0x219F,
+       /* A */ 0x21A0, 0x21A1, 0x21A2, 0x21A3, 0x21A4, 0x21A5, 0x21A6, 0x21A7, 0x21A8, 0x21A9, 0x21AA, 0x21AB, 0x21AC, 0x21AD, 0x21AE, 0x21AF,
+       /* B */ 0x21B0, 0x21B1, 0x21B2, 0x21B3, 0x21B4, 0x21B5, 0x21B6, 0x21B7, 0x21B8, 0x21B9, 0x21BA, 0x21BB, 0x21BC, 0x21BD, 0x21BE, 0x21BF,
+       /* C */ 0x21C0, 0x21C1, 0x21C2, 0x21C3, 0x21C4, 0x21C5, 0x21C6, 0x21C7, 0x21C8, 0x21C9, 0x21CA, 0x21CB, 0x21CC, 0x21CD, 0x21CE, 0x21CF,
+       /* D */ 0x21D0, 0x21D1, 0x21D2, 0x21D3, 0x21D4, 0x21D5, 0x21D6, 0x21D7, 0x21D8, 0x21D9, 0x21DA, 0x21DB, 0x21DC, 0x21DD, 0x21DE, 0x21DF,
+       /* E */ 0x21E0, 0x21E1, 0x21E2, 0x21E3, 0x21E4, 0x21E5, 0x21E6, 0x21E7, 0x21E8, 0x21E9, 0x21EA, 0x21EB, 0x21EC, 0x21ED, 0x21EE, 0x21EF,
+       /* F */ 0x21F0, 0x21F1, 0x21F2, 0x21F3, 0x21F4, 0x21F5, 0x21F6, 0x21F7, 0x21F8, 0x21F9, 0x21FA, 0x21FB, 0x21FC, 0x21FD, 0x21FE, 0x21FF,
+
+       // Table 9 (for high byte 0xFE)
+
+       /* 0 */ 0xFE00, 0xFE01, 0xFE02, 0xFE03, 0xFE04, 0xFE05, 0xFE06, 0xFE07, 0xFE08, 0xFE09, 0xFE0A, 0xFE0B, 0xFE0C, 0xFE0D, 0xFE0E, 0xFE0F,
+       /* 1 */ 0xFE10, 0xFE11, 0xFE12, 0xFE13, 0xFE14, 0xFE15, 0xFE16, 0xFE17, 0xFE18, 0xFE19, 0xFE1A, 0xFE1B, 0xFE1C, 0xFE1D, 0xFE1E, 0xFE1F,
+       /* 2 */ 0xFE20, 0xFE21, 0xFE22, 0xFE23, 0xFE24, 0xFE25, 0xFE26, 0xFE27, 0xFE28, 0xFE29, 0xFE2A, 0xFE2B, 0xFE2C, 0xFE2D, 0xFE2E, 0xFE2F,
+       /* 3 */ 0xFE30, 0xFE31, 0xFE32, 0xFE33, 0xFE34, 0xFE35, 0xFE36, 0xFE37, 0xFE38, 0xFE39, 0xFE3A, 0xFE3B, 0xFE3C, 0xFE3D, 0xFE3E, 0xFE3F,
+       /* 4 */ 0xFE40, 0xFE41, 0xFE42, 0xFE43, 0xFE44, 0xFE45, 0xFE46, 0xFE47, 0xFE48, 0xFE49, 0xFE4A, 0xFE4B, 0xFE4C, 0xFE4D, 0xFE4E, 0xFE4F,
+       /* 5 */ 0xFE50, 0xFE51, 0xFE52, 0xFE53, 0xFE54, 0xFE55, 0xFE56, 0xFE57, 0xFE58, 0xFE59, 0xFE5A, 0xFE5B, 0xFE5C, 0xFE5D, 0xFE5E, 0xFE5F,
+       /* 6 */ 0xFE60, 0xFE61, 0xFE62, 0xFE63, 0xFE64, 0xFE65, 0xFE66, 0xFE67, 0xFE68, 0xFE69, 0xFE6A, 0xFE6B, 0xFE6C, 0xFE6D, 0xFE6E, 0xFE6F,
+       /* 7 */ 0xFE70, 0xFE71, 0xFE72, 0xFE73, 0xFE74, 0xFE75, 0xFE76, 0xFE77, 0xFE78, 0xFE79, 0xFE7A, 0xFE7B, 0xFE7C, 0xFE7D, 0xFE7E, 0xFE7F,
+       /* 8 */ 0xFE80, 0xFE81, 0xFE82, 0xFE83, 0xFE84, 0xFE85, 0xFE86, 0xFE87, 0xFE88, 0xFE89, 0xFE8A, 0xFE8B, 0xFE8C, 0xFE8D, 0xFE8E, 0xFE8F,
+       /* 9 */ 0xFE90, 0xFE91, 0xFE92, 0xFE93, 0xFE94, 0xFE95, 0xFE96, 0xFE97, 0xFE98, 0xFE99, 0xFE9A, 0xFE9B, 0xFE9C, 0xFE9D, 0xFE9E, 0xFE9F,
+       /* A */ 0xFEA0, 0xFEA1, 0xFEA2, 0xFEA3, 0xFEA4, 0xFEA5, 0xFEA6, 0xFEA7, 0xFEA8, 0xFEA9, 0xFEAA, 0xFEAB, 0xFEAC, 0xFEAD, 0xFEAE, 0xFEAF,
+       /* B */ 0xFEB0, 0xFEB1, 0xFEB2, 0xFEB3, 0xFEB4, 0xFEB5, 0xFEB6, 0xFEB7, 0xFEB8, 0xFEB9, 0xFEBA, 0xFEBB, 0xFEBC, 0xFEBD, 0xFEBE, 0xFEBF,
+       /* C */ 0xFEC0, 0xFEC1, 0xFEC2, 0xFEC3, 0xFEC4, 0xFEC5, 0xFEC6, 0xFEC7, 0xFEC8, 0xFEC9, 0xFECA, 0xFECB, 0xFECC, 0xFECD, 0xFECE, 0xFECF,
+       /* D */ 0xFED0, 0xFED1, 0xFED2, 0xFED3, 0xFED4, 0xFED5, 0xFED6, 0xFED7, 0xFED8, 0xFED9, 0xFEDA, 0xFEDB, 0xFEDC, 0xFEDD, 0xFEDE, 0xFEDF,
+       /* E */ 0xFEE0, 0xFEE1, 0xFEE2, 0xFEE3, 0xFEE4, 0xFEE5, 0xFEE6, 0xFEE7, 0xFEE8, 0xFEE9, 0xFEEA, 0xFEEB, 0xFEEC, 0xFEED, 0xFEEE, 0xFEEF,
+       /* F */ 0xFEF0, 0xFEF1, 0xFEF2, 0xFEF3, 0xFEF4, 0xFEF5, 0xFEF6, 0xFEF7, 0xFEF8, 0xFEF9, 0xFEFA, 0xFEFB, 0xFEFC, 0xFEFD, 0xFEFE, 0x0000,
+
+       // Table 10 (for high byte 0xFF)
+
+       /* 0 */ 0xFF00, 0xFF01, 0xFF02, 0xFF03, 0xFF04, 0xFF05, 0xFF06, 0xFF07, 0xFF08, 0xFF09, 0xFF0A, 0xFF0B, 0xFF0C, 0xFF0D, 0xFF0E, 0xFF0F,
+       /* 1 */ 0xFF10, 0xFF11, 0xFF12, 0xFF13, 0xFF14, 0xFF15, 0xFF16, 0xFF17, 0xFF18, 0xFF19, 0xFF1A, 0xFF1B, 0xFF1C, 0xFF1D, 0xFF1E, 0xFF1F,
+       /* 2 */ 0xFF20, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F,
+       /* 3 */ 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0xFF3B, 0xFF3C, 0xFF3D, 0xFF3E, 0xFF3F,
+       /* 4 */ 0xFF40, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F,
+       /* 5 */ 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0xFF5B, 0xFF5C, 0xFF5D, 0xFF5E, 0xFF5F,
+       /* 6 */ 0xFF60, 0xFF61, 0xFF62, 0xFF63, 0xFF64, 0xFF65, 0xFF66, 0xFF67, 0xFF68, 0xFF69, 0xFF6A, 0xFF6B, 0xFF6C, 0xFF6D, 0xFF6E, 0xFF6F,
+       /* 7 */ 0xFF70, 0xFF71, 0xFF72, 0xFF73, 0xFF74, 0xFF75, 0xFF76, 0xFF77, 0xFF78, 0xFF79, 0xFF7A, 0xFF7B, 0xFF7C, 0xFF7D, 0xFF7E, 0xFF7F,
+       /* 8 */ 0xFF80, 0xFF81, 0xFF82, 0xFF83, 0xFF84, 0xFF85, 0xFF86, 0xFF87, 0xFF88, 0xFF89, 0xFF8A, 0xFF8B, 0xFF8C, 0xFF8D, 0xFF8E, 0xFF8F,
+       /* 9 */ 0xFF90, 0xFF91, 0xFF92, 0xFF93, 0xFF94, 0xFF95, 0xFF96, 0xFF97, 0xFF98, 0xFF99, 0xFF9A, 0xFF9B, 0xFF9C, 0xFF9D, 0xFF9E, 0xFF9F,
+       /* A */ 0xFFA0, 0xFFA1, 0xFFA2, 0xFFA3, 0xFFA4, 0xFFA5, 0xFFA6, 0xFFA7, 0xFFA8, 0xFFA9, 0xFFAA, 0xFFAB, 0xFFAC, 0xFFAD, 0xFFAE, 0xFFAF,
+       /* B */ 0xFFB0, 0xFFB1, 0xFFB2, 0xFFB3, 0xFFB4, 0xFFB5, 0xFFB6, 0xFFB7, 0xFFB8, 0xFFB9, 0xFFBA, 0xFFBB, 0xFFBC, 0xFFBD, 0xFFBE, 0xFFBF,
+       /* C */ 0xFFC0, 0xFFC1, 0xFFC2, 0xFFC3, 0xFFC4, 0xFFC5, 0xFFC6, 0xFFC7, 0xFFC8, 0xFFC9, 0xFFCA, 0xFFCB, 0xFFCC, 0xFFCD, 0xFFCE, 0xFFCF,
+       /* D */ 0xFFD0, 0xFFD1, 0xFFD2, 0xFFD3, 0xFFD4, 0xFFD5, 0xFFD6, 0xFFD7, 0xFFD8, 0xFFD9, 0xFFDA, 0xFFDB, 0xFFDC, 0xFFDD, 0xFFDE, 0xFFDF,
+       /* E */ 0xFFE0, 0xFFE1, 0xFFE2, 0xFFE3, 0xFFE4, 0xFFE5, 0xFFE6, 0xFFE7, 0xFFE8, 0xFFE9, 0xFFEA, 0xFFEB, 0xFFEC, 0xFFED, 0xFFEE, 0xFFEF,
+       /* F */ 0xFFF0, 0xFFF1, 0xFFF2, 0xFFF3, 0xFFF4, 0xFFF5, 0xFFF6, 0xFFF7, 0xFFF8, 0xFFF9, 0xFFFA, 0xFFFB, 0xFFFC, 0xFFFD, 0xFFFE, 0xFFFF,
+};
+
+
+/* RelString case folding table */
+
+unsigned short gCompareTable[] = {
+
+       /* 0 */ 0x0000, 0x0100, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600, 0x0700, 0x0800, 0x0900, 0x0A00, 0x0B00, 0x0C00, 0x0D00, 0x0E00, 0x0F00, 
+       /* 1 */ 0x1000, 0x1100, 0x1200, 0x1300, 0x1400, 0x1500, 0x1600, 0x1700, 0x1800, 0x1900, 0x1A00, 0x1B00, 0x1C00, 0x1D00, 0x1E00, 0x1F00, 
+       /* 2 */ 0x2000, 0x2100, 0x2200, 0x2300, 0x2400, 0x2500, 0x2600, 0x2700, 0x2800, 0x2900, 0x2A00, 0x2B00, 0x2C00, 0x2D00, 0x2E00, 0x2F00, 
+       /* 3 */ 0x3000, 0x3100, 0x3200, 0x3300, 0x3400, 0x3500, 0x3600, 0x3700, 0x3800, 0x3900, 0x3A00, 0x3B00, 0x3C00, 0x3D00, 0x3E00, 0x3F00, 
+       /* 4 */ 0x4000, 0x4100, 0x4200, 0x4300, 0x4400, 0x4500, 0x4600, 0x4700, 0x4800, 0x4900, 0x4A00, 0x4B00, 0x4C00, 0x4D00, 0x4E00, 0x4F00, 
+       /* 5 */ 0x5000, 0x5100, 0x5200, 0x5300, 0x5400, 0x5500, 0x5600, 0x5700, 0x5800, 0x5900, 0x5A00, 0x5B00, 0x5C00, 0x5D00, 0x5E00, 0x5F00, 
+
+       // 0x60 maps to 'a'
+       // range 0x61 to 0x7a ('a' to 'z') map to upper case
+
+       /* 6 */ 0x4180, 0x4100, 0x4200, 0x4300, 0x4400, 0x4500, 0x4600, 0x4700, 0x4800, 0x4900, 0x4A00, 0x4B00, 0x4C00, 0x4D00, 0x4E00, 0x4F00, 
+       /* 7 */ 0x5000, 0x5100, 0x5200, 0x5300, 0x5400, 0x5500, 0x5600, 0x5700, 0x5800, 0x5900, 0x5A00, 0x7B00, 0x7C00, 0x7D00, 0x7E00, 0x7F00, 
+
+       // range 0x80 to 0xd8 gets mapped...
+       
+       /* 8 */ 0x4108, 0x410C, 0x4310, 0x4502, 0x4E0A, 0x4F08, 0x5508, 0x4182, 0x4104, 0x4186, 0x4108, 0x410A, 0x410C, 0x4310, 0x4502, 0x4584,
+       /* 9 */ 0x4586, 0x4588, 0x4982, 0x4984, 0x4986, 0x4988, 0x4E0A, 0x4F82, 0x4F84, 0x4F86, 0x4F08, 0x4F0A, 0x5582, 0x5584, 0x5586, 0x5508,
+       /* A */ 0xA000, 0xA100, 0xA200, 0xA300, 0xA400, 0xA500, 0xA600, 0x5382, 0xA800, 0xA900, 0xAA00, 0xAB00, 0xAC00, 0xAD00, 0x4114, 0x4F0E,
+       /* B */ 0xB000, 0xB100, 0xB200, 0xB300, 0xB400, 0xB500, 0xB600, 0xB700, 0xB800, 0xB900, 0xBA00, 0x4192, 0x4F92, 0xBD00, 0x4114, 0x4F0E,
+       /* C */ 0xC000, 0xC100, 0xC200, 0xC300, 0xC400, 0xC500, 0xC600, 0x2206, 0x2208, 0xC900, 0x2000, 0x4104, 0x410A, 0x4F0A, 0x4F14, 0x4F14,
+       /* D */ 0xD000, 0xD100, 0x2202, 0x2204, 0x2702, 0x2704, 0xD600, 0xD700, 0x5988, 0xD900, 0xDA00, 0xDB00, 0xDC00, 0xDD00, 0xDE00, 0xDF00,
+
+       /* E */ 0xE000, 0xE100, 0xE200, 0xE300, 0xE400, 0xE500, 0xE600, 0xE700, 0xE800, 0xE900, 0xEA00, 0xEB00, 0xEC00, 0xED00, 0xEE00, 0xEF00, 
+       /* F */ 0xF000, 0xF100, 0xF200, 0xF300, 0xF400, 0xF500, 0xF600, 0xF700, 0xF800, 0xF900, 0xFA00, 0xFB00, 0xFC00, 0xFD00, 0xFE00, 0xFF00, 
+
+};
diff --git a/i386/libsaio/hfs_compare.c b/i386/libsaio/hfs_compare.c
new file mode 100644 (file)
index 0000000..8917c1c
--- /dev/null
@@ -0,0 +1,316 @@
+/*
+ * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License").  You may not use this file except in compliance with the
+ * License.  Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
+ * 
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ *  HFSCompare.c - Functions for working with and comparing HFS nams.
+ *
+ *  Copyright (c) 1999-2000 Apple Computer, Inc.
+ *
+ *  DRI: Josh de Cesare
+ */
+
+#include <sl.h>
+#include "hfs_CaseTables.h"
+
+//_______________________________________________________________________
+//
+//     Routine:        FastRelString
+//
+//     Output:         returns -1 if str1 < str2
+//                             returns  1 if str1 > str2
+//                             return   0 if equal
+//
+//_______________________________________________________________________
+
+int32_t        FastRelString(char * str1, char * str2)
+{
+       int32_t  bestGuess;
+       u_int8_t length, length2;
+
+       length = *(str1++);
+       length2 = *(str2++);
+
+       if (length == length2)
+               bestGuess = 0;
+       else if (length < length2)
+               bestGuess = -1;
+       else
+       {
+               bestGuess = 1;
+               length = length2;
+       }
+
+       while (length--)
+       {
+               u_int32_t aChar, bChar;
+
+               aChar = *(str1++);
+               bChar = *(str2++);
+               
+               if (aChar != bChar)     /* If they don't match exacly, do case conversion */
+               {
+                       u_int16_t aSortWord, bSortWord;
+
+                       aSortWord = gCompareTable[aChar];
+                       bSortWord = gCompareTable[bChar];
+
+                       if (aSortWord > bSortWord)
+                               return 1;
+
+                       if (aSortWord < bSortWord)
+                               return -1;
+               }
+               
+               /*
+                * If characters match exactly, then go on to next character
+                * immediately without doing any extra work.
+                */
+       }
+       
+       /* if you got to here, then return bestGuess */
+       return bestGuess;
+}      
+
+
+//
+//     FastUnicodeCompare - Compare two Unicode strings; produce a relative ordering
+//
+//         IF                          RESULT
+//     --------------------------
+//     str1 < str2             =>      -1
+//     str1 = str2             =>       0
+//     str1 > str2             =>      +1
+//
+//     The lower case table starts with 256 entries (one for each of the upper bytes
+//     of the original Unicode char).  If that entry is zero, then all characters with
+//     that upper byte are already case folded.  If the entry is non-zero, then it is
+//     the _index_ (not byte offset) of the start of the sub-table for the characters
+//     with that upper byte.  All ignorable characters are folded to the value zero.
+//
+//     In pseudocode:
+//
+//             Let c = source Unicode character
+//             Let table[] = lower case table
+//
+//             lower = table[highbyte(c)]
+//             if (lower == 0)
+//                     lower = c
+//             else
+//                     lower = table[lower+lowbyte(c)]
+//
+//             if (lower == 0)
+//                     ignore this character
+//
+//     To handle ignorable characters, we now need a loop to find the next valid character.
+//     Also, we can't pre-compute the number of characters to compare; the string length might
+//     be larger than the number of non-ignorable characters.  Further, we must be able to handle
+//     ignorable characters at any point in the string, including as the first or last characters.
+//     We use a zero value as a sentinel to detect both end-of-string and ignorable characters.
+//     Since the File Manager doesn't prevent the NUL character (value zero) as part of a filename,
+//     the case mapping table is assumed to map u+0000 to some non-zero value (like 0xFFFF, which is
+//     an invalid Unicode character).
+//
+//     Pseudocode:
+//
+//             while (1) {
+//                     c1 = GetNextValidChar(str1)                     //      returns zero if at end of string
+//                     c2 = GetNextValidChar(str2)
+//
+//                     if (c1 != c2) break                                     //      found a difference
+//
+//                     if (c1 == 0)                                            //      reached end of string on both strings at once?
+//                             return 0;                                               //      yes, so strings are equal
+//             }
+//
+//             // When we get here, c1 != c2.  So, we just need to determine which one is less.
+//             if (c1 < c2)
+//                     return -1;
+//             else
+//                     return 1;
+//
+
+int32_t FastUnicodeCompare( u_int16_t * str1, register u_int32_t length1,
+                            u_int16_t * str2, register u_int32_t length2 )
+{
+       register u_int16_t c1,c2;
+       register u_int16_t temp;
+
+       while (1) {
+               /* Set default values for c1, c2 in case there are no more valid chars */
+               c1 = 0;
+               c2 = 0;
+
+               /* Find next non-ignorable char from str1, or zero if no more */
+               while (length1 && c1 == 0) {
+                       c1 = SWAP_BE16(*(str1++));
+                       --length1;
+                       if ((temp = gLowerCaseTable[c1>>8]) != 0)               // is there a subtable for this upper byte?
+                               c1 = gLowerCaseTable[temp + (c1 & 0x00FF)];     // yes, so fold the char
+               }
+
+               /* Find next non-ignorable char from str2, or zero if no more */
+               while (length2 && c2 == 0) {
+                       c2 = SWAP_BE16(*(str2++));
+                       --length2;
+                       if ((temp = gLowerCaseTable[c2>>8]) != 0)               // is there a subtable for this upper byte?
+                               c2 = gLowerCaseTable[temp + (c2 & 0x00FF)];     // yes, so fold the char
+               }
+
+               if (c1 != c2)   /* found a difference, so stop looping */
+                       break;
+               
+               if (c1 == 0)            /* did we reach the end of both strings at the same time? */
+                       return 0;       /* yes, so strings are equal */
+       }
+       
+       if (c1 < c2)
+               return -1;
+       else
+               return 1;
+}
+
+
+/*
+ * UTF-8 (UCS Transformation Format)
+ *
+ * The following subset of UTF-8 is used to encode UCS-2 filenames. It
+ * requires a maximum of three 3 bytes per UCS-2 character.  Only the
+ * shortest encoding required to represent the significant UCS-2 bits
+ * is legal.
+ * 
+ * UTF-8 Multibyte Codes
+ *
+ * Bytes   Bits   UCS-2 Min   UCS-2 Max   UTF-8 Byte Sequence (binary)
+ * -------------------------------------------------------------------
+ *   1       7     0x0000      0x007F      0xxxxxxx
+ *   2      11     0x0080      0x07FF      110xxxxx 10xxxxxx
+ *   3      16     0x0800      0xFFFF      1110xxxx 10xxxxxx 10xxxxxx
+ * -------------------------------------------------------------------
+ */
+
+
+/*
+ * utf_encodestr - Encodes the UCS-2 (Unicode) string at ucsp into a
+ * null terminated UTF-8 string at utf8p.
+ *
+ * ucslen is the number of UCS-2 input characters (not bytes)
+ * bufsize is the size of the output buffer in bytes
+ */
+void
+utf_encodestr( const u_int16_t * ucsp, int ucslen,
+               u_int8_t * utf8p, u_int32_t bufsize )
+{
+       u_int8_t *bufend;
+       u_int16_t ucs_ch;
+
+       bufend = utf8p + bufsize;
+
+       while (ucslen-- > 0) {
+               ucs_ch = SWAP_BE16(*ucsp++);
+
+               if (ucs_ch < 0x0080) {
+                       if (utf8p >= bufend)
+                               break;
+                       if (ucs_ch == '\0')
+                               continue;       /* skip over embedded NULLs */
+                       *utf8p++ = ucs_ch;
+
+               } else if (ucs_ch < 0x800) {
+                       if ((utf8p + 1) >= bufend)
+                               break;
+                       *utf8p++ = (ucs_ch >> 6)   | 0xc0;
+                       *utf8p++ = (ucs_ch & 0x3f) | 0x80;
+
+               } else {
+                       if ((utf8p + 2) >= bufend)
+                               break;
+                       *utf8p++ = (ucs_ch >> 12)         | 0xe0;
+                       *utf8p++ = ((ucs_ch >> 6) & 0x3f) | 0x80;
+                       *utf8p++ = ((ucs_ch) & 0x3f)      | 0x80;
+               }
+       }
+
+       *utf8p = '\0';
+}
+
+
+/*
+ * utf_decodestr - Decodes the null terminated UTF-8 string at
+ * utf8p into a UCS-2 (Unicode) string at ucsp.
+ *
+ * ucslen is the number of UCS-2 output characters (not bytes)
+ * bufsize is the size of the output buffer in bytes
+ */
+void utf_decodestr(const u_int8_t * utf8p, u_int16_t * ucsp, u_int16_t * ucslen, u_int32_t bufsize)
+{
+       u_int16_t *bufstart;
+       u_int16_t *bufend;
+       u_int16_t ucs_ch;
+       u_int8_t  byte;
+
+       bufstart = ucsp;
+       bufend = (u_int16_t *)((u_int8_t *)ucsp + bufsize);
+
+       while ((byte = *utf8p++) != '\0') {
+               if (ucsp >= bufend)
+                       break;
+
+               /* check for ascii */
+               if (byte < 0x80) {
+                       ucs_ch = byte;
+                       
+                       *ucsp++ = SWAP_BE16(ucs_ch);
+                       continue;
+               }
+
+               switch (byte & 0xf0) {
+               /*  2 byte sequence*/
+               case 0xc0:
+               case 0xd0:
+                       /* extract bits 6 - 10 from first byte */
+                       ucs_ch = (byte & 0x1F) << 6;  
+                       break;
+               /* 3 byte sequence*/
+               case 0xe0:
+                       /* extract bits 12 - 15 from first byte */
+                       ucs_ch = (byte & 0x0F) << 6;
+
+                       /* extract bits 6 - 11 from second byte */
+                       if (((byte = *utf8p++) & 0xc0) != 0x80)
+                               goto stop;
+
+                       ucs_ch += (byte & 0x3F);
+                       ucs_ch <<= 6;
+                       break;
+               default:
+                       goto stop;
+               }
+
+               /* extract bits 0 - 5 from final byte */
+               if (((byte = *utf8p++) & 0xc0) != 0x80)
+                       goto stop;
+               ucs_ch += (byte & 0x3F);  
+
+               *ucsp++ = SWAP_BE16(ucs_ch);
+       }
+stop:
+       *ucslen = SWAP_BE16(ucsp - bufstart);
+}
diff --git a/i386/libsaio/legacy/PCI.h b/i386/libsaio/legacy/PCI.h
deleted file mode 100644 (file)
index 70f711d..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Copyright (c) 1994-1996 NeXT Software, Inc.  All rights reserved. 
- *
- * PCI Configuration space structure and associated defines.
- *
- * HISTORY
- *
- * 13 May 1994 Dean Reece at NeXT
- *     Created.
- *
- */
-
-/* The IOPCIConfigSpace structure can be used to decode the 256 byte
- * configuration space presented by each PCI device.  This structure
- * is based on the PCI LOCAL BUS SPECIFICATION, rev 2.1, section 6.1
- */
-
-typedef struct _IOPCIConfigSpace {
-       unsigned short  VendorID;
-       unsigned short  DeviceID;
-       unsigned short  Command;
-       unsigned short  Status;
-       unsigned long   RevisionID:8;
-       unsigned long   ClassCode:24;
-       unsigned char   CacheLineSize;
-       unsigned char   LatencyTimer;
-       unsigned char   HeaderType;
-       unsigned char   BuiltInSelfTest;
-       unsigned long   BaseAddress[6];
-       unsigned long   CardbusCISpointer;
-       unsigned short  SubVendorID;
-       unsigned short  SubDeviceID;
-       unsigned long   ROMBaseAddress;
-       unsigned long   reserved3;
-       unsigned long   reserved4;
-       unsigned char   InterruptLine;
-       unsigned char   InterruptPin;
-       unsigned char   MinGrant;
-       unsigned char   MaxLatency;
-       unsigned long   VendorUnique[48];
-} IOPCIConfigSpace;
-
-
-/* PCI_DEFAULT_DATA is the value resulting from a read to a non-existent
- * PCI device's configuration space.
- */
-
-#define PCI_DEFAULT_DATA       0xffffffff
-
-
-/* PCI_INVALID_VENDOR_ID is a Vendor ID reserved by the PCI/SIG and is
- * guaranteed not to be assigned to any vendor.
- */
-
-#define        PCI_INVALID_VENDOR_ID   0xffff
diff --git a/i386/libsaio/legacy/asm.h b/i386/libsaio/legacy/asm.h
deleted file mode 100644 (file)
index b7e9016..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/* 
- * Mach Operating System
- * Copyright (c) 1989 Carnegie-Mellon University
- * All rights reserved.  The CMU software License Agreement specifies
- * the terms and conditions for use and redistribution.
- */
-/* 
- * HISTORY
- * $Log: asm.h,v $
- * Revision 1.2  2000/03/07 06:10:59  wsanchez
- * Make main branch like boot-3, which builds.
- *
- * Revision 1.1.2.1  2000/02/29 00:04:34  jliu
- * Added legacy header files.
- *
- * Revision 1.1.1.1  1997/09/30 02:45:05  wsanchez
- * Import of kernel from umeshv/kernel
- *
- * Revision 2.1.1.6  90/03/29  20:45:08  rvb
- *     Typo on ENTRY if gprof
- *     [90/03/29            rvb]
- * 
- * Revision 2.1.1.5  90/02/28  15:47:31  rvb
- *     fix SVC for "ifdef wheeze" [kupfer]
- * 
- * Revision 2.1.1.4  90/02/27  08:47:30  rvb
- *     Fix the GPROF definitions.
- *      ENTRY(x) gets profiled iffdef GPROF.
- *      Entry(x) (and DATA(x)) is NEVER profiled.
- *      MCOUNT can be used by asm that intends to build a frame,
- *      after the frame is built.
- *     [90/02/26            rvb]
- * 
- * Revision 2.1.1.3  90/02/09  17:23:23  rvb
- *     Add #define addr16 .byte 0x67
- *     [90/02/09            rvb]
- * 
- * Revision 2.1.1.2  89/11/10  09:51:33  rvb
- *     Added LBi, SVC and ENTRY
- * 
- * Revision 2.1.1.1  89/10/22  11:29:38  rvb
- *     New a.out and coff compatible .s files.
- *     [89/10/16            rvb]
- * 
- */
-
-
-#define S_ARG0  4(%esp)
-#define S_ARG1  8(%esp)
-#define S_ARG2 12(%esp)
-#define S_ARG3 16(%esp)
-
-#define FRAME  pushl %ebp; movl %esp, %ebp
-#define EMARF  leave
-
-#define B_ARG0  8(%ebp)
-#define B_ARG1 12(%ebp)
-#define B_ARG2 16(%ebp)
-#define B_ARG3 20(%ebp)
-
-#define EXT(x)         _##x
-#define LBb(x,n)       n##b
-#define LBf(x,n)       n##f
-
-#define ALIGN 2
-#define        LCL(x)  x
-
-#define LB(x,n) n
-
-#define SVC .byte 0x9a; .long 0; .word 0x7
-#define String .ascii
-#define Value  .word
-
-#define Times(a,b) (a*b)
-#define Divide(a,b) (a/b)
-
-#define INB    inb     %dx, %al
-#define OUTB   outb    %al, %dx
-#define INL    inl     %dx, %eax
-#define OUTL   outl    %eax, %dx
-
-#define data16 .byte 0x66
-#define addr16 .byte 0x67
-
-
-
-#ifdef GPROF
-#define MCOUNT         .data; LB(x, 9): .long 0; .text; lea LBb(x, 9),%edx; call mcount
-#define        ENTRY(x)        .globl EXT(x); .align ALIGN; EXT(x): ; \
-                       pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp;
-#define        ASENTRY(x)      .globl x; .align ALIGN; x: ; \
-                       pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp;
-#else  /* GPROF */
-#define MCOUNT
-#define        ENTRY(x)        .globl EXT(x); .align ALIGN; EXT(x):
-#define        ASENTRY(x)      .globl x; .align ALIGN; x:
-#endif /* GPROF */
-
-#define        Entry(x)        .globl EXT(x); .align ALIGN; EXT(x):
-#define        DATA(x)         .globl EXT(x); .align ALIGN; EXT(x):
-
diff --git a/i386/libsaio/legacy/disk.h b/i386/libsaio/legacy/disk.h
deleted file mode 100644 (file)
index 02ee90e..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-/*     @(#)disk.h      1.0     08/29/87        (c) 1987 NeXT   */
-
-/* 
- * HISTORY
- * 28-Mar-92  Doug Mitchell
- *     Moved disk_label struct to <bsd/dev/disk_label.h>.
- *
- * 22-May-91  Gregg Kellogg (gk) at NeXT
- *     Split out public interface.
- *
- * 20-Jul-90  Doug Mitchell
- *     Added DKIOCSFORMAT, DKIOCGFORMAT
- *
- * 16-Apr-90  Doug Mitchell at NeXT
- *     Added DKIOCPANELPRT.
- *
- * 25-Mar-90  John Seamons (jks) at NeXT
- *     Removed obsolete DKIOCNOTIFY and DKIOCINSERT.
- *
- * 23-Mar-90  Doug Mitchell
- *     Added DKIOCEJECT.
- * 
- * 14-Feb-90  Doug Mitchell at NeXT
- *     Added DKIOCMNOTIFY.
- *
- * 16-Mar-88  John Seamons (jks) at NeXT
- *     Cleaned up to support standard disk label definitions.
- *
- * 24-Feb-88  Mike DeMoney (mike) at NeXT
- *     Added defines for dl_bootfile and dl_boot0_blkno.
- *     Reduced NBAD to allow for these entries in disktab.
- *
- * 29-Aug-87  John Seamons (jks) at NeXT
- *     Created.
- *
- */
-
-#ifndef        _BSD_DEV_DISK_
-#define        _BSD_DEV_DISK_
-
-#include <mach/machine/vm_types.h>
-#include <mach/machine/boolean.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/time.h>
-#include <bsd/dev/disk_label.h>
-
-#define        DR_CMDSIZE      32
-#define        DR_ERRSIZE      32
-
-struct disk_req {
-       int     dr_bcount;              /* byte count for data transfers */
-       caddr_t dr_addr;                /* memory addr for data transfers */
-       struct  timeval dr_exec_time;   /* execution time of operation */
-
-       /* 
-        * interpretation of cmdblk and errblk is driver specific.
-        */
-       char    dr_cmdblk[DR_CMDSIZE];
-       char    dr_errblk[DR_ERRSIZE];
-};
-
-struct sdc_wire {
-       vm_offset_t     start, end;
-       boolean_t       new_pageable;
-};
-
-
-#define        BAD_BLK_OFF     4               /* offset of bad blk tbl from label */
-#define        NBAD_BLK        (12 * 1024 / sizeof (int))
-
-struct bad_block {                     /* bad block table, sized to be 12KB */
-       int     bad_blk[NBAD_BLK];
-};
-
-/* 
- * sector bitmap states (2 bits per sector) 
- */
-#define        SB_UNTESTED     0               /* must be zero */
-#define        SB_BAD          1
-#define        SB_WRITTEN      2
-#define        SB_ERASED       3
-
-struct drive_info {                    /* info about drive hardware */
-       char    di_name[MAXDNMLEN];     /* drive type name */
-       int     di_label_blkno[NLABELS];/* label loc'ns in DEVICE SECTORS */
-       int     di_devblklen;           /* device sector size */
-       int     di_maxbcount;           /* max bytes per transfer request */
-};
-
-#define        DS_STATSIZE     32
-
-struct disk_stats {
-       int     s_ecccnt;       /* avg ECC corrections per sector */
-       int     s_maxecc;       /* max ECC corrections observed */
-
-       /* 
-        * interpretation of s_stats is driver specific 
-        */
-       char    s_stats[DS_STATSIZE];
-};
-
-struct drive_location {
-       char    location[ 128 ];
-};
-
-#define        DKIOCGLABEL     _IOR('d', 0,struct disk_label)                  // read label
-#define        DKIOCSLABEL     _IOW('d', 1,struct disk_label)                  // write label
-#define        DKIOCGBITMAP    _IO('d', 2)                     // read bitmap
-#define        DKIOCSBITMAP    _IO('d', 3)                     // write bitmap
-#define        DKIOCREQ        _IOWR('d', 4, struct disk_req)  // cmd request
-#define        DKIOCINFO       _IOR('d', 5, struct drive_info) // get drive info
-#define        DKIOCZSTATS     _IO('d',7)                      // zero statistics
-#define        DKIOCGSTATS     _IO('d', 8)                     // get statistics
-#define        DKIOCRESET      _IO('d', 9)                     // reset disk
-#define        DKIOCGFLAGS     _IOR('d', 11, int)              // get driver flags
-#define        DKIOCSFLAGS     _IOW('d', 12, int)              // set driver flags
-#define        DKIOCSDCWIRE    _IOW('d', 14, struct sdc_wire)  // sdc wire memory
-#define        DKIOCSDCLOCK    _IO('d', 15)                    // sdc lock
-#define        DKIOCSDCUNLOCK  _IO('d', 16)                    // sdc unlock
-#define        DKIOCGFREEVOL   _IOR('d', 17, int)              // get free volume #
-#define        DKIOCGBBT       _IO('d', 18)                    // read bad blk tbl
-#define        DKIOCSBBT       _IO('d', 19)                    // write bad blk tbl
-#define        DKIOCMNOTIFY    _IOW('d', 20, int)              // message on insert
-#define        DKIOCEJECT      _IO('d', 21)                    // eject disk
-#define        DKIOCPANELPRT   _IOW('d', 22, int)              // register Panel
-                                                       // Request port
-#define DKIOCSFORMAT   _IOW('d', 23, int)              // set 'Formatted' flag 
-#define DKIOCGFORMAT   _IOR('d', 23, int)              // get 'Formatted' flag 
-#define DKIOCBLKSIZE   _IOR('d', 24, int)              // device sector size
-#define        DKIOCNUMBLKS    _IOR('d', 25, int)              // number of sectors
-#define DKIOCCHECKINSERT _IO('d',26)           // manually poll removable 
-                                               // media drive
-#define DKIOCCANCELAUTOMOUNT _IOW('d',27, dev_t)       // cancel automount request
-#define DKIOCGLOCATION _IOR('d',28, struct drive_location)     // arch dependent location descrip
-#endif /* _BSD_DEV_DISK_ */
-
diff --git a/i386/libsaio/legacy/fdisk.h b/i386/libsaio/legacy/fdisk.h
deleted file mode 100644 (file)
index 176ab85..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 1992 NeXT Computer, Inc.
- *
- * IBM PC disk partitioning data structures.
- *
- * HISTORY
- *
- * 8 July 1992 David E. Bohman at NeXT
- *     Created.
- */
-#ifdef DRIVER_PRIVATE
-
-#define DISK_BLK0      0               /* blkno of boot block */
-#define DISK_BLK0SZ    512             /* size of boot block */
-#define DISK_BOOTSZ    446             /* size of boot code in boot block */
-#define        DISK_SIGNATURE  0xAA55          /* signature of the boot record */
-#define FDISK_NPART    4               /* number of entries in fdisk table */
-#define FDISK_ACTIVE   0x80            /* indicator of active partition */
-#define FDISK_NEXTNAME 0xA7            /* indicator of NeXT partition */
-#define FDISK_DOS12    0x01            /* 12-bit fat < 10MB dos partition */
-#define FDISK_DOS16S   0x04            /* 16-bit fat < 32MB dos partition */
-#define FDISK_DOSEXT   0x05            /* extended dos partition */
-#define FDISK_DOS16B   0x06            /* 16-bit fat >= 32MB dos partition */
-
-/*
- * Format of fdisk partion entry (if present).
- */
-struct fdisk_part {
-    unsigned char      bootid;         /* bootable or not */
-    unsigned char      beghead;        /* begining head, sector, cylinder */
-    unsigned char      begsect;        /* begcyl is a 10-bit number */
-    unsigned char      begcyl;         /* High 2 bits are in begsect */
-    unsigned char      systid;         /* OS type */
-    unsigned char      endhead;        /* ending head, sector, cylinder */
-    unsigned char      endsect;        /* endcyl is a 10-bit number */
-    unsigned char      endcyl;         /* High 2 bits are in endsect */
-    unsigned long      relsect;        /* partion physical offset on disk */
-    unsigned long      numsect;        /* number of sectors in partition */
-};
-
-/*
- * Format of boot block.
- */
-struct disk_blk0 {
-    unsigned char      bootcode[DISK_BOOTSZ];
-    unsigned char      parts[FDISK_NPART][sizeof (struct fdisk_part)];
-    unsigned short     signature;
-};
-
-#endif /* DRIVER_PRIVATE */
index d56e70bdeb747764d9f60764effc46e5ae669bd5..40c852ce5e2b9ff2f0d09780d95ac87c716c7e9e 100644 (file)
 #define __LIBSAIO_LIBSAIO_H
 
 #include "libsa.h"
-#include "saio.h"
+#include "memory.h"
+#include "kernBootStruct.h"
+#include "io_inline.h"
 #include "saio_types.h"
 #include "saio_internal.h"
 
-#endif /* !__LIBSAIO_LIBSAIO_H */
\ No newline at end of file
+#endif /* !__LIBSAIO_LIBSAIO_H */
index ef3973415f6225288f5f5a3ff7bccb842cf17893..77e6ad0a7f909a309a4c734adc34eb7eb4bed5e6 100644 (file)
  */
 
 #include "libsaio.h"
-#include "memory.h"
-#include "kernBootStruct.h"
 #include "rcz_common.h"
-#include <ufs/ufs/dir.h>
+#include "rcz_decompress_file.h"
 #include <mach-o/fat.h>
 
-static int devMajor[3] = { 6, 3, 1 };          // sd, hd, fd major dev #'s
+static int devMajor[3] = { 6, 3, 1 };   // sd, hd, fd major dev #'s
+
+static int xread(int fd, char * addr, int size);
+static int loadmacho(struct mach_header * head, int dev, int io,
+                     entry_t * rentry, char ** raddr, int * rsize,
+                     int file_offset);
 
 //==========================================================================
 // Open a file for reading.  If the file doesn't exist,
 // try opening the compressed version.
 
 #ifdef RCZ_COMPRESSED_FILE_SUPPORT
-int
-openfile(char *filename, int ignored)
+int openfile(const char * filename, int ignored)
 {
     unsigned char *buf;
     int fd, size, ret;
     unsigned char *addr;
-       
+
     if ((fd = open(filename, 0)) < 0) {
-       buf = malloc(256);
-       sprintf(buf, "%s%s", filename, RCZ_EXTENSION);
-       if ((fd = open(buf, 0)) >= 0) {
-           size = rcz_file_size(fd);
-           addr = (unsigned char *)((KERNEL_ADDR + KERNEL_LEN) - size);
-           ret = rcz_decompress_file(fd, addr);
-           close(fd);
-           if (ret < 0)
-               fd = -1;
-           else
-               fd = openmem(addr, size);
-       }
-       free(buf);
+        buf = malloc(256);
+        sprintf(buf, "%s%s", filename, RCZ_EXTENSION);
+        if ((fd = open(buf, 0)) >= 0) {
+            size = rcz_file_size(fd);
+            addr = (unsigned char *)((KERNEL_ADDR + KERNEL_LEN) - size);
+            ret = rcz_decompress_file(fd, addr);
+            close(fd);
+            if (ret < 0)
+                fd = -1;
+            else
+                fd = openmem(addr, size);
+        }
+        free(buf);
     }
     return fd;
 }
 #else
-int
-openfile(char *filename, int ignored)
+int openfile(char * filename, int ignored)
 {
     return open(filename, 0);
 }
@@ -75,13 +76,10 @@ openfile(char *filename, int ignored)
 //==========================================================================
 // loadprog
 
-int
-loadprog( int                  dev,
-          int                  fd,
-          struct mach_header * headOut,
-          entry_t *            entry,       /* entry point */
-          char **              addr,        /* load address */
-          int *                size )       /* size of loaded program */
+int loadprog( int dev, int fd, struct mach_header * headOut,
+              entry_t * entry,   /* entry point */
+              char **   addr,    /* load address */
+              int *     size )   /* size of loaded program */
 {
     struct mach_header head;
     int file_offset = 0;
@@ -101,18 +99,18 @@ read_again:
     else if ( file_offset == 0 && 
               ((head.magic == FAT_CIGAM) || (head.magic == FAT_MAGIC)) )
     {
-               int swap = (head.magic == FAT_CIGAM) ? 1 : 0;
-               struct fat_header * fhp = (struct fat_header *) &head;
-               struct fat_arch *   fap;
-               int i, narch = swap ? NXSwapLong(fhp->nfat_arch) : fhp->nfat_arch;
-               int cpu, size;
-               char * buf;
-
-               size = sizeof(struct fat_arch) * narch;
-               buf = malloc(size);
+        int swap = (head.magic == FAT_CIGAM) ? 1 : 0;
+        struct fat_header * fhp = (struct fat_header *) &head;
+        struct fat_arch *   fap;
+        int i, narch = swap ? NXSwapLong(fhp->nfat_arch) : fhp->nfat_arch;
+        int cpu, size;
+        char * buf;
+
+        size = sizeof(struct fat_arch) * narch;
+        buf = malloc(size);
         b_lseek(fd, 0, 0);
         read(fd, buf, size);
-       
+    
         for ( i = 0, fap = (struct fat_arch *)(buf+sizeof(struct fat_header));
               i < narch;
               i++, fap++ )
@@ -140,110 +138,103 @@ read_again:
 //
 // Read from file descriptor. addr is a physical address.
 
-int xread( int    fd,
-           char * addr,
-           int    size )
+static int xread( int fd, char * addr, int size )
 {
-       char *      orgaddr = addr;
-       long            offset;
-       unsigned        count;
-       long            max;
+    char *      orgaddr = addr;
+    long        offset;
+    unsigned    count;
+    long        max;
 #define BUFSIZ 8192
-       char *      buf;
-       int         bufsize = BUFSIZ;
+    char *      buf;
+    int         bufsize = BUFSIZ;
 
 #if 0
     printf("xread: addr=%x, size=%x\n", addr, size);
     sleep(1);
 #endif
 
-       buf = malloc(BUFSIZ);
-       
-       // align your read to increase speed
-       offset = tell(fd) & 4095;
-       if ( offset != 0 )
-               max = 4096 - offset;
-       else
-               max = bufsize;
-
-       while ( size > 0 )
-       {
-               if ( size > max ) count = max;
-               else count = size;
+    buf = malloc(BUFSIZ);
+
+    // align your read to increase speed
+    offset = tell(fd) & 4095;
+    if ( offset != 0 )
+        max = 4096 - offset;
+    else
+        max = bufsize;
+
+    while ( size > 0 )
+    {
+        if ( size > max ) count = max;
+        else count = size;
 #if 0
-               printf("xread: loop size=%x, count=%x\n", size, count);
-               sleep(1);
+        printf("xread: loop size=%x, count=%x\n", size, count);
+        sleep(1);
 #endif
 
-               if ( read(fd, buf, count) != count) break;
+        if ( read(fd, buf, count) != count) break;
 
-               bcopy(buf, ptov(addr), count);
-               size -= count;
-               addr += count;
+        bcopy(buf, ptov(addr), count);
+        size -= count;
+        addr += count;
 
-               max = bufsize;
+        max = bufsize;
 
 #if 0
-               tick += count;
-               if ( tick > (50*1024) )
-               {
-                       putchar('+');
-                       tick = 0;
-               }
+        tick += count;
+        if ( tick > (50*1024) )
+        {
+            putchar('+');
+            tick = 0;
+        }
 #endif
-       }
+    }
 
-       free(buf);
-       return addr-orgaddr;
+    free(buf);
+    return addr-orgaddr;
 }
 
 //==========================================================================
 // loadmacho
 
-int
-loadmacho( struct mach_header * head,
-           int                  dev,
-           int                  io,
-           entry_t *            rentry,
-           char **              raddr,
-           int *                rsize,
-           int                  file_offset )
+static int loadmacho( struct mach_header * head, int dev, int io,
+                      entry_t * rentry, char ** raddr, int * rsize,
+                      int file_offset )
 {
-       int          ncmds;
-       void *       cmds;
+    int          ncmds;
+    void *       cmds;
     void *       cp;
-       unsigned int entry  = 0;
-       int          vmsize = 0;
-       unsigned int vmaddr = ~0;
+    unsigned int entry  = 0;
+    int          vmsize = 0;
+    unsigned int vmaddr = ~0;
     unsigned int vmend  = 0;
 
-       struct xxx_thread_command {
-               unsigned long   cmd;
-               unsigned long   cmdsize;
-               unsigned long   flavor;
-               unsigned long   count;
-               i386_thread_state_t state;
-       } * th;
+    struct xxx_thread_command {
+        unsigned long    cmd;
+        unsigned long    cmdsize;
+        unsigned long    flavor;
+        unsigned long    count;
+        i386_thread_state_t state;
+    } * th;
 
-       // XXX should check cputype
-       cmds = malloc(head->sizeofcmds);
-       b_lseek(io, sizeof(struct mach_header) + file_offset, 0);
+    // XXX should check cputype
+    cmds = malloc(head->sizeofcmds);
+    b_lseek(io, sizeof(struct mach_header) + file_offset, 0);
 
-       if ( read(io, (char *) cmds, head->sizeofcmds) != head->sizeofcmds )
+    if ( read(io, (char *) cmds, head->sizeofcmds) != head->sizeofcmds )
     {
-           error("loadmacho: error reading commands\n");
-           goto shread;
-       }
+        error("loadmacho: error reading commands\n");
+        goto shread;
+    }
 
-       for ( ncmds = head->ncmds, cp = cmds; ncmds > 0; ncmds-- )
-       {
-               unsigned int addr;
+    for ( ncmds = head->ncmds, cp = cmds; ncmds > 0; ncmds-- )
+    {
+        unsigned int addr;
 
-#define lcp    ((struct load_command *) cp)
-#define scp    ((struct segment_command *) cp)
+#define lcp ((struct load_command *) cp)
+#define scp ((struct segment_command *) cp)
 
-               switch ( lcp->cmd )
-               {
+        switch ( lcp->cmd )
+        {
             case LC_SEGMENT:
                 addr = (scp->vmaddr & 0x3fffffff) + (int)*raddr;
                 if ( scp->filesize )
@@ -260,7 +251,7 @@ loadmacho( struct mach_header * head,
                     // FIXME:  check to see if we overflow
                     // the available space (should be passed in
                     // as the size argument).
-                           
+  
 #if 0
                     printf("LC: fileoff %x, filesize %x, off %x, addr %x\n",
                            scp->fileoff, scp->filesize, file_offset, addr);
@@ -282,21 +273,21 @@ loadmacho( struct mach_header * head,
                 th = (struct xxx_thread_command *) cp;
                 entry = th->state.eip;
                 break;
-               }
-               cp += lcp->cmdsize;
-       }
+        }
+        cp += lcp->cmdsize;
+    }
 
-       kernBootStruct->rootdev = (dev & 0xffffff00) | devMajor[Dev(dev)];
+    kernBootStruct->rootdev = (dev & 0xffffff00) | devMajor[B_TYPE(dev)];
 
-       free(cmds);
+    free(cmds);
 
-       *rentry = (entry_t)( (int) entry & 0x3fffffff );
-       *rsize = vmend - vmaddr;
-       *raddr = (char *)vmaddr;
+    *rentry = (entry_t)( (int) entry & 0x3fffffff );
+    *rsize = vmend - vmaddr;
+    *raddr = (char *)vmaddr;
 
-       return 0;
+    return 0;
 
 shread:
-       free(cmds);
-       return -1;
+    free(cmds);
+    return -1;
 }
index ed9703fb554ff559b08b157fd3c245d0cf326259..1336ee6cb21bcac7cd4baeb1d3a9a833742ca75d 100644 (file)
@@ -44,7 +44,6 @@
  * All rights reserved.
  */
 
-#include "io_inline.h"
 #include "libsaio.h"
 
 /*
 
 void enableA20()
 {
-       /* make sure that the input buffer is empty */
-       while (inb(PORT_B) & KB_INFULL);
+    /* make sure that the input buffer is empty */
+    while (inb(PORT_B) & KB_INFULL);
 
-       /* make sure that the output buffer is empty */
-       if (inb(PORT_B) & KB_OUTFULL)
-               (void)inb(PORT_A);
+    /* make sure that the output buffer is empty */
+    if (inb(PORT_B) & KB_OUTFULL)
+        (void)inb(PORT_A);
 
-       /* make sure that the input buffer is empty */
-       while (inb(PORT_B) & KB_INFULL);
+    /* make sure that the input buffer is empty */
+    while (inb(PORT_B) & KB_INFULL);
 
-       /* write output port */
-       outb(PORT_B, CMD_WOUT);
+    /* write output port */
+    outb(PORT_B, CMD_WOUT);
 
-       /* wait until command is accepted */
-       while (inb(PORT_B) & KB_INFULL);
+    /* wait until command is accepted */
+    while (inb(PORT_B) & KB_INFULL);
 
-       outb(PORT_A, KB_A20);
+    outb(PORT_A, KB_A20);
 
-       while (inb(PORT_B) & KB_INFULL);        /* wait until done */
+    while (inb(PORT_B) & KB_INFULL);   /* wait until done */
 }
 
 void sleep(int n)
 {
-       int     endtime = (time18() + 18*n);
-       while (time18() < endtime);
+    int endtime = (time18() + 18*n);
+    while (time18() < endtime);
 }
 
 void turnOffFloppy(void)
 {
-       /*
-        * Disable floppy:
-        * Hold controller in reset,
-        * disable DMA and IRQ,
-        * turn off floppy motors.
-        */
-       outb(0x3F2, 0x00);
+    /*
+     * Disable floppy:
+     * Hold controller in reset,
+     * disable DMA and IRQ,
+     * turn off floppy motors.
+     */
+    outb(0x3F2, 0x00);
 }
 
-char * newString(char * oldString)
+char * newString(const char * oldString)
 {
     if ( oldString )
         return strcpy(malloc(strlen(oldString)+1), oldString);
     else
         return NULL;
 }
+
+void stop(const char * msg)
+{
+    error("\n%s\n", msg);
+    halt();
+}
index 3cfe1a22526026b0f64aeff8adf6d821b38f964c..bb35897e88b8b8535778ace027bd634e2983276b 100644 (file)
  */
 
 #include "libsaio.h"
-#include "nbp.h"
+
+/*
+ * Convert zero-based linear address to far pointer.
+ */
+#define GET_FP(x)   ( (((x) & 0xffff0000) << (16 - 4)) | ((x) & 0xffff) )
 
 /*==========================================================================
  * Issue a command to the network loader.
@@ -32,8 +36,7 @@
  * ensure that it resides within the addressable range for the
  * network loader, which runs in real mode.
  */
-UInt32
-nbp(nbpCommandCode_t code, nbpCommand_u * cmd)
+static UInt32 nbp(nbpCommandCode_t code, nbpCommand_u * cmd)
 {
        loader(code, GET_FP((UInt32) cmd));
 
@@ -46,33 +49,70 @@ nbp(nbpCommandCode_t code, nbpCommand_u * cmd)
 }
 
 /*==========================================================================
- * Execute a TFTP Read File command.
- *
+ * Unload Base Code Stack command.
+ */
+UInt32 nbpUnloadBaseCode()
+{
+    return nbp(nbpCommandUnloadBaseCode, (nbpCommand_u *) 0);
+}
+
+/*==========================================================================
+ * TFTP Read File command.
  */
-UInt32 nbpTFTPReadFile(UInt8 *  filename,   // name of the file
-                       UInt32 * bufferSize, // [IN] size limit, [OUT} real size
-                       UInt32   bufferAddr) // physical address
+static long NBPLoadFile(CICell ih, char * filePath)
 {
     nbpCommandTFTPReadFile_s  cmd;
        UInt32                    ret;
 
-       strcpy(cmd.filename, filename);
+       strcpy(cmd.filename, filePath);
        cmd.status     = nbpStatusFailed;
-       cmd.bufferSize = *bufferSize;
-       cmd.buffer     = bufferAddr;
+       cmd.bufferSize = TFTP_LEN;
+       cmd.buffer     = TFTP_ADDR;
 
-       ret = nbp(nbpCommandTFTPReadFile, (nbpCommand_u *) &cmd);
+    verbose("Loading file: %s\n", filePath);
 
-       *bufferSize = cmd.bufferSize;  // bytes transferred
+       ret = nbp(nbpCommandTFTPReadFile, (nbpCommand_u *) &cmd);
 
-    return ret;
+    return (ret == nbpStatusSuccess) ? cmd.bufferSize : -1;
 }
 
 /*==========================================================================
- * Execute an Unload Base Code Stack command.
- *
+ * GetDirEntry is not supported.
  */
-UInt32 nbpUnloadBaseCode()
+static long NBPGetDirEntry(CICell ih, char * dirPath, long * dirIndex,
+                           char ** name, long * flags, long * time)
 {
-    return nbp(nbpCommandUnloadBaseCode, (nbpCommand_u *) 0);
+    return -1;
+}
+
+//==========================================================================
+
+static void NBPGetDescription(CICell ih, char * str, long strMaxLen)
+{
+    sprintf( str, "Ethernet PXE Client" );
+}
+
+//==========================================================================
+
+BVRef nbpScanBootVolumes( int biosdev, int * countPtr )
+{
+    static BVRef gNetBVR = NULL;
+
+    if ( countPtr ) *countPtr = 1;
+
+    if ( !gNetBVR )
+    {
+        gNetBVR = malloc( sizeof(*gNetBVR) );
+        if ( gNetBVR )
+        {
+            bzero(gNetBVR, sizeof(*gNetBVR));
+            gNetBVR->biosdev = biosdev;
+            gNetBVR->flags   = kBVFlagPrimary | kBVFlagNativeBoot;
+            gNetBVR->description = NBPGetDescription;
+            gNetBVR->fs_loadfile = NBPLoadFile;
+            gNetBVR->fs_getdirentry = NBPGetDirEntry;
+        }
+    }
+
+    return gNetBVR;
 }
diff --git a/i386/libsaio/nbp.h b/i386/libsaio/nbp.h
deleted file mode 100644 (file)
index 63ad268..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License").  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#ifndef __LIBSAIO_NBP_H
-#define __LIBSAIO_NBP_H
-
-#include "nbp_cmd.h"
-
-/*==========================================================================
- * Call the network loader's exported entry point.
- * Function is in asm.s.
- */
-extern void loader(UInt32 code, UInt32 cmdptr);
-
-/*==========================================================================
- * Convert zero-based linear address to far pointer.
- */
-#define GET_FP(x)         ( (((x) & 0xffff0000) << (16 - 4)) | \
-                             ((x) & 0xffff) )
-
-/*==========================================================================
- * Issue a command to the network loader.
- */
-extern UInt32 nbp(nbpCommandCode_t code, nbpCommand_u * cmd);
-
-/*==========================================================================
- * Execute a TFTP Read File command.
- */
-extern UInt32 nbpTFTPReadFile(UInt8 *  filename,
-                              UInt32 * bufferSize,
-                              UInt32   bufferAddr);
-
-/*==========================================================================
- * Execute an Unload Base Code Stack command.
- */
-extern UInt32 nbpUnloadBaseCode();
-
-#endif /* !__LIBSAIO_NBP_H */
diff --git a/i386/libsaio/old/bios_old.s b/i386/libsaio/old/bios_old.s
deleted file mode 100644 (file)
index 52af82e..0000000
+++ /dev/null
@@ -1,610 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License").  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-/* 
- * Mach Operating System
- * Copyright (c) 1990 Carnegie-Mellon University
- * Copyright (c) 1989 Carnegie-Mellon University
- * All rights reserved.  The CMU software License Agreement specifies
- * the terms and conditions for use and redistribution.
- */
-
-//                     INTEL CORPORATION PROPRIETARY INFORMATION
-//
-//     This software is supplied under the terms of a license  agreement or 
-//     nondisclosure agreement with Intel Corporation and may not be copied 
-//     nor disclosed except in accordance with the terms of that agreement.
-//
-//     Copyright 1988 Intel Corporation
-// Copyright 1988, 1989 by Intel Corporation
-//
-
-       .file   "bios.s"
-
-#include <machdep/i386/asm.h>
-#include "memory.h"
-
-       .text
-
-#if 0
-// biosread(dev, cyl, head, sec, num)
-//     Read num sectors from disk into the internal buffer "intbuf" which
-//     is the first 4K bytes of the boot loader.
-// BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
-//     Call with       %ah = 0x2
-//                     %al = number of sectors
-//                     %ch = cylinder
-//                     %cl = sector
-//                     %dh = head
-//                     %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
-//                     %es:%bx = segment:offset of buffer
-//     Return:         
-//                     %al = 0x0 on success; err code on failure
-
-ENTRY(_biosread)
-       push    %ebp
-       mov     %esp, %ebp
-
-       push    %ebx
-       push    %ecx
-       push    %edx
-       push    %esi
-       push    %edi
-       push    %ds
-       push    %es
-//     push    %fs
-//     push    %gs
-
-       movb    0x10(%ebp), %dh         // head
-
-       movw    0x0c(%ebp), %cx
-       xchgb   %ch, %cl                // cylinder; %cl=the high 2 bits of cyl
-       rorb    $2, %cl
-       movb    0x14(%ebp), %al
-       orb     %al, %cl
-       incb    %cl                     // sector; sec starts from 1, not 0
-
-       movb    0x8(%ebp), %dl          // device
-       movb    0x18(%ebp),%bl          // number of sectors
-       movb    $2,%bh                  // bios read function
-
-       call    EXT(_prot_to_real)      // enter real mode, set %es to BOOTSEG
-
-       data16
-       mov     $5,%edi                 // retry up to 5 times
-
-retry_disc:
-               mov     %ebx,%eax       // get function and amount
-//             xor     %ebx, %ebx      // offset = 0
-               data16
-               mov     $(ptov(BIOS_ADDR)), %ebx
-
-               push %eax               // save amount
-               push %ecx
-               push %edx
-               push %edi
-               int     $0x13
-               pop %edi
-               pop %edx
-               pop %ecx
-               pop %ebx                // pop amount into bx (safe place)
-
-//             test $0, %ah
-               data16
-               jnb     read_succes
-
-               // woops, bios failed to read sector
-               push %eax               // save error
-               xor %eax,%eax
-               int     $0x13           // reset disk
-               pop %eax                // restore error code
-               dec %edi
-               data16
-               jne retry_disc
-
-read_succes:
-       mov     %eax, %ebx              // save return value
-
-       data16
-       call    EXT(_real_to_prot) // back to protected mode
-
-       xor     %ax, %ax
-       movb    %bh, %al                // return value in %ax
-
-//     pop     %gs
-//     pop     %fs
-       pop     %es
-       pop     %ds
-       pop     %edi
-       pop     %esi
-       pop     %edx
-       pop     %ecx
-       pop     %ebx
-
-       pop     %ebp
-
-       ret
-
-// putc(ch)
-// BIOS call "INT 10H Function 0Eh" to write character to console
-//     Call with       %ah = 0x0e
-//                     %al = character
-//                     %bh = page
-//                     %bl = foreground color ( graphics modes)
-
-
-ENTRY(_putc)
-       push    %ebp
-       mov     %esp, %ebp
-
-       push    %ebx
-       push    %ecx
-       push    %edx
-       push    %esi
-       push    %edi
-       push    %ds
-       push    %es
-
-       movb    0x8(%ebp), %cl
-
-       call    EXT(_prot_to_real)
-
-//     data16
-//     mov     $0x13, %ebx     // colors in 2 bit palette, grey and white
-//     mov     $0x1, %ebx      // %bh=0, %bl=1 (blue)
-//
-//     movb    $1,%bh          // background gray
-       movb    $0,%bh          // background gray
-       movb    $3,%bl          // foreground white in 2 bit palette
-
-       movb    $0xe, %ah
-       movb    %cl, %al
-
-       int     $0x10           // display a byte
-
-       data16
-       call    EXT(_real_to_prot)
-
-       pop     %es
-       pop     %ds
-       pop     %edi
-       pop     %esi
-       pop     %edx
-       pop     %ecx
-       pop     %ebx
-
-       pop     %ebp
-       ret
-
-ENTRY(cputc)
-       push    %ebp
-       mov     %esp, %ebp
-
-       push    %ebx
-       push    %ecx
-       push    %edx
-       push    %esi
-       push    %edi
-       push    %ds
-       push    %es
-
-       movb    0x8(%ebp), %cl
-       movb    0x12(%ebp), %bl
-       
-       call    EXT(_prot_to_real)
-
-       movb    $0,%bh          // page 0
-
-       movb    %cl, %al
-       movb    $0x9, %ah
-       movb    $1, %cx
-       
-       int     $0x10           // display a byte
-
-       data16
-       call    EXT(_real_to_prot)
-
-       pop     %es
-       pop     %ds
-       pop     %edi
-       pop     %esi
-       pop     %edx
-       pop     %ecx
-       pop     %ebx
-
-       pop     %ebp
-       ret
-
-// bgetc()
-// BIOS call "INT 16H Function 00H" to read character from keyboard
-//     Call with       %ah = 0x0
-//     Return:         %ah = keyboard scan code
-//                     %al = ASCII character
-
-ENTRY(bgetc)
-       push    %ebp
-       mov     %esp, %ebp
-
-       push    %ebx
-       push    %ecx
-       push    %edx
-       push    %esi
-       push    %edi
-       push    %ds
-       push    %es
-
-       call    EXT(_prot_to_real)
-
-       movb    $0, %ah
-       
-       int     $0x16
-
-       mov     %eax, %ebx      // _real_to_prot uses %eax
-
-       data16
-       call    EXT(_real_to_prot)
-
-       xor     %eax, %eax
-       mov     %bx, %ax
-
-       pop     %es
-       pop     %ds
-       pop     %edi
-       pop     %esi
-       pop     %edx
-       pop     %ecx
-       pop     %ebx
-
-       pop     %ebp
-       ret
-
-// readKeyboardStatus()
-//       if there is a character pending, return it; otherwise return 0
-// BIOS call "INT 16H Function 01H" to check whether a character is pending
-//     Call with       %ah = 0x1
-//     Return:
-//             If key waiting to be input:
-//                     %ah = keyboard scan code
-//                     %al = ASCII character
-//                     Zero flag = clear
-//             else
-//                     Zero flag = set
-
-ENTRY(_readKeyboardStatus)
-       push    %ebp
-       mov     %esp, %ebp
-
-       push    %ebx
-       push    %ecx
-       push    %edx
-       push    %esi
-       push    %edi
-       push    %ds
-       push    %es
-
-       call    EXT(_prot_to_real)              // enter real mode
-
-       xor     %ebx, %ebx
-       movb    $0x1, %ah
-       int     $0x16
-
-       data16
-       jz      nochar
-
-       movw    %ax, %bx
-
-nochar:
-       data16
-       call    EXT(_real_to_prot)
-
-       xor     %eax, %eax
-       movw    %bx, %ax
-
-       pop     %es
-       pop     %ds
-       pop     %edi
-       pop     %esi
-       pop     %edx
-       pop     %ecx
-       pop     %ebx
-
-       pop     %ebp
-       ret
-
-
-// time in 18ths of a second
-ENTRY(_time18)
-       push    %ebp
-       mov     %esp, %ebp
-
-       push    %ebx
-       push    %ecx
-       push    %edx
-       push    %esi
-       push    %edi
-       push    %ds
-       push    %es
-
-       call    EXT(_prot_to_real)              // enter real mode
-
-       xor     %bx, %bx
-       xor     %eax, %eax
-       int     $0x1a
-
-       mov     %edx,%ebx
-       shl     $16,%cx                         // shifts ecx
-       or      %cx,%bx                         // %ebx has 32 bit time
-
-       data16
-       call    EXT(_real_to_prot)
-
-       mov     %ebx,%eax
-
-       pop     %es
-       pop     %ds
-       pop     %edi
-       pop     %esi
-       pop     %edx
-       pop     %ecx
-       pop     %ebx
-
-       pop     %ebp
-       ret
-
-//
-// get_diskinfo():  return a word that represents the
-//     max number of sectors and  heads and drives for this device
-//
-
-ENTRY(_get_diskinfo)
-       push    %ebp
-       mov     %esp, %ebp
-
-       push    %ebx
-       push    %ecx
-       push    %edx
-       push    %esi
-       push    %edi
-       push    %ds
-       push    %es
-
-       movb    0x8(%ebp), %dl          // diskinfo(drive #)
-       call    EXT(_prot_to_real)      // enter real mode
-
-       movb    $0x8, %ah               // ask for disk info
-       int     $0x13
-
-       data16
-       call    EXT(_real_to_prot)      // back to protected mode
-
-//     form a longword representing all this gunk
-       mov     %ecx, %eax
-       shrb    $6, %al
-       andb    $0x03, %al
-       xchgb   %ah, %al                // ax has max cyl
-       shl     $16, %eax
-       
-       movb    %dh, %ah                // # heads
-       andb    $0x3f, %cl              // mask of cylinder gunk
-       movb    %cl, %al                // # sectors
-
-       pop     %es
-       pop     %ds
-       pop     %edi
-       pop     %esi
-       pop     %edx
-       pop     %ecx
-       pop     %ebx
-
-       pop     %ebp
-       ret
-#endif
-#if 0
-//
-// getEisaInfo(<slot>):  return an int that represents the
-//     vendor id for the specified slot (0 < slot < 64)
-//     returns 0 for any error
-//     returns bytes in the order [0 1 2 3] in %eax;
-
-ENTRY(getEisaInfo)
-       push    %ebp
-       mov     %esp, %ebp
-
-       push    %ebx
-       push    %ecx
-       push    %edx
-       push    %esi
-       push    %edi
-       push    %ds
-       push    %es
-
-       movb    0x8(%ebp), %cl          // slot #
-       call    EXT(_prot_to_real)      // enter real mode
-
-       movb    $0,%al
-       movb    $0xd8, %ah              // eisa slot info
-       int     $0x15
-
-       data16
-       call    EXT(_real_to_prot)      // back to protected mode
-
-       movb    %ah,%bl
-       xor     %eax,%eax
-
-       test    $0,%bl
-       jne     eisaerr
-
-//     form a longword representing all this gunk
-       mov     %esi, %eax
-       shl     $16, %eax
-       mov     %di,%ax
-       bswap   %eax
-
-eisaerr:       
-       pop     %es
-       pop     %ds
-       pop     %edi
-       pop     %esi
-       pop     %edx
-       pop     %ecx
-       pop     %ebx
-
-       pop     %ebp
-       ret
-#endif
-
-#if 0
-//
-// memsize(i) :  return the memory size in KB. i == 0 for conventional memory,
-//             i == 1 for extended memory
-//     BIOS call "INT 12H" to get conventional memory size
-//     BIOS call "INT 15H, AH=88H" to get extended memory size
-//             Both have the return value in AX.
-//
-
-ENTRY(_memsize)
-       push    %ebp
-       mov     %esp, %ebp
-
-       push    %ebx
-       push    %ecx
-       push    %edx
-       push    %esi
-       push    %edi
-       push    %ds
-       push    %es
-
-       mov     8(%ebp), %ebx
-       call    EXT(_prot_to_real)              // enter real mode
-       cmpb    $0x1, %bl
-       data16
-       je      xext
-       int     $0x12
-       data16
-       jmp     xdone
-xext:
-       movb    $0x88, %ah
-       int     $0x15
-xdone:
-       mov     %eax, %ebx
-       data16
-       call    EXT(_real_to_prot)
-       xor     %eax, %eax
-       mov     %ebx, %eax
-
-       pop     %es
-       pop     %ds
-       pop     %edi
-       pop     %esi
-       pop     %edx
-       pop     %ecx
-       pop     %ebx
-
-       pop     %ebp
-       ret
-
-
-// video_mode(mode)
-// BIOS call "INT 10H Function 0h" to set vga graphics mode
-
-
-ENTRY(_video_mode)
-       push    %ebp
-       mov     %esp, %ebp
-
-       push    %ebx
-       push    %ecx
-       push    %edx
-       push    %esi
-       push    %edi
-       push    %ds
-       push    %es
-
-       movb    0x8(%ebp), %cl
-
-       call    EXT(_prot_to_real)
-
-       movb    $0, %ah
-       movb    %cl, %al
-
-       int     $0x10           // display a byte
-
-       data16
-       call    EXT(_real_to_prot)
-
-       pop     %es
-       pop     %ds
-       pop     %edi
-       pop     %esi
-       pop     %edx
-       pop     %ecx
-       pop     %ebx
-
-       pop     %ebp
-       ret
-
-
-
-// setCursorPosition(x,y)
-// BIOS call "INT 10H Function 2" to set cursor position
-
-
-ENTRY(_setCursorPosition)
-       push    %ebp
-       mov     %esp, %ebp
-
-       push    %ebx
-       push    %ecx
-       push    %edx
-       push    %esi
-       push    %edi
-       push    %ds
-       push    %es
-
-       movb    0x8(%ebp), %cl
-       movb    0xc(%ebp), %ch
-
-       call    EXT(_prot_to_real)
-
-       movb    $2, %ah         // setcursor function
-       movb    $0, %bh         // page num 0 for graphics
-       movb    %cl, %dl        // column, x
-       movb    %ch, %dh        // row, y
-
-       int     $0x10           // set cursor
-
-       data16
-       call    EXT(_real_to_prot)
-
-       pop     %es
-       pop     %ds
-       pop     %edi
-       pop     %esi
-       pop     %edx
-       pop     %ecx
-       pop     %ebx
-
-       pop     %ebp
-       ret
-#endif
-
diff --git a/i386/libsaio/old/shmalloc.c b/i386/libsaio/old/shmalloc.c
deleted file mode 100644 (file)
index 09b136b..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License").  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-#import "libsa.h"
-#import "libsaio.h"
-
-void *sh_malloc(size_t size) {return malloc(size);}
-void sh_free(void *start) { free(start); }
-void *sh_realloc(void *ptr, size_t size) {return realloc(ptr,size);}
diff --git a/i386/libsaio/old/stringTable.h.00 b/i386/libsaio/old/stringTable.h.00
deleted file mode 100644 (file)
index bdb7441..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * string table functions.
- */
-
-#import "saio_types.h"
-
-extern char *
-newStringFromList(
-    char **list,
-    int *size
-);
-extern int stringLength(char *table, int compress);
-extern BOOL getValueForStringTableKey(char *table, char *key, char **val, int *size);
-extern char *newStringForStringTableKey(
-       char *table,
-       char *key
-);
-extern BOOL getValueForBootKey(char *line, char *match, char **matchval, int *len);
-extern BOOL getValueForKey(
-    char *key,
-    char **val,
-    int *size
-);
-extern char *
-loadLocalizableStrings(
-    char *name
-);
-extern char *
-bundleLongName(
-    char *bundleName
-);
-extern loadConfigFile( char *configFile, char **table, int allocTable);
-extern int
-loadConfigDir(
-    char *bundleName,  // bundle directory name (e.g. "System.config")
-    int useDefault,    // use Default.table instead of instance tables
-    char **table,      // returns pointer to config table
-    int allocTable     // zalloc the table and return in *table
-);
-extern loadSystemConfig(
-    char *which,
-    int size
-);
-extern int
-loadOtherConfigs(
-    int useDefault
-);
-
-
-
-
-
diff --git a/i386/libsaio/old/stringTableNew.c b/i386/libsaio/old/stringTableNew.c
deleted file mode 100644 (file)
index cd2664a..0000000
+++ /dev/null
@@ -1,564 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License").  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright 1993 NeXT, Inc.
- * All rights reserved.
- */
-
-#import "libsaio.h"
-#import "kernBootStruct.h"
-#import "stringConstants.h"
-#import <driverkit/configTablePrivate.h>
-
-extern KERNBOOTSTRUCT *kernBootStruct;
-extern char *Language;
-extern char *LoadableFamilies;
-
-
-static char_ret
-getachar(
-    char       **string_p
-)
-{
-    register char *str = *string_p;
-    register int c;
-    char_ret   r;
-    
-    c = *str++;
-    if (c == '\\') {
-       r.quoted = YES;
-       c = *str++;
-       switch(c) {
-       case 'n':
-           c = '\n';
-           break;
-       case 'r':
-           c = '\r';
-           break;
-       case 't':
-           c = '\t';
-           break;
-       default:
-           break;
-       }
-    } else {
-       r.quoted = NO;
-    }
-    *string_p = str;
-    r.c = c;
-    return r;
-}
-
-/*
- * A token is:
- * <non_space_non_semicolon>*
- * "<non_quote>*"
- * <semicolon>
- */
-char *
-get_token(
-    char       **string_p
-)
-{
-    char *begin;
-    char *newstr;
-    char_ret r;
-    int len;
-    
-    do {
-       r = getachar(string_p);
-    } while (r.c && isspace(r.c));
-
-    if (!r.quoted && r.c == '\"') {
-       begin = *string_p;
-       do {
-           r = getachar(string_p);
-       } while (r.c && !r.quoted && r.c != '\"');
-    } else {
-       begin = *string_p - 1;
-       do {
-           r = getachar(string_p);
-       } while (r.c && !r.quoted && r.c != ';' && !isspace(r.c));
-    }
-    len = *string_p - begin - 1;
-    newstr = (char *)malloc(len + 1);
-    strncpy(newstr, begin, len);
-    newstr[len] = '\0';
-    return newstr;
-}
-
-
-char *
-stringFromList(
-    char **list,
-    int *size
-)
-{
-    char *begin = *list, *end;
-    char *newstr;
-    int newsize = *size;
-    
-    while (*begin && newsize && isspace(*begin)) {
-       begin++;
-       newsize--;
-    }
-    end = begin;
-    while (*end && newsize && !isspace(*end)) {
-       end++;
-       newsize--;
-    }
-    if (begin == end)
-       return 0;
-    newstr = malloc(end - begin + 1);
-    strncpy(newstr, begin, end - begin);
-    *list = end;
-    *size = newsize;
-    return newstr;
-}
-
-char *
-valueForStringTableKey(
-    char *table,
-    char *key
-)
-{
-    char *token;
-    enum {
-       KEY,
-       EQUALS,
-       VALUE,
-       SEMICOLON,
-       BEGINCOMMENT,
-       ENDCOMMENT
-    } state;
-    BOOL foundKey;
-    int len;
-    
-    state = KEY;
-    foundKey = NO;
-    while (*table) {
-       token = get_token(&table);
-       switch(state) {
-       case KEY:
-           if (strcmp(token, key) == 0)
-               foundKey = YES;
-           if (strncmp(token, "/*", 2) == 0)
-               state = ENDCOMMENT;
-           else
-               state = EQUALS;
-           break;
-       case EQUALS:
-           if (strcmp(token, "=") == 0) {
-               state = VALUE;
-           }
-           break;
-       case VALUE:
-           if (foundKey) {
-               return token;
-           }
-           state = SEMICOLON;
-           break;
-       case SEMICOLON:
-           if (strcmp(token, ";") == 0) {
-               state = KEY;
-           }
-           break;
-       case ENDCOMMENT:
-           len = strlen(token);
-           if (len >= 2 && strncmp(token + len - 2, "*/", 2) == 0)
-               state = KEY;
-           break;
-       }
-       free(token);
-    }
-    return 0;
-}
-
-char *
-valueForBootKey(
-    char *line,
-    char *match
-)
-{
-    char *token;
-    enum {
-       KEY,
-       EQUALS,
-       VALUE,
-       WHITESPACE
-    } state;
-    BOOL foundKey;
-    int len;
-
-    state = KEY;
-    while (*line) {
-       token = get_token(&line);
-    }
-}
-
-BOOL
-boolForKey(
-    char *key
-)
-{
-    char *str = valueForKey(key);
-    BOOL ret;
-    
-    if (str && (str[0] == 'Y' || str[1] == 'y'))
-       ret = YES;
-    else
-       ret = NO;
-    free(str);
-    return ret;
-}
-
-BOOL
-getIntForKey(
-    char *key,
-    int *value
-)
-{
-    char *str = valueForKey(key), *ptr = str;
-    int sum;
-    BOOL ret;
-    
-    if (str) {
-       for (sum = 0; size > 0; size--) {
-           sum = (sum * 10) + (*ptr++ - '0');
-       }
-       *value = sum;
-       ret = YES;
-    } else {
-       ret = NO;
-    }
-    free(str);
-    return ret;
-}
-
-char *
-valueForKey(
-    char *key
-)
-{
-    char *str = valueForBootKey(kernBootStruct->bootString, key);;
-    
-    if (str)
-       return str;
-    else
-       return valueForStringTableKey(kernBootStruct->config, key);
-}
-
-#define        LOCALIZABLE_PATH \
-       "%s/%s.config/%s.lproj/%s.strings"
-char *
-loadLocalizableStrings(
-    char *name,
-    char *tableName
-)
-{
-    char buf[256], *config;
-    register int i, count, fd = -1;
-    char * paths[] = {
-       ARCH_DEVICES,
-       USR_DEVICES,
-       "/",
-       NULL
-    }, **path;
-    
-    for (i=0; i<2; i++) {
-       for (path = paths; *path; path++) {
-           sprintf(buf, LOCALIZABLE_PATH, *path, name,
-                  (i == 0) ? Language : "English", tableName);
-           if ((fd = open(buf, 0)) >= 0) {
-               i = 2;
-               break;
-           }
-       }
-    }
-    if (fd < 0)
-       return 0;
-    count = file_size(fd);
-    config = malloc(count);
-    count = read(fd, config, count);
-    close(fd);
-    if (count <= 0) {
-       free(config);
-       return 0;
-    }
-    return config;
-}
-
-char *
-bundleLongName(
-    char *bundleName,
-    char *tableName
-)
-{
-    char *table, *name, *val;
-    int size;
-    
-    table = loadLocalizableStrings(bundleName,
-       tableName ? tableName : "Localizable");
-    if ( table != 0 &&
-        getValueForStringTableKey(table,"Long Name", &val, &size) == YES) {
-       name = malloc(size+1);
-       strncpy(name, val, size);
-       free(table);
-    } else {
-       name = newString(bundleName);
-    }
-    return name;
-}
-
-int sysConfigValid;
-
-void
-addConfig(
-    char *config
-)
-{
-    char *configPtr = kernBootStruct->configEnd;
-    int len = strlen(config);
-    
-    if ((configPtr - kernBootStruct->config) > CONFIG_SIZE) {
-       error("No room in memory for config files\n");
-       return;
-    }
-    strcpy(configPtr, config);
-    configPtr += (len + 1);
-    *configPtr = 0;
-    kernBootStruct->configEnd = configPtr;
-}
-
-/*
- * Returns 0 if file loaded OK,
- *        -1 if file was not loaded
- * Does not print error messages.
- * Returns pointer to table in memory in *table.
- */
-int
-loadConfigFile( char *configFile, char **table, BOOL allocTable)
-{
-    char *configPtr = kernBootStruct->configEnd;
-    int fd, count;
-    
-    /* Read config file into memory */
-    if ((fd = open(configFile, 0)) >= 0)
-    {
-       if (allocTable) {
-           configPtr = malloc(file_size(fd)+2);
-       } else {
-           if ((configPtr - kernBootStruct->config) > CONFIG_SIZE) {
-               error("No room in memory for config files\n");
-               close(fd);
-               return -1;
-           }
-           verbose("Reading configuration file '%s'.\n",configFile);       
-       }
-       if (table) *table = configPtr;
-       count = read(fd, configPtr, IO_CONFIG_DATA_SIZE);
-       close(fd);
-
-       configPtr += count;
-       *configPtr++ = 0;
-       *configPtr = 0;
-       if (!allocTable)
-           kernBootStruct->configEnd = configPtr;
-
-       return 0;
-    } else {
-       return -1;
-    }
-}
-
-/* Returns 0 if requested config files were loaded,
- *         1 if default files were loaded,
- *        -1 if no files were loaded.
- * Prints error message if files cannot be loaded.
- */
-int
-loadConfigDir(
-    char *bundleName,  // bundle directory name (e.g. "System")
-    BOOL useDefault,   // use Default.table instead of instance tables
-    char **table,      // returns pointer to config table
-    BOOL allocTable    // malloc the table and return in *table
-)
-{
-    char *buf;
-    int i, ret;
-    BOOL archConfig = dirExists(ARCH_DEVICES);
-    
-    buf = malloc(256);
-    ret = 0;
-    
-    // load up to 99 instance tables
-    for (i=0; i < 99; i++) {
-       sprintf(buf, "%s/%s.config/Instance%d.table",
-               archConfig ? ARCH_DEVICES : USR_DEVICES,
-               bundleName, i);
-       if (useDefault || (loadConfigFile(buf, table, allocTable) != 0)) {
-           if (i == 0) {
-               // couldn't load first instance table;
-               // try the default table
-               sprintf(buf, "%s/%s.config/%s",
-                       archConfig ? ARCH_DEVICES : USR_DEVICES,
-                       bundleName,
-                       IO_DEFAULT_TABLE_FILENAME);
-               if (loadConfigFile(buf, table, allocTable) == 0) {
-                   ret = 1;
-               } else {
-                   if (!allocTable)
-                       error("Config file \"%s\" not found\n", buf);
-                   ret = -1;
-               }
-           }
-           // we must be done.
-           break;
-       }
-    }
-    free(buf);
-    return ret;
-}
-
-
-#define USR_SYSTEM_CONFIG \
-       USR_DEVICES "/System.config"
-#define USR_SYSTEM_DEFAULT_FILE \
-       USR_SYSTEM_CONFIG "/Default.table"
-#define ARCH_SYSTEM_CONFIG \
-       ARCH_DEVICES "/System.config"
-#define ARCH_SYSTEM_DEFAULT_FILE \
-       ARCH_SYSTEM_CONFIG "/Default.table"
-#define SYSTEM_CONFIG "System"
-#define LP '('
-#define RP ')'
-
-/* Returns 0 if requested config files were loaded,
- *         1 if default files were loaded,
- *        -1 if no files were loaded.
- * Prints error message if files cannot be loaded.
- */
-int
-loadSystemConfig(
-    char *which,
-    int size
-)
-{
-    char *buf, *bp, *cp;
-    int ret, len, doDefault=0;
-    BOOL archConfig = dirExists(ARCH_DEVICES);
-
-    buf = bp = malloc(256);
-    if (which && size)
-    {
-       for(cp = which, len = size; len && *cp && *cp != LP; cp++, len--) ;
-       if (*cp == LP) {
-           while (len-- && *cp && *cp++ != RP) ;
-           /* cp now points past device */
-           strncpy(buf,which,cp - which);
-           bp += cp - which;
-       } else {
-           cp = which;
-           len = size;
-       }
-       if (*cp != '/') {
-           strcpy(bp, archConfig ?
-               ARCH_SYSTEM_CONFIG : USR_SYSTEM_CONFIG);
-           strcat(bp, "/");
-           strncat(bp, cp, len);
-           if (strncmp(cp + len - strlen(IO_TABLE_EXTENSION),
-                      IO_TABLE_EXTENSION, strlen(IO_TABLE_EXTENSION)) != 0)
-               strcat(bp, IO_TABLE_EXTENSION);
-       } else {
-           strncpy(bp, cp, len);
-           bp[size] = '\0';
-       }
-       if ((strcmp(bp, USR_SYSTEM_DEFAULT_FILE) == 0) ||
-           (strcmp(bp, ARCH_SYSTEM_DEFAULT_FILE) == 0))
-           doDefault = 1;
-       ret = loadConfigFile(bp = buf, 0, 0);
-    } else {
-       ret = loadConfigDir((bp = SYSTEM_CONFIG), 0, 0, 0);
-    }
-    if (ret < 0) {
-       error("System config file '%s' not found\n", bp);
-    } else
-       sysConfigValid = 1;
-    free(buf);
-    return (ret < 0 ? ret : doDefault);
-}
-
-
-int
-loadOtherConfigs(
-    int useDefault
-)
-{
-    char *val, *table;
-    int count;
-    char *string;
-    int fd, ret;
-
-    if (getValueForKey( "Boot Drivers", &val, &count))
-    {
-       while (string = stringFromList(&val, &count)) {
-           ret = loadConfigDir(string, useDefault, &table, 0);
-           if (ret >= 0) {
-               if ((fd = openDriverReloc(string)) >= 0) {
-                   verbose("Loading binary for %s device driver.\n",string);
-                   if (loadDriver(string, fd) < 0)
-                       error("Error loading %s device driver.\n",string);
-                   close(fd);
-               }
-               driverWasLoaded(string, table, NULL);
-               free(string);
-           } else {
-               driverIsMissing(string);
-           }
-       }
-    } else {
-       error("Warning: No active drivers specified in system config.\n");
-    }
-
-    kernBootStruct->first_addr0 =
-           (int)kernBootStruct->configEnd + 1024;
-    return 0;
-}
-
-static BOOL
-dirExists(char *path)
-{
-    int fd;
-    
-    if ((fd = open(path, 0)) < 0) {
-       return NO;
-    } else {
-       close(fd);
-       return YES;
-    }
-}
-
-
-
index 7fd0542fa205735d24f9838b35afadface850ea0..1650bb6115e5d5ce8b8d7b16ced65b959cef64e3 100644 (file)
  *     Created
  */
 
-#include <mach/mach_types.h>
-// #include "legacy/KernDevice.h"
-#include "legacy/PCI.h"
-
-#include "kernBootStruct.h"
 #include "libsaio.h"
-#include "io_inline.h"
 #include "pci.h"
 
 static BOOL testMethod1(void);
@@ -76,7 +70,6 @@ PCI_Bus_Init(
     PCI_bus_info_t *info       /* pass in the PCI boot info struct */
 )
 {
-
     unsigned int maxBusNum = 0, maxDevNum = 0, useMethod = 0;
     _pci_bus_method_t method = NULL;
     _pci_slot_info_t *slot_array;
@@ -104,14 +97,13 @@ PCI_Bus_Init(
        }
     }
 
-
     if (useMethod == 1)
        method = getMethod1;
     else if (useMethod == 2)
        method = getMethod2;
     else
        return NULL;
-       
+
     nslots = scanBus(maxBusNum, maxDevNum, method, NULL);
     slot_array = (_pci_slot_info_t *)
        malloc(sizeof(_pci_slot_info_t) * nslots +1);
index 5a334bf764f9d564e203739a8fad1aa59c2d32aa..d1fde1a91c7ad34f6d90c6a1d57fe306bf608b44 100644 (file)
@@ -38,4 +38,48 @@ typedef struct _pci_slot_info {
 
 extern _pci_slot_info_t *PCISlotInfo;
 
+/* The IOPCIConfigSpace structure can be used to decode the 256 byte
+ * configuration space presented by each PCI device.  This structure
+ * is based on the PCI LOCAL BUS SPECIFICATION, rev 2.1, section 6.1
+ */
+
+typedef struct _IOPCIConfigSpace {
+       unsigned short  VendorID;
+       unsigned short  DeviceID;
+       unsigned short  Command;
+       unsigned short  Status;
+       unsigned long   RevisionID:8;
+       unsigned long   ClassCode:24;
+       unsigned char   CacheLineSize;
+       unsigned char   LatencyTimer;
+       unsigned char   HeaderType;
+       unsigned char   BuiltInSelfTest;
+       unsigned long   BaseAddress[6];
+       unsigned long   CardbusCISpointer;
+       unsigned short  SubVendorID;
+       unsigned short  SubDeviceID;
+       unsigned long   ROMBaseAddress;
+       unsigned long   reserved3;
+       unsigned long   reserved4;
+       unsigned char   InterruptLine;
+       unsigned char   InterruptPin;
+       unsigned char   MinGrant;
+       unsigned char   MaxLatency;
+       unsigned long   VendorUnique[48];
+} IOPCIConfigSpace;
+
+
+/* PCI_DEFAULT_DATA is the value resulting from a read to a non-existent
+ * PCI device's configuration space.
+ */
+
+#define PCI_DEFAULT_DATA       0xffffffff
+
+
+/* PCI_INVALID_VENDOR_ID is a Vendor ID reserved by the PCI/SIG and is
+ * guaranteed not to be assigned to any vendor.
+ */
+
+#define        PCI_INVALID_VENDOR_ID   0xffff
+
 #endif /* !__LIBSAIO_PCI_H */
diff --git a/i386/libsaio/saio.h b/i386/libsaio/saio.h
deleted file mode 100644 (file)
index 4b70b70..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License").  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-/* 
- * Mach Operating System
- * Copyright (c) 1990 Carnegie-Mellon University
- * Copyright (c) 1989 Carnegie-Mellon University
- * Copyright (c) 1988 Carnegie-Mellon University
- * All rights reserved.  The CMU software License Agreement specifies
- * the terms and conditions for use and redistribution.
- *
- */
-/*
- * Copyright (c) 1982, 1986 Regents of the University of California.
- * All rights reserved.  The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
- *
- *  @(#)saio.h  7.1 (Berkeley) 6/5/86
- */
-
-#ifndef __LIBSAIO_SAIO_H
-#define __LIBSAIO_SAIO_H
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/vnode.h>
-#include <ufs/ufs/quota.h>
-#include <ufs/ufs/inode.h>
-
-/*
- * Io block: includes an inode, cells for the use of seek, etc,
- * and a buffer.
- */
-struct  iob {
-    int             i_flgs;        /* see F_ below */
-    struct inode    i_ino;         /* inode, if file */
-    daddr_t         i_boff;        /* block offset on device */
-    unsigned int    i_offset;      /* seek offset in file */
-    daddr_t         i_bn;          /* 1st block # of next read */
-    char *          i_ma;          /* memory address of i/o buffer */
-    int             i_cc;          /* character count of transfer */
-    int             i_error;       /* error # return */
-    char *          i_buf;         /* i/o buffer */
-    struct fs *     i_ffs;         /* file system super block info */
-    int             biosdev;       /* bios device for file, i_ino inadequate */
-    daddr_t         dirbuf_blkno;  /* blk of currently buffered dir */
-    int             partition;     /* which partition */
-};
-
-struct dirstuff {
-    int          loc;
-    struct iob * io;
-};
-
-#define F_READ      0x1            /* file opened for reading */
-#define F_WRITE     0x2            /* file opened for writing */
-#define F_ALLOC     0x4            /* buffer allocated */
-#define F_FILE      0x8            /* file instead of device */
-#define F_NBSF      0x10           /* no bad sector forwarding */
-#define F_SSI       0x40           /* set skip sector inhibit */
-#define F_MEM       0x80           /* memory instead of file or device */
-
-/* IO types */
-#define F_RDDATA    0x0100         /* read data */
-#define F_WRDATA    0x0200         /* write data */
-#define F_HDR       0x0400         /* include header on next i/o */
-
-#define F_TYPEMASK  0xff00
-
-extern char * devsw[];
-
-/*
- * Request codes. Must be the same a F_XXX above
- */
-#define READ    1
-#define WRITE   2
-
-#define NBUFS   4
-extern char *   b[NBUFS];
-extern daddr_t  blknos[NBUFS];
-
-#define NFILES  6
-extern struct   iob iob[NFILES];
-
-/* Error codes */
-#define EBADF   1   /* bad file descriptor */
-#define EOFFSET 2   /* relative seek not supported */
-#define EDEV    3   /* improper device specification on open */
-#define ENXIO   4   /* unknown device specified */
-#define ESRCH   6   /* directory search for file failed */
-#define EIO     7   /* generic error */
-#define ECMD    10  /* undefined driver command */
-#define EBSE    11  /* bad sector error */
-#define EWCK    12  /* write check error */
-#define EECC    13  /* uncorrectable ecc error */
-#define EHER    14  /* hard error */
-
-#define BIOS_DEV_FLOPPY  0x0
-#define BIOS_DEV_HD      0x80
-#define BIOS_DEV_WIN     BIOS_DEV_HD
-#define BIOS_DEV_EN      0xff  /* not really a BIOS device number */
-
-#define DEV_SD      0
-#define DEV_HD      1
-#define DEV_FLOPPY  2
-#define DEV_EN      3
-
-#define BIOSDEV(dev)    ((dev) == DEV_FLOPPY ? BIOS_DEV_FLOPPY : BIOS_DEV_WIN)
-
-#define NSECS   16  /* number of buffered 512 byte sectors */
-
-#define        Dev(x)          (((x)>>B_TYPESHIFT)&B_TYPEMASK)
-
-#ifndef max
-#define max(a,b) ((a) > (b) ? (a) : (b))
-#endif
-
-#ifndef min
-#define min(a,b) ((a) < (b) ? (a) : (b))
-#endif
-
-#endif /* !__LIBSAIO_SAIO_H */
index 16968b444ad146bbca9a8733c92a8f5816e083d3..6ecde2d6ee743df76170007815fc187769b4eb5d 100644 (file)
 #include "saio_types.h"
 
 /* asm.s */
-extern void  real_to_prot(void);
-extern void  prot_to_real(void);
-extern void  halt(void);
-extern void  startprog(unsigned int address);
+extern void   real_to_prot(void);
+extern void   prot_to_real(void);
+extern void   halt(void);
+extern void   startprog(unsigned int address);
+extern void   loader(UInt32 code, UInt32 cmdptr);
 
 /* bios.s */
-extern void  bios(biosBuf_t *bb);
-extern void  get_memsize(biosBuf_t *bb);
+extern void   bios(biosBuf_t *bb);
+extern void   get_memsize(biosBuf_t *bb);
 
 /* biosfn.c */
 #ifdef EISA_SUPPORT
-extern BOOL eisa_present(void);
+extern BOOL   eisa_present(void);
 #endif
-extern int  bgetc(void);
-extern int  biosread(int dev, int cyl, int head, int sec, int num);
-extern int  ebiosread(int dev, long sec, int count);
-extern void putc(int ch);
-extern int  getc(void);
-extern int  readKeyboardStatus(void);
-extern unsigned int  time18(void);
-extern unsigned int  get_diskinfo(int dev);
-extern int  APMPresent(void);
-extern int  APMConnect32(void);
-extern int  memsize(int i);
-extern void video_mode(int mode);
-extern void setCursorPosition(int x, int y);
+extern int    bgetc(void);
+extern int    biosread(int dev, int cyl, int head, int sec, int num);
+extern int    ebiosread(int dev, long sec, int count);
+extern void   putc(int ch);
+extern void   putca(int ch, int attr, int repeat);
+extern int    getc(void);
+extern int    readKeyboardStatus(void);
+extern unsigned int time18(void);
+extern unsigned int get_diskinfo(int dev);
+extern int    APMPresent(void);
+extern int    APMConnect32(void);
+extern int    memsize(int i);
+extern void   video_mode(int mode);
+extern void   setCursorPosition(int x, int y, int page);
+extern void   setCursorType(int type);
+extern void   getCursorPositionAndType(int *x, int *y, int *type);
+extern void   scollPage(int x1, int y1, int x2, int y2, int attr, int rows, int dir);
+extern void   clearScreenRows(int y1, int y2);
+extern void   setActiveDisplayPage( int page );
 
 /* bootstruct.c */
-extern void initKernBootStruct(void);
+extern void   initKernBootStruct(int biosdev);
+
+/* cache.c */
+extern void   CacheInit(CICell ih, long blockSize);
+extern long   CacheRead(CICell ih, char *buffer, long long offset,
+                        long length, long cache);
 
 /* console.c */
-extern BOOL gVerboseMode;
-extern void putchar(int ch);
-extern int  getchar(void);
-extern int  printf(const char *format, ...);
-extern int  error(const char *format, ...);
-extern int  verbose(const char *format, ...);
+extern BOOL   gVerboseMode;
+extern BOOL   gErrors;
+extern void   putchar(int ch);
+extern int    getchar(void);
+extern int    printf(const char *format, ...);
+extern int    error(const char *format, ...);
+extern int    verbose(const char *format, ...);
 
 /* disk.c */
-extern void devopen(char *name, struct iob *io);
-extern int devread(struct iob *io);
-extern void devflush(void);
-
-/* gets.c */
-extern int  gets(char *buf, int len);
-extern int  Gets(
-    char *buf,
-    int len,
-    int timeout,
-    char *prompt,
-    char *message
-);
+extern BVRef  diskScanBootVolumes(int biosdev, int *count);
+extern void   diskSeek(BVRef bvr, long long position);
+extern int    diskRead(BVRef bvr, long addr, long length);
+extern int    readBootSector(int biosdev, unsigned int secno, void *buffer);
 
 /* load.c */
-extern int openfile(char *filename, int ignored);
-
-extern int  loadmacho(
-    struct mach_header *head,
-    int dev,
-    int io,
-    entry_t *entry,
-    char **addr,
-    int *size,
-    int file_offset
-);
-extern int  loadprog(
-    int dev,
-    int fd,
-    struct mach_header *headOut,
-    entry_t *entry,
-    char **addr,
-    int *size
-);
+extern int    openfile(const char *filename, int ignored);
+extern int    loadprog(int dev, int fd, struct mach_header *headOut,
+                       entry_t *entry, char **addr, int *size);
 
 /* misc.c */
-extern void  sleep(int n);
-extern void  enableA20(void);
-extern void  turnOffFloppy(void);
-extern char *newString(char *oldString);
+extern void   sleep(int n);
+extern void   enableA20(void);
+extern void   turnOffFloppy(void);
+extern char * newString(const char *oldString);
+extern void   stop(const char *message);
+
+/* nbp.c */
+extern UInt32 nbpUnloadBaseCode();
+extern BVRef  nbpScanBootVolumes(int biosdev, int *count);
 
 /* stringTable.c */
 extern char * newStringFromList(char **list, int *size);
-extern int    stringLength(char *table, int compress);
-extern BOOL   getValueForStringTableKey(char *table, char *key, char **val, int *size);
+extern int    stringLength(const char *table, int compress);
+extern BOOL   getValueForStringTableKey(const char *table, const char *key, const char **val, int *size);
 extern BOOL   removeKeyFromTable(const char *key, char *table);
 extern char * newStringForStringTableKey(char *table, char *key);
 extern char * newStringForKey(char *key);
-extern BOOL   getValueForBootKey(char *line, char *match, char **matchval, int *len);
-extern BOOL   getValueForKey(char *key, char **val, int *size);
-extern BOOL   getBoolForKey(char *key);
-extern BOOL   getIntForKey(char *key, int *val);
+extern BOOL   getValueForBootKey(const char *line, const char *match, const char **matchval, int *len);
+extern BOOL   getValueForKey(const char *key, const char **val, int *size);
+extern BOOL   getBoolForKey(const char *key);
+extern BOOL   getIntForKey(const char *key, int *val);
 #if 0
 extern char * loadLocalizableStrings(char *name, char *tableName);
 extern char * bundleLongName(char *bundleName, char *tableName);
 extern int    loadOtherConfigs(int useDefault);
 #endif
-extern int    loadConfigFile( char *configFile, char **table, BOOL allocTable);
-extern int    loadConfigDir(char *bundleName, BOOL useDefault, char **table,
+extern int    loadConfigFile(const char *configFile, const char **table, BOOL allocTable);
+extern int    loadConfigDir(const char *bundleName, BOOL useDefault, const char **table,
                             BOOL allocTable);
-extern int    loadSystemConfig(char *which, int size);
-extern void   addConfig(char *config);
+extern int    loadSystemConfig(const char *which, int size);
+extern void   addConfig(const char *config);
 
 /* sys.c */
-extern void stop(char *message);
-extern int  openmem(char * buf, int len);
-extern int  open(char *str, int how);
-extern int  close(int fdesc);
-extern int  file_size(int fdesc);
-extern int  read(int fdesc, char *buf, int count);
-extern int  b_lseek(int fdesc, unsigned int addr, int ptr);
-extern int  tell(int fdesc);
-extern void  flushdev(void);
-extern char *usrDevices(void);
-extern struct dirstuff * opendir(char *path);
-extern int  closedir(struct dirstuff *dirp);
-extern struct direct * readdir(struct dirstuff *dirp);
-extern int  currentdev(void);
-extern int  switchdev(int dev);
-
-/* ufs_byteorder.c */
-extern void byte_swap_superblock(struct fs *sb);
-extern void byte_swap_inode_in(struct dinode *dc, struct dinode *ic);
-extern void byte_swap_dir_block_in(char *addr, int count);
-
-/*
- * vbe.c
- */
-extern int  set_linear_video_mode(unsigned short mode);
-
-/*
- * vga.c
- */
-extern void set_video_mode(unsigned int mode);
+extern long   LoadFile(const char *fileSpec);
+extern long   GetDirEntry(const char *dirSpec, long *dirIndex, const char **name,
+                          long *flags, long *time);
+extern long   GetFileInfo(const char *dirSpec, const char *name,
+                          long *flags, long *time);
+extern int    openmem(char *buf, int len);
+extern int    open(const char *str, int how);
+extern int    close(int fdesc);
+extern int    file_size(int fdesc);
+extern int    read(int fdesc, char *buf, int count);
+extern int    b_lseek(int fdesc, int addr, int ptr);
+extern int    tell(int fdesc);
+extern const char * usrDevices(void);
+extern struct dirstuff * opendir(const char *path);
+extern int    closedir(struct dirstuff *dirp);
+extern int    readdir(struct dirstuff *dirp, const char **name, long *flags, long *time);
+extern void   flushdev(void);
+extern int    currentdev(void);
+extern int    switchdev(int dev);
+extern BVRef  scanBootVolumes(int biosdev, int *count);
+extern BVRef  selectBootVolume(BVRef chain);
+extern void   getBootVolumeDescription(BVRef bvr, char *str, long strMaxLen);
 
 #endif /* !__LIBSAIO_SAIO_INTERNAL_H */
index b98d4ea8c9d62d1df43e41eb27e7a5c13dd2e9dc..e78fc1a253e8c5b6ea6edf39a013e4641b643f84 100644 (file)
 #ifndef __LIBSAIO_SAIO_TYPES_H
 #define __LIBSAIO_SAIO_TYPES_H
 
-typedef char BOOL;
-#define NO  0
-#define YES 1
-
-#include <mach-o/loader.h>
-#undef i386_THREAD_STATE
-#undef i386_THREAD_STATE_COUNT
-#include <mach/i386/thread_status.h>
 #include <sys/reboot.h>
+#include <sys/types.h>
+#include "bios.h"
+#include "nbp_cmd.h"
 
-typedef unsigned long  entry_t;
+#if 0
+#define DEBUG_DISK(x)    printf x
+#else
+#define DEBUG_DISK(x)
+#endif
 
-#include <stdarg.h>
-#include "bios.h"
-#include "saio.h"
+typedef char BOOL;
+#define NO   0
+#define YES  1
+
+typedef unsigned long entry_t;
 
 typedef struct {
     unsigned int sectors:8;
@@ -55,4 +56,86 @@ struct driveParameters {
     int totalDrives;
 };
 
+struct         BootVolume;
+typedef struct BootVolume * BVRef;
+typedef struct BootVolume * CICell;
+
+typedef long (*FSInit)(CICell ih);
+typedef long (*FSLoadFile)(CICell ih, char * filePath);
+typedef long (*FSGetDirEntry)(CICell ih, char * dirPath, long * dirIndex,
+                              char ** name, long * flags, long * time);
+typedef void (*BVGetDescription)(CICell ih, char * str, long strMaxLen);
+
+struct iob {
+    unsigned int   i_flgs;          /* see F_* below */
+    unsigned int   i_offset;        /* seek byte offset in file */
+    int            i_filesize;      /* size of file */
+    char *         i_buf;           /* file load address */
+};
+
+#define F_READ     0x1              /* file opened for reading */
+#define F_WRITE    0x2              /* file opened for writing */
+#define F_ALLOC    0x4              /* buffer allocated */
+#define F_FILE     0x8              /* file instead of device */
+#define F_NBSF     0x10             /* no bad sector forwarding */
+#define F_SSI      0x40             /* set skip sector inhibit */
+#define F_MEM      0x80             /* memory instead of file or device */
+
+struct dirstuff {
+    char *         dir_path;        /* directory path */
+    long           dir_index;       /* directory entry index */
+    BVRef          dir_bvr;         /* volume reference */
+};
+
+struct BootVolume {
+    BVRef            next;            /* list linkage pointer */
+    int              biosdev;         /* BIOS device number */
+    unsigned int     flags;           /* attribute flags */
+    BVGetDescription description;     /* BVGetDescription function */
+    int              part_no;         /* partition number (1 based) */
+    unsigned int     part_boff;       /* partition block offset */
+    unsigned int     part_type;       /* partition type */
+    unsigned int     fs_boff;         /* 1st block # of next read */
+    FSLoadFile       fs_loadfile;     /* FSLoadFile function */
+    FSGetDirEntry    fs_getdirentry;  /* FSGetDirEntry function */
+};
+
+enum {
+    kBVFlagPrimary     = 0x01,
+    kBVFlagNativeBoot  = 0x02,
+    kBVFlagForeignBoot = 0x04
+};
+
+enum {
+    kBIOSDevTypeFloppy    = 0x00,
+    kBIOSDevTypeHardDrive = 0x80,
+    kBIOSDevTypeNetwork   = 0xE0,
+    kBIOSDevUnitMask      = 0x0F,
+    kBIOSDevTypeMask      = 0xF0,
+    kBIOSDevMask          = 0xFF
+};
+
+#define BIOS_DEV_TYPE(d)  ((d) & kBIOSDevTypeMask)
+#define BIOS_DEV_UNIT(d)  ((d) & kBIOSDevUnitMask)
+
+/*
+ * KernBootStruct device types.
+ */
+enum {
+    DEV_SD = 0,
+    DEV_HD = 1,
+    DEV_FD = 2,
+    DEV_EN = 3
+};
+
+#ifndef max
+#define max(a,b) ((a) > (b) ? (a) : (b))
+#endif
+
+#ifndef min
+#define min(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+#define MAKEKERNDEV(t, u, p)  MAKEBOOTDEV(t, 0, 0, u, p)
+
 #endif /* !__LIBSAIO_SAIO_TYPES_H */
diff --git a/i386/libsaio/sl.h b/i386/libsaio/sl.h
new file mode 100644 (file)
index 0000000..baa9e67
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef __LIBSAIO_SL_H
+#define __LIBSAIO_SL_H
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/vnode.h>
+#include "libsaio.h"
+
+#define SWAP_BE16(x)  NXSwapBigShortToHost(x)
+#define SWAP_BE32(x)  NXSwapBigLongToHost(x)
+#define SWAP_BE64(x)  NXSwapBigLongLongToHost(x)
+
+// File Permissions and Types
+enum {
+    kPermOtherExecute  = 1 << 0,
+    kPermOtherWrite    = 1 << 1,
+    kPermOtherRead     = 1 << 2,
+    kPermGroupExecute  = 1 << 3,
+    kPermGroupWrite    = 1 << 4,
+    kPermGroupRead     = 1 << 5,
+    kPermOwnerExecute  = 1 << 6,
+    kPermOwnerWrite    = 1 << 7,
+    kPermOwnerRead     = 1 << 8,
+    kPermMask          = 0x1FF,
+    kOwnerNotRoot      = 1 << 9,
+    kFileTypeUnknown   = 0x0 << 16,
+    kFileTypeFlat      = 0x1 << 16,
+    kFileTypeDirectory = 0x2 << 16,
+    kFileTypeLink      = 0x3 << 16,
+    kFileTypeMask      = 0x3 << 16
+};
+
+#define Seek(c, p)     diskSeek(c, p);
+#define Read(c, a, l)  diskRead(c, a, l);
+
+extern void * gFSLoadAddress;
+
+#endif /* !__LIBSAIO_SL_H */
index 8fafe9bcd284efb72082d5d286bf022dd50097b7..1d917316bae9cfe86deb63b1d108b5d2eb38570b 100644 (file)
@@ -27,7 +27,6 @@
  */
 
 #include "libsaio.h"
-#include "kernBootStruct.h"
 #include "stringConstants.h"
 #include "legacy/configTablePrivate.h"
 
@@ -35,7 +34,7 @@ extern KERNBOOTSTRUCT *kernBootStruct;
 extern char *Language;
 extern char *LoadableFamilies;
 
-static void eatThru(char val, char **table_p);
+static void eatThru(char val, const char **table_p);
 
 static inline int isspace(char c)
 {
@@ -46,7 +45,7 @@ static inline int isspace(char c)
  * Compare a string to a key with quoted characters
  */
 static inline int
-keyncmp(char *str, char *key, int n)
+keyncmp(const char *str, const char *key, int n)
 {
     int c;
     while (n--) {
@@ -76,9 +75,9 @@ keyncmp(char *str, char *key, int n)
     return 0;
 }
 
-static void eatThru(char val, char **table_p)
+static void eatThru(char val, const char **table_p)
 {
-       register char *table = *table_p;
+       register const char *table = *table_p;
        register BOOL found = NO;
 
        while (*table && !found)
@@ -170,7 +169,7 @@ newStringFromList(
 /* 
  * compress == compress escaped characters to one character
  */
-int stringLength(char *table, int compress)
+int stringLength(const char *table, int compress)
 {
        int ret = 0;
 
@@ -193,10 +192,10 @@ int stringLength(char *table, int compress)
 
 // looks in table for strings of format << "key" = "value"; >>
 // or << "key"; >>
-BOOL getValueForStringTableKey(char *table, char *key, char **val, int *size)
+BOOL getValueForStringTableKey(const char *table, const char *key, const char **val, int *size)
 {
        int keyLength;
-       char *tableKey;
+       const char *tableKey;
 
        do
        {
@@ -249,11 +248,12 @@ char *newStringForStringTableKey(
        char *key
 )
 {
-    char *val, *newstr, *p;
+    const char *val;
+    char *newstr, *p;
     int size;
     
     if (getValueForStringTableKey(table, key, &val, &size)) {
-       newstr = malloc(size+1);
+       newstr = (char *)malloc(size+1);
        for (p = newstr; size; size--, p++, val++) {
            if ((*p = *val) == '\\') {
                switch (*++val) {
@@ -283,11 +283,12 @@ char *newStringForStringTableKey(
 char *
 newStringForKey(char *key)
 {
-    char *val, *newstr;
+    const char *val;
+    char *newstr;
     int size;
     
     if (getValueForKey(key, &val, &size) && size) {
-       newstr = malloc(size + 1);
+       newstr = (char *)malloc(size + 1);
        strncpy(newstr, val, size);
        return newstr;
     } else {
@@ -301,7 +302,7 @@ newStringForKey(char *key)
  * non-whitespace characters, or enclosed in quotes.
  */
 
-static char *getToken(char *line, char **begin, int *len)
+static const char *getToken(const char *line, const char **begin, int *len)
 {
     if (*line == '\"') {
        *begin = ++line;
@@ -317,9 +318,9 @@ static char *getToken(char *line, char **begin, int *len)
     return line;
 }
 
-BOOL getValueForBootKey(char *line, char *match, char **matchval, int *len)
+BOOL getValueForBootKey(const char *line, const char *match, const char **matchval, int *len)
 {
-    char *key, *value;
+    const char *key, *value;
     int key_len, value_len;
     
     while (*line) {
@@ -346,10 +347,10 @@ BOOL getValueForBootKey(char *line, char *match, char **matchval, int *len)
 }
 
 BOOL getBoolForKey(
-    char *key
+    const char *key
 )
 {
-    char *val;
+    const char *val;
     int size;
     
     if (getValueForKey(key, &val, &size) && (size >= 1) &&
@@ -359,11 +360,11 @@ BOOL getBoolForKey(
 }
 
 BOOL getIntForKey(
-    char *key,
+    const char *key,
     int *value
 )
 {
-    char *val;
+    const char *val;
     int size, sum;
     
     if (getValueForKey(key, &val, &size)) {
@@ -377,8 +378,8 @@ BOOL getIntForKey(
 }
 
 BOOL getValueForKey(
-    char *key,
-    char **val,
+    const char *key,
+    const char **val,
     int *size
 )
 {
@@ -401,7 +402,7 @@ loadLocalizableStrings(
 {
     char buf[256], *config;
     register int count, fd = -1;
-    char *device_dir = usrDevices();
+    const char *device_dir = usrDevices();
     
     sprintf(buf, LOCALIZABLE_PATH, device_dir, name,
            Language, tableName);
@@ -462,7 +463,7 @@ int sysConfigValid;
 
 void
 addConfig(
-    char *config
+    const char *config
 )
 {
     char *configPtr = kernBootStruct->configEnd;
@@ -488,7 +489,7 @@ addConfig(
  * Allocates an extra number of bytes for table expansion.
  */
 int
-loadConfigFile( char *configFile, char **table, BOOL allocTable)
+loadConfigFile(const char *configFile, const char **table, BOOL allocTable)
 {
     char *configPtr = kernBootStruct->configEnd;
     int fd, count;
@@ -530,15 +531,15 @@ loadConfigFile( char *configFile, char **table, BOOL allocTable)
  
 int
 loadConfigDir(
-    char *bundleName,  // bundle directory name (e.g. "System")
+    const char *bundleName,    // bundle directory name (e.g. "System")
     BOOL useDefault,   // use Default.table instead of instance tables
-    char **table,      // returns pointer to config table
+    const char **table,        // returns pointer to config table
     BOOL allocTable    // malloc the table and return in *table
 )
 {
     char *buf;
     int i, max, ret;
-    char *device_dir = usrDevices();
+    const char *device_dir = usrDevices();
     
     buf = malloc(256);
     ret = 0;
@@ -598,13 +599,14 @@ static int sysconfig_dev;
  */
 int
 loadSystemConfig(
-    char *which,
+    const char *which,
     int size
 )
 {
-    char *buf, *bp, *cp;
+    char *buf, *bp;
+    const char *cp;
     int ret, len, doDefault=0;
-    char *device_dir = usrDevices();
+    const char *device_dir = usrDevices();
 
 #if 0
                printf("In Load system config which=%d ; size=%d\n", which, size);
index e8b75b449d8ebe82fdb136a1932f4156f14ccff6..b4e88ed56b0d9d3aeb812240e6ea3ff7b237fb14 100644 (file)
  *     @(#)sys.c       7.1 (Berkeley) 6/5/86
  */
 
-#include <sys/param.h>
-#include <ufs/ufs/dir.h>
-#include <sys/reboot.h>
-#include <architecture/byte_order.h>
-#include "ufs_byteorder.h"
 #include "libsaio.h"
-#include "cache.h"
-#include "kernBootStruct.h"
-#include "stringConstants.h"
-#include <ufs/ffs/fs.h>
-#include "nbp.h"
-#include "memory.h"
-
-char * gFilename;
-
-extern int ram_debug_sarld;            // in load.c
-
-#define DCACHE            1
-#define ICACHE            1
-#define SYS_MESSAGES      1
-#define CHECK_CAREFULLY   0
-#define COMPRESSION       1
-
-// #define DEBUG 1
-
-#ifdef DEBUG
-#define DPRINT(x)       { printf x; }
-#define DSPRINT(x)      { printf x; sleep(2); }
-#define RDPRINT(x)      { if (ram_debug_sarld) printf x; }
-#define RDSPRINT(x)     { if (ram_debug_sarld) printf x; sleep(2); }
-#else
-#define DPRINT(x)
-#define DSPRINT(x)
-#define RDPRINT(x)
-#define RDSPRINT(x)
-#endif
-
-char * devsw[] = {
-    "sd",
-    "hd",
-    "fd",
-    "en",
-    NULL
+
+struct devsw {
+    const char *  name;
+    unsigned char biosdev;
 };
 
-//#############################################################################
-//#
-//# Disk filesystem functions.
-//#
-//#############################################################################
+static struct devsw devsw[] =
+{
+    { "sd", 0x80 },  /* DEV_SD */
+    { "hd", 0x80 },  /* DEV_HD */
+    { "fd", 0x00 },  /* DEV_FD */
+    { "en", 0xE0 },  /* DEV_EN */
+    { 0, 0 }
+};
 
-static ino_t dlook(char *s, struct iob *io);
-static char * xx(char *str, struct iob *file);
-static int ffs(register long mask);
+/*
+ * Max number of file descriptors.
+ */
+#define NFILES  6
 
-extern int label_secsize;
+static struct iob iob[NFILES];
 
-#define BIG_ENDIAN_INTEL_FS __LITTLE_ENDIAN__
+void * gFSLoadAddress = 0;
 
-#if ICACHE
-#define ICACHE_SIZE       256
-#define ICACHE_READAHEAD  8    // read behind and read ahead
-static cache_t * icache;
-#endif ICACHE
+static BVRef getBootVolumeRef( const char * path, const char ** outPath );
+static BVRef newBootVolumeRef( int biosdev, int partno );
 
-#if DCACHE
-#define DCACHE_SIZE       16   // 1k (DIRBLKSIZ) blocks
-static cache_t * dcache;
-#endif
+//==========================================================================
+// LoadFile - LOW-LEVEL FILESYSTEM FUNCTION.
+//            Load the specified file to the load buffer at LOAD_ADDR.
 
-#define        DEV_BSIZE         label_secsize
+long LoadFile(const char * fileSpec)
+{
+    const char * filePath;
+    long         fileSize;
+    BVRef        bvr;
 
-#if CHECK_CAREFULLY
-static int open_init;
-#endif
+    // Resolve the boot volume from the file spec.
 
-static struct fs * fs_block;
-static int         fs_block_valid;
+    if ((bvr = getBootVolumeRef(fileSpec, &filePath)) == NULL)
+        return -1;
 
-#define SUPERBLOCK_ERROR  "Bad superblock: error %d\n"
+    // Read file into load buffer. The data in the load buffer will be
+    // overwritten by the next LoadFile() call.
 
-/*==========================================================================
- *
- *
- */
-static struct iob * iob_from_fdesc(int fdesc)
-{
-    register struct iob * file;
-    
-    if (fdesc < 0 || fdesc >= NFILES ||
-        ((file = &iob[fdesc])->i_flgs & F_ALLOC) == 0)
-           return NULL;
-    else
-           return file;
-}
+    gFSLoadAddress = (void *) LOAD_ADDR;
 
+    fileSize = bvr->fs_loadfile(bvr, (char *)filePath);
 
-/***************************************************************************
- *
- * Disk functions.
- *
- ***************************************************************************/
+    // Return the size of the file, or -1 if load failed.
 
-/*==========================================================================
- *
- *
- */
-static int
-openi(int n, struct iob * io)
-{
-       struct dinode * dp;
-       int    cc, i, j, n_round;
-
-#if ICACHE
-       struct dinode *ip;
-       
-       if (icache == 0) {
-           icache = cacheInit(ICACHE_SIZE, sizeof(struct dinode));
-       }
-#endif /* ICACHE */
-
-       io->i_offset = 0;
-       io->i_bn = fsbtodb(io->i_ffs, ino_to_fsba(io->i_ffs, n)) + io->i_boff;
-       io->i_cc = io->i_ffs->fs_bsize;
-       io->i_ma = io->i_buf;
-
-#if ICACHE
-       if (cacheFind(icache, n, 0, (char **)&ip) == 1) {
-               io->i_ino.i_din = *ip;
-               cc = 0;
-       } else {
-#endif ICACHE
-        cc = devread(io);
-           dp = (struct dinode *)io->i_buf;
-           n_round = (n / INOPB(io->i_ffs)) * INOPB(io->i_ffs);
-#if ICACHE
-           /* Read multiple inodes into cache */
-        for (i = max(ino_to_fsbo(io->i_ffs, n) - ICACHE_READAHEAD, 0),
-             j = min(i+2*ICACHE_READAHEAD, INOPB(io->i_ffs)); i < j; i++) {
-            cacheFind(icache, n_round + i, 0, (char **)&ip);
-
-#if    BIG_ENDIAN_INTEL_FS
-#warning Building with Big Endian changes
-            byte_swap_dinode_in(&dp[i]);
-#endif /* BIG_ENDIAN_INTEL_FS */
-
-            *ip = dp[i];
-            if (i == ino_to_fsbo(io->i_ffs, n)) {
-                io->i_ino.i_din = *ip;
-            }
-           }
-       }
-#else ICACHE
-
-#if     BIG_ENDIAN_INTEL_FS
-    byte_swap_dinode_in(&dp[ino_to_fsbo(io->i_ffs, n)]);
-#endif  /* BIG_ENDIAN_INTEL_FS */
-
-    io->i_ino.i_din = dp[ino_to_fsbo(io->i_ffs, n)];
-#endif ICACHE
-       
-    io->i_ino.i_number = n;
-       return (cc);
+    return fileSize;
 }
 
-/*==========================================================================
- *
- *
- */
-static int
-readlink(struct iob * io, char * buf, int len)
+//==========================================================================
+// GetDirEntry - LOW-LEVEL FILESYSTEM FUNCTION.
+//               Fetch the next directory entry for the given directory.
+
+long GetDirEntry(const char * dirSpec, long * dirIndex, const char ** name, 
+                 long * flags, long * time)
 {
-       register struct inode * ip;
-       
-       ip = &io->i_ino;
-#if 1
-    /* read contents */
-    io->i_offset = 0;
-    io->i_cc = 0;
-    io->i_flgs |= F_FILE;
-    if (read(io - iob, buf, len) < 0)
+    const char * dirPath;
+    BVRef        bvr;
+
+    // Resolve the boot volume from the dir spec.
+
+    if ((bvr = getBootVolumeRef(dirSpec, &dirPath)) == NULL)
         return -1;
-#else    
-       if (ip->i_icflags & IC_FASTLINK) {
-          if (ip->i_size > len)
-           return -1;
-           bcopy(ip->i_symlink, buf, ip->i_size);
-       } else {
-           /* read contents */
-           io->i_offset = 0;
-           io->i_cc = 0;
-           io->i_flgs |= F_FILE;
-           if (read(io - iob, buf, len) < 0)
-               return -1;
-       }
-#endif
-       return 0;
+
+    // Return 0 on success, or -1 if there are no additional entries.
+
+    return bvr->fs_getdirentry( bvr,
+                /* dirPath */   (char *)dirPath,
+                /* dirIndex */  dirIndex,
+                /* dirEntry */  (char **)name, flags, time );
 }
 
-/*==========================================================================
- *
- *
- */
-static int
-find(char * path, struct iob * file)
+//==========================================================================
+// GetFileInfo - LOW-LEVEL FILESYSTEM FUNCTION.
+//               Get attributes for the specified file.
+
+long GetFileInfo(const char * dirSpec, const char * name,
+                 long * flags, long * time)
 {
-       char * q;
-       char   c;
-       int    n, parent;
-       char * lbuf = malloc(MAXPATHLEN + 1);
-       int    ret;
-
-#if    CHECK_CAREFULLY
-       if (path==NULL || *path=='\0') {
-               error("null path\n");
-               ret = 0; goto out;
-       }
-#endif CHECK_CAREFULLY
-
-    DSPRINT(("in find: path=%s\n", path));
-
-root:
-       n = ROOTINO;
-       if (openi(n, file) < 0)
-       {
-        DPRINT(("openi failed\n"));
-
-#if    SYS_MESSAGES
-               error("bad root inode\n");
-#endif
-
-               ret = 0; goto out;
-       }
-    DPRINT(("openi ok\n"));
-
-       while (*path)
-       {
-               while (*path == '/')
-                       path++;
-               q = path;
-               while(*q != '/' && *q != '\0')
-                       q++;
-               c = *q;
-               *q = '\0';
-               if (q == path) path = "." ;     /* "/" means "/." */
-
-               parent = n;
-               if ((n = dlook(path, file)) != 0)
-               {
-                       if (c == '\0')
-                               break;
-                       if (openi(n, file) < 0)
-                       {
-                               *q = c;
-                               ret = 0; goto out;
-                       }
-                       *q = c;
-                       path = q;
-
-                       /* Check for symlinks */
-                       if (file->i_ino.i_mode & IFLNK) {
-                           char *buf = malloc(MAXPATHLEN + 1);
-                           if (readlink(file, buf, MAXPATHLEN + 1) < 0)
-                               return -1;
-                           strcat(buf, q);
-                           strcpy(lbuf, buf);
-                           free(buf);
-                           path = lbuf;
-                           if (*path == '/')
-                               goto root;
-                           if (openi(parent, file) < 0) {
-                               ret = 0; goto out;
-                           }
-                       }
-                       continue;
-               }
-               else
-               {
-                       *q = c;
-                       ret = 0; goto out;
-               }
-       }
-       ret = n;
-out:
-       free(lbuf);
-       return (ret);
+    long         index = 0;
+    const char * entryName;
+
+    while (GetDirEntry(dirSpec, &index, &entryName, flags, time) == 0)
+    {
+        if (strcmp(entryName, name) == 0)
+            return 0;  // success
+    }
+    return -1;  // file not found
 }
 
-/*==========================================================================
- *
- *
- */
-static daddr_t
-sbmap(struct iob * io, daddr_t bn)
+//==========================================================================
+// iob_from_fdesc()
+//
+// Return a pointer to an allocated 'iob' based on the file descriptor
+// provided. Returns NULL if the file descriptor given is invalid.
+
+static struct iob * iob_from_fdesc(int fdesc)
 {
-       register struct inode * ip;
-       int     i, j, sh;
-       daddr_t nb, * bap;
-
-       ip = &io->i_ino;
-
-       if (bn < 0) {
-#if    SYS_MESSAGES
-               error("bn negative\n");
-#endif
-               return ((daddr_t)0);
-       }
-
-       /*
-        * blocks 0..NDADDR are direct blocks
-        */
-       if (bn < NDADDR)
-       {
-               nb = ip->i_db[bn];
-               return (nb);
-       }
-
-       /*
-        * addresses NIADDR have single and double indirect blocks.
-        * the first step is to determine how many levels of indirection.
-        */
-    RDPRINT(("In NINADDR\n"));
-
-       sh = 1;
-       bn -= NDADDR;
-       for (j = NIADDR; j > 0; j--) {
-               sh *= NINDIR(io->i_ffs);
-               if (bn < sh)
-                       break;
-               bn -= sh;
-       }
-
-       if (j == 0) {
-#if    SYS_MESSAGES
-               error("bn ovf %d\n", bn);
-#endif
-               return ((daddr_t)0);
-       }
-
-       /*
-        * fetch the first indirect block address from the inode
-        */
-       nb = ip->i_ib[NIADDR - j];
-       if (nb == 0) {
-#if    SYS_MESSAGES
-               error("bn void %d\n",bn);
-#endif
-               return ((daddr_t)0);
-       }
-
-       /*
-        * fetch through the indirect blocks
-        */
-       for (; j <= NIADDR; j++) {
-               if (blknos[j] != nb) {
-                       io->i_bn = fsbtodb(io->i_ffs, nb) + io->i_boff;
-                       if (b[j] == (char *)0)
-                               b[j] = malloc(MAXBSIZE);
-                       io->i_ma = b[j];
-                       io->i_cc = io->i_ffs->fs_bsize;
-
-            RDPRINT(("Indir block read\n"));
-
-                       if (devread(io) != io->i_ffs->fs_bsize) {
-#if    SYS_MESSAGES
-                               error("bn %d: read error\n", io->i_bn);
-#endif
-                               return ((daddr_t)0);
-                       }
-                       blknos[j] = nb;
-               }
-               bap = (daddr_t *)b[j];
-               sh /= NINDIR(io->i_ffs);
-               i = (bn / sh) % NINDIR(io->i_ffs);
-#if    BIG_ENDIAN_INTEL_FS
-               nb = NXSwapBigLongToHost(bap[i]);
-#else  /* BIG_ENDIAN_INTEL_FS */
-               nb = bap[i];
-#endif /* BIG_ENDIAN_INTEL_FS */
-               if (nb == 0) {
-#if    SYS_MESSAGES
-                       error("bn void %d\n",bn);
-#endif
-                       return ((daddr_t)0);
-               }
-       }
-
-       return (nb);
+    register struct iob * io;
+
+    if (fdesc < 0 || fdesc >= NFILES ||
+        ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0)
+        return NULL;
+    else
+        return io;
 }
 
-/*==========================================================================
- *
- *
- */
-static struct dirstuff *
-disk_opendir(char * path)
+//==========================================================================
+// openmem()
+
+int openmem(char * buf, int len)
 {
-    register struct dirstuff * dirp;
-    register int fd;
-    
-    dirp = (struct dirstuff *)malloc(sizeof(struct dirstuff));
-    if (dirp == (struct dirstuff *)-1)
-        return 0;
+    int          fdesc;
+    struct iob * io;
 
-    DPRINT(("Calling open in opendir\n"));
-    fd = open(path,0);
-    if (fd == -1) {
-        DPRINT(("open failed \n"));
-        free((void *)dirp);
-        return 0;
-    }
+    // Locate a free descriptor slot.
 
-    DPRINT(("open ok fd is %d \n", fd));
-    dirp->io = &iob[fd];
-    dirp->loc = 0;
-    iob[fd].dirbuf_blkno = -1;
+    for (fdesc = 0; fdesc < NFILES; fdesc++)
+        if (iob[fdesc].i_flgs == 0)
+            goto gotfile;
 
-    return dirp;
-}
+    stop("Out of file descriptors");
 
-/*==========================================================================
- *
- *
- */
-static int
-disk_closedir(struct dirstuff * dirp)
-{
-    close(dirp->io - iob);
-    free((void *)dirp);
-    return 0;
-}
+gotfile:
+    io = &iob[fdesc];
+    bzero(io, sizeof(*io));
 
-/*==========================================================================
- * get next entry in a directory.
- */
-static struct direct *
-disk_readdir(struct dirstuff * dirp)
-{
-       struct direct *       dp;
-       register struct iob * io;
-       daddr_t               lbn, d;
-       int                   off;
-#if DCACHE
-       char *                bp;
-       int                   dirblkno;
-
-       if (dcache == 0)
-               dcache = cacheInit(DCACHE_SIZE, DIRBLKSIZ);
-#endif DCACHE
-
-       io = dirp->io;
-       for(;;)
-       {
-               if (dirp->loc >= io->i_ino.i_size)
-                       return (NULL);
-               off = blkoff(io->i_ffs, dirp->loc);
-               lbn = lblkno(io->i_ffs, dirp->loc);
-
-#if DCACHE
-               dirblkno = dirp->loc / DIRBLKSIZ;
-               if (cacheFind(dcache, io->i_ino.i_number, dirblkno, &bp)) {
-                   dp = (struct direct *)(bp + (dirp->loc % DIRBLKSIZ));
-               } else
-#else DCACHE
-               if (io->dirbuf_blkno != lbn)
-#endif DCACHE
-               {
-                   if((d = sbmap(io, lbn)) == 0)
-                           return NULL;
-                   io->i_bn = fsbtodb(io->i_ffs, d) + io->i_boff;
-                   io->i_ma = io->i_buf;
-                   io->i_cc = blksize(io->i_ffs, &io->i_ino, lbn);
-               
-                   if (devread(io) < 0)
-                   {
-#if    SYS_MESSAGES
-                           error("bn %d: directory read error\n", io->i_bn);
-#endif
-                           return (NULL);
-                   }
-#if    BIG_ENDIAN_INTEL_FS
-                   byte_swap_dir_block_in(io->i_buf, io->i_cc);
-#endif /* BIG_ENDIAN_INTEL_FS */
-
-#if DCACHE
-                   bcopy(io->i_buf + dirblkno * DIRBLKSIZ, bp, DIRBLKSIZ);
-                   dp = (struct direct *)(io->i_buf + off);
-#endif
-               }
-#if !DCACHE
-               dp = (struct direct *)(io->i_buf + off);
-#endif
-               dirp->loc += dp->d_reclen;
-
-               if (dp->d_ino != 0) return (dp);
-       }
-}
+    // Mark the descriptor as taken. Set the F_MEM flag to indicate
+    // that the file buffer is provided by the caller.
 
-/*==========================================================================
- *
- *
- */
-static ino_t
-dlook(
-       char *       s,
-       struct iob * io
-)
-{
-       struct direct *         dp;
-       register struct inode * ip;
-       struct dirstuff         dirp;
-       int                     len;
-
-       if (s == NULL || *s == '\0')
-               return (0);
-       ip = &io->i_ino;
-       if ((ip->i_mode & IFMT) != IFDIR) {
-#if    SYS_MESSAGES
-               error(". before %s not a dir\n", s);
-#endif
-               return (0);
-       }
-       if (ip->i_size == 0) {
-#if    SYS_MESSAGES
-               error("%s: 0 length dir\n", s);
-#endif
-               return (0);
-       }
-       len = strlen(s);
-       dirp.loc = 0;
-       dirp.io = io;
-       io->dirbuf_blkno = -1;
-
-       for (dp = disk_readdir(&dirp); dp != NULL; dp = disk_readdir(&dirp)) {
-        DPRINT(("checking name %s\n", dp->d_name));
-               if(dp->d_ino == 0)
-                       continue;
-               if (dp->d_namlen == len && !strcmp(s, dp->d_name))
-                       return (dp->d_ino);
-       }
-       return (0);
-}
+    io->i_flgs     = F_ALLOC | F_MEM;
+    io->i_buf      = buf;
+    io->i_filesize = len;
 
-/*==========================================================================
- *
- *
- */
-static int
-getch(int fdesc)
-{
-       register struct iob * io;
-       struct fs *           fs;
-       char *                p;
-       int                   c, lbn, off, size, diff;
-
-       if ((io = iob_from_fdesc(fdesc)) == 0) {
-               return (-1);
-       }
-
-    RDPRINT(("In getch\n"));
-
-    p = io->i_ma;
-       if (io->i_cc <= 0) {
-               if ((io->i_flgs & F_FILE) != 0) {
-                       diff = io->i_ino.i_size - io->i_offset;
-                       if (diff <= 0)
-                               return (-1);
-                       fs = io->i_ffs;
-                       lbn = lblkno(fs, io->i_offset);
-#if 1
-                       io->i_bn = fsbtodb(fs, sbmap(io, lbn)) + io->i_boff;
-#else
-                       io->i_bn = fsbtodb(fs, sbmap(io, lbn)) + io->i_boff;
-#endif
-                       off = blkoff(fs, io->i_offset);
-                       size = blksize(fs, &io->i_ino, lbn);
-               } else {
-                       diff = 0;
-#ifndef        SMALL
-                       io->i_bn = io->i_offset / DEV_BSIZE;
-                       off = 0;
-                       size = DEV_BSIZE;
-#endif SMALL
-               }
-
-        RDPRINT(("gc: bn=%x; off=%x\n",io->i_bn, io->i_offset));
-       
-        io->i_ma = io->i_buf;
-               io->i_cc = size;
-               if (devread(io) < 0) {
-                       return (-1);
-               }
-               if ((io->i_flgs & F_FILE) != 0) {
-                       if (io->i_offset - off + size >= io->i_ino.i_size)
-                               io->i_cc = diff + off;
-                       io->i_cc -= off;
-               }
-               p = &io->i_buf[off];
-       }
-       io->i_cc--;
-       io->i_offset++;
-       c = (unsigned)*p++;
-       io->i_ma = p;
-       return (c);
+    return fdesc;
 }
 
-/*==========================================================================
- *
- */
-static int
-disk_read(int fdesc, char * buf, int count)
-{
-       int                   i, size;
-       register struct iob * file;
-       struct fs *           fs;
-       int                   lbn, off;
-
-    RDSPRINT(("IN READ\n"));
-
-       if ((file = iob_from_fdesc(fdesc)) == 0) {
-               return (-1);
-       }
-#if CHECK_CAREFULLY
-       if ((file->i_flgs&F_READ) == 0) {
-               return (-1);
-       }
-#endif
-       if ((file->i_flgs & F_MEM) != 0) {
-
-        RDSPRINT(("In read FMEM\n"));
-
-           if (file->i_offset < file->i_boff) {
-            if (count > (file->i_boff - file->i_offset))
-                count = file->i_boff - file->i_offset;
-            bcopy(file->i_buf + file->i_offset, buf, count);
-            file->i_offset += count;
-           } else {
-            count = 0;
-           }
-           return count;
-       }
-       
-#ifndef        SMALL
-       if ((file->i_flgs & F_FILE) == 0) {
-               file->i_cc = count;
-               file->i_ma = buf;
-               file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE);
-
-        RDPRINT(("In read nsmall fbn=%x; offset=%x;", file->i_bn,
-                 file->i_offset));
-        RDSPRINT(("boff=%x\n", file->i_boff));
-
-               i = devread(file);
-               file->i_offset += count;
-               return (i);
-       }
-#endif /* SMALL */
-
-       if (file->i_offset+count > file->i_ino.i_size)
-               count = file->i_ino.i_size - file->i_offset;
-
-    RDSPRINT(("In read nsmall count=%x;", count));
-
-    if ((i = count) <= 0)
-        return (0);
-
-       /*
-        * While reading full blocks, do I/O into user buffer.
-        * Anything else uses getc().
-        */
-       fs = file->i_ffs;
-       while (i) {
-        RDSPRINT(("In lread while\n"));
-               off = blkoff(fs, file->i_offset);
-               lbn = lblkno(fs, file->i_offset);
-               size = blksize(fs, &file->i_ino, lbn);
-               if (off == 0 && size <= i) {
-                       file->i_bn = fsbtodb(fs, sbmap(file, lbn)) +
-                           file->i_boff;
-                       file->i_cc = size;
-                       file->i_ma = buf;
-
-            RDPRINT(("In read->devread\n"));
-            RDPRINT(("In read fbn=%x; offset=%x;", file->i_bn,
-                     file->i_offset));
-            RDSPRINT((" boff=%x\n", file->i_boff));
-
-            if (devread(file) < 0) {
-                return (-1);
-            }
-            file->i_offset += size;
-            file->i_cc = 0;
-            buf += size;
-            i -= size;
-               }
-        else {
-            RDSPRINT(("IN while nonread\n"));
-                       size -= off;
-                       if (size > i)
-                               size = i;
-                       i -= size;
-                       do {
-                               *buf++ = getch(fdesc);
-                       } while (--size);
-               }
-       }
-
-       return (count);
-}
+//==========================================================================
+// open() - Open the file specified by 'path' for reading.
 
-/*==========================================================================
- * Disk (block device) functions.
- */
-static BOOL
-disk_open(char * name, struct iob * file, int how)
+int open(const char * path, int flags)
 {
-       int    i;
-
-       file->i_cc = SBSIZE;
-//     file->i_bn = (SBLOCK / DEV_BSIZE) + file->i_boff;
-       file->i_bn = (SBOFF/label_secsize) + file->i_boff;
-       file->i_offset = 0;
-
-       if (file->i_ffs == 0) {
-               if (fs_block == 0) {
-            DPRINT(("No super block; reading one \n"));
-                   fs_block = (struct fs *) malloc(SBSIZE);
-               }
-               if (fs_block_valid == 0) {
-                   file->i_ma = (char *)fs_block;
-                   if (devread(file) < 0) {
-#ifndef SMALL
-                           error(SUPERBLOCK_ERROR, 1);
-#endif
-                           return NO;
-                   }
-#if    BIG_ENDIAN_INTEL_FS
-                   byte_swap_superblock(fs_block);
-#endif /* BIG_ENDIAN_INTEL_FS */
-            DPRINT(("Read SB \n"));
-                   fs_block_valid = 1;
-               }
-               file->i_ffs = fs_block;
-               file->i_buf = malloc(MAXBSIZE);
-       }
-#if    BIG_ENDIAN_INTEL_FS
-    DPRINT(("IN BE_FS code \n"));
-
-       if (file->i_ffs->fs_magic != FS_MAGIC) {
-        DPRINT(("Bad magic in FS %d ; got %d\n", FS_MAGIC,
-                file->i_ffs->fs_magic));
-               error(SUPERBLOCK_ERROR, 2);
-               return NO;
-       }
-       /*
-        *  The following is a gross hack to boot disks that have an actual
-        *  blocksize of 512 bytes but were written with a theoretical 1024
-        *  byte blocksize (fsbtodb == 0).
-        *
-        *  We can make this assumption because we can only boot disks with
-        *  a 512 byte sector size.
-        */
-    DPRINT(("SB  magic ok \n"));
-       if (file->i_ffs->fs_fsize == 0) {
-               error(SUPERBLOCK_ERROR,3);
-               return NO;
-       }
-       file->i_ffs->fs_fsbtodb = ffs(file->i_ffs->fs_fsize / DEV_BSIZE) - 1;
-#endif /* BIG_ENDIAN_INTEL_FS */
-
-       if ((i = find(name, file)) == 0) {
-        DPRINT(("find() failed\n"));
-               return NO;
-       }
-
-#if    CHECK_CAREFULLY
-       if (how != 0) {
-               error("Can't write files\n");
-               return NO;
-       }
-#endif CHECK_CAREFULLY
-
-    DPRINT(("calling openi \n"));
-       if (openi(i, file) < 0) {
-        DPRINT(("openi failed \n"));
-               return NO;
-       }
-
-    DPRINT(("openi ok \n"));
-
-       file->i_offset = 0;
-       file->i_cc = 0;
-       file->i_flgs |= F_FILE | (how+1);
-
-       return YES;
-}
+    int          fdesc, i;
+    struct iob * io;
+    const char * filePath;
+    BVRef        bvr;
 
-/*==========================================================================
- *
- *
- */
-static int
-ffs(register long mask)
-{
-       register int cnt;
+    // Locate a free descriptor slot.
 
-       if (mask == 0) return(0);
+    for (fdesc = 0; fdesc < NFILES; fdesc++)
+        if (iob[fdesc].i_flgs == 0)
+            goto gotfile;
 
-       for (cnt = 1; !(mask & 1); cnt++)
-               mask >>= 1;
-       return(cnt);
-}
+    stop("Out of file descriptors");
 
-/*==========================================================================
- *
- *
- */
-static void
-disk_flushdev()
-{
-    register int i;
-    
-    devflush();
+gotfile:
+    io = &iob[fdesc];
+    bzero(io, sizeof(*io));
+
+    // Mark the descriptor as taken.
+
+    io->i_flgs = F_ALLOC;
+
+    // Resolve the boot volume from the file spec.
+
+    if ((bvr = getBootVolumeRef(path, &filePath)) == NULL)
+        goto error;
+
+    // Find the next available memory block in the download buffer.
+
+    io->i_buf = (char *) LOAD_ADDR;
     for (i = 0; i < NFILES; i++)
-        if (iob[i].i_flgs & (F_READ | F_WRITE))
-            error("flushdev: fd %d is open\n",i);
-
-    fs_block_valid = 0;
-#if ICACHE
-    cacheFlush(icache);
-#endif
-#if DCACHE
-    cacheFlush(dcache);
-#endif
+    {
+        if ((iob[i].i_flgs != F_ALLOC) || (i == fdesc)) continue;
+        io->i_buf = max(iob[i].i_filesize + iob[i].i_buf, io->i_buf);
+    }
+
+    // Load entire file into memory. Unnecessary open() calls must
+    // be avoided.
+
+    gFSLoadAddress = io->i_buf;
+    io->i_filesize = bvr->fs_loadfile(bvr, (char *)filePath);
+    if (io->i_filesize < 0) goto error;
+
+    return fdesc;
+
+error:
+    close(fdesc);
+    return -1;
 }
 
-/***************************************************************************
- *
- * Network functions.
- *
- ***************************************************************************/
+//==========================================================================
+// close() - Close a file descriptor.
 
-static int
-en_read(int fdesc, char * buf, int count)
+int close(int fdesc)
 {
-       struct iob * file;
+    struct iob * io;
 
-       if ((file = iob_from_fdesc(fdesc)) == 0)
-               return (-1);
-       
-       DSPRINT(("read[%d]: %x %x %d\n",
-               fdesc, TFTP_ADDR + file->i_offset, (unsigned) buf, count)); 
+    if ((io = iob_from_fdesc(fdesc)) == NULL)
+        return (-1);
 
-       bcopy((char *)(TFTP_ADDR + file->i_offset), buf, count);
-       file->i_offset += count;
+    io->i_flgs = 0;
 
-       return count;
+    return 0;
 }
-static BOOL
-en_open(char * name, struct iob * file, int how)
+
+//==========================================================================
+// lseek() - Reposition the byte offset of the file descriptor from the
+//           beginning of the file. Returns the relocated offset.
+
+int b_lseek(int fdesc, int offset, int ptr)
 {
-       unsigned long  txferSize = TFTP_LEN;
-       
-       if (nbpTFTPReadFile(name, &txferSize, TFTP_ADDR) != nbpStatusSuccess)
-               return NO;
+    struct iob * io;
 
-       file->i_buf        = NULL;
-       file->i_offset     = 0;
-       file->i_ino.i_size = txferSize;         // update the real size
+    if ((io = iob_from_fdesc(fdesc)) == NULL)
+        return (-1);
 
-       return YES;
-}
+    io->i_offset = offset;
 
-static void
-en_devopen(char * name, struct iob * io)
-{
-       io->i_error = 0;
+    return offset;
 }
 
-/***************************************************************************
- *
- * Dispatch functions.
- *
- ***************************************************************************/
+//==========================================================================
+// tell() - Returns the byte offset of the file descriptor.
 
-/*==========================================================================
- *
- */
-static int
-gen_read(int fdesc, char * buf, int count)
+int tell(int fdesc)
 {
-       struct iob * file;
-       
-       if ((file = iob_from_fdesc(fdesc)) == 0)
-               return (-1);
-       
-       return (file->i_ino.i_dev == DEV_EN) ?
-               en_read(fdesc, buf, count) :
-               disk_read(fdesc, buf, count);
-}
+    struct iob * io;
 
-/*==========================================================================
- *
- */
-static int
-gen_open(char * name, struct iob * file, int how)
-{
-       return (file->i_ino.i_dev == DEV_EN) ?
-               en_open(name, file, how) : disk_open(name, file, how);
+    if ((io = iob_from_fdesc(fdesc)) == NULL)
+        return 0;
+
+    return io->i_offset;
 }
 
-/*==========================================================================
- *
- */
-static void
-gen_devopen(char * name, struct iob * io)
+//==========================================================================
+// read() - Read up to 'count' bytes of data from the file descriptor
+//          into the buffer pointed to by buf.
+
+int read(int fdesc, char * buf, int count)
 {
-       return (io->i_ino.i_dev == DEV_EN) ?
-               en_devopen(name, io) : devopen(name, io);
+    struct iob * io;
+    
+    if ((io = iob_from_fdesc(fdesc)) == NULL)
+        return (-1);
+
+    if (io->i_offset + count > io->i_filesize)
+        count = io->i_filesize - io->i_offset;
+
+    if (count <= 0)
+        return 0;  // end of file
+
+    bcopy(io->i_buf + io->i_offset, buf, count);
+
+    io->i_offset += count;
+
+    return count;
 }
 
-/*==========================================================================
- *
- */
-static void
-gen_flushdev()
+//==========================================================================
+// file_size() - Returns the size of the file described by the file
+//               descriptor.
+
+int file_size(int fdesc)
 {
-       return disk_flushdev();
+    struct iob * io;
+
+    if ((io = iob_from_fdesc(fdesc)) == 0)
+        return 0;
+
+    return io->i_filesize;
 }
 
-/*==========================================================================
- *
- */
-static char *
-gen_usrDevices()
+//==========================================================================
+
+struct dirstuff * opendir(const char * path)
 {
-#define NET_ARCH_DEVICES ""
+    struct dirstuff * dirp = 0;
+    const char *      dirPath;
+    BVRef             bvr;
+
+    if ((bvr = getBootVolumeRef(path, &dirPath)) == NULL)
+        goto error;
+
+    dirp = (struct dirstuff *) malloc(sizeof(struct dirstuff));
+    if (dirp == NULL)
+        goto error;
+
+    dirp->dir_path = newString(dirPath);
+    if (dirp->dir_path == NULL)
+        goto error;
+
+    dirp->dir_bvr = bvr;
+
+    return dirp;
 
-       return (((currentdev() >> B_TYPESHIFT) & B_TYPEMASK) == DEV_EN) ?
-               NET_ARCH_DEVICES : ARCH_DEVICES;
+error:
+    closedir(dirp);
+    return NULL;
 }
 
-/***************************************************************************
- *
- * External functions.
- *
- ***************************************************************************/
+//==========================================================================
 
-/*==========================================================================
- *
- */
-struct dirstuff *
-opendir(char * path)
+int closedir(struct dirstuff * dirp)
 {
-    return disk_opendir(path);
+    if (dirp) {
+        if (dirp->dir_path) free(dirp->dir_path);
+        free(dirp);
+    }
+    return 0;
 }
 
-/*==========================================================================
- *
- */
-int
-closedir(struct dirstuff * dirp)
+//==========================================================================
+
+int readdir(struct dirstuff * dirp, const char ** name, long * flags,
+            long * time)
 {
-    return disk_closedir(dirp);
+    return dirp->dir_bvr->fs_getdirentry( dirp->dir_bvr,
+                          /* dirPath */   dirp->dir_path,
+                          /* dirIndex */  &dirp->dir_index,
+                          /* dirEntry */  (char **)name, flags, time );
 }
 
-/*==========================================================================
- * get next entry in a directory.
- */
-struct direct *
-readdir(struct dirstuff * dirp)
+//==========================================================================
+
+int currentdev()
 {
-    return disk_readdir(dirp);
+    return kernBootStruct->kernDev;
 }
 
-/*==========================================================================
- *
- */
-int
-b_lseek(int fdesc, unsigned int addr, int ptr)
+//==========================================================================
+
+int switchdev(int dev)
 {
-       register struct iob * io;
+    kernBootStruct->kernDev = dev;
+    return dev;
+}
 
-    RDPRINT(("In lseek addr= %x\n", addr));
+//==========================================================================
 
-#if    CHECK_CAREFULLY
-       if (ptr != 0) {
-               error("Seek not from beginning of file\n");
-               return (-1);
-       }
-#endif /* CHECK_CAREFULLY */
+const char * usrDevices()
+{
+    return (B_TYPE(currentdev()) == DEV_EN) ? "" : "/private/Drivers/i386";
+}
 
-       if ((io = iob_from_fdesc(fdesc)) == 0) {
-               return (-1);
-       }
-       io->i_offset = addr;
-       io->i_bn = addr / DEV_BSIZE;
-       io->i_cc = 0;
+//==========================================================================
 
-    RDPRINT(("In end of lseek offset %x; bn %x\n", io->i_offset,io->i_bn));
+BVRef scanBootVolumes( int biosdev, int * count )
+{
+    BVRef bvr = 0;
 
-       return (0);
+    switch ( BIOS_DEV_TYPE( biosdev ) )
+    {
+        case kBIOSDevTypeFloppy:
+        case kBIOSDevTypeHardDrive:
+            bvr = diskScanBootVolumes( biosdev, count );
+            break;
+        case kBIOSDevTypeNetwork:
+            bvr = nbpScanBootVolumes( biosdev, count );
+            break;
+    }
+    return bvr;
 }
 
-/*==========================================================================
- *
- */
-int
-tell(int fdesc)
-{
-       return iob[fdesc].i_offset;
-}
+//==========================================================================
 
-/*==========================================================================
- *
- */
-int
-read(int fdesc, char * buf, int count)
+void getBootVolumeDescription( BVRef bvr, char * str, long strMaxLen )
 {
-       return gen_read(fdesc, buf, count);
+    bvr->description( bvr, str, strMaxLen );
 }
 
-/*==========================================================================
- *
- */
-int
-openmem(char * buf, int len)
-{
-       register struct iob * file;
-       int                   fdesc;
+//==========================================================================
 
-       for (fdesc = 0; fdesc < NFILES; fdesc++)
-               if (iob[fdesc].i_flgs == 0)
-                       goto gotfile;
-       stop("Out of file descriptor slots");
+BVRef selectBootVolume( BVRef chain )
+{
+    BVRef bvr, bvr1 = 0, bvr2 = 0;
 
-gotfile:
-       (file = &iob[fdesc])->i_flgs |= F_ALLOC;
-       file->i_buf = buf;
-       file->i_boff = len;
-       file->i_offset = 0;
-       file->i_flgs |= F_MEM;
-       return fdesc;
-}
+    for ( bvr = chain; bvr; bvr = bvr->next )
+    {
+        if ( bvr->flags & kBVFlagNativeBoot ) bvr1 = bvr;
+        if ( bvr->flags & kBVFlagPrimary )    bvr2 = bvr;
+    }
 
-/*==========================================================================
- * Generic open call.
- */
-int
-open(char * str, int how)
-{
-       register char *       cp;
-       register struct iob * file;
-       int                   fdesc;
-
-    DSPRINT(("In open %s\n", str));
-
-#if CHECK_CAREFULLY    /* iob[] is in BSS, so it is guaranteed to be zero. */
-       if (open_init == 0) {
-        int i;
-               for (i = 0; i < NFILES; i++)
-                       iob[i].i_flgs = 0;
-               open_init = 1;
-       }
-#endif
-
-       for (fdesc = 0; fdesc < NFILES; fdesc++)
-               if (iob[fdesc].i_flgs == 0)
-                       goto gotfile;
-       stop("Out of file descriptor slots");
+    bvr = bvr1 ? bvr1 :
+          bvr2 ? bvr2 : chain;
 
-gotfile:
-       (file = &iob[fdesc])->i_flgs |= F_ALLOC;
-
-       if ((cp = xx(str, file)) == (char *) -1)
-       {
-               close(fdesc);
-               return -1;
-       }
-
-       if (*cp == '\0') {
-               file->i_flgs |= how+1;
-               file->i_cc = 0;
-               file->i_offset = 0;
-               return (fdesc);
-       }
-       
-       if (gen_open(cp, file, how) == NO) {
-               close(fdesc);
-               return -1;
-       }
-       return (fdesc);
+    return bvr;
 }
 
-/*==========================================================================
- *
- */
+//==========================================================================
+
 #define LP '('
 #define RP ')'
+extern int gBIOSDev;
 
-static char * xx(char *str, struct iob *file)
+static BVRef getBootVolumeRef( const char * path, const char ** outPath )
 {
-       register char *cp = str, *xp;
-       char ** dp;
-       int old_dev = kernBootStruct->kernDev;
-       int dev  = (kernBootStruct->kernDev >> B_TYPESHIFT) & B_TYPEMASK;
-       int unit = (kernBootStruct->kernDev >> B_UNITSHIFT) & B_UNITMASK;
-       int part = (kernBootStruct->kernDev >> B_PARTITIONSHIFT) & B_PARTITIONMASK;
-       int i;
-       int no_dev;
-       int biosOffset;
-
-       biosOffset = unit;              // set the device
-
-       for (; *cp && *cp != LP; cp++) ;
-       if (no_dev = !*cp) {    // no left paren found
-               cp = str;
-               xp = devsw[dev];
-       } else if (cp == str) { // paren but no device
-               cp++;
-               xp = devsw[dev];
-       } else {
-               xp = str;
-               cp++;
-       }
-
-       for (dp = devsw; *dp; dp++)
-       {
-               if ((xp[0] == *dp[0]) && (xp[1] == *(dp[0] + 1)))
-                       goto gotdev;
-       }
-
-       error("Unknown device '%c%c'\n",xp[0],xp[1]);
-       return ((char *)-1);
-
-gotdev:
-       if (no_dev)
-               goto none;
-       i = 0;
-       while (*cp >= '0' && *cp <= '9')
-       {
-               i = i * 10 + *cp++ - '0';
-        unit = i;           // get the specified unit number
-       }
-
-       biosOffset = unit;              // set the device
-
-       if (*cp == RP || no_dev)
-               /* do nothing since ptol(")") returns 0 */ ;
-       else if (*cp == ',')
-        part = ptol(++cp);  // get the specified partition number
-       else if (cp[-1] == LP) 
-               part = ptol(cp);
-       else {
-badoff:
-               error("Missing offset specification\n");
-               return ((char *)-1);
-       }
-
-       for ( ;!no_dev ;) {     // skip after the right paren
-               if (*cp == RP)
-                       break;
-               if (*cp++)
-                       continue;
-               goto badoff;
-       }
-
-none:
-       file->i_ino.i_dev = dev = dp - devsw;
-       file->partition   = part;
-       file->biosdev     = (BIOSDEV(dev)) + biosOffset;
-
-       if (dev == DEV_SD) {
-               file->biosdev += kernBootStruct->numIDEs;
-       }
-    else if (dev == DEV_EN) {
-        file->biosdev = BIOS_DEV_EN;
+    const char * cp;
+    BVRef        bvr;
+    int          type = B_TYPE( kernBootStruct->kernDev );
+    int          unit = B_UNIT( kernBootStruct->kernDev );
+    int          part = B_PARTITION( kernBootStruct->kernDev );
+    int          biosdev = gBIOSDev;
+    static BVRef lastBVR = 0;
+    static int   lastKernDev;
+
+    // Search for left parenthesis in the path specification.
+
+    for (cp = path; *cp; cp++) {
+        if (*cp == LP || *cp == '/') break;
     }
-    else if (dev == DEV_HD && kernBootStruct->numIDEs == 0) {
-               error("No IDE drives detected\n");
-               return ((char *)-1);
-       }
 
-       kernBootStruct->kernDev = (dev << B_TYPESHIFT) | 
-                              (unit << B_UNITSHIFT) |
-                              (part << B_PARTITIONSHIFT);
+    if (*cp != LP)  // no left paren found
+    {
+        cp = path;
+        if ( lastBVR && lastKernDev == kernBootStruct->kernDev )
+        {
+            bvr = lastBVR;
+            goto quick_exit;
+        }
+    }
+    else if ((cp - path) == 2)  // found "xx("
+    {
+        const struct devsw * dp;
+        const char * xp = path;
+        int          i;
+
+        cp++;
+
+        // Check the 2 character device name pointed by 'xp'.
+
+        for (dp = devsw; dp->name; dp++)
+        {
+            if ((xp[0] == dp->name[0]) && (xp[1] == dp->name[1]))
+                break;  // found matching entry
+        }
+        if (dp->name == NULL)
+        {
+            error("Unknown device '%c%c'\n", xp[0], xp[1]);
+            return NULL;
+        }
+        type = dp - devsw;  // kerndev type
+        
+        // Extract the optional unit number from the specification.
+        // hd(unit) or hd(unit, part).
+
+        i = 0;
+        while (*cp >= '0' && *cp <= '9')
+        {
+            i = i * 10 + *cp++ - '0';
+            unit = i;
+        }
+
+        // Extract the optional partition number from the specification.
+
+        if (*cp == ',')
+            part = atoi(++cp);
+
+        // Skip past the right paren.
+
+        for ( ; *cp && *cp != RP; cp++) /* LOOP */;
+        if (*cp == RP) cp++;
+        
+        biosdev = dp->biosdev;
+    }
+    else
+    {
+        // Bad device specifier, skip past the right paren.
 
-       if (kernBootStruct->kernDev != old_dev)
-           flushdev();
+        for ( cp++; *cp && *cp != RP; cp++) /* LOOP */;
+        if (*cp == RP) cp++;
+    }
 
-       gen_devopen(str, file);
+    biosdev += (unit & kBIOSDevUnitMask);
 
-       if (file->i_error) 
-               return (char *)-1;
-       if (!no_dev && *cp) cp++;
+    if ((bvr = newBootVolumeRef(biosdev, part)) == NULL)
+    {
+        // error("newBootVolumeRef() error\n");
+        return NULL;
+    }
 
-       gFilename = cp;
+    // Record the most recent device parameters in the
+    // KernBootStruct.
 
-       return cp;
-}
+    kernBootStruct->kernDev = MAKEKERNDEV(type, unit, bvr->part_no);
 
-/*==========================================================================
- *
- */
-int
-close(int fdesc)
-{
-       register struct iob * file;
-       register int          i;
-
-       if ((file = iob_from_fdesc(fdesc)) == 0)
-               return (-1);
-
-       if ((file->i_flgs & F_MEM) == 0) {
-//             free((char *)file->i_ffs);
-           file->i_ffs = NULL;
-           if (file->i_buf) {
-                       free(file->i_buf);
-                       file->i_buf = NULL;
-               }
-           for (i=0;i<NBUFS;i++)
-           {
-                   if (b[i])
-                   {   free(b[i]); 
-                           b[i] = NULL;
-                   }
-                   blknos[i] = 0;
-           }
-       }
-
-       file->i_flgs = 0;
-       return (0);
-}
+    lastBVR = bvr;
+    lastKernDev = kernBootStruct->kernDev;
 
-/*==========================================================================
- *
- */
-int
-file_size(int fdesc)
-{
-       register struct iob * io;
-    
-       if ((io = iob_from_fdesc(fdesc)) == 0)
-               return (-1);
+quick_exit:
+    // Returns the file path following the device spec.
+    // e.g. 'hd(1,b)mach_kernel' is reduced to 'mach_kernel'.
 
-       return io->i_ino.i_size;
-}
+    *outPath = cp;
 
-/*==========================================================================
- * ensure that all device caches are flushed,
- * because we are about to change the device media
- */
-void
-flushdev()
-{
-       gen_flushdev();
+    return bvr;
 }
 
-/*==========================================================================
- *
- */
-void
-stop(char * s)
-{
-#if    CHECK_CAREFULLY
-       register int i;
-       
-       for (i = 0; i < NFILES; i++)
-               if (iob[i].i_flgs != 0)
-                       close(i);
-#endif CHECK_CAREFULLY
-
-    /* textMode(); */    // can't call this function from here
-       error("\n%s\n", s);
-       sleep(4);            // about to halt
-       halt();
-}
+//==========================================================================
 
-/*==========================================================================
- *
- */
-int currentdev()
+static BVRef newBootVolumeRef( int biosdev, int partno )
 {
-    return kernBootStruct->kernDev;
-}
+    BVRef bvr, bvr1, bvrChain;
 
-/*==========================================================================
- *
- */
-int
-switchdev(int dev)
-{
-    flushdev();
-    kernBootStruct->kernDev = dev;
-    return dev;
-}
+    // Fetch the volume list from the device.
 
-/*==========================================================================
- *
- */
-char *
-usrDevices()
-{
-       return gen_usrDevices();
+    bvrChain = scanBootVolumes( biosdev, NULL );
+
+    // Look for a perfect match based on device and partition number.
+
+    for ( bvr1 = NULL, bvr = bvrChain; bvr; bvr = bvr->next )
+    {
+        if ( ( bvr->flags & kBVFlagNativeBoot ) == 0 ) continue;
+    
+        bvr1 = bvr;
+        if ( bvr->part_no == partno ) break;
+    }
+
+    return bvr ? bvr : bvr1;
 }
index aa5c40eda527ea105d7a07d9f42ed55260f1c1e3..35d211701d364b24c3ccdb669f5712d100824434 100644 (file)
@@ -46,9 +46,6 @@
  
 #include "memory.h"
 
-#define NGDTENT                6
-#define GDTLIMIT       48      /* NGDTENT * 8 */
-
 /*  Segment Descriptor
  *
  * 31          24         19   16                 7           0
  */
 
 struct seg_desc {
-       unsigned short  limit_15_0;
-       unsigned short  base_15_0;
-       unsigned char   base_23_16;
-       unsigned char   bit_15_8;
-       unsigned char   bit_23_16;
-       unsigned char   base_31_24;
-       };
+    unsigned short  limit_15_0;
+    unsigned short  base_15_0;
+    unsigned char   base_23_16;
+    unsigned char   bit_15_8;
+    unsigned char   bit_23_16;
+    unsigned char   base_31_24;
+};
 
+struct seg_desc Gdt[ NGDTENT ] = {
+    /*  0x0 : null */
+    {0x0000, 0x0000,  0x00, 0x00, 0x00, 0x00},
 
-struct seg_desc        Gdt[NGDTENT] = {
-    {0x0,    0x0,     0x0, 0x0,  0x0,  0x0},    /*  0x0 : null */
-    // byte granularity, 1Mb limit, MEMBASE offset
-    {0xFFFF, MEMBASE, 0x0, 0x9E, 0x4F, 0x0},    /*  0x8 : boot code */
-    // dword granularity, 2Gb limit, MEMBASE offset
-    {0xFFFF, MEMBASE, 0x0, 0x92, 0xCF, 0x0},    /* 0x10 : boot data */
-    {0xFFFF, MEMBASE, 0x0, 0x9E, 0xF,  0x0},    /* 0x18 : boot code, 16 bits */
-    {0xFFFF, 0x0,     0x0, 0x92, 0xCF, 0x0},    /* 0x20 : init data */
-    {0xFFFF, 0x0,     0x0, 0x9E, 0xCF, 0x0}     /* 0x28 : init code */
-};
+    /*  0x8 : boot protected mode 32-bit code segment
+              byte granularity, 1MB limit, MEMBASE offset */
+    {0xFFFF, MEMBASE, 0x00, 0x9E, 0x4F, 0x00},    
+    
+    /* 0x10 : boot protected mode data segment
+              page granularity, 4GB limit, MEMBASE offset */
+    {0xFFFF, MEMBASE, 0x00, 0x92, 0xCF, 0x00},
+
+    /* 0x18 : boot protected mode 16-bit code segment
+              byte granularity, 1MB limit, MEMBASE offset */
+    {0xFFFF, MEMBASE, 0x00, 0x9E, 0x0F, 0x00},
 
+    /* 0x20 : kernel init 32-bit data segment
+              page granularity, 4GB limit, zero offset */
+    {0xFFFF, 0x0000,  0x00, 0x92, 0xCF, 0x00},
+
+    /* 0x28 : kernel init 32-bit code segment
+              page granularity, 4GB limit, zero offset */
+    {0xFFFF, 0x0000,  0x00, 0x9E, 0xCF, 0x00},
+
+    /* 0x30 : boot real mode data/stack segment
+              byte granularity, 64K limit, MEMBASE offset, expand-up */
+    {0xFFFF, MEMBASE, 0x00, 0x92, 0x00, 0x00},    
+};
diff --git a/i386/libsaio/ufs.c b/i386/libsaio/ufs.c
new file mode 100644 (file)
index 0000000..059a133
--- /dev/null
@@ -0,0 +1,450 @@
+/*
+ * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License").  You may not use this file except in compliance with the
+ * License.  Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
+ * 
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ *  ufs.c - File System Module for UFS.
+ *
+ *  Copyright (c) 1998-2002 Apple Computer, Inc.
+ *
+ *  DRI: Josh de Cesare
+ */
+
+#include <sl.h>
+
+#include "ufs_byteorder.h"
+
+typedef struct dinode Inode, *InodePtr;
+
+// Private function prototypes
+
+static char *ReadBlock(long fragNum, long fragOffset, long length,
+                       char *buffer, long cache);
+static long ReadInode(long inodeNum, InodePtr inode, long *flags, long *time);
+static long ResolvePathToInode(char *filePath, long *flags,
+                               InodePtr fileInode, InodePtr dirInode);
+static long ReadDirEntry(InodePtr dirInode, long *fileInodeNum,
+                         long *dirIndex, char **name);
+static long FindFileInDir(char *fileName, long *flags,
+                          InodePtr fileInode, InodePtr dirInode);
+static char *ReadFileBlock(InodePtr fileInode, long fragNum, long blockOffset,
+                           long length, char *buffer, long cache);
+static long ReadFile(InodePtr fileInode, long *length);
+
+#define kDevBlockSize (0x200)    // Size of each disk block.
+#define kDiskLableBlock (15)     // Block the DL is in.
+
+#ifdef __i386__
+
+static CICell    gCurrentIH;
+static long long gPartitionBase;
+static char      *gDLBuf;
+static char      *gFSBuf;
+static struct fs *gFS;
+static long      gBlockSize;
+static long      gFragSize;
+static long      gFragsPerBlock;
+static char      *gTempBlock;
+static char      *gTempName;
+static char      *gTempName2;
+static InodePtr  gRootInodePtr;
+static InodePtr  gFileInodePtr;
+
+#else  /* !__i386__ */
+
+static CICell    gCurrentIH;
+static long long gPartitionBase;
+static char      gDLBuf[8192];
+static char      gFSBuf[SBSIZE];
+static struct fs *gFS;
+static long      gBlockSize;
+static long      gFragSize;
+static long      gFragsPerBlock;
+static char      *gTempBlock;
+static char      gTempName[MAXNAMLEN + 1];
+static char      gTempName2[MAXNAMLEN + 1];
+static Inode     _gRootInode;
+static Inode     _gFileInode;
+static InodePtr  gRootInodePtr = &_gRootInode;
+static InodePtr  gFileInodePtr = &_gFileInode;
+
+#endif /* !__i386__ */
+
+// Public functions
+
+long UFSInitPartition( CICell ih )
+{
+    if (ih == gCurrentIH) {
+#ifdef __i386__
+        CacheInit(ih, gBlockSize);
+#endif
+        return 0;
+    }
+
+    verbose("UFSInitPartition: %x\n", ih);
+
+    gCurrentIH = 0;
+
+#ifdef __i386__
+    if (!gDLBuf) gDLBuf = (char *) malloc(8192);
+    if (!gFSBuf) gFSBuf = (char *) malloc(SBSIZE);
+    if (!gTempName) gTempName = (char *) malloc(MAXNAMLEN + 1);
+    if (!gTempName2) gTempName2 = (char *) malloc(MAXNAMLEN + 1);
+    if (!gRootInodePtr) gRootInodePtr = (InodePtr) malloc(sizeof(Inode));
+    if (!gFileInodePtr) gFileInodePtr = (InodePtr) malloc(sizeof(Inode));
+    if (!gDLBuf || !gFSBuf || !gTempName || !gTempName2 ||
+        !gRootInodePtr || !gFileInodePtr) return -1;
+#endif
+
+    // Assume there is no Disk Label
+    gPartitionBase = 0;
+
+    // Look for the Super Block
+    Seek(ih, gPartitionBase + SBOFF);
+    Read(ih, (long)gFSBuf, SBSIZE);
+
+    gFS = (struct fs *)gFSBuf;
+    byte_swap_superblock(gFS);
+
+    if (gFS->fs_magic != FS_MAGIC) {
+#ifdef __i386__
+        return -1;  // not yet for Intel
+#else  /* !__i386__ */
+        disk_label_t *dl;
+        partition_t  *part;
+
+        // Did not find it... Look for the Disk Label.
+        // Look for the Disk Label
+        Seek(ih, 1ULL * kDevBlockSize * kDiskLableBlock);
+        Read(ih, (long)gDLBuf, 8192);
+    
+        dl = (disk_label_t *)gDLBuf;
+        byte_swap_disklabel_in(dl);
+    
+        if (dl->dl_version != DL_VERSION) {
+            return -1;
+        }
+    
+        part = &dl->dl_part[0];
+        gPartitionBase = (1ULL * (dl->dl_front + part->p_base) * dl->dl_secsize) -
+                         (1ULL * (dl->dl_label_blkno - kDiskLableBlock) * kDevBlockSize);
+    
+        // Re-read the Super Block.
+        Seek(ih, gPartitionBase + SBOFF);
+        Read(ih, (long)gFSBuf, SBSIZE);
+
+        gFS = (struct fs *)gFSBuf;
+        if (gFS->fs_magic != FS_MAGIC) {
+            return -1;
+        }
+#endif /* !__i386__ */
+    }
+
+    // Calculate the block size and set up the block cache.
+    gBlockSize = gFS->fs_bsize;
+    gFragSize  = gFS->fs_fsize;
+    gFragsPerBlock = gBlockSize / gFragSize;
+    if (gTempBlock != 0) free(gTempBlock);
+    gTempBlock = malloc(gBlockSize);
+    CacheInit(ih, gBlockSize);
+
+    gCurrentIH = ih;
+
+    // Read the Root Inode
+    ReadInode(ROOTINO, gRootInodePtr, 0, 0);
+
+    return 0;
+}
+
+long UFSLoadFile( CICell ih, char * filePath )
+{
+    long ret, length, flags;
+
+    if (UFSInitPartition(ih) == -1) return -1;
+
+    verbose("Loading UFS file: [%s] from %x.\n", filePath, (unsigned)ih);
+
+    // Skip one or two leading '/'.
+    if (*filePath == '/') filePath++;
+    if (*filePath == '/') filePath++;
+
+    ret = ResolvePathToInode(filePath, &flags, gFileInodePtr, gRootInodePtr);
+    if ((ret == -1) || ((flags & kFileTypeMask) != kFileTypeFlat)) return -1;
+
+#if 0
+    // System.config/Default.table will fail this check.
+    // Turn this back on when usage of System.config is deprecated.
+    if (flags & (kOwnerNotRoot | kPermGroupWrite | kPermOtherWrite)) return -1;
+#endif
+
+    ret = ReadFile(gFileInodePtr, &length);
+    if (ret == -1) return -1;
+    
+    return length;
+}
+
+long UFSGetDirEntry( CICell ih, char * dirPath, long * dirIndex,
+                     char ** name, long * flags, long * time )
+{
+    long  ret, fileInodeNum, dirFlags;
+    Inode tmpInode;
+
+    if (UFSInitPartition(ih) == -1) return -1;
+
+    // Skip a leading '/' if present
+    if (*dirPath == '/') dirPath++;
+    if (*dirPath == '/') dirPath++;
+
+    ret = ResolvePathToInode(dirPath, &dirFlags, gFileInodePtr, gRootInodePtr);
+    if ((ret == -1) || ((dirFlags & kFileTypeMask) != kFileTypeDirectory))
+        return -1;
+
+    ret = ReadDirEntry(gFileInodePtr, &fileInodeNum, dirIndex, name);
+    if (ret != 0) return ret;
+
+    ReadInode(fileInodeNum, &tmpInode, flags, time);
+
+    return 0;
+}
+
+// Private functions
+
+static char * ReadBlock( long fragNum, long blockOffset, long length,
+                         char * buffer, long cache )
+{
+    long long offset;
+    long blockNum;
+
+    blockNum = fragNum / gFragsPerBlock;
+    fragNum -= blockNum * gFragsPerBlock;
+    
+    blockOffset += fragNum * gFragSize;
+    
+    offset = gPartitionBase + 1ULL * blockNum * gBlockSize;
+
+    if (cache && ((blockOffset + length) <= gBlockSize)) {
+        CacheRead(gCurrentIH, gTempBlock, offset, gBlockSize, 1);
+        if (buffer != 0) bcopy(gTempBlock + blockOffset, buffer, length);
+        else buffer = gTempBlock + blockOffset;
+    } else {
+        offset += blockOffset;
+        CacheRead(gCurrentIH, buffer, offset, length, 0);
+    }
+
+    return buffer;
+}
+
+static long ReadInode( long inodeNum, InodePtr inode, long * flags, long * time )
+{
+    long fragNum = ino_to_fsba(gFS, inodeNum);
+    long blockOffset = ino_to_fsbo(gFS, inodeNum) * sizeof(Inode);
+
+    ReadBlock(fragNum, blockOffset, sizeof(Inode), (char *)inode, 1);
+    byte_swap_dinode_in(inode);
+
+    if (time != 0) *time = inode->di_mtime;
+
+    if (flags != 0) {
+        switch (inode->di_mode & IFMT) {
+            case IFREG: *flags = kFileTypeFlat; break;
+            case IFDIR: *flags = kFileTypeDirectory; break;
+            case IFLNK: *flags = kFileTypeLink; break;
+            default :   *flags = kFileTypeUnknown; break;
+        }
+
+        *flags |= inode->di_mode & kPermMask;
+
+        if (inode->di_uid != 0) *flags |= kOwnerNotRoot;
+    }
+
+    return 0;
+}
+
+static long ResolvePathToInode( char * filePath, long * flags,
+                                InodePtr fileInode, InodePtr dirInode )
+{
+    char * restPath;
+    long   ret, cnt;
+
+    // if filePath is empty the we want this directory.
+    if (*filePath == '\0') {
+        bcopy((char *)dirInode, (char *)fileInode, sizeof(Inode));
+        return 0;
+    }
+
+    // Copy the file name to gTempName
+    cnt = 0;
+    while ((filePath[cnt] != '/') && (filePath[cnt] != '\0')) cnt++;
+    strncpy(gTempName, filePath, cnt);
+
+    // Move restPath to the right place.
+    if (filePath[cnt] != '\0') cnt++;
+    restPath = filePath + cnt;
+
+    // gTempName is a name in the current Dir.
+    // restPath is the rest of the path if any.
+
+    ret = FindFileInDir(gTempName, flags, fileInode, dirInode);
+    if (ret == -1) return -1;
+
+    if ((*restPath != '\0') && ((*flags & kFileTypeMask) == kFileTypeDirectory))
+        ret = ResolvePathToInode(restPath, flags, fileInode, fileInode);
+
+    return ret;
+}
+
+static long ReadDirEntry( InodePtr dirInode, long * fileInodeNum,
+                          long * dirIndex, char ** name )
+{
+    struct direct *dir;
+    char          *buffer;
+    long          index;
+    long          dirBlockNum, dirBlockOffset;
+
+    while (1) {
+        index = *dirIndex;
+    
+        dirBlockOffset = index % DIRBLKSIZ;
+        dirBlockNum    = index / DIRBLKSIZ;
+
+        buffer = ReadFileBlock(dirInode, dirBlockNum, 0, DIRBLKSIZ, 0, 1);
+        if (buffer == 0) return -1;
+
+        dir = (struct direct *)(buffer + dirBlockOffset);
+        byte_swap_dir_block_in((char *)dir, 1);
+
+        *dirIndex += dir->d_reclen;
+        
+        if (dir->d_ino != 0) break;
+        
+        if (dirBlockOffset != 0) return -1;
+    }
+
+    *fileInodeNum = dir->d_ino;
+    *name = strncpy(gTempName2, dir->d_name, dir->d_namlen);
+
+    return 0;
+}
+
+static long FindFileInDir( char * fileName, long * flags,
+                           InodePtr fileInode, InodePtr dirInode )
+{
+    long ret, inodeNum, index = 0;
+    char *name;
+
+    while (1) {
+        ret = ReadDirEntry(dirInode, &inodeNum, &index, &name);
+        if (ret == -1) return -1;
+
+        if (strcmp(fileName, name) == 0) break;
+    }
+
+    ReadInode(inodeNum, fileInode, flags, 0);
+
+    return 0;
+}
+
+static char * ReadFileBlock( InodePtr fileInode, long fragNum, long blockOffset,
+                             long length, char * buffer, long cache )
+{
+    long fragCount, blockNum;
+    long diskFragNum, indFragNum, indBlockOff, refsPerBlock;
+    char *indBlock;
+
+    fragCount = (fileInode->di_size + gFragSize - 1) / gFragSize;
+    if (fragNum >= fragCount) return 0;
+
+    refsPerBlock = gBlockSize / sizeof(ufs_daddr_t);
+
+    blockNum = fragNum / gFragsPerBlock;
+    fragNum -= blockNum * gFragsPerBlock;
+    
+    // Get Direct Block Number.
+    if (blockNum < NDADDR) {
+        diskFragNum = fileInode->di_db[blockNum];
+    } else {
+        blockNum -= NDADDR;
+
+        // Get Single Indirect Fragment Number.
+        if (blockNum < refsPerBlock) {
+            indFragNum = fileInode->di_ib[0];
+        } else {
+            blockNum -= refsPerBlock;
+
+            // Get Double Indirect Fragment Number.
+            if (blockNum < (refsPerBlock * refsPerBlock)) {
+                indFragNum = fileInode->di_ib[1];
+            } else {
+                blockNum -= refsPerBlock * refsPerBlock;
+
+                // Get Triple Indirect Fragment Number.
+                indFragNum = fileInode->di_ib[2];
+
+                indBlock = ReadBlock(indFragNum, 0, gBlockSize, 0, 1);
+                indBlockOff = blockNum / (refsPerBlock * refsPerBlock);
+                blockNum %= (refsPerBlock * refsPerBlock);
+                indFragNum = SWAP_BE32(((ufs_daddr_t *)indBlock)[indBlockOff]);
+            }
+
+            indBlock = ReadBlock(indFragNum, 0, gBlockSize, 0, 1);
+            indBlockOff = blockNum / refsPerBlock;
+            blockNum %= refsPerBlock;
+            indFragNum = SWAP_BE32(((ufs_daddr_t *)indBlock)[indBlockOff]);
+        }
+
+        indBlock = ReadBlock(indFragNum, 0, gBlockSize, 0, 1);
+        diskFragNum = SWAP_BE32(((ufs_daddr_t *)indBlock)[blockNum]);
+    }
+
+    buffer = ReadBlock(diskFragNum+fragNum, blockOffset, length, buffer, cache);
+
+    return buffer;
+}
+
+static long ReadFile( InodePtr fileInode, long * length )
+{
+    long bytesLeft, curSize, curFrag = 0;
+    char *buffer, *curAddr = (char *)kLoadAddr;
+
+#ifdef __i386__
+    curAddr = gFSLoadAddress;
+#endif
+
+    bytesLeft = *length = fileInode->di_size;
+
+    if (*length > kLoadSize) {
+        printf("File is too large.\n");
+        return -1;
+    }
+
+    while (bytesLeft) {
+        if (bytesLeft > gBlockSize) curSize = gBlockSize;
+        else curSize = bytesLeft;
+
+        buffer = ReadFileBlock(fileInode, curFrag, 0, curSize, curAddr, 0);
+        if (buffer == 0) break;
+
+        curFrag += gFragsPerBlock;
+        curAddr += curSize;
+        bytesLeft -= curSize;
+    }
+
+    return bytesLeft;
+}
index a49b56f8b425a9e0089bd96b39fe69161db9c810..f55ac08e05a3be6f55ea7d9cf7c1d9fa75438851 100644 (file)
@@ -26,9 +26,9 @@
  * All rights reserved.
  */
 
-#include <bsd/sys/types.h>
-#include <bsd/sys/param.h>
-#include <bsd/sys/vnode.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/vnode.h>
 #include <ufs/ufs/dir.h>
 #include <architecture/byte_order.h>
 #include "ufs_byteorder.h"
index ad4f2f9e1913270249e5af69b77237735d3e3884..ef0c37e494bf7628fd9ef882e70e9b16b111b1b1 100644 (file)
 #ifndef __LIBSAIO_UFS_BYTEORDER_H
 #define __LIBSAIO_UFS_BYTEORDER_H
 
-#include <bsd/sys/disktab.h>
-#include <bsd/sys/vnode.h>
-#include <bsd/sys/buf.h>
-#include <bsd/dev/disk.h>
-#include <bsd/ufs/ufs/quota.h>
-#include <bsd/ufs/ufs/inode.h>
-#include <bsd/ufs/ffs/fs.h>
+#include <sys/disktab.h>
+#include <sys/vnode.h>
+#include <sys/buf.h>
+#include <dev/disk.h>
+#include <ufs/ufs/quota.h>
+#include <ufs/ufs/inode.h>
+#include <ufs/ffs/fs.h>
 
 void byte_swap_ints(int *array, int count);
 void byte_swap_shorts(short *array, int count);
@@ -54,5 +54,6 @@ void byte_swap_disktab_in(struct disktab *dt);
 void byte_swap_partition(struct partition *part);
 void byte_swap_dinode_in(struct dinode *di);
 void byte_swap_dir_block_in(char *addr, int count);
+void byte_swap_inode_in(struct dinode *dc, struct dinode *ic);
 
 #endif /* !__LIBSAIO_UFS_BYTEORDER_H */
index 36c11f861996654941616e4e18ad031a59d218cf..a195171ee4722208142fa9d4b7c53e7dbc13548d 100644 (file)
  * Copyright 1993 NeXT, Inc.
  * All rights reserved.
  */
-#include "io_inline.h"
+
 #include "libsaio.h"
-#include "vga.h"
 #include "vbe.h"
-#include "kernBootStruct.h"
-#include "appleClut8.h"
-
-/*
- * Graphics mode settings.
- */
-BOOL            in_linear_mode;
-unsigned char * frame_buffer;
-unsigned short  screen_width;
-unsigned short  screen_height;
-unsigned char   bits_per_pixel;
-unsigned short  screen_rowbytes;
 
 /* 
  * Various inline routines for video I/O
@@ -72,160 +59,27 @@ rmwi (int port, int index, int clear, int set)
     outb (port + 1, (inb (port + 1) & ~clear) | set);
 }
 
-/*
- * Local Prototypes
- */
-void setupPalette(VBEPalette * p, const unsigned char * g);
-
 /*
  * Globals
  */
 static biosBuf_t bb;
 
-#if 0
-static char *models[] = { "Text", 
-                         "CGA", 
-                         "Hercules", 
-                         "Planar", 
-                         "Packed Pixel", 
-                         "Non-Chain 4", 
-                         "Direct Color", 
-                         "YUV" };
-#endif
-
-int
-set_linear_video_mode(unsigned short mode)
-{
-    VBEInfoBlock        vinfo;
-    VBEModeInfoBlock    minfo;
-    int                 err;
-    VBEPalette          palette;
-
-    do {
-        /*
-         * See if VESA is around.
-         */
-        err = getVBEInfo(&vinfo);
-        if (err != errSuccess)
-        {
-            printf("VESA not available.\n");
-            break;
-        }
-
-#if 0
-        /*
-         * See if this mode is supported.
-         */
-        err = getVBEModeInfo(mode, &minfo);
-        if ( !((err == errSuccess) && 
-            (minfo.ModeAttributes & maModeIsSupportedBit) &&
-            (minfo.ModeAttributes & maGraphicsModeBit) /* &&
-            (minfo.ModeAttributes & maLinearFrameBufferAvailBit)*/) )
-        {
-            printf("Mode %d is not supported.\n", mode);
-            err = errFuncNotSupported;
-            break;
-        }
-#endif
-
-        /*
-         * Set the mode.
-         */
-        err = setVBEMode(mode | kLinearFrameBufferBit );
-        if ( err != errSuccess )
-        {
-            if (vinfo.VESAVersion < MIN_VESA_VERSION)
-            {
-                printf("Video Card is VESA %d.%d. It must be at least VESA %d.%d\n",
-                    vinfo.VESAVersion >> 8,
-                    vinfo.VESAVersion & 0xff,
-                    MIN_VESA_VERSION >> 8,
-                    MIN_VESA_VERSION & 0xff);
-            }
-            else
-            {
-                printf("Error #%d in set video mode.\n", err);
-            }
-            break;
-        }
-
-        /*
-         * Get mode info.
-         */
-        err = getVBEModeInfo(mode, &minfo);
-        if ( err != errSuccess )
-        {
-            printf("Error #%d in get mode info.\n", err);
-            break;
-        }
-
-        /*
-         * Set the palette.
-         */
-        if (( vinfo.VESAVersion >= MIN_VESA_VERSION ) &&
-            ( minfo.BitsPerPixel == 8 ))
-        {
-            setupPalette(&palette, appleClut8);
-            if ((err = setVBEPalette(palette)) != errSuccess)
-            {
-                printf("Error #%d in setting palette.\n", err);
-                break;
-            }
-        }
-
-        err             = errSuccess;
-        in_linear_mode  = YES;
-        screen_width    = minfo.XResolution;
-        screen_height   = minfo.YResolution;
-        bits_per_pixel  = minfo.BitsPerPixel;
-        screen_rowbytes = minfo.BytesPerScanline;
-
-        /* The S3 video card reports 15 bits... the video console driver
-         * Can't deal.. set it to 16.
-         */
-        if (bits_per_pixel > 8 && bits_per_pixel < 16)
-            bits_per_pixel = 16;
-
-        frame_buffer = (unsigned char *) ADDRESS(minfo.PhysBasePtr_low, 
-                                                 minfo.PhysBasePtr_1, 
-                                                 minfo.PhysBasePtr_2, 
-                                                 minfo.PhysBasePtr_high);
-    }
-    while ( 0 );
-    
-    return err;
-}
-
-void setupPalette(VBEPalette * p, const unsigned char * g)
+int getVBEInfo( void * infoBlock )
 {
-    int             i;
-    unsigned char * source = (unsigned char *) g;
-
-    for (i = 0; i < 256; i++)
-    {
-        (*p)[i] = 0;
-        (*p)[i] |= ((unsigned long)((*source++) >> 2)) << 16;   // Red
-        (*p)[i] |= ((unsigned long)((*source++) >> 2)) << 8;    // Green
-        (*p)[i] |= ((unsigned long)((*source++) >> 2));         // Blue
-    }
-}
-
-int getVBEInfo(void *vinfo_p)
-{
-    bb.intno = 0x10;
+    bb.intno  = 0x10;
     bb.eax.rr = funcGetControllerInfo;
-    bb.es = SEG(vinfo_p);
-    bb.edi.rr = OFF(vinfo_p);
-    bios(&bb);
+    bb.es     = SEG( infoBlock );
+    bb.edi.rr = OFF( infoBlock );
+    bios( &bb );
     return(bb.eax.r.h);
 }
 
-int getVBEModeInfo(int mode, void *minfo_p)
+int getVBEModeInfo( int mode, void * minfo_p )
 {
-    bb.intno = 0x10;
+    bb.intno  = 0x10;
     bb.eax.rr = funcGetModeInfo;
     bb.ecx.rr = mode;
-    bb.es = SEG(minfo_p);
+    bb.es     = SEG(minfo_p);
     bb.edi.rr = OFF(minfo_p);
     bios(&bb);
     return(bb.eax.r.h);
index 62e5c04bf322e67ebdcfc07e94d10c170da21c06..5481f8c6c98bff32ee1b3fa2346fced848ff38cd 100644 (file)
 #ifndef __LIBSAIO_VBE_H
 #define __LIBSAIO_VBE_H
 
-/*
- * Graphics mode settings.
- */
-extern BOOL            in_linear_mode;
-extern unsigned char * frame_buffer;
-extern unsigned short  screen_width;
-extern unsigned short  screen_height;
-extern unsigned char   bits_per_pixel;
-extern unsigned short  screen_rowbytes;
-
 #define MIN_VESA_VERSION    0x200
 
 #define SEG(address) \
         ((unsigned short)(((unsigned long)address & 0xffff0000) >> 4))
-#define OFF(address) ((unsigned short)((unsigned long)address & 0x0000ffff))
-#define RTOV(low, one, two, high) \
-        (((unsigned long)high << 12) | ((unsigned long)one << 8) | \
-         (unsigned long)low)
-#define ADDRESS(low, one, two, high) \
-        (((unsigned long)high << 24) | ((unsigned long)two << 16) | \
-         ((unsigned long)one << 8) | (unsigned long)low)
+
+#define OFF(address) \
+        ((unsigned short)((unsigned long)address & 0x0000ffff))
+
+#define VBEMakeUInt32(x)                   \
+        (((unsigned long)x##_high << 24) | \
+         ((unsigned long)x##_2    << 16) | \
+         ((unsigned long)x##_1    <<  8) | \
+          (unsigned long)x##_low)
+
+#define VBEDecodeFP(t, fp) \
+        ((t)(((fp ## _low) | ((fp ## _1 ) << 8)) + \
+             (((fp ## _2) << 4) | ((fp ## _high ) << 12))))
 
 /*
- *  Functions
+ * Functions
  */
 enum {
     funcGetControllerInfo    = 0x4F00,
@@ -120,9 +116,9 @@ typedef struct {
  * Capabilites
  */
 enum {
-    capDACWidthIsSwitchableBit          = (1 << 0), /* 1 = yes; 0 = no */
-    capControllerIsNotVGACompatableBit  = (1 << 1), /* 1 = no; 0 = yes */
-    capOldRAMDAC                        = (1 << 2)  /* 1 = yes; 0 = no */
+    capDACWidthIsSwitchableBit          = (1 << 0), /* 1 = yes; 0 = no  */
+    capControllerIsNotVGACompatableBit  = (1 << 1), /* 1 = no;  0 = yes */
+    capOldRAMDAC                        = (1 << 2)  /* 1 = yes; 0 = no  */
 };
 
 /*
@@ -182,7 +178,7 @@ enum {
 };
 
 /*
- *  Modes
+ * Modes
  */
 enum {
     mode640x400x256   = 0x100,
@@ -213,11 +209,12 @@ enum {
     mode1280x1024x555 = 0x119,
     mode1280x1024x565 = 0x11A,
     mode1280x1024x888 = 0x11B,
-    modeSpecial       = 0x81FF
+    modeSpecial       = 0x81FF,
+    modeEndOfList     = 0xFFFF
 };
 
 /*
- *  Get/Set VBE Mode parameters
+ * Get/Set VBE Mode parameters
  */
 enum {
     kLinearFrameBufferBit  =  (1 << 14),
diff --git a/i386/libsaio/vga.c b/i386/libsaio/vga.c
deleted file mode 100644 (file)
index c1dd659..0000000
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License").  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright 1993 NeXT, Inc.
- * All rights reserved.
- */
-#include "io_inline.h"
-#include "libsaio.h"
-#include "vga.h"
-
-#define        VGA_SEQ_CNT     5
-#define        VGA_CRT_CNT     25
-#define        VGA_ATR_CNT     21
-#define        VGA_GFX_CNT     9
-
-typedef struct VGAState {
-    /* Miscellaneous output register. */
-    unsigned char miscOutput;
-    /* Sequencer registers. */
-    unsigned char sequencerData[VGA_SEQ_CNT];
-    /* CRT Controller registers. */
-    unsigned char crtcData[VGA_CRT_CNT];
-    /* Graphics controller registers. */
-    unsigned char graphicsData[VGA_GFX_CNT];
-    /* Attribute controller registers. */
-    unsigned char attrData[VGA_ATR_CNT];
-} VGAState;
-
-#if 0
-/* VGA Mode 0x03. */
-
-static const VGAState VGAMode3 = {
-    /* Miscellaneous output register. */
-    0x67,
-    /* Sequencer registers. */
-    { 0x01, 0x00, 0x03, 0x00, 0x02 },
-    /* CRT controller registers. */
-    {
-       0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, 0x00, 0x4f,
-       0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x28,
-       0x1f, 0x96, 0xb9, 0xa3, 0xff,
-    },
-    /* Graphics controller registers. */
-    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, 0xff },
-    /* Attribute controller registers. */
-    {
-       0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39,
-       0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x0c, 0x00, 0x0f, 0x08,
-       0x00,
-    },
-};
-#endif
-
-/* VGA Mode 0x12. */
-
-static const VGAState VGAMode12 = {
-    /* Miscellaneous output register. */
-    0xe3,
-    /* Sequencer registers. */
-    {0x03, 0x21, 0x0f, 0x00, 0x06},
-    /* CRT controller registers. */
-    {
-       0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e, 0x00,
-       0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0xea, 0x8c,
-       0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3, 0xff,
-    },
-    /* Graphics controller registers. */
-    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff },
-    /* Attribute controller registers. */
-    {
-       0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03,
-       0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03,
-       0x01, 0x00,
-       0x03, 0x00,
-       0x00,
-    },
-};
-
-#define palette_entry(r,g,b) (((r) << 4)|((g) << 2)|(b))
-
-static const unsigned char colorData[4] = {
-    0x00, 0x15, 0x2a, 0x3f,
-};
-
-#ifdef NOTYET
-static const unsigned char mode_03_palette[] = {
-    palette_entry(0, 0, 0),
-    palette_entry(0, 0, 2),
-    palette_entry(0, 2, 0),
-    palette_entry(0, 2, 2),
-    palette_entry(2, 0, 0),
-    palette_entry(2, 0, 2),
-    palette_entry(2, 2, 0),
-    palette_entry(2, 2, 2),
-    palette_entry(0, 0, 1),
-    palette_entry(0, 0, 3),
-    palette_entry(0, 2, 1),
-    palette_entry(0, 2, 3),
-    palette_entry(2, 0, 1),
-    palette_entry(2, 0, 3),
-    palette_entry(2, 2, 1),
-    palette_entry(2, 2, 3),
-    palette_entry(0, 1, 0),
-    palette_entry(0, 1, 2),
-    palette_entry(0, 3, 0),
-    palette_entry(0, 3, 2),
-    palette_entry(2, 1, 0),
-    palette_entry(2, 1, 2),
-    palette_entry(2, 3, 0),
-    palette_entry(2, 3, 2),
-    palette_entry(0, 1, 1),
-    palette_entry(0, 1, 3),
-    palette_entry(0, 3, 1),
-    palette_entry(0, 3, 3),
-    palette_entry(2, 1, 1),
-    palette_entry(2, 1, 3),
-    palette_entry(2, 3, 1),
-    palette_entry(2, 3, 3),
-    palette_entry(1, 0, 0),
-    palette_entry(1, 0, 2),
-    palette_entry(1, 2, 0),
-    palette_entry(1, 2, 2),
-    palette_entry(3, 0, 0),
-    palette_entry(3, 0, 2),
-    palette_entry(3, 2, 0),
-    palette_entry(3, 2, 2),
-    palette_entry(1, 0, 1),
-    palette_entry(1, 0, 3),
-    palette_entry(1, 2, 1),
-    palette_entry(1, 2, 3),
-    palette_entry(3, 0, 1),
-    palette_entry(3, 0, 3),
-    palette_entry(3, 2, 1),
-    palette_entry(3, 2, 3),
-    palette_entry(1, 1, 0),
-    palette_entry(1, 1, 2),
-    palette_entry(1, 3, 0),
-    palette_entry(1, 3, 2),
-    palette_entry(3, 1, 0),
-    palette_entry(3, 1, 2),
-    palette_entry(3, 3, 0),
-    palette_entry(3, 3, 2),
-    palette_entry(1, 1, 1),
-    palette_entry(1, 1, 3),
-    palette_entry(1, 3, 1),
-    palette_entry(1, 3, 3),
-    palette_entry(3, 1, 1),
-    palette_entry(3, 1, 3),
-    palette_entry(3, 3, 1),
-    palette_entry(3, 3, 3),
-};
-#endif NOTYET
-
-static void
-spin(volatile int count)
-{
-    while (count--)
-       count = count;
-}
-
-void
-set_video_mode(unsigned int mode)
-{
-    register unsigned int j, k;
-    const VGAState *      state;
-    extern unsigned short screen_width;
-    extern unsigned short screen_height;
-
-    screen_width  = 640;
-    screen_height = 480;
-
-    switch (mode) {
-        case 0x02:
-        case 0x03:
-            video_mode(mode);
-            return;
-            /*
-            state = &VGAMode3;
-            break;
-            */
-        case 0x12:
-            state = &VGAMode12;
-            break;
-        default:
-            return;
-    }
-
-    /* Turn the video off while we are doing this.... */
-    outb(VGA_SEQ_INDEX, 1);
-    outb(VGA_SEQ_DATA, state->sequencerData[1]);
-
-    /* Set the attribute flip-flop to "index" */
-    inb(VGA_INPUT_STATUS_1);
-
-    /* Give palette to CPU, turns off video */
-    outb(VGA_WRITE_ATTR_INDEX, 0x00);
-
-    /* Set the general registers */
-    outb(VGA_WRITE_MISC_PORT, state->miscOutput);
-    outb(VGA_WRITE_FEATURE_PORT, 0x00);
-
-    /* Load the sequencer registers */
-    for (k = 0; k < VGA_SEQ_CNT; k++) {
-        outb(VGA_SEQ_INDEX, k);
-        outb(VGA_SEQ_DATA, state->sequencerData[k]);
-    }
-    outb(VGA_SEQ_INDEX, 0x00);
-    outb(VGA_SEQ_DATA, 0x03);  /* Low order two bits are reset bits */
-    
-    /* Load the CRTC registers.
-     * CRTC registers 0-7 are locked by a bit in register 0x11. We need
-     * to unlock these registers before we can start setting them.
-     */
-    outb(VGA_CRTC_INDEX, 0x11);
-    outb(VGA_CRTC_DATA, 0x00);         /* Unlocks registers 0-7 */
-    for (k = 0; k < VGA_CRT_CNT; k++) {
-        outb(VGA_CRTC_INDEX, k);
-        outb(VGA_CRTC_DATA, state->crtcData[k]);
-    }
-
-    /* Load the attribute registers */
-    inb(VGA_INPUT_STATUS_1);  /* Set the attribute flip-flop to "index" */
-    for (k = 0; k < VGA_ATR_CNT; k++) {
-        outb(VGA_WRITE_ATTR_INDEX, k);
-        outb(VGA_WRITE_ATTR_DATA, state->attrData[k]);
-    }
-    
-    /* Load graphics registers */
-    for (k = 0; k < VGA_GFX_CNT; k++) {
-        outb(VGA_GFX_INDEX, k);
-        outb(VGA_GFX_DATA, state->graphicsData[k]);
-    }    
-
-    /* Set up the palette. */
-
-    outb(VGA_PALETTE_WRITE, 0);
-    for (k = 0; k < 256; k++) {
-#ifdef NOTYET
-        if (mode == 0x12) {
-#endif NOTYET
-            j = colorData[k % 4];
-            outb(VGA_PALETTE_DATA, j); spin(1000);
-            outb(VGA_PALETTE_DATA, j); spin(1000);
-            outb(VGA_PALETTE_DATA, j); spin(1000);
-#ifdef NOTYET
-        } else {
-            j = mode_03_palette[(k - 64) % 64];
-            outb(VGA_PALETTE_DATA, colorData[(j >> 4) & 3]);
-            outb(VGA_PALETTE_DATA, colorData[(j >> 2) & 3]);
-            outb(VGA_PALETTE_DATA, colorData[j & 3]);
-        }
-#endif NOTYET
-    }
-
-    /* Re-enable video */
-    /* First, clear memory to zeros */
-    bzero((void *) VGA_BUF_ADDR, VGA_BUF_LENGTH);
-
-    /* Set the attribute flip-flop to "index" */
-    inb(VGA_INPUT_STATUS_1);
-
-    /* Give the palette back to the VGA */
-    outb(VGA_WRITE_ATTR_INDEX, 0x20);
-
-    // Really re-enable video.
-    outb(VGA_SEQ_INDEX, 1);
-    outb(VGA_SEQ_DATA, (state->sequencerData[1] & ~0x20));
-}
diff --git a/i386/libsaio/vga.h b/i386/libsaio/vga.h
deleted file mode 100644 (file)
index ee7ad5b..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License").  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * VGA Graphics Controller Port
- */
-
-#ifndef __LIBSAIO_VGA_H
-#define __LIBSAIO_VGA_H
-
-#define VGA_BUF_ADDR               0xA0000
-#define        VGA_BUF_LENGTH              0x10000
-
-#define VGA_GFX_INDEX           0x3CE
-#define VGA_GFX_DATA            0x3CF
-#define        VGA_GFX_RD_MAP_SEL          0x4
-#define        VGA_GFX_BIT_MASK        0x8
-#define VGA_NUM_GFX_REGS        6   // number of graphics controller
-                                    // registers to preserve
-#define VGA_SEQ_INDEX           0x3C4
-#define VGA_SEQ_DATA               0x3C5
-#define        VGA_SEQ_MAP_MASK            0x2
-#define VGA_NUM_SEQ_REGS           5   // number of sequencer
-                                    // registers to preserve
-#define VGA_AC_ADDR             0x3C0
-#define VGA_NUM_AC_REGS         0x14
-
-#define VGA_CRTC_INDEX          0x3D4
-#define VGA_CRTC_DATA              0x3D5
-
-#define        VGA_READ_ATTR_INDEX         0x3C1
-#define VGA_READ_ATTR_DATA         0x3C1
-#define VGA_WRITE_ATTR_INDEX    0x3C0
-#define VGA_WRITE_ATTR_DATA        0x3C0
-
-#define VGA_PALETTE_WRITE          0x3C8
-#define VGA_PALETTE_READ           0x3C7
-#define VGA_PALETTE_DATA           0x3C9
-
-#define        VGA_INPUT_STATUS_1          0x3DA
-#define        VGA_READ_MISC_PORT          0x3CC
-#define        VGA_WRITE_MISC_PORT         0x3C2
-
-#define        VGA_READ_FEATURE_PORT   0x3CA
-#define        VGA_WRITE_FEATURE_PORT  0x3DA
-
-#endif /* !__LIBSAIO_VGA_H */
index 4622a5065bef1a11d3d3821489e6055ac8609b71..eee23ffcdfc135ef12b8ceae8d08a339ca529ebb 100644 (file)
@@ -10,7 +10,7 @@ MANINSTALLDIR = $(SYMROOT)
 INSTALLDIR = $(SYMROOT)
 
 OPTIM = -O2
-CFLAGS = $(OPTIM) -g  -Wall -traditional-cpp
+CFLAGS = $(OPTIM) -g  -Wmost -Werror
 DEFINES=
 INC = -I.
 ifneq "" "$(wildcard /bin/mkdirs)"
index 2f17c72fd08c4887b8abd2cfda99dbc87d01b772..7d0017666067a55cc7244431361593dcf3a011d8 100644 (file)
@@ -1127,9 +1127,9 @@ static ea *process_ea (operand *input, ea *output, int addrbits, int rfield,
                    return NULL;
 
                if (s!=1 && i!=-1) return NULL;/* no can do, in 16-bit EA */
-               if (b==-1 && i!=-1) b ^= i ^= b ^= i;   /* swap them round */
+               if (b==-1 && i!=-1) b ^= i, i ^= b, b ^= i;   /* swap them round */
                if ((b==R_SI || b==R_DI) && i!=-1)
-                   b ^= i ^= b ^= i; /* have BX/BP as base, SI/DI index */
+                   b ^= i, i ^= b, b ^= i; /* have BX/BP as base, SI/DI index */
                if (b==i) return NULL;/* shouldn't ever happen, in theory */
                if (i!=-1 && b!=-1 &&
                    (i==R_BP || i==R_BX || b==R_SI || b==R_DI))
index cf15acdacb1056b12f00b74fa58115592d9577c5..58b517b7544b332fac28f9ff249996cf3bfd8bb6 100644 (file)
@@ -7,8 +7,8 @@ LIBSADIR = ../libsa
 INSTALLDIR = $(DSTROOT)/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders/standalone
 
 OPTIM = -Os
-CFLAGS = $(RC_CFLAGS) $(OPTIM) $(MORECPP) -arch i386 -g -Wmost -Wno-precomp \
-    -munaligned-text -static -traditional-cpp
+CFLAGS = $(RC_CFLAGS) $(OPTIM) $(MORECPP) -arch i386 -g -Wmost -Werror \
+          -fno-builtin -static
 DEFINES=
 CONFIG = hd
 INC = -I. -I$(SYMROOT) -I$(UTILDIR) -I$(LIBSADIR)
index af4470416d49b3fd33aee035720ad38ff4079d0e..56a58c206ef3f60ad944aea0952591a5569f0bd1 100644 (file)
@@ -44,9 +44,9 @@ rcz_compress_memory(
 ) 
 /* Returns actual number of bytes emitted as compressed stream 'out.' */
 {
-    unsigned int c, ct, j, jmatch, jabove, match;
-    unsigned int data[32], version;
-    unsigned int word, token, tokenct, total;
+    unsigned int c, ct, j, jmatch = 0, jabove, match;
+    unsigned int data[32];
+    unsigned int word, token, tokenct;
     unsigned char *outorigin = out;
 
 /* First, put version number into stream. */
index b5a3f86dc411d606c5d7b14099659bf6313d033d..e223f492b6a3634214ae28871357b5917dc1c4aa 100644 (file)
@@ -46,7 +46,6 @@ rcz_decompress_memory(unsigned char *in, unsigned char *out)
     unsigned int c, j, k, jmatch, jabove;
     unsigned int length, even_length, word, token, version;
     unsigned char *outorigin = out;
-    int *a, *b;
 
     version = *in++;
     version = (version<<8) | (*in++);
diff --git a/i386/testmodule/install/install.module b/i386/testmodule/install/install.module
deleted file mode 100755 (executable)
index 5258bb3..0000000
Binary files a/i386/testmodule/install/install.module and /dev/null differ
diff --git a/i386/testmodule/test.module b/i386/testmodule/test.module
deleted file mode 100755 (executable)
index 533445a..0000000
Binary files a/i386/testmodule/test.module and /dev/null differ
diff --git a/i386/tests/sizeof b/i386/tests/sizeof
deleted file mode 100755 (executable)
index 540414f..0000000
Binary files a/i386/tests/sizeof and /dev/null differ
index 59148611a0cafa8e3b958f819ed36667a2b4c708..8bd1b723f060f01009f9f5c1da3f78b529d83d2d 100644 (file)
@@ -14,8 +14,9 @@ LOCALBIN = $(DSTROOT)/usr/local/bin
 LANGDIR = $(INSTALLDIR)/English.lproj
 
 OPTIM = -Os
-CFLAGS = $(RC_CFLAGS) $(OPTIM) -Wmost -Wno-precomp -g -I../rcz -traditional-cpp -nostdinc -nostdlib -I/usr/include -I/System/Library/Frameworks/System.framework/Headers
-LDFLAGS = /usr/lib/crt1.o /System/Library/Frameworks/System.framework/System -lcc
+CFLAGS = $(RC_CFLAGS) $(OPTIM) -Wmost -Werror -g -I../rcz -nostdinc -nostdlib -I/usr/include \
+        -I/System/Library/Frameworks/System.framework/Headers
+LDFLAGS = -L/usr/lib -lcrt1.o -lSystem -lcc_dynamic
 CFILES = machOconv.c mkfont.c tif_packbits.c
 MFILES = dumptiff.m
 HFILES = cursor.h
diff --git a/i386/util/dumptiff b/i386/util/dumptiff
deleted file mode 100755 (executable)
index eec7853..0000000
Binary files a/i386/util/dumptiff and /dev/null differ
index d90c80ebdedcf4f26ab6b798c226212af743bfb8..4d47482777bbaf3ded7cdea39ac7dc92db271adc 100644 (file)
@@ -22,7 +22,7 @@
  * @APPLE_LICENSE_HEADER_END@
  */
 #ifndef lint
-static char rcsid[] = "$Header: /cvs/Darwin/System/boot/i386/util/tif_packbits.c,v 1.1.1.2 1999/08/04 21:17:19 wsanchez Exp $";
+static char rcsid[] = "$Header: /cvs/Darwin/boot/i386/util/tif_packbits.c,v 1.1.1.2 1999/08/04 21:17:19 wsanchez Exp $";
 #endif
 
 /*