📄 context.asm
字号:
pop ax ;restore ax = oMrsCur
;now unlink this entry from the mrs chain and link it into the free
; mrs chain
GETRS_SEG es,bx,<SIZE,LOAD>
mov bx,ax ;ax = bx = oMrs we're unlinking
RS_BASE add,bx ;PTRRS:bx = pMrs we're unlinking
mov cx,ax
xchg cx,[oFreeMrsFirst] ;cx = offset to first free mrs,
; this mrs is new first free
xchg PTRRS[bx.MRS_oMrsNext],cx ;mrs now linked into free list
;now, cx is the offset to the next mrs in the active chain; use
; that to unlink this mrs from the active chain
mov bx,OMRS_GLOBAL ; start from global mrs
UnLink_Loop:
RS_BASE add,bx
mov dx,PTRRS[bx.MRS_oMrsNext] ;offset to next mrs in chain
cmp dx,ax ;found previous chain entry?
jz UnLinkIt ; brif so
mov bx,dx ;advance to next entry
jmp UnLink_Loop
UnLinkIt:
mov PTRRS[bx.MRS_oMrsNext],cx ;unlink the discarded mrs
push sp ; Default return value
; Assumes:
; sp != 0
; sp != UNDEFINED
test [conFlags],F_CON_LeaveTMrsEmpty ;should we just leave tMrs
; empty if this was only mrs?
jnz MrsDiscard_Exit ;brif so
Mrs_No_Trim:
push ax ;pass oMrsCur to WnReAssign
call MrsTableEmpty ;PSW.Z clear if no mrs's
; bx = remaining oMrs (if any)
push bx ;pass oMrsNew to WnReAssign
jnz MrsDiscard_Exit1 ;brif mrs table not empty
call far ptr MakeInitMrs ;make initial mrs
; (certain it won't run out
; of memory here ...)
DbAssertRel ax,z,0,CP,<MrsDiscard: MakeInitMrs returned an error code>
pop bx ;discard invalid oMrsNew
pop dx ; Get oMrsOld
pop ax ; discard default ret val
pushi ax, UNDEFINED ; return UNDEFINED to
; indicate MakeInitMrs called
push dx ; Put oMrsOld back
push [grs.GRS_oMrsCur] ;pass oMrsNew to WnReAssign
cCall MrsDeActivate ;don't want it active
MrsDiscard_Exit1:
PUSHI ax,0 ;not just renaming an oRs
call WnReAssign ;parms already pushed
MrsDiscard_Exit:
pop ax ; Get return value
MrsDiscard_Exit2:
cEnd MrsDiscard
;***
;UnlinkFreeMrs
;Purpose:
; Given an oMrs, search the free mrs chain for the oMrs and unlink it
; from the chain if found.
;Input:
; ax = oMrs to be unlinked from the free list
;Exit:
; none
;******************************************************************************
UnlinkFreeMrs PROC NEAR
GETRS_SEG es,bx,<SIZE,LOAD> ; prepare for link work
mov dx,[oFreeMrsFirst]
inc dx
jz UnlinkEmpty_Done ;free chain is empty
dec dx
cmp ax,dx
jnz Unlink_Unnamed_Entry ;brif unnamed hole not first free
mov bx,dx
RS_BASE add,bx
mov dx,PTRRS[bx.MRS_oMrsNext]
mov [oFreeMrsFirst],dx ;unlink complete
jmp short UnlinkEmpty_Done
Unlink_Unnamed_Entry:
mov bx,dx
RS_BASE add,bx
mov dx,PTRRS[bx.MRS_oMrsNext]
inc dx
jz UnlinkEmpty_Done ;unnamed mrs hole not in free list
dec dx
cmp ax,dx
jnz Unlink_Unnamed_Entry
xchg dx,bx
RS_BASE add,bx
mov cx,PTRRS[bx.MRS_oMrsNext]
xchg dx,bx
mov PTRRS[bx.MRS_oMrsNext],cx ;unlink complete
UnlinkEmpty_Done:
ret
UnlinkFreeMrs ENDP
;***
;MrsMake(ogNam, flags)
;
;Purpose:
; The user-interface is the only QBI component which deals in any way with
; module names. A module's name is the same as the path name from which it
; was loaded. This function searches for a module by the name 'ogNam'. If
; found, an error code is returned (ER_DD). If not found, it creates
; a new Mrs entry and names it 'ogNam'. Calls the TextMgr routine
; TxtCurInit() to initialize the text table. Calls the Variable Manager's
; MakeMrsTVar() if this mrs is not for a text object.
;
; Note that if we're making a named mrs and there exists an empty unnamed
; mrs (which can only be at a specific offset from the start of the
; table), we'll just discard the empty unnamed one, and use that as a
; hole to put the new mrs in.
;
; Note also that, if there is no MAIN module on successful conclusion of
; this routine, the new current module will be made the MAIN one.
;
;Entry:
; ogNam:
; If module's name is to be 'Untitled',
; ogNam = OGNAM_UNNAMED
; else if module is the global module (created only once)
; ogNam = OGNAM_GMRS
; else if module is for some other special purpose
; ogNam <= OGNAM_PSEUDO_MAX
; else
; ogNam is an offset into the global name table for this module name
; flags:
; low byte = initial value of MRS_flags
; high byte = initial value of MRS_flags2
; Command Window: FM2_NoPcode
; ClipBoard: FM2_NoPcode
; Module: FM2_File
; Include File: FM2_File + FM2_Include
; Document File: FM2_File + FM2_NoPcode
; If either FM2_Include or FM2_NoPcode are set:
; - we must NOT replace the existing first module even if it's empty
; - this mrs can never be made the MAIN module
; - it can never have oMrs of 0
; - this mrs can never have a variable table (or be scanned to
; SS_PARSE or SS_EXECUTE)
;Exit:
; if no error
; AX = 0
; grs.oMrsCur = new module's oMrs
; grs.oPrsCur = UNDEFINED
; all fields in mrsCur are setup
; all fields in txdCur are setup
; rsNew = module's oMrs (tell's user interface to show list window)
; else
; caller can count on the input mrsCur being still active
; if out of memory error, AX = ER_OM
; if a matching module is found, AX = ER_DD and [oRsDupErr] =
; oRs of existing module with same name.
;Uses:
; none.
;Exceptions:
; none.
;*******************************************************************************
cProc MrsMake,<PUBLIC,FAR,NODATA>,<SI,DI>
parmW ogNam
parmW flags
localB fUsingUnNamed_Mrs
localB fGrewRsTable
cBegin MrsMake
mov word ptr [fGrewRsTable],FALSE ; initialize both
; fUsingUnNamed_Mrs and
; fGrewRsTable with one mov
mov di,[grs.GRS_oMrsCur] ; save grs.oMrsCur
cmp [ogNam],OGNAM_GMRS ; making global mrs?
DJMP jz Make_gMrs ; brif so - special case
call AlphaORsFree ;release table of sorted oRs's
cCall MrsDeActivate ;save existing mrs, empty mrsCur
mov al,PT_NOT_PROC ;signal to search tMrs, not tPrs
cCall RsTableSearch,<ogNam> ; returns oMrs if entry
; found, or
mov dx,UNDEFINED
cmp ax,dx ; UNDEFINED if not found
; also puts oHole in bx
jnz Make_Mrs_DD_ER ;brif entry was found
inc dx ;now dx == 0
.errnz OGNAM_UNNAMED - 0
mov cx,[ogNam]
cmp cx,dx ; making an unnamed mrs?
jz Make_Unnamed_Mrs ; brif so
cmp cx,OGNAM_PSEUDO_MAX ; some other special ogNam?
jbe Make_Mrs ; brif so
DbChk ogNam,ogNam
test byte ptr ([flags+1]),FM2_NoPcode OR FM2_Include
;is this mrs for a text object?
jnz Make_Mrs ; brif so; keep unnamed mrs
call EmptyMrs ;see if there's an empty
; unnamed mrs
jcxz Make_Mrs ; brif there isn't one
jmp short Use_Empty_Mrs
Make_Mrs_DD_ER:
mov [oRsDupErr],ax ;tell caller oRs of conflict
mov ax,ER_DD
jmp MrsMake_Err_Exit1 ;reactivate input mrsCur & exit
Use_Empty_Mrs:
mov si,SIZE MRS + OMRS_GLOBAL ; oMrs for unnamed entry
push si ;parm to MrsActivateCP
call MrsActivateCP
or [conFlags],F_CON_LeaveTMrsEmpty ;so MrsDiscard won't create a
; new module after discarding!
cCall MrsDiscard ;discard empty unnamed mrs
and [conFlags],NOT F_CON_LeaveTMrsEmpty ;reset to default
mov [fUsingUnNamed_Mrs],TRUE ;in case of later OM error
mov ax,si ;oMrs to unlink from free list
call UnlinkFreeMrs ;unlink the entry from the
; free list, (MrsDiscard
; linked it in)
jmp SHORT Init_New_Mrs1
Make_Text_Mrs:
or bx,bx
jnz Make_Mrs
dec bx ;if making a text mrs, CANNOT
; allow it to go in @ offset 0
jmp short Make_Mrs
Make_Unnamed_Mrs:
mov ax,SIZE MRS + OMRS_GLOBAL ;offset that empty unnamed mrs
; MUST go at (parm to UnlinkFree Mrs)
mov si,ax
call UnlinkFreeMrs ;unlink the entry from the
mov bx,si ; offset that empty unnamed
; mrs MUST go at
cmp bx,[grs.GRS_bdRs.BD_cbLogical] ;is the table empty?
jz Make_Mrs_Grow
Init_New_Mrs1:
jmp short Init_New_Mrs
Make_gMrs:
mov si,OMRS_GLOBAL ; new oMrs
PUSHI ax,<dataOFFSET grs.GRS_bdRs>
PUSHI ax,<SIZE MRS + OMRS_GLOBAL>
call BdGrow
jmp short Make_Mrs_Grow_1
Make_Mrs:
mov si,bx ;save hole location
cmp si,UNDEFINED ;is there a hole in table?
jz Make_Mrs_Grow ; brif not
DbAssertRel bx,z,oFreeMrsFirst,CP,<MrsMake: given hole not first free>
RS_BASE add,bx
mov bx,PTRRS[bx.MRS_oMrsNext]
mov [oFreeMrsFirst],bx ;free entry now unlinked from
; free mrs chain
GETRS_SEG es,bx,<SIZE,LOAD>
jmp short Init_New_Mrs
Make_Mrs_Grow:
mov si,[grs.GRS_bdRs.BD_cbLogical] ;new oMrs
or si,si ; Rs table > 32k?
js J_MrsMake_OM_Err ; brif so ... give OM error
PUSHI ax,<dataOFFSET grs.GRS_bdRs>
PUSHI ax,<SIZE MRS>
call BdGrow
Make_Mrs_Grow_1:
or ax,ax
jnz @F ; brif successful
J_MrsMake_OM_Err:
jmp MrsMake_OM_Err
@@:
mov [fGrewRsTable],TRUE ; remember we grew in case
; later error
Init_New_Mrs:
mov ax,dataOFFSET mrsCur
mov bx,SIZE MRS
mov cx,MRS_CB_ZERO_INIT
call InitStruct
mov [mrsCur.MRS_cbFrameVars],-FR_FirstVar ;
; reset to init. value. This
; value is 2 to account for
; the fact that b$curframe
; is always pushed on the
; stack after bp, so we
; treat this word as a frame
; var for ref'ing the real
; frame vars off of bp
mov ax,[flags]
mov [mrsCur.MRS_flags],al
mov [mrsCur.MRS_flags2],ah
mov ax,si
call SetMrsAx ;grs.oMrsCur = oRsCur = ax
GETRS_SEG es,bx,<SIZE,LOAD>
mov bx,si ;oMrsNew
RS_BASE add,bx ;add base of tRs to bx
mov PTRRS[bx.MRS_ogNam],UNDEFINED ;mark entry as inactive, since
; mrsCur has actual mrs
mov PTRRS[bx.MRS_oMrsNext],UNDEFINED ;in case someone tries to walk
; the mrs chain before this
; mrs gets deactivated
cCall TxtCurInit ;init txdCur
jnz no_error
jmp MrsMake_TxtInit_Err
no_error:
test byte ptr ([flags+1]),FM2_NoPcode; is a document mrs?
jz MakeVarTables ; brif not, create tables
call NewBuf ; allocate document buffer
mov WORD PTR [mrsCur.MRS_pDocumentBuf],ax ; set ptr to buffer
or ax,ax ; was it successful?
mov al,ER_OM ; assume not, set error
jz MrsMake_OM_2_Err ; brif out of memory
jmp SHORT MrsMake_Name ; finish creating txt tbl
MakeVarTables:
cCall MakeMrsTVar ; set up module var table
or ax,ax
jz MrsMake_OM_2_Err
mov ax,SbGNam ; assume global mrs
cmp [ogNam],OGNAM_GMRS ; making global mrs?
jz MrsMake_TNam ; brif so
sub ax,ax ; don't use special sb
MrsMake_TNam:
cCall TNamInit,<ax> ; set up module name table
or ax,ax
jz MrsMake_OM_3_Err
MrsMake_Name:
mov ax,[ogNam]
mov [mrsCur.MRS_ogNam],ax ; set module name
mov [mrsCur.MRS_oMrsNext],UNDEFINED
.errnz 1 - OGNAM_GMRS
dec ax ; is this the global module?
jz MrsMake_Exit ; brif so - exit (this
; mrs doesn't have to be
; linked, as it's known
; to be at offset 0)
;After this point, no errors can occur, so its ok to tell
;user interface the oRs of the new module
xchg ax,dx
mov ax,[grs.GRS_oMrsCur]
mov [rsNew],ax ;tell user interface to
; show new mrs in list window
Link_Mrs:
;Now, link this module into mrs chain
GETRS_SEG es,bx,<SIZE,LOAD>
mov bx,OMRS_GLOBAL ;start with global mrs
MrsLink_Loop:
RS_BASE add,bx
mov dx,PTRRS[bx.MRS_oMrsNext]
inc dx
.errnz UNDEFINED - 0FFFFH
jz GotChainEnd ;brif bx points to last current
; entry in the mrs chain
dec dx
mov bx,dx
jmp MrsLink_Loop
GotChainEnd:
mov PTRRS[bx.MRS_oMrsNext],ax ;link new entry at end of chain
;Note that the oMrsNext field in the new entry will automatically be
;UNDEFINED in the new entry, and we set it to UNDEFINED earlier in
;this routine
xor ax,ax
test byte ptr ([flags+1]),FM2_NoPcode OR FM2_Include
;is this mrs for a text or
; INCLUDE object?
jnz Main_Set2 ; brif so - IT can't be MAIN
dec ax
.errnz UNDEFINED - 0FFFFh
cmp [grs.GRS_oMrsMain],ax ;is there already a MAIN module?
jz Main_Set0 ; brif not
call MainModified ;mark main module as modified
; if current mrs is pcode
; mrs (so we will be sure
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -