📄 fhinit.asm
字号:
TITLE FHINIT - Far Heap Initialization and Support
PAGE 56,132
;***
;FHINIT.ASM - Far Heap Initialization for the BASIC 3 Common Runtime
;
; Copyright (C) Microsoft Corp. 1986.
;
;*****************************************************************************
SUBTTL INCLUDES AND DEFINITIONS FOLLOWS
INCLUDE switch.inc
INCLUDE rmacros.inc
USESEG <INIT_CODE> ;Initialization
USESEG <BR_DATA>
USESEG <_DATA>
USESEG <_BSS>
USESEG <NH_TEXT>
USESEG <RT_TEXT>
USESEG <FH_TEXT>
USESEG <DV_TEXT>
USESEG <XIB>
USESEG <XI>
USESEG <XIE>
USESEG <BC_SAB>
USESEG <BC_SA>
INCLUDE seg.inc
INCLUDE idmac.inc
INCLUDE messages.inc
INCLUDE compvect.inc
INCLUDE array.inc
INCLUDE smchain.inc
INCLUDE oscalls.inc
INCLUDE addr.inc
INCLUDE baslibma.inc
INCLUDE string.inc
INCLUDE stack2.inc
externFP B$ERR_OM_FH ; out of memory error
externFP B$ERR_MEM ;arena destroyed error
externNP B$ERR_FHC ;bad memory block address
externFP B$ULAllocDataImage ;alloc UL data images for restart
externFP B$ULDataRelease ;dealloc UL data images
externFP CompressHelp ; compress and close help system
externFP ShrinkHelp ; compress help system (stay open)
externFP fEditorActive
externFP CompressBufs
INITIALIZER B$xFHINI ;put B$xFHINI in initializer list.
SUBTTL DATA DEFINITIONS
sBegin BR_DATA
externW __acmdseg ; C startup __psp
sEnd BR_DATA
sBegin _DATA
externW b$ini_disp ;One time initialization dispatch table
externW b$clrt_disp ;CLEAR dispatch table
externW b$run_disp ;RUN dispatch table
externW b$pFHRaiseBottom ;Vector to B$FHRaiseBottom
externW b$pFHLowerTop ;Vector to B$FHLowerTop
externW b$shli_disp ;Shell initialization dispatch table
externW b$shlt_disp ;Shell termination dispatch table
externB b$Chaining ;non-zero if we are CHAINING
sEnd _DATA
sBegin _BSS
globalB b$FHDStart,,<SIZE FHD> ; starting FHD for list
globalB b$FHDEnd,,<SIZE FHD> ;ending FHD for list
externW b$NH_first ;NHINIT - starting offset of near heap
externW b$NH_last ;NHINIT - ending offset of near heap
externW b$UcodeOff ;offset of usercode header
externW b$UcodeSeg ;segment of usercode header
sEnd _BSS
sBegin DV_TEXT
externNP B$NearRet ;for disp vectors in compvect.inc
sEnd DV_TEXT
sBegin NH_TEXT
externNP B$NHMOV ;move near heap
sEnd NH_TEXT
sBegin RT_TEXT
sEnd RT_TEXT
PAGE
SUBTTL Far Heap Initialization
assumes CS,INIT_CODE
sBegin INIT_CODE
;***
;B$xFHINI - Far Heap initializer
;PLM B$xFHINI()
;
;Purpose:
; Initializer for Far Heap component. This routine is called
; by the Crt0 startup before _main is called. It will update the
; indirect dispatch tables for the far heap routines. This
; insures that the only time that the far heap is accessed is when
; this module is linked into the user program.
;
;Entry:
; None.
;
;Exit:
; Appropriate dispatch vectors filled.
;
;Uses:
; None.
;
;Exceptions:
; None.
;****************************************************************************
cProc B$xFHINI,<FAR>
cBegin
; update "ONE" time initialization dispatch address to B$FHIni
MOV WORD PTR [b$ini_disp].FH_IVEC,FH_TEXTOFFSET B$FHIni
; update CLEAR time initialization dispatch address to B$FHClear
MOV WORD PTR [b$clrt_disp].FH_CLTVEC,FH_TEXTOFFSET B$FHClear
; update RUN time initialization dispatch address to B$FHClear
MOV WORD PTR [b$run_disp].FH_RVEC,FH_TEXTOFFSET B$FHClear
cEnd
sEnd INIT_CODE
ASSUMES CS, FH_TEXT
sBegin FH_TEXT
;***
; B$FHIni - One time initialization for far heap (DOS 3 & 5)
;
;Purpose:
; One time initialization for the far heap. For DOS 3, this routine
; allocates all available memory and sets up the initial free space.
; Set vector b$pFHRaiseBottom to B$FHRaiseBottom (DOS 3).
; Set vector b$pFHLowerTop to B$FHLowerTop (DOS 3).
;
;Entry:
; None.
;
;Exit:
; Allocates memory and inits descriptor chain (DOS 3)
;
;Uses:
; None.
;
;Exceptions:
; Out of memory condition if allocation cannot be done.
;******************************************************************************
FHIniError:
JMP B$ERR_MEM ;report out of memory error
DbPub B$FHIni
cProc B$FHIni,<NEAR>,<ES>
cBegin
MOV b$pFHRaiseBottom, FH_TEXTOFFSET B$FHRaiseBottom
MOV b$pFHLowerTop, FH_TEXTOFFSET B$FHLowerTop
MOV ES,__acmdseg ;get address for CODE/DGROUP block
MOV BX,0FFFFH ;ask for maximum memory possible...
MOV AH,4AH ;so DOS will get maximum size...
CALL B$FHMemDosCall ;call to perform INT and handle fatal errors
JNC FHIniError ;call should always fail
MOV AH,4AH ;allocate the maximum block, leaving none
CALL B$FHMemDosCall ;remaining for any other process
JC FHIniError ;error if allocation failed
; Build the FHD list static descriptors b$FHDStart and b$FHDEnd.
MOV AX,b$NH_last ;get last offset of near heap
INC AX ;nxt word (+2) + nxt para (+0F) - one para (10)
MOV CL,4 ;...and shift by four...
SHR AX,CL ;...to get paragraph size
INC AX ;put paragraph back that was subtracted
MOV CX,DS ;get starting segment of DGROUP
ADD CX,AX ;add to get lower boundary paragraph
MOV b$FHDEnd.FHD_hData,CX ;put lower boundary in static descriptor
MOV CX,ES ;get start of CODE/DGROUP block
ADD CX,BX ;add maximum size to get upper boundary
MOV b$FHDStart.FHD_hData,CX ; put upper boundary in static desc
XOR AX,AX ;clear for repeated use below
MOV b$FHDStart.FHD_cPara,AX ; size of starting entry in list is zero
MOV b$FHDStart.FHD_pNext,OFFSET DGROUP:b$FHDEnd ; start points to end
MOV b$FHDEnd.FHD_cPara,AX ;size of ending entry in list is zero
MOV b$FHDEnd.FHD_pNext,AX ;last entry points to null - end of list
; Allocate Preinited Data images for quick restartability
CALL B$ULAllocDataImage
cEnd
;***
; B$FHClear - CLEAR support for far heap
;
;Purpose:
; Added routine as part of revision [22].
; Far heap support for the CLEAR statement. Deallocate all
; entries either in COMMON or in the user variables.
;Entry:
; None.
;Exit:
; None.
;Uses:
; None.
;Exceptions:
; None.
;******************************************************************************
cProc B$FHClear,<NEAR,PUBLIC>,<BX,ES>
cBegin
CMP b$UcodeSeg,0 ;test if any compiled code
JZ FHClearRet ;if not, just return
LES BX,DWORD PTR b$UcodeOff ;ES:BX = seg:off of usercode header
MOV AX,OFFSET FHClearEntry ;get offset to routine for each entry
CALL B$FHSelect ;select the far heap entries to deallocate
FHClearRet:
cEnd
;***
; FHClearEntry - FHSelect routine for CLEAR support
;
;Purpose:
; Added as part of revision [22].
; Returns flag to deallocate any FH entry in COMMON or
; the user variables.
;Entry:
; ES:BX = far pointer to usercode header
; SI = pointer to FH descriptor to check.
;Exit:
; AX = 0 - do not deallocate entry described at SI.
; AX <> 0 - deallocate entry described at SI.
;Uses:
; None.
;Exceptions:
; None.
;******************************************************************************
cProc FHClearEntry,<NEAR>,<SI>
cBegin
MOV AX,-1 ;default to deallocate entry
; Test if descriptor is in the user variables. If so, flag deallocation.
CMP SI,ES:[BX].OF_DAT ;test against lower bound of user variables
JB FHClrEntCommon ;if too low, then test for COMMON area
CMP SI,ES:[BX].OF_FT ;test against upper bound of user variables
JB FHClrEntDealloc ;if within bounds, then jump to flag deallocate
; Test if descriptor is in COMMON. If so, flag deallocation.
FHClrEntCommon:
CMP b$Chaining,0 ;are we CHAINing in interpreter?
JNZ FHClrEntNoDealloc ;don't deallocate COMMON entries if so
SUB SI,ES:[BX].OF_COM ; compute offset of descriptor in COMMON
JB FHClrEntNoDealloc ;if below COMMON, then flag no dealloc
CMP SI,ES:[BX].SZ_COM ; test if offset if with COMMON
; this use of SZ_COM is OK, since we are
; looking at ALL the modules
JB FHClrEntDealloc ;if in COMMON, then deallocate
; Increment AX to 0 for no deallocation, else leave at -1.
FHClrEntNoDealloc:
INC AX ;set to zero for no deallocation
FHClrEntDealloc:
cEnd
SUBTTL B$FHClearRange - Delete entries in a range
PAGE
;***
; B$FHClearRange - Delete entries in a range (QBI Only)
; Added Rev [39]
; needed for BC6 also now
;
;Purpose:
; Delete all far heap entries whose descriptors fall into a passed DGROUP
; range.
;
;Entry:
; [AX] = start of the range to deallocate in
; [BX] = end of range
;
;Exit:
; none
;
;Uses:
; Per convention
;
;******************************************************************************
cProc B$FHClearRange,<NEAR,PUBLIC>
cBegin
XCHG AX,CX ;[CX] = start of range
MOV AX,OFFSET FHClearRangeEntry
Call B$FHSelect
cEnd
;***
; B$FHClearRangeEntry - Delete entry if in a range (QBI Only)
; needed for BC6 also now
; Added Rev [39]
;
;Purpose:
; Delete far heap entry if descriptor falls into a passed DGROUP range.
;
;Entry:
; [CX] = start of the range to deallocate in
; [BX] = end of range
; [SI] = address of heap descriptor
;
;Exit:
; [AX] = Non-zero if entry to be deallocated
;
;Uses:
; Per convention
;
;******************************************************************************
cProc FHClearRangeEntry,NEAR
cBegin
XOR AX,AX ;Assume not deallocating
CMP SI,CX
JB ClearRangeSkip ;Jump if below range
CMP SI,BX
JA ClearRangeSkip ;Jump if above range
DEC AX ;[AX] = -1
ClearRangeSkip:
cEnd
;***
;B$FHAllocFAR - far entrypoint for B$FHAlloc.
;
;Purpose:
; Added with revision [75].
; Far entrypoint for B$FHAlloc (called from LOADRTM segment).
;Entry:
; Same as B$FHAlloc
;Exit:
; Same as B$FHAlloc
;Uses:
; Same as B$FHAlloc
;Exceptions:
; Same as B$FHAlloc
;******************************************************************************
cProc B$FHAllocFAR,<FAR,PUBLIC>
cBegin
CALL B$FHAlloc
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -