34 Commits
Author SHA1 Message Date
josh 311b8afc83 Import backup from 2004-01-26 2017-07-25 22:23:46 -04:00
josh 21e3943b5e Import backup from 2004-01-20 2017-07-25 22:23:46 -04:00
josh 10fd7102ca Import backup from 2004-01-18 2017-07-25 22:23:46 -04:00
josh 7de4f94423 Import backup from 2004-01-15 2017-07-25 22:23:46 -04:00
josh 0a546f1467 Import backup from 2004-01-07 2017-07-25 22:23:45 -04:00
josh af6087ecec Import backup from 2004-01-04 2017-07-25 22:23:45 -04:00
josh c613002307 Import backup from 2003-12-31 2017-07-25 22:23:45 -04:00
josh 76398df125 Import backup from 2003-12-30 2017-07-25 22:23:45 -04:00
josh e83408ce83 Import backup from 2003-12-29 2017-07-25 22:23:45 -04:00
josh 715bb9341a Import backup from 2003-12-28 2017-07-25 22:23:45 -04:00
josh e82bf2ecdf Import backup from 2003-12-25 2017-07-25 22:23:45 -04:00
josh 528527a7ed Import backup from 2003-12-23_2 2017-07-25 22:23:45 -04:00
josh 71aaa7a598 Import backup from 2003-12-23 2017-07-25 22:23:45 -04:00
josh 9070a76b18 Import backup from 2003-12-22_2 2017-07-25 22:23:45 -04:00
josh 5048a93ff7 Import backup from 2003-12-22 2017-07-25 22:23:45 -04:00
josh 282b856e24 Import backup from 2003-12-21 2017-07-25 22:23:45 -04:00
josh 3bb1e5fffc Import backup from 2003-12-20 2017-07-25 22:23:45 -04:00
josh 5ccfd0fc74 Import backup from 2003-11-13 2017-07-25 22:23:45 -04:00
josh 70d6bb1eb3 Import backup from 2003-11-12 2017-07-25 22:23:45 -04:00
josh 294b4b0e27 Import backup from 2003-11-11 2017-07-25 22:23:45 -04:00
josh 57980293e6 Import backup from 2003-11-03 2017-07-25 22:23:45 -04:00
josh ba97e8a7f0 Import backup from 2003-10-30 2017-07-25 22:23:45 -04:00
josh 36b025ccb4 Import backup from 2003-10-27 2017-07-25 22:23:45 -04:00
josh aab5ff3c90 Import backup from 2003-10-23 2017-07-25 22:23:45 -04:00
josh 8bf6e65a95 Import backup from 2003-10-16 2017-07-25 22:23:45 -04:00
josh 5da602b162 Import backup from 2003-10-06 2017-07-25 22:23:45 -04:00
josh 7a0351e123 Import backup from 2003-10-03 2017-07-25 22:23:45 -04:00
josh 3dc0fe5e2b Import backup from 2003-09-30 2017-07-25 22:23:45 -04:00
josh 82da40c9f0 Import backup from 2003-09-29 2017-07-25 22:23:45 -04:00
josh 8d5b28f823 Import backup from 2003-09-28 2017-07-25 22:23:45 -04:00
josh 68fd6cad70 Import backup from 2003-09-26 2017-07-25 22:23:45 -04:00
josh c3309d4e5d Import backup from 2003-09-23 2017-07-25 22:23:45 -04:00
josh 06d7cbef47 Import backup from 2003-09-13 2017-07-25 22:23:44 -04:00
josh e8b1abb265 Import backup from 2003-09-12 2017-07-25 22:23:44 -04:00
49 changed files with 2722 additions and 1034 deletions

No files matched your search

