📄 floppy.inc
字号:
;===========================================================
;
; WarmOS
; by HotHeart(xujiwei)
;
; Floppy
; floppy operate
;
; History:
; 2005.08.30 file created
;
;===========================================================
;===========================================================
; data used
;===========================================================
SectorsPerTrack dw 18
NumHeads dw 2
DriveNumber db 0
FDT_POS_SEG equ 0x9C00
FAT_POS_SEG equ 0x9E00
DATAES dw 0
DATABX dw 0
CLUSTER dw 0
TRACK db 0
HEAD db 0
SECTOR db 0
;===========================================================
; file name expand
; in si filename end with 0
; di buffer
;===========================================================
align 4
EXT_COM db 'COM',0
FD_Expand:
push ax
push bx
push si
push di
push bp
mov bp,sp
call UpCase
call strlen
mov bx,ax
lea si,[si+bx-4]
cmp [si],byte '.'
jne .no_ext
mov [si],byte 0
inc si
mov di,EXT_COM
call strcmp
cmp ax,0
je .no_ext
jmp .exit_err
.no_ext:
mov si,[bp+4]
call strlen
mov bx,ax
cmp ax,8
jbe .copyfn
mov [si+6],word '~1'
mov [si+8],byte 0
.copyfn:
mov di,[bp+2]
call strcpy
mov [es:di+bx],byte ' '
mov [es:di+8],word 'CO'
mov [es:di+10],byte 'M'
mov [es:di+11],byte 0
.exit_ok:
pop bp
pop di
pop si
pop bx
pop ax
mov ax,0
ret
.exit_err:
pop bp
pop di
pop si
pop bx
pop ax
mov ax,-1
ret
;===========================================================
; get size of a file
; in si filename end with 0
;===========================================================
align 4
FD_GetFileSize:
;===========================================================
; write a file to floppy
; in si filename end with 0
;===========================================================
align 4
FD_WriteFile:
;===========================================================
; load a file from floppy
; in si filename end with 0
; es:bx load pos
;===========================================================
align 4
FD_LoadFile:
mov ax,es
mov [CS:DATAES],ax
mov [CS:DATABX],bx
push es
mov ax,FDT_POS_SEG
mov es,ax
push si
push bp
mov bp,sp
.loadFDT:
mov cx,5 ; if error try 5 times
.readfdt:
push cx
mov ax,0x020E ; read 14 sectors
mov bx,0 ; read FDT to 0x8000
mov cx,0x0002 ; track 0 sector 2
mov dh,0x01 ; head 1
mov dl,[DriveNumber] ; drive 0
int 0x13
pop cx
jnc .getfileinfo
dec cx
jnz .readfdt
pop bp
pop si
pop es
; mov ax,0
; mov bx,errmsg1
; int 0x40
mov ax,-1
ret
.getfileinfo:
mov si,[bp+2]
mov di,0
jmp .gl
.getnext:
add di,32
cmp di,0x1C00
jge .errgf
.gl:
push di
mov si,[bp+2]
mov cx,11
repe cmpsb
pop di
jne .getnext
test [es:di+0xB],byte 00010000b
jnz .getnext
cmp [es:di+0xB],byte 0xF
je .getnext
jmp .readfat
.errgf:
; mov ax,0
; mov bx,errmsg2
; int 0x40
pop bp
pop si
pop es
mov ax,-2
ret
.readfat:
add di,26
mov ax,[es:di]
mov [cs:CLUSTER],ax
mov ax,FAT_POS_SEG
mov es,ax
mov cx,5 ; if error try 5 times
.readfatl:
push cx
mov ax,0x0209 ; read 9 sectors
mov bx,0 ; read FAT to 0x8000
mov cx,0x0002 ; track 0 sector 2
mov dh,0x00 ; head 0
mov dl,[cs:DriveNumber] ; drive 0
int 0x13
pop cx
jnc .loadfile
dec cx
jnz .readfatl
; mov ax,0 ; error
; mov bx,errmsg1
; int 0x40
pop bp
pop si
pop es
mov ax,-1
ret
.loadfile:
mov ax,[CS:CLUSTER]
push es
call ReadSector
pop es
add word [CS:DATAES],0x20
call GetNextCluster
cmp ax,0x0FF0
jge .loadsuccess
cmp ax,0x0FF7
jge .loadfailure
mov [CS:CLUSTER],ax
mov ax,0x0E00+'.'
mov bx,0x0007
int 0x10
jmp .loadfile
.loadsuccess:
pop bp
pop si
pop es
mov ax,0
ret
.loadfailure:
; mov ax,0
; mov bx,errmsg3
; int 0x40
pop bp
pop si
pop es
mov ax,-3
ret
;===========================================================
; GetNextCluster
; get the next cluster
; in: AX = current cluster
;===========================================================
GetNextCluster:
mov dx,ax ; copy current cluster
shl dx,1 ; x2
add dx,ax ; copy current cluster
shr dx,1 ; /2
mov bx,0 ; location of FAT in memory
add bx,dx ; index into FAT
mov dx,WORD [es:bx] ; read two bytes from FAT
test ax,0x0001
jnz .odd_cluster
and dx,0000111111111111b ; take low twelve bits
jmp .done
.odd_cluster:
shr dx,0x0004 ; take high twelve bits
.done:
mov ax,dx
ret
;===========================================================
; readsector
; read sector to memory
; in: AX = cluster
;===========================================================
ReadSector:
push ax
call LBACHS
mov cx,5
.rsl:
push cx
mov ch,[CS:TRACK] ; track
mov cl,[CS:SECTOR] ; sector
mov dh,[CS:HEAD] ; head
mov dl,[CS:DriveNumber] ; dirve number
mov ax,[CS:DATAES]
mov es,ax ; seg address
mov bx,0 ; pos 0x0
mov ax,0x0201 ; read disk one secotr
int 0x13 ; read
pop cx
jnc .done
dec cx
jnz .rsl
mov si,errmsg3
call printf
jmp $
.done:
pop ax
ret
;===========================================================
; CHS
; convert LBA addressing scheme to CHS addressing scheme
; absolute sector = (logical sector / sectors per track) + 1
; absolute head = (logical sector / sectors per track) MOD number of heads
; absolute track = logical sector / (sectors per track * number of heads)
; in: AX = cluster
;===========================================================
LBACHS:
pusha
add ax,31
xor dx,dx ; prepare dx:ax for operation
div WORD [cs:SectorsPerTrack] ; calculate
inc dl ; adjust for sector 0
mov BYTE [cs:SECTOR],dl
xor dx,dx ; prepare dx:ax for operation
div WORD [CS:NumHeads] ; calculate
mov BYTE [CS:HEAD],dl
mov BYTE [CS:TRACK],al
popa
ret
errmsg1 db "软驱错误!",13,10,0
errmsg2 db "文件没有找到!",13,10,0
errmsg3 db "文件读取错误!",13,10,0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -