Changes in v1.3 (6/5/2002)

- Added protected mode exception handling in case FreeLoader crashes
- Reworked memory manager to use all of extended memory
- Reworked UI code, now supports multiple text-mode resolutions

svn path=/trunk/; revision=3010
This commit is contained in:
Brian Palmer 2002-06-06 05:58:37 +00:00
parent 998a072d3f
commit ac99fa1fdc
58 changed files with 4808 additions and 2078 deletions

View file

@ -1,3 +1,9 @@
Changes in v1.3 (6/5/2002)
- Added protected mode exception handling in case FreeLoader crashes
- Reworked memory manager to use all of extended memory
- Reworked UI code, now supports multiple text-mode resolutions
Changes in v1.2.2 (5/4/2002)
- Fixed memory leak in menu.c

View file

@ -85,7 +85,16 @@ OS=Drive D:
DefaultOS=ReactOS (Floppy)
TimeOut=10
; DisplayMode can be:
; NORMAL_VGA for 80x25
; EXTENDED_VGA for 80x50 on VGA 80x43 on EGA
; 0x501C for 80x28
; 0x501E for 80x30
; 0x5022 for 80x34
; 0x502B for 80x43
; 0x503C for 80x60
[Display]
DisplayMode=NORMAL_VGA
TitleText=Boot Menu
StatusBarColor=Cyan
StatusBarTextColor=Black

View file

@ -117,7 +117,7 @@ LoadExtraBootCode:
; CX has number of sectors to read
ReadSectors:
cmp eax,DWORD [BiosCHSDriveSize] ; Check if they are reading a sector within CHS range
jbe ReadSectorsCHS ; Yes - go to the old CHS routine
jb ReadSectorsCHS ; Yes - go to the old CHS routine
ReadSectorsLBA:
pushad ; Save logical sector number & sector count
@ -270,8 +270,8 @@ StartSearch:
jb ContinueSearch ; If not continue, if so then we didn't find freeldr.sys
jmp PrintFileNotFound
ContinueSearch:
mov bx,800h
mov es,bx ; Read cluster to [0000:8000h]
mov bx,2000h
mov es,bx ; Read cluster to [2000:0000h]
call ReadCluster ; Read the cluster
@ -280,7 +280,7 @@ ContinueSearch:
xor bx,bx
mov bl,[BYTE bp+SectsPerCluster]
shl bx,4 ; BX = BX * 512 / 32
mov ax,800h ; We loaded at 0800:0000
mov ax,2000h ; We loaded at 2000:0000
mov es,ax
xor di,di
mov si,filename

View file

@ -22,8 +22,10 @@
# CHANGE THESE FOR YOUR OUTPUT
#
TARGET = i386
DEBUG = 1 # Debugging information on (bigger binary)
#DEBUG = 0 # Debugging information off (smaller binary)
# Debugging information on (bigger binary)
DEBUG = yes
# Debugging information off (smaller binary)
#DEBUG = no
OBJDIR = obj
OUTPUT_DIR = $(OBJDIR)/$(TARGET)
@ -34,14 +36,15 @@ OUTPUT_DIR = $(OBJDIR)/$(TARGET)
CC = gcc
LD = ld
AR = ar
NM = nm
RM = cmd /C del
CP = cmd /C copy
MKDIR = cmd /C md
RMDIR = cmd /C rd
MAKE = cmd /C make
MAKE = make
NASM_CMD = nasm
OBJCOPY = objcopy
SED = $(SRCDIR)/../sed
DEPTOOL = $(SRCDIR)/../tools/deptool
#-----------------------------------------------------------------------------------------------------
# TEST IF WE ARE IN THE TARGET DIRECTORY
@ -60,6 +63,7 @@ MAKETARGET = $(MAKE) --no-print-directory -C $(OUTPUT_DIR) \
.PHONY: CHANGE_TO_TARGET
CHANGE_TO_TARGET: $(OBJDIR) $(OBJDIR)/$(TARGET)
@echo Calculating source file dependencies...
+@$(MAKETARGET)
$(OBJDIR):
@ -95,15 +99,15 @@ else
#############################################
# COMPILER COMMAND LINE OPTIONS
#
COMPILER_OPTIONS = -Wall -nostdlib -nostdinc -fno-builtin -O3 -MD
COMPILER_OPTIONS = -Wall -nostdlib -nostdinc -fno-builtin -O1 -MD
#############################################
# COMPILER DEFINES
#
ifeq ($(DEBUG),1)
ifeq ($(DEBUG),yes)
COMPILER_DEFINES = -DDEBUG
else
COMPILERS_DEFINES =
COMPILER_DEFINES =
endif
#############################################
@ -134,14 +138,17 @@ LFLAGS = $(LINKER_OPTIONS)
#
# fathelp.o must come first in the link line because it contains bootsector helper code
# arch.o must come second in the link line because it contains the startup code
# end.o must come last in the link line
ARCH_OBJS = fathelp.o \
arch.o \
i386idt.o \
i386trap.o \
boot.o \
linux.o \
mb.o \
mem.o \
diskint13.o
diskint13.o \
rtlcode.o \
biosvid.o
RTL_OBJS = memory.o \
print.o \
@ -154,7 +161,9 @@ FS_OBJS = fs.o \
iso.o
UI_OBJS = tui.o \
menu.o
tuimenu.o \
ui.o \
gui.o
REACTOS_OBJS= reactos.o \
arcname.o \
@ -170,7 +179,7 @@ DISK_OBJS = disk.o \
partition.o
MM_OBJS = mm.o \
mm_init.o
meminit.o
CACHE_OBJS = cache.o \
blocklist.o
@ -179,6 +188,9 @@ INIFILE_OBJS= inifile.o \
ini_init.o \
parse.o
VIDEO_OBJS = video.o \
vidmode.o
FREELDR_OBJS= freeldr.o \
miscboot.o \
options.o \
@ -186,8 +198,7 @@ FREELDR_OBJS= freeldr.o \
multiboot.o \
debug.o \
oslist.o \
version.o \
end.o # Must come last in the link line
version.o
#############################################
# ALL THE OBJECTS
@ -202,6 +213,7 @@ OBJS = $(ARCH_OBJS) \
$(MM_OBJS) \
$(CACHE_OBJS) \
$(INIFILE_OBJS) \
$(VIDEO_OBJS) \
$(FREELDR_OBJS)
#############################################
@ -218,19 +230,26 @@ VPATH = $(SRCDIR)/ \
$(SRCDIR)/mm \
$(SRCDIR)/cache \
$(SRCDIR)/inifile \
$(SRCDIR)/video \
$(SRCDIR)/include
#############################################
all : freeldr.sys
all : $(DEPTOOL) freeldr.sys
@echo Make ALL done.
#############################################
$(DEPTOOL): $(DEPTOOL).c
@echo ===================================================== Compiling deptool
@$(CC) -Wall -O3 -o $@ $<
#############################################
freeldr.sys : $(OBJS)
@echo ===================================================== LINKING $@
# @$(LD) -N -Ttext=0x8000 --oformat=binary -s -o freeldr.sys $(OBJS)
@$(LD) $(LFLAGS) -o freeldr.exe $(OBJS)
@$(LD) $(LFLAGS) -Map freeldr.map -o freeldr.exe $(OBJS)
@$(OBJCOPY) -O binary freeldr.exe freeldr.sys
#############################################
@ -238,14 +257,12 @@ freeldr.sys : $(OBJS)
%.o :: %.c
@echo ===================================================== Compiling $*
@$(CC) $(CFLAGS) -o $@ -c $<
@$(SED) -e "s/\($*\)\.o[ :]*/\1.o $*.dep : /g" < $*.d > $*.dep
# @$(SED) -e "s/#.*//" -e "s/^[^:]*: *//" -e "s/ *\\$$//" -e "/^$$/ d" -e "s/$$/ :/" < $*.d >> $*.P
@$(DEPTOOL) $*.d
%.o :: %.S
@echo ===================================================== Assembling $*
@$(CC) $(CFLAGS) -o $@ -c $<
@$(SED) -e "s/\($*\)\.o[ :]*/\1.o $*.dep : /g" < $*.d > $*.dep
# @$(SED) -e "s/#.*//" -e "s/^[^:]*: *//" -e "s/ *\\$$//" -e "/^$$/ d" -e "s/$$/ :/" < $*.d >> $*.P
@$(DEPTOOL) $*.d
%.o :: %.asm
@echo ===================================================== Assembling $*
@ -254,7 +271,7 @@ freeldr.sys : $(OBJS)
#############################################
# Include the automagically generated dependencies
-include $(OBJS:%.o=%.dep)
-include $(OBJS:%.o=%.d)
#############################################

View file

@ -21,7 +21,7 @@
.code16
#define ASM
#include "arch.h"
#include <arch.h>
EXTERN(RealEntryPoint)
@ -79,6 +79,8 @@ EXTERN(switch_to_prot)
/* Load the GDT */
lgdt gdtptr
/* Load the IDT */
lidt i386idtptr
/* Enable Protected Mode */
mov %cr0,%eax
@ -155,657 +157,15 @@ inrmode:
/* Put the return address back onto the stack */
pushw (code16ret)
/* Load IDTR with real mode value */
lidt rmode_idtptr
sti /* These are ok now */
/* Now return in r-mode! */
ret
/*
* void putchar(int ch);
*/
EXTERN(_putchar)
.code32
push %eax
push %ebx
push %ebp
/* Get character to display */
movb 0x10(%esp),%bl
/* If we are displaying a CR '\n' then do a LF also */
cmpb $0x0a,%bl
jnz putchar_1
/* Display the LF */
pushl $0x0d
call _putchar
popl %eax
putchar_1:
/* If we are displaying a TAB '\t' then display 8 spaces ' ' */
cmpb $0x09,%bl
jnz putchar_2
/* Display the 8 spaces ' ' */
pushl $0x20
call _putchar
call _putchar
call _putchar
call _putchar
call _putchar
call _putchar
call _putchar
call _putchar
popl %eax
pop %ebp
pop %ebx
pop %eax
ret
putchar_2:
call switch_to_real
.code16
/* Display the character via BIOS int 0x10 function 0x0e */
movb $0x0e,%ah
movb %bl,%al
movw $1,%bx
int $0x10
call switch_to_prot
.code32
pop %ebp
pop %ebx
pop %eax
ret
/*
* void clrscr(void);
*/
EXTERN(_clrscr)
.code32
push %eax
push %ebp
call switch_to_real
.code16
/* Int 0x10, AH = 0x0F - Get Current Video Mode */
movb $0x0f,%ah
int $0x10
/* Int 0x10, AH = 0x00 - Set Current Video Mode, also clears the screen */
movb $0x00,%ah
int $0x10
call switch_to_prot
.code32
pop %ebp
pop %eax
ret
/*
* int kbhit(void);
*/
EXTERN(_kbhit)
.code32
push %ebp
push %ebx
call switch_to_real
.code16
/* Int 0x16, AH = 0x01 - Get Keyboard Status */
movb $0x01,%ah
int $0x16
jz kbhit_1 // ZF=0 if no key is available
/* Return value is non-zero if a key is available */
movl $1,%ebx
jmp kbhit_done
kbhit_1:
/* Return value is zero if no key is available */
movl $0,%ebx
kbhit_done:
call switch_to_prot
.code32
/* Get return value from ebx */
movl %ebx,%eax
pop %ebx
pop %ebp
ret
/*
* int getch(void);
*/
extended_scancode:
.byte 0
EXTERN(_getch)
.code32
push %ebp
push %ebx
call switch_to_real
.code16
/* Check and see if we have an extended scancode to return */
movb extended_scancode,%al
movb $0,extended_scancode
movzbl %al,%ebx
cmpb $0,%al
jnz getch_done
/* Int 0x16, AH = 0x00 - Wait for keypress */
movb $0,%ah
int $0x16
/* If al is zero then it is an extended key */
cmp $0,%al
jnz getch_1
/* Save the scan code to be returned on the next call to getch() */
movb %ah,extended_scancode
getch_1:
/* Store character in ebx */
movzbl %al,%ebx
getch_done:
call switch_to_prot
.code32
/* Get return value from ebx */
movl %ebx,%eax
pop %ebx
pop %ebp
ret
/*
* void gotoxy(int x, int y);
*/
EXTERN(_gotoxy)
.code32
push %ebp
push %eax
push %ebx
push %edx
/* Get cursor positions */
movb 0x14(%esp),%dl
movb 0x18(%esp),%dh
call switch_to_real
.code16
/* Update the cursor position */
movb $2,%ah
movb $0,%bh
int $0x10
call switch_to_prot
.code32
pop %edx
pop %ebx
pop %eax
pop %ebp
ret
/*
* int getyear(void);
*/
EXTERN(_getyear)
.code32
push %ebp
push %ebx
push %ecx
push %edx
call switch_to_real
.code16
/* Get the date */
movb $4,%ah
int $0x1a
/* Convert from BCD to normal */
movb %ch,%al
andb $0x0f,%al
movb %al,%dl
movb %ch,%al
shrb $0x04,%al
andb $0x0f,%al
movb $0x0a,%bl
mulb %bl
addb %al,%dl
movb %dl,%dh
movb %cl,%al
andb $0x0f,%al
movb %al,%dl
movb %cl,%al
shrb $0x04,%al
andb $0x0f,%al
movb $0x0a,%bl
mulb %bl
addb %al,%dl
movb %dl,%cl
movzbl %dh,%eax
movl $100,%ebx
mull %ebx
movl %eax,%edx
addb %cl,%dl
/* Save return value */
movl %edx,%edx
call switch_to_prot
.code32
/* Restore return value */
movl %edx,%eax
pop %edx
pop %ecx
pop %ebx
pop %ebp
ret
/*
* int getday(void);
*/
EXTERN(_getday)
.code32
push %ebp
push %ebx
push %ecx
push %edx
call switch_to_real
.code16
/* Get the date */
movb $4,%ah
int $0x1a
/* Convert from BCD to normal */
movb %dl,%al
andb $0x0f,%al
movb %al,%cl
movb %dl,%al
shrb $0x04,%al
andb $0x0f,%al
movb $0x0a,%bl
mulb %bl
addb %al,%cl
/* Save return value */
movzbl %cl,%edx
call switch_to_prot
.code32
/* Restore return value */
movl %edx,%eax
pop %edx
pop %ecx
pop %ebx
pop %ebp
ret
/*
* int getmonth(void);
*/
EXTERN(_getmonth)
.code32
push %ebp
push %ebx
push %ecx
push %edx
call switch_to_real
.code16
/* Get the date */
movb $4,%ah
int $0x1a
/* Convert from BCD to normal */
movb %dh,%al
andb $0x0f,%al
movb %al,%dl
movb %dh,%al
shrb $0x04,%al
andb $0x0f,%al
movb $0x0a,%bl
mulb %bl
addb %al,%dl
/* Save return value */
movzbl %dl,%edx
call switch_to_prot
.code32
/* Restore return value */
movl %edx,%eax
pop %edx
pop %ecx
pop %ebx
pop %ebp
ret
/*
* int gethour(void);
*/
EXTERN(_gethour)
.code32
push %ebp
push %ebx
push %ecx
push %edx
call switch_to_real
.code16
/* Get the time */
movb $2,%ah
int $0x1a
/* Convert from BCD to normal */
movb %ch,%al
andb $0x0f,%al
movb %al,%dl
movb %ch,%al
shrb $0x04,%al
andb $0x0f,%al
movb $0x0a,%bl
mulb %bl
addb %al,%dl
/* Save return value */
movzbl %dl,%edx
call switch_to_prot
.code32
/* Restore return value */
movl %edx,%eax
pop %edx
pop %ecx
pop %ebx
pop %ebp
ret
/*
* int getminute(void);
*/
EXTERN(_getminute)
.code32
push %ebp
push %ebx
push %ecx
push %edx
call switch_to_real
.code16
/* Get the time */
movb $2,%ah
int $0x1a
/* Convert from BCD to normal */
movb %cl,%al
andb $0x0f,%al
movb %al,%dl
movb %cl,%al
shrb $0x04,%al
andb $0x0f,%al
movb $0x0a,%bl
mulb %bl
addb %al,%dl
/* Save return value */
movzbl %dl,%edx
call switch_to_prot
.code32
/* Restore return value */
movl %edx,%eax
pop %edx
pop %ecx
pop %ebx
pop %ebp
ret
/*
* int getsecond(void);
*/
EXTERN(_getsecond)
.code32
push %ebp
push %ebx
push %ecx
push %edx
call switch_to_real
.code16
/* Get the time */
movb $2,%ah
int $0x1a
/* Convert from BCD to normal */
movb %dh,%al
andb $0x0f,%al
movb %al,%dl
movb %dh,%al
shrb $0x04,%al
andb $0x0f,%al
movb $0x0a,%bl
mulb %bl
addb %al,%dl
/* Save return value */
movzbl %dl,%edx
call switch_to_prot
.code32
/* Restore return value */
movl %edx,%eax
pop %edx
pop %ecx
pop %ebx
pop %ebp
ret
/*
* void hidecursor(void);
*/
EXTERN(_hidecursor)
.code32
push %ebp
push %ebx
push %ecx
push %edx
call switch_to_real
.code16
/* Hide the cursor */
movb $1,%ah
movw $0x2000,%cx
int $0x10
call switch_to_prot
.code32
pop %edx
pop %ecx
pop %ebx
pop %ebp
ret
/*
* void showcursor(void);
*/
EXTERN(_showcursor)
.code32
push %ebp
push %ebx
push %ecx
push %edx
call switch_to_real
.code16
/* Show the cursor */
movb $1,%ah
movb $0x0d,%ch
movb $0x0e,%cl
int $0x10
call switch_to_prot
.code32
pop %edx
pop %ecx
pop %ebx
pop %ebp
ret
/*
* int wherex(void);
*/
EXTERN(_wherex)
.code32
push %ebp
push %ebx
push %ecx
push %edx
call switch_to_real
.code16
/* Get the cursor position */
movb $3,%ah
movb $0,%bh
int $0x10
/* Save return value */
movzbl %dl,%edx
call switch_to_prot
.code32
/* Restore return value */
movl %edx,%eax
pop %edx
pop %ecx
pop %ebx
pop %ebp
ret
/*
* int wherey(void);
*/
EXTERN(_wherey)
.code32
push %ebp
push %ebx
push %ecx
push %edx
call switch_to_real
.code16
/* Get the cursor position */
movb $3,%ah
movb $0,%bh
int $0x10
/* Save return value */
movzbl %dh,%edx
call switch_to_prot
.code32
/* Restore return value */
movl %edx,%eax
pop %edx
pop %ecx
pop %ebx
pop %ebp
ret
/*
* Needed for enabling the a20 address line
*/
@ -820,8 +180,11 @@ empty_8042:
/*
* Enable the A20 address line (to allow access to over 1mb)
*/
EXTERN(_EnableA20)
.code32
EXTERN(_enable_a20)
pushal
call switch_to_real
.code16
@ -835,6 +198,33 @@ EXTERN(_enable_a20)
call switch_to_prot
.code32
popal
ret
/*
* Disable the A20 address line
*/
EXTERN(_DisableA20)
.code32
pushal
call switch_to_real
.code16
call empty_8042
movb $0xD1,%al // command write
outb %al,$0x64
call empty_8042
mov $0xDD,%al // A20 off
out %al,$0x60
call empty_8042
call switch_to_prot
.code32
popal
ret
@ -894,5 +284,10 @@ gdtptr:
.word 0x27 /* Limit */
.long gdt /* Base Address */
/* Real-mode IDT pointer */
rmode_idtptr:
.word 0x3ff /* Limit */
.long 0 /* Base Address */
EXTERN(_BootDrive)
.long 0

View file

@ -0,0 +1,588 @@
/*
* FreeLoader
* Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
* Portions from Linux video.S - Display adapter & video mode setup, version 2.13 (14-May-99)
* Copyright (C) 1995 -- 1999 Martin Mares <mj@ucw.cz>
* Based on the original setup.S code (C) Linus Torvalds and Mats Anderson
*
* 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.
*/
.text
.code16
#define ASM
#include <arch.h>
/*
* VOID BiosSetVideoMode(ULONG VideoMode);
*/
BiosVideoMode:
.long 0
EXTERN(_BiosSetVideoMode)
.code32
pushal
/* Get BIOS video mode */
movl 0x24(%esp),%eax
movl %eax,BiosVideoMode
call switch_to_real
.code16
/* Int 0x10, AH = 0x00 - Set Current Video Mode, also clears the screen */
movb $0x00,%ah
movb BiosVideoMode,%al
int $0x10
call switch_to_prot
.code32
popal
ret
/*
* VOID BiosSetVideoFont8x8(VOID);
*/
EXTERN(_BiosSetVideoFont8x8)
.code32
pushal
call switch_to_real
.code16
/* Int 0x10, AX = 0x1112 - Load 8x8 Font */
movw $0x1112,%ax
xorb %bl,%bl
int $0x10
call switch_to_prot
.code32
popal
ret
/*
* VOID BiosSetVideoFont8x14(VOID);
*/
EXTERN(_BiosSetVideoFont8x14)
.code32
pushal
call switch_to_real
.code16
/* Int 0x10, AX = 0x1111 - Load 8x16 Font */
movw $0x1111,%ax
xorb %bl,%bl
int $0x10
call switch_to_prot
.code32
popal
ret
/*
* VOID BiosSetVideoFont8x16(VOID);
*/
EXTERN(_BiosSetVideoFont8x16)
.code32
pushal
call switch_to_real
.code16
/* Int 0x10, AX = 0x1114 - Load 8x16 Font */
movw $0x1114,%ax
xorb %bl,%bl
int $0x10
call switch_to_prot
.code32
popal
ret
/*
* VOID BiosSelectAlternatePrintScreen(VOID);
*/
EXTERN(_BiosSelectAlternatePrintScreen)
.code32
pushal
call switch_to_real
.code16
/* Int 0x10, AH = 0x12 - Select alternate print screen routine */
movb $0x12,%ah
movb $0x20,%bl
int $0x10
call switch_to_prot
.code32
popal
ret
/*
* VOID BiosDisableCursorEmulation(VOID);
*/
EXTERN(_BiosDisableCursorEmulation)
.code32
pushal
call switch_to_real
.code16
/* Int 0x10, AH = 0x12 - Disable cursor emulation */
movw $0x1201,%ax
movb $0x34,%bl
int $0x10
call switch_to_prot
.code32
popal
ret
/*
* VOID BiosDefineCursor(ULONG StartScanLine, ULONG EndScanLine);
*/
BiosDefineCursorStartScanLine:
.long 0
BiosDefineCursorEndScanLine:
.long 0
EXTERN(_BiosDefineCursor)
.code32
pushal
/* Get cursor scan line positions */
movl 0x24(%esp),%eax
movl %eax,BiosDefineCursorStartScanLine
movl 0x28(%esp),%eax
movl %eax,BiosDefineCursorEndScanLine
call switch_to_real
.code16
/* Int 0x10, AH = 0x01 - Set Text-Mode Cursor Shape */
movb $0x01,%ah
movb $0x03,%al // Current video mode in AL for buggy AMI 386 BIOS
movb BiosDefineCursorStartScanLine,%ch
movb BiosDefineCursorEndScanLine,%cl
int $0x10
call switch_to_prot
.code32
popal
ret
/*
* ULONG BiosDetectVideoCard(VOID);
*/
BiosDetectVideoCardReturnValue:
.long 0
EXTERN(_BiosDetectVideoCard)
.code32
pushal
movl $0x00,BiosDetectVideoCardReturnValue
call switch_to_real
.code16
/* Int 0x10, AH = 0x12 - Get EGA Info */
movb $0x12,%ah
movb $0x10,%bl
int $0x10
movl $0x00,BiosDetectVideoCardReturnValue
cmpb $0x10,%bl
je BiosDetectVideoCardDone
/* Int 0x10, AX = 0x1A00 - Get Display Combination Code */
movw $0x1a00,%ax
int $0x10
cmpb $0x1a,%al
je BiosDetectVideoCardVga
movl $0x01,BiosDetectVideoCardReturnValue
jmp BiosDetectVideoCardDone
BiosDetectVideoCardVga:
movl $0x02,BiosDetectVideoCardReturnValue
BiosDetectVideoCardDone:
call switch_to_prot
.code32
popal
movl BiosDetectVideoCardReturnValue,%eax
ret
/*
* VOID BiosSet200ScanLines(VOID);
*/
EXTERN(_BiosSet200ScanLines)
.code32
pushal
call switch_to_real
.code16
/* Int 0x10, AX = 0x1200 - Set Vertical Resolution */
movw $0x1200,%ax
movb $0x30,%bl
int $0x10
call switch_to_prot
.code32
popal
ret
/*
* VOID BiosSet350ScanLines(VOID);
*/
EXTERN(_BiosSet350ScanLines)
.code32
pushal
call switch_to_real
.code16
/* Int 0x10, AX = 0x1201 - Set Vertical Resolution */
movw $0x1201,%ax
movb $0x30,%bl
int $0x10
call switch_to_prot
.code32
popal
ret
/*
* VOID BiosSet400ScanLines(VOID);
*/
EXTERN(_BiosSet400ScanLines)
.code32
pushal
call switch_to_real
.code16
/* Int 0x10, AX = 0x1202 - Set Vertical Resolution */
movw $0x1202,%ax
movb $0x30,%bl
int $0x10
call switch_to_prot
.code32
popal
ret
/*
* VOID BiosSet480ScanLines(VOID);
*/
EXTERN(_BiosSet480ScanLines)
.code32
pushal
call switch_to_real
.code16
movw $0x03CC,%dx // Get CRTC port
inb %dx,%al
movb $0xD4,%dl
rorb $0x01,%al
jc set48a
movb $0xB4,%dl
set48a:
movw $0x0C11,%ax // Vertical sync end (also unlocks CR0-7)
call outidx
movw $0x0B06,%ax // Vertical total
call outidx
movw $0x3E07,%ax // (vertical) overflow
call outidx
movw $0xEA10,%ax // Vertical sync start
call outidx
movw $0xDF12,%ax // Vertical display end
call outidx
movw $0xE715,%ax // Vertical blank start
call outidx
movw $0x0416,%ax // Vertical blank end
call outidx
push %dx
movb $0xCC,%dl // Misc output register (read)
inb %dx,%al
movb $0xC2,%dl // (write)
andb $0x0D,%al // Preserve clock select bits and color bit
orb $0xE2,%al // Set correct sync polarity
outb %al,%dx
pop %dx
call switch_to_prot
.code32
popal
ret
/*
* VOID BiosSetVideoDisplayEnd(VOID);
*/
EXTERN(_BiosSetVideoDisplayEnd)
.code32
pushal
call switch_to_real
.code16
movw $0x03CC,%dx // Get CRTC port
inb %dx,%al
movb $0xD4,%dl
rorb $0x01,%al
jc set48a
movb $0xB4,%dl
setvde:
movw $0xDF12,%ax // Vertical display end
call outidx
call switch_to_prot
.code32
popal
ret
/*
* Write to indexed VGA register (AL=index, AH=data, DX=index reg. port)
*/
outidx:
.code16
outb %al,%dx
push %ax
movb %ah,%al
incw %dx
outb %al,%dx
decw %dx
pop %ax
ret
/*
* VOID VideoSetTextCursorPosition(ULONG X, ULONG Y);
*/
EXTERN(_VideoSetTextCursorPosition)
.code32
pushal
/* Get cursor positions */
movb 0x24(%esp),%dl
movb 0x28(%esp),%dh
call switch_to_real
.code16
/* Update the cursor position */
movb $2,%ah
movb $0,%bh
int $0x10
call switch_to_prot
.code32
popal
ret
/*
* VOID VideoHideTextCursor(VOID);
*/
EXTERN(_VideoHideTextCursor)
.code32
pushal
call switch_to_real
.code16
/* Hide the cursor */
movb $1,%ah
movw $0x2000,%cx
int $0x10
call switch_to_prot
.code32
popal
ret
/*
* VOID VideoShowTextCursor(VOID);
*/
EXTERN(_VideoShowTextCursor)
.code32
pushal
call switch_to_real
.code16
/* Show the cursor */
movb $1,%ah
movb $0x0d,%ch
movb $0x0e,%cl
int $0x10
call switch_to_prot
.code32
popal
ret
/*
* ULONG VideoGetTextCursorPositionX(VOID);
*/
VideoGetTextCursorPositionXReturnValue:
.long 0
EXTERN(_VideoGetTextCursorPositionX)
.code32
pushal
movl $0x00,VideoGetTextCursorPositionXReturnValue
call switch_to_real
.code16
/* Get the cursor position */
movb $3,%ah
movb $0,%bh
int $0x10
/* Save return value */
movzbl %dl,%edx
movl %edx,VideoGetTextCursorPositionXReturnValue
call switch_to_prot
.code32
popal
/* Restore return value */
movl VideoGetTextCursorPositionXReturnValue,%eax
ret
/*
* ULONG VideoGetTextCursorPositionY(VOID);
*/
VideoGetTextCursorPositionYReturnValue:
.long 0
EXTERN(_VideoGetTextCursorPositionY)
.code32
pushal
movl $0x00,VideoGetTextCursorPositionYReturnValue
call switch_to_real
.code16
/* Get the cursor position */
movb $3,%ah
movb $0,%bh
int $0x10
/* Save return value */
movzbl %dh,%edx
movl %edx,VideoGetTextCursorPositionYReturnValue
call switch_to_prot
.code32
popal
/* Restore return value */
movl VideoGetTextCursorPositionYReturnValue,%eax
ret

