Interrupts
Posted: Wed Aug 14, 2013 7:56 pm
So far I haven't had much luck with this at all. I don't know if any of what I have is working because none of it works until it all works, so I don't know where the problem is. Here is the various relavant pieces of code.
idt.h
now I have two keyboard codes (i've tried both). one uses else if statements and the other doesn't have the right scan codes for my computer. I think the problem might be here, becauese I don't know how the keyboard sends an interrupt. anyway, here's one
and
and here is the main function
the big block that's commented out only works with one keyboard function. the pic is commented out because of a line that I think disables interrupts.
here is the pics code
I hope someone can help,
thanks,
johnyburd
idt.h
Code: Select all
#ifndef __IDT_H
#define __IDT_H
#define IDT_TASK_32 0x5
#define IDT_INT_16 0x6
#define IDT_TRAP_16 0x7
#define IDT_INT_32 0xE
#define IDT_TRAP_32 0xF
#define IDT_SEG_STORAGE 0x10
#define IDT_DPL0 0x0
#define IDT_DPL1 0x20
#define IDT_DPL2 0x40
#define IDT_DPL3 0x60
#define IDT_PRESENT 0x80
struct IDTDescr{
uint16_t offset_1; // offset bits 0..15
uint16_t selector; // a code segment selector in GDT or LDT
uint8_t zero; // unused, set to 0
uint8_t type_attr; // type and attributes, see below
uint16_t offset_2; // offset bits 16..31
};
struct IDTDescr IDT[48];
void setIdt(void *ptr, uint16_t size);
#endif
Code: Select all
#include "gdt.h"
gdt_descriptor create_descriptor(uint32_t base, uint32_t limit, uint16_t flag)
{
gdt_descriptor descriptor;
// Create the high 32 bit segment
descriptor = limit & 0x000F0000; // set limit bits 19:16
descriptor |= (flag << 8) & 0x00F0FF00; // set type, p, dpl, s, g, d/b, l and avl fields
descriptor |= (base >> 16) & 0x000000FF; // set base bits 23:16
descriptor |= base & 0xFF000000; // set base bits 31:24
// Shift by 32 to allow for low part of segment
descriptor <<= 32;
// Create the low 32 bit segment
descriptor |= base << 16; // set base bits 15:0
descriptor |= limit & 0x0000FFFF; // set limit bits 15:0
return descriptor;
}
Code: Select all
#include "io.h"
#include "string.h"
int ccol;
int led_stat=0;
int crow;
char keysq[100];
int scan(){
char oldkey;
char key;
for (;;){
oldkey=key;
key=inportb(0x60);
if(!(oldkey==key)){
return key;
}
}
}
void klights(){
if (led_stat == 0){
outportb(0x60, 0xED);
while(inportb(0x64) & 2);
outportb(0x60, 4);
while(inportb(0x64) & 2);
led_stat++;
}
else if (led_stat == 1){
outportb(0x60, 0xED);
while(inportb(0x64) & 2);
outportb(0x60, 0);
while(inportb(0x64) & 2);
led_stat=0;
}
}
char * keyboard(){
for(int i=0;i<100;i++)
keysq[i] = 0;
int kcount = 0;
int code = 0;
scan(); //so it doesn't think its enter
outportb(0x60, 0xF4);
while (1){
code = scan();
if (code == 0x01){
print("esc");
kcount+=3;
}
else if (code == 0x02){
print("1");
keysq[kcount]='1';
kcount++;
}
else if (code == 0x03){
print("2");
keysq[kcount]='2';
kcount++;
}
else if (code == 0x04){
print("3");
keysq[kcount]='3';
kcount++;
}
else if (code == 0x05){
print("4");
keysq[kcount]='4';
kcount++;
}
else if (code == 0x06){
print("5");
keysq[kcount]='5';
kcount++;
}
else if (code == 0x07){
print("6");
keysq[kcount]='6';
kcount++;
}
else if (code == 0x08){
print("7");
keysq[kcount]='7';
kcount++;
}
else if (code == 0x09){
print("8");
keysq[kcount]='8';
kcount++;
}
else if (code == 0x0A){
print("9");
keysq[kcount]='9';
kcount++;
}
else if (code == 0x0B){
print("0");
keysq[kcount]='0';
kcount++;
}
else if (code == 0x0C){
print("-");
keysq[kcount]='-';
kcount++;
}
else if (code == 0x0D){
print("=");
keysq[kcount]='=';
kcount++;
}
else if (code == 0x0E){
if (kcount > 0){
ccol-=2;
cursor-=2;
print(" ");
cursor-=2;// BKSP
kcount--;
keysq[kcount]=0;
}
}
else if (code == 0x0F){
print(" ");
}
else if (code == 0x10){
print("q");
keysq[kcount]='q';
kcount++;
}
else if (code == 0x11){
print("w");
keysq[kcount]='w';
kcount++;
}
else if (code == 0x12){
print("e");
keysq[kcount]='e';
kcount++;
}
else if (code == 0x13){
print("r");
keysq[kcount]='r';
kcount++;
}
else if (code == 0x14){
print("t");
keysq[kcount]='t';
kcount++;
}
else if (code == 0x15){
print("y");
keysq[kcount]='y';
kcount++;
}
else if (code == 0x16){
print("u");
keysq[kcount]='u';
kcount++;
}
else if (code == 0x17){
print("i");
keysq[kcount]='i';
kcount++;
}
else if (code == 0x18){
print("o");
keysq[kcount]='o';
kcount++;
}
else if (code == 0x19){
print("p");
keysq[kcount]='p';
kcount++;
}
else if (code == 0x1A){
print("[");
keysq[kcount]='[';
kcount++;
}
else if (code == 0x1B){
print("]");
keysq[kcount]=']';
kcount++;
}
else if (code == 0x1C){
// ENTER
code = 0;
print("\n");
break;
}
else if (code == 0x1D){
print("lctrl");
kcount+=5;
}
else if (code == 0x1E){
print("a");
keysq[kcount]='a';
kcount++;
}
else if (code == 0x1F){
print("s");
keysq[kcount]='s';
kcount++;
}
else if (code == 0x20){
print("d");
keysq[kcount]='d';
kcount++;
}
else if (code == 0x21){
print("f");
keysq[kcount]='f';
kcount++;
}
else if (code == 0x22){
print("g");
keysq[kcount]='g';
kcount++;
}
else if (code == 0x23){
print("h");
keysq[kcount]='h';
kcount++;
}
else if (code == 0x24){
print("j");
keysq[kcount]='j';
kcount++;
}
else if (code == 0x25){
print("k");
keysq[kcount]='[';
kcount++;
}
else if (code == 0x26){
print("l");
keysq[kcount]='l';
kcount++;
}
else if (code == 0x27){
print(";");
keysq[kcount]=';';
kcount++;
}
else if (code == 0x28){
print("'");
keysq[kcount]='\'';
kcount++;
}
else if (code == 0x29){
print("`");
keysq[kcount]='`';
kcount++;
}
else if (code == 0x2A){
print("lshift");
kcount+=6;
}
else if (code == 0x2B){
print("\\");
kcount++;
}
else if (code == 0x2C){
print("z");
keysq[kcount]='z';
kcount++;
}
else if (code == 0x2D){
print("x");
keysq[kcount]='x';
kcount++;
}
else if (code == 0x2E){
print("c");
keysq[kcount]='c';
kcount++;
}
else if (code == 0x2F){
print("v");
keysq[kcount]='v';
kcount++;
}
else if (code == 0x30){
print("b");
keysq[kcount]='b';
kcount++;
}
else if (code == 0x31){
print("n");
keysq[kcount]='n';
kcount++;
}
else if (code == 0x32){
print("m");
keysq[kcount]='m';
kcount++;
}
else if (code == 0x33){
print(",");
keysq[kcount]=',';
kcount++;
}
else if (code == 0x34){
print(".");
keysq[kcount]='.';
kcount++;
}
else if (code == 0x35){
print("/");
keysq[kcount]='/';
kcount++;
}
else if (code == 0x36){
print("rshift");
kcount+=6;
}
else if (code == 0x38){
print("lalt");
kcount+=4;
}
else if (code == 0x39){
print(" ");
kcount++;
}
else if (code == 0x3A){
klights();
}
}
return keysq;
}
Code: Select all
#include "string.h"
#include "io.h"
#include "kb.h"
/* KBDUS means US Keyboard Layout. This is a scancode table
* used to layout a standard US keyboard. I have left some
* comments in to give you an idea of what key is what, even
* though I set it's array index to 0. You can change that to
* whatever you want using a macro, if you wish! */
unsigned char kbdus[128] =
{
0, 27, '1', '2', '3', '4', '5', '6', '7', '8', /* 9 */
'9', '0', '-', '=', '\b', /* Backspace */
'\t', /* Tab */
'q', 'w', 'e', 'r', /* 19 */
't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', /* Enter key */
0, /* 29 - Control */
'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* 39 */
'\'', '`', 0, /* Left shift */
'\\', 'z', 'x', 'c', 'v', 'b', 'n', /* 49 */
'm', ',', '.', '/', 0, /* Right shift */
'*',
0, /* Alt */
' ', /* Space bar */
0, /* Caps lock */
0, /* 59 - F1 key ... > */
0, 0, 0, 0, 0, 0, 0, 0,
0, /* < ... F10 */
0, /* 69 - Num lock*/
0, /* Scroll Lock */
0, /* Home key */
0, /* Up Arrow */
0, /* Page Up */
'-',
0, /* Left Arrow */
0,
0, /* Right Arrow */
'+',
0, /* 79 - End key*/
0, /* Down Arrow */
0, /* Page Down */
0, /* Insert Key */
0, /* Delete Key */
0, 0, 0,
0, /* F11 Key */
0, /* F12 Key */
0, /* All other keys are undefined */
};
/* Handles the keyboard interrupt */
void keyboard_handler()
//struct regs *r
{
unsigned char scancode;
/* Read from the keyboard's data buffer */
scancode = inportb(0x60);
/* If the top bit of the byte we read from the keyboard is
* set, that means that a key has just been released */
if (scancode & 0x80)
{
/* You can use this one to see if the user released the
* shift, alt, or control keys... */
}
else
{
/* Here, a key was just pressed. Please note that if you
* hold a key down, you will get repeated key press
* interrupts. */
/* Just to show you how this works, we simply translate
* the keyboard scancode into an ASCII value, and then
* display it to the screen. You can get creative and
* use some flags to see if a shift is pressed and use a
* different layout, or you can add another 128 entries
* to the above layout to correspond to 'shift' being
* held. If shift is held using the larger lookup table,
* you would add 128 to the scancode when you look for it */
char hi[2];
char oldkey;
char key;
for (;;){
oldkey=key;
key=inportb(0x60);
if(!(oldkey==key)){
hi[0] = kbdus[scancode];
print(hi);
}
}
}
}
Code: Select all
#include <stdint.h>
#include <string.h>
#include "pic.h"
#include "io.h"
//#include "keyboard.h"
#include "string.h"
#include "gdt.h"
#include "idt.h"
#include "kb.h"
void init_gdt(void);
void init_idt(void);
void exit(void);
void _interrupt_handler(void);
void kmain(void)
{
extern uint32_t magic;
if ( magic != 0x2BADB002 )
{
print("Something went not according to specs.");
exit();
}
kclear();
print("initializing GDT...\n");
init_gdt();
print("initializing IDT...\n");
init_idt();
print("initializing keyboard...\n");
outportb(0x60, 0xF4);
//print("initializing PICs...\n");
//init_pics(0x20, 0x28);
cprint("Jonathan's OS\n", 2);
update_cursor();
while (1)
keyboard_handler(); //this should call one of the keyboard functions
/*while(1){
char * input = keyboard();
if (strcheck(input, "help") == 1){
print("supported commands:\nhelp - displays this message.\nclear - clears the screen.\nreboot - might make it restart.\n");
}
else if (strcheck(input, "clear") ==1)
{
kclear();
}
else if (strcheck(input, "reboot") == 1)
{
exit();
print("this needs to be fixed. BAD.");
}
else{
print("don't know that one\n");
}
}*/
}
void exit(void){
while(inportb(0x64) & 0x02);
outportb(0x64, 0xFE);
}
void init_gdt(void) {
/*GDT[0] = ((sizeof(gdt_descriptor) * GDT_ENTRIES - 1) & 0xFFFF)
| ((uint32_t)GDT) << 16;*/
GDT[1] = create_descriptor(0, 0xFFFFF, GDT_CODE_PL0);
GDT[2] = create_descriptor(0, 0xFFFFF, GDT_DATA_PL0);
setGdt(GDT, sizeof(GDT));
}
void init_idt(void) {
for (unsigned int i = 0; i < sizeof(IDT); i++) {
*(((char *)IDT)+i) = 0;
}
IDT[1].offset_1 = ((uint32_t)(&_interrupt_handler)) & 0xFFFF;
IDT[1].offset_2 = ((uint32_t)(&_interrupt_handler)) >> 16;
IDT[1].selector = 0x08;
IDT[1].type_attr = IDT_DPL0 | IDT_INT_32 | IDT_PRESENT;
setIdt(IDT, sizeof(IDT));
}
void _interrupt_handler(void) {
print("interrupt");
}
here is the pics code
Code: Select all
#include "pic.h"
#include "io.h"
void init_pics(int pic1, int pic2)
{
/* send ICW1 */
outportb(PIC1, ICW1);
outportb(PIC2, ICW1);
/* send ICW2 */
outportb(PIC1 + 1, pic1); /* remap */
outportb(PIC2 + 1, pic2); /* pics */
/* send ICW3 */
outportb(PIC1 + 1, 4); /* IRQ2 -> connection to slave */
outportb(PIC2 + 1, 2);
/* send ICW4 */
outportb(PIC1 + 1, ICW4);
outportb(PIC2 + 1, ICW4);
/* disable all IRQs */
outportb(PIC1 + 1, 0xFF);
}
I hope someone can help,
thanks,
johnyburd