📄 block.asm
字号:
Registers need not be preserved.
@
media_check PROC NEAR ; function 1 = Media Check
call check_unit ; Check for errors & send sync
jc mc_exit
les di, rhptr ; es:di -> request header packet
mov packet_buf.common_packet.packet_type, MEDIA_CHECK_REQ
; Set up media check request packet
mov al, BYTE PTR mapped_unit
mov packet_buf.media_check_r.mcr_unit, al
mov al, es:[di].media_check_req.media_id
mov packet_buf.media_check_r.mcr_media_id, al
mov cx, TYPE media_check_r ; Set up send pack parameters
mov si, DVR:packet_buf
push ds
pop es ; es:si, cx = packet
call send_pack
jc mc_error
mov di, DVR:packet_buf
mov cx, MAX_PACKET
call recv_pack ; receive media check answer
jc mc_error
les di, rhptr ; Now setup return packet
mov al, packet_buf.media_check_a.mca_changed
mov si, DVR:packet_buf.media_check_a.mca_volume
call copy_label ; Copy label from server
mov bx, unmapped_unit
test invalid[bx], 0FFH
jz mc_store_mc ; See if invalid flag set
mov al, MEDIA_CHANGED ; If unit invalid, force media changed
mc_store_mc: mov es:[di].media_check_ans.media_changed, al
cmp al, MEDIA_CHANGED
jne mc_status
mov WORD PTR es:[di].media_check_ans.media_label, DVR:vol_ser_buff
mov WORD PTR es:[di].media_check_ans.media_label + 2, ds
mc_status: mov ax, packet_buf.media_check_a.mca_status
jmp short mc_exit
mc_error: mov ax, STATUS_ERROR OR ERR_NOT_READY
mc_exit: ret
media_check ENDP
build_bpb PROC NEAR ; function 2 = Build BIOS param block
call check_unit
jc bb_exit
les di, rhptr ; es:di -> request header packet
mov packet_buf.common_packet.packet_type, BUILD_BPB_REQ
mov al, BYTE PTR mapped_unit
mov packet_buf.build_bpb_r.bbr_unit, al
mov al, es:[di].build_bpb_req.media_id
mov packet_buf.build_bpb_r.bbr_media_id, al
mov cx, TYPE build_bpb_r ; set up send pack parameters
mov si, DVR:packet_buf
push ds
pop es ; es:si, cx = packet
call send_pack
jc bb_error
mov di, DVR:packet_buf
mov cx, MAX_PACKET ; es:di, cx -> recieve area
call recv_pack
jnc bb_ok
bb_error: mov ax, STATUS_ERROR OR ERR_NOT_READY
jmp short bb_exit
bb_ok: les di, rhptr ; Now setup return packet
mov bx, unmapped_unit
shl bx, 1 ; bx = unit * 2
mov bx, bpb_pnt_array[bx] ; bx = offset of units bpb
mov WORD PTR es:[di].build_bpb_ans.bpb_bpb, bx
mov WORD PTR es:[di].build_bpb_ans.bpb_bpb + 2, ds
test packet_buf.build_bpb_a.bba_status, STATUS_ERROR
jnz bb_status ; On error, skip copying BPB
push ds ; Get ready for block move
pop es ; es:di = dest. for BPB
mov di, bx
mov si, DVR:packet_buf.build_bpb_a.bba_bpb ; ds:si = bpb address in packet
mov cx, TYPE bios_parameter_block
rep movsb
mov bx, unmapped_unit
mov invalid[bx], 0 ; Clear invalid flag
; Now check the media for unusable types.
; bad media if 32-bit sectors and not DOS 3.31+,
; or devices sector size greater than masters maximum sector size
mov si, packet_buf.build_bpb_a.bba_bpb.bytes_per_sector
cmp si, max_secsize ; devices sector size is larger than
ja bb_bad_media ; maximum sector size -> bad media
mov bx, packet_buf.build_bpb_a.bba_bpb.total_sectors
or bx, bx ; Check for 32 bit sector addressing
jnz bb_status ; No - we're OK then
cmp dos_version, DOS331 ; Yes - require DOS 3.31 or later
jb bb_bad_media ; dos_version < MS-DOS 3.31 -> bad media
; Note: MS-DOS 3.31 can address 32-bit sectors, but the format of the
; RHP is different than DOS 4.0.
cmp slave_dos_version, DOS331
jae bb_status
bb_bad_media: mov bx, mapped_unit
shl bx, 1 ; si = offset of attribute word
or dd_attributes[bx], ATT_CHARACTER
; Flag device as having incompatable media
mov ax, STATUS_ERROR OR ERR_UNK_MEDIA
ret
bb_status: mov ax, packet_buf.build_bpb_a.bba_status
bb_exit: ret
build_bpb ENDP
check_data_len PROC NEAR
; Enter with:
; AX = # of sectors to read or write
; Return:
; DX:AX = # of bytes to read or write
; CX = copy of final AX value
; BX = bytes per sector from BPB
; NC - success if DX:CX != 00000H and DX:CX <= 10000H
; C - failure (bad count)
mov bx, unmapped_unit
shl bx, 1 ; bx = unit * 2
mov bx, bpb_pnt_array[bx] ; bx = offset of units bpb
mov bx, [bx].bios_parameter_block.bytes_per_sector ; bx = length of one sector
mul bx ; dx:ax = bytes to transfer
mov cx, ax
jcxz check_64k
or dx, dx
jnz bad_length
jmp short check_ok
check_64k: cmp dx, 1 ; If CX == 0, DX must equal 1
je check_ok
bad_length: stc
jmp short check_ret
check_ok: clc
check_ret: ret
check_data_len ENDP
read_count dw ?
read PROC NEAR ; function 4 = read (input)
call check_unit
jc rd_err_exit
les di, rhptr ; es:di -> request header packet
mov packet_buf.common_packet.packet_type, READ_REQ
mov al, BYTE PTR mapped_unit
mov packet_buf.io_r.ior_unit, al
mov al, es:[di].io_req.media_id
mov packet_buf.io_r.ior_media_id, al
mov ax, es:[di].io_req.io_requested
or ax, ax
jz rd_bad_length
mov packet_buf.io_r.ior_requested, ax
call convert_start_sector ; Convert sector numbers
mov cx, TYPE io_r ; set up send pack parameters
mov si, DVR:packet_buf
push ds
pop es ; es:si, cx = packet
call send_pack
jc rd_error
mov di, DVR:packet_buf
mov cx, MAX_PACKET
call recv_pack
jc rd_error
les di, rhptr
mov ax, packet_buf.io_a.ioa_status
cmp al, ERR_DISK_CHANGE
jne check_count
mov si, DVR:packet_buf.io_a.ioa_volume
call copy_label ; Get the label into a safe place
mov WORD PTR es:[di].io_ans.io_label, DVR:vol_ser_buff
mov WORD PTR es:[di].io_ans.io_label + 2, ds
check_count: mov ax, packet_buf.io_a.ioa_transfered
mov read_count, ax
or ax, ax ; see if anything transfered
jz rd_done
cmp ax, es:[di].io_req.io_requested
ja rd_bad_length
call check_data_len
jc rd_bad_length
les di, es:[di].io_req.io_data
call recv_pack
jc rd_error
rd_done: les di, rhptr
mov ax, read_count
mov es:[di].io_ans.io_transfered, ax
mov ax, packet_buf.io_a.ioa_status
ret
rd_bad_length: mov ax, STATUS_ERROR OR ERR_READ_FAULT
jmp short rd_err_exit
rd_error: mov ax, STATUS_ERROR OR ERR_NOT_READY
rd_err_exit: les di, rhptr ; Error in transfer
mov es:[di].io_ans.io_transfered, 0 ; set NO data transfered
rd_exit: ret
read ENDP
write PROC NEAR ; function 8 = Write (output)
write_verify LABEL PROC ; function 9 = Write with verify
mov bl, es:[di].static_rhp.rhp_unit
xor bh, bh ; See if device is write protected!
test drive_mapping[bx], 80H
jz not_wr_prot
mov ax, STATUS_ERROR OR ERR_WRITE_PROT
jmp wr_err_exit
not_wr_prot: call check_unit
jc wr_err_exit
les di, rhptr ; es:di -> request header packet
mov packet_buf.common_packet.packet_type, WRITE_REQ
cmp es:[di].static_rhp.rhp_command, WRITE
je @F
mov packet_buf.common_packet.packet_type, WRITE_VER_REQ
@@: mov al, BYTE PTR mapped_unit
mov packet_buf.io_r.ior_unit, al
mov al, es:[di].io_req.media_id
mov packet_buf.io_r.ior_media_id, al
mov ax, es:[di].io_req.io_requested
mov packet_buf.io_r.ior_requested, ax
call convert_start_sector
mov cx, TYPE io_r ; set up send pack parameters
mov si, DVR:packet_buf
push ds
pop es ; es:si, cx = packet
call send_pack
jc wr_error
les di, rhptr ; Now get ready to send data
mov ax, es:[di].io_req.io_requested
call check_data_len
jc wr_bad_length
les si, es:[di].io_req.io_data ; es:si, cx -> buffer
call send_pack ; Send the data
jc wr_error
push ds
pop es ; receive write answer
mov di, DVR:packet_buf
mov cx, MAX_PACKET
call recv_pack
jc wr_error
les di, rhptr
mov ax, packet_buf.io_a.ioa_status
cmp al, ERR_DISK_CHANGE
jne copy_count
mov si, DVR:packet_buf.io_a.ioa_volume
call copy_label ; Get the label into a safe place
mov WORD PTR es:[di].io_ans.io_label, DVR:vol_ser_buff
mov WORD PTR es:[di].io_ans.io_label + 2, ds
copy_count: mov bx, packet_buf.io_a.ioa_transfered
mov es:[di].io_ans.io_transfered, bx
;NOTE: AX still has status in it from before the copy_label call
ret
wr_bad_length: mov ax, STATUS_ERROR OR ERR_WRITE_FAULT
jmp short wr_err_exit
wr_error: mov ax, STATUS_ERROR OR ERR_NOT_READY
wr_err_exit: les di, rhptr ; Error in transmission
mov es:[di].io_ans.io_transfered, 0 ; Return no data transfered
wr_exit: ret
write ENDP
lpt_write_block PROC NEAR
; Enter with:
; EX:SI - points to block of characters to print
; CX - count
push bx
mov packet_buf.common_packet.packet_type, AUX_WRITE_REQ
mov bl, device_id
xor bh, bh
dec bx
mov al, actual_prn_map[bx]
cmp al, 3
jae unknown_lpt
mov packet_buf.lpt_o_r.lpt_id, al
mov packet_buf.lpt_o_r.print_count, cx
mov al, es:[si]
mov packet_buf.lpt_o_r.print_data, al
push cx
push si
push es
mov cx, TYPE lpt_o_r ; set up send pack parameters
mov si, DVR:packet_buf
push ds
pop es ; es:si, cx = packet
call send_pack
pop es
pop si
pop cx
jc wr_error
cmp packet_buf.lpt_o_r.print_count, 1
je get_reply
call send_pack ; Send the data
jc wr_error
get_reply: push ds
pop es ; receive write answer
mov di, DVR:packet_buf
mov cx, MAX_PACKET
call recv_pack
jc wr_error
les di, rhptr
mov bx, packet_buf.lpt_o_a.lpt_transferred
mov es:[di].io_ans.io_transfered, bx
mov ax, packet_buf.lpt_o_a.lpt_status
jmp short wr_exit
unknown_lpt: mov ax, STATUS_ERROR OR ERR_UNK_UNIT
jmp short wr_zero_trans
wr_error: mov ax, STATUS_ERROR OR ERR_NOT_READY
les di, rhptr ; Error in transmission
wr_zero_trans: mov es:[di].io_ans.io_transfered, 0 ; Return no data transfered
wr_exit: pop bx
ret
lpt_write_block ENDP
lpt_write PROC NEAR ; function 8 = Write (output)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -