User Tools

Site Tools


wswan:guide:interrupt_handlers

Writing interrupt handlers

C interrupt handlers

For less performance-sensitive interrupts (such as the vertical blank interrupt), it is possible to write the relevant handlers using only C. This is done by marking the interrupt function with special attributes:

__attribute__((assume_ss_data, interrupt))
void __far vblank_int_handler(void) {
    vbl_ticks++;
    
    // Acknowledge the hardware interrupt.
    ws_hwint_ack(HWINT_VBLANK);
}

These mean the following:

  • __far - This function is always a “far” call. This is required for interrupt functions - while all functions are “far” calls by default on wswan/medium, this is not true on other subtargets.
  • interrupt - This function is an interrupt. This ensures it saves/restores all registers and that it uses IRET to return from the function.
  • assume_ss_data - This function can assume that SS points to the default data segment when it is called. This assumption holds true throughout the Wonderful toolchain's default libraries. However, beware that any assembler code which modifies the location of the stack segment SS must ensure that an interrupt function with this attribute is never called during its execution.

Configuring interrupt handlers

libws provides useful functions for configuring interrupt handlers:

// Set the function "vblank_int_handler" to run during vertical blank.
ws_hwint_set_handler(HWINT_IDX_VBLANK, (ws_int_handler_t) vblank_int_handler);

// Enable the vertical blank hardware interrupt.
ws_hwint_enable(HWINT_VBLANK);

// Disable the vertical blank hardware interrupt.
ws_hwint_disable(HWINT_VBLANK);

Watch out! ws_hwint_set_handler expects a HWINT_IDX parameter, while most other ws_hwint operations - enable, disable, ack - expect a HWINT parameter.

I admit, this is a little confusing. ^^;

wswan/guide/interrupt_handlers.txt · Last modified: 2024/02/18 08:32 by asie