rtc - try implementing RTC / kernel: removed rt from the codebase (released separately)

This commit is contained in:
RaphProductions 2025-05-12 10:24:48 +02:00
parent 6af9752e24
commit 3461dcb1ed
6 changed files with 54 additions and 154 deletions

View file

@ -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);
}

View file

@ -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);

View file

@ -41,6 +41,7 @@ void idt_init() {
pic_init(); pic_init();
pic_unmask_irq(1); pic_unmask_irq(1);
pic_unmask_irq(8);
__asm__ volatile("lidt %0" : : "m"(idtr)); // load the new IDT __asm__ volatile("lidt %0" : : "m"(idtr)); // load the new IDT
__asm__ volatile("sti"); // set the interrupt flag __asm__ volatile("sti"); // set the interrupt flag

View file

@ -45,7 +45,7 @@ void exception_handler(registers_t *regs) {
log("ints - keyboard\n"); log("ints - keyboard\n");
} else if (regs->int_no == 32 + 8) { } 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) { } else if (regs->int_no == 0x80 - 32 || regs->int_no == 32) {
pit_handler(regs); pit_handler(regs);
} else if (regs->int_no == 0x80) { } else if (regs->int_no == 0x80) {

View file

@ -1,28 +1,41 @@
#include "sys/arch/x86_64/idt.h" #include "rtc.h"
#include "sys/arch/x86_64/io.h" #include "io.h"
#include <sys/arch/x86_64/pic.h>
#include <sys/arch/x86_64/rtc.h>
#include <sys/printf.h>
void rtc_init() { char bcd;
asm("cli");
outb(0x70, 0x8A);
outb(0x71, 0x20);
asm("sti");
asm("cli"); // disable interrupts unsigned char read_register(unsigned char reg) {
outb(0x70, 0x8B); // select register B, and disable NMI __asm__ volatile("cli");
char prev = inb(0x71); // read the current value of register B outb(RTC_COMMAND, reg);
outb(0x70, return inb(RTC_DATA);
0x8B); // set the index again (a read will reset the index to register D) __asm__ volatile("sti");
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 write_register(unsigned char reg, unsigned char value) {
(void)regs; __asm__ volatile("cli");
printf("RTC!\n"); 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);
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__ volatile("sti");
return 0;
} }

View file

@ -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(); #define RTC_SECONDS 0x00
void rtc_handle_interrupt(registers_t *regs); #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__