mirror of
https://github.com/erkyrath/infocom-zcode-terps.git
synced 2026-02-14 03:44:45 +00:00
527 lines
14 KiB
Plaintext
527 lines
14 KiB
Plaintext
SUBTTL GAMEOPS
|
|
PAGE
|
|
|
|
;
|
|
; VERIFY
|
|
;
|
|
; OP VERIFY HAS BEEN GIVEN A SPLIT PERSONALITY. THE CASE THAT THE ENTIRE
|
|
; GAME FITS INTO MEMORY CALLS ON OPVR2$ WHICH READS THE GAME IN TWO 64K
|
|
; READS. THE SECOND ES SEGMENT IS USED SO THAT THE SECOND READ WILL RESTORE
|
|
; THE GAME TO ITS ORIGINAL STATE. 64K IS READ IN AND CHECKSUMED AND THEN
|
|
; THE REMAINDER OF THE GAME IS READ BACK IN AND CHECKSUMED.
|
|
;
|
|
; THE ORIGINAL VERIFY FORCES THE PRELOAD TO BE LOADED AGAIN BY SETTING THE
|
|
; ENDLOD POINTER TO ZERO. THIS TRICKS GETBYT INTO THINKING THAT NO PAGES
|
|
; ARE LOCKED ALREADY IN CORE AND FORCES A CALL TO THE PAGING ROUTINES.
|
|
;
|
|
;
|
|
PUBLIC OPVERI
|
|
OPVERI PROC
|
|
CALL GAMOPEN ; (7q) PUT THE DISK BACK IN
|
|
PRINT IDSTR
|
|
CMP FITS,1 ; (6) WHOLE GAME IN???
|
|
JNZ OPVR1$
|
|
JMP OPVR2$
|
|
OPVR1$: MOV AX,ES:[PLENTH] ; (7q) GET END BYTE ADDR
|
|
XCHG AH,AL ; (7q) FLOP BYTES
|
|
MOV ZPCFLG,1 ; (7n) SET MUNGED ZPC FLAG
|
|
PUSH SI
|
|
PUSH DI
|
|
PUSH ENDLOD
|
|
CALL BSPLITQ
|
|
MOV SI,AX
|
|
; SUB BX,2 ; (A7) A FUDGE FACTOR (B1 wrong ehb)
|
|
MOV DI,BX
|
|
|
|
CALL TBLINI ; (7n) REINITIALIZE THE PAGE TABLE
|
|
MOV BX,CURTAB
|
|
SUB BX,2 ; (A0) BACKUP TO BLK NUMBER
|
|
MOV AX,CURBLK
|
|
MOV [BX],AX
|
|
MOV AX,0FFFFH ; (A0) DWORDIFY REF TIMES
|
|
MOV [BX+2],AX ; (A0)
|
|
MOV [BX+4],AX ; (A0)
|
|
|
|
MOV AX,0
|
|
MOV BX,64
|
|
MOV DX,0
|
|
MOV ENDLOD,0
|
|
OPVR1: PUSH SI
|
|
PUSH DI
|
|
PUSH DX
|
|
CMP LSTGGD,1 ; (A16) DON'T STRUGGLE
|
|
JNE OPVRA$
|
|
CALL GETLST ; (A16) GET LAST GETBYT VALUE
|
|
JMP OPVR$$
|
|
OPVRA$: CALL GETBYT ; GET A BYTE FROM SEG1
|
|
OPVR$$: POP DX
|
|
POP DI
|
|
POP SI
|
|
ADD DX,CX ; SUM IT
|
|
CMP AX,SI
|
|
JNE OPVR1
|
|
CMP BX,DI
|
|
JNE OPVR1
|
|
MOV AX,ES:[PCHKSM] ; REMOVED SEG OVERRIDE
|
|
XCHG AH,AL
|
|
POP ENDLOD
|
|
POP DI
|
|
POP SI
|
|
OPVR4: CMP AX,DX
|
|
JE OPVR2
|
|
JMP PFALSE
|
|
OPVR2: JMP PTRUE
|
|
;
|
|
; VERIFY FOR FITS==1 OR ALL OF GAME IS IN MEMORY
|
|
;
|
|
OPVR2$: PUSH SI
|
|
PUSH DI
|
|
PUSH CX
|
|
PUSH DS ; (6) ADDRESS SEGMENT 1
|
|
MOV BX,GAMHNDL ; (6) READ FROM GAME FILE
|
|
MOV SI,GAMESEG ; (6) THROUGH DS
|
|
MOV DS,SI ; (6) SO THAT WE OVERLAY GAME
|
|
MOV CX,0 ; (6) MOVE FILE PTR TO BEGINNING
|
|
MOV DX,64 ; (6) SKIP FIRST 64 BYTES
|
|
MOV AL,0 ; (6) METHOD OF SEEKING
|
|
MOV AH,CFSEEK ; (6) SEEK FUNCTION
|
|
INT 21H ; (6) DO IT
|
|
MOV CX,03FC0H ; (7n) READ 16K AT A TIME
|
|
MOV DX,0C000H ; (6) OFFSET INTO SEGMENT
|
|
MOV AH,CRDRNDZ ; (6) READ FUNCTION
|
|
INT 21H ; (6) DO IT
|
|
CMP AX,CX ; (6) DID WE GET IT ALL
|
|
JNE OPVR5 ; (6) DIE PAINFULLY
|
|
XOR DX,DX ; (7n) ZERO THE CHECKSUM
|
|
CALL CHKSUM ; (6) DO A CHKSUM
|
|
;
|
|
OPVR6: MOV DI,DX ; (7n) SAVE CHECK SUM
|
|
MOV DX,0C000H ; (7n) BUFFER SPACE
|
|
MOV CX,4000H ; (7n) READ 16K EACH TIME
|
|
MOV AH,CRDRNDZ ; (7n) DO A RANDOM READ
|
|
INT 21H ; (7n) DO IT
|
|
CMP AX,CX ; (7n) LAST READ?
|
|
JNE OPVR8
|
|
MOV DX,DI ; (7n) RESTORE CHECKSUM
|
|
CALL CHKSUM
|
|
JMP OPVR6
|
|
OPVR8: MOV AX,ES:[PLENTH] ; (7n) GET FILE LENGTH IN WORDS
|
|
XCHG AH,AL ; (7n) INTO AX
|
|
MOV DX,0 ; (7n) ZERO THIS FOR DIVIDE
|
|
MOV CX,1000H ; (A7) 4K quadbytes per 16K bytes
|
|
DIV CX ; (7n) number of quadbytes out of 4K
|
|
SHL DX,1 ; (A7) shift twice to get bytes
|
|
SHL DX,1 ; (7n) in partial block of 16K
|
|
; SUB DX,2 ; (A7) FUDGE FACTOR (B0 Bull!-ehb)
|
|
MOV AX,DX ; (7n) DX SHOULD HAVE REM BYTES
|
|
MOV DX,DI ; (7n) RESTORE CHECKSUM
|
|
CALL CHKSUM
|
|
;
|
|
PUSH DX
|
|
MOV CX,0 ; (7n) SEEK TO 48K INTO FILE
|
|
MOV DX,0C000H ; (7n) TO GET OVERWRITTEN PART
|
|
MOV AH,CFSEEK ; (7n) FUNCTION IS SEEK
|
|
MOV AL,0 ; (7n) TO OFFSET FROM BEGINNING
|
|
INT 21H ; (7n) DO IT
|
|
MOV DX,0C000H ; (7n) NOW REFILL SEG WITH ORIG
|
|
MOV CX,4000H ; (7n) READ 16K IN
|
|
MOV AH,CRDRNDZ ; (7n) FUNCTION READ
|
|
INT 21H
|
|
POP DX
|
|
|
|
POP DS ; (6) RESTORES
|
|
POP CX
|
|
POP DI
|
|
POP SI
|
|
MOV AX,ES:[PCHKSM] ; (6) GET CHKSUM
|
|
XCHG AH,AL
|
|
JMP OPVR4
|
|
;
|
|
CHKSUM: MOV CX,AX ; (7n) GET NUMBER ACTUALLY READ
|
|
XOR AX,AX ; (6) ZERO THIS
|
|
MOV SI,0C000H ; (7n) 48K INTO THE BUFFER
|
|
JCXZ OPVR7 ; (B0) check for 0 before loop
|
|
OPVR3: LODSB ; (6) GET A BYTE
|
|
ADD DX,AX ; (6) ADD IT ALL UP
|
|
LOOP OPVR3
|
|
OPVR7: RET
|
|
;
|
|
OPVR5: FATAL FTL7 ; GAME FILE READ ERROR
|
|
OPVERI ENDP
|
|
|
|
;
|
|
; SAVE AND RESTORE HAVE BEEN MODIFIED TO USE DOS 2.0 FILE NAMES. THIS
|
|
; ALLOWS THE USER TO SAVE AND RESTORE TO ANY DISK DRIVE AND ANY SUBDIRECTORY.
|
|
; FILE NAMES ARE READ FROM THE CONSOLE AND TRANSFERRED INTO THE SAVFILE
|
|
; VARIABLE WITH NO PARSING OTHER THAN A CHECK FOR A DISK DRIVE SPECIFIER.
|
|
; IF THE NAME IS TYPED INCORRECTLY, THEN DOS RETURNS AN ERROR WHICH WE
|
|
; REPORT ACCORDINGLY.
|
|
|
|
;
|
|
; RESTORE
|
|
;
|
|
PUBLIC OPREST
|
|
OPREST PROC
|
|
MOV DSKDIR,0 ;INDICATE RESTORE (READ)
|
|
JMP OSV0$
|
|
OPREST ENDP
|
|
|
|
;
|
|
; SAVE
|
|
;
|
|
PUBLIC OPSAVE
|
|
OPSAVE PROC
|
|
MOV DSKDIR,1 ;INDICATE SAVE (WRITE)
|
|
|
|
;
|
|
;COMMON ENTRYPOINT FOR SAVE AND RESTORE
|
|
;
|
|
PUBLIC OSV0$,OSVD1,OSVD2,OSVD3,OSVD4A,OSVPSX,OSVOPW
|
|
PUBLIC OSVOPDF,OSVPS,OSVT0,OSV4X,OSV4Y
|
|
; PUBLIC OSVCC,OSV1C,OSV2C
|
|
PUBLIC OSV4,OSVPRR
|
|
; DO A DISK RESET IN CASE THEY WANT TO CHANGE DISKS
|
|
; UNFORTUNATELY WE HAVE TO ASSUME A 1 DRIVE SYSTEM AT THIS POINT
|
|
|
|
OSV0$: CMP FITS,1 ; (n) ARE WE ALL THERE
|
|
JZ OSV0A ; (n) YES, NO CLOSE
|
|
MOV AH,CFCLOSZ ; (7s) CLOSE THE GAME FILE
|
|
MOV BX,GAMHNDL ; (7s) FOR REINSERTION
|
|
INT 21H
|
|
MOV AH,CDRESET ; (K6) WILL RESET FLUSH BUFFERS?
|
|
INT 21H ; (K6) HOPE SO...
|
|
|
|
; PRINT "FILENAME (DEFAULT IS drv:filename.ext):"
|
|
|
|
; PRINT "FILENAME (DEFAULT IS drv:"
|
|
OSV0A: PRINT SAV0 ;PRINT "INSERT SAVE DISK THEN ENTER FILE NAME."
|
|
PRINT SAV1 ;PRINT "FILE NAME (DEFAULT IS "
|
|
TEST DRVFLG,1 ; HAS USER SPECIFIED A DRIVE
|
|
JNZ OSVD1 ; YES, USE USER DEFAULT DRIVE
|
|
MOV AL,CURDRV ;AL <= DRIVE NO.
|
|
ADD AL,65 ;....NO. ADD 65 TO GET ASCII CHARACTER
|
|
CALL MTTYO ;PRINT DRIVE B, C, OR D
|
|
MOV AL,":" ;PRINT ":"
|
|
CALL MTTYO
|
|
|
|
; PRINT "filename"
|
|
OSVD1: PUSH SI ; (6) SAVE THIS
|
|
MOV SI,OFFSET SAVFILE ; (6) POINTER TO SAVE FILENAME (6)
|
|
MOV CX,SI ; (6) SAVE POINTER
|
|
CLD ; (6) SET DIR INCREMENT
|
|
OSVD2: LODSB ; (6) GET A BYTE INTO AL
|
|
TEST AL,AL ; (6) CHECK IF NULL
|
|
JZ OSVD3 ; (6) EXIT THIS LOOP
|
|
CALL MTTYO ; (6) OUTPUT IT
|
|
JMP OSVD2
|
|
OSVD3: SUB SI,CX ; (6) CALCULATE NUMBER OF CHARS
|
|
MOV CX,SI ; (6) GET NUMBER BACK INTO CX
|
|
POP SI ; (6) RESTORE THIS
|
|
|
|
; PRINT " ): "
|
|
PRINT SAV2 ;PRINT " ): "
|
|
CMP SCPL,50 ;ARE MAX CHARS/LINE >50?
|
|
JG OSVD4A ;....YES
|
|
CALL MCRLF ;....NO. PRINT A <cr><lf>
|
|
|
|
; GET LOSER'S SAVE FILENAME FROM THE KEYBOARD
|
|
OSVD4A: MOV BX,OFFSET INBUF ;^ KEYBOARD INPUT BUFFER
|
|
MOV AL,63 ;(6) COULD BE A WHOLE PATH
|
|
MOV BYTE PTR [BX],AL ;SET UP BUFFER TO TAKE 15 CHARACTERS
|
|
MOV DX,BX ;DX ^ BUFFER
|
|
MOV AH,CRDLIN ;READ A LINE FROM THE KEYBOARD
|
|
INT 21H
|
|
|
|
; PARSE THE FILENAME
|
|
|
|
CALL SAVESAV ; (7o) PRESERVE THE SAVE NAME
|
|
PUSH SI
|
|
PUSH DI
|
|
PUSH CX ; SAVE THIS
|
|
PUSH ES
|
|
PUSH DS
|
|
POP ES
|
|
LEA SI,INBUF[1] ; POINT TO NUM CHARS READ
|
|
LODSB ; GET NUM
|
|
TEST AL,AL ; ANY CHARS READ
|
|
JZ LOOK
|
|
MOV CL,AL ; STORE IT
|
|
XOR CH,CH ; CLEAR TOP HALF OF COUNTER
|
|
MOV DI,OFFSET SAVFILE ; (6) DI ^FCB
|
|
REPZ MOVSB ; TRANSFER THE STRING IF ANY
|
|
MOV AL,0 ; (6) GET A NULL
|
|
STOSB ; (6) DROP IT IN AT END OF STRING
|
|
LOOK: TEST SCRFLG,1 ; (7p) IS SCRIPTING ON?
|
|
JZ NOSCR ; (7p) NO SCRIPTING
|
|
CALL SCRSAVE ; (7p) SCRIPT THE SAVE FILE NAME
|
|
NOSCR: MOV SI,OFFSET SAVFILE ; (6) IS THERE A ':'
|
|
INC SI
|
|
LODSB ; (6) CHECK IT
|
|
CMP AL,':' ; (6) IF SO, FIX DEFDRV
|
|
JNZ NODRV ; (6) NOPE...
|
|
MOV DRVFLG,1 ; (6) SET FLAG
|
|
MOV AL,SAVFILE ; (7n) GET DRIVE LETTER
|
|
AND AL,5FH ; (7n) UPPERCASIFY
|
|
SUB AL,'A' ; (7n) BASIFY
|
|
CMP AL,CURDRV ; (7n) DON'T CHANGE IF UNNECESSARY
|
|
JZ DRV
|
|
MOV DL,AL ; (7n) SET UP FOR CHGDSK
|
|
MOV AH,CSELDSK ; (7n) SELECT DISK IN DL
|
|
INT 21H
|
|
MOV AH,CURDSK ; (7n) CHECK IF IT WORKED
|
|
INT 21H
|
|
MOV CURDRV,AL ; (7n) SAVE IT
|
|
JMP DRV
|
|
USEDEF: MOV SKPDRV,1 ; (7n) DON'T OUTPUT A DRIVE
|
|
NODRV: MOV DRVFLG,0
|
|
DRV: POP ES
|
|
POP CX
|
|
POP DI ;RESTORE'M
|
|
POP SI
|
|
CALL MCRLF ; (7) SCROLL PROPERLY
|
|
|
|
; OPEN THE FILE IF OP RESTORE
|
|
|
|
CMP DSKDIR,1 ;OP SAVE?
|
|
JE OSVOPW ;....YES
|
|
MOV DX,OFFSET SAVFILE ; 6) ....NO. OP RESTORE. DX ^ FCB
|
|
MOV AH,CFOPENZ ; (6) SELECT DOS OPEN FUNCTION
|
|
MOV AL,0 ; (6) FILE OPEN FOR READING
|
|
INT 21H ;OPEN THE FILE
|
|
JC OSVPSX ; (6) ....NO. FILE NOT FOUND
|
|
JMP OSVPS ;....YES
|
|
;
|
|
; **** ERROR **** [File Not Found]
|
|
;
|
|
OSVPSX: MOV AX,OFFSET ERR1 ;^ "SAVE FILE NOT FOUND" MSG
|
|
JMP OSVPER ;ERROR EXIT
|
|
|
|
; CREATE THE FILE IF OP SAVE
|
|
OSVOPW: MOV DX,OFFSET SAVFILE ; (6) ^ FCB
|
|
MOV CX,0 ; (6) NO SPECIAL ATTRIBUTE
|
|
MOV AH,CFCREAZ ; (6) SELECT DOS CREATE FUNCTION
|
|
INT 21H
|
|
JC OSVOPDF
|
|
JMP OSVPS ;....YES
|
|
;
|
|
; **** ERROR **** [Directory Full]
|
|
;
|
|
OSVOPDF:MOV AX,OFFSET ERR4 ;....NO. ^ "NO ROOM IN DIRECTORY" MSG
|
|
JMP OSVPER ;HOP TO ERROR EXIT
|
|
;
|
|
; WE'VE GOT AN OPEN FILE (WHICH WE CREATED IF IT WAS A SAVE FUNCTION)
|
|
; AND ARE READY TO EITHER READ (RESTORE) OR WRITE (SAVE) AS REQUIRED
|
|
;
|
|
; THE BELOW CODE GRIMLY EXPLAINS THE FORMAT OF A SAVE FILE. BASICALLY,
|
|
; FROM WHAT I CAN TELL, THE LOCALS AND VITALS ARE PUSHED ONTO THE ZSTACK
|
|
; AS WELL AS THE ZPC AND THE ZSTACK POINTER. THIS INFORMATION IS FIRST
|
|
; WRITTEN TO DISK. THEN THE REST OF PURBOT IS WRITTEN TO DISK. THIS CODE
|
|
; ALSO WORKS FOR A RESTORE. SO THE SAVE FILE CONSISTS OF FIRST ZIP INFO
|
|
; SAVED ON DISK FOLLOWED BY THE IMPURE PART OF THE GAME CODE.
|
|
;
|
|
OSVPS: XCHG DI,SP
|
|
PUSH ZPC1 ; PUSH VITALS ONTO ZSTACK
|
|
PUSH ZPC2
|
|
PUSH ZLOCS
|
|
PUSH ZORKID
|
|
|
|
|
|
SUB SP,OFFSET STKBOT ; (7v) RELATIVISE THE POINTER
|
|
MOV STKBOT,SP ; PUT DEST. INDEX INTO STACKBOTTOM
|
|
MOV SP,DI ; RESTORE SP
|
|
|
|
MOV SAVHNDL,AX ; SAVE FILE HANDLE
|
|
PUSH ES
|
|
|
|
MOV AX,SS ; FLOP STACK SEG AND EXTRA SEG
|
|
MOV ES,AX ; ES<=SS
|
|
|
|
MOV DX,OFFSET STKBOT ; CORE LOCATION
|
|
MOV CX,LSTACK*2 ; (6) DO TRANSFER HERE
|
|
MOV BX,SAVHNDL ; (6) GET HANDLE
|
|
MOV AH,CRDRNDZ ; SETUP FOR A READ
|
|
ADD AH,DSKDIR ; MAKE IT A WRITE IF NECESSARY
|
|
INT 21H ;
|
|
CMP AX,400H ; DID WE GET IT ALL
|
|
PUSHF ;SAVE RETURN CODE
|
|
MOV DI,SP ;DI ^ CURRENT ZSTACK POSITION
|
|
MOV SP,STKBOT ;SP <= ZSTACK POINTER
|
|
ADD SP,OFFSET STKBOT ; (7v) RELATIVISE THIS VALUE
|
|
POP AX ; POP OFF AND COMPARE FOR ZORKID
|
|
CMP AX,ZORKID ;ID OK?
|
|
JE OSVT0 ;....YES
|
|
MOV GAMEIN,0 ; (7v) INDICATE THAT THE GAME IS LOST
|
|
FATAL FTL4 ;....NO. FATAL ERROR
|
|
|
|
OSVT0: POP ZLOCS ;RESTORE LOCALS AND ZIP PROGRAM COUNTERS
|
|
POP ZPC2
|
|
POP ZPC1
|
|
|
|
XCHG DI,SP ;RESTORE MACHINE SP AND ZSTACK POINTER
|
|
POPF ;RESTORE REGS
|
|
POP ES
|
|
JNE OSV4Y ;TRANSFER WAS UNSUCCESSFUL
|
|
;
|
|
; THE OPEN/CREATE FILE WAS SUCCESSFUL, AND SO WAS THE BLOCK TRANSFER
|
|
; SO TRANSFER THE REST
|
|
;
|
|
OSV4X: MOV CX,ES:[PPURBT] ; (K3) MAYBE THIS IS WRONG
|
|
XCHG CH,CL ; (K3) XCHANGE BYTES
|
|
MOV AH,CRDRNDZ ; (K1) FUNCTION IS READ (OR WRITE)
|
|
ADD AH,DSKDIR ; (K1) ADD IN WRITE STUFF
|
|
MOV BX,SAVHNDL ; (K1) READ IT FROM HERE
|
|
MOV DX,0 ; (K1) READ IT RIGHT IN TO SEG0
|
|
PUSH DS ; (K1) SAVE DS
|
|
PUSH ES ; (K1) FLOP BYTES
|
|
POP DS ; (K1) ES IS NOW DOS ADDRESSIBLE
|
|
INT 21H ; (K1) DO THE SAVE/RESTORE
|
|
POP DS ; (K1) RESTORE DS
|
|
CMP AX,CX ; (K1) DID WE GET IT ALL?
|
|
OSV4Y: PUSHF ;SAVE DOS RETURN CODE
|
|
MOV AH,CFCLOSZ ; (6) CLOSE THE FILE
|
|
MOV BX,SAVHNDL ; (6) WITH THIS HANDLE
|
|
INT 21H
|
|
POPF ;RESTORE DOS RETURN CODE
|
|
JNE OSV4 ;ERROR EXIT
|
|
;
|
|
;ELSE EVERYTHING WORKED SUCCESSFULLY
|
|
;AND WE CAN GO BACK TO WHAT WE WERE
|
|
;DOING..........
|
|
;
|
|
MOV AH,SCRFLG ; (J2) FIX SCRFLG
|
|
OR AH,STSBIT ; (A9) TURN ON STATUS LINE REFRESH BIT
|
|
XOR AL,AL ; (J2)
|
|
MOV WORD PTR ES:[PFLAGS],AX ; (J1) SCRIPT SHOULD MATCH SCRFLG
|
|
CMP FITS,1 ;(n) do not need to replace disk if in mem
|
|
JZ n1
|
|
CALL GAMOPEN ; (7s) OPEN GAME FILE
|
|
MOV DL,CURDRV ; (7n) RETURN TO SAVE DISK
|
|
MOV AH,CSELDSK ; (7n) AND SELECT IT FOR OPEN
|
|
INT 21H
|
|
N1: CALL NEWZPC ;GET A NEW PC
|
|
MOV AX,2 ; (A0) RETURN 1 FOR SAVE OR 2 FOR RESTORE
|
|
SUB AL,DSKDIR ; (A0) SUBTRACT ONE FOR SAVE
|
|
JMP PUTVAL ; (A0)
|
|
;
|
|
; **** ERROR **** [Unable to Read File]
|
|
;
|
|
OSV4: MOV AX,OFFSET ERR6 ;^ "Read of SAVE file failed."
|
|
CMP DSKDIR,1 ;OP SAVE?
|
|
JNE OSVPRR ;....NO
|
|
MOV AH,CFCLOSZ ; (6) ....YES. CLOSE IT
|
|
MOV BX,SAVHNDL ; (6) GET HANDLE FOR CLOSE
|
|
INT 21H
|
|
;
|
|
; **** ERROR **** [Diskette Full]
|
|
;
|
|
MOV DX,OFFSET SAVFILE ; (7n) DELETE THE PIECE OF A FILE
|
|
MOV AH,CFDELEZ ; (7n) SO AS NOT TO CONFUSE
|
|
INT 21H
|
|
MOV AX,OFFSET ERR5 ;^ "No room on diskette for SAVE file."
|
|
OSVPRR: JMP OSVPER
|
|
OPSAVE ENDP
|
|
;
|
|
; ERROR EXIT R/W operations
|
|
;
|
|
OSVPER PROC
|
|
CALL MPRNT ;PRINT ERROR MESSAGE
|
|
CALL ZRESTOR ; (7o) RESTORE OLD SAVE NAME
|
|
CMP FITS,1 ; (7v) HAVE WE CLOSED THE GAME FILE
|
|
JZ OSVPR1 ; (7v) SKIP REOPEN
|
|
CALL GAMOPEN ; (7v) OPEN IT
|
|
OSVPR1: MOV AH,SCRFLG ; (A13) RESTORE SCRIPTING STATE
|
|
OR AH,STSBIT ; (A9) TURN ON STATUS LINE REFRESH BIT
|
|
XOR AL,AL ; (J1) FIX SCRIPT ON BAD RESTART (RANDOM)
|
|
MOV ES:[PFLAGS],AX
|
|
MOV AX,0 ; (A0) RETURN A FALSE
|
|
JMP PUTVAL ; (A0)
|
|
OSVPER ENDP
|
|
;
|
|
PUBLIC SAVESAV,ZRESTOR,SCRSAVE
|
|
SCRSAVE PROC
|
|
PUSH AX ; (7p) SAVES
|
|
PUSH SI
|
|
PUSH DX
|
|
MOV SI,OFFSET SAVFILE ; (7p) POINTER TO SAVE
|
|
SCRS0: LODSB ; (7p) GET A CHARACTER
|
|
TEST AL,AL ; (7p) LOOK FOR A NULL
|
|
JNZ SCRS1 ; (7p) DIE ON A NULL
|
|
POP DX
|
|
POP SI
|
|
POP AX
|
|
RET ; (7p) RETURN
|
|
SCRS1: MOV DL,AL ; (7p) GET CHARACTER INTO DL
|
|
MOV AH,CPROUT ; (7p) FOR DOS"IE" OUTPUT
|
|
INT 21H ; (7p) PRINT IT
|
|
JMP SCRS0
|
|
SCRSAVE ENDP
|
|
|
|
SAVESAV PROC
|
|
PUSH DI ; (7o) SAVES
|
|
PUSH SI
|
|
PUSH AX
|
|
PUSH ES
|
|
MOV AX,DS ; (7o) SET UP REGS
|
|
MOV ES,AX
|
|
MOV AL,CURDRV ; (7o) SAVE CURRENT DRIVE SPEC
|
|
MOV LASTDRV,AL ; (7o) IN CASE OF FAILURE
|
|
MOV AL,DRVFLG ; (7o) TEST DRIVE FLAG
|
|
MOV LSTDFLG,AL ; (7o) IN CASE OF FAILURE
|
|
MOV SI,OFFSET SAVFILE ; (7o) SETUP SOURCE AND DESTINATION
|
|
MOV DI,OFFSET LASTSAV
|
|
COPYLP: LODSB ; (7o) GET A BYTE
|
|
STOSB ; (7o) STORE A BYTE
|
|
TEST AL,AL ; (7o) STOP ON A NUL
|
|
JNZ COPYLP ; (7o) CONTINUE THE COPY
|
|
POP ES
|
|
POP AX ; (7o) RESTORES
|
|
POP SI
|
|
POP DI
|
|
RET
|
|
SAVESAV ENDP
|
|
;
|
|
;
|
|
ZRESTOR PROC
|
|
PUSH DI ; (7o) SAVES
|
|
PUSH SI
|
|
PUSH AX
|
|
PUSH ES
|
|
MOV AX,DS ; (7o) SET UP REGS
|
|
MOV ES,AX
|
|
MOV AL,LSTDFLG ; (7o) GET LAST DRIVE FLAG
|
|
MOV DRVFLG,AL ; (7o) AND RESTORE IT
|
|
MOV AL,LASTDRV ; (7o) GET ORIGINAL DRIVE SPEC
|
|
CMP AL,CURDRV ; (7o) HAS IT CHANGED
|
|
JZ ZRES1
|
|
MOV DL,AL ; (7o) SELECT DISK
|
|
MOV AH,CSELDSK ; (7o) TO CORRECT
|
|
INT 21H
|
|
MOV CURDRV,DL ; (7o) UPDATE THIS BABY
|
|
ZRES1: MOV DI,OFFSET SAVFILE ; (7o) SETUP SOURCE AND DESTINATION
|
|
MOV SI,OFFSET LASTSAV
|
|
ZRESLP: LODSB ; (7o) GET A BYTE
|
|
STOSB ; (7o) STORE A BYTE
|
|
TEST AL,AL ; (7o) STOP ON A NUL
|
|
JNZ ZRESLP ; (7o) CONTINUE THE COPY
|
|
POP ES
|
|
POP AX ; (7o) RESTORES
|
|
POP SI
|
|
POP DI
|
|
RET
|
|
ZRESTOR ENDP
|
|
;
|
|
; OP RESTART
|
|
;
|
|
PUBLIC OPRSTT
|
|
OPRSTT PROC
|
|
MOV BP,CHRPTR
|
|
MOV BYTE PTR DS:[BP],0 ;FORCE OUT THE BUFFER
|
|
PRINT OUTBUF
|
|
JMP RESTRT ;JUMP TO RESTART ADDRESS
|
|
OPRSTT ENDP
|
|
|
|
PUBLIC OPQUIT
|
|
OPQUIT PROC
|
|
JMP FINISH
|
|
OPQUIT ENDP
|