Can't get keyboard input working

Programming, for all ages and all languages.
Post Reply
User avatar
WeeLonelySoul
Posts: 1
Joined: Tue Feb 13, 2018 12:38 am

Can't get keyboard input working

Post by WeeLonelySoul »

Hello!

As the title says, I've been stuck on this issue for a couple of weeks now and felt that I might just ask the community and see if they know how to solve the issue.
It feels that no matter what I do the OS won't recieve the input by the keyboard.

Here's the code

GDT.c

Code: Select all

#include "../../libraries/bikka/gdt.h"
#include "../../libraries/bikka/tss.h"
#include "../../libraries/bikka/memory.h"

gdt_entry_t GDT_ENTRIES[6]; /* This is the amount of GDT_SET_ENTRY below */
gdt_ptr_t GDT_PTR;
/*
GDT, IRQ and IDE are things that quite quickly can go out of hand
Therefore I recommend James Malloy's tutorial on this
-> http://www.jamesmolloy.co.uk/tutorial_html/
*/

void GDT_INSTALL(void){
    /* Install the Global Descriptor Table */
    GDT_PTR.limit = (sizeof(gdt_entry_t) * 6) -1; 
    GDT_PTR.base = (u32)&GDT_ENTRIES;

    GDT_SET_ENTRY(0, 0, 0, 0, 0); /* Null segment */
    GDT_SET_ENTRY(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); /* Code segment */
    GDT_SET_ENTRY(2, 0, 0xFFFFFFFF, 0x92, 0xCF); /* Data segment */
    GDT_SET_ENTRY(3, &tss_entry_t, sizeof(tss_entry_t), 0x89, 0xCF); /* TSS segment */

    MEM_ALC(&tss_entry_t, 0, sizeof(tss_entry_t)); /* Allocate space for the tss */
    GDT_SET_ENTRY(4, 0, 0xFFFFFFFF, 0xFA, 0xCF); /* User mode code segment */
    GDT_SET_ENTRY(5, 0, 0xFFFFFFFF, 0xF2, 0xCF); /* User mode data segment */

    GDT_FLUSH((u32)&GDT_PTR);
}


void GDT_SET_ENTRY(s32 Index, u32 Base, u32 Limit, u8 Access, u8 Gran){

    GDT_ENTRIES[Index].base_low = (Base & 0xFFFF);
    GDT_ENTRIES[Index].base_middle = (Base >> 16) & 0xFF;
    GDT_ENTRIES[Index].base_high = (Base >> 24) & 0xFF;

    GDT_ENTRIES[Index].limit_low = (Limit & 0xFFFF);
    GDT_ENTRIES[Index].granularity = ((Limit >> 16) & 0x0F);

    GDT_ENTRIES[Index].granularity |= (Gran & 0xF0);
    GDT_ENTRIES[Index].access = Access;

}
GDT.asm

Code: Select all

; These functions are used in gdt.c
; Courtesy of james Molloy
; Check out his guides
; -> http://www.jamesmolloy.co.uk/tutorial_html/4.-The%20GDT%20and%20IDT.html

global GDT_FLUSH

GDT_FLUSH:
   mov eax, [esp+4]  ; Get the pointer to the GDT, passed as a parameter.
   lgdt [eax]        ; Load the new GDT pointer

   mov ax, 0x10      ; 0x10 is the offset in the GDT to our data segment
   mov ds, ax        ; Load all data segment selectors
   mov es, ax
   mov fs, ax
   mov gs, ax
   mov ss, ax
   jmp 0x08:.flush   ; 0x08 is the offset to our code segment: Far jump!
.flush:
   ret
GDT.h

Code: Select all

#ifndef GDT_H
#define GDT_H 1

#include "../common.h"

typedef struct GDT {
   u16 limit_low;
   u16 base_low;
   u8 base_middle;
   u8 access;
   u8 granularity;
   u8 base_high;
}__attribute((packed)) gdt_entry_t;

typedef struct GDT_PTR{
    u16 limit;
    u32 base;
}__attribute__((packed)) gdt_ptr_t;


void GDT_INSTALL(void);
void GDT_SET_ENTRY(s32 Index, u32 Base, u32 Limit, u8 Access, u8 Gran);
extern void GDT_FLUSH(u32 GDT_PTR); /* Located in gdt.asm file */

#endif
IDT.c

Code: Select all

#include "../../libraries/bikka/idt.h"
#include "../../libraries/common.h"
#include "../../libraries/bikka/isr.h"
#include "../../libraries/bikka/memory.h"

void IDT_INSTALL(void){
    IDT_REG.limit = sizeof(idt_gate_t) * 256 - 1;
    IDT_REG.base = (u32)&IDT;

    memset(&IDT, 0, sizeof(idt_gate_t)*256);
    
    IDT_SET_GATE(0, (u32)isr0, 0x08, 0x8E);
    IDT_SET_GATE(1, (u32)isr1, 0x08, 0x8E);
    IDT_SET_GATE(2, (u32)isr2, 0x08, 0x8E);
    IDT_SET_GATE(3, (u32)isr3, 0x08, 0x8E);
    IDT_SET_GATE(4, (u32)isr4, 0x08, 0x8E);
    IDT_SET_GATE(5, (u32)isr5, 0x08, 0x8E);
    IDT_SET_GATE(6, (u32)isr6, 0x08, 0x8E);
    IDT_SET_GATE(7, (u32)isr7, 0x08, 0x8E);
    IDT_SET_GATE(8, (u32)isr8, 0x08, 0x8E);
    IDT_SET_GATE(9, (u32)isr9, 0x08, 0x8E);
    IDT_SET_GATE(10, (u32)isr10, 0x08, 0x8E);
    IDT_SET_GATE(11, (u32)isr11, 0x08, 0x8E);
    IDT_SET_GATE(12, (u32)isr12, 0x08, 0x8E);
    IDT_SET_GATE(13, (u32)isr13, 0x08, 0x8E);
    IDT_SET_GATE(14, (u32)isr14, 0x08, 0x8E);
    IDT_SET_GATE(15, (u32)isr15, 0x08, 0x8E);
    IDT_SET_GATE(16, (u32)isr16, 0x08, 0x8E);
    IDT_SET_GATE(17, (u32)isr17, 0x08, 0x8E);
    IDT_SET_GATE(18, (u32)isr18, 0x08, 0x8E);
    IDT_SET_GATE(19, (u32)isr19, 0x08, 0x8E);
    IDT_SET_GATE(20, (u32)isr20, 0x08, 0x8E);
    IDT_SET_GATE(21, (u32)isr21, 0x08, 0x8E);
    IDT_SET_GATE(22, (u32)isr22, 0x08, 0x8E);
    IDT_SET_GATE(23, (u32)isr23, 0x08, 0x8E);
    IDT_SET_GATE(24, (u32)isr24, 0x08, 0x8E);
    IDT_SET_GATE(25, (u32)isr25, 0x08, 0x8E);
    IDT_SET_GATE(26, (u32)isr26, 0x08, 0x8E);
    IDT_SET_GATE(27, (u32)isr27, 0x08, 0x8E);
    IDT_SET_GATE(28, (u32)isr28, 0x08, 0x8E);
    IDT_SET_GATE(29, (u32)isr29, 0x08, 0x8E);
    IDT_SET_GATE(30, (u32)isr30, 0x08, 0x8E);
    IDT_SET_GATE(31, (u32)isr31, 0x08, 0x8E);

    IDT_FLUSH((u32)&IDT_REG);

}