View file

@ -21,11 +21,12 @@
.code16
#define ASM
#include "arch.h"
#include <arch.h>
.code32
EXTERN(_ChainLoadBiosBootSectorCode)
.code32
call switch_to_real
.code16

View file

@ -21,7 +21,7 @@
.code16
#define ASM
#include "arch.h"
#include <arch.h>
/*
@ -48,25 +48,20 @@ _biosdisk_error_code:
EXTERN(_BiosInt13Read)
.code32
push %ebp
push %esi
push %edi
push %ebx
push %ecx
push %edx
pushal
/* Get parameters */
movl 0x1c(%esp),%eax
movl %eax,_biosdisk_drive
movl 0x20(%esp),%eax
movl %eax,_biosdisk_head
movl 0x24(%esp),%eax
movl %eax,_biosdisk_track
movl %eax,_biosdisk_drive
movl 0x28(%esp),%eax
movl %eax,_biosdisk_sector
movl %eax,_biosdisk_head
movl 0x2c(%esp),%eax
movl %eax,_biosdisk_nsects
movl %eax,_biosdisk_track
movl 0x30(%esp),%eax
movl %eax,_biosdisk_sector
movl 0x34(%esp),%eax
movl %eax,_biosdisk_nsects
movl 0x38(%esp),%eax
movl %eax,_biosdisk_buffer
call switch_to_real
@ -138,15 +133,11 @@ _biosdisk_done:
.code32
popal
movl _biosdisk_retval,%eax // Get return value
//movl $1,%eax
pop %edx
pop %ecx
pop %ebx
pop %edi
pop %esi
pop %ebp
ret
/*
@ -178,25 +169,20 @@ _int13_extended_retrycount:
EXTERN(_BiosInt13ReadExtended)
.code32
push %ebp
push %esi
push %edi
push %ebx
push %ecx
push %edx
pushal
/* Get parameters */
movl 0x1c(%esp),%eax
movl %eax,_int13_extended_drive
movl 0x20(%esp),%eax
movl %eax,_packet_lba_sector_number
movl 0x24(%esp),%eax
movl %eax,_int13_extended_drive
movl 0x28(%esp),%eax
movl %eax,_packet_lba_sector_number
movl 0x2c(%esp),%eax
movw %ax,_packet_sector_count
movl %eax,_int13_extended_sector_count
movl 0x28(%esp),%eax // Get buffer address in eax
movl 0x30(%esp),%eax // Get buffer address in eax
shrl $4,%eax // Make linear address into segment
movw %ax,_packet_transfer_buffer_segment // Save segment
movl 0x28(%esp),%eax // Get buffer address in eax
movl 0x34(%esp),%eax // Get buffer address in eax
andl $0x0f,%eax // Make linear address into offset
movw %ax,_packet_transfer_buffer_offset // Save offset
@ -250,14 +236,10 @@ _int13_extended_done:
.code32
popal
movl _int13_extended_retval,%eax // Get return value
pop %edx
pop %ecx
pop %ebx
pop %edi
pop %esi
pop %ebp
ret
/*
@ -270,15 +252,10 @@ _int13_extension_check_retval:
EXTERN(_BiosInt13ExtensionsSupported)
.code32
push %ebp
push %esi
push %edi
push %ebx
push %ecx
push %edx
pushal
/* Get parameters */
movl 0x1c(%esp),%eax
movl 0x24(%esp),%eax
movl %eax,_int13_extension_check_drive
call switch_to_real
@ -309,14 +286,10 @@ _int13_extension_check_done:
.code32
popal
movl _int13_extension_check_retval,%eax // Get return value
pop %edx
pop %ecx
pop %ebx
pop %edi
pop %esi
pop %ebp
ret
/*
@ -331,16 +304,15 @@ EXTERN(_BiosInt13GetLastErrorCode)
/*
* void stop_floppy(void);
* void StopFloppyMotor(void);
*
* Stops the floppy drive from spinning, so that other software is
* jumped to with a known state.
*/
EXTERN(_stop_floppy)
EXTERN(_StopFloppyMotor)
.code32
push %eax
push %edx
pushal
call switch_to_real
@ -354,8 +326,8 @@ EXTERN(_stop_floppy)
.code32
pop %edx
pop %eax
popal
ret
/*
@ -364,14 +336,11 @@ EXTERN(_stop_floppy)
EXTERN(_get_heads)
.code32
push %ebx
push %ecx
push %edx
push %edi
pushal
push %es
/* Get drive */
movl 0x18(%esp),%eax
movl 0x28(%esp),%eax
movl %eax,_biosdisk_drive
call switch_to_real
@ -397,13 +366,10 @@ _get_heads_done:
.code32
movl _biosdisk_retval,%eax // Get return value
pop %es
pop %edi
pop %edx
pop %ecx
pop %ebx
popal
movl _biosdisk_retval,%eax // Get return value
ret
@ -413,14 +379,11 @@ _get_heads_done:
EXTERN(_get_cylinders)
.code32
push %ebx
push %ecx
push %edx
push %edi
pushal
push %es
/* Get drive */
movl 0x18(%esp),%eax
movl 0x28(%esp),%eax
movl %eax,_biosdisk_drive
call switch_to_real
@ -450,13 +413,10 @@ _get_cylinders_done:
.code32
movl _biosdisk_retval,%eax // Get return value
pop %es
pop %edi
pop %edx
pop %ecx
pop %ebx
popal
movl _biosdisk_retval,%eax // Get return value
ret
@ -466,14 +426,11 @@ _get_cylinders_done:
EXTERN(_get_sectors)
.code32
push %ebx
push %ecx
push %edx
push %edi
pushal
push %es
/* Get drive */
movl 0x18(%esp),%eax
movl 0x28(%esp),%eax
movl %eax,_biosdisk_drive
call switch_to_real
@ -499,13 +456,10 @@ _get_sectors_done:
.code32
movl _biosdisk_retval,%eax // Get return value
pop %es
pop %edi
pop %edx
pop %ecx
pop %ebx
popal
movl _biosdisk_retval,%eax // Get return value
ret
@ -526,17 +480,13 @@ _bios_int13_drive_parameters_struct_address:
EXTERN(_BiosInt13GetDriveParameters)
.code32
push %ebx
push %ecx
push %edx
push %edi
push %esi
pushal
push %es
/* Get drive */
movl 0x1c(%esp),%eax
movl 0x28(%esp),%eax
movl %eax,_biosdisk_drive
movl 0x20(%esp),%eax
movl 0x2c(%esp),%eax
movl %eax,_bios_int13_drive_parameters_struct_address
call switch_to_real
@ -589,14 +539,10 @@ _BiosInt13GetDriveParameters_Done:
cld
rep movsl
movl _biosdisk_retval,%eax // Get return value
pop %es
pop %esi
pop %edi
pop %edx
pop %ecx
pop %ebx
popal
movl _biosdisk_retval,%eax // Get return value
ret

View file

@ -0,0 +1,224 @@
/*
* FreeLoader
* Copyright (C) 1998-2002 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.
*/
.text
.code16
#define ASM
#include <arch.h>
.p2align 2 /* force 4-byte alignment */
EXTERN(i386idt)
/* Exception 0 - Divide By Zero */
.word i386DivideByZero /* Offset 0 - 15 */
.word 0x0008 /* Selector */
.word 0x8e00 /* Flags, Zero Byte */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 1 - Debug Exception */
.word i386DebugException /* Offset 0 - 15 */
.word 0x0008 /* Selector */
.word 0x8e00 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 2 - NMI */
.word i386NMIException /* Offset 0 - 15 */
.word 0x0008 /* Selector */
.word 0x8e00 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 3 - Breakpoint (INT 3) */
.word i386Breakpoint /* Offset 0 - 15 */
.word 0x0008 /* Selector */
.word 0x8e00 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 4 - Overflow (INTO with EFLAGS[OF] set) */
.word i386Overflow /* Offset 0 - 15 */
.word 0x0008 /* Selector */
.word 0x8e00 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 5 - Bound Exception */
.word i386BoundException /* Offset 0 - 15 */
.word 0x0008 /* Selector */
.word 0x8e00 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 6 - Invalid Opcode */
.word i386InvalidOpcode /* Offset 0 - 15 */
.word 0x0008 /* Selector */
.word 0x8e00 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 7 - FPU Not Available */
.word i386FPUNotAvailable /* Offset 0 - 15 */
.word 0x0008 /* Selector */
.word 0x8e00 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 8 - Double Fault */
.word i386DoubleFault /* Offset 0 - 15 */
.word 0x0008 /* Selector */
.word 0x8e00 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 9 - Coprocessor Segment Overrun */
.word i386CoprocessorSegment /* Offset 0 - 15 */
.word 0x0008 /* Selector */
.word 0x8e00 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 10 (0x0A) - Invalid TSS */
.word i386InvalidTSS /* Offset 0 - 15 */
.word 0x0008 /* Selector */
.word 0x8e00 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 11 (0x0B) - Segment Not Present */
.word i386SegmentNotPresent /* Offset 0 - 15 */
.word 0x0008 /* Selector */
.word 0x8e00 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 12 (0x0C) - Stack Exception */
.word i386StackException /* Offset 0 - 15 */
.word 0x0008 /* Selector */
.word 0x8e00 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 13 (0x0D) - General Protection Fault */
.word i386GeneralProtectionFault /* Offset 0 - 15 */
.word 0x0008 /* Selector */
.word 0x8e00 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 14 (0x0E) - Page Fault */
.word i386PageFault /* Offset 0 - 15 */
.word 0x0008 /* Selector */
.word 0x8e00 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 15 (0x0F) - Reserved */
.word 0x0000 /* Offset 0 - 15 */
.word 0x0000 /* Selector */
.word 0x0000 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 16 (0x10) - Coprocessor Error */
.word i386CoprocessorError /* Offset 0 - 15 */
.word 0x0008 /* Selector */
.word 0x8e00 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 17 (0x11) - Alignment Check */
.word i386AlignmentCheck /* Offset 0 - 15 */
.word 0x0008 /* Selector */
.word 0x8e00 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 18 (0x12) - Machine Check */
.word i386MachineCheck /* Offset 0 - 15 */
.word 0x0008 /* Selector */
.word 0x8e00 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 19 (0x13) - Reserved */
.word 0x0000 /* Offset 0 - 15 */
.word 0x0000 /* Selector */
.word 0x0000 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 20 (0x14) - Reserved */
.word 0x0000 /* Offset 0 - 15 */
.word 0x0000 /* Selector */
.word 0x0000 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 21 (0x15) - Reserved */
.word 0x0000 /* Offset 0 - 15 */
.word 0x0000 /* Selector */
.word 0x0000 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 22 (0x16) - Reserved */
.word 0x0000 /* Offset 0 - 15 */
.word 0x0000 /* Selector */
.word 0x0000 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 23 (0x17) - Reserved */
.word 0x0000 /* Offset 0 - 15 */
.word 0x0000 /* Selector */
.word 0x0000 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 24 (0x18) - Reserved */
.word 0x0000 /* Offset 0 - 15 */
.word 0x0000 /* Selector */
.word 0x0000 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 25 (0x19) - Reserved */
.word 0x0000 /* Offset 0 - 15 */
.word 0x0000 /* Selector */
.word 0x0000 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 26 (0x1A) - Reserved */
.word 0x0000 /* Offset 0 - 15 */
.word 0x0000 /* Selector */
.word 0x0000 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 27 (0x1B) - Reserved */
.word 0x0000 /* Offset 0 - 15 */
.word 0x0000 /* Selector */
.word 0x0000 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 28 (0x1C) - Reserved */
.word 0x0000 /* Offset 0 - 15 */
.word 0x0000 /* Selector */
.word 0x0000 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 29 (0x1D) - Reserved */
.word 0x0000 /* Offset 0 - 15 */
.word 0x0000 /* Selector */
.word 0x0000 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 30 (0x1E) - Reserved */
.word 0x0000 /* Offset 0 - 15 */
.word 0x0000 /* Selector */
.word 0x0000 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* Exception 31 (0x1F) - Reserved */
.word 0x0000 /* Offset 0 - 15 */
.word 0x0000 /* Selector */
.word 0x0000 /* Zero byte, flags */
.word 0x0000 /* Offset 16 - 31 */
/* IDT table pointer */
EXTERN(i386idtptr)
.word (i386idtptr-i386idt) /* Limit */
.long i386idt /* Base Address */

View file

@ -0,0 +1,761 @@
/*
* FreeLoader
* Copyright (C) 1998-2002 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.
*/
.text
.code16
#define ASM
#include <arch.h>
.macro SAVE_CPU_REGS
movl %eax,i386_EAX
movl %ebx,i386_EBX
movl %ecx,i386_ECX
movl %edx,i386_EDX
movl %esp,i386_ESP
movl %ebp,i386_EBP
movl %esi,i386_ESI
movl %edi,i386_EDI
movw %ds,%ax
movw %ax,i386_DS
movw %es,%ax
movw %ax,i386_ES
movw %fs,%ax
movw %ax,i386_FS
movw %gs,%ax
movw %ax,i386_GS
movw %ss,%ax
movw %ax,i386_SS
popl %eax
movl %eax,i386_EIP
popl %eax
movw %ax,i386_CS
popl %eax
movl %eax,i386_EFLAGS
movl %cr0,%eax
movl %eax,i386_CR0
//movl %cr1,%eax
//movl %eax,i386_CR1
movl %cr2,%eax
movl %eax,i386_CR2
movl %cr3,%eax
movl %eax,i386_CR3
movl %dr0,%eax
movl %eax,i386_DR0
movl %dr1,%eax
movl %eax,i386_DR1
movl %dr2,%eax
movl %eax,i386_DR2
movl %dr3,%eax
movl %eax,i386_DR3
sgdt i386_GDTR
sidt i386_IDTR
sldt i386_LDTR
str i386_TR
.endm
.macro SAVE_CPU_REGS_ERROR_CODE
movl %eax,i386_EAX
movl %ebx,i386_EBX
movl %ecx,i386_ECX
movl %edx,i386_EDX
movl %esp,i386_ESP
movl %ebp,i386_EBP
movl %esi,i386_ESI
movl %edi,i386_EDI
movw %ds,%ax
movw %ax,i386_DS
movw %es,%ax
movw %ax,i386_ES
movw %fs,%ax
movw %ax,i386_FS
movw %gs,%ax
movw %ax,i386_GS
movw %ss,%ax
movw %ax,i386_SS
popl %eax
movl %eax,i386_ERROR_CODE
popl %eax
movl %eax,i386_EIP
popl %eax
movw %ax,i386_CS
popl %eax
movl %eax,i386_EFLAGS
movl %cr0,%eax
movl %eax,i386_CR0
//movl %cr1,%eax
//movl %eax,i386_CR1
movl %cr2,%eax
movl %eax,i386_CR2
movl %cr3,%eax
movl %eax,i386_CR3
movl %dr0,%eax
movl %eax,i386_DR0
movl %dr1,%eax
movl %eax,i386_DR1
movl %dr2,%eax
movl %eax,i386_DR2
movl %dr3,%eax
movl %eax,i386_DR3
sgdt i386_GDTR
sidt i386_IDTR
sldt i386_LDTR
str i386_TR
.endm
i386ExceptionHandlerText:
.ascii "FreeLoader i386 Exception Handler\n"
.asciz "Report bugs to Brian Palmer <brianp@reactos.org>\n\n"
i386DivideByZeroText:
.asciz "Exception 00: DIVIDE BY ZERO\n\n"
i386DebugExceptionText:
.asciz "Exception 01: DEBUG EXCEPTION\n\n"
i386NMIExceptionText:
.asciz "Exception 02: NON-MASKABLE INTERRUPT EXCEPTION\n\n"
i386BreakpointText:
.asciz "Exception 03: BREAKPOINT (INT 3)\n\n"
i386OverflowText:
.asciz "Exception 04: OVERFLOW\n\n"
i386BoundExceptionText:
.asciz "Exception 05: BOUND EXCEPTION\n\n"
i386InvalidOpcodeText:
.asciz "Exception 06: INVALID OPCODE\n\n"
i386FPUNotAvailableText:
.asciz "Exception 07: FPU NOT AVAILABLE\n\n"
i386DoubleFaultText:
.asciz "Exception 08: DOUBLE FAULT\n\n"
i386CoprocessorSegmentText:
.asciz "Exception 09: COPROCESSOR SEGMENT OVERRUN\n\n"
i386InvalidTSSText:
.asciz "Exception 0A: INVALID TSS\n\n"
i386SegmentNotPresentText:
.asciz "Exception 0B: SEGMENT NOT PRESENT\n\n"
i386StackExceptionText:
.asciz "Exception 0C: STACK EXCEPTION\n\n"
i386GeneralProtectionFaultText:
.asciz "Exception 0D: GENERAL PROTECTION FAULT\n\n"
i386PageFaultText:
.asciz "Exception 0E: PAGE FAULT\n\n"
i386CoprocessorErrorText:
.asciz "Exception 10: COPROCESSOR ERROR\n\n"
i386AlignmentCheckText:
.asciz "Exception 11: ALIGNMENT CHECK\n\n"
i386MachineCheckText:
.asciz "Exception 12: MACHINE CHECK\n\n"
i386_EAX_Text:
.asciz "EAX: "
i386_EBX_Text:
.asciz "EBX: "
i386_ECX_Text:
.asciz "ECX: "
i386_EDX_Text:
.asciz "EDX: "
i386_ESP_Text:
.asciz " ESP: "
i386_EBP_Text:
.asciz " EBP: "
i386_ESI_Text:
.asciz " ESI: "
i386_EDI_Text:
.asciz " EDI: "
i386_CS_Text:
.asciz "CS: "
i386_DS_Text:
.asciz "DS: "
i386_ES_Text:
.asciz "ES: "
i386_FS_Text:
.asciz "FS: "
i386_GS_Text:
.asciz "GS: "
i386_SS_Text:
.asciz "SS: "
i386_EFLAGS_Text:
.asciz " EFLAGS: "
i386_EIP_Text:
.asciz " EIP: "
i386_ERROR_CODE_Text:
.asciz " ERROR CODE: "
i386_CR0_Text:
.asciz " CR0: "
i386_CR1_Text:
.asciz " CR1: "
i386_CR2_Text:
.asciz " CR2: "
i386_CR3_Text:
.asciz " CR3: "
i386_DR0_Text:
.asciz " DR0: "
i386_DR1_Text:
.asciz " DR1: "
i386_DR2_Text:
.asciz " DR2: "
i386_DR3_Text:
.asciz " DR3: "
i386_GDTR_Text:
.asciz " GDTR Base: "
i386_IDTR_Text:
.asciz " IDTR Base: "
i386_Limit_Text:
.asciz " Limit: "
i386_LDTR_Text:
.asciz " LDTR: "
i386_TR_Text:
.asciz " TR: "
/* Set by each exception handler to the address of the description text */
i386ExceptionDescriptionText:
.long 0
/* Used to store the contents of all the registers when an exception occurs */
i386_EAX:
.long 0
i386_EBX:
.long 0
i386_ECX:
.long 0
i386_EDX:
.long 0
i386_ESP:
.long 0
i386_EBP:
.long 0
i386_ESI:
.long 0
i386_EDI:
.long 0
i386_CS:
.word 0
i386_DS:
.word 0
i386_ES:
.word 0
i386_FS:
.word 0
i386_GS:
.word 0
i386_SS:
.word 0
i386_EFLAGS:
.long 0
i386_EIP:
.long 0
i386_ERROR_CODE:
.long 0
i386_CR0:
.long 0
i386_CR1:
.long 0
i386_CR2:
.long 0
i386_CR3:
.long 0
i386_DR0:
.long 0
i386_DR1:
.long 0
i386_DR2:
.long 0
i386_DR3:
.long 0
i386_GDTR:
.word 0
.long 0
i386_IDTR:
.word 0
.long 0
i386_LDTR:
.word 0
i386_TR:
.word 0
/* Used to store the current X and Y position on the screen */
i386_ScreenPosX:
.long 0
i386_ScreenPosY:
.long 0
/************************************************************************/
i386CommonExceptionHandler:
.code32
call i386ClearScreenToBlue
movl $i386ExceptionHandlerText,%esi
call i386PrintText
movl i386ExceptionDescriptionText,%esi
call i386PrintText
movl $i386_EAX_Text,%esi
call i386PrintText
movl i386_EAX,%eax
call i386PrintHexDword // Display EAX
movl $i386_ESP_Text,%esi
call i386PrintText
movl i386_ESP,%eax
call i386PrintHexDword // Display ESP
movl $i386_CR0_Text,%esi
call i386PrintText
movl i386_CR0,%eax
call i386PrintHexDword // Display CR0
movl $i386_DR0_Text,%esi
call i386PrintText
movl i386_DR0,%eax
call i386PrintHexDword // Display DR0
movl $0,i386_ScreenPosX
incl i386_ScreenPosY
movl $i386_EBX_Text,%esi
call i386PrintText
movl i386_EBX,%eax
call i386PrintHexDword // Display EBX
movl $i386_EBP_Text,%esi
call i386PrintText
movl i386_EBP,%eax
call i386PrintHexDword // Display EBP
movl $i386_CR1_Text,%esi
call i386PrintText
movl i386_CR1,%eax
call i386PrintHexDword // Display CR1
movl $i386_DR1_Text,%esi
call i386PrintText
movl i386_DR1,%eax
call i386PrintHexDword // Display DR1
movl $0,i386_ScreenPosX
incl i386_ScreenPosY
movl $i386_ECX_Text,%esi
call i386PrintText
movl i386_ECX,%eax
call i386PrintHexDword // Display ECX
movl $i386_ESI_Text,%esi
call i386PrintText
movl i386_ESI,%eax
call i386PrintHexDword // Display ESI
movl $i386_CR2_Text,%esi
call i386PrintText
movl i386_CR2,%eax
call i386PrintHexDword // Display CR2
movl $i386_DR2_Text,%esi
call i386PrintText
movl i386_DR2,%eax
call i386PrintHexDword // Display DR2
movl $0,i386_ScreenPosX
incl i386_ScreenPosY
movl $i386_EDX_Text,%esi
call i386PrintText
movl i386_EDX,%eax
call i386PrintHexDword // Display EDX
movl $i386_EDI_Text,%esi
call i386PrintText
movl i386_EDI,%eax
call i386PrintHexDword // Display EDI
movl $i386_CR3_Text,%esi
call i386PrintText
movl i386_CR3,%eax
call i386PrintHexDword // Display CR3
movl $i386_DR3_Text,%esi
call i386PrintText
movl i386_DR3,%eax
call i386PrintHexDword // Display DR3
movl $0,i386_ScreenPosX
incl i386_ScreenPosY
incl i386_ScreenPosY
movl $i386_CS_Text,%esi
call i386PrintText
movw i386_CS,%ax
call i386PrintHexWord // Display CS
movl $i386_EIP_Text,%esi
call i386PrintText
movl i386_EIP,%eax
call i386PrintHexDword // Display EIP
movl $0,i386_ScreenPosX
incl i386_ScreenPosY
movl $i386_DS_Text,%esi
call i386PrintText
movw i386_DS,%ax
call i386PrintHexWord // Display DS
movl $i386_ERROR_CODE_Text,%esi
call i386PrintText
movl i386_ERROR_CODE,%eax
call i386PrintHexDword // Display ERROR CODE
movl $0,i386_ScreenPosX
incl i386_ScreenPosY
movl $i386_ES_Text,%esi
call i386PrintText
movw i386_ES,%ax
call i386PrintHexWord // Display ES
movl $i386_EFLAGS_Text,%esi
call i386PrintText
movl i386_EFLAGS,%eax
call i386PrintHexDword // Display EFLAGS
movl $0,i386_ScreenPosX
incl i386_ScreenPosY
movl $i386_FS_Text,%esi
call i386PrintText
movw i386_FS,%ax
call i386PrintHexWord // Display FS
movl $i386_GDTR_Text,%esi
call i386PrintText
movl i386_GDTR+2,%eax
call i386PrintHexDword // Display GDTR Base
movl $i386_Limit_Text,%esi
call i386PrintText
movw i386_GDTR,%ax
call i386PrintHexWord // Display GDTR Limit
movl $0,i386_ScreenPosX
incl i386_ScreenPosY
movl $i386_GS_Text,%esi
call i386PrintText
movw i386_GS,%ax
call i386PrintHexWord // Display GS
movl $i386_IDTR_Text,%esi
call i386PrintText
movl i386_IDTR+2,%eax
call i386PrintHexDword // Display IDTR Base
movl $i386_Limit_Text,%esi
call i386PrintText
movw i386_IDTR,%ax
call i386PrintHexWord // Display IDTR Limit
movl $0,i386_ScreenPosX
incl i386_ScreenPosY
movl $i386_SS_Text,%esi
call i386PrintText
movw i386_SS,%ax
call i386PrintHexWord // Display SS
movl $i386_LDTR_Text,%esi
call i386PrintText
movw i386_LDTR,%ax
call i386PrintHexWord // Display LDTR
movl $i386_TR_Text,%esi
call i386PrintText
movw i386_TR,%ax
call i386PrintHexWord // Display TR
movl $0,i386_ScreenPosX
incl i386_ScreenPosY
incl i386_ScreenPosY
i386ExceptionHandlerHang:
jmp i386ExceptionHandlerHang
iret
/************************************************************************/
i386ClearScreenToBlue:
.code32
cld
movw $0x1F20,%ax
movl $0xB0000,%edi
movl $0x8000,%ecx
rep stosw
ret
/************************************************************************/
/* ESI = Address of text to display */
/************************************************************************/
i386PrintText:
.code32
i386PrintTextLoop:
lodsb
// Check for end of string char
cmp $0,%al
je i386PrintTextDone
// Check for newline char
cmp $0x0a,%al
jne i386PrintTextLoop2
incl i386_ScreenPosY
movl $0,i386_ScreenPosX
jmp i386PrintTextLoop
i386PrintTextLoop2:
call i386PrintTextCalcAddressOfNextChar
stosb
incl i386_ScreenPosX
jmp i386PrintTextLoop
i386PrintTextDone:
ret
/************************************************************************/
/* On return EDI = Address of next char in screen memory */
/************************************************************************/
i386PrintTextCalcAddressOfNextChar:
.code32
push %eax
movl $0xB8000,%edi
addl i386_ScreenPosX,%edi
addl i386_ScreenPosX,%edi
movl i386_ScreenPosY,%eax
movl $160,%ecx // 80 columns, 2 bytes per column
mull %ecx
addl %eax,%edi
pop %eax
ret
/************************************************************************/
/* Prints the value in EAX on the screen in hex */
/************************************************************************/
i386PrintHexDword:
.code32
call i386PrintHex1
i386PrintHex1:
call i386PrintHex2
i386PrintHex2:
call i386PrintHex3
i386PrintHex3:
movb $4,%cl
rol %cl,%eax
push %eax
andb $0x0f,%al
movl $i386PrintHexTable,%ebx
xlat /*$i386PrintHexTable*/
call i386PrintTextCalcAddressOfNextChar
stosb
incl i386_ScreenPosX
pop %eax
ret
i386PrintHexTable:
.ascii "0123456789ABCDEF"
/************************************************************************/
/* Prints the value in AX on the screen in hex */
/************************************************************************/
i386PrintHexWord:
.code32
call i386PrintHexWord1
i386PrintHexWord1:
call i386PrintHexWord2
i386PrintHexWord2:
movb $4,%cl
rol %cl,%ax
push %eax
andb $0x0f,%al
movl $i386PrintHexTable,%ebx
xlat /*$i386PrintHexTable*/
call i386PrintTextCalcAddressOfNextChar
stosb
incl i386_ScreenPosX
pop %eax
ret
/************************************************************************/
/* Prints the value in AL on the screen in hex */
/************************************************************************/
i386PrintHexByte:
.code32
call i386PrintHexByte1
i386PrintHexByte1:
movb $4,%cl
rol %cl,%al
push %eax
andb $0x0f,%al
movl $i386PrintHexTable,%ebx
xlat /*$i386PrintHexTable*/
call i386PrintTextCalcAddressOfNextChar
stosb
incl i386_ScreenPosX
pop %eax
ret
/************************************************************************/
EXTERN(i386DivideByZero)
.code32
SAVE_CPU_REGS
movl $i386DivideByZeroText,i386ExceptionDescriptionText
jmp i386CommonExceptionHandler
/************************************************************************/
EXTERN(i386DebugException)
.code32
SAVE_CPU_REGS
movl $i386DebugExceptionText,i386ExceptionDescriptionText
jmp i386CommonExceptionHandler
/************************************************************************/
EXTERN(i386NMIException)
.code32
SAVE_CPU_REGS
movl $i386NMIExceptionText,i386ExceptionDescriptionText
jmp i386CommonExceptionHandler
/************************************************************************/
EXTERN(i386Breakpoint)
.code32
SAVE_CPU_REGS
movl $i386BreakpointText,i386ExceptionDescriptionText
jmp i386CommonExceptionHandler
/************************************************************************/
EXTERN(i386Overflow)
.code32
SAVE_CPU_REGS
movl $i386OverflowText,i386ExceptionDescriptionText
jmp i386CommonExceptionHandler
/************************************************************************/
EXTERN(i386BoundException)
.code32
SAVE_CPU_REGS
movl $i386BoundExceptionText,i386ExceptionDescriptionText
jmp i386CommonExceptionHandler
/************************************************************************/
EXTERN(i386InvalidOpcode)
.code32
SAVE_CPU_REGS
movl $i386InvalidOpcodeText,i386ExceptionDescriptionText
jmp i386CommonExceptionHandler
/************************************************************************/
EXTERN(i386FPUNotAvailable)
.code32
SAVE_CPU_REGS
movl $i386FPUNotAvailableText,i386ExceptionDescriptionText
jmp i386CommonExceptionHandler
/************************************************************************/
EXTERN(i386DoubleFault)
.code32
SAVE_CPU_REGS_ERROR_CODE
movl $i386DoubleFaultText,i386ExceptionDescriptionText
jmp i386CommonExceptionHandler
/************************************************************************/
EXTERN(i386CoprocessorSegment)
.code32
SAVE_CPU_REGS
movl $i386CoprocessorSegmentText,i386ExceptionDescriptionText
jmp i386CommonExceptionHandler
/************************************************************************/
EXTERN(i386InvalidTSS)
.code32
SAVE_CPU_REGS_ERROR_CODE
movl $i386InvalidTSSText,i386ExceptionDescriptionText
jmp i386CommonExceptionHandler
/************************************************************************/
EXTERN(i386SegmentNotPresent)
.code32
SAVE_CPU_REGS_ERROR_CODE
movl $i386SegmentNotPresentText,i386ExceptionDescriptionText
jmp i386CommonExceptionHandler
/************************************************************************/
EXTERN(i386StackException)
.code32
SAVE_CPU_REGS_ERROR_CODE
movl $i386StackExceptionText,i386ExceptionDescriptionText
jmp i386CommonExceptionHandler
/************************************************************************/
EXTERN(i386GeneralProtectionFault)
.code32
SAVE_CPU_REGS_ERROR_CODE
movl $i386GeneralProtectionFaultText,i386ExceptionDescriptionText
jmp i386CommonExceptionHandler
/************************************************************************/
EXTERN(i386PageFault)
.code32
SAVE_CPU_REGS_ERROR_CODE
movl $i386PageFaultText,i386ExceptionDescriptionText
jmp i386CommonExceptionHandler
/************************************************************************/
EXTERN(i386CoprocessorError)
.code32
SAVE_CPU_REGS
movl $i386CoprocessorErrorText,i386ExceptionDescriptionText
jmp i386CommonExceptionHandler
/************************************************************************/
EXTERN(i386AlignmentCheck)
.code32
SAVE_CPU_REGS
movl $i386AlignmentCheckText,i386ExceptionDescriptionText
jmp i386CommonExceptionHandler
/************************************************************************/
EXTERN(i386MachineCheck)
.code32
SAVE_CPU_REGS
movl $i386MachineCheckText,i386ExceptionDescriptionText
jmp i386CommonExceptionHandler

