CTAOS v1
This commit is contained in:
		
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -5,7 +5,7 @@
 | 
			
		||||
# Compiled Object files
 | 
			
		||||
*.slo
 | 
			
		||||
*.lo
 | 
			
		||||
*.o
 | 
			
		||||
#*.o
 | 
			
		||||
*.obj
 | 
			
		||||
 | 
			
		||||
# Precompiled Headers
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										22
									
								
								compile.bat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								compile.bat
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
@echo off
 | 
			
		||||
rem The name of the loader assembly file (without extension, must be .asm):
 | 
			
		||||
set loader_name=loader
 | 
			
		||||
 | 
			
		||||
rem NASM and DJGPP executable paths:
 | 
			
		||||
set nasm_path=C:\nasm
 | 
			
		||||
set djgpp_path=C:\DJGPP\bin
 | 
			
		||||
 | 
			
		||||
@echo on
 | 
			
		||||
rem Compile loader
 | 
			
		||||
%nasm_path%\nasm.exe -f aout -o %loader_name%.o %loader_name%.asm
 | 
			
		||||
rem Compile main Kernel
 | 
			
		||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o main.o main.c
 | 
			
		||||
rem OTHER GCC/NASM SOURCES GO HERE
 | 
			
		||||
 | 
			
		||||
@echo on
 | 
			
		||||
%djgpp_path%\ld -T link.ld -o kernel.bin %loader_name%.o main.o
 | 
			
		||||
@echo .
 | 
			
		||||
@echo Done!
 | 
			
		||||
 | 
			
		||||
@pause
 | 
			
		||||
copy C:\CTAOS\KERNEL.BIN C:\SHARE
 | 
			
		||||
							
								
								
									
										78
									
								
								gdt.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								gdt.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,78 @@
 | 
			
		||||
#include <system.h>
 | 
			
		||||
 | 
			
		||||
/* Defines a GDT entry. We say packed, because it prevents the
 | 
			
		||||
*  compiler from doing things that it thinks is best: Prevent
 | 
			
		||||
*  compiler "optimization" by packing */
 | 
			
		||||
struct gdt_entry
 | 
			
		||||
{
 | 
			
		||||
    unsigned short limit_low;
 | 
			
		||||
    unsigned short base_low;
 | 
			
		||||
    unsigned char base_middle;
 | 
			
		||||
    unsigned char access;
 | 
			
		||||
    unsigned char granularity;
 | 
			
		||||
    unsigned char base_high;
 | 
			
		||||
} __attribute__((packed));
 | 
			
		||||
 | 
			
		||||
/* Special pointer which includes the limit: The max bytes
 | 
			
		||||
*  taken up by the GDT, minus 1. Again, this NEEDS to be packed */
 | 
			
		||||
struct gdt_ptr
 | 
			
		||||
{
 | 
			
		||||
    unsigned short limit;
 | 
			
		||||
    unsigned int base;
 | 
			
		||||
} __attribute__((packed));
 | 
			
		||||
 | 
			
		||||
/* Our GDT, with 3 entries, and finally our special GDT pointer */
 | 
			
		||||
struct gdt_entry gdt[3];
 | 
			
		||||
struct gdt_ptr gp;
 | 
			
		||||
 | 
			
		||||
/* This will be a function in start.asm. We use this to properly
 | 
			
		||||
*  reload the new segment registers */
 | 
			
		||||
extern void gdt_flush();
 | 
			
		||||
		
 | 
			
		||||
/* Setup a descriptor in the Global Descriptor Table */
 | 
			
		||||
