diff options
author | Robert de Bath <rdebath@poboxes.com> | 1996-11-03 22:33:35 +0100 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2013-10-23 23:33:35 +0200 |
commit | c218c617b5be443b7968308506969ad2b726d73c (patch) | |
tree | 0051f396af56133d24fcf2ab757fabc78c1a09bf /doselks | |
parent | 0936b9aeab611665645a4e6bafaded7ca76dd189 (diff) | |
parent | 0d2fbe9b1bd284ce2cad55be17e8f2c896031a25 (diff) | |
download | dev86-c218c617b5be443b7968308506969ad2b726d73c.tar.gz |
Import Dev86src-0.0.8.tar.gzv0.0.8
Diffstat (limited to 'doselks')
-rw-r--r-- | doselks/Makefile | 41 | ||||
-rw-r--r-- | doselks/coroutine.c | 120 | ||||
-rw-r--r-- | doselks/doselks.c | 302 | ||||
-rw-r--r-- | doselks/doselks.h | 111 | ||||
-rw-r--r-- | doselks/syscalls.c | 498 | ||||
-rw-r--r-- | doselks/syscalls.h | 59 |
6 files changed, 1131 insertions, 0 deletions
diff --git a/doselks/Makefile b/doselks/Makefile new file mode 100644 index 0000000..de3dd55 --- /dev/null +++ b/doselks/Makefile @@ -0,0 +1,41 @@ + +CC=bcc +CFLAGS=-Md +LDFLAGS=-Md -s + +DISTFILES=Makefile syscalls.h doselks.h coroutine.c doselks.c syscalls.c + +# NB coroutine.o first then we can find it easily for breakpoints in CV.EXE +OBJ=coroutine.o doselks.o syscalls.o + +all: doselks.com + +install: + # Err, Ok, but where do I install a dos program ? + +doselks.com: $(OBJ) + $(CC) $(LDFLAGS) -o doselks.com $(OBJ) + +syscalls.o: call_tab.v +$(OBJ): doselks.h + +call_tab.v: dummy + -cp -p ../libc/syscall/call_tab.v . 2>/dev/null + -cp -p ../libc/syscall/defn_tab.v . 2>/dev/null + +distribution: + tar czf /tmp/doselks.tar.gz $(DISTFILES) + +dummy: + +clean: + rm -f $(OBJ) doselks.com + +realclean: + rm -f call_tab.v defn_tab.v + rm -f $(OBJ) doselks.com + +VVV=xx +$(VVV).o: $(VVV).c + $(CC) $(CFLAGS) -A-l -A$(VVV).lst -c $(VVV).c + diff --git a/doselks/coroutine.c b/doselks/coroutine.c new file mode 100644 index 0000000..259b7c1 --- /dev/null +++ b/doselks/coroutine.c @@ -0,0 +1,120 @@ +#include <stdio.h> +#include "doselks.h" + +int in_process = 0; +int intr_pending = 0; +unsigned int current_ds, current_stack; +struct process * proc; + +/*************************************************************************** + * These two routines to make doselks and the user program into co-routines. + * + * The Server calls run_cpu which runs the client. + * The client then does an int $80 which calls elks_int. + * Elks_int then returns to the caller of run_cpu. + * + * The return value is the value of AX when the int $80 occured. + * On return ES is set to the DS of the client program. + * + * The instruction times are for the 286 + * + * If we were using a 486 then using mov's would be faster on the 286 they + * are the same speed but push/pop is smaller. + */ + +#asm + .data +bx_temp: ! Tempoary storage for BX. + .word 0 + .text ! The is where we store the current_ds in the _TEXT_ segment +cs_current_ds: ! for the elks_int routine + .word 0 +#endasm + +unsigned int run_cpu() +{ +#asm + mov ax,ds ; 2 + seg cs ! Store ds for return + mov [cs_current_ds],ax ; 5 + + cli ! We`re messing! ; 3 + test [_intr_pending],#$FFFF ! Last chance ... + jz skp + sti + xor ax,ax + ret +skp: + push bp ; 3 + push si ; 3 + push di ; 3 + mov [_current_stack],sp ; 5 + mov ax,#1 ; 2 + mov [_in_process],ax ; 5 + mov sp,[_proc] ; 5 + pop ax ! pppop ; 5 + pop [bx_temp] ; 5 + pop cx ; 5 + pop dx ; 5 + pop di ; 5 + pop si ; 5 + pop bp ; 5 + pop es ; 5 + mov bx,sp ! Switch to client stack ; 2 + mov ss,[bx+8] ! SS ; 5 + mov sp,[bx+10] ! SP ; 5 + push [bx+6] ! flags ; 5 + push [bx+4] ! CS ; 5 + push [bx+2] ! PC ; 5 + push [bx+0] ! DS ; 5 + mov bx,[bx_temp] ; 5 + pop ds ; 5 + iret ; 17 +#endasm +} + +unsigned int elks_int() +{ +#asm +.text + cli ; 3 + push ds ; 3 + push cs ; 3 + pop ds ; 5 + mov ds,[cs_current_ds] ; 5 + mov [bx_temp],bx ; 3 + mov bx,[_proc] ; 5 + add bx,#16 ; 2 + pop [bx+0] ! DS ; 5 + pop [bx+2] ! PC ; 5 + pop [bx+4] ! CS ; 5 + pop [bx+6] ! flags ; 5 + mov [bx+8],ss ! SS ; 3 + mov [bx+10],sp ! SP ; 3 + + mov sp,bx ! Ready for pppppush ; 2 + mov bx,ds ; 2 + mov ss,bx ; 2 + + push es ! wheeee ; 3 + push bp ; 3 + push si ; 3 + push di ; 3 + push dx ; 3 + push cx ; 3 + push [bx_temp] ; 5 + push ax ! This is the return value, handy ; 3 + + mov sp,[_current_stack] ; 5 + mov bx,#1 ; 2 + mov [_in_process],bx ; 5 + sti ! Finished F**** around with the stack ; 2 + + mov bx,[_proc] ; 5 + mov es,[bx+16] ! Set ES to the client`s DS ; 5 + pop di ; 5 + pop si ; 5 + pop bp ; 5 +#endasm +} + diff --git a/doselks/doselks.c b/doselks/doselks.c new file mode 100644 index 0000000..3056e19 --- /dev/null +++ b/doselks/doselks.c @@ -0,0 +1,302 @@ +#include <stdio.h> +#include "doselks.h" + +#define DEBUGGER + +void build_stack(/* char ** argv, char ** envp */); + +long elks_int_orig; +union REGS regs; +int process_running; +int exit_code = 255; + +main(argc, argv, envp) +int argc; +char ** argv; +char ** envp; +{ + int rv; + + current_ds = __get_ds(); + if( argc <= 1 ) + { + printf("Usage: %s <8086_exe> [args]\n", argv[0]); + exit(exit_code); + } + + proc = calloc(sizeof(struct process), 1); + if( proc == 0 ) + printf("Unable to allocate memory for executable\n"); + else if( (rv = loadexe(argv[1])) >= 0 ) + { + proc->pid = 1; + proc->ppid = 1; + proc->pgrp = 1; + proc->umask = 022; + proc->next = proc; + + build_stack(argv+1, envp); + + elks_int_orig = __getvect(ELKSINT); + __setvect(ELKSINT, (long)elks_int); + +#ifndef MAKEME + run_executable(); +#else + dump_core(); +#endif + + __setvect(ELKSINT, elks_int_orig); + } + else + { + if( rv == -ENOMEM ) + printf("Unable to allocate memory for executable\n"); + else + printf("Cannot execute %s\n", argv[1]); + } + return(exit_code); +} + +int loadexe(fname) +char * fname; +{ + char bbuf[1024]; + long size; + unsigned int tsize, dsize; + struct elks_exec_hdr mh; + int i; + int fd = -1; + int err = ENOEXEC; + + proc->text_seg = 0; + proc->data_seg = 0; + + if( ( fd = open(fname, O_RDONLY|O_BINARY) ) < 0 ) + goto no_exec; + + /* Load the elks binary image and set it up in a suitable + * segment. Load CS and DS/SS according to image type. + */ + + if( read(fd, &mh,sizeof(mh))!=sizeof(mh) + || mh.hlen!=EXEC_HEADER_SIZE + || (mh.type!=ELKS_COMBID&&mh.type!=ELKS_SPLITID) + ) + goto no_exec; + + if(mh.type==ELKS_COMBID) + { + tsize = 0; + dsize = ((mh.tseg+mh.chmem + 0xF)>>4); + } + else + { + tsize = ((mh.tseg+0xF) >> 4); + dsize = ((mh.chmem+0xF) >> 4); + } + if(tsize) + { + if( (proc->text_seg = seg_allocate(tsize)) == 0) + goto no_mem; + + proc->cs = proc->text_seg->seg; + } + + if( (proc->data_seg = seg_allocate(dsize)) == 0 ) + goto no_mem; + + proc->ds = proc->data_seg->seg; + if(proc->text_seg == 0) proc->cs = proc->ds; + +#ifdef DEBUGGER + fprintf(stderr,"Executable - %s. tseg=0x%04lx dseg=0x%04lx bss=0x%04lx chmem=0x%04lx\n", + mh.type==ELKS_COMBID?"(impure)":"Sep I/D", + mh.tseg,mh.dseg,mh.bseg,mh.chmem); +#endif + + if(proc->text_seg) + { + for(size=0; size<mh.tseg; ) + { + i = sizeof(bbuf); if( i>mh.tseg-size ) i=mh.tseg-size; + + if(read(fd,bbuf,i)!=i) + goto no_exec; + + __movedata(current_ds, (unsigned)bbuf, proc->cs, (int)size, i); + size += i; + } + } + else + mh.dseg += mh.tseg; + + for(size=0; size<mh.dseg; ) + { + i = sizeof(bbuf); if( i>mh.dseg-size ) i=mh.dseg-size; + + if(read(fd,bbuf,i)!=i) + goto no_exec; + + __movedata(current_ds, (unsigned)bbuf, proc->ds, (int)size, i); + size += i; + } + + close(fd); + + /* Zap the bss */ + memset(bbuf, '\0', 1024); + mh.dseg += mh.bseg; + for(; size<mh.dseg; ) + { + i = sizeof(bbuf); if( i>mh.dseg-size ) i=mh.dseg-size; + + __movedata(current_ds, (unsigned)bbuf, proc->ds, (int)size, i); + size += i; + } + + /* + * Load the VM86 registers + */ + + proc->ss=proc->ds; + proc->es=0; /* This will be preserved */ + proc->sp=mh.chmem; /* Args stacked later */ + proc->pc=0; /* Run from 0 */ + + /* + * Loaded + */ + + return 0; +no_mem:; + err = ENOMEM; +no_exec:; + seg_free(proc->text_seg); + seg_free(proc->data_seg); + if( fd > 0 ) close(fd); + return -err; +} + +void +build_stack(argv, envp) +char ** argv; char ** envp; +{ + char buffer[1024]; + + char **p; + int argv_len=0, argv_count=0; + int envp_len=0, envp_count=0; + int stack_bytes; + unsigned short * pip; + char * pcp; + + /* How much space for argv */ + if(argv) for(p=argv; *p; p++) + { + argv_count++; argv_len += strlen(*p)+1; + } + + /* How much space for envp */ + if(envp) for(p=envp; *p; p++) + { + envp_count++; envp_len += strlen(*p)+1; + } + + /* tot it all up */ + stack_bytes = 2 /* argc */ + + argv_count * 2 + 2 /* argv */ + + argv_len + + envp_count * 2 + 2 /* envp */ + + envp_len; + + if( stack_bytes > sizeof(buffer)-2 ) + { + printf("Environment too large\n"); + exit(exit_code); + } + /* Allocate it */ + proc->sp -= stack_bytes; + +#ifdef DEBUGGER + printf("Argv = (%d,%d), Envp=(%d,%d), stack=%d\n", + argv_count, argv_len, envp_count, envp_len, stack_bytes); +#endif + + /* Now build the data */ + pip=(unsigned short *) buffer; + pcp=buffer+sizeof(unsigned short *)*(1+argv_count+1+envp_count+1); + + *pip++ = argv_count; + for(p=argv; *p; p++) + { + *pip++ = (pcp-buffer)+proc->sp; + strcpy(pcp, *p); + pcp += strlen(*p)+1; + } + *pip++ = 0; + + for(p=envp; *p; p++) + { + *pip++ = (pcp-buffer)+proc->sp; + strcpy(pcp, *p); + pcp += strlen(*p)+1; + } + *pip++ = 0; + __movedata(current_ds, (unsigned)buffer, + proc->ds, proc->sp, stack_bytes); +} + +/***************************************************************************/ + +dump_core() +{ + char bbuf[1024]; + int i, fd; + unsigned destseg; + printf("Not dumping core\n"); + +/* + if( ( fd = open("core", O_WRONLY|O_BINARY|O_CREAT|O_TRUNC) ) < 0 ) + { + return -1; + } + + destseg = proc->memory; + + for(i=0; i<(proc->memsize+63)/64; i++) + { + __movedata( destseg+i*64, 0, current_ds, (unsigned)bbuf, 1024); + if( write(fd, bbuf, 1024) < 0 ) + printf("FAIL 7\n"); + } + + close(fd); +*/ +} + +/***************************************************************************/ + +seg_allocate(size) +{ + struct segment *nptr = calloc(sizeof(struct segment),1); + + if( nptr == 0 ) return 0; + + nptr->ref_count = 1; + nptr->size = size; + nptr->seg = __segalloc(size); + if( nptr->seg == 0 ) { free(nptr); return 0; } + + return nptr; +} + +seg_free(ptr) +struct segment * ptr; +{ + if(ptr == 0) return; + if( --ptr->ref_count > 0 ) + return; + __segfree(ptr->seg); + free(ptr); +} diff --git a/doselks/doselks.h b/doselks/doselks.h new file mode 100644 index 0000000..6ea67eb --- /dev/null +++ b/doselks/doselks.h @@ -0,0 +1,111 @@ + +#include <ctype.h> +#include <dos.h> +#include <malloc.h> +#include <errno.h> +#include <fcntl.h> +#include <signal.h> +#include <sys/wait.h> +#include <sys/resource.h> +#include <sys/stat.h> + +/* Function return vals */ + +extern unsigned int elks_int(); +extern unsigned int run_cpu(); + +/* Elks binary formats */ + +#define EXEC_HEADER_SIZE 32 + +struct elks_exec_hdr +{ + unsigned long type; +#define ELKS_COMBID 0x04100301L +#define ELKS_SPLITID 0x04200301L + unsigned long hlen; + unsigned long tseg; + unsigned long dseg; + unsigned long bseg; + unsigned long unused; + unsigned long chmem; + unsigned long unused2; +}; + +/* Elks cpu structure. */ + +struct fd_ref { + int ftype; + union { + int i; + FILE * f; + } fd; +} ; + +struct segment { + unsigned int seg; + unsigned int size; + int ref_count; +}; + +struct process +{ + unsigned int ax; /* NOTE The order of this is _closely_ related to */ + unsigned int bx; /* the coroutine assembler */ + unsigned int cx; + unsigned int dx; + unsigned int di; + unsigned int si; + unsigned int bp; + unsigned int es; + + unsigned int ds; /* start +16 +0 */ + unsigned int pc; /* start +16 +2 */ + unsigned int cs; /* start +16 +4 */ + unsigned int flgs; /* start +16 +6 */ + unsigned int ss; /* start +16 +8 */ + unsigned int sp; /* start +16 +10 */ + + /* From here down only accessed from C */ + int pending_op; + struct process * next; + + struct segment * text_seg; + struct segment * data_seg; + + int pid; + int ppid; + int pgrp; + int umask; + int uid; + int gid; + int euid; + int egid; + int suid; + int sgid; + long ignmask, trpmask; + int sigtrap; + + struct fd_ref fds[20]; + + struct rusage ruse; +}; + +extern struct process * proc; +extern unsigned int current_ds, current_stack; +extern int in_process; +extern int process_running; +extern int intr_pending; + +/* Elks syscall interface */ + +#define ELKSINT 0x80 +typedef int (*Scallp)( /* int, int, int */ ); +extern Scallp syscalltab[]; + +/******************************************************************************/ + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + diff --git a/doselks/syscalls.c b/doselks/syscalls.c new file mode 100644 index 0000000..a4f3e69 --- /dev/null +++ b/doselks/syscalls.c @@ -0,0 +1,498 @@ +#include <stdio.h> +#include "doselks.h" +#include "syscalls.h" + +/***************************************************************************/ + +/* Need to use stdio for CR<->NL translation */ +#define MAX_FD 20 +FILE * tty_file[MAX_FD] = {stdin, stdout, stderr}; + +int nextpid = 2; +int proc_one = 1; + +/***************************************************************************/ + +#define sys_exit elks_exit +elks_exit(wait_stat) +int wait_stat; +{ + struct process * cur; + int x; + + if(wait_stat & 0x80) dump_core(); + + /* save wait_stat */ + proc->ax = wait_stat; + if(proc->pid == 1) proc_one = 0; + + process_running--; + seg_free(proc->text_seg); + seg_free(proc->data_seg); + + for(cur=proc->next; cur!=proc; cur=cur->next) + if(cur->ppid == proc->pid) + cur->ppid = 1; + + return 0; +} + +#define sys_fork elks_fork +elks_fork(bx, cx, dx) +int bx, cx, dx; +{ + unsigned int size, i; + struct process * newproc; + + if(nextpid<0) return -EINVAL; /* TODO: max 32k forks */ + + newproc = calloc(sizeof(struct process), 1); + if( newproc == 0 ) return -ENOMEM; + + proc->pending_op = 0; + *newproc = *proc; + newproc->ppid = newproc->pid; + newproc->data_seg = seg_allocate(proc->data_seg->size); + + if( newproc->data_seg == 0 ) + { + free(newproc); + return -ENOMEM; + } + newproc->text_seg->ref_count++; + + newproc->cs = newproc->text_seg->seg; + newproc->ds = newproc->data_seg->seg; + newproc->ss = newproc->ds; + + newproc->pid = nextpid++; + + /* Duplicate memory */ + for(i=0; i<newproc->data_seg->size; i+=size ) + { + size = 0xFFF; + if(size > newproc->data_seg->size-i) size = newproc->data_seg->size-i; + + __movedata(proc->ds, i*16, newproc->ds, i*16, size*16); + } + + proc->ax = newproc->pid; + newproc->ax = 0; + proc->next = newproc; + process_running++; + /* proc = newproc; */ + + return newproc->pid; +} + +struct process * +get_zombie(ppid, pid) +int ppid, pid; +{ + struct process * prev, * cur, *running=0; + /* Process group, not defined */ + if( pid < -1 ) return 0; + if( pid == 0 ) pid = -1; + + for(prev=proc, cur=proc->next; cur!=proc; prev=cur, cur=cur->next) + { + if(cur->ppid == ppid && (pid == -1 || cur->pid == pid)) + { + if(cur->pending_op != 1) + { + running = cur; + continue; + } + prev->next = cur->next; + cur->next = 0; + return cur; + } + } + return running; +} + +#define sys_wait4 elks_wait4 +elks_wait4(bx, cx, dx, di, si) +int bx, cx, dx, di, si; +{ + struct process * cur; + int cpid; + + cur = get_zombie(proc->pid, bx); + if( cur == 0 ) return -ECHILD; + + if( cur->pending_op != 1) + { + if( dx & WNOHANG ) + return 0; + else + return -EINTR; + } + + cpid = cur->pid; + if( cx ) __doke_es(cx, cur->ax); + if( di ) + __movedata(current_ds, (unsigned)&(cur->ruse), + proc->ds, di, sizeof(struct rusage)); + free(cur); + return cpid; +} + +#define sys_exec elks_exec +int elks_exec(bx, cx, dx) +int bx, cx, dx; +{ + struct process oldproc; + char fname[128]; + int ax; + + oldproc = *proc; + __strnget_es(fname, bx, sizeof(fname)-1); + fname[sizeof(fname)-1] = '\0'; + + if( (ax=loadexe(fname)) != 0 ) + { + *proc = oldproc; + return ax; + } + + __movedata(oldproc.ds, cx, proc->ds, proc->sp-dx, dx); + + /* + Fudge pointers. + */ + proc->sp -= dx; + + /* Args */ + ax = proc->sp + 2; + __set_es(proc->ds); + while(__deek_es(ax) != 0 ) + __doke_es(ax, __deek_es(ax)-dx), ax+=2; + + /* env */ + ax+=2; + while(__deek_es(ax) != 0 ) + __doke_es(ax, __deek_es(ax)-dx), ax+=2; + + seg_free(oldproc.text_seg); + seg_free(oldproc.data_seg); + return 0; +} + +#define sys_read elks_read +int elks_read(bx, cx, dx) +int bx, cx, dx; +{ + register int ch, rv=0; + if( bx<0 || bx>MAX_FD || tty_file[bx] == 0 ) return -EBADF; + do + { + ch = fgetc(tty_file[bx]); + if( ch == EOF ) break; + __poke_es(cx++, ch); + rv++; + } + while(--dx > 0 && stdio_pending(tty_file[bx])); + + return rv; +} + +#define sys_write elks_write +int elks_write(bx, cx, dx) +unsigned int bx, cx, dx; +{ + char ch[2]; + register unsigned int i; + if( bx<0 || bx>MAX_FD || tty_file[bx] == 0 ) return -EBADF; + + for(i=dx; i>0; i--) + { + if( fputc(__peek_es(cx++), tty_file[bx]) == EOF ) + return -1; + } + fflush(tty_file[bx]); + return dx; +} + +#define sys_open elks_open +int elks_open(bx, cx, dx) +{ + char fname[128]; + int i; + char *mode = ""; + + __strnget_es(fname, bx, sizeof(fname)-1); + fname[sizeof(fname)-1] = '\0'; + + for(i=0; i<MAX_FD; i++) + { + if(tty_file[i] == 0) break; + } + if( i >= MAX_FD ) return -EMFILE; + + /* Translate the mode; more or less */ + switch(cx&O_ACCMODE) + { + case O_RDONLY: + mode="r"; + break; + case O_WRONLY: + if( cx&O_APPEND ) mode="a"; + else if( cx&O_TRUNC ) mode="w"; + else mode="r+"; + break; + case O_RDWR: + if( cx&O_APPEND ) mode="a+"; + else if( cx&O_TRUNC ) mode="w+"; + else mode="r+"; + break; + } + + if( ( tty_file[i] = fopen(fname, mode) ) == 0 ) + { + if( errno == 0 ) return -ENOENT; + return -errno; + } + return i; +} + +#define sys_close elks_close +int elks_close(bx, cx, dx) +{ + if( bx<0 || bx>MAX_FD || tty_file[bx] == 0 ) return -EBADF; + fclose(tty_file[bx]); + tty_file[bx] = 0; + return 0; +} + +#define sys_lseek elks_lseek +int elks_lseek(bx, cx, dx) +{ + long l; + if( bx<0 || bx>MAX_FD || tty_file[bx] == 0 ) return -EBADF; + + __movedata(proc->ds, cx, current_ds, &l, 4); + + if( fseek(tty_file[bx], l, dx) < 0 ) return -ESPIPE; + + l = ftell(tty_file[bx]); + __movedata(current_ds, &l, proc->ds, cx, 4); + return 0; +} + +#define sys_brk elks_brk +int elks_brk(bx, cx, dx) +{ + /* For the moment we don't care; libc does enough */ + return 0; +} + +#define sys_getpid elks_getpid +int elks_getpid(bx, cx, dx) +{ + __doke_es(bx, proc->ppid); + return proc->pid; +} + +#define sys_getuid elks_getuid +int elks_getuid(bx, cx, dx) +{ + __doke_es(bx, proc->euid); + return proc->uid; +} + +#define sys_getgid elks_getgid +int elks_getgid(bx, cx, dx) +{ + __doke_es(bx, proc->egid); + return proc->gid; +} + +#define sys_setuid elks_setuid +int elks_setuid(bx, cx, dx) +{ + if( proc->euid == 0 + || proc->uid == bx || proc->euid == bx || proc->suid == bx) + { + if( proc->euid == 0 ) + proc->suid = proc->uid = bx; + proc->euid = bx; + } + else + return -EPERM; +} + +#define sys_setgid elks_setgid +int elks_setgid(bx, cx, dx) +{ + if( proc->euid == 0 + || proc->gid == bx || proc->egid == bx || proc->sgid == bx) + { + if( proc->euid == 0 ) + proc->sgid = proc->gid = bx; + proc->egid = bx; + } + else + return -EPERM; +} + +#define sys_umask elks_umask +int elks_umask(bx, cx, dx) +{ + cx= proc->umask; + proc->umask = (bx&0777); + return cx; +} + +void sig_trap(signo) +int signo; +{ + proc->sp -= 2; + __doke_es(proc->sp, signo); + proc->sp -= 2; + __doke_es(proc->sp, proc->pc); + proc->pc = proc->sigtrap; +} + +#define sys_signal elks_signal +int elks_signal(bx,cx,dx) +{ + int rv; + if( bx < 0 || bx >= NSIG ) return -EINVAL; + if( bx == SIGSTOP || bx == SIGKILL ) return 0; + + proc->trpmask &= ~(1L<<bx); + proc->ignmask &= ~(1L<<bx); + + if( cx == 0 ) /* Default */; + else if( cx == 1 ) proc->ignmask |= (1L<<bx); + else + { + proc->trpmask |= (1L<<bx); + proc->sigtrap = cx; + } + + return 0; +} + +#define sys_lstat elks_stat +#define sys_stat elks_stat +int elks_stat(bx,cx,dx) +{ + struct stat ms; + char fnamebuf[65]; + char dtabuf[128]; /* I think this only needs 32 bytes ... but ... */ + int v; + long ttime, tdate; + + __strnget_es(fnamebuf, bx, sizeof(fnamebuf)-1); + fnamebuf[64] = '\0'; + + v = __dos_stat(fnamebuf, dtabuf); + if( v < 0 ) return -ENOENT; + + ms.st_dev= *dtabuf; + ms.st_ino= 0; + ms.st_mode= ((dtabuf[0x15]&0x1)?0555:0777); /* + File or directory */ + if (dtabuf[0x15]&0x10) + ms.st_mode |= S_IFDIR; + else + ms.st_mode |= S_IFREG; + ms.st_nlink= 1; + ms.st_uid= 0; + ms.st_gid= 0; + ms.st_rdev= 0; + ms.st_size= *(long*)(dtabuf+0x1A); + + ttime = *((unsigned short*)(dtabuf+0x16)); + ttime = ( ttime &0x1F) * 2 + + ((ttime>>5) &0x2F) * 60 + + ((ttime>>11) &0x1F) * 3600L; + +/* FIXME: This needs a julian day calculator .. */ + tdate = *((unsigned short*)(dtabuf+0x18)); + tdate = ((tdate) &0x1F) -32 + + ((tdate>>5) &0x0F) * 31 + + ((tdate>>9) &0x7F) * (31*12); + + ms.st_mtime= tdate*86400L + ttime; + ms.st_atime= ms.st_mtime; + ms.st_ctime= ms.st_mtime; + + /* copy &ms -> es:cx */ + __movedata(current_ds, &ms, proc->ds, cx, sizeof(struct stat)); + + return 0; +} + +/***************************************************************************/ + +#define sys_enosys elks_enosys +int elks_enosys(bx, cx, dx) +int bx, cx, dx; +{ + printf("Unimplemented syscall(%d,0x%04x,0x%04x,0x%04x)\n", + proc->ax,proc->bx,proc->cx,proc->dx); + return -ENOSYS; +} + +#include "defn_tab.v" + +Scallp syscalltab[] = { +#include "call_tab.v" + elks_enosys +}; + +FILE * error; +run_executable() +{ + + register unsigned int r_ax; + register Scallp ptr; + process_running=1; + + error = fopen("errlog", "w"); + + do + { + if( proc->pending_op == 0 ) + { + fprintf(error, "Run %d AX=%-4d proc =%04x IP=%04x...", + proc->pid, proc->ax, proc, proc->pc); fflush(error); + proc->pending_op = run_cpu(); + } + if( r_ax = proc->pending_op ) + { + if( r_ax >= sizeof(syscalltab)/sizeof(Scallp) ) + r_ax = 0; + + fprintf(error, "%d: Call_%d(%04x, %04x, %04x) -> ", + proc->pid, r_ax, proc->bx, proc->cx, proc->dx); + fflush(error); + + if( r_ax == 1 ) + (void) elks_exit(proc->bx << 8); + else + { + __set_es(proc->ds); + if( (proc->ax = (*syscalltab[r_ax])(proc->bx, proc->cx, proc->dx, + proc->di, proc->si)) + != (unsigned) -EINTR ) + { + proc->pending_op = 0; + /* + fprintf(error, "%d\n", proc->ax); + fflush(error); + continue; + */ + } + } + fprintf(error, "%d\n", proc->ax); + fflush(error); + } + intr_pending = 0; /* FIXME: deal with */ + do { proc = proc->next; } while(proc->pending_op==1 && process_running); + } + while(process_running); +} + diff --git a/doselks/syscalls.h b/doselks/syscalls.h new file mode 100644 index 0000000..90c7a99 --- /dev/null +++ b/doselks/syscalls.h @@ -0,0 +1,59 @@ +extern int sys_exit __P((int, int, int)); +extern int sys_vfork __P((int, int, int)); +extern int sys_read __P((int, int, int)); +extern int sys_write __P((int, int, int)); +extern int sys_open __P((int, int, int)); +extern int sys_close __P((int, int, int)); +extern int sys_wait __P((int, int, int)); +extern int sys_creat __P((int, int, int)); +extern int sys_link __P((int, int, int)); +extern int sys_unlink __P((int, int, int)); +extern int sys_waitpid __P((int, int, int)); +extern int sys_chdir __P((int, int, int)); +extern int sys_time __P((int, int, int)); +extern int sys_mknod __P((int, int, int)); +extern int sys_chmod __P((int, int, int)); +extern int sys_chown __P((int, int, int)); +extern int sys_brk __P((int, int, int)); +extern int sys_stat __P((int, int, int)); +extern int sys_lseek __P((int, int, int)); +extern int sys_getpid __P((int, int, int)); +extern int sys_mount __P((int, int, int)); +extern int sys_umount __P((int, int, int)); +extern int sys_setuid __P((int, int, int)); +extern int sys_getuid __P((int, int, int)); +extern int sys_stime __P((int, int, int)); +extern int sys_ptrace __P((int, int, int)); +extern int sys_alarm __P((int, int, int)); +extern int sys_fstat __P((int, int, int)); +extern int sys_pause __P((int, int, int)); +extern int sys_utime __P((int, int, int)); +extern int sys_stty __P((int, int, int)); +extern int sys_gtty __P((int, int, int)); +extern int sys_access __P((int, int, int)); +extern int sys_nice __P((int, int, int)); +extern int sys_ftime __P((int, int, int)); +extern int sys_sync __P((int, int, int)); +extern int sys_kill __P((int, int, int)); +extern int sys_rename __P((int, int, int)); +extern int sys_mkdir __P((int, int, int)); +extern int sys_rmdir __P((int, int, int)); +extern int sys_pipe __P((int, int, int)); +extern int sys_times __P((int, int, int)); +extern int sys_prof __P((int, int, int)); +extern int sys_setgid __P((int, int, int)); +extern int sys_getgid __P((int, int, int)); +extern int sys_signal __P((int, int, int)); +extern int sys_acct __P((int, int, int)); +extern int sys_plock __P((int, int, int)); +extern int sys_ioctl __P((int, int, int)); +extern int sys_fcntl __P((int, int, int)); +extern int sys_exec __P((int, int, int)); +extern int sys_umask __P((int, int, int)); +extern int sys_chroot __P((int, int, int)); +extern int sys_sigaction __P((int, int, int)); +extern int sys_sigsuspend __P((int, int, int)); +extern int sys_sigpending __P((int, int, int)); +extern int sys_sigprocmask __P((int, int, int)); +extern int sys_sigreturn __P((int, int, int)); +extern int sys_reboot __P((int, int, int)); |