Remove doscmd from the base system now that it lives in the ports tree.

This commit is contained in:
Dag-Erling Smørgrav 2004-03-23 22:27:24 +00:00
parent dde5634ff5
commit 6ae3893bf3
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=127340
70 changed files with 0 additions and 25635 deletions

View File

@ -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

View File

@ -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.
*/
}

View File

@ -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)

View File

@ -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>

View File

@ -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}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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".

View File

@ -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");
}

View File

@ -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));
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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 */

View File

@ -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);
}

View File

@ -1,113 +0,0 @@
$FreeBSD$
begin 644 cp437-8x14.pcf.gz
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
8/CR)#Z_*3G)5^.G]#>&?`*T-&*=$6@``
`
end

View File

@ -1,113 +0,0 @@
$FreeBSD$
begin 644 cp437-8x16.pcf.gz
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
A>!(?GL2')_'A27QXK7:2:Y7SZW/Q_Q#X7P&*JEP88@``
`
end

View File

@ -1,104 +0,0 @@
$FreeBSD$
begin 644 cp437-8x8.pcf.gz
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
6^(@Z=)+K`/[7_A\"WP<A_#T,0$(``)/X
`
end

View File

@ -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;
}

View File

@ -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));
}

View File

@ -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);
}

View File

@ -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 *);

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);
}

File diff suppressed because it is too large Load Diff

View File

@ -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);

View File

@ -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 .

View File

@ -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);
}

View File

@ -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;

View File

@ -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???");
}

File diff suppressed because it is too large Load Diff

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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;
}
}

View File

@ -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 */

View File

@ -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 */
}

View File

@ -1,4 +0,0 @@
3
cp437-8x8.pcf.gz vga8x8
cp437-8x14.pcf.gz vga8x14
cp437-8x16.pcf.gz vga8x16

File diff suppressed because it is too large Load Diff

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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 */

View File

@ -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;
}

View File

@ -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;

View File

@ -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");
}

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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 *)&REGS->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 *)&REGS->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);
}

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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 *);

View File

@ -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;
}

View File

@ -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 *);

View File

@ -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 */
};

File diff suppressed because it is too large Load Diff

View File

@ -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 */