CTAOS v6
This commit is contained in:
85
SysCore/drivers/BSOD.c
Normal file
85
SysCore/drivers/BSOD.c
Normal file
@@ -0,0 +1,85 @@
|
||||
#include <system.h>
|
||||
#include <conio.h>
|
||||
|
||||
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"
|
||||
};
|
||||
|
||||
|
||||
//void _STOP_ERROR_SCREEN (ISR_stack_regs *r)
|
||||
//{
|
||||
//set_default_colors (0x01, 0x0F); clrscr();
|
||||
/*puts_pos (0, 0, " 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_pos(15, 4, r->gs);
|
||||
puts_pos_font (10, 5, "fs", 0x01, 0x0B); put_hex_pos(15, 5, r->fs);
|
||||
puts_pos_font (10, 6, "es", 0x01, 0x0B); put_hex_pos(15, 6, r->es);
|
||||
puts_pos_font (10, 7, "ds", 0x01, 0x0B); put_hex_pos(15, 7, r->ds);
|
||||
|
||||
puts_pos_font (40, 4, "edi", 0x01, 0x0B); put_hex_pos(45, 4, r->edi);
|
||||
puts_pos_font (40, 5, "esi", 0x01, 0x0B); put_hex_pos(45, 5, r->esi);
|
||||
puts_pos_font (40, 6, "ebp", 0x01, 0x0B); put_hex_pos(45, 6, r->ebp);
|
||||
puts_pos_font (40, 7, "esp", 0x01, 0x0B); put_hex_pos(45, 7, r->esp);
|
||||
|
||||
puts_pos_font (10, 9, "eax", 0x01, 0x0B); put_hex_pos(15, 9, r->eax);
|
||||
puts_pos_font (10, 10, "ebx", 0x01, 0x0B); put_hex_pos(15, 10, r->ebx);
|
||||
puts_pos_font (40, 9, "ecx", 0x01, 0x0B); put_hex_pos(45, 9, r->ecx);
|
||||
puts_pos_font (40, 10, "edx", 0x01, 0x0B); put_hex_pos(45, 10, r->edx);
|
||||
|
||||
puts_pos_font (10, 12, "int_no", 0x01, 0x0B); put_hex_pos(17, 12, r->int_no);
|
||||
puts_pos_font (10, 14, "Error code:", 0x01, 0x0B); put_hex_pos(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_pos(17, 17, r->eip);
|
||||
puts_pos_font (10, 18, "cs", 0x01, 0x0B); put_hex_pos(17, 18, r->cs);
|
||||
puts_pos_font (10, 19, "eflags", 0x01, 0x0B); put_hex_pos(17, 19, r->eflags);
|
||||
puts_pos_font (10, 20, "useresp", 0x01, 0x0B); put_hex_pos(17, 20, r->useresp);
|
||||
puts_pos_font (10, 21, "ss", 0x01, 0x0B); put_hex_pos(17, 21, r->ss);
|
||||
|
||||
puts_pos_font (29, 24, "!!! System Halted !!!", 0x01, 0x0C);*/
|
||||
//}
|
||||
|
||||
/*void _STOP_ERROR_SCREEN (ISR_stack_regs *r)
|
||||
{
|
||||
puts_pos_font (30, 24, "Stop error 0x", 0x01, 0x0B); put_hex_pos(37, 24, r->int_no);
|
||||
puts_pos(50, 24, exception_messages[r->int_no]);
|
||||
|
||||
puts_pos_font (5, 24, "!!! System Halted !!!", 0x01, 0x0C);
|
||||
}*/
|
||||
|
||||
void _STOP_ERROR_SCREEN (ISR_stack_regs *r)
|
||||
{
|
||||
cprintf ("%#0C** Fatal Error: "); cprintf("%#0E %s \n\r", exception_messages[r->int_no]);
|
||||
for (;;);
|
||||
}
|
20
SysCore/drivers/clock/clock.h
Normal file
20
SysCore/drivers/clock/clock.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef __PIT_H
|
||||
#define __PIT_H
|
||||
|
||||
#include <regs.h>
|
||||
#include <time.h>
|
||||
|
||||
extern void i86_PitHandler(ISR_stack_regs *r);
|
||||
extern void i86_PitInitialize(int freq);
|
||||
extern unsigned char PitIsInitialized();
|
||||
extern void PitSetFrequency(int frequency);
|
||||
extern unsigned int PitGetFrequency();
|
||||
|
||||
extern TIME ClockGetTime();
|
||||
extern unsigned int ClockSetTickCount(unsigned int i);
|
||||
extern unsigned int ClockGetTickCount();
|
||||
|
||||
extern void i86_SetRTC (const TIME* time);
|
||||
extern void i86_GetRTC(TIME* tim);
|
||||
|
||||
#endif
|
120
SysCore/drivers/clock/pit.c
Normal file
120
SysCore/drivers/clock/pit.c
Normal file
@@ -0,0 +1,120 @@
|
||||
#include <system.h>
|
||||
#include <time.h>
|
||||
#include "clock.h"
|
||||
|
||||
volatile unsigned int ClockTicks = 0;
|
||||
volatile unsigned int ClockFrequency = 0;
|
||||
unsigned char PitInitialized = 0;
|
||||
volatile TIME _InternalClock;
|
||||
|
||||
|
||||
void PitSetFrequency(int frequency)
|
||||
{
|
||||
int divisor = 1193180/frequency; // 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
|
||||
ClockFrequency = frequency;
|
||||
}
|
||||
|
||||
void i86_PitHandler(ISR_stack_regs *r)
|
||||
{
|
||||
ClockTicks++; // count tick
|
||||
if (ClockTicks % ClockFrequency == 0)
|
||||
_CLOCK_INC((TIME*)&_InternalClock); // update internal clock
|
||||
}
|
||||
|
||||
unsigned int ClockSetTickCount(unsigned int i)
|
||||
{
|
||||
unsigned int r = ClockTicks;
|
||||
ClockTicks = i;
|
||||
return r;
|
||||
}
|
||||
|
||||
unsigned int ClockGetTickCount()
|
||||
{
|
||||
return ClockTicks;
|
||||
}
|
||||
unsigned int PitGetFrequency()
|
||||
{
|
||||
return ClockFrequency;
|
||||
}
|
||||
|
||||
void i86_PitInitialize(int freq)
|
||||
{
|
||||
PitSetFrequency(freq);
|
||||
ClockTicks = 0;
|
||||
|
||||
i86_GetRTC((TIME*) &_InternalClock);
|
||||
|
||||
PitInitialized = 1;
|
||||
}
|
||||
|
||||
TIME ClockGetTime()
|
||||
{
|
||||
return _InternalClock;
|
||||
}
|
||||
|
||||
unsigned char PitIsInitialized()
|
||||
{
|
||||
return PitInitialized;
|
||||
}
|
||||
|
||||
|
||||
inline unsigned char CmosRead (unsigned char address)
|
||||
{
|
||||
outportb(0x70, address); iowait();
|
||||
return inportb(0x71);
|
||||
}
|
||||
|
||||
inline void CmosWrite (unsigned char address, unsigned char val)
|
||||
{
|
||||
outportb(0x70, address); iowait();
|
||||
outportb(0x71, val);
|
||||
}
|
||||
|
||||
void i86_SetRTC (const TIME* time)
|
||||
{
|
||||
unsigned char BCD = ((CmosRead(0x0b)&4)==0) ? 1 : 0;
|
||||
unsigned char ampm = ((CmosRead(0x0b)&2)==0) ? 1 : 0;
|
||||
|
||||
CmosWrite (0, (BCD) ? (time->second%10) | (time->second/10*16) : time->second); // Seconds
|
||||
CmosWrite (2, (BCD) ? (time->minute%10) | (time->minute/10*16) : time->minute); // Minutes
|
||||
|
||||
if (ampm && time->hour > 12) // Hours
|
||||
CmosWrite (4, (BCD) ? (((time->hour - 12) % 10) | ((time->hour - 12)/10*16) | 0x80) : (time->hour | 0x80) );
|
||||
|
||||
else if (ampm && time->hour == 0) // Midnight convention: 12 PM = 00:00
|
||||
CmosWrite (4, (BCD) ? 0x92 : 0x8C);
|
||||
|
||||
else CmosWrite (4, (BCD) ? (time->hour%10) | (time->hour/10*16) : time->hour); // 24h / AM
|
||||
|
||||
CmosWrite (6, (BCD) ? (time->weekday%10) | (time->weekday/10*16) : time->weekday); // Weekday
|
||||
CmosWrite (7, (BCD) ? (time->day%10) | (time->day/10*16) : time->day); // Day
|
||||
CmosWrite (8, (BCD) ? (time->month%10) | (time->month/10*16) : time->month); // Month
|
||||
CmosWrite (9, (BCD) ? (time->year%10) | (time->year/10*16) : time->year); // Year
|
||||
CmosWrite (0x32, (BCD) ? (time->century%10) | (time->century/10*16) : time->century); // Century
|
||||
}
|
||||
|
||||
void i86_GetRTC(TIME* tim)
|
||||
{
|
||||
unsigned char BCD = ((CmosRead(0x0b)&4)==0) ? 1 : 0;
|
||||
unsigned char am_pm = ((CmosRead(0x0b)&2)==0) ? 1 : 0;
|
||||
|
||||
tim->second = (BCD) ? (CmosRead(0x00)%16) + 10*(CmosRead(0x00)/16): CmosRead(0x00);
|
||||
tim->minute = (BCD) ? (CmosRead(0x02)%16) + 10*(CmosRead(0x02)/16): CmosRead(0x02);
|
||||
|
||||
// Time is PM
|
||||
if (am_pm && CmosRead(0x04)&80) {
|
||||
tim->hour = (BCD) ? ((CmosRead(0x04)-0x80)%16) + 10*((CmosRead(0x04)-0x80)/16): CmosRead(0x04)-0x80;
|
||||
tim->hour += 12;
|
||||
}
|
||||
// 24Hour format, or AM
|
||||
else tim->hour = (BCD) ? (CmosRead(0x04)%16) + 10*(CmosRead(0x04)/16): CmosRead(0x04);
|
||||
|
||||
tim->weekday = (BCD) ? (CmosRead(0x06)%16) + 10*(CmosRead(0x06)/16): CmosRead(0x06);
|
||||
tim->day = (BCD) ? (CmosRead(0x07)%16) + 10*(CmosRead(0x07)/16): CmosRead(0x07);
|
||||
tim->month = (BCD) ? (CmosRead(0x08)%16) + 10*(CmosRead(0x08)/16): CmosRead(0x08);
|
||||
tim->year = (BCD) ? (CmosRead(0x09)%16) + 10*(CmosRead(0x09)/16): CmosRead(0x09);
|
||||
tim->century = (BCD) ? (CmosRead(0x32)%16) + 10*(CmosRead(0x32)/16): CmosRead(0x32);
|
||||
}
|
43
SysCore/drivers/compile.bat
Normal file
43
SysCore/drivers/compile.bat
Normal file
@@ -0,0 +1,43 @@
|
||||
@echo off
|
||||
|
||||
set loader_name=loader
|
||||
set nasm_path=C:\nasm
|
||||
set djgpp_path=C:\mingw\bin
|
||||
|
||||
|
||||
@echo ***************** CTA KERNEL *****************
|
||||
|
||||
:KernelEntry
|
||||
@echo.
|
||||
@echo Building Kernel entry...
|
||||
@echo * Compiling kernel loader...
|
||||
%nasm_path%\nasm.exe -f aout -o ./objects/%loader_name%.o %loader_name%.asm
|
||||
|
||||
@echo * Compiling kernel main...
|
||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I./include -c -o ./objects/main.o main.c
|
||||
|
||||
|
||||
:KernelSTDLIB
|
||||
cd lib
|
||||
call compile.bat
|
||||
cd..
|
||||
|
||||
:KernelMemoryManager
|
||||
cd memory
|
||||
call compile.bat
|
||||
cd..
|
||||
|
||||
|
||||
rem here go other sources:
|
||||
|
||||
rem here go other sources ^
|
||||
|
||||
:Finish
|
||||
cd objects
|
||||
@echo Linking...
|
||||
%djgpp_path%\ld -T link.ld
|
||||
@echo.
|
||||
|
||||
echo Copying to floppy drive...
|
||||
copy KERNEL.BIN A:\KERNEL.CTA
|
||||
cd..
|
18
SysCore/drivers/cpu/compile.bat
Normal file
18
SysCore/drivers/cpu/compile.bat
Normal file
@@ -0,0 +1,18 @@
|
||||
@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:\mingw\bin
|
||||
set objpath=../../objects
|
||||
set incpath=../../include
|
||||
|
||||
@echo on
|
||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/cpu.o cpu.c
|
||||
|
||||
@echo off
|
||||
@echo .
|
||||
@echo Done!
|
||||
|
||||
@pause
|
40
SysCore/drivers/cpu/cpu.c
Normal file
40
SysCore/drivers/cpu/cpu.c
Normal file
@@ -0,0 +1,40 @@
|
||||
#include <system.h>
|
||||
#include "cpu.h"
|
||||
#include "gdt/gdt.h"
|
||||
#include "idt/idt.h"
|
||||
#include "irq/irq.h"
|
||||
#include "isrs/isrs.h"
|
||||
|
||||
#define cpuid(in, a, b, c, d) __asm__("cpuid": "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "a" (in));
|
||||
|
||||
// initializes cpu resources
|
||||
void i86_CpuInitialize()
|
||||
{
|
||||
i86_GdtInstall();
|
||||
i86_IdtInstall();
|
||||
i86_IsrsInstall();
|
||||
i86_IrqInstall();
|
||||
}
|
||||
|
||||
void i86_CpuShutdown()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
char* i86_CpuGetVendor()
|
||||
{
|
||||
unsigned unused;
|
||||
unsigned static arr[3];
|
||||
|
||||
cpuid(0, unused, arr[0], arr[2], arr[1]);
|
||||
|
||||
return (char*) arr;
|
||||
}
|
||||
|
||||
_R32BIT i86_CpuID(unsigned function)
|
||||
{
|
||||
_R32BIT ret = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
cpuid(function, ret.eax, ret.ebx, ret.ecx, ret.edx);
|
||||
return ret;
|
||||
}
|
17
SysCore/drivers/cpu/cpu.h
Normal file
17
SysCore/drivers/cpu/cpu.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef _CPU_H_INCLUDED
|
||||
#define _CPU_H_INCLUDED
|
||||
|
||||
#include <stdint.h>
|
||||
#include <regs.h>
|
||||
#include "gdt/gdt.h"
|
||||
#include "idt/idt.h"
|
||||
#include "irq/irq.h"
|
||||
#include "irq/pic.h"
|
||||
#include "isrs/isrs.h"
|
||||
|
||||
|
||||
extern void i86_CpuInitialize ();
|
||||
extern void i86_CpuShutdown ();
|
||||
extern char* i86_CpuGetVendor ();
|
||||
|
||||
#endif
|
20
SysCore/drivers/cpu/gdt/gdt.asm
Normal file
20
SysCore/drivers/cpu/gdt/gdt.asm
Normal file
@@ -0,0 +1,20 @@
|
||||
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.
|
||||
; This is declared in C as 'extern void gdt_flush();'
|
||||
|
||||
global _i86_GdtFlush ; Allows the C code to link to this
|
||||
extern _gp ; Says that '_gp' is in another file
|
||||
_i86_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!
|
76
SysCore/drivers/cpu/gdt/gdt.c
Normal file
76
SysCore/drivers/cpu/gdt/gdt.c
Normal file
@@ -0,0 +1,76 @@
|
||||
/******************************************************************
|
||||
* gdt.c - GLOBAL DESCRIPTOR TABLE *
|
||||
* Contains function prototypes for setting up the GDT *
|
||||
******************************************************************/
|
||||
#define MAX_DESCRIPTORS 5
|
||||
#include "gdt.h"
|
||||
|
||||
extern void i86_GdtInstall();
|
||||
|
||||
/* 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 i86_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 gdt_entry* i86_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 i86_GdtInstall()
|
||||
{
|
||||
/* Setup the GDT pointer and limit */
|
||||
gp.limit = (sizeof(struct GdtEntry) * 3) - 1;
|
||||
gp.base = (unsigned int)&gdt;
|
||||
|
||||
/* Our NULL descriptor */
|
||||
i86_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 */
|
||||
i86_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 */
|
||||
i86_GdtSetGate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
|
||||
|
||||
/* User mode Code segment*/
|
||||
i86_GdtSetGate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF);
|
||||
|
||||
/* User mode data segment*/
|
||||
i86_GdtSetGate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF);
|
||||
|
||||
/* Flush out the old GDT and install the new changes! */
|
||||
i86_GdtFlush();
|
||||
}
|
||||
|
38
SysCore/drivers/cpu/gdt/gdt.h
Normal file
38
SysCore/drivers/cpu/gdt/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 i86_GdtInstall();
|
||||
extern void i86_GdtFlush();
|
||||
extern void i86_GdtSetGate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran);
|
||||
//extern struct GdtEntry* i86_GdtGetGate(int num);
|
||||
|
||||
#endif
|
9
SysCore/drivers/cpu/idt/idt.asm
Normal file
9
SysCore/drivers/cpu/idt/idt.asm
Normal file
@@ -0,0 +1,9 @@
|
||||
bits 32
|
||||
|
||||
; !!! IDT !!!
|
||||
; Loads the IDT defined in '_idtp'
|
||||
global _i86_IdtLoad
|
||||
extern _idtp
|
||||
_i86_IdtLoad:
|
||||
lidt [_idtp]
|
||||
ret
|
45
SysCore/drivers/cpu/idt/idt.c
Normal file
45
SysCore/drivers/cpu/idt/idt.c
Normal file
@@ -0,0 +1,45 @@
|
||||
/******************************************************************
|
||||
* idt.h - INTERRUPT DESCRIPTOR TABLE *
|
||||
* Contains structures and function declarations for IDT *
|
||||
******************************************************************/
|
||||
#include <system.h>
|
||||
#include "idt.h"
|
||||
|
||||
extern void i86_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 i86_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* i86_IdtGetGate(unsigned char num)
|
||||
{
|
||||
return &idt[num];
|
||||
}
|
||||
|
||||
/* Installs the IDT */
|
||||
void i86_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 */
|
||||
i86_IdtLoad();
|
||||
}
|
31
SysCore/drivers/cpu/idt/idt.h
Normal file
31
SysCore/drivers/cpu/idt/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 i86_IdtSetGate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags);
|
||||
extern struct IdtEntry* i86_IdtGetGate(unsigned char num);
|
||||
extern void i86_IdtInstall();
|
||||
|
||||
#endif
|
159
SysCore/drivers/cpu/irq/irq.asm
Normal file
159
SysCore/drivers/cpu/irq/irq.asm
Normal file
@@ -0,0 +1,159 @@
|
||||
bits 32
|
||||
|
||||
; !!! IRQ !!!
|
||||
global _i86_irq0
|
||||
global _i86_irq1
|
||||
global _i86_irq2
|
||||
global _i86_irq3
|
||||
global _i86_irq4
|
||||
global _i86_irq5
|
||||
global _i86_irq6
|
||||
global _i86_irq7
|
||||
global _i86_irq8
|
||||
global _i86_irq9
|
||||
global _i86_irq10
|
||||
global _i86_irq11
|
||||
global _i86_irq12
|
||||
global _i86_irq13
|
||||
global _i86_irq14
|
||||
global _i86_irq15
|
||||
|
||||
; 32: IRQ0
|
||||
_i86_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
|
||||
_i86_irq1:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 33
|
||||
jmp irq_common_stub
|
||||
|
||||
; 34: IRQ2
|
||||
_i86_irq2:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 34
|
||||
jmp irq_common_stub
|
||||
|
||||
; 35: IRQ3
|
||||
_i86_irq3:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 35
|
||||
jmp irq_common_stub
|
||||
|
||||
; 36: IRQ4
|
||||
_i86_irq4:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 36
|
||||
jmp irq_common_stub
|
||||
|
||||
; 37: IRQ5
|
||||
_i86_irq5:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 37
|
||||
jmp irq_common_stub
|
||||
|
||||
; 38: IRQ6
|
||||
_i86_irq6:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 38
|
||||
jmp irq_common_stub
|
||||
|
||||
; 39: IRQ7
|
||||
_i86_irq7:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 39
|
||||
jmp irq_common_stub
|
||||
|
||||
; 40: IRQ8
|
||||
_i86_irq8:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 40
|
||||
jmp irq_common_stub
|
||||
; 41: IRQ9
|
||||
_i86_irq9:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 41
|
||||
jmp irq_common_stub
|
||||
|
||||
; 42: IRQ10
|
||||
_i86_irq10:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 42
|
||||
jmp irq_common_stub
|
||||
|
||||
; 43: IRQ11
|
||||
_i86_irq11:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 43
|
||||
jmp irq_common_stub
|
||||
|
||||
; 44: IRQ12
|
||||
_i86_irq12:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 44
|
||||
jmp irq_common_stub
|
||||
|
||||
; 45: IRQ13
|
||||
_i86_irq13:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 45
|
||||
jmp irq_common_stub
|
||||
|
||||
; 46: IRQ14
|
||||
_i86_irq14:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 46
|
||||
jmp irq_common_stub
|
||||
|
||||
; 47: IRQ15
|
||||
_i86_irq15:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 47
|
||||
jmp irq_common_stub
|
||||
|
||||
extern _i86_IrqHandler
|
||||
|
||||
; This is a stub that we have created for IRQ based ISRs. This calls
|
||||
; '_i86_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, _i86_IrqHandler
|
||||
call eax
|
||||
pop eax
|
||||
pop gs
|
||||
pop fs
|
||||
pop es
|
||||
pop ds
|
||||
popa
|
||||
add esp, 8
|
||||
iret
|
99
SysCore/drivers/cpu/irq/irq.c
Normal file
99
SysCore/drivers/cpu/irq/irq.c
Normal file
@@ -0,0 +1,99 @@
|
||||
#include <system.h>
|
||||
#include "pic.h"
|
||||
#include "irq.h"
|
||||
#include "../idt/idt.h"
|
||||
|
||||
/* These are own ISRs that point to our special IRQ handler
|
||||
* instead of the regular 'fault_handler' function */
|
||||
extern void i86_irq0();
|
||||
extern void i86_irq1();
|
||||
extern void i86_irq2();
|
||||
extern void i86_irq3();
|
||||
extern void i86_irq4();
|
||||
extern void i86_irq5();
|
||||
extern void i86_irq6();
|
||||
extern void i86_irq7();
|
||||
extern void i86_irq8();
|
||||
extern void i86_irq9();
|
||||
extern void i86_irq10();
|
||||
extern void i86_irq11();
|
||||
extern void i86_irq12();
|
||||
extern void i86_irq13();
|
||||
extern void i86_irq14();
|
||||
extern void i86_irq15();
|
||||
|
||||
/* 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 i86_IrqInstallHandler (int irq, void (*handler)(ISR_stack_regs *r))
|
||||
{
|
||||
IrqRoutines[irq] = handler;
|
||||
}
|
||||
|
||||
void i86_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 i86_IrqInstall()
|
||||
{
|
||||
i86_PicRemap(32,40);
|
||||
|
||||
i86_IdtSetGate(32, (unsigned)i86_irq0, 0x08, 0x8E);
|
||||
i86_IdtSetGate(33, (unsigned)i86_irq1, 0x08, 0x8E);
|
||||
i86_IdtSetGate(34, (unsigned)i86_irq2, 0x08, 0x8E);
|
||||
i86_IdtSetGate(35, (unsigned)i86_irq3, 0x08, 0x8E);
|
||||
i86_IdtSetGate(36, (unsigned)i86_irq4, 0x08, 0x8E);
|
||||
i86_IdtSetGate(37, (unsigned)i86_irq5, 0x08, 0x8E);
|
||||
i86_IdtSetGate(38, (unsigned)i86_irq6, 0x08, 0x8E);
|
||||
i86_IdtSetGate(39, (unsigned)i86_irq7, 0x08, 0x8E);
|
||||
i86_IdtSetGate(40, (unsigned)i86_irq8, 0x08, 0x8E);
|
||||
i86_IdtSetGate(41, (unsigned)i86_irq9, 0x08, 0x8E);
|
||||
i86_IdtSetGate(42, (unsigned)i86_irq10, 0x08, 0x8E);
|
||||
i86_IdtSetGate(43, (unsigned)i86_irq11, 0x08, 0x8E);
|
||||
i86_IdtSetGate(44, (unsigned)i86_irq12, 0x08, 0x8E);
|
||||
i86_IdtSetGate(45, (unsigned)i86_irq13, 0x08, 0x8E);
|
||||
i86_IdtSetGate(46, (unsigned)i86_irq14, 0x08, 0x8E);
|
||||
i86_IdtSetGate(47, (unsigned)i86_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 i86_IrqHandler (ISR_stack_regs *r)
|
||||
{
|
||||
/* This is a blank function pointer */
|
||||
void (*handler)(ISR_stack_regs *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(0x0A, 0x20);
|
||||
|
||||
/* In either case, we need to send an EOI to the master
|
||||
* interrupt controller too */
|
||||
outportb(0x20, 0x20);
|
||||
}
|
10
SysCore/drivers/cpu/irq/irq.h
Normal file
10
SysCore/drivers/cpu/irq/irq.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#ifndef __IRQ_H
|
||||
#define __IRQ_H
|
||||
|
||||
#include <regs.h>
|
||||
|
||||
extern void i86_IrqInstallHandler (int irq, void (*handler)(ISR_stack_regs *r));
|
||||
extern void i86_IrqUninstallHandler (int irq);
|
||||
extern void i86_IrqInstall();
|
||||
|
||||
#endif
|
23
SysCore/drivers/cpu/irq/pic.c
Normal file
23
SysCore/drivers/cpu/irq/pic.c
Normal file
@@ -0,0 +1,23 @@
|
||||
#include <system.h>
|
||||
#include "pic.h"
|
||||
|
||||
void i86_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
SysCore/drivers/cpu/irq/pic.h
Normal file
6
SysCore/drivers/cpu/irq/pic.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef _PIC_H
|
||||
#define _PIC_H
|
||||
|
||||
extern void i86_PicRemap(int pic1, int pic2);
|
||||
|
||||
#endif
|
217
SysCore/drivers/cpu/isrs/isrs.asm
Normal file
217
SysCore/drivers/cpu/isrs/isrs.asm
Normal file
@@ -0,0 +1,217 @@
|
||||
bits 32
|
||||
|
||||
; !!! ISRs !!!
|
||||
global _i86_isr0
|
||||
global _i86_isr1
|
||||
global _i86_isr2
|
||||
global _i86_isr3
|
||||
global _i86_isr4
|
||||
global _i86_isr5
|
||||
global _i86_isr6
|
||||
global _i86_isr7
|
||||
global _i86_isr8
|
||||
global _i86_isr9
|
||||
global _i86_isr10
|
||||
global _i86_isr11
|
||||
global _i86_isr12
|
||||
global _i86_isr13
|
||||
global _i86_isr14
|
||||
global _i86_isr15
|
||||
global _i86_isr16
|
||||
global _i86_isr17
|
||||
global _i86_isr18
|
||||
global _i86_isr19
|
||||
global _i86_isr20
|
||||
global _i86_isr21
|
||||
global _i86_isr22
|
||||
global _i86_isr23
|
||||
global _i86_isr24
|
||||
global _i86_isr25
|
||||
global _i86_isr26
|
||||
global _i86_isr27
|
||||
global _i86_isr28
|
||||
global _i86_isr29
|
||||
global _i86_isr30
|
||||
global _i86_isr31
|
||||
|
||||
_i86_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
|
||||
_i86_isr1:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 1
|
||||
jmp isr_common_stub
|
||||
_i86_isr2:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 2
|
||||
jmp isr_common_stub
|
||||
_i86_isr3:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 3
|
||||
jmp isr_common_stub
|
||||
_i86_isr4:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 4
|
||||
jmp isr_common_stub
|
||||
_i86_isr5:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 5
|
||||
jmp isr_common_stub
|
||||
_i86_isr6:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 6
|
||||
jmp isr_common_stub
|
||||
_i86_isr7:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 7
|
||||
jmp isr_common_stub
|
||||
_i86_isr8:
|
||||
cli
|
||||
push byte 8
|
||||
jmp isr_common_stub
|
||||
_i86_isr9:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 9
|
||||
jmp isr_common_stub
|
||||
_i86_isr10:
|
||||
cli
|
||||
push byte 10
|
||||
jmp isr_common_stub
|
||||
_i86_isr11:
|
||||
cli
|
||||
push byte 11
|
||||
jmp isr_common_stub
|
||||
_i86_isr12:
|
||||
cli
|
||||
push byte 12
|
||||
jmp isr_common_stub
|
||||
_i86_isr13:
|
||||
cli
|
||||
push byte 13
|
||||
jmp isr_common_stub
|
||||
_i86_isr14:
|
||||
cli
|
||||
push byte 14
|
||||
jmp isr_common_stub
|
||||
_i86_isr15:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 15
|
||||
jmp isr_common_stub
|
||||
_i86_isr16:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 16
|
||||
jmp isr_common_stub
|
||||
_i86_isr17:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 17
|
||||
jmp isr_common_stub
|
||||
_i86_isr18:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 18
|
||||
jmp isr_common_stub
|
||||
_i86_isr19:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 19
|
||||
jmp isr_common_stub
|
||||
_i86_isr20:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 20
|
||||
jmp isr_common_stub
|
||||
_i86_isr21:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 21
|
||||
jmp isr_common_stub
|
||||
_i86_isr22:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 22
|
||||
jmp isr_common_stub
|
||||
_i86_isr23:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 23
|
||||
jmp isr_common_stub
|
||||
_i86_isr24:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 24
|
||||
jmp isr_common_stub
|
||||
_i86_isr25:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 25
|
||||
jmp isr_common_stub
|
||||
_i86_isr26:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 26
|
||||
jmp isr_common_stub
|
||||
_i86_isr27:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 27
|
||||
jmp isr_common_stub
|
||||
_i86_isr28:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 28
|
||||
jmp isr_common_stub
|
||||
_i86_isr29:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 29
|
||||
jmp isr_common_stub
|
||||
_i86_isr30:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 30
|
||||
jmp isr_common_stub
|
||||
_i86_isr31:
|
||||
cli
|
||||
push byte 0
|
||||
push byte 31
|
||||
jmp isr_common_stub
|
||||
|
||||
extern _i86_FaultHandler
|
||||
|
||||
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, _i86_FaultHandler
|
||||
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!
|
115
SysCore/drivers/cpu/isrs/isrs.c
Normal file
115
SysCore/drivers/cpu/isrs/isrs.c
Normal file
@@ -0,0 +1,115 @@
|
||||
#include <system.h>
|
||||
#include <conio.h>
|
||||
#include "isrs.h"
|
||||
#include "../idt/idt.h"
|
||||
|
||||
// Assembly coded
|
||||
extern void i86_isr0();
|
||||
extern void i86_isr1();
|
||||
extern void i86_isr2();
|
||||
extern void i86_isr3();
|
||||
extern void i86_isr4();
|
||||
extern void i86_isr5();
|
||||
extern void i86_isr6();
|
||||
extern void i86_isr7();
|
||||
extern void i86_isr8();
|
||||
extern void i86_isr9();
|
||||
extern void i86_isr10();
|
||||
extern void i86_isr11();
|
||||
extern void i86_isr12();
|
||||
extern void i86_isr13();
|
||||
extern void i86_isr14();
|
||||
extern void i86_isr15();
|
||||
extern void i86_isr16();
|
||||
extern void i86_isr17();
|
||||
extern void i86_isr18();
|
||||
extern void i86_isr19();
|
||||
extern void i86_isr20();
|
||||
extern void i86_isr21();
|
||||
extern void i86_isr22();
|
||||
extern void i86_isr23();
|
||||
extern void i86_isr24();
|
||||
extern void i86_isr25();
|
||||
extern void i86_isr26();
|
||||
extern void i86_isr27();
|
||||
extern void i86_isr28();
|
||||
extern void i86_isr29();
|
||||
extern void i86_isr30();
|
||||
extern void i86_isr31();
|
||||
|
||||
|
||||
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 i86_IsrsInstall()
|
||||
{
|
||||
i86_IdtSetGate(0, (unsigned)i86_isr0, 0x08, 0x8E);
|
||||
i86_IdtSetGate(1, (unsigned)i86_isr1, 0x08, 0x8E);
|
||||
i86_IdtSetGate(2, (unsigned)i86_isr2, 0x08, 0x8E);
|
||||
i86_IdtSetGate(3, (unsigned)i86_isr3, 0x08, 0x8E);
|
||||
i86_IdtSetGate(4, (unsigned)i86_isr4, 0x08, 0x8E);
|
||||
i86_IdtSetGate(5, (unsigned)i86_isr5, 0x08, 0x8E);
|
||||
i86_IdtSetGate(6, (unsigned)i86_isr6, 0x08, 0x8E);
|
||||
i86_IdtSetGate(7, (unsigned)i86_isr7, 0x08, 0x8E);
|
||||
i86_IdtSetGate(8, (unsigned)i86_isr8, 0x08, 0x8E);
|
||||
i86_IdtSetGate(9, (unsigned)i86_isr9, 0x08, 0x8E);
|
||||
i86_IdtSetGate(10, (unsigned)i86_isr10, 0x08, 0x8E);
|
||||
i86_IdtSetGate(11, (unsigned)i86_isr11, 0x08, 0x8E);
|
||||
i86_IdtSetGate(12, (unsigned)i86_isr12, 0x08, 0x8E);
|
||||
i86_IdtSetGate(13, (unsigned)i86_isr13, 0x08, 0x8E);
|
||||
i86_IdtSetGate(14, (unsigned)i86_isr14, 0x08, 0x8E);
|
||||
i86_IdtSetGate(15, (unsigned)i86_isr15, 0x08, 0x8E);
|
||||
i86_IdtSetGate(16, (unsigned)i86_isr16, 0x08, 0x8E);
|
||||
i86_IdtSetGate(17, (unsigned)i86_isr17, 0x08, 0x8E);
|
||||
i86_IdtSetGate(18, (unsigned)i86_isr18, 0x08, 0x8E);
|
||||
i86_IdtSetGate(19, (unsigned)i86_isr19, 0x08, 0x8E);
|
||||
i86_IdtSetGate(20, (unsigned)i86_isr20, 0x08, 0x8E);
|
||||
i86_IdtSetGate(21, (unsigned)i86_isr21, 0x08, 0x8E);
|
||||
i86_IdtSetGate(22, (unsigned)i86_isr22, 0x08, 0x8E);
|
||||
i86_IdtSetGate(23, (unsigned)i86_isr23, 0x08, 0x8E);
|
||||
i86_IdtSetGate(24, (unsigned)i86_isr24, 0x08, 0x8E);
|
||||
i86_IdtSetGate(25, (unsigned)i86_isr25, 0x08, 0x8E);
|
||||
i86_IdtSetGate(26, (unsigned)i86_isr26, 0x08, 0x8E);
|
||||
i86_IdtSetGate(27, (unsigned)i86_isr27, 0x08, 0x8E);
|
||||
i86_IdtSetGate(28, (unsigned)i86_isr28, 0x08, 0x8E);
|
||||
i86_IdtSetGate(29, (unsigned)i86_isr29, 0x08, 0x8E);
|
||||
i86_IdtSetGate(30, (unsigned)i86_isr30, 0x08, 0x8E);
|
||||
i86_IdtSetGate(31, (unsigned)i86_isr31, 0x08, 0x8E);
|
||||
}
|
||||
|
||||
|
||||
void i86_IsrsInstallHandler(int interr, void (*function)(ISR_stack_regs *r))
|
||||
{
|
||||
if (interr < 32) IdtFaultHandlers[interr] = function;
|
||||
}
|
||||
|
||||
void i86_IsrsUninstallHandler(int interr)
|
||||
{
|
||||
if (interr < 32) IdtFaultHandlers[interr] = 0;
|
||||
}
|
||||
|
||||
/* 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 i86_FaultHandler(ISR_stack_regs *r)
|
||||
{
|
||||
/* Is this a fault whose number is from 0 to 31? */
|
||||
if (r->int_no < 32)
|
||||
{
|
||||
void (*func)(ISR_stack_regs *r);
|
||||
func = IdtFaultHandlers[r->int_no];
|
||||
|
||||
// Halt system if unhandled
|
||||
if (!func) {
|
||||
cprintf("%#0C*** %#0EFatal error: Unhandled interrupt (INT%u)", r->int_no);
|
||||
for(;;);
|
||||
}
|
||||
|
||||
else (*func)(r);
|
||||
}
|
||||
}
|
8
SysCore/drivers/cpu/isrs/isrs.h
Normal file
8
SysCore/drivers/cpu/isrs/isrs.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef __ISRS_H_
|
||||
#define __ISRS_H_
|
||||
|
||||
extern void i86_IsrsInstall();
|
||||
extern void i86_IsrsInstallHandler(int interr, void (*function)(ISR_stack_regs *r));
|
||||
extern void i86_IsrsUninstallHandler(int interr);
|
||||
|
||||
#endif
|
55
SysCore/drivers/drivers.c
Normal file
55
SysCore/drivers/drivers.c
Normal file
@@ -0,0 +1,55 @@
|
||||
#include <system.h>
|
||||
#include "cpu/cpu.h"
|
||||
#include "clock/clock.h"
|
||||
#include "floppy/floppy.h"
|
||||
#include <drivers/keyboard.h>
|
||||
//BSOD
|
||||
|
||||
extern void _STOP_ERROR_SCREEN(ISR_stack_regs *);
|
||||
|
||||
void DriversInstall()
|
||||
{
|
||||
// Initialize CPU stuff (GDT, IDT etc)
|
||||
i86_CpuInitialize();
|
||||
|
||||
// Install default fault handler
|
||||
int i;
|
||||
for (i=0; i<32; i++)
|
||||
i86_IsrsInstallHandler(i, _STOP_ERROR_SCREEN);
|
||||
|
||||
|
||||
// Start installing keyboard
|
||||
i86_IrqInstallHandler(1, i86_KeyboardHandler);
|
||||
KeyboardInstallA();
|
||||
|
||||
// Install PIT
|
||||
i86_PitInitialize(100);
|
||||
i86_IrqInstallHandler(0, i86_PitHandler);
|
||||
|
||||
// Finish installing keyboard
|
||||
KeyboardInstallB();
|
||||
|
||||
// Install floppy driver
|
||||
asm volatile ("sti");
|
||||
i86_IrqInstallHandler(6, i86_FloppyHandler);
|
||||
FloppyInstall();
|
||||
|
||||
}
|
||||
|
||||
void SystemShutDown()
|
||||
{
|
||||
i86_CpuShutdown();
|
||||
// TODO: real shutdown
|
||||
}
|
||||
|
||||
void SystemReboot()
|
||||
{
|
||||
unsigned char good = 0x02;
|
||||
while ((good & 0x02) != 0)
|
||||
good = inportb(0x64);
|
||||
outportb(0x64, 0xFE);
|
||||
|
||||
asm volatile ("cli");
|
||||
asm volatile ("hlt");
|
||||
}
|
||||
|
9
SysCore/drivers/drivers.h
Normal file
9
SysCore/drivers/drivers.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef __DRIVERS__H__
|
||||
#define __DRIVERS__H__
|
||||
|
||||
|
||||
extern void DriversInstall();
|
||||
extern void SystemShutDown();
|
||||
extern void SystemReboot();
|
||||
|
||||
#endif
|
34
SysCore/drivers/filesys/fat.c
Normal file
34
SysCore/drivers/filesys/fat.c
Normal file
@@ -0,0 +1,34 @@
|
||||
#include "../floppy/floppy.h"
|
||||
//#include "vfs.h"
|
||||
#include "fat.h"
|
||||
|
||||
#include <conio.h>
|
||||
|
||||
// Detect what FAT is used
|
||||
unsigned FATDetect(unsigned TotalClusters)
|
||||
{
|
||||
if (TotalClusters == 0) return 0;
|
||||
if (TotalClusters < 4085) return 12;
|
||||
if (TotalClusters < 65525) return 16;
|
||||
return 32;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*FatMountInfo FloppyMount(int drive)
|
||||
{
|
||||
FatMountInfo a;
|
||||
FATBootSectorPointer fat = (FATBootSectorPointer)0x7e00;
|
||||
FloppyReadSector((unsigned*)fat, drive, 0);
|
||||
|
||||
// Write mount info
|
||||
a.FATEntrySize = 8;
|
||||
a.FATOffset = 1;
|
||||
a.FATSize = (unsigned)fat->SectorsPerFAT;
|
||||
a.NumberOfRootEntries = (unsigned)fat->NumberOfDirectoryEntries;
|
||||
a.NumberOfSectors = (unsigned)(fat->NumberOfSectors == 0) ? (fat->NumberOfSectorsLong) : (fat->NumberOfSectors);
|
||||
a.RootOffset = (unsigned)(fat->NumberOfFATs)*a.FATSize + 1;
|
||||
a.RootSize = (a.NumberOfRootEntries * 32) / (unsigned)fat->BytesPerSector;
|
||||
|
||||
return a;
|
||||
}*/
|
91
SysCore/drivers/filesys/fat.h
Normal file
91
SysCore/drivers/filesys/fat.h
Normal file
@@ -0,0 +1,91 @@
|
||||
#ifndef __FAT_H__
|
||||
#define __FAT_H__
|
||||
|
||||
typedef struct {
|
||||
unsigned char Drive; //useless
|
||||
unsigned char FlagsNT;
|
||||
unsigned char Signature; // 0x28 or 0x29
|
||||
unsigned SerialNumber;
|
||||
char VolumeLabel[11];
|
||||
char SysIDString[8]; // unreliable
|
||||
} __attribute__((packed)) BPB_EXT_16;
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned SectorsPerFAT;
|
||||
unsigned short Flags;
|
||||
unsigned short Version;
|
||||
unsigned ClusterOfRootDirectory;
|
||||
unsigned short ClusterOfFSInfo;
|
||||
unsigned short ClusterOfBackupBootSector;
|
||||
unsigned char Reserved[12]; // Should be 0 at format
|
||||
unsigned char Drive;
|
||||
unsigned char FlagsNT;
|
||||
unsigned char Signature; // 0x28 or 0x29
|
||||
unsigned SerialNumber;
|
||||
char VolumeLabel[11];
|
||||
char SysIDString[8]; // always FAT12
|
||||
|
||||
} __attribute__((packed)) BPB_EXT_32;
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned char _ignore[3];
|
||||
|
||||
// Bios Parameter Block
|
||||
char OEMIdentify[8];
|
||||
unsigned short BytesPerSector;
|
||||
unsigned char SectorsPerCluster;
|
||||
unsigned short ReservedSectors;
|
||||
unsigned char NumberOfFATs;
|
||||
unsigned short NumberOfDirectoryEntries;
|
||||
unsigned short NumberOfSectors;
|
||||
unsigned char MediaDescriptorType;
|
||||
unsigned short SectorsPerFAT;
|
||||
unsigned short SectorsPerTrack;
|
||||
unsigned short HeadsPerCylinder;
|
||||
unsigned HiddenSectors;
|
||||
unsigned NumberOfSectorsLong;
|
||||
|
||||
union {
|
||||
BPB_EXT_16 Ext16;
|
||||
BPB_EXT_32 Ext32;
|
||||
} Extended;
|
||||
|
||||
} __attribute__((packed)) FATBootSector, *FATBootSectorPointer;
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned NumberOfSectors;
|
||||
unsigned SizeOfSector;
|
||||
unsigned FatOffset;
|
||||
unsigned NumberOfRootEntries;
|
||||
unsigned RootOffset;
|
||||
unsigned SizeOfRoot;
|
||||
unsigned SizeOfFat;
|
||||
unsigned SizeOfFatEntry;
|
||||
unsigned SizeOfCluster;
|
||||
void (*ReadSector) (void* buffer, int lba);
|
||||
} FatMountInfo, *FatMountInfoPointer;
|
||||
|
||||
|
||||
typedef struct {
|
||||
char FileName[8];
|
||||
char Extension[3];
|
||||
unsigned char Atributes;
|
||||
unsigned char Reserved;
|
||||
unsigned char CreateTimeFine;
|
||||
unsigned short CreateTime;
|
||||
unsigned short CreateDate;
|
||||
unsigned short LastAccessedDate;
|
||||
unsigned short EAIndex;
|
||||
unsigned short LastModifiedTime;
|
||||
unsigned short LastModifiedDate;
|
||||
unsigned short FirstCluster;
|
||||
unsigned FileSize;
|
||||
} __attribute__((packed)) FatDirectoryEntry, *FatDirectoryEntryPointer;
|
||||
|
||||
|
||||
extern FatMountInfo FloppyMount(int drive);
|
||||
|
||||
#endif
|
98
SysCore/drivers/filesys/vfs.c
Normal file
98
SysCore/drivers/filesys/vfs.c
Normal file
@@ -0,0 +1,98 @@
|
||||
#include "vfs.h"
|
||||
#define MaxDevices 256
|
||||
|
||||
#define ReturnInvalid() { File ret; ret.Type = FileTypeInvalid; return ret;}
|
||||
|
||||
unsigned CurrentDevice = 0;
|
||||
unsigned DeviceCount = 0;
|
||||
|
||||
FileSystemPointer _FileSystems[MaxDevices];
|
||||
|
||||
File VFSOpenFile (const char* FileName)
|
||||
{
|
||||
unsigned Device = CurrentDevice;
|
||||
|
||||
// No filename specified.
|
||||
if (!FileName) ReturnInvalid();
|
||||
|
||||
// File length
|
||||
int len = strlen(FileName);
|
||||
// File name without drive
|
||||
char* Name = 0;
|
||||
|
||||
// Check if relative or absolute path
|
||||
int i;
|
||||
for (i=0; i < len; i++)
|
||||
if (FileName[i] == ':') {
|
||||
Name = &FileName[i+1];
|
||||
FileName[i] = 0;
|
||||
len = i;
|
||||
}
|
||||
|
||||
// If absolute path, find device
|
||||
if (Name != 0) {
|
||||
for (i=0; i < MaxDevices; i++)
|
||||
if (_FileSystems[i]) {
|
||||
if (strcmp(_FileSystems[i]->Name, FileName) == 0) Device = i;
|
||||
}
|
||||
}
|
||||
// Drive is nonexistant or current drive not mounted
|
||||
if (i==MaxDevices || !_FileSystems[Device]) ReturnInvalid();
|
||||
|
||||
// Open file
|
||||
return _FileSystems[Device]->Open((Name) ? Name : FileName);
|
||||
}
|
||||
|
||||
|
||||
int VFSInstallFileSystem(FileSystemPointer fs)
|
||||
{
|
||||
// Sanity check
|
||||
if (!fs) return 0;
|
||||
|
||||
// Verify device does not exist
|
||||
int i;
|
||||
for (i=0; i < DeviceCount; i++)
|
||||
if (_FileSystems[i])
|
||||
if (strcmp (fs->Name, _FileSystems[i]->Name) == 0) return 0;
|
||||
|
||||
_FileSystems[DeviceCount] = fs; DeviceCount++;
|
||||
}
|
||||
|
||||
void VFSUninstallFileSystem(FileSystemPointer fs)
|
||||
{
|
||||
if (!fs) return;
|
||||
|
||||
int i;
|
||||
for (i=0; i<DeviceCount; i++)
|
||||
if (_FileSystems[i] == fs) {
|
||||
_FileSystems[i] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void VFSUninstallFileSystemByName(const char* fs)
|
||||
{
|
||||
if (!fs) return;
|
||||
|
||||
int i;
|
||||
for (i=0; i<DeviceCount; i++)
|
||||
if (_FileSystems[i])
|
||||
if (strcmp(_FileSystems[i]->Name, fs) == 0){
|
||||
_FileSystems[i] = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void VFSReadFile (FilePointer f, unsigned char* buffer, unsigned len)
|
||||
{
|
||||
if (!f || !_FileSystems[f->Device]) return;
|
||||
_FileSystems[f->Device]->Read (f, buffer, len);
|
||||
}
|
||||
|
||||
void VFSCloseFile (FilePointer f)
|
||||
{
|
||||
if (!f || !_FileSystems[f->Device]) return;
|
||||
_FileSystems[f->Device]->Close(f);
|
||||
}
|
||||
|
57
SysCore/drivers/filesys/vfs.h
Normal file
57
SysCore/drivers/filesys/vfs.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/***** vfs.h *********************************************************
|
||||
* (c) 2010 CTA Systems Inc. All rights reserved. Glory To God *
|
||||
* *
|
||||
* Virtual File System (VFS) Implementation *
|
||||
* ======================================== *
|
||||
* *
|
||||
************************************************************ cta os */
|
||||
#ifndef __VFS__H___
|
||||
#define __VFS__H___
|
||||
|
||||
#include <time.h>
|
||||
|
||||
typedef enum {
|
||||
FileTypeInvalid,
|
||||
FileTypeFile,
|
||||
FileTypeDirectory,
|
||||
FileTypeSymbolicLink
|
||||
} FileType;
|
||||
|
||||
enum FileFlags {
|
||||
FileFlagReadOnly = 0x1,
|
||||
FileFlagHidden = 0x2,
|
||||
FileFlagSystem = 0x4,
|
||||
FileFlagVolumeID = 0x8,
|
||||
FileFlagDirectory = 0x10,
|
||||
FileFlagArchive = 0x20
|
||||
};
|
||||
|
||||
|
||||
typedef struct {
|
||||
char Name[256];
|
||||
FileType Type;
|
||||
unsigned Flags;
|
||||
unsigned Length;
|
||||
unsigned EndOfFile;
|
||||
unsigned ID;
|
||||
unsigned Position, CurrentCluster;
|
||||
unsigned Device;
|
||||
TIME Created;
|
||||
DATE LastAccessed;
|
||||
TIME LastModified;
|
||||
} File, *FilePointer;
|
||||
|
||||
|
||||
typedef struct {
|
||||
char Name[256];
|
||||
|
||||
File (*Directory) (const char* DirectoryName);
|
||||
void (*Mount) ();
|
||||
void (*Read) (FilePointer, unsigned char*, unsigned);
|
||||
void (*Close) (FilePointer);
|
||||
FILE (*Open) (const char*);
|
||||
|
||||
} FileSystem, *FileSystemPointer;
|
||||
|
||||
|
||||
#endif
|
137
SysCore/drivers/floppy/dma.c
Normal file
137
SysCore/drivers/floppy/dma.c
Normal file
@@ -0,0 +1,137 @@
|
||||
/***** dma.c *********************************************************
|
||||
* (c) 2010 CTA Systems Inc. All rights reserved. Glory To God *
|
||||
* *
|
||||
* Direct Memory Access (DMA) Routines *
|
||||
* =================================== *
|
||||
* *
|
||||
************************************************************ cta os */
|
||||
|
||||
#include "dma.h"
|
||||
#include <system.h>
|
||||
|
||||
enum DMA0InputOutput {
|
||||
DMA0StatusRegister = 0x08,
|
||||
DMA0CommandRegister = 0x08,
|
||||
DMA0RequestRegister = 0x09,
|
||||
DMA0ChannelMaskRegister = 0x0a,
|
||||
DMA0ModeRegister = 0x0b,
|
||||
DMA0ClearByteFlipFlopRegister = 0x0c,
|
||||
DMA0TempRegister = 0x0d,
|
||||
DMA0MasterClearRegister = 0x0d,
|
||||
DMA0ClearMaskRegister = 0x0e,
|
||||
DMA0MaskRegister = 0x0f
|
||||
};
|
||||
|
||||
enum DMA1InputOutput {
|
||||
DMA1StatusRegister = 0xd0,
|
||||
DMA1CommandRegister = 0xd0,
|
||||
DMA1RequestRegister = 0xd2,
|
||||
DMA1ChannelMaskRegister = 0xd4,
|
||||
DMA1ModeRegister = 0xd6,
|
||||
DMA1ClearByteFlipFlopRegister = 0xd8,
|
||||
DMA1InterRegister = 0xda,
|
||||
DMA1UnmaskAllRegister = 0xdc,
|
||||
DMA1MaskRegister = 0xde
|
||||
};
|
||||
|
||||
void DMASetAddress(unsigned short channel, unsigned char low, unsigned char high)
|
||||
{
|
||||
if (channel > 7) return; // Ignore if channel > 7
|
||||
|
||||
// Calculate port
|
||||
unsigned short port = (channel >= 4) ? 4*(channel - 4) + 0xc0 : 2*channel;
|
||||
|
||||
// Set address
|
||||
outportb (port, low);
|
||||
outportb (port, high);
|
||||
}
|
||||
|
||||
|
||||
void DMASetCount (unsigned short channel, unsigned char low, unsigned char high)
|
||||
{
|
||||
if (channel > 7) return; // Ignore if channel > 7
|
||||
|
||||
// Calculate port
|
||||
unsigned short port = (channel >= 4) ? 4*(channel - 4) + 0xc2
|
||||
: (2*channel) + 1;
|
||||
|
||||
// Set count
|
||||
outportb (port, low);
|
||||
outportb (port, high);
|
||||
}
|
||||
|
||||
|
||||
void DMASetExternalPageRegisters (unsigned char channel, unsigned char val)
|
||||
{
|
||||
unsigned short port = 0;
|
||||
|
||||
switch (channel) {
|
||||
case 1: port = 0x83; break;
|
||||
case 2: port = 0x81; break;
|
||||
case 3: port = 0x82; break;
|
||||
// <- nothing should ever write to chan 4
|
||||
case 5: port = 0x89; break;
|
||||
case 6: port = 0x87; break;
|
||||
case 7: port = 0x88; break;
|
||||
default: if (channel == 4 || channel > 14) return;
|
||||
}
|
||||
|
||||
outportb(port, val);
|
||||
}
|
||||
|
||||
|
||||
void DMAMaskChannel (unsigned char channel)
|
||||
{
|
||||
if (channel <= 4) outportb (DMA0ChannelMaskRegister, (1<< (channel -1)));
|
||||
else outportb (DMA1ChannelMaskRegister, (1<< (channel -5)));
|
||||
}
|
||||
|
||||
|
||||
void DMAUnmaskChannel (unsigned char channel)
|
||||
{
|
||||
if (channel <= 4) outportb (DMA0ChannelMaskRegister, channel);
|
||||
else outportb (DMA1ChannelMaskRegister, channel);
|
||||
}
|
||||
|
||||
|
||||
void DMAUnmaskAll()
|
||||
{
|
||||
outportb (DMA1UnmaskAllRegister, 0xff);
|
||||
}
|
||||
|
||||
|
||||
void DMAResetFlipFlop (unsigned char dma)
|
||||
{
|
||||
switch (dma) {
|
||||
case 0: outportb (DMA0ClearByteFlipFlopRegister, 0xff);
|
||||
case 1: outportb (DMA1ClearByteFlipFlopRegister, 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
void DMAReset ()
|
||||
{
|
||||
outportb (DMA0TempRegister, 0xff);
|
||||
}
|
||||
|
||||
|
||||
void DMASetMode(unsigned char channel, unsigned char mode)
|
||||
{
|
||||
unsigned char dma = (channel < 4) ? 0:1;
|
||||
unsigned char chan = (dma == 0) ? channel : channel-4;
|
||||
|
||||
DMAMaskChannel (channel);
|
||||
outportb ((channel < 4) ? DMA0ModeRegister : DMA1ModeRegister, chan | mode);
|
||||
DMAUnmaskAll ();
|
||||
}
|
||||
|
||||
|
||||
void DMASetRead (unsigned char channel)
|
||||
{
|
||||
DMASetMode (channel, DMAModeReadTransfer | DMAModeTransferSingle);
|
||||
}
|
||||
|
||||
|
||||
void DMASetWrite (unsigned char channel)
|
||||
{
|
||||
DMASetMode (channel, DMAModeWriteTransfer | DMAModeTransferSingle);
|
||||
}
|
42
SysCore/drivers/floppy/dma.h
Normal file
42
SysCore/drivers/floppy/dma.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/***** dma.h *********************************************************
|
||||
* (c) 2010 CTA Systems Inc. All rights reserved. Glory To God *
|
||||
* *
|
||||
* Direct Memory Access (DMA) Routines *
|
||||
* =================================== *
|
||||
* *
|
||||
************************************************************ cta os */
|
||||
|
||||
#ifndef __DMA__H__
|
||||
#define __DMA__H__
|
||||
|
||||
enum DMA_MODE_REG_MASK {
|
||||
DMAModeMaskSelect = 3,
|
||||
|
||||
DMAModeMaskTra = 0xc,
|
||||
DMAModeSelfTest = 0,
|
||||
DMAModeReadTransfer = 4,
|
||||
DMAModeWriteTransfer = 8,
|
||||
|
||||
DMAModeMaskAuto = 0x10,
|
||||
DMAModeMaskIdec = 0x20,
|
||||
|
||||
DMAModeMask = 0xc0,
|
||||
DMAModeTransferOnDemand = 0,
|
||||
DMAModeTransferSingle = 0x40,
|
||||
DMAModeTransferBlock = 0x80,
|
||||
DMAModeTransferCascade = 0xC0
|
||||
};
|
||||
|
||||
extern void DMASetAddress(unsigned short channel, unsigned char low, unsigned char high);
|
||||
extern void DMASetCount (unsigned short channel, unsigned char low, unsigned char high);
|
||||
extern void DMASetExternalPageRegisters (unsigned char channel, unsigned char val);
|
||||
extern void DMAMaskChannel (unsigned char channel);
|
||||
extern void DMAUnmaskChannel (unsigned char channel);
|
||||
extern void DMAUnmaskAll();
|
||||
extern void DMAResetFlipFlop (unsigned char dma);
|
||||
extern void DMAReset ();
|
||||
extern void DMASetMode(unsigned char channel, unsigned char mode);
|
||||
extern void DMASetRead (unsigned char channel);
|
||||
extern void DMASetWrite (unsigned char channel);
|
||||
|
||||
#endif
|
494
SysCore/drivers/floppy/floppy.c
Normal file
494
SysCore/drivers/floppy/floppy.c
Normal file
@@ -0,0 +1,494 @@
|
||||
/***** floppy.c ******************************************************
|
||||
* (c) 2010 CTA Systems Inc. All rights reserved. Glory To God *
|
||||
* *
|
||||
* Floppy Drive I/O Routines *
|
||||
* ========================= *
|
||||
* *
|
||||
************************************************************ cta os */
|
||||
#include <system.h>
|
||||
#include <conio.h>
|
||||
#include <time.h>
|
||||
#include "dma.h"
|
||||
#include "storage.h"
|
||||
|
||||
unsigned char CmosReadFloppyData ()
|
||||
{
|
||||
outportb (0x70, 0x10);
|
||||
return inportb(0x71);
|
||||
}
|
||||
|
||||
unsigned char FloppyDrivesInstalled;
|
||||
volatile unsigned char FloppyNewInterrupt;
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned char Type;
|
||||
unsigned Size;
|
||||
unsigned char SectorsPerTrack;
|
||||
unsigned char Heads;
|
||||
unsigned char Tracks;
|
||||
unsigned char DataRate;
|
||||
unsigned char StepRateTime;
|
||||
unsigned char HeadLoadTime;
|
||||
unsigned char HeadUnloadTime;
|
||||
unsigned char Gap3;
|
||||
unsigned char Gap3Format;
|
||||
} FloppyType;
|
||||
|
||||
FloppyType fd[2];
|
||||
|
||||
void FloppyReset();
|
||||
enum FloppyRegisters {
|
||||
FloppyRegDOR = 0x3f2,
|
||||
FloppyRegMSR = 0x3f4,
|
||||
FloppyRegFIFO = 0x3f5,
|
||||
FloppyRegCTRL = 0x3f7
|
||||
};
|
||||
|
||||
enum FloppyCommands {
|
||||
FloppyCommandReadTrack = 2,
|
||||
FloppyCommandSpecify = 3,
|
||||
FloppyCommandCheckStatus = 4,
|
||||
FloppyCommandWriteSector = 5,
|
||||
FloppyCommandReadSector = 6,
|
||||
FloppyCommandCalibrate = 7,
|
||||
FloppyCommandCheckInt = 8,
|
||||
FloppyCommandFormatTrack = 0xd,
|
||||
FloppyCommandSeek = 0xf,
|
||||
|
||||
FloppyCommandExtSkip = 0x20,
|
||||
FloppyCommandExtDensity = 0x40,
|
||||
FloppyCommandExtMultiTrack = 0x80
|
||||
};
|
||||
|
||||
// Initialize DMA
|
||||
unsigned char FloppyInitializeDMA(unsigned char* buffer, unsigned length)
|
||||
{
|
||||
union { unsigned char byt[4]; // Low[0], Mid[1], Hi[2]
|
||||
unsigned long l;
|
||||
} a, c;
|
||||
|
||||
a.l = (unsigned) buffer;
|
||||
c.l = (unsigned) length-1;
|
||||
|
||||
// Check for buffer issues
|
||||
if ((a.l >> 24) || (c.l >> 16) || (((a.l & 0xffff)+c.l) >> 16)) return 0;
|
||||
|
||||
DMAReset();
|
||||
DMAMaskChannel(2); // Mask channel 2
|
||||
DMAResetFlipFlop(1); // FlipFlop reset on DMA1
|
||||
|
||||
DMASetAddress(2, a.byt[0], a.byt[1]); // Buffer address
|
||||
DMAResetFlipFlop(1); // FlipFlop reset on DMA2
|
||||
|
||||
DMASetCount(2, c.byt[0], c.byt[1]); // Set count
|
||||
DMASetRead(2);
|
||||
DMAUnmaskAll();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
inline void FloppyDisableController() {
|
||||
outportb (FloppyRegDOR, 0);
|
||||
}
|
||||
|
||||
inline void FloppyEnableController() {
|
||||
outportb (FloppyRegDOR, 4 | 8);
|
||||
}
|
||||
|
||||
|
||||
inline unsigned char FloppySendCommand (unsigned char command)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 750; i++)
|
||||
if (inportb(FloppyRegMSR) & 128) {
|
||||
outportb(FloppyRegFIFO, command); return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
inline unsigned char FloppyReadData ()
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 750; i++)
|
||||
if (inportb(FloppyRegMSR) & 0x80)
|
||||
return inportb(FloppyRegFIFO);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
inline void FloppyCheckInt(unsigned* st0, unsigned* cyl)
|
||||
{
|
||||
int t;
|
||||
for (t=3; t>=0; t--) {
|
||||
if (!FloppySendCommand(0x8)) FloppyReset();
|
||||
else break;
|
||||
}
|
||||
for (t=50; !(inportb(FloppyRegMSR) & 0x80) && t>0; --t);
|
||||
|
||||
*st0 = FloppyReadData();
|
||||
*cyl = FloppyReadData();
|
||||
}
|
||||
|
||||
|
||||
inline unsigned char FloppyWaitIRQ()
|
||||
{
|
||||
unsigned tick = ClockGetTickCount();
|
||||
unsigned freq = PitGetFrequency();
|
||||
tick = tick + (freq * 3); // Wait 3 seconds
|
||||
|
||||
while (FloppyNewInterrupt==0)
|
||||
if (tick <= ClockGetTickCount()) return 0; // timeout
|
||||
|
||||
FloppyNewInterrupt = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void FloppyMotor (unsigned char drive, unsigned char on)
|
||||
{
|
||||
if (drive >= FloppyDrivesInstalled) return;
|
||||
|
||||
// Read DOR register
|
||||
unsigned char dor = inportb(FloppyRegDOR);
|
||||
|
||||
// Un/set selected drive motor
|
||||
if (on) dor |= 1 << (4+drive);
|
||||
else dor &= ~(1 << (4+drive));
|
||||
|
||||
// Write DOR
|
||||
outportb (FloppyRegDOR, dor);
|
||||
|
||||
// Wait a fifth of a second for motor to turn on
|
||||
unsigned temp = ClockGetTickCount();
|
||||
unsigned freq = PitGetFrequency();
|
||||
while (temp + (freq/5) > ClockGetTickCount());
|
||||
}
|
||||
|
||||
|
||||
void i86_FloppyHandler(ISR_stack_regs *r)
|
||||
{
|
||||
FloppyNewInterrupt = 1;
|
||||
}
|
||||
|
||||
|
||||
void FloppyDriveData (unsigned char drv, unsigned char dma)
|
||||
{
|
||||
unsigned data = 0;
|
||||
if (drv >= FloppyDrivesInstalled) return;
|
||||
|
||||
outportb(FloppyRegCTRL, fd[drv].DataRate);
|
||||
|
||||
FloppySendCommand (0x3);
|
||||
|
||||
data = ((fd[drv].StepRateTime & 0xf) << 4) | (fd[drv].HeadUnloadTime & 0xf);
|
||||
FloppySendCommand (data);
|
||||
|
||||
data = (fd[drv].HeadLoadTime <<1 ) | (dma) ? 1 : 0;
|
||||
FloppySendCommand (data);
|
||||
}
|
||||
|
||||
|
||||
inline void FloppySelect(unsigned char drive)
|
||||
{
|
||||
if (drive >= FloppyDrivesInstalled) return;
|
||||
|
||||
unsigned char dor = inportb(FloppyRegDOR) & 0xf0;
|
||||
|
||||
// Send mechanical drive data
|
||||
FloppyDriveData(drive, 1);
|
||||
|
||||
// Select drive in DOR register
|
||||
outportb (FloppyRegDOR, dor | 4 | 8 | drive);
|
||||
|
||||
}
|
||||
|
||||
|
||||
unsigned char FloppyCalibrate(unsigned drive)
|
||||
{
|
||||
unsigned st0, cyl;
|
||||
|
||||
if (drive >= FloppyDrivesInstalled) return 0;
|
||||
|
||||
FloppyMotor (drive, 1);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 15; i++) {
|
||||
FloppyNewInterrupt = 0;
|
||||
FloppySendCommand(FloppyCommandCalibrate);
|
||||
FloppySendCommand(drive);
|
||||
FloppyWaitIRQ();
|
||||
FloppyCheckInt(&st0, &cyl);
|
||||
|
||||
if (!cyl) {
|
||||
FloppyMotor(drive, 0);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
FloppyMotor(drive, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void FloppyReset()
|
||||
{
|
||||
unsigned st0, cyl;
|
||||
|
||||
FloppyNewInterrupt = 0;
|
||||
FloppyDisableController();
|
||||
FloppyEnableController();
|
||||
FloppyWaitIRQ();
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 4; i++)
|
||||
FloppyCheckInt(&st0, &cyl);
|
||||
|
||||
unsigned char drive;
|
||||
for (drive = 0; drive < FloppyDrivesInstalled; drive++) {
|
||||
FloppyDriveData(drive, 1);
|
||||
FloppyCalibrate(drive);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned FloppyReadSectorImp (unsigned* where, unsigned char drive, unsigned char head, unsigned char track, unsigned char sector)
|
||||
{
|
||||
int t, fail;
|
||||
for (t=3; t>=0; t--) {
|
||||
fail = 0;
|
||||
FloppySelect (drive);
|
||||
FloppyInitializeDMA((unsigned char*) where, 512);
|
||||
DMASetRead(2);
|
||||
|
||||
FloppyNewInterrupt = 0;
|
||||
|
||||
fail += 1-FloppySendCommand(0x06 | 0x80 | 0x40 );
|
||||
fail += 1-FloppySendCommand(head<<2 | drive);
|
||||
fail += 1-FloppySendCommand(track);
|
||||
fail += 1-FloppySendCommand(head);
|
||||
fail += 1-FloppySendCommand(sector);
|
||||
fail += 1-FloppySendCommand(2);
|
||||
fail += 1-FloppySendCommand( ((sector+1) >= fd[drive].SectorsPerTrack) ? fd[drive].SectorsPerTrack : sector+1);
|
||||
fail += 1-FloppySendCommand(fd[drive].Gap3);
|
||||
fail += 1-FloppySendCommand(0xff);
|
||||
|
||||
if (fail) {
|
||||
FloppyReset(); continue;
|
||||
}
|
||||
|
||||
FloppyWaitIRQ();
|
||||
while (!(inportb(FloppyRegMSR) & 0x80));
|
||||
|
||||
int i; unsigned ccc=0;
|
||||
|
||||
for (i = 0; i < 7; i++) {
|
||||
if (i<3) ccc |= FloppyReadData() << (i*4);
|
||||
else FloppyReadData();
|
||||
}
|
||||
|
||||
return ccc;
|
||||
}
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
|
||||
unsigned FloppyWriteSectorImp (unsigned* where, unsigned char drive, unsigned char head, unsigned char track, unsigned char sector)
|
||||
{
|
||||
int t, fail;
|
||||
for (t=3; t>=0; t--) {
|
||||
fail = 0;
|
||||
FloppySelect (drive);
|
||||
FloppyInitializeDMA((unsigned char*) where, 512);
|
||||
DMASetWrite(2);
|
||||
|
||||
FloppyNewInterrupt = 0;
|
||||
|
||||
fail += 1-FloppySendCommand(0x05 | 0x80 | 0x40 );
|
||||
fail += 1-FloppySendCommand(head<<2 | drive);
|
||||
fail += 1-FloppySendCommand(track);
|
||||
fail += 1-FloppySendCommand(head);
|
||||
fail += 1-FloppySendCommand(sector);
|
||||
fail += 1-FloppySendCommand(2);
|
||||
fail += 1-FloppySendCommand( ((sector+1) >= fd[drive].SectorsPerTrack) ? fd[drive].SectorsPerTrack : sector+1);
|
||||
fail += 1-FloppySendCommand(fd[drive].Gap3);
|
||||
fail += 1-FloppySendCommand(0xff);
|
||||
|
||||
if (fail) {
|
||||
FloppyReset(); continue;
|
||||
}
|
||||
|
||||
FloppyWaitIRQ();
|
||||
|
||||
int i; unsigned ccc=0;
|
||||
for (i = 0; i < 7; i++)
|
||||
if (i<3) ccc |= FloppyReadData() << (i*4);
|
||||
else FloppyReadData();
|
||||
|
||||
return ccc;
|
||||
}
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
unsigned char FloppySeek (unsigned drive, unsigned cyl, unsigned head)
|
||||
{
|
||||
unsigned st0, cyl0;
|
||||
|
||||
if (drive >= FloppyDrivesInstalled) return 0;
|
||||
|
||||
FloppySelect (drive);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 20; i++) {
|
||||
FloppyNewInterrupt = 0;
|
||||
FloppySendCommand (0xF);
|
||||
FloppySendCommand ( (head) << 2 | drive);
|
||||
FloppySendCommand (cyl);
|
||||
|
||||
FloppyWaitIRQ();
|
||||
FloppyCheckInt(&st0, &cyl0);
|
||||
|
||||
if (cyl0 == cyl) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
inline void FloppyLBAtoCHS (int lba, unsigned char drive, unsigned char *head, unsigned char *track, unsigned char *sectors)
|
||||
{
|
||||
*head = (lba % (fd[drive].SectorsPerTrack * 2)) / fd[drive].SectorsPerTrack;
|
||||
*track = lba / (fd[drive].SectorsPerTrack * 2);
|
||||
*sectors = lba % fd[drive].SectorsPerTrack + 1;
|
||||
}
|
||||
|
||||
|
||||
/*const char* types[] = {
|
||||
"Nonexistant", "5.25\", unsupported.", "5.25\", unsupported.",
|
||||
"3.5\", 720kb", "3.5\", 1.44mb", "3.5\", 2.88 mb"};*/
|
||||
|
||||
void FloppyInstall()
|
||||
{
|
||||
unsigned char temp = CmosReadFloppyData();
|
||||
int i;
|
||||
|
||||
// Set fd0 and fd1 types
|
||||
fd[1].Type = temp & 0xf;
|
||||
fd[0].Type = temp >> 4;
|
||||
|
||||
// SRT = 16 - (ms * datarate / 500000);
|
||||
// HLT = ms * datarate / 1000000
|
||||
// HUT = ms * datarate / 8000000
|
||||
|
||||
// Set up
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (fd[i].Type >= 3) FloppyDrivesInstalled++; // 5.25" drives unsupported
|
||||
if (fd[i].Type == 3) { // 720 kb, DD
|
||||
fd[i].DataRate = 2; // speed = 250 kbps
|
||||
fd[i].StepRateTime = 12; // 16 - (ms * 250000 / 500000), ms = 8
|
||||
fd[i].HeadLoadTime = 7;
|
||||
fd[i].HeadUnloadTime = 7;
|
||||
fd[i].SectorsPerTrack = 9;
|
||||
fd[i].Size = 1440;
|
||||
fd[i].Gap3 = 0x2A;
|
||||
fd[i].Gap3Format = 0x50;
|
||||
fd[i].Heads = 2;
|
||||
fd[i].Tracks = 80;
|
||||
}
|
||||
else if (fd[i].Type == 4) { // 1.44 MB, HD
|
||||
fd[i].DataRate = 0; // speed = 500 kbps
|
||||
fd[i].StepRateTime = 8;
|
||||
fd[i].HeadLoadTime = 15;
|
||||
fd[i].HeadUnloadTime = 15;
|
||||
fd[i].SectorsPerTrack = 18;
|
||||
fd[i].Size = 2880;
|
||||
fd[i].Gap3 = 0x1B;
|
||||
fd[i].Gap3Format = 0x6C;
|
||||
fd[i].Heads = 2;
|
||||
fd[i].Tracks = 80;
|
||||
}
|
||||
else if (fd[i].Type == 5) { // 2.88 MB, ED
|
||||
fd[i].DataRate = 3; // speed = 1000 kbps;
|
||||
fd[i].StepRateTime = 0;
|
||||
fd[i].HeadLoadTime = 30;
|
||||
fd[i].HeadUnloadTime = 30;
|
||||
fd[i].SectorsPerTrack = 36;
|
||||
fd[i].Size = 5760;
|
||||
fd[i].Gap3 = 0x1B;
|
||||
fd[i].Gap3Format = 0x54;
|
||||
fd[i].Heads = 2;
|
||||
fd[i].Tracks = 80;
|
||||
}
|
||||
}
|
||||
if (FloppyDrivesInstalled == 0) return; // No drives to set
|
||||
|
||||
|
||||
FloppyReset();
|
||||
}
|
||||
|
||||
|
||||
unsigned char FloppyIsDriverEnabled()
|
||||
{
|
||||
return FloppyDrivesInstalled;
|
||||
}
|
||||
|
||||
unsigned* FloppyReadSectors (unsigned* where, unsigned char drive, int sectorLBA, unsigned count)
|
||||
{
|
||||
if (drive >= FloppyDrivesInstalled || !where) return 0;
|
||||
|
||||
unsigned head=0, track=0, sector=1, i, addr = (unsigned)where;
|
||||
|
||||
// start motor, seek to track
|
||||
FloppyMotor(drive, 1);
|
||||
|
||||
// read count sectors
|
||||
for (i=0; i<count; i++) {
|
||||
|
||||
// Convert lba to chs
|
||||
head=0, track=0, sector=1;
|
||||
FloppyLBAtoCHS(sectorLBA+i, drive, (unsigned char*)&head, (unsigned char*)&track, (unsigned char*) §or);
|
||||
|
||||
// Seek
|
||||
if (!FloppySeek(drive, track, head)) return 0;
|
||||
|
||||
// Read the sector
|
||||
FloppyReadSectorImp((unsigned*)0x7e00, drive, head, track, sector);
|
||||
|
||||
memcpy((void*)(addr+(0x200*i)), (void*)0x7e00, 0x200);
|
||||
}
|
||||
|
||||
FloppyMotor(drive, 0);
|
||||
|
||||
return (unsigned*)where;
|
||||
}
|
||||
|
||||
unsigned* FloppyWriteSectors (unsigned* where, unsigned char drive, int sectorLBA, unsigned count)
|
||||
{
|
||||
if (drive >= FloppyDrivesInstalled || !where) return 0;
|
||||
|
||||
unsigned head=0, track=0, sector=1, i, addr = (unsigned)where;
|
||||
|
||||
// start motor, seek to track
|
||||
FloppyMotor(drive, 1);
|
||||
|
||||
// read count sectors
|
||||
for (i=0; i<count; i++) {
|
||||
memcpy((void*)0x7e00, (void*)(addr+(0x200*i)), 0x200);
|
||||
where = where+0x200;
|
||||
// Convert lba to chs
|
||||
head=0, track=0, sector=1;
|
||||
FloppyLBAtoCHS(sectorLBA+i, drive, (unsigned char*)&head, (unsigned char*)&track, (unsigned char*) §or);
|
||||
|
||||
// Seek
|
||||
if (!FloppySeek(drive, track, head)) return 0;
|
||||
|
||||
// Read the sector
|
||||
FloppyWriteSectorImp((unsigned*)0x7e00, drive, head, track, sector);
|
||||
}
|
||||
|
||||
FloppyMotor(drive, 0);
|
||||
|
||||
return (unsigned*)where;
|
||||
}
|
26
SysCore/drivers/floppy/floppy.h
Normal file
26
SysCore/drivers/floppy/floppy.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/***** floppy.h ******************************************************
|
||||
* (c) 2010 CTA Systems Inc. All rights reserved. Glory To God *
|
||||
* *
|
||||
* Floppy Drive I/O Routines *
|
||||
* ========================= *
|
||||
* *
|
||||
************************************************************ cta os */
|
||||
#include<regs.h>
|
||||
|
||||
extern unsigned char FloppyInitializeDMA(unsigned char* buffer, unsigned length);
|
||||
extern void FloppyMotor (unsigned char drive, unsigned char on);
|
||||
extern void i86_FloppyHandler(ISR_stack_regs *r);
|
||||
extern void FloppyDriveData (unsigned char drv, unsigned char dma);
|
||||
extern unsigned char FloppyCalibrate(unsigned drive);
|
||||
extern void FloppyReset();
|
||||
|
||||
extern unsigned char FloppySeek (unsigned drive, unsigned cyl, unsigned head);
|
||||
extern void FloppyInstall();
|
||||
extern unsigned char FloppyIsDriverEnabled();
|
||||
|
||||
// Read/Write routines
|
||||
extern unsigned* FloppyReadSectors (unsigned* where, unsigned char drive, int sectorLBA, unsigned count);
|
||||
extern unsigned* FloppyWriteSectors (unsigned* where, unsigned char drive, int sectorLBA, unsigned count);
|
||||
|
||||
extern void FloppyReadSectorImp (unsigned* where, unsigned char drive, unsigned char head, unsigned char track, unsigned char sector);
|
||||
extern void FloppyWritedSectorImp (unsigned* where, unsigned char drive, unsigned char head, unsigned char track, unsigned char sector);
|
14
SysCore/drivers/floppy/storage.h
Normal file
14
SysCore/drivers/floppy/storage.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef __STORAGE__H__
|
||||
#define __STORAGE__H__
|
||||
|
||||
/**Structure used by the file system drivers.\n
|
||||
\Warning: the driver that provides the Read/Write routines must
|
||||
include conversions for partitions on hard drives.*/
|
||||
typedef struct {
|
||||
unsigned NumberOfSectors;
|
||||
unsigned SizeOfSector;
|
||||
void (*ReadSectors) (void* buffer, int startlba, int endlba);
|
||||
void (*WriteSectors) (void* buffer, int startlba, int endlba);
|
||||
} StorageDeviceInterface, *StorageDeviceInterfacePointer;
|
||||
|
||||
#endif
|
16
SysCore/drivers/keyboard/compile.bat
Normal file
16
SysCore/drivers/keyboard/compile.bat
Normal file
@@ -0,0 +1,16 @@
|
||||
@echo off
|
||||
|
||||
rem NASM and DJGPP executable paths:
|
||||
set nasm_path=C:\nasm
|
||||
set djgpp_path=C:\mingw\bin
|
||||
set objpath=../../objects
|
||||
set incpath=../../include
|
||||
|
||||
@echo on
|
||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/drivers/keyboard.o keyboard.c
|
||||
|
||||
@echo off
|
||||
@echo .
|
||||
@echo Done!
|
||||
|
||||
@pause
|
135
SysCore/drivers/keyboard/key_list.txt
Normal file
135
SysCore/drivers/keyboard/key_list.txt
Normal file
@@ -0,0 +1,135 @@
|
||||
*0x00 Pause/Break
|
||||
0x01 F9
|
||||
0x02 F7
|
||||
0x03 F5
|
||||
0x04 F3
|
||||
0x05 F1
|
||||
0x06 F2
|
||||
0x07 F12
|
||||
0x08 Print Screen
|
||||
0x09 F10
|
||||
0x0A F8
|
||||
0x0B F6
|
||||
0x0C F4
|
||||
0x0D Tab
|
||||
0x0E `~
|
||||
0x0F
|
||||
|
||||
0x10
|
||||
0x11
|
||||
0x12
|
||||
0x13
|
||||
0x14
|
||||
0x15 Q
|
||||
0x16 1!
|
||||
0x17
|
||||
0x18
|
||||
0x19
|
||||
0x1A Z
|
||||
0x1B S
|
||||
0x1C A
|
||||
0x1D W
|
||||
0x1E 2@
|
||||
0x1F LeftWin
|
||||
|
||||
0x20
|
||||
0x21 C
|
||||
0x22 X
|
||||
0x23 D
|
||||
0x24 E
|
||||
0x25 4$
|
||||
0x26 3#
|
||||
0x27 RightWin
|
||||
0x28
|
||||
0x29 Space
|
||||
0x2A V
|
||||
0x2B F
|
||||
0x2C T
|
||||
0x2D R
|
||||
0x2E 5%
|
||||
0x2F Menu
|
||||
|
||||
0x30
|
||||
0x31 N
|
||||
0x32 B
|
||||
0x33 H
|
||||
0x34 G
|
||||
0x35 Y
|
||||
0x36 6^
|
||||
0x37
|
||||
0x38
|
||||
0x39
|
||||
0x3A M
|
||||
0x3B J
|
||||
0x3C U
|
||||
0x3D 7&
|
||||
0x3E 8*
|
||||
0x3F
|
||||
|
||||
0x40
|
||||
0x41 ,<
|
||||
0x42 K
|
||||
0x43 I
|
||||
0x44 O
|
||||
0x45 0)
|
||||
0x46 9(
|
||||
0x47
|
||||
0x48
|
||||
0x49 .>
|
||||
0x4A /?
|
||||
0x4B L
|
||||
0x4C ;:
|
||||
0x4D P
|
||||
0x4E -_
|
||||
0x4F
|
||||
|
||||
0x50
|
||||
0x51
|
||||
0x52 '"
|
||||
0x53
|
||||
0x54 [{
|
||||
0x55 =+
|
||||
0x56
|
||||
0x57
|
||||
0x58
|
||||
0x59 Numpad Enter
|
||||
0x5A Enter
|
||||
0x5B ]}
|
||||
0x5C
|
||||
0x5D \|
|
||||
0x5E End
|
||||
0x5F Left
|
||||
|
||||
0x60 Home
|
||||
0x61 Insert
|
||||
0x62 Delete
|
||||
0x63 Down
|
||||
0x64 Right
|
||||
0x65 Up
|
||||
0x66 Backspace
|
||||
0x67 PageDown
|
||||
0x68 PageUp
|
||||
0x69 Numpad 1 (end)
|
||||
0x6A Numpad /
|
||||
0x6B Numpad 4 (left)
|
||||
0x6C Numpad 7 (Home)
|
||||
0x6D
|
||||
0x6E
|
||||
0x6F
|
||||
|
||||
0x70 Numpad 0 (insert)
|
||||
0x71 Numpad . (del)
|
||||
0x72 Numpad 2 (down)
|
||||
0x73 Numpad 5
|
||||
0x74 Numpad 6 (right)
|
||||
0x75 Numpad 8 (up)
|
||||
0x76 Esc
|
||||
0x77
|
||||
0x78 F11
|
||||
0x79 Numpad +
|
||||
0x7A Numpad 3 (pgdwn)
|
||||
0x7B Numpad -
|
||||
0x7C Numpad *
|
||||
0x7D Numpad 9 (pgup)
|
||||
0x7E
|
||||
0x7F
|
306
SysCore/drivers/keyboard/keyboard.c
Normal file
306
SysCore/drivers/keyboard/keyboard.c
Normal file
@@ -0,0 +1,306 @@
|
||||
#include <system.h>
|
||||
#include <drivers/keyboard.h>
|
||||
|
||||
const char KeyMap[] = {
|
||||
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, '\n', '\n', ']', 0, '\\', 0, 0,
|
||||
0, 0, 0x7F, 0, 0, 0, '\b', 0, 0, '1', '/', '4', '7', 0, 0, 0,
|
||||
'0', '.', '2', '5', '6', '8', 0, 0, 0, '+', '3', '-', '*', '9', 0, 0
|
||||
};
|
||||
|
||||
const char KeyMapShift[] = {
|
||||
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, '\n', '\n', '}', 0, '|', 0, 0,
|
||||
0, 0, 0x7F, 0, 0, 0, '\b', 0, 0, '1', '/', '4', '7', 0, 0, 0,
|
||||
'0', '.', '2', '5', '6', '8', 0, 0, 0, '+', '3', '-', '*', '9', 0, 0
|
||||
};
|
||||
|
||||
volatile unsigned char KeyArray[16];
|
||||
volatile unsigned char KeyboardNewData;
|
||||
volatile unsigned char KeyModifierStatus;
|
||||
volatile unsigned char KeyScancodePrefix;
|
||||
volatile unsigned char KeyLightsStatus;
|
||||
unsigned char KeyboardScancodeSet;
|
||||
|
||||
|
||||
void KeyboardSetKey(unsigned char scancode, unsigned char val)
|
||||
{
|
||||
unsigned char pos = scancode/8;
|
||||
unsigned char offset = scancode%8;
|
||||
|
||||
if (val) {
|
||||
KeyArray[pos] |= 1<<offset;
|
||||
KeyboardNewData = scancode;
|
||||
}
|
||||
else KeyArray[pos] &= 0xFF - (1<<offset);
|
||||
}
|
||||
|
||||
unsigned char KeyIsPressed(unsigned char scancode)
|
||||
{
|
||||
unsigned char pos = scancode/8;
|
||||
unsigned char offset = scancode%8;
|
||||
return (KeyArray[pos]&(1<<offset));
|
||||
}
|
||||
|
||||
|
||||
void i86_KeyboardHandler(ISR_stack_regs *r) {
|
||||
unsigned char scancode = inportb(0x60);
|
||||
|
||||
switch (scancode) {
|
||||
case 0x00: // Error 0x00
|
||||
case 0xFC: // Diagnostics failed (MF kb)
|
||||
case 0xFD: // Diagnostics failed (AT kb)
|
||||
case 0xFF: KeyboardWaitInput(); outportb(0x60, 0xF4); // Error 0xFF
|
||||
break;
|
||||
case 0xAA: // BAT test successful.
|
||||
case 0xFA: // ACKnowledge
|
||||
case 0xFE: // Last command invalid or parity error
|
||||
case 0xEE: break; // Echo response
|
||||
// Gray or break
|
||||
case 0xE0: KeyScancodePrefix |= 1; break;
|
||||
case 0xE1: KeyScancodePrefix |= 4; break;
|
||||
case 0xF0: KeyScancodePrefix |= 2; break;
|
||||
|
||||
// Alt, ctrl...
|
||||
case 0x11: if ((KeyScancodePrefix&1) == 0) { // Left alt
|
||||
if ((KeyScancodePrefix&2) == 0) KeyModifierStatus |= 1<<2;
|
||||
else KeyModifierStatus &= 0xFF - (1<<2);
|
||||
}
|
||||
else { // Right alt
|
||||
if ((KeyScancodePrefix&2) == 0) KeyModifierStatus |= 1<<3;
|
||||
else KeyModifierStatus &= 0xFF - (1<<3);
|
||||
}
|
||||
KeyScancodePrefix = 0; break;
|
||||
|
||||
case 0x12: if ((KeyScancodePrefix&1) == 0) { // Left shift
|
||||
if ((KeyScancodePrefix&2) == 0) KeyModifierStatus |= 1<<0;
|
||||
else KeyModifierStatus &= 0xFF - (1<<0);
|
||||
}
|
||||
else { // Fake shift
|
||||
if ((KeyScancodePrefix&2) == 0) KeyModifierStatus |= 1<<6;
|
||||
else KeyModifierStatus &= 0xFF - (1<<6);
|
||||
}
|
||||
KeyScancodePrefix = 0; break;
|
||||
|
||||
case 0x14: if (KeyScancodePrefix&4) { // Pause/break
|
||||
if ((KeyScancodePrefix&2) == 0) KeyboardSetKey (0, 1);
|
||||
else KeyboardSetKey (0, 0);
|
||||
KeyScancodePrefix |= 8; break;
|
||||
}
|
||||
|
||||
else if ((KeyScancodePrefix&1) == 0) { // Left ctrl
|
||||
if ((KeyScancodePrefix&2) == 0) KeyModifierStatus |= 1<<4;
|
||||
else KeyModifierStatus &= 0xFF - (1<<4);
|
||||
}
|
||||
else { // Right ctrl
|
||||
if ((KeyScancodePrefix&2) == 0) KeyModifierStatus |= 1<<5;
|
||||
else KeyModifierStatus &= 0xFF - (1<<5);
|
||||
}
|
||||
KeyScancodePrefix = 0; break;
|
||||
|
||||
case 0x59: // Right shift
|
||||
if ((KeyScancodePrefix&2) == 0) KeyModifierStatus |= 1<<1;
|
||||
else KeyModifierStatus &= 0xFF - (1<<1);
|
||||
|
||||
KeyScancodePrefix = 0; break;
|
||||
|
||||
// LEDs
|
||||
case 0x58: if ((KeyScancodePrefix&2) == 0) {
|
||||
KeyLightsStatus ^= 4; KeyboardSetLEDs(KeyLightsStatus);
|
||||
} KeyScancodePrefix = 0; break; // Caps
|
||||
|
||||
case 0x77:
|
||||
if ((KeyScancodePrefix&4) && (KeyScancodePrefix&8)) KeyScancodePrefix=0;
|
||||
else if ((KeyScancodePrefix&2) == 0) {
|
||||
KeyLightsStatus ^= 2; KeyboardSetLEDs(KeyLightsStatus);
|
||||
} KeyScancodePrefix = 0; break; // Num
|
||||
case 0x7E: if ((KeyScancodePrefix&2) == 0) {
|
||||
KeyLightsStatus ^= 1; KeyboardSetLEDs(KeyLightsStatus);
|
||||
} KeyScancodePrefix = 0; break; // Scroll
|
||||
|
||||
case 0x83: scancode = 0x02; // Put F7 under the 0x80 (128bit) barrier
|
||||
|
||||
default:
|
||||
// Remap gray keys
|
||||
if (KeyScancodePrefix&1) switch (scancode) {
|
||||
case 0x7C: scancode=0x08; break; // PrintScreen
|
||||
case 0x4A: scancode=0x6A; break; // Numpad /
|
||||
case 0x5A: scancode=0x59; break; // Numpad Enter
|
||||
case 0x69: scancode=0x5E; break; // End
|
||||
case 0x6B: scancode=0x5F; break; // Left
|
||||
case 0x6C: scancode=0x60; break; // Home
|
||||
case 0x70: scancode=0x61; break; // Insert
|
||||
case 0x71: scancode=0x62; break; // Delete
|
||||
case 0x72: scancode=0x63; break; // Down
|
||||
case 0x74: scancode=0x64; break; // Right
|
||||
case 0x75: scancode=0x65; break; // Up
|
||||
case 0x7A: scancode=0x67; break; // PageDown
|
||||
case 0x7D: scancode=0x68; break; // PageUp
|
||||
}
|
||||
if ((KeyScancodePrefix&2) == 0) KeyboardSetKey(scancode, 1);
|
||||
else KeyboardSetKey(scancode, 0);
|
||||
|
||||
KeyScancodePrefix = 0; break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
KeyboardKey GetKey()
|
||||
{
|
||||
KeyboardKey ret;
|
||||
|
||||
KeyboardNewData = 0xFF;
|
||||
while (KeyboardNewData==0xFF); // wait for keypress
|
||||
|
||||
ret.Scancode = KeyboardNewData; // Send scancode for non-chars
|
||||
ret.ModifierStatus = KeyModifierStatus; // Shift, ctrl... state
|
||||
ret.Lights = KeyLightsStatus; // Num, caps.... state
|
||||
|
||||
if ((ret.ModifierStatus & 1) || (ret.ModifierStatus & 2)) // Shift is on
|
||||
ret.Character = KeyMapShift[ret.Scancode];
|
||||
else ret.Character = KeyMap[ret.Scancode]; // Shift is off
|
||||
|
||||
return ret; // And send it.
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/***************************************
|
||||
* 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(unsigned char rate, unsigned char delay)
|
||||
{
|
||||
if (rate>3 || delay>31) return;
|
||||
|
||||
unsigned char out = rate<<5 | delay;
|
||||
while ((inportb(0x64)&2) != 0);
|
||||
outportb(0x60, 0xF3);
|
||||
while ((inportb(0x64)&2) != 0);
|
||||
outportb(0x60, out);
|
||||
}
|
||||
|
||||
|
||||
/***************************************
|
||||
* Set keyboard LEDs *
|
||||
***************************************
|
||||
+-----------+-------+-------+--------+
|
||||
| Bits 7-3 | Bit 2 | Bit 1 | Bit 0 |
|
||||
| 0 | Caps | Num | Scroll |
|
||||
|(reserved) | lock | lock | lock |
|
||||
+-----------+-------+-------+--------+
|
||||
***************************************/
|
||||
void KeyboardSetLEDs(unsigned char status)
|
||||
{
|
||||
while ((inportb (0x64)&2)!=0);
|
||||
outportb (0x60, 0xED);
|
||||
|
||||
while ((inportb (0x64)&2)!=0);
|
||||
outportb (0x60, status);
|
||||
}
|
||||
|
||||
/***************************************
|
||||
* Set scancode set *
|
||||
***************************************
|
||||
0 Get current scancode set
|
||||
1 Set to scancode set 1
|
||||
2 Set to scancode set 2
|
||||
3 Set to scancode set 3
|
||||
***************************************/
|
||||
void KeyboardSetScancodeSet(unsigned char set)
|
||||
{
|
||||
if (set>3) return;
|
||||
|
||||
while ((inportb (0x64)&2)!=0);
|
||||
outportb (0x60, 0xF0);
|
||||
|
||||
while ((inportb (0x64)&2)!=0);
|
||||
outportb (0x60, set);
|
||||
|
||||
KeyboardScancodeSet = set;
|
||||
}
|
||||
|
||||
/*unsigned char i86_kb_get_scancodeset() {
|
||||
return KeyboardScancodeSet;
|
||||
}*/
|
||||
|
||||
void KeyboardWaitInput()
|
||||
{
|
||||
int fail_safe=200000;
|
||||
while ((inportb(0x64)&2)!=0 && fail_safe>0) fail_safe--;
|
||||
}
|
||||
|
||||
void KeyboardWaitOutput()
|
||||
{
|
||||
int fail_safe=200000;
|
||||
while ((inportb(0x64)&1)==0 && fail_safe>0) fail_safe--;
|
||||
}
|
||||
|
||||
|
||||
void KeyboardInstallA()
|
||||
{
|
||||
KeyboardWaitInput(); outportb(0x60, 0xFF); // Reset kb
|
||||
|
||||
// Initialize variables
|
||||
KeyboardNewData = 0;
|
||||
KeyModifierStatus = 0;
|
||||
KeyScancodePrefix = 0;
|
||||
KeyLightsStatus = 0;
|
||||
KeyboardScancodeSet = 0;
|
||||
|
||||
memset((void*)KeyArray, 0, 16);
|
||||
}
|
||||
|
||||
|
||||
void KeyboardInstallB()
|
||||
{
|
||||
// Wait for BAT test results
|
||||
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
|
||||
|
||||
KeyboardWaitInput();
|
||||
outportb(0x64, 0x20); // Get "Command unsigned char"
|
||||
|
||||
do { temp = inportb(0x60);
|
||||
} while (temp==0xFA || temp==0xAA);
|
||||
|
||||
temp &= 0xFF - (1<<6); // Set bit6 to 0: disable conversion
|
||||
KeyboardWaitInput(); outportb(0x64, 0x60); // Function to write cmd unsigned char
|
||||
KeyboardWaitInput(); outportb(0x60, temp); // Send it
|
||||
}
|
135
SysCore/drivers/keyboard/keyboard.deprecated.h
Normal file
135
SysCore/drivers/keyboard/keyboard.deprecated.h
Normal file
@@ -0,0 +1,135 @@
|
||||
|
||||
#define KB_KEY_LSHIFT 0x81 // 1000 0001
|
||||
#define KB_KEY_RSHIFT 0X82 // 1000 0010
|
||||
#define KB_KEY_LALT 0X84 // 1000 0100
|
||||
#define KB_KEY_RALT 0x88 // 1000 1000
|
||||
#define KB_KEY_LCTRL 0x90 // 1001 0000
|
||||
#define KB_KEY_RCTRL 0xA0 // 1010 0000
|
||||
#define KB_KEY_FSHIFT 0xC0 // 1100 0000
|
||||
extern volatile unsigned char KeyModifierStatus;
|
||||
|
||||
#define KB_PREFIX_GRAY 0x01 // Gray
|
||||
#define KB_PREFIX_BREAK 0x02 // Break code
|
||||
#define KB_PREFIX_PAUSE 0x04 // Pause/break key
|
||||
#define KB_PREFIX_PAUSE1 0x08 // Recieved first unsigned char from pause/break
|
||||
extern volatile unsigned char KeyScancodePrefix;
|
||||
|
||||
#define KB_KEY_SCROLL 0xF1 // 1111 0001
|
||||
#define KB_KEY_NUM 0xF2 // 1111 0010
|
||||
#define KB_KEY_CAPS 0xF4 // 1111 0100
|
||||
extern volatile unsigned char KeyLightsStatus;
|
||||
|
||||
extern unsigned char KeyboardScancodeSet;
|
||||
|
||||
enum KeyboardKeys {
|
||||
KeyboardKeyPAUSE = 0x00,
|
||||
KeyboardKeyF9 = 0x01,
|
||||
KeyboardKeyF7 = 0x02,
|
||||
KeyboardKeyF5 = 0X03,
|
||||
KeyboardKeyF3 = 0x04,
|
||||
KeyboardKeyF1 = 0x05,
|
||||
KeyboardKeyF2 = 0x06,
|
||||
KeyboardKeyF12 = 0x07,
|
||||
KeyboardKeyPRINTSCRN = 0x08,
|
||||
KeyboardKeyF10 = 0x09,
|
||||
KeyboardKeyF8 = 0x0A,
|
||||
KeyboardKeyF6 = 0x0B,
|
||||
KeyboardKeyF4 = 0x0C,
|
||||
KeyboardKeyTAB = 0x0D,
|
||||
KeyboardKeyTILDA = 0x0E,
|
||||
KeyboardKeyQ = 0x15,
|
||||
KeyboardKey1 = 0x16,
|
||||
KeyboardKeyZ = 0x1A,
|
||||
KeyboardKeyS = 0x1B,
|
||||
KeyboardKeyA = 0x1C,
|
||||
KeyboardKeyW = 0x1D,
|
||||
KeyboardKey2 = 0x1E,
|
||||
KeyboardKeyLWIN = 0x1F,
|
||||
KeyboardKeyC = 0x21,
|
||||
KeyboardKeyX = 0x22,
|
||||
KeyboardKeyD = 0x23,
|
||||
KeyboardKeyE = 0x24,
|
||||
KeyboardKey4 = 0x25,
|
||||
KeyboardKey3 = 0x26,
|
||||
KeyboardKeyRWIN = 0x27,
|
||||
KeyboardKeySPACE = 0x29,
|
||||
KeyboardKeyV = 0x2A,
|
||||
KeyboardKeyF = 0x2B,
|
||||
KeyboardKeyT = 0x2C,
|
||||
KeyboardKeyR = 0x2D,
|
||||
KeyboardKey5 = 0x2E,
|
||||
KeyboardKeyMENU = 0x2F,
|
||||
KeyboardKeyN = 0x31,
|
||||
KeyboardKeyB = 0x32,
|
||||
KeyboardKeyH = 0x33,
|
||||
KeyboardKeyG = 0x34,
|
||||
KeyboardKeyY = 0x35,
|
||||
KeyboardKey6 = 0x36,
|
||||
KeyboardKeyM = 0x3A,
|
||||
KeyboardKeyJ = 0x3B,
|
||||
KeyboardKeyU = 0x3C,
|
||||
KeyboardKey7 = 0x3D,
|
||||
KeyboardKey8 = 0x3E,
|
||||
KeyboardKeyCOMMA = 0x41,
|
||||
KeyboardKeyK = 0x42,
|
||||
KeyboardKeyI = 0x43,
|
||||
KeyboardKeyO = 0x44,
|
||||
KeyboardKey0 = 0x45,
|
||||
KeyboardKey9 = 0x46,
|
||||
KeyboardKeyPERIOD = 0x49,
|
||||
KeyboardKeySLASH = 0x4A,
|
||||
KeyboardKeyL = 0x4B,
|
||||
KeyboardKeySEMICOLON = 0x4C,
|
||||
KeyboardKeyP = 0x4D,
|
||||
KeyboardKeyDASH = 0x4E,
|
||||
KeyboardKeyAPOSTROPHE = 0x52,
|
||||
KeyboardKeyLBRACKET = 0x54,
|
||||
KeyboardKeyEQUAL = 0x55,
|
||||
KeyboardKeyNUMPAD_ENTER = 0x59,
|
||||
KeyboardKeyENTER = 0x5A,
|
||||
KeyboardKeyRBRACKET = 0x5B,
|
||||
KeyboardKeyBACKSLASH = 0x5D,
|
||||
KeyboardKeyEND = 0x5E,
|
||||
KeyboardKeyLEFT = 0x5F,
|
||||
KeyboardKeyHOME = 0x60,
|
||||
KeyboardKeyINSERT = 0x61,
|
||||
KeyboardKeyDELETE = 0x62,
|
||||
KeyboardKeyDOWN = 0x63,
|
||||
KeyboardKeyRIGHT = 0x64,
|
||||
KeyboardKeyUP = 0x65,
|
||||
KeyboardKeyBACKSPACE = 0x66,
|
||||
KeyboardKeyPGDOWN = 0x67,
|
||||
KeyboardKeyPGUP = 0x68,
|
||||
KeyboardKeyNUMPAD_1 = 0x69,
|
||||
KeyboardKeyNUMPAD_SLASH = 0x6A,
|
||||
KeyboardKeyNUMPAD_4 = 0x6B,
|
||||
KeyboardKeyNUMPAD_7 = 0x6C,
|
||||
KeyboardKeyNUMPAD_0 = 0x70,
|
||||
KeyboardKeyNUMPAD_COLON = 0x71,
|
||||
KeyboardKeyNUMPAD_2 = 0x72,
|
||||
KeyboardKeyNUMPAD_5 = 0x73,
|
||||
KeyboardKeyNUMPAD_6 = 0x74,
|
||||
KeyboardKeyNUMPAD_8 = 0x75,
|
||||
KeyboardKeyESC = 0x76,
|
||||
KeyboardKeyF11 = 0x78,
|
||||
KeyboardKeyNUMPAD_PLUS = 0x79,
|
||||
KeyboardKeyNUMPAD_3 = 0x7A,
|
||||
KeyboardKeyNUMPAD_MINUS = 0x7B,
|
||||
KeyboardKeyNUMPAD_ASTERISK = 0x7C,
|
||||
KeyboardKeyNUMPAD_9 = 0x7D
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
unsigned char status;
|
||||
unsigned char lights;
|
||||
unsigned char scancode;
|
||||
unsigned char character;
|
||||
} kb_key;
|
||||
|
||||
|
||||
extern char getch();
|
||||
extern kb_key get_key();
|
||||
extern char scancode_to_ascii(unsigned char scancode);
|
||||
extern unsigned char get_key_status(unsigned char scancode);
|
||||
extern void kb_set_repeat(float rate, int delay);
|
||||
extern void kb_set_LEDs(unsigned char status);
|
135
SysCore/drivers/keyboard/keyboard.h.deprecated
Normal file
135
SysCore/drivers/keyboard/keyboard.h.deprecated
Normal file
@@ -0,0 +1,135 @@
|
||||
|
||||
#define KB_KEY_LSHIFT 0x81 // 1000 0001
|
||||
#define KB_KEY_RSHIFT 0X82 // 1000 0010
|
||||
#define KB_KEY_LALT 0X84 // 1000 0100
|
||||
#define KB_KEY_RALT 0x88 // 1000 1000
|
||||
#define KB_KEY_LCTRL 0x90 // 1001 0000
|
||||
#define KB_KEY_RCTRL 0xA0 // 1010 0000
|
||||
#define KB_KEY_FSHIFT 0xC0 // 1100 0000
|
||||
extern volatile unsigned char KeyModifierStatus;
|
||||
|
||||
#define KB_PREFIX_GRAY 0x01 // Gray
|
||||
#define KB_PREFIX_BREAK 0x02 // Break code
|
||||
#define KB_PREFIX_PAUSE 0x04 // Pause/break key
|
||||
#define KB_PREFIX_PAUSE1 0x08 // Recieved first unsigned char from pause/break
|
||||
extern volatile unsigned char KeyScancodePrefix;
|
||||
|
||||
#define KB_KEY_SCROLL 0xF1 // 1111 0001
|
||||
#define KB_KEY_NUM 0xF2 // 1111 0010
|
||||
#define KB_KEY_CAPS 0xF4 // 1111 0100
|
||||
extern volatile unsigned char KeyLightsStatus;
|
||||
|
||||
extern unsigned char KeyboardScancodeSet;
|
||||
|
||||
enum KB_KEYS {
|
||||
KB_KEY_PAUSE = 0x00,
|
||||
KB_KEY_F9 = 0x01,
|
||||
KB_KEY_F7 = 0x02,
|
||||
KB_KEY_F5 = 0X03,
|
||||
KB_KEY_F3 = 0x04,
|
||||
KB_KEY_F1 = 0x05,
|
||||
KB_KEY_F2 = 0x06,
|
||||
KB_KEY_F12 = 0x07,
|
||||
KB_KEY_PRINTSCRN = 0x08,
|
||||
KB_KEY_F10 = 0x09,
|
||||
KB_KEY_F8 = 0x0A,
|
||||
KB_KEY_F6 = 0x0B,
|
||||
KB_KEY_F4 = 0x0C,
|
||||
KB_KEY_TAB = 0x0D,
|
||||
KB_KEY_TILDA = 0x0E,
|
||||
KB_KEY_Q = 0x15,
|
||||
KB_KEY_1 = 0x16,
|
||||
KB_KEY_Z = 0x1A,
|
||||
KB_KEY_S = 0x1B,
|
||||
KB_KEY_A = 0x1C,
|
||||
KB_KEY_W = 0x1D,
|
||||
KB_KEY_2 = 0x1E,
|
||||
KB_KEY_LWIN = 0x1F,
|
||||
KB_KEY_C = 0x21,
|
||||
KB_KEY_X = 0x22,
|
||||
KB_KEY_D = 0x23,
|
||||
KB_KEY_E = 0x24,
|
||||
KB_KEY_4 = 0x25,
|
||||
KB_KEY_3 = 0x26,
|
||||
KB_KEY_RWIN = 0x27,
|
||||
KB_KEY_SPACE = 0x29,
|
||||
KB_KEY_V = 0x2A,
|
||||
KB_KEY_F = 0x2B,
|
||||
KB_KEY_T = 0x2C,
|
||||
KB_KEY_R = 0x2D,
|
||||
KB_KEY_5 = 0x2E,
|
||||
KB_KEY_MENU = 0x2F,
|
||||
KB_KEY_N = 0x31,
|
||||
KB_KEY_B = 0x32,
|
||||
KB_KEY_H = 0x33,
|
||||
KB_KEY_G = 0x34,
|
||||
KB_KEY_Y = 0x35,
|
||||
KB_KEY_6 = 0x36,
|
||||
KB_KEY_M = 0x3A,
|
||||
KB_KEY_J = 0x3B,
|
||||
KB_KEY_U = 0x3C,
|
||||
KB_KEY_7 = 0x3D,
|
||||
KB_KEY_8 = 0x3E,
|
||||
KB_KEY_COMMA = 0x41,
|
||||
KB_KEY_K = 0x42,
|
||||
KB_KEY_I = 0x43,
|
||||
KB_KEY_O = 0x44,
|
||||
KB_KEY_0 = 0x45,
|
||||
KB_KEY_9 = 0x46,
|
||||
KB_KEY_PERIOD = 0x49,
|
||||
KB_KEY_SLASH = 0x4A,
|
||||
KB_KEY_L = 0x4B,
|
||||
KB_KEY_SEMICOLON = 0x4C,
|
||||
KB_KEY_P = 0x4D,
|
||||
KB_KEY_DASH = 0x4E,
|
||||
KB_KEY_APOSTROPHE = 0x52,
|
||||
KB_KEY_LBRACKET = 0x54,
|
||||
KB_KEY_EQUAL = 0x55,
|
||||
KB_KEY_NUMPAD_ENTER = 0x59,
|
||||
KB_KEY_ENTER = 0x5A,
|
||||
KB_KEY_RBRACKET = 0x5B,
|
||||
KB_KEY_BACKSLASH = 0x5D,
|
||||
KB_KEY_END = 0x5E,
|
||||
KB_KEY_LEFT = 0x5F,
|
||||
KB_KEY_HOME = 0x60,
|
||||
KB_KEY_INSERT = 0x61,
|
||||
KB_KEY_DELETE = 0x62,
|
||||
KB_KEY_DOWN = 0x63,
|
||||
KB_KEY_RIGHT = 0x64,
|
||||
KB_KEY_UP = 0x65,
|
||||
KB_KEY_BACKSPACE = 0x66,
|
||||
KB_KEY_PGDOWN = 0x67,
|
||||
KB_KEY_PGUP = 0x68,
|
||||
KB_KEY_NUMPAD_1 = 0x69,
|
||||
KB_KEY_NUMPAD_SLASH = 0x6A,
|
||||
KB_KEY_NUMPAD_4 = 0x6B,
|
||||
KB_KEY_NUMPAD_7 = 0x6C,
|
||||
KB_KEY_NUMPAD_0 = 0x70,
|
||||
KB_KEY_NUMPAD_COLON = 0x71,
|
||||
KB_KEY_NUMPAD_2 = 0x72,
|
||||
KB_KEY_NUMPAD_5 = 0x73,
|
||||
KB_KEY_NUMPAD_6 = 0x74,
|
||||
KB_KEY_NUMPAD_8 = 0x75,
|
||||
KB_KEY_ESC = 0x76,
|
||||
KB_KEY_F11 = 0x78,
|
||||
KB_KEY_NUMPAD_PLUS = 0x79,
|
||||
KB_KEY_NUMPAD_3 = 0x7A,
|
||||
KB_KEY_NUMPAD_MINUS = 0x7B,
|
||||
KB_KEY_NUMPAD_ASTERISK = 0x7C,
|
||||
KB_KEY_NUMPAD_9 = 0x7D
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
unsigned char status;
|
||||
unsigned char lights;
|
||||
unsigned char scancode;
|
||||
unsigned char character;
|
||||
} kb_key;
|
||||
|
||||
|
||||
extern char getch();
|
||||
extern kb_key get_key();
|
||||
extern char scancode_to_ascii(unsigned char scancode);
|
||||
extern unsigned char get_key_status(unsigned char scancode);
|
||||
extern void kb_set_repeat(float rate, int delay);
|
||||
extern void kb_set_LEDs(unsigned char status);
|
158
SysCore/drivers/makeall.bat
Normal file
158
SysCore/drivers/makeall.bat
Normal file
@@ -0,0 +1,158 @@
|
||||
@echo off
|
||||
set nasm_path=C:\nasm
|
||||
set djgpp_path=C:\mingw\bin
|
||||
|
||||
goto this
|
||||
|
||||
:error
|
||||
@echo.
|
||||
@echo There have been build errors. Building halted.
|
||||
@pause
|
||||
exit
|
||||
|
||||
:this
|
||||
@echo Building Drivers...
|
||||
set objpath=..\objects\drivers
|
||||
set incpath=../include
|
||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o drivers.o drivers.c
|
||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o BSOD.o BSOD.c
|
||||
|
||||
if not exist drivers.o goto error
|
||||
if not exist BSOD.o goto error
|
||||
|
||||
xcopy /Y *.o %objpath% >nul
|
||||
del *.o
|
||||
|
||||
:clock
|
||||
set objpath=..\..\objects\drivers
|
||||
set incpath=../../include
|
||||
|
||||
cd clock
|
||||
@echo * Compiling internal clock...
|
||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o pit.o pit.c
|
||||
if not exist pit.o goto error
|
||||
|
||||
xcopy /Y *.o %objpath% >nul
|
||||
del *.o
|
||||
|
||||
cd..
|
||||
|
||||
|
||||
:floppy
|
||||
cd floppy
|
||||
@echo * Compiling floppy driver...
|
||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o dma.o dma.c
|
||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o floppy.o floppy.c
|
||||
if not exist dma.o goto error
|
||||
if not exist floppy.o goto error
|
||||
xcopy /Y *.o %objpath% >nul
|
||||
del *.o
|
||||
|
||||
cd..
|
||||
|
||||
:filesys
|
||||
cd filesys
|
||||
@echo * Compiling file systems...
|
||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o fat.o fat.c
|
||||
rem %djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o floppy.o floppy.c
|
||||
if not exist fat.o goto error
|
||||
rem if not exist floppy.o goto error
|
||||
xcopy /Y *.o %objpath% >nul
|
||||
del *.o
|
||||
|
||||
cd..
|
||||
|
||||
:keyboard
|
||||
cd keyboard
|
||||
@echo * Compiling keyboard driver...
|
||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o keyboard.o keyboard.c
|
||||
if not exist keyboard.o goto error
|
||||
xcopy /Y *.o %objpath% >nul
|
||||
del *.o
|
||||
|
||||
cd..
|
||||
|
||||
|
||||
:cpu
|
||||
cd cpu
|
||||
@echo * Compiling Central Processing Unit (CPU) modules...
|
||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o cpu.o cpu.c
|
||||
if not exist cpu.o goto error
|
||||
|
||||
xcopy /Y *.o %objpath% >nul
|
||||
del *.o
|
||||
|
||||
set objpath=..\..\..\objects\drivers
|
||||
set incpath=../../../include
|
||||
|
||||
:gdt
|
||||
@echo + Global Descriptor Table
|
||||
cd gdt
|
||||
|
||||
rem Assembly File:
|
||||
%nasm_path%\nasm.exe -f aout -o gdt_asm.o gdt.asm
|
||||
if not exist gdt_asm.o goto error
|
||||
|
||||
rem C File:
|
||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o gdt.o gdt.c
|
||||
if not exist gdt.o goto error
|
||||
|
||||
xcopy /Y *.o %objpath% >nul
|
||||
del *.o
|
||||
cd..
|
||||
|
||||
:idt
|
||||
@echo + Interrupt Descriptor Table
|
||||
cd idt
|
||||
|
||||
rem Assembly File:
|
||||
%nasm_path%\nasm.exe -f aout -o idt_asm.o idt.asm
|
||||
if not exist idt_asm.o goto error
|
||||
|
||||
rem C File:
|
||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o idt.o idt.c
|
||||
if not exist idt.o goto error
|
||||
|
||||
xcopy /Y *.o %objpath% >nul
|
||||
del *.o
|
||||
cd..
|
||||
|
||||
:irq
|
||||
@echo + Interrupt Requests
|
||||
cd irq
|
||||
|
||||
rem IRQ Assembly File:
|
||||
%nasm_path%\nasm.exe -f aout -o irq_asm.o irq.asm
|
||||
if not exist irq_asm.o goto error
|
||||
|
||||
rem IRQ C File:
|
||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o irq.o irq.c
|
||||
if not exist irq.o goto error
|
||||
|
||||
@echo + Programmable Interrupt Controller
|
||||
rem PIC C File:
|
||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o pic.o pic.c
|
||||
if not exist pic.o goto error
|
||||
|
||||
xcopy /Y *.o %objpath% >nul
|
||||
del *.o
|
||||
cd..
|
||||
|
||||
:isrs
|
||||
@echo + Interrupt Service Routines
|
||||
cd isrs
|
||||
|
||||
rem Assembly File:
|
||||
%nasm_path%\nasm.exe -f aout -o isrs_asm.o isrs.asm
|
||||
if not exist isrs_asm.o goto error
|
||||
|
||||
rem C File:
|
||||
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o isrs.o isrs.c
|
||||
if not exist isrs.o goto error
|
||||
|
||||
xcopy /Y *.o %objpath% >nul
|
||||
del *.o
|
||||
cd..
|
||||
|
||||
|
||||
cd..
|
Reference in New Issue
Block a user