uirs.asm
资源名称:DOS系统的源代码.rar [点击查看]
上传用户:xiaoan1112
上传日期:2013-04-11
资源大小:19621k
文件大小:13k
源码类别:
操作系统开发
开发平台:
Visual C++
- TITLE uirs.asm - User Interface Register Set Management.
- ;***
- ;uirs.asm - User interface register set management.
- ;
- ; Copyright <C> 1985-1988, Microsoft Corporation
- ;
- ;Purpose:
- ; This module attempts to localize the interface between the rest of
- ; the user-interface and the contest manager.
- ;
- ;
- ;*******************************************************************************
- .xlist
- include version.inc
- include ..uqintl.inc ;IPG - holds definition for CCHUNTITLED
- UIRS_ASM = ON
- includeOnce architec
- includeOnce context
- includeOnce heap
- includeOnce names
- includeOnce qbimsgs
- includeOnce txtmgr
- includeOnce ui
- includeOnce uiint
- .list
- assumes DS,DATA
- assumes ES,DATA
- assumes SS,DATA
- sBegin DATA
- externB szUntitled
- sEnd DATA
- sBegin CP
- assumes cs,CP
- ; Added with [7]
- ;****
- ;fogNamUntitled - is this ogNam reference to an untitiled text table
- ;
- ;Purpose:
- ; For QEDIT, there can be two untitled text tables: the untitled
- ; text table (ogNam = OGNAM_UNNAMED) and the text table with the title
- ; "UNTITLED". Figure out if this ogNam references either of them.
- ;
- ;Entry:
- ; ogNam - ogNam to check
- ;
- ;Exit:
- ; TRUE - ogNam is UNTITLED or for the UNTITILED window
- ;
- ;Uses:
- ; AX, BX, CX, DX
- ;****
- cProc fogNamUntitled,<FAR,PUBLIC>,<SI,DI>
- parmw ogNam
- cBegin
- mov ax,ogNam
- cmp ax,OGNAM_UNNAMED ;is it the untitled text table?
- je IsUntitled
- xor cx,cx ;(assume special, set length)
- cmp ax,OGNAM_PSEUDO_MAX ;is it a special one?
- jbe IsTitled ;yes, it has a title
- push ax
- call FpNamOfOgNam ;es:bx = ptr to name, cx = count
- IsTitled:
- xor ax,ax ;prepare to return FALSE (not untitled)
- cmp cx,CCHUNTITLED ;IPG ;is it 8 = len(UNTITLED)
- jne fogExit ;brif not, return FALSE
- mov di,bx
- mov si,dataOffset szUntitled
- repz cmpsb ;is it untitled?
- jnz fogExit ;brif not, return FALSE
- IsUntitled:
- mov ax,sp ;return TRUE
- fogExit:
- cEnd
- sEnd CP
- sBegin UI
- assumes cs,UI
- ;**************************************************************************
- ;fCanContUI
- ;
- ;Purpose:
- ; tests grs.otxCONT for UNDEFINED, i.e., sees if the user
- ; can CONTINUE.
- ;Entry:
- ; none.
- ;Exit:
- ; ax = 0 and psw.Z is set if the user cannot continue
- ;
- ;*******************************************************************************
- cProc fCanContUI,<PUBLIC,NEAR,NODATA>
- cBegin
- mov ax,[grs.GRS_otxCONT]
- inc ax ;ax = 0 if can't continue
- cEnd
- ;**************************************************************************
- ; ushort GetRsName(oRs, flags, cbMax)
- ; Purpose:
- ; Copy the ASCII Name of a given register set to the global buffer
- ; 'bufStdMsg'. This may be a module name or procedure name.
- ;
- ; Entry:
- ; ushort oRs = register set (as returned by RsMake)
- ; uchar flags says to display name in the form:
- ; RSN_fFullName: <module name>:<procedure name>
- ; where procedure name is only included if
- ; grs.oPrsCur != UNDEFINED
- ; RSN_fIndent: precede name with 2 spaces
- ; uchar cbMax = maximum number of characters to display. If name won't
- ; fit, "..." is inserted in middle of procedure name.
- ; Assumes cbMax > length of MSG_Untitled
- ; Assumes cbMax > 14
- ; Assumes cbMax < 256
- ; If cbMax > CB_MSG_MAX (defined in qbimsgs.inc) then
- ; cbMax is forced to CB_MSG_MAX
- ; mrsCur.ogNam describes module's name (assumed < 256 chars long)
- ; prsCur.ogNam describes procedure's name (assumed < 256 chars long)
- ;
- ; Exit:
- ; returns # bytes in name
- ; bufStdMsg contains a 0-byte terminated name
- ; preserves active register set on exit
- ;
- ; Algorithm:
- ; if (oRs == UNDEFINED) {
- ; strcpy( &bufStdMsg, "" )
- ; return(2)
- ; }
- ; if (fFullName or grs.oPrsCur != UNDEFINED)
- ; if (((grs.oPrsCur == UNDEFINED) || fFullName) &&
- ; (mrsCur.ogNam == NULL))
- ; cbMax -= (EmitMsg('<Untitled>'))
- ; else
- ; cbMax -= Emit(pFilePart(sdMrsName.pb, cbMax))
- ; if (grs.oPrsCur != UNDEFINED)
- ; emit ':'
- ; cbMax -= 1
- ; if (grs.oPrsCur != UNDEFINED)
- ; EmitName(&sdPrsName, cbMax)
- ;
- ;**************************************************************************
- cProc GetRsName,<PUBLIC,NEAR,NODATA>,<si,di>
- parmW oRs
- parmB flags
- parmB cbMax
- localD sdName,4
- localV rsName,255D
- cBegin GetRsName
- ; if (oRs == UNDEFINED) {
- ; strcpy( &bufStdMsg, "" )
- ; return(2)
- ; }
- mov di,dataOFFSET bufStdMsg ;di points to destination buffer
- mov ax,[oRs]
- inc ax ; Is oRs UNDEFINED?
- jne oRsOk
- mov byte ptr [di],0 ;store 0-byte terminator
- jmp GetRsNameEnd ;return ax = length = 0
- oRsOk:
- ; make a fake sd for use with ogNam of the Rs
- lea si,rsName
- mov [SEG_sdName],si ; set up pointer part of fake sd
- dec ax ;restore ax = oRs parm
- push [grs.GRS_oRsCur] ;preserve current context
- ; (will be restored on exit)
- push ax
- call UiRsActivate ;activate register set of interest
- push ds
- pop es ;es = DGROUP for stosb, movsb
- mov dx,[grs.GRS_oPrsCur]
- and dh,dl ;dh = FF only if oPrsCur == UNDEFINED
- mov dl,[cbMax] ;dl = cbMax
- cmp dl,CB_MSG_MAX
- jbe CbMaxOk ;brif cbMax <= CB_MSG_MAX
- mov dl,CB_MSG_MAX ;force cbMax within range
- CbMaxOk:
- test [flags],RSN_fIndent
- je NoIndent1
- dec dl ;cbMax -= 2
- dec dl
- NoIndent1:
- inc dh ;dh = 0 if oPrsCur == UNDEFINED
- je ListModName ;brif no active procedure
- test [flags],RSN_fFullName
- je ListProcName ;brif caller doesn't want mod name
- ListModName:
- push dx ; preserve DX
- push [mrsCur.MRS_ogNam]
- call fogNamUntitled
- pop dx ; restore DX
- or ax,ax ; is it an untitled module?
- mov bx,MSG_Untitled ; assume so
- jne SpecialOgNam ;brif module is untitled
- mov bx,MSG_Immediate
- mov ax,[mrsCur.MRS_ogNam]
- cmp ax,OGNAM_IMMEDIATE
- jne NotSpecialOgNam ;brif module is Immediate window
- SpecialOgNam:
- push dx ;preserve dx
- push bx ;pass MSG_xxx
- call ListStdMsg ;copy "<Untitled>" to buffer,
- ; ax = #bytes (international <> 8)
- pop dx ;restore dx
- add di,ax ;di points beyond "<Untitled>"
- inc ax ;add 1 for following space if proc
- sub dl,al ;cbMax = #bytes left in buffer
- jmp SHORT TryProcName
- NotSpecialOgNam:
- push dx ; preserve across call
- cCall CopyOgNamPb,<si,ax> ; copy name into fake sd on stack
- pop dx
- mov [OFF_sdName],ax ; save cbName in cb part of fake sd
- xchg ax,bx ; bx = length of module name
- cCall pFilePart ; Get pointer to file part of file spec.
- ; pointer in si; count in bx
- ; all other regs preserved.
- sub dl,bl ; cbMax -= length of module's name
- mov cx,bx ; Get byte count of file spec.
- rep movsb ; copy filename to destination
- ; if (grs.oPrsCur != UNDEFINED)
- ; if (anything emitted yet)
- ; emit ':'
- ; EmitName(&sdPrsName, cbMax)
- ;
- ; dh = 0 if no prs is active
- ; di points into bufStdMsg
- ; dl = max bytes left in output buffer
- ;
- TryProcName:
- or dh,dh
- je ListZeroTerm ;brif no procedure is active
- mov al,':'
- stosb ;emit ':' between module and proc name
- dec dl ;cbMax -= 1
- ListProcName:
- push dx ; preserve across call
- lea si,rsName
- cCall CopyOgNamPb,<si,prsCur.prs_ogNam>
- pop dx
- lea si,sdName
- mov [si.SD_cb],ax
- call EmitName ;EmitName(si, di, dl)
- ;di points beyond last byte of name
- ListZeroTerm:
- test [flags],RSN_fIndent
- je NoIndent2 ;brif no space to be inserted at front
- mov si,di
- dec si ;si points to last byte of name
- inc di
- push di ;save ptr beyond last byte
- mov cx,di
- sub cx,dataOFFSET bufStdMsg ;cx = byte count of name
- std
- rep movsb ;shift name right 2 bytes
- cld
- mov ax,' '
- stosb ;put ' ' in front of name
- stosb
- pop di ;di points to last byte of name
- inc di ;di points beyond last byte of name
- NoIndent2:
- pop ax ;ax = caller's context
- inc ax ;test for UNDEFINED
- je NoRsWasActive
- dec ax ;restore ax = oRs
- push ax
- call UiRsActivate ;re-activate saved register set
- NoRsWasActive:
- mov byte ptr [di],0 ;store 0-byte terminator
- xchg ax,di ;ax points beyond end of name
- sub ax,dataOFFSET bufStdMsg ;ax = actual size (return value)
- ;ax = #bytes in name
- GetRsNameEnd:
- DbAssertRelB [cbMax],ae,al,UI,<GetRsName: name too long>
- ; If the pathname code doesn't truncate names/extensions,
- ; GetRsName can return > cbMax chars, hosing DGROUP, etc.
- cEnd GetRsName
- ;**************************************************************************
- ; EmitName(si = psdSrc, di = pbDst, dl = cbMax)
- ; Purpose:
- ; List as much of a name as possible, storing "..." in middle
- ; if insufficient room.
- ;
- ; Entry:
- ; si = psdSrc = pointer to source name's string descriptor
- ; di = pbDst = pointer to destination buffer
- ; dl = size of destination buffer (assumed > 15)
- ;
- ; Algorithm:
- ; think of name as [cbLeft-cbSkip-cbRight]
- ; if entire name won't fit in destination, [cbLeft...cbRight] is listed
- ; cbLeft = cbMax / 2
- ; cbRight = cbMax - cbLeft
- ; cbSkip = cbName - cbLeft - cbRight = cbName - cbMax
- ;
- ; Exit:
- ; di points beyond emitted name
- ;
- ; Alters:
- ; al, bx, cx, si (ALL others are preserved)
- ;
- ;**************************************************************************
- EmitName:
- mov cx,[si.SD_cb] ;cx = length of name
- ; we can assume ch == 0
- mov si,[si.SD_pb] ;si points to 1st byte of name
- sub al,al ;al = cbRight = 0 (assume name fits)
- cmp cl,dl ;compare cbName with cbMax
- jbe NameFits ;brif plenty of room for entire name
- sub dl,3 ;account for the `...'
- mov bx,cx ;bx = bl = cbName
- mov cl,dl ;cx = cl = cbMax
- shr cl,1 ;cx = cl = cbLeft = cbMax / 2
- mov al,dl ;al = cbMax
- sub al,cl ;al = cbRight = cbMax - cbLeft
- sub bl,dl ;bx = bl = cbSkip = cbName - cbMax
- NameFits:
- rep movsb ;copy left part of name
- mov cl,al ;cx = cl = cbRight
- jcxz EmitNameExit ;brif no right half to emit
- mov al,'.'
- stosb ;emit '...'
- stosb
- stosb
- add si,bx ;si points to right half of name
- rep movsb ;copy right part of name
- EmitNameExit:
- ret
- ;**************************************************************************
- ; pFilePart(si = pointer to file spec, bx = byte count of file spec)
- ; Purpose:
- ; Advance file spec pointer so that it points to the filename part.
- ; Adjust byte count accordingly
- ;
- ; KANJI variant added with [6]
- ;
- ; Entry:
- ; SI - Pointer to file spec.
- ; BX - Count of bytes in file spec.
- ;
- ; Exit:
- ; SI - Pointer to file part of file spec.
- ; BX - Count of bytes of file part in file spec.
- ;
- ; Alters: si, bx
- ;
- ;**************************************************************************
- DbPub pFilePart
- cProc pFilePart,<NEAR>,<AX,CX,DX,DI,ES>
- cBegin
- push ds
- pop es
- mov di,si
- mov al,''
- mov cx,bx
- ScanForBackSlash:
- repne scasb
- jne NoMoreBackSlash
- inc si ; Point after the ''
- mov bx,cx ; Save away the count and the pointer
- mov si,di
- jmp SHORT ScanForBackSlash
- NoMoreBackSlash:
- cmp bx,2
- jbe pFilePartEnd
- cmp byte ptr [si+2],':' ; Is there a drive specification.
- jne pFilePartEnd
- inc si ; Throw away drive specification.
- inc si
- dec bx
- dec bx
- pFilePartEnd:
- cEnd
- ;************************************************************************
- ; boolean ContContext()
- ; Purpose:
- ; Make the current MRS and PRS the one where BASIC's program counter
- ; is pointing. If CONTinue is not possible, make main module active.
- ;
- ; Exit:
- ; If unable to CONT and no main module
- ; returns FALSE
- ; else
- ; returns TRUE after setting up grs.oRsCur, grs.otxCur
- ;
- ;************************************************************************
- cProc ContContext,<PUBLIC,NEAR>
- cBegin
- mov ax,[grs.GRS_otxCONT]
- mov [grs.GRS_otxCur],ax
- inc ax ;test for UNDEFINED
- mov ax,[grs.GRS_oRsCONT]
- jne CanCont
- ;we can't continue, use 'main' module if there is one
- mov ax,[grs.GRS_oMrsMain]
- inc ax
- je CcExit ;brif no main module
- mov [grs.GRS_otxCur],0 ;grs.otxCur = 0
- dec ax
- ;ax = oRs containing next stmt to be executed
- CanCont:
- cCall UiRsActivate,<ax>
- mov ax,sp ;return TRUE
- CcExit:
- or ax,ax ;set condition codes for caller
- cEnd
- ;************************************************************************
- ; boolean NeedContContext()
- ; Purpose:
- ; Make the current MRS and PRS the one where BASIC's program counter
- ; is pointing. If CONTinue is not possible, make main module active.
- ;
- ; Exit:
- ; If unable to CONT and no main module
- ; [uierr] = MSG_NoMainProg
- ; txtErr.oRs = UNDEFINED (so cursor won't be positioned by ReportError)
- ; returns FALSE
- ; else
- ; returns TRUE after setting up grs.oRsCur, grs.otxCur
- ;
- ;************************************************************************
- cProc NeedContContext,<PUBLIC,NEAR>
- cBegin
- call ContContext ;activate CONT program counter
- jne CcNoErr ;brif can CONT
- PUSHI ax,MSG_NoMainProg
- call SetUiErr
- xor ax,ax ; set ax and condition codes
- CcNoErr:
- cEnd
- sEnd CP
- end