mirror of
https://github.com/erkyrath/infocom-zcode-terps.git
synced 2026-02-08 01:01:24 +00:00
379 lines
13 KiB
Plaintext
379 lines
13 KiB
Plaintext
|
|
SUBTTL SYSINI - HIGH LEVEL IBMPC DEPENDENT STUFF
|
|
PAGE
|
|
|
|
;SYSTEM INITIALIZATION
|
|
; SYSINI HAS BEEN GREATLY MODIFIED TO INCLUDE DOS 2.0 FILE HANDLING,
|
|
; COMMAND LINE ARGUMENTS, COPY PROTECTION, AND DYNAMIC ALLOCATION OF
|
|
; PAGING SPACE.
|
|
;
|
|
; THE COPY PROTECTION SCHEME WORKS AS FOLLOWS: A NUMBER OF COMPUTERS ARE
|
|
; DEFINED AS COMPATIBLE WITH IBM IN THE DATA DECLARATIONS. INCLUDED FOR
|
|
; EACH IS THE FIRST 9 LETTERS OF THE COPYRIGHT NOTICE THAT EXISTS IN THE
|
|
; ROM. IF ANY OF THESE STRINGS IS FOUND IN THE ROM, COPY PROTECTION IS
|
|
; CHECKED, OTHERWISE IT IS NOT. IBM COMPATIBILITY MEANS TOTAL ROM BIOS
|
|
; COMPATIBILITY SUCH THAT WINDOWED SCROLLING AND SPECIAL DISK I/O MAY BE
|
|
; PERFORMED. NOT FINDING ANY OF THESE STRINGS RESULTS IN THE ZIP FUNCTIONING
|
|
; AS IF IT WERE ON A GENERIC MS-DOS BASED MACHINE.
|
|
;
|
|
; COMMAND LINE ARGUMENTS SET BITS IN THE VARIABLE CMDLIN IN THE ROUTINE
|
|
; SCANCMD. CMDLIN THEN AFFECTS VARIOUS PARAMETERS AND VARIABLES EITHER IN
|
|
; SYSINI OR SSETUP.
|
|
;
|
|
; THE PAGTAB IS SET UP ACCORDING TO AVAILABLE MEMORY. THERE EXISTS A WORD
|
|
; AT OFFSET 2 IN THE PSP (PROGRAM SEGMENT PREFIX, OR WHERE CS POINTS) WHICH
|
|
; INDICATES THE TOP OF PHYSICAL MEMORY. PAGTAB REPRESENTS THE LAST WORD USED
|
|
; BY THE ZIP. THE CODE SEGMENT REPRESENTS THE AMOUNT OF MEMORY TAKEN UP BY
|
|
; EVERYTHING UNDER THE ZIP SUCH AS THE OPERATING SYSTEM AND DEVICE DRIVERS.
|
|
; IF WE CONVERT PAGTAB TO PARAGRAPHS, THEN ALL OF THESE NUMBERS ARE IN
|
|
; PARAGRAPHS. SO:
|
|
;
|
|
; TOP_OF_MEM - (CS + PAGTAB) --> AVAILABLE MEMORY IN PARAGRAPHS
|
|
;
|
|
; AVAILABLE MEMORY IS CONVERTED INTO THE NUMBER OF BUFFERS AVAILABLE. FROM
|
|
; THIS NUMBER WE MUST SUBTRACT 1 OR 2 BUFFERS TO ALLOW FOR THE PAGTAB TO
|
|
; BE BUILT. KNOWING AVAILABLE BUFFERS TELLS US THE LENGTH OF OUR PAGTAB
|
|
; SINCE OUR PAGTAB IS 4 BYTES/BUFFER. AT THE NEXT PARAGRAPH BOUNDARDY BEYOND
|
|
; THE PAGTAB WE HAVE OUR FIRST GAME SEGMENT WHICH WILL BE MOVED TO ES AND
|
|
; STORED IN THE VARIABLE GAMESEG. ADDING 64K (IN PARAGRAPHS) TO GAMESEG
|
|
; WE ARRIVE AT OUT LOCATION FOR SEG1, THE SECOND GAME SEGMENT. THE PAGTAB
|
|
; IS THEN INITIALIZED.
|
|
;
|
|
PUBLIC SYSINI,SYS1,INITLP,SYSFTL,GOODOS,GODOS1
|
|
SYSINI PROC
|
|
MOV AH,DOSVER ; (7) GET DOS VERSION #
|
|
INT 21H ; (7) MUST BE 2.0 OR HIGHER
|
|
CMP AL,2 ; (7) DOS 2.0+
|
|
JGE GOODOS
|
|
FATAL FTL11 ; (7) DIE APPROPRIATELY
|
|
|
|
; ESTABLISH THE IBMNESS OF THE HOST
|
|
GOODOS: MOV IBMPC,0 ; (A9) PRESET TO NOT AN IBM
|
|
PUSH ES ; (A9)
|
|
PUSH DI ; (A9)
|
|
MOV BX,0F000H ; (A9) SEGMENT
|
|
MOV ES,BX ; (A9) LOAD THE SEGMENT
|
|
MOV DI,0E000H ; (A9) ES:DI OFFSET
|
|
|
|
MOV AX,OFFSET IBMSTR ; (A9) ^ IBM STRING
|
|
MOV CX,16H ; (A9) NO. CHARACTERS TO SEARCH
|
|
MOV DX,9 ; (A9) NO. OF CHARACTERS
|
|
CALL CHK ; (A9) SEE IF THIS IS AN IBM
|
|
POP DI ; (A9) RESTORE THOSE REGISTERS
|
|
POP ES ; (A9)
|
|
JC GODOS1 ; (A9) CARRY SET = IT'S NOT AN IBM
|
|
MOV IBMPC,1 ; (A9) SET FLAG TO INDICATE AN IBM
|
|
|
|
GODOS1: MOV AH,CURDSK ; (6) GET DEFAULT DRIVE
|
|
INT 21H ; (6) FROM DOS
|
|
MOV DEFDRV,AL ; (6) SAVE DEFAULT DRIVE
|
|
MOV CURDRV,AL ; (6) SAVE DEFAULT DRIVE
|
|
CALL SCANCMD ; (7) GET CMD LINE VARS
|
|
GOTONE: MOV SCROLL,0 ; (7) USE WINDOWED SCROLLING
|
|
NOCMD: MOV AH,CFOPENZ ; (6) ASCIZ STRINGS
|
|
MOV AL,0 ; (6) OPEN FOR READING
|
|
MOV DX,OFFSET GAMFILE
|
|
INT 21H
|
|
JNC SYSA$
|
|
JMP SYSFTL
|
|
SYSA$: MOV GAMHNDL,AX ; (6) SAVE THE FILE HANDLE
|
|
MOV BX,AX ; (7n) GET FILE HANDLE INTO BX
|
|
XOR CX,CX ; (7n) ZERO THESE
|
|
XOR DX,DX ; (7n) TO FIND EOF
|
|
MOV AH,CFSEEK ; (7n) SEEK TO END OF FILE
|
|
MOV AL,2 ; (7n) MOVE FILE PTR TO EOF
|
|
INT 21H ; (7n) DO IT
|
|
|
|
MOV CX,4 ; (7n) CONVERT AX TO PARAGRAPHS
|
|
SYSA0: SHR AX,1 ; (7n) TO SAVE AS FILESIZE
|
|
TEST DX,1 ; (A0) TEST HIBIT
|
|
JNZ SYSA1
|
|
SYSA2: SHR DX,1 ; (A0) MOVE HIWORD TOO
|
|
LOOP SYSA0
|
|
JMP SYSB$
|
|
SYSA1: OR AH,80H ; (7n) TURN ON THAT BIT
|
|
JMP SYSA2
|
|
|
|
SYSB$: MOV CL,5 ; (7n) REDUCE TO NUMBER OF 512 BLKS
|
|
SHR AX,CL ; (7n) FOR COMPARISON TO BUFFERS
|
|
MOV GAMESIZ,AX ; (7n) SAVE THIS SIZE FOR FITS
|
|
|
|
XOR CX,CX ; (7w) MOVE POINTER TO BOF
|
|
MOV DX,4 ; (7w) WE WANT THE WORD AT OFFSET 4
|
|
MOV AH,CFSEEK ; (7w) SEEK THERE
|
|
MOV AL,0 ; (7w) METHOD: OFFSET FROM BOF
|
|
INT 21H ; (7w) BX HAS FILE HANDLE
|
|
MOV AH,CRDRNDZ ; (7w) READ IN THE FIRST
|
|
MOV CX,2 ; (7w) READ THE WORD OF ENDLOD
|
|
MOV DX,OFFSET SSBUF ; (7w) ANY BUFFER BIG ENOUGH WILL DO
|
|
INT 21H ; (7w) READ IT
|
|
MOV AX,SSBUF ; (7w) GET THE WORD
|
|
XCHG AH,AL ; (7w) FLOP THE BYTES
|
|
TEST AX,1FFH ; (7w) ROUND UP TO NEXT BLOCK
|
|
JE SYSC$
|
|
AND AX,0FE00H ; (7w) TURN OF LOW BITS
|
|
ADD AX,200H ; (7w) ADD A BLOCK
|
|
SYSC$: MOV CL,9 ; (7w) CONVERT TO NUMBER OF BLOCKS
|
|
SHR AX,CL
|
|
MOV DX,AX ; (7w) AND SAVE NUMBER IN DX
|
|
|
|
MOV BX,2 ; (6) GET TOP OF MEMORY
|
|
MOV BX,CS:[BX] ; (6) FROM OUT OF THE PSP
|
|
MOV AX,CS ; (6) GET CODE SEG
|
|
SUB BX,AX ; (6) SUB CSEG FROM TOPMEM
|
|
MOV CL,4 ; (6) SHIFT COUNT
|
|
MOV AX,OFFSET PAGTAB ; (6) USE OFFSET TO FIGURE PARAG'S
|
|
SHR AX,CL ; (6) REDUCE THIS OFFSET TO PARAS
|
|
INC AX ; (6) SKIP ONE PARAGRAPH
|
|
AND AX,0FE0H ; (7z) BLOCKIFY THIS NUMBER
|
|
ADD AX,20H ; (7z) OTHERWISE LOSE A PAGE
|
|
SUB BX,AX ; (6) YIELDS PARAS AVAILABLE
|
|
|
|
TEST CMDLIN,4 ; (7) SET ON CMDLIN?
|
|
JZ SYS2
|
|
CMP BX,MEMORY ; (7) REASONABLE REQUEST
|
|
JBE SYS2 ; (7) NO, NOT REALLY THERE
|
|
MOV BX,MEMORY ; (7) USE USER SETTING
|
|
|
|
SYS2: CMP BX,MINMEM ; (7) AT LEAST 48K?
|
|
JAE SYS3 ; (7) YES
|
|
FATAL FTL12 ; (7) DIE APPROPRIATELY
|
|
SYS3: MOV CL,5 ; (6) DIVIDE BY 32 TO GET BUFFERS
|
|
SHR BX,CL ; (6) TO GET #BUFFERS
|
|
CMP BX,GAMESIZ ; (A0) IF LESS THEN NO PAGTAB NECES
|
|
JGE SYS4 ; (A0) SET THE FLAGS
|
|
SUB BX,DX ; (7w) SUBTRACT ALL PRELOD BLOCKS
|
|
JA SYS3A ; (A3) FATAL IF MORE PRELOD THAN BLKS
|
|
SYS3$: FATAL FTL12 ; (A3) SO DIE
|
|
SYS3A: CMP BX,5 ; (A3) THERE MUST BE AT LEAST 2 BUFS
|
|
JBE SYS3$ ; (A3) SO DIE IF NOT ENOUGH
|
|
SUB BX,4 ; (A0) SUB 4 BUFS FOR PAGTAB
|
|
CMP BX,255 ; (6) ABOVE 256, WE NEED MORE TBL
|
|
JB SYS1 ; (6) WE HAVE THIS MANY OR FEWER
|
|
SUB BX,2 ; (6) TAKE AWAY ANOTHER PAGE
|
|
CMP BX,383 ; (A0) ARE WE BETWEEN 3 AND 4 SEGS
|
|
JB SYS1 ; (A0) CHECK FOR FIT
|
|
SUB BX,2 ; (A0) WE GOT PLENTY, NEED 2 BUFFS
|
|
CMP BX,511 ; (6) THIS IS THE MOST WE WILL NEED
|
|
JLE SYS1 ; (6) DON'T MODIFY BX <= 255
|
|
MOV FITS,1 ; (6) FLAG THAT GAME FITS IN MEMORY
|
|
MOV BX,511 ; (6) DON'T ALLOW MORE THAN THIS
|
|
SYS1: PUSH BX ; (7w) SAVE THIS FOR FIDDLING
|
|
ADD BX,DX ;(7w) ADD IN THE BLOCKS PREV SBTRCTED
|
|
CMP BX,GAMESIZ ; (7n) CHECK FOR LUCKY FIT
|
|
POP BX ; (7w) AND RESTORE ACTUAL #BUFFERS
|
|
JBE SYSD$ ; (7n) IF BX IS GREATER, NO GO
|
|
SYS4: MOV FITS,1 ; (7n) IT DOES FIT AFTERALL!!!
|
|
MOV BX,OFFSET PAGTAB
|
|
JMP SYS5
|
|
SYSD$: MOV BUFFERS,BX ; (6) SAVE THIS NUMBER
|
|
MOV CL,3 ; (A0) MULTIPLY BUFFERS BY 8
|
|
SHL BX,CL ; (6) GET NUMBER OF BYTES IN PAGTBL
|
|
ADD BX,2 ; (A0) ADD 2 FOR TERMINATOR WORD
|
|
ADD BX,OFFSET PAGTAB ; (6) CALC TABLE LOCATION
|
|
SYS5: MOV CX,4 ; (6) REDUCE #BYTES IN TABLE = PARAS
|
|
SHR BX,CL ; (6) TO DYNAMICALLY ALLOCATE SPACE
|
|
MOV AX,DS ; (6) GET A COPY OF CURRENT SEG
|
|
ADD BX,AX ; (6) AND CALCULATE THE NEW SEG
|
|
ADD BX,1 ; (6) ADD ONE PARAGRAPH FOR SAFETY
|
|
MOV GAMESEG,BX ; (6) THIS WILL BE USED FOR ES:GAME
|
|
ADD BX,1000H ; (6) ADD 64K TO CALC 2ND SEG
|
|
MOV SEG1,BX ; (6) THIS IS SEG0+64K
|
|
TEST FITS,1 ; (A0) DON'T INIT A NON-EXISTANT TBL
|
|
JNZ SYS6
|
|
CALL TBLINI ; (7n) CALL TABLE INITIALIZATION
|
|
SYS6: CALL SSETUP
|
|
CALL INITSND ; (A0) INITIAL TIMER2 FOR SOUND
|
|
MOV AX,GAMESEG ; (A0) SET ES TO GAME SEG
|
|
MOV ES,AX
|
|
RET
|
|
SYSFTL: FATAL FTL9
|
|
SYSINI ENDP
|
|
|
|
|
|
; THIS ROUTINE INITIALIZES THE PAGE TABLE
|
|
;
|
|
TBLINI PROC
|
|
PUSH SI ; SAVES
|
|
PUSH DI
|
|
PUSH AX
|
|
PUSH BX
|
|
PUSH CX
|
|
MOV DI,OFFSET PAGTAB ; (6) GET BEGINNING ADDR
|
|
MOV CX,WORD PTR BUFFERS ; (6) GET NUMBER OF ENTRIES
|
|
MOV AX,DS ; (7)GET DATA SEG
|
|
MOV ES,AX ; (7) FIX ES
|
|
CLD ;(6) AUTO INCREMENT
|
|
INITLP: MOV SI,OFFSET INITTBL ; (6) POINT TO STRING TO INITIALIZE
|
|
PUSH CX ; (6) SAVE REP COUNT
|
|
MOV CX,8 ; (6) GET INNER LOOP COUNT
|
|
REP MOVSB ; (6) TRANSFER THE STRING TO TBL
|
|
POP CX ; (6) RESTORE COUNT
|
|
LOOP INITLP ; (6) AND FINISH TABLE INITIALIZING
|
|
MOV WORD PTR [DI],-1 ; (6) DEPOSIT A -1 TO INDICATE END
|
|
MOV BX,GAMESEG ;
|
|
MOV ES,BX ; (6) SET THE EXTRA SEG TO GAMESEG
|
|
POP CX ; RESTORES
|
|
POP BX
|
|
POP AX
|
|
POP DI
|
|
POP SI
|
|
RET
|
|
TBLINI ENDP
|
|
|
|
PUBLIC GAMOPEN
|
|
; THIS PROCEDURE OPENS THE GAME FILE AFTER CLOSING ALL FILES.
|
|
; IF THE GAME FILE IS NOT ON THE DISK, IT PROMPTS FOR REINSERTION
|
|
GAMOPEN PROC
|
|
PUSH DX
|
|
MOV DL,DEFDRV ; (7o) GET DRIVE WHERE GAME IS
|
|
MOV AH,CSELDSK ; (7o) TO MAKE OPEN WIN
|
|
INT 21H ; (7o) DO IT
|
|
MOV AH,CFCLOSZ ; (7s) TRY CLOSING INSTEAD OF RESET
|
|
MOV BX,GAMHNDL ; (7s) OF THE GAME FILE
|
|
INT 21H ; (7o) TO MAKE SURE THIS WINS
|
|
GOPEN0: MOV AH,CFOPENZ ; (6) ASCIZ STRINGS
|
|
MOV AL,0 ; (6) OPEN FOR READING
|
|
MOV DX,OFFSET GAMFILE ; (7o) OPEN THE FILE AGAIN
|
|
INT 21H
|
|
JNC GOPEN1 ; (7o) IF SUCCESS, CONTINUE
|
|
PRINT SAV3 ; (7o) OTHERWISE PROMPT
|
|
CALL MCHRI ; (7o) AND WAIT FOR A CHARACTER
|
|
JMP GOPEN0 ; (7o) AND LOOP
|
|
GOPEN1: MOV GAMHNDL,AX ; (7o) SAVE GAME HANDLE
|
|
MOV DL,CURDRV ; (7v) RESTORE SAVE DRIVE
|
|
MOV AH,CSELDSK ; (7v) SO THAT WE ARE NOT CONFUSED
|
|
INT 21H ; (7v) THANKS MAX
|
|
POP DX
|
|
RET
|
|
GAMOPEN ENDP
|
|
|
|
; GIVEN SOURCE PTR IN DS:AX, AND A DEST PTR IN ES:DI, CHK SEARCHES
|
|
; FOR THE DX CHARACTERS OF THE STRING POINTED TO BY DS:AX IN THE
|
|
; FIRST (CX) BYTES OF THE STRING POINTED TO BY ES:DI
|
|
PUBLIC CHK
|
|
CHK PROC
|
|
CLD ; (7) CLEAR THE DIRECTION FLAG
|
|
PUSH SI ; (7) SAVE THIS
|
|
PUSH DX ; (7) SAVE THIS FOR RETRIES
|
|
MOV BP,SP ; (7) GET A FRAME POINTER
|
|
MOV SI,AX ; (7) SET UP FIRST OFFSET
|
|
LUP: CMP BYTE PTR [SI],'$' ; (7) END CHAR
|
|
JE MATCH ; (7) REACHING END==MATCH
|
|
CMPSB ; (7) COMPARE TWO BYTES
|
|
JNE RESET ; (7) RESET SOURCE IF MISMATCH
|
|
DEC DX
|
|
LOOP LUP ; (7) DECREMENT COUNTER AND TRY AGAIN
|
|
JMP RTFAIL ; (7) OUT OF CHARS, FAILED
|
|
RESET: MOV SI,AX ; (7) MOVE SOURCE PTR BACK INTO SI
|
|
MOV DX,[BP] ; (7) RESTORE NUMBER OF BYTES IN STR
|
|
LOOP LUP ; (7) TRY AGAIN
|
|
RTFAIL: STC ; (7) FAIL BY RETURNING CARRY SET
|
|
POP DX
|
|
POP SI ; (7) RESTORE SI
|
|
RET
|
|
MATCH: TEST DX,DX ; (7) MATCH OF ENTIRE STRING
|
|
JNZ RTFAIL
|
|
CLC ; (7) GOT A MATCH, RETURN CARRY CLEAR
|
|
POP DX
|
|
POP SI ; (7) RESTORE SI
|
|
RET
|
|
CHK ENDP
|
|
|
|
; THIS ROUTINE CHECKS THE COPY PROTECTION
|
|
CHKCOP PROC
|
|
CLC ; FOR NOW, EVERYTHING WORKS
|
|
RET
|
|
CHKCOP ENDP
|
|
|
|
; THIS ROUTINE SETS SOME VARIABLES ACCORDING TO THE CMD LINE
|
|
; CURRENTLY THE 6 /PARAMETERS ARE SUPPORTED. THE FIRST THREE,
|
|
; /P INITIALIZE PRINTER THROUGH INT 17
|
|
; /M MONOCHROME
|
|
; /C COLOR
|
|
; /W WINDOWED SCROLLING
|
|
; /K<n> AMOUNT OF MEMORY IN K
|
|
; ARE INTENDED FOR THE USER. A FOURTH WILL NOT BE DOCUMENTED IS
|
|
; /G<gamefile.ext> WHICH WILL TEMPORARILY PATCH THE ZIP TO RUN THE
|
|
; GAME SPECIFIED.
|
|
;
|
|
PUBLIC SCANCMD,SCAN,SCAN0,SCAN1,SCAN2,SCAN3,SCAN4
|
|
PUBLIC SCAN5,SCAN6,SCAN7,SCAN8
|
|
SCANCMD PROC
|
|
CLD ; (7) AUTO INCREMENT
|
|
MOV SI,80H ; (7) GET # OF BYTES
|
|
LODSB ; (7) INTO AL
|
|
TEST AL,AL ; (7) ANY?
|
|
JNZ SCAN1
|
|
SCAN0: RET ; (7) NONE THERE
|
|
SCAN1: DEC AL ; (7) CARRIAGE RETURN DOESN'T COUNT
|
|
XOR DX,DX ; (7) ZERO THIS
|
|
MOV DL,AL ; (7) SAVE NUMBER OF BYTES
|
|
ADD DX,82H ; (7) ADDR OF LAST BYTE+1 ON LINE
|
|
INC SI ; (7) SKIP INITIAL SPACE
|
|
SCAN: CMP SI,DX ; (7) END OF CMD LINE?
|
|
LODSB ; (7) GET A DELIMITER
|
|
JZ SCAN0 ; (7) YEP, RETURN
|
|
CMP AL,'/' ; (7) WAS IT THE DELIMITER
|
|
JNZ SCAN ; (7) GET NEXT VALID CHAR
|
|
LODSB ; (7) GOT DELIMITER, GET BYTE
|
|
AND AL,5FH ; (7) UPPERCASIFY
|
|
CMP AL,'M' ; (7) DO THEY WANT MONOCHROME
|
|
JNZ SCAN2 ; (7) NOPE, TRY NEXT
|
|
OR CMDLIN,1 ; (7) SET FLAG IN CMDLIN VARIABLE
|
|
JMP SCAN
|
|
SCAN2: CMP AL,'W' ; (7) WINDOWED SCROLLING?
|
|
JNZ SCAN3
|
|
MOV SCROLL,0 ; (7) TURN ON SCROLLING
|
|
OR CMDLIN,8 ; (7) TURN ON 8 BIT
|
|
JMP SCAN
|
|
SCAN3: CMP AL,'G' ; (7) GAME FILE NAME?
|
|
JNZ SCAN5 ; (7) NOPE, CONTINUE ON...
|
|
MOV DI,OFFSET GAMFILE ; (7) MAKE THIS THE GAME
|
|
SCAN4: MOVSB ; (7) TRANSFER A BYTE
|
|
CMP DX,SI ; (7) THE END?
|
|
JNZ SCAN4
|
|
MOV AL,0 ; (7) DROP IN A NULL
|
|
STOSB ; (7) TO END THE STRING
|
|
RET
|
|
SCAN5: CMP AL,'C' ; (7) DO THEY WANT COLOR
|
|
JNZ SCAN6 ; (7) NOPE, TRY NEXT
|
|
OR CMDLIN,2 ; (7) SET FLAG IN CMDLIN VARIABLE
|
|
JMP SCAN
|
|
SCAN6: CMP AL,'K' ; (7) SET MEMORY SIZE
|
|
JNZ SCAN9 ; (7) NOPE LOOK ONWARD
|
|
MOV BX,0 ; (7) ZERO THIS
|
|
SCAN7: CMP DX,SI ; (7) THE END?
|
|
JNZ SCAN8 ; (7) NOPE
|
|
SCAN7A: OR CMDLIN,4 ; (7) TURN ON MEMORY SET BIT
|
|
MOV CL,6 ; (7w) CONVERT K TO PARAGRAPHS
|
|
SHL BX,CL ; (7) I THINK???
|
|
MOV MEMORY,BX ; (7) SAVE AMOUNT OF K SPECIFIED IN 512 BLKS
|
|
DEC SI ; (7v) BACKUP ONE
|
|
JMP SCAN
|
|
SCAN8: LODSB ; (7) GET FIRST BYTE
|
|
CMP AL,0D ; (7v) CR MEANS END OF STRING
|
|
JZ SCAN7A ; (7v) SO QUIT HERE
|
|
CMP AL,' ' ; (7v) SPACE MEANS NEXT STRING
|
|
JZ SCAN7A ; (7v) SO QUIT
|
|
CMP AL,'/' ; (7v) SLASH MEANS NEXT DELIMITER
|
|
JZ SCAN7A ; (7v) SO QUIT
|
|
XOR AH,AH ; (7) ZERO THIS
|
|
AAA ; (7) SCALE THE NUMBER DOWN
|
|
XCHG AX,BX ; (7) GET NUMBER (BX) INTO AC
|
|
PUSH DX ; (7) SAVE ENDPTR
|
|
MUL RADIX ; (7) MULTIPLY NUMBER BY TEN
|
|
ADD BX,AX ; (7) ADD IN NEW NUMBER
|
|
POP DX ; (7) RESTORE END PTR
|
|
JMP SCAN7
|
|
SCAN9: CMP AL,'P' ; (7w) DO WE NEED TO INITIALIZE THE PRINTER
|
|
JZ SCAN10 ; (7w) YES, DO IT
|
|
JMP SCAN
|
|
SCAN10: PUSH DX ; (7w) SAVE THIS
|
|
MOV DX,0 ; (7w) INITIALIZE FIRST PRINTER
|
|
MOV AH,1 ; (7w) FUNCTION NUMBER FOR INIT
|
|
INT 17H ; (7w) ASSUME IBM PC BECAUSE THEY USED /P
|
|
POP DX ; (7w) RESTORE END POINTER
|
|
JMP SCAN ; (7w) NOW GET BACK TO WORK
|
|
SCANCMD ENDP
|