.NLIST ;+ ; ZMAC - Macros for ZEMU. ; (c) 2000 by Johnny Billquist ;- ; ; Setup defaults, just in case ZEMU.CND didn't define them. ; ; Default name for game files. .IF NDF GAMMAC .MACRO GAMDIR .ASCII /SY:.DAT/ .ENDM GAMDIR .ENDC ; Default name for save files. .IF NDF SAVMAC .MACRO SAVDIR .ASCII /SY:.ZSG;0/ .ENDM SAVDIR .ENDC ; Default name for script files. .IF NDF SCPMAC .MACRO SCPDIR .ASCII /SY:.LOG;0/ .ENDM SCPDIR .ENDC .IIF NDF DCSIZE DCSIZE=10. ; Default cache size. .IIF NDF GAMSTK GAMSTK=1024. ; Default game stack size. .IIF NDF DIID DIID=1 ; Default interpreter ID .IIF NDF DBUG DBUG=1 ; Debug included or not .IIF NDF EIS EIS=1 ; Use EIS .IIF NDF ESOB ESOB=0 ; Use emulated SOB .IIF NDF RSX RSX=0 ; Target is RSX system ; MAXVER=8. ; Max z-machine game version we handle. ; ; Terminal types. ; UNKT=0 ANSI=1 VT52=2 VT100=3 VT102=4 VT200=5 VT300=6 VT400=7 VT500=10 ; ; Debug options. ; D.INFO=1 ; Informational D.MEM=2 ; Memory related D.INST=4 ; Instruction related D.DEC=10 ; Instruction decoding related D.VAR=20 ; Variable related D.CACH=40 ; Cache related D.TRC=100 ; Trace D.MRF=200 ; Memory references D.STK=400 ; Stack use D.LOC=1000 ; Local variables D.PARS=2000 ; Parser D.MAP=4000 ; Memory mapping ; ; General macros. ; ; .BRK - Check for z-machine breakpoint. .MACRO .BRK HI,LO,?ADR .IF GT,DBUG CMP HI,ZBRK BNE ADR CMP LO,ZBRK+2 BNE ADR BPT ADR: .ENDC .ENDM .BRK ; .MSG - Output a text message. .MACRO .MSG TXT,ARG1,ARG2,ARG3,ARG4 .SAVE .PSECT TEXT,D,RO $$$=. .ASCIZ TXT .RESTORE MOV R1,-(SP) SUB #10,SP .IF NB ARG1 MOV ARG1,(SP) .ENDC .IF NB ARG2 MOV ARG2,2(SP) .ENDC .IF NB ARG3 MOV ARG3,4(SP) .ENDC .IF NB ARG4 MOV ARG4,6(SP) .ENDC MOV #$$$,R1 CALL ZMSG ADD #10,SP MOV (SP)+,R1 .ENDM .MSG ; .DBG - Output a conditional debug message. .MACRO .DBG WHEN,STR,ARG1,ARG2,ARG3,ARG4,?LBL .IF GT,DBUG BIT WHEN,DBGFLG BEQ LBL .MSG ,ARG1,ARG2,ARG3,ARG4 LBL: .ENDC .ENDM .DBG ; .INSTR - Setup handler for instruction, including doing some general ; maintenance at the start. .MACRO .INSTR name,args,?LBL,?FNAM .IF GT,DBUG .SAVE .PSECT TEXT,D,RO FNAM: .ASCIZ name .RESTORE BIT #D.INST,DBGFLG BEQ LBL MOV #FNAM,INAM CALL ISHOW LBL: .ENDC .IF NB args .CHKAC args .ENDC .ENDM .INSTR ; .BLK - Read data from gamefile to memory .MACRO .BLK ADDR,PAGE,CNT MOV PAGE,BPAGE MOV ADDR,BADDR .IF NB CNT MOV CNT,BCNT .IFF MOV #512.,BCNT .ENDC CALL ZBLK .ENDM .BLK ; .ALLOC - Allocate memory .MACRO .ALLOC SIZE .IF B SIZE MOV #512.,R0 .IFF MOV SIZE,R0 .ENDC CALL ZALLOC .ENDM .ALLOC ; .GETIB - Get byte from instruction stream .MACRO .GETIB DEST CALL ZGETIB .IF NB DEST MOV (SP)+,DEST .IFF MOV (SP)+,R0 .ENDC .ENDM .GETIB ; .GETIW - Get word from instruction stream .MACRO .GETIW DEST CALL ZGETIB SWAB (SP) CALL ZGETIB ADD (SP)+,(SP) .IF NB DEST MOV (SP)+,DEST .IFF MOV (SP)+,R0 .ENDC .ENDM .GETIW ; .GETBB - Get byte from byte-address .MACRO .GETBB ADDR,DEST MOV ADDR,-(SP) CALL ZGETBB .IF NB DEST MOV (SP)+,DEST .IFF MOV (SP)+,R0 .ENDC .ENDM .GETBB ; .GETWB - Get word from byte-address .MACRO .GETWB ADDR,DEST MOV ADDR,-(SP) CALL ZGETWB .IF NB DEST MOV (SP)+,DEST .IFF MOV (SP)+,R0 .ENDC .ENDM .GETWB ; .GETBW - Get byte from word-address .MACRO .GETBW ADDR,DEST MOV ADDR,-(SP) CALL ZGETBW .IF NB DEST MOV (SP)+,DEST .IFF MOV (SP)+,R0 .ENDC .ENDM .GETBW ; .GETWW - Get word from word address .MACRO .GETWW ADDR,DEST MOV ADDR,-(SP) CALL ZGETWW .IF NB DEST MOV (SP)+,DEST .IFF MOV (SP)+,R0 .ENDC .ENDM .GETWW ; .PUTBB - Put byte at byte-address .MACRO .PUTBB ADDR,VAL MOV ADDR,-(SP) MOV VAL,-(SP) CALL ZPUTBB .ENDM .PUTBB ; .PUTWB - Put word at byte-address .MACRO .PUTWB ADDR,VAL MOV ADDR,-(SP) MOV VAL,-(SP) CALL ZPUTWB .ENDM .PUTWB ; .PUTBW - Put byte at word-address .MACRO .PUTBW ADDR,VAL MOV ADDR,-(SP) MOV VAL,-(SP) CALL ZPUTBW .ENDM .PUTBW ; .PUTWW - Put word at word-address .MACRO .PUTWW ADDR,VAL MOV ADDR,-(SP) MOV VAL,-(SP) CALL ZPUTWW .ENDM .PUTWW ; .CHKAC - Check argument count of instruction .MACRO .CHKAC CNT,?LBL .IF GT,DBUG CMP R3,CNT BEQ LBL JMP BADFUN LBL: .ENDC .ENDM .CHKAC ; ; Macros to simulate some instructions we don't have if no EIS ; ; MUL .IF GT,EIS .MACRO MUL SRC,DST MOV SRC,-(SP) ; Save source. MOV DST,-(SP) ; Destination. CALL ZEMUL ; Do multiply. .NTYPE ARG1,DST ; Get destination register ARG2=ARG1 ; We have two destinations... .IF EQ ARG1&1 ; If dst is even register, ARG2=ARG1+1 ; the dst is actually 32 bits. .ENDC 012600+ARG1 ; Get high part of answer. 012600+ARG2 ; Get low part of answer. .ENDM MUL ; DIV .MACRO DIV SRC,DST .NTYPE ARG1,DST ; Get both destination registers. ARG2=ARG1+1 010046+ ; Push low part. 010046+ ; Push high part. MOV SRC,-(SP) ; Push source. CALL ZEDIV ; Do divide. TST (SP)+ ; Remove junk. 012600+ARG2 ; Save remainder. 012600+ARG1 ; Save quotient. .ENDM DIV ; ASH .MACRO ASH SRC,DST,?L1,?L2,?L3 MOV SRC,-(SP) ; Setup count in (SP) BMI L1 BEQ L3 L2: ASL DST DEC (SP) BNE L2 BR L3 L1: ASR DST INC (SP) BNE L1 L3: TST (SP)+ TST DST .ENDM ASH ; ASHC .MACRO ASHC SRC,DST,?L1,?L2,?L3 .NTYPE ARG1,DST ARG2=ARG1+1 SHL1=+ARG2 SHL2=+ARG1 SHR1=+ARG1 SHR2=+ARG2 MOV SRC,-(SP) BMI L1 BEQ L3 L2: SHL1 SHL2 DEC (SP) BNE L2 BR L3 L1: SHR1 SHR2 INC (SP) BNE L1 L3: TST (SP)+ TST DST .ENDM ASHC .ENDC ; Emulated SOB .IF GT,ESOB .MACRO SOB SRC,DST DEC SRC BNE DST .ENDM SOB .ENDC .LIST