https://docs.mamedev.org/techspecs/memory.html#tapsI think that the thing that was confusing to me is that in my mind I established a 1:1 correspondence equivalence between the c functions and the lua functions.
When I installed a c function tap with install_write_tap (and ignoring the return value) it didn't disappear like the lua install_write_tap would.
I guess I expected them to behave in the exact same way where it would persist without any additional action.
plus when I ran "grep install_write_tap -r src" that a lot of drivers will use an install_write_tap without bothering with the return value.
Unrelated, but speaking of documentation that's a bit confusing I looked at this for an hour:
4.3.3 Lambda function
(...).lr{8,16,32,64}(NAME([...](address_space &space, offs_t offset, uNN mem_mask) -> uNN { ... }))
(...).lr{8,16,32,64}([...](address_space &space, offs_t offset, uNN mem_mask) -> uNN { ... }, "name")
(...).lw{8,16,32,64}(NAME([...](address_space &space, offs_t offset, uNN data, uNN mem_mask) -> void { ... }))
(...).lw{8,16,32,64}([...](address_space &space, offs_t offset, uNN data, uNN mem_mask) -> void { ... }, "name")
(...).lrw{8,16,32,64}(NAME(read), NAME(write))
(...).lrw{8,16,32,64}(read, "name_r", write, "name_w")
and I couldn't figure out what the last two meant...
(...).lrw{8,16,32,64}(NAME(read), NAME(write))
(...).lrw{8,16,32,64}(read, "name_r", write, "name_w")
then I finally realized they're just variations of the first 4, where lr and lw combined into one lrw.
The pattern for the last two doesn't match the pattern given for the first 4 (which of course is easy to spot if you know what you're looking at).
If it said "NAME(<read_function>), NAME(<write_function>)" that would have helped.
(that's what happens when you read documentation at 2am)