diff --git a/bootloader/bootloader.asm b/bootloader/bootloader.asm index 05beada6..1a4db17b 100644 --- a/bootloader/bootloader.asm +++ b/bootloader/bootloader.asm @@ -64,7 +64,7 @@ rm_start: ; Loading the assembly kernel from floppy ASM_KERNEL_BASE equ 0x100 ; 0x0100:0x0 = 0x1000 - sectors equ 0x28 ; sectors to read + sectors equ 0x30 ; sectors to read bootdev equ 0x0 mov ax, ASM_KERNEL_BASE diff --git a/fill.bash b/fill.bash index aba7330b..0c7de7eb 100644 --- a/fill.bash +++ b/fill.bash @@ -1,5 +1,5 @@ #!/bin/bash size=`stat -c%s kernel.bin` -let filler_size=4096-$size +let filler_size=8192-$size dd if=/dev/zero of=filler.bin bs=1 count=$filler_size diff --git a/kernel/src/console.cpp b/kernel/src/console.cpp index 6b5ca775..c1e86af3 100644 --- a/kernel/src/console.cpp +++ b/kernel/src/console.cpp @@ -70,7 +70,7 @@ void k_print(std::size_t number){ --i; - for(; i > 0; --i){ + for(; i >= 0; --i){ k_print(buffer[i]); } } diff --git a/kernel/src/shell.cpp b/kernel/src/shell.cpp index 0dc2110c..5ac64335 100644 --- a/kernel/src/shell.cpp +++ b/kernel/src/shell.cpp @@ -16,6 +16,20 @@ void reboot_command(); void help_command(); void uptime_command(); void clear_command(); +void date_command(); + +struct command_definition { + const char* name; + void (*function)(); +}; + +std::array commands = {{ + {"reboot", reboot_command}, + {"help", help_command}, + {"uptime", uptime_command}, + {"clear", clear_command}, + {"date", date_command} +}}; std::size_t current_input_length = 0; char current_input[50]; @@ -64,18 +78,6 @@ bool str_equals(const char* a, const char* b){ return *a == *b; } -struct command_definition { - const char* name; - void (*function)(); -}; - -std::array commands = {{ - {"reboot", reboot_command}, - {"help", help_command}, - {"uptime", uptime_command}, - {"clear", clear_command} -}}; - void reboot_command(){ interrupt<60>(); } @@ -113,6 +115,126 @@ void clear_command(){ wipeout(); } +#define CURRENT_YEAR 2013 +#define century_register 0x00 +#define cmos_address 0x70 +#define cmos_data 0x71 + +int get_update_in_progress_flag() { + out_byte(cmos_address, 0x0A); + return (in_byte(cmos_data) & 0x80); +} + +uint8_t get_RTC_register(int reg) { + out_byte(cmos_address, reg); + return in_byte(cmos_data); +} + +void date_command(){ + uint8_t second; + uint8_t minute; + uint8_t hour; + uint8_t day; + uint8_t month; + unsigned int year; + + uint8_t century; + uint8_t last_second; + uint8_t last_minute; + uint8_t last_hour; + uint8_t last_day; + uint8_t last_month; + uint8_t last_year; + uint8_t last_century; + uint8_t registerB; + + while (get_update_in_progress_flag()){}; // Make sure an update isn't in progress + + second = get_RTC_register(0x00); + minute = get_RTC_register(0x02); + hour = get_RTC_register(0x04); + day = get_RTC_register(0x07); + month = get_RTC_register(0x08); + year = get_RTC_register(0x09); + + if(century_register != 0) { + century = get_RTC_register(century_register); + } + + do { + last_second = second; + last_minute = minute; + last_hour = hour; + last_day = day; + last_month = month; + last_year = year; + last_century = century; + + while (get_update_in_progress_flag()){}; // Make sure an update isn't in progress + + second = get_RTC_register(0x00); + minute = get_RTC_register(0x02); + hour = get_RTC_register(0x04); + day = get_RTC_register(0x07); + month = get_RTC_register(0x08); + year = get_RTC_register(0x09); + + if(century_register != 0) { + century = get_RTC_register(century_register); + } + } while( (last_second != second) || (last_minute != minute) || (last_hour != hour) || + (last_day != day) || (last_month != month) || (last_year != year) || + (last_century != century) ); + + registerB = get_RTC_register(0x0B); + + // Convert BCD to binary values if necessary + + if (!(registerB & 0x04)) { + second = (second & 0x0F) + ((second / 16) * 10); + minute = (minute & 0x0F) + ((minute / 16) * 10); + hour = ( (hour & 0x0F) + (((hour & 0x70) / 16) * 10) ) | (hour & 0x80); + day = (day & 0x0F) + ((day / 16) * 10); + month = (month & 0x0F) + ((month / 16) * 10); + year = (year & 0x0F) + ((year / 16) * 10); + + if(century_register != 0) { + century = (century & 0x0F) + ((century / 16) * 10); + } + } + + // Convert 12 hour clock to 24 hour clock if necessary + + if (!(registerB & 0x02) && (hour & 0x80)) { + hour = ((hour & 0x7F) + 12) % 24; + } + + // Calculate the full (4-digit) year + + if(century_register != 0) { + year += century * 100; + } else { + year += (CURRENT_YEAR / 100) * 100; + if(year < CURRENT_YEAR) year += 100; + } + + k_print((std::size_t) day); + k_print('.'); + k_print((std::size_t) month); + k_print('.'); + k_print((std::size_t) year); + + k_print(' '); + + k_print((std::size_t) hour); + k_print(':'); + k_print((std::size_t) minute); + k_print(':'); + k_print((std::size_t) second); + + k_print_line(); +} + } //end of anonymous namespace void init_shell(){ diff --git a/kernel/src/timer.cpp b/kernel/src/timer.cpp index fdae4a8d..865d136b 100644 --- a/kernel/src/timer.cpp +++ b/kernel/src/timer.cpp @@ -4,8 +4,8 @@ namespace { -std::size_t _timer_ticks; -std::size_t _timer_seconds; +std::size_t _timer_ticks = 0; +std::size_t _timer_seconds = 0; void timer_handler(){ ++_timer_ticks;