[GOOD] BUILD 0.1.0.450 DATE 8/29/2011 AT 10:30 AM
==================================================== + Changed 'align 0x4' line above multiboot header in loader.asm to 'align 4' + Removed -e option for echo in build.sh + Modified build.sh for linux + Fixed triple fault when enabling paging + Fixed page faults at memory manager initialization + Fixed 'mem' console function + Added more info about page fault at crash screen + Added Panic() macro + Added verbose mode for memory manager [ BAD] BUILD 0.1.0.390 DATE 8/27/2011 AT 10:54 PM ==================================================== + Added stdlib routines, separated in different files + Rewritten physical memory manager + Added virtual mem manager + Added memory allocation/freeing + Added memory library + Added temporary allocation (at end of kernel), until paging is started - Removed functionality from debug console function 'mem' - Removed system.h, the one remaining function now in stdio.h
This commit is contained in:
		
							
								
								
									
										19
									
								
								Kernel/hal/clock/clock.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								Kernel/hal/clock/clock.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include "clock.h"
 | 
			
		||||
 | 
			
		||||
#define MILISECONDS_IN_DAY 86400000
 | 
			
		||||
 | 
			
		||||
volatile TimeSystem _internal_time;
 | 
			
		||||
uint32 _internal_frequency_hz;
 | 
			
		||||
 | 
			
		||||
void TimeHandler(_RegsStack32* UNUSED(r))
 | 
			
		||||
{
 | 
			
		||||
	if (_internal_frequency_hz == 0) return;
 | 
			
		||||
 | 
			
		||||
	_internal_time.Time += 1000/_internal_frequency_hz;
 | 
			
		||||
	if (_internal_time.Time >= MILISECONDS_IN_DAY)
 | 
			
		||||
	{
 | 
			
		||||
		_internal_time.Date++;
 | 
			
		||||
		_internal_time.Time-=MILISECONDS_IN_DAY;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										9
									
								
								Kernel/hal/clock/clock.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								Kernel/hal/clock/clock.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
#ifndef __CLOCK__H
 | 
			
		||||
#define __CLOCK__H
 | 
			
		||||
 | 
			
		||||
#include <time.h>
 | 
			
		||||
 | 
			
		||||
extern void TimeHandler(_RegsStack32 *r);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										23
									
								
								Kernel/hal/cpu/gdt-asm.asm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								Kernel/hal/cpu/gdt-asm.asm
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
; GLOBAL DESCRIPTOR TABLE
 | 
			
		||||
; 
 | 
			
		||||
; 
 | 
			
		||||
 | 
			
		||||
bits 32
 | 
			
		||||
; !!!  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.
 | 
			
		||||
 | 
			
		||||
global GdtFlush     ; Allows the C code to link to this
 | 
			
		||||
extern gp            ; Says that 'gp' is in another file
 | 
			
		||||
GdtFlush:
 | 
			
		||||
    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!
 | 
			
		||||
							
								
								
									
										74
									
								
								Kernel/hal/cpu/gdt.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								Kernel/hal/cpu/gdt.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,74 @@
 | 
			
		||||
/******************************************************************
 | 
			
		||||
 *    gdt.c  -  GLOBAL DESCRIPTOR TABLE                           *
 | 
			
		||||
 *      Contains function prototypes for setting up the GDT       *
 | 
			
		||||
 ******************************************************************/
 | 
			
		||||
#define MAX_DESCRIPTORS 5
 | 
			
		||||
#include "gdt.h"
 | 
			
		||||
 | 
			
		||||
/* Our GDT, with 3 entries, and finally our special GDT pointer */
 | 
			
		||||
struct GdtEntry gdt[MAX_DESCRIPTORS];
 | 
			
		||||
struct GdtPointer gp;
 | 
			
		||||
 | 
			
		||||
		
 | 
			
		||||
/* Setup a descriptor in the Global Descriptor Table */
 | 
			
		||||
void GdtSetGate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran)
 | 
			
		||||
{
 | 
			
		||||
    /* Sanity check */
 | 
			
		||||
    if (num >= MAX_DESCRIPTORS) return;
 | 
			
		||||
    
 | 
			
		||||
    /* 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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct GdtEntry* GdtGetGate(int num)
 | 
			
		||||
{
 | 
			
		||||
      if (num>MAX_DESCRIPTORS) return 0;
 | 
			
		||||
      return &gdt[num];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 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 GdtInstall()
 | 
			
		||||
{
 | 
			
		||||
    /* Setup the GDT pointer and limit */
 | 
			
		||||
    gp.limit = (sizeof(struct GdtEntry) * 3) - 1;
 | 
			
		||||
    gp.base = (unsigned int)&gdt;
 | 
			
		||||
 | 
			
		||||
    /* Our NULL descriptor */
 | 
			
		||||
    GdtSetGate(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 */
 | 
			
		||||
    GdtSetGate(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 */
 | 
			
		||||
    GdtSetGate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
 | 
			
		||||
 | 
			
		||||
    /* User mode Code segment*/
 | 
			
		||||
    GdtSetGate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF);
 | 
			
		||||
    
 | 
			
		||||
    /* User mode data segment*/
 | 
			
		||||
    GdtSetGate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF);
 | 
			
		||||
 | 
			
		||||
    /* Flush out the old GDT and install the new changes! */
 | 
			
		||||
    GdtFlush();
 | 
			
		||||
}
 | 
			
		||||
		
 | 
			
		||||
							
								
								
									
										38
									
								
								Kernel/hal/cpu/gdt.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								Kernel/hal/cpu/gdt.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
			
		||||
/******************************************************************
 | 
			
		||||
 *    gdt.h  -  GLOBAL DESCRIPTOR TABLE                           *
 | 
			
		||||
 *      Contains structures and function declarations for GDT     *
 | 
			
		||||
 ******************************************************************/
 | 
			
		||||
 | 
			
		||||
#ifndef __GDT_H
 | 
			
		||||
#define __GDT_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 GdtEntry
 | 
			
		||||
{
 | 
			
		||||
    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 GdtPointer
 | 
			
		||||
{
 | 
			
		||||
    unsigned short limit;
 | 
			
		||||
    unsigned int base;
 | 
			
		||||
} __attribute__((packed));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* This will be a function in start.asm. We use this to properly
 | 
			
		||||
*  reload the new segment registers */
 | 
			
		||||
extern void GdtInstall();
 | 
			
		||||
extern void GdtFlush();
 | 
			
		||||
extern void GdtSetGate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran);
 | 
			
		||||
extern struct GdtEntry* GdtGetGate(int num);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										9
									
								
								Kernel/hal/cpu/idt-asm.asm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								Kernel/hal/cpu/idt-asm.asm
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
bits 32
 | 
			
		||||
 | 
			
		||||
; !!!  IDT  !!!
 | 
			
		||||
; Loads the IDT defined in '_idtp'
 | 
			
		||||
global IdtLoad
 | 
			
		||||
extern idtp
 | 
			
		||||
IdtLoad:
 | 
			
		||||
      lidt [idtp]
 | 
			
		||||
      ret
 | 
			
		||||
							
								
								
									
										45
									
								
								Kernel/hal/cpu/idt.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								Kernel/hal/cpu/idt.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
			
		||||
/******************************************************************
 | 
			
		||||
 *    idt.h  -  INTERRUPT DESCRIPTOR TABLE                        *
 | 
			
		||||
 *      Contains structures and function declarations for IDT     *
 | 
			
		||||
 ******************************************************************/
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include "idt.h"
 | 
			
		||||
 | 
			
		||||
extern void IdtLoad();
 | 
			
		||||
/* Declare an IDT of 256 entries.  */
 | 
			
		||||
struct IdtEntry idt[256];
 | 
			
		||||
struct IdtPointer idtp;
 | 
			
		||||
 | 
			
		||||
/* Use this function to set an entry in the IDT. Alot simpler
 | 
			
		||||
*  than twiddling with the GDT ;) */
 | 
			
		||||
void IdtSetGate(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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct IdtEntry* IdtGetGate(unsigned char num)
 | 
			
		||||
{
 | 
			
		||||
      return &idt[num];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Installs the IDT */
 | 
			
		||||
void IdtInstall()
 | 
			
		||||
{
 | 
			
		||||
    /* Sets the special IDT pointer up, just like in 'gdt.c' */
 | 
			
		||||
    idtp.limit = (sizeof (struct IdtEntry) * 256) - 1;
 | 
			
		||||
    idtp.base = (unsigned int)&idt;
 | 
			
		||||
 | 
			
		||||
    /* Clear out the entire IDT, initializing it to zeros */
 | 
			
		||||
    memset (&idt, 0, sizeof(struct IdtEntry) * 256);
 | 
			
		||||
 | 
			
		||||
    /* Points the processor's internal register to the new IDT */
 | 
			
		||||
    IdtLoad();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										31
									
								
								Kernel/hal/cpu/idt.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								Kernel/hal/cpu/idt.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
/******************************************************************
 | 
			
		||||
 *    idt.h  -  INTERRUPT DESCRIPTOR TABLE                        *
 | 
			
		||||
 *      Contains structures and function declarations for IDT     *
 | 
			
		||||
 ******************************************************************/
 | 
			
		||||
 | 
			
		||||
#ifndef __IDT_H
 | 
			
		||||
#define __IDT_H
 | 
			
		||||
 | 
			
		||||
/* Defines an IDT entry */
 | 
			
		||||
struct IdtEntry
 | 
			
		||||
{
 | 
			
		||||
    unsigned short base_lo;
 | 
			
		||||
    unsigned short sel;
 | 
			
		||||
    unsigned char always0;
 | 
			
		||||
    unsigned char flags;
 | 
			
		||||
    unsigned short base_hi;
 | 
			
		||||
} __attribute__((packed));
 | 
			
		||||
 | 
			
		||||
struct IdtPointer
 | 
			
		||||
{
 | 
			
		||||
    unsigned short limit;
 | 
			
		||||
    unsigned int base;
 | 
			
		||||
} __attribute__((packed));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* This exists in 'start.asm', and is used to load our IDT */
 | 
			
		||||
extern void IdtSetGate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags);
 | 
			
		||||
extern struct IdtEntry* IdtGetGate(unsigned char num);
 | 
			
		||||
extern void IdtInstall();
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										159
									
								
								Kernel/hal/cpu/irq-asm.asm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										159
									
								
								Kernel/hal/cpu/irq-asm.asm
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,159 @@
 | 
			
		||||
bits 32
 | 
			
		||||
 | 
			
		||||
; !!!  IRQ !!!
 | 
			
		||||
global Irq_0
 | 
			
		||||
global Irq_1
 | 
			
		||||
global Irq_2
 | 
			
		||||
global Irq_3
 | 
			
		||||
global Irq_4
 | 
			
		||||
global Irq_5
 | 
			
		||||
global Irq_6
 | 
			
		||||
global Irq_7
 | 
			
		||||
global Irq_8
 | 
			
		||||
global Irq_9
 | 
			
		||||
global Irq_10
 | 
			
		||||
global Irq_11
 | 
			
		||||
global Irq_12
 | 
			
		||||
global Irq_13
 | 
			
		||||
global Irq_14
 | 
			
		||||
global Irq_15
 | 
			
		||||
 | 
			
		||||
; 32: IRQ0
 | 
			
		||||
Irq_0:
 | 
			
		||||
      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
 | 
			
		||||
Irq_1:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 33
 | 
			
		||||
      jmp irq_common_stub
 | 
			
		||||
 | 
			
		||||
; 34: IRQ2
 | 
			
		||||
Irq_2:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 34
 | 
			
		||||
      jmp irq_common_stub
 | 
			
		||||
      
 | 
			
		||||
; 35: IRQ3
 | 
			
		||||
Irq_3:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 35
 | 
			
		||||
      jmp irq_common_stub
 | 
			
		||||
 | 
			
		||||
; 36: IRQ4
 | 
			
		||||
Irq_4:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 36
 | 
			
		||||
      jmp irq_common_stub
 | 
			
		||||
 | 
			
		||||
; 37: IRQ5
 | 
			
		||||
Irq_5:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 37
 | 
			
		||||
      jmp irq_common_stub
 | 
			
		||||
 | 
			
		||||
; 38: IRQ6
 | 
			
		||||
Irq_6:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 38
 | 
			
		||||
      jmp irq_common_stub
 | 
			
		||||
      
 | 
			
		||||
; 39: IRQ7
 | 
			
		||||
Irq_7:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 39
 | 
			
		||||
      jmp irq_common_stub
 | 
			
		||||
 | 
			
		||||
; 40: IRQ8
 | 
			
		||||
Irq_8:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 40
 | 
			
		||||
      jmp irq_common_stub      
 | 
			
		||||
; 41: IRQ9
 | 
			
		||||
Irq_9:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 41
 | 
			
		||||
      jmp irq_common_stub
 | 
			
		||||
 | 
			
		||||
; 42: IRQ10
 | 
			
		||||
Irq_10:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 42
 | 
			
		||||
      jmp irq_common_stub
 | 
			
		||||
      
 | 
			
		||||
; 43: IRQ11
 | 
			
		||||
Irq_11:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 43
 | 
			
		||||
      jmp irq_common_stub
 | 
			
		||||
 | 
			
		||||
; 44: IRQ12
 | 
			
		||||
Irq_12:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 44
 | 
			
		||||
      jmp irq_common_stub
 | 
			
		||||
      
 | 
			
		||||
; 45: IRQ13
 | 
			
		||||
Irq_13:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 45
 | 
			
		||||
      jmp irq_common_stub
 | 
			
		||||
 | 
			
		||||
; 46: IRQ14
 | 
			
		||||
Irq_14:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 46
 | 
			
		||||
      jmp irq_common_stub
 | 
			
		||||
      
 | 
			
		||||
; 47: IRQ15
 | 
			
		||||
Irq_15:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 47
 | 
			
		||||
      jmp irq_common_stub
 | 
			
		||||
 | 
			
		||||
extern IrqHandler
 | 
			
		||||
 | 
			
		||||
; 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, IrqHandler
 | 
			
		||||
      call eax
 | 
			
		||||
      pop eax
 | 
			
		||||
      pop gs
 | 
			
		||||
      pop fs
 | 
			
		||||
      pop es
 | 
			
		||||
      pop ds
 | 
			
		||||
      popa
 | 
			
		||||
      add esp, 8
 | 
			
		||||
      iret
 | 
			
		||||
							
								
								
									
										91
									
								
								Kernel/hal/cpu/irq.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								Kernel/hal/cpu/irq.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,91 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include "pic.h"
 | 
			
		||||
#include "irq.h"
 | 
			
		||||
#include "idt.h"
 | 
			
		||||
 | 
			
		||||
/* These are own ISRs that point to our special IRQ handler
 | 
			
		||||
*  instead of the regular 'fault_handler' function */
 | 
			
		||||
extern void Irq_0();
 | 
			
		||||
extern void Irq_1();
 | 
			
		||||
extern void Irq_2();
 | 
			
		||||
extern void Irq_3();
 | 
			
		||||
extern void Irq_4();
 | 
			
		||||
extern void Irq_5();
 | 
			
		||||
extern void Irq_6();
 | 
			
		||||
extern void Irq_7();
 | 
			
		||||
extern void Irq_8();
 | 
			
		||||
extern void Irq_9();
 | 
			
		||||
extern void Irq_10();
 | 
			
		||||
extern void Irq_11();
 | 
			
		||||
extern void Irq_12();
 | 
			
		||||
extern void Irq_13();
 | 
			
		||||
extern void Irq_14();
 | 
			
		||||
extern void Irq_15();
 | 
			
		||||
 | 
			
		||||
/* This array is actually an array of function pointers. We use
 | 
			
		||||
*  this to handle custom IRQ handlers for a given IRQ */
 | 
			
		||||
void *IrqRoutines[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 IrqInstallHandler (int irq, void (*handler)(_RegsStack32 *r))
 | 
			
		||||
{
 | 
			
		||||
      IrqRoutines[irq] = handler;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IrqUninstallHandler (int irq)
 | 
			
		||||
{
 | 
			
		||||
      IrqRoutines[irq] = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* 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 IrqInstall()
 | 
			
		||||
{
 | 
			
		||||
      PicRemap(32,40);
 | 
			
		||||
      
 | 
			
		||||
      IdtSetGate(32, (unsigned)Irq_0, 0x08, 0x8E);
 | 
			
		||||
      IdtSetGate(33, (unsigned)Irq_1, 0x08, 0x8E);
 | 
			
		||||
      IdtSetGate(34, (unsigned)Irq_2, 0x08, 0x8E);
 | 
			
		||||
      IdtSetGate(35, (unsigned)Irq_3, 0x08, 0x8E);
 | 
			
		||||
      IdtSetGate(36, (unsigned)Irq_4, 0x08, 0x8E);
 | 
			
		||||
      IdtSetGate(37, (unsigned)Irq_5, 0x08, 0x8E);
 | 
			
		||||
      IdtSetGate(38, (unsigned)Irq_6, 0x08, 0x8E);
 | 
			
		||||
      IdtSetGate(39, (unsigned)Irq_7, 0x08, 0x8E);
 | 
			
		||||
      IdtSetGate(40, (unsigned)Irq_8, 0x08, 0x8E);
 | 
			
		||||
      IdtSetGate(41, (unsigned)Irq_9, 0x08, 0x8E);
 | 
			
		||||
      IdtSetGate(42, (unsigned)Irq_10, 0x08, 0x8E);
 | 
			
		||||
      IdtSetGate(43, (unsigned)Irq_11, 0x08, 0x8E);
 | 
			
		||||
      IdtSetGate(44, (unsigned)Irq_12, 0x08, 0x8E);
 | 
			
		||||
      IdtSetGate(45, (unsigned)Irq_13, 0x08, 0x8E);
 | 
			
		||||
      IdtSetGate(46, (unsigned)Irq_14, 0x08, 0x8E);
 | 
			
		||||
      IdtSetGate(47, (unsigned)Irq_15, 0x08, 0x8E);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Default IRQ handler, launches other handler if installed.
 | 
			
		||||
// Also sends end-of-interrupt messages to PIC
 | 
			
		||||
void IrqHandler (_RegsStack32 *r)
 | 
			
		||||
{
 | 
			
		||||
	/* This is a blank function pointer */
 | 
			
		||||
      void (*handler)(_RegsStack32 *r);
 | 
			
		||||
      
 | 
			
		||||
    /* Find out if we have a custom handler to run for this
 | 
			
		||||
    *  IRQ, and then finally, run it */
 | 
			
		||||
      handler = IrqRoutines[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(0xA0, 0x20);
 | 
			
		||||
      
 | 
			
		||||
    /* In either case, we need to send an EOI to the master
 | 
			
		||||
    *  interrupt controller too */
 | 
			
		||||
      outportb(0x20, 0x20);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										10
									
								
								Kernel/hal/cpu/irq.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								Kernel/hal/cpu/irq.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
#ifndef __IRQ_H
 | 
			
		||||
#define __IRQ_H
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
extern void IrqInstallHandler (int irq, void (*handler)(_RegsStack32 *r));
 | 
			
		||||
extern void IrqUninstallHandler (int irq);
 | 
			
		||||
extern void IrqInstall();
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										217
									
								
								Kernel/hal/cpu/isrs-asm.asm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										217
									
								
								Kernel/hal/cpu/isrs-asm.asm
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,217 @@
 | 
			
		||||
bits 32
 | 
			
		||||
 | 
			
		||||
; !!!  ISRs  !!!
 | 
			
		||||
global isr_exception_0
 | 
			
		||||
global isr_exception_1
 | 
			
		||||
global isr_exception_2
 | 
			
		||||
global isr_exception_3
 | 
			
		||||
global isr_exception_4
 | 
			
		||||
global isr_exception_5
 | 
			
		||||
global isr_exception_6
 | 
			
		||||
global isr_exception_7
 | 
			
		||||
global isr_exception_8
 | 
			
		||||
global isr_exception_9
 | 
			
		||||
global isr_exception_10
 | 
			
		||||
global isr_exception_11
 | 
			
		||||
global isr_exception_12
 | 
			
		||||
global isr_exception_13
 | 
			
		||||
global isr_exception_14
 | 
			
		||||
global isr_exception_15
 | 
			
		||||
global isr_exception_16
 | 
			
		||||
global isr_exception_17
 | 
			
		||||
global isr_exception_18
 | 
			
		||||
global isr_exception_19
 | 
			
		||||
global isr_exception_20
 | 
			
		||||
global isr_exception_21
 | 
			
		||||
global isr_exception_22
 | 
			
		||||
global isr_exception_23
 | 
			
		||||
global isr_exception_24
 | 
			
		||||
global isr_exception_25
 | 
			
		||||
global isr_exception_26
 | 
			
		||||
global isr_exception_27
 | 
			
		||||
global isr_exception_28
 | 
			
		||||
global isr_exception_29
 | 
			
		||||
global isr_exception_30
 | 
			
		||||
global isr_exception_31
 | 
			
		||||
 | 
			
		||||
isr_exception_0:
 | 
			
		||||
      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
 | 
			
		||||
isr_exception_1:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 1
 | 
			
		||||
      jmp isr_common_stub
 | 
			
		||||
isr_exception_2:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 2
 | 
			
		||||
      jmp isr_common_stub
 | 
			
		||||
isr_exception_3:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 3
 | 
			
		||||
      jmp isr_common_stub
 | 
			
		||||
isr_exception_4:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 4
 | 
			
		||||
      jmp isr_common_stub
 | 
			
		||||
isr_exception_5:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 5
 | 
			
		||||
      jmp isr_common_stub
 | 
			
		||||
isr_exception_6:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 6
 | 
			
		||||
      jmp isr_common_stub
 | 
			
		||||
isr_exception_7:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 7
 | 
			
		||||
      jmp isr_common_stub
 | 
			
		||||
isr_exception_8:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 8
 | 
			
		||||
      jmp isr_common_stub
 | 
			
		||||
isr_exception_9:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 9
 | 
			
		||||
      jmp isr_common_stub      
 | 
			
		||||
isr_exception_10:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 10
 | 
			
		||||
      jmp isr_common_stub
 | 
			
		||||
isr_exception_11:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 11
 | 
			
		||||
      jmp isr_common_stub
 | 
			
		||||
isr_exception_12:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 12
 | 
			
		||||
      jmp isr_common_stub
 | 
			
		||||
isr_exception_13:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 13
 | 
			
		||||
      jmp isr_common_stub
 | 
			
		||||
isr_exception_14:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 14
 | 
			
		||||
      jmp isr_common_stub
 | 
			
		||||
isr_exception_15:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 15
 | 
			
		||||
      jmp isr_common_stub
 | 
			
		||||
isr_exception_16:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 16
 | 
			
		||||
      jmp isr_common_stub
 | 
			
		||||
isr_exception_17:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 17
 | 
			
		||||
      jmp isr_common_stub      
 | 
			
		||||
isr_exception_18:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 18
 | 
			
		||||
      jmp isr_common_stub      
 | 
			
		||||
isr_exception_19:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 19
 | 
			
		||||
      jmp isr_common_stub      
 | 
			
		||||
isr_exception_20:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 20
 | 
			
		||||
      jmp isr_common_stub      
 | 
			
		||||
isr_exception_21:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 21
 | 
			
		||||
      jmp isr_common_stub      
 | 
			
		||||
isr_exception_22:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 22
 | 
			
		||||
      jmp isr_common_stub      
 | 
			
		||||
isr_exception_23:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 23
 | 
			
		||||
      jmp isr_common_stub      
 | 
			
		||||
isr_exception_24:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 24
 | 
			
		||||
      jmp isr_common_stub      
 | 
			
		||||
isr_exception_25:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 25
 | 
			
		||||
      jmp isr_common_stub      
 | 
			
		||||
isr_exception_26:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 26
 | 
			
		||||
      jmp isr_common_stub      
 | 
			
		||||
isr_exception_27:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 27
 | 
			
		||||
      jmp isr_common_stub      
 | 
			
		||||
isr_exception_28:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 28
 | 
			
		||||
      jmp isr_common_stub      
 | 
			
		||||
isr_exception_29:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 29
 | 
			
		||||
      jmp isr_common_stub      
 | 
			
		||||
isr_exception_30:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 30
 | 
			
		||||
      jmp isr_common_stub      
 | 
			
		||||
isr_exception_31:
 | 
			
		||||
      cli
 | 
			
		||||
      push byte 0
 | 
			
		||||
      push byte 31
 | 
			
		||||
      jmp isr_common_stub      
 | 
			
		||||
            
 | 
			
		||||
extern IsrsFaultHandler
 | 
			
		||||
 | 
			
		||||
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, IsrsFaultHandler
 | 
			
		||||
    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!
 | 
			
		||||
							
								
								
									
										114
									
								
								Kernel/hal/cpu/isrs.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								Kernel/hal/cpu/isrs.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,114 @@
 | 
			
		||||
#include <debugio.h>
 | 
			
		||||
 | 
			
		||||
#include "isrs.h"
 | 
			
		||||
#include "idt.h"
 | 
			
		||||
 | 
			
		||||
// Assembly coded
 | 
			
		||||
extern void isr_exception_0();
 | 
			
		||||
extern void isr_exception_1();
 | 
			
		||||
extern void isr_exception_2();
 | 
			
		||||
extern void isr_exception_3();
 | 
			
		||||
extern void isr_exception_4();
 | 
			
		||||
extern void isr_exception_5();
 | 
			
		||||
extern void isr_exception_6();
 | 
			
		||||
extern void isr_exception_7();
 | 
			
		||||
extern void isr_exception_8();
 | 
			
		||||
extern void isr_exception_9();
 | 
			
		||||
extern void isr_exception_10();
 | 
			
		||||
extern void isr_exception_11();
 | 
			
		||||
extern void isr_exception_12();
 | 
			
		||||
extern void isr_exception_13();
 | 
			
		||||
extern void isr_exception_14();
 | 
			
		||||
extern void isr_exception_15();
 | 
			
		||||
extern void isr_exception_16();
 | 
			
		||||
extern void isr_exception_17();
 | 
			
		||||
extern void isr_exception_18();
 | 
			
		||||
extern void isr_exception_19();
 | 
			
		||||
extern void isr_exception_20();
 | 
			
		||||
extern void isr_exception_21();
 | 
			
		||||
extern void isr_exception_22();
 | 
			
		||||
extern void isr_exception_23();
 | 
			
		||||
extern void isr_exception_24();
 | 
			
		||||
extern void isr_exception_25();
 | 
			
		||||
extern void isr_exception_26();
 | 
			
		||||
extern void isr_exception_27();
 | 
			
		||||
extern void isr_exception_28();
 | 
			
		||||
extern void isr_exception_29();
 | 
			
		||||
extern void isr_exception_30();
 | 
			
		||||
extern void isr_exception_31();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void* IdtFaultHandlers[32] = {
 | 
			
		||||
	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 | 
			
		||||
	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
void IsrsInstall()
 | 
			
		||||
{
 | 
			
		||||
	IdtSetGate(0, (unsigned)isr_exception_0, 0x08, 0x8E);
 | 
			
		||||
	IdtSetGate(1, (unsigned)isr_exception_1, 0x08, 0x8E);
 | 
			
		||||
	IdtSetGate(2, (unsigned)isr_exception_2, 0x08, 0x8E);
 | 
			
		||||
	IdtSetGate(3, (unsigned)isr_exception_3, 0x08, 0x8E);
 | 
			
		||||
	IdtSetGate(4, (unsigned)isr_exception_4, 0x08, 0x8E);
 | 
			
		||||
	IdtSetGate(5, (unsigned)isr_exception_5, 0x08, 0x8E);
 | 
			
		||||
	IdtSetGate(6, (unsigned)isr_exception_6, 0x08, 0x8E);
 | 
			
		||||
	IdtSetGate(7, (unsigned)isr_exception_7, 0x08, 0x8E);
 | 
			
		||||
	IdtSetGate(8, (unsigned)isr_exception_8, 0x08, 0x8E);
 | 
			
		||||
	IdtSetGate(9, (unsigned)isr_exception_9, 0x08, 0x8E);
 | 
			
		||||
	IdtSetGate(10, (unsigned)isr_exception_10, 0x08, 0x8E);
 | 
			
		||||
	IdtSetGate(11, (unsigned)isr_exception_11, 0x08, 0x8E);
 | 
			
		||||
	IdtSetGate(12, (unsigned)isr_exception_12, 0x08, 0x8E);
 | 
			
		||||
	IdtSetGate(13, (unsigned)isr_exception_13, 0x08, 0x8E);
 | 
			
		||||
	IdtSetGate(14, (unsigned)isr_exception_14, 0x08, 0x8E);
 | 
			
		||||
	IdtSetGate(15, (unsigned)isr_exception_15, 0x08, 0x8E);
 | 
			
		||||
	IdtSetGate(16, (unsigned)isr_exception_16, 0x08, 0x8E);
 | 
			
		||||
	IdtSetGate(17, (unsigned)isr_exception_17, 0x08, 0x8E);
 | 
			
		||||
	IdtSetGate(18, (unsigned)isr_exception_18, 0x08, 0x8E);
 | 
			
		||||
	IdtSetGate(19, (unsigned)isr_exception_19, 0x08, 0x8E);
 | 
			
		||||
	IdtSetGate(20, (unsigned)isr_exception_20, 0x08, 0x8E);
 | 
			
		||||
	IdtSetGate(21, (unsigned)isr_exception_21, 0x08, 0x8E);
 | 
			
		||||
	IdtSetGate(22, (unsigned)isr_exception_22, 0x08, 0x8E);
 | 
			
		||||
	IdtSetGate(23, (unsigned)isr_exception_23, 0x08, 0x8E);
 | 
			
		||||
	IdtSetGate(24, (unsigned)isr_exception_24, 0x08, 0x8E);
 | 
			
		||||
	IdtSetGate(25, (unsigned)isr_exception_25, 0x08, 0x8E);
 | 
			
		||||
	IdtSetGate(26, (unsigned)isr_exception_26, 0x08, 0x8E);
 | 
			
		||||
	IdtSetGate(27, (unsigned)isr_exception_27, 0x08, 0x8E);
 | 
			
		||||
	IdtSetGate(28, (unsigned)isr_exception_28, 0x08, 0x8E);
 | 
			
		||||
	IdtSetGate(29, (unsigned)isr_exception_29, 0x08, 0x8E);
 | 
			
		||||
	IdtSetGate(30, (unsigned)isr_exception_30, 0x08, 0x8E);
 | 
			
		||||
	IdtSetGate(31, (unsigned)isr_exception_31, 0x08, 0x8E);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void IsrsInstallHandler(int interr, void (*function)(_RegsStack32 *r))
 | 
			
		||||
{
 | 
			
		||||
	if (interr < 32) IdtFaultHandlers[interr] = function;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void IsrsUninstallHandler(int interr)
 | 
			
		||||
{
 | 
			
		||||
	if (interr < 32) IdtFaultHandlers[interr] = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern void CrashMessage(_RegsStack32 *r);
 | 
			
		||||
// Default fault handler; calls other handlers, or displays error message.
 | 
			
		||||
void IsrsFaultHandler(_RegsStack32 *r)
 | 
			
		||||
{
 | 
			
		||||
	/* Is this a fault whose number is from 0 to 31? */
 | 
			
		||||
	if (r->int_no < 32)
 | 
			
		||||
	{
 | 
			
		||||
		void (*func)(_RegsStack32 *r);
 | 
			
		||||
		func = IdtFaultHandlers[r->int_no];
 | 
			
		||||
		
 | 
			
		||||
		// Halt system if unhandled
 | 
			
		||||
		if (!func) {
 | 
			
		||||
			CrashMessage(r);
 | 
			
		||||
			asm ("cli");
 | 
			
		||||
			asm ("hlt");
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		else (*func)(r);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										10
									
								
								Kernel/hal/cpu/isrs.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								Kernel/hal/cpu/isrs.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
#ifndef __ISRS_H_
 | 
			
		||||
#define __ISRS_H_
 | 
			
		||||
 | 
			
		||||
#include <types.h>
 | 
			
		||||
 | 
			
		||||
extern void IsrsInstall();
 | 
			
		||||
extern void IsrsInstallHandler(int interr, void (*function)(_RegsStack32 *r));
 | 
			
		||||
extern void IsrsUninstallHandler(int interr);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										23
									
								
								Kernel/hal/cpu/pic.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								Kernel/hal/cpu/pic.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include "pic.h"
 | 
			
		||||
 | 
			
		||||
void PicRemap(int pic1, int pic2)
 | 
			
		||||
{
 | 
			
		||||
      // Send ICW1
 | 
			
		||||
      outportb(0x20, 0x11);
 | 
			
		||||
      outportb(0xA0, 0x11);
 | 
			
		||||
      
 | 
			
		||||
      // send ICW2
 | 
			
		||||
      outportb(0x21, pic1); // remap pics
 | 
			
		||||
      outportb(0xA1, pic2);
 | 
			
		||||
      
 | 
			
		||||
      // send ICW3
 | 
			
		||||
      outportb(0x21, 4);
 | 
			
		||||
      outportb(0xA1, 2);
 | 
			
		||||
      
 | 
			
		||||
      // Send ICW4
 | 
			
		||||
      outportb(0x21, 0x01);
 | 
			
		||||
      outportb(0xA1, 0x01);
 | 
			
		||||
      
 | 
			
		||||
      outportb(0x21, 0x00);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										6
									
								
								Kernel/hal/cpu/pic.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								Kernel/hal/cpu/pic.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
#ifndef _PIC_H
 | 
			
		||||
#define _PIC_H
 | 
			
		||||
 | 
			
		||||
extern void PicRemap(int pic1, int pic2);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										96
									
								
								Kernel/hal/crash.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								Kernel/hal/crash.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,96 @@
 | 
			
		||||
/*
 | 
			
		||||
 * crash.c
 | 
			
		||||
 *
 | 
			
		||||
 *  Created on: Aug 19, 2011
 | 
			
		||||
 *      Author: Tiberiu
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <debugio.h>
 | 
			
		||||
 | 
			
		||||
string errorCodes[] =
 | 
			
		||||
{
 | 
			
		||||
		"Division by zero",		//0
 | 
			
		||||
		"Debugger",				//1
 | 
			
		||||
		"Non maskable interrupt",	//2
 | 
			
		||||
		"Breakpoint",			//3
 | 
			
		||||
		"Overflow",				//4
 | 
			
		||||
		"Bounds",				//5
 | 
			
		||||
		"Invalid opcode",			//6
 | 
			
		||||
		"Coprocessor not available",  //7
 | 
			
		||||
		"Double fault",			//8
 | 
			
		||||
		"Coprocessor segment overrun",//9
 | 
			
		||||
		"Invalid task state segment", //A
 | 
			
		||||
		"Segment not present",		//B
 | 
			
		||||
		"Stack fault",			//C
 | 
			
		||||
		"General protection fault",	//D
 | 
			
		||||
		"Page fault",			//E
 | 
			
		||||
		"",					//F
 | 
			
		||||
		"Math fault",			//10
 | 
			
		||||
		"Alignment check",		//11
 | 
			
		||||
		"Machine check",			//12
 | 
			
		||||
		"SIMD floating-point exception" //13
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void CrashMessage(_RegsStack32 *r)
 | 
			
		||||
{
 | 
			
		||||
	ConsoleSetDefaultColor(ColorLightRed);
 | 
			
		||||
	ConsoleWrite("\n"); uint32 i;
 | 
			
		||||
	for (i = 0; i < 80; i++) ConsoleWrite("%c", 205);
 | 
			
		||||
 | 
			
		||||
	ConsoleWrite("%#\t\t\t\tSomething went terribly wrong :(\n\n", ColorWhite);
 | 
			
		||||
	ConsoleWrite("There was an unhandled exception: ");
 | 
			
		||||
 | 
			
		||||
	if (r->int_no < 20)
 | 
			
		||||
		ConsoleWrite("%#%s (INT%u)", ColorWhite, errorCodes[r->int_no], r->int_no);
 | 
			
		||||
	else ConsoleWrite("%#INT%u", ColorWhite, r->int_no);
 | 
			
		||||
 | 
			
		||||
	ConsoleWrite("\nTo protect your computer, it had to be halted.\n\n");
 | 
			
		||||
	ConsoleWrite("Here, this might help find the problem:\n");
 | 
			
		||||
 | 
			
		||||
	Point a = {4, -1}, b = {22, -1}, c = {40, -1}, d = {58, -1};
 | 
			
		||||
 | 
			
		||||
	ConsoleSetDefaultColor(ColorWhite);
 | 
			
		||||
	ConsoleCursorGoto(a); ConsoleWrite("eax=0x%x", r->eax);
 | 
			
		||||
	ConsoleCursorGoto(b); ConsoleWrite("ebx=0x%x", r->ebx);
 | 
			
		||||
	ConsoleCursorGoto(c); ConsoleWrite("ecx=0x%x", r->ecx);
 | 
			
		||||
	ConsoleCursorGoto(d); ConsoleWrite("edx=0x%x\n", r->edx);
 | 
			
		||||
 | 
			
		||||
	ConsoleCursorGoto(a); ConsoleWrite("edi=0x%x", r->edi);
 | 
			
		||||
	ConsoleCursorGoto(b); ConsoleWrite("esi=0x%x", r->esi);
 | 
			
		||||
	ConsoleCursorGoto(c); ConsoleWrite("ebp=0x%x", r->ebp);
 | 
			
		||||
	ConsoleCursorGoto(d); ConsoleWrite("esp=0x%x\n", r->esp);
 | 
			
		||||
 | 
			
		||||
	ConsoleCursorGoto(a); ConsoleWrite("gs=0x%x", r->gs);
 | 
			
		||||
	ConsoleCursorGoto(b); ConsoleWrite("fs=0x%x", r->fs);
 | 
			
		||||
	ConsoleCursorGoto(c); ConsoleWrite("es=0x%x", r->es);
 | 
			
		||||
	ConsoleCursorGoto(d); ConsoleWrite("ds=0x%x\n", r->ds);
 | 
			
		||||
 | 
			
		||||
	ConsoleCursorGoto(a); ConsoleWrite("eip=0x%x", r->eip);
 | 
			
		||||
	ConsoleCursorGoto(b); ConsoleWrite("cs=0x%x", r->cs);
 | 
			
		||||
	ConsoleCursorGoto(c); ConsoleWrite("eflags=0x%x", r->eflags);
 | 
			
		||||
	ConsoleCursorGoto(d); ConsoleWrite("useresp=0x%x\n", r->useresp);
 | 
			
		||||
 | 
			
		||||
	ConsoleCursorGoto(a); ConsoleWrite("gs=0x%x", r->ss);
 | 
			
		||||
	ConsoleCursorGoto(b); ConsoleWrite("fs=0x%x", r->int_no);
 | 
			
		||||
	ConsoleCursorGoto(c); ConsoleWrite("err_code=0x%x", r->err_code);
 | 
			
		||||
 | 
			
		||||
	// Useful info about page fault
 | 
			
		||||
	if (r->int_no == 0xE)
 | 
			
		||||
	{
 | 
			
		||||
		uint32 faulting_address;
 | 
			
		||||
		asm volatile("mov %%cr2, %0" : "=r" (faulting_address));
 | 
			
		||||
 | 
			
		||||
		ConsoleCursorGoto(d); ConsoleWrite("address=0x%x\n", faulting_address);
 | 
			
		||||
		ConsoleCursorGoto(a); ConsoleWrite("reason: ");
 | 
			
		||||
		
 | 
			
		||||
		if (!(r->err_code & 1)) ConsoleWrite("%#PAGE_NOT_PRESENT; ", ColorLightGray);
 | 
			
		||||
		if (r->err_code & 2) 	ConsoleWrite("%#WRITE_OPERATION; ", ColorLightGray);
 | 
			
		||||
		if (r->err_code & 4) 	ConsoleWrite("%#CPU_IN_USER_MODE; ", ColorLightGray);
 | 
			
		||||
		if (r->err_code & 8) 	ConsoleWrite("%#CPU_RESERVED_PAGE_ENTRY_OVERWRITTEN; ", ColorLightGray);
 | 
			
		||||
		if (r->err_code & 0x10)	ConsoleWrite("%#INSTRUCTION_FETCH; ", ColorLightGray);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	ConsoleSetDefaultColor(ColorLightRed);
 | 
			
		||||
	ConsoleWrite("\n");
 | 
			
		||||
	for (i = 0; i < 80; i++) ConsoleWrite("%c", 205);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										97
									
								
								Kernel/hal/crash.c~
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								Kernel/hal/crash.c~
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,97 @@
 | 
			
		||||
/*
 | 
			
		||||
 * crash.c
 | 
			
		||||
 *
 | 
			
		||||
 *  Created on: Aug 19, 2011
 | 
			
		||||
 *      Author: Tiberiu
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <debugio.h>
 | 
			
		||||
 | 
			
		||||
string errorCodes[] =
 | 
			
		||||
{
 | 
			
		||||
		"Division by zero",		//0
 | 
			
		||||
		"Debugger",				//1
 | 
			
		||||
		"Non maskable interrupt",	//2
 | 
			
		||||
		"Breakpoint",			//3
 | 
			
		||||
		"Overflow",				//4
 | 
			
		||||
		"Bounds",				//5
 | 
			
		||||
		"Invalid opcode",			//6
 | 
			
		||||
		"Coprocessor not available",  //7
 | 
			
		||||
		"Double fault",			//8
 | 
			
		||||
		"Coprocessor segment overrun",//9
 | 
			
		||||
		"Invalid task state segment", //A
 | 
			
		||||
		"Segment not present",		//B
 | 
			
		||||
		"Stack fault",			//C
 | 
			
		||||
		"General protection fault",	//D
 | 
			
		||||
		"Page fault",			//E
 | 
			
		||||
		"",					//F
 | 
			
		||||
		"Math fault",			//10
 | 
			
		||||
		"Alignment check",		//11
 | 
			
		||||
		"Machine check",			//12
 | 
			
		||||
		"SIMD floating-point exception" //13
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void CrashMessage(_RegsStack32 *r)
 | 
			
		||||
{
 | 
			
		||||
	ConsoleSetDefaultColor(ColorLightRed);
 | 
			
		||||
	
 | 
			
		||||
	ConsoleWrite("\n"); uint32 i;
 | 
			
		||||
	for (i = 0; i < 80; i++) ConsoleWrite("%c", 205);
 | 
			
		||||
 | 
			
		||||
	ConsoleWrite("%#\t\t\t\tSomething went terribly wrong :(\n\n", ColorWhite);
 | 
			
		||||
	ConsoleWrite("There was an unhandled exception: ");
 | 
			
		||||
 | 
			
		||||
	if (r->int_no < 20)
 | 
			
		||||
		ConsoleWrite("%#%s (INT%u)", ColorWhite, errorCodes[r->int_no], r->int_no);
 | 
			
		||||
	else ConsoleWrite("%#INT%u", ColorWhite, r->int_no);
 | 
			
		||||
 | 
			
		||||
	ConsoleWrite("\nTo protect your computer, it had to be halted.\n\n");
 | 
			
		||||
	ConsoleWrite("Here, this might help find the problem:\n");
 | 
			
		||||
 | 
			
		||||
	Point a = {4, -1}, b = {22, -1}, c = {40, -1}, d = {58, -1};
 | 
			
		||||
 | 
			
		||||
	ConsoleSetDefaultColor(ColorWhite);
 | 
			
		||||
	ConsoleCursorGoto(a); ConsoleWrite("eax=0x%x", r->eax);
 | 
			
		||||
	ConsoleCursorGoto(b); ConsoleWrite("ebx=0x%x", r->ebx);
 | 
			
		||||
	ConsoleCursorGoto(c); ConsoleWrite("ecx=0x%x", r->ecx);
 | 
			
		||||
	ConsoleCursorGoto(d); ConsoleWrite("edx=0x%x\n", r->edx);
 | 
			
		||||
 | 
			
		||||
	ConsoleCursorGoto(a); ConsoleWrite("edi=0x%x", r->edi);
 | 
			
		||||
	ConsoleCursorGoto(b); ConsoleWrite("esi=0x%x", r->esi);
 | 
			
		||||
	ConsoleCursorGoto(c); ConsoleWrite("ebp=0x%x", r->ebp);
 | 
			
		||||
	ConsoleCursorGoto(d); ConsoleWrite("esp=0x%x\n", r->esp);
 | 
			
		||||
 | 
			
		||||
	ConsoleCursorGoto(a); ConsoleWrite("gs=0x%x", r->gs);
 | 
			
		||||
	ConsoleCursorGoto(b); ConsoleWrite("fs=0x%x", r->fs);
 | 
			
		||||
	ConsoleCursorGoto(c); ConsoleWrite("es=0x%x", r->es);
 | 
			
		||||
	ConsoleCursorGoto(d); ConsoleWrite("ds=0x%x\n", r->ds);
 | 
			
		||||
 | 
			
		||||
	ConsoleCursorGoto(a); ConsoleWrite("eip=0x%x", r->eip);
 | 
			
		||||
	ConsoleCursorGoto(b); ConsoleWrite("cs=0x%x", r->cs);
 | 
			
		||||
	ConsoleCursorGoto(c); ConsoleWrite("eflags=0x%x", r->eflags);
 | 
			
		||||
	ConsoleCursorGoto(d); ConsoleWrite("useresp=0x%x\n", r->useresp);
 | 
			
		||||
 | 
			
		||||
	ConsoleCursorGoto(a); ConsoleWrite("gs=0x%x", r->ss);
 | 
			
		||||
	ConsoleCursorGoto(b); ConsoleWrite("fs=0x%x", r->int_no);
 | 
			
		||||
	ConsoleCursorGoto(c); ConsoleWrite("err_code=0x%x", r->err_code);
 | 
			
		||||
 | 
			
		||||
	// Useful info about page fault
 | 
			
		||||
	if (r->int_no == 0xE)
 | 
			
		||||
	{
 | 
			
		||||
		uint32 faulting_address;
 | 
			
		||||
		asm volatile("mov %%cr2, %0" : "=r" (faulting_address));
 | 
			
		||||
 | 
			
		||||
		ConsoleCursorGoto(d); ConsoleWrite("address=0x%x\n", faulting_address);
 | 
			
		||||
		ConsoleCursorGoto(a); ConsoleWrite("reason: ");
 | 
			
		||||
		
 | 
			
		||||
		if (!(r->err_code & 1)) ConsoleWrite("%#PAGE_NOT_PRESENT; ", ColorLightGray);
 | 
			
		||||
		if (r->err_code & 2) 	ConsoleWrite("%#WRITE_OPERATION; ", ColorLightGray);
 | 
			
		||||
		if (r->err_code & 4) 	ConsoleWrite("%#CPU_IN_USER_MODE; ", ColorLightGray);
 | 
			
		||||
		if (r->err_code & 8) 	ConsoleWrite("%#CPU_RESERVED_PAGE_ENTRY_OVERWRITTEN; ", ColorLightGray);
 | 
			
		||||
		if (r->err_code & 0x10)	ConsoleWrite("%#INSTRUCTION_FETCH; ", ColorLightGray);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	ConsoleSetDefaultColor(ColorLightRed);
 | 
			
		||||
	ConsoleWrite("\n");
 | 
			
		||||
	for (i = 0; i < 80; i++) ConsoleWrite("%c", 205);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										35
									
								
								Kernel/hal/hal.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								Kernel/hal/hal.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
// HARDWARE ABSTRACTION LAYER
 | 
			
		||||
#include "cpu/gdt.h"
 | 
			
		||||
#include "cpu/idt.h"
 | 
			
		||||
#include "cpu/isrs.h"
 | 
			
		||||
#include "cpu/irq.h"
 | 
			
		||||
 | 
			
		||||
#include "clock/clock.h"
 | 
			
		||||
#include "keyboard/keyboard.h"
 | 
			
		||||
#include "mouse/mouse.h"
 | 
			
		||||
 | 
			
		||||
#include <debugio.h>
 | 
			
		||||
 | 
			
		||||
void HalInitialize()
 | 
			
		||||
{
 | 
			
		||||
	// Initialize cpu
 | 
			
		||||
	GdtInstall(); 	Log("%#[HAL] %#Installed GDT\n", ColorYellow, ColorLightGreen);
 | 
			
		||||
	IdtInstall();	Log("%#[HAL] %#Installed IDT\n", ColorYellow, ColorLightGreen);
 | 
			
		||||
	IsrsInstall();	Log("%#[HAL] %#Installed ISRs\n", ColorYellow, ColorLightGreen);
 | 
			
		||||
	IrqInstall();	Log("%#[HAL] %#Installed IRQs\n", ColorYellow, ColorLightGreen);
 | 
			
		||||
 | 
			
		||||
	// Start interrupts
 | 
			
		||||
	asm volatile ("sti");
 | 
			
		||||
	Log("%#[HAL] %#Interrupts are started...\n", ColorYellow, ColorLightMagenta);
 | 
			
		||||
 | 
			
		||||
	// Install keyboard
 | 
			
		||||
	IrqInstallHandler(0, TimeHandler);
 | 
			
		||||
	IrqInstallHandler(1, KeyboardHandler);
 | 
			
		||||
	IrqInstallHandler(12, MouseHandler);
 | 
			
		||||
 | 
			
		||||
	KeyboardInstallA();	Log("%#[HAL] %#Installing keyboard... %#[1/2] ", ColorYellow, ColorLightGray, ColorLightGreen);
 | 
			
		||||
	KeyboardInstallB(); Log("%#[2/2]\n", ColorLightGreen);
 | 
			
		||||
 | 
			
		||||
	// Install mouse driver
 | 
			
		||||
	MouseInstall();		Log("%#[HAL] %#Installed mouse driver\n", ColorYellow, ColorLightGreen);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										6
									
								
								Kernel/hal/hal.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								Kernel/hal/hal.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
#ifndef __HAL__H
 | 
			
		||||
#define __HAL__H
 | 
			
		||||
 | 
			
		||||
extern void HalInitialize();
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										327
									
								
								Kernel/hal/keyboard/keyboard.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										327
									
								
								Kernel/hal/keyboard/keyboard.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,327 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include "keyboard.h"
 | 
			
		||||
 | 
			
		||||
#define KeybCmdWriteLED			0xed
 | 
			
		||||
#define KeybCmdEcho			0xee
 | 
			
		||||
#define KeybCmdSetScancodeSet		0xf0
 | 
			
		||||
#define KeybCmdGetID			0xf2
 | 
			
		||||
#define KeybCmdSetRepeatDelay		0xf3
 | 
			
		||||
#define KeybCmdEnable			0xf4
 | 
			
		||||
#define KeybCmdSetDefaultDisable	0xf5
 | 
			
		||||
#define KeybCmdSetDefault		0xf6
 | 
			
		||||
#define KeybCmdResend			0xfe
 | 
			
		||||
#define KeybCmdReset			0xff
 | 
			
		||||
 | 
			
		||||
volatile uint8 KeyState[16];
 | 
			
		||||
volatile uint8 KeyboardLastStatus;
 | 
			
		||||
volatile uint8 KeyboardLastScancode;
 | 
			
		||||
 | 
			
		||||
uint8	KeyboardScancodeSet = 2;
 | 
			
		||||
 | 
			
		||||
// Byte map:
 | 
			
		||||
// 0  If set, next code is break
 | 
			
		||||
// 1  'Gray' key
 | 
			
		||||
// 2  'Weird' key (Pause/Break)
 | 
			
		||||
// 3  Scroll
 | 
			
		||||
// 4  Num
 | 
			
		||||
// 5  Caps
 | 
			
		||||
// 6  If set, LEDs changed
 | 
			
		||||
uint8 KeyboardModifiers;
 | 
			
		||||
 | 
			
		||||
const char KeyboardMap[] = {
 | 
			
		||||
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '\t', '`', 0,
 | 
			
		||||
	0, 0, 0, 0, 0, 'q', '1', 0, 0, 0, 'z', 's', 'a', 'w', '2', 0,
 | 
			
		||||
	0, 'c', 'x', 'd', 'e', '4', '3', 0, 0, ' ', 'v', 'f', 't', 'r', '5', 0,
 | 
			
		||||
	0, 'n', 'b', 'h', 'g', 'y', '6', 0, 0, 0, 'm', 'j', 'u', '7', '8', 0,
 | 
			
		||||
	0, ',', 'k', 'i', 'o', '0', '9', 0, 0, '.', '/', 'l', ';', 'p', '-', 0,
 | 
			
		||||
	0, 0, '\'', 0, '[', '=', 0, 0, 0, 0, '\n', ']', 0, '\\', 0, 0,
 | 
			
		||||
	0, 0, 0, 0, 0, 0, '\b', 0, 0, '1', '/', '4', '7', '\n', 0, 0,
 | 
			
		||||
	'0', '.', '2', '5', '6', '8', 0, 0, 0, '+', '3', '-', '*', '9', 0, 0
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
const char KeyboardMapShift[] = {
 | 
			
		||||
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '\t', '~', 0,
 | 
			
		||||
	0, 0, 0, 0, 0, 'Q', '!', 0, 0, 0, 'Z', 'S', 'A', 'W', '@', 0,
 | 
			
		||||
	0, 'C', 'X', 'D', 'E', '$', '#', 0, 0, ' ', 'V', 'F', 'T', 'R', '%', 0,
 | 
			
		||||
	0, 'N', 'B', 'H', 'G', 'Y', '^', 0, 0, 0, 'M', 'J', 'U', '&', '*', 0,
 | 
			
		||||
	0, '<', 'K', 'I', 'O', ')', '(', 0, 0, '>', '?', 'L', ':', 'P', '_', 0,
 | 
			
		||||
	0, 0, '\"', 0, '{', '+', 0, 0, 0, 0, '\n', '}', 0, '|', 0, 0,
 | 
			
		||||
	0, 0, 0, 0, 0, 0, '\b', 0, 0, '1', '/', '4', '7', '\n', 0, 0,
 | 
			
		||||
	'0', '.', '2', '5', '6', '8', 0, 0, 0, '+', '3', '-', '*', '9', 0, 0
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void KeyboardSetKeyStatus (uint8 scancode, uint8 status)
 | 
			
		||||
{
 | 
			
		||||
	int32 index = scancode>>3, pos = scancode & 0x7;
 | 
			
		||||
 | 
			
		||||
	if (status) KeyState[index] |= 1<<pos;
 | 
			
		||||
	else KeyState[index] &= ~(1<<pos);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint8 KeyboardGetKeyStatus (uint8 scancode)
 | 
			
		||||
{
 | 
			
		||||
	int32 index = scancode>>3, pos = scancode & 0x7;
 | 
			
		||||
 | 
			
		||||
	return KeyState[index] & (1<<pos);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void _process_scancode(uint8 scancode)
 | 
			
		||||
{
 | 
			
		||||
	switch (scancode)
 | 
			
		||||
	{
 | 
			
		||||
	   // Messages from keyboard controller
 | 
			
		||||
		case 0x00:						// Error 0x00
 | 
			
		||||
		case 0xFC:						// Diagnostics failed (MF kb)
 | 
			
		||||
		case 0xFD:						// Diagnostics failed (AT kb)
 | 
			
		||||
		case 0xFF: KeyboardWaitOutport();
 | 
			
		||||
				outportb(0x60, KeybCmdEnable);
 | 
			
		||||
				return;				// Error 0xFF, reenable keyboard
 | 
			
		||||
		case 0xAA:						// BAT test successful.
 | 
			
		||||
		case 0xFA:						// ACKnowledge
 | 
			
		||||
		case 0xFE:						// Last command invalid or parity error
 | 
			
		||||
		case 0xEE: return;				// Echo response
 | 
			
		||||
 | 
			
		||||
	   // Break
 | 
			
		||||
		case 0xF0: KeyboardModifiers |= 1; return;
 | 
			
		||||
 | 
			
		||||
	   // Special character (gray, etc)
 | 
			
		||||
		case 0xE0: KeyboardModifiers |= 2; return;
 | 
			
		||||
		case 0xE1: KeyboardModifiers |= 4; return;
 | 
			
		||||
 | 
			
		||||
	   // Remap some characters:
 | 
			
		||||
		case 0x83: scancode = KeyboardKeyF7; break;
 | 
			
		||||
 | 
			
		||||
	   // LEDs
 | 
			
		||||
		case KeyboardKeyScrollLock:
 | 
			
		||||
			if ((KeyboardModifiers & 1) == 0) {
 | 
			
		||||
				KeyboardModifiers ^= 1<<3;
 | 
			
		||||
				KeyboardModifiers |= 1<<6;
 | 
			
		||||
			} break;
 | 
			
		||||
			
 | 
			
		||||
		case KeyboardKeyNumLock:
 | 
			
		||||
			if ((KeyboardModifiers & 1) == 0) {
 | 
			
		||||
				KeyboardModifiers ^= 1<<4;
 | 
			
		||||
				KeyboardModifiers |= 1<<6;
 | 
			
		||||
			} break;
 | 
			
		||||
		case KeyboardKeyCapsLock:
 | 
			
		||||
			if ((KeyboardModifiers & 1) == 0) {
 | 
			
		||||
				KeyboardModifiers ^= 1<<5;
 | 
			
		||||
				KeyboardModifiers |= 1<<6;
 | 
			
		||||
			} break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Remap most gray characters
 | 
			
		||||
	if (KeyboardModifiers & 2) switch (scancode)
 | 
			
		||||
	{
 | 
			
		||||
		case 0x10: scancode = KeyboardKeyMediaWebSearch; break;
 | 
			
		||||
		case 0x11: scancode = KeyboardKeyRightAlt; break;
 | 
			
		||||
		case 0x12: return;							// Fake shift, ignore
 | 
			
		||||
		case 0x14: scancode = KeyboardKeyRightCtrl; break;
 | 
			
		||||
		case 0x15: scancode = KeyboardKeyMediaPrevious; break;
 | 
			
		||||
		case 0x18: scancode = KeyboardKeyMediaWebFavorites; break;
 | 
			
		||||
		case 0x1F: scancode = KeyboardKeyLeftWin; break;
 | 
			
		||||
		case 0x20: scancode = KeyboardKeyMediaWebRefresh; break;
 | 
			
		||||
		case 0x21: scancode = KeyboardKeyMediaVolDown; break;
 | 
			
		||||
		case 0x23: scancode = KeyboardKeyMediaMute; break;
 | 
			
		||||
		case 0x27: scancode = KeyboardKeyRightWin; break;
 | 
			
		||||
		case 0x28: scancode = KeyboardKeyMediaWebStop; break;
 | 
			
		||||
		case 0x2B: scancode = KeyboardKeyMediaCalculator; break;
 | 
			
		||||
		case 0x2F: scancode = KeyboardKeyMenu; break;
 | 
			
		||||
		case 0x30: scancode = KeyboardKeyMediaWebForward; break;
 | 
			
		||||
		case 0x32: scancode = KeyboardKeyMediaVolUp; break;
 | 
			
		||||
		case 0x34: scancode = KeyboardKeyMediaPause; break;
 | 
			
		||||
		case 0x37: scancode = KeyboardKeyPower; break;
 | 
			
		||||
		case 0x38: scancode = KeyboardKeyMediaWebBack; break;
 | 
			
		||||
		case 0x3A: scancode = KeyboardKeyMediaWebHome; break;
 | 
			
		||||
		case 0x3B: scancode = KeyboardKeyMediaStop; break;
 | 
			
		||||
		case 0x3F: scancode = KeyboardKeySleep; break;
 | 
			
		||||
		case 0x40: scancode = KeyboardKeyMediaComputer; break;
 | 
			
		||||
		case 0x48: scancode = KeyboardKeyMediaEmail; break;
 | 
			
		||||
		case 0x4A: scancode = KeyboardKeyNumpadSlash; break;
 | 
			
		||||
		case 0x4D: scancode = KeyboardKeyMediaNext; break;
 | 
			
		||||
		case 0x50: scancode = KeyboardKeyMediaSelect; break;
 | 
			
		||||
		case 0x5A: scancode = KeyboardKeyNumpadEnter; break;
 | 
			
		||||
		case 0x5E: scancode = KeyboardKeyWake; break;
 | 
			
		||||
		case 0x69: scancode = KeyboardKeyEnd; break;
 | 
			
		||||
		case 0x6B: scancode = KeyboardKeyLeft; break;
 | 
			
		||||
		case 0x6C: scancode = KeyboardKeyHome; break;
 | 
			
		||||
		case 0x70: scancode = KeyboardKeyInsert; break;
 | 
			
		||||
		case 0x71: scancode = KeyboardKeyDelete; break;
 | 
			
		||||
		case 0x72: scancode = KeyboardKeyDown; break;
 | 
			
		||||
		case 0x74: scancode = KeyboardKeyRight; break;
 | 
			
		||||
		case 0x75: scancode = KeyboardKeyUp; break;
 | 
			
		||||
		case 0x7A: scancode = KeyboardKeyPageDown; break;
 | 
			
		||||
		case 0x7C: scancode = KeyboardKeyPrintScreen; break;
 | 
			
		||||
		case 0x7D: scancode = KeyboardKeyPageUp; break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Pause/break
 | 
			
		||||
	if (KeyboardModifiers & 4)
 | 
			
		||||
	{
 | 
			
		||||
		KeyboardSetKeyStatus(KeyboardKeyPause, 1 - (KeyboardModifiers & 1));
 | 
			
		||||
 | 
			
		||||
		if (scancode == 0x77) KeyboardModifiers = 0;
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	KeyboardSetKeyStatus(scancode, 1 - (KeyboardModifiers & 1));
 | 
			
		||||
 | 
			
		||||
	// Give functions something to wait for :P
 | 
			
		||||
	KeyboardLastScancode = scancode;
 | 
			
		||||
	KeyboardLastStatus = KeyboardModifiers;
 | 
			
		||||
	KeyboardModifiers &= ~7;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void KeyboardHandler (_RegsStack32* UNUSED(r))
 | 
			
		||||
{
 | 
			
		||||
	// Get scancode from keyboard
 | 
			
		||||
	uint8 scancode = inportb(0x60);
 | 
			
		||||
 | 
			
		||||
	// Process scancode
 | 
			
		||||
	_process_scancode(scancode);
 | 
			
		||||
 | 
			
		||||
	// LED update
 | 
			
		||||
	if (KeyboardModifiers & (1<<6))
 | 
			
		||||
	{
 | 
			
		||||
		KeyboardSetLEDs(KeyboardModifiers & (1<<3), KeyboardModifiers & (1<<4), KeyboardModifiers & (1<<5));
 | 
			
		||||
		KeyboardModifiers &= ~(1<<6);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void KeyboardSetLEDs (uint8 scroll, uint8 num, uint8 caps)
 | 
			
		||||
{
 | 
			
		||||
	uint8 status = 0;
 | 
			
		||||
	status |= (scroll > 0);
 | 
			
		||||
	status |= (num > 0) << 1;
 | 
			
		||||
	status |= (caps > 0) << 2;
 | 
			
		||||
 | 
			
		||||
	KeyboardWaitOutport();
 | 
			
		||||
	outportb (0x60, KeybCmdWriteLED);
 | 
			
		||||
 | 
			
		||||
	KeyboardWaitOutport();
 | 
			
		||||
	outportb (0x60, status);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/***************************************
 | 
			
		||||
 *	 Set repeat rate/delay	   *
 | 
			
		||||
 ***************************************
 | 
			
		||||
 Values for inter-character delay (bits 4-0)
 | 
			
		||||
 (characters per second; default is 10.9)
 | 
			
		||||
     |  0 |  1 |  2 |  3 |  4 |  5 |  6 |  7
 | 
			
		||||
 ----+----+----+----+----+----+----+----+----
 | 
			
		||||
  0  |30.0|26.7|24.0|21.8|20.0|18.5|17.1|16.0
 | 
			
		||||
  8  |15.0|13.3|12.0|10.9|10.0|9.2 |8.6 |8.0
 | 
			
		||||
  16 |7.5 |6.7 |6.0 |5.5 |5.0 |4.6 |4.3 |4.0
 | 
			
		||||
  24 |3.7 |3.3 |3.0 |2.7 |2.5 |2.3 |2.1 |2.0
 | 
			
		||||
 | 
			
		||||
 Values for delay:
 | 
			
		||||
 (miliseconds; default is 500)
 | 
			
		||||
    0 |   1 |   2 |   3
 | 
			
		||||
 -----+-----+-----+-----
 | 
			
		||||
  250 | 500 | 750 | 1000
 | 
			
		||||
 | 
			
		||||
 ***************************************/
 | 
			
		||||
void KeyboardSetRepeatRate(uint8 rate, uint8 delay)
 | 
			
		||||
{
 | 
			
		||||
	if (rate>3 || delay>31) return;
 | 
			
		||||
 | 
			
		||||
	uint8 out = rate<<5 | delay;
 | 
			
		||||
	
 | 
			
		||||
	KeyboardWaitOutport();
 | 
			
		||||
	outportb(0x60, KeybCmdSetRepeatDelay);
 | 
			
		||||
	
 | 
			
		||||
	KeyboardWaitOutport();
 | 
			
		||||
	outportb(0x60, out);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/***************************************
 | 
			
		||||
 *	 Set scancode set		  *
 | 
			
		||||
 ***************************************
 | 
			
		||||
	1  Set to scancode set 1
 | 
			
		||||
	2  Set to scancode set 2
 | 
			
		||||
	3  Set to scancode set 3
 | 
			
		||||
 ***************************************/
 | 
			
		||||
void KeyboardSetScancodeSet(uint8 set)
 | 
			
		||||
{
 | 
			
		||||
    if (set>3 || set <= 0) return;
 | 
			
		||||
 | 
			
		||||
    KeyboardWaitOutport();
 | 
			
		||||
    outportb (0x60, KeybCmdSetScancodeSet);
 | 
			
		||||
 | 
			
		||||
    KeyboardWaitOutport();
 | 
			
		||||
    outportb (0x60, set);
 | 
			
		||||
 | 
			
		||||
    KeyboardScancodeSet = set;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void KeyboardWaitOutport()
 | 
			
		||||
{
 | 
			
		||||
	int fail_safe=200000;
 | 
			
		||||
	while ((inportb(0x64)&2)!=0 && fail_safe>0) fail_safe--;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KeyboardWaitInport()
 | 
			
		||||
{
 | 
			
		||||
	int fail_safe=200000;
 | 
			
		||||
	while ((inportb(0x64)&1)==0 && fail_safe>0) fail_safe--;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void KeyboardInstallA()
 | 
			
		||||
{
 | 
			
		||||
	KeyboardWaitOutport();
 | 
			
		||||
	outportb(0x60, KeybCmdReset);	   // Reset kb
 | 
			
		||||
 | 
			
		||||
	// Initialize variables
 | 
			
		||||
	KeyboardLastStatus = 0;
 | 
			
		||||
	KeyboardModifiers = 0;
 | 
			
		||||
 | 
			
		||||
	int32 i;
 | 
			
		||||
	for (i = 0; i < 16; i++)
 | 
			
		||||
		KeyState[i] = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void KeyboardInstallB()
 | 
			
		||||
{
 | 
			
		||||
	// Wait for BAT test results
 | 
			
		||||
	KeyboardWaitInport();
 | 
			
		||||
	
 | 
			
		||||
	unsigned char temp;
 | 
			
		||||
	do temp = inportb(0x60);
 | 
			
		||||
	while (temp!=0xAA && temp!=0xFC);
 | 
			
		||||
 | 
			
		||||
	// Error
 | 
			
		||||
	if (temp == 0xFC) return;
 | 
			
		||||
 | 
			
		||||
	// Set new repeat rate
 | 
			
		||||
	KeyboardSetRepeatRate(1, 11);
 | 
			
		||||
 | 
			
		||||
	// Set scancode set 2
 | 
			
		||||
	KeyboardSetScancodeSet(2);  // Set new scancode set
 | 
			
		||||
 | 
			
		||||
	KeyboardWaitOutport();
 | 
			
		||||
	outportb(0x64, 0x20); // Get "Command unsigned char"
 | 
			
		||||
 | 
			
		||||
	do {  temp = inportb(0x60);
 | 
			
		||||
	} while (temp==0xFA || temp==0xAA);
 | 
			
		||||
 | 
			
		||||
	temp &= ~(1<<6); 	// Unset bit6: disable conversion
 | 
			
		||||
	KeyboardWaitOutport();
 | 
			
		||||
	outportb(0x64, 0x60); // Function to write cmd unsigned char
 | 
			
		||||
	
 | 
			
		||||
	KeyboardWaitOutport();
 | 
			
		||||
	outportb(0x60, temp); // Send it
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										52
									
								
								Kernel/hal/keyboard/keyboard.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								Kernel/hal/keyboard/keyboard.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
			
		||||
#ifndef __KEYBOARD__H
 | 
			
		||||
#define __KEYBOARD__H
 | 
			
		||||
 | 
			
		||||
#include <types.h>
 | 
			
		||||
 | 
			
		||||
extern const char KeyboardMap[0x80];
 | 
			
		||||
extern const char KeyboardMapShift[0x80];
 | 
			
		||||
extern volatile uint8 KeyboardLastStatus;
 | 
			
		||||
extern volatile uint8 KeyboardLastScancode;
 | 
			
		||||
 | 
			
		||||
extern void KeyboardSetKeyStatus (uint8 scancode, uint8 status);
 | 
			
		||||
extern uint8 KeyboardGetKeyStatus (uint8 scancode);
 | 
			
		||||
extern void KeyboardHandler (_RegsStack32 *r);
 | 
			
		||||
extern void KeyboardSetLEDs (uint8 scroll, uint8 num, uint8 caps);
 | 
			
		||||
/***************************************
 | 
			
		||||
 *	 Set repeat rate/delay	   *
 | 
			
		||||
 ***************************************
 | 
			
		||||
 Values for inter-character delay (bits 4-0)
 | 
			
		||||
 (characters per second; default is 10.9)
 | 
			
		||||
     |  0 |  1 |  2 |  3 |  4 |  5 |  6 |  7
 | 
			
		||||
 ----+----+----+----+----+----+----+----+----
 | 
			
		||||
  0  |30.0|26.7|24.0|21.8|20.0|18.5|17.1|16.0
 | 
			
		||||
  8  |15.0|13.3|12.0|10.9|10.0|9.2 |8.6 |8.0
 | 
			
		||||
  16 |7.5 |6.7 |6.0 |5.5 |5.0 |4.6 |4.3 |4.0
 | 
			
		||||
  24 |3.7 |3.3 |3.0 |2.7 |2.5 |2.3 |2.1 |2.0
 | 
			
		||||
 | 
			
		||||
 Values for delay:
 | 
			
		||||
 (miliseconds; default is 500)
 | 
			
		||||
    0 |   1 |   2 |   3
 | 
			
		||||
 -----+-----+-----+-----
 | 
			
		||||
  250 | 500 | 750 | 1000
 | 
			
		||||
 | 
			
		||||
 ***************************************/
 | 
			
		||||
extern void KeyboardSetRepeatRate(uint8 rate, uint8 delay);
 | 
			
		||||
 | 
			
		||||
/***************************************
 | 
			
		||||
 *	 Set scancode set		  *
 | 
			
		||||
 ***************************************
 | 
			
		||||
	1  Set to scancode set 1
 | 
			
		||||
	2  Set to scancode set 2
 | 
			
		||||
	3  Set to scancode set 3
 | 
			
		||||
 ***************************************/
 | 
			
		||||
extern void KeyboardSetScancodeSet(uint8 set);
 | 
			
		||||
 | 
			
		||||
extern void KeyboardWaitOutport();
 | 
			
		||||
extern void KeyboardWaitInport();
 | 
			
		||||
 | 
			
		||||
extern void KeyboardInstallA();
 | 
			
		||||
extern void KeyboardInstallB();
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										116
									
								
								Kernel/hal/mouse/mouse.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								Kernel/hal/mouse/mouse.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,116 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <debugio.h>
 | 
			
		||||
#include "mouse.h"
 | 
			
		||||
#include "../keyboard/keyboard.h"
 | 
			
		||||
 | 
			
		||||
uint8 MouseCycle = 0;
 | 
			
		||||
uint8 MouseCycleExpected = 3;
 | 
			
		||||
uint8 Packets[4];
 | 
			
		||||
 | 
			
		||||
Point MousePosition = {0,0};
 | 
			
		||||
Point MouseMinimumPosition = {0,0}, MouseMaximumPosition = {80, 25};
 | 
			
		||||
Point Prev = {0,0};
 | 
			
		||||
 | 
			
		||||
#define SpeedLimit 0x8
 | 
			
		||||
 | 
			
		||||
// IRQ12
 | 
			
		||||
void MouseHandler (_RegsStack32* UNUSED(r))
 | 
			
		||||
{
 | 
			
		||||
	uint8 data = inportb(0x60);
 | 
			
		||||
	Point delta;
 | 
			
		||||
 | 
			
		||||
	if (MouseCycle == 0 && (data == 0 || data == 0xFA || data == 0xFF || data == 0xAA)) return;
 | 
			
		||||
	Packets[MouseCycle++] = data;
 | 
			
		||||
 | 
			
		||||
	// Cycle ended
 | 
			
		||||
	if (MouseCycle >= MouseCycleExpected)
 | 
			
		||||
	{
 | 
			
		||||
		MouseCycle = 0;
 | 
			
		||||
		if (Packets[0] & 0xC0) return; // Discard packet
 | 
			
		||||
 | 
			
		||||
		// Update X position
 | 
			
		||||
		if (Packets[0] & 0x10) delta.X = (int32) (Packets[1] | 0xFFFFFF00);
 | 
			
		||||
		else delta.X = (int32) Packets[1];
 | 
			
		||||
 | 
			
		||||
		// Update Y position
 | 
			
		||||
		if (Packets[0] & 0x20) delta.Y = -1 * (int32) (Packets[2] | 0xFFFFFF00);
 | 
			
		||||
		else delta.Y = -1 * (int32)Packets[2];
 | 
			
		||||
 | 
			
		||||
		if (delta.X >= SpeedLimit) delta.X = SpeedLimit;
 | 
			
		||||
		if (delta.X <= -SpeedLimit) delta.X = -SpeedLimit;
 | 
			
		||||
		if (delta.Y >= SpeedLimit) delta.Y = SpeedLimit;
 | 
			
		||||
		if (delta.Y <= -SpeedLimit) delta.Y = -SpeedLimit;
 | 
			
		||||
 | 
			
		||||
		MousePosition.X += delta.X;
 | 
			
		||||
		MousePosition.Y += delta.Y;
 | 
			
		||||
 | 
			
		||||
		// Check limits
 | 
			
		||||
		if (MousePosition.X < MouseMinimumPosition.X) MousePosition.X = MouseMinimumPosition.X;
 | 
			
		||||
		if (MousePosition.Y < MouseMinimumPosition.Y) MousePosition.Y = MouseMinimumPosition.Y;
 | 
			
		||||
		if (MousePosition.X >= MouseMaximumPosition.X) MousePosition.X = MouseMaximumPosition.X - 1;
 | 
			
		||||
		if (MousePosition.Y >= MouseMaximumPosition.Y) MousePosition.Y = MouseMaximumPosition.Y - 1;
 | 
			
		||||
 | 
			
		||||
		/* TESTING ONLY */
 | 
			
		||||
		ConsoleSetColor(Prev, 0xFF - ConsoleGetColor(Prev));
 | 
			
		||||
		ConsoleSetColor(MousePosition, 0xFF - ConsoleGetColor(MousePosition));
 | 
			
		||||
		Prev = MousePosition;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MouseSendCommand(uint8 command)
 | 
			
		||||
{
 | 
			
		||||
	KeyboardWaitOutport();
 | 
			
		||||
	outportb(0x64, 0xD4);
 | 
			
		||||
	KeyboardWaitOutport();
 | 
			
		||||
	outportb(0x60, command);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8 MouseReadData ()
 | 
			
		||||
{
 | 
			
		||||
	KeyboardWaitInport();
 | 
			
		||||
	return inportb(0x60);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MouseInstall()
 | 
			
		||||
{
 | 
			
		||||
	KeyboardWaitOutport();
 | 
			
		||||
	outportb(0x64, 0xA8);
 | 
			
		||||
 | 
			
		||||
	// Enable interrupts
 | 
			
		||||
	KeyboardWaitOutport();
 | 
			
		||||
	outportb(0x64, 0x20);
 | 
			
		||||
 | 
			
		||||
	KeyboardWaitInport();
 | 
			
		||||
	uint8 temp = inportb(0x60) | 2;
 | 
			
		||||
	temp &= ~0x20;
 | 
			
		||||
 | 
			
		||||
	KeyboardWaitOutport();
 | 
			
		||||
	outportb(0x64, 0x60);
 | 
			
		||||
 | 
			
		||||
	KeyboardWaitOutport();
 | 
			
		||||
	outportb(0x60, temp);
 | 
			
		||||
 | 
			
		||||
	// Reset mouse, and enable it
 | 
			
		||||
	MouseSendCommand(MouseCommandReset);
 | 
			
		||||
	MouseReadData(); MouseReadData();
 | 
			
		||||
 | 
			
		||||
	MouseSendCommand(MouseCommandSetDefaults);
 | 
			
		||||
	MouseReadData();	// Read ack
 | 
			
		||||
 | 
			
		||||
	MouseSendCommand(MouseCommandEnableDataReporting);
 | 
			
		||||
	MouseReadData();	// Read ack
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MouseSetLimits (Point min_pos, Point max_pos)
 | 
			
		||||
{
 | 
			
		||||
	MouseMinimumPosition = min_pos;
 | 
			
		||||
	MouseMaximumPosition = max_pos;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MouseState MouseGetState()
 | 
			
		||||
{
 | 
			
		||||
	MouseState ret = { Packets[0] & 0x7, MousePosition};
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										36
									
								
								Kernel/hal/mouse/mouse.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								Kernel/hal/mouse/mouse.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
#ifndef __MOUSE__H
 | 
			
		||||
#define __MOUSE__H
 | 
			
		||||
 | 
			
		||||
#include <types.h>
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
	uint8 Buttons;
 | 
			
		||||
	Point Position;
 | 
			
		||||
} MouseState;
 | 
			
		||||
 | 
			
		||||
enum MouseCommands
 | 
			
		||||
{
 | 
			
		||||
	MouseCommandReset = 0xFF,
 | 
			
		||||
	MouseCommandResend = 0xFE,
 | 
			
		||||
	MouseCommandSetDefaults = 0xF6,
 | 
			
		||||
	MouseCommandDisableDataReporting = 0xF5,
 | 
			
		||||
	MouseCommandEnableDataReporting = 0xF4,
 | 
			
		||||
	MouseCommandSetSampleRate = 0xF3,
 | 
			
		||||
	MouseCommandGetDeviceID = 0xF2,
 | 
			
		||||
	MouseCommandSetRemoteMode = 0xF0,
 | 
			
		||||
	MouseCommandSetWrapMode = 0xEE,
 | 
			
		||||
	MouseCommandReadData = 0xEB,
 | 
			
		||||
	MouseCommandSetStreamMode = 0xEA,
 | 
			
		||||
	MouseCommandStatusRequest = 0xE9,
 | 
			
		||||
	MouseCommandSetResolution = 0xE8,
 | 
			
		||||
	MouseCommandSetScaling_2_1 = 0xE7,
 | 
			
		||||
	MouseCommandSetScaling_1_1 = 0xE6
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern void MouseInstall();
 | 
			
		||||
extern void MouseHandler (_RegsStack32 *r);
 | 
			
		||||
extern void MouseSetLimits (Point min_pos, Point max_pos);
 | 
			
		||||
extern MouseState MouseGetState();
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										27
									
								
								Kernel/hal/sysinfo.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								Kernel/hal/sysinfo.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
/*
 | 
			
		||||
 * sysinfo.c
 | 
			
		||||
 *
 | 
			
		||||
 * Provides information about system, and useful utilities
 | 
			
		||||
 *
 | 
			
		||||
 *  Created on: Aug 17, 2011
 | 
			
		||||
 *      Author: Tiberiu
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <multiboot.h>
 | 
			
		||||
#include <debugio.h>
 | 
			
		||||
#include <memory.h>
 | 
			
		||||
 | 
			
		||||
#include <../drivers/cmos/cmos.h>
 | 
			
		||||
 | 
			
		||||
#include "keyboard/keyboard.h"
 | 
			
		||||
void SystemReboot()
 | 
			
		||||
{
 | 
			
		||||
	Log("Rebooting system...\n");
 | 
			
		||||
 | 
			
		||||
	KeyboardWaitOutport();
 | 
			
		||||
	outportb (0x64, 0xFE);
 | 
			
		||||
 | 
			
		||||
	asm("cli");
 | 
			
		||||
	asm("hlt");
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										40
									
								
								Kernel/hal/vfs.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								Kernel/hal/vfs.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
#include<fileio.h>
 | 
			
		||||
#include<storage.h>
 | 
			
		||||
 | 
			
		||||
#define MAX_FS_COUNT 64
 | 
			
		||||
 | 
			
		||||
uint32 FsRead(FsNode *node, uint32 offset, uint32 size, uint8 *buffer)
 | 
			
		||||
{
 | 
			
		||||
	if (node->Read != NULL) return node->Read(node, offset, size, buffer);
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32 FsWrite(FsNode *node, uint32 offset, uint32 size, uint8 *buffer)
 | 
			
		||||
{
 | 
			
		||||
	if (node->Write != NULL) return node->Write(node, offset, size, buffer);
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void FsOpen(FsNode *node, uint8 read, uint8 write)
 | 
			
		||||
{
 | 
			
		||||
	if (node->Open != NULL) return node->Open(node, read, write);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void FsClose(FsNode *node)
 | 
			
		||||
{
 | 
			
		||||
	if (node->Close != NULL) return node->Close();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DirectoryEntry *FsReadDir(FsNode *node, uint32 index)
 | 
			
		||||
{
 | 
			
		||||
	if (node->ReadDir != NULL && (node->Flags&7) == FsDirectory)
 | 
			
		||||
		return node->ReadDir(node, index);
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
FsNode *FsFindDir(FsNode *node, char *name)
 | 
			
		||||
{
 | 
			
		||||
	if (node->FindDir != NULL && (node->Flags&7) == FsDirectory)
 | 
			
		||||
		return node->FindDir(node, name);
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user