diff --git a/freeldr/CHANGELOG b/freeldr/CHANGELOG index 3d858a64bc6..43ff3a19c72 100644 --- a/freeldr/CHANGELOG +++ b/freeldr/CHANGELOG @@ -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 diff --git a/freeldr/FREELDR.INI b/freeldr/FREELDR.INI index b9c4800f98a..22afd4fafbd 100644 --- a/freeldr/FREELDR.INI +++ b/freeldr/FREELDR.INI @@ -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 diff --git a/freeldr/bootsect/fat32.asm b/freeldr/bootsect/fat32.asm index 84e86cd5c83..232b3d0e3f9 100644 --- a/freeldr/bootsect/fat32.asm +++ b/freeldr/bootsect/fat32.asm @@ -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 diff --git a/freeldr/freeldr/Makefile b/freeldr/freeldr/Makefile index b7e684bee48..8a82242fed7 100644 --- a/freeldr/freeldr/Makefile +++ b/freeldr/freeldr/Makefile @@ -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) ############################################# diff --git a/freeldr/freeldr/arch/i386/arch.S b/freeldr/freeldr/arch/i386/arch.S index ee586cb02f6..903b47f3d8f 100644 --- a/freeldr/freeldr/arch/i386/arch.S +++ b/freeldr/freeldr/arch/i386/arch.S @@ -21,7 +21,7 @@ .code16 #define ASM -#include "arch.h" +#include 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 diff --git a/freeldr/freeldr/arch/i386/biosvid.S b/freeldr/freeldr/arch/i386/biosvid.S new file mode 100644 index 00000000000..8bca7dae79b --- /dev/null +++ b/freeldr/freeldr/arch/i386/biosvid.S @@ -0,0 +1,588 @@ +/* + * FreeLoader + * Copyright (C) 1998-2002 Brian Palmer + * Portions from Linux video.S - Display adapter & video mode setup, version 2.13 (14-May-99) + * Copyright (C) 1995 -- 1999 Martin Mares + * 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 + + + +/* + * 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 + + + diff --git a/freeldr/freeldr/arch/i386/boot.S b/freeldr/freeldr/arch/i386/boot.S index 7731ca74b5c..67af7cc2aea 100644 --- a/freeldr/freeldr/arch/i386/boot.S +++ b/freeldr/freeldr/arch/i386/boot.S @@ -21,11 +21,12 @@ .code16 #define ASM -#include "arch.h" +#include - .code32 EXTERN(_ChainLoadBiosBootSectorCode) + .code32 + call switch_to_real .code16 diff --git a/freeldr/freeldr/arch/i386/diskint13.S b/freeldr/freeldr/arch/i386/diskint13.S index 4ea859c806a..9275cd6f317 100644 --- a/freeldr/freeldr/arch/i386/diskint13.S +++ b/freeldr/freeldr/arch/i386/diskint13.S @@ -21,7 +21,7 @@ .code16 #define ASM -#include "arch.h" +#include /* @@ -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 diff --git a/freeldr/freeldr/arch/i386/i386idt.S b/freeldr/freeldr/arch/i386/i386idt.S new file mode 100644 index 00000000000..7fc46fa9ff0 --- /dev/null +++ b/freeldr/freeldr/arch/i386/i386idt.S @@ -0,0 +1,224 @@ +/* + * FreeLoader + * Copyright (C) 1998-2002 Brian Palmer + * + * 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 + + + .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 */ diff --git a/freeldr/freeldr/arch/i386/i386trap.S b/freeldr/freeldr/arch/i386/i386trap.S new file mode 100644 index 00000000000..34c1cd5a5a2 --- /dev/null +++ b/freeldr/freeldr/arch/i386/i386trap.S @@ -0,0 +1,761 @@ +/* + * FreeLoader + * Copyright (C) 1998-2002 Brian Palmer + * + * 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 + + + +.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 \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 diff --git a/freeldr/freeldr/arch/i386/linux.S b/freeldr/freeldr/arch/i386/linux.S index 5e53efb44c5..16a5a001f2d 100644 --- a/freeldr/freeldr/arch/i386/linux.S +++ b/freeldr/freeldr/arch/i386/linux.S @@ -21,7 +21,7 @@ .code16 #define ASM -#include "arch.h" +#include .code32 diff --git a/freeldr/freeldr/arch/i386/mb.S b/freeldr/freeldr/arch/i386/mb.S index 54ad30c8b0d..645ed6d8c85 100644 --- a/freeldr/freeldr/arch/i386/mb.S +++ b/freeldr/freeldr/arch/i386/mb.S @@ -21,8 +21,8 @@ .code16 #define ASM -#include "arch.h" -#include "multiboot.h" +#include +#include /* * Here we assume the kernel is loaded at 1mb diff --git a/freeldr/freeldr/arch/i386/mem.S b/freeldr/freeldr/arch/i386/mem.S index 0744dd3d4de..9381e899584 100644 --- a/freeldr/freeldr/arch/i386/mem.S +++ b/freeldr/freeldr/arch/i386/mem.S @@ -21,94 +21,96 @@ .code16 #define ASM -#include "arch.h" -#include "multiboot.h" +#include +#include - .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 diff --git a/freeldr/freeldr/arch/i386/rtlcode.S b/freeldr/freeldr/arch/i386/rtlcode.S new file mode 100644 index 00000000000..500f15cc859 --- /dev/null +++ b/freeldr/freeldr/arch/i386/rtlcode.S @@ -0,0 +1,470 @@ +/* + * FreeLoader + * Copyright (C) 1998-2002 Brian Palmer + * + * 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 + + +/* + * 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 diff --git a/freeldr/freeldr/cache/blocklist.c b/freeldr/freeldr/cache/blocklist.c index 18028841483..cddadbdaa69 100644 --- a/freeldr/freeldr/cache/blocklist.c +++ b/freeldr/freeldr/cache/blocklist.c @@ -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--; diff --git a/freeldr/freeldr/cache/cache.c b/freeldr/freeldr/cache/cache.c index c739421bd30..c44d115d00e 100644 --- a/freeldr/freeldr/cache/cache.c +++ b/freeldr/freeldr/cache/cache.c @@ -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; } diff --git a/freeldr/freeldr/comm/portio.c b/freeldr/freeldr/comm/portio.c index c8b4f113cbd..77f4d1ce085 100644 --- a/freeldr/freeldr/comm/portio.c +++ b/freeldr/freeldr/comm/portio.c @@ -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 -#include "freeldr.h" +#include /* FUNCTIONS ****************************************************************/ diff --git a/freeldr/freeldr/debug.c b/freeldr/freeldr/debug.c index 7b51ca6871c..b0163549024 100644 --- a/freeldr/freeldr/debug.c +++ b/freeldr/freeldr/debug.c @@ -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; diff --git a/freeldr/freeldr/disk/disk.c b/freeldr/freeldr/disk/disk.c index 93f0580245a..c6e2e515169 100644 --- a/freeldr/freeldr/disk/disk.c +++ b/freeldr/freeldr/disk/disk.c @@ -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) diff --git a/freeldr/freeldr/disk/partition.c b/freeldr/freeldr/disk/partition.c index 821f8f78afc..962f760aeea 100644 --- a/freeldr/freeldr/disk/partition.c +++ b/freeldr/freeldr/disk/partition.c @@ -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)) diff --git a/freeldr/freeldr/freeldr.c b/freeldr/freeldr/freeldr.c index c1d816fb777..e8d26cbf7f6 100644 --- a/freeldr/freeldr/freeldr.c +++ b/freeldr/freeldr/freeldr.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // 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; } diff --git a/freeldr/freeldr/fs/fat.c b/freeldr/freeldr/fs/fat.c index 6d0d28b367a..57623d6d4bc 100644 --- a/freeldr/freeldr/fs/fat.c +++ b/freeldr/freeldr/fs/fat.c @@ -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); } diff --git a/freeldr/freeldr/fs/fs.c b/freeldr/freeldr/fs/fs.c index 80d95224f4e..cd99626843e 100644 --- a/freeldr/freeldr/fs/fs.c +++ b/freeldr/freeldr/fs/fs.c @@ -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); } /* diff --git a/freeldr/freeldr/fs/iso.c b/freeldr/freeldr/fs/iso.c index 8654e649448..05921604feb 100644 --- a/freeldr/freeldr/fs/iso.c +++ b/freeldr/freeldr/fs/iso.c @@ -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; } diff --git a/freeldr/freeldr/include/arch.h b/freeldr/freeldr/include/arch.h index 176b4878ce2..8da23675bf7 100644 --- a/freeldr/freeldr/include/arch.h +++ b/freeldr/freeldr/include/arch.h @@ -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 */ diff --git a/freeldr/freeldr/include/disk.h b/freeldr/freeldr/include/disk.h index 9255bc6afb1..4719f39bf44 100644 --- a/freeldr/freeldr/include/disk.h +++ b/freeldr/freeldr/include/disk.h @@ -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 diff --git a/freeldr/freeldr/include/mm.h b/freeldr/freeldr/include/mm.h index 8b1a30e65e9..8633c006a53 100644 --- a/freeldr/freeldr/include/mm.h +++ b/freeldr/freeldr/include/mm.h @@ -21,19 +21,29 @@ #ifndef __MEMORY_H #define __MEMORY_H -#include + +#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); diff --git a/freeldr/freeldr/include/rtl.h b/freeldr/freeldr/include/rtl.h index 9626f6780c2..0078fb97834 100644 --- a/freeldr/freeldr/include/rtl.h +++ b/freeldr/freeldr/include/rtl.h @@ -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)) diff --git a/freeldr/freeldr/include/ui.h b/freeldr/freeldr/include/ui.h index b48d838d4f7..92f060cca5d 100644 --- a/freeldr/freeldr/include/ui.h +++ b/freeldr/freeldr/include/ui.h @@ -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 diff --git a/freeldr/freeldr/include/version.h b/freeldr/freeldr/include/version.h index 7a5baeba3a7..66da3bd30b1 100644 --- a/freeldr/freeldr/include/version.h +++ b/freeldr/freeldr/include/version.h @@ -22,19 +22,21 @@ /* just some stuff */ -#define VERSION "FreeLoader v1.2.2" -#define COPYRIGHT "Copyright (C) 1998-2002 Brian Palmer " +#define VERSION "FreeLoader v1.3" +#define COPYRIGHT "Copyright (C) 1998-2002 Brian Palmer " +#define AUTHOR_EMAIL "" +#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); diff --git a/freeldr/freeldr/include/video.h b/freeldr/freeldr/include/video.h new file mode 100644 index 00000000000..2ce807da5af --- /dev/null +++ b/freeldr/freeldr/include/video.h @@ -0,0 +1,79 @@ +/* + * FreeLoader + * Copyright (C) 1998-2002 Brian Palmer + * + * 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 diff --git a/freeldr/freeldr/inifile/ini_init.c b/freeldr/freeldr/inifile/ini_init.c index 4bcb53d875f..34735e546d7 100644 --- a/freeldr/freeldr/inifile/ini_init.c +++ b/freeldr/freeldr/inifile/ini_init.c @@ -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; } diff --git a/freeldr/freeldr/inifile/inifile.c b/freeldr/freeldr/inifile/inifile.c index ede7b7a94de..59af7ff9210 100644 --- a/freeldr/freeldr/inifile/inifile.c +++ b/freeldr/freeldr/inifile/inifile.c @@ -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)); diff --git a/freeldr/freeldr/inifile/parse.c b/freeldr/freeldr/inifile/parse.c index 6e5212e3d71..4a7a7fcde48 100644 --- a/freeldr/freeldr/inifile/parse.c +++ b/freeldr/freeldr/inifile/parse.c @@ -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; } diff --git a/freeldr/freeldr/linuxboot.c b/freeldr/freeldr/linuxboot.c index 9498a8b67fe..06cf522876a 100644 --- a/freeldr/freeldr/linuxboot.c +++ b/freeldr/freeldr/linuxboot.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // For RemoveQuotes() +#include 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; diff --git a/freeldr/freeldr/miscboot.c b/freeldr/freeldr/miscboot.c index 98bbce21d0c..0fb37be90f5 100644 --- a/freeldr/freeldr/miscboot.c +++ b/freeldr/freeldr/miscboot.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include 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(); } diff --git a/freeldr/freeldr/mm/mem.h b/freeldr/freeldr/mm/mem.h index 097fa095a71..94e5c0d8cce 100644 --- a/freeldr/freeldr/mm/mem.h +++ b/freeldr/freeldr/mm/mem.h @@ -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 diff --git a/freeldr/freeldr/mm/meminit.c b/freeldr/freeldr/mm/meminit.c new file mode 100644 index 00000000000..8a26b24de90 --- /dev/null +++ b/freeldr/freeldr/mm/meminit.c @@ -0,0 +1,402 @@ +/* + * FreeLoader + * Copyright (C) 1998-2002 Brian Palmer + * + * 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 +#include +#include +#include "mem.h" +#include +#include +#include + + +#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 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 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; + } + } +} diff --git a/freeldr/freeldr/mm/mm.c b/freeldr/freeldr/mm/mm.c index a1ab11afb72..7c333a0bb3d 100644 --- a/freeldr/freeldr/mm/mm.c +++ b/freeldr/freeldr/mm/mm.c @@ -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= 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 (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))) + 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 - * - * 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 -#include -#include -#include "mem.h" -#include -#include -#include - - -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 -} diff --git a/freeldr/freeldr/multiboot.c b/freeldr/freeldr/multiboot.c index fbf2fa323a5..33b94ae575d 100644 --- a/freeldr/freeldr/multiboot.c +++ b/freeldr/freeldr/multiboot.c @@ -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 +#include +#include +#include +#include +#include +#include +#include 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; diff --git a/freeldr/freeldr/options.c b/freeldr/freeldr/options.c index 5fe78af35b9..ecab20d7bcc 100644 --- a/freeldr/freeldr/options.c +++ b/freeldr/freeldr/options.c @@ -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 +#include +#include +#include +#include #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)); diff --git a/freeldr/freeldr/oslist.c b/freeldr/freeldr/oslist.c index 9dfe7e415c8..df01533b025 100644 --- a/freeldr/freeldr/oslist.c +++ b/freeldr/freeldr/oslist.c @@ -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 +#include +#include +#include +#include +#include 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 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; diff --git a/freeldr/freeldr/reactos/registry.c b/freeldr/freeldr/reactos/registry.c index 8b78eacbbf2..aa1c9cee3f0 100644 --- a/freeldr/freeldr/reactos/registry.c +++ b/freeldr/freeldr/reactos/registry.c @@ -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); } diff --git a/freeldr/freeldr/rtl/stdlib.c b/freeldr/freeldr/rtl/stdlib.c index 6bdc954fd22..3908df8fcce 100644 --- a/freeldr/freeldr/rtl/stdlib.c +++ b/freeldr/freeldr/rtl/stdlib.c @@ -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; diff --git a/freeldr/freeldr/ui/gui.c b/freeldr/freeldr/ui/gui.c new file mode 100644 index 00000000000..f22231dd384 --- /dev/null +++ b/freeldr/freeldr/ui/gui.c @@ -0,0 +1,85 @@ +/* + * FreeLoader + * Copyright (C) 1998-2002 Brian Palmer + * + * 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 +#include +#include "gui.h" +#include +#include +#include +#include +#include + +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; +} diff --git a/freeldr/freeldr/ui/gui.h b/freeldr/freeldr/ui/gui.h new file mode 100644 index 00000000000..72171f7e801 --- /dev/null +++ b/freeldr/freeldr/ui/gui.h @@ -0,0 +1,56 @@ +/* + * FreeLoader + * Copyright (C) 1998-2002 Brian Palmer + * + * 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 diff --git a/freeldr/freeldr/end.S b/freeldr/freeldr/ui/keycodes.h similarity index 61% rename from freeldr/freeldr/end.S rename to freeldr/freeldr/ui/keycodes.h index 531940d8f08..cd23ad0e138 100644 --- a/freeldr/freeldr/end.S +++ b/freeldr/freeldr/ui/keycodes.h @@ -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 diff --git a/freeldr/freeldr/ui/tui.c b/freeldr/freeldr/ui/tui.c index 130cf5ace38..9d6bd475967 100644 --- a/freeldr/freeldr/ui/tui.c +++ b/freeldr/freeldr/ui/tui.c @@ -18,214 +18,116 @@ */ #include -#include #include +#include "tui.h" +#include "keycodes.h" +#include #include #include #include #include -ULONG nScreenWidth = 80; // Screen Width -ULONG nScreenHeight = 25; // Screen Height - -CHAR cStatusBarFgColor = COLOR_BLACK; // Status bar foreground color -CHAR cStatusBarBgColor = COLOR_CYAN; // Status bar background color -CHAR cBackdropFgColor = COLOR_WHITE; // Backdrop foreground color -CHAR cBackdropBgColor = COLOR_BLUE; // Backdrop background color -CHAR cBackdropFillStyle = MEDIUM_FILL; // Backdrop fill style -CHAR cTitleBoxFgColor = COLOR_WHITE; // Title box foreground color -CHAR cTitleBoxBgColor = COLOR_RED; // Title box background color -CHAR cMessageBoxFgColor = COLOR_WHITE; // Message box foreground color -CHAR cMessageBoxBgColor = COLOR_BLUE; // Message box background color -CHAR cMenuFgColor = COLOR_WHITE; // Menu foreground color -CHAR cMenuBgColor = COLOR_BLUE; // Menu background color -CHAR cTextColor = COLOR_YELLOW; // Normal text color -CHAR cSelectedTextColor = COLOR_BLACK; // Selected text color -CHAR cSelectedTextBgColor = COLOR_GRAY; // Selected text background color -CHAR szTitleBoxTitleText[260] = "Boot Menu"; // Title box's title text - -PUCHAR szMessageBoxLineText = NULL; - -BOOL UserInterfaceUp = FALSE; // Tells us if the user interface is displayed - - -BOOL InitUserInterface(VOID) -{ - ULONG SectionId; - UCHAR SettingText[260]; - - DbgPrint((DPRINT_UI, "Initializing User Interface.\n")); - - szMessageBoxLineText = AllocateMemory(4096); - - if (szMessageBoxLineText == NULL) - { - return FALSE; - } - - DbgPrint((DPRINT_UI, "Reading in UI settings from [Display] section.\n")); - - if (IniOpenSection("Display", &SectionId)) - { - if (IniReadSettingByName(SectionId, "TitleText", SettingText, 260)) - { - strcpy(szTitleBoxTitleText, SettingText); - } - if (IniReadSettingByName(SectionId, "StatusBarColor", SettingText, 260)) - { - cStatusBarBgColor = TextToColor(SettingText); - } - if (IniReadSettingByName(SectionId, "StatusBarTextColor", SettingText, 260)) - { - cStatusBarFgColor = TextToColor(SettingText); - } - if (IniReadSettingByName(SectionId, "BackdropTextColor", SettingText, 260)) - { - cBackdropFgColor = TextToColor(SettingText); - } - if (IniReadSettingByName(SectionId, "BackdropColor", SettingText, 260)) - { - cBackdropBgColor = TextToColor(SettingText); - } - if (IniReadSettingByName(SectionId, "BackdropFillStyle", SettingText, 260)) - { - cBackdropFillStyle = TextToFillStyle(SettingText); - } - if (IniReadSettingByName(SectionId, "TitleBoxTextColor", SettingText, 260)) - { - cTitleBoxFgColor = TextToColor(SettingText); - } - if (IniReadSettingByName(SectionId, "TitleBoxColor", SettingText, 260)) - { - cTitleBoxBgColor = TextToColor(SettingText); - } - if (IniReadSettingByName(SectionId, "MessageBoxTextColor", SettingText, 260)) - { - cMessageBoxFgColor = TextToColor(SettingText); - } - if (IniReadSettingByName(SectionId, "MessageBoxColor", SettingText, 260)) - { - cMessageBoxBgColor = TextToColor(SettingText); - } - if (IniReadSettingByName(SectionId, "MenuTextColor", SettingText, 260)) - { - cMenuFgColor = TextToColor(SettingText); - } - if (IniReadSettingByName(SectionId, "MenuColor", SettingText, 260)) - { - cMenuBgColor = TextToColor(SettingText); - } - if (IniReadSettingByName(SectionId, "TextColor", SettingText, 260)) - { - cTextColor = TextToColor(SettingText); - } - if (IniReadSettingByName(SectionId, "SelectedTextColor", SettingText, 260)) - { - cSelectedTextColor = TextToColor(SettingText); - } - if (IniReadSettingByName(SectionId, "SelectedColor", SettingText, 260)) - { - cSelectedTextBgColor = TextToColor(SettingText); - } - } - - clrscr(); - hidecursor(); - - // Draw the backdrop and title box - DrawBackdrop(); - - UserInterfaceUp = TRUE; - - DbgPrint((DPRINT_UI, "InitUserInterface() returning TRUE.\n")); - - return TRUE; -} - -void DrawBackdrop(void) +VOID TuiDrawBackdrop(VOID) { // // Fill in the background (excluding title box & status bar) // - FillArea(0, - TITLE_BOX_HEIGHT, - nScreenWidth - 1, - nScreenHeight - 1, - cBackdropFillStyle, - ATTR(cBackdropFgColor, cBackdropBgColor)); + TuiFillArea(0, + TUI_TITLE_BOX_CHAR_HEIGHT, + UiScreenWidth - 1, + UiScreenHeight - 2, + UiBackdropFillStyle, + ATTR(UiBackdropFgColor, UiBackdropBgColor)); // // Draw the title box // - DrawBox(1, - 1, - nScreenWidth, - 5, + TuiDrawBox(0, + 0, + UiScreenWidth - 1, + TUI_TITLE_BOX_CHAR_HEIGHT - 1, D_VERT, D_HORZ, TRUE, FALSE, - ATTR(cTitleBoxFgColor, cTitleBoxBgColor)); + ATTR(UiTitleBoxFgColor, UiTitleBoxBgColor)); // // Draw version text // - DrawText(3, - 2, + TuiDrawText(2, + 1, GetFreeLoaderVersionString(), - ATTR(cTitleBoxFgColor, cTitleBoxBgColor)); + ATTR(UiTitleBoxFgColor, UiTitleBoxBgColor)); // // Draw copyright // - DrawText(3, + TuiDrawText(2, + 2, + BY_AUTHOR, + ATTR(UiTitleBoxFgColor, UiTitleBoxBgColor)); + TuiDrawText(2, 3, - "by Brian Palmer", - ATTR(cTitleBoxFgColor, cTitleBoxBgColor)); - DrawText(3, - 4, - "", - ATTR(cTitleBoxFgColor, cTitleBoxBgColor)); + AUTHOR_EMAIL, + ATTR(UiTitleBoxFgColor, UiTitleBoxBgColor)); // // Draw help text // - //DrawText(nScreenWidth-15, 4, /*"F1 for Help"*/"F8 for Options", ATTR(cTitleBoxFgColor, cTitleBoxBgColor)); + //TuiDrawText(UiScreenWidth - 16, 3, /*"F1 for Help"*/"F8 for Options", ATTR(UiTitleBoxFgColor, UiTitleBoxBgColor)); // // Draw title text // - DrawText( (nScreenWidth / 2) - (strlen(szTitleBoxTitleText)/2), - 3, - szTitleBoxTitleText, - ATTR(cTitleBoxFgColor, cTitleBoxBgColor)); + TuiDrawText( (UiScreenWidth / 2) - (strlen(UiTitleBoxTitleText) / 2), + 2, + UiTitleBoxTitleText, + ATTR(UiTitleBoxFgColor, UiTitleBoxBgColor)); // // Draw status bar // - DrawStatusText(""); + TuiDrawStatusText(""); // // Update the date & time // - UpdateDateTime(); + TuiUpdateDateTime(); } /* * FillArea() * This function assumes coordinates are zero-based */ -void FillArea(int nLeft, int nTop, int nRight, int nBottom, char cFillChar, char cAttr /* Color Attributes */) +VOID TuiFillArea(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, UCHAR FillChar, UCHAR Attr /* Color Attributes */) { - char *screen = (char *)SCREEN_MEM; - int i, j; + PUCHAR ScreenMemory = (PUCHAR)TUI_SCREEN_MEM; + ULONG i, j; - for(i=nTop; i<=nBottom; i++) + // Clip the area to the screen + // FIXME: This code seems to have problems... Uncomment and view ;-) + /*if ((Left >= UiScreenWidth) || (Top >= UiScreenHeight)) { - for(j=nLeft; j<=nRight; j++) + return; + } + if ((Left + Right) >= UiScreenWidth) + { + Right = UiScreenWidth - Left; + } + if ((Top + Bottom) >= UiScreenHeight) + { + Bottom = UiScreenHeight - Top; + }*/ + + // Loop through each line and fill it in + for (i=Top; i<=Bottom; i++) + { + // Loop through each character (column) in the line and fill it in + for (j=Left; j<=Right; j++) { - screen[((i*2)*nScreenWidth)+(j*2)] = cFillChar; - screen[((i*2)*nScreenWidth)+(j*2)+1] = cAttr; + ScreenMemory[((i*2)*UiScreenWidth)+(j*2)] = FillChar; + ScreenMemory[((i*2)*UiScreenWidth)+(j*2)+1] = Attr; } } } @@ -234,295 +136,317 @@ void FillArea(int nLeft, int nTop, int nRight, int nBottom, char cFillChar, char * DrawShadow() * This function assumes coordinates are zero-based */ -void DrawShadow(int nLeft, int nTop, int nRight, int nBottom) +VOID TuiDrawShadow(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom) { - char *screen = (char *)SCREEN_MEM; - int i; + PUCHAR ScreenMemory = (PUCHAR)TUI_SCREEN_MEM; + ULONG Idx; // Shade the bottom of the area - if(nBottom < (nScreenHeight-1)) + if (Bottom < (UiScreenHeight - 1)) { - for(i=nLeft+2; i<=nRight; i++) - screen[(((nBottom+1)*2)*nScreenWidth)+(i*2)+1] = ATTR(COLOR_GRAY, COLOR_BLACK); + if (UiScreenHeight < 34) + { + Idx=Left + 2; + } + else + { + Idx=Left + 1; + } + + for (; Idx<=Right; Idx++) + { + ScreenMemory[(((Bottom+1)*2)*UiScreenWidth)+(Idx*2)+1] = ATTR(COLOR_GRAY, COLOR_BLACK); + } } // Shade the right of the area - if(nRight < (nScreenWidth-1)) + if (Right < (UiScreenWidth - 1)) { - for(i=nTop+1; i<=nBottom; i++) - screen[((i*2)*nScreenWidth)+((nRight+1)*2)+1] = ATTR(COLOR_GRAY, COLOR_BLACK); + for (Idx=Top+1; Idx<=Bottom; Idx++) + { + ScreenMemory[((Idx*2)*UiScreenWidth)+((Right+1)*2)+1] = ATTR(COLOR_GRAY, COLOR_BLACK); + } } - if(nRight+1 < (nScreenWidth-1)) + if (UiScreenHeight < 34) { - for(i=nTop+1; i<=nBottom; i++) - screen[((i*2)*nScreenWidth)+((nRight+2)*2)+1] = ATTR(COLOR_GRAY, COLOR_BLACK); + if ((Right + 1) < (UiScreenWidth - 1)) + { + for (Idx=Top+1; Idx<=Bottom; Idx++) + { + ScreenMemory[((Idx*2)*UiScreenWidth)+((Right+2)*2)+1] = ATTR(COLOR_GRAY, COLOR_BLACK); + } + } } // Shade the bottom right corner - if((nRight < (nScreenWidth-1)) && (nBottom < (nScreenHeight-1))) - screen[(((nBottom+1)*2)*nScreenWidth)+((nRight+1)*2)+1] = ATTR(COLOR_GRAY, COLOR_BLACK); - if((nRight+1 < (nScreenWidth-1)) && (nBottom < (nScreenHeight-1))) - screen[(((nBottom+1)*2)*nScreenWidth)+((nRight+2)*2)+1] = ATTR(COLOR_GRAY, COLOR_BLACK); + if ((Right < (UiScreenWidth - 1)) && (Bottom < (UiScreenHeight - 1))) + { + ScreenMemory[(((Bottom+1)*2)*UiScreenWidth)+((Right+1)*2)+1] = ATTR(COLOR_GRAY, COLOR_BLACK); + } + if (UiScreenHeight < 34) + { + if (((Right + 1) < (UiScreenWidth - 1)) && (Bottom < (UiScreenHeight - 1))) + { + ScreenMemory[(((Bottom+1)*2)*UiScreenWidth)+((Right+2)*2)+1] = ATTR(COLOR_GRAY, COLOR_BLACK); + } + } } /* * DrawBox() - * This function assumes coordinates are one-based + * This function assumes coordinates are zero-based */ -void DrawBox(int nLeft, int nTop, int nRight, int nBottom, int nVertStyle, int nHorzStyle, int bFill, int bShadow, char cAttr) +VOID TuiDrawBox(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, UCHAR VertStyle, UCHAR HorzStyle, BOOL Fill, BOOL Shadow, UCHAR Attr) { - char cULCorner, cURCorner, cLLCorner, cLRCorner; - char cHorz, cVert; + UCHAR ULCorner, URCorner, LLCorner, LRCorner; - nLeft--; - nTop--; - nRight--; - nBottom--; - - cHorz = nHorzStyle; - cVert = nVertStyle; - if(nHorzStyle == HORZ) + // Calculate the corner values + if (HorzStyle == HORZ) { - if(nVertStyle == VERT) + if (VertStyle == VERT) { - cULCorner = UL; - cURCorner = UR; - cLLCorner = LL; - cLRCorner = LR; + ULCorner = UL; + URCorner = UR; + LLCorner = LL; + LRCorner = LR; } - else // nVertStyle == D_VERT + else // VertStyle == D_VERT { - cULCorner = VD_UL; - cURCorner = VD_UR; - cLLCorner = VD_LL; - cLRCorner = VD_LR; + ULCorner = VD_UL; + URCorner = VD_UR; + LLCorner = VD_LL; + LRCorner = VD_LR; } } - else // nHorzStyle == D_HORZ + else // HorzStyle == D_HORZ { - if(nVertStyle == VERT) + if (VertStyle == VERT) { - cULCorner = HD_UL; - cURCorner = HD_UR; - cLLCorner = HD_LL; - cLRCorner = HD_LR; + ULCorner = HD_UL; + URCorner = HD_UR; + LLCorner = HD_LL; + LRCorner = HD_LR; } - else // nVertStyle == D_VERT + else // VertStyle == D_VERT { - cULCorner = D_UL; - cURCorner = D_UR; - cLLCorner = D_LL; - cLRCorner = D_LR; + ULCorner = D_UL; + URCorner = D_UR; + LLCorner = D_LL; + LRCorner = D_LR; } } // Fill in box background - if(bFill) - FillArea(nLeft, nTop, nRight, nBottom, ' ', cAttr); + if (Fill) + { + TuiFillArea(Left, Top, Right, Bottom, ' ', Attr); + } // Fill in corners - FillArea(nLeft, nTop, nLeft, nTop, cULCorner, cAttr); - FillArea(nRight, nTop, nRight, nTop, cURCorner, cAttr); - FillArea(nLeft, nBottom, nLeft, nBottom, cLLCorner, cAttr); - FillArea(nRight, nBottom, nRight, nBottom, cLRCorner, cAttr); + TuiFillArea(Left, Top, Left, Top, ULCorner, Attr); + TuiFillArea(Right, Top, Right, Top, URCorner, Attr); + TuiFillArea(Left, Bottom, Left, Bottom, LLCorner, Attr); + TuiFillArea(Right, Bottom, Right, Bottom, LRCorner, Attr); // Fill in left line - FillArea(nLeft, nTop+1, nLeft, nBottom-1, cVert, cAttr); + TuiFillArea(Left, Top+1, Left, Bottom-1, VertStyle, Attr); // Fill in top line - FillArea(nLeft+1, nTop, nRight-1, nTop, cHorz, cAttr); + TuiFillArea(Left+1, Top, Right-1, Top, HorzStyle, Attr); // Fill in right line - FillArea(nRight, nTop+1, nRight, nBottom-1, cVert, cAttr); + TuiFillArea(Right, Top+1, Right, Bottom-1, VertStyle, Attr); // Fill in bottom line - FillArea(nLeft+1, nBottom, nRight-1, nBottom, cHorz, cAttr); + TuiFillArea(Left+1, Bottom, Right-1, Bottom, HorzStyle, Attr); - if(bShadow) - DrawShadow(nLeft, nTop, nRight, nBottom); + // Draw the shadow + if (Shadow) + { + TuiDrawShadow(Left, Top, Right, Bottom); + } } /* * DrawText() - * This function assumes coordinates are one-based + * This function assumes coordinates are zero-based */ -void DrawText(int nX, int nY, char *text, char cAttr) +VOID TuiDrawText(ULONG X, ULONG Y, PUCHAR Text, UCHAR Attr) { - char *screen = (char *)SCREEN_MEM; - int i, j; - - nX--; - nY--; + PUCHAR ScreenMemory = (PUCHAR)TUI_SCREEN_MEM; + ULONG i, j; // Draw the text - for(i=nX, j=0; text[j]; i++,j++) + for (i=X, j=0; Text[j] && i 12) + // Get the hour and change from 24-hour mode to 12-hour + Hour = gethour(); + if (Hour > 12) { - hour -= 12; - bPM = TRUE; + Hour -= 12; + PMHour = TRUE; + } + if (Hour == 0) + { + Hour = 12; + } + Minute = getminute(); + Second = getsecond(); + itoa(Hour, TempString, 10); + strcpy(TimeString, " "); + strcat(TimeString, TempString); + strcat(TimeString, ":"); + itoa(Minute, TempString, 10); + if (Minute < 10) + { + strcat(TimeString, "0"); + } + strcat(TimeString, TempString); + strcat(TimeString, ":"); + itoa(Second, TempString, 10); + if (Second < 10) + { + strcat(TimeString, "0"); + } + strcat(TimeString, TempString); + if (PMHour) + { + strcat(TimeString, " PM"); } - if (hour == 0) - hour = 12; - minute = getminute(); - second = getsecond(); - itoa(hour, temp, 10); - strcpy(time, " "); - strcat(time, temp); - strcat(time, ":"); - itoa(minute, temp, 10); - if(minute < 10) - strcat(time, "0"); - strcat(time, temp); - strcat(time, ":"); - itoa(second, temp, 10); - if(second < 10) - strcat(time, "0"); - strcat(time, temp); - if(bPM) - strcat(time, " PM"); else - strcat(time, " AM"); + { + strcat(TimeString, " AM"); + } // Draw the time - DrawText(nScreenWidth-strlen(time)-1, 3, time, ATTR(cTitleBoxFgColor, cTitleBoxBgColor)); + TuiDrawText(UiScreenWidth-strlen(TimeString)-2, 2, TimeString, ATTR(UiTitleBoxFgColor, UiTitleBoxBgColor)); } -void SaveScreen(char *buffer) +VOID TuiSaveScreen(PUCHAR Buffer) { - char *screen = (char *)SCREEN_MEM; - int i; + PUCHAR ScreenMemory = (PUCHAR)TUI_SCREEN_MEM; + ULONG i; - for(i=0; i < (nScreenWidth * nScreenHeight * 2); i++) - buffer[i] = screen[i]; + for (i=0; i < (UiScreenWidth * UiScreenHeight * 2); i++) + { + Buffer[i] = ScreenMemory[i]; + } } -void RestoreScreen(char *buffer) +VOID TuiRestoreScreen(PUCHAR Buffer) { - char *screen = (char *)SCREEN_MEM; - int i; + PUCHAR ScreenMemory = (PUCHAR)TUI_SCREEN_MEM; + ULONG i; - for(i=0; i < (nScreenWidth * nScreenHeight * 2); i++) - screen[i] = buffer[i]; + for (i=0; i < (UiScreenWidth * UiScreenHeight * 2); i++) + { + ScreenMemory[i] = Buffer[i]; + } } -void MessageBox(char *text) +VOID TuiMessageBox(PUCHAR MessageText) +{ + PVOID ScreenBuffer; + + // Save the screen contents + ScreenBuffer = MmAllocateMemory(UiScreenWidth * UiScreenHeight * 2); + TuiSaveScreen(ScreenBuffer); + + // Display the message box + TuiMessageBoxCritical(MessageText); + + // Restore the screen contents + TuiRestoreScreen(ScreenBuffer); + MmFreeMemory(ScreenBuffer); +} + +VOID TuiMessageBoxCritical(PUCHAR MessageText) { int width = 8; int height = 1; int curline = 0; int i , j, k; int x1, x2, y1, y2; - PVOID savebuffer; char temp[260]; char key; - if (!UserInterfaceUp) - { - printf("%s%s", szMessageBoxLineText, text); - printf("Press any key.\n"); - getch(); - return; - } - - savebuffer = AllocateMemory(8000); - SaveScreen(savebuffer); - strcat(szMessageBoxLineText, text); - // Find the height - for(i=0; i width) + if (k > width) width = k; k = 0; @@ -530,35 +454,38 @@ void MessageBox(char *text) } // Calculate box area - x1 = (nScreenWidth - (width+2))/2; + x1 = (UiScreenWidth - (width+2))/2; x2 = x1 + width + 3; - y1 = ((nScreenHeight - height - 2)/2) + 1; + y1 = ((UiScreenHeight - height - 2)/2) + 1; y2 = y1 + height + 4; // Draw the box - DrawBox(x1, y1, x2, y2, D_VERT, D_HORZ, TRUE, TRUE, ATTR(cMessageBoxFgColor, cMessageBoxBgColor)); + TuiDrawBox(x1, y1, x2, y2, D_VERT, D_HORZ, TRUE, TRUE, ATTR(UiMessageBoxFgColor, UiMessageBoxBgColor)); // Draw the text - for(i=0,j=0; i Range) + { + Position = Range; + } + + // Draw the box + TuiDrawBox(Left, Top, Right, Bottom, VERT, HORZ, TRUE, TRUE, ATTR(UiMenuFgColor, UiMenuBgColor)); + + // Draw the "Loading..." text + TuiDrawText(70/2, Top+1, "Loading...", ATTR(UiTextColor, UiMenuBgColor)); + + // Draw the percent complete + for (i=0; i<(Position*ProgressBarWidth)/Range; i++) + { + TuiDrawText(Left+2+i, Top+2, "\xDB", ATTR(UiTextColor, UiMenuBgColor)); + } + + // Draw the rest + for (; i 100) - nPos = 100; - - left = (nScreenWidth - width - 4) / 2; - right = left + width + 3; - top = (nScreenHeight - height - 2) / 2; - top += 4; - bottom = top + height + 1; - - // Draw the box - DrawBox(left, top, right, bottom, VERT, HORZ, TRUE, TRUE, ATTR(cMenuFgColor, cMenuBgColor)); - - // Draw the "Loading..." text - DrawText(70/2, top+1, "Loading...", ATTR(cTextColor, cMenuBgColor)); - - // Draw the percent complete - for(i=0; i<(nPos/2); i++) - DrawText(left+2+i, top+2, "\xDB", ATTR(cTextColor, cMenuBgColor)); - - // Draw the rest - for(; i<50; i++) - DrawText(left+2+i, top+2, "\xB2", ATTR(cTextColor, cMenuBgColor)); - - UpdateDateTime(); -} - -void ShowMessageBoxesInSection(PUCHAR SectionName) -{ - ULONG Idx; - UCHAR SettingName[80]; - UCHAR SettingValue[80]; - ULONG SectionId; - - // - // Zero out message line text - // - strcpy(szMessageBoxLineText, ""); - - if (!IniOpenSection(SectionName, &SectionId)) - { - sprintf(SettingName, "Section %s not found in freeldr.ini.\n", SectionName); - MessageBox(SettingName); - return; - } - - // - // Find all the message box settings and run them - // - for (Idx=0; Idx + * + * 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 diff --git a/freeldr/freeldr/ui/menu.c b/freeldr/freeldr/ui/tuimenu.c similarity index 62% rename from freeldr/freeldr/ui/menu.c rename to freeldr/freeldr/ui/tuimenu.c index 329b344e52c..be060c14301 100644 --- a/freeldr/freeldr/ui/menu.c +++ b/freeldr/freeldr/ui/tuimenu.c @@ -20,53 +20,16 @@ #include #include #include +#include "tui.h" +#include "keycodes.h" #include #include -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; IdxMenuItemCount; 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; diff --git a/freeldr/freeldr/ui/ui.c b/freeldr/freeldr/ui/ui.c new file mode 100644 index 00000000000..e0d9727881c --- /dev/null +++ b/freeldr/freeldr/ui/ui.c @@ -0,0 +1,456 @@ +/* + * FreeLoader + * Copyright (C) 1998-2002 Brian Palmer + * + * 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 +#include +#include "tui.h" +#include +#include +#include +#include +#include +#include + + +#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 + * + * 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 +#include +#include + + +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); +} diff --git a/freeldr/freeldr/video/vidmode.c b/freeldr/freeldr/video/vidmode.c new file mode 100644 index 00000000000..8baaac8797d --- /dev/null +++ b/freeldr/freeldr/video/vidmode.c @@ -0,0 +1,179 @@ +/* + * FreeLoader + * Copyright (C) 1998-2002 Brian Palmer + * + * 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 +#include + +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; +} diff --git a/freeldr/sed.exe b/freeldr/sed.exe deleted file mode 100644 index db6416fe9bf..00000000000 Binary files a/freeldr/sed.exe and /dev/null differ diff --git a/freeldr/tools/deptool.c b/freeldr/tools/deptool.c new file mode 100644 index 00000000000..3bd7d5f044c --- /dev/null +++ b/freeldr/tools/deptool.c @@ -0,0 +1,129 @@ +// +// deptool.c +// Copyright (C) 2002 by Brian Palmer +// + +#include +#include +#include + +#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; +}