📄 config.a86
字号:
call SetupHMA ; make sure HMA chain is established
pop cx ! push cx ; CX = bytes wanted
mov dx,0FFFFh ; anywhere is OK
call AllocHMA ; ES:DI -> allocated data
setup_b40:
pop ax ; AX = bytes wanted
pop dx ; DX = size of a buffer
pop cx ; CX = number of buffer
jnc setup_b70 ; if CY clear ES:DI -> our space
shr ax,1 ! shr ax,1
shr ax,1 ! shr ax,1
inc ax ; convert from bytes to para's
push dx
mov dl,'B' ; allocate as a Buffer
test buffersIn,BUFFERS_IN_UMB
jz setup_b50 ; allocation from UMB's OK ?
call alloc_hiseg ; yes, try and allocate memory there
jnc setup_b60
setup_b50:
call alloc_seg ; allocate memory in bottom 640 K
setup_b60:
pop dx
mov es,ax ; ES = segment
xor di,di ; ES:DI -> start of buffer
setup_b70:
; Buffer space for CX buffers, of size DX, allocated at ES:DI
mov si,di ; remember where 1st buffer is
setup_b80:
push cx
mov bx,di ; BX = current buffer
mov cx,dx
xor ax,ax
rep stosb ; zero the buffer, ES:DI -> next buffer
mov es:BCB_DRV[bx],0FFh ; invalidate buffer
mov es:BCB_NEXT[bx],di ; point to where "next" will be
mov ax,bx
sub ax,dx ; work out what our previous was
mov es:BCB_PREV[bx],ax ; and point to it
pop cx
loop setup_b80 ; do them all
mov es:BCB_NEXT[bx],si ; the last's "next" is our first buffer
mov es:BCB_PREV[si],bx ; the first's "previous" is our last
mov ax,es ; AX:SI -> 1st buffer
les bx,func52_ptr ; ES:BX -> internal data structure
mov es:F52_BCBOFF[bx],si
mov es:F52_BCBSEG[bx],ax ; fixup buffer pointers
mov es:word ptr F52_BUF_INFO[bx],si
mov es:word ptr F52_BUF_INFO+2[bx],ax
inc ax ; seg FFFF ?
jnz setup_b90 ; skip if not
mov es:F52_HMAFLAG[bx],1 ; buffers are in HMA
mov ax,es:F52_SECSIZE[bx]
add ax,15
mov cl,4
shr ax,cl ; convert to para size
mov dl,'B' ; allocate as a Buffer
call alloc_seg ; allocate a deblocking buffer
mov es:F52_DEBLOCK[bx],ax
les bx,drdos_ptr ; ES:BX -> data area
mov es:DRDOS_DEBLOCK[bx],ax ; of deblocking buffer
setup_b90:
ret
setup_doshndl:
push es
les bx,func52_ptr ; Internal Data Pointer
lea bx,F52_FILEPTR[bx] ; Start of Handle List
mov cx,num_files ; Number of DOS Handles
add cx,num_fcbs ; + some for FCB's
cmp cx,255
jbe setup_dh10
mov cx,255 ; maximum IFN is 255
setup_dh10:
cmp es:DCNTRL_DSOFF[bx],0FFFFh ; Last entry ?
je setup_dh20 ; no, loop round again
les bx,es:DCNTRL_DSADD[bx] ; Get the Next Entry
sub cx,es:DCNTRL_COUNT[bx] ; Update the count
jc setup_dh30 ; going negative isn't allowed
jmps setup_dh10
setup_dh20:
jcxz setup_dh30 ; any left to allocate ?
mov ax,DHNDL_LEN ; How many bytes do we need
mul cx ; for the structure
mov dx,ax ; including the control
add ax,DCNTRL_LEN+15 ; Ensure the new structure is
shr ax,1 ! shr ax,1 ; a paragraph value
shr ax,1 ! shr ax,1 ; allocate some memory
mov dl,'F' ; allocate for Files
call alloc_seg
mov es:DCNTRL_DSOFF[bx],0 ; link the new seg
mov es:DCNTRL_DSSEG[bx],ax ; to the end of the list
; We can now initialise the new structure
les bx,es:DCNTRL_DSADD[bx] ; Get the New Entry
mov es:DCNTRL_DSOFF[bx],0FFFFh ; terminate the list
mov es:DCNTRL_DSSEG[bx],0FFFFh ; with -1,-1
mov es:DCNTRL_COUNT[bx],cx ; Number of elements
; Now zero the tables
mov ax,DHNDL_LEN ; How many bytes do we have
mul cx ; with this number of elements
mov cx,ax ; in the structure
lea di,DCNTRL_LEN[bx] ; Zero the contents of the
sub al,al ; structure
rep stosb
setup_dh30:
pop es
ret
setup_drives:
mov al,next_drv ; AL = # of drives supported
push es ! push bx
les bx,func52_ptr ; ES:BX -> base of DOS variables
mov es:F52_PHYDRV[bx],al ; set # of Physical drives installed
mov es:F52_LASTDRV[bx],al ; set # of Logical drives installed
pop bx ! pop es
ret
setup_fopen: ; allocate file hashing information
;-----------
les bx,drdos_ptr
mov ax,num_fopen ; get # of hashed directory entries
cmp ax,-1 ; has it been set yet ?
jne setup_fopen10 ; yes, then leave it alone
mov ax,DEF_NUM_FOPEN
cmp es:DRDOS_HIMEM_ROOT[bx],0; do we have a high memory chain ?
jne setup_fopen10 ; high memory means no TPA hit
xor ax,ax ; keep things small otherwise
setup_fopen10:
xor dx,dx ; AX/DX = 32 bit # of entries
mov si,max_clsize ; max. cluster size
mov cl,5 ; 32 byte per directory entry
shr si,cl ; SI = directory entries per cluster
add ax,si ; round up count to multiple of cluster
dec ax
div si ; AX = # of hashed blocks
mov cx,ax
jcxz setup_fopen90 ; skip if hashing disabled
mov es:DRDOS_HASHMAX[bx],si ; maximum # dir entries allowed
shl si,1 ; SI = bytes required for data
lea si,HCB_DATA[si] ; + control information
mul si ; AX bytes of data required
test dx,dx
jnz setup_fopen90 ; overflow (shouldn't happen)
; Allocate CX HCB_'s of size SI bytes, AX bytes in total
mov bx,es:DRDOS_HIMEM_ROOT[bx]; do we have a high memory chain ?
test bx,bx ; zero indicates we don't
jz setup_fopen30
mov dx,0FFFFh ; use the magic FFFF segment
mov es,dx
cmp ax,es:2[bx] ; is there enough room ?
ja setup_fopen30 ; no, forget try conventinal memory
sub es:2[bx],ax ; else allocate the memory
mov di,es:2[bx] ; get base+length
add di,bx ; = our allocation
mov ax,es:2[bx] ; if the section left is under
cmp ax,2*WORD ; 2 words discard it
jae setup_fopen20 ; as we may overwrite size/link
mov ax,es:[bx] ; get next entry
les bx,drdos_ptr ; and make it the new himem root
mov es:DRDOS_HIMEM_ROOT[bx],ax
setup_fopen20:
xchg ax,dx ; AX = FFFF
jmps setup_fopen40 ; AX:DI -> data block allocated
setup_fopen30:
shr ax,1 ; convert size to para's
shr ax,1
shr ax,1
shr ax,1
inc ax ; allow for rounding
mov dl,'E'
call alloc_hiseg ; allocate it para aligned
dec ax ; zero offset terminates the chain
mov di,10h ; so start with a non-zero offset
; jmps setup_fopen40 ; AX:DI -> data block allocated
setup_fopen40:
; setup CX HCB_'s of size SI at AX:DI
les bx,drdos_ptr
mov es:DRDOS_HASHOFF[bx],di
mov es:DRDOS_HASHSEG[bx],ax
mov es,ax
setup_fopen50:
mov es:HCB_DRV[di],-1 ; discard the HCB initially
mov bx,di ; remember where it is
add di,si ; onto next HCB_
mov es:HCB_LINK[bx],di ; link it to previous HCB_
loop setup_fopen50 ; allocate all hash control blocks
mov es:HCB_LINK[bx],0 ; zero terminate the list
setup_fopen90: ; all HCBs done, return
push cs
pop es ; back to 8080 model
ret
Public whitespace
whitespace:
lodsb ; Skip any White Space in the
cmp al,' ' ! jz whitespace ; CR/LF terminated string
cmp al,TAB ! jz whitespace
dec si
ret
Public build_cmd_tail
build_cmd_tail:
push ds ! pop es
mov cx,length cfg_buffer - 3 ; (leave room for 3 extra chars)
mov di,offset cfg_buffer
build_cl1:
lodsb ; Copy the device name
cmp al,' ' ; until a Control char (end of line)
jbe build_cl2 ; or a Space (end of name)
cmp al,'/' ; Also stop scanning when a switch
je build_cl2 ; character is detected
stosb
loop build_cl1
mov al,CR ; indicate we can go no more....
build_cl2:
cmp al,CR ; it it really the end ?
mov al,' ' ; now insert a space character
stosb
je build_cl_exit ; CR meant it's time to go
dec si ; rewind the source one character
build_cl3:
lodsb ; Copy the tail
cmp al,CR ; until we find a CR
je build_cl4 ; at the end of the line
stosb
loop build_cl3
mov al,CR ; no more room, so terminate
build_cl4:
stosb
build_cl_exit:
mov al,LF ; now insert the terminating linefeed
stosb ; at the end of the buffer
mov si,offset cfg_buffer
ret
save_vecs:
; save interrupt vectors so we can restore if device init fails
push ds ! push es
push si ! push di ! push cx
mov cx,(length vec_save_buf)*2 ; CX = words to save
xor si,si
mov ds,si ; DS:SI -> vectors to save
push cs ! pop es
mov di,offset vec_save_buf ; ES:DI -> save area
rep movsw ; save them
pop cx ! pop di ! pop si
pop es ! pop ds
ret
restore_vecs:
; replace interrupt vectors after a dd_init fails
push ds ! push es
push si ! push di ! push cx
mov cx,length vec_save_buf ; CX = vectors to restore
push cs ! pop ds
mov si,offset vec_save_buf ; DS:SI -> save area
xor di,di
mov es,di ; ES:DI -> vectors to restore
rest_vec1:
mov ax,es:2[di] ; get updated vector
cmp ax,mem_current ; below attempted driver?
jb rest_vec2 ; yes, don't zap it
cmp ax,mem_max ; above attempted driver?
jae rest_vec2 ; yes, don't zap it
movsw ! movsw ; else restore vector
jmps rest_vec3 ; overwritten by driver
rest_vec2:
add si,dword ; skip vector in source
add di,dword ; and in destination
rest_vec3:
loop rest_vec1 ; next vector
pop cx ! pop di ! pop si
pop es ! pop ds
ret
INITDATA DSEG 'INITDATA'
extrn shell:byte ; Default Command Processor
extrn shell_cline:byte ; Default Command Line
extrn num_files:word ; default # of file handles
extrn num_fcbs:word ; default # of fcb file handles
extrn num_fopen:word ; default value for fast open
extrn country_code:word ; Requested Country Code (Default US)
extrn num_stacks:word ; # hardware stacks wanted
extrn stack_size:word ; size of a hardware stack
extrn mem_current:word ; Current Load Address
extrn mem_max:word ; Top of Available Memory
extrn init_dseg:word ; Current init Data Segment
extrn dos_dseg:word
extrn bios_seg:word
extrn func52_ptr:dword
extrn drdos_ptr:dword
extrn res_ddsc_ptr:dword
include initmsgs.def ; Include TFT Header File
extrn preload_drv:byte
extrn init_drv:byte ; the initial boot drive
Public dev_load_seg, dev_reloc_seg, dev_epb, dev_name, dev_count
Public rel_unit, dev_epb
Public strategy_off, strategy_seg, interrupt_off, interrupt_seg, request_hdr
Public next_drv, strategy_seg, strategy, interrupt
Public strategy_seg, condev_off, condev_seg, clkdev_off, clkdev_seg
Public num_blkdev, blkdev_table, next_drv, max_secsize
Public max_clsize, init_buf, num_read_ahead_buf
Public buffersIn, history_flg, history_size
Public dbcs_tbl, ctry_info, boot_device, boot_drv, resdev_chain
history_flg db 0 ; Disable history buffers to save RAM
history_size dw 256 ; When enabled 2*history size are used for bufs
cfg_buffer rb CFG_BUF_LEN ; extra termination for buggy Windows
db CR,LF,0 ; device driver - give it CR/LF to hit
init_buf db MIN_NUM_BUFFS ; default # of buffers
num_read_ahead_buf db DEF_READ_AHEAD ; default # of read-ahead
buffersIn db 0 ; default is low
dev_count db 0 ; count of new drives (used by preload)
next_drv db 0 ; Next Drive to Allocate
num_blkdev dw 0 ; # of block devices installed
boot_device dw 0,0 ; ptr to boot device
boot_drv db 0 ; and the sub unit number
max_secsize dw 0 ; max. sector size encountered
max_clsize dw 0 ; max. cluster size encountered
; Do not change the order of the next four words:
clkdev_off rw 1 ; clock device driver
clkdev_seg rw 1
condev_off rw 1 ; console device driver
condev_seg rw 1
bpbptr rd 0 ; temporary BPB pointer
bpboff rw 1
bpbseg rw 1
devptr rd 0 ; temporary device header pointer
devoff rw 1
devseg rw 1
resdev_chain rd 0 ; head of chain for resident device
resdev_off dw -1 ; drivers
resdev_seg dw -1
abs_unit dw 0 ; absolute unit #
rel_unit dw 0 ; relative unit #
blkdev_table rb BLKDEV_LENGTH*26 ; save block device driver addr. here
;
; Variable for the FUNC_DEVICE and DEV_INIT sub routines
;
strategy rd 0 ; Device Strategy Entry Point
strategy_off rw 1 ; Offset
strategy_seg rw 1 ; Segment Address
interrupt rd 0 ; Device Entry Point
interrupt_off rw 1 ; Offset
interrupt_seg rw 1 ; Segment Address
dev_root rd 0 ; Pointer to Root of Device List
dev_offset rw 1 ; Offset of First Device
dev_segment rw 1 ; Segment of First Device
request_hdr rb RH_SIZE ; DOS Request Header
dev_name rb MAX_FILELEN
dev_epb rw 0
dev_load_seg rw 1 ; Load Segment for Device Driver
dev_reloc_seg rw 1 ; Relocation Factor to be Applied
;
; A number of routines share this common buffer as they are never required
; at the same time. The current clients are -
;
; BDOSLDR.A86: a sector buffer for boot load of IBMDOS
; CONFIG.A86: vector save buffer (during devicehigh)
; NLSFUNC.A86: scratch area for country info
Public sector_buffer
sector_buffer rb 0
; rb 512 ; we need to read a single sector
Public nls_temp_area
nls_temp_area rb 0 ; NLS buffer can be shared with
; rb 258 ; vec_save_buf as they are never
; used together
vec_save_buf rd 256 ; reserve space to save int vectors
dbcs_buf rb 1 ; BDOS puts a 7 here
dbcs_tbl rd 1 ; pointer to DBCS table in BDOS
ctry_info rb CI_LENGTH ; country information
num_buf dw 0 ; # of buffers allocated
; The following are used for detecting old bus master controllers:
removableMediaRequest db 13 ; length of request
db 0 ; unit
db 15 ; removable media check command
dw 0 ; status
rb 8 ; reserved bytes
readRequest db 30 ; length of request
db 0 ; unit
db 4 ; read command
dw 0 ; status
rb 8 ; reserved bytes
db 0F8h ; media ID
dw 0,0 ; buffer address
dw 1 ; read one sector
dw 0FFFFh ; use big sector read
dw 0,0 ; Volume ID
dw 1,0 ; starting sector zero
UpperMemoryBuffer dw 0
numUnits dw 0
deblockPointer rd 0
deblockOffset dw 0
deblockSeg dw 0
Public DeblockSetByUser
DeblockSetByUser db FALSE
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -