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

📄 txtdata.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	TITLE	txtdata.asm - Ascii Load DATA Stmt movement Functions

;==========================================================================
;
;Module:  txtdata.asm
;System:  Quick BASIC Interpreter
;
;This entire module could disappear if previous versions of BASCOM
;either did not allow DATA statements within a SUB, or localized
;access to DATA and RESTORE statements to the context they are in.
;For compatibility, the functions in this module move DATA statements
;and labels for RESTORE statements from SUB/FUNCTIONs to main level code.
;
;
;===========================================================================

	include		version.inc
	TXTDATA_ASM = ON
	includeOnce	architec
	includeOnce	context
	includeOnce	heap
	includeOnce	msgshort
	includeOnce	names
	includeOnce	opmin
	includeOnce	parser
	includeOnce	scanner
	includeOnce	txtmgr
	includeOnce	txtint

	assumes	DS,DATA
	assumes	SS,DATA
	assumes	ES,NOTHING

sBegin	DATA

;-----------------------------------------------------------------------------
;		Description of Table bdData
;
; This table contains 1 entry for every statement in the module significant
; to migration of DATA statements from SUB/FUNCTION to main program.
; The first byte of each entry is a type, which determines what info
; is contained in the rest of the entry as follows:
;
; DT_Data - entry describes a DATA opcode which needs to be moved from an
;           SUB/FUNCTION's text table to the module's text table.
;	    It is followed by 2 byte oPrs and a 2 byte text offset to
;	    the opStData opcode within the prs.  This entry is created
;	    by TDataEntry when text mgr sees opStData during ASCII Load.
;
; DT_Restore - entry describes a RESTORE opcode which may or may not refer to 
;           a label within a SUB/FUNCTION's text table.
;	    It is followed by 2 byte oPrs and a 2 byte text offset to
;	    the opStRestore1 opcode.  This entry is created
;	    by TDataEntry when text mgr sees opStRestore1 during ASCII Load.
;
; DT_EndProc - entry is created when we see the end of a SUB/FUNCTION during
;	    ASCII Load.  It is followed by 2 byte oPrs and a 2 byte text offset
;	    into the module's text table, where the SUB/FUNCTION was encountered
;	    during the Load.
;
; DT_Label - entry describes a new label to be generated in the main program.
;	    This is needed because the label in the prs which was refered to
;	    by a RESTORE, may also be refered to by GOTO or GOSUB.
;	    This entry is created by TDataEnd after the Load has completed.
;
; DT_End  - marks the end of the table.
;
;-----------------------------------------------------------------------------
bdData	bd	<0,0,0>
fIgnoreTDataEntry	DB TRUE 	

CB_TDATA EQU 5				;5 bytes per entry

PUBLIC	fDataMoved
;set to TRUE every time a DATA statement is moved from a SUB to module level
fDataMoved	DB	0		

sEnd	DATA

sBegin	CP
assumes	cs,CP

;*****************************************************************************
; TDataStart
; Purpose:
;	Called at the start of ASCII Load to initialize things for movement
;	of DATA statements from prs to module.
; Exit:
;	returns al=ER_OM if out-of-memory
;	        al=0 if no error
;	        (with condition codes set accordingly)
;
;*****************************************************************************
PUBLIC	TDataStart
TDataStart PROC NEAR

; Don't allow nested calls to TDataStart
	DbAssertRelB [fIgnoreTDataEntry],ne,0,CP,<TDataStart: nested call>

	sub	ax,ax
	mov	[fIgnoreTDataEntry],al
	mov	[bdData.BD_cbLogical],ax

	PUSHI	ax,<dataOFFSET bdData>
	PUSHI	ax,CB_TDATA		;initial size of node buffer
	PUSHI	ax,<IT_NO_OWNERS>	;heap type
	call	BdAlloc
	or	ax,ax			;set condition codes for caller
	mov	al,ER_OM
	je	TDStartExit		;brif out-of-memory error
GotBd:
	mov	bx,[bdData.BD_pb]
	mov	BYTE PTR [bx],DT_End	;make table look empty
					;condition codes still based on ax
	sub	ax,ax			;no error
TDStartExit:
	or	ax,ax			;set condition codes for caller
	ret
TDataStart ENDP

;*****************************************************************************
; TDataEntry
; Purpose:
;	Called during ASCII Load every time a DATA statement
;	or a RESTORE statement is inserted into any text table.
;	It adds info about the statement to a buffer so TDataEnd
;	can move the DATA statements from prs to module at end of load.
;	Always keeps room for a new entry at end of buffer
; Entry:
;	al = DT_Data for DATA stmt, 
;	   = DT_Restore for RESTORE stmt, 
;	   = DT_EndProc for END SUB/FUNCTION stmt
;	bx = otx
;	grs.oPrsCur identifies the text table within the module
; Exit:
;	returns ax=0 (with condition codes set accordingly) if out-of-memory
;
;*****************************************************************************
PUBLIC	TDataEntry
TDataEntry PROC NEAR
DbAssertRelB [txdCur.TXD_scanState],ne,SS_EXECUTE,CP,<TDataEntry: bad scanstate>
DbAssertRelB al,ne,0,CP,<TDataEntry: called with al=0>
	;function assumes we can return al=non-zero if we don't alter ax
	FLoadActive
	je	TdExit			;brif not LOADing a file
	cmp	[fIgnoreTDataEntry],FALSE
	jne	TdExit			;brif TDataEnd is active.  TDataEnd
					; calls TxtInsUpdate, which can call
					; TDataEntry
	cmp	al,DT_Data
	jne	NotData
	test	[txdCur.TXD_flags],FTX_mrs
	jne	TdExit			;brif DATA stmt within main program
NotData:
	push	di			;save caller's di
	mov	di,[bdData.BD_pb]
	DbAssertRel di,ne,NULL,CP,<TDataEntry: no buffer>
	add	di,[bdData.BD_cbLogical]
	sub	di,CB_TDATA
	push	ds
	pop	es			;es = DGROUP
					;NOTE: al must still = TDataEntry parm
	;**********************************
	;NOTE: al still equals entry value 
	;**********************************
	stosb				;store node type
	mov	ax,[grs.GRS_oPrsCur]
	stosw				;store current prs
	xchg	ax,bx			;ax = otx
	stosw

	;make room for next entry
	PUSHI	ax,<DATAOFFSET bdData>
	PUSHI	ax,CB_TDATA
	call	BdGrow
	mov	bx,[bdData.BD_pb]
	add	bx,[bdData.BD_cbLogical]
	mov	BYTE PTR [bx - CB_TDATA],DT_End	;make table look empty
	pop	di			;restore caller's di
TdExit:
	or	ax,ax			;set condition codes for caller
	ret
TDataEntry ENDP

;*****************************************************************************
; TDataEnd
; Purpose:
;	Called at the end of an ASCII Load
;	Step1:	For each RESTORE in bdData, find the label definition.
;		If the label definition is in a prs,
;		  Generate a new unique oNam
;		  Store the new oNam in the restore opcode's operand
;		  Insert DT_Label into bdData with
;		     otx field to the label definition's otx,
;		     oPrs field to the label definition's oPrs
;		else
;		  ignore the entry
;	Step2:  For each DT_Data move the DATA opcode from the prs to
;		the mrs.  For each DT_Label entry in bdData, generate
;		an opBolLab opcode in the mrs.
;
; Exit:
;	returns al=ER_OM if out-of-memory
;	        al=0 if no error
;	        (with condition codes set accordingly)
;
;*****************************************************************************
cProc	TDataEnd,<PUBLIC,NEAR,NODATA>,<si,di>
	localW	lnCur
	localW	oPrsRestore
	localW	oNamNew
cBegin
	cmp	[fIgnoreTDataEntry],0	
	je	@F			; Redundant tDataEnd
J1_TDEndExitOk: 			
	jmp	TDEndExitOk		; Redundant tDataEnd
@@:					

	mov	[lnCur],100d
	mov	[fIgnoreTDataEntry],NOT FALSE
	mov	si,[bdData.BD_pb]
	or	si,si			; is bdData even allocated?
	jz	J1_TDEndExitOK		; brif not, nothing to do
Step1Loop:
	lodsb				;al = node type
	.errnz DT_End
	or	al,al			;test for DT_End
	je	Step1Done		;brif done with step1's pass over list
	cmp	al,DT_Restore
	jne	Step1Next		;brif not a RESTORE node
	lodsw				;ax = oPrs field (may be UNDEFINED)
	mov	[oPrsRestore],ax
	push	ax
	call	PrsActivateCP		;activate opRestore's prs

;Generate a label which has not been used in this module
UniqueLabelLoop:
	inc	[lnCur]
	mov	ax,[lnCur]		;pass line# to ONamOfLn in ax
	call	ONamOfLn		;ax = oNam for line number lnCur
	je	JE1_TdEndOmErr		;brif out-of-memory error
	mov	[oNamNew],ax		;preserve proposed oNam
	test	dl,NM_fLineNumLabel	;dl = flags byte returned by ONamOfLn
	jne	UniqueLabelLoop		;brif name is already used as label

	lodsw				;ax = otx field of opStRestore
	inc	ax			;advance to oNam operand
	inc	ax
	mov	di,ax			;di = otx to opStRestore's oNam
	call	GetWOtx			;ax = label's oNam (from opStRestore)
	call	FindLabelDef		;bx = oPrs, ax = otx of label def
					;current prs is preserved
	inc	ax
	je	Step1Loop		;brif label not found
	inc	bx			;test prs for UNDEFINED
	je	Step1Loop		;brif label defn is in mrs (no need
					; to change RESTORE's operand, we're
					; not moving DATA stmts already in mrs)
	dec	ax			;restore ax = otx
	dec	bx			;restore bx = oPrs where label's defined
	mov	cx,[oNamNew]
	call	InsertLabInTbl		;insert DT_Label entry in bdData
					; si updated if new entry inserted
					; before current si
	inc	ax			;test for UNDEFINED
	je	Step1Loop		;brif label defn is in prs with no DATA
					; stmts (we could handle this case,
					; but it is not worth the code it would
					; take)
	dec	ax			;test for 0
	je	JE1_TdEndOmErr		;brif out-of-memory error

⌨️ 快捷键说明

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