📄 block.asm
字号:
call get_lpt_id
jae unknown_lpt
les bx, rhptr
mov cx, es:[bx].io_req.io_requested
mov lpt_write_count, cx
check_count: mov ax, lpt_count
add ax, cx
jc flush
cmp ax, MAX_LPT_BUFF
ja flush
insert: cmp lpt_buffering, 0
je write_data
push cx
push ds ; Save driver DS
push es
mov di, lpt_count
add di, DVR:lpt_buff
push ds
lds si, es:[bx].io_req.io_data
pop es ; Driver DS to ES
rep movsb
pop es
pop ds
pop cx
add lpt_count, cx
xor cx, cx
mov ax, lpt_count
cmp ax, MAX_LPT_BUFF
jb flush_done
flush: call lpt_flush
test ax, STATUS_ERROR
jnz write_done
flush_done: jcxz write_ok
cmp cx, MAX_LPT_BUFF
jb insert
write_data: les di, rhptr
les si, es:[di].io_req.io_data
call lpt_write_block
jmp short write_done
write_error: les di, rhptr
mov es:[di].io_ans.io_transfered, 0
jmp short write_done
write_ok: les di, rhptr
mov cx, lpt_write_count
mov es:[di].io_ans.io_transfered, cx
mov ax, STATUS_DONE
jmp short write_done
unknown_lpt: mov ax, STATUS_ERROR OR ERR_UNK_UNIT
write_done: ret
lpt_write ENDP
lpt_flush PROC NEAR
push cx
push si
push es
xor ax, ax ; Preset for no error
mov cx, lpt_count
jcxz flush_done
mov si, DVR:lpt_buff
push ds
pop es
call lpt_write_block
test ax, STATUS_ERROR
jnz flush_done
mov lpt_count, 0
flush_done: test ax, STATUS_ERROR ; Set flags (NZ = error)
pop es
pop si
pop cx
ret
lpt_flush ENDP
get_lpt_id PROC NEAR
; Returns:
; AL = lpt_id
; B if lpt_id is valid (0 - 2)
; AE if lpt_id is invalid
mov bl, device_id
xor bh, bh
dec bx
mov al, actual_prn_map[bx]
cmp al, 3
ret
get_lpt_id ENDP
output_status LABEL NEAR
mov packet_buf.common_packet.packet_type, OUTPUT_STATUS_REQ
jmp short lpt_dev_common
flush_output LABEL NEAR
call lpt_flush
jnz dev_exit
mov packet_buf.common_packet.packet_type, FLUSH_OUTPUT_REQ
jmp short lpt_dev_common
lpt_dev_open LABEL NEAR
call get_lpt_id
jb @F
mov ax, STATUS_DONE
jmp short dev_exit
@@: call lpt_flush
jnz dev_exit
mov lpt_buffering, 1
mov packet_buf.common_packet.packet_type, AUX_DEV_OPEN_REQ
jmp short lpt_dev_common
lpt_dev_close PROC NEAR
call get_lpt_id
jb @F
mov ax, STATUS_DONE
jmp short dev_exit
@@: call lpt_flush
jnz dev_exit
mov lpt_buffering, 0
mov packet_buf.common_packet.packet_type, AUX_DEV_CLOSE_REQ
lpt_dev_common::call get_lpt_id
jae unknown_lpt
mov packet_buf.lpt_cmd_r.lpt_id, al
mov cx, TYPE lpt_cmd_r ; set up send pack parameters
mov si, DVR:packet_buf
push ds
pop es ; es:si, cx = packet
call send_pack
jc dev_error
mov di, DVR:packet_buf
mov cx, MAX_PACKET
call recv_pack
jc dev_error
mov ax, packet_buf.lpt_cmd_a.lca_status
jmp short dev_exit
unknown_lpt: mov ax, STATUS_ERROR OR ERR_UNK_UNIT
jmp short dev_exit
dev_error: mov ax, STATUS_ERROR OR ERR_NOT_READY
dev_exit:: ret
lpt_dev_close ENDP
removable_media PROC NEAR ; function 15 = Removable media
; NOTE: We always say the media is removeable without asking the server.
call map_unit
jc rm_exit
mov ax, STATUS_DONE ; Return busy bit == 0 for removable
rm_exit: ret
removable_media ENDP
device_open PROC NEAR ; function 13 = Device Open
device_close LABEL PROC ; function 14 = Device Close
call map_unit ; ax = mapped unit, bx = unmapped unit
jc do_exit
mov bx, ax ; See if slave driver supports ATT_OCRM
mov ax, STATUS_DONE ; Set return status in case slave
; doesn't support ATT_OCRM
shl bx, 1
test dd_attributes[bx], ATT_OCRM
jz do_exit
call check_unit ; Unit supports it, so go ahead and
jc do_exit ; send the packet
les di, rhptr
mov al, DEV_OPEN_REQ
cmp BYTE PTR es:[di].static_rhp.rhp_command, DEVICE_OPEN
je do_send
mov al, DEV_CLOSE_REQ
do_send: mov packet_buf.common_packet.packet_type, al
mov al, BYTE PTR mapped_unit
mov packet_buf.ocrm_r.ocr_unit, al
mov cx, TYPE ocrm_r
mov si, DVR:packet_buf
push ds
pop es ; es:si, cx = packet
call send_pack ; Send request
jc do_error
mov di, DVR:packet_buf
mov cx, MAX_PACKET
call recv_pack
jc do_error
mov ax, packet_buf.ocrm_a.oca_status
do_exit: ret
do_error: mov ax, STATUS_ERROR OR ERR_NOT_READY
ret
device_open ENDP
gen_data_save dd ?
generic_ioctl PROC NEAR ; function 19 = Generic IOCTL
call map_unit ; ax = mapped unit, bx = unmapped unit
jc gi_exit
mov bx, ax ; See if slave driver supports ATT_GEN_IOCTL
shl bx, 1
test dd_attributes[bx], ATT_GEN_IOCTL
jz gi_unsupported
les di, rhptr
cmp es:[di].gen_ioctl_req.gen_category, 8
jne gi_unsupported
mov al, es:[di].gen_ioctl_req.gen_function
mov packet_buf.gen_ioctl_r.gir_function, al ; Save function code
HEX al
les si, es:[di].gen_ioctl_req.gen_data ; Get data ptr
cmp al, 46H
je supported
cmp al, 66H
jne gi_unsupported
supported: mov WORD PTR gen_data_save, si
mov WORD PTR gen_data_save[2], es
mov packet_buf.common_packet.packet_type, GEN_IOCTL_REQ
mov al, BYTE PTR mapped_unit
mov packet_buf.gen_ioctl_r.gir_unit, al
mov packet_buf.gen_ioctl_r.gir_category, 8
mov cx, TYPE gen_ioctl_r
mov si, DVR:packet_buf
push ds
pop es
call send_pack
jc gi_error
les si, gen_data_save
cmp packet_buf.gen_ioctl_r.gir_function, 66H
je gi_recv
mov cx, TYPE media_id_buffer
call send_pack
jc gi_error
gi_recv: push ds
pop es ; receive response
mov di, DVR:packet_buf
mov cx, MAX_PACKET
call recv_pack
jc gi_error
test packet_buf.gen_ioctl_a.gia_status, STATUS_ERROR
jnz gi_done
les di, rhptr
cmp es:[di].gen_ioctl_req.gen_function, 46H
je gi_done
mov cx, TYPE media_id_buffer
les di, gen_data_save
call recv_pack
jc gi_error
gi_done: mov ax, packet_buf.gen_ioctl_a.gia_status
jmp short gi_exit
gi_unsupported: mov ax, STATUS_ERROR OR ERR_UNK_COMMAND
jmp short gi_exit
gi_error: mov ax, STATUS_ERROR OR ERR_NOT_READY
gi_exit: ret
generic_ioctl ENDP
lpt_unused PROC FAR
push es
push di
les di, cs:rhptr
mov WORD PTR es:[di].static_rhp.rhp_status, STATUS_DONE
pop di
pop es
pop ax
ret
lpt_unused ENDP
unused PROC NEAR
xor ax, ax
ret
unused ENDP
PAGE
init_char PROC NEAR
mov ax, init_size
mov WORD PTR es:[di].init_ans.init_end, ax
mov ax, header_seg
mov WORD PTR es:[di].init_ans.init_end + 2, ax
xor ax, ax
ret
init_char ENDP
init_block PROC NEAR
mov ax, init_size
mov WORD PTR es:[di].init_ans.init_end, ax
mov ax, header_seg
mov WORD PTR es:[di].init_ans.init_end + 2, ax
mov WORD PTR es:[di].init_ans.init_bpb, DVR:bpb_pnt_array
mov WORD PTR es:[di].init_ans.init_bpb + 2, ds ; BPB offset array
mov al, units
mov es:[di].init_ans.init_units, al
mov cs:header.device_header.name_num[0], al ; Number of units
xor ax, ax
ret
init_block ENDP
BLOCK ENDS
SUBTTL Resident variable length data
PAGE
VARLEN SEGMENT WORD PUBLIC 'CODE'
EVEN
bpb_array LABEL bios_parameter_block
bios_parameter_block MAX_DEVICES DUP (<200H, 1, 1, 2, 64, 128, 0, 1>)
; Allocation for BPB array
VARLEN ENDS
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -