summaryrefslogtreecommitdiff
path: root/libc/msdos
diff options
context:
space:
mode:
authorRobert de Bath <rdebath@poboxes.com>1999-06-11 14:11:38 +0200
committerLubomir Rintel <lkundrak@v3.sk>2013-10-23 23:41:25 +0200
commit3d4957c86ff239b24b43933924ec72a3fd288518 (patch)
treeda8225a4d7bb2d9123e10d558cdc3eebae6254c8 /libc/msdos
parente62b35169cdcd13632ae353b1e5ffde7dec44201 (diff)
downloaddev86-3d4957c86ff239b24b43933924ec72a3fd288518.tar.gz
Import Dev86src-0.14.8.tar.gzv0.14.8
Diffstat (limited to 'libc/msdos')
-rw-r--r--libc/msdos/Makefile4
-rw-r--r--libc/msdos/TODO8
-rw-r--r--libc/msdos/conio.c14
-rw-r--r--libc/msdos/dirent.c8
-rw-r--r--libc/msdos/dosound.c10
-rw-r--r--libc/msdos/i86.c177
-rw-r--r--libc/msdos/intr.c82
-rw-r--r--libc/msdos/msdos.c47
-rw-r--r--libc/msdos/mslib.c67
-rw-r--r--libc/msdos/new86.c13
-rw-r--r--libc/msdos/sound.c27
-rw-r--r--libc/msdos/time.c5
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;