summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2013-03-17 23:22:52 (GMT)
committerH. Peter Anvin <hpa@zytor.com>2013-03-17 23:22:52 (GMT)
commit7975d3894741ae6f7f0c81b3ef11be1b203ff8da (patch)
tree642886e70dc08208e2eca6d0d5c267cf74c93a3c
parent15ab0fe771cc4a65eef4a36c81aa76d4955094b6 (diff)
downloadvirtio9p-7975d3894741ae6f7f0c81b3ef11be1b203ff8da.zip
virtio9p-7975d3894741ae6f7f0c81b3ef11be1b203ff8da.tar.gz
virtio9p-7975d3894741ae6f7f0c81b3ef11be1b203ff8da.tar.bz2
virtio9p-7975d3894741ae6f7f0c81b3ef11be1b203ff8da.tar.xz
Add freespace function, and trivial error returns for findfirst/next
Add the freespace function. However, there are at least two problems here: 1. It is unclear if > 2 GiB can be accurately handled by DOS. If not, this function can be written much simpler. 2. For some reason, statfs doesn't seem to work at all, returning Rerror (not Rlerror even...)
-rw-r--r--fxn.asm104
1 files changed, 101 insertions, 3 deletions
diff --git a/fxn.asm b/fxn.asm
index b518ea2..af04168 100644
--- a/fxn.asm
+++ b/fxn.asm
@@ -80,8 +80,104 @@ END(fxn_delete)
* ------------------------------------------------------------------------- */
GPROC(fxn_diskspace)
- stc
+ movw msgbuf7,%di
+ movl $FID_ROOT,%eax
+ stosl
+ movb $P9_TSTATFS,%al
+ call simple_message
+ jc 12f
+
+ /*
+ * In the response:
+ * dword @ 4(%di) = block size
+ * qword @ 8(%di) = total blocks
+ * qword @ 24(%di) = free blocks for non-superuser
+ */
+ movl 12(%di),%eax
+ mull 4(%di)
+ andl %edx,%edx
+ jne 10f /* > 2^64 bytes! */
+ movl %eax,%ecx
+ movl 8(%di),%eax
+ mull 4(%di)
+ addl %ecx,%edx
+ jc 10f
+
+ /*
+ * %edx:%eax now contains a byte count; we can represent it in
+ * a meaningful way iff it is < 2^38...
+ */
+ bsrl %edx,%ecx
+ jnz 2f
+ bsrl %eax,%ecx
+ jmp 3f
+2:
+ addb $32,%cl
+3:
+ cmpb $38,%cl
+ jae 10f
+ subb $16,%cl
+ shrdl %cl,%edx,%eax
+
+4:
+ movw %ax,F_BX /* Total clusters */
+
+ movl 28(%di),%eax
+ mull 4(%di)
+ andl %edx,%edx
+ jne 11f
+ movl %eax,%ecx
+ movl 24(%di),%eax
+ mull 4(%di)
+ addl %ecx,%edx
+ jc 11f
+
+ shrdl %cl,%edx,%eax
+ shrl %cl,%edx
+
+ andl %edx,%edx
+ jnz 11f
+ cmpl $0x10000,%eax
+ jae 11f
+
+5:
+ movw %ax,F_DX /* Available clusters */
+
+ /* Now, we need to turn %cl into a count */
+ movw $1,%ax
+ movb $15,%ch
+ pushw %ax
+ cmpb %ch,%cl
+ jbe 6f
+ subb %ch,%cl
+ shlw %cl,%ax
+ movb %ch,%cl
+6:
+ movb %al,F_AL /* Sectors/cluster */
+ popw %ax /* %ax <- 1 */
+ shlw %cl,%ax
+ movw %ax,F_CX /* Bytes/sector */
+
+7:
+ xorw %ax,%ax
retw
+
+10: /* Total size overflow */
+ movb $(37-16),%cl
+ movw $0xffff,%ax
+ jmp 4b
+
+11: /* Free space overflow */
+ movw $0xffff,%ax
+ jmp 5b
+
+12: /* Error, but DOS doesn't like this. Return zero space. */
+ xorw %ax,%ax
+ movw $512,F_CX
+ movb $64,F_AL
+ movw %ax,F_BX
+ movw %ax,F_DX
+ jmp 7b
END(fxn_diskspace)
/* ------------------------------------------------------------------------- *
@@ -89,7 +185,8 @@ END(fxn_diskspace)
* ------------------------------------------------------------------------- */
GPROC(fxn_findfirst)
- stc
+ movl $0x08030002,%eax /* File not found */
+ clc
retw
END(fxn_findfirst)
@@ -98,7 +195,8 @@ END(fxn_findfirst)
* ------------------------------------------------------------------------- */
GPROC(fxn_findnext)
- stc
+ movl $0x08060012,%eax /* No more files */
+ clc
retw
END(fxn_findnext)