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

📄 uimain.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 3 页
字号:
	or	al,[grs.GRS_fDirect]
	je	DontReEnter
	or	[bosFlags],FBOSDEBUG	;tell executor to call UserInterface
					; at the next beginning of stmt
DontReEnter:
	;ContReinitStat needs to be called every time we exit the
	;user interface if any editing/loading took place.  It ensures
	;there is no unused space within BDs and no free space between
	;near-heap entries.  If there was any, a string allocation could fail
	;even though there is free space, because arrays of string descriptors
	;can only be moved at statement level, because the runtime
	;could have several pointers to them, i.e. x$=a$(1)+a$(2)
	
	call	ContReinitStat

;Return to the executor to execute pcode indicated by:
;grs.fDirect, grs.oRs, grs.otx.
;If the Quit menu item is selected, or the SYSTEM command is entered
;UserInterface returns to let the executor execute ExStSystem.
;Returning from this function causes the pcode-executor to begin.
;

cEnd	;UserInterface

;**************************************************************************
; EnterUserInterface()
; Purpose:
;  Enable all user interface interrupt handlers.
;
;**************************************************************************
cProc	EnterUserInterface,<PUBLIC,NEAR>
cBegin
	cmp	[fUiActive],0
	jne	EntDmExit		;brif already in user interface
	mov	[fUiActive],sp
KbLoadOk:
	cCall	DrawDebugScr		
	cCall	B$UnhookKbd		;tell runtime to disable its handler
	cCall	HookInt24		;enable interrupt-24 interrupt handler
	cCall	CwHook
	call	FlushMsgs		;flush any type-ahead keystrokes or
					; mouse clicks
EntDmExit:
	;Set the BIOS INSERT flag to match what we will be using in
	;this invocation of the UI.  This will keep us in ssync with
	;what speach software thinks our insert state is.

	xor	bx, bx
	mov	es, bx
	cli				; don't allow interrupts (might
					; change BIOS flags on us)
	mov	al, es:[417h]		; get BIOS shift state flags
	and	al, 7fh			; assume insert mode off
	cmp	fInsertMode, bl 	; is CW in an insert mode
        je      @F                      ; brif not, assumption good
	or	al, 80h			; set BIOS insert mode on
@@:
	mov	es:[417h], al		; update BIOS flags
	sti				; reenable interrupts

cEnd	;EnterUserInterface

;**************************************************************************
; ExitUserInterface()
; Purpose:
;  Unhooks all user interface interrupt handlers.
;
;**************************************************************************
cProc	ExitUserInterface,<PUBLIC,NEAR>
cBegin
	call	FlushMsgs		;flush any type-ahead keystrokes or
					; mouse clicks
DbAssertRel [fUiActive],ne,0,UI,<ExitUserInterface: not in user interface>
	mov	[fUiActive],0
	cCall	CwUnHook
	cCall	UnHookInt24
	cCall	B$hookKbd		;tell runtime to enable its handler
cEnd	;ExitUserInterface

;**************************************************************************
; DebugExecCmd
; Purpose:
;	Invoked when we enter NextStmt with DEBUG_EXEC_CMD bit set in
;	debugFlags
; Exit:
;	Returns actionFlag bit which will cause the work to get done.
;
;**************************************************************************
DebugExecCmd PROC NEAR
	mov	[grs.GRS_otxCONT],UNDEFINED
					;RUN <filename> needs otxCont UNDEFINED
					; so scanner can grow variable tables.
	mov	al,FDM_ExecCmd
	ret
DebugExecCmd ENDP

;**************************************************************************
; NextStmt
; Purpose:
;  Called by UserInterface() to determine the next opcode to be executed
;  It is only called when UserInterface has something significant to do.
;
; Entry:
;  same as for UserInterface()
;	
;**************************************************************************
.errnz	DEBUG_ERROR	- 01h
.errnz	DEBUG_EXEC_CMD	- 02h
.errnz	DEBUG_STOP	- 04h
.errnz	DEBUG_END	- 08h
.errnz	DEBUG_WATCHPOINT - 10h
.errnz	DEBUG_TRACE	- 20h
DebugDispTbl LABEL WORD
	DW	UIOFFSET DebugError
	DW	UIOFFSET DebugExecCmd
	DW	UIOFFSET DebugStop
	DW	UIOFFSET DebugEnd
	DW	UIOFFSET DebugStop
	DW	UIOFFSET DebugTrace
