📄 disk.asm
字号:
; File : $DISK.ASM$
;
; Description :
;
; Original Author :
;
; Last Edited By : $Author: RGROSS$
;
;-----------------------------------------------------------------------;
; Copyright Unpublished Work of Novell, Inc. All Rights Reserved.
;
; THIS WORK IS AN UNPUBLISHED WORK AND CONTAINS CONFIDENTIAL,
; PROPRIETARY AND TRADE SECRET INFORMATION OF NOVELL, INC.
; ACCESS TO THIS WORK IS RESTRICTED TO (I) NOVELL, INC. EMPLOYEES
; WHO HAVE A NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF
; THEIR ASSIGNMENTS AND (II) ENTITIES OTHER THAN NOVELL, INC. WHO
; HAVE ENTERED INTO APPROPRIATE LICENSE AGREEMENTS. NO PART OF THIS
; WORK MAY BE USED, PRACTICED, PERFORMED, COPIED, DISTRIBUTED,
; REVISED, MODIFIED, TRANSLATED, ABRIDGED, CONDENSED, EXPANDED,
; COLLECTED, COMPILED, LINKED, RECAST, TRANSFORMED OR ADAPTED
; WITHOUT THE PRIOR WRITTEN CONSENT OF NOVELL, INC. ANY USE OR
; EXPLOITATION OF THIS WORK WITHOUT AUTHORIZATION COULD SUBJECT
; THE PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.
;-----------------------------------------------------------------------;
;
; *** Current Edit History ***
; *** End of Current Edit History ***
;
; $Log: $
; DISK.ASM 1.1 93/11/18 17:20:12 RGROSS
;
; DISK.ASM 1.41 93/11/18 17:20:25 IJACK
;
; DISK.ASM 1.40 93/11/10 00:28:12 IJACK
; Format changes so you can format your hard disk
; DISK.ASM 1.39 93/11/08 21:47:25 IJACK
; Add hidden sectors to ioctl format etc of hard disks
; DISK.ASM 1.38 93/11/02 16:09:29 IJACK
; Always zero BPB_HIDDEN_SECTORS on floppies - problem with PCW free disk which
; has garbage in those fields.
; DISK.ASM 1.37 93/10/18 17:33:18 IJACK
; format c: fix
; DISK.ASM 1.36 93/10/11 18:37:24 IJACK
; media-change checks serial-numbers for 3.5" disks
; DISK.ASM 1.35 93/10/06 22:09:16 IJACK
; vec_save extrn replaced by orgInt13 extrn
; DISK.ASM 1.34 93/09/03 20:13:32 IJACK
; Fix bug in disk formatting
; DISK.ASM 1.33 93/09/01 17:40:31 IJACK
; update UDSC_TIMER after media check forced by drive change
; (DBASE IV slow installation problem)
; DISK.ASM 1.32 93/08/12 15:33:07 IJACK
; Handle DMA error from multi-track read (ancient PC-XT hard disk)
; DISK.ASM 1.31 93/08/03 15:29:01 IJACK
; use serial numbers for media change detection
; DISK.ASM 1.30 93/08/02 18:44:50 IJACK
; don't trust the changeline if switching drives
; DISK.ASM 1.29 93/08/02 18:38:19 IJACK
;
; DISK.ASM 1.28 93/08/02 14:47:38 IJACK
;
; DISK.ASM 1.27 93/07/29 21:00:24 IJACK
; get rid of genpb_ptr and genpb_minor
; DISK.ASM 1.26 93/07/26 21:18:25 IJACK
; Correctly return UDSC_ root from Int 2F/0803
; DISK.ASM 1.25 93/07/26 18:07:21 IJACK
; Switch ms-windows to full screen when prompting for disk
; DISK.ASM 1.24 93/07/23 17:34:27 IJACK
; fix floppy/driver.sys support
; DISK.ASM 1.23 93/07/22 20:37:42 IJACK
;
; DISK.ASM 1.22 93/07/22 19:43:46 IJACK
; switch over to REQUEST.EQU
; change floppy drive order, add get/set serial number
; DISK.ASM 1.21 93/07/19 18:57:21 IJACK
; Add header
;
; ENDLOG
include BIOSGRPS.EQU
include DRMACROS.EQU ; standard DR macros
include IBMROS.EQU ; ROM BIOS equates
include REQUEST.EQU ; request header equates
include BPB.EQU ; BIOS parameter block equates
include UDSC.EQU ; unit descriptor equates
include DRIVER.EQU ; device driver equates
int_____DISK_INT macro
call Int13
endm
FASTSETTLE equ FALSE ; disable "head settle == 0 ms"
RETRY_MAX equ 3 ; do 3 retries if we get an error
MAX_SPT equ 40 ; maximum sectors per track
SECSIZE equ 512
IDOFF equ SECSIZE-2 ; last word in boot sector is ID
PTOFF equ IDOFF-40h ; 4*16 bytes for partition def's
DOS20_ID equ 1 ; DOS 2.0 partition, < 4086 clusters
DOS30_ID equ 4 ; DOS 3.0 partition, < 65536 sectors
DOSEX_ID equ 5 ; DOS 3.3 extended partition
DOS331_ID equ 6 ; COMPAQ DOS 3.31 partition > 32 Mb
; Now for the secure partition types
SEC_ID equ 0C0h ; New DR secure partition types
SEC_ID2 equ 0D0h ; Old DR secure partition types
page
CGROUP group CODE, RCODE, ICODE, RESBIOS, IDATA
CG equ offset CGROUP
Assume CS:CGROUP, DS:CGROUP, ES:Nothing, SS:Nothing
IVECT segment at 0000h
org 0013h*4
i13off dw ?
i13seg dw ?
org 001Eh*4
i1eptr dd ?
org 002Fh*4
i2Foff dw ?
i2Fseg dw ?
org 0472h
reset_flag dw ?
org 0504h
dual_byte db ? ; multiple drive byte at 50:4
IVECT ends
ROS segment at 0F000h
org 0FFF0h
reset proc far
reset endp
ROS ends
CODE segment 'CODE'
extrn endbios:word ; for device driver INIT function
extrn read_system_ticks:near ; get system tick count in CX/DX
extrn Int13Trap:near
extrn Int2FTrap:near
extrn orgInt13:dword
extrn i13pointer:dword
extrn i13off_save:word
extrn i13seg_save:word
extrn NumDiskUnits:byte
extrn DeblockSeg:word
extrn local_parms:byte
extrn parms_spt:byte
extrn parms_gpl:byte
extrn local_buffer:byte
extrn local_pt:word
extrn local_id:word
extrn layout_table:word
extrn bpbs:word
extrn bpb160:byte
extrn bpb360:byte
extrn bpb720:byte
extrn NBPBS:abs
extrn bpbtbl:word
extrn req_off:word
extrn req_seg:word
udsc_root label dword
dw -1,-1
orig_int1e_off dw 522h
orig_int1e_seg dw 0
new_int1e_off dw 522h
new_int1e_seg dw 0
Public i13_AX
i13_AX label word
i13_size db ? ; number of sectors to xfer
i13_op db ? ; Int13 Operation
i13_dma_ptr label dword
i13_dma_off dw ?
i13_dma_seg dw ?
activeRosUnit db ? ; currently active ROS unit
include biosmsgs.def ; Include TFT Header File
ifdef JAPAN
extrn disk_msgA_jpn :byte
extrn disk_msgB_jpn :byte
endif
;disk_msgA db 13,10,'Insert disk for drive '
;disk_msgB db ': any press any key when ready ', 0
page
Assume DS:nothing, SS:nothing, ES:nothing
CODE ends
RCODE segment 'RCODE'
extrn DataSegment:word
even
Int13 proc near
clc
push bp
int DISK_INT
pop bp
ret
Int13 endp
ros_errors db 03h, 80h, 08h, 10h, 40h, 04h, 06h, 00h
dos_errors db 00h, 02h, 04h, 04h, 06h, 08h, 0Fh, 0Ch
NUMROSERR equ dos_errors - ros_errors
; The following code is required in order to cope with
; application programs invoking Int 13h directly. It
; handles applications that format floppies or access the
; disk via Int 13h after a floppy disk change.
Assume CS:CGROUP, DS:Nothing, ES:Nothing, SS:Nothing
Public Int13Unsure
;----------
Int13Unsure proc far
;----------
sti
cld
push ds
mov ds,cs:DataSegment
Assume DS:CGROUP
call i13_unsure ; no longer sure of this drive
pop ds
ret
Int13Unsure endp
Public Int13Deblock
;-----------
Int13Deblock proc far
;-----------
; handle user programs formatting the disk
sti
cld
push ds
mov ds,cs:DataSegment
Assume DS:CGROUP
pushx <es, bx, cx, si, di> ; save work registers
mov i13_dma_off,bx
mov i13_dma_seg,es
i13_deblock10:
pushx <cx, dx>
mov cl,4
mov ax,i13_dma_seg ; get transfer address
shl ax,cl ; get A4..A15 from segment
add ax,i13_dma_off ; combine with A0..A15 from offset
not ax ; AX = # of bytes left in 64K bank
xor dx,dx
mov cx,SECSIZE
div cx ; convert this to physical sectors
mov dl,i13_size ; see if we can xfer amount wanted
cmp al,dl ; capable of more than requested?
jb i13_deblock20 ; skip if we can do it all
xchg ax,dx ; we can do them all
i13_deblock20:
les bx,i13_dma_ptr ; do the xfer to here
popx <dx, cx>
mov ah,i13_op ; get read/write/verify operation
test al,al ; if zero length possible
jz i13_deblock30 ; then deblock
mov di,es ; get transfer address
cmp di,DeblockSeg ; is this in high memory ?
jb i13_deblock50 ; then force through deblock buffer
i13_deblock30:
push ds ; if deblocking then we'd better
pop es ; point at local buffer we
mov bx,CG:local_buffer ; will be using for actual I/O
cmp i13_op,ROS_WRITE
jne i13_deblock40 ; skip data copy if not writing to disk
push ds
push cx
mov di,bx ; ES:DI -> local buffer
lds si,i13_dma_ptr ; DS:SI -> data to write
mov cx,SECSIZE/2
rep movsw ; copy to deblocking buffer
pop cx
pop ds
i13_deblock40:
mov al,1 ; do a single sector via buffer
clc
pushf ; fake an Int
call i13pointer ; to the track handler
jc i13_deblock90 ; stop on error
mov al,1 ; restore AL for buggy bios's
cmp i13_op,ROS_READ ; if we are reading then we'll
jne i13_deblock60 ; have to copy data out of
push cx ; the deblocking buffer
les di,i13_dma_ptr ; ES:DI -> dest for data
mov si,CG:local_buffer ; point at local buffer which
mov cx,SECSIZE/2 ; contains actual data
rep movsw ; copy from deblocking buffer
pop cx
jmps i13_deblock60
i13_deblock50:
push ax ; save # sectors in xfer
clc
pushf ; fake an Int
call i13pointer ; do the operation
pop bx
mov al,bl ; restore AL for buggy bios's
jc i13_deblock90 ; stop on error
i13_deblock60: ; we succeeded in doing AL sectors
sub i13_size,al ; forget about those we have done
jbe i13_deblock90 ; and do more if there are any
push ax
mov ah,SECSIZE/16
mul ah ; AX = paras to inc DMA address
add i13_dma_seg,ax ; up DMA address by this amount
pop ax
call i13_point_unit ; ES:DI -> UDSC_
jc i13_deblock90 ; exit if we can't find it
mov bx,cx ; get sector/cylinder in BX
and bx,0003Fh ; BX = sector
and cx,0FFC0h ; CX = mandled cylinder bits
add bl,al ; work out new sector
i13_deblock70:
mov ax,es:UDSC_BPB+BPB_SPT[di]
cmp bx,ax ; still on the same track ?
jbe i13_deblock80 ; easy if no overflow onto next track
sub bx,ax ; subtract a tracks worth
inc dh ; and move onto next head
mov al,dh ; isolate head from cylinder
and ax,003Fh ; bits 10/11
cmp ax,es:UDSC_BPB+BPB_HEADS[di]
jb i13_deblock70 ; onto next track yet ?
and dh,0C0h ; back to head zero
add ch,1 ; onto next track (bits 0-7)
jnc i13_deblock70 ; overflow to bits 8-9 ?
add cl,040h ; yes, "inc" bits 8/9 of cylinder
jnc i13_deblock70 ; overflow to bits 10-11 ?
add dh,040h ; yes, "inc" bits 10/11 of cylinder
jmps i13_deblock70
i13_deblock80:
or cx,bx ; recombine sector/cylinder
jmp i13_deblock10 ; and do some more
i13_deblock90:
popx <di, si, cx, bx, es> ; restore work registers
pop ds ; recover user DS
ret 2 ; return to user with result
i13_point_unit proc near
;-------------
; On Entry:
; DL = ROS unit
; On Exit:
; ES:DI -> UDSC_ for that unit
; All other regs preserved
;
les di,udsc_root ; ES:DI -> 1st es:UDSC_
i13_point_unit10:
cmp dl,es:UDSC_RUNIT[di] ; find the physical unit
je i13_point_unit20
les di,es:UDSC_NEXT[di]
cmp di,0FFFFh ; else try the next es:UDSC_
jne i13_point_unit10
mov ah,09h ; return DMA error to caller as we
stc ; don't know about this unit
i13_point_unit20:
ret
i13_point_unit endp
Int13Deblock endp
i13_unsure proc near
;---------
; mark physical drive DL as unsure
;
pushx <ds, si>
lds si,udsc_root
i13_unsure10:
cmp dl,ds:UDSC_RUNIT[si] ; does it match ROS drive?
jne i13_unsure20 ; skip if not
or ds:UDSC_FLAGS[si],UDF_UNSURE
i13_unsure20: ; next drive
lds si,ds:UDSC_NEXT[si]
cmp si,0FFFFh
jne i13_unsure10
popx <si, ds> ; restore registers
ret
i13_unsure endp
Assume DS:Nothing, SS:Nothing, ES:Nothing
Public Int2FHandler
Int2FHandler proc far
;-----------
; On Entry we have offset/seg of next in chain on the stack
; (ie. we can pass on by a RETF)
;
cmp ah,8 ; DRIVER.SYS support
je i2F_driver
cmp ah,13h ; int13 intercept
jne i2F_iret
;
; Int 13 interception support
; ---------------------------
;
; On Entry:
; DS:DX -> New Int 13 vector
; ES:BX -> Int 13 vector restored by Int 19
;
; On Exit:
; DS:DX -> Old Int 13 vector
; ES:BX -> Old Int 13 vector restored by Int 19
;
i2F_i13_intercept:
mov ax,ds
mov ds,cs:DataSegment
Assume DS:CGROUP
xchg dx,ds:i13off_save
xchg ax,ds:i13seg_save
push ax
xchg bx,ds:word ptr orgInt13
mov ax,es
xchg ax,ds:word ptr orgInt13+2
mov es,ax
pop ds
Assume DS:Nothing
i2F_iret:
iret
;
; DRIVER.SYS support
; -------------------
;
; On Entry:
; AX=0800, installation check
; AX=0801, add new block device at DS:SI
; AX=0802, execute driver request at ES:BX
; AX=0803, return address of first es:UDSC_
;
i2F_driver:
cmp al,1
jb i2F_driver_check
je i2F_driver_add
cmp al,3
jb i2F_driver_req
je i2F_driver_point
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -