No, there is no ingenious absolutely sure way to check if a vector is free.
This is because every of the possible 232 values for an interrupt is potentially a valid value.
Some value can be very suspicious, yet valid:
- 0ffffh:0ffffh can be valid (pointing to 0ffefh with the A20 masked).
- 0000h:0000h can be valid, even on vector 0. A DWORD of value zero decodes to a pair of
add [bx+si], al
which are valid.
- 0b800h:0000h and other similar ROM addresses can be valid as expansion ROMs can be used to carry code. Though it's unlikely that the standard video memory will.
- Addresses in reserved BIOS areas, like (E)BDA, can be valid in theory if the data is specially crafted to be both valid code and valid info.
Of course some of the above are very stretched and involve having data executed as code, but the main reason you should not trust vector pointers is that the BIOS is likely to fill every vector slot with at least a dummy ISR.
This won't let an unintentionally bad crafted int
instruction hang the system.
There are a couple of things you could do:
Chaining
Pick a not overcrowded interrupt number N. Pick up a set of input values I not yet used (say AH=d0-ff). Attach your ISR to N and handle only those I values, delegating the other inputs to the previous ISR.
Target a specific platform
Some interrupt vectors, like int EA, are used only in specific systems. Since most of those systems are gone, you can reclaim their interrupts.
If you steal an interrupt vector and everything keeps working and nobody is complaining, then it's your interrupt. Just double check the premises.
Use interrupt 2F
The Int 2F and its variant Alternate Multiplex Interrupt Specification (AMIS) at Int 2D can be used as a shared/multiplexed interrupt.
The AMIS did not gain much popularity however.
Try to find an empty spot anyway
As a first attempt you can try to search for null entries1 in the IVT, though valid in theory, they are likely empty slots.
You can also try to find a pointer that is present more than one or two times, suggesting the presence of a dummy ISR (as an ISR cannot identify its vector number easily).
I would go with n. 1 personally, if not possible I would implement n. 3. If not possible I would use n. 4 with fallback to n. 2.
1 Catching all the "suspicious" values is impractical and would only give a little gain, so just shoot for the big ones.