DebugDispTblEnd LABEL WORD

DbPub	NextStmt
cProc	NextStmt,<NEAR>
	localB	actionFlags
	localB	debugFlagsTmp
cBegin
	DbAssertRelB [cGrab],e,0,UI,<NextStmt: cGrab non-zero>
	;remember if the debug screen was visible when we entered NextStmt()
	mov	al,[debugFlags]
	mov	[debugFlagsTmp],al
	test	al,DEBUG_ERROR
	jne	GotRtErr

	;Set b$fCompErr 0 so any errors generated from within the user
	; interface don't look like they were generated in QuickLibrary.
	
	mov	[b$fCompErr],0
GotRtErr:

	;reset any variables that assume we're in same context we were
	;in last time they were set.
	
	call	UiFlushCache
	sub	ax,ax
	mov	[actionFlags],al
	mov	[debugFlags],al
	mov	[fDoCmd],ax

;  Dispatch to function based on debugFlagsTmp.  Function
;  returns ushort mask with 0 or more of FDM_xxx bits set
;  indicating what action is to be performed.
;  Function also sets various bits in debugFlagsTmp to cause
;  UserInterface to be entered after the next statement is executed.
;
;  NOTE: The order these flags are tested is IMPORTANT
;
	mov	al,[debugFlagsTmp]
	and	al,DEBUG_EXEC_CMD+DEBUG_ERROR+DEBUG_STOP+DEBUG_END+DEBUG_WATCHPOINT+DEBUG_TRACE
	je	DispRet			;brif nothing interesting
	mov	bx,UIOFFSET DebugDispTbl-2
DispLoop:
	inc	bx			;advance to next exception handler
	inc	bx
DbAssertRel bx,b,<UIOFFSET DebugDispTblEnd>,UI,<uimain.asm: Bad debugFlags>
	shr	al,1
	jnc	DispLoop
	call	cs:[bx]			;dispatch to routine based on debugFlags
					;al = bit mask of actions to carry out
DispRet:
 	mov	[actionFlags],al
 	test	al,FDM_ShowStmt
	je	TestGetCmd		;brif cursor not to be positioned
	call	EnsShowDebugScr		;make debug screen visible
	call	DoDrawDebugScr		;actually draw debug screen, can't
					; wait for next call in GetCmd() in the
					; case where user just executed a TRON
					; stmt, we don't call GetCmd at all
	call	ContContext		;activate "program counter's" context
	je	TestGetCmd		;brif can't continue & no main program

	;otx may point to beginning of next statement, get it back to current
	;map UNDEFINED,0,1,2,3,... to 0,0,0,1,2,3,...
	
	mov	ax,[grs.GRS_otxCONT]
	inc	ax			;test for UNDEFINED
	je	DoShowStmt		;if can't CONT, cur stmt is 0 of main
	dec	ax			;restore ax = otxCONT
	je	DoShowStmt		;map 0 to 0
	dec	ax			;map 1,2,... to 0,1,...
DoShowStmt:
	push	[grs.GRS_oRsCur]
	push	ax			;pass otxCur
	PUSHI	ax,UNDEFINED		;determine column from otx
	call	ShowStmt

TestGetCmd:
	;See if executor told user interface to not allow continuing.
	;This is done when it wants to show where execution stopped
	;(i.e. for error reporting) so it leaves grs.otxCur not UNDEFINED
	;on entry to UserInterface.  It is important that we not call CantCont
	;before calling ShowStmt, or else ShowStmt has nothing to show.
	
	test	[debugFlagsTmp],DEBUG_CANT_CONT
	je	CantContNotSet
	call	CantCont
	mov	[actionFlags],FDM_GetCmd
