On first glance, Regz generated output seems to be tightly coupled to Microzig because it imports microzig:
// At the top of generated files:
const microzig = @import("microzig");
const mmio = microzig.mmio;
pub const types = @import("types.zig");
// ...
pub const VectorTable = extern struct {
const Handler = microzig.interrupt.Handler;
const unhandled = microzig.interrupt.unhandled;
initial_stack_pointer: *const anyopaque,
Reset: Handler,
NMI: Handler = unhandled,
HardFault: Handler = unhandled,
MemManageFault: Handler = unhandled,
BusFault: Handler = unhandled,
UsageFault: Handler = unhandled,
// ...
};
But this is not the case. Yes, microzig is in there by name, but one can import a module of their creation with the name microzig. All that’s need are some declarations:
mmio.Mmio: compile-time wrapper for our MMIO abstraction.interrupt.Handler: Handler function type for your target’s interrupt service routines.interrupt.unhandled: Default interrupt service routine.
We did this this way so that one day someone could rewire some other MMIO layer, perhaps one with logging, or for simulation. We currently switch out the interrupt declarations depending on the target hardware.
You can find the mmio.zig implementation for MicroZig here, and it should be easy enough to find the interrupt declarations for your target using search.
If the directions here for overloading an import are alien to you, the ZSF has a great guide on how the build system works.