void IDT_SET_GATE(int Num, u32 Base, u16 Sel, u8 Flags){
    IDT[Num].low_offset = Base & 0xFFFF;
    IDT[Num].high_offset = (Base >> 16) & 0xFFFF;
    IDT[Num].sel = Sel;
    IDT[Num].always0 = 0; /* Woooooooow */
    IDT[Num].flags = Flags;
}
IDT.asm

Code: Select all

; Asm file for the code in idt.c

global IDT_FLUSH

IDT_FLUSH:
    mov eax, [esp+4]
    lidt [eax]
    ret
IDT.h

Code: Select all

#ifndef IDT_H
#define IDT_H 1

#define IDT_ENTRIES 256

#include "../common.h"

typedef struct{
    u16 low_offset;
    u16 sel;
    u8 always0;
    u8 flags;
    u16 high_offset;
} __attribute__((packed)) idt_gate_t;

typedef struct {
    u16 limit;
    u32 base;
} __attribute__((packed)) idt_registers_t;

idt_gate_t IDT[IDT_ENTRIES];
idt_registers_t IDT_REG;


/* Functions */
void IDT_SET_GATE(int Num, u32 Base, u16 Sel, u8 Flags);
void IDT_INSTALL(void);
extern void IDT_FLUSH(u32 IDT_PTR); /* Look in the idt.asm file */
#endif
IRQ.c

Code: Select all

void IRQ_HANDLER(registers_t R){
    /* After every interrupt we need to send an EOI to the PICs
     * or they will not send another interrupt again */
    if (R.int_no >= 40) { PORT_BYTE_OUT(0xA0, 0x20); } /* Slave */

    PORT_BYTE_OUT(0x20, 0x20); /* Master */

    if (InterruptHandler[R.int_no] != 0){
        isr_t Handler = InterruptHandler[R.int_no];
        Handler(R);
    }
}

void IRQ_INSTALL(void){
    /* Enable interruptions */
    asm volatile("sti");
    /* You can now init the keyboard */
    TIME_INIT(50);
    KEYBOARD_INIT(); /* Start the keyboard */
}
IRQ.asm

Code: Select all

; This file is used in irq.c
; Which should be located in the same directory as this .asm file
; The contents of this file is taking from my older version of Misha
; -> https://github.com/WeeLonelySoul/Misha/blob/master/Misha_phase1/stanlib/interrupt/interrupt.asm
; And will remain pretty much the smae

[extern IRQ_HANDLER]


; This function works much like the IRS_COMMON_STUB found in isr.asm
IRQ_COMMON_STUB:
    pusha
    mov ax, ds
    push eax
    mov ax, 0x10
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax

    call IRQ_HANDLER

    pop ebx
    mov ds, bx
    mov es, bx
    mov fs, bx
    mov gs, bx
    popa
    add esp, 8
    sti
    iret


; First make the IRQs global
global irq0
global irq1
global irq2
global irq3
global irq4
global irq5
global irq6
global irq7
global irq8
global irq9
global irq10
global irq11
global irq12
global irq13
global irq14
global irq15




; IRQ handlers
irq0:
	cli
	push byte 0
	push byte 32
	jmp IRQ_COMMON_STUB

irq1:
	cli
	push byte 1
	push byte 33
	jmp IRQ_COMMON_STUB

irq2:
	cli
	push byte 2
	push byte 34
	jmp IRQ_COMMON_STUB

irq3:
	cli
	push byte 3
	push byte 35
	jmp IRQ_COMMON_STUB

irq4:
	cli
	push byte 4
	push byte 36
	jmp IRQ_COMMON_STUB

irq5:
	cli
	push byte 5
	push byte 37
	jmp IRQ_COMMON_STUB

irq6:
	cli
	push byte 6
	push byte 38
	jmp IRQ_COMMON_STUB

irq7:
	cli
	push byte 7
	push byte 39
	jmp IRQ_COMMON_STUB

irq8:
	cli
	push byte 8
	push byte 40
	jmp IRQ_COMMON_STUB

irq9:
	cli
	push byte 9
	push byte 41
	jmp IRQ_COMMON_STUB

irq10:
	cli
	push byte 10
	push byte 42
	jmp IRQ_COMMON_STUB

irq11:
	cli
	push byte 11
	push byte 43
	jmp IRQ_COMMON_STUB

irq12:
	cli
	push byte 12
	push byte 44
	jmp IRQ_COMMON_STUB

irq13:
	cli
	push byte 13
	push byte 45
	jmp IRQ_COMMON_STUB

irq14:
	cli
	push byte 14
	push byte 46
	jmp IRQ_COMMON_STUB

irq15:
	cli
	push byte 15
	push byte 47
	jmp IRQ_COMMON_STUB
IRQ.h

Code: Select all

#ifndef IRQ_H
#define IRQ_H 1
#include "../common.h"

/* These are defined in irq.asm */
extern void irq0();
extern void irq1();
extern void irq2();
extern void irq3();
extern void irq4();
extern void irq5();
extern void irq6();
extern void irq7();
extern void irq8();
extern void irq9();
extern void irq10();
extern void irq11();
extern void irq12();
extern void irq13();
extern void irq14();
extern void irq15();

#define IRQ0 32
#define IRQ1 33
#define IRQ2 34
#define IRQ3 35
#define IRQ4 36
#define IRQ5 37
#define IRQ6 38
#define IRQ7 39
#define IRQ8 40
#define IRQ9 41
#define IRQ10 42
#define IRQ11 43
#define IRQ12 44
#define IRQ13 45
#define IRQ14 46
#define IRQ15 47

void IRQ_INSTALL(void);
bool ARE_INTERRUPTS_ENABLED(void);
#endif
Note that both the isr code and the irq code are located in the same file

ISR.c

Code: Select all

isr_t InterruptHandler[256];

char *exception_messages[] = {
    "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"
};

void ISR_INSTALL(void){
    /* Install our ISRs 
        This code makes me wanna puke. but I'm not changing it now and dooming the future me (5/2/2018)

    */

    /* Remap */
    PORT_WORD_OUT(0x20, 0x11);
    PORT_WORD_OUT(0xA0, 0x11);
    PORT_WORD_OUT(0x21, 0x20);
    PORT_WORD_OUT(0xA1, 0x28);
    PORT_WORD_OUT(0x21, 0x04);
    PORT_WORD_OUT(0xA1, 0x02);
    PORT_WORD_OUT(0x21, 0x01);
    PORT_WORD_OUT(0xA1, 0x01);
    PORT_WORD_OUT(0x21, 0x0);
    PORT_WORD_OUT(0xA1, 0x0);

    IDT_SET_GATE(32, (u32)irq0, 0x08, 0x8E);
    IDT_SET_GATE(33, (u32)irq1, 0x08, 0x8E);
    IDT_SET_GATE(34, (u32)irq2, 0x08, 0x8E);
    IDT_SET_GATE(35, (u32)irq3, 0x08, 0x8E);
    IDT_SET_GATE(36, (u32)irq4, 0x08, 0x8E);
    IDT_SET_GATE(37, (u32)irq5, 0x08, 0x8E);
    IDT_SET_GATE(38, (u32)irq6, 0x08, 0x8E);
    IDT_SET_GATE(39, (u32)irq7, 0x08, 0x8E);
    IDT_SET_GATE(40, (u32)irq8, 0x08, 0x8E);
    IDT_SET_GATE(41, (u32)irq9, 0x08, 0x8E);
    IDT_SET_GATE(42, (u32)irq10, 0x08, 0x8E);
    IDT_SET_GATE(43, (u32)irq11, 0x08, 0x8E);
    IDT_SET_GATE(44, (u32)irq12, 0x08, 0x8E);
    IDT_SET_GATE(45, (u32)irq13, 0x08, 0x8E);
    IDT_SET_GATE(46, (u32)irq14, 0x08, 0x8E);
    IDT_SET_GATE(47, (u32)irq15, 0x08, 0x8E);

    IDT_FLUSH((u32)&IDT_REG);
}

void ISR_HANDLER(registers_t R){
    printf("\n\nError Received interrupt: ");
    char s[3];
    INT_TO_ASCII(R.int_no, s);
    printf(s);
    printf("\n");
    printf(exception_messages[R.int_no]);
    printf("\n");
}

void ISR_REGISTER_INTERRUPT_HANDLER(u8 N, isr_t Handler){
    InterruptHandler[N] = Handler;
}
ISR.asm

Code: Select all

; This file is used in isr.c
; Which should be located in the same directory as this .asm file
; The contents of this file is taking from my older version of Misha
; -> https://github.com/WeeLonelySoul/Misha/blob/master/Misha_phase1/stanlib/interrupt/interrupt.asm
; And will remain pretty much the smae


[extern ISR_HANDLER] ; Extern function



ISR_COMMON_STUB:
    ; Save our current CPU state
    pusha ; Pushes edi, esi, ebp, esp, ebx, edx, ecx, eax
    mov ax, ds
    push eax
    mov ax, 0x10
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax

    call ISR_HANDLER ; Call the C function, again defined in the isr.c file

    ; Restore the CPU state
    pop eax
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    popa
    add esp, 8 ; Cleans up the pushed error code/ISR number
    sti
    iret

; First make the ISRs global
global isr0
global isr1
global isr2
global isr3
global isr4
global isr5
global isr6
global isr7
global isr8
global isr9
global isr10
global isr11
global isr12
global isr13
global isr14
global isr15
global isr16
global isr17
global isr18
global isr19
global isr20
global isr21
global isr22
global isr23
global isr24
global isr25
global isr26
global isr27
global isr28
global isr29
global isr30
global isr31


; 0: Divide By Zero Exception
isr0:
    cli
    push byte 0
    push byte 0
    jmp ISR_COMMON_STUB

; 1: Debug Exception
isr1:
    cli
    push byte 0
    push byte 1
    jmp ISR_COMMON_STUB

; 2: Non Maskable Interrupt Exception
isr2:
    cli
    push byte 0
    push byte 2
    jmp ISR_COMMON_STUB

; 3: Int 3 Exception
isr3:
    cli
    push byte 0
    push byte 3
    jmp ISR_COMMON_STUB

; 4: INTO Exception
isr4:
    cli
    push byte 0
    push byte 4
    jmp ISR_COMMON_STUB

; 5: Out of Bounds Exception
isr5:
    cli
    push byte 0
    push byte 5
    jmp ISR_COMMON_STUB

; 6: Invalid Opcode Exception
isr6:
    cli
    push byte 0
    push byte 6
    jmp ISR_COMMON_STUB

; 7: Coprocessor Not Available Exception
isr7:
    cli
    push byte 0
    push byte 7
    jmp ISR_COMMON_STUB

; 8: Double Fault Exception (With Error Code!)
isr8:
    cli
    push byte 8
    jmp ISR_COMMON_STUB

; 9: Coprocessor Segment Overrun Exception
isr9:
    cli
    push byte 0
    push byte 9
    jmp ISR_COMMON_STUB

; 10: Bad TSS Exception (With Error Code!)
isr10:
    cli
    push byte 10
    jmp ISR_COMMON_STUB

; 11: Segment Not Present Exception (With Error Code!)
isr11:
    cli
    push byte 11
    jmp ISR_COMMON_STUB

; 12: Stack Fault Exception (With Error Code!)
isr12:
    cli
    push byte 12
    jmp ISR_COMMON_STUB

; 13: General Protection Fault Exception (With Error Code!)
isr13:
    cli
    push byte 13
    jmp ISR_COMMON_STUB

; 14: Page Fault Exception (With Error Code!)
isr14:
    cli
    push byte 14
    jmp ISR_COMMON_STUB

; 15: Reserved Exception
isr15:
    cli
    push byte 0
    push byte 15
    jmp ISR_COMMON_STUB

; 16: Floating Point Exception
isr16:
    cli
    push byte 0
    push byte 16
    jmp ISR_COMMON_STUB

; 17: Alignment Check Exception
isr17:
    cli
    push byte 0
    push byte 17
    jmp ISR_COMMON_STUB

; 18: Machine Check Exception
isr18:
    cli
    push byte 0
    push byte 18
    jmp ISR_COMMON_STUB

; 19: Reserved
isr19:
    cli
    push byte 0
    push byte 19
    jmp ISR_COMMON_STUB

; 20: Reserved
isr20:
    cli
    push byte 0
    push byte 20
    jmp ISR_COMMON_STUB

; 21: Reserved
isr21:
    cli
    push byte 0
    push byte 21
    jmp ISR_COMMON_STUB

; 22: Reserved
isr22:
    cli
    push byte 0
    push byte 22
    jmp ISR_COMMON_STUB

; 23: Reserved
isr23:
    cli
    push byte 0
    push byte 23
    jmp ISR_COMMON_STUB

; 24: Reserved
isr24:
    cli
    push byte 0
    push byte 24
    jmp ISR_COMMON_STUB

; 25: Reserved
isr25:
    cli
    push byte 0
    push byte 25
    jmp ISR_COMMON_STUB

; 26: Reserved
isr26:
    cli
    push byte 0
    push byte 26
    jmp ISR_COMMON_STUB

; 27: Reserved
isr27:
    cli
    push byte 0
    push byte 27
    jmp ISR_COMMON_STUB

; 28: Reserved
isr28:
    cli
    push byte 0
    push byte 28
    jmp ISR_COMMON_STUB

; 29: Reserved
isr29:
    cli
    push byte 0
    push byte 29
    jmp ISR_COMMON_STUB

; 30: Reserved
isr30:
    cli
    push byte 0
    push byte 30
    jmp ISR_COMMON_STUB

; 31: Reserved
isr31:
    cli
    push byte 0
    push byte 31
    jmp ISR_COMMON_STUB
ISR.h

Code: Select all

#ifndef ISR_H
#define ISR_H 1

#include "../common.h"

/* These are defined in isr.asm */
extern void isr0();
extern void isr1();
extern void isr2();
extern void isr3();
extern void isr4();
extern void isr5();
extern void isr6();
extern void isr7();
extern void isr8();
extern void isr9();
extern void isr10();
extern void isr11();
extern void isr12();
extern void isr13();
extern void isr14();
extern void isr15();
extern void isr16();
extern void isr17();
extern void isr18();
extern void isr19();
extern void isr20();
extern void isr21();
extern void isr22();
extern void isr23();
extern void isr24();
extern void isr25();
extern void isr26();
extern void isr27();
extern void isr28();
extern void isr29();
extern void isr30();
extern void isr31();

typedef struct {
   u32 ds; /* Data segment selector */
   u32 edi, esi, ebp, esp, ebx, edx, ecx, eax; /* Pushed by pusha. */
   u32 int_no, err_code; /* Interrupt number and error code (if applicable) */
   u32 eip, cs, eflags, useresp, ss; /* Pushed by the processor automatically */
} registers_t;

typedef void (*isr_t)(registers_t);



void ISR_INSTALL(void);
void ISR_HANDLER(registers_t R);
void ISR_REGISTER_INTERRUPT_HANDLER(u8 N, isr_t Handler);

#endif
Keyboard.c

Code: Select all

#include "../../libraries/bikka/isr.h"
#include "../../libraries/bikka/irq.h"
#include "../../libraries/bikka/keyboard.h"
#include "../../libraries/bikka/video.h"
#include "../../libraries/bikka/low_level.h"
#include "../../libraries/shell.h"
#include "../../libraries/common.h"

char KeyBuffer[256]; /* Buffer for the keyboard */


const char *ServiceCodeName[] = {
    "Error",
    "Esc",
    "1",
    "2",
    "3",
    "4",
    "5",
    "6",
    "7",
    "8",
    "9",
    "0",
    "-",
    "=",
    "Backspace",
    "Tab",
    "Q",
    "W",
    "E",
    "R",
    "T",
    "Y",
    "U",
    "I",
    "O",
    "P",
    "[",
    "]",
    "Enter",
    "Lctrl",
    "A",
    "S",
    "D",
    "F",
    "G",
    "H",
    "J",
    "K",
    "L",
    ";",
    "'",
    "`",
    "LShift",
    "\\",
    "Z",
    "X",
    "C",
    "V",
    "B",
    "N",
    "M",
    ",",
    ".",
    "/",
    "RShift",
    "Keypad *",
    "LAlt",
    "Spacebar"
};

/* Keyboard layout */
const char ServiceCodeAscii[] = { '?', '?', '1', '2', '3', '4', '5', '6',     
    '7', '8', '9', '0', '-', '=', '?', '?', 'Q', 'W', 'E', 'R', 'T', 'Y', 
        'U', 'I', 'O', 'P', '[', ']', '?', '?', 'A', 'S', 'D', 'F', 'G', 
        'H', 'J', 'K', 'L', ';', '\'', '`', '?', '\\', 'Z', 'X', 'C', 'V', 
        'B', 'N', 'M', ',', '.', '/', '?', '?', '?', ' '};


void KEYBOARD_CALLBACK(registers_t Regs){
    do{
        u8 ScanCode = PORT_BYTE_IN(0x60); /* Get the keyboard input */

        if (ScanCode > ServiceCodeMax){ printf("Error Scancode > ServiceCodeMax!"); return; }

        if (ScanCode == BACKSPACE){ BACKSPACE_(KeyBuffer); TERMINAL_BACKSPACE(); }

        else if (ScanCode == ENTER){
            printf("\n");
            INPUT(KeyBuffer);
            KeyBuffer[0] = '\0';

        }else{
            char Letter = ServiceCodeAscii[(int)ScanCode];
            char Str[2] = {Letter, '\0'};
            APPEND(KeyBuffer, Letter);
            printf(Str);
        }
        //UNUSED(Regs);
    }while(1);

}

void KEYBOARD_INIT(void){
    ISR_REGISTER_INTERRUPT_HANDLER(IRQ1, &KEYBOARD_CALLBACK);
}
port_byte_in_or_out.c

Code: Select all

#include "../../libraries/bikka/low_level.h"




unsigned char PORT_BYTE_IN(unsigned short Port){
    /* Recieve byte */
    unsigned char Result;
    __asm__("inb %%dx , %%al" : "=a" (Result) : "d" (Port));
    return Result;
}

void PORT_BYTE_OUT(unsigned short Port, unsigned char Data){
    /* Send byte */
    asm("outb %%al , %%dx" : :"a" (Data), "d" (Port));
}
bikka.c

Code: Select all

#include "../libraries/bikka/bikka.h"
#include "../libraries/bikka/video.h"
#include "../libraries/bikka/gdt.h"
#include "../libraries/bikka/isr.h"
#include "../libraries/bikka/irq.h"
#include "../libraries/bikka/printsyssetup.h"
#include "../libraries/bikka/time.h"
#include "../libraries/bikka/memory.h"
#include "../libraries/bikka/authority.h"

/*

Bikka main entry

*/

