void tty_setcursor(int x, int y) { int offset = tty_getoffset(x, y); port_byte_out(REG_SCREEN_CTRL, 14); port_byte_out(REG_SCREEN_DATA, (uint8_t)(offset >> 8)); port_byte_out(REG_SCREEN_CTRL, 15); port_byte_out(REG_SCREEN_DATA, (uint8_t)(offset & 0xFF)); }
int tty_getcursor() { port_byte_out(REG_SCREEN_CTRL, 14); int offset = port_byte_in(REG_SCREEN_DATA) << 8; port_byte_out(REG_SCREEN_CTRL, 15); offset += port_byte_in(REG_SCREEN_DATA); return offset; }
void set_cursor_offset(int offset) { /* Similar to get_cursor_offset, but instead of reading we write data */ offset /= 2; port_byte_out(REG_SCREEN_CTRL, 14); port_byte_out(REG_SCREEN_DATA, (unsigned char)(offset >> 8)); port_byte_out(REG_SCREEN_CTRL, 15); port_byte_out(REG_SCREEN_DATA, (unsigned char)(offset & 0xff)); }
static void set_cursor(struct cursor cur) { uint16_t offset = get_offset(cur); port_byte_out(CTRL_PORT, 14); port_byte_out(DATA_PORT, (uint8_t)(offset >> 8)); port_byte_out(CTRL_PORT, 15); port_byte_out(DATA_PORT, (uint8_t)(offset)); }
int get_cursor_offset() { /* Use the VGA ports to get the current cursor position * 1. Ask for high byte of the cursor offset (data 14) * 2. Ask for low byte (data 15) */ port_byte_out(REG_SCREEN_CTRL, 14); int offset = port_byte_in(REG_SCREEN_DATA) << 8; /* High byte: << 8 */ port_byte_out(REG_SCREEN_CTRL, 15); offset += port_byte_in(REG_SCREEN_DATA); return offset * 2; /* Position * size of character cell */ }
void set_cursor(int nOffset) { nOffset /= 2; // This is similar to get cursor, only now we write // bytes to those interal device registers port_byte_out(REG_SCREEN_CTRL, 14); port_byte_out(REG_SCREEN_DATA, (unsigned char)((nOffset >> 8) & 0xff)); port_byte_out(REG_SCREEN_CTRL, 15); port_byte_out(REG_SCREEN_DATA, (unsigned char)(nOffset & 0xff)); }
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 */ /* Handle the interrupt in a more modular way */ if (interrupt_handlers[r->int_no] != 0) { isr_t handler = interrupt_handlers[r->int_no]; handler(r); } }
static struct cursor get_cursor(void) { port_byte_out(CTRL_PORT, 14); uint8_t high_byte = port_byte_in(DATA_PORT); port_byte_out(CTRL_PORT, 15); uint8_t low_byte = port_byte_in(DATA_PORT); uint16_t offset = high_byte; offset <<= 8; offset += low_byte; struct cursor cur = {(uint16_t)(offset / MAX_COLS), (uint16_t)(offset % MAX_COLS)}; return cur; }
void init_timer(u32 freq) { /* Install the function we just wrote */ register_interrupt_handler(IRQ0, timer_callback); /* Get the PIT value: hardware clock at 1193180 Hz */ u32 divisor = 1193180 / freq; u8 low = (u8)(divisor & 0xFF); u8 high = (u8)( (divisor >> 8) & 0xFF); /* Send the command */ port_byte_out(0x43, 0x36); /* Command port */ port_byte_out(0x40, low); port_byte_out(0x40, high); }
void irq_handler(registers_t regs) { void (*handler)(struct registers *r) = irq_handlers[regs.int_no]; if(handler != 0) { handler(®s); } //Did this come from the slave PIC? if (regs.int_no >= 8) { port_byte_out(SLAVE_COMMAND, PIC_EOI); } port_byte_out(MASTER_COMMAND, PIC_EOI); }
void init_interrupts(void) { init_idt(); port_byte_out(0x20, 0x11); port_byte_out(0xA0, 0x11); port_byte_out(0x21, 0x20); port_byte_out(0xA1, 0x28); port_byte_out(0x21, 0x04); port_byte_out(0xA1, 0x02); port_byte_out(0x21, 0x01); port_byte_out(0xA1, 0x01); port_byte_out(0x21, 0x0); port_byte_out(0xA1, 0x0); __asm__ __volatile__("lidt (%0)"::"r" (&idt_register)); __asm__ __volatile__("sti"); }
int get_cursor() { // The device uses its control register as an index // to select its interl registers, in which we are // interested in // reg 14: which is the high byte of cursor offset // reg 15: which is the low byte of cursor offet port_byte_out(REG_SCREEN_CTRL, 14); int nOffset = port_byte_in(REG_SCREEN_DATA) << 8; port_byte_out(REG_SCREEN_CTRL, 15); nOffset += port_byte_in(REG_SCREEN_DATA); // Since the cursor offset reported by the VGA hardware // is the number of characters, we have to multiply it // by two to convert it to a character cell offset return nOffset * 2; }
void remap_pic() { //Send ICW1 to the CMD ports port_byte_out(MASTER_COMMAND, PIC_ICW1); port_byte_out(SLAVE_COMMAND, PIC_ICW1); //Send ICW2 to the DATA ports port_byte_out(MASTER_DATA, 0x20); //IRQ0 = IDT #32 port_byte_out(SLAVE_DATA, 0x28); //IRQ8 = IDT #40 //Send ICW3 to the DATA ports port_byte_out(MASTER_DATA, PIC_ICW3m); port_byte_out(SLAVE_DATA, PIC_ICW3s); //Send ICW4 to the DATA ports port_byte_out(MASTER_DATA, PIC_ICW4m); port_byte_out(SLAVE_DATA, PIC_ICW4s); //Unmask ALL the IRQs! port_byte_out(MASTER_DATA, 0); port_byte_out(SLAVE_DATA, 0); }
/* Can't do this with a loop because we need the address * of the function names */ void isr_install() { set_idt_gate(0, (uint32_t)isr0); set_idt_gate(1, (uint32_t)isr1); set_idt_gate(2, (uint32_t)isr2); set_idt_gate(3, (uint32_t)isr3); set_idt_gate(4, (uint32_t)isr4); set_idt_gate(5, (uint32_t)isr5); set_idt_gate(6, (uint32_t)isr6); set_idt_gate(7, (uint32_t)isr7); set_idt_gate(8, (uint32_t)isr8); set_idt_gate(9, (uint32_t)isr9); set_idt_gate(10, (uint32_t)isr10); set_idt_gate(11, (uint32_t)isr11); set_idt_gate(12, (uint32_t)isr12); set_idt_gate(13, (uint32_t)isr13); set_idt_gate(14, (uint32_t)isr14); set_idt_gate(15, (uint32_t)isr15); set_idt_gate(16, (uint32_t)isr16); set_idt_gate(17, (uint32_t)isr17); set_idt_gate(18, (uint32_t)isr18); set_idt_gate(19, (uint32_t)isr19); set_idt_gate(20, (uint32_t)isr20); set_idt_gate(21, (uint32_t)isr21); set_idt_gate(22, (uint32_t)isr22); set_idt_gate(23, (uint32_t)isr23); set_idt_gate(24, (uint32_t)isr24); set_idt_gate(25, (uint32_t)isr25); set_idt_gate(26, (uint32_t)isr26); set_idt_gate(27, (uint32_t)isr27); set_idt_gate(28, (uint32_t)isr28); set_idt_gate(29, (uint32_t)isr29); set_idt_gate(30, (uint32_t)isr30); set_idt_gate(31, (uint32_t)isr31); // Remap the PIC port_byte_out(0x20, 0x11); port_byte_out(0xA0, 0x11); port_byte_out(0x21, 0x20); port_byte_out(0xA1, 0x28); port_byte_out(0x21, 0x04); port_byte_out(0xA1, 0x02); port_byte_out(0x21, 0x01); port_byte_out(0xA1, 0x01); port_byte_out(0x21, 0x0); port_byte_out(0xA1, 0x0); // Install the IRQs set_idt_gate(32, (uint32_t)irq0); set_idt_gate(33, (uint32_t)irq1); set_idt_gate(34, (uint32_t)irq2); set_idt_gate(35, (uint32_t)irq3); set_idt_gate(36, (uint32_t)irq4); set_idt_gate(37, (uint32_t)irq5); set_idt_gate(38, (uint32_t)irq6); set_idt_gate(39, (uint32_t)irq7); set_idt_gate(40, (uint32_t)irq8); set_idt_gate(41, (uint32_t)irq9); set_idt_gate(42, (uint32_t)irq10); set_idt_gate(43, (uint32_t)irq11); set_idt_gate(44, (uint32_t)irq12); set_idt_gate(45, (uint32_t)irq13); set_idt_gate(46, (uint32_t)irq14); set_idt_gate(47, (uint32_t)irq15); set_idt(); // Load with ASM }