# ! $Source$ ! $State$ ! $Revision$ ! Declare segments (the order is important). .sect .text .sect .rom .sect .data .sect .bss .sect .bss .define __sys_params_in .comm __sys_params_in, 6 .define __sys_params_out .comm __sys_params_out, 2 .comm opcode, 2 .comm returnto, 2 .sect .text ! Called on system call. This does *not* use the C calling convention: ! ax: syscall number ! stack: ( param3 param2 param1 - result ) .define .mon .mon: mov (opcode), ax pop (returnto) cmp ax, 1 je exit cmp ax, 3 je read cmp ax, 4 je write cmp ax, 5 je open cmp ax, 6 je nop_1 ! close cmp ax, 20 je nop_0 ! getpid cmp ax, 35 je nop_1 ! time cmp ax, 48 je sigtrp cmp ax, 54 je ioctl ! Syscall not supported --- write out an error message and halt. unsupported: mov si, msg 1: lodsb andb al, al jz 2f movb ah, 0xE ! service mov bx, 0x0007 ! page 0, white int 0x10 jmp 1b 2: ! Write out the syscall number. mov dx, (opcode) mov cx, 4 ! 4 hex digits 1: rol dx, 1 ! rotate so that highest 4 bits are at the bottom rol dx, 1 rol dx, 1 rol dx, 1 mov ax, 0xE0F ! ah = request, al = mask for nybble andb al, dl addb al, 0x90 ! convert al to ascii hex (four instructions) daa adcb al, 0x40 daa int 0x10 loop 1b ! Exit. jmp EXIT .sect .rom msg: .asciz 'NOSYS' .sect .text exit: jmp EXIT read: mov ax, __sys_read jmp in_3_out_1 write: mov ax, __sys_write jmp in_3_out_1 open: add sp, 2*2 jmp unimplemented ioctl: mov ax, __sys_ioctl jmp in_3_out_0 sigtrp: add sp, 4 jmp unimplemented in_3_out_0: pop (__sys_params_in+0) pop (__sys_params_in+2) pop (__sys_params_in+4) call ax jmp out_0 in_3_out_1: pop (__sys_params_in+0) pop (__sys_params_in+2) pop (__sys_params_in+4) call ax jmp out_1 out_0: or ax, ax jnz failed push ax jmp return out_1: or ax, ax jnz failed push (__sys_params_out) push ax jmp return unimplemented: mov ax, EBADMON failed: push ax push ax jmp return nop_1: add sp, 1*2 jmp nop_0 nop_3: add sp, 3*2 nop_0: mov ax, 0 push ax jmp return return: jmp (returnto)