The InfoTaskForce Infocom Interpreter Modification History. =========================================================== Copyright (c) 1992 InfoTaskForce REV_A - May 25, 1987. --------------------- * Original version of the Infocom Standard Series Interpreter. This was compiled on a 128K Apple Macintosh using Aztec C Version 1.06F. REV_B - June 1, 1987. --------------------- * The Interpreter was ported to Lightspeed C Version 2.01 on a 128K Apple Macintosh, an IBM PC on Microsoft C Version 4 and a VAX 11/780 running UNIX Version 7. These ports revealed some non-portable constructs in the code. * In file.c : fix for byte order (within word) problem. * In infocom.h : added a few new definitions and extra comments. * In io.c : fix for type mismatch (coersion added). * In jump.c : fix for an attempt to use a negative number when stored as an unsigned. * In infocom.c : add command line processing for cheat modes. * Added object.che: A replacement for object.c, allowing two "cheat" modes which can be invoked from the command line. * In print.c : fix for errors that occured when an "int" is not 16 bits. * In page.c : fix for a problem in the "fix_pc ()" function that occured when an int and short aren't the same size. * Added debug.c : A replacement for interp.c with debugging code built in - produces an instruction trace. Machine C Compiler Operational Porting details 128K Apple Macintosh Aztec C Version 1.06F 18/05/87 128K Apple Macintosh Lightspeed C 2.01 29/05/87 Use "rb" & "wb" in all fopen()s IBM PC/AT Microsoft C 4 30/05/87 Link with binmode.obj DEC VAX 11/780 UNIX V7 cc 01/06/87 REV_C - June 2, 1987. --------------------- *** This is the incomplete version which was released on the Internet *** *** (not by InfoTaskForce) *** * Nine more cases of faulty coersion have been found. They showed up quite graphically on the port to an HP 9000 UNIX machine. "signed_word" coersions were added to the following three files: funcs.c, print.c and variable.c. REV_D - June 16, 1987. ---------------------- * Fix one remaining byte order within word problem in "restore ()". * Remove checking on the "fread ()" in "load_page ()" to remove a "Failed to Read Block from File" error when the last block wasn't a full 512 bytes long (they need not be). REV_E - June 25, 1987. ---------------------- REV_E is the first major overhaul to the interpreter. * The source is now significantly lint free. * TERMCAP support has now been added [#define TERMCAP option]. * Screen paging and word wrap has been added, along with a new command line option which disables screen paging (-p). * Random number generator seeding using time () added [#define TIMESEED option]. * Attributes in the object list are listed as bits. * A debuging version can now be produced as an inbuilt options [#define DEBUG option]. * The coded requirement that 25k is always free in the system can now be removed [#define ALLOCALL option]. * A new command line option was added to print the object/room list as a tree (-r). * interp.c has been re-written to improve efficiency [large switches have been replaced with arrays of pointers to funcions]. There are now 14 machines on the porting list: Machine C Compiler Operational Porting details 128K Apple Macintosh Aztec C Version 1.06F 18/05/87 128K Apple Macintosh Lightspeed C 2.01 29/05/87 Use "rb" & "wb" in all fopen()s IBM PC/AT Microsoft C 4 30/05/87 Link with binmode.obj DEC VAX 11/780 UNIX V7 cc 01/06/87 HP-9000 HP-UX cc 02/06/87 gould cc 03/06/87 Amiga Aztec C 04/06/87 Pyramid 9810 cc 04/06/87 Pyramid 90x cc 04/06/87 Osiris cc 05/06/87 DEC PDP-11/? UNIX V? cc 07/06/87 EXTENSIVE mods to fix problems with signed chars. VAX VMS cc 16/06/87 Add #define times ttmes to fix multiply defined symbol problem. [infocom.h] Version 1.00 - August 17, 1987. ------------------------------- The REV_C interpreter of June 2, 1987 was officially archived as Version 1.00 on August 17, 1987. Version 2.00 - April 4, 1988. ----------------------------- [Note: Version 2.00 of the interpreter was derived from the REV_E version of the interpreter. The REV_E save/restore bug is fixed with Version 2.00. However, the following modification list shows the differences between Version 1.00 and Version 2.00, not the differences between REV_E and Version 2.00] *** The STANDARD Interpreter is finally complete *** * Merged file debug.c with interp.c (debug.c no longer exists - DEBUG can now be #defined). * Merged file object.che with object.c (object.che no longer exists - CHEAT can now be #defined). * Renamed function.c to funcs.c (filename was too big for some operating systems). * Renamed makefile to unix.mk and added unix support to the makefile. * Introduced term.c. This file contains the UNIX TERMCAP interface routines. * In file.c, the save and restore routines were completely rewritten. The old version saved only the save_blocks area of the data file, while the new version also saves the current values of the interpreter pc_page, pc_offset, stack pointer, stack_var_pointer and stack array. The size of the save file name was increased from 10 characters to 80 characters. * In infocom.c, the "main ()" routine was modified to support two new options - print object tree and page out (disable the [MORE] function). Some global variables have also been removed to other files. * In infocom.h, the macro "max_mem" was changed from 0xFFFF to 0xFE00 (that is, to a multiple of the block size 0x0200). The macros "dmx_scrx" and "mx_scry" have been introduced - they are the default line width and default screen height respectively. * In init.c, the "init ()" routine was rewritten. Many of the global variables were not needed. The interpreter stack is now a predefined global array and is not obtained from the block of memory obtained by "allocate ()". The new routines "init_io ()" and "init_status ()" are also called from here. * In input.c, the "input ()" routine was modified to reset the line count for every new line of input. * The routines in interp.c were completely rewritten - they now use arrays of function pointers instead of large case statements to execute the various opcode functions. * In io.c, the "init_io ()" routine was added to initialise any I/O variables (specifically the UNIX TERMCAP variables). The "cr_print_buffer ()" routine was added, allowing the "print_buffer ()" routine to be greatly simplified (it was actually quite a mess!). * In io.c, the "out_char ()" routine has been changed to include the "page_out" option and to use the "mx_scry" variable (current number of screen lines). * In io.c, the "allocate ()" routine now returns the number of bytes allocated. It also uses increments of 256 bytes instead of 1 Kbytes and preserves 24 Kbytes for system use instead of 25 Kbytes. This memory is no longer preserved if ALLOCALL is defined. * In io.c, the "seed_random ()" routine now uses the C library "time ()" function to seed the random number generator if TIMESEED is defined. * In options.c, the "out_char ()" routine is now used to print new line characters rather than using printf. "words_per_line" is now calculated from the current line length "mx_scrx" rather than #defined. The total number of entries in the object/room list is now correctly calculated using the start of the first object's property list (instead of blindly assuming that there are always 256 objects). * In options.c, the "bit_byte ()" routine was added to show an object's properties as bits rather than as a hexadecimal number. New routines were added ("show_tree ()" and "obtree ()") to display the data file's object/room list in a tree format. * The global variables "page_strt" and "strt_page_table" were moved from init.c to page.c. The page table initialisation code was also moved from init.c and put in the new "init_page ()" routine in page.c. * In print.c, changed some calls from "print_buffer ()" to "cr_print_buffer ()". * In print.c, introduced the status routine global variables and the "init_status ()" routine which initialises them. * In print.c, the "show_score ()" routine now checks the data file's header directly for the "score_or_time" information rather than use a preset global variable. This routine is now aware of the line length via the "mx_scrx" variable instead of always assuming 80 columns. The status buffer no longer puts the status buffer size in the first byte of the buffer (since this was never used anyway). * In support.c, the "quit ()" routine was modified to remove the superfluous request for the user to hit return before leaving the game. Version 2.50 - Date Unknown. ---------------------------- *** This is the first version to include PLUS Interpreter Routines *** * Renamed unix.mk to makefile. * Renamed funcs.c to fns.c. * Introduced machine.h, globals.c, message.c, plus_fns.c and status.c (the status routines were removed from print.c into status.c). * Made some variables register variables. * Introduced the "read_string" and "write_string" macros because Lightspeed C and Microsoft C require files to be explicitly opened in binary mode: "rb" and "wb". * Change the name of the "score_or_time" byte in the header to "mode_bits". * Renamed "save ()" to "save_game ()" and "restore ()" to "restore_game ()". * Moved global variables from infocom.c to globals.c, io.c, input.c, message.c and print.c. * Introduced the macros "prop_mask" and "mode_mask" due to the introduction of the PLUS interpreter. * In object.c, added code to handle the PLUS interpreter versions of "transfer ()", "remove_obj ()", "get_loc ()", "get_holds ()", "get_link ()" and "check_loc ()". Added "#ifdef CHEAT" to most functions and specified some variables as "register". In "test_attr ()", "set_attr ()" and "clr_attr ()", changed the variable "bit" to "attr_bit" - there was a reason for this but I can't remember what. * In property.c, added code to handle the PLUS interpreter versions of "next_addr ()", "get_prop_addr ()" and "get_p_len ()". Also specified some variables as "register" and in some functions, combined multiple statements into single statements. * Moved some initialisation code out of init.c and put it in "init_input ()" in input.c. * Moved the "print_coded ()", "decode ()" and "letter ()" functions from print.c to message.c. Also moved "encode ()", "find_mode ()" and "convert ()" from input.c to message.c. * Deleted the function "init_status ()" from print.c and moved the functions "show_score ()" { now called "show_status ()" with a different parameter list }, "put_status ()" and "copy_string ()" from print.c to status.c. Also added the function "prt_status ()" which calls "show_status ()" to print.c. * Rewrote "cr_print_buffer ()" and "print_buffer ()" - changed the parameter lists. * Added "init_print ()" and "flush_prt_buff ()" to print.c. Also added code to "print2 ()" to handle the PLUS interpreter version. * Redefined the page table structure in infocom.h. Rewrote all the functions in page.c to conform with the new page table structure definition. Used a new method to calculate "pc" in "fix_pc ()". * Changed the way the command line options are handled. Instead of each being a boolean, they are now different bit positions in an "options" variable. * In options.c, changed all occurrences of "out_char ( '\n' )" to "new_line ()" so that the output from the options use the MORE facility correctly. Also added code to "show_objects ()", "show_tree ()" and "obtree ()" to handle the PLUS version of the object list. The "show_header ()" function now knows about "mode_bits" and "script_status". * Changed the definition of "true" from "1" to "!false". * Revamped the "allocate ()" routine - it now returns a long instead of an unsigned int. Added the "LONG_ALLOCATE" option. * Merged the TERMCAP functions from term.c into io.c (term.c no longer exists). * In jump.c, completely rewrote the "gosub ()" routine. PLUS series code was added (the "pc_page" and "pc_offset" values are calculated differently). The parameters to "gosub ()" have been removed - it now uses the "param_stack[]" array instead for receiving its parameters. * During a subroutine call, the current "stack_var_ptr" offset which is pushed onto the stack is now a positive offset from the "stack_base" rather than a negative one. * In jump.c, added PLUS series comments to the "rtn ()" opcode. * In infocom.h, removed the "max_mem" macro and the default screen size macros "dmx_scrx" and "dmx_scry". Added macros "max_params", "table_size", "max_line_length", "max_PageTable_size" and "encoded_size". Added macros for "z_interp", "stack_size", "chars_per_word", "obj_size", "obj_offset", "plus_error_1" and "plus_error_2" for the PLUS series interpreter. Changed the structure definitions of "object" and "header" for the PLUS series interpreter. * In "init ()", more rigourous checks were added to the memory allocation code. A check is now made to ensure that there is enough room for the resident blocks and at least two data pages. It does not use the "status" global variable to determine the success or failure of the allocation code. * The "init ()" function no longer calls "init_io ()". This is now done by "init_print ()" as "init_io ()" now returns the length of a screen line. * The space used by "p_buff_strt" (the print buffer) and "ws_buff_strt" (the white_space buffer) are no longer allocated from allocated memory. They are now fixed global arrays allocated at compile time. * Moved the function prototypes and opcode jump tables from interp.c to globals.c. * The "interp ()" function now includes support for the PLUS series data file header and uses "init_print ()" rather than manipulate the print routine variables directly. * In "interp ()", renamed the local debug variable "pc" to "debug_pc" to avoid confusion with the "pc" global variable in globals.c. The debug code now uses "new_line ()" in order to use the [MORE] facility correctly. * In interp.c, code was changed to use the new "param_stack[]" and "operands[]" arrays instead of separate parameter variables. The "push_params ()" function was introduced to manipulate the parameter stack. * Changed the "input ()" routine from using two parameters which were explicitly passed to it to using the "param_stack[]" array. Also changed the "show_score ()" call to a "prt_status ()" call which is only compiled if the macro PLUS is not defined. The "flush_prt_buff ()" routine is also used, instead of calling the equivalent routines explicitly. * Fixed a bug in the "read_line ()" routine. Previously, if a backspace was typed and there was no character in the buffer, this routine would go into an infinite loop since "read_char ()" was never called for this special case to break it out of the loop. * Rewrote the "look_up ()" function used by "parse ()" routine to make it more general. Instead of updating the "word_ptr" array, it does the more general function of returning the offset value which is to be stored in the "word_ptr" array and leaves the actual storing of the value to "parse ()". "parse ()" also calls "encode ()", rather than allowing "look_up ()" to do it. The global array "coded[]" is now a local variable. * Added the "make_new_page ()" function in an attempt to isolate the "linecount" variable in the io.c file. * Changed the "read_char ()" routine in io.c to use the "quit ()" function when standard input is exhausted, rather than closing the file and deallocating memory itself. * In io.c, changed the "seed_random ()" routine to use the new "time_function" macro instead of using TIMESEED or the C "time ()" function explicitly. Version 3.00 - March 10, 1990. ------------------------------ * Renamed makefile to makefile.uni and introduced two new makefiles: makefile.azt and makefile.msc. * Created two new files: enhanced.c and plus.h. * Replaced calls to "printf ()" in file.c with calls to "echo ()". * Moved "init_print ()" call to init.c. * Added code to deal with the PLUS series data file header. * Added macro bit definitions for the "mode_bits" and "script_status" words in the data file header. * Renamed "play_game" to "PLAY_GAME", "init_game" to "INIT_GAME", "restart_game" to "RESTART_GAME" and "quit_game" to "QUIT_GAME". * Added the following STANDARD interpreter global variables: "screen_width", "screen_height", "linecount" and "enable_screen". * Added the following ENHANCED interpreter global variables: "disable_script", "windowing_enabled", "current_window" and "window_height". * Removed the following PLUS interpreter global variables: "current_window", "cuursor_x" and "cursor_y". * Added the following PLUS interpreter global variables: "printer_active", "use_buffered_io", "save_use_buffered_io", "use_internal_buffer", "internal_io_buffer", "internal_io_ptr" and "int_io_buff_length". * Added the following ENHANCED and PLUS series opcodes: "split_screen ()", "set_current_window ()", "clear_screen ()", "erase_line ()", "set_text_mode ()", "io_buffer_mode ()", "io_mode ()" and "get_key ()". * Modified the "verify ()" opcode in support.c to enable the verification of PLUS Series Data Files. * Rename variables "mx_scrx" to "screen_width" and "mx_scry" to "screen_height". * Rename macros "dmx_scrx" to "SCREEN_WIDTH" and "dmx_scry" to "SCREEN_HEIGHT". * Rename TERMCAP routine "gotoxy ()" to "tcap_goto_xy ()". * Implement new functions "tcap_putchar ()" and "tcap_erase_window ()". * Introduced the following Default I/O functions: "default_init_io ()", "default_exit_io ()", "default_putchar ()", "default_goto_xy ()", "default_use_window ()", "default_erase_window ()", "default_save_cursor ()", "default_restore_cursor ()", "default_erase_to_eoln ()" and "default_get_ch ()". * Introduced the following Lightspeed C I/O functions: "lsc_init_io ()", "lsc_putchar ()", "lsc_use_window ()", "lsc_erase_window ()", "lsc_save_cursor ()", "lsc_restore_cursor ()" and "lsc_erase_to_eoln ()". * Introduced the following Microsoft C I/O functions: "msdos_init_io ()", "msdos_putchar ()", "msdos_goto_xy ()", "msdos_use_window ()", "msdos_erase_window ()", "msdos_save_cursor ()", "msdos_restore_cursor ()" and "msdos_erase_to_eoln ()". * Inroduced the following UNIX I/O functions: "unix_init_io ()" and "unix_exit_io ()". * Introduced the following macros in machine.h for TERMCAP, UNIX, Lightspeed C, Microsoft C and default: "INIT_IO", "EXIT_IO", "PUT_CHAR", "GOTO_XY", "USE_WINDOW", "GET_CH", "ERASE_TO_EOLN", "ERASE_WINDOW", "SAVE_CURSOR" and "RESTORE_CURSOR". All I/O functions are now accessed through these macros. * Deleted "cr_print_buffer ()" and replaced it by a call to "print_buffer ()" followed by "out_char ( '\n' )". * Introduced the macro "USE_TIME". * Rename "status_line_length" to "screen_width". * In file io.c, deleted functions "init_io ()", "make_new_page ()" and "print_buffer ()". Removed the variable "linecount" from io.c and made it a global. Rewrote "print_buffer ()" - put it in print.c and changed its parameter list. The new "INIT_IO ()" function no longer returns the current line length. * Deleted the "prt_status ()" function from print.c and renamed the "show_status ()" function in status.c as "prt_status ()". * In plus_fns.c, rewrote the "set_cursor_posn ()" function. * In print.c, added code to initialise the ENHANCED and PLUS version print variables in the "init_print ()" function. Added code to handle the PLUS version of the "print_char ()" function. * In io.c, rewrote the "print_status ()" function to use "PUT_CHAR ()" and "GOTO_XY ()" instead of TERMCAP specific functions. * In io.c, rewrote the MORE code in the "out_char ()" function. Version 3.01 - March 29, 1990. ------------------------------ * Incorporated the file plus.h into infocom.h. * Incorporated the files makefile.azt, makefile.msc and makefile.uni into one makefile. * Defined the CAPITALISE & UNDERLINE macros for use in the PLUS version game header. * Removed the "back_space" macro and replaced it with the '\b' character (I didn't know about '\b' previously). * The "save_game ()" and "restore_game ()" functions were modified to support the PLUS interpreter. The Standard and Enhanced versions call the "ret_value ()" fuction before returning while the PLUS version calls the "store ()" function. * Defined new macros "MODE_BITS", "MALLOC ()" and "FREE ()". * Changed "ALLOCALL" to "RESERVE_RAM" due to a spelling bug in earlier files. * Corrected MS-DOS's screen height - changed it from 24 to 25 lines. * Removed the MSDOS dependency from the "print_status ()" routine in io.c. * Rewrote the "read_char ()" and "out_char ()" functions in io.c to support the ENHANCED interpreter mode. * Replaced the "msdos_use_window ()", "default_init_io ()", "default_exit_io ()", "default_use_window ()", "default_erase_to_eoln ()", "default_erase_window ()" and "default_save_cursor ()" with the new "null_io ()" function. * Renamed all msdos I/O routines as ansi I/O routines. The old "msdos_putchar ()" becomes "ansi_putchar ()" and "msdos_putchar ()" was completely rewritten to use MS-DOS interrupts for scrolling. Rewrote "ansi_goto_xy ()" and "ansi_erase_window ()". Coded "ansi_save_cursor ()" and "ansi_restore_cursor ()". * Defined new catagories for ANSI and CURSES. Added the CURSES functions "curses_init_io ()", "curses_exit_io ()", "curses_putchar ()", "curses_goto_xy ()", "curses_erase_window ()", "curses_save_cursor ()", "curses_restore_cursor ()" and "curses_erase_to_eoln ()". * Recoded "tcap_putchar ()" and "tcap_erase_window ()". Removed "cls ()", "standout ()" and "standend ()". Added new TERMCAP functions "tcap_erase_to_eoln ()", "tcap_save_cursor ()" and "tcap_restore_cursor ()". * Fixed a bug in the "io_mode ()" function in io.c. The internal "data_head" structure's "script_status" field should be updated to reflect the current state of the resident game data file's "script_status" field. The bug prevented this. * Modified the "interp ()" function to set the "mode_bits" field of the header in both the PLUS and ENHANCED versions (in both the resident data file AND the internal interpreter "data_head" structure ). Version 3.02 - May 24, 1990. ---------------------------- * In the makefile, added support for Turbo C and the ENHANCED versions of Microsoft C, BSD TERMCAP, BSD ANSI, BSD CURSES, SYSV TERMCAP, SYSV ANSI and SYSV CURSES. * Changed the definition of "long_word" from "long" to "unsigned long" and created a new definition called "signed_long". * Changed "PRINTER_OK" to "SCRIPT_OK" and "PRINTER_ERROR" to "SCRIPT_ERROR". * Implemented scripting. Added the "init_script ()", "open_script ()", "close_script ()" and "script_char ()" functions. * Added macro APPEND_STRING - it is used by the scripting routines. * Captialised macro names READ_STRING and WRITE_STRING for style purposes. * Moved "init_print ()" from init.c to interp.c and options.c. * Modified function "check ()" to check the serial number of the restored data file against that in the "data_head" structure. * Rewrote the Lightspeed C interface routines to prevent the text running into the scroll bars in the default stdout window. Also implemented underlining in Lightspeed C. * Fixed a bug in the "look_up ()" routine in input.c. The "v_ptr" variable should be a "long_word", not a "word". This caused the end of some vocab tables not to be searched - they refused to recognise words we knew were in the vocab list. * Fixed a bug in "interp ()". When a game is restored, the old screen modes are still in effect. Calls to "USE_WINDOW ()" were inserted to correct this. * Modified "io_mode ()" and "io_buffer_mode ()" opcodes in plus_fns.c. Version 3.03 - June 19, 1990. ----------------------------- * Capitalised the macros "TRUE", "FALSE", "BLOCK_SIZE", "STACK_SIZE", "MAX_PARAMS", "LOCAL_VARS", "Z_INTERP", "OBJ_SIZE", "OBJ_OFFSET", "TABLE_SIZE", "ENCODED_SIZE", "CHARS_PER_WORD", "ATTRIBUTE_BYTES", "TIME_FUNCTION", "OBJ_ATTR", "ECHO_INPUT", "HEAD_INFO", "OBJECTS", "NO_PAGE", "TREE", "OBJ_XFER", "VOCABULARY", "MAX_LINE_LENGTH", "EMPTY_PAGE", "MAX_COUNT", "END_OF_TABLE", "PLUS_ERROR_1", "PLUS_ERROR_2", "ERR_OPCODE", "ERR_MEMORY", "ERR_HEADER", "ERR_PUT_PROP", "ERR_NEXT_PROP". * Renamed "prop_mask" to "PROP_NUM_MASK", "mode_mask" to "WORD_MASK" and "max_mem" to "MAX_BYTES". * Introduced the "BITS_PER_BYTE", "FIRST_ATTRIBUTE", "USE_TIME", "NEXT_BYTE_IS_LENGTH", "WORD_MASK", "PROPERTY_LENGTH ()", "PAGE ()", "OFFSET ()", "MOST_SIGNIFICANT_BYTE ()" and "LEAST_SIGNIFICANT_BYTE ()" macros. * Changed definitions of "byte", "word", "long_word", "signed_word" and "signed_long" from macros to typedefs. * Introduced the types byte_ptr, word_ptr, object_ptr, Page_Table_ptr and header_ptr instead of byte *, word *, object *, Page_Table * and header *. They are defined in terms of the macros "BYTE", "WORD", "OBJECT", "PAGE_TABLE" and "HEADER" since the Turbo C version needs to explicitly specify huge pointers. * The "jmp_op0", "jmp_op1" and "jmp_op2" arrays are now defined as being of type "ProcPtr". * Improved the "allocate ()" function. It will now allocate the page table as well as the pages. The previous version would also try to allocate the maximum amount of memory, regardless of whether the game actually required the full amount. This has been fixed. * The "pre-load" option was introduced. * In makefile, removed the "-v" option from the Turbo C entry. * The "LT ()" and "GT ()" functions were renamed "less_than ()" and "greater_than ()". * In "save_game ()" and "restore_game ()" functions in file.c, the way the z-machine's stack was saved contained a bug. The previous version used fread and fwrite to save and restore the stack. However, if a game saved using this method on a high- endian machine (68000) was restored on a little-endian machine (8088, etc.) the game would not run - the high and low bytes of the stack would apprear to have been swapped. The stack is now saved and restored word by word in a machine independent manner. * Recoded the PLUS function "get_key ()" properly ( the previous version was a kludge ) and added the support functions "read_the_key ()", "wait_for_key ()" and "special_gosub ()". Introduced the "KBD_HIT" and "ONE_SECOND" macros and the "default_kbd_hit ()" routine. * The "interp ()" routine was split into two parts: an initialisation part "init_interpreter ()" and the main loop "execute_opcode ()". This was done because the "special_gosub ()" function needed to call the main loop recursively. This also caused the way the game's status was recorded. Instead of a word representing the game's status, a boolean representing the stop condition is used instead. * Completed the PLUS version of the "rtn ()" opcode - dummy code was previously enclosed by comments. Version 3.04 - August 13, 1990. ------------------------------- *** The PLUS Interpreter is finally complete *** * Added the "MSC" directive for Microsoft C. The "MSDOS" directive is now used for the generic MS-DOS routines. * Modified the makefile to generate the infocom.col file. In the Microsoft C definitions, added graphics.lib to all entries. In the Turbo C entry, defined the TC_LIB macro and removed the - DMSDOS definition. * Defined the macro "PROPERTY_NUMBER". * Fixed a bug in the "split_screen ()" function. If it is called with a non-zero parameter, the upper window should not be erased in the PLUS version. * In file.c, redefined "name_size" as "NAME_SIZE". * Changed the script file from having the fixed name of "transcript" to allowing the user to enter it. Also modified the "script_char ()" routine to ignore special characters. The line- feed to carriage-return translation is not necessary and was also removed. * Casting was added to integer constants to prevent compiler and lint complaints. * To fix a display mode bug the "raw_echo ()" function was added. It uses "printf ()" to directly print ANSI escape sequences. If "echo ()" is used instead, the new output capabilities of the PLUS interpreter may cause the string may be printed to a buffer instead of to standard output, delaying the changing of the printing modes. * Replaced all "printf ()" calls ( except in "raw_echo ()" ) with calls to new functions "echo ()", "hex_echo ()", "print_item ()" and "PUT_CHAR ()". * Fixed a bug in the "compare2 ()" function which prevented the PLUS interpreter from recognising certain words in the game's vocabulary. PLUS series games keep a list of synonyms by which all objects are known - the bug prevented the last synonym in the list from being checked. * In options.c, fixed a "bug" in the "show_vocab ()" function. Some games contain words in their vocab lists which do not have the end_of_word bit set. In these cases, the "print_coded ()" routine goes crazy. To fix this, the "show_vocab ()" routine was modified to directly call the "decode ()" routine the correct number of times, regardless of the end_of_word bit. * In property.c, added castings in the "load_word_array ()", "save_word_array ()" and "save_byte_array ()" functions to correctly calculate addresses. The logic of the "next_addr ()", "get_prop_addr ()" and "get_p_len ()" was also redone to enhance the clarity of their algorithms. * In machine.h and io.c, instead of having generic MS-DOS I/O routines, we now have three sets of routines - one for Microsoft C, one for Turbo C and a generic MS-DOS set of routines. The Microsoft C and Turbo C routines use the graphics library routines to enhance the interpreter's output - the screen height and width are also determined from the graphics library routines allowing 43 and 50 line mode support. The Microsoft C version uses a separate text page for the interpreter's output. * In io.c, fixed a bug in the putchar routines. The text attributes are now to be set regardless of the setting of the "enable_screen" flag. It was found that in some cases, the text attributes were being changed while the screen was disabled and hence were being lost - the screen was then enabled and the text printed, but in the wrong mode. * In io.c, fixed a bug in the "out_char ()" routine. A line_feed is printed only if the screen is enabled. * In io.c, the "ansi_erase_window ()" was modified to include a SIMPLE_ANSI variant some ANSI implementations support only the erase line ANSI sequence and not the erase screen ANSI sequence. MS-DOS's ANSI.SYS driver is one such implementation. Version 3.05 - August 29, 1990. ------------------------------- *** This is the first version to include ADVANCED Interpreter Routines *** * Added code to handle the new fields in the ADVANCED header. * Added ADVANCED Interpreter Routines to plus_fns.c. They are: "gosub4 ()", "gosub5 ()", "call ()", "branch_true ()", "num_local_params ()", "logical_shift ()" and "arithmetic_shift ()". * Replaced entries $1B, $1C, $38, $3B - $3E in the "jmp_op2" opcode table with the dummy functions "new_opcode0 ()", "new_opcode1 ()" and "new_opcode2 ()". * Increased the size of the "jmp_op2" opcode table from $3F entries to $50 entries. * Split the tail end of the "operand3 ()" function into a separate function called "call_function ()". * Added the "operand4 ()" function and other code to handle the new 0xBE opcode. * Updated the way the 0xEC opcode parameters are handled and added code to deal with the new 0xFA opcode. * Changed the "input ()" function to support the ADVANCED interpreter. The ADVANCED version requires the "input ()" function call "store ()" before returning. * Changed the opcode for "not ()" in the ADVANCED version. * Modified the "pop_stack ()" opcode for the ADVANCED Interpreter. * The "gosub ()" opcode was modified to call the "call ()" function in the ADVANCED Interpreter. This function stores the call type (FUNCTION or PROCEDURE) on the stack along with the number of parameters that this gosub call pushed onto the stack. It also does not decrement the "stack_var_ptr". The "rtn ()" function was similarly modified in order to reverse the "gosub ()" call. * Modified the "get_var ()" and "put_var ()" opcodes for the ADVANCED interpreter. This is due to the change in the way "stack_var_ptr" is calculated in the "gosub ()" opcode. * Added a test to see whether the "game_file" or "script_file" is open before closing them. * Fixed a bug in the "script_char ()" routine. We must temporarily turn off the "SCRIPT_MODE" bit that is pointed to by "script_status_ptr" because "script_on" must remain "FALSE" until the script file is open and "open_script ()" calls "filename ()" which calls "read_char ()" which calls this routine which will try to open a script file by calling "open_script ()" ... The "SCRIPT_MODE" bit is turned back on if the script file is successfully opened. * Pre-initialised global variables in globals.c * Changed the entries in the opcode tables from "save_game" and "restore_game" to the macros "save" and "restore". * In the "out_char ()" function in io.c, swapped the order of the "PUT_CHAR ()" and "script_char ()" calls. * Cleaned up the way the interpreter quits and moved the calls to the clean up functions from "quit ()" to "main ()". Version 3.06 - October 11, 1990. -------------------------------- * Disable the "save_game ()" and "restore_game ()" opcodes in ADVANCED mode. * Changed name of "echo ()" to "display ()" because there is an "echo ()" function in CURSES. * Also changed "hex_echo ()" to "hex_display ()" and "raw_echo ()" to "raw_display ()". * Cleaned up some definitions in infocom.h. * Added default INIT_SIGNAL stub - it did not actually do anything. * Added "interpreter_number" header byte definitions. * In input.c, the function "input ()" was changed to include support for the "default _parameter_stack" which is an ADVANCED interpreter addition. It is included for all versions since it actually has no effect on anything but the ADVANCED version. * In input.c, changed the logic in the "read_line ()" function. * In input.c, introduced the "advanced_parse_buffer ()" function for use by the ADVANCED interpreter instead of the "parse_buffer ()" routine used by the other versions. * Included the following ADVANCED functions in input.c: "scan_buffer ()","buffer_copy ()","get_code ()","advanced_parse_buffer ()". * Because of the way certain HP terminals do underlining and inverse characters, the TERMCAP entries in io.c were modified to turn off any inverse or underline modes before quitting or moving the cursor (including when printing a '\n'). Code was added to keep track of the current text mode and restore them after the cursor has been moved. * In io.c, introduced new functions to get the current x and y cursor coordinates: "default_get_x ()" and "default_get_y ()". Because of these functions, the individual "putchar ()" routines no longer need to keep track of which screen line they are currently printing on. Also introduced a generic "default_save_cursor ()" and modified the existing "default_restore_cursor ()" to use the new "GET_X ()" and "GET_Y ()" macros. This allowed the replacement of specific save and restore cursor routines with the generic ones in many cases. * In the TERMCAP routines, support was added for "Terminal_Init" and "Terminal_Exit" strings. This prompted the introduction of the "tcap_exit_io ()" routine instead of the "unix_exit_io ()" routine. * In CURSES routines, removed "refresh ()" calls from everywhere except the new "curses_get_ch ()" routine (the "curses_get_ch ()" routine is used instead of the "getch ()" routine for this reason). * In "curses_putchar ()", only SYS_V CURSES calls for changing text modes (inverse and underline) were used. The equivalent BSD CURSES calls have been added. * Included the following ADVANCED functions in plus_fns.c: "parameter_copy ()","throw_away_stack_frame ()","parse ()", "encrypt ()","block_copy ()","print_text ()","clear_flag ()", "set_flag ()","array_test ()","test_byte_array ()". * Modified "compare2 ()" function in plus_fns.c for ADVANCED operation. * Modified "set_mode ()" function in plus_fns.c to check its mode parameter is < 5 in ADVANCED operation. * Modified "get_key ()" function in plus_fns.c to firstly flush the print buffer in ADVANCED operation. * Included a "msc_adv" entry to the makefile. Version 3.07 - November 21, 1990. --------------------------------- * Added ADVANCED support to "set_current_window ()", "split_screen ()" and "restore_cursor_position ()" in enhanced.c. Before setting the current window in ADVANCED mode, the print buffer should be flushed. After setting a split screen in ADVANCED mode, move the cursor to the bottom left hand side of the screen. If "restore_cursor_position ()" is called in ADVANCED mode without the cursor having been saved, it is moved to the bottom left hand corner of the screen. * In the "clear_screen ()" function of plus_fns.c, after erasing the entire screen, the cursor is not placed at the bottom left hand corner of the screen if it is in ADVANCED mode. * Added signal handling to facilitate a graceful exit from the interpreter when etc. is received by the program. This affects infocom.h, machine.h, globals.c, infocom.c, init.c and io.c. * In the previous TERMCAP version, any text modes such as inverse or underline are turned off before the cursor is moved. However, funny things happen if these modes are turned off if they are not in fact currently turned on. Hence code was added toturn these modes off only if they are currently on. * Added "-ltermcap" to the BSD CURSES entries in the makefile. * To tidy up the display, a '\n' is printed and a refresh performed when leaving CURSES. * Fixed a bug in the CURSES routines in io.c. The "getyx ()" macro was used incorrectly. Version 3.08 - May 7, 1991. --------------------------- * Added VOID as the return type of most functions. * Changed the Standard Version of "read_header ()" to allow VERSION_1 and VERSION_2 files to be accepted. * In message.c, changed decoding routines to support VERSION_1 and VERSION_2 encodings. * Changed "init ()" to set max_blocks to 64 K for VERSION_1 and VERSION_2 since "verify_length" is not available in these headers. Also call "init_message ()". * In plus_fns.c, fixed bugs in the ADVANCED "print_text ()" routine. * For VERSION_4 and VERSION_5, in "init_interpreter ()" changed value of screen_width stored in the header from the actual screen width - 1 to actual screen width. This was required for the "print_text ()" bug fix - it was initially wrong. * In all "putchar ()" routines, translate character '\0' to ' ' before printing. This was required to fix a problem encountered in Beyond Zork where the text description of the initial location is printed in inverse and has a gap on the end of one line which should not be there. Version 4.00 - March 20, 1992. ------------------------------ *** This is the first version to play all version 1,2,3,4 and 5 data files *** * Changed type "VOID" to "Void" because of a definition clash with some versions of Curses. * Changed type "Boolean" to "boolean" to be consistent with the current type naming conventions used in the rest of the files. * Changed type "ProcPtr" to "proc_ptr" to be consistent with the current type naming conventions used in the rest of the files. * Changed types "Page_Table" and "Page_Table_ptr" to "page_table_t" and "page_table_ptr" to be consistent with the current type naming conventions used in the rest of the files. * Removed the #ifdefs for ENHANCED, PLUS and ADVANCED. Explicit checking of the z_code_version field of the data_head variable are used to distinguish between versions. This was done to allow a single interpreter to execute any data file instead of having to build explicit interpreters for each data file type using compile-time #ifdefs. * Changed the macro "TOP_SCREEN_LINE" to "STD_TOP_SCREEN_LINE" and "PLUS_TOP_SCREEN_LINE". A global variable "top_screen_line" was then introduced to hold the value of the top screen line applicable to the current data file. * Changed the definition of the "header_ptr", "byte_ptr", "object_ptr" and "page_table_ptr" types. They are usually the same as "header *", "byte *", "object *" and "page_table *" except for MS-DOS compilers, where they are explicitly defined as HUGE (the latter form may or may not be HUGE, depending upon the memory model chosen). All references that possibly require the HUGE qualifier are now defined in terms of the "header_ptr", "byte_ptr" or "object_ptr", while those that do not matter are now defined as "header *", "byte *" or "object *". Note that the "object" and "object_ptr" no longer exist - "std_object" and "plus_object" types replace "object" and their use depends upon the data file being run. Similarly, "std_object_ptr" and "plus_object_ptr" replace the "object_ptr" type. * The "word_ptr" type is now obsolete - "word *" is used instead since no "word_ptr" references required these pointers to be HUGE on MS-DOS compilers. * The macro MAX_VERSION was defined - it is the highest Z-Code version that the interpreter can understand. It is used in the "read_header ()" function in "file.c" to determine whether this version of the interpreter can handle the current data file. * The fields "unknown5", "unknown6" and "padding3" were added to the "header" type. * In file "fns.c", split the "random ()" function into "std_random ()" and "plus_random ()". * In file "globals.c", the "use_internal_buffer" variable is set to FALSE by default. * In file "globals.c", a global variable "main_vocab_list" was introduced. This is needed by the ADVANCED input processing routines. * In file "globals.c", the "obj_list" variable has become "std_obj_list" and "plus_obj_list". It depends upon the current data file as to which one is used. * Added the "enhanced" run-time flag - this is used instead of #ifdef ENHANCED. Also defined the NO_OPTIONS macro. * Function declarations were removed from "globals.c" - they are already in "infocom.h". "new_opcode1 ()" was moved from "globals.c" to "init.c". * The "save ()" and "restore ()" functions have been renamed "save_game ()" and "restore_game ()". * The functions "pop_stack ()", "get_link ()", "get_holds ()", "get_loc ()", "get_p_len ()", "remove_obj ()", "p_obj ()", "rtn ()", "print2 ()", "check_loc ()", "test_attr ()", "set_attr ()", "clr_attr ()", "transfer ()", "getprop ()", "get_prop_addr ()", "get_next_prop ()", "gosub ()", "put_prop ()", "random ()" have been split into a standard interperter function and a plus interperter function. * The jump tables in "globals.c" have been changed to reflect a VERSION_1 Z-Code interpreter only. Everything else is an illegal opcode. It is now up to the initialisation functions to identify the current data file's Z-Code type and patch the jump tables accordingly. * Added the -n ENHANCED, -s SHOW_PROPS and -x EXTENDED_VOCAB run-time options. * Improved macro definitions in "infocom.h". Removed the Z_INTERP and ATTRIBUTE_BYTES macros. Changed the PAGE, OFFSET, CHARS_PER_WORD, ENCODED_SIZE, OBJ_SIZE, OBJ_OFFSET, PROP_NUM_BITS, PROP_NUM_MASK, PROPERTY_LENGTH and PROPERTY_NUMBER macros to separate STD_ and PLUS_ macros. Defined the STD_OBJ_ADDR and PLUS_OBJ_ADDR macros. * Changed the structure type "object" into separate "std_object" and "plus_object" types. * Changed the "init ()" routine in "init.c" to correctly initialise the new standard interpreter and plus interpreter variables based on the current data file. A new function "init_opcodes ()" was added to correctly set up the interpreter jump tables. * Removed the global arrays "coded[]" and "the_word[]" from "input.c". * Introduced the globals variables "initial_chop" and "has_initial_chop" in "input.c". The function "init_vocab ()" was added to initialise the input routine global variables, depending upon the current data file's Z-Code version. This routine replaces some of the code from the "init_input ()" function. * In file "input.c", replaced the "parse_buffer ()" function by the "std_parse_buffer ()" and "plus_parse_buffer ()" routines. * In file "input.c", the "look_up ()" function parameter list has changed - it now requires the "encoded_size" parameter since its size is different for different data files. Added the "coded[]" parameter to the "get_code ()" function - this is now passed as a parameter instead of being a global variable. * The call to "advanced_parse_buffer ()" is now being passed the correct parameter in the "vocab_strt" and "ignore_offset" fields. The "advanced_parse_buffer ()" function now correctly handles parsing for version 5 games. * The LONG_ALLOCATE option has been removed - it is now the only type of allocation available. The RESERVE_RAM option has also been removed - this was originally added to support Macintoshes with very little RAM, a situation which has now changed. * In file "io.c", a "tc_getch ()" was added and used instead of the standard "getch ()" routine. The difference is that "tc_getch ()" handles CTRL_C signal processing. * Changed the ANSI and SIMPLE_ANSI macros to ANSI_ESCAPE and SIMPLE_ANSI_ESCAPE respectively. Added the ANSI_COLOR macro. * In file "io.c", added routines to parse a new default colour file ".infocomrc" and added the ANSI_COLOR routines. The default colour file is still "infocom.col" for the MS-DOS routines. Initially, ANSI escape sequence support was included primarily for MS-DOS machines - it can now be used by UNIX machines as well. Hence the creation of "ansi_exit_io ()" and modification to "ansi_init_io ()". Fixed the save and restore cursor routines to operate only if those escape sequences exist on the target system. * In file "io.c", declared the UNIX structures as static, added a signal_handler "signal_winch ()" to handle changes in size of Sun windows. Added extra checking to the TERMCAP routines in regard to saving and restoring the cursor. A call to "setbuf ()" was also added. * In file "io.c", added calls to "scrollok ()" and "idlok ()" in the "curses_init_io ()" routine. This improves the Curses interface somewhat. * In file "io.c", started adding interface routines for THINK C Version 4.0 for the Macintosh. New routines were necessary since the old ones relied on manipulating some of the internal variables of their standard library calls. In newer versions of the compiler, these internal variables are now declared as static and hence are not visible to the application program - hence the need for the new routines. THESE ARE NOT YET COMPLETE !!! * In file "jump.c", changed the "gosub ()" routine into "std_gosub ()", "plus_gosub ()" and "adv_gosub ()" routines. The "rtn ()" routine was changed into the "std_rtn ()" and "adv_rtn ()" routines. Since "ret_true ()" and "ret_false ()" rely on the "rtn ()" routine, these now use the jump table to execute the version of the "rtn ()" command that is in current use. The "pop_stack ()" function was also split into "std_pop_stack ()" and "adv_pop_stack ()" functions. * In interpreters prior to VERSION_5, the "stack_var_ptr" pointed to the first local variable on the z_code stack. In VERSION_5 and subsequent interpreters, the "stack_var_ptr" points to the stack entry above the first local variable on the z_code stack. However, there is no reason for us not to adopt the VERSION_5 method for all versions of the interpreter. This decision affects the following opcodes: gosub, std_rtn, load_var & put_var. * Removed the BYTE, WORD, OBJECT, PAGE_TABLE and HEADER macros. Added the HUGE macro for MS-DOS support. * AZTEC C for the Macintosh is no longer supported - THINK C 4.0 support is starting to be added instead. * In file "machine.h", checking was added for the Curses "cbreak ()" function. If this does not exist, "crmode ()" is used instead. * The "makefile" has been simplified by the removal of the ENHANCED, PLUS and ADVANCED options. ANSI_COLOR entries were added. The entries for TURBOC and MSC have been enhanced, with the "qc" build option also being added. * In file "message.c", changed the "encode ()" function into "std_encode ()" and "plus_encode ()". * In file "options.c", added the macros MAX_CHARS_PER_WORD and BYTE_DISPLAY. Modified the "show_vocab ()" routine to allow the new EXTENDED_VOCAB option. Modified the "show_objects ()", "show_tree ()" and "obtree ()" functions to handle the current data file Z-Code type dynamically by passing it as a parameter. Defined a new function "prop_name ()" which determines whether the name of an object is valid (that is, of non-zero length). Also defined functions "show_std_props ()" and "show_plus_props ()" for use by the "show_tree ()" and "show_objects ()" functions with the new SHOW_PROPS option. * In file "page.c", changed the "fix_pc ()" routine back to using the old method of calculating the current program counter value. This was done because the new method, although faster, was performed incorrectly on some compilers (they did not handle modulo operations (%) with negative arguments correctly). * In file "plus_fns.c", the "compare2 ()" function has been split into the "plus_compare2 ()" and "adv_compare2 ()" functions. The "gosub2 ()" and "special_gosub ()" functions were changed to use the opcode jump table to execute the current version of the "gosub ()" command (since these differ in version 4 and version 5 games). * In file "plus_fns.c", the "set_text_mode ()" function was slightly modified. In interpreters prior to VERSION_5, the "mode" parameter in the "set_text_mode ()" command is not checked before being incremented and passed to "print_char ()". In VERSION_5 and subsequent interpreters, the "mode" parameter is checked first. However, there is no reason for us not to adopt the VERSION_5 method for all versions of the interpreter. * In file "print.c", the "init_print ()" function was modified to correctly set the new "top_screen_line" global variable. * In file "status.c", the "copy_string ()" function was changed to return a pointer to the end of the destination string. * In file "variable.c", changed the "load_var ()" and "put_var ()" functions to interpret the meaning of the "stack_var_ptr" global variable in a way that is consistent across all Z-Code types. Version 4.01 - September 26, 1992. ---------------------------------- *** This is the first version to be officially released on the Internet *** * In "makefile", added explanantion entries for ANSI_COLOR and CURSES_COLOR. Changed all references of "infocom.col" to "infocom.rc". Removed the build target for "infocom.col" and replaced it with one for the new "infocom.rc" and ".infocomrc" colour file formats. Added the "-DMSC" option to the Microsoft C build line (this was previously omitted since some versions of make for MS-DOS define this by default). Enhanced the UNIX build entries (use gcc by default) and added some build options for CURSES_COLOR and TERMINFO. * In file "file.c", initialised the "script_status_ptr" global variable. * Moved calls to "init_script ()" from "init.c" to "infocom.c" - this fixes a subtle bug which ocurred with the setting of the "enhanced" flag. Some "init_io" routines require knowledge of whether or not it is set, and these are called before the game file is examined to determine its Z-Code type. * In files "init.c", "plus_fns.c" and "infocom.h", the "clear_screen ()" and "beep ()" functions were renamed to "do_clear_screen ()" and "do_beep ()" to prevent clashes with some versions of the termcap and curses library function names. * In file "io.c", added code to handle a generic configuration file, containing colour information, etc. Code to do similar things in the MSC, TURBOC and ANSI_ESCAPE sections have been removed and adapted to use these new generic routines. * In file "io.c", changed the parameter lists of the "default_signal_init ()", "signal_shit ()", "signal_chit ()" and "signal_winch ()" functions. * In file "io.c", added support for parametised delete_line to the TERMCAP routines. * In file "io.c", added the TERMINFO interface. * In file "io.c", changed the Curses colour routines to use the new generic routines. * In file "machine.h", added new macros RCFILE, CURSES_COLOR and WANT_COLOR. Added test for __STDC__ to define the Void macro. Added support for TERMINFO interface. Moved the #ifdef test for the Curses "cbreak ()" function to "io.c". * In file "plus_fns.c", fixed a bug in the "set_cursor_posn ()" function. In version 5 interpreters, it should flush the print buffer before moving the cursor. This bug was found with a version 5 Hitchhiker's Guide data file. * In files "enhanced.c", "file.c", "fns.c", "init.c", "input.c", "io.c", "message.c", "object.c", "options.c", "page.c", "plus_fns.c", and "status.c" - added some type casts to fix any compiler/lint complaints. * In file "io.c", added function declarations to fix any compiler/lint complaints. Version 4.01 - Known Bugs. -------------------------- * The interface for THINK C 4.0 for the Macintosh is currently broken. * There are still several version 5 opcodes and header flags which are unknown. Their absense should not affect the playing of version 5 data files. * It does not support sound opcodes for any data file version. Nor does it support the #comm, #reco and #unre debugging commands in some games. This will definitely be fixed in the next release. Version 4.01 - General Release. Current Porting List: ----------------------------------------------------- Machine C Compiler Interpreter Porting details ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 128K Apple Macintosh Aztec C Version 1.06F Version 2.00 No longer supported. DEC VAX 11/780 UNIX V7 cc Version 2.00 gould cc Version 2.00 Amiga Aztec C Version 2.00 Pyramid 9810 cc Version 2.00 Pyramid 90x cc Version 2.00 Osiris cc Version 2.00 DEC PDP-11/? UNIX V? cc Version 2.00 EXTENSIVE mods to fix problems with signed chars. VAX VMS cc Version 2.00 Add #define times ttmes to fix multiply defined symbol problem. [infocom.h] Apple Mac Plus Lightspeed C 2.01 Version 4.01 The Macintosh interface is broken for THINK C 4.0. This is currently being fixed. IBM PC/AT Microsoft C 6.0a & 7.0 Version 4.01 HP-9000/320 HP-UX cc Version 4.01 Apollo DN-4500 SR 10.1 cc Version 4.01