mirror of
https://github.com/erkyrath/infocom-zcode-terps.git
synced 2026-01-21 18:05:42 +00:00
1549 lines
42 KiB
Plaintext
1549 lines
42 KiB
Plaintext
|
|
* ___________________________________________________________________________
|
|
*
|
|
* YZIP INTERPRETER FOR THE MACINTOSH
|
|
*
|
|
* INFOCOM, INC. COMPANY CONFIDENTIAL -- NOT FOR DISTRIBUTION
|
|
*
|
|
* WRITTEN BY DUNCAN BLANCHARD
|
|
* ___________________________________________________________________________
|
|
*
|
|
|
|
* YZIP-MAC MODIFICATION HISTORY:
|
|
*
|
|
* 01 APR 88 DBB currow, curcol, clearLines - NOW 0-ORIGIN
|
|
* 02 MAY 88 DBB ADDED YZIP WINDOW CALLS, ETC
|
|
* 06 JUL 88 DBB ADDED ZBEEP, NOW READLN -> ZBEEP -> DOSOUND
|
|
* WAS TRASHING D1-D3; FIXES 'D3BUG', I THINK
|
|
* ADJUSTED PLENTH/PSTART FOR MOBY GAMES
|
|
* YZIP (VERSION) #1 FROZEN [NEW ID SCHEME]
|
|
* YZIP #2:
|
|
* 15 NOV 88 DBB CHANGED UNHUFFH SO CAN BE INTERRUPTED
|
|
* 30 NOV 88 DBB ADDED PCHRSET SETUP IN INIT, MODIFIED CHRBYT/ZWORD
|
|
*
|
|
* YZIP #3:
|
|
* 16 DEC 88 DBB FIXED SLIGHT BUG IN SHRINK75 LOOP COUNTER
|
|
* ShowGFXS now supports incremental display
|
|
|
|
* XZIP-MAC MODIFICATION HISTORY:
|
|
*
|
|
* 14 JUL 87 DBB PORTED FROM ST
|
|
* 14 SEP 87 DBB XZIP 'A' FROZEN
|
|
* 05 OCT 87 DBB (PASCAL) ROW/COL VARS ALLOW BIG-SCREEN WINDOW
|
|
* TIMEOUT COUNTER STOPS WHEN DA ACTIVE
|
|
* PUTLIN1 <-> PUTLIN
|
|
* OPINPUT/OPPRNT CALL PUTLIN (FIX HINT-WRAP BUG)
|
|
* FKEYS THAT AREN'T TCHARS REJECTED IN OPREAD
|
|
* ADDED UNDO AND MOUSE SUPPORT CHECKS
|
|
* 1-CHAR INPUT DISABLES MENU "CMD-STRINGS"
|
|
* 13 OCT 87 DBB DESKTOP RESTORE SETS SL REFRESH BIT
|
|
* BUFFER NOW DUMPED IN CURSET/SPLIT/SCREEN
|
|
* 14 OCT 87 DBB TO ALLOW SCREEN1 BUFFERING:
|
|
* BUFFER ALSO ZEROED FOR ABOVE 3 (CURSOR MOVED)
|
|
* SIZEQP NO LONGER SHRINKS BUF SIZE (ST ITALIC HACK)
|
|
* XZIP 'B' FROZEN
|
|
* 16 FEB 88 DBB ADDED SOUND, SOUND INTERRUPTS (GAMINT)
|
|
* FIXED COPYT/PRINTT PAGING BUG
|
|
* MOVED 'UNDO' SETUP BEFORE PAGING
|
|
* XZIP 'C' FROZEN
|
|
|
|
* XZIP-ATARI MODIFICATION HISTORY:
|
|
*
|
|
* 02 FEB 87 DBB MODIFIED EZIP
|
|
* 21 MAY 87 DBB ADDED LOWCORE, MOUSE VARS
|
|
* 02 JUN 87 DBB MOVED DUPNAM CHECK (_exist_file) INTO C
|
|
* 25 JUN 87 DBB CHANGED OPFONT TO IGNORE REDUNDANT FONT CHANGES
|
|
* FIXED STACK BUG, RESTORE VS. TIMER INTERRUPT
|
|
* 13 JUL 87 DBB BUFFER FLUSHED IN OPSCRN, OPDIRO, OPERASE, OPCLEAR
|
|
* CHKDSK MODIFIED FOR FULL PRELOAD SITUATION,
|
|
* RESTART, $VER MAKE SPECIAL CHECKS FOR GAME DISK
|
|
* XZIP 'A' FROZEN
|
|
|
|
* ZIP/EZIP (ATARI) MODIFICATION HISTORY:
|
|
*
|
|
* 02 AUG 85 ZIP A FROZEN
|
|
* 09 AUG 85 CLSGAM CHECKS WHETHER GAME FILE WAS OPENED
|
|
* 09 AUG 85 REBUILT OBJECT FILE WITH NEW LIBRARIES,
|
|
* INCREASED MACHINE STACK TO 2K (IN ZIPSTART)
|
|
* 09 AUG 85 ZIP B FROZEN
|
|
* EZIP A FROZEN
|
|
* 10 FEB 86 PURE PRELOAD MAY EXCEED 32K (PUT, PUTB, PTSIZE)
|
|
* OPSPLT (EZIP) NO LONGER CLEARS SCREEN
|
|
* 10 APR 86 CHANGED PUTCHR (SPECIAL HANDLING FOR TABLE OUTPUT)
|
|
* ADDED SCRNAM, SCRIPTS SAVE/RESTORE FILENAMES
|
|
* 18 APR 86 CHANGED NXTLIN/BUFOUT/LINOUT. BUFOUT CALLS NXTLIN
|
|
* SO [MORE] IS TIMED CORRECTLY DURING BOLDFACE, ETC
|
|
* CHANGED OPATTR AND DQUE INIT, FOR ITALICS HACK
|
|
* FIXED GETMEM, PREVENTS ST BUG WITH ODD MEM REQUEST
|
|
* 08 MAY 86 FIXED QUECHR (QCX2A), ALLOW FOR EMPTY [DUMPED] BUFFER
|
|
* CHANGED OPREAD, ONLY OVERFLOW WORDS ARE FLUSHED
|
|
* 13 MAY 86 LINES(A6) NOW NORMALLY RESET TO ZERO, UPDATED INCHR
|
|
* OPINPUT CHECKS VOBUFF(A6)
|
|
* OPSPLIT CHECKS MAXIMUM SIZE OF split_row
|
|
* NXTLIN TURNS OFF HIGHLIGHTING BEFORE PRINTING [MORE]
|
|
* COMBINED READLN AND INCHR
|
|
* EZIP B FROZEN
|
|
|
|
* XZIP: SUGGESTIONS FOR FURTHER OVERHAUL
|
|
*
|
|
* - WHEN READING ARGBLK, INDEX OFF A6, NOT A0.
|
|
* - MAKE ALL OPERATORS TAKE AN ARGBLK RATHER THAN REGISTER ARGS, NOW THAT
|
|
* SO MANY HAVE OPTIONALS. FOR CONVENIENCE, PASS A1 -> FIRST ARG
|
|
*
|
|
* - IMPLEMENT HIGHLIGHTING USING SPECIAL CHARS, PUT DIRECTLY INTO THE OUTPUT
|
|
* STREAM/BUFFER. LOW-LEVEL OUTPUT ROUTINE SCANS FOR THESE SPECIALS.
|
|
* AVOIDS NEED FOR MUCH SPECIAL FLUSHING OF BUFFER.
|
|
*
|
|
|
|
* ---------------------------------------------------------------------------
|
|
* REGISTER CONVENTIONS
|
|
* ---------------------------------------------------------------------------
|
|
|
|
* GENERALLY, SINGLE ARGUMENTS ARE PASSED IN D0 OR A0. SINGLE VALUES ARE
|
|
* LIKEWISE RETURNED IN D0 OR A0. IN ANY CASE, THESE ARE SCRATCH REGISTERS
|
|
* AND NEED NOT BE PRESERVED. ALL OTHER REGISTERS, EXCEPT WHERE OTHERWISE
|
|
* SPECIFIED, MUST BE PRESERVED ACROSS EACH SUBROUTINE CALL. NOTE THAT
|
|
* TOP-LEVEL ROUTINES, OPx ROUTINES, ARE EXCLUDED FROM THIS RESTRICTION.
|
|
|
|
* DEDICATED REGISTERS:
|
|
* A7 = SYSTEM SP
|
|
* A6 = FRAME POINTER FOR ZIP VARIABLES *** STATIC ***
|
|
* A5 = unused in this version
|
|
* A4 = VIRTUAL SP
|
|
|
|
* ---------------------------------------------------------------------------
|
|
* ASSEMBLY FLAGS
|
|
* ---------------------------------------------------------------------------
|
|
|
|
* THE FIRST TWO FLAGS EXIST ONLY FOR HISTORIC REASONS:
|
|
* XZIP CAN'T BE CONDITIONALLY ASSEMBLED AS EZIP OR CLASSIC ZIP
|
|
|
|
EZIP EQU 1 * ALWAYS ON (XZIP)
|
|
CZIP EQU 0 * ALWAYS OFF (XZIP)
|
|
|
|
DEBUG EQU 0 * IF ON, ASSEMBLES DEBUGGING CODE
|
|
D3BUG EQU 0 * REG D3 BEING TRASHED; TRY TO PINPOINT IT
|
|
* * (FIXED IN READLN/ZBEEP)
|
|
|
|
* ---------------------------------------------------------------------------
|
|
* INDEXING BASE FOR THE DISPATCH TABLE
|
|
* ---------------------------------------------------------------------------
|
|
|
|
ZBASE NOP
|
|
|
|
* DATA * ST LATTICE: BEGIN THE DATA SEGMENT
|
|
* DC.W 0 * (KLUGE TO AVOID AN OBSCURE LINKER BUG ASSOCIATED
|
|
* CODE * WITH SUCCESSIVE 'DC' STATEMENTS)
|
|
|
|
* ---------------------------------------------------------------------------
|
|
* GENERAL MACRO DEFINITIONS
|
|
* ---------------------------------------------------------------------------
|
|
|
|
* MACRO ZERO
|
|
* MOVEQ #0,%1 * CLEAR A REGISTER QUICKLY (BOTH WORDS)
|
|
* ENDM
|
|
|
|
* MACRO SOB * SUBTRACT ONE AND BRANCH IF NOT ZERO
|
|
* SUBQ.W #1,%1
|
|
* BNE.S %2
|
|
* ENDM
|
|
|
|
* PRIOR TO CALLING A PASCAL FUNCTION, MUST MAKE SPACE ON THE STACK
|
|
* FOR THE RESULT, WORD OR LONG. [FOR 'C' FUNCTIONS THIS WOULD BE A NOP.]
|
|
|
|
MACRO
|
|
RESWORD
|
|
SUBQ.L #2,SP * QUICKEST INSTR
|
|
*** TST.W -(SP)
|
|
ENDM
|
|
|
|
MACRO
|
|
RESLONG
|
|
SUBQ.L #4,SP
|
|
ENDM
|
|
|
|
* AFTER CALLING A PASCAL FUNCTION, POP THE RESULT FROM THE STACK INTO D0
|
|
* (PASCAL ONLY; MIMICS 'C' CONVENTION FOR PORTABILITY).
|
|
|
|
MACRO
|
|
POPWORD
|
|
MOVE.W (SP)+,D0
|
|
ENDM
|
|
|
|
MACRO
|
|
POPLONG
|
|
MOVE.L (SP)+,D0
|
|
ENDM
|
|
|
|
* SET RESULT FLAGS [C ONLY, UNNECESSARY IN PASCAL]
|
|
|
|
MACRO
|
|
TSTWORD
|
|
*** TST.W D0
|
|
ENDM
|
|
|
|
MACRO
|
|
TSTLONG
|
|
*** TST.L D0
|
|
ENDM
|
|
|
|
* WHEN CALLING ANY MAC PASCAL ROUTINE, THESE ARE THE REGISTERS THAT
|
|
* SHOULD NORMALLY BE PRESERVED, AND WHICH PASCAL MIGHT TRASH.
|
|
|
|
MACRO
|
|
SAVEREGS
|
|
*** MOVEM.L D1-D7/A1-A5,-(SP) * ULTRA-CONSERVATIVE SET
|
|
MOVEM.L D1-D2/A1,-(SP) * STANDARD SET FOR MAC PASCAL
|
|
ENDM
|
|
|
|
MACRO
|
|
RESTREGS
|
|
*** MOVEM.L (SP)+,D1-D7/A1-A5
|
|
MOVEM.L (SP)+,D1-D2/A1 * (DON'T AFFECT FLAGS)
|
|
ENDM
|
|
|
|
* ---------------------------------------------------------------------------
|
|
* GENERAL EQUATES
|
|
* ---------------------------------------------------------------------------
|
|
|
|
ARG0 EQU 0 * ARGUMENT COUNT
|
|
ARG1 EQU 2 * ARGUMENT OFFSETS IN PARAMETER BLOCK
|
|
ARG2 EQU 4
|
|
ARG3 EQU 6
|
|
ARG4 EQU 8
|
|
|
|
SKIP EQU 0 * 'PLACEHOLDER' IN DEFAULT-PARAMETER BLOCK
|
|
DBQLEN EQU 16 * LENGTH OF DEBUGGER HISTORY QUEUE
|
|
|
|
*** THIS INFO IS NOW DERIVED ELSEWHERE ...
|
|
* YCHAR EQU 12 * CHAR CELL PIXEL SIZE (MAC, MONACO 9)
|
|
* XCHAR EQU 6
|
|
|
|
IF EZIP THEN
|
|
|
|
VCHARS EQU 9 * MAX CHARS IN AN EZIP VOCAB WORD
|
|
ZCHARS EQU 6 * EZIP: BYTES PER ZWORD
|
|
|
|
OPLEN EQU 63*2 * OBJECT PROPERTY DEFAULT TABLE LENGTH
|
|
OLEN EQU 14 * OBJECT LENGTH
|
|
|
|
LOC EQU 6 * PARENT
|
|
NEXT EQU 8 * NEXT SIBLING
|
|
FIRST EQU 10 * FIRST CHILD
|
|
PROP EQU 12 * PROPERTY TABLE POINTER
|
|
|
|
PMASK EQU $003F * PROPERTY NUMBER IS LOW 6 BITS (OF FIRST ID BYTE)
|
|
PLBIT EQU 6 * PROPERTY LENGTH BIT (IF LENGTH IS TWO OR ONE)
|
|
|
|
ENDIF
|
|
IF CZIP THEN
|
|
|
|
VCHARS EQU 6 * MAX CHARS IN A ZIP VOCAB WORD
|
|
ZCHARS EQU 4 * CZIP: BYTES PER ZWORD
|
|
|
|
OPLEN EQU 31*2 * OBJECT PROPERTY DEFAULT TABLE LENGTH
|
|
OLEN EQU 9 * OBJECT LENGTH
|
|
|
|
LOC EQU 4 * PARENT
|
|
NEXT EQU 5 * NEXT SIBLING
|
|
FIRST EQU 6 * FIRST CHILD
|
|
PROP EQU 7 * PROPERTY TABLE POINTER
|
|
|
|
PMASK EQU $001F * PROPERTY NUMBER IS LOW 5 BITS (OF SINGLE ID BYTE)
|
|
PLBIT EQU 5 * PROPERTY LENGTH BIT (LOWEST OF 3 LENGTH BITS)
|
|
|
|
ENDIF
|
|
|
|
*--------------------------------------------------------------------------
|
|
* GENERALIZED OUTPUT-FOLDING PARAMETER BLOCK
|
|
*--------------------------------------------------------------------------
|
|
|
|
* THE QUECHR ROUTINE IS CALLED WITH A POINTER TO A STRUCTURE CONTAINING
|
|
* THE VARIABLES BELOW. THIS ARRANGEMENT ALLOWS FOR THE EXISTANCE OF MORE THAN
|
|
* ONE STRUCTURE, USEFUL IF DISPLAYED TEXT AND SCRIPTED TEXT NEED TO FOLD AT
|
|
* DIFFERENT POINTS.
|
|
|
|
* THE STRUCTURE IDENTIFIES TWO ACTION ROUTINES. THE OUTPUT FUNCTION
|
|
* DUMPS THE BUFFER WHEN IT BECOMES FULL. THE SIZE FUNCTION ALLOWS FOR THE
|
|
* HANDLING OF PROPORTIONALLY SPACED TEXT.
|
|
|
|
* THE AUTOCR/KEEPSP VARIABLES ARE CURRENTLY IGNORED, BUT MIGHT BE USEFUL
|
|
* FOR IMPLEMENTING RECALCULATION OF THE FOLD POINTS FOR A PARAGRAPH OF TEXT,
|
|
* AS WHEN A WINDOW CHANGES SIZE.
|
|
|
|
* DATA STRUCTURE FOR QUEUE-PARAMETERS BLOCK:
|
|
|
|
BUFPTR EQU 0 * START OF BUFFER
|
|
NXTPTR EQU 4 * CURRENT POSITION WITHIN BUFFER
|
|
ENDPTR EQU 8 * END OF BUFFER >> current not used <<
|
|
|
|
BUFSIZ EQU 12 * MAXIMUM UNITS IN BUFFER
|
|
CURSIZ EQU 14 * CURRENT UNITS IN BUFFER
|
|
|
|
SIZFUN EQU 16 * GIVEN A CHAR, RETURNS UNIT SIZE
|
|
OUTFUN EQU 20 * GIVEN PTRS (BEG AND END), DUMPS BUFFER, ADDS CR
|
|
RETFUN EQU 24 * (UNUSED -- THIS SHOULD ADD THE CR)
|
|
|
|
* FLAGS:
|
|
|
|
DUMPED EQU 28 * WAS BUFFER EMPTIED (WITHOUT CR) BEFORE FULL?
|
|
AUTOCR EQU 29 * APPEND A CR TO EACH BUFFER DUMP? *** YES
|
|
KEEPSP EQU 30 * DON'T DISCARD TRAILING SPACE? *** NO
|
|
INUSE EQU 31 * SEMAPHORE TO AVOID RE-ENTRANCE
|
|
|
|
QPLEN EQU 32 * LENGTH OF BLOCK (ALWAYS EVEN)
|
|
|
|
*--------------------------------------------------------------------------
|
|
* DATA STRUCTURE FOR YZIP WINDOWS:
|
|
*--------------------------------------------------------------------------
|
|
|
|
WYPOS EQU 0 * WINDOW POSITION
|
|
WXPOS EQU 2
|
|
WYSIZE EQU 4 * WINDOW SIZE
|
|
WXSIZE EQU 6
|
|
WYCURS EQU 8 * CURSOR POSITION
|
|
WXCURS EQU 10
|
|
WLMARG EQU 12 * MARGINS
|
|
WRMARG EQU 14
|
|
WCRINT EQU 16 * CR INTERRUPT FUNCTION, COUNTER
|
|
WCRCNT EQU 18
|
|
WHLIGHT EQU 20 * HIGHLIGHT MODE
|
|
WCOLOR EQU 22 * BACK/FORE COLORS
|
|
WFONTID EQU 24 * FONT ID, SIZE
|
|
WFONTYX EQU 26
|
|
WATTR EQU 28 * WRAP BIT, SCROLL BIT, ETC
|
|
WLCNT EQU 30 * LINES (NOT PIX) DISPLAYED SINCE LAST [MORE]
|
|
|
|
* PRIVATE VARIABLES:
|
|
WCSIZ EQU 32 * "FULLNESS" OF LAST BUFFER (CURSIZ FROM DQUE)
|
|
* END OF BLOCK:
|
|
WBLKLEN EQU 34 * TOTAL LENGTH OF BLOCK (ALWAYS EVEN)
|
|
|
|
MAXWIND EQU 8 * VALID WINDOW IDS ARE 0..7
|
|
|
|
* FLAG BITS IN WATTR:
|
|
WFWRAP EQU 1 * WRAP BIT
|
|
WFSCRL EQU 2 * SCROLL BIT
|
|
WFSCRP EQU 4 * SCRIPT BIT
|
|
WFBUFF EQU 8 * BUFFER BIT
|
|
|
|
* ---------------------------------------------------------------------------
|
|
* ZIP VARIABLES - INDEXED OFF A6
|
|
* ---------------------------------------------------------------------------
|
|
|
|
ZORKID EQU 0-2 * UNIQUE GAME AND VERSION ID
|
|
TIMEMD EQU ZORKID-2 * HOURS/MINUTES MODE FLAG
|
|
ENDLOD EQU TIMEMD-2 * END OF PRELOAD (FIRST PAGED BLOCK NUMBER)
|
|
PURBOT EQU ENDLOD-2 * END OF IMPURE (FIRST PURE BLOCK NUMBER)
|
|
|
|
VOCTAB EQU PURBOT-4 * VOCABULARY TABLE POINTER
|
|
OBJTAB EQU VOCTAB-4 * OBJECT TABLE POINTER
|
|
GLOTAB EQU OBJTAB-4 * GLOBAL TABLE POINTER
|
|
WRDTAB EQU GLOTAB-4 * FREQUENT WORD TABLE POINTER
|
|
|
|
RBRKS EQU WRDTAB-4 * POINTER TO STRING OF READ-BREAK CHARS
|
|
ESIBKS EQU RBRKS-4 * END OF SELF-INSERTING BREAK CHARS (+1)
|
|
|
|
VWLEN EQU ESIBKS-2 * NUMBER OF BYTES IN A VOCAB WORD ENTRY
|
|
VWORDS EQU VWLEN-2 * NUMBER OF VOCABULARY WORDS
|
|
VOCBEG EQU VWORDS-4 * POINTER TO FIRST VOCAB WORD
|
|
VOCEND EQU VOCBEG-4 * POINTER TO LAST VOCAB WORD
|
|
|
|
PAGTAB EQU VOCEND-4 * POINTER TO PAGE INFORMATION TABLE
|
|
PAGES EQU PAGTAB-4 * POINTER TO START OF PAGE BUFFERS
|
|
|
|
PAGTOT EQU PAGES-2 * NUMBER OF PAGE BUFFERS
|
|
MAXLOD EQU PAGTOT-2 * TOTAL BLOCKS IN GAME
|
|
MAXFLG EQU MAXLOD-2 * FLAG SET IF GAME FILE IS WHOLLY PRELOADED
|
|
|
|
TOPSP EQU MAXFLG-4 * TOP OF SYSTEM STACK
|
|
STKBOT EQU TOPSP-4 * BOTTOM OF GAME STACK
|
|
|
|
ZPC1 EQU STKBOT-2 * ZORK PC, BLOCK POINTER (RELATIVE ADDRESS)
|
|
ZPC2 EQU ZPC1-2 * ZORK PC, BYTE POINTER
|
|
NARGS EQU ZPC2-2 * (LOW BYTE) OPTIONAL ARG COUNT
|
|
ZLOCS EQU NARGS-4 * POINTER TO LOCALS (ABSOLUTE ADDRESS)
|
|
|
|
RSEED1 EQU ZLOCS-2 * RANDOM NUMBER SEED, HIGH WORD
|
|
RSEED2 EQU RSEED1-2 * LOW WORD
|
|
RCYCLE EQU RSEED2-2 * ZERO MEANS NORMAL, OTHERWISE TOP OF SEQUENCE
|
|
RCONST EQU RCYCLE-2 * CURRENT PLACE IN SEQUENCE
|
|
|
|
BUFFER EQU RCONST-4 * START OF PRELOADED GAME CODE
|
|
ARGBLK EQU BUFFER-18 * 8 ARGS MAX FOR EZIP, PLUS COUNT
|
|
DEFBLK EQU ARGBLK-10 * DEFAULT ARGUMENT BLOCK (4 ARGS + COUNT)
|
|
|
|
***
|
|
|
|
RDWSTR EQU DEFBLK-10 * ASCIZ STRING BUFFER (9 CHARS MAX FOR EZIP)
|
|
RDZSTR EQU RDWSTR-6 * ZSTR BUFFER (3 WORDS MAX FOR EZIP)
|
|
|
|
RDBOS EQU RDZSTR-4 * BEGINNING OF INPUT STRING BUFFER
|
|
RDEOS EQU RDBOS-4 * END OF INPUT STRING BUFFER (+1)
|
|
RDRET EQU RDEOS-4 * RETURN TABLE
|
|
|
|
VWSORT EQU RDRET-2 * FLAG: SET IF VOCTAB SORTED
|
|
VWBOFF EQU VWSORT-2 * INITIAL OFFSET FOR BINARY SEARCH
|
|
|
|
WRDOFF EQU VWBOFF-2 * OFFSET INTO WORD TABLE FOR CURRENT SET
|
|
|
|
* VIRTUAL I/O DEVICES
|
|
|
|
VOCONS EQU WRDOFF-2 * SET FOR SCREEN OUTPUT
|
|
VOPRNT EQU VOCONS-2 * SET FOR SCRIPTING
|
|
VOSTAT EQU VOPRNT-2 * SET FOR STATUS LINE OUTPUT
|
|
VOTABL EQU VOSTAT-2 * SET FOR TABLE OUTPUT
|
|
VOFILE EQU VOTABL-2 * SET FOR FILE OUTPUT
|
|
|
|
VIKEYB EQU VOFILE-2 * SET FOR KEYBOARD INPUT
|
|
VIFILE EQU VIKEYB-2 * SET FOR FILE INPUT
|
|
|
|
VOBUFF EQU VIFILE-2 * SET IF OUTPUT TO SCREEN IS BUFFERED
|
|
VIECHO EQU VOBUFF-2 * SET IF INPUT IS ECHOED
|
|
|
|
DQUE EQU VIECHO-4 * DISPLAY QUE PARAMETER BLOCK
|
|
SQUE EQU DQUE-4 * SCRIPT QUE PARAMETER BLOCK
|
|
|
|
TABOUT EQU SQUE-4 * POINTS TO CURRENT TABLE OUTPUT BUFFER (EZIP)
|
|
TABPTR EQU TABOUT-4 * POINTS TO NEXT TABLE POSITION
|
|
|
|
CURPAG EQU TABPTR-4 * CURRENT PAGE (WHERE ZPC IS) POINTER
|
|
CURBLK EQU CURPAG-2 * CURRENT BLOCK, USUALLY SAME AS ZPC1
|
|
CURTAB EQU CURBLK-4 * CURRENT PAGE TABLE POINTER
|
|
|
|
RTIME EQU CURTAB-4 * REFERENCE TIME, NOW USES 2 WORDS
|
|
LPAGE EQU RTIME-2 * LAST REFERENCED PAGE NUMBER
|
|
LPLOC EQU LPAGE-4 * AND ITS CORE LOCATION
|
|
LPTAB EQU LPLOC-4 * AND ITS TABLE POINTER
|
|
|
|
TWAIT EQU LPTAB-2 * DELAY, IN 1/10'S SEC, BETWEEN TIMEOUTS
|
|
TFUNC EQU TWAIT-2 * FUNCTION TO CALL UPON TIMEOUT
|
|
TCLOCK EQU TFUNC-4 * REF TIME (60THS) OF LAST CHANGE IN TCOUNT
|
|
TCOUNT EQU TCLOCK-2 * DELAY REMAINING (10THS)
|
|
|
|
SFUNC EQU TCOUNT-2 * FUNCTION TO CALL UPON SOUND-END
|
|
SCOUNT EQU SFUNC-2 * #OPS TO WAIT BEFORE NEXT SOUND-END CHECK
|
|
|
|
QFOFF EQU SCOUNT-4 * OFFSET OF FUNCTION AREA (QUADS, LONG)
|
|
QSOFF EQU QFOFF-4 * OFFSET OF STRING AREA (QUADS, LONG)
|
|
|
|
* WIND1 * [DEAD]
|
|
* ROW0 * WINDOW 0 (SAVED) CURSOR POSITION
|
|
* COL0
|
|
* ROW1 * WINDOW 1 (SAVED) CURSOR POSITION
|
|
* COL1
|
|
* LINES * [MOVED INTO EACH WBLOCK]
|
|
|
|
CURWIND EQU QSOFF-2 * CURRENT WINDOW
|
|
CURWP EQU CURWIND-4 * PTR TO CURWIND RECORD BLOCK
|
|
WBLOCKP EQU CURWP-(MAXWIND*4) * PTRS TO ALL BLOCKS
|
|
MSWIND EQU WBLOCKP-2 * CURRENT MOUSE WINDOW
|
|
|
|
INLAST EQU MSWIND-2 * INPUT SETS IT, OUTPUT CLEARS IT, QUIT CHECKS
|
|
CHRTOT EQU INLAST-2 * TOTAL CHARS INPUT SO FAR DURING OPREAD
|
|
|
|
GAMFIL EQU CHRTOT-2 * REF NUMBER OF OPENED GAME FILE
|
|
SAVFIL EQU GAMFIL-2 * REF NUMBER OF OPENED SAVE FILE
|
|
|
|
MSAVEB EQU SAVFIL-4 * PTR TO A RAM BUFFER FOR ISAVE/IRESTORE
|
|
MSAVEF EQU MSAVEB-2 * FLAG, SET FOR ISAVE/IRESTORE
|
|
|
|
***
|
|
|
|
FONT EQU MSAVEF-2 * NONZERO WHEN USING SPECIAL (MONOSPACED) FONT
|
|
MACBUF EQU FONT-4 * NEW VALUE FOR ENDBUF WHEN FONTSIZE CHANGES
|
|
|
|
APPARM EQU MACBUF-4 * HANDLE TO APPLICATION PARAMETERS
|
|
SHOWVE EQU APPARM-4 * POINTER TO "VERSION" STRING, ZERO IF NONE
|
|
|
|
***
|
|
|
|
DBZPC1 EQU SHOWVE-2 * BREAK WHEN ZPC REACHES THIS ADDRESS
|
|
DBZPC2 EQU DBZPC1-2
|
|
DBINST EQU DBZPC2-2 * BREAK WHEN NEXT INSTRUCTION HAS THIS VALUE
|
|
|
|
DBITOT EQU DBINST-4 * TOTAL INSTRUCTIONS EXECUTED
|
|
DBIBRK EQU DBITOT-4 * BREAK AFTER THIS MANY INSTRUCTIONS
|
|
|
|
DBQUE EQU DBIBRK-DBQLEN * CIRCULAR QUEUE FOR INST HISTORY
|
|
DBQPTR EQU DBQUE-4 * PTR, NEXT OPEN SLOT IN QUEUE
|
|
DBQEND EQU DBQPTR-4 * PTR, END OF QUEUE
|
|
|
|
***
|
|
|
|
ZVLEN EQU 0-DBQEND * TOTAL LENGTH OF ZIP'S VARIABLES FRAME
|
|
|
|
|
|
EJECT ; PAGE
|
|
* ---------------------------------------------------------------------------
|
|
* INITIALIZATIONS
|
|
* ---------------------------------------------------------------------------
|
|
|
|
* LOW-CORE GAME VARIABLES
|
|
|
|
PVERS1 EQU 0 * ZVERSION VERSION BYTE
|
|
PVERS2 EQU 1 * ZVERSION MODE BYTE
|
|
PZRKID EQU 2 * ZORK ID
|
|
PENDLD EQU 4 * ENDLOD (BYTE OFFSET)
|
|
PSTART EQU 6 * START
|
|
PVOCTB EQU 8 * VOCTAB
|
|
POBJTB EQU 10 * OBJTAB
|
|
PGLOTB EQU 12 * GLOTAB
|
|
PPURBT EQU 14 * PURBOT
|
|
PFLAGS EQU 16 * USER FLAGS WORD
|
|
PSERNM EQU 18 * SERIAL NUMBER (6 BYTES)
|
|
PWRDTB EQU 24 * WRDTAB
|
|
PLENTH EQU 26 * LENGTH (EZIP QUADS, ZIP WORDS)
|
|
PCHKSM EQU 28 * CHECKSUM (ALL BYTES STARTING WITH BYTE 64)
|
|
PINTWD EQU 30 * INTERPRETER ID/VERSION
|
|
PSCRWD EQU 32 * SCREEN SIZE, ROWS/COLUMNS
|
|
|
|
* FOR XZIP:
|
|
|
|
PHWRD EQU 2*17 * * WIDTH OF DISPLAY, IN PIXEL UNITS
|
|
PVWRD EQU 2*18 * * HEIGHT OF DISPLAY, IN PIXEL UNITS
|
|
PFWRD EQU 2*19 * * FONT HEIGHT, WIDTH
|
|
* PLMRG EQU 2*20 * DEAD * LEFT MARGIN, IN PIXEL UNITS
|
|
* PRMRG EQU 2*21 * DEAD * RIGHT MARGIN, IN PIXEL UNITS
|
|
PCLRWRD EQU 2*22 * COLOR, BACKGROUND/FOREGROUND
|
|
PTCHARS EQU 2*23 * BYTE PTR, TABLE OF TERMINATING CHARACTERS
|
|
* PCRCNT EQU 2*24 * DEAD * CR COUNTER
|
|
* PCRFUNC EQU 2*25 * DEAD * CR FUNCTION
|
|
PCHRSET EQU 2*26 * BYTE PTR, CHAR SET TABLE
|
|
PLCTBL EQU 2*27 * BYTE PTR, LOW-CORE VARS EXTENSION TABLE
|
|
|
|
* FOR YZIP (REPLACEMENTS FOR ABOVE):
|
|
|
|
PFOFF EQU 2*20 * OFFSET OF FUNCTION AREA (x8)
|
|
PSOFF EQU 2*21 * OFFSET OF STRING AREA (x8)
|
|
|
|
PTWID EQU 2*24 * TABLE WIDTH IN PIXELS (FROM DIROUT)
|
|
* EQU 2*25
|
|
|
|
* LOW CORE EXTENSION TABLE VARIABLES
|
|
* (WORD OFFSETS -- ACCESS THROUGH 'LOWCORE' ROUTINE)
|
|
|
|
PLCLEN EQU 0 * TABLE LENGTH, IN WORDS
|
|
PMLOCX EQU 1 * MOUSE LOCATION WHEN LAST CLICKED
|
|
PMLOCY EQU 2
|
|
|
|
* "PFLAGS" BIT DEFINITIONS
|
|
|
|
* NOTE: IN GENERAL, CAPABILITY BITS ARE INITIALLY SET BY THE GAME TO
|
|
* REQUEST A GIVEN FEATURE, AND SHOULD BE CLEARED BY THE INTERPRETER
|
|
* IF THE FEATURE IS UNAVAILABLE.
|
|
|
|
FSCRI EQU 0 * SCRIPTING ON [SET BY INTERPRETER ONLY]
|
|
FFIXE EQU 1 * FIXED-WIDTH FONT NEEDED
|
|
FSTAT EQU 2 * REQUEST FOR STATUS LINE REFRESH
|
|
FDISP EQU 3 * GAME USES DISPLAY OPS
|
|
FUNDO EQU 4 * GAME USES UNDO
|
|
FMOUS EQU 5 * GAME USES MOUSE
|
|
FCOLO EQU 6 * GAME USES (8) COLORS [FOR AMIGA, MAINLY]
|
|
* * (SEE ALSO THE COLOR BIT IN PVERS2)
|
|
FSOUN EQU 7 * GAME CONTAINS SOUNDS
|
|
FMENU EQU 8 * GAME UNDERSTANDS MENU/ITEM EVENT CODES
|
|
* 9-15 * RESERVED
|
|
|
|
* HLIGHT ARGUMENT: BIT DEFS
|
|
|
|
HLPLAIN EQU 0 * no highlight
|
|
HLINV EQU 1 * reverse video
|
|
HLBOLD EQU 2 * bold
|
|
HLUNDER EQU 4 * underlining
|
|
HLMONO EQU 8 * [use monospace font]
|
|
|
|
* MICRO'S ID CODE, INTERPRETER VERSION LETTER (SEE ALSO OPVERI)
|
|
|
|
DATA
|
|
INTWRD DC.B 3 * MACHINE ID FOR MACINTOSH
|
|
DC.B 3 * THIS YZIP INTERPRETER VERSION [WAS A-Z; NOW 1-255]
|
|
SUBVER DC.W 0 * INTERPRETER SUB-VERSION, ZERO TO DISABLE
|
|
CODE
|
|
|
|
* INITIAL SET OF READ BREAK CHARS -- SPACE, TAB, CR, <.>, <,>, <?>
|
|
|
|
DATA
|
|
IRBRKS DC.B $20,$09,$0D,$2E,$2C,$3F,0 * ASCIZ
|
|
CODE
|
|
|
|
ZMVERS EQU 6 * 'YZIP' Z-MACHINE VERSION NUMBER
|
|
STKLEN EQU 512*2 * LENGTH OF GAME STACK (MULTIPLE OF 512)
|
|
PAGMIN EQU 2 * MINIMUM # PAGES [NEEDED BY $VERIFY]
|
|
|
|
* ----------------------
|
|
* ZSTART
|
|
* ----------------------
|
|
|
|
ZSTART LINK A6,#-ZVLEN * CREATE A FRAME FOR ZIP VARIABLES
|
|
MOVE.L A6,A0 * TOP OF FRAME
|
|
|
|
MOVE.W #ZVLEN/2,D0
|
|
STRX1 CLR.W -(A0) * ALL INITIAL VALUES ARE ZERO
|
|
SUBQ.W #1,D0
|
|
BNE STRX1
|
|
|
|
MOVE.L SP,TOPSP(A6) * SAVE THE SP FOR RESTARTS
|
|
LEA ZVARS,A0
|
|
MOVE.L A6,(A0) * COPY A6 FOR EXTERNAL CALLS INTO ZIP ROUTINES
|
|
|
|
*** careful about error msgs before screen & buffers are initialized ...
|
|
|
|
MOVE.W #1,VOCONS(A6) * OUTPUT ERRORS TO SCREEN FOR NOW (NO BUFFER)
|
|
MOVE.W #1,VIECHO(A6) * INPUT IS NORMALLY ECHOED
|
|
|
|
*** MOVE.W #1,WIND1(A6) * AVOID PUTCHR/TSTSCR (CZIP ONLY) BUG DURING INIT
|
|
BSR SYSIN1 * OPEN GAME FILE, WINDOW, ETC
|
|
|
|
* SET UP ZIP DEBUGGER (IF REQUESTED)
|
|
|
|
IF DEBUG THEN
|
|
BSR INITDB * INIT SOME DEBUGGING VARS
|
|
LEA MSGDBG,A0
|
|
BSR OUTMSG * INFORM/REMIND USER
|
|
DATA
|
|
MSGDBG DC.B 'ZIP Debugger installed',0
|
|
CODE
|
|
ENDIF
|
|
|
|
*** READ GAME BLOCK 0 INTO A TEMP STACK BUFFER ...
|
|
|
|
SUBA.W #512,SP * CREATE THE BUFFER
|
|
MOVE.L SP,A4 * SAVE POINTER HERE FOR NOW
|
|
|
|
MOVE.L A4,A0
|
|
CLR.W D0 * BLOCK 0
|
|
BSR GETBLK * GET IT
|
|
|
|
*** CHECK FOR ID CODE ...
|
|
|
|
CMPI.B #ZMVERS,(A4) * PROPER Z-MACHINE VERSION?
|
|
BEQ.S STRX3 * YES
|
|
|
|
STRX2 CLR.W D0 * SOMETHING WRONG, DIE
|
|
LEA MSGZMV,A0
|
|
BRA FATAL * 'Wrong Z-machine'
|
|
DATA
|
|
MSGZMV DC.B 'Wrong Z-machine version',0
|
|
CODE
|
|
|
|
STRX3 MOVE.W PZRKID(A4),ZORKID(A6) * UNIQUE GAME ID, CHECKED BY "RESTORE"
|
|
|
|
MOVEQ #0,D0
|
|
MOVE.W PPURBT(A4),D0 * GET PURBOT BYTE POINTER
|
|
BSR BYTBLK * ROUND UP TO NEXT BLOCK BOUNDARY
|
|
MOVE.W D0,PURBOT(A6) * >> here for undo, below <<
|
|
|
|
* Allocate an "undo" buffer, if requested. This allocation now comes
|
|
* BEFORE the preload/paging allocations. It /ought/ to be skipped if
|
|
* it would leave either () not enough for preload, or () a critically low
|
|
* (defined in some heuristic way) amount for paging.
|
|
|
|
MOVEQ #0,D1 * ASSUME NO UNDO
|
|
MOVE.W PFLAGS(A4),D2
|
|
BTST #FUNDO,D2 * DOES THIS GAME USE UNDO?
|
|
BEQ.S STRX3B * NO
|
|
|
|
MOVE.W PURBOT(A6),D0 * BLOCKS
|
|
ADDQ.L #STKLEN/512,D0
|
|
BSR BLKBYT * TOTAL BYTES NEEDED FOR AN UNDO-SAVE
|
|
BSR GETM * GET IT, WITHOUT ERROR TRAPPING
|
|
BEQ.S STRX3B * ZERO: NOT ENOUGH MEM, FAILED
|
|
|
|
CLR.W (A0) * OK, MARK THE BUFFER AS EMPTY
|
|
MOVE.L A0,MSAVEB(A6) * AND STORE PTR
|
|
MOVEQ #1,D1 * SUCCESS
|
|
|
|
STRX3B MOVEQ #0,D0 * ASSUME NO MENU CAPABILITY
|
|
BTST #FMENU,D2 * DOES THIS GAME ACCEPT MENU/ITEM CODES?
|
|
BEQ.S STRX3C
|
|
MOVEQ #1,D0 * YES
|
|
|
|
STRX3C BSR SETMENU * SET MENU & UNDO FLAGS FOR PASCAL
|
|
|
|
* ALLOC/INIT SOME WINDOW RECORDS (YZIP)
|
|
|
|
MOVEQ #MAXWIND,D1 * TOTAL RECORDS TO CREATE
|
|
MOVEQ #WBLKLEN,D0 * SPACE FOR ONE BLOCK
|
|
MULU D1,D0
|
|
* ALLOC A BIG BLOCK [CLEARING IT FOR THE SAKE OF WATTR/SCRIPT BIT]
|
|
BSR GETMEMC
|
|
|
|
LEA WBLOCKP(A6),A1
|
|
INIWX1 MOVE.L A0,(A1)+ * STORE ALL THE POINTERS
|
|
ADDA.W #WBLKLEN,A0
|
|
SUBQ.W #1,D1
|
|
BGT.S INIWX1
|
|
|
|
BSR INITWB * THEN, INIT EACH RECORDS
|
|
|
|
*** CHECK MEMORY, SET ENDLOD & PAGTOT, DO PRELOAD
|
|
|
|
STRX4 BSR MEMAVAIL * DETERMINE HOW MUCH FREE MEMORY EXISTS
|
|
MOVE.L D0,D7 * REMEMBER THE AMOUNT
|
|
|
|
MOVEQ #0,D0
|
|
MOVE.W PLENTH(A4),D0 * LENGTH OF GAME FILE (WORDS/QUADS/OCTS)
|
|
ADD.L D0,D0
|
|
IF EZIP THEN
|
|
ADD.L D0,D0
|
|
|
|
MOVE.W PFOFF(A4),D1 * IS THIS IS A MOBY GAME?
|
|
ADD.W PSOFF(A4),D1
|
|
BEQ.S STRX4A * IF BOTH ZERO, NO
|
|
ADD.L D0,D0 * YES, LENGTH WAS AN OCT-WORD
|
|
STRX4A
|
|
ENDIF
|
|
|
|
IF DEBUG THEN
|
|
MOVE.L D0,D1
|
|
BSR BYTBLK * TOTAL BLOCKS IN GAME FILE
|
|
MOVE.W D0,MAXLOD(A6) * SAVE FOR DEBUGGING
|
|
MOVE.L D1,D0
|
|
ENDIF
|
|
|
|
CMP.L D7,D0 * ENOUGH ROOM TO PRELOAD ENTIRE GAME?
|
|
BLT.S LOAD1 * YES
|
|
|
|
MOVEQ #0,D0
|
|
MOVE.W PENDLD(A4),D0 * LENGTH OF PRELOAD SEGMENT (BYTES)
|
|
CMP.L D7,D0 * ENOUGH ROOM FOR IT?
|
|
BLT.S LOAD2 * YES
|
|
|
|
BRA MEMERROR * NO, FAIL
|
|
|
|
* WE HAVE MEGA-MEMORY, PRELOAD EVERYTHING ...
|
|
|
|
LOAD1 BSR BYTBLK * LENGTH OF GAME FILE (IN BLOCKS)
|
|
MOVE.W D0,ENDLOD(A6) * MAXIMIZE THE PRELOAD
|
|
|
|
MOVE.W #PAGMIN,PAGTOT(A6) * MINIMIZE THE PAGING SPACE (FOR $VER)
|
|
MOVE.W #1,MAXFLG(A6) * SET FLAG
|
|
BRA.S LOAD3
|
|
|
|
* WE HAVE LIMITED MEMORY, PRELOAD ONLY WHAT'S NEEDED
|
|
|
|
LOAD2 SUB.L D0,D7 * FIRST DETERMINE MEMORY LEFT AFTER PRELOAD
|
|
BSR BYTBLK
|
|
MOVE.W D0,ENDLOD(A6) * LENGTH OF PRELOAD (IN BLOCKS)
|
|
|
|
DIVU #512+8,D7 * PAGES AVAIL (ALLOW 8 BYTES PER TABLE ENTRY)
|
|
CMPI.W #2,D7
|
|
BGE.S LOADX1
|
|
MOVEQ #2,D7 * MUST HAVE AT LEAST TWO (FOR $VERIFY)
|
|
LOADX1 MOVE.W D7,PAGTOT(A6) * MAXIMIZE THE PAGING SPACE
|
|
|
|
LOAD3 MOVE.W ENDLOD(A6),D0 * SPACE NEEDED FOR PRELOAD, IN BLOCKS
|
|
BSR BLKBYT * CONVERT TO BYTES
|
|
BSR GETMEM * GET IT
|
|
|
|
MOVE.L A0,BUFFER(A6) * SAVE POINTER
|
|
MOVE.L A0,A4 * ALSO HERE FOR REMAINING INIT
|
|
|
|
MOVE.W ENDLOD(A6),D1 * NUMBER OF BLOCKS TO PRELOAD
|
|
CLR.W D0 * STARTING WITH BLOCK 0
|
|
BSR GTBLKS * READ THEM IN
|
|
|
|
*** CLR.W WIND1(A6) * RESTORE NORMAL VALUE (AFTER PREV KLUGE)
|
|
|
|
* ------------------------------------------------------------------------
|
|
|
|
*** INITIALIZE MAJOR TABLE POINTERS
|
|
|
|
STRX6 MOVEQ #0,D0
|
|
MOVE.W PVOCTB(A4),D0 * RELATIVE VOCAB TABLE POINTER
|
|
ADD.L A4,D0 * ABSOLUTIZE IT
|
|
MOVE.L D0,VOCTAB(A6) * AND SAVE IT
|
|
|
|
MOVEQ #0,D0
|
|
MOVE.W POBJTB(A4),D0 * RELATIVE OBJECT TABLE POINTER
|
|
ADD.L A4,D0
|
|
MOVE.L D0,OBJTAB(A6)
|
|
BSR EZERR * CHECK OBJTAB ALIGNMENT
|
|
|
|
MOVEQ #0,D0
|
|
MOVE.W PGLOTB(A4),D0 * RELATIVE GLOBAL TABLE POINTER
|
|
ADD.L A4,D0
|
|
MOVE.L D0,GLOTAB(A6)
|
|
|
|
MOVEQ #0,D0
|
|
MOVE.W PWRDTB(A4),D0 * RELATIVE WORD TABLE POINTER
|
|
ADD.L A4,D0
|
|
MOVE.L D0,WRDTAB(A6)
|
|
|
|
* AND SEGMENT OFFSETS
|
|
|
|
MOVEQ #0,D0
|
|
MOVE.W PFOFF(A4),D0 * OFFSET OF FUNCTION AREA ("OCTS")
|
|
ADD.L D0,D0 * STORE AS QUADS (LONG)
|
|
MOVE.L D0,QFOFF(A6)
|
|
|
|
MOVEQ #0,D0
|
|
MOVE.W PSOFF(A4),D0 * OFFSET OF STRING AREA ("OCTS")
|
|
ADD.L D0,D0 * STORE AS QUADS (LONG)
|
|
MOVE.L D0,QSOFF(A6)
|
|
|
|
*** ALLOCATE MEMORY FOR Z STACK
|
|
|
|
MOVE.L #STKLEN,D0
|
|
BSR GETMEM
|
|
MOVE.L A0,STKBOT(A6) * THIS WILL BE BOTTOM OF GAME STACK
|
|
|
|
*** INITIALIZE LINE BUFFER, SCRIPT BUFFER
|
|
|
|
MAXLEN EQU 160 * MAX LENGTH OF LINE BUFFER (BYTES)
|
|
SCRLEN EQU 65 ** 80 * LENGTH OF SCRIPT BUFFER (BYTES)
|
|
|
|
BSR MAXSCRN * FULL SCREEN WIDTH (UNITS)
|
|
MOVE.W D1,D2
|
|
MOVE.W #MAXLEN,D1 * (BYTES)
|
|
LEA LINOUT,A1 * SCREEN DISPLAY FUNCTION
|
|
LEA DCHSIZ,A2
|
|
BSR INITQP * SET UP DISPLAY QUEUE STUFF
|
|
MOVE.L A0,DQUE(A6) * SAVE BLOCK POINTER
|
|
|
|
MOVE.W #SCRLEN,D1 * SCRIPTING WIDTH, NEVER CHANGES
|
|
MOVE.W D1,D2
|
|
LEA SCROUT,A1 * SCRIPTING DISPLAY FUNCTION
|
|
LEA SCHSIZ,A2
|
|
BSR INITQP * SET UP SCRIPT QUEUE STUFF
|
|
MOVE.L A0,SQUE(A6) * SAVE THIS POINTER TOO
|
|
|
|
* AND SET UP MACBUF ...
|
|
|
|
* ALLOCATE AND SET UP BREAK-CHAR TABLE
|
|
|
|
MOVE.L #64,D0 * MAX BREAK CHARS
|
|
BSR GETMEM * ALLOCATE BUFFER FOR BREAK-CHAR TABLE
|
|
MOVE.L A0,RBRKS(A6)
|
|
|
|
MOVE.L VOCTAB(A6),A1 * (DEFAULT) VOCAB TABLE
|
|
CLR.W D0
|
|
MOVE.B (A1)+,D0 * FIRST BYTE OF VOCTAB IS # OF SI BREAK CHARS
|
|
BRA.S STRX11 * (ZERO CHECK)
|
|
|
|
STRX10 MOVE.B (A1)+,(A0)+ * TRANSFER SI BREAKS FIRST
|
|
STRX11 DBF D0,STRX10
|
|
MOVE.L A0,ESIBKS(A6) * REMEMBER END OF SI BREAKS
|
|
|
|
LEA IRBRKS,A2 * THESE ARE THE "NORMAL" BREAK CHARS
|
|
STRX12 MOVE.B (A2)+,(A0)+ * TRANSFER THEM TOO
|
|
BNE STRX12 * ASCIZ
|
|
|
|
*** ALLOCATE MEMORY FOR PAGE TABLE & BUFFERS
|
|
|
|
MOVE.W PAGTOT(A6),D0 * PREVIOUSLY CALCULATED NUMBER OF PAGE BUFFERS
|
|
MULU #8,D0 * 8-BYTE TABLE ENTRY FOR EACH PAGE
|
|
ADDQ.L #2,D0 * ALLOW FOR THE END MARK
|
|
BSR GETMEM
|
|
MOVE.L A0,PAGTAB(A6) * THIS WILL BE START OF PAGE TABLE
|
|
|
|
MOVE.W PAGTOT(A6),D0 * PREVIOUSLY CALCULATED NUMBER OF PAGE BUFFERS
|
|
MULU #512,D0 * 512 BYTES EACH
|
|
BSR GETMEM
|
|
MOVE.L A0,PAGES(A6) * PAGES THEMSELVES WILL START HERE
|
|
|
|
*** INITIALIZE THE PAGE TABLE
|
|
|
|
MOVE.W PAGTOT(A6),D0 * PREVIOUSLY CALCULATED NUMBER OF PAGE BUFFERS
|
|
MOVE.L PAGTAB(A6),A0
|
|
|
|
STRX16 MOVE.W #-2,(A0)+ * BLOCK (NO BLOCK "$FFFE")
|
|
CLR.L (A0)+ * REF TIME IS ZERO
|
|
CLR.W (A0)+ * THIS SLOT UNUSED (BUT 8 BYTES SPEEDS CALCS)
|
|
SUBQ.W #1,D0
|
|
BNE STRX16
|
|
MOVE.W #-1,(A0) * MARK THE END OF THE TABLE (NO BLOCK "$FFFF")
|
|
|
|
MOVE.W #-1,CURBLK(A6) * MUST INIT THESE PAGING VARS TOO!
|
|
MOVE.W #-1,LPAGE(A6)
|
|
|
|
* CHECK FOR CUSTOM CHARSET TABLE (NOW THAT PAGING IS SET UP!)
|
|
|
|
MOVE.W PCHRSET(A4),D0 * CUSTOM TABLE PTR
|
|
BEQ.S STRX18 * IF NONE, USE INTERPRETER DEFAULTS
|
|
BSR BSPLTB * SPLIT THE BYTE POINTER
|
|
|
|
LEA ZCHRS,A2 * DEFAULT TBL (IN INTERPRETER DATA SPACE)
|
|
MOVEQ #(26*3)-1,D3 * TABLE LENGTH (IMPLICIT)
|
|
STRX17 BSR GETBYT * UPDATE D0/D1, RESULT IN D2
|
|
MOVE.B D2,(A2)+ * COPY ONE ITEM
|
|
DBF D3,STRX17
|
|
|
|
* INITIALIZE THE RANDOM NUMBER SEEDS
|
|
|
|
STRX18 BSR GTSEED
|
|
MOVE.W D0,RSEED1(A6)
|
|
SWAP D0
|
|
MOVE.W D0,RSEED2(A6) * PUT HIGH WORD HERE, "RELATIVELY CONSTANT"
|
|
|
|
MOVE.W #1,VOBUFF(A6) * BEGIN BUFFERING OUTPUT
|
|
BSR ENDTITLE * PAUSE FOR TITLE SCREEN, IF SHOWING
|
|
BRA.S START1
|
|
|
|
* ----------------------
|
|
* RESTRT
|
|
* ----------------------
|
|
|
|
* RESTART EXECUTION HERE
|
|
|
|
RESTRT MOVE.L BUFFER(A6),A0
|
|
MOVE.W PFLAGS(A0),-(SP) * PRESERVE THE USER FLAGS (SCRIPT ETC)
|
|
|
|
CLR.W D0 * REREAD ALL OF THE IMPURE STUFF
|
|
MOVE.W PURBOT(A6),D1
|
|
BSR GTBLKS
|
|
|
|
MOVE.L BUFFER(A6),A0
|
|
MOVE.W (SP)+,PFLAGS(A0) * RESTORE FLAGS
|
|
|
|
BSR INITWB * RE-INIT WINDOW RECORDS
|
|
|
|
START1 MOVE.L TOPSP(A6),SP * RESET SYSTEM STACK POINTER
|
|
|
|
MOVE.L DQUE(A6),A0
|
|
MOVE.L BUFPTR(A0),NXTPTR(A0) * INITIALIZE OUTPUT BUFFER POINTER
|
|
|
|
MOVE.L STKBOT(A6),A4
|
|
ADDA.W #STKLEN,A4 * INITIALIZE GAME STACK POINTER
|
|
MOVE.L A4,ZLOCS(A6) * INITIALIZE POINTER TO LOCALS/FRAME
|
|
MOVE.L BUFFER(A6),A2
|
|
|
|
ORI.B #2,PVERS2(A2) * DISPLAY OP IS AVAILABLE
|
|
ORI.B #32+16+8+4,PVERS2(A2) * SOUND, MONOSPACE, ITALIC, BOLD
|
|
|
|
BSR INITDISP * GET/STORE TTY-SPECIFIC LOWCORE VARS
|
|
|
|
MOVE.W INTWRD,PINTWD(A2) * SET INTERPRETER ID/VERSION WORD
|
|
CLR.W RCYCLE(A6) * ALWAYS RESTART WITH NORMAL RANDOMNESS
|
|
MOVE.W #1,MSWIND(A6) * YZIP: INITIALLY CONSTRAIN MOUSE TO W1
|
|
|
|
MOVEQ #0,D0
|
|
MOVE.W PSTART(A2),D0 * BYTE/QUAD PTR TO STARTING LOCATION
|
|
MOVE.L QFOFF(A6),D1 * QUAD FUNC OFF -- IS THIS IS A MOBY GAME?
|
|
|
|
*** "NOW ALWAYS A FUNC PTR, EVEN IF QFOFF = 0"
|
|
* BNE.S STA1X1 * YES
|
|
* BSR BSPLTB * SPLIT INTO BLOCK AND BYTE
|
|
* BRA.S STA1X2
|
|
|
|
STA1X1 BSR BSPLTQ2 * SPLIT INTO BLOCK AND BYTE
|
|
ADDQ.W #1,D1 * AND SKIP OVER #LOCS BYTE
|
|
|
|
STA1X2 MOVE.W D0,ZPC1(A6) * INITIALIZE THE ZPC
|
|
MOVE.W D1,ZPC2(A6)
|
|
BSR NEWZPC * GET THE PAGE TO EXECUTE
|
|
|
|
* SYSIN2 SHOULD BE THE /LAST/ CALL BEFORE NXTINS, BECAUSE OF STACK HACKING
|
|
* (FOR KLUDGY TIMEOUTS) IN OPREST.
|
|
|
|
BSR SYSIN2 * MAC -- BUT LOAD A SAVED GAME IF REQUESTED
|
|
BRA NXTINS * TALLY HO
|
|
|
|
* ----------------------
|
|
* INITWB
|
|
* ----------------------
|
|
|
|
* INITIALIZE (OR RE-INITIALIZE) ALL WINDOW RECORDS (ALREADY ALLOC'ED)
|
|
|
|
INITWB MOVEM.L D1-D2/A1-A2,-(SP)
|
|
LEA WBLOCKP(A6),A2
|
|
MOVEQ #MAXWIND,D2 * TOTAL RECORDS TO INIT
|
|
|
|
INWBX2 MOVE.L (A2)+,A0 * NEXT REC
|
|
BSR IWBONE
|
|
SUBQ.W #1,D2
|
|
BGT.S INWBX2
|
|
|
|
* THEN DO SOME SPECIAL INITS FOR THE FIRST TWO WINDOWS
|
|
|
|
BSR MAXSCRN * GET D0.W = ROWS, D1.W = COLS
|
|
LEA WBLOCKP(A6),A2
|
|
MOVE.L (A2)+,A0 * GET POINTER TO WINDOW 0 RECORD
|
|
|
|
MOVE.W D0,WYSIZE(A0) * W0 GETS SEVERAL SPECIAL INIT VALS
|
|
MOVE.W D1,WXSIZE(A0)
|
|
ORI.W #WFWRAP+WFSCRL+WFSCRP,WATTR(A0)
|
|
|
|
MOVE.L A0,CURWP(A6) * THIS IS INITIAL RECORD POINTER
|
|
CLR.W CURWIND(A6) * AND INITIAL WINDOW
|
|
|
|
MOVE.L (A2)+,A0 * GET POINTER TO WINDOW 1 RECORD
|
|
MOVE.W D1,WXSIZE(A0) * W1 GETS ONE SPECIAL INIT VAL
|
|
|
|
MOVEM.L (SP)+,D1-D2/A1-A2
|
|
RTS
|
|
|
|
* ----------------------
|
|
* IWBONE
|
|
* ----------------------
|
|
|
|
* INIT ONE RECORD, A0 -> BLOCK, USES A1/D1
|
|
|
|
IWBONE MOVE.L A0,A1 * SAVE HERE
|
|
MOVE.W WATTR(A1),-(SP) * PRESERVE THE SCRIPTING FLAG, ETC
|
|
|
|
MOVEQ #WBLKLEN,D0
|
|
IWB1X1 CLR.B (A0)+ * ZERO THE BLOCK
|
|
SUBQ.W #1,D0
|
|
BNE.S IWB1X1
|
|
MOVE.W (SP)+,WATTR(A1) * [CLEARED AT INITIAL ALLOC ONLY]
|
|
|
|
* INIT ALL NON-ZERO SLOTS
|
|
|
|
MOVEQ #1,D0
|
|
MOVE.W D0,WYPOS(A1) * EACH WINDOW LIVES INITIALLY AT 1,1
|
|
MOVE.W D0,WXPOS(A1)
|
|
MOVE.W D0,WYCURS(A1) * CURSOR INITIALLY AT UPPER LEFT
|
|
MOVE.W D0,WXCURS(A1)
|
|
|
|
MOVE.W D0,WFONTID(A1) * INITIALLY FONT #1
|
|
BSR GETFYX * GET (DEFAULT) FONT SIZE
|
|
MOVE.W D0,WFONTYX(A1)
|
|
|
|
MOVEQ #0,D0 * GET DEFAULT COLORS
|
|
MOVEQ #0,D1
|
|
BSR MDCOLOR
|
|
MOVE.W D0,WCOLOR(A1) * (BACK/FORE)
|
|
|
|
ORI.W #WFBUFF,WATTR(A1) * BUFFERING ON
|
|
RTS
|
|
|
|
* ----------------------
|
|
* INITDISP
|
|
* ----------------------
|
|
|
|
* GET/STORE TTY-SPECIFIC LOWCORE VARS
|
|
* [MAY CHANGE BETWEEN MAC & MACII -- ALSO CALLED AFTER RESTORE]
|
|
|
|
INITDISP
|
|
MOVEM.L D1-D3/A2,-(SP)
|
|
MOVE.L BUFFER(A6),A2
|
|
|
|
BSR GETFYX
|
|
MOVE.W D0,PFWRD(A2) * FONT SIZE, HEIGHT/WIDTH (PIXELS)
|
|
*** MOVE.W D0,D2
|
|
*** ROR.W #8,D2 * SWAP BYTES (BUG IN YZIP20)
|
|
*** MOVE.W D2,PFWRD(A2)
|
|
|
|
** PFWRD/PVWRD/PHWRD DEAD IN 'YZIP', BUT KEEP FOR NOW, FOR BACKWARD COMPAT ...
|
|
|
|
MOVE.W D0,D2
|
|
MOVE.W D0,D3
|
|
LSR.W #8,D2 * UNPACK HEIGHT
|
|
ANDI.W #$FF,D3 * UNPACK WIDTH
|
|
|
|
BSR MAXSCRN * SCREEN SIZE, PIXELS
|
|
MOVE.W D0,PVWRD(A2)
|
|
MOVE.W D1,PHWRD(A2)
|
|
|
|
EXT.L D0
|
|
DIVU D2,D0
|
|
LSL.W #8,D0 * ROWS (ROUNDED DOWN) IN HIGH BYTE
|
|
EXT.L D1
|
|
DIVU D3,D1
|
|
MOVE.B D1,D0 * COLUMNS IN LOW
|
|
MOVE.W D0,PSCRWD(A2) * SCREEN SIZE, CHARS
|
|
|
|
* INIT COLOR STUFF TOO
|
|
|
|
MOVEQ #0,D0 * GET DEFAULT COLORS (OR BLACK/WHITE)
|
|
MOVEQ #0,D1
|
|
BSR MDCOLOR
|
|
MOVE.W D0,PCLRWRD(A2) * (BACK/FORE)
|
|
TST.W D1 * COLOR MACHINE?
|
|
BEQ.S IDSPX8 * NO
|
|
|
|
ORI.B #1,PVERS2(A2) * YES, COLOR IS AVAILABLE
|
|
BSET #FCOLO,PFLAGS+1(A2) * [ALSO ADJUST THIS BIT]
|
|
BRA.S IDSPX9
|
|
IDSPX8 ANDI.B #$FE,PVERS2(A2) * (FORCE BIT -> 0)
|
|
BCLR #FCOLO,PFLAGS+1(A2)
|
|
|
|
IDSPX9 MOVEM.L (SP)+,D1-D3/A2
|
|
RTS
|
|
|
|
* ----------------------
|
|
* EZERR
|
|
* ----------------------
|
|
|
|
IF EZIP THEN
|
|
* FOR EZIP/XZIP, MAKE SURE D0.L = OBJ TABLE BASE IS WORD ALIGNED
|
|
|
|
EZERR BTST #0,D0 * WORD ALIGNED?
|
|
BNE.S EZERX1 * NO, FAIL
|
|
RTS
|
|
|
|
EZERX1 CLR.W D0
|
|
LEA MSGEZR,A0
|
|
BRA FATAL * 'OBJTAB align err'
|
|
|
|
DATA
|
|
MSGEZR DC.B 'OBJTAB align err',0
|
|
CODE
|
|
|
|
ENDIF
|
|
|
|
EJECT ; PAGE
|
|
* ---------------------------------------------------------------------------
|
|
* MISC FUNCTIONS
|
|
* ---------------------------------------------------------------------------
|
|
|
|
* ------------------------------
|
|
* COPYB
|
|
* ------------------------------
|
|
|
|
* COPY BYTES
|
|
* GIVEN A0 -> SRC, D0 = LEN, A1 -> DEST
|
|
|
|
CPBX1 MOVE.B (A0)+,(A1)+ * COPY THEM
|
|
COPYB DBF D0,CPBX1 * ZERO CHECK << ENTRY POINT >>
|
|
RTS
|
|
|
|
* ------------------------------
|
|
* COPYS
|
|
* ------------------------------
|
|
|
|
* COPY A STRING, AND TACK ON A NULL BYTE
|
|
* GIVEN A0 -> SRC, A1 -> DEST, D0 = LEN, D1 = MAX LEN
|
|
|
|
COPYS CMP.W D1,D0 * LEN WITHIN MAX?
|
|
BLE.S CPSX1
|
|
MOVE.W D1,D0 * NO, TRUNCATE IT
|
|
CPSX1 BRA.S CPSX3 * ZERO CHECK
|
|
|
|
CPSX2 MOVE.B (A0)+,(A1)+
|
|
CPSX3 DBF D0,CPSX2
|
|
CLR.B (A1) * ASCIZ
|
|
RTS
|
|
|
|
* --------------------------
|
|
* COMPS
|
|
* --------------------------
|
|
|
|
* COMPARE STRINGS, PTRS IN A0 AND A1, LENGTHS IN D0.W
|
|
* RETURN FLAGS, 'EQ' IF SAME
|
|
|
|
COMPS TST.W D0
|
|
BLE.S CMPSX4 * ZERO CHECK
|
|
CMPSX2 CMP.B (A0)+,(A1)+
|
|
BNE.S CMPSX4 * MISMATCH, RETURN "DIFFERENT"
|
|
SUBQ.W #1,D0
|
|
BNE.S CMPSX2 * IF DONE, RETURN "SAME"
|
|
CMPSX4 RTS
|
|
|
|
* ----------------------
|
|
* STRLEN
|
|
* ----------------------
|
|
|
|
* FIND LENGTH OF AN NULL-TERMINATED STRING, POINTER IN A0
|
|
* RETURN POINTER IN A0, LENGTH IN D0
|
|
|
|
STRLEN MOVE.L A0,-(SP) * SAVE START
|
|
STRLX1 TST.B (A0)+ * SEARCH FOR NULL
|
|
BNE.S STRLX1
|
|
MOVE.L A0,D0 * FOUND IT
|
|
SUBQ.L #1,D0 * BACKUP TO THE NULL
|
|
MOVE.L (SP)+,A0 * RETURN ORIGINAL POINTER
|
|
SUB.L A0,D0 * RETURN LENGTH
|
|
RTS
|
|
|
|
* ------------------------------
|
|
* RELABS [RRELABS]
|
|
* ------------------------------
|
|
|
|
* CONVERT A RELATIVE (BYTE) OFFSET (D0.W) TO AN ABSOLUTE PTR (A0)
|
|
|
|
RELABS MOVE.L BUFFER(A6),A0
|
|
*** CMP.W PPURBT(A0),D0 * MAX FOR READ/WRITE
|
|
CMP.W PENDLD(A0),D0 * MAX FOR READ-ONLY (USED BY OPLEX!)
|
|
BHI.S RLBSX2 * REQUEST TOO HIGH
|
|
|
|
RLBSX1 SWAP D0
|
|
CLR.W D0 * ZERO THE HIGH WORD (NO SIGN-EXTENDING)
|
|
SWAP D0 * [14 cycles vs 16]
|
|
ADDA.L D0,A0 * ABSOLUTIZE IT
|
|
RTS
|
|
|
|
RLBSX2 LEA MSGRLB,A0
|
|
*** CLR.W D0
|
|
BRA FATAL
|
|
DATA
|
|
MSGRLB DC.B 'Out of range in RELABS',0
|
|
CODE
|
|
|
|
* ----------------------
|
|
* BLKBYT
|
|
* ----------------------
|
|
|
|
* GIVEN A ZIP BLOCK COUNT IN D0.W, RETURN A BYTE COUNT IN D0.L
|
|
|
|
BLKBYT EXT.L D0 * CLEAR HIGH WORD
|
|
SWAP D0
|
|
LSR.L #7,D0 * x512
|
|
RTS
|
|
|
|
* ----------------------
|
|
* BYTBLK
|
|
* ----------------------
|
|
|
|
* GIVEN A BYTE COUNT IN D0.L, RETURN A ZIP BLOCK COUNT IN D0.W, ROUNDING UP
|
|
|
|
BYTBLK MOVE.W D0,-(SP) * SAVE LOW WORD
|
|
LSR.L #8,D0
|
|
LSR.L #1,D0 * EXTRACT BLOCK NUMBER
|
|
|
|
ANDI.W #$01FF,(SP)+ * EXACT MULTIPLE OF 512?
|
|
BEQ.S BYTBX1 * YES
|
|
ADDQ.W #1,D0 * NO, ROUND UP TO NEXT BLOCK
|
|
BYTBX1 RTS
|
|
|
|
* ----------------------
|
|
* LOWCORE
|
|
* ----------------------
|
|
|
|
* USE THIS ROUTINE TO ACCESS LOW-CORE EXTENSION-TABLE VARS
|
|
|
|
* GIVEN D0 = VAR (WORD OFFSET)
|
|
* RETURN A0 (MAY BE ODD) -> VAR, AND FLAGS (ZERO IF INVALID VAR)
|
|
|
|
LOWCORE MOVEM.L D1,-(SP)
|
|
MOVE.W D0,D1
|
|
MOVE.L BUFFER(A6),A0
|
|
MOVEQ #0,D0 * GET EXTENSION TABLE OFFSET (MAY BE >32K, ODD)
|
|
MOVE.W PLCTBL(A0),D0 * EXISTS?
|
|
BEQ.S LWCX1 * NO, ERROR
|
|
|
|
ADDA.L D0,A0 * TABLE BASE
|
|
BSR GTAWRD * TABLE LEN (WORDS)
|
|
CMP.W D0,D1 * ENOUGH?
|
|
BGT.S LWCX1 * NO, ERROR
|
|
|
|
SUBQ.L #2,A0
|
|
ADD.W D1,D1 * BYTE OFFSET
|
|
ADDA.W D1,A0 * POINT TO DESIRED VAR
|
|
BRA.S LWCX2 * NONZERO FLAGS
|
|
|
|
LWCX1 MOVEQ #0,D0 * ZERO FLAGS
|
|
LWCX2 MOVEM.L (SP)+,D1 * DON'T DISTURB FLAGS
|
|
RTS
|
|
|
|
* ----------------------
|
|
* GTAWRD
|
|
* ----------------------
|
|
|
|
* GET CORE WORD, ABSOLUTE POINTER IN A0, RETURN THE WORD IN D0, UPDATE POINTER
|
|
|
|
GTAWRD
|
|
MOVE.B (A0)+,D0 * GET HIGH-ORDER BYTE, ADVANCE A0
|
|
ASL.W #8,D0 * POSITION IT
|
|
MOVE.B (A0)+,D0 * GET LOW-ORDER BYTE, ADVANCE A0
|
|
RTS
|
|
|
|
* ----------------------
|
|
* PTAWRD
|
|
* ----------------------
|
|
|
|
* WRITE WORD TO CORE, ABSOLUTE POINTER IN A0, VALUE IN D0, UPDATE A0
|
|
|
|
PTAWRD
|
|
MOVE.B D0,1(A0) * STORE LOW-ORDER BYTE
|
|
ASR.W #8,D0
|
|
MOVE.B D0,(A0) * STORE HIGH-ORDER BYTE
|
|
ADDQ.L #2,A0
|
|
RTS
|
|
|
|
* ---------------------------------------------------------------------------
|
|
* LOW LEVEL ZIP FUNCTIONS
|
|
* ---------------------------------------------------------------------------
|
|
|
|
* ----------------------
|
|
* GETBYT
|
|
* ----------------------
|
|
|
|
* GET A BYTE FROM GAME, BLOCK-POINTER IN D0, BYTE-POINTER IN D1, RESULT IN D2
|
|
* UPDATE D0 AND D1 TO REFLECT BYTE GOTTEN
|
|
|
|
GETBYT MOVE.W D0,-(SP)
|
|
CMP.W ENDLOD(A6),D0 * IS THIS A PRELOADED LOCATION?
|
|
BGE.S GETBX1 * NO
|
|
|
|
BSR BLKBYT * YES, RECONSTRUCT POINTER (MAY EXCEED 32K)
|
|
OR.W D1,D0
|
|
|
|
CLR.W D2 * CLEAR THE UNWANTED HIGH BYTE
|
|
MOVE.L BUFFER(A6),A0 * ABSOLUTE POINTER
|
|
MOVE.B 0(A0,D0.L),D2 * GET THE DESIRED BYTE
|
|
BRA.S GETBX2
|
|
|
|
GETBX1 BSR GETPAG * FIND THE PROPER PAGE (POINTER RETURNED IN A0)
|
|
CLR.W D2 * CLEAR THE UNWANTED HIGH BYTE
|
|
MOVE.B 0(A0,D1.W),D2 * GET THE DESIRED BYTE
|
|
|
|
GETBX2 MOVE.W (SP)+,D0
|
|
ADDQ.W #1,D1 * UPDATE BYTE-POINTER
|
|
CMPI.W #512,D1 * END OF PAGE?
|
|
BNE.S GETBX3 * NO, DONE
|
|
|
|
CLR.W D1 * YES, CLEAR BYTE-POINTER
|
|
ADDQ.W #1,D0 * AND UPDATE BLOCK-POINTER
|
|
GETBX3 RTS
|
|
|
|
* ----------------------
|
|
* GETWRD
|
|
* ----------------------
|
|
|
|
* GET A WORD FROM GAME, BLOCK-POINTER IN D0, BYTE-POINTER IN D1, RESULT IN D2
|
|
|
|
GETWRD BSR GETBYT * GET HIGH-ORDER BYTE
|
|
ASL.W #8,D2 * POSITION IT
|
|
MOVE.W D2,-(SP) * SAVE IT
|
|
|
|
BSR GETBYT * GET LOW-ORDER BYTE
|
|
OR.W (SP)+,D2 * OR IN THE OTHER BYTE
|
|
RTS
|
|
|
|
* ----------------------
|
|
* NXTBYT
|
|
* ----------------------
|
|
|
|
* GET THE NEXT BYTE, RETURN IT IN D0
|
|
|
|
NXTBYT MOVE.L CURPAG(A6),A0 * INDEX INTO CURRENT PAGE
|
|
ADDA.W ZPC2(A6),A0
|
|
CLR.W D0 * CLEAR HIGH REGISTER AND
|
|
MOVE.B (A0),D0 * GET THE NEXT BYTE
|
|
|
|
ADDQ.W #1,ZPC2(A6) * UPDATE PC
|
|
CMPI.W #512,ZPC2(A6) * END OF PAGE?
|
|
BLT.S NXTBX1 * NO
|
|
|
|
MOVE.W D0,-(SP)
|
|
BSR NEWZPC * YES, UPDATE PAGE
|
|
MOVE.W (SP)+,D0
|
|
NXTBX1 RTS * AND RETURN
|
|
|
|
* ----------------------
|
|
* NXTWRD
|
|
* ----------------------
|
|
|
|
* GET THE NEXT WORD, RETURN IT IN D0
|
|
|
|
NXTWRD BSR NXTBYT * GET HIGH-ORDER BYTE
|
|
ASL.W #8,D0 * SHIFT TO PROPER POSITION
|
|
MOVE.W D0,-(SP) * SAVE IT
|
|
|
|
BSR NXTBYT * GET LOW-ORDER BYTE
|
|
OR.W (SP)+,D0 * OR IN THE OTHER BYTE
|
|
RTS
|
|
|
|
* ----------------------
|
|
* GETARG
|
|
* ----------------------
|
|
|
|
* GET AN ARGUMENT GIVEN ITS TYPE IN D0
|
|
|
|
GETARG SUBQ.W #1,D0 * EXAMINE ARGUMENT
|
|
BLT.S NXTWRD * 0 MEANT LONG IMMEDIATE
|
|
BEQ.S NXTBYT * 1 MEANT SHORT IMMEDIATE
|
|
|
|
BSR NXTBYT * 2 MEANT VARIABLE, GET THE VAR
|
|
TST.W D0 * STACK?
|
|
BNE.S GETV1 * NO, JUST GET THE VAR'S VALUE
|
|
MOVE.W (A4)+,D0 * YES, POP THE STACK
|
|
RTS
|
|
|
|
* ----------------------
|
|
* GETVAR
|
|
* ----------------------
|
|
|
|
* GET VALUE OF A VARIABLE, VAR IN D0, VALUE RETURNED IN D0
|
|
|
|
GETVAR TST.W D0 * STACK?
|
|
BNE.S GETV1 * NO
|
|
MOVE.W (A4),D0 * YES, GET TOP-OF-STACK (DON'T POP)
|
|
RTS
|
|
|
|
GETV1 CMPI.W #16,D0 * LOCAL?
|
|
BGE.S GETVX2 * NO
|
|
MOVE.L ZLOCS(A6),A0 * YES, POINT TO PROPER STACK ELEMENT
|
|
ADD.W D0,D0
|
|
SUBA.W D0,A0 * LOCALS BUILD DOWN
|
|
MOVE.W (A0),D0 * GET IT
|
|
RTS
|
|
|
|
GETVX2 SUB.W #16,D0 * GLOBAL, ADJUST FOR LOCALS
|
|
MOVE.L GLOTAB(A6),A0 * POINT TO PROPER GLOBAL TABLE ELEMENT
|
|
ADD.W D0,D0
|
|
ADDA.W D0,A0
|
|
BRA GTAWRD * GET IT AND RETURN
|
|
|
|
* ----------------------
|
|
* PUTVAR
|
|
* ----------------------
|
|
|
|
* UPDATE VALUE OF A VARIABLE, VAR IN D0, NEW VALUE IN D1
|
|
|
|
PUTVAR TST.W D0 * STACK?
|
|
BNE.S PUTVX1 * NO
|
|
MOVE.W D1,(A4) * YES, UPDATE TOP-OF-STACK (DON'T PUSH)
|
|
RTS
|
|
|
|
PUTVX1 CMPI.W #16,D0 * LOCAL?
|
|
BGE.S PUTVX2 * NO
|
|
MOVE.L ZLOCS(A6),A0 * YES, POINT TO PROPER STACK ELEMENT
|
|
ADD.W D0,D0
|
|
SUBA.W D0,A0 * LOCALS BUILD DOWN
|
|
MOVE.W D1,(A0) * UPDATE IT
|
|
RTS
|
|
|
|
PUTVX2 SUB.W #16,D0 * GLOBAL, ADJUST FOR LOCALS
|
|
MOVE.L GLOTAB(A6),A0 * POINT TO PROPER GLOBAL TABLE ELEMENT
|
|
ADD.W D0,D0
|
|
ADDA.W D0,A0
|
|
MOVE.W D1,D0
|
|
BRA PTAWRD * UPDATE IT AND RETURN
|
|
|
|
* ----------------------
|
|
* PUTVAL, BYTVAL
|
|
* ----------------------
|
|
|
|
* RETURN VAL IN D0 TO LOCATION SPECIFIED BY NEXTBYTE
|
|
* DESTROYS D1, BUT IS USUALLY CALLED AT END OF TOP-LEVEL FUNCTION
|
|
|
|
BYTVAL ANDI.W #$00FF,D0 * ENTER HERE TO CLEAR HIGH BYTE
|
|
PUTVAL MOVE.W D0,D1 * NORMAL ENTRY
|
|
BSR NXTBYT * GET VAR TO USE
|
|
TST.W D0 * STACK?
|
|
BNE.S PUTVAR * NO, GO STORE VALUE
|
|
MOVE.W D1,-(A4) * YES, PUSH ONTO STACK
|
|
RTS
|
|
|
|
* ----------------------
|
|
* PFALSE, PTRUE
|
|
* ----------------------
|
|
|
|
* PREDICATE HANDLERS TRUE AND FALSE
|
|
* DESTROYS REGISTERS, BUT ARE ONLY CALLED FROM END OF TOP-LEVEL FUNCTIONS
|
|
|
|
PFALSE CLR.W D1 * PREDICATE WAS FALSE, CLEAR FLAG
|
|
BRA.S PTRUE1
|
|
|
|
PTRUE MOVEQ #1,D1 * PREDICATE WAS TRUE, SET FLAG
|
|
PTRUE1 BSR NXTBYT * GET FIRST (OR ONLY) PREDICATE JUMP BYTE
|
|
BCLR #7,D0 * NORMAL POLARITY PREDICATE?
|
|
BEQ.S PTRUX1 * NO, LEAVE FLAG ALONE
|
|
ADDQ.W #1,D1 * YES, INCREMENT FLAG
|
|
|
|
PTRUX1 BCLR #6,D0 * ONE-BYTE JUMP OFFSET?
|
|
BNE.S PTRUX3 * YES
|
|
|
|
ASL.W #8,D0 * NO, TWO-BYTE, POSITION HIGH-ORDER OFFSET BYTE
|
|
MOVE.W D0,D2
|
|
BSR NXTBYT * GET LOW-ORDER BYTE
|
|
OR.W D2,D0 * OR IN HIGH-ORDER BITS
|
|
BTST #13,D0 * IS NUMBER NEGATIVE (14-BIT 2'S COMP NUMBER)?
|
|
BEQ.S PTRUX3 * NO
|
|
ORI.W #$C000,D0 * YES, MAKE 16-BIT NUMBER NEGATIVE
|
|
|
|
PTRUX3 SUBQ.W #1,D1 * TEST FLAG
|
|
BEQ.S PTRUX6 * WAS 1, THAT MEANS DO NOTHING
|
|
TST.W D0 * ZERO JUMP?
|
|
BNE.S PTRUX4 * NO
|
|
BRA OPRFAL * YES, THAT MEANS DO AN RFALSE
|
|
|
|
PTRUX4 SUBQ.W #1,D0 * ONE JUMP?
|
|
BNE.S PTRUX5 * NO
|
|
BRA OPRTRU * YES, THAT MEANS DO AN RTRUE
|
|
|
|
PTRUX5 SUBQ.W #1,D0 * ADJUST OFFSET
|
|
ADD.W D0,ZPC2(A6) * ADD TO PC
|
|
BRA NEWZPC * AND UPDATE ZPC STUFF
|
|
PTRUX6 RTS
|
|
|
|
* ----------------------
|
|
* BSPLTB
|
|
* ----------------------
|
|
|
|
* SPLIT BYTE-POINTER IN D0.W (16 BIT UNSIGNED)
|
|
* INTO BLOCK NUMBER IN D0 & BYTE OFFSET IN D1
|
|
|
|
BSPLTB MOVE.W D0,D1
|
|
LSR.W #8,D0 * EXTRACT THE 7 BLOCK BITS (64K RANGE)
|
|
LSR.W #1,D0
|
|
ANDI.W #$01FF,D1 * EXTRACT THE 9 OFFSET BITS (0-511)
|
|
IF DEBUG THEN
|
|
CMP.W MAXLOD(A6),D0 * VALID BLOCK NUMBER?
|
|
BCC BLKERR * BHS * NO, FAIL
|
|
ENDIF
|
|
RTS
|
|
|
|
* ----------------------
|
|
* BSPLIT
|
|
* ----------------------
|
|
|
|
* SPLIT WORD-POINTER IN D0.W (16 BIT UNSIGNED)
|
|
* INTO BLOCK NUMBER IN D0 & BYTE OFFSET IN D1
|
|
|
|
BSPLIT MOVE.W D0,D1
|
|
LSR.W #8,D0 * EXTRACT THE 8 BLOCK BITS (128K RANGE)
|
|
ANDI.W #$00FF,D1 * EXTRACT THE 8 OFFSET BITS (0-255)
|
|
ADD.W D1,D1 * CONVERT OFFSET TO BYTES
|
|
IF DEBUG THEN
|
|
CMP.W MAXLOD(A6),D0 * VALID BLOCK NUMBER?
|
|
BCC BLKERR * BHS * NO, FAIL
|
|
ENDIF
|
|
RTS
|
|
|
|
* ----------------------
|
|
* BSPLTQ
|
|
* ----------------------
|
|
|
|
* SPLIT QUAD-POINTER IN D0.W
|
|
* INTO BLOCK NUMBER IN D0.W & BYTE OFFSET IN D1.W -- EZIP ONLY
|
|
|
|
** BSPLTQ MOVE.W D0,D1
|
|
** LSR.W #7,D0 * EXTRACT THE 9 BLOCK BITS (256K RANGE)
|
|
** ANDI.W #$007F,D1 * EXTRACT THE 7 OFFSET BITS (0-127)
|
|
** ADD.W D1,D1 * CONVERT OFFSET TO BYTES
|
|
** ADD.W D1,D1
|
|
** IF DEBUG THEN
|
|
** CMP.W MAXLOD(A6),D0 * VALID BLOCK NUMBER?
|
|
** BCC BLKERR * BHS * NO, FAIL
|
|
** ENDIF
|
|
** RTS
|
|
|
|
* ----------------------
|
|
* BSPLTQ2
|
|
* ----------------------
|
|
|
|
* COMBINE/SPLIT QUAD-POINTERS IN D0.L AND D1.L
|
|
* INTO BLOCK NUMBER IN D0.W & BYTE OFFSET IN D1.W -- EZIP ONLY
|
|
|
|
BSPLTQ2 ADD.L D1,D0
|
|
MOVE.W D0,D1
|
|
LSR.L #7,D0 * EXTRACT THE 9 BLOCK BITS (256K RANGE)
|
|
ANDI.W #$007F,D1 * EXTRACT THE 7 OFFSET BITS (0-127)
|
|
ADD.W D1,D1 * CONVERT OFFSET TO BYTES
|
|
ADD.W D1,D1
|
|
IF DEBUG THEN
|
|
CMP.W MAXLOD(A6),D0 * VALID BLOCK NUMBER?
|
|
BCC BLKERR * BHS * NO, FAIL
|
|
ENDIF
|
|
RTS
|
|
|
|
* ----------------------
|
|
* BLKERR
|
|
* ----------------------
|
|
|
|
IF DEBUG THEN
|
|
BLKERR LEA MSGBLK,A0
|
|
BRA FATAL * 'Block range error'
|
|
|
|
DATA
|
|
MSGBLK DC.B 'Block range error',0
|
|
CODE
|
|
|
|
ENDIF
|
|
|