⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wrtio.asm

📁 一个朋友写的操作系统源码
💻 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 + -