CONFIG.A86
资源名称:drdossrc.zip [点击查看]
上传用户:xiaogehua
上传日期:2007-01-08
资源大小:1183k
文件大小:42k
源码类别:
操作系统开发
开发平台:
Asm
- ; File : $CONFIG.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$
- ;
- ; CONFIG.A86 1.35 93/12/01 18:30:29
- ; nls_temp_area grows to 258 bytes
- ; CONFIG.A86 1.34 93/11/28 15:30:27
- ; Support HIBUFFERS in UMB's
- ; CONFIG.A86 1.32 93/11/22 15:02:14
- ; Bus Master checks do Int 21/0D before/after to discard any buffers
- ; CONFIG.A86 1.30 93/11/18 18:02:26
- ; Add primitive multi-master checking
- ; CONFIG.A86 1.27 93/11/04 16:34:24
- ; Extra callout to STACKER to determine if a drive is valid
- ; CONFIG.A86 1.26 93/11/03 17:00:19
- ; Stop dblspace phantom drives from appearing (FATsize=0)
- ; CONFIG.A86 1.25 93/09/14 20:12:24
- ; Initialise LFLG_PHYSICAL better - allow for zero FAT's meaning phantom drive
- ; CONFIG.A86 1.24 93/09/02 22:34:50
- ; Add header to system allocations
- ; CONFIG.A86 1.23 93/08/06 20:55:23
- ; re-arrange device init order for SCREATE.SYS on a VDISK.SYS
- ; CONFIG.A86 1.22 93/08/02 14:45:55
- ; hide preload drives from func_device
- ; CONFIG.A86 1.20 93/07/28 19:19:08
- ; call to SetupHMA before AllocHMA in setup_buffers allows buffers to go high
- ; on novell memory managers
- ; ENDLOG
- include config.equ
- include i:msdos.equ
- include i:char.def
- include i:reqhdr.equ
- include i:driver.equ
- include i:fdos.equ
- include i:f52data.def ; Function 52 DOS Data Area
- include i:doshndl.def ; DOS Handle Structure Definition
- include i:country.def
- TRUE equ 0FFFFh ; value of TRUE
- FALSE equ 0 ; value of FALSE
- CGROUP group INITCODE, INITDATA
- INITCODE CSEG PARA 'INITCODE'
- extrn AllocHMA:near
- extrn SetupHMA:near
- extrn alloc_instseg:near ; Allocate "Segment" Instance Memory
- extrn alloc_hiseg:near ; Allocate "Segment" High Memory
- extrn alloc_seg:near ; Allocate "Segment" Memory
- extrn config_process:near
- extrn InitStacks:near
- extrn HookInt2F:near
- extrn UnhookInt2F:near
- extrn Verify386:near
- Public config_init
- config_init: ; Initialize the CONFIG data
- ret
- Public country_init
- country_init:
- ;------------
- push ds
- push es
- push di
- push si
- ; Obtain the address of the DBCS table in the BDOS.
- mov ax, 06507h ; Extended Country Info: get DBCS ptr
- mov bx, 0FFFFh ; codepage number: -1 for global cp
- mov cx, 00005h ; size of info. buffer
- mov dx, 0FFFFh ; country code: -1 for current country
- mov di, offset dbcs_buf
- push ds
- pop es ; es:di -> 5 byte buffer
- int DOS_INT ; returns with buffer filled in
- ; Get the current country information.
- mov dx, offset ctry_info ; ds:dx -> buffer to be filled in
- mov ax, 03800h ; get current country info
- int DOS_INT
- jnc ctry_info_done ; no carry = no error
- ; Failed to get country info. Place dummy uppercase routine in table.
- mov si, offset ctry_info
- mov CI_CASEOFF[si], offset myretf
- mov CI_CASESEG[si], cs
- mov bx, country_code
- ctry_info_done:
- mov country_code, bx
- pop si
- pop di
- pop es
- pop ds
- ret
- myretf: retf
- ;
- ; CONFIG is called after the BIOS INIT code has been relocated to high
- ; memory, the BIOS and BDOS have been initialised.
- ;
- Public config ; Process CONFIG.SYS, loading and
- config: ; initialising device drivers
- call country_init ; initialise DBCS tbl and country info
- mov ax,max_secsize ; get maximum sector size in BIOS
- les bx,func52_ptr
- cmp ax,es:F52_SECSIZE[bx] ; larger than default?
- jbe cfg_skip ; skip if not
- mov es:F52_SECSIZE[bx],ax ; else update sector size
- cfg_skip:
- call cpu_init ; initialise CPU type
- push ds ! pop es
- call config_process ; Process CONFIG.SYS
- cmp num_files,MIN_NUM_FILES ; Ensure the Minimum number of File
- jae cfg_ex10 ; have been allocated.
- mov num_files,MIN_NUM_FILES
- cfg_ex10:
- xor ax,ax
- mov al,init_buf ; now ensure we have allocated
- mov num_buf,ax ; the correct number of buffers
- call SetupDeblocking ; do our thing with deblocking
- call config_finish ; clean up configuration
- call setup_fopen ; allocate disk hashing
- call setup_history
- ret
- cpu_init:
- ; If we are on a 386 or above set CPU flag
- call Verify386 ; make sure it's a 386
- jc cpu_init10 ; skip setting falg if not
- les bx,func52_ptr
- mov es:F52_CPU_TYPE[bx],1 ; we have a 386 !
- cpu_init10:
- stc ; it's not a 386
- ret
- SetupDeblocking:
- ;---------------
- ; Some types of hard disk controller give us problems with disk access of
- ; mapped memory (eg. upper memory, LIM pages).
- ; We can force single sector deblocking in the disk driver to avoid these
- ; problems. On DRDOS 5/6 our default was single sector I/O above A000, but
- ; this gives performance problems when devices/tsr's are loaded into upper
- ; memory (eg. STACKER, SERVER). To avoid this we use the following strategy.
- ;
- ; Default for CONFIG is A000, and may be updated at any time by a DEBLOCK=
- ; statement. If this happens the user setting has priority.
- ;
- ; At the end of CONFIG, assume no user supplied setting, we do some simple
- ; tests for multi-master controllers. If these fail we leave the settings
- ; at A000. If they succeed we go ahead and change the default setting to
- ; deblock at FFFF. The test is to read the 1st sector into low memory, and
- ; again into upper memory. If we read the same thing then assume all is well.
- ; If we can't do this leave the deblocking set at A000.
- ;
- ; NB. We will still have problems from LIM, and from DMA crossing page
- ; boundaries on some memory managers (eg. DRDOS 5.0)
- ;
- les bx,func52_ptr
- lea bx,F52_DEVROOT[bx] ; ES:BX -> NUL device link
- cmp DeblockSetByUser,FALSE
- je SetupDeblocking20 ; the user is king
- SetupDeblocking10:
- push cs ! pop es ; ES -> local data again
- ret
- SetupDeblocking20: ; get next device driver
- les bx,es:[bx] ; we want resident disk device
- cmp bx,0FFFFh ; end of the chain ?
- je SetupDeblocking10
- test es:word ptr 4[bx],8000h
- jnz SetupDeblocking20 ; we assume one disk device at 70:xxxx
- mov ax,es
- cmp ax,cs:bios_seg ; scan for resident disk in IO.SYS
- jne SetupDeblocking20
- cmp es:word ptr 18[bx],0EDCh
- jne SetupDeblocking20 ; is it our disk driver ?
- lea ax,22[bx] ; deblocking variable is here
- mov deblockOffset,ax ; remember that for fixups
- mov deblockSeg,es
- mov ax,es:DH_STRATEGY[bx] ; Set up the STRATEGY Entry Point
- mov strategy_off,ax
- mov strategy_seg,es
- mov ax,es:DH_INTERRUPT[bx] ; Set up the INTERRUPT Entry Point
- mov interrupt_off,ax
- mov interrupt_seg,es
- mov al,es:DH_NAME[bx] ; get # supported units
- cbw
- mov numUnits,ax ; remember for later
- mov ax,(MS_M_STRATEGY*256)+1; set allocation strategy
- mov bl,42h ; to last fit, upper only
- int DOS_INT
- mov bx,512/16 ; we need a 512 byte buffer
- mov ah, MS_M_ALLOC ; try to allocate on in upper memory
- int DOS_INT
- jc SetupDeblocking50
- mov UpperMemoryBuffer,ax ; use this for deblocking checks
- mov cx,numUnits ; CX = # of drives supported
- mov dx,'C'-'A' ; start with drive C:
- sub cx,dx ; CX = # of potential hard disks
- jbe SetupDeblocking40 ; skip tests if none
- SetupDeblocking30: ; DX = next drive, CX = drive count
- push cx ! push dx
- call BusMasterCheck ; check if drive DL bus master disk
- pop dx ! pop cx
- jc SetupDeblocking40 ; is so leave deblocking alone
- inc dx ; else move to next drive
- loop SetupDeblocking30 ; repeat for all drives
- les bx,deblockPointer
- mov es:word ptr [bx],0FFFFh ; safe to disable deblocking
- SetupDeblocking40:
- mov es,UpperMemoryBuffer
- mov ah,MS_M_FREE
- int DOS_INT ; free the upper memory buffer
- SetupDeblocking50:
- mov ax,(MS_M_STRATEGY*256)+1; set allocation strategy
- mov bl,0 ; to first fit
- int DOS_INT
- push cs ! pop es ; ES -> local data again
- ret
- BusMasterCheck: ; determine if we have an old troublesome controller
- ;--------------
- ; On Entry:
- ; DL = drive to check (zero based)
- ; On Exit:
- ; CY set if troublesome drive
- ;
- call BusMasterRemovable ; is it a removable device ?
- jnc BMCheck10 ; yes, skip the checks
- mov ax,mem_current ; read into low memory
- call BusMasterRead ; read one sector from disk
- jc BMCheck10 ; give up if we couldn't read
- mov es,mem_current ; ensure at least the 1st word will
- mov ax,es:.0 ; differ if the read doesn't happen
- not ax
- mov es,UpperMemoryBuffer
- mov es:.0,ax
- mov ax,UpperMemoryBuffer ; read into upper memory
- call BusMasterRead ; read one sector from disk
- jc BMCheck10 ; give up if we couldn't read
- xor si,si
- xor di,di
- mov cx,512/2
- mov es,mem_current
- mov ds,UpperMemoryBuffer
- repe cmpsw ; does the sector match ?
- push cs ! pop ds
- je BMCheck10 ; yes, everything is fine
- stc ; no, better leave DEBLOCK at A000
- BMCheck10:
- ret
- BusMasterRemovable:
- ;------------------
- ; On Entry:
- ; DL = drive
- ; On Exit:
- ; CY set if not a removable drive
- ; DL preserved
- ;
- push cs ! pop es
- mov bx,offset removableMediaRequest
- mov es:RH_UNIT[bx],dl
- callf cs:strategy
- callf cs:interrupt
- test es:RH_STATUS[bx],RHS_BUSY
- jz BusMasterRemovable10
- stc ; busy bit set, it's a hard disk
- BusMasterRemovable10:
- ret
- BusMasterRead: ; Read first sector from drive BL
- ;-------------
- ; On Entry:
- ; AX = segment of buffer
- ; DL = 02 for C:, 03 for D:, etc.
- ; Exit:
- ; CY clear if deblocking not required
- ; DL preserved
- ;
- les bx,deblockPointer
- mov es:word ptr [bx],0FFFFh ; no deblocking during the test
- push cs ! pop es
- mov bx,offset readRequest
- mov es:RH_UNIT[bx],dl
- mov es:RH4_BUFOFF[bx],0
- mov es:RH4_BUFSEG[bx],ax
- mov es:RH4_COUNT[bx],1
- callf cs:strategy
- callf cs:interrupt
- test es:RH_STATUS[bx],RHS_ERROR
- jz BusMasterRead10
- stc ; error bit set, say we had a problem
- BusMasterRead10:
- les bx,deblockPointer
- mov es:word ptr [bx],0A000h ; enable deblocking again
- ret
- Public setup_stacks
- setup_stacks:
- mov cx,num_stacks ; we want this many stacks
- jcxz setup_stacks10 ; skip if we don't want any
- mov dx,stack_size ; they should be this big
- call InitStacks ; initialise the stacks
- setup_stacks10:
- ret
- setup_history:
- test history_flg,RLF_ENHANCED
- jz setup_hist10 ; if history not enabled just exit
- push es
- les bx,drdos_ptr ; Get the internal data area
- mov si,es:DRDOS_HIST1CTL[bx]; Get the address of History Control
- mov ax,history_size ; Get Offset buffer for History data
- call setup_hist20 ; Allocate Buffer 1
- mov si,es:DRDOS_HIST2CTL[bx]; Get the address of History Control 2
- mov ax,history_size ; Get Offset buffer for History data
- call setup_hist20 ; Allocate Buffer 2
- mov al,history_flg ; copy history state
- mov es:DRDOS_HISTFLG[bx],al ; into DRDOS data area
- pop es
- setup_hist10:
- ret
- setup_hist20:
- and ax,not 15 ; round to a complete paragraph
- add ax,16 ; always be a para bigger
- mov es:word ptr 02[si],ax ; Buffer Tail Address
- mov cl,4
- push ax ; save buffers size in bytes
- shr ax,cl ; convert to para's
- mov dl,'H' ; History buffer
- call alloc_instseg ; Allocate Buffer
- mov es:word ptr 00[si],ax ; Buffer Start Address
- pop cx ; recover buffer size in bytes
- push es
- mov es,ax ; point ES at buffer seg
- xor di,di ; ES:DI -> buffer
- xor ax,ax ; zero it
- rep stosb ; before use
- pop es
- ret
- Public device_init, resident_device_init
- ; DEVICE_INIT will initialise the device with the Device Header at
- ; ES:BX
- ;
- ; Entry:
- ; ES:DI Address of First Device Header
- ; DS:SI Command Line Parameters
- ;
- ; Exit:
- ; AX Top bit set on error, error code in AL
- ;
- device_init:
- ;-----------
- push es ! push di
- call build_cmd_tail ; point DS:SI to dos style cmd line
- pop di ! pop es
- call HookInt2F ; hook the Int 2F vector
- call resident_device_init
- call UnhookInt2F ; get off the Int 2F vector
- test ax,ax ; set the flags
- ret
- resident_device_init:
- ;--------------------
- mov rel_unit,0 ; set rel unit to zero for block devices
- mov dev_count,0
- mov bx,offset request_hdr ; ds:bx -> command block
- if TRUE
- mov ax,mem_max ; AX:0 -> top of available memory
- mov ds:RH0_RESIDENT,0 ; pass to the device driver
- mov ds:RH0_RESIDENT+2,ax ; in the RESIDENT field
- else
- mov ds:RH0_RESIDENT,di ; Force the default RESIDENT field
- mov ds:RH0_RESIDENT+2,es ; to be the error condition
- endif
- dev_i10:
- push si
- push es ! push di
- call save_vecs ; save interrupt vectors
- mov bx,offset request_hdr ; ds:bx -> command block
- call dev_init ; initialise the device driver
- test es:DH_ATTRIB[di],DA_CHARDEV
- jnz dev_i18 ; skip if a character device
- cmp ds:RH0_NUNITS,0 ; no drives installed for disk device?
- je dev_i_err ; failed if no drives found
- dev_i18:
- mov ax,ds:RH0_RESIDENT ; Calculate the address of
- mov cl,4 ; last paragraph used by the
- shr ax,cl ; device driver. If this is the
- add ax,ds:RH0_RESIDENT+2 ; device driver CS then error
- test ds:RH0_RESIDENT,15 ; allow for partial para ?
- jz dev_i19
- inc ax ; round it up
- dev_i19:
- cmp ax,strategy_seg
- jbe dev_i_err
- cmp ax,mem_max ; Check for Memory Overflow
- jb dev_i30 ; if it does then we can't install
- call restore_vecs ; so replace interrupt vectors
- dev_i_err: ; device initialization failed!
- les di,cs:func52_ptr ; ES:DI -> internal data
- mov ax,es
- or ax,di ; DOS data area present yet?
- pop di ! pop es ; recover the device header
- les di,es:DH_NEXT[di] ; try next device driver
- jz dev_i60 ; if it's resident initialisation
- mov di,0FFFFh ; else stop now
- jmps dev_i60
- ; The device driver initialised OK so now build/update internal
- ; tables based on the device driver type.
- ;
- ; AX = next available paragraph
- ; DS:BX = request header
- ; ES:DI = device driver header
- ;
- dev_i30: ; DEV_INIT OK so update the Top of
- mov mem_current,ax ; memory field
- test es:DH_ATTRIB[di],DA_CHARDEV
- jz dev_i40
- call char_device ; Handle Initialization of all
- jmps dev_i50 ; character devices
- dev_i40:
- call block_device ; Handle Initialization of all
- ; jmps dev_i50 ; Block Devices
- dev_i50:
- pop di ! pop es ; Retrieve the current device header
- push es:DH_NEXTSEG[di] ; save next entry on the list
- push es:DH_NEXTOFF[di] ; while we deal with existing one
- mov es:DH_NEXTOFF[di],0FFFFh; terminate the list
- call device_insert ; and insert into the list
- pop di
- pop es ; go round till the end
- dev_i60:
- pop si ; recover cmdline for next device
- cmp di,0FFFFh ; was that the last device to
- jne dev_i10 ; initialise, no do next
- mov bx,offset request_hdr ; ds:bx -> command block
- mov ax,ds:RH_STATUS ; return Status Register
- and ax,80FFh ; is there an error ?
- js dev_i70
- xor ax,ax ; no, return success
- dev_i70:
- ret
- public init_static_request
- init_static_request:
- ; Set up request header for INIT command.
- sub ax,ax ; get a convenient zero
- mov ds:RH_LEN,RH0_LEN ; Init Request Length
- mov ds:RH_UNIT,al ; relative drive always 0
- mov ds:RH_CMD,CMD_INIT ; Init Command
- mov ds:RH_STATUS,ax ; Zero Status Register
- mov ds:RH0_BPBOFF,si ; Save the command line offset and
- mov ds:RH0_BPBSEG,ds ; Segment in the BPB Pointer
- mov al,next_drv ; the first drive for this device
- sub al,preload_drv ; (not including preloaded devices)
- mov ds:RH0_DRIVE,al ; will be allocated as NEXT_DRV
- ;;; mov es:DH_NEXTSEG[di],0 ; force seg to zero (386max 4.05)
- ret
- dev_init:
- ;--------
- ; On Entry:
- ; ES:DI -> device driver header
- ; DS:BX -> req header
- ; DS:SI -> command line
- ; On Exit:
- ; ES:DI/DS:BX <preserved>
- ;
- mov ax,es:DH_STRATEGY[di] ; Set up the STRATEGY Entry Point
- mov strategy_off,ax
- mov strategy_seg,es
- mov ax,es:DH_INTERRUPT[di] ; Set up the INTERRUPT Entry Point
- mov interrupt_off,ax
- mov interrupt_seg,es
- call init_static_request
- push ds ! push es ; Save Segment registers
- push bx ! push si ! push di ; and pointers (not all preserve them)
- push ds ! pop es ; ES -> Points at the Data Segment
- mov ds,strategy_seg ; DS == Device Drive Segment
- mov si,di ; DS:SI -> device driver header
- callf cs:strategy ; Call Device Strategy Routine
- callf cs:interrupt ; Call Device Interrupt Routine
- pop di ! pop si ! pop bx ; recover the pointers
- pop es ! pop ds ; Restore Segment Registers
- mov es:DH_NEXTSEG[di],es ; ignore segment - it MUST be same one
- ret
- ;
- ; Character Device Driver Initialised OK so now build/update internal
- ; tables based on the device driver type.
- ;
- ; DS:BX Request Header
- ; ES:DI Device Driver Header
- ;
- char_device:
- test es:DH_ATTRIB[di],DA_ISCIN
- jz char_d10 ; is this the standard console device?
- mov condev_off,di ; save console device driver address
- mov condev_seg,es
- ret
- char_d10:
- test es:DH_ATTRIB[di],DA_ISCLK
- jz char_d20 ; is this the standard clock device?
- mov clkdev_off,di ; save clock device driver address
- mov clkdev_seg,es
- char_d20:
- ret
- ; Block device driver initialised OK. Save the values
- ; returned from the INIT call so we can later build all the
- ; required internal tables.
- ;
- ; entry: DS:BX -> request header
- ; ES:DI -> device driver header
- ;
- public block_device
- block_device:
- mov al,BLKDEV_LENGTH ; bytes per block device table entry
- mul byte ptr num_blkdev ; * # of block devices installed
- add ax,offset blkdev_table ; AX -> block dev init result table
- xchg ax,si ; pointer to next block device struct
- mov devoff,di
- mov devseg,es ; point to device driver header
- mov 0[si],di
- mov 2[si],es ; save device driver address for later
- mov ax,ds:RH0_BPBOFF
- mov 4[si],ax ; save BPB table address (offset)
- mov ax,ds:RH0_BPBSEG
- mov 6[si],ax ; save BPB table address (segment)
- mov cl,ds:RH0_NUNITS
- mov 8[si],cl ; get # of units supported by driver
- mov es:DH_NAME[di],cl ; set # of units in device name
- inc num_blkdev ; we've installed another block device
- add next_drv,cl ; update drive base for next driver
- add dev_count,cl ; number of new units
- mov ax,boot_device ; now for Andy's bit about boot device
- or ax,boot_device+2 ; have we already got a boot device?
- jnz not_boot_dev
- mov ch,init_drv
- sub ch,next_drv ; is sub unit in this driver
- ja not_boot_dev ; no, skip it
- add ch,cl ; work out which sub unit it is
- mov boot_drv,ch ; and remember it
- mov boot_device,di
- mov boot_device+2,es
- not_boot_dev:
- push si ! push es ! push di
- mov cl,8[si]
- mov ch,0 ; CX = # of drives found in driver
- les si,4[si] ; ES:SI -> BPB array in BIOS
- mov bpbseg,es ; remember the segment
- blkdev_loop:
- lods es:ax ; AX = offset of next BPB
- push es ! push si ! push cx
- mov bpboff,ax ; remember the offset
- xchg ax,di ; ES:DI -> next BPB
- mov ax,es:[di] ; AX = sector size for BPB
- cmp ax,max_secsize ; new maximum for sector size
- jbe blkdev_next1 ; skip if sector size not grown
- mov max_secsize,ax ; else set new maximum
- blkdev_next1:
- mov dl,es:2[di] ; get sectors per cluster
- mov dh,0 ; make this a word
- mul dx ; AX = bytes per cluster
- cmp ax,max_clsize ; more than previous maximum
- jbe blkdev_next2 ; skip if no new high score
- mov max_clsize,ax ; else record max. sector size
- blkdev_next2:
- les bx,func52_ptr ; ES:BX -> internal data
- mov ax,es
- or ax,bx ; DOS data area present yet?
- jz blkdev_next3 ; skip if BDOS not present yet
- call setup_drives ; update drives in BDOS data
- mov es,mem_current ; MUST create a DDSC just after driver
- add mem_current,(DDSC_LEN+15)/16
- xor bp,bp ; ES:BP points to the DDSC
- call setup_ddsc ; add new DDSC_ to chain
- call setup_ldt ; initialise LDT for that drive
- blkdev_next3:
- pop cx ! pop si ! pop es
- loop blkdev_loop ; repeat for all BPBs in driver
- pop di ! pop es ! pop si
- ret
- resident_ddscs:
- ;--------------
- ; Allocate DDSC's for the resident device drivers - we can only do this
- ; after the DOS data area is established.
- ;
- sub bx,bx ; start with 1st block device
- mov cx,num_blkdev ; get # of block devices
- jcxz res_ddsc40 ; skip if no block devices
- res_ddsc10:
- push bx ! push cx
- mov ax,BLKDEV_LENGTH
- mul bx
- add ax,offset blkdev_table
- xchg ax,si ; SI -> block device table
- sub cx,cx
- mov cl,8[si] ; CX = # of units on device
- sub bx,bx ; BX = relative unit # * 2
- mov rel_unit,bx ; start with relative unit # 0
- res_ddsc20: ; CX = remaining units
- push bx ! push cx ! push si ; BX = offset, SI -> drive structure
- lodsw
- mov devoff,ax ; save device header offset
- lodsw
- mov devseg,ax ; save device header segment
- les si,[si] ; get offset of BPB array
- mov ax,es:[bx+si] ; get offset for our BPB
- mov bpboff,ax
- mov bpbseg,es ; save pointer to BPB
- les bp,res_ddsc_ptr ; point to position for DDSC_
- add ds:word ptr res_ddsc_ptr,DDSC_LEN
- call setup_ddsc ; setup one unit
- pop si ! pop cx ! pop bx
- inc bx ! inc bx ; increment (unit index*2)
- loop res_ddsc20 ; repeat for next unit, same driver
- pop cx ! pop bx
- inc bx
- loop res_ddsc10 ; repeat for next driver
- res_ddsc40: ; all block devices done
- ret
- setup_ddsc:
- ;----------
- ; On Entry:
- ; ES:BP -> DDSC_ to initialise and link into chain
- ; bpbptr -> BPB to initialise from
- ; devseg:devoff -> device driver header
- ; abs_unit, rel_unit reflect drive
- ; On Exit:
- ; None
- ;
- push ds
- lds si,bpbptr ; DS:SI points to the BPB
- mov ah,53h ; build DDSC from BPB call
- int DOS_INT ; initialises the structure
- pop ds
- mov ax,devoff
- mov es:DDSC_DEVOFF[bp],ax
- mov ax,devseg
- mov es:DDSC_DEVSEG[bp],ax
- mov ax,abs_unit
- inc abs_unit
- mov es:DDSC_UNIT[bp],al ; set absolute unit (global)
- mov ax,rel_unit
- inc rel_unit
- mov es:DDSC_RUNIT[bp],al ; set relative unit (driver relative)
- mov ax,-1 ; set link to FFFFh:FFFFh
- mov es:word ptr DDSC_LINK[bp],ax
- mov es:word ptr DDSC_LINK+2[bp],ax
- mov es:DDSC_FIRST[bp],al ; set drive never accessed flag
- mov ax,es ; now link into device chain
- ;
- les bx,func52_ptr ; ES:BX -> secret 52h data
- lea bx,F52_DDSCPTR-(offset .DDSC_LINK)[bx]
- setup_ddsc10:
- cmp es:word ptr DDSC_LINK[bx],0FFFFh
- je setup_ddsc20 ; is there another one ?
- les bx,es:DDSC_LINK[bx] ; onto next DDSC_
- jmps setup_ddsc10
- setup_ddsc20: ; link new DDSC to end of chain
- mov es:word ptr DDSC_LINK[bx],bp
- mov es:word ptr DDSC_LINK+2[bx],ax
- ret ; now RAF will be happy
- Public setup_ldt
- setup_ldt:
- push ds
- push es
- les bx,func52_ptr ; get internal data in ES:BX
- mov al,LDT_LEN ; we need this many bytes per drive
- mul es:F52_LASTDRV[bx] ; *lastdrive
- xchg ax,cx ; CX = size to initialise
- mov al,es:F52_LASTDRV[bx] ; lastdrive
- push ax ; save for later
- les di,es:F52_PATHPTR[bx] ; now initialise the CSD's
- xor al,al ; to zero
- rep stosb ; zero them
- pop ax ; recover lastdrive
- xor bx,bx ; start with zero offset
- xor cx,cx ; start with drive A
- xchg al,cl ; AH = physical limit, CX logical limit
- ldt_init:
- push ax
- push cx
- push ax
- lea di,LDT_NAME[bx]
- add al,'A' ; make drive ASCII
- stosb
- mov ax,':' ; point at the root
- stosw
- mov ax,0FFFFh
- lea di,LDT_BLK[bx] ; set to FFFF to force LDT_ rebuild
- stosw ! stosw ! stosw ; next two words are FFFF too
- ; lea di,LDT_ROOTLEN[bx]
- mov ax,2
- stosw ; set the length field
- pop ax
- lds si,cs:func52_ptr ; get internal data in DS:SI
- sub si,offset .DDSC_LINK
- ldt_init20:
- lds si,ds:DDSC_LINK[si] ; point to next PDT
- cmp si,-1 ; skip if there isn't one
- je ldt_init40
- cmp al,ds:DDSC_UNIT[si] ; is this the DDSC for the drive
- jne ldt_init20 ; if not try another
- mov es:word ptr LDT_PDT[bx],si
- mov es:word ptr LDT_PDT+2[bx],ds
- cmp ds:DDSC_NFATS[si],0 ; no FATS, then it's a reserved drive
- je ldt_init40
- push es
- push bx
- push ax ; save drive we are processing
- mov ax,4A11h
- xor bx,bx
- int 2Fh ; do an STACKER installation check
- pop dx ; DL = drive we are processing
- test ax,ax
- mov ax,LFLG_PHYSICAL ; assume a physical drive
- jnz ldt_init30 ; no STACKER, it's physical
- sub cl,'A' ; zero base STACKER drive returned
- cmp cl,dl ; should we check this drive ?
- ja ldt_init30 ; below 1st drive, it's physical
- push ax
- push dx
- mov ax,4A11h
- mov bx,1 ; ask STACKER for host drive
- int 2Fh
- pop dx
- pop ax
- cmp bl,dl ; is this the host drive ?
- jne ldt_init30
- xor ax,ax ; drive is invalid
- ldt_init30:
- pop bx
- pop es
- mov es:LDT_FLAGS[bx],ax
- ldt_init40:
- add bx,LDT_LEN ; move onto next LDT_
- pop cx
- pop ax
- inc ax ; and next drive
- loop ldt_init ; done to lastdrive ? no, do another
- pop es
- pop ds
- ret
- Public device_insert
- device_insert:
- ;-------------
- ; insert device drivers at ES:DI into global chain
- ; if we are initialising the resident device drivers then we don't have
- ; a global chain, so insert them on a local chain and try again later
- push ds
- lds bx,func52_ptr ; Internal Data Pointer
- lea si,F52_DEVROOT[bx] ; DS:SI -> NUL device
- mov ax,ds ; if BDOS data area isn't present
- or ax,bx ; we are initialising resident
- jnz dev_ins_next ; devices
- push cs ! pop ds
- mov si,offset resdev_chain ; it's resident devices
- dev_ins_next:
- cmp di,-1 ; end of device chain reached?
- je devins_done ; yes, all devices inserted
- mov ax,0[si]
- mov dx,2[si] ; DX:AX = original chain
- mov 0[si],di
- mov 2[si],es ; link our device at head of chain
- xchg ax,es:0[di] ; link old global chain to device
- xchg dx,es:2[di] ; & get next device in local chain
- mov di,ax ; point to next device in chain
- mov es,dx
- jmps dev_ins_next ; repeat until chain empty
- devins_done:
- pop ds
- ret
- public config_finish
- config_finish: ; finish off configuration
- ;-------------
- cmp resdev_off,-1 ; are resident devices already
- je cfg_fin10 ; installed
- les di,resdev_chain ; insert all the resident device
- call device_insert ; drivers into DOS chain
- call resident_ddscs ; build DDSC's for resident devices
- mov resdev_off,-1 ; only do this once...
- cfg_fin10:
- les bx,func52_ptr ; ES:BX -> base of DOS variables
- call setup_drives ; Update No of Physical Drives in case
- ; this is the first pass
- call setup_ldt ; setup the ldt's
- les bx,func52_ptr
- lea di,F52_CLKDEV[bx] ; ES:DI -> clock ptr, console ptr
- mov si,offset clkdev_off ; DS:SI -> local pointer values
- movsw ; set offset of clock device driver
- movsw ; set segment of clock device driver
- movsw ; set offset of console device driver
- movsw ; set segment of console device driver
- call setup_doshndl ; Allocate DOS compatible Handles
- ; NB must immediately follow devices !
- call setup_buffers ; allocate the requested #
- ret
- setup_buffers:
- ;-------------
- ; entry: num_buf = minimum # of buffers required
- ; 0 - use temporary high buffers
- ;
- les bx,func52_ptr ; ES:BX -> internal data structure
- mov ax,num_buf ; fill in info in DOS for diagnostic
- mov es:F52_NUM_BUF[bx],ax ; programs
- mov al,num_read_ahead_buf
- mov es:F52_READ_AHEAD[bx],ax
- mov ax,es:F52_SECSIZE[bx] ; get DOS data sector size
- cmp ax,max_secsize ; has it been poked to a bigger value ?
- ja setup_b10 ; if so we must discard anyway
- mov ax,max_secsize ; get max. sector size found
- setup_b10:
- mov es:F52_SECSIZE[bx],ax ; update max. sector size in PCMODE
- mov max_secsize,ax ; update max. sector size locally
- add ax,offset .BCB_DATA ; add in the header size
- mov es,init_dseg ; ES:DI -> init buffers
- mov di,offset INIT_BUFFERS
- mov cx,NUM_BUFFS ; CX buffs, DX in size, at ES:DI
- mov dx,SIZEOF_BUFFS ; size of init buffers
- cmp num_buf,0 ; (zero at init time)
- je setup_b70 ; go ahead and initialise
- push ax ; save size of buffer
- mul num_buf ; AX = total bytes required
- test dx,dx ; > 64 K ?
- jz setup_b30
- mov ax,0FFFFh ; do the maximum
- setup_b30:
- pop bx ; BX = size of a buffer
- mov cx,ax ; CX bytes required
- xor dx,dx
- div bx ; AX = # buffers
- push ax ; save # buffers
- push bx ; save size of a buffer
- push cx ; save bytes wanted
- test buffersIn,BUFFERS_IN_HMA
- stc ; do we want buffers at FFFF ?
- jz setup_b40
- 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