00001
00002
00003
00004
00005
00006
00007
00008 #ifndef __pc_timer_h
00009 #define __pc_timer_h
00010
00011 #include <timer.h>
00012 #include <ic.h>
00013
00014 __BEGIN_SYS
00015
00016 class PC_Timer: public Timer_Common {
00017
00018
00019 private:
00020 typedef Traits<PC_Timer> Traits;
00021 static const Type_Id TYPE = Type<PC_Timer>::TYPE;
00022
00023 public:
00024
00025 static const int CLOCK = 1193180;
00026
00027
00028 enum {
00029 CNT_0 = 0x40,
00030 CNT_1 = 0x41,
00031 CNT_2 = 0x42,
00032 CTL = 0x43
00033 };
00034
00035
00036 enum {
00037 SELECT_MASK = 0xc0,
00038 SC0 = 0x00,
00039 SC1 = 0x40,
00040 SC2 = 0x80,
00041 RB = 0xc0,
00042 RW_MASK = 0x30,
00043 LATCH = 0x00,
00044 MSB = 0x10,
00045 LSB = 0x20,
00046 LMSB = 0x30,
00047 MODE_MASK = 0x0e,
00048 IOTC = 0x00,
00049 HROS = 0x02,
00050 RG = 0x04,
00051 CSSW = 0x06,
00052 STS = 0x08,
00053 HTS = 0x0a,
00054 COUNT_MODE_MASK = 0x01,
00055 BINARY = 0x00,
00056 BCD = 0x01,
00057 DEF_CTL_C0 = SC0 | LMSB | CSSW | BINARY,
00058 DEF_CTL_C1 = SC1 | MSB | RG | BINARY,
00059 DEF_CTL_C2 = SC2 | LMSB | CSSW | BINARY
00060 };
00061
00062
00063 enum {
00064 DEF_CNT_C0 = 0x0000,
00065 DEF_CNT_C1 = 0x0012,
00066 DEF_CNT_C2 = 0x0533,
00067 };
00068
00069 public:
00070 PC_Timer(int u = 0) {}
00071 ~PC_Timer() {}
00072
00073 Hertz frequency() {return Timer_Common::frequency();}
00074 void frequency(const Hertz & f) {
00075 unsigned short count = freq2cnt(f);
00076
00077 Timer_Common::frequency(cnt2freq(count));
00078 IA32::out8(CTL, DEF_CTL_C0);
00079 IA32::out8(CNT_0, count & 0xff);
00080 IA32::out8(CNT_0, count >> 8);
00081 db<PC_Timer>(INF) << "PC_Timer::resolution(res=" << frequency()
00082 << ",cnt=" << count << ")\n";
00083 }
00084
00085 void enable() {PC_IC::enable(PC_IC::IRQ_TIMER);}
00086 void disable() {PC_IC::disable(PC_IC::IRQ_TIMER);}
00087
00088 void reset() {
00089
00090
00091 IA32::out8(CTL, DEF_CTL_C0);
00092 unsigned short count = IA32::in8(CNT_0) | (IA32::in8(CNT_0) << 8);
00093 IA32::out8(CNT_0, count & 0xff);
00094 IA32::out8(CNT_0, count >> 8);
00095 }
00096
00097 static int init(System_Info * si);
00098
00099 private:
00100 static Hertz cnt2freq(unsigned short c) {return CLOCK / c;}
00101 static unsigned short freq2cnt(const Hertz & f) {return CLOCK / f;}
00102 };
00103
00104 __END_SYS
00105
00106 #endif