Prev: 9CEC Up: Map Next: 9D2E
9D12: Search a table of 3-byte entries
Searches a table at IX made of 3-byte entries, each a one-byte key followed by a two-byte value, for the key in A. The table ends with $FF. Returns with IX pointing at the matching entry if found, or at the terminating $FF entry if not. The flags are set by a final CP $FF on the entry's own key: Z is SET when that key is $FF, so Z RESET (NZ) means the search succeeded and Z SET means it ran off the end without a match; equivalently, the carry flag is SET when the entry was found. This is easy to get backwards, so callers are shown branching on NZ/carry for success and Z for failure throughout this disassembly. Used for the object index (BF53), the room-entry handlers (C67D) and several other tables.
Input
A Key
IX Table
Output
IX Matching entry, or the $FF terminator
F Z SET if not found (end of table); NZ or carry set if found
9D12 EXX Switch to the alternate registers, so this search does not disturb the caller's own BC, DE and HL
9D13 PUSH IX HL = the table to search, taken from IX
9D15 POP HL
9D16 LD B,A B = the key being searched for
9D17 LD E,$03 DE = 3: the size of one entry, ready for stepping through the table
9D19 LD D,$00
9D1B LD A,(HL) A = this entry's key
9D1C CP B Does it match what we are looking for?
9D1D JR Z,$9D27 Yes: stop here, with this entry found
9D1F CP $FF No: is this the table's $FF terminator, meaning there are no more entries?
9D21 JR Z,$9D27 Yes: stop here too, empty-handed
9D23 ADD HL,DE Neither: move on to the next entry
9D24 JP $9D1B ...and keep looking
9D27 PUSH HL Whichever way we stopped, move the address we ended up at into IX...
9D28 POP IX ...for the caller to use
9D2A CP $FF Was that the $FF terminator (not found), or a genuine entry (found)? Z ends up SET when NOT found, so the caller should test NZ, or the carry flag, for success
9D2C EXX Switch back to the caller's own registers
9D2D RET
Prev: 9CEC Up: Map Next: 9D2E