⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bambi.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 5 页
字号:
	page    58,132
;/*
; *                      Microsoft Confidential
; *                      Copyright (C) Microsoft Corporation 1991
; *                      All Rights Reserved.
; */

;debug  =       1       ; enables some debug code
;tracker        =       0ffffh  ; enables special TRACKER events
debug = 0
tracker = 0

;    BAMBI global register conventions:
;
;       The machine registers are generally considered extremely
;       volatile in this program and should not generally be
;       considered to be preserved when calling a subroutine,
;       unless specifically stated otherwise.
;
;       DS: generally points to CS: in order to access the data
;       stored there without overrides.
;
;    BAMBI design assumptions:
;
;       The number of sectors per cache block CANNOT be > 16.
;
;       Write caching of a given drive implies that it is read cached.
;
;    Purpose of this module:
;
;       This is the main resident device driver interface for Bambi.
;       It contains the main caching logic flow and utilizes external
;       modules for keeping track of caching data structure and accessing
;       secondary RAM storage.
;
;       This module provides one main entry point, which is our_strat/
;       our_int.  This is what DOS calls through to access the block
;       device drivers.  It also contains entry points which are used
;       by the dirty_write function in a companion module.

	.xlist
	include msequ.inc       ; get device request packet definitions
	include devsym.inc      ; get device driver structure definitions
	include bambi.inc
	include bootform.inc
	include bpb.inc
	.list

public  our_int                 ; DOS branches here for ALL block
public  our_strat               ;  device driver calls for devices which
				;  are present when we're first initialized

;       We publish a few special entry points and variables for use
;       by the dirtywrt.asm module.

public  lookup_device
public  read_full_cache_block
public  set_start_sector
public  call_dd_common

public  loc_req_seg             ; allow bambinit to initialize our pointers
public  lb_seg

public  our_count
public  our_trans_off
public  our_trans_seg
public  our_starth
public  our_startl
public  our_start

public  loc_reqblk
public  num_valid_buffers
public  rblk_op
public  media_id
public  media_ids 

public  packet_size
public  packet_sizes

public  next_bad_entry_ptr 
public  num_bad_blocks  

zseg    segment public 'code'
	assume  cs:zseg,ds:nothing,es:nothing

;
;       data from rdata.asm
;
extrn   last_buffer             :word
extrn   max_valid_buffers       :word

extrn   dos_3x                  :word
extrn   hit_l                   :word
extrn   hit_h                   :word
extrn   nohit_l                 :word
extrn   nohit_h                 :word
extrn   in_bambi                :byte

extrn   selected_drive          :byte

extrn   real_dd_headers         :dword
extrn   real_cache_units        :byte
extrn   secsize_and_align_info  :word
extrn   cache_block_bytes       :word

extrn   cache_block_words       :word

;
;       routines from queueman.asm
;
extrn   flush_queue             :near
extrn   set_dirtyindex          :near
extrn   fast_lookup             :near
extrn   invalidate_element      :near
extrn   queue_element           :near

;
;       routines from cacheman.asm
;
extrn   cache_to_buffer         :near
extrn   buffer_to_cache         :near
extrn   commit_all_dirty        :near
;
;       data from int2f.asm
;
extrn   accessing_swap_file_ptr :dword
;
;       data from queueman.asm
;
extrn   queuelength             :word
;
;       data from hooks.asm
;
extrn   resident_stack          :word
extrn   temp_res_stack          :word
extrn   save_stack_ss           :word
extrn   save_stack_sp           :word
extrn   commit_all_when_ok      :byte
extrn   write_behind_cache      :near

;
;       routines from popup.asm
;
extrn   warning_pop_up          :near

;
;       data from bambinit.asm
;
extrn   ending_address          :word
extrn   number_of_cache_elements:word   ;WARNING transient!
extrn   initqueue               :near

;       local variables
;
;       Please note:  Many of these variables are only valid for
;                     the operation being performed by the mainline
;                     routine.  dirty_write must handle its own
;                     configuration constants on the fly.
;
;       put our dword pointers first so they're all
;       aligned without wasting space

far_call_address        dd      0
d_trans                 dd      0
dd_header               dd      0
user_reqblk             dd      0
MAXRENTER       equ     5               ;arbitrary number of reentracy allowed
user_save_reqblk        dd      MAXRENTER       dup(0)

;       quick reference points for our block buffer and request block
;          the segments fields are declared external so bambinit.asm
;          can initialize them.

loc_reqblk              label   dword
			dw      our_reqblk
loc_req_seg             dw      0       ; init'd by bambinit, always == cs

local_buf               label   dword
			dw      0
lb_seg                  dw      0       ; this will generally be a
					;  different segment from cs

;       put word variables next

blockids                dw      16 dup (?)
d_count                 dw      0
curblk_l                dw      0
curblk_h                db      0,0     ; may be accessed as word

lastblk_l               dw      0
lastblk_h               db      0,0     ; may be accessed as word

curblk_index            dw      0       ; high byte may be assumed to be zero
cache_element_index     dw      0

num_valid_buffers       dw      0       ; num. valid buffers in 'super-cache'
bufferblk_l             dw      0       ; low word of base block of super-cache
bufferblk_h             dw      0       ; high word + drive number

cache_align_factor      dw      0       ; must be < cache_block_sectors
cache_block_shift       dw      2       ; log2(blocksize/sectorsize)

sector_size_bytes       dw      512
cache_block_sectors     dw      4

dirty_mask              dw      0       ; mask for last looked up element
	ifdef   USE_VALID
valid_mask              dw      0       ; mask for last looked up element
	endif
cache_mask              dw      0       ; this is the full mask
;                                       ; for the selected block/sector size

;       the following data structure is used when we wish to
;       wish to issue a device driver call other than the one
;       originally passed to us from DOS.  It can benefit from
;       word alignment.

our_reqblk      label   byte
packet_size     db      30      ; length
rblk_cache_unit db      2       ; cache unit
rblk_op         db      devrd   ; read command
devstatus       dw      0       ; status
		db      13-5 dup (0) ; other stuff (???)
media_id        db      0f0h    ; media id byte
our_trans_off   dw      0       ; transfer offset
our_trans_seg   dw      0       ; transfer segment
our_count       dw      0       ; count
our_start       dw      0ffffh  ; start (ignored)
		dw      0,0
our_startl      dw      0       ; start low
our_starth      dw      0

in_device_call  dw      -1
media_ids       db      26      dup(0f0h) ;save media_id for dirty writes

packet_sizes    db      26      dup(30h)  ;save packet sizes for dirty writes

MAXBADS         equ     32
next_bad_entry_ptr dw   0       ; first entry will be 0
num_bad_blocks  dw      0
bad_blocks      dw      MAXBADS dup(0)
bad_drives      dw      MAXBADS dup(-1)

;       now the byte variables

original_unit           db      -1
flags_and_unit          db      0
cache_unit              db      0


;       enter a BAMBI record in TRACKER, subtype as argument to macro
;         this macro is defined to be a null macro of TRACKER is set
;         false, so that every single LOG event needn't have IF TRACKER
;         conditionals on it.

log_it  macro   rectype
	if      tracker
	push    ax
	mov     al,rectype
	call    tracker_log
	pop     ax
	endif
	endm

	if      tracker

;       We may want to save some special BAMBI events in
;       the TRACKER log.  If this feature is enabled, we'll
;       call through a FAR variable into TRACKER.

	public  save_it_off     ; allow external initialization for
	public  save_it_seg     ;  TRACKER save entry point

save_it         label   dword
save_it_off     dw      offset far_ret
save_it_seg     dw      0       ; will be init'd to cs if tracker not present

far_ret:
	retf

code_bambi      =       6       ; this is our special TRACKER record type

event           struc           ; this is the TRACKER event structure
rectype         db      ?
level           db      ?
regax           dw      ?
regbx           dw      ?
regcx           dw      ?
regdx           dw      ?
reges           dw      ?
time            dd      ?       ; time stamp
event           ends

xbuf    event   <code_bambi,0>  ; this is our local event structure

;-----------------------------------------------------------------------
;
;       enter a bambi-type tracker log
;
;       entry: al == event subtype
;              ds == cs
;
;       exit:  no registers affected

tracker_log     proc    near
	assume  cs:zseg,ds:zseg,es:nothing

	push    si
	mov     si,offset xbuf
	mov     ds:[si].regax,ax
	call    save_it
	pop     si
	ret

tracker_log     endp

	endif

;-----------------------------------------------------------------------
;
;       call into the device driver using the user's original
;         request packet.
;
;       Entry: ds == cs
;
;       Trashed: es, bx, ax, si, far_call_addr
;                (plus anything affected by bad d.d.'s)

call_dd_ureqblk proc    near
	assume  cs:zseg,ds:zseg,es:nothing

	les     bx,user_reqblk          ;es:bx points to request packet

call_dd_ureqblk endp                    ; note:  fall through to call_dd

;-----------------------------------------------------------------------
;
;       call through to the device driver
;         plug in the mapped unit code to the request block
;
;       Entry: ds == cs, es:[bx] -> request block
;
;       Trashed: ax, si, far_call_addr
;                (plus anything affected by bad d.d.'s)

call_dd proc    near
	assume  cs:zseg,ds:zseg,es:nothing

	mov     al,cache_unit           ; get remapped cache unit
	mov     es:byte ptr [bx].requnit,al
	push    ds                      ; save caller's ds
	lds     si,dd_header            ; get actual device's header
	assume  ds:nothing
					; fall into call_dd_common
call_dd endp

;-----------------------------------------------------------------------
;
;       This is a special entry point used by dirtywrt for calling
;       out to the device driver.  When this routine is JMP'd to,
;       the original ds is already saved on the stack after the
;       actual return address.
;
;       Entry:  ds:[si] -> device driver header
;               es:[bx] -> request packet
;
;       Exit:   ds restored from stack
;
;       Trashed: ax, "far_call_address", and anything munched by
;                 bad device drivers.

call_dd_common  proc    near
	assume  cs:zseg,ds:nothing,es:nothing

	mov     devstatus,0
	mov     ax,word ptr [si].SDEVSTRAT ; get strategy entry
	mov     word ptr far_call_address[2],ds
	mov     word ptr far_call_address[0],ax

	push    es                      ; save packet for unit restore
	push    bx

	call    DWORD PTR[far_call_address]

	mov     ax,word ptr [si].SDEVINT ; get interrupt entry
	mov     word ptr far_call_address[0],ax

	call    DWORD PTR[far_call_address]

	pop     bx                      ; get packet
	pop     es

;       We have to make sure the UNIT code is returned to the
;         caller unchanged if we're calling through on DOS's
;         packet.  In the case of our own packet, original_unit
;         may not have any meaning, but in this case, we're sure
;         we're not going to care about what's left in that
;         field in the packet.
;
;       This is made more complicated by the fact that the SET_LOGICAL
;         device function returns a value in that field, so in this
;         particular case, we can't restore the original field.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -