My code is provided down below:
Code: Select all
asm("jmp kmain");
#define VIDEO_BUF_PTR (0xb8000)
#define IDT_TYPE_INTR (0x0E)
#define IDT_TYPE_TRAP (0x0F)
#define GDT_CS (0x8)
#define PIC1_PORT (0x20)
#define CURSOR_PORT (0x3D4)
#define VIDEO_WIDTH (80)
unsigned char keyboard[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 */
1, /* Caps lock */
0, /* 59 - F1 key ... > */
0, 0, 0, 0, 0, 0, 0, 0,
0, /* < ... F10 */ /*68*/
0, /* 69 - Num lock*/
0, /* Scroll Lock */
'7', '8', '9', '-', '4', '5', '6', '+', /*78*/
'1', /* 79 - End key*/
'2', /* Down Arrow */
'3', /* Page Down */
'0', /* Insert Key */
0, /* Delete Key */
0, 0, 0,
0, /* F11 Key */
0, /* F12 Key */
0, /* All other keys are undefined */
};
struct idt_entry
{
unsigned short base_lo;
unsigned short segm_sel;
unsigned char always0;
unsigned char flags;
unsigned short base_hi;
} __attribute__((packed));
struct idt_ptr
{
unsigned short limit;
unsigned int base;
} __attribute__((packed));
struct idt_entry g_idt[256];
struct idt_ptr g_idtp;
void default_intr_handler()
{
asm("pusha");
asm("popa; leave; iret");
}
typedef void (*intr_handler)();
void intr_reg_handler(int num, unsigned short segm_sel, unsigned short flags, intr_handler hndlr)
{
unsigned int hndlr_addr = (unsigned int) hndlr;
g_idt[num].base_lo = (unsigned short) (hndlr_addr & 0xFFFF);
g_idt[num].segm_sel = segm_sel;
g_idt[num].always0 = 0;
g_idt[num].flags = flags;
g_idt[num].base_hi = (unsigned short) (hndlr_addr >> 16);
}
void intr_init()
{
int i;
int idt_count = sizeof(g_idt) / sizeof(g_idt[0]);
for(i = 0; i < idt_count; i++)
intr_reg_handler(i, GDT_CS, 0x80 | IDT_TYPE_INTR, default_intr_handler);
}
void intr_start()
{
int idt_count = sizeof(g_idt) / sizeof(g_idt[0]);
g_idtp.base = (unsigned int) (&g_idt[0]);
g_idtp.limit = (sizeof (struct idt_entry) * idt_count) - 1;
asm("lidt %0" : : "m" (g_idtp) );
}
void intr_enable()
{
asm("sti");
}
void intr_disable()
{
asm("cli");
}
static inline unsigned char inb (unsigned short port)
{
unsigned char data;
asm volatile ("inb %w1, %b0" : "=a" (data) : "Nd" (port));
return data;
}
static inline void outb (unsigned short port, unsigned char data)
{
asm volatile ("outb %b0, %w1" : : "a" (data), "Nd" (port));
}
void out_str(int color, const char* ptr, unsigned int strnum)
{
unsigned char* video_buf = (unsigned char*) VIDEO_BUF_PTR;
video_buf += 80*2 * strnum;
while (*ptr)
{
video_buf[0] = (unsigned char) *ptr; // Символ (код)
video_buf[1] = color; // Цвет символа и фона
video_buf += 2;
ptr++;
}
}
void cursor_moveto(unsigned int strnum, unsigned int pos)
{
unsigned short new_pos = (strnum * VIDEO_WIDTH) + pos;
outb(CURSOR_PORT, 0x0F);
outb(CURSOR_PORT + 1, (unsigned char)(new_pos & 0xFF));
outb(CURSOR_PORT, 0x0E);
outb(CURSOR_PORT + 1, (unsigned char)( (new_pos >> 8) & 0xFF));
}
char scan_to_char(unsigned char s)
{
if(keyboard[s] == 0) return '\t';
return (keyboard[s]);
}
int g_caret = 0;
void clear_str()
{
char* vb = (char*) VIDEO_BUF_PTR;
int i;
for (i = 0; i<80; i++)
{
vb[i*2]=' ';
vb[i*2+1] = 0x0A;
}
cursor_moveto(0,0);
}
char onscreenchar(const unsigned char ch)
{
return keyboard[ch];
}
void on_key(unsigned char scan_code)
{
unsigned char c;
c = scan_to_char(scan_code);
char* vb = (char*) VIDEO_BUF_PTR;
if (c != '\t'){
vb[g_caret*2] = c;
vb[g_caret*2+1] = 0x07;
//g_caret = g_caret + 2;
g_caret++;
cursor_moveto(0, g_caret);
}
}
void keyb_process_keys()
{
if (inb(0x64) & 0x01)
{
unsigned char scan_code;
unsigned char state;
scan_code = inb(0x60);
if (scan_code < 128);
on_key(scan_code);
}
}
void keyb_handler()
{
asm("pusha");
keyb_process_keys();
outb(PIC1_PORT, 0x20);
asm("popa; leave; iret");
}
void keyb_init()
{
intr_reg_handler(0x09, GDT_CS, 0x80 | IDT_TYPE_INTR, keyb_handler);
outb(PIC1_PORT + 1, 0xFF ^ 0x02);
}
void videomode()
{
asm("movb $0x00, %ah");
asm("movb $0x03, %al");
asm("int $0x10");
asm("ret");
}
void shutdown()
{
asm("movw $0x0604, %dx");
asm("movw $0x2000, %ax");
asm("outw %ax, %dx");
}
int gcd(int a, int b){
return b == 0 ? a : gcd(b, a % b);
}
int solve(int a, int b, int c){
return 0;
}
int lcm(int a, int b){
int max;
max = (a > b) ? a : b;
do
{
if (max % a == 0 && max % b == 0)
{
char maxch = (char)max;
out_str(0x02, &maxch, 24); //Must be changed!
//cout << "LCM = " << max;
break;
}
else
++max;
} while (true);
return 0;
}
const char* second_str = "Compilers: bootloader: gas, kernel: gcc";
const char* third_str = "entered color";
const char* gcd_str = "gcd";
const char* solve_str = "solve";
const char* lcm_str = "lcm";
const char* shutdown_str = "shutdown";
const char* info_str = "info";
extern "C" int kmain()
{
const char* hello = "Welcome to SolverOS!";
out_str(0x01, hello, 20);
out_str(0x03, second_str, 22);
out_str(0x04, third_str, 23);
intr_init();
keyb_init();
intr_start();
intr_enable();
//intr_disable();
while(1)
{
asm("hlt");
}
return 0;
}