+220 -18
View File
@@ -1,18 +1,21 @@
//Functions.c //Functions.c
//05/07/03 Josh Holtrop //05/07/03 Josh Holtrop
//for HOS //for HOS
//Modified: 10/30/03
//Writes a byte out to a port
inline void outportb(unsigned int port, unsigned char value) // Output a byte to a port inline void outportb(unsigned int port, unsigned char value) // Output a byte to a port
{ {
asm volatile ("outb %%al,%%dx"::"d" (port), "a" (value)); asm volatile ("outb %%al,%%dx"::"d" (port), "a" (value));
}; };
//Writes a word out to a port
inline void outportw(unsigned int port, unsigned int value) // Output a word to a port inline void outportw(unsigned int port, unsigned int value) // Output a word to a port
{ {
asm volatile ("outw %%ax,%%dx"::"d" (port), "a" (value)); asm volatile ("outw %%ax,%%dx"::"d" (port), "a" (value));
}; };
//Reads a byte from a port
inline byte inportb(unsigned short port) inline byte inportb(unsigned short port)
{ {
unsigned char ret_val; unsigned char ret_val;
@@ -23,47 +26,245 @@ inline byte inportb(unsigned short port)
return ret_val; return ret_val;
}; };
void enable_ints() //Enables (SeTs) Interrupt Flag on the processor
inline void enable_ints()
{ {
asm("sti"); asm("sti");
}; };
void disable_ints() //Disables (CLears) Interrupt Flag on the processor
inline void disable_ints()
{ {
asm("cli"); asm("cli");
}; };
char *strcat(char *dest, char *src)
{
strcpy(dest+strlen(dest), src);
}
//converts a binary-coded-decimal byte to its decimal equivalent
inline byte bcd2byte(byte bcd)
{
return (10* ((bcd & 0xF0) >> 4)) + (bcd & 0x0F);
}
//converts a binary-coded-decimal byte to its decimal equivalent
inline byte byte2bcd(byte bite)
{
return ((bite / 10) << 4) | (bite % 10);
}
void rtrim(char *str)
{
str += strlen(str); //now points to the null character at the end of the string
str--;
for (;;)
{
if ((*str == ' ') || (*str == '\t') || (*str == '\n'))
*str-- = 0;
else
break;
}
}
char *ucase(char *str)
{
char *ret = str;
for (;;)
{
if (*str == 0)
break;
if ((*str >= 'a') && (*str <= 'z'))
*str = (*str) - 32;
str++;
}
return ret;
}
char *lcase(char *str)
{
char *ret = str;
for (;;)
{
if (*str == 0)
break;
if ((*str >= 'A') && (*str <= 'Z'))
*str = (*str) + 32;
str++;
}
return ret;
}
//Re-maps the Programmable Interrupr Controllers so IRQ0->pic1 base address, IRG8->pic2 base address
void remap_pics(int pic1, int pic2) void remap_pics(int pic1, int pic2)
{ {
byte a1, a2; byte a1, a2;
a1 = inportb(PIC1_DATA); a1 = inportb(PIC1_DATA); //0x21
a2 = inportb(PIC2_DATA); a2 = inportb(PIC2_DATA); //0xA1
outportb(PIC1_COMMAND, ICW1_INIT+ICW1_ICW4); outportb(PIC1_COMMAND, ICW1_INIT+ICW1_ICW4); //0x20, 0x10+0x01 00010001b
outportb(PIC2_COMMAND, ICW1_INIT+ICW1_ICW4); outportb(PIC2_COMMAND, ICW1_INIT+ICW1_ICW4); //0xA0, 0x10+0x01 00010001b
outportb(PIC1_DATA, pic1); outportb(PIC1_DATA, pic1); //0x21, pic1
outportb(PIC2_DATA, pic2); outportb(PIC2_DATA, pic2); //0xA1, pic2
outportb(PIC1_DATA, 4); outportb(PIC1_DATA, 4); //0x21, 0x04 00000100b
outportb(PIC2_DATA, 2); outportb(PIC2_DATA, 2); //0xA1, 0x02 00000010b
outportb(PIC1_DATA, ICW4_8086); outportb(PIC1_DATA, ICW4_8086); //0x21, 0x01 00000001b
outportb(PIC2_DATA, ICW4_8086); outportb(PIC2_DATA, ICW4_8086); //0xA1, 0x01 00000001b
outportb(PIC1_DATA, a1);
outportb(PIC2_DATA, a2);
};
outportb(PIC1_DATA, a1); //0x21
outportb(PIC2_DATA, a2); //0xA1
}
//Masks interrupts on first Programmable Interrupt Controller
inline void pic1_mask(byte mask)
{
outportb(PIC1_DATA, mask); //0x21, maskfield *OCW1*
}
//Masks interrupts on second Programmable Interrupt Controller
inline void pic2_mask(byte mask)
{
outportb(PIC2_DATA, mask); //0xA1, maskfield *OCW1*
}
//Restarts the computer
inline void restart() inline void restart()
{ {
enable_ints();
byte temp;
do
{
temp = inportb(0x64);
if (temp & 1)
inportb(0x60);
} while(temp & 2);
outportb (0x64, 0xfe); outportb (0x64, 0xfe);
for (;;) for (;;)
{ {
} }
} }
//Halts (freezes) the computer
inline void halt()
{
asm("cli");
asm("hlt");
while (1)
;
}
//Initializes 8253 Programmable Interrupt Timer
inline void init_timer()
{
//set timer : 2e9c = 100hz
outportb(0x43, 0x34);
outportb(0x40, 0x9c); //lsb
outportb(0x40, 0x2e); //msb
}
//Signals an End Of Interrupt signal to the first PIC
inline void eoi() inline void eoi()
{ {
outportb(0x20, 0x20); //EOI outportb(0x20, 0x20);
}
//Signals an End Of Interrupt signal to both the second and first PIC unit
inline void eoi2()
{
outportb(0xA0, 0x20);
outportb(0x20, 0x20);
}
//Returns the size of the kernel (code & data)
// - this does not include the bss section
// - this should be 4kb aligned per the linker script
// - this should be the size of kernel.bin
inline dword kernel_size()
{
return (dword)(&_bss)-(dword)(&_code);
}
//These functions are for reading and writing various values stored on the CMOS Real Time Clock
byte rtc_readDay()
{
outportb(0x70, 7);
return bcd2byte(inportb(0x71));
}
byte rtc_readMonth()
{
outportb(0x70, 8);
return bcd2byte(inportb(0x71));
}
byte rtc_readYear()
{
outportb(0x70, 9);
return bcd2byte(inportb(0x71));
}
byte rtc_readSecond()
{
outportb(0x70, 0);
return bcd2byte(inportb(0x71));
}
byte rtc_readMinute()
{
outportb(0x70, 2);
return bcd2byte(inportb(0x71));
}
byte rtc_readHour()
{
outportb(0x70, 4);
return bcd2byte(inportb(0x71));
}
void rtc_setDay(byte day)
{
outportb(0x70, 7);
outportb(0x71, byte2bcd(day));
}
void rtc_setMonth(byte month)
{
outportb(0x70, 8);
outportb(0x71, byte2bcd(month));
}
void rtc_setYear(byte year)
{
outportb(0x70, 9);
outportb(0x71, byte2bcd(year));
}
void rtc_setSecond(byte second)
{
outportb(0x70, 0);
outportb(0x71, byte2bcd(second));
}
void rtc_setMinute(byte minute)
{
outportb(0x70, 2);
outportb(0x71, byte2bcd(minute));
}
void rtc_setHour(byte hour)
{
outportb(0x70, 4);
outportb(0x71, byte2bcd(hour));
} }
@@ -72,3 +273,4 @@ inline void eoi()
+470
View File
@@ -0,0 +1,470 @@
; asmfuncs.asm
; Josh Holtrop
; Created: 10/23/03
; Modified: 12/25/03
[extern _putc]
[extern _console_memory]
[extern _cursorPosition]
[extern _video_drawConsole]
[extern _videoMode]
%macro jzfar 1
jnz %%skip
jmp %1
%%skip:
%endmacro
;stores the parameter to the CR0 register
;extern dword write_cr0(dword cr0);
[global _write_cr0]
_write_cr0:
push ebp
mov ebp, esp
mov eax, [ebp+8]
mov cr0, eax
pop ebp
ret
;returns the value in the CR0 register
;extern dword read_cr0();
[global _read_cr0]
_read_cr0:
mov eax, cr0;
ret
;stores the parameter to the CR3 register
;extern dword write_cr3(dword cr3);
[global _write_cr3]
_write_cr3:
push ebp
mov ebp, esp
mov eax, [ebp+8]
mov cr3, eax
pop ebp
ret
;returns the value in the CR2 register
;extern dword read_cr2();
[global _read_cr2]
_read_cr2:
mov eax, cr2;
ret
;returns the value in the CR3 register
;extern dword read_cr3();
[global _read_cr3]
_read_cr3:
mov eax, cr3;
ret
;compares one string to another
;returns 0 if the strings are different
;extern dword strcmp(char *str1, char *str2);
[global _strcmp]
_strcmp:
push ebp
mov ebp, esp
push esi
push edi
mov esi, [ebp+8]
mov edi, [ebp+12]
strcmp_loop1:
lodsb
mov ah, [edi]
inc edi
cmp ah, al
jnz strcmp_ne
or al, al
jz strcmp_e
jmp strcmp_loop1
strcmp_e:
mov eax, 1
jmp short strcmp_done
strcmp_ne:
xor eax, eax
strcmp_done:
pop edi
pop esi
pop ebp
ret
;copies a string from the source to the destination parameter
;extern void strcpy(char *dest, char *src);
[global _strcpy]
_strcpy:
push ebp
mov ebp, esp
push esi
push edi
mov edi, [ebp+8]
mov esi, [ebp+12]
strcpyloop:
lodsb
stosb
or al, al
jnz strcpyloop
pop edi
pop esi
pop ebp
ret
;copies memory of n bytes from src to destination
;extern void memcpy(dword dest, dword src, dword n);
[global _memcpy]
_memcpy:
push ebp
mov ebp, esp
push esi
push edi
push ecx
mov edi, [ebp+8]
mov esi, [ebp+12]
mov ecx, [ebp+16]
rep movsb
pop ecx
pop edi
pop esi
pop ebp
ret
;returns the number of characters in a string
;extern dword strlen(char *str);
[global _strlen]
_strlen:
push ebp
mov ebp, esp
push esi
push ebx
mov esi, [ebp+8]
xor ebx, ebx
strlenloop:
lodsb
or al, al
jz strlendone
inc ebx
jmp strlenloop
strlendone:
mov eax, ebx
pop ebx
pop esi
pop ebp
ret
;this function invalidates the page directory/table entry that
; would be used to access the memory address given in the parameter
;extern void invlpg(dword addr);
[global _invlpg]
_invlpg:
mov eax, [esp+4]
invlpg [eax]
ret
;
;void writeCursorPosition(word pos)
;
[global _writeCursorPosition]
_writeCursorPosition:
push ebp
mov ebp, esp
push eax
push ebx
push edx
mov eax, [ebp+8] ;cursor position in ax
mov bl, al
mov dx, 0x03D4
mov al, 0x0E
out dx, al
inc dx
mov al, ah
out dx, al
dec dx
mov al, 0x0F
out dx, al
inc dx
mov al, bl
out dx, al
pop edx
pop ebx
pop eax
pop ebp
ret
;
;word getCursorPosition()
;
[global _getCursorPosition]
_getCursorPosition:
push ebx
push edx
xor eax, eax
mov dx, 0x03D4
mov al, 0x0E
out dx, al
inc dx
in al, dx
mov bl, al
dec dx
mov al, 0x0F
out dx, al
inc dx
in al, dx
mov ah, bl
pop edx
pop ebx
ret
;
;void console_scroll()
;
[global _console_scroll]
_console_scroll:
pusha
mov esi, _console_memory+160
mov edi, _console_memory
mov ecx, 960 ;(2000-80)/2
rep movsd
mov ax, 0x0720
mov ecx, 80
rep stosw
mov esi, _console_memory
mov edi, 0xC00B8000
mov ecx, 1000
rep movsd
mov eax, [_videoMode]
cmp eax, 0
jz _console_scroll_end
call _video_drawConsole
_console_scroll_end:
popa
ret
;
;void console_cls()
;
[global _console_cls]
_console_cls:
pusha
mov edi, _console_memory
mov ax, 0x0720
mov ecx, 2000
rep stosw
push dword 0
call _writeCursorPosition
add esp, 4
mov [_cursorPosition], dword 0
mov esi, _console_memory
mov edi, 0xC00B8000
mov ecx, 1000
rep movsd
popa
ret
;
;int puts(char *str)
;
[global _puts]
_puts:
push ebp
mov ebp, esp
push esi
push eax
mov esi, [ebp+8] ;esi = to string
puts_loop:
lodsb
cmp al, 0
jz puts_done
push eax
call _putc
add esp, 4
jmp puts_loop
puts_done:
pop eax
pop esi
pop ebp
ret
[global _putDecu]
_putDecu:
push ebp
mov ebp, esp
sub esp, 24
mov DWORD [ebp-4], 1
mov BYTE [ebp-5], 0
L2:
mov edx, DWORD [ebp+8]
mov eax, -858993459
mul edx
mov eax, edx
shr eax, 3
cmp eax, DWORD [ebp-4]
jae L4
jmp L3
L4:
mov eax, DWORD [ebp-4]
mov edx, eax
sal edx, 2
add edx, eax
lea eax, [edx+edx]
mov DWORD [ebp-4], eax
jmp L2
L3:
nop
L5:
cmp DWORD [ebp-4], 1
ja L7
jmp L6
L7:
mov edx, DWORD [ebp+8]
mov eax, edx
mov edx, 0
div DWORD [ebp-4]
mov DWORD [ebp-12], eax
mov al, BYTE [ebp-12]
mov BYTE [ebp-5], al
mov eax, 0
mov al, BYTE [ebp-5]
imul eax, DWORD [ebp-4]
sub DWORD [ebp+8], eax
mov edx, DWORD [ebp-4]
mov eax, -858993459
mul edx
mov eax, edx
shr eax, 3
mov DWORD [ebp-4], eax
lea eax, [ebp-5]
add BYTE [eax], 48
sub esp, 12
mov eax, 0
mov al, BYTE [ebp-5]
push eax
call _putc
add esp, 16
jmp L5
L6:
sub esp, 12
mov al, BYTE [ebp+8]
add eax, 48
and eax, 255
push eax
call _putc
add esp, 16
leave
ret
[global _putDec]
_putDec:
push ebp
mov ebp, esp
sub esp, 24
cmp DWORD [ebp+8], 0
jns L9
sub esp, 12
push 45
call _putc
add esp, 16
neg DWORD [ebp+8]
L9:
mov DWORD [ebp-4], 1
mov BYTE [ebp-5], 0
L10:
mov eax, DWORD [ebp+8]
cmp eax, DWORD [ebp-4]
jae L12
jmp L11
L12:
mov eax, DWORD [ebp-4]
mov edx, eax
sal edx, 2
add edx, eax
lea eax, [edx+edx]
mov DWORD [ebp-4], eax
jmp L10
L11:
mov edx, DWORD [ebp-4]
mov eax, -858993459
mul edx
mov eax, edx
shr eax, 3
mov DWORD [ebp-4], eax
L13:
cmp DWORD [ebp-4], 1
ja L15
jmp L14
L15:
mov edx, DWORD [ebp+8]
mov eax, edx
mov edx, 0
div DWORD [ebp-4]
mov DWORD [ebp-12], eax
mov al, BYTE [ebp-12]
mov BYTE [ebp-5], al
mov eax, 0
mov al, BYTE [ebp-5]
imul eax, DWORD [ebp-4]
sub DWORD [ebp+8], eax
mov edx, DWORD [ebp-4]
mov eax, -858993459
mul edx
mov eax, edx
shr eax, 3
mov DWORD [ebp-4], eax
lea eax, [ebp-5]
add BYTE [eax], 48
sub esp, 12
mov eax, 0
mov al, BYTE [ebp-5]
push eax
call _putc
add esp, 16
jmp L13
L14:
sub esp, 12
mov al, BYTE [ebp+8]
add eax, 48
and eax, 255
push eax
call _putc
add esp, 16
leave
ret
Executable
+12
View File
@@ -0,0 +1,12 @@
@echo off
echo Backing up to .\Backup\%1
mkdir .\Backup\%1
copy *.h .\Backup\%1
copy *.c .\Backup\%1
copy *.inc .\Backup\%1
copy *.asm .\Backup\%1
copy *.ld .\Backup\%1
copy *.bat .\Backup\%1
+2 -2
View File
@@ -1,12 +1,12 @@
%define VERSION "0.1.2" ;HOS version %define VERSION "0.13" ;HOS version
%define BOOT_FAT_SEG 0x07E0 ;right after boot sector %define BOOT_FAT_SEG 0x07E0 ;right after boot sector
%define BOOT_ROOT_SEG 0x0900 ;right after FAT %define BOOT_ROOT_SEG 0x0900 ;right after FAT
%define BOOT_KERNEL_SEG 0x0AC0 ;right after ROOT_DIR %define BOOT_KERNEL_SEG 0x0AC0 ;right after ROOT_DIR
%define BOOT_STAGE2_SEG 0x0B00 ;right after KERNEL_SEG %define BOOT_STAGE2_SEG 0x0B00 ;right after KERNEL_SEG
%define BOOT_STAGE2_ADD 0xB000 ;address of stage2 to jump to, org at %define BOOT_STAGE2_ADD 0xB000 ;address of stage2 to jump to, org at
%define BOOT_KERNEL_ADD 0x100000 ;final pmode kernel destination - physical %define BOOT_KERNEL_ADD 0x106000 ;final pmode kernel destination - physical
%define BOOT_RD_ADD 0x200000 ;2mb for ram disk %define BOOT_RD_ADD 0x200000 ;2mb for ram disk
%define BOOT_DATA_SEG 0x9000 ;data gathered by stage2 loader goes here %define BOOT_DATA_SEG 0x9000 ;data gathered by stage2 loader goes here
Executable
+2
View File
@@ -0,0 +1,2 @@
nasmw -f aout -o ks.o -l .\lst\kernel.lst kernel.asm
Executable
+1
View File
@@ -0,0 +1 @@
gcc -ffreestanding -fno-builtin -nostdlib -nodefaultlibs -c kernel.c -o kernel.o
Executable
+1
View File
@@ -0,0 +1 @@
nasmw -f aout -o asmfuncs.o -l .\lst\asmfuncs.lst asmfuncs.asm
Executable
+1
View File
@@ -0,0 +1 @@
copy kernel.bin a:
Executable
+2
View File
@@ -0,0 +1,2 @@
rem rawrite -f stage1.bin -d a -n
partcopy stage1.bin 0 200 -f0
Executable
+1
View File
@@ -0,0 +1 @@
copy stage2.bin a:
Executable
+1
View File
@@ -0,0 +1 @@
nasmw -f bin -o stage1.bin -l .\lst\stage1.lst stage1.asm
Executable
+1
View File
@@ -0,0 +1 @@
nasmw -f bin -o stage2.bin -l .\lst\stage2.lst stage2.asm
-7
View File
@@ -1,7 +0,0 @@
typedef unsigned int dword;
typedef unsigned short word;
typedef unsigned char byte;
+345
View File
@@ -0,0 +1,345 @@
// fat12.c
// Author: Josh Holtrop
// Created: 01/04/04
// Modified: 01/14/04
byte *fat12_readFile(char *fileName, DiskDevice *dd)
{
char *fileNameUCase = malloc(strlen(fileName) + 1);
strcpy(fileNameUCase, fileName);
ucase(fileNameUCase);
dword iMadeClusterChain = getClusterChain(dd);
Fat12Entry fe;
if (fat12_getFileHandle(fileNameUCase, dd, &fe))
{
free(fileNameUCase);
if (iMadeClusterChain)
{
free(clusterChain);
clusterChain = 0;
}
return 0;
}
byte *fp = (byte *)fat12_readClusterChain(dd, &fe);
free(fileNameUCase);
if (iMadeClusterChain)
{
free(clusterChain);
clusterChain = 0;
}
return fp;
}
dword fat12_getFileHandle(char *fileName, DiskDevice *dd, Fat12Entry *destination)
{
if (strlen(fileName) < 1)
return 1;
if (fileName[strlen(fileName)-1] == '/')
return 2;
dword iMadeClusterChain = getClusterChain(dd);
int fileName_length = strlen(fileName);
int a;
int entries = 1;
for (a = 0; a < fileName_length; a++)
{
if (fileName[a] == '/')
{
fileName[a] = 0;
entries++;
}
}
char *pointer = fileName;
Fat12Entry *workingDirectory = 0;
Fat12Entry workingDir;
for (a = 0; a < (entries - 1); a++)
{
if (fat12_getDirectoryHandle(pointer, dd, workingDirectory, &workingDir)) //an error occurred if this returns nonzero
{
if (iMadeClusterChain)
{
free(clusterChain);
clusterChain = 0;
}
return 3;
}
workingDirectory = &workingDir;
for (;;) //advance to the next dir name
{
pointer++;
if (*pointer == 0)
{
pointer++;
break;
}
}
}
if (fat12_getFileHandleInDirectory(pointer, dd, workingDirectory, destination)) //an error occurred if this returns nonzero
{
if (iMadeClusterChain)
{
free(clusterChain);
clusterChain = 0;
}
return 4;
}
if (iMadeClusterChain)
{
free(clusterChain);
clusterChain = 0;
}
return 0;
}
dword fat12_getFileHandleInDirectory(char *fileName, DiskDevice *dd, Fat12Entry *currDir, Fat12Entry *destination)
{
if (!currDir) // we are working in the root directory
{
Fat12Entry *rootDir = malloc(14*512); //root directory is 14 sectors long
vfs_readSector(dd, 19, (byte *)rootDir, 14);
int a;
for (a = 0; a < 224; a++) //224 max root directory entries in 14 sectors
{
if (rootDir[a].fileName[0] == 0)
break;
if ((byte)rootDir[a].fileName[0] != 0xE5)
{
if ((rootDir[a].attributes & 0x18) == 0) //this entry is a directory
{
char dirName[9];
char dirExt[4];
memcpy(dirName, rootDir[a].fileName, 8);
dirName[8] = 0;
memcpy(dirExt, rootDir[a].ext, 3);
dirExt[3] = 0;
rtrim(dirName);
rtrim(dirExt);
char dirWhole[14];
strcpy(dirWhole, dirName);
if (strlen(dirExt) > 0) //the directory has an extension
{
strcat(dirWhole, ".");
strcat(dirWhole, dirExt);
}
if (strcmp(dirWhole, fileName)) //the entry found is a match
{
free(rootDir);
*destination = rootDir[a];
return 0;
}
}
}
}
free(rootDir);
return 1; //no match found
}
dword retVal = 2;
dword iMadeClusterChain = getClusterChain(dd);
Fat12Entry *subDirectory = fat12_readClusterChain(dd, currDir);
if (!subDirectory)
return 5;
dword numberOfClusters = fat12_readClusterChainCount(dd, currDir);
int a;
for (a = 0; a < (numberOfClusters * 16); a++)
{
if (subDirectory[a].fileName[0] == 0)
break;
if ((byte)subDirectory[a].fileName[0] != 0xE5)
{
if ((subDirectory[a].attributes & 0x18) == 0) //this entry is a directory
{
char dirName[9];
char dirExt[4];
memcpy(dirName, subDirectory[a].fileName, 8);
dirName[8] = 0;
memcpy(dirExt, subDirectory[a].ext, 3);
dirExt[3] = 0;
rtrim(dirName);
rtrim(dirExt);
char dirWhole[14];
strcpy(dirWhole, dirName);
if (strlen(dirExt) > 0) //the directory has an extension
{
strcat(dirWhole, ".");
strcat(dirWhole, dirExt);
}
if (strcmp(dirWhole, fileName)) //the entry found is a match
{
*destination = subDirectory[a];
retVal = 0;
break;
}
}
}
}
free(subDirectory);
if (iMadeClusterChain)
{
free(clusterChain);
clusterChain = 0;
}
return retVal;
}
dword fat12_getDirectoryHandle(char *directory, DiskDevice *dd, Fat12Entry *currDir, Fat12Entry *destination)
{
if (!currDir) // we are working in the root directory
{
Fat12Entry *rootDir = malloc(14*512); //root directory is 14 sectors long
vfs_readSector(dd, 19, (byte *)rootDir, 14);
int a;
for (a = 0; a < 224; a++) //224 max root directory entries in 14 sectors
{
if (rootDir[a].fileName[0] == 0)
break;
if ((byte)rootDir[a].fileName[0] != 0xE5)
{
if ((rootDir[a].attributes & 0x18) == 0x10) //this entry is a directory
{
char dirName[9];
char dirExt[4];
memcpy(dirName, rootDir[a].fileName, 8);
dirName[8] = 0;
memcpy(dirExt, rootDir[a].ext, 3);
dirExt[3] = 0;
rtrim(dirName);
rtrim(dirExt);
char dirWhole[14];
strcpy(dirWhole, dirName);
if (strlen(dirExt) > 0) //the directory has an extension
{
strcat(dirWhole, ".");
strcat(dirWhole, dirExt);
}
if (strcmp(dirWhole, directory)) //the entry found is a match
{
free(rootDir);
*destination = rootDir[a];
return 0;
}
}
}
}
free(rootDir);
return 1; //no match found
}
dword retVal = 2;
dword iMadeClusterChain = getClusterChain(dd);
Fat12Entry *subDirectory = fat12_readClusterChain(dd, currDir);
if (!subDirectory)
return 5;
dword numberOfClusters = fat12_readClusterChainCount(dd, currDir);
int a;
for (a = 0; a < (numberOfClusters * 16); a++)
{
if (subDirectory[a].fileName[0] == 0)
break;
if ((byte)subDirectory[a].fileName[0] != 0xE5)
{
if ((subDirectory[a].attributes & 0x18) == 0x10) //this entry is a directory
{
char dirName[9];
char dirExt[4];
memcpy(dirName, subDirectory[a].fileName, 8);
dirName[8] = 0;
memcpy(dirExt, subDirectory[a].ext, 3);
dirExt[3] = 0;
rtrim(dirName);
rtrim(dirExt);
char dirWhole[14];
strcpy(dirWhole, dirName);
if (strlen(dirExt) > 0) //the directory has an extension
{
strcat(dirWhole, ".");
strcat(dirWhole, dirExt);
}
if (strcmp(dirWhole, directory)) //the entry found is a match
{
*destination = subDirectory[a];
retVal = 0;
break;
}
}
}
}
free(subDirectory);
if (iMadeClusterChain)
{
free(clusterChain);
clusterChain = 0;
}
return retVal;
}
Fat12Entry *fat12_readClusterChain(DiskDevice *dd, Fat12Entry *directory)
{
dword numberOfClusters = fat12_readClusterChainCount(dd, directory);
if (numberOfClusters == 0)
return 0;
byte *bp = malloc(numberOfClusters * 512);
Fat12Entry *retVal = (Fat12Entry *)bp;
dword cluster = directory->firstCluster;
while (cluster < 0xFF0)
{
vfs_readSector(dd, cluster + 31, bp, 1);
cluster = fat12_getNextCluster(cluster);
bp += 512;
}
return retVal;
}
dword fat12_readClusterChainCount(DiskDevice *dd, Fat12Entry *directory)
{
dword numberOfClusters = 0;
dword cluster = directory->firstCluster;
if (cluster == 0)
return 0;
while (cluster < 0xFF0)
{
cluster = fat12_getNextCluster(cluster);
numberOfClusters++;
}
return numberOfClusters;
}
dword fat12_getNextCluster(dword thisCluster)
{
dword nextCluster = *(word *)((dword)clusterChain + ((thisCluster * 3) >> 1));
if (thisCluster & 0x01) //this is an odd cluster
return nextCluster >> 4;
else //this is an even cluster
return nextCluster & 0x0FFF;
}
dword fat12_getFileSize(char *fileName, DiskDevice *dd)
{
Fat12Entry fe;
if (fat12_getFileHandle(fileName, dd, &fe))
return 0xFFFFFFFF;
return fe.fileSize;
}
dword getClusterChain(DiskDevice *dd)
{
if (!clusterChain)
{
clusterChain = malloc(9*512); //9 sectors for File Allocation Table (cluster chain)
vfs_readSector(dd, 1, clusterChain, 9); //sectors 1 through 9 contain the first FAT
return 1; //this call created the cluster chain
}
else
return 0; //this call did not create the cluster chain
}
+58
View File
@@ -0,0 +1,58 @@
// fat12.h
// Author: Josh Holtrop
// Created: 01/04/04
typedef struct {
char fileName[8];
char ext[3];
byte attributes;
dword createTime;
word createDate;
word accessDate;
word unused0;
word modifiedDate;
word modifiedTime;
word firstCluster;
dword fileSize;
} __attribute__((packed)) Fat12Entry;
typedef struct {
byte jump[3];
byte sysName[8];
word bytesPerSector;
byte sectorsPerCluster;
word reservedSectors;
byte FATcount;
word maxRootEntries;
word totalSectors1;
byte mediaDescriptor;
word sectorsPerFAT;
word sectorsPerTrack;
word headCount;
dword hiddenSectors;
dword totalSectors2;
byte driveNumber;
byte reserved1;
byte extBootSignature;
dword volumeSerial;
char volumeLabel[11];
char fileSystemID[8];
} __attribute__((packed)) Fat12BootSector;
byte *fat12_readFile(char *fileName, DiskDevice *dd);
dword fat12_getFileHandle(char *fileName, DiskDevice *dd, Fat12Entry *destination);
dword fat12_getDirectoryHandle(char *directory, DiskDevice *dd, Fat12Entry *currDir, Fat12Entry *destination);
Fat12Entry *fat12_readClusterChain(DiskDevice *dd, Fat12Entry *directory);
dword fat12_getFileHandleInDirectory(char *fileName, DiskDevice *dd, Fat12Entry *currDir, Fat12Entry *destination);
dword fat12_readClusterChainCount(DiskDevice *dd, Fat12Entry *directory);
dword fat12_getFileSize(char *fileName, DiskDevice *dd);
dword getClusterChain(DiskDevice *dd);
dword fat12_getNextCluster(dword thisCluster);
byte *clusterChain = 0;
+9
View File
@@ -0,0 +1,9 @@
//fdc.c
//Author: Josh Holtrop
//Date: 10/30/03
inline void fdc_sendDOR(byte dor)
{
outportb(FDC_DOR, dor);
}
+12
View File
@@ -0,0 +1,12 @@
//fdc.h
//Author: Josh Holtrop
//Date: 10/30/03
#define FDC_DOR 0x3f2
#define FDC_MSR 0x3f4
inline void fdc_sendDOR(byte dor);
+30 -5
View File
@@ -1,19 +1,44 @@
//functions.h //functions.h
//05/07/03 Josh Holtrop //05/07/03 Josh Holtrop
//for HOS //for HOS
//Modified: 10/30/03
extern dword _code;
extern dword _bss;
extern dword _end;
inline void outportb(unsigned int port, unsigned char value); inline void outportb(unsigned int port, unsigned char value);
inline void outportw(unsigned int port, unsigned int value); inline void outportw(unsigned int port, unsigned int value);
inline byte inportb(unsigned short port); inline byte inportb(unsigned short port);
void enable_ints(); inline void enable_ints();
void disable_ints(); inline void disable_ints();
inline void restart(); inline void restart();
inline void halt();
void remap_pics(int pic1, int pic2); void remap_pics(int pic1, int pic2);
inline void pic1_mask(byte mask);
inline void pic2_mask(byte mask);
inline void eoi(); inline void eoi();
inline void eoi2();
inline dword kernel_size();
inline void init_timer();
char *strcat(char *dest, char *src);
void rtrim(char *str);
char *ucase(char *str);
char *lcase(char *str);
inline byte bcd2byte(byte bcd);
inline byte byte2bcd(byte bite);
byte rtc_readDay();
byte rtc_readMonth();
byte rtc_readYear();
byte rtc_readSecond();
byte rtc_readMinute();
byte rtc_readHour();
void rtc_setDay(byte dat);
void rtc_setMonth(byte month);
void rtc_setYear(byte year);
void rtc_setSecond(byte second);
void rtc_setMinute(byte minute);
void rtc_setHour(byte hour);
Executable
+1
View File
@@ -0,0 +1 @@
gcc -S kernel.c -masm=intel -fno-builtin
+5 -2
View File
@@ -1,8 +1,11 @@
;gdt.inc
;Author: Josh Holtrop
;for HOS
;Modified: 10/30/03
gdtr: gdtr:
dw gdt_end-gdt-1 dw gdt_end-gdt-1
dd GDT dd GDT_P
gdt: gdt:
dd 0 dd 0
dd 0 dd 0
Executable
+1
View File
@@ -0,0 +1 @@
partcopy -f0 0 168000 flop.img
+27 -2
View File
@@ -1,11 +1,16 @@
;idt.inc
;Author: Josh Holtrop
;for HOS
;Modified: 10/30/03
idtr: idtr:
dw 50*8-1 ;size of idt dw 50*8-1 ;size of idt
dd IDT ;address of idt dd IDT_V ;address of idt
%macro isr_label 1 %macro isr_label 1
isr_%1: isr_%1:
push eax
mov eax, %1 mov eax, %1
jmp isr_main jmp isr_main
%endmacro %endmacro
@@ -62,6 +67,9 @@ isr_label 48
isr_label 49 isr_label 49
isr_main: isr_main:
cmp eax, 0x30
jz isr_syscall
pusha pusha
push ds push ds
push es push es
@@ -75,10 +83,27 @@ isr_main:
pop es pop es
pop ds pop ds
popa popa
pop eax
iret iret
isr_syscall:
pop eax ;syscall function number
pusha
push ds
push es
push ebx
call _putc
add esp, 4
pop es
pop ds
popa
iret
-530
View File
@@ -1,530 +0,0 @@
%macro jzfar 1
jnz %%skip
jmp %1
%%skip:
%endmacro
[global _writeCursorPosition]
[global _getCursorPosition]
[global _putc]
[global _puts]
[global _printf]
[global _console_scroll]
[global _console_cls]
[global _putHex]
[global _putDec]
[global _putDecu]
;
;void writeCursorPosition(word pos)
;
_writeCursorPosition:
push ebp
mov ebp, esp
push ebx
push edx
mov eax, [ebp+8] ;cursor position in ax
mov bl, al
mov dx, 0x03D4
mov al, 0x0E
out dx, al
inc dx
mov al, ah
out dx, al
dec dx
mov al, 0x0F
out dx, al
inc dx
mov al, bl
out dx, al
pop edx
pop ebx
pop ebp
ret
;
;word getCursorPosition()
;
_getCursorPosition:
push ebx
push edx
xor eax, eax
mov dx, 0x03D4
mov al, 0x0E
out dx, al
inc dx
in al, dx
mov bl, al
dec dx
mov al, 0x0F
out dx, al
inc dx
in al, dx
mov ah, bl
pop edx
pop ebx
ret
;
;int putc(int chr)
;
_putc:
push ebp
mov ebp, esp
push ebx
push ecx
push edx
call _getCursorPosition
mov ebx, eax
mov ecx, ebx
mov eax, [ebp+8] ;al=character
cmp al, 10 ;newline
jz putc_newline
cmp al, 9 ;tab
jz putc_tab
shl ebx, 1
add ebx, 0xb8000
mov ah, 0x07
mov [ebx], ax
mov eax, ecx
inc eax
cmp eax, 2000
jnz putc_writeit2
call _console_scroll
mov eax, 2000-80
putc_writeit2:
push eax
call _writeCursorPosition
add esp, 4
jmp putc_done
putc_newline:
mov eax, ebx ;eax = cursor position
mov ebx, 80
xor edx, edx
div bx ;ax=dx:ax/bx, dx=remainder
mov bx, 80
sub bx, dx
mov eax, ecx
add eax, ebx ;eax = new cursor position
cmp eax, 2000
jnz putc_newline_writeit2
call _console_scroll
mov eax, 2000-80 ;beginning of last row
putc_newline_writeit2:
push eax
call _writeCursorPosition
add esp, 4
jmp putc_done
putc_tab:
mov eax, ebx ;eax = cursor position
mov ebx, 8
div bl ;al=ax/bl, ah=remainder
xor edx, edx
mov dl, ah
mov bx, 8
sub bx, dx
mov eax, ecx
add eax, ebx ;eax = new cursor position
cmp eax, 2000
jnz putc_tab_writeit2
call _console_scroll
mov eax, 2000-80 ;beginning of last row
putc_tab_writeit2:
push eax
call _writeCursorPosition
add esp, 4
putc_done:
pop edx
pop ecx
pop ebx
pop ebp
ret
;
;void printf(char *fmt, ... )
;
_printf:
push ebp
mov ebp, esp
pusha
mov ebx, [ebp+8] ;ebx = in format string
mov esi, ebp
add esi, 12 ;esi = to next variable arg
xor ecx, ecx ;ecx used if we encounter a '%'
printf_loop:
mov al, [ebx]
inc ebx
cmp al, 0
jzfar printf_done
cmp al, '%'
jzfar printf_percent
cmp ecx, 1
jz printf_special
push eax
call _putc
add esp, 4
jmp printf_loop
printf_special:
xor ecx, ecx
cmp al, 'd'
jz printf_decimal
cmp al, 'u'
jz printf_decimalu
cmp al, 'x'
jz printf_hex
cmp al, '%'
jz printf_ppercent
cmp al, 's'
jz printf_string
cmp al, 'c'
jz printf_char
jmp printf_special_done
printf_decimal:
mov eax, [esi]
push eax
call _putDec
add esp, 4
jmp printf_special_done
printf_decimalu:
mov eax, [esi]
push eax
call _putDecu
add esp, 4
jmp printf_special_done
printf_hex:
mov eax, [esi]
push eax
call _putHex
add esp, 4
jmp printf_special_done
printf_ppercent:
push eax
call _putc
add esp, 4
jmp printf_special_done
printf_string:
mov eax, [esi]
push eax
call _puts
add esp, 4
jmp printf_special_done
printf_char:
mov eax, [esi]
push eax
call _putc
add esp, 4
jmp printf_special_done
printf_special_done
add esi, 4 ;point to next extra argument
jmp printf_loop
printf_percent:
mov ecx, 1
jmp printf_loop
printf_done:
popa
pop ebp
ret
;
;void console_scroll()
;
_console_scroll:
pusha
mov esi, 0xb8000+160
mov edi, 0xb8000
mov ecx, 960 ;(2000-80)/2
console_scroll_loop:
lodsd
stosd
loop console_scroll_loop
mov ax, 0x0720
mov ecx, 80
console_scroll_loop2:
stosw
loop console_scroll_loop2
popa
ret
;
;void console_cls()
;
_console_cls:
pusha
mov edi, 0xb8000
mov ax, 0x0720
mov ecx, 2000
console_cls_loop:
stosw
loop console_cls_loop
push dword 0
call _writeCursorPosition
add esp, 4
popa
ret
;
;int putHex(dword number)
;
_putHex:
push ebp
mov ebp, esp
pusha
mov eax, [ebp+8] ;eax = number to print
xor ebx, ebx ;we have not printed a character yet
mov ecx, 8 ;counter for number of characters
putHex_loop:
push eax
push ecx
dec ecx
shl ecx, 2 ;edx=counter*4 (amount to shift by)
shr eax, cl
and eax, 0x0F
cmp cl, 0
jz putHex_notzero ;if number is 0
cmp al, 0
jnz putHex_notzero
cmp bl, 0
jz putHex_loop_end
putHex_notzero:
mov bl, 1
add eax, '0'
cmp eax, '9'
jbe putHex_dontadjust
add eax, 'A'-'9'-1
putHex_dontadjust:
push eax
call _putc
add esp, 4
putHex_loop_end:
pop ecx
pop eax
loop putHex_loop
popa
pop ebp
ret
;
;int puts(char *str)
;
_puts:
push ebp
mov ebp, esp
push esi
push eax
mov esi, [ebp+8] ;esi = to string
puts_loop:
lodsb
cmp al, 0
jz puts_done
push eax
call _putc
add esp, 4
jmp puts_loop
puts_done:
pop eax
pop esi
pop ebp
ret
_putDecu:
push ebp
mov ebp, esp
sub esp, 24
mov DWORD [ebp-4], 1
mov BYTE [ebp-5], 0
L2:
mov edx, DWORD [ebp+8]
mov eax, -858993459
mul edx
mov eax, edx
shr eax, 3
cmp eax, DWORD [ebp-4]
jae L4
jmp L3
L4:
mov eax, DWORD [ebp-4]
mov edx, eax
sal edx, 2
add edx, eax
lea eax, [edx+edx]
mov DWORD [ebp-4], eax
jmp L2
L3:
nop
L5:
cmp DWORD [ebp-4], 1
ja L7
jmp L6
L7:
mov edx, DWORD [ebp+8]
mov eax, edx
mov edx, 0
div DWORD [ebp-4]
mov DWORD [ebp-12], eax
mov al, BYTE [ebp-12]
mov BYTE [ebp-5], al
mov eax, 0
mov al, BYTE [ebp-5]
imul eax, DWORD [ebp-4]
sub DWORD [ebp+8], eax
mov edx, DWORD [ebp-4]
mov eax, -858993459
mul edx
mov eax, edx
shr eax, 3
mov DWORD [ebp-4], eax
lea eax, [ebp-5]
add BYTE [eax], 48
sub esp, 12
mov eax, 0
mov al, BYTE [ebp-5]
push eax
call _putc
add esp, 16
jmp L5
L6:
sub esp, 12
mov al, BYTE [ebp+8]
add eax, 48
and eax, 255
push eax
call _putc
add esp, 16
leave
ret
_putDec:
push ebp
mov ebp, esp
sub esp, 24
cmp DWORD [ebp+8], 0
jns L9
sub esp, 12
push 45
call _putc
add esp, 16
neg DWORD [ebp+8]
L9:
mov DWORD [ebp-4], 1
mov BYTE [ebp-5], 0
L10:
mov eax, DWORD [ebp+8]
cmp eax, DWORD [ebp-4]
jae L12
jmp L11
L12:
mov eax, DWORD [ebp-4]
mov edx, eax
sal edx, 2
add edx, eax
lea eax, [edx+edx]
mov DWORD [ebp-4], eax
jmp L10
L11:
mov edx, DWORD [ebp-4]
mov eax, -858993459
mul edx
mov eax, edx
shr eax, 3
mov DWORD [ebp-4], eax
L13:
cmp DWORD [ebp-4], 1
ja L15
jmp L14
L15:
mov edx, DWORD [ebp+8]
mov eax, edx
mov edx, 0
div DWORD [ebp-4]
mov DWORD [ebp-12], eax
mov al, BYTE [ebp-12]
mov BYTE [ebp-5], al
mov eax, 0
mov al, BYTE [ebp-5]
imul eax, DWORD [ebp-4]
sub DWORD [ebp+8], eax
mov edx, DWORD [ebp-4]
mov eax, -858993459
mul edx
mov eax, edx
shr eax, 3
mov DWORD [ebp-4], eax
lea eax, [ebp-5]
add BYTE [eax], 48
sub esp, 12
mov eax, 0
mov al, BYTE [ebp-5]
push eax
call _putc
add esp, 16
jmp L13
L14:
sub esp, 12
mov al, BYTE [ebp+8]
add eax, 48
and eax, 255
push eax
call _putc
add esp, 16
leave
ret
-18
View File
@@ -1,18 +0,0 @@
#ifndef __HIO_H__
#define __HIO_H__ __HIO_H__
void writeCursorPosition(word pos);
word getCursorPosition();
int putc(byte chr);
int printf(char *fmt, ...);
int puts(char *str);
int putDec(int number);
int putDecu(dword number);
int putHex(dword number);
void console_cls();
void console_scroll();
#endif
+7 -1
View File
@@ -1,5 +1,6 @@
//k_defines.h //k_defines.h
//03/17/03 Josh Holtrop //03/17/03 Josh Holtrop
//Modified: 10/30/03
#define PIC1 0x20 #define PIC1 0x20
#define PIC2 0xA0 #define PIC2 0xA0
@@ -28,7 +29,12 @@
#define YELLOW_TXT 0x0E #define YELLOW_TXT 0x0E
#define BRWHITE_TXT 0x0F #define BRWHITE_TXT 0x0F
#define FREERAM_START 0x268000 #define FREERAM_START 0x368000 // 0x368000 is first available byte (this is right after the initrd @ 2mb, 1440kb.
#define MAX_RAM 0x40000000 //1gb maximum RAM supported
#define PID_KERNEL 0x02 //kernel's PID
#define PID_VMM 0x03
#define PID_USER 0x10000 //user processes' start PID
typedef unsigned char byte; typedef unsigned char byte;
typedef unsigned short word; typedef unsigned short word;
+49 -10
View File
@@ -1,18 +1,56 @@
;kernel.asm
;Author: Josh Holtrop
;Modified: 10/30/03
%include "bootdef.inc" %define GDT_P 0x100000; ;1mb physical - Global Descriptor Table space
%define GDT_V GDT_P+0xC0000000
%define GDT 0x140000 %define IDT_P 0x102000 ;1mb+8kb - Interrupt Descriptor Table space
%define IDT 0x150000 %define IDT_V IDT_P+0xC0000000
%define PDBR_P 0x104000 ;1mb+16kb - Page Directory Base Register (first PD)
%define PDBR_V PDBR_P+0xC0000000
%define LOPT_P 0x105000 ;1mb+20kb - LOw Page Table for mapping first 4mb
%define LOPT_V LOPT_P+0xC0000000
%define KERNEL_P 0x106000 ;1mb+24kb - the kernel's physical address
%define KERNEL_V KERNEL_P+0xC0000000 ;3gb+1mb+24kb, the virtual address of the kernel
[global start] [global start]
[extern _isr] [extern _isr]
[extern _k_init] [extern _k_init]
[extern _putc]
bits 32 bits 32
;This is where the kernel begins execution
;At this point, the temporary gdt is set up to "map" 0xC000_0000 to 0x0.
;We must enable paging with the first 4mb mapped 1:1 virtual:physical
; and with the 4mb starting at 0xC000_0000 mapped to the first 4mb physical.
;Then we can start using our "real" gdt, then unmap the lower 4mb.
start: start:
cli ;if they weren't already off cli ;if they weren't already off
mov edi, GDT
xor eax, eax
mov edi, PDBR_V
mov ecx, 1024 ;clear the PDBR
rep stosd
mov [PDBR_V], dword LOPT_P|0x03 ;store the physical address of the LOw Page Table (read/write, present)
mov [PDBR_V+0xC00], dword LOPT_P|0x03 ;store the physical address of the LOw Page Table (read/write, present)
mov edi, LOPT_V
mov ecx, 1024
mov eax, 0x03 ;starting physical address = 0x0 (read/write, present flags)
fill_lopt_loop: ;fill the page table
stosd
add eax, 4096 ;increment next phsyical address by 4kb
loop fill_lopt_loop
mov eax, PDBR_P
mov cr3, eax ;store the Page Directory Base Address
mov eax, cr0
or eax, 0x80000000 ;set page enable bit
mov cr0, eax ;now paging is active!
mov edi, GDT_V
mov esi, gdt mov esi, gdt
mov ecx, gdt_end-gdt mov ecx, gdt_end-gdt
copy_gdt: copy_gdt:
@@ -20,7 +58,7 @@ copy_gdt:
stosb stosb
loop copy_gdt loop copy_gdt
mov edi, IDT ;destination mov edi, IDT_V ;destination
mov esi, isr_0 ;address of isr0 mov esi, isr_0 ;address of isr0
mov edx, isr_1-isr_0 ;distance between isr labels mov edx, isr_1-isr_0 ;distance between isr labels
mov ecx, 50 ;number of isrlabels mov ecx, 50 ;number of isrlabels
@@ -38,6 +76,7 @@ fill_idt:
mov esi, ebx mov esi, ebx
add esi, edx add esi, edx
loop fill_idt loop fill_idt
mov word [IDT_V+0x30*8+4], 0xEE00 ;interrupt 0x30 has user priviledges
lgdt [gdtr] ;load gdt lgdt [gdtr] ;load gdt
jmp KERNEL_CODE:newgdtcontinue jmp KERNEL_CODE:newgdtcontinue
@@ -48,15 +87,15 @@ newgdtcontinue:
mov gs, ax mov gs, ax
mov fs, ax mov fs, ax
mov ss, ax mov ss, ax
mov esp, 0x1ffffc ;stack just under 2mb, moves downward mov esp, 0xc01ffffc ;stack just under 3gb+2mb, moves downward
lidt [idtr] ;load idt lidt [idtr] ;load idt
call _k_init call _k_init
haltit:
hlt ;halt processor when k_init is done hlt ;halt processor when k_init is done
jmp $ ;shouldn't get here... jmp haltit ;shouldn't get here...
%include "gdt.inc" %include "gdt.inc"
%include "idt.inc" %include "idt.inc"
+105 -57
View File
@@ -1,91 +1,139 @@
//kernel.c //kernel.c
//08/13/03 Josh Holtrop //08/13/03 Josh Holtrop
//Holtrop's Operating System //Holtrop's Operating System
//Version: 0.12
//Modified: 12/30/03
#define VXR video_mode.XResolution #include "k_defines.h" //#DEFINE's for kernel
#define VYR video_mode.YResolution
#include "k_defines.h"
#include "lib/string.h" #include "functions.h" //general functions
#include "lib/io.h" #include "video.h" //video functions
#include "mm.h" //physical memory management functions
#include "functions.h" #include "vmm.h" //virtual memory management & paging functions
#include "video.h" #include "keyboard.h" //generic keyboard driver & functions
#include "mm.h" #include "mouse.h" //generic ps/2 mouse driver & functions
#include "keyboard.h" #include "fdc.h" //Floppy Disk Controller functions
#include "stdfont.h" //Standard font bitmask array
#include "kio.h"
#include "vfs.h"
#include "rd.h"
#include "fat12.h"
void isr(dword num); void isr(dword num);
void k_init(); void k_init();
/* These functions are defined in asmfuncs.asm */
extern dword write_cr0(dword cr0);
extern dword read_cr0();
extern dword write_cr3(dword cr3);
extern dword read_cr2();
extern dword read_cr3();
extern void writeCursorPosition(dword pos);
extern dword getCursorPosition();
extern void console_scroll();
extern void console_cls();
extern int puts(char *str);
extern int putDec(int number);
extern int putDecu(dword number);
extern void strcpy(char *dest, char *src);
extern void memcpy(void *dest, void *src, dword n);
extern dword strlen(char *str);
#include "fat12.c"
#include "rd.c"
#include "vfs.c"
#include "kio.c"
#include "fdc.c"
#include "mouse.c"
#include "keyboard.c" #include "keyboard.c"
#include "mm.c" #include "mm.c"
#include "vmm.c"
#include "functions.c" #include "functions.c"
#include "video.c" #include "video.c"
dword timer = 0; dword timer = 0;
//Main kernel initialization method
void k_init() void k_init()
{ {
remap_pics(0x20, 0x28); // ===== Initialization
//set timer : 2e9c = 100hz fdc_sendDOR(0x0C); //turn off floppy motor!!
outportb(0x43, 0x34);
outportb(0x40, 0x9c); //lsb
outportb(0x40, 0x2e); //msb
video_init((ModeInfoBlock *) 0x90306);
mm_init();
enable_ints();
console_cls(); console_cls();
printf("Memory available to OS: %d MB\n (Bytes: %d)", mm_totalmem/0x100000, mm_totalmem); video_init();
mm_init();
vmm_init();
remap_pics(0x20, 0x28);
init_timer();
mouse_init();
pic1_mask(0); //unmask IRQ's 0-7
pic2_mask(0); //unmask IRQ's 8-15
vfs_init();
enable_ints();
kbd_resetLEDs(); //after enabling interrupts!!
if (videoMode)
{
int p = video_mode.XResolution*video_mode.YResolution-1;
for (; p >= 0; p--)
video_psetp(p, 0x00000044);
video_drawConsole();
}
for (;;) printf("HOS 0.13 - Kernel File Size: %u kb\tData Size: %u bytes\n", kernel_size()>>10, (dword)(&_end)-(dword)(&_code));
printf("%c ", kbdWaitKey()); printf("Memory available to OS: %u MB (%u bytes)\n", mm_megabytes, mm_totalmem);
/* pageblock *pb = first_pageblock; printf("Free memory: %u bytes (%u pages)\n", mm_freemem(), mm_freemem()>>12);
printf("%d/%d/%d\t%d:%d:%d\n", rtc_readMonth(), rtc_readDay(), rtc_readYear(), rtc_readHour(), rtc_readMinute(), rtc_readSecond());
printf("Root Directory: %s/\n", rootDevice->id);
/* int a;
byte *addr = 0;
for (a = 0; a < 5; a++)
{
byte *app = mm_palloc();
vmm_map1((dword)addr, (dword)app);
addr += 4096;
}
addr = vfs_readFile("/bin/hash.hos");
memcpy(0, addr, 4192);
asm("call 0");
free(addr);
*/
dword key = 0;
for (;;) for (;;)
{ {
if (pb->flags == MM_PB_NP) key = kbdWaitKey();
break; if ((key & 0xFF) > 2) //key is not a control key
printf("\nBase: 0x%x; Limit: 0x%x; Flags: 0x%x, Link: 0x%x", pb->base, pb->length, pb->flags, pb->link); putc(key);
pb = (pageblock *) pb->link; }
} */
} }
// main Interrupt Service Routine - handles all interrupts unless caught by kernel.asm
void isr(dword num) void isr(dword num)
{ {
switch(num) switch(num)
{ {
case 0x20: case 14:
printf("Page fault, CR2 = 0x%x\n", read_cr2());
halt();
break;
case 0x20: // IRQ0 - timer interrupt
timer++; timer++;
(*(byte *)0xb8000)++; (*(byte *)(0xc00b8000))++;
switch(timer)
{
case 150:
video_rectf(VXR*3/11, 0, VXR*4/11, VYR-1, 0x00000088);
break;
case 200:
video_rectf(VXR*7/11, 0, VXR*8/11, VYR-1, 0x00000088);
break;
case 250:
video_rectf(VXR/11, 0, VXR*2/11, VYR*2/5, 0x00000088);
break;
case 300:
video_rectf(VXR/11, VYR*3/5, VXR*2/11, VYR-1, 0x00000088);
break;
case 350:
video_rectf(VXR*5/11, VYR/5, VXR*6/11, VYR*4/5, 0x00000088);
break;
case 400:
video_rectf(VXR*9/11, VYR/5, VXR-1, VYR*2/5, 0x00000088);
break;
case 450:
video_rectf(VXR*8/11, VYR*3/5, VXR*10/11, VYR*4/5, 0x00000088);
break;
}
eoi(); eoi();
break; break;
case 0x21: case 0x21: // IRQ1 - keyboard interrupt
printf("------------------KEYBOARD ISR--------------------------\n"); isr_keyboard(); //isr_keybard() takes care of calling eoi()
isr_keyboard(); break;
case 0x2C: // IRQ12 - PS/2 mouse
isr_mouse();
eoi2();
break;
default:
printf("Interrupt %d (0x%x) Unhandled!!\n", num, num);
halt();
break; break;
} }
} }
+44 -39
View File
@@ -1,53 +1,55 @@
//Keyboard.c //Keyboard.c
// Created: 04/17/03 Josh Holtrop // Created: 04/17/03 Josh Holtrop
// Modified: 09/09/03 // Modified: 10/30/03
//for HOS //for HOS
#define KBD_BUFFER_LENGTH 64 #define KBD_BUFFER_LENGTH 64
byte kbdFlags = 0; byte kbdFlags = 0; //holds current keyboard flags - caps/num/scroll/shift/ctrl/alt
byte kbdAscii = 0; byte kbdAscii = 0; //holds ASCII value of a key pressed
byte kbdScan = 0; byte kbdScan = 0; //holds the keyboard scan code of a key pressed
dword kbdBuffer[KBD_BUFFER_LENGTH]; dword kbdBuffer[KBD_BUFFER_LENGTH]; //a buffer for all keypresses
byte kbdBufferStart = 0; int kbdBufferStart = 0; //position of next key in buffer
byte kbdBufferLen = 0; int kbdBufferLen = 0; //number of keys left in the buffer
byte kbdExt = 0; byte kbdExt = 0; //# of extended key codes left to input
byte kbdExt2 = 0; byte kbdExt2 = 0; //# of 2nd-set-extended key codes left to input
byte ackReason = 0; //used to record the reason why we would get an acknowledge byte (0xFA) byte ackReason = 0; //used to record the reason why we would get an acknowledge byte (0xFA)
//these arrays convert a keyboard scan code to an ASCII character value
//nul esc bksp tab lctl lsft rsft lalt caps F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 numScrlNumPad------- unknown---- F11 F12 unknown.... //nul esc bksp tab lctl lsft rsft lalt caps F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 numScrlNumPad------- unknown---- F11 F12 unknown....
const byte SCAN2ASCII[128] = "\000\0331234567890-=\010\011qwertyuiop[]\n\001asdfghjkl;'`\001\\zxcvbnm,./\001*\001 \001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001-\001\001\001+\001\001\001\001\001\002\002\002\001\001\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002"; const byte SCAN2ASCII[128] = "\000\0331234567890-=\010\011qwertyuiop[]\n\001asdfghjkl;'`\001\\zxcvbnm,./\001*\001 \001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001-\001\001\001+\001\001\001\001\001\002\002\002\001\001\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002";
const byte SCAN2ASCIISHIFT[128] = "\000\033!@#$%^&*()_+\010\011QWERTYUIOP{}\n\001ASDFGHJKL:\"~\001|ZXCVBNM<>?\001*\001 \001\001\001\001\001\001\001\001\001\001\001\001\001789-456+1230.\002\002\002\001\001\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002"; const byte SCAN2ASCIISHIFT[128] = "\000\033!@#$%^&*()_+\010\011QWERTYUIOP{}\n\001ASDFGHJKL:\"~\001|ZXCVBNM<>?\001*\001 \001\001\001\001\001\001\001\001\001\001\001\001\001789-456+1230.\002\002\002\001\001\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002";
//====FUNCTIONS: //====FUNCTIONS:
// The Keyboard Interrupt Service Routine
void isr_keyboard() void isr_keyboard()
{ {
kbdScan = inportb(0x60); kbdScan = inportb(0x60);
//printf("\nKEYBOARD INTERRUPT: 0x%x", kbdScan);
byte inState = inportb(0x61); byte inState = inportb(0x61);
outportb(0x61, inState|0x80); outportb(0x61, inState|0x80);
outportb(0x61, inState); outportb(0x61, inState);
printf("IRQ 1: %x\n", kbdScan); //printf("IRQ 1: %x\n", kbdScan);
if (kbdScan == 0xFA) //250 //ACKnowledge if (kbdScan == 0xFA) //250 //ACKnowledge
{ {
//printf("KBD_ACK 0x%x!\n", ackReason);
if (ackReason == 0xED) //reset LEDs if (ackReason == 0xED) //reset LEDs
{ {
outportb(0x64, (kbdFlags & 0x07)); outportb(0x60, (kbdFlags & 0x07));
printf("KBD_ACK!");
} }
ackReason = 0; ackReason = 0;
} }
if (kbdScan == 224) //extended key if (kbdScan == 224) //extended key
{ {
kbdExt = 1; kbdExt = 1;
eoi(); eoi();
return; return;
} }
if (kbdScan == 225) if (kbdScan == 225) //2nd-set-extended key
{ {
kbdExt2 = 2; kbdExt2 = 2;
eoi(); eoi();
@@ -56,7 +58,7 @@ void isr_keyboard()
//====handle control keys:: //====handle control keys::
kbdAscii = 2; kbdAscii = 2;
switch (kbdScan) //control keys switch (kbdScan) //control keys
{ {
case KBD_SCAN_LSHIFT: case KBD_SCAN_LSHIFT:
kbdFlags |= KBD_SHIFT; kbdFlags |= KBD_SHIFT;
@@ -95,17 +97,17 @@ void isr_keyboard()
case KBD_SCAN_CAPS+KBD_SCAN_RELEASED: case KBD_SCAN_CAPS+KBD_SCAN_RELEASED:
kbdFlags ^= KBD_CAPS; kbdFlags ^= KBD_CAPS;
kbdAscii = 1; kbdAscii = 1;
kbd_resetLEDs(); //update LEDs kbd_resetLEDs(); //update LEDs
break; break;
case KBD_SCAN_SCROLL+KBD_SCAN_RELEASED: case KBD_SCAN_SCROLL+KBD_SCAN_RELEASED:
kbdFlags ^= KBD_SCROLL; kbdFlags ^= KBD_SCROLL;
kbdAscii = 1; kbdAscii = 1;
kbd_resetLEDs(); //update LEDs kbd_resetLEDs(); //update LEDs
break; break;
case KBD_SCAN_NUM+KBD_SCAN_RELEASED: case KBD_SCAN_NUM+KBD_SCAN_RELEASED:
kbdFlags ^= KBD_NUM; kbdFlags ^= KBD_NUM;
kbdAscii = 1; kbdAscii = 1;
kbd_resetLEDs(); //update LEDs kbd_resetLEDs(); //update LEDs
break; break;
} }
if (kbdAscii == 1) if (kbdAscii == 1)
@@ -169,7 +171,8 @@ void isr_keyboard()
} }
//====do something with key:: //====do something with key::
if ((kbdScan == 83) & ((kbdFlags & KBD_CTRL) != 0) & ((kbdFlags & KBD_ALT) != 0)) // printf("kbdScan == %d\nkbdAscii == %d\nkbdFlags == %d\n", kbdScan, kbdAscii, kbdFlags);
if ((kbdScan == 83) && (kbdFlags & KBD_CTRL) && (kbdFlags & KBD_ALT))
{ {
printf("Initiating reboot."); printf("Initiating reboot.");
restart(); restart();
@@ -188,57 +191,59 @@ void isr_keyboard()
} }
else else
{ {
kbdBuffer[(kbdBufferStart+kbdBufferLen)%KBD_BUFFER_LENGTH] = (dword) ((kbdFlags << 16) | (kbdScan << 8) | kbdAscii); kbdBuffer[(kbdBufferStart+kbdBufferLen++)%KBD_BUFFER_LENGTH] = (dword) ((kbdFlags << 16) | (kbdScan << 8) | kbdAscii);
kbdBufferLen++; // printf("S:%d\tL:%d\tR:%x\n", kbdBufferStart, kbdBufferLen, kbdBuffer[kbdBufferStart]);
} }
} }
eoi(); eoi();
// if (key == 0xFA) //ACKnowledge }
// outportb(0x60, 0x3);
};
inline byte switchCase(byte asciiCode) //Switches the case of an ASCII character
/*inline byte (byte asciiCode)
{ {
if ((asciiCode >= 'A') & (asciiCode <= 'Z')) if ((asciiCode >= 'A') & (asciiCode <= 'Z'))
return (asciiCode + ('a' - 'A')); return (asciiCode + ('a' - 'A'));
if ((asciiCode >= 'a') & (asciiCode <= 'z')) if ((asciiCode >= 'a') & (asciiCode <= 'z'))
return (asciiCode - ('a' - 'A')); return (asciiCode - ('a' - 'A'));
return asciiCode; return asciiCode;
} }*/
//Gets a key from the buffer, returns 0 if no keys available, returns immediately
dword kbdGetKey() dword kbdGetKey()
{ {
if (kbdBufferLen == 0) //buffer empty if (kbdBufferLen == 0) //buffer empty
return 0; return 0;
dword retVal = kbdBuffer[kbdBufferStart]; dword retVal = kbdBuffer[kbdBufferStart];
printf("S:%d\tE:%d\tR:%x\n", kbdBufferStart, kbdBufferLen, retVal);
kbdBufferStart++; kbdBufferStart++;
kbdBufferLen--; kbdBufferLen--;
if (kbdBufferStart == KBD_BUFFER_LENGTH) if (kbdBufferStart >= KBD_BUFFER_LENGTH)
kbdBufferStart = 0; kbdBufferStart = 0;
return retVal; return retVal;
} }
//Gets a key from the buffer, if no keys available, waits for one to be entered
dword kbdWaitKey() dword kbdWaitKey()
{ {
dword retVal = 0;
for (;;) for (;;)
{ {
retVal = kbdGetKey(); if (kbdBufferLen != 0) //buffer empty
if (retVal != 0) break;
{ }
printf("S:%d\tE:%d\tR:%x\n", kbdBufferStart, kbdBufferLen, retVal); dword retVal = kbdBuffer[kbdBufferStart];
return retVal; kbdBufferStart++;
} kbdBufferLen--;
} if (kbdBufferStart >= KBD_BUFFER_LENGTH)
kbdBufferStart = 0;
return retVal;
} }
//Resets the keyboard LEDs to reflect the current state of the num lock, caps lock, and scroll lock bits
inline void kbd_resetLEDs() inline void kbd_resetLEDs()
{ {
outportb(0x64, 0xED); outportb(0x60, 0xED);
//outportb(0x64, (kbdFlags & 0x07)); //outportb(0x60, (kbdFlags & 0x07));
ackReason = 0xED; ackReason = 0xED;
} }
+133
View File
@@ -0,0 +1,133 @@
//kio.c
// Author: Josh Holtrop
// Created: 12/25/03
// Modified: 12/25/03
// This is the main output routine, it uses a format string and a variable
// number of arguments to print formatted text
void printf(char *fmt, ...)
{
dword *params = ((dword *)(&fmt)) + 1; //points to the first paramater
int i;
int special = 0;
for (i = 0; ; i++)
{
if (special)
{
special = 0;
switch (fmt[i])
{
case 0:
return;
case '%':
putc('%');
break;
case 's': case 'S':
puts((char *)*params);
params++;
break;
case 'c': case 'C':
putc(*params);
params++;
break;
case 'd': case 'D':
putDec(*params);
params++;
break;
case 'u': case 'U':
putDecu(*params);
params++;
break;
case 'x': case 'X':
putHex(*params);
params++;
break;
}
}
else
{
switch (fmt[i])
{
case '%':
special = 1;
break;
case 0:
return;
default:
putc(fmt[i]);
}
}
}
}
// This function draws a single character
void putc(dword chr)
{
char charac = (char)chr;
word *vidmem = (word *)0xC00B8000;
if (charac == '\n')
{
if (cursorPosition % 80)
cursorPosition = cursorPosition + 80 - (cursorPosition % 80);
else
cursorPosition += 80;
}
else if (charac == '\t')
{
if (cursorPosition % 8)
cursorPosition = cursorPosition + 8 - (cursorPosition % 8);
else
cursorPosition += 8;
}
else
{
if (videoMode)
{
console_memory[cursorPosition] = charac | 0x0700;
video_drawConsoleChar(cursorPosition);
}
else
{
console_memory[cursorPosition] = charac | 0x0700;
vidmem[cursorPosition] = charac | 0x0700;
}
cursorPosition++;
}
if (cursorPosition >= 2000)
{
console_scroll();
cursorPosition = 2000-80;
if (videoMode)
video_drawConsole();
}
if (!videoMode)
writeCursorPosition(cursorPosition);
}
// This function displays a number in hexadecimal
int putHex(dword number)
{
int hitNum = 0;
int i;
for (i = 7; i >= 0; i--)
{
dword val = (number >> (i*4)) & 0xF;
if ((val != 0) || (i == 0))
hitNum = 1;
if (hitNum)
{
val = val + '0';
if (val > '9')
val = val + ('A' - '9' - 1);
putc(val);
}
}
}
+15
View File
@@ -0,0 +1,15 @@
//kio.h
// Author: Josh Holtrop
// Created: 12/25/03
// Modified: 12/25/03
void printf(char *fmt, ...);
void putc(dword chr);
int putHex(dword number);
dword cursorPosition = 0; //Caches the current cursor position
Executable
+1
View File
@@ -0,0 +1 @@
ld -nodefaultlibs -nostdlib -T link.ld -o kernel.bin -Map .\lst\LDout.doc ks.o kernel.o asmfuncs.o
+1 -1
View File
@@ -2,7 +2,7 @@ OUTPUT_FORMAT("binary")
ENTRY(start) ENTRY(start)
SECTIONS SECTIONS
{ {
.text 0x100000 : { .text 0xC0106000 : {
code = .; _code = .; __code = .; code = .; _code = .; __code = .;
*(.text) *(.text)
. = ALIGN(4096); . = ALIGN(4096);
+68 -189
View File
@@ -1,233 +1,112 @@
// mm.c // mm.c
// 09/01/03 Josh Holtrop // Author: Josh Holtrop
// Created: 09/01/03
// Modified: 12/28/03
// 0x368000 is first available byte (this is right after the kernel @ 1mb and the initrd @ 2mb, 1440kb. //The total amount of physical memory available (bytes)
#define BITMAP_SIZE 0x20000
dword mm_totalmem = 0;
pageblock *first_pageblock = (pageblock *) 0; dword mm_megabytes;
dword mm_totalmem = 0x100000; //assume 1mb byte page_bitmap[BITMAP_SIZE]; //used to store a bit for each page that is used, 0 if available
//0x20000*(8 bits/byte)=0x100000 pages in 4gb total
//This function initializes the memory manager's linked list, filling it with the
// memory areas returned by bios interrupt 0x8E20
void mm_init() void mm_init()
{ {
dword *memmap_entries = (dword *) 0x9040A; dword memmap_entries = *(dword *)0xC009040A;
memmap_entry *maps = (memmap_entry *) 0x92000; memmap_entry *maps = (memmap_entry *) 0xC0092000;
dword a; dword a;
for (a=0;a<(*memmap_entries);a++) for (a = 0; a < BITMAP_SIZE; a++)
{
page_bitmap[a] = 0xFF; //all pages used
}
for (a = 0; a < memmap_entries; a++)
{ {
if (maps[a].attributes == 1) // (1) mem free to OS if (maps[a].attributes == 1) // (1) mem free to OS
{ {
mm_totalmem += maps[a].limit.lowdword; mm_totalmem += maps[a].limit.lowdword;
if ((maps[a].base.lowdword + maps[a].limit.lowdword) > (FREERAM_START+8192)) //goes past where we start freeram if ((maps[a].base.lowdword + maps[a].limit.lowdword) >= (FREERAM_START+4096)) //goes past where we start freeram
{ {
if (maps[a].base.lowdword < FREERAM_START) if (maps[a].base.lowdword < FREERAM_START)
{ {
maps[a].limit.lowdword = maps[a].limit.lowdword - (FREERAM_START - maps[a].base.lowdword); mm_pfreen(FREERAM_START, (maps[a].limit.lowdword - (FREERAM_START - maps[a].base.lowdword)) >> 12);
maps[a].base.lowdword = FREERAM_START; //block at least 4kb, starts >= FREERAM_START
} }
if (first_pageblock == 0) //no pageblock page set up yet, so set it up here else
{ {
first_pageblock = (pageblock *) maps[a].base.lowdword ; mm_pfreen(maps[a].base.lowdword, maps[a].limit.lowdword >> 12); //set the appropriate bits as "free" in the page bitmap
maps[a].base.lowdword += 4096;
maps[a].limit.lowdword -= 4096;
mm_init_pageblockpage(first_pageblock);
first_pageblock->base = maps[a].base.lowdword;
first_pageblock->length = maps[a].limit.lowdword / 4096;
first_pageblock->flags = MM_PB_AVAIL;
}
else //first_pageblock already set up, add on segment
{
pageblock *pb = first_pageblock;
for (;;)
{
if (pb->flags == MM_PB_NP)
break;
else
pb++;
}
pb->base = maps[a].base.lowdword;
pb->length = maps[a].limit.lowdword / 4096;
pb->flags = MM_PB_AVAIL;
} }
} }
} }
} }
if (first_pageblock == 0) if (mm_totalmem % 0x100000)
mm_megabytes = (mm_totalmem >> 20) + 1;
else
mm_megabytes = mm_totalmem >> 20;
}
// This function frees a certain number of pages starting at the address
// specified in base for a length of pages pages
void mm_pfreen(dword base, dword pages)
{
dword a;
dword max = base + (pages << 12);
for (a = base; a < max; a += 4096)
{ {
printf("ERROR! NO INITIAL PAGE BLOCK COULD BE CREATED."); mm_pfree(a);
asm("cli");
asm("hlt");
} }
} }
// This function frees a single page
void mm_pfree(dword base)
void mm_init_pageblockpage(pageblock *pbp)
{ {
pageblock *pb = pbp; // dword pageNumber = base >> 12; // >>12 == /4096
int a; dword byteNumber = base >> 15; //pageNumber >> 3; //pageNumber/8
for (a=0; a<512; a++) dword bitNumber = (base >> 12) % 8; //pageNumber % 8;
{ page_bitmap[byteNumber] = page_bitmap[byteNumber] & ((0x01 << bitNumber) ^ 0xFF);
pb->base = 0;
pb->length = 0;
pb->flags = MM_PB_NP;
if (a<511)
pb->link = (dword)pb + sizeof(pageblock);
else
pb->link = 0;
pb++;
}
} }
void *mm_palloc(dword numpages) // This function allocates a single page, returning its physical address
void *mm_palloc()
{ {
pageblock *pb = first_pageblock; dword bite;
dword freeentries = mm_freeentries(); for (bite = 0; bite < BITMAP_SIZE; bite++)
if (freeentries < 2)
{ {
if(mm_new_pageblock_page() == 0) if (page_bitmap[bite] != 0xFF) //there is an available page within this 8-page region
return 0;
}
pageblock *newentry = mm_nextpageblockentry();
for (;;)
{
if ((pb->flags == MM_PB_AVAIL) && (pb->length >= numpages))
break;
if (pb->link == 0)
return 0;
pb = (pageblock *)pb->link;
}
if (pb->length == numpages) //dont need a new entry, just mark this one as used :)
{
pb->flags = MM_PB_USED;
return pb;
}
else //subtract out allocated number of pages from length
{
newentry->base = pb->base;
newentry->length = numpages;
newentry->flags = MM_PB_USED;
pb->base += (numpages * 4096);
pb->length -= numpages;
return (void *)newentry->base;
}
}
dword mm_freeentries()
{
pageblock *pb = first_pageblock;
dword counter = 0;
for (;;)
{
if (pb->flags == MM_PB_NP)
counter++;
if (pb->link == 0)
return counter;
pb = (pageblock *) pb->link;
}
}
pageblock *mm_new_pageblock_page()
{
pageblock *pb = first_pageblock;
for (;;)
{
if ((pb->flags == MM_PB_AVAIL) && (pb->length > 1))
{ {
pageblock *retval = (pageblock *)pb->base; int bit;
pb->base += 4096; for (bit = 0; bit < 8; bit++)
pb->length--;
mm_init_pageblockpage(retval); //zeros out, links new pageblock page
mm_lastpageblockentry()->link = (dword)retval; //set up link to new pageblock page
return retval;
}
pb = (pageblock *) pb->link;
if (pb == 0)
return 0;
}
}
int mm_pfree(void *ptr)
{
pageblock *pb = first_pageblock;
dword tofree = (dword) ptr;
for (;;)
{
if ((pb->base == tofree) && (pb->flags == MM_PB_USED))
{
pb->flags = MM_PB_AVAIL; //found block, mark available / coalesce it
pageblock *pbc = first_pageblock;
for (;;)
{ {
if (pbc->flags == MM_PB_AVAIL) if (!(page_bitmap[bite] & (1 << bit))) //this bite/bit combination is available
{ {
if ((pbc->base + (pbc->length * 4096)) == pb->base) //pbc ends where pb starts page_bitmap[bite] = page_bitmap[bite] | (1 << bit); //set page as used
{ return (void *)((bite << 15) | (bit << 12));
pbc->length += pb->length; //extend pbc's length by pb's length }
pb->flags = MM_PB_NP; //mark pb as an unused entry
return 0;
}
if ((pb->base + (pb->length * 4096)) == pbc->base) //pb ends where pb starts
{
pb->length += pbc->length;
pbc->flags = MM_PB_NP;
return 0;
}
}
if (pbc->link == 0) //no entry found to consolidate...
return 0;
pbc = (pageblock *) pbc->link; //next entry to test
} }
} }
if (pb->link == 0)
return 1;
pb = (pageblock *) pb->link;
} }
return 0; //no free page
} }
pageblock *mm_lastpageblockentry() // This function reports the number of bytes of free physical memory
dword mm_freemem()
{ {
pageblock *pb = first_pageblock; dword a;
for (;;) dword pages = 0;
for (a = 0; a < BITMAP_SIZE; a++)
{ {
if (pb->link == 0) int bit;
return pb; for (bit = 0; bit < 8; bit++)
pb = (pageblock *)pb->link; {
} if (!(page_bitmap[a] & (1 << bit)))
} pages++;
}
pageblock *mm_nextpageblockentry()
{
pageblock *pb = first_pageblock;
for (;;)
{
if (pb->flags == MM_PB_NP)
return pb;
if (pb->link == 0)
return 0;
pb = (pageblock *)pb->link;
}
}
dword mm_freemem()
{
dword amount = 0;
pageblock *pb = first_pageblock;
for (;;)
{
if (pb->flags == MM_PB_AVAIL)
amount += (pb->length)*4096;
if (pb->link == 0)
return amount;
pb = (pageblock *) pb->link;
} }
return pages << 12;
} }
+6 -21
View File
@@ -7,29 +7,14 @@ typedef struct {
} __attribute__((packed)) memmap_entry; } __attribute__((packed)) memmap_entry;
typedef struct {
dword base;
dword length; //in pages
dword flags;
dword link;
} __attribute__ ((packed)) pageblock; //16 byte pageblock entry - 512 entries = 1 page
void mm_init(); void mm_init();
void mm_init_pageblockpage(pageblock *pbp); void mm_pfreen(dword base, dword pages);
void *mm_palloc(dword numpages); void mm_pfree(dword base);
int mm_pfree(void *ptr); void *mm_palloc();
dword mm_freeentries(); dword mm_freemem();
pageblock *mm_new_pageblock_page();
pageblock *mm_lastpageblockentry();
pageblock *mm_nextpageblockentry();
dword mm_freemem();
#define MM_PB_FLAGMASK 0x03 //00000011
#define MM_PB_NP 0x00 //00000000
#define MM_PB_AVAIL 0x01 //00000001
#define MM_PB_USED 0x02 //00000010
+60
View File
@@ -0,0 +1,60 @@
// mouse.c
// 10/03/03
// Author: Josh Holtrop
//This method initializes the ps/2 mouse
void mouse_init()
{
outportb(0x64, 0x20); //tell keyboard controller we are going to read keyboard controller command byte
byte temp = inportb(0x60); //read keyboard controller command byte
outportb(0x64, 0x60); //tell keyboard controller we are going to write keyboard controller command byte
outportb(0x60, 0x03 | (temp&0x40)); //write keyboard controller command byte: enable mouse/keyboard ints, include original XLATE bit from temp (bit6)
outportb(0x64, 0xA8); //enable mouse port
outportb(0x64, 0xD4); //send command to mouse, not kbd
outportb(0x60, 0xF4); //enable data reporting
mouse_x = video_mode.XResolution >> 1;
mouse_y = video_mode.YResolution >> 1;
//outportb(0x64, 0xD4);
//outportb(0x60, 0xE7); //scaling 2:1
}
//This method is called when a mouse interrupt occurs
void isr_mouse()
{
byte inb = inportb(0x60); //read mouse byte
if ((inb == 0xFA) && (mouse_bytesRead < 1)) //ACK
return;
mouse_inbuffer[mouse_bytesRead] = inb;
mouse_bytesRead++;
if (mouse_bytesRead == 3) //complete packet received
{
mouse_bytesRead = 0;
int adjx = (char) mouse_inbuffer[1];
int adjy = (char) mouse_inbuffer[2];
mouse_x += adjx;
mouse_y -= adjy; //-= because screen y coordinates are opposite mouse y coordinates
if (mouse_x < 0)
mouse_x = 0;
if (mouse_x >= video_mode.XResolution)
mouse_x = video_mode.XResolution - 1;
if (mouse_y < 0)
mouse_y = 0;
if (mouse_y >= video_mode.YResolution)
mouse_y = video_mode.YResolution - 1;
if (mouse_inbuffer[0] & 0x01) //left button
video_pset(mouse_x, mouse_y, 0x00FF8800);
else
video_pset(mouse_x, mouse_y, 0x00FFFFFF);
}
}
+17
View File
@@ -0,0 +1,17 @@
// mouse.h
// 10/03/03
// Author: Josh Holtrop
int mouse_x;
int mouse_y;
int mouse_bytesRead = 0;
byte mouse_inbuffer[16];
void mouse_init();
void isr_mouse();
+14
View File
@@ -0,0 +1,14 @@
// rd.c
// Author: Josh Holtrop
// Created: 12/31/03
// Modified: 01/04/04
byte *rd_readSector(DiskDevice *rd, dword sector, byte *dest)
{
memcpy(dest, (void *)(rd->location + (sector * 512)), 512);
return dest;
}
+9
View File
@@ -0,0 +1,9 @@
// rd.h
// Author: Josh Holtrop
// Created: 12/31/03
// Modified: 01/04/04
byte *rd_readSector(DiskDevice *rd, dword sector, byte *dest);
+3 -3
View File
@@ -28,12 +28,12 @@ brDrive DB 0 ; 0024h - Physical drive no.
DB 0 ; 0025h - Reserved (FAT32) DB 0 ; 0025h - Reserved (FAT32)
DB 29H ; 0026h - Extended boot record sig (FAT32) DB 29H ; 0026h - Extended boot record sig (FAT32)
brSerialNum DD 404418EAH ; 0027h - Volume serial number brSerialNum DD 404418EAH ; 0027h - Volume serial number
brLabel DB 'HOS 0.1.1 ' ; 002Bh - Volume label brLabel DB 'Holtrops OS' ; 002Bh - Volume label
brFSID DB 'FAT12 ' ; 0036h - File System ID brFSID DB 'FAT12 ' ; 0036h - File System ID
;------------------------------------------------------------------------ ;------------------------------------------------------------------------
start: start:
jmp 0:jmphere ;ensure that cs=0 and ip=0x7c... jmp 0:jmphere ;ensure that cs=0 and ip=0x7c00...
jmphere: jmphere:
;dl=drive number, save it! ;dl=drive number, save it!
xor ax, ax xor ax, ax
@@ -88,7 +88,7 @@ unreal:
pop es ;segments back, with 4gb limits! pop es ;segments back, with 4gb limits!
sti sti
;now lets read in the FAT and root directory so we can search for the kernel file... ;now lets read in the FAT and root directory so we can search for the stage2 file...
mov ax, 0x0209 ;FAT1 mov ax, 0x0209 ;FAT1
mov cx, 0x0002 mov cx, 0x0002
xor dh, dh xor dh, dh
+67 -16
View File
@@ -30,6 +30,7 @@ loop_name:
jmp found_file ;good file, ds:si points to start of root directory entry jmp found_file ;good file, ds:si points to start of root directory entry
goon: goon:
pop si pop si
add si, 32
pop cx pop cx
loop loop_compare loop loop_compare
@@ -147,29 +148,43 @@ got_rd:
mov [ds:BOOT_HASRD], al mov [ds:BOOT_HASRD], al
pop ds ;ds=0 pop ds ;ds=0
cmp al, 0 ;dont load rd cmp al, 0 ;dont load rd
jz no_rd jnz yes_rd
jmp no_rd
yes_rd:
mov cx, 80 mov cx, 80
mov edi, 0xb8000+160*4 mov edi, 0xb8000+160*4
filler_loop: filler_loop: ;draw a red bar
mov word [ds:edi], 0x0400+177 mov word [ds:edi], 0x0400+177
inc edi inc edi
inc edi inc edi
loop filler_loop loop filler_loop
mov cx, 80 ;80 cylinders to read mov cx, 80 ;80 cylinders to read
xor si, si xor si, si ;start at cylinder 0
mov edi, BOOT_RD_ADD ;ram disk address mov edi, BOOT_RD_ADD ;ram disk address
read_cylinder: read_cylinder:
push cx push cx
mov bx, 0x0100
mov bx, 0x0100 ;read sectors from head 0
mov es, bx mov es, bx
xor bx, bx xor bx, bx ;es:bx = data buffer for read
mov ax, 0x0224 mov ax, 0x0212 ;ah = int 0x13 function 2, al = number of sectors to read
mov cx, si mov cx, si ;what cyl. we are on is now in cx
mov ch, cl mov ch, cl ;ch = cyl. number
mov cl, 1 mov cl, 1 ;cl = sector number 1-63
xor dx, dx xor dx, dx ;dh = head number
mov dl, [gs:BOOT_DRIVE] mov dl, [gs:BOOT_DRIVE] ;dl = drive number
int 0x13
mov bx, 0x0100 ;now read sectors from head 1
mov es, bx
mov bx, 9216 ;es:bx = data buffer for read
mov ax, 0x0212 ;ah = int 0x13 function 2, al = number of sectors to read
mov cx, si ;what cyl. we are on is now in cx
mov ch, cl ;ch = cyl. number
mov cl, 1 ;cl = sector number 1-63
mov dh, 1 ;dh = head number
mov dl, [gs:BOOT_DRIVE] ;dl = drive number
int 0x13 int 0x13
mov ebx, 0xb8000 mov ebx, 0xb8000
@@ -836,7 +851,7 @@ puthex2_goon2:
ret ret
;------------------------------------------------------ ;------------------------------------------------------
txt_welcome: db " Welcome to HOS v", VERSION, "! ", 0 txt_welcome: db " Welcome to HOS v", VERSION, "! ", 0
txt_rd1: db "1. Do not load an initial ram disk", 0 txt_rd1: db "1. Do not load an initial ram disk", 0
txt_rd2: db "2. Load initial ram disk from floppy", 0 txt_rd2: db "2. Load initial ram disk from floppy", 0
txt_input: db "Enter your selection: ", 0 txt_input: db "Enter your selection: ", 0
@@ -889,11 +904,43 @@ KERNEL_DATA equ $-gdt
db 0x00 db 0x00
db 0x00 db 0x00
db 0x92 db 0x92
db 0xcf ;cf db 0xcf
db 0x00 db 0x00
gdt_end: gdt_end:
;-------------------------------------------------------
gdtr32:
dw gdt_end32-gdt32-1
dd gdt32
gdt32:
dd 0
dd 0
;a base of 0x4000_0000, when added to 0xC000_0000 will produce 0x0000_0000 physical before paging in effect
KERNEL_CODE32 equ $-gdt32
db 0xff ;limit 7:0
db 0xff ;limit 15:8
db 0x00 ;base 7:0
db 0x00 ;base 15:8
db 0x00 ;base 23:16
db 0x9a ;access
db 0xcf ;flags / limit 19:16
db 0x40 ;base 31:24
KERNEL_DATA32 equ $-gdt32
db 0xff ;segment 16 = 4gb data
db 0xff
db 0x00
db 0x00
db 0x00
db 0x92
db 0xcf
db 0x40
gdt_end32:
;------------------------------------------------------ ;------------------------------------------------------
go_pm: go_pm:
xor ax, ax xor ax, ax
@@ -908,12 +955,16 @@ go_pm:
bits 32 bits 32
pmode: pmode:
mov ax, KERNEL_DATA lgdt [gdtr32]
jmp KERNEL_CODE32:pmode_offsetted+0xC0000000
pmode_offsetted:
mov ax, KERNEL_DATA32
mov es, ax mov es, ax
mov ds, ax mov ds, ax
mov fs, ax mov fs, ax
mov gs, ax mov gs, ax
jmp KERNEL_CODE:BOOT_KERNEL_ADD jmp KERNEL_CODE:BOOT_KERNEL_ADD+0xC0000000
kernel: db "KERNEL BIN", 0 kernel: db "KERNEL BIN", 0
+258
View File
@@ -0,0 +1,258 @@
const byte stdfont[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xE0, 0xC0, 0x80,
0x00, 0x08, 0x18, 0x38, 0x78, 0x38, 0x18, 0x08,
0x00, 0x20, 0x70, 0xA8, 0x20, 0xA8, 0x70, 0x20,
0x00, 0xA0, 0xA0, 0xA0, 0xA0, 0x00, 0xA0, 0xA0,
0x00, 0x78, 0xA8, 0xA8, 0x78, 0x28, 0x28, 0x68,
0x00, 0x78, 0x80, 0x70, 0x88, 0x70, 0x08, 0xF0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xF8,
0x00, 0x20, 0x70, 0xA8, 0x20, 0xA8, 0x70, 0xF8,
0x00, 0x20, 0x70, 0xA8, 0x20, 0x20, 0x20, 0x20,
0x00, 0x20, 0x20, 0x20, 0x20, 0xA8, 0x70, 0x20,
0x00, 0x00, 0x20, 0x10, 0xF8, 0x10, 0x20, 0x00,
0x00, 0x00, 0x20, 0x40, 0xF8, 0x40, 0x20, 0x00,
0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
0x00, 0x60, 0x90, 0x60, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x20, 0x70, 0xF8, 0xF8, 0x00, 0x00,
0x00, 0x00, 0xF8, 0xF8, 0x70, 0x20, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x20, 0x20, 0x20, 0x20, 0x00, 0x20, 0x20,
0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x50, 0xF8, 0x50, 0x50, 0x50, 0xF8, 0x50,
0x00, 0x20, 0x78, 0xA0, 0x70, 0x28, 0xF0, 0x20,
0x00, 0x00, 0x08, 0x90, 0x20, 0x48, 0x80, 0x00,
0x00, 0x20, 0x50, 0x50, 0x20, 0x58, 0x90, 0x68,
0x00, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00,
0x00, 0x20, 0x40, 0x40, 0x40, 0x40, 0x40, 0x20,
0x00, 0x40, 0x20, 0x20, 0x20, 0x20, 0x20, 0x40,
0x00, 0x00, 0xA8, 0x70, 0xF8, 0x70, 0xA8, 0x00,
0x00, 0x00, 0x20, 0x20, 0xF8, 0x20, 0x20, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40,
0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60,
0x00, 0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00,
0x00, 0x70, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70,
0x00, 0x20, 0x60, 0xA0, 0x20, 0x20, 0x20, 0x20,
0x00, 0x70, 0x88, 0x08, 0x10, 0x20, 0x40, 0xF8,
0x00, 0x70, 0x88, 0x08, 0x10, 0x08, 0x88, 0x70,
0x00, 0x30, 0x50, 0x90, 0x90, 0xF8, 0x10, 0x10,
0x00, 0xF8, 0x80, 0x80, 0xF8, 0x08, 0x88, 0x70,
0x00, 0x38, 0x40, 0x80, 0xF0, 0x88, 0x88, 0x70,
0x00, 0xF8, 0x08, 0x10, 0x20, 0x40, 0x40, 0x40,
0x00, 0x70, 0x88, 0x88, 0x70, 0x88, 0x88, 0x70,
0x00, 0x70, 0x88, 0x88, 0x78, 0x08, 0x10, 0x60,
0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00,
0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x40,
0x00, 0x10, 0x20, 0x40, 0x80, 0x40, 0x20, 0x10,
0x00, 0x00, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x00,
0x00, 0x80, 0x40, 0x20, 0x10, 0x20, 0x40, 0x80,
0x00, 0x70, 0x88, 0x08, 0x10, 0x20, 0x00, 0x20,
0x00, 0x70, 0x88, 0x88, 0xB8, 0xB0, 0x80, 0x78,
0x00, 0x70, 0x88, 0x88, 0xF8, 0x88, 0x88, 0x88,
0x00, 0xF0, 0x88, 0x88, 0xF0, 0x88, 0x88, 0xF0,
0x00, 0x70, 0x88, 0x80, 0x80, 0x80, 0x88, 0x70,
0x00, 0xF0, 0x88, 0x88, 0x88, 0x88, 0x88, 0xF0,
0x00, 0xF8, 0x80, 0x80, 0xF0, 0x80, 0x80, 0xF8,
0x00, 0xF8, 0x80, 0x80, 0xF0, 0x80, 0x80, 0x80,
0x00, 0x70, 0x88, 0x80, 0xB8, 0x88, 0x88, 0x70,
0x00, 0x88, 0x88, 0x88, 0xF8, 0x88, 0x88, 0x88,
0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x90, 0x60,
0x00, 0x88, 0x90, 0xA0, 0xC0, 0xA0, 0x90, 0x88,
0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xF8,
0x00, 0x88, 0xD8, 0xA8, 0x88, 0x88, 0x88, 0x88,
0x00, 0x88, 0xC8, 0xE8, 0xB8, 0x98, 0x88, 0x88,
0x00, 0x70, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70,
0x00, 0xF0, 0x88, 0x88, 0xF0, 0x80, 0x80, 0x80,
0x00, 0x70, 0x88, 0x88, 0x88, 0xA8, 0x98, 0x70,
0x00, 0xF0, 0x88, 0x88, 0xF0, 0xA0, 0x90, 0x88,
0x00, 0x70, 0x88, 0x80, 0x70, 0x08, 0x88, 0x70,
0x00, 0xF8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x00, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70,
0x00, 0x88, 0x88, 0x88, 0x88, 0x88, 0x50, 0x20,
0x00, 0x88, 0x88, 0x88, 0x88, 0x88, 0xA8, 0x50,
0x00, 0x88, 0x50, 0x20, 0x20, 0x50, 0x88, 0x88,
0x00, 0x88, 0x88, 0x50, 0x20, 0x20, 0x20, 0x20,
0x00, 0xF8, 0x08, 0x10, 0x20, 0x40, 0x80, 0xF8,
0x00, 0x70, 0x40, 0x40, 0x40, 0x40, 0x40, 0x70,
0x00, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x08, 0x00,
0x00, 0xE0, 0x20, 0x20, 0x20, 0x20, 0x20, 0xE0,
0x00, 0x20, 0x50, 0x88, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8,
0x00, 0x60, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x70, 0x08, 0x78, 0x88, 0x78,
0x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0x88, 0xF0,
0x00, 0x00, 0x00, 0x70, 0x88, 0x80, 0x88, 0x70,
0x00, 0x08, 0x08, 0x78, 0x88, 0x88, 0x88, 0x78,
0x00, 0x00, 0x00, 0x70, 0x88, 0xF8, 0x80, 0x78,
0x00, 0x30, 0x40, 0x40, 0xE0, 0x40, 0x40, 0x40,
0x00, 0x00, 0x00, 0x78, 0x88, 0x78, 0x08, 0x70,
0x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0x88, 0x88,
0x00, 0x20, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20,
0x00, 0x10, 0x00, 0x10, 0x10, 0x10, 0x90, 0x60,
0x00, 0x80, 0x80, 0x90, 0xA0, 0xC0, 0xA0, 0x90,
0x00, 0xC0, 0x40, 0x40, 0x40, 0x40, 0x40, 0xE0,
0x00, 0x00, 0x00, 0xD0, 0xA8, 0xA8, 0xA8, 0xA8,
0x00, 0x00, 0x00, 0xF0, 0x88, 0x88, 0x88, 0x88,
0x00, 0x00, 0x00, 0x70, 0x88, 0x88, 0x88, 0x70,
0x00, 0x00, 0x00, 0xF0, 0x88, 0xF0, 0x80, 0x80,
0x00, 0x00, 0x00, 0x78, 0x88, 0x78, 0x08, 0x38,
0x00, 0x00, 0x00, 0x70, 0x48, 0x40, 0x40, 0x40,
0x00, 0x00, 0x00, 0x78, 0x80, 0x70, 0x08, 0xF0,
0x00, 0x40, 0x40, 0xE0, 0x40, 0x40, 0x40, 0x20,
0x00, 0x00, 0x00, 0x88, 0x88, 0x88, 0x88, 0x78,
0x00, 0x00, 0x00, 0x88, 0x88, 0x88, 0x50, 0x20,
0x00, 0x00, 0x00, 0x88, 0x88, 0x88, 0xA8, 0x50,
0x00, 0x00, 0x00, 0x88, 0x50, 0x20, 0x50, 0x88,
0x00, 0x00, 0x00, 0x88, 0x88, 0x78, 0x08, 0xF0,
0x00, 0x00, 0x00, 0xF8, 0x10, 0x20, 0x40, 0xF8,
0x00, 0x30, 0x40, 0x40, 0x80, 0x40, 0x40, 0x30,
0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x00, 0xC0, 0x20, 0x20, 0x10, 0x20, 0x20, 0xC0,
0x00, 0x00, 0x68, 0x90, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x70, 0x88, 0x88, 0xF8, 0x88, 0x88, 0x88,
0x00, 0xF8, 0x88, 0x80, 0xF0, 0x88, 0x88, 0xF0,
0x00, 0xF0, 0x88, 0x88, 0xF0, 0x88, 0x88, 0xF0,
0x00, 0xF8, 0x48, 0x40, 0x40, 0x40, 0x40, 0xE0,
0x00, 0xF0, 0x50, 0x50, 0x50, 0x50, 0x78, 0x88,
0x00, 0xF8, 0x80, 0x80, 0xF0, 0x80, 0x80, 0xF8,
0x00, 0xA8, 0xA8, 0x70, 0x20, 0x70, 0xA8, 0xA8,
0x00, 0x70, 0x88, 0x08, 0x30, 0x08, 0x88, 0x70,
0x00, 0x88, 0x98, 0xA8, 0xA8, 0xA8, 0xC8, 0x88,
0x00, 0xA8, 0xC8, 0x98, 0xA8, 0xA8, 0xC8, 0x88,
0x00, 0x88, 0x90, 0xA0, 0xC0, 0xA0, 0x90, 0x88,
0x00, 0xF8, 0x50, 0x50, 0x50, 0x50, 0x50, 0x90,
0x00, 0x88, 0xD8, 0xA8, 0x88, 0x88, 0x88, 0x88,
0x00, 0x88, 0x88, 0x88, 0xF8, 0x88, 0x88, 0x88,
0x00, 0x70, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70,
0x00, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
0x00, 0xF0, 0x88, 0x88, 0xF0, 0x80, 0x80, 0x80,
0x00, 0x70, 0x88, 0x80, 0x80, 0x80, 0x88, 0x70,
0x00, 0xF8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x00, 0x88, 0x88, 0x88, 0x50, 0x20, 0x40, 0x80,
0x00, 0x70, 0x20, 0xF8, 0xA8, 0xF8, 0x20, 0x70,
0x00, 0x88, 0x88, 0x50, 0x20, 0x50, 0x88, 0x88,
0x00, 0x88, 0x88, 0x88, 0x88, 0x88, 0xF8, 0x08,
0x00, 0x88, 0x88, 0x88, 0xF8, 0x08, 0x08, 0x38,
0x00, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xF8,
0x00, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xF8, 0x08,
0x00, 0xC0, 0x40, 0x40, 0x78, 0x48, 0x48, 0x78,
0x00, 0x88, 0x88, 0xC8, 0xA8, 0xA8, 0xA8, 0xE8,
0x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0x88, 0xF0,
0x00, 0xF0, 0x88, 0x08, 0x78, 0x08, 0x88, 0xF0,
0x00, 0x90, 0xA8, 0xA8, 0xE8, 0xA8, 0xA8, 0x90,
0x00, 0x78, 0x88, 0x88, 0x78, 0x28, 0x48, 0x88,
0x00, 0x00, 0x70, 0x08, 0x78, 0x88, 0x88, 0x78,
0x00, 0x00, 0xF8, 0x80, 0xF0, 0x88, 0x88, 0xF0,
0x00, 0x00, 0xF0, 0x88, 0xF0, 0x88, 0x88, 0xF0,
0x00, 0x00, 0xF8, 0x48, 0x48, 0x40, 0x40, 0xE0,
0x00, 0x00, 0x78, 0x50, 0x50, 0x50, 0x70, 0x88,
0x00, 0x00, 0x70, 0x88, 0xF8, 0x80, 0x88, 0x70,
0x00, 0x00, 0xA8, 0x70, 0x20, 0x70, 0xA8, 0xA8,
0x00, 0x00, 0x00, 0xF0, 0x88, 0x30, 0x88, 0x70,
0x00, 0x00, 0x88, 0x98, 0xA8, 0xC8, 0x88, 0x88,
0x00, 0x50, 0x20, 0x88, 0x98, 0xA8, 0xC8, 0x88,
0x00, 0x00, 0x88, 0x90, 0xA0, 0xE0, 0x90, 0x88,
0x00, 0x00, 0xF8, 0x48, 0x48, 0x48, 0x48, 0xC8,
0x00, 0x00, 0x88, 0xD8, 0xA8, 0x88, 0x88, 0x88,
0x00, 0x00, 0x88, 0x88, 0xF8, 0x88, 0x88, 0x88,
0x00, 0x00, 0x70, 0x88, 0x88, 0x88, 0x88, 0x70,
0x00, 0x00, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x70, 0x50, 0x70, 0x08, 0x78, 0x88, 0x78,
0x00, 0x88, 0x00, 0x70, 0x08, 0x78, 0x88, 0x78,
0x00, 0x88, 0x00, 0x70, 0x88, 0x88, 0x88, 0x70,
0x00, 0x88, 0x00, 0x88, 0x88, 0x88, 0x88, 0x78,
0x00, 0x90, 0x00, 0xF0, 0x80, 0xE0, 0x80, 0xF0,
0x00, 0x00, 0x70, 0x48, 0x70, 0x48, 0x48, 0xF0,
0x00, 0x88, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20,
0x00, 0x88, 0x00, 0x70, 0x88, 0xF8, 0x80, 0x78,
0x00, 0x70, 0x50, 0x70, 0x88, 0xF8, 0x88, 0x88,
0x00, 0x88, 0x70, 0x88, 0x88, 0xF8, 0x88, 0x88,
0x00, 0x88, 0x70, 0x88, 0x88, 0x88, 0x88, 0x70,
0x00, 0x88, 0x00, 0x88, 0x88, 0x88, 0x88, 0x78,
0x00, 0x88, 0xF8, 0x80, 0xE0, 0x80, 0x80, 0xF8,
0x00, 0x40, 0x20, 0x70, 0x88, 0xF8, 0x80, 0x78,
0x00, 0x10, 0x20, 0x70, 0x88, 0xF8, 0x80, 0x78,
0x00, 0x20, 0x50, 0x70, 0x88, 0xF8, 0x80, 0x78,
0x00, 0x40, 0x20, 0x70, 0x08, 0x78, 0x88, 0x78,
0x00, 0x20, 0x50, 0x00, 0x20, 0x20, 0x20, 0x20,
0x00, 0x20, 0x10, 0x88, 0x88, 0x88, 0x88, 0x78,
0x00, 0x00, 0x00, 0x70, 0x80, 0x80, 0x70, 0x20,
0x00, 0x70, 0x88, 0x40, 0xF0, 0x40, 0x40, 0xF8,
0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x88, 0x88, 0x88, 0xF0, 0x80, 0x80,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xF0, 0x88, 0x88, 0xF0, 0x80, 0x80,
0x00, 0x00, 0x70, 0x88, 0x80, 0x80, 0x88, 0x70,
0x00, 0x00, 0xF8, 0x20, 0x20, 0x20, 0x20, 0x20,
0x00, 0x00, 0x88, 0x88, 0x50, 0x20, 0x40, 0x80,
0x00, 0x00, 0x70, 0x20, 0xF8, 0xF8, 0x20, 0x70,
0x00, 0x00, 0x88, 0x50, 0x20, 0x50, 0x88, 0x88,
0x00, 0x00, 0x88, 0x88, 0x88, 0x88, 0xF8, 0x08,
0x00, 0x00, 0x88, 0x88, 0x88, 0xF8, 0x08, 0x38,
0x00, 0x00, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xF8,
0x00, 0x00, 0xA8, 0xA8, 0xA8, 0xA8, 0xF8, 0x08,
0x00, 0x00, 0xC0, 0x40, 0x70, 0x48, 0x48, 0x70,
0x00, 0x00, 0x88, 0x88, 0xC8, 0xA8, 0xA8, 0xE8,
0x00, 0x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0xF0,
0x00, 0x00, 0x70, 0x88, 0x38, 0x08, 0x88, 0x70,
0x00, 0x00, 0x90, 0xA8, 0xA8, 0xE8, 0xA8, 0x90,
0x00, 0x00, 0x38, 0x48, 0x48, 0x38, 0x28, 0x48,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-13
View File
@@ -1,13 +0,0 @@
#include "string.h"
int strlen(char *str)
{
int retn = 0;
while (*str++ != 0)
retn++;
return retn;
}
-8
View File
@@ -1,8 +0,0 @@
#ifndef __HSTRING_H__
#define __HSTRING_H__ __HSTRING_H__
int strlen(char *str);
#endif
+91
View File
@@ -0,0 +1,91 @@
// vfs.c
// Author: Josh Holtrop
// Created: 12/31/03
// Modified: 01/04/04
void vfs_init()
{
firstDiskDevice = malloc(sizeof(DiskDevice));
firstDiskDevice->type = VFS_DISK_FD;
firstDiskDevice->fileSystem = VFS_FS_FAT12;
firstDiskDevice->location = VFS_LOC_FD0;
firstDiskDevice->link = 0;
strcpy(firstDiskDevice->id, "fd0");
rootDevice = firstDiskDevice;
if (*(byte *)0xC0090000) // the user chose to load an initial ram disk from the floppy
{
DiskDevice *rd = malloc(sizeof(DiskDevice));
firstDiskDevice->link = (dword)rd;
rd->type = VFS_DISK_RD;
rd->fileSystem = VFS_FS_FAT12;
rd->location = 0xC0200000;
rd->link = 0;
strcpy(rd->id, "rd0");
rootDevice = rd;
}
}
byte *vfs_readFile(char *fileName)
{
DiskDevice *dd;
dword fileStartPosition;
if (fileName[0] == '/')
{
dd = rootDevice;
fileStartPosition = 1;
}
else
{
if (strlen(fileName) < 5) //not a long enough file name
return 0;
if (!((fileName[3] == ':') && (fileName[4] == '/'))) //if we aren't using the root directory, then there must be a 3 character device explicitly specified
return 0; // followed by a colon and then a slash
char device[4];
memcpy(device, fileName, 3); //copy the 3 digit device id to device
device[3] = 0; //null-terminating character for device string
dd = vfs_getDiskDeviceByID(device);
if (!dd) //the specified device was not found
return 0;
fileStartPosition = 5;
}
switch (dd->fileSystem)
{
case VFS_FS_FAT12:
return fat12_readFile(fileName+fileStartPosition, dd);
}
return 0;
}
byte *vfs_readSector(DiskDevice *dd, dword sector, byte *dest, dword sectors)
{
byte *origDest = dest;
switch (dd->type)
{
case VFS_DISK_RD:
for (; sectors > 0; sectors--, dest += 512, sector++)
rd_readSector(dd, sector, dest);
return origDest;
}
return 0;
}
DiskDevice *vfs_getDiskDeviceByID(char *id)
{
DiskDevice *dd = firstDiskDevice;
for (;;)
{
if (strcmp(dd->id, id))
return dd;
dd = (DiskDevice *)dd->link;
if (!dd)
break;
}
return 0;
}
+33
View File
@@ -0,0 +1,33 @@
// vfs.h
// Author: Josh Holtrop
// Created: 12/31/03
// Modified: 01/04/04
#define VFS_DISK_RD 1
#define VFS_DISK_FD 2
#define VFS_DISK_HD 3
#define VFS_FS_FAT12 1
#define VFS_LOC_FD0 1
typedef struct {
dword type;
dword fileSystem;
dword location;
dword link;
char id[4];
} __attribute__((packed)) DiskDevice;
void vfs_init();
byte *vfs_readFile(char *fileName);
byte *vfs_readSector(DiskDevice *dd, dword sector, byte *dest, dword sectors);
DiskDevice *vfs_getDiskDeviceByID(char *id);
DiskDevice *rootDevice = 0;
DiskDevice *firstDiskDevice = 0;
+108 -83
View File
@@ -1,151 +1,176 @@
//video.c //video.c
// 08/13/03 Josh Holtrop // 08/13/03 Josh Holtrop
// Modified: 11/12/03
ModeInfoBlock video_mode;
byte *vid_ptr24;
word *vid_ptr16;
dword *vid_ptr32;
void video_init(ModeInfoBlock *mib) //Initialized the video mode information block video_mode and allocated double-buffer memory for graphics display
void video_init()
{ {
video_mode = *mib; videoMode = *(word *)0xC0090002;
if (!videoMode) //we are in console mode
return;
video_mode = *(ModeInfoBlock *) 0xC0090306;
switch(video_mode.BitsPerPixel) switch(video_mode.BitsPerPixel)
{ {
case 16: case 16:
vid_ptr16 = (word *) video_mode.PhysBasePtr; video_psetp = &video_psetp16;
break; break;
case 24: case 24:
vid_ptr24 = (byte *) video_mode.PhysBasePtr; video_psetp = &video_psetp24;
break; break;
case 32: case 32:
vid_ptr32 = (dword *) video_mode.PhysBasePtr; video_psetp = &video_psetp32;
}
dword tot = ((video_mode.XResolution) * (video_mode.YResolution));
int a;
for (a = 0; a < tot; a++)
{
if (a < (tot / 4))
video_psetp(a, 0x00FF0000);
else if (a < (tot / 2))
video_psetp(a, 0x0000FF00);
else if (a < ((tot * 3) / 4))
video_psetp(a, 0x000000FF);
else
video_psetp(a, 0x00FFFFFF);
} }
} }
void video_horiz(int y, int x1, int x2, dword color) //Renders a character using stdfont[] as a bitmask
void video_renderChar(int x, int y, int character, dword color)
{
int charpos = (character & 0xFF) * 8;
int row;
int col;
for (row = 0; row < 8; row++)
{
for (col = 0; col < 5; col++)
{
if ((stdfont[charpos+row] >> (col+3)) & 0x01)
video_pset(x+(5-col), y+row, color);
}
}
}
//Draws a horizontal line
void video_horiz(int y, int x1, int x2, dword color)
{ {
checkBoundsy(y);
checkBoundsx(x1);
checkBoundsx(x2);
if (x1 > x2) if (x1 > x2)
{ {
int tmp = x2; int tmp = x2;
x2 = x1; x2 = x1;
x1 = tmp; x1 = tmp; //x2 >= x1 now
} }
if (x2 < 0)
return;
if (x1 > video_mode.XResolution)
return;
if (x1 < 0)
x1 = 0;
if (x2 > video_mode.XResolution)
x2 = video_mode.XResolution;
int pixel = y*video_mode.XResolution+x1; int pixel = y*video_mode.XResolution+x1;
int a; for (; x1 <= x2; x1++)
for (a = 0; a <= (x2-x1); a++)
{ {
video_psetp(pixel, color); video_psetp(pixel++, color);
pixel++;
} }
} }
void video_vert(int x, int y1, int y2, dword color) //Draws a vertical line
void video_vert(int x, int y1, int y2, dword color)
{ {
checkBoundsx(x);
checkBoundsy(y1);
checkBoundsy(y2);
if (y1 > y2) if (y1 > y2)
{ {
int tmp = y2; int tmp = y2;
y2 = y1; y2 = y1;
y1 = tmp; y1 = tmp; //y2 >= y1 now
} }
if (y2 < 0)
return;
if (y1 > video_mode.YResolution)
return;
if (y1 < 0)
y1 = 0;
if (y2 > video_mode.YResolution)
y2 = video_mode.YResolution;
int pixel = y1*video_mode.XResolution+x; int pixel = y1*video_mode.XResolution+x;
int a; for (; y1 <= y2; y1++)
for (a = 0; a <= (y2-y1); a++)
{ {
video_psetp(pixel, color); video_psetp(pixel, color);
pixel+=video_mode.XResolution; pixel+=video_mode.XResolution;
} }
} }
void video_rect(int x1, int y1, int x2, int y2, dword color) //Draws a rectangle
void video_rect(int x1, int y1, int x2, int y2, dword color)
{ {
checkBoundsx(x1);
checkBoundsx(x2);
checkBoundsy(y1);
checkBoundsy(y2);
if (x2 < x1)
{
int tmp = x2;
x2 = x1;
x1 = tmp;
}
if (y2 < y1)
{
int tmp = y2;
y2 = y1;
y1 = tmp;
}
video_horiz(y1, x1, x2, color); video_horiz(y1, x1, x2, color);
video_horiz(y2, x1, x2, color); video_horiz(y2, x1, x2, color);
video_vert(x1, y1, y2, color); video_vert(x1, y1, y2, color);
video_vert(x2, y1, y2, color); video_vert(x2, y1, y2, color);
} }
void video_rectf(int x1, int y1, int x2, int y2, dword color) //Draws a filled rectangle
void video_rectf(int x1, int y1, int x2, int y2, dword color)
{ {
checkBoundsx(x1);
checkBoundsx(x2);
checkBoundsy(y1);
checkBoundsy(y2);
if (x2 < x1)
{
int tmp = x2;
x2 = x1;
x1 = tmp;
}
if (y2 < y1) if (y2 < y1)
{ {
int tmp = y2; int tmp = y2;
y2 = y1; y2 = y1;
y1 = tmp; y1 = tmp;
} }
int a; for (; y1 <= y2; y1++)
for (a = 0; a <= (y2-y1); a++) video_horiz(y1, x1, x2, color);
video_horiz(y1+a, x1, x2, color);
} }
//Draws a single pixel
inline void video_pset(int x, int y, dword color) inline void video_pset(int x, int y, dword color)
{ {
if ((x < 0) || (x > video_mode.XResolution) || (y < 0) || (y > video_mode.YResolution))
return;
video_psetp(y*video_mode.XResolution+x, color); video_psetp(y*video_mode.XResolution+x, color);
} }
void video_psetp(int pixel, dword color) //Draws a pixel at the specified pixel position
void video_psetp16(int pixel, dword color)
{ {
switch(video_mode.BitsPerPixel) vid_ptr16[pixel] = ((color&0xFF)>>3) | ((((color>>8)&0xFF)>>2)<<5) | ((((color>>16)&0xFF)>>3)<<11);
}
//Draws a pixel at the specified pixel position
void video_psetp24(int pixel, dword color)
{
vid_ptr24[pixel*3] = color & 0xFF;
vid_ptr24[pixel*3+1] = (color>>8) & 0xFF;
vid_ptr24[pixel*3+2] = (color>>16) & 0xFF;
}
//Draws a pixel at the specified pixel position
void video_psetp32(int pixel, dword color)
{
vid_ptr32[pixel] = color;
}
//Dummy function to not draw anything if there is no graphical mode enabled
void video_psetpnull(int pixel, dword color) {}
// This function draws a simple "console" window in graphical mode to display text
void video_drawConsole()
{
video_rectf(9, 9, 490, 260, 0);
video_rect(8, 8, 491, 261, 0x00777777);
int x, y;
for (x = 0; x < 80; x++)
{ {
case 16: for (y = 0; y < 25; y++)
vid_ptr16[pixel] = ((color&0xFF)>>3) | ((((color>>8)&0xFF)>>2)<<6) | ((((color>>16)&0xFF)>>3)<<11); {
//vid_ptr16[pixel] = ((color&0xFF)>>3) | ((((color>>8)&0xFF)>>3)<<5) | ((((color>>16)&0xFF)>>3)<<10); video_renderChar(x*6+10, y*10+10, console_memory[y*80+x], 0x00FFFFFF);
break; }
case 24:
vid_ptr24[pixel*3] = color & 0xFF;
vid_ptr24[pixel*3+1] = (color>>8) & 0xFF;
vid_ptr24[pixel*3+2] = (color>>16) & 0xFF;
break;
case 32:
vid_ptr32[pixel] = color;
} }
} }
// This function draws a "console" character to the graphical video screen
void video_drawConsoleChar(dword position)
{
int x = position % 80;
int y = position / 80;
video_renderChar(x*6+10, y*10+10, console_memory[y*80+x], 0x00FFFFFF);
}
+22 -9
View File
@@ -1,18 +1,22 @@
//video.h //video.h
// 08/18/03 Josh Holtrop // 08/18/03 Josh Holtrop
// Modified: 12/28/03
void video_init(); void video_init();
void video_horiz(int y, int x1, int x2, dword color); void video_horiz(int y, int x1, int x2, dword color);
void video_vert(int x, int y1, int y2, dword color); void video_vert(int x, int y1, int y2, dword color);
void video_rect(int x1, int y1, int x2, int y2, dword color); void video_rect(int x1, int y1, int x2, int y2, dword color);
void video_rectf(int x1, int y1, int x2, int y2, dword color); void video_rectf(int x1, int y1, int x2, int y2, dword color);
inline void video_pset(int x, int y, dword color); inline void video_pset(int x, int y, dword color);
void video_psetp(int pixel, dword color); void video_psetp16(int pixel, dword color);
void video_psetp24(int pixel, dword color);
void video_psetp32(int pixel, dword color);
void video_psetpnull(int pixel, dword color);
void video_renderChar(int x, int y, int character, dword color);
void video_drawConsole();
void video_drawConsoleChar(dword position);
#define checkBoundsx(x) (x<0 ? x=0 : (x>=video_mode.XResolution ? x=video_mode.XResolution-1 : 0))
#define checkBoundsy(x) (x<0 ? x=0 : (x>=video_mode.YResolution ? x=video_mode.YResolution-1 : 0))
typedef struct{ typedef struct{
word ModeAttributes; word ModeAttributes;
byte WinAAttributes; byte WinAAttributes;
@@ -53,6 +57,15 @@ typedef struct{
} ModeInfoBlock; } ModeInfoBlock;
ModeInfoBlock video_mode;
dword videoMode = 0; //what video mode # we are in, 0 for console mode
word *vid_ptr16 = (word *)0xF0000000;
byte *vid_ptr24 = (byte *)0xF0000000;
dword *vid_ptr32 = (dword *)0xF0000000;
word console_memory[2000]; //holds a copy of the console's memory
void (*video_psetp)(int, dword) = video_psetpnull; //function pointer to set a pixel
+354
View File
@@ -0,0 +1,354 @@
// vmm.c
// Author: Josh Holtrop
// Date: 09/30/03
// Rewritten from scratch: 12/23/03
// Modified: 12/30/03
// This is the initialization procedure for the Virtual Memory Manager
// It sets up the final page directory/page table setup and maps video memory, if present
void vmm_init()
{
dword *pageTables = (dword *)0xC0104000; //this is the location of the page directory
pageTables[0x3FF] = 0x104000|0x03; //the last page directory entry points to the page directory itself
pageTables[0] = 0;
invlpg(0);
if (videoMode) //we are in a graphical mode
{
dword vidPages = video_mode.XResolution * video_mode.YResolution * (video_mode.BitsPerPixel >> 3);
if (vidPages % 4096)
vidPages = (vidPages >> 12) + 1;
else
vidPages = (vidPages >> 12);
vmm_mapn(0xF0000000, video_mode.PhysBasePtr, vidPages);
}
dword firstHeapEntryBlock = (dword)mm_palloc();
vmm_map1((dword)firstHeapEntry, firstHeapEntryBlock);
HeapEntryBlock *heb = (HeapEntryBlock *)firstHeapEntry;
vmm_heb_init(heb);
heb->entry[0].base = (dword)firstHeapEntry; //start of kernel's heap memory
heb->entry[0].size = 4096; //the first HeapEntryBlock is 1 page long
heb->entry[0].attributes = VMM_HE_HEB; //this is a HeapEntryBlock
heb->entry[1].base = (dword)firstHeapEntry+4096; //this is the start of the rest of the kernel's heap memory
heb->entry[1].size = 0x10000000-4096; //the rest of the kernel's heap memory: 256mb - 4kb
heb->entry[1].attributes = VMM_HE_HOLE; //this is a hold - an unmapped section of heap memory
}
// This function initialzes a Heap Entry Block to unused entries linked together
void vmm_heb_init(HeapEntryBlock *heb)
{
int a;
for (a = 0; a < 256; a++)
{
heb->entry[a].base = 0;
heb->entry[a].size = 0;
heb->entry[a].attributes = VMM_HE_UNUSED;
heb->entry[a].link = (dword)&(heb->entry[a+1]);
}
heb->entry[255].link = 0;
}
// This function maps a virtual address to a physical address using the page directory / page table
void vmm_map1(dword virt, dword physical)
{
dword pde = virt >> 22;
dword pte = (virt & 0x003FF000) >> 12;
dword *pageTables = (dword *)0xC0104000; //this is the location of the page directory
if (!(pageTables[pde] & 0x01)) //the page directory entry does not exist, we must allocate a page for it
{
dword *newpagetable = mm_palloc();
pageTables[pde] = ((dword)newpagetable) | 0x03;
invlpg(virt);
dword *newpteptr = (dword *)(0xFFC00000 | (pde << 12)); //points to first dword of newly allocated page table
int a;
for (a = 0; a < 1024; a++)
{
newpteptr[a] = 0;
}
}
dword *pteptr = (dword *)(0xFFC00000 | (pde << 12) | (pte << 2));
*pteptr = physical | 0x03;
invlpg(virt);
}
// This function maps a variable number of pages in a row
void vmm_mapn(dword virt, dword physical, dword n)
{
for (; n > 0; n--)
{
vmm_map1(virt, physical);
virt += 4096;
physical += 4096;
}
}
// This function removes the virtual address's entry in the page directory / page table
void vmm_unmap1(dword virt)
{
dword *pteptr = (dword *)(0xFFC00000 | ((virt & 0xFFC00000) >> 10) | ((virt & 0x003FF000) >> 10));
*pteptr = 0;
invlpg(virt);
}
// This function removes multiple pages' entries
void vmm_unmapn(dword virt, dword n)
{
for (; n > 0; n--)
{
vmm_unmap1(virt);
virt += 4096;
}
}
// Virtual Memory allocator function
void *malloc(dword bytes)
{
if (bytes % VMM_MALLOC_GRANULARITY)
bytes = bytes + VMM_MALLOC_GRANULARITY - (bytes % VMM_MALLOC_GRANULARITY);
void *attempt = vmm_getFreeChunk(bytes);
if (attempt)
return attempt;
if(vmm_moreCore(bytes))
return 0; //we could not get any more heap memory
return vmm_getFreeChunk(bytes);
}
// This function returns a pointer if a free chunk of memory exists
void *vmm_getFreeChunk(dword bytes)
{
HeapEntry *he = firstHeapEntry;
for (;;)
{
if (he->attributes == VMM_HE_FREE)
{
if (he->size > bytes)
{
HeapEntry *nhe = vmm_nextHeapEntry();
nhe->base = he->base;
nhe->size = bytes;
nhe->attributes = VMM_HE_USED;
he->base += bytes;
he->size -= bytes;
return (void *)(nhe->base);
}
if (he->size == bytes)
{
he->attributes = VMM_HE_USED;
return (void *)(he->base);
}
}
he = (HeapEntry *)he->link;
if (!he)
break;
}
return 0;
}
// This function coalesces any two adjacent heap entries into one entry
void vmm_coalesceHeapEntry(HeapEntry *he)
{
if (!(he->attributes == VMM_HE_FREE || he->attributes == VMM_HE_HOLE))
return;
if (he->size == 0)
{
he->attributes = VMM_HE_UNUSED;
return;
}
HeapEntry *hec = firstHeapEntry;
for (;;)
{
if (hec->attributes == he->attributes)
{
if ((hec->base + hec->size) == he->base) //hec ends where he begins
{
he->base = hec->base;
he->size += hec->size;
hec->attributes = VMM_HE_UNUSED;
}
if ((he->base + he->size) == hec->base) //he ends where hec begins
{
he->size += hec->size;
hec->attributes = VMM_HE_UNUSED;
}
}
hec = (HeapEntry *)hec->link;
if (!hec)
break;
}
}
// This function retrieves more physical memory for the heap
int vmm_moreCore(dword bytes)
{
dword pages = (bytes >> 12) + 1;
bytes = pages << 12;
HeapEntry *he = vmm_getFirstHoleHeapEntry(bytes);
dword virt = he->base;
for (; pages > 0; pages--)
{
dword phys = (dword)mm_palloc();
if (!phys)
return 1;
vmm_map1(virt, phys);
virt += 4096;
}
if (he->size == bytes)
{
he->attributes = VMM_HE_FREE;
vmm_coalesceHeapEntry(he);
}
else
{
HeapEntry *nhe = vmm_nextHeapEntry();
nhe->base = he->base;
nhe->size = bytes;
nhe->attributes = VMM_HE_FREE;
he->base += bytes;
he->size -= bytes;
vmm_coalesceHeapEntry(nhe);
}
return 0;
}
// This function returns the next available heap entry, creates more entries if we are running low
HeapEntry *vmm_nextHeapEntry()
{
if (vmm_heapEntriesLeft() < 10)
vmm_addHeapEntryBlock();
return vmm_getFirstUnusedHeapEntry();
}
// This function creates a new block (page) of heap entries (256)
void vmm_addHeapEntryBlock()
{
HeapEntry *he = vmm_getFirstHoleHeapEntry(4096);
HeapEntry *newBlock = vmm_getFirstUnusedHeapEntry();
dword heb = (dword)mm_palloc();
vmm_map1(he->base, heb);
vmm_heb_init((HeapEntryBlock *)he->base);
HeapEntry *lhe = vmm_getLastHeapEntry();
if (he->size == 4096)
{
he->attributes = VMM_HE_HEB;
lhe->link = (dword)he->base;
}
else
{
newBlock->base = he->base;
newBlock->size = 4096;
newBlock->attributes = VMM_HE_HEB;
he->base += 4096;
he->size -= 4096;
lhe->link = (dword)newBlock->base;
}
return;
}
// This function returns the last heap entry in the linked list, useful for setting
// its link field to point to the first entry of a newly allocated list
HeapEntry *vmm_getLastHeapEntry()
{
HeapEntry *he = firstHeapEntry;
for (;;)
{
if (he->link == 0)
return he;
he = (HeapEntry *)he->link;
}
}
// This function returns the first heap entry corresponding to a memory "hole"
HeapEntry *vmm_getFirstHoleHeapEntry(dword minBytes)
{
HeapEntry *he = firstHeapEntry;
for (;;)
{
if ((he->attributes == VMM_HE_HOLE) && (he->size >= minBytes))
return he;
he = (HeapEntry *)he->link;
if (!he)
break;
}
return 0;
}
// This function returns the first heap entry that is not being used
HeapEntry *vmm_getFirstUnusedHeapEntry()
{
HeapEntry *he = firstHeapEntry;
for (;;)
{
if (he->attributes == VMM_HE_UNUSED)
return he;
he = (HeapEntry *)he->link;
if (!he)
break;
}
return 0;
}
// This function returns the number of heap entries available for use
dword vmm_heapEntriesLeft()
{
HeapEntry *he = firstHeapEntry;
dword entries = 0;
for (;;)
{
if (he->attributes == VMM_HE_UNUSED)
entries++;
he = (HeapEntry *)he->link;
if (!he)
break;
}
return entries;
}
// This function "frees" an area of memory previously allocated with malloc()
int free(void *ptr)
{
HeapEntry *he = vmm_getHeapEntryByBase((dword)ptr);
if (!he)
return 1; //a heap entry starting at the given address was not found
he->attributes = VMM_HE_FREE;
vmm_coalesceHeapEntry(he);
return 0;
}
// This function scans the heap entry linked list for an entry that begins at the given address
HeapEntry *vmm_getHeapEntryByBase(dword base)
{
HeapEntry *he = firstHeapEntry;
for (;;)
{
if (he->base == base)
return he;
he = (HeapEntry *)he->link;
if (!he)
break;
}
return 0;
}
+55
View File
@@ -0,0 +1,55 @@
// vmm.h
// Author: Josh Holtrop
// Date: 09/30/03
// Rewritten from scratch: 12/23/03
// Modified: 12/30/03
#define VMM_HE_UNUSED 0 //available entry
#define VMM_HE_FREE 1 //free section of memory
#define VMM_HE_USED 2 //used section of memory
#define VMM_HE_HOLE 3 //a "hole" (unmapped) section of virtual memory
#define VMM_HE_HEB 4 //HeapEntryBlock
#define VMM_MALLOC_GRANULARITY 4 //granularity for all memory requests
typedef struct {
dword base; //virtual base address
dword size; //size in bytes
dword attributes; //free/used/hole
dword link; //link to next HeapEntry
} __attribute__((packed)) HeapEntry;
typedef struct {
HeapEntry entry[256]; //256 HeapEntry objects = 4kb (1 page)
} __attribute__((packed)) HeapEntryBlock;
void vmm_init();
void *malloc(dword bytes);
int free(void *ptr);
void vmm_map1(dword virt, dword physical);
void vmm_mapn(dword virt, dword physical, dword n);
void vmm_unmap1(dword virt);
void vmm_unmapn(dword virt, dword n);
void vmm_heb_init(HeapEntryBlock *heb);
void *vmm_getFreeChunk(dword bytes);
HeapEntry *vmm_nextHeapEntry();
dword vmm_heapEntriesLeft();
HeapEntry *vmm_getLastHeapEntry();
HeapEntry *vmm_getFirstUnusedHeapEntry();
HeapEntry *vmm_getFirstHoleHeapEntry(dword minBytes);
void vmm_addHeapEntryBlock();
int vmm_moreCore(dword bytes);
void vmm_coalesceHeapEntry(HeapEntry *he);
HeapEntry *vmm_getHeapEntryByBase(dword base);
HeapEntry *firstHeapEntry = (HeapEntry *)0xD0000000; //this is where heap memory starts