Looks like we've essentially done the same thing, I guess there's only so many ways to skin this particular cat
/////////////////////////////////////////////////////////////////////
//
// Function name: PIOINTx_IRQHandler
//
// Description: Replacement for the default PORT0 interrupt handler.
//
// Parameters: none
//
// Returned value: none
//
// Errors raised: none
//
// Notes: The code has to determine the pin that caused the interrupt.
// This is done by scanning the value in the MIS register
// looking for a 1 bit. When found the corresponding user handler
// is called if it exists.
//
// Whether or not the user handler exists the interrupt is cleared.
//
// Only a single interrupt at a time is called so an active pin
// cannot hog the system. This is implemented by maintaining a
// counter across invocations so for example if pin 4 is handled
// this time the scan starts from pin 5 next time.
//
// This method however has a side effect of increasing the latency
// considerably in systems that only have 1 or 2 external interrupts,
// for example after handling a pin 4 interrupt the next invocation
// has to scan 31 bits before arriving back at pin 4.
//
// This is largely reduced by writing 0 to the __force_interrupt_scan
// variable. In this case the next scan starts from the pin the
// last scan ended on.
//
// TODO: Implement a scan range to further reduce latency.
//
// Example:
//
void PIOINT0_IRQHandler() {
static uint8 pin = 0;
ATOMIC_START;
uint8 x = PINS_ON_PORT0;
uint32 misVal = LPC_GPIO0->MIS; // get the masked interrupt flags for this port
do {
if (misVal & 1) {
////////////////////////////////////////////////
// Check for a user-defined handler, if one exists
// then call it, clear the interrupt, increment the
// pin counter and exit
if (eventFunctions[EVENT_PININT_0 + pin] != NULL) {
(eventFunctions[EVENT_PININT_0 + pin]) ();
pinClearInterrupt(pin);
pin = (pin > PINS_ON_PORT0 ? 0 : pin + __force_interrupt_scan);
ATOMIC_END;
return;
}
/////////////////////////////////////////////////
// Clear the interrupt, if no user handler was called
// the interrupt is lost.
pinClearInterrupt(pin);
}
pin = (pin > PINS_ON_PORT0 ? 0 : pin +1);
misVal >>= 1;
} while (--x);
ATOMIC_END;
}
One difference is that I only allow the servicing of one interrupt per invocation, I'm not convinced that a good idea or not yet

There's a big difference in our attachInterrupt() functions though
void attachInterrupt (uint8_t pin, void (*func)(void), int mode) {
switch (mode) {
case LOW:
pinSetInterruptMode(pin, PININT_LOW_LEVEL);
break;
case CHANGE:
pinSetInterruptMode(pin, PININT_BOTH_EDGES);
break;
case FALLING:
pinSetInterruptMode(pin, PININT_FALLING_EDGE);
break;
case RISING:
pinSetInterruptMode(pin, PININT_RISING_EDGE);
break;
}
attachEventHandler(EVENT_PININT_0 + pin, func);
pinEnableInterrupt(pin);
}
Although I suspect that if I inserted the code from the function calls they would be similar. Note that this is a function that's part of my Arduino port, it maps the Arduino call to my LPC equivalent, that's really why there's no real work done here.
I work with a flat model of the pins, at this level I don't care what port they are on or anything. Also I'm implementing a system of "events" whereby everything that happens on the system is an event that can have a user function supplied if required. Pin interrupts are simply another 55 events.
______
Rob