📄 patchvol.asm
字号:
ror ax,cl
noshift:
jmp anext2
pw2loop:
xor dx,dx
mov [zbindex],dx
mov si,[zbmapoff] ; bit search out in current word bit, load next
cld
lodsw
; inc si as its side effect
anext2:
; properly treat this word bit boundary
; when [zbindex] reaches 16, its time to
; to reset to 0 and switch to next word
; if after the first time this routine was
; called again, this indicates in previous
; there's a block bit found available just
; on the word boundary (15 bit of a word)
cmp dx,16
jae pw2loop
mov di,[bp-6]
mov bx,[bp-4]
cmp ss:[di],bx
jb notful
mov ax,77
push ax
call rtzbmap
notful:
inc si
inc si
mov [zbmapoff],si ; save next search word position
mov [zbindex],dx
inc word ptr ss:[di]
inc dx
ror ax,1
jnc anext1
jmp anext2
anext1:
; this algorithm is efficient oriented
; you are not expected to understand this!
mov cx,dx
xor ch,ch
; set 15 bit of ax, after it was rotate left
; it is just the position we want to use
or ax,8000h
rol ax,cl
; indicate that bit has been alloced
mov di,si ; si is points to next bit word now
dec di ; so just move back
dec di
cld
stosw ; updata the zone bit map
mov ax,si
sub ax,[zbmapoff] ; get the index, not offset of segment
mov bx,16
mul bx
mov di,[zbindex]
add ax,di
mov di,[bp-2]
add ax,di
push ax
; debug
push ax
mov ax,offset allocsuc
push ax
call printf
pop cx
pop cx
mov ax,offset newline
push ax
call printf
pop cx
pop ax
; ax now contains the physical zone to be alloced
mov sp,bp
pop bp
pop es
pop ds
ret
alloczone endp
;/============================================================================
;
; rtzbmap
;
;============================================================================/
rtzbmap proc near
push ds
push es
push bp
mov bp,sp
sub sp,2 ; receive the error code
mov ax,8[bp]
mov [bp-2],ax
mov si,offset orizbmap
mov di,offset zonespace
mov cx,1024
cld
repnz movsb
mov ax,3
push ax
call wrtzone ; restore original zone bit map
pop cx
mov ax,[bp-2] ; error code
push ax
call panic ; never come back
rtzbmap endp
;/============================================================================
;
; updat
;
;============================================================================/
updat proc near
push ds
push es
push bp
mov bp,sp
sub sp,4
; stack arranges like this
; [bp-2] : physical zone # return by alloczone
; [bp-4] : address of patch index
; [bp-6] : if != 1024, it must be last block
; depend on wether this is the last block
; it operates on, if so, wirte the updata
; block imageto the second half of boot
; block, if not, just modify the structure
; of block image
mov ax,8[bp]
mov [bp-2],ax ; physical zone #
mov ax,10[bp]
mov [bp-4],ax ; address of patch index
mov ax,12[bp]
mov [bp-6],ax ; number of byte in last block
mov di,[bp-4]
mov ax,ss:[di]
cmp word ptr [bp-6],0
jne unext1
dec ax
; invalidate the last block which contains nothing
unext1:
mov di,offset bootblock
add di,512
stosw ; set the number of patched block
mov di,[bp-4]
mov ax,ss:[di]
mov bx,2
mul bx
mov di,ax
add di,offset bootblock
add di,512
mov ax,[bp-2]
stosw ; get appropriate slot patched
mov di,[bp-4]
mov ax,ss:[di]
inc ax ; index only increase 1 not 2
mov ss:[di],ax ; write back
cmp word ptr [bp-6],1024
je unext2
mov si,offset bootblock
mov di,offset zonespace
mov cx,1024
cld
repnz movsb
mov ax,0
push ax
call wrtzone
pop cx
unext2:
mov sp,bp
pop bp
pop es
pop ds
ret
updat endp
;/============================================================================
;
; wrtofs
;
;============================================================================/
wrtofs proc near
push ds
push es
push bp
mov bp,sp
sub sp,6
; stack arranges like this
; [bp-2] : current index of patch blk
; [bp-4] : last blk byte number
; [bp-6] : physical block to be patched
mov ax,8[bp]
mov [bp-2],ax
mov ax,10[bp]
mov [bp-4],ax
mov ax,12[bp]
mov [bp-6],ax
; determine the last block and verify
; if it is empty, if so, don't write
cmp word ptr [bp-4],0
je wrtnext1
cmp word ptr [bp-4],1024
je wrtnext2
; reset the rest bytes to 0
mov di,offset zonespace
add di,[bp-4]
mov cx,1024
sub cx,[bp-4]
xor ax,ax
cld
repnz stosb
wrtnext2:
mov ax,[bp-6]
push ax
call wrtzone
pop cx
wrtnext1:
mov ax,[bp-4]
push ax
mov ax,[bp-2]
push ax
mov ax,[bp-6]
push ax
call updat
pop cx
pop cx
pop cx
mov sp,bp
pop bp
pop es
pop ds
ret
wrtofs endp
;/============================================================================
;
; wrtzone
;
;============================================================================/
wrtzone 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,3 ; select write function
int 13h
mov ah,1
int 13h ; get diskette status
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
wrtzone endp
cseg ends
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -