summaryrefslogtreecommitdiffstats
path: root/int2f.asm
diff options
context:
space:
mode:
Diffstat (limited to 'int2f.asm')
-rw-r--r--int2f.asm191
1 files changed, 191 insertions, 0 deletions
diff --git a/int2f.asm b/int2f.asm
new file mode 100644
index 0000000..2f41e0c
--- /dev/null
+++ b/int2f.asm
@@ -0,0 +1,191 @@
+/* -*- asm -*- ----------------------------------------------------------- *
+ *
+ * Copyright 2013 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include "v9fs.h"
+
+ .code16
+
+/*
+ * Only intercept INT 2Fh for AH=11h and AL <= this value
+ */
+#define MAX_FUNCTION 0x2E
+
+ .section ".rtext","ax"
+ .globl int2f
+ .globl int2f_chain
+int2f:
+ cmpb $0x11,%ah
+ je int2f_11
+not_us:
+ .byte 0xea /* ljmpw */
+int2f_chain:
+ .long 0
+ .size int2f, .-int2f
+ .type int2f,@function
+
+int2f_11: /* it is a redirector call */
+ cmpb $MAX_FUNCTION,%ah
+ ja not_us
+ btsw $0,%cs:stack_lock
+ jc not_us
+
+ pushal
+ pushw %ds
+ pushw %es
+ pushw %fs
+ pushw %gs
+
+ movw %cs,%cx
+ movw %cx,%ds
+ movw %ss,prev_stack+2
+ movw %sp,prev_stack
+ movw %cx,%ss
+ movw int2f_sp,%sp
+
+ /* Now we are on our own stack. Get down to doing real work. */
+
+ cbw /* %ax <- %al */
+ movw %ax,%bx /* Function number */
+ shlw $2,%bx
+
+ lgsw prev_stack,%bp /* Point %gs:%bp to the invocation frame */
+
+ /*
+ * First call: is this for us? Clear CF if we want to claim it.
+ * %al/%ax still contains the function number on entry.
+ *
+ * This call must preserve %bx, %bp, %ds, %es, and %gs.
+ */
+ callw *dispatch_table(%bx)
+ jc quit
+
+ /*
+ * Second call: actually do the work. Return CF if we should
+ * be chained. On entry %eax should return the error code:
+ * bits [31:24] - error action
+ * bits [23:16] - error class
+ * bits [15: 0] - normal error code
+ *
+ * For no error, return %ax = 0, upper bits are forced to zero.
+ *
+ * This call must preserve %bp, %ds, and %gs.
+ */
+ callw *(dispatch_table+2)(%bx)
+ jc quit
+
+ movb $3,%cl /* Error locus = network */
+ andw %ax,%ax /* If this is zero, no error */
+ setnz F_FLAGS /* Return with CF=1 only on error */
+ jnz 1f
+ xorw %cx,%cx /* No error locus */
+ xorl %eax,%eax /* No extended error */
+1:
+ lesw dos_sda,%bx
+ movb %cl,%es:3(%bx) /* Error locus */
+ movl %eax,%es:4(%bx) /* Error action:class:code */
+
+quit:
+ lssw prev_stack,%sp
+ movb $0,stack_lock
+
+ popw %gs
+ popw %fs
+ popw %es
+ popw %ds
+ popal
+ jc not_us
+ iret
+ .size int2f_11, .-int2f_11
+ .type int2f_11,@function
+
+ lrbword stack_lock /* Local stack is busy */
+
+ grblong prev_stack /* Invocation frame/previous stack (far ptr) */
+
+ .section ".rrodata","a"
+ .balign 4
+dispatch_table:
+ .word acc_always, fxn_inquiry /* 0x00 */
+ .word acc_cds, fxn_rmdir
+ .word acc_never, fxn_unknown
+ .word acc_cds, fxn_mkdir
+
+ .word acc_never, fxn_unknown /* 0x04 */
+ .word acc_cds, fxn_chdir
+ .word acc_file, fxn_closefile
+ .word acc_file, fxn_commitfile
+
+ .word acc_file, fxn_readfile /* 0x08 */
+ .word acc_file, fxn_writefile
+ .word acc_file, fxn_lockfile
+ .word acc_file, fxn_unlockfile
+
+ .word acc_cds, fxn_diskspace /* 0x0c */
+ .word acc_never, fxn_unknown
+ .word acc_cds, fxn_setattr
+ .word acc_cds, fxn_getattr
+
+ .word acc_never, fxn_unknown /* 0x10 */
+ .word acc_cds, fxn_rename
+ .word acc_never, fxn_unknown
+ .word acc_cds, fxn_delete
+
+ .word acc_never, fxn_unknown /* 0x14 */
+ .word acc_never, fxn_unknown
+ .word acc_cds, fxn_open
+ .word acc_cds, fxn_create
+
+ .word acc_never, fxn_unknown /* 0x18 */
+ .word acc_never, fxn_unknown
+ .word acc_never, fxn_unknown
+ .word acc_cds, fxn_findfirst
+
+ .word acc_findnext, fxn_findnext /* 0x1c */
+ .word acc_never, fxn_unknown
+ .word acc_never, fxn_unknown
+ .word acc_never, fxn_unknown
+
+ .word acc_never, fxn_unknown /* 0x20 */
+ .word acc_file, fxn_skfmend
+ .word acc_never, fxn_unknown
+ .word acc_qualify, fxn_qualify
+
+ .word acc_never, fxn_unknown /* 0x24 */
+ .word acc_never, fxn_unknown
+ .word acc_never, fxn_unknown
+ .word acc_never, fxn_unknown
+
+ .word acc_never, fxn_unknown /* 0x28 */
+ .word acc_never, fxn_unknown
+ .word acc_never, fxn_unknown
+ .word acc_never, fxn_unknown
+
+ .word acc_never, fxn_unknown /* 0x2c */
+ .word acc_file, fxn_unknown_2d
+ .word acc_cds, fxn_spopenfile
+
+ .size dispatch_table, .-dispatch_table