uimain.asm
上传用户:xiaoan1112
上传日期:2013-04-11
资源大小:19621k
文件大小:40k
源码类别:

操作系统开发

开发平台:

Visual C++

  1. TITLE uimain.asm - BASIC's top level interface to user interface.
  2. ;***
  3. ;uimain.asm
  4. ;
  5. ; Copyright <C> 1985-1988, Microsoft Corporation
  6. ;
  7. ;Purpose:
  8. ; Main user interface, and support routines.
  9. ;
  10. ;
  11. ;*******************************************************************************
  12. include version.inc
  13. UIMAIN_ASM = ON
  14. ;Next, include COW's interface headers
  15. include cw/version.inc
  16. include cw/windows.inc
  17. include cw/edityp.inc
  18. ;Next, include QBI's headers
  19. includeOnce architec
  20. includeOnce context
  21. includeOnce executor
  22. includeOnce heap
  23. includeOnce parser
  24. includeOnce qbimsgs
  25. includeOnce rtinterp
  26. includeOnce txtmgr
  27. includeOnce ui
  28. includeOnce uiint
  29. includeOnce uimenu
  30. assumes ds,DATA
  31. assumes ss,DATA
  32. assumes es,NOTHING
  33. ; external procedures used by uictl
  34. externFP EnableMenuItem 
  35. externFP CheckMenuItem
  36. externNP fCanContUI
  37. externNP GetEditLine
  38. externFP SetBlinkBit
  39. IFNDEF ROMBASIC
  40.         externFP FCheckTandy1000
  41. ENDIF
  42. ;Runtime supplied functions used by this module:
  43. EXTRN B$UnhookKbd:FAR
  44. EXTRN B$hookKbd:FAR
  45. sBegin DATA
  46. externW fIsProgram 
  47. externB fPasteOK
  48. externB fSyntaxCheck
  49. externW cWatch
  50. externB fInsertMode ;EditMgr insert state.
  51. EXTRN b$fCompErr:word ;non-zero if error was in compiled code
  52. EXTRN fRefreshWatch:byte ;non-zero if WATCH window needs to
  53. ; be refreshed
  54. externW szDialogTitle ; * current dialog box title, or
  55. ; 0 if no title.
  56. ;fUiActive is TRUE when user-interface keyboard and mouse interrupt
  57. ;handlers are active.
  58. PUBLIC  fUiActive
  59. fUiActive dw 0
  60. fUIInit  db 0 ; non-zero if UI Initialized.
  61. ;When we can CONTinue, and we execute a direct mode stmt that causes a ret
  62. ; adr to the direct mode buffer to be pushed on the stack (call/gosub/func),
  63. ; and then enter direct mode to save the otx of the called routine, we save the
  64. ; old grs.otxCont in otxContProg, so that after the direct mode call finishes,
  65. ; we can still CONTinue the stopped program.
  66. ;This variable gets set to UNDEFINED if we do any EDITs (because otxContProg
  67. ; isn't updated as pcode is moved by the text mgr and static-scanner).
  68. ;It is also set to UNDEFINED if we execute another direct mode stmt
  69. ; while there is a return address to the direct mode buffer on the stack,
  70. ; because we choose not to remember an arbitrary number of these, and
  71. ; it would be difficult for the user to keep track of them anyway.
  72. ;TxtDirect guarentees that if user enters a direct mode statement
  73. ; while there is a return address to the direct-mode-buffer on the
  74. ; stack (FG_RetDir), that CantCont will occur.
  75. ;
  76. otxContProg DW UNDEFINED
  77. cGrab db 0 ;number of active callers of UiGrabSpace
  78. sEnd DATA
  79. sBegin UI
  80. assumes cs,UI
  81. ;**************************************************************************
  82. ; UiInit
  83. ; Purpose:
  84. ; In QB, the RUNTIME gets control first (since in stand-alone EXEs
  85. ; there is no user-interface).  This is called after the runtime
  86. ; has initialized.  It initializes the user interface.
  87. ; Entry:
  88. ; cmdSwitches has flags set to indicate command-line switch settings
  89. ; Exit:
  90. ; the file QB.INI is read
  91. ; If command line didn't contain /RUN <filename>, the debug screen
  92. ;    is shown.
  93. ; AX nonzero if Out of Memory
  94. ;
  95. ;**************************************************************************
  96. cProc UiInit,<PUBLIC,FAR>
  97. cBegin
  98. ; Set colors at beginning so first screen writes are the same color.
  99. call ReadQbIni
  100. call B$UnhookKbd
  101. IFNDEF ROMBASIC
  102.         call    FCheckTandy1000         ;check for/install TANDY 1000 KBD
  103. ENDIF
  104. call CwInit
  105. call B$HookKbd
  106. test [cmdSwitches],CMD_SW_RUN ;/RUN filename given on command line?
  107. jnz NoDebugScr ;  brif so, no debug screen
  108. call EnsShowDebugScr
  109. NoDebugScr:
  110. call GrabSpace ;make sure we can successfully
  111. or ax,ax ;  GrabSpace (ax = 0 if failed)
  112. not ax ;0 -> -1 if failed, preserves flags
  113. jz UiInitExit ;brif failure, exit with ax<>0
  114. call ReleaseSpace ;release what we grabbed
  115. xor ax,ax ;exit with ax = 0 for success
  116. UiInitExit:
  117. inc fUIInit  ;indicate UiInit complete
  118. cEnd
  119. ;**************************************************************************
  120. ; UiTerm
  121. ; Purpose:
  122. ;    Called just before we are about to leave the QB for good.
  123. ;    Calls COW and KKIF to tell it to terminate.
  124. ;
  125. ;    Also called before a SHELL is performed.  The runtime calls
  126. ;    this routine prior to SHELL, or at termination.  After a SHELL,
  127. ;    The runtime calls UiReInit so COW can re-initialize.
  128. ; Entry:
  129. ; Exit:
  130. ;
  131. ;**************************************************************************
  132. cProc UiTerm,<PUBLIC,FAR>
  133. cBegin
  134. cmp fUIInit,0 ; were we ever initialized?
  135. jz UTExit ; brif not, exit now
  136. cCall WriteQbIni ; write the qb.ini file
  137. cCall CwTerm
  138. mov al, 1
  139. cCall SetBlinkBit,<ax>
  140. UTExit:
  141. cEnd
  142. ;**************************************************************************
  143. ; UiReInit
  144. ; Purpose:
  145. ; In QB, the RUNTIME needs to reinitialize the user interface
  146. ; at certain points (primarily after SHELL).  This entry point
  147. ; allows the user interface to reestablish any state (such as
  148. ; hooking interrupts) that is necessary.
  149. ; Entry:
  150. ; none.
  151. ; Exit:
  152. ; none.
  153. ;
  154. ;**************************************************************************
  155. cProc UiReInit,<PUBLIC,FAR>
  156. cBegin
  157. cEnd
  158. ;**************************************************************************
  159. ; UiPause
  160. ; Purpose:
  161. ;    Added with [24].
  162. ;    Called before a SHELL is performed.  The runtime calls
  163. ;    this routine prior to SHELL, or at termination.  After a SHELL,
  164. ;    The runtime calls UiReInit so COW can re-initialize.
  165. ; Entry:
  166. ; Exit:
  167. ;
  168. ;**************************************************************************
  169. cProc UiPause,<PUBLIC,FAR>
  170. cBegin
  171. cEnd
  172. ;**************************************************************************
  173. ; UserInterface()
  174. ; Purpose:
  175. ;  UserInterface() is the primary interface the user-interface
  176. ;  provides to the rest of BASIC.
  177. ;  It is called by the beginning-of-statement/line
  178. ;  executor when it sees bosMask & BOS_DEBUG non-zero,
  179. ;  by opEot and opStEnd (end-of-program), opBreakPoint, and opStStop.
  180. ;
  181. ;  For example, if tracing was active for the program:
  182. ;    CLS : PRINT
  183. ;    STOP
  184. ;  UserInterface would be invoked between the opcodes seperated by '^':
  185. ;    opBol ^ opStCls opBos ^ opBreakPoint ^ opStPrint opBol ^ opStStop ^ opEot ^
  186. ;
  187. ; Entry:
  188. ;  grs.oRsCur, otxCur identify the next statement to be executed.
  189. ;  If grs.otxCur == UNDEFINED, it means we've just executed an ExEot,
  190. ;     and thus cannot continue.  Otherwise, it points just beyond the
  191. ;     ExBos opcode which caused UserInterface to be called.
  192. ;  If the parser's input buffer (ps.bdpSrc) contains any text, that
  193. ;     text is executed as if the user entered it as a direct mode stmt.
  194. ;     This allows executors like RUN <filename> to load the file, then
  195. ;     re-invoke UserInterface after stuffing the command "RUN" in the
  196. ;     parser's input buffer.  This allows there to be only 1 control path
  197. ;     to scan all loaded text tables.
  198. ;
  199. ;  The actions performed by UserInterface() are determined by which
  200. ;  bits are set in debugFlags as follows:
  201. ;
  202. ;  DEBUG_EXEC_CMD - set by some executor like RUN <file>/CHAIN <file>,
  203. ;     which has loaded pcode, and now wants the pcode to be scanned
  204. ;     and a direct mode statement executed (like RUN or CONT).  The
  205. ;     executor for the direct mode stmt has been loaded into grs.bdlDirect.
  206. ;
  207. ;  DEBUG_ERROR - set when a runtime error occurs and
  208. ;     is not trapped.  The runtime error code restores SI to
  209. ;     the beginning of statement, sets this flag, then re-
  210. ;     executes the statement, which invokes the debugger.
  211. ;     The error code is passed in the same static variable
  212. ;     examined by the ERR intrinsic function.  Causes
  213. ;     DebugError() to be invoked.
  214. ;
  215. ;  DEBUG_STOP - set when a STOP statement is executed,
  216. ;     when Ctrl-BREAK is pressed and not trapped, or
  217. ;     when a breakpoint is executed.
  218. ;     Causes DebugStop() to be invoked.
  219. ;
  220. ;  DEBUG_WATCHPOINT - set when a Stop-Watch-Expression evaluates to TRUE
  221. ;     Causes DebugStop() to be invoked.
  222. ;
  223. ;  DEBUG_END - set by the executors for opEot and
  224. ;     opStEnd to indicate end-of-program.  Causes DebugEnd()
  225. ;     to be invoked.
  226. ;
  227. ;  DEBUG_TRACE - set while tracing statement execution
  228. ;     either because of TRON, single-step, or procedure-
  229. ;     step.  Causes DebugTrace() to be invoked.
  230. ;
  231. ;  DEBUG_WATCH - set when any Watch Expressions are
  232. ;     active in the program.  Causes DebugWatch() to be invoked.
  233. ;
  234. ;  DEBUG_CANT_CONT - Causes UserInterface() to set grs.otxCONT to
  235. ;     UNDEFINED the next time it is called.
  236. ;     This is used by executors, which cannot call CantCont
  237. ;     because UserInterface sets grs.otxCONT every time
  238. ;     we enter UserInterface, thus undoing their change.
  239. ;     Since it sets otxCONT rather than calling CantCont(),
  240. ;     stack tracing and variable printing are still possible
  241. ;     from direct mode, just not continuing.
  242. ;
  243. ; Exit:
  244. ; grs.fDirect, grs.oRsCur, grs.otxCur indicate where pcode
  245. ;    execution is to commence
  246. ;
  247. ;**************************************************************************
  248. cProc UserInterface,<PUBLIC,FAR>
  249. cBegin
  250. DbAssertRelB [cGrab],e,0,UI,<UserInterface: cGrab non-zero>
  251. test [debugFlags],DEBUG_WATCH
  252. je NoWatch ;brif no WATCH expressions visible
  253. call DebugWatch ;get next watch expression, or
  254. ; normal program pcode
  255. jne J1_TestRestore ;brif the next pcode to be executed
  256. ; is WATCH pcode, DebugWatch has
  257. ; set grs up so it's ready to go
  258. cmp [fDebugScr],FALSE
  259. jne NoWatch ;brif debug screen is visible
  260. ; need to print values in watch window
  261. test [debugFlags],NOT DEBUG_WATCH
  262. jne NoWatch ;brif WATCH isn't only thing to do
  263. ;speeds up WATCHPOINTs significantly
  264. J1_TestRestore:
  265. jmp SHORT TestRestore
  266. ;If we didn't care about Watch functions that write to the screen
  267. ; we could branch to ExecStmt and be faster, but since most watchpoints
  268. ; are handled by the executor calling DebugWatch directly, the only
  269. ; watch points we are slowing down are when the debug screen is active.
  270. NoWatch:
  271. cmp [grs.GRS_fDirect],FALSE
  272. je NotInDirect ;brif not executing direct mode stmts
  273. ;Following test prevents tracing statements in direct mode.
  274. test [debugFlags],NOT (DEBUG_TRACE OR DEBUG_WATCH)
  275. je GotNextStmt ;brif nothing other than TRACE/WATCH
  276. ;We've returned to direct mode, potentially after having debugged
  277. ;a GOSUB/SUB/FUNCTION/DEF FN.  If we don't set otxCur to
  278. ;otxContProg, we'd show the RETURN or END DEF/SUB/FUNCTION
  279. ;stmt as the next stmt to be executed, instead of the statement
  280. ;that was active before the direct mode statement executed.
  281. mov ax,[otxContProg]
  282. mov [grs.GRS_otxCur],ax ;will be stored in grs.otxCONT
  283. NotInDirect:
  284. ;we were not executing in direct mode, setup for CONT executor.
  285. ;If grs.otxCur == UNDEFINED (as set by opEot), we cannot continue
  286. cmp [debugFlags],0
  287. je GotNextStmt ;brif nothing to do.  This is true
  288. ;for the 1st non-direct-mode-buffer
  289. ;pcode we execute.  Once we branch
  290. ;out of the direct mode buffer,
  291. ;there's no need to call UserInterface
  292. ;between statements.
  293. mov ax,[grs.GRS_oRsCur]
  294. mov [grs.GRS_oRsCONT],ax
  295. test [txdCur.TXD_flags],FTX_mrs
  296. je NotInDefFn ;brif definately not within a DEF FN
  297. mov ax,[grs.GRS_oMrsCur]
  298. NotInDefFn:
  299. mov [grs.GRS_oRsContTxtTbl],ax
  300. mov ax,[grs.GRS_otxCur]
  301. mov [grs.GRS_otxCONT],ax
  302. GetNextStmt:
  303. ;Call NextStmt() to determine what stmt should be executed next.
  304. ;NextStmt() may interact with user, letting user edit program etc.
  305. call NextStmt
  306. ;If user added or removed a WATCH expression, we need to refresh
  307. ;the values in the Watch window.
  308. cmp [fRefreshWatch],FALSE
  309. je GotNextStmt
  310. mov [fRefreshWatch],FALSE
  311. call DebugWatch
  312. je GetNextStmt ;brif can't execute WATCH pcode
  313. ; for any reason
  314. GotNextStmt:
  315. cmp [cWatch],0
  316. je TestRestore ;brif no WATCH expressions are active
  317. or [debugFlags],DEBUG_WATCH; tell Executor to call UserInterface
  318. ; after executing next statement
  319. ;The reason we enter direct mode for each statement, regardless of
  320. ;the state of debugFlags, is so we can toggle to the output screen
  321. ;for direct mode lines like:
  322. ;    FOR I=1 TO 10: PRINT A(I): NEXT I
  323. ;but leave the debug screen active for direct mode lines like:
  324. ;    FOR I=1 TO 10: A(I) = 1: NEXT I
  325. ;
  326. ;Make the output screen visible IF:
  327. ; we're tracing or watching variables AND next stmt does screen I/O OR
  328. ; we're NOT tracing or watching variables AND next stmt is in program
  329. ;   (as opposed to direct mode statement buffer)
  330. ;
  331. TestRestore:
  332. cmp [fDebugScr],FALSE
  333. je ExecStmt ;brif output screen already visible
  334. ;If this test is removed, callers
  335. ;who set DebugFlags.DEBUG_EXEC_CMD
  336. ;need to put an ExEot in bdlDirect
  337. ;for FNextStmtDoesIO
  338. test [debugFlags],DEBUG_WATCH OR DEBUG_TRACE
  339. jne TestForIO ;brif we're watching or tracing
  340. cmp [grs.GRS_fDirect],FALSE
  341. je ShowUserScr ;brif not executing direct mode stmts
  342. TestForIO:
  343. call FNextStmtDoesIO
  344. or ax,ax
  345. je ExecStmt ;brif next stmt causes no screen I/O
  346. ShowUserScr:
  347. call EnsShowOutSaveRs ;show output screen, don't alter
  348. ; grs.oRsCur
  349. ExecStmt:
  350. ;***** Begin revision [17]
  351. ;Clear FBOSSTOP in bosFlags now, because we have just had the
  352. ;chance to responde to it so if it is still set it is because
  353. ;we stopped for some other reason.  There for, the FBOSSTOP
  354. ;has already been serviced.
  355. and [bosFlags], NOT FBOSSTOP
  356. ;***** End revision [17]
  357. ;If we are debugging or we are executing a direct mode statement,
  358. ;make sure we re-enter user interface for each opBos.
  359. mov al,[debugFlags]
  360. or al,[grs.GRS_fDirect]
  361. je DontReEnter
  362. or [bosFlags],FBOSDEBUG ;tell executor to call UserInterface
  363. ; at the next beginning of stmt
  364. DontReEnter:
  365. ;ContReinitStat needs to be called every time we exit the
  366. ;user interface if any editing/loading took place.  It ensures
  367. ;there is no unused space within BDs and no free space between
  368. ;near-heap entries.  If there was any, a string allocation could fail
  369. ;even though there is free space, because arrays of string descriptors
  370. ;can only be moved at statement level, because the runtime
  371. ;could have several pointers to them, i.e. x$=a$(1)+a$(2)
  372. call ContReinitStat
  373. ;Return to the executor to execute pcode indicated by:
  374. ;grs.fDirect, grs.oRs, grs.otx.
  375. ;If the Quit menu item is selected, or the SYSTEM command is entered
  376. ;UserInterface returns to let the executor execute ExStSystem.
  377. ;Returning from this function causes the pcode-executor to begin.
  378. ;
  379. cEnd ;UserInterface
  380. ;**************************************************************************
  381. ; EnterUserInterface()
  382. ; Purpose:
  383. ;  Enable all user interface interrupt handlers.
  384. ;
  385. ;**************************************************************************
  386. cProc EnterUserInterface,<PUBLIC,NEAR>
  387. cBegin
  388. cmp [fUiActive],0
  389. jne EntDmExit ;brif already in user interface
  390. mov [fUiActive],sp
  391. KbLoadOk:
  392. cCall DrawDebugScr
  393. cCall B$UnhookKbd ;tell runtime to disable its handler
  394. cCall HookInt24 ;enable interrupt-24 interrupt handler
  395. cCall CwHook
  396. call FlushMsgs ;flush any type-ahead keystrokes or
  397. ; mouse clicks
  398. EntDmExit:
  399. ;Set the BIOS INSERT flag to match what we will be using in
  400. ;this invocation of the UI.  This will keep us in ssync with
  401. ;what speach software thinks our insert state is.
  402. xor bx, bx
  403. mov es, bx
  404. cli ; don't allow interrupts (might
  405. ; change BIOS flags on us)
  406. mov al, es:[417h] ; get BIOS shift state flags
  407. and al, 7fh ; assume insert mode off
  408. cmp fInsertMode, bl  ; is CW in an insert mode
  409.         je      @F                      ; brif not, assumption good
  410. or al, 80h ; set BIOS insert mode on
  411. @@:
  412. mov es:[417h], al ; update BIOS flags
  413. sti ; reenable interrupts
  414. cEnd ;EnterUserInterface
  415. ;**************************************************************************
  416. ; ExitUserInterface()
  417. ; Purpose:
  418. ;  Unhooks all user interface interrupt handlers.
  419. ;
  420. ;**************************************************************************
  421. cProc ExitUserInterface,<PUBLIC,NEAR>
  422. cBegin
  423. call FlushMsgs ;flush any type-ahead keystrokes or
  424. ; mouse clicks
  425. DbAssertRel [fUiActive],ne,0,UI,<ExitUserInterface: not in user interface>
  426. mov [fUiActive],0
  427. cCall CwUnHook
  428. cCall UnHookInt24
  429. cCall B$hookKbd ;tell runtime to enable its handler
  430. cEnd ;ExitUserInterface
  431. ;**************************************************************************
  432. ; DebugExecCmd
  433. ; Purpose:
  434. ; Invoked when we enter NextStmt with DEBUG_EXEC_CMD bit set in
  435. ; debugFlags
  436. ; Exit:
  437. ; Returns actionFlag bit which will cause the work to get done.
  438. ;
  439. ;**************************************************************************
  440. DebugExecCmd PROC NEAR
  441. mov [grs.GRS_otxCONT],UNDEFINED
  442. ;RUN <filename> needs otxCont UNDEFINED
  443. ; so scanner can grow variable tables.
  444. mov al,FDM_ExecCmd
  445. ret
  446. DebugExecCmd ENDP
  447. ;**************************************************************************
  448. ; NextStmt
  449. ; Purpose:
  450. ;  Called by UserInterface() to determine the next opcode to be executed
  451. ;  It is only called when UserInterface has something significant to do.
  452. ;
  453. ; Entry:
  454. ;  same as for UserInterface()
  455. ;
  456. ;**************************************************************************
  457. .errnz DEBUG_ERROR - 01h
  458. .errnz DEBUG_EXEC_CMD - 02h
  459. .errnz DEBUG_STOP - 04h
  460. .errnz DEBUG_END - 08h
  461. .errnz DEBUG_WATCHPOINT - 10h
  462. .errnz DEBUG_TRACE - 20h
  463. DebugDispTbl LABEL WORD
  464. DW UIOFFSET DebugError
  465. DW UIOFFSET DebugExecCmd
  466. DW UIOFFSET DebugStop
  467. DW UIOFFSET DebugEnd
  468. DW UIOFFSET DebugStop
  469. DW UIOFFSET DebugTrace
  470. DebugDispTblEnd LABEL WORD
  471. DbPub NextStmt
  472. cProc NextStmt,<NEAR>
  473. localB actionFlags
  474. localB debugFlagsTmp
  475. cBegin
  476. DbAssertRelB [cGrab],e,0,UI,<NextStmt: cGrab non-zero>
  477. ;remember if the debug screen was visible when we entered NextStmt()
  478. mov al,[debugFlags]
  479. mov [debugFlagsTmp],al
  480. test al,DEBUG_ERROR
  481. jne GotRtErr
  482. ;Set b$fCompErr 0 so any errors generated from within the user
  483. ; interface don't look like they were generated in QuickLibrary.
  484. mov [b$fCompErr],0
  485. GotRtErr:
  486. ;reset any variables that assume we're in same context we were
  487. ;in last time they were set.
  488. call UiFlushCache
  489. sub ax,ax
  490. mov [actionFlags],al
  491. mov [debugFlags],al
  492. mov [fDoCmd],ax
  493. ;  Dispatch to function based on debugFlagsTmp.  Function
  494. ;  returns ushort mask with 0 or more of FDM_xxx bits set
  495. ;  indicating what action is to be performed.
  496. ;  Function also sets various bits in debugFlagsTmp to cause
  497. ;  UserInterface to be entered after the next statement is executed.
  498. ;
  499. ;  NOTE: The order these flags are tested is IMPORTANT
  500. ;
  501. mov al,[debugFlagsTmp]
  502. and al,DEBUG_EXEC_CMD+DEBUG_ERROR+DEBUG_STOP+DEBUG_END+DEBUG_WATCHPOINT+DEBUG_TRACE
  503. je DispRet ;brif nothing interesting
  504. mov bx,UIOFFSET DebugDispTbl-2
  505. DispLoop:
  506. inc bx ;advance to next exception handler
  507. inc bx
  508. DbAssertRel bx,b,<UIOFFSET DebugDispTblEnd>,UI,<uimain.asm: Bad debugFlags>
  509. shr al,1
  510. jnc DispLoop
  511. call cs:[bx] ;dispatch to routine based on debugFlags
  512. ;al = bit mask of actions to carry out
  513. DispRet:
  514.   mov [actionFlags],al
  515.   test al,FDM_ShowStmt
  516. je TestGetCmd ;brif cursor not to be positioned
  517. call EnsShowDebugScr ;make debug screen visible
  518. call DoDrawDebugScr ;actually draw debug screen, can't
  519. ; wait for next call in GetCmd() in the
  520. ; case where user just executed a TRON
  521. ; stmt, we don't call GetCmd at all
  522. call ContContext ;activate "program counter's" context
  523. je TestGetCmd ;brif can't continue & no main program
  524. ;otx may point to beginning of next statement, get it back to current
  525. ;map UNDEFINED,0,1,2,3,... to 0,0,0,1,2,3,...
  526. mov ax,[grs.GRS_otxCONT]
  527. inc ax ;test for UNDEFINED
  528. je DoShowStmt ;if can't CONT, cur stmt is 0 of main
  529. dec ax ;restore ax = otxCONT
  530. je DoShowStmt ;map 0 to 0
  531. dec ax ;map 1,2,... to 0,1,...
  532. DoShowStmt:
  533. push [grs.GRS_oRsCur]
  534. push ax ;pass otxCur
  535. PUSHI ax,UNDEFINED ;determine column from otx
  536. call ShowStmt
  537. TestGetCmd:
  538. ;See if executor told user interface to not allow continuing.
  539. ;This is done when it wants to show where execution stopped
  540. ;(i.e. for error reporting) so it leaves grs.otxCur not UNDEFINED
  541. ;on entry to UserInterface.  It is important that we not call CantCont
  542. ;before calling ShowStmt, or else ShowStmt has nothing to show.
  543. test [debugFlagsTmp],DEBUG_CANT_CONT
  544. je CantContNotSet
  545. call CantCont
  546. mov [actionFlags],FDM_GetCmd
  547. CantContNotSet:
  548. test [actionFlags],FDM_GetCmd
  549. je TestDoCmd
  550. ;Init debug screen if necessary, make it visible.  This is necessary
  551. ;because DEBUG_END causes FDM_GetCmd to be set, but not FDM_ShowStmt.
  552. ;Continue calling GetCmd() until we get a command which we can execute
  553. ;without errors.  GetCmd() interacts with user until user enters a
  554. ;direct-mode command (which may take the form of a menu selection, or
  555. ;accelerator key like SingleStep).
  556. ;This can cause context switches to different module and
  557. ;procedure text tables.  It also invokes the text
  558. ;manager (which invokes the parser) to alter program text.
  559. ;
  560. GetCmdLoop:
  561. ;Turn off CMD_SW_RUN switch in case user specified /RUN <filename>
  562. ;in qb command line, and then got a runtime error.  This will
  563. ;cause the SYSTEM statement to return to user interface rather than
  564. ;terminating qb.
  565. and [cmdSwitches],NOT CMD_SW_RUN
  566. call EnsShowDebugScr
  567. call EnterUserInterface ;enable userInterface interrupt handlers
  568. mov [otxContProg],UNDEFINED ;since this call to GetCmd can cause
  569. ; editing, and otxContProg isn't updated
  570. ; for pcode movement, we can't depend
  571. ; on it after this call.
  572. call GetCmd
  573. call WatchInfoUI ;update cWatch if necessary
  574. WatchWnOk:
  575. call ExitUserInterface ;restore runtime's interrupt handlers
  576. ;Make sure TxtDirect and SystemScan are unable to tie up so much
  577. ;variable table space that we are unable to execute very simple
  578. ;direct mode statements.  This block of memory will be freed
  579. ;by UiReleaseSpace below.  Be very careful when changing control
  580. ;flow below this point that all UiGrabSpace calls are balanced by
  581. ;UiReleaseSpace calls.
  582. TestDoCmd:
  583. call UiGrabSpace ; UiGrabSpace can take a lot of time...
  584. ; slows down tracing, and WATCH (when
  585. ; debug screen is visible)
  586. cmp [fDoCmd],0 ; fDoCmd can only be set as a result
  587. ;  of calling GetCmd().  It is not
  588. ;  set as a if user wants to TRACE
  589. je NoDirect ; brif all scanned and ready to execute
  590. ;  (speed optimization for WATCH/TRACE)
  591. mov [fDoCmd],0
  592. call ContContext ;activate "program counter's" context
  593. ; for TxtDirect
  594. call TxtDirect ;Now parse & scan direct mode statement
  595. mov ax,[grs.GRS_otxCONT]
  596. mov [otxContProg],ax
  597. jmp SHORT CheckErr
  598. ;no direct mode stmt (we're tracing), just scan all text tables
  599. ;and set current context to grs.otxCONT
  600. NoDirect:
  601. call SystemScan
  602. test [actionFlags],FDM_ExecCmd
  603. je NoExecCmd
  604. ;some executor setup direct mode buffer, i.e. ExRunFile
  605. ;loaded program and put ExRunMain in grs.bdlDirect
  606. cmp [txtErr.TXER_errCode],0
  607. jne CheckErr ;dont set otxCONT if scan error
  608. mov ax,[grs.GRS_oMrsMain]
  609. mov [grs.GRS_oRsCONT],ax
  610. push ax
  611. call UiRsActivate ;activate oRs to continue
  612. sub ax,ax
  613. mov [grs.GRS_otxCur],ax
  614. mov [grs.GRS_otxCONT],ax ;ExStChain causes ExStCont to be
  615. ; invoked, which needs otxCONT=0
  616. dec ax
  617. mov [grs.GRS_fDirect],al ;execute pcode out of direct mode buf
  618. ;If we were tracing when we entered with DEBUG_EXEC_CMD,
  619. ; continue tracing.  The only reason we entered DirectMode
  620. ; was to SystemScan and report errors.
  621. mov al,[debugFlagsTmp]
  622. and al,DEBUG_TRACE
  623. or [debugFlags],al
  624. jmp SHORT CheckErr ;report any parser/scanner errors
  625. NoExecCmd:
  626. call NeedContContext ;activate "program counter's" context
  627. ; if no main module, uierr is set
  628. je SHORT GetNextCmd ;brif CONT is not possible
  629. ;now see if TxtDirect/SystemScan encountered any errors
  630. CheckErr:
  631. mov ax,[txtErr.TXER_errCode]
  632. or ax,ax
  633. jne CmdErr ;brif parser/scanner errors
  634. ;We could get here without having called UiGrabSpace (if we were
  635. ;tracing, and all text tables were already scanned to SS_EXECUTE)
  636. ;If we didn't call UiGrabSpace, we are guarenteed that cGrab=0
  637. ;by assertion at entry of NextStmt().
  638. cmp [cGrab],0
  639. je NoneGrabbed1
  640. call UiReleaseSpace
  641. NoneGrabbed1:
  642. cEnd ;NextStmt
  643. CmdErr:
  644. inc ax ;test for UNDEFINED
  645. je GetNextCmd ;brif user wants to back out of cmd
  646. ; because it would prevent CONT
  647. dec ax ;restore ax=errCode
  648. mov [uierr],ax ;remember to report error in GetCmd's
  649. GetNextCmd: ; structure txtErr.xxx
  650. call UiReleaseSpace ;at this point, we know we called
  651. ; UiGrabSpace.  Release it
  652. jmp GetCmdLoop
  653. ;*********************************************************************
  654. ; AskCantCont()
  655. ;
  656. ; Purpose:
  657. ;  AskCantCont() is called by TextMgr when it is about to make an
  658. ;  edit which would prevent continuing program execution.
  659. ;  This function should not be called during exection. It is not
  660. ;  valid (or useful) while the executor is in operation.
  661. ;  If already impossible to continue (i.e. grs.otxCONT ==
  662. ;     UNDEFINED) AskCantCont returns TRUE.  Otherwise, the user is warned
  663. ;     with a dialog box that this edit will prevent continuing.
  664. ;  If the user says OK, grs.otxCONT is set to UNDEFINED
  665. ;     and the context manager's CantCont() is called (which
  666. ;     sets grs.otxCONT to UNDEFINED among other things.
  667. ;     AskCantCont() then returns TRUE.
  668. ;  If the user says CANCEL, the Debug screen is refreshed (discarding
  669. ;     the current edit) and AskCantCont() returns FALSE.
  670. ;
  671. ; Exit:
  672. ;  Returns FALSE if user wants to abort current edit, with
  673. ;  condition codes set based on value in ax.
  674. ;
  675. ;*********************************************************************
  676. cProc AskCantCont,<PUBLIC,FAR>
  677. cBegin
  678. call fCanContUI
  679. je AcCantCont ;brif already can't continue
  680. ;display "This will prevent CONT, proceed anyway?"
  681. PUSHI ax,MB_OKCANCEL
  682. PUSHI ax,MSG_CantCont
  683. call MsgBoxStd
  684. cmp al,IDOK
  685. mov ax,0 ;prepare to return FALSE
  686. jne AcExit ; brif user wants to backout of edit
  687. call CantCont ;disable CONT
  688. AcCantCont:
  689. mov ax,sp ;return TRUE
  690. AcExit:
  691. or ax,ax ;set condition codes for caller
  692. cEnd ;AskCantCont
  693. ;*********************************************************************
  694. ; AskMakeRem()
  695. ; Purpose:
  696. ;  The user tried to insert a blank line before a SUB/FUNCTION line.
  697. ;  This would cause us grief when we tried to ASCII save/load the
  698. ;  file, because blank lines delimit the block of comments that are
  699. ;  to remain with the SUB/FUNCTION.  The case where this is important
  700. ;  is when the user has a module with no module level code, but still
  701. ;  wants to have a block of comments at module-level.
  702. ;  If we allowed blank lines in the block of comments that we move
  703. ;  into the SUB during ASCII load, this block of module comments
  704. ;  would be moved as well.
  705. ;
  706. ; Exit:
  707. ;  Returns FALSE if user wants to abort current edit, with
  708. ;  condition codes set based on value in ax.
  709. ;
  710. ;*********************************************************************
  711. cProc AskMakeRem,<PUBLIC,FAR>
  712. cBegin
  713. ;"Blank lines not allowed before SUB/FUNCTION line.  Is remark ok?"
  714. PUSHI ax,MB_OKCANCEL
  715. PUSHI ax,MSG_MakeRem
  716. call MsgBoxStd
  717. sub ax,IDCANCEL ;ax=0 if user said CANCEL
  718. cEnd
  719. ;*********************************************************************
  720. ; NotSaved(), NotSavedInc(), NotSavedIncSav()
  721. ;
  722. ; Purpose:
  723. ;  Called by Context Mgr's NewStmt and SYSTEM executor when it is about
  724. ;  to discard module(s).
  725. ;  If any module has been modified since last saved, a dialog box asks
  726. ;     the user if the module(s) are to be saved.
  727. ;     If user selects Yes,
  728. ;        CmdFileSaveAll is invoked
  729. ;        If any errors occur during CmdFileSaveAll, an error code is returned.
  730. ;        else the function returns 0.
  731. ;     If user selects Cancel,
  732. ;        it returns MSG_GoDirect, which is not trappable,
  733. ;        and eventually gets us back into user interface, which does not
  734. ;        report this special MSG_GoDirect runtime error.
  735. ;     If user selects No,
  736. ;        the function returns -2.
  737. ;  Else if no modules need to be saved,
  738. ;     it just returns -1.
  739. ;
  740. ;  NotSavedInc just does this for INCLUDE mrs's with the prompt:
  741. ;   "Modified $INCLUDE files must be saved before running. Save them now?"
  742. ;
  743. ;  NotSavedIncSav just does this for INCLUDE mrs's with the prompt:
  744. ;   "Save modified $INCLUDE files first?"
  745. ;
  746. ; Entry:
  747. ;  none
  748. ;
  749. ; Exit:
  750. ;  returns 0 if all modified files were saved without error,
  751. ;  returns -1 if no files were modified (and thus not saved)
  752. ;  returns -2 if user responded NO to the prompt
  753. ;  returns MSG_GoDirect if user responded CANCEL to the prompt
  754. ;  returns error code in ax if an I/O error occurred while trying to save.
  755. ;
  756. ;*********************************************************************
  757. PUBLIC NotSaved, NotSavedInc, NotSavedIncSav
  758. NotSavedIncSav PROC FAR
  759. mov al,2
  760. SKIP2_PSW ;skip following mov al,1 instruction
  761. NotSavedIncSav ENDP
  762. NotSavedInc PROC FAR
  763. mov al,1
  764. SKIP2_PSW ;skip following mov al,0 instruction
  765. NotSavedInc ENDP
  766. NotSaved PROC FAR
  767. mov al,0
  768. ;Common entry for NotSaved, NotSavedInc
  769. push si ;save caller's si,di
  770. push di
  771. cbw ;ax = fInclude
  772. xchg di,ax ;di = fInclude
  773. mov [uierr],0 ;need to init uierr, because it
  774. ; could be non-zero if user selected
  775. ; File/Exit with dirty line in editor.
  776. call EnStaticStructs ;activate static prsCur, mrsCur, txdCur
  777. ;cx = 0 if no action taken
  778. push ax ;remember if we need to call DisStatic..
  779. push WORD PTR([grs.GRS_fDirect])
  780. push [grs.GRS_oRsCur] ;save caller's oRs (for UiRsActivate)
  781. mov si,UNDEFINED
  782. .erre IDCANCEL - UNDEFINED ; (it will be tested below)
  783. .erre IDNO - UNDEFINED ; (it will be tested below)
  784. .erre IDYES - UNDEFINED ; (it will be tested below)
  785. ;pass UNDEFINED to UiRsActivate so no mrs is active
  786. cCall UiRsActivate,<si>
  787. NsLoop:
  788. call NextMrsFile_All ; activate next mrs that has a FILE
  789. ; NextMrsFile doesn't pick up an
  790. ; empty <Untitled> module.
  791. inc ax ;test for UNDEFINED
  792. je NsDone ;brif done with all mrs's
  793. test [mrsCur.MRS_flags2],FM2_Modified
  794. je NsLoop ;brif module is unchanged
  795. or di,di
  796. je SaveIt ;brif saving ALL files, not just INCLUDE
  797. test [mrsCur.MRS_flags2],FM2_Include
  798. je NsLoop ;brif this isn't an INCLUDE file
  799. SaveIt: ;Got at least 1 module which needs to be saved - ask user
  800. PUSHI ax,MB_YESNOCANCEL
  801. mov ax,MSG_NotSavedAll
  802. .errnz MSG_NotSavedInc - MSG_NotSavedAll - 1
  803. .errnz MSG_NotSavedIncSav - MSG_NotSavedAll - 2
  804. add ax,di ;bump to MSG_NotSavedInc if fInclude
  805. push ax
  806. call MsgBoxStd ;al = reply
  807. cmp al,IDYES
  808. xchg si,ax ;save user's response in si
  809. jne NsNoSave ;brif NO or CANCEL reply
  810. xor ax,ax ; no title for subsequent dialog
  811. xchg ax,szDialogTitle ; boxes (save all)
  812. push ax ; save current dialog box title title
  813. cCall CmdFileSaveAll,<di> ;save all modified modules
  814. pop szDialogTitle ; restore current dialog box title
  815. or ax,ax
  816. jne NsNoSave ;brif user didn't select CANCEL in
  817. ; Save dialog, and no I/O errors
  818. mov si,IDCANCEL
  819. NsNoSave:
  820. ;At this point, si = UNDEFINED if no files needed to be saved,
  821. ;      IDNO if user chose to not save unsaved files,
  822. ;      IDCANCEL if user wants to back out of current operation,
  823. ;      IDYES if all files were saved,
  824. ;                 (uierr = non-zero if any errors occurred while saving)
  825. ;
  826. NsDone:
  827. call UiRsActivate ;activate stacked register set.
  828. pop ax ;ax = saved value of grs.fDirect
  829. mov [grs.GRS_fDirect],al ;restore it
  830. pop cx ;cx=0 if static structs were already
  831. jcxz NsStatic ; enabled when NotSaved was called
  832. call DisStaticStructs ;ensure static structs deactivated
  833. NsStatic:
  834. ;If CANCEL button was pressed, return untrappable runtime error
  835. ;which will get us back into user interface if we were in the
  836. ;middle of CHAIN/RUN <file>
  837. mov ax,[uierr]
  838. or ax,ax
  839. jne NsExit ;brif I/O error during save
  840. mov al,MSG_GoDirect
  841. cmp si,IDCANCEL
  842. je NsExit ;brif user responded CANCEL
  843. sub ax,ax ;ax = 0
  844. cmp si,IDYES
  845. je NsExit ;return 0 if any/all files saved
  846. dec ax ;ax = -1
  847. inc si ;test for UNDEFINED
  848. je NsExit ;return -1 if no files need to be saved
  849. dec ax ;if user said NO, return -2
  850. NsExit:
  851. pop di ;restore caller's si,di
  852. pop si
  853. or ax,ax ;set condition codes for caller
  854. ret
  855. NotSaved ENDP
  856. ;**************************************************************************
  857. ; UiGrabSpace
  858. ; Purpose:
  859. ; Don't let user enter such a long program that he can't even execute
  860. ; a SYSTEM, CLEAR, or SETMEM statement.
  861. ; VERY IMPORTANT: Every call to UiGrabSpace MUST be balanced by
  862. ; a subsequent call to UiReleaseSpace.  Make sure the code in
  863. ; between can't take pathological branches (RtError) or non-pathological
  864. ; branches around the UiReleaseSpace call.
  865. ;
  866. ; The goal of user-interface tight-memory-management is to never
  867. ; let the user get so low on memory that they get locked up
  868. ; (i.e. so tight they can't even delete some text or unload a module
  869. ; or execute a direct-mode clear/setmem statement).  If they
  870. ; get locked up to the point where they can't save their file,
  871. ; it is as bad as crashing.
  872. ;   Part of the strategy involves reserving memory whenever the
  873. ; user could potentially be making long-term memory commitments
  874. ; (i.e. loading a new module or inserting a new line of text)
  875. ;   Another part of it is having UiGrabSpace release any
  876. ; "discretionary memory" it can when we run out of memory.
  877. ;
  878. ;**************************************************************************
  879. cProc UiGrabSpace,<PUBLIC,NEAR>
  880. cBegin
  881. inc [cGrab]
  882. call GrabSpace
  883. or ax,ax
  884. jne GotSpace ;brif got space
  885. ;We're very low on memory
  886. ;Release any discretionary info we can to give us the space we need.
  887. call AlphaORsFree ;release sorted alphabetised list
  888. ; of modules/procedures - we build
  889. ; it whenever we need it.
  890. extrn FreeCmdHistory:near
  891. call FreeCmdHistory ;release command window's history
  892. call GrabSpace ;should never fail.
  893. GotSpace:
  894. cEnd
  895. ;**************************************************************************
  896. ; UiReleaseSpace
  897. ; Purpose:
  898. ; We're not in an area where we could make long-term memory commitments
  899. ; that would prevent us from doing a SYSTEM, CLEAR, or SETMEM statement.
  900. ; Unlike ReleaseSpace(), this function doesn't release the space
  901. ; unless all nested callers of UiGrabSpace have released their hold.
  902. ;
  903. ;**************************************************************************
  904. cProc UiReleaseSpace,<PUBLIC,NEAR>
  905. cBegin
  906. DbAssertRelB [cGrab],ne,0,UI,<UiReleaseSpace: cGrab=0>
  907. dec [cGrab]
  908. jne NotDone ;brif not everyone that called
  909. call ReleaseSpace ; UiGrabSpace has called UiReleaseSpace
  910. NotDone:
  911. cEnd
  912. ;**************************************************************************
  913. ; UiAlphaORsBuild
  914. ; Purpose:
  915. ; Since AlphaORsBuild allocates a heap entry, we need to make sure
  916. ; it doesn't encroach upon the minimum heap the user interface needs.
  917. ; Exit:
  918. ; ax = 0 if out-of-memory
  919. ;
  920. ;**************************************************************************
  921. cProc UiAlphaORsBuild,<PUBLIC,NEAR>
  922. cBegin
  923. call AlphaBuildORs
  924. cEnd
  925. ;**************************************************************************
  926. ;**************************************************************************
  927. ;EnMenuCall
  928. ;Purpose:
  929. ; Makes a far call to EnableMenuItem.
  930. ;Entry:
  931. ; AL = Menu Item Name
  932. ; DI = Enable / Disable item
  933. ;Exit:
  934. ; None
  935. ;Usage:
  936. ; Saves AX,BX,CX,DX.
  937. ;**************************************************************************
  938. cProc EnMenuCall,<NEAR>,<AX,BX,CX,DX>
  939. cBegin
  940. xor ah,ah ; AX = MenuItemName
  941. cCall EnableMenuItem,<ax,di>
  942. cEnd
  943. ;*************************************************************************
  944. ;ChMenuCall
  945. ;Purpose:
  946. ; Makes a far call to CheckMenuItem
  947. ;Entry:
  948. ; AL = Menu Item Name
  949. ; DI = Enable / Disable item
  950. ;Exit:
  951. ; None
  952. ;Usage:
  953. ; Per Convention
  954. ;*************************************************************************
  955. cProc ChMenuCall,<NEAR>
  956. cBegin
  957. xor ah,ah ; AX = MenuItemName
  958. cCall CheckMenuItem,<ax,di>
  959. cEnd
  960. ;**************************************************************************
  961. ; MenuEnable - rewritten in assembler from c code in uictl.c
  962. ; Purpose:
  963. ; Enables Display in Main Window.
  964. ; Entry:
  965. ; None
  966. ; Exit:
  967. ; None
  968. ; Uses:
  969. ; PerConvention
  970. ;
  971. ;**************************************************************************
  972. cProc MenuEnable,<PUBLIC,FAR>,<DI,SI>
  973. cBegin
  974. cCall UiRsActivateWnd     ; Tell context manager to activate
  975.     ; active window's register set
  976. ; The Edit Field Structure is updated by every cursor movement
  977. ; indicating system's current state, in terms of options available.
  978. ; For example at the begining of qb sesbx on with blank screen, i.e.
  979. ; no files loaded, you would not have any 'Edit' options available.
  980. ; the moment you type anything 'Undo' becomes available. Further
  981. ; until you select and 'cut', 'paste' would not be availble.
  982. mov bx,pwndAct     ; bx  = pointer to active window's reg set
  983. mov bx,[bx.pefExtra]    ; bx  = * to edit field structure
  984. push bx      ; Save for later use
  985. mov bl,[bx.EF_fSelection]
  986. xor bh,bh      ; BX = fSelection from edit field structure
  987. xor cx,cx     ; if pwndAct != wndCmd then ListWnd=False
  988. cmp pwndAct,DATAOFFSET wndCmd;        else ListWnd=True
  989. je fIsListWndSet     ; CX = ListWnd Status
  990. dec cx
  991. fIsListWndSet:
  992. xor dx,dx     ; So no changes like cut, paste
  993. cmp pwndAct,DATAOFFSET wndHelp  ; are allowed. fChangeable flag
  994. je fChangeableSet     ; specifies if user is in Help.
  995. dec dx
  996. fChangeableSet:      ; DX = fChangeable
  997. mov si,dx ;SI = fChangeable
  998. mov di,bx     ; DI = fSelection
  999. mov al,midEditCopy     ; Set up Edit/Copy
  1000. cCall EnMenuCall
  1001. and di,si     ; DI = fSelection AND fChangeable
  1002. mov al,midEditCut     ; Setup Edit/Cut
  1003. call EnMenuCall
  1004. mov al,midEditClear     ; Set up Edit/Clear
  1005. cCall EnMenuCall
  1006. mov al,fPasteOk
  1007. cbw
  1008. xchg di,ax     ; DI = Paste Command availability status
  1009. and di,si     ; DI = fPasteOK AND fChangeable
  1010. mov al,midEditPaste     ; Set up Edit/Paste
  1011. cCall EnMenuCall
  1012. mov di,cx     ; DI = ListWindow Status
  1013. mov al,midSearchFind    ; Set up Search/Find
  1014. cCall EnMenuCall
  1015. mov al,midSearchNext    ; Set up Search/Next
  1016. cCall EnMenuCall
  1017. and di,si     ; DI = ListWnd AND fChangeable
  1018. mov al,midSearchChange  ; Set up Search/Change
  1019. cCall EnMenuCall
  1020.     ; bx  was save way above.
  1021. pop bx     ; Restore bx  = * Edit Field Structure
  1022. mov al,fSyntaxCheck
  1023. cbw     ; AX = Syntax Check options Selected?
  1024. xchg di,ax     ; DI = Syntax Check options
  1025. mov al,midOptnsSyntax   ; in Options of menus
  1026. cCall ChMenuCall
  1027. xor cx,cx
  1028. xor ah,ah
  1029. mov al,[mrsCur].MRS_flags2 ;get mrs file flags
  1030. and al,FM2_Include+FM2_NoPcode ;is this a pcoded window?
  1031. jnz SetFalse     ; brif not
  1032. dec cx
  1033. SetFalse:
  1034. mov dx,si ; DX = fChangable
  1035. and dx,cx ; fIsCodeWnd = Pcode & Changeable
  1036. ; DX = fIsCodeWnd, CX = fPcode
  1037. mov di,dx     ; DI = IsCodeWnd
  1038. mov al,midEditNewSub    ; Setup Edit/New Sub
  1039. cCall EnMenuCall
  1040. mov al,midEditNewFunc   ; Setup Edit/New Function
  1041. cCall EnMenuCall
  1042. mov al,midDebugToggleBp ; Set up Debug/Toggle BreakPoint
  1043. cCall EnMenuCall
  1044. mov al,midGoUntilCursor
  1045. cCall EnMenuCall
  1046. mov di,fIsProgram ; DI = TRUE if prog, FALSE if doc
  1047. mov al,midViewSubs ; Setup View/Subs
  1048. cCall EnMenuCall     
  1049. mov al,midRunStart ; Setup Run/Start
  1050. cCall EnMenuCall     
  1051. mov al,midRunRestart ; Setup Run/Retart
  1052. cCall EnMenuCall     
  1053. mov al,midRunContinue ; Setup Run/Continue
  1054. cCall EnMenuCall     
  1055. mov al,midStep ; Setup Debug/Step
  1056. cCall EnMenuCall     
  1057. mov al,midPStep ; Setup Debug/PStep
  1058. cCall EnMenuCall     
  1059. mov al,midDebugClearAllBp ; Setup Debug/Clear all Bp
  1060. cCall EnMenuCall     
  1061. mov al,midDebugTraceOn  ; Setup Debug/Trace On
  1062. cCall EnMenuCall     
  1063. mov di,dx ; di = fIsCodeWnd
  1064. or di,di ; is this a code window?
  1065. je NotCodeWnd ; brif not
  1066. cCall fCanContUI     ; returns AX = Execution State
  1067. xchg ax,di     ; False if Not in Code Window
  1068. NotCodeWnd:
  1069. mov al,midDebugSetNextStmt; Set up Set Next Stmt command
  1070. cCall EnMenuCall     ; in debug options of menus
  1071. mov al,fTraceOn
  1072. cbw
  1073. xchg di,ax     ; di = Trace On Flag
  1074. mov al,midDebugTraceOn  ; Setup Debug/Trace On
  1075. cCall ChMenuCall
  1076. cEnd
  1077. sEnd UI
  1078. end