rtc - try implementing RTC / kernel: removed rt from the codebase (released separately)
This commit is contained in:
parent
6af9752e24
commit
3461dcb1ed
6 changed files with 54 additions and 154 deletions
|
@ -1,85 +0,0 @@
|
|||
#include "rt.h"
|
||||
#include <font.h>
|
||||
#include <stdint.h>
|
||||
#include <mm/memop.h>
|
||||
|
||||
static rt_context _curctx;
|
||||
|
||||
void _rt_drawchar(unsigned char c, int x, int y, int fgcolor, int bgcolor)
|
||||
{
|
||||
int cx,cy;
|
||||
int mask[8]={128, 64, 32, 16, 8, 4, 2, 1};
|
||||
unsigned char *glyph=VGA8+(int)c*16;
|
||||
|
||||
uint32_t *buf = _curctx.framebuffer;
|
||||
|
||||
for(cy=0;cy<16;cy++){
|
||||
for(cx=0;cx<8;cx++){
|
||||
buf[((y + cy) * _curctx.framebuffer_width) + (x + cx)] = glyph[cy]&mask[cx]?fgcolor:bgcolor;
|
||||
}
|
||||
}
|
||||
}
|
||||
void _rt_draw_fillchar(int x, int y, int bgcolor, int fgcolor) {
|
||||
int cx,cy;
|
||||
uint32_t *buf = _curctx.framebuffer;
|
||||
for(cy=0;cy<16;cy++){
|
||||
for(cx=0;cx<8;cx++){
|
||||
buf[((y + cy) * _curctx.framebuffer_width) + (x + cx)] = cy > 12 ? fgcolor : bgcolor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int _rt_strlen(char *str) {
|
||||
int i = 0;
|
||||
while (str[i] != '\0') i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
void rt_init(rt_context ctx) {
|
||||
// Copy the structure
|
||||
char *src = (char*)&ctx;
|
||||
char *dst = (char*)&_curctx;
|
||||
for (unsigned long i = 0; i < sizeof(rt_context); i++) {
|
||||
dst[i] = src[i];
|
||||
}
|
||||
|
||||
// Fill fields
|
||||
_curctx.term_width = _curctx.framebuffer_width / 8;
|
||||
_curctx.term_height = _curctx.framebuffer_height / 16;
|
||||
}
|
||||
|
||||
void rt_print(char *str) {
|
||||
_rt_draw_fillchar(_curctx.x * 8, _curctx.y * 16, 0x0, 0x0);
|
||||
|
||||
for (int i = 0; i < _rt_strlen(str); i++) {
|
||||
if (str[i] == '\n' && _curctx.use_crlf_ending)
|
||||
if (_curctx.y * 16 >= (int)_curctx.framebuffer_height) {
|
||||
_curctx.y = 0;
|
||||
memset(
|
||||
_curctx.framebuffer, _curctx.bg_color,
|
||||
_curctx.framebuffer_width * _curctx.framebuffer_height * sizeof(uint32_t));
|
||||
} else {
|
||||
_curctx.y++;
|
||||
}
|
||||
else if (str[i] == '\n')
|
||||
{
|
||||
if (_curctx.y * 16 >= (int)_curctx.framebuffer_height) {
|
||||
_curctx.y = 0;
|
||||
memset(
|
||||
_curctx.framebuffer, _curctx.bg_color,
|
||||
_curctx.framebuffer_width * _curctx.framebuffer_height * sizeof(uint32_t));
|
||||
} else {
|
||||
_curctx.y++;
|
||||
}
|
||||
_curctx.x = 0;
|
||||
}
|
||||
else if (str[i] == '\r')
|
||||
_curctx.x = 0;
|
||||
else {
|
||||
_rt_drawchar(str[i], _curctx.x * 8, _curctx.y * 16, 0xFFFFFF, 0x0);
|
||||
_curctx.x++;
|
||||
}
|
||||
}
|
||||
|
||||
_rt_draw_fillchar(_curctx.x * 8, _curctx.y * 16, 0x0, 0xFFFFFF);
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct _rt_ctx {
|
||||
// A pointer to the framebuffer.
|
||||
void *framebuffer;
|
||||
|
||||
// The framebuffer width, in pixels.
|
||||
uint32_t framebuffer_width;
|
||||
|
||||
// The framebuffer height, in pixels.
|
||||
uint32_t framebuffer_height;
|
||||
|
||||
// Set this to 1 if you prefer using DOS line endings to UNIX line endings.
|
||||
int use_crlf_ending;
|
||||
|
||||
// Do we need to show a cursor after printing text?
|
||||
int show_cursor;
|
||||
|
||||
// The background color
|
||||
uint32_t bg_color;
|
||||
|
||||
// The foreground color
|
||||
uint32_t fg_color;
|
||||
|
||||
/*
|
||||
* Do NOT modify everything below me!
|
||||
*/
|
||||
// The terminal's width, in columns of 8 pixels.
|
||||
int term_width;
|
||||
// The terminal's height, in rows of 16 pixels.
|
||||
int term_height;
|
||||
// The X position of the cursor, in columns of 8 pixels.
|
||||
int x;
|
||||
// The Y position of the cursor, in rows of 16 pixels.
|
||||
int y;
|
||||
} rt_context;
|
||||
|
||||
void rt_init(rt_context ctx);
|
||||
void rt_print(char *str);
|
|
@ -41,6 +41,7 @@ void idt_init() {
|
|||
|
||||
pic_init();
|
||||
pic_unmask_irq(1);
|
||||
pic_unmask_irq(8);
|
||||
|
||||
__asm__ volatile("lidt %0" : : "m"(idtr)); // load the new IDT
|
||||
__asm__ volatile("sti"); // set the interrupt flag
|
||||
|
|
|
@ -45,7 +45,7 @@ void exception_handler(registers_t *regs) {
|
|||
|
||||
log("ints - keyboard\n");
|
||||
} else if (regs->int_no == 32 + 8) {
|
||||
rtc_handle_interrupt(regs);
|
||||
log("rtc\n");
|
||||
} else if (regs->int_no == 0x80 - 32 || regs->int_no == 32) {
|
||||
pit_handler(regs);
|
||||
} else if (regs->int_no == 0x80) {
|
||||
|
|
|
@ -1,28 +1,41 @@
|
|||
#include "sys/arch/x86_64/idt.h"
|
||||
#include "sys/arch/x86_64/io.h"
|
||||
#include <sys/arch/x86_64/pic.h>
|
||||
#include <sys/arch/x86_64/rtc.h>
|
||||
#include <sys/printf.h>
|
||||
#include "rtc.h"
|
||||
#include "io.h"
|
||||
|
||||
void rtc_init() {
|
||||
asm("cli");
|
||||
outb(0x70, 0x8A);
|
||||
outb(0x71, 0x20);
|
||||
asm("sti");
|
||||
char bcd;
|
||||
|
||||
unsigned char read_register(unsigned char reg) {
|
||||
__asm__ volatile("cli");
|
||||
outb(RTC_COMMAND, reg);
|
||||
return inb(RTC_DATA);
|
||||
__asm__ volatile("sti");
|
||||
}
|
||||
|
||||
void write_register(unsigned char reg, unsigned char value) {
|
||||
__asm__ volatile("cli");
|
||||
outb(RTC_COMMAND, reg);
|
||||
outb(RTC_DATA, value);
|
||||
__asm__ volatile("sti");
|
||||
}
|
||||
|
||||
unsigned char bcd2bin(unsigned char in_bcd) {
|
||||
return (bcd) ? ((in_bcd >> 4) * 10) + (in_bcd & 0x0F) : in_bcd;
|
||||
}
|
||||
|
||||
int rtc_init() {
|
||||
__asm__ volatile("cli");
|
||||
unsigned char status;
|
||||
status = read_register(RTC_STATUS);
|
||||
status |= 0x02; // 24 hour clock
|
||||
status |= 0x10; // update ended interrupts
|
||||
status &= ~0x20; // no alarm interrupts
|
||||
status &= ~0x40; // no periodic interrupt
|
||||
bcd = !(status & 0x04); // check if data type is BCD
|
||||
write_register(RTC_STATUS, status);
|
||||
|
||||
asm("cli"); // disable interrupts
|
||||
outb(0x70, 0x8B); // select register B, and disable NMI
|
||||
char prev=inb(0x71); // read the current value of register B
|
||||
outb(0x70,
|
||||
0x8B); // set the index again (a read will reset the index to register D)
|
||||
outb(0x71, prev | 0x40); // write the previous value ORed with 0x40. This
|
||||
// turns on bit 6 of register B
|
||||
asm("sti");
|
||||
|
||||
// pic_unmask_irq(8);
|
||||
}
|
||||
|
||||
void rtc_handle_interrupt(registers_t *regs) {
|
||||
(void)regs;
|
||||
printf("RTC!\n");
|
||||
outb(0x70, 0x8B); // set the index again (a read will reset the index to register D)
|
||||
outb(0x71, prev | 0x40); // write the previous value ORed with 0x40. This turns on bit 6 of register B
|
||||
__asm__ volatile("sti");
|
||||
return 0;
|
||||
}
|
|
@ -1,6 +1,18 @@
|
|||
#pragma once
|
||||
#ifndef __TIME_H
|
||||
#define __TIME_H
|
||||
|
||||
#include "sys/arch/x86_64/idt.h"
|
||||
#define RTC_COMMAND 0x70
|
||||
#define RTC_DATA 0x71
|
||||
#define RTC_STATUS 0x0B
|
||||
|
||||
void rtc_init();
|
||||
void rtc_handle_interrupt(registers_t *regs);
|
||||
#define RTC_SECONDS 0x00
|
||||
#define RTC_MINUTES 0x02
|
||||
#define RTC_HOURS 0x04
|
||||
#define RTC_DAY_OF_WEEK 0x06
|
||||
#define RTC_DAY 0x07
|
||||
#define RTC_MONTH 0x08
|
||||
#define RTC_YEAR 0x09
|
||||
|
||||
int rtc_init();
|
||||
|
||||
#endif // __TIME_H__
|
Loading…
Add table
Add a link
Reference in a new issue