📄 getinfo.asm
字号:
;/++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; This file deals with the low leavel diskette I/O performance
; it is almost the scale down verion of UNIX file system low layer
; implementation except it stips the support of multiprograming
; after all it only execute at real mode in DOS environment
;
; The entry points into this file are
; getinode: read the specified inode # into memory
; getsuper: read super block into memory
; getzone: read the specified zone # into memory
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++/
include comstruc.inc
sseg segment stack
db 128 dup (0)
sseg ends
overlap segment para common 'strucinfo'
; this is the only way to reference
; extern struct
inodeinfo minixinode <>
superinfo minixsuper <>
dent dirent <>
overlap ends
dseg segment para public 'global'
extrn inodeblk:byte
extrn superblk:byte
extrn zonespace:byte
dseg ends
cseg segment para public 'code'
assume cs:cseg,ds:dseg,es:dseg,ss:sseg
public getinode,getsuper,getzone
extrn panic:near
;/============================================================================
;
; getinode
;
;============================================================================/
getinode proc near
push ds
push es
push bp
mov bp,sp
mov ax,8[bp] ; get parameter
sub sp,4 ; used for ip1 & ip2
sub sp,6 ; used for store the C H S automatic variable
add ax,31 ; skip the 0# reserved inode
mov bx,16 ; 16 inodes per blk
xor dx,dx
div bx ; ax = blk#
push dx ; save remainer for latter usage
; we assume this algorithm only
; apply to floppy disk using Minix V2 fs
mov bx,2
mul bx ; The DOS handles the overflow
inc ax ; ajust base number from 0 to 1
; we must skip the inode & zone bitmap blocks
; we can obtain the appropriate information on super block
push ds
mov di,overlap
mov ds,di
assume ds:overlap
mov si,[superinfo.s_imap_blocks]
mov di,[superinfo.s_zmap_blocks]
add si,di
shl si,1 ; blk# * 2
add ax,si ; skip the inode & zone bitmap blocks
pop ds
assume ds:dseg ; restore original segment definition
mov bx,36 ; 2*18
xor dx,dx
div bx ; LBA # / (sector per track*total head)
mov [bp-6],ax ; save cylinder #
cmp dx,17 ; determinate head #
ja next
mov word ptr [bp-8],0 ; save head #
jmp combin
next:
mov word ptr [bp-8],1 ; save head #
combin:
mov ax,dx ; use the remain to evaluate the
xor dx,dx ; sector offset in each head
mov bx,18
div bx
mov [bp-10],dx ; sector #
;now everything is ready
;start floppy I/O
mov cx,5 ; we allow max 5 time I/O retry
push cx
retry:
mov bx,offset inodeblk ; specify destination
push ds
pop es ; let ds = es
mov dl,0 ; floppy A
mov dh,[bp-8] ; load head #
mov ch,[bp-6] ; load cylinder #
mov cl,[bp-10] ; sector #
mov al,2 ; 1 blk = 1024 byte
mov ah,2 ; select read function
int 13h
mov ah,1 ; get diskette status
int 13h
cmp ah,0
je next1 ; no error
dec word ptr [bp-14] ; decrease the retry time
cmp word ptr [bp-14],0 ; if we can try again
ja next2
mov al,ah ; get error code
xor ah,ah
add ax,6 ; avoid overlap DOS file I/O error code
push ax
call panic ; we can't move on
next2:
mov ah,0
int 13h ; do disk controller reset
mov ah,2
jmp retry ; we have the opportunity to retry
next1:
; there's no error, we will fill inode incore structure
mov ax,[bp-12] ; we use the remainer to locate the inode image
mov bx,64 ; each inode occupied 64 byte
xor dx,dx
mul bx ; ax = remainer * 64
; we assume the inode doesn't exceed 1024
; we don't process overflow
; leave it to DOS system
mov word ptr [bp-2],offset inodeblk
add [bp-2],ax
mov di,overlap ; change segment
mov es,di
assume es:overlap
mov word ptr [bp-4],offset inodeinfo
mov si,[bp-2]
mov di,[bp-4]
cld ; direction increment
mov cx,64
repnz movsb ; fill incore inode structure
push ds ; restore es segment
pop es
assume es:dseg
; we have finished our job just return
mov sp,bp ; obsolete the stack frame
pop bp
pop es
pop ds
ret
getinode endp
;/============================================================================
;
; getsuper
;
;============================================================================/
getsuper proc near
push ds
push es
push bp
mov bp,sp
; we just read 3#,4# sector into memory
; stip unnecessary information
mov cx,5
push cx
sretry:
mov bx,offset superblk
push ds
pop es
mov dl,0 ; floppy A
mov dh,0 ; head #
mov ch,0 ; cylinder #
mov cl,3 ; sector #
mov al,2 ; transfer two block one time
mov ah,2
int 13h
mov ah,1 ; get diskette status
int 13h
cmp ah,0
je snext1
dec word ptr [bp-2]
cmp word ptr [bp-2],0
ja snext2
mov al,ah ; get error code
xor ah,ah
add ax,6
push ax
call panic
snext2:
mov ah,0
int 13h ; reset disk controller
mov ah,2
jmp sretry ; try again
snext1:
; we will check the magic # present
; on Minix V2 file system
mov si,offset superblk
mov di,overlap ; change segment
mov es,di
assume es:overlap
mov di,offset superinfo
mov cx,24 ; size of super blk
cld
repnz movsb
mov ax,[superinfo.s_magic]
push ds ; restore es segment
pop es
assume es:dseg
cmp ax,2468h ; fs magic number
je snext3
mov ax,77h ; avoid overlap with DOS file
add ax,6 ; I/O error code
push ax ; this number is more or less arbitary
call panic
snext3:
mov sp,bp ; obsolet the stack frame
pop bp
pop es
pop ds
ret
getsuper endp
;/============================================================================
;
; getzone
;
;============================================================================/
getzone proc near
push ds
push es
push bp
mov bp,sp
mov ax,8[bp] ; get parameter
; we use only 16 bit addressing zones because
; it is big enough for such a small diskette
; but we still need to implement C H S translation
sub sp,6 ; alloc for C H S varible storage
mov bx,2
mul bx
inc ax ; covert base number from 0 to 1
mov bx,36 ; 2*18
xor dx,dx
div bx
mov [bp-2],ax ; cylinder #
cmp dx,17
ja znext
mov word ptr [bp-4],0 ; head 0#
jmp zcombin
znext:
mov word ptr [bp-4],1 ; head 1#
zcombin:
mov ax,dx
xor dx,dx
mov bx,18
div bx
mov [bp-6],dx ; sector #
; start floppy I/O
mov cx,5
push cx ; set retry times
zretry:
mov bx,offset zonespace
push ds
pop es
mov dl,0 ; floppy A
mov dh,[bp-4] ; load head #
mov ch,[bp-2] ; load cylinder #
mov cl,[bp-6] ; load sector #
mov al,2 ; 1 blk = 1024 byte
mov ah,2 ; select read function
int 13h
mov ah,1 ; get diskette status
int 13h
cmp ah,0
je znext1 ; no error
dec word ptr [bp-8] ; decrease the retry time
cmp word ptr [bp-8],0 ; if we can try again
ja znext2
mov al,ah ; get error code
xor ah,ah
add ax,6 ; avoid overlap DOS file I/O error code
push ax
call panic ; we can't move on
znext2:
mov ah,0
int 13h ; do disk controller reset
mov ah,2
jmp zretry ; we have the opportunity to retry
znext1:
mov sp,bp ; obsolet the stack frame
pop bp
pop es
pop ds
ret
getzone endp
cseg ends
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -