Ok here is my IRQ, ISR, IDT, and KERNEL code as well as the Assembler stubs
ISR and IRQ asm stub
Code: Select all
[BITS 32]
%macro ISR_NOERRCODE 2 ; define a macro, taking one parameter
GLOBAL %1 ; %1 accesses the first parameter.
%1:
cli
push byte 0
push byte %2
jmp isr_common_stub
%endmacro
%macro ISR_ERRCODE 2
GLOBAL %1
%1:
cli
push byte %2
jmp isr_common_stub
%endmacro
ISR_NOERRCODE isr0,0
ISR_NOERRCODE isr1,1
ISR_NOERRCODE isr2,2
ISR_NOERRCODE isr3,3
ISR_NOERRCODE isr4,4
ISR_NOERRCODE isr5,5
ISR_NOERRCODE isr6,6
ISR_NOERRCODE isr7,7
ISR_ERRCODE isr8,8
ISR_NOERRCODE isr9,9
ISR_ERRCODE isr10,10
ISR_ERRCODE isr11,11
ISR_ERRCODE isr12,12
ISR_ERRCODE isr13,13
ISR_ERRCODE isr14,14
ISR_NOERRCODE isr15,15
ISR_NOERRCODE isr16,16
ISR_NOERRCODE isr17,17
ISR_NOERRCODE isr18,18
ISR_NOERRCODE isr19,19
ISR_NOERRCODE isr20,20
ISR_NOERRCODE isr21,21
ISR_NOERRCODE isr22,22
ISR_NOERRCODE isr23,23
ISR_NOERRCODE isr24,24
ISR_NOERRCODE isr25,25
ISR_NOERRCODE isr26,26
ISR_NOERRCODE isr27,27
ISR_NOERRCODE isr28,28
ISR_NOERRCODE isr29,29
ISR_NOERRCODE isr30,30
ISR_NOERRCODE isr31,31
ISR_NOERRCODE isr32,32
[EXTERN isr_handler]
; This is our common ISR stub. It saves the processor state, sets
; up for kernel mode segments, calls the C-level fault handler,
; and finally restores the stack frame.
isr_common_stub:
pusha ; Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax
mov ax, ds ; Lower 16-bits of eax = ds.
push eax ; save the data segment descriptor
mov ax, 0x10 ; load the kernel data segment descriptor
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
call isr_handler
pop eax ; reload the original data segment descriptor
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
popa ; Pops edi,esi,ebp...
add esp, 8 ; Cleans up the pushed error code and pushed ISR number
sti
iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP
%macro irqmacro 2
global %1
%1:
cli
push byte 0
push byte %2
jmp irq_common_stub
%endmacro
irqmacro irq0,32 ; 32: Timer
irqmacro irq1,33 ; 33: Keyboard
irqmacro irq2,34 ; 34: ???
irqmacro irq3,35 ; 35: ???
irqmacro irq4,36 ; 36: ???
irqmacro irq5,37 ; 37: ???
irqmacro irq6,38 ; 38: ???
irqmacro irq7,39 ; 39: ???
irqmacro irq8,40 ; 40: ???
irqmacro irq9,41 ; 41: ???
irqmacro irq10,42 ; 42: ???
irqmacro irq11,43 ; 43: ???
irqmacro irq12,44 ; 44: ???
irqmacro irq13,45 ; 45: ???
irqmacro irq14,46 ; 46: ???
irqmacro irq15,47 ; 47: ???
extern irq_handler
irq_common_stub:
pusha
push ds
push es
push fs
push gs
mov ax,0x10
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov eax,esp
push eax
mov eax,irq_handler
call eax
pop eax
pop gs
pop fs
pop es
pop ds
popa
add esp,8
iret
IRQ code
Code: Select all
unit irq;
interface
type
TIRQHandler = procedure (var r : TRegisters);
const
IRQRoutines : array[0..15] of TIRQHandler = (
nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil
);
procedure InitIRQ;stdcall;
procedure InstallIRQHandler(const IRQNo : byte; Handler : TIRQHandler);
procedure UninstallIRQHandler(const IRQNo : byte);
procedure IRQWait(IRQNo : byte);
var
IRQWaiting : boolean = false;
IRQWaiter : byte;
implementation
uses IDT, console;
procedure irq0; external name 'irq0';
procedure irq1; external name 'irq1';
procedure irq2; external name 'irq2';
procedure irq3; external name 'irq3';
procedure irq4; external name 'irq4';
procedure irq5; external name 'irq5';
procedure irq6; external name 'irq6';
procedure irq7; external name 'irq7';
procedure irq8; external name 'irq8';
procedure irq9; external name 'irq9';
procedure irq10; external name 'irq10';
procedure irq11; external name 'irq11';
procedure irq12; external name 'irq12';
procedure irq13; external name 'irq13';
procedure irq14; external name 'irq14';
procedure irq15; external name 'irq15';
procedure InstallIRQHandler(const IRQNo : byte; Handler : TIRQHandler);
begin
IRQRoutines[IRQNo] := Handler;
end;
procedure UninstallIRQHandler(const IRQNo : byte);
begin
IRQRoutines[IRQNo] := nil;
end;
procedure RemapIRQ;
begin
WritePort($20,$11);
WritePort($A0,$11);
WritePort($21,$20);
WritePort($A1,$28);
WritePort($21,$04);
WritePort($A1,$02);
WritePort($21,$01);
WritePort($A1,$01);
WritePort($21,$0);
WritePort($A1,$0);
end;
procedure InitIRQ;stdcall;[public, alias : 'initIRQ'];
begin
PrintString(#10'Remapping the Interupt Requests (IRQ)');
RemapIRQ;
PrintString(#10'Done'#10'Initialising IRQs 0 - 15');
SetIDTGate(32,PtrUInt(@irq0),$08,$8E,false); //timer
SetIDTGate(33,PtrUInt(@irq1),$08,$8E,false); //keyboard
SetIDTGate(34,PtrUInt(@irq2),$08,$8E,false);
SetIDTGate(35,PtrUInt(@irq3),$08,$8E,false);
SetIDTGate(36,PtrUInt(@irq4),$08,$8E,false);
SetIDTGate(37,PtrUInt(@irq5),$08,$8E,false);
SetIDTGate(38,PtrUInt(@irq6),$08,$8E,false);
SetIDTGate(39,PtrUInt(@irq7),$08,$8E,false);
SetIDTGate(40,PtrUInt(@irq8),$08,$8E,false);
SetIDTGate(41,PtrUInt(@irq9),$08,$8E,false);
SetIDTGate(42,PtrUInt(@irq10),$08,$8E,false);
SetIDTGate(43,PtrUInt(@irq11),$08,$8E,false);
SetIDTGate(44,PtrUInt(@irq12),$08,$8E,false);
SetIDTGate(45,PtrUInt(@irq13),$08,$8E,false);
SetIDTGate(46,PtrUInt(@irq14),$08,$8E,false);
SetIDTGate(47,PtrUInt(@irq15),$08,$8E,false);
PrintString(#10'Done');
end;
procedure IRQWait(IRQNo : byte);
begin
IRQWaiter := IRQNo;
IRQWaiting := true;
while IRQWaiting = true do;
end;
procedure IrqHandler(var r : TRegisters); cdecl; [public, alias: 'irq_handler'];
var
Handler : TIrqHandler = nil;
begin
Handler := IrqRoutines[r.InterruptNumber-32];
if (IRQWaiting = true) and (IRQWaiter = (r.InterruptNumber-32)) then
IRQWaiting := false;
if Assigned(Handler) then
Handler(r);
if r.InterruptNumber >= 40 then
WritePort($A0,$20);
WritePort($20,$20);
end;
end.
ISR code:
Code: Select all
unit isr;
interface
procedure InitISR;stdcall;
implementation
uses idt, console;
const
ExceptionMessages: array [0..31] of String = (
'Division By Zero',
'Debug',
'Non Maskable Interrupt',
'Breakpoint',
'Into Detected Overflow',
'Out of Bounds',
'Invalid Opcode',
'No Coprocessor',
'Double Fault',
'Coprocessor Segment Overrun',
'Bad TSS',
'Segment Not Present',
'Stack Fault',
'General Protection Fault',
'Page Fault',
'Unknown Interrupt',
'Coprocessor Fault',
'Alignment Check',
'Machine Check',
'Reserved',
'Reserved',
'Reserved',
'Reserved',
'Reserved',
'Reserved',
'Reserved',
'Reserved',
'Reserved',
'Reserved',
'Reserved',
'Reserved',
'Reserved'
);
procedure isr0; external name 'isr0';
procedure isr1; external name 'isr1';
procedure isr2; external name 'isr2';
procedure isr3; external name 'isr3';
procedure isr4; external name 'isr4';
procedure isr5; external name 'isr5';
procedure isr6; external name 'isr6';
procedure isr7; external name 'isr7';
procedure isr8; external name 'isr8';
procedure isr9; external name 'isr9';
procedure isr10; external name 'isr10';
procedure isr11; external name 'isr11';
procedure isr12; external name 'isr12';
procedure isr13; external name 'isr13';
procedure isr14; external name 'isr14';
procedure isr15; external name 'isr15';
procedure isr16; external name 'isr16';
procedure isr17; external name 'isr17';
procedure isr18; external name 'isr18';
procedure isr19; external name 'isr19';
procedure isr20; external name 'isr20';
procedure isr21; external name 'isr21';
procedure isr22; external name 'isr22';
procedure isr23; external name 'isr23';
procedure isr24; external name 'isr24';
procedure isr25; external name 'isr25';
procedure isr26; external name 'isr26';
procedure isr27; external name 'isr27';
procedure isr28; external name 'isr28';
procedure isr29; external name 'isr29';
procedure isr30; external name 'isr30';
procedure isr31; external name 'isr31';
procedure InitISR; stdcall;[public, alias: 'initISR'];
begin
// PrintString(#10'Initalising Interupt Service Requests (ISR)');
SetIDTGate(0,PtrUInt(@isr0),$08,$8E,false);
SetIDTGate(1,PtrUInt(@isr1),$08,$8E,false);
SetIDTGate(2,PtrUInt(@isr2),$08,$8E,false);
SetIDTGate(3,PtrUInt(@isr3),$08,$8E,false);
SetIDTGate(4,PtrUInt(@isr4),$08,$8E,false);
SetIDTGate(5,PtrUInt(@isr5),$08,$8E,false);
SetIDTGate(6,PtrUInt(@isr6),$08,$8E,false);
SetIDTGate(7,PtrUInt(@isr7),$08,$8E,false);
SetIDTGate(8,PtrUInt(@isr8),$08,$8E,false);
SetIDTGate(9,PtrUInt(@isr9),$08,$8E,false);
SetIDTGate(10,PtrUInt(@isr10),$08,$8E,false);
SetIDTGate(11,PtrUInt(@isr11),$08,$8E,false);
SetIDTGate(12,PtrUInt(@isr12),$08,$8E,false);
SetIDTGate(13,PtrUInt(@isr13),$08,$8E,false);
SetIDTGate(14,PtrUInt(@isr14),$08,$8E,false);
SetIDTGate(15,PtrUInt(@isr15),$08,$8E,false);
SetIDTGate(16,PtrUInt(@isr16),$08,$8E,false);
SetIDTGate(17,PtrUInt(@isr17),$08,$8E,false);
SetIDTGate(18,PtrUInt(@isr18),$08,$8E,false);
SetIDTGate(19,PtrUInt(@isr19),$08,$8E,false);
SetIDTGate(20,PtrUInt(@isr20),$08,$8E,false);
SetIDTGate(21,PtrUInt(@isr21),$08,$8E,false);
SetIDTGate(22,PtrUInt(@isr22),$08,$8E,false);
SetIDTGate(23,PtrUInt(@isr23),$08,$8E,false);
SetIDTGate(24,PtrUInt(@isr24),$08,$8E,false);
SetIDTGate(25,PtrUInt(@isr25),$08,$8E,false);
SetIDTGate(26,PtrUInt(@isr26),$08,$8E,false);
SetIDTGate(27,PtrUInt(@isr27),$08,$8E,false);
SetIDTGate(28,PtrUInt(@isr28),$08,$8E,false);
SetIDTGate(29,PtrUInt(@isr29),$08,$8E,false);
SetIDTGate(30,PtrUInt(@isr30),$08,$8E,false);
SetIDTGate(31,PtrUInt(@isr31),$08,$8E,false);
// PrintString(#10'Done');
end;
procedure ISR_Handler(var r: TRegisters); cdecl; [public, alias: 'isr_handler'];
var
s : string;
begin
if r.InterruptNumber < 32 then begin
SetTextColor(clBlack,clRed);
PrintChar(#10);
PrintString(ExceptionMessages[r.InterruptNumber]);
PrintString(' Exception');
with r do begin
Str(ErrorCode, s);
PrintString(#10'Error code = ');PrintString(s);
PrintString(#10'EAX'#9'= $');PrintString(HexStr(eax,8));
PrintString(#10'EBX'#9'= $');PrintString(HexStr(ebx,8));
PrintString(#10'ECX'#9'= $');PrintString(HexStr(ecx,8));
PrintString(#10'EDX'#9'= $');PrintString(HexStr(edx,8));
PrintString(#10'ESI'#9'= $');PrintString(HexStr(esi,8));
PrintString(#10'EDI'#9'= $');PrintString(HexStr(edi,8));
PrintString(#10'ESP'#9'= $');PrintString(HexStr(esp,8));
PrintString(#10'EBP'#9'= $');PrintString(HexStr(ebp,8));
PrintString(#10'CS'#9'= $');PrintString(HexStr(cs,8));
PrintString(#10'DS'#9'= $');PrintString(HexStr(ds,8));
PrintString(#10'ES'#9'= $');PrintString(HexStr(es,8));
PrintString(#10'FS'#9'= $');PrintString(HexStr(fs,8));
PrintString(#10'GS'#9'= $');PrintString(HexStr(gs,8));
PrintString(#10'SS'#9'= $');PrintString(HexStr(ss,8));
PrintString(#10'EIP'#9'= $');PrintString(HexStr(eip,8));
PrintString(#10'EFLAGS'#9'= $');PrintString(HexStr(eflags,8));
PrintString(#10'User ESP'#9'= $');PrintString(HexStr(UserESP,8));
end;
SetTextColor(clBlack,clWhite);
PrintChar(#10);
while true do ;
end;
end;
end.
IDT code
Code: Select all
unit idt;
interface
type
TIDTEntry = packed record
BaseLow : word;
SegSel : word;
Always0 : byte;
Flags : byte;
BaseHigh : word;
end;
TIDTPtr = packed record
limit : word;
base : LongWord;
end;
var
IDTPtr : TIDTPtr;
IDTTables : array[0..255] of TIDTEntry;
procedure SetIDTGate(idx: Byte; base: LongWord; SSelect: Word; flg: Byte; UserMode : boolean);
procedure initIDT;stdcall;
implementation
uses console;
procedure FlushIDT; assembler; nostackframe;
asm
lidt IDTPtr
end;
procedure SetIDTGate(idx: Byte; base: LongWord; SSelect: Word; flg: Byte; UserMode : boolean);
begin
with IDTTables[idx] do
begin
BaseLow := base and $FFFF;
BaseHigh := (base shr 16) and $FFFF;
SegSel := SSelect;
Always0 := 0;
if UserMode = true then
Flags := flg or $60
else
Flags := flg;
end;
end;
procedure initIDT;stdcall;[public, alias: 'initIDT'];
begin
//PrintString(#10'Initialising the Interupt Descriptor Table (IDT)');
IDTPtr.limit := SizeOf(IDTTables)-1;
IDTPtr.base := PtrUInt(@IDTTables);
FillByte(IDTTables,SizeOf(IDTTables),0);
FlushIDT;
//PrintString(#10'Done');
end;
end.
Kernel Code
Code: Select all
unit kernel;
interface
procedure kmain; stdcall;
implementation
uses console, idt, gdt, isr, irq, pit, keyboard, paging{, heap, DMA, Sound}, Floppy {,ConsoleEXP};
Const
kHeader = 'GIZMIC OS v0.01';
kHeaderBg = clBlue;
kHeaderFg = clWhite;
procedure kmain; stdcall;[public, alias: 'kmain'];
var
sTemp : string;
i, x : byte;
begin
initScreen;
SetTextColor(clBlack,clLightGreen);
initGDT;
initIDT;
initISR;
initIRQ;
initTimer(100);
initKeyboard;
initPaging(1000000);
PrintString('STI - Start');
asm
sti
end;
PrintString(#10'STI - done');
//dmainit;
//initFloppy;
SetTextColor(clBlack,clWhite);
ClearScreen;
GoToXY(0,0);
SetTextColor(clBlue,clWhite);
PrintString(kHeader + #10);
SetTextColor(clBlack,clWhite);
SetHeader(true);
{i := 0;
x := 122323 div i; }
while true do ;
end;
end.
I hope this can help.