mirror of
https://github.com/erkyrath/infocom-zcode-terps.git
synced 2026-02-21 06:45:49 +00:00
938 lines
24 KiB
Plaintext
938 lines
24 KiB
Plaintext
SUBTTL READIO - I/O OPERATIONS
|
|
PAGE +
|
|
|
|
PUBLIC GETLIN
|
|
GETLIN PROC
|
|
MOV AX,CX ; (A0) AX HAS NUMBER OF ARGS TO READ
|
|
PUSH BX
|
|
MOV SCRHLD,1 ; (7n) HOLD SCRIPTING
|
|
PUSH SI
|
|
MOV CL,ES:[SI]
|
|
MOV BX,OFFSET INBUF
|
|
MOV BYTE PTR [BX],CL
|
|
CMP CL,MAXLIN ; (7r) DON'T EXCEED BUFFER LENGTH
|
|
JBE GTLN0 ; (7r) FIX IF ABOVE
|
|
MOV BYTE PTR [BX],MAXLIN ; (7r) WITH OUR NEW MAXIMUM
|
|
GTLN0: MOV DX,BX
|
|
CMP AX,2 ; (A0) TIME OUT VERSION?
|
|
JBE GTLNA ; (A0) TWO TABLES, GET NORMALLY
|
|
MOV BX,OFFSET ARGBLK ; (A0) GET ADDR OF ARGBLK
|
|
MOV AX,[BX+4] ; (A0) GET THE DELAY COUNT
|
|
MOV BX,[BX+6] ; (A0) AND THE TIMEOUT FUNCTION
|
|
PUSH SI ; (A0) SI IS GETTING WRECKED???
|
|
CALL LININP ; (A0) CALL TIMEOUT INPUT ROUTINE
|
|
POP SI ; (A0) SO I PRESERVED IT
|
|
JMP GTLNB ; (A0) SKIP NORMAL CALL
|
|
|
|
|
|
;GTLNA: MOV AH,CRDLIN
|
|
; INT 21H
|
|
|
|
GTLNA: CALL RDLIN ;(A9)
|
|
|
|
GTLNB: TEST SCROLL,1 ;(7) WHAT KIND OF SCROLLING
|
|
JNZ GTLN1
|
|
MOV AH,SCROLLUP ;(7) USE A VIDEO BIOS SCROLL
|
|
MOV AL,1 ;(7) ONLY 1 LINE
|
|
MOV CX,TOPLIN ;(7) ALWAYS FREEZE TOP LINE
|
|
MOV DH,SLPP ;(7) GET SCREEN LENGTH
|
|
MOV DL,SCPL ;(7) GET THE WIDTH OF THE SCREEN
|
|
DEC DL ; (7v) COORDINATES ARE ZERO BASED
|
|
MOV BH,SCRATR ;(7) GET THE SCREEN ATTRIBUTE
|
|
INT 10H ;(7) CALL THE VIDEO
|
|
JMP GTLN2 ;(7) SKIP LINE FEED OUTPUT
|
|
GTLN1: MOV AH,CCONIO
|
|
MOV DL,10
|
|
INT 21H
|
|
GTLN2: POP DX
|
|
MOV BX,OFFSET INBUF
|
|
MOV CL,BYTE PTR [BX+1]
|
|
SUB CH,CH
|
|
INC BX
|
|
CMP CL,0
|
|
JE GETLEM
|
|
GETLLP: INC SI
|
|
INC BX
|
|
MOV AL,BYTE PTR [BX]
|
|
CMP AL,"A"
|
|
JL GETLLC
|
|
CMP AL,"Z"
|
|
JG GETLLC
|
|
ADD AL,32
|
|
GETLLC: MOV ES:[SI],AL
|
|
LOOP GETLLP
|
|
GETLEM: INC SI
|
|
SUB AL,AL
|
|
MOV ES:[SI],AL
|
|
MOV SCRHLD,0 ; (7n) TURN OFF SCRIPT HOLD
|
|
POP BX
|
|
RET
|
|
GETLIN ENDP
|
|
|
|
PUBLIC PRTOUT
|
|
PRTOUT PROC
|
|
PUSH AX
|
|
PUSH BX
|
|
PUSH CX
|
|
PUSH DX ; (7) SAVE THIS, USING STD PRT
|
|
TEST WORD PTR ES:[PFLAGS],SCRPTBT ; (A17) SCRIPTING ON?
|
|
JZ POUT2 ; (A17) NOPE
|
|
TEST CMDLIN,16 ; (7n) DO WE WANT IBM PRINTER
|
|
JZ POUT1 ; (7n) GUESS NOT
|
|
POUT0: MOV AH,0 ; (7) FUNCTION TO PRINT
|
|
MOV DX,0 ; (7) TO THE FIRST PRINTER
|
|
INT 17H ; (7) TRY IT
|
|
TEST AH,RDYBIT ; (7) TIME OUT?
|
|
JZ POUT2 ; (7) WORKED, RETURN
|
|
CALL PRNRDY ; (7)
|
|
JC POUT2
|
|
JMP POUT0 ; (7) RETRY
|
|
POUT1: MOV DL,AL ; (7n) GET CHARACTER TO PRINT
|
|
MOV AH,CPROUT ; (7n) PRINT IT
|
|
INT 21H
|
|
POUT2: POP DX ; (7n) FORGET THIS AND BREAK...
|
|
POP CX
|
|
POP BX
|
|
POP AX
|
|
RET
|
|
PRTOUT ENDP
|
|
|
|
PUBLIC PRNRDY
|
|
PRNRDY PROC
|
|
OR WORD PTR ES:[PFLAGS],REFRESH ;(E0) REFRESH THE STATUS LINE
|
|
PUSH AX
|
|
MOV SCRHLD,1 ; (7n) HOLD OFF SCRIPTING
|
|
PRINT PRNNRDY ; (7) ASK USER ABOUT ACTION
|
|
RDY1: CALL MCHRI ; (7) GET A RESPONSE
|
|
CALL MTTYO ; (7u) ECHO THE CHARACTER
|
|
AND AL,5FH ; (7) UPPPER CASIFY
|
|
CMP AL,'A' ; (7) SHOULD WE ABORT
|
|
JNZ RDY2 ; (7) ATTEMPTING RETRY
|
|
MOV SCRFLG,0 ; (7) TURN OFF SCRIPTING
|
|
|
|
; (A10) COMMENTED OUT LINE
|
|
; AND ES:[PFLAGS],SCRMSK ; (7) AND IN THE MODE WORD
|
|
|
|
MOV SCRHLD,0 ; (7n) TURN OFF BAN ON SCRIPTING
|
|
STC ; (7) SET CARRY FOR NO RETRY
|
|
PUSHF ; (7) SAVE THESE
|
|
JMP RDY3 ; (7) CR LF ON EXIT
|
|
RDY2: CMP AL,'R' ; (7) RETRY???
|
|
JNZ RDY1 ; (7) WRONG CHARACTER
|
|
CLC ; (7) CLEAR CARRY FOR RETRY
|
|
PUSHF ; (7) SAVE FLAGS
|
|
RDY3: CALL MCRLF ; (7) DO A <CR><LF>
|
|
MOV SCRHLD,0 ; (7n) TURN OFF BAN ON SCRIPTING
|
|
POPF ; (7) RESTORE FLAGS AND
|
|
POP AX ; (7) CHARACTER TO PRINT
|
|
RET
|
|
PRNRDY ENDP
|
|
|
|
SCRCHK PROC
|
|
PUSH AX
|
|
PUSH BX
|
|
PUSH DX
|
|
TEST SCRFLG,1 ; (A11) IS SCRIPTING ENABLED?
|
|
JNZ SCR0L$ ; (7x) ....YES, CONTINUE
|
|
JMP SCREX$ ; (A11)....NO
|
|
|
|
|
|
; MOV SCRFLG,1 ; (7n) TURN ON SCRIPT FLAG
|
|
; CMP SCROLL,0 ; (7) SHOULD WE BE DOING THIS?
|
|
; JNZ SCR0L$ ; (7) NOPE...
|
|
; TEST CMDLIN,16 ; (7n) DID WE REALLY REQUEST IBM
|
|
; JZ SCR0L$
|
|
;SCR_1$: MOV DX,0 ; (7) TRY TO INIT THE PRINTER
|
|
; MOV AH,1
|
|
; INT 17H ; (7) SO THAT WE WILL TIME OUT FAST
|
|
; TEST AH,PRTMSK ; (7) TEST FOR TIME OUT
|
|
; JZ SCR0L$ ; (7) NO PROBLEM, WE'RE FINE
|
|
; CALL PRNRDY ; (7) INFORM USER OF PROBLEM
|
|
; JNC SCR_1$
|
|
; JMP SCRNN$ ; (7) TURN OFF SCRIPTING
|
|
|
|
|
|
SCR0L$: SUB CX,CX
|
|
MOV BP,DX
|
|
INC BP
|
|
SCR1L$: MOV AL,ES:[BP]
|
|
INC BP
|
|
CMP BP,SI
|
|
JLE SCR2L$
|
|
CALL PRTCRL
|
|
JMP SCREX$
|
|
SCR2L$: CALL PRTOUT
|
|
INC CX
|
|
CMP CL,SCPL
|
|
JNE SCR1L$
|
|
CALL PRTCRL
|
|
JC SCREX$
|
|
SUB CX,CX
|
|
JMP SCR1L$
|
|
|
|
SCRNN$: MOV SCRFLG,0
|
|
SCREX$: POP DX
|
|
POP BX
|
|
POP AX
|
|
RET
|
|
SCRCHK ENDP
|
|
|
|
PUBLIC PRTCRL
|
|
PRTCRL PROC
|
|
TEST WORD PTR ES:[PFLAGS],SCRPTBT ;(A18) DON'T SCRIPT READ
|
|
JNZ PRTC1
|
|
RET
|
|
PRTC1: MOV AL,13 ;FINISH UP WITH CRLF
|
|
CALL PRTOUT
|
|
MOV AL,10
|
|
CALL PRTOUT
|
|
; OR WORD PTR ES:[PFLAGS],REFRESH ; (A17) SET THE REFRESH BIT
|
|
RET
|
|
PRTCRL ENDP
|
|
|
|
;READ (A LINE OF INPUT & PARSE IT, LINE BUF IN ES:AX,
|
|
;RETURN BUF IN ES:BX)
|
|
PUBLIC OPREAD,ORD1$,ORDNS$,ORD8$,ORD9$,ORD10$,ORD1A$,ORD11$,ORD12$
|
|
; PUBLIC ORD13$,ORD14$,ORD15$,ORD16$,ORD17$,ORD18$,ORD19$,ORD20$
|
|
; PUBLIC ORD21$,ORD22$,ORD23$
|
|
OPREAD PROC
|
|
NOP ; (A0) GET ARGS IN ARGBLK
|
|
MOV CX,AX ; (A0) GET # OF ARGS
|
|
MOV BX,OFFSET ARGBLK
|
|
MOV AX,[BX] ; (A0) GET FIRST TWO ARGS INTO AX & BX
|
|
MOV BX,[BX+2]
|
|
PUSH AX ;SAVE LINE BUF
|
|
MOV BP,CHRPTR ;NEXT CHARACTER POSITION
|
|
MOV BYTE PTR DS:[BP],80H ;(6)DON'T END OUTPUT, IF ANY, WITH CRLF
|
|
ORD1$: PRINT OUTBUF ;FORCE OUT ANY QUEUED TEXT
|
|
MOV CHRPTR,OFFSET OUTBUF ;RESET CHARACTER POINTER
|
|
POP SI ;INPUT BUFFER POINTER
|
|
MOV MORLIN,0 ;RE-INITIALIZE MORE COUNT FROM HERE
|
|
MOV CHRCNT,BUFLEN ; (A15) RE-INITIALIZE THE CHAR COUNTER
|
|
CALL GETLIN ;GET SOME CHARACTERS
|
|
|
|
CALL SCRCHK ;PRINT THE BUFFER IF SCRIPTING IS ON
|
|
|
|
ORDNS$: PUSH DI
|
|
MOV RDBOS,DX ;INITIALIZE RDBOS
|
|
MOV RDEOS,SI ;AND RDEOS
|
|
MOV RDRET,BX ;STORE RET POINTER
|
|
MOV RDNWDS,0 ;NO WORDS SO FAR
|
|
INC DX ;SKIP LENGTH BYTE
|
|
MOV DI,BX ;THIS WILL BE WORD ENTRY POINTER
|
|
INC DI ;SKIP MAX WORDS & NWORDS BYTES
|
|
INC DI
|
|
ORD8$: MOV CX,OFFSET RDWSTR;HERE FOR NEXT WORD, POINT TO WORD STRING
|
|
MOV BX,DX ;AND SAVE BEGINNING OF WORD POINTER
|
|
ORD9$: CMP DX,RDEOS ;END OF STRING?
|
|
JNE ORD10$ ;NO
|
|
CMP CX,OFFSET RDWSTR;YES, WAS A WORD FOUND?
|
|
JNE ORD15$ ;YES, WE STILL HAVE TO LOOKUP WORD
|
|
JMP ORD23$ ;NO, WE'RE DONE
|
|
ORD10$: MOV BP,DX ;GET NEXT CHARACTER FROM BUFFER
|
|
MOV AL,ES:[BP]
|
|
CMP AL,"A"
|
|
JL ORD1A$
|
|
CMP AL,"Z"
|
|
JG ORD1A$
|
|
ADD AL,32 ;LOWERCASIFY ALPHABETICS
|
|
ORD1A$: INC DX
|
|
MOV SI,OFFSET RBRKS ;LIST OF READ BREAK CHARACTERS
|
|
ORD11$: INC SI
|
|
CMP AL,[SI-1] ;SEARCH LIST FOR THIS ONE
|
|
JE ORD12$ ;FOUND IT
|
|
CMP BYTE PTR [SI],0 ;END OF LIST?
|
|
JNE ORD11$ ;NO, CONTINUE SEARCH
|
|
CMP CX,OFFSET RDWSTR[9] ;YES, NOT A BREAK, WORD STRING FULL?
|
|
JE ORD9$ ;YES, LOOP UNTIL END OF WORD
|
|
MOV BP,CX ;NO, TACK THIS CHARACTER ONTO STRING
|
|
MOV DS:[BP],AL
|
|
INC CX
|
|
JMP ORD9$ ;AND LOOP
|
|
ORD12$: CMP CX,OFFSET RDWSTR;WORD READ BEFORE THIS BREAK?
|
|
JNE ORD14$ ;YES
|
|
CMP SI,ESIBKS ;NO, BUT IS IT A SELF-INSERTING BREAK?
|
|
JBE ORD13$ ;YES
|
|
INC BX ;NO, UPDATE BEGINNING OF WORD TO SKIP BREAK
|
|
JMP ORD9$ ;AND RETURN TO LOOP TO FIND A WORD
|
|
ORD13$: MOV BP,CX ;STORE THE BREAK IN WORD STRING
|
|
MOV DS:[BP],AL
|
|
INC CX
|
|
JMP ORD15$ ;AND GO FOR THE WORD
|
|
ORD14$: DEC DX ;UNREAD TERMINATING BREAK IN CASE IT WAS SI
|
|
ORD15$: INC RDNWDS ;INCREMENT FOUND WORD COUNT
|
|
MOV BP,BX ;GREATER THAN MAX ALLOWED?
|
|
MOV BX,RDRET
|
|
MOV BL,ES:[BX]
|
|
CMP BL,59 ; (7w) GAME FIX
|
|
JBE ORD15A ; (7w) FIX NUMBER OF TOKENS ALLOWED
|
|
MOV BL,59 ; (7w) OTHERWISE WE OVERRUN A TABLE
|
|
ORD15A: CMP RDNWDS,BL
|
|
MOV BX,BP
|
|
JLE ORD16$ ;NO
|
|
PRINT ERR2 ;YES, INFORM LOSER
|
|
MOV AX,BX ;BEGINNING OF THIS WORD
|
|
MOV BP,RDEOS ;SAVE BYTE AFTER EOS
|
|
MOV BL,ES:[BP]
|
|
MOV BYTE PTR ES:[BP],0 ; ZERO IT TO MAKE STRING ASCIZ
|
|
PUSH BX ; (7w) SAVE THIS ADDRESS
|
|
MOV BX,DS ; (7w) FIGURE WHERE STRING IS IN DS
|
|
NEG BX ; (7w) SUBTRACT DS FROM ES
|
|
ADD BX,GAMESEG ; (7w) BX HAS PARAGRAPHS OF DIFFERENCE
|
|
MOV CL,4 ; (7w) CONVERT TO AN OFFSET
|
|
SHL BX,CL ; (7w) TO ADD IN WITH AX
|
|
ADD AX,BX ; (7w) NOW DS:AX SHOULD EQUAL PREV ES:AX
|
|
POP BX ; (7w) RESTORE BX
|
|
CALL MPRNT ;PRINT IT
|
|
MOV ES:[BP],BL ; AND RESTORE OLD BYTE
|
|
DEC RDNWDS ;REMEMBER THAT WE FLUSHED THIS WORD
|
|
JMP ORD23$ ;AND WE'RE DONE
|
|
ORD16$: MOV AX,BX ;CALCULATE NUMBER OF CHARACTERS IN WORD
|
|
NEG AX
|
|
ADD AX,DX
|
|
MOV ES:[DI+2],AL ;(6)SAVE THE NUMBER IN RET TABLE
|
|
SUB BX,RDBOS ;BYTE OFFSET FOR BEGINNING OF WORD
|
|
MOV ES:[DI+3],BL ;(6)STORE IT, TOO
|
|
MOV BP,CX ;MAKE WORD STRING ASCIZ
|
|
MOV BYTE PTR DS:[BP],0 ;(6) REMOVED SEG OVERRIDE (DS)
|
|
MOV AX,OFFSET RDWSTR;POINT TO IT
|
|
CALL ZWORD ;AND CONVERT TO (2-WORD) ZWORD
|
|
MOV ZTHIRD,CX ; (A0) SAVE THIRD WORD
|
|
PUSH DX ;SAVE CHAR & WORD ENTRY POINTERS
|
|
PUSH DI
|
|
MOV DI,AX ;FIRST ZWORD WORD
|
|
MOV SI,VWORDS ;NUMBER OF VOCABULARY WORDS
|
|
MOV AX,SI
|
|
DEC AX ;WE WANT TO POINT TO LAST WORD
|
|
MUL VWLEN ;MULTIPLY BY WORD LENGTH IN BYTES
|
|
ADD AX,VOCBEG ;ADD POINTER TO BEGINNING TO FIND LAST WORD
|
|
MOV CX,AX ;POINTER TO LAST WORD
|
|
MOV DX,DI ;FIRST ZWORD WORD
|
|
MOV DI,BX ;SECOND ZWORD WORD
|
|
MOV BX,VWLEN ;CALCULATE INITIAL OFFSET FOR BINARY SEARCH
|
|
SAR SI,1
|
|
ORD17$: SAL BX,1
|
|
SAR SI,1
|
|
CMP SI,0
|
|
JNE ORD17$
|
|
MOV SI,VOCBEG ;BEGINNING OF WORD TABLE
|
|
ADD SI,BX ;ADD CURRENT OFFSET(HALF OF POWER-OF-2 TABLE)
|
|
PUSH AX ;SAVE
|
|
MOV AX,VWLEN ;AVOID FENCEPOST BUG FOR EXACT POWER-OF-2 TBL
|
|
SUB SI,AX
|
|
POP AX ;RESTORE
|
|
ORD18$: SAR BX,1 ;NEXT OFFSET WILL BE HALF OF PREVIOUS ONE
|
|
GTAWRD A,[SI] ;GET FIRST HALF OF CURRENT ZWORD
|
|
CMP DX,AX ;COMPARE DESIRED ONE TO IT
|
|
JA ORD19$ ;GREATER, WE'LL HAVE TO MOVE UP
|
|
JB ORD20$ ;LESS, WE'LL HAVE TO MOVE DOWN
|
|
MOV BP,SI ;SAME, GET SECOND HALF
|
|
ADD BP,2 ; (A0) LOOK AT SECOND WORD
|
|
GTAWRD A,[BP]
|
|
CMP DI,AX ;COMPARE DESIRED WORD WITH IT
|
|
JA ORD19$ ;GREATER, WE'LL HAVE TO MOVE UP
|
|
JB ORD20$ ;LESS, WE'LL HAVE TO MOVE DOWN
|
|
MOV BP,SI ; (A0) SAME, GET SECOND HALF
|
|
ADD BP,4 ; (A0) LOOK AT THIRD WORD
|
|
GTAWRD A,[BP] ; (A0)
|
|
CMP ZTHIRD,AX ; (A0) COMPARE DESIRED WORD WITH IT
|
|
JA ORD19$ ; (A0) GREATER, WE'LL HAVE TO MOVE UP
|
|
JB ORD20$ ; (A0) LESS, WE'LL HAVE TO MOVE DOWN
|
|
JMP ORD22$ ;SAME, WE'VE FOUND IT, RETURN IT
|
|
ORD19$: ADD SI,BX ;TO MOVE UP, ADD CURRENT OFFSET
|
|
jc ORD24$ ; overflowed a segment, set back to end
|
|
CMP SI,CX ;HAVE WE MOVED PAST END OF TABLE?
|
|
JBE ORD21$ ;NO
|
|
ORD24$: MOV SI,CX ;YES, POINT TO END OF TABLE INSTEAD
|
|
JMP ORD21$
|
|
ORD20$: SUB SI,BX ;TO MOVE DOWN, SIMPLY SUBTRACT OFFSET
|
|
ORD21$: CMP BX,VWLEN ;IS OFFSET RESOLUTION BELOW ONE WORD?
|
|
JGE ORD18$ ;NO, CONTINUE LOOP
|
|
SUB SI,SI ;YES, WORD NOT FOUND, RETURN ZERO
|
|
ORD22$: POP DI ;RESTORE WORD ENTRY POINTER
|
|
MOV DX,SI ;POINTER TO WORD FOUND
|
|
XCHG DH,DL
|
|
MOV ES:[DI],DX ;(6) STORE IT
|
|
POP DX ;RESTORE CHAR POINTER
|
|
ADD DI,4 ;UPDATE POINTER FOR NEXT WORD ENTRY
|
|
JMP ORD8$ ;GO FOR IT
|
|
ORD23$: INC RDRET ;DONE, STORE NUMBER OF WORDS FOUND
|
|
MOV BP,RDRET
|
|
MOVM ES:[BP],RDNWDS,DL ; REMOVED ES OVERRIDE
|
|
POP DI ;RESTORE USER STACK POINTER
|
|
RET ;AND RETURN
|
|
OPREAD ENDP
|
|
|
|
PUBLIC OPBFOUT
|
|
OPBFOUT PROC
|
|
CMP AX,0 ; (A0) WHAT DO WE WANT?
|
|
JNZ BUFFED ; (A0) TURN OFF BUFFERED INPUT
|
|
MOV BUFBIT,0 ; (A0) SET FLAG
|
|
PUSH BX
|
|
MOV BX,CHRPTR ; (A0) LOCATION FOR NEXT CHAR
|
|
MOV BYTE PTR [BX],80H ; (A0) INDICATE END OF STRING
|
|
PRINT OUTBUF ; (A0) FLUSH THE BUFFER
|
|
MOV BX,OFFSET OUTBUF ; (A0) GET BUFFER ADDR
|
|
MOV CHRPTR,BX ; (A0) RESET THE CHRPTR
|
|
POP BX ; (A0) RESTORE BX
|
|
RET
|
|
BUFFED: MOV BUFBIT,1 ; (A0) TURN BUFFERING BACK ON
|
|
RET
|
|
OPBFOUT ENDP
|
|
|
|
PUBLIC OPDIRIN
|
|
OPDIRIN PROC
|
|
RET
|
|
OPDIRIN ENDP
|
|
|
|
;
|
|
; SELECT OR DESELECT A VIRTUAL OUTPUT DEVICE
|
|
;
|
|
|
|
PUBLIC OPDIROU
|
|
OPDIROU PROC
|
|
OR AL,AL ; (A10) ENABLE OR DISABLE A DEVICE
|
|
JNS ODIR0 ; (A10) IF (+) IT'S ENABLE
|
|
JMP ODIR5 ; (A10) IF (-) IT'S DISABLE
|
|
|
|
; {CASE} DEVICE ENABLE HANDLER
|
|
ODIR0: CMP AL,1 ; (A10) IS IT THE SCREEN?
|
|
JNE ODIR1 ; (A10) NOPE
|
|
|
|
; {SUBCASE} SCREEN HANDLER
|
|
MOV VIDFLG,1 ; (A10) TURN SCREEN ON
|
|
RET
|
|
|
|
ODIR1: CMP AL,2 ; (A10) IS IT THE SCRIPT DEVICE?
|
|
JNE ODIR2 ; (A10) NOPE
|
|
|
|
; {SUBCASE} SCRIPT HANDLER
|
|
PUSH AX
|
|
PUSH BX
|
|
PUSH DX
|
|
TEST SCRFLG,1 ; (A11) IS SCRIPTING ALREADY ENABLED?
|
|
JNZ ODIR1B ; (A11) ....YES
|
|
;
|
|
OR WORD PTR ES:[PFLAGS],SCRPTBT ;(A18) TURN ON SCRIPT FOR HI
|
|
MOV SCRFLG,1 ; (A18) TURN ON ZIP FLAG
|
|
|
|
TEST CMDLIN,16 ; (A11) DID WE REALLY REQUEST IBM?
|
|
JZ ODIR1B ; (A11) ....YES
|
|
|
|
; INITIALIZE PRINTER
|
|
ODIR1A: MOV DX,0 ; TRY TO INIT THE PRINTER
|
|
MOV AH,1
|
|
INT 17H ; SO THAT WE WILL TIME OUT FAST
|
|
TEST AH,PRTMSK ; TEST FOR TIME OUT
|
|
JZ ODIR1B ; NO PROBLEM, WE'RE FINE
|
|
CALL PRNRDY ; INFORM USER OF PROBLEM
|
|
JNC ODIR1A
|
|
|
|
; THE PRINTER WOULDN'T INITIALIZE
|
|
XOR AH,AH ; (A13) DISABLE SCRIPTING
|
|
MOV SCRFLG,AH ; (A13)
|
|
OR AH,STSBIT ; (A13) TURN ON STATUS LINE REFRESH BIT
|
|
XOR AL,AL ; (A13)
|
|
XCHG AH,AL ; (A18) BYTE SWAP
|
|
MOV WORD PTR ES:[PFLAGS],AX ; (A13) LET HIGH LEVEL KNOW
|
|
|
|
ODIR1B: POP DX
|
|
POP BX
|
|
POP AX
|
|
RET
|
|
|
|
ODIR2: CMP AL,3 ; (A10) IS IT THE TABLE DEVICE?
|
|
JNE ODIR3 ; (A10) NOPE
|
|
|
|
; {SUBCASE} TABLE HANDLER
|
|
MOV AL,BUFBIT ; (A0) GET STATE OF BUFBIT
|
|
MOV PREVBUF,AL ; (A0) AND SAVE IT FOR LATER
|
|
; (B0) Dirout should not flush the buffer
|
|
; MOV AX,0 ; (A0) USE TO CALL BUFOUT
|
|
; CALL OPBFOUT ; (A0) TURN OFF BUFBIT AND FLUSH
|
|
MOV BUFBIT,0 ; (B0) TURN OFF BUFBIT
|
|
MOV RDIR,1 ; (A0) STORE REDIRECTION FLAG
|
|
MOV RTABLE,BX ; (A0) ZEROTH ELEMENT OF TABLE
|
|
MOV RDIROUT,0 ; (A0) ZERO THE NUMBER OF BYTES READ
|
|
ADD BX,2 ; (A0) THIS IS TABLE+2
|
|
MOV RTABLE2,BX ; (A0) AND TABLE LOCATION (IF INT IS <> 1)
|
|
RET
|
|
|
|
ODIR3: CMP AL,4 ; (A10) IS IT A FILE?
|
|
JNE ODIR4 ; (A10) NOPE, DON'T HANDLE IT
|
|
|
|
; {SUBCASE} FILE HANDLER
|
|
; NOT IMPLIMENTED
|
|
ODIR4: RET
|
|
|
|
;
|
|
|
|
; {CASE} DEVICE DISABLE HANDLER
|
|
ODIR5: CMP AL,0FFH ; (A10) IS IT THE SCREEN?
|
|
JNE ODIR6 ; (A10) NOPE
|
|
|
|
; {SUBCASE} SCREEN HANDLER
|
|
MOV VIDFLG,0 ; (A10) TURN SCREEN OFF
|
|
RET
|
|
|
|
ODIR6: CMP AL,0FEH ; (A10) IS IT THE SCRIPT DEVICE?
|
|
JNE ODIR7 ; (A10) NOPE
|
|
|
|
; {SUBCASE} SCRIPT HANDLER
|
|
MOV SCRFLG,0 ; (A18) TURN OFF SCRIPTING
|
|
AND WORD PTR ES:[PFLAGS],SCRMSK
|
|
; XOR AH,AH ; (A13) DISABLE SCRIPTING
|
|
; MOV SCRFLG,AH ; (A13)
|
|
; OR AH,STSBIT ; (A13) TURN ON STATUS LINE REFRESH T
|
|
; XOR AL,AL ; (A13)
|
|
; MOV ES:[PFLAGS],AX ; (A13) LET HIGH LEVEL KNOW
|
|
RET
|
|
|
|
ODIR7: CMP AL,0FDH ; (A10) IS IT THE TABLE DEVICE?
|
|
JNE ODIR8 ; (A10) NOPE
|
|
|
|
; {SUBCASE} TABLE HANDLER
|
|
CMP RDIR,0 ; (C0) IF ALREADY OFF
|
|
JE OUT7 ; (C0) LEAVE AS IS
|
|
|
|
MOV AL,PREVBUF ; (A0) GET PREVIOUS STATE OF BUFFER
|
|
MOV BUFBIT,AL ; (A0) AND RESTORE THAT STATE
|
|
MOV RDIR,0 ; (A0) AND RESTORE REDIRECTION TO SCREEN
|
|
MOV AX,RDIROUT ; (A0) GET NUMBER OF CHARS WRITTEN
|
|
MOV BX,RTABLE ; (A0) GET ADDR OF ZEROTH ELEMENT
|
|
PTAWRD ES:[BX],A ; (A0) PUT THE WORD INTO THE TABLE
|
|
MOV BX,RTABLE2 ; (A18) GET FIRST ELEMENT
|
|
MOV BYTE PTR ES:[BX],0 ; (A18) DROP IN A NULL
|
|
OUT7: RET ; (C0)
|
|
|
|
ODIR8: CMP AL,0FCH ; (A10) IS IT A FILE?
|
|
JNE ODIR9 ; (A10) NOPE, DON'T HANDLE IT
|
|
|
|
; {SUBCASE} FILE HANDLER
|
|
; NOT IMPLIMENTED
|
|
ODIR9: RET
|
|
OPDIROU ENDP
|
|
|
|
|
|
SUBTTL OPINPUT
|
|
PAGE
|
|
|
|
; -------
|
|
; OPINPUT
|
|
; -------
|
|
|
|
;
|
|
; PURPOSE: THIS ROUTINE IS USED TO PERFORM A TIMED CHARACTER REQUEST
|
|
;
|
|
; IF [ARG1] = 1, THEN THIS IS A TIMED INPUT KEYBOARD REQUEST
|
|
; AND THE TIME LIMIT IS PROVIDED IN [ARG2].
|
|
;
|
|
; IF A KEY IS DETECTED BEFORE TIMEOUT, THEN WE RETURN THE
|
|
; CHARACTER VIA PUTBYTE.
|
|
;
|
|
;IF A FUNCTION IS PROVIDED [ARG3] IT IS INTERNALLY CALLED AFTER
|
|
; TIMEOUT. IF THE VALUE RETURNED BY THE FUNCTION = 0, THEN
|
|
; WE KEEP LOOPING.
|
|
;
|
|
; IF A TIMEOUT OCCURS AND WE HAVE NO FUNCTION TO CALL, OR THE
|
|
; VALUE RETURNED FROM THE INTERNAL FUNCTION CALL NE. 0, THEN
|
|
; WE RETURN A "0" VIA RET0.
|
|
;
|
|
; INPUTS: [NARGS],[ARG1],[ARG2]opt,[ARG3]opt
|
|
;
|
|
; OUTPUTS: EITHER A ASCII CHAR RETURNED VIA PUTBYTE
|
|
; OR "0" VIA RET0
|
|
;
|
|
; REGISTERS DESTROYED: AX,DX
|
|
;
|
|
; EXTERNAL REFERENCES: INCALL
|
|
;
|
|
PUBLIC OPINPUT,ZTIMLP,NOZFCN,ZIN
|
|
OPINPUT PROC
|
|
NOP ; (A0) GET ARGS IN ARGBLK
|
|
PUSH BX ;(A0) SAVE REGISTERS
|
|
PUSH CX
|
|
|
|
MOV MORLIN,0 ; (A8) RESET THIS VAR
|
|
MOV CHRCNT,BUFLEN ; (A15) RESET INPUT CHAR COUNT
|
|
MOV BX,ARGBLK ; (A0) GET ARG1
|
|
CMP BX,1 ; (A0) KEYBOARD?
|
|
JNE NOZFCN ;....NO INVALID REQUEST
|
|
|
|
CMP AX,3 ;(A0) IS THIS A TIMED INPUT
|
|
JB ZIN ;(A0) ....NO
|
|
|
|
;
|
|
; TIMED INPUT
|
|
;
|
|
|
|
ZTIMLP: MOV AX,ARGBLK[2] ; (A0) GET DELAY COUNT
|
|
IDIV RADIX
|
|
MOV DLYCNT,AX
|
|
MOV BX,ARGBLK[4] ; (A0) GET FUNCTION ADDR
|
|
|
|
CALL TIMLP1 ; (A0) GET A CHAR [+ TIMEOUT]
|
|
JNC ZIN ; (A0) GET THE CHAR READY
|
|
TEST AL,AL ; (A0) WHAT DID INCALL RETURN
|
|
JZ ZIN ; (A0) A ZERO MEANS CONTINUE ANYWAY
|
|
|
|
NOZFCN: POP CX ; (A0) RESTORE REGISTERS
|
|
POP BX
|
|
MOV AX,0 ; (A0) RETURN A NULL
|
|
JMP BYTVAL ; (A0) IS THIS RIGHT?
|
|
|
|
; GET A CHARACTER FROM THE KEYBOARD
|
|
ZIN: CALL GETKEY
|
|
POP CX ; (A0) RESTORE REGISTERS
|
|
POP BX
|
|
JMP BYTVAL ; (A0) RETURN THE BYTE
|
|
OPINPUT ENDP
|
|
|
|
SUBTTL LINE INPUT FOR GETLIN
|
|
PAGE
|
|
|
|
; ------
|
|
; LININP
|
|
; ------
|
|
|
|
;
|
|
; PURPOSE: THIS ROUTINE IS USED BY GETLIN TO FETCH A LINE OF INPUT
|
|
; FROM THE KEYBOARD AND PLACE IT IN THE INPUT BUFFER (INBUFF)
|
|
; IN ADDITION, IT HAS THE RESPONSIBILITY TO TACKLE TIMED LINE
|
|
; INPUT REQUESTS.
|
|
;
|
|
; {CASE TIMED INPUT}
|
|
; IF NARGS GE. 3, THEN THIS IS A TIMED INPUT
|
|
; IF A KEY IS DETECTED BEFORE TIMEOUT, THEN WE DROP INTO
|
|
; LINE INPUT PROCESSING.
|
|
;
|
|
; IF NARGS EQ. 4, THEN UPON TIMEOUT THE FUNCTION [ARG4] IS
|
|
; INTERNALLY CALLED. IF THE VALUE RETURNED BY THE FUNCTION = 0,
|
|
; THEN WE KEEP LOOPING.
|
|
;
|
|
;IF NARGS NE. 4 OR THE VALUE RETURNED FROM THE INTERNAL FUNCTION
|
|
; CALL NE. 0, THEN WE RETURN A "FALSE" IN [AX] TO {GETLIN}.
|
|
;
|
|
; {CASE LINE INPUT PROCESSING}
|
|
; GET A LINE OF INPUT AND RETURN A "TRUE" IN [AX] TO {GETLIN}.
|
|
;
|
|
; INPUTS: [NARGS],[ARG3]opt,[AGR4]opt
|
|
;
|
|
; OUTPUTS: DX = ADDRESS OF INBUF, AX = TRUE OR FALSE (see above)
|
|
;
|
|
; REGISTERS DESTROYED: AX,DX
|
|
;
|
|
; EXTERNAL REFERENCES: INCALL,CHROUT
|
|
;
|
|
PUBLIC LININP
|
|
LININP PROC
|
|
PUSH BX ; (A0) SAVE FCN ADDRESS
|
|
MOV BX,OFFSET INBUF ; (A0) POINT AT INPUT BUFFER
|
|
MOV BYTE PTR [BX],MAXLIN ; (A0) MAXIMUM NUMBER OF CHARACTERS
|
|
MOV BYTE PTR [BX+1],0 ; (A0) RESET THE CHARACTER COUNT
|
|
|
|
;
|
|
; TIMED INPUT
|
|
;
|
|
|
|
TIMELP: IDIV RADIX
|
|
MOV DLYCNT,AX ; (A0) AX HAS DELAY COUNT
|
|
POP BX ; (A0) RESTORE FCN ADDRESS
|
|
|
|
CALL TIMLP1 ; (A0) SEE IF CHAR IS READY
|
|
JNC ENTIN ; (A0) YES, NO TIMEOUT, GET IT
|
|
TEST AL,AL ; (A0) SEE WHAT INCALL RETURNED
|
|
JZ ENTIN ; (A0) CONTINUE NORMALLY
|
|
|
|
MOV BX,OFFSET INBUF+2 ;POINT THE START OF THE ACTUAL BUFFER
|
|
ADD BX,CX ;(A0) POINT AT THE CHARACTER SLOT
|
|
MOV [BX],AL ;(A0) SAVE THE EOL
|
|
CALL MTTYO ;(A0) AND OUTPUT IT TO THE CONSOLE
|
|
RET
|
|
|
|
ENTIN: JMP INLOOP
|
|
LININP ENDP
|
|
|
|
;
|
|
; GET A LINE OF INPUT
|
|
;
|
|
|
|
PUBLIC INLOOP
|
|
INLOOP PROC
|
|
CALL GETKEY
|
|
CMP AL,14 ;(A0) CLEAR OFF ARROWS
|
|
JE INBAD
|
|
|
|
CMP AL,7
|
|
JE INBAD
|
|
|
|
CMP AL,EOL ;(A0) CARRIAGE RETURN?
|
|
JE ENDLIN ;(A0) ....YES. WE'RE DONE
|
|
|
|
CMP AL,7FH ;(A0) REGULAR DELETE
|
|
JE BACKUP ;(A0) ....YES
|
|
|
|
CMP AL,BACKSP ;(A0) BACKSPACE (DELETE)?
|
|
JE BACKUP ;(A0) ....YES
|
|
|
|
CMP AL,11 ;(A0) LEFT ARROW (DELETE)?
|
|
JE BACKUP ;(A0) ....YES
|
|
|
|
; PUT THE CHARACTER IN THE INPUT BUFFER, IF POSSIBLE
|
|
SUB CH,CH
|
|
MOV CL,INBUF+1 ;(A0) GET NUMBER OF CHARACTERS ALREADY
|
|
;(A0) IN THE BUFFER
|
|
|
|
; CMP CL,INBUF ;(A0) IS THE BUFFER FULL?
|
|
|
|
MOV BL,INBUF ;(A9) GET THE MAXIMUM NO. OF CHARACTERS
|
|
DEC BL ;(A9) <CR> ENDS ALL INPUT - LEAVE ROOM
|
|
|
|
DEC BL ;(B0) bl/Length, not ptr
|
|
CMP CL,BL ;(A9) IS THE BUFFER FULL?
|
|
JE NOMO ;(A0) ....YES
|
|
|
|
; THERE'S ROOM IN THE BUFFER
|
|
INC BYTE PTR INBUF+1 ;(A0) UPDATE NUMBER OF CHARACTERS
|
|
;(A0) IN THE BUFFER
|
|
|
|
MOV BX,OFFSET INBUF+2 ;POINT THE START OF THE ACTUAL BUFFER
|
|
ADD BX,CX ;(A0) POINT AT THE CHARACTER SLOT
|
|
MOV [BX],AL ;(A0) SAVE THE CHARACTER
|
|
|
|
;DISPLAY THE CHARACTER ON THE SCREEN
|
|
SHOWIT: CALL MTTYO ;(A0) DISPLAY IT
|
|
JMP INLOOP ;(A0) AND GET ANOTHER
|
|
|
|
;
|
|
; LINE OVERFLOW
|
|
;
|
|
|
|
NOMORE: CALL GETKEY ;(A0) GET A KEY
|
|
CMP AL,EOL ;(A0) <CR>?
|
|
JE ENDLIN ;(A0) ....YES, WE'RE DONE
|
|
|
|
CMP AL,7FH ;(A0) REGULAR DELETE
|
|
JE BACKUP ;(A0) ....YES
|
|
|
|
CMP AL,BACKSP ;(A0) BACKSPACE (DELETE)?
|
|
JE BACKUP ;(A0) ....YES
|
|
|
|
CMP AL,11 ;(A0) LEFT ARROW (DELETE)?
|
|
JE BACKUP ;(A0) ....YES
|
|
|
|
NOMO: CALL FEEP ;(A0) CAN' DO IT, SO COMPLAIN
|
|
JMP NOMORE ;(A0) AND DON'T LET THEM OFF THE HOOK
|
|
|
|
;
|
|
; BACKUP (DELETE A CHARACTER)
|
|
;
|
|
|
|
BACKUP: CMP BYTE PTR INBUF+1,0 ;(A0) CAN WE REALLY DELETE A CHARACTER?
|
|
JE INBAD ;(A0) ....NO, WE HAVE NONE TO DELETE
|
|
|
|
; ACTUAL DELETE
|
|
DEC BYTE PTR INBUF+1 ;(A0) ONE LESS IN THE BUFFER
|
|
MOV AL,BACKSP ;(A0) BACKUP A CHARACTER POSITION
|
|
CALL MTTYO ;(A0) ON THE SCREEN
|
|
MOV AL,SPACE ;(A0) ERASE CHARACTER
|
|
CALL MTTYO ;(A0) BY REPLACING IT WITH A SPACE
|
|
MOV AL,BACKSP ;(A0) BACKUP A CHARACTER POSITION
|
|
JMP SHOWIT ;(A0) ON THE SCREEN AND LOOP
|
|
|
|
INBAD: CALL FEEP ;(A0) CAN' DO IT, SO COMPLAIN
|
|
JMP INLOOP ;(A0) AND DON'T LET THEM OFF THE HOOK
|
|
|
|
;
|
|
; LINE TERMINATED BY A EOL <CR>
|
|
;
|
|
|
|
ENDLIN: MOV BX,OFFSET INBUF+2 ;POINT THE START OF THE ACTUAL BUFFER
|
|
SUB CX,CX
|
|
MOV CL,INBUF+1 ;(B1) Point at 1st unused byte
|
|
ADD BX,CX ;(A0) POINT AT THE CHARACTER SLOT
|
|
; INC BX ;(A9)(b1 2 entry pts w/different conditions;fixed cx)
|
|
MOV [BX],AL ;(A0) SAVE THE EOL
|
|
CALL MTTYO ;(A0) AND OUTPUT IT TO THE CONSOLE
|
|
LINRET: RET
|
|
INLOOP ENDP
|
|
|
|
|
|
; ----------------------
|
|
; FETCH AN ASCII KEYCODE
|
|
; ----------------------
|
|
;
|
|
; PURPOSE: GETKEY WAITS FOR A KEY TO BE DEPRESSED ON THE CONSOLE.
|
|
; WHEN A KEY IS DEPRESSED, IT'S ASCII VALUE IS RETURNED
|
|
; FROM THE DOS FUNCTION.THE ASCII VALUE IS THEN PREPROCESSED
|
|
; SO THAT CERTAIN KEYS ARE TRANSLATED INTO EZIP ASCII VALUES
|
|
;
|
|
; OTHER KEYS ARE CONSIDERED ILLEGAL AND IF DETECTED CAUSE A
|
|
; BEEP SOUND TO BE HEARD, THE KEYPRESS IS IGNORED, AND THE
|
|
; ROUTINE CONTINUES TO WAIT FOR A VALID KEY.
|
|
;
|
|
; INPUTS: NONE
|
|
;
|
|
; OUTPUTS: [AL] = A 7-BIT ASCII CODE
|
|
;
|
|
; REGISTERS DESTROYED:
|
|
; AX,BX,CX
|
|
;
|
|
; EXTERNAL REFERENCES: FEEP
|
|
;
|
|
PUBLIC GETKEY,GK0,GK1,GK2,GK3,GK4,KEYOK,CHKKEY
|
|
GETKEY PROC
|
|
GK0: MOV AH,CNOECHO ;(A0) WAIT FOR KEYPRESS, NO ECHO
|
|
INT 21H ;(A0) MSDOS FUNCTION CALL
|
|
AND AL,7FH ;(A0) 7-BIT ASCII ONLY
|
|
|
|
; EXTENDED SPECIAL FUNCTIONS
|
|
CMP AL,0 ;(A0) IF AL=0,THIS IS AN EXTENDED KEY
|
|
JNE CHKKEY ;(A0) THANK GOODNESS, IT ISN'T
|
|
|
|
; PROCESS EXTENDED KEYS
|
|
; DO A SECOND READ
|
|
MOV AH,CNOECHO ;(A0) WAIT FOR KEYPRESS, NO ECHO
|
|
INT 21H ;(A0) MSDOS FUNCTION CALL
|
|
|
|
CMP AL,72 ;(A0) UP ARROW
|
|
JNE GK1
|
|
MOV AL,14
|
|
JMP KEYOK
|
|
|
|
GK1: CMP AL,75 ;(A0) LEFT ARROW
|
|
JNE GK2
|
|
MOV AL,11
|
|
JMP KEYOK
|
|
|
|
GK2: CMP AL,77 ;(A0) RIGHT ARROW
|
|
JNE GK3
|
|
MOV AL,7
|
|
JMP KEYOK
|
|
|
|
GK3: CMP AL,80 ;(A0) DOWN ARROW
|
|
JNE GK4
|
|
MOV AL,13
|
|
JMP KEYOK
|
|
|
|
GK4: CMP AL,83 ;(A0) DEL KEY
|
|
JNE GK0 ;(A0) IT'S BAD, TRY AGAIN
|
|
MOV AL,7FH
|
|
JMP KEYOK ;(A9)
|
|
|
|
;
|
|
; WE'RE RECEIVED A NON-EXTENDED KEY
|
|
; SO, NATURALLY ENOUGH, WE'RE GOING TO RUN IT THROUGH
|
|
; AN ASCII FILTER TO REMOVE THOSE KEYS THAT WE DON'T
|
|
; (THROUGH NO FAULT OF THEIR OWN) LIKE.
|
|
;
|
|
|
|
CHKKEY: CMP AL,08H ;(A9) BACKSPACE IS OK
|
|
JE KEYOK ;(A9)
|
|
CMP AL,0DH ;(A9) <CR>
|
|
JE KEYOK ;(A9)
|
|
CMP AL,20H ;(A9) AND SO ARE KEYS .GE SPACE
|
|
JAE KEYOK ;(A9)
|
|
JMP GK0 ;(A9)
|
|
KEYOK: MOV IOCHAR,AL ; (LD1) HOLD A SEC
|
|
ADC AX,RSEED1 ; (LD1) PLAY WITH RANDOM BYTES
|
|
MOV RSEED1,AX ; (LD1) EACH TIME THRU HERE
|
|
XOR RSEED2,AX ; (LD1)
|
|
MOV AL,IOCHAR ; (LD1) THANKS FOR WAITING
|
|
RET
|
|
GETKEY ENDP
|
|
|
|
|
|
; POLL THE KEYBOARD FOR 1/nTH SEC
|
|
; NOTE: THIS ROUTINE DOES IT IN 0.11 SEC WITH A FAIR DEGREE
|
|
; OF PRECISION, INDEPENDENT OF SYSTEM CLOCK (AT+, PC, ETC.)
|
|
TIMLP1 PROC
|
|
PUSH DI
|
|
TRESET: MOV DI,DLYCNT
|
|
TIMIN: MOV AH,CTIME ;(A0) GET TIME FROM REAL TIME CLOCK
|
|
INT 21H ;(A0) MSDOS FUNCTION CALL
|
|
MOV CLKLOW,DX ;(A0) SAVE 1/100 SEC COUNT
|
|
|
|
; IS A KEY AVAILABLE
|
|
TRY: MOV AH,CINSTAT ;(A0) CHECK STANDARD INPUT STATUS
|
|
INT 21H ;(A0) MSDOS FUNCTION CALL
|
|
OR AL,AL ;(A0) IS A CHARACTER AVAILABLE
|
|
JZ TRY1 ;(A0) NO
|
|
POP DI
|
|
CLC ; (A0) CLEAR TO SIGNAL A CHAR
|
|
RET
|
|
|
|
; NOKEY
|
|
TRY1: MOV AH,CTIME ;(A0) GET TIME FROM REAL TIME CLOCK
|
|
INT 21H ;(A0) MSDOS FUNCTION CALL
|
|
MOV AX,DX ; (A0) SAVE IT
|
|
SUB DX,CLKLOW ;(A0) IF EQUAL TO SAVED TIME
|
|
CMP DX,100H
|
|
JB TRY ;(A0) .1 SECS HASN'T EXPIRED YET
|
|
NEG DX
|
|
CMP DX,100H
|
|
JB TRY
|
|
|
|
MOV CLKLOW,AX ;(A0) SAVE 1/100 SEC COUNT
|
|
|
|
|
|
DEC DI ;(A0) DECREMENT DELAY TIMER
|
|
JNZ TIMIN ;(A0) IF TIME IS LEFT, TRY AGAIN
|
|
|
|
; TIME OUT, CHECK FOR A FUNCTION
|
|
MOV AX,BX ;(A0) GET ORIGINAL BX (FCN) INTO AX
|
|
CALL INCALL ;(A0) ....YES, CALL THE FUNCTION
|
|
CMP AX,0 ; IF VALUE RETURNED=0
|
|
JNZ INFAIL ;(A0) THEN TRY AGAIN
|
|
JMP TRESET
|
|
INFAIL: POP DI ; (A0) RESTORE THIS ONE
|
|
STC ; (A0) INDICATE A TIMEOUT
|
|
RET ; (A0) RETURN WITH TIMEOUT RET IN AX
|
|
|
|
TIMLP1 ENDP
|
|
|
|
SUBTTL RDLIN
|
|
PAGE
|
|
|
|
; ------
|
|
; RDLIN
|
|
; ------
|
|
|
|
;
|
|
; PURPOSE: THIS ROUTINE PROVIDES BUFFERED KEYBOARD INPUT
|
|
;
|
|
;
|
|
; NOTE: NORMALLY LINE INPUT IS PROVIDED BY USING DOS
|
|
; INT 21H FUNCTION CALLS WITH [AH]=0AH. BECAUSE WE
|
|
; WANT TO INTERCEPT AND IGNORE MANY POSSIBLE KEYS, THIS
|
|
; ROUTINE IS NECESSARY.
|
|
;
|
|
;
|
|
; INPUTS: [AH]=0AH, DS:DX ^ INPUT BUFFER. THE FIRST BYTE
|
|
; SPECIFIES THE NUMBER OF BYTES THE BUFFER CAN HOLD
|
|
; (MUST BE .NE 0). THE SECOND BYTE IS SET TO THE
|
|
; NUMBER OF CHARACTERS RECEIVED.
|
|
;
|
|
; OUTPUTS: THE INPUT BUFFER WILL CONTAIN A FILTERED ASCII STRING
|
|
; TERMINATED BY <CR>.
|
|
;
|
|
; REGISTERS DESTROYED: NONE?
|
|
;
|
|
;
|
|
|
|
RDLIN PROC
|
|
PUSH AX ;(A9)
|
|
PUSH BX ;(A9)
|
|
PUSH CX ;(A9)
|
|
PUSH DX ;(A9)
|
|
PUSH DX ;(A9)
|
|
POP BX ;(A9)
|
|
MOV BYTE PTR [BX+1],0 ;(A9) RESET THE CHARACTER COUNT
|
|
CALL INLOOP ;(A9)
|
|
POP DX ;(A9)
|
|
POP CX ;(A9)
|
|
POP BX ;(A9)
|
|
POP AX ;(A9)
|
|
RET
|
|
RDLIN ENDP
|