vgabios: Add scrolling for linear (packed pixel) graphics mode.
[seabios.git] / src / clock.c
index c79f3924fc062aedbb318aa97b34cdfa8f5ec653..fcdc698bb15b8c9a0cad8a950312fa1b3b35e965 100644 (file)
@@ -1,6 +1,6 @@
 // 16bit code to handle system clocks.
 //
-// Copyright (C) 2008  Kevin O'Connor <kevin@koconnor.net>
+// Copyright (C) 2008-2010  Kevin O'Connor <kevin@koconnor.net>
 // Copyright (C) 2002  MandrakeSoft S.A.
 //
 // This file may be distributed under the terms of the GNU LGPLv3 license.
@@ -54,7 +54,6 @@
  * TSC timer
  ****************************************************************/
 
-#define TICKS_PER_DAY (u32)((u64)60*60*24*PIT_TICK_RATE / PIT_TICK_INTERVAL)
 #define CALIBRATE_COUNT 0x800   // Approx 1.7ms
 
 u32 cpu_khz VAR16VISIBLE;
@@ -95,7 +94,7 @@ tscdelay(u64 diff)
 {
     u64 start = rdtscll();
     u64 end = start + diff;
-    while (!check_time(end))
+    while (!check_tsc(end))
         cpu_relax();
 }
 
@@ -104,7 +103,7 @@ tscsleep(u64 diff)
 {
     u64 start = rdtscll();
     u64 end = start + diff;
-    while (!check_time(end))
+    while (!check_tsc(end))
         yield();
 }
 
@@ -164,7 +163,7 @@ rtc_updating(void)
     for (;;) {
         if ((inb_cmos(CMOS_STATUS_A) & RTC_A_UIP) == 0)
             return 0;
-        if (check_time(end))
+        if (check_tsc(end))
             // update-in-progress never transitioned to 0
             return -1;
         yield();
@@ -212,10 +211,9 @@ timer_setup(void)
     u32 ticks = (hours * 60 + minutes) * 60 + seconds;
     ticks = ((u64)ticks * PIT_TICK_RATE) / PIT_TICK_INTERVAL;
     SET_BDA(timer_counter, ticks);
-    SET_BDA(timer_rollover, 0);
 
-    enable_hwirq(0, entry_08);
-    enable_hwirq(8, entry_70);
+    enable_hwirq(0, FUNC16(entry_08));
+    enable_hwirq(8, FUNC16(entry_70));
 }
 
 
@@ -223,6 +221,35 @@ timer_setup(void)
  * Standard clock functions
  ****************************************************************/
 
+#define TICKS_PER_DAY (u32)((u64)60*60*24*PIT_TICK_RATE / PIT_TICK_INTERVAL)
+
+// Calculate the timer value at 'count' number of full timer ticks in
+// the future.
+u32
+calc_future_timer_ticks(u32 count)
+{
+    return (GET_BDA(timer_counter) + count + 1) % TICKS_PER_DAY;
+}
+
+// Return the timer value that is 'msecs' time in the future.
+u32
+calc_future_timer(u32 msecs)
+{
+    if (!msecs)
+        return GET_BDA(timer_counter);
+    u32 kticks = DIV_ROUND_UP((u64)msecs * PIT_TICK_RATE, PIT_TICK_INTERVAL);
+    u32 ticks = DIV_ROUND_UP(kticks, 1000);
+    return calc_future_timer_ticks(ticks);
+}
+
+// Check if the given timer value has passed.
+int
+check_timer(u32 end)
+{
+    return (((GET_BDA(timer_counter) + TICKS_PER_DAY - end) % TICKS_PER_DAY)
+            < (TICKS_PER_DAY/2));
+}
+
 // get current clock count
 static void
 handle_1a00(struct bregs *regs)