📄 rtinit.asm
字号:
;
; "One time" termination occurs once when the system is terminated.
; For the interpreter this occurs when a SYSTEM statement is
; executed. For the compiler this happens whenever an END, SYSTEM,
; Cntrl-Break, end of module, RUN "filename", or CHAIN "filename"
; (non DOS 3 runtime module) is executed. The compiler RUN/CHAIN
; case is somewhat special since we aren't actually returning
; to the OS. However, the actions taken are identical to terminating
; to the OS except that another program is started. The new program
; will reinitialize the whole runtime system as if it were started
; from the DOS command line.
;
; "END time" termination is specific to the interpreter. The only
; thing that happens here is that all files and devices are closed.
; This will only occur when the interpreter executes an END statement.
;
; "CHAIN time" and "SHELL time" termination occur whenever a
; CHAIN (only applicable for interpreter and DOS 3 runtime module
; for the compiler) or SHELL statement is executed.
;
; Initialization/termination of each runtime component may need to
; take specific actions based on the context of the execution
; environment (compiled or interpreted), the product (QB4, BC3),
; the DOS (3,5), and (for the compiler) the runtime environment (/O,
; runtime module).
;******************************************************************************
SUBTTL C runtime CRT0 support for BASIC runtime
PAGE
;******************************************************************************
; Assumptions the runtime makes about startup.
;
; The runtime assumes that crt0 provides the following
; initialization support for us:
; all initializers in XI are called before _main
; DS, ES, SS are set up to DGROUP
; __osversion is a word containing DOS major and
; minor version numbers.
; __osfile[] is a static array of system file handles
; which can be checked against 40H to determine
; if redirection has occurred.
; __psp contains the PSP segment value
; __aenvseg contains selector to environment segment for OS/2
; __psp:[2C] contains environment segment for non-OS/2.
; _end points to last useable word of STACK
; __atopsp points to first useable word of stack
;
; __osversion is a word containing the DOS major and minor
; version numbers. The version is stored as MinMaj in
; a decimal value. For example DOS 5.00 is 0005H, DOS 2.10
; is 0A02H etc.
;
; To determine if input and/or output is redirected,
; check the file handle in the __osfile[] array against
; 40H (bit 6). If bit 6 is clear then there is redirection.
; __osfile[] is a static array of file handles managed by C.
; __osfile[0] is stdin, __osfile[1] is stdout, etc.
; NOTE: this is valid for DOS 3, but C is uncertain if this
; will stay this way for OS/2.
;
;******************************************************************************
SUBTTL Code Externals
PAGE
sBegin DV_TEXT
externNP B$IOCLOS ;to de-install interrupt vectors
externNP B$IOINI ;to install interrupt vectors
externNP B$NearRet
sEnd DV_TEXT
externFP __fpreset ; floating point reset
externFP B$ERR_LLI ; low-level init error
externFP B$ERR_DOS ; bad DOS version error
sBegin FH_TEXT
externNP B$FHClear ;cleans far heap
sEnd FH_TEXT
sBegin NH_TEXT
externNP B$NHCLR ;cleans near heap
sEnd NH_TEXT
externFP B$ULInit ;calls UL "C" initializers
externFP B$SETM ; SETMEM function
externFP B$RTMInstall ;install the RTM interrupt vector
externFP B$?EVT ; event initialization
sBegin RT_TEXT
externFP B$GWINI ;Low level initialization
externNP B$CNINI ;drag in console io
externNP B$RTLLINI ; Low Level one time core init
externNP B$LHClearRange ; Clear local heap
externNP B$SSClearRange ; Clear string space
externNP B$FHClearRange ; Clear far heap
externNP B$TglHeapSptNEAR ; Toggle to/from var heap support
externNP B$DONOTE ;turns off sound for QBI CHAIN
sEnd RT_TEXT
SUBTTL Runtime data definitions for BASIC Runtime Core
PAGE
sBegin _BSS
globalW b$UcodeOff,? ;offset to user code module header
globalW b$UcodeSeg,? ;segment of user code module
LabelW <PUBLIC,b_cbComBuffer> ;Interpreter reachable symbol
globalW b$cbComBuffer,? ;combuffer size specified on QB command line
externW b$STRTAB ;Beginning of soft key table
globalB b$fRTInit,? ;TRUE if RT initialization complete
sEnd _BSS
sBegin _DATA
;
; Global data
;
EVEN ;insure disp vectors are word aligned
PUBLIC b$ini_disp
PUBLIC b$term_disp
PUBLIC b$run_disp
PUBLIC b$end_disp
PUBLIC b$clrt_disp
PUBLIC b$clr_disp
PUBLIC b$shli_disp
PUBLIC b$shlt_disp
PUBLIC b$err_disp
b$ini_disp INIT_VECTORS <> ;One time initialization dispatch table
b$term_disp TERM_VECTORS <> ;One time termination dispatch table
b$run_disp RUN_VECTORS <> ;"RUN" initialization dispatch table
b$end_disp END_VECTORS <> ;"END" termination dispatch table
b$clrt_disp CLRT_VECTORS <> ; CLEAR "termination" dispatch table
b$clr_disp CLR_VECTORS <> ;CLEAR statement dispatch table
b$shli_disp SHLI_VECTORS <> ;SHELL re-initialization dispatch table
b$shlt_disp SHLT_VECTORS <> ;SHELL "termination" dispatch table
b$err_disp ERROR_VECTORS <> ; error vectors
globalW b$commonfirst,0 ;first word of COMMON block
globalW b$commonlast,0 ;last word of COMMON block
;output is also sent to lpt.
PUBLIC b$fCompErr
b$fCompErr = OFFSET DGROUP:b$errmod+2 ;seg of errmod 0 if interp error
PUBLIC b_fCompErr ;Interpeter reachable symbol
b_fCompErr = b$fCompErr ;Interpeter reachable symbol
sEnd _DATA
sBegin NMALLOC
DB NMALLOC_MIN DUP(?) ; Default malloc buffer - room
sEnd NMALLOC ; for header.
SUBTTL Runtime Core Initializer
PAGE
assumes CS,INIT_CODE
sBegin INIT_CODE
;***
;B$xRTINI - Initializer for the runtime core.
;PLM B$xRTINI()
;
;Purpose:
; This is the initializer for the BASIC runtime core. It is placed
; in the same module as _main so that it is guaranteed to always
; be present at initialization time. It's sole responsiblility
; is to update the initialization and termination dispatch vectors
; to include the true initialization and termination entry points
; for the runtime core.
;
;Entry:
; None.
;
;Exit:
; Appropriate dispatch vectors filled.
;
;Uses:
; None.
;
;Exceptions:
; None.
;****
cProc B$xRTINI,<FAR>
cBegin
;
; update "ONE" time initialization dispatch address to B$RTINI
;
MOV WORD PTR [b$ini_disp].RT_IVEC,RT_TEXTOFFSET B$RTINI
;
; update "ONE" time termination dispatch address to B$IOCLOS
;
MOV WORD PTR [b$term_disp].RT_TVEC,RT_TEXTOFFSET B$IOCLOS
;
; update "RUN" time initialization dispatch address to B$RTRUNINI
;
MOV WORD PTR [b$run_disp].RT_RVEC,RT_TEXTOFFSET B$RTRUNINI
;
; update CLEAR statement dispatch address to B$RTCLR
;
MOV WORD PTR [b$clr_disp].RT_CVEC,RT_TEXTOFFSET B$RTCLR
cEnd
SUBTTL Runtime Initialization Code
PAGE
;***
;_main,B$IINIT - Main entry point into the runtime
;main()
;void pascal B$IINIT()
;
;Purpose:
; This is the main entry point into the runtime. It is responsible for
; initializing the components of the runtime which are present and
; need initializing. This is done by indirectly calling each routine
; which has an address defined in b$ini_disp. This table is built
; up by conditional initializers which are dragged in at link time.
; BC3
; ---
; A BASCOM compiled program enters in the C library startup(crt0). Crt0
; calls each routine which has its address defined in the segment XI.
; These initializers will update the dispatch table b$ini_disp.
; Crt0 will then call runtime at _main. _main will call all routines in
; b$ini_disp. After all components of the runtime have been initialized,
; _main needs to determine where to begin execution of the user program.
; BASIC has no concept of a "main" module the compiler does not generate
; an _main label (the first module in the link is considered to be the
; entry point).
; NOTE: the compiler generates modulename_CODE as the segment name for
; the user code. Therefore the runtime does not know what
; segment the users code resides in.
; The compiler generates a segment called BC_SA of CLASS 'BC_SEGS'
; which contains the segmented address of every module linked. Therefore
; the runtime can pick out the first dword of this segment to obtain the
; address of the user code module that was linked FIRST. This address
; points to the module header of the module. The actual beginning of
; the users code is at a fixed offset (O_ENT) from this address. We can
; then call the users module to begin execution of the BASIC program.
; QB4
; ---
; The routine B$IINIT is identical to the compilers _main except
; that it does not need to find the users program. All components
; will be inited in the interpreter. The initializers will be set
; up identically for the compiler and interpreter. Note that B$IINIT
; is called by the interpreter, initializes and returns.
;
;Entry:
; DS = ES = user DS for DOS3 RTM
; SS:SI = ptr to command parameters (QB4 only)
; [SI] - UlibNameOffset
; [SI+2] - UlibNameSegment
; [SI+4] - cbLibName
; [SI+6] - cbComBuffer
;Exit:
; None
;
;Uses:
; None
;
;Exceptions:
; May not return if initialization error occurrs.
;****
cProc B$IINIT,<PUBLIC,FAR>,<SI,ES>
cBegin
?PLM = 1
PUSH DS
POP ES
MOV AX,[SI+6] ;get requested com buffer size
MOV b$cbComBuffer,AX ;save combuffer size
;
; Call "ONE" time and "RUN" time initialization routines for
; each component which has an entry defined in b$ini_disp and
; b$run_disp. Components not needing initialization point
; to B$FAR_RET, which just does a far return.
;
MOV SI,OFFSET DGROUP:b$ini_disp ;get dispatch table addr
CALL FAR PTR B$COMP_DISP ;routine to do table dispatches
MOV SI,OFFSET DGROUP:b$run_disp ;get "run" time dispatch table
CALL FAR PTR B$COMP_DISP ;do "RUN" time initialization
call fEditorActive ; did we start with /EDITOR
jnz InEditor ; brif so, don't restrict memory
MOV AH,7Fh ; request 7Fxx7Fxx bytes more in
cCall B$SETM,<AX,AX> ; order to REDUCE max available
; memory to 128K (far) + 32K (near)
InEditor:
inc b$fRTInit ; indicate RT is inited
cEnd
?PLM = 1
; common error entry points to save NEAR jumps
BADLL:
JMP B$ERR_LLI ; Low level initialization error
SUBTTL Post-RTM-load initialization
PAGE
;***
; B$RTMInit - initialization for RTM programs.
;
;Purpose:
; Moved from RTMLOAD.ASM with revision [64]. (was called ChainInit)
; Moved into segment INIT_CODE from RT_TEXT with revision [75].
;
; To perform initialization specific to RTM programs.
;Entry:
; SS = DGROUP segment.
;Exit:
; None.
;Uses:
; None
;Exceptions:
;
;******************************************************************************
sEnd INIT_CODE
SUBTTL Top Level "RUN" time initialization for QB4
PAGE
assumes CS,RT_TEXT
sBegin RT_TEXT
;***
;B$INIT - Initialization prior to XI processing.
;PLM B$INIT()
;
;Purpose:
; This is the FIRST entry point into the BASIC runtime. It gets called
; prior to any of the initialization vectors. It's primary purpose in
; life is to clear BC user variables prior to the XI dispatches.
; The reason that we need to do this here is that near malloc() space
; comes out of the NMALLOC BASIC common block, and we would wipe out
; any initial mallocs done in the XI dispatches. Fortran and Pascal
; both do this kind of allocation.
; Added with revision [68].
;
; This routine move from INIT_CODE to RT_TEXT with [88].
;
;Entry:
; None.
;Exit:
; The bit flag b$CtrlFlags.BCVarsCleard is set.
;Uses:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -