📄 block.asm
字号:
;***
;* $Workfile: block.asm $
;* $Revision: 1.5 $
;* $Author: Dave Sewell $
;* $Date: 08 Aug 1989 16:44:52 $
;***
TITLE Permanent device driver code and data
PAGE 66, 132
INCLUDE drivers.mac
INCLUDE packets.mac
INCLUDE debug.mac
SUBTTL MS-DOS device driver definitions
PAGE
DOS30 EQU (3 SHL 8) + 30 ; MS-DOS 3.30 word format version number
DOS331 EQU (3 SHL 8) + 31 ; MS-DOS 3.31 word format version number
DOS40 EQU (4 SHL 8) + 00 ; MS-DOS 4.00 word format version number
DOS50 EQU (5 SHL 8) + 00 ; MS-DOS 5.00 word format version number
CORE SEGMENT WORD PUBLIC 'CODE'
EXTRN header:BYTE
EXTRN init_size:WORD
EXTRN strat_seg:WORD
EXTRN header_seg:WORD
EXTRN crctab:WORD
EXTRN dos_version:WORD
EXTRN dos_minor:BYTE
EXTRN dos_major:BYTE
EXTRN slave_dos_version:WORD
EXTRN slave_dos_minor:BYTE
EXTRN slave_dos_major:BYTE
EXTRN busy_semaphore:BYTE
EXTRN idle_semaphore:BYTE
EXTRN is_serial:BYTE
EXTRN win386_enh_mode:BYTE
EXTRN int2f_ok:BYTE
EXTRN send_pack:WORD
EXTRN recv_pack:WORD
EXTRN send_sync:WORD
EXTRN get_remote_info:WORD
EXTRN rhptr:DWORD
EXTRN packet_buf:BYTE
EXTRN default_units:BYTE
EXTRN first_unit:BYTE
EXTRN slave_units:BYTE
EXTRN initialized:BYTE
EXTRN port_address:WORD
EXTRN drive_mapping:BYTE
EXTRN dd_attributes:WORD
EXTRN invalid:BYTE
EXTRN device_id:BYTE
EXTRN actual_prn_map:BYTE
IFDEF DEBUG
EXTRN hex_out:WORD
EXTRN debug_msg:WORD
ENDIF
CORE ENDS
INIT SEGMENT WORD PUBLIC 'CODE'
EXTRN initialize:NEAR
EXTRN init_end:BYTE
INIT ENDS
BLOCK SEGMENT WORD PUBLIC 'CODE'
PUBLIC intr
PUBLIC block_start
PUBLIC intr_vector
PUBLIC block_init_end
PUBLIC max_devices
PUBLIC units
PUBLIC max_secsize
PUBLIC dispatch
PUBLIC bpb_array
PUBLIC bpb_pnt_array
PUBLIC unmapped_unit
PUBLIC lpt_dispatch
PUBLIC lpt_unused
ORG 0
block_start LABEL BYTE
MAX_LPT_BUFF EQU 64
save_sp dw ? ; save area for DOS stack
save_ss dw ?
; Device driver stack. If debugging, the device driver stack has words
; 1234H and 4321H on the top and bottom. These are used in debugging to
; check for stack overflows and under flows. They have no other purpose.
; The stack must be aligned on an even boundry.
EVEN
IFDEF DEBUG
dw 1234H ; Start of stack has a 1234H
ENDIF
db STACK_SIZE dup (0)
stack_end:
IFDEF DEBUG
dw 4321H ; End of stack always 4321H
ENDIF
lpt_buff db MAX_LPT_BUFF dup(0)
lpt_count dw 0
lpt_write_count dw 0
lpt_buffering db 0
intr PROC FAR ; device driver "Interrupt" routine
pushf ; Save flags
cli ; Disable until switch to larger stack
cld ; Set direction flag to UP
push ds ; Save all registers
push es
push bx
mov bx, cs ; make local data addressable
mov ds, bx
mov bl, 0FFH
xchg busy_semaphore, bl
or bl, bl
jnz intr_busy
push cx
push dx
push di
push si
push bp
mov device_id, al ; Save device ID passed in AL
mov save_sp, sp ; save old stack location
mov save_ss, ss
mov bx, cs
mov ss, bx ; Interrupts must be disabled--in case
mov sp, DVR:stack_end ; we're on an old 8088/8086!
sti ; ok to turn interrupts back on now
call initialize ; Call address get modified!!
intr_vector EQU $ - 2
mov busy_semaphore, 0
cli ; Just in case an old 8088/8086
mov ss, save_ss ; restore the old stack
mov sp, save_sp
pop bp
pop si
pop di
pop dx
pop cx
jmp short intr_restore
intr_busy: les bx, rhptr
mov es:[bx].static_rhp.rhp_status, STATUS_ERROR OR STATUS_DONE OR ERR_NOT_READY
intr_restore: pop bx
pop es
pop ds
popf
pop ax
ret ; return (far) to MS-DOS
intr ENDP
; units This is the number of logical devices supported by the driver.
;
units db 0 ; Number of devices
;==== Above here is the core portion of BLOCK which is always loaded =====
block_init_end LABEL BYTE
; max_devices This is the maximum number of devices ever allowed by the
; the driver, reguardless of the default units.
;
max_devices db MAX_DEVICES ; Maximum number of devices allowed
max_secsize dw ? ; Maximum sector size for driver
; bpb_pnt_array is the array of offsets to the BPBs addressed by the unit
; number in the RHP.
;
bpb_pnt_array LABEL WORD ; Array of offsets to the BPBs
CNT = 0
REPT MAX_DEVICES
dw DVR:bpb_array + CNT
CNT = CNT + TYPE bios_parameter_block
ENDM
mapped_unit dw ? ; Device number on slave system
unmapped_unit dw ? ; Unit on master system
vol_ser_buff db MAX_VOLUME DUP (0) ; Safe area for volume label
dd 0 ; and serial number
comm_start_time dw ?
handler_index dw ?
handler_value LABEL BYTE
db 'i' ; 0 = initialize driver
db 'm' ; 1 = media check on block device
db 'b' ; 2 = build BIOS parameter Block
db 'o' ; 3 = I/O control read
db 'r' ; 4 = read input from device
db 'n' ; 5 = non-destructive read
db '6' ; 6 = return current input status
db 'f' ; 7 = flush device input buffers
db 'w' ; 8 = write (output) to device
db 'v' ; 9 = write with verify
db 'O' ; 10 = return current output status
db 'B' ; 11 = flush output buffers
db 'W' ; 12 = I/O control write
db 'd' ; 13 = device open
db 'D' ; 14 = device close
db 'r' ; 15 = removable media
db 'u' ; 16 = output until busy
db '7' ; 17 = not used
db '8' ; 18 = not used
db 'g' ; 19 = generic IOCTL
db '0' ; 20 = not used
db '1' ; 21 = not used
db '2' ; 22 = not used
db 'l' ; 23 = get logical device
db 'L' ; 24 = set logical device
db '?' ; Invalid commands
;*** The table below corresponds to the dispatch table below it. A non-zero
;*** value in this table means the handler needs to communicate with the
;*** remote system. It also contains the size of the request header packet
;*** which should be saved and restored when retries are necessary. Doing
;*** this allows the lower level routines to modify the request header fields
;*** as necessary without worrying about messing up retries.
;*** IMPORTANT NOTE: The buffer below MUST be at least as large as the largest
;*** number in the table below it.
rhp_size LABEL BYTE
db 0 ; 0 = initialize driver
db 14 ; 1 = media check on block device
db 16 ; 2 = build BIOS parameter Block
db 0 ; 3 = I/O control read
db 28 ; 4 = read input from device
db 0 ; 5 = non-destructive read
db 0 ; 6 = return current input status
db 0 ; 7 = flush device input buffers
db 22 ; 8 = write (output) to device
db 22 ; 9 = write with verify
db 0 ; 10 = return current output status
db 0 ; 11 = flush output buffers
db 0 ; 12 = I/O control write
db 3 ; 13 = device open
db 3 ; 14 = device close
db 0 ; 15 = removable media
db 0 ; 16 = output until busy
db 0 ; 17 = not used
db 0 ; 18 = not used
db 23 ; 19 = generic IOCTL
db 0 ; 20 = not used
db 0 ; 21 = not used
db 0 ; 22 = not used
db 0 ; 23 = get logical device
db 0 ; 24 = set logical device
db 0 ; Invalid commands
EVEN
dispatch LABEL WORD ; Interrupt routine command-code
; dispatch table
dw DVR:init_block ; 0 = inititalize driver
dw DVR:media_check ; 1 = media check on block device
dw DVR:build_bpb ; 2 = build BIOS parameter Block
dw DVR:unused ; 3 = I/O control read
dw DVR:read ; 4 = read input from device
dw DVR:unused ; 5 = non-destructive read
dw DVR:unused ; 6 = return current input status
dw DVR:unused ; 7 = flush device input buffers
dw DVR:write ; 8 = write (output) to device
dw DVR:write_verify ; 9 = write with verify
dw DVR:unused ; 10 = return current output status
dw DVR:unused ; 11 = flush output buffers
dw DVR:unused ; 12 = I/O control write
dw DVR:device_open ; 13 = device open
dw DVR:device_close ; 14 = device close
dw DVR:removable_media ; 15 = removable media
dw DVR:unused ; 16 = output until busy
; commands below are for MS-DOS 3.2+
dw 0 ; 17 = not used
dw 0 ; 18 = not used
dw DVR:generic_ioctl ; 19 = generic IOCTL
dw 0 ; 20 = not used
dw 0 ; 21 = not used
dw 0 ; 22 = not used
dw 0 ; 23 = get logical device
dw 0 ; 24 = set logical device
lpt_dispatch LABEL WORD ; Interrupt routine command-code
; dispatch table
dw DVR:init_char ; 0 = inititalize driver
dw 0 ; 1 = media check on block device
dw 0 ; 2 = build BIOS parameter Block
dw 0 ; 3 = I/O control read
dw 0 ; 4 = read input from device
dw 0 ; 5 = non-destructive read
dw 0 ; 6 = return current input status
dw 0 ; 7 = flush device input buffers
dw DVR:lpt_write ; 8 = write (output) to device
dw DVR:lpt_write ; 9 = write with verify
dw DVR:output_status ; 10 = return current output status
dw DVR:flush_output ; 11 = flush output buffers
dw 0 ; 12 = I/O control write
dw DVR:lpt_dev_open ; 13 = device open
dw DVR:lpt_dev_close ; 14 = device close
dw 0 ; 15 = removable media
dw 0 ; 16 = output until busy
IFDEF DEBUG
print_sector PROC NEAR
push ax
push bx
push dx
mov bx, handler_index
mov al, handler_value[bx]
cmp al, 'r'
je print
cmp al, 'w'
jne print_done
print: xor dx, dx
mov ax, es:[di].io_req.io_start
cmp ax, 0FFFFH
jne print_high
mov ax, word ptr es:[di].io_req.io_huge_start
mov dx, word ptr es:[di].io_req.io_huge_start + 2
print_high: or dx, dx
jz print_low
HEX dh
HEX dl
print_low: or dh, dl
or dh, ah
jz @F
HEX ah
@@: HEX al
mov ax, es:[di].io_req.io_requested
cmp ax, 1
je print_done
DBG ','
or ah, ah
jz low_length
HEX ah
low_length: HEX al
print_done: pop dx
pop bx
pop ax
ret
print_sector ENDP
ENDIF
normal_intr PROC NEAR
PUBLIC normal_intr
les di, rhptr ; es:di = request header ptr
mov bl, es:[di].static_rhp.rhp_command
xor bh, bh ; bx = driver subfunction
cmp device_id, 0
jne lpt_driver
mov al, handler_value[bx]
DBG al
cmp bl, 24
ja invalid_cmd
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -