Merge into main the new state of the operating system/kernel #1
@ -62,15 +62,17 @@ void kterm_scrollup(){
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void kterm_put (char c) {
 | 
			
		||||
 
 | 
			
		||||
    if(++kterm_column == VGA_WIDTH || c == '\n' ) {
 | 
			
		||||
        kterm_column = 0;
 | 
			
		||||
        if(kterm_row == VGA_HEIGHT-1) {       
 | 
			
		||||
        if(kterm_row == VGA_HEIGHT-1 ) {       
 | 
			
		||||
            kterm_scrollup();
 | 
			
		||||
        } else {
 | 
			
		||||
            kterm_row ++;
 | 
			
		||||
        }
 | 
			
		||||
            
 | 
			
		||||
    }
 | 
			
		||||
    if ( c == '\r'){
 | 
			
		||||
        kterm_column = 0;
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    if(c == '\n') return;
 | 
			
		||||
@ -89,3 +91,100 @@ void kterm_writestring(const char* data ){
 | 
			
		||||
    AS_KERNEL();
 | 
			
		||||
    kterm_write(data, strlen(data));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void itoa (char *buf, int base, int d) {
 | 
			
		||||
    char *p = buf;
 | 
			
		||||
    char *p1, *p2;
 | 
			
		||||
    unsigned long ud = d;
 | 
			
		||||
    int divisor = 10;
 | 
			
		||||
    if ( base == 'd' && d < 0){
 | 
			
		||||
        *p++ = '-';
 | 
			
		||||
        buf++;
 | 
			
		||||
        ud = -d;
 | 
			
		||||
    } else if (base == 'x'){
 | 
			
		||||
        divisor = 16;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    do { 
 | 
			
		||||
        int remainder = ud % divisor;
 | 
			
		||||
 | 
			
		||||
         *p++ = (remainder < 10 ) ? remainder + '0' : remainder + 'a' -10;
 | 
			
		||||
    } while(ud /= divisor);
 | 
			
		||||
 | 
			
		||||
    /*terminate buf*/
 | 
			
		||||
    *p =0;
 | 
			
		||||
    p1 = buf;
 | 
			
		||||
    p2 = p -1;
 | 
			
		||||
 | 
			
		||||
    while (p1 < p2)
 | 
			
		||||
    {
 | 
			
		||||
        char tmp = *p1;
 | 
			
		||||
        *p1 = *p2;
 | 
			
		||||
        *p2 = tmp;
 | 
			
		||||
        p1++;
 | 
			
		||||
        p2--;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void printf ( const char *format, ...) {
 | 
			
		||||
    
 | 
			
		||||
    char **arg = (char **)&format;
 | 
			
		||||
    int c;
 | 
			
		||||
    char buf[20];
 | 
			
		||||
 | 
			
		||||
    arg++;
 | 
			
		||||
    
 | 
			
		||||
    while ((c = *format++) != 0){
 | 
			
		||||
        if( c != '%')
 | 
			
		||||
            kterm_put(c);
 | 
			
		||||
        else{
 | 
			
		||||
            char *p, *p2;
 | 
			
		||||
            int pad0 = 0, pad = 0;
 | 
			
		||||
 | 
			
		||||
            c = *format++;
 | 
			
		||||
            if(c =='0'){
 | 
			
		||||
                pad0 = 1;
 | 
			
		||||
                c = *format++;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if ( c >= '0' && c <= '9'){
 | 
			
		||||
                pad = c - '0';
 | 
			
		||||
                c = *format++;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            switch (c)
 | 
			
		||||
            {
 | 
			
		||||
            case 'd':
 | 
			
		||||
 | 
			
		||||
            case 'u':
 | 
			
		||||
            case 'x':
 | 
			
		||||
                itoa(buf, c, *((int *) arg++));
 | 
			
		||||
 | 
			
		||||
                p = buf;
 | 
			
		||||
                goto string;
 | 
			
		||||
                break;
 | 
			
		||||
            
 | 
			
		||||
            case 's':
 | 
			
		||||
                p = *arg++;
 | 
			
		||||
                if(!p)
 | 
			
		||||
                    p = "(null)";
 | 
			
		||||
                
 | 
			
		||||
                string: 
 | 
			
		||||
                    for (p2 = p; *p2; p2++);
 | 
			
		||||
                    for (; p2 < p + pad; p2++)
 | 
			
		||||
                        kterm_put(pad0 ? '0': ' ');
 | 
			
		||||
                    while (*p)
 | 
			
		||||
                        kterm_put(*p++);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            default:
 | 
			
		||||
                kterm_put(*((int *)arg++));
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -15,10 +15,16 @@ void kterm_putat(char, uint8_t, size_t, size_t);
 | 
			
		||||
void kterm_put(char);
 | 
			
		||||
void kterm_write(const char*, size_t);
 | 
			
		||||
void kterm_writestring(const char*);
 | 
			
		||||
 | 
			
		||||
void kterm_scrollup();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void printf ( const char *format, ...);
 | 
			
		||||
 | 
			
		||||
static void itoa (char *buf, int base, int d);
 | 
			
		||||
 | 
			
		||||
#define KernelTag "[Kernel]: "
 | 
			
		||||
#define AS_KERNEL() (  kterm_setcolor(VGA_COLOR_LIGHT_BLUE),\
 | 
			
		||||
                       kterm_write(KernelTag, 10 ), \
 | 
			
		||||
                       kterm_resetcolor())
 | 
			
		||||
                       kterm_resetcolor())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										151
									
								
								src/kernel/time.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								src/kernel/time.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,151 @@
 | 
			
		||||
#define CURRENT_YEAR        2021                            // Change this each year!
 | 
			
		||||
 
 | 
			
		||||
int century_register = 0x00;                                // Set by ACPI table parsing code if possible
 | 
			
		||||
 
 | 
			
		||||
unsigned char second;
 | 
			
		||||
unsigned char minute;
 | 
			
		||||
unsigned char hour;
 | 
			
		||||
unsigned char day;
 | 
			
		||||
unsigned char month;
 | 
			
		||||
unsigned int year;
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
enum {
 | 
			
		||||
      cmos_address = 0x70,
 | 
			
		||||
      cmos_data    = 0x71
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
int get_update_in_progress_flag() {
 | 
			
		||||
      outb(cmos_address, 0x0A);
 | 
			
		||||
      return (inb(cmos_data) & 0x80);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
unsigned char get_RTC_register(int reg) {
 | 
			
		||||
      outb(cmos_address, reg);
 | 
			
		||||
      return inb(cmos_data);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
void read_rtc() {
 | 
			
		||||
      unsigned char century;
 | 
			
		||||
      unsigned char last_second;
 | 
			
		||||
      unsigned char last_minute;
 | 
			
		||||
      unsigned char last_hour;
 | 
			
		||||
      unsigned char last_day;
 | 
			
		||||
      unsigned char last_month;
 | 
			
		||||
      unsigned char last_year;
 | 
			
		||||
      unsigned char last_century;
 | 
			
		||||
      unsigned char registerB;
 | 
			
		||||
 
 | 
			
		||||
      // Note: This uses the "read registers until you get the same values twice in a row" technique
 | 
			
		||||
      //       to avoid getting dodgy/inconsistent values due to RTC updates
 | 
			
		||||
 
 | 
			
		||||
      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;
 | 
			
		||||
      }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
void ReadFromCMOS(unsigned char array[])
 | 
			
		||||
{
 | 
			
		||||
    unsigned char tvalue, index;
 | 
			
		||||
 | 
			
		||||
    for (index = 0; index < 128; index++)
 | 
			
		||||
    {
 | 
			
		||||
        asm(
 | 
			
		||||
            "cli\n\t"           // Disable interrupts
 | 
			
		||||
            "mov al, index\n\t" // Move index address
 | 
			
		||||
            // since the 0x80 bit of al is not set, NMI is active 
 | 
			
		||||
            "out 0x70,al\n\t" // Copy address to CMOS register
 | 
			
		||||
            // some kind of real delay here is probably best 
 | 
			
		||||
            "in al,0x71\n\t" // Fetch 1 byte to al
 | 
			
		||||
            "sti\n\t"        // Enable interrupts
 | 
			
		||||
            "mov tvalue,al\n\t");
 | 
			
		||||
 | 
			
		||||
        array[index] = tvalue;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
void WriteTOCMOS(unsigned char array[])
 | 
			
		||||
{
 | 
			
		||||
   unsigned char index;
 | 
			
		||||
 
 | 
			
		||||
   for(index = 0; index < 128; index++)
 | 
			
		||||
   {
 | 
			
		||||
      unsigned char tvalue = array[index];
 | 
			
		||||
      
 | 
			
		||||
       asm("cli\n\t"       // Clear interrupts
 | 
			
		||||
         "mov al,index\n\t"    // move index address
 | 
			
		||||
         "out 0x70,al\n\t"     // copy address to CMOS register
 | 
			
		||||
         /* some kind of real delay here is probably best 
 | 
			
		||||
         "mov al,tvalue\n\t"   // move value to al
 | 
			
		||||
         "out 0x71,al\n\t"   // write 1 byte to CMOS
 | 
			
		||||
         "sti\n\\t"   );        // Enable interrupts
 | 
			
		||||
      
 | 
			
		||||
   }
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
		Reference in New Issue
	
	Block a user