📄 biosinit.a86
字号:
; File : $BIOSINIT.A86$
;
; Description :
;
; Original Author : DIGITAL RESEARCH
;
; Last Edited By : $CALDERA$
;
;-----------------------------------------------------------------------;
; Copyright Work of Caldera, Inc. All Rights Reserved.
;
; THIS WORK IS A COPYRIGHT WORK AND CONTAINS CONFIDENTIAL,
; PROPRIETARY AND TRADE SECRET INFORMATION OF CALDERA, INC.
; ACCESS TO THIS WORK IS RESTRICTED TO (I) CALDERA, INC. EMPLOYEES
; WHO HAVE A NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF
; THEIR ASSIGNMENTS AND (II) ENTITIES OTHER THAN CALDERA, INC. WHO
; HAVE ACCEPTED THE CALDERA OPENDOS SOURCE LICENSE OR OTHER CALDERA LICENSE
; AGREEMENTS. EXCEPT UNDER THE EXPRESS TERMS OF THE CALDERA LICENSE
; AGREEMENT NO PART OF THIS WORK MAY BE USED, PRACTICED, PERFORMED,
; COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED, ABRIDGED,
; CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST,
; TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF
; CALDERA, INC. ANY USE OR EXPLOITATION OF THIS WORK WITHOUT
; AUTHORIZATION COULD SUBJECT THE PERPETRATOR TO CRIMINAL AND
; CIVIL LIABILITY.
;-----------------------------------------------------------------------;
;
; *** Current Edit History ***
; *** End of Current Edit History ***
;
; $Log$
; BIOSINIT.A86 1.43 93/12/03 00:38:19
; Fix bug in AllocHMA when base not para aligned
; BIOSINIT.A86 1.42 93/11/29 21:40:03
; Fill in name field of system DMD's (owner=8) with 'SC'
; BIOSINIT.A86 1.41 93/11/18 15:43:14
; Add primitive multi-master checking
; BIOSINIT.A86 1.40 93/11/11 12:25:29
; VDISK header changes
; BIOSINIT.A86 1.39 93/11/08 23:19:22
; SetupHMA does CALL5 initialisation
; BIOSINIT.A86 1.38 93/10/29 20:03:48
; BIOS relocation services restored for possible 3rd party memory manager use
; BIOSINIT.A86 1.37 93/10/29 19:42:27
; Change HIDOS default to off
; BIOSINIT.A86 1.36 93/09/22 15:22:14
; Change int21/4458 to les bx,cs:drdos_ptr (smaller, faster)
; BIOSINIT.A86 1.35 93/09/03 20:10:55
; Support intl YES/NO
; BIOSINIT.A86 1.34 93/09/02 22:34:42
; Add header to system allocations
; BIOSINIT.A86 1.33 93/09/01 17:36:57
; increase stack size for aspi4dos.sys
; BIOSINIT.A86 1.31 93/08/06 20:55:16
; re-arrange device init order for SCREATE.SYS on a VDISK.SYS
; BIOSINIT.A86 1.28 93/08/02 14:45:43
; hide preload drives from func_device
; ENDLOG
include i:msdos.equ ; DOS Function Equates
include i:psp.def ; PSP Definition
include i:f52data.def ; Internal DOS data area
include i:doshndl.def ; Dummy DOS structures
include config.equ
include i:fdos.equ
include i:modfunc.def
TRUE equ 0FFFFh ; value of TRUE
FALSE equ 0 ; value of FALSE
;
; Equates for INIT_FLAGS which can be modified by the BIOS
; the default is a RAM based BDOS (Code and Data) with INIT_DRV
; specifing the default drive and the initial drive for COMSPEC
;
INIT_ROMCODE equ 0001h ; Rom based DOS CODE
INIT_COMSPEC equ 0002h ; COMSPEC_DRV specifies the default
; Command Processor Drive
INIT_WINDOWS equ 0004h ; Disable windows support
COMMAND_BASE equ 000E0h ; must cover FFFF:D0 for CALL5 fixup
COMMAND_SIZE equ 015C0h
CGROUP GROUP CODE, INITCODE, INITDATA, INITPSP, INITENV, DATAEND
CODE CSEG
eject
;
; The DOS Code Segment is formatted as follows.
;
DOS_OFFSET equ word ptr .0008h ; Offset of code in segment
HISTORY_CODE equ word ptr .000Ch ; Start of history code
INIT_CODE equ word ptr .000Eh ; Start of initialisation code
DOS_FLAG equ word ptr .001Ch ; Compressed Data Flag
DOS_CODE equ word ptr .001Eh ; DOS Code Length (Bytes)
DOS_DATA equ word ptr .0020h ; DOS Data Length (Bytes)
NO_YES_CHARS equ word ptr .0028h ; DOS Data No/Yes characters
INT31_SEGMENT equ word ptr .00C6h ; DOS Data Segment pointer
; for ROM systems
JMPF_OPCODE equ 0EAh ; 8086 JMPF instruction
INITCODE CSEG PARA 'INITCODE'
extrn cleanup:near ; BIOS Clean Up routine
extrn config_init:near ; CONFIG Code Init
extrn config_finish:near ; Update DOS with Device Info
extrn config:near ; CONFIG.SYS Processor
extrn crlf:near ; Output CR/LF to screen
extrn resident_device_init:near ; Device Driver Init
extrn read_dos:near ; load DOS file
extrn setup_ldt:near
extrn setup_stacks:near
extrn dos_version_check:near
db 'Copyright (c) 1983,1996 '
db 'Caldera, Inc. All Rights Reserved '
db 'XXXX-0000-987654321X'
Public biosinit
;========
biosinit:
;========
; entry: MEM_SIZE = memory size in paragraphs
; DEVICE_ROOT = address of 1st resident device driver
; INIT_DRV = boot drive (0 = A:, 1 = B:, etc.)
; INIT_BUF = minimum # of disk buffers
; CURRENT_DOS = code segment of DOS (if loaded)
; INIT_FLAGS = Control Flags
; COMSPEC_DRV = Drive for Command Processor
;
;
; we set up the following variables
; BIOS_SEG = low memory BIOS code/data (static)
; DOS_DSEG = low memory DOS data area (static)
; RCODE_SEG = relocated BIOS code segment
; DOS_CSEG = relocated DOS code segment
; INIT_DSEG = segment based initialisation data
;
cld
cli
mov ax,cs ; Initialise our stack and Data Segment
mov ds,ax
mov ss,ax
mov sp,offset stack
sti
mov bios_seg,ax ; Save the BIOS Segment
; Now some code which allows Remote Program Loader to reserve some memory
; which will be safe from being trampled on by the system.
; The RPL takes over Int 2F and has a magic signature "RPL" at offset 3 from
; it's entry point. If this is detected an Int2f is issued
;
; On Entry:
; AX = 4A06, DX = Segment address of top of memory
; On Exit:
; DX = segment address of the RPL
;
; On return the system will build a DMD entry for the RPL, with an owner field
; of 8 (ie. System). The RPL can poke this entry to 0 when it wishes to free
; the memory.
;
; In addition we now look for "RPLOADER", and if found we remember the address
; of the entry point so we can call it with status information
mov dx,mem_size ; get existing size
dec dx ; one para less for upper mem DMD link
xor ax,ax
mov es,ax ; point to vectors
mov bx,4*2fh ; we want Int 2F vector
les bx,es:dword ptr [bx] ; pick up the contents
lea di,3[bx] ; point to magic signature "RPL"
mov si,offset rpl_name
mov cx,3
repe cmpsb ; does the signature match ?
jne biosinit20
mov cx,5 ; look also for "RPLOADER"
repe cmpsb
jne biosinit10
mov rpl_off,bx ; save entry point for use later
mov rpl_seg,es
biosinit10:
mov ax,4a06h ; magic number for RPL
int 2fh ; does anyone want to steal memory ?
inc dx
cmp dx,mem_size ; is memory size unchanged ?
jnb biosinit20
dec dx ; point back at start of memory
dec dx ; then one below for DMD start
mov es,dx ; ES points to DMD
mov DMD_ID,IDZ ; make it last in the chain
mov DMD_PSP,8 ; owned by system
lea di,DMD_NAME ; point to name field
mov si,offset rpl_name
mov cx,(length rpl_name)/2
rep movsw ; initialise name field too
inc dx ; skip the DMD for real top
xchg dx,mem_size ; replace memory size with new value
sub dx,mem_size ; whats the difference ?
mov DMD_LEN,dx ; save it's this length
biosinit20:
; End of RPL support
mov ax,mem_size ; get top of memory
sub ax,MOVE_DOWN
mov mem_max,ax ; last available paragraph
mov init_dseg,ax ; initialisation data lives here
mov cl,4
mov dx,offset DYNAMIC_DATA_END+15
shr dx,cl ; we need this much dynamic data
add ax,dx
; Now we try to relocate the BIOS
mov dx,rcode_len ; we want to keep this much BIOS code
add systemSize,dx ; so add to reserved space in HMA
mov dx,icode_len ; how much do we want to move ?
shr dx,cl
jz biosinit30 ; if ROMed we have nothing to relocate
mov rcode_seg,ax ; relocated BIOS lives here
add ax,dx ; remember how much we allocated
mov dx,rcode_offset
mov si,dx
mov di,dx
shr dx,cl ; DX = para offset of data
sub rcode_seg,dx ; adjust our segment value
mov es,rcode_seg
mov cx,icode_len
rep movsb ; copy it up
biosinit30:
mov dos_cseg,ax ; a relocated DOS image will live here
mov ax,offset biosinit_end+32
mov cl,4 ; Leave the Last Paragraph Free for
shr ax,cl ; himem DMD
neg ax ; Calculate the destination
add ax,mem_size ; Segment for the BIOS relocation
mov cx,offset biosinit_end ; Relocate the BIOSINIT code to
mov si,offset biosinit ; the top of available memory
mov di,si
sub cx,si ; Size of BIOSINIT
mov es,ax ; Initialize ES and copy CX words
rep movsb
push es ; fiddle RETF to relocated code
mov ax,offset relocated_init
push ax
retf
;
; Generic BIOS INIT Patch area
;
include i:patch.cod
;
; BIOSINIT CODE and DATA have now been relocated to high memory
;
relocated_init:
mov ax,cs
cli
mov ss,ax
mov sp,offset stack
sti
mov ds,ax ; All Segment registers now point
mov es,ax ; to the relocated BIOSINIT
call config_init ; initialize setup module
call dd_fixup ; fixup relocatable device drivers
les di,device_root ; initialize all the resident
call resident_device_init ; device drivers
push cs ! pop es
mov dx,1 ; phase one of RPL initialisation
call rploader ; inform RPLoader if present
call Verify386 ; CY set if not a 386
mov ax,mem_current ; get ending address returned by BIOS
jc dont_align
cmp ax,0100h
jae dont_align ; lets be 4 KByte aligned to benefit
mov ax,0100h ; the multi tasker (386 or above)
dont_align:
mov free_seg,ax ; and save as first Free Segment
cmp current_dos,0 ; does the OEM want us to read
jnz dos_reloc ; the DOS file from disk?
mov ax,dos_cseg
mov current_dos,ax ; the file is held on the INIT_DRV with
call read_dos ; the name specified in DOS_NAME
eject
;
; The following code will relocate the DOS code.
;
dos_reloc:
;
; We now move the DOS data to low memory
;
mov ax,current_dos
mov dos_cseg,ax ; Update the DOS Code Segment
mov ds,ax
mov cl,4
mov ax,ds:DOS_CODE ; get size of DOS code
add cs:systemSize,ax ; and add to the system size
shr ax,cl ; convert to para's
mov cs:dosCodeParaSize,ax ; save for EMM386.SYS
mov ax,ds:DOS_OFFSET ; remember we have padding
add cs:dos_coff,ax ; and adjust DOS init offset
shr ax,cl ; also adjust DOS segment
sub cs:dos_cseg,ax ; to account for padding
xor ax,ax
mov es,ax ; ES -> interrupt vectors
mov ax,ds:DOS_DATA ; get # of bytes of DOS data
shr ax,cl ; get para size of DOS data
xchg ax,cs:free_seg ; get seg for DOS data
add cs:free_seg,ax ; remember how much we used
mov es:INT31_SEGMENT,ax ; update the segment value of INT31
mov es,ax ; so ROMMED systems can find PCM_DSEG
mov cs:dos_dseg,ax ; we need to remember where too...
mov si,ds:DOS_CODE ; offset of DOS Data
xor di,di ; destination offset
test DOS_FLAG,1 ; has the DOS Data been compressed
jnz dos_r20 ; yes so call the decompress routine
mov cx,ds:DOS_DATA ; otherwise just copy the data.
rep movsb
jmps dos_r40
;
; This routine will decompress the DOS data area which has
; been compressed after linking using Andy Wightmans data
; compression algorithm.
;
dos_r20:
lodsw ; get control word
mov cx,ax ; as a count
jcxz dos_r40 ; all done
test cx,8000h ; negative ?
jnz dos_r30 ; yes do zeros
rep movsb ; else move in data bytes
jmps dos_r20 ; and to the next
dos_r30:
and cx,7fffh ; remove sign
jcxz dos_r20 ; none to do
xor ax,ax
rep stosb ; fill with zeros
jmps dos_r20
dos_r40:
push cs ! pop ds
push cs ! pop es
mov cl,4 ; reserve space for resident DDSC's
mov ax,DDSC_LEN
mul dev_count ; AX byte are required
add ax,15
shr ax,cl ; AX para are required
xchg ax,free_seg
add free_seg,ax ; we have allocated the space
mov res_ddsc_seg,ax ; point res_ddsc_ptr at the space
mov dx,dos_dseg
sub ax,dx ; DOS resident DDSC_'s use DOS data seg
cmp ax,1000h ; surely we must fit ?
jae dos_r50
shl ax,cl ; offset within pcmode data segment
mov res_ddsc_off,ax
mov res_ddsc_seg,dx ; setup pointer to resident DDSC's
dos_r50:
;
; Call the DOS INIT Code passing all the information setup
; by the BIOS.
;
mov ax,mem_size ; pass the Memory Size, the first free
mov bx,free_seg ; segment and the initial
mov dl,init_drv ; drive to the DOS init routine
cli
mov ds,dos_dseg ; DS -> DOS data segment
callf cs:dos_init
mov es,cs:dos_dseg
mov bx,26h ; ES:BX -> list of lists
mov ax,es:word ptr F52_FCBPTR[bx]
shr ax,1 ! shr ax,1
shr ax,1 ! shr ax,1
and es:word ptr F52_FCBPTR[bx],15
add es:word ptr F52_FCBPTR+2[bx],ax
sti
push cs ! pop ds
mov es,current_dos ; internationalise the yes/no chars
mov di,es:NO_YES_CHARS
mov es,dos_dseg ; ES:DI -> internal table
mov ax,word ptr no_char
stosw ; replace default no chars
mov ax,word ptr yes_char
stosw ; replace default yes chars
push cs ! pop es
add dos_coff,3 ; next dos_init call just fixes up
; segment relocations
mov dx,2 ; phase two of RPL initialisation
call rploader ; inform RPLoader if present
call config_start ; get free memory
call config ; read and process CONFIG.SYS
call config_end ; relocate DOS code and free memory
mov ax,(MS_X_OPEN*256)+2 ; Open for Write
mov dx,offset idle_dev ; Get the IDLE Device Name#
int DOS_INT ; Open the device
jc dos_r70 ; Quit on Error
push ax ; Save the Handle
mov ax,4458h ; Get the address of the IDLE data
int DOS_INT ; area in ES:AX
pop bx ; Restore the Handle
mov idle_off,ax ; Save the data area offset and
mov idle_seg,es ; segment
mov ax,4403h
mov dx,offset idle_off
mov cx,DWORD
int DOS_INT
mov ah,MS_X_CLOSE
int DOS_INT
dos_r70:
call mark_system_memory ; ensure any memory we have allocated
; is marked as system
mov bios_offset,offset cleanup
callf bios ; execute BIOS cleanup code
mov ax,(MS_M_STRATEGY*256)+3
xor bx,bx ; unlink in upper memory region
int 21h
mov dx,3 ; phase three of RPL initialisation
call rploader ; inform RPLoader if present
mov ax,12ffh ; magic cleanup call to MemMAX
mov bx,5 ; to do any tidy ups it wishes
xor cx,cx
xor dx,dx
int 2fh
push cs ! pop es
load_e10:
mov ax,(MS_X_EXEC * 256)+0 ; Exec the Command Processor
mov bx,offset exec_env ; Get the Parameter Block Address
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -