📄 block.asm
字号:
shl bx, 1
cmp dispatch[bx], 0
je invalid_cmd
shr bx, 1
call handler
jmp short handler_done
lpt_driver: cmp bl, 16
ja invalid_cmd
mov al, handler_value[bx]
DBG al
shl bx, 1
cmp lpt_dispatch[bx], 0
je invalid_cmd
shr bx, 1
call lpt_handler
jmp short handler_done
invalid_cmd: mov ax, STATUS_ERROR OR ERR_UNK_COMMAND
handler_done: or ax, STATUS_DONE ; set the done bit
mov idle_semaphore, MINIMUM_TICKS + 1
les di, rhptr
mov es:[di].static_rhp.rhp_status, ax
ret
normal_intr ENDP
handler PROC NEAR
mov handler_index, bx
cmp bl, 19 ; Generic IOCTL?
jne @F
;--- For generic IOCTL, bypass connection attempt unless function == 46H or 66H
les di, rhptr
mov al, es:[di].gen_ioctl_req.gen_function
cmp al, 46H
je @F
cmp al, 66H
jne call_handler
@@: cmp rhp_size[bx], 0
je call_handler
IFDEF DEBUG
call print_sector
ENDIF
cmp port_address, 0
jne call_handler
call send_sync ; Insure we are connected
jc not_ready
call get_remote_info ; Insure we are initialized.
jc not_ready
call_handler: mov bx, handler_index
shl bx, 1 ; form index to dispatch table
les di, rhptr
call dispatch[bx] ; Call the handler
cmp port_address, 0
jne handler_ret
mov bx, handler_index
cmp rhp_size[bx], 0
je handler_ret
not_ready: mov ax, STATUS_ERROR OR ERR_NOT_READY
;--- NOTE: If a write, or write-verify request fails due to a
;--- communications problem, we must insure the transfer count is zeroed.
mov bx, handler_index
cmp bl, 4
je rd_wr_fail
cmp bl, 8
je rd_wr_fail
cmp bl, 9
jne handler_ret
rd_wr_fail: les di, rhptr
mov es:[di].io_ans.io_transfered, 0
handler_ret: ret
handler ENDP
lpt_handler PROC NEAR
mov handler_index, bx
cmp rhp_size[bx], 0
je call_handler
cmp port_address, 0
jne call_handler
call send_sync ; Insure we are connected
jc not_ready
call get_remote_info ; Insure we are initialized.
jc not_ready
call_handler: mov bx, handler_index
shl bx, 1 ; form index to dispatch table
les di, rhptr
call lpt_dispatch[bx] ; Call the handler
cmp port_address, 0
jne handler_ret
mov bx, handler_index
cmp rhp_size[bx], 0
je handler_ret
not_ready: mov ax, STATUS_ERROR OR ERR_NOT_READY
mov bx, handler_index
;--- NOTE: Always return success for device_open and device_close to get
;--- around problem with CHCP command.
cmp bl, 13
je open_close_ok
cmp bl, 14
je open_close_ok
;--- NOTE: If a read, write, or write-verify request fails due to a
;--- communications problem, we must insure the transfer count is zeroed.
cmp bl, 8
je wr_fail
cmp bl, 9
jne handler_ret
wr_fail: les di, rhptr
mov es:[di].io_ans.io_transfered, 0
jmp short handler_ret
open_close_ok: xor ax, ax
handler_ret: ret
lpt_handler ENDP
; error_packet -- This routine sends an error packet to the remote system.
; Any communication errors are ignored.
;
; Inputs:
; ah error code
; mapped_unit Mapped unit number
; unmapped_unit Unit number passed in from DOS
;
; Outputs: none
;
; Destroys all registers
;
error_packet PROC NEAR
mov packet_buf.common_packet.packet_type, ERROR_REQ
; Set up media check request packet
mov packet_buf.error_r.err_code, ah
mov packet_buf.error_r.err_block_dvr, 0FFH
mov al, BYTE PTR unmapped_unit
mov packet_buf.error_r.err_unit, al
mov al, BYTE PTR mapped_unit
mov packet_buf.error_r.err_data, al
mov cx, TYPE error_r ; Set up send pack parameters
mov si, DVR:packet_buf
push ds
pop es ; es:si, cx = packet
call send_pack ; Ignore errors
ret
error_packet ENDP
; map_unit converts the masters unit number into the slaves device number
; checking for invalid units
;
; Inputs:
; es:di pointer to request header packet (with valid rhp_unit)
; units number of units on master system
; slave_units number of block devices on slave system
; drive_mapping translation table
;
; Outputs:
; CF Clear if unit is OK
; Set if invalid unit number
; If error, AX is also set to STATUS_ERROR OR ERR_UNK_UNIT
; mapped_unit The translated unit number (WORD)
; unmapped_unit The masters unit number (WORD)
; ax same as mapped_unit
; bx same as unmapped_unit
;
; Destroys registers: ax, bx
;
map_unit PROC NEAR
mov bl, es:[di].static_rhp.rhp_unit
cmp bl, units ; See if valid unit number
jae mu_unknown
xor bh, bh ; bx = master unit number
mov al, drive_mapping[bx]
and al, 7FH ; And off write protect
cmp al, slave_units ; See if valid slave unit number
jae mu_unknown
xor ah, ah
mov mapped_unit, ax ; keep track of unit numbers
mov unmapped_unit, bx
clc
ret
mu_unknown: stc
mov ax, STATUS_ERROR OR ERR_UNK_UNIT
ret
map_unit ENDP
; convert_start_sector Convert requested sector number into appropriate format
; for slave system.
; Inputs:
; es:di Pointer to current request header packet
; mapped_unit Unit number on the slave system
;
; Outputs:
; packet_buf.io_r.ior_start 16 bit start packet value
; packet_buf.io_r.ior_huge_start 32 bit start packet value
;
; Uses registers: ax, bx, cx, dx
;
convert_start_sector PROC NEAR
; Now get the 16 bit start sector into cx and the 32 bit start
; sector into dx,ax
cmp dos_version, DOS331
ja css_dos40
je css_dos331
mov cx, es:[di].io_req.io_start
mov ax, cx
xor dx, dx
jmp SHORT css_convert
css_dos331: mov cx, es:[di].io_req.io_start
mov ax, cx
mov dx, es:[di].io_req.io_start_high
jmp SHORT css_convert
css_dos40: mov ax, WORD PTR es:[di].io_req.io_huge_start
mov dx, WORD PTR es:[di].io_req.io_huge_start + 2
mov cx, ax
css_convert: ; Now find out if we need to stuff a FFFF in for the 16 bit
; sector number (DOS 4.0 HUGE media only)
cmp slave_dos_version, DOS331
jbe load_start
mov bx, mapped_unit ; Get device driver attributes
shl bx, 1
test dd_attributes[bx], ATT_HUGE
jz load_start
mov cx, 0FFFFH
; Now put the values into the ior packet
load_start: mov packet_buf.io_r.ior_start, cx
mov WORD PTR packet_buf.io_r.ior_huge_start, ax
mov WORD PTR packet_buf.io_r.ior_huge_start + 2, dx
ret
convert_start_sector ENDP
; check_unit -- Check for valid unit number
; Inputs:
; initialized Current initialization state
; rhptr Seg:Off of reequest header packet
;
; Outputs:
; CF Set if unit number ok
; Clear if invalid unit number
; AX If invalid unit or not initialized,
; STATUS_ERROR OR <appropriate critical error>
; If valid unit, ax = undefined
;
; packet_buf.master_id Set to master code if unit is ok (most routines
; need to set this anyway, so it saves a little code
; to set it here).
;
; initialized Set if communications are established
;
; If driver has not been initialized (communications established with remote)
; get_remote_info will be called. So all of the inputs of get_remote_info
; need to be set before calling this routine (they should have been
; calculated in initialize). Also, the outputs of get_remote_info will be
; set (overwriting the default information).
;
; Registers destroyed: ALL
;
; This function first checks to see if communications have been initialized.
;
; Once communcations have been initialized, the unit for the request is
; verified. First, it must be a valid unit number (x < units) and the
; CHARACTER bit must be clear in the device attribute word. build_bpb sets
; ATT_CHARACTER if the master system is going to have a problem reading this
; device (the device has HUGE sectors and the master's DOS version is before
; 4.00 or 16-bit fat table entries and the master's DOS version is before
; 3.00, or the devices sector size is to big).
;
;
check_unit PROC NEAR ; Check unit number
; Check the unit for which I/O is being requested.
les di, rhptr
call map_unit ; ax = mapped unit, bx = unmapped unit
jc cu_error
shl ax, 1 ; ax = offset in attribute list
mov bx, ax
mov bx, dd_attributes[bx] ; bx = device's driver attribute
test bx, ATT_CHARACTER
jz stuff_code
mov ah, ER_BAD_MEDIA
call error_packet ; Send a bad media packet
mov ax, STATUS_ERROR OR ERR_UNK_MEDIA
jmp SHORT cu_error
stuff_code: clc ; Set success flag
ret
cu_error: stc ; Set fail flag
ret
check_unit ENDP
; copy_label Copies a volume label from a packet to a safe place in the
; driver
; Inputs:
;
; Outputs: none
;
; Uses registers si, es:di, cx
;
copy_label PROC NEAR
mov cx, MAX_VOLUME + 4 ; add 4 for vol id number
push ds
pop es ; es:di = safe place to store label
mov di, DVR:vol_ser_buff
rep movsb ; copy the label
les di, rhptr
ret
copy_label ENDP
SUBTTL Subfunction handlers
PAGE
COMMENT @
Command code subfunctions follow:
Inputs: es:di - Points to the request header packet
Outputs: ax - 0 if function completed succesfully
- STATUS_ERROR OR (error code) if error condition
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -