| The Hobbit (v1.0) | Routines |
| Prev: 6E82 | Up: Map | Next: 6F27 |
|
The tokeniser. Starting at HL in the input buffer, it skips spaces, finds the next word or punctuation mark, and returns its class in A and a two-byte token in B (high) and C (low). HL is left after the word, ready for the next call. The address of the start of the word is stored at B5CB so that an 'I don't know the word' message can quote it.
The search works like this:
1. 6F3E copies the typed letters (keeping only their low five bits, so case does not matter) into the buffer at 7071 and their count into 7081. It then uses the letter index at 6000 to find the first dictionary word beginning with the same letter, and unpacks that word into the buffer at 7082 (count in 7092). If there are no words for that letter, the word is unknown.
2. 6FB1 compares the typed letters with the dictionary word, over the length of the shorter of the two.
3. If they differ, 6F69 unpacks the next word in the dictionary and the comparison is repeated. The search gives up (unknown word) as soon as it reaches a word with a different first letter.
4. If they agree, the lengths decide (6EB7). If the dictionary word is at least as long as what was typed, it is accepted. So any abbreviation matches the first word that starts with those letters: this is why N means NORTH, but also why EX finds EXAMINE and not EXCEPT. If the player typed MORE letters than the dictionary word has, and the dictionary word is 1-3 letters long, it is rejected and the search moves on (so typing EASTWARD does not match E). If the dictionary word is 4 letters or longer, the game looks at the following dictionary word (6F6D, without moving the current position); if that one also matches the typed letters, the search moves on to it, otherwise the current word is accepted. So extra letters after a long enough word are ignored: SWORDS finds SWORD, and TROLLS finds TROLLS rather than TROLL.
5. For the accepted word (6EE2), the end of the word is found. If bit 6 of the last letter is set, the word is a synonym and the next two bytes give the offset of the real word; HL is switched to that word, so for example HIT is returned as ATTACK. The class is then assembled from bits 5 and 6 of the real word's first two bytes (see 6040), and $A000 is added to the word's address to turn it into an offset from 6000 (because 6000 + $A000 = $10000).
|
|||||||||||||||||||||||||||||||||||||
| 6E8E | PUSH DE | Save DE | |||||||||||||||||||||||||||||||||||
| 6E8F | LD A,(HL) | Skip spaces | |||||||||||||||||||||||||||||||||||
| 6E90 | INC HL | Increment HL | |||||||||||||||||||||||||||||||||||
| 6E91 | CP $20 | Is it " "? | |||||||||||||||||||||||||||||||||||
| 6E93 | JR Z,$6E8F | If yes, go to 6E8F | |||||||||||||||||||||||||||||||||||
| 6E95 | DEC HL | Decrement HL | |||||||||||||||||||||||||||||||||||
| 6E96 | LD ($B5CB),HL | Remember where the word starts | |||||||||||||||||||||||||||||||||||
| 6E99 | CP $0D | End of the line? | |||||||||||||||||||||||||||||||||||
| 6E9B | JR Z,$6ED5 | If yes, go to 6ED5 | |||||||||||||||||||||||||||||||||||
| 6E9D | CALL $6F27 | Punctuation? | |||||||||||||||||||||||||||||||||||
| 6EA0 | JR Z,$6EDA | If the routine returned with Z set, go to 6EDA | |||||||||||||||||||||||||||||||||||
| 6EA2 | CALL $6F3E | Copy the typed word and find the first dictionary word with the same first letter | |||||||||||||||||||||||||||||||||||
| 6EA5 | JR NZ,$6EB3 | No words start with this letter: unknown word | |||||||||||||||||||||||||||||||||||
| 6EA7 | PUSH HL | Save HL | |||||||||||||||||||||||||||||||||||
| 6EA8 | CALL $6FB1 | Compare the typed word with the dictionary word | |||||||||||||||||||||||||||||||||||
| 6EAB | JR Z,$6EB7 | If the routine returned with Z set, go to 6EB7 | |||||||||||||||||||||||||||||||||||
| 6EAD | CALL $6F69 | Different: try the next dictionary word | |||||||||||||||||||||||||||||||||||
| 6EB0 | JR Z,$6EA8 | If the routine returned with Z set, go to 6EA8 | |||||||||||||||||||||||||||||||||||
| 6EB2 | POP HL | Restore HL | |||||||||||||||||||||||||||||||||||
| 6EB3 | LD A,$D0 | Class $D0: unknown word | |||||||||||||||||||||||||||||||||||
| 6EB5 | JR $6ED7 | Continue at 6ED7 | |||||||||||||||||||||||||||||||||||
| 6EB7 | LD A,($7081) | Letters agree. Is the dictionary word at least as long as the typed word? | |||||||||||||||||||||||||||||||||||
| 6EBA | LD B,A | B = A | |||||||||||||||||||||||||||||||||||
| 6EBB | LD A,($7092) | A = the dictionary word length | |||||||||||||||||||||||||||||||||||
| 6EBE | CP B | Compare with B | |||||||||||||||||||||||||||||||||||
| 6EBF | JR NC,$6EE2 | If carry clear, go to 6EE2 | |||||||||||||||||||||||||||||||||||
| 6EC1 | CP $04 | No: reject dictionary words of 1-3 letters | |||||||||||||||||||||||||||||||||||
| 6EC3 | JR C,$6EAD | If A < 4, go to 6EAD | |||||||||||||||||||||||||||||||||||
| 6EC5 | PUSH IX | Save IX | |||||||||||||||||||||||||||||||||||
| 6EC7 | CALL $6F6D | Otherwise, does the next dictionary word also fit? | |||||||||||||||||||||||||||||||||||
| 6ECA | JR NZ,$6EE0 | If the routine returned with Z reset, go to 6EE0 | |||||||||||||||||||||||||||||||||||
| 6ECC | CALL $6FB1 | Call: Compare the typed word with a dictionary word (6FB1) | |||||||||||||||||||||||||||||||||||
| 6ECF | JR NZ,$6EE0 | If the routine returned with Z reset, go to 6EE0 | |||||||||||||||||||||||||||||||||||
| 6ED1 | POP IX | Restore IX | |||||||||||||||||||||||||||||||||||
| 6ED3 | JR $6EAD | Continue at 6EAD | |||||||||||||||||||||||||||||||||||
| 6ED5 | LD A,$C0 | End of line: class $C0 | |||||||||||||||||||||||||||||||||||
| 6ED7 | LD BC,$0000 | BC = 0 | |||||||||||||||||||||||||||||||||||
| 6EDA | POP DE | Put the class into the top of B and return it in A | |||||||||||||||||||||||||||||||||||
| 6EDB | LD D,A | D = A | |||||||||||||||||||||||||||||||||||
| 6EDC | ADD A,B | Add A,B | |||||||||||||||||||||||||||||||||||
| 6EDD | LD B,A | B = A | |||||||||||||||||||||||||||||||||||
| 6EDE | LD A,D | A = D | |||||||||||||||||||||||||||||||||||
| 6EDF | RET | Done | |||||||||||||||||||||||||||||||||||
| 6EE0 | POP IX | Restore IX | |||||||||||||||||||||||||||||||||||
| 6EE2 | LD IX,($B607) | Accept the dictionary word at (B607): find its last letter | |||||||||||||||||||||||||||||||||||
| 6EE6 | PUSH IX | Save IX | |||||||||||||||||||||||||||||||||||
| 6EE8 | XOR A | A = 0 | |||||||||||||||||||||||||||||||||||
| 6EE9 | INC IX | Increment IX | |||||||||||||||||||||||||||||||||||
| 6EEB | INC A | Increment A | |||||||||||||||||||||||||||||||||||
| 6EEC | BIT 7,(IX-$01) | Test bit 7 of (IX-$01) | |||||||||||||||||||||||||||||||||||
| 6EF0 | JR Z,$6EE9 | If the bit is clear, go to 6EE9 | |||||||||||||||||||||||||||||||||||
| 6EF2 | CP $02 | Compare with 2 | |||||||||||||||||||||||||||||||||||
| 6EF4 | JR Z,$6EE9 | If yes, go to 6EE9 | |||||||||||||||||||||||||||||||||||
| 6EF6 | CP $03 | Compare with 3 | |||||||||||||||||||||||||||||||||||
| 6EF8 | JR NZ,$6F00 | If no, go to 6F00 | |||||||||||||||||||||||||||||||||||
| 6EFA | BIT 7,(IX-$02) | Test bit 7 of (IX-$02) | |||||||||||||||||||||||||||||||||||
| 6EFE | JR NZ,$6EE9 | If the bit is set, go to 6EE9 | |||||||||||||||||||||||||||||||||||
| 6F00 | BIT 6,(IX-$01) | Is it a synonym? | |||||||||||||||||||||||||||||||||||
| 6F04 | JR Z,$6F11 | If the bit is clear, go to 6F11 | |||||||||||||||||||||||||||||||||||
| 6F06 | LD L,(IX+$00) | Yes: switch to the word it stands for | |||||||||||||||||||||||||||||||||||
| 6F09 | LD H,(IX+$01) | H = (IX+1) | |||||||||||||||||||||||||||||||||||
| 6F0C | LD DE,$6000 | DE = Dictionary letter index (6000) | |||||||||||||||||||||||||||||||||||
| 6F0F | ADD HL,DE | Add HL,DE | |||||||||||||||||||||||||||||||||||
| 6F10 | EX (SP),HL | Swap HL with the value on top of the stack | |||||||||||||||||||||||||||||||||||
| 6F11 | POP HL | Restore HL | |||||||||||||||||||||||||||||||||||
| 6F12 | LD A,(HL) | Build the class from bits 5-6 of the first two bytes | |||||||||||||||||||||||||||||||||||
| 6F13 | RLCA | Rotate A left | |||||||||||||||||||||||||||||||||||
| 6F14 | AND $C0 | Keep only the bits of $C0 | |||||||||||||||||||||||||||||||||||
| 6F16 | LD B,A | B = A | |||||||||||||||||||||||||||||||||||
| 6F17 | INC HL | Increment HL | |||||||||||||||||||||||||||||||||||
| 6F18 | LD A,(HL) | A = (HL) | |||||||||||||||||||||||||||||||||||
| 6F19 | RRCA | Rotate A right | |||||||||||||||||||||||||||||||||||
| 6F1A | AND $30 | Keep only the bits of $30 | |||||||||||||||||||||||||||||||||||
| 6F1C | ADD A,B | Add A,B | |||||||||||||||||||||||||||||||||||
| 6F1D | DEC HL | Decrement HL | |||||||||||||||||||||||||||||||||||
| 6F1E | LD DE,$A000 | Turn the address into an offset from 6000 | |||||||||||||||||||||||||||||||||||
| 6F21 | ADD HL,DE | Add HL,DE | |||||||||||||||||||||||||||||||||||
| 6F22 | PUSH HL | Save HL | |||||||||||||||||||||||||||||||||||
| 6F23 | POP BC | Restore BC | |||||||||||||||||||||||||||||||||||
| 6F24 | POP HL | Restore HL | |||||||||||||||||||||||||||||||||||
| 6F25 | JR $6EDA | Continue at 6EDA | |||||||||||||||||||||||||||||||||||
| Prev: 6E82 | Up: Map | Next: 6F27 |