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

操作系统开发

开发平台:

Visual C++

  1. TITLE uirs.asm - User Interface Register Set Management.
  2. ;*** 
  3. ;uirs.asm - User interface register set management.
  4. ;
  5. ; Copyright <C> 1985-1988, Microsoft Corporation
  6. ;
  7. ;Purpose:
  8. ; This module attempts to localize the interface between the rest of
  9. ; the user-interface and the contest manager.
  10. ;
  11. ;
  12. ;*******************************************************************************
  13. .xlist
  14. include version.inc
  15. include  ..uqintl.inc       ;IPG - holds definition for CCHUNTITLED
  16. UIRS_ASM = ON
  17. includeOnce architec
  18. includeOnce context
  19. includeOnce heap
  20. includeOnce names
  21. includeOnce qbimsgs
  22. includeOnce txtmgr
  23. includeOnce ui
  24. includeOnce uiint
  25. .list
  26. assumes DS,DATA
  27. assumes ES,DATA
  28. assumes SS,DATA
  29. sBegin DATA
  30. externB szUntitled
  31. sEnd DATA
  32. sBegin CP
  33. assumes cs,CP
  34. ; Added with [7]
  35. ;****
  36. ;fogNamUntitled - is this ogNam reference to an untitiled text table
  37. ;
  38. ;Purpose:
  39. ; For QEDIT, there can be two untitled text tables: the untitled
  40. ; text table (ogNam = OGNAM_UNNAMED) and the text table with the title
  41. ; "UNTITLED".  Figure out if this ogNam references either of them.
  42. ;
  43. ;Entry:
  44. ; ogNam - ogNam to check
  45. ;
  46. ;Exit:
  47. ; TRUE - ogNam is UNTITLED or for the UNTITILED window
  48. ;
  49. ;Uses:
  50. ; AX, BX, CX, DX
  51. ;****
  52. cProc fogNamUntitled,<FAR,PUBLIC>,<SI,DI>
  53. parmw ogNam
  54. cBegin
  55. mov ax,ogNam
  56. cmp ax,OGNAM_UNNAMED ;is it the untitled text table?
  57. je IsUntitled
  58. xor cx,cx ;(assume special, set length)
  59. cmp ax,OGNAM_PSEUDO_MAX ;is it a special one?
  60. jbe IsTitled ;yes, it has a title
  61. push ax
  62. call FpNamOfOgNam ;es:bx = ptr to name, cx = count
  63. IsTitled:
  64. xor ax,ax ;prepare to return FALSE (not untitled)
  65. cmp cx,CCHUNTITLED ;IPG ;is it 8 = len(UNTITLED)
  66. jne fogExit  ;brif not, return FALSE
  67. mov di,bx
  68. mov si,dataOffset szUntitled
  69. repz cmpsb ;is it untitled?
  70. jnz fogExit  ;brif not, return FALSE
  71. IsUntitled:
  72. mov ax,sp ;return TRUE
  73. fogExit:
  74. cEnd
  75. sEnd CP
  76. sBegin UI
  77. assumes cs,UI
  78. ;**************************************************************************
  79. ;fCanContUI
  80. ;
  81. ;Purpose:
  82. ;       tests grs.otxCONT for UNDEFINED, i.e., sees if the user
  83. ;       can CONTINUE.
  84. ;Entry:
  85. ;       none.
  86. ;Exit:
  87. ;       ax = 0 and psw.Z is set if the user cannot continue
  88. ;
  89. ;*******************************************************************************
  90. cProc fCanContUI,<PUBLIC,NEAR,NODATA>
  91. cBegin
  92. mov ax,[grs.GRS_otxCONT]
  93. inc ax ;ax = 0 if can't continue
  94. cEnd
  95. ;**************************************************************************
  96. ; ushort GetRsName(oRs, flags, cbMax)
  97. ; Purpose:
  98. ; Copy the ASCII Name of a given register set to the global buffer
  99. ; 'bufStdMsg'.  This may be a module name or procedure name.
  100. ;
  101. ; Entry:
  102. ; ushort oRs = register set (as returned by RsMake)
  103. ; uchar flags says to display name in the form:
  104. ;   RSN_fFullName:   <module name>:<procedure name>
  105. ; where procedure name is only included if
  106. ;   grs.oPrsCur != UNDEFINED
  107. ;   RSN_fIndent:     precede name with 2 spaces
  108. ; uchar cbMax = maximum number of characters to display.  If name won't
  109. ; fit, "..." is inserted in middle of procedure name.
  110. ; Assumes cbMax > length of MSG_Untitled
  111. ; Assumes cbMax > 14
  112. ; Assumes cbMax < 256
  113. ; If cbMax > CB_MSG_MAX (defined in qbimsgs.inc) then
  114. ;    cbMax is forced to CB_MSG_MAX
  115. ; mrsCur.ogNam describes module's name (assumed < 256 chars long)
  116. ; prsCur.ogNam describes procedure's name (assumed < 256 chars long)
  117. ;
  118. ; Exit:
  119. ; returns # bytes in name
  120. ; bufStdMsg contains a 0-byte terminated name
  121. ; preserves active register set on exit
  122. ;
  123. ; Algorithm:
  124. ;       if (oRs == UNDEFINED) {
  125. ;          strcpy( &bufStdMsg, "" )
  126. ;          return(2)
  127. ;          }
  128. ; if (fFullName or grs.oPrsCur != UNDEFINED)
  129. ;    if (((grs.oPrsCur == UNDEFINED) || fFullName) &&
  130. ;        (mrsCur.ogNam == NULL))
  131. ;          cbMax -= (EmitMsg('<Untitled>'))
  132. ;    else
  133. ;       cbMax -= Emit(pFilePart(sdMrsName.pb, cbMax))
  134. ;    if (grs.oPrsCur != UNDEFINED)
  135. ;       emit ':'
  136. ;       cbMax -= 1
  137. ; if (grs.oPrsCur != UNDEFINED)
  138. ;    EmitName(&sdPrsName, cbMax)
  139. ;
  140. ;**************************************************************************
  141. cProc GetRsName,<PUBLIC,NEAR,NODATA>,<si,di>
  142. parmW oRs
  143. parmB flags
  144. parmB cbMax
  145. localD sdName,4
  146. localV rsName,255D
  147.  cBegin GetRsName
  148. ;       if (oRs == UNDEFINED) {
  149. ;          strcpy( &bufStdMsg, "" )
  150. ;          return(2)
  151. ;          }
  152. mov di,dataOFFSET bufStdMsg ;di points to destination buffer
  153. mov ax,[oRs]
  154. inc ax ; Is oRs UNDEFINED?
  155. jne oRsOk
  156. mov byte ptr [di],0 ;store 0-byte terminator
  157. jmp GetRsNameEnd ;return ax = length = 0
  158. oRsOk:
  159. ; make a fake sd for use with ogNam of the Rs
  160. lea si,rsName
  161. mov [SEG_sdName],si ; set up pointer part of fake sd
  162. dec ax ;restore ax = oRs parm
  163. push [grs.GRS_oRsCur] ;preserve current context
  164. ; (will be restored on exit)
  165. push ax
  166. call UiRsActivate ;activate register set of interest
  167. push ds
  168. pop es ;es = DGROUP for stosb, movsb
  169. mov dx,[grs.GRS_oPrsCur]
  170. and dh,dl ;dh = FF only if oPrsCur == UNDEFINED
  171. mov dl,[cbMax] ;dl = cbMax
  172. cmp dl,CB_MSG_MAX
  173. jbe CbMaxOk ;brif cbMax <= CB_MSG_MAX
  174. mov dl,CB_MSG_MAX ;force cbMax within range
  175. CbMaxOk:
  176. test [flags],RSN_fIndent
  177. je NoIndent1
  178. dec dl ;cbMax -= 2
  179. dec dl
  180. NoIndent1:
  181. inc dh ;dh = 0 if oPrsCur == UNDEFINED
  182. je ListModName ;brif no active procedure
  183. test [flags],RSN_fFullName
  184. je ListProcName ;brif caller doesn't want mod name
  185. ListModName:
  186. push dx ; preserve DX
  187. push [mrsCur.MRS_ogNam]
  188. call fogNamUntitled
  189. pop dx ; restore DX
  190. or ax,ax ; is it an untitled module?
  191. mov bx,MSG_Untitled ; assume so
  192. jne SpecialOgNam ;brif module is untitled
  193. mov bx,MSG_Immediate
  194. mov ax,[mrsCur.MRS_ogNam]
  195. cmp ax,OGNAM_IMMEDIATE
  196. jne NotSpecialOgNam ;brif module is Immediate window
  197. SpecialOgNam:
  198. push dx ;preserve dx
  199. push bx ;pass MSG_xxx
  200. call ListStdMsg ;copy "<Untitled>" to buffer,
  201. ; ax = #bytes (international <> 8)
  202. pop dx ;restore dx
  203. add di,ax ;di points beyond "<Untitled>"
  204. inc ax ;add 1 for following space if proc
  205. sub dl,al ;cbMax = #bytes left in buffer
  206. jmp SHORT TryProcName
  207. NotSpecialOgNam:
  208. push dx ; preserve across call
  209. cCall CopyOgNamPb,<si,ax> ; copy name into fake sd on stack
  210. pop dx
  211. mov [OFF_sdName],ax ; save cbName in cb part of fake sd
  212. xchg ax,bx ; bx = length of module name
  213. cCall pFilePart ; Get pointer to file part of file spec.
  214. ; pointer in si; count in bx
  215. ; all other regs preserved.
  216. sub dl,bl ; cbMax -= length of module's name
  217. mov cx,bx ; Get byte count of file spec.
  218. rep movsb ; copy filename to destination
  219. ; if (grs.oPrsCur != UNDEFINED)
  220. ;    if (anything emitted yet)
  221. ;       emit ':'
  222. ;    EmitName(&sdPrsName, cbMax)
  223. ;
  224. ; dh = 0 if no prs is active
  225. ; di points into bufStdMsg
  226. ; dl = max bytes left in output buffer
  227. ;
  228. TryProcName:
  229. or dh,dh
  230. je ListZeroTerm ;brif no procedure is active
  231. mov al,':'
  232. stosb ;emit ':' between module and proc name
  233. dec dl ;cbMax -= 1
  234. ListProcName:
  235. push dx ; preserve across call
  236. lea si,rsName
  237. cCall CopyOgNamPb,<si,prsCur.prs_ogNam> 
  238. pop dx
  239. lea si,sdName
  240. mov [si.SD_cb],ax
  241. call EmitName ;EmitName(si, di, dl)
  242. ;di points beyond last byte of name
  243. ListZeroTerm:
  244. test [flags],RSN_fIndent
  245. je NoIndent2 ;brif no space to be inserted at front
  246. mov si,di
  247. dec si ;si points to last byte of name
  248. inc di
  249. push di ;save ptr beyond last byte
  250. mov cx,di
  251. sub cx,dataOFFSET bufStdMsg ;cx = byte count of name
  252. std
  253. rep movsb ;shift name right 2 bytes
  254. cld
  255. mov ax,' '
  256. stosb ;put '  ' in front of name
  257. stosb
  258. pop di ;di points to last byte of name
  259. inc di ;di points beyond last byte of name
  260. NoIndent2:
  261. pop ax ;ax = caller's context
  262. inc ax ;test for UNDEFINED
  263. je NoRsWasActive
  264. dec ax ;restore ax = oRs
  265. push ax
  266. call UiRsActivate ;re-activate saved register set
  267. NoRsWasActive:
  268. mov byte ptr [di],0 ;store 0-byte terminator
  269. xchg ax,di ;ax points beyond end of name
  270. sub ax,dataOFFSET bufStdMsg ;ax = actual size (return value)
  271. ;ax = #bytes in name
  272. GetRsNameEnd:
  273. DbAssertRelB [cbMax],ae,al,UI,<GetRsName: name too long>
  274. ; If the pathname code doesn't truncate names/extensions,
  275. ; GetRsName can return > cbMax chars, hosing DGROUP, etc.
  276. cEnd GetRsName
  277. ;**************************************************************************
  278. ; EmitName(si = psdSrc, di = pbDst, dl = cbMax)
  279. ; Purpose:
  280. ; List as much of a name as possible, storing "..." in middle
  281. ; if insufficient room.
  282. ;
  283. ; Entry:
  284. ; si = psdSrc = pointer to source name's string descriptor
  285. ; di = pbDst = pointer to destination buffer
  286. ; dl = size of destination buffer (assumed > 15)
  287. ;
  288. ; Algorithm:
  289. ;  think of name as [cbLeft-cbSkip-cbRight]
  290. ;  if entire name won't fit in destination, [cbLeft...cbRight] is listed
  291. ;  cbLeft = cbMax / 2
  292. ;  cbRight = cbMax - cbLeft
  293. ;  cbSkip = cbName - cbLeft - cbRight = cbName - cbMax
  294. ;
  295. ; Exit:
  296. ; di points beyond emitted name
  297. ;
  298. ; Alters:
  299. ; al, bx, cx, si (ALL others are preserved)
  300. ;
  301. ;**************************************************************************
  302. EmitName:
  303. mov cx,[si.SD_cb] ;cx = length of name
  304. ; we can assume ch == 0
  305. mov si,[si.SD_pb] ;si points to 1st byte of name
  306. sub al,al ;al = cbRight = 0 (assume name fits)
  307. cmp cl,dl ;compare cbName with cbMax
  308. jbe NameFits ;brif plenty of room for entire name
  309. sub dl,3 ;account for the `...'
  310. mov bx,cx ;bx = bl = cbName
  311. mov cl,dl ;cx = cl = cbMax
  312. shr cl,1 ;cx = cl = cbLeft = cbMax / 2
  313. mov al,dl ;al = cbMax
  314. sub al,cl ;al = cbRight = cbMax - cbLeft
  315. sub bl,dl ;bx = bl = cbSkip = cbName - cbMax
  316. NameFits:
  317. rep movsb ;copy left part of name
  318. mov cl,al ;cx = cl = cbRight
  319. jcxz EmitNameExit ;brif no right half to emit
  320. mov al,'.'
  321. stosb ;emit '...'
  322. stosb
  323. stosb
  324. add si,bx ;si points to right half of name
  325. rep movsb ;copy right part of name
  326. EmitNameExit:
  327. ret
  328. ;**************************************************************************
  329. ; pFilePart(si = pointer to file spec, bx = byte count of file spec)
  330. ; Purpose:
  331. ;  Advance file spec pointer so that it points to the filename part.
  332. ;  Adjust byte count accordingly
  333. ;
  334. ;  KANJI variant added with [6]
  335. ;
  336. ; Entry:
  337. ;    SI - Pointer to file spec.
  338. ;    BX - Count of bytes in file spec.
  339. ;
  340. ; Exit:
  341. ;    SI - Pointer to file part of file spec.
  342. ;    BX - Count of bytes of file part in file spec.
  343. ;
  344. ; Alters: si, bx
  345. ;
  346. ;**************************************************************************
  347. DbPub pFilePart
  348. cProc pFilePart,<NEAR>,<AX,CX,DX,DI,ES>
  349. cBegin
  350. push ds
  351. pop es
  352. mov di,si
  353. mov al,''
  354. mov cx,bx
  355. ScanForBackSlash:
  356. repne scasb
  357. jne NoMoreBackSlash
  358. inc si ; Point after the ''
  359. mov bx,cx ; Save away the count and the pointer
  360. mov si,di
  361. jmp SHORT ScanForBackSlash
  362. NoMoreBackSlash:
  363. cmp bx,2
  364. jbe pFilePartEnd
  365. cmp byte ptr [si+2],':' ; Is there a drive specification.
  366. jne pFilePartEnd
  367. inc si ; Throw away drive specification.
  368. inc si
  369. dec bx
  370. dec bx
  371. pFilePartEnd:
  372. cEnd
  373. ;************************************************************************
  374. ; boolean ContContext()
  375. ; Purpose:
  376. ; Make the current MRS and PRS the one where BASIC's program counter
  377. ; is pointing.  If CONTinue is not possible, make main module active.
  378. ;
  379. ; Exit:
  380. ; If unable to CONT and no main module
  381. ;    returns FALSE
  382. ; else
  383. ;    returns TRUE after setting up grs.oRsCur, grs.otxCur
  384. ;
  385. ;************************************************************************
  386. cProc ContContext,<PUBLIC,NEAR>
  387. cBegin
  388. mov ax,[grs.GRS_otxCONT]
  389. mov [grs.GRS_otxCur],ax
  390. inc ax ;test for UNDEFINED
  391. mov ax,[grs.GRS_oRsCONT]
  392. jne CanCont
  393. ;we can't continue, use 'main' module if there is one
  394. mov ax,[grs.GRS_oMrsMain]
  395. inc ax
  396. je CcExit ;brif no main module
  397. mov [grs.GRS_otxCur],0 ;grs.otxCur = 0
  398. dec ax
  399. ;ax = oRs containing next stmt to be executed
  400. CanCont:
  401. cCall UiRsActivate,<ax>
  402. mov ax,sp ;return TRUE
  403. CcExit:
  404. or ax,ax ;set condition codes for caller
  405. cEnd
  406. ;************************************************************************
  407. ; boolean NeedContContext()
  408. ; Purpose:
  409. ; Make the current MRS and PRS the one where BASIC's program counter
  410. ; is pointing.  If CONTinue is not possible, make main module active.
  411. ;
  412. ; Exit:
  413. ; If unable to CONT and no main module
  414. ;    [uierr] = MSG_NoMainProg
  415. ;    txtErr.oRs = UNDEFINED (so cursor won't be positioned by ReportError)
  416. ;    returns FALSE
  417. ; else
  418. ;    returns TRUE after setting up grs.oRsCur, grs.otxCur
  419. ;
  420. ;************************************************************************
  421. cProc NeedContContext,<PUBLIC,NEAR>
  422. cBegin
  423. call ContContext ;activate CONT program counter
  424. jne CcNoErr ;brif can CONT
  425. PUSHI ax,MSG_NoMainProg
  426. call SetUiErr
  427. xor ax,ax ; set ax and condition codes
  428. CcNoErr:
  429. cEnd
  430. sEnd CP
  431. end