/** * PIT (Programmable Interval Timer) functionality. */ module hulk.pit; import hulk.cpu; import hulk.klog; import hulk.console; struct Pit { /** PIT input frequency in 1/1000 Hz. */ private enum ulong PIT_FREQUENCY_1000HZ = 1_193_181_667u; private enum ulong TARGET_INTERRUPT_HZ = 1000u; private enum ulong TARGET_INTERRUPT_1000HZ = TARGET_INTERRUPT_HZ * 1000u; private enum ulong PIT_DIVIDER = (PIT_FREQUENCY_1000HZ + TARGET_INTERRUPT_1000HZ / 2u) / TARGET_INTERRUPT_1000HZ; /** PIT channel 0 I/O port. */ private enum ubyte PORT_CH_0 = 0x40u; /** PIT channel 1 I/O port. */ private enum ubyte PORT_CH_1 = 0x41u; /** PIT channel 2 I/O port. */ private enum ubyte PORT_CH_2 = 0x42u; /** PIT mode/command register I/O port. */ private enum ubyte PORT_MC = 0x43u; private enum ubyte MC_CH_0 = 0x00u; private enum ubyte MC_LO_HI = 0x30u; private enum ubyte MC_RATE_GENERATOR = 0x04u; private enum ubyte MC_BINARY = 0x00u; private static __gshared ulong milliseconds; public static void initialize() { Klog.writefln("\a3Initializing PIT"); out8(PORT_MC, MC_CH_0 | MC_LO_HI | MC_RATE_GENERATOR | MC_BINARY); out8(PORT_CH_0, PIT_DIVIDER & 0xFFu); out8(PORT_CH_0, PIT_DIVIDER >> 8u); } public static void isr() { milliseconds++; } }