View file

@ -21,7 +21,7 @@
.code16
#define ASM
#include "arch.h"
#include <arch.h>
.code32

View file

@ -21,8 +21,8 @@
.code16
#define ASM
#include "arch.h"
#include "multiboot.h"
#include <arch.h>
#include <multiboot.h>
/*
* Here we assume the kernel is loaded at 1mb

View file

@ -21,94 +21,96 @@
.code16
#define ASM
#include "arch.h"
#include "multiboot.h"
#include <arch.h>
#include <multiboot.h>
.code32
/*
* ULONG GetExtendedMemorySize(VOID);
*/
ExtendedMemorySize:
.long 0
EXTERN(_GetExtendedMemorySize)
.code32
//
// get extended memory size in KB
//
pushl %edx
pushl %ecx
pushl %ebx
pushal
movl $0,ExtendedMemorySize
call switch_to_real
.code16
movw $0xe801,%ax
movw $0xE801,%ax
int $0x15
jc .oldstylemem
jc GetExtendedMemorySizeTryInt15Func88
cmpw $0,%ax
je .cmem
je GetExtendedMemorySizeUseCXDX
movzwl %bx,%ebx
shll $6,%ebx
movzwl %ax,%eax
addl %ebx,%eax
jmp .done_mem
movl %eax,ExtendedMemorySize
jmp GetExtendedMemorySizeDone
.cmem:
GetExtendedMemorySizeUseCXDX:
cmpw $0,%cx
je .oldstylemem
je GetExtendedMemorySizeTryInt15Func88
movzwl %dx,%edx
shll $6,%edx
movzwl %cx,%ecx
addl %ecx,%edx
movl %edx,%eax
jmp .done_mem
movl %edx,ExtendedMemorySize
jmp GetExtendedMemorySizeDone
.oldstylemem:
// int 15h opt e801 don't work , try int 15h, option 88h
GetExtendedMemorySizeTryInt15Func88:
movb $0x88,%ah
int $0x15
cmp $0,%ax
je .cmosmem
jc GetExtendedMemorySizeTryCMOS
cmpw $0,%ax
je GetExtendedMemorySizeTryCMOS
movzwl %ax,%eax
jmp .done_mem
movl %eax,ExtendedMemorySize
jmp GetExtendedMemorySizeDone
.cmosmem:
// int 15h opt 88h don't work , try read cmos
GetExtendedMemorySizeTryCMOS:
xorl %eax,%eax
movb $0x31,%al
outb %al,$0x70
inb $0x71,%al
andl $0xffff,%eax // clear carry
andl $0xffff,%eax
shll $8,%eax
movl %eax,ExtendedMemorySize
.done_mem:
/* Save return value */
movl %eax,%edx
GetExtendedMemorySizeDone:
call switch_to_prot
.code32
/* Restore return value */
movl %edx,%eax
popal
popl %ebx
popl %ecx
popl %edx
/* Restore return value */
movl ExtendedMemorySize,%eax
ret
.code32
/*
* ULONG GetConventionalMemorySize(VOID);
*/
ConventionalMemorySize:
.long 0
EXTERN(_GetConventionalMemorySize)
.code32
//
// Get conventional memory size in KB
//
pushl %edx
pushal
movl $0,ConventionalMemorySize
call switch_to_real
.code16
@ -116,83 +118,96 @@ EXTERN(_GetConventionalMemorySize)
xorl %eax,%eax
int $0x12
/*xorl %eax,%eax
movb $0x30,%al
outb %al,$0x70
inb $0x71,%al
andl $0xffff,%eax*/ // clear carry
/* Save return value */
movzwl %ax,%edx
movzwl %ax,%eax
movl %eax,ConventionalMemorySize
call switch_to_prot
.code32
/* Restore return value */
movl %edx,%eax
popal
popl %edx
/* Restore return value */
movl ConventionalMemorySize,%eax
ret
.code32
/*
* ULONG GetBiosMemoryMap(BIOS_MEMORY_MAP BiosMemoryMap[32]);
*/
_gbmm_mem_map_length:
.long 0
_gbmm_memory_map_addr:
.long 0
_gbmm_memory_map:
.rept 32
.quad 0
.quad 0
.long 0
.long 0
.endr
EXTERN(_GetBiosMemoryMap)
//
// Retrieve BIOS memory map if available
//
pushl %edx
pushl %ecx
pushl %ebx
pushl %edi
.code32
pushal
movl $0,_gbmm_mem_map_length
/* Get memory map address off stack */
movl 0x10(%esp),%eax
/* Get memory map structure array address off stack */
movl 0x24(%esp),%eax
movl %eax,_gbmm_memory_map_addr
call switch_to_real
.code16
xorl %ebx,%ebx
movl _gbmm_memory_map_addr,%edi
movl $_gbmm_memory_map,%edi
.mmap_next:
GetBiosMemoryMapNext:
movl $0x534D4150,%edx // 'SMAP'
movl $/*sizeof(memory_map_t)*/24,%ecx
movl 0xE820,%eax
movl $24,%ecx
movl $0xE820,%eax
int $0x15
jc .done_mmap
jc GetBiosMemoryMapDone
// If the BIOS didn't return 'SMAP' in EAX then
// it doesn't support this call
cmpl $0x534D4150,%eax // 'SMAP'
jne .done_mmap
jne GetBiosMemoryMapDone
addl $/*sizeof(memory_map_t)*/24,%edi
addl $/*sizeof(memory_map_t)*/24,_gbmm_mem_map_length
// Increment our count of items and the offset in the array
addl $24,%edi
incl _gbmm_mem_map_length
// If we have copied 32 items then we can't hold any
// more in our array so we're done
cmpl $32,_gbmm_mem_map_length
jae GetBiosMemoryMapDone
// If the continuation value is zero then this was
// the last entry so we're done
cmpl $0,%ebx
jne .mmap_next
jne GetBiosMemoryMapNext
.done_mmap:
GetBiosMemoryMapDone:
call switch_to_prot
.code32
// Copy the memory map data into the supplied buffer
movl $_gbmm_memory_map,%esi
movl _gbmm_memory_map_addr,%edi
movl $(24 * 32),%ecx
rep movsb
popal
/* Get return value */
movl _gbmm_mem_map_length,%eax
popl %edi
popl %ebx
popl %ecx
popl %edx
ret

View file

@ -0,0 +1,470 @@
/*
* FreeLoader
* Copyright (C) 1998-2002 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.
*/
.text
.code16
#define ASM
#include <arch.h>
/*
* void putchar(int ch);
*/
EXTERN(_putchar)
.code32
pushal
/* Get character to display */
movb 0x24(%esp),%bl
/* If we are displaying a CR '\n' then do a LF also */
cmpb $0x0a,%bl
jnz putchar_1
/* Display the LF */
pushl $0x0d
call _putchar
popl %eax
putchar_1:
/* If we are displaying a TAB '\t' then display 8 spaces ' ' */
cmpb $0x09,%bl
jnz putchar_2
/* Display the 8 spaces ' ' */
pushl $0x20
call _putchar
call _putchar
call _putchar
call _putchar
call _putchar
call _putchar
call _putchar
call _putchar
popl %eax
popal
ret
putchar_2:
call switch_to_real
.code16
/* Display the character via BIOS int 0x10 function 0x0e */
movb $0x0e,%ah
movb %bl,%al
movw $1,%bx
int $0x10
call switch_to_prot
.code32
popal
ret
/*
* int kbhit(void);
*/
_kbhit_retval:
.long 0
EXTERN(_kbhit)
.code32
pushal
movl $0x00,_kbhit_retval
call switch_to_real
.code16
/* Int 0x16, AH = 0x01 - Get Keyboard Status */
movb $0x01,%ah
int $0x16
jz kbhit_1 // ZF=0 if no key is available
/* Return value is non-zero if a key is available */
movl $1,_kbhit_retval
jmp kbhit_done
kbhit_1:
/* Return value is zero if no key is available */
movl $0,_kbhit_retval
kbhit_done:
call switch_to_prot
.code32
popal
/* Get return value */
movl _kbhit_retval,%eax
ret
/*
* int getch(void);
*/
extended_scancode:
.byte 0
EXTERN(_getch)
.code32
push %ebp
push %ebx
call switch_to_real
.code16
/* Check and see if we have an extended scancode to return */
movb extended_scancode,%al
movb $0,extended_scancode
movzbl %al,%ebx
cmpb $0,%al
jnz getch_done
/* Int 0x16, AH = 0x00 - Wait for keypress */
movb $0,%ah
int $0x16
/* If al is zero then it is an extended key */
cmp $0,%al
jnz getch_1
/* Save the scan code to be returned on the next call to getch() */
movb %ah,extended_scancode
getch_1:
/* Store character in ebx */
movzbl %al,%ebx
getch_done:
call switch_to_prot
.code32
/* Get return value from ebx */
movl %ebx,%eax
pop %ebx
pop %ebp
ret
/*
* int getyear(void);
*/
EXTERN(_getyear)
.code32
push %ebp
push %ebx
push %ecx
push %edx
call switch_to_real
.code16
/* Get the date */
movb $4,%ah
int $0x1a
/* Convert from BCD to normal */
movb %ch,%al
andb $0x0f,%al
movb %al,%dl
movb %ch,%al
shrb $0x04,%al
andb $0x0f,%al
movb $0x0a,%bl
mulb %bl
addb %al,%dl
movb %dl,%dh
movb %cl,%al
andb $0x0f,%al
movb %al,%dl
movb %cl,%al
shrb $0x04,%al
andb $0x0f,%al
movb $0x0a,%bl
mulb %bl
addb %al,%dl
movb %dl,%cl
movzbl %dh,%eax
movl $100,%ebx
mull %ebx
movl %eax,%edx
addb %cl,%dl
/* Save return value */
movl %edx,%edx
call switch_to_prot
.code32
/* Restore return value */
movl %edx,%eax
pop %edx
pop %ecx
pop %ebx
pop %ebp
ret
/*
* int getday(void);
*/
EXTERN(_getday)
.code32
push %ebp
push %ebx
push %ecx
push %edx
call switch_to_real
.code16
/* Get the date */
movb $4,%ah
int $0x1a
/* Convert from BCD to normal */
movb %dl,%al
andb $0x0f,%al
movb %al,%cl
movb %dl,%al
shrb $0x04,%al
andb $0x0f,%al
movb $0x0a,%bl
mulb %bl
addb %al,%cl
/* Save return value */
movzbl %cl,%edx
call switch_to_prot
.code32
/* Restore return value */
movl %edx,%eax
pop %edx
pop %ecx
pop %ebx
pop %ebp
ret
/*
* int getmonth(void);
*/
EXTERN(_getmonth)
.code32
push %ebp
push %ebx
push %ecx
push %edx
call switch_to_real
.code16
/* Get the date */
movb $4,%ah
int $0x1a
/* Convert from BCD to normal */
movb %dh,%al
andb $0x0f,%al
movb %al,%dl
movb %dh,%al
shrb $0x04,%al
andb $0x0f,%al
movb $0x0a,%bl
mulb %bl
addb %al,%dl
/* Save return value */
movzbl %dl,%edx
call switch_to_prot
.code32
/* Restore return value */
movl %edx,%eax
pop %edx
pop %ecx
pop %ebx
pop %ebp
ret
/*
* int gethour(void);
*/
EXTERN(_gethour)
.code32
push %ebp
push %ebx
push %ecx
push %edx
call switch_to_real
.code16
/* Get the time */
movb $2,%ah
int $0x1a
/* Convert from BCD to normal */
movb %ch,%al
andb $0x0f,%al
movb %al,%dl
movb %ch,%al
shrb $0x04,%al
andb $0x0f,%al
movb $0x0a,%bl
mulb %bl
addb %al,%dl
/* Save return value */
movzbl %dl,%edx
call switch_to_prot
.code32
/* Restore return value */
movl %edx,%eax
pop %edx
pop %ecx
pop %ebx
pop %ebp
ret
/*
* int getminute(void);
*/
EXTERN(_getminute)
.code32
push %ebp
push %ebx
push %ecx
push %edx
call switch_to_real
.code16
/* Get the time */
movb $2,%ah
int $0x1a
/* Convert from BCD to normal */
movb %cl,%al
andb $0x0f,%al
movb %al,%dl
movb %cl,%al
shrb $0x04,%al
andb $0x0f,%al
movb $0x0a,%bl
mulb %bl
addb %al,%dl
/* Save return value */
movzbl %dl,%edx
call switch_to_prot
.code32
/* Restore return value */
movl %edx,%eax
pop %edx
pop %ecx
pop %ebx
pop %ebp
ret
/*
* int getsecond(void);
*/
EXTERN(_getsecond)
.code32
push %ebp
push %ebx
push %ecx
push %edx
call switch_to_real
.code16
/* Get the time */
movb $2,%ah
int $0x1a
/* Convert from BCD to normal */
movb %dh,%al
andb $0x0f,%al
movb %al,%dl
movb %dh,%al
shrb $0x04,%al
andb $0x0f,%al
movb $0x0a,%bl
mulb %bl
addb %al,%dl
/* Save return value */
movzbl %dl,%edx
call switch_to_prot
.code32
/* Restore return value */
movl %edx,%eax
pop %edx
pop %ecx
pop %ebx
pop %ebp
ret

View file

