Full memory management support (memory.c & memory.h & mem.S)
authorBrian Palmer <brianp@sginet.com>
Fri, 6 Jul 2001 22:05:05 +0000 (22:05 +0000)
committerBrian Palmer <brianp@sginet.com>
Fri, 6 Jul 2001 22:05:05 +0000 (22:05 +0000)
Preliminary debug code (debug.c & debug.h)
Reworked .ini file code (parseini.c & parseini.h)
Size optimizations (fat.asm & fat32.asm)
FAT12/16 boot sector now fully understands the FAT (fat.asm)

svn path=/trunk/; revision=2049

34 files changed:
freeldr/Makefile [new file with mode: 0644]
freeldr/bootsect/BOOTSECT.ASM [deleted file]
freeldr/bootsect/MAKE.BAT [deleted file]
freeldr/bootsect/Makefile [new file with mode: 0644]
freeldr/bootsect/bin2c.c [moved from freeldr/bootsect/c_data.c with 54% similarity]
freeldr/bootsect/bootsect.h [deleted file]
freeldr/bootsect/btsect32.h [deleted file]
freeldr/bootsect/fat.asm [new file with mode: 0644]
freeldr/bootsect/fat32.asm [moved from freeldr/bootsect/BTSECT32.ASM with 82% similarity]
freeldr/bootsect/install.bat [deleted file]
freeldr/bootsect/install.src [deleted file]
freeldr/bootsect/split.c [new file with mode: 0644]
freeldr/bootsect/stubit.c [new file with mode: 0644]
freeldr/bootsect/win2k.asm
freeldr/freeldr/Makefile
freeldr/freeldr/arcname.c
freeldr/freeldr/arcname.h
freeldr/freeldr/debug.c [new file with mode: 0644]
freeldr/freeldr/debug.h [new file with mode: 0644]
freeldr/freeldr/freeldr.c
freeldr/freeldr/freeldr.h
freeldr/freeldr/fs.c
freeldr/freeldr/linux.c
freeldr/freeldr/memory.c
freeldr/freeldr/memory.h
freeldr/freeldr/miscboot.c
freeldr/freeldr/multiboot.c
freeldr/freeldr/multiboot.h
freeldr/freeldr/options.c
freeldr/freeldr/parseini.c [new file with mode: 0644]
freeldr/freeldr/parseini.h [new file with mode: 0644]
freeldr/freeldr/reactos.c
freeldr/freeldr/reactos.h
freeldr/freeldr/stdlib.h

diff --git a/freeldr/Makefile b/freeldr/Makefile
new file mode 100644 (file)
index 0000000..e84bfbb
--- /dev/null
@@ -0,0 +1,43 @@
+#
+#  FreeLoader
+#  Copyright (C) 1999, 2000, 2001  Brian Palmer  <brianp@sginet.com>
+#
+#  This program is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+       
+
+export CC      = gcc
+export LD      = ld
+export AR      = ar
+export RM      = cmd /C del
+export CP      = cmd /C copy
+export NASM    = nasm
+export MAKE    = make
+
+.PHONY : bootsect freeldr install clean
+
+all: bootsect freeldr install
+
+bootsect:
+       $(MAKE) -C bootsect
+
+freeldr: bootsect
+       $(MAKE) -C freeldr
+
+install:
+       $(MAKE) -C install
+
+clean:
+       $(RM) *.bin
diff --git a/freeldr/bootsect/BOOTSECT.ASM b/freeldr/bootsect/BOOTSECT.ASM
deleted file mode 100644 (file)
index b3cea1d..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-; BOOTSECT.ASM
-; FAT12/16 Boot Sector
-; Copyright (c) 1998 Brian Palmer
-
-org 7c00h
-
-segment .text
-
-bits 16
-
-start:
-        jmp short main
-        nop
-
-OEMName         db 'FreeLDR!'
-BytesPerSector  dw 512
-SectsPerCluster db 1
-ReservedSectors dw 1
-NumberOfFats    db 2
-MaxRootEntries  dw 224
-TotalSectors    dw 2880
-MediaDescriptor db 0f0h
-SectorsPerFat   dw 9
-SectorsPerTrack dw 18
-NumberOfHeads   dw 2
-HiddenSectors   dd 0
-TotalSectorsBig dd 0
-BootDrive       db 0
-Reserved        db 0
-ExtendSig       db 29h
-SerialNumber    dd 00000000h
-VolumeLabel     db 'FreeLoader!'
-FileSystem      db 'FAT12   '
-
-main:
-        cli
-        cld
-        xor ax,ax
-        mov ss,ax
-        mov sp,7c00h            ; Setup a stack
-        mov ax,cs               ; Setup segment registers
-        mov ds,ax               ; Make DS correct
-        mov es,ax               ; Make ES correct
-
-
-        sti                     ; Enable ints now
-        mov [BootDrive],dl      ; Save the boot drive
-        xor ax,ax               ; Zero out AX
-
-        ; Reset disk controller
-        int 13h         
-        jnc Continue1           
-        jmp BadBoot             ; Reset failed...
-
-Continue1:
-        ; Now we must find our way to the first sector of the root directory
-        xor ax,ax
-        xor cx,cx
-        mov al,[NumberOfFats]    ; Number of fats
-        mul WORD [SectorsPerFat] ; Times sectors per fat
-        add ax,WORD [HiddenSectors] 
-        adc dx,WORD [HiddenSectors+2] ; Add the number of hidden sectors 
-        add ax,[ReservedSectors]     ; Add the number of reserved sectors
-        adc dx,cx               ; Add carry bit
-        push ax                 ; Store it on the stack
-        push dx                 ; Save 32-bit logical start sector
-        push ax
-        push dx                 ; Save it for later use also
-        ; DX:AX now has the number of the starting sector of the root directory
-
-        ; Now calculate the size of the root directory
-        mov ax,0020h            ; Size of dir entry
-        mul WORD [MaxRootEntries] ; Times the number of entries
-        mov bx,[BytesPerSector]
-        add ax,bx
-        dec ax
-        div bx                  ; Divided by the size of a sector
-        ; AX now has the number of root directory sectors
-
-        xchg ax,cx              ; Now CX has number of sectors
-        pop  dx
-        pop  ax                 ; Restore logical sector start
-        push cx                 ; Save for later use
-        mov  bx,7c0h            ; We will load the root directory 
-        add  bx,20h             ; Right after the boot sector in memory
-        mov  es,bx
-        xor  bx,bx              ; We will load it to [0000:7e00h]
-        call ReadSectors        ; Read the sectors
-        jnc  Continue2          ; BadBoot on error
-        jmp  BadBoot
-Continue2:
-
-
-        ; Now we have to find our way through the root directory to
-        ; The OSLOADER.SYS file
-        mov  bx,[MaxRootEntries]; Search entire root directory
-        mov  ax,7e0h            ; We loaded at 07e0:0000
-        mov  es,ax
-        xor  di,di
-        mov  si,filename
-        mov  cx,11
-        rep  cmpsb              ; Compare filenames
-        jz   FoundFile          ; If same we found it
-        dec  bx
-        jnz  FindFile
-        jmp  ErrBoot
-
-FindFile:
-        mov  ax,es              ; We didn't find it in the previous dir entry
-        add  ax,2               ; So lets move to the next one
-        mov  es,ax              ; And search again
-        xor  di,di
-        mov  si,filename        
-        mov  cx,11
-        rep  cmpsb              ; Compare filenames
-        jz   FoundFile          ; If same we found it
-        dec  bx                 ; Keep searching till we run out of dir entries
-        jnz  FindFile           ; Last entry?
-        jmp  ErrBoot
-
-FoundFile:
-        xor  di,di              ; ES:DI has dir entry
-        xor  dx,dx
-        mov  ax,WORD [es:di+1ah]        ; Get start cluster
-        dec  ax
-        dec  ax
-        xor  ch,ch
-        mov  cl,BYTE [SectsPerCluster] ; Times sectors per cluster
-        mul  cx
-        pop  cx                 ; Get number of sectors for root dir
-        add  ax,cx
-        adc  dx,0
-        pop  cx                 ; Get logical start sector of
-        pop  bx                 ; Root directory
-        add  ax,bx              ; Now we have DX:AX with the logical start
-        adc  dx,cx              ; Sector of OSLOADER.SYS
-        push ax
-        push dx
-        mov  ax,WORD [es:di+1ch]
-        mov  dx,WORD [es:di+1eh]
-        mov  bx,[BytesPerSector]
-        dec  bx
-        add  ax,bx
-        adc  dx,0
-        div  WORD [BytesPerSector]
-        xchg ax,cx              ; Now CX has number of sectors of OSLOADER.SYS
-        pop  dx
-        pop  ax
-        mov  bx,800h
-        mov  es,bx
-        xor  bx,bx              ; Load ROSLDR at 0000:8000h
-        call ReadSectors        ; Load it
-        jc   BadBoot
-        mov  dl,[BootDrive]
-        xor  ax,ax
-        push ax
-        mov  ax,8000h
-        push ax                 ; We will do a far return to 0000:8000h
-        retf                    ; Transfer control to ROSLDR
-
-
-
-; Reads logical sectors into [ES:BX]
-; DX:AX has logical sector number to read
-; CX has number of sectors to read
-; CarryFlag set on error
-ReadSectors:
-        push ax
-        push dx
-        push cx
-        xchg ax,cx
-        xchg ax,dx
-        xor  dx,dx
-        div  WORD [SectorsPerTrack]
-        xchg ax,cx                    
-        div  WORD [SectorsPerTrack]    ; Divide logical by SectorsPerTrack
-        inc  dx                        ; Sectors numbering starts at 1 not 0
-        xchg cx,dx
-        div  WORD [NumberOfHeads]      ; Number of heads
-        mov  dh,dl                     ; Head to DH, drive to DL
-        mov  dl,[BootDrive]            ; Drive number
-        mov  ch,al                     ; Cylinder in CX
-        ror  ah,1                      ; Low 8 bits of cylinder in CH, high 2 bits
-        ror  ah,1                      ;  in CL shifted to bits 6 & 7
-        or   cl,ah                     ; Or with sector number
-        mov  ax,513
-        int  13h     ; DISK - READ SECTORS INTO MEMORY
-                     ; AL = number of sectors to read, CH = track, CL = sector
-                     ; DH = head, DL    = drive, ES:BX -> buffer to fill
-                     ; Return: CF set on error, AH =    status (see AH=01h), AL    = number of sectors read
-        pop  cx
-        pop  dx
-        pop  ax
-        jc   ReadFail
-        inc  ax       ;Increment Sector to Read
-        jnz  NoCarry
-        inc  dx
-
-
-NoCarry:
-        push bx
-        mov  bx,es
-        add  bx,20h
-        mov  es,bx
-        pop  bx
-                                        ; Increment read buffer for next sector
-        loop ReadSectors                ; Read next sector
-
-
-ReadFail:
-        ret   
-
-
-
-; Displays a bad boot message
-; And reboots
-BadBoot:
-        mov  si,msgDiskError    ; Bad boot disk message
-        call PutChars           ; Display it
-        mov  si,msgAnyKey       ; Press any key message
-        call PutChars           ; Display it
-
-               jmp  Reboot
-
-; Displays an error message
-; And reboots
-ErrBoot:
-        mov  si,msgFreeLdr      ; FreeLdr not found message
-        call PutChars           ; Display it
-        mov  si,msgAnyKey       ; Press any key message
-        call PutChars           ; Display it
-
-Reboot:
-        xor ax,ax       
-        int 16h                 ; Wait for a keypress
-        int 19h                 ; Reboot
-
-PutChars:
-        lodsb
-        or al,al
-        jz short Done
-        mov ah,0eh
-        mov bx,07h
-        int 10h
-        jmp short PutChars
-Done:
-        retn
-
-msgDiskError db 'Disk error',0dh,0ah,0
-msgFreeLdr   db 'FREELDR.SYS not found',0dh,0ah,0
-msgAnyKey    db 'Press any key to continue.',0dh,0ah,0
-filename     db 'FREELDR SYS'
-
-        times 510-($-$$) db 0   ; Pad to 510 bytes
-        dw 0aa55h       ; BootSector signature
-        
diff --git a/freeldr/bootsect/MAKE.BAT b/freeldr/bootsect/MAKE.BAT
deleted file mode 100644 (file)
index 35efa95..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-nasm -o bootsect.bin -f bin bootsect.asm
-nasm -o btsect32.bin -f bin btsect32.asm
\ No newline at end of file
diff --git a/freeldr/bootsect/Makefile b/freeldr/bootsect/Makefile
new file mode 100644 (file)
index 0000000..194b154
--- /dev/null
@@ -0,0 +1,54 @@
+#
+#  FreeLoader
+#  Copyright (C) 1999, 2000, 2001  Brian Palmer  <brianp@sginet.com>
+#
+#  This program is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+       
+
+export CC = gcc
+export LD = ld
+export AR = ar
+export RM = cmd /C del
+export CP = cmd /C copy
+export NASM = nasm
+
+.PHONY : clean
+
+all: fat.bin fat32.bin bin2c.exe split.exe stubit.exe
+
+fat.bin: fat.asm bin2c.exe split.exe
+       $(NASM) -o fat_tmp.bin -f bin fat.asm
+       split fat_tmp.bin fat.bin fatstub.bin 512
+       $(RM) fat_tmp.bin
+       bin2c fat.bin fat.h fat_data
+
+fat32.bin: fat32.asm bin2c.exe
+       $(NASM) -o fat32.bin -f bin fat32.asm
+       bin2c fat32.bin fat32.h fat32_data
+
+bin2c.exe: bin2c.c
+       $(CC) -o bin2c.exe bin2c.c
+
+split.exe: split.c
+       $(CC) -o split.exe split.c
+
+stubit.exe: stubit.c
+       $(CC) -o stubit.exe stubit.c
+
+clean:
+       $(RM) *.bin
+       $(RM) *.exe
+       $(RM) *.h
similarity index 54%
rename from freeldr/bootsect/c_data.c
rename to freeldr/bootsect/bin2c.c
index 963df42..88de4b7 100644 (file)
@@ -1,32 +1,31 @@
 #include <stdio.h>
 
-char   in_filename[260];
-char   out_filename[260];
 FILE   *in;
 FILE   *out;
 
-int main(void)
+int main(int argc, char *argv[])
 {
        unsigned char   ch;
        int                             cnt = 0;
 
-       printf("Enter data filename: ");
-       scanf("%s", in_filename);
-       printf("Enter output filename: ");
-       scanf("%s", out_filename);
+       if (argc < 4)
+       {
+               printf("usage: bin2c infile.bin outfile.h array_name\n");
+               return -1;
+       }
 
-       if ((in = fopen(in_filename, "rb")) == NULL)
+       if ((in = fopen(argv[1], "rb")) == NULL)
        {
                printf("Couldn't open data file.\n");
-               return 0;
+               return -1;
        }
-       if ((out = fopen(out_filename, "wb")) == NULL)
+       if ((out = fopen(argv[2], "wb")) == NULL)
        {
                printf("Couldn't open output file.\n");
-               return 0;
+               return -1;
        }
 
-       fprintf(out, "unsigned char data[] = {\n");
+       fprintf(out, "unsigned char %s[] = {\n", argv[3]);
 
        ch = fgetc(in);
        while (!feof(in))
diff --git a/freeldr/bootsect/bootsect.h b/freeldr/bootsect/bootsect.h
deleted file mode 100644 (file)
index ef020f3..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-unsigned char data[] = {
-
-0xeb, 0x3c, 0x90, 0x46, 0x72, 0x65, 0x65, 0x4c, 0x44, 0x52, 0x21, 0x00, 0x02, 0x01, 0x01, 0x00, 
-0x02, 0x00, 0x02, 0x40, 0x0b, 0xf0, 0x09, 0x00, 0x12, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0x46, 0x72, 0x65, 0x65, 0x4c, 
-0x6f, 0x61, 0x64, 0x65, 0x72, 0x21, 0x46, 0x41, 0x54, 0x31, 0x32, 0x20, 0x20, 0x20, 0xfa, 0xfc, 
-0x31, 0xc0, 0x8e, 0xd0, 0xbc, 0x00, 0x7c, 0x8c, 0xc8, 0x8e, 0xd8, 0x8e, 0xc0, 0xfb, 0x88, 0x16, 
-0x24, 0x7c, 0x31, 0xc0, 0xcd, 0x13, 0x73, 0x03, 0xe9, 0x0b, 0x01, 0x31, 0xc0, 0x31, 0xc9, 0xa0, 
-0x10, 0x7c, 0xf7, 0x26, 0x16, 0x7c, 0x03, 0x06, 0x1c, 0x7c, 0x13, 0x16, 0x1e, 0x7c, 0x03, 0x06, 
-0x0e, 0x7c, 0x11, 0xca, 0x50, 0x52, 0x50, 0x52, 0xb8, 0x20, 0x00, 0xf7, 0x26, 0x11, 0x7c, 0x8b, 
-0x1e, 0x0b, 0x7c, 0x01, 0xd8, 0x48, 0xf7, 0xf3, 0x91, 0x5a, 0x58, 0x51, 0xbb, 0xc0, 0x07, 0x81, 
-0xc3, 0x20, 0x00, 0x8e, 0xc3, 0x31, 0xdb, 0xe8, 0x8c, 0x00, 0x73, 0x03, 0xe9, 0xc7, 0x00, 0x8b, 
-0x1e, 0x11, 0x7c, 0xb8, 0xe0, 0x07, 0x8e, 0xc0, 0x31, 0xff, 0xbe, 0xd8, 0x7d, 0xb9, 0x0b, 0x00, 
-0xf3, 0xa6, 0x74, 0x1f, 0x4b, 0x75, 0x03, 0xe9, 0xbb, 0x00, 0x8c, 0xc0, 0x05, 0x02, 0x00, 0x8e, 
-0xc0, 0x31, 0xff, 0xbe, 0xd8, 0x7d, 0xb9, 0x0b, 0x00, 0xf3, 0xa6, 0x74, 0x06, 0x4b, 0x75, 0xea, 
-0xe9, 0xa2, 0x00, 0x31, 0xff, 0x31, 0xd2, 0x26, 0x8b, 0x45, 0x1a, 0x48, 0x48, 0x30, 0xed, 0x8a, 
-0x0e, 0x0d, 0x7c, 0xf7, 0xe1, 0x59, 0x01, 0xc8, 0x81, 0xd2, 0x00, 0x00, 0x59, 0x5b, 0x01, 0xd8, 
-0x11, 0xca, 0x50, 0x52, 0x26, 0x8b, 0x45, 0x1c, 0x26, 0x8b, 0x55, 0x1e, 0x8b, 0x1e, 0x0b, 0x7c, 
-0x4b, 0x01, 0xd8, 0x81, 0xd2, 0x00, 0x00, 0xf7, 0x36, 0x0b, 0x7c, 0x91, 0x5a, 0x58, 0xbb, 0x00, 
-0x08, 0x8e, 0xc3, 0x31, 0xdb, 0xe8, 0x0e, 0x00, 0x72, 0x4c, 0x8a, 0x16, 0x24, 0x7c, 0x31, 0xc0, 
-0x50, 0xb8, 0x00, 0x80, 0x50, 0xcb, 0x50, 0x52, 0x51, 0x91, 0x92, 0x31, 0xd2, 0xf7, 0x36, 0x18, 
-0x7c, 0x91, 0xf7, 0x36, 0x18, 0x7c, 0x42, 0x87, 0xca, 0xf7, 0x36, 0x1a, 0x7c, 0x88, 0xd6, 0x8a, 
-0x16, 0x24, 0x7c, 0x88, 0xc5, 0xd0, 0xcc, 0xd0, 0xcc, 0x08, 0xe1, 0xb8, 0x01, 0x02, 0xcd, 0x13, 
-0x59, 0x5a, 0x58, 0x72, 0x10, 0x40, 0x75, 0x01, 0x42, 0x53, 0x8c, 0xc3, 0x81, 0xc3, 0x20, 0x00, 
-0x8e, 0xc3, 0x5b, 0xe2, 0xc1, 0xc3, 0xbe, 0x96, 0x7d, 0xe8, 0x1b, 0x00, 0xbe, 0xbb, 0x7d, 0xe8, 
-0x15, 0x00, 0xe9, 0x0c, 0x00, 0xbe, 0xa3, 0x7d, 0xe8, 0x0c, 0x00, 0xbe, 0xbb, 0x7d, 0xe8, 0x06, 
-0x00, 0x31, 0xc0, 0xcd, 0x16, 0xcd, 0x19, 0xac, 0x08, 0xc0, 0x74, 0x09, 0xb4, 0x0e, 0xbb, 0x07, 
-0x00, 0xcd, 0x10, 0xeb, 0xf2, 0xc3, 0x44, 0x69, 0x73, 0x6b, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 
-0x0d, 0x0a, 0x00, 0x46, 0x52, 0x45, 0x45, 0x4c, 0x44, 0x52, 0x2e, 0x53, 0x59, 0x53, 0x20, 0x6e, 
-0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x0d, 0x0a, 0x00, 0x50, 0x72, 0x65, 0x73, 0x73, 
-0x20, 0x61, 0x6e, 0x79, 0x20, 0x6b, 0x65, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x6f, 0x6e, 0x74, 
-0x69, 0x6e, 0x75, 0x65, 0x2e, 0x0d, 0x0a, 0x00, 0x46, 0x52, 0x45, 0x45, 0x4c, 0x44, 0x52, 0x20, 
-0x53, 0x59, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa
-};
\ No newline at end of file
diff --git a/freeldr/bootsect/btsect32.h b/freeldr/bootsect/btsect32.h
deleted file mode 100644 (file)
index 57dc647..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-unsigned char data[] = {
-
-0xeb, 0x58, 0x90, 0x46, 0x72, 0x65, 0x65, 0x4c, 0x44, 0x52, 0x21, 0x00, 0x02, 0x01, 0x01, 0x00, 
-0x02, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x12, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0x46, 0x72, 0x65, 0x65, 0x4c, 0x6f, 0x61, 0x64, 0x65, 
-0x72, 0x21, 0x46, 0x41, 0x54, 0x33, 0x32, 0x20, 0x20, 0x20, 0xfa, 0xfc, 0x31, 0xc0, 0x8e, 0xd0, 
-0xbc, 0x00, 0x7c, 0x8c, 0xc8, 0x8e, 0xd8, 0x8e, 0xc0, 0xfb, 0x88, 0x16, 0x40, 0x7c, 0x31, 0xc0, 
-0xcd, 0x13, 0x73, 0x03, 0xe9, 0x05, 0x01, 0x31, 0xd2, 0xb8, 0x0e, 0x00, 0x03, 0x06, 0x1c, 0x7c, 
-0x13, 0x16, 0x1e, 0x7c, 0xb9, 0x01, 0x00, 0xbb, 0xe0, 0x07, 0x8e, 0xc3, 0x31, 0xdb, 0xe8, 0xab, 
-0x00, 0x73, 0x03, 0xe9, 0xe6, 0x00, 0x66, 0xa1, 0x2c, 0x7c, 0x66, 0x3d, 0xf8, 0xff, 0xff, 0x0f, 
-0x72, 0x03, 0xe9, 0xe6, 0x00, 0xbb, 0x00, 0x08, 0x8e, 0xc3, 0xe8, 0xb2, 0x01, 0x31, 0xdb, 0x8a, 
-0x1e, 0x0d, 0x7c, 0xc1, 0xe3, 0x04, 0xb8, 0x00, 0x08, 0x8e, 0xc0, 0x31, 0xff, 0xbe, 0xee, 0x7d, 
-0xb9, 0x0b, 0x00, 0xf3, 0xa6, 0x74, 0x2a, 0x4b, 0x75, 0x03, 0xe9, 0xbe, 0x00, 0x8c, 0xc0, 0x05, 
-0x02, 0x00, 0x8e, 0xc0, 0x31, 0xff, 0xbe, 0xee, 0x7d, 0xb9, 0x0b, 0x00, 0xf3, 0xa6, 0x74, 0x11, 
-0x4b, 0x75, 0xea, 0x66, 0xa1, 0x2c, 0x7c, 0xe8, 0x16, 0x01, 0x66, 0xa3, 0x2c, 0x7c, 0xe9, 0xa5, 
-0xff, 0x31, 0xff, 0x31, 0xd2, 0x26, 0x8b, 0x45, 0x14, 0x66, 0xc1, 0xe0, 0x10, 0x26, 0x8b, 0x45, 
-0x1a, 0xbb, 0x00, 0x08, 0x8e, 0xc3, 0x66, 0x3d, 0xf8, 0xff, 0xff, 0x0f, 0x73, 0x22, 0x66, 0x50, 
-0x31, 0xdb, 0x06, 0xe8, 0x49, 0x01, 0x07, 0x31, 0xdb, 0x8a, 0x1e, 0x0d, 0x7c, 0xc1, 0xe3, 0x05, 
-0x8c, 0xc0, 0x01, 0xd8, 0x8e, 0xc0, 0x66, 0x58, 0x06, 0xe8, 0xd4, 0x00, 0x07, 0xe9, 0xd6, 0xff, 
-0x8a, 0x16, 0x40, 0x7c, 0x31, 0xc0, 0x50, 0xb8, 0x00, 0x80, 0x50, 0xcb, 0x50, 0x52, 0x51, 0x91, 
-0x92, 0x31, 0xd2, 0xf7, 0x36, 0x18, 0x7c, 0x91, 0xf7, 0x36, 0x18, 0x7c, 0x42, 0x87, 0xca, 0xf7, 
-0x36, 0x1a, 0x7c, 0x88, 0xd6, 0x8a, 0x16, 0x40, 0x7c, 0x88, 0xc5, 0xd0, 0xcc, 0xd0, 0xcc, 0x08, 
-0xe1, 0xb8, 0x01, 0x02, 0xcd, 0x13, 0x59, 0x5a, 0x58, 0x72, 0x10, 0x40, 0x75, 0x01, 0x42, 0x53, 
-0x8c, 0xc3, 0x81, 0xc3, 0x20, 0x00, 0x8e, 0xc3, 0x5b, 0xe2, 0xc1, 0xc3, 0xbe, 0xac, 0x7d, 0xe8, 
-0x1b, 0x00, 0xbe, 0xd1, 0x7d, 0xe8, 0x15, 0x00, 0xe9, 0x0c, 0x00, 0xbe, 0xb9, 0x7d, 0xe8, 0x0c, 
-0x00, 0xbe, 0xd1, 0x7d, 0xe8, 0x06, 0x00, 0x31, 0xc0, 0xcd, 0x16, 0xcd, 0x19, 0xac, 0x08, 0xc0, 
-0x74, 0x09, 0xb4, 0x0e, 0xbb, 0x07, 0x00, 0xcd, 0x10, 0xeb, 0xf2, 0xc3, 0x44, 0x69, 0x73, 0x6b, 
-0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x0d, 0x0a, 0x00, 0x46, 0x52, 0x45, 0x45, 0x4c, 0x44, 0x52, 
-0x2e, 0x53, 0x59, 0x53, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x0d, 0x0a, 
-0x00, 0x50, 0x72, 0x65, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x6b, 0x65, 0x79, 0x20, 0x74, 
-0x6f, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x2e, 0x0d, 0x0a, 0x00, 0x46, 0x52, 
-0x45, 0x45, 0x4c, 0x44, 0x52, 0x20, 0x53, 0x59, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa, 
-0x66, 0xc1, 0xe0, 0x02, 0x66, 0x89, 0xc1, 0x66, 0x31, 0xd2, 0x66, 0x0f, 0xb7, 0x1e, 0x0b, 0x7c, 
-0x66, 0x53, 0x66, 0xf7, 0xf3, 0x66, 0x0f, 0xb7, 0x1e, 0x0e, 0x7c, 0x66, 0x01, 0xd8, 0x66, 0x0f, 
-0xb7, 0x1e, 0x1c, 0x7c, 0x66, 0x01, 0xd8, 0x66, 0x5b, 0x66, 0x4b, 0x66, 0x21, 0xd9, 0x66, 0x51, 
-0x66, 0xc1, 0xc8, 0x10, 0x89, 0xc2, 0x66, 0xc1, 0xc8, 0x10, 0xbb, 0x00, 0x70, 0x8e, 0xc3, 0x31, 
-0xdb, 0xb9, 0x01, 0x00, 0xe8, 0xf5, 0xfe, 0x73, 0x03, 0xe9, 0x30, 0xff, 0xbb, 0x00, 0x70, 0x8e, 
-0xc3, 0x66, 0x59, 0x26, 0x66, 0x67, 0x8b, 0x01, 0x66, 0x25, 0xff, 0xff, 0xff, 0x0f, 0xc3, 0x66, 
-0x48, 0x66, 0x48, 0x66, 0x31, 0xd2, 0x66, 0x0f, 0xb6, 0x1e, 0x0d, 0x7c, 0x66, 0xf7, 0xe3, 0x66, 
-0x50, 0x66, 0x31, 0xd2, 0x66, 0x0f, 0xb6, 0x06, 0x10, 0x7c, 0x66, 0xf7, 0x26, 0x24, 0x7c, 0x66, 
-0x0f, 0xb7, 0x1e, 0x0e, 0x7c, 0x66, 0x01, 0xd8, 0x66, 0x03, 0x06, 0x1c, 0x7c, 0x66, 0x5b, 0x66, 
-0x01, 0xd8, 0x66, 0xc1, 0xc8, 0x10, 0x89, 0xc2, 0x66, 0xc1, 0xc8, 0x10, 0x31, 0xdb, 0x0f, 0xb6, 
-0x0e, 0x0d, 0x7c, 0xe8, 0x96, 0xfe, 0x73, 0x03, 0xe9, 0xd1, 0xfe, 0xc3, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa
-};
\ No newline at end of file
diff --git a/freeldr/bootsect/fat.asm b/freeldr/bootsect/fat.asm
new file mode 100644 (file)
index 0000000..ce44006
--- /dev/null
@@ -0,0 +1,494 @@
+; FAT.ASM
+; FAT12/16 Boot Sector
+; Copyright (c) 1998, 2001 Brian Palmer
+
+
+
+; This is a FAT12/16 file system boot sector
+; that searches the entire root directory
+; for the file freeldr.sys and loads it into
+; memory.
+;
+; The stack is set to 0000:7C00 so that the first
+; DWORD pushed will be placed at 0000:7BFC
+;
+; When it locates freeldr.sys on the disk it will
+; load the first sector of the file to 0000:7E00
+; With the help of this sector we should be able
+; to load the entire file off the disk, no matter
+; how fragmented it is.
+;
+; We load the entire FAT table into memory at
+; 7000:0000. This improves the speed of floppy disk
+; boots dramatically.
+
+
+
+org 7c00h
+
+segment .text
+
+bits 16
+
+start:
+        jmp short main
+        nop
+
+OEMName         db 'FrLdr1.0'
+BytesPerSector  dw 512
+SectsPerCluster db 1
+ReservedSectors dw 1
+NumberOfFats    db 2
+MaxRootEntries  dw 224
+TotalSectors    dw 2880
+MediaDescriptor db 0f0h
+SectorsPerFat   dw 9
+SectorsPerTrack dw 18
+NumberOfHeads   dw 2
+HiddenSectors   dd 0
+TotalSectorsBig dd 0
+BootDrive       db 0
+Reserved        db 0
+ExtendSig       db 29h
+SerialNumber    dd 00000000h
+VolumeLabel     db 'NO NAME    '
+FileSystem      db 'FAT12   '
+
+main:
+        cli
+        cld
+        xor ax,ax
+        mov ss,ax
+        mov bp,7c00h
+        mov sp,bp               ; Setup a stack
+        mov ax,cs               ; Setup segment registers
+        mov ds,ax               ; Make DS correct
+        mov es,ax               ; Make ES correct
+
+
+        sti                     ; Enable ints now
+        mov [BYTE bp+BootDrive],dl      ; Save the boot drive
+        xor ax,ax               ; Zero out AX
+
+        ; Reset disk controller
+        int 13h         
+        jnc Continue1           
+        jmp BadBoot             ; Reset failed...
+
+Continue1:
+        ; Now we must find our way to the first sector of the root directory
+        xor ax,ax
+        xor dx,dx
+        mov al,[BYTE bp+NumberOfFats]    ; Number of fats
+        mul WORD [BYTE bp+SectorsPerFat] ; Times sectors per fat
+        add ax,WORD [BYTE bp+HiddenSectors] 
+        adc dx,WORD [BYTE bp+HiddenSectors+2] ; Add the number of hidden sectors 
+        add ax,WORD [BYTE bp+ReservedSectors] ; Add the number of reserved sectors
+        adc dx,byte 0           ; Add carry bit
+        push ax                 ; Store it on the stack
+        push dx                 ; Save 32-bit logical start sector
+        push ax
+        push dx                 ; Save it for later use also
+        ; DX:AX now has the number of the starting sector of the root directory
+
+        ; Now calculate the size of the root directory
+        mov ax,0020h            ; Size of dir entry
+        mul WORD [BYTE bp+MaxRootEntries] ; Times the number of entries
+        mov bx,[BYTE bp+BytesPerSector]
+        add ax,bx
+        dec ax
+        div bx                  ; Divided by the size of a sector
+        ; AX now has the number of root directory sectors
+
+        xchg ax,cx              ; Now CX has number of sectors
+        pop  dx
+        pop  ax                 ; Restore logical sector start
+        push cx                 ; Save number of root dir sectors for later use
+        mov  bx,7c0h            ; We will load the root directory 
+        add  bx,byte 20h        ; Right after the boot sector in memory
+        mov  es,bx
+        xor  bx,bx              ; We will load it to [0000:7e00h]
+        call ReadSectors        ; Read the sectors
+
+
+        ; Now we have to find our way through the root directory to
+        ; The OSLOADER.SYS file
+        mov  bx,[BYTE bp+MaxRootEntries]; Search entire root directory
+        mov  ax,7e0h            ; We loaded at 07e0:0000
+        mov  es,ax
+        xor  di,di
+        mov  si,filename
+        mov  cx,11
+        rep  cmpsb              ; Compare filenames
+        jz   FoundFile          ; If same we found it
+        dec  bx
+        jnz  FindFile
+        jmp  ErrBoot
+
+FindFile:
+        mov  ax,es              ; We didn't find it in the previous dir entry
+        add  ax,byte 2          ; So lets move to the next one
+        mov  es,ax              ; And search again
+        xor  di,di
+        mov  si,filename        
+        mov  cx,11
+        rep  cmpsb              ; Compare filenames
+        jz   FoundFile          ; If same we found it
+        dec  bx                 ; Keep searching till we run out of dir entries
+        jnz  FindFile           ; Last entry?
+        jmp  ErrBoot
+
+FoundFile:
+               ; We found freeldr.sys on the disk
+               ; so we need to load the first 512
+               ; bytes of it to 0000:7E00
+        xor  di,di              ; ES:DI has dir entry
+        xor  dx,dx
+        mov  ax,WORD [es:di+1ah]; Get start cluster
+        dec  ax                                        ; Adjust start cluster by 2
+        dec  ax                                        ; Because the data area starts on cluster 2
+        xor  ch,ch
+        mov  cl,BYTE [BYTE bp+SectsPerCluster] ; Times sectors per cluster
+        mul  cx
+        pop  cx                 ; Get number of sectors for root dir
+        add  ax,cx                             ; Add it to the start sector of freeldr.sys
+        adc  dx,byte 0
+        pop  cx                 ; Get logical start sector of
+        pop  bx                 ; Root directory
+        add  ax,bx              ; Now we have DX:AX with the logical start
+        adc  dx,cx              ; Sector of OSLOADER.SYS
+               mov  cx,1                               ; We will load 1 sector
+        push WORD [es:di+1ah]   ; Save start cluster
+        mov  bx,7e0h
+        mov  es,bx
+        xor  bx,bx
+        call ReadSectors        ; Load it
+               pop  ax                                 ; Restore start cluster
+               jmp  LoadFile
+
+
+
+; Reads logical sectors into [ES:BX]
+; DX:AX has logical sector number to read
+; CX has number of sectors to read
+; CarryFlag set on error
+ReadSectors:
+        push ax
+        push dx
+        push cx
+        xchg ax,cx
+        xchg ax,dx
+        xor  dx,dx
+        div  WORD [BYTE bp+SectorsPerTrack]
+        xchg ax,cx                    
+        div  WORD [BYTE bp+SectorsPerTrack]    ; Divide logical by SectorsPerTrack
+        inc  dx                        ; Sectors numbering starts at 1 not 0
+        xchg cx,dx
+        div  WORD [BYTE bp+NumberOfHeads]      ; Number of heads
+        mov  dh,dl                     ; Head to DH, drive to DL
+        mov  dl,[BYTE bp+BootDrive]            ; Drive number
+        mov  ch,al                     ; Cylinder in CX
+        ror  ah,1                      ; Low 8 bits of cylinder in CH, high 2 bits
+        ror  ah,1                      ;  in CL shifted to bits 6 & 7
+        or   cl,ah                     ; Or with sector number
+        mov  ax,0201h
+        int  13h     ; DISK - READ SECTORS INTO MEMORY
+                     ; AL = number of sectors to read, CH = track, CL = sector
+                     ; DH = head, DL    = drive, ES:BX -> buffer to fill
+                     ; Return: CF set on error, AH =    status (see AH=01h), AL    = number of sectors read
+
+        jc   BadBoot
+
+        pop  cx
+        pop  dx
+        pop  ax
+        inc  ax       ;Increment Sector to Read
+        jnz  NoCarry
+        inc  dx
+
+
+NoCarry:
+        push bx
+        mov  bx,es
+        add  bx,byte 20h
+        mov  es,bx
+        pop  bx
+                                        ; Increment read buffer for next sector
+        loop ReadSectors                ; Read next sector
+
+        ret   
+
+
+
+; Displays a bad boot message
+; And reboots
+BadBoot:
+        mov  si,msgDiskError    ; Bad boot disk message
+        call PutChars           ; Display it
+        mov  si,msgAnyKey       ; Press any key message
+        call PutChars           ; Display it
+
+               jmp  Reboot
+
+; Displays an error message
+; And reboots
+ErrBoot:
+        mov  si,msgFreeLdr      ; FreeLdr not found message
+        call PutChars           ; Display it
+        mov  si,msgAnyKey       ; Press any key message
+        call PutChars           ; Display it
+
+Reboot:
+        xor ax,ax       
+        int 16h                 ; Wait for a keypress
+        int 19h                 ; Reboot
+
+PutChars:
+        lodsb
+        or al,al
+        jz short Done
+        mov ah,0eh
+        mov bx,07h
+        int 10h
+        jmp short PutChars
+Done:
+        retn
+
+msgDiskError db 'Disk error',0dh,0ah,0
+msgFreeLdr   db 'FREELDR.SYS not found',0dh,0ah,0
+msgAnyKey    db 'Press any key to continue.',0dh,0ah,0
+filename     db 'FREELDR SYS'
+
+        times 510-($-$$) db 0   ; Pad to 510 bytes
+        dw 0aa55h       ; BootSector signature
+        
+        
+
+; End of bootsector
+;
+; Now starts the extra boot code that we will store
+; in the first 512 bytes of freeldr.sys
+
+
+
+LoadFile:
+               ; Display "Loading FreeLoader..." message
+               push ax
+        mov  si,msgLoading      ; Loading message
+        call PutChars           ; Display it
+               pop  ax
+
+               ; AX has start cluster of freeldr.sys
+               push ax
+               call ReadFatIntoMemory
+               pop  ax
+
+        mov  bx,7e0h
+        mov  es,bx
+
+LoadFile2:
+               push ax
+               call IsFat12
+               pop  ax
+               jnc  LoadFile3
+               cmp  ax,0ff8h               ; Check to see if this is the last cluster in the chain
+               jmp  LoadFile4
+LoadFile3:
+               cmp  ax,0fff8h
+LoadFile4:
+               jae      LoadFile_Done          ; If so continue, if not then read then next one
+               push ax
+        xor  bx,bx              ; Load ROSLDR starting at 0000:8000h
+               push es
+               call ReadCluster
+               pop  es
+
+               xor  bx,bx
+        mov  bl,BYTE [BYTE bp+SectsPerCluster]
+               shl  bx,5                               ; BX = BX * 512 / 16
+               mov  ax,es                              ; Increment the load address by
+               add  ax,bx                              ; The size of a cluster
+               mov  es,ax
+
+               call IsFat12
+               pop  ax
+               push es
+               jnc  LoadFile5
+               call GetFatEntry12              ; Get the next entry
+               jmp  LoadFile6
+LoadFile5:
+               call GetFatEntry16
+LoadFile6:
+               pop  es
+
+        jmp  LoadFile2                 ; Load the next cluster (if any)
+
+LoadFile_Done:
+        mov  dl,BYTE [BYTE bp+BootDrive]
+        xor  ax,ax
+        push ax
+        mov  ax,8000h
+        push ax                 ; We will do a far return to 0000:8000h
+        retf                    ; Transfer control to ROSLDR
+
+
+; Reads the entire FAT into memory at 7000:0000
+ReadFatIntoMemory:
+        mov   ax,WORD [BYTE bp+HiddenSectors] 
+        mov   dx,WORD [BYTE bp+HiddenSectors+2]
+               add   ax,WORD [BYTE bp+ReservedSectors]
+               adc   dx,byte 0
+               mov   cx,WORD [BYTE bp+SectorsPerFat]
+               mov   bx,7000h
+               mov   es,bx
+               xor   bx,bx
+               call  ReadSectors
+               ret
+
+
+; Returns the FAT entry for a given cluster number for 16-bit FAT
+; On entry AX has cluster number
+; On return AX has FAT entry for that cluster
+GetFatEntry16:
+
+               xor   dx,dx
+               mov   cx,2                                              ; AX = AX * 2 (since FAT16 entries are 2 bytes)
+               mul   cx
+               shl   dx,0fh
+
+        mov   bx,7000h
+               add   bx,dx
+        mov   es,bx
+               mov   bx,ax                                             ; Restore FAT entry offset
+               mov   ax,WORD [es:bx]           ; Get FAT entry
+
+               ret
+
+
+; Returns the FAT entry for a given cluster number for 12-bit FAT
+; On entry AX has cluster number
+; On return AX has FAT entry for that cluster
+GetFatEntry12:
+
+               push  ax
+               mov   cx,ax
+               shr   ax,1
+               add   ax,cx                                             ; AX = AX * 1.5 (AX = AX + (AX / 2)) (since FAT12 entries are 12 bits)
+
+        mov   bx,7000h
+        mov   es,bx
+               mov   bx,ax                                             ; Put FAT entry offset into BX
+               mov   ax,WORD [es:bx]           ; Get FAT entry
+               pop   cx                                                ; Get cluster number from stack
+               and   cx,1
+               jz    UseLow12Bits
+               and   ax,0fff0h
+               shr   ax,4
+               jmp   GetFatEntry12_Done
+
+UseLow12Bits:
+               and   ax,0fffh
+
+GetFatEntry12_Done:
+
+               ret
+
+
+; Reads cluster number in AX into [ES:0000]
+ReadCluster:
+               ; StartSector = ((Cluster - 2) * SectorsPerCluster) + + ReservedSectors + HiddenSectors;
+
+               dec   ax
+               dec   ax
+               xor   dx,dx
+               movzx bx,BYTE [BYTE bp+SectsPerCluster]
+               mul   bx
+               push  ax
+               push  dx
+        ; Now calculate the size of the root directory
+        mov   ax,0020h            ; Size of dir entry
+        mul   WORD [BYTE bp+MaxRootEntries] ; Times the number of entries
+        mov   bx,WORD [BYTE bp+BytesPerSector]
+        add   ax,bx
+        dec   ax
+        div   bx                  ; Divided by the size of a sector
+               mov   cx,ax
+        ; CX now has the number of root directory sectors
+               xor   dx,dx
+               movzx ax,BYTE [BYTE bp+NumberOfFats]
+               mul   WORD [BYTE bp+SectorsPerFat]
+               add   ax,WORD [BYTE bp+ReservedSectors]
+               adc   dx,byte 0
+               add   ax,WORD [BYTE bp+HiddenSectors]
+               adc   dx,WORD [BYTE bp+HiddenSectors+2]
+               add   ax,cx
+               adc   dx,byte 0
+               pop   cx
+               pop   bx
+               add   ax,bx
+               adc   dx,cx
+        xor   bx,bx                            ; We will load it to [ES:0000], ES loaded before function call
+               movzx cx,BYTE [BYTE bp+SectsPerCluster]
+               call  ReadSectors
+               ret
+
+; Returns CF = 1 if this is a FAT12 file system
+; Otherwise CF = 0 for FAT16
+IsFat12:
+
+        ; Now calculate the size of the root directory
+        mov   ax,0020h            ; Size of dir entry
+        mul   WORD [BYTE bp+MaxRootEntries] ; Times the number of entries
+        mov   bx,WORD [BYTE bp+BytesPerSector]
+        add   ax,bx                              ; Plus (BytesPerSector - 1)
+        dec   ax
+        div   bx                  ; Divided by the size of a sector
+        ; AX now has the number of root directory sectors
+
+               mov   bx,ax
+        ; Now we must find our way to the first sector of the root directory
+        xor   ax,ax
+        xor   dx,dx
+        mov   al,BYTE [BYTE bp+NumberOfFats]    ; Number of fats
+        mul   WORD [BYTE bp+SectorsPerFat] ; Times sectors per fat
+        add   ax,WORD [BYTE bp+HiddenSectors] 
+        adc   dx,WORD [BYTE bp+HiddenSectors+2] ; Add the number of hidden sectors 
+        add   ax,[BYTE bp+ReservedSectors]     ; Add the number of reserved sectors
+        adc   dx,byte 0               ; Add carry bit
+               add   ax,bx
+               adc   dx,byte 0                           ; Add carry bit
+        ; DX:AX now has the number of the starting sector of the data area
+
+               xor   cx,cx
+               mov   bx,WORD [BYTE bp+TotalSectors]
+               cmp   bx,byte 0
+               jnz   IsFat12_2
+               mov   bx,WORD [BYTE bp+TotalSectorsBig]
+               mov   cx,WORD [BYTE bp+TotalSectorsBig+2]
+
+               ; CX:BX now contains the number of sectors on the volume
+IsFat12_2:
+               sub   bx,ax                             ; Subtract data area start sector
+               sub   cx,dx                             ; from total sectors of volume
+               mov   ax,bx
+               mov   dx,cx
+
+               ; DX:AX now contains the number of data sectors on the volume
+               movzx bx,BYTE [BYTE bp+SectsPerCluster]
+               div   bx
+               ; AX now has the number of clusters on the volume
+               stc
+               cmp   ax,4085
+               jb    IsFat12_Done
+               clc
+
+IsFat12_Done:
+               ret
+
+
+
+        times 998-($-$$) db 0   ; Pad to 998 bytes
+
+msgLoading   db 'Loading FreeLoader...',0dh,0ah,0
+
+        dw 0aa55h       ; BootSector signature
similarity index 82%
rename from freeldr/bootsect/BTSECT32.ASM
rename to freeldr/bootsect/fat32.asm
index 092769e..cdf935b 100644 (file)
@@ -1,6 +1,6 @@
-; BTSECT32.ASM
+; FAT32.ASM
 ; FAT32 Boot Sector
-; Copyright (c) 1998, 2000 Brian Palmer
+; Copyright (c) 1998, 2000, 2001 Brian Palmer
 
 org 7c00h
 
@@ -12,15 +12,15 @@ start:
         jmp short main
         nop
 
-OEMName                                db 'FreeLDR!'
+OEMName                                db 'FrLdr1.0'
 BytesPerSector         dw 512
 SectsPerCluster                db 1
-ReservedSectors                dw 1
+ReservedSectors                dw 32
 NumberOfFats           db 2
-MaxRootEntries         dw 0                    ;512 - Always zero for FAT32 volumes
-TotalSectors           dw 0                    ;2880 - Always zero for FAT32 volumes
+MaxRootEntries         dw 0                    ; Always zero for FAT32 volumes
+TotalSectors           dw 0                    ; Always zero for FAT32 volumes
 MediaDescriptor                db 0f8h
-SectorsPerFat          dw 0                    ;9 - Always zero for FAT32 volumes
+SectorsPerFat          dw 0                    ; Always zero for FAT32 volumes
 SectorsPerTrack                dw 18
 NumberOfHeads          dw 2
 HiddenSectors          dd 0
@@ -38,7 +38,7 @@ BootDrive                     db 0
 Reserved                       db 0
 ExtendSig                      db 29h
 SerialNumber           dd 00000000h
-VolumeLabel                    db 'FreeLoader!'
+VolumeLabel                    db 'NO NAME    '
 FileSystem                     db 'FAT32   '
 
 main:
@@ -56,12 +56,19 @@ main:
         mov [BootDrive],dl      ; Save the boot drive
         xor ax,ax               ; Zero out AX
 
+        cmp    word [TotalSectors],byte 0x00   ; Check the old 16-bit value of TotalSectors
+        jnz    ErrBoot                                                 ; If it is non-zero then exit with an error
+
+        cmp word [FSVersion],byte 0x00         ; Check the file system version word
+        ja ErrBoot                                                     ; If it is not zero then exit with an error
+
+
         ; Reset disk controller
         int 13h         
-        jnc Continue
+        jnc LoadExtraBootCode
         jmp BadBoot             ; Reset failed...
 
-Continue:
+LoadExtraBootCode:
                ; First we have to load our extra boot code at
                ; sector 14 into memory at [0000:7e00h]
                xor  dx,dx
@@ -73,96 +80,8 @@ Continue:
         mov  es,bx                             ; Read sector to [0000:7e00h]
                xor  bx,bx
                call ReadSectors
-               jnc  Continue1
-               jmp  BadBoot
-
-
-Continue1:
-        ; Now we must get the first cluster of the root directory
-               mov  eax,DWORD [RootDirStartCluster]
-               cmp  eax,0ffffff8h              ; Check to see if this is the last cluster in the chain
-               jb       Continue2                      ; If not continue, if so BadBoot
-               jmp  ErrBoot
-Continue2:
-        mov  bx,800h
-        mov  es,bx                             ; Read cluster to [0000:8000h]
-        call ReadCluster        ; Read the cluster
-
-
-        ; Now we have to find our way through the root directory to
-        ; The OSLOADER.SYS file
-               xor  bx,bx
-        mov  bl,[SectsPerCluster]
-               shl  bx,4                               ; BX = BX * 512 / 32
-        mov  ax,800h            ; We loaded at 0800:0000
-        mov  es,ax
-        xor  di,di
-        mov  si,filename
-        mov  cx,11
-        rep  cmpsb              ; Compare filenames
-        jz   FoundFile          ; If same we found it
-        dec  bx
-        jnz  FindFile
-        jmp  ErrBoot
-
-FindFile:
-        mov  ax,es              ; We didn't find it in the previous dir entry
-        add  ax,2               ; So lets move to the next one
-        mov  es,ax              ; And search again
-        xor  di,di
-        mov  si,filename        
-        mov  cx,11
-        rep  cmpsb              ; Compare filenames
-        jz   FoundFile          ; If same we found it
-        dec  bx                 ; Keep searching till we run out of dir entries
-        jnz  FindFile           ; Last entry?
-
-               ; Get the next root dir cluster and try again until we run out of clusters
-               mov  eax,DWORD [RootDirStartCluster]
-               call GetFatEntry
-               mov  [RootDirStartCluster],eax
-        jmp  Continue1
-
-FoundFile:
-        xor  di,di              ; ES:DI has dir entry
-        xor  dx,dx
-        mov  ax,WORD [es:di+14h]        ; Get start cluster high word
-               shl  eax,16
-        mov  ax,WORD [es:di+1ah]        ; Get start cluster low word
-
-        mov  bx,800h
-        mov  es,bx
-
-FoundFile2:
-               cmp  eax,0ffffff8h              ; Check to see if this is the last cluster in the chain
-               jae      FoundFile3                     ; If so continue, if not then read then next one
-               push eax
-        xor  bx,bx              ; Load ROSLDR starting at 0000:8000h
-               push es
-               call ReadCluster
-               pop  es
-
-               xor  bx,bx
-        mov  bl,[SectsPerCluster]
-               shl  bx,5                               ; BX = BX * 512 / 16
-               mov  ax,es                              ; Increment the load address by
-               add  ax,bx                              ; The size of a cluster
-               mov  es,ax
+               jmp  StartSearch
 
-               pop  eax
-               push es
-               call GetFatEntry                ; Get the next entry
-               pop  es
-
-        jmp  FoundFile2                        ; Load the next cluster (if any)
-
-FoundFile3:
-        mov  dl,[BootDrive]
-        xor  ax,ax
-        push ax
-        mov  ax,8000h
-        push ax                 ; We will do a far return to 0000:8000h
-        retf                    ; Transfer control to ROSLDR
 
 
 
@@ -189,15 +108,17 @@ ReadSectors:
         ror  ah,1                      ; Low 8 bits of cylinder in CH, high 2 bits
         ror  ah,1                      ;  in CL shifted to bits 6 & 7
         or   cl,ah                     ; Or with sector number
-        mov  ax,513
+        mov  ax,0201h
         int  13h     ; DISK - READ SECTORS INTO MEMORY
                      ; AL = number of sectors to read, CH = track, CL = sector
                      ; DH = head, DL    = drive, ES:BX -> buffer to fill
                      ; Return: CF set on error, AH =    status (see AH=01h), AL    = number of sectors read
+
+        jc   BadBoot
+
         pop  cx
         pop  dx
         pop  ax
-        jc   ReadFail
         inc  ax       ;Increment Sector to Read
         jnz  NoCarry
         inc  dx
@@ -206,15 +127,13 @@ ReadSectors:
 NoCarry:
         push bx
         mov  bx,es
-        add  bx,20h
+        add  bx,byte 20h
         mov  es,bx
         pop  bx
                                         ; Increment read buffer for next sector
         loop ReadSectors                ; Read next sector
 
-
-ReadFail:
-        ret
+        ret   
 
 
 
@@ -275,6 +194,99 @@ filename     db 'FREELDR SYS'
 ; Note: Win2k uses sector 12 for this purpose
 
 
+
+StartSearch:
+        ; Now we must get the first cluster of the root directory
+               mov  eax,DWORD [RootDirStartCluster]
+               cmp  eax,0ffffff8h              ; Check to see if this is the last cluster in the chain
+               jb       ContinueSearch         ; If not continue, if so BadBoot
+               jmp  ErrBoot
+ContinueSearch:
+        mov  bx,800h
+        mov  es,bx                             ; Read cluster to [0000:8000h]
+        call ReadCluster        ; Read the cluster
+
+
+        ; Now we have to find our way through the root directory to
+        ; The OSLOADER.SYS file
+               xor  bx,bx
+        mov  bl,[SectsPerCluster]
+               shl  bx,4                               ; BX = BX * 512 / 32
+        mov  ax,800h            ; We loaded at 0800:0000
+        mov  es,ax
+        xor  di,di
+        mov  si,filename
+        mov  cx,11
+        rep  cmpsb              ; Compare filenames
+        jz   FoundFile          ; If same we found it
+        dec  bx
+        jnz  FindFile
+        jmp  ErrBoot
+
+FindFile:
+        mov  ax,es              ; We didn't find it in the previous dir entry
+        add  ax,2               ; So lets move to the next one
+        mov  es,ax              ; And search again
+        xor  di,di
+        mov  si,filename        
+        mov  cx,11
+        rep  cmpsb              ; Compare filenames
+        jz   FoundFile          ; If same we found it
+        dec  bx                 ; Keep searching till we run out of dir entries
+        jnz  FindFile           ; Last entry?
+
+               ; Get the next root dir cluster and try again until we run out of clusters
+               mov  eax,DWORD [RootDirStartCluster]
+               call GetFatEntry
+               mov  [RootDirStartCluster],eax
+        jmp  StartSearch
+
+FoundFile:
+               ; Display "Loading FreeLoader..." message
+        mov  si,msgLoading      ; Loading message
+        call PutChars           ; Display it
+
+        xor  di,di              ; ES:DI has dir entry
+        xor  dx,dx
+        mov  ax,WORD [es:di+14h]        ; Get start cluster high word
+               shl  eax,16
+        mov  ax,WORD [es:di+1ah]        ; Get start cluster low word
+
+        mov  bx,800h
+        mov  es,bx
+
+FoundFile2:
+               cmp  eax,0ffffff8h              ; Check to see if this is the last cluster in the chain
+               jae      FoundFile3                     ; If so continue, if not then read then next one
+               push eax
+        xor  bx,bx              ; Load ROSLDR starting at 0000:8000h
+               push es
+               call ReadCluster
+               pop  es
+
+               xor  bx,bx
+        mov  bl,[SectsPerCluster]
+               shl  bx,5                               ; BX = BX * 512 / 16
+               mov  ax,es                              ; Increment the load address by
+               add  ax,bx                              ; The size of a cluster
+               mov  es,ax
+
+               pop  eax
+               push es
+               call GetFatEntry                ; Get the next entry
+               pop  es
+
+        jmp  FoundFile2                        ; Load the next cluster (if any)
+
+FoundFile3:
+        mov  dl,[BootDrive]
+        xor  ax,ax
+        push ax
+        mov  ax,8000h
+        push ax                 ; We will do a far return to 0000:8000h
+        retf                    ; Transfer control to ROSLDR
+
+
 ; Returns the FAT entry for a given cluster number
 ; On entry EAX has cluster number
 ; On return EAX has FAT entry for that cluster
@@ -288,13 +300,31 @@ GetFatEntry:
                div   ebx                                               ; FAT Sector Number = EAX / BytesPerSector
                movzx ebx,WORD [ReservedSectors]
                add   eax,ebx                                   ; FAT Sector Number += ReservedSectors
-               movzx ebx,WORD [HiddenSectors]
+               mov   ebx,DWORD [HiddenSectors]
                add   eax,ebx                                   ; FAT Sector Number += HiddenSectors
                pop   ebx
                dec   ebx
                and   ecx,ebx                                   ; FAT Offset Within Sector = ECX % BytesPerSector
                ; EAX holds logical FAT sector number
                ; ECX holds FAT entry offset
+
+               ; Now we have to check the extended flags
+               ; to see which FAT is the active one
+               ; and use it, or if they are mirrored then
+               ; no worries
+               movzx ebx,WORD [ExtendedFlags]  ; Get extended flags and put into ebx
+               and   bx,0x0f                                   ; Mask off upper 8 bits
+               jz    GetFatEntry2                              ; If fat is mirrored then skip fat calcs
+               cmp   bl,[NumberOfFats]                 ; Compare bl to number of fats
+               jc    GetFatEntry1
+               jmp   ErrBoot                                   ; If bl is bigger than numfats exit with error
+GetFatEntry1:
+               mov   edx,eax                                   ; Put logical FAT sector number in edx
+               mov   eax,[SectorsPerFatBig]    ; Get the number of sectors occupied by one fat in eax
+               mul   ebx                                               ; Multiplied by the active FAT index we have in ebx
+               add   eax,edx                                   ; Add the current FAT sector offset
+
+GetFatEntry2:
                push  ecx
                ror   eax,16
                mov   dx,ax
@@ -305,9 +335,9 @@ GetFatEntry:
         xor  bx,bx              ; We will load it to [7000:0000h]
                mov  cx,1
                call ReadSectors
-               jnc  GetFatEntry1
+               jnc  GetFatEntry3
                jmp  BadBoot
-GetFatEntry1:
+GetFatEntry3:
         mov  bx,7000h
         mov  es,bx
                pop  ecx
@@ -341,11 +371,10 @@ ReadCluster:
         xor   bx,bx                            ; We will load it to [ES:0000], ES loaded before function call
                movzx cx,BYTE [SectsPerCluster]
                call  ReadSectors
-               jnc   ReadCluster1
-               jmp   BadBoot
-
-ReadCluster1:
                ret
 
-        times 1022-($-$$) db 0   ; Pad to 1022 bytes
+        times 998-($-$$) db 0   ; Pad to 998 bytes
+
+msgLoading   db 'Loading FreeLoader...',0dh,0ah,0
+
         dw 0aa55h       ; BootSector signature
diff --git a/freeldr/bootsect/install.bat b/freeldr/bootsect/install.bat
deleted file mode 100644 (file)
index 32e2f3c..0000000
+++ /dev/null
@@ -1 +0,0 @@
-debug bootsect.bin < install.src
diff --git a/freeldr/bootsect/install.src b/freeldr/bootsect/install.src
deleted file mode 100644 (file)
index 8667502..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-w 100 0 0 1
-q
diff --git a/freeldr/bootsect/split.c b/freeldr/bootsect/split.c
new file mode 100644 (file)
index 0000000..2a170ec
--- /dev/null
@@ -0,0 +1,55 @@
+#include <stdio.h>
+
+FILE   *in;
+FILE   *out;
+FILE   *new;
+
+int main(int argc, char *argv[])
+{
+       unsigned char   ch;
+       int                             cnt;
+       int                             split_offset;
+
+       if (argc < 5)
+       {
+               printf("usage: split infile.bin outfile.bin newfile.bin split_offset\n");
+               return -1;
+       }
+
+       if ((in = fopen(argv[1], "rb")) == NULL)
+       {
+               printf("Couldn't open data file.\n");
+               return -1;
+       }
+       if ((out = fopen(argv[2], "wb")) == NULL)
+       {
+               printf("Couldn't open output file.\n");
+               return -1;
+       }
+       if ((new = fopen(argv[3], "wb")) == NULL)
+       {
+               printf("Couldn't open new file.\n");
+               return -1;
+       }
+
+       split_offset = atoi(argv[4]);
+
+       for (cnt=0; cnt<split_offset; cnt++)
+       {
+               ch = fgetc(in);
+               fputc(ch, out);
+       }
+
+       ch = fgetc(in);
+       while (!feof(in))
+       {
+               fputc(ch, new);
+               ch = fgetc(in);
+       }
+
+       fclose(in);
+       fclose(out);
+       fclose(new);
+
+       return 0;
+}
\ No newline at end of file
diff --git a/freeldr/bootsect/stubit.c b/freeldr/bootsect/stubit.c
new file mode 100644 (file)
index 0000000..e5380fc
--- /dev/null
@@ -0,0 +1,52 @@
+#include <stdio.h>
+
+FILE   *in;
+FILE   *in2;
+FILE   *out;
+
+int main(int argc, char *argv[])
+{
+       unsigned char   ch;
+
+       if (argc < 4)
+       {
+               printf("usage: stubit infile1.bin infile2.sys outfile.bin\n");
+               return -1;
+       }
+
+       if ((in = fopen(argv[1], "rb")) == NULL)
+       {
+               printf("Couldn't open data file.\n");
+               return -1;
+       }
+       if ((in2 = fopen(argv[2], "rb")) == NULL)
+       {
+               printf("Couldn't open data file.\n");
+               return -1;
+       }
+       if ((out = fopen(argv[3], "wb")) == NULL)
+       {
+               printf("Couldn't open output file.\n");
+               return -1;
+       }
+
+       ch = fgetc(in);
+       while (!feof(in))
+       {
+               fputc(ch, out);
+               ch = fgetc(in);
+       }
+
+       ch = fgetc(in2);
+       while (!feof(in2))
+       {
+               fputc(ch, out);
+               ch = fgetc(in2);
+       }
+
+       fclose(in);
+       fclose(in2);
+       fclose(out);
+
+       return 0;
+}
\ No newline at end of file
index 6a2798c..8b66697 100644 (file)
@@ -27,7 +27,7 @@ start:
         jmp short main
         nop
 
-OEMName                                db 'FreeLDR!'
+OEMName                                db 'MSWIN4.0'
 BytesPerSector         dw 512
 SectsPerCluster                db 1
 ReservedSectors                dw 1
@@ -53,8 +53,8 @@ BootDrive                     db 0
 Reserved                       db 0
 ExtendSig                      db 29h
 SerialNumber           dd 00000000h
-VolumeLabel                    db 'FreeLoader!'
-FileSystem                     db 'FAT12   '
+VolumeLabel                    db 'NO NAME    '
+FileSystem                     db 'FAT32   '
 
 main:
 00007C5A  33C9              xor                cx,cx
@@ -349,8 +349,8 @@ load_fat_sector:
 00008112  660FB74E0E        movzx ecx,word [bp+ReservedSectors]        ; Add the reserved sectors
 00008117  6603C1            add eax,ecx                                                        ; To the hidden sectors + the value we computed earlier
 0000811A  660FB75E28        movzx ebx,word [bp+ExtendedFlags]  ; Get extended flags and put into ebx
-0000811F  83E30F            and bx,byte +0xf                                   ; Mask off everything but the active fat bits
-00008122  7416              jz load_fat_sector_into_memory             ; If active fat is first fat skip fat size calcs
+0000811F  83E30F            and bx,byte +0xf                                   ; Mask off upper 8 bits
+00008122  7416              jz load_fat_sector_into_memory             ; If fat is mirrored then skip fat calcs
 00008124  3A5E10            cmp bl,[bp+NumberOfFats]                   ; Compare bl to number of fats
 00008127  0F83ABFB          jnc near print_ntldr_error_message ; If bl is bigger than numfats exit with error
 0000812B  52                push dx                                                            ; Save dx
index 06f16e8..4d1ff17 100644 (file)
@@ -1,6 +1,6 @@
 #
 #  FreeLoader
-#  Copyright (C) 1999, 2000  Brian Palmer  <brianp@sginet.com>
+#  Copyright (C) 1999, 2000, 2001  Brian Palmer  <brianp@sginet.com>
 #
 #  This program is free software; you can redistribute it and/or modify
 #  it under the terms of the GNU General Public License as published by
@@ -25,15 +25,17 @@ export RM = cmd /C del
 export CP = cmd /C copy
 
 #FLAGS = -Wall -nostdinc -fno-builtin
-FLAGS = -Wall -fno-builtin
+FLAGS = -Wall -fno-builtin -DDEBUG
 
 # asmcode.o has to be first in the link line because it contains the startup code
 OBJS = asmcode.a asmcode.o mb.o boot.o freeldr.o stdlib.o fs.a fs.o fs_fat.o \
        reactos.o tui.o menu.o miscboot.o options.o linux.o multiboot.o arcname.o \
-       mem.o memory.o
+       mem.o memory.o debug.o parseini.o
 ASM_OBJS = asmcode.o mb.o boot.o mem.o
 C_OBJS = freeldr.o stdlib.o fs.a reactos.o tui.o menu.o miscboot.o options.o linux.o \
-       multiboot.o arcname.o memory.o
+       multiboot.o arcname.o memory.o debug.o parseini.o
+
+.PHONY : clean
 
 all:   freeldr.sys
 
@@ -97,9 +99,15 @@ arcname.o:   arcname.c freeldr.h arcname.h stdlib.h Makefile
 mem.o: mem.S asmcode.h Makefile
        $(CC) $(FLAGS) -o mem.o -c mem.S
 
-memory.o:      memory.c asmcode.h memory.h Makefile
+memory.o:      memory.c memory.h Makefile
        $(CC) $(FLAGS) -o memory.o -c memory.c
 
+debug.o:       debug.c debug.h Makefile
+       $(CC) $(FLAGS) -o debug.o -c debug.c
+
+parseini.o:    parseini.c parseini.h Makefile
+       $(CC) $(FLAGS) -o parseini.o -c parseini.c
+
 clean:
        $(RM) *.o
        $(RM) *.a
index be974ff..8860601 100644 (file)
@@ -24,7 +24,7 @@
 #include "stdlib.h"
 
 
-BOOL DissectArcPath(char *ArcPath, char *BootPath, unsigned int *BootDrive, unsigned int *BootPartition)
+BOOL DissectArcPath(char *ArcPath, char *BootPath, PULONG BootDrive, PULONG BootPartition)
 {
        char *p;
 
index ae68b99..09dc3da 100644 (file)
@@ -22,8 +22,8 @@
 #ifndef __ARCNAME_H
 #define __ARCNAME_H
 
-BOOL   DissectArcPath(char *ArcPath, char *BootPath, unsigned int *BootDrive, unsigned int *BootPartition);
-//BOOL ConvertBiosDriveToArcName()
-//BOOL ConvertArcNameToBiosDrive()
+BOOL   DissectArcPath(char *ArcPath, char *BootPath, PULONG BootDrive, PULONG BootPartition);
+//BOOL ConvertBiosDriveToArcName(PUCHAR ArcName, ULONG BiosDriveNumber);
+//ULONG        ConvertArcNameToBiosDrive(PUCHAR ArcName);
 
 #endif // defined __ARCNAME_H
\ No newline at end of file
diff --git a/freeldr/freeldr/debug.c b/freeldr/freeldr/debug.c
new file mode 100644 (file)
index 0000000..699bfbf
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ *  FreeLoader
+ *  Copyright (C) 2001  Brian Palmer  <brianp@sginet.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "freeldr.h"
+#include "debug.h"
+#include "stdlib.h"
+
+ULONG  DebugPrintMask = DPRINT_WARNING | DPRINT_MEMORY;
+
+void DebugPrint(ULONG Mask, char *format, ...)
+{
+       int *dataptr = (int *) &format;
+       char c, *ptr, str[16];
+       char buffer[512];
+       char *p = buffer;
+       
+       // Mask out unwanted debug messages
+       if (!(Mask & DebugPrintMask))
+       {
+               return;
+       }
+
+       dataptr++;
+
+       while ((c = *(format++)))
+       {
+         if (c != '%')
+         {
+       *p = c;
+       p++;
+         }
+         else
+       switch (c = *(format++))
+         {
+         case 'd': case 'u': case 'x':
+               *convert_to_ascii(str, c, *((unsigned long *) dataptr++)) = 0;
+
+               ptr = str;
+
+               while (*ptr)
+               {
+                 *p = *(ptr++);
+                 p++;
+               }
+               break;
+
+         case 'c':
+               *p = (*(dataptr++))&0xff;
+               p++;
+               break;
+
+         case 's':
+               ptr = (char *)(*(dataptr++));
+
+               while ((c = *(ptr++)))
+               {
+                 *p = c;
+                 p++;
+               }
+               break;
+         }
+       }
+       *p=0;
+
+
+       print(buffer);
+}
diff --git a/freeldr/freeldr/debug.h b/freeldr/freeldr/debug.h
new file mode 100644 (file)
index 0000000..8ac0da9
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ *  FreeLoader
+ *  Copyright (C) 2001  Brian Palmer  <brianp@sginet.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#ifndef __DEBUG_H
+#define __DEBUG_H
+
+#define DPRINT_WARNING         0x00000001              // OR this with DebugPrintMask to enable debugger messages and other misc stuff
+#define DPRINT_MEMORY          0x00000002              // OR this with DebugPrintMask to enable memory management messages
+
+void   DebugPrint(ULONG Mask, char *format, ...);
+
+#define BugCheck0(format) \
+                       { \
+                               DebugPrint(DPRINT_WARNING, "Fatal Error: %s:%d\n", __FILE__, __LINE__); \
+                               DebugPrint(DPRINT_WARNING, format); \
+                               for (;;); \
+                       }
+
+#define BugCheck1(format, arg1) \
+                       { \
+                               DebugPrint(DPRINT_WARNING, "Fatal Error: %s:%d\n", __FILE__, __LINE__); \
+                               DebugPrint(DPRINT_WARNING, format, arg1); \
+                               for (;;); \
+                       }
+
+#define BugCheck2(format, arg1, arg2) \
+                       { \
+                               DebugPrint(DPRINT_WARNING, "Fatal Error: %s:%d\n", __FILE__, __LINE__); \
+                               DebugPrint(DPRINT_WARNING, format, arg1, arg2); \
+                               for (;;); \
+                       }
+
+#define BugCheck3(format, arg1, arg2, arg3) \
+                       { \
+                               DebugPrint(DPRINT_WARNING, "Fatal Error: %s:%d\n", __FILE__, __LINE__); \
+                               DebugPrint(DPRINT_WARNING, format, arg1, arg2, arg3); \
+                               for (;;); \
+                       }
+
+#endif // defined __DEBUG_H
\ No newline at end of file
index f286b22..52db113 100644 (file)
 #include "menu.h"
 #include "miscboot.h"
 #include "linux.h"
+#include "memory.h"
+#include "parseini.h"
 
 // Variable BootDrive moved to asmcode.S
-//unsigned int BootDrive = 0;          // BIOS boot drive, 0-A:, 1-B:, 0x80-C:, 0x81-D:, etc.
-unsigned int   BootPartition = 0;      // Boot Partition, 1-4
-BOOL                   bTUILoaded = FALSE; // Tells us if the user interface is loaded
+//ULONG                        BootDrive = 0;          // BIOS boot drive, 0-A:, 1-B:, 0x80-C:, 0x81-D:, etc.
+ULONG                  BootPartition = 0;      // Boot Partition, 1-4
+BOOL                   UserInterfaceUp = FALSE; // Tells us if the user interface is displayed
 
-char                   *pFreeldrIni = (char *)(FREELDRINIADDR); // Load address for freeldr.ini
-char                   *pScreenBuffer = (char *)(SCREENBUFFER); // Save address for screen contents
-int                            nCursorXPos = 0;        // Cursor's X Position
-int                            nCursorYPos = 0;        // Cursor's Y Position
+PUCHAR                 ScreenBuffer = (PUCHAR)(SCREENBUFFER); // Save buffer for screen contents
+int                            CursorXPos = 0; // Cursor's X Position
+int                            CursorYPos = 0; // Cursor's Y Position
 
 OSTYPE                 OSList[16];
 int                            nNumOS = 0;
@@ -51,12 +52,14 @@ void BootMain(void)
 
        enable_a20();
 
-       SaveScreen(pScreenBuffer);
-       nCursorXPos = wherex();
-       nCursorYPos = wherey();
+       SaveScreen(ScreenBuffer);
+       CursorXPos = wherex();
+       CursorYPos = wherey();
 
        printf("Loading FreeLoader...\n");
 
+       InitMemoryManager((PVOID)0x100000, 0x20000);
+
        if (!ParseIniFile())
        {
                printf("Press any key to reboot.\n");
@@ -68,15 +71,15 @@ void BootMain(void)
        hidecursor();
        // Draw the backdrop and title box
        DrawBackdrop();
-       bTUILoaded = TRUE;
+       UserInterfaceUp = TRUE;
 
        if (nNumOS == 0)
        {
                DrawStatusText(" Press ENTER to reboot");
-               MessageBox("Error: there were no operating systems listed to boot.\nPress ENTER to reboot.");
+               MessageBox("Error: there were no operating systems listed in freeldr.ini.\nPress ENTER to reboot.");
                clrscr();
                showcursor();
-               RestoreScreen(pScreenBuffer);
+               RestoreScreen(ScreenBuffer);
                return;
        }
        
@@ -119,617 +122,7 @@ void BootMain(void)
        }
 
        MessageBox("Press any key to reboot.");
-       RestoreScreen(pScreenBuffer);
+       RestoreScreen(ScreenBuffer);
        showcursor();
-       gotoxy(nCursorXPos, nCursorYPos);
-}
-
-BOOL ParseIniFile(void)
-{
-       int             i;
-       char    name[1024];
-       char    value[1024];
-       FILE    Freeldr_Ini;    // File handle for freeldr.ini
-
-       // Open the boot drive for file access
-       if(!OpenDiskDrive(BootDrive, 0))
-       {
-               printf("Error opening boot drive for file access.\n");
-               return FALSE;
-       }
-
-       // Try to open freeldr.ini or fail
-       if(!OpenFile("freeldr.ini", &Freeldr_Ini))
-       {
-               printf("FREELDR.INI not found.\nYou need to re-install FreeLoader.\n");
-               return FALSE;
-       }
-
-       // Check and see if freeldr.ini is too big
-       // if so display a warning
-       if(GetFileSize(&Freeldr_Ini) > 0x4000)
-       {
-               printf("Warning: FREELDR.INI is bigger than 16k.\n");
-               printf("Only 16k of it will be loaded off the disk.\n");
-               printf("Press any key to continue.\n");
-               getch();
-       }
-
-       // Read freeldr.ini off the disk
-       ReadFile(&Freeldr_Ini, 0x4000, pFreeldrIni);
-
-       // Make sure the [FREELOADER] section exists
-       if(!GetNumSectionItems("FREELOADER"))
-       {
-               printf("Section [FREELOADER] not found in FREELDR.INI.\nYou need to re-install FreeLoader.\n");
-               return FALSE;
-       }
-
-       // Validate the settings in the [FREELOADER] section
-       for(i=1; i<=GetNumSectionItems("FREELOADER"); i++)
-       {
-               ReadSectionSettingByNumber("FREELOADER", i, name, value);
-               if(!IsValidSetting(name, value))
-               {
-                       printf("Invalid setting in freeldr.ini.\nName: \"%s\", Value: \"%s\"\n", name, value);
-                       printf("Press any key to continue.\n");
-                       getch();
-               }
-               else
-                       SetSetting(name, value);
-       }
-
-       return TRUE;
-}
-
-int GetNumSectionItems(char *section)
-{
-       int             i;
-       char    str[1024];
-       char    real_section[1024];
-       int             num_items = 0;
-       int             freeldr_ini_offset;
-       BOOL    bFoundSection = FALSE;
-
-       // Get the real section name
-       strcpy(real_section, "[");
-       strcat(real_section, section);
-       strcat(real_section, "]");
-
-       // Get to the beginning of the file
-       freeldr_ini_offset = 0;
-
-       // Find the section
-       while(freeldr_ini_offset < 0x4000)
-       {
-               // Read a line 
-               for(i=0; i<1024; i++,freeldr_ini_offset++)
-               {
-                       if((freeldr_ini_offset < 0x4000) && (pFreeldrIni[freeldr_ini_offset] != '\n'))
-                               str[i] = pFreeldrIni[freeldr_ini_offset];
-                       else
-                       {
-                               freeldr_ini_offset++;
-                               break;
-                       }
-               }
-               str[i] = '\0';
-               //fgets(str, 1024, &Freeldr_Ini);
-
-               // Get rid of newline & linefeed characters (if any)
-               if((str[strlen(str)-1] == '\n') || (str[strlen(str)-1] == '\r'))
-                       str[strlen(str)-1] = '\0';
-               if((str[strlen(str)-1] == '\n') || (str[strlen(str)-1] == '\r'))
-                       str[strlen(str)-1] = '\0';
-
-               // Skip comments
-               if(str[0] == '#')
-                       continue;
-
-               // Skip blank lines
-               if(!strlen(str))
-                       continue;
-
-               // If it isn't a section header then continue on
-               if(str[0] != '[')
-                       continue;
-
-               // Check and see if we found it
-               if(stricmp(str, real_section) == 0)
-               {
-                       bFoundSection = TRUE;
-                       break;
-               }
-       }
-
-       // If we didn't find the section then we're outta here
-       if(!bFoundSection)
-               return 0;
-
-       // Now count how many settings are in this section
-       while(freeldr_ini_offset < 0x4000)
-       {
-               // Read a line 
-               for(i=0; i<1024; i++,freeldr_ini_offset++)
-               {
-                       if((freeldr_ini_offset < 0x4000) && (pFreeldrIni[freeldr_ini_offset] != '\n'))
-                               str[i] = pFreeldrIni[freeldr_ini_offset];
-                       else
-                       {
-                               freeldr_ini_offset++;
-                               break;
-                       }
-               }
-               str[i] = '\0';
-               //fgets(str, 1024, &Freeldr_Ini);
-
-               // Get rid of newline & linefeed characters (if any)
-               if((str[strlen(str)-1] == '\n') || (str[strlen(str)-1] == '\r'))
-                       str[strlen(str)-1] = '\0';
-               if((str[strlen(str)-1] == '\n') || (str[strlen(str)-1] == '\r'))
-                       str[strlen(str)-1] = '\0';
-
-               // Skip comments
-               if(str[0] == '#')
-                       continue;
-
-               // Skip blank lines
-               if(!strlen(str))
-                       continue;
-
-               // If we hit a new section then we're done
-               if(str[0] == '[')
-                       break;
-
-               num_items++;
-       }
-
-       return num_items;
-}
-
-BOOL ReadSectionSettingByNumber(char *section, int num, char *name, char *value)
-{
-       char    str[1024];
-       char    real_section[1024];
-       int             num_items = 0;
-       int             i;
-       int             freeldr_ini_offset;
-       BOOL    bFoundSection = FALSE;
-
-       // Get the real section name
-       strcpy(real_section, "[");
-       strcat(real_section, section);
-       strcat(real_section, "]");
-
-       // Get to the beginning of the file
-       freeldr_ini_offset = 0;
-
-       // Find the section
-       while(freeldr_ini_offset < 0x4000)
-       {
-               // Read a line 
-               for(i=0; i<1024; i++,freeldr_ini_offset++)
-               {
-                       if((freeldr_ini_offset < 0x4000) && (pFreeldrIni[freeldr_ini_offset] != '\n'))
-                               str[i] = pFreeldrIni[freeldr_ini_offset];
-                       else
-                       {
-                               freeldr_ini_offset++;
-                               break;
-                       }
-               }
-               str[i] = '\0';
-               //fgets(str, 1024, &Freeldr_Ini);
-
-               // Get rid of newline & linefeed characters (if any)
-               if((str[strlen(str)-1] == '\n') || (str[strlen(str)-1] == '\r'))
-                       str[strlen(str)-1] = '\0';
-               if((str[strlen(str)-1] == '\n') || (str[strlen(str)-1] == '\r'))
-                       str[strlen(str)-1] = '\0';
-
-               // Skip comments
-               if(str[0] == '#')
-                       continue;
-
-               // Skip blank lines
-               if(!strlen(str))
-                       continue;
-
-               // If it isn't a section header then continue on
-               if(str[0] != '[')
-                       continue;
-
-               // Check and see if we found it
-               if(stricmp(str, real_section) == 0)
-               {
-                       bFoundSection = TRUE;
-                       break;
-               }
-       }
-
-       // If we didn't find the section then we're outta here
-       if(!bFoundSection)
-               return FALSE;
-
-       // Now find the setting we are looking for
-       while(freeldr_ini_offset < 0x4000)
-       {
-               // Read a line 
-               for(i=0; i<1024; i++,freeldr_ini_offset++)
-               {
-                       if((freeldr_ini_offset < 0x4000) && (pFreeldrIni[freeldr_ini_offset] != '\n'))
-                               str[i] = pFreeldrIni[freeldr_ini_offset];
-                       else
-                       {
-                               freeldr_ini_offset++;
-                               break;
-                       }
-               }
-               str[i] = '\0';
-               //fgets(str, 1024, &Freeldr_Ini);
-
-               // Get rid of newline & linefeed characters (if any)
-               if((str[strlen(str)-1] == '\n') || (str[strlen(str)-1] == '\r'))
-                       str[strlen(str)-1] = '\0';
-               if((str[strlen(str)-1] == '\n') || (str[strlen(str)-1] == '\r'))
-                       str[strlen(str)-1] = '\0';
-
-               // Skip comments
-               if(str[0] == '#')
-                       continue;
-
-               // Skip blank lines
-               if(!strlen(str))
-                       continue;
-
-               // If we hit a new section then we're done
-               if(str[0] == '[')
-                       break;
-
-               // Increment setting number
-               num_items++;
-
-               // Check and see if we found the setting
-               if(num_items == num)
-               {
-                       for(i=0; i<strlen(str); i++)
-                       {
-                               // Check and see if this character is the separator
-                               if(str[i] == '=')
-                               {
-                                       name[i] = '\0';
-
-                                       strcpy(value, str+i+1);
-
-                                       return TRUE;
-                               }
-                               else
-                                       name[i] = str[i];
-                       }
-               }
-       }
-
-       return FALSE;
-}
-
-BOOL ReadSectionSettingByName(char *section, char *valuename, char *name, char *value)
-{
-       char    str[1024];
-       char    real_section[1024];
-       char    temp[1024];
-       int             i;
-       int             freeldr_ini_offset;
-       BOOL    bFoundSection = FALSE;
-
-       // Get the real section name
-       strcpy(real_section, "[");
-       strcat(real_section, section);
-       strcat(real_section, "]");
-
-       // Get to the beginning of the file
-       freeldr_ini_offset = 0;
-
-       // Find the section
-       while(freeldr_ini_offset < 0x4000)
-       {
-               // Read a line 
-               for(i=0; i<1024; i++,freeldr_ini_offset++)
-               {
-                       if((freeldr_ini_offset < 0x4000) && (pFreeldrIni[freeldr_ini_offset] != '\n'))
-                               str[i] = pFreeldrIni[freeldr_ini_offset];
-                       else
-                       {
-                               freeldr_ini_offset++;
-                               break;
-                       }
-               }
-               str[i] = '\0';
-               //fgets(str, 1024, &Freeldr_Ini);
-
-               // Get rid of newline & linefeed characters (if any)
-               if((str[strlen(str)-1] == '\n') || (str[strlen(str)-1] == '\r'))
-                       str[strlen(str)-1] = '\0';
-               if((str[strlen(str)-1] == '\n') || (str[strlen(str)-1] == '\r'))
-                       str[strlen(str)-1] = '\0';
-
-               // Skip comments
-               if(str[0] == '#')
-                       continue;
-
-               // Skip blank lines
-               if(!strlen(str))
-                       continue;
-
-               // If it isn't a section header then continue on
-               if(str[0] != '[')
-                       continue;
-
-               // Check and see if we found it
-               if(stricmp(str, real_section) == 0)
-               {
-                       bFoundSection = TRUE;
-                       break;
-               }
-       }
-
-       // If we didn't find the section then we're outta here
-       if(!bFoundSection)
-               return FALSE;
-
-       // Now find the setting we are looking for
-       while(freeldr_ini_offset < 0x4000)
-       {
-               // Read a line 
-               for(i=0; i<1024; i++,freeldr_ini_offset++)
-               {
-                       if((freeldr_ini_offset < 0x4000) && (pFreeldrIni[freeldr_ini_offset] != '\n'))
-                               str[i] = pFreeldrIni[freeldr_ini_offset];
-                       else
-                       {
-                               freeldr_ini_offset++;
-                               break;
-                       }
-               }
-               str[i] = '\0';
-               //fgets(str, 1024, &Freeldr_Ini);
-
-               // Get rid of newline & linefeed characters (if any)
-               if((str[strlen(str)-1] == '\n') || (str[strlen(str)-1] == '\r'))
-                       str[strlen(str)-1] = '\0';
-               if((str[strlen(str)-1] == '\n') || (str[strlen(str)-1] == '\r'))
-                       str[strlen(str)-1] = '\0';
-
-               // Skip comments
-               if(str[0] == '#')
-                       continue;
-
-               // Skip blank lines
-               if(!strlen(str))
-                       continue;
-
-               // If we hit a new section then we're done
-               if(str[0] == '[')
-                       break;
-
-               // Extract the setting name
-               for(i=0; i<strlen(str); i++)
-               {
-                       if(str[i] != '=')
-                               temp[i] = str[i];
-                       else
-                       {
-                               temp[i] = '\0';
-                               break;
-                       }
-               }
-
-               // Check and see if we found the setting
-               if(stricmp(temp, valuename) == 0)
-               {
-                       for(i=0; i<strlen(str); i++)
-                       {
-                               // Check and see if this character is the separator
-                               if(str[i] == '=')
-                               {
-                                       name[i] = '\0';
-
-                                       strcpy(value, str+i+1);
-
-                                       return TRUE;
-                               }
-                               else
-                                       name[i] = str[i];
-                       }
-               }
-       }
-
-       return FALSE;
-}
-
-BOOL IsValidSetting(char *setting, char *value)
-{
-       if(stricmp(setting, "MessageBox") == 0)
-               return TRUE;
-       else if(stricmp(setting, "MessageLine") == 0)
-               return TRUE;
-       else if(stricmp(setting, "TitleText") == 0)
-               return TRUE;
-       else if(stricmp(setting, "StatusBarColor") == 0)
-       {
-               if(IsValidColor(value))
-                       return TRUE;
-       }
-       else if(stricmp(setting, "StatusBarTextColor") == 0)
-       {
-               if(IsValidColor(value))
-                       return TRUE;
-       }
-       else if(stricmp(setting, "BackdropTextColor") == 0)
-       {
-               if(IsValidColor(value))
-                       return TRUE;
-       }
-       else if(stricmp(setting, "BackdropColor") == 0)
-       {
-               if(IsValidColor(value))
-                       return TRUE;
-       }
-       else if(stricmp(setting, "BackdropFillStyle") == 0)
-       {
-               if(IsValidFillStyle(value))
-                       return TRUE;
-       }
-       else if(stricmp(setting, "TitleBoxTextColor") == 0)
-       {
-               if(IsValidColor(value))
-                       return TRUE;
-       }
-       else if(stricmp(setting, "TitleBoxColor") == 0)
-       {
-               if(IsValidColor(value))
-                       return TRUE;
-       }
-       else if(stricmp(setting, "MessageBoxTextColor") == 0)
-       {
-               if(IsValidColor(value))
-                       return TRUE;
-       }
-       else if(stricmp(setting, "MessageBoxColor") == 0)
-       {
-               if(IsValidColor(value))
-                       return TRUE;
-       }
-       else if(stricmp(setting, "MenuTextColor") == 0)
-       {
-               if(IsValidColor(value))
-                       return TRUE;
-       }
-       else if(stricmp(setting, "MenuColor") == 0)
-       {
-               if(IsValidColor(value))
-                       return TRUE;
-       }
-       else if(stricmp(setting, "TextColor") == 0)
-       {
-               if(IsValidColor(value))
-                       return TRUE;
-       }
-       else if(stricmp(setting, "SelectedTextColor") == 0)
-       {
-               if(IsValidColor(value))
-                       return TRUE;
-       }
-       else if(stricmp(setting, "SelectedColor") == 0)
-       {
-               if(IsValidColor(value))
-                       return TRUE;
-       }
-       else if(stricmp(setting, "OS") == 0)
-               return TRUE;
-       else if(stricmp(setting, "TimeOut") == 0)
-               return TRUE;
-       /*else if(stricmp(setting, "") == 0)
-               return TRUE;
-       else if(stricmp(setting, "") == 0)
-               return TRUE;
-       else if(stricmp(setting, "") == 0)
-               return TRUE;
-       else if(stricmp(setting, "") == 0)
-               return TRUE;
-       else if(stricmp(setting, "") == 0)
-               return TRUE;
-       else if(stricmp(setting, "") == 0)
-               return TRUE;
-       else if(stricmp(setting, "") == 0)
-               return TRUE;*/
-
-       return FALSE;
-}
-
-void SetSetting(char *setting, char *value)
-{
-       char    name[260];
-       char    v[260];
-
-       if(stricmp(setting, "TitleText") == 0)
-               strcpy(szTitleBoxTitleText, value);
-       else if(stricmp(setting, "StatusBarColor") == 0)
-               cStatusBarBgColor = TextToColor(value);
-       else if(stricmp(setting, "StatusBarTextColor") == 0)
-               cStatusBarFgColor = TextToColor(value);
-       else if(stricmp(setting, "BackdropTextColor") == 0)
-               cBackdropFgColor = TextToColor(value);
-       else if(stricmp(setting, "BackdropColor") == 0)
-               cBackdropBgColor = TextToColor(value);
-       else if(stricmp(setting, "BackdropFillStyle") == 0)
-               cBackdropFillStyle = TextToFillStyle(value);
-       else if(stricmp(setting, "TitleBoxTextColor") == 0)
-               cTitleBoxFgColor = TextToColor(value);
-       else if(stricmp(setting, "TitleBoxColor") == 0)
-               cTitleBoxBgColor = TextToColor(value);
-       else if(stricmp(setting, "MessageBoxTextColor") == 0)
-               cMessageBoxFgColor = TextToColor(value);
-       else if(stricmp(setting, "MessageBoxColor") == 0)
-               cMessageBoxBgColor = TextToColor(value);
-       else if(stricmp(setting, "MenuTextColor") == 0)
-               cMenuFgColor = TextToColor(value);
-       else if(stricmp(setting, "MenuColor") == 0)
-               cMenuBgColor = TextToColor(value);
-       else if(stricmp(setting, "TextColor") == 0)
-               cTextColor = TextToColor(value);
-       else if(stricmp(setting, "SelectedTextColor") == 0)
-               cSelectedTextColor = TextToColor(value);
-       else if(stricmp(setting, "SelectedColor") == 0)
-               cSelectedTextBgColor = TextToColor(value);
-       else if(stricmp(setting, "OS") == 0)
-       {
-               if(nNumOS >= 16)
-               {
-                       printf("Error: you can only boot to at most 16 different operating systems.\n");
-                       printf("Press any key to continue\n");
-                       getch();
-                       return;
-               }
-
-               if(!GetNumSectionItems(value))
-               {
-                       printf("Error: OS \"%s\" listed.\n", value);
-                       printf("It does not have it's own [section], or it is empty.\n");
-                       printf("Press any key to continue\n");
-                       getch();
-                       return;
-               }
-
-               strcpy(OSList[nNumOS].name, value);
-
-               if (!ReadSectionSettingByName(value, "BootType", name, v))
-               {
-                       printf("Unknown BootType for OS \"%s\"\n", value);
-                       printf("Press any key to continue\n");
-                       getch();
-                       return;
-               }
-
-               if (stricmp(v, "ReactOS") == 0)
-                       OSList[nNumOS].nOSType = OSTYPE_REACTOS;
-               else if (stricmp(v, "Linux") == 0)
-                       OSList[nNumOS].nOSType = OSTYPE_LINUX;
-               else if (stricmp(v, "BootSector") == 0)
-                       OSList[nNumOS].nOSType = OSTYPE_BOOTSECTOR;
-               else if (stricmp(v, "Partition") == 0)
-                       OSList[nNumOS].nOSType = OSTYPE_PARTITION;
-               else if (stricmp(v, "Drive") == 0)
-                       OSList[nNumOS].nOSType = OSTYPE_DRIVE;
-               else
-               {
-                       printf("Unknown BootType for OS \"%s\"\n", value);
-                       printf("Press any key to continue\n");
-                       getch();
-                       return;
-               }
-
-               nNumOS++;
-       }
-       else if(stricmp(setting, "TimeOut") == 0)
-               nTimeOut = atoi(value);
+       gotoxy(CursorXPos, CursorYPos);
 }
index d8e3fd1..b290d82 100644 (file)
 #define WORD   unsigned short
 #define DWORD  unsigned long
 #define CHAR   char
+#define PCHAR  char *
+#define UCHAR  unsigned char
+#define PUCHAR unsigned char *
 #define WCHAR  unsigned short
+#define PWCHAR unsigned short *
 #define LONG   long
 #define ULONG  unsigned long
 #define PULONG unsigned long *
 #define PDWORD DWORD *
 #define PWORD  WORD *
+#define VOID   void
+#define PVOID  VOID*
+
+#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
 
 #define        OSTYPE_REACTOS          1
 #define OSTYPE_LINUX           2
@@ -55,16 +63,15 @@ typedef struct
 {
        char    name[260];
        int             nOSType;                        // ReactOS or Linux or a bootsector, etc.
-} OSTYPE;
+} OSTYPE, *POSTYPE;
 
-extern unsigned int    BootDrive; // BIOS boot drive, 0-A:, 1-B:, 0x80-C:, 0x81-D:, etc.
-extern unsigned int    BootPartition;  // Boot Partition, 1-4
-extern BOOL                    bTUILoaded; // Tells us if the user interface is loaded
+extern ULONG           BootDrive;                      // BIOS boot drive, 0-A:, 1-B:, 0x80-C:, 0x81-D:, etc.
+extern ULONG           BootPartition;          // Boot Partition, 1-4
+extern BOOL                    UserInterfaceUp;        // Tells us if the user interface is displayed
 
-extern char                    *pFreeldrIni; // Load address for freeldr.ini
-extern char                    *pScreenBuffer; // Save address for screen contents
-extern int                     nCursorXPos;    // Cursor's X Position
-extern int                     nCursorYPos;    // Cursor's Y Position
+extern PUCHAR          ScreenBuffer;           // Save buffer for screen contents
+extern int                     CursorXPos;                     // Cursor's X Position
+extern int                     CursorYPos;                     // Cursor's Y Position
 
 extern OSTYPE          OSList[16]; // The OS list
 extern int                     nNumOS;         // Number of OSes listed
@@ -72,11 +79,5 @@ extern int                   nNumOS;         // Number of OSes listed
 extern int                     nTimeOut;               // Time to wait for the user before booting
 
 void   BootMain(void);
-BOOL   ParseIniFile(void);
-int            GetNumSectionItems(char *section); // returns the number of items in a particular section (i.e. [FREELOADER])
-BOOL   ReadSectionSettingByNumber(char *section, int num, char *name, char *value); // Reads the num'th value from section
-BOOL   ReadSectionSettingByName(char *section, char *valuename, char *name, char *value); // Reads the value named name from section
-BOOL   IsValidSetting(char *setting, char *value);
-void   SetSetting(char *setting, char *value);
 
 #endif  // defined __FREELDR_H
\ No newline at end of file
index 03419dd..8fbd811 100644 (file)
@@ -25,7 +25,7 @@
 
 #define        FS_DO_ERROR(s)  \
        { \
-               if (bTUILoaded) \
+               if (UserInterfaceUp) \
                        MessageBox(s); \
                else \
                { \
index 0033897..448d86d 100644 (file)
@@ -92,9 +92,9 @@ void LoadAndBootLinux(int DriveNum, int Partition, char *vmlinuz, char *cmd_line
        memcpy((void*)0x90000, bootsector, 512);
        memcpy((void*)0x90200, setup, 2048);
 
-       RestoreScreen(pScreenBuffer);
+       RestoreScreen(ScreenBuffer);
        showcursor();
-       gotoxy(nCursorXPos, nCursorYPos);
+       gotoxy(CursorXPos, CursorYPos);
 
        stop_floppy();
        JumpToLinuxBootCode();
index 1d958e4..6dfcb02 100644 (file)
 
 #include "freeldr.h"
 #include "memory.h"
+#include "stdlib.h"
+#include "debug.h"
 
+#define MEM_BLOCK_SIZE 256
 
-void InitMemoryManager(void *HeapBaseAddress, unsigned long HeapLength)
+typedef struct
 {
+       BOOL    MemBlockAllocated;              // Is this block allocated or free
+       ULONG   BlocksAllocated;                // Block length, in multiples of 256 bytes
+} MEMBLOCK, *PMEMBLOCK;
+
+PVOID          HeapBaseAddress = NULL;
+ULONG          HeapLengthInBytes = 0;
+ULONG          HeapMemBlockCount = 0;
+PMEMBLOCK      HeapMemBlockArray = NULL;
+
+#ifdef DEBUG
+ULONG          AllocationCount = 0;
+
+VOID           VerifyHeap(VOID);
+VOID           IncrementAllocationCount(VOID);
+VOID           DecrementAllocationCount(VOID);
+VOID           MemAllocTest(VOID);
+#endif DEBUG
+
+VOID InitMemoryManager(PVOID BaseAddress, ULONG Length)
+{
+       ULONG   MemBlocks;
+
+       // Calculate how many memory blocks we have
+       MemBlocks = (Length / MEM_BLOCK_SIZE);
+
+       // Adjust the heap length so we can reserve
+       // enough storage space for the MEMBLOCK array
+       Length -= (MemBlocks * sizeof(MEMBLOCK));
+
+       // Initialize our tracking variables
+       HeapBaseAddress = BaseAddress;
+       HeapLengthInBytes = Length;
+       HeapMemBlockCount = (HeapLengthInBytes / MEM_BLOCK_SIZE);
+       HeapMemBlockArray = (PMEMBLOCK)(HeapBaseAddress + HeapLengthInBytes);
+
+       // Clear the memory
+       ZeroMemory(HeapBaseAddress, HeapLengthInBytes);
+       ZeroMemory(HeapMemBlockArray, (HeapMemBlockCount * sizeof(MEMBLOCK)));
+
+#ifdef DEBUG
+       DebugPrint(DPRINT_MEMORY, "Memory Manager initialized. BaseAddress = 0x%x Length = 0x%x. %d blocks in heap.\n", BaseAddress, Length, HeapMemBlockCount);
+       //MemAllocTest();
+#endif
 }
 
-void *malloc(int size)
+PVOID AllocateMemory(ULONG NumberOfBytes)
 {
-       return 0;
+       ULONG   BlocksNeeded;
+       ULONG   Idx;
+       ULONG   NumFree;
+       PVOID   MemPointer;
+
+#ifdef DEBUG
+       VerifyHeap();
+#endif DEBUG
+
+       // Find out how many blocks it will take to
+       // satisfy this allocation
+       BlocksNeeded = ROUND_UP(NumberOfBytes, MEM_BLOCK_SIZE) / MEM_BLOCK_SIZE;
+
+       // Now loop through our array of blocks and
+       // see if we have enough space
+       for (Idx=0,NumFree=0; Idx<HeapMemBlockCount; Idx++)
+       {
+               // Check this block and see if it is already allocated
+               // If so reset our counter and continue the loop
+               if (HeapMemBlockArray[Idx].MemBlockAllocated)
+               {
+                       NumFree = 0;
+                       continue;
+               }
+               else
+               {
+                       // It is free memory so lets increment our count
+                       NumFree++;
+               }
+
+               // If we have found enough blocks to satisfy the request
+               // then we're done searching
+               if (NumFree >= BlocksNeeded)
+               {
+                       break;
+               }
+       }
+       Idx++;
+
+       // If we don't have enough available mem
+       // then return NULL
+       if (NumFree < BlocksNeeded)
+       {
+               return NULL;
+       }
+
+       // Subtract the block count from Idx and we have
+       // the start block of the memory
+       Idx -= NumFree;
+
+       // Now we know which block to give them
+       MemPointer = HeapBaseAddress + (Idx * MEM_BLOCK_SIZE);
+
+       // Now loop through and mark all the blocks as allocated
+       for (NumFree=0; NumFree<BlocksNeeded; NumFree++)
+       {
+               HeapMemBlockArray[Idx + NumFree].MemBlockAllocated = TRUE;
+               HeapMemBlockArray[Idx + NumFree].BlocksAllocated = NumFree ? 0 : BlocksNeeded; // Mark only the first block with the count
+       }
+
+#ifdef DEBUG
+       IncrementAllocationCount();
+       DebugPrint(DPRINT_MEMORY, "Allocated %d bytes (%d blocks) of memory starting at block %d. AllocationCount: %d\n", NumberOfBytes, BlocksNeeded, Idx, AllocationCount);
+#endif DEBUG
+
+       // Now return the pointer
+       return MemPointer;
 }
 
-void free(void *memblock)
+VOID FreeMemory(PVOID MemBlock)
 {
+       ULONG   BlockNumber;
+       ULONG   BlockCount;
+       ULONG   Idx;
+
+#ifdef DEBUG
+       VerifyHeap();
+
+       // Make sure we didn't get a bogus pointer
+       if ((MemBlock < HeapBaseAddress) || (MemBlock > (HeapBaseAddress + HeapLengthInBytes)))
+       {
+               BugCheck1("Bogus memory pointer (0x%x) passed to FreeMemory()\n", MemBlock);
+       }
+#endif DEBUG
+
+       // Find out the block number if the first
+       // block of memory they allocated
+       BlockNumber = (MemBlock - HeapBaseAddress) / MEM_BLOCK_SIZE;
+       BlockCount = HeapMemBlockArray[BlockNumber].BlocksAllocated;
+
+#ifdef DEBUG
+       // Make sure we didn't get a bogus pointer
+       if ((BlockCount < 1) || (BlockCount > HeapMemBlockCount))
+       {
+               BugCheck1("Invalid block count in heap page header. HeapMemBlockArray[BlockNumber].BlocksAllocated = %d\n", HeapMemBlockArray[BlockNumber].BlocksAllocated);
+       }
+#endif
+
+       // Loop through our array and mark all the
+       // blocks as free
+       for (Idx=BlockNumber; Idx<(BlockNumber + BlockCount); Idx++)
+       {
+               HeapMemBlockArray[Idx].MemBlockAllocated = FALSE;
+               HeapMemBlockArray[Idx].BlocksAllocated = 0;
+       }
+
+#ifdef DEBUG
+       DecrementAllocationCount();
+       DebugPrint(DPRINT_MEMORY, "Freed %d blocks of memory starting at block %d. AllocationCount: %d\n", BlockCount, BlockNumber, AllocationCount);
+#endif DEBUG
+}
+
+#ifdef DEBUG
+VOID VerifyHeap(VOID)
+{
+       ULONG   Idx;
+       ULONG   Idx2;
+       ULONG   Count;
+
+       // Loop through the array and verify that
+       // everything is kosher
+       for (Idx=0; Idx<HeapMemBlockCount; Idx++)
+       {
+               // Check if this block is allocation
+               if (HeapMemBlockArray[Idx].MemBlockAllocated)
+               {
+                       // This is the first block in the run so it
+                       // had better have a length that is within range
+                       if ((HeapMemBlockArray[Idx].BlocksAllocated < 1) || (HeapMemBlockArray[Idx].BlocksAllocated > (HeapMemBlockCount - Idx)))
+                       {
+                               BugCheck1("Allocation length out of range in heap table. HeapMemBlockArray[Idx].BlocksAllocated = %d\n", HeapMemBlockArray[Idx].BlocksAllocated);
+                       }
+
+                       // Now go through and verify that the rest of
+                       // this run has the blocks marked allocated
+                       // with a length of zero but don't check the
+                       // first one because we already did
+                       Count = HeapMemBlockArray[Idx].BlocksAllocated;
+                       for (Idx2=1; Idx2<Count; Idx2++)
+                       {
+                               // Make sure it's allocated
+                               if (HeapMemBlockArray[Idx + Idx2].MemBlockAllocated != TRUE)
+                               {
+                                       BugCheck0("Heap table indicates hole in memory allocation. HeapMemBlockArray[Idx + Idx2].MemBlockAllocated != TRUE\n");
+                               }
+
+                               // Make sure the length is zero
+                               if (HeapMemBlockArray[Idx + Idx2].BlocksAllocated != 0)
+                               {
+                                       BugCheck0("Allocation chain has non-zero value in non-first block in heap table. HeapMemBlockArray[Idx + Idx2].BlocksAllocated != 0\n");
+                               }
+                       }
+
+                       // Move on to the next run
+                       Idx += Count;
+               }
+               else
+               {
+                       // Nope, not allocated so make sure the length is zero
+                       if (HeapMemBlockArray[Idx].BlocksAllocated != 0)
+                       {
+                               BugCheck0("Free block is start of memory allocation. HeapMemBlockArray[Idx].BlocksAllocated != 0\n");
+                       }
+               }
+       }
+}
+
+VOID IncrementAllocationCount(VOID)
+{
+       AllocationCount++;
+}
+
+VOID DecrementAllocationCount(VOID)
+{
+       AllocationCount--;
+}
+
+VOID MemAllocTest(VOID)
+{
+       PVOID   MemPtr1;
+       PVOID   MemPtr2;
+       PVOID   MemPtr3;
+       PVOID   MemPtr4;
+       PVOID   MemPtr5;
+
+       MemPtr1 = AllocateMemory(4096);
+       printf("MemPtr1: 0x%x\n", (int)MemPtr1);
+       getch();
+       MemPtr2 = AllocateMemory(4096);
+       printf("MemPtr2: 0x%x\n", (int)MemPtr2);
+       getch();
+       MemPtr3 = AllocateMemory(4096);
+       printf("MemPtr3: 0x%x\n", (int)MemPtr3);
+       getch();
+
+       FreeMemory(MemPtr2);
+       getch();
+
+       MemPtr4 = AllocateMemory(2048);
+       printf("MemPtr4: 0x%x\n", (int)MemPtr4);
+       getch();
+       MemPtr5 = AllocateMemory(4096);
+       printf("MemPtr5: 0x%x\n", (int)MemPtr5);
+       getch();
 }
+#endif DEBUG
index 5603d5c..b1113df 100644 (file)
 #include "multiboot.h"
 
 
-void   InitMemoryManager(void *HeapBaseAddress, unsigned long HeapLength);
+VOID   InitMemoryManager(PVOID BaseAddress, ULONG Length);
 
-void*  malloc(int size);
-void   free(void *memblock);
+PVOID  AllocateMemory(ULONG NumberOfBytes);
+VOID   FreeMemory(PVOID MemBlock);
 
 // These functions are implemented in mem.S
 int            GetExtendedMemorySize(void);                            // Returns extended memory size in KB
index 8b6026a..43a76b7 100644 (file)
@@ -24,6 +24,7 @@
 #include "stdlib.h"
 #include "fs.h"
 #include "tui.h"
+#include "parseini.h"
 
 void LoadAndBootBootSector(int nOSToBoot)
 {
@@ -43,7 +44,7 @@ void LoadAndBootBootSector(int nOSToBoot)
                        MessageLine(value);
        }
 
-       if (!ReadSectionSettingByName(OSList[nOSToBoot].name, "BootDrive", name, value))
+       if (!ReadSectionSettingByName(OSList[nOSToBoot].name, "BootDrive", value))
        {
                MessageBox("Boot drive not specified for selected OS!");
                return;
@@ -52,10 +53,10 @@ void LoadAndBootBootSector(int nOSToBoot)
        BootDrive = atoi(value);
 
        BootPartition = 0;
-       if (ReadSectionSettingByName(OSList[nOSToBoot].name, "BootPartition", name, value))
+       if (ReadSectionSettingByName(OSList[nOSToBoot].name, "BootPartition", value))
                BootPartition = atoi(value);
 
-       if (!ReadSectionSettingByName(OSList[nOSToBoot].name, "BootSector", name, value))
+       if (!ReadSectionSettingByName(OSList[nOSToBoot].name, "BootSector", value))
        {
                MessageBox("Boot sector file not specified for selected OS!");
                return;
@@ -89,9 +90,9 @@ void LoadAndBootBootSector(int nOSToBoot)
                return;
        }
 
-       RestoreScreen(pScreenBuffer);
+       RestoreScreen(ScreenBuffer);
        showcursor();
-       gotoxy(nCursorXPos, nCursorYPos);
+       gotoxy(CursorXPos, CursorYPos);
 
        stop_floppy();
        JumpToBootCode();
@@ -115,7 +116,7 @@ void LoadAndBootPartition(int nOSToBoot)
                        MessageLine(value);
        }
 
-       if (!ReadSectionSettingByName(OSList[nOSToBoot].name, "BootDrive", name, value))
+       if (!ReadSectionSettingByName(OSList[nOSToBoot].name, "BootDrive", value))
        {
                MessageBox("Boot drive not specified for selected OS!");
                return;
@@ -123,7 +124,7 @@ void LoadAndBootPartition(int nOSToBoot)
 
        BootDrive = atoi(value);
 
-       if (!ReadSectionSettingByName(OSList[nOSToBoot].name, "BootPartition", name, value))
+       if (!ReadSectionSettingByName(OSList[nOSToBoot].name, "BootPartition", value))
        {
                MessageBox("Boot partition not specified for selected OS!");
                return;
@@ -175,9 +176,9 @@ void LoadAndBootPartition(int nOSToBoot)
                return;
        }
 
-       RestoreScreen(pScreenBuffer);
+       RestoreScreen(ScreenBuffer);
        showcursor();
-       gotoxy(nCursorXPos, nCursorYPos);
+       gotoxy(CursorXPos, CursorYPos);
 
        stop_floppy();
        JumpToBootCode();
@@ -199,7 +200,7 @@ void LoadAndBootDrive(int nOSToBoot)
                        MessageLine(value);
        }
 
-       if (!ReadSectionSettingByName(OSList[nOSToBoot].name, "BootDrive", name, value))
+       if (!ReadSectionSettingByName(OSList[nOSToBoot].name, "BootDrive", value))
        {
                MessageBox("Boot drive not specified for selected OS!");
                return;
@@ -220,9 +221,9 @@ void LoadAndBootDrive(int nOSToBoot)
                return;
        }
 
-       RestoreScreen(pScreenBuffer);
+       RestoreScreen(ScreenBuffer);
        showcursor();
-       gotoxy(nCursorXPos, nCursorYPos);
+       gotoxy(CursorXPos, CursorYPos);
 
        stop_floppy();
        JumpToBootCode();
index 095bc98..8e7ccf6 100644 (file)
@@ -24,6 +24,7 @@
 #include "fs.h"
 #include "multiboot.h"
 #include "tui.h"
+#include "parseini.h"
 
 unsigned long                          next_module_load_base = 0;
 
@@ -145,10 +146,9 @@ BOOL MultiBootLoadModule(FILE *ModuleImage, char *ModuleName)
 int GetBootPartition(char *OperatingSystemName)
 {
        int             BootPartitionNumber = -1;
-       char    name[1024];
        char    value[1024];
 
-       if (ReadSectionSettingByName(OperatingSystemName, "BootPartition", name, value))
+       if (ReadSectionSettingByName(OperatingSystemName, "BootPartition", value))
        {
                BootPartitionNumber = atoi(value);
        }
index 324fb66..23befb4 100644 (file)
@@ -53,8 +53,6 @@
 #define MB_INFO_FLAG_APM_TABLE                 0x00000400
 #define MB_INFO_FLAG_GRAPHICS_TABLE            0x00000800
 
-#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
-
 #ifndef ASM
 /* Do not include here in boot.S. */
 
index 8550e24..3a0e92d 100644 (file)
@@ -125,9 +125,9 @@ void DoBootOptionsMenu(int BootDriveNum, char *BootDriveText)
                                return;
                        }
 
-                       RestoreScreen(pScreenBuffer);
+                       RestoreScreen(ScreenBuffer);
                        showcursor();
-                       gotoxy(nCursorXPos, nCursorYPos);
+                       gotoxy(CursorXPos, CursorYPos);
 
                        stop_floppy();
                        JumpToBootCode();
@@ -237,9 +237,9 @@ void DoBootPartitionOptionsMenu(int BootDriveNum)
                                return;
                        }
 
-                       RestoreScreen(pScreenBuffer);
+                       RestoreScreen(ScreenBuffer);
                        showcursor();
-                       gotoxy(nCursorXPos, nCursorYPos);
+                       gotoxy(CursorXPos, CursorYPos);
 
                        stop_floppy();
                        JumpToBootCode();
diff --git a/freeldr/freeldr/parseini.c b/freeldr/freeldr/parseini.c
new file mode 100644 (file)
index 0000000..1bb2615
--- /dev/null
@@ -0,0 +1,522 @@
+/*
+ *  FreeLoader
+ *  Copyright (C) 2001  Brian Palmer  <brianp@sginet.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "freeldr.h"
+#include "parseini.h"
+#include "tui.h"
+#include "fs.h"
+#include "stdlib.h"
+#include "memory.h"
+
+PUCHAR FreeLoaderIniFileData = NULL;
+ULONG  FreeLoaderIniFileSize = 0;
+
+BOOL ParseIniFile(void)
+{
+       int             i;
+       char    name[1024];
+       char    value[1024];
+       FILE    Freeldr_Ini;    // File handle for freeldr.ini
+
+       // Open the boot drive for file access
+       if (!OpenDiskDrive(BootDrive, 0))
+       {
+               printf("Error opening boot drive for file access.\n");
+               return FALSE;
+       }
+
+       // Try to open freeldr.ini or fail
+       if (!OpenFile("freeldr.ini", &Freeldr_Ini))
+       {
+               printf("FREELDR.INI not found.\nYou need to re-install FreeLoader.\n");
+               return FALSE;
+       }
+
+       // Get the file size & allocate enough memory for it
+       FreeLoaderIniFileSize = GetFileSize(&Freeldr_Ini);
+       FreeLoaderIniFileData = AllocateMemory(FreeLoaderIniFileSize);
+
+       // If we are out of memory then return FALSE
+       if (FreeLoaderIniFileData == NULL)
+       {
+               printf("Out of memory while loading FREELDR.INI.\n");
+               return FALSE;
+       }
+
+       // Read freeldr.ini off the disk
+       ReadFile(&Freeldr_Ini, FreeLoaderIniFileSize, FreeLoaderIniFileData);
+
+       // Make sure the [FREELOADER] section exists
+       if (!GetNumSectionItems("FREELOADER"))
+       {
+               printf("Section [FREELOADER] not found in FREELDR.INI.\nYou need to re-install FreeLoader.\n");
+               return FALSE;
+       }
+
+       // Validate the settings in the [FREELOADER] section
+       for (i=1; i<=GetNumSectionItems("FREELOADER"); i++)
+       {
+               ReadSectionSettingByNumber("FREELOADER", i, name, value);
+               if (!IsValidSetting(name, value))
+               {
+                       printf("Invalid setting in freeldr.ini.\nName: \"%s\", Value: \"%s\"\n", name, value);
+                       printf("Press any key to continue.\n");
+                       getch();
+               }
+               else
+                       SetSetting(name, value);
+       }
+
+       return TRUE;
+}
+
+ULONG GetNextLineOfFileData(PUCHAR Buffer, ULONG BufferSize, ULONG CurrentOffset)
+{
+       ULONG   Idx;
+
+       // Loop through grabbing chars until we hit the end of the
+       // file or we encounter a new line char
+       for (Idx=0; (CurrentOffset < FreeLoaderIniFileSize); CurrentOffset++)
+       {
+               // If we haven't exceeded our buffer size yet
+               // then store another char
+               if (Idx < (BufferSize - 1))
+               {
+                       Buffer[Idx++] = FreeLoaderIniFileData[CurrentOffset];
+               }
+
+               // Check for new line char
+               if (FreeLoaderIniFileData[CurrentOffset] == '\n')
+               {
+                       CurrentOffset++;
+                       break;
+               }
+       }
+
+       // Terminate the string
+       Buffer[Idx] = '\0';
+
+       // Get rid of newline & linefeed characters (if any)
+       if((Buffer[strlen(Buffer)-1] == '\n') || (Buffer[strlen(Buffer)-1] == '\r'))
+               Buffer[strlen(Buffer)-1] = '\0';
+       if((Buffer[strlen(Buffer)-1] == '\n') || (Buffer[strlen(Buffer)-1] == '\r'))
+               Buffer[strlen(Buffer)-1] = '\0';
+
+       // Send back new offset
+       return CurrentOffset;
+}
+
+ULONG GetOffsetOfFirstLineOfSection(PUCHAR SectionName)
+{
+       char    str[1024];
+       char    real_section[1024];
+       ULONG   freeldr_ini_offset;
+       BOOL    SectionFound = FALSE;
+
+       // Get the real section name
+       strcpy(real_section, "[");
+       strcat(real_section, SectionName);
+       strcat(real_section, "]");
+
+       // Get to the beginning of the file
+       freeldr_ini_offset = 0;
+
+       // Find the section
+       while (freeldr_ini_offset < FreeLoaderIniFileSize)
+       {
+               // Read a line
+               freeldr_ini_offset = GetNextLineOfFileData(str, 1024, freeldr_ini_offset);
+
+               // Skip comments
+               if (str[0] == '#')
+                       continue;
+
+               // Skip blank lines
+               if (!strlen(str))
+                       continue;
+
+               // If it isn't a section header then continue on
+               if (str[0] != '[')
+                       continue;
+
+               // Check and see if we found it
+               if (stricmp(str, real_section) == 0)
+               {
+                       SectionFound = TRUE;
+                       break;
+               }
+       }
+
+       // If we didn't find the section then we're outta here
+       if (!SectionFound)
+               return 0;
+
+       return freeldr_ini_offset;
+}
+
+ULONG GetNumSectionItems(PUCHAR SectionName)
+{
+       UCHAR   str[1024];
+       ULONG   num_items = 0;
+       ULONG   freeldr_ini_offset;
+
+       // Get to the beginning of the section
+       freeldr_ini_offset = GetOffsetOfFirstLineOfSection(SectionName);
+
+       // If the section wasn't found then exit
+       if (freeldr_ini_offset == 0)
+       {
+               return 0;
+       }
+
+       // Now count how many settings are in this section
+       while (freeldr_ini_offset < FreeLoaderIniFileSize)
+       {
+               // Read a line
+               freeldr_ini_offset = GetNextLineOfFileData(str, 1024, freeldr_ini_offset);
+
+               // Skip comments
+               if (str[0] == '#')
+                       continue;
+
+               // Skip blank lines
+               if (!strlen(str))
+                       continue;
+
+               // If we hit a new section then we're done
+               if (str[0] == '[')
+                       break;
+
+               num_items++;
+       }
+
+       return num_items;
+}
+
+BOOL ReadSectionSettingByNumber(PUCHAR SectionName, ULONG SettingNumber, PUCHAR SettingName, PUCHAR SettingValue)
+{
+       UCHAR   str[1024];
+       ULONG   num_items = 0;
+       ULONG   i;
+       ULONG   freeldr_ini_offset;
+
+       // Get to the beginning of the section
+       freeldr_ini_offset = GetOffsetOfFirstLineOfSection(SectionName);
+
+       // If the section wasn't found then exit
+       if (freeldr_ini_offset == 0)
+       {
+               return 0;
+       }
+
+       // Now find the setting we are looking for
+       while (freeldr_ini_offset < FreeLoaderIniFileSize)
+       {
+               // Read a line
+               freeldr_ini_offset = GetNextLineOfFileData(str, 1024, freeldr_ini_offset);
+
+               // Skip comments
+               if (str[0] == '#')
+                       continue;
+
+               // Skip blank lines
+               if (!strlen(str))
+                       continue;
+
+               // If we hit a new section then we're done
+               if (str[0] == '[')
+                       break;
+
+               // Increment setting number
+               num_items++;
+
+               // Check and see if we found the setting
+               if (num_items == SettingNumber)
+               {
+                       for (i=0; i<strlen(str); i++)
+                       {
+                               // Check and see if this character is the separator
+                               if (str[i] == '=')
+                               {
+                                       SettingName[i] = '\0';
+
+                                       strcpy(SettingValue, str+i+1);
+
+                                       return TRUE;
+                               }
+                               else
+                                       SettingName[i] = str[i];
+                       }
+               }
+       }
+
+       return FALSE;
+}
+
+BOOL ReadSectionSettingByName(PUCHAR SectionName, PUCHAR SettingName, PUCHAR SettingValue)
+{
+       UCHAR   str[1024];
+       UCHAR   temp[1024];
+       ULONG   i;
+       ULONG   freeldr_ini_offset;
+
+       // Get to the beginning of the section
+       freeldr_ini_offset = GetOffsetOfFirstLineOfSection(SectionName);
+
+       // If the section wasn't found then exit
+       if (freeldr_ini_offset == 0)
+       {
+               return 0;
+       }
+
+       // Now find the setting we are looking for
+       while (freeldr_ini_offset < FreeLoaderIniFileSize)
+       {
+               // Read a line
+               freeldr_ini_offset = GetNextLineOfFileData(str, 1024, freeldr_ini_offset);
+
+               // Skip comments
+               if (str[0] == '#')
+                       continue;
+
+               // Skip blank lines
+               if (!strlen(str))
+                       continue;
+
+               // If we hit a new section then we're done
+               if (str[0] == '[')
+                       break;
+
+               // Extract the setting name
+               for (i=0; i<strlen(str); i++)
+               {
+                       if (str[i] != '=')
+                               temp[i] = str[i];
+                       else
+                       {
+                               temp[i] = '\0';
+                               break;
+                       }
+               }
+
+               // Check and see if we found the setting
+               if (stricmp(temp, SettingName) == 0)
+               {
+                       for (i=0; i<strlen(str); i++)
+                       {
+                               // Check and see if this character is the separator
+                               if (str[i] == '=')
+                               {
+                                       strcpy(SettingValue, str+i+1);
+
+                                       return TRUE;
+                               }
+                       }
+               }
+       }
+
+       return FALSE;
+}
+
+BOOL IsValidSetting(char *setting, char *value)
+{
+       if(stricmp(setting, "MessageBox") == 0)
+               return TRUE;
+       else if(stricmp(setting, "MessageLine") == 0)
+               return TRUE;
+       else if(stricmp(setting, "TitleText") == 0)
+               return TRUE;
+       else if(stricmp(setting, "StatusBarColor") == 0)
+       {
+               if(IsValidColor(value))
+                       return TRUE;
+       }
+       else if(stricmp(setting, "StatusBarTextColor") == 0)
+       {
+               if(IsValidColor(value))
+                       return TRUE;
+       }
+       else if(stricmp(setting, "BackdropTextColor") == 0)
+       {
+               if(IsValidColor(value))
+                       return TRUE;
+       }
+       else if(stricmp(setting, "BackdropColor") == 0)
+       {
+               if(IsValidColor(value))
+                       return TRUE;
+       }
+       else if(stricmp(setting, "BackdropFillStyle") == 0)
+       {
+               if(IsValidFillStyle(value))
+                       return TRUE;
+       }
+       else if(stricmp(setting, "TitleBoxTextColor") == 0)
+       {
+               if(IsValidColor(value))
+                       return TRUE;
+       }
+       else if(stricmp(setting, "TitleBoxColor") == 0)
+       {
+               if(IsValidColor(value))
+                       return TRUE;
+       }
+       else if(stricmp(setting, "MessageBoxTextColor") == 0)
+       {
+               if(IsValidColor(value))
+                       return TRUE;
+       }
+       else if(stricmp(setting, "MessageBoxColor") == 0)
+       {
+               if(IsValidColor(value))
+                       return TRUE;
+       }
+       else if(stricmp(setting, "MenuTextColor") == 0)
+       {
+               if(IsValidColor(value))
+                       return TRUE;
+       }
+       else if(stricmp(setting, "MenuColor") == 0)
+       {
+               if(IsValidColor(value))
+                       return TRUE;
+       }
+       else if(stricmp(setting, "TextColor") == 0)
+       {
+               if(IsValidColor(value))
+                       return TRUE;
+       }
+       else if(stricmp(setting, "SelectedTextColor") == 0)
+       {
+               if(IsValidColor(value))
+                       return TRUE;
+       }
+       else if(stricmp(setting, "SelectedColor") == 0)
+       {
+               if(IsValidColor(value))
+                       return TRUE;
+       }
+       else if(stricmp(setting, "OS") == 0)
+               return TRUE;
+       else if(stricmp(setting, "TimeOut") == 0)
+               return TRUE;
+       /*else if(stricmp(setting, "") == 0)
+               return TRUE;
+       else if(stricmp(setting, "") == 0)
+               return TRUE;
+       else if(stricmp(setting, "") == 0)
+               return TRUE;
+       else if(stricmp(setting, "") == 0)
+               return TRUE;
+       else if(stricmp(setting, "") == 0)
+               return TRUE;
+       else if(stricmp(setting, "") == 0)
+               return TRUE;
+       else if(stricmp(setting, "") == 0)
+               return TRUE;*/
+
+       return FALSE;
+}
+
+void SetSetting(char *setting, char *value)
+{
+       char    v[260];
+
+       if(stricmp(setting, "TitleText") == 0)
+               strcpy(szTitleBoxTitleText, value);
+       else if(stricmp(setting, "StatusBarColor") == 0)
+               cStatusBarBgColor = TextToColor(value);
+       else if(stricmp(setting, "StatusBarTextColor") == 0)
+               cStatusBarFgColor = TextToColor(value);
+       else if(stricmp(setting, "BackdropTextColor") == 0)
+               cBackdropFgColor = TextToColor(value);
+       else if(stricmp(setting, "BackdropColor") == 0)
+               cBackdropBgColor = TextToColor(value);
+       else if(stricmp(setting, "BackdropFillStyle") == 0)
+               cBackdropFillStyle = TextToFillStyle(value);
+       else if(stricmp(setting, "TitleBoxTextColor") == 0)
+               cTitleBoxFgColor = TextToColor(value);
+       else if(stricmp(setting, "TitleBoxColor") == 0)
+               cTitleBoxBgColor = TextToColor(value);
+       else if(stricmp(setting, "MessageBoxTextColor") == 0)
+               cMessageBoxFgColor = TextToColor(value);
+       else if(stricmp(setting, "MessageBoxColor") == 0)
+               cMessageBoxBgColor = TextToColor(value);
+       else if(stricmp(setting, "MenuTextColor") == 0)
+               cMenuFgColor = TextToColor(value);
+       else if(stricmp(setting, "MenuColor") == 0)
+               cMenuBgColor = TextToColor(value);
+       else if(stricmp(setting, "TextColor") == 0)
+               cTextColor = TextToColor(value);
+       else if(stricmp(setting, "SelectedTextColor") == 0)
+               cSelectedTextColor = TextToColor(value);
+       else if(stricmp(setting, "SelectedColor") == 0)
+               cSelectedTextBgColor = TextToColor(value);
+       else if(stricmp(setting, "OS") == 0)
+       {
+               if(nNumOS >= 16)
+               {
+                       printf("Error: you can only boot to at most 16 different operating systems.\n");
+                       printf("Press any key to continue\n");
+                       getch();
+                       return;
+               }
+
+               if(!GetNumSectionItems(value))
+               {
+                       printf("Error: OS \"%s\" listed.\n", value);
+                       printf("It does not have it's own [section], or it is empty.\n");
+                       printf("Press any key to continue\n");
+                       getch();
+                       return;
+               }
+
+               strcpy(OSList[nNumOS].name, value);
+
+               if (!ReadSectionSettingByName(value, "BootType", v))
+               {
+                       printf("Unknown BootType for OS \"%s\"\n", value);
+                       printf("Press any key to continue\n");
+                       getch();
+                       return;
+               }
+
+               if (stricmp(v, "ReactOS") == 0)
+                       OSList[nNumOS].nOSType = OSTYPE_REACTOS;
+               else if (stricmp(v, "Linux") == 0)
+                       OSList[nNumOS].nOSType = OSTYPE_LINUX;
+               else if (stricmp(v, "BootSector") == 0)
+                       OSList[nNumOS].nOSType = OSTYPE_BOOTSECTOR;
+               else if (stricmp(v, "Partition") == 0)
+                       OSList[nNumOS].nOSType = OSTYPE_PARTITION;
+               else if (stricmp(v, "Drive") == 0)
+                       OSList[nNumOS].nOSType = OSTYPE_DRIVE;
+               else
+               {
+                       printf("Unknown BootType for OS \"%s\"\n", value);
+                       printf("Press any key to continue\n");
+                       getch();
+                       return;
+               }
+
+               nNumOS++;
+       }
+       else if(stricmp(setting, "TimeOut") == 0)
+               nTimeOut = atoi(value);
+}
diff --git a/freeldr/freeldr/parseini.h b/freeldr/freeldr/parseini.h
new file mode 100644 (file)
index 0000000..f123a51
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ *  FreeLoader
+ *  Copyright (C) 2001  Brian Palmer  <brianp@sginet.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __PARSEINI_H
+#define __PARSEINI_H
+
+BOOL   ParseIniFile(void);
+ULONG  GetNextLineOfFileData(PUCHAR Buffer, ULONG BufferSize, ULONG CurrentOffset); // Gets the next line of text (up to BufferSize) after CurrentOffset and returns the offset of the next line
+ULONG  GetOffsetOfFirstLineOfSection(PUCHAR SectionName); // Returns the offset of the first line in the section or zero if the section wasn't found
+ULONG  GetNumSectionItems(PUCHAR SectionName); // returns the number of items in a particular section (i.e. [FREELOADER])
+BOOL   ReadSectionSettingByNumber(PUCHAR SectionName, ULONG SettingNumber, PUCHAR SettingName, PUCHAR SettingValue); // Reads the num'th value from section
+BOOL   ReadSectionSettingByName(PUCHAR SectionName, PUCHAR SettingName, PUCHAR SettingValue); // Reads the value named name from section
+BOOL   IsValidSetting(char *setting, char *value);
+void   SetSetting(char *setting, char *value);
+
+
+#endif // defined __PARSEINI_H
\ No newline at end of file
index a18981d..7fca575 100644 (file)
 #include "multiboot.h"
 #include "arcname.h"
 #include "memory.h"
+#include "parseini.h"
 
-BOOL   LoadReactOSKernel(char *OperatingSystemName);
-BOOL   LoadReactOSDrivers(char *OperatingSystemName);
+BOOL   LoadReactOSKernel(PUCHAR OperatingSystemName);
+BOOL   LoadReactOSDrivers(PUCHAR OperatingSystemName);
 
-void LoadAndBootReactOS(char *OperatingSystemName)
+void LoadAndBootReactOS(PUCHAR OperatingSystemName)
 {
        FILE            file;
        char            name[1024];
@@ -72,7 +73,7 @@ void LoadAndBootReactOS(char *OperatingSystemName)
        /*
         * Make sure the system path is set in the .ini file
         */
-       if(!ReadSectionSettingByName(OperatingSystemName, "SystemPath", name, value))
+       if (!ReadSectionSettingByName(OperatingSystemName, "SystemPath", value))
        {
                MessageBox("System path not specified for selected operating system.");
                return;
@@ -81,7 +82,7 @@ void LoadAndBootReactOS(char *OperatingSystemName)
        /*
         * Verify system path
         */
-       if(!DissectArcPath(value, szBootPath, &BootDrive, &BootPartition))
+       if (!DissectArcPath(value, szBootPath, &BootDrive, &BootPartition))
        {
                sprintf(MsgBuffer,"Invalid system path: '%s'", value);
                MessageBox(MsgBuffer);
@@ -98,7 +99,7 @@ void LoadAndBootReactOS(char *OperatingSystemName)
        /*
         * Read the optional kernel parameters (if any)
         */
-       if (ReadSectionSettingByName(OperatingSystemName, "Options", name, value))
+       if (ReadSectionSettingByName(OperatingSystemName, "Options", value))
        {
                strcat(multiboot_kernel_cmdline, " ");
                strcat(multiboot_kernel_cmdline, value);
@@ -112,7 +113,7 @@ void LoadAndBootReactOS(char *OperatingSystemName)
        /*
         * Find the kernel image name
         */
-       if(!ReadSectionSettingByName(OperatingSystemName, "Kernel", name, value))
+       if(!ReadSectionSettingByName(OperatingSystemName, "Kernel", value))
        {
                MessageBox("Kernel image file not specified for selected operating system.");
                return;
@@ -149,7 +150,7 @@ void LoadAndBootReactOS(char *OperatingSystemName)
         * Find the kernel image name
         * and try to load the kernel off the disk
         */
-       if(ReadSectionSettingByName(OperatingSystemName, "Kernel", name, value))
+       if(ReadSectionSettingByName(OperatingSystemName, "Kernel", value))
        {
                /*
                 * Set the name and try to open the PE image
@@ -254,7 +255,7 @@ void LoadAndBootReactOS(char *OperatingSystemName)
        strcat(name, ".");
        //MessageBox(name);
 
-       RestoreScreen(pScreenBuffer);
+       RestoreScreen(ScreenBuffer);
 
        /*
         * Now boot the kernel
index c2928da..7117c11 100644 (file)
@@ -21,7 +21,7 @@
 #define __ROSBOOT_H
 
 
-void   LoadAndBootReactOS(char *OperatingSystemName);
+void   LoadAndBootReactOS(PUCHAR OperatingSystemName);
 
 
 #endif // defined __ROSBOOT_H
\ No newline at end of file
index 01cbe83..13a5ebf 100644 (file)
@@ -54,11 +54,15 @@ void        *memset(void *dest, int c, size_t count);
 char   *fgets(char *string, int n, FILE *stream);
 int    atoi(char *string);
 
+#define ZeroMemory(Destination, Length) memset(Destination, 0, Length)
+
 
 void   print(char *str);
 void   printf(char *fmt, ...);
 void   sprintf(char *buffer, char *format, ...);
 
+char *convert_to_ascii(char *buf, int c, ...);
+
 int    biosdisk(int cmd, int drive, int head, int track, int sector, int nsects, void *buffer); // Implemented in asmcode.S
 void   stop_floppy(void);              // Implemented in asmcode.S
 int    get_heads(int drive);           // Implemented in asmcode.S