1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 #ifndef GLK_FROTZ_PROCESSOR 24 #define GLK_FROTZ_PROCESSOR 25 26 #include "glk/frotz/mem.h" 27 #include "glk/frotz/glk_interface.h" 28 #include "glk/frotz/frotz_types.h" 29 #include "common/stack.h" 30 31 namespace Glk { 32 namespace Frotz { 33 34 #define TEXT_BUFFER_SIZE 200 35 36 #define CODE_BYTE(v) v = codeByte() 37 #define CODE_WORD(v) v = codeWord() 38 #define CODE_IDX_WORD(v,i) v = codeWordIdx(i) 39 #define GET_PC(v) v = getPC() 40 #define SET_PC(v) setPC(v) 41 42 enum string_type { 43 LOW_STRING, ABBREVIATION, HIGH_STRING, EMBEDDED_STRING, VOCABULARY 44 }; 45 46 class Processor; 47 class Quetzal; 48 typedef void (Processor::*Opcode)(); 49 50 /** 51 * Zcode processor 52 */ 53 class Processor : public GlkInterface, public virtual Mem { 54 friend class Quetzal; 55 private: 56 static const char *const ERR_MESSAGES[ERR_NUM_ERRORS]; 57 static Opcode var_opcodes[64]; 58 static Opcode ext_opcodes[64]; 59 Common::Array<Opcode> op0_opcodes; 60 Common::Array<Opcode> op1_opcodes; 61 62 int _finished; 63 zword zargs[8]; 64 int zargc; 65 uint _randomInterval; 66 uint _randomCtr; 67 bool first_restart; 68 bool script_valid; 69 70 // Stack data 71 zword _stack[STACK_SIZE]; 72 zword *_sp; 73 zword *_fp; 74 zword _frameCount; 75 76 // Text related fields 77 static zchar ZSCII_TO_LATIN1[]; 78 zchar *_decoded, *_encoded; 79 int _resolution; 80 int _errorCount[ERR_NUM_ERRORS]; 81 82 // Buffer related fields 83 bool _locked; 84 zchar _prevC; 85 zchar _buffer[TEXT_BUFFER_SIZE]; 86 size_t _bufPos; 87 88 // Stream related fields 89 int script_width; 90 strid_t sfp, rfp, pfp; 91 bool ostream_screen; 92 bool ostream_script; 93 bool ostream_memory; 94 bool ostream_record; 95 bool istream_replay; 96 bool message; 97 Common::FixedStack<Redirect, MAX_NESTING> _redirect; 98 protected: 99 /** 100 * \defgroup General support methods 101 * @{ 102 */ 103 104 /** 105 * Load an operand, either a variable or a constant. 106 */ 107 void load_operand(zbyte type); 108 109 /** 110 * Given the operand specifier byte, load all (up to four) operands 111 * for a VAR or EXT opcode. 112 */ 113 void load_all_operands(zbyte specifier); 114 115 /** 116 * Call a subroutine. Save PC and FP then load new PC and initialise 117 * new stack frame. Note that the caller may legally provide less or 118 * more arguments than the function actually has. The call type "ct" 119 * can be 0 (z_call_s), 1 (z_call_n) or 2 (direct call). 120 */ 121 void call(zword routine, int argc, zword *args, int ct); 122 123 /** 124 * Return from the current subroutine and restore the previous _stack 125 * frame. The result may be stored (0), thrown away (1) or pushed on 126 * the stack (2). In the latter case a direct call has been finished 127 * and we must exit the interpreter loop. 128 */ 129 void ret(zword value); 130 131 /** 132 * Take a jump after an instruction based on the flag, either true or 133 * false. The branch can be short or long; it is encoded in one or two 134 * bytes respectively. When bit 7 of the first byte is set, the jump 135 * takes place if the flag is true; otherwise it is taken if the flag 136 * is false. When bit 6 of the first byte is set, the branch is short; 137 * otherwise it is long. The offset occupies the bottom 6 bits of the 138 * first byte plus all the bits in the second byte for long branches. 139 * Uniquely, an offset of 0 means return false, and an offset of 1 is 140 * return true. 141 */ 142 void branch(bool flag); 143 144 /** 145 * Store an operand, either as a variable or pushed on the stack. 146 */ 147 void store(zword value); 148 149 /* 150 * Call the interpreter loop directly. This is necessary when 151 * 152 * - a sound effect has been finished 153 * - a read instruction has timed out 154 * - a newline countdown has hit zero 155 * 156 * The interpreter returns the result value on the stack. 157 */ 158 int direct_call(zword addr); 159 160 /** 161 * Set the seed value for the random number generator. 162 */ 163 void seed_random(int value); 164 165 /**@}*/ 166 167 /** 168 * \defgroup Input support methods 169 * @{ 170 */ 171 172 /** 173 * High level output function. 174 */ 175 void print_char(zchar c); 176 177 /** 178 * Print a string of ASCII characters. 179 */ 180 void print_string(const char *s); 181 182 /** 183 * Print an unsigned 32bit number in decimal or hex. 184 */ 185 void print_long(uint value, int base); 186 187 /** 188 * High level newline function. 189 */ 190 void new_line(); 191 192 /** 193 * Copy the contents of the text buffer to the output streams. 194 */ 195 void flush_buffer(); 196 197 /** 198 * Returns true if the buffer is empty 199 */ bufferEmpty()200 bool bufferEmpty() const { return !_bufPos; } 201 202 /** 203 * An error has occurred. Ignore it, pass it to os_fatal or report 204 * it according to err_report_mode. 205 * @param errNum Numeric code for error (1 to ERR_NUM_ERRORS) 206 */ 207 void runtimeError(ErrorCode errNum); 208 209 /**@}*/ 210 211 /** 212 * \defgroup Input support methods 213 * @{ 214 */ 215 216 /** 217 * Check if the given key is an input terminator. 218 */ 219 bool is_terminator(zchar key); 220 221 /** 222 * Ask the user a question; return true if the answer is yes. 223 */ 224 bool read_yes_or_no(const char *s); 225 226 /** 227 * Read a string from the current input stream. 228 */ 229 void read_string(int max, zchar *buffer); 230 231 /** 232 * Ask the user to type in a number and return it. 233 */ 234 int read_number(); 235 236 /**@}*/ 237 238 /** 239 * \defgroup Memory support methods 240 * @{ 241 */ 242 243 /** 244 * Called when the H_FLAGS field of the header has changed 245 */ 246 virtual void flagsChanged(zbyte value) override; 247 248 /** 249 * This function does the dirty work for z_save_undo. 250 */ 251 int save_undo(); 252 253 /** 254 * This function does the dirty work for z_restore_undo. 255 */ 256 int restore_undo(); 257 258 /** 259 * Begin output redirection to the memory of the Z-machine. 260 */ 261 void memory_open(zword table, zword xsize, bool buffering); 262 263 /** 264 * End of output redirection. 265 */ 266 void memory_close(); 267 268 /** 269 * Redirect a newline to the memory of the Z-machine. 270 */ 271 void memory_new_line(); 272 273 /** 274 * Redirect a string of characters to the memory of the Z-machine. 275 */ 276 void memory_word(const zchar *s); 277 278 /**@}*/ 279 280 /** 281 * \defgroup Object support methods 282 * @{ 283 */ 284 285 /** 286 * Calculate the address of an object. 287 */ 288 zword object_address(zword obj); 289 290 /** 291 * Return the address of the given object's name. 292 */ 293 zword object_name(zword object); 294 295 /** 296 * Calculate the start address of the property list associated with an object. 297 */ 298 zword first_property(zword obj); 299 300 /** 301 * Calculate the address of the next property in a property list. 302 */ 303 zword next_property(zword prop_addr); 304 305 /** 306 * Unlink an object from its parent and siblings. 307 */ 308 void unlink_object(zword object); 309 310 /**@}*/ 311 312 /** 313 * \defgroup Screen support methods 314 * @{ 315 */ 316 317 /** 318 * Start printing a so-called debugging message. The contents of the 319 * message are passed to the message stream, a Frotz specific output 320 * stream with maximum priority. 321 */ 322 void screen_mssg_on(); 323 324 /** 325 * Stop printing a "debugging" message 326 */ 327 void screen_mssg_off(); 328 329 /** 330 * Map a runic character to its Unicode equivalent, if there is one 331 */ 332 uint32 zchar_to_unicode_rune(zchar c); 333 334 /** 335 * Display a single character on the screen. 336 */ 337 void screen_char(zchar c); 338 339 /** 340 * Print a newline to the screen. 341 */ 342 void screen_new_line(); 343 344 /** 345 * Print a newline to the screen. 346 */ 347 void screen_word(const zchar *s); 348 349 /** 350 * Erase the entire screen to background colour. 351 */ 352 void erase_screen(zword win); 353 354 /** 355 * Erase a window to background colour. 356 */ 357 void erase_window(zword win); 358 359 /**@}*/ 360 361 /** 362 * \defgroup Stream support methods 363 * @{ 364 */ 365 366 /** 367 * Waits for the user to type an input line 368 */ 369 zchar console_read_input(int max, zchar *buf, zword timeout, bool continued); 370 371 /** 372 * Waits for a keypress 373 */ 374 zchar console_read_key(zword timeout); 375 376 /** 377 * Write a single character to the scrollback buffer. 378 * 379 */ 380 void scrollback_char(zchar c); 381 382 /** 383 * Write a string to the scrollback buffer. 384 */ 385 void scrollback_word(const zchar *s); 386 387 /** 388 * Send an input line to the scrollback buffer. 389 */ 390 void scrollback_write_input(const zchar *buf, zchar key); 391 392 /** 393 * Remove an input line from the scrollback buffer. 394 */ 395 void scrollback_erase_input(const zchar *buf); 396 397 /** 398 * Start printing a "debugging" message. 399 */ 400 void stream_mssg_on(); 401 402 /** 403 * Stop printing a "debugging" message. 404 */ 405 void stream_mssg_off(); 406 407 /** 408 * Send a single character to the output stream. 409 */ 410 void stream_char(zchar c); 411 412 /** 413 * Send a string of characters to the output streams. 414 */ 415 void stream_word(const zchar *s); 416 417 /** 418 * Send a newline to the output streams. 419 */ 420 void stream_new_line(); 421 422 /** 423 * Read a single keystroke from the current input stream. 424 */ 425 zchar stream_read_key(zword timeout, zword routine, bool hot_keys); 426 427 /** 428 * Read a line of input from the current input stream. 429 */ 430 zchar stream_read_input(int max, zchar *buf, zword timeout, zword routine, 431 bool hot_keys, bool no_scripting); 432 433 /* 434 * script_open 435 * 436 * Open the transscript file. 'AMFV' makes this more complicated as it 437 * turns transscription on/off several times to exclude some text from 438 * the transscription file. This wasn't a problem for the original V4 439 * interpreters which always sent transscription to the printer, but it 440 * means a problem to modern interpreters that offer to open a new file 441 * every time transscription is turned on. Our solution is to append to 442 * the old transscription file in V1 to V4, and to ask for a new file 443 * name in V5+. 444 * 445 */ 446 void script_open(); 447 448 /* 449 * Stop transscription. 450 */ 451 void script_close(); 452 453 /** 454 * Write a newline to the transscript file. 455 */ 456 void script_new_line(); 457 458 /** 459 * Write a single character to the transscript file. 460 */ 461 void script_char(zchar c); 462 463 /** 464 * Write a string to the transscript file. 465 */ 466 void script_word(const zchar *s); 467 468 /** 469 * Send an input line to the transscript file. 470 */ 471 void script_write_input(const zchar *buf, zchar key); 472 473 /** 474 * Remove an input line from the transscript file. 475 */ 476 void script_erase_input(const zchar *buf); 477 478 /** 479 * Start sending a "debugging" message to the transscript file. 480 */ 481 void script_mssg_on(); 482 483 /** 484 * Stop writing a "debugging" message. 485 */ 486 void script_mssg_off(); 487 488 /** 489 * Open a file to record the player's input. 490 */ 491 void record_open(); 492 493 /** 494 * Stop recording the player's input. 495 */ 496 void record_close(); 497 498 /** 499 * Helper function for record_char. 500 */ 501 void record_code(int c, bool force_encoding); 502 503 /** 504 * Write a character to the command file. 505 */ 506 void record_char(zchar c); 507 508 /** 509 * Copy a keystroke to the command file. 510 */ 511 void record_write_key(zchar key); 512 513 /** 514 * Copy a line of input to a command file. 515 */ 516 void record_write_input(const zchar *buf, zchar key); 517 518 /** 519 * Open a file of commands for playback. 520 */ 521 void replay_open(); 522 523 /** 524 * Stop playback of commands. 525 */ 526 void replay_close(); 527 528 /* 529 * Helper function for replay_key and replay_line. 530 */ 531 int replay_code(); 532 533 /** 534 * Read a character from the command file. 535 */ 536 zchar replay_char(); 537 538 /** 539 * Read a keystroke from a command file. 540 */ 541 zchar replay_read_key(); 542 543 /* 544 * Read a line of input from a command file. 545 */ 546 zchar replay_read_input(zchar *buf); 547 548 /**@}*/ 549 550 /** 551 * \defgroup Text support methods 552 * @{ 553 */ 554 555 /** 556 * Map a ZSCII character into Unicode. 557 */ 558 zchar translate_from_zscii(zbyte c); 559 560 /** 561 * Convert a Unicode character to ZSCII, returning 0 on failure. 562 */ 563 zbyte unicode_to_zscii(zchar c); 564 565 /** 566 * Map a Unicode character onto the ZSCII alphabet. 567 */ 568 zbyte translate_to_zscii(zchar c); 569 570 /** 571 * Return a character from one of the three character sets. 572 */ 573 zchar alphabet(int set, int index); 574 575 /** 576 * Find the number of bytes used for dictionary resolution. 577 */ 578 void find_resolution(); 579 580 /** 581 * Copy a ZSCII string from the memory to the global "decoded" string. 582 */ 583 void load_string(zword addr, zword length); 584 585 /** 586 * Encode the Unicode text in the global "decoded" string then write 587 * the result to the global "encoded" array. (This is used to look up 588 * words in the dictionary.) Up to V3 the vocabulary resolution is 589 * two, from V4 it is three, and from V9 it is any number of words. 590 * Because each word contains three Z-characters, that makes six or 591 * nine Z-characters respectively. Longer words are chopped to the 592 * proper size, shorter words are are padded out with 5's. For word 593 * completion we pad with 0s and 31s, the minimum and maximum 594 * Z-characters. 595 */ 596 void encode_text(int padding); 597 598 /** 599 * Convert _encoded text to Unicode. The _encoded text consists of 16bit 600 * words. Every word holds 3 Z-characters (5 bits each) plus a spare 601 * bit to mark the last word. The Z-characters translate to ZSCII by 602 * looking at the current current character set. Some select another 603 * character set, others refer to abbreviations. 604 * 605 * There are several different string types: 606 * 607 * LOW_STRING - from the lower 64KB (byte address) 608 * ABBREVIATION - from the abbreviations table (word address) 609 * HIGH_STRING - from the end of the memory map (packed address) 610 * EMBEDDED_STRING - from the instruction stream (at PC) 611 * VOCABULARY - from the dictionary (byte address) 612 * 613 * The last type is only used for word completion. 614 */ 615 void decode_text(string_type st, zword addr); 616 617 /** 618 * Print a signed 16bit number. 619 */ 620 void print_num(zword value); 621 622 /** 623 * print_object 624 * 625 * Print an object description. 626 * 627 */ 628 void print_object(zword object); 629 630 /** 631 * Scan a dictionary searching for the given word. The first argument 632 * can be 633 * 634 * 0x00 - find the first word which is >= the given one 635 * 0x05 - find the word which exactly matches the given one 636 * 0x1f - find the last word which is <= the given one 637 * 638 * The return value is 0 if the search fails. 639 */ 640 zword lookup_text(int padding, zword dct); 641 642 /** 643 * Handles converting abbreviations that weren't handled by early Infocom games 644 * into their expanded versions 645 */ 646 void handleAbbreviations(); 647 648 /** 649 * Translate a single word to a token and append it to the token 650 * buffer. Every token consists of the address of the dictionary 651 * entry, the length of the word and the offset of the word from 652 * the start of the text buffer. Unknown words cause empty slots 653 * if the flag is set (such that the text can be scanned several 654 * times with different dictionaries); otherwise they are zero. 655 * 656 */ 657 void tokenise_text(zword text, zword length, zword from, zword parse, zword dct, bool flag); 658 659 /** 660 * Split an input line into words and translate the words to tokens. 661 */ 662 void tokenise_line(zword text, zword token, zword dct, bool flag); 663 664 /** 665 * Scan the vocabulary to complete the last word on the input line 666 * (similar to "tcsh" under Unix). The return value is 667 * 668 * 2 ==> completion is impossible 669 * 1 ==> completion is ambiguous 670 * 0 ==> completion is successful 671 * 672 * The function also returns a string in its second argument. In case 673 * of 2, the string is empty; in case of 1, the string is the longest 674 * extension of the last word on the input line that is common to all 675 * possible completions (for instance, if the last word on the input 676 * is "fo" and its only possible completions are "follow" and "folly" 677 * then the string is "ll"); in case of 0, the string is an extension 678 * to the last word that results in the only possible completion. 679 */ 680 int completion(const zchar *buffer, zchar *result); 681 682 /** 683 * Convert a Unicode character to lowercase. 684 * Taken from Zip2000 by Kevin Bracey. 685 */ 686 zchar unicode_tolower(zchar c); 687 688 /**@}*/ 689 690 /** 691 * \defgroup Window/V6 Opcode methods 692 * @{ 693 */ 694 695 /** 696 * Return the window number in zargs[0]. In V6 only, -3 refers to the 697 * current window. 698 */ 699 zword winarg0(); 700 701 /** 702 * Return the (optional) window number in zargs[2]. -3 refers to the 703 * current window. This optional window number was only used by some 704 * V6 opcodes: set_cursor, set_margins, set_colour. 705 */ 706 zword winarg2(); 707 708 /**@}*/ 709 protected: 710 /** 711 * \defgroup General Opcode methods 712 * @{ 713 */ 714 715 /* 716 * Load and execute an extended opcode. 717 */ 718 void __extended__(); 719 720 /* 721 * Exit game because an unknown opcode has been hit. 722 */ 723 void __illegal__(); 724 725 /* 726 * Store the current _stack frame for later use with z_throw. 727 * 728 * no zargs used 729 */ 730 void z_catch(); 731 732 /** 733 * Go back to the given _stack frame and return the given value. 734 * 735 * zargs[0] = value to return 736 * zargs[1] = _stack frame 737 */ 738 void z_throw(); 739 740 /* 741 * Call a subroutine and discard its result. 742 * 743 * zargs[0] = packed address of subroutine 744 * zargs[1] = first argument (optional) 745 * ... 746 * zargs[7] = seventh argument (optional) 747 */ 748 void z_call_n(); 749 750 /** 751 * Call a subroutine and store its result. 752 * 753 * zargs[0] = packed address of subroutine 754 * zargs[1] = first argument (optional) 755 * ... 756 * zargs[7] = seventh argument (optional) 757 */ 758 void z_call_s(); 759 760 /** 761 * Branch if subroutine was called with >= n arg's. 762 * 763 * zargs[0] = number of arguments 764 */ 765 void z_check_arg_count(); 766 767 /** 768 * Jump unconditionally to the given address. 769 * 770 * zargs[0] = PC relative address 771 */ 772 void z_jump(); 773 774 /* 775 * No operation. 776 * 777 * no zargs used 778 */ 779 void z_nop(); 780 781 /* 782 * Stop game and exit interpreter. 783 * 784 * no zargs used 785 */ 786 void z_quit(); 787 788 /* 789 * Return from a subroutine with the given value. 790 * 791 * zargs[0] = value to return 792 */ 793 void z_ret(); 794 795 /* 796 * Return from a subroutine with a value popped off the stack. 797 * 798 * no zargs used 799 */ 800 void z_ret_popped(); 801 802 /* 803 * Return from a subroutine with false (0). 804 * 805 * no zargs used 806 */ 807 void z_rfalse(); 808 809 /* 810 * Return from a subroutine with true (1). 811 * 812 * no zargs used 813 */ 814 void z_rtrue(); 815 816 /** 817 * Store a random number or set the random number seed. 818 * 819 * zargs[0] = range (positive) or seed value (negative) 820 */ 821 void z_random(); 822 823 /** 824 * Load / play / stop / discard a sound effect. 825 * 826 * zargs[0] = number of bleep (1 or 2) or sample 827 * zargs[1] = operation to perform (samples only) 828 * zargs[2] = repeats and volume (play sample only) 829 * zargs[3] = end-of-sound routine (play sample only, optional) 830 * 831 * Note: Volumes range from 1 to 8, volume 255 is the default volume. 832 * Repeats are stored in the high byte, 255 is infinite loop. 833 * 834 */ 835 void z_sound_effect(); 836 837 /** 838 * Branch if the story file is a legal copy 839 */ 840 void z_piracy(); 841 842 /** 843 * Save the current Z-machine state for a future undo. 844 * 845 * no zargs used 846 */ 847 void z_save_undo(); 848 849 /** 850 * Restore a Z-machine state from memory. 851 * 852 * no zargs used 853 */ 854 void z_restore_undo(); 855 856 /**@}*/ 857 858 /** 859 * \defgroup Input Opcode methods 860 * @{ 861 */ 862 863 /** 864 * Add or remove a menu and branch if successful. 865 * 866 * zargs[0] = number of menu 867 * zargs[1] = table of menu entries or 0 to remove menu 868 */ 869 void z_make_menu(); 870 871 /** 872 * Read a line of input and (in V5+) store the terminating key. 873 * 874 * zargs[0] = address of text buffer 875 * zargs[1] = address of token buffer 876 * zargs[2] = timeout in tenths of a second (optional) 877 * zargs[3] = packed address of routine to be called on timeout 878 */ 879 void z_read(); 880 881 /** 882 * Read and store a key. 883 * 884 * zargs[0] = input device (must be 1) 885 * zargs[1] = timeout in tenths of a second (optional) 886 * zargs[2] = packed address of routine to be called on timeout 887 */ 888 void z_read_char(); 889 890 /** 891 * z_read_mouse, write the current mouse status into a table. 892 * 893 * zargs[0] = address of table 894 */ 895 void z_read_mouse(); 896 897 /**@}*/ 898 899 /** 900 * \defgroup Math Opcode methods 901 * @{ 902 */ 903 904 /** 905 * 16 bit addition. 906 * 907 * zargs[0] = first value 908 * zargs[1] = second value 909 */ 910 void z_add(); 911 912 /** 913 * Bitwise AND operation. 914 * 915 * zargs[0] = first value 916 * zargs[1] = second value 917 */ 918 void z_and(); 919 920 /** 921 * Arithmetic SHIFT operation. 922 * 923 * zargs[0] = value 924 * zargs[1] = #positions to shift left (positive) or right 925 */ 926 void z_art_shift(); 927 928 /** 929 * Signed 16bit division. 930 * 931 * zargs[0] = first value 932 * zargs[1] = second value 933 */ 934 void z_div(); 935 936 /** 937 * B ranch if the first value equals any of the following. 938 * 939 * zargs[0] = first value 940 * zargs[1] = second value (optional) 941 * ... 942 * zargs[3] = fourth value (optional) 943 */ 944 void z_je(); 945 946 /** 947 * Branch if the first value is greater than the second. 948 * 949 * zargs[0] = first value 950 * zargs[1] = second value 951 */ 952 void z_jg(); 953 954 /** 955 * Branch if the first value is less than the second. 956 * 957 * zargs[0] = first value 958 * zargs[1] = second value 959 */ 960 void z_jl(); 961 962 /** 963 * Branch if value is zero. 964 * 965 * zargs[0] = value 966 */ 967 void z_jz(); 968 969 /** 970 * Logical SHIFT operation. 971 * 972 * zargs[0] = value 973 * zargs[1] = #positions to shift left (positive) or right (negative) 974 */ 975 void z_log_shift(); 976 977 /* 978 * Remainder after signed 16bit division. 979 * 980 * zargs[0] = first value 981 * zargs[1] = second value 982 */ 983 void z_mod(); 984 985 /** 986 * 16 bit multiplication. 987 * 988 * zargs[0] = first value 989 * zargs[1] = second value 990 */ 991 void z_mul(); 992 993 /** 994 * Bitwise NOT operation. 995 * 996 * zargs[0] = value 997 */ 998 void z_not(); 999 1000 /** 1001 * Bitwise OR operation. 1002 * 1003 * zargs[0] = first value 1004 * zargs[1] = second value 1005 */ 1006 void z_or(); 1007 1008 /** 1009 * 16 bit substraction. 1010 * 1011 * zargs[0] = first value 1012 * zargs[1] = second value 1013 */ 1014 void z_sub(); 1015 1016 /** 1017 * Branch if all the flags of a bit mask are set in a value. 1018 * 1019 * zargs[0] = value to be examined 1020 * zargs[1] = bit mask 1021 */ 1022 void z_test(); 1023 1024 /**@}*/ 1025 1026 /** 1027 * \defgroup Object Opcode methods 1028 * @{ 1029 */ 1030 1031 /** 1032 * Branch if the first object is inside the second. 1033 * 1034 * zargs[0] = first object 1035 * zargs[1] = second object 1036 */ 1037 void z_jin(); 1038 1039 /** 1040 * Store the child of an object. 1041 * 1042 * zargs[0] = object 1043 */ 1044 void z_get_child(); 1045 1046 /** 1047 * Store the number of the first or next property. 1048 * 1049 * zargs[0] = object 1050 * zargs[1] = address of current property (0 gets the first property) 1051 */ 1052 void z_get_next_prop(); 1053 1054 /** 1055 * Store the parent of an object. 1056 * 1057 * zargs[0] = object 1058 */ 1059 void z_get_parent(); 1060 1061 /** 1062 * Store the value of an object property. 1063 * 1064 * zargs[0] = object 1065 * zargs[1] = number of property to be examined 1066 */ 1067 void z_get_prop(); 1068 1069 /** 1070 * Store the address of an object property. 1071 * 1072 * zargs[0] = object 1073 * zargs[1] = number of property to be examined 1074 */ 1075 void z_get_prop_addr(); 1076 1077 /** 1078 * Store the length of an object property. 1079 * 1080 * zargs[0] = address of property to be examined 1081 */ 1082 void z_get_prop_len(); 1083 1084 /** 1085 * Store the sibling of an object. 1086 * 1087 * zargs[0] = object 1088 */ 1089 void z_get_sibling(); 1090 1091 /** 1092 * Make an object the first child of another object. 1093 * 1094 * zargs[0] = object to be moved 1095 * zargs[1] = destination object 1096 */ 1097 void z_insert_obj(); 1098 1099 /** 1100 * Set the value of an object property. 1101 * 1102 * zargs[0] = object 1103 * zargs[1] = number of property to set 1104 * zargs[2] = value to set property to 1105 */ 1106 void z_put_prop(); 1107 1108 /** 1109 * Unlink an object from its parent and siblings. 1110 * 1111 * zargs[0] = object 1112 */ 1113 void z_remove_obj(); 1114 1115 /** 1116 * Set an object attribute. 1117 * 1118 * zargs[0] = object 1119 * zargs[1] = number of attribute to set 1120 */ 1121 void z_set_attr(); 1122 1123 /** 1124 * Branch if an object attribute is set. 1125 * 1126 * zargs[0] = object 1127 * zargs[1] = number of attribute to test 1128 */ 1129 void z_test_attr(); 1130 1131 /** 1132 * Clear an object attribute. 1133 * 1134 * zargs[0] = object 1135 * zargs[1] = number of attribute to be cleared 1136 */ 1137 void z_clear_attr(); 1138 1139 /**@}*/ 1140 1141 /** 1142 * \defgroup Screen Opcode methods 1143 * @{ 1144 */ 1145 1146 /** 1147 * Turn text buffering on/off. 1148 * 1149 * zargs[0] = new text buffering flag (0 or 1) 1150 */ 1151 void z_buffer_mode(); 1152 1153 /** 1154 * Set the screen buffering mode. 1155 * 1156 * zargs[0] = mode 1157 */ 1158 void z_buffer_screen(); 1159 1160 /** 1161 * Erase the line starting at the cursor position. 1162 * 1163 * zargs[0] = 1 + #units to erase (1 clears to the end of the line) 1164 */ 1165 void z_erase_line(); 1166 1167 /** 1168 * Erase a window or the screen to background colour. 1169 * 1170 * zargs[0] = window (-3 current, -2 screen, -1 screen & unsplit) 1171 */ 1172 void z_erase_window(); 1173 1174 /** 1175 * Write the cursor coordinates into a table. 1176 * 1177 * zargs[0] = address to write information to 1178 */ 1179 void z_get_cursor(); 1180 1181 /** 1182 * Print ASCII text in a rectangular area. 1183 * 1184 * zargs[0] = address of text to be printed 1185 * zargs[1] = width of rectangular area 1186 * zargs[2] = height of rectangular area (optional) 1187 * zargs[3] = number of char's to skip between lines (optional) 1188 */ 1189 void z_print_table(); 1190 1191 /** 1192 * Set the foreground and background colours 1193 * to specific RGB colour values. 1194 * 1195 * zargs[0] = foreground colour 1196 * zargs[1] = background colour 1197 * zargs[2] = window (-3 is the current one, optional) 1198 */ 1199 void z_set_true_colour(); 1200 1201 /** 1202 * Set the foreground and background colours. 1203 * 1204 * zargs[0] = foreground colour 1205 * zargs[1] = background colour 1206 * zargs[2] = window (-3 is the current one, optional) 1207 */ 1208 void z_set_colour(); 1209 1210 /** 1211 * Set the font for text output and store the previous font. 1212 * 1213 * zargs[0] = number of font or 0 to keep current font 1214 */ 1215 void z_set_font(); 1216 1217 /** 1218 * Set the cursor position or turn the cursor on/off. 1219 * 1220 * zargs[0] = y-coordinate or -2/-1 for cursor on/off 1221 * zargs[1] = x-coordinate 1222 * zargs[2] = window (-3 is the current one, optional) 1223 */ 1224 void z_set_cursor(); 1225 1226 /** 1227 * z_set_text_style, set the style for text output. 1228 * 1229 * zargs[0] = style flags to set or 0 to reset text style 1230 */ 1231 void z_set_text_style(); 1232 1233 /** 1234 * Select the current window. 1235 * 1236 * zargs[0] = window to be selected (-3 is the current one) 1237 */ 1238 void z_set_window(); 1239 1240 /** 1241 * Display the status line for V1 to V3 games. 1242 * 1243 * no zargs used 1244 */ 1245 void pad_status_line(int column); 1246 1247 /** 1248 * Display the status line for V1 to V3 games. 1249 * 1250 * no zargs used 1251 */ 1252 void z_show_status(); 1253 1254 /** 1255 * Split the screen into an upper (1) and lower (0) window. 1256 * 1257 * zargs[0] = height of upper window in screen units (V6) or #lines 1258 */ 1259 void z_split_window(); 1260 1261 /**@}*/ 1262 1263 /** 1264 * \defgroup Stream Opcode methods 1265 * @{ 1266 */ 1267 1268 /** 1269 * Select an input stream. 1270 * 1271 * zargs[0] = input stream to be selected 1272 */ 1273 void z_input_stream(); 1274 1275 /** 1276 * Open or close an output stream. 1277 * 1278 * zargs[0] = stream to open (positive) or close (negative) 1279 * zargs[1] = address to redirect output to (stream 3 only) 1280 * zargs[2] = width of redirected output (stream 3 only, optional) 1281 */ 1282 void z_output_stream(); 1283 1284 /** 1285 * Re-load dynamic area, clear the stack and set the PC. 1286 * 1287 * no zargs used 1288 */ 1289 void z_restart(); 1290 1291 /** 1292 * Save [a part of] the Z-machine state to disk. 1293 * 1294 * zargs[0] = address of memory area to save (optional) 1295 * zargs[1] = number of bytes to save 1296 * zargs[2] = address of suggested file name 1297 */ 1298 void z_save(); 1299 1300 /** 1301 * Restore [a part of] a Z-machine state from disk 1302 * 1303 * zargs[0] = address of area to restore (optional) 1304 * zargs[1] = number of bytes to restore 1305 * zargs[2] = address of suggested file name 1306 */ 1307 void z_restore(); 1308 1309 /** 1310 * Check the story file integrity. 1311 * 1312 * no zargs used 1313 */ 1314 void z_verify(); 1315 1316 /**@}*/ 1317 1318 /** 1319 * \defgroup Table Opcode methods 1320 * @{ 1321 */ 1322 1323 /** 1324 * Copy a table or fill it with zeroes. 1325 * 1326 * zargs[0] = address of table 1327 * zargs[1] = destination address or 0 for fill 1328 * zargs[2] = size of table 1329 * 1330 * Note: Copying is safe even when source and destination overlap; but 1331 * if zargs[1] is negative the table _must_ be copied forwards. 1332 */ 1333 void z_copy_table(); 1334 1335 /** 1336 * Store a value from a table of bytes. 1337 * 1338 * zargs[0] = address of table 1339 * zargs[1] = index of table entry to store 1340 */ 1341 void z_loadb(); 1342 1343 /** 1344 * Store a value from a table of words. 1345 * 1346 * zargs[0] = address of table 1347 * zargs[1] = index of table entry to store 1348 */ 1349 void z_loadw(); 1350 1351 /** 1352 * Find and store the address of a target within a table. 1353 * 1354 * zargs[0] = target value to be searched for 1355 * zargs[1] = address of table 1356 * zargs[2] = number of table entries to check value against 1357 * zargs[3] = type of table (optional, defaults to 0x82) 1358 * 1359 * Note: The table is a word array if bit 7 of zargs[3] is set; otherwise 1360 * it's a byte array. The lower bits hold the address step. 1361 */ 1362 void z_scan_table(); 1363 1364 /** 1365 * Write a byte into a table of bytes. 1366 * 1367 * zargs[0] = address of table 1368 * zargs[1] = index of table entry 1369 * zargs[2] = value to be written 1370 */ 1371 void z_storeb(); 1372 1373 /** 1374 * Write a word into a table of words. 1375 * 1376 * zargs[0] = address of table 1377 * zargs[1] = index of table entry 1378 * zargs[2] = value to be written 1379 */ 1380 void z_storew(); 1381 1382 /**@}*/ 1383 1384 /** 1385 * \defgroup Text Opcode methods 1386 * @{ 1387 */ 1388 1389 /** 1390 * Test if a unicode character can be printed (bit 0) and read (bit 1). 1391 * 1392 * zargs[0] = Unicode 1393 */ 1394 void z_check_unicode(); 1395 1396 /** 1397 * Encode a ZSCII string for use in a dictionary. 1398 * 1399 * zargs[0] = address of text buffer 1400 * zargs[1] = length of ASCII string 1401 * zargs[2] = offset of ASCII string within the text buffer 1402 * zargs[3] = address to store encoded text in 1403 * 1404 * This is a V5+ opcode and therefore the dictionary resolution must be 1405 * three 16bit words. 1406 */ 1407 void z_encode_text(); 1408 1409 /** 1410 * Print a new line. 1411 * 1412 * no zargs used 1413 * 1414 */ 1415 void z_new_line(); 1416 1417 /** 1418 * Print a string embedded in the instruction stream. 1419 * 1420 * no zargs used 1421 */ 1422 void z_print(); 1423 1424 /** 1425 * Print a string from the lower 64KB. 1426 * 1427 * zargs[0] = address of string to print 1428 */ 1429 void z_print_addr(); 1430 1431 /** 1432 * Print a single ZSCII character. 1433 * 1434 * zargs[0] = ZSCII character to be printed 1435 */ 1436 void z_print_char(); 1437 1438 /** 1439 * Print a formatted table. 1440 * 1441 * zargs[0] = address of formatted table to be printed 1442 */ 1443 void z_print_form(); 1444 1445 /** 1446 * Print a signed number. 1447 * 1448 * zargs[0] = number to print 1449 */ 1450 void z_print_num(); 1451 1452 /** 1453 * Print an object description. 1454 * 1455 * zargs[0] = number of object to be printed 1456 */ 1457 void z_print_obj(); 1458 1459 /** 1460 * Print the string at the given packed address. 1461 * 1462 * zargs[0] = packed address of string to be printed 1463 */ 1464 void z_print_paddr(); 1465 1466 /* 1467 * Print the string at PC, print newline then return true. 1468 * 1469 * no zargs used 1470 */ 1471 void z_print_ret(); 1472 1473 /** 1474 * Print unicode character 1475 * 1476 * zargs[0] = Unicode 1477 */ 1478 void z_print_unicode(); 1479 1480 /** 1481 * Make a lexical analysis of a ZSCII string. 1482 * 1483 * zargs[0] = address of string to analyze 1484 * zargs[1] = address of token buffer 1485 * zargs[2] = address of dictionary (optional) 1486 * zargs[3] = set when unknown words cause empty slots (optional) 1487 */ 1488 void z_tokenise(); 1489 1490 /**@}*/ 1491 1492 /** 1493 * \defgroup Variable Opcode methods 1494 * @{ 1495 */ 1496 1497 /** 1498 * Decrement a variable. 1499 * 1500 * zargs[0] = variable to decrement 1501 */ 1502 void z_dec(); 1503 1504 /** 1505 * Decrement a variable and branch if now less than value. 1506 * 1507 * zargs[0] = variable to decrement 1508 * zargs[1] = value to check variable against 1509 */ 1510 void z_dec_chk(); 1511 1512 /** 1513 * Increment a variable. 1514 * 1515 * zargs[0] = variable to increment 1516 */ 1517 void z_inc(); 1518 1519 /** 1520 * Increment a variable and branch if now greater than value. 1521 * 1522 * zargs[0] = variable to increment 1523 * zargs[1] = value to check variable against 1524 */ 1525 void z_inc_chk(); 1526 1527 /** 1528 * Store the value of a variable. 1529 * 1530 * zargs[0] = variable to store 1531 */ 1532 void z_load(); 1533 1534 /** 1535 * Pop a value off the game stack and discard it. 1536 * 1537 * no zargs used 1538 */ 1539 void z_pop(); 1540 1541 /** 1542 * Pop n values off the game or user stack and discard them. 1543 * 1544 * zargs[0] = number of values to discard 1545 * zargs[1] = address of user stack (optional) 1546 */ 1547 void z_pop_stack(); 1548 1549 /** 1550 * Pop a value off... 1551 * 1552 * a) ...the game or a user stack and store it (V6) 1553 * 1554 * zargs[0] = address of user stack (optional) 1555 * 1556 * b) ...the game stack and write it to a variable (other than V6) 1557 * 1558 * zargs[0] = variable to write value to 1559 */ 1560 void z_pull(); 1561 1562 /** 1563 * Push a value onto the game stack. 1564 * 1565 * zargs[0] = value to push onto the stack 1566 */ 1567 void z_push(); 1568 1569 /** 1570 * Push a value onto a user stack then branch if successful. 1571 * 1572 * zargs[0] = value to push onto the stack 1573 * zargs[1] = address of user stack 1574 */ 1575 void z_push_stack(); 1576 1577 /** 1578 * Write a value to a variable. 1579 * 1580 * zargs[0] = variable to be written to 1581 * zargs[1] = value to write 1582 */ 1583 void z_store(); 1584 1585 /**@}*/ 1586 1587 /** 1588 * \defgroup Window/V6 Opcode methods 1589 * @{ 1590 */ 1591 1592 /** 1593 * z_draw_picture, draw a picture. 1594 * 1595 * zargs[0] = number of picture to draw 1596 * zargs[1] = y-coordinate of top left corner 1597 * zargs[2] = x-coordinate of top left corner 1598 */ 1599 void z_draw_picture(); 1600 1601 /** 1602 * Get information on a picture or the graphics file. 1603 * 1604 * zargs[0] = number of picture or 0 for the graphics file 1605 * zargs[1] = address to write information to 1606 */ 1607 void z_picture_data(); 1608 1609 /** 1610 * Erase a picture with background colour. 1611 * 1612 * zargs[0] = number of picture to erase 1613 * zargs[1] = y-coordinate of top left corner (optional) 1614 * zargs[2] = x-coordinate of top left corner (optional) 1615 */ 1616 void z_erase_picture(); 1617 1618 /** 1619 * Set the left and right margins of a window. 1620 * 1621 * zargs[0] = left margin in pixels 1622 * zargs[1] = right margin in pixels 1623 * zargs[2] = window (-3 is the current one, optional) 1624 */ 1625 void z_set_margins(); 1626 1627 1628 /** 1629 * Place a window on the screen. 1630 * 1631 * zargs[0] = window (-3 is the current one) 1632 * zargs[1] = y-coordinate 1633 * zargs[2] = x-coordinate 1634 * 1635 */ 1636 void z_move_window(); 1637 1638 /** 1639 * Change the width and height of a window. 1640 * 1641 * zargs[0] = window (-3 is the current one) 1642 * zargs[1] = new height in screen units 1643 * zargs[2] = new width in screen units 1644 */ 1645 void z_window_size(); 1646 1647 /** 1648 * Set / clear / toggle window attributes. 1649 * 1650 * zargs[0] = window (-3 is the current one) 1651 * zargs[1] = window attribute flags 1652 * zargs[2] = operation to perform (optional, defaults to 0) 1653 */ 1654 void z_window_style(); 1655 1656 /** 1657 * Store the value of a window property. 1658 * 1659 * zargs[0] = window (-3 is the current one) 1660 * zargs[1] = number of window property to be stored 1661 */ 1662 void z_get_wind_prop(); 1663 1664 /** 1665 * Set the value of a window property. 1666 * 1667 * zargs[0] = window (-3 is the current one) 1668 * zargs[1] = number of window property to set 1669 * zargs[2] = value to set window property to 1670 */ 1671 void z_put_wind_prop(); 1672 1673 /** 1674 * Scroll a window up or down. 1675 * 1676 * zargs[0] = window (-3 is the current one) 1677 * zargs[1] = #screen units to scroll up (positive) or down (negative) 1678 */ 1679 void z_scroll_window(); 1680 1681 /** 1682 * Select a window as mouse window. 1683 * 1684 * zargs[0] = window number (-3 is the current) or -1 for the screen 1685 */ 1686 void z_mouse_window(); 1687 1688 /** 1689 * Prepare a group of pictures for faster display. 1690 * 1691 * zargs[0] = address of table holding the picture numbers 1692 */ 1693 void z_picture_table(); 1694 1695 /**@}*/ 1696 public: 1697 /** 1698 * Constructor 1699 */ 1700 Processor(OSystem *syst, const GlkGameDescription &gameDesc); ~Processor()1701 virtual ~Processor() {} 1702 1703 /** 1704 * Initialization 1705 */ 1706 void initialize(); 1707 1708 /** 1709 * Z-code interpreter main loop 1710 */ 1711 void interpret(); 1712 1713 /** 1714 * \defgroup Memory access methods 1715 * @{ 1716 */ 1717 1718 /** 1719 * Square brackets operator 1720 */ 1721 zbyte &operator[](uint addr) { return zmp[addr]; } 1722 1723 /** 1724 * Read a code byte 1725 */ codeByte()1726 zbyte codeByte() { return *pcp++; } 1727 1728 /** 1729 * Read a code word 1730 */ codeWord()1731 zword codeWord() { 1732 zword v = READ_BE_UINT16(pcp); 1733 pcp += 2; 1734 return v; 1735 } 1736 1737 /** 1738 * Return a code word at a given address 1739 */ codeWordIdx(uint addr)1740 zword codeWordIdx(uint addr) const { 1741 return READ_BE_UINT16(pcp + addr); 1742 } 1743 1744 /** 1745 * Return the current program execution offset 1746 */ getPC()1747 uint getPC() const { 1748 assert(pcp); 1749 return pcp - zmp; 1750 } 1751 1752 /** 1753 * Set the program execution offset 1754 */ setPC(uint addr)1755 void setPC(uint addr) { pcp = zmp + addr; } 1756 1757 /**@}*/ 1758 }; 1759 1760 } // End of namespace Frotz 1761 } // End of namespace Glk 1762 1763 #endif 1764