📄 biosinit.a86
字号:
mov dx,offset shell ; and the Command Processor
mov exec_clseg,ds
mov exec_fcb1seg,ds
mov exec_fcb2seg,ds
int DOS_INT ; Go for it
mov ah,MS_C_WRITESTR ; Print an error message and wait for
mov dx,offset bad_exec ; the user to enter new name
int DOS_INT
mov ah,MS_C_READSTR ; get user to input new COMMAND
mov dx,offset shell_ask ; location
int DOS_INT
call crlf ; tidy up with CR/LF
xor bx,bx
mov bl,shell_end
mov shell[bx],bh ; replace CR with NULL
jmps load_e10
eject
;
; Initialise the PSP and inform DOS of the
; location of the BIOSINIT PSP. The MS_P_SETPSP *MUST* be the first
; INT21 function call because the PSP Address is used during the
; entry code except when the INDOS flag is set and certain function
; calls are made.
;
; Then open the Resident character devices so that the dynamically
; devices can output messages to the screen etc.
;
config_start:
mov cl,4
mov bx,ds
mov ax,offset psp ; Now force DOS Plus to use the
shr ax,cl ; internal PSP for all disk and
add bx,ax ; character I/O
mov xftbl_seg,bx ; Update the Handle Table Pointer
mov parent_psp,bx ; and make this the root process
mov ah,MS_P_SETPSP ; Set the current PSP
int DOS_INT
if DOS5
mov ax,3306h
int 21h ; get true version
mov dosVersion,bx ; and plant in initial PSP
endif
call dos_version_check ; make sure we are on correct DOS
mov ax,4458h
int DOS_INT ; we need to access local data
mov drdos_off,bx ; so save a pointer to it
mov drdos_seg,es
mov ax,ext_mem_size
mov es:DRDOS_EXT_MEM[bx],ax ; save extended memory size in DOS
mov ax,5200h
int DOS_INT
mov func52_off,bx
mov func52_seg,es ; save pointer to internal data
if DOS5
mov ax,ext_mem_size
mov es:F52_EXT_MEM[bx],ax ; save extended memory size in DOS
endif
mov ax,(offset TEMP_LDT)/16 ; use our temporary LDT's
add ax,init_dseg ; during system init
mov es:F52_PATHOFF[bx],0 ; point at the LDT's
mov es:F52_PATHSEG[bx],ax
push cs ! pop es
mov ah,MS_M_ALLOC ; Allocate all available memory
mov bx,0FFFFh ; BX is returned with the maximum
int DOS_INT ; available block size
mov ah,MS_M_ALLOC
int DOS_INT
mov mem_first_base,ax ; Base of 1st allocated block
mov mem_current_base,ax ; Base of allocated memory
mov mem_current,ax ; Next available Segment
call config_finish ; Update DOS with the information
; obtained from loading the resident
; drivers.
mov ah,MS_DRV_SET ; Select the Default Drive
mov dl,init_drv ; passed to us by the BIOS
int DOS_INT
mov ah,MS_F_DMAOFF ; Initialise the DMA address for
mov dx,offset search_state ; the Search First State data
int DOS_INT
mov al,init_drv ; get the boot drive then check
test init_flags,INIT_COMSPEC ; flags to see if this is the
jz config_s05 ; default COMSPEC drive.
mov al,comspec_drv
config_s05:
add shell,al ; update the drive letter of shell
add shell_drv,al ; and the reload path
call open_stdaux ; Open STDAUX as internal handle #0
call open_stdcon ; Open Standard CON Devices as #1
mov ah,MS_X_CLOSE ; now close AUX again
mov bx,STDAUX ; for CONFIG processing
int DOS_INT
ret
;
; Relocate the DOS CODE from high memory to immediately above
; the device drivers, buffers etc. Then call the DOS_CLEANUP code
; so that any self segment pointers maintained in the DOS DATA
; can be updated. Then free all the unused memory and reopen the
; standard devices.
;
config_end:
push es
mov al,last_drv ; get lastdrive value
les bx,func52_ptr
cmp al,es:F52_PHYDRV[bx] ; less than the # of Physical drives ?
ja config_end10
mov al,es:F52_PHYDRV[bx] ; ensure minimum of # physical drives
config_end10:
mov es:F52_LASTDRV[bx],al ; set # of drives installed
mov cl,4 ; we will be converting byte-paras
mov ah,LDT_LEN ; we need this many bytes per drive
mul ah ; *lastdrive
add ax,15 ; round LDT's size up to para
shr ax,cl
mov dl,'L' ; allocate LDT's
call alloc_instseg ; Allocate memory AX is destination
mov es:F52_PATHOFF[bx],0 ; point at the LDT's
mov es:F52_PATHSEG[bx],ax ; save seg we just allocated
pop es
call setup_ldt ; initialise LDT structures
call setup_stacks ; allocate stacks
call relocate_system ; relocate system as requested
push es ; Free all of the unused memory
mov es,mem_current_base ; ES: Base Allocated Memory
mov bx,mem_current ; Get the currently allocated memory
sub bx,mem_current_base ; and subtract mem_current_base to
mov ah,MS_M_SETBLOCK ; give the number of paragraphs used
int DOS_INT ; and modify block accordingly
; Kludge - if the CONFIG file has had a line of the form INSTALL= to load a TSR
; then that TSR will have inherited the handles, so bumping the open count, but
; the func 31 exit leaves all these files open. As a result we will get the
; wrong internal file numbers unless we force complete closure. So we keep
; trying to close each internal handle until we get an error.
mov ah,MS_P_GETPSP
int DOS_INT ; get current PSP
mov es,bx
mov cx,PSP_XFNMAX ; Close all the standard handles
les di,PSP_XFTPTR ; and then reopen them in case a
mov bx,0 ; dynamicly loadable device has
cfg_e10: ; replaced the BIOS driver
mov dl,es:[di+bx] ; save old internal handle
mov ah,MS_X_CLOSE
int DOS_INT ; try and close this handle
mov es:[di+bx],dl ; put the internal handle back
jnc cfg_e10 ; and try and close it again
mov es:byte ptr [di+bx],0ffh
inc bx ; mark as closed and try next handle
loop cfg_e10
pop es
;; jmps open_std
open_std:
call open_stdaux ; open AUX device as STDAUX
call open_stdcon ; now STDIN, STDOUT, STDERR
; jmp open_stdprn ; finally STDPRN
open_stdprn:
mov ax,(MS_X_OPEN * 256) + 1
mov dx,offset printer ; Open the PRN device
int DOS_INT
jc open_sp10 ; No PRN device
cmp ax,STDPRN ; If all the previous Opens were
jz open_sp10 ; successful then this is STDPRN
mov bx,ax ; otherwise force this to STDPRN
mov cx,STDPRN
mov ah,MS_X_DUP2
int DOS_INT
mov ah,MS_X_CLOSE
int DOS_INT
open_sp10:
ret
open_stdcon:
mov ax,(MS_X_OPEN * 256) + 2
mov dx,offset console ; Open the CON device
int DOS_INT
jc open_sc10 ; No CON device
mov bx,ax ; First Open should be STDIN
mov cx,STDOUT ; Force Duplicate to STDOUT
mov ah,MS_X_DUP2
int DOS_INT
mov cx,STDERR ; Then Force Duplicate to STDERR
mov ah,MS_X_DUP2
int DOS_INT
open_sc10:
ret
open_stdaux:
mov ax,(MS_X_OPEN * 256) + 2
mov dx,offset auxilary ; Open the AUX device
int DOS_INT ; to get internal handle 0
jc open_sa10 ; No AUX device
mov bx,ax ; Force DUP to STDAUX
mov cx,STDAUX
mov ah,MS_X_DUP2
int DOS_INT
mov ah,MS_X_CLOSE
int DOS_INT
open_sa10:
ret
eject
relocate_system:
push ds ! push es
cmp dos_target_seg,0FFFFh ; is the OS going high ?
jne relocate_system10
call SetupHMA ; make sure HMA chain is established
xor cx,cx
xchg cx,systemHMA ; free up any space reserved for the OS
call FreeHMA
call ReserveCommandHMA ; reserve space for COMMAND.COM
relocate_system10:
call reloc_bios ; move down relocatable drivers
call reloc_dos ; move DOS above drivers if RAM based
xor cx,cx
xchg cx,commandHMA
call FreeHMA ; return command.com HMA space to pool
cli
mov ds,dos_dseg ; DS -> DOS data segment
callf cs:dos_init ; (in case of CS relative fixups)
sti
pop es ! pop ds
ret
eject
reloc_dos: ; move DOS down to just above drivers
;----------
push ds
push es
test init_flags,INIT_ROMCODE ; Run the DOS code in ROM
jz $+5 ! jmp reloc_dos90 ; at CURRENT_DOS - No Code Reloc
mov es,current_dos
mov cx,es:DOS_CODE ; get DOS code size in bytes
mov ax,dos_target_seg ; get DOS target
cmp ax,0FFFFh ; it it seg FFFF ?
jne reloc_dos10
mov es,current_dos
mov dx,es:DOS_OFFSET
call AllocHMA ; allocate CX bytes, offset < DX
jnc reloc_dos50 ; if we can use high memory
xor ax,ax ; can't, so try auto-allocation
reloc_dos10:
test ax,ax ; has a specific address been
jnz reloc_dos40 ; specified ?
push cx ; save DOS code size
xchg ax,cx
mov cl,4
shr ax,cl ; convert to paragraphs
pop cx
cmp hidos,0 ; do we want to relocate DOS ?
je reloc_dos20 ; no, allocate conventionally
call alloc_upper ; else allocate space for the DOS
jnc reloc_dos40 ; in upper memory if possible
reloc_dos20:
mov es,current_dos ; if conventional memory we
mov ax,es:INIT_CODE ; can discard INIT code
cmp history_flg,0 ; is history enabled ?
jne reloc_dos30
mov ax,es:HISTORY_CODE ; no, discard history code as well
reloc_dos30:
push cx
add ax,15
mov cl,4 ; convert to paragraphs
shr ax,cl
pop cx
call alloc_seg_with_padding ; allocate in conventional memory
reloc_dos40:
xchg ax,dx ; save segment address
mov es,current_dos ; point at code
mov ax,es:DOS_OFFSET ; get offset of code start
xor di,di
mov es,dx ; ES:DI -> destination address
push cx ; save DOS size
mov cl,4
shr ax,cl ; AX = header size in para's
sub dx,ax ; adjust DOS segment accordingly
pop cx ; CX = DOS size in bytes
reloc_dos50:
; At this point
; CX = # bytes to move
; ES:DI -> destination
; DX = segment to fixup
;
mov dos_cseg,dx ; new code segment for DOS
mov ds,current_dos ; DS -> DOS code
xor si,si
shr cx,1 ; CX = # of words in DOS
rep movsw ; copy DOS down
reloc_dos90: ; fixups performed
pop es
pop ds
ret
Public HookInt2F
HookInt2F:
;---------
; Hook Int 2F during device driver initialisation so we can intercept
; some broadcasts
; On Entry:
; None (beware DS/ES can be anything)
; On Exit:
; None (All regs preserved)
;
push es
push ax
push bx
les bx,cs:drdos_ptr
mov bx,es:DRDOS_INT2F[bx] ; ES:BX -> Int 2F hooks
mov ax,offset Int2FHandler
xchg ax,es:4[bx] ; get Int 2F offset
mov cs:int2FOff,ax
mov ax,cs
xchg ax,es:6[bx] ; get Int 2F segment
mov cs:int2FSeg,ax
pop bx
pop ax
pop es
ret
Public UnhookInt2F
UnhookInt2F:
;-----------
; Device driver initialisation has finished, so unhook from Int 2F
; On Entry:
; None (beware DS/ES can be anything)
; On Exit:
; None (All regs preserved)
;
push es
push ax
push bx
les bx,cs:drdos_ptr
mov bx,es:DRDOS_INT2F[bx] ; ES:BX -> Int 2F hooks
mov ax,cs:int2FOff
mov es:4[bx],ax ; restore Int 2F offset
mov ax,cs:int2FSeg
mov es:6[bx],ax ; restore Int 2F segment
pop bx
pop ax
pop es
ret
; During device driver init we provide some services on Int 2F
; eg. 12FF for EMM386.SYS and 4A01/4A02 for Windows HIMEM.SYS
Int2FHandler:
;------------
; On Entry:
; callers DS on stack
; On Exit:
; if not handled pass on to BIOS, callers DS on stack, all regs preserved
;
pop ds ; pop DS from stack
cmp ax,4A01h ; Query Free HMA Space ?
je HMAQueryFree
cmp ax,4A02h ; Allocate HMA Space ?
je HMAAlloc
cmp ax,12FFh ; is it a relocation service ?
jne OldInt2F
sti ; if we RETF don't leave IF disabled
cmp bx,9 ; register upper memory link
je DOSUpperMemoryRoot
cmp bx,1 ; Relocate BDOS
jb DOSQuerySize ; what's the size of DOS
je DOSRelocate ; where to put it
cmp bx,3 ; Relocate BIOS
jb BIOSQuerySize ; what's the size of BIOS
je BIOSRelocate ; where to put it
OldInt2F:
push ds ; DS on stack as expected
db JMPF_OPCODE
int2FOff dw 0
int2FSeg dw 0
; Enquire DOS size
DOSQuerySize:
;------------
; On Entry:
; None
; On Exit:
; AX = 0
; DX = DOS Size in para's
;
mov dx,cs:dosCodeParaSize ; DX = para's required for DOS code
jmps RelocExit
; Relocate DOS
DOSRelocate:
;-----------
; On Entry:
; DX = para to reloacte to (FFFF=HMA)
; On Exit:
; AX = 0
;
mov cs:dos_target_seg,dx ; save where
jmps RelocExit
; Enquire BIOS size
BIOSQuerySize:
;-------------
; On Entry:
; None
; On Exit:
; AX = 0
; DX = BIOS Size in para's
;
mov dx,cs:rcode_len ; DX = bytes required for BIOS code
add dx,15
mov cl,4
shr dx,cl ; DX para's required
jmps RelocExit
; Relocate BIOS
BIOSRelocate:
;------------
; On Entry:
; DX = para to reloacte to (FFFF=HMA)
; On Exit:
; AX = 0
;
mov cs:bios_target_seg,dx ; save where
; jmps RelocExit
RelocExit:
xor ax,ax ; indicate success
retf 2
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -