diff options
author | Robert de Bath <rdebath@poboxes.com> | 1999-06-11 14:11:38 +0200 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2013-10-23 23:41:25 +0200 |
commit | 3d4957c86ff239b24b43933924ec72a3fd288518 (patch) | |
tree | da8225a4d7bb2d9123e10d558cdc3eebae6254c8 /libc/msdos | |
parent | e62b35169cdcd13632ae353b1e5ffde7dec44201 (diff) | |
download | dev86-3d4957c86ff239b24b43933924ec72a3fd288518.tar.gz |
Import Dev86src-0.14.8.tar.gzv0.14.8
Diffstat (limited to 'libc/msdos')
-rw-r--r-- | libc/msdos/Makefile | 4 | ||||
-rw-r--r-- | libc/msdos/TODO | 8 | ||||
-rw-r--r-- | libc/msdos/conio.c | 14 | ||||
-rw-r--r-- | libc/msdos/dirent.c | 8 | ||||
-rw-r--r-- | libc/msdos/dosound.c | 10 | ||||
-rw-r--r-- | libc/msdos/i86.c | 177 | ||||
-rw-r--r-- | libc/msdos/intr.c | 82 | ||||
-rw-r--r-- | libc/msdos/msdos.c | 47 | ||||
-rw-r--r-- | libc/msdos/mslib.c | 67 | ||||
-rw-r--r-- | libc/msdos/new86.c | 13 | ||||
-rw-r--r-- | libc/msdos/sound.c | 27 | ||||
-rw-r--r-- | libc/msdos/time.c | 5 |
12 files changed, 390 insertions, 72 deletions
diff --git a/libc/msdos/Makefile b/libc/msdos/Makefile index 06d999a..0a53679 100644 --- a/libc/msdos/Makefile +++ b/libc/msdos/Makefile @@ -11,11 +11,11 @@ AOBJ= \ BSRC=i86.c BOBJ= __seg_regs.o __peek_es.o __poke_es.o __deek_es.o __doke_es.o \ - __strnget_es.o __strchr_es.o __strlen_es.o + __strnget_es.o __strchr_es.o __strlen_es.o int86.o int86x.o segread.o ifeq ($(LIB_CPU),i86) ifeq ($(LIB_OS),DOS) -OBJ=$(AOBJ) $(BOBJ) time.o +OBJ=$(AOBJ) $(BOBJ) time.o sound.o else OBJ=$(BOBJ) endif diff --git a/libc/msdos/TODO b/libc/msdos/TODO index f2664a2..c9f57e1 100644 --- a/libc/msdos/TODO +++ b/libc/msdos/TODO @@ -1,3 +1,11 @@ #define remove(x) unlink(x) +opendir + +closedir + +readdir + +rewinddir + See also the other files, many parts are incomplete. diff --git a/libc/msdos/conio.c b/libc/msdos/conio.c index 1abfa40..f6f9105 100644 --- a/libc/msdos/conio.c +++ b/libc/msdos/conio.c @@ -1,4 +1,12 @@ -/* Is this BIOS keyboard io ? */ +/* Copyright (C) 1999 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* + * I'm not sure if these should be BIOS or dos calls, so I'll assume they're + * BIOS calls but I may have to do something about Ctrl-C. + */ getch() { @@ -50,6 +58,8 @@ char * str; while(*str) putch(*str++); } +#if 0 + cgets() { } @@ -70,4 +80,4 @@ gotoxy() { } - +#endif diff --git a/libc/msdos/dirent.c b/libc/msdos/dirent.c deleted file mode 100644 index 00d774e..0000000 --- a/libc/msdos/dirent.c +++ /dev/null @@ -1,8 +0,0 @@ - -opendir - -closedir - -readdir - -rewinddir diff --git a/libc/msdos/dosound.c b/libc/msdos/dosound.c deleted file mode 100644 index 80f49d6..0000000 --- a/libc/msdos/dosound.c +++ /dev/null @@ -1,10 +0,0 @@ - - -nosound() -{ -} - -sound(freq) -int freq -{ -} diff --git a/libc/msdos/i86.c b/libc/msdos/i86.c index 6c613b2..3cab105 100644 --- a/libc/msdos/i86.c +++ b/libc/msdos/i86.c @@ -218,4 +218,181 @@ char * str; } #endif +#ifdef L_int86 +int +int86(intr, in_regs, out_regs) +int intr; +union REGS* in_regs; +union REGS* out_regs; +{ +#asm + push bp + mov bp,sp + push ds ! save ds + ! es too ? + push bp ! same for new bp + + pushf ! iret flags + mov ax,[bp-6] ! flags for simulated int + push cs ! iret address segment + mov bx,#ret_addr ! iret address offset + push bx + and ah,#$0C ! simulate interrupt flags + push ax ! flags are pushed first + + xor bx,bx + mov es,bx ! interrupt vectors in seg 0 + mov bl,[bp+4] + shl bx,#1 + shl bx,#1 ! intr*4 => interrupt vector address + seg es + push [bx+2] ! fetch interrupt segment + seg es + push [bx] ! fetch interrupt offset + mov bx,[bp+6] ! input union REGS* + + mov ax,[bx] + mov cx,[bx+4] + mov dx,[bx+6] + mov si,[bx+8] + mov di,[bx+10] + mov bx,[bx+2] + ! Ignore cflag/flags ? + + iret ! simulate interrupt. + ! But won't be nice for protected mode ... +ret_addr: + ! Int $25/6 would need resetting sp:ss too ... should I ? + + pop bp ! unzapped versions + pop ds ! paranoia + + pushf ! save interrupt flags + push bx ! save pointer register + mov bx,[bp+8] ! output union REGS* + + mov [bx],ax + pop [bx+2] + mov [bx+4],cx + mov [bx+6],dx + mov [bx+8],si + mov [bx+10],di + mov word [bx+12],#0 ! cflag + jnc no_carry + mov byte [bx+12],#1 +no_carry: + pop [bx+14] ! flags + + pop bp +#endasm +} + +#endif + +#ifdef L_int86x +int +int86x(intr, in_regs, out_regs, segr) +int intr; +union REGS* in_regs; +union REGS* out_regs; +struct SREGS * segr; +{ +#asm + push bp + mov bp,sp + push ds ! save ds + ! es too ? + push bp ! same for new bp + + pushf ! iret flags + mov ax,[bp-6] ! flags for simulated int + push cs ! iret address segment + mov bx,#ret_addr ! iret address offset + push bx + and ah,#$0C ! simulate interrupt flags + push ax ! flags are pushed first + + xor bx,bx + mov es,bx ! interrupt vectors in seg 0 + mov bl,[bp+4] + shl bx,1 + shl bx,1 ! intr*4 => interrupt vector address + seg es + push word [bx+2] ! fetch interrupt segment + seg es + push word [bx] ! fetch interrupt offset + + mov bx,[bp+10] ! struct SREGS* + mov es,[bx] + push [bx+6] ! ds + + mov bx,[bp+6] ! input union REGS* + + mov ax,[bx] + mov cx,[bx+4] + mov dx,[bx+6] + mov si,[bx+8] + mov di,[bx+10] + mov bx,[bx+2] + ! Ignore cflag/flags ? + + pop ds + + iret ! simulate interrupt + ! But won't be nice for protected mode ... + +ret_addr: + ! Int $25/6 would need resetting sp:ss too ... should I ? + + pop bp ! in case it was zapped + + pushf ! save interrupt flags + + push cx ! save work register + mov cx,ds + push bx ! save pointer register + + mov ds,word [bp-2] ! restore original ds + mov bx,[bp+10] ! struct SREGS* + mov [bx],es + mov [bx+6],cx + + mov bx,[bp+8] ! output union REGS* + mov [bx],ax + pop [bx+2] ! bx + pop [bx+4] ! cx + mov [bx+6],dx + mov [bx+8],si + mov [bx+10],di + mov word [bx+12],#0 ! cflag + jnc no_carry + mov byte [bx+12],#1 +no_carry: + pop [bx+14] ! flags + + pop ds + pop bp +#endasm +} +#endif + +#ifdef L_segread +segread(segp) +struct SREGS * segp; +{ +#asm +#if __FIRST_ARG_IN_AX__ + mov bx,ax +#else + mov bx,sp + mov bx,[bx+2] +#endif + mov [bx],es + mov [bx+2],cs + mov [bx+4],ss + mov [bx+6],ds +#endasm +} +#endif + #endif /* __AS386_16__ */ diff --git a/libc/msdos/intr.c b/libc/msdos/intr.c new file mode 100644 index 0000000..22de042 --- /dev/null +++ b/libc/msdos/intr.c @@ -0,0 +1,82 @@ + +struct REGPACK +{ + unsigned r_ax, r_bx, r_cx, r_dx; + unsigned r_bp, r_si, r_di, r_ds, r_es, r_flags; +}; + +/* DANGER DANGER -- Self modifying code! */ + +#asm +.text +save_sp: + dw 0 +#endasm + +intr(intr, regs) +int intr; +struct REGPACK * regs; +{ +#asm + mov bx,sp + push bp + push si + push di + push es + push ds + + mov ax,[bx+2] + seg cs + mov [intr_inst+1],al + seg cs + mov [save_sp],sp + + mov bx,[bx+4] + + mov ah,[bx+18] ! Flags low byte + sahf + + mov ax,[bx] + push [bx+2] + mov cx,[bx+4] + mov dx,[bx+6] + mov bp,[bx+8] + mov si,[bx+10] + mov di,[bx+12] + mov es,[bx+16] + mov ds,[bx+14] + pop bx + +intr_inst: + int $FF ! Must be a real int .. consider protected mode. + + seg cs ! Could be SS as DS==SS + mov sp,[save_sp] + seg cs + mov [save_sp],ds + pop ds + push [save_sp] + + push bx + mov bx,sp + mov bx,[bx+12] + + mov [bx],ax + pop [bx+2] + mov [bx+4],cx + mov [bx+6],dx + mov [bx+8],bp + mov [bx+10],si + mov [bx+12],di + pop [bx+14] + mov [bx+16],es + pushf + pop [bx+18] + + pop es + pop di + pop si + pop bp + +#endasm +} diff --git a/libc/msdos/msdos.c b/libc/msdos/msdos.c index 77100ae..ae10b39 100644 --- a/libc/msdos/msdos.c +++ b/libc/msdos/msdos.c @@ -180,7 +180,7 @@ int __argc; char ** __argv; { int length, i, argc=1, s=0; - char *ptr, *p; + unsigned char *ptr, *p; __set_es(__psp); /* Pointer to the args */ length = __peek_es(0x80); /* Length of cmd line */ if( length > 0 ) @@ -190,25 +190,25 @@ char ** __argv; for(i=0; i<length; i++) /* Copy it in. */ { ptr[i] = __peek_es(0x81+i); -/* Replaced because freedos adds \r to args. - if( ptr[i] != ' ' && s == 0 ) { argc++; s=1; } - if( ptr[i] == ' ' && s == 1 ) s=0; - */ - if( (ptr[i]&0xE0) != 0 && s == 0 ) { argc++; s=1; } - if( (ptr[i]&0xE0) == 0 && s == 1 ) s=0; + if( ptr[i] > ' ' && s == 0 ) { argc++; s=1; } + if( ptr[i] <= ' ' && s == 1 ) s=0; } ptr[length]=0; p= __argv[0]; __argv = (char**) sbrk((argc+1)*sizeof(char*)); - __argv[0] = p; /* FIXME: The real command can be found */ + __argv[0] = p; /* TODO: The real command can be found */ __argc=argc; + /* + * TODO: This needs to understand quoting and wildcards + */ + argc=1; s=0; for(i=0; i<length; i++) { - if( ptr[i] != ' ' && s == 0 ) { __argv[argc++] = ptr+i; s=1; } - if( ptr[i] == ' ' && s == 1 ) { ptr[i] = '\0'; s=0; } + if( ptr[i] > ' ' && s == 0 ) { __argv[argc++] = ptr+i; s=1; } + if( ptr[i] <= ' ' && s == 1 ) { ptr[i] = '\0'; s=0; } } __argv[argc] = 0; } @@ -233,7 +233,10 @@ int __argc; char ** __argv; char ** __envp; { - /* FIXME !!! */ + /* FIXME !!! + * + * Note must write to __envp argument but not touch __argv or __argc + */ } #endif @@ -383,6 +386,19 @@ int cmode; int creat_mode = 0; int rv; +static int xlate_mode[] = { +#ifdef OPEN_LIKE_UNIX + O_RDONLY|O_DENYNONE, + O_WRONLY|O_DENYNONE, + O_RDWR|O_DENYNONE, +#else + O_RDONLY|O_DENYNONE, + O_WRONLY|O_DENYWRITE, + O_RDWR|O_DENYALL, +#endif + 3 +}; + if( (cmode & 0222) == 0 ) creat_mode = 1; /* BzzzT. Assume these flags both mean the merge of them */ @@ -391,8 +407,13 @@ int cmode; rv = __dos_creat(nname, creat_mode); else - /* Warn, this assumes the standard vals for O_RDWR, O_RDONLY, O_WRONLY */ - rv = __dos_open(nname, type&O_ACCMODE); + { + /* If we would open in compatibility mode make it a little more unixy */ + if( type & O_DENYMODE ) + rv = __dos_open(nname, type&(O_ACCMODE|O_DENYMODE|O_SETFD)); + else + rv = __dos_open(nname, xlate_mode[type&O_ACCMODE]); + } return rv; } diff --git a/libc/msdos/mslib.c b/libc/msdos/mslib.c index c1dfb30..90e23ef 100644 --- a/libc/msdos/mslib.c +++ b/libc/msdos/mslib.c @@ -79,6 +79,44 @@ char * path; } #endif +/************************************************************************* + TO TEST ... +*/ + +#ifdef L_sleep +sleep(secs) +unsigned secs; +{ + int counter = 0; + int es = __get_es(); + + __set_es(0x40); + + while(secs>0) + { + int c = __peek_es(0x6C); + while( c == __peek_es(0x6C) ) ; + + counter += 549; + if( counter > 10000 ) + { + secs--; + counter -= 10000; + } + + /* Interrupt on ctrl-break */ + if( __peek_es(0x71) & 0x80 ) break; + } + __set_es(es); + + return secs; +} +#endif + +/************************************************************************* + TODO ... +*/ + #ifdef L_dos_access access(filename, amode) char * filename; @@ -89,7 +127,8 @@ int amode; #endif #ifdef L__dos_allocmem -_dos_allocmem(size +_dos_allocmem(size ...) +{ } #endif @@ -263,14 +302,6 @@ getpid() } #endif -#ifdef L_int86 - XXX; -#endif - -#ifdef L_int86x - XXX; -#endif - #ifdef L_rename rename(oldname, newpath) char *oldpath, *newpath; @@ -279,14 +310,6 @@ char *oldpath, *newpath; } #endif -#ifdef L_segread -segread(segp) -struct SREGS * segp; -{ - XXX; -} -#endif - #ifdef L_setmode setmode(fd, amode) int fd, amode; @@ -295,13 +318,6 @@ int fd, amode; } #endif -#ifdef L_sleep -sleep(secs) -unsigned secs; -{ - XXX; -} -#endif #ifdef L_system system(cmd) @@ -316,6 +332,9 @@ umask(mode) int mode; { XXX; + /* + * save umask value for open() use it for read-only bit. + */ } #endif diff --git a/libc/msdos/new86.c b/libc/msdos/new86.c index cc139bb..1c1e218 100644 --- a/libc/msdos/new86.c +++ b/libc/msdos/new86.c @@ -31,11 +31,11 @@ int portno; { } -outp( +outp(...) { } -outpw( +outpw(...) { } @@ -58,12 +58,3 @@ pokeb(segment, offset, value) unsigned segment, offset, value; { } - - - - - - - - - diff --git a/libc/msdos/sound.c b/libc/msdos/sound.c new file mode 100644 index 0000000..90c474c --- /dev/null +++ b/libc/msdos/sound.c @@ -0,0 +1,27 @@ + +#include <bios.h> + +static int port_val = -1; + +sound(freq) +unsigned freq; /* freq is in hertz */ +{ + if(port_val == -1 ) + port_val = inp(0x61); + + freq = 1193180L / freq; + + outp(0x61, port_val|3); + outp(0x43, 0xb6); + outp(0x42, freq&0xFF); + outp(0x42, (freq>>8)&0xFF); +} + +nosound() +{ + if( port_val ) + outp(0x61, port_val); + else + outp(0x61, inp(0x61)&~3); +} + diff --git a/libc/msdos/time.c b/libc/msdos/time.c index 271ea05..7f7b183 100644 --- a/libc/msdos/time.c +++ b/libc/msdos/time.c @@ -53,9 +53,10 @@ time_t *timer; rv >>= 8; year = (rv & 0xFFFF) - 1970; if (month <= 1 || year & 3) /* if before Feb or not a leap year */ - day--; /* don't add day for leap year */ + day--; /* don't add day for this leap year */ day += mdays[month]; /* day in year */ - day += (year + 3) >> 2; /* add a day for each leap year */ + day += (year + 3) >> 2; /* add a day for each leap year, but */ + /* don't worry about 2100 */ t += ((year * 365L) + day) * SECSPERDAY; if (timer) *timer = t; |