This commit is contained in:
2021-09-14 18:46:50 +03:00
parent d605c6a016
commit b6ddeca1c3
180 changed files with 5909 additions and 2039 deletions

85
SysCore/drivers/BSOD.c Normal file
View 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 (;;);
}

View 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
View 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);
}

View 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..

View 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
View 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
View 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

View 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!

View 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();
}

View 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

View File

@@ -0,0 +1,9 @@
bits 32
; !!! IDT !!!
; Loads the IDT defined in '_idtp'
global _i86_IdtLoad
extern _idtp
_i86_IdtLoad:
lidt [_idtp]
ret

View 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();
}

View 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

View 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

View 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);
}

View 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

View 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);
}

View File

@@ -0,0 +1,6 @@
#ifndef _PIC_H
#define _PIC_H
extern void i86_PicRemap(int pic1, int pic2);
#endif

View 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!

View 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);
}
}

View 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
View 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");
}

View File

@@ -0,0 +1,9 @@
#ifndef __DRIVERS__H__
#define __DRIVERS__H__
extern void DriversInstall();
extern void SystemShutDown();
extern void SystemReboot();
#endif

View 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;
}*/

View 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

View 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);
}

View 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

View 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);
}

View 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

View 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*) &sector);
// 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*) &sector);
// Seek
if (!FloppySeek(drive, track, head)) return 0;
// Read the sector
FloppyWriteSectorImp((unsigned*)0x7e00, drive, head, track, sector);
}
FloppyMotor(drive, 0);
return (unsigned*)where;
}

View 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);

View 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

View 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

View 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

View 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
}

View 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);

View 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
View 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..