#include #include #include #include volatile uint32_t ticks = 0; volatile uint32_t clock = 0; volatile uint8_t clock_secs = 0; volatile uint8_t clock_enabled = 0; volatile uint8_t *clock_updated = NULL; volatile void (*user_fn)(void) = NULL; static _go32_dpmi_seginfo old_handler, new_handler; static void timer_handler() { ticks++; if (clock_enabled) { clock += 5494; if (clock > 100000) { clock -= 100000; if (clock_secs) { clock_secs--; if (clock_updated) *clock_updated = 1; } } } if (user_fn) user_fn(); } void timer_init() { _go32_dpmi_get_protected_mode_interrupt_vector(0x1c, &old_handler); new_handler.pm_offset = (unsigned long)timer_handler; new_handler.pm_selector = _go32_my_cs(); _go32_dpmi_chain_protected_mode_interrupt_vector(0x1c, &new_handler); } void timer_user_fn(void (*fn)(void)) { user_fn = fn; } void timer_free() { if (_go32_dpmi_set_protected_mode_interrupt_vector(0x1c, &old_handler) == -1) fprintf(stderr, "Failed to free the timer :(\n"); } void timer_start(uint8_t secs, volatile uint8_t *updated) { *updated = 0; clock_updated = updated; clock_secs = secs; clock_enabled = 1; } uint8_t timer_value() { *clock_updated = 0; return clock_secs; } void timer_stop() { clock_enabled = 0; } void timer_resume() { clock_enabled = 1; }