📄 txtmove.asm
字号:
; within the current text table. Typically used to make room
; for text to be inserted.
;
; Entry:
; parmW otxSrcLow: offset of source of lowest byte to be moved
; parmW cbIns: number of bytes to make room for
; if grs.fDirect is TRUE,
; grs.bdlDirect (the direct mode pcode buffer) is the buffer to
; be shifted, and grs.bdlDirect.cbLogical = current logical
; size of text table
; else txdCur.bdlText is the buffer to be shifted and
; txdCur.bdlText.cbLogical = current logical size of text table
;
; Exit:
; returns ax = zero if out-of-memory, else non-zero
; condition codes set based on value in ax
; if grs.fDirect is TRUE
; grs.bdlDirect.cbLogical is updated for the move
; else
; txdCur.bdlText.cbLogical is updated for the move
;
; Example:
; Before:
; high memory
; txdCur.TXD_bdlText_cbLogical->+-----+
; | E |
; otxSrcLow + cbIns------------>| D |
; | C |
; otxSrcLow-------------------->| B |
; | A |
; low memory +-----+
;
; After:
; high memory
; txdCur.TXD_bdlText_cbLogical->+-----+
; | E |
; | D |
; | C |
; otxSrcLow + cbIns------------>| B |
; | - |
; otxSrcLow-------------------->| - |
; | A |
; low memory +-----+
;
;*************************************************************************
cProc TxtMoveUp,<PUBLIC,NODATA,NEAR>,<si,di>
parmW otxSrcLow
parmW cbIns
cBegin TxtMoveUp
DbChk Otx,otxSrcLow ;assert otxSrcLow is valid
DbChk TxdCur ;perform sanity check on txdCur
mov si,[otxSrcLow] ;si = source offset
; (is parm for TxtAdjust)
call TxtChkCache ;adjust/reset cached text offsets
;reset History and Watch info too
push [cbIns]
call TxtFree ;make sure we have enough free space
je TxtMoveUpExit ;brif out-of-memory
GetSegTxtCur ;es = seg adr of current txt tbl
; (this may be direct mode buffer)
mov dx,[cbIns] ;dx = #bytes to insert
mov bx,dataOFFSET grs.GRS_bdlDirect_cbLogical
cmp [grs.GRS_fDirect],FALSE
jne Up_InDirMode ;branch if in direct mode
mov bx,dataOFFSET txdCur.TXD_bdlText_cbLogical
Up_InDirMode:
mov di,si ;di = source offset
add di,dx ;di = destination offset
mov cx,[bx] ;cx = current size of text table
add [bx],dx ;update cbLogical for move
sub cx,si ;cx = # bytes to copy
add di,cx ;start copying at top of block
dec di ; so we don't overwrite end of
dec di ; source before we've copied it
add si,cx
dec si
dec si
shr cx,1 ;we will move words
DbAssertFlags nc,CP,<TxtMoveUp: err1>
push ds ;save caller's ds
push es ;push seg adr of current txt tbl
pop ds ;set up source seg
std ;copy moving down
rep movsw
cld ;always leave D flag clear by convention
pop ds ;restore caller's ds
mov ax,sp ;success result
TxtMoveUpExit:
or ax,ax ;set condition codes for caller
cEnd TxtMoveUp
cProc TxtMoveUpFar,<PUBLIC,NODATA,FAR>
parmW otxSrcLow
parmW cbIns
cBegin TxtMoveUpFar
cCall TxtMoveUp,<otxSrcLow, cbIns>
cEnd TxtMoveUpFar
;*************************************************************************
; TxtMoveDown(otxSrcLow, otxDstLow)
;
; Purpose:
; Move a block of text from a high address to a lower address
; within the current text table. Typically used to delete text.
;
; Entry:
; parmW otxSrcLow: offset of source of lowest byte to be moved
; parmW otxDstLow: offset of destination of lowest byte to be moved
; if grs.fDirect is TRUE,
; grs.bdlDirect (the direct mode pcode buffer) is the buffer to
; be shifted, and grs.bdlDirect.cbLogical = current logical
; size of text table
; else txdCur.bdlText is the buffer to be shifted and
; txdCur.bdlText.cbLogical = current logical size of text table
;
; Exit:
; if grs.fDirect is TRUE
; grs.bdlDirect.cbLogical is updated for the move
; else
; txdCur.bdlText.cbLogical is updated for the move
;
; Example:
; Before:
; high memory
; txdCur.TXD_bdlText_cbLogical->+-----+
; | F |
; | E |
; otxSrcLow-------------------->| D |
; | C |
; otxDstLow-------------------->| B |
; | A |
; low memory +-----+
;
; After:
; high memory
; txdCur.TXD_bdlText_cbLogical->+-----+
; otxSrcLow-------------------->| F |
; | E |
; otxDstLow-------------------->| D |
; | A |
; low memory +-----+
;
;*************************************************************************
cProc TxtMoveDown,<PUBLIC,NODATA,NEAR>,<si,di>
parmW otxSrcLow
parmW otxDstLow
cBegin TxtMoveDown
DbChk Otx,otxDstLow
DbChk Otx,otxSrcLow
DbChk TxdCur ;perform sanity check on txdCur
mov si,[otxDstLow] ;si = destination offset
; (is parm for TxtAdjust)
call TxtChkCache ;adjust/reset cached text offsets
;reset History and Watch info too
GetSegTxtCur ;es = seg adr of cur txt tbl
mov di,si ;di = destination offset
mov si,[otxSrcLow] ;si = source offset
mov dx,si ;dx = source offset
sub dx,di ;dx = number of bytes being deleted
mov bx,dataOFFSET grs.GRS_bdlDirect_cbLogical
cmp [grs.GRS_fDirect],FALSE
jne Dn_InDirMode ;branch if in direct mode
mov bx,dataOFFSET txdCur.TXD_bdlText_cbLogical
Dn_InDirMode:
mov cx,[bx] ;cx = current size of text table
sub [bx],dx ;update cbLogical for move
sub cx,si ;cx = # bytes to copy
shr cx,1 ;move words instead of bytes
DbAssertFlags nc,CP,<TxtMoveDown: err1>
push ds ;save caller's ds
push es ;push seg adr of current text tbl
pop ds ;set up source seg
rep movsw ;copy block
pop ds ;restore caller's ds
cEnd TxtMoveDown
;*************************************************************************
; TxtFree
;
; Purpose:
; Ensure that the current text table's cbPhysical exceeds its cbLogical
; by a given value, i.e. guarentee a given amount of free space.
; Entry:
; parm1: ushort cbFree
; if grs.fDirect is TRUE,
; table grs.bdlDirect is checked
; else
; table txdCur.bdlText is checked
; Exit:
; returns ax = zero if out-of-memory, else non-zero
; condition codes set based on value in ax
;
;*************************************************************************
cProc TxtFree,<PUBLIC,NODATA,NEAR>
parmW cbFree
localW fDirectMode
cBegin TxtFree
DbChk TxdCur ;perform sanity check on txdCur
mov [fDirectMode],0 ;default not directmode buffer
mov ax,dataOFFSET txdCur.TXD_bdlText
cmp [grs.GRS_fDirect],FALSE
je NotDirMode ;branch if not in direct mode
mov ax,dataOFFSET grs.GRS_bdlDirect
mov [fDirectMode],sp
NotDirMode:
push ax ;pass adr of bdl for text table
push cbFree
call BdlCheckFree ;ax = result
or ax,ax ;set condition codes for caller
jne TxtFreeExit ;brif not out of memory
; We have an out of memory error. Determine what caused the error so
; we can give the user a better idea of how to resolve the problem.
; If the we attempted to grow the text table beyond 64k then we will
; set the variable b$errinfo to one of the following values:
; Not changed - Was direct mode buffer, or legit out of memory.
; OMErr_Mod - Module level code blew past 64k.
; OMErr_Proc - Procedure level code blew past 64k.
; OMErr_Inc - Include file blew past 64k.
; OMErr_Doc - Document blew past 64k.
cmp [fDirectMode],0 ;was it the direct mode buffer?
jne TxtFreeOmExit ;brif so, standard OM error
mov ax,[txdCur.TXD_bdlText_cbLogical] ;get current size of text table
add ax,[cbFree] ;add requested increment
jnc TxtFreeOMExit ;brif request wasn't > 64K
.errnz OMErr_Mod-OMErr_Proc-1
.errnz OMErr_Inc-OMErr_Mod-1
.errnz OMErr_Doc-OMErr_Inc-1
mov cx,OMErr_Proc ;assume we are in a SUB/FUNC
test [txdCur.TXD_flags],FTX_mrs ;is this a SUB/FUNC?
je TxtFreeOMSet ;brif so, set b$errinfo
mov al,[mrsCur.MRS_flags2]
inc cx ;assume in a MODULE
test al,FM2_NoPcode OR FM2_Include ;is this an Include/Document?
je TxtFreeOMSet ;brif not, module text table
inc cx ;assume an INCLUDE file
test al,FM2_Include ;is this an include?
jne TxtFreeOMSet ;brif so
inc cx ;must be a document
DbAssertTst al,ne,FM2_NoPcode,CP,<TxtFree: Expected a Document txt table>
TxtFreeOMSet:
mov [b$errinfo],cl ;set extended OM error code
TxtFreeOMExit:
sub ax,ax ;set ax and condition codes for caller
TxtFreeExit:
cEnd TxtFree
cProc TxtFreeFar,<PUBLIC,NODATA,FAR>
parmW cbFree
cBegin TxtFreeFar
cCall TxtFree,<cbFree>
cEnd TxtFreeFar
;*************************************************************************
; TxtPrsInit
; Purpose:
; This is called by User Interface code after File/New/Sub
; to put the following pcode into the newly created text table:
; DEFxxx state from the end of the module so user who has
; DEFINT A-Z in module will get it in SUB as well.
; SUB/FUNCTION name
; END SUB/FUNCTION
; Entry:
; prs in question is active
; otype - If proc is a FUNCTION then otype is its return type
; Exit:
; No error return. If out of memory, the user just gets an
; empty text table.
;
;*************************************************************************
cProc TxtPrsInit,<PUBLIC,FAR>,<si,di>
parmB oType
cBegin
;Following is guarenteed by by PrsMake()
DbAssertRel [grs.GRS_oMrsCur],e,[prsCur.PRS_oMrs],CP,<TxtPrsInit: err2>
DbAssertTst [txdCur.TXD_flags],Z,FTX_mrs,CP,<TxtPrsInit: got an mrs>
and [prsCur.PRS_flags],NOT FP_STATIC
;in case this prs used to have a
; txt tbl, with FP_STATIC bit set,
; and then prs was discarded. FP_STATIC
; would still be set.
SetStartOtx di ;otxInsert = 0
push di ;pass otxInsert
PUSHI ax,16d ;we're about to insert 16 bytes
call TxtMoveUp ;make room for pcode to be inserted
je TxtPExit ;brif out-of-memory
GetSegTxtTblCur es ;es = seg adr of txt tbl
sub ax,ax ;ax = opBol
.errnz opBol
stosw ;emit opBol
mov ax,opStSub
cmp [prsCur.PRS_procType],PT_SUB
je TxtSub
mov ax,opStFunction
TxtSub:
stosw ;emit opStSub/opStFunction
mov ax,6
stosw ;emit cntEos operand
mov ax,[grs.GRS_oPrsCur]
stosw ;emit oPrs operand
.errnz ET_IMP
sub ax,ax ;al = ET_IMP
mov ah,[prsCur.PRS_procType];ah = PT_SUB or PT_FUNCTION
cmp ah, PT_FUNCTION
jne @F
mov al, [otype]
.errnz ET_IMP
or al,al ;ET_IMP?
jz @F ;brif yes.
or ax, DCLA_Explicit
@@:
stosw ;emit oTypFn operand
sub ax,ax
stosw ;emit parm count operand (0)
.errnz opBol ;ax = 0 = opBol
stosw ;emit opBol
mov ax,opStEndProc
stosw
or [mrsCur.MRS_flags2],FM2_Modified
push [grs.GRS_oPrsCur] ;save caller's oPrs
call PrsDeactivate
call OtxDefTypeEot ;fill ps.tEtCur with module's def state
call PrsActivateCP ;reactivate caller's prs
;init default ps.tEtCur[] (default type array)
SetStartOtx ax ;ax = start of text
mov bx,dataOFFSET tEtTemp
call OtxDefType ;fill tEtTemp with default types
; i.e. ET_R4 for all letters
PUSHI ax,<DATAOFFSET tEtTemp>
PUSHI ax,<DATAOFFSET ps.PS_tEtCur>
SetStartOtx ax ;ax = otxInsert = start of text
call InsertEtDiff
SetStartOtx si ;otx for inserted pcode
mov bx,[txdCur.TXD_bdlText_cbLogical]
sub bx,CB_EMPTY_TEXT-StartOtx ;otx beyond end of inserted pcode
call TxtInsUpdate ;update any static structures
; as a result of inserting this pcode.
TxtPExit:
cEnd
;*************************************************************************
; GetWOtx
;
; Purpose:
; Given an offset within the current text table, return
; the 16 bit value stored at that offset.
; Entry:
; ax = otx
; Exit:
; ax = 16 bit value from text table
;
;*************************************************************************
PUBLIC GetWOtx
GetWOtx PROC NEAR
DbChk Otx,ax ;check for invalid text offset
;NOTE - we can't call DbChkTxdCur here because DebChkTxdCur
; calls GetWOtx, which causes infinite recursion.
DbAssertTst [conFlags],nz,F_CON_StaticStructs,CP,<GetWOtx: static structs not enabled>
GetSegTxtTblCur ;es = seg addr of current text table
xchg bx,ax ;bx = offset into text table
mov ax,es:[bx] ;ax = value at that offset
ret
GetWOtx ENDP
;*************************************************************************
; PutWOtx
;
; Purpose:
; Store a 16 bit value at a given offset within the current text table
; Entry:
; parm1: ushort otx
; parm2: ushort value
;
;*************************************************************************
cProc PutWOtx,<PUBLIC,NODATA,NEAR>
parmW otx
parmW value
cBegin PutWOtx
DbChk Otx,otx ;check for invalid text offset
DbChk TxdCur ;perform sanity check on txdCur
GetSegTxtTblCur es ;es = seg adr of txt tbl
mov bx,[otx] ;bx = offset into text table
mov ax,[value] ;ax = value to store at that offset
mov es:[bx],ax ;store it
cEnd PutWOtx
;-----------------------------------------
; Non-RELEASE CP segment Functions
;-----------------------------------------
sEnd CP
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -