forked from PoliEcho-holding-org/kern
Added Real Time Clock. Time is now being shown at the top
This commit is contained in:
@@ -25,10 +25,10 @@ filesystem: bootloader kernel $(C_FILES) $(FONTS)
|
||||
@dd if=$(BUILD)/boot.bin of=kern.iso bs=512 seek=0 conv=notrunc status=none
|
||||
@dd if=$(BUILD)/filetable.bin of=kern.iso bs=512 seek=5 conv=notrunc status=none
|
||||
@dd if=$(BUILD)/kernel.bin of=kern.iso bs=512 seek=6 conv=notrunc status=none
|
||||
@dd if=$(BUILD)/term16n.bin of=kern.iso bs=512 seek=36 conv=notrunc status=none
|
||||
@dd if=$(BUILD)/testfont.bin of=kern.iso bs=512 seek=40 conv=notrunc status=none
|
||||
@dd if=$(SRC)/fs/test.txt of=kern.iso bs=512 seek=44 conv=notrunc status=none
|
||||
@dd if=$(BUILD)/calc.bin of=kern.iso bs=512 seek=45 conv=notrunc status=none
|
||||
@dd if=$(BUILD)/term16n.bin of=kern.iso bs=512 seek=46 conv=notrunc status=none
|
||||
@dd if=$(BUILD)/testfont.bin of=kern.iso bs=512 seek=50 conv=notrunc status=none
|
||||
@dd if=$(SRC)/fs/test.txt of=kern.iso bs=512 seek=54 conv=notrunc status=none
|
||||
@dd if=$(BUILD)/calc.bin of=kern.iso bs=512 seek=55 conv=notrunc status=none
|
||||
|
||||
$(BUILD):
|
||||
@[ -d $(BUILD) ] || mkdir $(BUILD)
|
||||
@@ -63,7 +63,11 @@ $(FONTS):
|
||||
|
||||
# Run QEMU
|
||||
run:
|
||||
qemu-system-x86_64 -drive format=raw,file="./kern.iso",index=0,media=disk -m 256M -accel tcg
|
||||
qemu-system-x86_64\
|
||||
-drive format=raw,file="./kern.iso",index=0,media=disk\
|
||||
-m 256M\
|
||||
-accel tcg\
|
||||
-rtc base=localtime,clock=host,driftfix=slew
|
||||
|
||||
# Clean all build files
|
||||
clean:
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
#ifndef RTC_H
|
||||
#define RTC_H
|
||||
|
||||
#include <interrupt/pic.h>
|
||||
#include <interrupt/idt.h>
|
||||
#include <screen/text.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#define CMOS_ADDRESS 0x70
|
||||
#define CMOS_DATA 0x71
|
||||
|
||||
typedef struct {
|
||||
uint8_t second;
|
||||
uint8_t minute;
|
||||
uint8_t hour;
|
||||
uint8_t day;
|
||||
uint8_t month;
|
||||
uint16_t year;
|
||||
} __attribute__ ((packed)) datetime_t;
|
||||
|
||||
static datetime_t* datetime = (datetime_t*)0x2000; // TODO: Put this at a constant address in memory
|
||||
|
||||
bool cmosUpdateProgress() {
|
||||
outb(CMOS_ADDRESS, 0x8a); // Read status reg A, disable NMI
|
||||
return inb(CMOS_DATA) & 0x80;
|
||||
}
|
||||
|
||||
uint8_t getRtcRegister(uint8_t reg) {
|
||||
outb(CMOS_ADDRESS, reg | 0x80); // Disable NMI when sending
|
||||
return inb(CMOS_DATA);
|
||||
}
|
||||
|
||||
void enableRtc() {
|
||||
uint8_t regB = getRtcRegister(0x0b);
|
||||
outb(CMOS_ADDRESS, 0x8b);
|
||||
outb(CMOS_DATA, regB | 0x40); // Set bit 6 - periodic int at 1024Hz
|
||||
|
||||
getRtcRegister(0x0c); // Clear pending interrupts
|
||||
}
|
||||
|
||||
void disableRtc() {
|
||||
__asm__ volatile ("cli");
|
||||
uint8_t regB = getRtcRegister(0x0b);
|
||||
outb(CMOS_ADDRESS, 0x8b);
|
||||
outb(CMOS_DATA, regB & 0xbf); // Clear bit 6
|
||||
__asm__ volatile ("sti");
|
||||
}
|
||||
|
||||
__attribute__ ((interrupt)) void rtcHandler(intFrame_t* iframe) {
|
||||
datetime_t newDatetime, oldDatetime;
|
||||
static uint16_t rtcTicks = 0;
|
||||
|
||||
__asm__ volatile ("cli");
|
||||
rtcTicks++;
|
||||
if (rtcTicks % 1024 == 0) { // 1 Second has passed
|
||||
while (cmosUpdateProgress()); // Wait
|
||||
|
||||
newDatetime.second = getRtcRegister(0);
|
||||
newDatetime.minute = getRtcRegister(2);
|
||||
newDatetime.hour = getRtcRegister(4);
|
||||
newDatetime.day = getRtcRegister(7);
|
||||
newDatetime.month = getRtcRegister(8);
|
||||
newDatetime.year = getRtcRegister(9);
|
||||
|
||||
do {
|
||||
oldDatetime = newDatetime;
|
||||
|
||||
while (cmosUpdateProgress()); // Wait
|
||||
newDatetime.second = getRtcRegister(0);
|
||||
newDatetime.minute = getRtcRegister(2);
|
||||
newDatetime.hour = getRtcRegister(4);
|
||||
newDatetime.day = getRtcRegister(7);
|
||||
newDatetime.month = getRtcRegister(8);
|
||||
newDatetime.year = getRtcRegister(9);
|
||||
|
||||
} while (
|
||||
newDatetime.second != oldDatetime.second ||
|
||||
newDatetime.minute != oldDatetime.minute ||
|
||||
newDatetime.hour != oldDatetime.hour ||
|
||||
newDatetime.day != oldDatetime.day ||
|
||||
newDatetime.month != oldDatetime.month ||
|
||||
newDatetime.year != oldDatetime.year
|
||||
);
|
||||
|
||||
uint8_t regB = getRtcRegister(0x0b);
|
||||
if (!(regB & 0x04)) {
|
||||
newDatetime.second = (newDatetime.second & 0x0f) + ((newDatetime.second >> 4) * 10);
|
||||
newDatetime.minute = (newDatetime.minute & 0x0f) + ((newDatetime.minute >> 4) * 10);
|
||||
newDatetime.hour = ((newDatetime.hour & 0x0f) + (((newDatetime.hour & 0x70) >> 4) * 10)) | (newDatetime.hour * 0x80); // 12/24 Hour format bs
|
||||
newDatetime.day = (newDatetime.day & 0x0f) + ((newDatetime.day >> 4) * 10);
|
||||
newDatetime.month = (newDatetime.month & 0x0f) + ((newDatetime.month >> 4) * 10);
|
||||
newDatetime.year = (newDatetime.year & 0x0f) + ((newDatetime.year >> 4) * 10);
|
||||
}
|
||||
|
||||
// Convert 12 to 14 hour format
|
||||
if (!(regB & 0x02) && (newDatetime.hour & 0x80)) {
|
||||
newDatetime.hour = ((newDatetime.hour & 0x7f) + 12) % 24;
|
||||
}
|
||||
|
||||
newDatetime.year += 2000; // Add current century
|
||||
|
||||
//*datetime = newDatetime;
|
||||
|
||||
datetime->second = newDatetime.second;
|
||||
datetime->minute = newDatetime.minute;
|
||||
datetime->hour = newDatetime.hour;
|
||||
datetime->day = newDatetime.day;
|
||||
datetime->month = newDatetime.month;
|
||||
datetime->year = newDatetime.year;
|
||||
|
||||
if (true) { // TODO: Probably get rid of this idk
|
||||
char buf[20] = { 0 }; // "12/12 2012 12:12:12" - Max string 20 chars with null byte
|
||||
|
||||
strcat(buf, itoa(datetime->day, 10));
|
||||
strcat(buf, "/");
|
||||
strcat(buf, itoa(datetime->month, 10));
|
||||
strcat(buf, " ");
|
||||
strcat(buf, itoa(datetime->year, 10));
|
||||
strcat(buf, " ");
|
||||
strcat(buf, itoa(datetime->hour, 10));
|
||||
strcat(buf, ":");
|
||||
strcat(buf, itoa(datetime->minute, 10));
|
||||
strcat(buf, ":");
|
||||
strcat(buf, itoa(datetime->second, 10));
|
||||
|
||||
printAt(" ", 30, 0);
|
||||
bgColor = 0x0027323f;
|
||||
fgColor = 0x00ededed;
|
||||
printAt(buf, 30, 0);
|
||||
bgColor = BG_COLOR;
|
||||
fgColor = FG_COLOR;
|
||||
}
|
||||
}
|
||||
|
||||
getRtcRegister(0x0c);
|
||||
sendPicEOI(8);
|
||||
|
||||
__asm__ volatile ("sti");
|
||||
}
|
||||
|
||||
void setupRtc() { // IRQ 8 - Real Time Clock
|
||||
idtSetGate(0x28, rtcHandler, INT_GATE_FLAGS);
|
||||
unsetIrqMask(8);
|
||||
enableRtc();
|
||||
}
|
||||
|
||||
#endif
|
||||
+5
-5
@@ -12,11 +12,11 @@
|
||||
filetable:
|
||||
db "boot",0,0,0,0,0,0, "bin",0,0,5
|
||||
db "filetable",0, "tab",0,5,1
|
||||
db "kernel",0,0,0,0, "bin",0,6,30
|
||||
db "term16n",0,0,0, "fnt",0,36,4
|
||||
db "testfont",0,0, "fnt",0,40,4
|
||||
db "test",0,0,0,0,0,0, "txt",0,44,1
|
||||
db "calc",0,0,0,0,0,0, "bin",0,45,2
|
||||
db "kernel",0,0,0,0, "bin",0,6,40
|
||||
db "term16n",0,0,0, "fnt",0,46,4
|
||||
db "testfont",0,0, "fnt",0,50,4
|
||||
db "test",0,0,0,0,0,0, "txt",0,54,1
|
||||
db "calc",0,0,0,0,0,0, "bin",0,55,2
|
||||
|
||||
times 512-($-$$) db 0
|
||||
|
||||
|
||||
+4
-1
@@ -10,6 +10,7 @@
|
||||
#include <screen/graphics.h>
|
||||
#include <keyboard/keyboard.h>
|
||||
#include <interrupt/pit.h>
|
||||
#include <interrupt/rtc.h>
|
||||
#include <time.h>
|
||||
|
||||
#define PROMPT "#> "
|
||||
@@ -39,7 +40,7 @@ void main() {
|
||||
deinitMemoryRegion(memmapAddr, maxBlocks / BLOCKS_PER_BYTE);
|
||||
|
||||
// TODO: Find font in filetable
|
||||
diskRead(36, 4, font); // Read font from disk
|
||||
diskRead(46, 4, font); // Read font from disk
|
||||
|
||||
clear();
|
||||
print("kern.\n\n");
|
||||
@@ -52,9 +53,11 @@ void main() {
|
||||
idtSetGate(0x80, syscallHandler, USR_INT_GAME_FLAGS); // Setup Syscall handler in IDT for int 0x80
|
||||
disableIrqs();
|
||||
remapPic();
|
||||
unsetIrqMask(2); // Enable PIC 2 line
|
||||
__asm__ volatile ("sti");
|
||||
|
||||
setupTimer();
|
||||
setupRtc();
|
||||
setupKeyboard();
|
||||
|
||||
// Run Interactive Shell Program
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
|
||||
%define VIDMEM 0xb800
|
||||
%define FILETAB_LOC 0x7000 ; TODO: Read kernel size and location from ft
|
||||
%define KERNEL_SIZE 30 ; 15kB
|
||||
%define KERNEL_SIZE 40 ; 20kB
|
||||
|
||||
start:
|
||||
mov [driveNum], dl ; Store the drive number
|
||||
|
||||
Reference in New Issue
Block a user