BIG refactor (indentation)
This commit is contained in:
parent
96d45988be
commit
d85ee2dee1
40 changed files with 2097 additions and 2100 deletions
|
@ -12,76 +12,76 @@ void **farg = (void**)0x1FFFFFFC;
|
|||
uint32_t *flags = (uint32_t*)0x1FFFFFF4;
|
||||
namespace MTGosHAL {
|
||||
void mainRoutine(void*) {
|
||||
*farg=nullptr;
|
||||
*fpointer=nullptr;
|
||||
while(true) {
|
||||
if(!(*fpointer))
|
||||
continue;
|
||||
(*fpointer)(*farg);
|
||||
*farg=nullptr;
|
||||
*fpointer=nullptr;
|
||||
*flags&=~1;
|
||||
}
|
||||
while(true) {
|
||||
if(!(*fpointer))
|
||||
continue;
|
||||
(*fpointer)(*farg);
|
||||
*farg=nullptr;
|
||||
*fpointer=nullptr;
|
||||
*flags&=~1;
|
||||
}
|
||||
}
|
||||
void initScreen(void*) {
|
||||
//top screen lfb size: 0x5dc00
|
||||
//bottom screen lfb size: 0x4b000
|
||||
//lfb locations: 0x18000000 (left 1)
|
||||
//lfb locations: 0x18060000 (left 2)
|
||||
//lfb locations: 0x180C0000 (right 1)
|
||||
//lfb locations: 0x18120000 (right 2)
|
||||
//lfb locations: 0x18180000 (bottom 1)
|
||||
//lfb locations: 0x181D0000 (bottom 2)
|
||||
unsigned int *lfbs = (unsigned int*)0x18000000;
|
||||
for(int i=0;i<475136;i++)
|
||||
lfbs[i]=0;
|
||||
unsigned int *fb_init=(unsigned int*)0x10400400;
|
||||
fb_init[0x70/4]&=~0x7;
|
||||
fb_init[0x170/4]&=~0x7;
|
||||
fb_init[0x68/4]=0x18000000; //Left eye
|
||||
fb_init[0x6C/4]=0x18060000; //Left eye
|
||||
fb_init[0x90/4]=960;
|
||||
fb_init[0x94/4]=0x180C0000; //Right eye
|
||||
fb_init[0x98/4]=0x18120000; //Right eye
|
||||
fb_init[0x168/4]=0x18180000;
|
||||
fb_init[0x16C/4]=0x181D0000;
|
||||
fb_init[0x190/4]=960;
|
||||
//top screen lfb size: 0x5dc00
|
||||
//bottom screen lfb size: 0x4b000
|
||||
//lfb locations: 0x18000000 (left 1)
|
||||
//lfb locations: 0x18060000 (left 2)
|
||||
//lfb locations: 0x180C0000 (right 1)
|
||||
//lfb locations: 0x18120000 (right 2)
|
||||
//lfb locations: 0x18180000 (bottom 1)
|
||||
//lfb locations: 0x181D0000 (bottom 2)
|
||||
unsigned int *lfbs = (unsigned int*)0x18000000;
|
||||
for(int i=0;i<475136;i++)
|
||||
lfbs[i]=0;
|
||||
unsigned int *fb_init=(unsigned int*)0x10400400;
|
||||
fb_init[0x70/4]&=~0x7;
|
||||
fb_init[0x170/4]&=~0x7;
|
||||
fb_init[0x68/4]=0x18000000; //Left eye
|
||||
fb_init[0x6C/4]=0x18060000; //Left eye
|
||||
fb_init[0x90/4]=960;
|
||||
fb_init[0x94/4]=0x180C0000; //Right eye
|
||||
fb_init[0x98/4]=0x18120000; //Right eye
|
||||
fb_init[0x168/4]=0x18180000;
|
||||
fb_init[0x16C/4]=0x181D0000;
|
||||
fb_init[0x190/4]=960;
|
||||
}
|
||||
void testSVC(void*) {
|
||||
initInterrupts();
|
||||
asm volatile("svc #1");
|
||||
initInterrupts();
|
||||
asm volatile("svc #1");
|
||||
}
|
||||
}
|
||||
struct cpu_info {
|
||||
unsigned int pc;
|
||||
unsigned int r12;
|
||||
unsigned int r11;
|
||||
unsigned int r10;
|
||||
unsigned int r9;
|
||||
unsigned int r8;
|
||||
unsigned int r7;
|
||||
unsigned int r6;
|
||||
unsigned int r5;
|
||||
unsigned int r4;
|
||||
unsigned int r3;
|
||||
unsigned int r2;
|
||||
unsigned int r1;
|
||||
unsigned int retAddr;
|
||||
unsigned int pc;
|
||||
unsigned int r12;
|
||||
unsigned int r11;
|
||||
unsigned int r10;
|
||||
unsigned int r9;
|
||||
unsigned int r8;
|
||||
unsigned int r7;
|
||||
unsigned int r6;
|
||||
unsigned int r5;
|
||||
unsigned int r4;
|
||||
unsigned int r3;
|
||||
unsigned int r2;
|
||||
unsigned int r1;
|
||||
unsigned int retAddr;
|
||||
};
|
||||
extern "C" void handleINT11(uint32_t stack, uint32_t id) {
|
||||
MTGosHAL::Screen out;
|
||||
*flags|=1;
|
||||
out << MTGosHAL::Base::HEXADECIMAL << MTGosHAL::FG_color::RED << "Interrupt! " << (int)stack << "-" << (int)id << "\n";
|
||||
struct cpu_info *cpu=(struct cpu_info*)stack;
|
||||
out << "handler addr " << (int) cpu->pc << "\n";
|
||||
out << "R1 " << (int) cpu->r1 << ", R2 " << (int)cpu->r2 << "\n";
|
||||
out << "R3 " << (int) cpu->r3 << ", R4 " << (int)cpu->r4 << "\n";
|
||||
out << "R5 " << (int) cpu->r5 << ", R6 " << (int)cpu->r6 << "\n";
|
||||
out << "R7 " << (int) cpu->r7 << ", R8 " << (int)cpu->r8 << "\n";
|
||||
out << "R9 " << (int) cpu->r9 << ", SL " << (int)cpu->r10 << "\n";
|
||||
out << "FP " << (int) cpu->r11 << ", IP " << (int)cpu->r12 << "\n";
|
||||
out << "SP " << (int) stack << ", PC " << (int)cpu->retAddr << "\n";
|
||||
*flags&=~1;
|
||||
if((id!=1)&&(id!=2)&&(id!=4))
|
||||
for(;;);
|
||||
MTGosHAL::Screen out;
|
||||
*flags|=1;
|
||||
out << MTGosHAL::Base::HEXADECIMAL << MTGosHAL::FG_color::RED << "Interrupt! " << (int)stack << "-" << (int)id << "\n";
|
||||
struct cpu_info *cpu=(struct cpu_info*)stack;
|
||||
out << "handler addr " << (int) cpu->pc << "\n";
|
||||
out << "R1 " << (int) cpu->r1 << ", R2 " << (int)cpu->r2 << "\n";
|
||||
out << "R3 " << (int) cpu->r3 << ", R4 " << (int)cpu->r4 << "\n";
|
||||
out << "R5 " << (int) cpu->r5 << ", R6 " << (int)cpu->r6 << "\n";
|
||||
out << "R7 " << (int) cpu->r7 << ", R8 " << (int)cpu->r8 << "\n";
|
||||
out << "R9 " << (int) cpu->r9 << ", SL " << (int)cpu->r10 << "\n";
|
||||
out << "FP " << (int) cpu->r11 << ", IP " << (int)cpu->r12 << "\n";
|
||||
out << "SP " << (int) stack << ", PC " << (int)cpu->retAddr << "\n";
|
||||
*flags&=~1;
|
||||
if((id!=1)&&(id!=2)&&(id!=4))
|
||||
for(;;);
|
||||
}
|
||||
|
|
|
@ -4,96 +4,96 @@
|
|||
int x=0, y=0;
|
||||
extern uint32_t *flags;
|
||||
namespace MTGosHAL {
|
||||
FG_color fg=FG_color::WHITE;
|
||||
BG_color bg=BG_color::BLACK;
|
||||
uint32_t* toplfb = (uint32_t*)0x18000000;
|
||||
uint32_t* bottomlfb = (uint32_t*)0x18180000;
|
||||
int base=10;
|
||||
FG_color fg=FG_color::WHITE;
|
||||
BG_color bg=BG_color::BLACK;
|
||||
uint32_t* toplfb = (uint32_t*)0x18000000;
|
||||
uint32_t* bottomlfb = (uint32_t*)0x18180000;
|
||||
int base=10;
|
||||
|
||||
void Screen::putChar(char c) {
|
||||
while(*flags&2); //to prevent garbage to be displayed when ARM9&ARM11 are trying to access it at the same time
|
||||
*flags|=2;
|
||||
switch(c) {
|
||||
case '\n':
|
||||
x=0; y++;
|
||||
break;
|
||||
case '\r':
|
||||
x=0;
|
||||
break;
|
||||
case '\b':
|
||||
x--;
|
||||
if(x<0) x=0;
|
||||
putChar(' ');
|
||||
x--;
|
||||
if(x<0) x=0;
|
||||
break;
|
||||
case '\0':
|
||||
break;
|
||||
default:
|
||||
for(int lx=0;lx<8;lx++) {
|
||||
for(int ly=0;ly<8;ly++) {
|
||||
if(font[(int)((uint8_t)c)][ly]&(1<<lx)) {
|
||||
if(y>=TOP_SCREEN_HEIGHT)
|
||||
bottomlfb[CALCXY(x*8+lx,(y-TOP_SCREEN_HEIGHT)*8+ly)]=__builtin_bswap32(static_cast<uint32_t>(fg));
|
||||
else
|
||||
toplfb[CALCXY(x*8+lx,(y)*8+ly)]=__builtin_bswap32(static_cast<uint32_t>(fg));
|
||||
} else {
|
||||
if(y>=TOP_SCREEN_HEIGHT)
|
||||
bottomlfb[CALCXY(x*8+lx,(y-TOP_SCREEN_HEIGHT)*8+ly)]=__builtin_bswap32(static_cast<uint32_t>(bg));
|
||||
else
|
||||
toplfb[CALCXY(x*8+lx,(y)*8+ly)]=__builtin_bswap32(static_cast<uint32_t>(bg));
|
||||
}
|
||||
}
|
||||
void Screen::putChar(char c) {
|
||||
while(*flags&2); //to prevent garbage to be displayed when ARM9&ARM11 are trying to access it at the same time
|
||||
*flags|=2;
|
||||
switch(c) {
|
||||
case '\n':
|
||||
x=0; y++;
|
||||
break;
|
||||
case '\r':
|
||||
x=0;
|
||||
break;
|
||||
case '\b':
|
||||
x--;
|
||||
if(x<0) x=0;
|
||||
putChar(' ');
|
||||
x--;
|
||||
if(x<0) x=0;
|
||||
break;
|
||||
case '\0':
|
||||
break;
|
||||
default:
|
||||
for(int lx=0;lx<8;lx++) {
|
||||
for(int ly=0;ly<8;ly++) {
|
||||
if(font[(int)((uint8_t)c)][ly]&(1<<lx)) {
|
||||
if(y>=TOP_SCREEN_HEIGHT)
|
||||
bottomlfb[CALCXY(x*8+lx,(y-TOP_SCREEN_HEIGHT)*8+ly)]=__builtin_bswap32(static_cast<uint32_t>(fg));
|
||||
else
|
||||
toplfb[CALCXY(x*8+lx,(y)*8+ly)]=__builtin_bswap32(static_cast<uint32_t>(fg));
|
||||
} else {
|
||||
if(y>=TOP_SCREEN_HEIGHT)
|
||||
bottomlfb[CALCXY(x*8+lx,(y-TOP_SCREEN_HEIGHT)*8+ly)]=__builtin_bswap32(static_cast<uint32_t>(bg));
|
||||
else
|
||||
toplfb[CALCXY(x*8+lx,(y)*8+ly)]=__builtin_bswap32(static_cast<uint32_t>(bg));
|
||||
}
|
||||
}
|
||||
}
|
||||
x++;
|
||||
if(x==(y>=TOP_SCREEN_HEIGHT?BOTTOM_SCREEN_WIDTH:TOP_SCREEN_WIDTH)) {
|
||||
x=0;
|
||||
y++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
x++;
|
||||
if(x==(y>=TOP_SCREEN_HEIGHT?BOTTOM_SCREEN_WIDTH:TOP_SCREEN_WIDTH)) {
|
||||
x=0;
|
||||
y++;
|
||||
}
|
||||
break;
|
||||
if(y>=TOP_SCREEN_HEIGHT+BOTTOM_SCREEN_HEIGHT)
|
||||
scroll_impl();
|
||||
*flags&=~2; //Unlock
|
||||
}
|
||||
if(y>=TOP_SCREEN_HEIGHT+BOTTOM_SCREEN_HEIGHT)
|
||||
scroll_impl();
|
||||
*flags&=~2; //Unlock
|
||||
}
|
||||
void Screen::clrscr_impl() {
|
||||
for(int p=0;p<400*240;p++)
|
||||
toplfb[p]=__builtin_bswap32(static_cast<uint32_t>(bg));
|
||||
for(int p=0;p<320*240;p++)
|
||||
bottomlfb[p]=__builtin_bswap32(static_cast<uint32_t>(bg));
|
||||
}
|
||||
void Screen::scroll_impl() {
|
||||
for(int ly=0;ly<240-8;ly++) {
|
||||
for(int lx=0;lx<400;lx++) {
|
||||
toplfb[CALCXY(lx,ly)]=toplfb[CALCXY(lx,ly+8)];
|
||||
}
|
||||
void Screen::clrscr_impl() {
|
||||
for(int p=0;p<400*240;p++)
|
||||
toplfb[p]=__builtin_bswap32(static_cast<uint32_t>(bg));
|
||||
for(int p=0;p<320*240;p++)
|
||||
bottomlfb[p]=__builtin_bswap32(static_cast<uint32_t>(bg));
|
||||
}
|
||||
for(int ly=0;ly<8;ly++) {
|
||||
for(int lx=0;lx<40;lx++) {
|
||||
toplfb[CALCXY(lx,ly+240-8)]=__builtin_bswap32(static_cast<uint32_t>(bg));
|
||||
}
|
||||
for(int lx=40;lx<360;lx++) {
|
||||
toplfb[CALCXY(lx,ly+240-8)]=bottomlfb[CALCXY(lx-40,ly)];
|
||||
}
|
||||
for(int lx=360;lx<400;lx++) {
|
||||
toplfb[CALCXY(lx,ly+240-8)]=__builtin_bswap32(static_cast<uint32_t>(bg));
|
||||
}
|
||||
void Screen::scroll_impl() {
|
||||
for(int ly=0;ly<240-8;ly++) {
|
||||
for(int lx=0;lx<400;lx++) {
|
||||
toplfb[CALCXY(lx,ly)]=toplfb[CALCXY(lx,ly+8)];
|
||||
}
|
||||
}
|
||||
for(int ly=0;ly<8;ly++) {
|
||||
for(int lx=0;lx<40;lx++) {
|
||||
toplfb[CALCXY(lx,ly+240-8)]=__builtin_bswap32(static_cast<uint32_t>(bg));
|
||||
}
|
||||
for(int lx=40;lx<360;lx++) {
|
||||
toplfb[CALCXY(lx,ly+240-8)]=bottomlfb[CALCXY(lx-40,ly)];
|
||||
}
|
||||
for(int lx=360;lx<400;lx++) {
|
||||
toplfb[CALCXY(lx,ly+240-8)]=__builtin_bswap32(static_cast<uint32_t>(bg));
|
||||
}
|
||||
}
|
||||
for(int ly=0;ly<240-8;ly++) {
|
||||
for(int lx=0;lx<320;lx++) {
|
||||
bottomlfb[CALCXY(lx,ly)]=bottomlfb[CALCXY(lx,ly+8)];
|
||||
}
|
||||
}
|
||||
for(int ly=240-8;ly<240;ly++) {
|
||||
for(int lx=0;lx<320;lx++) {
|
||||
bottomlfb[CALCXY(lx,ly)]=__builtin_bswap32(static_cast<uint32_t>(bg));
|
||||
}
|
||||
}
|
||||
y--;
|
||||
}
|
||||
for(int ly=0;ly<240-8;ly++) {
|
||||
for(int lx=0;lx<320;lx++) {
|
||||
bottomlfb[CALCXY(lx,ly)]=bottomlfb[CALCXY(lx,ly+8)];
|
||||
}
|
||||
auto Screen::a11puts(const char *s) -> void {
|
||||
int i=0;
|
||||
while(s[i])
|
||||
putChar(s[i]);
|
||||
}
|
||||
for(int ly=240-8;ly<240;ly++) {
|
||||
for(int lx=0;lx<320;lx++) {
|
||||
bottomlfb[CALCXY(lx,ly)]=__builtin_bswap32(static_cast<uint32_t>(bg));
|
||||
}
|
||||
}
|
||||
y--;
|
||||
}
|
||||
auto Screen::a11puts(const char *s) -> void {
|
||||
int i=0;
|
||||
while(s[i])
|
||||
putChar(s[i]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,67 +8,67 @@ extern unsigned int _a9vectors_end;
|
|||
extern unsigned int _a11vectors_begin;
|
||||
extern unsigned int _a11vectors_end;
|
||||
namespace MTGosHAL {
|
||||
void mainRoutine(void*);
|
||||
void initScreen(void*);
|
||||
void testSVC(void*);
|
||||
void main() {
|
||||
*a11farg = 0;
|
||||
*a11fpointer=&mainRoutine;
|
||||
while(*a11fpointer);
|
||||
*a11fpointer=&initScreen;
|
||||
while(*a11fpointer);
|
||||
unsigned int * output=(unsigned int*)0x08000000;
|
||||
Screen out;
|
||||
out << "Waiting for interrupt...\n";
|
||||
out << "Copying " << &_a9vectors_end-&_a9vectors_begin << " words...\n";
|
||||
for(int i=0;i<(&_a9vectors_end-&_a9vectors_begin);i++) {
|
||||
output[i]=(&_a9vectors_begin)[i];
|
||||
void mainRoutine(void*);
|
||||
void initScreen(void*);
|
||||
void testSVC(void*);
|
||||
void main() {
|
||||
*a11farg = 0;
|
||||
*a11fpointer=&mainRoutine;
|
||||
while(*a11fpointer);
|
||||
*a11fpointer=&initScreen;
|
||||
while(*a11fpointer);
|
||||
unsigned int * output=(unsigned int*)0x08000000;
|
||||
Screen out;
|
||||
out << "Waiting for interrupt...\n";
|
||||
out << "Copying " << &_a9vectors_end-&_a9vectors_begin << " words...\n";
|
||||
for(int i=0;i<(&_a9vectors_end-&_a9vectors_begin);i++) {
|
||||
output[i]=(&_a9vectors_begin)[i];
|
||||
}
|
||||
asm volatile("svc #0\n");
|
||||
out << "Did it work?\nSetting up A11 interrupts\n";
|
||||
output=(unsigned int*)0x1FF80000;
|
||||
out << "Copying " << &_a11vectors_end-&_a11vectors_begin << " words...\n";
|
||||
for(int i=0;i<(&_a11vectors_end-&_a11vectors_begin);i++) {
|
||||
output[i]=(&_a11vectors_begin)[i];
|
||||
}
|
||||
out << "Done!\n";
|
||||
*a11fpointer=&testSVC;
|
||||
while(*a11fpointer);
|
||||
out << "Did it work?\n";
|
||||
for(;;);
|
||||
}
|
||||
asm volatile("svc #0\n");
|
||||
out << "Did it work?\nSetting up A11 interrupts\n";
|
||||
output=(unsigned int*)0x1FF80000;
|
||||
out << "Copying " << &_a11vectors_end-&_a11vectors_begin << " words...\n";
|
||||
for(int i=0;i<(&_a11vectors_end-&_a11vectors_begin);i++) {
|
||||
output[i]=(&_a11vectors_begin)[i];
|
||||
}
|
||||
out << "Done!\n";
|
||||
*a11fpointer=&testSVC;
|
||||
while(*a11fpointer);
|
||||
out << "Did it work?\n";
|
||||
for(;;);
|
||||
}
|
||||
}
|
||||
extern "C" void init() {
|
||||
MTGosHAL::main();
|
||||
MTGosHAL::main();
|
||||
}
|
||||
struct cpu_info {
|
||||
unsigned int pc;
|
||||
unsigned int r12;
|
||||
unsigned int r11;
|
||||
unsigned int r10;
|
||||
unsigned int r9;
|
||||
unsigned int r8;
|
||||
unsigned int r7;
|
||||
unsigned int r6;
|
||||
unsigned int r5;
|
||||
unsigned int r4;
|
||||
unsigned int r3;
|
||||
unsigned int r2;
|
||||
unsigned int r1;
|
||||
unsigned int retAddr;
|
||||
unsigned int pc;
|
||||
unsigned int r12;
|
||||
unsigned int r11;
|
||||
unsigned int r10;
|
||||
unsigned int r9;
|
||||
unsigned int r8;
|
||||
unsigned int r7;
|
||||
unsigned int r6;
|
||||
unsigned int r5;
|
||||
unsigned int r4;
|
||||
unsigned int r3;
|
||||
unsigned int r2;
|
||||
unsigned int r1;
|
||||
unsigned int retAddr;
|
||||
};
|
||||
extern "C" void handleINT9(uint32_t stack, uint32_t id) {
|
||||
MTGosHAL::Screen out;
|
||||
out << MTGosHAL::Base::HEXADECIMAL << MTGosHAL::FG_color::RED << "Interrupt! " << (int)stack << "-" << (int)id << "\n";
|
||||
struct cpu_info *cpu=(struct cpu_info*)stack;
|
||||
out << "handler addr " << (int) cpu->pc << "\n";
|
||||
out << "R1 " << (int) cpu->r1 << ", R2 " << (int)cpu->r2 << "\n";
|
||||
out << "R3 " << (int) cpu->r3 << ", R4 " << (int)cpu->r4 << "\n";
|
||||
out << "R5 " << (int) cpu->r5 << ", R6 " << (int)cpu->r6 << "\n";
|
||||
out << "R7 " << (int) cpu->r7 << ", R8 " << (int)cpu->r8 << "\n";
|
||||
out << "R9 " << (int) cpu->r9 << ", SL " << (int)cpu->r10 << "\n";
|
||||
out << "FP " << (int) cpu->r11 << ", IP " << (int)cpu->r12 << "\n";
|
||||
out << "SP " << (int) stack << ", PC " << (int)cpu->retAddr << "\n";
|
||||
if((id!=1)&&(id!=2)&&(id!=4))
|
||||
for(;;);
|
||||
MTGosHAL::Screen out;
|
||||
out << MTGosHAL::Base::HEXADECIMAL << MTGosHAL::FG_color::RED << "Interrupt! " << (int)stack << "-" << (int)id << "\n";
|
||||
struct cpu_info *cpu=(struct cpu_info*)stack;
|
||||
out << "handler addr " << (int) cpu->pc << "\n";
|
||||
out << "R1 " << (int) cpu->r1 << ", R2 " << (int)cpu->r2 << "\n";
|
||||
out << "R3 " << (int) cpu->r3 << ", R4 " << (int)cpu->r4 << "\n";
|
||||
out << "R5 " << (int) cpu->r5 << ", R6 " << (int)cpu->r6 << "\n";
|
||||
out << "R7 " << (int) cpu->r7 << ", R8 " << (int)cpu->r8 << "\n";
|
||||
out << "R9 " << (int) cpu->r9 << ", SL " << (int)cpu->r10 << "\n";
|
||||
out << "FP " << (int) cpu->r11 << ", IP " << (int)cpu->r12 << "\n";
|
||||
out << "SP " << (int) stack << ", PC " << (int)cpu->retAddr << "\n";
|
||||
if((id!=1)&&(id!=2)&&(id!=4))
|
||||
for(;;);
|
||||
}
|
||||
|
|
|
@ -5,93 +5,93 @@
|
|||
//1: puts() lock
|
||||
extern uint32_t *flags;
|
||||
namespace MTGosHAL {
|
||||
auto Screen::puts(const char *s) -> void {
|
||||
auto Screen::puts(const char *s) -> void {
|
||||
|
||||
void(**a11fpointer)(void*)=(void(**)(void*))0x1FFFFFF8;
|
||||
void **a11farg = (void**)0x1FFFFFFC;
|
||||
int i=0;
|
||||
while(s[i]) {
|
||||
if(*flags&1)
|
||||
putChar(s[i++]);
|
||||
else {
|
||||
while(*a11fpointer);
|
||||
*a11farg=(void*)((unsigned int)s[i++]);
|
||||
*a11fpointer=(void(*)(void*))&putChar;
|
||||
}
|
||||
if(*flags&1)
|
||||
putChar(s[i++]);
|
||||
else {
|
||||
while(*a11fpointer);
|
||||
*a11farg=(void*)((unsigned int)s[i++]);
|
||||
*a11fpointer=(void(*)(void*))&putChar;
|
||||
}
|
||||
}
|
||||
}
|
||||
auto Screen::clrscr() -> void {
|
||||
void(**a11fpointer)(void*)=(void(**)(void*))0x1FFFFFF8;
|
||||
while(*a11fpointer);
|
||||
*a11fpointer=(void(*)(void*))(clrscr_impl);
|
||||
}
|
||||
auto Screen::scroll() -> void {
|
||||
void(**a11fpointer)(void*)=(void(**)(void*))0x1FFFFFF8;
|
||||
while(*a11fpointer);
|
||||
*a11fpointer=(void(*)(void*))(scroll_impl);
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<FG_color>(FG_color fg) -> Screen &{
|
||||
fg=fg;
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<BG_color>(BG_color bg) -> Screen &{
|
||||
bg=bg;
|
||||
return *this;
|
||||
}
|
||||
auto Screen::setColor(FG_color fg) -> Screen &{
|
||||
fg=fg;
|
||||
return *this;
|
||||
}
|
||||
auto Screen::setColor(BG_color bg) -> Screen &{
|
||||
bg=bg;
|
||||
return *this;
|
||||
}
|
||||
auto Screen::setColor(FG_color fg, BG_color bg) -> Screen &{
|
||||
return (*this).setColor(fg).setColor(bg);
|
||||
}
|
||||
}
|
||||
auto Screen::clrscr() -> void {
|
||||
void(**a11fpointer)(void*)=(void(**)(void*))0x1FFFFFF8;
|
||||
while(*a11fpointer);
|
||||
*a11fpointer=(void(*)(void*))(clrscr_impl);
|
||||
}
|
||||
auto Screen::scroll() -> void {
|
||||
void(**a11fpointer)(void*)=(void(**)(void*))0x1FFFFFF8;
|
||||
while(*a11fpointer);
|
||||
*a11fpointer=(void(*)(void*))(scroll_impl);
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<FG_color>(FG_color fg) -> Screen &{
|
||||
fg=fg;
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<BG_color>(BG_color bg) -> Screen &{
|
||||
bg=bg;
|
||||
return *this;
|
||||
}
|
||||
auto Screen::setColor(FG_color fg) -> Screen &{
|
||||
fg=fg;
|
||||
return *this;
|
||||
}
|
||||
auto Screen::setColor(BG_color bg) -> Screen &{
|
||||
bg=bg;
|
||||
return *this;
|
||||
}
|
||||
auto Screen::setColor(FG_color fg, BG_color bg) -> Screen &{
|
||||
return (*this).setColor(fg).setColor(bg);
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<Base>(Base output) -> Screen & {
|
||||
base=static_cast<int>(output);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<int>(int op) -> Screen & {
|
||||
uintptr_t output=op;
|
||||
const char* chars="0123456789ABCDEF";
|
||||
char buf[33];
|
||||
buf[32]='\0';
|
||||
char* ptr=buf+31;
|
||||
do {
|
||||
*(ptr--)=chars[output%base];
|
||||
output/=base;
|
||||
} while(output && (ptr!=buf));
|
||||
puts(ptr+1);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<long int>(long int op) -> Screen & {
|
||||
uint64_t output=op;
|
||||
const char* chars="0123456789ABCDEF";
|
||||
char buf[65];
|
||||
buf[64]='\0';
|
||||
char* ptr=buf+63;
|
||||
do {
|
||||
*(ptr--)=chars[output%base];
|
||||
output/=base;
|
||||
} while(output && (ptr!=buf));
|
||||
puts(ptr+1);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<char>(char output) -> Screen & {
|
||||
putChar(output);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<char*>(char* output) -> Screen & {
|
||||
puts(output);
|
||||
return *this;
|
||||
}
|
||||
auto Screen::operator<<<Base>(Base output) -> Screen & {
|
||||
base=static_cast<int>(output);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<int>(int op) -> Screen & {
|
||||
uintptr_t output=op;
|
||||
const char* chars="0123456789ABCDEF";
|
||||
char buf[33];
|
||||
buf[32]='\0';
|
||||
char* ptr=buf+31;
|
||||
do {
|
||||
*(ptr--)=chars[output%base];
|
||||
output/=base;
|
||||
} while(output && (ptr!=buf));
|
||||
puts(ptr+1);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<long int>(long int op) -> Screen & {
|
||||
uint64_t output=op;
|
||||
const char* chars="0123456789ABCDEF";
|
||||
char buf[65];
|
||||
buf[64]='\0';
|
||||
char* ptr=buf+63;
|
||||
do {
|
||||
*(ptr--)=chars[output%base];
|
||||
output/=base;
|
||||
} while(output && (ptr!=buf));
|
||||
puts(ptr+1);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<char>(char output) -> Screen & {
|
||||
putChar(output);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<char*>(char* output) -> Screen & {
|
||||
puts(output);
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,47 +18,47 @@
|
|||
#define DRV 6
|
||||
#define CMD 7
|
||||
namespace MTGosHAL {
|
||||
BlockDevice::BlockDevice(): numDevices(0), ata0(0x1F0,0), ata1(0x170,1), ata2(0x1E8,2), ata3(0x168,3) {
|
||||
BlockDevice::BlockDevice(): numDevices(0), ata0(0x1F0,0), ata1(0x170,1), ata2(0x1E8,2), ata3(0x168,3) {
|
||||
if(getDriveCnt()==0) {
|
||||
//err<<"Not a single device was found!\n";
|
||||
//err<<"Not a single device was found!\n";
|
||||
}
|
||||
}
|
||||
auto BlockDevice::getDriveCnt() -> int32_t {return ata0.getDriveCnt()+ata1.getDriveCnt()+ata2.getDriveCnt()+ata3.getDriveCnt();}
|
||||
auto BlockDevice::getDriveNumByName(const char * name) -> int32_t {
|
||||
}
|
||||
auto BlockDevice::getDriveCnt() -> int32_t {return ata0.getDriveCnt()+ata1.getDriveCnt()+ata2.getDriveCnt()+ata3.getDriveCnt();}
|
||||
auto BlockDevice::getDriveNumByName(const char * name) -> int32_t {
|
||||
int32_t tmp;
|
||||
if((tmp=ata0.getDriveNumByName(name))!=-1)
|
||||
return tmp;
|
||||
return tmp;
|
||||
else if((tmp=ata1.getDriveNumByName(name))!=-1)
|
||||
return tmp+ata0.getDriveCnt();
|
||||
return tmp+ata0.getDriveCnt();
|
||||
else if((tmp=ata2.getDriveNumByName(name))!=-1)
|
||||
return tmp+ata0.getDriveCnt()+ata1.getDriveCnt();
|
||||
return tmp+ata0.getDriveCnt()+ata1.getDriveCnt();
|
||||
else if((tmp=ata3.getDriveNumByName(name))!=-1)
|
||||
return tmp+ata0.getDriveCnt()+ata1.getDriveCnt()+ata2.getDriveCnt();
|
||||
return tmp+ata0.getDriveCnt()+ata1.getDriveCnt()+ata2.getDriveCnt();
|
||||
else return -1;
|
||||
}
|
||||
BlockDevice::~BlockDevice() {};
|
||||
auto BlockDevice::readSector(int32_t drv, uint64_t sectorNum, uint8_t *buf) -> void {
|
||||
}
|
||||
BlockDevice::~BlockDevice() {};
|
||||
auto BlockDevice::readSector(int32_t drv, uint64_t sectorNum, uint8_t *buf) -> void {
|
||||
ata0.readSector(drv, sectorNum, buf);
|
||||
ata1.readSector(drv, sectorNum, buf);
|
||||
ata2.readSector(drv, sectorNum, buf);
|
||||
ata3.readSector(drv, sectorNum, buf);
|
||||
}
|
||||
auto BlockDevice::readSector(int32_t drv, uint64_t sectorNum, uint32_t num, uint8_t *buf) -> void {
|
||||
}
|
||||
auto BlockDevice::readSector(int32_t drv, uint64_t sectorNum, uint32_t num, uint8_t *buf) -> void {
|
||||
ata0.readSector(drv, sectorNum, num, buf);
|
||||
ata1.readSector(drv, sectorNum, num, buf);
|
||||
ata2.readSector(drv, sectorNum, num, buf);
|
||||
ata3.readSector(drv, sectorNum, num, buf);
|
||||
}
|
||||
auto BlockDevice::writeSector(int32_t drv, uint64_t sectorNum, uint8_t *buf) -> void {
|
||||
}
|
||||
auto BlockDevice::writeSector(int32_t drv, uint64_t sectorNum, uint8_t *buf) -> void {
|
||||
ata0.writeSector(drv, sectorNum, buf);
|
||||
ata1.writeSector(drv, sectorNum, buf);
|
||||
ata2.writeSector(drv, sectorNum, buf);
|
||||
ata3.writeSector(drv, sectorNum, buf);
|
||||
}
|
||||
auto BlockDevice::writeSector(int32_t drv, uint64_t sectorNum, uint32_t num, uint8_t *buf) -> void {
|
||||
}
|
||||
auto BlockDevice::writeSector(int32_t drv, uint64_t sectorNum, uint32_t num, uint8_t *buf) -> void {
|
||||
ata0.writeSector(drv, sectorNum, num, buf);
|
||||
ata1.writeSector(drv, sectorNum, num, buf);
|
||||
ata2.writeSector(drv, sectorNum, num, buf);
|
||||
ata3.writeSector(drv, sectorNum, num, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,22 +19,22 @@
|
|||
#define CMD 7
|
||||
#define ALTCMD 0x206
|
||||
namespace MTGosHAL {
|
||||
IDE::IDE(uint16_t baseport, uint8_t num): baseport(baseport), num(num), existent(0), numDevices(0) {
|
||||
IDE::IDE(uint16_t baseport, uint8_t num): baseport(baseport), num(num), existent(0), numDevices(0) {
|
||||
if(inb(baseport+CMD)!=0xFF) { //Does the ATA controller return floating bus?
|
||||
// Checking existence of the master
|
||||
outb(baseport+DRV, 0xE0);
|
||||
outb(baseport+LBAlo,0x55);
|
||||
if(inb(baseport+LBAlo)==0x55) {
|
||||
existent|=1;
|
||||
numDevices++;
|
||||
}
|
||||
// Checking existence of the slave
|
||||
outb(baseport+DRV, 0xF0);
|
||||
outb(baseport+LBAlo,0x55);
|
||||
if(inb(baseport+LBAlo)==0x55) {
|
||||
existent|=2;
|
||||
numDevices++;
|
||||
}
|
||||
// Checking existence of the master
|
||||
outb(baseport+DRV, 0xE0);
|
||||
outb(baseport+LBAlo,0x55);
|
||||
if(inb(baseport+LBAlo)==0x55) {
|
||||
existent|=1;
|
||||
numDevices++;
|
||||
}
|
||||
// Checking existence of the slave
|
||||
outb(baseport+DRV, 0xF0);
|
||||
outb(baseport+LBAlo,0x55);
|
||||
if(inb(baseport+LBAlo)==0x55) {
|
||||
existent|=2;
|
||||
numDevices++;
|
||||
}
|
||||
} else {
|
||||
//err << "ATA device could not be found!\n";
|
||||
}
|
||||
|
@ -43,31 +43,31 @@ namespace MTGosHAL {
|
|||
inb(baseport+CMD);
|
||||
inb(baseport+CMD);
|
||||
outb(baseport+ALTCMD,0x00);
|
||||
}
|
||||
auto IDE::getDriveCnt() -> int32_t {return numDevices;}
|
||||
auto IDE::getDriveNumByName(const char* name) -> int32_t {
|
||||
}
|
||||
auto IDE::getDriveCnt() -> int32_t {return numDevices;}
|
||||
auto IDE::getDriveNumByName(const char* name) -> int32_t {
|
||||
if(strlen(name)!=5)
|
||||
return -1; //Format is ATA[0-3][sm] (regex)
|
||||
return -1; //Format is ATA[0-3][sm] (regex)
|
||||
if((name[0]!=name[2])||(name[2]!='A'))
|
||||
return -1;
|
||||
return -1;
|
||||
if(name[1]!='T')
|
||||
return -1;
|
||||
return -1;
|
||||
int32_t drivenum=name[3]-0x30;
|
||||
if(drivenum!=num)
|
||||
return -1;
|
||||
return -1;
|
||||
if((name[4]!='s')&&(name[4]!='m'))
|
||||
return -1;
|
||||
return -1;
|
||||
drivenum<<=1;
|
||||
drivenum+=(name[4]=='s')?1:0;
|
||||
if(!(existent&(1<<drivenum)))
|
||||
return -1;
|
||||
return -1;
|
||||
return drivenum;
|
||||
}
|
||||
auto IDE::readSector(int32_t drive, uint64_t sectorNum, uint8_t *buf) -> void {
|
||||
}
|
||||
auto IDE::readSector(int32_t drive, uint64_t sectorNum, uint8_t *buf) -> void {
|
||||
if(drive<(num*2)||drive>(num*2+1))
|
||||
return;
|
||||
return;
|
||||
if(!(existent&(1<<(drive-num*2))))
|
||||
return;
|
||||
return;
|
||||
while(inb(baseport+ALTCMD)&ATAPIO_BSY);
|
||||
outb(baseport+DRV, 0x40 | (drive&1)<<4);
|
||||
outb(baseport+SECTOR_CNT, 0);
|
||||
|
@ -85,12 +85,12 @@ namespace MTGosHAL {
|
|||
while(inb(baseport+CMD)&0x80);
|
||||
uint16_t *bufw=(uint16_t *)buf;
|
||||
asm volatile ("rep insw" : : "D"((int)bufw),"d"(baseport),"c"(256));
|
||||
}
|
||||
auto IDE::readSector(int32_t drive, uint64_t sectorNum, uint32_t num, uint8_t *buf) -> void {
|
||||
}
|
||||
auto IDE::readSector(int32_t drive, uint64_t sectorNum, uint32_t num, uint8_t *buf) -> void {
|
||||
if(drive<(this->num*2)||drive>(this->num*2+1))
|
||||
return;
|
||||
return;
|
||||
if(!(existent&(1<<(drive-this->num*2))))
|
||||
return;
|
||||
return;
|
||||
if(num==0)
|
||||
return;
|
||||
if(num>65536)
|
||||
|
@ -114,12 +114,12 @@ namespace MTGosHAL {
|
|||
while(inb(baseport+CMD)&0x80);
|
||||
uint16_t *bufw=(uint16_t *)buf;
|
||||
asm volatile ("rep insw" : : "D"((int)bufw),"d"(baseport),"c"(256*num));
|
||||
}
|
||||
auto IDE::writeSector(int32_t drive, uint64_t sectorNum, uint8_t *buf) -> void {
|
||||
}
|
||||
auto IDE::writeSector(int32_t drive, uint64_t sectorNum, uint8_t *buf) -> void {
|
||||
if(drive<(this->num*2)||drive>(this->num*2+1))
|
||||
return;
|
||||
return;
|
||||
if(!(existent&(1<<(drive-this->num*2))))
|
||||
return;
|
||||
return;
|
||||
while(inb(baseport+ALTCMD)&ATAPIO_BSY);
|
||||
outb(baseport+SECTOR_CNT, (uint8_t)(0));
|
||||
outb(baseport+LBAlo, (uint8_t)(sectorNum>>24));
|
||||
|
@ -138,11 +138,11 @@ namespace MTGosHAL {
|
|||
asm volatile("outsw; aad" : : "S"((int)buf),"d"(baseport),"a"(8787)); //The AAD is for creating a short delay between writes, as the compiler might unroll this loop.
|
||||
}
|
||||
}
|
||||
auto IDE::writeSector(int32_t drive, uint64_t sectorNum, uint32_t num, uint8_t *buf) -> void {
|
||||
auto IDE::writeSector(int32_t drive, uint64_t sectorNum, uint32_t num, uint8_t *buf) -> void {
|
||||
if(drive<(this->num*2)||drive>(this->num*2+1))
|
||||
return;
|
||||
return;
|
||||
if(!(existent&(1<<(drive-this->num*2))))
|
||||
return;
|
||||
return;
|
||||
if(num==0)
|
||||
return;
|
||||
if(num>65536)
|
||||
|
|
|
@ -11,18 +11,18 @@ auto schedule(struct cpu_state* cpu) -> struct cpu_state* {
|
|||
}
|
||||
Multitasking::Multitasking(): curr_task(nullptr), first_task(nullptr)
|
||||
{
|
||||
for(int i=0;i<32;i++) {
|
||||
if(i==2)
|
||||
continue;
|
||||
tss[i]=0;
|
||||
}
|
||||
tss[2]=0x10;
|
||||
for(int i=0;i<32;i++) {
|
||||
if(i==2)
|
||||
continue;
|
||||
tss[i]=0;
|
||||
}
|
||||
tss[2]=0x10;
|
||||
//task_states[0] = initTask(stack_a, user_stack_a, task_a);
|
||||
//task_states[1] = initTask(stack_b, user_stack_b, task_b);
|
||||
if(!idt.request(0x20,MTGosHAL::schedule)) {
|
||||
err << "Could not start multitasking\nFatal error; Kernel halted!\n";
|
||||
while(true)
|
||||
asm volatile("cli; hlt");
|
||||
asm volatile("cli; hlt");
|
||||
}
|
||||
}
|
||||
auto Multitasking::initTask(void(* entry)()) -> struct cpu_state*
|
||||
|
@ -59,24 +59,24 @@ auto Multitasking::initTask(void(* entry)()) -> struct cpu_state*
|
|||
//Create new task class
|
||||
Task* task = new Task(state);
|
||||
if(first_task)
|
||||
first_task->addTask(task);
|
||||
first_task->addTask(task);
|
||||
else {
|
||||
first_task=task;
|
||||
first_task=task;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
auto Multitasking::schedule(struct cpu_state* cpu) -> struct cpu_state*
|
||||
{
|
||||
Task* next=nullptr;
|
||||
if(curr_task) {
|
||||
next=curr_task->pause(cpu);
|
||||
}
|
||||
if (!next) {
|
||||
next=first_task;
|
||||
}
|
||||
curr_task=next;
|
||||
struct cpu_state* cpu_state=next->unpause();
|
||||
MTGosHAL::tasks.tss[1] = (uint32_t) (cpu_state + 1);
|
||||
return cpu_state;
|
||||
Task* next=nullptr;
|
||||
if(curr_task) {
|
||||
next=curr_task->pause(cpu);
|
||||
}
|
||||
if (!next) {
|
||||
next=first_task;
|
||||
}
|
||||
curr_task=next;
|
||||
struct cpu_state* cpu_state=next->unpause();
|
||||
MTGosHAL::tasks.tss[1] = (uint32_t) (cpu_state + 1);
|
||||
return cpu_state;
|
||||
}
|
||||
} // namespace MTGosHAL
|
||||
|
|
|
@ -2,20 +2,20 @@
|
|||
#include <gdt.hpp>
|
||||
#include <serial.hpp>
|
||||
namespace MTGosHAL {
|
||||
GDT::GDT() {
|
||||
gdt[0]=gdt[1]=gdt[2]=gdt[3]=gdt[4]=gdt[5]=gdt[6]=0x0ull;
|
||||
}
|
||||
auto GDT::setEntry(int i, unsigned int base, unsigned int limit, int flags) -> void {
|
||||
gdt[i] = limit & 0xffffLL;
|
||||
gdt[i] |= (base & 0xffffffLL) << 16;
|
||||
gdt[i] |= (flags & 0xffLL) << 40;
|
||||
gdt[i] |= ((limit >> 16) & 0xfLL) << 48;
|
||||
gdt[i] |= ((flags >> 8 )& 0xffLL) << 52;
|
||||
gdt[i] |= ((base >> 24) & 0xffLL) << 56;
|
||||
}
|
||||
auto GDT::apply() -> void {
|
||||
debug << "We are now trying to set our GDT. If the CPU triplefaults, something went wrong in MTGosHAL::GDT::apply() or loadGDT().\n";
|
||||
fin={(uint16_t)7*8-1, (void*)gdt};
|
||||
loadGDT((void*)(&fin));
|
||||
};
|
||||
GDT::GDT() {
|
||||
gdt[0]=gdt[1]=gdt[2]=gdt[3]=gdt[4]=gdt[5]=gdt[6]=0x0ull;
|
||||
}
|
||||
auto GDT::setEntry(int i, unsigned int base, unsigned int limit, int flags) -> void {
|
||||
gdt[i] = limit & 0xffffLL;
|
||||
gdt[i] |= (base & 0xffffffLL) << 16;
|
||||
gdt[i] |= (flags & 0xffLL) << 40;
|
||||
gdt[i] |= ((limit >> 16) & 0xfLL) << 48;
|
||||
gdt[i] |= ((flags >> 8 )& 0xffLL) << 52;
|
||||
gdt[i] |= ((base >> 24) & 0xffLL) << 56;
|
||||
}
|
||||
auto GDT::apply() -> void {
|
||||
debug << "We are now trying to set our GDT. If the CPU triplefaults, something went wrong in MTGosHAL::GDT::apply() or loadGDT().\n";
|
||||
fin={(uint16_t)7*8-1, (void*)gdt};
|
||||
loadGDT((void*)(&fin));
|
||||
};
|
||||
}
|
||||
|
|
|
@ -7,85 +7,85 @@
|
|||
auto syscall(uint32_t syscall_num, void* handle, void* args) -> void*;
|
||||
extern void** progs;
|
||||
namespace MTGosHAL {
|
||||
IDT::IDT() {
|
||||
//Init PIC
|
||||
outb(0x20, 0x11); //Init Master-PIC
|
||||
outb(0x21, 0x20); //Interrupt number for IRQ0
|
||||
outb(0x21, 0x04); //IRQ is the Slave
|
||||
outb(0x21, 0x01); //ICW 4
|
||||
outb(0xA0, 0x11); //Init Master-PIC
|
||||
outb(0xA1, 0x28); //Interrupt number for IRQ8
|
||||
outb(0xA1, 0x02); //IRQ is the Slave
|
||||
outb(0xA1, 0x01); //ICW 4
|
||||
//Activate IRQ's
|
||||
outb(0x21, 0x00);
|
||||
outb(0xA1, 0x00);
|
||||
}
|
||||
auto IDT::setEntry(int i, void* offset, uint16_t seg, uint8_t flags) -> void {
|
||||
idt[i]=(uint16_t)((uint32_t)offset);
|
||||
idt[i]|=(uint64_t)(((uint32_t)offset)>>16)<<48;
|
||||
idt[i]|=((uint64_t)seg)<<16;
|
||||
idt[i]|=((uint64_t)flags)<<40;
|
||||
}
|
||||
auto IDT::apply() -> void {
|
||||
debug << "Now trying to load the IDT.\n";
|
||||
idtptr.limit=(uint16_t)(256*8-1);
|
||||
idtptr.pointer=(uint64_t*)&idt;
|
||||
loadIDT((void*)&idtptr);
|
||||
}
|
||||
auto IDT::handle(struct cpu_state* cpu) -> struct cpu_state* {
|
||||
IDT::IDT() {
|
||||
//Init PIC
|
||||
outb(0x20, 0x11); //Init Master-PIC
|
||||
outb(0x21, 0x20); //Interrupt number for IRQ0
|
||||
outb(0x21, 0x04); //IRQ is the Slave
|
||||
outb(0x21, 0x01); //ICW 4
|
||||
outb(0xA0, 0x11); //Init Master-PIC
|
||||
outb(0xA1, 0x28); //Interrupt number for IRQ8
|
||||
outb(0xA1, 0x02); //IRQ is the Slave
|
||||
outb(0xA1, 0x01); //ICW 4
|
||||
//Activate IRQ's
|
||||
outb(0x21, 0x00);
|
||||
outb(0xA1, 0x00);
|
||||
}
|
||||
auto IDT::setEntry(int i, void* offset, uint16_t seg, uint8_t flags) -> void {
|
||||
idt[i]=(uint16_t)((uint32_t)offset);
|
||||
idt[i]|=(uint64_t)(((uint32_t)offset)>>16)<<48;
|
||||
idt[i]|=((uint64_t)seg)<<16;
|
||||
idt[i]|=((uint64_t)flags)<<40;
|
||||
}
|
||||
auto IDT::apply() -> void {
|
||||
debug << "Now trying to load the IDT.\n";
|
||||
idtptr.limit=(uint16_t)(256*8-1);
|
||||
idtptr.pointer=(uint64_t*)&idt;
|
||||
loadIDT((void*)&idtptr);
|
||||
}
|
||||
auto IDT::handle(struct cpu_state* cpu) -> struct cpu_state* {
|
||||
struct cpu_state* new_cpu=cpu;
|
||||
debug << "Interrupt 0x" << Base::HEXADECIMAL << (int) cpu->intr << " was raised.\n";
|
||||
if(cpu->intr<=0x1F) {
|
||||
err << "Exception 0x" << Base::HEXADECIMAL << (int) cpu->intr << "! Kernel halted!\n";
|
||||
err << "EAX = 0x" << (int)cpu->eax << " - EBX = 0x" << (int)cpu->ebx << "\n";
|
||||
err << "ECX = 0x" << (int)cpu->ecx << " - EDX = 0x" << (int)cpu->edx << "\n";
|
||||
err << "ESI = 0x" << (int)cpu->esi << " - EDI = 0x" << (int)cpu->edi << "\n";
|
||||
err << "SS:ESP = 0x" << (int)cpu->ss << ":0x" << (int)cpu->esp << " - SS:EBP = 0x" << (int)cpu->ss << ":0x" << (int)cpu->ebp << "\n";
|
||||
err << "CS:EIP = 0x" << (int)cpu->cs << ":0x" << (int)cpu->eip << " - INTR:ERR = 0x" << (int)cpu->intr << ":0x" << (int)cpu->error << "\n";
|
||||
err << "------ END OF REGISTER DUMP ------ ------ START OF PROGRAM LOADPOINTS ------\n";
|
||||
for(int i=0;i<1024;i++) {
|
||||
if(!progs[i])
|
||||
break;
|
||||
err << "0x" << (int)((uint32_t)progs[i]) << "; ";
|
||||
}
|
||||
err << "\n";
|
||||
uint16_t counter = 1193180 / 220; //Make an annoying beep
|
||||
outb(0x43, 0xB6);
|
||||
outb(0x42, (uint8_t)counter);
|
||||
outb(0x42, (uint8_t)(counter>>8));
|
||||
outb(0x61, inb(0x61) | 3);
|
||||
while(1) {
|
||||
asm volatile("cli; hlt");
|
||||
}
|
||||
} else if(cpu->intr >= 0x20 && cpu->intr <= 0x2F) {
|
||||
if(cpu->intr >= 0x28) {
|
||||
outb(0xA0, 0x20);
|
||||
}
|
||||
outb(0x20, 0x20);
|
||||
debug << "The IRQ " << Base::DECIMAL << (int) cpu->intr-0x20 << " was handled.\n";
|
||||
if(cpu->intr==0x20) {
|
||||
debug.debug();
|
||||
}
|
||||
}
|
||||
for(int i=0;i<16;i++) {
|
||||
if(ivt[cpu->intr][i])
|
||||
new_cpu=ivt[cpu->intr][i](new_cpu);
|
||||
}
|
||||
if(cpu->intr>=48)
|
||||
new_cpu->eax=(uint32_t)(::syscall(cpu->eax, (void*)(cpu->ebx), (void*)(cpu->esp)));
|
||||
return new_cpu;
|
||||
}
|
||||
auto IDT::request(uint8_t intr, struct cpu_state* (*handler)(struct cpu_state*)) -> bool {
|
||||
for(int i=0;i<16;i++) {
|
||||
if(ivt[intr][i])
|
||||
continue;
|
||||
ivt[intr][i]=handler;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
debug << "Interrupt 0x" << Base::HEXADECIMAL << (int) cpu->intr << " was raised.\n";
|
||||
if(cpu->intr<=0x1F) {
|
||||
err << "Exception 0x" << Base::HEXADECIMAL << (int) cpu->intr << "! Kernel halted!\n";
|
||||
err << "EAX = 0x" << (int)cpu->eax << " - EBX = 0x" << (int)cpu->ebx << "\n";
|
||||
err << "ECX = 0x" << (int)cpu->ecx << " - EDX = 0x" << (int)cpu->edx << "\n";
|
||||
err << "ESI = 0x" << (int)cpu->esi << " - EDI = 0x" << (int)cpu->edi << "\n";
|
||||
err << "SS:ESP = 0x" << (int)cpu->ss << ":0x" << (int)cpu->esp << " - SS:EBP = 0x" << (int)cpu->ss << ":0x" << (int)cpu->ebp << "\n";
|
||||
err << "CS:EIP = 0x" << (int)cpu->cs << ":0x" << (int)cpu->eip << " - INTR:ERR = 0x" << (int)cpu->intr << ":0x" << (int)cpu->error << "\n";
|
||||
err << "------ END OF REGISTER DUMP ------ ------ START OF PROGRAM LOADPOINTS ------\n";
|
||||
for(int i=0;i<1024;i++) {
|
||||
if(!progs[i])
|
||||
break;
|
||||
err << "0x" << (int)((uint32_t)progs[i]) << "; ";
|
||||
}
|
||||
err << "\n";
|
||||
uint16_t counter = 1193180 / 220; //Make an annoying beep
|
||||
outb(0x43, 0xB6);
|
||||
outb(0x42, (uint8_t)counter);
|
||||
outb(0x42, (uint8_t)(counter>>8));
|
||||
outb(0x61, inb(0x61) | 3);
|
||||
while(1) {
|
||||
asm volatile("cli; hlt");
|
||||
}
|
||||
} else if(cpu->intr >= 0x20 && cpu->intr <= 0x2F) {
|
||||
if(cpu->intr >= 0x28) {
|
||||
outb(0xA0, 0x20);
|
||||
}
|
||||
outb(0x20, 0x20);
|
||||
debug << "The IRQ " << Base::DECIMAL << (int) cpu->intr-0x20 << " was handled.\n";
|
||||
if(cpu->intr==0x20) {
|
||||
debug.debug();
|
||||
}
|
||||
}
|
||||
for(int i=0;i<16;i++) {
|
||||
if(ivt[cpu->intr][i])
|
||||
new_cpu=ivt[cpu->intr][i](new_cpu);
|
||||
}
|
||||
if(cpu->intr>=48)
|
||||
new_cpu->eax=(uint32_t)(::syscall(cpu->eax, (void*)(cpu->ebx), (void*)(cpu->esp)));
|
||||
return new_cpu;
|
||||
}
|
||||
auto IDT::request(uint8_t intr, struct cpu_state* (*handler)(struct cpu_state*)) -> bool {
|
||||
for(int i=0;i<16;i++) {
|
||||
if(ivt[intr][i])
|
||||
continue;
|
||||
ivt[intr][i]=handler;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
extern "C" void* handleINT(void* cpu) {
|
||||
return (void*)MTGosHAL::idt.handle((MTGosHAL::cpu_state*)cpu);
|
||||
return (void*)MTGosHAL::idt.handle((MTGosHAL::cpu_state*)cpu);
|
||||
}
|
||||
|
|
|
@ -25,12 +25,12 @@ namespace MTGosHAL {
|
|||
BlockDevice disk;
|
||||
void main(int eax, struct multiboot_info* ebx) {
|
||||
//Init debug output
|
||||
new (&debug) Serial();
|
||||
debug << "Hello debugger! This is MTGos v00r01\nThese logs are probably very long, so please redirect the output to a file.\n";
|
||||
new (&debug) Serial();
|
||||
debug << "Hello debugger! This is MTGos v00r01\nThese logs are probably very long, so please redirect the output to a file.\n";
|
||||
|
||||
debug << "Init GDT\n";
|
||||
new (&gdt) GDT();
|
||||
gdt.setEntry(0, 0, 0, 0);
|
||||
debug << "Init GDT\n";
|
||||
new (&gdt) GDT();
|
||||
gdt.setEntry(0, 0, 0, 0);
|
||||
gdt.setEntry(1, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_CODESEG | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT);
|
||||
gdt.setEntry(2, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_DATASEG | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT);
|
||||
gdt.setEntry(3, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_CODESEG | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT | GDT_FLAG_RING3);
|
||||
|
@ -39,51 +39,51 @@ namespace MTGosHAL {
|
|||
gdt.setEntry(6, 0, 0xfffff, GDT_FLAG_RING3 | GDT_FLAG_TSS | GDT_FLAG_PRESENT);
|
||||
gdt.apply();
|
||||
|
||||
debug << "Init IDT\n";
|
||||
new (&idt) IDT();
|
||||
for(int i=0;i<256;i++) {
|
||||
debug << "Init IDT\n";
|
||||
new (&idt) IDT();
|
||||
for(int i=0;i<256;i++) {
|
||||
idt.setEntry(i, (void *)((uint32_t)&intr_stub_0+i*16), SEG_KERNEL, IDT_INTERRUPT_GATE | IDT_SEG_32_BIT | IDT_RING_0 | IDT_USED);
|
||||
}
|
||||
idt.setEntry(48, (void *)((uint32_t)&intr_stub_0+768), SEG_KERNEL, IDT_TRAP_GATE | IDT_SEG_32_BIT | IDT_RING_3 | IDT_USED);
|
||||
idt.setEntry(8, (void *)((uint32_t)&intr_stub_0+128), SEG_DBL_FAULT, IDT_TASK_GATE | IDT_SEG_32_BIT | IDT_RING_0 | IDT_USED);
|
||||
idt.apply();
|
||||
asm volatile("ltr %%ax" : : "a"(5<<3));
|
||||
debug << "Init MM\n";
|
||||
new (&mm) PMM(ebx);
|
||||
asm volatile("ltr %%ax" : : "a"(5<<3));
|
||||
debug << "Init MM\n";
|
||||
new (&mm) PMM(ebx);
|
||||
|
||||
debug << "Init Screen output\n";
|
||||
new (&out) Screen(ebx);
|
||||
new (&err) Screen(ebx);
|
||||
debug << "Init Screen output\n";
|
||||
new (&out) Screen(ebx);
|
||||
new (&err) Screen(ebx);
|
||||
out << BG_color::BLACK << FG_color::WHITE << "Loading MTGos...\n";
|
||||
err << BG_color::BLACK << FG_color::RED;
|
||||
|
||||
debug << "Init Keyboard\n";
|
||||
new (&in) Keyboard();
|
||||
debug << "Init Keyboard\n";
|
||||
new (&in) Keyboard();
|
||||
|
||||
debug << "Init Multitasking\n";
|
||||
new (&tasks) Multitasking();
|
||||
|
||||
debug << "Init Disk\n";
|
||||
new (&disk) BlockDevice();
|
||||
debug << "Init Disk\n";
|
||||
new (&disk) BlockDevice();
|
||||
|
||||
debug << "Kernel initialized\n";
|
||||
debug << "Kernel initialized\n";
|
||||
if(eax!=0x2BADB002)
|
||||
err << "System wasn't loaded by a Multiboot-conformant launcher!\n";
|
||||
multiboot_mod_list *mods = (multiboot_mod_list*) ebx->mods_addr;
|
||||
multiboot_mod_list *mods = (multiboot_mod_list*) ebx->mods_addr;
|
||||
progs=(void**)mm.alloc(4096);
|
||||
for(int i=0;i<1024;i++) {
|
||||
progs[i]=nullptr;
|
||||
}
|
||||
for(int i=0;i<1024;i++) {
|
||||
progs[i]=nullptr;
|
||||
}
|
||||
for(uint32_t i=0;i<(ebx->mods_count<1023?ebx->mods_count:1023);i++) { //Basically until MIN(ebx->mods_count, 1023), as we only support loading up to 1023 programs directly.
|
||||
progs[i]=(void*)(mods[i].mod_start);
|
||||
debug << "Found module!\n";
|
||||
}
|
||||
::main(progs, debug, mm, out, err, in, tasks, disk);
|
||||
uint8_t buf[512];
|
||||
disk.readSector(disk.getDriveNumByName("ATA0m"),0,buf);
|
||||
out << (char*)buf;
|
||||
out << "こんにちは、ユニコード。\nЗдравствуй, Юникод.\nΓεια σου, Γιούνικοντ.\n안녕하세요, 유니코드.\n"_s;
|
||||
//sti();
|
||||
uint8_t buf[512];
|
||||
disk.readSector(disk.getDriveNumByName("ATA0m"),0,buf);
|
||||
out << (char*)buf;
|
||||
out << "こんにちは、ユニコード。\nЗдравствуй, Юникод.\nΓεια σου, Γιούνικοντ.\n안녕하세요, 유니코드.\n"_s;
|
||||
sti();
|
||||
for(;;);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,124 +5,124 @@
|
|||
#include <keymap_DE.hpp>
|
||||
|
||||
namespace MTGosHAL {
|
||||
auto handleIRQ(struct cpu_state* cpu) -> struct cpu_state* {
|
||||
return in.handleIRQ1(cpu);
|
||||
}
|
||||
auto Keyboard::getChar() -> char {
|
||||
char chr=buf[0];
|
||||
for(int i=0;i<15;i++) {
|
||||
buf[i]=buf[i+1];
|
||||
}
|
||||
buf[15]='\0';
|
||||
if(len)
|
||||
len--;
|
||||
return chr;
|
||||
}
|
||||
auto Keyboard::sendCommand(uint8_t command) -> void {
|
||||
while((inb(0x64) & 0x2));
|
||||
outb(0x60, command);
|
||||
}
|
||||
auto Keyboard::handleIRQ1(struct cpu_state* cpu) -> struct cpu_state* {
|
||||
uint8_t keycode=0,scancode=inb(0x60);
|
||||
if(scancode==0xFA) {
|
||||
response=false;
|
||||
return cpu;
|
||||
} else if(response && scancode == 0xFE) {
|
||||
sendCommand(0xED);
|
||||
outb(0x60, (scrolllock) + (numlock<<1) + (capslock<<2));
|
||||
return cpu;
|
||||
}
|
||||
debug << "Keyboard interrupt received.\nGot: 0x" << Base::HEXADECIMAL << (int)scancode;
|
||||
bool break_code=false;
|
||||
static bool e0_code=false;
|
||||
static int e1_code=0;
|
||||
static uint16_t e1_prev=0;
|
||||
uint8_t tableID=0;
|
||||
if((scancode & 0x80 ) && (e1_code || (scancode != 0xE1)) && (e0_code || (scancode != 0xE0))) {
|
||||
break_code = true;
|
||||
scancode &= ~0x80;
|
||||
}
|
||||
if(e0_code) {
|
||||
if((scancode==0x2A) || (scancode = 0x36)) {
|
||||
e0_code = false;
|
||||
return cpu;
|
||||
}
|
||||
keycode=keyboardKeycodes[1][scancode];
|
||||
e0_code=false;
|
||||
} else if (e1_code == 2) {
|
||||
e1_prev |= ((uint16_t) scancode << 8);
|
||||
//TODO. translate it, although I might not even use this code
|
||||
return cpu;
|
||||
} else if (e1_code) {
|
||||
e1_prev = scancode;
|
||||
e1_code++;
|
||||
return cpu;
|
||||
} else if (scancode == 0xE0) {
|
||||
e0_code = true;
|
||||
return cpu;
|
||||
} else if (scancode == 0xE1) {
|
||||
e1_code = true;
|
||||
return cpu;
|
||||
} else {
|
||||
keycode=keyboardKeycodes[0][scancode];
|
||||
}
|
||||
//Now put it into the keystate array
|
||||
if(break_code)
|
||||
keydowns[keycode]=false;
|
||||
else
|
||||
keydowns[keycode]=true;
|
||||
//0x2A 0x36 = Shift
|
||||
if(keydowns[0x2A] || keydowns[0x36])
|
||||
tableID^=1;
|
||||
//0x1D = Ctrl
|
||||
if(keydowns[0x1D])
|
||||
tableID^=2;
|
||||
//0x38 = Alt
|
||||
if(keydowns[0x38])
|
||||
tableID^=4;
|
||||
auto handleIRQ(struct cpu_state* cpu) -> struct cpu_state* {
|
||||
return in.handleIRQ1(cpu);
|
||||
}
|
||||
auto Keyboard::getChar() -> char {
|
||||
char chr=buf[0];
|
||||
for(int i=0;i<15;i++) {
|
||||
buf[i]=buf[i+1];
|
||||
}
|
||||
buf[15]='\0';
|
||||
if(len)
|
||||
len--;
|
||||
return chr;
|
||||
}
|
||||
auto Keyboard::sendCommand(uint8_t command) -> void {
|
||||
while((inb(0x64) & 0x2));
|
||||
outb(0x60, command);
|
||||
}
|
||||
auto Keyboard::handleIRQ1(struct cpu_state* cpu) -> struct cpu_state* {
|
||||
uint8_t keycode=0,scancode=inb(0x60);
|
||||
if(scancode==0xFA) {
|
||||
response=false;
|
||||
return cpu;
|
||||
} else if(response && scancode == 0xFE) {
|
||||
sendCommand(0xED);
|
||||
outb(0x60, (scrolllock) + (numlock<<1) + (capslock<<2));
|
||||
return cpu;
|
||||
}
|
||||
debug << "Keyboard interrupt received.\nGot: 0x" << Base::HEXADECIMAL << (int)scancode;
|
||||
bool break_code=false;
|
||||
static bool e0_code=false;
|
||||
static int e1_code=0;
|
||||
static uint16_t e1_prev=0;
|
||||
uint8_t tableID=0;
|
||||
if((scancode & 0x80 ) && (e1_code || (scancode != 0xE1)) && (e0_code || (scancode != 0xE0))) {
|
||||
break_code = true;
|
||||
scancode &= ~0x80;
|
||||
}
|
||||
if(e0_code) {
|
||||
if((scancode==0x2A) || (scancode = 0x36)) {
|
||||
e0_code = false;
|
||||
return cpu;
|
||||
}
|
||||
keycode=keyboardKeycodes[1][scancode];
|
||||
e0_code=false;
|
||||
} else if (e1_code == 2) {
|
||||
e1_prev |= ((uint16_t) scancode << 8);
|
||||
//TODO. translate it, although I might not even use this code
|
||||
return cpu;
|
||||
} else if (e1_code) {
|
||||
e1_prev = scancode;
|
||||
e1_code++;
|
||||
return cpu;
|
||||
} else if (scancode == 0xE0) {
|
||||
e0_code = true;
|
||||
return cpu;
|
||||
} else if (scancode == 0xE1) {
|
||||
e1_code = true;
|
||||
return cpu;
|
||||
} else {
|
||||
keycode=keyboardKeycodes[0][scancode];
|
||||
}
|
||||
//Now put it into the keystate array
|
||||
if(break_code)
|
||||
keydowns[keycode]=false;
|
||||
else
|
||||
keydowns[keycode]=true;
|
||||
//0x2A 0x36 = Shift
|
||||
if(keydowns[0x2A] || keydowns[0x36])
|
||||
tableID^=1;
|
||||
//0x1D = Ctrl
|
||||
if(keydowns[0x1D])
|
||||
tableID^=2;
|
||||
//0x38 = Alt
|
||||
if(keydowns[0x38])
|
||||
tableID^=4;
|
||||
|
||||
//0x45 = Numlock
|
||||
if(keycode==0x45)
|
||||
numlock=!numlock;
|
||||
//0x3A = CAPS
|
||||
if(keycode==0x3A)
|
||||
capslock=!capslock;
|
||||
//0x46 = Scrolllock
|
||||
if(keycode==0x46)
|
||||
scrolllock=!scrolllock;
|
||||
//0x45 = Numlock
|
||||
if(keycode==0x45)
|
||||
numlock=!numlock;
|
||||
//0x3A = CAPS
|
||||
if(keycode==0x3A)
|
||||
capslock=!capslock;
|
||||
//0x46 = Scrolllock
|
||||
if(keycode==0x46)
|
||||
scrolllock=!scrolllock;
|
||||
|
||||
if(capslock)
|
||||
tableID^=1;
|
||||
//Correct the LEDs
|
||||
sendCommand(0xED);
|
||||
outb(0x60, (scrolllock) + (numlock<<1) + (capslock<<2));
|
||||
response=true;
|
||||
//Convert it into a char
|
||||
if(!break_code)
|
||||
out << keymap[tableID][keycode];
|
||||
debug << " -> 0x" << (int)keycode << ".\n";
|
||||
return cpu;
|
||||
}
|
||||
Keyboard::Keyboard(): numlock(true), capslock(false), scrolllock(false), response(false) {
|
||||
if(!idt.request(0x21, (struct cpu_state*(*)(struct cpu_state*))&handleIRQ)) {
|
||||
debug << "Could not get an handler for IRQ1 (Keyboard)\n";
|
||||
return;
|
||||
}
|
||||
//Clear keyboard buffer
|
||||
while(inb(0x64) & 0x1) {
|
||||
inb(0x60);
|
||||
}
|
||||
sendCommand(0xF4); //Activate keyboard
|
||||
//Check for self-test being passed
|
||||
sendCommand(0x20);
|
||||
uint8_t ccb=inb(0x60);
|
||||
if((ccb&4)) {
|
||||
ccb &= ~1;
|
||||
} else {
|
||||
debug << "Keyboard didn't pass self-test!\nDeactivating IRQ1.\n";
|
||||
ccb |= 1;
|
||||
}
|
||||
sendCommand(0x60);
|
||||
outb(0x64, ccb);
|
||||
}
|
||||
if(capslock)
|
||||
tableID^=1;
|
||||
//Correct the LEDs
|
||||
sendCommand(0xED);
|
||||
outb(0x60, (scrolllock) + (numlock<<1) + (capslock<<2));
|
||||
response=true;
|
||||
//Convert it into a char
|
||||
if(!break_code)
|
||||
out << keymap[tableID][keycode];
|
||||
debug << " -> 0x" << (int)keycode << ".\n";
|
||||
return cpu;
|
||||
}
|
||||
Keyboard::Keyboard(): numlock(true), capslock(false), scrolllock(false), response(false) {
|
||||
if(!idt.request(0x21, (struct cpu_state*(*)(struct cpu_state*))&handleIRQ)) {
|
||||
debug << "Could not get an handler for IRQ1 (Keyboard)\n";
|
||||
return;
|
||||
}
|
||||
//Clear keyboard buffer
|
||||
while(inb(0x64) & 0x1) {
|
||||
inb(0x60);
|
||||
}
|
||||
sendCommand(0xF4); //Activate keyboard
|
||||
//Check for self-test being passed
|
||||
sendCommand(0x20);
|
||||
uint8_t ccb=inb(0x60);
|
||||
if((ccb&4)) {
|
||||
ccb &= ~1;
|
||||
} else {
|
||||
debug << "Keyboard didn't pass self-test!\nDeactivating IRQ1.\n";
|
||||
ccb |= 1;
|
||||
}
|
||||
sendCommand(0x60);
|
||||
outb(0x64, ccb);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,52 +3,52 @@
|
|||
#include <serial.hpp>
|
||||
#include <textDISP.hpp>
|
||||
namespace MTGosHAL {
|
||||
auto Output::puts(const char* s) -> void {
|
||||
int i=0;
|
||||
while(s[i]!='\0')
|
||||
putChar(s[i++]);
|
||||
}
|
||||
template <>
|
||||
auto Output::operator<<<Base>(Base output) -> Output & {
|
||||
base=static_cast<int>(output);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Output::operator<<<int>(int op) -> Output & {
|
||||
uintptr_t output=op;
|
||||
const char* chars="0123456789ABCDEF";
|
||||
char buf[33];
|
||||
buf[32]='\0';
|
||||
char* ptr=buf+31;
|
||||
do {
|
||||
*(ptr--)=chars[output%base];
|
||||
output/=base;
|
||||
} while(output && (ptr!=buf));
|
||||
puts(ptr+1);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Output::operator<<<long int>(long int op) -> Output & {
|
||||
uint64_t output=op;
|
||||
const char* chars="0123456789ABCDEF";
|
||||
char buf[65];
|
||||
buf[64]='\0';
|
||||
char* ptr=buf+63;
|
||||
do {
|
||||
*(ptr--)=chars[output%base];
|
||||
output/=base;
|
||||
} while(output && (ptr!=buf));
|
||||
puts(ptr+1);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Output::operator<<<char>(char output) -> Output & {
|
||||
putChar(output);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Output::operator<<<char*>(char* output) -> Output & {
|
||||
puts(output);
|
||||
return *this;
|
||||
}
|
||||
auto Output::puts(const char* s) -> void {
|
||||
int i=0;
|
||||
while(s[i]!='\0')
|
||||
putChar(s[i++]);
|
||||
}
|
||||
template <>
|
||||
auto Output::operator<<<Base>(Base output) -> Output & {
|
||||
base=static_cast<int>(output);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Output::operator<<<int>(int op) -> Output & {
|
||||
uintptr_t output=op;
|
||||
const char* chars="0123456789ABCDEF";
|
||||
char buf[33];
|
||||
buf[32]='\0';
|
||||
char* ptr=buf+31;
|
||||
do {
|
||||
*(ptr--)=chars[output%base];
|
||||
output/=base;
|
||||
} while(output && (ptr!=buf));
|
||||
puts(ptr+1);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Output::operator<<<long int>(long int op) -> Output & {
|
||||
uint64_t output=op;
|
||||
const char* chars="0123456789ABCDEF";
|
||||
char buf[65];
|
||||
buf[64]='\0';
|
||||
char* ptr=buf+63;
|
||||
do {
|
||||
*(ptr--)=chars[output%base];
|
||||
output/=base;
|
||||
} while(output && (ptr!=buf));
|
||||
puts(ptr+1);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Output::operator<<<char>(char output) -> Output & {
|
||||
putChar(output);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Output::operator<<<char*>(char* output) -> Output & {
|
||||
puts(output);
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,78 +1,78 @@
|
|||
#include <base.hpp>
|
||||
#include <serial.hpp>
|
||||
namespace MTGosHAL {
|
||||
auto Serial::isTransmitEmpty() -> int {
|
||||
return inb(port+SERIAL_LSR)&0x20;
|
||||
}
|
||||
auto Serial::putChar(char chr) -> void {
|
||||
// if(!works)
|
||||
return;
|
||||
int tries=65535;
|
||||
while(!isTransmitEmpty()) {
|
||||
waittimes++;
|
||||
tries--;
|
||||
if(!tries){
|
||||
works=false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
outb(port, chr);
|
||||
transmits++;
|
||||
}
|
||||
auto Serial::serial_received() -> int {
|
||||
return inb(port+SERIAL_LSR)&1;
|
||||
}
|
||||
auto Serial::getChar() -> char {
|
||||
//We try 500 times to get a character
|
||||
int tries=500;
|
||||
while(!serial_received()) {
|
||||
tries--;
|
||||
waittimes++;
|
||||
if(!tries) {
|
||||
return '\0';
|
||||
}
|
||||
}
|
||||
transmits++;
|
||||
char chr = inb(port);
|
||||
if(chr!='\r')
|
||||
*this << chr;
|
||||
else
|
||||
*this << '\n';
|
||||
return chr;
|
||||
}
|
||||
Serial::Serial(): works(true) {
|
||||
uint32_t baud=115200;
|
||||
port=*((uint16_t*)0x0400);
|
||||
union {
|
||||
uint8_t b[2];
|
||||
uint16_t w;
|
||||
} divisor;
|
||||
divisor.w = 115200/baud;
|
||||
//Turn off interrupts
|
||||
outb(port+SERIAL_IER, 0x00);
|
||||
//Set DLAB-bit
|
||||
outb(port+SERIAL_LCR, 0x80);
|
||||
//Set baud divisor
|
||||
outb(port, divisor.b[0]);
|
||||
outb(port+1, divisor.b[1]);
|
||||
//Set bit count, parity and reset DLAB
|
||||
outb(port+SERIAL_LCR, 3);
|
||||
//Finish init
|
||||
outb(port+SERIAL_FCR, 0xC7);
|
||||
outb(port+SERIAL_MCR, 0x0B);
|
||||
}
|
||||
auto Serial::debug() -> void {
|
||||
if(getChar()) {
|
||||
*this << "The interactive debug shell was started.\n> ";
|
||||
out << "The debug shell was started.\n";
|
||||
char buf[256];
|
||||
*this >> buf;
|
||||
out << buf << "\nDebug shell closed.\n";
|
||||
*this << "Unknown command. TODO\n";
|
||||
}
|
||||
uint64_t wt = waittimes;
|
||||
uint64_t tm = transmits;
|
||||
*this << "Transmit stats: " << (int32_t)wt << " times waited; " << (int32_t)tm << " bytes transferred.\n";
|
||||
waittimes=transmits=0;
|
||||
}
|
||||
auto Serial::isTransmitEmpty() -> int {
|
||||
return inb(port+SERIAL_LSR)&0x20;
|
||||
}
|
||||
auto Serial::putChar(char chr) -> void {
|
||||
if(!works)
|
||||
return;
|
||||
int tries=65535;
|
||||
while(!isTransmitEmpty()) {
|
||||
waittimes++;
|
||||
tries--;
|
||||
if(!tries){
|
||||
works=false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
outb(port, chr);
|
||||
transmits++;
|
||||
}
|
||||
auto Serial::serial_received() -> int {
|
||||
return inb(port+SERIAL_LSR)&1;
|
||||
}
|
||||
auto Serial::getChar() -> char {
|
||||
//We try 500 times to get a character
|
||||
int tries=500;
|
||||
while(!serial_received()) {
|
||||
tries--;
|
||||
waittimes++;
|
||||
if(!tries) {
|
||||
return '\0';
|
||||
}
|
||||
}
|
||||
transmits++;
|
||||
char chr = inb(port);
|
||||
if(chr!='\r')
|
||||
*this << chr;
|
||||
else
|
||||
*this << '\n';
|
||||
return chr;
|
||||
}
|
||||
Serial::Serial(): works(true) {
|
||||
uint32_t baud=115200;
|
||||
port=*((uint16_t*)0x0400);
|
||||
union {
|
||||
uint8_t b[2];
|
||||
uint16_t w;
|
||||
} divisor;
|
||||
divisor.w = 115200/baud;
|
||||
//Turn off interrupts
|
||||
outb(port+SERIAL_IER, 0x00);
|
||||
//Set DLAB-bit
|
||||
outb(port+SERIAL_LCR, 0x80);
|
||||
//Set baud divisor
|
||||
outb(port, divisor.b[0]);
|
||||
outb(port+1, divisor.b[1]);
|
||||
//Set bit count, parity and reset DLAB
|
||||
outb(port+SERIAL_LCR, 3);
|
||||
//Finish init
|
||||
outb(port+SERIAL_FCR, 0xC7);
|
||||
outb(port+SERIAL_MCR, 0x0B);
|
||||
}
|
||||
auto Serial::debug() -> void {
|
||||
if(getChar()) {
|
||||
*this << "The interactive debug shell was started.\n> ";
|
||||
out << "The debug shell was started.\n";
|
||||
char buf[256];
|
||||
*this >> buf;
|
||||
out << buf << "\nDebug shell closed.\n";
|
||||
*this << "Unknown command. TODO\n";
|
||||
}
|
||||
uint64_t wt = waittimes;
|
||||
uint64_t tm = transmits;
|
||||
*this << "Transmit stats: " << (int32_t)wt << " times waited; " << (int32_t)tm << " bytes transferred.\n";
|
||||
waittimes=transmits=0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,185 +7,185 @@
|
|||
#include <string.h>
|
||||
int x=0, y=0;
|
||||
namespace MTGosHAL {
|
||||
auto Screen::putChar(char c) -> void {
|
||||
putChar((unsigned short)c);
|
||||
}
|
||||
auto Screen::putChar(unsigned short c) -> void {
|
||||
switch(c) {
|
||||
case '\n':
|
||||
x=0; y++;
|
||||
break;
|
||||
case '\r':
|
||||
x=0;
|
||||
auto Screen::putChar(char c) -> void {
|
||||
putChar((unsigned short)c);
|
||||
}
|
||||
auto Screen::putChar(unsigned short c) -> void {
|
||||
switch(c) {
|
||||
case '\n':
|
||||
x=0; y++;
|
||||
break;
|
||||
case '\r':
|
||||
x=0;
|
||||
|
||||
break;
|
||||
case '\b':
|
||||
x--;
|
||||
if(x<0) x=0;
|
||||
putChar(' ');
|
||||
x--;
|
||||
if(x<0) x=0;
|
||||
break;
|
||||
case '\0':
|
||||
break;
|
||||
default:
|
||||
for(int lx=0;lx<16;lx++) {
|
||||
for(int ly=0;ly<16;ly++) {
|
||||
if(font[(int)(c)][ly]&(1<<(16-lx))) {
|
||||
lfb[(x*16+lx)+(y*16+ly)*1024]=static_cast<uint32_t>(fg);
|
||||
} else {
|
||||
lfb[(x*16+lx)+(y*16+ly)*1024]=static_cast<uint32_t>(bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
x++;
|
||||
if(x==SCREEN_WIDTH) {
|
||||
x=0; y++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(y>SCREEN_HEIGHT)
|
||||
scroll();
|
||||
}
|
||||
auto Screen::clrscr() -> void {
|
||||
for(int p=0;p<1024*786;p++) {
|
||||
lfb[p]=static_cast<uint32_t>(bg);
|
||||
}
|
||||
x=y=0;
|
||||
}
|
||||
auto Screen::scroll() -> void {
|
||||
for(int ly=0;ly<786-16;ly++) {
|
||||
for(int lx=0;lx<1024;lx++) {
|
||||
lfb[lx+ly*1024]=lfb[lx+(ly+16)*1024];
|
||||
}
|
||||
}
|
||||
for(int ly=786-16;ly<786;ly++) {
|
||||
for(int lx=0;lx<1024;lx++) {
|
||||
lfb[lx+ly*1024]=static_cast<uint32_t>(bg);
|
||||
}
|
||||
}
|
||||
y--;
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<FG_color>(FG_color fg) -> Screen &{
|
||||
this->fg=fg;
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<BG_color>(BG_color bg) -> Screen &{
|
||||
this->bg=bg;
|
||||
return *this;
|
||||
}
|
||||
auto Screen::setColor(FG_color fg) -> Screen &{
|
||||
this->fg=fg;
|
||||
return *this;
|
||||
}
|
||||
auto Screen::setColor(BG_color bg) -> Screen &{
|
||||
this->bg=bg;
|
||||
return *this;
|
||||
}
|
||||
auto Screen::setColor(FG_color fg, BG_color bg) -> Screen &{
|
||||
return (*this).setColor(fg).setColor(bg);
|
||||
}
|
||||
break;
|
||||
case '\b':
|
||||
x--;
|
||||
if(x<0) x=0;
|
||||
putChar(' ');
|
||||
x--;
|
||||
if(x<0) x=0;
|
||||
break;
|
||||
case '\0':
|
||||
break;
|
||||
default:
|
||||
for(int lx=0;lx<16;lx++) {
|
||||
for(int ly=0;ly<16;ly++) {
|
||||
if(font[(int)(c)][ly]&(1<<(16-lx))) {
|
||||
lfb[(x*16+lx)+(y*16+ly)*1024]=static_cast<uint32_t>(fg);
|
||||
} else {
|
||||
lfb[(x*16+lx)+(y*16+ly)*1024]=static_cast<uint32_t>(bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
x++;
|
||||
if(x==SCREEN_WIDTH) {
|
||||
x=0; y++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(y>SCREEN_HEIGHT)
|
||||
scroll();
|
||||
}
|
||||
auto Screen::clrscr() -> void {
|
||||
for(int p=0;p<1024*786;p++) {
|
||||
lfb[p]=static_cast<uint32_t>(bg);
|
||||
}
|
||||
x=y=0;
|
||||
}
|
||||
auto Screen::scroll() -> void {
|
||||
for(int ly=0;ly<786-16;ly++) {
|
||||
for(int lx=0;lx<1024;lx++) {
|
||||
lfb[lx+ly*1024]=lfb[lx+(ly+16)*1024];
|
||||
}
|
||||
}
|
||||
for(int ly=786-16;ly<786;ly++) {
|
||||
for(int lx=0;lx<1024;lx++) {
|
||||
lfb[lx+ly*1024]=static_cast<uint32_t>(bg);
|
||||
}
|
||||
}
|
||||
y--;
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<FG_color>(FG_color fg) -> Screen &{
|
||||
this->fg=fg;
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<BG_color>(BG_color bg) -> Screen &{
|
||||
this->bg=bg;
|
||||
return *this;
|
||||
}
|
||||
auto Screen::setColor(FG_color fg) -> Screen &{
|
||||
this->fg=fg;
|
||||
return *this;
|
||||
}
|
||||
auto Screen::setColor(BG_color bg) -> Screen &{
|
||||
this->bg=bg;
|
||||
return *this;
|
||||
}
|
||||
auto Screen::setColor(FG_color fg, BG_color bg) -> Screen &{
|
||||
return (*this).setColor(fg).setColor(bg);
|
||||
}
|
||||
|
||||
auto Screen::init(struct multiboot_info* mb_info) -> void {
|
||||
lfb=(uint32_t*)((uintptr_t)mb_info->framebuffer_addr);
|
||||
//Load font
|
||||
multiboot_mod_list *mods = (multiboot_mod_list*) mb_info->mods_addr;
|
||||
for(int i=0;i<65536;i++)
|
||||
for(int j=0;j<16;j++)
|
||||
font[i][j]=0;
|
||||
for(uint32_t i=0;i<mb_info->mods_count;i++) {
|
||||
fontfile* font=(fontfile*)(mods[i].mod_start);
|
||||
if((font->magic[0]!='F')||(font->magic[1]!='O')||(font->magic[2]!='N')||(font->magic[3]!='T')) //Is it a font file?
|
||||
continue;
|
||||
charmap* map=(charmap*)((char*)font+font->charmap_off);
|
||||
charwidth* width=(charwidth*)((char*)font+font->charwidth_off);
|
||||
CHR8* chr_begin=(CHR8*)((char*)font+font->chr_off);
|
||||
uint32_t hwcount=0;
|
||||
for(uint32_t i=0;i<font->no_char;i++) {
|
||||
uint16_t char_num=map[i].charnumber;
|
||||
bool wide_char=width[i].width==0x10;
|
||||
if(wide_char) {
|
||||
CHR16* chr=(CHR16*)((char*)(&chr_begin[hwcount]));
|
||||
for(int j=0;j<16;j++) {
|
||||
uint16_t tmp=chr->rows[j]&0xFF;
|
||||
tmp <<= 8;
|
||||
tmp += chr->rows[j]>>8;
|
||||
::font[i][j]=tmp;
|
||||
}
|
||||
hwcount+=2;
|
||||
} else {
|
||||
for(int j=0;j<16;j++)
|
||||
::font[i][j]=(uint16_t)(((uint16_t)chr_begin[hwcount].rows[j])<<8);
|
||||
hwcount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
//clrscr();
|
||||
//Render '\001' character
|
||||
for(int tx=0;tx<16;tx++) {
|
||||
for(int ty=0;ty<16;ty++) {
|
||||
for(int x=0;x<8;x++) {
|
||||
for(int y=0;y<8;y++) {
|
||||
if(font[tx+ty*16][y]&(1<<x))
|
||||
lfb[(x+tx*8)+(y+ty*8)*1024]=0xFFFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
auto Screen::puts(const char* s) -> void {
|
||||
int i=0;
|
||||
while(s[i]!='\0')
|
||||
putChar(s[i++]);
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<Base>(Base output) -> Screen & {
|
||||
base=static_cast<int>(output);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<int>(int op) -> Screen & {
|
||||
uintptr_t output=op;
|
||||
const char* chars="0123456789ABCDEF";
|
||||
char buf[33];
|
||||
buf[32]='\0';
|
||||
char* ptr=buf+31;
|
||||
do {
|
||||
*(ptr--)=chars[output%base];
|
||||
output/=base;
|
||||
} while(output && (ptr!=buf));
|
||||
puts(ptr+1);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<long int>(long int op) -> Screen & {
|
||||
uint64_t output=op;
|
||||
const char* chars="0123456789ABCDEF";
|
||||
char buf[65];
|
||||
buf[64]='\0';
|
||||
char* ptr=buf+63;
|
||||
do {
|
||||
*(ptr--)=chars[output%base];
|
||||
output/=base;
|
||||
} while(output && (ptr!=buf));
|
||||
puts(ptr+1);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<char>(char output) -> Screen & {
|
||||
putChar(output);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<char*>(char* output) -> Screen & {
|
||||
puts(output);
|
||||
return *this;
|
||||
}
|
||||
auto Screen::puts(String& output) -> void {
|
||||
for(size_t i=0;i<output.size();i++) {
|
||||
putChar((uint16_t)output[i]);
|
||||
}
|
||||
}
|
||||
auto Screen::init(struct multiboot_info* mb_info) -> void {
|
||||
lfb=(uint32_t*)((uintptr_t)mb_info->framebuffer_addr);
|
||||
//Load font
|
||||
multiboot_mod_list *mods = (multiboot_mod_list*) mb_info->mods_addr;
|
||||
for(int i=0;i<65536;i++)
|
||||
for(int j=0;j<16;j++)
|
||||
font[i][j]=0;
|
||||
for(uint32_t i=0;i<mb_info->mods_count;i++) {
|
||||
fontfile* font=(fontfile*)(mods[i].mod_start);
|
||||
if((font->magic[0]!='F')||(font->magic[1]!='O')||(font->magic[2]!='N')||(font->magic[3]!='T')) //Is it a font file?
|
||||
continue;
|
||||
charmap* map=(charmap*)((char*)font+font->charmap_off);
|
||||
charwidth* width=(charwidth*)((char*)font+font->charwidth_off);
|
||||
CHR8* chr_begin=(CHR8*)((char*)font+font->chr_off);
|
||||
uint32_t hwcount=0;
|
||||
for(uint32_t i=0;i<font->no_char;i++) {
|
||||
uint16_t char_num=map[i].charnumber;
|
||||
bool wide_char=width[i].width==0x10;
|
||||
if(wide_char) {
|
||||
CHR16* chr=(CHR16*)((char*)(&chr_begin[hwcount]));
|
||||
for(int j=0;j<16;j++) {
|
||||
uint16_t tmp=chr->rows[j]&0xFF;
|
||||
tmp <<= 8;
|
||||
tmp += chr->rows[j]>>8;
|
||||
::font[i][j]=tmp;
|
||||
}
|
||||
hwcount+=2;
|
||||
} else {
|
||||
for(int j=0;j<16;j++)
|
||||
::font[i][j]=(uint16_t)(((uint16_t)chr_begin[hwcount].rows[j])<<8);
|
||||
hwcount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
//clrscr();
|
||||
//Render '\001' character
|
||||
for(int tx=0;tx<16;tx++) {
|
||||
for(int ty=0;ty<16;ty++) {
|
||||
for(int x=0;x<8;x++) {
|
||||
for(int y=0;y<8;y++) {
|
||||
if(font[tx+ty*16][y]&(1<<x))
|
||||
lfb[(x+tx*8)+(y+ty*8)*1024]=0xFFFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
auto Screen::puts(const char* s) -> void {
|
||||
int i=0;
|
||||
while(s[i]!='\0')
|
||||
putChar(s[i++]);
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<Base>(Base output) -> Screen & {
|
||||
base=static_cast<int>(output);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<int>(int op) -> Screen & {
|
||||
uintptr_t output=op;
|
||||
const char* chars="0123456789ABCDEF";
|
||||
char buf[33];
|
||||
buf[32]='\0';
|
||||
char* ptr=buf+31;
|
||||
do {
|
||||
*(ptr--)=chars[output%base];
|
||||
output/=base;
|
||||
} while(output && (ptr!=buf));
|
||||
puts(ptr+1);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<long int>(long int op) -> Screen & {
|
||||
uint64_t output=op;
|
||||
const char* chars="0123456789ABCDEF";
|
||||
char buf[65];
|
||||
buf[64]='\0';
|
||||
char* ptr=buf+63;
|
||||
do {
|
||||
*(ptr--)=chars[output%base];
|
||||
output/=base;
|
||||
} while(output && (ptr!=buf));
|
||||
puts(ptr+1);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<char>(char output) -> Screen & {
|
||||
putChar(output);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<char*>(char* output) -> Screen & {
|
||||
puts(output);
|
||||
return *this;
|
||||
}
|
||||
auto Screen::puts(String& output) -> void {
|
||||
for(size_t i=0;i<output.size();i++) {
|
||||
putChar((uint16_t)output[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,46 +8,46 @@
|
|||
extern "C" const int kernel_start;
|
||||
extern "C" const int kernel_end; //those are voids actually
|
||||
void *operator new(size_t size) {
|
||||
return MTGosHAL::mm.alloc(size);
|
||||
return MTGosHAL::mm.alloc(size);
|
||||
}
|
||||
void *operator new[](size_t size) {
|
||||
return MTGosHAL::mm.alloc(size);
|
||||
return MTGosHAL::mm.alloc(size);
|
||||
}
|
||||
void operator delete(void* p) {
|
||||
MTGosHAL::mm.free(p);
|
||||
MTGosHAL::mm.free(p);
|
||||
}
|
||||
void operator delete[](void* p) {
|
||||
MTGosHAL::mm.free(p);
|
||||
MTGosHAL::mm.free(p);
|
||||
}
|
||||
void operator delete(void* p, size_t size) {
|
||||
MTGosHAL::mm.free(p);
|
||||
MTGosHAL::mm.free(p);
|
||||
}
|
||||
void operator delete[](void* p, size_t size) {
|
||||
MTGosHAL::mm.free(p);
|
||||
MTGosHAL::mm.free(p);
|
||||
}
|
||||
namespace MTGosHAL {
|
||||
auto PMM::alloc(size_t length) -> void * {
|
||||
auto PMM::alloc(size_t length) -> void * {
|
||||
if(!head) {
|
||||
//Alloc space for head
|
||||
if(length+sizeof(malloc_t)<=PAGESIZE) { //Small optimization. The routine for allocating more than one continuous page is terribly slow.
|
||||
void *tmp;
|
||||
*this >> tmp;
|
||||
head=(malloc_t*)tmp;
|
||||
} else
|
||||
head=(malloc_t*)(*this)(UNSHIFT((length+sizeof(malloc_t)))+1);
|
||||
if(!head) //The alloc() didn't work! We're out of RAM!
|
||||
return nullptr;
|
||||
head->len=length;
|
||||
head->next=head->last=nullptr;
|
||||
malloc_t* tmp=head;
|
||||
tmp++;
|
||||
return (void*)tmp;
|
||||
//Alloc space for head
|
||||
if(length+sizeof(malloc_t)<=PAGESIZE) { //Small optimization. The routine for allocating more than one continuous page is terribly slow.
|
||||
void *tmp;
|
||||
*this >> tmp;
|
||||
head=(malloc_t*)tmp;
|
||||
} else
|
||||
head=(malloc_t*)(*this)(UNSHIFT((length+sizeof(malloc_t)))+1);
|
||||
if(!head) //The alloc() didn't work! We're out of RAM!
|
||||
return nullptr;
|
||||
head->len=length;
|
||||
head->next=head->last=nullptr;
|
||||
malloc_t* tmp=head;
|
||||
tmp++;
|
||||
return (void*)tmp;
|
||||
}
|
||||
malloc_t* curr=head;
|
||||
malloc_t* last=nullptr;
|
||||
do {
|
||||
uintptr_t loc=(uintptr_t)curr+sizeof(malloc_t)+curr->len;
|
||||
if((loc+length+sizeof(malloc_t))<((loc&(~FLAGS))+PAGESIZE) &&
|
||||
uintptr_t loc=(uintptr_t)curr+sizeof(malloc_t)+curr->len;
|
||||
if((loc+length+sizeof(malloc_t))<((loc&(~FLAGS))+PAGESIZE) &&
|
||||
((!curr->next) || (loc+length+sizeof(malloc_t))<((uintptr_t)(curr->next)))) {
|
||||
malloc_t *allocd=(malloc_t *)loc;
|
||||
allocd->len=length;
|
||||
|
@ -55,23 +55,23 @@ namespace MTGosHAL {
|
|||
allocd->next=curr->next; //Set double linked list
|
||||
curr->next=allocd;
|
||||
if(allocd->next)
|
||||
allocd->next->last=allocd;
|
||||
allocd->next->last=allocd;
|
||||
malloc_t *tmp=allocd;
|
||||
tmp++;
|
||||
return (void*)tmp;
|
||||
}
|
||||
last=curr;
|
||||
curr=curr->next;
|
||||
}
|
||||
last=curr;
|
||||
curr=curr->next;
|
||||
} while(curr);
|
||||
malloc_t *allocd=nullptr;
|
||||
if(length+sizeof(malloc_t)<=PAGESIZE) { //Small optimization. The routine for allocating more than one continuous page is terribly slow.
|
||||
void *tmp;
|
||||
*this >> tmp;
|
||||
allocd=(malloc_t*)tmp;
|
||||
void *tmp;
|
||||
*this >> tmp;
|
||||
allocd=(malloc_t*)tmp;
|
||||
} else
|
||||
allocd=(malloc_t*)(*this)(UNSHIFT(length+sizeof(malloc_t))+1);
|
||||
allocd=(malloc_t*)(*this)(UNSHIFT(length+sizeof(malloc_t))+1);
|
||||
if(!allocd) //The alloc() didn't work! We're out of RAM!
|
||||
return nullptr;
|
||||
return nullptr;
|
||||
last->next=allocd;
|
||||
allocd->len=length;
|
||||
allocd->last=last;
|
||||
|
@ -82,24 +82,24 @@ namespace MTGosHAL {
|
|||
}
|
||||
auto PMM::free(void* ptr) -> bool {
|
||||
if(!ptr)
|
||||
return false;
|
||||
return false;
|
||||
malloc_t* curr=head;
|
||||
malloc_t* chk=(malloc_t*)ptr;
|
||||
chk--;
|
||||
do {
|
||||
if(curr==chk) {
|
||||
uintptr_t start=((uintptr_t)chk)&(~FLAGS);
|
||||
uintptr_t end=start+PAGESIZE;
|
||||
if((((uintptr_t)(curr->last)<start)||((uintptr_t)(curr->last)>=end))&&(((uintptr_t)(curr->next)>=end)||((uintptr_t)(curr->next)<start))) {
|
||||
*this << (void*)start;
|
||||
if(curr==chk) {
|
||||
uintptr_t start=((uintptr_t)chk)&(~FLAGS);
|
||||
uintptr_t end=start+PAGESIZE;
|
||||
if((((uintptr_t)(curr->last)<start)||((uintptr_t)(curr->last)>=end))&&(((uintptr_t)(curr->next)>=end)||((uintptr_t)(curr->next)<start))) {
|
||||
*this << (void*)start;
|
||||
}
|
||||
if(curr->last)
|
||||
curr->last->next=curr->next;
|
||||
curr->last->next=curr->next;
|
||||
else {
|
||||
head=curr->next;
|
||||
head=curr->next;
|
||||
}
|
||||
if(curr->next)
|
||||
curr->next->last=curr->last;
|
||||
curr->next->last=curr->last;
|
||||
return true;
|
||||
}
|
||||
curr=curr->next;
|
||||
|
@ -108,20 +108,20 @@ namespace MTGosHAL {
|
|||
}
|
||||
PMM::PMM(): head(nullptr), pmm2() {}
|
||||
auto PMM::init(struct multiboot_info* mb_info) -> void {
|
||||
pmm2.init(mb_info);
|
||||
pmm2.init(mb_info);
|
||||
}
|
||||
auto PMM::markUsed(const void * addr, uint32_t length) -> bool {
|
||||
return pmm2.markUsed(addr, length);
|
||||
return pmm2.markUsed(addr, length);
|
||||
}
|
||||
auto PMM::operator >> (void * &addr) -> PMM & {
|
||||
pmm2>>addr;
|
||||
return *this;
|
||||
pmm2>>addr;
|
||||
return *this;
|
||||
} //alloc
|
||||
auto PMM::operator << (const void * addr) -> PMM & {
|
||||
pmm2<<addr;
|
||||
return *this;
|
||||
pmm2<<addr;
|
||||
return *this;
|
||||
} //free
|
||||
auto PMM::operator()(int pages) -> void*{
|
||||
return pmm2(pages);
|
||||
return pmm2(pages);
|
||||
} //alloc_multipage
|
||||
}
|
||||
|
|
|
@ -19,80 +19,80 @@ PMM2::PMM2(): pmm3() {
|
|||
}
|
||||
|
||||
auto PMM2::markUsed(const void * addr, uint32_t length) -> bool {
|
||||
uint32_t add=(uint32_t)addr;
|
||||
uint32_t pagetid = SPLIT1_UNSHIFT(add);
|
||||
if(length > 256*1024*1024) //Maximum allocation limit is 256MB
|
||||
return false;
|
||||
if(!pageTable[pagetid]) {
|
||||
void* temp;
|
||||
pmm3 >> temp;
|
||||
pageTable[pagetid]=(uint16_t*)temp;
|
||||
for(int i=0;i<2048;i++)
|
||||
pageTable[pagetid][i]=0;
|
||||
markUsed(pageTable[pagetid],1024); //Not a mistake
|
||||
}
|
||||
//Check if used
|
||||
for(uint32_t curr_addr=add+length;curr_addr>=add;curr_addr-=0x1000) {
|
||||
if(pageTable[SPLIT1_UNSHIFT(curr_addr)][SPLIT2_UNSHIFT(curr_addr)])
|
||||
return false;
|
||||
}
|
||||
//Mark as used
|
||||
uint16_t counter=1;
|
||||
for(uint32_t curr_addr=add+length;curr_addr>=add;curr_addr-=0x1000) {
|
||||
pageTable[SPLIT1_UNSHIFT(curr_addr)][SPLIT2_UNSHIFT(curr_addr)]=counter++;
|
||||
pmm3.markUsed((void*)curr_addr);
|
||||
}
|
||||
return true;
|
||||
uint32_t add=(uint32_t)addr;
|
||||
uint32_t pagetid = SPLIT1_UNSHIFT(add);
|
||||
if(length > 256*1024*1024) //Maximum allocation limit is 256MB
|
||||
return false;
|
||||
if(!pageTable[pagetid]) {
|
||||
void* temp;
|
||||
pmm3 >> temp;
|
||||
pageTable[pagetid]=(uint16_t*)temp;
|
||||
for(int i=0;i<2048;i++)
|
||||
pageTable[pagetid][i]=0;
|
||||
markUsed(pageTable[pagetid],1024); //Not a mistake
|
||||
}
|
||||
//Check if used
|
||||
for(uint32_t curr_addr=add+length;curr_addr>=add;curr_addr-=0x1000) {
|
||||
if(pageTable[SPLIT1_UNSHIFT(curr_addr)][SPLIT2_UNSHIFT(curr_addr)])
|
||||
return false;
|
||||
}
|
||||
//Mark as used
|
||||
uint16_t counter=1;
|
||||
for(uint32_t curr_addr=add+length;curr_addr>=add;curr_addr-=0x1000) {
|
||||
pageTable[SPLIT1_UNSHIFT(curr_addr)][SPLIT2_UNSHIFT(curr_addr)]=counter++;
|
||||
pmm3.markUsed((void*)curr_addr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
auto PMM2::operator >> (void * &addr) -> PMM2 & {
|
||||
pmm3 >> addr;
|
||||
markUsed(addr,4096);
|
||||
return *this;
|
||||
pmm3 >> addr;
|
||||
markUsed(addr,4096);
|
||||
return *this;
|
||||
}
|
||||
auto PMM2::operator << (const void *addr) -> PMM2 & {
|
||||
uint32_t add=(uint32_t)addr;
|
||||
if(!pageTable[SPLIT1_UNSHIFT(add)])
|
||||
return *this; //Prevent nullptr derefs
|
||||
for(int i=0;i<pageTable[SPLIT1_UNSHIFT(add)][SPLIT2_UNSHIFT(add)];i++) {
|
||||
pageTable[SPLIT1_UNSHIFT(add+i*4096)][SPLIT2_UNSHIFT(add+i*4096)]=0;
|
||||
pmm3 << (void*)(add+i*4096);
|
||||
}
|
||||
return *this;
|
||||
uint32_t add=(uint32_t)addr;
|
||||
if(!pageTable[SPLIT1_UNSHIFT(add)])
|
||||
return *this; //Prevent nullptr derefs
|
||||
for(int i=0;i<pageTable[SPLIT1_UNSHIFT(add)][SPLIT2_UNSHIFT(add)];i++) {
|
||||
pageTable[SPLIT1_UNSHIFT(add+i*4096)][SPLIT2_UNSHIFT(add+i*4096)]=0;
|
||||
pmm3 << (void*)(add+i*4096);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
auto PMM2::operator()(int pages) -> void* {
|
||||
//I want to get this working so:
|
||||
//TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
|
||||
// NEVER USE A BRUTE-FORCE ALGO TO ALLOC PAGES!
|
||||
//TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
|
||||
for(uint32_t i=0;i<(uint32_t)(-(pages*4096));i+=4096) {
|
||||
if(markUsed((void*)i,pages*4096))
|
||||
return (void*)i;
|
||||
}
|
||||
return nullptr;
|
||||
//I want to get this working so:
|
||||
//TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
|
||||
// NEVER USE A BRUTE-FORCE ALGO TO ALLOC PAGES!
|
||||
//TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
|
||||
for(uint32_t i=0;i<(uint32_t)(-(pages*4096));i+=4096) {
|
||||
if(markUsed((void*)i,pages*4096))
|
||||
return (void*)i;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
auto PMM2::init(struct multiboot_info* mb_info) -> void {
|
||||
pmm3.init(mb_info);
|
||||
void *temp;
|
||||
pmm3 >> temp;
|
||||
pageTable=(uint16_t**)temp;
|
||||
for(int i=0;i<4096;i++)
|
||||
pageTable[i]=nullptr;
|
||||
markUsed(pageTable,4096);
|
||||
markUsed((void*)nullptr,4096);
|
||||
struct multiboot_mmap_entry* mmap = (struct multiboot_mmap_entry*) mb_info->mmap_addr;
|
||||
struct multiboot_mmap_entry* mmap_end = (struct multiboot_mmap_entry*) ((unsigned int) mb_info->mmap_addr + mb_info->mmap_length);
|
||||
while(mmap < mmap_end) {
|
||||
if(mmap->type != 1) {
|
||||
markUsed((void*)mmap->addr,mmap->len);
|
||||
pmm3.init(mb_info);
|
||||
void *temp;
|
||||
pmm3 >> temp;
|
||||
pageTable=(uint16_t**)temp;
|
||||
for(int i=0;i<4096;i++)
|
||||
pageTable[i]=nullptr;
|
||||
markUsed(pageTable,4096);
|
||||
markUsed((void*)nullptr,4096);
|
||||
struct multiboot_mmap_entry* mmap = (struct multiboot_mmap_entry*) mb_info->mmap_addr;
|
||||
struct multiboot_mmap_entry* mmap_end = (struct multiboot_mmap_entry*) ((unsigned int) mb_info->mmap_addr + mb_info->mmap_length);
|
||||
while(mmap < mmap_end) {
|
||||
if(mmap->type != 1) {
|
||||
markUsed((void*)mmap->addr,mmap->len);
|
||||
}
|
||||
mmap++;
|
||||
}
|
||||
markUsed(&kernel_start,((uint32_t)&kernel_end)-((uint32_t)&kernel_start)); //Protect kernel)
|
||||
multiboot_mod_list *mods = (multiboot_mod_list*) mb_info->mods_addr;
|
||||
for(uint32_t i=0;i<mb_info->mods_count;i++) {
|
||||
markUsed((void*)((uint32_t)(&mods[i])&(~0xFFF)),4096); //Mark all of the module table as used
|
||||
markUsed((void*)mods[i].mod_start,mods[i].mod_end-mods[i].mod_start);
|
||||
}
|
||||
mmap++;
|
||||
}
|
||||
markUsed(&kernel_start,((uint32_t)&kernel_end)-((uint32_t)&kernel_start)); //Protect kernel)
|
||||
multiboot_mod_list *mods = (multiboot_mod_list*) mb_info->mods_addr;
|
||||
for(uint32_t i=0;i<mb_info->mods_count;i++) {
|
||||
markUsed((void*)((uint32_t)(&mods[i])&(~0xFFF)),4096); //Mark all of the module table as used
|
||||
markUsed((void*)mods[i].mod_start,mods[i].mod_end-mods[i].mod_start);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,65 +7,65 @@ extern "C" const int kernel_end; //those are voids actually
|
|||
namespace MTGosHAL {
|
||||
PMM3::PMM3() {}
|
||||
auto PMM3::init(struct multiboot_info * mb_info) -> void {
|
||||
for(int i=0;i<0x8000;i++)
|
||||
bitmap[i]=0;
|
||||
struct multiboot_mmap_entry* mmap = (struct multiboot_mmap_entry*) mb_info->mmap_addr;
|
||||
struct multiboot_mmap_entry* mmap_end = (struct multiboot_mmap_entry*) ((unsigned int) mb_info->mmap_addr + mb_info->mmap_length);
|
||||
while (mmap < mmap_end) {
|
||||
if (mmap->type == 1) {
|
||||
// Memory is free
|
||||
uintptr_t addr = mmap->addr;
|
||||
uintptr_t end_addr = addr + mmap->len;
|
||||
while (addr < end_addr) {
|
||||
*this << (void*) addr;
|
||||
addr += 0x1000;
|
||||
}
|
||||
}
|
||||
mmap++;
|
||||
}
|
||||
unsigned int addr = (unsigned int) &kernel_start;
|
||||
while(addr < (unsigned int) &kernel_end) {
|
||||
markUsed((void*)addr);
|
||||
addr+=0x1000;
|
||||
}
|
||||
markUsed((void*)0);
|
||||
multiboot_mod_list *mods = (multiboot_mod_list*) mb_info->mods_addr;
|
||||
for(uint32_t i=0;i<mb_info->mods_count;i++) {
|
||||
markUsed((void*)((uint32_t)(&mods[i])&(~0xFFF))); //Mark all of the module table as used
|
||||
for(uint32_t start=(uint32_t)(mods[i].mod_start)&(~0xFFF);start<(uint32_t)(mods[i].mod_end);start+=0x1000) {
|
||||
markUsed((void*)start); //Protect all multiboot modules
|
||||
}
|
||||
}
|
||||
for(int i=0;i<0x8000;i++)
|
||||
bitmap[i]=0;
|
||||
struct multiboot_mmap_entry* mmap = (struct multiboot_mmap_entry*) mb_info->mmap_addr;
|
||||
struct multiboot_mmap_entry* mmap_end = (struct multiboot_mmap_entry*) ((unsigned int) mb_info->mmap_addr + mb_info->mmap_length);
|
||||
while (mmap < mmap_end) {
|
||||
if (mmap->type == 1) {
|
||||
// Memory is free
|
||||
uintptr_t addr = mmap->addr;
|
||||
uintptr_t end_addr = addr + mmap->len;
|
||||
while (addr < end_addr) {
|
||||
*this << (void*) addr;
|
||||
addr += 0x1000;
|
||||
}
|
||||
}
|
||||
mmap++;
|
||||
}
|
||||
unsigned int addr = (unsigned int) &kernel_start;
|
||||
while(addr < (unsigned int) &kernel_end) {
|
||||
markUsed((void*)addr);
|
||||
addr+=0x1000;
|
||||
}
|
||||
markUsed((void*)0);
|
||||
multiboot_mod_list *mods = (multiboot_mod_list*) mb_info->mods_addr;
|
||||
for(uint32_t i=0;i<mb_info->mods_count;i++) {
|
||||
markUsed((void*)((uint32_t)(&mods[i])&(~0xFFF))); //Mark all of the module table as used
|
||||
for(uint32_t start=(uint32_t)(mods[i].mod_start)&(~0xFFF);start<(uint32_t)(mods[i].mod_end);start+=0x1000) {
|
||||
markUsed((void*)start); //Protect all multiboot modules
|
||||
}
|
||||
}
|
||||
}
|
||||
auto PMM3::markUsed(const void * addr) -> void {
|
||||
unsigned int address=(unsigned int)addr;
|
||||
address>>=12;
|
||||
int index=address>>5;
|
||||
int bit=1<<(address&0x1F);
|
||||
bitmap[index]&=~bit;
|
||||
unsigned int address=(unsigned int)addr;
|
||||
address>>=12;
|
||||
int index=address>>5;
|
||||
int bit=1<<(address&0x1F);
|
||||
bitmap[index]&=~bit;
|
||||
}
|
||||
auto PMM3::operator >> (void * &addr) -> PMM3 & {
|
||||
for(int i=0;i<0x8000;i++) {
|
||||
if(!bitmap[i])
|
||||
continue;
|
||||
for(int j=0;j<32;j++) {
|
||||
if(bitmap[i]&(1<<j)) {
|
||||
//We found a free page!
|
||||
bitmap[i]&=~(1<<j);
|
||||
addr=(void*)(((i<<5)+j)<<12);
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
}
|
||||
addr=nullptr;
|
||||
return *this;
|
||||
for(int i=0;i<0x8000;i++) {
|
||||
if(!bitmap[i])
|
||||
continue;
|
||||
for(int j=0;j<32;j++) {
|
||||
if(bitmap[i]&(1<<j)) {
|
||||
//We found a free page!
|
||||
bitmap[i]&=~(1<<j);
|
||||
addr=(void*)(((i<<5)+j)<<12);
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
}
|
||||
addr=nullptr;
|
||||
return *this;
|
||||
}
|
||||
auto PMM3::operator << (const void * addr) -> PMM3 & {
|
||||
unsigned int address=(unsigned int)addr;
|
||||
address>>=12;
|
||||
int index=address>>5;
|
||||
int bit=1<<(address&0x1F);
|
||||
bitmap[index]|=bit;
|
||||
return *this;
|
||||
unsigned int address=(unsigned int)addr;
|
||||
address>>=12;
|
||||
int index=address>>5;
|
||||
int bit=1<<(address&0x1F);
|
||||
bitmap[index]|=bit;
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,21 +5,21 @@ namespace MTGosHAL {
|
|||
VMM3::VMM3(): pmm() {
|
||||
}
|
||||
auto VMM3::init(struct multiboot_info* mb_info) -> void {
|
||||
pmm.init(mb_info);
|
||||
void* tmp;
|
||||
pmm >> tmp;
|
||||
pd=(uint32_t**)tmp;
|
||||
uint32_t ent=0x87;
|
||||
for(int i=0;i<1024;i++) {
|
||||
pd[i]=(uint32_t*)ent;
|
||||
ent+=0x1000*1024;
|
||||
}
|
||||
enterPaging(pd);
|
||||
pmm.init(mb_info);
|
||||
void* tmp;
|
||||
pmm >> tmp;
|
||||
pd=(uint32_t**)tmp;
|
||||
uint32_t ent=0x87;
|
||||
for(int i=0;i<1024;i++) {
|
||||
pd[i]=(uint32_t*)ent;
|
||||
ent+=0x1000*1024;
|
||||
}
|
||||
enterPaging(pd);
|
||||
}
|
||||
auto VMM3::alloc(uint32_t length) -> void* {
|
||||
return pmm.alloc(length);
|
||||
return pmm.alloc(length);
|
||||
}
|
||||
auto VMM3::free(void* ptr) -> bool {
|
||||
return pmm.free(ptr);
|
||||
return pmm.free(ptr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <blockdev.hpp>
|
||||
namespace MTGosHAL {
|
||||
BlockDevice::BlockDevice() {}
|
||||
BlockDevice::~BlockDevice() {}
|
||||
BlockDevice::BlockDevice() {}
|
||||
BlockDevice::~BlockDevice() {}
|
||||
}
|
||||
|
|
|
@ -11,12 +11,12 @@ auto schedule(struct cpu_state* cpu) -> struct cpu_state* {
|
|||
}
|
||||
Multitasking::Multitasking(): curr_task(nullptr), first_task(nullptr)
|
||||
{
|
||||
for(int i=0;i<32;i++) {
|
||||
if(i==2)
|
||||
continue;
|
||||
tss[i]=0;
|
||||
}
|
||||
tss[2]=0x10;
|
||||
for(int i=0;i<32;i++) {
|
||||
if(i==2)
|
||||
continue;
|
||||
tss[i]=0;
|
||||
}
|
||||
tss[2]=0x10;
|
||||
//task_states[0] = initTask(stack_a, user_stack_a, task_a);
|
||||
//task_states[1] = initTask(stack_b, user_stack_b, task_b);
|
||||
if(!idt.request(0x20,MTGosHAL::schedule)) {
|
||||
|
@ -67,24 +67,24 @@ auto Multitasking::initTask(void(* entry)()) -> struct cpu_state*
|
|||
//Create new task class
|
||||
Task* task = new Task(state);
|
||||
if(first_task)
|
||||
first_task->addTask(task);
|
||||
first_task->addTask(task);
|
||||
else {
|
||||
first_task=task;
|
||||
first_task=task;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
auto Multitasking::schedule(struct cpu_state* cpu) -> struct cpu_state*
|
||||
{
|
||||
Task* next=nullptr;
|
||||
if(curr_task) {
|
||||
next=curr_task->pause(cpu);
|
||||
}
|
||||
if (!next) {
|
||||
next=first_task;
|
||||
}
|
||||
curr_task=next;
|
||||
struct cpu_state* cpu_state=next->unpause();
|
||||
MTGosHAL::tasks.tss[1] = (uint32_t) (uint64_t)(cpu_state + 1);
|
||||
return cpu_state;
|
||||
Task* next=nullptr;
|
||||
if(curr_task) {
|
||||
next=curr_task->pause(cpu);
|
||||
}
|
||||
if (!next) {
|
||||
next=first_task;
|
||||
}
|
||||
curr_task=next;
|
||||
struct cpu_state* cpu_state=next->unpause();
|
||||
MTGosHAL::tasks.tss[1] = (uint32_t) (uint64_t)(cpu_state + 1);
|
||||
return cpu_state;
|
||||
}
|
||||
} // namespace MTGosHAL
|
||||
|
|
|
@ -2,20 +2,20 @@
|
|||
#include <gdt.hpp>
|
||||
#include <serial.hpp>
|
||||
namespace MTGosHAL {
|
||||
GDT::GDT() {
|
||||
gdt[0]=gdt[1]=gdt[2]=gdt[3]=gdt[4]=gdt[5]=gdt[6]=0x0ull;
|
||||
}
|
||||
auto GDT::setEntry(int i, unsigned int base, unsigned int limit, int flags) -> void {
|
||||
gdt[i] = limit & 0xffffLL;
|
||||
gdt[i] |= (base & 0xffffffLL) << 16;
|
||||
gdt[i] |= (flags & 0xffLL) << 40;
|
||||
gdt[i] |= ((limit >> 16) & 0xfLL) << 48;
|
||||
gdt[i] |= ((flags >> 8 )& 0xffLL) << 52;
|
||||
gdt[i] |= ((base >> 24) & 0xffLL) << 56;
|
||||
}
|
||||
auto GDT::apply() -> void {
|
||||
debug << "We are now trying to set our GDT. If the CPU triplefaults, something went wrong in MTGosHAL::GDT::apply() or loadGDT().\n";
|
||||
fin={(uint16_t)7*8-1, (void*)gdt};
|
||||
loadGDT((void*)(&fin));
|
||||
};
|
||||
GDT::GDT() {
|
||||
gdt[0]=gdt[1]=gdt[2]=gdt[3]=gdt[4]=gdt[5]=gdt[6]=0x0ull;
|
||||
}
|
||||
auto GDT::setEntry(int i, unsigned int base, unsigned int limit, int flags) -> void {
|
||||
gdt[i] = limit & 0xffffLL;
|
||||
gdt[i] |= (base & 0xffffffLL) << 16;
|
||||
gdt[i] |= (flags & 0xffLL) << 40;
|
||||
gdt[i] |= ((limit >> 16) & 0xfLL) << 48;
|
||||
gdt[i] |= ((flags >> 8 )& 0xffLL) << 52;
|
||||
gdt[i] |= ((base >> 24) & 0xffLL) << 56;
|
||||
}
|
||||
auto GDT::apply() -> void {
|
||||
debug << "We are now trying to set our GDT. If the CPU triplefaults, something went wrong in MTGosHAL::GDT::apply() or loadGDT().\n";
|
||||
fin={(uint16_t)7*8-1, (void*)gdt};
|
||||
loadGDT((void*)(&fin));
|
||||
};
|
||||
}
|
||||
|
|
|
@ -8,119 +8,119 @@ bool epicfail=false;
|
|||
auto syscall(uint32_t syscall_num, void* handle, void* args) -> void*;
|
||||
extern void** progs;
|
||||
namespace MTGosHAL {
|
||||
auto startup() -> void;
|
||||
IDT::IDT() {
|
||||
//Init PIC
|
||||
outb(0x20, 0x11); //Init Master-PIC
|
||||
outb(0x21, 0x20); //Interrupt number for IRQ0
|
||||
outb(0x21, 0x04); //IRQ is the Slave
|
||||
outb(0x21, 0x01); //ICW 4
|
||||
outb(0xA0, 0x11); //Init Master-PIC
|
||||
outb(0xA1, 0x28); //Interrupt number for IRQ8
|
||||
outb(0xA1, 0x02); //IRQ is the Slave
|
||||
outb(0xA1, 0x01); //ICW 4
|
||||
//Activate IRQ's
|
||||
outb(0x21, 0x00);
|
||||
outb(0xA1, 0x00);
|
||||
}
|
||||
auto IDT::setEntry(int i, void* offset, uint16_t seg, uint8_t flags) -> void {
|
||||
idt[i]=(uint16_t)((uint64_t)offset);
|
||||
idt[i]|=(unsigned __int128)(((uint64_t)offset)>>16)<<48;
|
||||
idt[i]|=((unsigned __int128)seg)<<16;
|
||||
idt[i]|=((unsigned __int128)flags)<<40;
|
||||
}
|
||||
auto IDT::apply() -> void {
|
||||
debug << "Now trying to load the IDT.\n";
|
||||
idtptr.limit=(uint16_t)(256*8-1);
|
||||
idtptr.pointer=(unsigned __int128*)&idt;
|
||||
loadIDT((void*)&idtptr);
|
||||
}
|
||||
auto IDT::handle(struct cpu_state* cpu) -> struct cpu_state* {
|
||||
struct cpu_state* new_cpu=cpu;
|
||||
debug << "Interrupt 0x" << Base::HEXADECIMAL << (int) cpu->intr << " was raised.\n";
|
||||
if(cpu->intr<=0x1F) {
|
||||
if(epicfail) {
|
||||
err << "While trying to output the stack another exception happened\n";
|
||||
while(1) {
|
||||
asm volatile("cli; hlt");
|
||||
}
|
||||
}
|
||||
epicfail=true;
|
||||
err << "Exception 0x" << Base::HEXADECIMAL << (int) cpu->intr << "! Kernel halted!\n";
|
||||
err << "RAX = 0x" << (int)cpu->rax << " - RBX = 0x" << (int)cpu->rbx << "\n";
|
||||
err << "RCX = 0x" << (int)cpu->rcx << " - RDX = 0x" << (int)cpu->rdx << "\n";
|
||||
err << "RSI = 0x" << (int)cpu->rsi << " - RDI = 0x" << (int)cpu->rdi << "\n";
|
||||
err << "SS:RSP = 0x" << (int)cpu->ss << ":0x" << (int)cpu->rsp << " - SS:RBP = 0x" << (int)cpu->ss << ":0x" << (int)cpu->rbp << "\n";
|
||||
err << "CS:RIP = 0x" << (int)cpu->cs << ":0x" << (int)cpu->rip << " - INTR:ERR = 0x" << (int)cpu->intr << ":0x" << (int)cpu->error << "\n";
|
||||
err << "------ END OF REGISTER DUMP ------ ------ START OF PROGRAM LOADPOINTS ------\n";
|
||||
for(int i=0;i<1024;i++) {
|
||||
if(!progs[i])
|
||||
break;
|
||||
err << "0x" << (int)((uint64_t)progs[i]) << "; ";
|
||||
}
|
||||
err << "\n";
|
||||
uint16_t counter = 1193180 / 220; //Make an annoying beep
|
||||
outb(0x43, 0xB6);
|
||||
outb(0x42, (uint8_t)counter);
|
||||
outb(0x42, (uint8_t)(counter>>8));
|
||||
//outb(0x61, inb(0x61) | 3);
|
||||
err << "A detailled traceback is being output over the serial connector.\n";
|
||||
debug << "Outputting 32 stacks...\n";
|
||||
uint64_t *rsp=(uint64_t*)cpu->rsp;
|
||||
uint64_t *rbp=(uint64_t*)cpu->rbp;
|
||||
uint64_t *rip=(uint64_t*)cpu->rip;
|
||||
for(int i=0;i<32;i++) {
|
||||
if(!(rsp||rbp||rip))
|
||||
break;
|
||||
if((int64_t)(rbp-rsp)<1)
|
||||
break;
|
||||
debug << Base::HEXADECIMAL << "Execution at 0x" << (int64_t) rip << ":\n";
|
||||
debug << "Number of local variables: 0x" << (int64_t)(rbp-rsp)-1 << "\n";
|
||||
for(uintptr_t i=0;i<(uintptr_t)(rbp-rsp)-1;i++) {
|
||||
debug << "0x"<< (int64_t)(i*8) << ": 0x" << (int64_t)rsp[i] << "\n";
|
||||
}
|
||||
rip=(uint64_t*)rbp[1];
|
||||
rsp=rbp;
|
||||
rbp=(uint64_t*)rbp[0];
|
||||
}
|
||||
while(1) {
|
||||
asm volatile("cli; hlt");
|
||||
}
|
||||
} else if(cpu->intr >= 0x20 && cpu->intr <= 0x2F) {
|
||||
if(cpu->intr >= 0x28) {
|
||||
outb(0xA0, 0x20);
|
||||
}
|
||||
outb(0x20, 0x20);
|
||||
debug << "The IRQ " << Base::DECIMAL << (int) cpu->intr-0x20 << " was handled.\n";
|
||||
if(cpu->intr==0x20) {
|
||||
debug.debug();
|
||||
}
|
||||
auto startup() -> void;
|
||||
IDT::IDT() {
|
||||
//Init PIC
|
||||
outb(0x20, 0x11); //Init Master-PIC
|
||||
outb(0x21, 0x20); //Interrupt number for IRQ0
|
||||
outb(0x21, 0x04); //IRQ is the Slave
|
||||
outb(0x21, 0x01); //ICW 4
|
||||
outb(0xA0, 0x11); //Init Master-PIC
|
||||
outb(0xA1, 0x28); //Interrupt number for IRQ8
|
||||
outb(0xA1, 0x02); //IRQ is the Slave
|
||||
outb(0xA1, 0x01); //ICW 4
|
||||
//Activate IRQ's
|
||||
outb(0x21, 0x00);
|
||||
outb(0xA1, 0x00);
|
||||
}
|
||||
auto IDT::setEntry(int i, void* offset, uint16_t seg, uint8_t flags) -> void {
|
||||
idt[i]=(uint16_t)((uint64_t)offset);
|
||||
idt[i]|=(unsigned __int128)(((uint64_t)offset)>>16)<<48;
|
||||
idt[i]|=((unsigned __int128)seg)<<16;
|
||||
idt[i]|=((unsigned __int128)flags)<<40;
|
||||
}
|
||||
for(int i=0;i<16;i++) {
|
||||
if(ivt[cpu->intr][i])
|
||||
new_cpu=ivt[cpu->intr][i](new_cpu);
|
||||
auto IDT::apply() -> void {
|
||||
debug << "Now trying to load the IDT.\n";
|
||||
idtptr.limit=(uint16_t)(256*8-1);
|
||||
idtptr.pointer=(unsigned __int128*)&idt;
|
||||
loadIDT((void*)&idtptr);
|
||||
}
|
||||
if(cpu->intr==48)
|
||||
new_cpu->rax=(uint64_t)(::syscall(cpu->rax, (void*)(cpu->rbx), (void*)(cpu->rsp)));
|
||||
if(cpu->intr==49) {
|
||||
startup();
|
||||
for(int i=0;i<16;i++) {
|
||||
if(ivt[0x20][i])
|
||||
new_cpu=ivt[0x20][i](new_cpu);
|
||||
}
|
||||
}
|
||||
return new_cpu;
|
||||
}
|
||||
auto IDT::request(uint8_t intr, struct cpu_state* (*handler)(struct cpu_state*)) -> bool {
|
||||
for(int i=0;i<16;i++) {
|
||||
if(ivt[intr][i])
|
||||
continue;
|
||||
ivt[intr][i]=handler;
|
||||
return true;
|
||||
auto IDT::handle(struct cpu_state* cpu) -> struct cpu_state* {
|
||||
struct cpu_state* new_cpu=cpu;
|
||||
debug << "Interrupt 0x" << Base::HEXADECIMAL << (int) cpu->intr << " was raised.\n";
|
||||
if(cpu->intr<=0x1F) {
|
||||
if(epicfail) {
|
||||
err << "While trying to output the stack another exception happened\n";
|
||||
while(1) {
|
||||
asm volatile("cli; hlt");
|
||||
}
|
||||
}
|
||||
epicfail=true;
|
||||
err << "Exception 0x" << Base::HEXADECIMAL << (int) cpu->intr << "! Kernel halted!\n";
|
||||
err << "RAX = 0x" << (int)cpu->rax << " - RBX = 0x" << (int)cpu->rbx << "\n";
|
||||
err << "RCX = 0x" << (int)cpu->rcx << " - RDX = 0x" << (int)cpu->rdx << "\n";
|
||||
err << "RSI = 0x" << (int)cpu->rsi << " - RDI = 0x" << (int)cpu->rdi << "\n";
|
||||
err << "SS:RSP = 0x" << (int)cpu->ss << ":0x" << (int)cpu->rsp << " - SS:RBP = 0x" << (int)cpu->ss << ":0x" << (int)cpu->rbp << "\n";
|
||||
err << "CS:RIP = 0x" << (int)cpu->cs << ":0x" << (int)cpu->rip << " - INTR:ERR = 0x" << (int)cpu->intr << ":0x" << (int)cpu->error << "\n";
|
||||
err << "------ END OF REGISTER DUMP ------ ------ START OF PROGRAM LOADPOINTS ------\n";
|
||||
for(int i=0;i<1024;i++) {
|
||||
if(!progs[i])
|
||||
break;
|
||||
err << "0x" << (int)((uint64_t)progs[i]) << "; ";
|
||||
}
|
||||
err << "\n";
|
||||
uint16_t counter = 1193180 / 220; //Make an annoying beep
|
||||
outb(0x43, 0xB6);
|
||||
outb(0x42, (uint8_t)counter);
|
||||
outb(0x42, (uint8_t)(counter>>8));
|
||||
//outb(0x61, inb(0x61) | 3);
|
||||
err << "A detailled traceback is being output over the serial connector.\n";
|
||||
debug << "Outputting 32 stacks...\n";
|
||||
uint64_t *rsp=(uint64_t*)cpu->rsp;
|
||||
uint64_t *rbp=(uint64_t*)cpu->rbp;
|
||||
uint64_t *rip=(uint64_t*)cpu->rip;
|
||||
for(int i=0;i<32;i++) {
|
||||
if(!(rsp||rbp||rip))
|
||||
break;
|
||||
if((int64_t)(rbp-rsp)<1)
|
||||
break;
|
||||
debug << Base::HEXADECIMAL << "Execution at 0x" << (int64_t) rip << ":\n";
|
||||
debug << "Number of local variables: 0x" << (int64_t)(rbp-rsp)-1 << "\n";
|
||||
for(uintptr_t i=0;i<(uintptr_t)(rbp-rsp)-1;i++) {
|
||||
debug << "0x"<< (int64_t)(i*8) << ": 0x" << (int64_t)rsp[i] << "\n";
|
||||
}
|
||||
rip=(uint64_t*)rbp[1];
|
||||
rsp=rbp;
|
||||
rbp=(uint64_t*)rbp[0];
|
||||
}
|
||||
while(1) {
|
||||
asm volatile("cli; hlt");
|
||||
}
|
||||
} else if(cpu->intr >= 0x20 && cpu->intr <= 0x2F) {
|
||||
if(cpu->intr >= 0x28) {
|
||||
outb(0xA0, 0x20);
|
||||
}
|
||||
outb(0x20, 0x20);
|
||||
debug << "The IRQ " << Base::DECIMAL << (int) cpu->intr-0x20 << " was handled.\n";
|
||||
if(cpu->intr==0x20) {
|
||||
debug.debug();
|
||||
}
|
||||
}
|
||||
for(int i=0;i<16;i++) {
|
||||
if(ivt[cpu->intr][i])
|
||||
new_cpu=ivt[cpu->intr][i](new_cpu);
|
||||
}
|
||||
if(cpu->intr==48)
|
||||
new_cpu->rax=(uint64_t)(::syscall(cpu->rax, (void*)(cpu->rbx), (void*)(cpu->rsp)));
|
||||
if(cpu->intr==49) {
|
||||
startup();
|
||||
for(int i=0;i<16;i++) {
|
||||
if(ivt[0x20][i])
|
||||
new_cpu=ivt[0x20][i](new_cpu);
|
||||
}
|
||||
}
|
||||
return new_cpu;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
extern "C" void* handleINT(void* cpu) {
|
||||
return (void*)MTGosHAL::idt.handle((MTGosHAL::cpu_state*)cpu);
|
||||
}
|
||||
auto IDT::request(uint8_t intr, struct cpu_state* (*handler)(struct cpu_state*)) -> bool {
|
||||
for(int i=0;i<16;i++) {
|
||||
if(ivt[intr][i])
|
||||
continue;
|
||||
ivt[intr][i]=handler;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
extern "C" void* handleINT(void* cpu) {
|
||||
return (void*)MTGosHAL::idt.handle((MTGosHAL::cpu_state*)cpu);
|
||||
}
|
||||
|
|
|
@ -11,77 +11,75 @@
|
|||
#include <pmm.hpp>
|
||||
extern "C" void intr_stub_0(void);
|
||||
void main(void ** programs, MTGosHAL::Serial debug, MTGosHAL::PMM mm, MTGosHAL::Screen out,
|
||||
MTGosHAL::Screen err, MTGosHAL::Keyboard in, MTGosHAL::Multitasking tasks, MTGosHAL::BlockDevice disk);
|
||||
MTGosHAL::Screen err, MTGosHAL::Keyboard in, MTGosHAL::Multitasking tasks, MTGosHAL::BlockDevice disk);
|
||||
void** progs;
|
||||
namespace MTGosHAL {
|
||||
Serial debug;
|
||||
GDT gdt;
|
||||
IDT idt;
|
||||
PMM mm;
|
||||
Screen out;
|
||||
Screen err;
|
||||
Keyboard in;
|
||||
Multitasking tasks;
|
||||
BlockDevice disk;
|
||||
struct multiboot_info* ebx;
|
||||
void main(long eax, struct multiboot_info* mb, uint64_t**** pt) {
|
||||
ebx=mb;
|
||||
new (&debug) Serial();
|
||||
debug << "Hello debugger! This is MTGos v00r01\nThese logs are probably very long, so please redirect the output to a file.\n";
|
||||
Serial debug;
|
||||
GDT gdt;
|
||||
IDT idt;
|
||||
PMM mm;
|
||||
Screen out;
|
||||
Screen err;
|
||||
Keyboard in;
|
||||
Multitasking tasks;
|
||||
BlockDevice disk;
|
||||
struct multiboot_info* ebx;
|
||||
void main(long eax, struct multiboot_info* mb, uint64_t**** pt) {
|
||||
ebx=mb;
|
||||
new (&debug) Serial();
|
||||
debug << "Hello debugger! This is MTGos v00r01\nThese logs are probably very long, so please redirect the output to a file.\n";
|
||||
debug << "Init Screen output\n";
|
||||
new (&out) Screen(ebx);
|
||||
new (&err) Screen(ebx);
|
||||
out << BG_color::BLACK << FG_color::WHITE << "Loading MTGos...\n";
|
||||
err << BG_color::BLACK << FG_color::RED;
|
||||
debug << "Init GDT\n";
|
||||
new (&gdt) GDT();
|
||||
gdt.setEntry(0, 0, 0, 0);
|
||||
gdt.setEntry(1, 0, 0, GDT_FLAG_PRESENT | GDT_FLAG_64_BIT | GDT_FLAG_4K_GRAN | GDT_FLAG_RING0 | GDT_FLAG_SEGMENT | GDT_FLAG_CODESEG);
|
||||
gdt.setEntry(2, 0, 0, GDT_FLAG_PRESENT | GDT_FLAG_32_BIT | GDT_FLAG_4K_GRAN | GDT_FLAG_RING0 | GDT_FLAG_SEGMENT | GDT_FLAG_DATASEG);
|
||||
gdt.setEntry(3, 0, 0, GDT_FLAG_PRESENT | GDT_FLAG_64_BIT | GDT_FLAG_4K_GRAN | GDT_FLAG_RING3 | GDT_FLAG_SEGMENT | GDT_FLAG_CODESEG);
|
||||
gdt.setEntry(4, 0, 0, GDT_FLAG_PRESENT | GDT_FLAG_32_BIT | GDT_FLAG_4K_GRAN | GDT_FLAG_RING3 | GDT_FLAG_SEGMENT | GDT_FLAG_DATASEG);
|
||||
gdt.setEntry(5, (uint64_t)tasks.tss, sizeof(tasks.tss), GDT_FLAG_RING0 | GDT_FLAG_TSS | GDT_FLAG_PRESENT);
|
||||
gdt.setEntry(6, 0, 0, GDT_FLAG_RING3 | GDT_FLAG_TSS | GDT_FLAG_PRESENT);
|
||||
gdt.apply();
|
||||
|
||||
debug << "Init Screen output\n";
|
||||
new (&out) Screen(ebx);
|
||||
new (&err) Screen(ebx);
|
||||
out << BG_color::BLACK << FG_color::WHITE << "Loading MTGos...\n";
|
||||
err << BG_color::BLACK << FG_color::RED;
|
||||
|
||||
debug << "Init GDT\n";
|
||||
new (&gdt) GDT();
|
||||
gdt.setEntry(0, 0, 0, 0);
|
||||
gdt.setEntry(1, 0, 0, GDT_FLAG_PRESENT | GDT_FLAG_64_BIT | GDT_FLAG_4K_GRAN | GDT_FLAG_RING0 | GDT_FLAG_SEGMENT | GDT_FLAG_CODESEG);
|
||||
gdt.setEntry(2, 0, 0, GDT_FLAG_PRESENT | GDT_FLAG_32_BIT | GDT_FLAG_4K_GRAN | GDT_FLAG_RING0 | GDT_FLAG_SEGMENT | GDT_FLAG_DATASEG);
|
||||
gdt.setEntry(3, 0, 0, GDT_FLAG_PRESENT | GDT_FLAG_64_BIT | GDT_FLAG_4K_GRAN | GDT_FLAG_RING3 | GDT_FLAG_SEGMENT | GDT_FLAG_CODESEG);
|
||||
gdt.setEntry(4, 0, 0, GDT_FLAG_PRESENT | GDT_FLAG_32_BIT | GDT_FLAG_4K_GRAN | GDT_FLAG_RING3 | GDT_FLAG_SEGMENT | GDT_FLAG_DATASEG);
|
||||
gdt.setEntry(5, (uint64_t)tasks.tss, sizeof(tasks.tss), GDT_FLAG_RING0 | GDT_FLAG_TSS | GDT_FLAG_PRESENT);
|
||||
gdt.setEntry(6, 0, 0, GDT_FLAG_RING3 | GDT_FLAG_TSS | GDT_FLAG_PRESENT);
|
||||
gdt.apply();
|
||||
|
||||
debug << "Init IDT\n";
|
||||
new (&idt) IDT();
|
||||
for(int i=0;i<256;i++) {
|
||||
idt.setEntry(i, (void *)((uint64_t)&intr_stub_0+i*32), SEG_KERNEL, IDT_INTERRUPT_GATE | IDT_SEG_32_BIT | IDT_RING_0 | IDT_USED);
|
||||
}
|
||||
idt.setEntry(48, (void *)((uint64_t)&intr_stub_0+768*2), SEG_KERNEL, IDT_TRAP_GATE | IDT_SEG_32_BIT | IDT_RING_3 | IDT_USED);
|
||||
idt.setEntry(8, (void *)((uint64_t)&intr_stub_0+128*2), SEG_DBL_FAULT, IDT_TASK_GATE | IDT_SEG_32_BIT | IDT_RING_0 | IDT_USED);
|
||||
idt.apply();
|
||||
asm volatile("int $49"); // Finish loading GDT
|
||||
debug << "Init IDT\n";
|
||||
new (&idt) IDT();
|
||||
for(int i=0;i<256;i++) {
|
||||
idt.setEntry(i, (void *)((uint64_t)&intr_stub_0+i*32), SEG_KERNEL, IDT_INTERRUPT_GATE | IDT_SEG_32_BIT | IDT_RING_0 | IDT_USED);
|
||||
}
|
||||
idt.setEntry(48, (void *)((uint64_t)&intr_stub_0+768*2), SEG_KERNEL, IDT_TRAP_GATE | IDT_SEG_32_BIT | IDT_RING_3 | IDT_USED);
|
||||
idt.setEntry(8, (void *)((uint64_t)&intr_stub_0+128*2), SEG_DBL_FAULT, IDT_TASK_GATE | IDT_SEG_32_BIT | IDT_RING_0 | IDT_USED);
|
||||
idt.apply();
|
||||
asm volatile("int $49"); // Finish loading GDT
|
||||
}
|
||||
auto startup() -> void {
|
||||
//asm volatile("ltr %%ax" : : "a"(5<<3));
|
||||
//asm volatile("ltr %%ax" : : "a"(5<<3));
|
||||
|
||||
out << "Init MM\n";
|
||||
new (&mm) PMM(ebx);
|
||||
out << "Init MM\n";
|
||||
new (&mm) PMM(ebx);
|
||||
|
||||
|
||||
out << "Init Keyboard\n";
|
||||
new (&in) Keyboard();
|
||||
out << "Init Keyboard\n";
|
||||
new (&in) Keyboard();
|
||||
|
||||
out << "Init Multitasking\n";
|
||||
new (&tasks) Multitasking();
|
||||
out << "Init Multitasking\n";
|
||||
new (&tasks) Multitasking();
|
||||
|
||||
out << "Init blockdev\n";
|
||||
new (&disk) BlockDevice();
|
||||
out << "Kernel initialized\n";
|
||||
multiboot_mod_list *mods = (multiboot_mod_list*) (uint64_t)(ebx->mods_addr);
|
||||
progs=(void**)mm.alloc(8192);
|
||||
for(int i=0;i<1024;i++) {
|
||||
progs[i]=nullptr;
|
||||
}
|
||||
for(uint32_t i=0;i<(ebx->mods_count<1023?ebx->mods_count:1023);i++) { //Basically until MIN(ebx->mods_count, 1023), as we only support loading up to 1023 programs directly.
|
||||
progs[i]=(void*)((uint64_t)mods[i].mod_start);
|
||||
out << "Found module!\n";
|
||||
}
|
||||
::main(progs, debug, mm, out, err, in, tasks, disk);
|
||||
out << "Init blockdev\n";
|
||||
new (&disk) BlockDevice();
|
||||
out << "Kernel initialized\n";
|
||||
multiboot_mod_list *mods = (multiboot_mod_list*) (uint64_t)(ebx->mods_addr);
|
||||
progs=(void**)mm.alloc(8192);
|
||||
for(int i=0;i<1024;i++) {
|
||||
progs[i]=nullptr;
|
||||
}
|
||||
for(uint32_t i=0;i<(ebx->mods_count<1023?ebx->mods_count:1023);i++) { //Basically until MIN(ebx->mods_count, 1023), as we only support loading up to 1023 programs directly.
|
||||
progs[i]=(void*)((uint64_t)mods[i].mod_start);
|
||||
out << "Found module!\n";
|
||||
}
|
||||
::main(progs, debug, mm, out, err, in, tasks, disk);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -90,10 +88,10 @@ typedef void (*destructor)();
|
|||
extern "C" destructor start_dtors;
|
||||
extern "C" destructor end_dtors;
|
||||
extern "C" void init(int eax, struct multiboot_info* ebx, uint64_t**** ecx) {
|
||||
MTGosHAL::main(eax, ebx,ecx);
|
||||
for(destructor* i = &start_dtors; i != &end_dtors; i++)
|
||||
(*i)();
|
||||
MTGosHAL::main(eax, ebx,ecx);
|
||||
for(destructor* i = &start_dtors; i != &end_dtors; i++)
|
||||
(*i)();
|
||||
}
|
||||
extern "C" void __cxa_pure_virtual() {
|
||||
MTGosHAL::debug << "A pure virtual function just got called.\n";
|
||||
MTGosHAL::debug << "A pure virtual function just got called.\n";
|
||||
}
|
||||
|
|
|
@ -5,124 +5,124 @@
|
|||
#include <keymap_DE.hpp>
|
||||
|
||||
namespace MTGosHAL {
|
||||
auto handleIRQ(struct cpu_state* cpu) -> struct cpu_state* {
|
||||
return in.handleIRQ1(cpu);
|
||||
}
|
||||
auto Keyboard::getChar() -> char {
|
||||
char chr=buf[0];
|
||||
for(int i=0;i<15;i++) {
|
||||
buf[i]=buf[i+1];
|
||||
}
|
||||
buf[15]='\0';
|
||||
if(len)
|
||||
len--;
|
||||
return chr;
|
||||
}
|
||||
auto Keyboard::sendCommand(uint8_t command) -> void {
|
||||
while((inb(0x64) & 0x2));
|
||||
outb(0x60, command);
|
||||
}
|
||||
auto Keyboard::handleIRQ1(struct cpu_state* cpu) -> struct cpu_state* {
|
||||
uint8_t keycode=0,scancode=inb(0x60);
|
||||
if(scancode==0xFA) {
|
||||
response=false;
|
||||
return cpu;
|
||||
} else if(response && scancode == 0xFE) {
|
||||
sendCommand(0xED);
|
||||
outb(0x60, (scrolllock) + (numlock<<1) + (capslock<<2));
|
||||
return cpu;
|
||||
}
|
||||
debug << "Keyboard interrupt received.\nGot: 0x" << Base::HEXADECIMAL << (int)scancode;
|
||||
bool break_code=false;
|
||||
static bool e0_code=false;
|
||||
static int e1_code=0;
|
||||
static uint16_t e1_prev=0;
|
||||
uint8_t tableID=0;
|
||||
if((scancode & 0x80 ) && (e1_code || (scancode != 0xE1)) && (e0_code || (scancode != 0xE0))) {
|
||||
break_code = true;
|
||||
scancode &= ~0x80;
|
||||
}
|
||||
if(e0_code) {
|
||||
if((scancode==0x2A) || (scancode = 0x36)) {
|
||||
e0_code = false;
|
||||
return cpu;
|
||||
}
|
||||
keycode=keyboardKeycodes[1][scancode];
|
||||
e0_code=false;
|
||||
} else if (e1_code == 2) {
|
||||
e1_prev |= ((uint16_t) scancode << 8);
|
||||
//TODO. translate it, although I might not even use this code
|
||||
return cpu;
|
||||
} else if (e1_code) {
|
||||
e1_prev = scancode;
|
||||
e1_code++;
|
||||
return cpu;
|
||||
} else if (scancode == 0xE0) {
|
||||
e0_code = true;
|
||||
return cpu;
|
||||
} else if (scancode == 0xE1) {
|
||||
e1_code = true;
|
||||
return cpu;
|
||||
} else {
|
||||
keycode=keyboardKeycodes[0][scancode];
|
||||
}
|
||||
//Now put it into the keystate array
|
||||
if(break_code)
|
||||
keydowns[keycode]=false;
|
||||
else
|
||||
keydowns[keycode]=true;
|
||||
//0x2A 0x36 = Shift
|
||||
if(keydowns[0x2A] || keydowns[0x36])
|
||||
tableID^=1;
|
||||
//0x1D = Ctrl
|
||||
if(keydowns[0x1D])
|
||||
tableID^=2;
|
||||
//0x38 = Alt
|
||||
if(keydowns[0x38])
|
||||
tableID^=4;
|
||||
auto handleIRQ(struct cpu_state* cpu) -> struct cpu_state* {
|
||||
return in.handleIRQ1(cpu);
|
||||
}
|
||||
auto Keyboard::getChar() -> char {
|
||||
char chr=buf[0];
|
||||
for(int i=0;i<15;i++) {
|
||||
buf[i]=buf[i+1];
|
||||
}
|
||||
buf[15]='\0';
|
||||
if(len)
|
||||
len--;
|
||||
return chr;
|
||||
}
|
||||
auto Keyboard::sendCommand(uint8_t command) -> void {
|
||||
while((inb(0x64) & 0x2));
|
||||
outb(0x60, command);
|
||||
}
|
||||
auto Keyboard::handleIRQ1(struct cpu_state* cpu) -> struct cpu_state* {
|
||||
uint8_t keycode=0,scancode=inb(0x60);
|
||||
if(scancode==0xFA) {
|
||||
response=false;
|
||||
return cpu;
|
||||
} else if(response && scancode == 0xFE) {
|
||||
sendCommand(0xED);
|
||||
outb(0x60, (scrolllock) + (numlock<<1) + (capslock<<2));
|
||||
return cpu;
|
||||
}
|
||||
debug << "Keyboard interrupt received.\nGot: 0x" << Base::HEXADECIMAL << (int)scancode;
|
||||
bool break_code=false;
|
||||
static bool e0_code=false;
|
||||
static int e1_code=0;
|
||||
static uint16_t e1_prev=0;
|
||||
uint8_t tableID=0;
|
||||
if((scancode & 0x80 ) && (e1_code || (scancode != 0xE1)) && (e0_code || (scancode != 0xE0))) {
|
||||
break_code = true;
|
||||
scancode &= ~0x80;
|
||||
}
|
||||
if(e0_code) {
|
||||
if((scancode==0x2A) || (scancode = 0x36)) {
|
||||
e0_code = false;
|
||||
return cpu;
|
||||
}
|
||||
keycode=keyboardKeycodes[1][scancode];
|
||||
e0_code=false;
|
||||
} else if (e1_code == 2) {
|
||||
e1_prev |= ((uint16_t) scancode << 8);
|
||||
//TODO. translate it, although I might not even use this code
|
||||
return cpu;
|
||||
} else if (e1_code) {
|
||||
e1_prev = scancode;
|
||||
e1_code++;
|
||||
return cpu;
|
||||
} else if (scancode == 0xE0) {
|
||||
e0_code = true;
|
||||
return cpu;
|
||||
} else if (scancode == 0xE1) {
|
||||
e1_code = true;
|
||||
return cpu;
|
||||
} else {
|
||||
keycode=keyboardKeycodes[0][scancode];
|
||||
}
|
||||
//Now put it into the keystate array
|
||||
if(break_code)
|
||||
keydowns[keycode]=false;
|
||||
else
|
||||
keydowns[keycode]=true;
|
||||
//0x2A 0x36 = Shift
|
||||
if(keydowns[0x2A] || keydowns[0x36])
|
||||
tableID^=1;
|
||||
//0x1D = Ctrl
|
||||
if(keydowns[0x1D])
|
||||
tableID^=2;
|
||||
//0x38 = Alt
|
||||
if(keydowns[0x38])
|
||||
tableID^=4;
|
||||
|
||||
//0x45 = Numlock
|
||||
if(keycode==0x45)
|
||||
numlock=!numlock;
|
||||
//0x3A = CAPS
|
||||
if(keycode==0x3A)
|
||||
capslock=!capslock;
|
||||
//0x46 = Scrolllock
|
||||
if(keycode==0x46)
|
||||
scrolllock=!scrolllock;
|
||||
//0x45 = Numlock
|
||||
if(keycode==0x45)
|
||||
numlock=!numlock;
|
||||
//0x3A = CAPS
|
||||
if(keycode==0x3A)
|
||||
capslock=!capslock;
|
||||
//0x46 = Scrolllock
|
||||
if(keycode==0x46)
|
||||
scrolllock=!scrolllock;
|
||||
|
||||
if(capslock)
|
||||
tableID^=1;
|
||||
//Correct the LEDs
|
||||
sendCommand(0xED);
|
||||
outb(0x60, (scrolllock) + (numlock<<1) + (capslock<<2));
|
||||
response=true;
|
||||
//Convert it into a char
|
||||
if(!break_code)
|
||||
out << keymap[tableID][keycode];
|
||||
debug << " -> 0x" << (int)keycode << ".\n";
|
||||
return cpu;
|
||||
}
|
||||
Keyboard::Keyboard(): numlock(true), capslock(false), scrolllock(false), response(false) {
|
||||
if(!idt.request(0x21, (struct cpu_state*(*)(struct cpu_state*))&handleIRQ)) {
|
||||
debug << "Could not get an handler for IRQ1 (Keyboard)\n";
|
||||
return;
|
||||
}
|
||||
//Clear keyboard buffer
|
||||
while(inb(0x64) & 0x1) {
|
||||
inb(0x60);
|
||||
}
|
||||
sendCommand(0xF4); //Activate keyboard
|
||||
//Check for self-test being passed
|
||||
sendCommand(0x20);
|
||||
uint8_t ccb=inb(0x60);
|
||||
if((ccb&4)) {
|
||||
ccb &= ~1;
|
||||
} else {
|
||||
debug << "Keyboard didn't pass self-test!\nDeactivating IRQ1.\n";
|
||||
ccb |= 1;
|
||||
}
|
||||
sendCommand(0x60);
|
||||
outb(0x64, ccb);
|
||||
}
|
||||
if(capslock)
|
||||
tableID^=1;
|
||||
//Correct the LEDs
|
||||
sendCommand(0xED);
|
||||
outb(0x60, (scrolllock) + (numlock<<1) + (capslock<<2));
|
||||
response=true;
|
||||
//Convert it into a char
|
||||
if(!break_code)
|
||||
out << keymap[tableID][keycode];
|
||||
debug << " -> 0x" << (int)keycode << ".\n";
|
||||
return cpu;
|
||||
}
|
||||
Keyboard::Keyboard(): numlock(true), capslock(false), scrolllock(false), response(false) {
|
||||
if(!idt.request(0x21, (struct cpu_state*(*)(struct cpu_state*))&handleIRQ)) {
|
||||
debug << "Could not get an handler for IRQ1 (Keyboard)\n";
|
||||
return;
|
||||
}
|
||||
//Clear keyboard buffer
|
||||
while(inb(0x64) & 0x1) {
|
||||
inb(0x60);
|
||||
}
|
||||
sendCommand(0xF4); //Activate keyboard
|
||||
//Check for self-test being passed
|
||||
sendCommand(0x20);
|
||||
uint8_t ccb=inb(0x60);
|
||||
if((ccb&4)) {
|
||||
ccb &= ~1;
|
||||
} else {
|
||||
debug << "Keyboard didn't pass self-test!\nDeactivating IRQ1.\n";
|
||||
ccb |= 1;
|
||||
}
|
||||
sendCommand(0x60);
|
||||
outb(0x64, ccb);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,52 +3,52 @@
|
|||
#include <serial.hpp>
|
||||
#include <textDISP.hpp>
|
||||
namespace MTGosHAL {
|
||||
auto Output::puts(const char* s) -> void {
|
||||
int i=0;
|
||||
while(s[i]!='\0')
|
||||
putChar(s[i++]);
|
||||
}
|
||||
template <>
|
||||
auto Output::operator<<<Base>(Base output) -> Output & {
|
||||
base=static_cast<int>(output);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Output::operator<<<int>(int op) -> Output & {
|
||||
uintptr_t output=op;
|
||||
const char* chars="0123456789ABCDEF";
|
||||
char buf[33];
|
||||
buf[32]='\0';
|
||||
char* ptr=buf+31;
|
||||
do {
|
||||
*(ptr--)=chars[output%base];
|
||||
output/=base;
|
||||
} while(output && (ptr!=buf));
|
||||
puts(ptr+1);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Output::operator<<<long int>(long int op) -> Output & {
|
||||
uint64_t output=op;
|
||||
const char* chars="0123456789ABCDEF";
|
||||
char buf[65];
|
||||
buf[64]='\0';
|
||||
char* ptr=buf+63;
|
||||
do {
|
||||
*(ptr--)=chars[output%base];
|
||||
output/=base;
|
||||
} while(output && (ptr!=buf));
|
||||
puts(ptr+1);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Output::operator<<<char>(char output) -> Output & {
|
||||
putChar(output);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Output::operator<<<char*>(char* output) -> Output & {
|
||||
puts(output);
|
||||
return *this;
|
||||
}
|
||||
auto Output::puts(const char* s) -> void {
|
||||
int i=0;
|
||||
while(s[i]!='\0')
|
||||
putChar(s[i++]);
|
||||
}
|
||||
template <>
|
||||
auto Output::operator<<<Base>(Base output) -> Output & {
|
||||
base=static_cast<int>(output);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Output::operator<<<int>(int op) -> Output & {
|
||||
uintptr_t output=op;
|
||||
const char* chars="0123456789ABCDEF";
|
||||
char buf[33];
|
||||
buf[32]='\0';
|
||||
char* ptr=buf+31;
|
||||
do {
|
||||
*(ptr--)=chars[output%base];
|
||||
output/=base;
|
||||
} while(output && (ptr!=buf));
|
||||
puts(ptr+1);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Output::operator<<<long int>(long int op) -> Output & {
|
||||
uint64_t output=op;
|
||||
const char* chars="0123456789ABCDEF";
|
||||
char buf[65];
|
||||
buf[64]='\0';
|
||||
char* ptr=buf+63;
|
||||
do {
|
||||
*(ptr--)=chars[output%base];
|
||||
output/=base;
|
||||
} while(output && (ptr!=buf));
|
||||
puts(ptr+1);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Output::operator<<<char>(char output) -> Output & {
|
||||
putChar(output);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Output::operator<<<char*>(char* output) -> Output & {
|
||||
puts(output);
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,78 +1,78 @@
|
|||
#include <base.hpp>
|
||||
#include <serial.hpp>
|
||||
namespace MTGosHAL {
|
||||
auto Serial::isTransmitEmpty() -> int {
|
||||
return inb(port+SERIAL_LSR)&0x20;
|
||||
}
|
||||
auto Serial::putChar(char chr) -> void {
|
||||
if(!works)
|
||||
return;
|
||||
int tries=65535;
|
||||
while(!isTransmitEmpty()) {
|
||||
waittimes++;
|
||||
tries--;
|
||||
if(!tries){
|
||||
works=false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
outb(port, chr);
|
||||
transmits++;
|
||||
}
|
||||
auto Serial::serial_received() -> int {
|
||||
return inb(port+SERIAL_LSR)&1;
|
||||
}
|
||||
auto Serial::getChar() -> char {
|
||||
//We try 500 times to get a character
|
||||
int tries=500;
|
||||
while(!serial_received()) {
|
||||
tries--;
|
||||
waittimes++;
|
||||
if(!tries) {
|
||||
return '\0';
|
||||
}
|
||||
}
|
||||
transmits++;
|
||||
char chr = inb(port);
|
||||
if(chr!='\r')
|
||||
*this << chr;
|
||||
else
|
||||
*this << '\n';
|
||||
return chr;
|
||||
}
|
||||
Serial::Serial(): works(true) {
|
||||
uint32_t baud=115200;
|
||||
port=*((uint16_t*)0x0400);
|
||||
union {
|
||||
uint8_t b[2];
|
||||
uint16_t w;
|
||||
} divisor;
|
||||
divisor.w = 115200/baud;
|
||||
//Turn off interrupts
|
||||
outb(port+SERIAL_IER, 0x00);
|
||||
//Set DLAB-bit
|
||||
outb(port+SERIAL_LCR, 0x80);
|
||||
//Set baud divisor
|
||||
outb(port, divisor.b[0]);
|
||||
outb(port+1, divisor.b[1]);
|
||||
//Set bit count, parity and reset DLAB
|
||||
outb(port+SERIAL_LCR, 3);
|
||||
//Finish init
|
||||
outb(port+SERIAL_FCR, 0xC7);
|
||||
outb(port+SERIAL_MCR, 0x0B);
|
||||
}
|
||||
auto Serial::debug() -> void {
|
||||
if(getChar()) {
|
||||
*this << "The interactive debug shell was started.\n> ";
|
||||
out << "The debug shell was started.\n";
|
||||
char buf[256];
|
||||
*this >> buf;
|
||||
out << buf << "\nDebug shell closed.\n";
|
||||
*this << "Unknown command. TODO\n";
|
||||
}
|
||||
uint64_t wt = waittimes;
|
||||
uint64_t tm = transmits;
|
||||
*this << "Transmit stats: " << (int32_t)wt << " times waited; " << (int32_t)tm << " bytes transferred.\n";
|
||||
waittimes=transmits=0;
|
||||
}
|
||||
auto Serial::isTransmitEmpty() -> int {
|
||||
return inb(port+SERIAL_LSR)&0x20;
|
||||
}
|
||||
auto Serial::putChar(char chr) -> void {
|
||||
if(!works)
|
||||
return;
|
||||
int tries=65535;
|
||||
while(!isTransmitEmpty()) {
|
||||
waittimes++;
|
||||
tries--;
|
||||
if(!tries){
|
||||
works=false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
outb(port, chr);
|
||||
transmits++;
|
||||
}
|
||||
auto Serial::serial_received() -> int {
|
||||
return inb(port+SERIAL_LSR)&1;
|
||||
}
|
||||
auto Serial::getChar() -> char {
|
||||
//We try 500 times to get a character
|
||||
int tries=500;
|
||||
while(!serial_received()) {
|
||||
tries--;
|
||||
waittimes++;
|
||||
if(!tries) {
|
||||
return '\0';
|
||||
}
|
||||
}
|
||||
transmits++;
|
||||
char chr = inb(port);
|
||||
if(chr!='\r')
|
||||
*this << chr;
|
||||
else
|
||||
*this << '\n';
|
||||
return chr;
|
||||
}
|
||||
Serial::Serial(): works(true) {
|
||||
uint32_t baud=115200;
|
||||
port=*((uint16_t*)0x0400);
|
||||
union {
|
||||
uint8_t b[2];
|
||||
uint16_t w;
|
||||
} divisor;
|
||||
divisor.w = 115200/baud;
|
||||
//Turn off interrupts
|
||||
outb(port+SERIAL_IER, 0x00);
|
||||
//Set DLAB-bit
|
||||
outb(port+SERIAL_LCR, 0x80);
|
||||
//Set baud divisor
|
||||
outb(port, divisor.b[0]);
|
||||
outb(port+1, divisor.b[1]);
|
||||
//Set bit count, parity and reset DLAB
|
||||
outb(port+SERIAL_LCR, 3);
|
||||
//Finish init
|
||||
outb(port+SERIAL_FCR, 0xC7);
|
||||
outb(port+SERIAL_MCR, 0x0B);
|
||||
}
|
||||
auto Serial::debug() -> void {
|
||||
if(getChar()) {
|
||||
*this << "The interactive debug shell was started.\n> ";
|
||||
out << "The debug shell was started.\n";
|
||||
char buf[256];
|
||||
*this >> buf;
|
||||
out << buf << "\nDebug shell closed.\n";
|
||||
*this << "Unknown command. TODO\n";
|
||||
}
|
||||
uint64_t wt = waittimes;
|
||||
uint64_t tm = transmits;
|
||||
*this << "Transmit stats: " << (int32_t)wt << " times waited; " << (int32_t)tm << " bytes transferred.\n";
|
||||
waittimes=transmits=0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,145 +7,145 @@
|
|||
#include <string.h>
|
||||
int x=0, y=0;
|
||||
namespace MTGosHAL {
|
||||
auto Screen::putChar(char c) -> void {
|
||||
switch(c) {
|
||||
case '\n':
|
||||
x=0; y++;
|
||||
break;
|
||||
case '\r':
|
||||
x=0;
|
||||
auto Screen::putChar(char c) -> void {
|
||||
switch(c) {
|
||||
case '\n':
|
||||
x=0; y++;
|
||||
break;
|
||||
case '\r':
|
||||
x=0;
|
||||
|
||||
break;
|
||||
case '\b':
|
||||
x--;
|
||||
if(x<0) x=0;
|
||||
putChar(' ');
|
||||
x--;
|
||||
if(x<0) x=0;
|
||||
break;
|
||||
case '\0':
|
||||
break;
|
||||
default:
|
||||
for(int lx=0;lx<8;lx++) {
|
||||
for(int ly=0;ly<8;ly++) {
|
||||
if(font[(int)((uint8_t)c)][ly]&(1<<lx)) {
|
||||
lfb[(x*8+lx)+(y*8+ly)*1024]=0xFFFFFF;//static_cast<uint32_t>(fg);
|
||||
} else {
|
||||
lfb[(x*8+lx)+(y*8+ly)*1024]=0x000000;//static_cast<uint32_t>(bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
x++;
|
||||
if(x==SCREEN_WIDTH) {
|
||||
x=0; y++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(y>SCREEN_HEIGHT)
|
||||
scroll();
|
||||
}
|
||||
auto Screen::clrscr() -> void {
|
||||
for(int p=0;p<1024*786;p++) {
|
||||
lfb[p]=0x000000;//static_cast<uint32_t>(bg);
|
||||
}
|
||||
x=y=0;
|
||||
}
|
||||
auto Screen::scroll() -> void {
|
||||
for(int ly=0;ly<786-8;ly++) {
|
||||
for(int lx=0;lx<1024;lx++) {
|
||||
lfb[lx+ly*1024]=lfb[lx+(ly+8)*1024];
|
||||
}
|
||||
}
|
||||
for(int ly=786-8;ly<786;ly++) {
|
||||
for(int lx=0;lx<1024;lx++) {
|
||||
lfb[lx+ly*1024]=0x000000;//static_cast<uint32_t>(bg);
|
||||
}
|
||||
}
|
||||
y--;
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<FG_color>(FG_color fg) -> Screen &{
|
||||
this->fg=fg;
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<BG_color>(BG_color bg) -> Screen &{
|
||||
this->bg=bg;
|
||||
return *this;
|
||||
}
|
||||
auto Screen::setColor(FG_color fg) -> Screen &{
|
||||
this->fg=fg;
|
||||
return *this;
|
||||
}
|
||||
auto Screen::setColor(BG_color bg) -> Screen &{
|
||||
this->bg=bg;
|
||||
return *this;
|
||||
}
|
||||
auto Screen::setColor(FG_color fg, BG_color bg) -> Screen &{
|
||||
return (*this).setColor(fg).setColor(bg);
|
||||
}
|
||||
break;
|
||||
case '\b':
|
||||
x--;
|
||||
if(x<0) x=0;
|
||||
putChar(' ');
|
||||
x--;
|
||||
if(x<0) x=0;
|
||||
break;
|
||||
case '\0':
|
||||
break;
|
||||
default:
|
||||
for(int lx=0;lx<8;lx++) {
|
||||
for(int ly=0;ly<8;ly++) {
|
||||
if(font[(int)((uint8_t)c)][ly]&(1<<lx)) {
|
||||
lfb[(x*8+lx)+(y*8+ly)*1024]=0xFFFFFF;//static_cast<uint32_t>(fg);
|
||||
} else {
|
||||
lfb[(x*8+lx)+(y*8+ly)*1024]=0x000000;//static_cast<uint32_t>(bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
x++;
|
||||
if(x==SCREEN_WIDTH) {
|
||||
x=0; y++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(y>SCREEN_HEIGHT)
|
||||
scroll();
|
||||
}
|
||||
auto Screen::clrscr() -> void {
|
||||
for(int p=0;p<1024*786;p++) {
|
||||
lfb[p]=0x000000;//static_cast<uint32_t>(bg);
|
||||
}
|
||||
x=y=0;
|
||||
}
|
||||
auto Screen::scroll() -> void {
|
||||
for(int ly=0;ly<786-8;ly++) {
|
||||
for(int lx=0;lx<1024;lx++) {
|
||||
lfb[lx+ly*1024]=lfb[lx+(ly+8)*1024];
|
||||
}
|
||||
}
|
||||
for(int ly=786-8;ly<786;ly++) {
|
||||
for(int lx=0;lx<1024;lx++) {
|
||||
lfb[lx+ly*1024]=0x000000;//static_cast<uint32_t>(bg);
|
||||
}
|
||||
}
|
||||
y--;
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<FG_color>(FG_color fg) -> Screen &{
|
||||
this->fg=fg;
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<BG_color>(BG_color bg) -> Screen &{
|
||||
this->bg=bg;
|
||||
return *this;
|
||||
}
|
||||
auto Screen::setColor(FG_color fg) -> Screen &{
|
||||
this->fg=fg;
|
||||
return *this;
|
||||
}
|
||||
auto Screen::setColor(BG_color bg) -> Screen &{
|
||||
this->bg=bg;
|
||||
return *this;
|
||||
}
|
||||
auto Screen::setColor(FG_color fg, BG_color bg) -> Screen &{
|
||||
return (*this).setColor(fg).setColor(bg);
|
||||
}
|
||||
|
||||
auto Screen::init(struct multiboot_info* mb_info) -> void {
|
||||
lfb=(uint32_t*)((uintptr_t)mb_info->framebuffer_addr);
|
||||
//clrscr();
|
||||
//Render '\001' character
|
||||
for(int tx=0;tx<16;tx++) {
|
||||
for(int ty=0;ty<16;ty++) {
|
||||
for(int x=0;x<8;x++) {
|
||||
for(int y=0;y<8;y++) {
|
||||
if(font[tx+ty*16][y]&(1<<x))
|
||||
lfb[(x+tx*8)+(y+ty*8)*1024]=0xFFFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
auto Screen::puts(const char* s) -> void {
|
||||
int i=0;
|
||||
while(s[i]!='\0')
|
||||
putChar(s[i++]);
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<Base>(Base output) -> Screen & {
|
||||
base=static_cast<int>(output);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<int>(int op) -> Screen & {
|
||||
uintptr_t output=op;
|
||||
const char* chars="0123456789ABCDEF";
|
||||
char buf[33];
|
||||
buf[32]='\0';
|
||||
char* ptr=buf+31;
|
||||
do {
|
||||
*(ptr--)=chars[output%base];
|
||||
output/=base;
|
||||
} while(output && (ptr!=buf));
|
||||
puts(ptr+1);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<long int>(long int op) -> Screen & {
|
||||
uint64_t output=op;
|
||||
const char* chars="0123456789ABCDEF";
|
||||
char buf[65];
|
||||
buf[64]='\0';
|
||||
char* ptr=buf+63;
|
||||
do {
|
||||
*(ptr--)=chars[output%base];
|
||||
output/=base;
|
||||
} while(output && (ptr!=buf));
|
||||
puts(ptr+1);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<char>(char output) -> Screen & {
|
||||
putChar(output);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<char*>(char* output) -> Screen & {
|
||||
puts(output);
|
||||
return *this;
|
||||
}
|
||||
auto Screen::init(struct multiboot_info* mb_info) -> void {
|
||||
lfb=(uint32_t*)((uintptr_t)mb_info->framebuffer_addr);
|
||||
//clrscr();
|
||||
//Render '\001' character
|
||||
for(int tx=0;tx<16;tx++) {
|
||||
for(int ty=0;ty<16;ty++) {
|
||||
for(int x=0;x<8;x++) {
|
||||
for(int y=0;y<8;y++) {
|
||||
if(font[tx+ty*16][y]&(1<<x))
|
||||
lfb[(x+tx*8)+(y+ty*8)*1024]=0xFFFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
auto Screen::puts(const char* s) -> void {
|
||||
int i=0;
|
||||
while(s[i]!='\0')
|
||||
putChar(s[i++]);
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<Base>(Base output) -> Screen & {
|
||||
base=static_cast<int>(output);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<int>(int op) -> Screen & {
|
||||
uintptr_t output=op;
|
||||
const char* chars="0123456789ABCDEF";
|
||||
char buf[33];
|
||||
buf[32]='\0';
|
||||
char* ptr=buf+31;
|
||||
do {
|
||||
*(ptr--)=chars[output%base];
|
||||
output/=base;
|
||||
} while(output && (ptr!=buf));
|
||||
puts(ptr+1);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<long int>(long int op) -> Screen & {
|
||||
uint64_t output=op;
|
||||
const char* chars="0123456789ABCDEF";
|
||||
char buf[65];
|
||||
buf[64]='\0';
|
||||
char* ptr=buf+63;
|
||||
do {
|
||||
*(ptr--)=chars[output%base];
|
||||
output/=base;
|
||||
} while(output && (ptr!=buf));
|
||||
puts(ptr+1);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<char>(char output) -> Screen & {
|
||||
putChar(output);
|
||||
return *this;
|
||||
}
|
||||
template <>
|
||||
auto Screen::operator<<<char*>(char* output) -> Screen & {
|
||||
puts(output);
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,70 +7,70 @@ extern "C" const int kernel_end; //those are voids actually
|
|||
#define SHIFT(a) ((a)<<20)
|
||||
#define FLAGS 0x7ffff
|
||||
void *operator new(size_t size) {
|
||||
return MTGosHAL::mm.alloc(size);
|
||||
return MTGosHAL::mm.alloc(size);
|
||||
}
|
||||
void *operator new[](size_t size) {
|
||||
return MTGosHAL::mm.alloc(size);
|
||||
return MTGosHAL::mm.alloc(size);
|
||||
}
|
||||
void operator delete(void* p) {
|
||||
MTGosHAL::mm.free(p);
|
||||
MTGosHAL::mm.free(p);
|
||||
}
|
||||
void operator delete[](void* p) {
|
||||
MTGosHAL::mm.free(p);
|
||||
MTGosHAL::mm.free(p);
|
||||
}
|
||||
void operator delete(void* p, size_t size) {
|
||||
MTGosHAL::mm.free(p);
|
||||
MTGosHAL::mm.free(p);
|
||||
}
|
||||
void operator delete[](void* p, size_t size) {
|
||||
MTGosHAL::mm.free(p);
|
||||
MTGosHAL::mm.free(p);
|
||||
}
|
||||
namespace MTGosHAL {
|
||||
auto PMM::alloc(size_t length) -> void * {
|
||||
auto PMM::alloc(size_t length) -> void * {
|
||||
if(!head) {
|
||||
//Alloc space for head
|
||||
if(length+sizeof(malloc_t)<=PAGESIZE) { //Small optimization. The routine for allocating more than one continuous page is terribly slow.
|
||||
void *tmp;
|
||||
*this >> tmp;
|
||||
head=(malloc_t*)tmp;
|
||||
} else
|
||||
head=(malloc_t*)(*this)(UNSHIFT((length+sizeof(malloc_t)))+1);
|
||||
if(!head) //The alloc() didn't work! We're out of RAM!
|
||||
return nullptr;
|
||||
head->len=length;
|
||||
head->next=head->last=nullptr;
|
||||
malloc_t* tmp=head;
|
||||
tmp++;
|
||||
return (void*)tmp;
|
||||
//Alloc space for head
|
||||
if(length+sizeof(malloc_t)<=PAGESIZE) { //Small optimization. The routine for allocating more than one continuous page is terribly slow.
|
||||
void *tmp;
|
||||
*this >> tmp;
|
||||
head=(malloc_t*)tmp;
|
||||
} else
|
||||
head=(malloc_t*)(*this)(UNSHIFT((length+sizeof(malloc_t)))+1);
|
||||
if(!head) //The alloc() didn't work! We're out of RAM!
|
||||
return nullptr;
|
||||
head->len=length;
|
||||
head->next=head->last=nullptr;
|
||||
malloc_t* tmp=head;
|
||||
tmp++;
|
||||
return (void*)tmp;
|
||||
}
|
||||
malloc_t* curr=head;
|
||||
malloc_t* last=nullptr;
|
||||
do {
|
||||
uintptr_t loc=(uintptr_t)curr+sizeof(malloc_t)+curr->len;
|
||||
if((loc+length+sizeof(malloc_t))<((loc&(~FLAGS))+PAGESIZE) &&
|
||||
((!curr->next) || (loc+length+sizeof(malloc_t))<((uintptr_t)(curr->next)))) {
|
||||
malloc_t *allocd=(malloc_t *)loc;
|
||||
allocd->len=length;
|
||||
allocd->last=curr;
|
||||
allocd->next=curr->next; //Set double linked list
|
||||
curr->next=allocd;
|
||||
if(allocd->next)
|
||||
allocd->next->last=allocd;
|
||||
malloc_t *tmp=allocd;
|
||||
tmp++;
|
||||
return (void*)tmp;
|
||||
}
|
||||
last=curr;
|
||||
curr=curr->next;
|
||||
uintptr_t loc=(uintptr_t)curr+sizeof(malloc_t)+curr->len;
|
||||
if((loc+length+sizeof(malloc_t))<((loc&(~FLAGS))+PAGESIZE) &&
|
||||
((!curr->next) || (loc+length+sizeof(malloc_t))<((uintptr_t)(curr->next)))) {
|
||||
malloc_t *allocd=(malloc_t *)loc;
|
||||
allocd->len=length;
|
||||
allocd->last=curr;
|
||||
allocd->next=curr->next; //Set double linked list
|
||||
curr->next=allocd;
|
||||
if(allocd->next)
|
||||
allocd->next->last=allocd;
|
||||
malloc_t *tmp=allocd;
|
||||
tmp++;
|
||||
return (void*)tmp;
|
||||
}
|
||||
last=curr;
|
||||
curr=curr->next;
|
||||
} while(curr);
|
||||
malloc_t *allocd=nullptr;
|
||||
if(length+sizeof(malloc_t)<=PAGESIZE) { //Small optimization. The routine for allocating more than one continuous page is terribly slow.
|
||||
void *tmp;
|
||||
*this >> tmp;
|
||||
allocd=(malloc_t*)tmp;
|
||||
void *tmp;
|
||||
*this >> tmp;
|
||||
allocd=(malloc_t*)tmp;
|
||||
} else
|
||||
allocd=(malloc_t*)(*this)(UNSHIFT(length+sizeof(malloc_t))+1);
|
||||
allocd=(malloc_t*)(*this)(UNSHIFT(length+sizeof(malloc_t))+1);
|
||||
if(!allocd) //The alloc() didn't work! We're out of RAM!
|
||||
return nullptr;
|
||||
return nullptr;
|
||||
last->next=allocd;
|
||||
allocd->len=length;
|
||||
allocd->last=last;
|
||||
|
@ -81,46 +81,46 @@ namespace MTGosHAL {
|
|||
}
|
||||
auto PMM::free(void* ptr) -> bool {
|
||||
if(!ptr)
|
||||
return false;
|
||||
return false;
|
||||
malloc_t* curr=head;
|
||||
malloc_t* chk=(malloc_t*)ptr;
|
||||
chk--;
|
||||
do {
|
||||
if(curr==chk) {
|
||||
uintptr_t start=((uintptr_t)chk)&(~FLAGS);
|
||||
uintptr_t end=start+PAGESIZE;
|
||||
if((((uintptr_t)(curr->last)<start)||((uintptr_t)(curr->last)>=end))&&(((uintptr_t)(curr->next)>=end)||((uintptr_t)(curr->next)<start))) {
|
||||
*this << (void*)start;
|
||||
if(curr==chk) {
|
||||
uintptr_t start=((uintptr_t)chk)&(~FLAGS);
|
||||
uintptr_t end=start+PAGESIZE;
|
||||
if((((uintptr_t)(curr->last)<start)||((uintptr_t)(curr->last)>=end))&&(((uintptr_t)(curr->next)>=end)||((uintptr_t)(curr->next)<start))) {
|
||||
*this << (void*)start;
|
||||
}
|
||||
if(curr->last)
|
||||
curr->last->next=curr->next;
|
||||
else {
|
||||
head=curr->next;
|
||||
}
|
||||
if(curr->next)
|
||||
curr->next->last=curr->last;
|
||||
return true;
|
||||
}
|
||||
if(curr->last)
|
||||
curr->last->next=curr->next;
|
||||
else {
|
||||
head=curr->next;
|
||||
}
|
||||
if(curr->next)
|
||||
curr->next->last=curr->last;
|
||||
return true;
|
||||
}
|
||||
curr=curr->next;
|
||||
curr=curr->next;
|
||||
} while(curr);
|
||||
return false;
|
||||
}
|
||||
PMM::PMM(): head(nullptr), pmm2() {}
|
||||
auto PMM::init(struct multiboot_info* mb_info) -> void {
|
||||
pmm2.init(mb_info);
|
||||
pmm2.init(mb_info);
|
||||
}
|
||||
auto PMM::markUsed(const void * addr, uint64_t length) -> bool {
|
||||
return pmm2.markUsed(addr, length);
|
||||
return pmm2.markUsed(addr, length);
|
||||
}
|
||||
auto PMM::operator >> (void * &addr) -> PMM & {
|
||||
pmm2>>addr;
|
||||
return *this;
|
||||
pmm2>>addr;
|
||||
return *this;
|
||||
} //alloc
|
||||
auto PMM::operator << (const void * addr) -> PMM & {
|
||||
pmm2<<addr;
|
||||
return *this;
|
||||
pmm2<<addr;
|
||||
return *this;
|
||||
} //free
|
||||
auto PMM::operator()(int pages) -> void*{
|
||||
return pmm2(pages);
|
||||
return pmm2(pages);
|
||||
} //alloc_multipage
|
||||
}
|
||||
|
|
|
@ -16,70 +16,70 @@ namespace MTGosHAL {
|
|||
PMM2::PMM2(): pmm3() {
|
||||
}
|
||||
auto PMM2::markUsed(const void * addr, uint32_t length) -> bool {
|
||||
if(length<0x200000)
|
||||
length=0x200000;
|
||||
uintptr_t add=(uintptr_t)addr;
|
||||
uint64_t pagetid = SPLIT1_UNSHIFT(add);
|
||||
if(length<0x200000)
|
||||
length=0x200000;
|
||||
uintptr_t add=(uintptr_t)addr;
|
||||
uint64_t pagetid = SPLIT1_UNSHIFT(add);
|
||||
|
||||
//Check if used
|
||||
for(uintptr_t curr_addr=add+length;curr_addr>add;curr_addr-=0x200000) {
|
||||
if(pageTable[SPLIT1_UNSHIFT(curr_addr)])
|
||||
return false;
|
||||
}
|
||||
//Mark as used
|
||||
uint64_t counter=1;
|
||||
for(uintptr_t curr_addr=add+length;curr_addr>add;curr_addr-=0x200000) {
|
||||
pageTable[SPLIT1_UNSHIFT(curr_addr)]=counter++;
|
||||
pmm3.markUsed((void*)curr_addr);
|
||||
}
|
||||
return true;
|
||||
//Check if used
|
||||
for(uintptr_t curr_addr=add+length;curr_addr>add;curr_addr-=0x200000) {
|
||||
if(pageTable[SPLIT1_UNSHIFT(curr_addr)])
|
||||
return false;
|
||||
}
|
||||
//Mark as used
|
||||
uint64_t counter=1;
|
||||
for(uintptr_t curr_addr=add+length;curr_addr>add;curr_addr-=0x200000) {
|
||||
pageTable[SPLIT1_UNSHIFT(curr_addr)]=counter++;
|
||||
pmm3.markUsed((void*)curr_addr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
auto PMM2::operator >> (void * &addr) -> PMM2 & {
|
||||
pmm3 >> addr;
|
||||
markUsed(addr,0x200000);
|
||||
return *this;
|
||||
pmm3 >> addr;
|
||||
markUsed(addr,0x200000);
|
||||
return *this;
|
||||
}
|
||||
auto PMM2::operator << (const void *addr) -> PMM2 & {
|
||||
uint64_t add=(uint64_t)addr;
|
||||
for(uint64_t i=0;i<pageTable[SPLIT1_UNSHIFT(add)];i++) {
|
||||
pageTable[SPLIT1_UNSHIFT(add+i*0x200000)]=0;
|
||||
pmm3 << (void*)(add+i*0x200000);
|
||||
}
|
||||
return *this;
|
||||
uint64_t add=(uint64_t)addr;
|
||||
for(uint64_t i=0;i<pageTable[SPLIT1_UNSHIFT(add)];i++) {
|
||||
pageTable[SPLIT1_UNSHIFT(add+i*0x200000)]=0;
|
||||
pmm3 << (void*)(add+i*0x200000);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
auto PMM2::operator()(int pages) -> void* {
|
||||
//I want to get this working so:
|
||||
//TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
|
||||
// NEVER USE A BRUTE-FORCE ALGO TO ALLOC PAGES!
|
||||
//TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
|
||||
for(uint64_t i=0;i<(uint64_t)(-(pages*0x200000));i+=0x200000) {
|
||||
if(markUsed((void*)i,pages*0x200000))
|
||||
return (void*)i;
|
||||
}
|
||||
return nullptr;
|
||||
//I want to get this working so:
|
||||
//TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
|
||||
// NEVER USE A BRUTE-FORCE ALGO TO ALLOC PAGES!
|
||||
//TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
|
||||
for(uint64_t i=0;i<(uint64_t)(-(pages*0x200000));i+=0x200000) {
|
||||
if(markUsed((void*)i,pages*0x200000))
|
||||
return (void*)i;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
auto PMM2::init(struct multiboot_info* mb_info) -> void {
|
||||
pmm3.init(mb_info);
|
||||
void *temp;
|
||||
pmm3 >> temp;
|
||||
pageTable=(uint64_t*)temp;
|
||||
for(int i=0;i<0x80000;i++)
|
||||
pageTable[i]=0;
|
||||
markUsed(pageTable,0x200000);
|
||||
markUsed((void*)nullptr,0x200000);
|
||||
struct multiboot_mmap_entry* mmap = (struct multiboot_mmap_entry*) (uintptr_t)(mb_info->mmap_addr);
|
||||
struct multiboot_mmap_entry* mmap_end = (struct multiboot_mmap_entry*) ((uintptr_t) mb_info->mmap_addr + mb_info->mmap_length);
|
||||
while(mmap < mmap_end) {
|
||||
if(mmap->type != 1) {
|
||||
markUsed((void*)mmap->addr,mmap->len);
|
||||
pmm3.init(mb_info);
|
||||
void *temp;
|
||||
pmm3 >> temp;
|
||||
pageTable=(uint64_t*)temp;
|
||||
for(int i=0;i<0x80000;i++)
|
||||
pageTable[i]=0;
|
||||
markUsed(pageTable,0x200000);
|
||||
markUsed((void*)nullptr,0x200000);
|
||||
struct multiboot_mmap_entry* mmap = (struct multiboot_mmap_entry*) (uintptr_t)(mb_info->mmap_addr);
|
||||
struct multiboot_mmap_entry* mmap_end = (struct multiboot_mmap_entry*) ((uintptr_t) mb_info->mmap_addr + mb_info->mmap_length);
|
||||
while(mmap < mmap_end) {
|
||||
if(mmap->type != 1) {
|
||||
markUsed((void*)mmap->addr,mmap->len);
|
||||
}
|
||||
mmap++;
|
||||
}
|
||||
markUsed(&kernel_start,((uintptr_t)&kernel_end)-((uintptr_t)&kernel_start)); //Protect kernel)
|
||||
multiboot_mod_list *mods = (multiboot_mod_list*) (uintptr_t)(mb_info->mods_addr);
|
||||
for(uint32_t i=0;i<mb_info->mods_count;i++) {
|
||||
markUsed((void*)((uintptr_t)(&mods[i])&(~0xFFF)),4096); //Mark all of the module table as used
|
||||
markUsed((void*)(uintptr_t)(mods[i].mod_start),mods[i].mod_end-mods[i].mod_start);
|
||||
}
|
||||
mmap++;
|
||||
}
|
||||
markUsed(&kernel_start,((uintptr_t)&kernel_end)-((uintptr_t)&kernel_start)); //Protect kernel)
|
||||
multiboot_mod_list *mods = (multiboot_mod_list*) (uintptr_t)(mb_info->mods_addr);
|
||||
for(uint32_t i=0;i<mb_info->mods_count;i++) {
|
||||
markUsed((void*)((uintptr_t)(&mods[i])&(~0xFFF)),4096); //Mark all of the module table as used
|
||||
markUsed((void*)(uintptr_t)(mods[i].mod_start),mods[i].mod_end-mods[i].mod_start);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,65 +7,65 @@ extern "C" const int kernel_end; //those are voids actually
|
|||
namespace MTGosHAL {
|
||||
PMM3::PMM3() {}
|
||||
auto PMM3::init(struct multiboot_info * mb_info) -> void {
|
||||
for(int i=0;i<0x8000;i++)
|
||||
bitmap[i]=0;
|
||||
struct multiboot_mmap_entry* mmap = (struct multiboot_mmap_entry*) (uintptr_t)(mb_info->mmap_addr);
|
||||
struct multiboot_mmap_entry* mmap_end = (struct multiboot_mmap_entry*) ((uintptr_t) mb_info->mmap_addr + mb_info->mmap_length);
|
||||
while (mmap < mmap_end) {
|
||||
if (mmap->type == 1) {
|
||||
// Memory is free
|
||||
uintptr_t addr = mmap->addr;
|
||||
uintptr_t end_addr = addr + mmap->len;
|
||||
while (addr < end_addr) {
|
||||
*this << (void*) addr;
|
||||
addr += 0x200000;
|
||||
}
|
||||
}
|
||||
mmap++;
|
||||
}
|
||||
uintptr_t addr = (uintptr_t) &kernel_start;
|
||||
while(addr < (uintptr_t) &kernel_end) {
|
||||
markUsed((void*)addr);
|
||||
addr+=0x200000;
|
||||
}
|
||||
markUsed((void*)0);
|
||||
multiboot_mod_list *mods = (multiboot_mod_list*) (uintptr_t)(mb_info->mods_addr);
|
||||
for(uint32_t i=0;i<mb_info->mods_count;i++) {
|
||||
markUsed((void*)((uint64_t)(&mods[i])&(~0x1FFFFF))); //Mark all of the module table as used
|
||||
for(uint64_t start=(uint64_t)(mods[i].mod_start)&(~0x1FFFFF);start<(uint32_t)(mods[i].mod_end);start+=0x200000) {
|
||||
markUsed((void*)start); //Protect all multiboot modules
|
||||
}
|
||||
}
|
||||
for(int i=0;i<0x8000;i++)
|
||||
bitmap[i]=0;
|
||||
struct multiboot_mmap_entry* mmap = (struct multiboot_mmap_entry*) (uintptr_t)(mb_info->mmap_addr);
|
||||
struct multiboot_mmap_entry* mmap_end = (struct multiboot_mmap_entry*) ((uintptr_t) mb_info->mmap_addr + mb_info->mmap_length);
|
||||
while (mmap < mmap_end) {
|
||||
if (mmap->type == 1) {
|
||||
// Memory is free
|
||||
uintptr_t addr = mmap->addr;
|
||||
uintptr_t end_addr = addr + mmap->len;
|
||||
while (addr < end_addr) {
|
||||
*this << (void*) addr;
|
||||
addr += 0x200000;
|
||||
}
|
||||
}
|
||||
mmap++;
|
||||
}
|
||||
uintptr_t addr = (uintptr_t) &kernel_start;
|
||||
while(addr < (uintptr_t) &kernel_end) {
|
||||
markUsed((void*)addr);
|
||||
addr+=0x200000;
|
||||
}
|
||||
markUsed((void*)0);
|
||||
multiboot_mod_list *mods = (multiboot_mod_list*) (uintptr_t)(mb_info->mods_addr);
|
||||
for(uint32_t i=0;i<mb_info->mods_count;i++) {
|
||||
markUsed((void*)((uint64_t)(&mods[i])&(~0x1FFFFF))); //Mark all of the module table as used
|
||||
for(uint64_t start=(uint64_t)(mods[i].mod_start)&(~0x1FFFFF);start<(uint32_t)(mods[i].mod_end);start+=0x200000) {
|
||||
markUsed((void*)start); //Protect all multiboot modules
|
||||
}
|
||||
}
|
||||
}
|
||||
auto PMM3::markUsed(const void * addr) -> void {
|
||||
uintptr_t address=(uintptr_t)addr;
|
||||
address>>=21;
|
||||
int index=address>>5;
|
||||
int bit=1<<(address&0x1F);
|
||||
bitmap[index]&=~bit;
|
||||
uintptr_t address=(uintptr_t)addr;
|
||||
address>>=21;
|
||||
int index=address>>5;
|
||||
int bit=1<<(address&0x1F);
|
||||
bitmap[index]&=~bit;
|
||||
}
|
||||
auto PMM3::operator >> (void * &addr) -> PMM3 & {
|
||||
for(uintptr_t i=0;i<0x8000;i++) {
|
||||
if(!bitmap[i])
|
||||
continue;
|
||||
for(uintptr_t j=0;j<32;j++) {
|
||||
if(bitmap[i]&(1<<j)) {
|
||||
//We found a free page!
|
||||
bitmap[i]&=~(1<<j);
|
||||
addr=(void*)(((i<<5)+j)<<21);
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
}
|
||||
addr=nullptr;
|
||||
return *this;
|
||||
for(uintptr_t i=0;i<0x8000;i++) {
|
||||
if(!bitmap[i])
|
||||
continue;
|
||||
for(uintptr_t j=0;j<32;j++) {
|
||||
if(bitmap[i]&(1<<j)) {
|
||||
//We found a free page!
|
||||
bitmap[i]&=~(1<<j);
|
||||
addr=(void*)(((i<<5)+j)<<21);
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
}
|
||||
addr=nullptr;
|
||||
return *this;
|
||||
}
|
||||
auto PMM3::operator << (const void * addr) -> PMM3 & {
|
||||
uintptr_t address=(uintptr_t)addr;
|
||||
address>>=21;
|
||||
int index=address>>5;
|
||||
int bit=1<<(address&0x1F);
|
||||
bitmap[index]|=bit;
|
||||
return *this;
|
||||
uintptr_t address=(uintptr_t)addr;
|
||||
address>>=21;
|
||||
int index=address>>5;
|
||||
int bit=1<<(address&0x1F);
|
||||
bitmap[index]|=bit;
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,23 +2,22 @@
|
|||
#include <textDISP.hpp>
|
||||
#include <Multitasking.hpp>
|
||||
namespace MTGosHAL {
|
||||
Task::Task(struct cpu_state* cpu): cpu_state(cpu), next(nullptr) {};
|
||||
//This is run every time this task is chosen by the scheduler
|
||||
auto Task::unpause() -> struct cpu_state* {
|
||||
|
||||
return cpu_state;
|
||||
}
|
||||
//This is run every time the timer ticks and a task is running
|
||||
auto Task::pause(struct cpu_state* cpu) -> Task * {
|
||||
cpu_state=cpu;
|
||||
return next;
|
||||
}
|
||||
auto Task::addTask(Task* task) -> void {
|
||||
if(next)
|
||||
return next->addTask(task);
|
||||
next=task;
|
||||
}
|
||||
auto Task::hasNext() -> bool {
|
||||
return next!=nullptr;
|
||||
}
|
||||
Task::Task(struct cpu_state* cpu): cpu_state(cpu), next(nullptr) {};
|
||||
//This is run every time this task is chosen by the scheduler
|
||||
auto Task::unpause() -> struct cpu_state* {
|
||||
return cpu_state;
|
||||
}
|
||||
//This is run every time the timer ticks and a task is running
|
||||
auto Task::pause(struct cpu_state* cpu) -> Task * {
|
||||
cpu_state=cpu;
|
||||
return next;
|
||||
}
|
||||
auto Task::addTask(Task* task) -> void {
|
||||
if(next)
|
||||
return next->addTask(task);
|
||||
next=task;
|
||||
}
|
||||
auto Task::hasNext() -> bool {
|
||||
return next!=nullptr;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,32 +4,32 @@
|
|||
#include <output.hpp>
|
||||
using namespace MTGosHAL;
|
||||
auto load(Elf32_Ehdr* file) -> void* {
|
||||
if((file->e_ident[0]!=ELFMAG0)||
|
||||
(file->e_ident[1]!=ELFMAG1)||
|
||||
(file->e_ident[2]!=ELFMAG2)||
|
||||
(file->e_ident[3]!=ELFMAG3) ) {
|
||||
return nullptr;
|
||||
debug << "File is not a valid ELF file!\n";
|
||||
}
|
||||
Elf32_Phdr *phdr = (Elf32_Phdr*)((uintptr_t)(file->e_phoff)+(uintptr_t)file);
|
||||
debug << "entry=";
|
||||
debug << Base::HEXADECIMAL;
|
||||
debug << (int)file->e_entry;
|
||||
for(int i=0;i<file->e_phnum;i++) {
|
||||
uint32_t start=phdr[i].p_vaddr;
|
||||
debug << "start=";
|
||||
debug << Base::HEXADECIMAL;
|
||||
debug << (int)start;
|
||||
uint32_t end=start+phdr[i].p_memsz;
|
||||
debug << "end=";
|
||||
debug << Base::HEXADECIMAL;
|
||||
debug << (int)end;
|
||||
if((start <= file->e_entry) && (file->e_entry < end)) {
|
||||
debug << "start=";
|
||||
debug << Base::HEXADECIMAL;
|
||||
debug << (int)(file->e_entry-start+phdr[i].p_offset+(uintptr_t)file);
|
||||
return (void*) (file->e_entry-start+phdr[i].p_offset+(uintptr_t)file); //Calculate _start address
|
||||
if((file->e_ident[0]!=ELFMAG0)||
|
||||
(file->e_ident[1]!=ELFMAG1)||
|
||||
(file->e_ident[2]!=ELFMAG2)||
|
||||
(file->e_ident[3]!=ELFMAG3) ) {
|
||||
return nullptr;
|
||||
debug << "File is not a valid ELF file!\n";
|
||||
}
|
||||
Elf32_Phdr *phdr = (Elf32_Phdr*)((uintptr_t)(file->e_phoff)+(uintptr_t)file);
|
||||
debug << "entry=";
|
||||
debug << Base::HEXADECIMAL;
|
||||
debug << (int)file->e_entry;
|
||||
for(int i=0;i<file->e_phnum;i++) {
|
||||
uint32_t start=phdr[i].p_vaddr;
|
||||
debug << "start=";
|
||||
debug << Base::HEXADECIMAL;
|
||||
debug << (int)start;
|
||||
uint32_t end=start+phdr[i].p_memsz;
|
||||
debug << "end=";
|
||||
debug << Base::HEXADECIMAL;
|
||||
debug << (int)end;
|
||||
if((start <= file->e_entry) && (file->e_entry < end)) {
|
||||
debug << "start=";
|
||||
debug << Base::HEXADECIMAL;
|
||||
debug << (int)(file->e_entry-start+phdr[i].p_offset+(uintptr_t)file);
|
||||
return (void*) (file->e_entry-start+phdr[i].p_offset+(uintptr_t)file); //Calculate _start address
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -13,33 +13,33 @@ void operator delete (void *, void *) { }
|
|||
void operator delete[] (void *, void *) { }
|
||||
using namespace MTGosHAL;
|
||||
void pid_null() {
|
||||
for(;;);
|
||||
for(;;);
|
||||
}
|
||||
void task_a() {
|
||||
while(true)
|
||||
out << "a";
|
||||
while(true)
|
||||
out << "a";
|
||||
}
|
||||
void task_b() {
|
||||
while(true)
|
||||
out << "b";
|
||||
while(true)
|
||||
out << "b";
|
||||
}
|
||||
void task_c() {
|
||||
while(true)
|
||||
out << "c";
|
||||
while(true)
|
||||
out << "c";
|
||||
}
|
||||
void task_d() {
|
||||
while(true)
|
||||
out << "d";
|
||||
while(true)
|
||||
out << "d";
|
||||
}
|
||||
void main(void ** files, MTGosHAL::Serial &debug, MTGosHAL::PMM &mm, MTGosHAL::Screen &out,
|
||||
MTGosHAL::Screen &err, MTGosHAL::Keyboard &in, MTGosHAL::Multitasking &tasks, MTGosHAL::BlockDevice &disk) {
|
||||
out << "Initializing Kernel!\n";
|
||||
Elf32_Ehdr** programs=(Elf32_Ehdr**)files;
|
||||
tasks.initTask(&pid_null);
|
||||
for(int i=0;programs[i];i++) {
|
||||
void(*start)()=(void(*)())load(programs[i]);
|
||||
if(!start)
|
||||
continue;
|
||||
tasks.initTask(start);
|
||||
}
|
||||
MTGosHAL::Screen &err, MTGosHAL::Keyboard &in, MTGosHAL::Multitasking &tasks, MTGosHAL::BlockDevice &disk) {
|
||||
out << "Initializing Kernel!\n";
|
||||
Elf32_Ehdr** programs=(Elf32_Ehdr**)files;
|
||||
tasks.initTask(&pid_null);
|
||||
for(int i=0;programs[i];i++) {
|
||||
void(*start)()=(void(*)())load(programs[i]);
|
||||
if(!start)
|
||||
continue;
|
||||
tasks.initTask(start);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,39 +3,39 @@
|
|||
#pragma GCC push_options
|
||||
#pragma GCC optimize ("O0")
|
||||
void memmove(void* dst, void* src, uint32_t size) {
|
||||
uint8_t* from=(uint8_t*)src;
|
||||
uint8_t* to=(uint8_t*)dst;
|
||||
if((src<dst)&&((src+size)>dst)) {
|
||||
for(int i=size-1;i>=0;i--)
|
||||
to[i]=from[i]; //This would get optimized by gcc to memmove(dst, src, size); if optimizations are enabled.
|
||||
} else if(src != dst) {
|
||||
for(int i=0;i<size;i++)
|
||||
to[i]=from[i]; //This would get optimized by gcc to memmove(dst, src, size); if optimizations are enabled.
|
||||
}
|
||||
uint8_t* from=(uint8_t*)src;
|
||||
uint8_t* to=(uint8_t*)dst;
|
||||
if((src<dst)&&((src+size)>dst)) {
|
||||
for(int i=size-1;i>=0;i--)
|
||||
to[i]=from[i]; //This would get optimized by gcc to memmove(dst, src, size); if optimizations are enabled.
|
||||
} else if(src != dst) {
|
||||
for(int i=0;i<size;i++)
|
||||
to[i]=from[i]; //This would get optimized by gcc to memmove(dst, src, size); if optimizations are enabled.
|
||||
}
|
||||
}
|
||||
void memcpy(void* dest, void* src, uint32_t size) {
|
||||
memmove(dest, src, size);
|
||||
memmove(dest, src, size);
|
||||
}
|
||||
uint32_t strlen(const char* str) {
|
||||
uint32_t i=0;
|
||||
char* str2=(char*)((uintptr_t)str);
|
||||
while(*str2) {
|
||||
i++;
|
||||
str2++;
|
||||
}
|
||||
return i;
|
||||
uint32_t i=0;
|
||||
char* str2=(char*)((uintptr_t)str);
|
||||
while(*str2) {
|
||||
i++;
|
||||
str2++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
int strcmp(const char* str1, const char* str2) {
|
||||
uint32_t len1=strlen(str1);
|
||||
uint32_t len2=strlen(str2);
|
||||
if(len1>len2)
|
||||
return 1;
|
||||
else if (len1<len2)
|
||||
return -1;
|
||||
for(int i=0;i<len1;i++) {
|
||||
if(str1[i]!=str2[i])
|
||||
return str1[i]-str2[i];
|
||||
}
|
||||
return 0;
|
||||
uint32_t len1=strlen(str1);
|
||||
uint32_t len2=strlen(str2);
|
||||
if(len1>len2)
|
||||
return 1;
|
||||
else if (len1<len2)
|
||||
return -1;
|
||||
for(int i=0;i<len1;i++) {
|
||||
if(str1[i]!=str2[i])
|
||||
return str1[i]-str2[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#pragma GCC pop_options
|
||||
|
|
|
@ -2,70 +2,70 @@
|
|||
#include <syscall.hpp>
|
||||
#include <base.hpp>
|
||||
#include <textDISP.hpp>
|
||||
#include <string.hpp>
|
||||
ScreenOut::ScreenOut(bool err): err(err) {
|
||||
|
||||
}
|
||||
auto ScreenOut::operator<<(char *text) -> ScreenOut & {
|
||||
if(!text)
|
||||
if(!text)
|
||||
return *this;
|
||||
if(err)
|
||||
MTGosHAL::err << String(text);
|
||||
else
|
||||
MTGosHAL::out << String(text);
|
||||
return *this;
|
||||
if(err)
|
||||
MTGosHAL::err << text;
|
||||
else
|
||||
MTGosHAL::out << text;
|
||||
return *this;
|
||||
}
|
||||
auto ScreenOut::clrscr() -> ScreenOut & {
|
||||
if(err)
|
||||
MTGosHAL::err.clrscr();
|
||||
else
|
||||
MTGosHAL::out.clrscr();
|
||||
return *this;
|
||||
if(err)
|
||||
MTGosHAL::err.clrscr();
|
||||
else
|
||||
MTGosHAL::out.clrscr();
|
||||
return *this;
|
||||
}
|
||||
auto ScreenOut::setColor(BGColor bg, FGColor fg) -> ScreenOut & {
|
||||
if(err)
|
||||
MTGosHAL::err << static_cast<MTGosHAL::BG_color>(bg) << static_cast<MTGosHAL::FG_color>(fg) ;
|
||||
else
|
||||
MTGosHAL::out << static_cast<MTGosHAL::BG_color>(bg) << static_cast<MTGosHAL::FG_color>(fg) ;
|
||||
return *this;
|
||||
if(err)
|
||||
MTGosHAL::err << static_cast<MTGosHAL::BG_color>(bg) << static_cast<MTGosHAL::FG_color>(fg) ;
|
||||
else
|
||||
MTGosHAL::out << static_cast<MTGosHAL::BG_color>(bg) << static_cast<MTGosHAL::FG_color>(fg) ;
|
||||
return *this;
|
||||
}
|
||||
ScreenOut::~ScreenOut() {}
|
||||
auto syscall(uint32_t syscall_num, void* handle, void* args) -> void* {
|
||||
uint16_t objnum=(uint16_t)(syscall_num>>16);
|
||||
uint16_t funcnum=(uint16_t)syscall_num;
|
||||
switch(objnum) {
|
||||
case 0: {
|
||||
ScreenOut *obj = (ScreenOut*)handle;
|
||||
switch(funcnum) {
|
||||
case 0:
|
||||
return (void*)(new ScreenOut(((bool *)args)[0]));
|
||||
case 0: {
|
||||
ScreenOut *obj = (ScreenOut*)handle;
|
||||
switch(funcnum) {
|
||||
case 0:
|
||||
return (void*)(new ScreenOut(((bool *)args)[0]));
|
||||
break;
|
||||
case 1:
|
||||
*obj << ((char**)args)[0];
|
||||
return handle;
|
||||
break;
|
||||
case 2:
|
||||
obj->clrscr();
|
||||
return handle;
|
||||
break;
|
||||
case 3: {
|
||||
BGColor bg=static_cast<BGColor>(((uint32_t *)args)[0]);
|
||||
FGColor fg=static_cast<FGColor>(((uint32_t *)args)[1]);
|
||||
obj->setColor(bg,fg);
|
||||
return handle;
|
||||
break;
|
||||
}
|
||||
case 0xFFFF:
|
||||
delete obj;
|
||||
return nullptr;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
case 1:
|
||||
|
||||
*obj << ((char**)args)[0];
|
||||
return handle;
|
||||
break;
|
||||
case 2:
|
||||
obj->clrscr();
|
||||
return handle;
|
||||
break;
|
||||
case 3: {
|
||||
BGColor bg=static_cast<BGColor>(((uint32_t *)args)[0]);
|
||||
FGColor fg=static_cast<FGColor>(((uint32_t *)args)[1]);
|
||||
obj->setColor(bg,fg);
|
||||
return handle;
|
||||
break;
|
||||
}
|
||||
case 0xFFFF:
|
||||
delete obj;
|
||||
return nullptr;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -1,45 +1,45 @@
|
|||
.global screenout_init
|
||||
// void * screenout_init(int err);
|
||||
screenout_init:
|
||||
stmdb sp!, {r0} //r0 is err
|
||||
mov r0, #0
|
||||
svc #0 //Only one svc
|
||||
sub sp, #4
|
||||
bx lr
|
||||
stmdb sp!, {r0} //r0 is err
|
||||
mov r0, #0
|
||||
svc #0 //Only one svc
|
||||
sub sp, #4
|
||||
bx lr
|
||||
|
||||
.global screenout_out
|
||||
// void * screenout_out(void* handle, char *str);
|
||||
screenout_out:
|
||||
stmdb sp!, {r1} // R1 is str
|
||||
mov r1, r0 //R0 is handle
|
||||
mov r0, #1
|
||||
svc #0
|
||||
add sp, #4
|
||||
bx lr
|
||||
stmdb sp!, {r1} // R1 is str
|
||||
mov r1, r0 //R0 is handle
|
||||
mov r0, #1
|
||||
svc #0
|
||||
add sp, #4
|
||||
bx lr
|
||||
|
||||
.global screenout_clear
|
||||
// void * screenout_clear(void* handle);
|
||||
screenout_clear:
|
||||
mov r1, r0
|
||||
mov r0, #2
|
||||
svc #0
|
||||
bx lr
|
||||
mov r1, r0
|
||||
mov r0, #2
|
||||
svc #0
|
||||
bx lr
|
||||
|
||||
.global screenout_setcolor
|
||||
// void * screenout_setcolor(void* handle, uint32_t BG, uint32_t FG)
|
||||
screenout_setcolor:
|
||||
stmdb sp!, {r1, r2}
|
||||
mov r1, r0
|
||||
mov r0, #3
|
||||
svc #0
|
||||
add sp, #8
|
||||
bx lr
|
||||
stmdb sp!, {r1, r2}
|
||||
mov r1, r0
|
||||
mov r0, #3
|
||||
svc #0
|
||||
add sp, #8
|
||||
bx lr
|
||||
|
||||
.global screenout_destroy
|
||||
// void * screenout_destroy(void * handle)
|
||||
screenout_destroy:
|
||||
mov r1, r0
|
||||
mov r0, #0x10000
|
||||
sub r0, #1
|
||||
svc #0
|
||||
bx lr
|
||||
mov r1, r0
|
||||
mov r0, #0x10000
|
||||
sub r0, #1
|
||||
svc #0
|
||||
bx lr
|
||||
|
|
|
@ -7,38 +7,38 @@ void * screenout_setcolor(void* handle, uint32_t BG, uint32_t FG);
|
|||
void * screenout_destroy(void * handle);
|
||||
}
|
||||
ScreenOut::ScreenOut(bool err) {
|
||||
handle=screenout_init(err);
|
||||
handle=screenout_init(err);
|
||||
}
|
||||
auto ScreenOut::operator<<(const char * str) -> ScreenOut & {
|
||||
screenout_out(handle, str);
|
||||
return *this;
|
||||
screenout_out(handle, str);
|
||||
return *this;
|
||||
}
|
||||
auto ScreenOut::operator<<(int output) -> ScreenOut & {
|
||||
int base=10;
|
||||
const char* chars="0123456789ABCDEF";
|
||||
char buf[33];
|
||||
buf[32]='\0';
|
||||
char* ptr=buf+31;
|
||||
do {
|
||||
*(ptr--)=chars[output%base];
|
||||
output/=base;
|
||||
} while(output && (ptr!=buf));
|
||||
*this << ptr+1;
|
||||
return *this;
|
||||
int base=10;
|
||||
const char* chars="0123456789ABCDEF";
|
||||
char buf[33];
|
||||
buf[32]='\0';
|
||||
char* ptr=buf+31;
|
||||
do {
|
||||
*(ptr--)=chars[output%base];
|
||||
output/=base;
|
||||
} while(output && (ptr!=buf));
|
||||
*this << ptr+1;
|
||||
return *this;
|
||||
}
|
||||
auto ScreenOut::clrscr() -> ScreenOut & {
|
||||
screenout_clear(handle);
|
||||
return *this;
|
||||
screenout_clear(handle);
|
||||
return *this;
|
||||
}
|
||||
auto ScreenOut::setColor(BGColor bg, FGColor fg) -> ScreenOut & {
|
||||
screenout_setcolor(handle, static_cast<uint32_t>(bg), static_cast<uint32_t>(fg));
|
||||
return *this;
|
||||
screenout_setcolor(handle, static_cast<uint32_t>(bg), static_cast<uint32_t>(fg));
|
||||
return *this;
|
||||
}
|
||||
ScreenOut::~ScreenOut() {
|
||||
handle=screenout_destroy(handle);
|
||||
handle=screenout_destroy(handle);
|
||||
}
|
||||
void main();
|
||||
extern "C" void _start() {
|
||||
main();
|
||||
for(;;);
|
||||
main();
|
||||
for(;;);
|
||||
}
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
#include <mtgos.hpp>
|
||||
static unsigned short* videomem = (unsigned short*) 0xb8000;
|
||||
void temp() {
|
||||
int i;
|
||||
int i;
|
||||
for (i = 0; i < 3; i++) {
|
||||
*videomem++ = (0x07 << 8) | ('0' + i);
|
||||
}
|
||||
}
|
||||
void main()
|
||||
{
|
||||
char arr[4]="123";
|
||||
ScreenOut out=ScreenOut(false);
|
||||
int i;
|
||||
out.setColor(BGColor::BLUE, FGColor::YELLOW);
|
||||
for(;;) {
|
||||
long double a;
|
||||
long double b=a;
|
||||
out << a;
|
||||
a+=0.5;
|
||||
if(a!=b+0.5)
|
||||
out << " ";
|
||||
else
|
||||
out << "=";
|
||||
out << a;
|
||||
}
|
||||
char arr[4]="123";
|
||||
ScreenOut out=ScreenOut(false);
|
||||
int i;
|
||||
out.setColor(BGColor::BLUE, FGColor::YELLOW);
|
||||
for(;;) {
|
||||
long double a;
|
||||
long double b=a;
|
||||
out << a;
|
||||
a+=0.5;
|
||||
if(a!=b+0.5)
|
||||
out << " ";
|
||||
else
|
||||
out << "=";
|
||||
out << a;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,62 +1,62 @@
|
|||
.global screenout_init
|
||||
// void * screenout_init(int err);
|
||||
screenout_init:
|
||||
mov 0x4(%esp), %eax
|
||||
push %eax
|
||||
xor %eax, %eax
|
||||
int $0x30
|
||||
pop %ecx
|
||||
ret
|
||||
mov 0x4(%esp), %eax
|
||||
push %eax
|
||||
xor %eax, %eax
|
||||
int $0x30
|
||||
pop %ecx
|
||||
ret
|
||||
|
||||
.global screenout_out
|
||||
// void * screenout_out(void* handle, char *str);
|
||||
screenout_out:
|
||||
push %ebx
|
||||
mov 0xC(%esp), %eax
|
||||
mov 0x8(%esp), %ebx
|
||||
push %eax
|
||||
xor %eax, %eax
|
||||
inc %eax
|
||||
int $0x30
|
||||
pop %ebx
|
||||
pop %ebx
|
||||
ret
|
||||
push %ebx
|
||||
mov 0xC(%esp), %eax
|
||||
mov 0x8(%esp), %ebx
|
||||
push %eax
|
||||
xor %eax, %eax
|
||||
inc %eax
|
||||
int $0x30
|
||||
pop %ebx
|
||||
pop %ebx
|
||||
ret
|
||||
|
||||
.global screenout_clear
|
||||
// void * screenout_clear(void* handle);
|
||||
screenout_clear:
|
||||
push %ebx
|
||||
mov 0x8(%esp), %ebx
|
||||
xor %eax, %eax
|
||||
inc %eax
|
||||
inc %eax
|
||||
int $0x30
|
||||
pop %ebx
|
||||
ret
|
||||
push %ebx
|
||||
mov 0x8(%esp), %ebx
|
||||
xor %eax, %eax
|
||||
inc %eax
|
||||
inc %eax
|
||||
int $0x30
|
||||
pop %ebx
|
||||
ret
|
||||
|
||||
.global screenout_setcolor
|
||||
// void * screenout_setcolor(void* handle, uint32_t BG, uint32_t FG)
|
||||
screenout_setcolor:
|
||||
push %ebx
|
||||
mov 0x8(%esp), %ebx
|
||||
mov 0xC(%esp), %eax
|
||||
mov 0x10(%esp), %ecx
|
||||
push %ecx
|
||||
push %eax
|
||||
mov $3, %eax
|
||||
int $0x30
|
||||
pop %ebx
|
||||
pop %ebx
|
||||
pop %ebx
|
||||
ret
|
||||
push %ebx
|
||||
mov 0x8(%esp), %ebx
|
||||
mov 0xC(%esp), %eax
|
||||
mov 0x10(%esp), %ecx
|
||||
push %ecx
|
||||
push %eax
|
||||
mov $3, %eax
|
||||
int $0x30
|
||||
pop %ebx
|
||||
pop %ebx
|
||||
pop %ebx
|
||||
ret
|
||||
|
||||
.global screenout_destroy
|
||||
// void * screenout_destroy(void * handle)
|
||||
screenout_destroy:
|
||||
push %ebx
|
||||
mov 0x8(%esp), %ebx
|
||||
xor %eax, %eax
|
||||
dec %ax
|
||||
int $0x30
|
||||
pop %ebx
|
||||
ret
|
||||
push %ebx
|
||||
mov 0x8(%esp), %ebx
|
||||
xor %eax, %eax
|
||||
dec %ax
|
||||
int $0x30
|
||||
pop %ebx
|
||||
ret
|
||||
|
|
Loading…
Reference in a new issue