Advertisement
iocoder

rtc.cpp

May 26th, 2014
345
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.06 KB | None | 0 0
  1. // this was last written on 01 July 2010
  2.  
  3. asm("clock:");          // Header of ISA CMOS Real Time Clock.
  4. asm("call  clock_main");    // Go to start of code.
  5. asm("iret");            // Return.
  6. asm("clock_package_data: .space 128");
  7. asm("drive_size:  .long 0x00002000");  
  8. asm("drive_class: .long 0x010103FF"); // ISA -> Base Systems Peripheral -> RTC -> General
  9. unsigned int *clock_pack;
  10.  
  11. #include <kernel.h>
  12. #include <asm.h>
  13. #include <cga.h>
  14.  
  15. void clock_update();
  16.  
  17. struct rtc_date_time {
  18.     unsigned short year;
  19.     unsigned char  month;
  20.     unsigned char  day;
  21.     unsigned char  dayw;
  22.     unsigned char  hour;
  23.     unsigned char  minute;
  24.     unsigned char  second;
  25. } static system_time;
  26.  
  27. void clock_initialize() {
  28.     printk(" Initializing CMOS RTC (Real Time Clock) Driver ...\n");
  29.     asm("movl $clock_package_data, clock_pack");
  30.     unsigned int static pack[32];
  31.     pack[1] = 1;
  32.     pack[2] = 0x0405;
  33.     pack[3] = 10;
  34.     asm("int $0x81"::"a"(0x0401), "b"(3), "D"(pack));
  35.     clock_update();
  36. }
  37.  
  38. void clock_gettime() {
  39.     // Outputs:
  40.     // ----------
  41.     // 0: Year
  42.     // 1: Month
  43.     // 2: Day
  44.     // 3: Day of Week.
  45.     // 4: Hour
  46.     // 5: Minutes
  47.     // 6: Seconds
  48.  
  49.     // Output Information:
  50.     // ----------------------
  51.     clock_pack[6] = system_time.second;
  52.     clock_pack[5] = system_time.minute;
  53.     clock_pack[4] = system_time.hour;
  54.     clock_pack[3] = system_time.dayw;
  55.     clock_pack[2] = system_time.day;
  56.     clock_pack[1] = system_time.month;
  57.     clock_pack[0] = system_time.year;
  58. }
  59.  
  60.  
  61. void clock_update() {
  62.     outb(0x0, 0x70); system_time.second = (inb(0x71) & 0x0F) + (((inb(0x71)&0xF0)>>4)*10); // Get Seconds from CMOS.
  63.     outb(0x2, 0x70); system_time.minute = (inb(0x71) & 0x0F) + (((inb(0x71)&0xF0)>>4)*10); // Get Minutes from CMOS.
  64.     outb(0x4, 0x70); system_time.hour   = (inb(0x71) & 0x0F) + (((inb(0x71)&0xF0)>>4)*10); // Get Hours from CMOS.
  65.     outb(0x7, 0x70); system_time.day    = (inb(0x71) & 0x0F) + (((inb(0x71)&0xF0)>>4)*10); // Get Day from CMOS.
  66.     outb(0x8, 0x70); system_time.month  = (inb(0x71) & 0x0F) + (((inb(0x71)&0xF0)>>4)*10); // Get Month from CMOS.
  67.     outb(0x9, 0x70); system_time.year   = (inb(0x71) & 0x0F) + (((inb(0x71)&0xF0)>>4)*10) + 2000; // Get Year.
  68.  
  69.     // Algorithm of getting the day of week:
  70.     // ---------------------------------------
  71.     // [Source: http://en.wikipedia.org/wiki/Calculating_the_day_of_the_week ]
  72.     unsigned char months[] = {0, 0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5};
  73.     unsigned char months_leap[] = {0, 6, 2, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5};
  74.     unsigned int step1 = 6; // We are working on the 2000s
  75.     unsigned int step2 = system_time.year - 2000; // Last two digits.
  76.     unsigned int step3 = step2/4;   // Divide the two digits by 4. notice that this is integer not float.
  77.     unsigned int step4; if (step2%4) step4=months[system_time.month]; else step4=months_leap[system_time.month];
  78.     unsigned int step5 = step1 + step2 + step3 + step4 + system_time.day;
  79.     system_time.dayw = step5 % 7;
  80. }
  81.  
  82. extern "C" {
  83. void clock_main() {
  84.     unsigned char func;
  85.     asm("":"=b"(func));
  86.     switch (func) {
  87.         case  1: {clock_initialize();   break;}
  88.         case  2: {clock_gettime();  break;}
  89.         case 10: {clock_update();   break;}
  90.     }
  91. }
  92. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement