⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 inptty.asm

📁 [随书类]Dos6.0源代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;		turn user cursor off (in order to print prompt)
;		save # of values in VALCNT
;		save input flag ("?" and/or CR)
;
;	(II) Parse each value
;		print prompt with/out "? " <CR>
;	     ** read line
;		clean the stack by using [b$StkBottom]
;
;		loop each input value and check the type (B$FIN)
;			Note that around the call to B$FIN (for as short a
;			period as possible) the error vector is set such that
;			all errors encounted will vector back here.
;		if no error then
;			push value into the stack
;		else /* error happened */
;			give error message
;			reconstruct stack frame on the TOP OF THE STACK
;			goto (II)
;	(III) epilog
;		give error if the number of values is not correct (goto
;			error handling routine and start over)
;		restore registers from memory location
;		far jump to the caller
;
;	Note: ** means stack frame has to be in stack.
;
; NOTE: This routine can take a far pointer to a movable item in a heap. This
; routine cannot directly or indirectly cause heap movement. (The interpeter
; places the parameter block in a far heap entry).
;
;Entry:
;	Parameters in stack.
;	sd	sdPrompt
;	int	far*pBlock
;
;	Refer the source head comments for the structure of Block.
;Exit:
;	values are in stack.
;
;	[b$DATAPT] = [b$StkBottom] points to the bottom of var list & stack
;	NOTE: the direction of the list is auto-decrement.
;
;	[BlockPt] contains the far pointer to the types list
;	NOTE: the type list is the subset of the Block described above.
;
;	[VALCNT] is the count of how many variables
;Uses:
;	none
;Exceptions:
;
;*******************************************************************************

cProc	B$INPP,<PUBLIC,FAR>
	ParmSD	sdPrompt	;sd of prompt string
	ParmD	pBlock		;far point to Block
				;NOTE: we may use the symbols of off_pBlock
				;	and seg_pBlock
cBegin				;generate stack frame
	MOV	[SaveES],ES	;save ES
	MOV	[SaveSI],SI	;save SI
	MOV	[SaveDI],DI	;save DI

	LEA	BX,[BP+12]	;bottom of the stack and var list
	MOV	[b$DATAPT],BX	; [b$DATAPT] = [b$StkBottom]
	MOV	[b$StkBottom],BX 

.erre	ID_SSEQDS		; give error if SS <> DS
	PUSH	DS		
	POP	ES		; let ES=DS
	MOV	SI,BP		; source addr
	MOV	DI,OFFSET DGROUP:SaveBP ; destination addr
	MOV	CX,3		; 3 words
	REP	MOVSW		; save in data area, stack frame still in
				;  stack
	MOV	[b$PTRFIL],CX	; Set output to TTY (CX=0)

	GetpSD	BX,sdPrompt	;BX = psdPrompt
	MOV	[PROMPT],BX	;Save prompt string descriptor address
	LES	DI,pBlock	;ES:DI points to the block
	MOV	AX,ES:[DI]	;get block length
	DEC	AX		; block length is n+1
	MOV	[VALCNT],AX	;Remember number of values
	INC	DI
	INC	DI		;increment the pointer
	MOV	AL,ES:[DI]	;get the flag byte
	MOV	[INFLG],AL	;save flag byte
	INC	DI		;so DI points to the list of types now
	MOV	[BlockOff],DI	
	MOV	[BlockSeg],ES	;save segment:offset to the Block

	
PrtPrompt:			;Enter here if error to re-prompt and
				; re-read data
	MOV	BX,[PROMPT]	;BX=*sd of Prompt
	CALL	B$TYPSTR 	;Print the prompt
	TEST	[INFLG],FINP_QSupress ;Need a "?" after prompt?
	JNZ	GetLin		;Brif not
	MOV	AL,"?"		;output "?"
	CALL	B$$WCHT
	MOV	AL," "		; and one blank
	CALL	B$$WCHT
GetLin:
	CALL	B$RDLIN	;get input line
	TEST	[INFLG],FINP_CrLf ;is it INPUT "semi-colon" ?
	JNZ	CleanStk	;Brif yes, don't send <CR><LF>
	CALL	B$INPCRLF	; force CR to all places where input was
				; written (screen and/or redirected file)

CleanStk:
	MOV	SP,[b$StkBottom]	; clean the stack
				; at this point, stack frame is destroyed.
				;  Since B$FIN return error code and error
				;  handler will restore the stack frame, it
				;  should be fine.
	MOV	AX,[VALCNT]	;get # of types
	MOV	[TYPCNT],AX	;Initialize count of values
	MOV	SI,OFFSET DGROUP:b$Buf1
				;DS:SI points to the value list
	LES	DI,[BlockPt]	;ES:DI points to the type list

; At this point, [TYPCNT] has the number of values
;		 ES:DI points to the next type in the type list
;		 DS:SI points to the next input in the input stream
;		 stack is ready to put values.

EachVal:
	MOV	AL,ES:[DI]	;get next type
	INC	DI		;increment the pointer
	MOV	[b$VTYP],AL	;save the type (used by B$FIN)

	MOV	[b$errvec],DK_TEXTOFFSET InpErr	; set err vec
	PUSH	ES		
	PUSH	DS		; set ES = segment of source
	POP	ES		
	INC	[b$curlevel]	; Increment level for possible dealloc
	CALL	B$FIN		;get number or string (AL=Next Char)
	DEC	[b$curlevel]	; restore b$curlevel
	POP	ES		
	MOV	[b$errvec],0	; reset error vector

	MOV	CL,[b$VTYP]	;get the type
	AND	CL,0FH		;get rid of upper half
	CMP	CL,VT_R4	;is 2 byte value ?
	MOV	BX,OFFSET DGROUP:B$AC
				;BX has the result
	JB	PushAC		;Don't do high word if integer or string
	PUSH	[BX+2]		;Push highest word
PushAC:
	PUSH	[BX]
	JBE	NextVal 	;Only push low words if D.P.
	PUSH	[BX-2]
	PUSH	[BX-4]
NextVal:
	DEC	[TYPCNT]	;any values left?
	JZ	ChkEnd		;Brif no more
	CMP	AL,","		;values must be separated by ","
	JZ	EachVal 	;process next value

;Come here to restart if any error occurred

RedoFromStart:			
	CALL	B$$TCR		;force CR/LF
	MOV	AX,MS_REDO	;message number
	cCall	B$PUTNUM	; output message
	CALL	B$$TCR		;force CR/LF

	MOV	AX,[b$curlevel]	; setup for string temp deallocation...
	INC	AX		; ...only above current level!
	CALL	B$STDALCALLTMP	; deallocate all string temps.

	MOV	SP,[b$DATAPT]	;roughly clean the stack, this is only to
				; avoid stack overflow when we restore the
				; stack frame.	the thorough clean will be
				; done after read line.
	PUSH	[RetSeg]	;restore stack fram on stack
	PUSH	[RetOff]
	PUSH	[SaveBP]
	MOV	BP,SP
	JMP	PrtPrompt	;redo from start

;Come here from error trap if overflow in $FIN

InpErr: 			; give error message
	DEC 	[b$curlevel]	; restore [b$curlevel] after B$FIN error
	MOV	[b$errvec],0	; don't allow infinite loop
	PUSH	BX		; save error number
	CALL	B$$TCR		;force CR/LF
	POP	AX		; get back error number
	cCall	B$PUTNUM	; output message
	JMP	SHORT RedoFromStart	; redo from start

ChkEnd:
	OR	AL,AL		;Did we reach end of line?
	JNZ	RedoFromStart	; Brif not, redo from the start

	MOV	BX,[PROMPT]	; BX = pointer to prompt string
	cCall	B$STDALCTMP	; deallocate it if it was temp


	MOV	[b$GetOneVal],OFFSET TTYInpVal
				;set up for get one input item
	MOV	[b$FInput],InpTTY
				;set input flag
	MOV	DI,[SaveDI]	;restore registers
	MOV	SI,[SaveSI]
	MOV	ES,[SaveES]
	MOV	BP,[SaveBP]
	JMP	[RetAddr]	;return to caller
cEnd	nogen			;no code generated

	SUBTTL	TTY input supporting routine -- TTYInpVal
	page
;***
;TTYInpVal -- get one input value
;
;Purpose:
;	This routine gets one value from the buffer (in stack).
;
;	After the input preamble, the succeeding calls will assign values
;	into variables.  The functionality of those assignment routines,
;	B$RD<type>, may be roughly split into two parts -- namely, getting
;	one value and then assigning it to the variable.  In BASCOM 3.0,
;	those assignment routines are shared by READ stmt, input from TTY
;	and input from a disk file (or a device).  Generally speaking,
;	the second part of the assignment routines DOESN'T discriminate
;	among the statements which share its use.  However, the first part
;	of the assignment routines MUST discriminate among the statements
;	which share its use.  In order to achieve this, the first part of
;	the assignment routines uses an indirect call, CALL [b$GetOneVal],
;	to get one value.  [b$GetOneVal] is default to the address of
;	ReadVal, which gets one value for READ stmt, or contains either
;	the address of TTYInpVal for TTY input or the address of DskInpVal
;	for disk (device) input.
;
;Entry:
;	[b$VTYP]	= types
;	[b$DATAPT]	points to the var list
;Exit:
;	[SI]		= pointer to the value
;	[b$DATAPT]	is updated
;Uses:
;	none
;Exceptions:
;	none
;*******************************************************************************

cProc	TTYInpVal,<NEAR>	;assume DS=SS, ES=DS when enter

cBegin
.erre	ID_SSEQDS		;assume SS=DS (used in B$RD<type>)
	MOV	SI,[b$DATAPT]	;get pointer to next value
	MOV	AL,[b$VTYP]	; AL has the type
	CBW			;AX has the type
	AND	AL,0EH		;AX has the length
	SUB	SI,AX		;SI points to the begining of the source
	MOV	[b$DATAPT],SI	;save for next call
cEnd				;return to caller


	SUBTTL	RANDOMIZE interface -- B$RNZ0
	page
;***
;B$RNZ0 -- randomize without parameter specified.
;void B$RNZ0(void)
;
;Purpose:
; Reseeds the random number generator.
; Moved here from RANDOM.ASM [21]
;
;Entry:
; This routine prompts for the user to enter the new random number seed'
;
;Exit:
; User specified seed is stored in b$RndVar+1 (the middle word of the random
; number (DWORD)).
;
;Uses:
; Per convention
;
;Exceptions:
; B$ERR_OV -- overflow (in B$INPP)
;
;*******************************************************************************
cProc	B$RNZ0,<PUBLIC,FAR,FORCEFRAME>
cBegin
	MOV	AX,MS_SEED
	cCall	B$PUTNUM	;Output seed message
	MOV	AX,OFFSET DGROUP:b$nuldes
	PUSH	AX		;push *sd of prompt
	PUSH	DS		;far pointer
	MOV	AX,OFFSET DGROUP:RandpBlock
	PUSH	AX		;push *pBlock
	cCall	B$INPP		;on return, input value is in stack
	PUSH	DS
	MOV	AX,OFFSET DGROUP:b$RndVar+1 ;destination
	PUSH	AX
	cCall	B$RDI2		;read user's seed into destination
	cCall	B$PEOS		;reset flags & variables
cEnd				;exit to caller

sEnd	;DK_TEXT

	END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -