diff options
70 files changed, 0 insertions, 25635 deletions
diff --git a/usr.bin/Makefile b/usr.bin/Makefile index 229f788..36aeb63 100644 --- a/usr.bin/Makefile +++ b/usr.bin/Makefile @@ -46,7 +46,6 @@ SUBDIR= alias \ dirname \ ${_dnskeygen} \ ${_dnsquery} \ - ${_doscmd} \ du \ ee \ elf2aout \ @@ -267,7 +266,6 @@ _usbhidctl= usbhidctl .if !defined(NO_BLUETOOTH) _bluetooth= bluetooth .endif -_doscmd= doscmd _ncplist= ncplist _ncplogin= ncplogin _smbutil= smbutil diff --git a/usr.bin/doscmd/AsyncIO.c b/usr.bin/doscmd/AsyncIO.c deleted file mode 100644 index aa2ac07..0000000 --- a/usr.bin/doscmd/AsyncIO.c +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI AsyncIO.c,v 2.2 1996/04/08 19:32:10 bostic Exp - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <sys/types.h> -#include <sys/time.h> -#include <errno.h> -#include <fcntl.h> -#include <limits.h> -#include <signal.h> -#include <stdio.h> -#include <unistd.h> - -#include "doscmd.h" -#include "AsyncIO.h" - -#define FD_ISZERO(p) ((p)->fds_bits[0] == 0) - -/* - * Set or Clear the Async nature of an FD - */ - -#define SETASYNC(fd) fcntl(fd, F_SETFL, handlers[fd].flag | FASYNC) -#define CLRASYNC(fd) fcntl(fd, F_SETFL, handlers[fd].flag & ~FASYNC) - -/* - * Request that ``func'' be called everytime data is available on ``fd'' - */ - -static fd_set fdset; /* File Descriptors to select on */ - -typedef struct { - void (*func)(int, int, void *, regcontext_t *); - /* Function to call on data arrival */ - void (*failure)(void *); /* Function to call on failure */ - void *arg; /* Argument to above functions */ - int lockcnt; /* Nested level of lock */ - fd_set members; /* Set of FD's to disable on SIGIO */ - int flag; /* The flag from F_GETFL (we own it) */ -} Async; - -static Async handlers[OPEN_MAX]; - -static void CleanIO(void); -static void HandleIO(struct sigframe *sf); - -void -_RegisterIO(int fd, void (*func)(int, int, void *, regcontext_t *), - void *arg, void (*failure)(void *)) -{ - static int firsttime = 1; - Async *as; - - if (fd < 0 || fd > OPEN_MAX) { -printf("%d: Invalid FD\n", fd); - return; - } - - as = &handlers[fd]; - - if ((as->flag = fcntl(fd, F_GETFL, 0)) == -1) { - if (func) { -/*@*/ perror("get fcntl"); -/*@*/ abort(); - return; - } - } - - if (firsttime) { - firsttime = 0; - setsignal(SIGIO, HandleIO); - } - - if ((handlers[fd].func = func) != 0) { - as->lockcnt = 0; - as->arg = arg; - as->failure = failure; - - FD_SET(fd, &fdset); - FD_ZERO(&handlers[fd].members); - FD_SET(fd, &handlers[fd].members); - if (fcntl(fd, F_SETOWN, getpid()) < 0) { -/*@*/ perror("SETOWN"); - } - SETASYNC(fd); - } else { - as->arg = 0; - as->failure = 0; - as->lockcnt = 0; - - CLRASYNC(fd); - FD_CLR(fd, &fdset); - } -} - -static void -CleanIO() -{ - int x; - static struct timeval tv; - - /* - * For every file des in fd_set, we check to see if it - * causes a fault on select(). If so, we unregister it - * for the user. - */ - for (x = 0; x < OPEN_MAX; ++x) { - fd_set set; - - if (!FD_ISSET(x, &fdset)) - continue; - - FD_ZERO(&set); - FD_SET(x, &set); - errno = 0; - if (select(FD_SETSIZE, &set, 0, 0, &tv) < 0 && - errno == EBADF) { - void (*f)(void *); - void *a; -printf("Closed file descriptor %d\n", x); - - f = handlers[x].failure; - a = handlers[x].arg; - handlers[x].failure = 0; - handlers[x].func = 0; - handlers[x].arg = 0; - handlers[x].lockcnt = 0; - FD_CLR(x, &fdset); - if (f) - (*f)(a); - } - } -} - -static void -HandleIO(struct sigframe *sf) -{ - static struct timeval tv; - fd_set readset, writeset; - int x, fd; - -again: - readset = writeset = fdset; - if ((x = select(FD_SETSIZE, &readset, &writeset, 0, &tv)) < 0) { - /* - * If we failed because of a BADFiledes, go find - * which one(s), fail them out and then try a - * new select to see if any of the good ones are - * okay. - */ - if (errno == EBADF) { - CleanIO(); - if (FD_ISZERO(&fdset)) - return; - goto again; - } - perror("select"); - return; - } - - /* - * If we run out of fds to look at, break out of the loop - * and exit the handler. - */ - if (x == 0) - return; - - /* - * If there is at least 1 fd saying it has something for - * us, then loop through the sets looking for those - * bits, stopping when we have handleed the number it has - * asked for. - */ - for (fd = 0; x && fd < OPEN_MAX; fd ++) { - Async *as; - int cond; - - cond = 0; - - if (FD_ISSET(fd, &readset)) { - cond |= AS_RD; - x --; - } - if (FD_ISSET(fd, &writeset)) { - cond |= AS_WR; - x --; - } - - if (cond == 0) - continue; - - /* - * Is suppose it is possible that one of the previous - * I/O requests changed the fdset. - * We do know that SIGIO is turned off right now, - * so it is safe to checkit. - */ - if (!FD_ISSET(fd, &fdset)) { - continue; - } - as = &handlers[fd]; - - /* - * as in above, maybe someone locked us... - * we are in dangerous water now if we are - * multi-tasked - */ - if (as->lockcnt) { - fprintf(stderr, "Selected IO on locked %d\n",fd); - continue; - } - /* - * Okay, now if there exists a handler, we should - * call it. We must turn back on SIGIO if there - * are possibly other people waiting for it. - */ - if (as->func) { - (*handlers[fd].func)(fd, cond, handlers[fd].arg, - (regcontext_t *)&sf->sf_uc.uc_mcontext); - } else { - /* - * Otherwise deregister this guy. - */ - _RegisterIO(fd, 0, 0, 0); - } - } - /* - * If we did not process all the fd's, then we should - * break out of the probable infinite loop. - */ -} diff --git a/usr.bin/doscmd/AsyncIO.h b/usr.bin/doscmd/AsyncIO.h deleted file mode 100644 index f1c96a1..0000000 --- a/usr.bin/doscmd/AsyncIO.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI AsyncIO.h,v 2.2 1996/04/08 19:32:12 bostic Exp - * - * $FreeBSD$ - */ - -#if defined(__cplusplus) -extern "C" { -#endif -enum { - AS_RD = 1, - AS_WR = 2 -}; - -void _RegisterIO(int, void (*)(int, int, void *, regcontext_t *), - void *, void (*)(void *)); -#if defined(__cplusplus) -} -#endif - -#define _Un_RegisterIO(x) _RegisterIO((x), (void (*))0, (void *)0, (void (*))0) diff --git a/usr.bin/doscmd/Makefile b/usr.bin/doscmd/Makefile deleted file mode 100644 index facebb8..0000000 --- a/usr.bin/doscmd/Makefile +++ /dev/null @@ -1,76 +0,0 @@ -# from BSDI Makefile,v 2.6 1996/04/08 20:06:40 bostic Exp -# -# $FreeBSD$ - -PROG= doscmd -SRCS= AsyncIO.c ParseBuffer.c bios.c callback.c cmos.c config.c cpu.c cwd.c \ - debug.c disktab.c dos.c doscmd.c ems.c emuint.c exe.c i386-pinsn.c \ - int.c int10.c int13.c int14.c int16.c int17.c int1a.c int2f.c intff.c \ - mem.c mouse.c net.c port.c setver.c signal.c timer.c trace.c trap.c \ - tty.c video.c xms.c ${FONTHDRS} -CFLAGS+= -I. -DDISASSEMBLER -FONTFILES= cp437-8x8.pcf.gz cp437-8x14.pcf.gz cp437-8x16.pcf.gz -FONTHDRS= font8x8.h font8x14.h font8x16.h -CLEANFILES= ${FONTFILES} ${FONTHDRS} emsdriv.sys redir.com - -XINCDIR= ${DESTDIR}${X11BASE}/include -XLIBDIR= ${DESTDIR}${X11BASE}/lib - -EXEGRP:= ${BINGRP} -EXEMODE= ${NOBINMODE} -#BINGRP= kmem -#BINMODE= 2555 - -.if !defined(NO_X) && exists(${XINCDIR}/X11/X.h) && exists(${XLIBDIR}/libX11.a) -CFLAGS+= -I${XINCDIR} -LDFLAGS= -L${XLIBDIR} -LDADD= -lX11 -DPADD= ${XLIBDIR}/libX11.a -.else -CFLAGS+= -DNO_X -.endif - -beforeinstall: - ${INSTALL} -o ${BINOWN} -g ${EXEGRP} -m ${EXEMODE} \ - emsdriv.sys redir.com ${DESTDIR}/usr/libdata/doscmd/ - ${INSTALL} -o ${BINOWN} -g ${EXEGRP} -m ${SHAREMODE} \ - ${FONTFILES} ${DESTDIR}/usr/libdata/doscmd/fonts - cd ${.CURDIR} && \ - ${INSTALL} -o ${BINOWN} -g ${EXEGRP} -m ${SHAREMODE} \ - fonts.dir ${DESTDIR}/usr/libdata/doscmd/fonts - -doscmd: ${FONTFILES} ${FONTHDRS} emsdriv.sys redir.com - -cp437-8x8.pcf.gz: cp437-8x8.pcf.gz.uu - uudecode ${.CURDIR}/cp437-8x8.pcf.gz.uu - -cp437-8x14.pcf.gz: cp437-8x14.pcf.gz.uu - uudecode ${.CURDIR}/cp437-8x14.pcf.gz.uu - -cp437-8x16.pcf.gz: cp437-8x16.pcf.gz.uu - uudecode ${.CURDIR}/cp437-8x16.pcf.gz.uu - -emsdriv.sys: emsdriv.sys.uu - uudecode ${.CURDIR}/emsdriv.sys.uu - -font8x8.h: ${.CURDIR}/../../share/syscons/fonts/cp437-8x8.fnt - uudecode -p ${.ALLSRC} | \ - file2c 'u_int8_t font8x8[] = {' '};' > ${.TARGET} - -font8x14.h: ${.CURDIR}/../../share/syscons/fonts/cp437-8x14.fnt - uudecode -p ${.ALLSRC} | \ - file2c 'u_int8_t font8x14[] = {' '};' > ${.TARGET} - -font8x16.h: ${.CURDIR}/../../share/syscons/fonts/cp437-8x16.fnt - uudecode -p ${.ALLSRC} | \ - file2c 'u_int8_t font8x16[] = {' '};' > ${.TARGET} - -redir.com: redir.com.uu - uudecode ${.CURDIR}/redir.com.uu - -# Make sure the library names are defined. We want to specify the full -# path to the standard crt0.o, and building two binaries in one directory -# breaks the automatic generation of dependencies for binaries. -NEED_LIBNAMES= yes - -.include <bsd.prog.mk> diff --git a/usr.bin/doscmd/Makefile.dos b/usr.bin/doscmd/Makefile.dos deleted file mode 100644 index d454834..0000000 --- a/usr.bin/doscmd/Makefile.dos +++ /dev/null @@ -1,48 +0,0 @@ -# Special makefile for the as86/ld86 tools -# -# This is used only to make the dos tools. It is not used in the normal -# build process, except one of the *.S files is changed. The ready to -# use tools are included as uuencoded files. -# To use this makefile you must have Bruce Evans bcc package installed -# -# $FreeBSD$ - -AS86 = as86 -LD86 = ld86 - -OBJS = redir.o emsdriv.o -DOSPROG = redir.com emsdriv.sys -DOSDIST = redir.com.uu emsdriv.sys.uu - -all: ${DOSPROG} ${DOSDIST} - -redir.com: redir.o - $(LD86) -T 0 -s -o ${.PREFIX}.tmp ${.ALLSRC} - dd if=${.PREFIX}.tmp of=${.TARGET} bs=1 skip=288 - rm -f ${.PREFIX}.tmp - -emsdriv.sys: emsdriv.o - $(LD86) -T 0 -s -o ${.PREFIX}.tmp ${.ALLSRC} - dd if=${.PREFIX}.tmp of=${.TARGET} bs=1 skip=32 - rm -f ${.PREFIX}.tmp - -redir.com.uu: redir.com - uuencode redir.com redir.com > redir.com.uu - -emsdriv.sys.uu: emsdriv.sys - uuencode emsdriv.sys emsdriv.sys > emsdriv.sys.uu - -clean: - rm -f ${DOSPROG} ${OBJS} - -allclean: - rm -f ${DOSPROG} ${DOSDIST} ${OBJS} - - -# Rule for as86 -.S.o: - $(AS86) -0 -o ${.TARGET} ${.IMPSRC} - - - - diff --git a/usr.bin/doscmd/PROBLEMS b/usr.bin/doscmd/PROBLEMS deleted file mode 100644 index ba40611..0000000 --- a/usr.bin/doscmd/PROBLEMS +++ /dev/null @@ -1,21 +0,0 @@ -trailing \ missing in tempname (affects PKZIP) - -FCB find routines don't store the state correctly (affects DIR, NUSQ, GET) -support for non-extended FCBs is broken (affects LAR) -wrong device attributes reported after redirection (affects GZIP) -REP IN/OUT not implemented -find_next may not close fd -tty modes wrong when running in terminal session -devices not really implemented - -keyboard queue not fully implemented (affects VSAFE) -several ioctl request not implemented (affects PKZOOM) -no font file -int 0x28 not implemented -timer chip not implemented -country info needs localization - -specific programs: -charc crashes with a segment overrun -sqwez gets a fault while exiting -jrc outputs its banner again on exit, and sometimes complains about aa.aaa diff --git a/usr.bin/doscmd/ParseBuffer.c b/usr.bin/doscmd/ParseBuffer.c deleted file mode 100644 index a053a08..0000000 --- a/usr.bin/doscmd/ParseBuffer.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI ParseBuffer.c,v 2.2 1996/04/08 19:32:15 bostic Exp - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <stdlib.h> -#include <string.h> - -#include "doscmd.h" -int -ParseBuffer(obuf, av, mac) -char *obuf; -char **av; -int mac; -{ - static char *_buf; - char *buf; - static int buflen = 0; - int len; - - register char *b = buf; - register char *p; - register char **a; - register char **e; - - len = strlen(obuf) + 1; - if (len > buflen) { - if (buflen) - free(_buf); - buflen = (len + 1023) & ~1023; - _buf = malloc(buflen); - } - buf = _buf; - strcpy(buf, obuf); - - a = av; - e = &av[mac]; - - while (*buf) { - while (*buf == ' ' || *buf == '\t' || *buf == '\n') - ++buf; - if (*buf) { - p = b = buf; - - *a++ = buf; - if (a == e) { - a[-1] = (char *)0; - return(mac - 1); - } - - while (*p && !(*p == ' ' || *p == '\t' || *p == '\n')) { - *b++ = *p++ & 0177; - } - if (*p) - ++p; - *b = 0; - buf = p; - } - } - *a = (char *)0; - return(a - av); -} diff --git a/usr.bin/doscmd/README b/usr.bin/doscmd/README deleted file mode 100644 index 0201150..0000000 --- a/usr.bin/doscmd/README +++ /dev/null @@ -1,37 +0,0 @@ -/* BSDI README,v 2.2 1996/04/08 19:32:16 bostic Exp*/ -/* $FreeBSD$ */ - -This is the merged doscmd/rundos project. Please read the man -page for help on configuring doscmd. - -Things known not to work: - * No mouse support (yet) - * No raw VGA support (yet) - * Printer support (yet) - * COM ports (being worked on) - * redirected filesystem only supported for DOS 4.0 and above - (3.3 will be supported in a future version) - * Graphics in an X window (only 16 colors, very few programs) - -Even with this, I think it is actually a much better product. There have -been problems reported with the ibmpc font and the distributed X server. -If you have that problem, try setting - - X11_FONT=fixed - -in your .doscmdrc. Be aware that graphics characters will not print correctly -if you do this. - -You will need to patch your kernel. Diffs are provided against the CD-ROM. -Please let me know if there are a problem with them (I am running a pre 1.1 -kernel now). - -It is possible there are some problems in the floppy code due to the fact -that I am not set up to test under 1.0 at this point. I will be in a few -days I hope. - -Please send all bug reports to prb@BSDI.COM. - - -Paul Borman - prb@BSDI.COM - Jan 4 1994 diff --git a/usr.bin/doscmd/README.booting_dos b/usr.bin/doscmd/README.booting_dos deleted file mode 100644 index 41a6804..0000000 --- a/usr.bin/doscmd/README.booting_dos +++ /dev/null @@ -1,98 +0,0 @@ -/* BSDI README.booting_dos,v 2.2 1996/04/08 19:32:18 bostic Exp*/ -/* $FreeBSD$ */ - -To install DOS on a pseudo hard disk under doscmd: - - 1) Create a .doscmdrc with at least the following: - - assign A: /dev/fd0.1440 1440 - assign A: /dev/fd0.720 720 - assign hard boot_drive 80 2 2 - - You may need to adjust the raw files for the A: drive to match - your system. This example will cause the HD drive to be tried - first and the DD drive second. - - Note that you should only use raw devices or files at this point, - do not use a cooked device! (Well, it would probably be okay - for a hard disk, but certainly not the floppy) - - boot_drive should be the file name of where you want your bootable - image to be. The three numbers which follow "80 2 2" say that the - drive will have 80 cylinders, 2 heads and 2 sectors per track. - This is the smallest drive possible which still can have MS DOS - 5.0 installed on it along with a config.sys and autoexec.bat file. - - You might want to create a larger boot drive. - - The file boot_drive must exist, so use the command touch to create - it. - - 2) Insert a floppy disk into the A: drive which is bootable to MS-DOS - and has the commands fdisk, format and sys on it. You should also - copy the file redir.com onto the floppy by either mounting it - with the msdos filesystem type or by using mtools. - - (i.e. mwrite redir.com a:) - - 3) run doscmd. - - 4) At the > prompt type "fdisk" - - 5) Select "Create DOS partition or Logical Drive" - - 6) Select "Create Primary DOS Partition" - - 7) Tell it how big to make it (I say use the whole drive. - It is pretty tiny after all.) - - 8) Get out of FDISK by hitting <ESC> a few times. - - 9) doscmd will now abort (will try and fix this in a future version) - - 10) start up doscmd again, leaving the floppy in the drive. - - 11) At the > prompt, type "format c:" and follow the instructions. - - 12) At the > prompt type "sys c:" - - 13) Get out of doscmd. - - 14) Either remove the floppy from the drive or add the line - - boot C: - - to your .doscmdrc - - 15) You should now be running DOS off of your new disk. You will - probably want both config.sys and an autoexec.bat file. To - start with, you can say: - - > copy con: config.sys - LASTDRIVE=Z - ^Z - > copy con: autoexec.bat - @echo off - redir.com - ^Z - - - 16) Quit doscmd. - - 17) You now have a bootable pseudo disk which will automatically call - the magic "redir" program, which installs FreeBSD disks. To use - them add lines to your .doscmdrc such as: - - assign D: /usr/dos - assign P: -ro /usr/prb - - Note that you will not always be able to access every file due to - naming problems. - - 18) To use the new EMS memory you need to copy the file emsdriv.sys - to your DOS boot disk (disk image) in the same way you copied - redir.com. The use it in your "config.sys" from DOS: - device=C:\emsdriv.sys - where C: is your boot drive (supply the correct letter, if needed) - and emsdriv.sys is the driver. You could load it high. It should - report "Doscmd EMS 4.0 driver installed". diff --git a/usr.bin/doscmd/bios.c b/usr.bin/doscmd/bios.c deleted file mode 100644 index 0577c74..0000000 --- a/usr.bin/doscmd/bios.c +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI bios.c,v 2.3 1996/04/08 19:32:19 bostic Exp - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include "doscmd.h" -#include "mouse.h" -#include "com.h" - -#define BIOS_copyright 0xfe000 -#define BIOS_reset 0xfe05b -#define BIOS_nmi 0xfe2c3 -#define BIOS_hdisk_table 0xfe401 -#define BIOS_boot 0xfe6f2 -#define BIOS_comm_table 0xfe729 -#define BIOS_comm_io 0xfe739 -#define BIOS_keyboard_io 0xfe82e -#define BIOS_keyboard_isr 0xfe987 -#define BIOS_fdisk_io 0xfec59 -#define BIOS_fdisk_isr 0xfef57 -#define BIOS_disk_parms 0xfefc7 -#define BIOS_printer_io 0xfefd2 -#define BIOS_video_io 0xff065 -#define BIOS_video_parms 0xff0a4 -#define BIOS_mem_size 0xff841 -#define BIOS_equipment 0xff84d -#define BIOS_cassette_io 0xff859 -#define BIOS_video_font 0xffa6e -#define BIOS_time_of_day 0xffe6e -#define BIOS_timer_int 0xffea5 -#define BIOS_vector 0xffef3 -#define BIOS_dummy_iret 0xfff53 -#define BIOS_print_screen 0xfff54 -#define BIOS_hard_reset 0xffff0 -#define BIOS_date_stamp 0xffff5 -#define BIOS_hardware_id 0xffffe - -static u_char disk_params[] = { - 0xdf, 2, 0x25, 2, 0x0f, 0x1b, 0xff, 0x54, 0xf6, 0x0f, 8, -}; - -static u_short comm_table[] = { - 1047, 768, 384, 192, 96, 48, 24, 12, -}; - -/* exports */ - -int nfloppies = 0; -int ndisks = 0; -int nserial = 0; -int nparallel = 0; -unsigned long rom_config; - -/* -** BIOS equipment list -*/ -static void -int11(regcontext_t *REGS) -{ - R_AX = - (nfloppies ? 1:0) | /* do we have any floppydisks? */ - (0x2 << 4) | /* 80x25 colour */ - ((nfloppies-1) << 6) | /* how many floppies? */ - (nserial << 9) | /* serial ports? */ - (nparallel << 14); /* parallel ports? */ -} - -/* -** get installed memory -*/ -static void -int12(regcontext_t *REGS) -{ - R_AX = 640; -} - -/* -** assorted oddments -*/ -static void -int15(regcontext_t *REGS) -{ - R_FLAGS &= ~PSL_C; - - switch (R_AH) { - case 0x00: /* Get Cassette Status */ - R_AH = 0x86; - R_FLAGS |= PSL_C; /* We don't support a cassette */ - break; - case 0x04: /* Set ABIOS table */ - R_FLAGS |= PSL_C; /* We don't support it */ - break; - case 0x4f: /* Keyboard intercept */ - debug(D_TRAPS | 0x15, "BIOS: Keyboard intercept\n"); - /* Don't translate scan code. */ - break; - case 0x88: - get_raw_extmemory_info(REGS); - break; - case 0xc0: /* Get configuration */ - debug(D_TRAPS | 0x15, "BIOS: Get configuration\n"); - PUTVEC(R_ES, R_BX, rom_config); - R_AH = 0; - break; - case 0xc1: /* Get extended BIOS data area */ - R_FLAGS |= PSL_C; - break; - case 0xc2: /* Pointing device */ - debug(D_TRAPS | 0x15, "BIOS: Pointing device?\n"); - R_FLAGS |= PSL_C; - R_AH = 5; /* No pointer */ - break; - default: - unknown_int2(0x15, R_AX, REGS); - break; - } -} - -void -bios_init(void) -{ - int i, j, k; - u_char *jtab; - struct timeval tv; - time_t tv_sec; - struct timezone tz; - struct tm tm; - u_long vec; - - strcpy((char *)BIOS_copyright, - "Copyright (C) 1993 Krystal Technologies/BSDI"); - - *(u_short *)BIOS_reset = 0xffcd; - *(u_short *)BIOS_nmi = 0xffcd; - *(u_short *)BIOS_boot = 0xffcd; - *(u_short *)BIOS_comm_io = 0xffcd; - *(u_short *)BIOS_keyboard_io = 0xffcd; - *(u_short *)BIOS_keyboard_isr = 0xffcd; - *(u_short *)BIOS_fdisk_io = 0xffcd; - *(u_short *)BIOS_fdisk_isr = 0xffcd; - *(u_short *)BIOS_printer_io = 0xffcd; - *(u_short *)BIOS_video_io = 0xffcd; - *(u_short *)BIOS_cassette_io = 0xffcd; - *(u_short *)BIOS_time_of_day = 0xffcd; - *(u_short *)BIOS_timer_int = 0xffcd; - *(u_short *)BIOS_dummy_iret = 0xffcd; - *(u_short *)BIOS_print_screen = 0xffcd; - *(u_short *)BIOS_hard_reset = 0xffcd; - *(u_short *)BIOS_mem_size = 0xffcd; - *(u_short *)BIOS_equipment = 0xffcd; - *(u_short *)BIOS_vector = 0xffcd; - *(u_char *)0xffff2 = 0xcf; /* IRET */ - - memcpy((u_char *)BIOS_disk_parms, disk_params, sizeof(disk_params)); - memcpy((u_char *)BIOS_comm_table, comm_table, sizeof(comm_table)); - - *(u_short *)BIOS_video_font = 0xffcd; - - jtab = (u_char *)BIOS_date_stamp; - *jtab++ = '1'; - *jtab++ = '0'; - *jtab++ = '/'; - *jtab++ = '3'; - *jtab++ = '1'; - *jtab++ = '/'; - *jtab++ = '9'; - *jtab++ = '3'; - - *(u_char *)BIOS_hardware_id = 0xfc; /* Identify as a PC/AT */ - - /* - * Interrupt revectors F000:0000 - F000:03ff - */ - for (i = 0, j = 0, k = 0; i < 0x100; ++i) { - if ((i >= 0x60 && i < 0x68) || - (i >= 0x78 && i < 0xe2)) - continue; - if ((i >= 0x00 && i < 0x2f) || - (i >= 0x30 && i < 0xfe)) { - ivec[i] = 0xF0300000L | (k * 1); - jtab = (u_char *)VECPTR(ivec[i]); - *jtab++ = 0xf4; /* HLT */ - ++k; - } else { - ivec[i] = 0xF0000000L | (j * 6); - jtab = (u_char *)VECPTR(ivec[i]); - *jtab++ = 0xcd; /* INT i */ - *jtab++ = i; - *jtab++ = 0xca; /* RETF 2 */ - *jtab++ = 2; - *jtab++ = 0; - ++j; - } - } - - /* - * Misc variables from F000:0400 - F000:0fff - */ - rom_config = 0xF0000400; - jtab = (u_char *)VECPTR(rom_config); - *jtab++ = 20; /* length of entry */ - *jtab++ = 0; - *jtab++ = *(u_char *)BIOS_hardware_id; - *jtab++ = 0x00; /* Sub model */ - *jtab++ = 0x01; /* Bios Rev Enhanced kbd w/3.5" floppy */ - *jtab++ = 0x20; /* real time clock present */ - *jtab++ = 0; /* Reserved */ - *jtab++ = 0; - *jtab++ = 0; - *jtab++ = 0; - strcpy((char *)jtab, "BSDI BIOS"); - *jtab += 10; - - InDOS = jtab++; - *InDOS = 0; - - mouse_area = jtab; - jtab += 0x10; - - *(u_short *)&BIOSDATA[0x10] = - (1 << 0) | /* Diskette avail for boot */ - (1 << 1) | /* Math co-processor */ - (nmice << 2) | /* No pointing device */ - (2 << 4) | /* Initial video (80 x 25 C) */ - ((nfloppies - 1) << 6) | /* Number of floppies - 1 */ - (nserial << 9) | /* Number of serial devices */ - (nparallel << 14); /* Number of parallel devices */ - - - *(u_short *)&BIOSDATA[0x13] = 640; /* Amount of memory */ - BIOSDATA[0x75] = ndisks; /* number of fixed disks */ - - BIOSDATA[0x8F] = 0; - if (nfloppies >= 1) { - BIOSDATA[0x8F] |= 0x04; - BIOSDATA[0x90] = 0x40; - } - if (nfloppies >= 2) { - BIOSDATA[0x8F] |= 0x40; - BIOSDATA[0x91] = 0x40; - } - - gettimeofday(&tv, &tz); - tv_sec = tv.tv_sec; - tm = *localtime(&tv_sec); - *(u_long *)&BIOSDATA[0x6c] = - (((tm.tm_hour * 60 + tm.tm_min) * 60) + tm.tm_sec) * 182 / 10; - - vec = insert_softint_trampoline(); - ivec[0x11] = vec; - register_callback(vec, int11, "int 11"); - - vec = insert_softint_trampoline(); - ivec[0x12] = vec; - register_callback(vec, int12, "int 12"); - - vec = insert_softint_trampoline(); - ivec[0x14] = vec; - register_callback(vec, int14, "int 14"); - - vec = insert_softint_trampoline(); - ivec[0x15] = vec; - register_callback(vec, int15, "int 15"); - - vec = insert_softint_trampoline(); - ivec[0x16] = vec; - register_callback(vec, int16, "int 16"); - - vec = insert_softint_trampoline(); - ivec[0x17] = vec; - register_callback(vec, int17, "int 17"); - - vec = insert_softint_trampoline(); - ivec[0x1a] = vec; - register_callback(vec, int1a, "int 1a"); -} diff --git a/usr.bin/doscmd/callback.c b/usr.bin/doscmd/callback.c deleted file mode 100644 index d5ce428..0000000 --- a/usr.bin/doscmd/callback.c +++ /dev/null @@ -1,119 +0,0 @@ -/* No copyright?! */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/queue.h> -#include "doscmd.h" - -/* -** Callbacks are used for chaining interrupt handlers -** off interrupt vectors -*/ - -struct callback { - LIST_ENTRY(callback) chain; - u_long vec; - callback_t func; - const char *name; -}; - -LIST_HEAD(cbhead , callback) cbhead[127]; - -#define CBHASH(x) (((x) * 17) % 127) - -/* -** Register (func) as a handler for (vec) -*/ -void -register_callback(u_long vec, callback_t func, const char *name) -{ - struct cbhead *head; - struct callback *elm; - - elm = malloc(sizeof(struct callback)); - elm->vec = vec; - elm->func = func; - elm->name = name; - - head = &cbhead[CBHASH(vec)]; - LIST_INSERT_HEAD(head, elm, chain); -} - -/* -** Find a handler for (vec) -*/ -callback_t -find_callback(u_long vec) -{ - struct cbhead *head; - struct callback *elm; - - head = &cbhead[CBHASH(vec)]; - LIST_FOREACH(elm, head, chain) - if (elm->vec == vec) - break; - if (elm) { - debug(D_TRAPS2, "callback %s\n", elm->name); - return (elm->func); - } else - return ((callback_t)0); -} - -u_long trampoline_rover = 0xF1000000; - -/* - * Interrupts are disabled on an INTn call, so we must restore interrupts - * before via STI returning. IRET is not used here because 1) some DOS - * calls want to return status via the FLAGS register, and 2) external - * routines which hook INTn calls do not always put a FLAGS image on the - * stack which re-enables interrupts. - */ -u_char softint_trampoline[] = { - 0xf4, /* HLT */ - 0xfb, /* STI */ - 0xca, /* RETF 2 */ - 2, - 0, -}; -u_char hardint_trampoline[] = { - 0xf4, /* HLT */ - 0xcf, /* IRET */ -}; -u_char null_trampoline[] = { - 0xcf, /* IRET */ -}; - -u_long -insert_generic_trampoline(size_t len, u_char *p) -{ - u_char *q; - u_long where; - - where = trampoline_rover; - q = (u_char *)VECPTR(where); - memcpy(q, p, len); - trampoline_rover += len; - return (where); -} - -u_long -insert_softint_trampoline(void) -{ - return (insert_generic_trampoline( - sizeof(softint_trampoline), softint_trampoline)); -} - -u_long -insert_hardint_trampoline(void) -{ - return (insert_generic_trampoline( - sizeof(hardint_trampoline), hardint_trampoline)); -} - -u_long -insert_null_trampoline(void) -{ - return (insert_generic_trampoline( - sizeof(null_trampoline), null_trampoline)); -} diff --git a/usr.bin/doscmd/callback.h b/usr.bin/doscmd/callback.h deleted file mode 100644 index b1ab3d7..0000000 --- a/usr.bin/doscmd/callback.h +++ /dev/null @@ -1,13 +0,0 @@ -/* -** No copyright?! -** -** $FreeBSD$ -*/ -typedef void (*callback_t)(regcontext_t *); - -void register_callback(u_long, callback_t, const char *); -callback_t find_callback(u_long); -u_long insert_generic_trampoline(size_t, u_char *); -u_long insert_softint_trampoline(void); -u_long insert_hardint_trampoline(void); -u_long insert_null_trampoline(void); diff --git a/usr.bin/doscmd/cmos.c b/usr.bin/doscmd/cmos.c deleted file mode 100644 index 61534b7..0000000 --- a/usr.bin/doscmd/cmos.c +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI cmos.c,v 2.3 1996/04/08 19:32:20 bostic Exp - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include "doscmd.h" - -#define ALARM_ON ((unsigned char) 0x20) -#define FAST_TIMER ((unsigned char) 0x40) -#define SEC_SIZE 1 -#define MIN_SIZE 60 -#define HOUR_SIZE (MIN_SIZE * 60) -#define DAY_SIZE (HOUR_SIZE * 24) -#define YEAR_DAY 365 - -#define SEC_MS 1000000 -#define FAST_TICK_BSD 0x3D00 - -#define Jan 31 -#define Feb 28 -#define Mar 31 -#define Apr 30 -#define May 31 -#define Jun 30 -#define Jul 31 -#define Aug 31 -#define Sep 31 -#define Oct 31 -#define Nov 30 -#define Dec 31 - -static unsigned char cmos_last_port_70 = 0; -static unsigned char cmos_data[0x40] = { - 0x00, /* 0x00 Current Second */ - 0x00, /* 0x01 Alarm Second */ - 0x00, /* 0x02 Current minute */ - 0x00, /* 0x03 Alarm minute */ - 0x00, /* 0x04 Current hour */ - 0x00, /* 0x05 Alarm hour */ - 0x00, /* 0x06 Current week day */ - 0x00, /* 0x07 Current day */ - 0x00, /* 0x08 Current month */ - 0x00, /* 0x09 Current year */ - 0x26, /* 0x0A Status register A */ - 0x02, /* 0x0B Status register B */ - 0x00, /* 0x0C Status register C */ - 0x80, /* 0x0D Status register D */ - 0x00, /* 0x0E Diagnostic status */ - 0x00, /* 0x0F Shutdown Code */ - 0x00, /* 0x10 Drive types (1 FDHD disk) */ - 0x00, /* 0x11 Fixed disk 0 type */ - 0x00, /* 0x12 Fixed disk 1 type */ - 0x00, - 0x00, /* Installed equipment */ -}; - -int day_in_year [12] = { - 0, Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov -}; - -/* consumed by dos.c */ -time_t delta_clock = 0; - -/* locals */ -static struct timeval fast_clock; -static int fast_tick; - -static struct timeval glob_clock; -static int cmos_alarm_time = 0; -static int cmos_alarm_daytime = 0; - -static __inline int -day_in_mon_year(int mon, int year) -{ - return day_in_year[mon] + (mon > 2 && (year % 4 == 0)); -} - -static __inline int -to_BCD (int n) -{ - n &= 0xFF; - return n%10 + ((n/10)<<4); -} - -static __inline int -from_BCD (int n) -{ - n &= 0xFF; - return (n & 0xF) + (n >> 4) * 10; -} - -/* -** inb() from clock ports. -** -** 0x70 is scratchpad/register select -** 0x71 is data -*/ -static unsigned char -cmos_inb(int portnum) -{ - unsigned char ret_val; - int cmos_reg; - struct timezone tz; - struct tm tm; - time_t now; - - switch (portnum) { - case 0x70: - ret_val = cmos_last_port_70; - break; - case 0x71: - cmos_reg = cmos_last_port_70 & 0x3f; - if (cmos_reg < 0xa) { - gettimeofday(&glob_clock, &tz); - now = glob_clock.tv_sec + delta_clock; - tm = *localtime(&now); - } - switch (cmos_reg) { - case 0: - ret_val = to_BCD(tm.tm_sec); - break; - case 2: - ret_val = to_BCD(tm.tm_min); - break; - case 4: - ret_val = to_BCD(tm.tm_hour); - break; - case 6: - ret_val = to_BCD(tm.tm_wday); - break; - case 7: - ret_val = to_BCD(tm.tm_mday); - break; - case 8: - ret_val = to_BCD(tm.tm_mon + 1); - break; - case 9: - ret_val = to_BCD((tm.tm_year + 1900) % 100); - break; - default: - ret_val = cmos_data[cmos_reg]; - break; - } - break; - } - return (ret_val); -} - -static void -cmos_outb(int portnum, unsigned char byte) -{ - int cmos_reg; - int year; - int time00; - struct timezone tz; - struct tm tm; - time_t now; - - switch (portnum) { - case 0x70: - cmos_last_port_70 = byte; - break; - case 0x71: - cmos_reg = cmos_last_port_70 & 0x3f; - if (cmos_reg < 0xa) { - gettimeofday(&glob_clock, &tz); - now = glob_clock.tv_sec + delta_clock; - tm = *localtime(&now); - } - switch (cmos_reg) { - case 0: - delta_clock += SEC_SIZE * (from_BCD(byte) - tm.tm_sec); - break; - case 1: - cmos_alarm_daytime += - SEC_SIZE * (from_BCD(byte) - from_BCD(cmos_data[1])); - break; - case 2: - delta_clock += MIN_SIZE * (from_BCD(byte) - tm.tm_min); - break; - case 3: - cmos_alarm_daytime += - MIN_SIZE * (from_BCD(byte) - from_BCD(cmos_data[3])); - break; - case 4: - delta_clock += HOUR_SIZE * (from_BCD(byte) - tm.tm_hour); - break; - case 5: - cmos_alarm_daytime += - HOUR_SIZE * (from_BCD(byte) - from_BCD(cmos_data[5])); - break; - case 7: - delta_clock += DAY_SIZE * (from_BCD(byte) - tm.tm_mday); - break; - case 8: - delta_clock += DAY_SIZE * - (day_in_mon_year(from_BCD(byte), tm.tm_year) - - day_in_mon_year(tm.tm_mon + 1, tm.tm_year)); - break; - case 9: - year = from_BCD(byte); - delta_clock += DAY_SIZE * (YEAR_DAY * (year - tm.tm_year) - + (year/4 - tm.tm_year/4)); - break; - case 0xB: - cmos_data[0xc] = byte; - if (byte & ALARM_ON) { - debug(D_ALWAYS, "Alarm turned on\n"); - time00 = glob_clock.tv_sec + delta_clock - - (tm.tm_sec + MIN_SIZE * tm.tm_min - + HOUR_SIZE * tm.tm_hour); - cmos_alarm_time = time00 + cmos_alarm_daytime; - if (cmos_alarm_time < (glob_clock.tv_sec + delta_clock)) - cmos_alarm_time += DAY_SIZE; - } - if (byte & FAST_TIMER) { - debug(D_ALWAYS, "Fast timer turned on\n"); - fast_clock = glob_clock; - fast_tick = 0; - } - break; - } - cmos_data[cmos_reg] = byte; - break; - } -} - - -void -cmos_init(void) -{ - int numflops = 0; - int checksum = 0; - int i; - - cmos_data[0x0e] = 0; - - numflops = nfloppies; - cmos_data[0x10] = (search_floppy(0) << 4) | search_floppy(1); - - if (numflops) /* floppy drives present + numflops */ - cmos_data[0x14] = ((numflops - 1) << 6) | 1; - - cmos_data[0x15] = 0x80; /* base memory 640k */ - cmos_data[0x16] = 0x2; - for (i=0x10; i<=0x2d; i++) - checksum += cmos_data[i]; - cmos_data[0x2e] = checksum >>8; /* High byte */ - cmos_data[0x2f] = checksum & 0xFF; /* Low byte */ - - cmos_data[0x32] = 0x19; /* Century in BCD ; temporary */ - - for (i = 1; i < 12; i++){ - day_in_year[i] += day_in_year[i-1]; - } - - define_input_port_handler(0x70, cmos_inb); - define_input_port_handler(0x71, cmos_inb); - define_output_port_handler(0x70, cmos_outb); - define_output_port_handler(0x71, cmos_outb); -} diff --git a/usr.bin/doscmd/com.h b/usr.bin/doscmd/com.h deleted file mode 100644 index 495ca88..0000000 --- a/usr.bin/doscmd/com.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI com.h,v 2.2 1996/04/08 19:32:21 bostic Exp - * - * $FreeBSD$ - */ - -/* com.h for doscmd int14.c */ - -/* NS16550A register definitions */ - -/* interrupt enable register */ - -#define IE_NOP 0xF0 /* Not used */ -#define IE_MODEM_STAT 0x08 /* modem status int. */ -#define IE_LINE_STAT 0x04 /* receiver-line status int. */ -#define IE_TRANS_HLD 0x02 /* transmitter holding register empty int. */ -#define IE_RCV_DATA 0x01 /* received data available int. */ - -/* interrupt identification register */ - -#define II_FIFOS_EN 0xC0 /* if FIFOs are enabled */ -#define II_NOP 0x30 /* not used */ -#define II_INT_ID 0x0E /* mask: bits see below */ -#define II_PEND_INT 0x01 /* 1=no interrupt pending */ - -/* bit masks for II_INT_ID */ - -#define II_TO 0x0C -#define II_LINE_STAT 0x06 -#define II_RCV_DATA 0x04 -#define II_TRANS_HLD 0x02 -#define II_MODEM_STAT 0x00 - -/* FIFO control reg */ - -#define FC_FIFO_SZ_MASK 0xC0 -#define FC_FIFO_1B 0x80 -#define FC_FIFO_4B 0x40 -#define FC_FIFO_8B 0x80 -#define FC_FIFO_14B 0xC0 -#define FC_FIFO_CTR 0x04 -#define FC_FIFO_CRV 0x02 -#define FC_FIFO_EN 0x01 - -/* line control register */ - -#define LC_DIV_ACC 0x80 /* divisor latch access bit */ -#define LC_BRK_CTRL 0x40 /* set break control */ -#define LC_S_PAR 0x20 /* stick parity */ -#define LC_EVEN_P 0x10 /* even parity select */ -#define LC_PAR_E 0x08 /* parity enable */ -#define LC_STOP_B 0x04 /* number of stop bits (0 - 1 bit) */ -#define LC_W_LEN 0x03 /* unsigned short length (00 - 5, 01 - 6 etc.) */ - -/* line status register */ - -#define LS_NOP 0x80 /* not used */ -#define LS_X_DATA_E 0x40 /* 1=empty */ -#define LS_X_HOLD_E 0x20 /* 1=empty */ -#define LS_BREAK 0x10 /* break received */ -#define LS_FRM_ERR 0x08 /* framing error */ -#define LS_PAR_ERR 0x04 /* parity error */ -#define LS_OVRN_ERR 0x02 /* overrun error */ -#define LS_RCV_DATA_RD 0x01 /* data received */ - -/* modem status register */ - -#define MS_DCD 0x80 /* Data Carrier Detect in */ -#define MS_RI 0x40 /* Ring Indicator in */ -#define MS_DSR 0x20 /* Data Set Ready in */ -#define MS_CTS 0x10 /* Clear To Send in */ -#define MS_DELTA_DCD 0x08 /* Data Carrier Detect changed state */ -#define MS_DELTA_RI 0x04 /* Ring Indicator changed state */ -#define MS_DELTA_DSR 0x02 /* Data Set Ready changed state */ -#define MS_DELTA_CTS 0x01 /* Clear To Send changed state */ - -/* DOS definitions -- parameters */ - -#define BITRATE_110 0x00 -#define BITRATE_150 0x20 -#define BITRATE_300 0x40 -#define BITRATE_600 0x60 -#define BITRATE_1200 0x80 -#define BITRATE_2400 0xA0 -#define BITRATE_4800 0xC0 -#define BITRATE_9600 0xE0 -#define PARITY_NONE 0x00 -#define PARITY_ODD 0x08 -#define PARITY_EVEN 0x18 -#define STOPBIT_1 0x00 -#define STOPBIT_2 0x04 -#define TXLEN_7BITS 0x02 -#define TXLEN_8BITS 0x03 - -#define N_OF_COM_REGS 8 - -/* DOS definitions -- return codes */ - -#define LS_SW_TIME_OUT LS_NOP /* return value used by DOS */ - -/* routine declarations */ - -void int14(regcontext_t *REGS); -void init_com(int, char *, int, unsigned char); - -/* end of file com.h */ diff --git a/usr.bin/doscmd/config.c b/usr.bin/doscmd/config.c deleted file mode 100644 index bb43a1f..0000000 --- a/usr.bin/doscmd/config.c +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI config.c,v 2.2 1996/04/08 19:32:22 bostic Exp - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/types.h> -#include <sys/uio.h> -#include <ctype.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> - -#include "doscmd.h" -#include "com.h" -#include "cwd.h" -#include "tty.h" -#include "video.h" - -/* -** doscmdrc parser -*/ -int -read_config(FILE *fp) -{ - char *buffer; - char _buffer[1024]; - char *_av[16]; - char **av; - int ac; - int bootdrive = -1; - - while ((buffer = fgets(_buffer, sizeof(_buffer), fp)) != 0) { - char *comment = strchr(buffer, '#'); - char *equal; - - if (comment) - *comment = 0; - - while (isspace(*buffer)) - ++buffer; - if (!*buffer) - continue; - - /* - * Strip <CR><LF> - */ - comment = buffer; - while (*comment && *comment != '\n' && *comment != '\r') - ++comment; - *comment = 0; - - /* - * Check to see if this is to go in the environment - */ - equal = buffer; - while (*equal && *equal != '=' && !isspace(*equal)) - ++equal; - - if (*equal == '=') { - if (strncmp(buffer, "MS_VERSION=", 11) == 0) - setver(0, strtol(equal + 1, 0, 0)); - else if (strncmp(buffer, "X11_FONT=", 9) == 0) - xfont = strdup(equal + 1); - else - put_dosenv(buffer); - continue; - } - - ac = ParseBuffer(buffer, av = _av, 16); - - if (ac == 0) - continue; - if (!strcasecmp(av[0], "assign")) { - int drive = -1; - int printer; - int ro = 0; - - if (ac < 2) { - fprintf(stderr, "usage: assign device ...\n"); - quit(1); - } - if (av[2] && !strcasecmp(av[2], "-ro")) { - av[2] = av[1]; - av[1] = av[0]; - ++av; - --ac; - ro = 1; - } - if (!strncasecmp(av[1], "lpt", 3)) { - if (av[1][3] < '1' || av[1][3] > '4' - || av[1][4] != ':' || ac < 3) { - fprintf(stderr, "usage: assign lptn: [direct] lpr-name [ time-out]\n"); - quit(1); - } - printer = av[1][3] - '1'; - if (strchr(av[2], '/')) { - printer_direct(printer); - printer_spool(printer, av[2]); - } else if (!strcasecmp(av[2], "direct")) { - printer_direct(printer); - printer_spool(printer, 0); - } else { - printer_spool(printer, av[2]); - if (ac == 4) - printer_timeout(printer, av[3]); - } - } else if (!strncasecmp(av[1], "flop", 4)) { - if (ac != 4) { - fprintf(stderr, "usage: assign flop [-ro] file type\n"); - quit(1); - } - - if (isdigit(av[1][4])) { - drive = atoi(&av[1][4]) - 1; - } else if (isalpha(av[1][4]) && av[1][5] == ':' && !av[1][6]) { - drive = drlton(av[1][4]); - } -init_soft: - drive = init_floppy(drive, atoi(av[3]), av[2]); - if (ro) - make_readonly(drive); - } else if (!strncasecmp(av[1], "hard", 4)) { - int cyl, head, sec; - - if (isdigit(av[1][4])) { - drive = atoi(&av[1][4]) + 1; - } else if (isalpha(av[1][4]) && av[1][5] == ':' && !av[1][6]) { - drive = drlton(av[1][4]); - } - -init_hard: - switch (ac) { - default: - fprintf(stderr, "usage: assign [A-Z]: [-ro] directory\n" - " assign hard [-ro] file type [boot_sector]\n" - " assign hard [-ro] file cylinders heads sectors/track [boot_sector]\n"); - quit(1); - case 5: - case 4: - if (!map_type(atoi(av[3]), &cyl, &head, &sec)) { - fprintf(stderr, "%s: invalid type\n", av[3]); - quit(1); - } - drive = init_hdisk(drive, cyl, head, sec, av[2], av[4]); - if (ro) - make_readonly(drive); - break; - case 7: - case 6: - drive = init_hdisk(drive, atoi(av[3]), atoi(av[4]), atoi(av[5]), - av[2], av[6]); - if (ro) - make_readonly(drive); - break; - } - } else if (av[1][1] == ':') { - if (av[1][2] || !isalpha(av[1][0])) { - fprintf(stderr, "usage: assign [A-Z]: ...\n"); - quit(1); - } - drive = drlton(av[1][0]); - - if (ac == 3) { - init_path(drive, (u_char *)av[2], 0); - if (ro) - dos_makereadonly(drive); - } else if (drive < 2) - goto init_soft; - else - goto init_hard; - } else if (!strncasecmp(av[1], "com", 3)) { - int port; - int addr; - unsigned char irq; - - if ((ac != 5) || (!isdigit(av[1][3]))) { - fprintf(stderr, "usage: assign com[1-4] path addr irq\n"); - quit(1); - } - port = atoi(&av[1][3]) - 1; - if ((port < 0) || (port > (N_COMS_MAX - 1))) { - fprintf(stderr, "usage: assign com[1-4] path addr irq\n"); - quit(1); - } - errno = 0; - addr = (int)strtol(av[3], '\0', 0); - /* XXX DEBUG ISA-specific */ - if ((errno != 0) || (addr > MAXPORT)) { - fprintf(stderr, "usage: assign com[1-4] path addr irq\n"); - quit(1); - } - errno = 0; - irq = (unsigned char)strtol(av[4], '\0', 0); - /* XXX DEBUG ISA-specific */ - if ((errno != 0) || (irq < 2) || (irq > 7)) { - fprintf(stderr, "usage: assign com[1-4] path addr irq[2-7]\n"); - quit(1); - } - init_com(port, av[2], addr, irq); - } else { - fprintf(stderr, "usage: assign flop ...\n"); - fprintf(stderr, " assign hard ...\n"); - fprintf(stderr, " assign [A-Z]: ...\n"); - fprintf(stderr, " assign comX ...\n"); - quit(1); - } - } else if (!strcasecmp(av[0], "boot")) { - if (ac != 2 || av[1][2] || !isalpha(av[1][0])) { - fprintf(stderr, "usage: boot [A: | C:]\n"); - quit(1); - } - bootdrive = drlton(av[1][0]); - if (bootdrive != 0 && bootdrive != 2) { - fprintf(stderr, "Boot drive must be either A: or C:\n"); - quit(1); - } - } else if (!strcasecmp(av[0], "portmap")) { - int p, c; - if (ac < 2 || ac > 3 || !isdigit(av[1][0]) || - (ac == 3 && !isdigit(av[2][0]))) { - fprintf(stderr, "usage: portmap port [count]\n"); - quit(1); - } - p = strtol(av[1], 0, 0); - c = (ac == 3) ? strtol(av[2], 0, 0) : 1; - iomap_port(p, c); - - while (c-- > 0) { - define_input_port_handler(p++, inb_port); - define_output_port_handler(p++, outb_port); - } - } else if (!strcasecmp(av[0], "setver")) { - int v; - if (ac != 3 || !(v = strtol(av[2], 0, 0))) { - fprintf(stderr, "usage: setver command version\n"); - quit(1); - } - setver(av[1], v); - } else { - fprintf(stderr, "%s: invalid command\n", av[0]); - quit(1); - } - } - fclose(fp); - return(bootdrive); -} diff --git a/usr.bin/doscmd/cp437-8x14.pcf.gz.uu b/usr.bin/doscmd/cp437-8x14.pcf.gz.uu deleted file mode 100644 index cd2f122..0000000 --- a/usr.bin/doscmd/cp437-8x14.pcf.gz.uu +++ /dev/null @@ -1,113 +0,0 @@ -$FreeBSD$ - -begin 644 cp437-8x14.pcf.gz -M'XL(`,8!X#H``^V<?WR55WW'/T!+8W^F:#52A$AKC6CK/4]N;FXHXS>4L!8H -MI2W%3E)"*<7^R*"S*83\),DE=!K1:63315:W#-UDN+D,UPVI<QFZC;'-13I= -MQIQEZ%K&YA89$S_GGN_)/7EXGN<^]];])5]>[W.?7^?[/<\YW^_WG.>YETS8 -M5-_P!@`3R$12SHT^V9[([8W\'.3G%;)?<B4PC2=+Y)JR.<"M5P&ESODYBZA' -MSI>R6+P,F"_[)52T9CG0*OO]UP`/KS`-L/8N/&3.70N1Y\DU>N-Z\F:]08VX -MQ6XD['5SM9ZE<G3"`RR>UAO/L&C1YZ\F77JCGGQ$;URD[-,;^GX^2U:MK%VQ -M9OU]M>N68%7MVB5WF\W52^Y;>??]:VI7KEB_UMUY"`L>6+)ZP5U+UC]8NWC- -M,MRW:L&BVA5W81'6K[UGX>*E2Q:OKUVQ="66;'S\F4<WEC_[^#.;RQN?W+!Q -M$W>2=R3OP-*5*]:@OB%967U[NE$E\>"2VKN6K7%,8.WZ9>;8O?<O6"QFI*\G -M3(#^E^VGB;8/>"<E[*Q)EVSKO8L71R_JL1Q_/$RT#4QHS63V=%PN+A>7B\O% -MSV`AN76"R8EITD`&R(B>_WA\%<F0(V24)%AA,^DGPZ24B789:26#Y"RIX#Q8 -M1_K(\2O,O#F?-)*#Y#0IGPRL);UDB(#S;)HTD`$R0LHX<:TB&7*$C)($)_3- -MI)\,DU+.>\M(*QDD9TD%Y],ZTD>.DQ).(O-)(SE(3I/RZVB?])*AZ\STFR8- -M9(",D+(;:)]DR!$R2A)<#&PF_628E-Y(^Z25#)*SI&(*[9,^<IR4O)'V22,Y -M2$Z3\C?1/NDE0P0WT3YI(`-DA)1Q.;"*9,@1,DH2;Z%]TD^&26D9[9-6,DC. -MDHJWTC[I(\=)R53:)XWD(#E-RF^F?=)+A@BFT3YI(`-DA)2]C?9)AAPAHR0Q -MG?9)/QDFI3-HG[2207*65'"!5$?ZR'%2\G;:)XWD(#E-RF?2/NDE0S/-BB=- -M&L@`&2%EM](^R9`C9)0DWD'[I)\,D]+;:)^TDD%REE2\D_9)'SE.2BIHGS22 -M@^0T*7\7[9->,D0PB_9)`QD@(Z3LW;1/,N0(&26)]]`^Z2?#I/1VVB>M9)"< -M)15WT#[I(\=)R7MIGS22@^0T*>?";BWI)4-ZD:=HGS20`3)"RCS:)QERA(R2 -M1"7MDWXR3$J3M$]:R2`Y2RJJ:)_TD>.D)$7[I)$<)*=)>37MDUXR5"W+SVE. -M$GB=TDS:8-:=;<*+Y).RW1Q1C\LXO"R?FI?(*[(=5D\+;RN[%G;1RV9]6R41 -M]4KDFKD%U&&888[PBD.9<RZJGKU/>T_YZH79+@NYYF(`NGTO87Q_^O&+MK&) -M+!0VA;31KT?;T&/](G+C_E*$O488MUM+[B9,+:ATF!YRG[9]%MLG;I\&R07R -M#?F\UD&'`=.\GHX"Y<?D:\ZGY7LP??H8"7KVL&UY&3F?F2/[4>V<(/IT>YA: -ML_XY0_8G86SJOD3FDSJ8/FV2>DVR7R?G@\3USS*'9D3[VZ80X-OVB^['EQV^ -M0X9]^$7'IW[*U<L&':<IV:^7;7TL(?MS0^SZQ<T901*G7X)R4U@]ES![0>0; -M![=^0NXG$>-Z*SH&)DN]R7#>4\2020YA_>@7O?2Q>3LE^_G$YFN;LVW>SF?3 -MG1-LCL^7YXL5-T?;\2ISS@6-AQLWMQ9H+X7Q_1BT[V^?QL;2(IAQT_MUY!'D -MXB?*3Q?)==;'KI7VUX=<;^/5QNE3Y$[D\OQ3`77<_#PY1&^8N.WR8V,D2-SS -M?JR^*+%ST47DYJ@XXL9Y5+_'U1.GK5KBQFL<FT$R'\:OW/[38QDUAVFQ_KF- -M[(!YZ?D8<OD^++]K&]J_IN/2'!J6JUU[06W5Q\/ZR:VGF>-L1[53VTC+]3HF -M*I'+V9K&D'KZ&C??SHMI;QIR_6[KU2-_?[8@N%]<@L3VBZL_CCW_=<W._6G[ -M8>M!(-@/X\125+VP^[/M<?W$S1UU>6QJ:0[9#I(@_7[[0>+VI[T^WWSDK[?# -M0>=L.U\$B9VCW;59"\:/:9!H?W3GP;F^_7DA]6R.M?.891'"GUFTS)`V!JU= -M4W(^2%KD&OV-C/[69KI\+I7C87DBK-YDX88"[D^/0[T<?SBD7KT/_QB$C8.[ -M9@DBK#]UO@J:,_,]QSV&7)^GY#J[O4G.!XGNK\D!Y!L'?=_/(K<F_`#B]4N] -MM.5IJ:?'8%N,>OY8<+%KH2`)B@?W/L/\Q9\_Z^4>=\@Y/29!KWF"[+GQ$38. -MKCW[7)9PCH7EB69A'0KSLZ!^C#.OA%UOQR#L62"H+S7V><*_OO;7L_HMKB\$ -MB3\7^>,QK%]L?"N,GQ/L.CTL'N8@>(UL";/GOI_POT*L0_A[!JTO*$]8_/;\ -M\\G_E]AW4NXSPNL5G<OT/6D_B7K.T:+[T<:VS8'^>,PG-A;M/!$5#VF,[W.[ -M!LW7SB![=DV:;_VI;=R&7/Z*D\]<><K71IO/@N87MS]34M?MS[!\YJZ)IB%^ -M7JI#;LW7X.Q;W'@.:Z>=!]WQ#VMG4-OBM-,5_?K?SH&6.#%V)R[-4W&><X/F -MICA^[;?GSH51?A/F+U'/5]:>]9="_-/>G\Z':43?G\YK-M?,P_B<^X34SR>5 -M`<2)V[`Y)I\$S8%A\Y^_GCL/QLWE?E^QSX)Z_,+6YY!VZ;YPWTN%S7\-&!\W -MU_OVP[X2"WJ7&^?];I!^O_T@L>_+BI6PY[(P"7KN<)^I[#.HW[^M'[K;^?S3 -M_VXM[KSBWI.60N9;MYUQZ[G/X(74LVV<5F`]5^QXV'G"'8.H-1-0V#SM]DO< -M>OY^*<2>.W?$G6_M\4+K^=L9MYZ-EWSO-ESQCWG<>O[W.?:]@=ZW\UY4/K-B -M?4K/)3IOWBQ\,.3Z)HQ?`[9@?-QN"Z@3YF>%/(\54B_,S_+5TW7L]\I`_+SD -MMU?(?.O>7]0\-CV@3M@[@[#W!5&VHOK%]7EWK>-_[O1+OK6\7K.&O:_SKSF: -M?9]!]O1<;_M;;]\BVSN<XT'K"3VW#F-\?`=]'ZOCPIUW_3$8-U_[Y[%"\IEK -M+ZY?^^L5XI_N>B+.>MZ]7K<GZEV87^SSI:9)CN5[WZW%_YVAEKC?Z[O?3;C? -M(1;RW*'%_WU+7-'UZC#^N=`O[G.Z'JN;G7;JOM;?Q5J?:HI13X^9'H?GY/H@ -MVT'K5?_WU5&BYY.4V$S)?AQQK[?U@R1#9A;Q>8#<7\3GE\FK17Q&/7L7RXPB -MKX^J]T0$3T><BY*6`NL5VT[=OKH\[2R6L/LJQIYM9]2:+*I^5+U\XUZ,%.IG -MEM$"VVD)^GUA'+GX.MH9=BZ?O3#)=W_%M"^JG5'^\H,\YX.NU_/#A3SW[Q?[ -M&\E"[;TF]0L==WO]:T7>7U0[H^Q%M3/J_J+:&14'A=JS%-N?4?Z9KWXQN37* -MS_+%0R$2)XZBY$*1]Q?5+U'YH=A\5FR>C^J7H-^`QR%*HNK=4"1GBZ38>P@2 -M^^QCWZ'8[P>BQ#[#N;^STMMV[3[1=[W[/FA2"%'B__VG2]CUVI;[CN-:Y/^] -MFRON>R5+V/MK*_YG3/>[G*A[M&,0-\;M<W[4_Q,(DJCW=%&_UPAZ9^..P;,A -M]1HQ_G==30'MS2?Z7NSOZ/,]5Q^!6:NZ=?Y:]J/&((V<?[CO(JW_I"-L!KW/ -M<`F3EAC;06+](NB=4EC\NV-0ATO?Y83U:]1O`*/JV7=3PX@W!^0C3ORY?=$< -M<"Q*W/<_^;Z+"GIO4ZS$;5]8W2C1\T30;U#T]^*Z[3KV@OS:OLN(DV==N1[C -MW_&\$87/[7-#^&F)_'V$UDPKR>R6HCN3R18MN6/M79FNYNQ_)F[KSG2WF/]; -MW,T3;=UCU5BT6052M/DNZ<[TM+/HR!YK<\Y2:;,MNL:VV()LH=O'%F0O[MEN -MU>_1JKK%T"Z>R%Z2+6BMNUFWM+F],]/1QDLZFSHZ,^W9BUM:7;NQ"M;-M%!5 -M9NR.NIH+4I`K3/OB7=SFZ\F@Z]H"--NM/<^UZG:SX7L:=<>.51NW)1=WM>?J -M:J7MXU1U^8KVL<*OKRWD8M-2]J33YN=:L]XT9DT[R%CA[NJQ;/.=L$/!K2ZG -MVIZQHGN\%I]Z<ZQ]G(T>1[,YD3$>VZ,[PE_7&-+5FG0+FNRQSA9;F+KMMA/% -MQ]O&__=\=@FW<D6W*7;IW2ZSVR['S.Y.4W2:8E='1T9O26%VM>9=.XUZ7;3; -M8B>+K@Y[<9<YH;=VCC5H9^YL5E^V6H<4V1J[W+\PT&E.Y(YQ:Q>W=ME+FJP? -M=(\-<FYDS(FV[+&V(,_.F,2S6P^R+S=EG/S"%NS.MD7O9O,&^YF#LIV]V[F3 -M1;8W>K2W<Z`ZS9!UF]1BU^>YU<($'IF$*W`E,_=5*,$;<#6N82:_CEG]!I3B -M1DQA/G\3;L*;\1;./&_%5.;Z:7@;IC/'E^/MF(E;<"O>@=OP3E3@79B%=^,] -MN!UWX+V<=10\5"*)*LXDU9QU:C";<^P<_!RS^SS,QP(LQ"(LQA(LQ5U8AEHL -MQ\_C;MR#%5B)5;@7JW$?UN!^/(`'L18/81W>AX?Q"W@_UG-%\P@V<*VU$8]R -M5?D8-N-Q;,$'^,3Z)&?SI[D:^45LQ38\@U_"![E6;<1SV(X=7(WNY$JA!:UH -M0SLZL`N=Z$(W,MB-'NS!\_AE?`@?1B\^@KWX*#Z&7\''\0GTX9/8AU_%K^%3 -M^#1^'?WX#/;C-_`"/HO?Q&]A`+^-`_@</H_?P>_B"SB(W\,A?!&_CS_`E_"' -M&,0?X3"^C#_&B_@3_"E7K5_!4;R$K^+/\#7\.8;P%SB&K^,;^$O\%=>OQ_$W -M.(&_Q=_A[_%-_`-75=_"2:YM_Q'?QG?P3QC!/^,4_@7?Q;_B>W@%I_%O.(/O -MXP?X=[R*U[@2^`^<PW_BO_!#_#?^AT_./\)Y_"\NX/_PXZP7V+^7\<)E+G.9 -MGUG<OYMCG_>FP#QKZ-\)Z/^_.POF.<(^0^C?S2TG]\+\G8/U,,_V3Q+]=]ST -M]^?M9#?I)9\@GX;Y&QJ?)U\DA\E7R!#,\_HWR;?)=\GWR3GR(VG;5>1Z<A.9 -M1FXALX@B:3*/+"7WD#7D?60#>9PTD&=),^DDSY./DGWD,V2`?(%\B;Q(ODJ^ -M3DZ0;Y$1\@IYE?R07""3V&E7DQM)&9E!;B.WDR2YDRPDM605>9"\GSQ*GB#; -MR';21C+DP^3CY%/D!?(Y<H@<)D?),7*"G"2GR!ERCIPG$R>Q+60*F4IFDEG$ -M([/)0K*<K";KR`:RA6PEVTD[Z2%[R3ZRGQP@A\AA<I0<(R?(27**G"'GR'DR -M\0K:)U/(5#*3S"(>F4T6DN5D-5E'-I`M9"O93MI)#]E+]I']Y``Y1`Z3H^08 -M.4%.DE/D##E'SI.)5](^F4*FDIED%O'(;+*0+">KR3JR@6PA6\EVTDYZR%ZR -MC^PG!\@A<I@<)<?("7*2G")GR#ERGDQDT%Q-II"I9":913PRFRPDR\EJLHYL -M(%O(5K*=M),>LI?L(_O)`7*('"9'R3%R@IPDI\@9<HZ<)Q.OHGTRA4PE,\DL -MXI'99"%93E:3=60#V4*VDNVDG?20O:1^\R-;$]E294LO6U9FRV2VK,J6J6Q9 -MG2W3V;+&U)+*IK8RU96IKXP"930HHT(9'<HH44:+9[1XT@:CQ3-:/*/%,UH\ -MH\4S6CRCQ3-:*HV62J.E4F[%:*DT6BJ-EDJCI=)HJ31:*HV6I-&2-%J21DM2 -M>L1H21HM2:,E:;0DC9:DT5)EM%09+55&2Y714B4=:[14&2U51DN5T5)EM*2, -MEI31DC):4D9+RFA)R?@8+2FC)66TI(R6:J.EVFBI-EJJC99JHZ7::*F6839: -MJHV6:J,E;;2DC9:TT9(V6M)&2]IH21LM:?$6HR5MM-08+35&2XW14F.TU!@M -M-49+C=%28[34B--9KQ.W2XC?)<3Q$N)Y"7&]A/A>0IPO(=Z7$/=+B+XQ-Q9] -MUI&M)UM7MKYLG=EZLW5G\6<E#JT\&Q>B3WQ:B5,K\6HE;JW$KY4XMA+/5N+: -M2GQ;5=I`$WWBWDK\6XF#*_%P)2ZNQ,>5.+D2+U?BYBII(U?TB:<K<74EOJ[$ -MV95XNQ)W5^+O2AQ>B<>K*IL*1)\XO1*O5^+V2OQ>B>,K\7PEKJ_$]Y4XOTK9 -MW"+ZQ/^5!("2"%`2`DIB0$D0*(D")6&@)`Y4M4U6HD]"04DL*`D&)=&@)!R4 -MQ(.2@%`2$4I"0J5M]A-]$A5*PD))7"@)#"61H20TE,2&DN!0$AVJQJ93FT\E -MH4I\>!(?GL2')_'A27QX$A^>Q(<G\>%)?'C*)FC1)_'A27QX$A^>Q(<G\>%) -M?'@2'Y[-]S;ACV5\T6=SODWZ-NO;M&_SODW\$A^>Q(<G\>%5VBE$]$E\>!(? -MGL2')_'A27QX$A^>Q(<G\>%)?'A).R>)/HD/3^+#D_CP)#X\B0]/XL.3^/`D -8/CR)#Z_*3G)5^.G]#>&?`*T-&*=$6@`` -` -end diff --git a/usr.bin/doscmd/cp437-8x16.pcf.gz.uu b/usr.bin/doscmd/cp437-8x16.pcf.gz.uu deleted file mode 100644 index 8071221..0000000 --- a/usr.bin/doscmd/cp437-8x16.pcf.gz.uu +++ /dev/null @@ -1,113 +0,0 @@ -$FreeBSD$ - -begin 644 cp437-8x16.pcf.gz -M'XL("#J#2SD``V-P-#,W+3AX,38N<&-F`.V=?9Q51WG'?T`"A,204*,(")'$ -MF*").V=W[^X2A!O>`I@`(<0@6MFPA"3D#4D:"&QVSRZ[[.6EOF#K"ZTV4FTM -MVMIB:UMLVB.QUJ)M+6UM)-5::DV+-K%4:Z2I]#=GGMD[]^QYO9?V'WGR^<X] -M<^]YGIDS\SSSMI>;41N[-E\$8!0937Y`/BC7H_GF!K[NX^L%DA]_(?!]_2KW -M3%X(O#@6N,SY_+(W`U?*YY<QF;P2*$M^/`U=NPKP)?_DQ4#36TP%;'E?O<M\ -M-@$B3Y*+(>],TA?WD%?K"Q:%6?:B35^,@REMU!(FR_3%&B;OU!>/,>G3]XP/ -MS>XC*U<L7;YZW>U+UR["G8N6WKQD-58MNGW%+7>L7KIBN7.Y;HV;>2O6K%MB -M[KY]Y4T+EBZ_&2NQ;LVM\Q<N7K1PW=+EBU=@T8;['KU[PY5;[WOTWBNW/;A^ -MPT9F6FYHN0&+5RQ?C:[-+<UMU[=O4R7<=L=-"]?=N73AZB7A\X\*!;@$ILV- -MC.=_ETC>O=:YLV=_=%;?6_M^DN@R,,JO5/8-G$_.)^>3\\E/86+FEW#2D]E" -MST>!O%<F/@ED4BP3GP1::0SSQ"?!&#-(EXE/`CWX<OXK$Y\$!)P;R\0GP5@S -M/96)3X)Q9BHJ$Y\$!)R,R\0GP45FRBL3GP03S#Q8)CX)])S(B:),?!+H2>-E -MS!.?!`27,D]\$A!,9)[X))B(<.(N$Y\$>A*_G'GBD^!R,]V6B4\"/?7^#//$ -M)P'!RYDG/@D(KF">^"0@>`7SQ"<!P2N9)SX)""8S3WP2$+R*>>*3@&`*\\0G -M`<%4YHE/`H)IS!.?!-/,JJ!,?!+H%<)TYHE/`H(9S!.?!$0O5,K$)P'!:Y@G -M/@D(9C)/?!(07,4\\4E`<#7SQ"<!P6N9)SX)"*YAGO@D('@=\\0G`<&US!.? -M!`37,4]\$EQG%C=EXI-`+W1>SSSQ24#P!N:)3P*"ZYDG/@D(;F">^"0@>"/S -MQ"<!01/SQ"<!@6*>^"0@\)@G/@D(FIDG/@D(6I@G/@D(6IDG/@D(2LP3GP1$ -MK]'*Q">!7J^U,T]\$A!T,$]\$A#,9I[X)""XD7GBDX!@#O/$)P'!FY@G/@D( -MYC)/?!(0S&.>^"289_P_7*S:0>`<20_,4O/C\JIYBGS(R?=DZ'-9AV?E5?,T -M><[)I^E;T4W>&T$W@PZ5\3GTQ\N]<^O0U>$\1WC.8;+S61Y]VQ;VF?/J)]5E -M<LI]9Q/0]7X:(_L@2ISH,C>2^<+&E+K'V=1E:K]Y"E4?>CJC_&UD,]%[GUL0 -M#H,Z=&N8GM(.MLXNMNW</DB2E\A7Y/62"#(-A3NU)/D)^:+SZO(=F#[0F\`Q -M*39L'9]%U0?G2#ZM_J/$[CBIIYXF>N75UGL,AI</(Z1,.F':7_=#M^AWH]HO -MG7)?6MVM[T]VZ$&V#VN)]IT+(M=QHMO]68=ODF=BB!,]1G0A7/J$8T5)\EUR -MK=]KDOS<C.>(2G0L2Y(\[9<V?B;I1TG33R)O'[JV='OURFM>/2LZYL:*_EC) -M%Y4Q#FGM'B=Z66CGH9+D\XJ=?^P<9.>AO'5PYSP[=^6=OQH1=[ZQ?>WZ3)K_ -MN+%Z=0-U**&VW>/R<?76V!A>`-/G.M\IW(5J[&;%P0*YU_JM]<4NL9,D=MRP -MX\5#")=^-?/70PFZ[EPS-J6,-''K&X>-R21Q[XG#VLXC=NX]B^J\7$3<<2>K -MOXK8*_(,6HJ.&WGJD"5E&)^-^E_:_*TE.F_=+T3GL;3ZZ<^GH[:]HO-`DMCX -M2ZJ[_BRM/5U]S1SGNA/9<Z\NLUWT]+,VHSK_6+:EZ/>B=LZ85[!\W7;V6:U^ -M5X0T_5[4/G]2/">);3^WK"+E1^_O0>WSZ_JDK;^MQ/EYD1A.T\^*W4Z,]#UW -M7.O,68>>A.LLB2LO6I\D<=O?ZN2=?^-L['#0\Y"=$Y/$KEO<,:07(WTH2;2_ -MN^N`N1BYCI^7HF_G"3M_NRQ`^AY4RPRI>](>HB3W)$FOW+<8X1%@Z.OZ=:R\ -MMQ'IXU>:OF5BBG[<\^N^L^VN/WM[BGZTG^+Z+JW_HFN^.-+:7X^M<>N&O/MW -MO3=V^VJZX/;I/2GZNFW')I"G_W3;;$5U_>W.G7G:KTOJ][#HZ[Y[I(!^W'A= -M9/R.B[]H.Z3Y7UKY]\OSZ'MTGV[.67XT'M/ZSRW?[L/M&)KG^7N$M:C/?[/: -M/JO\-#V[]DK;P\6UN47[TU;$[W^B^B74[AMM/V3Y7]+96=[VL^.-WB-%Y[P% -MR%[_S4'RWL62=7[JGH/I,SO]_'I-F.?\:@Z2]SZ6N/*C\^;_A[CGIN[^[ER) -M'G?U\VK?R;-_U:+;W(XST7';'1/RB!T+W#5`5ORUH[:?[!X@;_WCRG?W!'G6 -M_[I,_2<S.]86&7]=>2BF[LVHCK]Q<ZG;_B6Q$6W_M/'775].0_'QLQ/5]?5F -MU.X=7-SQ):G^26N`M/HGU3EO_5W1?^:S:P"7O/%](]+/LK,D:2[.&S])Y;MK -M@C1?S/*_K+WTC:CZ7SW^'SV/SW/VKL=A.Q;.P\BYXP&8,2*/Q#U[D?$CKNV+ -MG)\GK0'2YO^HOEUS6(K,3TGK&'LFH/LC:R^EVRMZ?IHV_V]&;:Q>BI'Q&[?N -MM!+W=XXB?_^(EA>MCZU3DMCSWD8E;A^>U79:DO;/[M[9KJ?CXJ@Y<EW$_Z/G -MPT7G3_>9M=2S_G#K7U3?/;>I1]_6W9ZOUE-_*[8?W;G0[;NL-2A0W_K%'1N* -MZD?;KY[RW;FQZ/K#?F9M%-6/UK^HOFV[/&=H48GZ3E']Z-FB/8?2>7>^SSK_ -M<,7ZJIXS]9@_57@L1:<;M6ON7HP</QY)T$WRWZ+[;RM%]9/\-Z^^UK7?5P&* -MCY_1\NM9?W1%KK/F[^DQNEEG4$G/W^6\UJ/OQE=TS1@]BXB3/'LOO7=(.W^. -MKM-Z(J]IY>NUD.TC?7V57.]`;?\EK;_T6N.92#E)W^/0<1A=AT3'@*+S3W3^ -MKF?\=<LO&C]1_7K\WUU_%=E_N7JZCEEGN'%BSQLTW?)>D;\;1;\[H*7H]XS< -MOP^ZWR6P<V^1_:.6Z-]#QQ2LC];OC)`D[EI5US.Z=]#]XYXK=A?0UWVN^_!Q -MT4NJ2]*^(?J=F#RBYTW=EU/E]8&<>E9</6LG22H(O_)=]^LA<D<#KY\CSS?P -MFG5FTP@S&M3+H_]`"@]G?)[E%[UUZC=:?UWOSISU;Y2DYVZD?%O_/.O=-#MY -M]+/\IQ&IUW\M+]99?TO2]\/SRMES4/^L>[+*SY*LYV^DWGGJG^9_W\OX/$U/ -MSWTOY7C^.+'?@:^W_!?$3KW^8_5>J+-\^_QYZI]6?I[ZISU_GOJGQ5V]Y5L: -M;?\\_I]EIY&Y(8__9L5?/5(D?M-$U[^1Y\_3?FGC5J/C;Z/S5Y[V2_IW27E) -MDSSZ$QOD^PU2[[.EB=W33G6P?Y-+DNB_MYJ*ZIF%I3E1N_:<,KIO++*'C'[W -M/TJ6KB[?/4^[!/G^_N2*>^;IDO;W'RM9?W?-:@/;=_6,-_;,*/IOX?+\^R$M -M:6?/6=\?C_N;5;3OMJ;H;T/M=V>[$?\WU#RBG]/]MV!YSV("F'V#J_]7DL_J -MNW94?2UZ]F[]L3VC_#S?`<R2WAS7:6+]+.[?7F2-26[_=6+DN6)6/Z1]=SM+ -MWYZA/H/L.:<(1>/?;;.>F/?RB'LFF>?ORG'GA^="BM8[R4:6Z'DP[OMV^GLX -M]KET["?%SU04GRM<N51L6+_3/Q-1[]IG;@K_%R*_C^17?%+9(\E0I1(FO<SN -M]L.D?U=E5T_X8R)]0Y6A7O/;(D.\N6]H6(U)G]$8JNPUB?ZTU[F%[_4Q&3!J -MU83O#?789-?P%6L0)KI^K$%X\]['^5Y8QKY^6U-^,,`/PEO"A*4-]>B:]O0/ -M5G;J(@>[=PY6^GU'0\K-E5"WTDM3%:VV6R=#3_1)-<);=N<V9>J7[^;^:C:Q -MNGTC+.\>OMJWS=?U9L7W;=5M.JQ6<R4W#^VL6M%&=]88'8HD.X>3J+V^A)M- -M3=F23IVWV4ZN/NK>X<3-4J/2%_G`N@^O=CEJ^X:3H5HK$?/FO9TU93AN*[=4 -M*GO[PZO^72-T34%:;8>NP0[[WJY>FQC=_N%&-)[=5_OS/&P27E63(9,,ZNR0 -MR?;+>R;;;9)!DPP.[*SH*TE,5EL>[#;F==)ODVXF0P/VYB'S@;[J'JY0=_73 -MT%ZHME.24&/0_86A0?-!]3U>#?!JP-ZRHZ8KJN/+[N$^"KM68JL:3';<&.H) -M1Y6^8??V96RJ1N-NGS78$]8E=)5>T\[LE,?9NH-/,!EX0O>E]G9VU*#I,AE: -MY/>19(6R>:S^+OAHKM<NP(4<T<=A/"["!%S,$?YE'.TGXC)<CDD<YU^.*_`* -MO)*SU*LPA7/`-+R:.Z$9N!*OP4Q<A:OQ6ER#U^%:7(=9>#W>@.MQ`][(V4G! -MXWZH!:V<:=HX,W5@-N?I.7@31_IY*.,FS,<"+,0B+,;-6(*E6(8WXQ;<BN58 -M@96X#:MP.U;C#KP%=V(-WHJU>!O>CI_%.[".JZ>[L)[KO0VXFRO?>W`O[L,F -MW,\=_X-<$3S,U<X[L06/X%'\'![CNGH;'L=V[."J^0FN.GKAHP_]V(D!#&(7 -MAE#!;NS!7NS#S^-=>#?>@_=B/]Z'7\`OXOWX`#Z(#^$`?@F_C`_C(_@5/(F/ -MXB!^%1_#Q_%K^'5\`K^!0_@D/H7?Q&_AT_AM_`X.XS/X7?P>/HO?QQ_@#W$$ -MG\,?X2G\,?Z$*^G/XRB>QA?PI_@B_@Q?PI_C&+Z,K^`O\)=<4W\5?XWC^!O\ -M+?X.7\/?<]7V=9S@>OL?\`U\$_^(;^&?<!+_C&_C7_`=/(=_Q;_A%+Z+[^'? -M\3Q>X(KA/W`:_XD?X(?X+_P(+^+'.(/_QDOX'_PD]`+[>UG?.L]YSO-3B_N[ -M>79/J7\63N]+])F7_KT*_3-E>K]A]QGZ>P3ZAUAO@_D]HG4PYP\/DD=AOA?2 -M3W:3]Y`/D(_`_';6I\AGR!'R>?(EF#.$KY%OD&^3[Y+3Y,=2MW'D4G(%F4:N -M(K.((NUD'EE,;B6KR=O(>G(?V4RVDAXR.,K\]NW[R`'R4?()\FGR6?(4^0+Y -M,CE.OBYM]!QYGOR0O$3&L-$FD,OU;^&2&>0:<CUI(3>2^60I64GN).\@=Y,' -MR"-D.^DC%?)N\G[R8?(Q\DERF!PA1\DQ<IR<("?)*7*:G"&CQ[`N9!*90F:2 -M6<0CL\E\LHRL(FO)>K*);"';23_90_:3`^0@.40.DR/D*#E&CI,3Y"0Y14Z3 -M,V3T!2R?3")3R$PRBWAD-IE/EI%59"U93S:1+60[Z2=[R'YR@!PDA\AA<H0< -M)<?(<7*"G"2GR&ERAHR^D.63260*F4EF$8_,)O/),K**K"7KR2:RA6PG_60/ -MV4\.D(/D$#E,CI"CY!@Y3DZ0D^04.4W.D-$,F@ED$IE"9I)9Q".SR7RRC*PB -M:\EZLHEL(=M)/]E#]I,#Y"`Y1`Z3(^0H.4:.DQ/D)#E%3I,S9/0XED\FD2ED -M)IE%/#*;S"?+R"JREJPGF\@6LIWTDSUD/^FZ]ZXM36&JPM0+T^8P;0G3UC`M -MA6E;F+:':8?1$F6CK8RZ,OK*&%#&@C(FE+&AC!%EK'C&BB=U,%8\8\4S5CQC -MQ3-6/&/%,U8\8Z796&DV5IKE48R59F.EV5AI-E::C95F8Z796&DQ5EJ,E19C -MI45:Q%AI,59:C)468Z7%6&DQ5EJ-E59CI=58:3566J5AC9568Z756&DU5EJ- -ME9*Q4C)62L9*R5@I&2LEZ1]CI62LE(R5DK'29JRT&2MMQDJ;L=)FK+09*VW2 -MS<9*F['29JRT&ROMQDJ[L=)NK+0;*^W&2KNQTB[>8JRT&RL=QDJ'L=)AK'08 -M*QW&2H>QTF&L=!@K'>)TUNO$[9K$[YK$\9K$\YK$]9K$]YK$^9K$^YK$_9K$ -MWK`;BSWKR-:3K2M;7[;.;+W9NK/XLQ*'5IZ-"[$G/JW$J95XM1*W5N+72AQ; -MB6<K<6TEOJV:;:")/7%O)?ZMQ,&5>+@2%U?BXTJ<7(F7*W%SU6(C5^R)IRMQ -M=26^KL39E7B[$G=7XN]*'%Z)QZM6.Q2(/7%Z)5ZOQ.V5^+T2QU?B^4I<7XGO -M*W%^5;)CB]@3_U<2`$HB0$D(*(D!)4&@)`J4A(&2.%!M=K`2>Q(*2F)!23`H -MB08EX:`D'I0$A)*(4!(2JMV.?F)/HD))6"B)"R6!H20RE(2&DMA0$AQ*HD-U -MV.'4CJ<RH$I\>!(?GL2')_'A27QX$A^>Q(<G\>%)?'C*#M!B3^+#D_CP)#X\ -MB0]/XL.3^/`D/CP[WML!?WC$%WMVS+>#OAWU[;!OQWT[\$M\>!(?GL2'UVRG -M$+$G\>%)?'@2'Y[$AR?QX4E\>!(?GL2')_'AM=@Y2>Q)?'@2'Y[$AR?QX4E\ -A>!(?GL2')_'A27QXK7:2:Y7SZW/Q_Q#X7P&*JEP88@`` -` -end diff --git a/usr.bin/doscmd/cp437-8x8.pcf.gz.uu b/usr.bin/doscmd/cp437-8x8.pcf.gz.uu deleted file mode 100644 index ee49e12..0000000 --- a/usr.bin/doscmd/cp437-8x8.pcf.gz.uu +++ /dev/null @@ -1,104 +0,0 @@ -$FreeBSD$ - -begin 644 cp437-8x8.pcf.gz -M'XL(`,\!X#H``^V<?9Q4UUG'?T"R2R"%E#8IH91=28Q*F[CGSK[,0F2'#4M8 -M3(`0DE"JY1;(DI#F18B"A+)W9W>6+59;J;8-VCK%5"NM5FFMBJ9.2:V55JNH -MM:6VCK06I36-U-86D>WOS'F>G3-G[^SD#_]23C[?<U^>>W[WW'.>YYQS[PZ9 -M-K#MB6L`3"/3R4+NO$OVIW-_.[<?X?8J.9YY-3"?QIERS?R;@=9FX#K/GGTU -MSXG].F:Y-B+',RFT/@(2.2[.!C9UN@KH_;Z[PMFNA:3U9+;=L7>]P>ZL)C?I -M3IM>M]SJK)*ST^YG]KC=>9+9`6N?10IV9QMYF]T99WI:E9^QMUK7OW;CEGO[ -M-_=A??^FOKO<[H:^>]?===_&_G5KMVSR#UZ+%??W;5AQ9]^6!_I7;ER->]>O -MN*-_[9VX`ULVW=V[<E7?RBW]:U>M0]_VAY]\<'OKGH>??*AU[Z-;MP_PH/VV -M]MNP:MW:C=CV1'NFZ];LWBP>Z.N_<_5&[P[8M&6U.W?/?2M6REUL.TV;!OL? -MFJ7O7)K)_YHJ;5>[;X_&QR^-VWZL/5\OV7M@6C(V-IJ_DEW)KF17LO^'F9N' -M=("U<YJ=QV*X^:M(2J0LU[22'(E)0HJD1,HRN;;:N9#$)"%%4B)E>Y,9M),< -MB4E"BJ1$RL1.P*TD1V*2D"(ID;*=G#GOMI(<B4E"BJ1$RH1#/EI)CL0D(452 -M(F5B)Q([C^=(3!)2)"52;G839"O)D9@DI$A*I&PG3RXB6DF.Q"0A15(BY6O< -MW-M*<B0F"2F2$BG/<O-[*\F1F"2SW=J@1,JSW6*@E>1(3!)2)"52M@N%E]!. -M<B0F"2F2$BD3S*&=Y$A,$E(D)5(FF$L[R9&8)*1(2J1,[`*GE>1(3!)2)"52 -MMHN?E]).<B0F"2F2$BD3S*.=Y$A,$E(D)5(F>!GM)$=BDI`B*9$RP<MI)SD2 -MDX0428F4":ZGG>1(3!)2)"52OMXMFUI)CL0D(452(F6[I'H%[21'8I*0(BF1 -M,L%\VDF.Q"0A15(B98(;:2<Y$I.$%$F)E`D6T$YR)"8)*9(2*1.\DG:2(S%) -M2)&42)E@(>TD1V*2D"(ID3+!JV@G.1*3A!1)B90)%M%.<B0F"2F2$BD3M-!. -M<B0F"2F2$BFWR`+Q.F\0:)#L>G.(O$^VSY*G9?^`P.48OBC;Y\@YV;<VNR0> -M]%CNFJ!2#<AVH9Q/LR_TSH4:R^6Z>AK+O>>P77N[,-\[/RZ<D[K[]1^7:VR9 -M`=(K#,@Y+?^<M,FS7OL\)[87X,95N_T8R7@L\K0'/-WYTG9V>XE\1K;7"A+F -ME37S9?));VOY&MF!RE!<J<MFT3TGW"[GK&V:Z+1(V[6@=BV>(T^0_6+?+\>Y -MH%VUOEIW?8Z!%.!M;;V_*'R9?-X#<C_[3+8_.X6%7ON%Z8!'6OW\NHW7J;^" -ME'-^>7C7M$G[M`4VFVR?-8F]"=[[H)=F>`P&-KZ:5MIK7+8W!W;_&7R_U:3G -MTNK>*-FZ+A+4_^!M.SW2DMH&@ZU>;W5LG,Z0>]CV:T%M&]FWW(S4VYX?D',V -MJ5_8[6-DF5S[F-B;A!EUZJ>:31[7HMI&_O'\X'I-&K?CJ,:SG[3=>E#;AO62 -M7M,4G.]I4"XL;U.,JD^JIFT+C6_;]K8M=Y.GX#XT[$!U[-3QYMH`K8OMLXS< -M8Z'H9Z:PMZ$V=K-P;=8IYS6&]GK/;.O;(N?#\GI/O283V'N\^VL;^.VS*"@3 -MEO?/+?=TYJ":PCY]L<=-F-POH?]IZJFS[U\?]K-??]\&;ZO]_Y2'QJ)>Y[=! -MC[>O==%Q?;FWKW74>/#'-W_^M'W6B=KYH5/.VV3]P7X)NT'J<8,<#TYAM\\^ -MM\[]=\OQ?K'[\W%/<*SM%_J^MHE->U'URS9,]I\=WC,M\IYUA]CGHG;L625V -M?3[;-WM07?L\(N>V>7:K9>/V*7D^WZ[CXS8/'2^!R?VG]=#V\_O>LDS.9>N4 -M#Y]/R]LUQ1PI%\;GK5.T;Z8./5/8M<^T?91'I`WW!.WGMXG?7J&^[PM:OT&Y -MUL#%UUVH[;]%J.U?1<N',6]]*$9U?;4(D]<@\[WRNO;UZ_QBT[CW/(W6!#HW -MVS[VY]=F[YG\^%^64MZ6FX')X[_&CFK[^F%YG0_\\;\359\-_5?38YZVCN.Z -MUFT2C<>\^JO_JA^%<Z#>O\W;IHT!JA^.`3OJZ(;ZFG1N],<`/_ESGS]^:0KC -M.-1?ALGC@-^&:>VW-RBO[9?6_FEK/)MFHKH&U&=_#2;[8_ALH7_4BW]-?OSK -M&C2TZQB0%DN^ON\_FJQ?WBCWO075\2GK/5>SMZ_CYU3O&T@IXVL!U37O5"D< -M([:A=GP*XU+'(7\,#MM`WZ^R@4X8G_8Z^RYLY^$8;MZU/G(IT`['%]5O;F#W -MXR7-#J^\K@'TVH5!_0;DN`G5]8E?O[3G:VY@U_+UQ@]=?]FZ^'VO]V]N4%[+ -M:M_J?*3^F[;6U76.3?X\KO-2$R:_:UR6-KLL92_+^?VH7;NK?^P.[NGOA^-/ -M(WO8QFGK<R#=/_WR]>QA>3^^K6]H?X3?:-+*AO7SOQNH__G?&K3O[)BA\Y>= -M&\+US2)4WQ_]]TA_W-\"U^_?DNU7X+[5?-Y[!KVO_12IZS%MQ[3XT75B/?\# -M)H\!8?^IO5[[MWC;</[RVZ%+CI=Y=GUWM.B:WM<.OQL!M=\%_?<A?0=+FQ^U -M+MJ':<G:=0V@R?J/?K^PZW/[+6]`CE\([/8;V#?(=^#ZL(2IOT5I\C4'Y-A/ -M_GF]3M-*5#[YU]T>(_=-L;5U?EZV>U*.T]:N4]'2X'QH?V/`X\%QF`;KV!OI -M6]TX1;\1_GVG*J_ZX;>_\+K0GM8^4Z5Z[:M\MXZ^$GY;#-,X&NNG^;!?OM'] -MI](-]</V^T;*.3UOQP!=EX1)O[_7*__-.O4/G^N;#>X?ZH?E0_WP_J%^V&_U -MRBN-ZA^V?]IU4\5#V+YI_9>6ZO5OF"XUN']8O]"O&OEOH_@*ZS?>@#"%]KD- -M>*$!C>ZG2=\C7H;JNYPFG==;O*T_#^IZ<D:`)O^;?_CW`BVKWT#"[\>:[)S^ -M2@__^VOX]R5]?]4ZZ+.ES9^ZE@K7+KK.2EM;^VN)\+U*GVV/V/6=;3YJOV^$ -MZPO[?/IW,'_]$L.M)T*[/E_X_5N_)VG]PO?^M.\#/76V0/V_7>@U_K<K[3_? -M[I_7ZWR[KD]UC?IB\'T@K4[^.9O\=^3P?3EM?5@OU1MSPFO\9&/0_S;4)?>R -MZU;K&_H]J-[?T>:@M@W3UJ5`]6_;RHM-\OO(9"Q)O-\,'1P;'9K(*H?Y_.C8 -MB+MDZ.!88:AZ\=#!E!\=30A4K$.5PS')[&%^8L]=8B\N))I5;E3P,UN_H8*] -M>'1L]$U.?E2*24V':7"7%-R-6&R4V=#(V%">>\,'\MP;\IYMM#9+.S>1L6QA -MB%*%?%)PYT:2H;2R!Z?,1B?J-_5U!QO7*N6ZJO+$W@$VQ&`^7W"M-C)1HF9/ -M!$;R7ME1[4:5&IFX>&3B8I>Y<T.CM=<=G,A&[743-QHN^'7>[WI0[E80PUAJ -M:XSDG2&M(0ICD]MJS'O*2E:03!VN<NB+'ISPW=')_JSM4JB6E0ZEM>(,B=YH -M.''9A,!PU2?'G(_[\M9:\2O)I!IY>S@BX2?GW.&@RPHNR^>'Q^R>9.[0*N<' -MG;S-\IH-,G,M::TCSF#W!B<J-%BU5O0JQ88EJY3(^XU3<(;J.>Z-<&]$+SF@ -M?E#(U[3?Z(27%/(U?E#3EV,Z\"0%OR^3P`^&QR;:3T>&2J<<8.L.#S*3UK#G -M!FU?#KHAS0XM\OM(;X4TC6=FX"I<S5&W&3-Q#69A-D?AEW!$GHOK^&X\CVNE -ME^-ZW(!7<(2^$0LX)RW$JSA"MZ`5/X#%N`DWXP=Q"WX(/XP?P1*\&J_!K;@- -M/\J9P"#B'-R.#H[X79P)NK&4\]+M^#&N$GJ0PPKTX@Z^A?=A%>[$:O1C#7X< -M=^%NK,4ZK,<]V(![L9'OX/?C`6S":[$9K\-/X"?Q>FSAJN$-V,KUR'8\R!71 -M#CR$A[$3CW#%^RAGP,<YZ_X4=F$WGL1/XV>X5MF+G\4^/(7]>!-7%X-(,(0\ -MAC&"`D9Q$&-X,P[AY_`6_#Q^`6_%V_"+.(RWXY?PRW@'WHEWX6D<P:_@5_%N -MO`>_AB+>BZ/X=3R#]^$W\)MX/WX+Q_`!?!"_C=_!A_"[^#T<QX?Q$?P^/HH_ -MP!_BCW`"?XP_P;/X&/X4)7P<)_$</H$_PR?QY_@4_@*G\&E\!G^)O\)G\=?X -M&YS&W^+O\/?X'/Z!JX<OX`S71O^(+^'+^">4\<\XBZ_@J_@7?`WG\*_X-YS' -MU_EV]>]XGN](+^`_<`'?PG_BV_@._HNK]N_A(OZ;;P__@\L5+]#?RS9:7U_A -M"E?XOXO_NWE]A[$_<[9K<KL6M[_%6P*WMM=U_1UD#;F';(+[+F_?2Q\E]M]P -MV>_`>?)FN'^]]4[R'KC?V'Z0?)B<(!\GGR*?)9\C7R)?)5\G%\CWI&[-9`ZY -M?IK[=V\WD27$D"SI(:O(W60C>1W92AXF3Y`]Y``ID+>0MY,CY+WD_>1#Y*/D -M6?()\FERFGQ!_DW`.?(\^3:Y1&:PT6:1EQ+[;^Q:R"WD5M).EI%>TD_6DP?( -MZ\F#Y(UD-]E'AL@8>2MY!WDW>89\@!PG)\A)<HJ<)F?(67*>7"`7R72^$,\B -M\\@"LI@L(1%92GK)&K*!;"9;R4ZRB^PC>7*('"9'R%%RC!PG)\A)<HJ<)F?( -M67*>7"`7R?2K>'\RCRP@B\D2$I&EI)>L(1O(9K*5["2[R#Z2)X?(87*$'"7' -MR'%R@IPDI\AI<H:<)>?)!7*13+^:]R?SR`*RF"PA$5E*>LD:LH%L)EO)3K*+ -M["-Y<H@<)D?(47*,'"<GR$ERBIPF9\A9<IY<(!?)=`;-+#*/+""+R1(2D:6D -MEZPA&\AFLI7L)+O(/I(GA\AA<H0<)<?(<7*"G"2GR&ERAIPEY\D%<I%,;^;] -MR3RR@"PF2TA$EI)>LH9L()O)5K*3["+[2)X<(H?)MH?>L*NMDIM*'E7R3"5O -MK^0=E;RSDG=5\FPE[W:EI+`K;5QQX\H;)V"<@G$2QFD8)V*<2N14(JF#4XF< -M2N14(J<2.97(J41.)7(J&:>2<2H9>12GDG$J&:>2<2H9IY)Q*AFGTNY4VIU* -MNU-IEQ9Q*NU.I=VIM#N5=J?2[E0ZG$J'4^EP*AU.I4,:UJET.)4.I]+A5#J< -M2J=3Z70JG4ZETZET.I5.Z1^GTNE4.IU*IU/I<BI=3J7+J70YE2ZGTN54NJ2; -MG4J74^ER*EFGDG4J6:>2=2I9IY)U*EFGDA5O<2I9I]+M5+J=2K=3Z78JW4ZE -MVZET.Y5NI](M3J=>)V[7)G[7)H[7)I[7)J[7)K[7)L[7)M[7)N[7)GH3;BQZ -MZLCJR>K*ZLOJS.K-ZL[BST8<VD0:%Z(G/FW$J8UXM1&W-N+71AS;B&<;<6TC -MOFTR&FBB)^YMQ+^-.+@1#S?BXD9\W(B3&_%R(VYNVC5R14\\W8BK&_%U(\YN -MQ-N-N+L1?S?B\$8\WG3H4"!ZXO1&O-Z(VQOQ>R..;\3SC;B^$=\WXORF4\<6 -MT1/_-Q(`1B+`2`@8B0$C06`D"HR$@9$X,%TZ6(F>A(*16#`2#$:BP4@X&(D' -M(P%A)"*,A(3)ZN@G>A(51L+"2%P8"0PCD6$D-(S$AI'@,!(=IEN'4QU/94"5 -M^(@D/B*)CTCB(Y+XB"0^(HF/2.(CDOB(C`[0HB?Q$4E\1!(?D<1')/$127Q$ -M$A^1CO<ZX$^,^**G8[X.^CKJZ["OX[X._!(?D<1')/$1970*$3V)CTCB(Y+X -MB"0^(HF/2.(CDOB()#XBB8^H7><DT9/XB"0^(HF/2.(CDOB()#XBB8](XB.2 -6^(@Z=)+K`/[7_A\"WP<A_#T,0$(``)/X -` -end diff --git a/usr.bin/doscmd/cpu.c b/usr.bin/doscmd/cpu.c deleted file mode 100644 index c42dc22..0000000 --- a/usr.bin/doscmd/cpu.c +++ /dev/null @@ -1,431 +0,0 @@ -/* - * Copyright (c) 2001 The FreeBSD Project, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY The FreeBSD Project, Inc. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL The FreeBSD Project, Inc. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include "doscmd.h" -#include "video.h" - -static u_int32_t decode_modrm(u_int8_t *, u_int16_t, - regcontext_t *, int *); -static u_int8_t *reg8(u_int8_t c, regcontext_t *); -static u_int16_t *reg16(u_int8_t c, regcontext_t *); -#if 0 -static u_int32_t *reg32(u_int8_t c, regcontext_t *); -#endif -static u_int8_t read_byte(u_int32_t); -static void write_byte(u_int32_t, u_int8_t); -static void write_word(u_int32_t, u_int16_t); - -/* -** Hardware /0 interrupt -*/ -void -int00(regcontext_t *REGS __unused) -{ - debug(D_ALWAYS, "Divide by 0 in DOS program!\n"); - exit(1); -} - -void -int01(regcontext_t *REGS __unused) -{ - debug(D_ALWAYS, "INT 1 with no handler! (single-step/debug)\n"); -} - -void -int03(regcontext_t *REGS __unused) -{ - debug(D_ALWAYS, "INT 3 with no handler! (breakpoint)\n"); -} - -void -int0d(regcontext_t *REGS __unused) -{ - debug(D_ALWAYS, "IRQ5 with no handler!\n"); -} - -void -cpu_init(void) -{ - u_long vec; - - vec = insert_hardint_trampoline(); - ivec[0x00] = vec; - register_callback(vec, int00, "int 00"); - - vec = insert_softint_trampoline(); - ivec[0x01] = vec; - register_callback(vec, int01, "int 01"); - - vec = insert_softint_trampoline(); - ivec[0x03] = vec; - register_callback(vec, int03, "int 03"); - - vec = insert_hardint_trampoline(); - ivec[0x0d] = vec; - register_callback(vec, int0d, "int 0d"); - - vec = insert_null_trampoline(); - ivec[0x34] = vec; /* floating point emulator */ - ivec[0x35] = vec; /* floating point emulator */ - ivec[0x36] = vec; /* floating point emulator */ - ivec[0x37] = vec; /* floating point emulator */ - ivec[0x38] = vec; /* floating point emulator */ - ivec[0x39] = vec; /* floating point emulator */ - ivec[0x3a] = vec; /* floating point emulator */ - ivec[0x3b] = vec; /* floating point emulator */ - ivec[0x3c] = vec; /* floating point emulator */ - ivec[0x3d] = vec; /* floating point emulator */ - ivec[0x3e] = vec; /* floating point emulator */ - ivec[0x3f] = vec; /* floating point emulator */ -} - -/* - * Emulate CPU instructions. We need this for VGA graphics, at least in the 16 - * color modes. - * - * The emulator is far from complete. We are adding the instructions as we - * encounter them, so this function is likely to change over time. There are - * no optimizations and we only emulate a single instruction at a time. - * - * As long as there is no support for DPMI or the Operand Size Override prefix - * we won't need the 32-bit registers. This also means that the default - * operand size is 16 bit. - */ -int -emu_instr(regcontext_t *REGS) -{ - int prefix = 1; - u_int8_t *cs = (u_int8_t *)(R_CS << 4); - int ip = R_IP; - int dir, i, instrlen; - u_int8_t *r8; - u_int8_t val8; - u_int16_t val16; - u_int16_t *seg = &R_DS; - u_int32_t addr, toaddr; - - while (prefix) { - prefix = 0; - switch (cs[ip]) { - case 0x08: /* or r/m8, r8 */ - addr = decode_modrm(cs + ip, *seg, REGS, &instrlen); - r8 = reg8(cs[ip + 1], REGS); - val8 = read_byte(addr) | *r8; - write_byte(addr, val8); - /* clear carry and overflow; check zero, sign, parity */ - R_EFLAGS &= ~PSL_C | ~PSL_V; - if (val8 == 0) - R_EFLAGS |= PSL_Z; - if (val8 % 2 != 0) - R_EFLAGS |= PSL_PF; - if (val8 & 0x80) - R_EFLAGS |= PSL_N; - ip += 2 + instrlen; - break; - case 0x22: /* and r8, r/m8 */ - addr = decode_modrm(cs + ip, *seg, REGS, &instrlen); - r8 = reg8(cs[ip + 1], REGS); - *r8 &= read_byte(addr); - /* clear carry and overflow; check zero, sign, parity */ - R_EFLAGS &= ~PSL_C | ~PSL_V; - if (*r8 == 0) - R_EFLAGS |= PSL_Z; - if (*r8 % 2 != 0) - R_EFLAGS |= PSL_PF; - if (*r8 & 0x80) - R_EFLAGS |= PSL_N; - ip += 2 + instrlen; - break; - case 0x26: /* Segment Override ES */ - seg = &R_ES; - prefix = 1; - ip++; - break; - case 0x2e: /* Segment Override CS */ - seg = &R_CS; - prefix = 1; - ip++; - break; - case 0x36: /* Segment Override SS */ - seg = &R_SS; - prefix = 1; - ip++; - break; - case 0x3e: /* Segment Override DS */ - seg = &R_DS; - prefix = 1; - ip++; - break; - case 0x64: /* Segment Override FS */ - seg = &R_FS; - prefix = 1; - ip++; - break; - case 0x65: /* Segment Override GS */ - seg = &R_GS; - prefix = 1; - ip++; - break; - case 0x88: /* mov r/m8, r8 */ - addr = decode_modrm(cs + ip, *seg, REGS, &instrlen); - write_byte(addr, *reg8(cs[ip + 1], REGS)); - ip += 2 + instrlen; - break; - case 0x8a: /* mov r8, r/m8 */ - addr = decode_modrm(cs + ip, *seg, REGS, &instrlen); - r8 = reg8(cs[ip + 1], REGS); - *r8 = read_byte(addr); - ip += 2 + instrlen; - break; - case 0xc6: /* mov r/m8, imm8 */ - addr = decode_modrm(cs + ip, *seg, REGS, &instrlen); - write_byte(addr, cs[ip + 2 + instrlen]); - ip += 2 + instrlen + 1; - break; - case 0xc7: /* mov r/m32/16, imm32/16 */ - addr = decode_modrm(cs + ip, *seg, REGS, &instrlen); - val16 = *(u_int16_t *)&cs[ip + 2 + instrlen]; - write_word(addr, val16); - ip += 2 + instrlen + 2; - break; - case 0xa4: /* movs m8, m8 */ - write_byte(MAKEPTR(R_ES, R_DI), read_byte(MAKEPTR(*seg, R_SI))); - dir = (R_EFLAGS & PSL_D) ? -1 : 1; - R_DI += dir; - R_SI += dir; - ip++; - break; - case 0xaa: /* stos m8 */ - addr = MAKEPTR(R_ES, R_DI); - write_byte(addr, R_AL); - R_DI += (R_EFLAGS & PSL_D) ? -1 : 1; - ip++; - break; - case 0xab: /* stos m32/16*/ - addr = MAKEPTR(R_ES, R_DI); - write_word(addr, R_AX); - R_DI += (R_EFLAGS & PSL_D) ? -2 : 2; - ip++; - break; - case 0xf3: /* rep */ - switch (cs[++ip]) { - case 0xa4: /* movs m8, m8 */ - /* XXX Possible optimization: if both source and target - addresses lie within the video memory and write mode 1 is - selected, we can use memcpy(). */ - dir = (R_EFLAGS & PSL_D) ? -1 : 1; - addr = MAKEPTR(R_ES, R_DI); - toaddr = MAKEPTR(*seg, R_SI); - for (i = R_CX; i > 0; i--) { - write_byte(addr, read_byte(toaddr)); - addr += dir; - toaddr += dir; - } - PUTPTR(R_ES, R_DI, addr); - PUTPTR(*seg, R_SI, toaddr); - ip++; - break; - case 0xaa: /* stos m8 */ - /* direction */ - dir = (R_EFLAGS & PSL_D) ? -1 : 1; - addr = MAKEPTR(R_ES, R_DI); - for (i = R_CX; i > 0; i--) { - write_byte(addr, R_AL); - addr += dir; - } - PUTPTR(R_ES, R_DI, addr); - ip++; - break; - case 0xab: /* stos m32/16 */ - /* direction */ - dir = (R_EFLAGS & PSL_D) ? -2 : 2; - addr = MAKEPTR(R_ES, R_DI); - for (i = R_CX; i > 0; i--) { - write_word(addr, R_AX); - addr += dir; - } - PUTPTR(R_ES, R_DI, addr); - ip++; - break; - default: - R_IP = --ip; /* Move IP back to the 'rep' instruction. */ - return -1; - } - R_CX = 0; - break; - default: - /* Unknown instruction, get out of here and let trap.c:sigbus() - catch it. */ - return -1; - } - R_IP = ip; - } - - return 0; -} - -/* Decode the ModR/M byte. Returns the memory address of the operand. 'c' - points to the current instruction, 'seg' contains the value for the current - base segment; this is usually 'DS', but may have been changed by a segment - override prefix. We return the length of the current instruction in - 'instrlen' so we can adjust 'IP' on return. - - XXX We will probably need a second function for 32-bit instructions. - - XXX We do not check for undefined combinations, like Mod=01, R/M=001. */ -static u_int32_t -decode_modrm(u_int8_t *c, u_int16_t seg, regcontext_t *REGS, int *instrlen) -{ - u_int32_t addr = 0; /* absolute address */ - int16_t dspl = 0; /* displacement, signed */ - *instrlen = 0; - - switch (c[1] & 0xc0) { /* decode Mod */ - case 0x00: /* DS:[reg] */ - /* 'reg' is selected in the R/M bits */ - break; - case 0x40: /* 8 bit displacement */ - dspl = (int16_t)(int8_t)c[2]; - *instrlen = 1; - break; - case 0x80: /* 16 bit displacement */ - dspl = *(int16_t *)&c[2]; - *instrlen = 2; - break; - case 0xc0: /* reg in R/M */ - if (c[0] & 1) /* 16-bit reg */ - return *reg16(c[1], REGS); - else /* 8-bit reg */ - return *reg8(c[1], REGS); - break; - } - - switch (c[1] & 0x07) { /* decode R/M */ - case 0x00: - addr = MAKEPTR(seg, R_BX + R_SI); - break; - case 0x01: - addr = MAKEPTR(seg, R_BX + R_DI); - break; - case 0x02: - addr = MAKEPTR(seg, R_BP + R_SI); - break; - case 0x03: - addr = MAKEPTR(seg, R_BP + R_DI); - break; - case 0x04: - addr = MAKEPTR(seg, R_SI); - break; - case 0x05: - addr = MAKEPTR(seg, R_DI); - break; - case 0x06: - if ((c[1] & 0xc0) >= 0x40) - addr += R_BP; - else { - addr = MAKEPTR(seg, *(int16_t *)&c[2]); - *instrlen = 2; - } - break; - case 0x07: - addr = MAKEPTR(seg, R_BX + dspl); - break; - } - - return addr; -} - -static u_int8_t * -reg8(u_int8_t c, regcontext_t *REGS) -{ - u_int8_t *r8[] = {&R_AL, &R_CL, &R_DL, &R_BL, - &R_AH, &R_CH, &R_DH, &R_BH}; - - /* select 'rrr' bits in ModR/M */ - return r8[(c & 0x38) >> 3]; -} - -static u_int16_t * -reg16(u_int8_t c, regcontext_t *REGS) -{ - u_int16_t *r16[] = {&R_AX, &R_CX, &R_DX, &R_BX, - &R_SP, &R_BP, &R_SI, &R_DI}; - - return r16[(c & 0x38) >> 3]; -} - -#if 0 -/* not yet */ -static u_int32_t * -reg32(u_int8_t c, regcontext_t *REGS) -{ - u_int32_t *r32[] = {&R_EAX, &R_ECX, &R_EDX, &R_EBX, - &R_ESP, &R_EBP, &R_ESI, &R_EDI}; - - return r32[(c & 0x38) >> 3]; -} -#endif - -/* Read an 8-bit value from the location specified by 'addr'. If 'addr' lies - within the video memory, we call 'video.c:vga_read()'. */ -static u_int8_t -read_byte(u_int32_t addr) -{ - if (addr >= 0xa0000 && addr < 0xb0000) - return vga_read(addr); - else - return *(u_int8_t *)addr; -} - -/* Write an 8-bit value to the location specified by 'addr'. If 'addr' lies - within the video memory region, we call 'video.c:vga_write()'. */ -static void -write_byte(u_int32_t addr, u_int8_t val) -{ - if (addr >= 0xa0000 && addr < 0xb0000) - vga_write(addr, val); - else - *(u_int8_t *)addr = val; - - return; -} - -/* Write a 16-bit value to the location specified by 'addr'. If 'addr' lies - within the video memory region, we call 'video.c:vga_write()'. */ -static void -write_word(u_int32_t addr, u_int16_t val) -{ - if (addr >= 0xa0000 && addr < 0xb0000) { - vga_write(addr, (u_int8_t)(val & 0xff)); - vga_write(addr + 1, (u_int8_t)((val & 0xff00) >> 8)); - } else - *(u_int16_t *)addr = val; - - return; -} diff --git a/usr.bin/doscmd/crt0.c b/usr.bin/doscmd/crt0.c deleted file mode 100644 index b51603f..0000000 --- a/usr.bin/doscmd/crt0.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI crt0.c,v 2.2 1996/04/08 19:32:24 bostic Exp - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -char **environ; -char *__progname; - -start(int argc, char **argv, char **env) -{ - environ = env; - __progname = *argv; - quit(main(argc, argv, environ)); -} diff --git a/usr.bin/doscmd/cwd.c b/usr.bin/doscmd/cwd.c deleted file mode 100644 index 58b9434..0000000 --- a/usr.bin/doscmd/cwd.c +++ /dev/null @@ -1,979 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI cwd.c,v 2.2 1996/04/08 19:32:25 bostic Exp - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/mount.h> -#include <dirent.h> -#include <errno.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <stdio.h> - -#include "doscmd.h" -#include "cwd.h" - -/* Local functions */ -static __inline int isvalid(unsigned); -static __inline int isdot(unsigned); -static __inline int isslash(unsigned); -static void to_dos_fcb(u_char *, u_char *); - -#define D_REDIR 0x0080000 /* XXX - ack */ -#define D_TRAPS3 0x0200000 - -typedef struct { - u_char *path; - u_char *cwd; - int len; - int maxlen; - int read_only:1; -} Path_t; - -typedef struct Name_t { - u_char *real; - struct Name_t *next; - u_char name[9]; - u_char ext[4]; -} Name_t; - - -#define MAX_DRIVE 26 - -static Path_t paths[MAX_DRIVE]; -static Name_t *names; - -/* - * Initialize the drive to be based at 'base' in the BSD filesystem - */ -void -init_path(int drive, const u_char *base, const u_char *dir) -{ - Path_t *d; - - if (drive < 0 || drive >= MAX_DRIVE) - return; - - debug(D_TRAPS3, "init_path(%d, %s, %s)\n", drive, base, dir); - - d = &paths[drive]; - - if (d->path) - free(d->path); - - if ((d->path = ustrdup(base)) == NULL) - fatal("strdup in init_path for %c:%s: %s", drntol(drive), base, - strerror(errno)); - - if (d->maxlen < 2) { - d->maxlen = 128; - if ((d->cwd = (u_char *)malloc(d->maxlen)) == NULL) - fatal("malloc in init_path for %c:%s: %s", drntol(drive), base, - strerror(errno)); - } - - d->cwd[0] = '\\'; - d->cwd[1] = 0; - d->len = 1; - if (dir) { - if (ustrncmp(base, dir, ustrlen(base)) == 0) - dir += ustrlen(base); - while (*dir == '/') - ++dir; - - while (*dir) { - u_char dosname[15]; - u_char realname[256]; - u_char *r = realname;; - - while ((*r = *dir) && *dir++ != '/') { - ++r; - } - *r = 0; - while (*dir == '/') - ++dir; - - dosname[0] = drntol(drive); - dosname[1] = ':'; - real_to_dos(realname, &dosname[2]); - - if (dos_setcwd(dosname)) { - fprintf(stderr, "Failed to CD to directory %s in %s\n", - dosname, d->cwd); - } - } - } -} - -/* - * Mark this drive as read only - */ -void -dos_makereadonly(int drive) -{ - - if (drive < 0 || drive >= MAX_DRIVE) - return; - paths[drive].read_only = 1; -} - -/* - * Return read-only status of drive - */ -int -dos_readonly(int drive) -{ - - if (drive < 0 || drive >= MAX_DRIVE) - return (0); - debug(D_REDIR, "dos_readonly(%d) -> %d\n", drive, paths[drive].read_only); - return (paths[drive].read_only); -} - -/* - * Return DOS's idea of the CWD for drive - * Return 0 if the drive specified is not mapped (or bad) - */ -u_char * -dos_getcwd(int drive) -{ - - if (drive < 0 || drive >= MAX_DRIVE) - return (0); - debug(D_REDIR, "dos_getcwd(%d) -> %s\n", drive, paths[drive].cwd); - return (paths[drive].cwd); -} - -/* - * Return DOS's idea of the CWD for drive - * Return 0 if the drive specified is not mapped (or bad) - */ -u_char * -dos_getpath(int drive) -{ - - if (drive < 0 || drive >= MAX_DRIVE) - return (0); - debug(D_REDIR, "dos_getpath(%d) -> %s\n", drive, paths[drive].path); - return (paths[drive].path); -} - -/* - * Fix up a DOS path name. Strip out all '.' and '..' entries, turn - * '/' into '\\' and convert all lowercase to uppercase. - * Returns 0 on success or DOS errno - */ -int -dos_makepath(u_char *where, u_char *newpath) -{ - int drive; - u_char **dirs; - u_char *np; - Path_t *d; - u_char tmppath[1024]; - u_char *snewpath = newpath; - - if (where[0] != '\0' && where[1] == ':') { - drive = drlton(*where); - *newpath++ = *where++; - *newpath++ = *where++; - } else { - drive = diskdrive; - *newpath++ = drntol(diskdrive); - *newpath++ = ':'; - } - - if (drive < 0 || drive >= MAX_DRIVE) { - debug(D_REDIR,"drive %c invalid\n", drntol(drive)); - return (DISK_DRIVE_INVALID); - } - - d = &paths[drive]; - if (d->cwd == NULL) { - debug(D_REDIR,"no cwd for drive %c\n",drntol(drive)); - return (DISK_DRIVE_INVALID); - } - - debug(D_REDIR, "dos_makepath(%d, %s)\n", drive, where); - - np = newpath; - if (*where != '\\' && *where != '/') { - ustrncpy(tmppath, d->cwd, 1024); - if (d->cwd[1]) - ustrncat(tmppath, "/", 1024 - ustrlen(tmppath)); - ustrncat(tmppath, where, 1024 - ustrlen(tmppath)); - } else { - ustrncpy(tmppath, where, 1024 - ustrlen(tmppath)); - } - - dirs = get_entries(tmppath); - if (dirs == NULL) - return (PATH_NOT_FOUND); - - np = newpath; - while (*dirs) { - u_char *dir = *dirs++; - if (*dir == '/' || *dir == '\\') { - np = newpath + 1; - newpath[0] = '\\'; - } else if (dir[0] == '.' && dir[1] == 0) { - ; - } else if (dir[0] == '.' && dir[1] == '.' && dir[2] == '\0') { - while (np[-1] != '/' && np[-1] != '\\') - --np; - if (np - 1 > newpath) - --np; - } else { - if (np[-1] != '\\') - *np++ = '\\'; - while ((*np = *dir++) && np - snewpath < 1023) - ++np; - } - } - *np = 0; - - return (0); -} - -/* - * Set DOS's idea of the CWD for drive to be where. - * Returns DOS errno on failure. - */ -int -dos_setcwd(u_char *where) -{ - u_char new_path[1024]; - u_char real_path[1024]; - int drive; - struct stat sb; - Path_t *d; - int error; - - debug(D_REDIR, "dos_setcwd(%s)\n", where); - - error = dos_makepath(where, new_path); - if (error) - return (error); - - error = dos_to_real_path(new_path, real_path, &drive); - if (error) - return (error); - - if (ustat(real_path, &sb) < 0 || !S_ISDIR(sb.st_mode)) - return (PATH_NOT_FOUND); - if (uaccess(real_path, R_OK | X_OK)) - return (PATH_NOT_FOUND); - - d = &paths[drive]; - d->len = ustrlen(new_path + 2); - - if (d->len + 1 > d->maxlen) { - free(d->cwd); - d->maxlen = d->len + 1 + 32; - d->cwd = (u_char *)malloc(d->maxlen); - if (d->cwd == NULL) - fatal("malloc in dos_setcwd for %c:%s: %s", drntol(drive), - new_path, strerror(errno)); - } - ustrncpy(d->cwd, new_path + 2, d->maxlen - d->len); - return (0); -} - -/* - * Given a DOS path dos_path and a drive, convert it to a BSD pathname - * and store the result in real_path. - * Return DOS errno on failure. - */ -int -dos_to_real_path(u_char *dos_path, u_char *real_path, int *drivep) -{ - Path_t *d; - u_char new_path[1024]; - u_char *rp; - u_char **dirs; - u_char *dir; - int drive; - - debug(D_REDIR, "dos_to_real_path(%s)\n", dos_path); - - if (dos_path[0] != '\0' && dos_path[1] == ':') { - drive = drlton(*dos_path); - dos_path++; - dos_path++; - } else { - drive = diskdrive; - } - - d = &paths[drive]; - if (d->cwd == NULL) - return (DISK_DRIVE_INVALID); - - ustrcpy(real_path, d->path); - - rp = real_path; - while (*rp) - ++rp; - - ustrncpy(new_path, dos_path, 1024 - ustrlen(new_path)); - - dirs = get_entries(new_path); - if (dirs == NULL) - return (PATH_NOT_FOUND); - - /* - * Skip the leading / - * There are no . or .. entries to worry about either - */ - - while ((dir = *++dirs) != 0) { - *rp++ = '/'; - dos_to_real(dir, rp); - while (*rp) - ++rp; - } - - *drivep = drive; - return (0); -} - -/* - * Provide a few istype() style functions. - * isvalid: True if the character is a valid DOS filename character - * isdot: True if '.' - * isslash: True if '/' or '\' - * - * 0 - invalid - * 1 - okay - * 2 - * - * 3 - dot - * 4 - slash - * 5 - colon - * 6 - ? - * 7 - lowercase - */ -u_char cattr[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 */ - 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 1, 3, 4, /* 0x20 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 0, 0, 0, 0, 6, /* 0x30 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 4, 0, 1, 1, /* 0x50 */ - 1, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, /* 0x60 */ - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 1, 0, 1, 1, 0, /* 0x70 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x80 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -}; - -static __inline int -isvalid(unsigned c) -{ - return (cattr[c & 0xff] == 1); -} - -static __inline int -isdot(unsigned c) -{ - return (cattr[c & 0xff] == 3); -} - -static __inline int -isslash(unsigned c) -{ - return (cattr[c & 0xff] == 4); -} - -/* - * Given a real component, compute the DOS component. - */ -void -real_to_dos(u_char *real, u_char *dos) -{ - Name_t *n; - Name_t *nn; - u_char *p; - u_char nm[9], ex[4]; - int ncnt, ecnt; - int echar = '0'; - int nchar = '0'; - - if (real[0] == '.' && (real[1] == '\0' - || (real[1] == '.' && real[2] == '\0'))) { - sprintf((char *)dos, "%.8s", real); - return; - } - - n = names; - while (n) { - if (ustrcmp(real, n->real) == 0) { - if (n->ext[0]) - sprintf((char *)dos, "%.8s.%.3s", n->name, n->ext); - else - sprintf((char *)dos, "%.8s", n->name); - return; - } - n = n->next; - } - - p = real; - ncnt = ecnt = 0; - while (isvalid(*p) && ncnt < 8) { - nm[ncnt] = *p; - ++ncnt; - ++p; - } - if (isdot(*p)) { - ++p; - while (isvalid(*p) && ecnt < 3) { - ex[ecnt] = *p; - ++ecnt; - ++p; - } - } - nm[ncnt] = '\0'; - ex[ecnt] = '\0'; - - if (!*p && ncnt <= 8 && ecnt <= 3) { - n = names; - while (n) { - if (ustrncmp(n->name, nm, 8) == 0 && ustrncmp(n->ext, ex, 3) == 0) { - break; - } - n = n->next; - } - if (n == 0) { - ustrcpy(dos, real); - return; - } - } - - n = (Name_t *)malloc(sizeof(Name_t)); - - if (!n) - fatal("malloc in real_to_dos: %s\n", strerror(errno)); - - n->real = ustrdup(real); - - if (!n->real) - fatal("strdup in real_to_dos: %s\n", strerror(errno)); - - p = real; - ncnt = ecnt = 0; - while (*p && ncnt < 8) { - if (isvalid(*p)) - n->name[ncnt] = *p; - else if (islower(*p)) - n->name[ncnt] = toupper(*p); - else if (isdot(*p)) - break; - else - n->name[ncnt] = (*p |= 0x80); - ++ncnt; - ++p; - } - if (isdot(*p)) { - ++p; - while (*p && ecnt < 3) { - if (isvalid(*p)) - n->ext[ecnt] = *p; - else if (islower(*p)) - n->ext[ecnt] = toupper(*p); -#if 0 - else if (isdot(*p)) - ERROR -#endif - else - n->ext[ecnt] = (*p |= 0x80); - ++ecnt; - ++p; - } - } - n->name[ncnt] = '\0'; - n->ext[ecnt] = '\0'; - - for (;;) { - nn = names; - while (nn) { - if (ustrncmp(n->name, nn->name, 8) == 0 && - ustrncmp(n->ext, nn->ext, 3) == 0) { - break; - } - nn = nn->next; - } - if (!nn) - break; - /* - * Dang, this name was already in the cache. - * Let's munge it a little and try again. - */ - if (ecnt < 3) { - n->ext[ecnt] = echar; - if (echar == '9') { - echar = 'A'; - } else if (echar == 'Z') { - ++ecnt; - echar = '0'; - } else { - ++echar; - } - } else if (ncnt < 8) { - n->name[ncnt] = nchar; - if (nchar == '9') { - nchar = 'A'; - } else if (nchar == 'Z') { - ++ncnt; - nchar = '0'; - } else { - ++nchar; - } - } else if (n->ext[2] < 'Z') - n->ext[2]++; - else if (n->ext[1] < 'Z') - n->ext[1]++; - else if (n->ext[0] < 'Z') - n->ext[0]++; - else if (n->name[7] < 'Z') - n->name[7]++; - else if (n->name[6] < 'Z') - n->name[6]++; - else if (n->name[5] < 'Z') - n->name[5]++; - else if (n->name[4] < 'Z') - n->name[4]++; - else if (n->name[3] < 'Z') - n->name[3]++; - else if (n->name[2] < 'Z') - n->name[2]++; - else if (n->name[1] < 'Z') - n->name[1]++; - else if (n->name[0] < 'Z') - n->name[0]++; - else - break; - } - - if (n->ext[0]) - sprintf((char *)dos, "%.8s.%.3s", n->name, n->ext); - else - sprintf((char *)dos, "%.8s", n->name); - n->next = names; - names = n; -} - - -/* - * Given a DOS component, compute the REAL component. - */ -void -dos_to_real(u_char *dos, u_char *real) -{ - int ncnt = 0; - int ecnt = 0; - u_char name[8]; - u_char ext[3]; - Name_t *n = names; - - while (ncnt < 8 && (isvalid(*dos) || islower(*dos))) { - name[ncnt++] = islower(*dos) ? toupper(*dos) : *dos; - ++dos; - } - if (ncnt < 8) - name[ncnt] = 0; - - if (isdot(*dos)) { - while (ecnt < 3 && (isvalid(*++dos) || islower(*dos))) { - ext[ecnt++] = islower(*dos) ? toupper(*dos) : *dos; - } - } - if (ecnt < 3) - ext[ecnt] = 0; - - while (n) { - if (!ustrncmp(name, n->name, 8) && !ustrncmp(ext, n->ext, 3)) { - ustrcpy(real, n->real); - return; - } - n = n->next; - } - - if (ext[0]) - sprintf((char *)real, "%-.8s.%-.3s", name, ext); - else - sprintf((char *)real, "%-.8s", name); - - while (*real) { - if (isupper(*real)) - *real = tolower(*real); - ++real; - } -} - -/* - * convert a path into an argv[] like vector of components. - * If the path starts with a '/' or '\' then the first entry - * will be "/" or "\". This is the only case in which a "/" - * or "\" may appear in an entry. - * Also convert all lowercase to uppercase. - * The data returned is in a static area, so a second call will - * erase the data of the first. - */ -u_char ** -get_entries(u_char *path) -{ - static u_char *entries[128]; /* Maximum depth... */ - static u_char mypath[1024]; - u_char **e = entries; - u_char *p = mypath; - - ustrncpy(mypath+1, path, 1022); - p = mypath+1; - mypath[1023] = 0; - if (path[0] == '/' || path[0] == '\\') { - mypath[0] = path[0]; - *e++ = mypath; - *p++ = 0; - } - while (*p && e < entries + 127) { - while (*p && (*p == '/' || *p == '\\')) { - ++p; - } - - if (!*p) - break; - *e++ = p; - while (*p && (*p != '/' && *p != '\\')) { - if (islower(*p)) - *p = tolower(*p); - ++p; - } - /* - * skip over the '/' or '\' - */ - if (*p) - *p++ = 0; - } - *e = 0; - return (entries); -} - -/* - * Return filesystem statistics for drive. - * Return the DOS errno on failure. - */ -int -get_space(int drive, fsstat_t *fs) -{ - Path_t *d; - struct statfs *buf; - int nfs; - int i; - struct statfs *me = 0; - - if (drive < 0 || drive >= MAX_DRIVE) - return (DISK_DRIVE_INVALID); - - d = &paths[drive]; - - if (!d->path) - return (DISK_DRIVE_INVALID); - - nfs = getfsstat(0, 0, MNT_WAIT); - - buf = (struct statfs *)malloc(sizeof(struct statfs) * nfs); - if (buf == NULL) { - perror("get_space"); - return (DISK_DRIVE_INVALID); - } - nfs = getfsstat(buf, sizeof(struct statfs) * nfs, MNT_WAIT); - - for (i = 0; i < nfs; ++i) { - if (strncmp(buf[i].f_mntonname, (char *)d->path, strlen(buf[i].f_mntonname))) - continue; - if (me && strlen(me->f_mntonname) > strlen(buf[i].f_mntonname)) - continue; - me = buf + i; - } - if (!me) { - free(buf); - return (3); - } - fs->bytes_sector = 512; - fs->sectors_cluster = me->f_bsize / fs->bytes_sector; - fs->total_clusters = me->f_blocks / fs->sectors_cluster; - while (fs->total_clusters > 0xFFFF) { - fs->sectors_cluster *= 2; - fs->total_clusters = me->f_blocks / fs->sectors_cluster; - } - fs->avail_clusters = me->f_bavail / fs->sectors_cluster; - free(buf); - return (0); -} - -#if 0 -DIR *dp = 0; -u_char searchdir[1024]; -u_char *searchend; -#endif - -/* - * Convert a dos filename into normal form (8.3 format, space padded) - */ -static void -to_dos_fcb(u_char *p, u_char *expr) -{ - int i; - - if (expr[0] == '.') { - p[0] = '.'; - if (expr[1] == '\0') { - for (i = 1; i < 11; i++) - p[i] = ' '; - return; - } - if (expr[1] == '.') { - p[1] = '.'; - if (expr[2] == '\0') { - for (i = 2; i < 11; i++) - p[i] = ' '; - return; - } - } - } - - for (i = 8; i > 0; i--) { - switch (*expr) { - case '\0': - case '.': - for (; i > 0; i--) - *p++ = ' '; - break; - case '*': - for (; i > 0; i--) - *p++ = '?'; - break; - default: - if (islower(*expr)) { - *p++ = toupper(*expr++); - break; - } - case '?': - *p++ = *expr++; - break; - } - } - - while (*expr != '\0' && *expr != '.') - ++expr; - if (*expr) - ++expr; - - for (i = 3; i > 0; i--) { - switch (*expr) { - case '\0': - case '.': - for (; i > 0; i--) - *p++ = ' '; - break; - case '*': - for (; i > 0; i--) - *p++ = '?'; - break; - default: - if (islower(*expr)) { - *p++ = toupper(*expr++); - break; - } - case '?': - *p++ = *expr++; - break; - } - } -} - -/* -** DOS can't handle multiple concurrent searches, and if we leave the -** search instance in the DTA we get screwed as soon as someone starts lots -** of searches without finishing them properly. -** We allocate a single search structure, and recycle it if find_first() -** is called before a search ends. -*/ -static search_t dir_search; - -/* - * Find the first file on drive which matches the path with the given - * attributes attr. - * If found, the result is placed in dir (32 bytes). - * The DTA is populated as required by DOS, but the state area is ignored. - * Returns DOS errno on failure. - */ -int -find_first(u_char *path, int attr, dosdir_t *dir, find_block_t *dta) -{ - u_char new_path[1024], real_path[1024]; - u_char *expr, *slash; - int drive; - int error; - search_t *search = &dir_search; - - debug(D_REDIR, "find_first(%s, %x, %x)\n", path, attr, (int)dta); - - error = dos_makepath(path, new_path); - if (error) - return (error); - - expr = new_path; - slash = 0; - while (*expr != '\0') { - if (*expr == '\\' || *expr == '/') - slash = expr; - expr++; - } - *slash++ = '\0'; - - error = dos_to_real_path(new_path, real_path, &drive); - if (error) - return (error); - - if (attr == VOLUME_LABEL) /* never find a volume label */ - return (NO_MORE_FILES); - - if (search->dp) /* stale search? */ - closedir(search->dp); - - search->dp = opendir(real_path); - if (search->dp == NULL) - return (PATH_NOT_FOUND); - - ustrncpy(search->searchdir, real_path, 1024 - ustrlen(real_path)); - search->searchend = search->searchdir; - while (*search->searchend) - ++search->searchend; - *search->searchend++ = '/'; - - search->dp->dd_fd = squirrel_fd(search->dp->dd_fd); - - dta->drive = drive | 0x80; - to_dos_fcb(dta->pattern, slash); - dta->flag = attr; - - return (find_next(dir, dta)); -} - -/* - * Continue on where find_first left off. - * The results will be placed in dir. - * DTA state area is ignored. - */ -int -find_next(dosdir_t *dir, find_block_t *dta) -{ - search_t *search = &dir_search; - struct dirent *d; - struct stat sb; - u_char name[16]; - - if (!search->dp) - return (NO_MORE_FILES); - -#if 0 - debug(D_REDIR, "find_next()\n"); -#endif - - while ((d = readdir(search->dp)) != 0) { - real_to_dos((u_char *)d->d_name, name); - to_dos_fcb(dir->name, name); -#if 0 -printf("find_next: |%-11.11s| |%-11.11s| |%s| |%s|\n", dta->pattern, dir->name, d->d_name, name); -#endif - if (dos_match(dta->pattern, dir->name) == 0) - continue; - - ustrcpy(search->searchend, (u_char *)d->d_name); - if (ustat(search->searchdir, &sb) < 0) - continue; -#if 0 -printf("find_next: %x\n", sb.st_mode); -#endif - if (S_ISDIR(sb.st_mode)) { - if (!(dta->flag & DIRECTORY)) { - continue; - } - } - dir->attr = (S_ISDIR(sb.st_mode) ? DIRECTORY : 0) | - (uaccess(search->searchdir, W_OK) < 0 ? READ_ONLY_FILE : 0); - encode_dos_file_time(sb.st_mtime, &dir->date, &dir->time); - dir->start = 1; - dir->size = sb.st_size; -#if 0 -printf("find_next: found %s\n",name); -#endif - return (0); - } - closedir(search->dp); - search->dp = NULL; - return (NO_MORE_FILES); -} - -/* - * perform hokey DOS pattern matching. pattern may contain the wild cards - * '*' and '?' only. Follow the DOS convention that '?*', '*?' and '**' all - * are the same as '*'. Also, allow '?' to match the blank padding in a - * name (hence, ???? matchs all of "a", "ab", "abc" and "abcd" but not "abcde") - * Return 1 if a match is found, 0 if not. - * - * XXX This appears to be severely busted! (no * handling - normal?) - */ -int -dos_match(u_char *pattern, u_char *string) -{ - int i; - - /* - * Check the base part first - */ - for (i = 11; i > 0; i--) { - if (*pattern != '?' && *string != *pattern) - return (0); - pattern++, string++; - } - return (1); -} diff --git a/usr.bin/doscmd/cwd.h b/usr.bin/doscmd/cwd.h deleted file mode 100644 index ac5bbd1..0000000 --- a/usr.bin/doscmd/cwd.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI cwd.h,v 2.2 1996/04/08 19:32:26 bostic Exp - * - * $FreeBSD$ - */ - -static __inline u_char * -ustrcpy(u_char *s1, u_char *s2) -{ - return((u_char *)strcpy((char *)s1, (char *)s2)); -} - -static __inline u_char * -ustrcat(u_char *s1, u_char *s2) -{ - return((u_char *)strcat((char *)s1, (char *)s2)); -} - -static __inline u_char * -ustrncat(u_char *s1, const u_char *s2, size_t n) -{ - return((u_char *)strncat((char *)s1, (const char *)s2, n)); -} - -static __inline u_char * -ustrncpy(u_char *s1, u_char *s2, size_t n) -{ - return((u_char *)strncpy((char *)s1, (char *)s2, n)); -} - -static __inline int -ustrcmp(u_char *s1, u_char *s2) -{ - return(strcmp((char *)s1, (char *)s2)); -} - -static __inline int -ustrncmp(const u_char *s1, const u_char *s2, size_t n) -{ - return(strncmp((const char *)s1, (const char *)s2, n)); -} - -static __inline int -ustrlen(const u_char *s) -{ - return(strlen((const char *)s)); -} - -static __inline u_char * -ustrrchr(u_char *s, u_char c) -{ - return((u_char *)strrchr((char *)s, c)); -} - -static __inline u_char * -ustrdup(const u_char *s) -{ - return((u_char *)strdup((const char *)s)); -} - -static __inline int -ustat(u_char *s, struct stat *sb) -{ - return(stat((char *)s, sb)); -} - -static __inline int -uaccess(u_char *s, int mode) -{ - return(access((char *)s, mode)); -} - -extern void init_path(int, const u_char *, const u_char *); -extern void dos_makereadonly(int); -extern int dos_readonly(int); -extern u_char *dos_getcwd(int); -extern u_char *dos_getpath(int); -extern int dos_makepath(u_char *, u_char *); -extern int dos_match(u_char *, u_char *); -extern int dos_setcwd(u_char *); -extern int dos_to_real_path(u_char *, u_char *, int *); -extern void real_to_dos(u_char *, u_char *); -extern void dos_to_real(u_char *, u_char *); -extern u_char **get_entries(u_char *); -extern int get_space(int, fsstat_t *); -extern int find_first(u_char *, int, dosdir_t *, find_block_t *); -extern int find_next(dosdir_t *, find_block_t *); diff --git a/usr.bin/doscmd/debug.c b/usr.bin/doscmd/debug.c deleted file mode 100644 index 8c2a46f..0000000 --- a/usr.bin/doscmd/debug.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright (c) 1996 - * Michael Smith, All rights reserved. - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: BSDI doscmd.c,v 2.3 1996/04/08 19:32:30 bostic Exp - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <stdarg.h> - -#include "doscmd.h" -#include "tty.h" - -/* debug output goes here */ -FILE *debugf; - -/* see doscmd.h for flag names */ -int debug_flags = D_ALWAYS; - -/* include register dumps when reporting unknown interrupts */ -int vflag = 0; - -/* interrupts to trace */ -#define BPW (sizeof(u_long) << 3) -u_long debug_ints[256/BPW]; - -/* Debug flag manipulation */ -void -debug_set(int x) -{ - x &= 0xff; - debug_ints[x/BPW] |= 1 << (x & (BPW - 1)); -} - -void -debug_unset(int x) -{ - x &= 0xff; - debug_ints[x/BPW] &= ~(1 << (x & (BPW - 1))); -} - -u_long -debug_isset(int x) -{ - x &= 0xff; - return(debug_ints[x/BPW] & (1 << (x & (BPW - 1)))); -} - - -/* -** Emit a debugging message if (flags) matches the current -** debugging mode. -*/ -void -debug(int flags, const char *fmt, ...) -{ - va_list args; - - if (flags & (debug_flags & ~0xff)) { - if ((debug_flags & 0xff) == 0 - && (flags & (D_ITRAPS | D_TRAPS)) - && !debug_isset(flags & 0xff)) - return; - va_start (args, fmt); - vfprintf (debugf, fmt, args); - va_end (args); - } -} - -/* -** Emit a terminal error message and exit -*/ -void -fatal(const char *fmt, ...) -{ - va_list args; - - dead = 1; - - if (xmode) { - char buf[1024]; - const char *m; - - va_start (args, fmt); - vfprintf (debugf, fmt, args); - vsprintf (buf, fmt, args); - va_end (args); - - tty_move(23, 0); - for (m = buf; *m; ++m) - tty_write(*m, 0x0400); - - tty_move(24, 0); - for (m = "(PRESS <CTRL-ALT> ANY MOUSE BUTTON TO exit)"; *m; ++m) - tty_write(*m, 0x0900); - tty_move(-1, -1); - for (;;) - tty_pause(); - } - - va_start (args, fmt); - fprintf (debugf, "doscmd: fatal error "); - vfprintf (debugf, fmt, args); - va_end (args); - quit (1); -} - -/* -** Emit a register dump (usually when dying) -*/ -void -dump_regs(regcontext_t *REGS) -{ - u_char *addr; - int i; - char buf[100]; - - debug (D_ALWAYS, "\n"); - debug (D_ALWAYS, "ax=%04x bx=%04x cx=%04x dx=%04x\n", R_AX, R_BX, R_CX, R_DX); - debug (D_ALWAYS, "si=%04x di=%04x sp=%04x bp=%04x\n", R_SI, R_DI, R_SP, R_BP); - debug (D_ALWAYS, "cs=%04x ss=%04x ds=%04x es=%04x\n", R_CS, R_SS, R_DS, R_ES); - debug (D_ALWAYS, "ip=%x eflags=%lx\n", R_IP, R_EFLAGS); - - addr = (u_char *)MAKEPTR(R_CS, R_IP); - - for (i = 0; i < 16; i++) - debug (D_ALWAYS, "%02x ", addr[i]); - debug (D_ALWAYS, "\n"); - - addr = (char *)MAKEPTR(R_CS, R_IP); - i386dis(R_CS, R_IP, addr, buf, 0); - - debug (D_ALWAYS, "%s\n", buf); -} - -/* -** Unknown interrupt error messages -*/ -void -unknown_int2(int maj, int min, regcontext_t *REGS) -{ - if (vflag) dump_regs(REGS); - printf("Unknown interrupt %02x function %02x\n", maj, min); - R_FLAGS |= PSL_C; -} - -void -unknown_int3(int maj, int min, int sub, regcontext_t *REGS) -{ - if (vflag) dump_regs(REGS); - printf("Unknown interrupt %02x function %02x subfunction %02x\n", - maj, min, sub); - R_FLAGS |= PSL_C; -} - -void -unknown_int4(int maj, int min, int sub, int ss, regcontext_t *REGS) -{ - if (vflag) dump_regs(REGS); - printf("Unknown interrupt %02x function %02x subfunction %02x %02x\n", - maj, min, sub, ss); - R_FLAGS |= PSL_C; -} - diff --git a/usr.bin/doscmd/disktab.c b/usr.bin/doscmd/disktab.c deleted file mode 100644 index 3ab43b8..0000000 --- a/usr.bin/doscmd/disktab.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI disktab.c,v 2.2 1996/04/08 19:32:27 bostic Exp - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* XXX goaway (requires change to config.c) */ - -#include "doscmd.h" - -static struct { - int cylinders; - int heads; - int sectors; -} disk_table[] = { - { 306, 4, 17 }, /* type 01 10M */ - { 615, 4, 17 }, /* type 02 20M */ - { 615, 6, 17 }, /* type 03 30M */ - { 940, 8, 17 }, /* type 04 62M */ - { 940, 6, 17 }, /* type 05 46M */ - { 615, 4, 17 }, /* type 06 20M */ - { 462, 8, 17 }, /* type 07 30M */ - { 733, 5, 17 }, /* type 08 30M */ - { 900, 15, 17 }, /* type 09 112M */ - { 820, 3, 17 }, /* type 10 20M */ - { 855, 5, 17 }, /* type 11 35M */ - { 855, 7, 17 }, /* type 12 49M */ - { 306, 8, 17 }, /* type 13 20M */ - { 733, 7, 17 }, /* type 14 42M */ - { 976, 15, 17 }, /* type 15 121M */ - { 612, 4, 17 }, /* type 16 20M */ - { 977, 5, 17 }, /* type 17 40M */ - { 977, 7, 17 }, /* type 18 56M */ - { 1024, 7, 17 }, /* type 19 59M */ - { 733, 5, 17 }, /* type 20 30M */ - { 733, 7, 17 }, /* type 21 42M */ - { 733, 5, 17 }, /* type 22 30M */ - { 306, 4, 17 }, /* type 23 10M */ - { 925, 7, 17 }, /* type 24 53M */ - { 925, 9, 17 }, /* type 25 69M */ - { 754, 7, 17 }, /* type 26 43M */ - { 754, 11, 17 }, /* type 27 68M */ - { 699, 7, 17 }, /* type 28 40M */ - { 823, 10, 17 }, /* type 29 68M */ - { 918, 7, 17 }, /* type 30 53M */ - { 1024, 11, 17 }, /* type 31 93M */ - { 1024, 15, 17 }, /* type 32 127M */ - { 1024, 5, 17 }, /* type 33 42M */ - { 612, 2, 17 }, /* type 34 10M */ - { 1024, 9, 17 }, /* type 35 76M */ - { 1024, 8, 17 }, /* type 36 68M */ - { 615, 8, 17 }, /* type 37 40M */ - { 987, 3, 17 }, /* type 38 24M */ - { 987, 7, 17 }, /* type 39 57M */ - { 820, 6, 17 }, /* type 40 40M */ - { 977, 5, 17 }, /* type 41 40M */ - { 981, 5, 17 }, /* type 42 40M */ - { 830, 7, 17 }, /* type 43 48M */ - { 830, 10, 17 }, /* type 44 68M */ - { 917, 15, 17 }, /* type 45 114M */ - { 1224, 15, 17 }, /* type 46 152M */ -}; - -static int ntypes = sizeof(disk_table)/sizeof(disk_table[0]); - -int -map_type(int type, int *cyl, int *head, int *sec) -{ - --type; - if (type < 0 || type >= ntypes) - return(0); - *cyl = disk_table[type].cylinders; - *head = disk_table[type].heads; - *sec = disk_table[type].sectors; - return(1); -} diff --git a/usr.bin/doscmd/dispatch.h b/usr.bin/doscmd/dispatch.h deleted file mode 100644 index 72df284..0000000 --- a/usr.bin/doscmd/dispatch.h +++ /dev/null @@ -1,110 +0,0 @@ -/* -** Copyright (c) 1996 -** Michael Smith. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** -** THIS SOFTWARE IS PROVIDED BY Michael Smith ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL Michael Smith BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. -** -** $FreeBSD$ -*/ - -/* -** Interrupt dispatcher assistants. -*/ - - -/* -** Declare a static, initialised array of these, with one -** entry per function/subfunction. -** -** The last element should be a dummy with a 'func' of -1 -*/ -struct intfunc_table -{ - int func; /* interrupt function number */ - int subfunc; /* subfunction number */ - int (* handler)(regcontext_t *REGS);/* handling function */ - const char *desc; /* textual description */ -}; -#define IFT_NOSUBFUNC -1 - - -/* -** Declare a static array of 256 integers to use as a fast lookup -** into the table of handlers. -** -** Call this function to initialise the lookup. Note that the table -** must be arranged with all handlers for a given function together, and -** that the handler listed with IFT_NOSUBFUNC should be last. -*/ -static __inline void -intfunc_init(struct intfunc_table table[], int idx[]) -{ - int hn; - - for (hn = 0; hn < 256; hn++) /* initialise all no-handler state */ - idx[hn] = -1; /* default to no handler */ - - for (hn = 0; table[hn].func >= 0; hn++) /* walk list of handlers and add references */ - if (idx[table[hn].func] == -1 ) /* reference first handler */ - idx[table[hn].func] = hn; -} - -/* -** Call this to get an index matching the function/subfunction -** described by (sc), or -1 if none exist -*/ -static __inline int -intfunc_find(struct intfunc_table table[], int idx[], int func, int subfunc) -{ - int ent = idx[func]; /* look for handler */ - - while ((ent >= 0) && /* scan entries for function */ - (table[ent].func == func)) { - - if ((table[ent].subfunc == IFT_NOSUBFUNC) || /* handles all */ - (table[ent].subfunc == subfunc)) { /* handles this one */ - return(ent); - } - ent++; - } - return(-1); -} - -/* -** A slower lookup for a set of function handlers, but one that requires -** no initialisation calls. -** Again, handlers with IFT_NOSUBFUNC should be listed after any with -** specific subfunction values. -*/ -static __inline int -intfunc_search(struct intfunc_table table[], int func, int subfunc) -{ - int ent; - - for (ent = 0; table[ent].func >= 0; ent++) - if ((table[ent].func == func) && /* matches required function */ - ((table[ent].subfunc == IFT_NOSUBFUNC) || table[ent].subfunc == subfunc)) - return(ent); - return(-1); -} - - diff --git a/usr.bin/doscmd/dos.c b/usr.bin/doscmd/dos.c deleted file mode 100644 index 478c8ce..0000000 --- a/usr.bin/doscmd/dos.c +++ /dev/null @@ -1,2576 +0,0 @@ -/* - * Copyright (c) 1996 - * Michael Smith. All rights reserved. - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI int21.c,v 2.2 1996/04/08 19:32:51 bostic Exp - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/ioctl.h> -#include <sys/param.h> -#include <sys/mount.h> -#include <ctype.h> -#include <dirent.h> -#include <errno.h> -#include <glob.h> -#include <paths.h> -#include <stddef.h> -#include <time.h> -#include <unistd.h> - -#include "doscmd.h" -#include "cwd.h" -#include "dispatch.h" -#include "tty.h" - -/* Country Info */ -struct { - ushort ciDateFormat; - char ciCurrency[5]; - char ciThousands[2]; - char ciDecimal[2]; - char ciDateSep[2]; - char ciTimeSep[2]; - char ciCurrencyFormat; - char ciCurrencyPlaces; - char ciTimeFormat; - ushort ciCaseMapOffset; - ushort ciCaseMapSegment; - char ciDataSep[2]; -#if 0 - char ciReserved[10]; -#endif -} countryinfo = { - 0, "$", ",", ".", "-", ":", 0, 2, 0, 0xffff, 0xffff, "?" -}; - -/* DOS File Control Block */ -struct fcb { - u_char fcbMagic; - u_char fcbResoived[5]; - u_char fcbAttribute; - u_char fcbDriveID; - u_char fcbFileName[8]; - u_char fcbExtent[3]; - u_short fcbCurBlockNo; - u_short fcbRecSize; - u_long fcbFileSize; - u_short fcbFileDate; - u_short fcbFileTime; - int fcbReserved; - int fcb_fd; /* hide UNIX FD here */ - u_char fcbCurRecNo; - u_long fcbRandomRecNo; -}/* __attribute__((__packed__))*/; - -/* exports */ -int diskdrive = 2; /* C: */ -char *InDOS; - -/* locals */ -static void fcb_to_string(struct fcb *, u_char *); - -static int ctrl_c_flag = 0; -static int return_status = 0; -static int doserrno = 0; -static int memory_strategy = 0; /* first fit (we ignore this) */ -static u_long upcase_vector; - -static u_char upc_table[0x80] = { - 0x80, 0x9a, 'E', 'A', 0x8e, 'A', 0x8f, 0x80, - 'E', 'E', 'E', 'I', 'I', 'I', 0x8e, 0x8f, - 0x90, 0x92, 0x92, 'O', 0x99, 'O', 'U', 'U', - 'Y', 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, - 'A', 'I', 'O', 'U', 0xa5, 0xa5, 0xa6, 0xa7, - 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, - 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, - 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, - 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, - 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, - 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, - 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, - 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, - 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, - 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, - 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, -}; - - -/****************************************************************************** -** utility functions -*/ - -static u_char -upcase(u_char c) -{ - - if (islower(c)) - return (toupper(c)); - else if (c >= 0x80) - return (upc_table[c - 0x80]); - else - return (c); -} - -static void -upcase_entry(regcontext_t *REGS) -{ - R_AL = upcase(R_AL); -} - - -/* -** Handle the DOS drive info/free space/etc. calls. -*/ -static int -int21_free(regcontext_t *REGS) -{ - fsstat_t fs; - int error; - int drive; - - /* work out drive */ - switch (R_AH) { - case 0x1c: - case 0x36: - drive = R_DL; - if (drive) - break; - /* FALLTHROUGH */ - case 0x1b: - drive = diskdrive; - break; - default: - fatal("int21_free called on unknown function %x\n",R_AH); - } - - error = get_space(drive, &fs); - if (error) - return(error); - - R_AL = fs.sectors_cluster; /* sectors per cluster */ - R_CX = fs.bytes_sector; /* bytes per sector */ - R_DX = fs.total_clusters; /* total clusters */ - - switch (R_AH) { - case 0x1b: - case 0x1c: - BIOSDATA[0xb4] = 0xf0; /* "reserved" area, "other media" FAT ID */ - R_DX = 0x40; /* BIOS data area */ - R_BX = 0xb4; - break; - - case 0x36: - R_BX = fs.avail_clusters; /* number of available clusters */ - break; - } - return(0); -} - -static void -pack_name(u_char *p, u_char *q) -{ - int i; - - for (i = 8; i > 0 && *p != ' '; i--) - *q++ = *p++; - p += i; - if (*p != ' ') { - *q++ = '.'; - for (i = 3; i > 0 && *p != ' '; i--) - *q++ = *p++; - p += i; - } - *q = '\0'; -} - -static void -dosdir_to_dta(dosdir_t *dosdir, find_block_t *dta) -{ - dta->attr = dosdir->attr; - dta->time = dosdir->time; - dta->date = dosdir->date; - dta->size = dosdir->size; - pack_name(dosdir->name, dta->name); -} - -/* exported */ -void -encode_dos_file_time(time_t t, u_short *dosdatep, u_short *dostimep) -{ - struct tm tm; - - tm = *localtime(&t); - *dostimep = (tm.tm_hour << 11) | - (tm.tm_min << 5) | - ((tm.tm_sec / 2) << 0); - *dosdatep = ((tm.tm_year - 80) << 9) | - ((tm.tm_mon + 1) << 5) | - (tm.tm_mday << 0); -} - -time_t -decode_dos_file_time(u_short dosdate, u_short dostime) -{ - struct tm tm; - time_t then; - - tm.tm_hour = (dostime >> 11) & 0x1f; - tm.tm_min = (dostime >> 5) & 0x3f; - tm.tm_sec = ((dostime >> 0) & 0x1f) * 2; - tm.tm_year = ((dosdate >> 9) & 0x7f) + 80; - tm.tm_mon = ((dosdate >> 5) & 0x0f) - 1; - tm.tm_mday = (dosdate >> 0) & 0x1f; - /* tm_wday and tm_yday are ignored. */ - tm.tm_isdst = 0; - /* tm_gmtoff is ignored. */ - then = mktime(&tm); - return (then); -} - -int -translate_filename(u_char *dname, u_char *uname, int *drivep) -{ - u_char newpath[1024]; - int error; - - if (!strcasecmp(dname, "con")) { - *drivep = -1; - strcpy(uname, _PATH_TTY); - return (0); - } - - /* XXX KLUDGE for EMS support w/o booting DOS */ - /* Really need a better way to handle devices */ - if (!strcasecmp(dname, "emmxxxx0")) { - *drivep = -1; - strcpy(uname, _PATH_DEVNULL); - return (0); - } - - error = dos_makepath(dname, newpath); - if (error) - return (error); - - error = dos_to_real_path(newpath, uname, drivep); - if (error) - return (error); - - return (0); -} - -static u_char magic[0x7e] = { - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - - 0x08, 0x0f, 0x06, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0x0f, 0x0f, 0x0f, 0x04, 0x04, 0x0f, 0x0e, 0x06, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0x0f, 0x0f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x0f, - - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0x0f, 0x0f, 0x0f, 0x06, 0x06, 0x06, 0x0f, 0x0f, - - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0x0f, 0x0f, 0x0f, 0x0f, 0x04, 0x0f, -}; - -#define isvalid(x) ((magic[(int)(x)] & 0x01) != 0) -#define issep(x) ((magic[(int)(x)] & 0x02) == 0) -#define iswhite(x) ((magic[(int)(x)] & 0x04) == 0) - -static char * -skipwhite(char *p) -{ - while (iswhite(*p)) - ++p; - return (p); -} - -#define get_drive_letter(x) ((x) - 0x40) - -int -parse_filename(int flag, char *str, char *fcb, int *nb) -{ - char *p; - int ret = 0; - int i; - - p = str; - - p = skipwhite(p); - if (flag & 1) { - if (issep(*p)) { - ++p; - p = skipwhite(p); - } - } - - if (isvalid(*p) && p[1] == ':') { - *fcb++ = get_drive_letter(upcase(*p)); - p += 2; - } else if (flag & 2) { - fcb++; - } else { - *fcb++ = 0; /* default drive */ - } - - i = 8; - if (isvalid(*p)) { - for (;;) { - if (!isvalid(*p)) { - for (; i > 0; i--) - *fcb++ = ' '; - break; - } - if (i > 0) { - switch (*p) { - case '*': - ret = 1; - for (; i > 0; i--) - *fcb++ = '?'; - break; - case '?': - ret = 1; - default: - *fcb++ = upcase(*p); - i--; - break; - } - } - ++p; - } - } else if (flag & 4) { - fcb += i; - } else { - for (; i > 0; i--) - *fcb++ = ' '; - } - - i = 3; - if (*p == '.') { - ++p; - for (;;) { - if (!isvalid(*p)) { - for (; i > 0; i--) - *fcb++ = ' '; - break; - } - if (i > 0) { - switch (*p) { - case '*': - ret = 1; - for (; i > 0; i--) - *fcb++ = '?'; - break; - case '?': - ret = 1; - default: - *fcb++ = upcase(*p); - i--; - break; - } - } - ++p; - } - } else if (flag & 8) { - fcb += i; - } else { - for (; i > 0; i--) - *fcb++ = ' '; - } - - for (i = 4; i > 0; i--) - *fcb++ = 0; /* filler */ - - *nb = p - str; - return (ret); -} - -/****************************************************************************** -** int21 functions -*/ - -/* -** 21:00 -** -** terminate -*/ -static int -int21_00(regcontext_t *REGS) -{ - done(REGS,0); - /* keep `gcc -Wall' happy */ - return(0); -} - -/* -** 21:01 -** -** read character with echo -*/ -static int -int21_01(regcontext_t *REGS) -{ - int n; - - if ((n = tty_read((regcontext_t *)®S->sc, TTYF_BLOCKALL)) >= 0) - R_AL = n; - return(0); -} - -/* -** 21:02 -** -** write char to stdout -*/ -static int -int21_02(regcontext_t *REGS) -{ - tty_write(R_DL, TTYF_REDIRECT); - return(0); -} - -/* -** 21:06 -** -** direct console I/O -** -** (dl) is output char unless 0xff, when we read instead -*/ -static int -int21_06(regcontext_t *REGS) -{ - int n; - - /* XXX - should be able to read a file */ - if (R_DL == 0xff) { - n = tty_read((regcontext_t *)®S->sc, TTYF_ECHO|TTYF_REDIRECT); - if (n < 0) { - R_FLAGS |= PSL_Z; /* nothing available */ - R_AL = 0; - } else { - R_AL = n; /* got character */ - R_FLAGS &= ~PSL_Z; - } - } else { - /* write and return char in %al */ - tty_write(R_DL, TTYF_REDIRECT); - R_AL = R_DL; - } - return(0); -} - -/* -** 21:07 -** -** direct console input with no echo -*/ -static int -int21_07(regcontext_t *REGS) -{ - R_AL = tty_read((regcontext_t *)®S->sc, - TTYF_BLOCK|TTYF_REDIRECT) & 0xff; - return(0); -} - -/* -** 21:08 -** -** character input with no echo -*/ -static int -int21_08(regcontext_t *REGS) -{ - int n; - - if ((n = tty_read((regcontext_t *)®S->sc, - TTYF_BLOCK|TTYF_CTRL|TTYF_REDIRECT)) >= 0) - R_AL = n; - return(0); -} - -/* -** 21:09 -** -** write string to standard out. -** -** We're a little paranoid here; if the string is very long, truncate it. -*/ -static int -int21_09(regcontext_t *REGS) -{ - char *addr; - int len; - - /* pointer to string */ - addr = (char *)MAKEPTR(R_DS, R_DX); - - /* walk string looking for terminator or overlength */ - for (len = 0; len < 10000; len++, addr++) { - if (*addr == '$') - break; - tty_write(*addr, TTYF_REDIRECT); - } - R_AL = 0x24; - return(0); -} - -/* -** 21:0a -** -** buffered input -*/ -static int -int21_0a(regcontext_t *REGS) -{ - unsigned char *addr; - int nbytes,avail; - int n; - - /* pointer to buffer */ - addr = (unsigned char *)MAKEPTR(R_DS, R_DX); - - /* capacity of buffer */ - avail = addr[0]; - if (avail == 0) /* no space */ - return(0); - nbytes = 0; /* read nothing yet */ - - /* read loop */ - while (1) { - n = tty_read((regcontext_t *)®S->sc, - TTYF_BLOCK|TTYF_CTRL|TTYF_REDIRECT); - if (n < 0) /* end of input */ - n = '\r'; /* make like CR */ - - switch (n) { - case '\r': /* done */ - addr[1] = nbytes; - addr[nbytes+2] = '\r'; - addr[nbytes+3] = '\0'; /* XXX is this necessary? */ - return (0); - case '\n': /* ignore */ - case '\0': - break; - case '\b': /* backspace */ - if (nbytes > 0) { - --nbytes; - tty_write('\b', TTYF_REDIRECT); - if (addr[nbytes+2] < ' ') - tty_write('\b', TTYF_REDIRECT); - } - break; - default: - if (nbytes >= (avail-2)) { /* buffer full */ - tty_write('\007', TTYF_REDIRECT); - } else { /* add to end */ - addr[(nbytes++) +2] = n; - if (n != '\t' && n < ' ') { - tty_write('^', TTYF_REDIRECT); - tty_write(n + '@', TTYF_REDIRECT); - } else - tty_write(n, TTYF_REDIRECT); - } - break; - } - } -} - -/* -** 21:0b -** -** get stdin status -** -** This is a favorite for camping on, so we do some poll-counting -** here as well. -*/ -static int -int21_0b(regcontext_t *REGS) -{ - int n; - - /* XXX this is pretty bogus, actually */ - if (!xmode) { - R_AL = 0xff; /* no X mode, always claim data available */ - return(0); - } - /* XXX tty_peek is broken */ - n = tty_peek(REGS, poll_cnt ? 0 : TTYF_POLL) ? 0xff : 0; - if (n < 0) /* control-break */ - return (0); - R_AL = n; /* will be 0 or 0xff */ - if (poll_cnt) - --poll_cnt; - return(0); -} - -/* -** 21:0c -** -** flush stdin and read using other function -*/ -static int -int21_0c(regcontext_t *REGS) -{ - if (xmode) /* XXX should always flush! */ - tty_flush(); - - switch(R_AL) { /* which subfunction? */ - case 0x01: - return(int21_01(REGS)); - case 0x06: - return(int21_06(REGS)); - case 0x07: - return(int21_07(REGS)); - case 0x08: - return(int21_08(REGS)); - case 0x0a: - return(int21_0a(REGS)); - } - return(0); -} - -/* -** 21:0e -** -** select default drive -*/ -static int -int21_0e(regcontext_t *REGS) -{ - diskdrive = R_DL; /* XXX rangecheck? */ - R_AL = ndisks + 2; /* report actual limit */ - return(0); -} - -/* -** 21:19 -** -** get default drive -*/ -static int -int21_19(regcontext_t *REGS) -{ - R_AL = diskdrive; - return(0); -} - -/* -** 21:1a -** -** set DTA -*/ -static int -int21_1a(regcontext_t *REGS) -{ - debug(D_FILE_OPS, "set dta to %x:%x\n", R_DS, R_DX); - disk_transfer_addr = MAKEVEC(R_DS, R_DX); - return(0); -} - -/* -** 21:23 -** -** Get file size for fcb -** DS:DX -> unopened FCB, no wildcards. -** pcb random record field filled in with number of records, rounded up. -*/ -static int -int21_23(regcontext_t *REGS) -{ - debug(D_HALF, "Returning failure from get file size for fcb 21:23\n"); - R_AL = 0xff; - return(0); -} - -/* -** 21:25 -** -** set interrupt vector -*/ -static int -int21_25(regcontext_t *REGS) -{ - debug(D_MEMORY, "%02x -> %04x:%04x\n", R_AL, R_DS, R_DX); - ivec[R_AL] = MAKEVEC(R_DS, R_DX); - return(0); -} - -/* -** 21:26 -** -** Create PSP -*/ -static int -int21_26(regcontext_t *REGS) -{ - unsigned char *addr; - - /* address of new PSP */ - addr = (unsigned char *)MAKEPTR(R_DX, 0); - - /* copy this process' PSP - XXX needs some work 8( */ - memcpy (addr, dosmem, 256); - return(0); -} - -/* -** 21:2a -** -** Get date -*/ -static int -int21_2a(regcontext_t *REGS) -{ - struct timeval tv; - struct timezone tz; - struct tm tm; - time_t now; - - gettimeofday(&tv, &tz); /* get time and apply DOS offset */ - now = tv.tv_sec + delta_clock; - - tm = *localtime(&now); /* deconstruct and timezoneify */ - R_CX = tm.tm_year + 1900; - R_DH = tm.tm_mon + 1; - R_DL = tm.tm_mday; - R_AL = tm.tm_wday; - return(0); -} - -/* -** 21:2b -** -** set date -*/ -static int -int21_2b(regcontext_t *REGS) -{ - struct timeval tv; - struct timezone tz; - struct tm tm; - time_t now; - - gettimeofday(&tv, &tz); /* get time and apply DOS offset */ - now = tv.tv_sec + delta_clock; - tm = *localtime(&now); - - tm.tm_year = R_CX - 1900; - tm.tm_mon = R_DH - 1; - tm.tm_mday = R_DL; - tm.tm_wday = R_AL; - - now = mktime(&tm); - if (now == -1) - return (DATA_INVALID); - - delta_clock = now - tv.tv_sec; /* compute new offset? */ - R_AL = 0; - return(0); -} - -/* -** 21:2c -** -** Get time -*/ -static int -int21_2c(regcontext_t *REGS) -{ - struct timeval tv; - struct timezone tz; - struct tm tm; - time_t now; - - gettimeofday(&tv, &tz); - now = tv.tv_sec + delta_clock; - tm = *localtime(&now); - - R_CH = tm.tm_hour; - R_CL = tm.tm_min; - R_DH = tm.tm_sec; - R_DL = tv.tv_usec / 10000; - return(0); -} - -/* -** 21:2d -** -** Set time -*/ -static int -int21_2d(regcontext_t *REGS) -{ - struct timeval tv; - struct timezone tz; - struct tm tm; - time_t now; - - gettimeofday(&tv, &tz); - now = tv.tv_sec + delta_clock; - tm = *localtime(&now); - - tm.tm_hour = R_CH; - tm.tm_min = R_CL; - tm.tm_sec = R_DH; - tv.tv_usec = R_DL * 10000; - - now = mktime(&tm); - if (now == -1) - return (DATA_INVALID); - - delta_clock = now - tv.tv_sec; - R_AL = 0; - return(0); -} - -/* -** 21:2f -** -** get DTA -*/ -static int -int21_2f(regcontext_t *REGS) -{ - PUTVEC(R_ES, R_BX, disk_transfer_addr); - debug(D_FILE_OPS, "get dta at %x:%x\n", R_ES, R_BX); - return(0); -} - -/* -** 21:30 -** -** get DOS version number. -** -** XXX begging for a rewrite -*/ -static int -int21_30(regcontext_t *REGS) -{ - int v; - - char *cmd = (char *)MAKEPTR(get_env(), 0); - - /* - * retch. I think this skips the environment and looks for the name - * of the current command. - */ - do { - while (*cmd) - ++cmd; - } while (*++cmd); - ++cmd; - cmd += *(short *)cmd + 1; - while (cmd[-1] && cmd[-1] != '\\' && cmd[-1] != ':') - --cmd; - - /* get the version we're pretending to be for this sucker */ - v = getver(cmd); - R_AL = (v / 100) & 0xff; - R_AH = v % 100; - return(0); -} - -/* -** 21:33:05 -** -** Get boot drive -*/ -static int -int21_33_5(regcontext_t *REGS) -{ - R_DL = 3; /* always booted from C */ - return(0); -} - -/* -** 21:33:06 -** -** get true DOS version -*/ -static int -int21_33_6(regcontext_t *REGS) -{ - int v; - - v = getver(NULL); - R_BL = (v / 100) & 0xff; - R_BH = v % 100; - R_DH = 0; - R_DL = 0; - return(0); -} - -/* -** 21:33 -** -** extended break checking -*/ -static int -int21_33(regcontext_t *REGS) -{ - int ftemp; - - switch (R_AL) { - case 0x00: - R_DL = ctrl_c_flag; - break; - case 0x01: - ctrl_c_flag = R_DL; - break; - case 0x02: - ftemp = ctrl_c_flag; - ctrl_c_flag = R_DL; - R_DL = ftemp; - break; - - default: - unknown_int3(0x21, 0x33, R_AL, REGS); - return(FUNC_NUM_IVALID); - } - return(0); -} - -/* -** 21:34 -** -** Get address of InDos flag -** -** XXX check interrupt list WRT location of critical error flag too. -*/ -static int -int21_34(regcontext_t *REGS) -{ - PUTVEC(R_ES, R_BX, (u_long)InDOS); - return(0); -} - -/* -** 21:35 -** -** get interrupt vector -*/ -static int -int21_35(regcontext_t *REGS) -{ - PUTVEC(R_ES, R_BX, ivec[R_AL]); - debug(D_MEMORY, "%02x <- %04x:%04x\n", R_AL, R_ES, R_BX); - return(0); -} - -/* -** 21:37 -** -** switch character manipulation -** -*/ -static int -int21_37(regcontext_t *REGS) -{ - switch (R_AL) { - case 0: /* get switch character */ - R_DL = '/'; - break; - - case 1: /* set switch character (normally /) */ - /* ignored by most versions of DOS */ - break; - default: - unknown_int3(0x21, 0x37, R_AL, REGS); - return (FUNC_NUM_IVALID); - } - return(0); - -} - -/* -** 21:38 -** -** country code information -** -** XXX internat guru? -*/ -static int -int21_38(regcontext_t *REGS) -{ - char *addr; - - if (R_DX == 0xffff) { - debug(D_HALF, "warning: set country code ignored"); - return(0); - } - addr = (char *)MAKEPTR(R_DS, R_DX); - PUTVEC(countryinfo.ciCaseMapSegment, countryinfo.ciCaseMapOffset, - upcase_vector); - memcpy(addr, &countryinfo, sizeof(countryinfo)); - return(0); -} - -/* -** 21:39 -** 21:3a -** 21:41 -** 21:56 -** -** mkdir, rmdir, unlink, rename -*/ -static int -int21_dirfn(regcontext_t *REGS) -{ - int error; - char fname[PATH_MAX],tname[PATH_MAX]; - int drive; - - error = translate_filename((u_char *)MAKEPTR(R_DS, R_DX), fname, &drive); - if (error) - return (error); - - if (dos_readonly(drive)) - return (WRITE_PROT_DISK); - - switch(R_AH) { - case 0x39: - debug(D_FILE_OPS, "mkdir(%s)\n", fname); - error = mkdir(fname, 0777); - break; - case 0x3a: - debug(D_FILE_OPS, "rmdir(%s)\n", fname); - error = rmdir(fname); - break; - case 0x41: - debug(D_FILE_OPS, "unlink(%s)\n", fname); - error = unlink(fname); - break; - case 0x56: /* rename - some extra work */ - error = translate_filename((u_char *)MAKEPTR(R_ES, R_DI), tname, &drive); - if (error) - return (error); - - debug(D_FILE_OPS, "rename(%s, %s)\n", fname, tname); - error = rename(fname, tname); - break; - - default: - fatal("call to int21_dirfn for unknown function %x\n",R_AH); - } - if (error < 0) { - switch (errno) { - case ENOTDIR: - case ENOENT: - return (PATH_NOT_FOUND); - case EXDEV: - return (NOT_SAME_DEV); - default: - return (ACCESS_DENIED); - } - } - return(0); -} - -/* -** 21:3b -** -** chdir -*/ -static int -int21_3b(regcontext_t *REGS) -{ - debug(D_FILE_OPS, "chdir(%s)\n",(u_char *)MAKEPTR(R_DS, R_DX)); - return(dos_setcwd((u_char *)MAKEPTR(R_DS, R_DX))); -} - -/* -** 21:3c -** 21:5b -** 21:6c -** -** open, creat, creat new, multipurpose creat -*/ -static int -int21_open(regcontext_t *REGS) -{ - int error; - char fname[PATH_MAX]; - struct stat sb; - int mode,action,status; - char *pname; - int drive; - int fd; - - switch(R_AH) { - case 0x3c: /* creat */ - pname = (char *)MAKEPTR(R_DS, R_DX); - action = 0x12; /* create/truncate regardless */ - mode = O_RDWR; - debug(D_FILE_OPS, "creat"); - break; - - case 0x3d: /* open */ - pname = (char *)MAKEPTR(R_DS, R_DX); - action = 0x01; /* fail if not exist, open if exists */ - switch (R_AL & 3) { - case 0: - mode = O_RDONLY; - break; - case 1: - mode = O_WRONLY; - break; - case 2: - mode = O_RDWR; - break; - default: - return (FUNC_NUM_IVALID); - } - debug(D_FILE_OPS, "open"); - break; - - case 0x5b: /* creat new */ - pname = (char *)MAKEPTR(R_DS, R_DL); - action = 0x10; /* create if not exist, fail if exists */ - mode = O_RDWR; - debug(D_FILE_OPS, "creat_new"); - break; - - case 0x6c: /* multipurpose */ - pname = (char *)MAKEPTR(R_DS, R_SI); - action = R_DX; - switch (R_BL & 3) { - case 0: - mode = O_RDONLY; - break; - case 1: - mode = O_WRONLY; - break; - case 2: - mode = O_RDWR; - break; - default: - return (FUNC_NUM_IVALID); - } - debug(D_FILE_OPS, "mopen"); - break; - - default: - fatal("called int21_creat for unknown function %x\n",R_AH); - } - if (action & 0x02) /* replace/open mode */ - mode |= O_TRUNC; - - /* consider proposed name */ - error = translate_filename(pname, fname, &drive); - if (error) - return (error); - - debug(D_FILE_OPS, "(%s)\n", fname); - - if (dos_readonly(drive) && (mode != O_RDONLY)) - return (WRITE_PROT_DISK); - - if (ustat(fname, &sb) < 0) { /* file does not exist */ - if (action & 0x10) { /* create? */ - sb.st_ino = 0; - mode |= O_CREAT; /* have to create as we go */ - status = 0x02; /* file created */ - } else { - return(FILE_NOT_FOUND); - } - } else { - if (S_ISDIR(sb.st_mode)) - return(ACCESS_DENIED); - if (action & 0x03) { /* exists, work with it */ - if (action & 0x02) { - if (!S_ISREG(sb.st_mode)) { /* only allowed for files */ - debug(D_FILE_OPS,"attempt to truncate non-regular file\n"); - return(ACCESS_DENIED); - } - status = 0x03; /* we're going to truncate it */ - } else { - status = 0x01; /* just open it */ - } - } else { - return(FILE_ALREADY_EXISTS); /* exists, fail */ - } - } - - if ((fd = open(fname, mode, from_dos_attr(R_CX))) < 0) { - debug(D_FILE_OPS,"failed to open %s : %s\n",fname,strerror(errno)); - return (ACCESS_DENIED); - } - - if (R_AH == 0x6c) /* need to return status too */ - R_CX = status; - R_AX = fd; /* return fd */ - return(0); -} - -/* -** 21:3e -** -** close -*/ -static int -int21_3e(regcontext_t *REGS) -{ - debug(D_FILE_OPS, "close(%d)\n", R_BX); - - if (R_BX == fileno(debugf)) { - printf("attempt to close debugging fd\n"); - return (HANDLE_INVALID); - } - - if (close(R_BX) < 0) - return (HANDLE_INVALID); - return(0); -} - -/* -** 21:3f -** -** read -*/ -static int -int21_3f(regcontext_t *REGS) -{ - char *addr; - int n; - int avail; - - addr = (char *)MAKEPTR(R_DS, R_DX); - - debug(D_FILE_OPS, "read(%d, %d)\n", R_BX, R_CX); - - if (R_BX == 0) { - if (redirect0) { - n = read (R_BX, addr, R_CX); - } else { - n = 0; - while (n < R_CX) { - avail = tty_read(REGS, TTYF_BLOCK|TTYF_CTRL|TTYF_ECHONL); - if (avail < 0) - return (0); - if ((addr[n++] = avail) == '\r') - break; - } - } - } else { - n = read (R_BX, addr, R_CX); - } - if (n < 0) - return (READ_FAULT); - - R_AX = n; - return(0); -} - -/* -** 21:40 -** -** write -*/ -static int -write_or_truncate(int fd, char *addr, int len) -{ - off_t offset; - - if (len == 0) { - offset = lseek(fd, 0, SEEK_CUR); - if (offset < 0) - return -1; - else - return ftruncate(fd, offset); - } else { - return write(fd, addr, len); - } -} - -static int -int21_40(regcontext_t *REGS) -{ - char *addr; - int nbytes,n; - - addr = (char *)MAKEPTR(R_DS, R_DX); - nbytes = R_CX; - - debug(D_FILE_OPS, "write(%d, %d)\n", R_BX, nbytes); - - switch (R_BX) { - case 0: - if (redirect0) { - n = write_or_truncate(R_BX, addr, nbytes); - break; - } - n = nbytes; - while (nbytes-- > 0) - tty_write(*addr++, -1); - break; - case 1: - if (redirect1) { - n = write_or_truncate(R_BX, addr, nbytes); - break; - } - n = nbytes; - while (nbytes-- > 0) - tty_write(*addr++, -1); - break; - case 2: - if (redirect2) { - n = write_or_truncate(R_BX, addr, nbytes); - break; - } - n = nbytes; - while (nbytes-- > 0) - tty_write(*addr++, -1); - break; - default: - n = write_or_truncate(R_BX, addr, nbytes); - break; - } - if (n < 0) - return (WRITE_FAULT); - - R_AX = n; - return(0); -} - -/* -** 21:42 -** -** seek -*/ -static int -int21_42(regcontext_t *REGS) -{ - int whence; - off_t offset; - - offset = (off_t) ((int) (R_CX << 16) + R_DX); - switch (R_AL) { - case 0: - whence = SEEK_SET; - break; - case 1: - whence = SEEK_CUR; - break; - case 2: - whence = SEEK_END; - break; - default: - return (FUNC_NUM_IVALID); - } - - debug(D_FILE_OPS, "seek(%d, 0x%qx, %d)\n", R_BX, offset, whence); - - if ((offset = lseek(R_BX, offset, whence)) < 0) { - if (errno == EBADF) - return (HANDLE_INVALID); - else - return (SEEK_ERROR); - } - - R_DX = (offset >> 16) & 0xffff; - R_AX = offset & 0xffff; - return(0); -} - -/* -** 21:43 -** -** get/set attributes -*/ -static int -int21_43(regcontext_t *REGS) -{ - int error; - char fname[PATH_MAX]; - struct stat sb; - int mode; - int drive; - - error = translate_filename((u_char *)MAKEPTR(R_DS, R_DX), fname, &drive); - if (error) - return (error); - - debug(D_FILE_OPS, "get/set attributes: %s, cx=%x, al=%d\n", - fname, R_CX, R_AL); - - if (stat(fname, &sb) < 0) { - debug(D_FILE_OPS, "stat failed for %s\n", fname); - return (FILE_NOT_FOUND); - } - - switch (R_AL) { - case 0: /* get attributes */ - mode = 0; - if (dos_readonly(drive) || access(fname, W_OK)) - mode |= 0x01; - if (S_ISDIR(sb.st_mode)) - mode |= 0x10; - R_CX = mode; - break; - - case 1: /* set attributes - XXX ignored */ - if (R_CX & 0x18) - return (ACCESS_DENIED); - break; - - default: - return (FUNC_NUM_IVALID); - } - return(0); -} - -/* -** 21:44:0 -** -** ioctl - get device info -** -** XXX it would be nice to detect EOF. -*/ -static int -int21_44_0(regcontext_t *REGS) -{ - debug(D_FILE_OPS, "ioctl get %d\n", R_BX); - - switch (R_BX) { - case 0: - R_DX = 0x80 | 0x01; /* is device, is standard output */ - break; - case 1: - R_DX = 0x80 | 0x02; /* is device, is standard input */ - break; - case 2: - R_DX = 0x80; /* is device */ - break; - default: - if (isatty (R_BX)) - R_DX = 0x80; /* is a device */ - else - R_DX = 0; /* is a file */ - break; - } - return(0); -} - -/* -** 21:44:01 -** -** ioctl - set device info -*/ -static int -int21_44_1(regcontext_t *REGS) -{ - debug(D_FILE_OPS, "ioctl set device info %d flags %x (ignored)\n", - R_BX, R_DX); - return(0); -} - -/* -** 21:44:7 -** -** Get output status -*/ -static int -int21_44_7(regcontext_t *REGS) -{ - /* XXX Should really check to see if BX is open or not */ - R_AX = 0xFF; - return(0); -} - -/* -** 21:44:8 -** -** test for removable block device -*/ -static int -int21_44_8(regcontext_t *REGS) -{ - R_AX = 1; /* fixed */ - return(0); -} - -/* -** 21:44:0 -** -** test for remote device (disallow direct I/O) -*/ -static int -int21_44_9(regcontext_t *REGS) -{ - R_DX = 0x1200; /* disk is remote, direct I/O not allowed */ - return (0); -} - -/* -** 21:45 -** -** dup -*/ -static int -int21_45(regcontext_t *REGS) -{ - int nfd; - - debug(D_FILE_OPS, "dup(%d)\n", R_BX); - - if ((nfd = dup(R_BX)) < 0) { - if (errno == EBADF) - return (HANDLE_INVALID); - else - return (TOO_MANY_OPEN_FILES); - } - R_AX = nfd; - return(0); -} - -/* -** 21:46 -** -** dup2 -*/ -static int -int21_46(regcontext_t *REGS) -{ - debug(D_FILE_OPS, "dup2(%d, %d)\n", R_BX, R_CX); - - if (dup2(R_BX, R_CX) < 0) { - if (errno == EMFILE) - return (TOO_MANY_OPEN_FILES); - else - return (HANDLE_INVALID); - } - return(0); -} - -/* -** 21:47 -** -** getcwd -*/ -static int -int21_47(regcontext_t *REGS) -{ - int n,nbytes; - char *p,*addr; - - n = R_DL; - if (!n--) - n = diskdrive; - - p = (char *)dos_getcwd(n) + 1; - addr = (char *)MAKEPTR(R_DS, R_SI); - - nbytes = strlen(p); - if (nbytes > 63) - nbytes = 63; - - memcpy(addr, p, nbytes); - addr[nbytes] = 0; - return(0); -} - -/* -** 21:48 -** -** allocate memory -*/ -static int -int21_48(regcontext_t *REGS) -{ - int memseg,avail; - - memseg = mem_alloc(R_BX, pspseg, &avail); - - if (memseg == 0L) { - R_BX = avail; - return (INSUF_MEM); - } - - R_AX = memseg; - return(0); -} - -/* -** 21:49 -** -** free memory -*/ -static int -int21_49(regcontext_t *REGS) -{ - if (mem_adjust(R_ES, 0, NULL) < 0) - return (MEM_BLK_ADDR_IVALID); - return(0); -} - -/* -** 21:4a -** -** resize memory block -*/ -static int -int21_4a(regcontext_t *REGS) -{ - int n,avail; - - if ((n = mem_adjust(R_ES, R_BX, &avail)) < 0) { - R_BX = avail; - if (n == -1) - return (INSUF_MEM); - else - return (MEM_BLK_ADDR_IVALID); - } - return(0); -} - -/* -** 21:4b -** -** exec -** -** XXX verify! -*/ -static int -int21_4b(regcontext_t *REGS) -{ - int fd; - u_short *param; - - debug(D_EXEC, "exec(%s)\n",(u_char *)MAKEPTR(R_DS, R_DX)); - - if ((fd = open_prog((u_char *)MAKEPTR(R_DS, R_DX))) < 0) { - debug(D_EXEC, "%s: command not found\n", - (u_char *)MAKEPTR(R_DS, R_DX)); - return (FILE_NOT_FOUND); - } - - /* child */ - param = (u_short *)MAKEPTR(R_ES, R_BX); - - switch (R_AL) { - case 0x00: /* load and execute */ - exec_command(REGS, 1, fd, cmdname, param); - close(fd); - break; - - case 0x01: /* just load */ - exec_command(REGS, 0, fd, cmdname, param); - close(fd); - break; - - case 0x03: /* load overlay */ - load_overlay(fd, param[0], param[1]); - close(fd); - break; - - default: - unknown_int3(0x21, 0x4b, R_AL, REGS); - return (FUNC_NUM_IVALID); - } - return(0); -} - -/* -** 21:4c -** -** return with code -*/ -static int -int21_4c(regcontext_t *REGS) -{ - return_status = R_AL; - done(REGS, R_AL); - return 0; -} - -/* -** 21:4d -** -** get return code of child -*/ -static int -int21_4d(regcontext_t *REGS) -{ - R_AX = return_status; - return(0); -} - -/* -** 21:4e -** 21:4f -** -** find first, find next -*/ -static int -int21_find(regcontext_t *REGS) -{ - find_block_t *dta; - dosdir_t dosdir; - int error; - - dta = (find_block_t *)VECPTR(disk_transfer_addr); - - switch (R_AH) { - case 0x4e: /* find first */ - error = find_first((u_char *)MAKEPTR(R_DS, R_DX), R_CX, &dosdir, dta); - break; - case 0x4f: - error = find_next(&dosdir, dta); - break; - default: - fatal("called int21_find for unknown function %x\n",R_AH); - } - if (!error) { - dosdir_to_dta(&dosdir, dta); - R_AX = 0; - } - return(error); -} - -/* -** 21:50 -** -** set PSP -*/ -static int -int21_50(regcontext_t *REGS) -{ - pspseg = R_BX; - return(0); -} - -/* -** 21:57:00 -** -** get mtime for handle -*/ -static int -int21_57_0(regcontext_t *REGS) -{ - struct stat sb; - u_short date, mtime; - - if (fstat(R_BX, &sb) < 0) - return (HANDLE_INVALID); - encode_dos_file_time(sb.st_mtime, &date, &mtime); - R_CX = mtime; - R_DX = date; - return(0); -} - -/* -** 21:57:01 -** -** set mtime for handle -*/ -static int -int21_57_1(regcontext_t *REGS __unused) -{ -#ifdef __NetBSD__ /* XXX need futimes() */ - struct stat sb; - struct timeval tv[2]; - u_short date, time; - - time = R_CX; - date = R_DX; - tv[0].tv_sec = tv[1].tv_sec = decode_dos_file_time(date, time); - tv[0].tv_usec = tv[1].tv_usec = 0; - if (futimes(R_BX, tv) < 0) - return (HANDLE_INVALID); - break; -#endif - return(0); -} - -/* -** 21:58 -** -** get/set memory strategy -** get/set UMB link state -*/ -static int -int21_58(regcontext_t *REGS) -{ - switch (R_AL) { - case 0x00: /* get memory strategy */ - R_AX = memory_strategy; - break; - case 0x01: /* set memory strategy */ - memory_strategy = R_BL; - if (memory_strategy > 2) /* higher make no sense without UMBs */ - memory_strategy = 2; - break; - case 0x02: /* get UMB link state */ - R_AL = 0; /* UMBs not in link chain */ - break; - default: /* includes set, which is invalid */ - unknown_int3(0x21, 0x58, R_AL, REGS); - return (FUNC_NUM_IVALID); - } - return(0); -} - -/* -** 21:59 -** -** get extended error information -*/ -static int -int21_59(regcontext_t *REGS) -{ - R_AX = doserrno; - switch (doserrno) { - case 1: - case 6: - case 9: - case 10: - case 11: - case 12: - case 13: - case 15: - R_BH = 7; /* application error */ - break; - - case 2: - case 3: - case 4: - case 5: - R_BH = 8; /* not found */ - break; - - case 7: - case 8: - R_BH = 1; /* out of resource */ - break; - - default: - R_BH = 12; /* already exists */ - break; - } - R_BL = 6; /* always ignore! */ - R_CH = 1; /* unknown/inappropriate */ - return(0); -} - -/* -** 21:5a -** -** create temporary file -*/ -static int -int21_5a(regcontext_t *REGS) -{ - char fname[PATH_MAX]; - char *pname; - int error; - int n; - int drive; - int fd; - - /* get and check proposed path */ - pname = (char *)MAKEPTR(R_DS, R_DX); - error = translate_filename(pname, fname, &drive); - if (error) - return (error); - - debug(D_FILE_OPS, "tempname(%s)\n", fname); - - if (dos_readonly(drive)) - return (WRITE_PROT_DISK); - - n = strlen(fname); - strcat(fname,"__dostmp.XXX"); - fd = mkstemp(fname); - if (fd < 0) - return (ACCESS_DENIED); - - strcat(pname, fname + n); /* give back the full name */ - R_AX = fd; - return(0); -} - -/* -** 21:60 -** -** canonicalise name -*/ -static int -int21_60(regcontext_t *REGS) -{ - return(dos_makepath((char *)MAKEPTR(R_DS, R_SI), - (char *)MAKEPTR(R_ES, R_DI))); -} - -/* -** 21:62 -** -** get current PSP -*/ -static int -int21_62(regcontext_t *REGS) -{ - R_BX = pspseg; - return(0); -} - -/* -** 21:65:23 -** -** determine yes/no -** (mostly for humour value 8) -*/ -static int -int21_65_23(regcontext_t *REGS) -{ - switch (R_DL) { - case 'n': /* no, nein, non, nyet */ - case 'N': - R_AX = 0; - break; - case 'y': /* yes */ - case 'Y': - case 'j': /* ja */ - case 'J': - case 'o': /* oui */ - case 'O': - case 'd': /* da */ - case 'D': - R_AX = 1; - break; - default: /* maybe */ - R_AX = 2; - break; - } - return(0); -} - -/* -** 21:68 -** 21:6a -** -** fflush/commit file -*/ -static int -int21_fflush(regcontext_t *REGS) -{ - debug(D_FILE_OPS, "fsync(%d)\n", R_BX); - - if (fsync(R_BX) < 0) - return (HANDLE_INVALID); - return(0); -} - -/****************************************************************************** -** 21:0f 21:10 21:11 21:12 21:16 21:27 21:28:21:29 -** -** FCB functions -*/ -static void -openfcb(struct fcb *fcbp) -{ - struct stat statb; - - fcbp->fcbDriveID = 3; /* drive C */ - fcbp->fcbCurBlockNo = 0; - fcbp->fcbRecSize = 128; - if (fstat(fcbp->fcb_fd, &statb) < 0) { - debug(D_FILE_OPS, "open not complete with errno %d\n", errno); - return; - } - encode_dos_file_time(statb.st_mtime, - &fcbp->fcbFileDate, &fcbp->fcbFileTime); - fcbp->fcbFileSize = statb.st_size; -} - -static int -getfcb_rec(struct fcb *fcbp, int nrec) -{ - int n; - - n = fcbp->fcbRandomRecNo; - if (fcbp->fcbRecSize >= 64) - n &= 0xffffff; - fcbp->fcbCurRecNo = n % 128; - fcbp->fcbCurBlockNo = n / 128; - if (lseek(fcbp->fcb_fd, n * fcbp->fcbRecSize, SEEK_SET) < 0) - return (-1); - return (nrec * fcbp->fcbRecSize); -} - - -static int -setfcb_rec(struct fcb *fcbp, int n) -{ - int recs, total; - - total = fcbp->fcbRandomRecNo; - if (fcbp->fcbRecSize >= 64) - total &= 0xffffff; - recs = (n+fcbp->fcbRecSize-1) / fcbp->fcbRecSize; - total += recs; - - fcbp->fcbRandomRecNo = total; - fcbp->fcbCurRecNo = total % 128; - fcbp->fcbCurBlockNo = total / 128; - - return(0); -} - -static void -fcb_to_string(fcbp, buf) - struct fcb *fcbp; - u_char *buf; -{ - - if (fcbp->fcbDriveID != 0x00) { - *buf++ = drntol(fcbp->fcbDriveID - 1); - *buf++ = ':'; - } - pack_name(fcbp->fcbFileName, buf); -} - - -static int -int21_fcb(regcontext_t *REGS) -{ - char buf[PATH_MAX]; - char fname[PATH_MAX]; - struct stat sb; - dosdir_t dosdir; - struct fcb *fcbp; - find_block_t *dta; - u_char *addr; - int error; - int drive; - int fd; - int nbytes,n; - - - fcbp = (struct fcb *)MAKEPTR(R_DS, R_DX); - - switch (R_AH) { - - case 0x0f: /* open file with FCB */ - fcb_to_string(fcbp, buf); - error = translate_filename(buf, fname, &drive); - if (error) - return (error); - - debug(D_FILE_OPS, "open FCB(%s)\n", fname); - - if (ustat(fname, &sb) < 0) - sb.st_ino = 0; - - if (dos_readonly(drive)) - return (WRITE_PROT_DISK); - - if (sb.st_ino == 0 || S_ISDIR(sb.st_mode)) - return (FILE_NOT_FOUND); - - if ((fd = open(fname, O_RDWR)) < 0) { - if (errno == ENOENT) - return (FILE_NOT_FOUND); - else - return (ACCESS_DENIED); - } - - fcbp->fcb_fd = fd; - openfcb(fcbp); - R_AL = 0; - break; - - case 0x10: /* close file with FCB */ - debug(D_FILE_OPS, "close FCB(%d)\n", fcbp->fcb_fd); - - if (close(fcbp->fcb_fd) < 0) - return (HANDLE_INVALID); - - fcbp->fcb_fd = -1; - R_AL = 0; - break; - - case 0x11: /* find_first with FCB */ - dta = (find_block_t *)VECPTR(disk_transfer_addr); - - fcb_to_string(fcbp, buf); - error = find_first(buf, fcbp->fcbAttribute, &dosdir, dta); - if (error) - return (error); - - dosdir_to_dta(&dosdir, dta); - R_AL = 0; - break; - - case 0x12: /* find_next with FCB */ - dta = (find_block_t *)VECPTR(disk_transfer_addr); - - error = find_next(&dosdir, dta); - if (error) - return (error); - - dosdir_to_dta(&dosdir, dta); - R_AL = 0; - break; - - case 0x16: /* create file with FCB */ - fcb_to_string(fcbp, buf); - error = translate_filename(buf, fname, &drive); - if (error) - return (error); - - debug(D_FILE_OPS, "creat FCB(%s)\n", fname); - - if (ustat(fname, &sb) < 0) - sb.st_ino = 0; - - if (dos_readonly(drive)) - return (WRITE_PROT_DISK); - - if (sb.st_ino && !S_ISREG(sb.st_mode)) - return (ACCESS_DENIED); - - if ((fd = open(fname, O_CREAT|O_TRUNC|O_RDWR, 0666)) < 0) - return (ACCESS_DENIED); - - fcbp->fcb_fd = fd; - openfcb(fcbp); - R_AL = 0; - break; - - case 0x27: /* random block read */ - addr = (u_char *)VECPTR(disk_transfer_addr); - nbytes = getfcb_rec(fcbp, R_CX); - - if (nbytes < 0) - return (READ_FAULT); - n = read(fcbp->fcb_fd, addr, nbytes); - if (n < 0) - return (READ_FAULT); - R_CX = setfcb_rec(fcbp, n); - if (n < nbytes) { - nbytes = n % fcbp->fcbRecSize; - if (0 == nbytes) { - R_AL = 0x01; - } else { - bzero(addr + n, fcbp->fcbRecSize - nbytes); - R_AL = 0x03; - } - } else { - R_AL = 0; - } - break; - - case 0x28: /* random block write */ - addr = (u_char *)VECPTR(disk_transfer_addr); - nbytes = getfcb_rec(fcbp, R_CX); - - if (nbytes < 0) - return (WRITE_FAULT); - n = write(fcbp->fcb_fd, addr, nbytes); - if (n < 0) - return (WRITE_FAULT); - R_CX = setfcb_rec(fcbp, n); - if (n < nbytes) { - R_AL = 0x01; - } else { - R_AL = 0; - } - break; - - case 0x29: /* parse filename */ - debug(D_FILE_OPS,"parse filename: flag=%d, ", R_AL); - - R_AX = parse_filename(R_AL, - (char *)MAKEPTR(R_DS, R_SI), - (char *)MAKEPTR(R_ES, R_DI), - &nbytes); - debug(D_FILE_OPS, "%d %s, FCB: %d, %.11s\n", - nbytes, - (char *)MAKEPTR(R_DS, R_SI), - *(int *)MAKEPTR(R_ES, R_DI), - (char *)MAKEPTR(R_ES, R_DI) + 1); - - R_SI += nbytes; - break; - - default: - fatal("called int21_fcb with unknown function %x\n",R_AH); - } - return(0); -} - -/* -** 21:5d -** 21:5e -** 21:5f -** -** network functions -** XXX relevant? -*/ -static int -int21_net(regcontext_t *REGS) -{ - switch(R_AH) { - case 0x5d: - switch(R_AL) { - case 0x06: - debug(D_HALF, "Get Swapable Area\n"); - return (ACCESS_DENIED); - case 0x08: /* Set redirected printer mode */ - debug(D_HALF, "Redirection is %s\n", - R_DL ? "separate jobs" : "combined"); - break; - case 0x09: /* Flush redirected printer output */ - break; - default: - unknown_int3(0x21, 0x5d, R_AL, REGS); - return (FUNC_NUM_IVALID); - } - break; - - case 0x5e: - case 0x5f: - unknown_int2(0x21, R_AH, REGS); - return (FUNC_NUM_IVALID); - default: - fatal("called int21_net with unknown function %x\n",R_AH); - } - return(0); -} - -/* -** 21:?? -** -** Unknown/unsupported -*/ -static int -int21_NOFUNC(regcontext_t *REGS) -{ - unknown_int2(0x21, R_AH, REGS); - return (FUNC_NUM_IVALID); -} - -/* -** 21:?? -** -** Null function; no error, no action -*/ -static int -int21_NULLFUNC(regcontext_t *REGS) -{ - R_AL = 0; - return(0); -} - - -static struct intfunc_table int21_table [] = { - { 0x00, IFT_NOSUBFUNC, int21_00, "terminate"}, - { 0x01, IFT_NOSUBFUNC, int21_01, "read character with echo"}, - { 0x02, IFT_NOSUBFUNC, int21_02, "write char to stdout"}, - { 0x03, IFT_NOSUBFUNC, int21_NOFUNC, "read char from stdaux"}, - { 0x04, IFT_NOSUBFUNC, int21_NOFUNC, "write char to stdaux"}, - { 0x05, IFT_NOSUBFUNC, int21_NOFUNC, "write char to printer"}, - { 0x06, IFT_NOSUBFUNC, int21_06, "direct console I/O"}, - { 0x07, IFT_NOSUBFUNC, int21_07, "direct console in without echo"}, - { 0x08, IFT_NOSUBFUNC, int21_08, "read character, no echo"}, - { 0x09, IFT_NOSUBFUNC, int21_09, "write string to standard out"}, - { 0x0a, IFT_NOSUBFUNC, int21_0a, "buffered input"}, - { 0x0b, IFT_NOSUBFUNC, int21_0b, "get stdin status"}, - { 0x0c, IFT_NOSUBFUNC, int21_0c, "flush stdin and read"}, - { 0x0d, IFT_NOSUBFUNC, int21_NULLFUNC, "disk reset"}, - { 0x0e, IFT_NOSUBFUNC, int21_0e, "select default drive"}, - { 0x19, IFT_NOSUBFUNC, int21_19, "get default drive"}, - { 0x1a, IFT_NOSUBFUNC, int21_1a, "set DTA"}, - { 0x1b, IFT_NOSUBFUNC, int21_free, "get allocation for default drive"}, - { 0x1c, IFT_NOSUBFUNC, int21_free, "get allocation for specific drive"}, - { 0x1f, IFT_NOSUBFUNC, int21_NOFUNC, "get DPB for current drive"}, - { 0x23, IFT_NOSUBFUNC, int21_23, "Get file size (old)"}, - { 0x25, IFT_NOSUBFUNC, int21_25, "set interrupt vector"}, - { 0x26, IFT_NOSUBFUNC, int21_26, "create new PSP"}, - { 0x2a, IFT_NOSUBFUNC, int21_2a, "get date"}, - { 0x2b, IFT_NOSUBFUNC, int21_2b, "set date"}, - { 0x2c, IFT_NOSUBFUNC, int21_2c, "get time"}, - { 0x2d, IFT_NOSUBFUNC, int21_2d, "set time"}, - { 0x2e, IFT_NOSUBFUNC, int21_NULLFUNC, "set verify flag"}, - { 0x2f, IFT_NOSUBFUNC, int21_2f, "get DTA"}, - { 0x30, IFT_NOSUBFUNC, int21_30, "get DOS version"}, - { 0x31, IFT_NOSUBFUNC, int21_NOFUNC, "terminate and stay resident"}, - { 0x32, IFT_NOSUBFUNC, int21_NOFUNC, "get DPB for specific drive"}, - { 0x33, 0x05, int21_33_5, "get boot drive"}, - { 0x33, 0x06, int21_33_6, "get true version number"}, - { 0x33, IFT_NOSUBFUNC, int21_33, "extended break checking"}, - { 0x34, IFT_NOSUBFUNC, int21_34, "get address of InDos flag"}, - { 0x35, IFT_NOSUBFUNC, int21_35, "get interrupt vector"}, - { 0x36, IFT_NOSUBFUNC, int21_free, "get disk free space"}, - { 0x37, IFT_NOSUBFUNC, int21_37, "switch character"}, - { 0x38, IFT_NOSUBFUNC, int21_38, "country code/information"}, - { 0x39, IFT_NOSUBFUNC, int21_dirfn, "mkdir"}, - { 0x3a, IFT_NOSUBFUNC, int21_dirfn, "rmdir"}, - { 0x3b, IFT_NOSUBFUNC, int21_3b, "chdir"}, - { 0x3c, IFT_NOSUBFUNC, int21_open, "creat"}, - { 0x3d, IFT_NOSUBFUNC, int21_open, "open"}, - { 0x3e, IFT_NOSUBFUNC, int21_3e, "close"}, - { 0x3f, IFT_NOSUBFUNC, int21_3f, "read"}, - { 0x40, IFT_NOSUBFUNC, int21_40, "write"}, - { 0x41, IFT_NOSUBFUNC, int21_dirfn, "unlink"}, - { 0x42, IFT_NOSUBFUNC, int21_42, "lseek"}, - { 0x43, IFT_NOSUBFUNC, int21_43, "get/set file attributes"}, - { 0x44, 0x00, int21_44_0, "ioctl(get)"}, - { 0x44, 0x01, int21_44_1, "ioctl(set)"}, - { 0x44, 0x07, int21_44_7, "ioctl(Check output status)"}, - { 0x44, 0x08, int21_44_8, "ioctl(test removable)"}, - { 0x44, 0x09, int21_44_9, "ioctl(test remote)"}, - { 0x45, IFT_NOSUBFUNC, int21_45, "dup"}, - { 0x46, IFT_NOSUBFUNC, int21_46, "dup2"}, - { 0x47, IFT_NOSUBFUNC, int21_47, "getwd"}, - { 0x48, IFT_NOSUBFUNC, int21_48, "allocate memory"}, - { 0x49, IFT_NOSUBFUNC, int21_49, "free memory"}, - { 0x4a, IFT_NOSUBFUNC, int21_4a, "resize memory block"}, - { 0x4b, IFT_NOSUBFUNC, int21_4b, "exec"}, - { 0x4c, IFT_NOSUBFUNC, int21_4c, "exit with return code"}, - { 0x4d, IFT_NOSUBFUNC, int21_4d, "get return code from child"}, - { 0x4e, IFT_NOSUBFUNC, int21_find, "findfirst"}, - { 0x4f, IFT_NOSUBFUNC, int21_find, "findnext"}, - { 0x50, IFT_NOSUBFUNC, int21_50, "set psp"}, - { 0x51, IFT_NOSUBFUNC, int21_62, "get psp"}, - { 0x52, IFT_NOSUBFUNC, int21_NOFUNC, "get LoL"}, - { 0x53, IFT_NOSUBFUNC, int21_NOFUNC, "translate BPB to DPB"}, - { 0x54, IFT_NOSUBFUNC, int21_NULLFUNC, "get verify flag"}, - { 0x55, IFT_NOSUBFUNC, int21_NOFUNC, "create PSP"}, - { 0x56, IFT_NOSUBFUNC, int21_dirfn, "rename"}, - { 0x57, 0x00, int21_57_0, "get mtime"}, - { 0x57, 0x01, int21_57_1, "set mtime"}, - { 0x58, IFT_NOSUBFUNC, int21_58, "get/set memory strategy"}, - { 0x59, IFT_NOSUBFUNC, int21_59, "get extended error information"}, - { 0x5a, IFT_NOSUBFUNC, int21_5a, "create temporary file"}, - { 0x5b, IFT_NOSUBFUNC, int21_open, "create new file"}, - { 0x5c, IFT_NOSUBFUNC, int21_NOFUNC, "flock"}, - { 0x5d, IFT_NOSUBFUNC, int21_net, "network functions"}, - { 0x5e, IFT_NOSUBFUNC, int21_net, "network functions"}, - { 0x5f, IFT_NOSUBFUNC, int21_net, "network functions"}, - { 0x60, IFT_NOSUBFUNC, int21_60, "canonicalise name/path"}, - { 0x61, IFT_NOSUBFUNC, int21_NULLFUNC, "network functions (reserved)"}, - { 0x62, IFT_NOSUBFUNC, int21_62, "get current PSP"}, - { 0x63, IFT_NOSUBFUNC, int21_NOFUNC, "get DBCS lead-byte table"}, - { 0x64, IFT_NOSUBFUNC, int21_NOFUNC, "set device-driver lookahead"}, - { 0x65, 0x23, int21_65_23, "determine yes/no"}, - { 0x65, IFT_NOSUBFUNC, int21_NOFUNC, "get extended country information"}, - { 0x66, IFT_NOSUBFUNC, int21_NOFUNC, "get/set codepage table"}, - { 0x67, IFT_NOSUBFUNC, int21_NULLFUNC, "set handle count"}, - { 0x68, IFT_NOSUBFUNC, int21_fflush, "fflush"}, - { 0x69, IFT_NOSUBFUNC, int21_NOFUNC, "get/set disk serial number"}, - { 0x6a, IFT_NOSUBFUNC, int21_fflush, "commit file"}, - { 0x6b, IFT_NOSUBFUNC, int21_NULLFUNC, "IFS ioctl"}, - { 0x6c, IFT_NOSUBFUNC, int21_open, "extended open/create"}, - -/* FCB functions */ - { 0x0f, IFT_NOSUBFUNC, int21_fcb, "open file"}, - { 0x10, IFT_NOSUBFUNC, int21_fcb, "close file"}, - { 0x11, IFT_NOSUBFUNC, int21_fcb, "find first"}, - { 0x12, IFT_NOSUBFUNC, int21_fcb, "find next"}, - { 0x13, IFT_NOSUBFUNC, int21_NOFUNC, "delete"}, - { 0x14, IFT_NOSUBFUNC, int21_NOFUNC, "sequential read"}, - { 0x15, IFT_NOSUBFUNC, int21_NOFUNC, "sequential write"}, - { 0x16, IFT_NOSUBFUNC, int21_fcb, "create/truncate"}, - { 0x17, IFT_NOSUBFUNC, int21_NOFUNC, "rename"}, - { 0x21, IFT_NOSUBFUNC, int21_NOFUNC, "read random"}, - { 0x22, IFT_NOSUBFUNC, int21_NOFUNC, "write random"}, - { 0x23, IFT_NOSUBFUNC, int21_NOFUNC, "get file size"}, - { 0x24, IFT_NOSUBFUNC, int21_NOFUNC, "set random record number"}, - { 0x27, IFT_NOSUBFUNC, int21_fcb, "random block read"}, - { 0x28, IFT_NOSUBFUNC, int21_fcb, "random block write"}, - { 0x29, IFT_NOSUBFUNC, int21_fcb, "parse filename into FCB"}, - -/* CPM compactability */ - { 0x18, IFT_NOSUBFUNC, int21_NULLFUNC, "CPM"}, - { 0x1d, IFT_NOSUBFUNC, int21_NULLFUNC, "CPM"}, - { 0x1e, IFT_NOSUBFUNC, int21_NULLFUNC, "CPM"}, - { 0x20, IFT_NOSUBFUNC, int21_NULLFUNC, "CPM"}, - - { -1, IFT_NOSUBFUNC, NULL, NULL} /* terminator */ - -}; - -static int int21_fastlookup[256]; - -const char *dos_return[] = { - "OK", - "FUNC_NUM_IVALID", - "FILE_NOT_FOUND", - "PATH_NOT_FOUND", - "TOO_MANY_OPEN_FILES", - "ACCESS_DENIED", - "HANDLE_INVALID", - "MEM_CB_DEST", - "INSUF_MEM", - "MEM_BLK_ADDR_IVALID", - "ENV_INVALID", - "FORMAT_INVALID", - "ACCESS_CODE_INVALID", - "DATA_INVALID", - "UNKNOWN_UNIT", - "DISK_DRIVE_INVALID", - "ATT_REM_CUR_DIR", - "NOT_SAME_DEV", - "NO_MORE_FILES", - "WRITE_PROT_DISK", - "UNKNOWN_UNIT_CERR", - "DRIVE_NOT_READY", - "UNKNOWN_COMMAND", - "DATA_ERROR_CRC", - "BAD_REQ_STRUCT_LEN", - "SEEK_ERROR", - "UNKNOWN_MEDIA_TYPE", - "SECTOR_NOT_FOUND", - "PRINTER_OUT_OF_PAPER", - "WRITE_FAULT", - "READ_FAULT", - "GENERAL_FAILURE" -}; - -const int dos_ret_size = (sizeof(dos_return) / sizeof(char *)); - -/* -** for want of anywhere better to go -*/ -static void -int20(regcontext_t *REGS) -{ - /* int 20 = exit(0) */ - done(REGS, 0); -} - -static void -int29(regcontext_t *REGS) -{ - tty_write(R_AL, TTYF_REDIRECT); -} - -/****************************************************************************** -** entrypoint for MS-DOS functions -*/ -static void -int21(regcontext_t *REGS) -{ - int error; - int idx; - - /* look for a handler */ - idx = intfunc_find(int21_table, int21_fastlookup, R_AH, R_AL); - - if (idx == -1) { /* no matching functions */ - unknown_int3(0x21, R_AH, R_AL, REGS); - R_FLAGS |= PSL_C; /* Flag an error */ - R_AX = 0xff; - return; - } - - /* call the handler */ - error = int21_table[idx].handler(REGS); - debug(D_DOSCALL, "msdos call %02x (%s) returns %d (%s)\n", - int21_table[idx].func, int21_table[idx].desc, error, - ((error >= 0) && (error <= dos_ret_size)) ? dos_return[error] : "unknown"); - - if (error) { - doserrno = error; - R_FLAGS |= PSL_C; - - /* XXX is this entirely legitimate? */ - if (R_AH >= 0x2f) - R_AX = error; - else - R_AX = 0xff; - } else { - R_FLAGS &= ~PSL_C; - } - return; -} - -static void -int67(regcontext_t *REGS) -{ - ems_entry(REGS); -} - -static u_char upcase_trampoline[] = { - 0xf4, /* HLT */ - 0xcb, /* RETF */ -}; - -/* -** initialise thyself -*/ -void -dos_init(void) -{ - u_long vec; - - /* hook vectors */ - vec = insert_softint_trampoline(); - ivec[0x20] = vec; - register_callback(vec, int20, "int 20"); - - vec = insert_softint_trampoline(); - ivec[0x21] = vec; - register_callback(vec, int21, "int 21"); - - vec = insert_softint_trampoline(); - ivec[0x29] = vec; - register_callback(vec, int29, "int 29"); - - vec = insert_softint_trampoline(); - ivec[0x67] = vec; - register_callback(vec, int67, "int 67 (EMS)"); - - vec = insert_null_trampoline(); - ivec[0x28] = vec; /* dos idle */ - ivec[0x2b] = vec; /* reserved */ - ivec[0x2c] = vec; /* reserved */ - ivec[0x2d] = vec; /* reserved */ - - upcase_vector = insert_generic_trampoline( - sizeof(upcase_trampoline), upcase_trampoline); - register_callback(upcase_vector, upcase_entry, "upcase"); - - /* build fastlookup index into the monster table of interrupts */ - intfunc_init(int21_table, int21_fastlookup); - - ems_init(); -} diff --git a/usr.bin/doscmd/dos.h b/usr.bin/doscmd/dos.h deleted file mode 100644 index 64ed492..0000000 --- a/usr.bin/doscmd/dos.h +++ /dev/null @@ -1,398 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI dos.h,v 2.2 1996/04/08 19:32:28 bostic Exp - * - * $FreeBSD$ - */ - -/* - * DOS Error codes - */ -/* MS-DOS version 2 error codes */ -#define FUNC_NUM_IVALID 0x01 -#define FILE_NOT_FOUND 0x02 -#define PATH_NOT_FOUND 0x03 -#define TOO_MANY_OPEN_FILES 0x04 -#define ACCESS_DENIED 0x05 -#define HANDLE_INVALID 0x06 -#define MEM_CB_DEST 0x07 -#define INSUF_MEM 0x08 -#define MEM_BLK_ADDR_IVALID 0x09 -#define ENV_INVALID 0x0a -#define FORMAT_INVALID 0x0b -#define ACCESS_CODE_INVALID 0x0c -#define DATA_INVALID 0x0d -#define UNKNOWN_UNIT 0x0e -#define DISK_DRIVE_INVALID 0x0f -#define ATT_REM_CUR_DIR 0x10 -#define NOT_SAME_DEV 0x11 -#define NO_MORE_FILES 0x12 -/* mappings to critical-error codes */ -#define WRITE_PROT_DISK 0x13 -#define UNKNOWN_UNIT_CERR 0x14 -#define DRIVE_NOT_READY 0x15 -#define UNKNOWN_COMMAND 0x16 -#define DATA_ERROR_CRC 0x17 -#define BAD_REQ_STRUCT_LEN 0x18 -#define SEEK_ERROR 0x19 -#define UNKNOWN_MEDIA_TYPE 0x1a -#define SECTOR_NOT_FOUND 0x1b -#define PRINTER_OUT_OF_PAPER 0x1c -#define WRITE_FAULT 0x1d -#define READ_FAULT 0x1e -#define GENERAL_FAILURE 0x1f - -/* MS-DOS version 3 and later extended error codes */ -#define SHARING_VIOLATION 0x20 -#define FILE_LOCK_VIOLATION 0x21 -#define DISK_CHANGE_INVALID 0x22 -#define FCB_UNAVAILABLE 0x23 -#define SHARING_BUF_EXCEEDED 0x24 - -#define NETWORK_NAME_NOT_FOUND 0x35 - -#define FILE_ALREADY_EXISTS 0x50 - -#define DUPLICATE_REDIR 0x55 - -/* - * dos attribute byte flags - */ -#define REGULAR_FILE 0x00 -#define READ_ONLY_FILE 0x01 -#define HIDDEN_FILE 0x02 -#define SYSTEM_FILE 0x04 -#define VOLUME_LABEL 0x08 -#define DIRECTORY 0x10 -#define ARCHIVE_NEEDED 0x20 - -/* - * Internal structure used for get_space() - */ -typedef struct { - long bytes_sector; - long sectors_cluster; - long total_clusters; - long avail_clusters; -} fsstat_t; - -/* - * Several DOS structures used by the file redirector - */ - -typedef struct { - DIR *dp; - u_char *searchend; - u_char searchdir[1024]; -} search_t; - -/* - * This is really the format of the DTA. The file redirector will only - * use the first 21 bytes. - */ -typedef struct { - u_char drive __attribute__ ((packed)); - u_char pattern[11] __attribute__ ((packed)); - u_char flag __attribute__ ((packed)); - u_char reserved1[4] __attribute__ ((packed)); - search_t *searchptr __attribute__ ((packed)); - u_char attr __attribute__ ((packed)); - u_short time __attribute__ ((packed)); - u_short date __attribute__ ((packed)); - u_long size __attribute__ ((packed)); - u_char name[13] __attribute__ ((packed)); -}/* __attribute__((__packed__))*/ find_block_t; - -/* - * DOS directory entry structure - */ -typedef struct { - u_char name[8] __attribute__ ((packed)); - u_char ext[3] __attribute__ ((packed)); - u_char attr __attribute__ ((packed)); - u_char reserved[10] __attribute__ ((packed)); - u_short time __attribute__ ((packed)); - u_short date __attribute__ ((packed)); - u_short start __attribute__ ((packed)); - u_long size __attribute__ ((packed)); -} dosdir_t; - -/* - * The Current Drive Structure - */ -typedef struct { - u_char path[0x43] __attribute__ ((packed)); - u_short flag __attribute__ ((packed)); - u_short dpb_off __attribute__ ((packed)); - u_short dpb_seg __attribute__ ((packed)); - u_short redirector_off __attribute__ ((packed)); - u_short redirector_seg __attribute__ ((packed)); - u_char paramter_int21[2] __attribute__ ((packed)); - u_short offset __attribute__ ((packed)); - u_char dummy __attribute__ ((packed)); - u_char ifs_driver[4] __attribute__ ((packed)); - u_char dummy2[2] __attribute__ ((packed)); -}/* __attribute__((__packed__))*/ CDS; - -#define CDS_remote 0x8000 -#define CDS_ready 0x4000 -#define CDS_joined 0x2000 -#define CDS_substed 0x1000 - -#define CDS_notnet 0x0080 - -/* - * The List of Lists (used to get the CDS and a few other numbers) - */ -typedef struct { - u_char dummy1[0x16] __attribute__ ((packed)); - u_short cds_offset __attribute__ ((packed)); - u_short cds_seg __attribute__ ((packed)); - u_char dummy2[6] __attribute__ ((packed)); - u_char numberbdev __attribute__ ((packed)); - u_char lastdrive __attribute__ ((packed)); -} LOL; - -/* - * The System File Table - */ -typedef struct { -/*00*/ u_short nfiles __attribute__ ((packed)); /* Number file handles referring to this file */ -/*02*/ u_short open_mode __attribute__ ((packed)); /* Open mode (bit 15 -> by FCB) */ -/*04*/ u_char attribute __attribute__ ((packed)); -/*05*/ u_short info __attribute__ ((packed)); /* 15 -> remote, 14 -> dont set date */ -/*07*/ u_char ddr_dpb[4] __attribute__ ((packed)); /* Device Driver Header/Drive Paramter Block */ -/*0b*/ u_short fd __attribute__ ((packed)); -/*0d*/ u_short time __attribute__ ((packed)); -/*0f*/ u_short date __attribute__ ((packed)); -/*11*/ u_long size __attribute__ ((packed)); -/*15*/ u_long offset __attribute__ ((packed)); -/*19*/ u_short rel_cluster __attribute__ ((packed)); -/*1b*/ u_short abs_cluster __attribute__ ((packed)); -/*1d*/ u_char dir_sector[2] __attribute__ ((packed)); -/*1f*/ u_char dir_entry __attribute__ ((packed)); -/*20*/ u_char name[8] __attribute__ ((packed)); -/*28*/ u_char ext[3] __attribute__ ((packed)); -/*2b*/ u_char sharesft[4] __attribute__ ((packed)); -/*2f*/ u_char sharenet[2] __attribute__ ((packed)); -/*31*/ u_short psp __attribute__ ((packed)); -/*33*/ u_char share_off[2] __attribute__ ((packed)); -/*35*/ u_char local_end[2] __attribute__ ((packed)); -/*37*/ u_char ifd_driver[4] __attribute__ ((packed)); -} /*__attribute__((__packed__))*/ SFT; - -/* - * Format of PCDOS 4.01 swappable data area - * (Sorry, but you need a wide screen to make this look nice) - */ -typedef struct { - u_char err_crit __attribute__ ((packed)); /* 00h BYTE critical error flag */ - u_char InDOS __attribute__ ((packed)); /* 01h BYTE InDOS flag (count of active INT 21 calls) */ - u_char err_drive __attribute__ ((packed)); /* 02h BYTE ??? drive number or FFh */ - u_char err_locus __attribute__ ((packed)); /* 03h BYTE locus of last error */ - u_short err_code __attribute__ ((packed)); /* 04h WORD extended error code of last error */ - u_char err_suggest __attribute__ ((packed)); /* 06h BYTE suggested action for last error */ - u_char err_class __attribute__ ((packed)); /* 07h BYTE class of last error */ - u_short err_di __attribute__ ((packed)); - u_short err_es __attribute__ ((packed)); /* 08h DWORD ES:DI pointer for last error */ - u_short dta_off __attribute__ ((packed)); - u_short dta_seg __attribute__ ((packed)); /* 0Ch DWORD current DTA */ - u_short psp __attribute__ ((packed)); /* 10h WORD current PSP */ - u_short int_23_sp __attribute__ ((packed)); /* 12h WORD stores SP across an INT 23 */ - u_short wait_status __attribute__ ((packed)); /* 14h WORD return code from last process termination (set to 0 after reading with AH=4Dh) */ - u_char current_drive __attribute__ ((packed)); /* 16h BYTE current drive */ - u_char break_flag __attribute__ ((packed)); /* 17h BYTE extended break flag */ - u_char unknown1[2] __attribute__ ((packed)); /* 18h 2 BYTEs ??? */ - u_short int_21_ax __attribute__ ((packed)); /* 1Ah WORD value of AX on call to INT 21 */ - u_short net_psp __attribute__ ((packed)); /* 1Ch WORD PSP segment for sharing/network */ - u_short net_number __attribute__ ((packed)); /* 1Eh WORD network machine number for sharing/network (0000h = us) */ - u_short first_mem __attribute__ ((packed)); /* 20h WORD first usable memory block found when allocating memory */ - u_short best_mem __attribute__ ((packed)); /* 22h WORD best usable memory block found when allocating memory */ - u_short last_mem __attribute__ ((packed)); /* 24h WORD last usable memory block found when allocating memory */ - u_char unknown[10] __attribute__ ((packed)); /* 26h 2 BYTEs ??? (don't seem to be referenced) */ - u_char monthday __attribute__ ((packed)); /* 30h BYTE day of month */ - u_char month __attribute__ ((packed)); /* 31h BYTE month */ - u_short year __attribute__ ((packed)); /* 32h WORD year - 1980 */ - u_short days __attribute__ ((packed)); /* 34h WORD number of days since 1-1-1980 */ - u_char weekday __attribute__ ((packed)); /* 36h BYTE day of week (0 = Sunday) */ - u_char unknown2[3] __attribute__ ((packed)); /* 37h BYTE ??? */ - u_char ddr_head[30] __attribute__ ((packed)); /* 38h 30 BYTEs device driver request header */ - u_short ddre_ip __attribute__ ((packed)); - u_short ddre_cs __attribute__ ((packed)); /* 58h DWORD pointer to device driver entry point (used in calling driver) */ - u_char ddr_head2[22] __attribute__ ((packed)); /* 5Ch 22 BYTEs device driver request header */ - u_char ddr_head3[30] __attribute__ ((packed)); /* 72h 30 BYTEs device driver request header */ - u_char unknown3[6] __attribute__ ((packed)); /* 90h 6 BYTEs ??? */ - u_char clock_xfer[6] __attribute__ ((packed)); /* 96h 6 BYTEs CLOCK$ transfer record (see AH=52h) */ - u_char unknown4[2] __attribute__ ((packed)); /* 9Ch 2 BYTEs ??? */ - u_char filename1[128] __attribute__ ((packed)); /* 9Eh 128 BYTEs buffer for filename */ - u_char filename2[128] __attribute__ ((packed)); /* 11Eh 128 BYTEs buffer for filename */ - u_char findfirst[21] __attribute__ ((packed)); /* 19Eh 21 BYTEs findfirst/findnext search data block (see AH=4Eh) */ - u_char foundentry[32] __attribute__ ((packed)); /* 1B3h 32 BYTEs directory entry for found file */ - u_char cds[88] __attribute__ ((packed)); /* 1D3h 88 BYTEs copy of current directory structure for drive being accessed */ - u_char fcbname[11] __attribute__ ((packed)); /* 22Bh 11 BYTEs ??? FCB-format filename */ - u_char unknown5 __attribute__ ((packed)); /* 236h BYTE ??? */ - u_char wildcard[11] __attribute__ ((packed)); /* 237h 11 BYTEs wildcard destination specification for rename (FCB format) */ - u_char unknown6[11] __attribute__ ((packed)); /* 242h 2 BYTEs ??? */ - u_char attrmask __attribute__ ((packed)); /* 24Dh BYTE attribute mask for directory search??? */ - u_char open_mode __attribute__ ((packed)); /* 24Eh BYTE open mode */ - u_char unknown7[3] __attribute__ ((packed)); /* 24fh BYTE ??? */ - u_char virtual_dos __attribute__ ((packed)); /* 252h BYTE flag indicating how DOS function was invoked (00h = direct INT 20/INT 21, FFh = server call AX=5D00h) */ - u_char unknown8[9] __attribute__ ((packed)); /* 253h BYTE ??? */ - u_char term_type __attribute__ ((packed)); /* 25Ch BYTE type of process termination (00h-03h) */ - u_char unknown9[3] __attribute__ ((packed)); /* 25Dh BYTE ??? */ - u_short dpb_off __attribute__ ((packed)); - u_short dpb_seg __attribute__ ((packed)); /* 260h DWORD pointer to Drive Parameter Block for critical error invocation */ - u_short int21_sf_off __attribute__ ((packed)); - u_short int21_sf_seg __attribute__ ((packed)); /* 264h DWORD pointer to stack frame containing user registers on INT 21 */ - u_short store_sp __attribute__ ((packed)); /* 268h WORD stores SP??? */ - u_short dosdpb_off __attribute__ ((packed)); - u_short dosdpb_seg __attribute__ ((packed)); /* 26Ah DWORD pointer to DOS Drive Parameter Block for ??? */ - u_short disk_buf_seg __attribute__ ((packed)); /* 26Eh WORD segment of disk buffer */ - u_short unknown10[4] __attribute__ ((packed)); /* 270h WORD ??? */ - u_char media_id __attribute__ ((packed)); /* 278h BYTE Media ID byte returned by AH=1Bh,1Ch */ - u_char unknown11 __attribute__ ((packed)); /* 279h BYTE ??? (doesn't seem to be referenced) */ - u_short unknown12[2] __attribute__ ((packed)); /* 27Ah DWORD pointer to ??? */ - u_short sft_off __attribute__ ((packed)); - u_short sft_seg __attribute__ ((packed)); /* 27Eh DWORD pointer to current SFT */ - u_short cds_off __attribute__ ((packed)); - u_short cds_seg __attribute__ ((packed)); /* 282h DWORD pointer to current directory structure for drive being accessed */ - u_short fcb_off __attribute__ ((packed)); - u_short fcb_seg __attribute__ ((packed)); /* 286h DWORD pointer to caller's FCB */ - u_short unknown13[2] __attribute__ ((packed)); /* 28Ah WORD ??? */ - u_short jft_off __attribute__ ((packed)); - u_short jft_seg __attribute__ ((packed)); /* 28Eh DWORD pointer to a JFT entry in process handle table (see AH=26h) */ - u_short filename1_off __attribute__ ((packed)); /* 292h WORD offset in DOS CS of first filename argument */ - u_short filename2_off __attribute__ ((packed)); /* 294h WORD offset in DOS CS of second filename argument */ - u_short unknown14[12] __attribute__ ((packed)); /* 296h WORD ??? */ - u_short file_offset_lo __attribute__ ((packed)); - u_short file_offset_hi __attribute__ ((packed)); /* 2AEh DWORD offset in file??? */ - u_short unknown15 __attribute__ ((packed)); /* 2B2h WORD ??? */ - u_short partial_bytes __attribute__ ((packed)); /* 2B4h WORD bytes in partial sector */ - u_short number_sectors __attribute__ ((packed)); /* 2B6h WORD number of sectors */ - u_short unknown16[3] __attribute__ ((packed)); /* 2B8h WORD ??? */ - u_short nbytes_lo __attribute__ ((packed)); - u_short nbytes_hi __attribute__ ((packed)); /* 2BEh DWORD number of bytes appended to file */ - u_short qpdb_off __attribute__ ((packed)); - u_short qpdb_seg __attribute__ ((packed)); /* 2C2h DWORD pointer to ??? disk buffer */ - u_short asft_off __attribute__ ((packed)); - u_short asft_seg __attribute__ ((packed)); /* 2C6h DWORD pointer to ??? SFT */ - u_short int21_bx __attribute__ ((packed)); /* 2CAh WORD used by INT 21 dispatcher to store caller's BX */ - u_short int21_ds __attribute__ ((packed)); /* 2CCh WORD used by INT 21 dispatcher to store caller's DS */ - u_short temporary __attribute__ ((packed)); /* 2CEh WORD temporary storage while saving/restoring caller's registers */ - u_short prevcall_off __attribute__ ((packed)); - u_short prevcall_seg __attribute__ ((packed)); /* 2D0h DWORD pointer to prev call frame (offset 264h) if INT 21 reentered also switched to for duration of INT 24 */ - u_char unknown17[9] __attribute__ ((packed)); /* 2D4h WORD ??? */ - u_short ext_action __attribute__ ((packed)); /* 2DDh WORD multipurpose open action */ - u_short ext_attr __attribute__ ((packed)); /* 2DFh WORD multipurpose attribute */ - u_short ext_mode __attribute__ ((packed)); /* 2E1h WORD multipurpose mode */ - u_char unknown17a[9] __attribute__ ((packed)); - u_short lol_ds __attribute__ ((packed)); /* 2ECh WORD stores DS during call to [List-of-Lists + 37h] */ - u_char unknown18[5] __attribute__ ((packed)); /* 2EEh WORD ??? */ - u_char usernameptr[4] __attribute__ ((packed)); /* 2F3h DWORD pointer to user-supplied filename */ - u_char unknown19[4] __attribute__ ((packed)); /* 2F7h DWORD pointer to ??? */ - u_char lol_ss[2] __attribute__ ((packed)); /* 2FBh WORD stores SS during call to [List-of-Lists + 37h] */ - u_char lol_sp[2] __attribute__ ((packed)); /* 2FDh WORD stores SP during call to [List-of-Lists + 37h] */ - u_char lol_flag __attribute__ ((packed)); /* 2FFh BYTE flag, nonzero if stack switched in calling [List-of-Lists+37h] */ - u_char searchdata[21] __attribute__ ((packed)); /* 300h 21 BYTEs FindFirst search data for source file(s) of a rename operation (see AH=4Eh) */ - u_char renameentry[32] __attribute__ ((packed)); /* 315h 32 BYTEs directory entry for file being renamed */ - u_char errstack[331] __attribute__ ((packed)); /* 335h 331 BYTEs critical error stack */ - u_char diskstack[384] __attribute__ ((packed)); /* 480h 384 BYTEs disk stack (functions greater than 0Ch, INT 25, INT 26) */ - u_char iostack[384] __attribute__ ((packed)); /* 600h 384 BYTEs character I/O stack (functions 01h through 0Ch) */ - u_char int_21_08_flag __attribute__ ((packed)); /* 780h BYTE flag affecting AH=08h (see AH=64h) */ - u_char unknown20[11] __attribute__ ((packed)); /* 781h BYTE ??? looks like a drive number */ -} /*__attribute__((__packed__))*/ SDA; - -struct exehdr { - u_short magic; - u_short bytes_on_last_page; - u_short size; /* 512 byte blocks */ - u_short nreloc; - u_short hdr_size; /* paragraphs */ - u_short min_memory; /* paragraphs */ - u_short max_memory; /* paragraphs */ - u_short init_ss; - u_short init_sp; - u_short checksum; - u_short init_ip; - u_short init_cs; - u_short reloc_offset; - u_short overlay_num; -}; - -struct reloc_entry { - u_short off; - u_short seg; -}; - - -/* -** DOS-related shrapnel -*/ - -static __inline int -from_dos_attr(int attr) -{ - return((attr & READ_ONLY_FILE) ? 0444 : 0666); -} - -static __inline int -to_dos_attr(int mode) -{ - int attr; - - attr = (mode & 0200) ? 0:READ_ONLY_FILE; - attr |= S_ISDIR(mode) ? DIRECTORY:0; - return(attr); -} - -/* prototypes */ - -extern const char *dos_return[]; /* names of DOS return codes */ -extern const int dos_ret_size; /* length of above */ -extern char *InDOS; -extern int diskdrive; /* current drive */ -unsigned long disk_transfer_addr; - -extern void encode_dos_file_time (time_t, u_short *, u_short *); -extern time_t decode_dos_file_time(u_short dosdate, u_short dostime); -extern int translate_filename(u_char *dname, u_char *uname, int *drivep); -extern int parse_filename(int flag, char *str, char *fcb, int *nb); -extern void dos_init(void); - -/* from exe.c */ -extern int pspseg; /* segment # of PSP */ -extern int curpsp; - -extern void exec_command(regcontext_t *REGS, int run, int fd, char *cmdname, u_short *param); -extern void load_overlay(int fd, int start_segment, int reloc_segment); -extern void load_command(regcontext_t *REGS, int run, int fd, char *cmdname, - u_short *param, char **argv, char **envs); -extern void exec_return(regcontext_t *REGS, int code); -extern int get_env(void); diff --git a/usr.bin/doscmd/doscmd.1 b/usr.bin/doscmd/doscmd.1 deleted file mode 100644 index 56bb6c9..0000000 --- a/usr.bin/doscmd/doscmd.1 +++ /dev/null @@ -1,766 +0,0 @@ -.\" -.\" Copyright (c) 1992, 1993, 1996 -.\" Berkeley Software Design, Inc. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by Berkeley Software -.\" Design, Inc. -.\" -.\" THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" BSDI doscmd.1,v 2.3 1996/04/08 19:32:29 bostic Exp -.\" $FreeBSD$ -.\" -.Dd January 30, 1995 -.Dt DOSCMD 1 -.Os -.Sh NAME -.Nm doscmd -.Nd run a subset of real-mode DOS programs -.Sh SYNOPSIS -.Nm -.Fl 23AbDEfGHIMOPRrtVvXxYz -.Fl c Ar file -.Fl d Ar file -.Fl i Ar port Ns Xo -.Op : Ns Ar cnt -.Xc -.Fl o Ar port Ns Xo -.Op : Ns Ar cnt -.Xc -.Fl S Ar int -.Fl U Ar int -.Op Ar cmd Op Ar args ... -.Sh DESCRIPTION -The -.Nm -utility can either emulate a subset of DOS and run the -single command -.Ar cmd -.Ar args , -or it can be used to emulate a PC and boot DOS, -which allows it to run a larger variety of DOS applications. -It should be noted that MS DOS 6.2 and higher appear -to cause difficulties for -.Nm . -To boot DOS, either provide the -.Fl b -flag or omit the -.Ar cmd -argument. -If -.Fl b -is specified, -.Ar cmd -and -.Ar args -are ignored. -.Pp -Although -.Nm -only provides a subset of DOS, it is sufficient to run a variety of -programs, including, but not limited to, compilers, assemblers and -linker-loaders. -.Pp -The various flags available to -.Nm -are: -.Bl -tag -width indent -.It Fl 2 -Enable debugging traces of every trap to the -.Nm -emulator from the DOS program. -Note that some traps are handled in the kernel and hence will not -be traced. -.It Fl 3 -Enable debugging of several lower level functions, such -as changing of interrupt vectors and initializing paths to logical drives. -.\" -.\" -.\" -.It Fl A -Enable tracing of all interrupts that pass into the emulator. -This is the same as using the -.Fl S -option with all 256 possible interrupt values. -.\" -.\" -.\" -.It Fl b -Attempt to boot DOS rather than emulate it. -.\" -.\" -.\" -.It Fl c Ar file -Capture all output directed at the screen into -.Ar file . -Note that direct screen writes will not be captured. -.\" -.\" -.\" -.It Fl C -List MS-DOS calls emulated and their return values. -.\" -.\" -.\" -.It Fl D -Enable debugging of the disk and file operations. -.\" -.\" -.\" -.It Fl d Ar file -Send the debug output to -.Ar file -instead of stderr. -.\" -.\" -.\" -.It Fl E -Enable debugging of the exec routines. -.\" -.\" -.\" -.It Fl G -Enable debugging of the video (graphics) routines. -.\" -.\" -.\" -.It Fl H -Enable tracing of half implemented calls. -.\" -.\" -.\" -.It Fl I -Enable tracing of all interrupts. Almost the same as -.Fl A -except a few less traces are turned on. -.\" -.\" -.\" -.It Fl i Ar port Ns Xo -.Op : Ns Ar cnt -.Xc -Enable tracing of all inputs requested from the io -.Ar port . -If -.Ar cnt -is present, trace from -.Ar port -to -.Ar port+cnt Ns No -1 . -.\" -.\" -.\" -.It Fl M -Enable debugging of the memory operations. -.\" -.\" -.\" -.It Fl O -Direct the debugging output to stdout rather than stderr. -.\" -.\" -.\" -.It Fl o Ar port Ns Xo -.Op : Ns Ar cnt -.Xc -Enable tracing of all outputs requested from the io -.Ar port . -If -.Ar cnt -is present, trace from -.Ar port -to -.Ar port+cnt Ns No -1 . -.\" -.\" -.\" -.It Fl p Ar port Ns Xo -.Op : Ns Ar cnt -.Xc -Map the requested io -.Ar port -(with optional range up to -.Ar port+cnt Ns No -1 ) -to the real hardware I/O port(s). -This will likely require root privs to access them. -.\" -.\" -.\" -.It Fl P -Enable tracing of io port calls (such as -.Li inb , -.Li outb , -etc). -.\" -.\" -.\" -.It Fl R -Enable debugging of the file redirect code. -.\" -.\" -.\" -.It Fl r -Use the raw keyboard and display. Pressing <CTRL-ALT-DEL> will -cause doscmd to exit. This allows use of VGA graphics. -.\" -.\" -.\" -.It Fl S Ar int -Enable tracing of the interrupt -.Ar int . -.\" -.\" -.\" -.It Fl t -Attempt to do instruction level tracing. -Some instructions confuse the trace. -Pressing -.Li <CTRL-ALT-T> -attempts to toggle the trace mode on and off. -.\" -.\" -.\" -.It Fl U Ar int -Disable tracing of the interrupt -.Ar int . -Useful after -.Fl A -or -.Fl I . -.\" -.\" -.\" -.It Fl V -Include register dumps when reporting unknown interrupts. -.\" -.\" -.\" -.It Fl v -Same as -.Fl AH -.\" -.\" -.\" -.It Fl X -Enable debugging of the XMS operations. -.\" -.\" -.\" -.It Fl x -Open an X11 window to display output. This enables a -variety interrupts not available otherwise. This -can be used with or without -.Fl b . -.\" -.\" -.\" -.It Fl Y -Enable debugging of the EMS operations. -.\" -.\" -.\" -.It Fl z -Cause -.Nm -to pause just prior to jumping to the DOS program. -Very little use except for developing -.Nm . -.El -.Pp -When starting up, -.Nm -attempts to read a configuration file. First the file -.Cm .doscmdrc -in the current directory. If not found there, the -.Cm $HOME -directory is searched. If still not found, the file -.Cm /etc/doscmdrc -is used. -.Pp -In the configuration file, a comment is started with the \fB#\fP character. -Blank lines are ignored. -Non empty lines either are environment variables -or commands which configure devices. -Any line which has an \fB=\fP before any white space is considered to be -an environment variable assignment and is added to the DOS environment. -The rest of the lines are one of the following -.Bl -tag -width XXXXX -.\" -.\" -.\" -.It Cm boot Op Cm A: | C: -Set the device to boot from. -By default -.Cm A: -is first tried, if it is defined, and if that fails, -.Cm C: -is tried. -.\" -.\" -.\" -.It Cm assign Xo -.Op Cm A-Z : -.Op Fl ro -.Ar path -.Xc -Assigns the -.Bsx -directory -.Ar path -to be assigned as the specified drive. If the -.Fl ro -flag is specified, it is a read only file system. -These assignments will not take place when booting DOS until the -.Pa /usr/libdata/doscmd/redir.com -binary is run. -.\" -.\" -.\" -.It Cm assign Xo -.Cm lpt Ns Op Cm 0-4 : -.Op Cm direct -.Ar path -.Op Ar timeout -.Xc -Attempt to assign the specified printer to -.Ar path . -If -.Ar timeout -is specified then use it as the length of time for no -activity (in seconds) to indicate that the printer -should be flushed. The default is 30 seconds. -The -.Cm direct -option should be set when -.Ar path -refers to a real printer. -.\" -.\" -.\" -.It Cm assign Xo -.Op Cm A: | B: -.Op Fl ro -.Ar path -.Ar density -.Xc -.It Cm assign Xo -.Cm flop Ns Op Cm 01 -.Op Fl ro -.Ar path -.Ar density -.Xc -Assign the file -.Ar path -to be used as either the next available floppy or -to the specified floppy. -If -.Fl ro -is specified the floppy will be read only. -The -.Ar density -may be one of: -.Pp -.Bl -tag -compact -width 1440x -.It 180 -9 head 40 track single sided floppy -.It 360 -9 head 40 track double sided floppy -.It 720 -9 head 80 track double sided floppy -.It 1200 -15 head 80 track double sided floppy -.It 1440 -18 head 80 track double sided floppy -.It 2880 -36 head 80 track double sided floppy -.El -.\" -.\" -.\" -.It Cm assign Xo -.Op Cm C-Z : -.Op Fl ro -.Ar path -.Op Ar type | cyl head sec -.Op Ar fdisk_tab -.Xc -.It Cm assign Xo -.Cm hard Ns Op Cm 01 -.Op Fl ro -.Ar path -.Op Ar type | cyl head sec -.Op Ar fdisk_tab -.Xc -Assign the file -.Ar path -to be used as either the next available hard disk or -to the specified hard disk. -A disk's geometry can either be directly specified with -.Ar cyl -being the number of cylinders, -.Ar head -the number of heads and -.Ar sec -the number of sectors per track, -or it can be one of the standard types specified by -.Ar type -(see below). -The option -.Ar fdisk_tab -argument specifies file to use as the first sector -of this disk. This can be useful for inserting a -false fdisk table when -.Ar path -only refers to part of a disk. -.\" -.\" -.\" -.It Cm assign Xo -.Cm com Ns Op Cm 1-4 : -.Ar path -.Ar port -.Ar irq -.Xc -Assign the tty or pty specified by -.Ar path -to be used as the specified com port. -Its base address will be emulated at -.Ar port -at interrupt specified by -.Ar irq . -This code is lightly tested and may not suit all needs. -.\" -.\" -.\" -.It Cm portmap Xo -.Ar port -.Op Ar count -.Xc -Map the requested io -.Ar port -(with optional range up to -.Ar port+count Ns No -1 ) -to the real hardware I/O port(s). -This will likely require root privs to access them. -.\" -.\" -.\" -.It Cm "setver command version" -Cause doscmd, when emulating DOS, to report -.Cm version -as the version number of DOS when called from the program named -.Cm command . -The format of -.Cm version -is the same as of the -.Cm MS_VERSION -variable described below. -.El -.Pp -If not already assigned, -.Cm C: -will be assigned to the root directory (/) and the current directory -for -.Cm C: -will be set to the actual current directory. -Note that this means that invocations such as: -.Pp -.Dl "doscmd ../foo -.Pp -will not work as the -.Cm C: -directory will start with the current path. -Also, the following environment variables will be defined if not -already defined: -.Bd -literal -.Cm "COMSPEC=C:\eCOMMAND.COM -.Cm "PATH=C:\e -.Cm "PROMPT=DOS> -.Ed -.Pp -The -.Cm PATH -variable is also used to find -.Ar cmd . -Like DOS, first -.Ar cmd.com -will be looked for and then -.Ar cmd.exe . -.Sh "CONFIGURATION VARIABLES" -There are several variables in the -.Cm .doscmdrc -file which are internal to doscmd and do not actually get inserted into -the DOS environment. These are: -.Bl -tag -width MS_VERSION -.It Cm MS_VERSION -The value of this variable is used to determine the version of DOS that -should be reported by -.Nm . -Note that -.Nm -will not change the way -it works, just the way it reports. By default this value is -.Cm 410 , -which corresponds to -.Tn "MS DOS -version 4.1. -To change it to version 3.2 (the default in previous versions of -.Nm ) -use the value of -.Cm 320 . -.It Cm X11_FONT -The value of this variable determines the font used in an X window. -The default font is -.Cm vga , -which is installed in -.Pa /usr/libdata/doscmd/fonts . -Add the line -.Ql xset fp+ /usr/libdata/doscmd/fonts -to your -.Pa ${HOME}/.xsession -or -.Pa ${HOME}/.xinitrc -to let the X server find it. -.El -.Sh FILE TRANSLATION -The -.Nm -utility translates -.Bsx -file names into -.Tn DOS -file names by converting to all upper case and eliminating any invalid -character. It does not make any attempt to convert ASCII files into -the -.Cm <CR><LF> -format favored in the DOS world. Use -.Xr fconv 1 -(part of the ports collection) or similar tools to convert ASCII files. -.bp -.Sh DISK TYPES -.TS H -expand, box; -r | r | r | r | r. -Type Cylinders Heads Sectors Size -= -01 306 4 17 10MB -02 615 4 17 20MB -03 615 6 17 30MB -04 940 8 17 62MB -05 940 6 17 46MB -_ -06 615 4 17 20MB -07 462 8 17 30MB -08 733 5 17 30MB -09 900 15 17 112MB -10 820 3 17 20MB -_ -11 855 5 17 35MB -12 855 7 17 49MB -13 306 8 17 20MB -14 733 7 17 42MB -15 976 15 17 121MB -_ -16 612 4 17 20MB -17 977 5 17 40MB -18 977 7 17 56MB -19 1024 7 17 59MB -20 733 5 17 30MB -_ -21 733 7 17 42MB -22 733 5 17 30MB -23 306 4 17 10MB -24 925 7 17 53MB -25 925 9 17 69MB -_ -26 754 7 17 43MB -27 754 11 17 68MB -28 699 7 17 40MB -29 823 10 17 68MB -30 918 7 17 53MB -_ -31 1024 11 17 93MB -32 1024 15 17 127MB -33 1024 5 17 42MB -34 612 2 17 10MB -35 1024 9 17 76MB -_ -36 1024 8 17 68MB -37 615 8 17 40MB -38 987 3 17 24MB -39 987 7 17 57MB -40 820 6 17 40MB -_ -41 977 5 17 40MB -42 981 5 17 40MB -43 830 7 17 48MB -44 830 10 17 68MB -45 917 15 17 114MB -_ -46 1224 15 17 152MB -.TE -.bp -.Sh INSTALLING DOS ON A PSEUDO DISK -To install DOS on a pseudo hard disk under doscmd, do the following: -.Bl -tag -width XXXX -.It 1 -Create a -.Pa .doscmdrc -with at least the following: -.Bd -literal -offset indent -assign A: /dev/fd0.1440 1440 -assign A: /dev/fd0.720 720 -assign hard boot_drive 80 2 2 -.Ed -.Pp -You may need to adjust the raw files for the A: drive to match -your system. This example will cause the HD drive to be tried -first and the DD drive second. -.Pp -Note that you should only use raw devices or files at this point, -do not use a cooked device! (Well, it would probably be okay -for a hard disk, but certainly not the floppy) -.Pp -.Li boot_drive -should be the file name of where you want your bootable -image to be. The three numbers which follow -.Li 80 2 2 -say that the drive will have 80 cylinders, 2 heads and 2 sectors per track. -This is the smallest drive possible which still can have MS DOS -5.0 installed on it along with a -.Pa config.sys -and -.Pa autoexec.bat -file. -.Pp -You might want to create a larger boot drive. -.Pp -The file -.Pa boot_drive -must exist, so use the command touch to create it. -.It 2 -Insert a floppy disk into the A: drive which is bootable to MS-DOS -and has the commands fdisk, format and sys on it. You should also -copy the file redir.com onto the floppy by either mounting it -with the msdos file system type or by using mtools -(e.g., -.Dq Li mwrite redir.com a: ) . -.It 3 -run doscmd. -.It 4 -At the > prompt type -.Li fdisk . -.It 5 -Select -.Li Create DOS partition or Logical Drive . -.It 6 -Select -.Li Create Primary DOS Partition . -.It 7 -Tell it how big to make it -(Typically the whole drive. It is pretty tiny after all.) -.It 8 -Get out of FDISK by hitting -.Li <ESC> -a few times. -.It 9 -doscmd may abort, if it does, start up doscmd again. -.It 10 -At the > prompt, type -.Li format c: -and follow the instructions. -.It 11 -At the > prompt type -.Li sys c: . -.It 12 -Get out of doscmd. -.It 13 -Either remove the floppy from the drive or add the line -.Bd -literal -offset indent -boot C: -.Ed -to your -.Pa .doscmdrc . -.It 14 -You should now be running DOS off of your new disk. You will -probably want both config.sys and an autoexec.bat file. To -start with, you can say: -.Bd -literal -offset indent -> copy con: config.sys -LASTDRIVE=Z -^Z -> copy con: autoexec.bat -@echo off -redir.com -^Z -.Ed -.It 15 -Quit doscmd. -.It 16 -You know have a bootable pseudo disk which will automatically call -the magic -.Li redir -program, which installs -.Fx -disks. To use -them add lines to your .doscmdrc such as: -.Bd -literal -offset indent -assign D: /usr/dos -assign P: -ro /usr/prb -.Ed -Note that you will not always be able to access every file due to -naming problems. -.El -.Sh DIAGNOSTICS -If -.Nm -encounters an interrupt which is unimplemented, it will print a message -such as: -.Pp -.Dl Unknown interrupt 21 function 99 -.Pp -and exit. -.Pp -If -.Nm -emits the message -.Ic X11 support not compiled in -when supplied the -.Fl x -switch, this support can be added by defining an environment variable -.Ev X11BASE -which points to the installed X Window System (normally -.Pa /usr/X11R6 ) -and then typing -.Ic make install -in the source directory (normally -.Pa /usr/src/usr.bin/doscmd ) . -For this to work, the X programmer's kit must have been installed. -.Sh AUTHORS -.An Pace Willisson , -.An Paul Borman -.Sh HISTORY -The -.Nm -program first appeared in -.Tn BSD/386 . diff --git a/usr.bin/doscmd/doscmd.c b/usr.bin/doscmd/doscmd.c deleted file mode 100644 index c1da1d5..0000000 --- a/usr.bin/doscmd/doscmd.c +++ /dev/null @@ -1,924 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI doscmd.c,v 2.3 1996/04/08 19:32:30 bostic Exp - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/mman.h> -#include <sys/time.h> - -#include <ctype.h> -#include <err.h> -#include <errno.h> -#include <limits.h> -#include <paths.h> -#include <pwd.h> -#include <signal.h> -#include <unistd.h> - -#include <machine/param.h> -#include <machine/vmparam.h> - -#include <sys/proc.h> -#include <machine/sysarch.h> -#include <machine/vm86.h> - -#include "doscmd.h" -#include "cwd.h" -#include "trap.h" -#include "tty.h" -#include "video.h" - -/* exports */ -int capture_fd = -1; -int dead = 0; -int xmode = 0; -int booting = 0; -int raw_kbd = 0; -int timer_disable = 0; -struct timeval boot_time; -unsigned long *ivec = (unsigned long *)0; - -#ifndef USE_VM86 -#define PRB_V86_FORMAT 0x4242 - -struct vconnect_area vconnect_area = { - 0, /* Interrupt state */ - PRB_V86_FORMAT, /* Magic number */ - { 0, }, /* Pass through ints */ - { 0x00000000, 0x00000000 } /* Magic iret location */ -}; -#endif - -/* local prototypes */ -static void setup_boot(regcontext_t *REGS); -static int try_boot(int); -static void setup_command(int argc, char *argv[], regcontext_t *REGS); -static FILE *find_doscmdrc(void); -static int do_args(int argc, char *argv[]); -static void usage(void); -static int open_name(char *name, char *ext); - -/* Local option flags &c. */ -static int zflag = 0; - -/* DOS environment emulation */ -static unsigned ecnt = 0; -static char *envs[256]; - -/* Search path and command name */ -static char *dos_path = 0; -char cmdname[256]; /* referenced from dos.c */ - -static struct vm86_init_args kargs; - -/* lobotomise */ -int -main(int argc, char **argv) -{ -#ifndef USE_VM86 - ucontext_t uc; -#else - struct vm86_struct vm86s; -#define sc vm86s.substr.regs.vmsc -#endif - regcontext_t *REGS = (regcontext_t *)&uc.uc_mcontext; - int fd; - int i; - sigset_t sigset; - - sigemptyset(&sigset); - sigaddset(&sigset, SIGIO); - sigaddset(&sigset, SIGALRM); - sigprocmask(SIG_BLOCK, &sigset, 0); - - init_ints(); - - debugf = stderr; - /* XXX should only be for tty mode */ - fd = open (_PATH_DEVNULL, O_RDWR); - if (fd != 3) - dup2 (fd, 3); /* stdaux */ - if (fd != 4) - dup2 (fd, 4); /* stdprt */ - if (fd != 3 && fd != 4) - close (fd); - fd = -1; - - debug_set(0); /* debug any D_TRAPS without intnum */ - - /* perform option argument processing */ - do_args(argc, argv); - argc -= optind; - argv += optind; - - if (vflag && debugf == stderr) { - debugf = stdout; - setbuf (stdout, NULL); - } - - initHMA(); - - /* This needs to happen before the executable is loaded */ - mem_init(); - -#ifdef USE_VM86 - memset(&vm86s, 0, sizeof(vm86s)); -#endif - - /* - * With no other arguments we will assume we must boot DOS - */ - if (argc <= 0) - booting = 1; - -#if 1 - /* - * Nominate interrupts to handle here when the kernel is - * performing interrupt handling. - * - * I would like to let INT 2F pass through as well, but I - * need to get my hands on INT 2F:11 to do file redirection. - */ - for (i = 0; i <= 0xff; ++i) { - switch (i) { - case 0x2f: - case 0xff: -#if 1 - kargs.int_map[i >> 3] |= (1 << (i & 7)); -#ifndef USE_VM86 - vconnect_area.passthru[i >> 5] &= ~(1 << (i & 0x1f)); -#else - vm86s.int_byuser[i >> 3] |= (1 << (i & 0x07)); -#endif -#endif - break; - default: -#if 1 - kargs.int_map[i >> 3] &= ~(1 << (i & 7)); -#ifndef USE_VM86 - vconnect_area.passthru[i >> 5] |= (1 << (i & 0x1f)); -#else - vm86s.int_byuser[i >> 3] |= (1 << (i & 0x07)); -#endif -#endif - break; - } - } -#endif - - if (booting) { /* are we booting? */ - setup_boot(REGS); - } else { /* no, load a command */ - setup_command(argc, argv, REGS); - } - - /* install signal handlers */ - setsignal(SIGFPE, sigfpe); /* */ - setsignal(SIGALRM, sigalrm); /* */ - setsignal(SIGILL, sigill); /* */ - setsignal(SIGTRAP, sigtrap); /* */ - setsignal(SIGUSR2, sigtrace); /* */ - setsignal(SIGINFO, sigtrace); /* */ -#ifdef USE_VM86 - setsignal(SIGURG, sigurg); /* entry from NetBSD vm86 */ -#else - setsignal(SIGBUS, sigbus); /* entry from FreeBSD, BSD/OS vm86 */ -#endif - - /* Call init functions */ - if (raw_kbd) - console_init(); - init_io_port_handlers(); - bios_init(); - cpu_init(); - kbd_init(); - kbd_bios_init(); - video_init(); - if (xmode) - mouse_init(); - video_bios_init(); - disk_bios_init(); - cmos_init(); - xms_init(); - dos_init(); - net_init(); - speaker_init(); - timer_init(); - /* iomap_init(); */ - - gettimeofday(&boot_time, 0); - - if (zflag) for (;;) pause(); /* spin if requested */ - - if (raw_kbd) { - /* - * If we have a raw keyboard, and hence, video, - * sneak in a call to the video BIOS to reinit the - * the video display. - */ - u_long video_vector; - static u_char video_trampoline[] = { - 0x60, /* pusha */ - 0xB8, 0x03, 0x00, /* mov ax,00003h */ - 0xCD, 0x10, /* int 010h */ - 0x61, /* popa */ - 0xCF, /* iret */ - }; - - video_vector = insert_generic_trampoline( - sizeof(video_trampoline), video_trampoline); - - PUSH(R_FLAGS, REGS); - PUSH(R_CS, REGS); - PUSH(R_IP, REGS); - PUTVEC(R_CS, R_IP, video_vector); - } - - sigemptyset(&uc.uc_sigmask); - sigaltstack(NULL, &uc.uc_stack); - uc.uc_mcontext.mc_onstack = 0; - - if (tmode) - tracetrap(REGS); - -#ifndef USE_VM86 - R_EAX = (booting || raw_kbd) ? (int)&vconnect_area : -1; - R_EFLAGS |= PSL_VM | PSL_VIF; /* request VM86 mode */ - - i386_vm86(VM86_INIT, &kargs); - - sigreturn(&uc); - debug(D_ALWAYS,"sigreturn failed : %s\n", strerror(errno)); -#else - vm86s.cpu_type = VCPU_586; - i386_vm86(&vm86s); -#endif - - /* shouldn't get here */ - if (vflag) dump_regs(REGS); - fatal ("vm86 returned (no kernel support?)\n"); -#undef sc - /* quiet -Wall */ - return 0; -} - -/* -** setup_boot -** -** Setup to boot DOS -*/ -static void -setup_boot(regcontext_t *REGS) -{ - FILE *fp; /* doscmdrc handle */ - int fd; /* don't close this! */ - - fp = find_doscmdrc(); /* get doscmdrc */ - if (!fp) { - fprintf(stderr, "You must have a doscmdrc to boot\n"); - quit(1); - } - - booting = read_config(fp); /* where to boot from? */ - fclose(fp); - if (booting < 0) { /* not specified */ - if ((fd = try_boot(booting = 0)) < 0) /* try A: */ - fd = try_boot(booting = 2); /* try C: */ - } else { - fd = try_boot(booting); /* do like the man says */ - } - - if (fd < 0) - errx(1, "Failed to boot"); - - /* initialise registers for entry to bootblock */ - R_EFLAGS = 0x20202; - R_CS = 0x0000; - R_IP = 0x7c00; - R_SS = 0x9800; - R_SP = 0x8000 - 2; - R_DS = 0x0000; - R_ES = 0x0000; - - R_AX = R_BX = R_CX = R_DX = R_SI = R_DI = R_BP = 0; - -#if defined(__FreeBSD__) || defined(__NetBSD__) - /* - ** init a few other context registers - */ - R_FS = 0x0000; - R_GS = 0x0000; -#endif -} - -/* -** try_boot -** -** try to read the boot sector from the specified disk -*/ -static int -try_boot(int bootdrv) -{ - int fd; - - fd = disk_fd(bootdrv); - if (fd < 0) { /* can we boot it? */ - debug(D_DISK, "Cannot boot from %c\n", drntol(bootdrv)); - return -1; - } - - /* read bootblock */ - if (read(fd, (char *)0x7c00, 512) != 512) { - debug(D_DISK, "Short read on boot block from %c:\n", drntol(bootdrv)); - return -1; - } - - return fd; -} - -/* -** setup_command -** -** Setup to run a single command and emulate DOS -*/ -static void -setup_command(int argc, char *argv[], regcontext_t *REGS) -{ - FILE *fp; - u_short param[7] = {0, 0, 0, 0, 0, 0, 0}; - const char *p; - char prog[1024]; - char buffer[PATH_MAX]; - unsigned i; - int fd; - - fp = find_doscmdrc(); /* dig up a doscmdrc */ - if (fp) { - read_config(fp); /* load config for non-boot mode */ - fclose(fp); - } - - if (argc <= 0) /* need some arguments */ - usage(); - - /* look for a working directory XXX ??? */ - if (dos_getcwd(drlton('C')) == NULL) { - - /* try to get our current directory, use '/' if desperate */ - p = getcwd(buffer, sizeof(buffer)); - if (!p || !*p) p = getenv("PWD"); - if (!p || !*p) p = "/"; - init_path(drlton('C'), "/", p); - - /* look for PATH= already set, learn from it if possible */ - for (i = 0; i < ecnt; ++i) { - if (!strncmp(envs[i], "PATH=", 5)) { - dos_path = envs[i] + 5; - break; - } - } - /* no PATH in DOS environment? put current directory there*/ - if (i >= ecnt) { - static char path[256]; - snprintf(path, sizeof(path), "PATH=C:%s", dos_getcwd(drlton('C'))); - put_dosenv(path); - dos_path = envs[ecnt-1] + 5; - } - } - - /* add a COMSPEC if required */ - for (i = 0; i < ecnt; ++i) { - if (!strncmp(envs[i], "COMSPEC=", 8)) - break; - } - if (i >= ecnt) - put_dosenv("COMSPEC=C:\\COMMAND.COM"); - - /* look for PATH already set, learn from it if possible */ - for (i = 0; i < ecnt; ++i) { - if (!strncmp(envs[i], "PATH=", 5)) { - dos_path = envs[i] + 5; - break; - } - } - /* No PATH, default to c:\ */ - if (i >= ecnt) { - put_dosenv("PATH=C:\\"); - dos_path = envs[ecnt-1] + 5; - } - - /* if no PROMPT, default to 'DOS>' */ - for (i = 0; i < ecnt; ++i) { - if (!strncmp(envs[i], "PROMPT=", 7)) - break; - } - if (i >= ecnt) - put_dosenv("PROMPT=DOS> "); - - /* terminate environment */ - envs[ecnt] = 0; - - /* XXX ??? */ - if (dos_getcwd(drlton('R')) == NULL) - init_path(drlton('R'), "/", 0); - - /* get program name */ - strncpy(prog, *argv++, sizeof(prog) -1); - prog[sizeof(prog) -1] = '\0'; - - /* try to open program */ - if ((fd = open_prog(prog)) < 0) { - fprintf (stderr, "%s: command not found\n", prog); - quit(1); - } - - /* load program */ - load_command(REGS, 1, fd, cmdname, param, argv, envs); - close(fd); -} - -/* -** find_doscmdrc -** -** Try to find a doscmdrc file -*/ -static FILE * -find_doscmdrc(void) -{ - FILE *fp; - char buffer[4096]; - - if ((fp = fopen(".doscmdrc", "r")) == NULL) { - struct passwd *pwd = getpwuid(geteuid()); - if (pwd) { - snprintf(buffer, sizeof(buffer), "%s/.doscmdrc", pwd->pw_dir); - fp = fopen(buffer, "r"); - } - if (!fp) { - char *home = getenv("HOME"); - if (home) { - snprintf(buffer, sizeof(buffer), "%s/.doscmdrc", home); - fp = fopen(buffer, "r"); - } - } - if (!fp) - fp = fopen("/etc/doscmdrc", "r"); - } - return(fp); -} - -/* -** do_args -** -** commandline argument processing -*/ -static int -do_args(int argc, char *argv[]) -{ - int i,c,p; - FILE *fp; - char *col; - - while ((c = getopt(argc, argv, "234AbCc:Dd:EGHIi:kLMOo:Pp:RrS:TtU:vVxXYz")) != -1) { - switch (c) { - case '2': - debug_flags |= D_TRAPS2; - break; - case '3': - debug_flags |= D_TRAPS3; - break; - case '4': - debug_flags |= D_DEBUGIN; - break; - case 'A': - debug_flags |= D_TRAPS | D_ITRAPS; - for (c = 0; c < 256; ++c) - debug_set(c); - break; - case 'b': - booting = 1; - break; - case 'C': - debug_flags |= D_DOSCALL; - break; - case 'c': - if ((capture_fd = creat(optarg, 0666)) < 0) { - perror(optarg); - quit(1); - } - break; - case 'D': - debug_flags |= D_DISK | D_FILE_OPS; - break; - case 'd': - if ((fp = fopen(optarg, "w")) != 0) { - debugf = fp; - setbuf (fp, NULL); - } else - perror(optarg); - break; - case 'E': - debug_flags |= D_EXEC; - break; - case 'G': - debug_flags |= D_VIDEO; - break; - case 'H': - debug_flags |= D_HALF; - break; - case 'I': - debug_flags |= D_ITRAPS; - for (c = 0; c < 256; ++c) - debug_set(c); - break; - case 'i': - i = 1; - if ((col = strchr(optarg, ':')) != 0) { - *col++ = 0; - i = strtol(col, 0, 0); - } - p = strtol(optarg, 0, 0); - iomap_port(p, i); - - while (i-- > 0) - define_input_port_handler(p++, inb_traceport); - break; - case 'k': - kargs.debug = 1; - break; - case 'L': - debug_flags |= D_PRINTER; - break; - case 'M': - debug_flags |= D_MEMORY; - break; - case 'O': - debugf = stdout; - setbuf (stdout, NULL); - break; - case 'o': - i = 1; - if ((col = strchr(optarg, ':')) != 0) { - *col++ = 0; - i = strtol(col, 0, 0); - } - p = strtol(optarg, 0, 0); - iomap_port(p, i); - - while (i-- > 0) - define_output_port_handler(p++, outb_traceport); - break; - case 'P': - debug_flags |= D_PORT; - break; - case 'p': - i = 1; - if ((col = strchr(optarg, ':')) != 0) { - *col++ = 0; - i = strtol(col, 0, 0); - } - p = strtol(optarg, 0, 0); - iomap_port(p, i); - - while (i-- > 0) { - define_input_port_handler(p++, inb_port); - define_output_port_handler(p++, outb_port); - } - break; - case 'R': - debug_flags |= D_REDIR; - break; - case 'r': - raw_kbd = 1; - break; - case 'S': - debug_flags |= D_TRAPS | D_ITRAPS; - debug_set(strtol(optarg, 0, 0)); - break; - case 'T': - timer_disable = 1; - break; - case 't': - tmode = 1; - break; - case 'U': - debug_unset(strtol(optarg, 0, 0)); - break; - case 'V': - vflag = 1; - break; - case 'v': - debug_flags |= D_TRAPS | D_ITRAPS | D_HALF | 0xff; - break; - case 'X': - debug_flags |= D_XMS; - break; - case 'x': -#ifdef NO_X - fatal("X11 support not compiled in.\n"); -#endif - xmode = 1; - break; - case 'Y': - debug_flags |= D_EMS; - break; - case 'z': - zflag = 1; - break; - default: - usage (); - } - } - return(optind); -} - -/* -** Very helpful 8( -*/ -void -usage (void) -{ - fprintf (stderr, "usage: doscmd cmd args...\n"); - quit (1); -} - -/* -** look up a DOS command name -** -** XXX ordering is wrong! -*/ -static int -open_name(char *name, char *ext) -{ - int fd; - char *p = name + strlen(name); - char *q; - - *ext = 0; - - q = strrchr(name, '/'); - if (q) - q++; - else - q = name; - - if (!strchr(q, '.')) { - strcpy(ext, ".exe"); - strcpy(p, ".exe"); - - if ((fd = open (name, O_RDONLY)) >= 0) - return (fd); - - strcpy(ext, ".com"); - strcpy(p, ".com"); - - if ((fd = open (name, O_RDONLY)) >= 0) - return (fd); - } else { - if ((fd = open (name, O_RDONLY)) >= 0) - return (fd); - } - - return (-1); -} - -/* -** look up a DOS command, search the path as well. -*/ -int -open_prog(char *name) -{ - int fd; - char fullname[1024], tmppath[1024]; - char *p; - char *e; - char ext[5]; - int error; - int drive; - char *path; - - if (strpbrk(name, ":/\\")) { - error = translate_filename(name, fullname, &drive); - if (error) - return (-1); - - fd = open_name(fullname, ext); - - strcpy(cmdname, name); - if (*ext) - strcat(cmdname, ext); - return (fd); - } - - path = dos_path; - - while (*path) { - p = path; - while (*p && *p != ';') - ++p; - - memcpy(tmppath, path, p - path); - e = tmppath + (p - path); - *e++ = '\\'; - strcpy(e, name); - - path = *p ? p + 1 : p; - - error = translate_filename(tmppath, fullname, &drive); - if (error) - continue; - - fd = open_name(fullname, ext); - - if (fd >= 0) { - strcpy(cmdname, tmppath); - if (*ext) - strcat(cmdname, ext); - return (fd); - } - } - - return (-1); -} - -/* -** append a value to the DOS environment -*/ -void -put_dosenv(const char *value) -{ - if (ecnt < sizeof(envs)/sizeof(envs[0])) { - if ((envs[ecnt++] = strdup(value)) == NULL) { - perror("put_dosenv"); - quit(1); - } - } else { - fprintf(stderr, "Environment full, ignoring %s\n", value); - } -} - -/* -** replicate a fd up at the top of the range -*/ -int -squirrel_fd(int fd) -{ - int sfd = sysconf(_SC_OPEN_MAX); - struct stat sb; - - do { - errno = 0; - fstat(--sfd, &sb); - } while (sfd > 0 && errno != EBADF); - - if (errno == EBADF && dup2(fd, sfd) >= 0) { - close(fd); - return(sfd); - } - return(fd); -} - -/* -** Exit-time stuff -*/ - -/* -** Going away time -** -** XXX belongs somewhere else perhaps -*/ -void -done(regcontext_t *REGS, int val) -{ - if (curpsp < 2) { - if (xmode) { - const char *m; - - tty_move(24, 0); - for (m = "END OF PROGRAM"; *m; ++m) - tty_write(*m, 0x8400); - - for (m = "(PRESS <CTRL-ALT> ANY MOUSE BUTTON TO exit)"; *m; ++m) - tty_write(*m, 0x0900); - tty_move(-1, -1); - for (;;) - tty_pause(); - } else { - quit(val); - } - } - exec_return(REGS, val); -} - -typedef struct COQ { - void (*func)(void *); - void *arg; - struct COQ *next; -} COQ; - -COQ *coq = 0; - -void -quit(int status) -{ - while (coq) { - COQ *c = coq; - coq = coq->next; - c->func(c->arg); - } - if (!xmode) /* XXX not for bootmode */ - puts("\n"); - exit(status); -} - -void -call_on_quit(void (*func)(void *), void *arg) -{ - COQ *c = (COQ *)malloc(sizeof(COQ)); - if (!c) { - perror("call_on_quit"); - quit(1); - } - c->func = func; - c->arg = arg; - c->next = coq; - coq = c; -} - -struct io_range { - u_int start; - u_int length; - int enable; -}; - -/* This is commented out as it is never called. Turn it back on if needed. - */ -#if COMMENTED_OUT -static void -iomap_init(void) -{ - int i; - struct io_range io[] = { -#if 0 - { 0x200, 0x200, 1 }, /* 0x200 - 0x400 */ - { 0x1c80, 2, 1 }, /* 0x1c80 - 0x1c81 */ - { 0x2c80, 2, 1 }, /* 0x2c80 - 0x2c81 */ - { 0x3c80, 2, 1 }, /* 0x3c80 - 0x3c81 */ - { 0x378, 8, 1 }, /* 0x378 - 0x37F */ - { 0x3c4, 2, 1 }, /* 0x3c4 - 0x3c5 */ - { 0x3c5, 2, 1 }, /* 0x3ce - 0x3cf */ -#else - { 0x0, 0x10000, 1 }, /* entire i/o space */ -#endif - { 0, 0, 0 } - }; - - for (i = 0; io[i].length; i++) - if (i386_set_ioperm(io[i].start, io[i].length, io[i].enable) < 0) - err(1, "i386_set_ioperm"); -} -#endif - -/* This is used to map in only the specified port range, instead of all - the ports or only certain port ranges. - */ -void -iomap_port(int port, int count) -{ - if (i386_set_ioperm(port, count, 1) < 0) - err(1, "i386_set_ioperm"); - - debug(D_PORT,"mapped I/O port: port=%#x count=%d\n", port, count); -} diff --git a/usr.bin/doscmd/doscmd.h b/usr.bin/doscmd/doscmd.h deleted file mode 100644 index e545c29..0000000 --- a/usr.bin/doscmd/doscmd.h +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI doscmd.h,v 2.3 1996/04/08 19:32:32 bostic Exp - * - * $FreeBSD$ - */ - - -#ifdef __NetBSD__ -#define USE_VM86 -#endif - -#include <sys/param.h> -#include <sys/types.h> -#include <sys/time.h> -#include <sys/stat.h> - -#include <dirent.h> -#include <fcntl.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ucontext.h> -#include <errno.h> - -#include <sys/signalvar.h> -#include <machine/sigframe.h> - -#include <machine/frame.h> -#include <machine/psl.h> -#include <machine/npx.h> -#ifdef USE_VM86 -#include <machine/vm86.h> -#endif - -#include "register.h" -#include "dos.h" -#include "callback.h" - -#define drlton(a) ((islower((a)) ? toupper((a)) : (a)) - 'A') -#define drntol(a) ((a) + 'A') - -/* -** assorted hardware/scope constants -*/ - -#define MAX_AVAIL_SEG 0xa000 - -#define MAXPORT 0x400 - -#define N_PARALS_MAX 3 -#define N_COMS_MAX 4 /* DOS restriction (sigh) */ - -struct vconnect_area { - int int_state; - int magic; /* 0x4242 -> PRB format */ - u_long passthru[256>>5]; /* bitmap of INTs to handle */ - u_long magiciret[2]; /* Bounds of "magic" IRET */ -}; -extern struct vconnect_area vconnect_area; -#define IntState vconnect_area.int_state - -/* ParseBuffer.c */ -int ParseBuffer(char *, char **, int); - -/* bios.c */ -#define BIOSDATA ((u_char *)0x400) -extern unsigned long rom_config; -extern int nfloppies; -extern int ndisks; -extern int nserial; -extern int nparallel; - -extern volatile int poll_cnt; -void bios_init(void); -void wakeup_poll(void); -void reset_poll(void); -void sleep_poll(void); - -/* cmos.c */ -extern time_t delta_clock; - -void cmos_init(void); - -/* config.c */ -int read_config(FILE *fp); - -/* cpu.c */ -void cpu_init(void); -int emu_instr(regcontext_t *); -void int00(regcontext_t *); -void int01(regcontext_t *); -void int03(regcontext_t *); -void int0d(regcontext_t *); - -/* debug.c */ -extern int vflag; -extern int tmode; -extern FILE *debugf; -extern int debug_flags; - -/* Lower 8 bits are int number */ -#define D_ALWAYS 0x0000100 /* always emit this message */ -#define D_TRAPS 0x0000200 /* trap-related activity */ -#define D_FILE_OPS 0x0000400 /* file-related activity */ -#define D_MEMORY 0x0000800 /* memory-related activity */ -#define D_HALF 0x0001000 /* "half-implemented" system calls */ -#define D_FLOAT 0x0002000 /* ??? */ -#define D_DISK 0x0004000 /* disk (not file) operations */ -#define D_TRAPS2 0x0008000 -#define D_PORT 0x0010000 /* port accesses */ -#define D_EXEC 0x0020000 -#define D_ITRAPS 0x0040000 -#define D_REDIR 0x0080000 /* redirector functions */ -#define D_PRINTER 0x0100000 -#define D_TRAPS3 0x0200000 -#define D_DEBUGIN 0x0400000 -#define D_DOSCALL 0x0800000 /* MS-DOS function results */ -#define D_XMS 0x1000000 /* XMS calls */ -#define D_EMS 0x2000000 /* EMS calls */ -#define D_VIDEO 0x4000000 /* video-related activity */ - -#define TTYF_ECHO 0x00000001 -#define TTYF_ECHONL 0x00000003 -#define TTYF_CTRL 0x00000004 -#define TTYF_BLOCK 0x00000008 -#define TTYF_POLL 0x00000010 -#define TTYF_REDIRECT 0x00010000 /* Cannot have 0xffff bits set */ - -#define TTYF_ALL (TTYF_ECHO | TTYF_CTRL | TTYF_REDIRECT) -#define TTYF_BLOCKALL (TTYF_ECHO | TTYF_CTRL | TTYF_REDIRECT | TTYF_BLOCK) - -void unknown_int2(int, int, regcontext_t *); -void unknown_int3(int, int, int, regcontext_t *); -void unknown_int4(int, int, int, int, regcontext_t *); -void fatal(const char *, ...) __printflike(1, 2); -void debug(int, const char *, ...) __printflike(2, 3); -void dump_regs(regcontext_t *); -void debug_set(int); -void debug_unset(int); -u_long debug_isset(int); - -/* disktab.c */ -int map_type(int, int *, int *, int *); - -/* doscmd.c */ -extern int capture_fd; -extern int dead; -extern int xmode; -extern int booting; -extern int raw_kbd; -extern int timer_disable; -extern char cmdname[]; -extern struct timeval boot_time; -extern unsigned long *ivec; - -int _prog(char *); -void call_on_quit(void (*)(void *), void *); -void done(regcontext_t *, int); -void iomap_port(int, int); -int open_prog(char *); -void put_dosenv(const char *); -void quit(int); -int squirrel_fd(int); - -/* ems.c */ -int ems_init(void); -void ems_entry(regcontext_t *); - -/* emuint.c */ -extern void emuint(regcontext_t *REGS); - -/* i386-pinsn.c */ -extern int i386dis(unsigned short, unsigned short, - unsigned char *, char *, int); - -/* int.c */ -void init_ints(void); -int isinhardint(int); -void softint(int); -void hardint(int); -void resume_interrupt(void); -void unpend(int); -void send_eoi(void); -void set_eoir(int, void (*)(void *), void *); - -/* int10.c */ -extern void int10(regcontext_t *); - -/* int13.c */ -extern int init_hdisk(int drive, int cyl, int head, int tracksize, - char *file, char *boot_sector); -extern int init_floppy(int drive, int type, char *file); -extern int disk_fd(int drive); -extern void make_readonly(int drive); -extern int search_floppy(int i); -extern void disk_bios_init(void); - -/* int16.c */ -void int16(regcontext_t *); - -/* int17.c */ -void int17(regcontext_t *); -void lpt_poll(void); -void printer_direct(int printer); -void printer_spool(int printer, char *print_queue); -void printer_timeout(int printer, char *time_out); - -/* int1a.c */ -void int1a(regcontext_t *); - -/* int2f.c */ -extern void int2f(regcontext_t *); - -/* intff.c */ -extern int int2f_11(regcontext_t *REGS); -extern void intff(regcontext_t *REGS); - -/* mem.c */ -extern char *dosmem; - -extern void mem_init(void); -extern int mem_alloc(int size, int owner, int *biggestp); -extern int mem_adjust(int addr, int size, int *availp); -extern void mem_free_owner(int owner); -extern void mem_change_owner(int addr, int owner); - -/* mouse.c */ -void int33(regcontext_t *); -void mouse_init(void); - -/* net.c */ -void net_init(void); - -/* port.c */ -void define_input_port_handler(int, unsigned char (*)(int)); -void define_output_port_handler(int, void (*)(int, unsigned char)); -void inb(regcontext_t *, int); -unsigned char inb_port(int); -unsigned char inb_speaker(int); -unsigned char inb_traceport(int); -void init_io_port_handlers(void); -void insb(regcontext_t *, int); -void insx(regcontext_t *, int); -void inx(regcontext_t *, int); -void outb(regcontext_t *, int); -void outb_port(int, unsigned char); -void outb_speaker(int, unsigned char); -void outb_traceport(int, unsigned char); -void outsb(regcontext_t *, int); -void outsx(regcontext_t *, int); -void outx(regcontext_t *, int); -void speaker_init(void); - -/* setver.c */ -extern void setver(char *, short); -extern short getver(char *); - -/* signal.c */ -extern struct sigframe *saved_sigframe; -extern regcontext_t *saved_regcontext; -extern int saved_valid; -extern void setsignal(int s, void (*h)(struct sigframe *)); - -/* timer.c */ -extern void timer_init(void); - -/* trace.c */ -extern int resettrace(regcontext_t *); -extern void tracetrap(regcontext_t *); - -/* xms.c */ -extern void get_raw_extmemory_info(regcontext_t *REGS); -extern int int2f_43(regcontext_t *REGS); -extern void initHMA(void); -extern void xms_init(void); -extern u_long xms_maxsize; - -/****************************** dirty below here *****************************/extern int nmice; diff --git a/usr.bin/doscmd/doscmd_loader.c b/usr.bin/doscmd/doscmd_loader.c deleted file mode 100644 index a3df681..0000000 --- a/usr.bin/doscmd/doscmd_loader.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI doscmd_loader.c,v 2.3 1996/04/08 19:32:33 bostic Exp - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <stdio.h> -#include <stdlib.h> -#include <a.out.h> - -/* - * reserve space in "low" memory for the interrupt vector table - */ -static const char filler[4096] = { 0, }; - -#define _PATH_DOS_KERNEL_DIR "/usr/libexec/" -#define _PATH_DOS_KERNEL "doscmd.kernel" - -int -load_kernel(void) -{ - FILE *fp; - struct exec exec; - int start_address; - - if ((fp = fopen(_PATH_DOS_KERNEL, "r")) == NULL && - (fp = fopen("obj/" _PATH_DOS_KERNEL, "r")) == NULL && - (fp = fopen(_PATH_DOS_KERNEL_DIR _PATH_DOS_KERNEL, "r")) == NULL && - (fp = fopen(getenv("DOS_KERNEL"), "r")) == NULL) - err(1, "load_kernel"); - - if (fread(&exec, sizeof(exec), 1, fp) != 1 || N_GETMAGIC(exec) != OMAGIC) - errx(1, "bad kernel file format"); - - start_address = exec.a_entry & (~(getpagesize() - 1)); - if (brk(start_address + exec.a_text + exec.a_data + exec.a_bss) < 0) - err(1, "load_kernel"); - fread((char *)start_address, exec.a_text + exec.a_data, 1, fp); - bzero((char *)(start_address + exec.a_text + exec.a_data), exec.a_bss); - fclose(fp); - return(exec.a_entry); -} - -void -main(int argc, char **argv, char **environ) -{ - void (*entry_point)(); -#ifndef __FreeBSD__ - int fd = open("/dev/mem", 0); -#endif - setgid(getgid()); - setuid(getuid()); - -#ifndef __FreeBSD__ - if (fd < 0) - err(1, "/dev/mem"); -#endif - - entry_point = (void (*)()) load_kernel(); - -#ifndef __FreeBSD__ - if (read(fd, 0, 0x500 != 0x500)) - err(1, "/dev/mem"); - - close(fd); -#endif - - (*entry_point)(argc, argv, environ); - errx(1, "return from doscmd kernel???"); -} diff --git a/usr.bin/doscmd/ems.c b/usr.bin/doscmd/ems.c deleted file mode 100644 index 953c90b..0000000 --- a/usr.bin/doscmd/ems.c +++ /dev/null @@ -1,1693 +0,0 @@ -/*- - * Copyright (c) 1997 Helmut Wirth <hfwirth@ping.at> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice immediately at the beginning of the file, witout modification, - * this list of conditions, and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * EMS memory emulation - * - * To emulate Expanded Memory we use a DOS driver (emsdriv.sys) which - * routes calls to int 0x67 to this emulator routine. The main entry point - * is ems_entry(..). The emulator needs to be initialized before the first - * call. The first step of the initialization is done during program startup - * the second part is done during DOS boot, from a call of the DOS driver. - * The DOS driver is necessary because DOS programs look for it to - * determine if EMS is available. - * - * To emulate a configurable amount of EMS memory we use a file created - * at startup with the size of the configured EMS memory. This file is - * mapped into the EMS window like any DOS memory manager would do, using - * mmap calls. - * - * The emulation follows the LIM EMS 4.0 standard. Not all functions of it - * are implemented yet. The "alter page map and jump" and "alter page map - * and call" functions are not implemented, because they are rather hard to - * do. (It would mean a call to the emulator executes a routine in EMS - * memory and returns to the emulator, the emulator switches the page map - * and then returns to the DOS program.) LINUX does not emulate this - * functions and I think they were very rarely used by DOS applications. - * - * Credits: To the writers of LINUX dosemu, I looked at their code - */ - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/mman.h> -#include <unistd.h> - -#include "doscmd.h" -#include "ems.h" - -/* Will be configurable */ -u_long ems_max_size = EMS_MAXSIZE * 1024; -u_long ems_frame_addr = EMS_FRAME_ADDR; - -/* - * Method for EMS: Allocate a mapfile with the size of EMS memory - * and map the needed part into the page frame - */ - -#define EMS_MAP_PATH "/var/tmp/" /* Use a big filesystem */ -#define EMS_MAP_FILE "doscmd.XXXXXX" -static int mapfile_fd = -1; - -/* Pages are always 16 kB in size. The page frame is 64 kB, there are - * 4 positions (0..3) for a page to map in. The pages are numbered from 0 to - * the highest 16 kB page in the mapfile, depending on the EMS size - */ - -EMS_mapping_context ems_mapping_context; - -/* Handle and page management (see ems.h) */ - -/* The handle array. If the pointer is NULL, the handle is unallocated */ -static EMS_handle *ems_handle[EMS_NUM_HANDLES]; -static u_long ems_alloc_handles; -/* The active handle, if any */ -static short active_handle; - -/* The page array. It is malloced at runtime, depending on the total - * allocation size - */ - -static EMS_page *ems_page = NULL; -static u_long ems_total_pages; -static u_long ems_alloc_pages; -static u_long ems_free_pages; - -/* Local structure used for region copy and move operations */ - -struct copydesc { -#define SRC_EMS 1 -#define DST_EMS 2 - short copytype; /* Type of source and destination memory */ - EMS_addr src_addr; /* Combined pointer for source */ - EMS_addr dst_addr; /* Combined pointer for destination */ - u_long rest_len; /* Length to copy */ -}; - - -/* Local prototypes */ -static int init_mapfile(void); -static void map_page(u_long, u_char, short, int); -static EMS_handle *get_new_handle(long); -static void context_to_handle(short); -static long find_next_free_handle(void); -static short lookup_handle(Hname *hp); -static void allocate_pages_to_handle(u_short, long); -static void allocate_handle(short, long); -static void reallocate_pages_to_handle(u_short, long); -static void free_handle(short); -static void free_pages_of_handle(short); -static void restore_context(EMS_mapping_context *); -static void save_context_to_dos(EMScontext *); -static int check_saved_context(EMScontext *); -static void *get_valid_pointer(u_short, u_short, u_long); -static u_long move_ems_to_conv(short, u_short, u_short, u_long, u_long); -static u_long move_conv_to_ems(u_long, u_short, u_short, u_short, u_long); -static u_long move_ems_to_ems(u_short, u_short, u_short, u_short, - u_short, u_short, u_long); - -/* - * EMS initialization routine: Return 1, if successful, return 0 if - * init problem or EMS disabled - */ - -int -ems_init() -{ - unsigned i; - - if (ems_max_size == 0) - return 0; - if (init_mapfile() == 0) - return 0; - /* Sanity */ - bzero((void *)(&ems_handle[0]), sizeof(ems_handle)); - ems_total_pages = ems_max_size / EMS_PAGESIZE; - ems_alloc_pages = 0; - ems_free_pages = ems_total_pages; - ems_alloc_handles = 0; - active_handle = 0; - /* Malloc the page array */ - ems_page = (EMS_page *)malloc(sizeof(EMS_page) * ems_total_pages); - if (ems_page == NULL) { - debug(D_ALWAYS, "Could not malloc page array, EMS disabled\n"); - ems_frame_addr = 0; - ems_max_size = 0; - ems_total_pages = 0; - return 0; - } - for (i = 0; i < ems_total_pages; i++) { - ems_page[i].handle = 0; - ems_page[i].status = EMS_FREE; - } - debug(D_EMS, "EMS: Emulation init OK.\n"); - return 1; -} - - -/* Main entry point */ - -void -ems_entry(regcontext_t *REGS) -{ - /* - * If EMS is not enabled, the DOS ems.exe module should not have - * been loaded. If it is loaded anyway, report software malfunction - */ - if (ems_max_size == 0) { - R_AH = EMS_SW_MALFUNC; - debug(D_EMS, "EMS emulation not enabled\n"); - return; - } - - switch (R_AH) - { - case GET_MANAGER_STATUS: - debug(D_EMS, "EMS: Get manager status\n"); - R_AH = EMS_SUCCESS; - break; - - case GET_PAGE_FRAME_SEGMENT: - debug(D_EMS, "EMS: Get page frame segment\n"); - R_BX = ems_frame_addr >> 4; - R_AH = EMS_SUCCESS; - break; - - case GET_PAGE_COUNTS: - R_BX = ems_total_pages - ems_alloc_pages; - R_DX = ems_total_pages; - debug(D_EMS, "EMS: Get page count: Returned total=%d, free=%d\n", - R_DX, R_BX); - R_AH = EMS_SUCCESS; - break; - - case GET_HANDLE_AND_ALLOCATE: - { - u_short npages; - short handle; - - npages = R_BX; - debug(D_EMS, "EMS: Get handle and allocate %d pages: ", npages); - - /* Enough handles? */ - if ((handle = find_next_free_handle()) < 0) { - debug(D_EMS,"Return error:No handles\n"); - R_AH = EMS_OUT_OF_HANDLES; - break; - } - /* Enough memory for this request ? */ - if (npages > ems_free_pages) { - debug(D_EMS,"Return error:Request too big\n"); - R_AH = EMS_OUT_OF_LOG; - break; - } - if (npages > ems_total_pages) { - debug(D_EMS,"Return error:Request too big\n"); - R_AH = EMS_OUT_OF_PHYS; - break; - } - /* Not allowed to allocate zero pages with this function */ - if (npages == 0) { - debug(D_EMS,"Return error:Cannot allocate 0 pages\n"); - R_AH = EMS_ZERO_PAGES; - break; - } - /* Allocate the handle */ - allocate_handle(handle, npages); - - /* Allocate the pages */ - allocate_pages_to_handle(handle, npages); - R_DX = handle; - R_AH = EMS_SUCCESS; - debug(D_EMS,"Return success:Handle = %d\n", handle); - break; - } - - case MAP_UNMAP: - { - u_char position; - u_short hpagenum, spagenum; - short handle; - - debug(D_EMS, "EMS: Map/Unmap handle=%d, pos=%d, pagenum=%d ", - R_DX, R_AL, R_BX); - handle = R_DX; - position = R_AL; - if (position > 3) { - debug(D_EMS, "invalid position\n"); - R_AH = EMS_ILL_PHYS; - break; - } - hpagenum = R_BX; - /* This succeeds without a valid handle ! */ - if (hpagenum == 0xffff) { - /* Unmap only */ - map_page(0, position, handle, 1); - debug(D_EMS, "(unmap only) success\n"); - R_AH = EMS_SUCCESS; - break; - } - if (handle > 255 || handle == 0 || ems_handle[handle] == NULL) { - R_AH = EMS_INV_HANDLE; - debug(D_EMS, "invalid handle\n"); - break; - } - if (hpagenum >= ems_handle[handle]->npages) { - R_AH = EMS_LOGPAGE_TOOBIG; - debug(D_EMS, "invalid pagenumber\n"); - break; - } - spagenum = ems_handle[handle]->pagenum[hpagenum]; - map_page(spagenum, position, handle, 0); - debug(D_EMS, "success\n"); - R_AH = EMS_SUCCESS; - break; - } - - case DEALLOCATE_HANDLE: - { - short handle; - - /* Handle valid ? */ - handle = R_DX; - debug(D_EMS, "EMS: Deallocate handle %d\n", handle); - if (handle > 255 || ems_handle[handle] == NULL) { - R_AH = EMS_INV_HANDLE; - break; - } - /* Mapping context saved ? */ - if (ems_handle[handle]->mcontext != NULL) { - R_AH = EMS_SAVED_MAP; - break; - } - - free_pages_of_handle(handle); - free_handle(handle); - R_AH = EMS_SUCCESS; - break; - } - - case GET_EMM_VERSION: - debug(D_EMS, "EMS: Get version\n"); - R_AL = EMS_VERSION; - R_AH = EMS_SUCCESS; - break; - - case SAVE_PAGE_MAP: - { - short handle; - - debug(D_EMS, "EMS: Save page map\n"); - handle = R_DX; - if (handle > 255 || handle == 0 || ems_handle[handle] == NULL) { - R_AH = EMS_INV_HANDLE; - break; - } - if (ems_handle[handle]->mcontext != NULL) { - /* There is already a context saved */ - if (memcmp((void *)ems_handle[handle]->mcontext, - (void *)&ems_mapping_context, - sizeof(EMS_mapping_context)) == 0) - R_AH = EMS_ALREADY_SAVED; - else - R_AH = EMS_NO_ROOM_TO_SAVE; - break; - } - context_to_handle(handle); - R_AH = EMS_SUCCESS; - break; - } - - case RESTORE_PAGE_MAP: - { - short handle; - - debug(D_EMS, "EMS: Restore page map\n"); - handle = R_DX; - if (handle > 255 || handle == 0 || ems_handle[handle] == NULL) { - R_AH = EMS_INV_HANDLE; - break; - } - if (ems_handle[handle]->mcontext == NULL) { - R_AH = EMS_NO_SAVED_CONTEXT; - break; - } - restore_context(ems_handle[handle]->mcontext); - free((void *)ems_handle[handle]->mcontext); - ems_handle[handle]->mcontext = NULL; - R_AH = EMS_SUCCESS; - break; - } - - case RESERVED_1: - case RESERVED_2: - debug(D_ALWAYS, "Reserved function called: %02x\n", R_AH); - R_AH = EMS_FUNC_NOSUP; - break; - - case GET_HANDLE_COUNT: - debug(D_EMS, "EMS: Get handle count\n"); - R_BX = ems_alloc_handles + 1; - R_AH = EMS_SUCCESS; - break; - - case GET_PAGES_OWNED: - { - short handle; - - debug(D_EMS, "EMS: Get pages owned\n"); - /* Handle valid ? */ - handle = R_DX; - if (handle > 255 || ems_handle[handle] == NULL) { - R_AH = EMS_INV_HANDLE; - break; - } - if (handle == 0) - R_BX = 0; - else - R_BX = ems_handle[handle]->npages; - R_AH = EMS_SUCCESS; - break; - } - - case GET_PAGES_FOR_ALL: - { - EMShandlepage *ehp; - unsigned safecount; - int i; - - debug(D_EMS, "EMS: Get pages for all\n"); - /* Get the address passed from DOS app */ - ehp = (EMShandlepage *)get_valid_pointer(R_ES, R_DI, - sizeof(EMShandlepage) * ems_alloc_handles); - if (ehp == NULL) { - R_AH = EMS_SW_MALFUNC; - break; - } - - R_BX = ems_alloc_handles; - safecount = 0; - for (i = 0; i < 255; i++) { - if (ems_handle[i] != NULL) { - if (safecount > (ems_alloc_handles+1)) - fatal("EMS: ems_alloc_handles is wrong, " - "cannot continue\n"); - ehp->handle = i; - ehp->npages = ems_handle[i]->npages; - ehp++; - safecount++; - } - } - R_AH = EMS_SUCCESS; - break; - } - - case PAGE_MAP: - /* This function is a nuisance. It was invented to save time and - * memory, but in our case it is useless. We have to support it - * but we use the same save memory as for the page map function. - * It uses only 20 bytes anyway. We store/restore the entire mapping - */ - case PAGE_MAP_PARTIAL: - { - int subfunction; - EMScontext *src, *dest; - - debug(D_EMS, "EMS: Page map "); - subfunction = R_AL; - if (R_AH == PAGE_MAP_PARTIAL) { - debug(D_EMS, "partial "); - /* Page map partial has slightly different subfunctions - * GET_SET does not exist and is GET_SIZE in this case - */ - if (subfunction == GET_SET) - subfunction = GET_SIZE; - } - switch (subfunction) - { - case GET: - { - debug(D_EMS, "get\n"); - /* Get the address passed from DOS app */ - dest = (EMScontext *)get_valid_pointer(R_ES, R_DI, - sizeof(EMScontext)); - if (dest == NULL) { - R_AH = EMS_SW_MALFUNC; - break; - } - save_context_to_dos(dest); - R_AH = EMS_SUCCESS; - break; - } - case SET: - { - debug(D_EMS, "set\n"); - src = (EMScontext *)get_valid_pointer(R_DS, R_SI, - sizeof(EMScontext)); - if (src == NULL) { - R_AH = EMS_SW_MALFUNC; - break; - } - if (check_saved_context(src) == 0) { - R_AH = EMS_SAVED_CONTEXT_BAD; - break; - } - restore_context(&src->ems_saved_context); - R_AH = EMS_SUCCESS; - break; - } - case GET_SET: - { - debug(D_EMS, "get/set\n"); - dest = (EMScontext *)get_valid_pointer(R_ES, R_DI, - sizeof(EMScontext)); - if (dest == NULL) { - R_AH = EMS_SW_MALFUNC; - break; - } - save_context_to_dos(dest); - src = (EMScontext *)get_valid_pointer(R_DS, R_SI, - sizeof(EMScontext)); - if (src == NULL) { - R_AH = EMS_SW_MALFUNC; - break; - } - if (check_saved_context(src) == 0) { - R_AH = EMS_SAVED_CONTEXT_BAD; - break; - } - restore_context(&src->ems_saved_context); - R_AH = EMS_SUCCESS; - break; - } - case GET_SIZE: - debug(D_EMS, "get size\n"); - R_AL = (sizeof(EMScontext) + 1) & 0xfe; - R_AH = EMS_SUCCESS; - break; - default: - debug(D_EMS, "invalid subfunction\n"); - R_AH = EMS_INVALID_SUB; - break; - } - break; - } - - case MAP_UNMAP_MULTI_HANDLE: - { - u_char position; - u_short hpagenum, spagenum; - short handle; - EMSmapunmap *mp; - int n_entry, i; - - - debug(D_EMS, "EMS: Map/Unmap multiple "); - - if ((n_entry = R_CX) > 3) { - R_AH = EMS_ILL_PHYS; - } - - /* This is valid according to the LIM EMS 4.0 spec */ - if (n_entry == 0) { - R_AH = EMS_SUCCESS; - break; - } - - handle = R_DX; - if (handle > 255 || handle == 0 || ems_handle[handle] == NULL) { - R_AH = EMS_INV_HANDLE; - break; - } - - mp = (EMSmapunmap *)get_valid_pointer(R_DS, R_SI, - sizeof(EMSmapunmap) * n_entry); - if (mp == NULL) { - R_AH = EMS_SW_MALFUNC; - break; - } - - R_AH = EMS_SUCCESS; - /* Walk through the table and map/unmap */ - for (i = 0; i < n_entry; i++) { - hpagenum = mp->log; - /* Method is in R_AL */ - if (R_AL == 0) { - debug(D_EMS, "phys page method\n"); - if (mp->phys <= 3) { - position = mp->phys; - } else { - R_AH = EMS_ILL_PHYS; - break; - } - } else if (R_AL == 1) { - /* Compute position from segment address */ - u_short p_seg; - - debug(D_EMS, "segment method\n"); - p_seg = mp->phys; - p_seg -= ems_frame_addr; - p_seg /= EMS_PAGESIZE; - if (p_seg <= 3) { - position = p_seg; - } else { - R_AH = EMS_ILL_PHYS; - break; - } - } else { - debug(D_EMS, "invalid subfunction\n"); - R_AH = EMS_INVALID_SUB; - break; - } - - mp++; - if (hpagenum == 0xffff) { - /* Unmap only */ - map_page(0, position, handle, 1); - continue; - } - if (hpagenum >= ems_handle[handle]->npages) { - R_AH = EMS_LOGPAGE_TOOBIG; - break; - } - spagenum = ems_handle[handle]->pagenum[hpagenum]; - map_page(spagenum, position, handle, 0); - } - break; - } - - case REALLOC_PAGES: - { - short handle; - u_long newpages; - - debug(D_EMS, "EMS: Realloc pages "); - - handle = R_DX; - if (handle > 255 || handle == 0 || ems_handle[handle] == NULL) { - R_AH = EMS_INV_HANDLE; - debug(D_EMS, "invalid handle\n"); - break; - } - newpages = R_BX; - debug(D_EMS, "changed from %ld to %ld pages\n", - ems_handle[handle]->npages, newpages); - - /* Case 1: Realloc to zero pages */ - if (newpages == 0) { - free_pages_of_handle(handle); - R_AH = EMS_SUCCESS; - break; - } - /* Case 2: New allocation is equal to allocated number */ - if (newpages == ems_handle[handle]->npages) { - R_AH = EMS_SUCCESS; - break; - } - /* Case 3: Reallocate to bigger and smaller sizes */ - if (newpages > ems_handle[handle]->npages) { - if (newpages > ems_free_pages) { - R_AH = EMS_OUT_OF_LOG; - break; - } - if (newpages > ems_total_pages) { - R_AH = EMS_OUT_OF_PHYS; - break; - } - } - reallocate_pages_to_handle(handle, newpages); - R_AH = EMS_SUCCESS; - break; - } - - /* We do not support nonvolatile pages */ - case HANDLE_ATTRIBUTES: - debug(D_EMS, "Handle attributes called\n"); - switch (R_AL) { - case GET: - case SET: - R_AH = EMS_FEAT_NOSUP; - break; - case HANDLE_CAPABILITY: - R_AL = 0; /* Volatile only */ - R_AH = EMS_SUCCESS; - break; - default: - R_AH = EMS_FUNC_NOSUP; - break; - } - break; - - case HANDLE_NAME: - { - short handle; - Hname *hp; - - handle = R_DX; - if (handle > 255 || handle == 0 || ems_handle[handle] == NULL) { - R_AH = EMS_INV_HANDLE; - debug(D_EMS, "invalid handle\n"); - break; - } - switch (R_AL) { - case GET: - if ((hp = (Hname *)get_valid_pointer(R_ES, R_DI, 8)) - == NULL) { - R_AH = EMS_SW_MALFUNC; - break; - } - *hp = ems_handle[handle]->hname; - R_AH = EMS_SUCCESS; - break; - - case SET: - if ((hp = (Hname *)get_valid_pointer(R_DS, R_SI, 8)) - == NULL) { - R_AH = EMS_SW_MALFUNC; - break; - } - /* If the handle name is not 0, it may not exist */ - if ((hp->ul_hn[0] | hp->ul_hn[1]) != 0) { - if (lookup_handle(hp) == 0) { - ems_handle[handle]->hname = *hp; - R_AH = EMS_SUCCESS; - } else { - R_AH = EMS_NAME_EXISTS; - break; - } - } else { - /* Name is deleted (set to zeros) */ - ems_handle[handle]->hname = *hp; - R_AH = EMS_SUCCESS; - } - break; - - default: - R_AH = EMS_FUNC_NOSUP; - break; - } - break; - } - - case HANDLE_DIRECTORY: - { - int i; - EMShandledir *hdp; - Hname *hp; - short handle; - - switch(R_AL) { - case GET: - hdp = (EMShandledir *)get_valid_pointer(R_ES, R_DI, - sizeof(EMShandledir) * ems_alloc_handles); - if (hdp == NULL) { - R_AH = EMS_SW_MALFUNC; - break; - } - for (i = 0; i < EMS_NUM_HANDLES; i++) { - if (ems_handle[i] != NULL) { - hdp->log = i; - hdp->name = ems_handle[i]->hname; - } - } - R_AH = EMS_SUCCESS; - break; - - case HANDLE_SEARCH: - hp = (Hname *)get_valid_pointer(R_DS, R_SI, 8); - if (hp == NULL) { - R_AH = EMS_SW_MALFUNC; - break; - } - /* Cannot search for NULL handle name */ - if ((hp->ul_hn[0] | hp->ul_hn[1]) != 0) { - R_AH = EMS_NAME_EXISTS; - break; - } - if ((handle = lookup_handle(hp)) == 0) { - R_AH = EMS_HNAME_NOT_FOUND; - } else { - R_DX = handle; - R_AH = EMS_SUCCESS; - } - break; - - case GET_TOTAL_HANDLES: - R_AH = EMS_SUCCESS; - R_BX = EMS_NUM_HANDLES; /* Includes OS handle */ - break; - - default: - R_AH = EMS_FUNC_NOSUP; - break; - } - break; - } - - - /* I do not know if we need this. LINUX emulation leaves it out - * so I leave it out too for now. - */ - case ALTER_PAGEMAP_JUMP: - debug(D_ALWAYS, "Alter pagemap and jump used!\n"); - R_AH = EMS_FUNC_NOSUP; - break; - case ALTER_PAGEMAP_CALL: - debug(D_ALWAYS, "Alter pagemap and call used!\n"); - R_AH = EMS_FUNC_NOSUP; - break; - - - case MOVE_MEMORY_REGION: - { - EMSmovemem *emvp; - u_long src_addr, dst_addr; - u_short src_handle, dst_handle; - - if (R_AL == EXCHANGE) - debug(D_EMS, "EMS: Exchange memory region "); - else - debug(D_EMS, "EMS: Move memory region "); - - emvp = (EMSmovemem *)get_valid_pointer(R_DS, R_SI, - sizeof(EMSmovemem)); - if (emvp == NULL) { - debug(D_EMS, "Invalid structure pointer\n"); - R_AH = EMS_SW_MALFUNC; - break; - } - /* Zero length is not an error */ - if (emvp->length == 0) { - debug(D_EMS, "Zero length\n"); - R_AH = EMS_SUCCESS; - break; - } - /* Some checks */ - if (emvp->src_type == EMS_MOVE_CONV) { - /* Conventional memory source */ - src_addr = MAKEPTR(emvp->src_seg, emvp->src_offset); - /* May not exceed conventional memory */ - if ((src_addr + emvp->length) > 640 * 1024) { - R_AH = EMS_SW_MALFUNC; - break; - } - } else { - /* Check the handle */ - src_handle = emvp->src_handle; - if (src_handle > 255 || src_handle == 0 || - ems_handle[src_handle] == NULL) { - R_AH = EMS_INV_HANDLE; - debug(D_EMS, "invalid source handle\n"); - break; - } - /* Offset may not exceed page size */ - if (emvp->src_offset >= (16 * 1024)) { - R_AH = EMS_PAGEOFFSET; - debug(D_EMS, "source page offset too big\n"); - break; - } - } - - if (emvp->dst_type == EMS_MOVE_CONV) { - /* Conventional memory source */ - dst_addr = MAKEPTR(emvp->dst_seg, emvp->dst_offset); - /* May not exceed conventional memory */ - if ((dst_addr + emvp->length) > 640 * 1024) { - R_AH = EMS_SW_MALFUNC; - break; - } - } else { - /* Check the handle */ - dst_handle = emvp->dst_handle; - if (dst_handle > 255 || dst_handle == 0 || - ems_handle[dst_handle] == NULL) { - R_AH = EMS_INV_HANDLE; - debug(D_EMS, "invalid destination handle\n"); - break; - } - /* Offset may not exceed page size */ - if (emvp->dst_offset >= (16 * 1024)) { - R_AH = EMS_PAGEOFFSET; - debug(D_EMS, "destination page offset too big\n"); - break; - } - } - - if (R_AL == MOVE) { - /* If it is conventional memory only, do it */ - if (emvp->src_type == EMS_MOVE_CONV && - emvp->dst_type == EMS_MOVE_CONV) { - memmove((void *)dst_addr, (void *)src_addr, - (size_t) emvp->length); - debug(D_EMS, "conventional to conventional memory done\n"); - R_AH = EMS_SUCCESS; - break; - } - if (emvp->src_type == EMS_MOVE_EMS && - emvp->dst_type == EMS_MOVE_CONV) - R_AH = move_ems_to_conv(src_handle, emvp->src_seg, - emvp->src_offset, dst_addr, emvp->length); - else if (emvp->src_type == EMS_MOVE_CONV && - emvp->dst_type == EMS_MOVE_EMS) - R_AH = move_conv_to_ems(src_addr, dst_handle, - emvp->dst_seg, emvp->dst_offset, emvp->length); - else - R_AH = move_ems_to_ems(src_handle, emvp->src_seg, - emvp->src_offset, dst_handle, emvp->dst_seg, - emvp->dst_offset, emvp->length); - debug(D_EMS, " done\n"); - break; - } else { - /* exchange memory region */ - - /* We need a scratch area for the exchange */ - void *buffer; - if ((buffer = malloc(emvp->length)) == NULL) - fatal("EMS: Could not malloc scratch area for exchange"); - - /* If it is conventional memory only, do it */ - if (emvp->src_type == EMS_MOVE_CONV && - emvp->dst_type == EMS_MOVE_CONV) { - /* destination -> buffer */ - memmove(buffer, (void *)dst_addr, (size_t) emvp->length); - /* Source -> destination */ - memmove((void *)dst_addr, (void *)src_addr, - (size_t) emvp->length); - /* Buffer -> source */ - memmove((void *)src_addr, buffer, (size_t) emvp->length); - free(buffer); - debug(D_EMS, "conventional to conventional memory done\n"); - R_AH = EMS_SUCCESS; - break; - } - - /* Exchange EMS with conventional */ - if (emvp->src_type == EMS_MOVE_EMS && - emvp->dst_type == EMS_MOVE_CONV) { - /* Destination -> buffer */ - memmove(buffer, (void *)dst_addr, (size_t) emvp->length); - /* Source -> destination */ - R_AH = move_ems_to_conv(src_handle, emvp->src_seg, - emvp->src_offset, dst_addr, emvp->length); - if (R_AH != EMS_SUCCESS) { - free(buffer); - break; - } - /* Buffer -> source */ - R_AH = move_conv_to_ems((u_long)buffer, src_handle, - emvp->src_seg, emvp->src_offset, emvp->length); - - /* Exchange conventional with EMS */ - } else if (emvp->src_type == EMS_MOVE_CONV && - emvp->dst_type == EMS_MOVE_EMS) { - /* Destination -> buffer */ - R_AH = move_ems_to_conv(dst_handle, emvp->dst_seg, - emvp->dst_offset, (u_long)buffer, emvp->length); - if (R_AH != EMS_SUCCESS) { - free(buffer); - break; - } - /* Source -> destination */ - R_AH = move_conv_to_ems((u_long)buffer, dst_handle, - emvp->dst_seg, emvp->dst_offset, emvp->length); - /* Buffer -> source */ - memmove(buffer, (void *)src_addr, (size_t) emvp->length); - - /* Exchange EMS with EMS */ - } else { - /* Destination -> buffer */ - R_AH = move_ems_to_conv(dst_handle, emvp->dst_seg, - emvp->dst_offset, (u_long)buffer, emvp->length); - if (R_AH != EMS_SUCCESS) { - free(buffer); - break; - } - /* Source -> destination */ - R_AH = move_ems_to_ems(src_handle, emvp->src_seg, - emvp->src_offset, dst_handle, emvp->dst_seg, - emvp->dst_offset, emvp->length); - if (R_AH != EMS_SUCCESS) { - free(buffer); - break; - } - /* Buffer -> source */ - R_AH = move_conv_to_ems((u_long)buffer, src_handle, - emvp->src_seg, emvp->src_offset, emvp->length); - } - free(buffer); - } - debug(D_EMS, " done\n"); - break; - } - - case GET_MAPPABLE_PHYS_ADDR: - { - switch (R_AL) { - case GET_ARRAY: - { - EMSaddrarray *eadp; - int i; - u_short seg; - - eadp = (EMSaddrarray *)get_valid_pointer(R_ES, R_DI, - sizeof(EMSaddrarray) * 4); - if (eadp == NULL) { - R_AH = EMS_SW_MALFUNC; - break; - } - for (i = 0, seg = (ems_frame_addr >> 4); i < 4; i++) { - eadp->segm = seg; - eadp->phys = i; - eadp++; - seg += 1024; - } - R_AH = EMS_SUCCESS; - break; - } - case GET_ARRAY_ENTRIES: - /* There are always 4 positions, 4*16kB = 64kB */ - R_CX = 4; - R_AH = EMS_SUCCESS; - break; - default: - R_AH = EMS_FUNC_NOSUP; - break; - } - break; - } - - /* This is an OS function in the LIM EMS 4.0 standard: It is - * usable only by an OS and its use can be disabled for all other - * programs. I think we do not need to support it. It is not - * implemented and it reports "disabled" to any caller. - */ - case GET_HW_CONFIGURATION: - R_AH = EMS_FUNCTION_DISABLED; - break; - - /* This function is a little different, it was defined with - * LIM EMS 4.0: It is allowed to allocate zero pages and raw - * page size (i.e. page size != 16kB) is supported. We have - * only 16kB pages, so the second difference does not matter. - */ - case ALLOCATE_PAGES: - { - u_short npages; - short handle; - - npages = R_BX; - debug(D_EMS, "EMS: Get handle and allocate %d pages: ", npages); - - /* Enough handles? */ - if ((handle = find_next_free_handle()) < 0) { - debug(D_EMS,"Return error:No handles\n"); - R_AH = EMS_OUT_OF_HANDLES; - break; - } - /* Enough memory for this request ? */ - if (npages > ems_free_pages) { - debug(D_EMS,"Return error:Request too big\n"); - R_AH = EMS_OUT_OF_LOG; - break; - } - if (npages > ems_total_pages) { - debug(D_EMS,"Return error:Request too big\n"); - R_AH = EMS_OUT_OF_PHYS; - break; - } - - /* Allocate the handle */ - allocate_handle(handle, npages); - - /* Allocate the pages */ - allocate_pages_to_handle(handle, npages); - R_DX = handle; - R_AH = EMS_SUCCESS; - debug(D_EMS,"Return success:Handle = %d\n", handle); - break; - } - - /* This is an OS function in the LIM EMS 4.0 standard: It is - * usable only by an OS and its use can be disabled for all other - * programs. I think we do not need to support it. It is not - * implemented and it reports "disabled" to any caller. - */ - case ALTERNATE_MAP_REGISTER: - R_AH = EMS_FUNCTION_DISABLED; - break; - - /* We cannot support that ! */ - case PREPARE_WARMBOOT: - R_AH = EMS_FUNC_NOSUP; - break; - - case OS_FUNCTION_SET: - R_AH = EMS_FUNCTION_DISABLED; - break; - - default: - debug(D_ALWAYS, "EMS: Unknown function called: %02x\n", R_AH); - R_AH = EMS_FUNC_NOSUP; - break; - } -} - -/* Initialize the EMS memory: Return 1 on success, 0 on failure */ - -static int -init_mapfile() -{ - char path[256]; - int mfd; - - /* Sanity */ - if (ems_max_size == 0) - return 0; - strcpy(path, EMS_MAP_PATH); - strcat(path, EMS_MAP_FILE); - - mfd = mkstemp(path); - - if (mfd < 0) { - debug(D_ALWAYS, "Could not create EMS mapfile, "); - goto fail; - } - unlink(path); - mapfile_fd = squirrel_fd(mfd); - - if (lseek(mapfile_fd, (off_t)(ems_max_size - 1), 0) < 0) { - debug(D_ALWAYS, "Could not seek into EMS mapfile, "); - goto fail; - } - if (write(mapfile_fd, "", 1) < 0) { - debug(D_ALWAYS, "Could not write to EMS mapfile, "); - goto fail; - } - /* Unmap the entire page frame */ - if (munmap((caddr_t)ems_frame_addr, 64 * 1024) < 0) { - debug(D_ALWAYS, "Could not unmap EMS page frame, "); - goto fail; - } - /* DOS programs will access the page frame without allocating - * pages first. Microsoft diagnose MSD.EXE does this, for example - * We need to have memory here to avoid segmentation violation - */ - if (mmap((caddr_t)ems_frame_addr, 64 * 1024, - PROT_EXEC | PROT_READ | PROT_WRITE, - MAP_ANON | MAP_FIXED | MAP_SHARED, - -1, 0) == MAP_FAILED) { - debug(D_ALWAYS, "Could not map EMS page frame, "); - goto fail; - } - bzero((void *)&ems_mapping_context, sizeof(EMS_mapping_context)); - return (1); - -fail: - debug(D_ALWAYS, "EMS disabled\n"); - ems_max_size = 0; - ems_frame_addr = 0; - return (0); -} - -/* Map/Unmap pages into one of four positions in the frame segment */ - -static void -map_page(u_long pagenum, u_char position, short handle, int unmaponly) -{ - caddr_t map_addr; - size_t len; - off_t file_offs; - - if (position > 3) - fatal("EMS: Internal error: Mapping position\n"); - - map_addr = (caddr_t)(ems_frame_addr + (1024 * 16 * (u_long)position)); - len = 1024 * 16; - file_offs = (off_t)(pagenum * 16 * 1024); - - if (ems_mapping_context.pos_mapped[position]) { - if (munmap(map_addr, len) < 0) { - fatal("EMS unmapping error: %s\nCannot recover\n", - strerror(errno)); - } - ems_page[ems_mapping_context.pos_pagenum[position]].status - &= ~EMS_MAPPED; - ems_mapping_context.pos_mapped[position] = 0; - ems_mapping_context.handle[position] = 0; - } - if (unmaponly) { - /* DOS programs will access the page frame without allocating - * pages first. Microsoft diagnose MSD.EXE does this, for example - * We need to have memory here to avoid segmentation violation - */ - if (mmap((caddr_t)ems_frame_addr, 64 * 1024, - PROT_EXEC | PROT_READ | PROT_WRITE, - MAP_ANON | MAP_FIXED | MAP_SHARED, - -1, 0) == MAP_FAILED) - fatal("Could not map EMS page frame during unmap only\n"); - return; - } - if (mmap(map_addr, len, - PROT_EXEC | PROT_READ | PROT_WRITE, - MAP_FILE | MAP_FIXED | MAP_SHARED, - mapfile_fd, file_offs) == MAP_FAILED) { - fatal("EMS mapping error: %s\nCannot recover\n", strerror(errno)); - } - ems_mapping_context.pos_mapped[position] = 1; - ems_mapping_context.pos_pagenum[position] = pagenum; - ems_mapping_context.handle[position] = handle; - ems_page[pagenum].status |= EMS_MAPPED; -} - -/* Get a pointer from VM86 app, check it and return it. This returns NULL - * if the pointer is not valid. We can check only for very limited - * criteria: The pointer and the area defined by size may not point to - * memory over 1MB and it may not may to addresses under 1kB, because there - * is the VM86 interrupt table. - */ -static void -*get_valid_pointer(u_short seg, u_short offs, u_long size) -{ - u_long addr; - addr = MAKEPTR(seg, offs); - /* Check bounds */ - if ((addr + size) >= (1024 * 1024) || addr < 1024) - return NULL; - else - return (void *)addr; -} - -/* Malloc a new handle */ -static EMS_handle -*get_new_handle(long npages) -{ - EMS_handle *ehp; - size_t dynsize = sizeof(EMS_handle) + sizeof(short) * npages; - - if ((ehp = calloc(1, dynsize)) == NULL) - fatal("Cannot malloc EMS handle, cannot continue\n"); - return ehp; -} - -/* Allocate a mapping context to a handle */ -static void -context_to_handle(short handle) -{ - EMS_mapping_context *emc; - - if (ems_handle[handle] == NULL) - fatal("EMS context_to_handle called with invalid handle\n"); - if ((emc = calloc(1, sizeof(EMS_mapping_context))) == NULL) - fatal("EMS Cannot malloc mapping context, cannot continue\n"); - ems_handle[handle]->mcontext = emc; - memmove((void *)emc, (void *)&ems_mapping_context, - sizeof(EMS_mapping_context)); -} - -/* Find the next free handle, returns -1 if there are no more handles */ -static long -find_next_free_handle() -{ - int i; - - if (ems_alloc_handles >= 255) - return (-1); - /* handle 0 is OS handle */ - for (i = 1; i < EMS_NUM_HANDLES; i++) { - if (ems_handle[i] == NULL) - return (i); - } - fatal("EMS handle count garbled, should not happen\n"); - /* quiet 'gcc -Wall' */ - return (-1); -} - -/* Look for a named handle, returns 0 if not found, else handle */ -static short -lookup_handle(Hname *hp) -{ - int i; - - for (i = 1; i < EMS_NUM_HANDLES; i++) { - if (ems_handle[i] != NULL) { - if (hp->ul_hn[0] == ems_handle[i]->hname.ul_hn[0] && - hp->ul_hn[1] == ems_handle[i]->hname.ul_hn[1]) - return (i); - } - } - return (0); -} - -/* Malloc a new handle struct and put into array at index handle */ -static void -allocate_handle(short handle, long npages) -{ - if (ems_handle[handle] != NULL) - fatal("EMS allocate_handle, handle was not free\n"); - ems_handle[handle] = get_new_handle(npages); - ems_alloc_handles++; -} - -/* Free a handle, return its memory. Call this *after* freeing the - * allocated pages ! - */ -static void -free_handle(short handle) -{ - if (ems_handle[handle] == NULL) - fatal("EMS free_handle, handle was free\n"); - if (ems_handle[handle]->mcontext != NULL) - free((void *)ems_handle[handle]->mcontext); - free((void *)ems_handle[handle]); - ems_handle[handle] = NULL; - ems_alloc_handles--; -} - - -/* Allocates npages to handle. Call this routine only after you have - * ensured there are enough free pages *and* the new handle is in place - * in the handle array ! - */ -static void -allocate_pages_to_handle(u_short handle, long npages) -{ - unsigned syspagenum; - int pages_to_alloc = npages; - int allocpagenum = 0; - - /* sanity */ - if (handle > 255 || ems_handle[handle] == NULL) - fatal("EMS allocate_pages_to_handle called with invalid handle\n"); - - ems_handle[handle]->npages = npages; - for (syspagenum = 0; syspagenum < ems_total_pages; syspagenum++) { - if (ems_page[syspagenum].status == EMS_FREE) { - ems_page[syspagenum].handle = handle; - ems_page[syspagenum].status = EMS_ALLOCED; - ems_handle[handle]->pagenum[allocpagenum] = syspagenum; - allocpagenum++; - pages_to_alloc--; - if (pages_to_alloc == 0) - break; - } - } - if (pages_to_alloc > 0) - fatal("EMS allocate_pages_to_handle found not enough free pages\n"); - ems_alloc_pages += npages; - ems_free_pages -= npages; -} - -/* Reallocates npages to handle. Call this routine only after you have - * ensured there are enough free pages *and* the new handle is in place - * in the handle array ! - */ -static void -reallocate_pages_to_handle(u_short handle, long npages) -{ - unsigned allocpagenum; - unsigned syspagenum; - int pages_to_alloc; - long delta; - size_t dynsize; - EMS_handle *emp; - - /* sanity */ - if (handle > 255 || ems_handle[handle] == NULL) - fatal("EMS allocate_pages_to_handle called with invalid handle\n"); - - delta = npages - ems_handle[handle]->npages; - if (delta > 0) { - /* Grow array size and allocation */ - - emp = ems_handle[handle]; - dynsize = sizeof(EMS_handle) + sizeof(short) * npages; - - /* First step: Make room in the handle pagenum array */ - if ((emp = (EMS_handle *)realloc((void *)emp, dynsize)) == NULL) - fatal("Cannot malloc EMS handle, cannot continue\n"); - ems_handle[handle] = emp; - - /* Second step: Add pages to the handle */ - pages_to_alloc = delta; - allocpagenum = ems_handle[handle]->npages; - ems_handle[handle]->npages = npages; - for (syspagenum = 0; syspagenum < ems_total_pages; syspagenum++) { - if (ems_page[syspagenum].status == EMS_FREE) { - ems_page[syspagenum].handle = handle; - ems_page[syspagenum].status = EMS_ALLOCED; - ems_handle[handle]->pagenum[allocpagenum] = syspagenum; - allocpagenum++; - pages_to_alloc--; - if (pages_to_alloc == 0) - break; - } - } - if (pages_to_alloc > 0) - fatal("EMS allocate_pages_to_handle found not enough free pages\n"); - - } else { - /* Shrink array size and allocation */ - - /* First step: Deallocate all pages from new size to old size */ - for (allocpagenum = npages; - allocpagenum < ems_handle[handle]->npages; - allocpagenum++) { - syspagenum = ems_handle[handle]->pagenum[allocpagenum]; - - /* sanity */ - if (syspagenum > ems_total_pages) - fatal("EMS free_pages_of_handle found invalid page number\n"); - if (!(ems_page[syspagenum].status & EMS_ALLOCED)) - fatal("EMS free_pages_of_handle tried to free page already free\n"); - ems_page[syspagenum].handle = 0; - ems_page[syspagenum].status = EMS_FREE; - } - - /* Second step: Shrink the dynamic array of the handle */ - dynsize = sizeof(EMS_handle) + sizeof(short) * npages; - emp = ems_handle[handle]; - if ((emp = (EMS_handle *)realloc((void *)emp, dynsize)) == NULL) - fatal("Cannot realloc EMS handle, cannot continue\n"); - ems_handle[handle] = emp; - ems_handle[handle]->npages = npages; - } - ems_alloc_pages += delta; - ems_free_pages -= delta; -} - -/* Free all pages belonging to a handle, handle must be valid */ -static void -free_pages_of_handle(short handle) -{ - int allocpagenum; - unsigned syspagenum; - int npages; - - /* sanity */ - - if (handle > 255 || ems_handle[handle] == NULL) - fatal("EMS free_pages_of_handle called with invalid handle\n"); - - if ((npages = ems_handle[handle]->npages) == 0) - return; - - for (allocpagenum = 0; allocpagenum < npages; allocpagenum++) { - syspagenum = ems_handle[handle]->pagenum[allocpagenum]; - /* sanity */ - if (syspagenum > ems_total_pages) - fatal("EMS free_pages_of_handle found invalid page number\n"); - if (!(ems_page[syspagenum].status & EMS_ALLOCED)) - fatal("EMS free_pages_of_handle tried to free page already free\n"); - ems_page[syspagenum].handle = 0; - ems_page[syspagenum].status = EMS_FREE; - } - ems_alloc_pages -= npages; - ems_free_pages += npages; -} - -/* Restore a saved mapping context, overwrites current mapping context */ -static void -restore_context(EMS_mapping_context *emc) -{ - int i; - - for (i = 0; i < 4; i++) { - ems_mapping_context.handle[i] = emc->handle[i]; - if (emc->pos_mapped[i] != 0 && - ems_mapping_context.pos_pagenum[i] != emc->pos_pagenum[i]) { - map_page(emc->pos_pagenum[i], (u_char) i, emc->handle[i], 0); - } else { - ems_mapping_context.pos_mapped[i] = 0; - } - } -} - -/* Prepare a special context save block for DOS and save it to - * VM86 memory - */ -static void -save_context_to_dos(EMScontext *emp) -{ - int i, end; - EMScontext context; - u_short *sp; - u_short sum; - - context.ems_saved_context = ems_mapping_context; - context.magic = EMS_SAVEMAGIC; - context.checksum = 0; - sp = (u_short *)&context; - end = sizeof(EMScontext) / sizeof(short); - /* Generate checksum */ - for (i = 0, sum = 0; i < end; i++) { - sum += *sp++; - sum &= 0xffff; - } - context.checksum = 0x10000L - sum; - /* Save it to VM86 memory */ - *emp = context; -} - -/* Check a context returned from VM86 app for validity, return 0, if - * not valid, else return 1 - */ -static int -check_saved_context(EMScontext *emp) -{ - int i, end; - u_short *sp; - u_short sum; - - if (emp->magic != EMS_SAVEMAGIC) - return 0; - - sp = (u_short *)emp; - end = sizeof(EMScontext) / sizeof(short); - /* Generate checksum */ - for (i = 0, sum = 0; i < end; i++) { - sum += *sp++; - sum &= 0xffff; - } - if (sum != 0) - return 0; - else - return 1; -} - -/* Helper routine for the move routines below: Check if length bytes - * can be moved from/to handle pages (i.e are there enough pages) - */ -static int -check_alloc_pages(u_short handle, u_short firstpage, u_short offset, - u_long length __unused) -{ - u_long nbytes; - - if (firstpage > ems_handle[handle]->npages) - return (0); - nbytes = (ems_handle[handle]->npages - firstpage) * EMS_PAGESIZE - offset; - return (ems_handle[handle]->npages >= nbytes); -} - -/* Copy a block of memory up to the next 16kB boundary in the source - * to the destination in upward direction (i.e. with ascending addresses) - * XXX Could be an inline function. - */ -static void -copy_block_up(struct copydesc *cdp) -{ - size_t size; - void *srcp; - void *dstp; - - /* If source or both memory types are EMS, source determines the - * block length, else destination determines the block length - */ - if (cdp->copytype & SRC_EMS) - size = EMS_PAGESIZE - cdp->EMS_OFFS(src_addr); - else - size = EMS_PAGESIZE - cdp->EMS_OFFS(dst_addr); - - if (size > cdp->rest_len) - size = cdp->rest_len; - - /* If src is EMS memory, it is mapped into position 0 */ - if (cdp->copytype & SRC_EMS) - srcp = (void *)(ems_frame_addr + cdp->EMS_OFFS(src_addr)); - else - srcp = (void *)(cdp->EMS_PTR(src_addr)); - - /* If dest is EMS memory, it is mapped into position 1,2 */ - if (cdp->copytype & DST_EMS) - dstp = (void *)(ems_frame_addr + EMS_PAGESIZE + - cdp->EMS_OFFS(dst_addr)); - else - dstp = (void *)(cdp->EMS_PTR(dst_addr)); - - /* Move this block */ - memmove(dstp, srcp, size); - - /* Update the copy descriptor: This updates the address of both - * conventional and EMS memory - */ - cdp->EMS_PTR(src_addr) += size; - cdp->EMS_PTR(dst_addr) += size; - - cdp->rest_len -= size; -} - - -/* Move EMS memory starting with handle page src_seg and offset src_offset - * to conventional memory dst_addr for length bytes - * dst_addr is checked, handle is valid - */ -static u_long -move_ems_to_conv(short src_handle, u_short src_seg, - u_short src_offset, u_long dst_addr, u_long length) -{ - EMS_mapping_context ems_saved_context; - EMS_handle *ehp; - int pageindx = src_seg; - struct copydesc cd; - - if (check_alloc_pages(src_handle, src_seg, src_offset, length) == 0) - return EMS_MOVE_OVERFLOW; - - ehp = ems_handle[src_handle]; - - /* Prepare the move: Save the mapping context */ - ems_saved_context = ems_mapping_context; - - /* Setup the copy descriptor struct */ - - cd.copytype = SRC_EMS; - cd.EMS_PAGE(src_addr) = ehp->pagenum[pageindx]; - cd.EMS_OFFS(src_addr) = src_offset; - cd.EMS_PTR(dst_addr) = dst_addr; - cd.rest_len = length; - - do { - /* Map for the first block copy, source is mapped to position zero */ - map_page(cd.EMS_PAGE(src_addr), 0, src_handle, 0); - copy_block_up(&cd); - } while(cd.rest_len > 0); - - /* Restore the original mapping */ - restore_context(&ems_saved_context); - return EMS_SUCCESS; -} - -/* Move conventional memory starting with src_addr - * to EMS memory starting with handle page src_seg and offset src_offset - * for length bytes - * dst_addr is checked, handle is valid - */ -static u_long -move_conv_to_ems(u_long src_addr, u_short dst_handle, u_short dst_seg, - u_short dst_offset, u_long length) -{ - EMS_mapping_context ems_saved_context; - EMS_handle *ehp; - int pageindx = dst_seg; - struct copydesc cd; - - if (check_alloc_pages(dst_handle, dst_seg, dst_offset, length) == 0) - return EMS_MOVE_OVERFLOW; - - ehp = ems_handle[dst_handle]; - - /* Prepare the move: Save the mapping context */ - ems_saved_context = ems_mapping_context; - - /* Setup the copy descriptor struct */ - - cd.copytype = DST_EMS; - cd.EMS_PAGE(dst_addr) = ehp->pagenum[pageindx]; - cd.EMS_OFFS(dst_addr) = dst_offset; - cd.EMS_PTR(src_addr) = src_addr; - cd.rest_len = length; - - do { - map_page(cd.EMS_PAGE(dst_addr), 1, dst_handle, 0); - copy_block_up(&cd); - } while(cd.rest_len > 0); - - /* Restore the original mapping */ - restore_context(&ems_saved_context); - return EMS_SUCCESS; -} - -static u_long -move_ems_to_ems(u_short src_handle, u_short src_seg, u_short src_offset, - u_short dst_handle, u_short dst_seg, u_short dst_offset, - u_long length) -{ - EMS_mapping_context ems_saved_context; - EMS_handle *src_hp, *dst_hp; - struct copydesc cd; - - if (check_alloc_pages(src_handle, src_seg, src_offset, length) == 0) - return EMS_MOVE_OVERFLOW; - if (check_alloc_pages(dst_handle, dst_seg, dst_offset, length) == 0) - return EMS_MOVE_OVERFLOW; - - src_hp = ems_handle[src_handle]; - dst_hp = ems_handle[dst_handle]; - - /* Prepare the move: Save the mapping context */ - ems_saved_context = ems_mapping_context; - - /* Setup the copy descriptor struct */ - - cd.copytype = SRC_EMS | DST_EMS; - cd.EMS_PAGE(src_addr) = src_hp->pagenum[src_seg]; - cd.EMS_OFFS(src_addr) = src_offset; - cd.EMS_PAGE(dst_addr) = dst_hp->pagenum[dst_seg]; - cd.EMS_OFFS(dst_addr) = dst_offset; - cd.rest_len = length; - - /* Copy */ - do { - map_page(cd.EMS_PAGE(src_addr), 0, src_handle, 0); - map_page(cd.EMS_PAGE(dst_addr), 1, dst_handle, 0); - /* If there are more pages, map the next destination page to - * position 2. This removes a compare between source and dest - * offsets. - */ - if (cd.EMS_PAGE(dst_addr) < dst_hp->npages) - map_page((cd.EMS_PAGE(dst_addr) + 1), 2, dst_handle, 0); - copy_block_up(&cd); - } while(cd.rest_len > 0); - - /* Restore the original mapping */ - restore_context(&ems_saved_context); - return EMS_SUCCESS; -} diff --git a/usr.bin/doscmd/ems.h b/usr.bin/doscmd/ems.h deleted file mode 100644 index 276bddc..0000000 --- a/usr.bin/doscmd/ems.h +++ /dev/null @@ -1,313 +0,0 @@ -/*- - * Copyright (c) 1997 Helmut Wirth <hfwirth@ping.at> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice immediately at the beginning of the file, witout modification, - * this list of conditions, and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef EMS_H -#define EMS_H - -/* Header for ems.c, the EMS emulation */ - -/* Global definitions, some of them will be configurable in the future */ - -#define EMS_NUM_HANDLES 256 /* Includes OS handle 0 */ -#define EMS_MAXSIZE 10240 /* In kbytes */ -#define EMS_MAX_PHYS 4 /* Frame is 64kB */ -#define EMS_FRAME_ADDR 0xe0000 -#define EMS_VERSION 0x40 /* Version 4.0 */ -#define EMS_PAGESIZE (16 *1024) /* page size in bytes */ -#define EMS_SAVEMAGIC 0xAFFE /* magic number */ - -/* These are the LIM EMS 3.0 calls */ -#define GET_MANAGER_STATUS 0x40 -#define GET_PAGE_FRAME_SEGMENT 0x41 -#define GET_PAGE_COUNTS 0x42 -#define GET_HANDLE_AND_ALLOCATE 0x43 -#define MAP_UNMAP 0x44 -#define DEALLOCATE_HANDLE 0x45 -#define GET_EMM_VERSION 0x46 -#define SAVE_PAGE_MAP 0x47 -#define RESTORE_PAGE_MAP 0x48 -#define RESERVED_1 0x49 -#define RESERVED_2 0x4a -#define GET_HANDLE_COUNT 0x4b -#define GET_PAGES_OWNED 0x4c -#define GET_PAGES_FOR_ALL 0x4d - -/* LIM EMS 4.0 calls */ -/* Global subfunctions for the LIM EMS 4.0 calls */ -#define GET 0x0 -#define SET 0x1 -/* Modes for Map/Unmap and AlterandCall/AlterAndJump */ -#define PHYS_ADDR 0x0 -#define SEG_ADDR 0x0 - -/* Page map functions */ -#define PAGE_MAP 0x4e -#define PAGE_MAP_PARTIAL 0x4f -/* Page map subfunctions */ -#define GET_SET 0x2 -#define GET_SIZE 0x3 - -#define MAP_UNMAP_MULTI_HANDLE 0x50 - -#define REALLOC_PAGES 0x51 - -#define HANDLE_ATTRIBUTES 0x52 -/* Subfunctions */ -#define HANDLE_CAPABILITY 0x2 - -#define HANDLE_NAME 0x53 - -#define HANDLE_DIRECTORY 0x54 -#define HANDLE_SEARCH 0x1 -#define GET_TOTAL_HANDLES 0x2 - -#define ALTER_PAGEMAP_JUMP 0x55 -#define ALTER_PAGEMAP_CALL 0x56 -/* Subfunction for call */ -#define GET_STACK_SIZE 0x2 - -#define MOVE_MEMORY_REGION 0x57 -/* Subfunctions */ -#define MOVE 0x0 -#define EXCHANGE 0x1 - -#define GET_MAPPABLE_PHYS_ADDR 0x58 -/* Subfunctions */ -#define GET_ARRAY 0x0 -#define GET_ARRAY_ENTRIES 0x1 - -#define GET_HW_CONFIGURATION 0x59 -/* Subfunctions */ -#define GET_HW_ARRAY 0x0 -#define GET_RAW_PAGE_COUNT 0x1 - -#define ALLOCATE_PAGES 0x5a -/* Subfunctions */ -#define ALLOC_STANDARD 0x0 -#define ALLOC_RAW 0x1 - -#define ALTERNATE_MAP_REGISTER 0x5b -/* Subfunctions */ -#define GET_SAVE_ARRAY_SIZE 0x2 -#define ALLOCATE_REGISTER_SET 0x3 -#define DEALLOCATE_REGISTER_SET 0x4 -#define ALLOCATE_DMA 0x5 -#define ENABLE_DMA 0x6 -#define DISABLE_DMA 0x7 -#define DEALLOCATE_DMA 0x8 - -#define PREPARE_WARMBOOT 0x5c - -#define OS_FUNCTION_SET 0x5d -/* Subfunctions */ -#define ENABLE 0x0 -#define DISABLE 0x1 -#define RETURN_KEY 0x2 - -/* End of call definitions */ - -/* EMS errors */ - -#define EMS_SUCCESS 0x0 -#define EMS_SW_MALFUNC 0x80 -#define EMS_HW_MALFUNC 0x81 -#define EMS_INV_HANDLE 0x83 -#define EMS_FUNC_NOSUP 0x84 -#define EMS_OUT_OF_HANDLES 0x85 -#define EMS_SAVED_MAP 0x86 -#define EMS_OUT_OF_PHYS 0x87 -#define EMS_OUT_OF_LOG 0x88 -#define EMS_ZERO_PAGES 0x89 -#define EMS_LOGPAGE_TOOBIG 0x8a -#define EMS_ILL_PHYS 0x8b -#define EMS_NO_ROOM_TO_SAVE 0x8c -#define EMS_ALREADY_SAVED 0x8d -#define EMS_NO_SAVED_CONTEXT 0x8e -#define EMS_INVALID_SUB 0x8f -#define EMS_INVALID_ATTR 0x90 -#define EMS_FEAT_NOSUP 0x91 -#define EMS_MOVE_OVERLAP1 0x92 -#define EMS_MOVE_OVERFLOW 0x93 -#define EMS_PAGEOFFSET 0x95 -#define EMS_MOVE_OVERLAP2 0x97 -#define EMS_HNAME_NOT_FOUND 0xa0 -#define EMS_NAME_EXISTS 0xa1 -#define EMS_SAVED_CONTEXT_BAD 0xa3 -#define EMS_FUNCTION_DISABLED 0xa4 - -/* - * EMS handles: The handle contains at its end an array of pointers to - * its allocated pages. The array is of size npages. Handle structs are - * malloced at runtime. - * Page numbering: Every page is 16kB, always. The pages are numbered - * from 0 to highest page, depending on total EMS memory. Every handle - * has pages allocated and this pages too are numbered from 0 to highest - * page allocated. This are *not* the same numbers, because there may be - * holes in the allocation. - * Page numbers are unsigned short, which will give us 65536 * 16 kB (1GB) - * pages to handle at maximum. This should be enough for the next years. - */ - -typedef struct { - short handle[4]; /* Handle for each mapping */ - u_char pos_mapped[4]; /* Boolean value, 1 if something is mapped */ - u_char pos_pagenum[4]; /* Page number currently mapped into position */ -} EMS_mapping_context; - - -/* This union is for copying operations of the handle name only */ -typedef union { - u_char uc_hn[8]; - u_long ul_hn[2]; -} Hname; - -typedef struct { - Hname hname; - u_long npages; - /* The mapping context for save/restore page map */ - EMS_mapping_context *mcontext; - /* The pagenum here is the number in the system page array. The - * logical page number connected with this handle is the index into - * this array. - */ - u_short pagenum[0]; - /* Will grow here, depending on allocation */ -} EMS_handle; - -/* - * The connection between every page in the system and the handles is - * maintained by an array of these structs. The array is indexed by the - * page numbers. - */ - -typedef struct { - short handle; /* The handle this page belongs to */ -#define EMS_FREE 0 -#define EMS_ALLOCED 1 -#define EMS_MAPPED 2 - u_short status; /* room for misc information */ -} EMS_page; - -/* - * The combined pointer into EMS memory: offs is the offset into an EMS - * page, page is the page index inside the region allocated to a handle. - * This depends on EMS_PAGESIZE. - * This is used for copy and move operations. - */ - -typedef struct { - u_long offs:14; - u_long page:18; -} EMS_combi; - -typedef union { - u_long ua_addr; /* Conventional address pointer */ - EMS_combi ua_emsaddr; /* EMS address pointer */ -} EMS_addr; - -#define EMS_OFFS(u) u.ua_emsaddr.offs -#define EMS_PAGE(u) u.ua_emsaddr.page -#define EMS_PTR(u) u.ua_addr - -/* - * EMS info structure, only used to pass information to and from - * DOS - */ - -typedef struct { - u_short handle __attribute__ ((packed)); /* handle */ - u_short npages __attribute__ ((packed)); /* pages allocated */ -} EMShandlepage; - -/* - * EMS map/unmap multiple, only used to pass information to and from - * DOS - */ - -typedef struct { - u_short log __attribute__ ((packed)); /* logical page number */ - u_short phys __attribute__ ((packed)); /* physical page (position) or - segment address inside frame */ -} EMSmapunmap; - -/* - * EMS handle directory, only used to pass information to and from - * DOS - */ - -typedef struct { - u_short log __attribute__ ((packed)); /* logical page number */ - Hname name __attribute__ ((packed)); /* Handle name */ - -} EMShandledir; - -/* - * Structure for get/set page map: This structure is used to save and - * restore the page map from DOS memory. A program can get the mapping - * context and later set (restore) it. To avoid errors we add a magic - * number and a checksum. - */ - -typedef struct { - u_short magic; /* Magic number */ - u_short checksum; /* Checksum over entire structure */ - EMS_mapping_context ems_saved_context; -} EMScontext; - -/* - * EMS physical address array, only used to pass information to and from - * DOS - */ - -typedef struct { - u_short segm __attribute__ ((packed)); /* segment address inside frame */ - u_short phys __attribute__ ((packed)); /* physical page (position) */ -} EMSaddrarray; - -/* - * EMS move memory call structure, only used to pass information to and from - * DOS - */ - -typedef struct { - u_long length __attribute__ ((packed)); /* length of region */ -#define EMS_MOVE_CONV 0 -#define EMS_MOVE_EMS 1 - u_char src_type __attribute__ ((packed)); /* source type (0,1) */ - u_short src_handle __attribute__ ((packed)); /* source handle */ - u_short src_offset __attribute__ ((packed)); /* source offset */ - u_short src_seg __attribute__ ((packed)); /* source type */ - u_char dst_type __attribute__ ((packed)); /* destination type (0,1) */ - u_short dst_handle __attribute__ ((packed)); /* destination handle */ - u_short dst_offset __attribute__ ((packed)); /* destination offset */ - u_short dst_seg __attribute__ ((packed)); /* destination type */ -} EMSmovemem; - -#endif /* EMS_H */ diff --git a/usr.bin/doscmd/emsdriv.S b/usr.bin/doscmd/emsdriv.S deleted file mode 100644 index 40c7aff..0000000 --- a/usr.bin/doscmd/emsdriv.S +++ /dev/null @@ -1,261 +0,0 @@ -! Copyright (c) 1997 Helmut Wirth <hfwirth@ping.at> -! All rights reserved. -! -! Redistribution and use in source and binary forms, with or without -! modification, are permitted provided that the following conditions -! are met: -! 1. Redistributions of source code must retain the above copyright -! notice immediately at the beginning of the file, witout modification, -! this list of conditions, and the following disclaimer. -! 2. Redistributions in binary form must reproduce the above copyright -! notice, this list of conditions and the following disclaimer in the -! documentation and/or other materials provided with the distribution. -! 3. The name of the author may not be used to endorse or promote products -! derived from this software without specific prior written permission. -! -! THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -! IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -! OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -! IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -! INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -! NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -! DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -! THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -! (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -! THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -! -! $FreeBSD$ - - -! -! This driver is needed for Expanded Memory emulation (EMS). A driver -! is needed here, because EMS drivers are installed as DOS devices -! with the name "EMMXXXX0" and programs look for such a device while -! checking the existence of EMS. -! The driver is installed by CONFIG.SYS, it has no options. It uses -! the emulator callback interrupt 0xff to initialize the EMS subsystem. -! If EMS is not configured or if there is an error inside the emulator -! the driver reports failure and does not install itself. -! If all works, the driver changes the interrupt vector for int 0x67 to -! point at itself. The resident part of the drivers simlpy routes calls -! to int 0x67 to the correct subfunction of the emulator callback interrupt. - -use16 - -.text -.bss -.data -.align 0 - - .org 0 - -NumFunc = 15 - -! Emulator interrupt entry -EmulatorINT = 0xFF - -! Emulator EMS callback function -EMU_EMS = 0x2 -EMU_EMS_CTL = 0 -EMU_EMS_CALL = 1 - -! DOS print message -DOSMesg = 0x9 - -cr = 0xd -lf = 0xa -eom = '$' ! DOS end of string - -EMSintnum = 0x67 -Intoffset = (EMSintnum * 4) - -.globl _main -_main: - -driverhead: - .long -1 ! link to next device driver - .word 0xC000 ! attribute word for driver - .word Strategy ! ptr to strategy routine - .word Interrupt ! ptr to interrupt service routine - .ascii "EMMXXXX0" ! logical device name - -reqhead: - .long 0 - -vectordone: - .word 0 ! != 0 , if vector installed - -FuncTable: - .word InitDrv ! initialize driver - .word Noop ! media Check - .word Noop ! build BPB - .word Noop ! Ioctl - .word Noop ! read - .word Noop ! non destructive read - .word Noop ! input status - .word Noop ! flush input - .word Noop ! write - .word Noop ! write with verify - .word Noop ! output status - .word Noop ! flush output - .word Noop ! ioctl output - .word Noop ! open device - .word Noop ! close device - .word Noop ! removeable media check - -Strategy: - seg cs - mov [reqhead], bx - seg cs - mov [reqhead+2],es - retf - -Interrupt: - push ax - push bx - push cx - push dx - push ds - push es - push di - push si - push bp - - push cs - pop ds - - les di,[reqhead] ! load pointer to request header - - seg es - movb bl,[di+2] - xorb bh,bh - cmp bx, #NumFunc - jle dointr - call errorhandler - jmp intrend - -dointr: - shl bx,#1 - call [bx+FuncTable] - les di,[reqhead] ! load pointer to request header - -intrend: - or ax,#0x100 ! done bit - seg es - mov [di+3],ax - - pop bp - pop si - pop di - pop es - pop ds - pop dx - pop cx - pop bx - pop ax - retf - -errorhandler: - mov ax,#0x8003 ! report error to caller - ret - - -! This is done for all functions except init. It supports the different -! methods for an EMS installation check described in the LIM EMS 4.0 spec -Noop: - call installvector - xor ax,ax - ret - -! The interrupt vector installed for int 0x67 points to this routine -intr67: - push ax ! Save original AX - mov ah, #EMU_EMS ! Emuint function - mov al, #EMU_EMS_CALL ! Emuint subfunction - int EmulatorINT ! Call emulator for EMS - iret - -installvector: - push cs - pop ds ! load DS to use local data - mov ax,[vectordone] - cmp ax,#0 - jne isinstalled ! already installed - - push di ! save request header pointer - push es - - mov ax, #0 ! write the new interrupt vector - mov es, ax - mov di, #Intoffset - seg es - mov [di], #intr67 - seg es - mov [di+2], cs - - pop es - pop di - - mov ax,#1 - mov [vectordone],ax - -isinstalled: - ret - -InitDrv: - push cs - pop ds - push ax - mov ah, #EMU_EMS ! Emuint function - mov al, #EMU_EMS_CTL ! Emuint subfunction - int EmulatorINT - cmp ax,#0 ! check if successful - je Fail - - call installvector - - push cs - pop ds - - mov ah, #DOSMesg - mov dx, #Success - int 0x21 - - seg es - mov [di+14], #InitDrv ! address break for driver - seg es - mov [di+16], cs - - xor ax,ax - ret - -Fail: - push cs - pop ds - mov ah, #DOSMesg - mov dx, #Failure - int 0x21 - - seg es - movb [di+13],#0 - seg es - mov [di+20],cs - seg es - mov [di+14],#0 ! address break == 0, no driver - seg es - mov [di+16],cs - ret - - -Success: - .ascii "Doscmd EMS 4.0 driver installed" - .byte cr,lf,eom - -Failure: - .byte cr,lf,lf - .ascii "EMS emulation is disabled" - .byte cr,lf - .ascii "Driver not installed" - .byte cr,lf,lf,eom - - end diff --git a/usr.bin/doscmd/emsdriv.sys.uu b/usr.bin/doscmd/emsdriv.sys.uu deleted file mode 100644 index a896efd..0000000 --- a/usr.bin/doscmd/emsdriv.sys.uu +++ /dev/null @@ -1,13 +0,0 @@ -$FreeBSD$ - -begin 644 emsdriv.sys -M_____P#`.`!#`$5-35A86%@P````````M`"``(``@`"``(``@`"``(``@`"` -M`(``@`"``(``@``NB1X2`"Z,!A0`RU!345(>!E=650X?Q#X2`":*70(P_X/[ -M#WX%Z!P`ZPG1X_]7&,0^$@`-``$FB44#75Y?!Q]:65M8R[@#@,/H"P`QP,-0 -MM`*P`<W_SPX?H18`/0``=1M7!K@``([`OYP!)L<%A@`FC$T"!U^X`0"C%@## -M#A]0M`*P`,W_/0``=!GHR?\.'[0)NO@`S2$FQT4.M``FC$T0,<###A^T";H: -M`<TA)L9%#0`FC$T4)L=%#@``)HQ-$,-$;W-C;60@14U3(#0N,"!D<FEV97(@ -M:6YS=&%L;&5D#0HD#0H*14U3(&5M=6QA=&EO;B!I<R!D:7-A8FQE9`T*1')I -5=F5R(&YO="!I;G-T86QL960-"@HD -` -end diff --git a/usr.bin/doscmd/emuint.c b/usr.bin/doscmd/emuint.c deleted file mode 100644 index d00a767..0000000 --- a/usr.bin/doscmd/emuint.c +++ /dev/null @@ -1,112 +0,0 @@ -/*- - * Copyright (c) 1997 Helmut Wirth <hfwirth@ping.at> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice immediately at the beginning of the file, witout modification, - * this list of conditions, and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <ctype.h> -#include "doscmd.h" -#include "emuint.h" - -/* The central entry point for the emulator interrupt. This is used by - * different special programs to call the emulator from VM86 space. - * Look at emuint.h for definitions and a list of the currently defined - * subfunctions. - * To call emuint from VM86 space do: - * push ax Save original ax value (*must be done* !) - * mov ah, funcnum Emuint function number to ah - * mov al, subfunc Subfunction number, optional, depending on func - * int 0xff - * .. - * .. - * Emuint saves the function and subfunction numbers internally, then - * pops ax off the stack and calls the function handler with the original - * value in ax. - */ -void -emuint(regcontext_t *REGS) -{ - u_short func, subfunc; - - /* Remove function number from stack */ - func = R_AH; - subfunc = R_AL; - - R_AX = POP(REGS); - - /* Call the function handler, subfunction is ignored, if unused */ - switch (func) - { - /* The redirector call */ - case EMU_REDIR: - intff(REGS); - break; - - /* EMS call, used by emsdriv.sys */ - case EMU_EMS: - { - switch (subfunc) - { - case EMU_EMS_CTL: - R_AX = (u_short)ems_init(); - break; - - case EMU_EMS_CALL: - ems_entry(REGS); - break; - - default: - debug(D_ALWAYS, "Undefined subfunction for EMS call\n"); - break; - } - break; - } - - default: - debug(D_ALWAYS, "Emulator interrupt called with undefined function %02x\n", func); - - /* - * XXX - * temporary backwards compatibility with instbsdi.exe - * remove after a while. - */ - fprintf(stderr, "***\n*** WARNING - unknown emuint function\n"); - fprintf(stderr, "*** Continuing; assuming instbsdi redirector.\n"); - fprintf(stderr, "*** Please install the new redirector"); - fprintf(stderr, " `redir.com' as soon as possible.\n"); - fprintf(stderr, "*** This compatibility hack is not permanent.\n"); - fprintf(stderr, "***\n"); - PUSH(R_AX, REGS); - R_BX = R_ES; - R_DX = R_DI; - R_DI = R_DS; - intff(REGS); - break; - } -} diff --git a/usr.bin/doscmd/emuint.h b/usr.bin/doscmd/emuint.h deleted file mode 100644 index bd53981..0000000 --- a/usr.bin/doscmd/emuint.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 1997 Helmut Wirth <hfwirth@ping.at> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice immediately at the beginning of the file, witout modification, - * this list of conditions, and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - - -/* - * The emulator helper interrupt: - * - * Interrupt 0xFF is used by some emulator functions. It is a portal into - * the emulator and cannot be used by ordinary DOS applications directly - * The interrupt 0xFF is called by helper functions under DOS (such as - * the redirector interface and the EMS emulation). - * There are functions and subfunctions defined. (See emuint.c for details) - */ - -/* The redirector interface (formerly instbsdi.exe) */ -#define EMU_REDIR 0x1 /* Function for redirector interface */ -/* No subfunctions defined */ - -/* Expanded memory (EMS) driver callback */ -#define EMU_EMS 0x2 /* Function for EMS driver control */ -/* subfunctions for EMS */ -#define EMU_EMS_CTL 0x0 /* Control function, used during init */ -#define EMU_EMS_CALL 0x1 /* Callback, calls are routed via this */ diff --git a/usr.bin/doscmd/exe.c b/usr.bin/doscmd/exe.c deleted file mode 100644 index c219609..0000000 --- a/usr.bin/doscmd/exe.c +++ /dev/null @@ -1,421 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI exe.c,v 2.2 1996/04/08 19:32:34 bostic Exp - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/types.h> -#include <sys/uio.h> -#include <ctype.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> - -#include "doscmd.h" - -/* exports */ -int pspseg; -int curpsp = 0; - -/* locals */ -static int psp_s[10] = { 0 }; -static int env_s[10]; -static regcontext_t frames[10]; - -static int -make_environment(char *cmd_name, char **env) -{ - int i; - int total; - int len; - int envseg; - char *p; - char *env_block; - - total = 0; - for (i = 0; env[i]; i++) { - debug (D_EXEC,"env: %s\n", env[i]); - len = strlen(env[i]); - if (total + len >= 32 * 1024) - break; - total += len + 1; - } - - total++; /* terminating null */ - total += 2; /* word count */ - total += strlen(cmd_name) + 1; - total += 4; /* some more zeros, just in case */ - - if ((envseg = mem_alloc(total/16 + 1, 1, NULL)) == 0) - fatal("out of memory for env\n"); - - env_block = (char *)MAKEPTR(envseg, 0); - memset (env_block, 0, total); - - p = env_block; - total = 0; - for (i = 0; env[i]; i++) { - len = strlen(env[i]); - if (total + len >= 32 * 1024) - break; - total += len + 1; - strcpy (p, env[i]); - p += strlen(p) + 1; - } - *p++ = 0; - *(short *)p = strlen(cmd_name); - p += 2; - strcpy (p, cmd_name); - while(*p) { - if (*p == '/') - *p = '\\'; - else if (islower(*p)) - *p = toupper(*p); - p++; - } - *p = '\0'; - return(envseg); -} - -static void -load_com(int fd, int start_segment) -{ - char *start_addr; - int i; - - start_addr = (char *)MAKEPTR(start_segment, 0); - - lseek (fd, 0, 0); - i = read (fd, start_addr, 0xff00); - - debug(D_EXEC, "Read %05x into %04x\n", - i, start_segment); -} - -static void -load_exe(int fd, int start_segment, int reloc_segment __unused, struct exehdr *hdr, int text_size) -{ - char *start_addr; - int reloc_size; - struct reloc_entry *reloc_tbl, *rp; - u_short *segp; - int i; - - start_addr = (char *)MAKEPTR(start_segment, 0); - - lseek (fd, hdr->hdr_size * 16, 0); - if (read (fd, start_addr, text_size) != text_size) - fatal ("error reading program text\n"); - debug(D_EXEC, "Read %05x into %04x\n", - text_size, start_segment); - - if (hdr->nreloc) { - reloc_size = hdr->nreloc * sizeof (struct reloc_entry); - - if ((reloc_tbl = (struct reloc_entry *)malloc (reloc_size)) == NULL) - fatal ("out of memory for program\n"); - - lseek (fd, hdr->reloc_offset, 0); - if (read (fd, reloc_tbl, reloc_size) != reloc_size) - fatal ("error reading reloc table\n"); - - for (i = 0, rp = reloc_tbl; i < hdr->nreloc; i++, rp++) { - segp = (u_short *)MAKEPTR(start_segment + rp->seg, rp->off); - *segp += start_segment; - } - free((char *)reloc_tbl); - } -} - -void -load_command(regcontext_t *REGS, int run, int fd, char *cmd_name, - u_short *param, char **argv, char **envs) -{ - struct exehdr hdr; - int min_memory, max_memory; - int biggest; - int envseg; - char *psp; - int text_size; - int i; - int start_segment; - int exe_file; - char *p; - int used, n; - char *fcb; - int newpsp; - u_short init_cs, init_ip, init_ss, init_sp, init_ds, init_es; - - if (envs) - envseg = make_environment(cmd_name, envs); - else - envseg = env_s[curpsp]; - - /* read exe header */ - if (read (fd, &hdr, sizeof hdr) != sizeof hdr) - fatal ("can't read header\n"); - - /* proper header ? */ - if (hdr.magic == 0x5a4d) { - exe_file = 1; - text_size = (hdr.size - 1) * 512 + hdr.bytes_on_last_page - - hdr.hdr_size * 16; - min_memory = hdr.min_memory + (text_size + 15)/16; - max_memory = hdr.max_memory + (text_size + 15)/16; - } else { - exe_file = 0; - min_memory = 64 * (1024/16); - max_memory = 0xffff; - } - - /* alloc mem block */ - pspseg = mem_alloc(max_memory, 1, &biggest); - if (pspseg == 0) { - if (biggest < min_memory || - (pspseg = mem_alloc(biggest, 1, NULL)) == 0) - fatal("not enough memory: needed %d have %d\n", - min_memory, biggest); - - max_memory = biggest; - } - - mem_change_owner(pspseg, pspseg); - mem_change_owner(envseg, pspseg); - - /* create psp */ - newpsp = curpsp + 1; - psp_s[newpsp] = pspseg; - env_s[newpsp] = envseg; - - psp = (char *)MAKEPTR(pspseg, 0); - memset(psp, 0, 256); - - psp[0] = 0xcd; - psp[1] = 0x20; - - *(u_short *)&psp[2] = pspseg + max_memory; - - /* - * this is supposed to be a long call to dos ... try to fake it - */ - psp[5] = 0xcd; - psp[6] = 0x99; - psp[7] = 0xc3; - - *(u_short *)&psp[0x16] = psp_s[curpsp]; - psp[0x18] = 1; - psp[0x19] = 1; - psp[0x1a] = 1; - psp[0x1b] = 0; - psp[0x1c] = 2; - memset(psp + 0x1d, 0xff, 15); - - *(u_short *)&psp[0x2c] = envseg; - - *(u_short *)&psp[0x32] = 20; - *(u_long *)&psp[0x34] = MAKEVEC(pspseg, 0x18); - *(u_long *)&psp[0x38] = 0xffffffff; - - psp[0x50] = 0xcd; - psp[0x51] = 0x98; - psp[0x52] = 0xc3; - - p = psp + 0x81; - *p = 0; - used = 0; - for (i = 0; argv[i]; i++) { - n = strlen(argv[i]); - if (used + 1 + n > 0x7d) - break; - *p++ = ' '; - memcpy(p, argv[i], n); - p += n; - used += n; - } - - psp[0x80] = strlen(psp + 0x81); - psp[0x81 + psp[0x80]] = 0x0d; - psp[0x82 + psp[0x80]] = 0; - - p = psp + 0x81; - parse_filename(0x00, p, psp + 0x5c, &n); - p += n; - parse_filename(0x00, p, psp + 0x6c, &n); - - if (param[4]) { - fcb = (char *)MAKEPTR(param[4], param[3]); - memcpy(psp + 0x5c, fcb, 16); - } - if (param[6]) { - fcb = (char *)MAKEPTR(param[6], param[5]); - memcpy(psp + 0x6c, fcb, 16); - } - -#if 0 - printf("005c:"); - for (n = 0; n < 16; n++) - printf(" %02x", psp[0x5c + n]); - printf("\n"); - printf("006c:"); - for (n = 0; n < 16; n++) - printf(" %02x", psp[0x6c + n]); - printf("\n"); -#endif - - disk_transfer_addr = MAKEVEC(pspseg, 0x80); - - start_segment = pspseg + 0x10; - - if (!exe_file) { - load_com(fd, start_segment); - - init_cs = pspseg; - init_ip = 0x100; - init_ss = init_cs; - init_sp = 0xfffe; - init_ds = init_cs; - init_es = init_cs; - } else { - load_exe(fd, start_segment, start_segment, &hdr, text_size); - - init_cs = hdr.init_cs + start_segment; - init_ip = hdr.init_ip; - init_ss = hdr.init_ss + start_segment; - init_sp = hdr.init_sp; - init_ds = pspseg; - init_es = init_ds; - } - - debug(D_EXEC, "cs:ip = %04x:%04x, ss:sp = %04x:%04x, " - "ds = %04x, es = %04x\n", - init_cs, init_ip, init_ss, init_sp, init_ds, init_es); - - if (run) { - frames[newpsp] = *REGS; - curpsp = newpsp; - - R_EFLAGS = 0x20202; - R_CS = init_cs; - R_IP = init_ip; - R_SS = init_ss; - R_SP = init_sp; - R_DS = init_ds; - R_ES = init_es; - - R_AX = R_BX = R_CX = R_DX = R_SI = R_DI = R_BP = 0; - - } else { - param[7] = init_sp; - param[8] = init_ss; - param[9] = init_ip; - param[10] = init_cs; - } -} - -void -load_overlay(int fd, int start_segment, int reloc_segment) -{ - struct exehdr hdr; - int text_size; - int exe_file; - - /* read exe header */ - if (read (fd, &hdr, sizeof hdr) != sizeof hdr) - fatal ("can't read header\n"); - - /* proper header ? */ - if (hdr.magic == 0x5a4d) { - exe_file = 1; - text_size = (hdr.size - 1) * 512 + hdr.bytes_on_last_page - - hdr.hdr_size * 16; - } else { - exe_file = 0; - } - - if (!exe_file) - load_com(fd, start_segment); - else - load_exe(fd, start_segment, reloc_segment, &hdr, text_size); -} - -int -get_env(void) -{ - return(env_s[curpsp]); -} - -void -exec_command(regcontext_t *REGS, int run, - int fd, char *cmd_name, u_short *param) -{ - char *arg; - char *env; - char *argv[2]; - char *envs[100]; - - env = (char *)MAKEPTR(param[0], 0); - arg = (char *)MAKEPTR(param[2], param[1]); - - if (arg) { - int nbytes = *arg++; - arg[nbytes] = 0; - if (!*arg) - arg = NULL; - } - argv[0] = arg; - argv[1] = NULL; - - debug (D_EXEC, "exec_command: cmd_name = %s\n" - "env = 0x0%x, arg = %04x:%04x(%s)\n", - cmd_name, param[0], param[2], param[1], arg); - - if (env) { - int i; - for ( i=0; i < 99 && *env; ++i ) { - envs[i] = env; - env += strlen(env)+1; - } - envs[i] = NULL; - load_command(REGS, run, fd, cmd_name, param, argv, envs); - } else - load_command(REGS, run, fd, cmd_name, param, argv, NULL); -} - -void -exec_return(regcontext_t *REGS, int code) -{ - debug(D_EXEC, "Returning from exec\n"); - mem_free_owner(psp_s[curpsp]); - *REGS = frames[curpsp--]; - R_AX = code; - R_FLAGS &= ~PSL_C; /* It must have worked */ -} diff --git a/usr.bin/doscmd/fonts.dir b/usr.bin/doscmd/fonts.dir deleted file mode 100644 index 32afa98..0000000 --- a/usr.bin/doscmd/fonts.dir +++ /dev/null @@ -1,4 +0,0 @@ -3 -cp437-8x8.pcf.gz vga8x8 -cp437-8x14.pcf.gz vga8x14 -cp437-8x16.pcf.gz vga8x16 diff --git a/usr.bin/doscmd/i386-pinsn.c b/usr.bin/doscmd/i386-pinsn.c deleted file mode 100644 index f36c479..0000000 --- a/usr.bin/doscmd/i386-pinsn.c +++ /dev/null @@ -1,1962 +0,0 @@ -#ifdef DISASSEMBLER - -/* Print i386 instructions for GDB, the GNU debugger. - Copyright (C) 1988, 1989 Free Software Foundation, Inc. - -This file is part of GDB. - -GDB is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 1, or (at your option) -any later version. - -GDB is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GDB; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* - * 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu) - * July 1988 - */ - -/* - * The main tables describing the instructions is essentially a copy - * of the "Opcode Map" chapter (Appendix A) of the Intel 80386 - * Programmers Manual. Usually, there is a capital letter, followed - * by a small letter. The capital letter tell the addressing mode, - * and the small letter tells about the operand size. Refer to - * the Intel manual for details. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <stdio.h> -#include <ctype.h> - -#include "doscmd.h" - -static void OP_E(int), OP_indirE(int), OP_G(int); -static void OP_I(int), OP_sI(int), OP_REG(int), OP_J(int), OP_SEG(int); -static void OP_DIR(int), OP_OFF(int), OP_DSSI(int), OP_ESDI(int); -static void OP_C(int), OP_D(int), OP_T(int), OP_rm(int); -static void OP_ST(int), OP_STi(int); -static void append_pc(unsigned long); -static void append_prefix(void); -static void dofloat(void); -static int get16(void); -static int get32(void); -static void oappend(const char *); -static void putop(const char *); - -#define Eb OP_E, b_mode -#define indirEb OP_indirE, b_mode -#define Gb OP_G, b_mode -#define Ev OP_E, v_mode -#define indirEv OP_indirE, v_mode -#define Ew OP_E, w_mode -#define Ma OP_E, v_mode -#define M OP_E, 0 -#define Mp OP_E, 0 /* ? */ -#define Gv OP_G, v_mode -#define Gw OP_G, w_mode -#define Rw OP_rm, w_mode -#define Rd OP_rm, d_mode -#define Ib OP_I, b_mode -#define sIb OP_sI, b_mode /* sign extended byte */ -#define Iv OP_I, v_mode -#define Iw OP_I, w_mode -#define Jb OP_J, b_mode -#define Jv OP_J, v_mode -#define Cd OP_C, d_mode -#define Dd OP_D, d_mode -#define Td OP_T, d_mode - -#define eAX OP_REG, eAX_reg -#define eBX OP_REG, eBX_reg -#define eCX OP_REG, eCX_reg -#define eDX OP_REG, eDX_reg -#define eSP OP_REG, eSP_reg -#define eBP OP_REG, eBP_reg -#define eSI OP_REG, eSI_reg -#define eDI OP_REG, eDI_reg -#define AL OP_REG, al_reg -#define CL OP_REG, cl_reg -#define DL OP_REG, dl_reg -#define BL OP_REG, bl_reg -#define AH OP_REG, ah_reg -#define CH OP_REG, ch_reg -#define DH OP_REG, dh_reg -#define BH OP_REG, bh_reg -#define AX OP_REG, ax_reg -#define DX OP_REG, dx_reg -#define indirDX OP_REG, indir_dx_reg - -#define Sw OP_SEG, w_mode -#define Ap OP_DIR, lptr -#define Av OP_DIR, v_mode -#define Ob OP_OFF, b_mode -#define Ov OP_OFF, v_mode -#define Xb OP_DSSI, b_mode -#define Xv OP_DSSI, v_mode -#define Yb OP_ESDI, b_mode -#define Yv OP_ESDI, v_mode - -#define es OP_REG, es_reg -#define ss OP_REG, ss_reg -#define cs OP_REG, cs_reg -#define ds OP_REG, ds_reg -#define fs OP_REG, fs_reg -#define gs OP_REG, gs_reg - -#define b_mode 1 -#define v_mode 2 -#define w_mode 3 -#define d_mode 4 - -#define es_reg 100 -#define cs_reg 101 -#define ss_reg 102 -#define ds_reg 103 -#define fs_reg 104 -#define gs_reg 105 -#define eAX_reg 107 -#define eCX_reg 108 -#define eDX_reg 109 -#define eBX_reg 110 -#define eSP_reg 111 -#define eBP_reg 112 -#define eSI_reg 113 -#define eDI_reg 114 - -#define lptr 115 - -#define al_reg 116 -#define cl_reg 117 -#define dl_reg 118 -#define bl_reg 119 -#define ah_reg 120 -#define ch_reg 121 -#define dh_reg 122 -#define bh_reg 123 - -#define ax_reg 124 -#define cx_reg 125 -#define dx_reg 126 -#define bx_reg 127 -#define sp_reg 128 -#define bp_reg 129 -#define si_reg 130 -#define di_reg 131 - -#define indir_dx_reg 150 - -#define NOFUNC NULL, 0 - -#define GRP1b NULL, NULL, 0, NOFUNC, NOFUNC -#define GRP1S NULL, NULL, 1, NOFUNC, NOFUNC -#define GRP1Ss NULL, NULL, 2, NOFUNC, NOFUNC -#define GRP2b NULL, NULL, 3, NOFUNC, NOFUNC -#define GRP2S NULL, NULL, 4, NOFUNC, NOFUNC -#define GRP2b_one NULL, NULL, 5, NOFUNC, NOFUNC -#define GRP2S_one NULL, NULL, 6, NOFUNC, NOFUNC -#define GRP2b_cl NULL, NULL, 7, NOFUNC, NOFUNC -#define GRP2S_cl NULL, NULL, 8, NOFUNC, NOFUNC -#define GRP3b NULL, NULL, 9, NOFUNC, NOFUNC -#define GRP3S NULL, NULL, 10, NOFUNC, NOFUNC -#define GRP4 NULL, NULL, 11, NOFUNC, NOFUNC -#define GRP5 NULL, NULL, 12, NOFUNC, NOFUNC -#define GRP6 NULL, NULL, 13, NOFUNC, NOFUNC -#define GRP7 NULL, NULL, 14, NOFUNC, NOFUNC -#define GRP8 NULL, NULL, 15, NOFUNC, NOFUNC - -#define FLOATCODE 50 -#define FLOAT NULL, NULL, FLOATCODE, NOFUNC, NOFUNC - -struct dis386 { - const char *name; - void (*op1)(int); - int bytemode1; - void (*op2)(int); - int bytemode2; - void (*op3)(int); - int bytemode3; -}; - -struct dis386 dis386[] = { - /* 00 */ - { "addb", Eb, Gb, NOFUNC }, - { "addS", Ev, Gv, NOFUNC }, - { "addb", Gb, Eb, NOFUNC }, - { "addS", Gv, Ev, NOFUNC }, - { "addb", AL, Ib, NOFUNC }, - { "addS", eAX, Iv, NOFUNC }, - { "pushl", es, NOFUNC, NOFUNC }, - { "popl", es, NOFUNC, NOFUNC }, - /* 08 */ - { "orb", Eb, Gb, NOFUNC }, - { "orS", Ev, Gv, NOFUNC }, - { "orb", Gb, Eb, NOFUNC }, - { "orS", Gv, Ev, NOFUNC }, - { "orb", AL, Ib, NOFUNC }, - { "orS", eAX, Iv, NOFUNC }, - { "pushl", cs, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, /* extended opcode escape */ - /* 10 */ - { "adcb", Eb, Gb, NOFUNC }, - { "adcS", Ev, Gv, NOFUNC }, - { "adcb", Gb, Eb, NOFUNC }, - { "adcS", Gv, Ev, NOFUNC }, - { "adcb", AL, Ib, NOFUNC }, - { "adcS", eAX, Iv, NOFUNC }, - { "pushl", ss, NOFUNC, NOFUNC }, - { "popl", ss, NOFUNC, NOFUNC }, - /* 18 */ - { "sbbb", Eb, Gb, NOFUNC }, - { "sbbS", Ev, Gv, NOFUNC }, - { "sbbb", Gb, Eb, NOFUNC }, - { "sbbS", Gv, Ev, NOFUNC }, - { "sbbb", AL, Ib, NOFUNC }, - { "sbbS", eAX, Iv, NOFUNC }, - { "pushl", ds, NOFUNC, NOFUNC }, - { "popl", ds, NOFUNC, NOFUNC }, - /* 20 */ - { "andb", Eb, Gb, NOFUNC }, - { "andS", Ev, Gv, NOFUNC }, - { "andb", Gb, Eb, NOFUNC }, - { "andS", Gv, Ev, NOFUNC }, - { "andb", AL, Ib, NOFUNC }, - { "andS", eAX, Iv, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC}, /* SEG ES prefix */ - { "daa", NOFUNC, NOFUNC, NOFUNC }, - /* 28 */ - { "subb", Eb, Gb, NOFUNC }, - { "subS", Ev, Gv, NOFUNC }, - { "subb", Gb, Eb, NOFUNC }, - { "subS", Gv, Ev, NOFUNC }, - { "subb", AL, Ib, NOFUNC }, - { "subS", eAX, Iv, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, /* SEG CS prefix */ - { "das", NOFUNC, NOFUNC, NOFUNC }, - /* 30 */ - { "xorb", Eb, Gb, NOFUNC }, - { "xorS", Ev, Gv, NOFUNC }, - { "xorb", Gb, Eb, NOFUNC }, - { "xorS", Gv, Ev, NOFUNC }, - { "xorb", AL, Ib, NOFUNC }, - { "xorS", eAX, Iv, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, /* SEG SS prefix */ - { "aaa", NOFUNC, NOFUNC, NOFUNC }, - /* 38 */ - { "cmpb", Eb, Gb, NOFUNC }, - { "cmpS", Ev, Gv, NOFUNC }, - { "cmpb", Gb, Eb, NOFUNC }, - { "cmpS", Gv, Ev, NOFUNC }, - { "cmpb", AL, Ib, NOFUNC }, - { "cmpS", eAX, Iv, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, /* SEG DS prefix */ - { "aas", NOFUNC, NOFUNC, NOFUNC }, - /* 40 */ - { "incS", eAX, NOFUNC, NOFUNC }, - { "incS", eCX, NOFUNC, NOFUNC }, - { "incS", eDX, NOFUNC, NOFUNC }, - { "incS", eBX, NOFUNC, NOFUNC }, - { "incS", eSP, NOFUNC, NOFUNC }, - { "incS", eBP, NOFUNC, NOFUNC }, - { "incS", eSI, NOFUNC, NOFUNC }, - { "incS", eDI, NOFUNC, NOFUNC }, - /* 48 */ - { "decS", eAX, NOFUNC, NOFUNC }, - { "decS", eCX, NOFUNC, NOFUNC }, - { "decS", eDX, NOFUNC, NOFUNC }, - { "decS", eBX, NOFUNC, NOFUNC }, - { "decS", eSP, NOFUNC, NOFUNC }, - { "decS", eBP, NOFUNC, NOFUNC }, - { "decS", eSI, NOFUNC, NOFUNC }, - { "decS", eDI, NOFUNC, NOFUNC }, - /* 50 */ - { "pushS", eAX, NOFUNC, NOFUNC }, - { "pushS", eCX, NOFUNC, NOFUNC }, - { "pushS", eDX, NOFUNC, NOFUNC }, - { "pushS", eBX, NOFUNC, NOFUNC }, - { "pushS", eSP, NOFUNC, NOFUNC }, - { "pushS", eBP, NOFUNC, NOFUNC }, - { "pushS", eSI, NOFUNC, NOFUNC }, - { "pushS", eDI, NOFUNC, NOFUNC }, - /* 58 */ - { "popS", eAX, NOFUNC, NOFUNC }, - { "popS", eCX, NOFUNC, NOFUNC }, - { "popS", eDX, NOFUNC, NOFUNC }, - { "popS", eBX, NOFUNC, NOFUNC }, - { "popS", eSP, NOFUNC, NOFUNC }, - { "popS", eBP, NOFUNC, NOFUNC }, - { "popS", eSI, NOFUNC, NOFUNC }, - { "popS", eDI, NOFUNC, NOFUNC }, - /* 60 */ - { "pusha", NOFUNC, NOFUNC, NOFUNC }, - { "popa", NOFUNC, NOFUNC, NOFUNC }, - { "boundS", Gv, Ma, NOFUNC }, - { "arpl", Ew, Gw, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, /* seg fs */ - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, /* seg gs */ - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, /* op size prefix */ - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, /* adr size prefix */ - /* 68 */ - { "pushS", Iv, NOFUNC, NOFUNC }, /* 386 book wrong */ - { "imulS", Gv, Ev, Iv }, - { "pushl", sIb, NOFUNC, NOFUNC }, /* push of byte really pushes 4 bytes */ - { "imulS", Gv, Ev, Ib }, - { "insb", Yb, indirDX, NOFUNC }, - { "insS", Yv, indirDX, NOFUNC }, - { "outsb", indirDX, Xb, NOFUNC }, - { "outsS", indirDX, Xv, NOFUNC }, - /* 70 */ - { "jo", Jb, NOFUNC, NOFUNC }, - { "jno", Jb, NOFUNC, NOFUNC }, - { "jb", Jb, NOFUNC, NOFUNC }, - { "jae", Jb, NOFUNC, NOFUNC }, - { "je", Jb, NOFUNC, NOFUNC }, - { "jne", Jb, NOFUNC, NOFUNC }, - { "jbe", Jb, NOFUNC, NOFUNC }, - { "ja", Jb, NOFUNC, NOFUNC }, - /* 78 */ - { "js", Jb, NOFUNC, NOFUNC }, - { "jns", Jb, NOFUNC, NOFUNC }, - { "jp", Jb, NOFUNC, NOFUNC }, - { "jnp", Jb, NOFUNC, NOFUNC }, - { "jl", Jb, NOFUNC, NOFUNC }, - { "jnl", Jb, NOFUNC, NOFUNC }, - { "jle", Jb, NOFUNC, NOFUNC }, - { "jg", Jb, NOFUNC, NOFUNC }, - /* 80 */ - { GRP1b }, - { GRP1S }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { GRP1Ss }, - { "testb", Eb, Gb, NOFUNC }, - { "testS", Ev, Gv, NOFUNC }, - { "xchgb", Eb, Gb, NOFUNC }, - { "xchgS", Ev, Gv, NOFUNC }, - /* 88 */ - { "movb", Eb, Gb, NOFUNC }, - { "movS", Ev, Gv, NOFUNC }, - { "movb", Gb, Eb, NOFUNC }, - { "movS", Gv, Ev, NOFUNC }, - { "movw", Ew, Sw, NOFUNC }, - { "leaS", Gv, M, NOFUNC }, - { "movw", Sw, Ew, NOFUNC }, - { "popS", Ev, NOFUNC, NOFUNC }, - /* 90 */ - { "nop", NOFUNC, NOFUNC, NOFUNC }, - { "xchgS", eCX, eAX, NOFUNC }, - { "xchgS", eDX, eAX, NOFUNC }, - { "xchgS", eBX, eAX, NOFUNC }, - { "xchgS", eSP, eAX, NOFUNC }, - { "xchgS", eBP, eAX, NOFUNC }, - { "xchgS", eSI, eAX, NOFUNC }, - { "xchgS", eDI, eAX, NOFUNC }, - /* 98 */ - { "cwtl", NOFUNC, NOFUNC, NOFUNC }, - { "cltd", NOFUNC, NOFUNC, NOFUNC }, - { "lcall", Ap, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, /* fwait */ - { "pushf", NOFUNC, NOFUNC, NOFUNC }, - { "popf", NOFUNC, NOFUNC, NOFUNC }, - { "sahf", NOFUNC, NOFUNC, NOFUNC }, - { "lahf", NOFUNC, NOFUNC, NOFUNC }, - /* a0 */ - { "movb", AL, Ob, NOFUNC }, - { "movS", eAX, Ov, NOFUNC }, - { "movb", Ob, AL, NOFUNC }, - { "movS", Ov, eAX, NOFUNC }, - { "movsb", Yb, Xb, NOFUNC }, - { "movsS", Yv, Xv, NOFUNC }, - { "cmpsb", Xb, Yb, NOFUNC }, - { "cmpsS", Xv, Yv, NOFUNC }, - /* a8 */ - { "testb", AL, Ib, NOFUNC }, - { "testS", eAX, Iv, NOFUNC }, - { "stosb", Yb, AL, NOFUNC }, - { "stosS", Yv, eAX, NOFUNC }, - { "lodsb", AL, Xb, NOFUNC }, - { "lodsS", eAX, Xv, NOFUNC }, - { "scasb", AL, Yb, NOFUNC }, - { "scasS", eAX, Yv, NOFUNC }, - /* b0 */ - { "movb", AL, Ib, NOFUNC }, - { "movb", CL, Ib, NOFUNC }, - { "movb", DL, Ib, NOFUNC }, - { "movb", BL, Ib, NOFUNC }, - { "movb", AH, Ib, NOFUNC }, - { "movb", CH, Ib, NOFUNC }, - { "movb", DH, Ib, NOFUNC }, - { "movb", BH, Ib, NOFUNC }, - /* b8 */ - { "movS", eAX, Iv, NOFUNC }, - { "movS", eCX, Iv, NOFUNC }, - { "movS", eDX, Iv, NOFUNC }, - { "movS", eBX, Iv, NOFUNC }, - { "movS", eSP, Iv, NOFUNC }, - { "movS", eBP, Iv, NOFUNC }, - { "movS", eSI, Iv, NOFUNC }, - { "movS", eDI, Iv, NOFUNC }, - /* c0 */ - { GRP2b }, - { GRP2S }, - { "ret", Iw, NOFUNC, NOFUNC }, - { "ret", NOFUNC, NOFUNC, NOFUNC }, - { "lesS", Gv, Mp, NOFUNC }, - { "ldsS", Gv, Mp, NOFUNC }, - { "movb", Eb, Ib, NOFUNC }, - { "movS", Ev, Iv, NOFUNC }, - /* c8 */ - { "enter", Iw, Ib, NOFUNC }, - { "leave", NOFUNC, NOFUNC, NOFUNC }, - { "lret", Iw, NOFUNC, NOFUNC }, - { "lret", NOFUNC, NOFUNC, NOFUNC }, - { "int3", NOFUNC, NOFUNC, NOFUNC }, - { "int", Ib, NOFUNC, NOFUNC }, - { "into", NOFUNC, NOFUNC, NOFUNC }, - { "iret", NOFUNC, NOFUNC, NOFUNC }, - /* d0 */ - { GRP2b_one }, - { GRP2S_one }, - { GRP2b_cl }, - { GRP2S_cl }, - { "aam", Ib, NOFUNC, NOFUNC }, - { "aad", Ib, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "xlat", NOFUNC, NOFUNC, NOFUNC }, - /* d8 */ - { FLOAT }, - { FLOAT }, - { FLOAT }, - { FLOAT }, - { FLOAT }, - { FLOAT }, - { FLOAT }, - { FLOAT }, - /* e0 */ - { "loopne", Jb, NOFUNC, NOFUNC }, - { "loope", Jb, NOFUNC, NOFUNC }, - { "loop", Jb, NOFUNC, NOFUNC }, - { "jCcxz", Jb, NOFUNC, NOFUNC }, - { "inb", AL, Ib, NOFUNC }, - { "inS", eAX, Ib, NOFUNC }, - { "outb", Ib, AL, NOFUNC }, - { "outS", Ib, eAX, NOFUNC }, - /* e8 */ - { "call", Av, NOFUNC, NOFUNC }, - { "jmp", Jv, NOFUNC, NOFUNC }, - { "ljmp", Ap, NOFUNC, NOFUNC }, - { "jmp", Jb, NOFUNC, NOFUNC }, - { "inb", AL, indirDX, NOFUNC }, - { "inS", eAX, indirDX, NOFUNC }, - { "outb", indirDX, AL, NOFUNC }, - { "outS", indirDX, eAX, NOFUNC }, - /* f0 */ - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, /* lock prefix */ - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, /* repne */ - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, /* repz */ - { "hlt", NOFUNC, NOFUNC, NOFUNC }, - { "cmc", NOFUNC, NOFUNC, NOFUNC }, - { GRP3b }, - { GRP3S }, - /* f8 */ - { "clc", NOFUNC, NOFUNC, NOFUNC }, - { "stc", NOFUNC, NOFUNC, NOFUNC }, - { "cli", NOFUNC, NOFUNC, NOFUNC }, - { "sti", NOFUNC, NOFUNC, NOFUNC }, - { "cld", NOFUNC, NOFUNC, NOFUNC }, - { "std", NOFUNC, NOFUNC, NOFUNC }, - { GRP4 }, - { GRP5 }, -}; - -struct dis386 dis386_twobyte[] = { - /* 00 */ - { GRP6 }, - { GRP7 }, - { "larS", Gv, Ew, NOFUNC }, - { "lslS", Gv, Ew, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "clts", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - /* 08 */ - { "invd", NOFUNC, NOFUNC, NOFUNC }, - { "wbinvd", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - /* 10 */ - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - /* 18 */ - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - /* 20 */ - /* these are all backward in appendix A of the intel book */ - { "movl", Rd, Cd, NOFUNC }, - { "movl", Rd, Dd, NOFUNC }, - { "movl", Cd, Rd, NOFUNC }, - { "movl", Dd, Rd, NOFUNC }, - { "movl", Rd, Td, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "movl", Td, Rd, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - /* 28 */ - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - /* 30 */ - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - /* 38 */ - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - /* 40 */ - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - /* 48 */ - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - /* 50 */ - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - /* 58 */ - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - /* 60 */ - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - /* 68 */ - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - /* 70 */ - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - /* 78 */ - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - /* 80 */ - { "jo", Jv, NOFUNC, NOFUNC }, - { "jno", Jv, NOFUNC, NOFUNC }, - { "jb", Jv, NOFUNC, NOFUNC }, - { "jae", Jv, NOFUNC, NOFUNC }, - { "je", Jv, NOFUNC, NOFUNC }, - { "jne", Jv, NOFUNC, NOFUNC }, - { "jbe", Jv, NOFUNC, NOFUNC }, - { "ja", Jv, NOFUNC, NOFUNC }, - /* 88 */ - { "js", Jv, NOFUNC, NOFUNC }, - { "jns", Jv, NOFUNC, NOFUNC }, - { "jp", Jv, NOFUNC, NOFUNC }, - { "jnp", Jv, NOFUNC, NOFUNC }, - { "jl", Jv, NOFUNC, NOFUNC }, - { "jge", Jv, NOFUNC, NOFUNC }, - { "jle", Jv, NOFUNC, NOFUNC }, - { "jg", Jv, NOFUNC, NOFUNC }, - /* 90 */ - { "seto", Eb, NOFUNC, NOFUNC }, - { "setno", Eb, NOFUNC, NOFUNC }, - { "setb", Eb, NOFUNC, NOFUNC }, - { "setae", Eb, NOFUNC, NOFUNC }, - { "sete", Eb, NOFUNC, NOFUNC }, - { "setne", Eb, NOFUNC, NOFUNC }, - { "setbe", Eb, NOFUNC, NOFUNC }, - { "seta", Eb, NOFUNC, NOFUNC }, - /* 98 */ - { "sets", Eb, NOFUNC, NOFUNC }, - { "setns", Eb, NOFUNC, NOFUNC }, - { "setp", Eb, NOFUNC, NOFUNC }, - { "setnp", Eb, NOFUNC, NOFUNC }, - { "setl", Eb, NOFUNC, NOFUNC }, - { "setge", Eb, NOFUNC, NOFUNC }, - { "setle", Eb, NOFUNC, NOFUNC }, - { "setg", Eb, NOFUNC, NOFUNC }, - /* a0 */ - { "pushl", fs, NOFUNC, NOFUNC }, - { "popl", fs, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "btS", Ev, Gv, NOFUNC }, - { "shldS", Ev, Gv, Ib }, - { "shldS", Ev, Gv, CL }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - /* a8 */ - { "pushl", gs, NOFUNC, NOFUNC }, - { "popl", gs, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "btsS", Ev, Gv, NOFUNC }, - { "shrdS", Ev, Gv, Ib }, - { "shrdS", Ev, Gv, CL }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "imulS", Gv, Ev, NOFUNC }, - /* b0 */ - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "lssS", Gv, Mp, NOFUNC }, /* 386 lists only Mp */ - { "btrS", Ev, Gv, NOFUNC }, - { "lfsS", Gv, Mp, NOFUNC }, /* 386 lists only Mp */ - { "lgsS", Gv, Mp, NOFUNC }, /* 386 lists only Mp */ - { "movzbS", Gv, Eb, NOFUNC }, - { "movzwS", Gv, Ew, NOFUNC }, - /* b8 */ - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { GRP8 }, - { "btcS", Ev, Gv, NOFUNC }, - { "bsfS", Gv, Ev, NOFUNC }, - { "bsrS", Gv, Ev, NOFUNC }, - { "movsbS", Gv, Eb, NOFUNC }, - { "movswS", Gv, Ew, NOFUNC }, - /* c0 */ - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - /* c8 */ - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - /* d0 */ - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - /* d8 */ - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - /* e0 */ - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - /* e8 */ - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - /* f0 */ - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - /* f8 */ - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, -}; - -static char obuf[100]; -static char *obufp; -static char scratchbuf[100]; -static unsigned char *start_codep; -static unsigned char *codep; -static int mod; -static int rm; -static int reg; - -static const char *names32[]={ - "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi", -}; -static const char *names16[] = { - "%ax","%cx","%dx","%bx","%sp","%bp","%si","%di", -}; -static const char *names8[] = { - "%al","%cl","%dl","%bl","%ah","%ch","%dh","%bh", -}; -static const char *names_seg[] = { - "%es","%cs","%ss","%ds","%fs","%gs","%?","%?", -}; -static const char *names16_pairs[] = { - "%bx+%si","%bx+%di","%bp+%si","%bp+%di","%si","%di","%bp","%bx", -}; - -struct dis386 grps[][8] = { - /* GRP1b */ - { - { "addb", Eb, Ib, NOFUNC }, - { "orb", Eb, Ib, NOFUNC }, - { "adcb", Eb, Ib, NOFUNC }, - { "sbbb", Eb, Ib, NOFUNC }, - { "andb", Eb, Ib, NOFUNC }, - { "subb", Eb, Ib, NOFUNC }, - { "xorb", Eb, Ib, NOFUNC }, - { "cmpb", Eb, Ib, NOFUNC } - }, - /* GRP1S */ - { - { "addS", Ev, Iv, NOFUNC }, - { "orS", Ev, Iv, NOFUNC }, - { "adcS", Ev, Iv, NOFUNC }, - { "sbbS", Ev, Iv, NOFUNC }, - { "andS", Ev, Iv, NOFUNC }, - { "subS", Ev, Iv, NOFUNC }, - { "xorS", Ev, Iv, NOFUNC }, - { "cmpS", Ev, Iv, NOFUNC } - }, - /* GRP1Ss */ - { - { "addS", Ev, sIb, NOFUNC }, - { "orS", Ev, sIb, NOFUNC }, - { "adcS", Ev, sIb, NOFUNC }, - { "sbbS", Ev, sIb, NOFUNC }, - { "andS", Ev, sIb, NOFUNC }, - { "subS", Ev, sIb, NOFUNC }, - { "xorS", Ev, sIb, NOFUNC }, - { "cmpS", Ev, sIb, NOFUNC } - }, - /* GRP2b */ - { - { "rolb", Eb, Ib, NOFUNC }, - { "rorb", Eb, Ib, NOFUNC }, - { "rclb", Eb, Ib, NOFUNC }, - { "rcrb", Eb, Ib, NOFUNC }, - { "shlb", Eb, Ib, NOFUNC }, - { "shrb", Eb, Ib, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "sarb", Eb, Ib, NOFUNC }, - }, - /* GRP2S */ - { - { "rolS", Ev, Ib, NOFUNC }, - { "rorS", Ev, Ib, NOFUNC }, - { "rclS", Ev, Ib, NOFUNC }, - { "rcrS", Ev, Ib, NOFUNC }, - { "shlS", Ev, Ib, NOFUNC }, - { "shrS", Ev, Ib, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "sarS", Ev, Ib, NOFUNC }, - }, - /* GRP2b_one */ - { - { "rolb", Eb, NOFUNC, NOFUNC }, - { "rorb", Eb, NOFUNC, NOFUNC }, - { "rclb", Eb, NOFUNC, NOFUNC }, - { "rcrb", Eb, NOFUNC, NOFUNC }, - { "shlb", Eb, NOFUNC, NOFUNC }, - { "shrb", Eb, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "sarb", Eb, NOFUNC, NOFUNC }, - }, - /* GRP2S_one */ - { - { "rolS", Ev, NOFUNC, NOFUNC }, - { "rorS", Ev, NOFUNC, NOFUNC }, - { "rclS", Ev, NOFUNC, NOFUNC }, - { "rcrS", Ev, NOFUNC, NOFUNC }, - { "shlS", Ev, NOFUNC, NOFUNC }, - { "shrS", Ev, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "sarS", Ev, NOFUNC, NOFUNC }, - }, - /* GRP2b_cl */ - { - { "rolb", Eb, CL, NOFUNC }, - { "rorb", Eb, CL, NOFUNC }, - { "rclb", Eb, CL, NOFUNC }, - { "rcrb", Eb, CL, NOFUNC }, - { "shlb", Eb, CL, NOFUNC }, - { "shrb", Eb, CL, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "sarb", Eb, CL, NOFUNC }, - }, - /* GRP2S_cl */ - { - { "rolS", Ev, CL, NOFUNC }, - { "rorS", Ev, CL, NOFUNC }, - { "rclS", Ev, CL, NOFUNC }, - { "rcrS", Ev, CL, NOFUNC }, - { "shlS", Ev, CL, NOFUNC }, - { "shrS", Ev, CL, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "sarS", Ev, CL, NOFUNC } - }, - /* GRP3b */ - { - { "testb", Eb, Ib, NOFUNC }, - { "(bad)", Eb, NOFUNC, NOFUNC }, - { "notb", Eb, NOFUNC, NOFUNC }, - { "negb", Eb, NOFUNC, NOFUNC }, - { "mulb", AL, Eb, NOFUNC }, - { "imulb", AL, Eb, NOFUNC }, - { "divb", AL, Eb, NOFUNC }, - { "idivb", AL, Eb, NOFUNC } - }, - /* GRP3S */ - { - { "testS", Ev, Iv, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "notS", Ev, NOFUNC, NOFUNC }, - { "negS", Ev, NOFUNC, NOFUNC }, - { "mulS", eAX, Ev, NOFUNC }, - { "imulS", eAX, Ev, NOFUNC }, - { "divS", eAX, Ev, NOFUNC }, - { "idivS", eAX, Ev, NOFUNC }, - }, - /* GRP4 */ - { - { "incb", Eb, NOFUNC, NOFUNC }, - { "decb", Eb, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - }, - /* GRP5 */ - { - { "incS", Ev, NOFUNC, NOFUNC }, - { "decS", Ev, NOFUNC, NOFUNC }, - { "call", indirEv, NOFUNC, NOFUNC }, - { "lcall", indirEv, NOFUNC, NOFUNC }, - { "jmp", indirEv, NOFUNC, NOFUNC }, - { "ljmp", indirEv, NOFUNC, NOFUNC }, - { "pushS", Ev, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - }, - /* GRP6 */ - { - { "sldt", Ew, NOFUNC, NOFUNC }, - { "str", Ew, NOFUNC, NOFUNC }, - { "lldt", Ew, NOFUNC, NOFUNC }, - { "ltr", Ew, NOFUNC, NOFUNC }, - { "verr", Ew, NOFUNC, NOFUNC }, - { "verw", Ew, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC } - }, - /* GRP7 */ - { - { "sgdt", Ew, NOFUNC, NOFUNC }, - { "sidt", Ew, NOFUNC, NOFUNC }, - { "lgdt", Ew, NOFUNC, NOFUNC }, - { "lidt", Ew, NOFUNC, NOFUNC }, - { "smsw", Ew, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "lmsw", Ew, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - }, - /* GRP8 */ - { - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "btS", Ev, Ib, NOFUNC }, - { "btsS", Ev, Ib, NOFUNC }, - { "btrS", Ev, Ib, NOFUNC }, - { "btcS", Ev, Ib, NOFUNC }, - } -}; - -#define PREFIX_REPZ 0x01 -#define PREFIX_REPNZ 0x02 -#define PREFIX_LOCK 0x04 -#define PREFIX_CS 0x08 -#define PREFIX_SS 0x10 -#define PREFIX_DS 0x20 -#define PREFIX_ES 0x40 -#define PREFIX_FS 0x80 -#define PREFIX_GS 0x100 -#define PREFIX_DATA 0x200 -#define PREFIX_ADR 0x400 -#define PREFIX_FWAIT 0x800 - -static int prefixes; - -static void -ckprefix(void) -{ - prefixes = 0; - while (1) - { - switch (*codep) - { - case 0xf3: - prefixes |= PREFIX_REPZ; - break; - case 0xf2: - prefixes |= PREFIX_REPNZ; - break; - case 0xf0: - prefixes |= PREFIX_LOCK; - break; - case 0x2e: - prefixes |= PREFIX_CS; - break; - case 0x36: - prefixes |= PREFIX_SS; - break; - case 0x3e: - prefixes |= PREFIX_DS; - break; - case 0x26: - prefixes |= PREFIX_ES; - break; - case 0x64: - prefixes |= PREFIX_FS; - break; - case 0x65: - prefixes |= PREFIX_GS; - break; - case 0x66: - prefixes |= PREFIX_DATA; - break; - case 0x67: - prefixes |= PREFIX_ADR; - break; - case 0x9b: - prefixes |= PREFIX_FWAIT; - break; - default: - return; - } - codep++; - } -} - -static int dflag; -static int aflag; - -static char op1out[100], op2out[100], op3out[100]; -static unsigned long start_pc; - -/* - * disassemble the first instruction in 'inbuf'. You have to make - * sure all of the bytes of the instruction are filled in. - * On the 386's of 1988, the maximum length of an instruction is 15 bytes. - * (see topic "Redundant prefixes" in the "Differences from 8086" - * section of the "Virtual 8086 Mode" chapter.) - * 'pc' should be the address of this instruction, it will - * be used to print the target address if this is a relative jump or call - * 'outbuf' gets filled in with the disassembled instruction. it should - * be long enough to hold the longest disassembled instruction. - * 100 bytes is certainly enough, unless symbol printing is added later - * The function returns the length of this instruction in bytes. - */ -int -i386dis (unsigned short ucs, unsigned short uip, unsigned char *inbuf, - char *outbuf, int mode) -{ - struct dis386 *dp; - int i; - int enter_instruction; - char *first, *second, *third; - int needcomma; - - obuf[0] = 0; - op1out[0] = 0; - op2out[0] = 0; - op3out[0] = 0; - - start_pc = ucs << 16 | uip; - start_codep = inbuf; - codep = inbuf; - - ckprefix (); - - if (*codep == 0xc8) - enter_instruction = 1; - else - enter_instruction = 0; - - obufp = obuf; - - if (prefixes & PREFIX_REPZ) - oappend ("repz "); - if (prefixes & PREFIX_REPNZ) - oappend ("repnz "); - if (prefixes & PREFIX_LOCK) - oappend ("lock "); - - if ((prefixes & PREFIX_FWAIT) - && ((*codep < 0xd8) || (*codep > 0xdf))) - { - /* fwait not followed by floating point instruction */ - oappend ("fwait"); - strcpy (outbuf, obuf); - return (1); - } - - /* these would be initialized to 0 if disassembling for 8086 or 286 */ - if (mode) { - dflag = 1; - aflag = 1; - } else { - dflag = 0; - aflag = 0; - } - - if (prefixes & PREFIX_DATA) - dflag ^= 1; - - if (prefixes & PREFIX_ADR) - { - aflag ^= 1; - oappend ("addr16 "); - } - - if (*codep == 0x0f) - dp = &dis386_twobyte[*++codep]; - else - dp = &dis386[*codep]; - codep++; - mod = (*codep >> 6) & 3; - reg = (*codep >> 3) & 7; - rm = *codep & 7; - - if (dp->name == NULL && dp->bytemode1 == FLOATCODE) - { - dofloat (); - } - else - { - if (dp->name == NULL) - dp = &grps[dp->bytemode1][reg]; - - putop (dp->name); - - obufp = op1out; - if (dp->op1) - (*dp->op1)(dp->bytemode1); - - obufp = op2out; - if (dp->op2) - (*dp->op2)(dp->bytemode2); - - obufp = op3out; - if (dp->op3) - (*dp->op3)(dp->bytemode3); - } - - obufp = obuf + strlen (obuf); - for (i = strlen (obuf); i < 6; i++) - oappend (" "); - oappend (" "); - - /* enter instruction is printed with operands in the - * same order as the intel book; everything else - * is printed in reverse order - */ - if (enter_instruction) - { - first = op1out; - second = op2out; - third = op3out; - } - else - { - first = op3out; - second = op2out; - third = op1out; - } - needcomma = 0; - if (*first) - { - oappend (first); - needcomma = 1; - } - if (*second) - { - if (needcomma) - oappend (","); - oappend (second); - needcomma = 1; - } - if (*third) - { - if (needcomma) - oappend (","); - oappend (third); - } - strcpy (outbuf, obuf); - return (codep - inbuf); -} - -const char *float_mem[] = { - /* d8 */ - "fadds", - "fmuls", - "fcoms", - "fcomps", - "fsubs", - "fsubrs", - "fdivs", - "fdivrs", - /* d9 */ - "flds", - "(bad)", - "fsts", - "fstps", - "fldenv", - "fldcw", - "fNstenv", - "fNstcw", - /* da */ - "fiaddl", - "fimull", - "ficoml", - "ficompl", - "fisubl", - "fisubrl", - "fidivl", - "fidivrl", - /* db */ - "fildl", - "(bad)", - "fistl", - "fistpl", - "(bad)", - "fldt", - "(bad)", - "fstpt", - /* dc */ - "faddl", - "fmull", - "fcoml", - "fcompl", - "fsubl", - "fsubrl", - "fdivl", - "fdivrl", - /* dd */ - "fldl", - "(bad)", - "fstl", - "fstpl", - "frstor", - "(bad)", - "fNsave", - "fNstsw", - /* de */ - "fiadd", - "fimul", - "ficom", - "ficomp", - "fisub", - "fisubr", - "fidiv", - "fidivr", - /* df */ - "fild", - "(bad)", - "fist", - "fistp", - "fbld", - "fildll", - "fbstp", - "fistpll", -}; - -#define ST OP_ST, 0 -#define STi OP_STi, 0 - -#define FGRPd9_2 NULL, NULL, 0, NOFUNC, NOFUNC -#define FGRPd9_4 NULL, NULL, 1, NOFUNC, NOFUNC -#define FGRPd9_5 NULL, NULL, 2, NOFUNC, NOFUNC -#define FGRPd9_6 NULL, NULL, 3, NOFUNC, NOFUNC -#define FGRPd9_7 NULL, NULL, 4, NOFUNC, NOFUNC -#define FGRPda_5 NULL, NULL, 5, NOFUNC, NOFUNC -#define FGRPdb_4 NULL, NULL, 6, NOFUNC, NOFUNC -#define FGRPde_3 NULL, NULL, 7, NOFUNC, NOFUNC -#define FGRPdf_4 NULL, NULL, 8, NOFUNC, NOFUNC - -struct dis386 float_reg[][8] = { - /* d8 */ - { - { "fadd", ST, STi, NOFUNC }, - { "fmul", ST, STi, NOFUNC }, - { "fcom", STi, NOFUNC, NOFUNC }, - { "fcomp", STi, NOFUNC, NOFUNC }, - { "fsub", ST, STi, NOFUNC }, - { "fsubr", ST, STi, NOFUNC }, - { "fdiv", ST, STi, NOFUNC }, - { "fdivr", ST, STi, NOFUNC }, - }, - /* d9 */ - { - { "fld", STi, NOFUNC, NOFUNC }, - { "fxch", STi, NOFUNC, NOFUNC }, - { FGRPd9_2 }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { FGRPd9_4 }, - { FGRPd9_5 }, - { FGRPd9_6 }, - { FGRPd9_7 }, - }, - /* da */ - { - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { FGRPda_5 }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - }, - /* db */ - { - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { FGRPdb_4 }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - }, - /* dc */ - { - { "fadd", STi, ST, NOFUNC }, - { "fmul", STi, ST, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "fsub", STi, ST, NOFUNC }, - { "fsubr", STi, ST, NOFUNC }, - { "fdiv", STi, ST, NOFUNC }, - { "fdivr", STi, ST, NOFUNC }, - }, - /* dd */ - { - { "ffree", STi, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "fst", STi, NOFUNC, NOFUNC }, - { "fstp", STi, NOFUNC, NOFUNC }, - { "fucom", STi, NOFUNC, NOFUNC }, - { "fucomp", STi, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - }, - /* de */ - { - { "faddp", STi, ST, NOFUNC }, - { "fmulp", STi, ST, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { FGRPde_3 }, - { "fsubp", STi, ST, NOFUNC }, - { "fsubrp", STi, ST, NOFUNC }, - { "fdivp", STi, ST, NOFUNC }, - { "fdivrp", STi, ST, NOFUNC }, - }, - /* df */ - { - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { FGRPdf_4 }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - { "(bad)", NOFUNC, NOFUNC, NOFUNC }, - }, -}; - - -const char *fgrps[][8] = { - /* d9_2 0 */ - { - "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", - }, - - /* d9_4 1 */ - { - "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)", - }, - - /* d9_5 2 */ - { - "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)", - }, - - /* d9_6 3 */ - { - "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp", - }, - - /* d9_7 4 */ - { - "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos", - }, - - /* da_5 5 */ - { - "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", - }, - - /* db_4 6 */ - { - "feni(287 only)","fdisi(287 only)","fNclex","fNinit", - "fNsetpm(287 only)","(bad)","(bad)","(bad)", - }, - - /* de_3 7 */ - { - "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", - }, - - /* df_4 8 */ - { - "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", - }, -}; - - -static void -dofloat () -{ - struct dis386 *dp; - unsigned char floatop; - - floatop = codep[-1]; - - if (mod != 3) - { - putop (float_mem[(floatop - 0xd8) * 8 + reg]); - obufp = op1out; - OP_E (v_mode); - return; - } - codep++; - - dp = &float_reg[floatop - 0xd8][reg]; - if (dp->name == NULL) - { - putop (fgrps[dp->bytemode1][rm]); - /* instruction fnstsw is only one with strange arg */ - if (floatop == 0xdf && *codep == 0xe0) - strcpy (op1out, "%eax"); - } - else - { - putop (dp->name); - obufp = op1out; - if (dp->op1) - (*dp->op1)(dp->bytemode1); - obufp = op2out; - if (dp->op2) - (*dp->op2)(dp->bytemode2); - } -} - -static void -OP_ST(int dummy __unused) -{ - oappend ("%st"); -} - -static void -OP_STi(int dummy __unused) -{ - sprintf (scratchbuf, "%%st(%d)", rm); - oappend (scratchbuf); -} - - -/* capital letters in template are macros */ -static void -putop(const char *template) -{ - const char *p; - - for (p = template; *p; p++) - { - switch (*p) - { - default: - *obufp++ = *p; - break; - case 'C': /* For jcxz/jecxz */ - if (aflag == 0) - *obufp++ = 'e'; - break; - case 'N': - if ((prefixes & PREFIX_FWAIT) == 0) - *obufp++ = 'n'; - break; - case 'S': - /* operand size flag */ - if (dflag) - *obufp++ = 'l'; - else - *obufp++ = 'w'; - break; - } - } - *obufp = 0; -} - -static void -oappend(const char *s) -{ - strcpy (obufp, s); - obufp += strlen (s); - *obufp = 0; -} - -static void -append_prefix() -{ - if (prefixes & PREFIX_CS) - oappend ("%cs:"); - if (prefixes & PREFIX_DS) - oappend ("%ds:"); - if (prefixes & PREFIX_SS) - oappend ("%ss:"); - if (prefixes & PREFIX_ES) - oappend ("%es:"); - if (prefixes & PREFIX_FS) - oappend ("%fs:"); - if (prefixes & PREFIX_GS) - oappend ("%gs:"); -} - -static void -OP_indirE(int bytemode) -{ - oappend ("*"); - OP_E (bytemode); -} - -static void -OP_E(int bytemode) -{ - int disp; - int havesib; - int base; - int idx; - int scale; - int havebase; - - /* skip mod/rm byte */ - codep++; - - havesib = 0; - havebase = 0; - disp = 0; - - if (mod == 3) { - switch (bytemode) { - case b_mode: - oappend (names8[rm]); - break; - case w_mode: - oappend (names16[rm]); - break; - case v_mode: - if (dflag) - oappend (names32[rm]); - else - oappend (names16[rm]); - break; - default: - oappend ("<bad dis table>"); - break; - } - return; - } - - append_prefix (); - - if (aflag && rm == 4) { - havesib = 1; - havebase = 1; - scale = (*codep >> 6) & 3; - idx = (*codep >> 3) & 7; - base = *codep & 7; - codep++; - } - - switch (mod) { - case 0: - if (aflag) { - switch (rm) { - case 4: - /* implies havesib and havebase */ - if (base == 5) { - havebase = 0; - disp = get32 (); - } - break; - case 5: - disp = get32 (); - break; - default: - havebase = 1; - base = rm; - break; - } - } else { - if (rm == 6) { - havebase = 0; - disp = get16 (); - } else { - havebase = 1; - base = rm; - } - } - break; - case 1: - disp = *(char *)codep++; - if (!aflag || rm != 4) { - havebase = 1; - base = rm; - } - break; - case 2: - if (aflag) - disp = get32 (); - else - disp = get16 (); - if (!aflag || rm != 4) { - havebase = 1; - base = rm; - } - break; - } - - if (mod != 0 || ((aflag && rm == 5) || (havesib && base == 5)) - || (!aflag && rm == 6)) { - sprintf (scratchbuf, "0x%x", disp); - oappend (scratchbuf); - } - - if (havebase || havesib) { - oappend ("("); - if (havebase) - oappend (aflag ? names32[base] : names16_pairs[base]); - if (havesib) { - if (idx != 4) { - sprintf (scratchbuf, ",%s", names32[idx]); - oappend (scratchbuf); - } - sprintf (scratchbuf, ",%d", 1 << scale); - oappend (scratchbuf); - } - oappend (")"); - } -} - -static void -OP_G(int bytemode) -{ - switch (bytemode) - { - case b_mode: - oappend (names8[reg]); - break; - case w_mode: - oappend (names16[reg]); - break; - case d_mode: - oappend (names32[reg]); - break; - case v_mode: - if (dflag) - oappend (names32[reg]); - else - oappend (names16[reg]); - break; - default: - oappend ("<internal disassembler error>"); - break; - } -} - -static int -get32() -{ - int x = 0; - - x = *codep++ & 0xff; - x |= (*codep++ & 0xff) << 8; - x |= (*codep++ & 0xff) << 16; - x |= (*codep++ & 0xff) << 24; - return (x); -} - -static int -get16() -{ - int x = 0; - - x = *codep++ & 0xff; - x |= (*codep++ & 0xff) << 8; - return (x); -} - -static void -OP_REG(int code) -{ - const char *s; - - switch (code) - { - case indir_dx_reg: s = "(%dx)"; break; - case ax_reg: case cx_reg: case dx_reg: case bx_reg: - case sp_reg: case bp_reg: case si_reg: case di_reg: - s = names16[code - ax_reg]; - break; - case es_reg: case ss_reg: case cs_reg: - case ds_reg: case fs_reg: case gs_reg: - s = names_seg[code - es_reg]; - break; - case al_reg: case ah_reg: case cl_reg: case ch_reg: - case dl_reg: case dh_reg: case bl_reg: case bh_reg: - s = names8[code - al_reg]; - break; - case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg: - case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg: - if (dflag) - s = names32[code - eAX_reg]; - else - s = names16[code - eAX_reg]; - break; - default: - s = "<internal disassembler error>"; - break; - } - oappend (s); -} - -static void -OP_I(int bytemode) -{ - int op; - - switch (bytemode) - { - case b_mode: - op = *codep++ & 0xff; - break; - case v_mode: - if (dflag) - op = get32 (); - else - op = get16 (); - break; - case w_mode: - op = get16 (); - break; - default: - oappend ("<internal disassembler error>"); - return; - } - sprintf (scratchbuf, "$0x%x", op); - oappend (scratchbuf); -} - -static void -OP_sI(int bytemode) -{ - int op; - - switch (bytemode) - { - case b_mode: - op = *(char *)codep++; - break; - case v_mode: - if (dflag) - op = get32 (); - else - op = (short)get16(); - break; - case w_mode: - op = (short)get16 (); - break; - default: - oappend ("<internal disassembler error>"); - return; - } - sprintf (scratchbuf, "$0x%x", op); - oappend (scratchbuf); -} - -static void -OP_J(int bytemode) -{ - int disp; - - switch (bytemode) - { - case b_mode: - disp = *(char *)codep++; - append_pc(start_pc + codep - start_codep + disp); - break; - case v_mode: - if (dflag) { - disp = get32 (); - append_pc(start_pc + codep - start_codep + disp); - } else { - disp = (short)get16 (); - disp = (((start_pc + codep - start_codep) & 0xffff) + disp) & 0xffff; - append_pc((start_pc & 0xffff0000) | disp); - } - break; - default: - oappend ("<internal disassembelr error>"); - return; - } - - oappend (scratchbuf); -} - -static void -append_pc(unsigned long pc) -{ - sprintf(scratchbuf, "%04lx:%04lx", pc >> 16, pc & 0xffff); -} - -static void -OP_SEG(int dummy __unused) -{ - static const char *sreg[] = { - "%es","%cs","%ss","%ds","%fs","%gs","%?","%?", - }; - - oappend (sreg[reg]); -} - -static void -OP_DIR(int size) -{ - int seg, offset; - - switch (size) - { - case lptr: - if (dflag) - { - offset = get32 (); - seg = get16 (); - } - else - { - offset = get16 (); - seg = get16 (); - } - sprintf (scratchbuf, "%04x:%04x", seg, offset); - oappend (scratchbuf); - break; - case v_mode: - if (aflag) - offset = get32 (); - else - offset = (short)get16 (); - - append_pc(start_pc + codep - start_codep + offset); - oappend (scratchbuf); - break; - default: - oappend ("<internal disassembler error>"); - break; - } -} - -static void -OP_OFF(int dummy __unused) -{ - int off; - - if (aflag) - off = get32 (); - else - off = get16 (); - - sprintf (scratchbuf, "0x%x", off); - oappend (scratchbuf); -} - -static void -OP_ESDI(int dummy __unused) -{ - oappend ("%es:("); - oappend (aflag ? "%edi" : "%di"); - oappend (")"); -} - -static void -OP_DSSI(int dummy __unused) -{ - oappend ("%ds:("); - oappend (aflag ? "%esi" : "%si"); - oappend (")"); -} - -static void -OP_C(int dummy __unused) -{ - codep++; /* skip mod/rm */ - sprintf (scratchbuf, "%%cr%d", reg); - oappend (scratchbuf); -} - -static void -OP_D(int dummy __unused) -{ - codep++; /* skip mod/rm */ - sprintf (scratchbuf, "%%db%d", reg); - oappend (scratchbuf); -} - -static void -OP_T(int dummy __unused) -{ - codep++; /* skip mod/rm */ - sprintf (scratchbuf, "%%tr%d", reg); - oappend (scratchbuf); -} - -static void -OP_rm(int bytemode) -{ - switch (bytemode) - { - case d_mode: - oappend (names32[rm]); - break; - case w_mode: - oappend (names16[rm]); - break; - } -} - -#else - -i386dis (pc, inbuf, outbuf, mode) - int pc; - unsigned char *inbuf; - char *outbuf; -{ - strcpy (outbuf, "(no disassembler)"); - return (1); -} - -#endif /* DISASSEMBLER */ diff --git a/usr.bin/doscmd/int.c b/usr.bin/doscmd/int.c deleted file mode 100644 index be70d1f..0000000 --- a/usr.bin/doscmd/int.c +++ /dev/null @@ -1,251 +0,0 @@ -/* -** No copyright?! -*/ -/* - * Notes: - * 1) Second PIC is not implemented. - * 2) Interrupt priority management is not implemented. - * 3) What should be read from port 0x20? - * - * "within interrupt processing" means the following is true: - * 1) Hardware interrupt <irql> is delivered by hardint(). - * 2) Next interrupt <irql> is not possible yet by either: - * a) V_IF; - * b) Interrupt mask; - * c) Current irql. - * - * Related functions: - * int isinhardint(int irql) - * void set_eoir(int irql, void (*eoir)(void *), void *arg); - * - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include "doscmd.h" - -struct IRQ { - int pending; - int busy; - int within; - void (*eoir)(void *arg); - void *arg; -}; - -static unsigned char IM; -static int Irql; -static struct IRQ Irqs[8]; - -#define int_allowed(n) ((IM & 1 << (n)) == 0 && Irql > (n)) - -void -set_eoir(int irql, void (*eoir)(void *), void *arg) -{ - Irqs [irql].eoir = eoir; - Irqs [irql].arg = arg; -} - -int -isinhardint(int irql) -{ - return Irqs[irql].within; -} - -static void -set_vip(void) -{ - regcontext_t *REGS = saved_regcontext; - int irql; - - if (R_EFLAGS & PSL_VIF) { - R_EFLAGS &= ~PSL_VIP; - return; - } - - for (irql = 0; irql < 8; irql++) - if (int_allowed(irql) && (Irqs[irql].within || Irqs[irql].pending)) { - R_EFLAGS |= PSL_VIP; - return; - } - - R_EFLAGS &= ~PSL_VIP; -} - -void -resume_interrupt(void) -{ - regcontext_t *REGS = saved_regcontext; - int irql; - - if (R_EFLAGS & PSL_VIF) { - for (irql = 0; irql < 8; irql++) - if (Irqs[irql].within && int_allowed(irql)) { - Irqs[irql].within = 0; - if (Irqs[irql].eoir) - Irqs[irql].eoir(Irqs[irql].arg); - } - - for (irql = 0; irql < 8; irql++) - if (Irqs[irql].pending && int_allowed(irql)) { - Irqs[irql].pending = 0; - hardint(irql); - break; - } - } - set_vip(); -} - -void -send_eoi(void) -{ - if (Irql >= 8) - return; - - Irqs[Irql].busy = 0; - - while (++Irql < 8) - if (Irqs [Irql].busy) - break; - - resume_interrupt(); -} - -/* -** Cause a hardware interrupt to happen immediately after -** we return to vm86 mode -*/ -void -hardint(int irql) -{ - regcontext_t *REGS = saved_regcontext; - u_long vec = ivec[8 + irql]; - - /* - ** if we're dead, or there's no vector, or the saved registers - ** are invalid - */ - if (dead || !saved_valid || vec == 0) - return; - - /* - ** if the vector points into the BIOS, or the handler at the - ** other end is just an IRET, don't bother - */ - if ((vec >> 16) == 0xf000 || *(u_char *)VECPTR(vec) == 0xcf) - return; - - if (!int_allowed(irql)) { - Irqs[irql].pending = 1; - return; - } - - if ((R_EFLAGS & PSL_VIF) == 0) { - Irqs[irql].pending = 1; - R_EFLAGS |= PSL_VIP; - return; - } - - debug(D_TRAPS | (8 + irql), "Int%02x [%04lx:%04lx]\n", - 8 + irql, vec >> 16, vec & 0xffff); - - Irql = irql; - Irqs[Irql].busy = 1; - if (Irqs[Irql].eoir) - Irqs[Irql].within = 1; - - PUSH((R_FLAGS & ~PSL_I) | (R_EFLAGS & PSL_VIF ? PSL_I : 0), REGS); - PUSH(R_CS, REGS); - PUSH(R_IP, REGS); - R_EFLAGS &= ~PSL_VIF; /* XXX disable interrupts */ - PUTVEC(R_CS, R_IP, vec); -} - -void -unpend(int irql) -{ - if (!Irqs[irql].pending) - return; - Irqs[irql].pending = 0; - set_vip(); -} - -static unsigned char -irqc_in(int port __unused) -{ - return 0x60; /* What should be here? */ -} - -static void -irqc_out(int port __unused, unsigned char val) -{ - if (val == 0x20) - send_eoi(); -} - -static unsigned char -imr_in(int port __unused) -{ - return IM; -} - -static void -imr_out(int port __unused, unsigned char val) -{ - IM = val; - resume_interrupt(); -} - -/* -** Cause a software interrupt to happen immediately after we -** return to vm86 mode -*/ -void -softint(int intnum) -{ - regcontext_t *REGS = saved_regcontext; - u_long vec = ivec[intnum]; - - /* - ** if we're dead, or there's no vector or the saved registers are - ** invalid - */ - if (dead || !saved_valid || vec == 0) - return; - - /* - ** if the vector points into the BIOS, or the handler at the other - ** end is just an IRET, don't bother. - */ - if ((vec >> 16) == 0xf000 || *(u_char *)VECPTR(vec) == 0xcf) - return; - - debug(D_TRAPS | intnum, "INT %02x [%04lx:%04lx]\n", - intnum, vec >> 16, vec & 0xffff); - - PUSH((R_FLAGS & ~PSL_I) | (R_EFLAGS & PSL_VIF ? PSL_I : 0), REGS); - PUSH(R_CS, REGS); - PUSH(R_IP, REGS); - R_EFLAGS &= ~PSL_VIF; /* XXX disable interrupts? */ - PUTVEC(R_CS, R_IP, vec); -} - -void -init_ints(void) -{ - int i; - - for (i = 0; i < 8; i++) { - Irqs[i].busy = 0; - Irqs[i].pending = 0; - Irqs[i].within = 0; - } - - IM = 0x00; - Irql = 8; - - define_input_port_handler(0x20, irqc_in); - define_output_port_handler(0x20, irqc_out); - define_input_port_handler(0x21, imr_in); - define_output_port_handler(0x21, imr_out); -} diff --git a/usr.bin/doscmd/int10.c b/usr.bin/doscmd/int10.c deleted file mode 100644 index 5f3892d..0000000 --- a/usr.bin/doscmd/int10.c +++ /dev/null @@ -1,466 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI int10.c,v 2.3 1996/04/08 19:32:40 bostic Exp - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <unistd.h> - -#include "doscmd.h" -#include "mouse.h" -#include "tty.h" -#include "video.h" - -static int cursoremu = 1; - -void -int10(regcontext_t *REGS) -{ - char *addr; - int i, j; - int saved_row, saved_col; - - /* - * Any call to the video BIOS is enough to reset the poll - * count on the keyboard. - */ - reset_poll(); - - switch (R_AH) { - case 0x00: /* Set display mode */ - if (!xmode) - goto unsupported; - init_mode(R_AL); - break; - case 0x01: /* Define cursor */ - { - int start, end; - - start = R_CH; - end = R_CL; - if (cursoremu == 0) - goto out; - /* Cursor emulation */ - if (start <= 3 && end <= 3) - goto out; - if (start + 2 >= end) { - /* underline cursor */ - start = CharHeight - 3; - end = CharHeight - 2; - goto out; - } - if (start <= 2 || end < start) { - /* block cursor */ - start = 0; - end = CharHeight - 2; - goto out; - } - if (start > CharHeight / 2) { - /* half block cursor */ - start = CharHeight / 2; - end = 0; - } - out: CursStart = start; - CursEnd = end; - break; - } - case 0x02: /* Position cursor */ - if (!xmode) - goto unsupported; - tty_move(R_DH, R_DL); - break; - case 0x03: /* Read cursor position */ - if (!xmode) - goto unsupported; - tty_report(&i, &j); - R_DH = i; - R_DL = j; - R_CH = CursStart; - R_CL = CursEnd; - break; - case 0x05: - debug(D_VIDEO, "Select current display page %d\n", R_AL); - break; - case 0x06: /* initialize window/scroll text upward */ - if (!xmode) - goto unsupported; - if (R_AL == 0) /* clear screen */ - R_AL = DpyRows + 1; - tty_scroll(R_CH, R_CL, - R_DH, R_DL, - R_AL, R_BH << 8); - break; - case 0x07: /* initialize window/scroll text downward */ - if (!xmode) - goto unsupported; - if (R_AL == 0) /* clear screen */ - R_AL = DpyRows + 1; - tty_rscroll(R_CH, R_CL, - R_DH, R_DL, - R_AL, R_BH << 8); - break; - case 0x08: /* read character/attribute */ - if (!xmode) - goto unsupported; - i = tty_char(-1, -1); - R_AX = i; - break; - case 0x09: /* write character/attribute */ - if (!xmode) - goto unsupported; - tty_rwrite(R_CX, R_AL, R_BL << 8); - break; - case 0x0a: /* write character */ - if (!xmode) - goto unsupported; - debug(D_HALF, "Int 10:0a: Write char: %02x\n", R_AL); - tty_rwrite(R_CX, R_AL, -1); - break; - case 0x0b: /* set border color */ - if (!xmode) - goto unsupported; - video_setborder(R_BL); - break; - case 0x0c: /* write graphics pixel */ - debug(D_VIDEO, "Write graphics pixel at %d, %d\n", R_CX, R_DX); - break; - case 0x0d: /* read graphics pixel */ - debug(D_VIDEO, "Read graphics pixel at %d, %d\n", R_CX, R_DX); - break; - case 0x0e: /* write character */ - tty_write(R_AL, -1); - break; - case 0x0f: /* get current video mode */ - R_AH = DpyCols; /* number of columns */ - R_AL = VideoMode; /* active mode */ - R_BH = 0;/*ActivePage *//* display page */ - break; - case 0x10: - if (!xmode) - goto unsupported; - switch (R_AL) { - case 0x00: /* Set single palette register */ - palette[R_BL] = R_BH; - update_pixels(); - break; - case 0x01: /* Set overscan register */ - VGA_ATC[ATC_OverscanColor] = R_BH; - break; - case 0x02: /* Set all palette registers */ - addr = (char *)MAKEPTR(R_ES, R_DX); - for (i = 0; i < 16; i++) - palette[i] = *addr++; - VGA_ATC[ATC_OverscanColor] = *addr; - update_pixels(); - break; - case 0x03: /* Enable/Disable blinking mode */ - video_blink((R_BL & 1) ? 1 : 0); - break; - case 0x07: /* Get individual palette register */ - R_BH = palette[R_BL]; - break; - case 0x08: /* Read overscan register */ - R_BH = VGA_ATC[ATC_OverscanColor]; - break; - case 0x09: /* Read all palette registers */ - addr = (char *)MAKEPTR(R_ES, R_DX); - for (i = 0; i < 16; i++) - *addr++ = palette[i]; - *addr = VGA_ATC[ATC_OverscanColor]; - break; - case 0x10: /* Set individual DAC register */ - dac_rgb[R_BX].red = R_DH & 0x3f; - dac_rgb[R_BX].green = R_CH & 0x3f; - dac_rgb[R_BX].blue = R_CL & 0x3f; - update_pixels(); - break; - case 0x12: /* Set block of DAC registers */ - addr = (char *)MAKEPTR(R_ES, R_DX); - for (i = R_BX; i < R_BX + R_CX; i++) { - dac_rgb[i].red = *addr++; - dac_rgb[i].green = *addr++; - dac_rgb[i].blue = *addr++; - } - update_pixels(); - break; - case 0x13: /* Select video DAC color page */ - switch (R_BL) { - case 0: - VGA_ATC[ATC_ModeCtrl] |= (R_BH & 0x01) << 7; - break; - case 1: - VGA_ATC[ATC_ColorSelect] = R_BH & 0x0f; - break; - default: - debug(D_VIDEO, "INT 10 10:13 " - "Bad value for BL: 0x%02x\n", R_BL); - break; - } - case 0x15: /* Read individual DAC register */ - R_DH = dac_rgb[R_BX].red; - R_CH = dac_rgb[R_BX].green; - R_CL = dac_rgb[R_BX].blue; - break; - case 0x17: /* Read block of DAC registers */ - addr = (char *)MAKEPTR(R_ES, R_DX); - for (i = R_BX; i < R_BX + R_CX; i++) { - *addr++ = dac_rgb[i].red; - *addr++ = dac_rgb[i].green; - *addr++ = dac_rgb[i].blue; - } - break; - case 0x18: /* Set PEL mask */ - debug(D_HALF, - "INT 10 10:18 Set PEL mask (%02x)\n", R_BL); - break; - case 0x19: /* Read PEL mask */ - debug(D_HALF, "INT 10 10:19 Read PEL mask\n"); - break; - case 0x1a: /* Get video dac color-page state */ - R_BH = (VGA_ATC[ATC_ModeCtrl] & 0x80) >> 7; - R_BL = VGA_ATC[ATC_ColorSelect]; - break; - case 0x1b: /* Perform gray-scale summing */ - debug(D_HALF, "Perform gray-scale summing\n"); - break; - default: - unknown_int3(0x10, 0x10, R_AL, REGS); - break; - } - break; - case 0x11: - switch (R_AL) { - case 0x00: /* Text-mode chargen: load user-specified - patterns */ - debug(D_VIDEO, "Tried to load user defined font.\n"); - break; - case 0x01: /* Text-mode chargen: load ROM monochrome - patterns */ - debug(D_VIDEO, "Tried to load 8x14 font.\n"); - break; - case 0x02: /* Text-mode chargen: load ROM 8x8 double-dot - patterns */ - debug(D_VIDEO, "Tried to load 8x8 font.\n"); - break; - case 0x03: /* Text-mode chargen: set block specifier */ - debug(D_VIDEO, "Tried to activate character set\n"); - break; - case 0x04: /* Text-mode chargen: load ROM 8x16 character - set */ - debug(D_VIDEO, "Tried to load 8x16 font.\n"); - break; - case 0x10: /* Text-mode chargen: load and activate - user-specified patterns */ - debug(D_VIDEO, - "Tried to load and activate user defined font\n"); - break; - case 0x11: /* Text-mode chargen: load and activate ROM - monochrome patterns */ - debug(D_VIDEO, - "Tried to load and activate 8x14 font.\n"); - break; - case 0x12: /* Text-mode chargen: load and activate ROM - 8x8 double-dot patterns */ - debug(D_VIDEO, - "Tried to load and activate 8x8 font.\n"); - break; - case 0x14: /* Text-mode chargen: load and activate ROM - 8x16 character set */ - debug(D_VIDEO, - "Tried to load and activate 8x16 font.\n"); - break; - case 0x20: /* Graph-mode chargen: set user 8x8 graphics - characters */ - debug(D_VIDEO, "Load second half of 8x8 char set\n"); - break; - case 0x21: /* Graph-mode chargen: set user graphics - characters */ - debug(D_VIDEO, "Install user defined char set\n"); - break; - case 0x22: /* Graph-mode chargen: set ROM 8x14 graphics - chars */ - debug(D_VIDEO, "Install 8x14 char set\n"); - break; - case 0x23: /* Graph-mode chargen: set ROM 8x8 double-dot - chars */ - debug(D_VIDEO, "Install 8x8 char set\n"); - break; - case 0x24: /* Graph-mode chargen: load 8x16 graphics - chars */ - debug(D_VIDEO, "Install 8x16 char set\n"); - break; - case 0x30: /* Get font information */ - debug(D_VIDEO, - "INT 10 11:30 Request font address %02x\n", R_BH); - R_CX = CharHeight; - R_DL = DpyRows; - switch(R_BH) { - case 0: - PUTVEC(R_ES, R_BP, ivec[0x1f]); - break; - case 1: - PUTVEC(R_ES, R_BP, ivec[0x43]); - break; - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - R_ES = 0; - R_BP = 0; - break; - default: - unknown_int4(0x10, 0x11, 0x30, R_BH, REGS); - break; - } - break; - default: - unknown_int3(0x10, 0x11, R_AL, REGS); - break; - } - break; - case 0x12: /* Alternate function select */ - if (!xmode) - goto unsupported; - switch (R_BL) { - case 0x10: /* Read EGA/VGA config */ - R_BH = NumColors > 1 ? 0 : 1; /* Color */ - R_BL = 3; /* 256 K */ - break; - case 0x34: /* Cursor emulation */ - if (R_AL == 0) - cursoremu = 1; - else - cursoremu = 0; - R_AL = 0x12; - break; - default: - if (vflag) - dump_regs(REGS); - unknown_int3(0x10, 0x12, R_BL, REGS); - break; - } - break; - case 0x13: /* write character string */ - if (!xmode) - goto unsupported; - addr = (char *)MAKEPTR(R_ES, R_BP); - switch (R_AL & 0x03) { - case 0: - tty_report(&saved_row, &saved_col); - tty_move(R_DH, R_DL); - for (i = 0; i < R_CX; ++i) - tty_write(*addr++, R_BL << 8); - tty_move(saved_row, saved_col); - break; - case 1: - tty_move(R_DH, R_DL); - for (i = 0; i < R_CX; ++i) - tty_write(*addr++, R_BL << 8); - break; - case 2: - tty_report(&saved_row, &saved_col); - tty_move(R_DH, R_DL); - for (i = 0; i < R_CX; ++i) { - tty_write(addr[0], addr[1]); - addr += 2; - } - tty_move(saved_row, saved_col); - break; - case 3: - tty_move(R_DH, R_DL); - for (i = 0; i < R_CX; ++i) { - tty_write(addr[0], addr[1]); - addr += 2; - } - break; - } - break; - case 0x1a: - if (!xmode) - goto unsupported; - R_AL = 0x1a; /* I am VGA */ - R_BL = 8; /* Color VGA */ - R_BH = 0; /* No other card */ - break; - case 0x1b: /* Video Functionality/State information */ - if (R_BX == 0) { - addr = (char *)MAKEPTR(R_ES, R_DI); - memcpy(addr, vga_status, 64); - R_AL = 0x1b; - } - break; - case 0x1c: /* Save/Restore video state */ - debug(D_VIDEO, "VGA: Save/restore video state\n"); - R_AL = 0; - break; - case 0x30: /* Locate 3270PC configuration table */ - R_CX = 0; - R_DX = 0; - break; - case 0x4f: /* get VESA information */ - R_AH = 0x01; /* no VESA support */ - break; - case 0x6f: - switch (R_AL) { - case 0x00: /* HP-Vectra or Video7 installation check */ - R_BX = 0; /* nope, none of that */ - break; - default: - unknown_int3(0x10, 0x6f, R_AL, REGS); - break; - } - break; - case 0xef: - case 0xfe: /* Get video buffer */ - break; - case 0xfa: /* Interrogate mouse driver */ - if (xmode) - PUTPTR(R_ES, R_BX, (long)mouse_area); - break; - case 0xff: /* Update real screen from video buffer */ - /* XXX - we should allow secondary buffer here and then - update it as the user requests. */ - break; - unsupported: - if (vflag) - dump_regs(REGS); - fatal("int10 function 0x%02x:%02x only available in X mode\n", - R_AH, R_AL); - default: - if (vflag) - dump_regs(REGS); - unknown_int3(0x10, R_AH, R_AL, REGS); - break; - } -} diff --git a/usr.bin/doscmd/int13.c b/usr.bin/doscmd/int13.c deleted file mode 100644 index ba9be70..0000000 --- a/usr.bin/doscmd/int13.c +++ /dev/null @@ -1,883 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI int13.c,v 2.3 1996/04/08 19:32:43 bostic Exp - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/ioctl.h> -#include <sys/types.h> -#include <sys/uio.h> -#include <unistd.h> - -#include "doscmd.h" - -#define FDCHANGED _IOR('F', 64, int) - -#define INT13_ERR_NONE 0x00 -#define INT13_ERR_BAD_COMMAND 0x01 -#define INT13_ERR_BAD_ADDRESS_MARK 0x02 -#define INT13_ERR_WRITE_PROTECT 0x03 -#define INT13_ERR_SECTOR_ID_BAD 0x04 -#define INT13_ERR_RESET_FAILURE 0x05 -#define INT13_ERR_CLL_ACTIVE 0x06 -#define INT13_ERR_ACT_FAILED 0x07 -#define INT13_ERR_DMA_OVERRUN 0x08 -#define INT13_ERR_DMA_BOUNDARY 0x09 -#define INT13_ERR_BAD_TRACK_FLAG 0x0B -#define INT13_ERR_MEDIA_TYP_UNKNOWN 0x0C -#define INT13_ERR_CRC 0x10 -#define INT13_ERR_CORRECTED 0x11 -#define INT13_ERR_CTRLR_FAILURE 0x20 -#define INT13_ERR_SEEK 0x40 -#define INT13_ERR_TIME_OUT 0x80 -#define INT13_ERR_NOT_READY 0xAA -#define INT13_ERR_UNDEFINED 0xBB -#define INT13_ERR_SENSE_OPERATION 0xFF - -typedef struct { - u_char bootIndicator; - u_char beginHead; - u_char beginSector; - u_char beginCyl; - u_char systemID; - u_char endHead; - u_char endSector; - u_char endCyl; - u_long relSector; - u_long numSectors; -} PTAB; - -struct diskinfo { - int type; - int sectors; - int cylinders; - int sides; - int secsize; - int fd; - char *path; - u_long location; - u_char *sector0; - u_long offset; - char *list[4]; /* Up to 4 devices allowed */ - unsigned multi:2; - int read_only:1; - int removeable:1; - int changed:1; /* Set if we change format */ -}; - -#define hd_status (*(u_char *)0x474) -#define fd_status (*(u_char *)0x441) - -static __inline int -disize(struct diskinfo *di) -{ - return(di->sectors * di->cylinders * di->sides); -} - -static __inline int -cylsize(struct diskinfo *di) -{ - return(di->sectors * di->sides); -} - -static u_long ftable = 0xF1000; /* Floppy table */ -static u_long htable = 0xF1020; /* Hard disk table */ - -static struct diskinfo diskinfo[26]; - -static struct diskinfo floppyinfo[] = { - {0, 9, 40, 1, 512, -1, NULL, 0, NULL, 0, - {NULL, NULL, NULL, NULL}, 0, 0, 0, 0}, /* Probably not correct */ - {1, 9, 40, 2, 512, -1, NULL, 0, NULL, 0, - {NULL, NULL, NULL, NULL}, 0, 0, 0, 0}, - {2, 9, 80, 2, 512, -1, NULL, 0, NULL, 0, - {NULL, NULL, NULL, NULL}, 0, 0, 0, 0}, - {3, 15, 80, 2, 512, -1, NULL, 0, NULL, 0, - {NULL, NULL, NULL, NULL}, 0, 0, 0, 0}, - {4, 18, 80, 2, 512, -1, NULL, 0, NULL, 0, - {NULL, NULL, NULL, NULL}, 0, 0, 0, 0}, - {6, 36, 80, 2, 512, -1, NULL, 0, NULL, 0, - {NULL, NULL, NULL, NULL}, 0, 0, 0, 0}, - {-1, 0, 0, 0, 0, 0, NULL, 0, NULL, 0, - {NULL, NULL, NULL, NULL}, 0, 0, 0, 0} -}; - -static struct diskinfo * -getdisk(int drive) -{ - struct diskinfo *di; - - if (drive >= 2 && drive < 0x80) { - return(0); - } - if (drive >= 0x80) { - drive -= 0x80; - drive += 2; - } - - if (drive > 25 || diskinfo[drive].path == 0) { - return(0); - } - di = &diskinfo[drive]; - if (di->fd < 0) { - if (di->removeable) { - di->read_only = 0; - if (!(di->path = di->list[di->multi])) - di->path = di->list[di->multi = 0]; - } - if ((di->fd = open(di->path, di->read_only ? O_RDONLY - : O_RDWR|O_FSYNC)) < 0 && - (di->read_only = 1) && - (di->fd = open(di->path, O_RDONLY)) < 0) { - return(0); - } - di->fd = squirrel_fd(di->fd); - } - return(di); -} - -int -disk_fd(int drive) -{ - struct diskinfo *di; - - if (drive > 1) - drive += 0x80 - 2; - di = getdisk(drive); - if (!di) - return(-1); - return(di->fd); -} - -void -make_readonly(int drive) -{ - if (drive < 0 || drive >= 26) - return; - diskinfo[drive].read_only = 1; -} - -int -init_hdisk(int drive, int cyl, int head, int tracksize, char *file, char *fake_ptab) -{ - struct diskinfo *di; - u_long table; - - if (drive < 0) { - for (drive = 2; drive < 26; ++drive) { - if (diskinfo[drive].path == 0) - break; - } - } - if (drive < 2) { - fprintf(stderr, "Only floppies may be assigned to A: or B:\n"); - return(-1); - } - - if (drive >= 26) { - fprintf(stderr, "Too many disk drives (only 24 allowed)\n"); - return(-1); - } - - di = &diskinfo[drive]; - - if (di->path) { - fprintf(stderr, "Drive %c: already assigned to %s\n", drntol(drive), - di->path); - return(-1); - } - di->fd = -1; - di->sectors = tracksize; - di->cylinders = cyl; - di->sides = head; - di->sector0 = 0; - di->offset = 0; - - if (fake_ptab) { - u_char buf[512]; - int fd; - PTAB *ptab; - int clusters; - - if ((fd = open(fake_ptab, 0)) < 0) { - perror(fake_ptab); - return(-1); - } - di->sector0 = malloc(512); - if (!di->sector0) { - perror("malloc in init_hdisk"); - quit(1); - } - - read(fd, di->sector0, 512); - close(fd); - - ptab = (PTAB *)(di->sector0 + 0x01BE); - - for (fd = 0; fd < 4; ++fd) { - if (*(u_short *)(di->sector0 + 0x1FE) == 0xAA55 && - ptab[fd].numSectors == (u_long)(head * tracksize * cyl) && - (ptab[fd].systemID == 1 || ptab[fd].systemID == 4 || - ptab[fd].systemID == 6)) - break; - } - if (fd < 4) { - if (fd) - memcpy(ptab, ptab + fd, sizeof(PTAB)); - memset(ptab + 1, 0, sizeof(PTAB) * 3); - di->offset = ptab[0].relSector; - di->cylinders += di->offset / cylsize(di); - } else { - memset(ptab, 0, sizeof(PTAB) * 4); - - ptab->beginHead = 0; - ptab->beginSector = 1; /* this is 1 based */ - ptab->beginCyl = 1; - - ptab->endHead = head - 1; - ptab->endSector = tracksize; /* this is 1 based */ - ptab->endCyl = cyl & 0xff; - ptab->endSector |= (cyl & 0x300) >> 2; - - ptab->relSector = head * tracksize; - ptab->numSectors = head * tracksize * cyl; - - *(u_short *)(di->sector0 + 0x1FE) = 0xAA55; - - fd = open(file, 0); - if (fd < 0) { - perror(file); - return(-1); - } - memset(buf, 0, 512); - read(fd, buf, 512); - close(fd); - if ((clusters = buf[0x0D]) == 0) { - if (disize(di) <= 128 * 2048) - clusters = 4; - else if (disize(di) <= 256 * 2048) - clusters = 8; - else if (disize(di) <= 8 * 1024 * 2048) - clusters = 16; - else if (disize(di) <= 16 * 1024 * 2048) - clusters = 32; - else - clusters = 64; - } - if ((disize(di) / clusters) <= 4096) { - ptab->systemID = 0x01; - } else { - ptab->systemID = 0x04; - } - - di->cylinders += 1; /* Extra cylinder for partition table, etc. */ - } - ptab->bootIndicator = 0x80; - } - di->type = 0xf8; - di->path = file; - di->secsize = 512; - di->path = strdup(file); - - di->location = ((table & 0xf0000) << 12) | (table & 0xffff); - - if (drive == 0) { - ivec[0x41] = di->location; - } else if (drive == 1) { - ivec[0x46] = di->location; - } - - table = htable + (drive - 2) * 0x10; - *(u_short *)(table+0x00) = di->cylinders-1; /* Cylinders */ - *(u_char *)(table+0x02) = di->sides; /* Heads */ - *(u_short *)(table+0x03) = 0; /* 0 */ - *(u_short *)(table+0x05) = 0xffff; /* write pre-comp */ - *(u_char *)(table+0x07) = 0; /* ECC Burst length */ - *(u_char *)(table+0x08) = 0; /* Control Byte */ - *(u_char *)(table+0x09) = 0; /* standard timeout */ - *(u_char *)(table+0x0a) = 0; /* formatting timeout */ - *(u_char *)(table+0x0b) = 0; /* timeout for checking drive */ - *(u_short *)(table+0x0c) = di->cylinders-1; /* landing zone */ - *(u_char *)(table+0x0e) = di->sectors; /* sectors/track */ - *(u_char *)(table+0x0f) = 0; - - if ((drive - 1) >= ndisks) - ndisks = drive - 1; - return(drive); -} - -static __inline int -bps(int size) -{ - switch (size) { - case 128: return(0); - case 256: return(1); - case 512: return(2); - case 1024: return(3); - default: - fprintf(stderr, "Invalid sector size: %d\n", size); - quit(1); - } - /* keep `gcc -Wall' happy */ - return(0); -} - -int -init_floppy(int drive, int type, char *file) -{ - struct diskinfo *di = floppyinfo; - u_long table; - struct stat sb; - - while (di->type >= 0 && di->type != type && disize(di)/2 != type) - ++di; - - if (!di->type) { - fprintf(stderr, "Invalid floppy type: %d\n", type); - return(-1); - } - - if (drive < 0) { - if (diskinfo[0].path == 0) { - drive = 0; - } else if (diskinfo[1].path == 0) { - drive = 1; - } else { - fprintf(stderr, "Too many floppy drives (only 2 allowed)\n"); - return(-1); - } - } - if (drive > 1) { - fprintf(stderr, "Floppies must be either drive A: or B:\n"); - return(-1); - } - - if (drive >= nfloppies) - nfloppies = drive + 1; - - if (diskinfo[drive].path == 0) { - diskinfo[drive] = *di; - } - - di = &diskinfo[drive]; - - if (stat(file, &sb) < 0) { - fprintf(stderr, "Drive %c: Could not stat %s\n", drntol(drive), file); - return(-1); - } - - if (drive < 2 && (S_ISCHR(sb.st_mode) || S_ISBLK(sb.st_mode))) { - if (di->path && !di->removeable) { - fprintf(stderr, "Drive %c: is not removeable and hence can only have one assignment\n", drntol(drive)); - return(-1); - } - di->removeable = 1; - } else if (di->removeable) { - fprintf(stderr, "Drive %c: already assigned to %s\n", drntol(drive), - di->path); - return(-1); - } - - if (di->removeable) { -#if 0 /*XXXXX*/ - if (di->multi == 4) { - fprintf(stderr, "Drive %c: already assigned 4 devices\n", - drntol(drive)); - return(-1); - } -#endif - di->path = di->list[di->multi++] = strdup(file); - } else { - if (di->path) { - fprintf(stderr, "Drive %c: already assigned to %s\n", - drntol(drive), di->path); - return(-1); - } - - di->path = strdup(file); - } - di->fd = -1; - di->location = ((table & 0xf0000) << 12) | (table & 0xffff); - di->sector0 = 0; - di->offset = 0; - - ivec[0x1e] = ((ftable & 0xf0000) << 12) | (ftable & 0xffff); - - table = ftable + drive * 0x0a; - - *(u_char *)(table+0x00) = 0xdf; /* First Specify Byte */ - *(u_char *)(table+0x01) = 0x02; /* Second Specify Byte */ - *(u_char *)(table+0x02) = 0x25; /* Timer ticks to wait 'til motor OFF */ - *(u_char *)(table+0x03) = bps(di->secsize); /* Number of bytes/sector */ - *(u_char *)(table+0x04) = di->sectors; /* Number of sectors/track */ - *(u_char *)(table+0x05) = 0x1b; /* Gap length, in bytes */ - *(u_char *)(table+0x06) = 0xff; /* Data length, in bytes */ - *(u_char *)(table+0x07) = 0x6c; /* Gap length for format */ - *(u_char *)(table+0x09) = 0xf6; /* Fill byte for formatting */ - *(u_char *)(table+0x09) = 0x0f; /* Head settle time, in milliseconds */ - *(u_char *)(table+0x0a) = 0x08; /* Motor startup time, in 1/8 seconds */ - return(drive); -} - -int -search_floppy(int i) -{ - return(i < nfloppies ? diskinfo[i].type : 0); -} - -#define seterror(err) { \ - if (drive & 0x80) \ - hd_status = err; \ - else \ - fd_status = err; \ - R_AH = err; \ - R_FLAGS |= PSL_C; \ -} - -static int -trynext(struct diskinfo *di) -{ - close(di->fd); - di->fd = -1; - di->changed = 1; -#if 0 /*XXXXX*/ - if (di->multi++ >= 4) - return(0); -#endif - if (di->list[di->multi] && (di = getdisk(di - diskinfo))) { - di->multi = 0; - return(1); - } - return(0); -} - -static int -diread(struct diskinfo *di, regcontext_t *REGS, - off_t start, char *addr, int sectors) -{ - off_t res; - - int drive = di - diskinfo; - di->multi = -1; - - if (drive > 1) { - drive -= 2; - drive |= 0x80; - } - -again: - res = lseek(di->fd, start * di->secsize, 0); - - if (res < 0 && di->removeable && trynext(di)) - goto again; - - if (res < 0) { - seterror(INT13_ERR_SEEK); - return(-1); - } - - res = read(di->fd, addr, sectors * di->secsize); - - if (res < 0 && di->removeable && trynext(di)) - goto again; - - if (di->removeable) { - if (res < 0) { - seterror(INT13_ERR_NOT_READY); - return(-1); - } - return(res / di->secsize); - } - - /* - * reads always work, if if they don't. - * Just pretend any byte not read was actually a 0 - */ - if (res < 0) - memset(addr, 0, sectors * di->secsize); - else if (res < sectors * di->secsize) - memset(addr + res, 0, sectors * di->secsize - res); - - return(sectors); -} - -static int -diwrite(struct diskinfo *di, regcontext_t *REGS, - off_t start, char *addr, int sectors) -{ - off_t res; - int drive = di - diskinfo; - di->multi = -1; - - if (drive > 1) { - drive -= 2; - drive |= 0x80; - } - -again: - res = lseek(di->fd, start * di->secsize, 0); - - if (res < 0 && di->removeable && trynext(di)) - goto again; - - if (res < 0) { - seterror(INT13_ERR_SEEK); - return(-1); - } - - res = write(di->fd, addr, sectors * di->secsize); - - if (res < 0 && di->removeable && trynext(di)) - goto again; - - if (di->removeable) { - if (res < 0) { - seterror(INT13_ERR_NOT_READY); - return(-1); - } - } else if (res < 0) { - seterror(INT13_ERR_WRITE_PROTECT); - return(-1); - } - return(res / di->secsize); -} - -static void -int13(regcontext_t *REGS) -{ - char *addr; - int sectors; - struct diskinfo *di; - off_t start; - int did; - - int cyl; - int sector; - int side; - int drive; - - reset_poll(); - - R_FLAGS &= ~PSL_C; - - drive = R_DL; - - if (R_AX != 0x01) { - if (drive & 0x80) - hd_status = 0; - else - fd_status = 0; - } - - switch (R_AH) { - case 0x00: /* Reset */ - break; - case 0x01: /* Read disk status */ - if (drive & 0x80) - R_AH = hd_status; - else - R_AH = fd_status; - if (R_AH) - R_FLAGS |= PSL_C; - break; - case 0x02: /* Read */ - R_AH = 0; - addr = (char *)MAKEPTR(R_ES, R_BX); - sectors = R_AL; - side = R_DH; - R_AL = 0; /* Start out with nothing read */ - - if (drive & 0x80) { - cyl = R_CH | ((R_CL & 0xc0) << 2); - sector = (R_CL & 0x3f) - 1; - } else { - sector = R_CL - 1; - cyl = R_CH; - } - - if ((di = getdisk(drive)) == 0) { - debug(D_DISK, "Bad drive: %02x (%d : %d : %d)\n", - drive, cyl, side, sector); - seterror(INT13_ERR_BAD_COMMAND); - break; - } - start = cyl * di->sectors * di->sides + - side * di->sectors + - sector; - - if (start >= disize(di)) { - debug(D_DISK, "Read past end of disk\n"); - seterror(INT13_ERR_SEEK); - break; - } - if (sectors + start >= disize(di)) { - sectors = disize(di) - start; - } - - if (di->sector0) { - if (start < di->offset) { - R_AL = sectors; - if (start == 0) { - memcpy(addr, di->sector0, di->secsize); - addr += di->secsize; - --sectors; - } - memset(addr, 0, sectors * di->secsize); - break; - } else { - start -= di->offset; - } - } - debug(D_DISK, "%02x: Read %2d sectors from %qd to %04x:%04x\n", - drive, sectors, start, R_ES, R_BX); - - if ((did = diread(di, REGS, start, addr, sectors)) >= 0) - R_AL = did; -#if 0 - callint(0x0d); - callint(0x76); -#endif - break; - - case 0x03: /* Write */ - R_AH = 0; - addr = (char *)MAKEPTR(R_ES, R_BX); - sectors = R_AL; - side = R_DH; - R_AL = 0; /* Start out with nothing written */ - - if (drive & 0x80) { - cyl = R_CH | ((R_CL & 0xc0) << 2); - sector = (R_CL & 0x3f) - 1; - } else { - sector = R_CL - 1; - cyl = R_CH; - } - - if ((di = getdisk(drive)) == 0) { - debug(D_DISK, "Bad drive: %d (%d : %d : %d)\n", - drive, cyl, side, sector); - seterror(INT13_ERR_BAD_COMMAND); - break; - } - if (di->read_only) { - debug(D_DISK, "%02x: Attempt to write readonly disk\n", drive); - seterror(INT13_ERR_WRITE_PROTECT); - break; - } - start = cyl * di->sectors * di->sides + - side * di->sectors + - sector; - - if (start >= disize(di)) { - debug(D_DISK, "Write past end of disk\n"); - seterror(INT13_ERR_SEEK); - break; - } - - if (sectors + start >= disize(di)) - sectors = disize(di) - start; - - if (di->sector0) { - if (start < di->offset) { - R_AL = sectors; - break; - } else { - start -= di->offset; - } - } - - debug(D_DISK, "%02x: Write %2d sectors from %qd to %04x:%04x\n", - drive, sectors, start, R_ES, R_BX); - - if ((did = diwrite(di, REGS, start, addr, sectors)) >= 0) - R_AL = did; -#if 0 - callint(0x0d); - callint(0x76); -#endif - break; - - case 0x04: /* Verify */ - R_AH = 0; - sectors = R_AL; - side = R_DH; - - if (drive & 0x80) { - cyl = R_CH | ((R_CL & 0xc0) << 2); - sector = (R_CL & 0x3f) - 1; - } else { - sector = R_CL - 1; - cyl = R_CH; - } - - if ((di = getdisk(drive)) == 0) { - debug(D_DISK, "Bad drive: %d (%d : %d : %d)\n", - drive, cyl, side, sector); - seterror(INT13_ERR_BAD_COMMAND); - break; - } - start = cyl * di->sectors * di->sides + - side * di->sectors + - sector; - - if (start >= disize(di)) { - debug(D_DISK, "Verify past end of disk\n"); - seterror(INT13_ERR_SEEK); - break; - } - - if (sectors + start >= disize(di)) - sectors = disize(di) - start; - - if (di->sector0) { - if (start < di->offset) - break; - else - start -= di->offset; - } - - debug(D_DISK, "Verify %2d sectors from %qd\n", sectors, start); - if (lseek(di->fd, start * di->secsize, 0) < 0) { - debug(D_DISK, "Seek error\n"); - seterror(INT13_ERR_SEEK); - break; - } - while (sectors > 0) { - char buf[512]; - if (read(di->fd, buf, di->secsize) != di->secsize) { - debug(D_DISK, "Verify error\n"); - seterror(0x04); - break; - } - --sectors; - } -#if 0 - callint(0x0d); - callint(0x76); -#endif - break; - - case 0x05: /* Format track */ - seterror(INT13_ERR_BAD_COMMAND); - break; - - case 0x08: /* Status */ - R_AH = 0; - - if ((di = getdisk(drive)) == 0) { - debug(D_DISK, "Bad drive: %d\n", drive); - seterror(INT13_ERR_BAD_COMMAND); - break; - } - R_AX = 0; - - R_BX = di->type; - if ((drive & 0x80) == 0) - PUTVEC(R_ES, R_DI, di->location); - - R_CL = di->sectors | ((di->cylinders >> 2) & 0xc0); - R_CH = di->cylinders & 0xff; - R_DL = (drive & 0x80) ? ndisks : nfloppies; - R_DH = di->sides - 1; - debug(D_DISK, "%02x: Status requested: sec %d cyl %d side %d drive %d\n", - drive, R_CL, R_CH, R_DH, R_DL); -#if 0 - callint(0x0d); - callint(0x76); -#endif - break; - - case 0x0c: /* Move read/write head */ - case 0x0d: /* Reset */ - break; - - case 0x10: /* check for disk ready */ - R_AH = 0; /* always open for business */ - break; - - case 0x15: - if ((di = getdisk(drive)) == 0) { - R_AH = 0; - R_FLAGS |= PSL_C; - break; - } - - if (drive & 0x80) { - start = di->sectors * di->cylinders * di->sides; - R_CX = start >> 16; - R_DX = start; - R_AH = 3; - } else { - R_AH = 1; /* Non-changeable disk */ - } - break; - - case 0x16: /* Media change */ - R_AH = 0; - if ((di = getdisk(drive)) && di->changed) { - di->changed = 0; - R_AH = 6; - } - break; - - case 0x17: /* Determine floppy disk format */ - seterror(INT13_ERR_BAD_COMMAND); - break; - - case 0x18: /* Determine disk format */ - if ((di = getdisk(drive)) == 0) { - R_AH = 0; - R_FLAGS |= PSL_C; - break; - } - /* XXX incomplete? */ - break; - - default: - unknown_int2(0x13, R_AH, REGS); - break; - } -} - -void -disk_bios_init(void) -{ - u_long vec; - - vec = insert_softint_trampoline(); - ivec[0x13] = vec; - register_callback(vec, int13, "int 13"); - - vec = insert_null_trampoline(); - ivec[0x76] = vec; -} diff --git a/usr.bin/doscmd/int14.c b/usr.bin/doscmd/int14.c deleted file mode 100644 index 0edaeee..0000000 --- a/usr.bin/doscmd/int14.c +++ /dev/null @@ -1,689 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * This code is derived from software contributed to Berkeley Software - * Design, Inc. by Mark Linoman. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI int14.c,v 2.2 1996/04/08 19:32:45 bostic Exp - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/ioctl.h> -#include <sys/types.h> -#include <sys/uio.h> -#include <termios.h> -#include <unistd.h> - -#include "doscmd.h" -#include "AsyncIO.h" -#include "com.h" - -#define N_BYTES 1024 - -struct com_data_struct { - int fd; /* BSD/386 file descriptor */ - char *path; /* BSD/386 pathname */ - int addr; /* ISA I/O address */ - unsigned char irq; /* ISA IRQ */ - unsigned char inbuf[N_BYTES]; /* input buffer */ - unsigned char outbuf[N_BYTES];/* output buffer */ - int ids; /* input data size */ - int ods; /* output data size */ - int emptyint; - struct termios tty; - unsigned char div_latch[2]; /* mirror of 16550 R0':R1' - read/write */ - unsigned char int_enable; /* mirror of 16550 R1 read/write */ - unsigned char fifo_ctrl; /* mirror of 16550 R2 write only */ - unsigned char line_ctrl; /* mirror of 16550 R3 read/write */ - unsigned char modem_ctrl; /* mirror of 16550 R4 read/write */ - unsigned char modem_stat; /* mirror of 16550 R6 read/write */ - unsigned char uart_spare; /* mirror of 16550 R7 read/write */ -}; - -#define DIV_LATCH_LOW 0 -#define DIV_LATCH_HIGH 1 - -struct com_data_struct com_data[N_COMS_MAX]; - -static unsigned char com_port_in(int port); -static void com_port_out(int port, unsigned char val); -static void com_set_line(struct com_data_struct *cdsp, - unsigned char port, unsigned char param); - -static void -manage_int(struct com_data_struct *cdsp) -{ - if ((cdsp->int_enable & IE_RCV_DATA) && cdsp->ids > 0) { - hardint(cdsp->irq); - debug(D_PORT, "manage_int: hardint rd\n"); - return; - } - if ((cdsp->int_enable & IE_TRANS_HLD) && cdsp->emptyint) { - hardint(cdsp->irq); - debug(D_PORT, "manage_int: hardint wr\n"); - return; - } - unpend (cdsp->irq); -} - -static int -has_enough_data(struct com_data_struct *cdsp) -{ - switch (cdsp->fifo_ctrl & (FC_FIFO_EN | FC_FIFO_SZ_MASK)) { - case FC_FIFO_EN | FC_FIFO_4B: - return cdsp->ids >= 4; - case FC_FIFO_EN | FC_FIFO_8B: - return cdsp->ids >= 8; - case FC_FIFO_EN | FC_FIFO_14B: - return cdsp->ids >= 14; - } - return cdsp->ids; -} - -static void -input(struct com_data_struct *cdsp, int force_read) -{ - int nbytes; - - if (cdsp->ids < N_BYTES && (force_read || !has_enough_data(cdsp))) { - nbytes = read(cdsp->fd, &cdsp->inbuf[cdsp->ids], - N_BYTES - cdsp->ids); - debug(D_PORT, "read of fd %d on '%s' returned %d (%s)\n", - cdsp->fd, cdsp->path, nbytes, - nbytes == -1 ? strerror(errno) : ""); - if (nbytes != -1) - cdsp->ids += nbytes; - } -} - -static void -output(struct com_data_struct *cdsp) -{ - int nbytes; - - if (cdsp->ods > 0) { - nbytes = write(cdsp->fd, &cdsp->outbuf[0], cdsp->ods); - debug(D_PORT, "write of fd %d on '%s' returned %d (%s)\n", - cdsp->fd, cdsp->path, nbytes, - nbytes == -1 ? strerror(errno) : ""); - if (nbytes != -1) { - cdsp->ods -= nbytes; - memmove (&cdsp->outbuf[0], - &cdsp->outbuf[nbytes], cdsp->ods); - if ((cdsp->int_enable & IE_TRANS_HLD) - && cdsp->ods == 0) - cdsp->emptyint = 1; - } - } -} - -static void -flush_out(void* arg) -{ - struct com_data_struct *cdsp = (struct com_data_struct*)arg; - output(cdsp); - manage_int(cdsp); -} - -/* - * We postponed flush till the end of interrupt processing - * (see int.c). - */ -static int -write_char(struct com_data_struct *cdsp, char c) -{ - int r = 0; - cdsp->emptyint = 0; - if (cdsp->ods >= N_BYTES) - output(cdsp); - if (cdsp->ods < N_BYTES) { - cdsp->outbuf[cdsp->ods ++] = c; - if (!isinhardint(cdsp->irq)) - output(cdsp); - r = 1; - } - manage_int(cdsp); - return r; -} - -static int -read_char(struct com_data_struct *cdsp) -{ - int c = -1; - - input(cdsp, 0); - - if (cdsp->ids > 0) { - c = cdsp->inbuf[0]; - cdsp->ids --; - memmove(&cdsp->inbuf[0], &cdsp->inbuf[1], cdsp->ids); - } - - manage_int(cdsp); - - debug(D_PORT, "read_char: %x\n", c); - return c; -} - -static void -new_ii(struct com_data_struct *cdsp) -{ - if ((cdsp->int_enable & IE_TRANS_HLD) && cdsp->ods == 0) - cdsp->emptyint = 1; - manage_int(cdsp); -} - -static unsigned char -get_status(struct com_data_struct *cdsp) -{ - unsigned char s = (LS_X_DATA_E | LS_X_HOLD_E); - if (cdsp->ids > 0) - s |= LS_RCV_DATA_RD; - if (cdsp->ods > 0) { - s &= ~LS_X_DATA_E; - if (cdsp->ods >= N_BYTES) - s &= ~LS_X_HOLD_E; - } - debug(D_PORT, "get_status: %x\n", (unsigned)s); - return s; -} - -static unsigned char -get_int_id(struct com_data_struct *cdsp) -{ - unsigned char s = II_PEND_INT; - if (cdsp->fifo_ctrl & FC_FIFO_EN) - s |= II_FIFOS_EN; - if ((cdsp->int_enable & IE_RCV_DATA) && cdsp->ids > 0) { - if (has_enough_data(cdsp)) - s = (s & ~II_PEND_INT) | II_RCV_DATA; - else - s = (s & ~II_PEND_INT) | II_TO; - } else - if ((cdsp->int_enable & IE_TRANS_HLD) && cdsp->emptyint) { - cdsp->emptyint = 0; - s = (s & ~II_PEND_INT) | II_TRANS_HLD; - } - debug(D_PORT, "get_int_id: %x\n", (unsigned)s); - return s; -} - -static void -com_async(int fd __unused, int cond, void *arg, regcontext_t *REGS __unused) -{ - struct com_data_struct *cdsp = (struct com_data_struct*) arg; - - debug(D_PORT, "com_async: %X.\n", cond); - - if (cond & AS_RD) - input(cdsp, 1); - if (cond & AS_WR) - output(cdsp); - manage_int(cdsp); -} - -void -int14(regcontext_t *REGS) -{ - struct com_data_struct *cdsp; - int i; - - debug(D_PORT, "int14: dl = 0x%02X, al = 0x%02X.\n", R_DL, R_AL); - if (R_DL >= N_COMS_MAX) { - if (vflag) - dump_regs(REGS); - fatal ("int14: illegal com port COM%d", R_DL + 1); - } - cdsp = &(com_data[R_DL]); - - switch (R_AH) { - case 0x00: /* Initialize Serial Port */ - com_set_line(cdsp, R_DL + 1, R_AL); - R_AH = get_status(cdsp); - R_AL = 0; - break; - - case 0x01: /* Write Character */ - if (write_char(cdsp, R_AL)) { - R_AH = get_status(cdsp); - R_AL = 0; - } else { - debug(D_PORT, "int14: lost output character 0x%02x\n", R_AL); - R_AH = LS_SW_TIME_OUT; - R_AL = 0; - } - break; - - case 0x02: /* Read Character */ - i = read_char(cdsp); - if (i != -1) { - R_AH = get_status(cdsp); - R_AL = (char)i; - } else { - R_AH = LS_SW_TIME_OUT; - R_AL = 0x60; - } - break; - - case 0x03: /* Status Request */ - R_AH = get_status(cdsp); - R_AL = 0; - break; - - case 0x04: /* Extended Initialization */ - R_AX = (LS_SW_TIME_OUT) << 8; - break; - - case 0x05: /* Modem Control Register operations */ - switch (R_AH) { - case 0x00: /* Read Modem Control Register */ - R_AX = (LS_SW_TIME_OUT) << 8; - break; - - case 0x01: /* Write Modem Control Register */ - R_AX = (LS_SW_TIME_OUT) << 8; - break; - - default: - unknown_int3(0x14, 0x05, R_AL, REGS); - break; - } - break; - default: - unknown_int2(0x14, R_AH, REGS); - break; - } -} - - -/* called when doscmd initializes a single line */ -static void -com_set_line(struct com_data_struct *cdsp, unsigned char port, unsigned char param) -{ - struct stat stat_buf; - int mode = 0; /* read | write */ - int reg_num, ret_val, spd, speed; - u_int8_t div_hi, div_lo; - - debug(D_PORT, "com_set_line: cdsp = %8p, port = 0x%04x," - "param = 0x%04X.\n", cdsp, port, param); - if (cdsp->fd > 0) { - debug(D_PORT, "Re-initialize serial port com%d\n", port); - _RegisterIO(cdsp->fd, 0, 0, 0); - (void)close(cdsp->fd); - } else { - debug(D_PORT, "Initialize serial port com%d\n", port); - } - - stat(cdsp->path, &stat_buf); - if (!S_ISCHR(stat_buf.st_mode) || - ((cdsp->fd = open(cdsp->path, O_RDWR | O_NONBLOCK, 0666)) == -1)) { - - debug(D_PORT, - "Could not initialize serial port com%d on path '%s'\n", - port, cdsp->path); - return; - } - - cdsp->ids = cdsp->ods = cdsp->emptyint = 0; - cdsp->int_enable = 0; - cdsp->fifo_ctrl = 0; - cdsp->modem_ctrl = 0; - cdsp->modem_stat = 0; - cdsp->uart_spare = 0; - - if ((param & PARITY_EVEN) == PARITY_NONE) - cdsp->tty.c_iflag = IGNBRK | IGNPAR /* | IXON | IXOFF | IXANY */; - else - cdsp->tty.c_iflag = IGNBRK /* | IXON | IXOFF | IXANY */; - cdsp->tty.c_oflag = 0; - cdsp->tty.c_lflag = 0; - cdsp->tty.c_cc[VTIME] = 0; - cdsp->tty.c_cc[VMIN] = 0; - cdsp->tty.c_cflag = CREAD | CLOCAL | HUPCL; - /* MCL WHY CLOCAL ??????; but, gets errno EIO on writes, else */ - if ((param & TXLEN_8BITS) == TXLEN_8BITS) { - cdsp->tty.c_cflag |= CS8; - cdsp->line_ctrl |= 3; - } else { - cdsp->tty.c_cflag |= CS7; - cdsp->line_ctrl |= 2; - } - if ((param & STOPBIT_2) == STOPBIT_2) { - cdsp->tty.c_cflag |= CSTOPB; - cdsp->line_ctrl |= LC_STOP_B; - } else { - cdsp->tty.c_cflag &= ~CSTOPB; - cdsp->line_ctrl &= ~LC_STOP_B; - } - switch (param & PARITY_EVEN) { - case PARITY_ODD: - cdsp->tty.c_cflag |= (PARENB | PARODD); - cdsp->line_ctrl &= ~LC_EVEN_P; - cdsp->line_ctrl |= LC_PAR_E; - break; - case PARITY_EVEN: - cdsp->tty.c_cflag |= PARENB; - cdsp->line_ctrl |= LC_EVEN_P | LC_PAR_E; - break; - case PARITY_NONE: - cdsp->line_ctrl &= ~LC_PAR_E; - default: - break; - } - switch (param & BITRATE_9600) { - case BITRATE_110: - speed = B110; - spd = 110; - break; - case BITRATE_150: - speed = B150; - spd = 150; - break; - case BITRATE_300: - speed = B300; - spd = 300; - break; - case BITRATE_600: - speed = B600; - spd = 600; - break; - case BITRATE_1200: - speed = B1200; - spd = 1200; - break; - case BITRATE_2400: - speed = B2400; - spd = 2400; - break; - case BITRATE_4800: - speed = B4800; - spd = 4800; - break; - case BITRATE_9600: - speed = B9600; - spd = 9600; - break; - } - debug(D_PORT, - "com_set_line: going with cflag 0x%X iflag 0x%X speed %d.\n", - cdsp->tty.c_cflag, cdsp->tty.c_iflag, speed); - div_lo = (115200 / spd) & 0x00ff; - div_hi = (115200 / spd) & 0xff00; - cdsp->div_latch[DIV_LATCH_LOW] = div_lo; - cdsp->div_latch[DIV_LATCH_HIGH] = div_hi; - errno = 0; - ret_val = cfsetispeed(&cdsp->tty, speed); - debug(D_PORT, "com_set_line: cfsetispeed returned 0x%X.\n", ret_val); - errno = 0; - ret_val = cfsetospeed(&cdsp->tty, speed); - debug(D_PORT, "com_set_line: cfsetospeed returned 0x%X.\n", ret_val); - errno = 0; - ret_val = tcsetattr(cdsp->fd, 0, &cdsp->tty); - debug(D_PORT, "com_set_line: tcsetattr returned 0x%X (%s).\n", - ret_val, ret_val == -1 ? strerror(errno) : ""); - errno = 0; - ret_val = fcntl(cdsp->fd, F_SETFL, O_NDELAY); - debug(D_PORT, "fcntl of 0x%X, 0x%X to fd %d returned %d errno %d\n", - F_SETFL, O_NDELAY, cdsp->fd, ret_val, errno); - errno = 0; - ret_val = ioctl(cdsp->fd, TIOCFLUSH, &mode); - debug(D_PORT, "ioctl of 0x%02lx to fd %d on 0x%X returned %d errno %d\n", - TIOCFLUSH, cdsp->fd, mode, ret_val, errno); - for (reg_num = 0; reg_num < N_OF_COM_REGS; reg_num++) { - define_input_port_handler(cdsp->addr + reg_num, com_port_in); - define_output_port_handler(cdsp->addr + reg_num, com_port_out); - } - debug(D_PORT, "com%d: attached '%s' at addr 0x%04x irq %d\n", - port, cdsp->path, cdsp->addr, cdsp->irq); - - set_eoir(cdsp->irq, flush_out, cdsp); - _RegisterIO(cdsp->fd, com_async, cdsp, 0); -} - -static void -try_set_speed(struct com_data_struct *cdsp) -{ - unsigned divisor, speed; - int ret_val; - - divisor = (unsigned) cdsp->div_latch[DIV_LATCH_HIGH] << 8 - | (unsigned) cdsp->div_latch[DIV_LATCH_LOW]; - - debug(D_PORT, "try_set_speed: divisor = %u\n", divisor); - - if (divisor == 0) - return; - - speed = 115200 / divisor; - if (speed == 0) - return; - - errno = 0; - ret_val = cfsetispeed(&cdsp->tty, speed); - debug(D_PORT, "try_set_speed: cfsetispeed returned 0x%X.\n", ret_val); - - errno = 0; - ret_val = cfsetospeed(&cdsp->tty, speed); - debug(D_PORT, "try_set_speed: cfsetospeed returned 0x%X.\n", ret_val); - - errno = 0; - ret_val = tcsetattr(cdsp->fd, 0, &cdsp->tty); - debug(D_PORT, "try_set_speed: tcsetattr returned 0x%X (%s).\n", ret_val, - ret_val == -1 ? strerror (errno) : ""); -} - -/* called when config.c initializes a single line */ -void -init_com(int port, char *path, int addr, unsigned char irq) -{ - struct com_data_struct *cdsp; - - debug(D_PORT, "init_com: port = 0x%04x, addr = 0x%04X, irq = %d.\n", - port, addr, irq); - cdsp = &(com_data[port]); - cdsp->path = path; /* XXX DEBUG strcpy? */ - cdsp->addr = addr; - cdsp->irq = irq; - cdsp->fd = -1; - com_set_line(cdsp, port + 1, TXLEN_8BITS | BITRATE_9600); - - /* update BIOS variables */ - nserial++; - *(u_int16_t *)&BIOSDATA[0x00 + 2 * port] = (u_int16_t)addr; -} - -/* called when DOS wants to read directly from a physical port */ -unsigned char -com_port_in(int port) -{ - struct com_data_struct *cdsp; - unsigned char rs; - unsigned char i; - int r; - - /* search for a valid COM ???or MOUSE??? port */ - for (i = 0; i < N_COMS_MAX; i++) { - if (com_data[i].addr == ((unsigned short)port & 0xfff8)) { - cdsp = &(com_data[i]); - break; - } - } - if (i == N_COMS_MAX) { - debug(D_PORT, "com port 0x%04x not found\n", port); - return 0xff; - } - - switch (port - cdsp->addr) { - /* 0x03F8 - (receive buffer) or (divisor latch LO) */ - case 0: - if (cdsp->line_ctrl & LC_DIV_ACC) - rs = cdsp->div_latch[DIV_LATCH_LOW]; - else { - rs = 0x60; - r = read_char(cdsp); - if (r != -1) - rs = (unsigned char)r; - } - break; - - /* 0x03F9 - (interrupt enable) or (divisor latch HI) */ - case 1: - if (cdsp->line_ctrl & LC_DIV_ACC) - rs = cdsp->div_latch[DIV_LATCH_HIGH]; - else - rs = cdsp->int_enable; - break; - - /* 0x03FA - interrupt identification register */ - case 2: - rs = get_int_id(cdsp); - break; - - /* 0x03FB - line control register */ - case 3: - rs = cdsp->line_ctrl; - break; - - /* 0x03FC - modem control register */ - case 4: - rs = cdsp->modem_ctrl; - break; - - /* 0x03FD - line status register */ - case 5: - rs = get_status(cdsp); - break; - - /* 0x03FE - modem status register */ - case 6: - rs = cdsp->modem_stat | MS_DCD | MS_DSR | MS_CTS; - break; - - /* 0x03FF - spare register */ - case 7: - rs = cdsp->uart_spare; - break; - - default: - debug(D_PORT, "com_port_in: illegal port index 0x%04x - 0x%04x\n", - port, cdsp->addr); - break; - } - return rs; -} - -/* called when DOS wants to write directly to a physical port */ -void -com_port_out(int port, unsigned char val) -{ - struct com_data_struct *cdsp; - int i; - - /* search for a valid COM ???or MOUSE??? port */ - for (i = 0; i < N_COMS_MAX; i++) { - if (com_data[i].addr == ((unsigned short)port & 0xfff8)) { - cdsp = &(com_data[i]); - break; - } - } - if (i == N_COMS_MAX) { - debug(D_PORT, "com port 0x%04x not found\n", port); - return; - } - - switch (port - cdsp->addr) { - /* 0x03F8 - (transmit buffer) or (divisor latch LO) */ - case 0: - if (cdsp->line_ctrl & LC_DIV_ACC) { - cdsp->div_latch[DIV_LATCH_LOW] = val; - try_set_speed(cdsp); - } else { - write_char(cdsp, val); - } - break; - - /* 0x03F9 - (interrupt enable) or (divisor latch HI) */ - case 1: - if (cdsp->line_ctrl & LC_DIV_ACC) { - cdsp->div_latch[DIV_LATCH_HIGH] = val; - try_set_speed(cdsp); - } else { - cdsp->int_enable = val; - new_ii(cdsp); - } - break; - - /* 0x03FA - FIFO control register */ - case 2: - cdsp->fifo_ctrl = val & (FC_FIFO_EN | FC_FIFO_SZ_MASK); - if (val & FC_FIFO_CRV) - cdsp->ids = 0; - if (val & FC_FIFO_CTR) { - cdsp->ods = 0; - cdsp->emptyint = 1; - } - input(cdsp, 1); - manage_int(cdsp); - break; - - /* 0x03FB - line control register */ - case 3: - cdsp->line_ctrl = val; - break; - - /* 0x03FC - modem control register */ - case 4: - cdsp->modem_ctrl = val; - break; - - /* 0x03FD - line status register */ - case 5: - /* read-only */ - break; - - /* 0x03FE - modem status register */ - case 6: - cdsp->modem_stat = val; - break; - - /* 0x03FF - spare register */ - case 7: - cdsp->uart_spare = val; - break; - - default: - debug(D_PORT, "com_port_out: illegal port index 0x%04x - 0x%04x\n", - port, cdsp->addr); - break; - } -} diff --git a/usr.bin/doscmd/int16.c b/usr.bin/doscmd/int16.c deleted file mode 100644 index 920cd15..0000000 --- a/usr.bin/doscmd/int16.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI int16.c,v 2.2 1996/04/08 19:32:47 bostic Exp - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include "doscmd.h" -#include "tty.h" - -#define K_NEXT *(u_short *)0x41a -#define K_FREE *(u_short *)0x41c - -#define HWM 16 -volatile int poll_cnt = 0; - -void -wakeup_poll(void) -{ - if (poll_cnt <= 0) - poll_cnt = HWM; -} - -void -reset_poll(void) -{ - poll_cnt = HWM; -} - -void -sleep_poll(void) -{ -#if 0 - printf("sleep_poll: poll_cnt=%d\n", poll_cnt); - if (poll_cnt == 14) - tmode = 1; -#endif - if (--poll_cnt <= 0) { - poll_cnt = 0; - while (KbdEmpty() && poll_cnt <= 0) { -#if 0 - softint(0x28); -#endif - if (KbdEmpty() && poll_cnt <= 0) - tty_pause(); - } - } -} - -void -int16(regcontext_t *REGS) -{ - if (!xmode && !raw_kbd) { - if (vflag) dump_regs(REGS); - fatal ("int16 func 0x%x only supported in X mode\n", R_AH); - } - switch(R_AH) { - case 0x00: - case 0x10: /* Get enhanced keystroke */ - poll_cnt = 16; - while (KbdEmpty()) - tty_pause(); - R_AX = KbdRead(); - break; - - case 0x01: /* Get keystroke */ - case 0x11: /* Get enhanced keystroke */ - if (KbdEmpty()) { - R_FLAGS |= PSL_Z; - break; - } - R_FLAGS &= ~PSL_Z; - R_AX = KbdPeek(); - break; - - case 0x02: - R_AL = tty_state(); - break; - - case 0x12: - R_AH = tty_estate(); - R_AL = tty_state(); - break; - - case 0x03: /* Set typematic and delay rate */ - break; - - case 0x05: - KbdWrite(R_CX); - break; - - case 0x55: - R_AX = 0x43af; /* Empirical value ... */ - break; - - case 0x92: - R_AH = 0x00; - break; - - case 0xa2: - debug(D_HALF, "122-key keyboard support check\n"); - break; - - default: - unknown_int2(0x16, R_AH, REGS); - break; - } -} diff --git a/usr.bin/doscmd/int17.c b/usr.bin/doscmd/int17.c deleted file mode 100644 index c5699b8..0000000 --- a/usr.bin/doscmd/int17.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI int17.c,v 2.2 1996/04/08 19:32:48 bostic Exp - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/types.h> -#include <sys/uio.h> -#include <paths.h> -#include <signal.h> -#include <unistd.h> - -#include "doscmd.h" - -static int lpt_fd[4] = { -1, -1, -1, -1, }; -static FILE *lpt_file[4] = { 0, 0, 0, 0}; -static int direct[4] = { 0, 0, 0, 0}; -static char *queue[4] = { 0, 0, 0, 0}; -static int timeout[4] = { 30, 30, 30, 30 }; -static int last_poll[4] = { 0, 0, 0, 0}; -static int last_count[4] = { 0, 0, 0, 0}; -static int current_count[4] = { 0, 0, 0, 0}; - -static void open_printer(int printer); - -void -int17(regcontext_t *REGS) -{ - int fd; - u_char c; - - switch (R_AH) { - - case 0x00: - reset_poll(); - - fd = lpt_fd[R_DX]; - if (fd == -1) { - open_printer(R_DX); - fd = lpt_fd[R_DX]; - } - if (fd >= 0) { - c = R_AL; - write(fd, &c, 1); - } - R_AH = 0x90; /* printed selected */ - current_count[R_DX]++; - break; - - case 0x01: - case 0x02: - R_AH = 0x90; - break; - - default: - unknown_int2(0x17, R_AH, REGS); - break; - } -} - -void -lpt_poll(void) -{ - int i; - int current; - - current = time(0); - - for(i=0; i < 4; i++) { - if (lpt_fd[i] < 0) - continue; - - if (current - last_poll[i] < timeout[i]) - continue; - - last_poll[i] = current; - - if (last_count[i] == current_count[i]) { - if (direct[i]) { - debug(D_PRINTER, "Closing printer %d\n", i); - close(lpt_fd[i]); - } else { - debug(D_PRINTER, "Closing spool printer %d\n", i); - pclose(lpt_file[i]); - } - lpt_fd[i] = -1; - lpt_file[i] = 0; - } - - last_count[i] = current_count[i]; - } -} - - -static void -open_printer(int printer) -{ - char printer_name[80]; - char command[120]; - int fd; - FILE *file; - char *p; - - /* - * if printer is direct then open output device. - */ - if (direct[printer]) { - if ((p = queue[printer]) != 0) { - if ((fd = open(p, O_WRONLY|O_APPEND|O_CREAT, 0666)) < 0) { - perror(p); - return; - } - } else { - sprintf(printer_name, "%slpt%d", _PATH_DEV, printer); - debug(D_PRINTER, "Opening device %s\n", printer_name); - if ((fd = open(printer_name, O_WRONLY)) < 0) { - perror(printer_name); - return; - } - } - lpt_fd[printer] = fd; - return; - } - - /* - * If printer is a spooled device then open pipe to spooled device - */ - if (queue[printer]) { - strncpy(printer_name, queue[printer], sizeof(printer_name)); - printer_name[sizeof(printer_name) - 1] = '\0'; - } else - strcpy(printer_name, "lp"); - - snprintf(command, sizeof(command), "lpr -P %s", printer_name); - debug(D_PRINTER, "opening pipe to %s\n", printer_name); - - if ((file = popen(command, "w")) == 0) { - perror(command); - return; - } - lpt_file[printer] = file; - lpt_fd[printer] = fileno(file); -} - -void -printer_direct(int printer) -{ - direct[printer] = 1; -} - -void -printer_spool(int printer, char *print_queue) -{ - queue[printer] = print_queue ? strdup(print_queue) : 0; -} - -void -printer_timeout(int printer, char *time_out) -{ - if (atoi(time_out) <= 0) { - fprintf(stderr, "Bad timeout value on lpt%d:\n", printer+1); - quit(1); - } - timeout[printer] = atoi(time_out); -} diff --git a/usr.bin/doscmd/int1a.c b/usr.bin/doscmd/int1a.c deleted file mode 100644 index abd1929..0000000 --- a/usr.bin/doscmd/int1a.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI int1a.c,v 2.2 1996/04/08 19:32:49 bostic Exp - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include "doscmd.h" - -static __inline int -to_BCD (int n) -{ - n &= 0xFF; - return n%10 + ((n/10)<<4); -} - -void -int1a(regcontext_t *REGS) -{ - struct timeval tod; - struct timezone zone; - struct tm *tm; - time_t tv_sec; - long value; - static long midnight = 0; - - R_FLAGS &= ~PSL_C; - - switch (R_AH) { - case 0x00: - gettimeofday(&tod, &zone); - - if (midnight == 0) { - tv_sec = boot_time.tv_sec; - tm = localtime(&tv_sec); - midnight = boot_time.tv_sec - (((tm->tm_hour * 60) - + tm->tm_min) * 60 - + tm->tm_sec); - } - - R_AL = (tod.tv_sec - midnight) / (24 * 60 * 60); - - if (R_AL) { - tv_sec = boot_time.tv_sec; - tm = localtime(&tv_sec); - midnight = boot_time.tv_sec - (((tm->tm_hour * 60) - + tm->tm_min) * 60 - + tm->tm_sec); - } - - tod.tv_sec -= midnight; - tod.tv_usec -= boot_time.tv_usec; - - value = (tod.tv_sec * 182 + tod.tv_usec / (1000000L/182)) / 10; - R_CX = value >> 16; - R_DX = value & 0xffff; - break; - - case 0x01: /* set current clock count */ - tv_sec = boot_time.tv_sec; - tm = localtime(&tv_sec); - midnight = boot_time.tv_sec - (((tm->tm_hour * 60) - + tm->tm_min) * 60 + tm->tm_sec); - break; - - case 0x02: - gettimeofday(&tod, &zone); - tv_sec = tod.tv_sec; - tm = localtime(&tv_sec); - R_CH = to_BCD(tm->tm_hour); - R_CL = to_BCD(tm->tm_min); - R_DH = to_BCD(tm->tm_sec); - break; - - case 0x04: - gettimeofday(&tod, &zone); - tv_sec = tod.tv_sec; - tm = localtime(&tv_sec); - R_CH = to_BCD((tm->tm_year + 1900) / 100); - R_CL = to_BCD((tm->tm_year + 1900) % 100); - R_DH = to_BCD(tm->tm_mon + 1); - R_DL = to_BCD(tm->tm_mday); - break; - - default: - unknown_int2(0x1a, R_AH, REGS); - break; - } -} diff --git a/usr.bin/doscmd/int2f.c b/usr.bin/doscmd/int2f.c deleted file mode 100644 index 4ac5349..0000000 --- a/usr.bin/doscmd/int2f.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI int2f.c,v 2.2 1996/04/08 19:32:53 bostic Exp - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include "doscmd.h" -#include "dispatch.h" -#include "tty.h" - -/* -** Multiplex interrupt. -** -** subfunctions 0-0x7f reserved for DOS, some are implemented here. -** -*/ - -/* -** 2f:00 2f:01 2f:02 2f:03 -** -** Various PRINT.COM functions -*/ -static int -int2f_printer(regcontext_t *REGS) -{ - debug (D_FILE_OPS, "Called printer function 0x%02x", R_AH); - R_AL = FUNC_NUM_IVALID; - return(0); -} - -/* -** 2f:12 -** -** DOS internal functions. Only one we support is 0x2e, and then only to -** complain about it. -*/ -static int -int2f_dosinternal(regcontext_t *REGS) -{ - switch (R_AL) { - case 0x2e: /* XXX - GET/SET ERROR TABLE ADDRESSES */ - switch (R_DL) { - case 0x00: - case 0x02: - case 0x04: - case 0x06: - debug(D_ALWAYS,"DOS program attempted to get internal error table.\n"); - break; - - case 0x01: - case 0x03: - case 0x05: - case 0x07: - case 0x09: - debug(D_ALWAYS,"DOS program attempted to set error table.\n"); - break; - } - - default: - unknown_int4(0x2f, 0x12, R_AL, R_DL, REGS); - break; - } - R_AL = FUNC_NUM_IVALID; - return(0); -} - -/* -** 2f:16 -** -** Windows Enhanced Mode functions. Aigh! -*/ -static int -int2f_windows(regcontext_t *REGS) -{ - switch (R_AL) { - case 0x00: - R_AL = 0x00; /* Neither Win 3.x nor 2.x running */ - return(0); - - case 0x80: /* installation check */ - tty_pause(); - R_AL = 0x00; - return(0); - - default: - unknown_int3(0x2f, 0x16, R_AL, REGS); - break; - } - R_AL = FUNC_NUM_IVALID; - return(0); -} - -/* -** 2f:43 -** -** XMS interface -*/ -static int -int2f_xms(regcontext_t *REGS) -{ - switch(R_AL) { - case 0: /* installation check */ - return(0); /* %al = 0 */ - default: - R_AL = FUNC_NUM_IVALID; - return(0); - } -} - - -static struct intfunc_table int2f_table[] = { - - { 0x00, IFT_NOSUBFUNC, int2f_printer, "printer"}, - { 0x01, IFT_NOSUBFUNC, int2f_printer, "printer"}, - { 0x02, IFT_NOSUBFUNC, int2f_printer, "printer"}, - { 0x03, IFT_NOSUBFUNC, int2f_printer, "printer"}, - { 0x12, IFT_NOSUBFUNC, int2f_dosinternal, "DOS internal function"}, - { 0x16, IFT_NOSUBFUNC, int2f_windows, "Windows detect"}, - { 0x43, IFT_NOSUBFUNC, int2f_xms, "XMS"}, - { -1, 0, NULL, NULL} -}; - -/* -** int2f (multiplex) handler. -** -** Note that due to the widely varied and inconsistent conventions, handlers -** called from here are expected to manage their own return values. -*/ -void -int2f(regcontext_t *REGS) -{ - int idx; - - /* look up the handler for the current function */ - idx = intfunc_search(int2f_table, R_AH, R_AL); - - if (idx >= 0) { /* respond on multiplex chain */ - int2f_table[idx].handler(REGS); - } else { - unknown_int2(0x2f, R_AH, REGS); - } -} - - - diff --git a/usr.bin/doscmd/intff.c b/usr.bin/doscmd/intff.c deleted file mode 100644 index a86bbc3..0000000 --- a/usr.bin/doscmd/intff.c +++ /dev/null @@ -1,808 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI intff.c,v 2.2 1996/04/08 19:32:56 bostic Exp - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <ctype.h> -#include <unistd.h> - -#include "doscmd.h" -#include "cwd.h" -#include "dispatch.h" - -static LOL *lol = 0; /* DOS list-of-lists */ -static SDA *sda = 0; /* DOS swappable data area */ - -/****************************************************************************** -** redirector functions -** -** -** These are set up on entry to the redirector each time, and are referenced -** by the functions here. -*/ -static int r_drive,n_drive = 0; -static CDS *r_cds; -static SFT *r_sft; - - -/* -** 2f:11:0 -** -** Installation check -*/ -static int -int2f11_00(regcontext_t *REGS) -{ - R_AL = 0xff; - R_AH = 'U'; /* and why not? 8) */ - return(0); -} - -/* -** 2f:11:1 2f:11:2 2f:11:3 2f:11:4 2f:11:5 2f:11:11 2f:11:13 -** -** Directory functions -*/ -static int -int2f11_dirfn(regcontext_t *REGS) -{ - char fname[PATH_MAX], tname[PATH_MAX]; - int error; - - error = translate_filename(sda->filename1, fname, &r_drive); - if (error) - return(error); - - if (dos_readonly(r_drive) && (R_AL != 0x05)) - return(WRITE_PROT_DISK); - - switch(R_AL) { - case 0x01: /* rmdir */ - case 0x02: - debug(D_REDIR,"rmdir(%s)\n",fname); - error = rmdir(fname); - break; - case 0x03: /* mkdir */ - case 0x04: - debug(D_REDIR,"mkdir(%s)\n",fname); - error = mkdir(fname,0777); - break; - case 0x05: /* chdir */ - debug(D_REDIR,"chdir(%s)\n",fname); - /* Note returns DOS error directly */ - return(dos_setcwd(sda->filename1)); - - case 0x11: /* rename */ - error = translate_filename(sda->filename2, tname, &r_drive); - if (!error) { - debug(D_REDIR,"rename(%s,%s)\n",fname,tname); - error = rename(fname, tname); - } - break; - - case 0x13: /* unlink */ - debug(D_REDIR,"unlink(%s)\n",fname); - error = unlink(fname); - break; - - default: - fatal("called int2f11_dirfn on unknown function %x\n",R_AL); - } - - if (error < 0) { - switch(errno) { - case ENOTDIR: - case ENOENT: - return(PATH_NOT_FOUND); - case EXDEV: - return(NOT_SAME_DEV); - default: - return(ACCESS_DENIED); - } - } - return(0); -} - -/* -** 2f:11:6 -** -** Close -*/ -static int -int2f11_close(regcontext_t *REGS __unused) -{ - int fd; - - fd = r_sft->fd; - debug(D_REDIR, "close(%d)\n", fd); - - r_sft->nfiles--; - if (r_sft->nfiles) { - debug(D_REDIR, "not last close\n"); - return(0); - } - if (close(fd) < 0) - return(HANDLE_INVALID); - return(0); -} - -/* -** 2f:11:8 2f:11:9 -** -** read/write -*/ -static int -int2f11_rdwr(regcontext_t *REGS __unused) -{ - int fd; - char *addr; - int nbytes; - int n; - - fd = r_sft->fd; - if (lseek(fd, r_sft->offset, SEEK_SET) < 0) - return(SEEK_ERROR); - - addr = (char *)MAKEPTR(sda->dta_seg, sda->dta_off); - nbytes = R_CX; - - switch(R_AL) { - case 0x08: /* read */ - debug(D_REDIR, "read(%d, %d)\n", fd, nbytes); - n = read(fd, addr, nbytes); - if (n < 0) - return(READ_FAULT); - break; - case 0x09: - debug(D_REDIR, "write(%d, %d)\n", fd, nbytes); - n = write(fd, addr, nbytes); - if (n < 0) - return(WRITE_FAULT); - break; - default: - fatal("called int2f11_rdwr on unknown function %x\n",R_AL); - } - - R_CX = n; /* report count */ - r_sft->offset += n; - if (r_sft->offset > r_sft->size) - r_sft->size = r_sft->offset; - debug(D_REDIR, "offset now %ld\n", r_sft->offset); - return(0); -} - -/* -** 2f:11:c -** -** Get free space (like 21:36) -*/ -static int -int2f11_free(regcontext_t *REGS __unused) -{ - fsstat_t fs; - int error; - - error = get_space(r_drive, &fs); - if (error) - return (error); - R_AX = fs.sectors_cluster; - R_BX = fs.total_clusters; - R_CX = fs.bytes_sector; - R_DX = fs.avail_clusters; - return(0); -} - -/* -** 2f:11:f -** -** get size and mode -*/ -static int -int2f11_stat(regcontext_t *REGS __unused) -{ - char fname[PATH_MAX]; - struct stat sb; - int error; - - error = translate_filename(sda->filename1, fname, &r_drive); - if (error) - return(error); - - if (stat(fname, &sb) < 0) - return(FILE_NOT_FOUND); - - R_AX = to_dos_attr(sb.st_mode); - R_BX = sb.st_size >> 16; - R_DI = sb.st_size & 0xffff; - return(0); -} - -/* -** 2f:11:16 2f:11:17 2f:11:18 2f:11:2e -** -** Open/create a file, closely resembles int21_open. -*/ -static int -int2f11_open(regcontext_t *REGS) -{ - char fname[PATH_MAX]; - struct stat sb; - int error; - int mode; /* open mode */ - int attr; /* attributes of created file */ - int action; /* what to do about file */ - u_char *p, *e; - int i; - int omode; /* mode to say we opened in */ - int status; - int fd; - - error = translate_filename(sda->filename1, fname, &r_drive); - if (error) - return(error); - - /* - ** get attributes/access mode off stack : low byte is attribute, high - ** byte is (sometimes) used in conjunction with 'action' - */ - attr = *(u_short *)MAKEPTR(R_SS, R_SP) & 0xff; - - /* which style? */ - switch(R_AL) { - case 0x16: /* open */ - action = 0x01; /* fail if does not exist */ - switch (sda->open_mode & 3) { - case 0: - mode = O_RDONLY; - break; - case 1: - mode = O_WRONLY; - break; - case 2: - mode = O_RDWR; - break; - default: - return (FUNC_NUM_IVALID); - } - omode = sda->open_mode & 0x7f; - debug(D_REDIR,"open"); - break; - - case 0x17: /* creat/creat new */ - case 0x18: /* creat/creat new (no CDS, but we don't care)*/ - mode = O_RDWR; - omode = 3; - if (attr & 0x100) { /* creat new */ - action = 0x10; /* create if not exist, fail if exists */ - debug(D_REDIR, "creat_new"); - } else { /* creat */ - action = 0x12; /* create and destroy */ - debug(D_REDIR, "creat"); - } - break; - - case 0x2e: /* multipurpose */ - attr = sda->ext_attr; - action = sda->ext_action; - switch (sda->ext_mode & 3) { - case 0: - mode = O_RDONLY; - break; - case 1: - mode = O_WRONLY; - break; - case 2: - mode = O_RDWR; - break; - default: - return (FUNC_NUM_IVALID); - } - omode = sda->ext_mode & 0x7f; - debug(D_REDIR,"mopen"); - break; - - default: - fatal("called int2f11_open for unknown function %x\n",R_AL); - } - if (action & 0x02) /* replace/open mode */ - mode |= O_TRUNC; - debug(D_REDIR, "(%s) action 0x%x mode 0x%x attr 0x%x omode 0x%x \n", - fname, action, mode, attr, omode); - - if (ustat(fname, &sb) < 0) { /* file does not exist */ - if ((action & 0x10) || (attr & 0x100)) { /* create it */ - sb.st_ino = 0; - mode |= O_CREAT; /* have to create as we go */ - status = 0x02; /* file created */ - } else { - return(FILE_NOT_FOUND); /* fail */ - } - } else { - if (S_ISDIR(sb.st_mode)) - return(ACCESS_DENIED); - if ((action & 0x03) && !(attr & 0x100)) { /* exists, work with it */ - if (action & 0x02) { - if (!S_ISREG(sb.st_mode)) { /* only allowed for files */ - debug(D_FILE_OPS,"attempt to truncate non-regular file\n"); - return(ACCESS_DENIED); - } - status = 0x03; /* we're going to truncate it */ - } else { - status = 0x01; /* just open it */ - } - } else { - return(FILE_ALREADY_EXISTS); /* exists, fail */ - } - } - - if ((fd = open(fname, mode, from_dos_attr(attr))) < 0) { - debug(D_FILE_OPS,"failed to open %s : %s\n",fname,strerror(errno)); - return (ACCESS_DENIED); - } - - if (R_AL == 0x2e) /* extended wants status returned */ - R_CX = status; - - /* black magic to populate the SFT */ - - e = p = sda->filename1 + 2; /* parse name */ - while (*p) { - if (*p++ == '\\') /* look for beginning of filename */ - e = p; - } - - for (i = 0; i < 8; ++i) { /* copy name and pad with spaces */ - if (*e && *e != '.') - r_sft->name[i] = *e++; - else - r_sft->name[i] = ' '; - } - - if (*e == '.') /* skip period on short names */ - ++e; - - for (i = 0; i < 3; ++i) { /* copy extension and pad with spaces */ - if (*e) - r_sft->ext[i] = *e++; - else - r_sft->ext[i] = ' '; - } - - if (ustat(fname, &sb) < 0) /* re-stat to be accurate */ - return(WRITE_FAULT); /* any better ideas?! */ - - r_sft->open_mode = omode; /* file open mode */ - *(u_long *)r_sft->ddr_dpb = 0; /* no parameter block */ - r_sft->size = sb.st_size; /* current size */ - r_sft->fd = fd; /* our fd for it (hidden in starting cluster number) */ - r_sft->offset = 0; /* current offset is 0 */ - *(u_short *)r_sft->dir_sector = 0; /* not local file, ignored */ - r_sft->dir_entry = 0; /* not local file, ignored */ - r_sft->attribute = attr & 0xff; /* file attributes as requested */ - r_sft->info = r_drive + 0x8040; /* hide drive number here for later reference */ - encode_dos_file_time(sb.st_mtime, &r_sft->date, &r_sft->time); - debug(D_REDIR,"success, fd %d status %x\n", fd, status); - return(0); -} - -/* -** 2f:11:19 2f:11:1b -** -** find first -*/ -static int -int2f11_findfirst(regcontext_t *REGS __unused) -{ - return(find_first(sda->filename1,sda->attrmask, - (dosdir_t *)sda->foundentry, - (find_block_t *)sda->findfirst)); -} - -/* -** 2f:11:1c -** -** find next -*/ -static int -int2f11_findnext(regcontext_t *REGS __unused) -{ - return(find_next((dosdir_t *)sda->foundentry, - (find_block_t *)sda->findfirst)); -} - -/* -** 2f:11:21 -** -** lseek -*/ -static int -int2f11_lseek(regcontext_t *REGS) -{ - int fd; - off_t offset; - - fd = r_sft->fd; - offset = (off_t) ((int) ((R_CX << 16) + R_DX)); - - debug(D_REDIR,"lseek(%d, 0x%qx, SEEK_END)\n", fd, offset); - - if ((offset = lseek(fd, offset, SEEK_END)) < 0) { - if (errno == EBADF) - return(HANDLE_INVALID); - else - return(SEEK_ERROR); - } - r_sft->offset = offset; /* update offset in SFT */ - R_DX = offset >> 16; - R_AX = offset; - return(0); -} - -/* -** 2f:11:23 -** -** qualify filename -*/ -static int -int2f11_fnqual(regcontext_t *REGS) -{ - char *fname; - char *tname; - static char errmsg[] = "(failed)"; - int savedrive; - int error; - - return(PATH_NOT_FOUND); - - savedrive = diskdrive; /* to get CWD for network drive */ - diskdrive = n_drive; - fname = (char *)MAKEPTR(R_DS, R_SI); /* path pointers */ - tname = (char *)MAKEPTR(R_ES, R_DI); - - error = dos_makepath(fname, tname); - if (error) - tname = errmsg; - - diskdrive = savedrive; /* restore correct drive */ - - debug(D_REDIR, "qualify '%s' -> '%s'\n", fname, tname); - return(error); -} - -/* -** 2f:11:?? -** -** Null function - we know about it but do nothing -*/ -static int -int2f11_NULLFUNC(regcontext_t *REGS __unused) -{ - return(0); -} - -/* -** 2f:11:?? -** -** no function - not handled here (error) -*/ -static int -int2f11_NOFUNC(regcontext_t *REGS __unused) -{ - return(-1); -} - -struct intfunc_table int2f11_table[] = { - { 0x00, IFT_NOSUBFUNC, int2f11_00, "installation check"}, - { 0x01, IFT_NOSUBFUNC, int2f11_dirfn, "rmdir"}, - { 0x02, IFT_NOSUBFUNC, int2f11_dirfn, "rmdir"}, - { 0x03, IFT_NOSUBFUNC, int2f11_dirfn, "mkdir"}, - { 0x04, IFT_NOSUBFUNC, int2f11_dirfn, "mkdir"}, - { 0x05, IFT_NOSUBFUNC, int2f11_dirfn, "chdir"}, - { 0x06, IFT_NOSUBFUNC, int2f11_close, "close"}, - { 0x07, IFT_NOSUBFUNC, int2f11_NULLFUNC, "commit file"}, - { 0x08, IFT_NOSUBFUNC, int2f11_rdwr, "read"}, - { 0x09, IFT_NOSUBFUNC, int2f11_rdwr, "write"}, - { 0x0a, IFT_NOSUBFUNC, int2f11_NULLFUNC, "lock region"}, - { 0x0b, IFT_NOSUBFUNC, int2f11_NULLFUNC, "unlock region"}, - { 0x0c, IFT_NOSUBFUNC, int2f11_free, "free space"}, - { 0x0e, IFT_NOSUBFUNC, int2f11_NULLFUNC, "chmod"}, - { 0x0f, IFT_NOSUBFUNC, int2f11_stat, "stat"}, - { 0x11, IFT_NOSUBFUNC, int2f11_dirfn, "rename"}, - { 0x13, IFT_NOSUBFUNC, int2f11_dirfn, "unlink"}, - { 0x16, IFT_NOSUBFUNC, int2f11_open, "open"}, - { 0x17, IFT_NOSUBFUNC, int2f11_open, "creat"}, - { 0x18, IFT_NOSUBFUNC, int2f11_open, "creat"}, - { 0x19, IFT_NOSUBFUNC, int2f11_findfirst, "find first"}, - { 0x1b, IFT_NOSUBFUNC, int2f11_findfirst, "find first"}, - { 0x1c, IFT_NOSUBFUNC, int2f11_findnext, "find next"}, - { 0x1d, IFT_NOSUBFUNC, int2f11_NULLFUNC, "close all (abort)"}, - { 0x1e, IFT_NOSUBFUNC, int2f11_NULLFUNC, "do redirection"}, - { 0x1f, IFT_NOSUBFUNC, int2f11_NULLFUNC, "printer setup"}, - { 0x20, IFT_NOSUBFUNC, int2f11_NULLFUNC, "flush all buffers"}, - { 0x21, IFT_NOSUBFUNC, int2f11_lseek, "lseek"}, - { 0x22, IFT_NOSUBFUNC, int2f11_NULLFUNC, "process terminated"}, - { 0x23, IFT_NOSUBFUNC, int2f11_fnqual, "qualify filename"}, - { 0x24, IFT_NOSUBFUNC, int2f11_NOFUNC, "turn off printer"}, - { 0x25, IFT_NOSUBFUNC, int2f11_NOFUNC, "printer mode"}, - { 0x2d, IFT_NOSUBFUNC, int2f11_NOFUNC, "extended attributes"}, - { 0x2e, IFT_NOSUBFUNC, int2f11_open, "extended open/create"}, - { -1, 0, NULL, NULL} -}; - -static int int2f11_fastlookup[256]; - -/****************************************************************************** -** 2f:11 -** -** The DOS redirector interface. -*/ - -/* -** Verify that the drive being referenced is one we are handling, and -** establish some state for upcoming functions. -** -** Returns 1 if we should handle this request. -** -** XXX this is rather inefficient, but much easier to read than the previous -** incarnation 8( -*/ -static int -int2f11_validate(regcontext_t *REGS) -{ - int func = R_AL; - const char *path = NULL; - int doit = 0; - - /* defaults may help trap problems */ - r_cds = NULL; - r_sft = NULL; - r_drive = -1; - - /* some functions we accept regardless */ - switch (func) { - case 0x00: /* installation check */ - case 0x23: /* qualify path */ - case 0x1c: /* XXX really only valid if a search already started... */ - return(1); - } - - /* Where's the CDS? */ - switch(func) { - case 0x01: /* referenced by the SDA */ - case 0x02: - case 0x03: - case 0x04: - case 0x05: - case 0x0e: - case 0x0f: - case 0x11: - case 0x13: - case 0x17: - case 0x1b: - r_cds = (CDS *)MAKEPTR(sda->cds_seg, sda->cds_off); - break; - - case 0x0c: /* in es:di */ - case 0x1c: - r_cds = (CDS *)MAKEPTR(R_ES, R_DI); - break; - } - - /* Where's the SFT? */ - switch(func) { - case 0x06: /* in es:di */ - case 0x07: - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: - case 0x16: - case 0x17: - case 0x18: - case 0x21: - case 0x2d: - case 0x2e: - r_sft = (SFT *)MAKEPTR(R_ES, R_DI); - break; - } - - /* What drive? */ - switch(func) { - case 0x01: /* get drive from fully-qualified path in SDA */ - case 0x02: - case 0x03: - case 0x04: - case 0x05: - case 0x0c: - case 0x0e: - case 0x0f: - case 0x11: - case 0x13: - case 0x16: - case 0x17: - case 0x18: - case 0x19: - case 0x1b: - case 0x2e: - path = sda->filename1; - break; - - case 0x06: /* get drive from SFT (we put it here when file was opened) */ - case 0x07: - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: - case 0x21: - case 0x2d: - r_drive = r_sft->info & 0x1f; - break; - } - - if (path) { /* we have a path and need to determine the drive it refers to */ - - if (path[1] != ':') { /* must be fully qualified; we cannot handle this */ - debug(D_REDIR,"attempt to work non-absolute path %s\n",path); - return(0); - } - - /* translate letter to drive number */ - r_drive = drlton(path[0]); - } else { - path = "(no path)"; - } - - /* do we handle this drive? */ - if (dos_getcwd(r_drive)) { - n_drive = r_drive; /* XXX GROSTIC HACK ALERT */ - doit = 1; - } - - debug(D_REDIR,"%s -> drive %c func %x (%sus)\n", - path, drntol(r_drive), func, doit?"":"not "); - - /* so do we deal with this one? */ - return(doit); -} - - -int -int2f_11(regcontext_t *REGS) -{ - int idx; - int error; - - if (!sda) { /* not initialised yet */ - error = FUNC_NUM_IVALID; - } else { - - idx = intfunc_find(int2f11_table, int2f11_fastlookup, R_AL, 0); - if (idx == -1) { - debug(D_ALWAYS,"no handler for int2f:11:%x\n", R_AL); - return(0); - } - reset_poll(); - - - if (!int2f11_validate(REGS)) { /* determine whether we handle this request */ - error = -1; /* not handled by us */ - } else { - debug(D_REDIR, "REDIR: %02x (%s)\n", - int2f11_table[idx].func, int2f11_table[idx].desc); - /* call the handler */ - error = int2f11_table[idx].handler(REGS); - if (error != -1) - debug(D_REDIR, "REDIR: returns %d (%s)\n", - error, ((error >= 0) && (error <= dos_ret_size)) ? dos_return[error] : "unknown"); - } - } - - if (error == -1) - return (0); - if (error) { - R_AX = error; - R_FLAGS |= PSL_C; - } else - R_FLAGS &= ~PSL_C; - return (1); -} - -/****************************************************************************** -** intff handler. -** -** intff is the (secret, proprietary, internal, evil) call to -** initialise the redirector. -*/ -static void -install_drive(int drive, u_char *path) -{ - CDS *cds; - - /* check that DOS considers this a valid drive */ - if (drive < 0 || drive >= lol->lastdrive) { - debug(D_REDIR, "Drive %c beyond limit of %c\n", - drntol(drive), drntol(lol->lastdrive - 1)); - return; - } - - /* get the CDS for this drive */ - cds = (CDS *)MAKEPTR(lol->cds_seg, lol->cds_offset); - cds += drive; - -#if 0 /* XXX looks OK to me - mjs */ - if (cds->flag & (CDS_remote | CDS_ready)) { - debug(D_REDIR, "Drive %c already installed\n", drntol(drive)); - return; - } -#endif - - debug(D_REDIR, "Installing %c: as %s\n", drntol(drive), path); - - cds->flag |= CDS_remote | CDS_ready | CDS_notnet; - cds->path[0] = drntol(drive); - cds->path[1] = ':'; - cds->path[2] = '\\'; - cds->path[3] = '\0'; - cds->offset = 2; /* offset of \ in current path field */ -} - -static void -init_drives(void) -{ - int drive; - u_char *path; - - /* for all possible drives */ - for (drive = 0; drive < 26; ++drive) { - if ((path = dos_getpath(drive)) != 0) /* assigned to a path? */ - install_drive(drive, path); /* make it visible to DOS */ - } -} - - -void -intff(regcontext_t *REGS) -{ - - if (lol && sda) { /* already been called? */ - debug(D_REDIR, "redirector duplicate install ignored"); - return; - } - lol = (LOL *)MAKEPTR(R_BX, R_DX); /* where DOS keeps its goodies */ - sda = (SDA *)MAKEPTR(R_DI, R_SI); - init_drives(); - - /* initialise dispatcher */ - intfunc_init(int2f11_table, int2f11_fastlookup); -} diff --git a/usr.bin/doscmd/mem.c b/usr.bin/doscmd/mem.c deleted file mode 100644 index 540bb8f..0000000 --- a/usr.bin/doscmd/mem.c +++ /dev/null @@ -1,325 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI mem.c,v 2.2 1996/04/08 19:32:57 bostic Exp - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <stdio.h> -#include "doscmd.h" - -#define Mark(x) (*(char *) (x)) -#define Owner(x) (*(u_short *) ((char *)(x)+1)) -#define Size(x) (*(u_short *) ((char *)(x)+3)) -#define Next(x) ((char *)(x) + (Size(x)+1)*16) - -/* exports */ -char *dosmem; - -/* locals */ -static int dosmem_size; - -static char *next_p = (char *)0; -static char *end_p = (char *)0xB0000L; - -static char * -core_alloc(int *size) -{ - char *ret; - if (*size) { - if (*size & 0xfff) { - *size = (*size & ~0xfff) + 0x1000; - } - } else { - *size = end_p - next_p; - } - - if (next_p + *size > end_p) { - return NULL; - } - - ret = next_p; - next_p += *size; - return ret; -} - -void -mem_free_owner(int owner) -{ - char *mp; - - debug(D_MEMORY, " : freeow(%04x)\n", owner); - - for (mp = dosmem; ; mp = Next(mp)) { - if (Owner(mp) == owner) - Owner(mp) = 0; - - if (Mark(mp) != 'M') - break; - } -} - -static void -mem_print(void) -{ - char *mp; - - for (mp = dosmem; ; mp = Next(mp)) { - debug(D_ALWAYS, "%8p: mark %c owner %04x size %04x\n", - mp, Mark(mp), Owner(mp), Size(mp)); - - if (Mark(mp) != 'M') - break; - } -} - -void -mem_change_owner(int addr, int owner) -{ - char *mp; - - debug(D_MEMORY, "%04x: owner (%04x)\n", addr, owner); - addr <<= 4; - - for (mp = dosmem; ; mp = Next(mp)) { - if ((int)(mp + 16) == addr) - goto found; - - if (Mark(mp) != 'M') - break; - } - - debug(D_ALWAYS, "%05x: illegal block in change owner\n", addr); - mem_print(); - return; - -found: - Owner(mp) = owner; -} - -void -mem_init(void) -{ - int base, avail_memory; - - base = 0x600; - core_alloc(&base); - - avail_memory = MAX_AVAIL_SEG * 16 - base; - dosmem = core_alloc(&avail_memory); - - if (!dosmem || dosmem != (char *)base) - fatal("internal memory error\n"); - - dosmem_size = avail_memory / 16; - - debug(D_MEMORY, "dosmem = %p base = 0x%x avail = 0x%x (%dK)\n", - dosmem, base, dosmem_size, avail_memory / 1024); - - Mark(dosmem) = 'Z'; - Owner(dosmem) = 0; - Size(dosmem) = dosmem_size - 1; -} - -static void -mem_unsplit(char *mp, int size) -{ - char *nmp; - - while (Mark(mp) == 'M' && Size(mp) < size) { - nmp = Next(mp); - - if (Owner(nmp) != 0) - break; - - Size(mp) += Size(nmp) + 1; - Mark(mp) = Mark(nmp); - } -} - -static void -mem_split(char *mp, int size) -{ - char *nmp; - int rest; - - rest = Size(mp) - size; - Size(mp) = size; - nmp = Next(mp); - Mark(nmp) = Mark(mp); - Mark(mp) = 'M'; - Owner(nmp) = 0; - Size(nmp) = rest - 1; -} - -int -mem_alloc(int size, int owner, int *biggestp) -{ - char *mp; - int biggest; - - biggest = 0; - for (mp = dosmem; ; mp = Next(mp)) { - if (Owner(mp) == 0) { - if (Size(mp) < size) - mem_unsplit(mp, size); - if (Size(mp) >= size) - goto got; - - if (Size(mp) > biggest) - biggest = Size(mp); - } - - if (Mark(mp) != 'M') - break; - } - - debug(D_MEMORY, "%04x: alloc(%04x, owner %04x) failed -> %d\n", - 0, size, owner, biggest); - - if (biggestp) - *biggestp = biggest; - return 0; - -got: - if (Size(mp) > size) - mem_split(mp, size); - Owner(mp) = owner; - debug(D_MEMORY, "%04x: alloc(%04x, owner %04x)\n", - (int)mp/16 + 1, size, owner); - - if (biggestp) - *biggestp = size; - return (int)mp/16 + 1; -} - -int -mem_adjust(int addr, int size, int *availp) -{ - char *mp; - - debug(D_MEMORY, "%04x: adjust(%05x)\n", addr, size); - addr <<= 4; - - for (mp = dosmem; ; mp = Next(mp)) { - if ((int)(mp + 16) == addr) - goto found; - - if (Mark(mp) != 'M') - break; - } - - debug(D_ALWAYS, "%05x: illegal block in adjust\n", addr); - mem_print(); - return -2; - -found: - if (Size(mp) < size) - mem_unsplit(mp, size); - if (Size(mp) >= size) - goto got; - - debug(D_MEMORY, "%04x: adjust(%04x) failed -> %d\n", - (int)mp/16 + 1, size, Size(mp)); - - if (availp) - *availp = Size(mp); - return -1; - -got: - if (Size(mp) > size) - mem_split(mp, size); - debug(D_MEMORY, "%04x: adjust(%04x)\n", - (int)mp/16 + 1, size); - - if (availp) - *availp = size; - return 0; -} - - - -#ifdef MEM_TEST -mem_check () -{ - struct mem_block *mp; - for (mp = mem_blocks.next; mp != &mem_blocks; mp = mp->next) { - if (mp->addr + mp->size != mp->next->addr) - break; - if (mp->inuse && mp->size == 0) - return (-1); - } - - if (mp->next != &mem_blocks) - return (-1); - return (0); -} - -char *blocks[10]; - -main () -{ - int i; - int n; - int newsize; - - mem_init (0, 300); - - for (i = 0; i < 100000; i++) { - n = random () % 10; - - if (blocks[n]) { - newsize = random () % 20; - if ((newsize & 1) == 0) - newsize = 0; - - if (0) - printf ("adjust %d %x %d\n", - n, blocks[n], newsize); - mem_adjust (blocks[n], newsize, NULL); - if (newsize == 0) - blocks[n] = NULL; - } else { - while ((newsize = random () % 20) == 0) - ; - if (0) - printf ("alloc %d %d\n", n, newsize); - blocks[n] = mem_alloc (newsize, NULL); - } - if (mem_check () < 0) { - printf ("==== %d\n", i); - mem_print (); - } - } - - mem_print (); -} -#endif /* MEM_TEST */ diff --git a/usr.bin/doscmd/mouse.c b/usr.bin/doscmd/mouse.c deleted file mode 100644 index 6d44789..0000000 --- a/usr.bin/doscmd/mouse.c +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI int33.c,v 2.2 1996/04/08 19:32:54 bostic Exp - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include "doscmd.h" -#include "mouse.h" - -mouse_t mouse_status; -u_char *mouse_area = 0; -int nmice = 1; - -static void -mouse_probe(void) -{ -} - -void -int33(regcontext_t *REGS) -{ - u_long vec; - u_short mask; - int i; - - if (!nmice) { - R_FLAGS |= PSL_C; /* We don't support a mouse */ - return; - } - - printf("Mouse: %02x\n", R_AX); - switch (R_AX) { - case 0x00: /* Reset Mouse */ - printf("Installing mouse driver\n"); - R_AX = 0xffff; /* Mouse installed */ - R_BX = 2; /* Number of mouse buttons */ - memset(&mouse_status, 0, sizeof(mouse_status)); - mouse_status.installed = 1; - mouse_status.hardcursor = 1; - mouse_status.end = 16; - mouse_status.hmickey = 8; - mouse_status.vmickey = 16; - mouse_status.doubling = 100; - mouse_status.init = -1; - mouse_status.range.w = 8 * 80; - mouse_status.range.h = 16 * 25; - break; - - case 0x01: /* Display Mouse Cursor */ - if ((mouse_status.init += 1) == 0) { - mouse_status.show = 1; - } - break; - - case 0x02: /* Hide Mouse Cursor */ - if (mouse_status.init == 0) - mouse_status.show = 0; - mouse_status.init -= 1; - break; - - case 0x03: /* Get cursor position/button status */ - mouse_probe(); - R_CX = mouse_status.x; - R_DX = mouse_status.y; - R_BX = mouse_status.buttons; - break; - - case 0x04: /* Move mouse cursor */ - /* mouse_move(GET16(sc->sc_ecx), GET16(sc->sc_edx)); */ - break; - - case 0x05: /* Determine number of times mouse button was active */ - i = R_BX & 3; - if (i == 3) - i = 1; - - R_BX = mouse_status.downs[i]; - mouse_status.downs[i] = 0; - R_AX = mouse_status.buttons; - R_CX = mouse_status.x; /* Not quite right */ - R_DX = mouse_status.y; /* Not quite right */ - break; - - case 0x06: /* Determine number of times mouse button was relsd */ - i = R_DX & 3; - if (i == 3) - i = 1; - - R_BX = mouse_status.ups[i]; - mouse_status.ups[i] = 0; - R_AX = mouse_status.buttons; - R_CX = mouse_status.x; /* Not quite right */ - R_DX = mouse_status.y; /* Not quite right */ - break; - - case 0x07: /* Set min/max horizontal cursor position */ - mouse_status.range.x = R_CX; - mouse_status.range.w = R_DX - R_CX; - break; - - case 0x08: /* Set min/max vertical cursor position */ - mouse_status.range.y = R_CX; - mouse_status.range.h = R_DX - R_CX; - - case 0x09: /* Set graphics cursor block */ - /* BX,CX is hot spot, ES:DX is data. */ - break; - - case 0x0a: /* Set Text Cursor */ - mouse_status.hardcursor = R_BX ? 1 : 0; - mouse_status.start = R_CX; - mouse_status.end = R_CX; /* XXX is this right ? */ - break; - - case 0x0b: /* Read Mouse Motion Counters */ - mouse_probe(); - R_CX = mouse_status.x - mouse_status.lastx; - R_DX = mouse_status.y - mouse_status.lasty; - break; - - case 0x0c: /* Set event handler */ - mouse_status.mask = R_CX; - mouse_status.handler = MAKEVEC(R_ES, R_DX); - break; - - case 0x0d: /* Enable light pen */ - case 0x0e: /* Disable light pen */ - break; - - case 0x0f: /* Set cursor speed */ - mouse_status.hmickey = R_CX; - mouse_status.vmickey = R_DX; - break; - - case 0x10: /* Exclusive area */ - mouse_status.exclude.x = R_CX; - mouse_status.exclude.y = R_DX; - mouse_status.exclude.w = R_SI - R_CX; - mouse_status.exclude.h = R_DI - R_DX; - break; - - case 0x13: /* Set maximum for mouse speed doubling */ - break; - case 0x14: /* Exchange event handlers */ - mask = mouse_status.mask; - vec = mouse_status.handler; - - mouse_status.mask = R_CX; - mouse_status.handler = MAKEVEC(R_ES, R_DX); - R_CX = mask; - PUTVEC(R_ES, R_DX, vec); - break; - - case 0x15: /* Determine mouse status buffer size */ - R_BX = sizeof(mouse_status); - break; - - case 0x16: /* Store mouse buffer */ - memcpy((char *)MAKEPTR(R_ES, R_DX), &mouse_status, - sizeof(mouse_status)); - break; - - case 0x17: /* Restore mouse buffer */ - memcpy(&mouse_status, (char *)MAKEPTR(R_ES, R_DX), - sizeof(mouse_status)); - break; - - case 0x18: /* Install alternate handler */ - mask = R_CX & 0xff; - if ((R_CX & 0xe0) == 0x00 || - mask == mouse_status.altmask[0] || - mask == mouse_status.altmask[1] || - mask == mouse_status.altmask[2] || - (mouse_status.altmask[i = 0] && - mouse_status.altmask[i = 1] && - mouse_status.altmask[i = 2])) { - R_AX = 0xffff; - break; - } - mouse_status.altmask[i] = R_CX; - mouse_status.althandler[i] = MAKEVEC(R_ES, R_DX); - break; - - case 0x19: /* Determine address of alternate event handler */ - mask = R_CX & 0xff; - if (mask == mouse_status.altmask[0]) - vec = mouse_status.althandler[0]; - else if (mask == mouse_status.altmask[1]) - vec = mouse_status.althandler[1]; - else if (mask == mouse_status.altmask[2]) - vec = mouse_status.althandler[2]; - else - R_CX = 0; - PUTVEC(R_ES, R_DX, vec); - break; - - case 0x1a: /* set mouse sensitivity */ - mouse_status.hmickey = R_BX; - mouse_status.vmickey = R_CX; - mouse_status.doubling = R_DX; - break; - - case 0x1b: /* get mouse sensitivity */ - R_BX = mouse_status.hmickey; - R_CX = mouse_status.vmickey; - R_DX = mouse_status.doubling; - break; - - case 0x1c: /* set mouse hardware rate */ - case 0x1d: /* set display page */ - break; - - case 0x1e: /* get display page */ - R_BX = 0; /* Always on display page 0 */ - break; - - case 0x1f: /* Disable mouse driver */ - if (mouse_status.installed) { - PUTVEC(R_ES, R_DX, mouse_status.handler); - mouse_status.installed = 0; - } else { - R_AX = 0xffff; - } - break; - - case 0x20: /* Enable mouse driver */ - mouse_status.installed = 1; - break; - - case 0x21: /* Reset mouse driver */ - if (mouse_status.installed) { - mouse_status.show = 0; - mouse_status.handler = 0; - mouse_status.mask = 0; - mouse_status.cursor = 0; - } else { - R_AX = 0xffff; - } - break; - - case 0x22: /* Specified language for mouse messages */ - break; - - case 0x23: /* Get language number */ - R_BX = 0; /* Always return english */ - break; - - case 0x24: /* Get mouse type */ - R_CX = 0x0400; /* PS/2 style mouse */ - R_BX = 0x0600 + 24; /* Version 6.24 */ - break; - - default: - R_FLAGS |= PSL_C; - break; - } -} - -void -mouse_init(void) -{ - u_long vec; - - vec = insert_softint_trampoline(); - ivec[0x33] = vec; - register_callback(vec, int33, "int 33"); - - mouse_area[1] = 24; -} diff --git a/usr.bin/doscmd/mouse.h b/usr.bin/doscmd/mouse.h deleted file mode 100644 index b77cba4..0000000 --- a/usr.bin/doscmd/mouse.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI mouse.h,v 2.2 1996/04/08 19:32:58 bostic Exp - * - * $FreeBSD$ - */ - -typedef struct { - u_short hardcursor:1; - u_short installed:1; - u_short cursor:1; - u_short show:1; - u_short buttons:3; - - u_short init; - u_short start; - u_short end; - u_short hmickey; - u_short vmickey; - u_short doubling; - u_long handler; - u_short mask; - u_long althandler[3]; - u_short altmask[3]; - struct { - u_short x; - u_short y; - u_short w; - u_short h; - } range, exclude; - u_short x; - u_short y; - u_short lastx; - u_short lasty; - - u_short downs[3]; - u_short ups[3]; -} mouse_t; - -extern mouse_t mouse_status; -extern u_char *mouse_area; diff --git a/usr.bin/doscmd/net.c b/usr.bin/doscmd/net.c deleted file mode 100644 index 55e291a..0000000 --- a/usr.bin/doscmd/net.c +++ /dev/null @@ -1,36 +0,0 @@ -/* -** No copyright! -** -** NetBIOS etc. hooks. -*/ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include "doscmd.h" - -static void -int2a(regcontext_t *REGS) -{ - unknown_int2(0x2a, R_AH, REGS); -} - -static void -int5c(regcontext_t *REGS) -{ - unknown_int2(0x5c, R_AH, REGS); -} - -void -net_init(void) -{ - u_long vec; - - vec = insert_softint_trampoline(); - ivec[0x2a] = vec; - register_callback(vec, int2a, "int 2a"); - - vec = insert_softint_trampoline(); - ivec[0x5c] = vec; - register_callback(vec, int5c, "int 5c"); -} diff --git a/usr.bin/doscmd/port.c b/usr.bin/doscmd/port.c deleted file mode 100644 index 22e995f..0000000 --- a/usr.bin/doscmd/port.c +++ /dev/null @@ -1,444 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI port.c,v 2.2 1996/04/08 19:33:03 bostic Exp - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/ioctl.h> -#include <machine/sysarch.h> - -#include "doscmd.h" -#include "tty.h" - -#define MINPORT 0x000 -#define MAXPORT_MASK (MAXPORT - 1) - -static __inline int -in(u_int port) -{ - int _inb_result; - -#ifdef __GNUC__ - __asm __volatile ("xorl %%eax,%%eax; inb %%dx,%%al" : - "=a" (_inb_result) : "d" (port)); -#endif - return _inb_result; -} - -static __inline void -out(u_int port, int data) -{ -#ifdef __GNUC__ - __asm __volatile ("outb %%al,%%dx" : : "a" (data), "d" (port)); -#endif -} - -FILE *iolog = 0; -u_long ioports[MAXPORT/32]; -#ifdef __FreeBSD__ -static void -iomap(int port, int cnt) -{ - if (port + cnt >= MAXPORT) { - errno = ERANGE; - goto bad; - } - if (i386_set_ioperm(port, cnt, 1) < 0) { - bad: - perror("iomap"); - quit(1); - } -} - -static void -iounmap(int port, int cnt) -{ - if (port + cnt >= MAXPORT) { - errno = ERANGE; - goto bad; - } - if (i386_set_ioperm(port, cnt, 0) < 0) { - bad: - perror("iounmap"); - quit(1); - } -} -#else -static void -iomap(int port, int cnt) -{ - - if (port + cnt >= MAXPORT) { - errno = ERANGE; - goto bad; - } - while (cnt--) { - ioports[port/32] |= (1 << (port%32)); - port++; - } - if (i386_set_ioperm(ioports) < 0) { - bad: - perror("iomap"); - quit(1); - } -} - -static void -iounmap(int port, int cnt) -{ - - if (port + cnt >= MAXPORT) { - errno = ERANGE; - goto bad; - } - while (cnt--) { - ioports[port/32] &= ~(1 << (port%32)); - port++; - } - if (i386_set_ioperm(ioports) < 0) { - bad: - perror("iounmap"); - quit(1); - } -} -#endif -void -outb_traceport(int port, unsigned char byte) -{ -/* - if (!iolog && !(iolog = fopen("/tmp/iolog", "a"))) - iolog = stderr; - - fprintf(iolog, "0x%03X -> %02X\n", port, byte); - */ - - iomap(port, 1); - out(port, byte); - iounmap(port, 1); -} - -unsigned char -inb_traceport(int port) -{ - unsigned char byte; - -/* - if (!iolog && !(iolog = fopen("/tmp/iolog", "a"))) - iolog = stderr; - */ - - iomap(port, 1); - byte = in(port); - iounmap(port, 1); - -/* - fprintf(iolog, "0x%03X <- %02X\n", port, byte); - fflush(iolog); - */ - return(byte); -} - -/* - * Real input/output to (hopefully) iomapped port - */ -void -outb_port(int port, unsigned char byte) -{ - out(port, byte); -} - -unsigned char -inb_port(int port) -{ - return in(port); -} - -/* - * Fake input/output ports - */ - -static void -outb_nullport(int port __unused, unsigned char byte __unused) -{ -/* - debug(D_PORT, "outb_nullport called for port 0x%03X = 0x%02X.\n", - port, byte); - */ -} - -static unsigned char -inb_nullport(int port __unused) -{ -/* - debug(D_PORT, "inb_nullport called for port 0x%03X.\n", port); - */ - return(0xff); -} - -/* - * configuration table for ports' emulators - */ - -struct portsw { - unsigned char (*p_inb)(int port); - void (*p_outb)(int port, unsigned char byte); -} portsw[MAXPORT]; - -void -init_io_port_handlers(void) -{ - int i; - - for (i = 0; i < MAXPORT; i++) { - if (portsw[i].p_inb == 0) - portsw[i].p_inb = inb_nullport; - if (portsw[i].p_outb == 0) - portsw[i].p_outb = outb_nullport; - } - -} - -void -define_input_port_handler(int port, unsigned char (*p_inb)(int port)) -{ - if ((port >= MINPORT) && (port < MAXPORT)) { - portsw[port].p_inb = p_inb; - } else - fprintf (stderr, "attempt to handle invalid port 0x%04x", port); -} - -void -define_output_port_handler(int port, void (*p_outb)(int port, unsigned char byte)) -{ - if ((port >= MINPORT) && (port < MAXPORT)) { - portsw[port].p_outb = p_outb; - } else - fprintf (stderr, "attempt to handle invalid port 0x%04x", port); -} - - -void -inb(regcontext_t *REGS, int port) -{ - unsigned char (*in_handler)(int); - - if ((port >= MINPORT) && (port < MAXPORT)) - in_handler = portsw[port].p_inb; - else - in_handler = inb_nullport; - R_AL = (*in_handler)(port); - debug(D_PORT, "IN on port %02x -> %02x\n", port, R_AL); -} - -void -insb(regcontext_t *REGS, int port) -{ - unsigned char (*in_handler)(int); - unsigned char data; - - if ((port >= MINPORT) && (port < MAXPORT)) - in_handler = portsw[port].p_inb; - else - in_handler = inb_nullport; - data = (*in_handler)(port); - *(u_char *)MAKEPTR(R_ES, R_DI) = data; - debug(D_PORT, "INS on port %02x -> %02x\n", port, data); - - if (R_FLAGS & PSL_D) - R_DI--; - else - R_DI++; -} - -void -inx(regcontext_t *REGS, int port) -{ - unsigned char (*in_handler)(int); - - if ((port >= MINPORT) && (port < MAXPORT)) - in_handler = portsw[port].p_inb; - else - in_handler = inb_nullport; - R_AL = (*in_handler)(port); - if ((port >= MINPORT) && (port < MAXPORT)) - in_handler = portsw[port + 1].p_inb; - else - in_handler = inb_nullport; - R_AH = (*in_handler)(port + 1); - debug(D_PORT, "IN on port %02x -> %04x\n", port, R_AX); -} - -void -insx(regcontext_t *REGS, int port) -{ - unsigned char (*in_handler)(int); - unsigned char data; - - if ((port >= MINPORT) && (port < MAXPORT)) - in_handler = portsw[port].p_inb; - else - in_handler = inb_nullport; - data = (*in_handler)(port); - *(u_char *)MAKEPTR(R_ES, R_DI) = data; - debug(D_PORT, "INS on port %02x -> %02x\n", port, data); - - if ((port >= MINPORT) && (port < MAXPORT)) - in_handler = portsw[port + 1].p_inb; - else - in_handler = inb_nullport; - data = (*in_handler)(port + 1); - ((u_char *)MAKEPTR(R_ES, R_DI))[1] = data; - debug(D_PORT, "INS on port %02x -> %02x\n", port, data); - - if (R_FLAGS & PSL_D) - R_DI -= 2; - else - R_DI += 2; -} - -void -outb(regcontext_t *REGS, int port) -{ - void (*out_handler)(int, unsigned char); - - if ((port >= MINPORT) && (port < MAXPORT)) - out_handler = portsw[port].p_outb; - else - out_handler = outb_nullport; - (*out_handler)(port, R_AL); - debug(D_PORT, "OUT on port %02x <- %02x\n", port, R_AL); -/* - if (port == 0x3bc && R_AL == 0x55) - tmode = 1; -*/ -} - -void -outx(regcontext_t *REGS, int port) -{ - void (*out_handler)(int, unsigned char); - - if ((port >= MINPORT) && (port < MAXPORT)) - out_handler = portsw[port].p_outb; - else - out_handler = outb_nullport; - (*out_handler)(port, R_AL); - debug(D_PORT, "OUT on port %02x <- %02x\n", port, R_AL); - if ((port >= MINPORT) && (port < MAXPORT)) - out_handler = portsw[port + 1].p_outb; - else - out_handler = outb_nullport; - (*out_handler)(port + 1, R_AH); - debug(D_PORT, "OUT on port %02x <- %02x\n", port + 1, R_AH); -} - -void -outsb(regcontext_t *REGS, int port) -{ - void (*out_handler)(int, unsigned char); - unsigned char value; - - if ((port >= MINPORT) && (port < MAXPORT)) - out_handler = portsw[port].p_outb; - else - out_handler = outb_nullport; - value = *(u_char *)MAKEPTR(R_ES, R_DI); - debug(D_PORT, "OUT on port %02x <- %02x\n", port, value); - (*out_handler)(port, value); - - if (R_FLAGS & PSL_D) - R_DI--; - else - R_DI++; -} - -void -outsx(regcontext_t *REGS, int port) -{ - void (*out_handler)(int, unsigned char); - unsigned char value; - - if ((port >= MINPORT) && (port < MAXPORT)) - out_handler = portsw[port].p_outb; - else - out_handler = outb_nullport; - value = *(u_char *)MAKEPTR(R_ES, R_DI); - debug(D_PORT, "OUT on port %02x <- %02x\n", port, value); - (*out_handler)(port, value); - - if ((port >= MINPORT) && (port < MAXPORT)) - out_handler = portsw[port + 1].p_outb; - else - out_handler = outb_nullport; - value = ((u_char *)MAKEPTR(R_ES, R_DI))[1]; - debug(D_PORT, "OUT on port %02x <- %02x\n", port+1, value); - (*out_handler)(port + 1, value); - - if (R_FLAGS & PSL_D) - R_DI -= 2; - else - R_DI += 2; -} - -unsigned char port_61 = 0x10; -int sound_on = 1; -int sound_freq = 1000; - -void -outb_speaker(int port __unused, unsigned char byte) -{ -#if 0 /*XXXXX*/ - if (raw_kbd) { - if ((port_61 & 3) != 3) { - if ((byte & 3) == 3 && /* prtim[2].gate && */ sound_on) - ioctl(kbd_fd, PCCONIOCSTARTBEEP, &sound_freq); - } else if ((byte & 3) != 3) - ioctl(kbd_fd, PCCONIOCSTOPBEEP); - } -#endif - port_61 = byte; -} - -unsigned char -inb_speaker(int port __unused) -{ -/* port_61 = (port_61 + 1) & 0xff; */ - return(port_61); -} - -void -speaker_init() -{ - define_input_port_handler(0x61, inb_speaker); - define_output_port_handler(0x61, outb_speaker); - -} diff --git a/usr.bin/doscmd/redir.S b/usr.bin/doscmd/redir.S deleted file mode 100644 index 1f40f3c..0000000 --- a/usr.bin/doscmd/redir.S +++ /dev/null @@ -1,122 +0,0 @@ -! Copyright (c) 1997 Helmut Wirth <hfwirth@ping.at> -! All rights reserved. -! -! Redistribution and use in source and binary forms, with or without -! modification, are permitted provided that the following conditions -! are met: -! 1. Redistributions of source code must retain the above copyright -! notice immediately at the beginning of the file, witout modification, -! this list of conditions, and the following disclaimer. -! 2. Redistributions in binary form must reproduce the above copyright -! notice, this list of conditions and the following disclaimer in the -! documentation and/or other materials provided with the distribution. -! 3. The name of the author may not be used to endorse or promote products -! derived from this software without specific prior written permission. -! -! THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -! IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -! OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -! IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -! INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -! NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -! DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -! THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -! (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -! THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -! -! $FreeBSD$ - - -! -! This is the new redirector program, it replaces instbsdi.exe -! The program fetches some pointers from DOS and reports them back to -! the emulator via the emulator interrupt 0xff. It does not stay resident. - -use16 - -.text -.bss -.data -.align 0 - -! Emulator interrupt entry -EmulatorINT = 0xFF -! Emulator redirector function -EmulatorRED = 0x1 - -! DOS interrupt -DOSInt = 0x21 - -! DOS get list of lists call, returns pointer to system vars in ES:BX -DOSGetList = 0x52 - -! DOS get swappable area, returns DOS swappable area in DS:SI -DOSGetSwapD = 0x5D06 - -! DOS terminate program with return code -DOSExit = 0x4C - -! DOS print message -DOSMesg = 0x9 - -cr = 0xd -lf = 0xa -eom = '$' ! DOS end of string - - .org 0x100 - -.globl _main -_main: - - mov ah, #DOSGetList - int DOSInt - jc Fail - mov [_list], bx - mov ax, es - mov [_list+2], ax - push ds - mov ax, #DOSGetSwapD - int DOSInt - mov ax, ds - pop ds - jc Fail - mov [_swap], si - mov [_swap+2], ax - push ax - mov ah, #EmulatorRED - mov dx, [_list] - mov bx, [_list+2] - mov si, [_swap] - mov di, [_swap+2] - int EmulatorINT - xor al, al ! return 0 - jmp Exit -Fail: - mov ah, #DOSMesg - mov dx, #ErrorMessage - int DOSInt - mov al, #1 ! return 1 -Exit: - mov ah, #DOSExit - int DOSInt -! -! Should never get to this point -! - nop - nop - hlt - -! The two pointers are found using the DOS calls -! and passed to the redirector interface via int FF -! The two pointers are passed in BX:DX (list) and DI:SI (swap) - -.align 2 - -_list: .word 0 - .word 0 -_swap: .word 0 - .word 0 - -ErrorMessage: - .ascii "Error installing redirector interface" - .byte cr,lf,eom, 0 diff --git a/usr.bin/doscmd/redir.com.uu b/usr.bin/doscmd/redir.com.uu deleted file mode 100644 index 58af948..0000000 --- a/usr.bin/doscmd/redir.com.uu +++ /dev/null @@ -1,8 +0,0 @@ -$FreeBSD$ - -begin 644 redir.com -MM%+-(7(TB1Y*`8S`HTP!'K@&7<TAC-@?<B")-DX!HU`!4+0!BQ9*`8L>3`&+ -M-DX!BSY0`<W_,,#K";0)NE(!S2&P`;1,S2&0D/0``````````$5R<F]R(&EN -B<W1A;&QI;F<@<F5D:7)E8W1O<B!I;G1E<F9A8V4-"B0````` -` -end diff --git a/usr.bin/doscmd/register.h b/usr.bin/doscmd/register.h deleted file mode 100644 index 6be5309..0000000 --- a/usr.bin/doscmd/register.h +++ /dev/null @@ -1,177 +0,0 @@ -/* -** Copyright (c) 1996 -** Michael Smith. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** -** THIS SOFTWARE IS PROVIDED BY Michael Smith ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL Michael Smith BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. -** -** $FreeBSD$ -*/ - -/****************************************************************************** -** Abstractions to hide register access methods across different platforms. -** -*/ - -#ifndef _MACHINE_VM86_H_ - -/* standard register representation */ -typedef union -{ - u_long r_ex; - struct - { - u_short r_x; - u_short :16; - } r_w; - struct - { - u_char r_l; - u_char r_h; - u_short :16; - } r_b; -} reg86_t; - -#endif - -#ifdef __FreeBSD__ - -/* layout must match definition of struct sigcontext in <machine/signal.h> */ - -typedef struct -{ - int onstack; - reg86_t gs; - reg86_t fs; - reg86_t es; - reg86_t ds; - reg86_t edi; - reg86_t esi; - reg86_t ebp; - reg86_t isp; - reg86_t ebx; - reg86_t edx; - reg86_t ecx; - reg86_t eax; - int pad[2]; - reg86_t eip; - reg86_t cs; - reg86_t efl; - reg86_t esp; - reg86_t ss; -} registers_t; - -typedef union -{ - mcontext_t sc; - registers_t r; -} regcontext_t; - -/* -** passed around as a reference to the registers. This must be in -** scope for the following register macros to work. -*/ - -/* register shorthands */ -#define R_ESP (REGS->r.esp.r_ex) -#define R_SP (REGS->r.esp.r_w.r_x) -#define R_EBP (REGS->r.ebp.r_ex) -#define R_BP (REGS->r.ebp.r_w.r_x) -#define R_ISP (REGS->r.isp.r_ex) -#define R_EIP (REGS->r.eip.r_ex) -#define R_IP (REGS->r.eip.r_w.r_x) -#define R_EFLAGS (REGS->r.efl.r_ex) -#define R_FLAGS (REGS->r.efl.r_w.r_x) -#define R_EES (REGS->r.es.r_ex) -#define R_ES (REGS->r.es.r_w.r_x) -#define R_EDS (REGS->r.ds.r_ex) -#define R_DS (REGS->r.ds.r_w.r_x) -#define R_ECS (REGS->r.cs.r_ex) -#define R_CS (REGS->r.cs.r_w.r_x) -#define R_ESS (REGS->r.ss.r_ex) -#define R_SS (REGS->r.ss.r_w.r_x) -#define R_EDI (REGS->r.edi.r_ex) -#define R_DI (REGS->r.edi.r_w.r_x) -#define R_ESI (REGS->r.esi.r_ex) -#define R_SI (REGS->r.esi.r_w.r_x) -#define R_EBX (REGS->r.ebx.r_ex) -#define R_BX (REGS->r.ebx.r_w.r_x) -#define R_BL (REGS->r.ebx.r_b.r_l) -#define R_BH (REGS->r.ebx.r_b.r_h) -#define R_EDX (REGS->r.edx.r_ex) -#define R_DX (REGS->r.edx.r_w.r_x) -#define R_DL (REGS->r.edx.r_b.r_l) -#define R_DH (REGS->r.edx.r_b.r_h) -#define R_ECX (REGS->r.ecx.r_ex) -#define R_CX (REGS->r.ecx.r_w.r_x) -#define R_CL (REGS->r.ecx.r_b.r_l) -#define R_CH (REGS->r.ecx.r_b.r_h) -#define R_EAX (REGS->r.eax.r_ex) -#define R_AX (REGS->r.eax.r_w.r_x) -#define R_AL (REGS->r.eax.r_b.r_l) -#define R_AH (REGS->r.eax.r_b.r_h) -#define R_EGS (REGS->r.gs.r_ex) -#define R_GS (REGS->r.gs.r_w.r_x) -#define R_EFS (REGS->r.fs.r_ex) -#define R_FS (REGS->r.fs.r_w.r_x) - -#endif - -#ifdef __bsdi__ -#endif - -#ifdef __NetBSD__ -#endif - -/* -** register manipulation macros -*/ - -#define PUTVEC(s, o, x) ((s) = ((x) >> 16), (o) = (x) & 0xffff) -#define MAKEVEC(s, o) (((s) << 16) + (o)) - -#define PUTPTR(s, o, x) (((s) = ((x) & 0xf0000) >> 4), (o) = (x) & 0xffff) -#define MAKEPTR(s, o) (((s) << 4) + (o)) - -#define VECPTR(x) MAKEPTR((x) >> 16, (x) & 0xffff) - -#define REGISTERS regcontext_t *REGS - -static __inline void -PUSH(u_short x, REGISTERS) -{ - R_SP -= 2; - *(u_short *)MAKEPTR(R_SS, R_SP) = (x); -} - -static __inline u_short -POP(REGISTERS) -{ - u_short x; - - x = *(u_short *)MAKEPTR(R_SS, R_SP); - R_SP += 2; - return(x); -} - -# ifndef PSL_ALLCC /* Grr, FreeBSD doesn't have this */ -# define PSL_ALLCC (PSL_C|PSL_PF|PSL_AF|PSL_Z|PSL_N) -# endif diff --git a/usr.bin/doscmd/setver.c b/usr.bin/doscmd/setver.c deleted file mode 100644 index da40c1b..0000000 --- a/usr.bin/doscmd/setver.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI setver.c,v 2.2 1996/04/08 19:33:04 bostic Exp - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include "doscmd.h" - -#if 1 /*XXXXX*/ -int ms_version = 622; -#else -int ms_version = 410; -#endif - -typedef struct setver_t { - short version; - char command[14]; - struct setver_t *next; -} setver_t; - -static setver_t *setver_root; - -void -setver(char *cmd, short version) -{ - if (cmd) { - setver_t *s = (setver_t *)malloc(sizeof(setver_t)); - - strncpy(s->command, cmd, 14); - s->version = version; - s->next = setver_root; - setver_root = s; - } else { - ms_version = version; - } -} - -short -getver(char *cmd) -{ - if (cmd) { - setver_t *s = setver_root; - - while (s) { - if (strncasecmp(cmd, s->command, 14) == 0) - return(s->version); - s = s->next; - } - } - return(ms_version); -} diff --git a/usr.bin/doscmd/signal.c b/usr.bin/doscmd/signal.c deleted file mode 100644 index 34937ec..0000000 --- a/usr.bin/doscmd/signal.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI signal.c,v 2.2 1996/04/08 19:33:06 bostic Exp - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include "doscmd.h" -#include "trap.h" - -static void (*handler[NSIG])(struct sigframe *); -static char signal_stack[16 * 1024]; -#define PSS(w) { char s; printf(w " @ %08x\n", (signal_stack + sizeof signal_stack) - &s); } - -struct sigframe *saved_sigframe; -regcontext_t *saved_regcontext; -int saved_valid = 0; - -static void -sanity_check(struct sigframe *sf __unused) -{ -#if 0 - static sigset_t oset; - int i; - - for (i = 1; i < 32; ++i) { - if (sigismember(&sf->sf_sc.sc_mask, i) != sigismember(&oset, i)) - fprintf(debugf, "Signal %s %s being blocked\n", - sys_signame[i], - sigismember(&sf->sf_sc.sc_mask, i) ? "now" : "no longer"); - } - oset = sf->sf_sc.sc_mask; -#endif - - if (dead) - fatal("attempting to return to vm86 while dead"); -} - -#if defined(__FreeBSD__) || defined(USE_VM86) -static void -generichandler(struct sigframe sf) -{ - if (sf.sf_uc.uc_mcontext.mc_eflags & PSL_VM) { - saved_sigframe = &sf; - saved_regcontext = (regcontext_t *)&(sf.sf_uc.uc_mcontext); - saved_valid = 1; - if (handler[sf.sf_signum]) - (*handler[sf.sf_signum])(&sf); - saved_valid = 0; - sanity_check(&sf); - } else { - if (handler[sf.sf_signum]) - (*handler[sf.sf_signum])(&sf); - } -} -#else -#error BSD/OS sigframe/trapframe kernel interface not currently supported. -#endif - -void setsignal(int s, void (*h)(struct sigframe *)) -{ - static int first = 1; - struct sigaction sa; - - if (first) { - struct sigaltstack sstack; - - sstack.ss_sp = signal_stack; - sstack.ss_size = sizeof signal_stack; - sstack.ss_flags = 0; - sigaltstack (&sstack, NULL); - first = 0; - } - - if (s >= 0 && s < NSIG) { - handler[s] = h; - - sa.sa_handler = (__sighandler_t *)generichandler; - sigemptyset(&sa.sa_mask); - sigaddset(&sa.sa_mask, SIGIO); - sigaddset(&sa.sa_mask, SIGALRM); - sa.sa_flags = SA_ONSTACK; - sigaction(s, &sa, NULL); - } -} diff --git a/usr.bin/doscmd/timer.c b/usr.bin/doscmd/timer.c deleted file mode 100644 index eff7bb6..0000000 --- a/usr.bin/doscmd/timer.c +++ /dev/null @@ -1,70 +0,0 @@ -/* -** No copyright?! -*/ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include "doscmd.h" - -static void -int08(regcontext_t *REGS __unused) -{ - *(u_long *)&BIOSDATA[0x6c] += 1; /* ticks since midnight */ - while (*(u_long *)&BIOSDATA[0x6c] >= 24*60*6*182) { - *(u_long *)&BIOSDATA[0x6c] -= 24*60*6*182; - BIOSDATA[0x70]++; /* # times past mn */ - } - /* What is the real BIOS' sequence? */ - send_eoi(); - softint(0x1c); -} - -static void -int1c(regcontext_t *REGS __unused) -{ -} - -unsigned char timer; - -static u_char -inb_timer(int port __unused) -{ - return (--timer); -} - -void -timer_init(void) -{ - u_long vec; - struct itimerval itv; - struct timeval tv; - time_t tv_sec; - struct timezone tz; - struct tm tm; - - vec = insert_hardint_trampoline(); - ivec[0x08] = vec; - register_callback(vec, int08, "int 08"); - - vec = insert_softint_trampoline(); - ivec[0x1c] = vec; - register_callback(vec, int1c, "int 1c"); - - define_input_port_handler(0x42, inb_timer); - define_input_port_handler(0x40, inb_timer); - - /* Initialize time counter BIOS variable. */ - gettimeofday(&tv, &tz); - tv_sec = tv.tv_sec; - tm = *localtime(&tv_sec); - *(u_long *)&BIOSDATA[0x6c] = - (((tm.tm_hour * 60 + tm.tm_min) * 60) + tm.tm_sec) * 182 / 10; - - itv.it_interval.tv_sec = 0; - itv.it_interval.tv_usec = 54925; /* 1193182/65536 times per second */ - itv.it_value.tv_sec = 0; - itv.it_value.tv_usec = 54925; /* 1193182/65536 times per second */ - if (! timer_disable) - setitimer(ITIMER_REAL, &itv, 0); -} diff --git a/usr.bin/doscmd/trace.c b/usr.bin/doscmd/trace.c deleted file mode 100644 index c710504..0000000 --- a/usr.bin/doscmd/trace.c +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI trace.c,v 2.2 1996/04/08 19:33:07 bostic Exp - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include "doscmd.h" -#include "trap.h" - -int tmode = 0; - -static u_short *saddr; -static u_char *iaddr, ibyte; - -/* locals */ -static void printtrace(regcontext_t *REGS, char *buf); -static __inline void showstate(long, long, char); - -/* - * Before exiting to VM86 mode: - * 1) Always set the trap flag. - * 2) If this is a POPF or IRET instruction, set the trap flag in the saved - * flag state on the stack. - * On entering from VM86 mode: - * 1) Restore the trap flag from our saved flag state. - * 2) If we just finished a POPF or IRET instruction, patch the saved flag - * state on the stack. - */ - -int tracetype; - -int -resettrace(regcontext_t *REGS) -{ - if ((R_EFLAGS & PSL_VM) == 0) /* invalid unless handling a vm86 process */ - return (0); - -/* XXX */ return 1; - - switch (tracetype) { - case 1: - R_EFLAGS &= ~PSL_T; - tracetype = 0; - return (1); - - case 2: - if ((u_char *)MAKEPTR(R_CS, R_IP - 1) == iaddr) - R_IP --; - *iaddr = ibyte; - tracetype = 0; - return (1); - - case 3: - case 4: - R_EFLAGS &= ~PSL_T; - *saddr &= ~PSL_T; - tracetype = 0; - return (1); - } - return (0); -} - -void -tracetrap(regcontext_t *REGS) -{ - u_char *addr; - int n; - char buf[100]; - - if ((R_EFLAGS & PSL_VM) == 0) - return; - - addr = (u_char *)MAKEPTR(R_CS, R_IP); - - n = i386dis(R_CS, R_IP, addr, buf, 0); - printtrace(REGS, buf); - -/* XXX */ - R_EFLAGS |= PSL_T; - return; -/* XXX */ - - - switch (addr[0]) { - case REPNZ: - case REPZ: - tracetype = 2; - iaddr = (u_char *)MAKEPTR(R_CS, R_IP + n); - break; - case PUSHF: - tracetype = 4; - saddr = (u_short *)MAKEPTR(R_SS, R_SP - 2); - break; - case POPF: - tracetype = 3; - saddr = (u_short *)MAKEPTR(R_SS, R_SP + 0); - break; - case IRET: - tracetype = 3; - saddr = (u_short *)MAKEPTR(R_SS, R_SP + 4); -#if 0 - printf("IRET: %04x %04x %04x\n", - ((u_short *)MAKEPTR(R_SS, R_SP))[0], - ((u_short *)MAKEPTR(R_SS, R_SP))[1], - ((u_short *)MAKEPTR(R_SS, R_SP))[2]); -#endif - break; - case OPSIZ: - switch (addr[1]) { - case PUSHF: - tracetype = 4; - saddr = (u_short *)MAKEPTR(R_SS, R_SP - 4); - break; - case POPF: - tracetype = 3; - saddr = (u_short *)MAKEPTR(R_SS, R_SP + 0); - break; - case IRET: - tracetype = 3; - saddr = (u_short *)MAKEPTR(R_SS, R_SP + 8); - break; - default: - tracetype = 1; - break; - } - default: - tracetype = 1; - break; - } - - switch (tracetype) { - case 1: - case 4: - if (R_EFLAGS & PSL_T) - tracetype = 0; - else - R_EFLAGS |= PSL_T; - break; - case 2: - if (*iaddr == TRACETRAP) - tracetype = 0; - else { - ibyte = *iaddr; - *iaddr = TRACETRAP; - } - break; - case 3: - R_EFLAGS |= PSL_T; - if (*saddr & PSL_T) - tracetype = 0; - else - *saddr |= PSL_T; - break; - } -} - -static __inline void -showstate(long flags, long flag, char f) -{ - putc((flags & flag) ? f : ' ', debugf); -} - -static void -printtrace(regcontext_t *REGS, char *buf) -{ - - static int first = 1; -#if BIG_DEBUG - u_char *addr = (u_char *)MAKEPTR(R_CS, R_IP); -#endif - - if (first) { - fprintf(debugf, "%4s:%4s " -#if BIG_DEBUG - ".. .. .. .. .. .. " -#endif - "%-30s " - "%4s %4s %4s %4s %4s %4s %4s %4s %4s %4s %4s\n", - "CS", "IP", "instruction", - "AX", "BX", "CX", "DX", - "DI", "SI", "SP", "BP", - "SS", "DS", "ES"); - first = 0; - } - - fprintf(debugf, "%04x:%04x " -#if BIG_DEBUG - "%02x %02x %02x %02x %02x %02x " -#endif - "%-30s " - "%04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x ", - R_CS, R_IP, -#if BIG_DEBUG - addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], -#endif - buf, - R_AX, R_BX, R_CX, R_DX, R_DI, R_SI, R_SP, R_BP, R_SS, R_DS, R_ES); -#if 0 - fprintf(debugf, "%04x %04x %04x %04x ", - ((u_short *)VECPTR(0x0D760FCA-14))[0], - ((u_short *)VECPTR(0x0D760FCA-14))[1], - ((u_short *)VECPTR(0x0D760F7A+8))[0], - ((u_short *)VECPTR(0x0D760F7A+8))[1]); -#endif - showstate(R_EFLAGS, PSL_C, 'C'); - showstate(R_EFLAGS, PSL_PF, 'P'); - showstate(R_EFLAGS, PSL_AF, 'c'); - showstate(R_EFLAGS, PSL_Z, 'Z'); - showstate(R_EFLAGS, PSL_N, 'N'); - showstate(R_EFLAGS, PSL_T, 'T'); - showstate(R_EFLAGS, PSL_I, 'I'); - showstate(R_EFLAGS, PSL_D, 'D'); - showstate(R_EFLAGS, PSL_V, 'V'); - showstate(R_EFLAGS, PSL_NT, 'n'); - showstate(R_EFLAGS, PSL_RF, 'r'); - showstate(R_EFLAGS, PSL_VM, 'v'); - showstate(R_EFLAGS, PSL_AC, 'a'); - showstate(R_EFLAGS, PSL_VIF, 'i'); - showstate(R_EFLAGS, PSL_VIP, 'p'); - putc('\n', debugf); -} diff --git a/usr.bin/doscmd/trap.c b/usr.bin/doscmd/trap.c deleted file mode 100644 index 02e9437..0000000 --- a/usr.bin/doscmd/trap.c +++ /dev/null @@ -1,635 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI trap.c,v 2.3 1996/04/08 19:33:08 bostic Exp - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <machine/trap.h> - -#include "doscmd.h" -#include "trap.h" -#include "tty.h" -#include "video.h" - -/* -** When the emulator is very busy, it's often common for -** SIGALRM to be missed, leading to missed screen updates. -** -** We update this counter every time a DOS interrupt is processed and -** if it hits a certain threshold, force an update. -** -** When updates occur, the counter is zeroed. -*/ -static int update_counter = 0; -#define BUSY_UPDATES 2000 - -/* -** handle interrupts passed to us by the kernel -*/ -void -fake_int(regcontext_t *REGS, int intnum) -{ - if (R_CS == 0xF000 || (ivec[intnum] >> 16) == 0xF000) { - if (R_CS != 0xF000) - intnum = ((u_char *)VECPTR(ivec[intnum]))[1]; - debug(D_ITRAPS | intnum, "INT %02x:%02x %04x:%04x/%08lx\n", - intnum, R_AH, R_CS, R_IP, ivec[intnum]); - switch (intnum) { - case 0x2f: /* multiplex interrupt */ - int2f((regcontext_t *)®S->sc); - break; - case 0xff: /* doscmd special */ - emuint(REGS); - break; - default: /* should not get here */ - if (vflag) dump_regs(REGS); - fatal("no interrupt set up for 0x%02x\n", intnum); - } - return; - } - - /* user_int: */ - debug(D_TRAPS | intnum, - "INT %02x:%02x [%04lx:%04lx] %04x %04x %04x %04x from %04x:%04x\n", - intnum, R_AH, ivec[intnum] >> 16, ivec[intnum] & 0xffff, - R_AX, R_BX, R_CX, R_DX, R_CS, R_IP); - -#if 0 - if ((intnum == 0x13) && (*(u_char *)VECPTR(ivec[intnum]) != 0xf4)) { -#if 1 - char *addr; /*= (char *)VECPTR(ivec[intnum]);*/ - int i, l, j; - char buf[100]; - - R_CS = 0x2c7; - R_IP = 0x14f9; - addr = (char *)MAKEPTR(R_CS, R_IP); - - printf("\n"); - for (i = 0; i < 100; i++) { - l = i386dis(R_CS, R_IP, addr, buf, 0); - printf("%04x:%04x %s\t;",R_CS,R_IP,buf); - for (j = 0; j < l; j++) - printf(" %02x", (u_char)addr[j]); - printf("\n"); - R_IP += l; - addr += l; - } - exit (0); -#else - tmode = 1; -#endif - } -#endif - - if (intnum == 0) - dump_regs(REGS); - - if (ivec[intnum] == 0) { /* uninitialised interrupt? */ - if (vflag) dump_regs(REGS); - fatal("Call to uninitialised interrupt 0x%02x\n", intnum); - } - - /* - * This is really ugly, but when DOS boots, it seems to loop - * for a while on INT 16:11 INT 21:3E INT 2A:82 - * INT 21:3E is a close(), which seems like something one would - * not sit on for ever, so we will allow it to reset our POLL count. - */ - if (intnum == 0x21 && R_AX == 0x3E) - reset_poll(); - - /* stack for and call the interrupt in vm86 space */ - PUSH((R_FLAGS & ~PSL_I) | (R_EFLAGS & PSL_VIF ? PSL_I : 0), REGS); - PUSH(R_CS, REGS); - PUSH(R_IP, REGS); - R_EFLAGS &= ~PSL_VIF; /* disable interrupts */ - PUTVEC(R_CS, R_IP, ivec[intnum]); -} - -/* make this read a little more intuitively */ -#define ipadvance(c,n) SET16(c->sc_eip, GET16(c->sc_eip) + n) /* move %ip along */ - -#ifdef USE_VM86 -/* entry from NetBSD-style vm86 */ -void -sigurg(struct sigframe *sf) -{ -#define sc (&sf->sf_sc) - int intnum; - u_char *addr; - int rep; - int port; - callback_t func; - -#if 0 - printf("ivec08 = %08x\n", ivec[0x08]); -#endif - - if (tmode) - resettrace(sc); - - switch (VM86_TYPE(sf->sf_code)) { - case VM86_INTx: - intnum = VM86_ARG(sf->sf_code); - switch (intnum) { - case 0x2f: - switch (GET8H(sc->sc_eax)) { - case 0x11: - debug (D_TRAPS|0x2f, "INT 2F:%04x\n", GET16(sc->sc_eax)); - if (int2f_11(sc)) { - /* Skip over int 2f:11 */ - goto out; - } - break; - case 0x43: - debug (D_TRAPS|0x2f, "INT 2F:%04x\n", GET16(sc->sc_eax)); - if (int2f_43(sc)) { - /* Skip over int 2f:43 */ - goto out; - } - break; - } - break; - } - fake_int(sc, intnum); - break; - case VM86_UNKNOWN: - /*XXXXX failed vector also gets here without IP adjust*/ - - addr = (u_char *)MAKEPTR(sc->sc_cs, sc->sc_eip); - rep = 1; - - debug (D_TRAPS2, "%04x:%04x [%02x]", GET16(sc->sc_cs), - GET16(sc->sc_eip), addr[0]); - switch (addr[0]) { - case TRACETRAP: - ipadvance(sc,1); - fake_int(sc, 3); - break; - case INd: - port = addr[1]; - ipadvance(sc,2); - inb(sc, port); - break; - case OUTd: - port = addr[1]; - ipadvance(sc,2); - outb(sc, port); - break; - case INdX: - port = addr[1]; - ipadvance(sc,2); - inx(sc, port); - break; - case OUTdX: - port = addr[1]; - ipadvance(sc,2); - outx(sc, port); - break; - case IN: - ipadvance(sc,1); - inb(sc, GET16(sc->sc_edx)); - break; - case INX: - ipadvance(sc,1); - inx(sc, GET16(sc->sc_edx)); - break; - case OUT: - ipadvance(sc,1); - outb(sc, GET16(sc->sc_edx)); - break; - case OUTX: - ipadvance(sc,1); - outx(sc, GET16(sc->sc_edx)); - break; - case OUTSB: - ipadvance(sc,1); - while (rep-- > 0) - outsb(sc, GET16(sc->sc_edx)); - break; - case OUTSW: - ipadvance(sc,1); - while (rep-- > 0) - outsx(sc, GET16(sc->sc_edx)); - break; - case INSB: - ipadvance(sc,1); - while (rep-- > 0) - insb(sc, GET16(sc->sc_edx)); - break; - case INSW: - ipadvance(sc,1); - while (rep-- > 0) - insx(sc, GET16(sc->sc_edx)); - break; - case LOCK: - debug(D_TRAPS2, "lock\n"); - ipadvance(sc,1); - break; - case HLT: /* BIOS entry points populated with HLT */ - func = find_callback(GETVEC(sc->sc_cs, sc->sc_eip)); - if (func) { - ipadvance(sc,); - SET16(sc->sc_eip, GET16(sc->sc_eip) + 1); - func(sc); - break; - } - default: - dump_regs(sc); - fatal("unsupported instruction\n"); - } - break; - default: - dump_regs(sc); - printf("code = %04x\n", sf->sf_code); - fatal("unrecognized vm86 trap\n"); - } - -out: - if (tmode) - tracetrap(sc); -#undef sc -#undef ipadvance -} - -#else /* USE_VM86 */ - -/* entry from FreeBSD, BSD/OS vm86 */ -void -sigbus(struct sigframe *sf) -{ - u_char *addr; - int tempflags,okflags; - int intnum; - int port; - callback_t func; - regcontext_t *REGS = (regcontext_t *)(&sf->sf_uc.uc_mcontext); - - if (!(R_EFLAGS && PSL_VM)) - fatal("SIGBUS in the emulator\n"); - - if ((int)sf->sf_siginfo != 0) { - switch (sf->sf_uc.uc_mcontext.mc_trapno) { - case T_PAGEFLT: - debug(D_TRAPS2, "Page fault, trying to access 0x%x\n", - sf->sf_addr); - /* nothing but accesses to video memory can fault for now */ - if (vmem_pageflt(sf) == 0) - goto out; - /* FALLTHROUGH */ - default: - dump_regs(REGS); - fatal("SIGBUS code %d, trapno: %d, err: %d\n", - (int)sf->sf_siginfo, sf->sf_uc.uc_mcontext.mc_trapno, - sf->sf_uc.uc_mcontext.mc_err); - /* NOTREACHED */ - } - } - - addr = (u_char *)MAKEPTR(R_CS, R_IP); - - if (tmode) - resettrace(REGS); - - if ((R_EFLAGS & (PSL_VIP | PSL_VIF)) == (PSL_VIP | PSL_VIF)) { - resume_interrupt(); - goto out; - } - -/* printf("%p\n", addr); fflush(stdout); */ - debug (D_TRAPS2, "%04x:%04x [%02x %02x %02x] ", R_CS, R_IP, - (int)addr[0], (int)addr[1], (int)addr[2]); -#if 0 - if ((int)addr[0] == 0x67) { - int i; - printf("HERE\n"); fflush(stdout); - printf("addr: %p\n", REGS); fflush(stdout); - for (i = 0; i < 21 * 4; i++) { - printf("%d: %x\n", i, ((u_char *)REGS)[i]); - fflush(stdout); - } - printf("Trapno, error: %p %p\n", REGS->sc.sc_trapno, REGS->sc.sc_err); - fflush(stdout); - dump_regs(REGS); - } -#endif - - switch (addr[0]) { /* what was that again dear? */ - - case CLI: - debug (D_TRAPS2, "cli\n"); - R_IP++; - R_EFLAGS &= ~PSL_VIP; - break; - - case STI: - debug (D_TRAPS2, "sti\n"); - R_IP++; - R_EFLAGS |= PSL_VIP; -#if 0 - if (update_counter++ > BUSY_UPDATES) - sigalrm(sf); -#endif - break; - - case PUSHF: - debug (D_TRAPS2, "pushf <- 0x%lx\n", R_EFLAGS); - R_IP++; - PUSH((R_FLAGS & ~PSL_I) | (R_EFLAGS & PSL_VIF ? PSL_I : 0), - REGS); - break; - - case IRET: - R_IP = POP(REGS); /* get new cs:ip off the stack */ - R_CS = POP(REGS); - debug (D_TRAPS2, "iret to %04x:%04x ", R_CS, R_IP); - /* FALLTHROUGH */ /* 'safe' flag pop operation */ - - case POPF: -/* XXX */ - fatal("popf/iret in emulator"); - - if (addr[0] == POPF) - R_IP++; - /* get flags from stack */ - tempflags = POP(REGS); - /* flags we consider OK */ - okflags = (PSL_ALLCC | PSL_T | PSL_D | PSL_V); - /* keep state of non-OK flags */ - R_FLAGS = ((R_FLAGS & ~okflags) | - /* pop state of OK flags */ - (tempflags & okflags)); - - /* restore pseudo PSL_I flag */ - IntState = tempflags & PSL_I; - debug(D_TRAPS2, "popf -> 0x%lx\n", R_EFLAGS); - break; - - case TRACETRAP: - debug(D_TRAPS2, "ttrap\n"); - R_IP++; - fake_int(REGS, 3); - break; - - case INTn: - intnum = addr[1]; - R_IP += 2; /* nobody else will do it for us */ - switch (intnum) { - case 0x2f: - switch (R_AH) { /* function number */ - case 0x11: - debug (D_TRAPS|0x2f, "INT 2F:%04x\n", R_AX); - if (int2f_11(REGS)) { - /* Skip over int 2f:11 */ - goto out; - } - break; - case 0x43: - debug (D_TRAPS|0x2f, "INT 2F:%04x\n", R_AX); - if (int2f_43(REGS)) { - /* Skip over int 2f:43 */ - goto out; - } - break; - } - break; - } - fake_int(REGS, intnum); - break; - - case INd: /* XXX implement in/out */ - R_IP += 2; - port = addr[1]; - inb(REGS, port); - break; - case IN: - R_IP++; - inb(REGS,R_DX); - break; - case INX: - R_IP++; - inx(REGS,R_DX); - break; - case INdX: - R_IP += 2; - port = addr[1]; - inx(REGS, port); - break; - case INSB: - R_IP++; - printf("(missed) INSB <- 0x%02x\n",R_DX); - break; - case INSW: - R_IP++; - printf("(missed) INSW <- 0x%02x\n",R_DX); - break; - - case OUTd: - R_IP += 2; - port = addr[1]; - outb(REGS, port); - break; - case OUTdX: - R_IP += 2; - port = addr[1]; - outx(REGS, port); - break; - case OUT: - R_IP++; - outb(REGS, R_DX); - break; - case OUTX: - R_IP++; - outx(REGS, R_DX); - break; - case OUTSB: - R_IP++; - printf("(missed) OUTSB -> 0x%02x\n",R_DX); - break; - case OUTSW: - R_IP++; - printf("(missed) OUTSW -> 0x%02x\n",R_DX); -/* tmode = 1; */ - break; - - case LOCK: - debug(D_TRAPS2, "lock\n"); - R_IP++; - break; - - case HLT: /* BIOS entry points populated with HLT */ - func = find_callback(MAKEVEC(R_CS, R_IP)); - if (func) { - R_IP++; /* pass HLT opcode */ - func(REGS); -/* dump_regs(REGS); */ -#if 0 - update_counter += 5; - if (update_counter > BUSY_UPDATES) - sigalrm(sf); -#endif - break; - } -/* if (R_EFLAGS & PSL_VIF) { */ - R_IP++; - tty_pause(); - goto out; -/* } */ - /* FALLTHROUGH */ - - default: - dump_regs(REGS); - fatal("unsupported instruction\n"); - } - -out: - if (tmode) - tracetrap(REGS); -} -#endif /* USE_VM86 */ - -void -sigtrace(struct sigframe *sf) -{ - int x; - regcontext_t *REGS = (regcontext_t *)(&sf->sf_uc.uc_mcontext); - - if (R_EFLAGS & PSL_VM) { - debug(D_ALWAYS, "Currently in DOS\n"); - dump_regs(REGS); - for (x = 0; x < 16; ++x) - debug(D_ALWAYS, " %02x", *(unsigned char *)x); - putc('\n', debugf); - } else { - debug(D_ALWAYS, "Currently in the emulator\n"); - sigalrm(sf); - } -} - -void -sigtrap(struct sigframe *sf) -{ - int intnum; - int trapno; - regcontext_t *REGS = (regcontext_t *)(&sf->sf_uc.uc_mcontext); - - if ((R_EFLAGS & PSL_VM) == 0) { - dump_regs(REGS); - fatal("%04x:%08x Sigtrap in protected mode\n", R_CS, R_IP); - } - - if (tmode) - if (resettrace(REGS)) - goto doh; - -#ifdef __FreeBSD__ - trapno = (int)sf->sf_siginfo; /* XXX GROSTIC HACK ALERT */ -#else - trapno = sc->sc_trapno; -#endif - if (trapno == T_BPTFLT) - intnum = 3; - else - intnum = 1; - - PUSH((R_FLAGS & ~PSL_I) | (R_EFLAGS & PSL_VIF ? PSL_I : 0), REGS); - PUSH(R_CS, REGS); - PUSH(R_IP, REGS); - R_FLAGS &= ~PSL_T; - PUTVEC(R_CS, R_IP, ivec[intnum]); - -doh: - if (tmode) - tracetrap(REGS); -} - -void -breakpoint(struct sigframe *sf) -{ - regcontext_t *REGS = (regcontext_t *)(&sf->sf_uc.uc_mcontext); - - if (R_EFLAGS & PSL_VM) - printf("doscmd "); - printf("breakpoint: %04x\n", *(u_short *)0x8e64); - - __asm__ volatile("mov 0, %eax"); - __asm__ volatile(".byte 0x0f"); /* MOV DR6,EAX */ - __asm__ volatile(".byte 0x21"); - __asm__ volatile(".byte 0x1b"); -} - -/* -** periodic updates -*/ -void -sigalrm(struct sigframe *sf) -{ - regcontext_t *REGS = (regcontext_t *)(&sf->sf_uc.uc_mcontext); - - if (tmode) - resettrace(REGS); - - update_counter = 0; /* remember we've updated */ - video_update((regcontext_t *)®S->sc); - hardint(0x00); - - if (tmode) - tracetrap(REGS); -} - -void -sigill(struct sigframe *sf) -{ - regcontext_t *REGS = (regcontext_t *)(&sf->sf_uc.uc_mcontext); - - fprintf(stderr, "Signal %d from DOS program\n", sf->sf_signum); - dump_regs(REGS); - fatal("%04x:%04x Illegal instruction\n", R_CS, R_IP); - -} - -void -sigfpe(struct sigframe *sf) -{ - regcontext_t *REGS = (regcontext_t *)(&sf->sf_uc.uc_mcontext); - - if (R_EFLAGS & PSL_VM) { - dump_regs(REGS); - debug(D_ALWAYS, "DOS program caused floating point fault\n"); -/*XXX Look into that !! */ - fake_int(REGS, 0); /* call handler XXX rather bogus, eh? */ - return; - } - dump_regs(REGS); - fatal("%04x:%04x Floating point fault in emulator.\n", R_CS, R_IP); -} diff --git a/usr.bin/doscmd/trap.h b/usr.bin/doscmd/trap.h deleted file mode 100644 index 853d2e7..0000000 --- a/usr.bin/doscmd/trap.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI trap.h,v 2.2 1996/04/08 19:33:09 bostic Exp - * - * $FreeBSD$ - */ - -#define CLI 0xfa -#define STI 0xfb -#define PUSHF 0x9c -#define POPF 0x9d -#define INTn 0xcd -#define TRACETRAP 0xcc -#define IRET 0xcf -#define LOCK 0xf0 -#define HLT 0xf4 - -#define OPSIZ 0x66 -#define REPNZ 0xf2 -#define REPZ 0xf3 - -#define INd 0xe4 -#define INdX 0xe5 -#define OUTd 0xe6 -#define OUTdX 0xe7 - -#define IN 0xec -#define INX 0xed -#define OUT 0xee -#define OUTX 0xef - -#define INSB 0x6c -#define INSW 0x6d -#define OUTSB 0x6e -#define OUTSW 0x6f - -#define IOFS 0x64 -#define IOGS 0x65 - -#define TWOBYTE 0x0f -#define LAR 0x02 - -#define AC_P 0x8000 /* Present */ -#define AC_P0 0x0000 /* Priv Level 0 */ -#define AC_P1 0x2000 /* Priv Level 1 */ -#define AC_P2 0x4000 /* Priv Level 2 */ -#define AC_P3 0x6000 /* Priv Level 3 */ -#define AC_S 0x1000 /* Memory Segment */ -#define AC_RO 0x0000 /* Read Only */ -#define AC_RW 0x0200 /* Read Write */ -#define AC_RWE 0x0600 /* Read Write Expand Down */ -#define AC_EX 0x0800 /* Execute Only */ -#define AC_EXR 0x0a00 /* Execute Readable */ -#define AC_EXC 0x0c00 /* Execute Only Conforming */ -#define AC_EXRC 0x0e00 /* Execute Readable Conforming */ -#define AC_A 0x0100 /* Accessed */ - -extern void fake_int(regcontext_t *REGS, int); -extern void sigtrap(struct sigframe *sf); -extern void sigtrace(struct sigframe *sf); -extern void sigalrm(struct sigframe *sf); -extern void sigill(struct sigframe *sf); -extern void sigfpe(struct sigframe *sf); -extern void sigsegv(struct sigframe *sf); -extern void breakpoint(struct sigframe *sf); -#ifdef USE_VM86 -extern void sigurg(struct sigframe *sf); -#else -extern void sigbus(struct sigframe *sf); -#endif diff --git a/usr.bin/doscmd/tty.c b/usr.bin/doscmd/tty.c deleted file mode 100644 index 506a04e..0000000 --- a/usr.bin/doscmd/tty.c +++ /dev/null @@ -1,2233 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI tty.c,v 2.4 1996/04/08 22:03:27 prb Exp - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/ioctl.h> -#include <sys/time.h> -#include <sys/types.h> -#include <sys/mman.h> -#include <ctype.h> -#include <err.h> -#include <fcntl.h> -#include <limits.h> -#include <paths.h> -#include <signal.h> -#include <stdio.h> -#include <termios.h> -#include <unistd.h> -#ifdef __FreeBSD__ -# include <osreldate.h> -# if __FreeBSD_version >= 500014 -# include <sys/kbio.h> -# else -# include <machine/console.h> -# endif -#else -# ifdef __NetBSD__ -# include "machine/pccons.h" -# else /* BSD/OS */ -# include "/sys/i386/isa/pcconsioctl.h" -# endif -#endif - -#ifndef NO_X -#include <X11/Xlib.h> -#include <X11/Xutil.h> -#include <X11/keysym.h> -#endif - -#include "doscmd.h" -#include "AsyncIO.h" -#include "font8x8.h" -#include "font8x14.h" -#include "font8x16.h" -#include "mouse.h" -#include "trap.h" -#include "tty.h" -#include "video.h" - -#ifndef NO_X -static int show = 1; -#endif -static int blink = 1; -int flipdelete = 0; /* Flip meaning of delete and backspace */ -static u_short break_code = 0x00; -static u_short scan_code = 0x00; -int height; -int width; -int vattr; -const char *xfont = 0; - -#ifndef NO_X -Display *dpy; -Window win; -XFontStruct *font; -XImage *xi = 0; -Visual *visual; -unsigned int depth; -unsigned long black; -unsigned long white; -int FW, FH, FD; -GC gc; -GC cgc; -int xfd; - -/* LUT for the vram -> XImage conversion */ -u_int8_t lut[4][256][8]; - -/* X pixel values for the RGB triples */ -unsigned long pixels[16]; -#endif - -typedef struct TextLine { - u_short *data; - u_char max_length; /* Not used, but here for future use */ - u_char changed:1; -} TextLine; -TextLine *lines = NULL; - -int kbd_fd = -1; -int kbd_read = 0; - -static struct termios tty_cook, tty_raw; - -#define row (CursRow0) -#define col (CursCol0) - -/* Local functions */ -static void _kbd_event(int, int, void *, regcontext_t *); -static void Failure(void *); -static void SetVREGCur(void); -#ifndef NO_X -static void debug_event(int, int, void *, regcontext_t *); -#endif -static unsigned char inb_port60(int); -static int inrange(int, int, int); -#ifndef NO_X -static void kbd_event(int, int, void *, regcontext_t *); -static u_short read_raw_kbd(int, u_short *); -static void setgc(u_short); -static void video_async_event(int, int, void *, regcontext_t *); -#endif - -#ifndef NO_X -static void dac2rgb(XColor *, int); -static void prepare_lut(void); -static void putchar_graphics(int, int, int); -static void tty_rwrite_graphics(int, int, int); -static int video_event(XEvent *ev); -static void video_update_graphics(void); -static void video_update_text(void); -static void vram2ximage(void); -#endif - -#define PEEKSZ 16 - -#define K_NEXT *(u_short *)0x41a -#define K_FREE *(u_short *)0x41c -#define K_BUFSTARTP *(u_short *)0x480 -#define K_BUFENDP *(u_short *)0x482 -#define K_BUFSTART ((u_short *)(0x400 + *(u_short *)0x480)) -#define K_BUFEND ((u_short *)(0x400 + *(u_short *)0x482)) -#define K_BUF(i) *((u_short *)((u_char *)0x400 + (i))) - -#define K1_STATUS BIOSDATA[0x17] -#define K1_RSHIFT 0x01 -#define K1_LSHIFT 0x02 -#define K1_SHIFT 0x03 -#define K1_CTRL 0x04 -#define K1_ALT 0x08 -#define K1_SLOCK 0x10 /* Active */ -#define K1_NLOCK 0x20 /* Active */ -#define K1_CLOCK 0x40 /* Active */ -#define K1_INSERT 0x80 /* Active */ - -#define K2_STATUS BIOSDATA[0x18] -#define K2_LCTRL 0x01 -#define K2_LALT 0x02 -#define K2_SYSREQ 0x04 -#define K2_PAUSE 0x08 -#define K2_SLOCK 0x10 /* Actually held down */ -#define K2_NLOCK 0x20 /* Actually held down */ -#define K2_CLOCK 0x40 /* Actually held down */ -#define K2_INSERT 0x80 /* Actually held down */ - -#define K3_STATUS BIOSDATA[0x96] -#define K3_E1 0x01 /* Last code read was e1 */ -#define K3_E2 0x02 /* Last code read was e2 */ -#define K3_RCTRL 0x04 -#define K3_RALT 0x08 -#define K3_ENHANCED 0x10 -#define K3_FORCENLOCK 0x20 -#define K3_TWOBYTE 0x40 /* last code was first of 2 */ -#define K3_READID 0x80 /* read ID in progress */ - -#define K4_STATUS BIOSDATA[0x97] -#define K4_SLOCK_LED 0x01 -#define K4_NLOCK_LED 0x02 -#define K4_CLOCK_LED 0x04 -#define K4_ACK 0x10 /* ACK received from keyboard */ -#define K4_RESEND 0x20 /* RESEND received from keyboard */ -#define K4_LED 0x40 /* LED update in progress */ -#define K4_ERROR 0x80 - -static void -Failure(void *arg __unused) -{ - fprintf(stderr, "X Connection shutdown\n"); - quit(1); -} - -static void -SetVREGCur() -{ - int cp = row * width + col; - VGA_CRTC[CRTC_CurLocHi] = cp >> 8; - VGA_CRTC[CRTC_CurLocLo] = cp & 0xff; -} - -static void -console_denit(void *arg) -{ - int fd = *(int *)arg; - -#ifdef __FreeBSD__ - if (ioctl(fd, KDSKBMODE, K_XLATE)) - perror("KDSKBMODE/K_XLATE"); -#else -# ifdef __NetBSD__ - if (ioctl(fd, CONSOLE_X_MODE_OFF, 0)) - perror("CONSOLE_X_MODE_OFF"); -# else /* BSD/OS */ - if (ioctl(fd, PCCONIOCCOOK, 0)) - perror("PCCONIOCCOOK"); -# endif -#endif - if (tcsetattr(fd, TCSANOW, &tty_cook)) - perror("tcsetattr"); -} - -void -_kbd_event(int fd, int cond, void *arg __unused, regcontext_t *REGS __unused) -{ - if (!(cond & AS_RD)) - return; - printf("_kbd_event: fd=%d\n", fd); - kbd_read = 1; -} - -void -console_init() -{ - int fd; - caddr_t addr; - - if ((fd = open(_PATH_DEV "vga", 2)) < 0) { - perror(_PATH_DEV "vga"); - quit(1); - } - addr = mmap((caddr_t)0xA0000, 5 * 64 * 1024, - PROT_EXEC | PROT_READ | PROT_WRITE, - MAP_FILE | MAP_FIXED | MAP_SHARED, - fd, 0); - if (addr != (caddr_t)0xA0000) { - perror("mmap"); - quit(1); - } - -#if 0 - addr = mmap((caddr_t)0x100000 - 0x1000, 0x1000, - PROT_EXEC | PROT_READ | PROT_WRITE, - MAP_FILE | MAP_FIXED | MAP_SHARED, - fd, 0); - if (addr != (caddr_t)(0x100000 - 0x1000)) { - perror("mmap"); - quit(1); - } -#endif - - if ((fd = open(_PATH_CONSOLE, 2)) < 0) { - perror(_PATH_CONSOLE); - quit(1); - } - - fd = squirrel_fd(fd); - kbd_fd = fd; - -#ifdef __FreeBSD__ - if (ioctl(fd, KDSKBMODE, K_RAW)) { - perror("KDSKBMODE/K_RAW"); - quit(1); - } -#else -# ifdef __NetBSD__ - if (ioctl(fd, CONSOLE_X_MODE_ON, 0)) { - perror("CONSOLE_X_MODE_ON"); - quit(1); - } -# else /* BSD/OS */ - if (ioctl(fd, PCCONIOCRAW, 0)) { - perror("PCCONIOCRAW"); - quit(1); - } -# endif -#endif - - call_on_quit(console_denit, &kbd_fd); - - if (fcntl(fd, F_SETFL, O_NDELAY|O_ASYNC) < 0) { - perror("fcntl"); - quit(1); - } - if (tcgetattr(fd, &tty_cook)) { - perror("tcgetattr"); - quit(1); - } - tty_raw = tty_cook; - cfmakeraw(&tty_raw); - if (tcsetattr(fd, TCSANOW, &tty_raw)) { - perror("tcsetattr"); - quit(1); - } - -#if 0 - _RegisterIO(STDIN_FILENO, debug_event, 0, Failure); - _RegisterIO(fd, kbd_event, 0, Failure); -#endif - _RegisterIO(fd, _kbd_event, 0, Failure); -} - -void -video_setborder(int color __unused) -{ -#ifndef NO_X - XSetWindowBackground(dpy, win, pixels[color & 0xf]); -#endif -} -void -video_blink(int mode) -{ - blink = mode; -} - -#ifndef NO_X -static void -setgc(u_short attr) -{ - XGCValues v; - if (blink && !show && (attr & 0x8000)) - v.foreground = pixels[(attr >> 12) & 0x07]; - else - v.foreground = pixels[(attr >> 8) & 0x0f]; - - v.background = pixels[(attr >> 12) & (blink ? 0x07 : 0x0f)]; - XChangeGC(dpy, gc, GCForeground|GCBackground, &v); -} -#endif - -void -video_update(regcontext_t *REGS __unused) -{ -#ifndef NO_X - static int icnt = 3; - - if (kbd_read) - kbd_event(kbd_fd, AS_RD, 0, REGS); - - if (--icnt == 0) { - icnt = 3; - - lpt_poll(); /* Handle timeout on lpt code */ - - /* quick and dirty */ - if (VGA_ATC[ATC_ModeCtrl] & 1) - video_update_graphics(); - else - video_update_text(); - } -#endif -} - -#ifndef NO_X -static void -video_update_graphics() -{ - vram2ximage(); - - XPutImage(dpy, win, DefaultGC(dpy, DefaultScreen(dpy)), - xi, 0, 0, 0, 0, width, height); - XFlush(dpy); - - return; -} - -static void -video_update_text() -{ - static int or = -1; - static int oc = -1; - - - static char buf[256]; - int r, c; - int attr = vmem[0] & 0xff00; - XGCValues v; - - if (xmode) { - wakeup_poll(); /* Wake up anyone waiting on kbd poll */ - - show ^= 1; - - setgc(attr); - - for (r = 0; r < height; ++r) { - int cc = 0; - - if (!lines[r].changed) { - if ((r == or || r == row) && (or != row || oc != col)) - lines[r].changed = 1; - else { - for (c = 0; c < width; ++c) { - if (lines[r].data[c] != vmem[r * width + c]) { - lines[r].changed = 1; - break; - } - if (blink && lines[r].data[c] & 0x8000) { - lines[r].changed = 1; - break; - } - } - } - } - - if (!lines[r].changed) - continue; - - reset_poll(); - lines[r].changed = 0; - memcpy(lines[r].data, - &vmem[r * width], sizeof(u_short) * width); - - for (c = 0; c < width; ++c) { - int cv = vmem[r * width + c]; - if ((cv & 0xff00) != attr) { - if (cc < c) - XDrawImageString(dpy, win, gc, - 2 + cc * FW, - 2 + (r + 1) * FH, - buf + cc, c - cc); - cc = c; - attr = cv & 0xff00; - setgc(attr); - } - buf[c] = (cv & 0xff) ? cv & 0xff : ' '; - } - if (cc < c) { - XDrawImageString(dpy, win, gc, - 2 + cc * FW, - 2 + (r + 1) * FH, - buf + cc, c - cc); - } - } - or = row; - oc = col; - - if (CursStart <= CursEnd && CursEnd <= FH && - show && row < height && col < width) { - - attr = vmem[row * width + col] & 0xff00; - v.foreground = pixels[(attr >> 8) & 0x0f] ^ - pixels[(attr >> 12) & (blink ? 0x07 : 0x0f)]; - if (v.foreground) { - v.function = GXxor; - } else { - v.foreground = pixels[7]; - v.function = GXcopy; - } - XChangeGC(dpy, cgc, GCForeground | GCFunction, &v); - XFillRectangle(dpy, win, cgc, - 2 + col * FW, - 2 + row * FH + CursStart + FD, - FW, CursEnd + 1 - CursStart); - } - - if (mouse_status.installed && mouse_status.show) { - c = mouse_status.x / mouse_status.hmickey; - r = mouse_status.y / mouse_status.vmickey; - - lines[r].changed = 1; - attr = vmem[r * width + c] & 0xff00; - v.foreground = pixels[(attr >> 8) & 0x0f] ^ - pixels[(attr >> 12) & 0x0f]; - if (v.foreground) { - v.function = GXxor; - } else { - v.foreground = pixels[7]; - v.function = GXcopy; - } - XChangeGC(dpy, cgc, GCForeground | GCFunction, &v); - XFillRectangle(dpy, win, cgc, - 2 + c * FW, - 2 + r * FH + 2, - FW, FH); - } - - XFlush(dpy); - } -} - -/* Convert the contents of the video RAM into an XImage. - - Bugs: - The function is way too slow. - - It only works for the 16 color modes. - - It only works on 15/16-bit TrueColor visuals. */ -static void -vram2ximage() -{ - int i, x, y, yoffset; - u_int16_t *image = (u_int16_t *)xi->data; - - yoffset = 0; - for (y = 0; y < height; y++) { - yoffset += width / 8; - for (x = 0; x < width; x += 8) { - int offset = yoffset + x / 8; - for (i = 0; i < 8; i++) { - int color = lut[0][vplane0[offset]][i] | - lut[1][vplane1[offset]][i] | - lut[2][vplane2[offset]][i] | - lut[3][vplane3[offset]][i]; - *image++ = (u_int16_t)pixels[color]; - } - } - } - - return; -} - -static u_short Ascii2Scan[] = { - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x000e, 0x000f, 0xffff, 0xffff, 0xffff, 0x001c, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0x0001, 0xffff, 0xffff, 0xffff, 0xffff, - 0x0039, 0x0102, 0x0128, 0x0104, 0x0105, 0x0106, 0x0108, 0x0028, - 0x010a, 0x010b, 0x0109, 0x010d, 0x0033, 0x000c, 0x0034, 0x0035, - 0x000b, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, - 0x0009, 0x000a, 0x0127, 0x0027, 0x0133, 0x000d, 0x0134, 0x0135, - 0x0103, 0x011e, 0x0130, 0x012e, 0x0120, 0x0112, 0x0121, 0x0122, - 0x0123, 0x0117, 0x0124, 0x0125, 0x0126, 0x0132, 0x0131, 0x0118, - 0x0119, 0x0110, 0x0113, 0x011f, 0x0114, 0x0116, 0x012f, 0x0111, - 0x012d, 0x0115, 0x012c, 0x001a, 0x002b, 0x001b, 0x0107, 0x010c, - 0x0029, 0x001e, 0x0030, 0x002e, 0x0020, 0x0012, 0x0021, 0x0022, - 0x0023, 0x0017, 0x0024, 0x0025, 0x0026, 0x0032, 0x0031, 0x0018, - 0x0019, 0x0010, 0x0013, 0x001f, 0x0014, 0x0016, 0x002f, 0x0011, - 0x002d, 0x0015, 0x002c, 0x011a, 0x012b, 0x011b, 0x0129, 0xffff, -}; -#endif - -struct { - u_short base; - u_short shift; - u_short ctrl; - u_short alt; -} ScanCodes[] = { - { 0xffff, 0xffff, 0xffff, 0xffff }, /* key 0 */ - { 0x011b, 0x011b, 0x011b, 0xffff }, /* key 1 - Escape key */ - { 0x0231, 0x0221, 0xffff, 0x7800 }, /* key 2 - '1' */ - { 0x0332, 0x0340, 0x0300, 0x7900 }, /* key 3 - '2' - special handling */ - { 0x0433, 0x0423, 0xffff, 0x7a00 }, /* key 4 - '3' */ - { 0x0534, 0x0524, 0xffff, 0x7b00 }, /* key 5 - '4' */ - { 0x0635, 0x0625, 0xffff, 0x7c00 }, /* key 6 - '5' */ - { 0x0736, 0x075e, 0x071e, 0x7d00 }, /* key 7 - '6' */ - { 0x0837, 0x0826, 0xffff, 0x7e00 }, /* key 8 - '7' */ - { 0x0938, 0x092a, 0xffff, 0x7f00 }, /* key 9 - '8' */ - { 0x0a39, 0x0a28, 0xffff, 0x8000 }, /* key 10 - '9' */ - { 0x0b30, 0x0b29, 0xffff, 0x8100 }, /* key 11 - '0' */ - { 0x0c2d, 0x0c5f, 0x0c1f, 0x8200 }, /* key 12 - '-' */ - { 0x0d3d, 0x0d2b, 0xffff, 0x8300 }, /* key 13 - '=' */ - { 0x0e08, 0x0e08, 0x0e7f, 0xffff }, /* key 14 - backspace */ - { 0x0f09, 0x0f00, 0xffff, 0xffff }, /* key 15 - tab */ - { 0x1071, 0x1051, 0x1011, 0x1000 }, /* key 16 - 'Q' */ - { 0x1177, 0x1157, 0x1117, 0x1100 }, /* key 17 - 'W' */ - { 0x1265, 0x1245, 0x1205, 0x1200 }, /* key 18 - 'E' */ - { 0x1372, 0x1352, 0x1312, 0x1300 }, /* key 19 - 'R' */ - { 0x1474, 0x1454, 0x1414, 0x1400 }, /* key 20 - 'T' */ - { 0x1579, 0x1559, 0x1519, 0x1500 }, /* key 21 - 'Y' */ - { 0x1675, 0x1655, 0x1615, 0x1600 }, /* key 22 - 'U' */ - { 0x1769, 0x1749, 0x1709, 0x1700 }, /* key 23 - 'I' */ - { 0x186f, 0x184f, 0x180f, 0x1800 }, /* key 24 - 'O' */ - { 0x1970, 0x1950, 0x1910, 0x1900 }, /* key 25 - 'P' */ - { 0x1a5b, 0x1a7b, 0x1a1b, 0xffff }, /* key 26 - '[' */ - { 0x1b5d, 0x1b7d, 0x1b1d, 0xffff }, /* key 27 - ']' */ - { 0x1c0d, 0x1c0d, 0x1c0a, 0xffff }, /* key 28 - CR */ - { 0xffff, 0xffff, 0xffff, 0xffff }, /* key 29 - control */ - { 0x1e61, 0x1e41, 0x1e01, 0x1e00 }, /* key 30 - 'A' */ - { 0x1f73, 0x1f53, 0x1f13, 0x1f00 }, /* key 31 - 'S' */ - { 0x2064, 0x2044, 0x2004, 0x2000 }, /* key 32 - 'D' */ - { 0x2166, 0x2146, 0x2106, 0x2100 }, /* key 33 - 'F' */ - { 0x2267, 0x2247, 0x2207, 0x2200 }, /* key 34 - 'G' */ - { 0x2368, 0x2348, 0x2308, 0x2300 }, /* key 35 - 'H' */ - { 0x246a, 0x244a, 0x240a, 0x2400 }, /* key 36 - 'J' */ - { 0x256b, 0x254b, 0x250b, 0x2500 }, /* key 37 - 'K' */ - { 0x266c, 0x264c, 0x260c, 0x2600 }, /* key 38 - 'L' */ - { 0x273b, 0x273a, 0xffff, 0xffff }, /* key 39 - ';' */ - { 0x2827, 0x2822, 0xffff, 0xffff }, /* key 40 - ''' */ - { 0x2960, 0x297e, 0xffff, 0xffff }, /* key 41 - '`' */ - { 0xffff, 0xffff, 0xffff, 0xffff }, /* key 42 - left shift */ - { 0x2b5c, 0x2b7c, 0x2b1c, 0xffff }, /* key 43 - '' */ - { 0x2c7a, 0x2c5a, 0x2c1a, 0x2c00 }, /* key 44 - 'Z' */ - { 0x2d78, 0x2d58, 0x2d18, 0x2d00 }, /* key 45 - 'X' */ - { 0x2e63, 0x2e43, 0x2e03, 0x2e00 }, /* key 46 - 'C' */ - { 0x2f76, 0x2f56, 0x2f16, 0x2f00 }, /* key 47 - 'V' */ - { 0x3062, 0x3042, 0x3002, 0x3000 }, /* key 48 - 'B' */ - { 0x316e, 0x314e, 0x310e, 0x3100 }, /* key 49 - 'N' */ - { 0x326d, 0x324d, 0x320d, 0x3200 }, /* key 50 - 'M' */ - { 0x332c, 0x333c, 0xffff, 0xffff }, /* key 51 - ',' */ - { 0x342e, 0x343e, 0xffff, 0xffff }, /* key 52 - '.' */ - { 0x352f, 0x353f, 0xffff, 0xffff }, /* key 53 - '/' */ - { 0xffff, 0xffff, 0xffff, 0xffff }, /* key 54 - right shift - */ - { 0x372a, 0xffff, 0x3772, 0xffff }, /* key 55 - prt-scr - */ - { 0xffff, 0xffff, 0xffff, 0xffff }, /* key 56 - Alt - */ - { 0x3920, 0x3920, 0x3920, 0x3920 }, /* key 57 - space bar */ - { 0xffff, 0xffff, 0xffff, 0xffff }, /* key 58 - caps-lock - */ - { 0x3b00, 0x5400, 0x5e00, 0x6800 }, /* key 59 - F1 */ - { 0x3c00, 0x5500, 0x5f00, 0x6900 }, /* key 60 - F2 */ - { 0x3d00, 0x5600, 0x6000, 0x6a00 }, /* key 61 - F3 */ - { 0x3e00, 0x5700, 0x6100, 0x6b00 }, /* key 62 - F4 */ - { 0x3f00, 0x5800, 0x6200, 0x6c00 }, /* key 63 - F5 */ - { 0x4000, 0x5900, 0x6300, 0x6d00 }, /* key 64 - F6 */ - { 0x4100, 0x5a00, 0x6400, 0x6e00 }, /* key 65 - F7 */ - { 0x4200, 0x5b00, 0x6500, 0x6f00 }, /* key 66 - F8 */ - { 0x4300, 0x5c00, 0x6600, 0x7000 }, /* key 67 - F9 */ - { 0x4400, 0x5d00, 0x6700, 0x7100 }, /* key 68 - F10 */ - { 0xffff, 0xffff, 0xffff, 0xffff }, /* key 69 - num-lock - */ - { 0xffff, 0xffff, 0xffff, 0xffff }, /* key 70 - scroll-lock - */ - { 0x4700, 0x4737, 0x7700, 0xffff }, /* key 71 - home */ - { 0x4800, 0x4838, 0xffff, 0xffff }, /* key 72 - cursor up */ - { 0x4900, 0x4939, 0x8400, 0xffff }, /* key 73 - page up */ - { 0x4a2d, 0x4a2d, 0xffff, 0xffff }, /* key 74 - minus sign */ - { 0x4b00, 0x4b34, 0x7300, 0xffff }, /* key 75 - cursor left */ - { 0xffff, 0x4c35, 0xffff, 0xffff }, /* key 76 - center key */ - { 0x4d00, 0x4d36, 0x7400, 0xffff }, /* key 77 - cursor right */ - { 0x4e2b, 0x4e2b, 0xffff, 0xffff }, /* key 78 - plus sign */ - { 0x4f00, 0x4f31, 0x7500, 0xffff }, /* key 79 - end */ - { 0x5000, 0x5032, 0xffff, 0xffff }, /* key 80 - cursor down */ - { 0x5100, 0x5133, 0x7600, 0xffff }, /* key 81 - page down */ - { 0x5200, 0x5230, 0xffff, 0xffff }, /* key 82 - insert */ - { 0x5300, 0x532e, 0xffff, 0xffff }, /* key 83 - delete */ - { 0xffff, 0xffff, 0xffff, 0xffff }, /* key 84 - sys key */ - { 0xffff, 0xffff, 0xffff, 0xffff }, /* key 85 */ - { 0xffff, 0xffff, 0xffff, 0xffff }, /* key 86 */ - { 0x8500, 0x5787, 0x8900, 0x8b00 }, /* key 87 - F11 */ - { 0x8600, 0x5888, 0x8a00, 0x8c00 }, /* key 88 - F12 */ -}; - -#ifndef NO_X -void -debug_event(int fd __unused, int cond, void *arg __unused, regcontext_t *REGS) -{ - static char ibuf[1024]; - static int icnt = 0; - static u_short ds = 0; - static u_short di = 0; - static u_short cnt = 16 * 8; - char *ep; - int r; - - if (!(cond & AS_RD)) - return; - - r = read(STDIN_FILENO, ibuf + icnt, sizeof(ibuf) - icnt); - if (r <= 0) - return; - - icnt += r; - - ibuf[icnt] = 0; - while ((ep = strchr(ibuf, '\n')) != 0) { - int ac; - char *_av[16]; - char **av; - - *ep++ = 0; - ac = ParseBuffer(ibuf, av = _av, 16); - - if (ac > 0) { - if (!strcasecmp(av[0], "dump")) { - if (ac > 1) { - char *c; - if ((c = strchr(av[1], ':')) != 0) { - ds = strtol(av[1], 0, 16); - di = strtol(c+1, 0, 16); - } else - di = strtol(av[1], 0, 16); - } - if (ac > 2) - cnt = strtol(av[2], 0, 0); - cnt = (cnt + 0xf) & ~0xf; - if (cnt == 0) - cnt = 0x10; - di &= ~0xf; - - for (r = 0; r < cnt; r += 0x10, di = (di + 0x10) & 0xffff) { - int i; - u_char *ap = (u_char *)(((u_long)ds << 4) + di); - - printf("%04x:%04x:", ds, di); - for (i = 0; i < 8; ++i) - printf(" %02x", ap[i]); - printf(" "); - for (i = 8; i < 16; ++i) - printf(" %02x", ap[i]); - printf(": "); - for (i = 0; i < 8; ++i) - printf("%c",(ap[i] < ' ' || ap[i] > '~') ? '.' : ap[i]); - printf(" "); - for (i = 8; i < 16; ++i) - printf("%c",(ap[i] < ' ' || ap[i] > '~') ? '.' : ap[i]); - printf("\n"); - } - } else if (!strcasecmp(av[0], "dis")) { - u_char *ap = (u_char *)(((u_long)ds << 4) + di); - - if (ac > 1) { - char *c; - if ((c = strchr(av[1], ':')) != 0) { - ds = strtol(av[1], 0, 16); - di = strtol(c+1, 0, 16); - } else - di = strtol(av[1], 0, 16); - } - if (ac > 2) - cnt = strtol(av[2], 0, 0); - - for (r = 0; r < cnt; ++r) { - char buf[16]; - int c = i386dis(ds, di, ap, buf, 0); - printf("%04x:%04x %s\n", ds, di, buf); - di += c; - ap += c; - } - } else if (!strcasecmp(av[0], "regs")) { - dump_regs(REGS); - } else if (!strcasecmp(av[0], "force")) { - char *p = av[1]; - - while ((p = *++av) != 0) { - while (*p) { - if (*p >= ' ' && *p <= '~') - KbdWrite(ScanCodes[Ascii2Scan[(int)*p] & 0xff].base); - ++p; - } - } - KbdWrite(ScanCodes[28].base); - } else if (!strcasecmp(av[0], "bell")) { -#ifndef NO_X - XBell(dpy, 0); - XFlush(dpy); -#endif - } else { - fprintf(stderr, "%s: unknown command\n", av[0]); - } - } - - if (ep < ibuf + icnt) { - char *f = ep; - char *t = ibuf; - icnt -= ep - ibuf; - while (icnt--) - *t++ = *f++; - } else - icnt = 0; - ibuf[icnt] = 0; - } -} -#endif - -unsigned char -inb_port60(int port __unused) -{ - int r = break_code; - break_code = 0; - scan_code = 0xffff; - return(r); -} - -#ifndef NO_X -void -kbd_event(int fd, int cond, void *arg __unused, regcontext_t *REGS __unused) -{ - if (!(cond & AS_RD)) - return; - - kbd_read = 0; - - printf("kbd_event: fd=%d\n", fd); - if ((break_code = read_raw_kbd(fd, &scan_code)) != 0xffff) - hardint(0x01); -} -#endif - -void -int09(REGISTERS __unused) -{ - if (raw_kbd) { - if (scan_code != 0xffff) { - KbdWrite(scan_code); - break_code = 0; - scan_code = 0xffff; -#if 0 - kbd_event(kbd_fd, 0, sc, REGS); -#endif - } - } - send_eoi(); -} - -#ifndef NO_X -u_short -read_raw_kbd(int fd, u_short *code) -{ - unsigned char c; - - *code = 0xffff; - - if (read(fd, &c, 1) == 1) { - if (c == 0xe0) { - K3_STATUS |= K3_TWOBYTE; - return(c); - } - switch (c) { - case 29: /* Control */ - K1_STATUS |= K1_CTRL; - if (K3_STATUS & K3_TWOBYTE) - K3_STATUS |= K3_RCTRL; - else - K2_STATUS |= K2_LCTRL; - break; - case 29 | 0x80: /* Control */ - K1_STATUS &= ~K1_CTRL; - if (K3_STATUS & K3_TWOBYTE) - K3_STATUS &= ~K3_RCTRL; - else - K2_STATUS &= ~K2_LCTRL; - break; - - case 42: /* left shift */ - K1_STATUS |= K1_LSHIFT; - break; - case 42 | 0x80: /* left shift */ - K1_STATUS &= ~K1_LSHIFT; - break; - - case 54: /* right shift */ - K1_STATUS |= K1_RSHIFT; - break; - case 54 | 0x80: /* right shift */ - K1_STATUS &= ~K1_RSHIFT; - break; - - case 56: /* Alt */ - K1_STATUS |= K1_ALT; - if (K3_STATUS & K3_TWOBYTE) - K3_STATUS |= K3_RALT; - else - K2_STATUS |= K2_LALT; - break; - case 56 | 0x80: /* Alt */ - K1_STATUS &= ~K1_ALT; - if (K3_STATUS & K3_TWOBYTE) - K3_STATUS &= ~K3_RALT; - else - K2_STATUS &= ~K2_LALT; - break; - - case 58: /* caps-lock */ - K1_STATUS ^= K1_CLOCK; - if (K1_STATUS & K1_CLOCK) - K4_STATUS |= K4_CLOCK_LED; - else - K4_STATUS &= ~K4_CLOCK_LED; - K2_STATUS |= K2_CLOCK; - break; - case 58 | 0x80: /* caps-lock */ - K2_STATUS &= ~K2_CLOCK; - break; - - case 69: /* num-lock */ - K1_STATUS ^= K1_NLOCK; - if (K1_STATUS & K1_NLOCK) - K4_STATUS |= K4_NLOCK_LED; - else - K4_STATUS &= ~K4_NLOCK_LED; - K2_STATUS |= K2_NLOCK; - break; - case 69 | 0x80: /* num-lock */ - K2_STATUS &= ~K2_NLOCK; - break; - - case 70: /* scroll-lock */ - K1_STATUS ^= K1_SLOCK; - if (K1_STATUS & K1_SLOCK) - K4_STATUS |= K4_SLOCK_LED; - else - K4_STATUS &= ~K4_SLOCK_LED; - K2_STATUS |= K2_SLOCK; - break; - case 70 | 0x80: /* scroll-lock */ - K2_STATUS &= ~K2_SLOCK; - break; - - case 82: /* insert */ - K1_STATUS ^= K1_INSERT; - K2_STATUS |= K2_INSERT; - break; - case 82 | 0x80: /* insert */ - K2_STATUS &= ~K2_INSERT; - break; - - } - -#if 0 /*XXXXX*/ - if ((K4_STATUS & 0x07) != oldled) { - oldled = K4_STATUS & 0x07; - ioctl (fd, PCCONIOCSETLED, &oldled); - } -#endif - - if (c == 83 && (K1_STATUS & (K1_ALT|K1_CTRL)) == (K1_ALT|K1_CTRL)) - quit(0); - - if (c < 89) { - u_short scode; - - if (K1_STATUS & K1_ALT) { - scode = ScanCodes[c].alt; - } else if (K1_STATUS & K1_CTRL) { - scode = ScanCodes[c].ctrl; - } else if (K1_STATUS & K1_SHIFT) { - scode = ScanCodes[c].shift; - } else { - scode = ScanCodes[c].base; - if (K1_STATUS & K1_CLOCK) { - if (islower(scode & 0xff)) { - scode = (scode & 0xff00) | toupper(scode & 0xff); - } - } - if ((K1_STATUS & K1_NLOCK) && (K3_STATUS & K3_TWOBYTE) == 0) { - switch (c) { - case 71: /* home */ - case 72: /* cursor up */ - case 73: /* page up */ - case 75: /* cursor left */ - case 76: /* center key */ - case 77: /* cursor right */ - case 79: /* end */ - case 80: /* cursor down */ - case 81: /* page down */ - case 82: /* insert */ - case 83: /* delete */ - scode = ScanCodes[c].shift; - break; - } - } - } - *code = scode; - } - K3_STATUS &= ~K3_TWOBYTE; - if ((K1_STATUS&(K1_ALT|K1_CTRL)) == (K1_ALT|K1_CTRL)) { - switch (c) { - case 0x13: /* R */ - kill(getpid(), SIGALRM); /* force redraw */ -printf("FORCED REDRAW\n"); - return(0xffff); - case 0x14: /* T */ - tmode ^= 1; - if (!tmode) - resettrace((regcontext_t *)&saved_sigframe-> - sf_uc.uc_mcontext); - return(0xffff); - case 0x53: /* DEL */ - quit(0); - } - } - return(c); - } else { - return(0xffff); - } -} -#endif - -#ifndef NO_X -void -video_async_event(int fd, int cond, void *arg __unused, regcontext_t *REGS __unused) -{ - int int9 = 0; - - if (!(cond & AS_RD)) - return; - - for (;;) { - int x; - fd_set fdset; - XEvent ev; - static struct timeval tv; - - /* - * Handle any events just sitting around... - */ - XFlush(dpy); - while (QLength(dpy) > 0) { - XNextEvent(dpy, &ev); - int9 |= video_event(&ev); - } - - FD_ZERO(&fdset); - FD_SET(fd, &fdset); - - x = select(FD_SETSIZE, &fdset, 0, 0, &tv); - - switch (x) { - case -1: - /* - * Errno might be wrong, so we just select again. - * This could cause a problem is something really - * was wrong with select.... - */ - perror("select"); - return; - case 0: - XFlush(dpy); - if (int9) - hardint(0x01); - return; - default: - if (FD_ISSET(fd, &fdset)) { - do { - XNextEvent(dpy, &ev); - int9 |= video_event(&ev); - } while (QLength(dpy)); - } - break; - } - } -} -#endif - -#ifndef NO_X -static int -video_event(XEvent *ev) -{ - switch (ev->type) { - case MotionNotify: { - XMotionEvent *me = (XMotionEvent *)ev; - me->x -= 2; - me->y -= 2; - - mouse_status.x = (me->x < mouse_status.range.x) - ? mouse_status.range.x - : (me->x > mouse_status.range.w) - ? mouse_status.range.w : me->x; - mouse_status.y = (me->y < mouse_status.range.y) - ? mouse_status.range.y - : (me->y > mouse_status.range.h) - ? mouse_status.range.h : me->y; - break; - } - case ButtonRelease: { - XButtonEvent *be = (XButtonEvent *)ev; - be->x -= 2; - be->y -= 2; - - if (be->button < 3) - mouse_status.ups[be->button]++; - - mouse_status.x = (be->x < mouse_status.range.x) - ? mouse_status.range.x - : (be->x > mouse_status.range.w) - ? mouse_status.range.w : be->x; - mouse_status.y = (be->y < mouse_status.range.y) - ? mouse_status.range.y - : (be->y > mouse_status.range.h) - ? mouse_status.range.h : be->y; - break; - } - case ButtonPress: { - XButtonEvent *be = (XButtonEvent *)ev; - be->x -= 2; - be->y -= 2; - - if (be->button < 3) - mouse_status.downs[be->button]++; - - mouse_status.x = (be->x < mouse_status.range.x) - ? mouse_status.range.x - : (be->x > mouse_status.range.w) - ? mouse_status.range.w : be->x; - mouse_status.y = (be->y < mouse_status.range.y) - ? mouse_status.range.y - : (be->y > mouse_status.range.h) - ? mouse_status.range.h : be->y; - - if ((K1_STATUS & (K1_ALT|K1_CTRL)) == (K1_ALT|K1_CTRL)) { - quit(0); - } - break; - } - case NoExpose: - break; - case GraphicsExpose: - case Expose: { - int r; - for (r = 0; r < height; ++r) - lines[r].changed = 1; - break; - } - case KeyRelease: { - static char buf[128]; - KeySym ks; - - break_code |= 0x80; - - if (!(ev->xkey.state & ShiftMask)) { - K1_STATUS &= ~K1_LSHIFT; - K1_STATUS &= ~K1_RSHIFT; - } - if (!(ev->xkey.state & ControlMask)) { - K1_STATUS &= ~K1_CTRL; - K2_STATUS &= ~K2_LCTRL; - K3_STATUS &= ~K3_RCTRL; - } - if (!(ev->xkey.state & Mod1Mask)) { - K1_STATUS &= ~K1_ALT; - K2_STATUS &= ~K2_LALT; - K3_STATUS &= ~K3_RALT; - } - if (!(ev->xkey.state & LockMask)) { - K2_STATUS &= ~K2_CLOCK; - } - - XLookupString((XKeyEvent *)ev, buf, sizeof(buf), &ks, 0); - switch (ks) { - case XK_Shift_L: - K1_STATUS &= ~K1_LSHIFT; - break; - case XK_Shift_R: - K1_STATUS &= ~K1_RSHIFT; - break; - case XK_Control_L: - K1_STATUS &= ~K1_CTRL; - K2_STATUS &= ~K2_LCTRL; - break; - case XK_Control_R: - K1_STATUS &= ~K1_CTRL; - K3_STATUS &= ~K3_RCTRL; - break; - case XK_Alt_L: - K1_STATUS &= ~K1_ALT; - K2_STATUS &= ~K2_LALT; - break; - case XK_Alt_R: - K1_STATUS &= ~K1_ALT; - K3_STATUS &= ~K3_RALT; - break; - case XK_Scroll_Lock: - K2_STATUS &= ~K2_SLOCK; - break; - case XK_Num_Lock: - K2_STATUS &= ~K2_NLOCK; - break; - case XK_Caps_Lock: - K2_STATUS &= ~K2_CLOCK; - break; - case XK_Insert: - K2_STATUS &= ~K2_INSERT; - break; - } - return(1); - } - case KeyPress: { - static char buf[128]; - KeySym ks; - int n; - int nlock = 0; - u_short scan = 0xffff; - - if (!(ev->xkey.state & ShiftMask)) { - K1_STATUS &= ~K1_LSHIFT; - K1_STATUS &= ~K1_RSHIFT; - } - if (!(ev->xkey.state & ControlMask)) { - K1_STATUS &= ~K1_CTRL; - K2_STATUS &= ~K2_LCTRL; - K3_STATUS &= ~K3_RCTRL; - } - if (!(ev->xkey.state & Mod1Mask)) { - K1_STATUS &= ~K1_ALT; - K2_STATUS &= ~K2_LALT; - K3_STATUS &= ~K3_RALT; - } - if (!(ev->xkey.state & LockMask)) { - K2_STATUS &= ~K2_CLOCK; - } - - n = XLookupString((XKeyEvent *)ev, buf, sizeof(buf), &ks, 0); - - switch (ks) { - case XK_Shift_L: - K1_STATUS |= K1_LSHIFT; - break; - case XK_Shift_R: - K1_STATUS |= K1_RSHIFT; - break; - case XK_Control_L: - K1_STATUS |= K1_CTRL; - K2_STATUS |= K2_LCTRL; - break; - case XK_Control_R: - K1_STATUS |= K1_CTRL; - K3_STATUS |= K3_RCTRL; - break; - case XK_Alt_L: - K1_STATUS |= K1_ALT; - K2_STATUS |= K2_LALT; - break; - case XK_Alt_R: - K1_STATUS |= K1_ALT; - K3_STATUS |= K3_RALT; - break; - case XK_Scroll_Lock: - K1_STATUS ^= K1_SLOCK; - K2_STATUS |= K2_SLOCK; - break; - case XK_Num_Lock: - K1_STATUS ^= K1_NLOCK; - K2_STATUS |= K2_NLOCK; - break; - case XK_Caps_Lock: - K1_STATUS ^= K1_CLOCK; - K2_STATUS |= K2_CLOCK; - break; - case XK_Insert: - case XK_KP_Insert: - K1_STATUS ^= K1_INSERT; - K2_STATUS |= K2_INSERT; - scan = 82; - goto docode; - - case XK_Escape: - scan = 1; - goto docode; - - case XK_Tab: - case XK_ISO_Left_Tab: - scan = 15; - goto docode; - - case XK_Return: - case XK_KP_Enter: - scan = 28; - goto docode; - - case XK_Print: - scan = 55; - goto docode; - - case XK_F1: - case XK_F2: - case XK_F3: - case XK_F4: - case XK_F5: - case XK_F6: - case XK_F7: - case XK_F8: - case XK_F9: - case XK_F10: - scan = ks - XK_F1 + 59; - goto docode; - - case XK_KP_7: - nlock = 1; - case XK_Home: - case XK_KP_Home: - scan = 71; - goto docode; - case XK_KP_8: - nlock = 1; - case XK_Up: - case XK_KP_Up: - scan = 72; - goto docode; - case XK_KP_9: - nlock = 1; - case XK_Prior: - case XK_KP_Prior: - scan = 73; - goto docode; - case XK_KP_Subtract: - scan = 74; - goto docode; - case XK_KP_4: - nlock = 1; - case XK_Left: - case XK_KP_Left: - scan = 75; - goto docode; - case XK_KP_5: - nlock = 1; - case XK_Begin: - case XK_KP_Begin: - scan = 76; - goto docode; - case XK_KP_6: - nlock = 1; - case XK_Right: - case XK_KP_Right: - scan = 77; - goto docode; - case XK_KP_Add: - scan = 78; - goto docode; - case XK_KP_1: - nlock = 1; - case XK_End: - case XK_KP_End: - scan = 79; - goto docode; - case XK_KP_2: - nlock = 1; - case XK_Down: - case XK_KP_Down: - scan = 80; - goto docode; - case XK_KP_3: - nlock = 1; - case XK_Next: - case XK_KP_Next: - scan = 81; - goto docode; - case XK_KP_0: - nlock = 1; - /* case XK_Insert: This is above */ - scan = 82; - goto docode; - - case XK_KP_Decimal: - nlock = 1; - scan = 83; - goto docode; - - case XK_Delete: - case XK_KP_Delete: - scan = flipdelete ? 14 : 83; - goto docode; - - case XK_BackSpace: - scan = flipdelete ? 83 : 14; - goto docode; - - case XK_F11: - scan = 87; - goto docode; - case XK_F12: - scan = 88; - goto docode; - - - case XK_KP_Divide: - scan = Ascii2Scan['/']; - goto docode; - - case XK_KP_Multiply: - scan = Ascii2Scan['*']; - goto docode; - - default: - if ((K1_STATUS&(K1_ALT|K1_CTRL)) == (K1_ALT|K1_CTRL)) { - if (ks == 'T' || ks == 't') { - tmode ^= 1; - if (!tmode) - resettrace((regcontext_t *)&saved_sigframe-> - sf_uc.uc_mcontext); - break; - } - if (ks == 'R' || ks == 'r') { - kill(getpid(), SIGALRM); /* redraw */ - break; - } - } - if (ks < ' ' || ks > '~') - break; - scan = Ascii2Scan[ks]; - docode: - if (nlock) - scan |= 0x100; - - if ((scan & ~0x100) > 88) { - scan = 0xffff; - break; - } - - if ((K1_STATUS & K1_SHIFT) || (scan & 0x100)) { - scan = ScanCodes[scan & 0xff].shift; - } else if (K1_STATUS & K1_CTRL) { - scan = ScanCodes[scan & 0xff].ctrl; - } else if (K1_STATUS & K1_ALT) { - scan = ScanCodes[scan & 0xff].alt; - } else - scan = ScanCodes[scan & 0xff].base; - - break; - } - if (scan != 0xffff) { - break_code = scan >> 8; - KbdWrite(scan); - } - return(1); - } - default: - break; - } - return(0); -} -#endif - -void -tty_move(int r, int c) -{ - row = r; - col = c; - SetVREGCur(); -} - -void -tty_report(int *r, int *c) -{ - *r = row; - *c = col; -} - -void -tty_flush() -{ - K_NEXT = K_FREE = K_BUFSTARTP; -} - -void -tty_index(int scroll) -{ - int i; - - if (row > (height - 1)) - row = 0; - else if (++row >= height) { - row = height - 1; - if (scroll) { - memcpy(vmem, &vmem[width], 2 * width * (height - 1)); - for (i = 0; i < width; ++i) - vmem[(height - 1) * width + i] = vattr | ' '; - } - } - SetVREGCur(); -} - -void -tty_write(int c, int attr) -{ - if (attr == TTYF_REDIRECT) { - if (redirect1) { - write(1, &c, 1); - return; - } - attr = -1; - } - if (capture_fd >= 0) { - char cc = c; - write(capture_fd, &cc, 1); - } - c &= 0xff; - switch (c) { - case 0x07: - if (xmode) { -#ifndef NO_X - XBell(dpy, 0); -#endif - } else - write(1, "\007", 1); - break; - case 0x08: - if (row > (height - 1) || col > width) - break; - if (col > 0) - --col; - vmem[row * width + col] &= 0xff00; - break; - case '\t': - if (row > (height - 1)) - row = 0; - col = (col + 8) & ~0x07; - if (col > width) { - col = 0; - tty_index(1); - } - break; - case '\r': - col = 0; - break; - case '\n': - tty_index(1); - break; - default: - if (col >= width) { - col = 0; - tty_index(1); - } - if (row > (height - 1)) - row = 0; - if (attr >= 0) - vmem[row * width + col] = attr & 0xff00; - else - vmem[row * width + col] &= 0xff00; - vmem[row * width + col++] |= c; - break; - } - SetVREGCur(); -} - -void -tty_rwrite(int n, int c, int attr) -{ - u_char srow, scol; - c &= 0xff; - -#ifndef NO_X - if (VGA_ATC[ATC_ModeCtrl] & 1) { - tty_rwrite_graphics(n, c, attr); - return; - } -#endif - - srow = row; - scol = col; - while (n--) { - if (col >= width) { - col = 0; - tty_index(0); - } - if (row > (height - 1)) - row = 0; - if (attr >= 0) - vmem[row * width + col] = attr & 0xff00; - else - vmem[row * width + col] &= 0xff00; - vmem[row * width + col++] |= c; - } - row = srow; - col = scol; - SetVREGCur(); -} - -#ifndef NO_X -/* Write a character in graphics mode. Note that the text is put at *text* - coordinates. */ -static void -tty_rwrite_graphics(int n, int c, int attr) -{ - u_int8_t srow, scol; - int ht = height / CharHeight; - int wd = width / 8; - - srow = row; - scol = col; - - while (n--) { - if (col >= wd) { - col = 0; - /* tty_index(0); *//* scroll up if last line is filled */ - } - if (row > (ht - 1)) - row = 0; - putchar_graphics(row * wd * CharHeight + col, c, attr); - col++; - } - row = srow; - col = scol; - SetVREGCur(); - - return; -} - -/* Put the character together from its pixel representation in 'font8xXX[]' - and write it to 'vram'. The attribute byte gives the desired color; if bit - 7 is set, the pixels are XOR'd with the underlying color(s). - - XXX This must be updated for the 256 color modes. */ -static void -putchar_graphics(int xy, int c, int attr) -{ - int i, j; - u_int8_t cline; - u_int8_t *cpos; - - /* get char position in the pixel representation */ - cpos = (u_int8_t *)(0xC3000 + c * CharHeight); - - for (i = 0; i < CharHeight; i++) { - cline = cpos[i]; - for (j = 0; j < 4; j++) { - if (attr & 0x8000) { - /* XOR */ - if (attr & (0x0100 << j)) - vram[xy + i * width / 8 + j * 0x10000] ^= cline; - } else { - /* replace */ - if (attr & (0x0100 << j)) - vram[xy + i * width / 8 + j * 0x10000] &= ~cline; - else - vram[xy + i * width / 8 + j * 0x10000] |= cline; - } - } - } - - return; -} -#endif - -void tty_pause() -{ - sigset_t set; - - sigprocmask(0, 0, &set); - sigdelset(&set, SIGIO); - sigdelset(&set, SIGALRM); - sigsuspend(&set); -} - -static int nextchar = 0; - -int -tty_read(REGISTERS, int flag) -{ - int r; - - if ((r = nextchar) != 0) { - nextchar = 0; - return(r & 0xff); - } - - if ((flag & TTYF_REDIRECT) && redirect0) { - char c; - if (read(STDIN_FILENO, &c, 1) != 1) - return(-1); - if (c == '\n') - c = '\r'; - return(c); - } - - if (KbdEmpty()) { - if (flag & TTYF_BLOCK) { - while (KbdEmpty()) - tty_pause(); - } else { - return(-1); - } - } - - r = KbdRead(); - if ((r & 0xff) == 0) - nextchar = r >> 8; - r &= 0xff; - if (flag & TTYF_CTRL) { - if (r == 3) { - /* - * XXX - Not quite sure where we should return, maybe not - * all the way to the user, but... - */ - if (ivec[0x23] && (ivec[0x23] >> 16) != 0xF000) { - fake_int(REGS, 0x23); - R_EIP = R_EIP - 2; - return(-2); - } - } - } - if (flag & TTYF_ECHO) { - if ((flag & TTYF_ECHONL) && (r == '\n' || r == '\r')) { - tty_write('\r', -1); - tty_write('\n', -1); - } else - tty_write(r, -1); - } - return(r & 0xff); -} - -int -tty_peek(REGISTERS, int flag) -{ - int c; - - if (c == nextchar) - return(nextchar & 0xff); - - if (KbdEmpty()) { - if (flag & TTYF_POLL) { - sleep_poll(); - if (KbdEmpty()) - return(0); - } else if (flag & TTYF_BLOCK) { - while (KbdEmpty()) - tty_pause(); - } else - return(0); - } - c = KbdPeek(); - if ((c & 0xff) == 3) { - /* - * XXX - Not quite sure where we should return, maybe not - * all the way to the user, but... - */ - if (ivec[0x23] && (ivec[0x23] >> 16) != 0xF000) { - fake_int(REGS, 0x23); - R_EIP = R_EIP - 2; - return(-2); - } - } - return(0xff); -} - -int -tty_state() -{ - return(K1_STATUS); -} - -int -tty_estate() -{ - int state = 0; - if (K2_STATUS & K2_SYSREQ) - state |= 0x80; - if (K2_STATUS & K2_CLOCK) - state |= 0x40; - if (K2_STATUS & K2_NLOCK) - state |= 0x20; - if (K2_STATUS & K2_SLOCK) - state |= 0x10; - if (K3_STATUS & K3_RALT) - state |= 0x08; - if (K3_STATUS & K3_RCTRL) - state |= 0x04; - if (K2_STATUS & K2_LALT) - state |= 0x02; - if (K2_STATUS & K2_LCTRL) - state |= 0x01; - return(state); -} - -static int -inrange(int a, int n, int x) -{ - return(a < n ? n : a > x ? x : a); -} - -void -tty_scroll(int sr, int sc, int er, int ec, int n, int attr) -{ - int i, j; - - sr = inrange(sr, 0, height); - er = inrange(er, 0, height); - sc = inrange(sc, 0, width); - ec = inrange(ec, 0, width); - if (sr > er || sc > ec) - return; - ++er; - ++ec; - - attr &= 0xff00; - attr |= ' '; - - if (n > 0 && n < er - sr) { - for (j = sr; j < er - n; ) { - memcpy(&vmem[j * width + sc], - &vmem[(j + n) * width + sc], - sizeof(vmem[0]) * (ec - sc)); - ++j; - } - } else - n = er - sr; - for (j = er - n; j < er; ) { - for (i = sc; i < ec; ++i) - vmem[j * width + i] = attr; - ++j; - } -} - -void -tty_rscroll(int sr, int sc, int er, int ec, int n, int attr) -{ - int i, j; - - sr = inrange(sr, 0, height); - er = inrange(er, 0, height); - sc = inrange(sc, 0, width); - ec = inrange(ec, 0, width); - if (sr > er || sc > ec) - return; - ++er; - ++ec; - - attr &= 0xff00; - attr |= ' '; - - if (n > 0 && n < er - sr) { - for (j = er; j > sr + n; ) { - --j; - memcpy(&vmem[j * width + sc], - &vmem[(j - n) * width + sc], - sizeof(vmem[0]) * (ec - sc)); - } - } else - n = er - sr; - for (j = sr + n; j > sr; ) { - --j; - for (i = sc; i < ec; ++i) - vmem[j * width + i] = attr; - } -} - -int -tty_char(int r, int c) -{ - if (r == -1) - r = row; - if (c == -1) - c = col; - r = inrange(r, 0, height); - c = inrange(c, 0, width); - return(vmem[r * width + c]); -} - -int -KbdEmpty() -{ - return(K_NEXT == K_FREE); -} - -void -KbdWrite(u_short code) -{ - int kf; - - kf = K_FREE + 2; - if (kf == K_BUFENDP) - kf = K_BUFSTARTP; - - if (kf == K_NEXT) { -#ifndef NO_X - XBell(dpy, 0); -#endif - return; - } - K_BUF(K_FREE) = code; - K_FREE = kf; -} - -u_short -KbdRead() -{ - int kf = K_NEXT; - - K_NEXT = K_NEXT + 2; - if (K_NEXT == K_BUFENDP) - K_NEXT = K_BUFSTARTP; - - return(K_BUF(kf)); -} - -u_short -KbdPeek() -{ - return(K_BUF(K_NEXT)); -} - -void -kbd_init() -{ - u_long vec; - - define_input_port_handler(0x60, inb_port60); - - K_BUFSTARTP = 0x1e; /* Start of keyboard buffer */ - K_BUFENDP = 0x3e; /* End of keyboard buffer */ - K_NEXT = K_FREE = K_BUFSTARTP; - - vec = insert_hardint_trampoline(); - ivec[0x09] = vec; - register_callback(vec, int09, "int 09"); - - return; -} - -void -kbd_bios_init() -{ - BIOSDATA[0x96] = 0x10; /* MF II kbd, 101 keys */ - K1_STATUS = 0; - K2_STATUS = 0; - K3_STATUS = 0; - K4_STATUS = 0; -} - -#ifndef NO_X -/* Calculate 16 bit RGB values for X from the 6 bit DAC values and the - palette. This works for 16 and 256 color modes, although we don't really - support the latter yet. */ -static void -dac2rgb(XColor *color, int i) -{ - int n, m; - - /* 256 colors are easy; just take the RGB values from the DAC and - shift left. For the pedants: multiplication with 65535./63. and - rounding makes a difference of less than two percent. */ - if (VGA_ATC[ATC_ModeCtrl] & 0x40) { - color->red = dac_rgb[i].red << 10; - color->green = dac_rgb[i].green << 10; - color->blue = dac_rgb[i].blue << 10; - - return; - } - - /* For the 16 color modes, check bit 7 of the Mode Control register in - the ATC. If set, we take bits 0-3 of the Color Select register and - bits 0-3 of the palette register 'i' to build the index into the - DAC table; otherwise, bits 2 and 3 of the CS reg and bits 0-5 of - the palette register are used. Note that the entries in 'palette[]' - are supposed to be already masked to 6 bits. */ - if (VGA_ATC[ATC_ModeCtrl] & 0x80) { - n = VGA_ATC[ATC_ColorSelect] & 0x0f; - m = palette[i] & 0x0f; - } else { - n = VGA_ATC[ATC_ColorSelect] & 0x0c; - m = palette[i]; - } - color->red = dac_rgb[16*n + m].red << 10; - color->green = dac_rgb[16*n + m].green << 10; - color->blue = dac_rgb[16*n + m].blue << 10; -} -#endif - -/* Get a connection to the X server and create the window. */ -void -init_window() -{ -#ifndef NO_X - XGCValues gcv; - int i; - - { - /* - * Arg... I can no longer change X's fd out from under it. - * Open up all the available fd's, leave 3 behind for X - * to play with, open X and then release all the other fds - */ - int nfds = sysconf(_SC_OPEN_MAX); - int *fds = malloc(sizeof(int) * nfds); - i = 0; - if (fds) - for (i = 0; i < nfds && (i == 0 || fds[i-1] < 63); ++i) - if ((fds[i] = open(_PATH_DEVNULL, 0)) < 0) - break; - /* - * Leave 3 fds behind for X to play with - */ - if (i > 0) close(fds[--i]); - if (i > 0) close(fds[--i]); - if (i > 0) close(fds[--i]); - - dpy = XOpenDisplay(NULL); - - while (i > 0) - close(fds[--i]); - } - if (dpy == NULL) - err(1, "Could not open display ``%s''\n", XDisplayName(NULL)); - xfd = ConnectionNumber(dpy); - - _RegisterIO(xfd, video_async_event, 0, Failure); - if (debug_flags & D_DEBUGIN) - _RegisterIO(0, debug_event, 0, Failure); - - /* Create window, but defer setting a size and GC. */ - win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, - 1, 1, 2, black, black); - - gcv.foreground = white; - gcv.background = black; - gc = XCreateGC(dpy, win, GCForeground | GCBackground, &gcv); - - gcv.foreground = 1; - gcv.background = 0; - gcv.function = GXxor; - cgc = XCreateGC(dpy, win, GCForeground|GCBackground|GCFunction, &gcv); - - if (raw_kbd) { - XSelectInput(dpy, win, ExposureMask | ButtonPressMask - | ButtonReleaseMask | PointerMotionMask ); - } else { - XSelectInput(dpy, win, KeyReleaseMask | KeyPressMask | - ExposureMask | ButtonPressMask - | ButtonReleaseMask | PointerMotionMask ); - } - - XStoreName(dpy, win, "DOS"); - - /* Get the default visual and depth for later use. */ - depth = DefaultDepth(dpy, DefaultScreen(dpy)); - visual = DefaultVisual(dpy, DefaultScreen(dpy)); - - prepare_lut(); - -#if 0 - /* While we are developing the graphics code ... */ - call_on_quit(write_vram, NULL); -#endif -#endif -} - -void -load_font() -{ -#ifndef NO_X - XGCValues gcv; - - if (!xfont) - xfont = FONTVGA; - - font = XLoadQueryFont(dpy, xfont); - - if (font == NULL) - font = XLoadQueryFont(dpy, FONTVGA); - - if (font == NULL) - err(1, "Could not open font ``%s''\n", xfont); - - gcv.font = font->fid; - XChangeGC(dpy, gc, GCFont, &gcv); - - FW = font->max_bounds.width; - FH = font->max_bounds.ascent + font->max_bounds.descent; - FD = font->max_bounds.descent; - - /* Put the pixel representation at c000:3000. */ - switch (CharHeight) { - case 8: - memcpy((void *)0xc3000, font8x8, sizeof(font8x8)); - break; - case 14: - memcpy((void *)0xc3000, font8x14, sizeof(font8x14)); - break; - case 16: - memcpy((void *)0xc3000, font8x16, sizeof(font8x16)); - break; - default: - err(1, "load_font: CharHeight = %d?", CharHeight); - } - - return; -#endif -} - -/* Get a new, or resize an old XImage as canvas for the graphics display. */ -void -get_ximage() -{ -#ifndef NO_X - if (xi != NULL) - XFree(xi); - - xi = XCreateImage(dpy, visual, depth, ZPixmap, 0, NULL, - width, height, 32, 0); - if (xi == NULL) - err(1, "Could not get ximage"); - - xi->data = malloc(width * height * depth / 8); - if (xi->data == NULL) { - XDestroyImage(xi); - err(1, "Could not get memory for ximage data"); - } - - return; -#endif -} - -/* Get memory for the text line buffer. */ -void -get_lines() -{ - int i; - - if (lines == NULL) { - lines = (TextLine *)malloc(sizeof(TextLine) * height); - if (lines == NULL) - err(1, "Could not allocate data structure for text lines\n"); - - for (i = 0; i < height; ++i) { - lines[i].max_length = width; - lines[i].data = (u_short *)malloc(width * sizeof(u_short)); - if (lines[i].data == NULL) - err(1, "Could not allocate data structure for text lines\n"); - lines[i].changed = 1; - } - } else { - lines = (TextLine *)realloc(lines, sizeof(TextLine) * height); - if (lines == NULL) - err(1, "Could not allocate data structure for text lines\n"); - - for (i = 0; i < height; ++i) { - lines[i].max_length = width; - lines[i].data = (u_short *)realloc(lines[i].data, - width * sizeof(u_short)); - if (lines[i].data == NULL) - err(1, "Could not allocate data structure for text lines\n"); - lines[i].changed = 1; - } - } -} - -#ifndef NO_X -/* Prepare the LUT for the VRAM -> XImage conversion. */ -static void -prepare_lut() -{ - int i, j, k; - - for (i = 0; i < 4; i++) { - for (j = 0; j < 256; j++) { - for (k = 0; k < 8; k++) { - lut[i][j][7 - k] = ((j & (1 << k)) ? (1 << i) : 0); - } - } - } - - return; -} -#endif - -/* Resize the window, using information from 'vga_status[]'. This function is - called after a mode change. */ -void -resize_window() -{ -#ifndef NO_X - XSizeHints *sh; - vmode_t vmode; - - sh = XAllocSizeHints(); - if (sh == NULL) - err(1, "Could not get XSizeHints structure"); -#endif - - width = DpyCols; - height = DpyRows + 1; - -#ifndef NO_X - vmode = vmodelist[find_vmode(VideoMode)]; - if (vmode.type == TEXT) { - sh->base_width = FW * width + 4; - sh->base_height = FH * height + 4; - sh->base_width += 4; - sh->base_height += 4; - } else { - width *= 8; - height *= CharHeight; - sh->base_width = width; - sh->base_height = height; - } - - sh->min_width = sh->max_width = sh->base_width; - sh->min_height = sh->max_height = sh->base_height; - sh->flags = USSize | PMinSize | PMaxSize | PSize; - - debug(D_VIDEO, "VGA: Set window size %dx%d\n", - sh->base_width, sh->base_height); - - XSetWMNormalHints(dpy, win, sh); - XResizeWindow(dpy, win, sh->base_width, sh->base_height); - XMapWindow(dpy, win); - XFlush(dpy); - - XFree(sh); - - return; -#endif -} - -/* Calculate 'pixels[]' from the current DAC table and palette. - - To do: do not use 'pixels[]', use an array of 'XColor's which we can - allocate and free on demand. Install a private colormap if necessary. */ -void -update_pixels() -{ -#ifndef NO_X - int i; - - /* We support only 16 colors for now. */ - for (i = 0; i < 16; i++) { - XColor color; - - dac2rgb(&color, i); - if (XAllocColor(dpy, - DefaultColormap(dpy, DefaultScreen(dpy)), &color)) { - pixels[i] = color.pixel; - } else if (i < 7) - pixels[i] = BlackPixel(dpy, DefaultScreen(dpy)); - else - pixels[i] = WhitePixel(dpy, DefaultScreen(dpy)); - } -#endif -} - -void -write_vram(void *arg __unused) -{ - int fd; - - if ((fd = open("vram", O_WRONLY | O_CREAT, 0644)) == -1) - err(1, "Can't open vram file"); - (void)write(fd, (void *)vram, 256 * 1024); - - return; -} diff --git a/usr.bin/doscmd/tty.h b/usr.bin/doscmd/tty.h deleted file mode 100644 index 0581dd1..0000000 --- a/usr.bin/doscmd/tty.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2001 The FreeBSD Project, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY The FreeBSD Project, Inc. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL The FreeBSD Project, Inc. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -/* TTY subsystem XXX rewrite! */ -int redirect0; -int redirect1; -int redirect2; -extern int kbd_fd; -extern const char *xfont; - -int KbdEmpty(void); -u_short KbdPeek(void); -u_short KbdRead(void); -void KbdWrite(u_short); - -void console_init(void); -void get_lines(void); -void get_ximage(void); -void init_window(void); -void init_ximage(int, int); -void int09(regcontext_t *); -void kbd_bios_init(void); -void kbd_init(void); -void load_font(void); -void resize_window(void); -int tty_char(int, int); -int tty_eread(REGISTERS, int, int); -int tty_estate(void); -void tty_flush(void); -void tty_index(int); -void tty_move(int, int); -int tty_read(regcontext_t *, int); -void tty_report(int *, int *); -void tty_pause(void); -int tty_peek(REGISTERS, int); -void tty_rwrite(int, int, int); -int tty_state(void); -void tty_scroll(int, int, int, int, int, int); -void tty_rscroll(int, int, int, int, int, int); -void tty_write(int, int); -void update_pixels(void); -void video_blink(int); -void video_setborder(int); -void video_update(regcontext_t *); diff --git a/usr.bin/doscmd/video.c b/usr.bin/doscmd/video.c deleted file mode 100644 index 204fd12..0000000 --- a/usr.bin/doscmd/video.c +++ /dev/null @@ -1,740 +0,0 @@ -/* - * Copyright (c) 2001 The FreeBSD Project, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY The FreeBSD Project, Inc. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL The FreeBSD Project, Inc. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/types.h> -#include <sys/mman.h> -#include <err.h> -#include <paths.h> -#include <unistd.h> - -#include "doscmd.h" -#include "AsyncIO.h" -#include "tty.h" -#include "video.h" -#include "vparams.h" - -/* - * Global variables - */ - -/* VGA registers */ -u_int8_t VGA_CRTC[CRTC_Size]; -u_int8_t VGA_ATC[ATC_Size]; -u_int8_t VGA_TSC[TSC_Size]; -u_int8_t VGA_GDC[GDC_Size]; - -/* VGA status information */ -u_int8_t vga_status[64]; - -/* Table of supported video modes. */ -vmode_t vmodelist[] = { - {0x00, 0x17, TEXT, 16, 8, 2, 0xb8000, FONT8x16}, - {0x01, 0x17, TEXT, 16, 8, 2, 0xb8000, FONT8x16}, - {0x02, 0x18, TEXT, 16, 8, 2, 0xb8000, FONT8x16}, - {0x03, 0x18, TEXT, 16, 8, 2, 0xb8000, FONT8x16}, - {0x04, 0x04, GRAPHICS, 4, 1, 0, 0xb8000, FONT8x8}, - {0x05, 0x05, GRAPHICS, 4, 1, 0, 0xb8000, FONT8x8}, - {0x06, 0x06, GRAPHICS, 2, 1, 0, 0xb8000, FONT8x8}, - {0x07, 0x19, TEXT, 1, 8, 2, 0xb0000, FONT8x16}, - {0x08, 0x08, NOMODE, 0, 0, 0, 0, 0}, - {0x09, 0x09, NOMODE, 0, 0, 0, 0, 0}, - {0x0a, 0x0a, NOMODE, 0, 0, 0, 0, 0}, - {0x0b, 0x0b, NOMODE, 0, 0, 0, 0, 0}, - {0x0c, 0x0c, NOMODE, 0, 0, 0, 0, 0}, - {0x0d, 0x0d, GRAPHICS, 16, 8, 0, 0xa0000, FONT8x8}, - {0x0e, 0x0e, GRAPHICS, 16, 4, 0, 0xa0000, FONT8x8}, - {0x0f, 0x11, GRAPHICS, 1, 2, 1, 0xa0000, FONT8x14}, - {0x10, 0x12, GRAPHICS, 16, 2, 1, 0xa0000, FONT8x14}, - {0x11, 0x1a, GRAPHICS, 2, 1, 3, 0xa0000, FONT8x16}, - {0x12, 0x1b, GRAPHICS, 16, 1, 3, 0xa0000, FONT8x16}, - /* {0x13, 0x1c, GRAPHICS, 256, 1, 0, 0xa0000, FONT8x8}, */ -}; - -#define NUMMODES (sizeof(vmodelist) / sizeof(vmode_t)) - -/* - * Local functions - */ -static void init_vga(void); -static u_int8_t video_inb(int); -static void video_outb(int, u_int8_t); - -/* - * Local types and variables - */ - -/* Save Table and assorted variables */ -struct VideoSaveTable { - u_short video_parameter_table[2]; - u_short parameter_dynamic_save_area[2]; /* Not used */ - u_short alphanumeric_character_set_override[2]; /* Not used */ - u_short graphics_character_set_override[2]; /* Not used */ - u_short secondary_save_table[2]; /* Not used */ - u_short mbz[4]; -}; - -struct SecondaryVideoSaveTable { - u_short length; - u_short display_combination_code_table[2]; - u_short alphanumeric_character_set_override[2]; /* Not used */ - u_short user_palette_profile_table[2]; /* Not used */ - u_short mbz[6]; -}; - -struct VideoSaveTable *vsp; -struct SecondaryVideoSaveTable *svsp; - -/* - * Read and write the VGA port - */ - -/* Save the selected index register */ -static u_int8_t crtc_index, atc_index, tsc_index, gdc_index; -/* Toggle between index and data on port ATC_WritePort */ -static u_int8_t set_atc_index = 1; - -static u_int8_t -video_inb(int port) -{ - switch(port) { - case CRTC_DataPortColor: - return VGA_CRTC[crtc_index]; - case CRTC_IndexPortColor: - return crtc_index; - case ATC_ReadPort: - return VGA_ATC[atc_index]; - case TSC_DataPort: - return VGA_TSC[tsc_index]; - case TSC_IndexPort: - return tsc_index; - case GDC_DataPort: - return VGA_GDC[gdc_index]; - case GDC_IndexPort: - return gdc_index; - case VGA_InputStatus1Port: - set_atc_index = 1; - VGA_InputStatus1 = (VGA_InputStatus1 + 1) & 15; - return VGA_InputStatus1; - default: - return 0; - } -} - -static void -video_outb(int port, u_int8_t value) -{ -/* XXX */ -#define row (CursRow0) -#define col (CursCol0) - - int cp; - - switch (port) { - case CRTC_IndexPortColor: - crtc_index = value; - break; - case CRTC_DataPortColor: - VGA_CRTC[crtc_index] = value; - switch (crtc_index) { - case CRTC_CurLocHi: /* Update cursor position in BIOS */ - cp = row * DpyCols + col; - cp &= 0xff; - cp |= value << 8; - row = cp / DpyCols; - col = cp % DpyCols; - break; - case CRTC_CurLocLo: /* Update cursor position in BIOS */ - cp = row * DpyCols + col; - cp &= 0xff00; - cp |= value; - row = cp / DpyCols; - col = cp % DpyCols; - break; - default: - debug(D_VIDEO, "VGA: outb 0x%04x, 0x%02x at index 0x%02x\n", - port, value, crtc_index); - break; - } - case CRTC_IndexPortMono: /* Not used */ - break; - case CRTC_DataPortMono: /* Not used */ - break; - case ATC_WritePort: - if (set_atc_index) - atc_index = value; - else { - VGA_ATC[atc_index] = value; - switch (atc_index) { - default: - debug(D_VIDEO, "VGA: outb 0x%04x, 0x%02x at index 0x%02x\n", - port, value, crtc_index); - break; - } - } - set_atc_index = 1 - set_atc_index; - break; - case TSC_IndexPort: - tsc_index = value; - break; - case TSC_DataPort: - VGA_TSC[tsc_index] = value; - switch (tsc_index) { - default: - debug(D_VIDEO, "VGA: outb 0x%04x, 0x%02x at index 0x%02x\n", - port, value, crtc_index); - break; - } - break; - case GDC_IndexPort: - gdc_index = value; - break; - case GDC_DataPort: - VGA_GDC[gdc_index] = value; -#if 0 - switch (gdc_index) { - default: - debug(D_VIDEO, "VGA: outb 0x%04x, 0x%02x at index 0x%02x\n", - port, value, crtc_index); - - break; - } -#endif - break; - default: - debug(D_ALWAYS, "VGA: Unknown port 0x%4x\n", port); - break; - } - - return; -#undef row -#undef col -} - -void -video_init() -{ - /* If we are running under X, get a connection to the X server and create - an empty window of size (1, 1). It makes a couple of init functions a - lot easier. */ - if (xmode) { - init_window(); - - /* Set VGA emulator to a sane state */ - init_vga(); - - /* Initialize mode 3 (text, 80x25, 16 colors) */ - init_mode(3); - } - - /* Define all known I/O port handlers */ - if (!raw_kbd) { - define_input_port_handler(CRTC_IndexPortColor, video_inb); - define_input_port_handler(CRTC_DataPortColor, video_inb); - define_input_port_handler(ATC_ReadPort, video_inb); - define_input_port_handler(TSC_IndexPort, video_inb); - define_input_port_handler(TSC_DataPort, video_inb); - define_input_port_handler(GDC_IndexPort, video_inb); - define_input_port_handler(GDC_DataPort, video_inb); - define_input_port_handler(VGA_InputStatus1Port, video_inb); - - define_output_port_handler(CRTC_IndexPortColor, video_outb); - define_output_port_handler(CRTC_DataPortColor, video_outb); - define_output_port_handler(ATC_WritePort, video_outb); - define_output_port_handler(TSC_IndexPort, video_outb); - define_output_port_handler(TSC_DataPort, video_outb); - define_output_port_handler(GDC_IndexPort, video_outb); - define_output_port_handler(GDC_DataPort, video_outb); - } - - redirect0 = isatty(0) == 0 || !xmode ; - redirect1 = isatty(1) == 0 || !xmode ; - redirect2 = isatty(2) == 0 || !xmode ; - - return; -} - -void -video_bios_init() -{ - u_char *p; - u_long vec; - - if (raw_kbd) - return; - - /* - * Put the Video Save Table Pointer @ C000:0000 - * Put the Secondary Video Save Table Pointer @ C000:0020 - * Put the Display Combination Code table @ C000:0040 - * Put the Video Parameter table @ C000:1000 - C000:2FFF - */ - BIOS_SaveTablePointer = 0xC0000000; - - vsp = (struct VideoSaveTable *)0xC0000L; - memset(vsp, 0, sizeof(struct VideoSaveTable)); - svsp = (struct SecondaryVideoSaveTable *)0xC0020L; - - vsp->video_parameter_table[0] = 0x1000; - vsp->video_parameter_table[1] = 0xC000; - - vsp->secondary_save_table[0] = 0x0020; - vsp->secondary_save_table[1] = 0xC000; - - svsp->display_combination_code_table[0] = 0x0040; - svsp->display_combination_code_table[1] = 0xC000; - - p = (u_char *)0xC0040; - *p++ = 2; /* Only support 2 combinations currently */ - *p++ = 1; /* Version # */ - *p++ = 8; /* We won't use more than type 8 */ - *p++ = 0; /* Reserved */ - *p++ = 0; *p++ = 0; /* No Display No Display */ - *p++ = 0; *p++ = 8; /* No Display VGA Color */ - - memcpy((void *)0xC1000, videoparams, sizeof(videoparams)); - ivec[0x1d] = 0xC0001000L; /* Video Parameter Table */ - - ivec[0x42] = ivec[0x10]; /* Copy of video interrupt */ - - /* Put the current font at C000:3000; the pixels are copied in - 'tty.c:load_font()'. */ - ivec[0x1f] = 0xC0003000L; - ivec[0x43] = 0xC0003000L; - - BIOSDATA[0x8a] = 1; /* Index into DCC table */ - - vec = insert_softint_trampoline(); - ivec[0x10] = vec; - register_callback(vec, int10, "int 10"); -} - -/* Initialize the VGA emulator - - XXX This is not nearly finished right now. -*/ -static void -init_vga(void) -{ - int i; - - /* Zero-fill 'dac_rgb' on allocation; the default (EGA) table has only - 64 entries. */ - dac_rgb = (struct dac_colors *)calloc(256, sizeof(struct dac_colors)); - if (dac_rgb == NULL) - err(1, "Get memory for dac_rgb"); - - /* Copy the default DAC table to a working copy we can trash. */ - for (i = 0; i < 64; i++) - dac_rgb[i] = dac_default64[i]; /* Structure copy */ - - /* Point 'palette[]' to the Attribute Controller space. We will only use - the first 16 slots. */ - palette = VGA_ATC; - - /* Get memory for the video RAM and adjust the plane pointers. */ - vram = calloc(256 * 1024, 1); /* XXX */ - if (vram == NULL) - warn("Could not get video memory; graphics modes not available."); - - /* XXX There is probably a more efficient memory layout... */ - vplane0 = vram; - vplane1 = vram + 0x10000; - vplane2 = vram + 0x20000; - vplane3 = vram + 0x30000; - - VGA_InputStatus1 = 0; -} - -/* - * Initialize the requested video mode. - */ - -/* Indices into the video parameter table. We will use that array to - initialize the registers on startup and when the video mode changes. */ -#define CRTC_Ofs 10 -#define ATC_Ofs 35 -#define TSC_Ofs 5 -#define GDC_Ofs 55 -#define MiscOutput_Ofs 9 - -void -init_mode(int mode) -{ - vmode_t vmode; - int idx; /* Index into vmode */ - int pidx; /* Index into videoparams */ - - debug(D_VIDEO, "VGA: Set video mode to 0x%02x\n", mode); - - idx = find_vmode(mode & 0x7f); - if (idx == -1 || vmodelist[idx].type == NOMODE) - err(1, "Mode 0x%02x is not supported", mode); - vmode = vmodelist[idx]; - pidx = vmode.paramindex; - - /* Preset VGA registers. */ - memcpy(VGA_CRTC, (u_int8_t *)&videoparams[pidx][CRTC_Ofs], - sizeof(VGA_CRTC)); - memcpy(VGA_ATC, (u_int8_t *)&videoparams[pidx][ATC_Ofs], - sizeof(VGA_ATC)); - /* Warning: the video parameter table does not contain the Sequencer's - Reset register. Its default value is 0x03.*/ - VGA_TSC[TSC_Reset] = 0x03; - memcpy(VGA_TSC + 1, (u_int8_t *)&videoparams[pidx][TSC_Ofs], - sizeof(VGA_TSC) - 1); - memcpy(VGA_GDC, (u_int8_t *)&videoparams[pidx][GDC_Ofs], - sizeof(VGA_GDC)); - VGA_MiscOutput = videoparams[pidx][MiscOutput_Ofs]; - - /* Paranoia */ - if ((VGA_ATC[ATC_ModeCtrl] & 1) == 1 && vmode.type == TEXT) - err(1, "Text mode requested, but ATC switched to graphics mode!"); - if ((VGA_ATC[ATC_ModeCtrl] & 1) == 0 && vmode.type == GRAPHICS) - err(1, "Graphics mode requested, but ATC switched to text mode!"); - - VideoMode = mode & 0x7f; - DpyCols = (u_int16_t)videoparams[pidx][0]; - DpyPageSize = *(u_int16_t *)&videoparams[pidx][3]; - ActivePageOfs = 0; - CursCol0 = 0; - CursRow0 = 0; - CursCol1 = 0; - CursRow1 = 0; - CursCol2 = 0; - CursRow2 = 0; - CursCol3 = 0; - CursRow3 = 0; - CursCol4 = 0; - CursRow4 = 0; - CursCol5 = 0; - CursRow5 = 0; - CursCol6 = 0; - CursRow6 = 0; - CursCol7 = 0; - CursRow7 = 0; - CursStart = VGA_CRTC[CRTC_CursStart]; - CursEnd = VGA_CRTC[CRTC_CursEnd]; - ActivePage = 0; - DpyRows = videoparams[pidx][1]; - CharHeight = videoparams[pidx][2]; - - CRTCPort = vmode.numcolors > 1 ? CRTC_IndexPortColor : CRTC_IndexPortMono; - NumColors = vmode.numcolors; - NumPages = vmode.numpages; - VertResolution = vmode.vrescode; - vmem = (u_int16_t *)vmode.vmemaddr; - - /* Copy VGA related BIOS variables from 'vga_status'. */ - memcpy(&BIOS_VideoMode, &VideoMode, 33); - BIOS_DpyRows = DpyRows; - BIOS_CharHeight = CharHeight; - - /* Load 'pixels[]' from default DAC values. */ - update_pixels(); - - /* Update font. */ - xfont = vmode.fontname; - load_font(); - - /* Resize window if necessary. */ - resize_window(); - - /* Mmap video memory for the graphics modes. Write access to 0xa0000 - - 0xaffff will generate a T_PAGEFAULT trap in VM86 mode (aside: why not a - SIGSEGV?), which is handled in 'trap.c:sigbus()'. */ - if (vmode.type == GRAPHICS) { - vmem = mmap((void *)0xa0000, 64 * 1024, PROT_NONE, - MAP_ANON | MAP_FIXED | MAP_SHARED, -1, 0); - if (vmem == NULL) - fatal("Could not mmap() video memory"); - - /* Create an XImage to display the graphics screen. */ - get_ximage(); - } else { - int i; - - get_lines(); - if (mode & 0x80) - return; - /* Initialize video memory with black background, white foreground */ - vattr = 0x0700; - for (i = 0; i < DpyPageSize / 2; ++i) - vmem[i] = vattr; - } - - return; -} - -/* Find the requested mode in the 'vmodelist' table. This function returns the - index into this table; we will also use the index for accessing the - 'videoparams' array. */ -int find_vmode(int mode) -{ - unsigned i; - - for (i = 0; i < NUMMODES; i++) - if (vmodelist[i].modenumber == mode) - return i; - - return -1; -} - -/* Handle access to the graphics memory. - - Simply changing the protection for the memory is not enough, unfortunately. - It would only work for the 256 color modes, where a memory byte contains - the color value of one pixel. The 16 color modes (and 4 color modes) make - use of four bit planes which overlay the first 64K of video memory. The - bits are distributed into these bit planes according to the GDC state, so - we will have to emulate the CPU instructions (see 'cpu.c:emu_instr()'). - - Handling the 256 color modes will be a bit easier, once we support those at - all. */ -int -vmem_pageflt(struct sigframe *sf) -{ - regcontext_t *REGS = (regcontext_t *)(&sf->sf_uc.uc_mcontext); - - /* The ATC's Mode Control register tells us whether 4 or 8 color bits are - used */ - if (VGA_ATC[ATC_ModeCtrl] & (1 << 6)) { - /* 256 colors, allow writes; the protection will be set back to - PROT_READ at the next display update */ - mprotect(vmem, 64 * 1024, PROT_READ | PROT_WRITE); - return 0; - } - - /* There's no need to change the protection in the 16 color modes, we will - write to 'vram'. Just emulate the next instruction. */ - return emu_instr(REGS); -} - -/* We need to keep track of the latches' contents.*/ -static u_int8_t latch0, latch1, latch2, latch3; - -/* Read a byte from the video memory. 'vga_read()' is called from - 'cpu.c:read_byte()' and will emulate the VGA read modes. */ -u_int8_t -vga_read(u_int32_t addr) -{ - u_int32_t dst; - - /* 'addr' lies between 0xa0000 and 0xaffff. */ - dst = addr - 0xa0000; - - /* Fill latches. */ - latch0 = vplane0[dst]; - latch1 = vplane1[dst]; - latch2 = vplane2[dst]; - latch3 = vplane3[dst]; - - /* Select read mode. */ - if ((VGA_GDC[GDC_Mode] & 0x80) == 0) - /* Read Mode 0; return the byte from the selected bit plane. */ - return vram[dst + (VGA_GDC[GDC_ReadMapSelect] & 3) * 0x10000]; - - /* Read Mode 1 */ - debug(D_ALWAYS, "VGA: Read Mode 1 not implemented\n"); - return 0; -} - -/* Write a byte to the video memory. 'vga_write()' is called from - 'cpu.c:write_word()' and will emulate the VGA write modes. Not all four - modes are implemented yet, nor are the addressing modes (odd/even, chain4). - (NB: I think the latter will have to be done in 'tty_graphics_update()'). - */ -void -vga_write(u_int32_t addr, u_int8_t val) -{ - u_int32_t dst; - u_int8_t c0, c1, c2, c3; - u_int8_t m0, m1, m2, m3; - u_int8_t mask; - -#if 0 - unsigned i; - - debug(D_VIDEO, "VGA: Write 0x%02x to 0x%x\n", val, addr); - debug(D_VIDEO, " GDC: "); - for (i = 0; i < sizeof(VGA_GDC); i++) - debug(D_VIDEO, "%02x ", VGA_GDC[i]); - debug(D_VIDEO, "\n"); - debug(D_VIDEO, " TSC: "); - for (i = 0; i < sizeof(VGA_TSC); i++) - debug(D_VIDEO, "%02x ", VGA_TSC[i]); - debug(D_VIDEO, "\n"); -#endif - - /* 'addr' lies between 0xa0000 and 0xaffff. */ - dst = addr - 0xa0000; - - c0 = latch0; - c1 = latch1; - c2 = latch2; - c3 = latch3; - - /* Select write mode. */ - switch (VGA_GDC[GDC_Mode] & 3) { - case 0: - mask = VGA_GDC[GDC_BitMask]; - - if (VGA_GDC[GDC_DataRotate] & 7) - debug(D_ALWAYS, "VGA: Data Rotate != 0\n"); - - /* Select function. */ - switch (VGA_GDC[GDC_DataRotate] & 0x18) { - case 0x00: /* replace */ - m0 = VGA_GDC[GDC_SetReset] & 1 ? mask : 0x00; - m1 = VGA_GDC[GDC_SetReset] & 2 ? mask : 0x00; - m2 = VGA_GDC[GDC_SetReset] & 4 ? mask : 0x00; - m3 = VGA_GDC[GDC_SetReset] & 8 ? mask : 0x00; - - c0 = VGA_GDC[GDC_EnableSetReset] & 1 ? c0 & ~mask : val & ~mask; - c1 = VGA_GDC[GDC_EnableSetReset] & 2 ? c1 & ~mask : val & ~mask; - c2 = VGA_GDC[GDC_EnableSetReset] & 4 ? c2 & ~mask : val & ~mask; - c3 = VGA_GDC[GDC_EnableSetReset] & 8 ? c3 & ~mask : val & ~mask; - - c0 |= m0; - c1 |= m1; - c2 |= m2; - c3 |= m3; - break; - case 0x08: /* AND */ - m0 = VGA_GDC[GDC_SetReset] & 1 ? 0xff : ~mask; - m1 = VGA_GDC[GDC_SetReset] & 2 ? 0xff : ~mask; - m2 = VGA_GDC[GDC_SetReset] & 4 ? 0xff : ~mask; - m3 = VGA_GDC[GDC_SetReset] & 8 ? 0xff : ~mask; - - c0 = VGA_GDC[GDC_EnableSetReset] & 1 ? c0 & m0 : val & m0; - c1 = VGA_GDC[GDC_EnableSetReset] & 2 ? c1 & m1 : val & m1; - c2 = VGA_GDC[GDC_EnableSetReset] & 4 ? c2 & m2 : val & m2; - c3 = VGA_GDC[GDC_EnableSetReset] & 8 ? c3 & m3 : val & m3; - break; - case 0x10: /* OR */ - m0 = VGA_GDC[GDC_SetReset] & 1 ? mask : 0x00; - m1 = VGA_GDC[GDC_SetReset] & 2 ? mask : 0x00; - m2 = VGA_GDC[GDC_SetReset] & 4 ? mask : 0x00; - m3 = VGA_GDC[GDC_SetReset] & 8 ? mask : 0x00; - - c0 = VGA_GDC[GDC_EnableSetReset] & 1 ? c0 | m0 : val | m0; - c1 = VGA_GDC[GDC_EnableSetReset] & 2 ? c1 | m1 : val | m1; - c2 = VGA_GDC[GDC_EnableSetReset] & 4 ? c2 | m2 : val | m2; - c3 = VGA_GDC[GDC_EnableSetReset] & 8 ? c3 | m3 : val | m3; - break; - case 0x18: /* XOR */ - m0 = VGA_GDC[GDC_SetReset] & 1 ? mask : 0x00; - m1 = VGA_GDC[GDC_SetReset] & 2 ? mask : 0x00; - m2 = VGA_GDC[GDC_SetReset] & 4 ? mask : 0x00; - m3 = VGA_GDC[GDC_SetReset] & 8 ? mask : 0x00; - - c0 = VGA_GDC[GDC_EnableSetReset] & 1 ? c0 ^ m0 : val ^ m0; - c1 = VGA_GDC[GDC_EnableSetReset] & 2 ? c1 ^ m1 : val ^ m1; - c2 = VGA_GDC[GDC_EnableSetReset] & 4 ? c2 ^ m2 : val ^ m2; - c3 = VGA_GDC[GDC_EnableSetReset] & 8 ? c3 ^ m3 : val ^ m3; - break; - } - break; - case 1: - /* Just copy the latches' content to the desired destination - address. */ - break; - case 2: - mask = VGA_GDC[GDC_BitMask]; - - /* select function */ - switch (VGA_GDC[GDC_DataRotate] & 0x18) { - case 0x00: /* replace */ - m0 = (val & 1 ? 0xff : 0x00) & mask; - m1 = (val & 2 ? 0xff : 0x00) & mask; - m2 = (val & 4 ? 0xff : 0x00) & mask; - m3 = (val & 8 ? 0xff : 0x00) & mask; - - c0 &= ~mask; - c1 &= ~mask; - c2 &= ~mask; - c3 &= ~mask; - - c0 |= m0; - c1 |= m1; - c2 |= m2; - c3 |= m3; - break; - case 0x08: /* AND */ - m0 = (val & 1 ? 0xff : 0x00) | ~mask; - m1 = (val & 2 ? 0xff : 0x00) | ~mask; - m2 = (val & 4 ? 0xff : 0x00) | ~mask; - m3 = (val & 8 ? 0xff : 0x00) | ~mask; - - c0 &= m0; - c1 &= m1; - c2 &= m2; - c3 &= m3; - break; - case 0x10: /* OR */ - m0 = (val & 1 ? 0xff : 0x00) & mask; - m1 = (val & 2 ? 0xff : 0x00) & mask; - m2 = (val & 4 ? 0xff : 0x00) & mask; - m3 = (val & 8 ? 0xff : 0x00) & mask; - - c0 |= m0; - c1 |= m1; - c2 |= m2; - c3 |= m3; - break; - case 0x18: /* XOR */ - m0 = (val & 1 ? 0xff : 0x00) & mask; - m1 = (val & 2 ? 0xff : 0x00) & mask; - m2 = (val & 4 ? 0xff : 0x00) & mask; - m3 = (val & 8 ? 0xff : 0x00) & mask; - - c0 ^= m0; - c1 ^= m1; - c2 ^= m2; - c3 ^= m3; - break; - } - break; - case 3: - /* not yet */ - debug(D_ALWAYS, "VGA: Write Mode 3 not implemented\n"); - break; - } - - /* Write back changed byte, depending on Map Mask register. */ - if (VGA_TSC[TSC_MapMask] & 1) - vplane0[dst] = c0; - if (VGA_TSC[TSC_MapMask] & 2) - vplane1[dst] = c1; - if (VGA_TSC[TSC_MapMask] & 4) - vplane2[dst] = c2; - if (VGA_TSC[TSC_MapMask] & 8) - vplane3[dst] = c3; - - return; -} diff --git a/usr.bin/doscmd/video.h b/usr.bin/doscmd/video.h deleted file mode 100644 index 25cf753..0000000 --- a/usr.bin/doscmd/video.h +++ /dev/null @@ -1,377 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI video.h,v 2.2 1996/04/08 19:33:12 bostic Exp - * - * $FreeBSD$ - */ - -/* - * The VGA CRT Controller - */ -extern u_int8_t VGA_CRTC[]; - -/* CRTC registers - - We use the VGA register functions and don't care about the MDA. We also - leave out the undocumented registers at 0x22, 0x24, 0x3?. */ -#define CRTC_HorzTotal 0x00 -#define CRTC_HorzDispEnd 0x01 -#define CRTC_StartHorzBlank 0x02 -#define CRTC_EndHorzBlank 0x03 -#define CRTC_StartHorzRetrace 0x04 -#define CRTC_EndHorzRetrace 0x05 -#define CRTC_VertTotal 0x06 -#define CRTC_Overflow 0x07 -#define CRTC_ResetRowScan 0x08 -#define CRTC_MaxScanLine 0x09 -#define CRTC_CursStart 0x0a -#define CRTC_CursEnd 0x0b -#define CRTC_StartAddrHi 0x0c -#define CRTC_StartAddrLo 0x0d -#define CRTC_CurLocHi 0x0e -#define CRTC_CurLocLo 0x0f -#define CRTC_StartVertRetrace 0x10 -#define CRTC_EndVertRetrace 0x11 -#define CRTC_VertDispEnd 0x12 -#define CRTC_Offset 0x13 -#define CRTC_UnderlineLoc 0x14 -#define CRTC_StartVertBlank 0x15 -#define CRTC_EndVertBlank 0x16 -#define CRTC_ModeCtrl 0x17 -#define CRTC_LineCompare 0x18 - -#define CRTC_Size 0x19 - -/* Port addresses for the CRTC - - The registers are read by - OUT index_port, reg_nr - IN data_port, res - - They are written by - OUT index_port, reg_nr - OUT data_port, value -*/ - -#define CRTC_IndexPortColor 0x03d4 /* CRTC Address Register (Color) */ -#define CRTC_DataPortColor 0x03d5 /* CRTC Data Register (Color) */ -#define CRTC_IndexPortMono 0x03b4 /* CRTC Address Register (Mono) */ -#define CRTC_DataPortMono 0x03b5 /* CRTC Data Register (Mono) */ - -/* - * VGA Attribute Controller - */ -extern u_int8_t VGA_ATC[]; - -/* ATC registers - - The palette registers are here for completeness. We'll always use a - separate array 'palette[]' to access them in our code. */ -#define ATC_Palette0 0x00 -#define ATC_Palette1 0x01 -#define ATC_Palette2 0x02 -#define ATC_Palette3 0x03 -#define ATC_Palette4 0x04 -#define ATC_Palette5 0x05 -#define ATC_Palette6 0x06 -#define ATC_Palette7 0x07 -#define ATC_Palette8 0x08 -#define ATC_Palette9 0x09 -#define ATC_PaletteA 0x0a -#define ATC_PaletteB 0x0b -#define ATC_PaletteC 0x0c -#define ATC_PaletteD 0x0d -#define ATC_PaletteE 0x0e -#define ATC_PaletteF 0x0f -#define ATC_ModeCtrl 0x10 -#define ATC_OverscanColor 0x11 -#define ATC_ColorPlaneEnable 0x12 -#define ATC_HorzPixelPanning 0x13 -#define ATC_ColorSelect 0x14 - -#define ATC_Size 0x15 - -/* Port addresses for the ATC - - The ATC has a combined index/data port at 0x03c0. To quote from Ralf - Brown's ports list: ``Every write access to this register will toggle an - internal index/data selection flipflop, so that consecutive writes to index - & data is possible through this port. To get a defined start condition, - each read access to the input status register #1 (3BAh in mono / 3DAh in - color) resets the flipflop to load index.'' */ -#define ATC_WritePort 0x03c0 -#define ATC_ReadPort 0x03c1 - -/* - * VGA Sequencer Controller - */ -extern u_int8_t VGA_TSC[]; - -/* TSC registers - - We leave out the undocumented register at 0x07. */ -#define TSC_Reset 0x00 -#define TSC_ClockingMode 0x01 -#define TSC_MapMask 0x02 -#define TSC_CharMapSelect 0x03 -#define TSC_MemoryMode 0x04 - -#define TSC_Size 0x05 - -/* Port addresses for the TSC */ -#define TSC_IndexPort 0x03c4 -#define TSC_DataPort 0x03c5 - -/* - * VGA Graphics Controller - */ -extern u_int8_t VGA_GDC[]; - -/* GDC registers */ -#define GDC_SetReset 0x00 -#define GDC_EnableSetReset 0x01 -#define GDC_ColorCompare 0x02 -#define GDC_DataRotate 0x03 -#define GDC_ReadMapSelect 0x04 -#define GDC_Mode 0x05 -#define GDC_Misc 0x06 -#define GDC_ColorDontCare 0x07 -#define GDC_BitMask 0x08 - -#define GDC_Size 0x09 - -/* Port addresses for the GDC */ -#define GDC_IndexPort 0x03ce -#define GDC_DataPort 0x03cf - -/* - * Miscellaneous VGA registers - */ -u_int8_t VGA_InputStatus0; -u_int8_t VGA_InputStatus1; -u_int8_t VGA_MiscOutput; - -u_int8_t VGA_DAC_PELData; -u_int8_t VGA_DAC_PELMask; -u_int8_t VGA_DAC_PELReadAddr; -u_int8_t VGA_DAC_PELWriteAddr; -u_int8_t VGA_DAC_State; - -/* Port addresses for miscellaneous VGA registers */ -#define VGA_InputStatus0Port 0x03c2 /* Read-only */ -#define VGA_InputStatus1Port 0x03da /* Read-only */ -#define VGA_MiscOutputPortW 0x03c2 /* Write-only */ -#define VGA_MiscOutputPortR 0x03cc /* Read-only */ - -/* Port addresses for VGA DAC registers */ -#define VGA_DAC_PELDataPort 0x03c9 /* Read/Write */ -#define VGA_DAC_PELMaskPort 0x03c6 /* Read/Write */ -#define VGA_DAC_PELReadAddrPort 0x03c7 /* Write-only */ -#define VGA_DAC_PELWriteAddrPort 0x03c8 /* Read/Write */ -#define VGA_DAC_StatePortOut 0x03c7 /* Read-only */ - -/* - * Additional variables and type definitions - */ - -/* To ease access to the palette registers, 'palette[]' will overlay the - Attribute Controller space. */ -u_int8_t *palette; - -/* Entry type for the DAC table. Each value is actually 6 bits wide. */ -struct dac_colors { - u_int8_t red; - u_int8_t green; - u_int8_t blue; -}; - -/* We need a working copy of the default DAC table. This is filled from - 'dac_default{64,256}[]' in 'video.c:init_vga()'. */ -struct dac_colors *dac_rgb; - -/* - * Video memory - * - * The video memory of a standard VGA card is 256K. For the standard modes, - * this is divided into four planes of 64K which are accessed according to the - * GDC state. Mode 0x13 will also fit within 64K. The higher resolution modes - * (VESA) require a bit more sophistication; we leave that for later - * implementation. - */ - -/* Video RAM */ -u_int8_t *vram; - -/* Pointers to the four bit planes */ -u_int8_t *vplane0; -u_int8_t *vplane1; -u_int8_t *vplane2; -u_int8_t *vplane3; - -/* Pointer to the video memory. The base address varies with the video mode. - 'vmem' is used directly only in the text modes; in the graphics modes, all - writes go to 'vram'. */ -u_int16_t *vmem; - -/* - * VGA status information - * - * Int 10:1b returns a 64 byte block of status info for the VGA card. This - * block also contains a couple of BIOS variables, so we will use it for - * general housekeeping. - */ -extern u_int8_t vga_status[]; - -/* Access to the VGA status fields. */ -#define StaticFuncTbl *(u_int32_t *)&vga_status[0] -#define VideoMode *(u_int8_t *)&vga_status[4] -#define DpyCols *(u_int16_t *)&vga_status[5] -#define DpyPageSize *(u_int16_t *)&vga_status[7] -#define ActivePageOfs *(u_int16_t *)&vga_status[9] -#define CursCol0 *(u_int8_t *)&vga_status[11] -#define CursRow0 *(u_int8_t *)&vga_status[12] -#define CursCol1 *(u_int8_t *)&vga_status[13] -#define CursRow1 *(u_int8_t *)&vga_status[14] -#define CursCol2 *(u_int8_t *)&vga_status[15] -#define CursRow2 *(u_int8_t *)&vga_status[16] -#define CursCol3 *(u_int8_t *)&vga_status[17] -#define CursRow3 *(u_int8_t *)&vga_status[18] -#define CursCol4 *(u_int8_t *)&vga_status[19] -#define CursRow4 *(u_int8_t *)&vga_status[20] -#define CursCol5 *(u_int8_t *)&vga_status[21] -#define CursRow5 *(u_int8_t *)&vga_status[22] -#define CursCol6 *(u_int8_t *)&vga_status[23] -#define CursRow6 *(u_int8_t *)&vga_status[24] -#define CursCol7 *(u_int8_t *)&vga_status[25] -#define CursRow7 *(u_int8_t *)&vga_status[26] -#define CursStart *(u_int8_t *)&vga_status[27] -#define CursEnd *(u_int8_t *)&vga_status[28] -#define ActivePage *(u_int8_t *)&vga_status[29] -#define CRTCPort *(u_int16_t *)&vga_status[30] -#define CGA_ModeCtrl *(u_int8_t *)&vga_status[32] -#define CGA_ColorSelect *(u_int8_t *)&vga_status[33] -#define DpyRows *(u_int8_t *)&vga_status[34] -#define CharHeight *(u_int16_t *)&vga_status[35] -#define ActiveDCC *(u_int8_t *)&vga_status[37] -#define SecondDCC *(u_int8_t *)&vga_status[38] -#define NumColors *(u_int16_t *)&vga_status[39] -#define NumPages *(u_int8_t *)&vga_status[41] -#define VertResolution *(u_int8_t *)&vga_status[42] -#define PrimaryCharset *(u_int8_t *)&vga_status[43] -#define SecondaryCharset *(u_int8_t *)&vga_status[44] -#define MiscStatus *(u_int8_t *)&vga_status[45] -/* -#define Reserved1 *(u_int16_t *)&vga_status[46] -#define Reserved2 *(u_int8_t *)&vga_status[48] -*/ -#define VMemSize *(u_int8_t *)&vga_status[49] -#define SavePointerStatus *(u_int8_t *)&vga_status[50] - -/* VGA Static Functionality Table - - This table contains mode-independent VGA status information. It is actually - defined in 'vparam.h'; the declaration here is just for completeness. */ -extern u_int8_t static_functionality_tbl[]; - -/* Add some names for the VGA related BIOS variables. */ -#define BIOS_VideoMode *(u_int8_t *)&BIOSDATA[0x49] -#define BIOS_DpyCols *(u_int16_t *)&BIOSDATA[0x4a] -#define BIOS_DpyPageSize *(u_int16_t *)&BIOSDATA[0x4c] -#define BIOS_ActivePageOfs *(u_int16_t *)&BIOSDATA[0x4e] -#define BIOS_CursCol0 *(u_int8_t *)&BIOSDATA[0x50] -#define BIOS_CursRow0 *(u_int8_t *)&BIOSDATA[0x51] -#define BIOS_CursCol1 *(u_int8_t *)&BIOSDATA[0x52] -#define BIOS_CursRow1 *(u_int8_t *)&BIOSDATA[0x53] -#define BIOS_CursCol2 *(u_int8_t *)&BIOSDATA[0x54] -#define BIOS_CursRow2 *(u_int8_t *)&BIOSDATA[0x55] -#define BIOS_CursCol3 *(u_int8_t *)&BIOSDATA[0x56] -#define BIOS_CursRow3 *(u_int8_t *)&BIOSDATA[0x57] -#define BIOS_CursCol4 *(u_int8_t *)&BIOSDATA[0x58] -#define BIOS_CursRow4 *(u_int8_t *)&BIOSDATA[0x59] -#define BIOS_CursCol5 *(u_int8_t *)&BIOSDATA[0x5a] -#define BIOS_CursRow5 *(u_int8_t *)&BIOSDATA[0x5b] -#define BIOS_CursCol6 *(u_int8_t *)&BIOSDATA[0x5c] -#define BIOS_CursRow6 *(u_int8_t *)&BIOSDATA[0x5d] -#define BIOS_CursCol7 *(u_int8_t *)&BIOSDATA[0x5e] -#define BIOS_CursRow7 *(u_int8_t *)&BIOSDATA[0x5f] -#define BIOS_CursStart *(u_int8_t *)&BIOSDATA[0x60] -#define BIOS_CursEnd *(u_int8_t *)&BIOSDATA[0x61] -#define BIOS_ActivePage *(u_int8_t *)&BIOSDATA[0x62] -#define BIOS_CRTCPort *(u_int16_t *)&BIOSDATA[0x63] -#define BIOS_CGA_ModeCtrl *(u_int8_t *)&BIOSDATA[0x65] -#define BIOS_CGA_ColorSelect *(u_int8_t *)&BIOSDATA[0x66] -#define BIOS_DpyRows *(u_int8_t *)&BIOSDATA[0x84] -#define BIOS_CharHeight *(u_int16_t *)&BIOSDATA[0x85] -#define BIOS_SaveTablePointer *(u_int32_t *)&BIOSDATA[0xa8] - -/* - * Video modes - * - * This started as a big 'switch' statement in 'video.c:init_mode()' which - * soon became too ugly and unmanagable. So, we collect all mode related - * information in one table and define a couple of helper function to access - * it. This will also benefit the VESA support, whenever we get to that. - */ -typedef struct { - int modenumber; /* Mode number */ - int paramindex; /* Index into the parameter table */ - int type; /* Text or Graphics */ - int numcolors; /* Number of colors */ - int numpages; /* Number of display pages */ - int vrescode; /* 0 = 200, 1 = 350, 2 = 400, 3 = 480 */ - u_int32_t vmemaddr; /* Video memory address */ - const char *fontname; /* Font name */ -} vmode_t; - -/* Types. 'NOMODE' is one of the 'forbidden' internal modes. */ -#define TEXT 0 -#define GRAPHICS 1 -#define NOMODE -1 - -extern vmode_t vmodelist[]; - -/* Font names */ -#define FONTVGA "vga" -#define FONT8x8 "vga8x8" -#define FONT8x14 "vga8x14" -#define FONT8x16 "vga8x16" /* same as FONTVGA */ - -/* External functions in 'video.c'. */ -void init_mode(int); -int find_vmode(int); -u_int8_t vga_read(u_int32_t); -void vga_write(u_int32_t, u_int8_t); -void video_bios_init(void); -void video_init(void); -int vmem_pageflt(struct sigframe *); - -/* Other external variables, mostly from tty.c. Needs to be cleaned up. */ -extern int vattr; -void write_vram(void *); diff --git a/usr.bin/doscmd/vparams.h b/usr.bin/doscmd/vparams.h deleted file mode 100644 index dce9027..0000000 --- a/usr.bin/doscmd/vparams.h +++ /dev/null @@ -1,495 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1996 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Berkeley Software - * Design, Inc. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI vparams.h,v 2.2 1996/04/08 19:33:13 bostic Exp - * - * $FreeBSD$ - */ - -/* Collect some default parameters for the VGA emulator in this file. This is - supposed to be included only from 'video.c' and needs some type definitions - from 'video.h'. */ - -u_int8_t videoparams[][64] = { - /* Mode 0: Text, 40x25, CGA (200 lines) */ - { 0x28, 0x18, 0x08, 0x00, 0x08, 0x09, 0x03, 0x00, - 0x02, 0x63, 0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, - 0xbf, 0x1f, 0x00, 0xc7, 0x06, 0x07, 0x00, 0x00, - 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, - 0xb9, 0xa3, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, - 0x05, 0x14, 0x07, 0x38, 0x39, 0x3a, 0x3b, 0x3c, - 0x3d, 0x3e, 0x3f, 0x08, 0x00, 0x0f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, 0xff - }, - /* Mode 1: Text, 40x25, CGA (200 lines) */ - { 0x28, 0x18, 0x08, 0x00, 0x08, 0x09, 0x03, 0x00, - 0x02, 0x63, 0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, - 0xbf, 0x1f, 0x00, 0xc7, 0x06, 0x07, 0x00, 0x00, - 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, - 0xb9, 0xa3, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, - 0x05, 0x14, 0x07, 0x38, 0x39, 0x3a, 0x3b, 0x3c, - 0x3d, 0x3e, 0x3f, 0x08, 0x00, 0x0f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, 0xff, - }, - /* Mode 2: Text, 80x25, CGA (200 lines) */ - { 0x50, 0x18, 0x08, 0x00, 0x10, 0x01, 0x03, 0x00, - 0x02, 0x63, 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, - 0xbf, 0x1f, 0x00, 0xc7, 0x06, 0x07, 0x00, 0x00, - 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, - 0xb9, 0xa3, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, - 0x05, 0x14, 0x07, 0x38, 0x39, 0x3a, 0x3b, 0x3c, - 0x3d, 0x3e, 0x3f, 0x08, 0x00, 0x0f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, 0xff, - }, - /* Mode 3: Text, 80x25, CGA (200 lines) */ - { 0x50, 0x18, 0x08, 0x00, 0x10, 0x01, 0x03, 0x00, - 0x02, 0x63, 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, - 0xbf, 0x1f, 0x00, 0xc7, 0x06, 0x07, 0x00, 0x00, - 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, - 0xb9, 0xa3, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, - 0x05, 0x14, 0x07, 0x38, 0x39, 0x3a, 0x3b, 0x3c, - 0x3d, 0x3e, 0x3f, 0x08, 0x00, 0x0f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, 0xff, - }, - /* Mode 4: Graphics, 320x200, 4 colors */ - { 0x28, 0x18, 0x08, 0x00, 0x40, 0x09, 0x03, 0x00, - 0x02, 0x63, 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, - 0xbf, 0x1f, 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, - 0xb9, 0xa2, 0xff, 0x00, 0x13, 0x15, 0x17, 0x02, - 0x04, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13, 0x14, - 0x15, 0x16, 0x17, 0x01, 0x00, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x00, 0xff, - }, - /* Mode 5: Graphics, 320x200, 4 colors */ - { 0x28, 0x18, 0x08, 0x00, 0x40, 0x09, 0x03, 0x00, - 0x02, 0x63, 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, - 0xbf, 0x1f, 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, - 0xb9, 0xa2, 0xff, 0x00, 0x13, 0x15, 0x17, 0x02, - 0x04, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13, 0x14, - 0x15, 0x16, 0x17, 0x01, 0x00, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x00, 0xff, - }, - /* Mode 6: Graphics, 640x200, 2 colors */ - { 0x50, 0x18, 0x08, 0x00, 0x40, 0x01, 0x01, 0x00, - 0x06, 0x63, 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, - 0xbf, 0x1f, 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, - 0xb9, 0xc2, 0xff, 0x00, 0x17, 0x17, 0x17, 0x17, - 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, - 0x17, 0x17, 0x17, 0x01, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0xff, - }, - /* Mode 7: Text, 80x25, mono, MDA (350 lines) */ - { 0x50, 0x18, 0x0e, 0x00, 0x10, 0x00, 0x03, 0x00, - 0x03, 0xa6, 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, - 0xbf, 0x1f, 0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, - 0x00, 0x00, 0x83, 0x85, 0x5d, 0x28, 0x0d, 0x63, - 0xba, 0xa3, 0xff, 0x00, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x10, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x0e, 0x00, 0x0f, 0x08, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x00, 0xff, - }, - /* Mode 8: reserved */ - { 0x50, 0x18, 0x10, 0x00, 0x10, 0x01, 0x03, 0x00, - 0x02, 0x62, 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, - 0xbf, 0x1f, 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, - 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x28, 0x0f, 0x96, - 0xb9, 0xa3, 0xff, 0x00, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x10, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x0a, 0x00, 0x0f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x00, 0xff, - }, - /* Mode 9: reserved */ - { 0x28, 0x18, 0x10, 0x00, 0x08, 0x09, 0x03, 0x00, - 0x02, 0x63, 0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, - 0xbf, 0x1f, 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, - 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, - 0xb9, 0xa3, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, - 0x05, 0x14, 0x07, 0x38, 0x39, 0x3a, 0x3b, 0x3c, - 0x3d, 0x3e, 0x3f, 0x08, 0x00, 0x0f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, 0xff, - }, - /* Mode a: reserved */ - { 0x50, 0x18, 0x10, 0x00, 0x10, 0x01, 0x03, 0x00, - 0x02, 0x63, 0x60, 0x4f, 0x50, 0x82, 0x56, 0x82, - 0xbf, 0x1f, 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, - 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, - 0xb9, 0xa3, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, - 0x05, 0x14, 0x07, 0x38, 0x39, 0x3a, 0x3b, 0x3c, - 0x3d, 0x3e, 0x3f, 0x08, 0x00, 0x0f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, 0xff, - }, - /* Mode b: reserved */ - { 0x50, 0x00, 0x00, 0x00, 0x00, 0x29, 0x0f, 0x00, - 0x06, 0x62, 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, - 0xbf, 0x1f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, - 0xb9, 0xe3, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3f, 0x01, 0x00, 0x0f, 0x00, 0x00, - 0x00, 0x0f, 0x00, 0x00, 0x08, 0x05, 0x0f, 0xff, - }, - /* Mode c: reserved */ - { 0x50, 0x00, 0x00, 0x00, 0x00, 0x29, 0x0f, 0x00, - 0x06, 0x63, 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, - 0xbf, 0x1f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, - 0xb9, 0xe3, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3f, 0x01, 0x00, 0x0f, 0x00, 0x00, - 0x00, 0x0f, 0x00, 0x00, 0x08, 0x05, 0x0f, 0xff, - }, - /* Mode d: Graphics, 320x200, 16 colors */ - { 0x28, 0x18, 0x08, 0x00, 0x20, 0x09, 0x0f, 0x00, - 0x06, 0x63, 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, - 0xbf, 0x1f, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, - 0xb9, 0xe3, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, - 0x05, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13, 0x14, - 0x15, 0x16, 0x17, 0x01, 0x00, 0x0f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, - }, - /* Mode e: Graphics, 640x200, 16 colors */ - { 0x50, 0x18, 0x08, 0x00, 0x40, 0x01, 0x0f, 0x00, - 0x06, 0x63, 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, - 0xbf, 0x1f, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, - 0xb9, 0xe3, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, - 0x05, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13, 0x14, - 0x15, 0x16, 0x17, 0x01, 0x00, 0x0f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, - }, - /* Mode f: Graphics, 640x350, mono (EGA with 64K) */ - { 0x50, 0x18, 0x0e, 0x00, 0x80, 0x01, 0x0f, 0x00, - 0x06, 0xa2, 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, - 0xbf, 0x1f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x83, 0x85, 0x5d, 0x28, 0x0f, 0x63, - 0xba, 0xe3, 0xff, 0x00, 0x08, 0x00, 0x00, 0x18, - 0x18, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x0b, 0x00, 0x05, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x05, 0xff, - }, - /* Mode 10: Graphics, 640x350, 4 colors (EGA with 64K) */ - { 0x50, 0x18, 0x0e, 0x00, 0x80, 0x01, 0x0f, 0x00, - 0x06, 0xa3, 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, - 0xbf, 0x1f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x83, 0x85, 0x5d, 0x28, 0x0f, 0x63, - 0xba, 0xe3, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, - 0x05, 0x14, 0x07, 0x38, 0x39, 0x3a, 0x3b, 0x3c, - 0x3d, 0x3e, 0x3f, 0x01, 0x00, 0x0f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, - }, - /* Mode f: Graphics, 640x350, mono (EGA with >64K) */ - { 0x50, 0x18, 0x0e, 0x00, 0x80, 0x01, 0x0f, 0x00, - 0x06, 0xa2, 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, - 0xbf, 0x1f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x83, 0x85, 0x5d, 0x28, 0x0f, 0x63, - 0xba, 0xe3, 0xff, 0x00, 0x08, 0x00, 0x00, 0x18, - 0x18, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x0b, 0x00, 0x05, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x05, 0xff, - }, - /* Mode 10: Graphics, 640x350, 16 colors (EGA with >64K) */ - { 0x50, 0x18, 0x0e, 0x00, 0x80, 0x01, 0x0f, 0x00, - 0x06, 0xa3, 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, - 0xbf, 0x1f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x83, 0x85, 0x5d, 0x28, 0x0f, 0x63, - 0xba, 0xe3, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, - 0x05, 0x14, 0x07, 0x38, 0x39, 0x3a, 0x3b, 0x3c, - 0x3d, 0x3e, 0x3f, 0x01, 0x00, 0x0f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, - }, - /* Mode 0: Text, 40x25, EGA (350 lines) */ - { 0x28, 0x18, 0x0e, 0x00, 0x08, 0x09, 0x03, 0x00, - 0x02, 0xa3, 0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, - 0xbf, 0x1f, 0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, - 0x00, 0x00, 0x83, 0x85, 0x5d, 0x14, 0x1f, 0x63, - 0xba, 0xa3, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, - 0x05, 0x14, 0x07, 0x38, 0x39, 0x3a, 0x3b, 0x3c, - 0x3d, 0x3e, 0x3f, 0x08, 0x00, 0x0f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, 0xff, - }, - /* Mode 1: Text, 40x25, EGA (350 lines) */ - { 0x28, 0x18, 0x0e, 0x00, 0x08, 0x09, 0x03, 0x00, - 0x02, 0xa3, 0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, - 0xbf, 0x1f, 0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, - 0x00, 0x00, 0x83, 0x85, 0x5d, 0x14, 0x1f, 0x63, - 0xba, 0xa3, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, - 0x05, 0x14, 0x07, 0x38, 0x39, 0x3a, 0x3b, 0x3c, - 0x3d, 0x3e, 0x3f, 0x08, 0x00, 0x0f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, 0xff, - }, - /* Mode 2: Text, 80x25, EGA (350 lines) */ - { 0x50, 0x18, 0x0e, 0x00, 0x10, 0x01, 0x03, 0x00, - 0x02, 0xa3, 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, - 0xbf, 0x1f, 0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, - 0x00, 0x00, 0x83, 0x85, 0x5d, 0x28, 0x1f, 0x63, - 0xba, 0xa3, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, - 0x05, 0x14, 0x07, 0x38, 0x39, 0x3a, 0x3b, 0x3c, - 0x3d, 0x3e, 0x3f, 0x08, 0x00, 0x0f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, 0xff, - }, - /* Mode 3: Text, 80x25, EGA (350 lines) */ - { 0x50, 0x18, 0x0e, 0x00, 0x10, 0x01, 0x03, 0x00, - 0x02, 0xa3, 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, - 0xbf, 0x1f, 0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, - 0x00, 0x00, 0x83, 0x85, 0x5d, 0x28, 0x1f, 0x63, - 0xba, 0xa3, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, - 0x05, 0x14, 0x07, 0x38, 0x39, 0x3a, 0x3b, 0x3c, - 0x3d, 0x3e, 0x3f, 0x08, 0x00, 0x0f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, 0xff, - }, - /* Modes 0, 1: Text, 40x25, VGA (400 lines) */ - { 0x28, 0x18, 0x10, 0x00, 0x08, 0x08, 0x03, 0x00, - 0x02, 0x67, 0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, - 0xbf, 0x1f, 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, - 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, - 0xb9, 0xa3, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, - 0x05, 0x14, 0x07, 0x38, 0x39, 0x3a, 0x3b, 0x3c, - 0x3d, 0x3e, 0x3f, 0x0c, 0x00, 0x0f, 0x08, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, 0xff, - }, - /* Modes 2, 3: Text, 80x25, VGA (400 lines) */ - { 0x50, 0x18, 0x10, 0x00, 0x10, 0x00, 0x03, 0x00, - 0x02, 0x67, 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, - 0xbf, 0x1f, 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, - 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, - 0xb9, 0xa3, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, - 0x05, 0x14, 0x07, 0x38, 0x39, 0x3a, 0x3b, 0x3c, - 0x3d, 0x3e, 0x3f, 0x0c, 0x00, 0x0f, 0x08, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, 0xff, - }, - /* Mode 7: Text, 80x25, mono, VGA (400 lines) */ - { 0x50, 0x18, 0x10, 0x00, 0x10, 0x00, 0x03, 0x00, - 0x02, 0x66, 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, - 0xbf, 0x1f, 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, - 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x28, 0x0f, 0x96, - 0xb9, 0xa3, 0xff, 0x00, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x10, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x0e, 0x00, 0x0f, 0x08, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x00, 0xff, - }, - /* Mode 11: Graphics, 640x480, 2 colors */ - { 0x50, 0x1d, 0x10, 0x00, 0xa0, 0x01, 0x0f, 0x00, - 0x06, 0xe3, 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, - 0x0b, 0x3e, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xea, 0x8c, 0xdf, 0x28, 0x00, 0xe7, - 0x04, 0xc3, 0xff, 0x00, 0x3f, 0x3f, 0x3f, 0x3f, - 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, - 0x3f, 0x3f, 0x3f, 0x01, 0x00, 0x0f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x01, 0xff, - }, - /* Mode 12: Graphics, 640x480, 16 colors */ - { 0x50, 0x1d, 0x10, 0x00, 0xa0, 0x01, 0x0f, 0x00, - 0x06, 0xe3, 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, - 0x0b, 0x3e, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xea, 0x8c, 0xdf, 0x28, 0x00, 0xe7, - 0x04, 0xe3, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, - 0x05, 0x14, 0x07, 0x38, 0x39, 0x3a, 0x3b, 0x3c, - 0x3d, 0x3e, 0x3f, 0x01, 0x00, 0x0f, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, - }, - /* Mode 13: Graphics, 320x200, 256 colors */ - { 0x28, 0x18, 0x08, 0x00, 0x20, 0x01, 0x0f, 0x00, - 0x0e, 0x63, 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, - 0xbf, 0x1f, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x28, 0x40, 0x96, - 0xb9, 0xa3, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, - 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, - 0x0d, 0x0e, 0x0f, 0x41, 0x00, 0x0f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f, 0xff, - }, - { 0x50, 0x1d, 0x10, 0x00, 0x20, 0x01, 0x03, 0x00, - 0x02, 0xe3, 0x5f, 0x4f, 0x50, 0x82, 0x57, 0x82, - 0x08, 0x3e, 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, - 0x00, 0x00, 0xea, 0x8f, 0xdf, 0x28, 0x00, 0xe7, - 0x04, 0xa3, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, - 0x05, 0x14, 0x07, 0x38, 0x39, 0x3a, 0x3b, 0x3c, - 0x3d, 0x3e, 0x3f, 0x08, 0x00, 0x0f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, 0xff, - }, - { 0x84, 0x18, 0x10, 0x00, 0x20, 0x01, 0x03, 0x00, - 0x42, 0x62, 0x9b, 0x83, 0x86, 0x9e, 0x8a, 0x1b, - 0xbf, 0x1f, 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, - 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x42, 0x0f, 0x96, - 0xb9, 0xa3, 0xff, 0x00, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x10, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x0a, 0x00, 0x0f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x00, 0xff, - }, - { 0x84, 0x18, 0x10, 0x00, 0x20, 0x01, 0x03, 0x00, - 0x42, 0x63, 0x9b, 0x83, 0x86, 0x9e, 0x8a, 0x1b, - 0xbf, 0x1f, 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, - 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x42, 0x0f, 0x96, - 0xb9, 0xa3, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, - 0x05, 0x14, 0x07, 0x38, 0x39, 0x3a, 0x3b, 0x3c, - 0x3d, 0x3e, 0x3f, 0x08, 0x00, 0x0f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, 0xff, - }, -}; - -/* The default DAC table for the EGA and VGA 16 color modes. This table is - installed on startup. The values are taken from the output of 'scon -p - list'. */ -struct dac_colors dac_default64[] = { - {0, 0, 0}, {0, 0, 42}, {0, 42, 0}, {0, 42, 42}, - {42, 0, 0}, {42, 0, 42}, {42, 42, 0}, {42, 42, 42}, - {0, 0, 21}, {0, 0, 63}, {0, 42, 21}, {0, 42, 63}, - {42, 0, 21}, {42, 0, 63}, {42, 42, 21}, {42, 42, 63}, - {0, 21, 0}, {0, 21, 42}, {0, 63, 0}, {0, 63, 42}, - {42, 21, 0}, {42, 21, 42}, {42, 63, 0}, {42, 63, 42}, - {0, 21, 21}, {0, 21, 63}, {0, 63, 21}, {0, 63, 63}, - {42, 21, 21}, {42, 21, 63}, {42, 63, 21}, {42, 63, 63}, - {21, 0, 0}, {21, 0, 42}, {21, 42, 0}, {21, 42, 42}, - {63, 0, 0}, {63, 0, 42}, {63, 42, 0}, {63, 42, 42}, - {21, 0, 21}, {21, 0, 63}, {21, 42, 21}, {21, 42, 63}, - {63, 0, 21}, {63, 0, 63}, {63, 42, 21}, {63, 42, 63}, - {21, 21, 0}, {21, 21, 42}, {21, 63, 0}, {21, 63, 42}, - {63, 21, 0}, {63, 21, 42}, {63, 63, 0}, {63, 63, 42}, - {21, 21, 21}, {21, 21, 63}, {21, 63, 21}, {21, 63, 63}, - {63, 21, 21}, {63, 21, 63}, {63, 63, 21}, {63, 63, 63} -}; - -/* The default DAC table for the 256 color mode. The values are taken from the - output of 'vdacc.exe', from Michael Tischler's book ``PC intern 4''. */ -struct dac_colors dac_default256[] = { - /* 16 CGA colors */ - {0, 0, 0}, {0, 0, 42}, {0, 42, 0}, {0, 42, 42}, - {42, 0, 0}, {42, 0, 42}, {42, 21, 0}, {42, 42, 42}, - {21, 21, 21}, {21, 21, 63}, {21, 63, 21}, {21, 63, 63}, - {63, 21, 21}, {63, 21, 63}, {63, 63, 21}, {63, 63, 63}, - /* grayscale */ - {0, 0, 0}, {5, 5, 5}, {8, 8, 8}, {11, 11, 11}, - {14, 14, 14}, {17, 17, 17}, {20, 20, 20}, {24, 24, 24}, - {28, 28, 28}, {32, 32, 32}, {36, 36, 36}, {40, 40, 40}, - {45, 45, 45}, {50, 50, 50}, {56, 56, 56}, {63, 63, 63}, - /* high intensity, high saturation */ - {0, 0, 63}, {16, 0, 63}, {31, 0, 63}, {47, 0, 63}, - {63, 0, 63}, {63, 0, 47}, {63, 0, 31}, {63, 0, 16}, - {63, 63, 0}, {63, 16, 0}, {63, 31, 0}, {63, 47, 0}, - {63, 63, 0}, {47, 63, 0}, {31, 63, 0}, {16, 63, 0}, - {0, 63, 0}, {0, 63, 16}, {0, 63, 31}, {0, 63, 47}, - {0, 63, 63}, {0, 47, 63}, {0, 31, 63}, {0, 16, 63}, - /* high intensity, medium saturation */ - {31, 31, 63}, {39, 31, 63}, {47, 31, 63}, {55, 31, 63}, - {63, 31, 63}, {63, 31, 55}, {63, 31, 47}, {63, 31, 39}, - {63, 31, 31}, {63, 39, 31}, {63, 47, 31}, {63, 55, 31}, - {63, 63, 31}, {55, 63, 31}, {47, 63, 31}, {39, 63, 31}, - {31, 63, 31}, {31, 63, 39}, {31, 63, 47}, {31, 63, 55}, - {31, 63, 63}, {31, 55, 63}, {31, 47, 63}, {31, 39, 63}, - /* high intensity, low saturation */ - {45, 45, 63}, {49, 45, 63}, {54, 45, 63}, {58, 45, 63}, - {63, 45, 63}, {63, 45, 58}, {63, 45, 54}, {63, 45, 49}, - {63, 45, 45}, {63, 49, 45}, {63, 54, 45}, {63, 58, 45}, - {63, 63, 45}, {58, 63, 45}, {54, 63, 45}, {49, 63, 45}, - {45, 63, 45}, {45, 63, 49}, {45, 63, 54}, {45, 63, 58}, - {45, 63, 63}, {45, 58, 63}, {45, 54, 63}, {45, 49, 63}, - /* medium intensity, high saturation */ - {0, 0, 28}, {7, 0, 28}, {14, 0, 28}, {21, 0, 28}, - {28, 0, 28}, {28, 0, 21}, {28, 0, 14}, {28, 0, 7}, - {28, 0, 0}, {28, 7, 0}, {28, 14, 0}, {28, 21, 0}, - {28, 28, 0}, {21, 28, 0}, {14, 28, 0}, {7, 28, 0}, - {0, 28, 0}, {0, 28, 7}, {0, 28, 14}, {0, 28, 21}, - {0, 28, 28}, {0, 21, 28}, {0, 14, 28}, {0, 7, 28}, - /* medium intensity, medium saturation */ - {14, 14, 28}, {17, 14, 28}, {21, 14, 28}, {24, 14, 28}, - {28, 14, 28}, {28, 14, 24}, {28, 14, 21}, {28, 14, 17}, - {28, 14, 14}, {28, 17, 14}, {28, 21, 14}, {28, 24, 14}, - {28, 28, 14}, {24, 28, 14}, {21, 28, 14}, {17, 28, 14}, - {14, 28, 14}, {14, 28, 17}, {14, 28, 21}, {14, 28, 24}, - {14, 28, 28}, {14, 24, 28}, {14, 21, 28}, {14, 17, 28}, - /* medium intensity, low saturation */ - {20, 20, 28}, {22, 20, 28}, {24, 20, 28}, {26, 20, 28}, - {28, 20, 28}, {28, 20, 26}, {28, 20, 24}, {28, 20, 22}, - {28, 20, 20}, {28, 22, 20}, {28, 24, 20}, {28, 26, 20}, - {28, 28, 20}, {26, 28, 20}, {24, 28, 20}, {22, 28, 20}, - {20, 28, 20}, {20, 28, 22}, {20, 28, 24}, {20, 28, 26}, - {20, 28, 28}, {20, 26, 28}, {20, 24, 28}, {20, 22, 28}, - /* low intensity, high saturation */ - {0, 0, 16}, {4, 0, 16}, {8, 0, 16}, {12, 0, 16}, - {16, 0, 16}, {16, 0, 12}, {16, 0, 8}, {16, 0, 4}, - {16, 0, 0}, {16, 4, 0}, {16, 8, 0}, {16, 12, 0}, - {16, 16, 0}, {12, 16, 0}, {8, 16, 0}, {4, 16, 0}, - {0, 16, 0}, {0, 16, 4}, {0, 16, 8}, {0, 16, 12}, - {0, 16, 16}, {0, 12, 16}, {0, 8, 16}, {0, 4, 16}, - /* low intensity, medium saturation */ - {8, 8, 16}, {10, 8, 16}, {12, 8, 16}, {14, 8, 16}, - {16, 8, 16}, {16, 8, 14}, {16, 8, 12}, {16, 8, 10}, - {16, 8, 8}, {16, 10, 8}, {16, 12, 8}, {16, 14, 8}, - {16, 16, 8}, {14, 16, 8}, {12, 16, 8}, {10, 16, 8}, - {8, 16, 8}, {8, 16, 10}, {8, 16, 12}, {8, 16, 14}, - {8, 16, 16}, {8, 14, 16}, {8, 12, 16}, {8, 10, 16}, - /* low intensity, low saturation */ - {11, 11, 16}, {12, 11, 16}, {13, 11, 16}, {15, 11, 16}, - {16, 11, 16}, {16, 11, 15}, {16, 11, 13}, {16, 11, 12}, - {16, 11, 11}, {16, 12, 11}, {16, 13, 11}, {16, 15, 11}, - {16, 16, 11}, {15, 16, 11}, {13, 16, 11}, {12, 16, 11}, - {11, 16, 11}, {11, 16, 12}, {11, 16, 13}, {11, 16, 15}, - {11, 16, 16}, {11, 15, 16}, {11, 13, 16}, {11, 12, 16}, - /* black */ - {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, - {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0} -}; - -/* The Static Functionality Table, a collection of mode-independent status - info. */ -u_int8_t static_functionality_table[] = { - 0x0c, /* Video modes 0 - 7 */ - 0, /* Video modes 8 - 15 */ - 0, /* Video modes 16 - 23 */ - 0, 0, 0, 0, /* reserved */ - 4, /* 400 lines */ - 1, /* Charset memory blocks available */ - 1, /* Charset memory blocks in use */ - 0x79, /* Bit 0: all modes on all displays - 1: grayscale equivalents - 2: user-definable charsets - 3: user-definable palette - 4: CGA cursor emulation - 5: EGA palette - 6: VGA color registers - 7: color pages */ - 0x8, /* Bit 0: lightpen interface - 1: save/load video status - 2: toggle intensity/blink - 3: DCC - 4-7: reserved */ - 0, /* reserved */ - 0, /* Save Pointer functions available - Bit 0: 2 charsets - 1: Palette Save Area - 2: user-defined charset (text) - 3: user-defined charset (graphics) - 4: user-defined palette - 5: DCC - 6, 7: reserved */ - 0 /* reserved */ -}; diff --git a/usr.bin/doscmd/xms.c b/usr.bin/doscmd/xms.c deleted file mode 100644 index 47ea427..0000000 --- a/usr.bin/doscmd/xms.c +++ /dev/null @@ -1,1104 +0,0 @@ -/*- - * Copyright (c) 1997 Helmut Wirth <hfwirth@ping.at> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice immediately at the beginning of the file, witout modification, - * this list of conditions, and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * XMS memory management - * - * To emulate DOS extended memory (EMM) we use an implementation of - * HIMEM.SYS driver capabilities, according to the XMS 3.0 Spec. - * The actual memory allocated via XMS calls from DOS is allocated - * via malloc by the emulator. Maximum memory allocation is configurable. - * - * Credits to: - * The original author of this file, some parts are still here - * Linux dosemu programmers. I looked into their code. - */ - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/mman.h> -#include <unistd.h> - -#include "doscmd.h" -#include "xms.h" - - -/* Extended memory handle management */ - -static XMS_handle xms_hand[NUM_HANDLES]; -int num_free_handle = NUM_HANDLES; - -/* This is planned to be selectable from .doscmdrc */ -u_long xms_maxsize = DEFAULT_EMM_SIZE; -static u_long xms_free_mem; -static u_long xms_used_mem; -static u_char vec_grabbed; - -/* Address entry for zero size allocated handles */ -#define XMS_NULL_ALLOC 0xffffffff - -/* High memory area (HMA) management */ -static u_char HMA_allocated = 0; -static short HMA_a20 = -1; -static int HMA_fd_off, HMA_fd_on; - -/* high memory mapfiles */ -static char memfile[] = "/tmp/doscmd.XXXXXX"; - -/* Upper memory block (UMB) management */ -UMB_block *UMB_freelist = NULL; -UMB_block *UMB_alloclist = NULL; - -/* Calls to emulator */ -u_long xms_vector; -static u_char xms_trampoline[] = { - 0xeb, /* JMP 5 */ - 0x03, - 0x90, /* NOP */ - 0x90, /* NOP */ - 0x90, /* NOP */ - 0xf4, /* HLT */ - 0xcb, /* RETF */ -}; - -/* Local prototypes */ -static void add_block(UMB_block **listp, UMB_block *blk); -static UMB_block *create_block(u_long addr, u_long size); -static void disable_a20(void); -static void enable_a20(void); -static int get_free_handle(void); -static void merge_blocks(void); -static void xms_entry(regcontext_t *REGS); - -/* Init the entire module */ -void -xms_init(void) -{ - /* Initialize handle table: xms_handle.addr == 0 means free */ - bzero((void *)xms_hand, sizeof(XMS_handle) * NUM_HANDLES); - xms_free_mem = xms_maxsize; - xms_used_mem = 0; - vec_grabbed = 0; - HMA_allocated = 0; - /* Initialize UMB blocks */ - /* 0xD0000 to 0xDffff */ - add_block(&UMB_freelist, create_block(0xd0000, 64*1024)); - /*XXX check for EMS emulation, when it is done! */ - /* 0xE0000 to 0xEffff */ - -/* This is used as window for EMS, will be configurable ! */ -/* add_block(&UMB_freelist, create_block(0xe0000, 64*1024)); */ - - merge_blocks(); - - xms_vector = insert_generic_trampoline( - sizeof(xms_trampoline), xms_trampoline); - register_callback(xms_vector + 5, xms_entry, "xms"); -} - -/* - * UMB management routines: UMBs normally lie between 0xd0000 and - * 0xefff0 in VM86 memory space and are accessible for all DOS applications. - * We could enable more space, but with the emulator we do not - * need many drivers, so I think 2 * 64kB will suffice. If EMS emulation - * exists, a 64kB segment (0xe0000 - 0xeffff for example) is needed for - * the EMS mapping, in this case we have 64kB UMB space. This is more than - * many PCs are able to do. - * This emulation does only the management for the memory, the memory - * is present and read/write/executable for VM86 applications. - */ - -/* Add a block to a list, maintain ascending start address order */ - -static void -add_block(UMB_block **listp, UMB_block *blk) -{ - UMB_block *bp, *obp; - - /* No blocks there, attach the new block to the head */ - if (*listp == NULL) { - *listp = blk; - blk->next = NULL; - } else { - /* Insert at the start */ - bp = obp = *listp; - if (blk->addr < bp->addr) { - blk->next = *listp; - *listp = blk; - return; - } - /* Not at the start, insert into the list */ - for (; bp != NULL; bp = bp->next) { - if (blk->addr > bp->addr) { - obp = bp; - continue; - } else { - obp->next = blk; - blk->next = bp; - return; - } - } - /* Append to the end of the list */ - obp->next = blk; - blk->next = NULL; - } - return; -} - -/* Find a block with address addr in the alloc list */ -static UMB_block * -find_allocated_block(u_long addr) -{ - UMB_block *bp; - - if (UMB_alloclist == NULL) - return NULL; - - for (bp = UMB_alloclist; bp != NULL; bp = bp->next) - if (bp->addr == addr) - return bp; - return NULL; -} - -/* Remove a block blk from a list, the block must exist on the list */ -static void -remove_block(UMB_block **listp, UMB_block *blk) -{ - UMB_block *bp; - - if (*listp == NULL) - goto faterr; - - if (*listp == blk) { - *listp = (*listp)->next; - return; - } - bp = *listp; - do { - if (bp->next == blk) { - bp->next = bp->next->next; - return; - } - bp = bp->next; - } while(bp != NULL); -faterr: - fatal("XMS: UMB remove_block did not find block\n"); -} - -/* Try to merge neighbouring blocks in the free list */ -static void -merge_blocks() -{ - UMB_block *bp; - u_long endaddr; - - if (UMB_freelist == NULL) - return; - bp = UMB_freelist; - do { - endaddr = bp->addr + bp->size; - if (bp->next != NULL && endaddr == bp->next->addr) { - /* Merge the current and the next block */ - UMB_block *mergebp = bp->next; - bp->size += mergebp->size; - bp->next = mergebp->next; - free(mergebp); - } else { - /* Goto next block */ - bp = bp->next; - } - } while (bp != NULL); -} - -/* Try to find a free block of size exactly siz */ -static UMB_block * -find_exact_block(u_long siz) -{ - UMB_block *bp; - - if (UMB_freelist == NULL) - return NULL; - - for (bp = UMB_freelist; bp != NULL; bp = bp->next) - if (bp->size == siz) - return bp; - return NULL; -} - -/* Try to find a block with a size bigger than requested. If there is - * no such block, return the block with the biggest size. If there is - * no free block at all, return NULL - */ -static UMB_block * -find_block(u_long siz) -{ - UMB_block *bp; - UMB_block *biggest = NULL; - - if (UMB_freelist == NULL) - return NULL; - - for (bp = UMB_freelist; bp != NULL; bp = bp->next) { - if (bp->size > siz) - return bp; - if (biggest == NULL) { - biggest = bp; - continue; - } - if (biggest->size < bp->size) - biggest = bp; - } - return biggest; -} - -/* Create a block structure, memory is allocated. The structure lives - * until the block is merged into another block, then it is freed */ -static UMB_block * -create_block(u_long addr, u_long size) -{ - UMB_block *blk; - - if ((blk = malloc(sizeof(UMB_block))) == NULL) - fatal ("XMS: Cannot allocate UMB structure\n"); - blk->addr = addr; - blk->size = size; - blk->next = NULL; - return blk; -} - - -/* - * initHMA(): The first 64kB of memory are mapped from 1MB (0x100000) - * again to emulate the address wrap around of the 808x. The HMA area - * is a cheap trick, usable only with 80386 and higher. The 80[345..]86 - * does not have this address wrap around. If more than 1MB is installed - * the processor can address more than 1MB: load 0xFFFF to the segment - * register and using the full offset of 0xffff the resulting highest - * address is (0xffff << 4) + 0xffff = 0x10ffef. Nearly 64kB are accessible - * from real or VM86 mode. The mmap calls emulate the address wrap by - * mapping the lowest 64kB the the first 64kB after the 1MB limit. - * In hardware this is achieved by setting and resetting the a20 bit, - * an ugly compatibility hack: The hardware simlpy clamps the address 20 - * line of the processor to low and hence the wrap around is forced. - * This is switchable via the BIOS or via HIMEM.SYS and therefore the - * first 64kB over 1MB can be enabled or disabled at will by software. - * DOS uses this trick to load itself high, if the memory is present. - * We emulate this behaviour by mapping and unmapping the HMA area. - * (Linux has implemented this feature using shared memory (SHM) calls.) - * - * This routine is called from doscmd.c at startup. A20 is disabled after - * startup. - */ - -void initHMA() -{ - int mfd; - - /* - * We need two files, one for the wrap around mapping and one - * for the HMA contents - */ - - mfd = mkstemp(memfile); - - if (mfd < 0) { - fprintf(stderr, "memfile: %s\n", strerror(errno)); - fprintf(stderr, "High memory will not be mapped\n"); - - /* We need this for XMS services. If it fails, turn HMA off */ - HMA_a20 = -1; - return; - } - unlink(memfile); - HMA_fd_off = squirrel_fd(mfd); - - lseek(HMA_fd_off, 64 * 1024 - 1, 0); - write(HMA_fd_off, "", 1); - - mfd = mkstemp(memfile); - - if (mfd < 0) { - fprintf(stderr, "memfile: %s\n", strerror(errno)); - fprintf(stderr, "High memory will not be mapped\n"); - - /* We need this for XMS services. If it fails, turn HMA off */ - HMA_a20 = -1; - return; - } - unlink(memfile); - HMA_fd_on = squirrel_fd(mfd); - - lseek(HMA_fd_on, 64 * 1024 - 1, 0); - write(HMA_fd_on, "", 1); - - if (mmap((caddr_t)0x000000, 0x100000, - PROT_EXEC | PROT_READ | PROT_WRITE, - MAP_ANON | MAP_FIXED | MAP_SHARED, - -1, 0) == MAP_FAILED) { - perror("Error mapping HMA, HMA disabled: "); - HMA_a20 = -1; - close(HMA_fd_off); - close(HMA_fd_on); - return; - } - if (mmap((caddr_t)0x000000, 64 * 1024, - PROT_EXEC | PROT_READ | PROT_WRITE, - MAP_FILE | MAP_FIXED | MAP_SHARED, - HMA_fd_off, 0) == MAP_FAILED) { - perror("Error mapping HMA, HMA disabled: "); - HMA_a20 = -1; - close(HMA_fd_off); - close(HMA_fd_on); - return; - } - if (mmap((caddr_t)0x100000, 64 * 1024, - PROT_EXEC | PROT_READ | PROT_WRITE, - MAP_FILE | MAP_FIXED | MAP_SHARED, - HMA_fd_off, 0) == MAP_FAILED) { - perror("Error mapping HMA, HMA disabled: "); - HMA_a20 = -1; - close(HMA_fd_off); - close(HMA_fd_on); - return; - } - HMA_a20 = 0; -} - - -/* Enable the a20 "address line" by unmapping the 64kB over 1MB */ -static void enable_a20() -{ - if (HMA_a20 < 0) - return; - - /* Unmap the wrap around portion (fd = HMA_fd_off) */ - /* XXX Not sure about this: Should I unmap first, then map new or - * does it suffice to map new "over' the existing mapping ? Both - * works (define to #if 0 next line and some lines below to try. - */ -#if 1 - if (munmap((caddr_t)0x100000, 64 * 1024) < 0) { - fatal("HMA unmapping error: %s\nCannot recover\n", strerror(errno)); - } -#endif - /* Map memory for the HMA with fd = HMA_fd_on */ - if (mmap((caddr_t)0x100000, 64 * 1024, - PROT_EXEC | PROT_READ | PROT_WRITE, - MAP_FILE | MAP_FIXED | MAP_SHARED, - HMA_fd_on, 0) == MAP_FAILED) { - fatal("HMA mapping error: %s\nCannot recover\n", strerror(errno)); - } -} - -/* Disable the a20 "address line" by mapping the 64kB over 1MB again */ -static void disable_a20() -{ - if (HMA_a20 < 0) - return; -#if 1 - /* Unmap the HMA (fd = HMA_fd_on) */ - if (munmap((caddr_t)0x100000, 64 * 1024) < 0) { - fatal("HMA unmapping error: %s\nCannot recover\n", strerror(errno)); - } -#endif - /* Remap the wrap around area */ - if (mmap((caddr_t)0x100000, 64 * 1024, - PROT_EXEC | PROT_READ | PROT_WRITE, - MAP_FILE | MAP_FIXED | MAP_SHARED, - HMA_fd_off, 0) == MAP_FAILED) { - fatal("HMA mapping error: %s\nCannot recover\n", strerror(errno)); - } -} - - -/* - * This handles calls to int15 function 88: BIOS extended memory - * request. XMS spec says: "In order to maintain compatibility with existing - * device drivers, DOS XMS drivers must not hook INT 15h until the first - * non-Version Number call to the control function is made." - */ - -void -get_raw_extmemory_info(regcontext_t *REGS) -{ - if (vec_grabbed) - R_AX = 0x0; - else - R_AX = xms_maxsize / 1024; - return; -} - - -/* Handle management routine: Find next free handle */ - -static int -get_free_handle() -{ - int i; - /* Linear search, there are only a few handles */ - for (i = 0; i < NUM_HANDLES; i++) { - if (xms_hand[i].addr == 0) - return i + 1; - } - return 0; -} - - -/* Installation check */ -int -int2f_43(regcontext_t *REGS) -{ - - switch (R_AL) { - case 0x00: /* installation check */ - R_AL = 0x80; - break; - - case 0x10: /* get handler address */ - PUTVEC(R_ES, R_BX, xms_vector); - break; - - default: - return (0); - } - return (1); -} - -/* Main call entry point for the XMS handler from DOS */ -static void -xms_entry(regcontext_t *REGS) -{ - - if (R_AH != 0) - vec_grabbed = 1; - - /* If the HMA feature is disabled these calls are "not managed" */ - if (HMA_a20 < 0) { - if (R_AH == XMS_ALLOCATE_HIGH_MEMORY || R_AH == XMS_FREE_HIGH_MEMORY || - R_AH == XMS_GLOBAL_ENABLE_A20 || R_AH == XMS_GLOBAL_DISABLE_A20 || - R_AH == XMS_LOCAL_ENABLE_A20 || R_AH == XMS_LOCAL_DISABLE_A20 || - R_AH == XMS_QUERY_A20) { - R_AX = 0x0; - R_BL = XMS_HMA_NOT_MANAGED; - return; - } - } - - switch (R_AH) { - case XMS_GET_VERSION: - debug(D_XMS, "XMS: Get Version\n"); - R_AX = XMS_VERSION; /* 3.0 */ - R_BX = XMS_REVISION; /* internal revision 0 */ - R_DX = (HMA_a20 < 0) ? 0x0000 : 0x0001; - break; - - /* - * XXX Not exact! Spec says compare size to a HMAMIN parameter and - * refuse HMA, if space is too small. With MSDOS 5.0 and higher DOS - * itself uses the HMA (DOS=HIGH), so I think we can safely ignore - * that. - */ - case XMS_ALLOCATE_HIGH_MEMORY: - debug(D_XMS, "XMS: Allocate HMA\n"); - if (HMA_allocated) { - R_AX = 0x0; - R_BL = XMS_HMA_ALREADY_USED; - } else { - HMA_allocated = 1; - R_AX = 0x1; - R_BL = XMS_SUCCESS; - } - break; - - case XMS_FREE_HIGH_MEMORY: - debug(D_XMS, "XMS: Free HMA\n"); - if (HMA_allocated) { - HMA_allocated = 0; - R_AX = 0x1; - R_BL = XMS_SUCCESS; - } else { - R_AX = 0x0; - R_BL = XMS_HMA_NOT_ALLOCATED; - } - break; - - case XMS_GLOBAL_ENABLE_A20: - debug(D_XMS, "XMS: Global enable A20\n"); - if (HMA_a20 == 0) - enable_a20(); - HMA_a20 = 1; - R_AX = 0x1; - R_BL = XMS_SUCCESS; - break; - - case XMS_GLOBAL_DISABLE_A20: - debug(D_XMS, "XMS: Global disable A20\n"); - if (HMA_a20 != 0) - disable_a20(); - HMA_a20 = 0; - R_AX = 0x1; - R_BL = XMS_SUCCESS; - break; - - /* - * This is an accumulating call. Every call increments HMA_a20. - * Caller must use LOCAL_DISBALE_A20 once for each previous call - * to LOCAL_ENABLE_A20. - */ - case XMS_LOCAL_ENABLE_A20: - debug(D_XMS, "XMS: Local enable A20\n"); - HMA_a20++; - if (HMA_a20 == 1) - enable_a20(); - R_AX = 0x1; - R_BL = XMS_SUCCESS; - break; - - case XMS_LOCAL_DISABLE_A20: - debug(D_XMS, "XMS: Local disable A20\n"); - if (HMA_a20 > 0) - HMA_a20--; - if (HMA_a20 == 0) - disable_a20(); - R_AX = 0x1; - R_BL = XMS_SUCCESS; - break; - - case XMS_QUERY_A20: - /* - * Disabled because DOS permanently scans this, to avoid endless output. - */ -#if 0 - debug(D_XMS, "XMS: Query A20\n"); */ -#endif - R_AX = (HMA_a20 > 0) ? 0x1 : 0x0; - R_BL = XMS_SUCCESS; - break; - - case XMS_QUERY_FREE_EXTENDED_MEMORY: - /* DOS MEM.EXE chokes, if the HMA is enabled and the reported - * free space includes the HMA. So we subtract 64kB from the - * space reported, if the HMA is enabled. - */ - if (HMA_a20 < 0) - R_EAX = R_EDX = xms_free_mem / 1024; - else - R_EAX = R_EDX = (xms_free_mem / 1024) - 64; - - if (xms_free_mem == 0) - R_BL = XMS_FULL; - else - R_BL = XMS_SUCCESS; - debug(D_XMS, "XMS: Query free EMM: Returned %dkB\n", R_AX); - break; - - case XMS_ALLOCATE_EXTENDED_MEMORY: - { - size_t req_siz; - int hindx, hnum; - void *mem; - - debug(D_XMS, "XMS: Allocate EMM: "); - /* Enough handles ? */ - if ((hnum = get_free_handle()) == 0) { - R_AX = 0x00; - R_BL = XMS_OUT_OF_HANDLES; - debug(D_XMS, " Out of handles\n"); - break; - } - hindx = hnum - 1; - req_siz = R_DX * 1024; - - /* Enough memory ? */ - if (req_siz > xms_free_mem) { - R_AX = 0x00; - R_BL = XMS_FULL; - debug(D_XMS, " No memory left\n"); - break; - } - - xms_hand[hindx].size = req_siz; - xms_hand[hindx].num_locks = 0; - - /* XXX - * Not sure about that: Is it possible to reserve a handle - * but with no memory attached ? XMS specs are unclear on - * that point. Linux implementation does it this way. - */ - if (req_siz == 0) { - /* This handle is reserved, but has size 0 and no address */ - xms_hand[hindx].addr = XMS_NULL_ALLOC; - } else { - if ((mem = malloc(req_siz)) == NULL) - fatal("XMS: Cannot malloc !"); - xms_hand[hindx].addr = (u_long)mem; - } - xms_free_mem -= req_siz; - xms_used_mem += req_siz; - num_free_handle--; - R_AX = 0x1; - R_DX = hnum; - R_BL = XMS_SUCCESS; - debug(D_XMS, " Allocated %d kB, handle %d\n", - req_siz / 1024, hnum); - break; - } - - case XMS_FREE_EXTENDED_MEMORY: - { - int hnum, hindx; - - debug(D_XMS, "XMS: Free EMM: "); - hnum = R_DX; - if (hnum > NUM_HANDLES || hnum == 0) { - R_AX = 0x0; - R_BL = XMS_INVALID_HANDLE; - debug(D_XMS, " Invalid handle\n"); - break; - } - hindx = hnum - 1; - - if (xms_hand[hindx].addr == 0) { - R_AX = 0x0; - R_BL = XMS_INVALID_HANDLE; - debug(D_XMS, " Invalid handle\n"); - - } else if (xms_hand[hindx].num_locks > 0) { - R_AX = 0x0; - R_BL = XMS_BLOCK_IS_LOCKED; - debug(D_XMS, " Is locked\n"); - - } else { - if (xms_hand[hindx].addr != XMS_NULL_ALLOC) { - free((void *)xms_hand[hindx].addr); - xms_free_mem += xms_hand[hindx].size; - xms_used_mem -= xms_hand[hindx].size; - } - xms_hand[hindx].addr = 0; - xms_hand[hindx].size = 0; - xms_hand[hindx].num_locks = 0; - num_free_handle++; - debug(D_XMS, " Success for handle %d\n", hnum); - R_AX = 0x1; - R_BL = XMS_SUCCESS; - } - break; - } - - case XMS_MOVE_EXTENDED_MEMORY_BLOCK: - { - u_long srcptr, dstptr; - u_long srcoffs, dstoffs; - int srcidx, dstidx; - const struct EMM *eptr; - int n; - - debug(D_XMS, "XMS: Move EMM block: "); - eptr = (struct EMM *)MAKEPTR(R_DS, R_SI); - - /* Sanity check: Don't allow eptr pointing to emulator data */ - if (((u_long)eptr + sizeof(struct EMM)) >= 0x100000) { - R_AX = 0x0; - R_BL = XMS_GENERAL_ERROR; - debug(D_XMS, " Offset to EMM structure wrong\n"); - break; - } - - /* Validate handles and offsets */ - - if (eptr->src_handle > NUM_HANDLES) { - R_AX = 0x0; - R_BL = XMS_INVALID_SOURCE_HANDLE; - debug(D_XMS, " Invalid handle\n"); - break; - } - if (eptr->dst_handle > NUM_HANDLES) { - R_AX = 0x0; - R_BL = XMS_INVALID_DESTINATION_HANDLE; - debug(D_XMS, " Invalid handle\n"); - break; - } - srcidx = eptr->src_handle - 1; - dstidx = eptr->dst_handle - 1; - srcoffs = eptr->src_offset; - dstoffs = eptr->dst_offset; - n = eptr->nbytes; - /* Length must be even, see XMS spec */ - if (n & 1) { - R_AX = 0x0; - R_BL = XMS_INVALID_LENGTH; - debug(D_XMS, " Length not even\n"); - break; - } - if (eptr->src_handle != 0) { - srcptr = xms_hand[srcidx].addr; - if (srcptr == 0 || srcptr == XMS_NULL_ALLOC) { - R_AX = 0x0; - R_BL = XMS_INVALID_SOURCE_HANDLE; - debug(D_XMS, " Invalid source handle\n"); - break; - } - if ((srcoffs + n) > xms_hand[srcidx].size) { - R_AX = 0x0; - R_BL = XMS_INVALID_SOURCE_OFFSET; - debug(D_XMS, " Invalid source offset\n"); - break; - } - srcptr += srcoffs; - } else { - srcptr = VECPTR(srcoffs); - /* Sanity check: Don't allow srcptr pointing to - * emulator data above 1M - */ - if ((srcptr + n) >= 0x100000) { - R_AX = 0x0; - R_BL = XMS_GENERAL_ERROR; - debug(D_XMS, " Source segment invalid\n"); - break; - } - } - - if (eptr->dst_handle != 0) { - dstptr = xms_hand[dstidx].addr; - if (dstptr == 0 || dstptr == XMS_NULL_ALLOC) { - R_AX = 0x0; - R_BL = XMS_INVALID_DESTINATION_HANDLE; - debug(D_XMS, " Invalid dest handle\n"); - break; - } - if ((dstoffs + n) > xms_hand[dstidx].size) { - R_AX = 0x0; - R_BL = XMS_INVALID_DESTINATION_OFFSET; - debug(D_XMS, " Invalid dest offset\n"); - break; - } - dstptr += dstoffs; - } else { - dstptr = VECPTR(dstoffs); - /* Sanity check: Don't allow dstptr pointing to - * emulator data above 1M - */ - if ((dstptr + n) >= 0x100000) { - R_AX = 0x0; - R_BL = XMS_GENERAL_ERROR; - debug(D_XMS, " Dest segment invalid\n"); - break; - } - } - memmove((void *)dstptr, (void *)srcptr, n); - debug(D_XMS, "Moved from %08lx to %08lx, %04x bytes\n", - srcptr, dstptr, n); - R_AX = 0x1; - R_BL = XMS_SUCCESS; - break; - } - - case XMS_LOCK_EXTENDED_MEMORY_BLOCK: - { - int hnum,hindx; - - debug(D_XMS, "XMS: Lock EMM block\n"); - hnum = R_DX; - if (hnum > NUM_HANDLES || hnum == 0) { - R_AX = 0x0; - R_BL = XMS_INVALID_HANDLE; - break; - } - hindx = hnum - 1; - if (xms_hand[hindx].addr == 0) { - R_AX = 0x0; - R_BL = XMS_INVALID_HANDLE; - break; - } - if (xms_hand[hindx].num_locks == 255) { - R_AX = 0x0; - R_BL = XMS_BLOCK_LOCKCOUNT_OVERFLOW; - break; - } - xms_hand[hindx].num_locks++; - R_AX = 0x1; - /* - * The 32 bit "physical" address is returned here. I hope - * the solution to simply return the linear address of the - * malloced area is good enough. Most DOS programs won't - * need this anyway. It could be important for future DPMI. - */ - R_BX = xms_hand[hindx].addr & 0xffff; - R_DX = (xms_hand[hindx].addr & 0xffff0000) >> 16; - break; - } - - case XMS_UNLOCK_EXTENDED_MEMORY_BLOCK: - { - int hnum,hindx; - - debug(D_XMS, "XMS: Unlock EMM block\n"); - hnum = R_DX; - if (hnum > NUM_HANDLES || hnum == 0) { - R_AX = 0x0; - R_BL = XMS_INVALID_HANDLE; - break; - } - hindx = hnum - 1; - if (xms_hand[hindx].addr == 0) { - R_AX = 0x0; - R_BL = XMS_INVALID_HANDLE; - break; - } - if (xms_hand[hindx].num_locks == 0) { - R_AX = 0x0; - R_BL = XMS_BLOCK_NOT_LOCKED; - break; - } - xms_hand[hindx].num_locks--; - R_AX = 0x1; - R_BL = XMS_SUCCESS; - break; - } - - case XMS_GET_EMB_HANDLE_INFORMATION: - { - int hnum,hindx; - - debug(D_XMS, "XMS: Get handle information: DX=%04x\n", R_DX); - hnum = R_DX; - if (hnum > NUM_HANDLES || hnum == 0) { - R_AX = 0x0; - R_BL = XMS_INVALID_HANDLE; - break; - } - hindx = hnum - 1; - if (xms_hand[hindx].addr == 0) { - R_AX = 0x0; - R_BL = XMS_INVALID_HANDLE; - break; - } - R_AX = 0x1; - R_BH = xms_hand[hindx].num_locks; - R_BL = num_free_handle; - R_DX = xms_hand[hindx].size / 1024; - break; - } - - case XMS_RESIZE_EXTENDED_MEMORY_BLOCK: - { - int hnum,hindx; - size_t req_siz; - long sizediff; - void *mem; - - debug(D_XMS, "XMS: Resize EMM block\n"); - hnum = R_DX; - req_siz = R_BX * 1024; - if (hnum > NUM_HANDLES || hnum == 0) { - R_AX = 0x0; - R_BL = XMS_INVALID_HANDLE; - break; - } - hindx = hnum - 1; - if (xms_hand[hindx].addr == 0) { - R_AX = 0x0; - R_BL = XMS_INVALID_HANDLE; - break; - } - if (xms_hand[hindx].num_locks > 0) { - R_AX = 0x0; - R_BL = XMS_BLOCK_IS_LOCKED; - break; - } - sizediff = req_siz - xms_hand[hindx].size; - - if (sizediff > 0) { - if ((sizediff + xms_used_mem) > xms_maxsize) { - R_AX = 0x0; - R_BL = XMS_FULL; - break; - } - } - - if (sizediff == 0) { /* Never trust DOS programs */ - R_AX = 0x1; - R_BL = XMS_SUCCESS; - break; - } - - xms_used_mem += sizediff; - xms_free_mem -= sizediff; - - if (xms_hand[hindx].addr == XMS_NULL_ALLOC) { - if ((mem = malloc(req_siz)) == NULL) - fatal("XMS: Cannot malloc !"); - xms_hand[hindx].addr = (u_long)mem; - xms_hand[hindx].size = req_siz; - } else { - if ((mem = realloc((void *)xms_hand[hindx].addr,req_siz)) - == NULL) - fatal("XMS: Cannot realloc !"); - xms_hand[hindx].addr = (u_long)mem; - xms_hand[hindx].size = req_siz; - } - - R_AX = 0x1; - R_BL = XMS_SUCCESS; - break; - } - - case XMS_ALLOCATE_UMB: - { - u_long req_siz; - UMB_block *bp; - - debug(D_XMS, "XMS: Allocate UMB: DX=%04x\n", R_DX); - req_siz = R_DX * 16; - /* Some programs try to allocate 0 bytes. XMS spec says - * nothing about this. So the driver grants the request - * but it rounds up to the next paragraph size (1) and - * returns this amount of memory - */ - if (req_siz == 0) - req_siz = 0x10; - - /* First try to find an exact fit */ - if ((bp = find_exact_block(req_siz)) != NULL) { - /* Found ! Move block from free list to alloc list */ - remove_block(&UMB_freelist, bp); - add_block(&UMB_alloclist, bp); - R_AX = 0x1; - R_DX = req_siz >> 4; - R_BX = bp->addr >> 4; - break; - } - /* Try to find a block big enough */ - bp = find_block(req_siz); - if (bp == NULL) { - R_AX = 0x0; - R_BL = XMS_NO_UMBS_AVAILABLE; - R_DX = 0x0; - - } else if (bp->size < req_siz) { - R_AX = 0x0; - R_BL = XMS_REQUESTED_UMB_TOO_BIG; - R_DX = bp->size / 16; - - } else { - UMB_block *newbp; - /* Found a block large enough. Split it into the size - * we need, rest remains on the free list. New block - * goes to the alloc list - */ - newbp = create_block(bp->addr, req_siz); - bp->addr += req_siz; - bp->size -= req_siz; - add_block(&UMB_alloclist, newbp); - R_AX = 0x1; - R_BX = newbp->addr >> 4; - R_DX = req_siz / 16; - } - break; - } - - case XMS_DEALLOCATE_UMB: - { - u_long req_addr; - UMB_block *blk; - - debug(D_XMS, "XMS: Deallocate UMB: DX=%04x\n", R_DX); - req_addr = R_DX << 4; - if ((blk = find_allocated_block(req_addr)) == NULL) { - R_AX = 0x0; - R_BL = XMS_INVALID_UMB_SEGMENT; - } else { - /* Move the block from the alloc list to the free list - * and try to do garbage collection - */ - remove_block(&UMB_alloclist, blk); - add_block(&UMB_freelist, blk); - merge_blocks(); - R_AX = 0x1; - R_BL = XMS_SUCCESS; - } - break; - } - - - /* - * If the option DOS=UMB is enabled, DOS grabs the entire UMB - * at boot time. In any other case this is used to load resident - * utilities. I don't think this function is neccesary here. - */ - case XMS_REALLOCATE_UMB: - debug(D_XMS, "XMS: Reallocate UMB\n"); - R_AX = 0x0; - R_BL = XMS_NOT_IMPLEMENTED; - break; - - /* Some test programs use this call */ - case XMS_QUERY_FREE_EXTENDED_MEMORY_LARGE: - /* DOS MEM.EXE chokes, if the HMA is enabled and the reported - * free space includes the HMA. So we subtract 64kB from the - * space reported, if the HMA is enabled. - */ - if (HMA_a20 < 0) - R_EAX = R_EDX = xms_free_mem / 1024; - else - R_EAX = R_EDX = (xms_free_mem / 1024) - 64; - /* ECX should return the highest address of any memory block - * We return 1MB + size of extended memory - */ - R_ECX = 1024 * 1024 + xms_maxsize -1; - if (xms_free_mem == 0) - R_BL = XMS_FULL; - else - R_BL = XMS_SUCCESS; - debug(D_XMS, "XMS: Query free EMM(large): Returned %dkB\n", R_AX); - break; - - /* These are the same as the above functions, but they use 32 bit - * registers (i.e. EDX instead of DX). This is for allocations of - * more than 64MB. I think this will hardly be used in the emulator - * It seems to work without them, but the functions are in the XMS 3.0 - * spec. If something breaks because they are not here, I can implement - * them - */ - case XMS_ALLOCATE_EXTENDED_MEMORY_LARGE: - case XMS_FREE_EXTENDED_MEMORY_LARGE: - debug(D_XMS, "XMS: %02x function called, not implemented\n", R_AH); - R_AX = 0x0; - R_BL = XMS_NOT_IMPLEMENTED; - break; - - default: - debug(D_ALWAYS, "XMS: Unimplemented function %02x, \n", R_AH); - R_AX = 0; - R_BL = XMS_NOT_IMPLEMENTED; - break; - } -} diff --git a/usr.bin/doscmd/xms.h b/usr.bin/doscmd/xms.h deleted file mode 100644 index 477fd84..0000000 --- a/usr.bin/doscmd/xms.h +++ /dev/null @@ -1,145 +0,0 @@ -/*- - * Copyright (c) 1997 Helmut Wirth <hfwirth@ping.at> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice immediately at the beginning of the file, witout modification, - * this list of conditions, and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef XMS_H -#define XMS_H - -#define XMS_VERSION 0x0300 /* version 3.00 */ -#define XMS_REVISION 0x0100 /* driver revision 1.0 */ - -#define NUM_HANDLES 64 /* number of available handles */ -#define FIRST_HANDLE 1 /* number of first valid handle */ -#define PARAGRAPH 16 /* bytes in a paragraph */ -#define MAX_BLOCK_LOCKS 256 /* number of locks on a block */ -#define DEFAULT_EMM_SIZE 512 * 1024 /* default EMM size */ - -/* Register AH codes for XMS functions */ -#define XMS_GET_VERSION 0x00 -#define XMS_ALLOCATE_HIGH_MEMORY 0x01 -#define XMS_FREE_HIGH_MEMORY 0x02 -#define XMS_GLOBAL_ENABLE_A20 0x03 -#define XMS_GLOBAL_DISABLE_A20 0x04 -#define XMS_LOCAL_ENABLE_A20 0x05 -#define XMS_LOCAL_DISABLE_A20 0x06 -#define XMS_QUERY_A20 0x07 -#define XMS_QUERY_FREE_EXTENDED_MEMORY 0x08 -#define XMS_ALLOCATE_EXTENDED_MEMORY 0x09 -#define XMS_FREE_EXTENDED_MEMORY 0x0a -#define XMS_MOVE_EXTENDED_MEMORY_BLOCK 0x0b -#define XMS_LOCK_EXTENDED_MEMORY_BLOCK 0x0c -#define XMS_UNLOCK_EXTENDED_MEMORY_BLOCK 0x0d -#define XMS_GET_EMB_HANDLE_INFORMATION 0x0e -#define XMS_RESIZE_EXTENDED_MEMORY_BLOCK 0x0f -#define XMS_ALLOCATE_UMB 0x10 -#define XMS_DEALLOCATE_UMB 0x11 -#define XMS_REALLOCATE_UMB 0x12 -/* New functions for values bigger than 65MB, not implanted yet */ -#define XMS_QUERY_FREE_EXTENDED_MEMORY_LARGE 0x88 -#define XMS_ALLOCATE_EXTENDED_MEMORY_LARGE 0x89 -#define XMS_FREE_EXTENDED_MEMORY_LARGE 0x8a - - -/* XMS error return codes */ -#define XMS_SUCCESS 0x0 -#define XMS_NOT_IMPLEMENTED 0x80 -#define XMS_VDISK 0x81 /* If vdisk.sys is present */ -#define XMS_A20_ERROR 0x82 -#define XMS_GENERAL_ERROR 0x8e -#define XMS_HMA_NOT_MANAGED 0x90 -#define XMS_HMA_ALREADY_USED 0x91 -#define XMS_HMA_NOT_ALLOCATED 0x93 -#define XMS_A20_STILL_ENABLED 0x94 -#define XMS_FULL 0xa0 -#define XMS_OUT_OF_HANDLES 0xa1 -#define XMS_INVALID_HANDLE 0xa2 -#define XMS_INVALID_SOURCE_HANDLE 0xa3 -#define XMS_INVALID_SOURCE_OFFSET 0xa4 -#define XMS_INVALID_DESTINATION_HANDLE 0xa5 -#define XMS_INVALID_DESTINATION_OFFSET 0xa6 -#define XMS_INVALID_LENGTH 0xa7 -#define XMS_BLOCK_NOT_LOCKED 0xaa -#define XMS_BLOCK_IS_LOCKED 0xab -#define XMS_BLOCK_LOCKCOUNT_OVERFLOW 0xac -#define XMS_REQUESTED_UMB_TOO_BIG 0xb0 -#define XMS_NO_UMBS_AVAILABLE 0xb1 -#define XMS_INVALID_UMB_SEGMENT 0xb2 - - -/* - * EMM structure for data exchange with DOS caller, hence the - * packed format - */ - -struct EMM { - u_long nbytes; - u_short src_handle __attribute__ ((packed)); - u_long src_offset __attribute__ ((packed)); - u_short dst_handle __attribute__ ((packed)); - u_long dst_offset __attribute__ ((packed)); -} ; - -/* - * XMS info structure, only used to pass information to and from - * DOS - */ - -struct XMSinfo { - u_char handle; /* the handle */ - u_char num_locks __attribute__ ((packed)); /* number of locks */ - u_long size __attribute__ ((packed)); /* size of memory */ - u_long phys_addr __attribute__ ((packed)); /* "physical" address */ -}; - -/* - * Handle management inside the emulator for extended memory pages, - * invisible to DOS - */ - -typedef struct { - u_long addr; /* address inside emulator, from malloc() */ - u_long size; /* size in bytes */ - u_char num_locks; /* lock count for this handle */ -} XMS_handle; - -/* - * Management of UMB memory paragraphs (16 bytes). UMB blocks are - * directly accessible by VM86 applications and lie between 0xd0000 and - * 0xefff0 in VM86 memory space. - */ - -struct _UMB_block { - u_long addr; /* Start address of block */ - u_long size; /* Size in bytes */ - struct _UMB_block *next; -}; - -typedef struct _UMB_block UMB_block; - -#endif /* XMS_H */ |