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

📄 prnval.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	INC	SI		;skip the leading blank if write statement
	DEC	AX		;decrement the length
WTMKSD:
	cCall	MAKESD		;[BX]=*sd
	JMP	SHORT PRTIT2	;go print it
PRTUSG:
				; print using, so make QBI compatable.
	CMP	AH,COMA		; PRINT USING COMMA?
	JNE	NotComma	; brif not -- don't alter terminator
	MOV	b$TTYP,SEMI	; change comma to semicolon
NotComma:			
	CALL	[b$PUSG]	;print using is handled specially
	JMP	SHORT PRTEND	;process the terminator
PRTSTR: 			;when enter, BX=*sd
	MOV	AX,[BX] 	; AX = length of string
	TEST	[b$PRFG],WRSTM	; is write stmt on ?
	JZ	PRTIT1		;Brif not, go printing string
	MOV	AL,'"'		;'"' is the delimitor of write string
	PUSH	BX		; save psd
	CALL	[VWCH]		;print '"'
	POP	BX		; restore psd
	CALL	[VTYP]		;output the string
	CALL	[b$pSTDALCTMP]	; deallocate the temp if it is
	MOV	AL,'"'		;'"' is the delimitor of write string
	CALL	[VWCH]		;print it
	JMP	SHORT PRTEND	;process the terminator
PRTCLF:
	CALL	[VWCLF] 	;force a EOL
	cCall	BPEOS		;epilog for PRINT
	JMP	SHORT PRINTX	;exit to caller
PRTEND2:			; here if comma or semi and NOT write stmt
	INC	AX		; test for semi delimitor
	JNZ	PRINTX		; go exit, done if semi-colon
PRTCMA:
	CALL	[VPOS]		;[AH]=current cursor position
	MOV	AL,AH		;position in AL
	XOR	AH,AH		;prepare for DIV
				;Note: can't use CBW here, since the range
				;	is 0 - 255 (unsigned)
	MOV	CL,CLMWID	;get field length
	DIV	CL		;AH=remainder, is the position in this column
	SUB	CL,AH		;spaces needed to fill this column
	XCHG	AX,CX		; put count in AL
	CBW			;extend to a word
	PUSH	AX		;save count of patching spaces
	ADD	AX,CLMWID	;account for width of next column
	cCall	[VPRTCHK]	; CY if room is not enough to fit (possibly
				; a EOL was forced)
	POP	CX		;get back count in CX
	JB	PRINTX		;no need to patch spaces
	CALL	B$OutBlanks	; output CX blanks
PRINTX: 			;pop SI & exit to caller

	POP	SI		; restore
	POP	BP		
	POP	CX		; [CX] = return offset
	POP	DX		; [DX:CX] = return address
	POP	BX		; discard 1st word of parameter
	MOV	AL,BYTE PTR [b$?TYP]	; [AL] = type byte
	TEST	AL,VT_SD	; NZ if I2 or SD, i.e., if 1-word parm
	JNZ	PRINTX_5	; Jump if we don't need to pop more
	POP	BX		; Discard 2nd word of parameter
	TEST	AL,8		; R8 or currency (8-byte values)?
	JZ	PRINTX_5	; no, don't pop any more
	POP	BX		; discard 3rd word of parameter
	POP	BX		; discard 4th word of parameter
PRINTX_5:			
	PUSH	DX		; put back seg...
	PUSH	CX		; ... and offset of far return address
	RET			; and return

cEnd	nogen			;no code generated

	SUBTTL	supporting routines for print an item
	page
;***
;PRTCHK -- check whether there is room for the printing string
;
;Purpose:
;	Check whether there is room for the printing string.  If it isn't,
;	force a EOL if the current position is not in col. 1.
;
;	Prtchk(len_of_str)
;	register int len_of_str
;	{
;	    register int d_width
;	    register int current_pos
;
;	    if ((d_width=vwid()) != 255)
;		if ( (len_of_str > 255) ||
;		     ((d_width - (current_pos=vpos()) - len_of_str) < 0) )
;		{   if (current_pos != 0) /* 0-relative */
;			vclf()
;		    Set_CY
;		}
;	}
;
;Entry:
;	register AX = len_of_str
;
;Exit:
;	CY if room left is not enough (may or may not force a EOL)
;
;Uses:
;	None
;
;Exceptions:
;	None
;*******************************************************************************

cProc	B$PRTCHK,<NEAR,PUBLIC>	

cBegin
	XCHG	DX,AX		; length in DX
	CALL	[VWID]		;[AH] = device width
	CMP	AH,255		;is device a file ?
	JZ	CHKEXT		;exit (with NC)
	MOV	AL,AH		;[AL] = device width
	JMP	SHORT PRTCHK1	
cEnd	<nogen>

cProc	TTY_PRTCHK,<NEAR>	
cBegin				
	XCHG	DX,AX		; length in DX
	MOV	AL,b$CRTWIDTH	; AL = device width

PRTCHK1:			
	CALL	[VPOS]		;[AH] = current position
	OR	DH,DH		; more than 255 char to print?
	JNZ	FORCE		; force a EOL
	SUB	AL,AH		;amount left on line
	JB	FORCE		;If no room on line, need new line
	CMP	AL,DL		;will amount requested fit?
	JAE	CHKEXT		;exit (with NC)
FORCE:
	OR	AH,AH		;is current position 0 (at col 1)
	JZ	NOCRLF		;do not print EOL if at col 1
	CALL	[VWCLF] 	;force EOL
NOCRLF:
	STC			;indicate room is not enough
Near_Ret:			;near return for vector
CHKEXT:
cEnd				;end of PRTCHK

;***
;MAKESD -- make a static string descriptor
;
;Purpose:
;	Make a static string descriptor (in b$TempSD) which points to the
;	input string.  Major changes with revision [38].
;
;	WARNING !!! This routine assumes that the word preceding the string
;	WARNING !!! is available to be used as the string header
;
;Entry:
;	[SI] = address of the string
;	[AX] = length of the string
;
;Exit:
;	[BX] = address of static descriptor (b$TempSD)
;	b$TempSD & b$TempStrPtr set up as SD.
;
;Uses:
;	Backs up SI by 2.
;
;*******************************************************************************

cProc	MAKESD,<NEAR>		;private local routine

cBegin
	MOV	BX,OFFSET DGROUP:b$TempSD	; get the offset
	MOV	WORD PTR [BX],AX		; length goes first
	MOV	WORD PTR [BX+2],SI		; string pointer next
cEnd

;***
;BPEOS -- actual code to terminate a print statement.
;
;Purpose:
;	This routine is called by either the interface B$PEOS or B$PExx
;	(print an item which terminated with a EOL)
;	If FV_FARSTR, deallocate "using" string here if it was a temp.
;Entry:
;	b$PTRFIL is the pointer/handle to FDB
;Exit:
;	b$PTRFIL & b$PRFG are reset
;Uses:
;	none
;Exceptions:
;	I/O error or disk full error (when flush the buffer)
;*******************************************************************************

cProc	BPEOS,<NEAR>,<SI>	;was part of $PV4, SI saved

cBegin
	MOV	SI,[b$PTRFIL]	;get the pointer to FDB
	OR	SI,SI		;is file 0 ? (TTY)
	JZ	PEOSX		;Brif tty output, reset flags and exit
	MOV	[b$PTRFIL],TTY ; clear out active FDB block
	FDB_PTR ES,SI,SI	;(ES:)[SI] = *FDB
	CMP	SI,OFFSET DGROUP:b$LPTFDB ;is line printer ?
	JE	PEOSX		;Brif LPRINT
	TEST	FileDB.FD_FLAGS,FL_CHAR ;check for character device file
	JZ	PEOSX		;Brif not character device
	CALL	[b$pFLUSH]	; is character device, flush buffer
				; was save and restore registers AX,BX,CX &
				; DX in $PV4
PEOSX:
	TEST	[b$PRFG],WRSTM+LPSTM+CHANL ;was LPRINT, WRITE or # ?
	MOV	[b$PRFG],PRSTM ;reset the print flag
	JZ	NoSetVec
	MOV	SI,OFFSET DGROUP:TTYVEC
				;get source to fill in
	cCall	B$WCHSET	;reset vector to default, needs SI
NoSetVec:
cEnd				;pop SI & exit to caller

	SUBTTL	print/input interface -- B$PEOS [4]
	page
;***
;B$PEOS -- epilog for PRINT/WRITE/LPRINT/INPUT[#]/READ
;
;Purpose:
;	if print, then clear out active FDB block, and flush buffer in case
;		of a character device, also reset print flags
;	if input, reset input flag & variable
;
;	NOTE: this routine plays around with the stack pointer and stack frame
;		pointer (BP).  Be really careful when save something in the
;		stack.
;Entry:
;	[b$PTRFIL] is the pointer to FDB
;	[b$FInput] is the flag for input
;	[b$PRFG] is the flag for print
;Exit:
;	b$PTRFIL & b$PRFG & b$FInput (also b$GetOneVal) are reset
;Uses:
;	none
;Exceptions:
;	I/O error or disk full error (when flush the buffer (BPEOS))
;*******************************************************************************

cProc	B$PEOS,<PUBLIC,FAR>	

cBegin
	PUSH	BP		
	MOV	BP,SP		;set up stack frame explicitly, since error
				; could happen when flushing the buffer
	PUSH	ES		
	MOV	AL,[b$Finput]	; get flag
	OR	AL,AL		; test it
	JS	TryPrint	; either READ stmt or default, try print
	JNZ	RstFlags	; was disk input, just reset flags
	PUSH	SI		; save SI
	PUSH	DI		; save DI
	MOV	DI,[b$StkBottom]	; DI is the stack bottom
	DEC	DI		; one word above
	DEC	DI
	MOV	SI,SP		; SI points to the BP
	ADD	SI,10		;[12] SI points to ret_seg
	MOV	CX,3		; 3 words to move
	STD			; the move has to be from memory high to
				;  low to avoid overlapping
	PUSH	DS		
	POP	ES		
	REP	MOVSW		; mov BP and return addr to new location
	CLD			; clear direction

	MOV	BP,DI		; stack frame has to be changed
	ADD	BP,2		; new locaton of old BP (later on,
				;  "MOV SP,BP" will clean the stack)
	POP	DI		; get back DI
	POP	SI		; get back SI
RstFlags:			
	cCall	B$InpReset	; reset input flag if this is input stmt
	JMP	SHORT EosExit	
TryPrint:			; either print or READ stmt may be here,
				;  however, next call, BPEOS, won't hurt
				;  if it is READ stmt
	cCall	BPEOS		;try print flush the buffer and reset flags
EosExit:			


	POP	ES		
	MOV	SP,BP		;remove stack frame
	POP	BP		
cEnd				;pop BP & exit

	SUBTTL	set up print dispatch vector
	page
;***
;B$WCHSET -- set up print dispatch vector
;
;Purpose:
;	b$VECS is the dispatch vector for PRINT/WRITE/LPRINT, which contains
;	the address for different functions.  The functions are:
;		b$VECS:
;			VPOS	-- current cursor position
;			VWID	-- device line width
;			VWCLF	-- force EOL
;			VWCH	-- write one character
;			VTYP	-- write a string with a given *sd
;			VTYPCNT -- write a string with length in CX
;			VOUTCNT -- write a string char. by char.
;			VPRTCHK -- check if EOL needs to be forced
;Entry:
;	[SI] points to the source which will fill in the b$VECS
;Exit:
;	b$VECS is set up
;Uses:
;	SI
;Exceptions:
;	none
;*******************************************************************************

cProc	B$WCHSET,<PUBLIC,NEAR>,<DI,ES> ;save ES,DI

cBegin
	PUSH	DS		
	POP	ES		; can't assume ES=DS, set them equal
	MOV	DI,OFFSET DGROUP:b$VECS
	MOV	CX,SizeOfVecs	;count of words to copy
	REP	MOVSW
cEnd				;pop DI,ES and exit to caller


;*** 
; B$OutBlanks -- output a string of blanks.  Added with [22].
;
;Purpose:
;	Save some code, and eliminate a static buffer of blanks.
;	Doesn't print anything if count not in range 1-32767.
;
;Entry:
;	CX = number of blanks to output
;Exit:
;	None
;Uses:
;	Per convention
;Exceptions:
;	None
;
;******************************************************************************

cProc	B$OutBlanks,<PUBLIC,NEAR>,<SI,DI>	; Save SI,DI

cBegin
	OR	CX,CX		; negative or zero byte count
	JLE	OutExit 	; brif no blanks to output


DbAssertRel CX,BE,2*FILNAML,DK_TEXT,<B$OutBlanks: cnt too large>    

	PUSH	CX		;save cnt
	PUSH	SS		;ES = DGROUP
	POP	ES		
	MOV	DI,OFFSET DGROUP:b$Buf1 
	PUSH	DI		
	INC	CX		;round byte count to word count
	SHR	CX,1		
	MOV	AX,'  ' 	
    REP STOSW			;fill with spaces
	POP	SI		;DS:SI = string
	POP	CX		;CX = count
	CALL	[VOUTCNT]	;print the spaces


OutExit:
cEnd				;exit to caller

	page
;***
;NoGetValAssert - Assertion code for calls through [b$GetOneVal].
;
;Purpose:
;	The variable [b$GetVal] is reset with common code to point to
;	the default READ/INPUT entry point.  When no INPUT/READ statement
;	is used in a program linked /O, there is no need to drag in the
;	READ code.  So, b$GetVal is initialized to point to this routine
;	for this case.	If someone inadvertently tries to call through
;	b$GetVal when no READ/INPUT code is loaded, it will be caught here.
;	Added with revision [27].
;Entry:
;	none
;Exit:
;	none
;Uses:
;	none
;Exceptions:
;	none
;*******************************************************************************

cProc	NoGetValAssert,<NEAR>
cBegin
	DbHalt <DK_TEXT>,<Tried to call B$ReadVal when it wasn't loaded>
cEnd
	page
;***
;B$InpReset -- reset flag and variables for INPUT related statement
;
;Purpose:
;	Reset flag and variables for input related statement.
;	Moved to this file with [23]
;
;Entry:
;	none
;
;Exit:
;	[b$FInput]	= InpDefault
;	[b$GetOneItem] = OFFSET B$ReadItem
;	[b$PTRFIL]	= TTY
;
;Uses:
;	none
;
;Exceptions:
;	none
;*******************************************************************************

cProc	B$InpReset,<PUBLIC,NEAR>

cBegin
	MOV	[b$FInput],InpDefault
				;reset input flag

; If input was pulled in, then this points to B$ReadVal, if no READ/INPUT
; statement was used, then this really points to the assertion routine
; NoGetValAssert

	PUSH	AX		
	MOV	AX,[b$pGetValDefault] ;get default value for READ/INPUT

	MOV	[b$GetOneVal],AX ;reset get item routine
	POP	AX
	MOV	[b$PTRFIL],TTY ;reset to TTY
cEnd				;exit to caller

	SUBTTL	interface for WRITE preamble
	page
; B$WRIT moved here from PR0A.ASM and modified for greater /O modularity.
;Revision number [25] applies to entire routine.
;***
;B$WRIT -- preamble for WRITE statement [25]
;void B$WRIT(void)
;
;Purpose:
;	This is the only preamble for WRITE statement.	This routine sets up
;	flag for WRITE statement.  BASCOM 2.0 uses two preambles,
;	$WRI for WRITE and $WRD for WRITE #.
;
;	The flag, b$PRFG, is set to 4 (WRSTM) to indicate a WRITE statement
;	is processing.	If it is a WRITE #, then B$CHOU will OR the flag,
;	b$PRFG, with 1 (CHANL) to indicate a special channel is being used.
;Entry:
;	none
;Exit:
;	b$PRFG is set to WRSTM (WRITE statement is on going)
;	uses default vectors, same as PRINT.
;Uses:
;	none
;Exceptions:
;	none
;*******************************************************************************

cProc	B$WRIT,<PUBLIC,FAR,FORCEFRAME>	; stack frame generated explicitly

cBegin
	OR	[b$PRFG],WRSTM	; set flag indicating WRITE stmt is on going
	CALL	B$CNTRL		; check for control chars during print
cEnd				; return to caller

sEnd				;end of DK_TEXT
	END

⌨️ 快捷键说明

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