📄 wrtio.asm
字号:
;/++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; we use the side effect of getinode subroutine, it set the inodeinfo
; structure correctly, by using this information, we can load the Minix
; file from floppy diskette zone by zone and write to harddisk with the
; same file name in current directory, we don't have any dedicate buf
; we share the same buf of zonespace, don't worry about the confliect
; with the directory buf, we are in single user mode after all, process
; anything in series order, at this point, the directory buf is no use
; we call bmap subroutine frequently and use the value it return to do
; the floppy I/O, it will be well taken cared by getzone subroutine. by
; the way before doing this, we will check the inode attrib, attrib rather
; than ordinary file will be ejected.
;
; The entry points into this file are
; bmap: map the logic file blk # into LBA
; wrtfile: write file blk into DOS file with the same name
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++/
include const.inc
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'
public newline
extrn prom:byte
extrn dbuf:byte
extrn zonespace:byte
extrn dirp:word ; path charcter indicator
extrn parambuf:byte
extrn paramnr:byte
extrn fn:word ; files have been processed
extrn fulstr:byte
suc db 'total %d blocks in %s converted successful!','$'
fai db 'failed!','$'
notregu db '%s is not an regular file','$'
; debug
debugstr db '%d# logic zone want to be converted','$'
newline db 0dh,0ah,'$'
phyzone db 'convert to physical zone %d','$'
dseg ends
cseg segment para public 'code'
assume cs:cseg,ds:dseg,es:dseg,ss:sseg
public wrtfile,bmap
extrn printf:near
extrn getinode:near
extrn getzone:near
extrn panic:near
;/============================================================================
;
; wrtfile
;
;============================================================================/
wrtfile proc near
push ds
push es
push bp
mov bp,sp
sub sp,6
; the local variable arranged as followed
; [bp-2] : maximum file logic blk #
; [bp-4] : current logic blk #
; [bp-6] : current file handler
push ds
mov ax,overlap
mov ds,ax
assume ds:overlap
mov ax,[inodeinfo.i_mode]
pop ds
assume ds:dseg
and ax,I_TYPE
cmp ax,I_REGULAR
je wnext1
mov ax,offset fai
push ax
call printf
pop cx
mov ax,offset newline
push ax
call printf
pop cx
mov ax,offset fulstr
push ax
mov ax,offset notregu
push ax
call printf
pop cx
pop cx
mov ax,offset newline
push ax
call printf
pop cx
mov sp,bp
pop bp
pop es
pop ds
ret ; this convertion failed
wnext1:
; we will determine how many block this file taken!
push es
mov ax,overlap
mov es,ax
assume es:overlap
mov ax,es:[inodeinfo.i_size] ; low 16 bit
mov dx,es:[inodeinfo.i_size2] ; high 16 bit
pop es
assume es:dseg
; bmap will change es definition again to access the
; physical zone #
mov cl,10
shr ax,cl
and dx,3ffh
mov cl,6
shl dx,cl
or ax,dx
; this is not precise, if the file size is not the
; multiple of blk size, it is one blk bigger, so
; it is the responsibility of bmap to assume this
; block won't write to DOS file
mov [bp-2],ax ; max file logic blk #
mov word ptr [bp-4],0 ; first logic blk #
; create a DOS file with the same name of current
; Minix file been converted, first fetch the file
; name from either the dbuf in global data segment
; or dent int overlap segment contain the file
; name expected ( end with 0 not '$'), we use the
; dbuf for convenient referecing, for error handling
; this procedure will not easily ruin, if it is so,
; just panic, terminate all batch jobs
xor ax,ax
mov ah,3ch
mov dx,offset dbuf
mov cx,0 ; regular file please
int 21h
jnc wnext4
push ax
call panic
wnext4:
mov [bp-6],ax ; save file handler
wnext2:
mov ax,[bp-2] ; load up limit
cmp ax,[bp-4]
jb wnext3
mov ax,[bp-4]
inc word ptr [bp-4] ; stepping logic zone
push ax
call bmap
pop cx
push ax
call getzone
pop cx
mov bx,[bp-6]
mov cx,1024
mov dx,offset zonespace
mov ah,40h
int 21h ; write one zone to file
jnc wnext5
push ax
call panic ; never return
wnext5:
; we don't close file until all
; block has been writen
jmp wnext2
wnext3:
mov bx,[bp-6] ; close file
mov ah,3eh
int 21h
jnc wnext6
push ax
call panic
wnext6:
; time for return
; debug
mov ax,offset fulstr
push ax
mov ax,[bp-2]
inc ax
push ax
mov ax,offset suc
push ax
call printf
pop cx
pop cx
pop cx
mov ax,offset newline
push ax
call printf
pop cx
inc word ptr [fn]
mov sp,bp
pop bp
pop es
pop ds
ret
wrtfile endp
;/============================================================================
;
; bmap
;
;============================================================================/
bmap proc near
push ds
push es
push bp
mov bp,sp
sub sp,6
; the stack arranges as follows
; [bp-2] : logic zone # (base 0)
; [bp-4] : physical zone # (base 0)
; [bp-6] : last zone # (base 0)
mov ax,8[bp] ; logic zone #
mov [bp-2],ax
; we use two register combination
; we can also use the shift instruction
; to divide the 32 bit value
push es
mov ax,overlap
mov es,ax
assume es:overlap
mov ax,es:[inodeinfo.i_size] ; low 16 bit
mov dx,es:[inodeinfo.i_size2] ; high 16 bit
; isize / zonesize +1 = total logic zone #
mov cl,10
shr ax,cl
; the low 10 bit of dx must be shift
; into the high 10 bit of ax which
; was shift out
and dx,3ffh
; we can process maximum 64M file
; that's enough for not only ASCII file
mov cl,6
shl dx,cl
or ax,dx
mov [bp-6],ax ; save last zone #
; inc ax ; add tail
; ax now contain the total zone #
jmp bnext13
bnext1:
jmp bnext12
bnext13:
mov ax,[bp-2] ; used to determine the algorithm for address zone
inc ax ; adjust base # from 0 to 1
cmp ax,7 ; direct zone
ja bnext1
mov ax,[bp-2]
mov bx,4
mul bx ; i_zone is only the low 16 bit of Minix zone
mov si,offset inodeinfo.i_zone
add si,ax
mov ax,es:[si]
mov [bp-4],ax ; save return value
pop es
assume es:dseg
; debug
mov ax,8[bp]
push ax
mov ax,offset debugstr
push ax
call printf
pop cx
pop cx
mov ax,offset newline
push ax
call printf
pop cx
; debug
mov ax,[bp-4]
push ax
mov ax,offset phyzone
push ax
call printf
pop cx
pop cx
mov ax,offset newline
push ax
call printf
pop cx
mov ax,[bp-4] ; restore return value
; now ax contain the phsical LBA block #
mov sp,bp
pop bp
pop es
pop ds
ret
; we will implement large file algorithm, including
; indirect and double indirect fetch. it is so important
; for file larger than 7k
bnext12:
; the following code maps the logic file block one per
; time, so we share the zonespace and getzone subroutine
; for storing the indirect / double indirect block
jmp bnext23
bnext2:
jmp bnext22
bnext23:
cmp ax,263 ; 7 + 256 , ax base # is 1 not 0
jbe bnext2
mov si,offset inodeinfo.i_zone
add si,32 ; get double indirect zone #, not 8
mov ax,es:[si] ; get the zone
pop es
assume es:dseg
mov [bp-4],ax
push ax
call getzone
pop cx
mov ax,[bp-2]
sub ax,263 ; get offset
mov cl,8
shr ax,cl
xor dx,dx
mov bx,4
mul bx
mov si,ax
add si,offset zonespace
mov ax,[si]
mov [bp-4],ax ; save physical zone
push ax
call getzone
pop cx
; evaluate remain using masking
mov ax,[bp-2]
sub ax,263
and ax,0ffh ; ax is offset now
xor dx,dx
mov bx,4
mul bx
mov si,ax
add si,offset zonespace
mov ax,[si]
mov [bp-4],ax
; debug
mov ax,8[bp]
push ax
mov ax,offset debugstr
push ax
call printf
pop cx
pop cx
mov ax,offset newline
push ax
call printf
pop cx
; debug
mov ax,[bp-4]
push ax
mov ax,offset phyzone
push ax
call printf
pop cx
pop cx
mov ax,offset newline
push ax
call printf
pop cx
mov ax,[bp-4]
; now ax contain the physical
; zone # we want
mov sp,bp
pop bp
pop es
pop ds
ret
bnext22:
mov si,offset inodeinfo.i_zone
add si,28 ; be more careful, this is not 7 but 7*4
mov ax,es:[si]
pop es
assume es:dseg
push ax
call getzone
pop cx
mov ax,[bp-2]
sub ax,7
xor dx,dx
mov bx,4
mul bx
mov si,ax
add si,offset zonespace
mov ax,[si]
mov [bp-4],ax
; debug
mov ax,8[bp]
push ax
mov ax,offset debugstr
push ax
call printf
pop cx
pop cx
mov ax,offset newline
push ax
call printf
pop cx
; debug
mov ax,[bp-4]
push ax
mov ax,offset phyzone
push ax
call printf
pop cx
pop cx
mov ax,offset newline
push ax
call printf
pop cx
mov ax,[bp-4]
mov sp,bp
pop bp
pop es
pop ds
ret
bmap endp
cseg ends
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -