📄 rtinit.asm
字号:
TITLE RTINIT - Initialization module for BASIC runtime
;***
;RTINIT.ASM - Initialization module for BASIC runtime
;
; Copyright <C> 1986, Microsoft Corporation
;
;Purpose:
; This module contains the main entry point and initialization
; routines for the BASIC 3.0 runtime. The runtime is designed
; to achieve modularity and granularity between components of
; the runtime. Detailed documentation about the structure of the
; runtime is presented below.
;
; BASIC Syntax mapping to included runtime entry points:
;
;
; - DEF SEG Statement - calls B$DSG0 if no parm, B$DSEG if segment addr given:
;
; DEF SEG [ = seg]
;
; Examples:
;
; DEF SEG DEF SEG = 3000
; ------- --------------
; | |
; B$DSG0 B$DSEG
;
;******************************************************************************
INCLUDE switch.inc ;assembly switch file
INCLUDE rmacros.inc ;segment/C macros
;
; Code Segments
;
USESEG <RT_TEXT> ;runtime core segment
USESEG <FH_TEXT> ;far heap segment
USESEG <NH_TEXT> ;near heap segment
USESEG <DV_TEXT> ;device segment
USESEG <INIT_CODE> ;initialization
USESEG _TEXT ; c
;
; Data Segments
;
USESEG <NULL> ;BegData
USESEG <BR_DATA> ;Hole for runtime module
USESEG <_DATA> ;runtime data (initialized)
USESEG <_BSS> ;runtime data (uninitialized)
USESEG <NMALLOC>
USESEG <ENMALLOC>
USESEG <XIB> ;beginning of C initializers
USESEG <XI> ;C initializers
USESEG <XIE> ;end of C initializers
USESEG <BC_DATA> ;users variables
USESEG <BC_FT> ;end of users variables
USESEG <BC_SAB> ;beginning of user module start address table
USESEG <BC_SA> ;user module start address table
INCLUDE seg.inc ;segment definitions
INCLUDE compvect.inc ;component vector structures
INCLUDE fdb.inc
INCLUDE const.inc ; bit flag constants
INCLUDE stack2.inc ; stack related constants
INCLUDE stack.inc
INCLUDE string.inc
;bring in our versions of C runtime routines.
externFP __chkstk ; drag in CHKSTK
externFP __exit
externFP __ctermsub
externB _end
externFP _exit ; C _exit proc
externFP B$ULtoRTFar ;UL to RT far call helper
externFP B$ULtoRTNear ;UL to RT near call helper
externFP fEditorActive
sBegin NULL
INCLUDE global.inc ;global data definitions
sEnd NULL
INCLUDE addr.inc ;compiled module header structure
INCLUDE idmac.inc ; internal debug macros
INCLUDE ibmunv.inc
INITIALIZER B$xRTINI ;Put B$xRTINI in initializer list
SUBTTL Runtime design
PAGE
;*****************************************************************************
;* BASCOM 3.0 and Quick BASIC Interpreter 3.0
;*
;* The runtime system has been reworked considerably since BASCOM 2.0.
;* The major goals which prompted the revision of the runtime are
;* numerous. A major deficiency in the BASIC language to this point
;* has been the lack of a truly compatable compiler/interpreter pair.
;* In order to resolve this deficiency, the BASIC 3.0 runtime
;* will attempt to achieve this goal without compromising size and
;* speed goals of either the interpreter or the compiler.
;*
;* Another major reason for reworking the runtime is to provide support
;* for the OS/2 environment. The runtime has been enhanced to
;* take advantage of new features provided by the DOS. In addition to
;* the support of new features. Some existing features have been
;* reworked to execute under the constraints of OS/2, while still
;* supporting previous versions of DOS.
;*
;* There have been several new language enhancements made which
;* the runtime has been modified to support. Such items as 4 byte
;* integers, EGA support, and Advanced 101-key Keyboard support have
;* been added to the runtime.
;*
;* The runtime has also been reworked to improve its granularity
;* through a series of techniques to segment and conditionally
;* initialize components of the runtime system.
;*****************************************************************************
SUBTTL Runtime components, segmentation, and granularity
PAGE
;*****************************************************************************
;* Segmentation and Granularity
;*
;* The initialization and segmentation schemes used by the runtime
;* attempt to view the runtime as a collection of individual components
;* which are unique and independent of each other. The intent is that
;* a compiled basic module should have the minimal amount of runtime
;* code present to correctly complete its assigned task. There are
;* two major ways to achieve this goal: 1) conditional initialization
;* of components on an as needed basis and 2) segmentation of compon-
;* ents, therby allowing the operating system to swap out unused segments
;* through an LRU mechanism. We have combined both of these techniques
;* to produce what we hope is the best of both worlds.
;*
;*
;* The common runtime is organized into several components, as follows:
;*
;* Code Contents
;* ------ ---------------------------------------------------------------
;* CN: Screen and Keyboard text I/O.
;* DB: User debug code /D.
;* DK: Disk file related I/O.
;* DV: Device Independant IO support.
;* ER: Error handling & trapping.
;* EV: Event trapping.
;* FH: Far heap manager.
;* GR: Graphics.
;* ID: Internal (development) debugging aids.
;* MT: Floating point math.
;* NH: Near heap manager.
;* OI: Comm/Printer I/O.
;* OS: Operating System functions & features.
;* RT: Runtime core.
;* SN: Sound and music.
;* ST: String package.
;*
;* Each component is further divided into 6 areas, which may or may not
;* be present for each component:
;*
;* Initializer - Updates core dispatch tables for ordered
;* initialization, termination, and indirect dispatches.
;* Initialization - Component-specific initialization.
;* Termination - Component-specific termination.
;* Dispatch - Dispatch tables used for indirect access to routines
;* within the component which may not always be present.
;* Core Code - Code which must always be present for the component.
;* Component Code - Code which is present on an as needed basis.
;*
;* Each component may be contained in its own physical segment, or
;* combined with other components into common segments. Throughout the
;* runtime source code, each component is placed in a segment with a
;* unique logical name. The global segment definitions control the
;* actual physical segment names used.
;*
;* In order to minimize the size of user programs, portions of each
;* component, or the entire component itself, may be optional and
;* linked/loaded only if referenced by the user program. An "optional
;* initialization" mechanism is used to initialize components which
;* require initialization only if they are present. In some cases stubs
;* or crippled versions of some component routines may be required, even
;* when the complete component is not present. In these cases indirect
;* calls are used. The target of the call defaults to the stub, or is
;* updated as appropriate by the component initialization routine.
;*
;* If a component needs specialized initialization then this is done
;* in an ordered manner through indirect dispatches performed on an
;* as needed basis. This is done by defining far pointers to initializers
;* in a special segment (XI) which is known to the startup. When a
;* module containing the pointer to the initializer gets linked into
;* the exe file, the pointer to the initializer also gets appended to
;* the XI segment. The startup will then indirectly call each routine
;* which has a pointer in the XI segment before _main is called. The
;* initializers for the runtime do not actually initialize the individual
;* components. Instead they change a pointer in an initialization vector
;* to the real initialization routine for the component. This mechanism
;* allows the runtime to initialize its components in a well defined
;* order when _main gets called. If a component needs specialized
;* termination then its initializer should also place a pointer to
;* the termination routine in the termination vector (analogous to
;* the initialization vector). When the runtime terminates it will
;* indirectly call all routines in the termination vector.
;*
;* Access between some components should be done through
;* indirect calls. An example of this would be the
;* floating input processor FIN. FIN can handle ints, longs, sp
;* and dp numbers. You shouldn't need to load the floating point
;* math pack if you want to call FIN with an integer. This can
;* be accomplished by indirectly calling FIN through a pointer.
;* If the floating math pack is not loaded then the routine
;* pointed to by the fin ptr only understands ints and longs.
;* If the math pack is loaded then the math pack initializer
;* will change the fin ptr to point to a fin routine which
;* understands all numeric types. This type of indirection
;* can greatly improve the granularity of the runtime.
;*
;* In addition each component can be composed of other components
;* (sub components). With the definition of what a component is
;* we can come up with a suggested module naming convention. A
;* module can be named as follows:
;*
;* xx(yy)zzzz.ext
;* where
;* xx - is abbreviation of major component (as listed above).
;* yy - is the optional abbreviation of a subcomponent such
;* as: HL for high level, LL for low level, etc.
;* zzzz - description of modules action such as: init, data,
;* term, disp, etc.
;* ext - is extension for file .asm .c .h .inc .doc etc.
;******************************************************************************
SUBTTL Runtime memory maps for BASIC 3.0
PAGE
;==============================================================================
;
; HIGH MEMORY
; Top of MEMORY ----------------------> +-----------------------+
; | QuickLIB symbols |
; | QuickLIB code |
; +-----------------------+
; | |
; | Far heap entries and |
; | free space for Huge |
; | Numeric arrays Comm |
; | buffers and interp |
; 64k DGROUP boundary ----------+ | tables |
; b$dynamic_end ----------------+-----> +-----------------------+ LH grows down
; | Local Heap Space | -------------
; | | |
; | contains FDBs | |
; | Dynamic String Array | |
; | entries and interp | |
; flexible boundary between the | tables | v
; Local Heap and String Space ------> |/\/\/\/\/\/\/\/\/\/\/\/| -
; | String Heap Space | ^
; | | |
; | contains string | |
; | entries |------------
; | | SS grows up
; b$dynamic_start --------------------> +-----------------------+
; __atopsp ---------------------------> | STACK (class STACK) | Stack grows
; | | down
; | | -----------
; |\/\/\/\/\/\/\/\/\/\/\/\| |
; | | |
; | | v
; _end -------------------------------> +-----------------------+
; +-------------> | BC_SA (class BC_SEGS) |
; | +-----------------------+
; | | BC_SAB (class BC_SEGS)|
; | +-----------------------+
; | | BC_DS (class BC_SEGS) |
; | +-----------------------+
; BASIC program data ---+ | BC_CN (class BC_SEGS) |
; | +-----------------------+
; | | BC_FT (class BC_SEGS) |
; | +-----------------------+
; +-------------> | BC_DATA (BC_DATA) |
; +-----------------------+
; +-------------> | XCE (class DATA) |
; | +-----------------------+
; | | XC (class DATA) |
; | +-----------------------+
; | | XCB (class DATA) |
; | +-----------------------+
; | | XPE (class DATA) |
; | +-----------------------+
; Initializers ---------+ | XP (class DATA) |
; and terminators | +-----------------------+
; | | XPB (class DATA) |
; | +-----------------------+
; | | XIE (class DATA) |
; | +-----------------------+
; | | XI (class DATA) |
; | +-----------------------+
; +-------------> | XIB (class DATA) |
; +-----------------------+
; | CDATA (class DATA) |
; b$common_end -----------------------> +-----------------------+
; | COMMON (class BLANK) | <-+preserved
; +-----------------------+ |
; Soft key string descriptors --------> | BR_SKYS (class BLANK) | --+
; b$common_start ---------------------> +-----------------------+ across chain
; Uninitialized runtime data ---------> | _BSS (class DATA) |
; +-----------------------+
; BASIC runtime data (initialized) ---> | _DATA (class DATA) |
; +-----------------------+
; BASIC constants --------------------> | CONST (class DATA) |
; +-----------------------+
; | NULL (class BEGDATA) |
; Beginning of DGROUP ----------------> +-----------------------+
; | C_ETEXT(class ENDCODE)|
; +-----------------------+
; BASIC runtime init code ------------> | INIT_CODE(INIT_CODE) |
; +-----------------------+
; FAR BASIC runtime code -------------> | *_TEXT (class CODE) |
; +-----------------------+
; BASIC runtime code --------------> | CODE (class CODE) |
; +-----------------------+
; Interpreter code --------------> | _TEXT (class CODE) |
; +-----------------------+
;
; LOW MEMORY
;
; _end - last word of useable stack space.
; __atopsp - points to first useable word of stack space.
; The BP register is assumed to point to a valid stack frame upon
; entry to the runtime.
;
; b$dynamic_start - points to the first useable word of dynamic space.
; b$dynamic_end - points to the last useable word of dynamic space.
; NOTE:
; 1) b$dynamic_start and b$dynamic_end are shadow values for dynamic space.
; the real heap management variables are internal to nh*.asm.
; 2) For OS/2 the above segments may be in any physical order (except
; for DGROUP). No assumptions can be made about selectors and the
; address correlation with physical memory.
; 3) The segments CONST, _DATA, _BSS, and BR_SKYS are aliased by BR_DATA
; in user programs using the common runtime module. BR_DATA is filled
; with blank storage and overlayed by the runtime module during RTM
; initialization.
;=============================================================================
SUBTTL Component Initialization and Termination
PAGE
;******************************************************************************
; There are several classes of initialization and termination for
; the runtime. There is "ONE time" intialization/termination,
; "RUN/END time" initialization/termination, and
; initialization/termination actions that take place during
; "SHELL", "CHAIN", "CLEAR", and "NEW" (QB4 only).
;
; "ONE time" initialization occurs once when the system is initialized.
; "RUN time" initialization takes place whenever a program
; is restarted (RUN, LOAD, NEW). The other functions occur
; whenever a "SHELL", "CHAIN", or "CLEAR" statement is executed.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -