19 Commits
Author SHA1 Message Date
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
47 changed files with 1116 additions and 261 deletions

No files matched your search

+89 -17
View File
@@ -1,18 +1,21 @@
//Functions.c
//05/07/03 Josh Holtrop
//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
{
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
{
asm volatile ("outw %%ax,%%dx"::"d" (port), "a" (value));
};
//Reads a byte from a port
inline byte inportb(unsigned short port)
{
unsigned char ret_val;
@@ -23,47 +26,114 @@ inline byte inportb(unsigned short port)
return ret_val;
};
void enable_ints()
//Enables (SeTs) Interrupt Flag on the processor
inline void enable_ints()
{
asm("sti");
};
void disable_ints()
//Disables (CLears) Interrupt Flag on the processor
inline void disable_ints()
{
asm("cli");
};
//Re-maps the Programmable Interrupr Controllers so IRQ0->pic1 base address, IRG8->pic2 base address
void remap_pics(int pic1, int pic2)
{
byte a1, a2;
a1 = inportb(PIC1_DATA);
a2 = inportb(PIC2_DATA);
a1 = inportb(PIC1_DATA); //0x21
a2 = inportb(PIC2_DATA); //0xA1
outportb(PIC1_COMMAND, ICW1_INIT+ICW1_ICW4);
outportb(PIC2_COMMAND, ICW1_INIT+ICW1_ICW4);
outportb(PIC1_DATA, pic1);
outportb(PIC2_DATA, pic2);
outportb(PIC1_DATA, 4);
outportb(PIC2_DATA, 2);
outportb(PIC1_DATA, ICW4_8086);
outportb(PIC2_DATA, ICW4_8086);
outportb(PIC1_COMMAND, ICW1_INIT+ICW1_ICW4); //0x20, 0x10+0x01 00010001b
outportb(PIC2_COMMAND, ICW1_INIT+ICW1_ICW4); //0xA0, 0x10+0x01 00010001b
outportb(PIC1_DATA, pic1); //0x21, pic1
outportb(PIC2_DATA, pic2); //0xA1, pic2
outportb(PIC1_DATA, 4); //0x21, 0x04 00000100b
outportb(PIC2_DATA, 2); //0xA1, 0x02 00000010b
outportb(PIC1_DATA, ICW4_8086); //0x21, 0x01 00000001b
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()
{
byte temp;
do
{
temp = inportb(0x64);
if (temp & 1)
inportb(0x60);
} while(temp & 2);
outportb (0x64, 0xfe);
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
}
//Invalidates the page tables to re-cache the Translation Lookaside Buffer
/*inline void invlpg()
{
asm("invlpg");
}*/
//Signals an End Of Interrupt signal to the first PIC
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);
}
@@ -72,3 +142,5 @@ inline void eoi()
+45
View File
@@ -0,0 +1,45 @@
; asmfuncs.asm
; Josh Holtrop
; 10/23/03
;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 CR3 register
;extern dword read_cr3();
[global _read_cr3]
_read_cr3:
mov eax, cr3;
ret
Executable
+19
View File
@@ -0,0 +1,19 @@
@echo off
echo Backing up to .\Backup\%1
mkdir .\Backup\%1
mkdir .\Backup\%1\lib
copy *.h .\Backup\%1
copy *.c .\Backup\%1
copy *.inc .\Backup\%1
copy *.asm .\Backup\%1
copy *.ld .\Backup\%1
copy *.bat .\Backup\%1
copy .\lib\*.h .\Backup\%1\lib
copy .\lib\*.c .\Backup\%1\lib
copy .\lib\*.inc .\Backup\%1\lib
copy .\lib\*.asm .\Backup\%1\lib
copy .\lib\*.ld .\Backup\%1\lib
copy .\lib\*.bat .\Backup\%1\lib
+2 -2
View File
@@ -1,12 +1,12 @@
%define VERSION "0.1.2" ;HOS version
%define VERSION "0.12" ;HOS version
%define BOOT_FAT_SEG 0x07E0 ;right after boot sector
%define BOOT_ROOT_SEG 0x0900 ;right after FAT
%define BOOT_KERNEL_SEG 0x0AC0 ;right after ROOT_DIR
%define BOOT_STAGE2_SEG 0x0B00 ;right after KERNEL_SEG
%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 0x104000 ;final pmode kernel destination - physical
%define BOOT_RD_ADD 0x200000 ;2mb for ram disk
%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
+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);
+14 -3
View File
@@ -1,17 +1,28 @@
//functions.h
//05/07/03 Josh Holtrop
//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 outportw(unsigned int port, unsigned int value);
inline byte inportb(unsigned short port);
void enable_ints();
void disable_ints();
inline void enable_ints();
inline void disable_ints();
inline void restart();
inline void halt();
void remap_pics(int pic1, int pic2);
inline void pic1_mask(byte mask);
inline void pic2_mask(byte mask);
inline void eoi();
inline void eoi2();
inline dword kernel_size();
inline void init_timer();
//inline void invlpg();
+4 -1
View File
@@ -1,4 +1,7 @@
;gdt.inc
;Author: Josh Holtrop
;for HOS
;Modified: 10/30/03
gdtr:
dw gdt_end-gdt-1
Executable
+1
View File
@@ -0,0 +1 @@
partcopy -f0 0 168000 flop.img
+4
View File
@@ -1,3 +1,7 @@
;idt.inc
;Author: Josh Holtrop
;for HOS
;Modified: 10/30/03
idtr:
dw 50*8-1 ;size of idt
BIN
View File
Binary file not shown.
+6
View File
@@ -1,5 +1,6 @@
//k_defines.h
//03/17/03 Josh Holtrop
//Modified: 10/30/03
#define PIC1 0x20
#define PIC2 0xA0
@@ -29,6 +30,11 @@
#define BRWHITE_TXT 0x0F
#define FREERAM_START 0x268000
#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 short word;
+9 -4
View File
@@ -1,8 +1,11 @@
;kernel.asm
;Author: Josh Holtrop
;Modified: 10/30/03
%include "bootdef.inc"
%define GDT 0x140000
%define IDT 0x150000
%define GDT 0x100000
%define IDT 0x102000
[global start]
[extern _isr]
@@ -10,6 +13,7 @@
bits 32
;This is where the kernel begins execution
start:
cli ;if they weren't already off
mov edi, GDT
@@ -38,6 +42,7 @@ fill_idt:
mov esi, ebx
add esi, edx
loop fill_idt
mov word [IDT+0x30*8+4], 0xEE00 ;interrupt 0x30 has user priviledges
lgdt [gdtr] ;load gdt
jmp KERNEL_CODE:newgdtcontinue
@@ -52,11 +57,11 @@ newgdtcontinue:
lidt [idtr] ;load idt
call _k_init
haltit:
hlt ;halt processor when k_init is done
jmp $ ;shouldn't get here...
jmp haltit ;shouldn't get here...
%include "gdt.inc"
%include "idt.inc"
+74 -56
View File
@@ -1,91 +1,109 @@
//kernel.c
//08/13/03 Josh Holtrop
//Holtrop's Operating System
//Version: 0.12
//Modified: 11/12/03
#define VXR video_mode.XResolution
#define VYR video_mode.YResolution
#include "k_defines.h" //#DEFINE's for kernel
#include "k_defines.h"
#include "lib/string.h" //library string functions
#include "lib/io.h" //library input/output functions
#include "lib/string.h"
#include "lib/io.h"
#include "functions.h"
#include "video.h"
#include "mm.h"
#include "keyboard.h"
#include "functions.h" //general functions
#include "video.h" //video functions
#include "mm.h" //physical memory management functions
#include "vmm.h" //virtual memory management & paging functions
#include "keyboard.h" //generic keyboard driver & functions
#include "mouse.h" //generic ps/2 mouse driver & functions
#include "fdc.h" //Floppy Disk Controller functions
#include "stdfont.h" //Standard font bitmask array
void isr(dword num);
void k_init();
extern dword write_cr0(dword cr0);
extern dword read_cr0();
extern dword write_cr3(dword cr3);
extern dword read_cr3();
#include "fdc.c"
#include "mouse.c"
#include "keyboard.c"
#include "mm.c"
#include "vmm.c"
#include "functions.c"
#include "video.c"
dword timer = 0;
dword *videoMode;
//Main kernel initialization method
void k_init()
{
remap_pics(0x20, 0x28);
//set timer : 2e9c = 100hz
outportb(0x43, 0x34);
outportb(0x40, 0x9c); //lsb
outportb(0x40, 0x2e); //msb
video_init((ModeInfoBlock *) 0x90306);
mm_init();
enable_ints();
// ===== Initialization
fdc_sendDOR(0x0C); //turn off floppy motor!!
console_cls();
printf("Memory available to OS: %d MB\n (Bytes: %d)", mm_totalmem/0x100000, mm_totalmem);
remap_pics(0x20, 0x28);
init_timer();
mm_init();
videoMode = (dword *)0x90002;
if (*videoMode)
video_init((ModeInfoBlock *) 0x90306);
vmm_init();
mouse_init();
vmm_enable_paging();
pic1_mask(0); //unmask IRQ's 0-7
pic2_mask(0); //unmask IRQ's 8-15
enable_ints();
kbd_resetLEDs(); //after enabling interrupts!!
for (;;)
printf("%c ", kbdWaitKey());
/* pageblock *pb = first_pageblock;
char *bmpptr = (char *)0x108000+54;
int a = 0;
int x = 0;
int y = 479;
for (a=0; a < 640*480; a++)
{
video_pset(x, y, *(dword *)bmpptr);
bmpptr += 3;
x++;
if (x == 640)
{
x = 0;
y--;
}
}
printf("HOS 0.12 - Kernel Size: %d kb\n", kernel_size()/1024);
printf("Memory available to OS: %d MB (Bytes: %d)\n", mm_totalmem/0x100000, mm_totalmem);
printf("Free memory: %d bytes\n", mm_freemem());
dword key = 0;
for (;;)
{
if (pb->flags == MM_PB_NP)
break;
printf("\nBase: 0x%x; Limit: 0x%x; Flags: 0x%x, Link: 0x%x", pb->base, pb->length, pb->flags, pb->link);
pb = (pageblock *) pb->link;
} */
key = kbdWaitKey();
if ((key & 0xFF) > 2) //key is not a control key
putc(key);
}
}
// main Interrupt Service Routine - handles all interrupts unless caught by kernel.asm
void isr(dword num)
{
switch(num)
{
case 0x20:
case 0x20: // IRQ0 - timer interrupt
timer++;
(*(byte *)0xb8000)++;
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;
}
(*(byte *)(0xb8000))++;
eoi();
break;
case 0x21:
printf("------------------KEYBOARD ISR--------------------------\n");
isr_keyboard();
case 0x21: // IRQ1 - keyboard interrupt
isr_keyboard(); //isr_keybard() takes care of calling eoi()
break;
case 0x2C: // IRQ12 - PS/2 mouse
isr_mouse();
eoi2();
break;
default:
printf("Interrupt %d (0x%x) Unhandled!!\n", num, num);
break;
}
}
+38 -33
View File
@@ -1,43 +1,45 @@
//Keyboard.c
// Created: 04/17/03 Josh Holtrop
// Modified: 09/09/03
// Modified: 10/30/03
//for HOS
#define KBD_BUFFER_LENGTH 64
byte kbdFlags = 0;
byte kbdAscii = 0;
byte kbdScan = 0;
byte kbdFlags = 0; //holds current keyboard flags - caps/num/scroll/shift/ctrl/alt
byte kbdAscii = 0; //holds ASCII value of a key pressed
byte kbdScan = 0; //holds the keyboard scan code of a key pressed
dword kbdBuffer[KBD_BUFFER_LENGTH];
byte kbdBufferStart = 0;
byte kbdBufferLen = 0;
byte kbdExt = 0;
byte kbdExt2 = 0;
dword kbdBuffer[KBD_BUFFER_LENGTH]; //a buffer for all keypresses
int kbdBufferStart = 0; //position of next key in buffer
int kbdBufferLen = 0; //number of keys left in the buffer
byte kbdExt = 0; //# of extended key codes left to input
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)
//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....
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";
//====FUNCTIONS:
// The Keyboard Interrupt Service Routine
void isr_keyboard()
{
kbdScan = inportb(0x60);
//printf("\nKEYBOARD INTERRUPT: 0x%x", kbdScan);
byte inState = inportb(0x61);
outportb(0x61, inState|0x80);
outportb(0x61, inState);
printf("IRQ 1: %x\n", kbdScan);
//printf("IRQ 1: %x\n", kbdScan);
if (kbdScan == 0xFA) //250 //ACKnowledge
{
//printf("KBD_ACK 0x%x!\n", ackReason);
if (ackReason == 0xED) //reset LEDs
{
outportb(0x64, (kbdFlags & 0x07));
printf("KBD_ACK!");
outportb(0x60, (kbdFlags & 0x07));
}
ackReason = 0;
}
@@ -47,7 +49,7 @@ void isr_keyboard()
eoi();
return;
}
if (kbdScan == 225)
if (kbdScan == 225) //2nd-set-extended key
{
kbdExt2 = 2;
eoi();
@@ -169,7 +171,8 @@ void isr_keyboard()
}
//====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.");
restart();
@@ -188,57 +191,59 @@ void isr_keyboard()
}
else
{
kbdBuffer[(kbdBufferStart+kbdBufferLen)%KBD_BUFFER_LENGTH] = (dword) ((kbdFlags << 16) | (kbdScan << 8) | kbdAscii);
kbdBufferLen++;
kbdBuffer[(kbdBufferStart+kbdBufferLen++)%KBD_BUFFER_LENGTH] = (dword) ((kbdFlags << 16) | (kbdScan << 8) | kbdAscii);
// printf("S:%d\tL:%d\tR:%x\n", kbdBufferStart, kbdBufferLen, kbdBuffer[kbdBufferStart]);
}
}
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'))
return (asciiCode + ('a' - 'A'));
if ((asciiCode >= 'a') & (asciiCode <= 'z'))
return (asciiCode - ('a' - 'A'));
return asciiCode;
}
}*/
//Gets a key from the buffer, returns 0 if no keys available, returns immediately
dword kbdGetKey()
{
if (kbdBufferLen == 0) //buffer empty
return 0;
dword retVal = kbdBuffer[kbdBufferStart];
printf("S:%d\tE:%d\tR:%x\n", kbdBufferStart, kbdBufferLen, retVal);
kbdBufferStart++;
kbdBufferLen--;
if (kbdBufferStart == KBD_BUFFER_LENGTH)
if (kbdBufferStart >= KBD_BUFFER_LENGTH)
kbdBufferStart = 0;
return retVal;
}
//Gets a key from the buffer, if no keys available, waits for one to be entered
dword kbdWaitKey()
{
dword retVal = 0;
for (;;)
{
retVal = kbdGetKey();
if (retVal != 0)
{
printf("S:%d\tE:%d\tR:%x\n", kbdBufferStart, kbdBufferLen, retVal);
if (kbdBufferLen != 0) //buffer empty
break;
}
dword retVal = kbdBuffer[kbdBufferStart];
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()
{
outportb(0x64, 0xED);
//outportb(0x64, (kbdFlags & 0x07));
outportb(0x60, 0xED);
//outportb(0x60, (kbdFlags & 0x07));
ackReason = 0xED;
}
Executable
+2
View File
@@ -0,0 +1,2 @@
del hlibc.a
ar -r hlibc.a *.o
Executable
+1
View File
@@ -0,0 +1 @@
gcc -ffreestanding -fno-builtin -c *.c
Executable
+2
View File
@@ -0,0 +1,2 @@
nasmw -f aout -l io.lst io.asm -o io_a.o
nasmw -f aout -l misc.lst misc.asm -o misc.o
View File
File renamed without changes.
+5 -3
View File
@@ -25,6 +25,7 @@ _writeCursorPosition:
push ebp
mov ebp, esp
push eax
push ebx
push edx
@@ -49,6 +50,7 @@ _writeCursorPosition:
pop edx
pop ebx
pop eax
pop ebp
ret
@@ -175,7 +177,7 @@ _printf:
push ebp
mov ebp, esp
pusha
mov ebx, [ebp+8] ;ebx = in format string
mov ebx, [ebp+8] ;ebx = position in format string
mov esi, ebp
add esi, 12 ;esi = to next variable arg
xor ecx, ecx ;ecx used if we encounter a '%'
@@ -184,10 +186,10 @@ printf_loop:
inc ebx
cmp al, 0
jzfar printf_done
cmp al, '%'
jzfar printf_percent
cmp ecx, 1
jz printf_special
cmp al, '%'
jzfar printf_percent
push eax
call _putc
+3 -3
View File
@@ -3,9 +3,9 @@
#ifndef __HIO_H__
#define __HIO_H__ __HIO_H__
void writeCursorPosition(word pos);
word getCursorPosition();
int putc(byte chr);
void writeCursorPosition(dword pos);
dword getCursorPosition();
int putc(dword chr);
int printf(char *fmt, ...);
int puts(char *str);
int putDec(int number);
+25
View File
@@ -0,0 +1,25 @@
;void memcpy(dword src, dword dest, dword length)
[global _memcpy]
_memcpy:
push ebp
mov ebp, esp
push esi
push edi
push ecx
mov esi, [ebp+8]
mov edi, [ebp+12]
mov ecx, [ebp+14]
rep movsb
pop ecx
pop edi
pop esi
pop ebp
ret
+8
View File
@@ -0,0 +1,8 @@
#ifndef __HMISC_H__
#define __HMISC_H__ __HMISC_H__
void memcpy(dword src, dword dest, dword length);
#endif
View File
File renamed without changes.
View File
File renamed without changes.
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 .\lib\hlibc.a
+1 -1
View File
@@ -2,7 +2,7 @@ OUTPUT_FORMAT("binary")
ENTRY(start)
SECTIONS
{
.text 0x100000 : {
.text 0x104000 : {
code = .; _code = .; __code = .;
*(.text)
. = ALIGN(4096);
+91 -51
View File
@@ -4,9 +4,15 @@
// 0x368000 is first available byte (this is right after the kernel @ 1mb and the initrd @ 2mb, 1440kb.
//Pointer to the first pageblock in the linked list
pageblock *first_pageblock = (pageblock *) 0;
dword mm_totalmem = 0x100000; //assume 1mb
//The total amount of physical memory available (bytes)
dword mm_totalmem = 0x100000; //start counting from 1mb
//The highest physical address
dword mm_highestAddress = 0;
//This function initializes the memory manager's linked list, filling it with the
// memory areas returned by bios interrupt 0x8E20
void mm_init()
{
dword *memmap_entries = (dword *) 0x9040A;
@@ -17,6 +23,8 @@ void mm_init()
if (maps[a].attributes == 1) // (1) mem free to OS
{
mm_totalmem += maps[a].limit.lowdword;
if (mm_highestAddress < (maps[a].base.lowdword + maps[a].limit.lowdword))
mm_highestAddress = maps[a].base.lowdword + 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 < FREERAM_START)
@@ -26,65 +34,70 @@ void mm_init()
}
if (first_pageblock == 0) //no pageblock page set up yet, so set it up here
{
first_pageblock = (pageblock *) maps[a].base.lowdword ;
first_pageblock = (pageblock *) maps[a].base.lowdword;
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;
first_pageblock->pid = MM_PB_AVAIL;
}
else //first_pageblock already set up, add on segment
{
pageblock *pb = first_pageblock;
for (;;)
{
if (pb->flags == MM_PB_NP)
if (pb->pid == MM_PB_NP)
break;
else
pb++;
}
pb->base = maps[a].base.lowdword;
pb->length = maps[a].limit.lowdword / 4096;
pb->flags = MM_PB_AVAIL;
pb->pid = MM_PB_AVAIL;
}
}
}
}
if (first_pageblock == 0)
{
printf("ERROR! NO INITIAL PAGE BLOCK COULD BE CREATED.");
printf("ERROR! NO INITIAL PAGE BLOCK CREATED.");
asm("cli");
asm("hlt");
for (;;)
;
}
}
//This function initializes a pageblock to be full of empty pointers
void mm_init_pageblockpage(pageblock *pbp)
{
pageblock *pb = pbp;
int a;
for (a=0; a<512; a++)
for (a=0; a<256; a++) // 256 pageblock entries * 16 bytes per page block entry = 4096 bytes (1 page of pageblock entries)
{
pb->base = 0;
pb->length = 0;
pb->flags = MM_PB_NP;
if (a<511)
pb->link = (dword)pb + sizeof(pageblock);
pbp[a].base = 0;
pbp[a].length = 0;
pbp[a].pid = MM_PB_NP;
if (a<255)
pbp[a].link = (dword)(&pbp[a+1]);
else
pb->link = 0;
pb++;
pbp[a].link = 0;
}
}
void *mm_palloc(dword numpages)
//This function allocates a certain number of physical pages for a particular process
//Returns:
// 0 - no free mem, invalied PID
// void* - physical address of allocated pages
void *mm_palloc(dword numpages, dword proc_pid)
{
if (proc_pid < PID_KERNEL)
return 0;
pageblock *pb = first_pageblock;
dword freeentries = mm_freeentries();
if (freeentries < 2)
if (mm_freeentries() < 2)
{
if(mm_new_pageblock_page() == 0)
return 0;
@@ -92,7 +105,7 @@ void *mm_palloc(dword numpages)
pageblock *newentry = mm_nextpageblockentry();
for (;;)
{
if ((pb->flags == MM_PB_AVAIL) && (pb->length >= numpages))
if ((pb->pid == MM_PB_AVAIL) && (pb->length >= numpages))
break;
if (pb->link == 0)
return 0;
@@ -100,14 +113,14 @@ void *mm_palloc(dword numpages)
}
if (pb->length == numpages) //dont need a new entry, just mark this one as used :)
{
pb->flags = MM_PB_USED;
return pb;
pb->pid = proc_pid;
return (void *)pb->base;
}
else //subtract out allocated number of pages from length
{
newentry->base = pb->base;
newentry->length = numpages;
newentry->flags = MM_PB_USED;
newentry->pid = proc_pid;
pb->base += (numpages * 4096);
pb->length -= numpages;
return (void *)newentry->base;
@@ -115,13 +128,14 @@ void *mm_palloc(dword numpages)
}
//This method returns the number of free pageblock entries at the end of the linked list
dword mm_freeentries()
{
pageblock *pb = first_pageblock;
dword counter = 0;
for (;;)
{
if (pb->flags == MM_PB_NP)
if (pb->pid == MM_PB_NP)
counter++;
if (pb->link == 0)
return counter;
@@ -130,12 +144,16 @@ dword mm_freeentries()
}
pageblock *mm_new_pageblock_page()
//This method creates a new page used to hold more pageblock entries at the end of the linked list
//Returns:
// 0 - no free pages
// pageblock* - address of pageblock page
pageblock *mm_new_pageblock_page() //as of 09/26/03 this method leaks 4kb main memory per call, unrecoverable
{
pageblock *pb = first_pageblock;
for (;;)
{
if ((pb->flags == MM_PB_AVAIL) && (pb->length > 1))
if ((pb->pid == MM_PB_AVAIL) && (pb->length > 1))
{
pageblock *retval = (pageblock *)pb->base;
pb->base += 4096;
@@ -151,38 +169,25 @@ pageblock *mm_new_pageblock_page()
}
//This method frees a physical page
//Returns:
// 2 - pointer to free was a null pointer
// 1 - address not found
// 0 - all went well
int mm_pfree(void *ptr)
{
if (ptr == 0)
return 2;
pageblock *pb = first_pageblock;
dword tofree = (dword) ptr;
for (;;)
{
if ((pb->base == tofree) && (pb->flags == MM_PB_USED))
if (pb->base == tofree) // && (pb->pid == 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 ((pbc->base + (pbc->length * 4096)) == pb->base) //pbc ends where pb starts
{
pbc->length += pb->length; //extend pbc's length by pb's length
pb->flags = MM_PB_NP; //mark pb as an unused entry
pb->pid = MM_PB_AVAIL; //found block, mark available / coalesce it
mm_coalesce(pb);
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;
@@ -190,6 +195,7 @@ int mm_pfree(void *ptr)
}
//This method returns a pointer to the last pageblock in the linked list
pageblock *mm_lastpageblockentry()
{
pageblock *pb = first_pageblock;
@@ -202,12 +208,14 @@ pageblock *mm_lastpageblockentry()
}
//This method returns the next available-for-use pageblock entry
// or 0, if they are all used
pageblock *mm_nextpageblockentry()
{
pageblock *pb = first_pageblock;
for (;;)
{
if (pb->flags == MM_PB_NP)
if (pb->pid == MM_PB_NP)
return pb;
if (pb->link == 0)
return 0;
@@ -216,13 +224,14 @@ pageblock *mm_nextpageblockentry()
}
//This method returns the amount of free physical RAM
dword mm_freemem()
{
dword amount = 0;
pageblock *pb = first_pageblock;
for (;;)
{
if (pb->flags == MM_PB_AVAIL)
if (pb->pid == MM_PB_AVAIL)
amount += (pb->length)*4096;
if (pb->link == 0)
return amount;
@@ -231,6 +240,37 @@ dword mm_freemem()
}
//This method "walks" through the linked list of pageblock entries and
// combines any two entries that are adjacent and of the same type
void mm_coalesce(pageblock *pb)
{
pageblock *pbc = first_pageblock;
for (;;)
{
if (pbc->pid == pb->pid) //pid fields must match, both same process, both avail, or both not present
{
if ((pbc->base + (pbc->length * 4096)) == pb->base) //pbc ends where pb starts
{
pbc->length += pb->length;
pb->pid = MM_PB_NP;
mm_coalesce(pbc); //recursion: checks for any more page blocks to coalesce if one found
return; //exit this recursion...
}
if ((pb->base + (pb->length * 4096)) == pbc->base) //pb ends where pbc starts
{
pb->length += pbc->length;
pbc->pid = MM_PB_NP;
mm_coalesce(pb);
return;
}
}
if (pbc->link == 0)
return;
pbc = (pageblock *)pbc->link;
}
}
+6 -7
View File
@@ -10,26 +10,25 @@ typedef struct {
typedef struct {
dword base;
dword length; //in pages
dword flags;
dword link;
} __attribute__ ((packed)) pageblock; //16 byte pageblock entry - 512 entries = 1 page
dword pid; //normally PID of process, use NP, AVAIL for special flags
dword link; //leave dword instead of pointer so i dont have to worry about pointer arithmetic
} __attribute__ ((packed)) pageblock; //16 byte pageblock entry - 256 entries = 1 page
void mm_init();
void mm_init_pageblockpage(pageblock *pbp);
void *mm_palloc(dword numpages);
void *mm_palloc(dword numpages, dword proc_pid);
void mm_coalesce(pageblock *pb);
int mm_pfree(void *ptr);
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
+68
View File
@@ -0,0 +1,68 @@
// 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
//printf("InB: %x\n", inb);
//return;
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);
printf("X: %d, Y: %d\n", mouse_x, mouse_y);
}
else
{
video_pset(mouse_x, mouse_y, 0x00FFFFFF);
printf("X: %d, Y: %d\n", mouse_x, mouse_y);
}
}
}
+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();
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 900 KiB

+3 -3
View File
@@ -28,12 +28,12 @@ brDrive DB 0 ; 0024h - Physical drive no.
DB 0 ; 0025h - Reserved (FAT32)
DB 29H ; 0026h - Extended boot record sig (FAT32)
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
;------------------------------------------------------------------------
start:
jmp 0:jmphere ;ensure that cs=0 and ip=0x7c...
jmp 0:jmphere ;ensure that cs=0 and ip=0x7c00...
jmphere:
;dl=drive number, save it!
xor ax, ax
@@ -88,7 +88,7 @@ unreal:
pop es ;segments back, with 4gb limits!
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 cx, 0x0002
xor dh, dh
+1
View File
@@ -30,6 +30,7 @@ loop_name:
jmp found_file ;good file, ds:si points to start of root directory entry
goon:
pop si
add si, 32
pop cx
loop loop_compare
+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 };
+64 -72
View File
@@ -1,11 +1,9 @@
//video.c
// 08/13/03 Josh Holtrop
// Modified: 11/12/03
ModeInfoBlock video_mode;
byte *vid_ptr24;
word *vid_ptr16;
dword *vid_ptr32;
//Initialized the video mode information block video_mode and allocated double-buffer memory for graphics display
void video_init(ModeInfoBlock *mib)
{
video_mode = *mib;
@@ -14,137 +12,131 @@ void video_init(ModeInfoBlock *mib)
{
case 16:
vid_ptr16 = (word *) video_mode.PhysBasePtr;
video_psetp = &video_psetp16;
break;
case 24:
vid_ptr24 = (byte *) video_mode.PhysBasePtr;
video_psetp = &video_psetp24;
break;
case 32:
video_psetp = &video_psetp32;
vid_ptr32 = (dword *) video_mode.PhysBasePtr;
}
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);
}
}
//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)
{
int tmp = x2;
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 a;
for (a = 0; a <= (x2-x1); a++)
for (; x1 <= x2; x1++)
{
video_psetp(pixel, color);
pixel++;
video_psetp(pixel++, 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)
{
int tmp = y2;
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 a;
for (a = 0; a <= (y2-y1); a++)
for (; y1 <= y2; y1++)
{
video_psetp(pixel, color);
pixel+=video_mode.XResolution;
}
}
//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(y2, x1, x2, color);
video_vert(x1, y1, y2, color);
video_vert(x2, y1, y2, 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)
{
int tmp = y2;
y2 = y1;
y1 = tmp;
}
int a;
for (a = 0; a <= (y2-y1); a++)
video_horiz(y1+a, x1, x2, color);
for (; y1 <= y2; y1++)
video_horiz(y1, x1, x2, color);
}
//Draws a single pixel
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);
}
void video_psetp(int pixel, dword color)
//Draws a pixel at the specified pixel position
void video_psetp16(int pixel, dword color)
{
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)
{
switch(video_mode.BitsPerPixel)
{
case 16:
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);
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:
}
//Draws a pixel at the specified pixel position
void video_psetp32(int pixel, dword color)
{
vid_ptr32[pixel] = color;
}
}
+11 -5
View File
@@ -1,5 +1,6 @@
//video.h
// 08/18/03 Josh Holtrop
// Modified: 11/12/03
void video_init();
void video_horiz(int y, int x1, int x2, dword color);
@@ -7,11 +8,10 @@ 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_rectf(int x1, int y1, int x2, int y2, dword color);
inline void video_pset(int x, int y, dword color);
void video_psetp(int pixel, dword color);
#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))
void video_psetp16(int pixel, dword color);
void video_psetp24(int pixel, dword color);
void video_psetp32(int pixel, dword color);
void video_renderChar(int x, int y, int character, dword color);
typedef struct{
word ModeAttributes;
@@ -52,6 +52,12 @@ typedef struct{
byte Reserved[206];
} ModeInfoBlock;
ModeInfoBlock video_mode;
byte *vid_ptr24;
word *vid_ptr16;
dword *vid_ptr32;
void (*video_psetp)(int, dword); //function pointer to set a pixel
+182
View File
@@ -0,0 +1,182 @@
// vmm.c
// Author: Josh Holtrop
// Date: 09/30/03
PageDirectory *vmm_PDBR = 0;
dword vmm_first_virtual_address = 0;
void vmm_init()
{
if (!(vmm_PDBR = mm_palloc(1, PID_KERNEL)))
{
printf("ERROR! COULD NOT ALLOCATE PAGE FOR INITIAL PAGE DIRECTORY!!\n");
halt();
}
vmm_init_pagetable((dword)vmm_PDBR);
if (mm_totalmem % 4096)
vmm_first_virtual_address = mm_totalmem + (4096 - (mm_totalmem % 4096));
else
vmm_first_virtual_address = mm_totalmem;
if (vmm_mapn(0, 0, 0x03, mm_totalmem/4096+1))
{
printf("Could not page in all physical RAM!\n");
halt();
}
//we also need to map in the video framebuffer memory:
if (video_mode.PhysBasePtr > 0 && video_mode.BitsPerPixel > 0)
{
if (vmm_mapn(video_mode.PhysBasePtr, video_mode.PhysBasePtr, 0x03, ((video_mode.BitsPerPixel>>3) * video_mode.XResolution * video_mode.YResolution)/4096+1))
{
printf("Could not page in video memory at 0x%x!\n", video_mode.PhysBasePtr);
halt();
}
}
}
void vmm_enable_paging()
{
write_cr3((dword)vmm_PDBR);
write_cr0(0x80000000|read_cr0());
}
int vmm_map1(dword virtual, dword physical, dword flags)
{
if (virtual & 0x00000FFF)
return 1; // ERROR 1: address not page-aligned
if (physical & 0x00000FFF)
return 1; // ERROR 1: address not page-aligned
int pde = (virtual & 0xFFC00000) >> 22;
int pte = (virtual & 0x003FF000) >> 12;
if (!(vmm_PDBR->pageTables[pde] & 0x01))
{
vmm_PDBR->pageTables[pde] = (dword)mm_palloc(1, PID_KERNEL) | 0x7; //user, r/w, present
vmm_init_pagetable(vmm_PDBR->pageTables[pde] & 0xFFFFF000);
if (vmm_PDBR->pageTables[pde] == 0x07)
return 2; // ERROR 2: page table could not be created
}
PageTable *ptp = (PageTable *)(vmm_PDBR->pageTables[pde] & 0xFFFFF000);
if (ptp->page[pte] & 0x01)
return 3; // ERROR 3: page table entry already exists
ptp->page[pte] = physical | flags;
//invlpg();
return 0;
}
int vmm_mapn(dword virtual, dword physical, dword flags, dword n)
{
int mapped;
int result = 0;
dword va = virtual;
dword pa = physical;
for (mapped = 0; mapped < n; mapped++)
{
if (result = vmm_map1(va, pa, flags))
{
if (mapped > 0)
vmm_unmapn(virtual, mapped);
return result;
}
va += 4096;
pa += 4096;
}
//invlpg();
return 0;
}
int vmm_unmap1(dword virtual)
{
if (virtual & 0x00000FFF)
return 1; // ERROR 1: address not page-aligned
int pde = (virtual & 0xFFC00000) >> 22;
int pte = (virtual & 0x003FF000) >> 12;
if (!(vmm_PDBR->pageTables[pde] & 0x01))
return 2; // ERROR 2: page table not present
PageTable *ptp = (PageTable *)(vmm_PDBR->pageTables[pde] & 0xFFFFF000);
ptp->page[pte] = 0;
//invlpg();
return 0;
}
int vmm_unmapn(dword virtual, dword n)
{
int reslt;
int i;
for (i = 0; i < n; i++)
{
if (reslt = vmm_unmap1(virtual))
return reslt;
virtual += 4096;
}
vmm_walkPageTables();
//invlpg();
return 0;
}
void vmm_init_pagetable(dword address)
{
PageTable *ptp = (PageTable *)address;
int n;
for (n = 0; n < 1024; n++)
ptp->page[n] = 0;
}
int vmm_walkPageTables()
{
int pde;
int pte;
int used_ptes;
PageTable *ptp;
for (pde = 0; pde < 1024; pde++)
{
if (vmm_PDBR->pageTables[pde] & 0x01)
{
used_ptes = 0;
ptp = (PageTable *)(vmm_PDBR->pageTables[pde] & 0xFFFFF000);
for (pte = 0; pte < 1024; pte++)
{
if (ptp->page[pte] & 0x01) //page table entry present
used_ptes++;
}
if (!(used_ptes)) //no used pte's -- remove page table & page directory entry
{
mm_pfree(ptp);
vmm_PDBR->pageTables[pde] = 0;
}
}
}
return 0;
}
void *malloc(dword bytes)
{
}
int free(void *ptr)
{
}
+31
View File
@@ -0,0 +1,31 @@
// vmm.h
// Author: Josh Holtrop
// Date: 09/30/03
typedef struct {
dword page[1024];
} PageTable;
typedef struct {
dword pageTables[1024];
} PageDirectory;
void vmm_enable_paging();
void vmm_init();
void *malloc(dword bytes);
int free(void *ptr);
int vmm_map1(dword virtual, dword physical, dword flags);
int vmm_mapn(dword virtual, dword physical, dword flags, dword n);
int vmm_unmap1(dword virtual);
int vmm_unmapn(dword virtual, dword n);
void vmm_init_pagetable(dword address);
int vmm_walkPageTables();