/* Tab space of doom, atleast make this into a function in the future */
const string Logo ="\n"
"\t\t                              $$\\                 \n" \
"\t\t   $$$\\    $$$ |$$|           $$ |                \n" \
"\t\t   $$$$\\  $$$$ |$$\\  $$$$$$$\\ $$$$$$$\\   $$$$$$\\  \n"\
"\t\t   $$\\$$\\$$ $$ |$$ |$$  _____|$$  __$$\\  \\____$$\\ \n"\
"\t\t   $$ \\$$$  $$ |$$ |\\$$$$$$\\  $$ |  $$ | $$$$$$$ |\n" \
"\t\t   $$ |\\$  /$$ |$$ | \\____$$\\ $$ |  $$ |$$  __$$ |\n" \
"\t\t   $$ | \\_/ $$ |$$ |$$$$$$$  |$$ |  $$ |\\$$$$$$$ |\n"\
"\t\t   \\__|     \\__|\\__|\\_______/ \\__|  \\__| \\_______|\n";

void BIKKA_MAIN(void){
    /* Core functions for pretty much every operating systems */
    TERMINAL_INSTALL(); /* Install the terminal */

    GDT_INSTALL(); /* Global Descriptor Table */
    ISR_INSTALL(); /* Interrupt handler */
    IDT_INSTALL();
    IRQ_INSTALL(); /* Interrupt request */


    /* Less but still important functions */
    MEMORY_PAGING_INSTALL(); /* Install paging */
    // MEMORY_INSTALL(); /* Install the memory management */
    // AUTHORITY_INSTALL(); /* Install the Authority */
    // FILESYSTEM_FIND_DISK(); /* Find the disks */
    // FILESYSTEM_SETUP_DISK(); /* Make sure the disc are set and ready for use */
    // FILESYSTEM_SETUP_PATH(); /* Set the path for our shell */
    /* Setup is done, init Misha */
    GeoPrint("Kernel-Mode", 68, 0); /* Shows that the user is currently in kernel-land */
    //GeoPrint(Logo , 20, 1); /* New print function */
    //GeoPrint("Kernel output", 2, 14);
    //SYS_SETUP_PRINT(); /* Print out the details regarding the system */


    // SYS_CPU_STAT(); /* Printo out cpu information */
    // _Sleep(30); /* Sleep for 30 secs */
    // START_MISHA(); /* Enter usermode and start Misha */
    INPUT();
    for(;;){}
}
time.c

Code: Select all

u32 tick = 0;

static void TIMER_CALLBACK(registers_t Regs){
    tick++;
    UNUSED(Regs);
}


void TIME_INIT(u32 Freq){
    ISR_REGISTER_INTERRUPT_HANDLER(IRQ0, &TIMER_CALLBACK);

    u32 Divisor = 1193180 / Freq;
    u8 Low = (u8)(Divisor & 0xFF);
    u8 High = (u8)((Divisor>>8)& 0xFF);

    PORT_BYTE_OUT(0x43, 0x36);
    PORT_BYTE_OUT(0x40, Low);
    PORT_BYTE_OUT(0x40, High);
}
The keyboard is suppose to be working at this point and the func "INPUT()" is supposed to take the user input and compare it to a selected amount of builtin commands.
But before the INPUT func is called an "interrupt 0 divide by zero" is sent, and I've boiled it down to the irq install func

Code: Select all

/* Enable interruptions */
    asm volatile("sti");
    /* You can now init the keyboard */
    TIME_INIT(50);
    KEYBOARD_INIT(); /* Start the keyboard */
Removing either "asm volatile("sti");" or "TIME_INIT(50)", "solves" the issue as in the error message goes away but the keyboard input still isn't working.

So is there anyone who could help me solve this issue?
Attachments
This is how it looks when you run it
This is how it looks when you run it
Screenshot from 2018-02-13 08-29-37.png (6.85 KiB) Viewed 11720 times
User avatar
igorov70
Posts: 11
Joined: Sun Mar 25, 2018 10:35 am
Libera.chat IRC: i dont have
Location: Exchange student in Moscow

Re: Can't get keyboard input working

Post by igorov70 »

Temporal: simple read PS/2 port and no do interrupt. You test other interrupts to get them work. Until, you can simple read port.
Post Reply