mirror of
https://github.com/reactos/reactos.git
synced 2024-06-26 07:51:52 +00:00
Changes in v1.7.10 (11/24/2002) (brianp)
- Added assembler versions of memcmp() memcpy() memset() - Implemented Int386() so that real-mode interrupts can be called from C-code - Removed unnecessary call in DbgPrint() macro (freeldr.sys is ~16k smaller now) - 64-bit lba sector addressing for disk calls - Re-coded biosdisk.S as i386disk.c - Re-coded mem.S as i386mem.c - Re-coded rtlcode.S as i386rtl.c - Cleaned up i386trap.S so that it only saves the registers once. - Re-coded biosvid.S as i386vid.c - Video fade in/out - VESA text modes supported now - Offscreen buffering to remove flicker - Standardized format of boot sector so that BootPartition is stored right before 0xaa55 - Prefixed all file system functions with 'Fs' svn path=/trunk/; revision=3782
This commit is contained in:
parent
787724058b
commit
425bbb1543
|
@ -29,7 +29,7 @@ start:
|
|||
nop
|
||||
|
||||
BootDrive db 0x80
|
||||
BootPartition db 0
|
||||
;BootPartition db 0 ; Moved to end of boot sector to have a standard format across all boot sectors
|
||||
;SectorsPerTrack db 63 ; Moved to [bp-SECTORS_PER_TRACK]
|
||||
;NumberOfHeads dw 16 ; Moved to [bp-NUMBER_OF_HEADS]
|
||||
;BiosCHSDriveSize dd (1024 * 1024 * 63) ; Moved to [bp-BIOS_CHS_DRIVE_SIZE]
|
||||
|
@ -274,8 +274,8 @@ ReadSectorsCHSLoop:
|
|||
mov dh,dl ; Head in DH
|
||||
mov dl,[BYTE bp+BootDrive] ; Drive number in DL
|
||||
mov ch,al ; Cylinder in CX
|
||||
ror ah,1 ; Low 8 bits of cylinder in CH, high 2 bits
|
||||
ror ah,1 ; in CL shifted to bits 6 & 7
|
||||
ror ah,2 ; Low 8 bits of cylinder in CH, high 2 bits
|
||||
; in CL shifted to bits 6 & 7
|
||||
or cl,ah ; Or with sector number
|
||||
mov ax,0201h
|
||||
int 13h ; DISK - READ SECTORS INTO MEMORY
|
||||
|
@ -336,7 +336,10 @@ Done:
|
|||
msgDiskError db 'Disk error',0
|
||||
msgAnyKey db 'Press any key to restart',0
|
||||
|
||||
times 510-($-$$) db 0 ; Pad to 510 bytes
|
||||
times 509-($-$$) db 0 ; Pad to 509 bytes
|
||||
|
||||
BootPartition db 0
|
||||
|
||||
dw 0aa55h ; BootSector signature
|
||||
|
||||
|
||||
|
|
|
@ -272,7 +272,7 @@ msgDiskError db 'Disk error',0dh,0ah,0
|
|||
msgFileSystemError db 'File system error',0dh,0ah,0
|
||||
msgAnyKey db 'Press any key to restart',0dh,0ah,0
|
||||
|
||||
times 509-($-$$) db 0 ; Pad to 510 bytes
|
||||
times 509-($-$$) db 0 ; Pad to 509 bytes
|
||||
|
||||
BootPartition:
|
||||
db 0
|
||||
|
|
|
@ -1,3 +1,20 @@
|
|||
Changes in v1.7.10 (11/24/2002) (brianp)
|
||||
|
||||
- Added assembler versions of memcmp() memcpy() memset()
|
||||
- Implemented Int386() so that real-mode interrupts can be called from C-code
|
||||
- Removed unnecessary call in DbgPrint() macro (freeldr.sys is ~16k smaller now)
|
||||
- 64-bit lba sector addressing for disk calls
|
||||
- Re-coded biosdisk.S as i386disk.c
|
||||
- Re-coded mem.S as i386mem.c
|
||||
- Re-coded rtlcode.S as i386rtl.c
|
||||
- Cleaned up i386trap.S so that it only saves the registers once.
|
||||
- Re-coded biosvid.S as i386vid.c
|
||||
- Video fade in/out
|
||||
- VESA text modes supported now
|
||||
- Offscreen buffering to remove flicker
|
||||
- Standardized format of boot sector so that BootPartition is stored right before 0xaa55
|
||||
- Prefixed all file system functions with 'Fs'
|
||||
|
||||
Changes in v1.7.9 (9/30/2002) (brianp)
|
||||
|
||||
- Fix for bug in BiosInt13ReadExtended() (biosdisk.S)
|
||||
|
|
|
@ -23,9 +23,9 @@
|
|||
#
|
||||
TARGET = i386
|
||||
# Debugging information on (bigger binary)
|
||||
DEBUG = yes
|
||||
#DEBUG = yes
|
||||
# Debugging information off (smaller binary)
|
||||
#DEBUG = no
|
||||
DEBUG = no
|
||||
|
||||
OBJDIR = obj
|
||||
OUTPUT_DIR = $(OBJDIR)/$(TARGET)
|
||||
|
@ -192,17 +192,20 @@ ARCH_OBJS = fathelp.o \
|
|||
boot.o \
|
||||
linux.o \
|
||||
mb.o \
|
||||
mem.o \
|
||||
biosdisk.o \
|
||||
rtlcode.o \
|
||||
biosvid.o \
|
||||
drvmap.o
|
||||
i386mem.o \
|
||||
i386rtl.o \
|
||||
i386vid.o \
|
||||
drvmap.o \
|
||||
int386.o \
|
||||
i386disk.o
|
||||
|
||||
RTL_OBJS = memory.o \
|
||||
print.o \
|
||||
RTL_OBJS = print.o \
|
||||
stdlib.o \
|
||||
string.o \
|
||||
list.o
|
||||
list.o \
|
||||
memcmp.o \
|
||||
memcpy.o \
|
||||
memset.o
|
||||
|
||||
FS_OBJS = fs.o \
|
||||
fat.o \
|
||||
|
@ -238,7 +241,11 @@ INIFILE_OBJS= inifile.o \
|
|||
parse.o
|
||||
|
||||
VIDEO_OBJS = video.o \
|
||||
vidmode.o
|
||||
vidmode.o \
|
||||
fade.o \
|
||||
palette.o \
|
||||
pixel.o \
|
||||
bank.o
|
||||
|
||||
# libgcc2.o contains code (__udivdi3, __umoddi3) necessary to do
|
||||
# 64-bit division on the i386 (and other 32-bit) architectures
|
||||
|
|
|
@ -74,6 +74,19 @@ EXTERN(switch_to_prot)
|
|||
|
||||
cli /* None of these */
|
||||
|
||||
/* We don't know what values are currently */
|
||||
/* in the segment registers. So we are */
|
||||
/* going to reload them with sane values. */
|
||||
/* Of course CS has to already be valid. */
|
||||
/* We are currently in real-mode so we */
|
||||
/* need real-mode segment values. */
|
||||
movw $0x0000,%ax
|
||||
movw %ax,%ds
|
||||
movw %ax,%es
|
||||
movw %ax,%fs
|
||||
movw %ax,%gs
|
||||
movw %ax,%ss
|
||||
|
||||
/* Get the return address off the stack */
|
||||
popw (code32ret)
|
||||
|
||||
|
@ -120,6 +133,19 @@ EXTERN(switch_to_real)
|
|||
|
||||
.code32
|
||||
|
||||
/* We don't know what values are currently */
|
||||
/* in the segment registers. So we are */
|
||||
/* going to reload them with sane values. */
|
||||
/* Of course CS has to already be valid. */
|
||||
/* We are currently in protected-mode so we */
|
||||
/* need protected-mode segment values. */
|
||||
movw $PMODE_DS,%ax
|
||||
movw %ax,%ds
|
||||
movw %ax,%es
|
||||
movw %ax,%fs
|
||||
movw %ax,%gs
|
||||
movw %ax,%ss
|
||||
|
||||
/* Get the return address off the stack */
|
||||
popl (code16ret)
|
||||
|
||||
|
@ -157,9 +183,9 @@ inrmode:
|
|||
movw %ax,%ss
|
||||
|
||||
/* Clear out the high 16-bits of ESP */
|
||||
/* This is needed because I have a stupid */
|
||||
/* MS-Win98 boot disk that hangs if there is */
|
||||
/* anything other than 0x0000 in the high */
|
||||
/* This is needed because I have one */
|
||||
/* machine that hangs when booted to dos if */
|
||||
/* anything other than 0x0000 is in the high */
|
||||
/* 16-bits of ESP. Even though real-mode */
|
||||
/* code should only use SP and not ESP. */
|
||||
xorl %esp,%esp
|
||||
|
|
|
@ -1,549 +0,0 @@
|
|||
/*
|
||||
* FreeLoader
|
||||
* Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
.text
|
||||
.code16
|
||||
|
||||
#define ASM
|
||||
#include <arch.h>
|
||||
|
||||
|
||||
/*
|
||||
* BOOL BiosInt13Read(ULONG Drive, ULONG Head, ULONG Track, ULONG Sector, ULONG SectorCount, PVOID Buffer);
|
||||
*/
|
||||
_biosdisk_drive:
|
||||
.long 0
|
||||
_biosdisk_head:
|
||||
.long 0
|
||||
_biosdisk_track:
|
||||
.long 0
|
||||
_biosdisk_sector:
|
||||
.long 0
|
||||
_biosdisk_nsects:
|
||||
.long 0
|
||||
_biosdisk_buffer:
|
||||
.long 0
|
||||
_biosdisk_retval:
|
||||
.long 0
|
||||
_biosdisk_retrycount:
|
||||
.byte 0
|
||||
_biosdisk_error_code:
|
||||
.byte 0
|
||||
EXTERN(_BiosInt13Read)
|
||||
.code32
|
||||
|
||||
pushal
|
||||
|
||||
/* Get parameters */
|
||||
movl 0x24(%esp),%eax
|
||||
movl %eax,_biosdisk_drive
|
||||
movl 0x28(%esp),%eax
|
||||
movl %eax,_biosdisk_head
|
||||
movl 0x2c(%esp),%eax
|
||||
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
|
||||
|
||||
.code16
|
||||
pushw %es // Save this just in case
|
||||
movb $3,_biosdisk_retrycount // Set the retry count to 3
|
||||
|
||||
_biosdisk_read:
|
||||
movl _biosdisk_buffer,%eax // Get buffer address in eax
|
||||
shrl $4,%eax // Make linear address into segment
|
||||
movw %ax,%es // Load ES with segment
|
||||
movl _biosdisk_buffer,%ebx // and BX with offset
|
||||
andl $0x0f,%ebx // so that data gets loaded to [ES:BX]
|
||||
movb _biosdisk_sector,%cl // Get the sector in CL
|
||||
movw _biosdisk_track,%ax // Cylinder in AX
|
||||
movb %al,%ch // Now put it in CH
|
||||
rorb $1,%ah // Low 8 bits of cylinder in CH, high 2 bits
|
||||
rorb $1,%ah // in CL shifted to bits 6 & 7
|
||||
andb $0xc0,%ah // Clear out low six bits
|
||||
orb %ah,%cl // Or with sector number
|
||||
movb _biosdisk_head,%dh // Get the head
|
||||
movb _biosdisk_drive,%dl // Get the drive
|
||||
movb $2,%ah // BIOS int 0x13, function 2 - Read Disk Sectors
|
||||
movb _biosdisk_nsects,%al // Number of sectors to read
|
||||
int $0x13 // Read a sector
|
||||
|
||||
// I have recently learned that not all bioses return
|
||||
// the sector read count in the AL register (at least mine doesn't)
|
||||
// even if the sectors were read correctly. So instead
|
||||
// of checking the sector read count we will rely solely
|
||||
// on the carry flag being set on error
|
||||
|
||||
//jmp _biosdisk_done
|
||||
//cmpb _biosdisk_nsects,%al // See how many sectors we actually read
|
||||
//jne _biosdisk_error // Jump if no error
|
||||
|
||||
movb $1,%al // Set the return value to be one (will be set to zero later if needed)
|
||||
jc _biosdisk_error // Jump if error (CF = 1 on error)
|
||||
jmp _biosdisk_done
|
||||
|
||||
|
||||
_biosdisk_error:
|
||||
movb %ah,_biosdisk_error_code// Save the error code
|
||||
|
||||
cmpb $0x11,%ah // Check and see if it was a corrected ECC error
|
||||
je _biosdisk_done // If so then the data is still good, if not fail
|
||||
|
||||
movb _biosdisk_retrycount,%al// Get the current retry count
|
||||
decb %al // Decrement it
|
||||
movb %al,_biosdisk_retrycount// Save it
|
||||
cmpb $0,%al // Is it zero?
|
||||
jz _biosdisk_zero // Yes, return zero
|
||||
|
||||
movb $0,%ah // BIOS int 0x13, function 0 - Reset Disk System
|
||||
movb _biosdisk_drive,%dl // Get the drive
|
||||
int $0x13 // Reset the disk system
|
||||
jmp _biosdisk_read // Try reading again
|
||||
|
||||
_biosdisk_zero:
|
||||
movb $0,%al // We will return zero
|
||||
|
||||
_biosdisk_done:
|
||||
movzbl %al,%eax // Put the number of sectors read into EAX
|
||||
movl %eax,_biosdisk_retval // Save it as the return value
|
||||
|
||||
popw %es // Restore ES
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
popal
|
||||
|
||||
movl _biosdisk_retval,%eax // Get return value
|
||||
//movl $1,%eax
|
||||
|
||||
ret
|
||||
|
||||
/*
|
||||
* BOOL BiosInt13ReadExtended(ULONG Drive, ULONG Sector, ULONG SectorCount, PVOID Buffer);
|
||||
*/
|
||||
_disk_address_packet:
|
||||
_packet_size:
|
||||
.byte 0x10
|
||||
_packet_reserved:
|
||||
.byte 0
|
||||
_packet_sector_count:
|
||||
.word 0
|
||||
_packet_transfer_buffer_offset:
|
||||
.word 0
|
||||
_packet_transfer_buffer_segment:
|
||||
.word 0
|
||||
_packet_lba_sector_number:
|
||||
.quad 0
|
||||
_packet_64bit_flat_address:
|
||||
.quad 0
|
||||
_int13_extended_drive:
|
||||
.long 0
|
||||
_int13_extended_sector_count:
|
||||
.long 0
|
||||
_int13_extended_retval:
|
||||
.long 0
|
||||
_int13_extended_retrycount:
|
||||
.byte 0
|
||||
EXTERN(_BiosInt13ReadExtended)
|
||||
.code32
|
||||
|
||||
pushal
|
||||
|
||||
/* Get parameters */
|
||||
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 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 0x30(%esp),%eax // Get buffer address in eax
|
||||
andl $0x0f,%eax // Make linear address into offset
|
||||
movw %ax,_packet_transfer_buffer_offset // Save offset
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
pushw %es // Save this just in case
|
||||
movb $3,_int13_extended_retrycount // Set the retry count to 3
|
||||
|
||||
_int13_extended_read:
|
||||
movb _int13_extended_drive,%dl // Get the drive
|
||||
movb $0x42,%ah // BIOS int 0x13, function 42h - IBM/MS INT 13 Extensions - EXTENDED READ
|
||||
movw $_disk_address_packet,%si // DS:SI -> disk address packet
|
||||
int $0x13 // Read sectors
|
||||
|
||||
jc _int13_extended_error // Jump if error (CF = 1 on error)
|
||||
|
||||
movl _int13_extended_sector_count,%eax // Get the sector count in eax
|
||||
cmpw _packet_sector_count,%ax // See how many sectors we actually read (returned in disk address packet sector count)
|
||||
jne _int13_extended_error // Jump if not equal
|
||||
|
||||
jmp _int13_extended_done
|
||||
|
||||
|
||||
_int13_extended_error:
|
||||
movb %ah,_biosdisk_error_code // Save the error code
|
||||
|
||||
cmpb $0x11,%ah // Check and see if it was a corrected ECC error
|
||||
je _int13_extended_done // If so then the data is still good, if not fail
|
||||
|
||||
movb _int13_extended_retrycount,%al // Get the current retry count
|
||||
decb %al // Decrement it
|
||||
movb %al,_int13_extended_retrycount // Save it
|
||||
cmpb $0,%al // Is it zero?
|
||||
jz _int13_extended_zero // Yes, return zero
|
||||
|
||||
movb $0,%ah // BIOS int 0x13, function 0 - Reset Disk System
|
||||
movb _int13_extended_drive,%dl // Get the drive
|
||||
int $0x13 // Reset the disk system
|
||||
jmp _int13_extended_read // Try reading again
|
||||
|
||||
_int13_extended_zero:
|
||||
movb $0,%al // We will return zero
|
||||
|
||||
_int13_extended_done:
|
||||
movzbl %al,%eax // Put the number of sectors read into EAX
|
||||
movl %eax,_int13_extended_retval // Save it as the return value
|
||||
|
||||
popw %es // Restore ES
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
popal
|
||||
|
||||
movl _int13_extended_retval,%eax // Get return value
|
||||
|
||||
ret
|
||||
|
||||
/*
|
||||
* BOOL BiosInt13ExtensionsSupported(ULONG Drive);
|
||||
*/
|
||||
_int13_extension_check_drive:
|
||||
.long 0
|
||||
_int13_extension_check_retval:
|
||||
.long 0
|
||||
EXTERN(_BiosInt13ExtensionsSupported)
|
||||
.code32
|
||||
|
||||
pushal
|
||||
|
||||
/* Get parameters */
|
||||
movl 0x24(%esp),%eax
|
||||
movl %eax,_int13_extension_check_drive
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
// Now make sure this computer supports extended reads
|
||||
movb $0x41,%ah // AH = 41h
|
||||
movw $0x55aa,%bx // BX = 55AAh
|
||||
movb _int13_extension_check_drive,%dl // DL = drive (80h-FFh)
|
||||
int $0x13 // IBM/MS INT 13 Extensions - INSTALLATION CHECK
|
||||
jc _int13_extension_check_error // CF set on error (extensions not supported)
|
||||
cmpw $0xaa55,%bx // BX = AA55h if installed
|
||||
jne _int13_extension_check_error
|
||||
testb $1,%cl // CX = API subset support bitmap
|
||||
jz _int13_extension_check_error // Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported
|
||||
|
||||
// If we get here then we passed all the int13 extension tests
|
||||
movl $1,_int13_extension_check_retval // Set return value to TRUE
|
||||
jmp _int13_extension_check_done
|
||||
|
||||
_int13_extension_check_error:
|
||||
|
||||
movl $0,_int13_extension_check_retval // The tests failed so return FALSE
|
||||
|
||||
_int13_extension_check_done:
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
popal
|
||||
|
||||
movl _int13_extension_check_retval,%eax // Get return value
|
||||
|
||||
ret
|
||||
|
||||
/*
|
||||
* ULONG BiosInt13GetLastErrorCode(VOID);
|
||||
*/
|
||||
EXTERN(_BiosInt13GetLastErrorCode)
|
||||
.code32
|
||||
|
||||
movzbl _biosdisk_error_code,%eax // Get return value
|
||||
|
||||
ret
|
||||
|
||||
|
||||
/*
|
||||
* void StopFloppyMotor(void);
|
||||
*
|
||||
* Stops the floppy drive from spinning, so that other software is
|
||||
* jumped to with a known state.
|
||||
*/
|
||||
EXTERN(_StopFloppyMotor)
|
||||
.code32
|
||||
|
||||
pushal
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
movw $0x3F2, %dx
|
||||
xorb %al, %al
|
||||
outb %al, %dx
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
popal
|
||||
|
||||
ret
|
||||
|
||||
/*
|
||||
* int get_heads(int drive);
|
||||
*/
|
||||
EXTERN(_get_heads)
|
||||
.code32
|
||||
|
||||
pushal
|
||||
push %es
|
||||
|
||||
/* Get drive */
|
||||
movl 0x28(%esp),%eax
|
||||
movl %eax,_biosdisk_drive
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
movb $0x08,%ah
|
||||
movb _biosdisk_drive,%dl
|
||||
int $0x13
|
||||
jc _get_heads_error
|
||||
|
||||
movzbl %dh,%edx
|
||||
incl %edx
|
||||
movl %edx,_biosdisk_retval
|
||||
jmp _get_heads_done
|
||||
|
||||
_get_heads_error:
|
||||
movl $0xff,_biosdisk_retval
|
||||
|
||||
_get_heads_done:
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
pop %es
|
||||
popal
|
||||
|
||||
movl _biosdisk_retval,%eax // Get return value
|
||||
|
||||
ret
|
||||
|
||||
/*
|
||||
* int get_cylinders(int drive);
|
||||
*/
|
||||
EXTERN(_get_cylinders)
|
||||
.code32
|
||||
|
||||
pushal
|
||||
push %es
|
||||
|
||||
/* Get drive */
|
||||
movl 0x28(%esp),%eax
|
||||
movl %eax,_biosdisk_drive
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
movb $0x08,%ah
|
||||
movb _biosdisk_drive,%dl
|
||||
int $0x13
|
||||
jc _get_cylinders_error
|
||||
|
||||
xorl %edx,%edx
|
||||
andb $0xc0,%cl
|
||||
shrb $0x06,%cl
|
||||
movb %cl,%dh
|
||||
movb %ch,%dl
|
||||
incl %edx
|
||||
movl %edx,_biosdisk_retval
|
||||
jmp _get_cylinders_done
|
||||
|
||||
_get_cylinders_error:
|
||||
movl $0xff,_biosdisk_retval
|
||||
|
||||
_get_cylinders_done:
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
pop %es
|
||||
popal
|
||||
|
||||
movl _biosdisk_retval,%eax // Get return value
|
||||
|
||||
ret
|
||||
|
||||
/*
|
||||
* int get_sectors(int drive);
|
||||
*/
|
||||
EXTERN(_get_sectors)
|
||||
.code32
|
||||
|
||||
pushal
|
||||
push %es
|
||||
|
||||
/* Get drive */
|
||||
movl 0x28(%esp),%eax
|
||||
movl %eax,_biosdisk_drive
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
movb $0x08,%ah
|
||||
movb _biosdisk_drive,%dl
|
||||
int $0x13
|
||||
jc _get_sectors_error
|
||||
|
||||
andb $0x3f,%cl
|
||||
movzbl %cl,%ecx
|
||||
movl %ecx,_biosdisk_retval
|
||||
jmp _get_sectors_done
|
||||
|
||||
_get_sectors_error:
|
||||
movl $0xff,_biosdisk_retval
|
||||
|
||||
_get_sectors_done:
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
pop %es
|
||||
popal
|
||||
|
||||
movl _biosdisk_retval,%eax // Get return value
|
||||
|
||||
ret
|
||||
|
||||
|
||||
/*
|
||||
* BOOL BiosInt13GetDriveParameters(ULONG Drive, PGEOMETRY Geometry);
|
||||
*/
|
||||
_bios_int13_cylinders:
|
||||
.long 0
|
||||
_bios_int13_heads:
|
||||
.long 0
|
||||
_bios_int13_sectors:
|
||||
.long 0
|
||||
_bios_int13_bytes_per_sector:
|
||||
.long 0
|
||||
_bios_int13_drive_parameters_struct_address:
|
||||
.long 0
|
||||
EXTERN(_BiosInt13GetDriveParameters)
|
||||
.code32
|
||||
|
||||
pushal
|
||||
push %es
|
||||
|
||||
/* Get drive */
|
||||
movl 0x28(%esp),%eax
|
||||
movl %eax,_biosdisk_drive
|
||||
movl 0x2c(%esp),%eax
|
||||
movl %eax,_bios_int13_drive_parameters_struct_address
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
movb $0x08,%ah
|
||||
movb _biosdisk_drive,%dl
|
||||
int $0x13
|
||||
jc _BiosInt13GetDriveParameters_Error
|
||||
|
||||
// Get the heads
|
||||
movzbl %dh,%eax
|
||||
incl %eax
|
||||
movl %eax,_bios_int13_heads
|
||||
|
||||
// Get the sectors
|
||||
movw %cx,%dx
|
||||
andb $0x3f,%dl
|
||||
movzbl %dl,%edx
|
||||
movl %edx,_bios_int13_sectors
|
||||
|
||||
// Get the cylinders
|
||||
xorl %edx,%edx
|
||||
andb $0xc0,%cl
|
||||
shrb $0x06,%cl
|
||||
movb %cl,%dh
|
||||
movb %ch,%dl
|
||||
incl %edx
|
||||
movl %edx,_bios_int13_cylinders
|
||||
|
||||
// Get the bytes per sector
|
||||
movl $512,_bios_int13_bytes_per_sector // Just assume 512 bytes per sector
|
||||
movl $0x01,_biosdisk_retval
|
||||
jmp _BiosInt13GetDriveParameters_Done
|
||||
|
||||
_BiosInt13GetDriveParameters_Error:
|
||||
movl $0x00,_biosdisk_retval
|
||||
|
||||
_BiosInt13GetDriveParameters_Done:
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
// Copy drive parameters to structure
|
||||
movl $_bios_int13_cylinders,%esi
|
||||
movl _bios_int13_drive_parameters_struct_address,%edi
|
||||
movl $0x04,%ecx
|
||||
cld
|
||||
rep movsl
|
||||
|
||||
pop %es
|
||||
popal
|
||||
|
||||
movl _biosdisk_retval,%eax // Get return value
|
||||
|
||||
ret
|
||||
|
||||
|
|
@ -1,622 +0,0 @@
|
|||
/*
|
||||
* FreeLoader
|
||||
* Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
|
||||
* Portions from Linux video.S - Display adapter & video mode setup, version 2.13 (14-May-99)
|
||||
* Copyright (C) 1995 -- 1999 Martin Mares <mj@ucw.cz>
|
||||
* Based on the original setup.S code (C) Linus Torvalds and Mats Anderson
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
.text
|
||||
.code16
|
||||
|
||||
#define ASM
|
||||
#include <arch.h>
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* VOID BiosSetVideoMode(ULONG VideoMode);
|
||||
*/
|
||||
BiosVideoMode:
|
||||
.long 0
|
||||
EXTERN(_BiosSetVideoMode)
|
||||
.code32
|
||||
|
||||
pushal
|
||||
|
||||
/* Get BIOS video mode */
|
||||
movl 0x24(%esp),%eax
|
||||
movl %eax,BiosVideoMode
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
/* Int 0x10, AH = 0x00 - Set Current Video Mode, also clears the screen */
|
||||
movb $0x00,%ah
|
||||
movb BiosVideoMode,%al
|
||||
int $0x10
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
popal
|
||||
ret
|
||||
|
||||
/*
|
||||
* VOID BiosSetVideoFont8x8(VOID);
|
||||
*/
|
||||
EXTERN(_BiosSetVideoFont8x8)
|
||||
.code32
|
||||
|
||||
pushal
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
/* Int 0x10, AX = 0x1112 - Load 8x8 Font */
|
||||
movw $0x1112,%ax
|
||||
xorb %bl,%bl
|
||||
int $0x10
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
popal
|
||||
ret
|
||||
|
||||
/*
|
||||
* VOID BiosSetVideoFont8x14(VOID);
|
||||
*/
|
||||
EXTERN(_BiosSetVideoFont8x14)
|
||||
.code32
|
||||
|
||||
pushal
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
/* Int 0x10, AX = 0x1111 - Load 8x16 Font */
|
||||
movw $0x1111,%ax
|
||||
xorb %bl,%bl
|
||||
int $0x10
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
popal
|
||||
ret
|
||||
|
||||
/*
|
||||
* VOID BiosSetVideoFont8x16(VOID);
|
||||
*/
|
||||
EXTERN(_BiosSetVideoFont8x16)
|
||||
.code32
|
||||
|
||||
pushal
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
/* Int 0x10, AX = 0x1114 - Load 8x16 Font */
|
||||
movw $0x1114,%ax
|
||||
xorb %bl,%bl
|
||||
int $0x10
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
popal
|
||||
ret
|
||||
|
||||
/*
|
||||
* VOID BiosSelectAlternatePrintScreen(VOID);
|
||||
*/
|
||||
EXTERN(_BiosSelectAlternatePrintScreen)
|
||||
.code32
|
||||
|
||||
pushal
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
/* Int 0x10, AH = 0x12 - Select alternate print screen routine */
|
||||
movb $0x12,%ah
|
||||
movb $0x20,%bl
|
||||
int $0x10
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
popal
|
||||
ret
|
||||
|
||||
/*
|
||||
* VOID BiosDisableCursorEmulation(VOID);
|
||||
*/
|
||||
EXTERN(_BiosDisableCursorEmulation)
|
||||
.code32
|
||||
|
||||
pushal
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
/* Int 0x10, AH = 0x12 - Disable cursor emulation */
|
||||
movw $0x1201,%ax
|
||||
movb $0x34,%bl
|
||||
int $0x10
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
popal
|
||||
ret
|
||||
|
||||
/*
|
||||
* VOID BiosDefineCursor(ULONG StartScanLine, ULONG EndScanLine);
|
||||
*/
|
||||
BiosDefineCursorStartScanLine:
|
||||
.long 0
|
||||
BiosDefineCursorEndScanLine:
|
||||
.long 0
|
||||
EXTERN(_BiosDefineCursor)
|
||||
.code32
|
||||
|
||||
pushal
|
||||
|
||||
/* Get cursor scan line positions */
|
||||
movl 0x24(%esp),%eax
|
||||
movl %eax,BiosDefineCursorStartScanLine
|
||||
movl 0x28(%esp),%eax
|
||||
movl %eax,BiosDefineCursorEndScanLine
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
/* Int 0x10, AH = 0x01 - Set Text-Mode Cursor Shape */
|
||||
movb $0x01,%ah
|
||||
movb $0x03,%al // Current video mode in AL for buggy AMI 386 BIOS
|
||||
movb BiosDefineCursorStartScanLine,%ch
|
||||
movb BiosDefineCursorEndScanLine,%cl
|
||||
int $0x10
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
popal
|
||||
ret
|
||||
|
||||
/*
|
||||
* ULONG BiosDetectVideoCard(VOID);
|
||||
*/
|
||||
BiosDetectVideoCardReturnValue:
|
||||
.long 0
|
||||
EXTERN(_BiosDetectVideoCard)
|
||||
.code32
|
||||
|
||||
pushal
|
||||
|
||||
movl $0x00,BiosDetectVideoCardReturnValue
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
/* Int 0x10, AH = 0x12 - Get EGA Info */
|
||||
movb $0x12,%ah
|
||||
movb $0x10,%bl
|
||||
int $0x10
|
||||
|
||||
movl $0x00,BiosDetectVideoCardReturnValue
|
||||
cmpb $0x10,%bl
|
||||
je BiosDetectVideoCardDone
|
||||
|
||||
/* Int 0x10, AX = 0x1A00 - Get Display Combination Code */
|
||||
movw $0x1a00,%ax
|
||||
int $0x10
|
||||
|
||||
cmpb $0x1a,%al
|
||||
je BiosDetectVideoCardVga
|
||||
|
||||
movl $0x01,BiosDetectVideoCardReturnValue
|
||||
jmp BiosDetectVideoCardDone
|
||||
|
||||
BiosDetectVideoCardVga:
|
||||
|
||||
movl $0x02,BiosDetectVideoCardReturnValue
|
||||
|
||||
BiosDetectVideoCardDone:
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
popal
|
||||
|
||||
movl BiosDetectVideoCardReturnValue,%eax
|
||||
|
||||
ret
|
||||
|
||||
/*
|
||||
* VOID BiosSet200ScanLines(VOID);
|
||||
*/
|
||||
EXTERN(_BiosSet200ScanLines)
|
||||
.code32
|
||||
|
||||
pushal
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
/* Int 0x10, AX = 0x1200 - Set Vertical Resolution */
|
||||
movw $0x1200,%ax
|
||||
movb $0x30,%bl
|
||||
int $0x10
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
popal
|
||||
ret
|
||||
|
||||
/*
|
||||
* VOID BiosSet350ScanLines(VOID);
|
||||
*/
|
||||
EXTERN(_BiosSet350ScanLines)
|
||||
.code32
|
||||
|
||||
pushal
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
/* Int 0x10, AX = 0x1201 - Set Vertical Resolution */
|
||||
movw $0x1201,%ax
|
||||
movb $0x30,%bl
|
||||
int $0x10
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
popal
|
||||
ret
|
||||
|
||||
/*
|
||||
* VOID BiosSet400ScanLines(VOID);
|
||||
*/
|
||||
EXTERN(_BiosSet400ScanLines)
|
||||
.code32
|
||||
|
||||
pushal
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
/* Int 0x10, AX = 0x1202 - Set Vertical Resolution */
|
||||
movw $0x1202,%ax
|
||||
movb $0x30,%bl
|
||||
int $0x10
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
popal
|
||||
ret
|
||||
|
||||
/*
|
||||
* VOID BiosSet480ScanLines(VOID);
|
||||
*/
|
||||
EXTERN(_BiosSet480ScanLines)
|
||||
.code32
|
||||
|
||||
pushal
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
movw $0x03CC,%dx // Get CRTC port
|
||||
inb %dx,%al
|
||||
movb $0xD4,%dl
|
||||
rorb $0x01,%al
|
||||
jc set48a
|
||||
movb $0xB4,%dl
|
||||
|
||||
set48a:
|
||||
movw $0x0C11,%ax // Vertical sync end (also unlocks CR0-7)
|
||||
call outidx
|
||||
movw $0x0B06,%ax // Vertical total
|
||||
call outidx
|
||||
movw $0x3E07,%ax // (vertical) overflow
|
||||
call outidx
|
||||
movw $0xEA10,%ax // Vertical sync start
|
||||
call outidx
|
||||
movw $0xDF12,%ax // Vertical display end
|
||||
call outidx
|
||||
movw $0xE715,%ax // Vertical blank start
|
||||
call outidx
|
||||
movw $0x0416,%ax // Vertical blank end
|
||||
call outidx
|
||||
|
||||
push %dx
|
||||
movb $0xCC,%dl // Misc output register (read)
|
||||
inb %dx,%al
|
||||
movb $0xC2,%dl // (write)
|
||||
andb $0x0D,%al // Preserve clock select bits and color bit
|
||||
orb $0xE2,%al // Set correct sync polarity
|
||||
outb %al,%dx
|
||||
pop %dx
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
popal
|
||||
ret
|
||||
|
||||
/*
|
||||
* VOID BiosSetVideoDisplayEnd(VOID);
|
||||
*/
|
||||
EXTERN(_BiosSetVideoDisplayEnd)
|
||||
.code32
|
||||
|
||||
pushal
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
movw $0x03CC,%dx // Get CRTC port
|
||||
inb %dx,%al
|
||||
movb $0xD4,%dl
|
||||
rorb $0x01,%al
|
||||
jc set48a
|
||||
movb $0xB4,%dl
|
||||
|
||||
setvde:
|
||||
movw $0xDF12,%ax // Vertical display end
|
||||
call outidx
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
popal
|
||||
ret
|
||||
|
||||
/*
|
||||
* Write to indexed VGA register (AL=index, AH=data, DX=index reg. port)
|
||||
*/
|
||||
outidx:
|
||||
.code16
|
||||
|
||||
outb %al,%dx
|
||||
push %ax
|
||||
movb %ah,%al
|
||||
incw %dx
|
||||
outb %al,%dx
|
||||
decw %dx
|
||||
pop %ax
|
||||
|
||||
ret
|
||||
|
||||
/*
|
||||
* VOID VideoSetTextCursorPosition(ULONG X, ULONG Y);
|
||||
*/
|
||||
EXTERN(_VideoSetTextCursorPosition)
|
||||
.code32
|
||||
|
||||
pushal
|
||||
|
||||
/* Get cursor positions */
|
||||
movb 0x24(%esp),%dl
|
||||
movb 0x28(%esp),%dh
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
/* Update the cursor position */
|
||||
movb $2,%ah
|
||||
movb $0,%bh
|
||||
int $0x10
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
popal
|
||||
ret
|
||||
|
||||
|
||||
/*
|
||||
* VOID VideoHideTextCursor(VOID);
|
||||
*/
|
||||
EXTERN(_VideoHideTextCursor)
|
||||
.code32
|
||||
|
||||
pushal
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
/* Hide the cursor */
|
||||
movb $1,%ah
|
||||
movw $0x2000,%cx
|
||||
int $0x10
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
popal
|
||||
ret
|
||||
|
||||
/*
|
||||
* VOID VideoShowTextCursor(VOID);
|
||||
*/
|
||||
EXTERN(_VideoShowTextCursor)
|
||||
.code32
|
||||
|
||||
pushal
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
/* Show the cursor */
|
||||
movb $1,%ah
|
||||
movb $0x0d,%ch
|
||||
movb $0x0e,%cl
|
||||
int $0x10
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
popal
|
||||
ret
|
||||
|
||||
/*
|
||||
* ULONG VideoGetTextCursorPositionX(VOID);
|
||||
*/
|
||||
VideoGetTextCursorPositionXReturnValue:
|
||||
.long 0
|
||||
EXTERN(_VideoGetTextCursorPositionX)
|
||||
.code32
|
||||
|
||||
pushal
|
||||
|
||||
movl $0x00,VideoGetTextCursorPositionXReturnValue
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
/* Get the cursor position */
|
||||
movb $3,%ah
|
||||
movb $0,%bh
|
||||
int $0x10
|
||||
|
||||
/* Save return value */
|
||||
movzbl %dl,%edx
|
||||
movl %edx,VideoGetTextCursorPositionXReturnValue
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
popal
|
||||
|
||||
/* Restore return value */
|
||||
movl VideoGetTextCursorPositionXReturnValue,%eax
|
||||
|
||||
ret
|
||||
|
||||
/*
|
||||
* ULONG VideoGetTextCursorPositionY(VOID);
|
||||
*/
|
||||
VideoGetTextCursorPositionYReturnValue:
|
||||
.long 0
|
||||
EXTERN(_VideoGetTextCursorPositionY)
|
||||
.code32
|
||||
|
||||
pushal
|
||||
|
||||
movl $0x00,VideoGetTextCursorPositionYReturnValue
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
/* Get the cursor position */
|
||||
movb $3,%ah
|
||||
movb $0,%bh
|
||||
int $0x10
|
||||
|
||||
/* Save return value */
|
||||
movzbl %dh,%edx
|
||||
movl %edx,VideoGetTextCursorPositionYReturnValue
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
popal
|
||||
|
||||
/* Restore return value */
|
||||
movl VideoGetTextCursorPositionYReturnValue,%eax
|
||||
|
||||
ret
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* VOID BiosVideoDisableBlinkBit(VOID);
|
||||
*/
|
||||
EXTERN(_BiosVideoDisableBlinkBit)
|
||||
.code32
|
||||
|
||||
pushal
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
/* Toggle Intensity/Blinking Bit */
|
||||
/* AX = 1003h */
|
||||
/* BL = new state */
|
||||
/* 00h background intensity enabled */
|
||||
/* 01h blink enabled */
|
||||
/* Note: although there is no function to get */
|
||||
/* the current status, bit 5 of 0040h:0065h */
|
||||
/* indicates the state. */
|
||||
movw $0x1003,%ax
|
||||
movb $0x00,%bl
|
||||
int $0x10
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
popal
|
||||
|
||||
ret
|
||||
|
||||
|
||||
|
431
freeldr/freeldr/arch/i386/i386disk.c
Normal file
431
freeldr/freeldr/arch/i386/i386disk.c
Normal file
|
@ -0,0 +1,431 @@
|
|||
/*
|
||||
* FreeLoader
|
||||
* Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <freeldr.h>
|
||||
#include <disk.h>
|
||||
#include <rtl.h>
|
||||
#include <arch.h>
|
||||
#include <debug.h>
|
||||
#include <comm.h>
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
U8 PacketSize; // 00h - Size of packet (10h or 18h)
|
||||
U8 Reserved; // 01h - Reserved (0)
|
||||
U16 LBABlockCount; // 02h - Number of blocks to transfer (max 007Fh for Phoenix EDD)
|
||||
U16 TransferBufferOffset; // 04h - Transfer buffer offset (seg:off)
|
||||
U16 TransferBufferSegment; // Transfer buffer segment (seg:off)
|
||||
U64 LBAStartBlock; // 08h - Starting absolute block number
|
||||
U64 TransferBuffer64; // 10h - (EDD-3.0, optional) 64-bit flat address of transfer buffer
|
||||
// used if DWORD at 04h is FFFFh:FFFFh
|
||||
} PACKED I386_DISK_ADDRESS_PACKET, *PI386_DISK_ADDRESS_PACKET;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// FUNCTIONS
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef __i386__
|
||||
|
||||
BOOL DiskReadLogicalSectors(U32 DriveNumber, U64 SectorNumber, U32 SectorCount, PVOID Buffer)
|
||||
{
|
||||
|
||||
DbgPrint((DPRINT_DISK, "DiskReadLogicalSectors() DriveNumber: 0x%x SectorNumber: %d%d SectorCount: %d Buffer: 0x%x\n", DriveNumber, (U32)SectorNumber, SectorCount, Buffer));
|
||||
|
||||
//
|
||||
// Check to see if it is a fixed disk drive
|
||||
// If so then check to see if Int13 extensions work
|
||||
// If they do then use them, otherwise default back to BIOS calls
|
||||
//
|
||||
if ((DriveNumber >= 0x80) && (IsSetupLdr || DiskInt13ExtensionsSupported(DriveNumber)))
|
||||
{
|
||||
DbgPrint((DPRINT_DISK, "Using Int 13 Extensions for read. DiskInt13ExtensionsSupported(%d) = %s\n", DriveNumber, DiskInt13ExtensionsSupported(DriveNumber) ? "TRUE" : "FALSE"));
|
||||
|
||||
//
|
||||
// LBA is easy, nothing to calculate
|
||||
// Just do the read
|
||||
//
|
||||
return DiskReadLogicalSectorsLBA(DriveNumber, SectorNumber, SectorCount, Buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
// LBA is not supported default to the CHS calls
|
||||
return DiskReadLogicalSectorsCHS(DriveNumber, SectorNumber, SectorCount, Buffer);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL DiskReadLogicalSectorsLBA(U32 DriveNumber, U64 SectorNumber, U32 SectorCount, PVOID Buffer)
|
||||
{
|
||||
REGS RegsIn;
|
||||
REGS RegsOut;
|
||||
U32 RetryCount;
|
||||
PI386_DISK_ADDRESS_PACKET Packet = (PI386_DISK_ADDRESS_PACKET)(BIOSCALLBUFFER);
|
||||
|
||||
DbgPrint((DPRINT_DISK, "DiskReadLogicalSectorsLBA()\n"));
|
||||
|
||||
// BIOS int 0x13, function 42h - IBM/MS INT 13 Extensions - EXTENDED READ
|
||||
RegsIn.b.ah = 0x42; // Subfunction 42h
|
||||
RegsIn.b.dl = DriveNumber; // Drive number in DL (0 - floppy, 0x80 - harddisk)
|
||||
RegsIn.x.ds = BIOSCALLBUFSEGMENT; // DS:SI -> disk address packet
|
||||
RegsIn.w.si = BIOSCALLBUFOFFSET;
|
||||
|
||||
// Setup disk address packet
|
||||
RtlZeroMemory(Packet, sizeof(I386_DISK_ADDRESS_PACKET));
|
||||
Packet->PacketSize = sizeof(I386_DISK_ADDRESS_PACKET);
|
||||
Packet->Reserved = 0;
|
||||
Packet->LBABlockCount = SectorCount;
|
||||
Packet->TransferBufferOffset = ((U32)Buffer) & 0x0F;
|
||||
Packet->TransferBufferSegment = ((U32)Buffer) >> 4;
|
||||
Packet->LBAStartBlock = SectorNumber;
|
||||
Packet->TransferBuffer64 = 0;
|
||||
|
||||
// BIOS int 0x13, function 42h - IBM/MS INT 13 Extensions - EXTENDED READ
|
||||
// Return:
|
||||
// CF clear if successful
|
||||
// AH = 00h
|
||||
// CF set on error
|
||||
// AH = error code
|
||||
// disk address packet's block count field set to the
|
||||
// number of blocks successfully transferred
|
||||
|
||||
// Retry 3 times
|
||||
for (RetryCount=0; RetryCount<3; RetryCount++)
|
||||
{
|
||||
Int386(0x13, &RegsIn, &RegsOut);
|
||||
|
||||
// If it worked return TRUE
|
||||
if (INT386_SUCCESS(RegsOut))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
// If it was a corrected ECC error then the data is still good
|
||||
else if (RegsOut.b.ah == 0x11)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
// If it failed the do the next retry
|
||||
else
|
||||
{
|
||||
DiskResetController(DriveNumber);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// If we get here then the read failed
|
||||
DiskError("Disk Read Failed", RegsOut.b.ah);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL DiskReadLogicalSectorsCHS(U32 DriveNumber, U64 SectorNumber, U32 SectorCount, PVOID Buffer)
|
||||
{
|
||||
U32 PhysicalSector;
|
||||
U32 PhysicalHead;
|
||||
U32 PhysicalTrack;
|
||||
GEOMETRY DriveGeometry;
|
||||
U32 NumberOfSectorsToRead;
|
||||
REGS RegsIn;
|
||||
REGS RegsOut;
|
||||
U32 RetryCount;
|
||||
|
||||
DbgPrint((DPRINT_DISK, "DiskReadLogicalSectorsCHS()\n"));
|
||||
|
||||
//
|
||||
// Get the drive geometry
|
||||
//
|
||||
if (!DiskGetDriveGeometry(DriveNumber, &DriveGeometry))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
while (SectorCount)
|
||||
{
|
||||
|
||||
//
|
||||
// Calculate the physical disk offsets
|
||||
//
|
||||
PhysicalSector = 1 + (SectorNumber % DriveGeometry.Sectors);
|
||||
PhysicalHead = (SectorNumber / DriveGeometry.Sectors) % DriveGeometry.Heads;
|
||||
PhysicalTrack = (SectorNumber / DriveGeometry.Sectors) / DriveGeometry.Heads;
|
||||
|
||||
//
|
||||
// Calculate how many sectors we need to read this round
|
||||
//
|
||||
if (PhysicalSector > 1)
|
||||
{
|
||||
if (SectorCount >= (DriveGeometry.Sectors - (PhysicalSector - 1)))
|
||||
NumberOfSectorsToRead = (DriveGeometry.Sectors - (PhysicalSector - 1));
|
||||
else
|
||||
NumberOfSectorsToRead = SectorCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SectorCount >= DriveGeometry.Sectors)
|
||||
NumberOfSectorsToRead = DriveGeometry.Sectors;
|
||||
else
|
||||
NumberOfSectorsToRead = SectorCount;
|
||||
}
|
||||
|
||||
//
|
||||
// Make sure the read is within the geometry boundaries
|
||||
//
|
||||
if ((PhysicalHead >= DriveGeometry.Heads) ||
|
||||
(PhysicalTrack >= DriveGeometry.Cylinders) ||
|
||||
((NumberOfSectorsToRead + PhysicalSector) > (DriveGeometry.Sectors + 1)) ||
|
||||
(PhysicalSector > DriveGeometry.Sectors))
|
||||
{
|
||||
DiskError("Disk read exceeds drive geometry limits.", 0);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// BIOS Int 13h, function 2 - Read Disk Sectors
|
||||
// AH = 02h
|
||||
// AL = number of sectors to read (must be nonzero)
|
||||
// CH = low eight bits of cylinder number
|
||||
// CL = sector number 1-63 (bits 0-5)
|
||||
// high two bits of cylinder (bits 6-7, hard disk only)
|
||||
// DH = head number
|
||||
// DL = drive number (bit 7 set for hard disk)
|
||||
// ES:BX -> data buffer
|
||||
// Return:
|
||||
// CF set on error
|
||||
// if AH = 11h (corrected ECC error), AL = burst length
|
||||
// CF clear if successful
|
||||
// AH = status
|
||||
// AL = number of sectors transferred
|
||||
// (only valid if CF set for some BIOSes)
|
||||
RegsIn.b.ah = 0x02;
|
||||
RegsIn.b.al = NumberOfSectorsToRead;
|
||||
RegsIn.b.ch = (PhysicalTrack & 0xFF);
|
||||
RegsIn.b.cl = (PhysicalSector + ((PhysicalTrack & 0x300) >> 2));
|
||||
RegsIn.b.dh = PhysicalHead;
|
||||
RegsIn.b.dl = DriveNumber;
|
||||
RegsIn.w.es = ((U32)Buffer) >> 4;
|
||||
RegsIn.w.bx = ((U32)Buffer) & 0x0F;
|
||||
|
||||
//
|
||||
// Perform the read
|
||||
// Retry 3 times
|
||||
//
|
||||
for (RetryCount=0; RetryCount<3; RetryCount++)
|
||||
{
|
||||
Int386(0x13, &RegsIn, &RegsOut);
|
||||
|
||||
// If it worked break out
|
||||
if (INT386_SUCCESS(RegsOut))
|
||||
{
|
||||
break;
|
||||
}
|
||||
// If it was a corrected ECC error then the data is still good
|
||||
else if (RegsOut.b.ah == 0x11)
|
||||
{
|
||||
break;
|
||||
}
|
||||
// If it failed the do the next retry
|
||||
else
|
||||
{
|
||||
DiskResetController(DriveNumber);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// If we retried 3 times then fail
|
||||
if (RetryCount >= 3)
|
||||
{
|
||||
DiskError("Disk Read Failed", RegsOut.b.ah);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// I have learned that not all bioses return
|
||||
// the sector read count in the AL register (at least mine doesn't)
|
||||
// even if the sectors were read correctly. So instead
|
||||
// of checking the sector read count we will rely solely
|
||||
// on the carry flag being set on error
|
||||
|
||||
Buffer += (NumberOfSectorsToRead * DriveGeometry.BytesPerSector);
|
||||
SectorCount -= NumberOfSectorsToRead;
|
||||
SectorNumber += NumberOfSectorsToRead;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL DiskResetController(U32 DriveNumber)
|
||||
{
|
||||
REGS RegsIn;
|
||||
REGS RegsOut;
|
||||
|
||||
DbgPrint((DPRINT_DISK, "DiskResetController(0x%x) DISK OPERATION FAILED -- RESETTING CONTROLLER\n", DriveNumber));
|
||||
|
||||
// BIOS Int 13h, function 0 - Reset disk system
|
||||
// AH = 00h
|
||||
// DL = drive (if bit 7 is set both hard disks and floppy disks reset)
|
||||
// Return:
|
||||
// AH = status
|
||||
// CF clear if successful
|
||||
// CF set on error
|
||||
RegsIn.b.ah = 0x02;
|
||||
RegsIn.b.dl = DriveNumber;
|
||||
|
||||
// Reset the disk controller
|
||||
Int386(0x13, &RegsIn, &RegsOut);
|
||||
|
||||
return INT386_SUCCESS(RegsOut);
|
||||
}
|
||||
|
||||
BOOL DiskInt13ExtensionsSupported(U32 DriveNumber)
|
||||
{
|
||||
REGS RegsIn;
|
||||
REGS RegsOut;
|
||||
|
||||
DbgPrint((DPRINT_DISK, "DiskInt13ExtensionsSupported()\n"));
|
||||
|
||||
// IBM/MS INT 13 Extensions - INSTALLATION CHECK
|
||||
// AH = 41h
|
||||
// BX = 55AAh
|
||||
// DL = drive (80h-FFh)
|
||||
// Return:
|
||||
// CF set on error (extensions not supported)
|
||||
// AH = 01h (invalid function)
|
||||
// CF clear if successful
|
||||
// BX = AA55h if installed
|
||||
// AH = major version of extensions
|
||||
// 01h = 1.x
|
||||
// 20h = 2.0 / EDD-1.0
|
||||
// 21h = 2.1 / EDD-1.1
|
||||
// 30h = EDD-3.0
|
||||
// AL = internal use
|
||||
// CX = API subset support bitmap
|
||||
// DH = extension version (v2.0+ ??? -- not present in 1.x)
|
||||
//
|
||||
// Bitfields for IBM/MS INT 13 Extensions API support bitmap
|
||||
// Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported
|
||||
// Bit 1, removable drive controller functions (AH=45h,46h,48h,49h,INT 15/AH=52h) supported
|
||||
// Bit 2, enhanced disk drive (EDD) functions (AH=48h,AH=4Eh) supported
|
||||
// extended drive parameter table is valid
|
||||
// Bits 3-15 reserved
|
||||
RegsIn.b.ah = 0x41;
|
||||
RegsIn.w.bx = 0x55AA;
|
||||
RegsIn.b.dl = DriveNumber;
|
||||
|
||||
// Reset the disk controller
|
||||
Int386(0x13, &RegsIn, &RegsOut);
|
||||
|
||||
if (!INT386_SUCCESS(RegsOut))
|
||||
{
|
||||
// CF set on error (extensions not supported)
|
||||
return FALSE;
|
||||
}
|
||||
if (RegsOut.w.bx != 0xAA55)
|
||||
{
|
||||
// BX = AA55h if installed
|
||||
return FALSE;
|
||||
}
|
||||
if (!(RegsOut.w.cx & 0x01))
|
||||
{
|
||||
// CX = API subset support bitmap
|
||||
// Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID DiskStopFloppyMotor(VOID)
|
||||
{
|
||||
WRITE_PORT_UCHAR((PUCHAR)0x3F2, 0);
|
||||
}
|
||||
|
||||
BOOL DiskGetDriveParameters(U32 DriveNumber, PGEOMETRY Geometry)
|
||||
{
|
||||
REGS RegsIn;
|
||||
REGS RegsOut;
|
||||
U32 Cylinders;
|
||||
|
||||
DbgPrint((DPRINT_DISK, "DiskGetDriveParameters()\n"));
|
||||
|
||||
// BIOS Int 13h, function 08h - Get drive parameters
|
||||
// AH = 08h
|
||||
// DL = drive (bit 7 set for hard disk)
|
||||
// ES:DI = 0000h:0000h to guard against BIOS bugs
|
||||
// Return:
|
||||
// CF set on error
|
||||
// AH = status (07h)
|
||||
// CF clear if successful
|
||||
// AH = 00h
|
||||
// AL = 00h on at least some BIOSes
|
||||
// BL = drive type (AT/PS2 floppies only)
|
||||
// CH = low eight bits of maximum cylinder number
|
||||
// CL = maximum sector number (bits 5-0)
|
||||
// high two bits of maximum cylinder number (bits 7-6)
|
||||
// DH = maximum head number
|
||||
// DL = number of drives
|
||||
// ES:DI -> drive parameter table (floppies only)
|
||||
RegsIn.b.ah = 0x08;
|
||||
RegsIn.b.dl = DriveNumber;
|
||||
RegsIn.w.es = 0x0000;
|
||||
RegsIn.w.di = 0x0000;
|
||||
|
||||
// Get drive parameters
|
||||
Int386(0x13, &RegsIn, &RegsOut);
|
||||
|
||||
if (!INT386_SUCCESS(RegsOut))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Cylinders = (RegsOut.b.cl & 0xC0) << 2;
|
||||
Cylinders += RegsOut.b.ch;
|
||||
Cylinders++;
|
||||
Geometry->Cylinders = Cylinders;
|
||||
Geometry->Heads = RegsOut.b.dh + 1;
|
||||
Geometry->Sectors = RegsOut.b.cl & 0x3F;
|
||||
Geometry->BytesPerSector = 512; // Just assume 512 bytes per sector
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
U32 DiskGetCacheableBlockCount(U32 DriveNumber)
|
||||
{
|
||||
GEOMETRY Geometry;
|
||||
|
||||
// Get the disk geometry
|
||||
// If this fails then we will just return 1 sector to be safe
|
||||
if (!DiskGetDriveParameters(DriveNumber, &Geometry))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
// If LBA is supported then the block size will be 64 sectors (32k)
|
||||
// If not then the block size is the size of one track
|
||||
if (DiskInt13ExtensionsSupported)
|
||||
{
|
||||
return 64;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Geometry.Sectors;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // defined __i386__
|
208
freeldr/freeldr/arch/i386/i386mem.c
Normal file
208
freeldr/freeldr/arch/i386/i386mem.c
Normal file
|
@ -0,0 +1,208 @@
|
|||
/*
|
||||
* FreeLoader
|
||||
* Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <freeldr.h>
|
||||
#include <arch.h>
|
||||
#include <mm.h>
|
||||
#include <debug.h>
|
||||
#include <rtl.h>
|
||||
#include <comm.h>
|
||||
|
||||
|
||||
U32 GetExtendedMemorySize(VOID)
|
||||
{
|
||||
REGS RegsIn;
|
||||
REGS RegsOut;
|
||||
U32 MemorySize;
|
||||
|
||||
DbgPrint((DPRINT_MEMORY, "GetExtendedMemorySize()\n"));
|
||||
|
||||
// Int 15h AX=E801h
|
||||
// Phoenix BIOS v4.0 - GET MEMORY SIZE FOR >64M CONFIGURATIONS
|
||||
//
|
||||
// AX = E801h
|
||||
// Return:
|
||||
// CF clear if successful
|
||||
// AX = extended memory between 1M and 16M, in K (max 3C00h = 15MB)
|
||||
// BX = extended memory above 16M, in 64K blocks
|
||||
// CX = configured memory 1M to 16M, in K
|
||||
// DX = configured memory above 16M, in 64K blocks
|
||||
// CF set on error
|
||||
RegsIn.w.ax = 0xE801;
|
||||
Int386(0x15, &RegsIn, &RegsOut);
|
||||
|
||||
DbgPrint((DPRINT_MEMORY, "Int15h AX=E801h\n"));
|
||||
DbgPrint((DPRINT_MEMORY, "AX = 0x%x\n", RegsOut.w.ax));
|
||||
DbgPrint((DPRINT_MEMORY, "BX = 0x%x\n", RegsOut.w.bx));
|
||||
DbgPrint((DPRINT_MEMORY, "CX = 0x%x\n", RegsOut.w.cx));
|
||||
DbgPrint((DPRINT_MEMORY, "DX = 0x%x\n", RegsOut.w.dx));
|
||||
DbgPrint((DPRINT_MEMORY, "CF set = %s\n\n", (RegsOut.x.eflags & I386FLAG_CF) ? "TRUE" : "FALSE"));
|
||||
|
||||
if (INT386_SUCCESS(RegsOut))
|
||||
{
|
||||
// If AX=BX=0000h the use CX and DX
|
||||
if (RegsOut.w.ax == 0)
|
||||
{
|
||||
// Return extended memory size in K
|
||||
MemorySize = RegsOut.w.dx * 64;
|
||||
MemorySize += RegsOut.w.cx;
|
||||
return MemorySize;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Return extended memory size in K
|
||||
MemorySize = RegsOut.w.bx * 64;
|
||||
MemorySize += RegsOut.w.ax;
|
||||
return MemorySize;
|
||||
}
|
||||
}
|
||||
|
||||
// If we get here then Int15 Func E801h didn't work
|
||||
// So try Int15 Func 88h
|
||||
|
||||
// Int 15h AH=88h
|
||||
// SYSTEM - GET EXTENDED MEMORY SIZE (286+)
|
||||
//
|
||||
// AH = 88h
|
||||
// Return:
|
||||
// CF clear if successful
|
||||
// AX = number of contiguous KB starting at absolute address 100000h
|
||||
// CF set on error
|
||||
// AH = status
|
||||
// 80h invalid command (PC,PCjr)
|
||||
// 86h unsupported function (XT,PS30)
|
||||
RegsIn.b.ah = 0x88;
|
||||
Int386(0x15, &RegsIn, &RegsOut);
|
||||
|
||||
DbgPrint((DPRINT_MEMORY, "Int15h AH=88h\n"));
|
||||
DbgPrint((DPRINT_MEMORY, "AX = 0x%x\n", RegsOut.w.ax));
|
||||
DbgPrint((DPRINT_MEMORY, "CF set = %s\n\n", (RegsOut.x.eflags & I386FLAG_CF) ? "TRUE" : "FALSE"));
|
||||
|
||||
if (INT386_SUCCESS(RegsOut) && RegsOut.w.ax != 0)
|
||||
{
|
||||
MemorySize = RegsOut.w.ax;
|
||||
return MemorySize;
|
||||
}
|
||||
|
||||
// If we get here then Int15 Func 88h didn't work
|
||||
// So try reading the CMOS
|
||||
WRITE_PORT_UCHAR((PUCHAR)0x70, 0x31);
|
||||
MemorySize = READ_PORT_UCHAR((PUCHAR)0x71);
|
||||
MemorySize = (MemorySize & 0xFFFF);
|
||||
MemorySize = (MemorySize << 8);
|
||||
|
||||
DbgPrint((DPRINT_MEMORY, "Int15h Failed\n"));
|
||||
DbgPrint((DPRINT_MEMORY, "CMOS reports: 0x%x\n", MemorySize));
|
||||
|
||||
return MemorySize;
|
||||
}
|
||||
|
||||
U32 GetConventionalMemorySize(VOID)
|
||||
{
|
||||
REGS Regs;
|
||||
|
||||
DbgPrint((DPRINT_MEMORY, "GetConventionalMemorySize()\n"));
|
||||
|
||||
// Int 12h
|
||||
// BIOS - GET MEMORY SIZE
|
||||
//
|
||||
// Return:
|
||||
// AX = kilobytes of contiguous memory starting at absolute address 00000h
|
||||
//
|
||||
// This call returns the contents of the word at 0040h:0013h;
|
||||
// in PC and XT, this value is set from the switches on the motherboard
|
||||
Regs.w.ax = 0;
|
||||
Int386(0x12, &Regs, &Regs);
|
||||
|
||||
DbgPrint((DPRINT_MEMORY, "Int12h\n"));
|
||||
DbgPrint((DPRINT_MEMORY, "AX = 0x%x\n\n", Regs.w.ax));
|
||||
|
||||
return (U32)Regs.w.ax;
|
||||
}
|
||||
|
||||
U32 GetBiosMemoryMap(BIOS_MEMORY_MAP BiosMemoryMap[32])
|
||||
{
|
||||
REGS Regs;
|
||||
U32 MapCount;
|
||||
|
||||
DbgPrint((DPRINT_MEMORY, "GetBiosMemoryMap()\n"));
|
||||
|
||||
// Int 15h AX=E820h
|
||||
// Newer BIOSes - GET SYSTEM MEMORY MAP
|
||||
//
|
||||
// AX = E820h
|
||||
// EAX = 0000E820h
|
||||
// EDX = 534D4150h ('SMAP')
|
||||
// EBX = continuation value or 00000000h to start at beginning of map
|
||||
// ECX = size of buffer for result, in bytes (should be >= 20 bytes)
|
||||
// ES:DI -> buffer for result
|
||||
// Return:
|
||||
// CF clear if successful
|
||||
// EAX = 534D4150h ('SMAP')
|
||||
// ES:DI buffer filled
|
||||
// EBX = next offset from which to copy or 00000000h if all done
|
||||
// ECX = actual length returned in bytes
|
||||
// CF set on error
|
||||
// AH = error code (86h)
|
||||
Regs.x.eax = 0x0000E820;
|
||||
Regs.x.edx = 0x534D4150; // ('SMAP')
|
||||
Regs.x.ebx = 0x00000000;
|
||||
Regs.x.ecx = sizeof(BIOS_MEMORY_MAP);
|
||||
Regs.w.es = BIOSCALLBUFSEGMENT;
|
||||
Regs.w.di = BIOSCALLBUFOFFSET;
|
||||
for (MapCount=0; MapCount<32; MapCount++)
|
||||
{
|
||||
Int386(0x15, &Regs, &Regs);
|
||||
|
||||
DbgPrint((DPRINT_MEMORY, "Memory Map Entry %d\n", MapCount));
|
||||
DbgPrint((DPRINT_MEMORY, "Int15h AX=E820h\n"));
|
||||
DbgPrint((DPRINT_MEMORY, "EAX = 0x%x\n", Regs.x.eax));
|
||||
DbgPrint((DPRINT_MEMORY, "EBX = 0x%x\n", Regs.x.ebx));
|
||||
DbgPrint((DPRINT_MEMORY, "ECX = 0x%x\n", Regs.x.ecx));
|
||||
DbgPrint((DPRINT_MEMORY, "CF set = %s\n", (Regs.x.eflags & I386FLAG_CF) ? "TRUE" : "FALSE"));
|
||||
|
||||
// If the BIOS didn't return 'SMAP' in EAX then
|
||||
// it doesn't support this call
|
||||
if (Regs.x.eax != 0x534D4150)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Copy data to caller's buffer
|
||||
RtlCopyMemory(&BiosMemoryMap[MapCount], (PVOID)BIOSCALLBUFFER, Regs.x.ecx);
|
||||
|
||||
DbgPrint((DPRINT_MEMORY, "BaseAddress: 0x%x%x\n", BiosMemoryMap[MapCount].BaseAddress));
|
||||
DbgPrint((DPRINT_MEMORY, "Length: 0x%x%x\n", BiosMemoryMap[MapCount].Length));
|
||||
DbgPrint((DPRINT_MEMORY, "Type: 0x%x\n", BiosMemoryMap[MapCount].Type));
|
||||
DbgPrint((DPRINT_MEMORY, "Reserved: 0x%x\n", BiosMemoryMap[MapCount].Reserved));
|
||||
DbgPrint((DPRINT_MEMORY, "\n"));
|
||||
|
||||
// If the continuation value is zero or the
|
||||
// carry flag is set then this was
|
||||
// the last entry so we're done
|
||||
if (Regs.x.ebx == 0x00000000 || !INT386_SUCCESS(Regs))
|
||||
{
|
||||
MapCount++;
|
||||
DbgPrint((DPRINT_MEMORY, "End Of System Memory Map!\n\n"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return MapCount;
|
||||
}
|
328
freeldr/freeldr/arch/i386/i386rtl.c
Normal file
328
freeldr/freeldr/arch/i386/i386rtl.c
Normal file
|
@ -0,0 +1,328 @@
|
|||
/*
|
||||
* FreeLoader
|
||||
* Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <freeldr.h>
|
||||
#include <arch.h>
|
||||
|
||||
|
||||
void putchar(int ch)
|
||||
{
|
||||
REGS Regs;
|
||||
|
||||
/* If we are displaying a CR '\n' then do a LF also */
|
||||
if (ch == '\n')
|
||||
{
|
||||
/* Display the LF */
|
||||
putchar('\r');
|
||||
}
|
||||
|
||||
/* If we are displaying a TAB '\t' then display 8 spaces ' ' */
|
||||
if (ch == '\t')
|
||||
{
|
||||
/* Display the 8 spaces ' ' */
|
||||
putchar(' ');
|
||||
putchar(' ');
|
||||
putchar(' ');
|
||||
putchar(' ');
|
||||
putchar(' ');
|
||||
putchar(' ');
|
||||
putchar(' ');
|
||||
putchar(' ');
|
||||
return;
|
||||
}
|
||||
|
||||
// Int 10h AH=0Eh
|
||||
// VIDEO - TELETYPE OUTPUT
|
||||
//
|
||||
// AH = 0Eh
|
||||
// AL = character to write
|
||||
// BH = page number
|
||||
// BL = foreground color (graphics modes only)
|
||||
Regs.b.ah = 0x0E;
|
||||
Regs.b.al = ch;
|
||||
Regs.w.bx = 1;
|
||||
Int386(0x10, &Regs, &Regs);
|
||||
}
|
||||
|
||||
int kbhit(void)
|
||||
{
|
||||
REGS Regs;
|
||||
|
||||
// Int 16h AH=01h
|
||||
// KEYBOARD - CHECK FOR KEYSTROKE
|
||||
//
|
||||
// AH = 01h
|
||||
// Return:
|
||||
// ZF set if no keystroke available
|
||||
// ZF clear if keystroke available
|
||||
// AH = BIOS scan code
|
||||
// AL = ASCII character
|
||||
Regs.b.ah = 0x01;
|
||||
Int386(0x16, &Regs, &Regs);
|
||||
|
||||
if (Regs.x.eflags & I386FLAG_ZF)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int getch(void)
|
||||
{
|
||||
REGS Regs;
|
||||
static BOOL ExtendedKey = FALSE;
|
||||
static char ExtendedScanCode = 0;
|
||||
|
||||
// If the last time we were called an
|
||||
// extended key was pressed then return
|
||||
// that keys scan code.
|
||||
if (ExtendedKey)
|
||||
{
|
||||
ExtendedKey = FALSE;
|
||||
return ExtendedScanCode;
|
||||
}
|
||||
|
||||
// Int 16h AH=00h
|
||||
// KEYBOARD - GET KEYSTROKE
|
||||
//
|
||||
// AH = 00h
|
||||
// Return:
|
||||
// AH = BIOS scan code
|
||||
// AL = ASCII character
|
||||
Regs.b.ah = 0x00;
|
||||
Int386(0x16, &Regs, &Regs);
|
||||
|
||||
// Check for an extended keystroke
|
||||
if (Regs.b.al == 0)
|
||||
{
|
||||
ExtendedKey = TRUE;
|
||||
ExtendedScanCode = Regs.b.ah;
|
||||
}
|
||||
|
||||
// Return keystroke
|
||||
return Regs.b.al;
|
||||
}
|
||||
|
||||
int getyear(void)
|
||||
{
|
||||
REGS Regs;
|
||||
U16 Digit1;
|
||||
U16 Digit2;
|
||||
U16 Cent1;
|
||||
U16 Cent2;
|
||||
U16 Year;
|
||||
|
||||
// Some BIOSes, such es the 1998/07/25 system ROM
|
||||
// in the Compaq Deskpro EP/SB, leave CF unchanged
|
||||
// if successful, so CF should be cleared before
|
||||
// calling this function.
|
||||
__asm__ ("clc");
|
||||
|
||||
// Int 1Ah AH=04h
|
||||
// TIME - GET REAL-TIME CLOCK DATE (AT,XT286,PS)
|
||||
//
|
||||
// AH = 04h
|
||||
// CF clear to avoid bug
|
||||
// Return:
|
||||
// CF clear if successful
|
||||
// CH = century (BCD)
|
||||
// CL = year (BCD)
|
||||
// DH = month (BCD)
|
||||
// DL = day (BCD)
|
||||
// CF set on error
|
||||
Regs.b.ah = 0x04;
|
||||
Int386(0x1A, &Regs, &Regs);
|
||||
|
||||
/* Convert from BCD to normal */
|
||||
Digit1 = Regs.b.cl & 0x0F;
|
||||
Digit2 = ((Regs.b.cl >> 4) & 0x0F) * 10;
|
||||
Cent1 = Regs.b.ch & 0x0F;
|
||||
Cent2 = ((Regs.b.ch >> 4) & 0x0F) * 10;
|
||||
|
||||
Year = Cent1 + Cent2;
|
||||
Year *= 100;
|
||||
Year += Digit1 + Digit2;
|
||||
|
||||
return Year;
|
||||
}
|
||||
|
||||
int getday(void)
|
||||
{
|
||||
REGS Regs;
|
||||
U16 Digit1;
|
||||
U16 Digit2;
|
||||
|
||||
// Some BIOSes, such es the 1998/07/25 system ROM
|
||||
// in the Compaq Deskpro EP/SB, leave CF unchanged
|
||||
// if successful, so CF should be cleared before
|
||||
// calling this function.
|
||||
__asm__ ("clc");
|
||||
|
||||
// Int 1Ah AH=04h
|
||||
// TIME - GET REAL-TIME CLOCK DATE (AT,XT286,PS)
|
||||
//
|
||||
// AH = 04h
|
||||
// CF clear to avoid bug
|
||||
// Return:
|
||||
// CF clear if successful
|
||||
// CH = century (BCD)
|
||||
// CL = year (BCD)
|
||||
// DH = month (BCD)
|
||||
// DL = day (BCD)
|
||||
// CF set on error
|
||||
Regs.b.ah = 0x04;
|
||||
Int386(0x1A, &Regs, &Regs);
|
||||
|
||||
/* Convert from BCD to normal */
|
||||
Digit1 = Regs.b.dl & 0x0F;
|
||||
Digit2 = ((Regs.b.dl >> 4) & 0x0F) * 10;
|
||||
|
||||
return (Digit1 + Digit2);
|
||||
}
|
||||
|
||||
int getmonth(void)
|
||||
{
|
||||
REGS Regs;
|
||||
U16 Digit1;
|
||||
U16 Digit2;
|
||||
|
||||
// Some BIOSes, such es the 1998/07/25 system ROM
|
||||
// in the Compaq Deskpro EP/SB, leave CF unchanged
|
||||
// if successful, so CF should be cleared before
|
||||
// calling this function.
|
||||
__asm__ ("clc");
|
||||
|
||||
// Int 1Ah AH=04h
|
||||
// TIME - GET REAL-TIME CLOCK DATE (AT,XT286,PS)
|
||||
//
|
||||
// AH = 04h
|
||||
// CF clear to avoid bug
|
||||
// Return:
|
||||
// CF clear if successful
|
||||
// CH = century (BCD)
|
||||
// CL = year (BCD)
|
||||
// DH = month (BCD)
|
||||
// DL = day (BCD)
|
||||
// CF set on error
|
||||
Regs.b.ah = 0x04;
|
||||
Int386(0x1A, &Regs, &Regs);
|
||||
|
||||
/* Convert from BCD to normal */
|
||||
Digit1 = Regs.b.dh & 0x0F;
|
||||
Digit2 = ((Regs.b.dh >> 4) & 0x0F) * 10;
|
||||
|
||||
return (Digit1 + Digit2);
|
||||
}
|
||||
|
||||
int gethour(void)
|
||||
{
|
||||
REGS Regs;
|
||||
U16 Digit1;
|
||||
U16 Digit2;
|
||||
|
||||
// Some BIOSes leave CF unchanged if successful,
|
||||
// so CF should be cleared before calling this function.
|
||||
__asm__ ("clc");
|
||||
|
||||
// Int 1Ah AH=02h
|
||||
// TIME - GET REAL-TIME CLOCK TIME (AT,XT286,PS)
|
||||
//
|
||||
// AH = 02h
|
||||
// CF clear to avoid bug
|
||||
// Return:
|
||||
// CF clear if successful
|
||||
// CH = hour (BCD)
|
||||
// CL = minutes (BCD)
|
||||
// DH = seconds (BCD)
|
||||
// DL = daylight savings flag (00h standard time, 01h daylight time)
|
||||
// CF set on error (i.e. clock not running or in middle of update)
|
||||
Regs.b.ah = 0x02;
|
||||
Int386(0x1A, &Regs, &Regs);
|
||||
|
||||
/* Convert from BCD to normal */
|
||||
Digit1 = Regs.b.ch & 0x0F;
|
||||
Digit2 = ((Regs.b.ch >> 4) & 0x0F) * 10;
|
||||
|
||||
return (Digit1 + Digit2);
|
||||
}
|
||||
|
||||
int getminute(void)
|
||||
{
|
||||
REGS Regs;
|
||||
U16 Digit1;
|
||||
U16 Digit2;
|
||||
|
||||
// Some BIOSes leave CF unchanged if successful,
|
||||
// so CF should be cleared before calling this function.
|
||||
__asm__ ("clc");
|
||||
|
||||
// Int 1Ah AH=02h
|
||||
// TIME - GET REAL-TIME CLOCK TIME (AT,XT286,PS)
|
||||
//
|
||||
// AH = 02h
|
||||
// CF clear to avoid bug
|
||||
// Return:
|
||||
// CF clear if successful
|
||||
// CH = hour (BCD)
|
||||
// CL = minutes (BCD)
|
||||
// DH = seconds (BCD)
|
||||
// DL = daylight savings flag (00h standard time, 01h daylight time)
|
||||
// CF set on error (i.e. clock not running or in middle of update)
|
||||
Regs.b.ah = 0x02;
|
||||
Int386(0x1A, &Regs, &Regs);
|
||||
|
||||
/* Convert from BCD to normal */
|
||||
Digit1 = Regs.b.cl & 0x0F;
|
||||
Digit2 = ((Regs.b.cl >> 4) & 0x0F) * 10;
|
||||
|
||||
return (Digit1 + Digit2);
|
||||
}
|
||||
|
||||
int getsecond(void)
|
||||
{
|
||||
REGS Regs;
|
||||
U16 Digit1;
|
||||
U16 Digit2;
|
||||
|
||||
// Some BIOSes leave CF unchanged if successful,
|
||||
// so CF should be cleared before calling this function.
|
||||
__asm__ ("clc");
|
||||
|
||||
// Int 1Ah AH=02h
|
||||
// TIME - GET REAL-TIME CLOCK TIME (AT,XT286,PS)
|
||||
//
|
||||
// AH = 02h
|
||||
// CF clear to avoid bug
|
||||
// Return:
|
||||
// CF clear if successful
|
||||
// CH = hour (BCD)
|
||||
// CL = minutes (BCD)
|
||||
// DH = seconds (BCD)
|
||||
// DL = daylight savings flag (00h standard time, 01h daylight time)
|
||||
// CF set on error (i.e. clock not running or in middle of update)
|
||||
Regs.b.ah = 0x02;
|
||||
Int386(0x1A, &Regs, &Regs);
|
||||
|
||||
/* Convert from BCD to normal */
|
||||
Digit1 = Regs.b.dh & 0x0F;
|
||||
Digit2 = ((Regs.b.dh >> 4) & 0x0F) * 10;
|
||||
|
||||
return (Digit1 + Digit2);
|
||||
}
|
|
@ -76,59 +76,6 @@
|
|||
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
|
||||
movl %dr6,%eax
|
||||
movl %eax,i386_DR6
|
||||
movl %dr7,%eax
|
||||
movl %eax,i386_DR7
|
||||
sgdt i386_GDTR
|
||||
sidt i386_IDTR
|
||||
sldt i386_LDTR
|
||||
str i386_TR
|
||||
.endm
|
||||
|
||||
|
||||
|
||||
i386ExceptionHandlerText:
|
||||
|
@ -317,6 +264,8 @@ i386_ScreenPosY:
|
|||
i386CommonExceptionHandler:
|
||||
.code32
|
||||
|
||||
SAVE_CPU_REGS
|
||||
|
||||
call i386ClearScreenToBlue
|
||||
|
||||
movl $i386ExceptionHandlerText,%esi
|
||||
|
@ -630,8 +579,6 @@ i386PrintHexByte1:
|
|||
EXTERN(i386DivideByZero)
|
||||
.code32
|
||||
|
||||
SAVE_CPU_REGS
|
||||
|
||||
movl $i386DivideByZeroText,i386ExceptionDescriptionText
|
||||
jmp i386CommonExceptionHandler
|
||||
|
||||
|
@ -639,8 +586,6 @@ EXTERN(i386DivideByZero)
|
|||
EXTERN(i386DebugException)
|
||||
.code32
|
||||
|
||||
SAVE_CPU_REGS
|
||||
|
||||
movl $i386DebugExceptionText,i386ExceptionDescriptionText
|
||||
jmp i386CommonExceptionHandler
|
||||
|
||||
|
@ -648,8 +593,6 @@ EXTERN(i386DebugException)
|
|||
EXTERN(i386NMIException)
|
||||
.code32
|
||||
|
||||
SAVE_CPU_REGS
|
||||
|
||||
movl $i386NMIExceptionText,i386ExceptionDescriptionText
|
||||
jmp i386CommonExceptionHandler
|
||||
|
||||
|
@ -657,8 +600,6 @@ EXTERN(i386NMIException)
|
|||
EXTERN(i386Breakpoint)
|
||||
.code32
|
||||
|
||||
SAVE_CPU_REGS
|
||||
|
||||
movl $i386BreakpointText,i386ExceptionDescriptionText
|
||||
jmp i386CommonExceptionHandler
|
||||
|
||||
|
@ -666,8 +607,6 @@ EXTERN(i386Breakpoint)
|
|||
EXTERN(i386Overflow)
|
||||
.code32
|
||||
|
||||
SAVE_CPU_REGS
|
||||
|
||||
movl $i386OverflowText,i386ExceptionDescriptionText
|
||||
jmp i386CommonExceptionHandler
|
||||
|
||||
|
@ -675,8 +614,6 @@ EXTERN(i386Overflow)
|
|||
EXTERN(i386BoundException)
|
||||
.code32
|
||||
|
||||
SAVE_CPU_REGS
|
||||
|
||||
movl $i386BoundExceptionText,i386ExceptionDescriptionText
|
||||
jmp i386CommonExceptionHandler
|
||||
|
||||
|
@ -684,8 +621,6 @@ EXTERN(i386BoundException)
|
|||
EXTERN(i386InvalidOpcode)
|
||||
.code32
|
||||
|
||||
SAVE_CPU_REGS
|
||||
|
||||
movl $i386InvalidOpcodeText,i386ExceptionDescriptionText
|
||||
jmp i386CommonExceptionHandler
|
||||
|
||||
|
@ -693,8 +628,6 @@ EXTERN(i386InvalidOpcode)
|
|||
EXTERN(i386FPUNotAvailable)
|
||||
.code32
|
||||
|
||||
SAVE_CPU_REGS
|
||||
|
||||
movl $i386FPUNotAvailableText,i386ExceptionDescriptionText
|
||||
jmp i386CommonExceptionHandler
|
||||
|
||||
|
@ -702,7 +635,8 @@ EXTERN(i386FPUNotAvailable)
|
|||
EXTERN(i386DoubleFault)
|
||||
.code32
|
||||
|
||||
SAVE_CPU_REGS_ERROR_CODE
|
||||
popl %eax
|
||||
movl %eax,i386_ERROR_CODE
|
||||
|
||||
movl $i386DoubleFaultText,i386ExceptionDescriptionText
|
||||
jmp i386CommonExceptionHandler
|
||||
|
@ -711,8 +645,6 @@ EXTERN(i386DoubleFault)
|
|||
EXTERN(i386CoprocessorSegment)
|
||||
.code32
|
||||
|
||||
SAVE_CPU_REGS
|
||||
|
||||
movl $i386CoprocessorSegmentText,i386ExceptionDescriptionText
|
||||
jmp i386CommonExceptionHandler
|
||||
|
||||
|
@ -720,7 +652,8 @@ EXTERN(i386CoprocessorSegment)
|
|||
EXTERN(i386InvalidTSS)
|
||||
.code32
|
||||
|
||||
SAVE_CPU_REGS_ERROR_CODE
|
||||
popl %eax
|
||||
movl %eax,i386_ERROR_CODE
|
||||
|
||||
movl $i386InvalidTSSText,i386ExceptionDescriptionText
|
||||
jmp i386CommonExceptionHandler
|
||||
|
@ -729,7 +662,8 @@ EXTERN(i386InvalidTSS)
|
|||
EXTERN(i386SegmentNotPresent)
|
||||
.code32
|
||||
|
||||
SAVE_CPU_REGS_ERROR_CODE
|
||||
popl %eax
|
||||
movl %eax,i386_ERROR_CODE
|
||||
|
||||
movl $i386SegmentNotPresentText,i386ExceptionDescriptionText
|
||||
jmp i386CommonExceptionHandler
|
||||
|
@ -738,7 +672,8 @@ EXTERN(i386SegmentNotPresent)
|
|||
EXTERN(i386StackException)
|
||||
.code32
|
||||
|
||||
SAVE_CPU_REGS_ERROR_CODE
|
||||
popl %eax
|
||||
movl %eax,i386_ERROR_CODE
|
||||
|
||||
movl $i386StackExceptionText,i386ExceptionDescriptionText
|
||||
jmp i386CommonExceptionHandler
|
||||
|
@ -747,7 +682,8 @@ EXTERN(i386StackException)
|
|||
EXTERN(i386GeneralProtectionFault)
|
||||
.code32
|
||||
|
||||
SAVE_CPU_REGS_ERROR_CODE
|
||||
popl %eax
|
||||
movl %eax,i386_ERROR_CODE
|
||||
|
||||
movl $i386GeneralProtectionFaultText,i386ExceptionDescriptionText
|
||||
jmp i386CommonExceptionHandler
|
||||
|
@ -756,7 +692,8 @@ EXTERN(i386GeneralProtectionFault)
|
|||
EXTERN(i386PageFault)
|
||||
.code32
|
||||
|
||||
SAVE_CPU_REGS_ERROR_CODE
|
||||
popl %eax
|
||||
movl %eax,i386_ERROR_CODE
|
||||
|
||||
movl $i386PageFaultText,i386ExceptionDescriptionText
|
||||
jmp i386CommonExceptionHandler
|
||||
|
@ -765,8 +702,6 @@ EXTERN(i386PageFault)
|
|||
EXTERN(i386CoprocessorError)
|
||||
.code32
|
||||
|
||||
SAVE_CPU_REGS
|
||||
|
||||
movl $i386CoprocessorErrorText,i386ExceptionDescriptionText
|
||||
jmp i386CommonExceptionHandler
|
||||
|
||||
|
@ -774,8 +709,6 @@ EXTERN(i386CoprocessorError)
|
|||
EXTERN(i386AlignmentCheck)
|
||||
.code32
|
||||
|
||||
SAVE_CPU_REGS
|
||||
|
||||
movl $i386AlignmentCheckText,i386ExceptionDescriptionText
|
||||
jmp i386CommonExceptionHandler
|
||||
|
||||
|
@ -783,8 +716,6 @@ EXTERN(i386AlignmentCheck)
|
|||
EXTERN(i386MachineCheck)
|
||||
.code32
|
||||
|
||||
SAVE_CPU_REGS
|
||||
|
||||
movl $i386MachineCheckText,i386ExceptionDescriptionText
|
||||
jmp i386CommonExceptionHandler
|
||||
|
||||
|
|
807
freeldr/freeldr/arch/i386/i386vid.c
Normal file
807
freeldr/freeldr/arch/i386/i386vid.c
Normal file
|
@ -0,0 +1,807 @@
|
|||
/*
|
||||
* FreeLoader
|
||||
* Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
|
||||
* Portions from Linux video.S - Display adapter & video mode setup, version 2.13 (14-May-99)
|
||||
* Copyright (C) 1995 -- 1999 Martin Mares <mj@ucw.cz>
|
||||
* Based on the original setup.S code (C) Linus Torvalds and Mats Anderson
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include <freeldr.h>
|
||||
#include <arch.h>
|
||||
#include <video.h>
|
||||
#include <comm.h>
|
||||
#include <rtl.h>
|
||||
#include <debug.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
U8 Signature[4]; // (ret) signature ("VESA")
|
||||
// (call) VESA 2.0 request signature ("VBE2"), required to receive
|
||||
// version 2.0 info
|
||||
U16 VesaVersion; // VESA version number (one-digit minor version -- 0102h = v1.2)
|
||||
U32 OemNamePtr; // pointer to OEM name
|
||||
// "761295520" for ATI
|
||||
U32 Capabilities; // capabilities flags (see #00078)
|
||||
U32 SupportedModeListPtr; // pointer to list of supported VESA and OEM video modes
|
||||
// (list of words terminated with FFFFh)
|
||||
U16 TotalVideoMemory; // total amount of video memory in 64K blocks
|
||||
|
||||
// ---VBE v1.x ---
|
||||
//U8 Reserved[236];
|
||||
|
||||
// ---VBE v2.0 ---
|
||||
U16 OemSoftwareVersion; // OEM software version (BCD, high byte = major, low byte = minor)
|
||||
U32 VendorNamePtr; // pointer to vendor name
|
||||
U32 ProductNamePtr; // pointer to product name
|
||||
U32 ProductRevisionStringPtr; // pointer to product revision string
|
||||
U16 VBE_AF_Version; // (if capabilities bit 3 set) VBE/AF version (BCD)
|
||||
// 0100h for v1.0P
|
||||
U32 AcceleratedModeListPtr; // (if capabilities bit 3 set) pointer to list of supported
|
||||
// accelerated video modes (list of words terminated with FFFFh)
|
||||
U8 Reserved[216]; // reserved for VBE implementation
|
||||
U8 ScratchPad[256]; // OEM scratchpad (for OEM strings, etc.)
|
||||
} PACKED VESA_SVGA_INFO, *PVESA_SVGA_INFO;
|
||||
|
||||
// Bitfields for VESA capabilities:
|
||||
//
|
||||
// Bit(s) Description (Table 00078)
|
||||
// 0 DAC can be switched into 8-bit mode
|
||||
// 1 non-VGA controller
|
||||
// 2 programmed DAC with blank bit (i.e. only during blanking interval)
|
||||
// 3 (VBE v3.0) controller supports hardware stereoscopic signalling
|
||||
// 3 controller supports VBE/AF v1.0P extensions
|
||||
// 4 (VBE v3.0) if bit 3 set:
|
||||
// =0 stereo signalling via external VESA stereo connector
|
||||
// =1 stereo signalling via VESA EVC connector
|
||||
// 4 (VBE/AF v1.0P) must call EnableDirectAccess to access framebuffer
|
||||
// 5 (VBE/AF v1.0P) controller supports hardware mouse cursor
|
||||
// 6 (VBE/AF v1.0P) controller supports hardware clipping
|
||||
// 7 (VBE/AF v1.0P) controller supports transparent BitBLT
|
||||
// 8-31 reserved (0)
|
||||
|
||||
// Notes: The list of supported video modes is stored in the reserved
|
||||
// portion of the SuperVGA information record by some implementations,
|
||||
// and it may thus be necessary to either copy the mode list or use a
|
||||
// different buffer for all subsequent VESA calls. Not all of the video
|
||||
// modes in the list of mode numbers may be supported, e.g. if they require
|
||||
// more memory than currently installed or are not supported by the
|
||||
// attached monitor. Check any mode you intend to use through AX=4F01h first..
|
||||
// The 1.1 VESA document specifies 242 reserved bytes at the end, so the
|
||||
// buffer should be 262 bytes to ensure that it is not overrun; for v2.0,
|
||||
// the buffer should be 512 bytes. The S3 specific video modes will most
|
||||
// likely follow the FFFFh terminator at the end of the standard modes.
|
||||
// A search must then be made to find them, FFFFh will also terminate this
|
||||
// second list. In some cases, only a "stub" VBE may be present, supporting
|
||||
// only AX=4F00h; this case may be assumed if the list of supported video modes
|
||||
// is empty (consisting of a single word of FFFFh)
|
||||
|
||||
|
||||
VOID BiosSetVideoMode(U32 VideoMode)
|
||||
{
|
||||
REGS Regs;
|
||||
|
||||
// Int 10h AH=00h
|
||||
// VIDEO - SET VIDEO MODE
|
||||
//
|
||||
// AH = 00h
|
||||
// AL = desired video mode
|
||||
// Return:
|
||||
// AL = video mode flag (Phoenix, AMI BIOS)
|
||||
// 20h mode > 7
|
||||
// 30h modes 0-5 and 7
|
||||
// 3Fh mode 6
|
||||
// AL = CRT controller mode byte (Phoenix 386 BIOS v1.10)
|
||||
Regs.b.ah = 0x00;
|
||||
Regs.b.al = VideoMode;
|
||||
Int386(0x10, &Regs, &Regs);
|
||||
}
|
||||
|
||||
VOID BiosSetVideoFont8x8(VOID)
|
||||
{
|
||||
REGS Regs;
|
||||
|
||||
// Int 10h AX=1112h
|
||||
// VIDEO - TEXT-MODE CHARGEN - LOAD ROM 8x8 DBL-DOT PATTERNS (PS,EGA,VGA)
|
||||
//
|
||||
// AX = 1112h
|
||||
// BL = block to load
|
||||
// Return:
|
||||
// Nothing
|
||||
Regs.w.ax = 0x1112;
|
||||
Regs.b.bl = 0x00;
|
||||
Int386(0x10, &Regs, &Regs);
|
||||
}
|
||||
|
||||
VOID BiosSetVideoFont8x14(VOID)
|
||||
{
|
||||
REGS Regs;
|
||||
|
||||
// Int 10h AX=1111h
|
||||
// VIDEO - TEXT-MODE CHARGEN - LOAD ROM MONOCHROME PATTERNS (PS,EGA,VGA)
|
||||
//
|
||||
// AX = 1111h
|
||||
// BL = block to load
|
||||
// Return:
|
||||
// Nothing
|
||||
Regs.w.ax = 0x1111;
|
||||
Regs.b.bl = 0;
|
||||
Int386(0x10, &Regs, &Regs);
|
||||
}
|
||||
|
||||
VOID BiosSetVideoFont8x16(VOID)
|
||||
{
|
||||
REGS Regs;
|
||||
|
||||
// Int 10h AX=1114h
|
||||
// VIDEO - TEXT-MODE CHARGEN - LOAD ROM 8x16 CHARACTER SET (VGA)
|
||||
//
|
||||
// AX = 1114h
|
||||
// BL = block to load
|
||||
// Return:
|
||||
// Nothing
|
||||
Regs.w.ax = 0x1114;
|
||||
Regs.b.bl = 0;
|
||||
Int386(0x10, &Regs, &Regs);
|
||||
}
|
||||
|
||||
VOID BiosSelectAlternatePrintScreen(VOID)
|
||||
{
|
||||
REGS Regs;
|
||||
|
||||
// Int 10h AH=12h BL=20h
|
||||
// VIDEO - ALTERNATE FUNCTION SELECT (PS,EGA,VGA,MCGA) - ALTERNATE PRTSC
|
||||
//
|
||||
// AH = 12h
|
||||
// BL = 20h select alternate print screen routine
|
||||
// Return:
|
||||
// Nothing
|
||||
//
|
||||
// Installs a PrtSc routine from the video card's BIOS to replace the
|
||||
// default PrtSc handler from the ROM BIOS, which usually does not
|
||||
// understand screen heights other than 25 lines.
|
||||
//
|
||||
// Some adapters disable print-screen instead of enhancing it.
|
||||
Regs.b.ah = 0x12;
|
||||
Regs.b.bl = 0x20;
|
||||
Int386(0x10, &Regs, &Regs);
|
||||
}
|
||||
|
||||
VOID BiosDisableCursorEmulation(VOID)
|
||||
{
|
||||
REGS Regs;
|
||||
|
||||
// Int 10h AH=12h BL=34h
|
||||
// VIDEO - ALTERNATE FUNCTION SELECT (VGA) - CURSOR EMULATION
|
||||
//
|
||||
// AH = 12h
|
||||
// BL = 34h
|
||||
// AL = new state
|
||||
// 00h enable alphanumeric cursor emulation
|
||||
// 01h disable alphanumeric cursor emulation
|
||||
// Return:
|
||||
// AL = 12h if function supported
|
||||
//
|
||||
// Specify whether the BIOS should automatically remap cursor start/end
|
||||
// according to the current character height in text modes.
|
||||
Regs.b.ah = 0x12;
|
||||
Regs.b.bl = 0x34;
|
||||
Regs.b.al = 0x01;
|
||||
Int386(0x10, &Regs, &Regs);
|
||||
}
|
||||
|
||||
VOID BiosDefineCursor(U32 StartScanLine, U32 EndScanLine)
|
||||
{
|
||||
REGS Regs;
|
||||
|
||||
// Int 10h AH=01h
|
||||
// VIDEO - SET TEXT-MODE CURSOR SHAPE
|
||||
//
|
||||
// AH = 01h
|
||||
// CH = cursor start and options
|
||||
// CL = bottom scan line containing cursor (bits 0-4)
|
||||
// Return:
|
||||
// Nothing
|
||||
//
|
||||
// Specify the starting and ending scan lines to be occupied
|
||||
// by the hardware cursor in text modes.
|
||||
//
|
||||
// AMI 386 BIOS and AST Premier 386 BIOS will lock up the
|
||||
// system if AL is not equal to the current video mode.
|
||||
//
|
||||
// Bitfields for cursor start and options:
|
||||
//
|
||||
// Bit(s) Description
|
||||
// 7 should be zero
|
||||
// 6,5 cursor blink
|
||||
// (00=normal, 01=invisible, 10=erratic, 11=slow).
|
||||
// (00=normal, other=invisible on EGA/VGA)
|
||||
// 4-0 topmost scan line containing cursor
|
||||
Regs.b.ah = 0x01;
|
||||
Regs.b.al = 0x03;
|
||||
Regs.b.ch = StartScanLine;
|
||||
Regs.b.cl = EndScanLine;
|
||||
Int386(0x10, &Regs, &Regs);
|
||||
}
|
||||
|
||||
U32 BiosDetectVideoCard(VOID)
|
||||
{
|
||||
REGS Regs;
|
||||
|
||||
// Int 10h AH=12h BL=10h
|
||||
// VIDEO - ALTERNATE FUNCTION SELECT (PS,EGA,VGA,MCGA) - GET EGA INFO
|
||||
//
|
||||
// AH = 12h
|
||||
// BL = 10h
|
||||
// Return:
|
||||
// BH = video state
|
||||
// 00h color mode in effect (I/O port 3Dxh)
|
||||
// 01h mono mode in effect (I/O port 3Bxh)
|
||||
// BL = installed memory (00h = 64K, 01h = 128K, 02h = 192K, 03h = 256K)
|
||||
// CH = feature connector bits
|
||||
// CL = switch settings
|
||||
// AH destroyed (at least by Tseng ET4000 BIOS v8.00n)
|
||||
//
|
||||
// Installation check;EGA
|
||||
Regs.b.ah = 0x12;
|
||||
Regs.b.bl = 0x10;
|
||||
Int386(0x10, &Regs, &Regs);
|
||||
|
||||
// If BL is still equal to 0x10 then there is no EGA/VGA present
|
||||
if (Regs.b.bl == 0x10)
|
||||
{
|
||||
return VIDEOCARD_CGA_OR_OTHER;
|
||||
}
|
||||
|
||||
// Int 10h AX=1A00h
|
||||
// VIDEO - GET DISPLAY COMBINATION CODE (PS,VGA/MCGA)
|
||||
//
|
||||
// AX = 1A00h
|
||||
// Return:
|
||||
// AL = 1Ah if function was supported
|
||||
// BL = active display code
|
||||
// BH = alternate display code
|
||||
//
|
||||
// This function is commonly used to check for the presence of a VGA.
|
||||
//
|
||||
// Installation check;VGA
|
||||
//
|
||||
// Values for display combination code:
|
||||
// 00h no display
|
||||
// 01h monochrome adapter w/ monochrome display
|
||||
// 02h CGA w/ color display
|
||||
// 03h reserved
|
||||
// 04h EGA w/ color display
|
||||
// 05h EGA w/ monochrome display
|
||||
// 06h PGA w/ color display
|
||||
// 07h VGA w/ monochrome analog display
|
||||
// 08h VGA w/ color analog display
|
||||
// 09h reserved
|
||||
// 0Ah MCGA w/ digital color display
|
||||
// 0Bh MCGA w/ monochrome analog display
|
||||
// 0Ch MCGA w/ color analog display
|
||||
// FFh unknown display type
|
||||
Regs.b.ah = 0x12;
|
||||
Regs.b.bl = 0x10;
|
||||
Int386(0x10, &Regs, &Regs);
|
||||
|
||||
if (Regs.b.al == 0x1A)
|
||||
{
|
||||
return VIDEOCARD_VGA;
|
||||
}
|
||||
else
|
||||
{
|
||||
return VIDEOCARD_EGA;
|
||||
}
|
||||
}
|
||||
|
||||
VOID BiosSetVerticalResolution(U32 ScanLines)
|
||||
{
|
||||
REGS Regs;
|
||||
|
||||
// Int 10h AH=12h BL=30h
|
||||
// VIDEO - ALTERNATE FUNCTION SELECT (VGA) - SELECT VERTICAL RESOLUTION
|
||||
//
|
||||
// AH = 12h
|
||||
// BL = 30h
|
||||
// AL = vertical resolution
|
||||
// 00h 200 scan lines
|
||||
// 01h 350 scan lines
|
||||
// 02h 400 scan lines
|
||||
// Return:
|
||||
// AL = 12h if function supported
|
||||
//
|
||||
// Specifiy the number of scan lines used to display text modes.
|
||||
//
|
||||
// The specified resolution will take effect on the next mode set.
|
||||
Regs.b.ah = 0x12;
|
||||
Regs.b.bl = 0x30;
|
||||
Regs.b.al = ScanLines;
|
||||
Int386(0x10, &Regs, &Regs);
|
||||
}
|
||||
|
||||
VOID BiosSet480ScanLines(VOID)
|
||||
{
|
||||
int CRTC;
|
||||
|
||||
// Read CRTC port
|
||||
CRTC = READ_PORT_UCHAR((PUCHAR)0x03CC);
|
||||
|
||||
if (CRTC & 1)
|
||||
{
|
||||
CRTC = 0x3D4;
|
||||
}
|
||||
else
|
||||
{
|
||||
CRTC = 0x3B4;
|
||||
}
|
||||
|
||||
// Vertical sync end (also unlocks CR0-7)
|
||||
WRITE_PORT_UCHAR((PUCHAR)CRTC, 0x11);
|
||||
WRITE_PORT_UCHAR((PUCHAR)CRTC+1, 0x0C);
|
||||
|
||||
// Vertical total
|
||||
WRITE_PORT_UCHAR((PUCHAR)CRTC, 0x06);
|
||||
WRITE_PORT_UCHAR((PUCHAR)CRTC+1, 0x0B);
|
||||
|
||||
// (vertical) overflow
|
||||
WRITE_PORT_UCHAR((PUCHAR)CRTC, 0x07);
|
||||
WRITE_PORT_UCHAR((PUCHAR)CRTC+1, 0x3E);
|
||||
|
||||
// Vertical sync start
|
||||
WRITE_PORT_UCHAR((PUCHAR)CRTC, 0x10);
|
||||
WRITE_PORT_UCHAR((PUCHAR)CRTC+1, 0xEA);
|
||||
|
||||
// Vertical display end
|
||||
WRITE_PORT_UCHAR((PUCHAR)CRTC, 0x12);
|
||||
WRITE_PORT_UCHAR((PUCHAR)CRTC+1, 0xDF);
|
||||
|
||||
// Vertical blank start
|
||||
WRITE_PORT_UCHAR((PUCHAR)CRTC, 0x15);
|
||||
WRITE_PORT_UCHAR((PUCHAR)CRTC+1, 0xE7);
|
||||
|
||||
// Vertical blank end
|
||||
WRITE_PORT_UCHAR((PUCHAR)CRTC, 0x16);
|
||||
WRITE_PORT_UCHAR((PUCHAR)CRTC+1, 0x04);
|
||||
|
||||
// Misc output register (read)
|
||||
CRTC = READ_PORT_UCHAR((PUCHAR)0x03CC);
|
||||
|
||||
// Preserve clock select bits and color bit
|
||||
CRTC = (CRTC & 0x0D);
|
||||
// Set correct sync polarity
|
||||
CRTC = (CRTC | 0xE2);
|
||||
|
||||
// (write)
|
||||
WRITE_PORT_UCHAR((PUCHAR)0x03C2, CRTC);
|
||||
}
|
||||
|
||||
VOID BiosSetVideoDisplayEnd(VOID)
|
||||
{
|
||||
int CRTC;
|
||||
|
||||
// Read CRTC port
|
||||
CRTC = READ_PORT_UCHAR((PUCHAR)0x03CC);
|
||||
|
||||
if (CRTC & 1)
|
||||
{
|
||||
CRTC = 0x3D4;
|
||||
}
|
||||
else
|
||||
{
|
||||
CRTC = 0x3B4;
|
||||
}
|
||||
|
||||
// Vertical display end
|
||||
WRITE_PORT_UCHAR((PUCHAR)CRTC, 0x12);
|
||||
WRITE_PORT_UCHAR((PUCHAR)CRTC+1, 0xDF);
|
||||
}
|
||||
|
||||
VOID VideoSetTextCursorPosition(U32 X, U32 Y)
|
||||
{
|
||||
REGS Regs;
|
||||
|
||||
// Int 10h AH=02h
|
||||
// VIDEO - SET CURSOR POSITION
|
||||
//
|
||||
// AH = 02h
|
||||
// BH = page number
|
||||
// 0-3 in modes 2&3
|
||||
// 0-7 in modes 0&1
|
||||
// 0 in graphics modes
|
||||
// DH = row (00h is top)
|
||||
// DL = column (00h is left)
|
||||
// Return:
|
||||
// Nothing
|
||||
Regs.b.ah = 0x01;
|
||||
Regs.b.bh = 0x00;
|
||||
Regs.b.dh = Y;
|
||||
Regs.b.dl = X;
|
||||
Int386(0x10, &Regs, &Regs);
|
||||
}
|
||||
|
||||
VOID VideoHideTextCursor(VOID)
|
||||
{
|
||||
BiosDefineCursor(0x20, 0x00);
|
||||
}
|
||||
|
||||
VOID VideoShowTextCursor(VOID)
|
||||
{
|
||||
BiosDefineCursor(0x0D, 0x0E);
|
||||
}
|
||||
|
||||
U32 VideoGetTextCursorPositionX(VOID)
|
||||
{
|
||||
REGS Regs;
|
||||
|
||||
// Int 10h AH=03h
|
||||
// VIDEO - GET CURSOR POSITION AND SIZE
|
||||
//
|
||||
// AH = 03h
|
||||
// BH = page number
|
||||
// 0-3 in modes 2&3
|
||||
// 0-7 in modes 0&1
|
||||
// 0 in graphics modes
|
||||
// Return:
|
||||
// AX = 0000h (Phoenix BIOS)
|
||||
// CH = start scan line
|
||||
// CL = end scan line
|
||||
// DH = row (00h is top)
|
||||
// DL = column (00h is left)
|
||||
Regs.b.ah = 0x03;
|
||||
Regs.b.bh = 0x00;
|
||||
Int386(0x10, &Regs, &Regs);
|
||||
|
||||
return Regs.b.dl;
|
||||
}
|
||||
|
||||
U32 VideoGetTextCursorPositionY(VOID)
|
||||
{
|
||||
REGS Regs;
|
||||
|
||||
// Int 10h AH=03h
|
||||
// VIDEO - GET CURSOR POSITION AND SIZE
|
||||
//
|
||||
// AH = 03h
|
||||
// BH = page number
|
||||
// 0-3 in modes 2&3
|
||||
// 0-7 in modes 0&1
|
||||
// 0 in graphics modes
|
||||
// Return:
|
||||
// AX = 0000h (Phoenix BIOS)
|
||||
// CH = start scan line
|
||||
// CL = end scan line
|
||||
// DH = row (00h is top)
|
||||
// DL = column (00h is left)
|
||||
Regs.b.ah = 0x03;
|
||||
Regs.b.bh = 0x00;
|
||||
Int386(0x10, &Regs, &Regs);
|
||||
|
||||
return Regs.b.dh;
|
||||
}
|
||||
|
||||
VOID BiosVideoDisableBlinkBit(VOID)
|
||||
{
|
||||
REGS Regs;
|
||||
|
||||
// Int 10h AX=1003h
|
||||
// VIDEO - TOGGLE INTENSITY/BLINKING BIT (Jr, PS, TANDY 1000, EGA, VGA)
|
||||
//
|
||||
// AX = 1003h
|
||||
// BL = new state
|
||||
// 00h background intensity enabled
|
||||
// 01h blink enabled
|
||||
// BH = 00h to avoid problems on some adapters
|
||||
// Return:
|
||||
// Nothing
|
||||
//
|
||||
// Note: although there is no function to get
|
||||
// the current status, bit 5 of 0040h:0065h
|
||||
// indicates the state.
|
||||
Regs.w.ax = 0x1003;
|
||||
Regs.w.bx = 0x0000;
|
||||
Int386(0x10, &Regs, &Regs);
|
||||
}
|
||||
|
||||
VOID BiosVideoEnableBlinkBit(VOID)
|
||||
{
|
||||
REGS Regs;
|
||||
|
||||
// Int 10h AX=1003h
|
||||
// VIDEO - TOGGLE INTENSITY/BLINKING BIT (Jr, PS, TANDY 1000, EGA, VGA)
|
||||
//
|
||||
// AX = 1003h
|
||||
// BL = new state
|
||||
// 00h background intensity enabled
|
||||
// 01h blink enabled
|
||||
// BH = 00h to avoid problems on some adapters
|
||||
// Return:
|
||||
// Nothing
|
||||
//
|
||||
// Note: although there is no function to get
|
||||
// the current status, bit 5 of 0040h:0065h
|
||||
// indicates the state.
|
||||
Regs.w.ax = 0x1003;
|
||||
Regs.w.bx = 0x0001;
|
||||
Int386(0x10, &Regs, &Regs);
|
||||
}
|
||||
|
||||
U16 BiosIsVesaSupported(VOID)
|
||||
{
|
||||
REGS Regs;
|
||||
PVESA_SVGA_INFO SvgaInfo = (PVESA_SVGA_INFO)BIOSCALLBUFFER;
|
||||
#ifdef DEBUG
|
||||
//U16* VideoModes;
|
||||
//U16 Index;
|
||||
#endif // defined DEBUG
|
||||
|
||||
DbgPrint((DPRINT_UI, "BiosIsVesaSupported()\n"));
|
||||
|
||||
RtlZeroMemory(SvgaInfo, sizeof(VESA_SVGA_INFO));
|
||||
|
||||
// Make sure we receive version 2.0 info
|
||||
SvgaInfo->Signature[0] = 'V';
|
||||
SvgaInfo->Signature[1] = 'B';
|
||||
SvgaInfo->Signature[2] = 'E';
|
||||
SvgaInfo->Signature[3] = '2';
|
||||
|
||||
// Int 10h AX=4F00h
|
||||
// VESA SuperVGA BIOS (VBE) - GET SuperVGA INFORMATION
|
||||
//
|
||||
// AX = 4F00h
|
||||
// ES:DI -> buffer for SuperVGA information (see #00077)
|
||||
// Return:
|
||||
// AL = 4Fh if function supported
|
||||
// AH = status
|
||||
// 00h successful
|
||||
// ES:DI buffer filled
|
||||
// 01h failed
|
||||
// ---VBE v2.0---
|
||||
// 02h function not supported by current hardware configuration
|
||||
// 03h function invalid in current video mode
|
||||
//
|
||||
// Determine whether VESA BIOS extensions are present and the
|
||||
// capabilities supported by the display adapter
|
||||
//
|
||||
// Installation check;VESA SuperVGA
|
||||
Regs.w.ax = 0x4F00;
|
||||
Regs.w.es = BIOSCALLBUFSEGMENT;
|
||||
Regs.w.di = BIOSCALLBUFOFFSET;
|
||||
Int386(0x10, &Regs, &Regs);
|
||||
|
||||
DbgPrint((DPRINT_UI, "AL = 0x%x\n", Regs.b.al));
|
||||
DbgPrint((DPRINT_UI, "AH = 0x%x\n", Regs.b.ah));
|
||||
|
||||
if (Regs.w.ax != 0x004F)
|
||||
{
|
||||
DbgPrint((DPRINT_UI, "Failed.\n"));
|
||||
return 0x0000;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
DbgPrint((DPRINT_UI, "Supported.\n"));
|
||||
DbgPrint((DPRINT_UI, "SvgaInfo->Signature[4] = %c%c%c%c\n", SvgaInfo->Signature[0], SvgaInfo->Signature[1], SvgaInfo->Signature[2], SvgaInfo->Signature[3]));
|
||||
DbgPrint((DPRINT_UI, "SvgaInfo->VesaVersion = v%d.%d\n", ((SvgaInfo->VesaVersion >> 8) & 0xFF), (SvgaInfo->VesaVersion & 0xFF)));
|
||||
DbgPrint((DPRINT_UI, "SvgaInfo->OemNamePtr = 0x%x\n", SvgaInfo->OemNamePtr));
|
||||
DbgPrint((DPRINT_UI, "SvgaInfo->Capabilities = 0x%x\n", SvgaInfo->Capabilities));
|
||||
DbgPrint((DPRINT_UI, "SvgaInfo->VideoMemory = %dK\n", SvgaInfo->TotalVideoMemory * 64));
|
||||
DbgPrint((DPRINT_UI, "---VBE v2.0 ---\n"));
|
||||
DbgPrint((DPRINT_UI, "SvgaInfo->OemSoftwareVersion = v%d.%d\n", ((SvgaInfo->OemSoftwareVersion >> 8) & 0x0F) + (((SvgaInfo->OemSoftwareVersion >> 12) & 0x0F) * 10), (SvgaInfo->OemSoftwareVersion & 0x0F) + (((SvgaInfo->OemSoftwareVersion >> 4) & 0x0F) * 10)));
|
||||
DbgPrint((DPRINT_UI, "SvgaInfo->VendorNamePtr = 0x%x\n", SvgaInfo->VendorNamePtr));
|
||||
DbgPrint((DPRINT_UI, "SvgaInfo->ProductNamePtr = 0x%x\n", SvgaInfo->ProductNamePtr));
|
||||
DbgPrint((DPRINT_UI, "SvgaInfo->ProductRevisionStringPtr = 0x%x\n", SvgaInfo->ProductRevisionStringPtr));
|
||||
DbgPrint((DPRINT_UI, "SvgaInfo->VBE/AF Version = 0x%x (BCD WORD)\n", SvgaInfo->VBE_AF_Version));
|
||||
|
||||
//DbgPrint((DPRINT_UI, "\nSupported VESA and OEM video modes:\n"));
|
||||
//VideoModes = (U16*)SvgaInfo->SupportedModeListPtr;
|
||||
//for (Index=0; VideoModes[Index]!=0xFFFF; Index++)
|
||||
//{
|
||||
// DbgPrint((DPRINT_UI, "Mode %d: 0x%x\n", Index, VideoModes[Index]));
|
||||
//}
|
||||
|
||||
//if (SvgaInfo->VesaVersion >= 0x0200)
|
||||
//{
|
||||
// DbgPrint((DPRINT_UI, "\nSupported accelerated video modes (VESA v2.0):\n"));
|
||||
// VideoModes = (U16*)SvgaInfo->AcceleratedModeListPtr;
|
||||
// for (Index=0; VideoModes[Index]!=0xFFFF; Index++)
|
||||
// {
|
||||
// DbgPrint((DPRINT_UI, "Mode %d: 0x%x\n", Index, VideoModes[Index]));
|
||||
// }
|
||||
//}
|
||||
|
||||
DbgPrint((DPRINT_UI, "\n"));
|
||||
//getch();
|
||||
#endif // defined DEBUG
|
||||
|
||||
return SvgaInfo->VesaVersion;
|
||||
}
|
||||
|
||||
BOOL BiosVesaSetBank(U16 Bank)
|
||||
{
|
||||
REGS Regs;
|
||||
|
||||
// Int 10h AX=4F05h
|
||||
// VESA SuperVGA BIOS - CPU VIDEO MEMORY CONTROL
|
||||
//
|
||||
// AX = 4F05h
|
||||
// BH = subfunction
|
||||
// 00h select video memory window
|
||||
// 01h get video memory window
|
||||
// DX = window address in video memory (in granularity units)
|
||||
// Return:
|
||||
// DX = window address in video memory (in gran. units)
|
||||
// BL = window number
|
||||
// 00h window A
|
||||
// 01h window B.
|
||||
// Return:
|
||||
// AL = 4Fh if function supported
|
||||
// AH = status
|
||||
// 00h successful
|
||||
// 01h failed
|
||||
|
||||
Regs.w.ax = 0x4F05;
|
||||
Regs.w.bx = 0x0000;
|
||||
Regs.w.dx = Bank;
|
||||
Int386(0x10, &Regs, &Regs);
|
||||
|
||||
if (Regs.w.ax != 0x004F)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL BiosVesaSetVideoMode(U16 Mode)
|
||||
{
|
||||
REGS Regs;
|
||||
|
||||
// Int 10h AX=4F02h
|
||||
// VESA SuperVGA BIOS - SET SuperVGA VIDEO MODE
|
||||
//
|
||||
// AX = 4F02h
|
||||
// BX = new video mode
|
||||
// ES:DI -> (VBE 3.0+) CRTC information block, bit mode bit 11 set
|
||||
// Return:
|
||||
// AL = 4Fh if function supported
|
||||
// AH = status
|
||||
// 00h successful
|
||||
// 01h failed
|
||||
//
|
||||
// Values for VESA video mode:
|
||||
// 00h-FFh OEM video modes (see #00010 at AH=00h)
|
||||
// 100h 640x400x256
|
||||
// 101h 640x480x256
|
||||
// 102h 800x600x16
|
||||
// 103h 800x600x256
|
||||
// 104h 1024x768x16
|
||||
// 105h 1024x768x256
|
||||
// 106h 1280x1024x16
|
||||
// 107h 1280x1024x256
|
||||
// 108h 80x60 text
|
||||
// 109h 132x25 text
|
||||
// 10Ah 132x43 text
|
||||
// 10Bh 132x50 text
|
||||
// 10Ch 132x60 text
|
||||
// ---VBE v1.2+ ---
|
||||
// 10Dh 320x200x32K
|
||||
// 10Eh 320x200x64K
|
||||
// 10Fh 320x200x16M
|
||||
// 110h 640x480x32K
|
||||
// 111h 640x480x64K
|
||||
// 112h 640x480x16M
|
||||
// 113h 800x600x32K
|
||||
// 114h 800x600x64K
|
||||
// 115h 800x600x16M
|
||||
// 116h 1024x768x32K
|
||||
// 117h 1024x768x64K
|
||||
// 118h 1024x768x16M
|
||||
// 119h 1280x1024x32K (1:5:5:5)
|
||||
// 11Ah 1280x1024x64K (5:6:5)
|
||||
// 11Bh 1280x1024x16M
|
||||
// ---VBE 2.0+ ---
|
||||
// 120h 1600x1200x256
|
||||
// 121h 1600x1200x32K
|
||||
// 122h 1600x1200x64K
|
||||
// 81FFh special full-memory access mode
|
||||
|
||||
// Notes: The special mode 81FFh preserves the contents of the video memory and gives
|
||||
// access to all of the memory; VESA recommends that the special mode be a packed-pixel
|
||||
// mode. For VBE 2.0+, it is required that the VBE implement the mode, but not place it
|
||||
// in the list of available modes (mode information for this mode can be queried
|
||||
// directly, however).. As of VBE 2.0, VESA will no longer define video mode numbers
|
||||
Regs.w.ax = 0x4F02;
|
||||
Regs.w.bx = Mode;
|
||||
Int386(0x10, &Regs, &Regs);
|
||||
|
||||
if (Regs.w.ax != 0x004F)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL BiosVesaGetSVGAModeInformation(U16 Mode, PSVGA_MODE_INFORMATION ModeInformation)
|
||||
{
|
||||
REGS Regs;
|
||||
|
||||
RtlZeroMemory((PVOID)BIOSCALLBUFFER, 256);
|
||||
|
||||
// VESA SuperVGA BIOS - GET SuperVGA MODE INFORMATION
|
||||
// AX = 4F01h
|
||||
// CX = SuperVGA video mode (see #04082 for bitfields)
|
||||
// ES:DI -> 256-byte buffer for mode information (see #00079)
|
||||
// Return:
|
||||
// AL = 4Fh if function supported
|
||||
// AH = status
|
||||
// 00h successful
|
||||
// ES:DI buffer filled
|
||||
// 01h failed
|
||||
//
|
||||
// Desc: Determine the attributes of the specified video mode
|
||||
//
|
||||
// Note: While VBE 1.1 and higher will zero out all unused bytes
|
||||
// of the buffer, v1.0 did not, so applications that want to be
|
||||
// backward compatible should clear the buffer before calling
|
||||
Regs.w.ax = 0x4F01;
|
||||
Regs.w.cx = Mode;
|
||||
Regs.w.es = BIOSCALLBUFSEGMENT;
|
||||
Regs.w.di = BIOSCALLBUFOFFSET;
|
||||
Int386(0x10, &Regs, &Regs);
|
||||
|
||||
if (Regs.w.ax != 0x004F)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RtlCopyMemory(ModeInformation, (PVOID)BIOSCALLBUFFER, sizeof(SVGA_MODE_INFORMATION));
|
||||
|
||||
DbgPrint((DPRINT_UI, "\n"));
|
||||
DbgPrint((DPRINT_UI, "BiosVesaGetSVGAModeInformation() mode 0x%x\n", Mode));
|
||||
DbgPrint((DPRINT_UI, "ModeAttributes = 0x%x\n", ModeInformation->ModeAttributes));
|
||||
DbgPrint((DPRINT_UI, "WindowAttributesA = 0x%x\n", ModeInformation->WindowAttributesA));
|
||||
DbgPrint((DPRINT_UI, "WindowAttributesB = 0x%x\n", ModeInformation->WindowsAttributesB));
|
||||
DbgPrint((DPRINT_UI, "WindowGranularity = %dKB\n", ModeInformation->WindowGranularity));
|
||||
DbgPrint((DPRINT_UI, "WindowSize = %dKB\n", ModeInformation->WindowSize));
|
||||
DbgPrint((DPRINT_UI, "WindowAStartSegment = 0x%x\n", ModeInformation->WindowAStartSegment));
|
||||
DbgPrint((DPRINT_UI, "WindowBStartSegment = 0x%x\n", ModeInformation->WindowBStartSegment));
|
||||
DbgPrint((DPRINT_UI, "WindowPositioningFunction = 0x%x\n", ModeInformation->WindowPositioningFunction));
|
||||
DbgPrint((DPRINT_UI, "BytesPerScanLine = %d\n", ModeInformation->BytesPerScanLine));
|
||||
DbgPrint((DPRINT_UI, "WidthInPixels = %d\n", ModeInformation->WidthInPixels));
|
||||
DbgPrint((DPRINT_UI, "HeightInPixels = %d\n", ModeInformation->HeightInPixels));
|
||||
DbgPrint((DPRINT_UI, "CharacterWidthInPixels = %d\n", ModeInformation->CharacterWidthInPixels));
|
||||
DbgPrint((DPRINT_UI, "CharacterHeightInPixels = %d\n", ModeInformation->CharacterHeightInPixels));
|
||||
DbgPrint((DPRINT_UI, "NumberOfMemoryPlanes = %d\n", ModeInformation->NumberOfMemoryPlanes));
|
||||
DbgPrint((DPRINT_UI, "BitsPerPixel = %d\n", ModeInformation->BitsPerPixel));
|
||||
DbgPrint((DPRINT_UI, "NumberOfBanks = %d\n", ModeInformation->NumberOfBanks));
|
||||
DbgPrint((DPRINT_UI, "MemoryModel = %d\n", ModeInformation->MemoryModel));
|
||||
DbgPrint((DPRINT_UI, "BankSize = %d\n", ModeInformation->BankSize));
|
||||
DbgPrint((DPRINT_UI, "NumberOfImagePlanes = %d\n", ModeInformation->NumberOfImagePanes));
|
||||
DbgPrint((DPRINT_UI, "---VBE v1.2+ ---\n"));
|
||||
DbgPrint((DPRINT_UI, "RedMaskSize = %d\n", ModeInformation->RedMaskSize));
|
||||
DbgPrint((DPRINT_UI, "RedMaskPosition = %d\n", ModeInformation->RedMaskPosition));
|
||||
DbgPrint((DPRINT_UI, "GreenMaskSize = %d\n", ModeInformation->GreenMaskSize));
|
||||
DbgPrint((DPRINT_UI, "GreenMaskPosition = %d\n", ModeInformation->GreenMaskPosition));
|
||||
DbgPrint((DPRINT_UI, "BlueMaskSize = %d\n", ModeInformation->BlueMaskSize));
|
||||
DbgPrint((DPRINT_UI, "BlueMaskPosition = %d\n", ModeInformation->BlueMaskPosition));
|
||||
DbgPrint((DPRINT_UI, "ReservedMaskSize = %d\n", ModeInformation->ReservedMaskSize));
|
||||
DbgPrint((DPRINT_UI, "ReservedMaskPosition = %d\n", ModeInformation->ReservedMaskPosition));
|
||||
DbgPrint((DPRINT_UI, "\n"));
|
||||
|
||||
return TRUE;
|
||||
}
|
155
freeldr/freeldr/arch/i386/int386.S
Normal file
155
freeldr/freeldr/arch/i386/int386.S
Normal file
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
* FreeLoader
|
||||
* Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
.text
|
||||
.code16
|
||||
|
||||
#define ASM
|
||||
#include <arch.h>
|
||||
|
||||
|
||||
Int386_REGS:
|
||||
|
||||
Int386_eax:
|
||||
.long 0
|
||||
Int386_ebx:
|
||||
.long 0
|
||||
Int386_ecx:
|
||||
.long 0
|
||||
Int386_edx:
|
||||
.long 0
|
||||
|
||||
Int386_esi:
|
||||
.long 0
|
||||
Int386_edi:
|
||||
.long 0
|
||||
|
||||
Int386_ds:
|
||||
.word 0
|
||||
Int386_es:
|
||||
.word 0
|
||||
Int386_fs:
|
||||
.word 0
|
||||
Int386_gs:
|
||||
.word 0
|
||||
|
||||
Int386_eflags:
|
||||
.long 0
|
||||
|
||||
Int386_vector:
|
||||
.long 0
|
||||
Int386_regsin:
|
||||
.long 0
|
||||
Int386_regsout:
|
||||
.long 0
|
||||
|
||||
/*
|
||||
* int Int386(int ivec, REGS* in, REGS* out);
|
||||
*/
|
||||
EXTERN(_Int386)
|
||||
.code32
|
||||
|
||||
/* Get the function parameters */
|
||||
movl 0x04(%esp),%eax
|
||||
movl %eax,Int386_vector
|
||||
movb %al,Int386_vector_opcode
|
||||
movl 0x08(%esp),%eax
|
||||
movl %eax,Int386_regsin
|
||||
movl 0x0c(%esp),%eax
|
||||
movl %eax,Int386_regsout
|
||||
|
||||
pushal
|
||||
|
||||
/* Copy the input regs to our variables */
|
||||
movl $Int386_REGS,%edi
|
||||
movl Int386_regsin,%esi
|
||||
movl $0x24,%ecx
|
||||
rep
|
||||
movsb
|
||||
|
||||
call switch_to_real
|
||||
.code16
|
||||
|
||||
/* Setup the registers */
|
||||
movw %cs:Int386_ds,%ax
|
||||
movw %ax,%ds /* DS register */
|
||||
movw %cs:Int386_es,%ax
|
||||
movw %ax,%es /* ES register */
|
||||
movw %cs:Int386_fs,%ax
|
||||
movw %ax,%fs /* FS register */
|
||||
movw %cs:Int386_gs,%ax
|
||||
movw %ax,%gs /* GS register */
|
||||
|
||||
movl %cs:Int386_eax,%eax /* EAX register */
|
||||
movl %cs:Int386_ebx,%ebx /* EBX register */
|
||||
movl %cs:Int386_ecx,%ecx /* ECX register */
|
||||
movl %cs:Int386_edx,%edx /* EDX register */
|
||||
|
||||
movl %cs:Int386_esi,%esi /* ESI register */
|
||||
movl %cs:Int386_edi,%edi /* EDI register */
|
||||
|
||||
/* Do not set the flags register */
|
||||
/* only return its value in regsout */
|
||||
//pushl Int386_eflags
|
||||
//popfl /* EFLAGS register */
|
||||
|
||||
/* Call the interrupt vector */
|
||||
/*int Int386_vector*/
|
||||
Int386_int_opcode:
|
||||
.byte 0xcd
|
||||
Int386_vector_opcode:
|
||||
.byte 0x00
|
||||
|
||||
/* Save the registers */
|
||||
movl %eax,%cs:Int386_eax /* EAX register */
|
||||
movl %ebx,%cs:Int386_ebx /* EBX register */
|
||||
movl %ecx,%cs:Int386_ecx /* ECX register */
|
||||
movl %edx,%cs:Int386_edx /* EDX register */
|
||||
|
||||
movl %esi,%cs:Int386_esi /* ESI register */
|
||||
movl %edi,%cs:Int386_edi /* EDI register */
|
||||
|
||||
movw %ds,%ax /* DS register */
|
||||
movw %ax,%cs:Int386_ds
|
||||
movw %es,%ax /* ES register */
|
||||
movw %ax,%cs:Int386_es
|
||||
movw %fs,%ax /* FS register */
|
||||
movw %ax,%cs:Int386_fs
|
||||
movw %gs,%ax /* GS register */
|
||||
movw %ax,%cs:Int386_gs
|
||||
|
||||
pushf
|
||||
popw %cs:Int386_eflags /* EFLAGS register */
|
||||
|
||||
call switch_to_prot
|
||||
.code32
|
||||
|
||||
/* Copy the variables to the output regs */
|
||||
movl $Int386_REGS,%esi
|
||||
movl Int386_regsout,%edi
|
||||
movl $0x24,%ecx
|
||||
rep
|
||||
movsb
|
||||
|
||||
popal
|
||||
|
||||
/* Get return value */
|
||||
movl Int386_eax,%eax
|
||||
|
||||
ret
|
|
@ -1,213 +0,0 @@
|
|||
/*
|
||||
* FreeLoader
|
||||
* Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
.text
|
||||
.code16
|
||||
|
||||
#define ASM
|
||||
#include <arch.h>
|
||||
#include <multiboot.h>
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* ULONG GetExtendedMemorySize(VOID);
|
||||
*/
|
||||
ExtendedMemorySize:
|
||||
.long 0
|
||||
EXTERN(_GetExtendedMemorySize)
|
||||
.code32
|
||||
|
||||
pushal
|
||||
|
||||
movl $0,ExtendedMemorySize
|
||||
|
||||
call switch_to_real
|
||||
.code16
|
||||
|
||||
movw $0xE801,%ax
|
||||
int $0x15
|
||||
jc GetExtendedMemorySizeTryInt15Func88
|
||||
|
||||
cmpw $0,%ax
|
||||
je GetExtendedMemorySizeUseCXDX
|
||||
|
||||
movzwl %bx,%ebx
|
||||
shll $6,%ebx
|
||||
movzwl %ax,%eax
|
||||
addl %ebx,%eax
|
||||
movl %eax,ExtendedMemorySize
|
||||
jmp GetExtendedMemorySizeDone
|
||||
|
||||
GetExtendedMemorySizeUseCXDX:
|
||||
cmpw $0,%cx
|
||||
je GetExtendedMemorySizeTryInt15Func88
|
||||
|
||||
movzwl %dx,%edx
|
||||
shll $6,%edx
|
||||
movzwl %cx,%ecx
|
||||
addl %ecx,%edx
|
||||
movl %edx,ExtendedMemorySize
|
||||
jmp GetExtendedMemorySizeDone
|
||||
|
||||
GetExtendedMemorySizeTryInt15Func88:
|
||||
movb $0x88,%ah
|
||||
int $0x15
|
||||
jc GetExtendedMemorySizeTryCMOS
|
||||
cmpw $0,%ax
|
||||
je GetExtendedMemorySizeTryCMOS
|
||||
movzwl %ax,%eax
|
||||
movl %eax,ExtendedMemorySize
|
||||
jmp GetExtendedMemorySizeDone
|
||||
|
||||
GetExtendedMemorySizeTryCMOS:
|
||||
xorl %eax,%eax
|
||||
movb $0x31,%al
|
||||
outb %al,$0x70
|
||||
inb $0x71,%al
|
||||
andl $0xffff,%eax
|
||||
shll $8,%eax
|
||||
movl %eax,ExtendedMemorySize
|
||||
|
||||
GetExtendedMemorySizeDone:
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
popal
|
||||
|
||||
/* Restore return value */
|
||||
movl ExtendedMemorySize,%eax
|
||||
|
||||
ret
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* ULONG GetConventionalMemorySize(VOID);
|
||||
*/
|
||||
ConventionalMemorySize:
|
||||
.long 0
|
||||
EXTERN(_GetConventionalMemorySize)
|
||||
.code32
|
||||
|
||||
pushal
|
||||
|
||||
movl $0,ConventionalMemorySize
|
||||
|
||||
call switch_to_real
|
||||
.code16
|
||||
|
||||
xorl %eax,%eax
|
||||
int $0x12
|
||||
|
||||
/* Save return value */
|
||||
movzwl %ax,%eax
|
||||
movl %eax,ConventionalMemorySize
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
popal
|
||||
|
||||
/* Restore return value */
|
||||
movl ConventionalMemorySize,%eax
|
||||
|
||||
ret
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* ULONG GetBiosMemoryMap(PBIOS_MEMORY_MAP_ARRAY BiosMemoryMap);
|
||||
*/
|
||||
_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)
|
||||
.code32
|
||||
|
||||
pushal
|
||||
|
||||
movl $0,_gbmm_mem_map_length
|
||||
|
||||
/* 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,%edi
|
||||
|
||||
GetBiosMemoryMapNext:
|
||||
|
||||
movl $0x534D4150,%edx // 'SMAP'
|
||||
movl $24,%ecx
|
||||
movl $0xE820,%eax
|
||||
int $0x15
|
||||
jc GetBiosMemoryMapDone
|
||||
|
||||
// If the BIOS didn't return 'SMAP' in EAX then
|
||||
// it doesn't support this call
|
||||
cmpl $0x534D4150,%eax // 'SMAP'
|
||||
jne GetBiosMemoryMapDone
|
||||
|
||||
// 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 GetBiosMemoryMapNext
|
||||
|
||||
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
|
||||
|
||||
ret
|
|
@ -1,470 +0,0 @@
|
|||
/*
|
||||
* FreeLoader
|
||||
* Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
.text
|
||||
.code16
|
||||
|
||||
#define ASM
|
||||
#include <arch.h>
|
||||
|
||||
|
||||
/*
|
||||
* void putchar(int ch);
|
||||
*/
|
||||
EXTERN(_putchar)
|
||||
.code32
|
||||
|
||||
pushal
|
||||
|
||||
/* Get character to display */
|
||||
movb 0x24(%esp),%bl
|
||||
|
||||
/* If we are displaying a CR '\n' then do a LF also */
|
||||
cmpb $0x0a,%bl
|
||||
jnz putchar_1
|
||||
|
||||
/* Display the LF */
|
||||
pushl $0x0d
|
||||
call _putchar
|
||||
popl %eax
|
||||
|
||||
putchar_1:
|
||||
/* If we are displaying a TAB '\t' then display 8 spaces ' ' */
|
||||
cmpb $0x09,%bl
|
||||
jnz putchar_2
|
||||
|
||||
/* Display the 8 spaces ' ' */
|
||||
pushl $0x20
|
||||
call _putchar
|
||||
call _putchar
|
||||
call _putchar
|
||||
call _putchar
|
||||
call _putchar
|
||||
call _putchar
|
||||
call _putchar
|
||||
call _putchar
|
||||
popl %eax
|
||||
popal
|
||||
|
||||
ret
|
||||
|
||||
putchar_2:
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
/* Display the character via BIOS int 0x10 function 0x0e */
|
||||
movb $0x0e,%ah
|
||||
movb %bl,%al
|
||||
movw $1,%bx
|
||||
int $0x10
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
popal
|
||||
|
||||
ret
|
||||
|
||||
/*
|
||||
* int kbhit(void);
|
||||
*/
|
||||
_kbhit_retval:
|
||||
.long 0
|
||||
EXTERN(_kbhit)
|
||||
.code32
|
||||
|
||||
pushal
|
||||
|
||||
movl $0x00,_kbhit_retval
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
/* Int 0x16, AH = 0x01 - Get Keyboard Status */
|
||||
movb $0x01,%ah
|
||||
int $0x16
|
||||
jz kbhit_1 // ZF=0 if no key is available
|
||||
|
||||
/* Return value is non-zero if a key is available */
|
||||
movl $1,_kbhit_retval
|
||||
jmp kbhit_done
|
||||
|
||||
kbhit_1:
|
||||
/* Return value is zero if no key is available */
|
||||
movl $0,_kbhit_retval
|
||||
|
||||
kbhit_done:
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
popal
|
||||
|
||||
/* Get return value */
|
||||
movl _kbhit_retval,%eax
|
||||
|
||||
ret
|
||||
|
||||
/*
|
||||
* int getch(void);
|
||||
*/
|
||||
extended_scancode:
|
||||
.byte 0
|
||||
EXTERN(_getch)
|
||||
.code32
|
||||
|
||||
push %ebp
|
||||
push %ebx
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
/* Check and see if we have an extended scancode to return */
|
||||
movb extended_scancode,%al
|
||||
movb $0,extended_scancode
|
||||
movzbl %al,%ebx
|
||||
cmpb $0,%al
|
||||
jnz getch_done
|
||||
|
||||
/* Int 0x16, AH = 0x00 - Wait for keypress */
|
||||
movb $0,%ah
|
||||
int $0x16
|
||||
|
||||
/* If al is zero then it is an extended key */
|
||||
cmp $0,%al
|
||||
jnz getch_1
|
||||
|
||||
/* Save the scan code to be returned on the next call to getch() */
|
||||
movb %ah,extended_scancode
|
||||
|
||||
getch_1:
|
||||
/* Store character in ebx */
|
||||
movzbl %al,%ebx
|
||||
|
||||
getch_done:
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
/* Get return value from ebx */
|
||||
movl %ebx,%eax
|
||||
|
||||
pop %ebx
|
||||
pop %ebp
|
||||
ret
|
||||
|
||||
/*
|
||||
* int getyear(void);
|
||||
*/
|
||||
EXTERN(_getyear)
|
||||
.code32
|
||||
|
||||
push %ebp
|
||||
push %ebx
|
||||
push %ecx
|
||||
push %edx
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
/* Get the date */
|
||||
movb $4,%ah
|
||||
int $0x1a
|
||||
|
||||
/* Convert from BCD to normal */
|
||||
movb %ch,%al
|
||||
andb $0x0f,%al
|
||||
movb %al,%dl
|
||||
movb %ch,%al
|
||||
shrb $0x04,%al
|
||||
andb $0x0f,%al
|
||||
movb $0x0a,%bl
|
||||
mulb %bl
|
||||
addb %al,%dl
|
||||
movb %dl,%dh
|
||||
|
||||
movb %cl,%al
|
||||
andb $0x0f,%al
|
||||
movb %al,%dl
|
||||
movb %cl,%al
|
||||
shrb $0x04,%al
|
||||
andb $0x0f,%al
|
||||
movb $0x0a,%bl
|
||||
mulb %bl
|
||||
addb %al,%dl
|
||||
|
||||
movb %dl,%cl
|
||||
|
||||
movzbl %dh,%eax
|
||||
movl $100,%ebx
|
||||
mull %ebx
|
||||
movl %eax,%edx
|
||||
addb %cl,%dl
|
||||
|
||||
/* Save return value */
|
||||
movl %edx,%edx
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
/* Restore return value */
|
||||
movl %edx,%eax
|
||||
|
||||
pop %edx
|
||||
pop %ecx
|
||||
pop %ebx
|
||||
pop %ebp
|
||||
ret
|
||||
|
||||
/*
|
||||
* int getday(void);
|
||||
*/
|
||||
EXTERN(_getday)
|
||||
.code32
|
||||
|
||||
push %ebp
|
||||
push %ebx
|
||||
push %ecx
|
||||
push %edx
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
/* Get the date */
|
||||
movb $4,%ah
|
||||
int $0x1a
|
||||
|
||||
/* Convert from BCD to normal */
|
||||
movb %dl,%al
|
||||
andb $0x0f,%al
|
||||
movb %al,%cl
|
||||
movb %dl,%al
|
||||
shrb $0x04,%al
|
||||
andb $0x0f,%al
|
||||
movb $0x0a,%bl
|
||||
mulb %bl
|
||||
addb %al,%cl
|
||||
|
||||
/* Save return value */
|
||||
movzbl %cl,%edx
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
/* Restore return value */
|
||||
movl %edx,%eax
|
||||
|
||||
pop %edx
|
||||
pop %ecx
|
||||
pop %ebx
|
||||
pop %ebp
|
||||
ret
|
||||
|
||||
/*
|
||||
* int getmonth(void);
|
||||
*/
|
||||
EXTERN(_getmonth)
|
||||
.code32
|
||||
|
||||
push %ebp
|
||||
push %ebx
|
||||
push %ecx
|
||||
push %edx
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
/* Get the date */
|
||||
movb $4,%ah
|
||||
int $0x1a
|
||||
|
||||
/* Convert from BCD to normal */
|
||||
movb %dh,%al
|
||||
andb $0x0f,%al
|
||||
movb %al,%dl
|
||||
movb %dh,%al
|
||||
shrb $0x04,%al
|
||||
andb $0x0f,%al
|
||||
movb $0x0a,%bl
|
||||
mulb %bl
|
||||
addb %al,%dl
|
||||
|
||||
/* Save return value */
|
||||
movzbl %dl,%edx
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
/* Restore return value */
|
||||
movl %edx,%eax
|
||||
|
||||
pop %edx
|
||||
pop %ecx
|
||||
pop %ebx
|
||||
pop %ebp
|
||||
ret
|
||||
|
||||
/*
|
||||
* int gethour(void);
|
||||
*/
|
||||
EXTERN(_gethour)
|
||||
.code32
|
||||
|
||||
push %ebp
|
||||
push %ebx
|
||||
push %ecx
|
||||
push %edx
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
/* Get the time */
|
||||
movb $2,%ah
|
||||
int $0x1a
|
||||
|
||||
/* Convert from BCD to normal */
|
||||
movb %ch,%al
|
||||
andb $0x0f,%al
|
||||
movb %al,%dl
|
||||
movb %ch,%al
|
||||
shrb $0x04,%al
|
||||
andb $0x0f,%al
|
||||
movb $0x0a,%bl
|
||||
mulb %bl
|
||||
addb %al,%dl
|
||||
|
||||
/* Save return value */
|
||||
movzbl %dl,%edx
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
/* Restore return value */
|
||||
movl %edx,%eax
|
||||
|
||||
pop %edx
|
||||
pop %ecx
|
||||
pop %ebx
|
||||
pop %ebp
|
||||
ret
|
||||
|
||||
/*
|
||||
* int getminute(void);
|
||||
*/
|
||||
EXTERN(_getminute)
|
||||
.code32
|
||||
|
||||
push %ebp
|
||||
push %ebx
|
||||
push %ecx
|
||||
push %edx
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
/* Get the time */
|
||||
movb $2,%ah
|
||||
int $0x1a
|
||||
|
||||
/* Convert from BCD to normal */
|
||||
movb %cl,%al
|
||||
andb $0x0f,%al
|
||||
movb %al,%dl
|
||||
movb %cl,%al
|
||||
shrb $0x04,%al
|
||||
andb $0x0f,%al
|
||||
movb $0x0a,%bl
|
||||
mulb %bl
|
||||
addb %al,%dl
|
||||
|
||||
/* Save return value */
|
||||
movzbl %dl,%edx
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
/* Restore return value */
|
||||
movl %edx,%eax
|
||||
|
||||
pop %edx
|
||||
pop %ecx
|
||||
pop %ebx
|
||||
pop %ebp
|
||||
ret
|
||||
|
||||
/*
|
||||
* int getsecond(void);
|
||||
*/
|
||||
EXTERN(_getsecond)
|
||||
.code32
|
||||
|
||||
push %ebp
|
||||
push %ebx
|
||||
push %ecx
|
||||
push %edx
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
/* Get the time */
|
||||
movb $2,%ah
|
||||
int $0x1a
|
||||
|
||||
/* Convert from BCD to normal */
|
||||
movb %dh,%al
|
||||
andb $0x0f,%al
|
||||
movb %al,%dl
|
||||
movb %dh,%al
|
||||
shrb $0x04,%al
|
||||
andb $0x0f,%al
|
||||
movb $0x0a,%bl
|
||||
mulb %bl
|
||||
addb %al,%dl
|
||||
|
||||
/* Save return value */
|
||||
movzbl %dl,%edx
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
/* Restore return value */
|
||||
movl %edx,%eax
|
||||
|
||||
pop %edx
|
||||
pop %ecx
|
||||
pop %ebx
|
||||
pop %ebp
|
||||
ret
|
1
freeldr/freeldr/cache/blocklist.c
vendored
1
freeldr/freeldr/cache/blocklist.c
vendored
|
@ -214,7 +214,6 @@ VOID CacheInternalDumpBlockList(PCACHE_DRIVE CacheDrive)
|
|||
PCACHE_BLOCK CacheBlock;
|
||||
|
||||
DbgPrint((DPRINT_CACHE, "Dumping block list for BIOS drive 0x%x.\n", CacheDrive->DriveNumber));
|
||||
DbgPrint((DPRINT_CACHE, "LbaSupported = %s.\n", CacheDrive->LbaSupported ? "TRUE" : "FALSE"));
|
||||
DbgPrint((DPRINT_CACHE, "Cylinders: %d.\n", CacheDrive->DriveGeometry.Cylinders));
|
||||
DbgPrint((DPRINT_CACHE, "Heads: %d.\n", CacheDrive->DriveGeometry.Heads));
|
||||
DbgPrint((DPRINT_CACHE, "Sectors: %d.\n", CacheDrive->DriveGeometry.Sectors));
|
||||
|
|
17
freeldr/freeldr/cache/cache.c
vendored
17
freeldr/freeldr/cache/cache.c
vendored
|
@ -82,25 +82,13 @@ BOOL CacheInitializeDrive(U32 DriveNumber)
|
|||
// Initialize the structure
|
||||
RtlZeroMemory(&CacheManagerDrive, sizeof(CACHE_DRIVE));
|
||||
CacheManagerDrive.DriveNumber = DriveNumber;
|
||||
CacheManagerDrive.LbaSupported = BiosInt13ExtensionsSupported(DriveNumber);
|
||||
if (!DiskGetDriveGeometry(DriveNumber, &CacheManagerDrive.DriveGeometry))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// If LBA is supported then the block size will be 128 sectors (64k)
|
||||
// If not then the block size is the size of one track
|
||||
if (CacheManagerDrive.LbaSupported)
|
||||
{
|
||||
// FIXME: Temporarily reduced this to
|
||||
// 64 sectors since not all BIOS calls
|
||||
// support reading as many as 128 sectors
|
||||
CacheManagerDrive.BlockSize = 64;//128;
|
||||
}
|
||||
else
|
||||
{
|
||||
CacheManagerDrive.BlockSize = CacheManagerDrive.DriveGeometry.Sectors;
|
||||
}
|
||||
// Get the number of sectors in each cache block
|
||||
CacheManagerDrive.BlockSize = DiskGetCacheableBlockCount(DriveNumber);
|
||||
|
||||
CacheBlockCount = 0;
|
||||
CacheSizeLimit = GetSystemMemorySize() / 8;
|
||||
|
@ -113,7 +101,6 @@ BOOL CacheInitializeDrive(U32 DriveNumber)
|
|||
CacheManagerInitialized = TRUE;
|
||||
|
||||
DbgPrint((DPRINT_CACHE, "Initializing BIOS drive 0x%x.\n", DriveNumber));
|
||||
DbgPrint((DPRINT_CACHE, "LbaSupported = %s.\n", CacheManagerDrive.LbaSupported ? "TRUE" : "FALSE"));
|
||||
DbgPrint((DPRINT_CACHE, "Cylinders: %d.\n", CacheManagerDrive.DriveGeometry.Cylinders));
|
||||
DbgPrint((DPRINT_CACHE, "Heads: %d.\n", CacheManagerDrive.DriveGeometry.Heads));
|
||||
DbgPrint((DPRINT_CACHE, "Sectors: %d.\n", CacheManagerDrive.DriveGeometry.Sectors));
|
||||
|
|
1
freeldr/freeldr/cache/cm.h
vendored
1
freeldr/freeldr/cache/cm.h
vendored
|
@ -56,7 +56,6 @@ typedef struct
|
|||
typedef struct
|
||||
{
|
||||
U32 DriveNumber;
|
||||
BOOL LbaSupported;
|
||||
GEOMETRY DriveGeometry;
|
||||
|
||||
U32 BlockSize; // Block size (in sectors)
|
||||
|
|
|
@ -24,13 +24,13 @@
|
|||
|
||||
#ifdef DEBUG
|
||||
|
||||
//#define DEBUG_ULTRA
|
||||
#define DEBUG_ALL
|
||||
//#define DEBUG_INIFILE
|
||||
//#define DEBUG_REACTOS
|
||||
//#define DEBUG_CUSTOM
|
||||
#define DEBUG_NONE
|
||||
|
||||
#if defined (DEBUG_ULTRA)
|
||||
#if defined (DEBUG_ALL)
|
||||
U32 DebugPrintMask = DPRINT_WARNING | DPRINT_MEMORY | DPRINT_FILESYSTEM |
|
||||
DPRINT_UI | DPRINT_DISK | DPRINT_CACHE | DPRINT_REACTOS |
|
||||
DPRINT_LINUX;
|
||||
|
@ -55,8 +55,8 @@ U32 DebugPrintMask = 0;
|
|||
|
||||
#define BOCHS_OUTPUT_PORT 0xe9
|
||||
|
||||
//U32 DebugPort = RS232;
|
||||
U32 DebugPort = SCREEN;
|
||||
U32 DebugPort = RS232;
|
||||
//U32 DebugPort = SCREEN;
|
||||
//U32 DebugPort = BOCHS;
|
||||
U32 ComPort = COM1;
|
||||
//U32 BaudRate = 19200;
|
||||
|
|
|
@ -19,126 +19,95 @@
|
|||
|
||||
#include <freeldr.h>
|
||||
#include <disk.h>
|
||||
#include <fs.h>
|
||||
#include <arch.h>
|
||||
#include <rtl.h>
|
||||
#include <ui.h>
|
||||
#include <arch.h>
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
#undef UNIMPLEMENTED
|
||||
#define UNIMPLEMENTED BugCheck((DPRINT_WARNING, "Unimplemented\n"));
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// FUNCTIONS
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
VOID DiskError(PUCHAR ErrorString)
|
||||
VOID DiskError(PUCHAR ErrorString, U32 ErrorCode)
|
||||
{
|
||||
UCHAR ErrorCodeString[80];
|
||||
|
||||
sprintf(ErrorCodeString, "%s\nError Code: 0x%x", ErrorString, BiosInt13GetLastErrorCode());
|
||||
sprintf(ErrorCodeString, "%s\n\nError Code: 0x%x", ErrorString, ErrorCode);
|
||||
|
||||
DbgPrint((DPRINT_DISK, "%s\n", ErrorCodeString));
|
||||
|
||||
UiMessageBox(ErrorCodeString);
|
||||
}
|
||||
|
||||
BOOL DiskReadLogicalSectors(U32 DriveNumber, U32 SectorNumber, U32 SectorCount, PVOID Buffer)
|
||||
// This function is in arch/i386/i386disk.c
|
||||
//BOOL DiskReadLogicalSectors(U32 DriveNumber, U64 SectorNumber, U32 SectorCount, PVOID Buffer)
|
||||
|
||||
BOOL DiskIsDriveRemovable(U32 DriveNumber)
|
||||
{
|
||||
U32 PhysicalSector;
|
||||
U32 PhysicalHead;
|
||||
U32 PhysicalTrack;
|
||||
GEOMETRY DriveGeometry;
|
||||
U32 NumberOfSectorsToRead;
|
||||
|
||||
DbgPrint((DPRINT_DISK, "ReadLogicalSectors() DriveNumber: 0x%x SectorNumber: %d SectorCount: %d Buffer: 0x%x\n", DriveNumber, SectorNumber, SectorCount, Buffer));
|
||||
|
||||
//
|
||||
// Check to see if it is a fixed disk drive
|
||||
// If so then check to see if Int13 extensions work
|
||||
// If they do then use them, otherwise default back to BIOS calls
|
||||
//
|
||||
if ((DriveNumber >= 0x80) && (IsSetupLdr || BiosInt13ExtensionsSupported(DriveNumber)))
|
||||
// Hard disks use drive numbers >= 0x80
|
||||
// So if the drive number indicates a hard disk
|
||||
// then return FALSE
|
||||
if (DriveNumber >= 0x80)
|
||||
{
|
||||
DbgPrint((DPRINT_DISK, "Using Int 13 Extensions for read. BiosInt13ExtensionsSupported(%d) = %s\n", DriveNumber, BiosInt13ExtensionsSupported(DriveNumber) ? "TRUE" : "FALSE"));
|
||||
|
||||
//
|
||||
// LBA is easy, nothing to calculate
|
||||
// Just do the read
|
||||
//
|
||||
if (!BiosInt13ReadExtended(DriveNumber, SectorNumber, SectorCount, Buffer))
|
||||
{
|
||||
DiskError("Disk read error.");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Get the drive geometry
|
||||
//
|
||||
if (!DiskGetDriveGeometry(DriveNumber, &DriveGeometry))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
while (SectorCount)
|
||||
{
|
||||
|
||||
//
|
||||
// Calculate the physical disk offsets
|
||||
//
|
||||
PhysicalSector = 1 + (SectorNumber % DriveGeometry.Sectors);
|
||||
PhysicalHead = (SectorNumber / DriveGeometry.Sectors) % DriveGeometry.Heads;
|
||||
PhysicalTrack = (SectorNumber / DriveGeometry.Sectors) / DriveGeometry.Heads;
|
||||
|
||||
//
|
||||
// Calculate how many sectors we are supposed to read
|
||||
//
|
||||
if (PhysicalSector > 1)
|
||||
{
|
||||
if (SectorCount >= (DriveGeometry.Sectors - (PhysicalSector - 1)))
|
||||
NumberOfSectorsToRead = (DriveGeometry.Sectors - (PhysicalSector - 1));
|
||||
else
|
||||
NumberOfSectorsToRead = SectorCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SectorCount >= DriveGeometry.Sectors)
|
||||
NumberOfSectorsToRead = DriveGeometry.Sectors;
|
||||
else
|
||||
NumberOfSectorsToRead = SectorCount;
|
||||
}
|
||||
|
||||
DbgPrint((DPRINT_DISK, "Calling BiosInt13Read() with PhysicalHead: %d\n", PhysicalHead));
|
||||
DbgPrint((DPRINT_DISK, "Calling BiosInt13Read() with PhysicalTrack: %d\n", PhysicalTrack));
|
||||
DbgPrint((DPRINT_DISK, "Calling BiosInt13Read() with PhysicalSector: %d\n", PhysicalSector));
|
||||
DbgPrint((DPRINT_DISK, "Calling BiosInt13Read() with NumberOfSectorsToRead: %d\n", NumberOfSectorsToRead));
|
||||
|
||||
//
|
||||
// Make sure the read is within the geometry boundaries
|
||||
//
|
||||
if ((PhysicalHead >= DriveGeometry.Heads) ||
|
||||
(PhysicalTrack >= DriveGeometry.Cylinders) ||
|
||||
((NumberOfSectorsToRead + PhysicalSector) > (DriveGeometry.Sectors + 1)) ||
|
||||
(PhysicalSector > DriveGeometry.Sectors))
|
||||
{
|
||||
DiskError("Disk read exceeds drive geometry limits.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// Perform the read
|
||||
//
|
||||
if (!BiosInt13Read(DriveNumber, PhysicalHead, PhysicalTrack, PhysicalSector, NumberOfSectorsToRead, Buffer))
|
||||
{
|
||||
DiskError("Disk read error.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Buffer += (NumberOfSectorsToRead * DriveGeometry.BytesPerSector);
|
||||
SectorCount -= NumberOfSectorsToRead;
|
||||
SectorNumber += NumberOfSectorsToRead;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Drive is a floppy diskette so return TRUE
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL DiskIsDriveCdRom(U32 DriveNumber)
|
||||
{
|
||||
PUCHAR Sector = (PUCHAR)DISKREADBUFFER;
|
||||
|
||||
// FIXME:
|
||||
// I need to move this code to somewhere else
|
||||
// probably in the file system code.
|
||||
// I don't like the fact that the disk code
|
||||
// reads the on-disk structures to determine
|
||||
// if it's a CD-ROM drive. Only the file system
|
||||
// should interpret on-disk data.
|
||||
// The disk code should use some other method
|
||||
// to determine if it's a CD-ROM drive.
|
||||
|
||||
// Hard disks use drive numbers >= 0x80
|
||||
// So if the drive number indicates a hard disk
|
||||
// then return FALSE
|
||||
//
|
||||
// We first check if we are running as a SetupLoader
|
||||
// If so then we are probably booting from a CD-ROM
|
||||
// So we shouldn't call i386DiskInt13ExtensionsSupported()
|
||||
// because apparently it screws up some BIOSes
|
||||
if ((DriveNumber >= 0x80) && (IsSetupLdr || DiskInt13ExtensionsSupported(DriveNumber)))
|
||||
{
|
||||
|
||||
// We are a CD-ROM drive so we should only
|
||||
// use the extended Int13 disk functions
|
||||
if (!DiskReadLogicalSectorsLBA(DriveNumber, 16, 1, Sector))
|
||||
{
|
||||
DiskError("Disk read error.", 0);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return (Sector[0] == 1 &&
|
||||
Sector[1] == 'C' &&
|
||||
Sector[2] == 'D' &&
|
||||
Sector[3] == '0' &&
|
||||
Sector[4] == '0' &&
|
||||
Sector[5] == '1');
|
||||
}
|
||||
|
||||
// Drive is not CdRom so return FALSE
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// This function is in arch/i386/i386disk.c
|
||||
//VOID DiskStopFloppyMotor(VOID)
|
||||
|
||||
// This function is in arch/i386/i386disk.c
|
||||
//U32 DiskGetCacheableBlockCount(U32 DriveNumber)
|
||||
|
|
|
@ -23,15 +23,22 @@
|
|||
#include <mm.h>
|
||||
|
||||
|
||||
#ifdef __i386__
|
||||
BOOL DiskGetDriveGeometry(U32 DriveNumber, PGEOMETRY DriveGeometry)
|
||||
{
|
||||
// For now just return the geometry as the BIOS reports it
|
||||
// BytesPerSector is always set to 512 by BiosInt13GetDriveParameters()
|
||||
if (!BiosInt13GetDriveParameters(DriveNumber, DriveGeometry))
|
||||
// BytesPerSector is always set to 512 by i386DiskGetDriveParameters()
|
||||
if (!DiskGetDriveParameters(DriveNumber, DriveGeometry))
|
||||
{
|
||||
DiskError("Drive geometry unknown.");
|
||||
DiskError("Drive geometry unknown.", 0);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#else
|
||||
BOOL DiskGetDriveGeometry(U32 DriveNumber, PGEOMETRY DriveGeometry)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -25,51 +25,6 @@
|
|||
#include <arch.h>
|
||||
|
||||
|
||||
|
||||
BOOL DiskIsDriveRemovable(U32 DriveNumber)
|
||||
{
|
||||
// Hard disks use drive numbers >= 0x80
|
||||
// So if the drive number indicates a hard disk
|
||||
// then return FALSE
|
||||
if (DriveNumber >= 0x80)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Drive is a floppy diskette so return TRUE
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL DiskIsDriveCdRom(U32 DriveNumber)
|
||||
{
|
||||
PUCHAR Sector = (PUCHAR)DISKREADBUFFER;
|
||||
|
||||
// Hard disks use drive numbers >= 0x80
|
||||
// So if the drive number indicates a hard disk
|
||||
// then return FALSE
|
||||
if ((DriveNumber >= 0x80) && (IsSetupLdr || BiosInt13ExtensionsSupported(DriveNumber)))
|
||||
{
|
||||
|
||||
if (!BiosInt13ReadExtended(DriveNumber, 16, 1, Sector))
|
||||
{
|
||||
DiskError("Disk read error.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return (Sector[0] == 1 &&
|
||||
Sector[1] == 'C' &&
|
||||
Sector[2] == 'D' &&
|
||||
Sector[3] == '0' &&
|
||||
Sector[4] == '0' &&
|
||||
Sector[5] == '1');
|
||||
}
|
||||
|
||||
// Drive is not CdRom so return FALSE
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
BOOL DiskGetActivePartitionEntry(U32 DriveNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry)
|
||||
{
|
||||
U32 BootablePartitionCount = 0;
|
||||
|
@ -106,12 +61,12 @@ BOOL DiskGetActivePartitionEntry(U32 DriveNumber, PPARTITION_TABLE_ENTRY Partiti
|
|||
// Make sure there was only one bootable partition
|
||||
if (BootablePartitionCount == 0)
|
||||
{
|
||||
DiskError("No bootable (active) partitions found.");
|
||||
DiskError("No bootable (active) partitions found.", 0);
|
||||
return FALSE;
|
||||
}
|
||||
else if (BootablePartitionCount != 1)
|
||||
{
|
||||
DiskError("Too many bootable (active) partitions found.");
|
||||
DiskError("Too many bootable (active) partitions found.", 0);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -235,7 +190,7 @@ BOOL DiskGetFirstExtendedPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PP
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL DiskReadBootRecord(U32 DriveNumber, U32 LogicalSectorNumber, PMASTER_BOOT_RECORD BootRecord)
|
||||
BOOL DiskReadBootRecord(U32 DriveNumber, U64 LogicalSectorNumber, PMASTER_BOOT_RECORD BootRecord)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
U32 Index;
|
||||
|
@ -276,7 +231,7 @@ BOOL DiskReadBootRecord(U32 DriveNumber, U32 LogicalSectorNumber, PMASTER_BOOT_R
|
|||
// Check the partition table magic value
|
||||
if (BootRecord->MasterBootRecordMagic != 0xaa55)
|
||||
{
|
||||
DiskError("Invalid partition table magic (0xaa55)");
|
||||
DiskError("Invalid partition table magic (0xaa55)", 0);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
// DATA
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
U32 FileSystemType = 0; // Type of filesystem on boot device, set by OpenDiskDrive()
|
||||
U32 FileSystemType = 0; // Type of filesystem on boot device, set by FsOpenVolume()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// FUNCTIONS
|
||||
|
@ -48,9 +48,9 @@ VOID FileSystemError(PUCHAR ErrorString)
|
|||
|
||||
/*
|
||||
*
|
||||
* BOOL OpenDiskDrive(U32 DriveNumber, U32 PartitionNumber);
|
||||
* BOOL FsOpenVolume(U32 DriveNumber, U32 PartitionNumber);
|
||||
*
|
||||
* This function is called to open a disk drive for file access.
|
||||
* This function is called to open a disk volume for file access.
|
||||
* It must be called before any of the file functions will work.
|
||||
* It takes two parameters:
|
||||
*
|
||||
|
@ -61,12 +61,12 @@ VOID FileSystemError(PUCHAR ErrorString)
|
|||
* If it is zero then it opens the active (bootable) partition
|
||||
*
|
||||
*/
|
||||
BOOL OpenDiskDrive(U32 DriveNumber, U32 PartitionNumber)
|
||||
BOOL FsOpenVolume(U32 DriveNumber, U32 PartitionNumber)
|
||||
{
|
||||
PARTITION_TABLE_ENTRY PartitionTableEntry;
|
||||
UCHAR ErrorText[80];
|
||||
|
||||
DbgPrint((DPRINT_FILESYSTEM, "OpenDiskDrive() DriveNumber: 0x%x PartitionNumber: 0x%x\n", DriveNumber, PartitionNumber));
|
||||
DbgPrint((DPRINT_FILESYSTEM, "FsOpenVolume() DriveNumber: 0x%x PartitionNumber: 0x%x\n", DriveNumber, PartitionNumber));
|
||||
|
||||
// Check and see if it is a floppy drive
|
||||
// If so then just assume FAT12 file system type
|
||||
|
@ -141,7 +141,7 @@ BOOL OpenDiskDrive(U32 DriveNumber, U32 PartitionNumber)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
PFILE OpenFile(PUCHAR FileName)
|
||||
PFILE FsOpenFile(PUCHAR FileName)
|
||||
{
|
||||
PFILE FileHandle = NULL;
|
||||
|
||||
|
@ -183,18 +183,18 @@ PFILE OpenFile(PUCHAR FileName)
|
|||
//
|
||||
if (FileHandle != NULL)
|
||||
{
|
||||
DbgPrint((DPRINT_FILESYSTEM, "OpenFile() succeeded. FileHandle: 0x%x\n", FileHandle));
|
||||
DbgPrint((DPRINT_FILESYSTEM, "FsOpenFile() succeeded. FileHandle: 0x%x\n", FileHandle));
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgPrint((DPRINT_FILESYSTEM, "OpenFile() failed.\n"));
|
||||
DbgPrint((DPRINT_FILESYSTEM, "FsOpenFile() failed.\n"));
|
||||
}
|
||||
#endif // defined DEBUG
|
||||
|
||||
return FileHandle;
|
||||
}
|
||||
|
||||
VOID CloseFile(PFILE FileHandle)
|
||||
VOID FsCloseFile(PFILE FileHandle)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -202,12 +202,15 @@ VOID CloseFile(PFILE FileHandle)
|
|||
* ReadFile()
|
||||
* returns number of bytes read or EOF
|
||||
*/
|
||||
BOOL ReadFile(PFILE FileHandle, U32 BytesToRead, U32* BytesRead, PVOID Buffer)
|
||||
BOOL FsReadFile(PFILE FileHandle, U32 BytesToRead, U32* BytesRead, PVOID Buffer)
|
||||
{
|
||||
U64 BytesReadBig;
|
||||
BOOL Success;
|
||||
|
||||
//
|
||||
// Set the number of bytes read equal to zero
|
||||
//
|
||||
if (BytesRead !=NULL)
|
||||
if (BytesRead != NULL)
|
||||
{
|
||||
*BytesRead = 0;
|
||||
}
|
||||
|
@ -224,7 +227,10 @@ BOOL ReadFile(PFILE FileHandle, U32 BytesToRead, U32* BytesRead, PVOID Buffer)
|
|||
|
||||
case FS_EXT2:
|
||||
|
||||
return Ext2ReadFile(FileHandle, BytesToRead, BytesRead, Buffer);
|
||||
//return Ext2ReadFile(FileHandle, BytesToRead, BytesRead, Buffer);
|
||||
Success = Ext2ReadFile(FileHandle, BytesToRead, &BytesReadBig, Buffer);
|
||||
*BytesRead = (U32)BytesReadBig;
|
||||
return Success;
|
||||
|
||||
default:
|
||||
|
||||
|
@ -235,7 +241,7 @@ BOOL ReadFile(PFILE FileHandle, U32 BytesToRead, U32* BytesRead, PVOID Buffer)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
U32 GetFileSize(PFILE FileHandle)
|
||||
U32 FsGetFileSize(PFILE FileHandle)
|
||||
{
|
||||
switch (FileSystemType)
|
||||
{
|
||||
|
@ -259,7 +265,7 @@ U32 GetFileSize(PFILE FileHandle)
|
|||
return 0;
|
||||
}
|
||||
|
||||
VOID SetFilePointer(PFILE FileHandle, U32 NewFilePointer)
|
||||
VOID FsSetFilePointer(PFILE FileHandle, U32 NewFilePointer)
|
||||
{
|
||||
switch (FileSystemType)
|
||||
{
|
||||
|
@ -284,7 +290,7 @@ VOID SetFilePointer(PFILE FileHandle, U32 NewFilePointer)
|
|||
}
|
||||
}
|
||||
|
||||
U32 GetFilePointer(PFILE FileHandle)
|
||||
U32 FsGetFilePointer(PFILE FileHandle)
|
||||
{
|
||||
switch (FileSystemType)
|
||||
{
|
||||
|
@ -311,9 +317,9 @@ U32 GetFilePointer(PFILE FileHandle)
|
|||
return 0;
|
||||
}
|
||||
|
||||
BOOL IsEndOfFile(PFILE FileHandle)
|
||||
BOOL FsIsEndOfFile(PFILE FileHandle)
|
||||
{
|
||||
if (GetFilePointer(FileHandle) >= GetFileSize(FileHandle))
|
||||
if (FsGetFilePointer(FileHandle) >= FsGetFileSize(FileHandle))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,10 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef __ARCH_H
|
||||
#define __ARCH_H
|
||||
|
||||
/* Defines needed for switching between real and protected mode */
|
||||
#define NULL_DESC 0x00 /* NULL descriptor */
|
||||
|
@ -36,15 +39,14 @@
|
|||
#define CR0_PE_SET 0x00000001 /* OR this value with CR0 to enable pmode */
|
||||
#define CR0_PE_CLR 0xFFFFFFFE /* AND this value with CR0 to disable pmode */
|
||||
|
||||
#define NR_TASKS 128 /* Space reserved in the GDT for TSS descriptors */
|
||||
|
||||
#define STACK16ADDR 0x7000 /* The 16-bit stack top will be at 0000:7000 */
|
||||
#define STACK32ADDR 0x80000 /* The 32-bit stack top will be at 7000:FFFF, or 0x7FFFF */
|
||||
#define STACK32ADDR 0x78000 /* The 32-bit stack top will be at 7000:8000, or 0x78000 */
|
||||
|
||||
#define MAXLOWMEMADDR 0x78000 /* The highest usuable low memory address for our memory allocator */
|
||||
|
||||
#define FILESYSBUFFER 0x80000 /* Buffer to store file system data (e.g. cluster buffer for FAT) */
|
||||
#define DISKREADBUFFER 0x90000 /* Buffer to store data read in from the disk via the BIOS */
|
||||
#define BIOSCALLBUFFER 0x78000 /* Buffer to store temporary data for any Int386() call */
|
||||
#define BIOSCALLBUFSEGMENT 0x7800 /* Buffer to store temporary data for any Int386() call */
|
||||
#define BIOSCALLBUFOFFSET 0x0000 /* Buffer to store temporary data for any Int386() call */
|
||||
#define FILESYSBUFFER 0x80000 /* Buffer to store file system data (e.g. cluster buffer for FAT) */
|
||||
#define DISKREADBUFFER 0x90000 /* Buffer to store data read in from the disk via the BIOS */
|
||||
|
||||
/* Makes "x" a global variable or label */
|
||||
#define EXTERN(x) .global x; x:
|
||||
|
@ -54,7 +56,111 @@
|
|||
|
||||
#ifndef ASM
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned long eax;
|
||||
unsigned long ebx;
|
||||
unsigned long ecx;
|
||||
unsigned long edx;
|
||||
|
||||
unsigned long esi;
|
||||
unsigned long edi;
|
||||
|
||||
unsigned short ds;
|
||||
unsigned short es;
|
||||
unsigned short fs;
|
||||
unsigned short gs;
|
||||
|
||||
unsigned long eflags;
|
||||
|
||||
} PACKED DWORDREGS;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short ax, _upper_ax;
|
||||
unsigned short bx, _upper_bx;
|
||||
unsigned short cx, _upper_cx;
|
||||
unsigned short dx, _upper_dx;
|
||||
|
||||
unsigned short si, _upper_si;
|
||||
unsigned short di, _upper_di;
|
||||
|
||||
unsigned short ds;
|
||||
unsigned short es;
|
||||
unsigned short fs;
|
||||
unsigned short gs;
|
||||
|
||||
unsigned short flags, _upper_flags;
|
||||
|
||||
} PACKED WORDREGS;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char al;
|
||||
unsigned char ah;
|
||||
unsigned short _upper_ax;
|
||||
unsigned char bl;
|
||||
unsigned char bh;
|
||||
unsigned short _upper_bx;
|
||||
unsigned char cl;
|
||||
unsigned char ch;
|
||||
unsigned short _upper_cx;
|
||||
unsigned char dl;
|
||||
unsigned char dh;
|
||||
unsigned short _upper_dx;
|
||||
|
||||
unsigned short si, _upper_si;
|
||||
unsigned short di, _upper_di;
|
||||
|
||||
unsigned short ds;
|
||||
unsigned short es;
|
||||
unsigned short fs;
|
||||
unsigned short gs;
|
||||
|
||||
unsigned short flags, _upper_flags;
|
||||
|
||||
} PACKED BYTEREGS;
|
||||
|
||||
typedef union
|
||||
{
|
||||
DWORDREGS x;
|
||||
DWORDREGS d;
|
||||
WORDREGS w;
|
||||
BYTEREGS b;
|
||||
} REGS;
|
||||
|
||||
// Int386()
|
||||
//
|
||||
// Real mode interrupt vector interface
|
||||
//
|
||||
// (E)FLAGS can *only* be returned by this function, not set.
|
||||
// Make sure all memory pointers are in SEG:OFFS format and
|
||||
// not linear addresses, unless the interrupt handler
|
||||
// specifically handles linear addresses.
|
||||
int Int386(int ivec, REGS* in, REGS* out);
|
||||
|
||||
// Flag Masks
|
||||
#define I386FLAG_CF 0x0001 // Carry Flag
|
||||
#define I386FLAG_RESV1 0x0002 // Reserved - Must be 1
|
||||
#define I386FLAG_PF 0x0004 // Parity Flag
|
||||
#define I386FLAG_RESV2 0x0008 // Reserved - Must be 0
|
||||
#define I386FLAG_AF 0x0010 // Auxiliary Flag
|
||||
#define I386FLAG_RESV3 0x0020 // Reserved - Must be 0
|
||||
#define I386FLAG_ZF 0x0040 // Zero Flag
|
||||
#define I386FLAG_SF 0x0080 // Sign Flag
|
||||
#define I386FLAG_TF 0x0100 // Trap Flag (Single Step)
|
||||
#define I386FLAG_IF 0x0200 // Interrupt Flag
|
||||
#define I386FLAG_DF 0x0400 // Direction Flag
|
||||
#define I386FLAG_OF 0x0800 // Overflow Flag
|
||||
|
||||
// This macro tests the Carry Flag
|
||||
// If CF is set then the call failed (usually)
|
||||
#define INT386_SUCCESS(regs) ((regs.x.eflags & I386FLAG_CF) == 0)
|
||||
|
||||
void EnableA20(void);
|
||||
void StopFloppyMotor(void);
|
||||
|
||||
#endif /* ! ASM */
|
||||
|
||||
|
||||
#endif // #defined __ARCH_H
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
#ifdef DEBUG
|
||||
|
||||
#define DPRINT_NONE 0x00000000 // Simple debug print
|
||||
#define DPRINT_NONE 0x00000000 // No debug print
|
||||
#define DPRINT_WARNING 0x00000001 // OR this with DebugPrintMask to enable debugger messages and other misc stuff
|
||||
#define DPRINT_MEMORY 0x00000002 // OR this with DebugPrintMask to enable memory management messages
|
||||
#define DPRINT_FILESYSTEM 0x00000004 // OR this with DebugPrintMask to enable file system messages
|
||||
|
@ -39,8 +39,8 @@
|
|||
VOID DebugPrint(U32 Mask, char *format, ...);
|
||||
VOID DebugDumpBuffer(U32 Mask, PVOID Buffer, U32 Length);
|
||||
|
||||
#define DbgPrint(_x_) { DebugPrint(DPRINT_NONE, "%s:%d(%s)\n", __FILE__, __LINE__, __FUNCTION__); DebugPrint _x_ ; }
|
||||
#define BugCheck(_x_) { DebugPrint(DPRINT_WARNING, "Fatal Error: %s:%d(%s)\n", __FILE__, __LINE__, __FUNCTION__); DebugPrint _x_ ; for (;;); }
|
||||
#define DbgPrint(_x_) DebugPrint _x_ ;
|
||||
#define BugCheck(_x_) { DebugPrint(DPRINT_WARNING, "Fatal Error: %s:%d(%s)\n", __FILE__, __LINE__, __FUNCTION__); DebugPrint _x_ ; for (;;); }
|
||||
#define DbgDumpBuffer(_x_, _y_, _z_) DebugDumpBuffer(_x_, _y_, _z_)
|
||||
|
||||
#ifdef __i386__
|
||||
|
@ -78,6 +78,6 @@ void MEMORY_WRITE_BREAKPOINT4(unsigned long addr);
|
|||
|
||||
#endif // defined DEBUG
|
||||
|
||||
#define UNIMPLEMENTED BugCheck((DPRINT_WARNING, "Unimplemented\n"));
|
||||
#define UNIMPLEMENTED() BugCheck((DPRINT_WARNING, "This function is unimplemented!\n"))
|
||||
|
||||
#endif // defined __DEBUG_H
|
||||
|
|
|
@ -23,10 +23,10 @@
|
|||
|
||||
typedef struct _GEOMETRY
|
||||
{
|
||||
U32 Cylinders;
|
||||
U32 Heads;
|
||||
U32 Sectors;
|
||||
U32 BytesPerSector;
|
||||
U32 Cylinders; // Number of cylinders on the disk
|
||||
U32 Heads; // Number of heads on the disk
|
||||
U32 Sectors; // Number of sectors per track
|
||||
U32 BytesPerSector; // Number of bytes per sector
|
||||
|
||||
} GEOMETRY, *PGEOMETRY;
|
||||
|
||||
|
@ -83,42 +83,44 @@ typedef struct _MASTER_BOOT_RECORD
|
|||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// BIOS Disk Functions
|
||||
// i386 BIOS Disk Functions (i386disk.c)
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
int biosdisk(int cmd, int drive, int head, int track, int sector, int nsects, void *buffer); // Implemented in asmcode.S
|
||||
#ifdef __i386__
|
||||
|
||||
BOOL BiosInt13Read(U32 Drive, U32 Head, U32 Track, U32 Sector, U32 SectorCount, PVOID Buffer); // Implemented in asmcode.S
|
||||
BOOL BiosInt13ReadExtended(U32 Drive, U32 Sector, U32 SectorCount, PVOID Buffer); // Implemented in asmcode.S
|
||||
BOOL BiosInt13ExtensionsSupported(U32 Drive);
|
||||
U32 BiosInt13GetLastErrorCode(VOID);
|
||||
//BOOL DiskReadLogicalSectors(U32 DriveNumber, U64 SectorNumber, U32 SectorCount, PVOID Buffer);
|
||||
BOOL DiskReadLogicalSectorsLBA(U32 DriveNumber, U64 SectorNumber, U32 SectorCount, PVOID Buffer);
|
||||
BOOL DiskReadLogicalSectorsCHS(U32 DriveNumber, U64 SectorNumber, U32 SectorCount, PVOID Buffer);
|
||||
BOOL DiskResetController(U32 DriveNumber);
|
||||
BOOL DiskInt13ExtensionsSupported(U32 DriveNumber);
|
||||
//VOID DiskStopFloppyMotor(VOID);
|
||||
BOOL DiskGetDriveParameters(U32 DriveNumber, PGEOMETRY Geometry);
|
||||
//U32 DiskGetCacheableBlockCount(U32 DriveNumber);
|
||||
|
||||
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
|
||||
BOOL BiosInt13GetDriveParameters(U32 Drive, PGEOMETRY Geometry); // Implemented in disk.S
|
||||
#endif // defined __i386__
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// FreeLoader Disk Functions
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
VOID DiskError(PUCHAR ErrorString);
|
||||
VOID DiskError(PUCHAR ErrorString, U32 ErrorCode);
|
||||
BOOL DiskGetDriveGeometry(U32 DriveNumber, PGEOMETRY DriveGeometry);
|
||||
BOOL DiskReadLogicalSectors(U32 DriveNumber, U32 SectorNumber, U32 SectorCount, PVOID Buffer);
|
||||
BOOL DiskReadLogicalSectors(U32 DriveNumber, U64 SectorNumber, U32 SectorCount, PVOID Buffer); // Implemented in i386disk.c
|
||||
BOOL DiskIsDriveRemovable(U32 DriveNumber);
|
||||
BOOL DiskIsDriveCdRom(U32 DriveNumber);
|
||||
VOID DiskStopFloppyMotor(VOID); // Implemented in i386disk.c
|
||||
U32 DiskGetCacheableBlockCount(U32 DriveNumber); // Implemented in i386disk.c
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Fixed Disk Partition Management Functions
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
BOOL DiskIsDriveRemovable(U32 DriveNumber);
|
||||
BOOL DiskIsDriveCdRom(U32 DriveNumber);
|
||||
BOOL DiskGetActivePartitionEntry(U32 DriveNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry);
|
||||
BOOL DiskGetPartitionEntry(U32 DriveNumber, U32 PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry);
|
||||
BOOL DiskGetFirstPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry);
|
||||
BOOL DiskGetFirstExtendedPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry);
|
||||
BOOL DiskReadBootRecord(U32 DriveNumber, U32 LogicalSectorNumber, PMASTER_BOOT_RECORD BootRecord);
|
||||
BOOL DiskReadBootRecord(U32 DriveNumber, U64 LogicalSectorNumber, PMASTER_BOOT_RECORD BootRecord);
|
||||
|
||||
#endif // defined __DISK_H
|
||||
|
|
|
@ -33,14 +33,14 @@
|
|||
#define PFILE FILE *
|
||||
|
||||
VOID FileSystemError(PUCHAR ErrorString);
|
||||
BOOL OpenDiskDrive(U32 DriveNumber, U32 PartitionNumber);
|
||||
PFILE OpenFile(PUCHAR FileName);
|
||||
VOID CloseFile(PFILE FileHandle);
|
||||
BOOL ReadFile(PFILE FileHandle, U32 BytesToRead, U32* BytesRead, PVOID Buffer);
|
||||
U32 GetFileSize(PFILE FileHandle);
|
||||
VOID SetFilePointer(PFILE FileHandle, U32 NewFilePointer);
|
||||
U32 GetFilePointer(PFILE FileHandle);
|
||||
BOOL IsEndOfFile(PFILE FileHandle);
|
||||
BOOL FsOpenVolume(U32 DriveNumber, U32 PartitionNumber);
|
||||
PFILE FsOpenFile(PUCHAR FileName);
|
||||
VOID FsCloseFile(PFILE FileHandle);
|
||||
BOOL FsReadFile(PFILE FileHandle, U32 BytesToRead, U32* BytesRead, PVOID Buffer);
|
||||
U32 FsGetFileSize(PFILE FileHandle);
|
||||
VOID FsSetFilePointer(PFILE FileHandle, U32 NewFilePointer);
|
||||
U32 FsGetFilePointer(PFILE FileHandle);
|
||||
BOOL FsIsEndOfFile(PFILE FileHandle);
|
||||
U32 FsGetNumPathParts(PUCHAR Path);
|
||||
VOID FsGetFirstNameFromPath(PUCHAR Buffer, PUCHAR Path);
|
||||
|
||||
|
|
|
@ -127,6 +127,6 @@ BOOL LinuxReadBootSector(PFILE LinuxKernelFile);
|
|||
BOOL LinuxReadSetupSector(PFILE LinuxKernelFile);
|
||||
BOOL LinuxReadKernel(PFILE LinuxKernelFile);
|
||||
BOOL LinuxCheckKernelVersion(VOID);
|
||||
BOOL LinuxReadInitrd(VOID);
|
||||
BOOL LinuxReadInitrd(PFILE LinuxInitrdFile);
|
||||
|
||||
#endif // defined __LINUX_H
|
||||
|
|
|
@ -35,18 +35,13 @@ typedef struct
|
|||
U32 Reserved;
|
||||
} PACKED BIOS_MEMORY_MAP, *PBIOS_MEMORY_MAP;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BIOS_MEMORY_MAP BiosMemoryMapArray[32];
|
||||
} PACKED BIOS_MEMORY_MAP_ARRAY, *PBIOS_MEMORY_MAP_ARRAY;
|
||||
|
||||
|
||||
U32 GetSystemMemorySize(VOID); // Returns the amount of total memory in the system
|
||||
|
||||
// These functions are implemented in mem.S
|
||||
U32 GetExtendedMemorySize(VOID); // Returns extended memory size in KB
|
||||
U32 GetConventionalMemorySize(VOID); // Returns conventional memory size in KB
|
||||
U32 GetBiosMemoryMap(PBIOS_MEMORY_MAP_ARRAY BiosMemoryMap); // Fills structure with BIOS memory map and returns memory map item count
|
||||
U32 GetBiosMemoryMap(BIOS_MEMORY_MAP BiosMemoryMap[32]); // Fills structure with BIOS memory map and returns memory map item count
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -44,14 +44,14 @@ int strnicmp(const char *string1, const char *string2, size_t length);
|
|||
// Memory Functions
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
int RtlCompareMemory(const PVOID Source1, const PVOID Source2, U32 Length);
|
||||
VOID RtlCopyMemory(PVOID Destination, const PVOID Source, U32 Length);
|
||||
VOID RtlFillMemory(PVOID Destination, U32 Length, UCHAR Fill);
|
||||
VOID RtlZeroMemory(PVOID Destination, U32 Length);
|
||||
int memcmp(const void *buf1, const void *buf2, size_t count);
|
||||
void * memcpy(void *to, const void *from, size_t count);
|
||||
void * memset(void *src, int val, size_t count);
|
||||
|
||||
#define memcmp(buf1, buf2, count) RtlCompareMemory(buf1, buf2, count)
|
||||
#define memcpy(dest, src, count) RtlCopyMemory(dest, src,count)
|
||||
#define memset(dest, c, count) RtlFillMemory(dest,count, c)
|
||||
#define RtlCompareMemory(Source1, Source2, Length) memcmp(Source1, Source2, Length)
|
||||
#define RtlCopyMemory(Destination, Source, Length) memcpy(Destination, Source, Length)
|
||||
#define RtlFillMemory(Destination, Length, Fill) memset(Destination, Fill, Length)
|
||||
#define RtlZeroMemory(Destination, Length) memset(Destination, 0, Length)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
|
|
@ -44,6 +44,8 @@ extern PUCHAR UiMessageBoxLineText;
|
|||
|
||||
extern BOOL UserInterfaceUp; // Tells us if the user interface is displayed
|
||||
|
||||
extern BOOL UiUseSpecialEffects; // Tells us if we should use fade effects
|
||||
|
||||
extern UCHAR UiMonthNames[12][15];
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -52,6 +54,7 @@ extern UCHAR UiMonthNames[12][15];
|
|||
//
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
BOOL UiInitialize(VOID); // Initialize User-Interface
|
||||
VOID UiUnInitialize(PUCHAR BootText); // Un-initialize User-Interface
|
||||
VOID UiDrawBackdrop(VOID); // Fills the entire screen with a backdrop
|
||||
VOID UiFillArea(U32 Left, U32 Top, U32 Right, U32 Bottom, UCHAR FillChar, UCHAR Attr /* Color Attributes */); // Fills the area specified with FillChar and Attr
|
||||
VOID UiDrawShadow(U32 Left, U32 Top, U32 Right, U32 Bottom); // Draws a shadow on the bottom and right sides of the area specified
|
||||
|
@ -60,6 +63,7 @@ VOID UiDrawText(U32 X, U32 Y, PUCHAR Text, UCHAR Attr); // Draws text at coordin
|
|||
VOID UiDrawCenteredText(U32 Left, U32 Top, U32 Right, U32 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 UiInfoBox(PUCHAR MessageText); // Displays a info box on the screen
|
||||
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
|
||||
|
@ -72,6 +76,9 @@ UCHAR UiTextToFillStyle(PUCHAR FillStyleText); // Converts the text fill into
|
|||
|
||||
VOID UiTruncateStringEllipsis(PUCHAR StringText, U32 MaxChars); // Truncates a string to MaxChars by adding an ellipsis on the end '...'
|
||||
|
||||
VOID UiFadeInBackdrop(VOID); // Draws the backdrop and fades the screen in
|
||||
VOID UiFadeOut(VOID); // Fades the screen out
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Menu Functions
|
||||
|
|
|
@ -21,10 +21,18 @@
|
|||
#define __VIDEO_H
|
||||
|
||||
|
||||
|
||||
#define VIDEOCARD_CGA_OR_OTHER 0
|
||||
#define VIDEOCARD_EGA 1
|
||||
#define VIDEOCARD_VGA 2
|
||||
|
||||
#define VERTRES_200_SCANLINES 0x00
|
||||
#define VERTRES_350_SCANLINES 0x01
|
||||
#define VERTRES_400_SCANLINES 0x02
|
||||
|
||||
#define MODETYPE_TEXT 0
|
||||
#define MODETYPE_GRAPHICS 1
|
||||
|
||||
#define VIDEOMODE_NORMAL_TEXT 0
|
||||
#define VIDEOMODE_EXTENDED_TEXT 1
|
||||
#define VIDEOMODE_80X28 0x501C
|
||||
|
@ -32,32 +40,114 @@
|
|||
#define VIDEOMODE_80X34 0x5022
|
||||
#define VIDEOMODE_80X43 0x502B
|
||||
#define VIDEOMODE_80X60 0x503C
|
||||
#define VIDEOMODE_132X25 0x8419
|
||||
#define VIDEOMODE_132X43 0x842B
|
||||
#define VIDEOMODE_132X50 0x8432
|
||||
#define VIDEOMODE_132X60 0x843C
|
||||
|
||||
#define VIDEOPORT_PALETTE_READ 0x03C7
|
||||
#define VIDEOPORT_PALETTE_WRITE 0x03C8
|
||||
#define VIDEOPORT_PALETTE_DATA 0x03C9
|
||||
#define VIDEOPORT_VERTICAL_RETRACE 0x03DA
|
||||
|
||||
VOID BiosSetVideoMode(U32 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(U32 StartScanLine, U32 EndScanLine); // Implemented in biosvid.S
|
||||
U32 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 BiosVideoDisableBlinkBit(VOID); // Implemented in biosvid.S
|
||||
#define VIDEOVGA_MEM_ADDRESS 0xA0000
|
||||
#define VIDEOTEXT_MEM_ADDRESS 0xB8000
|
||||
|
||||
VOID VideoSetTextCursorPosition(U32 X, U32 Y); // Implemented in biosvid.S
|
||||
VOID VideoHideTextCursor(VOID); // Implemented in biosvid.S
|
||||
VOID VideoShowTextCursor(VOID); // Implemented in biosvid.S
|
||||
U32 VideoGetTextCursorPositionX(VOID); // Implemented in biosvid.S
|
||||
U32 VideoGetTextCursorPositionY(VOID); // Implemented in biosvid.S
|
||||
typedef struct
|
||||
{
|
||||
U8 Red;
|
||||
U8 Green;
|
||||
U8 Blue;
|
||||
} PACKED PALETTE_ENTRY, *PPALETTE_ENTRY;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
U16 ModeAttributes; // mode attributes (see #00080)
|
||||
U8 WindowAttributesA; // window attributes, window A (see #00081)
|
||||
U8 WindowsAttributesB; // window attributes, window B (see #00081)
|
||||
U16 WindowGranularity; // window granularity in KB
|
||||
U16 WindowSize; // window size in KB
|
||||
U16 WindowAStartSegment; // start segment of window A (0000h if not supported)
|
||||
U16 WindowBStartSegment; // start segment of window B (0000h if not supported)
|
||||
U32 WindowPositioningFunction; // -> FAR window positioning function (equivalent to AX=4F05h)
|
||||
U16 BytesPerScanLine; // bytes per scan line
|
||||
//---remainder is optional for VESA modes in v1.0/1.1, needed for OEM modes---
|
||||
U16 WidthInPixels; // width in pixels (graphics) or characters (text)
|
||||
U16 HeightInPixels; // height in pixels (graphics) or characters (text)
|
||||
U8 CharacterWidthInPixels; // width of character cell in pixels
|
||||
U8 CharacterHeightInPixels; // height of character cell in pixels
|
||||
U8 NumberOfMemoryPlanes; // number of memory planes
|
||||
U8 BitsPerPixel; // number of bits per pixel
|
||||
U8 NumberOfBanks; // number of banks
|
||||
U8 MemoryModel; // memory model type (see #00082)
|
||||
U8 BankSize; // size of bank in KB
|
||||
U8 NumberOfImagePanes; // number of image pages (less one) that will fit in video RAM
|
||||
U8 Reserved1; // reserved (00h for VBE 1.0-2.0, 01h for VBE 3.0)
|
||||
//---VBE v1.2+ ---
|
||||
U8 RedMaskSize; // red mask size
|
||||
U8 RedMaskPosition; // red field position
|
||||
U8 GreenMaskSize; // green mask size
|
||||
U8 GreenMaskPosition; // green field size
|
||||
U8 BlueMaskSize; // blue mask size
|
||||
U8 BlueMaskPosition; // blue field size
|
||||
U8 ReservedMaskSize; // reserved mask size
|
||||
U8 ReservedMaskPosition; // reserved mask position
|
||||
U8 DirectColorModeInfo; // direct color mode info
|
||||
// bit 0:Color ramp is programmable
|
||||
// bit 1:Bytes in reserved field may be used by application
|
||||
//---VBE v2.0+ ---
|
||||
U32 LinearVideoBufferAddress; // physical address of linear video buffer
|
||||
U32 OffscreenMemoryPointer; // pointer to start of offscreen memory
|
||||
U16 OffscreenMemorySize; // KB of offscreen memory
|
||||
//---VBE v3.0 ---
|
||||
U16 LinearBytesPerScanLine; // bytes per scan line in linear modes
|
||||
U8 BankedNumberOfImages; // number of images (less one) for banked video modes
|
||||
U8 LinearNumberOfImages; // number of images (less one) for linear video modes
|
||||
U8 LinearRedMaskSize; // linear modes:Size of direct color red mask (in bits)
|
||||
U8 LinearRedMaskPosition; // linear modes:Bit position of red mask LSB (e.g. shift count)
|
||||
U8 LinearGreenMaskSize; // linear modes:Size of direct color green mask (in bits)
|
||||
U8 LinearGreenMaskPosition; // linear modes:Bit position of green mask LSB (e.g. shift count)
|
||||
U8 LinearBlueMaskSize; // linear modes:Size of direct color blue mask (in bits)
|
||||
U8 LinearBlueMaskPosition; // linear modes:Bit position of blue mask LSB (e.g. shift count)
|
||||
U8 LinearReservedMaskSize; // linear modes:Size of direct color reserved mask (in bits)
|
||||
U8 LinearReservedMaskPosition; // linear modes:Bit position of reserved mask LSB
|
||||
U32 MaximumPixelClock; // maximum pixel clock for graphics video mode, in Hz
|
||||
U8 Reserved2[190]; // 190 BYTEs reserved (0)
|
||||
} PACKED SVGA_MODE_INFORMATION, *PSVGA_MODE_INFORMATION;
|
||||
|
||||
|
||||
extern U32 CurrentMemoryBank;
|
||||
extern SVGA_MODE_INFORMATION VesaVideoModeInformation;
|
||||
|
||||
extern PVOID VideoOffScreenBuffer;
|
||||
|
||||
|
||||
|
||||
|
||||
VOID BiosSetVideoMode(U32 VideoMode); // Implemented in i386vid.S
|
||||
VOID BiosSetVideoFont8x8(VOID); // Implemented in i386vid.S
|
||||
VOID BiosSetVideoFont8x14(VOID); // Implemented in i386vid.S
|
||||
VOID BiosSetVideoFont8x16(VOID); // Implemented in i386vid.S
|
||||
VOID BiosSelectAlternatePrintScreen(VOID); // Implemented in i386vid.S
|
||||
VOID BiosDisableCursorEmulation(VOID); // Implemented in i386vid.S
|
||||
VOID BiosDefineCursor(U32 StartScanLine, U32 EndScanLine); // Implemented in i386vid.S
|
||||
U32 BiosDetectVideoCard(VOID); // Implemented in i386vid.S
|
||||
VOID BiosSetVerticalResolution(U32 ScanLines); // Implemented in i386vid.S, must be called right before BiosSetVideoMode()
|
||||
VOID BiosSet480ScanLines(VOID); // Implemented in i386vid.S, must be called right after BiosSetVideoMode()
|
||||
VOID BiosSetVideoDisplayEnd(VOID); // Implemented in i386vid.S
|
||||
VOID BiosVideoDisableBlinkBit(VOID); // Implemented in i386vid.S
|
||||
VOID BiosVideoEnableBlinkBit(VOID); // Implemented in i386vid.S
|
||||
|
||||
U16 BiosIsVesaSupported(VOID); // Implemented in i386vid.S, returns the VESA version
|
||||
BOOL BiosVesaSetBank(U16 Bank); // Implemented in i386vid.S
|
||||
BOOL BiosVesaSetVideoMode(U16 Mode); // Implemented in i386vid.S
|
||||
BOOL BiosVesaGetSVGAModeInformation(U16 Mode, PSVGA_MODE_INFORMATION ModeInformation); // Implemented in i386vid.S
|
||||
|
||||
VOID VideoSetTextCursorPosition(U32 X, U32 Y); // Implemented in i386vid.S
|
||||
VOID VideoHideTextCursor(VOID); // Implemented in i386vid.S
|
||||
VOID VideoShowTextCursor(VOID); // Implemented in i386vid.S
|
||||
U32 VideoGetTextCursorPositionX(VOID); // Implemented in i386vid.S
|
||||
U32 VideoGetTextCursorPositionY(VOID); // Implemented in i386vid.S
|
||||
|
||||
BOOL VideoSetMode(U32 VideoMode);
|
||||
BOOL VideoSetMode80x25(VOID); // Sets 80x25
|
||||
|
@ -69,12 +159,39 @@ BOOL VideoSetMode80x34(VOID); // Sets 80x34. Works on all VGA's. 480 scanli
|
|||
BOOL VideoSetMode80x60(VOID); // Sets 80x60. Works on all VGA's. 480 scanlines, 8-pixel font.
|
||||
U32 VideoGetCurrentModeResolutionX(VOID);
|
||||
U32 VideoGetCurrentModeResolutionY(VOID);
|
||||
U32 VideoGetBytesPerScanLine(VOID);
|
||||
U32 VideoGetCurrentMode(VOID);
|
||||
U32 VideoGetCurrentModeType(VOID); // MODETYPE_TEXT or MODETYPE_GRAPHICS
|
||||
BOOL VideoIsCurrentModeVesa(VOID);
|
||||
U32 VideoGetCurrentModeColorDepth(VOID); // Returns 0 for text mode, 16 for 4-bit, 256 for 8-bit, 32768 for 15-bit, 65536 for 16-bit, etc.
|
||||
|
||||
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);
|
||||
PVOID VideoAllocateOffScreenBuffer(VOID); // Returns a pointer to an off-screen buffer sufficient for the current video mode
|
||||
|
||||
U32 VideoGetMemoryBankForPixel(U32 X, U32 Y);
|
||||
U32 VideoGetMemoryBankForPixel16(U32 X, U32 Y);
|
||||
U32 VideoGetBankOffsetForPixel(U32 X, U32 Y);
|
||||
U32 VideoGetBankOffsetForPixel16(U32 X, U32 Y);
|
||||
VOID VideoSetMemoryBank(U16 BankNumber);
|
||||
U32 VideoGetOffScreenMemoryOffsetForPixel(U32 X, U32 Y);
|
||||
VOID VideoCopyOffScreenBufferToVRAM(VOID);
|
||||
|
||||
VOID VideoSetPaletteColor(U8 Color, U8 Red, U8 Green, U8 Blue);
|
||||
VOID VideoGetPaletteColor(U8 Color, U8* Red, U8* Green, U8* Blue);
|
||||
VOID VideoSavePaletteState(PPALETTE_ENTRY Palette, U32 ColorCount);
|
||||
VOID VideoRestorePaletteState(PPALETTE_ENTRY Palette, U32 ColorCount);
|
||||
|
||||
VOID VideoSetPixel16(U32 X, U32 Y, U8 Color);
|
||||
VOID VideoSetPixel256(U32 X, U32 Y, U8 Color);
|
||||
VOID VideoSetPixelRGB(U32 X, U32 Y, U8 Red, U8 Green, U8 Blue);
|
||||
VOID VideoSetPixel16_OffScreen(U32 X, U32 Y, U8 Color);
|
||||
VOID VideoSetPixel256_OffScreen(U32 X, U32 Y, U8 Color);
|
||||
VOID VideoSetPixelRGB_OffScreen(U32 X, U32 Y, U8 Red, U8 Green, U8 Blue);
|
||||
|
||||
VOID VideoSetAllColorsToBlack(U32 ColorCount);
|
||||
VOID VideoFadeIn(PPALETTE_ENTRY Palette, U32 ColorCount);
|
||||
VOID VideoFadeOut(U32 ColorCount);
|
||||
|
||||
|
||||
#endif // defined __VIDEO_H
|
||||
|
|
|
@ -58,26 +58,26 @@ BOOL IniFileInitialize(VOID)
|
|||
}
|
||||
|
||||
// Get the file size & allocate enough memory for it
|
||||
FreeLoaderIniFileSize = GetFileSize(Freeldr_Ini);
|
||||
FreeLoaderIniFileSize = FsGetFileSize(Freeldr_Ini);
|
||||
FreeLoaderIniFileData = MmAllocateMemory(FreeLoaderIniFileSize);
|
||||
|
||||
// If we are out of memory then return FALSE
|
||||
if (FreeLoaderIniFileData == NULL)
|
||||
{
|
||||
printf("Out of memory while loading freeldr.ini.\n");
|
||||
CloseFile(Freeldr_Ini);
|
||||
FsCloseFile(Freeldr_Ini);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Read freeldr.ini off the disk
|
||||
if (!ReadFile(Freeldr_Ini, FreeLoaderIniFileSize, NULL, FreeLoaderIniFileData))
|
||||
if (!FsReadFile(Freeldr_Ini, FreeLoaderIniFileSize, NULL, FreeLoaderIniFileData))
|
||||
{
|
||||
CloseFile(Freeldr_Ini);
|
||||
FsCloseFile(Freeldr_Ini);
|
||||
MmFreeMemory(FreeLoaderIniFileData);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CloseFile(Freeldr_Ini);
|
||||
FsCloseFile(Freeldr_Ini);
|
||||
|
||||
// Parse the .ini file data
|
||||
Success = IniParseFile(FreeLoaderIniFileData, FreeLoaderIniFileSize);
|
||||
|
@ -91,7 +91,7 @@ PFILE IniOpenIniFile(U8 BootDriveNumber, U8 BootPartitionNumber)
|
|||
{
|
||||
PFILE IniFileHandle; // File handle for freeldr.ini
|
||||
|
||||
if (!OpenDiskDrive(BootDriveNumber, BootPartitionNumber))
|
||||
if (!FsOpenVolume(BootDriveNumber, BootPartitionNumber))
|
||||
{
|
||||
if (BootPartitionNumber == 0)
|
||||
{
|
||||
|
@ -106,7 +106,7 @@ PFILE IniOpenIniFile(U8 BootDriveNumber, U8 BootPartitionNumber)
|
|||
}
|
||||
|
||||
// Try to open freeldr.ini
|
||||
IniFileHandle = OpenFile("freeldr.ini");
|
||||
IniFileHandle = FsOpenFile("freeldr.ini");
|
||||
|
||||
return IniFileHandle;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include <freeldr.h>
|
||||
#include <arch.h>
|
||||
#include <disk.h>
|
||||
#include <miscboot.h>
|
||||
#include <rtl.h>
|
||||
#include <fs.h>
|
||||
|
@ -31,11 +32,17 @@
|
|||
#include <oslist.h> // For RemoveQuotes()
|
||||
#include <video.h>
|
||||
|
||||
|
||||
|
||||
#define LINUX_READ_CHUNK_SIZE 0x20000 // Read 128k at a time
|
||||
|
||||
|
||||
PLINUX_BOOTSECTOR LinuxBootSector = NULL;
|
||||
PLINUX_SETUPSECTOR LinuxSetupSector = NULL;
|
||||
U32 SetupSectorSize = 0;
|
||||
BOOL NewStyleLinuxKernel = FALSE;
|
||||
U32 LinuxKernelSize = 0;
|
||||
U32 LinuxInitrdSize = 0;
|
||||
UCHAR LinuxKernelName[260];
|
||||
UCHAR LinuxInitrdName[260];
|
||||
BOOL LinuxHasInitrd = FALSE;
|
||||
|
@ -47,10 +54,14 @@ PVOID LinuxInitrdLoadAddress = NULL;
|
|||
VOID LoadAndBootLinux(PUCHAR OperatingSystemName)
|
||||
{
|
||||
PFILE LinuxKernel = NULL;
|
||||
PFILE LinuxInitrdFile = NULL;
|
||||
UCHAR TempString[260];
|
||||
|
||||
UiDrawBackdrop();
|
||||
|
||||
UiDrawStatusText("Loading Linux...");
|
||||
UiDrawProgressBarCenter(0, 100);
|
||||
|
||||
// Parse the .ini file section
|
||||
if (!LinuxParseIniSection(OperatingSystemName))
|
||||
{
|
||||
|
@ -58,14 +69,14 @@ VOID LoadAndBootLinux(PUCHAR OperatingSystemName)
|
|||
}
|
||||
|
||||
// Open the boot volume
|
||||
if (!OpenDiskDrive(BootDrive, BootPartition))
|
||||
if (!FsOpenVolume(BootDrive, BootPartition))
|
||||
{
|
||||
UiMessageBox("Failed to open boot drive.");
|
||||
goto LinuxBootFailed;
|
||||
}
|
||||
|
||||
// Open the kernel
|
||||
LinuxKernel = OpenFile(LinuxKernelName);
|
||||
LinuxKernel = FsOpenFile(LinuxKernelName);
|
||||
if (LinuxKernel == NULL)
|
||||
{
|
||||
sprintf(TempString, "Linux kernel \'%s\' not found.", LinuxKernelName);
|
||||
|
@ -73,6 +84,18 @@ VOID LoadAndBootLinux(PUCHAR OperatingSystemName)
|
|||
goto LinuxBootFailed;
|
||||
}
|
||||
|
||||
// Open the initrd file image (if necessary)
|
||||
if (LinuxHasInitrd)
|
||||
{
|
||||
LinuxInitrdFile = FsOpenFile(LinuxInitrdName);
|
||||
if (LinuxInitrdFile == NULL)
|
||||
{
|
||||
sprintf(TempString, "Linux initrd image \'%s\' not found.", LinuxInitrdName);
|
||||
UiMessageBox(TempString);
|
||||
goto LinuxBootFailed;
|
||||
}
|
||||
}
|
||||
|
||||
// Read the boot sector
|
||||
if (!LinuxReadBootSector(LinuxKernel))
|
||||
{
|
||||
|
@ -85,6 +108,12 @@ VOID LoadAndBootLinux(PUCHAR OperatingSystemName)
|
|||
goto LinuxBootFailed;
|
||||
}
|
||||
|
||||
// Calc kernel size
|
||||
LinuxKernelSize = FsGetFileSize(LinuxKernel) - (512 + SetupSectorSize);
|
||||
|
||||
// Get the file size
|
||||
LinuxInitrdSize = FsGetFileSize(LinuxInitrdFile);
|
||||
|
||||
// Read the kernel
|
||||
if (!LinuxReadKernel(LinuxKernel))
|
||||
{
|
||||
|
@ -94,7 +123,7 @@ VOID LoadAndBootLinux(PUCHAR OperatingSystemName)
|
|||
// Read the initrd (if necessary)
|
||||
if (LinuxHasInitrd)
|
||||
{
|
||||
if (!LinuxReadInitrd())
|
||||
if (!LinuxReadInitrd(LinuxInitrdFile))
|
||||
{
|
||||
goto LinuxBootFailed;
|
||||
}
|
||||
|
@ -122,10 +151,9 @@ VOID LoadAndBootLinux(PUCHAR OperatingSystemName)
|
|||
RtlCopyMemory((PVOID)0x90200, LinuxSetupSector, SetupSectorSize);
|
||||
RtlCopyMemory((PVOID)0x99000, LinuxCommandLine, LinuxCommandLineSize);
|
||||
|
||||
VideoShowTextCursor();
|
||||
VideoClearScreen();
|
||||
UiUnInitialize("Booting Linux...");
|
||||
|
||||
StopFloppyMotor();
|
||||
DiskStopFloppyMotor();
|
||||
|
||||
if (LinuxSetupSector->LoadFlags & LINUX_FLAG_LOAD_HIGH)
|
||||
{
|
||||
|
@ -141,7 +169,11 @@ LinuxBootFailed:
|
|||
|
||||
if (LinuxKernel != NULL)
|
||||
{
|
||||
CloseFile(LinuxKernel);
|
||||
FsCloseFile(LinuxKernel);
|
||||
}
|
||||
if (LinuxInitrdFile != NULL)
|
||||
{
|
||||
FsCloseFile(LinuxInitrdFile);
|
||||
}
|
||||
|
||||
if (LinuxBootSector != NULL)
|
||||
|
@ -237,8 +269,8 @@ BOOL LinuxReadBootSector(PFILE LinuxKernelFile)
|
|||
}
|
||||
|
||||
// Read linux boot sector
|
||||
SetFilePointer(LinuxKernelFile, 0);
|
||||
if (!ReadFile(LinuxKernelFile, 512, NULL, LinuxBootSector))
|
||||
FsSetFilePointer(LinuxKernelFile, 0);
|
||||
if (!FsReadFile(LinuxKernelFile, 512, NULL, LinuxBootSector))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -271,8 +303,8 @@ BOOL LinuxReadSetupSector(PFILE LinuxKernelFile)
|
|||
LinuxSetupSector = (PLINUX_SETUPSECTOR)TempLinuxSetupSector;
|
||||
|
||||
// Read first linux setup sector
|
||||
SetFilePointer(LinuxKernelFile, 512);
|
||||
if (!ReadFile(LinuxKernelFile, 512, NULL, TempLinuxSetupSector))
|
||||
FsSetFilePointer(LinuxKernelFile, 512);
|
||||
if (!FsReadFile(LinuxKernelFile, 512, NULL, TempLinuxSetupSector))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -303,8 +335,8 @@ BOOL LinuxReadSetupSector(PFILE LinuxKernelFile)
|
|||
RtlCopyMemory(LinuxSetupSector, TempLinuxSetupSector, 512);
|
||||
|
||||
// Read in the rest of the linux setup sectors
|
||||
SetFilePointer(LinuxKernelFile, 1024);
|
||||
if (!ReadFile(LinuxKernelFile, SetupSectorSize - 512, NULL, ((PVOID)LinuxSetupSector) + 512))
|
||||
FsSetFilePointer(LinuxKernelFile, 1024);
|
||||
if (!FsReadFile(LinuxKernelFile, SetupSectorSize - 512, NULL, ((PVOID)LinuxSetupSector) + 512))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -338,10 +370,6 @@ BOOL LinuxReadKernel(PFILE LinuxKernelFile)
|
|||
|
||||
sprintf(StatusText, "Loading %s", LinuxKernelName);
|
||||
UiDrawStatusText(StatusText);
|
||||
UiDrawProgressBarCenter(0, 100);
|
||||
|
||||
// Calc kernel size
|
||||
LinuxKernelSize = GetFileSize(LinuxKernelFile) - (512 + SetupSectorSize);
|
||||
|
||||
// Allocate memory for Linux kernel
|
||||
LinuxKernelLoadAddress = MmAllocateMemoryAtAddress(LinuxKernelSize, (PVOID)LINUX_KERNEL_LOAD_ADDRESS);
|
||||
|
@ -353,18 +381,18 @@ BOOL LinuxReadKernel(PFILE LinuxKernelFile)
|
|||
LoadAddress = LinuxKernelLoadAddress;
|
||||
|
||||
// Read linux kernel to 0x100000 (1mb)
|
||||
SetFilePointer(LinuxKernelFile, 512 + SetupSectorSize);
|
||||
FsSetFilePointer(LinuxKernelFile, 512 + SetupSectorSize);
|
||||
for (BytesLoaded=0; BytesLoaded<LinuxKernelSize; )
|
||||
{
|
||||
if (!ReadFile(LinuxKernelFile, 0x4000, NULL, LoadAddress))
|
||||
if (!FsReadFile(LinuxKernelFile, LINUX_READ_CHUNK_SIZE, NULL, LoadAddress))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BytesLoaded += 0x4000;
|
||||
LoadAddress += 0x4000;
|
||||
BytesLoaded += LINUX_READ_CHUNK_SIZE;
|
||||
LoadAddress += LINUX_READ_CHUNK_SIZE;
|
||||
|
||||
UiDrawProgressBarCenter(BytesLoaded, LinuxKernelSize);
|
||||
UiDrawProgressBarCenter(BytesLoaded, LinuxKernelSize + LinuxInitrdSize);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -407,29 +435,13 @@ BOOL LinuxCheckKernelVersion(VOID)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LinuxReadInitrd(VOID)
|
||||
BOOL LinuxReadInitrd(PFILE LinuxInitrdFile)
|
||||
{
|
||||
PFILE LinuxInitrdFile;
|
||||
UCHAR TempString[260];
|
||||
U32 LinuxInitrdSize;
|
||||
U32 BytesLoaded;
|
||||
UCHAR StatusText[260];
|
||||
|
||||
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);
|
||||
UiMessageBox(TempString);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Get the file size
|
||||
LinuxInitrdSize = GetFileSize(LinuxInitrdFile);
|
||||
|
||||
// Allocate memory for the ramdisk
|
||||
LinuxInitrdLoadAddress = MmAllocateMemory(LinuxInitrdSize);
|
||||
|
@ -445,15 +457,15 @@ BOOL LinuxReadInitrd(VOID)
|
|||
// Read in the ramdisk
|
||||
for (BytesLoaded=0; BytesLoaded<LinuxInitrdSize; )
|
||||
{
|
||||
if (!ReadFile(LinuxInitrdFile, 0x4000, NULL, (PVOID)LinuxInitrdLoadAddress))
|
||||
if (!FsReadFile(LinuxInitrdFile, LINUX_READ_CHUNK_SIZE, NULL, (PVOID)LinuxInitrdLoadAddress))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BytesLoaded += 0x4000;
|
||||
LinuxInitrdLoadAddress += 0x4000;
|
||||
BytesLoaded += LINUX_READ_CHUNK_SIZE;
|
||||
LinuxInitrdLoadAddress += LINUX_READ_CHUNK_SIZE;
|
||||
|
||||
UiDrawProgressBarCenter(BytesLoaded, LinuxInitrdSize);
|
||||
UiDrawProgressBarCenter(BytesLoaded + LinuxKernelSize, LinuxInitrdSize + LinuxKernelSize);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#include <ui.h>
|
||||
#include <inifile.h>
|
||||
#include <disk.h>
|
||||
#include <video.h>
|
||||
|
||||
VOID LoadAndBootBootSector(PUCHAR OperatingSystemName)
|
||||
{
|
||||
|
@ -68,13 +67,13 @@ VOID LoadAndBootBootSector(PUCHAR OperatingSystemName)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!OpenDiskDrive(BootDrive, BootPartition))
|
||||
if (!FsOpenVolume(BootDrive, BootPartition))
|
||||
{
|
||||
UiMessageBox("Failed to open boot drive.");
|
||||
return;
|
||||
}
|
||||
|
||||
FilePointer = OpenFile(FileName);
|
||||
FilePointer = FsOpenFile(FileName);
|
||||
if (FilePointer == NULL)
|
||||
{
|
||||
strcat(FileName, " not found.");
|
||||
|
@ -83,7 +82,7 @@ VOID LoadAndBootBootSector(PUCHAR OperatingSystemName)
|
|||
}
|
||||
|
||||
// Read boot sector
|
||||
if (!ReadFile(FilePointer, 512, &BytesRead, (void*)0x7c00) || (BytesRead != 512))
|
||||
if (!FsReadFile(FilePointer, 512, &BytesRead, (void*)0x7c00) || (BytesRead != 512))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -95,8 +94,7 @@ VOID LoadAndBootBootSector(PUCHAR OperatingSystemName)
|
|||
return;
|
||||
}
|
||||
|
||||
VideoClearScreen();
|
||||
VideoShowTextCursor();
|
||||
UiUnInitialize("Booting...");
|
||||
// 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
|
||||
|
@ -104,7 +102,7 @@ VOID LoadAndBootBootSector(PUCHAR OperatingSystemName)
|
|||
// 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();
|
||||
//DiskStopFloppyMotor();
|
||||
//DisableA20();
|
||||
ChainLoadBiosBootSectorCode();
|
||||
}
|
||||
|
@ -165,8 +163,7 @@ VOID LoadAndBootPartition(PUCHAR OperatingSystemName)
|
|||
return;
|
||||
}
|
||||
|
||||
VideoClearScreen();
|
||||
VideoShowTextCursor();
|
||||
UiUnInitialize("Booting...");
|
||||
// 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
|
||||
|
@ -174,7 +171,7 @@ VOID LoadAndBootPartition(PUCHAR OperatingSystemName)
|
|||
// 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();
|
||||
//DiskStopFloppyMotor();
|
||||
//DisableA20();
|
||||
ChainLoadBiosBootSectorCode();
|
||||
}
|
||||
|
@ -218,8 +215,7 @@ VOID LoadAndBootDrive(PUCHAR OperatingSystemName)
|
|||
return;
|
||||
}
|
||||
|
||||
VideoClearScreen();
|
||||
VideoShowTextCursor();
|
||||
UiUnInitialize("Booting...");
|
||||
// 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
|
||||
|
@ -227,7 +223,7 @@ VOID LoadAndBootDrive(PUCHAR OperatingSystemName)
|
|||
// 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();
|
||||
//DiskStopFloppyMotor();
|
||||
//DisableA20();
|
||||
ChainLoadBiosBootSectorCode();
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ BOOL MmInitializeMemoryManager(VOID)
|
|||
|
||||
RtlZeroMemory(BiosMemoryMap, sizeof(BIOS_MEMORY_MAP) * 32);
|
||||
|
||||
BiosMemoryMapEntryCount = GetBiosMemoryMap((PBIOS_MEMORY_MAP_ARRAY)BiosMemoryMap);
|
||||
BiosMemoryMapEntryCount = GetBiosMemoryMap(BiosMemoryMap);
|
||||
ExtendedMemorySize = GetExtendedMemorySize();
|
||||
ConventionalMemorySize = GetConventionalMemorySize();
|
||||
|
||||
|
@ -97,7 +97,7 @@ BOOL MmInitializeMemoryManager(VOID)
|
|||
// to handle just a flat extended memory size I'm going
|
||||
// to create a 'fake' memory map entry out of the
|
||||
// extended memory size if GetBiosMemoryMap() fails.
|
||||
if (BiosMemoryMapEntryCount == 0)
|
||||
//if (BiosMemoryMapEntryCount == 0)
|
||||
{
|
||||
BiosMemoryMap[0].BaseAddress = 0x100000; // Start at 1MB
|
||||
BiosMemoryMap[0].Length = ExtendedMemorySize * 1024;
|
||||
|
@ -385,7 +385,7 @@ VOID MmFixupSystemMemoryMap(BIOS_MEMORY_MAP BiosMemoryMap[32], U32* MapCount)
|
|||
// If the entry type isn't usable then remove
|
||||
// it from the memory map (this will help reduce
|
||||
// the size of our lookup table)
|
||||
if (BiosMemoryMap[Index].Type != 0)
|
||||
if (BiosMemoryMap[Index].Type != MEMTYPE_USABLE)
|
||||
{
|
||||
// Slide every entry after this down one
|
||||
for (Index2=Index; Index2<(*MapCount - 1); Index2++)
|
||||
|
|
|
@ -51,7 +51,7 @@ BOOL MultiBootLoadKernel(FILE *KernelImage)
|
|||
* Load the first 8192 bytes of the kernel image
|
||||
* so we can search for the multiboot header
|
||||
*/
|
||||
if (!ReadFile(KernelImage, 8192, NULL, ImageHeaders))
|
||||
if (!FsReadFile(KernelImage, 8192, NULL, ImageHeaders))
|
||||
{
|
||||
MmFreeMemory(ImageHeaders);
|
||||
return FALSE;
|
||||
|
@ -111,13 +111,13 @@ BOOL MultiBootLoadKernel(FILE *KernelImage)
|
|||
* Get the file offset, this should be 0, and move the file pointer
|
||||
*/
|
||||
dwFileLoadOffset = (Idx * sizeof(U32)) - (mb_header.header_addr - mb_header.load_addr);
|
||||
SetFilePointer(KernelImage, dwFileLoadOffset);
|
||||
FsSetFilePointer(KernelImage, dwFileLoadOffset);
|
||||
|
||||
/*
|
||||
* Load the file image
|
||||
*/
|
||||
dwDataSize = (mb_header.load_end_addr - mb_header.load_addr);
|
||||
ReadFile(KernelImage, dwDataSize, NULL, (void*)mb_header.load_addr);
|
||||
FsReadFile(KernelImage, dwDataSize, NULL, (void*)mb_header.load_addr);
|
||||
|
||||
/*
|
||||
* Initialize bss area
|
||||
|
@ -150,7 +150,7 @@ BOOL MultiBootLoadModule(FILE *ModuleImage, char *ModuleName)
|
|||
|
||||
ModuleNameString = multiboot_module_strings[mb_info.mods_count];
|
||||
|
||||
dwModuleSize = GetFileSize(ModuleImage);
|
||||
dwModuleSize = FsGetFileSize(ModuleImage);
|
||||
pModule->mod_start = next_module_load_base;
|
||||
pModule->mod_end = next_module_load_base + dwModuleSize;
|
||||
strcpy(ModuleNameString, ModuleName);
|
||||
|
@ -159,7 +159,7 @@ BOOL MultiBootLoadModule(FILE *ModuleImage, char *ModuleName)
|
|||
/*
|
||||
* Load the file image
|
||||
*/
|
||||
ReadFile(ModuleImage, dwModuleSize, NULL, (void*)next_module_load_base);
|
||||
FsReadFile(ModuleImage, dwModuleSize, NULL, (void*)next_module_load_base);
|
||||
|
||||
next_module_load_base = ROUND_UP(pModule->mod_end, /*PAGE_SIZE*/4096);
|
||||
mb_info.mods_count++;
|
||||
|
@ -187,7 +187,7 @@ PVOID MultiBootLoadModule(FILE *ModuleImage, char *ModuleName, U32* ModuleSize)
|
|||
|
||||
ModuleNameString = multiboot_module_strings[mb_info.mods_count];
|
||||
|
||||
dwModuleSize = GetFileSize(ModuleImage);
|
||||
dwModuleSize = FsGetFileSize(ModuleImage);
|
||||
pModule->mod_start = next_module_load_base;
|
||||
pModule->mod_end = next_module_load_base + dwModuleSize;
|
||||
strcpy(ModuleNameString, ModuleName);
|
||||
|
@ -196,7 +196,7 @@ PVOID MultiBootLoadModule(FILE *ModuleImage, char *ModuleName, U32* ModuleSize)
|
|||
/*
|
||||
* Load the file image
|
||||
*/
|
||||
ReadFile(ModuleImage, dwModuleSize, NULL, (void*)next_module_load_base);
|
||||
FsReadFile(ModuleImage, dwModuleSize, NULL, (void*)next_module_load_base);
|
||||
|
||||
next_module_load_base = ROUND_UP(pModule->mod_end, /*PAGE_SIZE*/4096);
|
||||
mb_info.mods_count++;
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <arch.h>
|
||||
#include <reactos.h>
|
||||
#include <rtl.h>
|
||||
#include <disk.h>
|
||||
#include <fs.h>
|
||||
#include <ui.h>
|
||||
#include <multiboot.h>
|
||||
|
@ -49,7 +50,7 @@ LoadKernel(PCHAR szFileName, int nPos)
|
|||
else
|
||||
szShortName = szShortName + 1;
|
||||
|
||||
FilePointer = OpenFile(szFileName);
|
||||
FilePointer = FsOpenFile(szFileName);
|
||||
if (FilePointer == NULL)
|
||||
{
|
||||
strcpy(szBuffer, szShortName);
|
||||
|
@ -108,7 +109,7 @@ LoadSymbolFile(PCHAR szSystemRoot,
|
|||
strncat(SymbolFileName, Start, Length);
|
||||
strcat(SymbolFileName, ".sym");
|
||||
|
||||
FilePointer = OpenFile((PCHAR)&SymbolFileName[0]);
|
||||
FilePointer = FsOpenFile((PCHAR)&SymbolFileName[0]);
|
||||
if (FilePointer == NULL)
|
||||
{
|
||||
DbgPrint((DPRINT_REACTOS, "Symbol file %s not loaded.\n", SymbolFileName));
|
||||
|
@ -146,7 +147,7 @@ LoadDriver(PCHAR szFileName, int nPos)
|
|||
char value[256];
|
||||
char *p;
|
||||
|
||||
FilePointer = OpenFile(szFileName);
|
||||
FilePointer = FsOpenFile(szFileName);
|
||||
if (FilePointer == NULL)
|
||||
{
|
||||
strcpy(value, szFileName);
|
||||
|
@ -185,7 +186,7 @@ LoadNlsFile(PCHAR szFileName, PCHAR szModuleName)
|
|||
char value[256];
|
||||
char *p;
|
||||
|
||||
FilePointer = OpenFile(szFileName);
|
||||
FilePointer = FsOpenFile(szFileName);
|
||||
if (FilePointer == NULL)
|
||||
{
|
||||
strcpy(value, szFileName);
|
||||
|
@ -463,7 +464,7 @@ LoadAndBootReactOS(PUCHAR OperatingSystemName)
|
|||
mb_info.cmdline = (unsigned long)multiboot_kernel_cmdline;
|
||||
mb_info.mods_count = 0;
|
||||
mb_info.mods_addr = (unsigned long)multiboot_modules;
|
||||
mb_info.mmap_length = (unsigned long)GetBiosMemoryMap((PBIOS_MEMORY_MAP_ARRAY)&multiboot_memory_map) * sizeof(memory_map_t);
|
||||
mb_info.mmap_length = (unsigned long)GetBiosMemoryMap((PBIOS_MEMORY_MAP)&multiboot_memory_map) * sizeof(memory_map_t);
|
||||
if (mb_info.mmap_length)
|
||||
{
|
||||
mb_info.mmap_addr = (unsigned long)&multiboot_memory_map;
|
||||
|
@ -531,7 +532,7 @@ LoadAndBootReactOS(PUCHAR OperatingSystemName)
|
|||
/*
|
||||
* Try to open boot drive
|
||||
*/
|
||||
if (!OpenDiskDrive(BootDrive, BootPartition))
|
||||
if (!FsOpenVolume(BootDrive, BootPartition))
|
||||
{
|
||||
UiMessageBox("Failed to open boot drive.");
|
||||
return;
|
||||
|
@ -629,7 +630,7 @@ LoadAndBootReactOS(PUCHAR OperatingSystemName)
|
|||
|
||||
DbgPrint((DPRINT_REACTOS, "SystemHive: '%s'", szFileName));
|
||||
|
||||
FilePointer = OpenFile(szFileName);
|
||||
FilePointer = FsOpenFile(szFileName);
|
||||
if (FilePointer == NULL)
|
||||
{
|
||||
strcat(value, " not found.");
|
||||
|
@ -708,10 +709,13 @@ LoadAndBootReactOS(PUCHAR OperatingSystemName)
|
|||
strcat(name, ".");
|
||||
//MessageBox(name);
|
||||
|
||||
|
||||
UiUnInitialize("Booting ReactOS...");
|
||||
|
||||
/*
|
||||
* Now boot the kernel
|
||||
*/
|
||||
StopFloppyMotor();
|
||||
DiskStopFloppyMotor();
|
||||
boot_reactos();
|
||||
}
|
||||
|
||||
|
|
|
@ -225,7 +225,7 @@ getKeyValueTypeFromChunk (PCHAR regChunk, PCHAR dataFormat, int *keyValueType)
|
|||
}
|
||||
else
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
return *regChunk ? regChunk : 0;
|
||||
|
@ -311,7 +311,7 @@ computeKeyValueDataSize (PCHAR regChunk, PCHAR dataFormat)
|
|||
}
|
||||
else
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
return dataSize;
|
||||
|
@ -425,7 +425,7 @@ getKeyValueDataFromChunk (PCHAR regChunk, PCHAR dataFormat, PCHAR data)
|
|||
}
|
||||
else
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
return *regChunk ? regChunk : 0;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <freeldr.h>
|
||||
#include <debug.h>
|
||||
#include <arch.h>
|
||||
#include <disk.h>
|
||||
#include <reactos.h>
|
||||
#include <rtl.h>
|
||||
#include <fs.h>
|
||||
|
@ -44,7 +45,7 @@ LoadKernel(PCHAR szFileName)
|
|||
else
|
||||
szShortName = szShortName + 1;
|
||||
|
||||
FilePointer = OpenFile(szFileName);
|
||||
FilePointer = FsOpenFile(szFileName);
|
||||
if (FilePointer == NULL)
|
||||
{
|
||||
printf("Could not find %s\n", szShortName);
|
||||
|
@ -78,7 +79,7 @@ LoadDriver(PCHAR szFileName)
|
|||
szShortName = szShortName + 1;
|
||||
|
||||
|
||||
FilePointer = OpenFile(szFileName);
|
||||
FilePointer = FsOpenFile(szFileName);
|
||||
if (FilePointer == NULL)
|
||||
{
|
||||
printf("Could not find %s\n", szFileName);
|
||||
|
@ -108,7 +109,7 @@ VOID RunLoader(VOID)
|
|||
mb_info.cmdline = (unsigned long)multiboot_kernel_cmdline;
|
||||
mb_info.mods_count = 0;
|
||||
mb_info.mods_addr = (unsigned long)multiboot_modules;
|
||||
mb_info.mmap_length = (unsigned long)GetBiosMemoryMap((PBIOS_MEMORY_MAP_ARRAY)&multiboot_memory_map);
|
||||
mb_info.mmap_length = (unsigned long)GetBiosMemoryMap((PBIOS_MEMORY_MAP)&multiboot_memory_map);
|
||||
if (mb_info.mmap_length)
|
||||
{
|
||||
mb_info.mmap_addr = (unsigned long)&multiboot_memory_map;
|
||||
|
@ -146,7 +147,7 @@ VOID RunLoader(VOID)
|
|||
(unsigned int)BootDrive);
|
||||
|
||||
/* Open boot drive */
|
||||
if (!OpenDiskDrive(BootDrive, BootPartition))
|
||||
if (!FsOpenVolume(BootDrive, BootPartition))
|
||||
{
|
||||
printf("Failed to open boot drive.");
|
||||
return;
|
||||
|
@ -247,7 +248,7 @@ VOID RunLoader(VOID)
|
|||
/*
|
||||
* Now boot the kernel
|
||||
*/
|
||||
StopFloppyMotor();
|
||||
DiskStopFloppyMotor();
|
||||
boot_reactos();
|
||||
|
||||
|
||||
|
|
|
@ -19,13 +19,13 @@
|
|||
|
||||
#include <freeldr.h>
|
||||
|
||||
int RtlCompareMemory(const PVOID Source1, const PVOID Source2, U32 Length)
|
||||
int memcmp(const void *buf1, const void *buf2, size_t count)
|
||||
{
|
||||
U32 i;
|
||||
const PCHAR buffer1 = Source1;
|
||||
const PCHAR buffer2 = Source2;
|
||||
unsigned int i;
|
||||
const char* buffer1 = buf1;
|
||||
const char* buffer2 = buf2;
|
||||
|
||||
for (i=0; i<Length; i++)
|
||||
for (i=0; i<count; i++)
|
||||
{
|
||||
if(buffer1[i] == buffer2[i])
|
||||
continue;
|
||||
|
@ -35,33 +35,3 @@ int RtlCompareMemory(const PVOID Source1, const PVOID Source2, U32 Length)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
VOID RtlCopyMemory(PVOID Destination, const PVOID Source, U32 Length)
|
||||
{
|
||||
U32 i;
|
||||
PCHAR buf1 = Destination;
|
||||
const PCHAR buf2 = Source;
|
||||
|
||||
for (i=0; i<Length; i++)
|
||||
{
|
||||
buf1[i] = buf2[i];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
VOID RtlFillMemory(PVOID Destination, U32 Length, UCHAR Fill)
|
||||
{
|
||||
U32 i;
|
||||
PUCHAR buf1 = Destination;
|
||||
|
||||
for (i=0; i<Length; i++)
|
||||
{
|
||||
buf1[i] = Fill;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
VOID RtlZeroMemory(PVOID Destination, U32 Length)
|
||||
{
|
||||
RtlFillMemory(Destination, Length, 0);
|
||||
}
|
50
freeldr/freeldr/rtl/memcpy.c
Normal file
50
freeldr/freeldr/rtl/memcpy.c
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* FreeLoader
|
||||
* Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <freeldr.h>
|
||||
|
||||
#ifdef __i386__
|
||||
void *memcpy(void *to, const void *from, size_t count)
|
||||
{
|
||||
__asm__( \
|
||||
"or %%ecx,%%ecx\n\t"\
|
||||
"jz .L1\n\t" \
|
||||
"cld\n\t" \
|
||||
"rep\n\t" \
|
||||
"movsb\n\t" \
|
||||
".L1:\n\t"
|
||||
:
|
||||
: "D" (to), "S" (from), "c" (count));
|
||||
return to;
|
||||
}
|
||||
#else
|
||||
void *memcpy(void *to, const void *from, size_t count)
|
||||
{
|
||||
unsigned int i;
|
||||
char* buf1 = to;
|
||||
const char* buf2 = from;
|
||||
|
||||
for (i=0; i<count; i++)
|
||||
{
|
||||
buf1[i] = buf2[i];
|
||||
}
|
||||
|
||||
return to;
|
||||
}
|
||||
#endif
|
49
freeldr/freeldr/rtl/memset.c
Normal file
49
freeldr/freeldr/rtl/memset.c
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* FreeLoader
|
||||
* Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <freeldr.h>
|
||||
|
||||
#ifdef __i386__
|
||||
void *memset(void *src, int val, size_t count)
|
||||
{
|
||||
__asm__( \
|
||||
"or %%ecx,%%ecx\n\t"\
|
||||
"jz .L1\n\t" \
|
||||
"cld\t\n" \
|
||||
"rep\t\n" \
|
||||
"stosb\t\n" \
|
||||
".L1:\n\t"
|
||||
:
|
||||
: "D" (src), "c" (count), "a" (val));
|
||||
return src;
|
||||
}
|
||||
#else
|
||||
void *memset(void *src, int val, size_t count)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned char* buf1 = src;
|
||||
|
||||
for (i=0; i<count; i++)
|
||||
{
|
||||
buf1[i] = val;
|
||||
}
|
||||
|
||||
return src;
|
||||
}
|
||||
#endif
|
|
@ -26,6 +26,42 @@
|
|||
#include <debug.h>
|
||||
#include <inifile.h>
|
||||
#include <version.h>
|
||||
#include <video.h>
|
||||
|
||||
|
||||
PVOID TextVideoBuffer = NULL;
|
||||
|
||||
BOOL TuiInitialize(VOID)
|
||||
{
|
||||
VideoClearScreen();
|
||||
VideoHideTextCursor();
|
||||
BiosVideoDisableBlinkBit();
|
||||
|
||||
TextVideoBuffer = VideoAllocateOffScreenBuffer();
|
||||
if (TextVideoBuffer == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID TuiUnInitialize(VOID)
|
||||
{
|
||||
if (UiUseSpecialEffects)
|
||||
{
|
||||
TuiFadeOut();
|
||||
}
|
||||
else
|
||||
{
|
||||
VideoSetMode(VIDEOMODE_NORMAL_TEXT);
|
||||
}
|
||||
|
||||
//VideoClearScreen();
|
||||
VideoSetMode(VIDEOMODE_NORMAL_TEXT);
|
||||
VideoShowTextCursor();
|
||||
BiosVideoEnableBlinkBit();
|
||||
}
|
||||
|
||||
VOID TuiDrawBackdrop(VOID)
|
||||
{
|
||||
|
@ -88,12 +124,14 @@ VOID TuiDrawBackdrop(VOID)
|
|||
//
|
||||
// Draw status bar
|
||||
//
|
||||
TuiDrawStatusText("");
|
||||
TuiDrawStatusText("Welcome to FreeLoader!");
|
||||
|
||||
//
|
||||
// Update the date & time
|
||||
//
|
||||
TuiUpdateDateTime();
|
||||
|
||||
VideoCopyOffScreenBufferToVRAM();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -102,7 +140,7 @@ VOID TuiDrawBackdrop(VOID)
|
|||
*/
|
||||
VOID TuiFillArea(U32 Left, U32 Top, U32 Right, U32 Bottom, UCHAR FillChar, UCHAR Attr /* Color Attributes */)
|
||||
{
|
||||
PUCHAR ScreenMemory = (PUCHAR)TUI_SCREEN_MEM;
|
||||
PUCHAR ScreenMemory = (PUCHAR)TextVideoBuffer;
|
||||
U32 i, j;
|
||||
|
||||
// Clip the area to the screen
|
||||
|
@ -138,7 +176,7 @@ VOID TuiFillArea(U32 Left, U32 Top, U32 Right, U32 Bottom, UCHAR FillChar, UCHAR
|
|||
*/
|
||||
VOID TuiDrawShadow(U32 Left, U32 Top, U32 Right, U32 Bottom)
|
||||
{
|
||||
PUCHAR ScreenMemory = (PUCHAR)TUI_SCREEN_MEM;
|
||||
PUCHAR ScreenMemory = (PUCHAR)TextVideoBuffer;
|
||||
U32 Idx;
|
||||
|
||||
// Shade the bottom of the area
|
||||
|
@ -270,7 +308,7 @@ VOID TuiDrawBox(U32 Left, U32 Top, U32 Right, U32 Bottom, UCHAR VertStyle, UCHAR
|
|||
*/
|
||||
VOID TuiDrawText(U32 X, U32 Y, PUCHAR Text, UCHAR Attr)
|
||||
{
|
||||
PUCHAR ScreenMemory = (PUCHAR)TUI_SCREEN_MEM;
|
||||
PUCHAR ScreenMemory = (PUCHAR)TextVideoBuffer;
|
||||
U32 i, j;
|
||||
|
||||
// Draw the text
|
||||
|
@ -283,6 +321,63 @@ VOID TuiDrawText(U32 X, U32 Y, PUCHAR Text, UCHAR Attr)
|
|||
|
||||
VOID TuiDrawCenteredText(U32 Left, U32 Top, U32 Right, U32 Bottom, PUCHAR TextString, UCHAR Attr)
|
||||
{
|
||||
U32 TextLength;
|
||||
U32 BoxWidth;
|
||||
U32 BoxHeight;
|
||||
U32 LineBreakCount;
|
||||
U32 Index;
|
||||
U32 LastIndex;
|
||||
U32 RealLeft;
|
||||
U32 RealTop;
|
||||
U32 X;
|
||||
U32 Y;
|
||||
UCHAR Temp[2];
|
||||
|
||||
TextLength = strlen(TextString);
|
||||
|
||||
// Count the new lines and the box width
|
||||
LineBreakCount = 0;
|
||||
BoxWidth = 0;
|
||||
LastIndex = 0;
|
||||
for (Index=0; Index<TextLength; Index++)
|
||||
{
|
||||
if (TextString[Index] == '\n')
|
||||
{
|
||||
LastIndex = Index;
|
||||
LineBreakCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((Index - LastIndex) > BoxWidth)
|
||||
{
|
||||
BoxWidth = (Index - LastIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BoxHeight = LineBreakCount + 1;
|
||||
|
||||
RealLeft = (((Right - Left) - BoxWidth) / 2) + Left;
|
||||
RealTop = (((Bottom - Top) - BoxHeight) / 2) + Top;
|
||||
|
||||
LastIndex = 0;
|
||||
for (Index=0; Index<TextLength; Index++)
|
||||
{
|
||||
if (TextString[Index] == '\n')
|
||||
{
|
||||
RealTop++;
|
||||
LastIndex = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
X = RealLeft + LastIndex;
|
||||
Y = RealTop;
|
||||
LastIndex++;
|
||||
Temp[0] = TextString[Index];
|
||||
Temp[1] = 0;
|
||||
TuiDrawText(X, Y, Temp, Attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VOID TuiDrawStatusText(PUCHAR StatusText)
|
||||
|
@ -296,6 +391,8 @@ VOID TuiDrawStatusText(PUCHAR StatusText)
|
|||
{
|
||||
TuiDrawText(i, UiScreenHeight-1, " ", ATTR(UiStatusBarFgColor, UiStatusBarBgColor));
|
||||
}
|
||||
|
||||
VideoCopyOffScreenBufferToVRAM();
|
||||
}
|
||||
|
||||
VOID TuiUpdateDateTime(VOID)
|
||||
|
@ -380,11 +477,13 @@ VOID TuiUpdateDateTime(VOID)
|
|||
|
||||
// Draw the time
|
||||
TuiDrawText(UiScreenWidth-strlen(TimeString)-2, 2, TimeString, ATTR(UiTitleBoxFgColor, UiTitleBoxBgColor));
|
||||
|
||||
VideoCopyOffScreenBufferToVRAM();
|
||||
}
|
||||
|
||||
VOID TuiSaveScreen(PUCHAR Buffer)
|
||||
{
|
||||
PUCHAR ScreenMemory = (PUCHAR)TUI_SCREEN_MEM;
|
||||
PUCHAR ScreenMemory = (PUCHAR)TextVideoBuffer;
|
||||
U32 i;
|
||||
|
||||
for (i=0; i < (UiScreenWidth * UiScreenHeight * 2); i++)
|
||||
|
@ -395,7 +494,7 @@ VOID TuiSaveScreen(PUCHAR Buffer)
|
|||
|
||||
VOID TuiRestoreScreen(PUCHAR Buffer)
|
||||
{
|
||||
PUCHAR ScreenMemory = (PUCHAR)TUI_SCREEN_MEM;
|
||||
PUCHAR ScreenMemory = (PUCHAR)TextVideoBuffer;
|
||||
U32 i;
|
||||
|
||||
for (i=0; i < (UiScreenWidth * UiScreenHeight * 2); i++)
|
||||
|
@ -483,6 +582,8 @@ VOID TuiMessageBoxCritical(PUCHAR MessageText)
|
|||
// Draw status text
|
||||
UiDrawStatusText("Press ENTER to continue");
|
||||
|
||||
VideoCopyOffScreenBufferToVRAM();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (kbhit())
|
||||
|
@ -500,6 +601,8 @@ VOID TuiMessageBoxCritical(PUCHAR MessageText)
|
|||
}
|
||||
|
||||
TuiUpdateDateTime();
|
||||
|
||||
VideoCopyOffScreenBufferToVRAM();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -549,6 +652,8 @@ VOID TuiDrawProgressBar(U32 Left, U32 Top, U32 Right, U32 Bottom, U32 Position,
|
|||
}
|
||||
|
||||
TuiUpdateDateTime();
|
||||
|
||||
VideoCopyOffScreenBufferToVRAM();
|
||||
}
|
||||
|
||||
UCHAR TuiTextToColor(PUCHAR ColorText)
|
||||
|
@ -606,3 +711,57 @@ UCHAR TuiTextToFillStyle(PUCHAR FillStyleText)
|
|||
|
||||
return LIGHT_FILL;
|
||||
}
|
||||
|
||||
VOID TuiFadeInBackdrop(VOID)
|
||||
{
|
||||
PPALETTE_ENTRY TuiFadePalette = NULL;
|
||||
|
||||
if (UiUseSpecialEffects)
|
||||
{
|
||||
TuiFadePalette = (PPALETTE_ENTRY)MmAllocateMemory(sizeof(PALETTE_ENTRY) * 64);
|
||||
|
||||
if (TuiFadePalette != NULL)
|
||||
{
|
||||
VideoSavePaletteState(TuiFadePalette, 64);
|
||||
VideoSetAllColorsToBlack(64);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the backdrop and title box
|
||||
TuiDrawBackdrop();
|
||||
|
||||
if (UiUseSpecialEffects && TuiFadePalette != NULL)
|
||||
{
|
||||
VideoFadeIn(TuiFadePalette, 64);
|
||||
MmFreeMemory(TuiFadePalette);
|
||||
}
|
||||
}
|
||||
|
||||
VOID TuiFadeOut(VOID)
|
||||
{
|
||||
PPALETTE_ENTRY TuiFadePalette = NULL;
|
||||
|
||||
if (UiUseSpecialEffects)
|
||||
{
|
||||
TuiFadePalette = (PPALETTE_ENTRY)MmAllocateMemory(sizeof(PALETTE_ENTRY) * 64);
|
||||
|
||||
if (TuiFadePalette != NULL)
|
||||
{
|
||||
VideoSavePaletteState(TuiFadePalette, 64);
|
||||
}
|
||||
}
|
||||
|
||||
if (UiUseSpecialEffects && TuiFadePalette != NULL)
|
||||
{
|
||||
VideoFadeOut(64);
|
||||
}
|
||||
|
||||
VideoSetMode(VIDEOMODE_NORMAL_TEXT);
|
||||
|
||||
if (UiUseSpecialEffects && TuiFadePalette != NULL)
|
||||
{
|
||||
VideoRestorePaletteState(TuiFadePalette, 64);
|
||||
MmFreeMemory(TuiFadePalette);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,6 +28,9 @@
|
|||
// Textual User Interface Functions
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
BOOL TuiInitialize(VOID); // Initialize User-Interface
|
||||
VOID TuiUnInitialize(VOID); // Un-initialize User-Interface
|
||||
|
||||
VOID TuiDrawBackdrop(VOID); // Fills the entire screen with a backdrop
|
||||
VOID TuiFillArea(U32 Left, U32 Top, U32 Right, U32 Bottom, UCHAR FillChar, UCHAR Attr /* Color Attributes */); // Fills the area specified with FillChar and Attr
|
||||
VOID TuiDrawShadow(U32 Left, U32 Top, U32 Right, U32 Bottom); // Draws a shadow on the bottom and right sides of the area specified
|
||||
|
@ -46,6 +49,9 @@ VOID TuiDrawProgressBar(U32 Left, U32 Top, U32 Right, U32 Bottom, U32 Position,
|
|||
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
|
||||
|
||||
VOID TuiFadeInBackdrop(VOID); // Draws the backdrop and fades the screen in
|
||||
VOID TuiFadeOut(VOID); // Fades the screen out
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Menu Functions
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "keycodes.h"
|
||||
#include <options.h>
|
||||
#include <mm.h>
|
||||
#include <video.h>
|
||||
|
||||
|
||||
BOOL TuiDisplayMenu(PUCHAR MenuItemList[], U32 MenuItemCount, U32 DefaultMenuItem, S32 MenuTimeOut, U32* SelectedMenuItem)
|
||||
|
@ -88,7 +89,9 @@ BOOL TuiDisplayMenu(PUCHAR MenuItemList[], U32 MenuItemCount, U32 DefaultMenuIte
|
|||
//
|
||||
// Update the date & time
|
||||
//
|
||||
UiUpdateDateTime();
|
||||
TuiUpdateDateTime();
|
||||
|
||||
VideoCopyOffScreenBufferToVRAM();
|
||||
|
||||
if (MenuInformation.MenuTimeRemaining > 0)
|
||||
{
|
||||
|
@ -104,6 +107,8 @@ BOOL TuiDisplayMenu(PUCHAR MenuItemList[], U32 MenuItemCount, U32 DefaultMenuIte
|
|||
// Update the menu
|
||||
//
|
||||
TuiDrawMenuBox(&MenuInformation);
|
||||
|
||||
VideoCopyOffScreenBufferToVRAM();
|
||||
}
|
||||
}
|
||||
else if (MenuInformation.MenuTimeRemaining == 0)
|
||||
|
@ -183,6 +188,8 @@ VOID TuiDrawMenu(PTUI_MENU_INFO MenuInfo)
|
|||
{
|
||||
TuiDrawMenuItem(MenuInfo, Idx);
|
||||
}
|
||||
|
||||
VideoCopyOffScreenBufferToVRAM();
|
||||
}
|
||||
|
||||
VOID TuiDrawMenuBox(PTUI_MENU_INFO MenuInfo)
|
||||
|
@ -347,6 +354,8 @@ U32 TuiProcessMenuKeyboardEvent(PTUI_MENU_INFO MenuInfo)
|
|||
|
||||
break;
|
||||
}
|
||||
|
||||
VideoCopyOffScreenBufferToVRAM();
|
||||
}
|
||||
|
||||
return KeyEvent;
|
||||
|
|
|
@ -57,6 +57,8 @@ BOOL UserInterfaceUp = FALSE; // Tells us if the user interface is display
|
|||
|
||||
BOOL UiDisplayMode = DISPLAYMODE_TEXT; // Tells us if we are in text or graphics mode
|
||||
|
||||
BOOL UiUseSpecialEffects = FALSE; // Tells us if we should use fade effects
|
||||
|
||||
UCHAR UiMonthNames[12][15] = { "January ", "February ", "March ", "April ", "May ", "June ", "July ", "August ", "September ", "October ", "November ", "December " };
|
||||
|
||||
|
||||
|
@ -86,38 +88,49 @@ BOOL UiInitialize(VOID)
|
|||
if (BiosDetectVideoCard() == VIDEOCARD_CGA_OR_OTHER)
|
||||
{
|
||||
DbgPrint((DPRINT_UI, "CGA or other display adapter detected.\n"));
|
||||
printf("CGA or other display adapter detected.\n");
|
||||
printf("Using 80x25 text mode.\n");
|
||||
VideoMode = VIDEOMODE_NORMAL_TEXT;
|
||||
}
|
||||
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)
|
||||
{
|
||||
printf("EGA display adapter detected.\n");
|
||||
printf("Using 80x25 text mode.\n");
|
||||
VideoMode = VIDEOMODE_NORMAL_TEXT;
|
||||
}
|
||||
else if (stricmp(SettingText, "EXTENDED_VGA") == 0)
|
||||
else //if (BiosDetectVideoCard() == VIDEOCARD_VGA)
|
||||
{
|
||||
VideoMode = VIDEOMODE_EXTENDED_TEXT;
|
||||
}
|
||||
else
|
||||
{
|
||||
VideoMode = atoi(SettingText);
|
||||
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%lx\n", VideoMode);
|
||||
printf("Error: unable to set video display mode 0x%x\n", VideoMode);
|
||||
printf("Defaulting to 80x25 text mode.\n");
|
||||
printf("Press any key to continue.\n");
|
||||
getch();
|
||||
|
||||
VideoMode = VIDEOMODE_NORMAL_TEXT;
|
||||
VideoSetMode(VIDEOMODE_NORMAL_TEXT);
|
||||
}
|
||||
|
||||
UiScreenWidth = VideoGetCurrentModeResolutionX();
|
||||
UiScreenHeight = VideoGetCurrentModeResolutionY();
|
||||
UiDisplayMode = VideoGetCurrentModeType();
|
||||
}
|
||||
if (IniReadSettingByName(SectionId, "TitleText", SettingText, 260))
|
||||
{
|
||||
|
@ -179,14 +192,39 @@ BOOL UiInitialize(VOID)
|
|||
{
|
||||
UiSelectedTextBgColor = UiTextToColor(SettingText);
|
||||
}
|
||||
if (IniReadSettingByName(SectionId, "SpecialEffects", SettingText, 260))
|
||||
{
|
||||
if (stricmp(SettingText, "Yes") == 0 && strlen(SettingText) == 3)
|
||||
{
|
||||
UiUseSpecialEffects = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
UiUseSpecialEffects = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VideoClearScreen();
|
||||
VideoHideTextCursor();
|
||||
BiosVideoDisableBlinkBit();
|
||||
if (UiDisplayMode == DISPLAYMODE_TEXT)
|
||||
{
|
||||
if (!TuiInitialize())
|
||||
{
|
||||
VideoSetMode(VIDEOMODE_NORMAL_TEXT);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
//if (!GuiInitialize())
|
||||
//{
|
||||
// VideoSetMode(VIDEOMODE_NORMAL_TEXT);
|
||||
// return FALSE;
|
||||
//}
|
||||
}
|
||||
|
||||
// Draw the backdrop and title box
|
||||
UiDrawBackdrop();
|
||||
// Draw the backdrop and fade it in if special effects are enabled
|
||||
UiFadeInBackdrop();
|
||||
|
||||
UserInterfaceUp = TRUE;
|
||||
|
||||
|
@ -195,6 +233,23 @@ BOOL UiInitialize(VOID)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
VOID UiUnInitialize(PUCHAR BootText)
|
||||
{
|
||||
UiDrawBackdrop();
|
||||
UiDrawStatusText("Booting...");
|
||||
UiInfoBox(BootText);
|
||||
|
||||
if (UiDisplayMode == DISPLAYMODE_TEXT)
|
||||
{
|
||||
TuiUnInitialize();
|
||||
}
|
||||
else
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
//GuiUnInitialize();
|
||||
}
|
||||
}
|
||||
|
||||
VOID UiDrawBackdrop(VOID)
|
||||
{
|
||||
if (UiDisplayMode == DISPLAYMODE_TEXT)
|
||||
|
@ -203,7 +258,7 @@ VOID UiDrawBackdrop(VOID)
|
|||
}
|
||||
else
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
UNIMPLEMENTED();
|
||||
//GuiDrawBackdrop();
|
||||
}
|
||||
}
|
||||
|
@ -216,7 +271,7 @@ VOID UiFillArea(U32 Left, U32 Top, U32 Right, U32 Bottom, UCHAR FillChar, UCHAR
|
|||
}
|
||||
else
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
UNIMPLEMENTED();
|
||||
//GuiFillArea(Left, Top, Right, Bottom, FillChar, Attr);
|
||||
}
|
||||
}
|
||||
|
@ -229,7 +284,7 @@ VOID UiDrawShadow(U32 Left, U32 Top, U32 Right, U32 Bottom)
|
|||
}
|
||||
else
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
UNIMPLEMENTED();
|
||||
//GuiDrawShadow(Left, Top, Right, Bottom);
|
||||
}
|
||||
}
|
||||
|
@ -242,7 +297,7 @@ VOID UiDrawBox(U32 Left, U32 Top, U32 Right, U32 Bottom, UCHAR VertStyle, UCHAR
|
|||
}
|
||||
else
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
UNIMPLEMENTED();
|
||||
//GuiDrawBox(Left, Top, Right, Bottom, VertStyle, HorzStyle, Fill, Shadow, Attr);
|
||||
}
|
||||
}
|
||||
|
@ -255,7 +310,7 @@ VOID UiDrawText(U32 X, U32 Y, PUCHAR Text, UCHAR Attr)
|
|||
}
|
||||
else
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
UNIMPLEMENTED();
|
||||
//GuiDrawText(X, Y, Text, Attr);
|
||||
}
|
||||
}
|
||||
|
@ -268,7 +323,7 @@ VOID UiDrawCenteredText(U32 Left, U32 Top, U32 Right, U32 Bottom, PUCHAR TextStr
|
|||
}
|
||||
else
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
UNIMPLEMENTED();
|
||||
//GuiDrawCenteredText(Left, Top, Right, Bottom, TextString, Attr);
|
||||
}
|
||||
}
|
||||
|
@ -281,7 +336,7 @@ VOID UiDrawStatusText(PUCHAR StatusText)
|
|||
}
|
||||
else
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
UNIMPLEMENTED();
|
||||
//GuiDrawStatusText(StatusText);
|
||||
}
|
||||
}
|
||||
|
@ -294,11 +349,72 @@ VOID UiUpdateDateTime(VOID)
|
|||
}
|
||||
else
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
//TuiUpdateDateTime();
|
||||
UNIMPLEMENTED();
|
||||
//GuiUpdateDateTime();
|
||||
}
|
||||
}
|
||||
|
||||
VOID UiInfoBox(PUCHAR MessageText)
|
||||
{
|
||||
U32 TextLength;
|
||||
U32 BoxWidth;
|
||||
U32 BoxHeight;
|
||||
U32 LineBreakCount;
|
||||
U32 Index;
|
||||
U32 LastIndex;
|
||||
U32 Left;
|
||||
U32 Top;
|
||||
U32 Right;
|
||||
U32 Bottom;
|
||||
|
||||
TextLength = strlen(MessageText);
|
||||
|
||||
// Count the new lines and the box width
|
||||
LineBreakCount = 0;
|
||||
BoxWidth = 0;
|
||||
LastIndex = 0;
|
||||
for (Index=0; Index<TextLength; Index++)
|
||||
{
|
||||
if (MessageText[Index] == '\n')
|
||||
{
|
||||
LastIndex = Index;
|
||||
LineBreakCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((Index - LastIndex) > BoxWidth)
|
||||
{
|
||||
BoxWidth = (Index - LastIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Calc the box width & height
|
||||
BoxWidth += 6;
|
||||
BoxHeight = LineBreakCount + 4;
|
||||
|
||||
// Calc the box coordinates
|
||||
Left = (UiScreenWidth / 2) - (BoxWidth / 2);
|
||||
Top =(UiScreenHeight / 2) - (BoxHeight / 2);
|
||||
Right = (UiScreenWidth / 2) + (BoxWidth / 2);
|
||||
Bottom = (UiScreenHeight / 2) + (BoxHeight / 2);
|
||||
|
||||
// Draw the box
|
||||
UiDrawBox(Left,
|
||||
Top,
|
||||
Right,
|
||||
Bottom,
|
||||
VERT,
|
||||
HORZ,
|
||||
TRUE,
|
||||
TRUE,
|
||||
ATTR(UiMenuFgColor, UiMenuBgColor)
|
||||
);
|
||||
|
||||
// Draw the text
|
||||
UiDrawCenteredText(Left, Top, Right, Bottom, MessageText, ATTR(UiTextColor, UiMenuBgColor));
|
||||
}
|
||||
|
||||
VOID UiMessageBox(PUCHAR MessageText)
|
||||
{
|
||||
// We have not yet displayed the user interface
|
||||
|
@ -321,7 +437,7 @@ VOID UiMessageBox(PUCHAR MessageText)
|
|||
}
|
||||
else
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
UNIMPLEMENTED();
|
||||
//GuiMessageBox(UiMessageBoxLineText);
|
||||
}
|
||||
|
||||
|
@ -348,7 +464,7 @@ VOID UiMessageBoxCritical(PUCHAR MessageText)
|
|||
}
|
||||
else
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
UNIMPLEMENTED();
|
||||
//GuiMessageBoxCritical(MessageText);
|
||||
}
|
||||
}
|
||||
|
@ -367,8 +483,8 @@ UCHAR UiTextToColor(PUCHAR ColorText)
|
|||
}
|
||||
else
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return 0;
|
||||
UNIMPLEMENTED();
|
||||
return 0;
|
||||
//return GuiTextToColor(ColorText);
|
||||
}
|
||||
}
|
||||
|
@ -381,8 +497,8 @@ UCHAR UiTextToFillStyle(PUCHAR FillStyleText)
|
|||
}
|
||||
else
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return 0;
|
||||
UNIMPLEMENTED();
|
||||
return 0;
|
||||
//return GuiTextToFillStyle(FillStyleText);
|
||||
}
|
||||
}
|
||||
|
@ -395,7 +511,7 @@ VOID UiDrawProgressBarCenter(U32 Position, U32 Range)
|
|||
}
|
||||
else
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
UNIMPLEMENTED();
|
||||
//GuiDrawProgressBarCenter(Position, Range);
|
||||
}
|
||||
}
|
||||
|
@ -408,7 +524,7 @@ VOID UiDrawProgressBar(U32 Left, U32 Top, U32 Right, U32 Bottom, U32 Position, U
|
|||
}
|
||||
else
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
UNIMPLEMENTED();
|
||||
//GuiDrawProgressBar(Left, Top, Right, Bottom, Position, Range);
|
||||
}
|
||||
}
|
||||
|
@ -457,7 +573,10 @@ VOID UiShowMessageBoxesInSection(PUCHAR SectionName)
|
|||
|
||||
VOID UiTruncateStringEllipsis(PUCHAR StringText, U32 MaxChars)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
if (strlen(StringText) > MaxChars)
|
||||
{
|
||||
strcpy(&StringText[MaxChars - 3], "...");
|
||||
}
|
||||
}
|
||||
|
||||
BOOL UiDisplayMenu(PUCHAR MenuItemList[], U32 MenuItemCount, U32 DefaultMenuItem, S32 MenuTimeOut, U32* SelectedMenuItem)
|
||||
|
@ -468,8 +587,34 @@ BOOL UiDisplayMenu(PUCHAR MenuItemList[], U32 MenuItemCount, U32 DefaultMenuItem
|
|||
}
|
||||
else
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return FALSE;
|
||||
UNIMPLEMENTED();
|
||||
return FALSE;
|
||||
//return GuiDisplayMenu(MenuItemList, MenuItemCount, DefaultMenuItem, MenuTimeOut, SelectedMenuItem);
|
||||
}
|
||||
}
|
||||
|
||||
VOID UiFadeInBackdrop(VOID)
|
||||
{
|
||||
if (UiDisplayMode == DISPLAYMODE_TEXT)
|
||||
{
|
||||
TuiFadeInBackdrop();
|
||||
}
|
||||
else
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
//GuiFadeInBackdrop();
|
||||
}
|
||||
}
|
||||
|
||||
VOID UiFadeOut(VOID)
|
||||
{
|
||||
if (UiDisplayMode == DISPLAYMODE_TEXT)
|
||||
{
|
||||
TuiFadeOut();
|
||||
}
|
||||
else
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
//GuiFadeInOut();
|
||||
}
|
||||
}
|
||||
|
|
152
freeldr/freeldr/video/bank.c
Normal file
152
freeldr/freeldr/video/bank.c
Normal file
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* FreeLoader
|
||||
* Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <freeldr.h>
|
||||
#include <video.h>
|
||||
#include <comm.h>
|
||||
#include <rtl.h>
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
U32 CurrentMemoryBank = 0;
|
||||
|
||||
VOID VideoSetMemoryBank(U16 BankNumber)
|
||||
{
|
||||
if (CurrentMemoryBank != BankNumber)
|
||||
{
|
||||
BiosVesaSetBank(BankNumber);
|
||||
CurrentMemoryBank = BankNumber;
|
||||
}
|
||||
}
|
||||
|
||||
U32 VideoGetMemoryBankForPixel(U32 X, U32 Y)
|
||||
{
|
||||
U32 Bank;
|
||||
U32 MemoryPos;
|
||||
U32 BankSize;
|
||||
U32 BytesPerPixel;
|
||||
|
||||
//BytesPerPixel = ROUND_UP(VesaVideoModeInformation.BitsPerPixel, 8) / 8;
|
||||
BytesPerPixel = (VesaVideoModeInformation.BitsPerPixel + 7) >> 3;
|
||||
MemoryPos = (Y * VideoGetBytesPerScanLine()) + (X * BytesPerPixel);
|
||||
//BankSize = VesaVideoModeInformation.WindowGranularity * 1024;
|
||||
BankSize = VesaVideoModeInformation.WindowGranularity << 10;
|
||||
Bank = MemoryPos / BankSize;
|
||||
|
||||
return Bank;
|
||||
}
|
||||
|
||||
U32 VideoGetMemoryBankForPixel16(U32 X, U32 Y)
|
||||
{
|
||||
U32 Bank;
|
||||
U32 MemoryPos;
|
||||
U32 BankSize;
|
||||
|
||||
MemoryPos = (Y * VideoGetBytesPerScanLine()) + (X / 2);
|
||||
//BankSize = VesaVideoModeInformation.WindowGranularity * 1024;
|
||||
BankSize = VesaVideoModeInformation.WindowGranularity << 10;
|
||||
Bank = MemoryPos / BankSize;
|
||||
|
||||
return Bank;
|
||||
}
|
||||
|
||||
U32 VideoGetBankOffsetForPixel(U32 X, U32 Y)
|
||||
{
|
||||
U32 BankOffset;
|
||||
U32 MemoryPos;
|
||||
U32 BankSize;
|
||||
U32 BytesPerPixel;
|
||||
|
||||
//BytesPerPixel = ROUND_UP(VesaVideoModeInformation.BitsPerPixel, 8) / 8;
|
||||
BytesPerPixel = (VesaVideoModeInformation.BitsPerPixel + 7) >> 3;
|
||||
MemoryPos = (Y * VideoGetBytesPerScanLine()) + (X * BytesPerPixel);
|
||||
//BankSize = VesaVideoModeInformation.WindowGranularity * 1024;
|
||||
BankSize = VesaVideoModeInformation.WindowGranularity << 10;
|
||||
BankOffset = MemoryPos % BankSize;
|
||||
|
||||
return BankOffset;
|
||||
}
|
||||
|
||||
U32 VideoGetBankOffsetForPixel16(U32 X, U32 Y)
|
||||
{
|
||||
U32 BankOffset;
|
||||
U32 MemoryPos;
|
||||
U32 BankSize;
|
||||
|
||||
MemoryPos = (Y * VideoGetBytesPerScanLine()) + (X / 2);
|
||||
//BankSize = VesaVideoModeInformation.WindowGranularity * 1024;
|
||||
BankSize = VesaVideoModeInformation.WindowGranularity << 10;
|
||||
BankOffset = MemoryPos % BankSize;
|
||||
|
||||
return BankOffset;
|
||||
}
|
||||
|
||||
U32 VideoGetOffScreenMemoryOffsetForPixel(U32 X, U32 Y)
|
||||
{
|
||||
U32 MemoryPos;
|
||||
U32 BytesPerPixel;
|
||||
|
||||
//BytesPerPixel = ROUND_UP(VesaVideoModeInformation.BitsPerPixel, 8) / 8;
|
||||
BytesPerPixel = (VesaVideoModeInformation.BitsPerPixel + 7) >> 3;
|
||||
MemoryPos = (Y * VesaVideoModeInformation.BytesPerScanLine) + (X * BytesPerPixel);
|
||||
|
||||
return MemoryPos;
|
||||
}
|
||||
|
||||
VOID VideoCopyOffScreenBufferToVRAM(VOID)
|
||||
{
|
||||
U32 BanksToCopy;
|
||||
U32 BytesInLastBank;
|
||||
U32 CurrentBank;
|
||||
U32 BankSize;
|
||||
U32 BufferSize;
|
||||
|
||||
//VideoWaitForVerticalRetrace();
|
||||
|
||||
// Text mode (BIOS or VESA)
|
||||
if (VideoGetCurrentModeType() == MODETYPE_TEXT)
|
||||
{
|
||||
BufferSize = VideoGetCurrentModeResolutionX() * VideoGetBytesPerScanLine();
|
||||
RtlCopyMemory((PVOID)VIDEOTEXT_MEM_ADDRESS, VideoOffScreenBuffer, BufferSize);
|
||||
}
|
||||
// VESA graphics mode
|
||||
else if (VideoGetCurrentModeType() == MODETYPE_GRAPHICS && VideoIsCurrentModeVesa())
|
||||
{
|
||||
BankSize = VesaVideoModeInformation.WindowGranularity << 10;
|
||||
BanksToCopy = (VesaVideoModeInformation.HeightInPixels * VesaVideoModeInformation.BytesPerScanLine) / BankSize;
|
||||
BytesInLastBank = (VesaVideoModeInformation.HeightInPixels * VesaVideoModeInformation.BytesPerScanLine) % BankSize;
|
||||
|
||||
// Copy all the banks but the last one because
|
||||
// it is probably a partial bank
|
||||
for (CurrentBank=0; CurrentBank<BanksToCopy; CurrentBank++)
|
||||
{
|
||||
VideoSetMemoryBank(CurrentBank);
|
||||
RtlCopyMemory((PVOID)VIDEOVGA_MEM_ADDRESS, VideoOffScreenBuffer, BankSize);
|
||||
}
|
||||
|
||||
// Copy the remaining bytes into the last bank
|
||||
VideoSetMemoryBank(CurrentBank);
|
||||
RtlCopyMemory((PVOID)VIDEOVGA_MEM_ADDRESS, VideoOffScreenBuffer, BytesInLastBank);
|
||||
}
|
||||
// BIOS graphics mode
|
||||
else
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
}
|
130
freeldr/freeldr/video/fade.c
Normal file
130
freeldr/freeldr/video/fade.c
Normal file
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* FreeLoader
|
||||
* Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <freeldr.h>
|
||||
#include <video.h>
|
||||
#include <comm.h>
|
||||
|
||||
|
||||
#define RGB_MAX 64
|
||||
#define RGB_MAX_PER_ITERATION 64
|
||||
|
||||
VOID VideoSetAllColorsToBlack(U32 ColorCount)
|
||||
{
|
||||
U32 Color;
|
||||
|
||||
VideoWaitForVerticalRetrace();
|
||||
|
||||
for (Color=0; Color<ColorCount; Color++)
|
||||
{
|
||||
VideoSetPaletteColor(Color, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
VOID VideoFadeIn(PPALETTE_ENTRY Palette, U32 ColorCount)
|
||||
{
|
||||
U32 Index;
|
||||
U32 Color;
|
||||
PALETTE_ENTRY PaletteColors[ColorCount];
|
||||
|
||||
for (Index=0; Index<RGB_MAX; Index++)
|
||||
{
|
||||
|
||||
for (Color=0; Color<ColorCount; Color++)
|
||||
{
|
||||
VideoGetPaletteColor(Color, &PaletteColors[Color].Red, &PaletteColors[Color].Green, &PaletteColors[Color].Blue);
|
||||
|
||||
// Increment each color so it approaches its real value
|
||||
if (PaletteColors[Color].Red < Palette[Color].Red)
|
||||
{
|
||||
PaletteColors[Color].Red++;
|
||||
}
|
||||
if (PaletteColors[Color].Green < Palette[Color].Green)
|
||||
{
|
||||
PaletteColors[Color].Green++;
|
||||
}
|
||||
if (PaletteColors[Color].Blue < Palette[Color].Blue)
|
||||
{
|
||||
PaletteColors[Color].Blue++;
|
||||
}
|
||||
|
||||
// Make sure we haven't exceeded the real value
|
||||
if (PaletteColors[Color].Red > Palette[Color].Red)
|
||||
{
|
||||
PaletteColors[Color].Red = Palette[Color].Red;
|
||||
}
|
||||
if (PaletteColors[Color].Green > Palette[Color].Green)
|
||||
{
|
||||
PaletteColors[Color].Green = Palette[Color].Green;
|
||||
}
|
||||
if (PaletteColors[Color].Blue > Palette[Color].Blue)
|
||||
{
|
||||
PaletteColors[Color].Blue = Palette[Color].Blue;
|
||||
}
|
||||
}
|
||||
|
||||
// Set the colors
|
||||
for (Color=0; Color<ColorCount; Color++)
|
||||
{
|
||||
if ((Color % RGB_MAX_PER_ITERATION) == 0)
|
||||
{
|
||||
VideoWaitForVerticalRetrace();
|
||||
}
|
||||
|
||||
VideoSetPaletteColor(Color, PaletteColors[Color].Red, PaletteColors[Color].Green, PaletteColors[Color].Blue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VOID VideoFadeOut(U32 ColorCount)
|
||||
{
|
||||
U32 Index;
|
||||
U32 Color;
|
||||
U8 Red;
|
||||
U8 Green;
|
||||
U8 Blue;
|
||||
|
||||
for (Index=0; Index<RGB_MAX; Index++)
|
||||
{
|
||||
for (Color=0; Color<ColorCount; Color++)
|
||||
{
|
||||
if ((Color % RGB_MAX_PER_ITERATION) == 0)
|
||||
{
|
||||
VideoWaitForVerticalRetrace();
|
||||
}
|
||||
|
||||
VideoGetPaletteColor(Color, &Red, &Green, &Blue);
|
||||
|
||||
if (Red > 0)
|
||||
{
|
||||
Red--;
|
||||
}
|
||||
if (Green > 0)
|
||||
{
|
||||
Green--;
|
||||
}
|
||||
if (Blue > 0)
|
||||
{
|
||||
Blue--;
|
||||
}
|
||||
|
||||
VideoSetPaletteColor(Color, Red, Green, Blue);
|
||||
}
|
||||
}
|
||||
}
|
61
freeldr/freeldr/video/palette.c
Normal file
61
freeldr/freeldr/video/palette.c
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* FreeLoader
|
||||
* Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <freeldr.h>
|
||||
#include <video.h>
|
||||
#include <comm.h>
|
||||
|
||||
|
||||
VOID VideoSetPaletteColor(U8 Color, U8 Red, U8 Green, U8 Blue)
|
||||
{
|
||||
WRITE_PORT_UCHAR((U8*)VIDEOPORT_PALETTE_WRITE, Color);
|
||||
WRITE_PORT_UCHAR((U8*)VIDEOPORT_PALETTE_DATA, Red);
|
||||
WRITE_PORT_UCHAR((U8*)VIDEOPORT_PALETTE_DATA, Green);
|
||||
WRITE_PORT_UCHAR((U8*)VIDEOPORT_PALETTE_DATA, Blue);
|
||||
}
|
||||
|
||||
VOID VideoGetPaletteColor(U8 Color, U8* Red, U8* Green, U8* Blue)
|
||||
{
|
||||
WRITE_PORT_UCHAR((U8*)VIDEOPORT_PALETTE_READ, Color);
|
||||
*Red = READ_PORT_UCHAR((U8*)VIDEOPORT_PALETTE_DATA);
|
||||
*Green = READ_PORT_UCHAR((U8*)VIDEOPORT_PALETTE_DATA);
|
||||
*Blue = READ_PORT_UCHAR((U8*)VIDEOPORT_PALETTE_DATA);
|
||||
}
|
||||
|
||||
VOID VideoSavePaletteState(PPALETTE_ENTRY Palette, U32 ColorCount)
|
||||
{
|
||||
U32 Color;
|
||||
|
||||
for (Color=0; Color<ColorCount; Color++)
|
||||
{
|
||||
VideoGetPaletteColor(Color, &Palette[Color].Red, &Palette[Color].Green, &Palette[Color].Blue);
|
||||
}
|
||||
}
|
||||
|
||||
VOID VideoRestorePaletteState(PPALETTE_ENTRY Palette, U32 ColorCount)
|
||||
{
|
||||
U32 Color;
|
||||
|
||||
VideoWaitForVerticalRetrace();
|
||||
|
||||
for (Color=0; Color<ColorCount; Color++)
|
||||
{
|
||||
VideoSetPaletteColor(Color, Palette[Color].Red, Palette[Color].Green, Palette[Color].Blue);
|
||||
}
|
||||
}
|
333
freeldr/freeldr/video/pixel.c
Normal file
333
freeldr/freeldr/video/pixel.c
Normal file
|
@ -0,0 +1,333 @@
|
|||
/*
|
||||
* FreeLoader
|
||||
* Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <freeldr.h>
|
||||
#include <video.h>
|
||||
#include <comm.h>
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Arrrggh!
|
||||
// I really really hate 16 color bit plane modes.
|
||||
// They should all burn in hell for what they've
|
||||
// done to my sleeping habits. And I still can't
|
||||
// get this code to work and I have absolutely
|
||||
// no idea why...
|
||||
//
|
||||
VOID VideoSetPixel16(U32 X, U32 Y, U8 Color)
|
||||
{
|
||||
U8 CurrentColor;
|
||||
U8* MemoryPointer;
|
||||
U32 ByteOffset;
|
||||
U8 BitInByte;
|
||||
U8 ReadByte;
|
||||
U8 BitToChange;
|
||||
|
||||
MemoryPointer = (U8*)(VIDEOVGA_MEM_ADDRESS);
|
||||
|
||||
// Calculate the byte offset into the bit-plane
|
||||
// where the pixel is to be set and the bit
|
||||
// offset in that byte.
|
||||
//ByteOffset = (Y * VideoGetBytesPerScanLine()) + (X >> 3);
|
||||
//ByteOffset = (Y * 80) + (X >> 3);
|
||||
ByteOffset = (Y * 640) + X;
|
||||
BitInByte = ByteOffset & 7;
|
||||
ByteOffset = ByteOffset >> 3;
|
||||
//BitToChange = 0x80 >> BitInByte;
|
||||
BitToChange = 0x80;
|
||||
|
||||
DbgPrint((DPRINT_WARNING, "X = %d Y = %d Color = %d ByteOffset = %d BitInByte = %d BitToChange = %d\n", X, Y, Color, ByteOffset, BitInByte, BitToChange));
|
||||
//getch();
|
||||
|
||||
// Read the byte of memory to be changed. This is a
|
||||
// read for the video card latches and the data read
|
||||
// from memory does not need to be used.
|
||||
ReadByte = MemoryPointer[ByteOffset];
|
||||
|
||||
// Select the bit or bits in the byte that need to be
|
||||
// changed through index 8 of the VGA card address
|
||||
// register by sending an 8 out to I/O port 3CEh.
|
||||
// Next get the bits to be changed (a one-bit represents
|
||||
// a bit to be changed) and send this out to I/O
|
||||
// port 3CFh, the bit mask register (BMR).
|
||||
//WRITE_PORT_USHORT((U16*)0x3CE, (((U16)BitToChange) << 8) + 0x08);
|
||||
WRITE_PORT_UCHAR((U8*)0x3CE, 0x08);
|
||||
//WRITE_PORT_UCHAR((U8*)0x3CF, BitToChange);
|
||||
WRITE_PORT_UCHAR((U8*)0x3CF, BitInByte);
|
||||
|
||||
// Next set all mask bits to 1111 in the map mask register
|
||||
// (MMR) at sequencer offset 2, and write color 0 to the
|
||||
// VGA card to set the color to black. The mask bits select
|
||||
// the bit planes to be changed. If all are selected and a
|
||||
// color of 0 is written, all four bit-planes are clear to zero.
|
||||
WRITE_PORT_USHORT((U16*)0x3C4, 0x0F02);
|
||||
//WRITE_PORT_UCHAR((U8*)0x3C4, 0x02);
|
||||
//WRITE_PORT_UCHAR((U8*)0x3C5, 0x0F); // Mask to 1111 binary
|
||||
MemoryPointer[ByteOffset] = 0x00;
|
||||
|
||||
// Send the desired color number to the map mask register and
|
||||
// write an FFh to the video memory. This places a logic one
|
||||
// in only the selected bit planes to write a new color to
|
||||
// a pixel or dot on the screen.
|
||||
WRITE_PORT_UCHAR((U8*)0x3C4, 0x02);
|
||||
//WRITE_PORT_UCHAR((U8*)0x3C5, Color);
|
||||
WRITE_PORT_UCHAR((U8*)0x3C5, 0x0F);
|
||||
//WRITE_PORT_USHORT((U16*)0x3C4, 0x0A02);
|
||||
MemoryPointer[ByteOffset] = 0xFF;
|
||||
|
||||
|
||||
/*CurrentColor = Color;
|
||||
|
||||
MemoryPointer = (U8*)(VIDEOVGA_MEM_ADDRESS);
|
||||
|
||||
WRITE_PORT_USHORT((U16*)0x3CE, 0x00 | (CurrentColor << 8));
|
||||
WRITE_PORT_USHORT((U16*)0x3CE, 0x08 | 0x8000 >> (X & 7));
|
||||
|
||||
MemoryPointer += (Y * VideoGetBytesPerScanLine()) + (X >> 3);
|
||||
|
||||
*MemoryPointer = *MemoryPointer;
|
||||
getch();*/
|
||||
|
||||
|
||||
// First select the color plane
|
||||
//ColorPlane = Color;
|
||||
//ColorPlane = (ColorPlane << 8) + 0x02;
|
||||
//WRITE_PORT_USHORT((U16*)0x3C4, ColorPlane);
|
||||
|
||||
// Now calculate the byte offset in the
|
||||
// color plane that contains our pixel
|
||||
// Since there are 8 pixels per byte we
|
||||
// have to adjust accordingly
|
||||
/*ByteOffset = (Y * VideoGetCurrentModeResolutionX()) + X;
|
||||
BitInByte = ByteOffset % 8;
|
||||
ByteOffset = ByteOffset / 8;
|
||||
|
||||
// Shift the color to the right bit
|
||||
Color = 1;
|
||||
Color = Color << BitInByte;
|
||||
|
||||
// Get the current color
|
||||
CurrentColor = MemoryPointer[ByteOffset];
|
||||
|
||||
// Add the new color
|
||||
CurrentColor = CurrentColor | Color;
|
||||
|
||||
// Now set the color
|
||||
MemoryPointer[ByteOffset] = CurrentColor;*/
|
||||
}
|
||||
|
||||
VOID VideoSetPixel256(U32 X, U32 Y, U8 Color)
|
||||
{
|
||||
U32 Bank;
|
||||
U32 Offset;
|
||||
U8* MemoryPointer;
|
||||
|
||||
MemoryPointer = (U8*)(VIDEOVGA_MEM_ADDRESS);
|
||||
|
||||
Bank = VideoGetMemoryBankForPixel(X, Y);
|
||||
Offset = VideoGetBankOffsetForPixel(X, Y);
|
||||
|
||||
VideoSetMemoryBank(Bank);
|
||||
|
||||
MemoryPointer[Offset] = Color;
|
||||
}
|
||||
|
||||
VOID VideoSetPixelRGB_15Bit(U32 X, U32 Y, U8 Red, U8 Green, U8 Blue)
|
||||
{
|
||||
U32 Bank;
|
||||
U32 Offset;
|
||||
U8* MemoryPointer;
|
||||
U16 Pixel;
|
||||
|
||||
MemoryPointer = (U8*)(VIDEOVGA_MEM_ADDRESS);
|
||||
|
||||
Bank = VideoGetMemoryBankForPixel(X, Y);
|
||||
Offset = VideoGetBankOffsetForPixel(X, Y);
|
||||
|
||||
VideoSetMemoryBank(Bank);
|
||||
|
||||
Red = Red >> 3;
|
||||
Green = Green >> 3;
|
||||
Blue = Blue >> 3;
|
||||
|
||||
Pixel = Red << 11 | Green << 6 | Blue << 1;
|
||||
|
||||
MemoryPointer[Offset] = Pixel & 0xFF;
|
||||
MemoryPointer[Offset+1] = Pixel >> 8;
|
||||
}
|
||||
|
||||
VOID VideoSetPixelRGB_16Bit(U32 X, U32 Y, U8 Red, U8 Green, U8 Blue)
|
||||
{
|
||||
U32 Bank;
|
||||
U32 Offset;
|
||||
U8* MemoryPointer;
|
||||
U16 Pixel;
|
||||
|
||||
MemoryPointer = (U8*)(VIDEOVGA_MEM_ADDRESS);
|
||||
|
||||
Bank = VideoGetMemoryBankForPixel(X, Y);
|
||||
Offset = VideoGetBankOffsetForPixel(X, Y);
|
||||
|
||||
VideoSetMemoryBank(Bank);
|
||||
|
||||
Red = Red >> 3;
|
||||
Green = Green >> 2;
|
||||
Blue = Blue >> 3;
|
||||
|
||||
Pixel = (U16)Red << 11 | (U16)Green << 5 | (U16)Blue << 0;
|
||||
|
||||
MemoryPointer[Offset] = Pixel & 0xFF;
|
||||
MemoryPointer[Offset+1] = Pixel >> 8;
|
||||
}
|
||||
|
||||
VOID VideoSetPixelRGB_24Bit(U32 X, U32 Y, U8 Red, U8 Green, U8 Blue)
|
||||
{
|
||||
U32 Bank;
|
||||
U32 Offset;
|
||||
U8* MemoryPointer;
|
||||
|
||||
MemoryPointer = (U8*)(VIDEOVGA_MEM_ADDRESS);
|
||||
|
||||
Bank = VideoGetMemoryBankForPixel(X, Y);
|
||||
Offset = VideoGetBankOffsetForPixel(X, Y);
|
||||
|
||||
VideoSetMemoryBank(Bank);
|
||||
|
||||
MemoryPointer[Offset] = Blue;
|
||||
MemoryPointer[Offset+1] = Green;
|
||||
MemoryPointer[Offset+2] = Red;
|
||||
}
|
||||
|
||||
VOID VideoSetPixelRGB(U32 X, U32 Y, U8 Red, U8 Green, U8 Blue)
|
||||
{
|
||||
if (VesaVideoModeInformation.BitsPerPixel >= 24)
|
||||
{
|
||||
VideoSetPixelRGB_24Bit(X, Y, Red, Green, Blue);
|
||||
}
|
||||
else if (VesaVideoModeInformation.BitsPerPixel >= 16)
|
||||
{
|
||||
// 16-bit color modes give green an extra bit (5:6:5)
|
||||
// 15-bit color modes have just 5:5:5 for R:G:B
|
||||
if (VesaVideoModeInformation.GreenMaskSize == 6)
|
||||
{
|
||||
VideoSetPixelRGB_16Bit(X, Y, Red, Green, Blue);
|
||||
}
|
||||
else
|
||||
{
|
||||
VideoSetPixelRGB_15Bit(X, Y, Red, Green, Blue);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BugCheck((DPRINT_UI, "This function does not support %d bits per pixel!", VesaVideoModeInformation.BitsPerPixel));
|
||||
}
|
||||
}
|
||||
|
||||
VOID VideoSetPixel16_OffScreen(U32 X, U32 Y, U8 Color)
|
||||
{
|
||||
}
|
||||
|
||||
VOID VideoSetPixel256_OffScreen(U32 X, U32 Y, U8 Color)
|
||||
{
|
||||
U8* MemoryPointer;
|
||||
|
||||
MemoryPointer = (U8*)(VideoOffScreenBuffer + VideoGetOffScreenMemoryOffsetForPixel(X, Y));
|
||||
|
||||
*MemoryPointer = Color;
|
||||
}
|
||||
|
||||
VOID VideoSetPixelRGB_15Bit_OffScreen(U32 X, U32 Y, U8 Red, U8 Green, U8 Blue)
|
||||
{
|
||||
U32 Offset;
|
||||
U8* MemoryPointer;
|
||||
U16 Pixel;
|
||||
|
||||
MemoryPointer = (U8*)(VideoOffScreenBuffer);
|
||||
Offset = VideoGetOffScreenMemoryOffsetForPixel(X, Y);
|
||||
|
||||
Red = Red >> 3;
|
||||
Green = Green >> 3;
|
||||
Blue = Blue >> 3;
|
||||
|
||||
Pixel = Red << 11 | Green << 6 | Blue << 1;
|
||||
|
||||
MemoryPointer[Offset] = Pixel & 0xFF;
|
||||
MemoryPointer[Offset+1] = Pixel >> 8;
|
||||
}
|
||||
|
||||
VOID VideoSetPixelRGB_16Bit_OffScreen(U32 X, U32 Y, U8 Red, U8 Green, U8 Blue)
|
||||
{
|
||||
U32 Offset;
|
||||
U8* MemoryPointer;
|
||||
U16 Pixel;
|
||||
|
||||
MemoryPointer = (U8*)(VideoOffScreenBuffer);
|
||||
Offset = VideoGetOffScreenMemoryOffsetForPixel(X, Y);
|
||||
|
||||
Red = Red >> 3;
|
||||
Green = Green >> 2;
|
||||
Blue = Blue >> 3;
|
||||
|
||||
Pixel = (U16)Red << 11 | (U16)Green << 5 | (U16)Blue << 0;
|
||||
|
||||
MemoryPointer[Offset] = Pixel & 0xFF;
|
||||
MemoryPointer[Offset+1] = Pixel >> 8;
|
||||
}
|
||||
|
||||
VOID VideoSetPixelRGB_24Bit_OffScreen(U32 X, U32 Y, U8 Red, U8 Green, U8 Blue)
|
||||
{
|
||||
U32 Offset;
|
||||
U8* MemoryPointer;
|
||||
|
||||
MemoryPointer = (U8*)(VideoOffScreenBuffer);
|
||||
Offset = VideoGetOffScreenMemoryOffsetForPixel(X, Y);
|
||||
|
||||
MemoryPointer[Offset] = Blue;
|
||||
MemoryPointer[Offset+1] = Green;
|
||||
MemoryPointer[Offset+2] = Red;
|
||||
}
|
||||
|
||||
VOID VideoSetPixelRGB_OffScreen(U32 X, U32 Y, U8 Red, U8 Green, U8 Blue)
|
||||
{
|
||||
if (VesaVideoModeInformation.BitsPerPixel >= 24)
|
||||
{
|
||||
VideoSetPixelRGB_24Bit_OffScreen(X, Y, Red, Green, Blue);
|
||||
}
|
||||
else if (VesaVideoModeInformation.BitsPerPixel >= 16)
|
||||
{
|
||||
// 16-bit color modes give green an extra bit (5:6:5)
|
||||
// 15-bit color modes have just 5:5:5 for R:G:B
|
||||
if (VesaVideoModeInformation.GreenMaskSize == 6)
|
||||
{
|
||||
VideoSetPixelRGB_16Bit_OffScreen(X, Y, Red, Green, Blue);
|
||||
}
|
||||
else
|
||||
{
|
||||
VideoSetPixelRGB_15Bit_OffScreen(X, Y, Red, Green, Blue);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BugCheck((DPRINT_UI, "This function does not support %d bits per pixel!", VesaVideoModeInformation.BitsPerPixel));
|
||||
}
|
||||
}
|
|
@ -20,8 +20,11 @@
|
|||
#include <freeldr.h>
|
||||
#include <video.h>
|
||||
#include <comm.h>
|
||||
#include <mm.h>
|
||||
|
||||
|
||||
PVOID VideoOffScreenBuffer = NULL;
|
||||
|
||||
VOID VideoClearScreen(VOID)
|
||||
{
|
||||
VideoSetMode(VideoGetCurrentMode());
|
||||
|
@ -29,29 +32,36 @@ VOID VideoClearScreen(VOID)
|
|||
|
||||
VOID VideoWaitForVerticalRetrace(VOID)
|
||||
{
|
||||
while ((READ_PORT_UCHAR((PUCHAR)VIDEOPORT_VERTICAL_RETRACE) & 0x08))
|
||||
|
||||
while ((READ_PORT_UCHAR((U8*)VIDEOPORT_VERTICAL_RETRACE) & 0x08) == 1)
|
||||
{
|
||||
// Keep reading the port until bit 4 is clear
|
||||
// Keep reading the port until bit 3 is clear
|
||||
// This waits for the current retrace to end and
|
||||
// we can catch the next one so we know we are
|
||||
// getting a full retrace.
|
||||
}
|
||||
|
||||
while (!(READ_PORT_UCHAR((PUCHAR)VIDEOPORT_VERTICAL_RETRACE) & 0x08))
|
||||
while ((READ_PORT_UCHAR((U8*)VIDEOPORT_VERTICAL_RETRACE) & 0x08) == 0)
|
||||
{
|
||||
// Keep reading the port until bit 4 is set
|
||||
// Keep reading the port until bit 3 is set
|
||||
// Now that we know we aren't doing a vertical
|
||||
// retrace we need to wait for the next one.
|
||||
}
|
||||
}
|
||||
|
||||
VOID VideoSetPaletteColor(UCHAR Color, UCHAR Red, UCHAR Green, UCHAR Blue)
|
||||
PVOID VideoAllocateOffScreenBuffer(VOID)
|
||||
{
|
||||
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);
|
||||
}
|
||||
U32 BufferSize;
|
||||
|
||||
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);
|
||||
if (VideoOffScreenBuffer != NULL)
|
||||
{
|
||||
MmFreeMemory(VideoOffScreenBuffer);
|
||||
VideoOffScreenBuffer = NULL;
|
||||
}
|
||||
|
||||
BufferSize = VideoGetCurrentModeResolutionX() * VideoGetBytesPerScanLine();
|
||||
|
||||
VideoOffScreenBuffer = MmAllocateMemory(BufferSize);
|
||||
|
||||
return VideoOffScreenBuffer;
|
||||
}
|
||||
|
|
|
@ -19,41 +19,123 @@
|
|||
|
||||
#include <freeldr.h>
|
||||
#include <video.h>
|
||||
#include <debug.h>
|
||||
#include <comm.h>
|
||||
|
||||
U32 CurrentVideoMode = VIDEOMODE_NORMAL_TEXT;
|
||||
U32 VideoResolutionX = 80;
|
||||
U32 VideoResolutionY = 25;
|
||||
U32 CurrentVideoMode = VIDEOMODE_NORMAL_TEXT;
|
||||
U32 VideoResolutionX = 80;
|
||||
U32 VideoResolutionY = 25;
|
||||
U32 VideoBytesPerScanLine = 0; // Number of bytes per scan line
|
||||
U32 CurrentModeType = MODETYPE_TEXT;
|
||||
BOOL VesaVideoMode = FALSE;
|
||||
|
||||
SVGA_MODE_INFORMATION VesaVideoModeInformation;
|
||||
|
||||
BOOL VideoSetMode(U32 VideoMode)
|
||||
{
|
||||
CurrentMemoryBank = 0;
|
||||
|
||||
// Set the values for the default text modes
|
||||
// If they are setting a graphics mode then
|
||||
// these values will be changed.
|
||||
CurrentVideoMode = VideoMode;
|
||||
VideoResolutionX = 80;
|
||||
VideoResolutionY = 25;
|
||||
VideoBytesPerScanLine = 160;
|
||||
CurrentModeType = MODETYPE_TEXT;
|
||||
VesaVideoMode = FALSE;
|
||||
|
||||
switch (VideoMode)
|
||||
{
|
||||
case VIDEOMODE_NORMAL_TEXT:
|
||||
CurrentVideoMode = VideoMode;
|
||||
case 0x03: /* BIOS 80x25 text mode number */
|
||||
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;
|
||||
if (VideoMode == 0x12)
|
||||
{
|
||||
// 640x480x16
|
||||
BiosSetVideoMode(VideoMode);
|
||||
//WRITE_PORT_USHORT((U16*)0x03CE, 0x0205); // For some reason this is necessary?
|
||||
WRITE_PORT_USHORT((U16*)0x03CE, 0x0F01); // For some reason this is necessary?
|
||||
VideoResolutionX = 640;
|
||||
VideoResolutionY = 480;
|
||||
VideoBytesPerScanLine = 80;
|
||||
CurrentVideoMode = 0x12;
|
||||
CurrentModeType = MODETYPE_GRAPHICS;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else if (VideoMode == 0x13)
|
||||
{
|
||||
// 320x200x256
|
||||
BiosSetVideoMode(VideoMode);
|
||||
VideoResolutionX = 320;
|
||||
VideoResolutionY = 200;
|
||||
VideoBytesPerScanLine = 320;
|
||||
CurrentVideoMode = 0x13;
|
||||
CurrentModeType = MODETYPE_GRAPHICS;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else if (VideoMode >= 0x0108 && VideoMode <= 0x010C)
|
||||
{
|
||||
// VESA Text Mode
|
||||
if (!BiosVesaGetSVGAModeInformation(VideoMode, &VesaVideoModeInformation))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!BiosVesaSetVideoMode(VideoMode))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
VideoResolutionX = VesaVideoModeInformation.WidthInPixels;
|
||||
VideoResolutionY = VesaVideoModeInformation.HeightInPixels;
|
||||
VideoBytesPerScanLine = VesaVideoModeInformation.BytesPerScanLine;
|
||||
CurrentVideoMode = VideoMode;
|
||||
CurrentModeType = MODETYPE_TEXT;
|
||||
VesaVideoMode = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// VESA Graphics Mode
|
||||
if (!BiosVesaGetSVGAModeInformation(VideoMode, &VesaVideoModeInformation))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!BiosVesaSetVideoMode(VideoMode))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
VideoResolutionX = VesaVideoModeInformation.WidthInPixels;
|
||||
VideoResolutionY = VesaVideoModeInformation.HeightInPixels;
|
||||
VideoBytesPerScanLine = VesaVideoModeInformation.BytesPerScanLine;
|
||||
CurrentVideoMode = VideoMode;
|
||||
CurrentModeType = MODETYPE_GRAPHICS;
|
||||
VesaVideoMode = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL VideoSetMode80x25(VOID)
|
||||
|
@ -110,7 +192,7 @@ BOOL VideoSetMode80x28(VOID)
|
|||
BOOL VideoSetMode80x43(VOID)
|
||||
{
|
||||
// FIXME: Is this VGA-only?
|
||||
BiosSet350ScanLines();
|
||||
BiosSetVerticalResolution(VERTRES_350_SCANLINES);
|
||||
VideoSetMode80x25();
|
||||
BiosSetVideoFont8x8();
|
||||
BiosSelectAlternatePrintScreen();
|
||||
|
@ -173,7 +255,59 @@ U32 VideoGetCurrentModeResolutionY(VOID)
|
|||
return VideoResolutionY;
|
||||
}
|
||||
|
||||
U32 VideoGetBytesPerScanLine(VOID)
|
||||
{
|
||||
return VideoBytesPerScanLine;
|
||||
}
|
||||
|
||||
U32 VideoGetCurrentMode(VOID)
|
||||
{
|
||||
return CurrentVideoMode;
|
||||
}
|
||||
|
||||
U32 VideoGetCurrentModeType(VOID)
|
||||
{
|
||||
return CurrentModeType;
|
||||
}
|
||||
|
||||
BOOL VideoIsCurrentModeVesa(VOID)
|
||||
{
|
||||
return VesaVideoMode;
|
||||
}
|
||||
|
||||
U32 VideoGetCurrentModeColorDepth(VOID)
|
||||
{
|
||||
U32 ColorDepth = 2;
|
||||
U32 i;
|
||||
|
||||
if (CurrentModeType == MODETYPE_TEXT)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else // CurrentModeType == MODETYPE_GRAPHICS
|
||||
{
|
||||
// Calculate 2^BitsPerPixel'th power
|
||||
for (i=0; i<(VesaVideoModeInformation.BitsPerPixel-1); i++)
|
||||
{
|
||||
ColorDepth *= 2;
|
||||
}
|
||||
|
||||
// This algorithm works great for 24-bit & 8-bit color modes
|
||||
// but 15-bit color modes really use 16 bits per pixel.
|
||||
// So check to see if green has an extra bit, if so then
|
||||
// it is 16-bit, if not it is 15-bit
|
||||
if (ColorDepth == 65536)
|
||||
{
|
||||
if (VesaVideoModeInformation.GreenMaskSize == 6)
|
||||
{
|
||||
return ColorDepth;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 32768;
|
||||
}
|
||||
}
|
||||
|
||||
return ColorDepth;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
FreeLoader notes
|
||||
|
||||
To build FreeLoader you will need DJGPP because Mingw32 doesn't support 16-bit code
|
||||
ext2 filesystem support needs to be added.
|
||||
The MessageBox() function needs to not allocate memory. Because it gets called when memory allocation fails.
|
||||
|
||||
Memory layout:
|
||||
|
||||
|
|
Loading…
Reference in a new issue