This commit is contained in:
2021-09-14 18:34:14 +03:00
parent 7cb940e485
commit 4e5c38d0ff
152 changed files with 5042 additions and 2585 deletions

View File

@ -0,0 +1,19 @@
@echo off
rem The name of the loader assembly file (without extension, must be .asm):
set loader_name=loader
rem NASM and DJGPP executable paths:
set nasm_path=C:\nasm
set djgpp_path=C:\DJGPP\bin
set objpath=../../objects
set incpath=../../include
@echo on
%nasm_path%\nasm.exe -f aout -o %objpath%/irq_asm.o irq.asm
%djgpp_path%\gcc.exe -Wall -O -fstrength-reduce -fomit-frame-pointer -nostdinc -fno-builtin -I%incpath% -c -o %objpath%/irq.o irq.c
@echo off
@echo .
@echo Done!
@pause

159
SysCore/hal/irq/irq.asm Normal file
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_irq_handler
; 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_irq_handler
call eax
pop eax
pop gs
pop fs
pop es
pop ds
popa
add esp, 8
iret

79
SysCore/hal/irq/irq.c Normal file
View File

@ -0,0 +1,79 @@
#include <system.h>
#include "../idt/idt.h"
#include "../pic/pic.h"
#include "irq.h"
/* This array is actually an array of function pointers. We use
* this to handle custom IRQ handlers for a given IRQ */
void *irq_routines[16] =
{
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
/* This installs a custom IRQ handler for the given IRQ */
void i86_irq_install_handler (int irq, void (*handler)(ISR_stack_regs *r))
{
irq_routines[irq] = handler;
}
void i86_irq_uninstall_handler (int irq)
{
irq_routines[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_irq_install()
{
i86_pic_remap(32,40);
i86_idt_set_gate(32, (unsigned)i86_irq0, 0x08, 0x8E);
i86_idt_set_gate(33, (unsigned)i86_irq1, 0x08, 0x8E);
i86_idt_set_gate(34, (unsigned)i86_irq2, 0x08, 0x8E);
i86_idt_set_gate(35, (unsigned)i86_irq3, 0x08, 0x8E);
i86_idt_set_gate(36, (unsigned)i86_irq4, 0x08, 0x8E);
i86_idt_set_gate(37, (unsigned)i86_irq5, 0x08, 0x8E);
i86_idt_set_gate(38, (unsigned)i86_irq6, 0x08, 0x8E);
i86_idt_set_gate(39, (unsigned)i86_irq7, 0x08, 0x8E);
i86_idt_set_gate(40, (unsigned)i86_irq8, 0x08, 0x8E);
i86_idt_set_gate(41, (unsigned)i86_irq9, 0x08, 0x8E);
i86_idt_set_gate(42, (unsigned)i86_irq10, 0x08, 0x8E);
i86_idt_set_gate(43, (unsigned)i86_irq11, 0x08, 0x8E);
i86_idt_set_gate(44, (unsigned)i86_irq12, 0x08, 0x8E);
i86_idt_set_gate(45, (unsigned)i86_irq13, 0x08, 0x8E);
i86_idt_set_gate(46, (unsigned)i86_irq14, 0x08, 0x8E);
i86_idt_set_gate(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_irq_handler (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 = irq_routines[r->int_no - 32];
if (handler) handler(r);
/* If the IDT entry that was invoked was greater than 40
* (meaning IRQ8 - 15), then we need to send an EOI to
* the slave controller */
if (r->int_no >=40) outportb(0x0A, 0x20);
/* In either case, we need to send an EOI to the master
* interrupt controller too */
outportb(0x20, 0x20);
}

29
SysCore/hal/irq/irq.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef __IRQ_H
#define __IRQ_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();
extern void i86_irq_install_handler (int irq, void (*handler)(ISR_stack_regs *r));
extern void i86_irq_uninstall_handler (int irq);
extern void i86_irq_install();
extern void i86_irq_handler (ISR_stack_regs *r);
#endif