40 minutes ago, rje said:
You're right - I could just use MEMTOP and check the accumulator. I did it brute force instead, which might actually not work in real life if the X16 doesn't do RAM mirroring.
Your thinking isn't far off though. You can see how KERNAL does it
here. The biggest difference between your implementation and KERNAL is that you use the random number 17 and KERNAL uses the random number "1 + whatever is in $a000 of bank 0". If I'm reading the code correctly, KERNAL is making the optimization assumption that the number of banks will always be a power of 2 since the loop uses the accumulator to select the bank and modifies the accumulator with asl. If loop #7 passes (testing bank #128) it calls memtop with 0 in A, which I guess means 256 banks (2 MB).
2 hours ago, desertfish said:
For what I can see, it is not mirrored via a vector in ram. The entry at $ff99 in the kernal's jump table directly jmps to another location in rom, instead of doing a vectored (indirect) jmp. Indeed a handful of kernal routines do the vectoring (not many, tbh), but MEMTOP isn't among those. Does this matter?
It is stored in the KERNAL variable area (KVAR segment, which is $0200-$02BA I think) but you'd probably need to look at the assembler map file to know where. Most importantly though: doing so would be a bad idea. There is nothing that says the location is guaranteed to be the same across all releases of KERNAL. MEMTOP is guaranteed to always return the correct value.