CantContNotSet:
	test	[actionFlags],FDM_GetCmd
	je	TestDoCmd

;Init debug screen if necessary, make it visible.  This is necessary
;because DEBUG_END causes FDM_GetCmd to be set, but not FDM_ShowStmt.
;Continue calling GetCmd() until we get a command which we can execute
;without errors.  GetCmd() interacts with user until user enters a
;direct-mode command (which may take the form of a menu selection, or
;accelerator key like SingleStep).
;This can cause context switches to different module and
;procedure text tables.  It also invokes the text
;manager (which invokes the parser) to alter program text.
;
GetCmdLoop:
	;Turn off CMD_SW_RUN switch in case user specified /RUN <filename>
	;in qb command line, and then got a runtime error.  This will
	;cause the SYSTEM statement to return to user interface rather than
	;terminating qb.
	
	and	[cmdSwitches],NOT CMD_SW_RUN

	call	EnsShowDebugScr
	call	EnterUserInterface	;enable userInterface interrupt handlers
	mov	[otxContProg],UNDEFINED	;since this call to GetCmd can cause
					; editing, and otxContProg isn't updated
					; for pcode movement, we can't depend
					; on it after this call.
	call	GetCmd
	call	WatchInfoUI		;update cWatch if necessary
WatchWnOk:
	call	ExitUserInterface	;restore runtime's interrupt handlers

;Make sure TxtDirect and SystemScan are unable to tie up so much
;variable table space that we are unable to execute very simple
;direct mode statements.  This block of memory will be freed
;by UiReleaseSpace below.  Be very careful when changing control
;flow below this point that all UiGrabSpace calls are balanced by
;UiReleaseSpace calls.
TestDoCmd:
	call	UiGrabSpace		; UiGrabSpace can take a lot of time...
					; slows down tracing, and WATCH (when
					; debug screen is visible)
	cmp	[fDoCmd],0		; fDoCmd can only be set as a result
					;  of calling GetCmd().  It is not
					;  set as a if user wants to TRACE
	je	NoDirect		; brif all scanned and ready to execute
					;  (speed optimization for WATCH/TRACE)
	mov	[fDoCmd],0
	call	ContContext		;activate "program counter's" context
					; for TxtDirect
	call	TxtDirect		;Now parse & scan direct mode statement
	mov	ax,[grs.GRS_otxCONT]
	mov	[otxContProg],ax
	jmp	SHORT CheckErr

;no direct mode stmt (we're tracing), just scan all text tables
;and set current context to grs.otxCONT
NoDirect:
	call	SystemScan
	test	[actionFlags],FDM_ExecCmd
	je	NoExecCmd

	;some executor setup direct mode buffer, i.e. ExRunFile
	;loaded program and put ExRunMain in grs.bdlDirect
	
	cmp	[txtErr.TXER_errCode],0
	jne	CheckErr		;dont set otxCONT if scan error
	mov	ax,[grs.GRS_oMrsMain]
	mov	[grs.GRS_oRsCONT],ax
	push	ax
	call	UiRsActivate		;activate oRs to continue
	sub	ax,ax
	mov	[grs.GRS_otxCur],ax
	mov	[grs.GRS_otxCONT],ax	;ExStChain causes ExStCont to be
					; invoked, which needs otxCONT=0
	dec	ax
	mov	[grs.GRS_fDirect],al	;execute pcode out of direct mode buf

	;If we were tracing when we entered with DEBUG_EXEC_CMD,
	; continue tracing.  The only reason we entered DirectMode
	; was to SystemScan and report errors.
	
	mov	al,[debugFlagsTmp]
	and	al,DEBUG_TRACE
	or	[debugFlags],al
	jmp	SHORT CheckErr		;report any parser/scanner errors

NoExecCmd:
	call	NeedContContext		;activate "program counter's" context
					; if no main module, uierr is set
	je	SHORT GetNextCmd	;brif CONT is not possible

;now see if TxtDirect/SystemScan encountered any errors
CheckErr:
	mov	ax,[txtErr.TXER_errCode]
	or	ax,ax
	jne	CmdErr			;brif parser/scanner errors

	;We could get here without having called UiGrabSpace (if we were
	;tracing, and all text tables were already scanned to SS_EXECUTE)
	;If we didn't call UiGrabSpace, we are guarenteed that cGrab=0
	;by assertion at entry of NextStmt().
	
	cmp	[cGrab],0
	je	NoneGrabbed1
	call	UiReleaseSpace
NoneGrabbed1:
cEnd	;NextStmt

CmdErr:
	inc	ax			;test for UNDEFINED
	je	GetNextCmd		;brif user wants to back out of cmd
					; because it would prevent CONT
	dec	ax			;restore ax=errCode
	mov	[uierr],ax		;remember to report error in GetCmd's
GetNextCmd:				; structure txtErr.xxx
	call	UiReleaseSpace		;at this point, we know we called
					; UiGrabSpace.  Release it
	jmp	GetCmdLoop

;*********************************************************************
; AskCantCont()
;
; Purpose:
;  AskCantCont() is called by TextMgr when it is about to make an
;  edit which would prevent continuing program execution.
;  This function should not be called during exection.	It is not
;  valid (or useful) while the executor is in operation.
;  If already impossible to continue (i.e. grs.otxCONT ==
;     UNDEFINED) AskCantCont returns TRUE.  Otherwise, the user is warned
;     with a dialog box that this edit will prevent continuing.
;  If the user says OK, grs.otxCONT is set to UNDEFINED
;     and the context manager's CantCont() is called (which
;     sets grs.otxCONT to UNDEFINED among other things.
;     AskCantCont() then returns TRUE.
;  If the user says CANCEL, the Debug screen is refreshed (discarding
;     the current edit) and AskCantCont() returns FALSE.
;
; Exit:
;  Returns FALSE if user wants to abort current edit, with
;  condition codes set based on value in ax.
;
;*********************************************************************
cProc	AskCantCont,<PUBLIC,FAR>
cBegin
	call	fCanContUI
	je	AcCantCont		;brif already can't continue

	;display "This will prevent CONT, proceed anyway?"
	PUSHI	ax,MB_OKCANCEL
	PUSHI	ax,MSG_CantCont
	call	MsgBoxStd
	cmp	al,IDOK
	mov	ax,0			;prepare to return FALSE
	jne	AcExit			; brif user wants to backout of edit
	call	CantCont		;disable CONT
AcCantCont:
	mov	ax,sp			;return TRUE
AcExit:
	or	ax,ax			;set condition codes for caller
cEnd	;AskCantCont

;*********************************************************************
; AskMakeRem()
; Purpose:
;  The user tried to insert a blank line before a SUB/FUNCTION line.
;  This would cause us grief when we tried to ASCII save/load the
;  file, because blank lines delimit the block of comments that are
;  to remain with the SUB/FUNCTION.  The case where this is important
;  is when the user has a module with no module level code, but still
;  wants to have a block of comments at module-level.
;  If we allowed blank lines in the block of comments that we move
;  into the SUB during ASCII load, this block of module comments
;  would be moved as well.
;
; Exit:
;  Returns FALSE if user wants to abort current edit, with
;  condition codes set based on value in ax.
;
;*********************************************************************
cProc	AskMakeRem,<PUBLIC,FAR>
cBegin
	;"Blank lines not allowed before SUB/FUNCTION line.  Is remark ok?"
	PUSHI	ax,MB_OKCANCEL
	PUSHI	ax,MSG_MakeRem
	call	MsgBoxStd
	sub	ax,IDCANCEL		;ax=0 if user said CANCEL
cEnd

;*********************************************************************
; NotSaved(), NotSavedInc(), NotSavedIncSav()
;
; Purpose:
;  Called by Context Mgr's NewStmt and SYSTEM executor when it is about

⌨️ 快捷键说明

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