/**************************************************************************************
 Copyright (c) 2002
      The UbixOS Project

 $Id: main.c,v 1.43 2002/04/30 10:34:07 reddawg Exp $
**************************************************************************************/

#include <ubixos/schedule.h>
#include <ubixos/io.h>
#include <ubixos/exec.h>
#include <ubixos/ide.h>
#include <ubixos/gdt.h>
#include <ubixos/video.h>
#include <ubixos/8259.h>
#include <ubixos/idt.h>
#include <ubixos/keyboard.h>
#include <ubixos/string.h>
#include <ubixos/pit.h>
#include <ubixos/delay.h>
#include <drivers/fdc.h>
#include <ubixfs/ubixfs.h>
#include <gui/gui.h>
#include <version.h>
#include <mm/paging.h>
#include <temp.h> // just temp


unsigned char KERNEL_STACK[8192];              /* The stack to use: 8k stack   */
unsigned int endImage = 0x300000;
int errno;

void _start(void);                                /* Entry Point For UbOS                                                              */
int main();                                         /* The Main Kernel Program                                                         */
void _exit(void);                                  /* What to do when finished                                                       */


desc_table(GDT,5) {
  {dummy:0},
  stnd_desc(0, 0xFFFFF, (D_CODE + D_READ + D_BIG + D_BIG_LIM)),
  stnd_desc(0, 0xFFFFF, (D_DATA + D_WRITE + D_BIG + D_BIG_LIM)),
  stnd_desc(0, 0xFFFFF, (D_LDT)),
  stnd_desc(100000, (sizeof(struct tssStruct)-1), (D_TSS)),
  };

struct {
  unsigned short limit __attribute__ ((packed));
  union DT_entry *idt __attribute__ ((packed));
  } loadgdt = { (5 * sizeof(union DT_entry) - 1), GDT };


void _start(void) {
  countMemory();
  initPaging();
  //outportb(0x20,0x11);
  //outportb(0xA0,0x11);
  //outportb(0x21,0x20);
  //outportb(0xA1,0x28);
  //outportb(0x21,0x04);
  //outportb(0xA1,0x02);
  //outportb(0x21,0x01);
  //outportb(0xA1,0x01);
  //calibrateDelayLoop();
  /*
  Load our gdt and set kernel stack
  */
  asm(
    "lgdtl (loadgdt)     \n"
    "movw $0x10,%%ax     \n"
    "movw %%ax,%%ds      \n"
    "movw %%ax,%%es      \n"
    "movw %%ax,%%fs      \n"
    "movw %%ax,%%gs      \n"
    "movw %%ax,%%ss      \n"
    "movl $0xFFFF,%%esp  \n"
    "mov $0x18,%%ax      \n" //Set up dummy LDT
    "lldt %%ax           \n"
    "mov $0x20,%%ax      \n" // Set up dummy TSS
    "ltr %%ax            \n" // Loads dummy TSS
    :
    : "r" (GDT), "p" (KERNEL_STACK+4096)
    : "%eax"
    );
  main(); //Start Of Kernel Functionality
  _exit(); //Reboot The Machine
  }

void _exit(void) {                                   /* Exit point of the kernel                                                              */
  while(inportb(0x64) & 0x02);                 /* Reboot the computer                                                                */
  outportb(0x64, 0xfe);
  asm("cli;hlt");                                      /* Half the computer if it doesnt work.                                             */
  }

/* Start of the UbixOS kernel */
int main() {
  outputVersion();
  init_8259();
  init_IDT();;
  kprintf("Countring Memory\nMemory Total: %iK, TotalPage: %i\n",(mem_end/1024),(mem_end/4096));
  init_keyboard();
  init_pit(100, 0);
  set_vector(timerINT, M_VEC, (D_INT + D_PRESENT + D_DPL3));
  initFloppy();
  initIde();
  initUbixfs();
  initScheduler();
  asm("sti");
  //init_gui();
  //init_mode_0x11();
  //defVGAFillRect(0,0,640,480,3);
  execThread(badaboom,0xAFFF,"badaboom");
  execThread(badabing,0xBFFF,"badabing");
  execThread(shell,0xCFFF,"Shell Thread");
  //execFile("bsd.bin");
  enable_irq(0);
  while (1);
  }