void gdt_set_gate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran)
 | 
			
		||||
{
 | 
			
		||||
    /* Setup the descriptor base address */
 | 
			
		||||
    gdt[num].base_low = (base & 0xFFFF);
 | 
			
		||||
    gdt[num].base_middle = (base >> 16) & 0xFF;
 | 
			
		||||
    gdt[num].base_high = (base >> 24) & 0xFF;
 | 
			
		||||
 | 
			
		||||
    /* Setup the descriptor limits */
 | 
			
		||||
    gdt[num].limit_low = (limit & 0xFFFF);
 | 
			
		||||
    gdt[num].granularity = ((limit >> 16) & 0x0F);
 | 
			
		||||
 | 
			
		||||
    /* Finally, set up the granularity and access flags */
 | 
			
		||||
    gdt[num].granularity |= (gran & 0xF0);
 | 
			
		||||
    gdt[num].access = access;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Should be called by main. This will setup the special GDT
 | 
			
		||||
*  pointer, set up the first 3 entries in our GDT, and then
 | 
			
		||||
*  finally call gdt_flush() in our assembler file in order
 | 
			
		||||
*  to tell the processor where the new GDT is and update the
 | 
			
		||||
*  new segment registers */
 | 
			
		||||
void gdt_install()
 | 
			
		||||
{
 | 
			
		||||
    /* Setup the GDT pointer and limit */
 | 
			
		||||
    gp.limit = (sizeof(struct gdt_entry) * 3) - 1;
 | 
			
		||||
    gp.base = &gdt;
 | 
			
		||||
 | 
			
		||||
    /* Our NULL descriptor */
 | 
			
		||||
    gdt_set_gate(0, 0, 0, 0, 0);
 | 
			
		||||
 | 
			
		||||
    /* The second entry is our Code Segment. The base address
 | 
			
		||||
    *  is 0, the limit is 4GBytes, it uses 4KByte granularity,
 | 
			
		||||
    *  uses 32-bit opcodes, and is a Code Segment descriptor.
 | 
			
		||||
    *  Please check the table above in the tutorial in order
 | 
			
		||||
    *  to see exactly what each value means */
 | 
			
		||||
    gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
 | 
			
		||||
 | 
			
		||||
    /* The third entry is our Data Segment. It's EXACTLY the
 | 
			
		||||
    *  same as our code segment, but the descriptor type in
 | 
			
		||||
    *  this entry's access byte says it's a Data Segment */
 | 
			
		||||
    gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
 | 
			
		||||
 | 
			
		||||
    /* Flush out the old GDT and install the new changes! */
 | 
			
		||||
    gdt_flush();
 | 
			
		||||
}
 | 
			
		||||
		
 | 
			
		||||
							
								
								
									
										62
									
								
								idt.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								idt.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
			
		||||
#include <system.h>
 | 
			
		||||
 | 
			
		||||
/* Defines an IDT entry */
 | 
			
		||||
struct idt_entry
 | 
			
		||||
{
 | 
			
		||||
    unsigned short base_lo;
 | 
			
		||||
    unsigned short sel;
 | 
			
		||||
    unsigned char always0;
 | 
			
		||||
    unsigned char flags;
 | 
			
		||||
    unsigned short base_hi;
 | 
			
		||||
} __attribute__((packed));
 | 
			
		||||
 | 
			
		||||
struct idt_ptr
 | 
			
		||||
{
 | 
			
		||||
    unsigned short limit;
 | 
			
		||||
    unsigned int base;
 | 
			
		||||
} __attribute__((packed));
 | 
			
		||||
 | 
			
		||||
/* Declare an IDT of 256 entries. Although we will only use the
 | 
			
		||||
*  first 32 entries in this tutorial, the rest exists as a bit
 | 
			
		||||
*  of a trap. If any undefined IDT entry is hit, it normally
 | 
			
		||||
*  will cause an "Unhandled Interrupt" exception. Any descriptor
 | 
			
		||||
*  for which the 'presence' bit is cleared (0) will generate an
 | 
			
		||||
*  "Unhandled Interrupt" exception */
 | 
			
		||||
struct idt_entry idt[256];
 | 
			
		||||
struct idt_ptr idtp;
 | 
			
		||||
 | 
			
		||||
/* This exists in 'start.asm', and is used to load our IDT */
 | 
			
		||||
extern void idt_load();
 | 
			
		||||
 | 
			
		||||
/* Use this function to set an entry in the IDT. Alot simpler
 | 
			
		||||
*  than twiddling with the GDT ;) */
 | 
			
		||||
void idt_set_gate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags)
 | 
			
		||||
{
 | 
			
		||||
    /* The interrupt routine's base address */
 | 
			
		||||
    idt[num].base_lo = (base & 0xFFFF);
 | 
			
		||||
    idt[num].base_hi = (base >> 16) & 0xFFFF;
 | 
			
		||||
 | 
			
		||||
    /* The segment or 'selector' that this IDT entry will use
 | 
			
		||||
    *  is set here, along with any access flags */
 | 
			
		||||
    idt[num].sel = sel;
 | 
			
		||||
    idt[num].always0 = 0;
 | 
			
		||||
    idt[num].flags = flags;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Installs the IDT */
 | 
			
		||||
void idt_install()
 | 
			
		||||
{
 | 
			
		||||
    /* Sets the special IDT pointer up, just like in 'gdt.c' */
 | 
			
		||||
    idtp.limit = (sizeof (struct idt_entry) * 256) - 1;
 | 
			
		||||
    idtp.base = &idt;
 | 
			
		||||
 | 
			
		||||
    /* Clear out the entire IDT, initializing it to zeros */
 | 
			
		||||
    memset(&idt, 0, sizeof(struct idt_entry) * 256);
 | 
			
		||||
 | 
			
		||||
    /* Add any new ISRs to the IDT here using idt_set_gate */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /* Points the processor's internal register to the new IDT */
 | 
			
		||||
    idt_load();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										152
									
								
								include/console.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										152
									
								
								include/console.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,152 @@
 | 
			
		||||
#include <system.h>
 | 
			
		||||
 | 
			
		||||
#ifndef __CONSOLE_H
 | 
			
		||||
#define __CONSOLE_H
 | 
			
		||||
#define _ATTRIB 0x0F
 | 
			
		||||
 | 
			
		||||
byte default_background, default_foreground;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Change cursor position
 | 
			
		||||
void text_mode_cursor(int x, int y)
 | 
			
		||||
{
 | 
			
		||||
      unsigned temp = y*current_mode_width + x;
 | 
			
		||||
      
 | 
			
		||||
      outportb (0x3D4, 14);
 | 
			
		||||
      outportb (0x3D5, temp >> 8);
 | 
			
		||||
      outportb (0x3D4, 15);
 | 
			
		||||
      outportb (0x3D5, temp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Set the default colors; max is 0x0F
 | 
			
		||||
void set_default_colors(byte back, byte fore)
 | 
			
		||||
{
 | 
			
		||||
      if (back < 0x10) default_background = back;
 | 
			
		||||
      if (fore < 0x10) default_foreground = fore;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Clear screen, and set font to default font
 | 
			
		||||
void clrscr()
 | 
			
		||||
{
 | 
			
		||||
      byte font = default_foreground | (default_background<<4);
 | 
			
		||||
      int i = 0;
 | 
			
		||||
      for (i = 0; i < current_mode_width*current_mode_height; i++)
 | 
			
		||||
      {     TextVideoRam[2*i] = 0;
 | 
			
		||||
            TextVideoRam[2*i+1] = font;
 | 
			
		||||
      }
 | 
			
		||||
      cursor_x = 0; cursor_y = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void scroll(int n)
 | 
			
		||||
{
 | 
			
		||||
      memcpy(TextVideoRam,
 | 
			
		||||
             TextVideoRam+(current_mode_width*n*2),
 | 
			
		||||
             2*current_mode_width*(current_mode_height - n));
 | 
			
		||||
             
 | 
			
		||||
      byte blank = default_foreground | (default_background<<4);
 | 
			
		||||
      
 | 
			
		||||
      int i;
 | 
			
		||||
      for (i = current_mode_width*(current_mode_height-n);
 | 
			
		||||
           i < current_mode_width*current_mode_height; i++){
 | 
			
		||||
              TextVideoRam[2*i] = 0;
 | 
			
		||||
              TextVideoRam[2*i+1] = blank;
 | 
			
		||||
      }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void _endl()
 | 
			
		||||
{
 | 
			
		||||
      cursor_x = 0;
 | 
			
		||||
      if (++cursor_y >=25) {
 | 
			
		||||
            cursor_y = 24; scroll(1);
 | 
			
		||||
            }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Put character on screen in specified position; can use different font colors
 | 
			
		||||
void putc_pos_font(int x, int y, char c, byte back, byte fore)
 | 
			
		||||
{
 | 
			
		||||
	TextVideoRam[2*(y*current_mode_width+x)] = c;
 | 
			
		||||
	TextVideoRam[2*(y*current_mode_width+x)+1] = fore|(back<<4);
 | 
			
		||||
}
 | 
			
		||||
// Put character on screen in specified position; use default font colors
 | 
			
		||||
void putc_pos(int x, int y, char c)
 | 
			
		||||
{
 | 
			
		||||
	TextVideoRam[2*(y*current_mode_width+x)] = c;
 | 
			
		||||
}
 | 
			
		||||
// Put character on screen in the current cursor position; different font colors
 | 
			
		||||
void putc_font(char c, byte back, byte fore)
 | 
			
		||||
{
 | 
			
		||||
      if (cursor_x > current_mode_width) _endl();
 | 
			
		||||
      
 | 
			
		||||
      if (c == '\n') {_endl(); return;};
 | 
			
		||||
      TextVideoRam[2*(cursor_y*current_mode_width+cursor_x)] = c;
 | 
			
		||||
      TextVideoRam[2*(cursor_y*current_mode_width+cursor_x)+1] = fore|(back<<4);
 | 
			
		||||
      cursor_x++;
 | 
			
		||||
}
 | 
			
		||||
// Put character on screen in the current cursor position; default font colors
 | 
			
		||||
void putc(char c)
 | 
			
		||||
{
 | 
			
		||||
      if (cursor_x > current_mode_width) _endl();
 | 
			
		||||
 | 
			
		||||
      if (c == '\n') {_endl(); return;};
 | 
			
		||||
      TextVideoRam[2*(cursor_y*current_mode_width+cursor_x)] = c;
 | 
			
		||||
      cursor_x++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Put string on screen in specified position; can use different font colors
 | 
			
		||||
void puts_pos_font(int x, int y, char *str, byte back, byte fore)
 | 
			
		||||
{
 | 
			
		||||
      int i;
 | 
			
		||||
      for (i = 0; str[i] != 0; i++) 
 | 
			
		||||
            putc_pos_font(x+i, y, str[i], back, fore);
 | 
			
		||||
      
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Put string on screen in specified position; use default font colors
 | 
			
		||||
void puts_pos(int x, int y, char *str)
 | 
			
		||||
{
 | 
			
		||||
      int i;
 | 
			
		||||
      for (i = 0; str[i] != 0; i++)
 | 
			
		||||
            putc_pos(x+i, y, str[i]);
 | 
			
		||||
}
 | 
			
		||||
void puts(char *str)
 | 
			
		||||
{
 | 
			
		||||
      int i;
 | 
			
		||||
      for (i = 0; str[i] != 0; i++)
 | 
			
		||||
            putc(str[i]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void puts_font(char *str, byte back, byte fore)
 | 
			
		||||
{
 | 
			
		||||
      int i;
 | 
			
		||||
      for (i = 0; str[i] != 0; i++)
 | 
			
		||||
            putc_font(str[i], back, fore);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void put_hex(int x, int y, unsigned int alpha)
 | 
			
		||||
{
 | 
			
		||||
      char hex[] = "0123456789ABCDEF";
 | 
			
		||||
      char nr[9];
 | 
			
		||||
      int i;
 | 
			
		||||
      for (i = 7; i >= 0; i--) {
 | 
			
		||||
            nr[i] = hex[alpha%16];
 | 
			
		||||
            alpha /= 16;
 | 
			
		||||
            }
 | 
			
		||||
      nr[8] = 0;
 | 
			
		||||
      puts_pos(x, y, nr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void put_bin (int x, int y, byte xz)
 | 
			
		||||
{
 | 
			
		||||
      int i;
 | 
			
		||||
      char arr[9] = {0,0,0,0,0,0,0,0,0};
 | 
			
		||||
      for(i=7; i>=0; i--) {
 | 
			
		||||
          arr[i] = (xz%2) + '0'; xz/=2;
 | 
			
		||||
      }
 | 
			
		||||
      puts_pos (x, y, arr);
 | 
			
		||||
}
 | 
			
		||||
      
 | 
			
		||||
      
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										104
									
								
								include/system.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								include/system.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,104 @@
 | 
			
		||||
#ifndef __SYSTEM_H
 | 
			
		||||
#define __SYSTEM_H
 | 
			
		||||
 | 
			
		||||
// Data type declarations
 | 
			
		||||
typedef unsigned char byte;
 | 
			
		||||
typedef unsigned short word;
 | 
			
		||||
typedef unsigned int dword;
 | 
			
		||||
 | 
			
		||||
/* This defines what the stack looks like after an ISR was running */
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    unsigned int gs, fs, es, ds;      /* pushed the segs last */
 | 
			
		||||
    unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax;  /* pushed by 'pusha' */
 | 
			
		||||
    unsigned int int_no, err_code;    /* our 'push byte #' and ecodes do this */
 | 
			
		||||
    unsigned int eip, cs, eflags, useresp, ss;   /* pushed by the processor automatically */ 
 | 
			
		||||
} regs;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
byte *TextVideoRam;
 | 
			
		||||
int cursor_x, cursor_y;
 | 
			
		||||
int current_mode_width;
 | 
			
		||||
int current_mode_height;
 | 
			
		||||
 | 
			
		||||
// System functions declaration
 | 
			
		||||
void system_init();
 | 
			
		||||
void *memcpy(void *dest, const void *src, int count);
 | 
			
		||||
void *memset(void *dest, char val, int count);
 | 
			
		||||
unsigned short *memsetw(unsigned short *dest, unsigned short val, int count);
 | 
			
		||||
int strlen (const char *str);
 | 
			
		||||
byte inportb (word _port);
 | 
			
		||||
byte inb (word _port);
 | 
			
		||||
void outportb (word _port, byte _data);
 | 
			
		||||
void outb (word _port, byte _data) ;
 | 
			
		||||
 | 
			
		||||
// GDT, IDT, ISRs, IRQ functions declarations
 | 
			
		||||
void gdt_set_gate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran);
 | 
			
		||||
void gdt_install();
 | 
			
		||||
 | 
			
		||||
void idt_set_gate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags);
 | 
			
		||||
void idt_install();
 | 
			
		||||
 | 
			
		||||
void isrs_install();
 | 
			
		||||
 | 
			
		||||
void irq_install_handler(int irq, void (*handler)(regs *r));
 | 
			
		||||
void irq_uninstall_handler(int irq);
 | 
			
		||||
void irq_install();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Initialize system
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void *memcpy(void *dest, const void *src, int count)
 | 
			
		||||
{
 | 
			
		||||
    const char *sp = (const char *)src;
 | 
			
		||||
    char *dp = (char *)dest;
 | 
			
		||||
    for(; count != 0; count--) *dp++ = *sp++;
 | 
			
		||||
    return dest;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void *memset(void *dest, char val, int count)
 | 
			
		||||
{
 | 
			
		||||
    char *temp = (char *)dest;
 | 
			
		||||
    for( ; count != 0; count--) *temp++ = val;
 | 
			
		||||
    return dest;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned short *memsetw(unsigned short *dest, unsigned short val, int count)
 | 
			
		||||
{
 | 
			
		||||
    unsigned short *temp = (unsigned short *)dest;
 | 
			
		||||
    for( ; count != 0; count--) *temp++ = val;
 | 
			
		||||
    return dest;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// strlen -- Get lenght of str
 | 
			
		||||
int strlen (const char *str)
 | 
			
		||||
{
 | 
			
		||||
      int i;
 | 
			
		||||
      for (i = 0; str[i]!=0; i++) {}
 | 
			
		||||
      return i;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
byte inportb (word _port) {
 | 
			
		||||
      byte rv;
 | 
			
		||||
      __asm__ __volatile__ ("inb %1, %0" : "=a" (rv) : "dN" (_port));
 | 
			
		||||
      return rv;
 | 
			
		||||
}
 | 
			
		||||
byte inb (word _port) {
 | 
			
		||||
      byte rv;
 | 
			
		||||
      __asm__ __volatile__ ("inb %1, %0" : "=a" (rv) : "dN" (_port));
 | 
			
		||||
      return rv;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void outportb (word _port, byte _data) {
 | 
			
		||||
      __asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data));
 | 
			
		||||
}
 | 
			
		||||
void outb (word _port, byte _data) {
 | 
			
		||||
      __asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										37
									
								
								init.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								init.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
#include <system.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void system_init()
 | 
			
		||||
{
 | 
			
		||||
      // Detect if color/monochrome screen
 | 
			
		||||
	char c = (*(volatile unsigned short*)0x410)&0x30;
 | 
			
		||||
	if (c==0x30) TextVideoRam = (byte *)0xb0000;
 | 
			
		||||
	else TextVideoRam = (byte *)0xb8000;
 | 
			
		||||
	
 | 
			
		||||
	// Reset cursor, use 80x25 text video mode
 | 
			
		||||
	current_mode_width = 80;
 | 
			
		||||
	current_mode_height = 25;
 | 
			
		||||
	cursor_x = cursor_y = 0;
 | 
			
		||||
	
 | 
			
		||||
	// Install GDT, IDT, ISRs and IRQs; Enable interrupts
 | 
			
		||||
      gdt_install();
 | 
			
		||||
      idt_install();
 | 
			
		||||
	isrs_install();
 | 
			
		||||
	irq_install();
 | 
			
		||||
      __asm__ __volatile__ ("sti");
 | 
			
		||||
	 
 | 
			
		||||
      // Install PIT timer
 | 
			
		||||
      timer_ticks = 0;
 | 
			
		||||
      irq_install_handler(0, timer_handler);
 | 
			
		||||
      timer_phase (100);
 | 
			
		||||
      
 | 
			
		||||
      // Install keyboard
 | 
			
		||||
      kb_modifier_status = 0;
 | 
			
		||||
      kb_lights_status = 0xFF; kb_update_LED();
 | 
			
		||||
      kb_lights_status = 0; kb_update_LED();
 | 
			
		||||
      irq_install_handler(1, kb_handler);
 | 
			
		||||
      
 | 
			
		||||
      // mouse_driver();
 | 
			
		||||
 | 
			
		||||
      
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										118
									
								
								irq.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								irq.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,118 @@
 | 
			
		||||
#include <system.h>
 | 
			
		||||
 | 
			
		||||
/* These are own ISRs that point to our special IRQ handler
 | 
			
		||||
*  instead of the regular 'fault_handler' function */
 | 
			
		||||
 | 
			
		||||
extern void irq0();
 | 
			
		||||
extern void irq1();
 | 
			
		||||
extern void irq2();
 | 
			
		||||
extern void irq3();
 | 
			
		||||
extern void irq4();
 | 
			
		||||
extern void irq5();
 | 
			
		||||
extern void irq6();
 | 
			
		||||
extern void irq7();
 | 
			
		||||
extern void irq8();
 | 
			
		||||
extern void irq9();
 | 
			
		||||
extern void irq10();
 | 
			
		||||
extern void irq11();
 | 
			
		||||
extern void irq12();
 | 
			
		||||
extern void irq13();
 | 
			
		||||
extern void irq14();
 | 
			
		||||
extern void irq15();
 | 
			
		||||
 | 
			
		||||
/* This array is actually an array of function pointers. We use
 | 
			
		||||
*  this to handle custom IRQ handlers for a given IRQ */
 | 
			
		||||
void *irq_routines[16] =
 | 
			
		||||
{
 | 
			
		||||
    0, 0, 0, 0, 0, 0, 0, 0,
 | 
			
		||||
    0, 0, 0, 0, 0, 0, 0, 0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* This installs a custom IRQ handler for the given IRQ */
 | 
			
		||||
void irq_install_handler (int irq, void (*handler)(regs *r))
 | 
			
		||||
{
 | 
			
		||||
      irq_routines[irq] = handler;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void irq_uninstall_handler (int irq)
 | 
			
		||||
{
 | 
			
		||||
      irq_routines[irq] = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Normally, IRQs 0 to 7 are mapped to entries 8 to 15. This
 | 
			
		||||
*  is a problem in protected mode, because IDT entry 8 is a
 | 
			
		||||
*  Double Fault! Without remapping, every time IRQ0 fires,
 | 
			
		||||
*  you get a Double Fault Exception, which is NOT actually
 | 
			
		||||
*  what's happening. We send commands to the Programmable
 | 
			
		||||
*  Interrupt Controller (PICs - also called the 8259's) in
 | 
			
		||||
*  order to make IRQ0 to 15 be remapped to IDT entries 32 to
 | 
			
		||||
*  47 */
 | 
			
		||||
void irq_remap(void)
 | 
			
		||||
{
 | 
			
		||||
      outportb(0x20, 0x11);
 | 
			
		||||
      outportb(0xA0, 0x11);
 | 
			
		||||
      outportb(0x21, 0x20);
 | 
			
		||||
      outportb(0xA1, 0x28);
 | 
			
		||||
      outportb(0x21, 0x04);
 | 
			
		||||
      outportb(0xA1, 0x02);
 | 
			
		||||
      outportb(0x21, 0x01);
 | 
			
		||||
      outportb(0xA1, 0x01);
 | 
			
		||||
      outportb(0x21, 0x0);
 | 
			
		||||
      outportb(0xA1, 0x0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* We first remap the interrupt controllers, and then we install
 | 
			
		||||
*  the appropriate ISRs to the correct entries in the IDT. This
 | 
			
		||||
*  is just like installing the exception handlers */
 | 
			
		||||
void irq_install()
 | 
			
		||||
{
 | 
			
		||||
      irq_remap();
 | 
			
		||||
      
 | 
			
		||||
      idt_set_gate(32, (unsigned)irq0, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(33, (unsigned)irq1, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(34, (unsigned)irq2, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(35, (unsigned)irq3, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(36, (unsigned)irq4, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(37, (unsigned)irq5, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(38, (unsigned)irq6, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(39, (unsigned)irq7, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(40, (unsigned)irq8, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(41, (unsigned)irq9, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(42, (unsigned)irq10, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(43, (unsigned)irq11, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(44, (unsigned)irq12, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(45, (unsigned)irq13, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(46, (unsigned)irq14, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(47, (unsigned)irq15, 0x08, 0x8E);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Each of the IRQ ISRs point to this function, rather than
 | 
			
		||||
*  the 'fault_handler' in 'isrs.c'. The IRQ Controllers need
 | 
			
		||||
*  to be told when you are done servicing them, so you need
 | 
			
		||||
*  to send them an "End of Interrupt" command (0x20). There
 | 
			
		||||
*  are two 8259 chips: The first exists at 0x20, the second
 | 
			
		||||
*  exists at 0xA0. If the second controller (an IRQ from 8 to
 | 
			
		||||
*  15) gets an interrupt, you need to acknowledge the
 | 
			
		||||
*  interrupt at BOTH controllers, otherwise, you only send
 | 
			
		||||
*  an EOI command to the first controller. If you don't send
 | 
			
		||||
*  an EOI, you won't raise any more IRQs */
 | 
			
		||||
void irq_handler (regs *r)
 | 
			
		||||
{
 | 
			
		||||
      /* This is a blank function pointer */
 | 
			
		||||
      void (*handler)(regs *r);
 | 
			
		||||
      
 | 
			
		||||
    /* Find out if we have a custom handler to run for this
 | 
			
		||||
    *  IRQ, and then finally, run it */
 | 
			
		||||
      handler = irq_routines[r->int_no - 32];
 | 
			
		||||
      if (handler) handler(r);
 | 
			
		||||
      
 | 
			
		||||
    /* If the IDT entry that was invoked was greater than 40
 | 
			
		||||
    *  (meaning IRQ8 - 15), then we need to send an EOI to
 | 
			
		||||
    *  the slave controller */
 | 
			
		||||
      if (r->int_no >=40) outportb(0x0A, 0x20);
 | 
			
		||||
      
 | 
			
		||||
    /* In either case, we need to send an EOI to the master
 | 
			
		||||
    *  interrupt controller too */
 | 
			
		||||
      outportb(0x20, 0x20);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										163
									
								
								isrs.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								isrs.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,163 @@
 | 
			
		||||
#include <system.h>
 | 
			
		||||
#include <console.h>
 | 
			
		||||
 | 
			
		||||
extern void isr0();
 | 
			
		||||
extern void isr1();
 | 
			
		||||
extern void isr2();
 | 
			
		||||
extern void isr3();
 | 
			
		||||
extern void isr4();
 | 
			
		||||
extern void isr5();
 | 
			
		||||
extern void isr6();
 | 
			
		||||
extern void isr7();
 | 
			
		||||
extern void isr8();
 | 
			
		||||
extern void isr9();
 | 
			
		||||
extern void isr10();
 | 
			
		||||
extern void isr11();
 | 
			
		||||
extern void isr12();
 | 
			
		||||
extern void isr13();
 | 
			
		||||
extern void isr14();
 | 
			
		||||
extern void isr15();
 | 
			
		||||
extern void isr16();
 | 
			
		||||
extern void isr17();
 | 
			
		||||
extern void isr18();
 | 
			
		||||
extern void isr19();
 | 
			
		||||
extern void isr20();
 | 
			
		||||
extern void isr21();
 | 
			
		||||
extern void isr22();
 | 
			
		||||
extern void isr23();
 | 
			
		||||
extern void isr24();
 | 
			
		||||
extern void isr25();
 | 
			
		||||
extern void isr26();
 | 
			
		||||
extern void isr27();
 | 
			
		||||
extern void isr28();
 | 
			
		||||
extern void isr29();
 | 
			
		||||
extern void isr30();
 | 
			
		||||
extern void isr31();
 | 
			
		||||
 | 
			
		||||
/* This is a very repetitive function... it's not hard, it's
 | 
			
		||||
*  just annoying. As you can see, we set the first 32 entries
 | 
			
		||||
*  in the IDT to the first 32 ISRs. We can't use a for loop
 | 
			
		||||
*  for this, because there is no way to get the function names
 | 
			
		||||
*  that correspond to that given entry. We set the access
 | 
			
		||||
*  flags to 0x8E. This means that the entry is present, is
 | 
			
		||||
*  running in ring 0 (kernel level), and has the lower 5 bits
 | 
			
		||||
*  set to the required '14', which is represented by 'E' in
 | 
			
		||||
*  hex. */
 | 
			
		||||
void isrs_install()
 | 
			
		||||
{
 | 
			
		||||
      idt_set_gate(0, (unsigned)isr0, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(1, (unsigned)isr1, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(2, (unsigned)isr2, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(3, (unsigned)isr3, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(4, (unsigned)isr4, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(5, (unsigned)isr5, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(6, (unsigned)isr6, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(7, (unsigned)isr7, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(8, (unsigned)isr8, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(9, (unsigned)isr9, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(10, (unsigned)isr10, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(11, (unsigned)isr11, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(12, (unsigned)isr12, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(13, (unsigned)isr13, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(14, (unsigned)isr14, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(15, (unsigned)isr15, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(16, (unsigned)isr16, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(17, (unsigned)isr17, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(18, (unsigned)isr18, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(19, (unsigned)isr19, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(20, (unsigned)isr20, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(21, (unsigned)isr21, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(22, (unsigned)isr22, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(23, (unsigned)isr23, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(24, (unsigned)isr24, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(25, (unsigned)isr25, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(26, (unsigned)isr26, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(27, (unsigned)isr27, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(28, (unsigned)isr28, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(29, (unsigned)isr29, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(30, (unsigned)isr30, 0x08, 0x8E);
 | 
			
		||||
      idt_set_gate(31, (unsigned)isr31, 0x08, 0x8E);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  char *exception_messages[] = {
 | 
			
		||||
      "Division By Zero Exception",
 | 
			
		||||
 	"Debug Exception",
 | 
			
		||||
 	"Non Maskable Interrupt Exception",
 | 
			
		||||
  	"Breakpoint Exception",
 | 
			
		||||
 	"Into Detected Overflow Exception",
 | 
			
		||||
 	"Out of Bounds Exception",
 | 
			
		||||
 	"Invalid Opcode Exception",
 | 
			
		||||
 	"No Coprocessor",
 | 
			
		||||
 	"Double Fault Exception",
 | 
			
		||||
 	"Coprocessor Segment Overrun Exception",
 | 
			
		||||
 	"Bad TSS Exception",
 | 
			
		||||
 	"Segment Not Present Exception",
 | 
			
		||||
 	"Stack Fault Exception",
 | 
			
		||||
 	"General Protection Fault Exception",
 | 
			
		||||
 	"Page Fault Exception",
 | 
			
		||||
 	"Unknown Interrupt Exception",
 | 
			
		||||
 	"Coprocessor Fault Exception",
 | 
			
		||||
 	"Alignment Check Exception",
 | 
			
		||||
 	"Machine Check Exception",
 | 
			
		||||
	"Reserved Exception",
 | 
			
		||||
	"Reserved Exception",
 | 
			
		||||
	"Reserved Exception",
 | 
			
		||||
	"Reserved Exception",
 | 
			
		||||
	"Reserved Exception",
 | 
			
		||||
	"Reserved Exception",
 | 
			
		||||
	"Reserved Exception",
 | 
			
		||||
	"Reserved Exception",
 | 
			
		||||
	"Reserved Exception",
 | 
			
		||||
	"Reserved Exception",
 | 
			
		||||
	"Reserved Exception",
 | 
			
		||||
	"Reserved Exception"
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* All of our Exception handling Interrupt Service Routines will
 | 
			
		||||
*  point to this function. This will tell us what exception has
 | 
			
		||||
*  happened! Right now, we simply halt the system by hitting an
 | 
			
		||||
*  endless loop. All ISRs disable interrupts while they are being
 | 
			
		||||
*  serviced as a 'locking' mechanism to prevent an IRQ from
 | 
			
		||||
*  happening and messing up kernel data structures */
 | 
			
		||||
void fault_handler(regs *r)
 | 
			
		||||
{
 | 
			
		||||
    /* Is this a fault whose number is from 0 to 31? */
 | 
			
		||||
    if (r->int_no < 32)
 | 
			
		||||
    {
 | 
			
		||||
        /* Display the description for the Exception that occurred.*/
 | 
			
		||||
        
 | 
			
		||||
        // Put on the BSOD screen
 | 
			
		||||
        set_default_colors (0x01, 0x0F); clrscr();
 | 
			
		||||
        puts ("                              Blue Screen Of Death\n");
 | 
			
		||||
        int i; for (i = 79; i>=0; i--) putc('=');
 | 
			
		||||
        puts_pos_font (15, 2, "A fatal error has occured, CTA OS has been halted.", 0x01, 0x0C);
 | 
			
		||||
        puts_pos_font (10, 4, "gs", 0x01, 0x0B); put_hex(15, 4, r->gs);
 | 
			
		||||
        puts_pos_font (10, 5, "fs", 0x01, 0x0B); put_hex(15, 5, r->fs);
 | 
			
		||||
        puts_pos_font (10, 6, "es", 0x01, 0x0B); put_hex(15, 6, r->es);
 | 
			
		||||
        puts_pos_font (10, 7, "ds", 0x01, 0x0B); put_hex(15, 7, r->ds);
 | 
			
		||||
        
 | 
			
		||||
        puts_pos_font (40, 4, "edi", 0x01, 0x0B); put_hex(45, 4, r->edi);
 | 
			
		||||
        puts_pos_font (40, 5, "esi", 0x01, 0x0B); put_hex(45, 5, r->esi);
 | 
			
		||||
        puts_pos_font (40, 6, "ebp", 0x01, 0x0B); put_hex(45, 6, r->ebp);
 | 
			
		||||
        puts_pos_font (40, 7, "esp", 0x01, 0x0B); put_hex(45, 7, r->esp);
 | 
			
		||||
        
 | 
			
		||||
        puts_pos_font (10, 9, "eax", 0x01, 0x0B); put_hex(15, 9, r->eax);
 | 
			
		||||
        puts_pos_font (10, 10, "ebx", 0x01, 0x0B); put_hex(15, 10, r->ebx);
 | 
			
		||||
        puts_pos_font (40, 9, "ecx", 0x01, 0x0B); put_hex(45, 9, r->ecx);
 | 
			
		||||
        puts_pos_font (40, 10, "edx", 0x01, 0x0B); put_hex(45, 10, r->edx);
 | 
			
		||||
 | 
			
		||||
        puts_pos_font (10, 12, "int_no", 0x01, 0x0B); put_hex(17, 12, r->int_no);
 | 
			
		||||
        puts_pos_font (10, 14, "Error code:", 0x01, 0x0B); put_hex(24, 14, r->err_code);
 | 
			
		||||
        puts_pos_font (10, 15, "Error msg: ", 0x01, 0x0B); puts_pos(24, 15, exception_messages[r->int_no]);
 | 
			
		||||
        
 | 
			
		||||
        puts_pos_font (10, 17, "eip", 0x01, 0x0B); put_hex(17, 17, r->eip);
 | 
			
		||||
        puts_pos_font (10, 18, "cs", 0x01, 0x0B); put_hex(17, 18, r->cs);
 | 
			
		||||
        puts_pos_font (10, 19, "eflags", 0x01, 0x0B); put_hex(17, 19, r->eflags);
 | 
			
		||||
        puts_pos_font (10, 20, "useresp", 0x01, 0x0B); put_hex(17, 20, r->useresp);
 | 
			
		||||
        puts_pos_font (10, 21, "ss", 0x01, 0x0B); put_hex(17, 21, r->ss);
 | 
			
		||||
        
 | 
			
		||||
        puts_pos_font (29, 24, "!!! System  Halted !!!", 0x01, 0x0C);
 | 
			
		||||
        for (;;);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								kernel.bin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								kernel.bin
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										209
									
								
								keyus.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										209
									
								
								keyus.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,209 @@
 | 
			
		||||
unsigned char kbdus[128] =
 | 
			
		||||
{
 | 
			
		||||
    0,  27, '1', '2', '3', '4', '5', '6', '7', '8',	/* 9 */
 | 
			
		||||
  '9', '0', '-', '=', '\b',	/* Backspace */
 | 
			
		||||
  '\t',			/* Tab */
 | 
			
		||||
  'q', 'w', 'e', 'r',	/* 19 */
 | 
			
		||||
  't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n',	/* Enter key */
 | 
			
		||||
    0,			/* 29   - Control */
 | 
			
		||||
  'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',	/* 39 */
 | 
			
		||||
 '\'', '`',   0,		/* Left shift */
 | 
			
		||||
 '\\', 'z', 'x', 'c', 'v', 'b', 'n',			/* 49 */
 | 
			
		||||
  'm', ',', '.', '/',   0,				/* Right shift */
 | 
			
		||||
  '*',
 | 
			
		||||
    0,	/* Alt */
 | 
			
		||||
  ' ',	/* Space bar */
 | 
			
		||||
    0,	/* Caps lock */
 | 
			
		||||
    0,	/* 59 - F1 key ... > */
 | 
			
		||||
    0,   0,   0,   0,   0,   0,   0,   0,
 | 
			
		||||
    0,	/* < ... F10 */
 | 
			
		||||
    0,	/* 69 - Num lock*/
 | 
			
		||||
    0,	/* Scroll Lock */
 | 
			
		||||
    0,	/* Home key */
 | 
			
		||||
    0,	/* Up Arrow */
 | 
			
		||||
    0,	/* Page Up */
 | 
			
		||||
  '-',
 | 
			
		||||
    0,	/* Left Arrow */
 | 
			
		||||
    0,
 | 
			
		||||
    0,	/* Right Arrow */
 | 
			
		||||
  '+',
 | 
			
		||||
    0,	/* 79 - End key*/
 | 
			
		||||
    0,	/* Down Arrow */
 | 
			
		||||
    0,	/* Page Down */
 | 
			
		||||
    0,	/* Insert Key */
 | 
			
		||||
    0,	/* Delete Key */
 | 
			
		||||
    0,   0,   0,
 | 
			
		||||
    0,	/* F11 Key */
 | 
			
		||||
    0,	/* F12 Key */
 | 
			
		||||
    0,	/* All other keys are undefined */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
unsigned char kbdus_shift[128] =
 | 
			
		||||
{
 | 
			
		||||
    0,  27, '!', '@', '#', '$', '%', '^', '&', '*',	/* 9 */
 | 
			
		||||
  '(', ')', '_', '+', '\b',	/* Backspace */
 | 
			
		||||
  '\t',			/* Tab */
 | 
			
		||||
  'Q', 'W', 'E', 'R',	/* 19 */
 | 
			
		||||
  'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n',	/* Enter key */
 | 
			
		||||
    0,			/* 29   - Control */
 | 
			
		||||
  'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':',	/* 39 */
 | 
			
		||||
 '\"', '~',   0,		/* Left shift */
 | 
			
		||||
 '|', 'Z', 'X', 'C', 'V', 'B', 'N',			/* 49 */
 | 
			
		||||
  'M', '<', '>', '?',   0,				/* Right shift */
 | 
			
		||||
  '*',
 | 
			
		||||
    0,	/* Alt */
 | 
			
		||||
  ' ',	/* Space bar */
 | 
			
		||||
    0,	/* Caps lock */
 | 
			
		||||
    0,	/* 59 - F1 key ... > */
 | 
			
		||||
    0,   0,   0,   0,   0,   0,   0,   0,
 | 
			
		||||
    0,	/* < ... F10 */
 | 
			
		||||
    0,	/* 69 - Num lock*/
 | 
			
		||||
    0,	/* Scroll Lock */
 | 
			
		||||
    0,	/* Home key */
 | 
			
		||||
    0,	/* Up Arrow */
 | 
			
		||||
    0,	/* Page Up */
 | 
			
		||||
  '-',
 | 
			
		||||
    0,	/* Left Arrow */
 | 
			
		||||
    0,
 | 
			
		||||
    0,	/* Right Arrow */
 | 
			
		||||
  '+',
 | 
			
		||||
    0,	/* 79 - End key*/
 | 
			
		||||
    0,	/* Down Arrow */
 | 
			
		||||
    0,	/* Page Down */
 | 
			
		||||
    0,	/* Insert Key */
 | 
			
		||||
    0,	/* Delete Key */
 | 
			
		||||
    0,   0,   0,
 | 
			
		||||
    0,	/* F11 Key */
 | 
			
		||||
    0,	/* F12 Key */
 | 
			
		||||
    0,	/* All other keys are undefined */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* kb_modifier_status:
 | 
			
		||||
    BIT |    Description
 | 
			
		||||
    ----+-----------------------------------
 | 
			
		||||
     0  | Left Shift
 | 
			
		||||
     1  | Right Shift
 | 
			
		||||
     2  | Left Alt
 | 
			
		||||
     3  | Right Alt
 | 
			
		||||
     4  | Left CTRL
 | 
			
		||||
     5  | Right CTRL
 | 
			
		||||
     6  | Fake Shift
 | 
			
		||||
     7  | Special     */
 | 
			
		||||
unsigned char kb_modifier_status;
 | 
			
		||||
 | 
			
		||||
/* kb_lights_status
 | 
			
		||||
    BIT |    Description
 | 
			
		||||
    ----+-----------------------------------
 | 
			
		||||
     0  | SCROLLOCK
 | 
			
		||||
     1  | NUMLOCK
 | 
			
		||||
     2  | CAPSLOCK */
 | 
			
		||||
unsigned char kb_lights_status;
 | 
			
		||||
 | 
			
		||||
void kb_update_LED()
 | 
			
		||||
{
 | 
			
		||||
    while ((inportb (0x64)&2)!=0);
 | 
			
		||||
    outportb (0x60, 0xED);
 | 
			
		||||
  
 | 
			
		||||
    while ((inportb (0x64)&2)!=0);
 | 
			
		||||
    outportb (0x60, kb_lights_status);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* kb_toggle_LED
 | 
			
		||||
 Toggle NUM/CAPS/SCROLL LOCK LEDs. 0 to ignore. If all 0, reset; */
 | 
			
		||||
void kb_toggle_LED(int NUM, int CAPS, int SCROLL)
 | 
			
		||||
{
 | 
			
		||||
      if (NUM) kb_lights_status ^= 1<<1;
 | 
			
		||||
      if (CAPS) kb_lights_status ^= 1<<2;
 | 
			
		||||
      if (SCROLL) kb_lights_status ^= 1;
 | 
			
		||||
      if ((!NUM) && (!CAPS) && (!SCROLL)) kb_lights_status = 0;
 | 
			
		||||
      kb_update_LED();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
byte prev, scancode;
 | 
			
		||||
void kb_handler(regs *r) {
 | 
			
		||||
      scancode = inportb(0x60);
 | 
			
		||||
     
 | 
			
		||||
      puts_pos(0, 0, "Key Pressed ");put_hex(30, 0, scancode);
 | 
			
		||||
 | 
			
		||||
      switch (scancode) {
 | 
			
		||||
        // Special
 | 
			
		||||
        case 0x0E: kb_modifier_status |= 1<<7;
 | 
			
		||||
                    break;
 | 
			
		||||
            
 | 
			
		||||
        // Left Shift or fake shift make
 | 
			
		||||
        case 0x2A: if (kb_modifier_status && 128) kb_modifier_status |= 1<<6;
 | 
			
		||||
                    else kb_modifier_status |= 1;
 | 
			
		||||
                    break;
 | 
			
		||||
                    
 | 
			
		||||
        // Left Shift or fake shift release
 | 
			
		||||
        case 0xAA: if (kb_modifier_status && 128) kb_modifier_status &= (1<<6) ^0xFF;
 | 
			
		||||
                    else kb_modifier_status &= 1 ^0xFF;
 | 
			
		||||
                    break;
 | 
			
		||||
                    
 | 
			
		||||
        // Right Shift make
 | 
			
		||||
        case 0x36: kb_modifier_status |= 1<<1;
 | 
			
		||||
                    break;
 | 
			
		||||
        
 | 
			
		||||
        // Right shift release
 | 
			
		||||
        case 0xB6: kb_modifier_status &= (1<<1) ^0xFF;
 | 
			
		||||
                    break;
 | 
			
		||||
                    
 | 
			
		||||
        // Left Alt or Right Alt make
 | 
			
		||||
        case 0x38: if (kb_modifier_status && 128) kb_modifier_status |= 1<<3;
 | 
			
		||||
                    else kb_modifier_status |= 1<<2;
 | 
			
		||||
                    break;
 | 
			
		||||
        
 | 
			
		||||
        // Left Alt or Right Alt release            
 | 
			
		||||
        case 0xB8: if (kb_modifier_status && 128) kb_modifier_status &= (1<<3) ^0xFF;
 | 
			
		||||
                    else kb_modifier_status &= (1<<2) ^0xFF;
 | 
			
		||||
                    break;
 | 
			
		||||
                    
 | 
			
		||||
        // Left Ctrl or Right Ctrl make
 | 
			
		||||
        case 0x1D: if (kb_modifier_status && 128) kb_modifier_status |= 1<<5;
 | 
			
		||||
                    else kb_modifier_status |= 1<<4;
 | 
			
		||||
                    break;
 | 
			
		||||
                    
 | 
			
		||||
        // Left Ctrl or Right Ctrl release
 | 
			
		||||
        case 0x9D: if (kb_modifier_status && 128) kb_modifier_status &= (1<<5) ^0xFF;
 | 
			
		||||
                    else kb_modifier_status &= (1<<5) ^0xFF;
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
        // Caps, Num and Scroll (in this order)
 | 
			
		||||
        case 0x3A: kb_toggle_LED (0,1,0); break;
 | 
			
		||||
        case 0x45: kb_toggle_LED (1,0,0); break;
 | 
			
		||||
        case 0x46: kb_toggle_LED (0,0,1); break;
 | 
			
		||||
 | 
			
		||||
        default: if (scancode & 0x80) break;
 | 
			
		||||
                  if (scancode != prev) kb_modifier_status &= (1<<7) ^0xFF;
 | 
			
		||||
                  if ((kb_modifier_status && 1) || (kb_modifier_status && 2))
 | 
			
		||||
                        putc_pos(50, 0, kbdus_shift[scancode]);
 | 
			
		||||
                  else putc_pos (50, 0, kbdus[scancode]);
 | 
			
		||||
                  break;
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      outportb(0x20, 0x20);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
char kb_getch()
 | 
			
		||||
{
 | 
			
		||||
      regs *r = 0;
 | 
			
		||||
      do {
 | 
			
		||||
            prev = scancode; kb_handler(r); }
 | 
			
		||||
      while (prev == scancode || prev+0x80 == scancode);
 | 
			
		||||
      
 | 
			
		||||
            
 | 
			
		||||
      if ((kb_modifier_status && 1) || (kb_modifier_status && 2))
 | 
			
		||||
                  return kbdus_shift[scancode];
 | 
			
		||||
 | 
			
		||||
      return kbdus[scancode];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void kb_get_status()
 | 
			
		||||
{
 | 
			
		||||
      byte a = inportb(0x64);
 | 
			
		||||
      puts_pos(0, 8, "KeyBrd Status: ");
 | 
			
		||||
      put_bin(0, 9, a);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										25
									
								
								link.ld
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								link.ld
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
OUTPUT_FORMAT("binary")
 | 
			
		||||
ENTRY(start)
 | 
			
		||||
phys = 0x00100000;
 | 
			
		||||
SECTIONS
 | 
			
		||||
{
 | 
			
		||||
  .text phys : AT(phys) {
 | 
			
		||||
    code = .;
 | 
			
		||||
    *(.text)
 | 
			
		||||
    *(.rodata)
 | 
			
		||||
    . = ALIGN(4096);
 | 
			
		||||
  }
 | 
			
		||||
  .data : AT(phys + (data - code))
 | 
			
		||||
  {
 | 
			
		||||
    data = .;
 | 
			
		||||
    *(.data)
 | 
			
		||||
    . = ALIGN(4096);
 | 
			
		||||
  }
 | 
			
		||||
  .bss : AT(phys + (bss - code))
 | 
			
		||||
  {
 | 
			
		||||
    bss = .;
 | 
			
		||||
    *(.bss)
 | 
			
		||||
    . = ALIGN(4096);
 | 
			
		||||
  }
 | 
			
		||||
  end = .;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										449
									
								
								loader.asm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										449
									
								
								loader.asm
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,449 @@
 | 
			
		||||
[BITS 32]
 | 
			
		||||
global start
 | 
			
		||||
start:      mov esp, _sys_stack  ; This points the stack to our new stack area
 | 
			
		||||
            jmp stublet
 | 
			
		||||
       
 | 
			
		||||
            
 | 
			
		||||
; This part MUST be 4byte aligned, so we solve that issue using 'ALIGN 4'
 | 
			
		||||
ALIGN 4
 | 
			
		||||
mboot:
 | 
			
		||||
    ; Multiboot macros to make a few lines later more readable
 | 
			
		||||
    MULTIBOOT_PAGE_ALIGN	equ 1<<0
 | 
			
		||||
    MULTIBOOT_MEMORY_INFO	equ 1<<1
 | 
			
		||||
    MULTIBOOT_AOUT_KLUDGE	equ 1<<16
 | 
			
		||||
    MULTIBOOT_HEADER_MAGIC	equ 0x1BADB002
 | 
			
		||||
    MULTIBOOT_HEADER_FLAGS	equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO | MULTIBOOT_AOUT_KLUDGE
 | 
			
		||||
    MULTIBOOT_CHECKSUM	equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
 | 
			
		||||
    EXTERN code, bss, end
 | 
			
		||||
 | 
			
		||||
    ; This is the GRUB Multiboot header. A boot signature
 | 
			
		||||
    dd MULTIBOOT_HEADER_MAGIC
 | 
			
		||||
    dd MULTIBOOT_HEADER_FLAGS
 | 
			
		||||
    dd MULTIBOOT_CHECKSUM
 | 
			
		||||
    
 | 
			
		||||
    ; AOUT kludge - must be physical addresses. Make a note of these:
 | 
			
		||||
    ; The linker script fills in the data for these ones!
 | 
			
		||||
    dd mboot
 | 
			
		||||
    dd code
 | 
			
		||||
    dd bss
 | 
			
		||||
    dd end
 | 
			
		||||
    dd start
 | 
			
		||||
 | 
			
		||||
; This is an endless loop here. Make a note of this: Later on, we
 | 
			
		||||
; will insert an 'extern _main', followed by 'call _main', right
 | 
			
		||||
; before the 'jmp $'.
 | 
			
		||||
stublet:
 | 
			
		||||
    extern _main
 | 
			
		||||
    call _main
 | 
			
		||||
    jmp $
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
; !!!  GDT  !!!
 | 
			
		||||
; This will set up our new segment registers. We need to do
 | 
			
		||||
; something special in order to set CS. We do what is called a
 | 
			
		||||
; far jump. A jump that includes a segment as well as an offset.
 | 
			
		||||
; This is declared in C as 'extern void gdt_flush();'
 | 
			
		||||
 | 
			
		||||
global _gdt_flush     ; Allows the C code to link to this
 | 
			
		||||
extern _gp            ; Says that '_gp' is in another file
 | 
			
		||||
_gdt_flush:
 | 
			
		||||
    lgdt [_gp]        ; Load the GDT with our '_gp' which is a special pointer
 | 
			
		||||
    mov ax, 0x10      ; 0x10 is the offset in the GDT to our data segment
 | 
			
		||||
    mov ds, ax
 | 
			
		||||
    mov es, ax
 | 
			
		||||
    mov fs, ax
 | 
			
		||||
    mov gs, ax
 | 
			
		||||
    mov ss, ax
 | 
			
		||||
    jmp 0x08:flush2   ; 0x08 is the offset to our code segment: Far jump!
 | 
			
		||||
flush2:
 | 
			
		||||
    ret               ; Returns back to the C code!
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
; !!!  IDT  !!!
 | 
			
		||||
; Loads the IDT defined in '_idtp'
 | 
			
		||||
global _idt_load
 | 
			
		||||
extern _idtp
 | 
			
		||||
_idt_load:
 | 
			
		||||
      lidt [_idtp]
 | 
			
		||||
      ret
 | 
			
		||||
      
 | 
			
		||||
; !!!  ISRs  !!!
 | 
			
		||||
global _isr0
 | 
			
		||||
global _isr1
 | 
			
		||||
global _isr2
 | 
			
		||||
global _isr3
 | 
			
		||||
global _isr4
 | 
			
		||||
global _isr5
 | 
			
		||||
global _isr6
 | 
			
		||||
global _isr7
 | 
			
		||||
global _isr8
 | 
			
		||||
global _isr9
 | 
			
		||||
global _isr10
 | 
			
		||||
global _isr11
 | 
			
		||||
global _isr12
 | 
			
		||||
global _isr13
 | 
			
		||||
global _isr14
 | 
			
		||||
global _isr15
 | 
			
		||||
global _isr16
 | 
			
		||||
global _isr17
 | 
			
		||||
global _isr18
 | 
			
		||||
global _isr19
 | 
			
		||||
global _isr20
 | 
			
		||||
global _isr21
 | 
			
		||||
global _isr22
 | 
			
		||||
global _isr23
 | 
			
		||||
global _isr24
 | 
			
		||||
global _isr25
 | 
			
		||||
global _isr26
 | 
			
		||||
global _isr27
 | 
			
		||||
global _isr28
 | 
			
		||||
global _isr29
 | 
			
		||||
global _isr30
 | 
			
		||||
global _isr31
 | 
			
		||||
 | 
			
		||||
_isr0:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0; A normal ISR stub that pops a dummy error code to keep a
 | 
			
		||||
                   ; uniform stack frame
 | 
			
		||||
      push byte 0
 | 
			
		||||
      jmp isr_common_stub
 | 
			
		||||
_isr1:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 1
 | 
			
		||||
      jmp isr_common_stub
 | 
			
		||||
_isr2:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 2
 | 
			
		||||
      jmp isr_common_stub
 | 
			
		||||
_isr3:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 3
 | 
			
		||||
      jmp isr_common_stub
 | 
			
		||||
_isr4:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 4
 | 
			
		||||
      jmp isr_common_stub
 | 
			
		||||
_isr5:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 5
 | 
			
		||||
      jmp isr_common_stub
 | 
			
		||||
_isr6:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 6
 | 
			
		||||
      jmp isr_common_stub
 | 
			
		||||
_isr7:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 7
 | 
			
		||||
      jmp isr_common_stub
 | 
			
		||||
_isr8:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 8
 | 
			
		||||
      jmp isr_common_stub
 | 
			
		||||
_isr9:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 9
 | 
			
		||||
      jmp isr_common_stub      
 | 
			
		||||
_isr10:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 10
 | 
			
		||||
      jmp isr_common_stub
 | 
			
		||||
_isr11:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 11
 | 
			
		||||
      jmp isr_common_stub
 | 
			
		||||
_isr12:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 12
 | 
			
		||||
      jmp isr_common_stub
 | 
			
		||||
_isr13:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 13
 | 
			
		||||
      jmp isr_common_stub
 | 
			
		||||
_isr14:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 14
 | 
			
		||||
      jmp isr_common_stub
 | 
			
		||||
_isr15:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 15
 | 
			
		||||
      jmp isr_common_stub
 | 
			
		||||
_isr16:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 16
 | 
			
		||||
      jmp isr_common_stub
 | 
			
		||||
_isr17:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 17
 | 
			
		||||
      jmp isr_common_stub      
 | 
			
		||||
_isr18:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 18
 | 
			
		||||
      jmp isr_common_stub      
 | 
			
		||||
_isr19:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 19
 | 
			
		||||
      jmp isr_common_stub      
 | 
			
		||||
_isr20:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 20
 | 
			
		||||
      jmp isr_common_stub      
 | 
			
		||||
_isr21:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 21
 | 
			
		||||
      jmp isr_common_stub      
 | 
			
		||||
_isr22:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 22
 | 
			
		||||
      jmp isr_common_stub      
 | 
			
		||||
_isr23:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 23
 | 
			
		||||
      jmp isr_common_stub      
 | 
			
		||||
_isr24:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 24
 | 
			
		||||
      jmp isr_common_stub      
 | 
			
		||||
_isr25:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 25
 | 
			
		||||
      jmp isr_common_stub      
 | 
			
		||||
_isr26:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 26
 | 
			
		||||
      jmp isr_common_stub      
 | 
			
		||||
_isr27:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 27
 | 
			
		||||
      jmp isr_common_stub      
 | 
			
		||||
_isr28:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 28
 | 
			
		||||
      jmp isr_common_stub      
 | 
			
		||||
_isr29:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 29
 | 
			
		||||
      jmp isr_common_stub      
 | 
			
		||||
_isr30:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 30
 | 
			
		||||
      jmp isr_common_stub      
 | 
			
		||||
_isr31:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 31
 | 
			
		||||
      jmp isr_common_stub      
 | 
			
		||||
            
 | 
			
		||||
extern _fault_handler
 | 
			
		||||
 | 
			
		||||
isr_common_stub:
 | 
			
		||||
    pusha
 | 
			
		||||
    push ds
 | 
			
		||||
    push es
 | 
			
		||||
    push fs
 | 
			
		||||
    push gs
 | 
			
		||||
    mov ax, 0x10   ; Load the Kernel Data Segment descriptor!
 | 
			
		||||
    mov ds, ax
 | 
			
		||||
    mov es, ax
 | 
			
		||||
    mov fs, ax
 | 
			
		||||
    mov gs, ax
 | 
			
		||||
    mov eax, esp   ; Push us the stack
 | 
			
		||||
    push eax
 | 
			
		||||
    mov eax, _fault_handler
 | 
			
		||||
    call eax       ; A special call, preserves the 'eip' register
 | 
			
		||||
    pop eax
 | 
			
		||||
    pop gs
 | 
			
		||||
    pop fs
 | 
			
		||||
    pop es
 | 
			
		||||
    pop ds
 | 
			
		||||
    popa
 | 
			
		||||
    add esp, 8     ; Cleans up the pushed error code and pushed ISR number
 | 
			
		||||
    iret           ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP!
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
; !!!  IRQ !!!
 | 
			
		||||
global _irq0
 | 
			
		||||
global _irq1
 | 
			
		||||
global _irq2
 | 
			
		||||
global _irq3
 | 
			
		||||
global _irq4
 | 
			
		||||
global _irq5
 | 
			
		||||
global _irq6
 | 
			
		||||
global _irq7
 | 
			
		||||
global _irq8
 | 
			
		||||
global _irq9
 | 
			
		||||
global _irq10
 | 
			
		||||
global _irq11
 | 
			
		||||
global _irq12
 | 
			
		||||
global _irq13
 | 
			
		||||
global _irq14
 | 
			
		||||
global _irq15
 | 
			
		||||
 | 
			
		||||
; 32: IRQ0
 | 
			
		||||
_irq0:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 32; Note that these don't push an error code on the stack:
 | 
			
		||||
                   ; We need to push a dummy error code
 | 
			
		||||
      jmp irq_common_stub
 | 
			
		||||
 | 
			
		||||
; 33: IRQ1
 | 
			
		||||
_irq1:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 33
 | 
			
		||||
      jmp irq_common_stub
 | 
			
		||||
 | 
			
		||||
; 34: IRQ2
 | 
			
		||||
_irq2:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 34
 | 
			
		||||
      jmp irq_common_stub
 | 
			
		||||
      
 | 
			
		||||
; 35: IRQ3
 | 
			
		||||
_irq3:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 35
 | 
			
		||||
      jmp irq_common_stub
 | 
			
		||||
 | 
			
		||||
; 36: IRQ4
 | 
			
		||||
_irq4:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 36
 | 
			
		||||
      jmp irq_common_stub
 | 
			
		||||
 | 
			
		||||
; 37: IRQ5
 | 
			
		||||
_irq5:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 37
 | 
			
		||||
      jmp irq_common_stub
 | 
			
		||||
 | 
			
		||||
; 38: IRQ6
 | 
			
		||||
_irq6:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 38
 | 
			
		||||
      jmp irq_common_stub
 | 
			
		||||
      
 | 
			
		||||
; 39: IRQ7
 | 
			
		||||
_irq7:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 39
 | 
			
		||||
      jmp irq_common_stub
 | 
			
		||||
 | 
			
		||||
; 40: IRQ8
 | 
			
		||||
_irq8:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 40
 | 
			
		||||
      jmp irq_common_stub      
 | 
			
		||||
; 41: IRQ9
 | 
			
		||||
_irq9:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 41
 | 
			
		||||
      jmp irq_common_stub
 | 
			
		||||
 | 
			
		||||
; 42: IRQ10
 | 
			
		||||
_irq10:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 42
 | 
			
		||||
      jmp irq_common_stub
 | 
			
		||||
      
 | 
			
		||||
; 43: IRQ11
 | 
			
		||||
_irq11:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 43
 | 
			
		||||
      jmp irq_common_stub
 | 
			
		||||
 | 
			
		||||
; 44: IRQ12
 | 
			
		||||
_irq12:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 44
 | 
			
		||||
      jmp irq_common_stub
 | 
			
		||||
      
 | 
			
		||||
; 45: IRQ13
 | 
			
		||||
_irq13:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 45
 | 
			
		||||
      jmp irq_common_stub
 | 
			
		||||
 | 
			
		||||
; 46: IRQ14
 | 
			
		||||
_irq14:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 46
 | 
			
		||||
      jmp irq_common_stub
 | 
			
		||||
      
 | 
			
		||||
; 47: IRQ15
 | 
			
		||||
_irq15:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 47
 | 
			
		||||
      jmp irq_common_stub
 | 
			
		||||
 | 
			
		||||
extern _irq_handler
 | 
			
		||||
 | 
			
		||||
; This is a stub that we have created for IRQ based ISRs. This calls
 | 
			
		||||
; '_irq_handler' in our C code. We need to create this in an 'irq.c'
 | 
			
		||||
irq_common_stub:
 | 
			
		||||
      pusha
 | 
			
		||||
      push ds
 | 
			
		||||
      push es
 | 
			
		||||
      push fs
 | 
			
		||||
      push gs
 | 
			
		||||
      mov ax, 0x10
 | 
			
		||||
      mov ds, ax
 | 
			
		||||
      mov es, ax
 | 
			
		||||
      mov fs, ax
 | 
			
		||||
      mov gs, ax
 | 
			
		||||
      mov eax, esp
 | 
			
		||||
      push eax
 | 
			
		||||
      mov eax, _irq_handler
 | 
			
		||||
      call eax
 | 
			
		||||
      pop eax
 | 
			
		||||
      pop gs
 | 
			
		||||
      pop fs
 | 
			
		||||
      pop es
 | 
			
		||||
      pop ds
 | 
			
		||||
      popa
 | 
			
		||||
      add esp, 8
 | 
			
		||||
      iret
 | 
			
		||||
      
 | 
			
		||||
      
 | 
			
		||||
      
 | 
			
		||||
SECTION .bss
 | 
			
		||||
    resb 8192               ; This reserves 8KBytes of memory here
 | 
			
		||||
_sys_stack:
 | 
			
		||||
							
								
								
									
										65
									
								
								main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								main.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,65 @@
 | 
			
		||||
#include <system.h>
 | 
			
		||||
#include <console.h>
 | 
			
		||||
#include "gdt.c"
 | 
			
		||||
#include "idt.c"
 | 
			
		||||
#include "isrs.c"
 | 
			
		||||
#include "irq.c"
 | 
			
		||||
#include "timer.c"
 | 
			
		||||
#include "keyus.c"
 | 
			
		||||
#include "init.c"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*void put_line_scroll(int line, char c)
 | 
			
		||||
{
 | 
			
		||||
      int i = 0;
 | 
			
		||||
      while (TextVideoRam[2*(80*line+i)] != 0 && i<=80) ++i;
 | 
			
		||||
      if (i>78) {
 | 
			
		||||
            memcpy(TextVideoRam + (2*80*line), TextVideoRam + (2*80*line) + 2, (i+1)*2);
 | 
			
		||||
            }
 | 
			
		||||
      putc_pos(i, line, c);
 | 
			
		||||
}*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
      system_init();
 | 
			
		||||
      set_default_colors (0x07, 0x04);
 | 
			
		||||
      clrscr();
 | 
			
		||||
      
 | 
			
		||||
      int i;
 | 
			
		||||
      for (i=0;i<80;i++) putc_pos_font (i, 0, ' ', 0x02, 0x0F);
 | 
			
		||||
      puts_pos_font (60, 0, "Uptime:", 0x02, 0x0E); cursor_y++;
 | 
			
		||||
 | 
			
		||||
      // Do other stuff
 | 
			
		||||
      puts ("Testing puts...\nAnd this shoudl be new line\n");
 | 
			
		||||
      puts_font ("And this should be colored in another color ", 0x02, 0x0F);
 | 
			
		||||
      puts ("<- colored font should be right about heree");
 | 
			
		||||
      
 | 
			
		||||
      puts_pos (0, 23, "This text should be starting in position (0, 23)");
 | 
			
		||||
      puts_pos_font (0, 23, "THIS", 0x00, 0x09);
 | 
			
		||||
      
 | 
			
		||||
      puts_pos (5, 20, "<- The cursor should be blinking right here");
 | 
			
		||||
      putc_pos_font (3, 20, 0, 0x04, 0x0F);
 | 
			
		||||
      text_mode_cursor(3, 20);     
 | 
			
		||||
 | 
			
		||||
      
 | 
			
		||||
      while (1) {
 | 
			
		||||
            kb_get_status();
 | 
			
		||||
 | 
			
		||||
            put_bin(60, 15, kb_modifier_status);
 | 
			
		||||
            puts_pos_font (60, 16, "LShift", 0x07, 0x08 - (kb_modifier_status&1)*0x06);
 | 
			
		||||
            puts_pos_font (60, 17, "RShift", 0x07, 0x08 - (kb_modifier_status&2)*0x06);
 | 
			
		||||
            puts_pos_font (60, 18, "LAlt", 0x07, 0x08 - (kb_modifier_status&4)*0x06);
 | 
			
		||||
            puts_pos_font (60, 19, "RAlt", 0x07, 0x08 - (kb_modifier_status&8)*0x06);
 | 
			
		||||
            puts_pos_font (60, 20, "LCtrl", 0x07, 0x08 - (kb_modifier_status&16)*0x06);
 | 
			
		||||
            puts_pos_font (60, 21, "RCtrl", 0x07, 0x08 - (kb_modifier_status&32)*0x06);
 | 
			
		||||
            puts_pos_font (60, 22, "FakeShift", 0x07, 0x08 - (kb_modifier_status&64)*0x06);
 | 
			
		||||
            puts_pos_font (60, 23, "Special", 0x07, 0x08 - (kb_modifier_status&128)*0x06);
 | 
			
		||||
            
 | 
			
		||||
            putc (kb_getch());
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      // do nothing
 | 
			
		||||
      for(;;);
 | 
			
		||||
      return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										52
									
								
								timer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								timer.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
			
		||||
#include<system.h>
 | 
			
		||||
int timer_ticks = 0;
 | 
			
		||||
int timer_hz;
 | 
			
		||||
 | 
			
		||||
void timer_phase(int hz)
 | 
			
		||||
{
 | 
			
		||||
      int divisor = 1193180/hz;           // Calculate the divisor
 | 
			
		||||
      outportb(0x43, 0x36);               // Set our command byte 0x36
 | 
			
		||||
      outportb(0x40, divisor&0xFF);       // Set low byte
 | 
			
		||||
      outportb(0x40, divisor>>8);         // Set high byte
 | 
			
		||||
      timer_hz = hz;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void timer_clock (int x, int y, int secs)
 | 
			
		||||
{
 | 
			
		||||
      int s, m, h;
 | 
			
		||||
      char arr[9] = {0,0,0,0,0,0,0,0,0};
 | 
			
		||||
      
 | 
			
		||||
      s = secs%60;
 | 
			
		||||
      m = (secs/60)%60;
 | 
			
		||||
      h = secs/3600;
 | 
			
		||||
      
 | 
			
		||||
      arr[0] = (h/10)%10 + '0'; if (arr[0]=='0') arr[0] = ' ';
 | 
			
		||||
      arr[1] = h%10 + '0';
 | 
			
		||||
      
 | 
			
		||||
      arr[3] = (m/10) + '0';
 | 
			
		||||
      arr[4] = m%10 + '0';
 | 
			
		||||
      
 | 
			
		||||
      arr[6] = s/10 + '0';
 | 
			
		||||
      arr[7] = s%10 + '0';
 | 
			
		||||
      
 | 
			
		||||
      if (secs%2 == 0) {
 | 
			
		||||
            arr[2] = ' ';
 | 
			
		||||
            arr[5] = ' ';
 | 
			
		||||
            }
 | 
			
		||||
      else {
 | 
			
		||||
            arr[2] = ':';
 | 
			
		||||
            arr[5] = ':';
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
      puts_pos(x, y, arr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void timer_handler(regs *r)
 | 
			
		||||
{
 | 
			
		||||
      timer_ticks++;
 | 
			
		||||
      
 | 
			
		||||
      if (timer_ticks % timer_hz) {
 | 
			
		||||
            timer_clock (70, 0, timer_ticks / timer_hz);
 | 
			
		||||
      }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user