@ -104,7 +104,7 @@ PCACHE_BLOCK CacheInternalAddBlockToCache(PCACHE_DRIVE CacheDrive, ULONG BlockNu
// We will need to add the block to the
// drive's list of cached blocks. So allocate
// the block memory.
CacheBlock = AllocateMemory(sizeof(CACHE_BLOCK));
CacheBlock = MmAllocateMemory(sizeof(CACHE_BLOCK));
if (CacheBlock == NULL)
{
return NULL;
@ -114,18 +114,18 @@ PCACHE_BLOCK CacheInternalAddBlockToCache(PCACHE_DRIVE CacheDrive, ULONG BlockNu
// allocate room for the block data
RtlZeroMemory(CacheBlock, sizeof(CACHE_BLOCK));
CacheBlock->BlockNumber = BlockNumber;
CacheBlock->BlockData = AllocateMemory(CacheDrive->BlockSize * CacheDrive->DriveGeometry.BytesPerSector);
CacheBlock->BlockData = MmAllocateMemory(CacheDrive->BlockSize * CacheDrive->DriveGeometry.BytesPerSector);
if (CacheBlock->BlockData ==NULL)
{
FreeMemory(CacheBlock);
MmFreeMemory(CacheBlock);
return NULL;
}
// Now try to read in the block
if (!DiskReadLogicalSectors(CacheDrive->DriveNumber, (BlockNumber * CacheDrive->BlockSize), CacheDrive->BlockSize, (PVOID)DISKREADBUFFER))
{
FreeMemory(CacheBlock->BlockData);
FreeMemory(CacheBlock);
MmFreeMemory(CacheBlock->BlockData);
MmFreeMemory(CacheBlock);
return NULL;
}
RtlCopyMemory(CacheBlock->BlockData, (PVOID)DISKREADBUFFER, CacheDrive->BlockSize * CacheDrive->DriveGeometry.BytesPerSector);
@ -182,8 +182,8 @@ BOOL CacheInternalFreeBlock(PCACHE_DRIVE CacheDrive)
RtlListRemoveEntry((PLIST_ITEM)CacheBlockToFree);
// Free the block memory and the block structure
FreeMemory(CacheBlockToFree->BlockData);
FreeMemory(CacheBlockToFree);
MmFreeMemory(CacheBlockToFree->BlockData);
MmFreeMemory(CacheBlockToFree);
// Update the cache data
CacheBlockCount--;

View file

@ -68,8 +68,8 @@ BOOL CacheInitializeDrive(ULONG DriveNumber)
{
NextCacheBlock = (PCACHE_BLOCK)RtlListGetNext((PLIST_ITEM)CacheManagerDrive.CacheBlockHead);
FreeMemory(CacheManagerDrive.CacheBlockHead->BlockData);
FreeMemory(CacheManagerDrive.CacheBlockHead);
MmFreeMemory(CacheManagerDrive.CacheBlockHead->BlockData);
MmFreeMemory(CacheManagerDrive.CacheBlockHead);
CacheManagerDrive.CacheBlockHead = NextCacheBlock;
}

View file

@ -1,4 +1,4 @@
/* $Id: portio.c,v 1.1 2001/11/28 10:26:52 bpalmer Exp $
/* $Id: portio.c,v 1.2 2002/06/06 05:58:35 bpalmer Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -10,7 +10,7 @@
*/
//#include <ddk/ntddk.h>
#include "freeldr.h"
#include <freeldr.h>
/* FUNCTIONS ****************************************************************/

View file

@ -27,7 +27,7 @@
//ULONG DebugPrintMask = DPRINT_WARNING | DPRINT_MEMORY | DPRINT_FILESYSTEM |
// DPRINT_UI | DPRINT_DISK | DPRINT_CACHE | DPRINT_REACTOS |
// DPRINT_LINUX;
ULONG DebugPrintMask = DPRINT_WARNING | DPRINT_FILESYSTEM |
ULONG DebugPrintMask = DPRINT_WARNING | DPRINT_UI | DPRINT_MEMORY |
/*DPRINT_CACHE |*/ DPRINT_LINUX;
//ULONG DebugPrintMask = DPRINT_INIFILE;

View file

@ -38,16 +38,7 @@ VOID DiskError(PUCHAR ErrorString)
DbgPrint((DPRINT_DISK, "%s\n", ErrorCodeString));
if (UserInterfaceUp)
{
MessageBox(ErrorCodeString);
}
else
{
printf("%s", ErrorCodeString);
printf("\nPress any key\n");
getch();
}
UiMessageBox(ErrorCodeString);
}
BOOL DiskReadLogicalSectors(ULONG DriveNumber, ULONG SectorNumber, ULONG SectorCount, PVOID Buffer)

View file

@ -55,7 +55,7 @@ BOOL DiskIsDriveCdRom(ULONG DriveNumber)
if (!BiosInt13ReadExtended(DriveNumber, 16, 1, Sector))
{
DiskError("Disk read error.");
FreeMemory(Sector);
MmFreeMemory(Sector);
return FALSE;
}
@ -224,7 +224,9 @@ BOOL DiskGetFirstExtendedPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PP
BOOL DiskReadBootRecord(ULONG DriveNumber, ULONG LogicalSectorNumber, PMASTER_BOOT_RECORD BootRecord)
{
#ifdef DEBUG
ULONG Index;
#endif
// Read master boot record
if (!DiskReadLogicalSectors(DriveNumber, LogicalSectorNumber, 1, (PVOID)DISKREADBUFFER))

View file

@ -17,19 +17,19 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "freeldr.h"
#include "rtl.h"
#include "fs.h"
#include "reactos.h"
#include "ui.h"
#include "arch.h"
#include "miscboot.h"
#include "linux.h"
#include "mm.h"
#include "inifile.h"
#include "debug.h"
#include "oslist.h"
#include "cache.h"
#include <freeldr.h>
#include <rtl.h>
#include <fs.h>
#include <reactos.h>
#include <ui.h>
#include <arch.h>
#include <miscboot.h>
#include <linux.h>
#include <mm.h>
#include <inifile.h>
#include <debug.h>
#include <oslist.h>
#include <video.h>
// Variable BootDrive moved to asmcode.S
//ULONG BootDrive = 0; // BIOS boot drive, 0-A:, 1-B:, 0x80-C:, 0x81-D:, etc.
@ -50,13 +50,18 @@ VOID BootMain(VOID)
LONG TimeOut;
ULONG SelectedOperatingSystem;
enable_a20();
EnableA20();
#ifdef DEBUG
DebugInit();
#endif
InitMemoryManager();
if (!MmInitializeMemoryManager())
{
printf("Press any key to reboot.\n");
getch();
return;
}
if (!IniFileInitialize())
{
@ -72,7 +77,7 @@ VOID BootMain(VOID)
return;
}
if (!InitUserInterface())
if (!UiInitialize())
{
printf("Press any key to reboot.\n");
getch();
@ -81,13 +86,13 @@ VOID BootMain(VOID)
if (!InitOperatingSystemList(&OperatingSystemSectionNames, &OperatingSystemDisplayNames, &OperatingSystemCount))
{
MessageBox("Press ENTER to reboot.\n");
UiMessageBox("Press ENTER to reboot.\n");
goto reboot;
}
if (OperatingSystemCount == 0)
{
MessageBox("There were no operating systems listed in freeldr.ini.\nPress ENTER to reboot.");
UiMessageBox("There were no operating systems listed in freeldr.ini.\nPress ENTER to reboot.");
goto reboot;
}
@ -97,23 +102,27 @@ VOID BootMain(VOID)
//
// Find all the message box settings and run them
//
ShowMessageBoxesInSection("FreeLoader");
UiShowMessageBoxesInSection("FreeLoader");
for (;;)
{
// Redraw the backdrop
UiDrawBackdrop();
// Show the operating system list menu
if (!DisplayMenu(OperatingSystemDisplayNames, OperatingSystemCount, DefaultOperatingSystem, TimeOut, &SelectedOperatingSystem))
if (!UiDisplayMenu(OperatingSystemDisplayNames, OperatingSystemCount, DefaultOperatingSystem, TimeOut, &SelectedOperatingSystem))
{
MessageBox("Press ENTER to reboot.\n");
UiMessageBox("Press ENTER to reboot.\n");
goto reboot;
}
TimeOut = -1;
DefaultOperatingSystem = SelectedOperatingSystem;
// Try to open the operating system section in the .ini file
if (!IniOpenSection(OperatingSystemSectionNames[SelectedOperatingSystem], &SectionId))
{
sprintf(SettingName, "Section [%s] not found in freeldr.ini.\n", OperatingSystemSectionNames[SelectedOperatingSystem]);
MessageBox(SettingName);
UiMessageBox(SettingName);
continue;
}
@ -121,7 +130,7 @@ VOID BootMain(VOID)
if (!IniReadSettingByName(SectionId, "BootType", SettingValue, 80))
{
sprintf(SettingName, "BootType= line not found in section [%s] in freeldr.ini.\n", OperatingSystemSectionNames[SelectedOperatingSystem]);
MessageBox(SettingName);
UiMessageBox(SettingName);
continue;
}
@ -149,8 +158,8 @@ VOID BootMain(VOID)
reboot:
clrscr();
showcursor();
VideoClearScreen();
VideoShowTextCursor();
return;
}

View file

@ -53,7 +53,7 @@ BOOL FatOpenVolume(ULONG DriveNumber, ULONG VolumeStartSector)
//
if (FatVolumeBootSector != NULL)
{
FreeMemory(FatVolumeBootSector);
MmFreeMemory(FatVolumeBootSector);
FatVolumeBootSector = NULL;
Fat32VolumeBootSector = NULL;
@ -62,7 +62,7 @@ BOOL FatOpenVolume(ULONG DriveNumber, ULONG VolumeStartSector)
//
// Now allocate the memory to hold the boot sector
//
FatVolumeBootSector = (PFAT_BOOTSECTOR) AllocateMemory(512);
FatVolumeBootSector = (PFAT_BOOTSECTOR) MmAllocateMemory(512);
Fat32VolumeBootSector = (PFAT32_BOOTSECTOR) FatVolumeBootSector;
//
@ -76,10 +76,11 @@ BOOL FatOpenVolume(ULONG DriveNumber, ULONG VolumeStartSector)
// Now try to read the boot sector
// If this fails then abort
if (!DiskReadLogicalSectors(DriveNumber, VolumeStartSector, 1, FatVolumeBootSector))
if (!DiskReadLogicalSectors(DriveNumber, VolumeStartSector, 1, (PVOID)DISKREADBUFFER))
{
return FALSE;
}
RtlCopyMemory(FatVolumeBootSector, (PVOID)DISKREADBUFFER, 512);
// Get the FAT type
FatType = FatDetermineFatType(FatVolumeBootSector);
@ -302,7 +303,7 @@ PVOID FatBufferDirectory(UINT32 DirectoryStartCluster, PUINT32 EntryCountPointer
// Attempt to allocate memory for directory buffer
//
DbgPrint((DPRINT_FILESYSTEM, "Trying to allocate (DirectorySize) %d bytes.\n", DirectorySize));
DirectoryBuffer = AllocateMemory(DirectorySize);
DirectoryBuffer = MmAllocateMemory(DirectorySize);
if (DirectoryBuffer == NULL)
{
@ -318,7 +319,7 @@ PVOID FatBufferDirectory(UINT32 DirectoryStartCluster, PUINT32 EntryCountPointer
{
if (!FatReadClusterChain(Fat32VolumeBootSector->RootDirStartCluster, 0xFFFFFFFF, DirectoryBuffer))
{
FreeMemory(DirectoryBuffer);
MmFreeMemory(DirectoryBuffer);
return NULL;
}
}
@ -332,7 +333,7 @@ PVOID FatBufferDirectory(UINT32 DirectoryStartCluster, PUINT32 EntryCountPointer
if (!FatReadVolumeSectors(FatDriveNumber, RootDirectoryStartSector, RootDirectorySectorCount, DirectoryBuffer))
{
FreeMemory(DirectoryBuffer);
MmFreeMemory(DirectoryBuffer);
return NULL;
}
}
@ -341,7 +342,7 @@ PVOID FatBufferDirectory(UINT32 DirectoryStartCluster, PUINT32 EntryCountPointer
{
if (!FatReadClusterChain(DirectoryStartCluster, 0xFFFFFFFF, DirectoryBuffer))
{
FreeMemory(DirectoryBuffer);
MmFreeMemory(DirectoryBuffer);
return NULL;
}
}
@ -626,11 +627,11 @@ BOOL FatLookupFile(PUCHAR FileName, PFAT_FILE_INFO FatFileInfoPointer)
//
if (!FatSearchDirectoryBufferForFile(DirectoryBuffer, DirectoryEntryCount, PathPart, &FatFileInfo))
{
FreeMemory(DirectoryBuffer);
MmFreeMemory(DirectoryBuffer);
return FALSE;
}
FreeMemory(DirectoryBuffer);
MmFreeMemory(DirectoryBuffer);
//
// If we have another sub-directory to go then
@ -639,7 +640,7 @@ BOOL FatLookupFile(PUCHAR FileName, PFAT_FILE_INFO FatFileInfoPointer)
if ((i+1) < NumberOfPathParts)
{
DirectoryStartCluster = FatFileInfo.FileFatChain[0];
FreeMemory(FatFileInfo.FileFatChain);
MmFreeMemory(FatFileInfo.FileFatChain);
}
}
@ -857,7 +858,7 @@ FILE* FatOpenFile(PUCHAR FileName)
return NULL;
}
FileHandle = AllocateMemory(sizeof(FAT_FILE_INFO));
FileHandle = MmAllocateMemory(sizeof(FAT_FILE_INFO));
if (FileHandle == NULL)
{
@ -921,7 +922,7 @@ PUINT32 FatGetClusterChainArray(UINT32 StartCluster)
//
// Allocate array memory
//
ArrayPointer = AllocateMemory(ArraySize);
ArrayPointer = MmAllocateMemory(ArraySize);
if (ArrayPointer == NULL)
{
@ -954,7 +955,7 @@ PUINT32 FatGetClusterChainArray(UINT32 StartCluster)
//
if (!FatGetFatEntry(StartCluster, &StartCluster))
{
FreeMemory(ArrayPointer);
MmFreeMemory(ArrayPointer);
return NULL;
}
}
@ -1256,6 +1257,15 @@ ULONG FatGetFilePointer(FILE *FileHandle)
BOOL FatReadVolumeSectors(ULONG DriveNumber, ULONG SectorNumber, ULONG SectorCount, PVOID Buffer)
{
//return DiskReadMultipleLogicalSectors(DriveNumber, SectorNumber + FatVolumeBootSector->HiddenSectors, SectorCount, Buffer);
//GEOMETRY DiskGeometry;
//BOOL ReturnValue;
//if (!DiskGetDriveGeometry(DriveNumber, &DiskGeometry))
//{
// return FALSE;
//}
//ReturnValue = DiskReadLogicalSectors(DriveNumber, SectorNumber + FatVolumeBootSector->HiddenSectors, SectorCount, (PVOID)DISKREADBUFFER);
//RtlCopyMemory(Buffer, (PVOID)DISKREADBUFFER, SectorCount * DiskGeometry.BytesPerSector);
//return ReturnValue;
return CacheReadDiskSectors(DriveNumber, SectorNumber + FatVolumeBootSector->HiddenSectors, SectorCount, Buffer);
}

View file

@ -42,16 +42,7 @@ VOID FileSystemError(PUCHAR ErrorString)
{
DbgPrint((DPRINT_FILESYSTEM, "%s\n", ErrorString));
if (UserInterfaceUp)
{
MessageBox(ErrorString);
}
else
{
printf("%s", ErrorString);
printf("\nPress any key\n");
getch();
}
UiMessageBox(ErrorString);
}
/*

View file

@ -49,19 +49,19 @@ BOOL IsoOpenVolume(ULONG DriveNumber)
IsoRootSector = 0;
IsoRootLength = 0;
Pvd = AllocateMemory(SECTORSIZE);
Pvd = MmAllocateMemory(SECTORSIZE);
if (!DiskReadLogicalSectors(DriveNumber, 16, 1, Pvd))
{
FileSystemError("Failed to read the PVD.");
FreeMemory(Pvd);
MmFreeMemory(Pvd);
return FALSE;
}
IsoRootSector = Pvd->RootDirRecord.ExtentLocationL;
IsoRootLength = Pvd->RootDirRecord.DataLengthL;
FreeMemory(Pvd);
MmFreeMemory(Pvd);
DbgPrint((DPRINT_FILESYSTEM, "IsoRootSector = %u IsoRootLegth = %u\n", IsoRootSector, IsoRootLength));
@ -142,7 +142,7 @@ static PVOID IsoBufferDirectory(UINT32 DirectoryStartSector, UINT32 DirectoryLen
// Attempt to allocate memory for directory buffer
//
DbgPrint((DPRINT_FILESYSTEM, "Trying to allocate (DirectoryLength) %d bytes.\n", DirectoryLength));
DirectoryBuffer = AllocateMemory(DirectoryLength);
DirectoryBuffer = MmAllocateMemory(DirectoryLength);
if (DirectoryBuffer == NULL)
{
@ -157,7 +157,7 @@ static PVOID IsoBufferDirectory(UINT32 DirectoryStartSector, UINT32 DirectoryLen
//
if (!DiskReadLogicalSectors(IsoDriveNumber, DirectoryStartSector, SectorCount, DirectoryBuffer))
{
FreeMemory(DirectoryBuffer);
MmFreeMemory(DirectoryBuffer);
return NULL;
}
@ -290,11 +290,11 @@ static BOOL IsoLookupFile(PUCHAR FileName, PISO_FILE_INFO IsoFileInfoPointer)
//
if (!IsoSearchDirectoryBufferForFile(DirectoryBuffer, DirectoryLength, PathPart, &IsoFileInfo))
{
FreeMemory(DirectoryBuffer);
MmFreeMemory(DirectoryBuffer);
return FALSE;
}
FreeMemory(DirectoryBuffer);
MmFreeMemory(DirectoryBuffer);
//
// If we have another sub-directory to go then
@ -331,7 +331,7 @@ FILE* IsoOpenFile(PUCHAR FileName)
return NULL;
}
FileHandle = AllocateMemory(sizeof(ISO_FILE_INFO));
FileHandle = MmAllocateMemory(sizeof(ISO_FILE_INFO));
if (FileHandle == NULL)
{
@ -354,7 +354,7 @@ static BOOL IsoReadPartialSector(ULONG SectorNumber, ULONG StartingOffset, ULONG
DbgPrint((DPRINT_FILESYSTEM, "IsoReadPartialSector() SectorNumber = %d StartingOffset = %d Length = %d Buffer = 0x%x\n", SectorNumber, StartingOffset, Length, Buffer));
SectorBuffer = AllocateMemory(SECTORSIZE);
SectorBuffer = MmAllocateMemory(SECTORSIZE);
if (SectorBuffer == NULL)
{
return FALSE;
@ -362,13 +362,13 @@ static BOOL IsoReadPartialSector(ULONG SectorNumber, ULONG StartingOffset, ULONG
if (!DiskReadLogicalSectors(IsoDriveNumber, SectorNumber, 1, SectorBuffer))
{
FreeMemory(SectorBuffer);
MmFreeMemory(SectorBuffer);
return FALSE;
}
memcpy(Buffer, ((PVOID)SectorBuffer + StartingOffset), Length);
FreeMemory(SectorBuffer);
MmFreeMemory(SectorBuffer);
return TRUE;
}

View file

@ -54,9 +54,7 @@
#ifndef ASM
void enable_a20(void);
void stop_floppy(void);
extern unsigned long FreeLoaderModuleEnd;
void EnableA20(void);
void StopFloppyMotor(void);
#endif /* ! ASM */

View file

@ -91,7 +91,7 @@ BOOL BiosInt13ReadExtended(ULONG Drive, ULONG Sector, ULONG SectorCount, PVOID B
BOOL BiosInt13ExtensionsSupported(ULONG Drive);
ULONG BiosInt13GetLastErrorCode(VOID);
void stop_floppy(void); // Implemented in asmcode.S
void StopFloppyMotor(void); // Implemented in asmcode.S
int get_heads(int drive); // Implemented in asmcode.S
int get_cylinders(int drive); // Implemented in asmcode.S
int get_sectors(int drive); // Implemented in asmcode.S

View file

@ -21,19 +21,29 @@
#ifndef __MEMORY_H
#define __MEMORY_H
#include <multiboot.h>
#define MEMTYPE_USABLE 0x01
#define MEMTYPE_RESERVED 0x02
#define MEMTYPE_ACPI_RECLAIM 0x03
#define MEMTYPE_ACPI_NVS 0x04
typedef struct
{
ULONG BaseAddressLow;
ULONG BaseAddressHigh;
ULONG LengthLow;
ULONG LengthHigh;
ULONG Type;
ULONG Reserved;
} PACKED BIOS_MEMORY_MAP, *PBIOS_MEMORY_MAP;
VOID InitMemoryManager(VOID);
PVOID AllocateMemory(ULONG NumberOfBytes);
VOID FreeMemory(PVOID MemBlock);
ULONG GetSystemMemorySize(VOID); // Returns the amount of total usuable memory available to the memory manager
ULONG GetSystemMemorySize(VOID); // Returns the amount of total memory in the system
// These functions are implemented in mem.S
int GetExtendedMemorySize(void); // Returns extended memory size in KB
int GetConventionalMemorySize(void); // Returns conventional memory size in KB
int GetBiosMemoryMap(memory_map_t *mem_map); // Fills mem_map structure with BIOS memory map and returns length of memory map
ULONG GetExtendedMemorySize(VOID); // Returns extended memory size in KB
ULONG GetConventionalMemorySize(VOID); // Returns conventional memory size in KB
ULONG GetBiosMemoryMap(BIOS_MEMORY_MAP BiosMemoryMap[32]); // Fills mem_map structure with BIOS memory map and returns length of memory map
@ -46,8 +56,9 @@ int GetBiosMemoryMap(memory_map_t *mem_map); // Fills mem_map structure with BI
//BOOL MmInitializeMemoryManager(ULONG LowMemoryStart, ULONG LowMemoryLength);
//PVOID MmAllocateMemory(ULONG MemorySize);
//VOID MmFreeMemory(PVOID MemoryPointer);
BOOL MmInitializeMemoryManager(VOID);
PVOID MmAllocateMemory(ULONG MemorySize);
VOID MmFreeMemory(PVOID MemoryPointer);
//PVOID MmAllocateLowMemory(ULONG MemorySize);
//VOID MmFreeLowMemory(PVOID MemoryPointer);
//PVOID MmAllocateMemoryFrom1Mb(ULONG MemorySize);

View file

@ -69,20 +69,14 @@ int isxdigit(int c);
char * convert_to_ascii(char *buf, int c, ...);
void putchar(int ch); // Implemented in asmcode.S
void clrscr(void); // Implemented in asmcode.S
int kbhit(void); // Implemented in asmcode.S
int getch(void); // Implemented in asmcode.S
void gotoxy(int x, int y); // Implemented in asmcode.S
int getyear(void); // Implemented in asmcode.S
int getday(void); // Implemented in asmcode.S
int getmonth(void); // Implemented in asmcode.S
int gethour(void); // Implemented in asmcode.S
int getminute(void); // Implemented in asmcode.S
int getsecond(void); // Implemented in asmcode.S
void hidecursor(void); // Implemented in asmcode.S
void showcursor(void); // Implemented in asmcode.S
int wherex(void); // Implemented in asmcode.S
int wherey(void); // Implemented in asmcode.S
#ifndef max
#define max(a, b) (((a) > (b)) ? (a) : (b))

View file

@ -17,141 +17,68 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __TUI_H
#define __TUI_H
#ifndef __UI_H
#define __UI_H
#define SCREEN_MEM 0xB8000
#define TITLE_BOX_HEIGHT 5
// Initialize Textual-User-Interface
BOOL InitUserInterface(VOID);
// Fills the entire screen with a backdrop
void DrawBackdrop(void);
// Fills the area specified with cFillChar and cAttr
void FillArea(int nLeft, int nTop, int nRight, int nBottom, char cFillChar, char cAttr /* Color Attributes */);
// Draws a shadow on the bottom and right sides of the area specified
void DrawShadow(int nLeft, int nTop, int nRight, int nBottom);
// Draws a box around the area specified
void DrawBox(int nLeft, int nTop, int nRight, int nBottom, int nVertStyle, int nHorzStyle, int bFill, int bShadow, char cAttr);
// Draws text at coordinates specified
void DrawText(int nX, int nY, char *text, char cAttr);
// Draws text at the very bottom line on the screen
void DrawStatusText(char *text);
// Updates the date and time
void UpdateDateTime(void);
// Saves the screen so that it can be restored later
void SaveScreen(char *buffer);
// Restores the screen from a previous save
void RestoreScreen(char *buffer);
// Displays a message box on the screen with an ok button
void MessageBox(char *text);
// Adds a line of text to the message box buffer
void MessageLine(char *text);
// Returns true if color is valid
BOOL IsValidColor(char *color);
// Converts the text color into it's equivalent color value
char TextToColor(char *color);
// Returns true if fill is valid
BOOL IsValidFillStyle(char *fill);
// Converts the text fill into it's equivalent fill value
char TextToFillStyle(char *fill);
// Draws the progress bar showing nPos percent filled
void DrawProgressBar(int nPos);
// Displays all the message boxes in a given section
void ShowMessageBoxesInSection(PUCHAR SectionName);
extern ULONG UiScreenWidth; // Screen Width
extern ULONG UiScreenHeight; // Screen Height
/*
* Combines the foreground and background colors into a single attribute byte
*/
#define ATTR(cFore, cBack) ((cBack << 4)|cFore)
extern UCHAR UiStatusBarFgColor; // Status bar foreground color
extern UCHAR UiStatusBarBgColor; // Status bar background color
extern UCHAR UiBackdropFgColor; // Backdrop foreground color
extern UCHAR UiBackdropBgColor; // Backdrop background color
extern UCHAR UiBackdropFillStyle; // Backdrop fill style
extern UCHAR UiTitleBoxFgColor; // Title box foreground color
extern UCHAR UiTitleBoxBgColor; // Title box background color
extern UCHAR UiMessageBoxFgColor; // Message box foreground color
extern UCHAR UiMessageBoxBgColor; // Message box background color
extern UCHAR UiMenuFgColor; // Menu foreground color
extern UCHAR UiMenuBgColor; // Menu background color
extern UCHAR UiTextColor; // Normal text color
extern UCHAR UiSelectedTextColor; // Selected text color
extern UCHAR UiSelectedTextBgColor; // Selected text background color
extern UCHAR UiTitleBoxTitleText[260]; // Title box's title text
/*
* Fill styles for DrawBackdrop()
*/
#define LIGHT_FILL 0xB0
#define MEDIUM_FILL 0xB1
#define DARK_FILL 0xB2
extern PUCHAR UiMessageBoxLineText;
/*
* Screen colors
*/
#define COLOR_BLACK 0
#define COLOR_BLUE 1
#define COLOR_GREEN 2
#define COLOR_CYAN 3
#define COLOR_RED 4
#define COLOR_MAGENTA 5
#define COLOR_BROWN 6
#define COLOR_GRAY 7
extern BOOL UserInterfaceUp; // Tells us if the user interface is displayed
#define COLOR_DARKGRAY 8
#define COLOR_LIGHTBLUE 9
#define COLOR_LIGHTGREEN 10
#define COLOR_LIGHTCYAN 11
#define COLOR_LIGHTRED 12
#define COLOR_LIGHTMAGENTA 13
#define COLOR_YELLOW 14
#define COLOR_WHITE 15
extern UCHAR UiMonthNames[12][15];
/* Add COLOR_BLINK to a background to cause blinking */
#define COLOR_BLINK 8
///////////////////////////////////////////////////////////////////////////////////////
//
// User Interface Functions
//
///////////////////////////////////////////////////////////////////////////////////////
BOOL UiInitialize(VOID); // Initialize User-Interface
VOID UiDrawBackdrop(VOID); // Fills the entire screen with a backdrop
VOID UiFillArea(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, UCHAR FillChar, UCHAR Attr /* Color Attributes */); // Fills the area specified with FillChar and Attr
VOID UiDrawShadow(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom); // Draws a shadow on the bottom and right sides of the area specified
VOID UiDrawBox(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, UCHAR VertStyle, UCHAR HorzStyle, BOOL Fill, BOOL Shadow, UCHAR Attr); // Draws a box around the area specified
VOID UiDrawText(ULONG X, ULONG Y, PUCHAR Text, UCHAR Attr); // Draws text at coordinates specified
VOID UiDrawCenteredText(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, PUCHAR TextString, UCHAR Attr); // Draws centered text at the coordinates specified and clips the edges
VOID UiDrawStatusText(PUCHAR StatusText); // Draws text at the very bottom line on the screen
VOID UiUpdateDateTime(VOID); // Updates the date and time
VOID UiMessageBox(PUCHAR MessageText); // Displays a message box on the screen with an ok button
VOID UiMessageBoxCritical(PUCHAR MessageText); // Displays a message box on the screen with an ok button using no system resources
VOID UiMessageLine(PUCHAR MessageText); // Adds a line of text to the message box buffer
VOID UiDrawProgressBarCenter(ULONG Position, ULONG Range); // Draws the progress bar showing nPos percent filled
VOID UiDrawProgressBar(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, ULONG Position, ULONG Range); // Draws the progress bar showing nPos percent filled
VOID UiShowMessageBoxesInSection(PUCHAR SectionName); // Displays all the message boxes in a given section
/*
* Defines for IBM box drawing characters
*/
#define HORZ (0xc4) /* Single horizontal line */
#define D_HORZ (0xcd) /* Double horizontal line.*/
#define VERT (0xb3) /* Single vertical line */
#define D_VERT (0xba) /* Double vertical line. */
/* Definitions for corners, depending on HORIZ and VERT */
#define UL (0xda)
#define UR (0xbf) /* HORZ and VERT */
#define LL (0xc0)
#define LR (0xd9)
#define D_UL (0xc9)
#define D_UR (0xbb) /* D_HORZ and D_VERT */
#define D_LL (0xc8)
#define D_LR (0xbc)
#define HD_UL (0xd5)
#define HD_UR (0xb8) /* D_HORZ and VERT */
#define HD_LL (0xd4)
#define HD_LR (0xbe)
#define VD_UL (0xd6)
#define VD_UR (0xb7) /* HORZ and D_VERT */
#define VD_LL (0xd3)
#define VD_LR (0xbd)
// Key codes
#define KEY_EXTENDED 0x00
#define KEY_ENTER 0x0D
#define KEY_SPACE 0x20
#define KEY_UP 0x48
#define KEY_DOWN 0x50
#define KEY_LEFT 0x4B
#define KEY_RIGHT 0x4D
#define KEY_ESC 0x1B
#define KEY_F1 0x3B
#define KEY_F2 0x3C
#define KEY_F3 0x3D
#define KEY_F4 0x3E
#define KEY_F5 0x3F
#define KEY_F6 0x40
#define KEY_F7 0x41
#define KEY_F8 0x42
#define KEY_F9 0x43
#define KEY_F10 0x44
UCHAR UiTextToColor(PUCHAR ColorText); // Converts the text color into it's equivalent color value
UCHAR UiTextToFillStyle(PUCHAR FillStyleText); // Converts the text fill into it's equivalent fill value
VOID UiTruncateStringEllipsis(PUCHAR StringText, ULONG MaxChars); // Truncates a string to MaxChars by adding an ellipsis on the end '...'
///////////////////////////////////////////////////////////////////////////////////////
//
// Menu Functions
//
///////////////////////////////////////////////////////////////////////////////////////
BOOL DisplayMenu(PUCHAR MenuItemList[], ULONG MenuItemCount, ULONG DefaultMenuItem, LONG MenuTimeOut, PULONG SelectedMenuItem);
BOOL UiDisplayMenu(PUCHAR MenuItemList[], ULONG MenuItemCount, ULONG DefaultMenuItem, LONG MenuTimeOut, PULONG SelectedMenuItem);
#endif // #defined __TUI_H
#endif // #defined __UI_H

View file

@ -22,19 +22,21 @@
/* just some stuff */
#define VERSION "FreeLoader v1.2.2"
#define COPYRIGHT "Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>"
#define VERSION "FreeLoader v1.3"
#define COPYRIGHT "Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>"
#define AUTHOR_EMAIL "<brianp@sginet.com>"
#define BY_AUTHOR "by Brian Palmer"
// FreeLoader version defines
//
// NOTE:
// If you fix bugs then you increment the patch version
// If you add features then you increment the minor version
// If you add major functionality then you increment the major version
// If you add features then you increment the minor version and zero the patch version
// If you add major functionality then you increment the major version and zero the minor & patch versions
//
#define FREELOADER_MAJOR_VERSION 1
#define FREELOADER_MINOR_VERSION 2
#define FREELOADER_PATCH_VERSION 2
#define FREELOADER_MINOR_VERSION 3
#define FREELOADER_PATCH_VERSION 0
PUCHAR GetFreeLoaderVersionString(VOID);

View file

@ -0,0 +1,79 @@
/*
* FreeLoader
* Copyright (C) 1998-2002 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 __VIDEO_H
#define __VIDEO_H
#define VIDEOCARD_CGA_OR_OTHER 0
#define VIDEOCARD_EGA 1
#define VIDEOCARD_VGA 2
#define VIDEOMODE_NORMAL_TEXT 0
#define VIDEOMODE_EXTENDED_TEXT 1
#define VIDEOMODE_80X28 0x501C
#define VIDEOMODE_80X30 0x501E
#define VIDEOMODE_80X34 0x5022
#define VIDEOMODE_80X43 0x502B
#define VIDEOMODE_80X60 0x503C
#define VIDEOPORT_PALETTE_READ 0x03C7
#define VIDEOPORT_PALETTE_WRITE 0x03C8
#define VIDEOPORT_PALETTE_DATA 0x03C9
#define VIDEOPORT_VERTICAL_RETRACE 0x03DA
VOID BiosSetVideoMode(ULONG VideoMode); // Implemented in biosvid.S
VOID BiosSetVideoFont8x8(VOID); // Implemented in biosvid.S
VOID BiosSetVideoFont8x14(VOID); // Implemented in biosvid.S
VOID BiosSetVideoFont8x16(VOID); // Implemented in biosvid.S
VOID BiosSelectAlternatePrintScreen(VOID); // Implemented in biosvid.S
VOID BiosDisableCursorEmulation(VOID); // Implemented in biosvid.S
VOID BiosDefineCursor(ULONG StartScanLine, ULONG EndScanLine); // Implemented in biosvid.S
ULONG BiosDetectVideoCard(VOID); // Implemented in biosvid.S
VOID BiosSet200ScanLines(VOID); // Implemented in biosvid.S, must be called right before BiosSetVideoMode()
VOID BiosSet350ScanLines(VOID); // Implemented in biosvid.S, must be called right before BiosSetVideoMode()
VOID BiosSet400ScanLines(VOID); // Implemented in biosvid.S, must be called right before BiosSetVideoMode()
VOID BiosSet480ScanLines(VOID); // Implemented in biosvid.S, must be called right after BiosSetVideoMode()
VOID BiosSetVideoDisplayEnd(VOID); // Implemented in biosvid.S
VOID VideoSetTextCursorPosition(ULONG X, ULONG Y); // Implemented in biosvid.S
VOID VideoHideTextCursor(VOID); // Implemented in biosvid.S
VOID VideoShowTextCursor(VOID); // Implemented in biosvid.S
ULONG VideoGetTextCursorPositionX(VOID); // Implemented in biosvid.S
ULONG VideoGetTextCursorPositionY(VOID); // Implemented in biosvid.S
BOOL VideoSetMode(ULONG VideoMode);
BOOL VideoSetMode80x25(VOID); // Sets 80x25
BOOL VideoSetMode80x50_80x43(VOID); // Sets 80x50 (VGA) or 80x43 (EGA) 8-pixel mode
BOOL VideoSetMode80x28(VOID); // Sets 80x28. Works on all VGA's. Standard 80x25 with 14-point font
BOOL VideoSetMode80x43(VOID); // Sets 80x43. Works on all VGA's. It's a 350-scanline mode with 8-pixel font.
BOOL VideoSetMode80x30(VOID); // Sets 80x30. Works on all VGA's. 480 scanlines, 16-pixel font.
BOOL VideoSetMode80x34(VOID); // Sets 80x34. Works on all VGA's. 480 scanlines, 14-pixel font.
BOOL VideoSetMode80x60(VOID); // Sets 80x60. Works on all VGA's. 480 scanlines, 8-pixel font.
ULONG VideoGetCurrentModeResolutionX(VOID);
ULONG VideoGetCurrentModeResolutionY(VOID);
ULONG VideoGetCurrentMode(VOID);
VOID VideoClearScreen(VOID);
VOID VideoWaitForVerticalRetrace(VOID);
VOID VideoSetPaletteColor(UCHAR Color, UCHAR Red, UCHAR Green, UCHAR Blue);
VOID VideoGetPaletteColor(UCHAR Color, PUCHAR Red, PUCHAR Green, PUCHAR Blue);
#endif // defined __VIDEO_H

View file

@ -49,7 +49,7 @@ BOOL IniFileInitialize(VOID)
// Get the file size & allocate enough memory for it
FreeLoaderIniFileSize = GetFileSize(Freeldr_Ini);
FreeLoaderIniFileData = AllocateMemory(FreeLoaderIniFileSize);
FreeLoaderIniFileData = MmAllocateMemory(FreeLoaderIniFileSize);
// If we are out of memory then return FALSE
if (FreeLoaderIniFileData == NULL)
@ -63,7 +63,7 @@ BOOL IniFileInitialize(VOID)
if (!ReadFile(Freeldr_Ini, FreeLoaderIniFileSize, NULL, FreeLoaderIniFileData))
{
CloseFile(Freeldr_Ini);
FreeMemory(FreeLoaderIniFileData);
MmFreeMemory(FreeLoaderIniFileData);
return FALSE;
}
@ -72,7 +72,7 @@ BOOL IniFileInitialize(VOID)
// Parse the .ini file data
Success = IniParseFile(FreeLoaderIniFileData, FreeLoaderIniFileSize);
FreeMemory(FreeLoaderIniFileData);
MmFreeMemory(FreeLoaderIniFileData);
return Success;
}

View file

@ -65,7 +65,9 @@ BOOL IniReadSettingByNumber(ULONG SectionId, ULONG SettingNumber, PUCHAR Setting
{
PINI_SECTION Section = (PINI_SECTION)SectionId;
PINI_SECTION_ITEM SectionItem;
#ifdef DEBUG
ULONG RealSettingNumber = SettingNumber;
#endif
DbgPrint((DPRINT_INIFILE, "IniReadSettingByNumber() SectionId = 0x%x\n", SectionId));

View file

@ -43,7 +43,7 @@ BOOL IniParseFile(PUCHAR IniFileData, ULONG IniFileSize)
// Start with an 80-byte buffer
IniFileLineSize = 80;
IniFileLine = AllocateMemory(IniFileLineSize);
IniFileLine = MmAllocateMemory(IniFileLineSize);
if (!IniFileLine)
{
return FALSE;
@ -58,8 +58,8 @@ BOOL IniParseFile(PUCHAR IniFileData, ULONG IniFileSize)
if (IniFileLineSize < IniGetNextLineSize(IniFileData, IniFileSize, CurrentOffset))
{
IniFileLineSize = IniGetNextLineSize(IniFileData, IniFileSize, CurrentOffset);
FreeMemory(IniFileLine);
IniFileLine = AllocateMemory(IniFileLineSize);
MmFreeMemory(IniFileLine);
IniFileLine = MmAllocateMemory(IniFileLineSize);
if (!IniFileLine)
{
return FALSE;
@ -81,21 +81,21 @@ BOOL IniParseFile(PUCHAR IniFileData, ULONG IniFileSize)
if (IniIsSectionName(IniFileLine, LineLength))
{
// Allocate a new section structure
CurrentSection = AllocateMemory(sizeof(INI_SECTION));
CurrentSection = MmAllocateMemory(sizeof(INI_SECTION));
if (!CurrentSection)
{
FreeMemory(IniFileLine);
MmFreeMemory(IniFileLine);
return FALSE;
}
RtlZeroMemory(CurrentSection, sizeof(INI_SECTION));
// Allocate the section name buffer
CurrentSection->SectionName = AllocateMemory(IniGetSectionNameSize(IniFileLine, LineLength));
CurrentSection->SectionName = MmAllocateMemory(IniGetSectionNameSize(IniFileLine, LineLength));
if (!CurrentSection->SectionName)
{
FreeMemory(CurrentSection);
FreeMemory(IniFileLine);
MmFreeMemory(CurrentSection);
MmFreeMemory(IniFileLine);
return FALSE;
}
@ -129,30 +129,30 @@ BOOL IniParseFile(PUCHAR IniFileData, ULONG IniFileSize)
}
// Allocate a new item structure
CurrentItem = AllocateMemory(sizeof(INI_SECTION_ITEM));
CurrentItem = MmAllocateMemory(sizeof(INI_SECTION_ITEM));
if (!CurrentItem)
{
FreeMemory(IniFileLine);
MmFreeMemory(IniFileLine);
return FALSE;
}
RtlZeroMemory(CurrentItem, sizeof(INI_SECTION_ITEM));
// Allocate the setting name buffer
CurrentItem->ItemName = AllocateMemory(IniGetSettingNameSize(IniFileLine, LineLength));
CurrentItem->ItemName = MmAllocateMemory(IniGetSettingNameSize(IniFileLine, LineLength));
if (!CurrentItem->ItemName)
{
FreeMemory(CurrentItem);
FreeMemory(IniFileLine);
MmFreeMemory(CurrentItem);
MmFreeMemory(IniFileLine);
return FALSE;
}
// Allocate the setting value buffer
CurrentItem->ItemValue = AllocateMemory(IniGetSettingValueSize(IniFileLine, LineLength));
CurrentItem->ItemValue = MmAllocateMemory(IniGetSettingValueSize(IniFileLine, LineLength));
if (!CurrentItem->ItemValue)
{
FreeMemory(CurrentItem);
FreeMemory(IniFileLine);
MmFreeMemory(CurrentItem);
MmFreeMemory(IniFileLine);
return FALSE;
}

View file

@ -18,17 +18,18 @@
*/
#include "freeldr.h"
#include "arch.h"
#include "miscboot.h"
#include "rtl.h"
#include "fs.h"
#include "ui.h"
#include "linux.h"
#include "debug.h"
#include "mm.h"
#include "inifile.h"
#include "oslist.h" // For RemoveQuotes()
#include <freeldr.h>
#include <arch.h>
#include <miscboot.h>
#include <rtl.h>
#include <fs.h>
#include <ui.h>
#include <linux.h>
#include <debug.h>
#include <mm.h>
#include <inifile.h>
#include <oslist.h> // For RemoveQuotes()
#include <video.h>
PLINUX_BOOTSECTOR LinuxBootSector = NULL;
PLINUX_SETUPSECTOR LinuxSetupSector = NULL;
@ -46,7 +47,7 @@ VOID LoadAndBootLinux(PUCHAR OperatingSystemName)
PFILE LinuxKernel = NULL;
UCHAR TempString[260];
DrawBackdrop();
UiDrawBackdrop();
// Parse the .ini file section
if (!LinuxParseIniSection(OperatingSystemName))
@ -57,7 +58,7 @@ VOID LoadAndBootLinux(PUCHAR OperatingSystemName)
// Open the boot volume
if (!OpenDiskDrive(BootDrive, BootPartition))
{
MessageBox("Failed to open boot drive.");
UiMessageBox("Failed to open boot drive.");
goto LinuxBootFailed;
}
@ -66,7 +67,7 @@ VOID LoadAndBootLinux(PUCHAR OperatingSystemName)
if (LinuxKernel == NULL)
{
sprintf(TempString, "Linux kernel \'%s\' not found.", LinuxKernelName);
MessageBox(TempString);
UiMessageBox(TempString);
goto LinuxBootFailed;
}
@ -119,10 +120,10 @@ VOID LoadAndBootLinux(PUCHAR OperatingSystemName)
RtlCopyMemory((PVOID)0x90200, LinuxSetupSector, SetupSectorSize);
RtlCopyMemory((PVOID)0x99000, LinuxCommandLine, LinuxCommandLineSize);
showcursor();
clrscr();
VideoShowTextCursor();
VideoClearScreen();
stop_floppy();
StopFloppyMotor();
if (LinuxSetupSector->LoadFlags & LINUX_FLAG_LOAD_HIGH)
{
@ -143,11 +144,11 @@ LinuxBootFailed:
if (LinuxBootSector != NULL)
{
FreeMemory(LinuxBootSector);
MmFreeMemory(LinuxBootSector);
}
if (LinuxSetupSector != NULL)
{
FreeMemory(LinuxSetupSector);
MmFreeMemory(LinuxSetupSector);
}
LinuxBootSector = NULL;
@ -167,19 +168,19 @@ BOOL LinuxParseIniSection(PUCHAR OperatingSystemName)
ULONG SectionId;
// Find all the message box settings and run them
ShowMessageBoxesInSection(OperatingSystemName);
UiShowMessageBoxesInSection(OperatingSystemName);
// Try to open the operating system section in the .ini file
if (!IniOpenSection(OperatingSystemName, &SectionId))
{
sprintf(SettingName, "Section [%s] not found in freeldr.ini.\n", OperatingSystemName);
MessageBox(SettingName);
UiMessageBox(SettingName);
return FALSE;
}
if (!IniReadSettingByName(SectionId, "BootDrive", SettingValue, 260))
{
MessageBox("Boot drive not specified for selected OS!");
UiMessageBox("Boot drive not specified for selected OS!");
return FALSE;
}
@ -194,7 +195,7 @@ BOOL LinuxParseIniSection(PUCHAR OperatingSystemName)
// Get the kernel name
if (!IniReadSettingByName(SectionId, "Kernel", LinuxKernelName, 260))
{
MessageBox("Linux kernel filename not specified for selected OS!");
UiMessageBox("Linux kernel filename not specified for selected OS!");
return FALSE;
}
@ -217,7 +218,7 @@ BOOL LinuxParseIniSection(PUCHAR OperatingSystemName)
BOOL LinuxReadBootSector(PFILE LinuxKernelFile)
{
// Allocate memory for boot sector
LinuxBootSector = (PLINUX_BOOTSECTOR)AllocateMemory(512);
LinuxBootSector = (PLINUX_BOOTSECTOR)MmAllocateMemory(512);
if (LinuxBootSector == NULL)
{
return FALSE;
@ -233,7 +234,7 @@ BOOL LinuxReadBootSector(PFILE LinuxKernelFile)
// Check for validity
if (LinuxBootSector->BootFlag != LINUX_BOOT_SECTOR_MAGIC)
{
MessageBox("Invalid boot sector magic (0xaa55)");
UiMessageBox("Invalid boot sector magic (0xaa55)");
return FALSE;
}
@ -280,7 +281,7 @@ BOOL LinuxReadSetupSector(PFILE LinuxKernelFile)
}
// Allocate memory for setup sectors
LinuxSetupSector = (PLINUX_SETUPSECTOR)AllocateMemory(SetupSectorSize);
LinuxSetupSector = (PLINUX_SETUPSECTOR)MmAllocateMemory(SetupSectorSize);
if (LinuxSetupSector == NULL)
{
return FALSE;
@ -323,9 +324,9 @@ BOOL LinuxReadKernel(PFILE LinuxKernelFile)
ULONG BytesLoaded;
UCHAR StatusText[260];
sprintf(StatusText, " Loading %s", LinuxKernelName);
DrawStatusText(StatusText);
DrawProgressBar(0);
sprintf(StatusText, "Loading %s", LinuxKernelName);
UiDrawStatusText(StatusText);
UiDrawProgressBarCenter(0, 100);
// Calc kernel size
LinuxKernelSize = GetFileSize(LinuxKernelFile) - (512 + SetupSectorSize);
@ -342,7 +343,7 @@ BOOL LinuxReadKernel(PFILE LinuxKernelFile)
BytesLoaded += 0x4000;
LoadAddress += 0x4000;
DrawProgressBar( (BytesLoaded * 100) / LinuxKernelSize );
UiDrawProgressBarCenter(BytesLoaded, LinuxKernelSize);
}
return TRUE;
@ -378,7 +379,7 @@ BOOL LinuxCheckKernelVersion(VOID)
if ((NewStyleLinuxKernel == FALSE) && (LinuxHasInitrd == TRUE))
{
MessageBox("Error: Cannot load a ramdisk (initrd) with an old kernel image.");
UiMessageBox("Error: Cannot load a ramdisk (initrd) with an old kernel image.");
return FALSE;
}
@ -394,16 +395,16 @@ BOOL LinuxReadInitrd(VOID)
ULONG BytesLoaded;
UCHAR StatusText[260];
sprintf(StatusText, " Loading %s", LinuxInitrdName);
DrawStatusText(StatusText);
DrawProgressBar(0);
sprintf(StatusText, "Loading %s", LinuxInitrdName);
UiDrawStatusText(StatusText);
UiDrawProgressBarCenter(0, 100);
// Open the initrd file image
LinuxInitrdFile = OpenFile(LinuxInitrdName);
if (LinuxInitrdFile == NULL)
{
sprintf(TempString, "Linux initrd image \'%s\' not found.", LinuxInitrdName);
MessageBox(TempString);
UiMessageBox(TempString);
return FALSE;
}
@ -436,7 +437,7 @@ BOOL LinuxReadInitrd(VOID)
BytesLoaded += 0x4000;
LinuxInitrdLoadAddress += 0x4000;
DrawProgressBar( (BytesLoaded * 100) / LinuxInitrdSize );
UiDrawProgressBarCenter(BytesLoaded, LinuxInitrdSize);
}
return TRUE;

View file

@ -18,14 +18,15 @@
*/
#include "freeldr.h"
#include "arch.h"
#include "miscboot.h"
#include "rtl.h"
#include "fs.h"
#include "ui.h"
#include "inifile.h"
#include "disk.h"
#include <freeldr.h>
#include <arch.h>
#include <miscboot.h>
#include <rtl.h>
#include <fs.h>
#include <ui.h>
#include <inifile.h>
#include <disk.h>
#include <video.h>
VOID LoadAndBootBootSector(PUCHAR OperatingSystemName)
{
@ -37,19 +38,19 @@ VOID LoadAndBootBootSector(PUCHAR OperatingSystemName)
ULONG BytesRead;
// Find all the message box settings and run them
ShowMessageBoxesInSection(OperatingSystemName);
UiShowMessageBoxesInSection(OperatingSystemName);
// Try to open the operating system section in the .ini file
if (!IniOpenSection(OperatingSystemName, &SectionId))
{
sprintf(SettingName, "Section [%s] not found in freeldr.ini.\n", OperatingSystemName);
MessageBox(SettingName);
UiMessageBox(SettingName);
return;
}
if (!IniReadSettingByName(SectionId, "BootDrive", SettingValue, 80))
{
MessageBox("Boot drive not specified for selected OS!");
UiMessageBox("Boot drive not specified for selected OS!");
return;
}
@ -63,13 +64,13 @@ VOID LoadAndBootBootSector(PUCHAR OperatingSystemName)
if (!IniReadSettingByName(SectionId, "BootSectorFile", FileName, 260))
{
MessageBox("Boot sector file not specified for selected OS!");
UiMessageBox("Boot sector file not specified for selected OS!");
return;
}
if (!OpenDiskDrive(BootDrive, BootPartition))
{
MessageBox("Failed to open boot drive.");
UiMessageBox("Failed to open boot drive.");
return;
}
@ -77,7 +78,7 @@ VOID LoadAndBootBootSector(PUCHAR OperatingSystemName)
if (FilePointer == NULL)
{
strcat(FileName, " not found.");
MessageBox(FileName);
UiMessageBox(FileName);
return;
}
@ -90,13 +91,20 @@ VOID LoadAndBootBootSector(PUCHAR OperatingSystemName)
// Check for validity
if (*((PWORD)(0x7c00 + 0x1fe)) != 0xaa55)
{
MessageBox("Invalid boot sector magic (0xaa55)");
UiMessageBox("Invalid boot sector magic (0xaa55)");
return;
}
clrscr();
showcursor();
stop_floppy();
VideoClearScreen();
VideoShowTextCursor();
// Don't stop the floppy drive motor when we
// are just booting a bootsector, or drive, or partition.
// If we were to stop the floppy motor then
// the BIOS wouldn't be informed and if the
// next read is to a floppy then the BIOS will
// still think the motor is on and this will
// result in a read error.
//StopFloppyMotor();
ChainLoadBiosBootSectorCode();
}
@ -108,20 +116,20 @@ VOID LoadAndBootPartition(PUCHAR OperatingSystemName)
PARTITION_TABLE_ENTRY PartitionTableEntry;
// Find all the message box settings and run them
ShowMessageBoxesInSection(OperatingSystemName);
UiShowMessageBoxesInSection(OperatingSystemName);
// Try to open the operating system section in the .ini file
if (!IniOpenSection(OperatingSystemName, &SectionId))
{
sprintf(SettingName, "Section [%s] not found in freeldr.ini.\n", OperatingSystemName);
MessageBox(SettingName);
UiMessageBox(SettingName);
return;
}
// Read the boot drive
if (!IniReadSettingByName(SectionId, "BootDrive", SettingValue, 80))
{
MessageBox("Boot drive not specified for selected OS!");
UiMessageBox("Boot drive not specified for selected OS!");
return;
}
@ -130,7 +138,7 @@ VOID LoadAndBootPartition(PUCHAR OperatingSystemName)
// Read the boot partition
if (!IniReadSettingByName(SectionId, "BootPartition", SettingValue, 80))
{
MessageBox("Boot partition not specified for selected OS!");
UiMessageBox("Boot partition not specified for selected OS!");
return;
}
@ -152,13 +160,20 @@ VOID LoadAndBootPartition(PUCHAR OperatingSystemName)
// Check for validity
if (*((PWORD)(0x7c00 + 0x1fe)) != 0xaa55)
{
MessageBox("Invalid boot sector magic (0xaa55)");
UiMessageBox("Invalid boot sector magic (0xaa55)");
return;
}
clrscr();
showcursor();
stop_floppy();
VideoClearScreen();
VideoShowTextCursor();
// Don't stop the floppy drive motor when we
// are just booting a bootsector, or drive, or partition.
// If we were to stop the floppy motor then
// the BIOS wouldn't be informed and if the
// next read is to a floppy then the BIOS will
// still think the motor is on and this will
// result in a read error.
//StopFloppyMotor();
ChainLoadBiosBootSectorCode();
}
@ -169,19 +184,19 @@ VOID LoadAndBootDrive(PUCHAR OperatingSystemName)
ULONG SectionId;
// Find all the message box settings and run them
ShowMessageBoxesInSection(OperatingSystemName);
UiShowMessageBoxesInSection(OperatingSystemName);
// Try to open the operating system section in the .ini file
if (!IniOpenSection(OperatingSystemName, &SectionId))
{
sprintf(SettingName, "Section [%s] not found in freeldr.ini.\n", OperatingSystemName);
MessageBox(SettingName);
UiMessageBox(SettingName);
return;
}
if (!IniReadSettingByName(SectionId, "BootDrive", SettingValue, 80))
{
MessageBox("Boot drive not specified for selected OS!");
UiMessageBox("Boot drive not specified for selected OS!");
return;
}
@ -197,12 +212,19 @@ VOID LoadAndBootDrive(PUCHAR OperatingSystemName)
// Check for validity
if (*((PWORD)(0x7c00 + 0x1fe)) != 0xaa55)
{
MessageBox("Invalid boot sector magic (0xaa55)");
UiMessageBox("Invalid boot sector magic (0xaa55)");
return;
}
clrscr();
showcursor();
stop_floppy();
VideoClearScreen();
VideoShowTextCursor();
// Don't stop the floppy drive motor when we
// are just booting a bootsector, or drive, or partition.
// If we were to stop the floppy motor then
// the BIOS wouldn't be informed and if the
// next read is to a floppy then the BIOS will
// still think the motor is on and this will
// result in a read error.
//StopFloppyMotor();
ChainLoadBiosBootSectorCode();
}

View file

@ -22,6 +22,14 @@
#define __MEM_H
#define MM_PAGE_SIZE 4096
typedef struct
{
UINT32 PageAllocated; // Zero = free, non-zero = allocated
UINT32 PageAllocationLength; // Number of pages allocated (or zero if this isn't the first page in the chain)
} PAGE_LOOKUP_TABLE_ITEM, *PPAGE_LOOKUP_TABLE_ITEM;
//
// Define this to 1 if you want the entire contents
// of the memory allocation bitmap displayed
@ -29,20 +37,28 @@
//
#define DUMP_MEM_MAP_ON_VERIFY 0
#define MEM_BLOCK_SIZE 256
typedef struct
{
BOOL MemBlockAllocated; // Is this block allocated or free
ULONG BlocksAllocated; // Block length, in multiples of MEM_BLOCK_SIZE
} MEMBLOCK, *PMEMBLOCK;
extern ULONG RealFreeLoaderModuleEnd;
extern PVOID PageLookupTableAddress;
extern ULONG TotalPagesInLookupTable;
extern ULONG FreePagesInLookupTable;
extern ULONG LastFreePageHint;
extern PVOID HeapBaseAddress;
extern ULONG HeapLengthInBytes;
extern ULONG HeapMemBlockCount;
extern PMEMBLOCK HeapMemBlockArray;
#ifdef DEBUG
PUCHAR MmGetSystemMemoryMapTypeString(ULONG Type);
#endif
ULONG MmGetPageNumberFromAddress(PVOID Address); // Returns the page number that contains a linear address
PVOID MmGetEndAddressOfAnyMemory(BIOS_MEMORY_MAP BiosMemoryMap[32], ULONG MapCount); // Returns the last address of memory from the memory map
ULONG MmGetAddressablePageCountIncludingHoles(BIOS_MEMORY_MAP BiosMemoryMap[32], ULONG MapCount); // Returns the count of addressable pages from address zero including any memory holes and reserved memory regions
PVOID MmFindLocationForPageLookupTable(BIOS_MEMORY_MAP BiosMemoryMap[32], ULONG MapCount); // Returns the address for a memory chunk big enough to hold the page lookup table (starts search from end of memory)
VOID MmSortBiosMemoryMap(BIOS_MEMORY_MAP BiosMemoryMap[32], ULONG MapCount); // Sorts the BIOS_MEMORY_MAP array so the first element corresponds to the first address in memory
VOID MmInitPageLookupTable(PVOID PageLookupTable, ULONG TotalPageCount, BIOS_MEMORY_MAP BiosMemoryMap[32], ULONG MapCount); // Inits the page lookup table according to the memory types in the memory map
VOID MmMarkPagesInLookupTable(PVOID PageLookupTable, ULONG StartPage, ULONG PageCount, ULONG PageAllocated); // Marks the specified pages as allocated or free in the lookup table
VOID MmAllocatePagesInLookupTable(PVOID PageLookupTable, ULONG StartPage, ULONG PageCount); // Allocates the specified pages in the lookup table
ULONG MmCountFreePagesInLookupTable(PVOID PageLookupTable, ULONG TotalPageCount); // Returns the number of free pages in the lookup table
ULONG MmFindAvailablePagesFromEnd(PVOID PageLookupTable, ULONG TotalPageCount, ULONG PagesNeeded); // Returns the page number of the first available page range from the end of memory
VOID MmFixupSystemMemoryMap(BIOS_MEMORY_MAP BiosMemoryMap[32], PULONG MapCount); // Removes entries in the memory map that describe memory above 4G
VOID MmUpdateLastFreePageHint(PVOID PageLookupTable, ULONG TotalPageCountVOID); // Sets the LastFreePageHint to the last usable page of memory
#endif // defined __MEM_H

View file

@ -0,0 +1,402 @@
/*
* FreeLoader
* Copyright (C) 1998-2002 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 <arch.h>
#include <mm.h>
#include "mem.h"
#include <rtl.h>
#include <debug.h>
#include <ui.h>
#ifdef DEBUG
typedef struct
{
ULONG Type;
UCHAR TypeString[20];
} MEMORY_TYPE, *PMEMORY_TYPE;
ULONG MemoryTypeCount = 5;
MEMORY_TYPE MemoryTypeArray[] =
{
{ 0, "Unknown Memory" },
{ MEMTYPE_USABLE, "Usable Memory" },
{ MEMTYPE_RESERVED, "Reserved Memory" },
{ MEMTYPE_ACPI_RECLAIM, "ACPI Reclaim Memory" },
{ MEMTYPE_ACPI_NVS, "ACPI NVS Memory" },
};
#endif
PVOID PageLookupTableAddress = NULL;
ULONG TotalPagesInLookupTable = 0;
ULONG FreePagesInLookupTable = 0;
ULONG LastFreePageHint = 0;
BOOL MmInitializeMemoryManager(VOID)
{
BIOS_MEMORY_MAP BiosMemoryMap[32];
ULONG BiosMemoryMapEntryCount;
ULONG ExtendedMemorySize;
ULONG ConventionalMemorySize;
ULONG Index;
DbgPrint((DPRINT_MEMORY, "Initializing Memory Manager.\n"));
RtlZeroMemory(BiosMemoryMap, sizeof(BIOS_MEMORY_MAP) * 32);
BiosMemoryMapEntryCount = GetBiosMemoryMap(BiosMemoryMap);
ExtendedMemorySize = GetExtendedMemorySize();
ConventionalMemorySize = GetConventionalMemorySize();
// If we got the system memory map then fixup invalid entries
if (BiosMemoryMapEntryCount != 0)
{
MmFixupSystemMemoryMap(BiosMemoryMap, &BiosMemoryMapEntryCount);
}
#ifdef DEBUG
// Dump the system memory map
if (BiosMemoryMapEntryCount != 0)
{
DbgPrint((DPRINT_MEMORY, "System Memory Map (Base Address, Length, Type):\n"));
for (Index=0; Index<BiosMemoryMapEntryCount; Index++)
{
DbgPrint((DPRINT_MEMORY, "%x%x\t %x%x\t %s\n", BiosMemoryMap[Index].BaseAddressHigh, BiosMemoryMap[Index].BaseAddressLow, BiosMemoryMap[Index].LengthHigh, BiosMemoryMap[Index].LengthLow, MmGetSystemMemoryMapTypeString(BiosMemoryMap[Index].Type)));
}
}
else
{
DbgPrint((DPRINT_MEMORY, "GetBiosMemoryMap() not supported.\n"));
}
#endif
DbgPrint((DPRINT_MEMORY, "Extended memory size: %d KB\n", ExtendedMemorySize));
DbgPrint((DPRINT_MEMORY, "Conventional memory size: %d KB\n", ConventionalMemorySize));
// Since I don't feel like writing two sets of routines
// one to handle the BiosMemoryMap structure and another
// to handle just a flat extended memory size I'm going
// to create a 'fake' memory map entry out of the
// extended memory size if GetBiosMemoryMap() fails.
if (BiosMemoryMapEntryCount == 0)
{
BiosMemoryMap[0].BaseAddressLow = 0x100000; // Start at 1MB
BiosMemoryMap[0].BaseAddressHigh = 0;
BiosMemoryMap[0].LengthLow = ExtendedMemorySize * 1024;
BiosMemoryMap[0].LengthHigh = 0;
BiosMemoryMap[0].Type = MEMTYPE_USABLE;
BiosMemoryMapEntryCount = 1;
}
TotalPagesInLookupTable = MmGetAddressablePageCountIncludingHoles(BiosMemoryMap, BiosMemoryMapEntryCount);
PageLookupTableAddress = MmFindLocationForPageLookupTable(BiosMemoryMap, BiosMemoryMapEntryCount);
LastFreePageHint = TotalPagesInLookupTable;
if (PageLookupTableAddress == 0)
{
// If we get here then we probably couldn't
// find a contigous chunk of memory big
// enough to hold the page lookup table
printf("Error initializing memory manager!\n");
return FALSE;
}
MmInitPageLookupTable(PageLookupTableAddress, TotalPagesInLookupTable, BiosMemoryMap, BiosMemoryMapEntryCount);
MmUpdateLastFreePageHint(PageLookupTableAddress, TotalPagesInLookupTable);
FreePagesInLookupTable = MmCountFreePagesInLookupTable(PageLookupTableAddress, TotalPagesInLookupTable);
DbgPrint((DPRINT_MEMORY, "Memory Manager initialized. %d pages available.\n", FreePagesInLookupTable));
return TRUE;
}
#ifdef DEBUG
PUCHAR MmGetSystemMemoryMapTypeString(ULONG Type)
{
ULONG Index;
for (Index=1; Index<MemoryTypeCount; Index++)
{
if (MemoryTypeArray[Index].Type == Type)
{
return MemoryTypeArray[Index].TypeString;
}
}
return MemoryTypeArray[0].TypeString;
}
#endif
ULONG MmGetPageNumberFromAddress(PVOID Address)
{
return ((ULONG)Address) / MM_PAGE_SIZE;
}
PVOID MmGetEndAddressOfAnyMemory(BIOS_MEMORY_MAP BiosMemoryMap[32], ULONG MapCount)
{
ULONG MaxStartAddressSoFar;
UINT64 EndAddressOfMemory;
ULONG Index;
MaxStartAddressSoFar = 0;
EndAddressOfMemory = 0;
for (Index=0; Index<MapCount; Index++)
{
if (MaxStartAddressSoFar < BiosMemoryMap[Index].BaseAddressLow)
{
MaxStartAddressSoFar = BiosMemoryMap[Index].BaseAddressLow;
EndAddressOfMemory = ((UINT64)MaxStartAddressSoFar + (UINT64)BiosMemoryMap[Index].LengthLow);
if (EndAddressOfMemory > 0xFFFFFFFF)
{
EndAddressOfMemory = 0xFFFFFFFF;
}
}
}
DbgPrint((DPRINT_MEMORY, "MmGetEndAddressOfAnyMemory() returning 0x%x\n", (UINT32)EndAddressOfMemory));
return (PVOID)(UINT32)EndAddressOfMemory;
}
ULONG MmGetAddressablePageCountIncludingHoles(BIOS_MEMORY_MAP BiosMemoryMap[32], ULONG MapCount)
{
ULONG PageCount;
PageCount = MmGetPageNumberFromAddress(MmGetEndAddressOfAnyMemory(BiosMemoryMap, MapCount));
DbgPrint((DPRINT_MEMORY, "MmGetAddressablePageCountIncludingHoles() returning %d\n", PageCount));
return PageCount;
}
PVOID MmFindLocationForPageLookupTable(BIOS_MEMORY_MAP BiosMemoryMap[32], ULONG MapCount)
{
ULONG TotalPageCount;
ULONG PageLookupTableSize;
PVOID PageLookupTableAddress;
int Index;
BIOS_MEMORY_MAP TempBiosMemoryMap[32];
TotalPageCount = MmGetAddressablePageCountIncludingHoles(BiosMemoryMap, MapCount);
PageLookupTableSize = TotalPageCount * sizeof(PAGE_LOOKUP_TABLE_ITEM);
PageLookupTableAddress = 0;
RtlCopyMemory(TempBiosMemoryMap, BiosMemoryMap, sizeof(BIOS_MEMORY_MAP) * 32);
MmSortBiosMemoryMap(TempBiosMemoryMap, MapCount);
for (Index=(MapCount-1); Index>=0; Index--)
{
// If this is usable memory with a big enough length
// then we'll put our page lookup table here
if (TempBiosMemoryMap[Index].Type == MEMTYPE_USABLE && TempBiosMemoryMap[Index].LengthLow >= PageLookupTableSize)
{
PageLookupTableAddress = (PVOID)(TempBiosMemoryMap[Index].BaseAddressLow + (TempBiosMemoryMap[Index].LengthLow - PageLookupTableSize));
break;
}
}
DbgPrint((DPRINT_MEMORY, "MmFindLocationForPageLookupTable() returning 0x%x\n", PageLookupTableAddress));
return PageLookupTableAddress;
}
VOID MmSortBiosMemoryMap(BIOS_MEMORY_MAP BiosMemoryMap[32], ULONG MapCount)
{
ULONG Index;
ULONG LoopCount;
BIOS_MEMORY_MAP TempMapItem;
// Loop once for each entry in the memory map minus one
// On each loop iteration go through and sort the memory map
for (LoopCount=0; LoopCount<(MapCount-1); LoopCount++)
{
for (Index=0; Index<(MapCount-1); Index++)
{
if (BiosMemoryMap[Index].BaseAddressLow > BiosMemoryMap[Index+1].BaseAddressLow)
{
TempMapItem = BiosMemoryMap[Index];
BiosMemoryMap[Index] = BiosMemoryMap[Index+1];
BiosMemoryMap[Index+1] = TempMapItem;
}
}
}
}
VOID MmInitPageLookupTable(PVOID PageLookupTable, ULONG TotalPageCount, BIOS_MEMORY_MAP BiosMemoryMap[32], ULONG MapCount)
{
ULONG MemoryMapStartPage;
ULONG MemoryMapEndPage;
ULONG MemoryMapPageCount;
ULONG MemoryMapPageAllocated;
ULONG PageLookupTableStartPage;
ULONG PageLookupTablePageCount;
ULONG Index;
DbgPrint((DPRINT_MEMORY, "MmInitPageLookupTable()\n"));
// Mark every page as allocated initially
// We will go through and mark pages again according to the memory map
// But this will mark any holes not described in the map as allocated
MmMarkPagesInLookupTable(PageLookupTable, 0, TotalPageCount, 1);
for (Index=0; Index<MapCount; Index++)
{
MemoryMapStartPage = MmGetPageNumberFromAddress((PVOID)BiosMemoryMap[Index].BaseAddressLow);
MemoryMapEndPage = MmGetPageNumberFromAddress((PVOID)(BiosMemoryMap[Index].BaseAddressLow + BiosMemoryMap[Index].LengthLow - 1));
MemoryMapPageCount = (MemoryMapEndPage - MemoryMapStartPage) + 1;
MemoryMapPageAllocated = (BiosMemoryMap[Index].Type == MEMTYPE_USABLE) ? 0 : BiosMemoryMap[Index].Type;
DbgPrint((DPRINT_MEMORY, "Marking pages as type %d: StartPage: %d PageCount: %d\n", MemoryMapPageAllocated, MemoryMapStartPage, MemoryMapPageCount));
MmMarkPagesInLookupTable(PageLookupTable, MemoryMapStartPage, MemoryMapPageCount, MemoryMapPageAllocated);
}
// Mark the low memory region below 1MB as reserved (256 pages in region)
DbgPrint((DPRINT_MEMORY, "Marking the low 1MB region as reserved.\n"));
MmMarkPagesInLookupTable(PageLookupTable, 0, 256, MEMTYPE_RESERVED);
// Mark the pages that the lookup tabel occupies as reserved
PageLookupTableStartPage = MmGetPageNumberFromAddress(PageLookupTable);
PageLookupTablePageCount = MmGetPageNumberFromAddress(PageLookupTable + ROUND_UP(TotalPageCount * sizeof(PAGE_LOOKUP_TABLE_ITEM), MM_PAGE_SIZE)) - PageLookupTableStartPage;
DbgPrint((DPRINT_MEMORY, "Marking the page lookup table pages as reserved StartPage: %d PageCount: %d\n", PageLookupTableStartPage, PageLookupTablePageCount));
MmMarkPagesInLookupTable(PageLookupTable, PageLookupTableStartPage, PageLookupTablePageCount, MEMTYPE_RESERVED);
}
VOID MmMarkPagesInLookupTable(PVOID PageLookupTable, ULONG StartPage, ULONG PageCount, ULONG PageAllocated)
{
PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
ULONG Index;
for (Index=StartPage; Index<(StartPage+PageCount); Index++)
{
RealPageLookupTable[Index].PageAllocated = PageAllocated;
RealPageLookupTable[Index].PageAllocationLength = PageAllocated ? 1 : 0;
}
}
VOID MmAllocatePagesInLookupTable(PVOID PageLookupTable, ULONG StartPage, ULONG PageCount)
{
PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
ULONG Index;
for (Index=StartPage; Index<(StartPage+PageCount); Index++)
{
RealPageLookupTable[Index].PageAllocated = 1;
RealPageLookupTable[Index].PageAllocationLength = (Index == StartPage) ? PageCount : 0;
}
}
ULONG MmCountFreePagesInLookupTable(PVOID PageLookupTable, ULONG TotalPageCount)
{
PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
ULONG Index;
ULONG FreePageCount;
FreePageCount = 0;
for (Index=0; Index<TotalPageCount; Index++)
{
if (RealPageLookupTable[Index].PageAllocated == 0)
{
FreePageCount++;
}
}
return FreePageCount;
}
ULONG MmFindAvailablePagesFromEnd(PVOID PageLookupTable, ULONG TotalPageCount, ULONG PagesNeeded)
{
PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
ULONG AvailablePageStart;
ULONG AvailablePagesSoFar;
ULONG Index;
if (LastFreePageHint > TotalPageCount)
{
LastFreePageHint = TotalPageCount;
}
AvailablePageStart = 0;
AvailablePagesSoFar = 0;
for (Index=LastFreePageHint-1; Index>=0; Index--)
{
if (RealPageLookupTable[Index].PageAllocated != 0)
{
AvailablePagesSoFar = 0;
continue;
}
else
{
AvailablePagesSoFar++;
}
if (AvailablePagesSoFar >= PagesNeeded)
{
return Index;
}
}
return 0;
}
VOID MmFixupSystemMemoryMap(BIOS_MEMORY_MAP BiosMemoryMap[32], PULONG MapCount)
{
int Index;
int Index2;
UINT64 RealLength;
// Loop through each entry in the array
for (Index=0; Index<*MapCount; Index++)
{
// If the base address for this entry starts at
// or above 4G then remove this entry
if (BiosMemoryMap[Index].BaseAddressHigh != 0)
{
// Slide every entry after this down one
for (Index2=Index; Index2<(*MapCount - 1); Index2++)
{
BiosMemoryMap[Index2] = BiosMemoryMap[Index2 + 1];
}
(*MapCount)--;
Index--;
}
// If the base address plus the length for this entry
// extends beyond 4G then truncate this entry
RealLength = BiosMemoryMap[Index].BaseAddressLow + BiosMemoryMap[Index].LengthLow;
if ((BiosMemoryMap[Index].LengthHigh != 0) || (RealLength > 0xFFFFFFFF))
{
BiosMemoryMap[Index].LengthLow = 0xFFFFFFFF - BiosMemoryMap[Index].BaseAddressLow;
}
}
}
VOID MmUpdateLastFreePageHint(PVOID PageLookupTable, ULONG TotalPageCount)
{
PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
ULONG Index;
for (Index=TotalPageCount-1; Index>=0; Index--)
{
if (RealPageLookupTable[Index].PageAllocated == 0)
{
LastFreePageHint = Index + 1;
break;
}
}
}

View file

@ -35,133 +35,120 @@ VOID DecrementAllocationCount(VOID);
VOID MemAllocTest(VOID);
#endif // DEBUG
PVOID AllocateMemory(ULONG NumberOfBytes)
PVOID MmAllocateMemory(ULONG MemorySize)
{
ULONG BlocksNeeded;
ULONG Idx;
ULONG NumFree;
ULONG PagesNeeded;
ULONG FirstFreePageFromEnd;
PVOID MemPointer;
if (NumberOfBytes == 0)
if (MemorySize == 0)
{
DbgPrint((DPRINT_MEMORY, "AllocateMemory() called for 0 bytes. Returning NULL.\n"));
MessageBox("Memory allocation failed: AllocateMemory() called for 0 bytes.");
DbgPrint((DPRINT_MEMORY, "MmAllocateMemory() called for 0 bytes. Returning NULL.\n"));
UiMessageBoxCritical("Memory allocation failed: MmAllocateMemory() called for 0 bytes.");
return NULL;
}
// 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++;
PagesNeeded = ROUND_UP(MemorySize, MM_PAGE_SIZE) / MM_PAGE_SIZE;
// If we don't have enough available mem
// then return NULL
if (NumFree < BlocksNeeded)
if (FreePagesInLookupTable < PagesNeeded)
{
DbgPrint((DPRINT_MEMORY, "Memory allocation failed. Not enough free memory to allocate %d bytes. AllocationCount: %d\n", NumberOfBytes, AllocationCount));
MessageBox("Memory allocation failed: out of memory.");
DbgPrint((DPRINT_MEMORY, "Memory allocation failed. Not enough free memory to allocate %d bytes. AllocationCount: %d\n", MemorySize, AllocationCount));
UiMessageBoxCritical("Memory allocation failed: out of memory.");
return NULL;
}
// Subtract the block count from Idx and we have
// the start block of the memory
Idx -= NumFree;
FirstFreePageFromEnd = MmFindAvailablePagesFromEnd(PageLookupTableAddress, TotalPagesInLookupTable, PagesNeeded);
// 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++)
if (FirstFreePageFromEnd == 0)
{
HeapMemBlockArray[Idx + NumFree].MemBlockAllocated = TRUE;
HeapMemBlockArray[Idx + NumFree].BlocksAllocated = NumFree ? 0 : BlocksNeeded; // Mark only the first block with the count
DbgPrint((DPRINT_MEMORY, "Memory allocation failed. Not enough free memory to allocate %d bytes. AllocationCount: %d\n", MemorySize, AllocationCount));
UiMessageBoxCritical("Memory allocation failed: out of memory.");
return NULL;
}
MmAllocatePagesInLookupTable(PageLookupTableAddress, FirstFreePageFromEnd, PagesNeeded);
FreePagesInLookupTable -= PagesNeeded;
MemPointer = (PVOID)(FirstFreePageFromEnd * MM_PAGE_SIZE);
#ifdef DEBUG
IncrementAllocationCount();
DbgPrint((DPRINT_MEMORY, "Allocated %d bytes (%d blocks) of memory starting at block %d. AllocCount: %d\n", NumberOfBytes, BlocksNeeded, Idx, AllocationCount));
DbgPrint((DPRINT_MEMORY, "Allocated %d bytes (%d pages) of memory starting at page %d. AllocCount: %d\n", MemorySize, PagesNeeded, FirstFreePageFromEnd, AllocationCount));
DbgPrint((DPRINT_MEMORY, "Memory allocation pointer: 0x%x\n", MemPointer));
VerifyHeap();
//VerifyHeap();
#endif // DEBUG
// Now return the pointer
return MemPointer;
}
VOID FreeMemory(PVOID MemBlock)
VOID MmFreeMemory(PVOID MemoryPointer)
{
ULONG BlockNumber;
ULONG BlockCount;
ULONG Idx;
ULONG PageNumber;
ULONG PageCount;
ULONG Idx;
PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTableAddress;
#ifdef DEBUG
// Make sure we didn't get a bogus pointer
if ((MemBlock < HeapBaseAddress) || (MemBlock > (HeapBaseAddress + HeapLengthInBytes)))
if (MemoryPointer >= (PVOID)(TotalPagesInLookupTable * MM_PAGE_SIZE))
{
BugCheck((DPRINT_MEMORY, "Bogus memory pointer (0x%x) passed to FreeMemory()\n", MemBlock));
BugCheck((DPRINT_MEMORY, "Bogus memory pointer (0x%x) passed to MmFreeMemory()\n", MemoryPointer));
}
#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;
// Find out the page number of the first
// page of memory they allocated
PageNumber = MmGetPageNumberFromAddress(MemoryPointer);
PageCount = RealPageLookupTable[PageNumber].PageAllocationLength;
#ifdef DEBUG
// Make sure we didn't get a bogus pointer
if ((BlockCount < 1) || (BlockCount > HeapMemBlockCount))
if ((PageCount < 1) || (PageCount > (TotalPagesInLookupTable - PageNumber)))
{
BugCheck((DPRINT_MEMORY, "Invalid block count in heap page header. HeapMemBlockArray[BlockNumber].BlocksAllocated = %d\n", HeapMemBlockArray[BlockNumber].BlocksAllocated));
BugCheck((DPRINT_MEMORY, "Invalid page count in lookup table. PageLookupTable[%d].PageAllocationLength = %d\n", PageNumber, RealPageLookupTable[PageNumber].PageAllocationLength));
}
// Loop through our array check all the pages
// to make sure they are allocated with a length of 0
for (Idx=PageNumber+1; Idx<(PageNumber + PageCount); Idx++)
{
if ((RealPageLookupTable[Idx].PageAllocated != 1) ||
(RealPageLookupTable[Idx].PageAllocationLength != 0))
{
BugCheck((DPRINT_MEMORY, "Invalid page entry in lookup table, PageAllocated should = 1 and PageAllocationLength should = 0 because this is not the first block in the run. PageLookupTable[%d].PageAllocated = %d PageLookupTable[%d].PageAllocationLength = %d\n", PageNumber, RealPageLookupTable[PageNumber].PageAllocated, PageNumber, RealPageLookupTable[PageNumber].PageAllocationLength));
}
}
#endif
// Loop through our array and mark all the
// blocks as free
for (Idx=BlockNumber; Idx<(BlockNumber + BlockCount); Idx++)
for (Idx=PageNumber; Idx<(PageNumber + PageCount); Idx++)
{
HeapMemBlockArray[Idx].MemBlockAllocated = FALSE;
HeapMemBlockArray[Idx].BlocksAllocated = 0;
RealPageLookupTable[Idx].PageAllocated = 0;
RealPageLookupTable[Idx].PageAllocationLength = 0;
}
#ifdef DEBUG
DecrementAllocationCount();
DbgPrint((DPRINT_MEMORY, "Freed %d blocks of memory starting at block %d. AllocationCount: %d\n", BlockCount, BlockNumber, AllocationCount));
VerifyHeap();
DbgPrint((DPRINT_MEMORY, "Freed %d pages of memory starting at page %d. AllocationCount: %d\n", PageCount, PageNumber, AllocationCount));
//VerifyHeap();
#endif // DEBUG
}
#ifdef DEBUG
VOID VerifyHeap(VOID)
{
ULONG Idx;
ULONG Idx2;
ULONG Count;
ULONG Idx;
ULONG Idx2;
ULONG Count;
PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTableAddress;
if (DUMP_MEM_MAP_ON_VERIFY)
{
@ -170,35 +157,35 @@ VOID VerifyHeap(VOID)
// Loop through the array and verify that
// everything is kosher
for (Idx=0; Idx<HeapMemBlockCount; Idx++)
for (Idx=0; Idx<TotalPagesInLookupTable; Idx++)
{
// Check if this block is allocation
if (HeapMemBlockArray[Idx].MemBlockAllocated)
// Check if this block is allocated
if (RealPageLookupTable[Idx].PageAllocated != 0)
{
// 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)))
if ((RealPageLookupTable[Idx].PageAllocationLength < 1) || (RealPageLookupTable[Idx].PageAllocationLength > (TotalPagesInLookupTable - Idx)))
{
BugCheck((DPRINT_MEMORY, "Allocation length out of range in heap table. HeapMemBlockArray[Idx].BlocksAllocated = %d\n", HeapMemBlockArray[Idx].BlocksAllocated));
BugCheck((DPRINT_MEMORY, "Allocation length out of range in heap table. PageLookupTable[Idx].PageAllocationLength = %d\n", RealPageLookupTable[Idx].PageAllocationLength));
}
// 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;
Count = RealPageLookupTable[Idx].PageAllocationLength;
for (Idx2=1; Idx2<Count; Idx2++)
{
// Make sure it's allocated
if (HeapMemBlockArray[Idx + Idx2].MemBlockAllocated != TRUE)
if (RealPageLookupTable[Idx + Idx2].PageAllocated == 0)
{
BugCheck((DPRINT_MEMORY, "Heap table indicates hole in memory allocation. HeapMemBlockArray[Idx + Idx2].MemBlockAllocated != TRUE\n"));
BugCheck((DPRINT_MEMORY, "Lookup table indicates hole in memory allocation. RealPageLookupTable[Idx + Idx2].PageAllocated == 0\n"));
}
// Make sure the length is zero
if (HeapMemBlockArray[Idx + Idx2].BlocksAllocated != 0)
if (RealPageLookupTable[Idx + Idx2].PageAllocationLength != 0)
{
BugCheck((DPRINT_MEMORY, "Allocation chain has non-zero value in non-first block in heap table. HeapMemBlockArray[Idx + Idx2].BlocksAllocated != 0\n"));
BugCheck((DPRINT_MEMORY, "Allocation chain has non-zero value in non-first block in lookup table. RealPageLookupTable[Idx + Idx2].PageAllocationLength != 0\n"));
}
}
@ -208,9 +195,9 @@ VOID VerifyHeap(VOID)
else
{
// Nope, not allocated so make sure the length is zero
if (HeapMemBlockArray[Idx].BlocksAllocated != 0)
if (RealPageLookupTable[Idx].PageAllocationLength != 0)
{
BugCheck((DPRINT_MEMORY, "Free block is start of memory allocation. HeapMemBlockArray[Idx].BlocksAllocated != 0\n"));
BugCheck((DPRINT_MEMORY, "Free block is start of memory allocation. RealPageLookupTable[Idx].PageAllocationLength != 0\n"));
}
}
}
@ -218,29 +205,43 @@ VOID VerifyHeap(VOID)
VOID DumpMemoryAllocMap(VOID)
{
ULONG Idx;
ULONG Idx;
PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTableAddress;
DbgPrint((DPRINT_MEMORY, "----------- Memory Allocation Bitmap -----------\n"));
for (Idx=0; Idx<HeapMemBlockCount; Idx++)
for (Idx=0; Idx<TotalPagesInLookupTable; Idx++)
{
if ((Idx % 32) == 0)
{
DbgPrint((DPRINT_MEMORY, "\n"));
DbgPrint((DPRINT_MEMORY, "%x:\t", HeapBaseAddress + (Idx * 256)));
DbgPrint((DPRINT_MEMORY, "%x:\t", (Idx * MM_PAGE_SIZE)));
}
else if ((Idx % 4) == 0)
{
DbgPrint((DPRINT_MEMORY, " "));
}
if (HeapMemBlockArray[Idx].MemBlockAllocated)
{
DbgPrint((DPRINT_MEMORY, "X"));
}
else
switch (RealPageLookupTable[Idx].PageAllocated)
{
case 0:
DbgPrint((DPRINT_MEMORY, "*"));
break;
case 1:
DbgPrint((DPRINT_MEMORY, "A"));
break;
case MEMTYPE_RESERVED:
DbgPrint((DPRINT_MEMORY, "R"));
break;
case MEMTYPE_ACPI_RECLAIM:
DbgPrint((DPRINT_MEMORY, "M"));
break;
case MEMTYPE_ACPI_NVS:
DbgPrint((DPRINT_MEMORY, "N"));
break;
default:
DbgPrint((DPRINT_MEMORY, "X"));
break;
}
}
@ -265,32 +266,31 @@ VOID MemAllocTest(VOID)
PVOID MemPtr4;
PVOID MemPtr5;
MemPtr1 = AllocateMemory(4096);
MemPtr1 = MmAllocateMemory(4096);
printf("MemPtr1: 0x%x\n", (int)MemPtr1);
getch();
MemPtr2 = AllocateMemory(4096);
MemPtr2 = MmAllocateMemory(4096);
printf("MemPtr2: 0x%x\n", (int)MemPtr2);
getch();
MemPtr3 = AllocateMemory(4096);
MemPtr3 = MmAllocateMemory(4096);
printf("MemPtr3: 0x%x\n", (int)MemPtr3);
DumpMemoryAllocMap();
VerifyHeap();
getch();
FreeMemory(MemPtr2);
MmFreeMemory(MemPtr2);
getch();
MemPtr4 = AllocateMemory(2048);
MemPtr4 = MmAllocateMemory(2048);
printf("MemPtr4: 0x%x\n", (int)MemPtr4);
getch();
MemPtr5 = AllocateMemory(4096);
MemPtr5 = MmAllocateMemory(4096);
printf("MemPtr5: 0x%x\n", (int)MemPtr5);
getch();
}
#endif // DEBUG
// Returns the amount of total usuable memory available to the memory manager
ULONG GetSystemMemorySize(VOID)
{
return HeapLengthInBytes;
return (TotalPagesInLookupTable * MM_PAGE_SIZE);
}

View file

@ -1,88 +0,0 @@
/*
* FreeLoader
* Copyright (C) 1998-2002 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 <arch.h>
#include <mm.h>
#include "mem.h"
#include <rtl.h>
#include <debug.h>
#include <ui.h>
ULONG RealFreeLoaderModuleEnd = 0;
PVOID HeapBaseAddress = NULL;
ULONG HeapLengthInBytes = 0;
ULONG HeapMemBlockCount = 0;
PMEMBLOCK HeapMemBlockArray = NULL;
VOID InitMemoryManager(VOID)
{
ULONG MemBlocks;
ULONG BaseAddress;
ULONG Length;
// Round up to the next page of memory
RealFreeLoaderModuleEnd = ROUND_UP(FreeLoaderModuleEnd, 4096);
// FIXME:
// Add extra space for .data & .bss sections
// which are listed after FreeLoaderModuleEnd
// because it is in the .text section.
// I need to have everything in one section...
RealFreeLoaderModuleEnd += 0x2000;
BaseAddress = RealFreeLoaderModuleEnd;
Length = (MAXLOWMEMADDR - RealFreeLoaderModuleEnd);
DbgPrint((DPRINT_MEMORY, "Initializing Memory Manager.\n"));
DbgPrint((DPRINT_MEMORY, "Conventional memory size: %d KB\n", GetConventionalMemorySize()));
DbgPrint((DPRINT_MEMORY, "Low memory map:\n"));
DbgPrint((DPRINT_MEMORY, "00000\t1000\tReserved\n"));
DbgPrint((DPRINT_MEMORY, "01000\t6000\t16-bit stack\n"));
DbgPrint((DPRINT_MEMORY, "07000\t1000\tUnused\n"));
DbgPrint((DPRINT_MEMORY, "08000\t%x\tFreeLoader program code\n", (RealFreeLoaderModuleEnd - 0x8000)));
DbgPrint((DPRINT_MEMORY, "%x\t%x\tLow memory heap\n", BaseAddress, Length));
DbgPrint((DPRINT_MEMORY, "78000\t8000\t32-bit stack\n"));
DbgPrint((DPRINT_MEMORY, "80000\t10000\tFile system read buffer\n"));
DbgPrint((DPRINT_MEMORY, "90000\t10000\tDisk read buffer\n"));
DbgPrint((DPRINT_MEMORY, "A0000\t60000\tReserved\n"));
// 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 = (PVOID)BaseAddress;
HeapLengthInBytes = Length;
HeapMemBlockCount = (HeapLengthInBytes / MEM_BLOCK_SIZE);
HeapMemBlockArray = (PMEMBLOCK)(HeapBaseAddress + HeapLengthInBytes);
// Clear the memory
DbgPrint((DPRINT_MEMORY, "HeapBaseAddress: 0x%x HeapLengthInBytes: %d\n", HeapBaseAddress, HeapLengthInBytes));
RtlZeroMemory(HeapBaseAddress, HeapLengthInBytes);
RtlZeroMemory(HeapMemBlockArray, (HeapMemBlockCount * sizeof(MEMBLOCK)));
#ifdef DEBUG
DbgPrint((DPRINT_MEMORY, "Memory Manager initialized. BaseAddress = 0x%x Length = 0x%x. %d blocks in heap.\n", BaseAddress, Length, HeapMemBlockCount));
//MemAllocTest();
#endif
}

View file

@ -18,14 +18,14 @@
*/
#include "freeldr.h"
#include "arch.h"
#include "rtl.h"
#include "fs.h"
#include "multiboot.h"
#include "ui.h"
#include "inifile.h"
#include "mm.h"
#include <freeldr.h>
#include <arch.h>
#include <rtl.h>
#include <fs.h>
#include <multiboot.h>
#include <ui.h>
#include <inifile.h>
#include <mm.h>
unsigned long next_module_load_base = 0;
module_t* pOpenModule = NULL;
@ -39,10 +39,9 @@ BOOL MultiBootLoadKernel(FILE *KernelImage)
DWORD dwFileLoadOffset;
DWORD dwDataSize;
DWORD dwBssSize;
ULONG BytesRead;
// Allocate 8192 bytes for multiboot header
ImageHeaders = (PDWORD)AllocateMemory(8192);
ImageHeaders = (PDWORD)MmAllocateMemory(8192);
if (ImageHeaders == NULL)
{
return FALSE;
@ -54,7 +53,7 @@ BOOL MultiBootLoadKernel(FILE *KernelImage)
*/
if (!ReadFile(KernelImage, 8192, NULL, ImageHeaders))
{
FreeMemory(ImageHeaders);
MmFreeMemory(ImageHeaders);
return FALSE;
}
@ -73,7 +72,7 @@ BOOL MultiBootLoadKernel(FILE *KernelImage)
}
}
FreeMemory(ImageHeaders);
MmFreeMemory(ImageHeaders);
/*
* If we reached the end of the 8192 bytes without
@ -81,7 +80,7 @@ BOOL MultiBootLoadKernel(FILE *KernelImage)
*/
if (Idx == 2048)
{
MessageBox("No multiboot header found!");
UiMessageBox("No multiboot header found!");
return FALSE;
}
@ -104,7 +103,7 @@ BOOL MultiBootLoadKernel(FILE *KernelImage)
dwHeaderChecksum += mb_header.checksum;
if (dwHeaderChecksum != 0)
{
MessageBox("Multiboot header checksum invalid!");
UiMessageBox("Multiboot header checksum invalid!");
return FALSE;
}
@ -254,7 +253,7 @@ BOOL MultiBootCloseModule(PVOID ModuleBase, DWORD dwModuleSize)
module_t* pModule;
if ((pOpenModule != NULL) &&
((module_t*)ModuleBase == pOpenModule->mod_start) &&
((module_t*)ModuleBase == (module_t*)pOpenModule->mod_start) &&
(pOpenModule->mod_end == -1))
{
pModule = pOpenModule;

View file

@ -17,11 +17,11 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "freeldr.h"
#include "rtl.h"
#include "ui.h"
#include "options.h"
#include "miscboot.h"
#include <freeldr.h>
#include <rtl.h>
#include <ui.h>
#include <options.h>
#include <miscboot.h>
#if 0
void DoOptionsMenu(void)
@ -126,10 +126,10 @@ void DoBootOptionsMenu(int BootDriveNum, char *BootDriveText)
}
RestoreScreen(ScreenBuffer);
showcursor();
VideoShowTextCursor();
gotoxy(CursorXPos, CursorYPos);
stop_floppy();
StopFloppyMotor();
JumpToBootCode();
break;
@ -238,10 +238,10 @@ void DoBootPartitionOptionsMenu(int BootDriveNum)
}
RestoreScreen(ScreenBuffer);
showcursor();
VideoShowTextCursor();
gotoxy(CursorXPos, CursorYPos);
stop_floppy();
StopFloppyMotor();
JumpToBootCode();
}
}*/
@ -365,7 +365,7 @@ void DrawOptionsMenu(char OptionsMenuItems[][80], int OptionsMenuItemCount, int
int space, space_left, space_right;
// Update the status bar
/*DrawStatusText(" Use \x18\x19 to select, then press ENTER. Press ESC to go back.");
/*DrawStatusText("Use \x18\x19 to select, then press ENTER. Press ESC to go back.");
DrawBox(nOptionsMenuBoxLeft, nOptionsMenuBoxTop, nOptionsMenuBoxRight, nOptionsMenuBoxBottom, D_VERT, D_HORZ, TRUE, TRUE, ATTR(cMenuFgColor, cMenuBgColor));
DrawText(nOptionsMenuBoxLeft + (((nOptionsMenuBoxRight - nOptionsMenuBoxLeft) - strlen(OptionsMenuTitle)) / 2) + 1, nOptionsMenuBoxTop, OptionsMenuTitle, ATTR(cMenuFgColor, cMenuBgColor));

View file

@ -17,19 +17,19 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "freeldr.h"
#include "inifile.h"
#include "oslist.h"
#include "rtl.h"
#include "mm.h"
#include "ui.h"
#include <freeldr.h>
#include <inifile.h>
#include <oslist.h>
#include <rtl.h>
#include <mm.h>
#include <ui.h>
BOOL InitOperatingSystemList(PUCHAR **SectionNamesPointer, PUCHAR **DisplayNamesPointer, PULONG OperatingSystemCountPointer)
{
ULONG Idx;
ULONG CurrentOperatingSystemIndex;
UCHAR SettingName[80];
UCHAR SettingValue[80];
UCHAR SettingName[260];
UCHAR SettingValue[260];
ULONG OperatingSystemCount;
ULONG SectionId;
ULONG OperatingSystemSectionId;
@ -42,7 +42,7 @@ BOOL InitOperatingSystemList(PUCHAR **SectionNamesPointer, PUCHAR **DisplayNames
//
if (!IniOpenSection("FreeLoader", &SectionId))
{
MessageBox("Section [FreeLoader] not found in freeldr.ini.");
UiMessageBox("Section [FreeLoader] not found in freeldr.ini.");
return FALSE;
}
@ -63,9 +63,9 @@ BOOL InitOperatingSystemList(PUCHAR **SectionNamesPointer, PUCHAR **DisplayNames
CurrentOperatingSystemIndex = 0;
for (Idx=0; Idx<SectionSettingCount; Idx++)
{
IniReadSettingByNumber(SectionId, Idx, SettingName, 80, SettingValue, 80);
IniReadSettingByNumber(SectionId, Idx, SettingName, 260, SettingValue, 260);
if (stricmp(SettingName, "OS") == 0)
if (stricmp(SettingName, "OS") == 0 && IniOpenSection(SettingValue, &OperatingSystemSectionId))
{
strcpy(OperatingSystemSectionNames[CurrentOperatingSystemIndex], SettingValue);
@ -80,7 +80,7 @@ BOOL InitOperatingSystemList(PUCHAR **SectionNamesPointer, PUCHAR **DisplayNames
{
if (IniOpenSection(OperatingSystemSectionNames[Idx], &OperatingSystemSectionId))
{
if (IniReadSettingByName(OperatingSystemSectionId, "Name", SettingValue, 80))
if (IniReadSettingByName(OperatingSystemSectionId, "Name", SettingValue, 260))
{
//
// Remove any quotes around the string
@ -90,8 +90,8 @@ BOOL InitOperatingSystemList(PUCHAR **SectionNamesPointer, PUCHAR **DisplayNames
}
else
{
sprintf(SettingName, "Operating System '%s' has no Name= line in it's [section].", OperatingSystemSectionNames[Idx]);
MessageBox(SettingName);
sprintf(SettingName, "Operating System '%s' has no\nName= line in it's [section].", OperatingSystemSectionNames[Idx]);
UiMessageBox(SettingName);
strcpy(OperatingSystemDisplayNames[Idx], "");
}
}
@ -107,8 +107,8 @@ BOOL InitOperatingSystemList(PUCHAR **SectionNamesPointer, PUCHAR **DisplayNames
ULONG CountOperatingSystems(ULONG SectionId)
{
ULONG Idx;
UCHAR SettingName[80];
UCHAR SettingValue[80];
UCHAR SettingName[260];
UCHAR SettingValue[260];
ULONG OperatingSystemCount = 0;
ULONG SectionSettingCount;
@ -118,7 +118,7 @@ ULONG CountOperatingSystems(ULONG SectionId)
SectionSettingCount = IniGetNumSectionItems(SectionId);
for (Idx=0; Idx<SectionSettingCount; Idx++)
{
IniReadSettingByNumber(SectionId, Idx, SettingName, 80, SettingValue, 80);
IniReadSettingByNumber(SectionId, Idx, SettingName, 260, SettingValue, 260);
if (stricmp(SettingName, "OS") == 0)
{
@ -128,8 +128,8 @@ ULONG CountOperatingSystems(ULONG SectionId)
}
else
{
sprintf(SettingName, "Operating System '%s' is listed in freeldr.ini but doesn't have a [section].", SettingValue);
MessageBox(SettingName);
sprintf(SettingName, "Operating System '%s' is listed in\nfreeldr.ini but doesn't have a [section].", SettingValue);
UiMessageBox(SettingName);
}
}
}
@ -146,8 +146,8 @@ BOOL AllocateListMemory(PUCHAR **SectionNamesPointer, PUCHAR **DisplayNamesPoint
//
// Allocate memory to hold operating system list arrays
//
OperatingSystemSectionNames = (PUCHAR*) AllocateMemory( sizeof(PUCHAR) * OperatingSystemCount);
OperatingSystemDisplayNames = (PUCHAR*) AllocateMemory( sizeof(PUCHAR) * OperatingSystemCount);
OperatingSystemSectionNames = (PUCHAR*) MmAllocateMemory( sizeof(PUCHAR) * OperatingSystemCount);
OperatingSystemDisplayNames = (PUCHAR*) MmAllocateMemory( sizeof(PUCHAR) * OperatingSystemCount);
//
// If either allocation failed then return FALSE
@ -156,12 +156,12 @@ BOOL AllocateListMemory(PUCHAR **SectionNamesPointer, PUCHAR **DisplayNamesPoint
{
if (OperatingSystemSectionNames != NULL)
{
FreeMemory(OperatingSystemSectionNames);
MmFreeMemory(OperatingSystemSectionNames);
}
if (OperatingSystemDisplayNames != NULL)
{
FreeMemory(OperatingSystemDisplayNames);
MmFreeMemory(OperatingSystemDisplayNames);
}
return FALSE;
@ -178,8 +178,8 @@ BOOL AllocateListMemory(PUCHAR **SectionNamesPointer, PUCHAR **DisplayNamesPoint
//
for (Idx=0; Idx<OperatingSystemCount; Idx++)
{
OperatingSystemSectionNames[Idx] = (PUCHAR) AllocateMemory(80);
OperatingSystemDisplayNames[Idx] = (PUCHAR) AllocateMemory(80);
OperatingSystemSectionNames[Idx] = (PUCHAR) MmAllocateMemory(80);
OperatingSystemDisplayNames[Idx] = (PUCHAR) MmAllocateMemory(80);
//
// If it failed then jump to the cleanup code
@ -204,20 +204,20 @@ AllocateListMemoryFailed:
{
if (OperatingSystemSectionNames[Idx] != NULL)
{
FreeMemory(OperatingSystemSectionNames[Idx]);
MmFreeMemory(OperatingSystemSectionNames[Idx]);
}
if (OperatingSystemDisplayNames[Idx] != NULL)
{
FreeMemory(OperatingSystemDisplayNames[Idx]);
MmFreeMemory(OperatingSystemDisplayNames[Idx]);
}
}
//
// Free operating system list arrays
//
FreeMemory(OperatingSystemSectionNames);
FreeMemory(OperatingSystemDisplayNames);
MmFreeMemory(OperatingSystemSectionNames);
MmFreeMemory(OperatingSystemDisplayNames);
return FALSE;
}

View file

@ -53,23 +53,23 @@ LoadKernel(PCHAR szFileName, int nPos)
{
strcpy(szBuffer, szShortName);
strcat(szBuffer, " not found.");
MessageBox(szBuffer);
UiMessageBox(szBuffer);
return(FALSE);
}
/*
* Update the status bar with the current file
*/
strcpy(szBuffer, " Reading ");
strcpy(szBuffer, "Reading ");
strcat(szBuffer, szShortName);
DrawStatusText(szBuffer);
UiDrawStatusText(szBuffer);
/*
* Load the kernel
*/
MultiBootLoadKernel(FilePointer);
DrawProgressBar(nPos);
UiDrawProgressBarCenter(nPos, 100);
return(TRUE);
}
@ -87,27 +87,27 @@ LoadDriver(PCHAR szFileName, int nPos)
{
strcpy(value, szFileName);
strcat(value, " not found.");
MessageBox(value);
UiMessageBox(value);
return(FALSE);
}
/*
* Update the status bar with the current file
*/
strcpy(value, " Reading ");
strcpy(value, "Reading ");
p = strrchr(szFileName, '\\');
if (p == NULL)
strcat(value, szFileName);
else
strcat(value, p + 1);
DrawStatusText(value);
UiDrawStatusText(value);
/*
* Load the driver
*/
MultiBootLoadModule(FilePointer, szFileName, NULL);
DrawProgressBar(nPos);
UiDrawProgressBarCenter(nPos, 100);
return(TRUE);
}
@ -125,20 +125,20 @@ LoadNlsFile(PCHAR szFileName, PCHAR szModuleName)
{
strcpy(value, szFileName);
strcat(value, " not found.");
MessageBox(value);
UiMessageBox(value);
return(FALSE);
}
/*
* Update the status bar with the current file
*/
strcpy(value, " Reading ");
strcpy(value, "Reading ");
p = strrchr(szFileName, '\\');
if (p == NULL)
strcat(value, szFileName);
else
strcat(value, p + 1);
DrawStatusText(value);
UiDrawStatusText(value);
/*
* Load the driver
@ -387,7 +387,7 @@ void LoadAndBootReactOS(PUCHAR OperatingSystemName)
if (!IniOpenSection(OperatingSystemName, &SectionId))
{
sprintf(MsgBuffer,"Operating System section '%s' not found in freeldr.ini", OperatingSystemName);
MessageBox(MsgBuffer);
UiMessageBox(MsgBuffer);
return;
}
@ -423,7 +423,7 @@ void LoadAndBootReactOS(PUCHAR OperatingSystemName)
*/
if (!IniReadSettingByName(SectionId, "SystemPath", value, 1024))
{
MessageBox("System path not specified for selected operating system.");
UiMessageBox("System path not specified for selected operating system.");
return;
}
@ -433,7 +433,7 @@ void LoadAndBootReactOS(PUCHAR OperatingSystemName)
if (!DissectArcPath(value, szBootPath, &BootDrive, &BootPartition))
{
sprintf(MsgBuffer,"Invalid system path: '%s'", value);
MessageBox(MsgBuffer);
UiMessageBox(MsgBuffer);
return;
}
@ -460,20 +460,20 @@ void LoadAndBootReactOS(PUCHAR OperatingSystemName)
#ifndef NDEBUG
sprintf(MsgBuffer,"SystemRoot: '%s'", szBootPath);
MessageBox(MsgBuffer);
UiMessageBox(MsgBuffer);
#endif
DrawBackdrop();
UiDrawBackdrop();
DrawStatusText(" Loading...");
DrawProgressBar(0);
UiDrawStatusText("Loading...");
UiDrawProgressBarCenter(0, 100);
/*
* Try to open boot drive
*/
if (!OpenDiskDrive(BootDrive, BootPartition))
{
MessageBox("Failed to open boot drive.");
UiMessageBox("Failed to open boot drive.");
return;
}
@ -569,25 +569,25 @@ void LoadAndBootReactOS(PUCHAR OperatingSystemName)
#ifndef NDEBUG
sprintf(MsgBuffer,"SystemHive: '%s'", szFileName);
MessageBox(MsgBuffer);
UiMessageBox(MsgBuffer);
#endif
FilePointer = OpenFile(szFileName);
if (FilePointer == NULL)
{
strcat(value, " not found.");
MessageBox(value);
UiMessageBox(value);
return;
}
/*
* Update the status bar with the current file
*/
strcpy(name, " Reading ");
strcpy(name, "Reading ");
strcat(name, value);
while (strlen(name) < 80)
strcat(name, " ");
DrawStatusText(name);
UiDrawStatusText(name);
/*
* Load the system hive
@ -596,11 +596,11 @@ void LoadAndBootReactOS(PUCHAR OperatingSystemName)
RegInitializeRegistry();
RegImportHive(Base, Size);
DrawProgressBar(15);
UiDrawProgressBarCenter(15, 100);
#ifndef NDEBUG
sprintf(MsgBuffer,"SystemHive loaded at 0x%x size %u", (unsigned)Base, (unsigned)Size);
MessageBox(MsgBuffer);
UiMessageBox(MsgBuffer);
#endif
/*
@ -611,7 +611,7 @@ void LoadAndBootReactOS(PUCHAR OperatingSystemName)
// RegExportHive("\\Registry\\Machine\\HARDWARE", Base, &Size);
// MultiBootCloseModule(Base, Size);
DrawProgressBar(20);
UiDrawProgressBarCenter(20, 100);
/*
* Load NLS files
@ -624,7 +624,7 @@ void LoadAndBootReactOS(PUCHAR OperatingSystemName)
}
#endif
DrawProgressBar(25);
UiDrawProgressBarCenter(25, 100);
/*
* Load boot drivers
@ -635,8 +635,8 @@ void LoadAndBootReactOS(PUCHAR OperatingSystemName)
/*
* Clear the screen and redraw the backdrop and status bar
*/
DrawBackdrop();
DrawStatusText(" Press any key to boot");
UiDrawBackdrop();
UiDrawStatusText("Press any key to boot");
/*
* Wait for user
@ -649,7 +649,7 @@ void LoadAndBootReactOS(PUCHAR OperatingSystemName)
/*
* Now boot the kernel
*/
stop_floppy();
StopFloppyMotor();
boot_reactos();
}

View file

@ -83,9 +83,9 @@ static BOOL
allocateKeyName(PCHAR *newKeyName, int newKeySize)
{
if (*newKeyName != NULL)
FreeMemory(*newKeyName);
MmFreeMemory(*newKeyName);
*newKeyName = AllocateMemory(newKeySize + 1);
*newKeyName = MmAllocateMemory(newKeySize + 1);
if (*newKeyName == NULL)
return(FALSE);
@ -282,8 +282,8 @@ allocateDataBuffer (PVOID * data, int * dataBufferSize, int dataSize)
if (*dataBufferSize < dataSize)
{
if (*dataBufferSize > 0)
FreeMemory(*data);
*data = AllocateMemory(dataSize);
MmFreeMemory(*data);
*data = MmAllocateMemory(dataSize);
*dataBufferSize = dataSize;
}
@ -497,11 +497,11 @@ RegImportHive(PCHAR ChunkBase,
if (newKeyName != NULL)
{
FreeMemory(newKeyName);
MmFreeMemory(newKeyName);
}
if (data != NULL)
{
FreeMemory(data);
MmFreeMemory(data);
}
return;

View file

@ -39,14 +39,14 @@ static HKEY RootKey;
VOID
RegInitializeRegistry(VOID)
{
RootKey = (HKEY)AllocateMemory(sizeof(KEY));
RootKey = (HKEY)MmAllocateMemory(sizeof(KEY));
InitializeListHead(&RootKey->SubKeyList);
InitializeListHead(&RootKey->ValueList);
InitializeListHead(&RootKey->KeyList);
RootKey->NameSize = 2;
RootKey->Name = (PUCHAR)AllocateMemory(2);
RootKey->Name = (PUCHAR)MmAllocateMemory(2);
strcpy(RootKey->Name, "\\");
RootKey->Type = 0;
@ -131,7 +131,7 @@ RegCreateKey(HKEY ParentKey,
if (Ptr == &CurrentKey->SubKeyList)
{
/* no key found -> create new subkey */
NewKey = (HKEY)AllocateMemory(sizeof(KEY));
NewKey = (HKEY)MmAllocateMemory(sizeof(KEY));
if (NewKey == NULL)
return(ERROR_OUTOFMEMORY);
@ -144,7 +144,7 @@ RegCreateKey(HKEY ParentKey,
InsertTailList(&CurrentKey->SubKeyList, &NewKey->KeyList);
NewKey->NameSize = subkeyLength + 1;
NewKey->Name = (PCHAR)AllocateMemory(NewKey->NameSize);
NewKey->Name = (PCHAR)MmAllocateMemory(NewKey->NameSize);
if (NewKey->Name == NULL)
return(ERROR_OUTOFMEMORY);
memcpy(NewKey->Name, name, subkeyLength);
@ -337,8 +337,8 @@ RegSetValue(HKEY Key,
{
/* set default value */
if (Key->Data != NULL)
FreeMemory(Key->Data);
Key->Data = (PUCHAR)AllocateMemory(DataSize);
MmFreeMemory(Key->Data);
Key->Data = (PUCHAR)MmAllocateMemory(DataSize);
Key->DataSize = DataSize;
Key->Type = Type;
memcpy(Key->Data, Data, DataSize);
@ -367,12 +367,12 @@ RegSetValue(HKEY Key,
#ifndef NDEBUG
printf("No value found - adding new value\n");
#endif
Value = (PVALUE)AllocateMemory(sizeof(VALUE));
Value = (PVALUE)MmAllocateMemory(sizeof(VALUE));
if (Value == NULL)
return(ERROR_OUTOFMEMORY);
InsertTailList(&Key->ValueList, &Value->ValueList);
Value->NameSize = strlen(ValueName)+1;
Value->Name = (PCHAR)AllocateMemory(Value->NameSize);
Value->Name = (PCHAR)MmAllocateMemory(Value->NameSize);
if (Value->Name == NULL)
return(ERROR_OUTOFMEMORY);
strcpy(Value->Name, ValueName);
@ -389,8 +389,8 @@ RegSetValue(HKEY Key,
else
{
if(Value->Data != NULL)
FreeMemory(Value->Data);
Value->Data = (PUCHAR)AllocateMemory(DataSize);
MmFreeMemory(Value->Data);
Value->Data = (PUCHAR)MmAllocateMemory(DataSize);
if (Value->Data == NULL)
return(ERROR_OUTOFMEMORY);
Value->DataSize = DataSize;
@ -483,7 +483,7 @@ RegDeleteValue(HKEY Key,
{
/* delete default value */
if (Key->Data != NULL)
FreeMemory(Key->Data);
MmFreeMemory(Key->Data);
Key->Data = NULL;
Key->DataSize = 0;
Key->Type = 0;
@ -508,21 +508,21 @@ RegDeleteValue(HKEY Key,
/* delete value */
if (Value->Name != NULL)
FreeMemory(Value->Name);
MmFreeMemory(Value->Name);
Value->Name = NULL;
Value->NameSize = 0;
if (Value->DataSize > sizeof(PUCHAR))
{
if (Value->Data != NULL)
FreeMemory(Value->Data);
MmFreeMemory(Value->Data);
}
Value->Data = NULL;
Value->DataSize = 0;
Value->Type = 0;
RemoveEntryList(&Value->ValueList);
FreeMemory(Value);
MmFreeMemory(Value);
}
return(ERROR_SUCCESS);
}

View file

@ -108,12 +108,29 @@ int atoi(char *string)
while(1)
{
if((*str < '0') || (*str > '9'))
break;
if(base == 16)
{
if(((*str < '0') || (*str > '9')) && ((*str < 'a') || (*str > 'f')) && ((*str < 'A') || (*str > 'F')))
break;
result *= base;
result += (*str - '0');
str++;
result *= base;
if((*str >= '0') && (*str <= '9'))
result += (*str - '0');
if((*str >= 'a') && (*str <= 'f'))
result += (*str - 'a') + 10;
if((*str >= 'A') && (*str <= 'F'))
result += (*str - 'A') + 10;
str++;
}
else //if(base == 10)
{
if((*str < '0') || (*str > '9'))
break;
result *= base;
result += (*str - '0');
str++;
}
}
return result;

85
freeldr/freeldr/ui/gui.c Normal file
View file

@ -0,0 +1,85 @@
/*
* FreeLoader
* Copyright (C) 1998-2002 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 <ui.h>
#include "gui.h"
#include <rtl.h>
#include <mm.h>
#include <debug.h>
#include <inifile.h>
#include <version.h>
VOID GuiDrawBackdrop(VOID)
{
}
VOID GuiFillArea(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, UCHAR FillChar, UCHAR Attr /* Color Attributes */)
{
}
VOID GuiDrawShadow(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom)
{
}
VOID GuiDrawBox(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, UCHAR VertStyle, UCHAR HorzStyle, BOOL Fill, BOOL Shadow, UCHAR Attr)
{
}
VOID GuiDrawText(ULONG X, ULONG Y, PUCHAR Text, UCHAR Attr)
{
}
VOID GuiDrawStatusText(PUCHAR StatusText)
{
}
VOID GuiUpdateDateTime(VOID)
{
}
VOID GuiSaveScreen(PUCHAR Buffer)
{
}
VOID GuiRestoreScreen(PUCHAR Buffer)
{
}
VOID GuiMessageBox(PUCHAR MessageText)
{
}
VOID GuiMessageBoxCritical(PUCHAR MessageText)
{
}
VOID GuiDrawProgressBar(ULONG Position, ULONG Range)
{
}
UCHAR GuiTextToColor(PUCHAR ColorText)
{
return 0;
}
UCHAR GuiTextToFillStyle(PUCHAR FillStyleText)
{
return 0;
}

56
freeldr/freeldr/ui/gui.h Normal file
View file

@ -0,0 +1,56 @@
/*
* FreeLoader
* Copyright (C) 1998-2002 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 __GUI_H
#define __GUI_H
#define TUI_SCREEN_MEM 0xB8000
#define TITLE_BOX_CHAR_HEIGHT 5
///////////////////////////////////////////////////////////////////////////////////////
//
// Graphical User Interface Functions
//
///////////////////////////////////////////////////////////////////////////////////////
VOID GuiDrawBackdrop(VOID); // Fills the entire screen with a backdrop
VOID GuiFillArea(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, UCHAR FillChar, UCHAR Attr /* Color Attributes */); // Fills the area specified with FillChar and Attr
VOID GuiDrawShadow(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom); // Draws a shadow on the bottom and right sides of the area specified
VOID GuiDrawBox(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, UCHAR VertStyle, UCHAR HorzStyle, BOOL Fill, BOOL Shadow, UCHAR Attr); // Draws a box around the area specified
VOID GuiDrawText(ULONG X, ULONG Y, PUCHAR Text, UCHAR Attr); // Draws text at coordinates specified
VOID GuiDrawStatusText(PUCHAR StatusText); // Draws text at the very bottom line on the screen
VOID GuiUpdateDateTime(VOID); // Updates the date and time
VOID GuiSaveScreen(PUCHAR Buffer); // Saves the screen so that it can be restored later
VOID GuiRestoreScreen(PUCHAR Buffer); // Restores the screen from a previous save
VOID GuiMessageBox(PUCHAR MessageText); // Displays a message box on the screen with an ok button
VOID GuiMessageBoxCritical(PUCHAR MessageText); // Displays a message box on the screen with an ok button using no system resources
VOID GuiDrawProgressBar(ULONG Position, ULONG Range); // Draws the progress bar showing nPos percent filled
UCHAR GuiTextToColor(PUCHAR ColorText); // Converts the text color into it's equivalent color value
UCHAR GuiTextToFillStyle(PUCHAR FillStyleText); // Converts the text fill into it's equivalent fill value
///////////////////////////////////////////////////////////////////////////////////////
//
// Menu Functions
//
///////////////////////////////////////////////////////////////////////////////////////
BOOL GuiDisplayMenu(PUCHAR MenuItemList[], ULONG MenuItemCount, ULONG DefaultMenuItem, LONG MenuTimeOut, PULONG SelectedMenuItem);
#endif // #defined __GUI_H

View file

@ -17,11 +17,29 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
.text
#define ASM
#include "arch.h"
#ifndef __KEYCODES_H
#define __KEYCODES_H
EXTERN(_FreeLoaderModuleEnd)
.long _FreeLoaderModuleEnd
// Key codes
#define KEY_EXTENDED 0x00
#define KEY_ENTER 0x0D
#define KEY_SPACE 0x20
#define KEY_UP 0x48
#define KEY_DOWN 0x50
#define KEY_LEFT 0x4B
#define KEY_RIGHT 0x4D
#define KEY_ESC 0x1B
#define KEY_F1 0x3B
#define KEY_F2 0x3C
#define KEY_F3 0x3D
#define KEY_F4 0x3E
#define KEY_F5 0x3F
#define KEY_F6 0x40
#define KEY_F7 0x41
#define KEY_F8 0x42
#define KEY_F9 0x43
#define KEY_F10 0x44
#endif // #defined __KEYCODES_H

File diff suppressed because it is too large Load diff

143
freeldr/freeldr/ui/tui.h Normal file
View file

@ -0,0 +1,143 @@
/*
* FreeLoader
* Copyright (C) 1998-2002 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 __TUI_H
#define __TUI_H
#define TUI_SCREEN_MEM 0xB8000
#define TUI_TITLE_BOX_CHAR_HEIGHT 5
///////////////////////////////////////////////////////////////////////////////////////
//
// Textual User Interface Functions
//
///////////////////////////////////////////////////////////////////////////////////////
VOID TuiDrawBackdrop(VOID); // Fills the entire screen with a backdrop
VOID TuiFillArea(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, UCHAR FillChar, UCHAR Attr /* Color Attributes */); // Fills the area specified with FillChar and Attr
VOID TuiDrawShadow(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom); // Draws a shadow on the bottom and right sides of the area specified
VOID TuiDrawBox(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, UCHAR VertStyle, UCHAR HorzStyle, BOOL Fill, BOOL Shadow, UCHAR Attr); // Draws a box around the area specified
VOID TuiDrawText(ULONG X, ULONG Y, PUCHAR Text, UCHAR Attr); // Draws text at coordinates specified
VOID TuiDrawCenteredText(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, PUCHAR TextString, UCHAR Attr); // Draws centered text at the coordinates specified and clips the edges
VOID TuiDrawStatusText(PUCHAR StatusText); // Draws text at the very bottom line on the screen
VOID TuiUpdateDateTime(VOID); // Updates the date and time
VOID TuiSaveScreen(PUCHAR Buffer); // Saves the screen so that it can be restored later
VOID TuiRestoreScreen(PUCHAR Buffer); // Restores the screen from a previous save
VOID TuiMessageBox(PUCHAR MessageText); // Displays a message box on the screen with an ok button
VOID TuiMessageBoxCritical(PUCHAR MessageText); // Displays a message box on the screen with an ok button using no system resources
VOID TuiDrawProgressBarCenter(ULONG Position, ULONG Range); // Draws the progress bar showing nPos percent filled
VOID TuiDrawProgressBar(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, ULONG Position, ULONG Range); // Draws the progress bar showing nPos percent filled
UCHAR TuiTextToColor(PUCHAR ColorText); // Converts the text color into it's equivalent color value
UCHAR TuiTextToFillStyle(PUCHAR FillStyleText); // Converts the text fill into it's equivalent fill value
///////////////////////////////////////////////////////////////////////////////////////
//
// Menu Functions
//
///////////////////////////////////////////////////////////////////////////////////////
typedef struct
{
PUCHAR *MenuItemList;
ULONG MenuItemCount;
LONG MenuTimeRemaining;
ULONG SelectedMenuItem;
ULONG Left;
ULONG Top;
ULONG Right;
ULONG Bottom;
} TUI_MENU_INFO, *PTUI_MENU_INFO;
VOID TuiCalcMenuBoxSize(PTUI_MENU_INFO MenuInfo);
VOID TuiDrawMenu(PTUI_MENU_INFO MenuInfo);
VOID TuiDrawMenuBox(PTUI_MENU_INFO MenuInfo);
VOID TuiDrawMenuItem(PTUI_MENU_INFO MenuInfo, ULONG MenuItemNumber);
ULONG TuiProcessMenuKeyboardEvent(PTUI_MENU_INFO MenuInfo);
BOOL TuiDisplayMenu(PUCHAR MenuItemList[], ULONG MenuItemCount, ULONG DefaultMenuItem, LONG MenuTimeOut, PULONG SelectedMenuItem);
/*
* Combines the foreground and background colors into a single attribute byte
*/
#define ATTR(cFore, cBack) ((cBack << 4)|cFore)
/*
* Fill styles for DrawBackdrop()
*/
#define LIGHT_FILL 0xB0
#define MEDIUM_FILL 0xB1
#define DARK_FILL 0xB2
/*
* Screen colors
*/
#define COLOR_BLACK 0
#define COLOR_BLUE 1
#define COLOR_GREEN 2
#define COLOR_CYAN 3
#define COLOR_RED 4
#define COLOR_MAGENTA 5
#define COLOR_BROWN 6
#define COLOR_GRAY 7
#define COLOR_DARKGRAY 8
#define COLOR_LIGHTBLUE 9
#define COLOR_LIGHTGREEN 10
#define COLOR_LIGHTCYAN 11
#define COLOR_LIGHTRED 12
#define COLOR_LIGHTMAGENTA 13
#define COLOR_YELLOW 14
#define COLOR_WHITE 15
/* Add COLOR_BLINK to a background to cause blinking */
#define COLOR_BLINK 8
/*
* Defines for IBM box drawing characters
*/
#define HORZ (0xc4) /* Single horizontal line */
#define D_HORZ (0xcd) /* Double horizontal line.*/
#define VERT (0xb3) /* Single vertical line */
#define D_VERT (0xba) /* Double vertical line. */
/* Definitions for corners, depending on HORIZ and VERT */
#define UL (0xda)
#define UR (0xbf) /* HORZ and VERT */
#define LL (0xc0)
#define LR (0xd9)
#define D_UL (0xc9)
#define D_UR (0xbb) /* D_HORZ and D_VERT */
#define D_LL (0xc8)
#define D_LR (0xbc)
#define HD_UL (0xd5)
#define HD_UR (0xb8) /* D_HORZ and VERT */
#define HD_LL (0xd4)
#define HD_LR (0xbe)
#define VD_UL (0xd6)
#define VD_UR (0xb7) /* HORZ and D_VERT */
#define VD_LL (0xd3)
#define VD_LR (0xbd)
#endif // #defined __TUI_H

View file

@ -20,53 +20,16 @@
#include <freeldr.h>
#include <rtl.h>
#include <ui.h>
#include "tui.h"
#include "keycodes.h"
#include <options.h>
#include <mm.h>
typedef struct
BOOL TuiDisplayMenu(PUCHAR MenuItemList[], ULONG MenuItemCount, ULONG DefaultMenuItem, LONG MenuTimeOut, PULONG SelectedMenuItem)
{
PUCHAR *MenuItemList;
ULONG MenuItemCount;
LONG MenuTimeRemaining;
ULONG SelectedMenuItem;
ULONG Left;
ULONG Top;
ULONG Right;
ULONG Bottom;
} MENU_INFO, *PMENU_INFO;
VOID CalcMenuBoxSize(PMENU_INFO MenuInfo);
VOID DrawMenu(PMENU_INFO MenuInfo);
VOID DrawMenuBox(PMENU_INFO MenuInfo);
VOID DrawMenuItem(PMENU_INFO MenuInfo, ULONG MenuItemNumber);
ULONG ProcessMenuKeyboardEvent(PMENU_INFO MenuInfo);
extern ULONG nScreenWidth; // Screen Width
extern ULONG nScreenHeight; // Screen Height
extern CHAR cStatusBarFgColor; // Status bar foreground color
extern CHAR cStatusBarBgColor; // Status bar background color
extern CHAR cBackdropFgColor; // Backdrop foreground color
extern CHAR cBackdropBgColor; // Backdrop background color
extern CHAR cBackdropFillStyle; // Backdrop fill style
extern CHAR cTitleBoxFgColor; // Title box foreground color
extern CHAR cTitleBoxBgColor; // Title box background color
extern CHAR cMessageBoxFgColor; // Message box foreground color
extern CHAR cMessageBoxBgColor; // Message box background color
extern CHAR cMenuFgColor; // Menu foreground color
extern CHAR cMenuBgColor; // Menu background color
extern CHAR cTextColor; // Normal text color
extern CHAR cSelectedTextColor; // Selected text color
extern CHAR cSelectedTextBgColor; // Selected text background color
BOOL DisplayMenu(PUCHAR MenuItemList[], ULONG MenuItemCount, ULONG DefaultMenuItem, LONG MenuTimeOut, PULONG SelectedMenuItem)
{
PUCHAR ScreenBuffer;
MENU_INFO MenuInformation;
ULONG CurrentClockSecond;
TUI_MENU_INFO MenuInformation;
ULONG CurrentClockSecond;
//
// The first thing we need to check is the timeout
@ -83,20 +46,6 @@ BOOL DisplayMenu(PUCHAR MenuItemList[], ULONG MenuItemCount, ULONG DefaultMenuIt
return TRUE;
}
//
// Allocate memory to hold screen contents before menu is drawn
//
ScreenBuffer = AllocateMemory(4000);
if (ScreenBuffer == NULL)
{
return FALSE;
}
//
// Save screen contents to our buffer
//
SaveScreen(ScreenBuffer);
//
// Setup the MENU_INFO structure
//
@ -108,12 +57,12 @@ BOOL DisplayMenu(PUCHAR MenuItemList[], ULONG MenuItemCount, ULONG DefaultMenuIt
//
// Calculate the size of the menu box
//
CalcMenuBoxSize(&MenuInformation);
TuiCalcMenuBoxSize(&MenuInformation);
//
// Draw the menu
//
DrawMenu(&MenuInformation);
TuiDrawMenu(&MenuInformation);
//
// Get the current second of time
@ -128,7 +77,7 @@ BOOL DisplayMenu(PUCHAR MenuItemList[], ULONG MenuItemCount, ULONG DefaultMenuIt
//
// Process key presses
//
if (ProcessMenuKeyboardEvent(&MenuInformation) == KEY_ENTER)
if (TuiProcessMenuKeyboardEvent(&MenuInformation) == KEY_ENTER)
{
//
// If they pressed enter then exit this loop
@ -139,7 +88,7 @@ BOOL DisplayMenu(PUCHAR MenuItemList[], ULONG MenuItemCount, ULONG DefaultMenuIt
//
// Update the date & time
//
UpdateDateTime();
UiUpdateDateTime();
if (MenuInformation.MenuTimeRemaining > 0)
{
@ -154,7 +103,7 @@ BOOL DisplayMenu(PUCHAR MenuItemList[], ULONG MenuItemCount, ULONG DefaultMenuIt
//
// Update the menu
//
DrawMenuBox(&MenuInformation);
TuiDrawMenuBox(&MenuInformation);
}
}
else if (MenuInformation.MenuTimeRemaining == 0)
@ -173,17 +122,11 @@ BOOL DisplayMenu(PUCHAR MenuItemList[], ULONG MenuItemCount, ULONG DefaultMenuIt
{
*SelectedMenuItem = MenuInformation.SelectedMenuItem;
}
//
// Restore screen and free the memory
//
RestoreScreen(ScreenBuffer);
FreeMemory(ScreenBuffer);
return TRUE;
}
VOID CalcMenuBoxSize(PMENU_INFO MenuInfo)
VOID TuiCalcMenuBoxSize(PTUI_MENU_INFO MenuInfo)
{
ULONG Idx;
ULONG Width;
@ -218,31 +161,31 @@ VOID CalcMenuBoxSize(PMENU_INFO MenuInfo)
//
// Calculate the menu box area
//
MenuInfo->Left = (nScreenWidth - Width) / 2;
MenuInfo->Left = (UiScreenWidth - Width) / 2;
MenuInfo->Right = (MenuInfo->Left) + Width;
MenuInfo->Top = (( (nScreenHeight - TITLE_BOX_HEIGHT) - Height) / 2 + 1) + (TITLE_BOX_HEIGHT / 2);
MenuInfo->Top = (( (UiScreenHeight - TUI_TITLE_BOX_CHAR_HEIGHT) - Height) / 2 + 1) + (TUI_TITLE_BOX_CHAR_HEIGHT / 2);
MenuInfo->Bottom = (MenuInfo->Top) + Height;
}
VOID DrawMenu(PMENU_INFO MenuInfo)
VOID TuiDrawMenu(PTUI_MENU_INFO MenuInfo)
{
ULONG Idx;
//
// Draw the menu box
//
DrawMenuBox(MenuInfo);
TuiDrawMenuBox(MenuInfo);
//
// Draw each line of the menu
//
for (Idx=0; Idx<MenuInfo->MenuItemCount; Idx++)
{
DrawMenuItem(MenuInfo, Idx);
TuiDrawMenuItem(MenuInfo, Idx);
}
}
VOID DrawMenuBox(PMENU_INFO MenuInfo)
VOID TuiDrawMenuBox(PTUI_MENU_INFO MenuInfo)
{
UCHAR MenuLineText[80];
UCHAR TempString[80];
@ -250,12 +193,12 @@ VOID DrawMenuBox(PMENU_INFO MenuInfo)
//
// Update the status bar
//
DrawStatusText(" Use \x18\x19 to select, ENTER to boot.");
UiDrawStatusText("Use \x18\x19 to select, ENTER to boot.");
//
// Draw the menu box
//
DrawBox(MenuInfo->Left,
UiDrawBox(MenuInfo->Left,
MenuInfo->Top,
MenuInfo->Right,
MenuInfo->Bottom,
@ -263,7 +206,7 @@ VOID DrawMenuBox(PMENU_INFO MenuInfo)
D_HORZ,
FALSE, // Filled
TRUE, // Shadow
ATTR(cMenuFgColor, cMenuBgColor));
ATTR(UiMenuFgColor, UiMenuBgColor));
//
// If there is a timeout draw the time remaining
@ -275,14 +218,14 @@ VOID DrawMenuBox(PMENU_INFO MenuInfo)
strcat(MenuLineText, TempString);
strcat(MenuLineText, " ]");
DrawText(MenuInfo->Right - strlen(MenuLineText) - 1,
UiDrawText(MenuInfo->Right - strlen(MenuLineText) - 1,
MenuInfo->Bottom,
MenuLineText,
ATTR(cMenuFgColor, cMenuBgColor));
ATTR(UiMenuFgColor, UiMenuBgColor));
}
}
VOID DrawMenuItem(PMENU_INFO MenuInfo, ULONG MenuItemNumber)
VOID TuiDrawMenuItem(PTUI_MENU_INFO MenuInfo, ULONG MenuItemNumber)
{
ULONG Idx;
UCHAR MenuLineText[80];
@ -326,21 +269,21 @@ VOID DrawMenuItem(PMENU_INFO MenuInfo, ULONG MenuItemNumber)
//
if (MenuItemNumber == MenuInfo->SelectedMenuItem)
{
DrawText(MenuInfo->Left + 1,
UiDrawText(MenuInfo->Left + 1,
MenuInfo->Top + 1 + MenuItemNumber,
MenuLineText,
ATTR(cSelectedTextColor, cSelectedTextBgColor));
ATTR(UiSelectedTextColor, UiSelectedTextBgColor));
}
else
{
DrawText(MenuInfo->Left + 1,
UiDrawText(MenuInfo->Left + 1,
MenuInfo->Top + 1 + MenuItemNumber,
MenuLineText,
ATTR(cTextColor, cMenuBgColor));
ATTR(UiTextColor, UiMenuBgColor));
}
}
ULONG ProcessMenuKeyboardEvent(PMENU_INFO MenuInfo)
ULONG TuiProcessMenuKeyboardEvent(PTUI_MENU_INFO MenuInfo)
{
ULONG KeyEvent = 0;
@ -355,7 +298,7 @@ ULONG ProcessMenuKeyboardEvent(PMENU_INFO MenuInfo)
if (MenuInfo->MenuTimeRemaining != -1)
{
MenuInfo->MenuTimeRemaining = -1;
DrawMenuBox(MenuInfo);
TuiDrawMenuBox(MenuInfo);
}
//
@ -383,8 +326,8 @@ ULONG ProcessMenuKeyboardEvent(PMENU_INFO MenuInfo)
//
// Update the menu
//
DrawMenuItem(MenuInfo, MenuInfo->SelectedMenuItem + 1); // Deselect previous item
DrawMenuItem(MenuInfo, MenuInfo->SelectedMenuItem); // Select new item
TuiDrawMenuItem(MenuInfo, MenuInfo->SelectedMenuItem + 1); // Deselect previous item
TuiDrawMenuItem(MenuInfo, MenuInfo->SelectedMenuItem); // Select new item
}
break;
@ -398,8 +341,8 @@ ULONG ProcessMenuKeyboardEvent(PMENU_INFO MenuInfo)
//
// Update the menu
//
DrawMenuItem(MenuInfo, MenuInfo->SelectedMenuItem - 1); // Deselect previous item
DrawMenuItem(MenuInfo, MenuInfo->SelectedMenuItem); // Select new item
TuiDrawMenuItem(MenuInfo, MenuInfo->SelectedMenuItem - 1); // Deselect previous item
TuiDrawMenuItem(MenuInfo, MenuInfo->SelectedMenuItem); // Select new item
}
break;

456
freeldr/freeldr/ui/ui.c Normal file
View file

@ -0,0 +1,456 @@
/*
* FreeLoader
* Copyright (C) 1998-2002 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 <ui.h>
#include "tui.h"
#include <rtl.h>
#include <mm.h>
#include <debug.h>
#include <inifile.h>
#include <version.h>
#include <video.h>
#define DISPLAYMODE_TEXT 0
#define DISPLAYMODE_GRAPHICS 1
ULONG UiScreenWidth = 80; // Screen Width
ULONG UiScreenHeight = 25; // Screen Height
UCHAR UiStatusBarFgColor = COLOR_BLACK; // Status bar foreground color
UCHAR UiStatusBarBgColor = COLOR_CYAN; // Status bar background color
UCHAR UiBackdropFgColor = COLOR_WHITE; // Backdrop foreground color
UCHAR UiBackdropBgColor = COLOR_BLUE; // Backdrop background color
UCHAR UiBackdropFillStyle = MEDIUM_FILL; // Backdrop fill style
UCHAR UiTitleBoxFgColor = COLOR_WHITE; // Title box foreground color
UCHAR UiTitleBoxBgColor = COLOR_RED; // Title box background color
UCHAR UiMessageBoxFgColor = COLOR_WHITE; // Message box foreground color
UCHAR UiMessageBoxBgColor = COLOR_BLUE; // Message box background color
UCHAR UiMenuFgColor = COLOR_WHITE; // Menu foreground color
UCHAR UiMenuBgColor = COLOR_BLUE; // Menu background color
UCHAR UiTextColor = COLOR_YELLOW; // Normal text color
UCHAR UiSelectedTextColor = COLOR_BLACK; // Selected text color
UCHAR UiSelectedTextBgColor = COLOR_GRAY; // Selected text background color
UCHAR UiTitleBoxTitleText[260] = "Boot Menu"; // Title box's title text
PUCHAR UiMessageBoxLineText = NULL;
#define UIMESSAGEBOXLINETEXTSIZE 4096
BOOL UserInterfaceUp = FALSE; // Tells us if the user interface is displayed
BOOL UiDisplayMode = DISPLAYMODE_TEXT; // Tells us if we are in text or graphics mode
UCHAR UiMonthNames[12][15] = { "January ", "February ", "March ", "April ", "May ", "June ", "July ", "August ", "September ", "October ", "November ", "December " };
BOOL UiInitialize(VOID)
{
ULONG SectionId;
UCHAR SettingText[260];
ULONG VideoMode = VIDEOMODE_NORMAL_TEXT;
DbgPrint((DPRINT_UI, "Initializing User Interface.\n"));
UiMessageBoxLineText = MmAllocateMemory(UIMESSAGEBOXLINETEXTSIZE);
if (UiMessageBoxLineText == NULL)
{
return FALSE;
}
RtlZeroMemory(UiMessageBoxLineText, UIMESSAGEBOXLINETEXTSIZE);
DbgPrint((DPRINT_UI, "Reading in UI settings from [Display] section.\n"));
if (IniOpenSection("Display", &SectionId))
{
if (IniReadSettingByName(SectionId, "DisplayMode", SettingText, 260))
{
if (BiosDetectVideoCard() == VIDEOCARD_CGA_OR_OTHER)
{
DbgPrint((DPRINT_UI, "CGA or other display adapter detected.\n"));
}
else if (BiosDetectVideoCard() == VIDEOCARD_EGA)
{
DbgPrint((DPRINT_UI, "EGA display adapter detected.\n"));
}
else if (BiosDetectVideoCard() == VIDEOCARD_VGA)
{
DbgPrint((DPRINT_UI, "VGA display adapter detected.\n"));
}
if (stricmp(SettingText, "NORMAL_VGA") == 0)
{
VideoMode = VIDEOMODE_NORMAL_TEXT;
}
else if (stricmp(SettingText, "EXTENDED_VGA") == 0)
{
VideoMode = VIDEOMODE_EXTENDED_TEXT;
}
else
{
VideoMode = atoi(SettingText);
}
if (!VideoSetMode(VideoMode))
{
printf("Error: unable to set video display mode 0x%x\n", VideoMode);
printf("Press any key to continue.\n");
getch();
}
UiScreenWidth = VideoGetCurrentModeResolutionX();
UiScreenHeight = VideoGetCurrentModeResolutionY();
}
if (IniReadSettingByName(SectionId, "TitleText", SettingText, 260))
{
strcpy(UiTitleBoxTitleText, SettingText);
}
if (IniReadSettingByName(SectionId, "StatusBarColor", SettingText, 260))
{
UiStatusBarBgColor = UiTextToColor(SettingText);
}
if (IniReadSettingByName(SectionId, "StatusBarTextColor", SettingText, 260))
{
UiStatusBarFgColor = UiTextToColor(SettingText);
}
if (IniReadSettingByName(SectionId, "BackdropTextColor", SettingText, 260))
{
UiBackdropFgColor = UiTextToColor(SettingText);
}
if (IniReadSettingByName(SectionId, "BackdropColor", SettingText, 260))
{
UiBackdropBgColor = UiTextToColor(SettingText);
}
if (IniReadSettingByName(SectionId, "BackdropFillStyle", SettingText, 260))
{
UiBackdropFillStyle = UiTextToFillStyle(SettingText);
}
if (IniReadSettingByName(SectionId, "TitleBoxTextColor", SettingText, 260))
{
UiTitleBoxFgColor = UiTextToColor(SettingText);
}
if (IniReadSettingByName(SectionId, "TitleBoxColor", SettingText, 260))
{
UiTitleBoxBgColor = UiTextToColor(SettingText);
}
if (IniReadSettingByName(SectionId, "MessageBoxTextColor", SettingText, 260))
{
UiMessageBoxFgColor = UiTextToColor(SettingText);
}
if (IniReadSettingByName(SectionId, "MessageBoxColor", SettingText, 260))
{
UiMessageBoxBgColor = UiTextToColor(SettingText);
}
if (IniReadSettingByName(SectionId, "MenuTextColor", SettingText, 260))
{
UiMenuFgColor = UiTextToColor(SettingText);
}
if (IniReadSettingByName(SectionId, "MenuColor", SettingText, 260))
{
UiMenuBgColor = UiTextToColor(SettingText);
}
if (IniReadSettingByName(SectionId, "TextColor", SettingText, 260))
{
UiTextColor = UiTextToColor(SettingText);
}
if (IniReadSettingByName(SectionId, "SelectedTextColor", SettingText, 260))
{
UiSelectedTextColor = UiTextToColor(SettingText);
}
if (IniReadSettingByName(SectionId, "SelectedColor", SettingText, 260))
{
UiSelectedTextBgColor = UiTextToColor(SettingText);
}
}
VideoClearScreen();
VideoHideTextCursor();
// Draw the backdrop and title box
UiDrawBackdrop();
UserInterfaceUp = TRUE;
DbgPrint((DPRINT_UI, "UiInitialize() returning TRUE.\n"));
return TRUE;
}
VOID UiDrawBackdrop(VOID)
{
if (UiDisplayMode == DISPLAYMODE_TEXT)
{
TuiDrawBackdrop();
}
else
{
//GuiDrawBackdrop();
}
}
VOID UiFillArea(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, UCHAR FillChar, UCHAR Attr /* Color Attributes */)
{
if (UiDisplayMode == DISPLAYMODE_TEXT)
{
TuiFillArea(Left, Top, Right, Bottom, FillChar, Attr);
}
else
{
//GuiFillArea(Left, Top, Right, Bottom, FillChar, Attr);
}
}
VOID UiDrawShadow(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom)
{
if (UiDisplayMode == DISPLAYMODE_TEXT)
{
TuiDrawShadow(Left, Top, Right, Bottom);
}
else
{
//GuiDrawShadow(Left, Top, Right, Bottom);
}
}
VOID UiDrawBox(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, UCHAR VertStyle, UCHAR HorzStyle, BOOL Fill, BOOL Shadow, UCHAR Attr)
{
if (UiDisplayMode == DISPLAYMODE_TEXT)
{
TuiDrawBox(Left, Top, Right, Bottom, VertStyle, HorzStyle, Fill, Shadow, Attr);
}
else
{
//GuiDrawBox(Left, Top, Right, Bottom, VertStyle, HorzStyle, Fill, Shadow, Attr);
}
}
VOID UiDrawText(ULONG X, ULONG Y, PUCHAR Text, UCHAR Attr)
{
if (UiDisplayMode == DISPLAYMODE_TEXT)
{
TuiDrawText(X, Y, Text, Attr);
}
else
{
//GuiDrawText(X, Y, Text, Attr);
}
}
VOID UiDrawCenteredText(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, PUCHAR TextString, UCHAR Attr)
{
if (UiDisplayMode == DISPLAYMODE_TEXT)
{
TuiDrawCenteredText(Left, Top, Right, Bottom, TextString, Attr);
}
else
{
//GuiDrawCenteredText(Left, Top, Right, Bottom, TextString, Attr);
}
}
VOID UiDrawStatusText(PUCHAR StatusText)
{
if (UiDisplayMode == DISPLAYMODE_TEXT)
{
TuiDrawStatusText(StatusText);
}
else
{
//GuiDrawStatusText(StatusText);
}
}
VOID UiUpdateDateTime(VOID)
{
if (UiDisplayMode == DISPLAYMODE_TEXT)
{
TuiUpdateDateTime();
}
else
{
//TuiUpdateDateTime();
}
}
VOID UiMessageBox(PUCHAR MessageText)
{
strcat(UiMessageBoxLineText, MessageText);
// We have not yet displayed the user interface
// We are probably still reading the .ini file
// and have encountered an error. Just use printf()
// and return.
if (!UserInterfaceUp)
{
printf("%s\n", UiMessageBoxLineText);
printf("Press any key\n");
getch();
return;
}
if (UiDisplayMode == DISPLAYMODE_TEXT)
{
TuiMessageBox(UiMessageBoxLineText);
}
else
{
//GuiMessageBox(UiMessageBoxLineText);
}
RtlZeroMemory(UiMessageBoxLineText, UIMESSAGEBOXLINETEXTSIZE);
}
VOID UiMessageBoxCritical(PUCHAR MessageText)
{
// We have not yet displayed the user interface
// We are probably still reading the .ini file
// and have encountered an error. Just use printf()
// and return.
if (!UserInterfaceUp)
{
printf("%s\n", MessageText);
printf("Press any key\n");
getch();
return;
}
if (UiDisplayMode == DISPLAYMODE_TEXT)
{
TuiMessageBoxCritical(MessageText);
}
else
{
//GuiMessageBoxCritical(MessageText);
}
}
VOID UiMessageLine(PUCHAR MessageText)
{
strcat(UiMessageBoxLineText, MessageText);
strcat(UiMessageBoxLineText, "\n");
}
UCHAR UiTextToColor(PUCHAR ColorText)
{
if (UiDisplayMode == DISPLAYMODE_TEXT)
{
return TuiTextToColor(ColorText);
}
else
{
//return GuiTextToColor(ColorText);
}
}
UCHAR UiTextToFillStyle(PUCHAR FillStyleText)
{
if (UiDisplayMode == DISPLAYMODE_TEXT)
{
return TuiTextToFillStyle(FillStyleText);
}
else
{
//return GuiTextToFillStyle(FillStyleText);
}
}
VOID UiDrawProgressBarCenter(ULONG Position, ULONG Range)
{
if (UiDisplayMode == DISPLAYMODE_TEXT)
{
TuiDrawProgressBarCenter(Position, Range);
}
else
{
//GuiDrawProgressBarCenter(Position, Range);
}
}
VOID UiDrawProgressBar(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, ULONG Position, ULONG Range)
{
if (UiDisplayMode == DISPLAYMODE_TEXT)
{
TuiDrawProgressBar(Left, Top, Right, Bottom, Position, Range);
}
else
{
//GuiDrawProgressBar(Left, Top, Right, Bottom, Position, Range);
}
}
VOID UiShowMessageBoxesInSection(PUCHAR SectionName)
{
ULONG Idx;
UCHAR SettingName[80];
UCHAR SettingValue[80];
ULONG SectionId;
//
// Zero out message line text
//
strcpy(UiMessageBoxLineText, "");
if (!IniOpenSection(SectionName, &SectionId))
{
sprintf(SettingName, "Section %s not found in freeldr.ini.\n", SectionName);
UiMessageBox(SettingName);
return;
}
//
// Find all the message box settings and run them
//
for (Idx=0; Idx<IniGetNumSectionItems(SectionId); Idx++)
{
IniReadSettingByNumber(SectionId, Idx, SettingName, 80, SettingValue, 80);
if (stricmp(SettingName, "MessageBox") == 0)
{
UiMessageBox(SettingValue);
}
else if (stricmp(SettingName, "MessageLine") == 0)
{
UiMessageLine(SettingValue);
}
}
//
// Zero out message line text
//
strcpy(UiMessageBoxLineText, "");
}
VOID UiTruncateStringEllipsis(PUCHAR StringText, ULONG MaxChars)
{
}
BOOL UiDisplayMenu(PUCHAR MenuItemList[], ULONG MenuItemCount, ULONG DefaultMenuItem, LONG MenuTimeOut, PULONG SelectedMenuItem)
{
if (UiDisplayMode == DISPLAYMODE_TEXT)
{
return TuiDisplayMenu(MenuItemList, MenuItemCount, DefaultMenuItem, MenuTimeOut, SelectedMenuItem);
}
else
{
//return GuiDisplayMenu(MenuItemList, MenuItemCount, DefaultMenuItem, MenuTimeOut, SelectedMenuItem);
}
}

View file

@ -0,0 +1,57 @@
/*
* FreeLoader
* Copyright (C) 1998-2002 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 <video.h>
#include <comm.h>
VOID VideoClearScreen(VOID)
{
VideoSetMode(VideoGetCurrentMode());
}
VOID VideoWaitForVerticalRetrace(VOID)
{
while ((READ_PORT_UCHAR((PUCHAR)VIDEOPORT_VERTICAL_RETRACE) & 0x08))
{
// Keep reading the port until bit 4 is clear
}
while (!(READ_PORT_UCHAR((PUCHAR)VIDEOPORT_VERTICAL_RETRACE) & 0x08))
{
// Keep reading the port until bit 4 is set
}
}
VOID VideoSetPaletteColor(UCHAR Color, UCHAR Red, UCHAR Green, UCHAR Blue)
{
WRITE_PORT_UCHAR((PUCHAR)VIDEOPORT_PALETTE_WRITE, Color);
WRITE_PORT_UCHAR((PUCHAR)VIDEOPORT_PALETTE_DATA, Red);
WRITE_PORT_UCHAR((PUCHAR)VIDEOPORT_PALETTE_DATA, Green);
WRITE_PORT_UCHAR((PUCHAR)VIDEOPORT_PALETTE_DATA, Blue);
}
VOID VideoGetPaletteColor(UCHAR Color, PUCHAR Red, PUCHAR Green, PUCHAR Blue)
{
WRITE_PORT_UCHAR((PUCHAR)VIDEOPORT_PALETTE_READ, Color);
*Red = READ_PORT_UCHAR((PUCHAR)VIDEOPORT_PALETTE_DATA);
*Green = READ_PORT_UCHAR((PUCHAR)VIDEOPORT_PALETTE_DATA);
*Blue = READ_PORT_UCHAR((PUCHAR)VIDEOPORT_PALETTE_DATA);
}

View file

@ -0,0 +1,179 @@
/*
* FreeLoader
* Copyright (C) 1998-2002 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 <video.h>
ULONG CurrentVideoMode = VIDEOMODE_NORMAL_TEXT;
ULONG VideoResolutionX = 80;
ULONG VideoResolutionY = 25;
BOOL VideoSetMode(ULONG VideoMode)
{
switch (VideoMode)
{
case VIDEOMODE_NORMAL_TEXT:
CurrentVideoMode = VideoMode;
return VideoSetMode80x25();
case VIDEOMODE_EXTENDED_TEXT:
CurrentVideoMode = VideoMode;
return VideoSetMode80x50_80x43();
case VIDEOMODE_80X28:
CurrentVideoMode = VideoMode;
return VideoSetMode80x28();
case VIDEOMODE_80X30:
CurrentVideoMode = VideoMode;
return VideoSetMode80x30();
case VIDEOMODE_80X34:
CurrentVideoMode = VideoMode;
return VideoSetMode80x34();
case VIDEOMODE_80X43:
CurrentVideoMode = VideoMode;
return VideoSetMode80x43();
case VIDEOMODE_80X60:
CurrentVideoMode = VideoMode;
return VideoSetMode80x60();
default:
return FALSE;
}
return TRUE;
}
BOOL VideoSetMode80x25(VOID)
{
BiosSetVideoMode(0x03);
VideoResolutionX = 80;
VideoResolutionY = 25;
return TRUE;
}
BOOL VideoSetMode80x50_80x43(VOID)
{
if (BiosDetectVideoCard() == VIDEOCARD_VGA)
{
BiosSetVideoMode(0x03);
BiosSetVideoFont8x8();
BiosSelectAlternatePrintScreen();
BiosDisableCursorEmulation();
BiosDefineCursor(6, 7);
VideoResolutionX = 80;
VideoResolutionY = 50;
}
else if (BiosDetectVideoCard() == VIDEOCARD_EGA)
{
BiosSetVideoMode(0x03);
BiosSetVideoFont8x8();
BiosSelectAlternatePrintScreen();
BiosDisableCursorEmulation();
BiosDefineCursor(6, 7);
VideoResolutionX = 80;
VideoResolutionY = 43;
}
else // VIDEOCARD_CGA_OR_OTHER
{
return FALSE;
}
return TRUE;
}
BOOL VideoSetMode80x28(VOID)
{
// FIXME: Is this VGA-only?
VideoSetMode80x25();
BiosSetVideoFont8x14();
BiosDefineCursor(11, 12);
VideoResolutionX = 80;
VideoResolutionY = 28;
return TRUE;
}
BOOL VideoSetMode80x43(VOID)
{
// FIXME: Is this VGA-only?
BiosSet350ScanLines();
VideoSetMode80x25();
BiosSetVideoFont8x8();
BiosSelectAlternatePrintScreen();
BiosDisableCursorEmulation();
BiosDefineCursor(6, 7);
VideoResolutionX = 80;
VideoResolutionY = 43;
return TRUE;
}
BOOL VideoSetMode80x30(VOID)
{
// FIXME: Is this VGA-only?
VideoSetMode80x25();
BiosSet480ScanLines();
VideoResolutionX = 80;
VideoResolutionY = 30;
return TRUE;
}
BOOL VideoSetMode80x34(VOID)
{
// FIXME: Is this VGA-only?
VideoSetMode80x25();
BiosSet480ScanLines();
BiosSetVideoFont8x14();
BiosDefineCursor(11, 12);
BiosSetVideoDisplayEnd();
VideoResolutionX = 80;
VideoResolutionY = 34;
return TRUE;
}
BOOL VideoSetMode80x60(VOID)
{
// FIXME: Is this VGA-only?
VideoSetMode80x25();
BiosSet480ScanLines();
BiosSetVideoFont8x8();
BiosSelectAlternatePrintScreen();
BiosDisableCursorEmulation();
BiosDefineCursor(6, 7);
BiosSetVideoDisplayEnd();
VideoResolutionX = 80;
VideoResolutionY = 60;
return TRUE;
}
ULONG VideoGetCurrentModeResolutionX(VOID)
{
return VideoResolutionX;
}
ULONG VideoGetCurrentModeResolutionY(VOID)
{
return VideoResolutionY;
}
ULONG VideoGetCurrentMode(VOID)
{
return CurrentVideoMode;
}

Binary file not shown.

129
freeldr/tools/deptool.c Normal file
View file

@ -0,0 +1,129 @@
//
// deptool.c
// Copyright (C) 2002 by Brian Palmer <brianp@sginet.com>
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ERROR_SUCCESS 0
#define ERROR_NOTENOUGHPARAMS 1
#define ERROR_DEPENDFILENOTFOUND 2
#define ERROR_OUTOFMEMORY 3
#define ERROR_READERROR 4
#define ERROR_WRITEERROR 5
int main(int argc, char *argv[])
{
FILE* DependFile;
int DependFileSize;
char* DependFileData;
char* NewDependFileData;
int CurIdx;
int CurIdx2;
int RuleDependencySplit = 0;
// Make sure they passed enough command line parameters
if (argc < 2)
{
printf("Usage: deptool srcfile.d\n");
return ERROR_NOTENOUGHPARAMS;
}
// Try to open the dependency file
DependFile = fopen(argv[1], "r+t");
if (DependFile == NULL)
{
printf("deptool: No such dependency file: %s\n", argv[1]);
return ERROR_DEPENDFILENOTFOUND;
}
// Get the file size
fseek(DependFile, 0, SEEK_END);
DependFileSize = ftell(DependFile);
rewind(DependFile);
// Allocate memory
DependFileData = (char *)malloc(DependFileSize);
NewDependFileData = (char *)malloc(DependFileSize * 3);
if (!DependFileData || !NewDependFileData)
{
printf("deptool: Out of memory!\n");
fclose(DependFile);
return ERROR_OUTOFMEMORY;
}
memset(DependFileData, 0, DependFileSize);
memset(NewDependFileData, 0, DependFileSize * 3);
// Read in file data
fread(DependFileData, 1, DependFileSize, DependFile);
if (ferror(DependFile))
{
printf("deptool: Dependency file read error.\n");
fclose(DependFile);
return ERROR_READERROR;
}
// Loop through the dependency file data and
// insert the rule for the dependency file itself
for (CurIdx=0,CurIdx2=0; DependFileData[CurIdx]; CurIdx++,CurIdx2++)
{
// Find the first colon ':' in the file and insert
// the rule right before it
if (DependFileData[CurIdx] == ':')
{
NewDependFileData[CurIdx2] = ' ';
CurIdx2++;
strcat(&NewDependFileData[CurIdx2], argv[1]);
CurIdx2 += strlen(argv[1]);
NewDependFileData[CurIdx2] = ' ';
CurIdx2++;
strcat(NewDependFileData, &DependFileData[CurIdx]);
CurIdx2 += 2;
RuleDependencySplit = CurIdx + 2;
break;
}
else
{
NewDependFileData[CurIdx2] = DependFileData[CurIdx];
}
}
// Now loop through all the rule dependencies and
// turn them into rules themselves
strcat(NewDependFileData, "\n\n");
CurIdx = RuleDependencySplit;
CurIdx2 = strlen(NewDependFileData);
for (; DependFileData[CurIdx]; CurIdx++,CurIdx2++)
{
// If it's a line continuation char '\' then skip over it
if (DependFileData[CurIdx] == '\\')
{
CurIdx2--;
continue;
}
// If it's a new line char '\n' then insert a colon ':' to make it a rule
if (DependFileData[CurIdx] == '\n')
{
NewDependFileData[CurIdx2] = ':';
CurIdx2++;
}
NewDependFileData[CurIdx2] = DependFileData[CurIdx];
}
// Write out file data
rewind(DependFile);
fwrite(NewDependFileData, 1, strlen(NewDependFileData), DependFile);
if (ferror(DependFile))
{
printf("deptool: Dependency file write error.\n");
fclose(DependFile);
return ERROR_WRITEERROR;
}
fclose(DependFile);
return ERROR_SUCCESS;
}