| The Hobbit (v1.0) | Routines |
| Prev: 768E | Up: Map | Next: 7754 |
|
Prints one character in the story window, which fills the upper part of the screen and uses the game's own 6-pixel font (77BC). The screen address is kept at $768F, the pixel offset within the byte at $7691, and the number of characters left on the line at 768E (42 per line).
Letters are converted to lower case, except that the first letter after a full stop or a new line is capitalised: the flag at $B5F5 is set by those, and cleared once a capital has been printed. This is why the game's text needs no capital letters in the dictionary.
A carriage return sends the finished line to the ZX Printer if it is switched on (7B15), then scrolls the story window up (775E) and starts a new line. Before scrolling, the game checks the line counter at B606, which is set to 9 each time the player enters a command: after that many lines, each further line waits (for about half a second, or until a key is pressed) so that long bursts of text do not rush past unread. A key held down at that point has to be released before the text continues.
A backspace moves back 6 pixels (7754) and rubs out the character there. A full line wraps automatically.
If $7692 is non-zero, that many spaces are printed at the start of the line first (an indent). This is the routine I used as a hook in the emulator to capture everything the game printed.
|
||||||||
| 7694 | PUSH HL | Save the registers this uses | ||||||
| 7695 | PUSH BC | |||||||
| 7696 | PUSH AF | |||||||
| 7697 | LD HL,($768F) | HL = the current print position on screen | ||||||
| 769A | LD A,($7691) | C = the pixel offset within that screen byte | ||||||
| 769D | LD C,A | |||||||
| 769E | LD A,($7693) | Has a capital letter already been printed since the last full stop or new line? | ||||||
| 76A1 | AND A | |||||||
| 76A2 | JR NZ,$76B9 | Yes: no indent needed | ||||||
| 76A4 | LD A,($7692) | Is an indent wanted at the start of this line (e.g. for a container's contents)? | ||||||
| 76A7 | AND A | |||||||
| 76A8 | JR Z,$76B9 | No: skip straight to printing the character below | ||||||
| 76AA | LD B,A | B = how many indent spaces | ||||||
| 76AB | LD A,$20 | Draw a space... | ||||||
| 76AD | CALL $77BC | |||||||
| 76B0 | LD A,($768E) | One less character of room on this line now | ||||||
| 76B3 | DEC A | |||||||
| 76B4 | LD ($768E),A | |||||||
| 76B7 | DJNZ $76AB | Repeat for the whole indent | ||||||
| 76B9 | POP AF | Restore the actual character to print | ||||||
| 76BA | PUSH AF | |||||||
| 76BB | CP $0D | Is it a new line? | ||||||
| 76BD | JR NZ,$7700 | |||||||
| 76BF | LD A,$01 | Yes: the very next character printed should get a capital letter | ||||||
| 76C1 | LD ($B5F5),A | |||||||
| 76C4 | XOR A | No capital has been printed yet on this new line | ||||||
| 76C5 | LD ($7693),A | |||||||
| 76C8 | CALL $7B15 | Send the finished line to the ZX Printer, if it is switched on | ||||||
| 76CB | PUSH BC | Save the pixel offset | ||||||
| 76CC | LD A,($B606) | How many more lines can be printed before pausing for a key? | ||||||
| 76CF | AND A | |||||||
| 76D0 | JR NZ,$76E6 | Some left: just count one down below | ||||||
| 76D2 | LD BC,$8000 | None left: wait for a key, but time out eventually rather than freeze forever | ||||||
| 76D5 | XOR A | |||||||
| 76D6 | IN A,($FE) | Is a key being pressed right now? | ||||||
| 76D8 | AND $1F | |||||||
| 76DA | CP $1F | |||||||
| 76DC | JR NZ,$76EA | Yes: stop waiting | ||||||
| 76DE | DEC BC | No: count down the timeout | ||||||
| 76DF | LD A,B | |||||||
| 76E0 | OR C | |||||||
| 76E1 | JR NZ,$76D5 | |||||||
| 76E3 | POP BC | Timed out: give up waiting | ||||||
| 76E4 | JR $76F4 | |||||||
| 76E6 | DEC A | Still some lines left before a pause: one fewer | ||||||
| 76E7 | LD ($B606),A | |||||||
| 76EA | POP BC | Restore the pixel offset | ||||||
| 76EB | XOR A | Wait here until a key really is pressed | ||||||
| 76EC | IN A,($FE) | |||||||
| 76EE | AND $1F | |||||||
| 76F0 | CP $1F | |||||||
| 76F2 | JR NZ,$76EB | |||||||
| 76F4 | LD HL,$5020 | Back to the top of the story window | ||||||
| 76F7 | LD C,$01 | |||||||
| 76F9 | CALL $775E | Scroll it up one line | ||||||
| 76FC | LD A,$2A | Start the new line with a fresh indent marker | ||||||
| 76FE | JR $7746 | |||||||
| 7700 | CP $08 | Is it a backspace? | ||||||
| 7702 | JR NZ,$7715 | |||||||
| 7704 | CALL $7754 | Move the print position back one character... | ||||||
| 7707 | LD A,$20 | ...draw a space over what was there... | ||||||
| 7709 | CALL $77BC | |||||||
| 770C | CALL $7754 | ...then move back again, ready for whatever comes next | ||||||
| 770F | LD A,($768E) | One more character of room on the line | ||||||
| 7712 | INC A | |||||||
| 7713 | JR $7746 | |||||||
| 7715 | CP $41 | Is it an upper-case letter? | ||||||
| 7717 | JR C,$771F | |||||||
| 7719 | CP $5B | |||||||
| 771B | JR NC,$771F | |||||||
| 771D | OR $20 | Yes: make it lower case, since the story window's own text is always in lower case | ||||||
| 771F | PUSH HL | Save HL | ||||||
| 7720 | LD HL,$B5F5 | Should THIS letter be a capital instead (the "start a new sentence" flag)? | ||||||
| 7723 | INC (HL) | |||||||
| 7724 | DEC (HL) | |||||||
| 7725 | JR Z,$7733 | No: leave it as it is | ||||||
| 7727 | CP $61 | Is it actually a lower-case letter that could be capitalised? | ||||||
| 7729 | JR C,$7733 | |||||||
| 772B | CP $7B | |||||||
| 772D | JR NC,$7733 | |||||||
| 772F | RES 5,A | Yes: make it upper case | ||||||
| 7731 | LD (HL),$00 | The "next letter gets a capital" flag has now been used up | ||||||
| 7733 | CP $2E | Is this character a full stop? | ||||||
| 7735 | JR NZ,$7738 | |||||||
| 7737 | INC (HL) | If so, arrange for the very next letter to be capitalised | ||||||
| 7738 | POP HL | Restore HL | ||||||
| 7739 | CALL $77BC | Draw the character itself | ||||||
| 773C | LD ($7693),A | Remember that something has now been printed on this line, so no further indent is added | ||||||
| 773F | LD A,($768E) | One less character of room on the line | ||||||
| 7742 | DEC A | |||||||
| 7743 | JP Z,$76C4 | None left: treat it as if a new line had just been reached, to wrap and scroll | ||||||
| 7746 | LD ($768E),A | Save the room left on the line | ||||||
| 7749 | LD ($768F),HL | Save the new print position | ||||||
| 774C | LD A,C | Save the new pixel offset | ||||||
| 774D | LD ($7691),A | |||||||
| 7750 | POP AF | Restore AF, BC and HL | ||||||
| 7751 | POP BC | |||||||
| 7752 | POP HL | |||||||
| 7753 | RET | |||||||
| Prev: 768E | Up: Map | Next: 7754 |