1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-25 11:37:56 +00:00

Add our doscmd to the tree. This is a result of work from BSDI, and

a group of dos emulator developers.
Submitted by:	Jonathan Lemon <jlemon@americantv.com>
Obtained from:	BSDI
This commit is contained in:
John Dyson 1997-08-09 01:43:15 +00:00
parent a98421fc82
commit 90c38ed200
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=27999
53 changed files with 18766 additions and 0 deletions

342
usr.bin/doscmd/AsyncIO.c Normal file
View File

@ -0,0 +1,342 @@
/*
* 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 <stdio.h>
#include <sys/param.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/time.h>
#include <signal.h>
#include <errno.h>
#include <limits.h>
#include "doscmd.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 = { 0 }; /* File Descriptors to select on */
typedef struct {
void (*func)(void *, REGISTERS);
/* Function to call when data arrives */
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 HandleIO (struct sigframe *sf);
static int in_handler = 0;
void
_RegisterIO(fd, func, arg, failure)
int fd;
void (*func)();
void *arg;
void (*failure)();
{
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) {
struct sigaction sa;
firsttime = 0;
setsignal(SIGIO, HandleIO);
}
if (handlers[fd].func = func) {
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 = { 0 };
/*
* 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 *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)
{
++in_handler;
for (;;) {
static struct timeval tv = { 0 };
fd_set readset;
int x;
int fd;
readset = fdset;
if ((x = select(FD_SETSIZE, &readset, 0, 0, &tv)) < 0) {
/*
* If we failed becuase 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))
break;
continue;
}
perror("select");
break;
}
/*
* If we run out of fds to look at, break out of the loop
* and exit the handler.
*/
if (!x)
break;
/*
* 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;
if (!FD_ISSET(fd, &readset)) {
continue;
}
--x;
/*
* Is suppose it is possible that one of the previous
* io 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) {
int afd;
Async *aas;
/*
* STEP 1: Lock out all "members"
*/
aas = handlers;
if (0)
for (afd = 0; afd < OPEN_MAX; ++afd, ++aas) {
if (FD_ISSET(afd, &as->members)) {
if (aas->func) {
if (as->lockcnt++ == 0) {
FD_CLR(afd, &fdset);
CLRASYNC(afd);
}
}
}
}
/*
* STEP 2: Renable SIGIO so other FDs can
* use a hit.
_UnblockIO();
*/
/*
* STEP 3: Call the handler
*/
(*handlers[fd].func)(handlers[fd].arg, &sf->sf_sc);
/*
* STEP 4: Just turn SIGIO off. No check.
_BlockIO();
*/
/*
* STEP 5: Unlock all "members"
*/
aas = handlers;
if (0)
for (afd = 0; afd < OPEN_MAX; ++afd, ++aas) {
if (FD_ISSET(afd, &as->members)) {
if (aas->func) {
if (--as->lockcnt == 0) {
FD_SET(afd, &fdset);
SETASYNC(afd);
}
}
}
}
} 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.
*/
if (x) {
break;
}
}
--in_handler;
}
static int stackp = 0;
void
_BlockIO()
{
sigset_t set;
if (stackp >= 64) {
fprintf(stderr, "Signal stack count too deep\n");
abort();
}
if (stackp++ == 0) {
sigaddset(&set, SIGIO);
sigprocmask(SIG_BLOCK, &set, 0);
}
}
void
_UnblockIO()
{
sigset_t set;
if (stackp <= 0) {
fprintf(stderr, "Negative signal stack count\n");
abort();
}
if (--stackp == 0) {
sigaddset(&set, SIGIO);
sigprocmask(SIG_UNBLOCK, &set, 0);
}
}

50
usr.bin/doscmd/AsyncIO.h Normal file
View File

@ -0,0 +1,50 @@
/*
* 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
*/
#if defined(__cplusplus)
extern "C" {
#endif
void _RegisterIO(int, void (*)(void *), void *, void (*)());
void _AssociateIO(int, int);
void _DeAssociateIO(int, int);
void _LockIO(int);
int _UnlockIO(int);
int _LevelIO(int);
int _DetachIO(int);
int _EndIO(int, int);
void _BlockIO(void);
void _UnblockIO(void);
#if defined(__cplusplus)
}
#endif
#define _Un_RegisterIO(x) _RegisterIO((x), (void (*))0, (void *)0, (void (*))0)

21
usr.bin/doscmd/PROBLEMS Normal file
View File

@ -0,0 +1,21 @@
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

@ -0,0 +1,89 @@
/*
* 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
*
* $Id: ParseBuffer.c,v 1.2 1996/09/22 05:52:53 miff Exp $
*/
#include <stdlib.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);
}

37
usr.bin/doscmd/README Normal file
View File

@ -0,0 +1,37 @@
/* BSDI README,v 2.2 1996/04/08 19:32:16 bostic Exp*/
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 xms/ems support (yet)
* No raw VGA support (yet)
* Printer support (yet)
* COM ports (being worked on)
* redirected file system only supported for DOS 4.0 and above
(3.3 will be supported in a future version)
* Graphics in an X window (not planned to work)
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

@ -0,0 +1,89 @@
/* BSDI README.booting_dos,v 2.2 1996/04/08 19:32:18 bostic Exp*/
To install DOS on a pseudo hard disk under doscmd:
1) Create a .doscmdrc with at least the following:
assign A: /dev/rfd0_1440_3.5 1440
assign A: /dev/rfd0_720_3.5 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 instbsdi.exe onto the floppy by either mounting it
with the msdos file system type or by using mtools.
(i.e. mwrite instbsdi.exe 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
instbsdi.exe
^Z
16) Quit doscmd.
17) You know have a bootable pseudo disk which will automatically call
the magic "instbsdi" program, which installs BSDI disks. To use
them add lines to your .doscmdrc such as:
assign D: /usr/dos
assign P: -ro /usr/prb
Not ethat you will not always be able to access every file due to
naming problems.

329
usr.bin/doscmd/bios.c Normal file
View File

@ -0,0 +1,329 @@
/*
* 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
*
* $Id: bios.c,v 1.4 1996/09/22 15:42:47 miff Exp $
*/
#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 video_parms[] = {
0x38, 40, 0x2d, 10, 0x1f, 6, 0x19, 0x1c, 2, 7, 6, 7, 0, 0, 0, 0,
0x71, 80, 0x5a, 10, 0x1f, 6, 0x19, 0x1c, 2, 7, 6, 7, 0, 0, 0, 0,
0x38, 40, 0x2d, 10, 0x7f, 6, 0x64, 0x70, 2, 1, 6, 7, 0, 0, 0, 0,
0x61, 80, 0x52, 15, 0x19, 6, 0x19, 0x19, 2, 13, 11, 12, 0, 0, 0, 0,
};
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)
{
int cond;
int count;
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:
/*
* XXX - Check scan code in GET8L(sc->sc_eax).
*/
break;
case 0x88:
R_AX = 0; /* memory past 1M */
break;
case 0xc0: /* get configuration */
debug (D_TRAPS|0x15, "Get configuration\n", R_DX);
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 */
R_FLAGS |= PSL_C;
R_AH = 5; /* No pointer */
break;
default:
unknown_int2(0x15, R_AX, REGS);
break;
}
}
extern void int16(regcontext_t *REGS);
extern void int17(regcontext_t *REGS);
extern void int1a(regcontext_t *REGS);
void
bios_init(void)
{
int i, j, k;
u_char *jtab;
struct timeval tv;
struct timezone tz;
struct tm tm;
u_long vec;
if (1 || !raw_kbd) {
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_video_parms, video_parms, sizeof(video_parms));
*/
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';
#if 0
*(u_char *)BIOS_hardware_id = 0xfe; /* Identify as a PC/XT */
*(u_char *)BIOS_hardware_id = 0xff; /* Identify as a PC */
#endif
*(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);
tm = *localtime(&tv.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");
}

120
usr.bin/doscmd/callback.c Normal file
View File

@ -0,0 +1,120 @@
/* No copyright?!
**
** $Id: callback.c,v 1.3 1996/09/24 00:02:25 miff Exp $
*/
#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;
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, 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)];
for (elm = head->lh_first; elm; elm = elm->chain.le_next)
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));
}

13
usr.bin/doscmd/callback.h Normal file
View File

@ -0,0 +1,13 @@
/*
** No copyright?!
**
** $Id: callback.h,v 1.4 1996/09/22 15:42:48 miff Exp $
*/
typedef void (*callback_t)(regcontext_t *REGS);
extern void register_callback(u_long vec, callback_t func, char *name);
extern callback_t find_callback(u_long vec);
extern u_long insert_generic_trampoline(size_t len, u_char *p);
extern u_long insert_softint_trampoline(void);
extern u_long insert_hardint_trampoline(void);
extern u_long insert_null_trampoline(void);

291
usr.bin/doscmd/cmos.c Normal file
View File

@ -0,0 +1,291 @@
/*
* 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
*
* $Id: cmos.c,v 1.2 1996/09/18 16:12:24 miff Exp $
*/
#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 int fast_delta_uclock;
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 (mon, 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);
}

167
usr.bin/doscmd/com.h Normal file
View File

@ -0,0 +1,167 @@
/*
* 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
*
* $Id: com.h,v 1.3 1996/09/22 15:42:48 miff Exp $
*/
/* com.h for doscmd int14.c */
#define BUFSIZE 1024
/* 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 0x38 /* not used */
#define II_INT_ID 0x06 /* mask: bits see below */
#define II_PEND_INT 0x01 /* 1=no interrupt pending */
/* bit masks for II_INT_ID */
#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_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_SHFT_E 0x40 /* 0=data transfer, 1=transmitter idle */
#define LS_X_HOLD_E 0x20 /* 0=ready, 1=transferring character */
#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 */
/* data structure definitions */
#define N_OF_COM_REGS 8
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 flags; /* some general software flags */
struct queue *com_queue; /* XXX DEBUG obsolete MCL? */
unsigned char div_latch[2]; /* mirror of 16550 R0':R1' read/write */
unsigned char last_char_read; /* mirror of 16550 R0 read only */
unsigned char int_enable; /* mirror of 16550 R1 read/write */
unsigned char int_id; /* mirror of 16550 R2 read only */
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 line_stat; /* mirror of 16550 R5 read/write */
unsigned char modem_stat; /* mirror of 16550 R6 read/write */
unsigned char uart_spare; /* mirror of 16550 R7 read/write */
};
/* 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
/* DOS definitions -- return codes */
#define LS_SW_TIME_OUT LS_NOP /* return value used by DOS */
/* miscellaneous definitions */
#define DIV_LATCH_LOW 0
#define DIV_LATCH_HIGH 1
#define DIV_LATCH_LOW_WRITTEN 0x01
#define DIV_LATCH_HIGH_WRITTEN 0x02
#define DIV_LATCH_BOTH_WRITTEN 0x03
/* variable declarations */
extern int errno;
/* routine declarations */
extern void int14(regcontext_t *REGS);
extern void com_set_line(struct com_data_struct *, unsigned char, unsigned char);
extern void init_com(int, char *, int, unsigned char);
extern u_char com_port_in(int);
extern void com_port_out(int, unsigned char);
/* end of file com.h */

265
usr.bin/doscmd/config.c Normal file
View File

@ -0,0 +1,265 @@
/*
* 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
*
* $Id: config.c,v 1.2 1996/09/18 16:12:24 miff Exp $
*/
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <sys/types.h>
#include "doscmd.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)) {
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 (islower(av[1][4]) && av[1][5] == ':' && !av[1][6]) {
drive = av[1][4] - 'a';
} else if (isupper(av[1][4]) && av[1][5] == ':' && !av[1][6]) {
drive = av[1][4] - 'A';
}
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 (islower(av[1][4]) && av[1][5] == ':' && !av[1][6]) {
drive = av[1][4] - 'a';
} else if (isupper(av[1][4]) && av[1][5] == ':' && !av[1][6]) {
drive = av[1][4] - 'A';
}
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);
}
if (isupper(av[1][0]))
drive = av[1][0] - 'A';
else
drive = av[1][0] - 'a';
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;
int i;
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 < 1) || (irq > 15)) {
fprintf(stderr, "Usage: assign com[1-4] path addr irq\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);
}
if (isupper(av[1][0]))
bootdrive = av[1][0] - 'A';
else
bootdrive = av[1][0] - 'a';
if (bootdrive != 0 && bootdrive != 2) {
fprintf(stderr, "Boot drive must be either A: or C:\n");
quit(1);
}
} 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);
}

70
usr.bin/doscmd/cpu.c Normal file
View File

@ -0,0 +1,70 @@
/*
** No copyright ?!
**
** $Id: cpu.c,v 1.5 1996/09/25 11:05:54 miff Exp $
*/
#include "doscmd.h"
/*
** Hardware /0 interrupt
*/
void
int00(regcontext_t *REGS)
{
debug(D_ALWAYS, "Divide by 0 in DOS program!\n");
exit(1);
}
void
int01(regcontext_t *REGS)
{
debug(D_ALWAYS, "INT 1 with no handler! (single-step/debug)\n");
}
void
int03(regcontext_t *REGS)
{
debug(D_ALWAYS, "INT 3 with no handler! (breakpoint)\n");
}
void
int0d(regcontext_t *REGS)
{
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 */
}

43
usr.bin/doscmd/crt0.c Normal file
View File

@ -0,0 +1,43 @@
/*
* 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
*
* $Id: crt0.c,v 1.2 1996/09/18 16:12:25 miff Exp $
*/
char **environ;
char *__progname;
start(int argc, char **argv, char **env)
{
environ = env;
__progname = *argv;
quit(main(argc, argv, environ));
}

970
usr.bin/doscmd/cwd.c Normal file
View File

@ -0,0 +1,970 @@
/*
* 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
*
* $Id: cwd.c,v 1.6 1996/09/23 09:59:23 miff Exp $
*/
#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"
#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] = { 0, };
static Name_t *names;
extern int diskdrive;
/*
* Initialize the drive to be based at 'base' in the BSD filesystem
*/
void
init_path(int drive, u_char *base, 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", drive + 'A', 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", drive + 'A', 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] = drive + 'A';
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];
if (where[0] != '\0' && where[1] == ':') {
drive = *where - 'A';
*newpath++ = *where++;
*newpath++ = *where++;
} else {
drive = diskdrive;
*newpath++ = diskdrive + 'A';
*newpath++ = ':';
}
if (drive < 0 || drive >= MAX_DRIVE) {
debug(D_REDIR,"drive %c invalid\n",drive + 'A');
return (DISK_DRIVE_INVALID);
}
d = &paths[drive];
if (d->cwd == NULL) {
debug(D_REDIR,"no cwd for drive %c\n",drive + 'A');
return (DISK_DRIVE_INVALID);
}
debug(D_REDIR, "dos_makepath(%d, %s)\n", drive, where);
np = newpath;
if (*where != '\\' && *where != '/') {
ustrcpy(tmppath, d->cwd);
if (d->cwd[1])
ustrcat(tmppath, (u_char *)"/");
ustrcat(tmppath, where);
} else {
ustrcpy(tmppath, where);
}
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;
}
}
*np = 0;
return (0);
}
/*
* Set DOS's idea of the CWD for drive to be where.
* Returns DOS errno on failuer.
*/
int
dos_setcwd(u_char *where)
{
u_char newpath[1024];
u_char realpath[1024];
int drive;
struct stat sb;
Path_t *d;
int error;
debug(D_REDIR, "dos_setcwd(%s)\n", where);
error = dos_makepath(where, newpath);
if (error)
return (error);
error = dos_to_real_path(newpath, realpath, &drive);
if (error)
return (error);
if (ustat(realpath, &sb) < 0 || !S_ISDIR(sb.st_mode))
return (PATH_NOT_FOUND);
if (uaccess(realpath, R_OK | X_OK))
return (PATH_NOT_FOUND);
d = &paths[drive];
d->len = ustrlen(newpath + 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",
drive + 'A', newpath, strerror(errno));
}
ustrcpy(d->cwd, newpath + 2);
return (0);
}
/*
* Given a DOS path dospath and a drive, convert it to a BSD pathname
* and store the result in realpath.
* Return DOS errno on failure.
*/
int
dos_to_real_path(u_char *dospath, u_char *realpath, int *drivep)
{
Path_t *d;
u_char newpath[1024];
u_char *rp;
int error;
u_char **dirs;
u_char *dir;
int drive;
debug(D_REDIR, "dos_to_real_path(%s)\n", dospath);
if (dospath[0] != '\0' && dospath[1] == ':') {
drive = *dospath - 'A';
dospath++;
dospath++;
} else {
drive = diskdrive;
}
d = &paths[drive];
if (d->cwd == NULL)
return (DISK_DRIVE_INVALID);
ustrcpy(realpath, d->path);
rp = realpath;
while (*rp)
++rp;
ustrcpy(newpath, dospath);
dirs = get_entries(newpath);
if (dirs == NULL)
return (PATH_NOT_FOUND);
/*
* Skip the leading /
* There are no . or .. entries to worry about either
*/
while (dir = *++dirs) {
*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,
};
inline
isvalid(unsigned c)
{
return (cattr[c & 0xff] == 1);
}
inline
isdot(unsigned c)
{
return (cattr[c & 0xff] == 3);
}
inline
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 file system statistics for drive.
* Return the DOS errno on failure.
*/
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)
*/
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 = {dp : NULL};
/*
* 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.
*/
find_first(u_char *path, int attr, dosdir_t *dir, find_block_t *dta)
{
u_char newpath[1024], realpath[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, dta);
error = dos_makepath(path, newpath);
if (error)
return (error);
expr = newpath;
slash = 0;
while (*expr != '\0') {
if (*expr == '\\' || *expr == '/')
slash = expr;
expr++;
}
*slash++ = '\0';
error = dos_to_real_path(newpath, realpath, &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(realpath);
if (search->dp == NULL)
return (PATH_NOT_FOUND);
ustrcpy(search->searchdir, realpath);
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)) {
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);
}
/*
* perfrom 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);
}

109
usr.bin/doscmd/cwd.h Normal file
View File

@ -0,0 +1,109 @@
/*
* 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
*
* $Id: cwd.h,v 1.3 1996/09/23 09:59:23 miff Exp $
*/
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 *
ustrncpy(u_char *s1, u_char *s2, unsigned 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(u_char *s1, u_char *s2, unsigned n)
{
return(strncmp((char *)s1, (char *)s2, n));
}
static inline int
ustrlen(u_char *s)
{
return(strlen((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(u_char *s)
{
return((u_char *)strdup((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 drive, u_char *base, u_char *where);
extern void dos_makereadonly(int drive);
extern int dos_readonly(int drive);
extern u_char *dos_getcwd(int drive);
extern u_char *dos_getpath(int drive);
extern int dos_makepath(u_char *where, u_char *newpath);
extern int dos_setcwd(u_char *where);
extern int dos_to_real_path(u_char *dospath, u_char *realpath, int *);
extern void real_to_dos(u_char *real, u_char *dos);
extern void dos_to_real(u_char *dos, u_char *real);
extern u_char **get_entries(u_char *path);
extern int get_space(int drive, fsstat_t *fs);
extern int find_first(u_char *path, int attr,
dosdir_t *dir, find_block_t *dta);
extern int find_next(dosdir_t *dir, find_block_t *dta);

193
usr.bin/doscmd/debug.c Normal file
View File

@ -0,0 +1,193 @@
/*
* 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
*
* $Id: debug.c,v 1.5 1996/09/25 00:03:43 miff Exp $
*/
#include <stdarg.h>
#include "doscmd.h"
/* debug output goes here */
FILE *debugf = stderr;
/* 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, 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 (char *fmt, ...)
{
va_list args;
dead = 1;
if (xmode) {
char buf[1024];
char buf2[1024];
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=%x\n", R_IP, R_EFLAGS);
addr = (u_char *)N_GETPTR(R_CS, R_IP);
for (i = 0; i < 16; i++)
debug (D_ALWAYS, "%02x ", addr[i]);
debug (D_ALWAYS, "\n");
addr = (char *)N_GETPTR(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;
}

100
usr.bin/doscmd/disktab.c Normal file
View File

@ -0,0 +1,100 @@
/*
* 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
*/
/* XXX goaway (requires change to config.c) */
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);
}

110
usr.bin/doscmd/dispatch.h Normal file
View File

@ -0,0 +1,110 @@
/*
** 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.
**
** $Id: dispatch.h,v 1.3 1996/09/22 05:52:56 miff Exp $
*/
/*
** 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 index[])
{
int hn;
for (hn = 0; hn < 256; hn++) /* initialise all no-handler state */
index[hn] = -1; /* default to no handler */
for (hn = 0; table[hn].func >= 0; hn++) /* walk list of handlers and add references */
if (index[table[hn].func] == -1 ) /* reference first handler */
index[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 index[], int func, int subfunc)
{
int ent = index[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);
}

2508
usr.bin/doscmd/dos.c Normal file

File diff suppressed because it is too large Load Diff

402
usr.bin/doscmd/dos.h Normal file
View File

@ -0,0 +1,402 @@
/*
* 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
*
* $Id: dos.h,v 1.7 1996/09/23 09:59:24 miff Exp $
*/
/*
* 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 (zerod 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; /* pargraphs */
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 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);
/* from setver.c */
extern void setver(char *cmd, short version);
extern short getver(char *cmd);

892
usr.bin/doscmd/doscmd.c Normal file
View File

@ -0,0 +1,892 @@
/*
* 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
*
* $Id: doscmd.c,v 1.10 1997/03/18 02:36:55 msmith Exp $
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <errno.h>
#include <limits.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"
/* 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;
u_long pending[256]; /* pending interrupts */
int n_pending;
#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 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);
static void init_iomap(void);
/* Local option flags &c. */
static int zflag = 0;
/* DOS environment emulation */
static int ecnt = 0;
static char *envs[256];
/* Search path and command name */
static char *dos_path = 0;
char cmdname[256]; /* referenced from dos.c */
/* high memory mapfile */
static char *memfile = "/tmp/doscmd.XXXXXX";
static struct i386_vm86_args vm86;
static struct vm86_init_args kargs;
/* lobotomise */
int
main(int argc, char **argv)
{
#ifndef USE_VM86
struct sigcontext sc;
#else
struct vm86_struct vm86s;
#define sc vm86s.substr.regs.vmsc
#endif
regcontext_t *REGS = (regcontext_t *)&sc;
int fd;
int i;
char buffer[4096];
int mfd;
FILE *fp;
/* XXX should only be for tty mode */
fd = open ("/dev/null", 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 */
optind = do_args(argc, argv);
argc -= optind;
argv += optind;
if (vflag && debugf == stderr) {
debugf = stdout;
setbuf (stdout, NULL);
}
mfd = mkstemp(memfile);
if (mfd < 0) {
fprintf(stderr, "memfile: %s\n", strerror(errno));
fprintf(stderr, "High memory will not be mapped\n");
} else {
caddr_t add;
unlink(memfile);
mfd = squirrel_fd(mfd);
lseek(mfd, 64 * 1024 - 1, 0);
write(mfd, "", 1);
add = mmap((caddr_t)0x000000, 64 * 1024,
PROT_EXEC | PROT_READ | PROT_WRITE,
MAP_FILE | MAP_FIXED | MAP_INHERIT | MAP_SHARED,
mfd, 0);
add = mmap((caddr_t)0x100000, 64 * 1024,
PROT_EXEC | PROT_READ | PROT_WRITE,
MAP_FILE | MAP_FIXED | MAP_INHERIT | MAP_SHARED,
mfd, 0);
}
/* 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
for (i = 0; i < 256; i++)
pending[i] = 0;
n_pending = 0;
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();
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);
N_PUSH(R_FLAGS, REGS);
N_PUSH(R_CS, REGS);
N_PUSH(R_IP, REGS);
N_PUTVEC(R_CS, R_IP, video_vector);
}
sc.sc_mask = 0;
sc.sc_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 */
vm86.sub_op = VM86_INIT;
vm86.sub_args = (char *)&kargs;
i = sysarch(I386_VM86, &vm86);
printf("Init: %d\n", i);
sigreturn(&sc);
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((regcontext_t *)&sc);
fatal ("vm86 returned (no kernel support?)\n");
#undef sc
}
/*
** 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 = disk_fd(booting = 0)) < 0) /* try A: */
fd = disk_fd(booting = 2); /* try C: */
} else {
fd = disk_fd(booting); /* do like the man says */
}
if (fd < 0) { /* can we boot it? */
fprintf(stderr, "Cannot boot from %c: (can't open)\n",
booting + 'A');
quit(1);
}
/* read bootblock */
if (read(fd, (char *)0x7c00, 512) != 512) {
fprintf(stderr, "Short read on boot block from %c:\n",
booting + 'A');
quit(1);
}
/* 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
}
/*
** 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};
char *p;
char prog[1024];
char buffer[PATH_MAX];
int 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('C' - 'A') == 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('C' - 'A', (u_char *)"/", (u_char *)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];
sprintf(path, "PATH=C:%s",
dos_getcwd('C' - 'A'));
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) {
dos_path = envs[ecnt-1] + 5;
put_dosenv("PATH=C:\\");
}
/* 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('R' - 'A') == NULL)
init_path('R' - 'A', (u_char *)"/", 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];
int fd;
if ((fp = fopen(".doscmdrc", "r")) == NULL) {
struct passwd *pwd = getpwuid(geteuid());
if (pwd) {
sprintf(buffer, "%s/.doscmdrc", pwd->pw_dir);
fp = fopen(buffer, "r");
}
if (!fp) {
char *home = getenv("HOME");
if (home) {
sprintf(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, "234Oc:TkCIEMPRLAU:S:HDtzvVxXfbri:o:d:")) != -1) {
switch (c) {
case 'd':
if (fp = fopen(optarg, "w")) {
debugf = fp;
setbuf (fp, NULL);
} else
perror(optarg);
break;
case '2':
debug_flags |= D_TRAPS2;
break;
case '3':
debug_flags |= D_TRAPS3;
break;
case '4':
debug_flags |= D_DEBUGIN;
break;
case 'O':
debugf = stdout;
setbuf (stdout, NULL);
break;
case 'c':
if ((capture_fd = creat(optarg, 0666)) < 0) {
perror(optarg);
quit(1);
}
break;
case 'i':
i = 1;
if (col = strchr(optarg, ':')) {
*col++ = 0;
i = strtol(col, 0, 0);
}
p = strtol(optarg, 0, 0);
while (i-- > 0)
define_input_port_handler(p++, inb_traceport);
break;
case 'o':
i = 1;
if (col = strchr(optarg, ':')) {
*col++ = 0;
i = strtol(col, 0, 0);
}
p = strtol(optarg, 0, 0);
while (i-- > 0)
define_output_port_handler(p++, outb_traceport);
break;
case 'r':
raw_kbd = 1;
break;
case 'I':
debug_flags |= D_ITRAPS;
for (c = 0; c < 256; ++c)
debug_set(c);
break;
case 'k':
kargs.debug = 1;
break;
case 'T':
timer_disable = 1;
break;
case 'E':
debug_flags |= D_EXEC;
break;
case 'C':
debug_flags |= D_DOSCALL;
break;
case 'M':
debug_flags |= D_MEMORY;
break;
case 'P':
debug_flags |= D_PORT;
break;
case 'R':
debug_flags |= D_REDIR;
break;
case 'L':
debug_flags |= D_PRINTER;
break;
case 'A':
debug_flags |= D_TRAPS|D_ITRAPS;
for (c = 0; c < 256; ++c)
debug_set(c);
break;
case 'U':
debug_unset(strtol(optarg, 0, 0));
break;
case 'S':
debug_flags |= D_TRAPS|D_ITRAPS;
debug_set(strtol(optarg, 0, 0));
break;
case 'H':
debug_flags |= D_HALF;
break;
case 'x':
#ifdef NO_X
fatal("X11 support not compiled in.\n");
#endif
xmode = 1;
break;
case 't':
tmode = 1;
break;
case 'z':
zflag = 1;
break;
case 'D':
debug_flags |= D_DISK | D_FILE_OPS;
break;
case 'v':
debug_flags |= D_TRAPS | D_ITRAPS | D_HALF | 0xff;
break;
case 'V':
vflag = 1;
break;
case 'b':
booting = 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(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) {
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 *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 i386_ioperm_args {
u_short start;
u_short length;
char disable;
};
struct sysarch_args {
int op;
char *parms;
};
static void
iomap_init(void)
{
int i;
struct i386_ioperm_args args[] = {
#if 0
{ 0x200, 0x200, 1 }, /* 0x200 - 0x400 */
{ 0x1c80, 2, 1 }, /* 0x1c80 - 0x1c81 */
{ 0x2c80, 2, 1 }, /* 0x2c80 - 0x2c81 */
{ 0x3c80, 2, 1 }, /* 0x3c80 - 0x3c81 */
{ 0x3c4, 2, 1 }, /* 0x3c4 - 0x3c5 */
{ 0x3c5, 2, 1 }, /* 0x3ce - 0x3cf */
#else
{ 0x0, 0xffff, 1 }, /* entire i/o space */
#endif
{ 0, 0, 0 }
};
for (i = 0; args[i].length; i++)
if (sysarch(I386_SET_IOPERM, &(args[i])) < 0)
err(1, "sysarch");
}

272
usr.bin/doscmd/doscmd.h Normal file
View File

@ -0,0 +1,272 @@
/*
* 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
*
* $Id: doscmd.h,v 1.9 1996/09/23 09:59:25 miff Exp $
*/
#ifdef __NetBSD__
#define USE_VM86
#endif
#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 <errno.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"
#include "cwd.h"
/*
** 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
/* 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 /* for "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 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)
extern void unknown_int2(int, int, regcontext_t *REGS);
extern void unknown_int3(int, int, int, regcontext_t *REGS);
extern void unknown_int4(int, int, int, int, regcontext_t *REGS);
extern void fatal (char *fmt, ...);
extern void debug (int flags, char *fmt, ...);
extern void dump_regs(regcontext_t *REGS);
extern void debug_set(int x);
extern void debug_unset(int x);
extern u_long debug_isset(int x);
/* 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;
extern int open_prog(char *name);
extern void done(regcontext_t *REGS, int val);
extern void quit(int);
extern void call_on_quit(void (*)(void *), void *);
/* 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 *));
/* cmos.c */
extern time_t delta_clock;
extern void cmos_init(void);
/* config.c */
extern int read_config(FILE *fp);
/* tty.c */
extern char *xfont;
/* setver.c */
extern void setver(char *, short);
extern short getver(char *);
/* 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);
/* intff.c */
extern int int2f_11(regcontext_t *REGS);
extern void intff(regcontext_t *REGS);
/* trap.c */
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 breakpoint(struct sigframe *sf);
#ifdef USE_VM86
extern void sigurg(struct sigframe *sf);
#else
extern void sigbus(struct sigframe *sf);
#endif
/* int.c */
extern void softint(int intnum);
extern void hardint(int intnum);
extern void delay_interrupt(int intnum, void (*func)(int));
extern void resume_interrupt(void);
/* 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;
extern void wakeup_poll(void);
extern void reset_poll(void);
extern void sleep_poll(void);
/* 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);
/* int17.c */
extern void lpt_poll(void);
extern void printer_direct(int printer);
extern void printer_spool(int printer, char *print_queue);
extern void printer_timeout(int printer, char *time_out);
/* xms.c */
extern int int2f_43(regcontext_t *REGS);
/****************************** dirty below here ******************************/
extern u_long pending[]; /* pending interrupts */
extern int n_pending;
u_char *VREG;
extern int nmice;
extern int redirect0;
extern int redirect1;
extern int redirect2;
extern int kbd_fd;
extern int jmp_okay;
void put_dosenv(char *value);
/* TTY subsystem XXX rewrite! */
int tty_eread(REGISTERS, int, int);
void tty_write(int, int);
void tty_rwrite(int, int, int);
void tty_move(int, int);
void tty_report(int *, int *);
void tty_flush();
void tty_index();
void tty_pause();
int tty_peek(REGISTERS, int);
int tty_state();
void tty_scroll(int, int, int, int, int, int);
void tty_rscroll(int, int, int, int, int, int);
int tty_char(int, int);
void video_setborder(int);
void outb_traceport(int, unsigned char);
unsigned char inb_traceport(int);

View File

@ -0,0 +1,98 @@
/*
* 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
*
* $Id: doscmd_loader.c,v 1.2 1996/09/22 05:52:59 miff Exp $
*/
#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???");
}

423
usr.bin/doscmd/exe.c Normal file
View File

@ -0,0 +1,423 @@
/*
* 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
* $Id: exe.c,v 1.3 1996/09/22 06:26:01 miff Exp $
*/
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <ctype.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 char *env_block;
static int
make_environment (char *cmdname, 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 (cmdname) + 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(cmdname);
p += 2;
strcpy (p, cmdname);
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, 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 *cmdname,
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(cmdname, 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);
}
static int
get_psp(void)
{
return(psp_s[curpsp]);
}
int
get_env(void)
{
return(env_s[curpsp]);
}
void
exec_command(regcontext_t *REGS, int run,
int fd, char *cmdname, 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: cmdname = %s\n"
"env = 0x0%x, arg = %04x:%04x(%s)\n",
cmdname, 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, cmdname, param, argv, envs);
} else
load_command(REGS, run, fd, cmdname, 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 */
}

407
usr.bin/doscmd/font.h Normal file
View File

@ -0,0 +1,407 @@
/*
* 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 font.h,v 2.2 1996/04/08 19:32:35 bostic Exp
*/
unsigned char ascii_font[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81,
0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe,
0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7,
0xe7, 0x99, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c,
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66,
0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc,
0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66,
0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63,
0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00,
0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8,
0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06,
0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18,
0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b,
0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38,
0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe,
0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18,
0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe,
0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6c, 0xfe, 0x6c,
0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38,
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18,
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c,
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c,
0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0x86, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc,
0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30,
0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30,
0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18,
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18,
0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c,
0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x7c, 0xc6, 0xc6, 0xce, 0xd6, 0xd6, 0xe6, 0xc6, 0xc6, 0x7c, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c,
0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06,
0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1c,
0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x0e, 0x06, 0x06,
0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x60, 0xc0,
0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30,
0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6,
0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00,
0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60,
0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c,
0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc,
0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c,
0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66,
0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0,
0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78,
0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde,
0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6,
0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c,
0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xe6, 0x66, 0x6c, 0x6c, 0x78, 0x78, 0x6c, 0x66,
0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60,
0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6,
0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe,
0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c,
0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c,
0x0e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c,
0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c,
0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6,
0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c,
0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6,
0xc6, 0xc6, 0xd6, 0xd6, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x6c, 0x38, 0x38, 0x6c, 0x6c, 0xc6,
0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66,
0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c,
0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x30, 0x30, 0x18, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc,
0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60, 0x60,
0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0xdc, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6,
0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c,
0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0,
0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c,
0xcc, 0x78, 0x00, 0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66,
0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60,
0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c,
0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c,
0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc,
0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xdc, 0x76, 0x62, 0x60, 0x60, 0x60, 0xf0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60,
0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc,
0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6,
0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
0x7e, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00,
0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2,
0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc,
0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0,
0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00,
0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xcc, 0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc,
0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x78,
0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00,
0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60,
0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x10,
0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x00, 0x7c, 0xc6, 0xfe,
0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30,
0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18,
0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66,
0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18,
0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x10, 0x38,
0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6,
0xc6, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66,
0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xcc, 0x76, 0x36, 0x7e, 0xd8, 0xd8, 0x6e,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe,
0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x00, 0x7c, 0xc6, 0xc6,
0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30,
0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00,
0x00, 0x00, 0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc,
0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18,
0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xc6, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, 0x00, 0xc6, 0xc6, 0x00, 0x38,
0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,
0x00, 0xc6, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x3c, 0x66, 0x60,
0x60, 0x60, 0x66, 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x3c, 0x18, 0x7e,
0x18, 0x7e, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
0xcc, 0xcc, 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0xcc, 0xcc, 0xc6, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18,
0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x18, 0x30,
0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18,
0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60,
0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00,
0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6,
0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00,
0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30,
0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06,
0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0,
0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x93, 0x06, 0x0c, 0x1f,
0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x66,
0xce, 0x9a, 0x3f, 0x06, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18,
0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x66, 0xcc, 0x66, 0x33,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xcc, 0x66, 0x33, 0x66, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11,
0x44, 0x11, 0x44, 0x11, 0x44, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0xdd,
0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,
0xdd, 0x77, 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00,
0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6,
0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18,
0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30,
0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36,
0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18,
0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0x0f,
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xc6, 0xfc,
0xc6, 0xc6, 0xfc, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xfe,
0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xfe, 0x6c, 0x6c, 0x6c,
0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8,
0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66,
0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c,
0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6,
0x6c, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb,
0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x06, 0x7e, 0xcf, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60,
0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c,
0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00,
0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00,
0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30,
0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00,
0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c,
0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c,
0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x6c, 0x6c,
0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x70, 0x98, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c,
0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
};

1814
usr.bin/doscmd/i386-pinsn.c Normal file

File diff suppressed because it is too large Load Diff

55
usr.bin/doscmd/instbsdi.c Normal file
View File

@ -0,0 +1,55 @@
/*
* 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 instbsdi.c,v 2.2 1996/04/08 19:32:39 bostic Exp
*/
#include <dos.h>
#include <string.h>
main(int ac, char **av)
{
union REGS in, out, tmp;
struct SREGS seg, stmp;
memset(&out, 0, sizeof(out));
out.h.ah = 0x52;
int86x(0x21, &out, &tmp, &stmp);
seg.es = stmp.es;
in.x.di = tmp.x.bx;
out.x.ax = 0x5D06;
int86x(0x21, &out, &tmp, &stmp);
seg.ds = stmp.ds;
in.x.si = tmp.x.si;
int86x(0xff, &in, &out, &seg);
}

139
usr.bin/doscmd/int.c Normal file
View File

@ -0,0 +1,139 @@
/*
** No copyright?!
**
** $Id: int.c,v 1.4 1997/03/18 02:36:56 msmith Exp $
*/
#include "doscmd.h"
/*
** 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;
#if 0
/*
* software interrupts are always taken
*/
if ((R_EFLAGS & PSL_VIF) == 0) {
delay_interrupt(intnum, softint);
return;
}
#endif
debug(D_TRAPS|intnum, "Int%x [%04x:%04x]\n",
intnum, vec >> 16, vec & 0xffff);
N_PUSH((R_FLAGS & ~PSL_I) | (R_EFLAGS & PSL_VIF ? PSL_I : 0), REGS);
N_PUSH(R_CS, REGS);
N_PUSH(R_IP, REGS);
#if 1
R_EFLAGS &= ~PSL_VIF; /* XXX disable interrupts? */
#else
R_EFLAGS |= PSL_VIF;
#endif
N_PUTVEC(R_CS, R_IP, vec);
}
/*
** Cause a hardware interrupt to happen immediately after
** we return to vm86 mode
*/
void
hardint(int intnum)
{
regcontext_t *REGS = saved_regcontext;
u_long vec = ivec[intnum];
/*
* XXXXX
* We should simulate the IRQ mask in the PIC.
*/
/*
** 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 ((R_EFLAGS & PSL_VIF) == 0) {
delay_interrupt(intnum, hardint);
return;
}
debug(D_TRAPS|intnum, "Int%x [%04x:%04x]\n",
intnum, vec >> 16, vec & 0xffff);
N_PUSH((R_FLAGS & ~PSL_I) | (R_EFLAGS & PSL_VIF ? PSL_I : 0), REGS);
N_PUSH(R_CS, REGS);
N_PUSH(R_IP, REGS);
#if 1
R_EFLAGS &= ~PSL_VIF; /* XXX disable interrupts */
#else
R_EFLAGS |= PSL_VIF;
#endif
N_PUTVEC(R_CS, R_IP, vec);
}
typedef void (*foo_t)(int);
void
resume_interrupt(void)
{
int i;
regcontext_t *REGS = saved_regcontext;
n_pending--;
if (n_pending == 0)
R_EFLAGS &= ~PSL_VIP;
for (i = 0; i < 256; i++) {
if (pending[i]) {
((foo_t)(pending[i]))(i);
pending[i] = 0;
break;
}
}
}
void
delay_interrupt(int intnum, void (*func)(int))
{
regcontext_t *REGS = saved_regcontext;
#if 0
printf("DELAY [%x/%d]\n", intnum, n_pending);
#endif
if (pending[intnum] == 0) {
pending[intnum] = (u_long)func;
n_pending++;
}
R_EFLAGS |= PSL_VIP;
}

277
usr.bin/doscmd/int10.c Normal file
View File

@ -0,0 +1,277 @@
/*
* 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
*
* $Id: int10.c,v 1.2 1996/09/22 05:53:00 miff Exp $
*/
#include "doscmd.h"
#include "mouse.h"
/*
* 0040:0060 contains the start and end of the cursor
*/
#define curs_end BIOSDATA[0x60]
#define curs_start BIOSDATA[0x61]
void
int10(REGISTERS)
{
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 (GET8H(sc->sc_eax)) {
case 0x00: /* Set display mode */
debug(D_HALF, "Set video mode to %02x\n", GET8L(sc->sc_eax));
break;
case 0x01: /* Define cursor */
curs_start = GET8H(sc->sc_ecx);
curs_end = GET8L(sc->sc_ecx);
break;
case 0x02: /* Position cursor */
if (!xmode)
goto unsupported;
tty_move(GET8H(sc->sc_edx), GET8L(sc->sc_edx));
break;
case 0x03: /* Read cursor position */
if (!xmode)
goto unsupported;
tty_report(&i, &j);
SET8H(sc->sc_edx, i);
SET8L(sc->sc_edx, j);
SET8H(sc->sc_ecx, curs_start);
SET8L(sc->sc_ecx, curs_end);
break;
case 0x05:
debug(D_HALF, "Select current display page %d\n", GET8L(sc->sc_eax));
break;
case 0x06: /* initialize window/scroll text upward */
if (!xmode)
goto unsupported;
tty_scroll(GET8H(sc->sc_ecx), GET8L(sc->sc_ecx),
GET8H(sc->sc_edx), GET8L(sc->sc_edx),
GET8L(sc->sc_eax), GET8H(sc->sc_ebx) << 8);
break;
case 0x07: /* initialize window/scroll text downward */
if (!xmode)
goto unsupported;
tty_rscroll(GET8H(sc->sc_ecx), GET8L(sc->sc_ecx),
GET8H(sc->sc_edx), GET8L(sc->sc_edx),
GET8L(sc->sc_eax), GET8H(sc->sc_ebx) << 8);
break;
case 0x08: /* read character/attribute */
if (!xmode)
goto unsupported;
i = tty_char(-1, -1);
SET16(sc->sc_eax, i);
break;
case 0x09: /* write character/attribute */
if (!xmode)
goto unsupported;
tty_rwrite(GET16(sc->sc_ecx), GET8L(sc->sc_eax), GET8L(sc->sc_ebx) << 8);
break;
case 0x0a: /* write character */
if (!xmode)
goto unsupported;
tty_rwrite(GET16(sc->sc_ecx), GET8L(sc->sc_eax), -1);
break;
case 0x0b: /* set border color */
if (!xmode)
goto unsupported;
video_setborder(GET8L(sc->sc_ebx));
break;
case 0x0e: /* write character */
tty_write(GET8L(sc->sc_eax), -1);
break;
case 0x0f: /* get display mode */
SET8H(sc->sc_eax, 80); /* number of columns */
SET8L(sc->sc_eax, 3); /* color */
SET8H(sc->sc_ebx, 0); /* display page */
break;
case 0x10:
switch (GET8L(sc->sc_eax)) {
case 0x01:
video_setborder(GET8H(sc->sc_ebx) & 0x0f);
break;
case 0x02: /* Set pallete registers */
debug(D_HALF, "INT 10 10:02 Set all palette registers\n");
break;
case 0x03: /* Enable/Disable blinking mode */
video_blink(GET8L(sc->sc_ebx) ? 1 : 0);
break;
case 0x13:
debug(D_HALF,
"INT 10 10:13 Select color or DAC (%02x, %02x)\n",
GET8L(sc->sc_ebx), GET8H(sc->sc_ebx));
break;
case 0x1a: /* get video dac color-page state */
SET8H(sc->sc_ebx, 0); /* Current page */
SET8L(sc->sc_ebx, 0); /* four pages of 64... */
break;
default:
unknown_int3(0x10, 0x10, GET8L(sc->sc_eax), sc);
break;
}
break;
#if 1
case 0x11:
switch (GET8L(sc->sc_eax)) {
case 0x00: printf("Tried to load user defined font.\n"); break;
case 0x01: printf("Tried to load 8x14 font.\n"); break;
case 0x02: printf("Tried to load 8x8 font.\n"); break;
case 0x03: printf("Tried to activate character set\n"); break;
case 0x04: printf("Tried to load 8x16 font.\n"); break;
case 0x10: printf("Tried to load and activate user defined font\n"); break;
case 0x11: printf("Tried to load and activate 8x14 font.\n"); break;
case 0x12: printf("Tried to load and activate 8x8 font.\n"); break;
case 0x14: printf("Tried to load and activate 8x16 font.\n"); break;
case 0x30:
SET16(sc->sc_ecx, 14);
SET8L(sc->sc_edx, 24);
switch(GET8H(sc->sc_ebx)) {
case 0:
PUTVEC(sc->sc_es, sc->sc_ebp, ivec[0x1f]);
break;
case 1:
PUTVEC(sc->sc_es, sc->sc_ebp, ivec[0x43]);
break;
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
SET16(sc->sc_es, 0);
SET16(sc->sc_ebp, 0);
debug(D_HALF,
"INT 10 11:30 Request font address %02x",
GET8H(sc->sc_ebx));
break;
default:
unknown_int4(0x10, 0x11, 0x30, GET8H(sc->sc_ebx), sc);
break;
}
break;
default:
unknown_int3(0x10, 0x11, GET8L(sc->sc_eax), sc);
break;
}
break;
#endif
case 0x12: /* Load multiple DAC color register */
if (!xmode)
goto unsupported;
switch (GET8L(sc->sc_ebx)) {
case 0x10: /* Read EGA/VGA config */
SET8H(sc->sc_ebx, 0); /* Color */
SET8L(sc->sc_ebx, 0); /* 64K */
break;
default:
unknown_int3(0x10, 0x12, GET8L(sc->sc_ebx), sc);
break;
}
break;
case 0x13: /* write character string */
if (!xmode)
goto unsupported;
addr = (char *)GETPTR(sc->sc_es, sc->sc_ebp);
switch (GET8L(sc->sc_eax) & 0x03) {
case 0:
tty_report(&saved_row, &saved_col);
tty_move(GET8H(sc->sc_edx), GET8L(sc->sc_edx));
for (i = 0; i < GET16(sc->sc_ecx); ++i)
tty_write(*addr++, GET8L(sc->sc_ebx) << 8);
tty_move(saved_row, saved_col);
break;
case 1:
tty_move(GET8H(sc->sc_edx), GET8L(sc->sc_edx));
for (i = 0; i < GET16(sc->sc_ecx); ++i)
tty_write(*addr++, GET8L(sc->sc_ebx) << 8);
break;
case 2:
tty_report(&saved_row, &saved_col);
tty_move(GET8H(sc->sc_edx), GET8L(sc->sc_edx));
for (i = 0; i < GET16(sc->sc_ecx); ++i) {
tty_write(addr[0], addr[1]);
addr += 2;
}
tty_move(saved_row, saved_col);
break;
case 3:
tty_move(GET8H(sc->sc_edx), GET8L(sc->sc_edx));
for (i = 0; i < GET16(sc->sc_ecx); ++i) {
tty_write(addr[0], addr[1]);
addr += 2;
}
break;
}
break;
case 0x1a:
if (!xmode)
goto unsupported;
SET8L(sc->sc_eax, 0x1a); /* I am VGA */
SET8L(sc->sc_ebx, 8); /* Color VGA */
SET8H(sc->sc_ebx, 0); /* No other card */
break;
case 0x4f: /* get VESA information */
SET8H(sc->sc_eax, 0x01); /* no VESA support */
break;
case 0x1b: /* Functionality state information */
case 0xef:
case 0xfe: /* Get video buffer */
break;
case 0xfa: /* Interrogate mouse driver */
if (xmode)
PUTPTR(sc->sc_es, sc->sc_ebx, (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(sc);
fatal ("int10 function 0x%02x:%02x only available in X mode\n",
GET8H(sc->sc_eax), GET8L(sc->sc_eax));
unknown:
default:
unknown_int2(0x10, GET8H(sc->sc_eax), sc);
break;
}
}

873
usr.bin/doscmd/int13.c Normal file
View File

@ -0,0 +1,873 @@
/*
* 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
*
* $Id: int13.c,v 1.3 1996/09/22 15:42:53 miff Exp $
*/
#include "doscmd.h"
#include <sys/ioctl.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] = { 0 };
static struct diskinfo floppyinfo[] = {
{ 0, 9, 40, 1, 512, -1, 0, 0, }, /* Probably not correct */
{ 1, 9, 40, 2, 512, -1, 0, 0, },
{ 2, 9, 80, 2, 512, -1, 0, 0, },
{ 3, 15, 80, 2, 512, -1, 0, 0, },
{ 4, 18, 80, 2, 512, -1, 0, 0, },
{ 6, 36, 80, 2, 512, -1, 0, 0, },
{ -1, 0, 0, 0, 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",
drive + 'A', 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 == head * tracksize * cyl &&
(ptab[fd].systemID == 1 || ptab[fd].systemID == 4))
break;
}
if (fd < 4) {
if (fd)
memcpy(ptab, ptab + fd, sizeof(PTAB));
memset(ptab + 1, 0, sizeof(PTAB) * 3);
di->offset = ptab[fd].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
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);
}
}
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",
drive + 'A', 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", drive + 'A');
return(-1);
}
di->removeable = 1;
} else if (di->removeable) {
fprintf(stderr, "Drive %c: already assigned to %s\n",
drive + 'A', di->path);
return(-1);
}
if (di->removeable) {
#if 0 /*XXXXX*/
if (di->multi == 4) {
fprintf(stderr, "Drive %c: already assigned 4 devices\n",
drive + 'A');
return(-1);
}
#endif
di->path = di->list[di->multi++] = strdup(file);
} else {
if (di->path) {
fprintf(stderr, "Drive %c: already assigned to %s\n",
drive + 'A', 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);
}
static int icnt = 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 *)N_GETPTR(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 *)GETPTR(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 %d\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)
N_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;
}

510
usr.bin/doscmd/int14.c Normal file
View File

@ -0,0 +1,510 @@
/*
* 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
*
* $Id: int14.c,v 1.3 1996/09/22 15:42:53 miff Exp $
*/
#include "doscmd.h"
#include <sys/ioctl.h>
#include <termios.h>
#include "com.h"
struct com_data_struct com_data[N_COMS_MAX];
struct queue *create_queue() { return(0); }
int get_char_q() {}
int queue_not_empty() {}
int reset_irq_request() {}
int set_irq_request() {}
int test_irq_request() {}
int write_div_latches() {}
void
int14(regcontext_t *REGS)
{
int reg_num;
struct com_data_struct *cdsp;
int i;
int nbytes;
char c;
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 */
#if 0 /* hold off: try to defeat stupid DOS defaults */
com_set_line(cdsp, R_DL + 1, R_AL);
R_AH = LS_X_SHFT_E | LS_X_HOLD_E;
R_AL = 0;
#endif 0
break;
case 0x01: /* Write Character */
errno = 0;
c = R_AL;
nbytes = write(cdsp->fd, &c, 1);
debug (D_PORT, "write of 0x%02x to fd %d on '%s' returned %d %s\n",
R_AL, cdsp->fd, cdsp->path, nbytes, strerror(errno));
if (nbytes == 1) {
R_AH = LS_X_SHFT_E | LS_X_HOLD_E;
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 */
errno = 0;
nbytes = read(cdsp->fd, &c, 1);
debug (D_PORT, "read of fd %d on '%s' returned %d byte 0x%02x %s\n",
cdsp->fd, cdsp->path, nbytes, c,
errno ? strerror(errno) : "");
if (nbytes == 1) {
R_AH = LS_X_SHFT_E | LS_X_HOLD_E;
R_AL = c;
} else {
R_AH = LS_SW_TIME_OUT;
R_AL = 0x60;
}
break;
case 0x03: /* Status Request */
R_AX = (LS_X_SHFT_E | LS_X_HOLD_E) << 8;
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 */
void
com_set_line(struct com_data_struct *cdsp, unsigned char port, unsigned char param)
{
struct termios tty;
struct stat stat_buf;
int mode = 0; /* read|write */
int speed;
int reg_num;
int ret_val;
debug (D_PORT, "com_set_line: cdsp = 0x%08X, 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);
(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->flags = 0x00;
cdsp->last_char_read = 0x00;
#if 0
if ((param & PARITY_EVEN) == PARITY_NONE)
tty.c_iflag = IGNBRK | IGNPAR | IXON | IXOFF /* | IXANY */;
else
tty.c_iflag = IGNBRK | IXON | IXOFF /* | IXANY */;
tty.c_oflag = 0;
tty.c_lflag = 0;
tty.c_cc[VTIME] = 0;
tty.c_cc[VMIN] = 1;
tty.c_cflag = CREAD | CLOCAL | HUPCL;
/* MCL WHY CLOCAL ??????; but, gets errno EIO on writes, else */
if ((param & TXLEN_8BITS) == TXLEN_8BITS)
tty.c_cflag |= CS8;
else
tty.c_cflag |= CS7;
if ((param & STOPBIT_2) == STOPBIT_2)
tty.c_cflag |= CSTOPB;
switch (param & PARITY_EVEN) {
case (PARITY_ODD):
tty.c_cflag |= (PARENB | PARODD);
break;
case (PARITY_EVEN):
tty.c_cflag |= PARENB;
break;
case (PARITY_NONE):
default:
break;
}
switch (param & BITRATE_9600) {
case (BITRATE_110):
speed = B110;
break;
case (BITRATE_150):
speed = B150;
break;
case (BITRATE_300):
speed = B300;
break;
case (BITRATE_600):
speed = B600;
break;
case (BITRATE_1200):
speed = B1200;
break;
case (BITRATE_2400):
speed = B2400;
break;
case (BITRATE_4800):
speed = B4800;
break;
case (BITRATE_9600):
speed = B9600;
break;
}
debug (D_PORT, "com_set_line: going with cflag 0x%X iflag 0x%X speed %d.\n",
tty.c_cflag, tty.c_iflag, speed);
errno = 0;
ret_val = cfsetispeed(&tty, speed);
debug (D_PORT, "com_set_line: cfsetispeed returned 0x%X.\n", ret_val);
errno = 0;
ret_val = cfsetospeed(&tty, speed);
debug (D_PORT, "com_set_line: cfsetospeed returned 0x%X.\n", ret_val);
errno = 0;
ret_val = tcsetattr(cdsp->fd, 0, &tty);
debug (D_PORT, "com_set_line: tcsetattr returned 0x%X.\n", ret_val);
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%02x to fd %d on 0x%X returned %d errno %d\n",
TIOCFLUSH, cdsp->fd, mode, ret_val, errno);
#endif
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);
}
cdsp->com_queue = create_queue(cdsp->irq);
debug(D_PORT, "com%d: attached '%s' at addr 0x%04x irq %d\n",
port, cdsp->path, cdsp->addr, cdsp->irq);
}
/* 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);
}
/* 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 nbytes;
/* 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 {
#if 0
if (queue_not_empty(cdsp->com_queue)) {
rs = get_char_q(cdsp->com_queue);
cdsp->last_char_read = rs;
if (queue_not_empty(cdsp->com_queue) &&
(cdsp->int_enable & IE_RCV_DATA) != 0) {
debug(D_PORT,
"com_port_in: setting irq %d because bytes yet to be read.\n",
cdsp->irq);
set_irq_request(cdsp->irq);
}
} else
#else
errno = 0;
nbytes = read(cdsp->fd, &rs, 1);
debug (D_PORT, "read of fd %d on '%s' returned %d byte 0x%02x errno %d\n",
cdsp->fd, cdsp->path, nbytes, rs, errno);
if (nbytes != 1)
#endif
rs = cdsp->last_char_read;
}
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;
/* 0x03FA - interrupt identification register */
case 2:
/* rs = cdsp->int_id; * XXX DEBUG not initialized */
rs = 0;
if ((queue_not_empty(cdsp->com_queue))
&& (test_irq_request(cdsp->irq) != 0))
rs |= II_PEND_INT | II_RCV_DATA;
if ((cdsp->fifo_ctrl & FC_FIFO_EN) == FC_FIFO_EN)
rs |= II_FIFOS_EN;
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 = LS_X_SHFT_E | LS_X_HOLD_E;
/* if (queue_not_empty(cdsp->com_queue)) */
ioctl(cdsp->fd, FIONREAD, &nbytes);
if (nbytes > 0);
rs |= LS_RCV_DATA_RD;
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 nbytes;
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;
cdsp->flags |= DIV_LATCH_LOW_WRITTEN;
write_div_latches(cdsp);
} else {
errno = 0;
nbytes = write(cdsp->fd, val, 1);
debug (D_PORT, "write of 0x%02x to fd %d on '%s' returned %d errno %d\n",
val, cdsp->fd, cdsp->path, nbytes, errno);
if (nbytes != 1)
debug(D_PORT,
"int14: lost output character 0x%02x\n",
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;
cdsp->flags |= DIV_LATCH_HIGH_WRITTEN;
write_div_latches(cdsp);
} else {
cdsp->int_enable = val;
if ((val & IE_RCV_DATA) == 0) {
reset_irq_request(cdsp->irq);
} else {
if (queue_not_empty(cdsp->com_queue)) {
set_irq_request(cdsp->irq);
}
}
}
break;
/* 0x03FA - FIFO control register */
case 2:
cdsp->fifo_ctrl = val;
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:
cdsp->line_stat = val;
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;
}
}
#if 0
/*
* called when BSD has bytes ready (as discovered via select) for DOS
*/
static void do_com_input(int fd)
{
struct com_data_struct *cdsp;
unsigned char buffer[BUFSIZE];
int i, nbytes;
dp = search_com_device_by_fd(fd);
if (dp == NULL)
return;
do {
nbytes = read(cdsp->fd, buffer, BUFSIZE);
if (nbytes > 0) {
debug(D_PORT, "do_com_input: read %d bytes from fd %d (aka %d): ",
nbytes, fd, cdsp->fd);
for (i = 0; i < nbytes; i++) {
put_char_q(cdsp->com_queue, buffer[i]);
if (cdsp->int_enable & IE_RCV_DATA) {
debug(D_PORT, "\n");
debug(D_PORT, "do_com_input: setting irq %d because %d bytes read.\n",
dp->irq, nbytes);
debug(D_PORT, "do_com_input: ");
set_irq_request(dp->irq);
}
debug(D_PORT, "%02x ", buffer[i]);
}
debug(D_PORT, "\n");
}
} while (nbytes == BUFSIZE);
}
#endif 0

140
usr.bin/doscmd/int16.c Normal file
View File

@ -0,0 +1,140 @@
/*
* 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
*
* $Id: int16.c,v 1.3 1996/09/22 15:42:54 miff Exp $
*/
#include "doscmd.h"
#define K_NEXT *(u_short *)0x41a
#define K_FREE *(u_short *)0x41c
#define KbdEmpty() (K_NEXT == K_FREE)
#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)
{
int c;
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 (!raw_kbd)
sleep_poll();
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;
}
}

191
usr.bin/doscmd/int17.c Normal file
View File

@ -0,0 +1,191 @@
/*
* 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
*
* $Id: int17.c,v 1.3 1996/09/22 15:42:56 miff Exp $
*/
#include "doscmd.h"
#include <signal.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 int alarm_active[4] = { 0, 0, 0, 0};
static int alarm_set = 0;
static void open_printer(int printer);
void
int17(regcontext_t *REGS)
{
char printer_name[20];
int fd;
int p;
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]) {
if ((fd = open(p, O_WRONLY|O_APPEND|O_CREAT, 0666)) < 0) {
perror(p);
return;
}
} else {
sprintf(printer_name, "/dev/lp%d", 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])
strcpy(printer_name, queue[printer]);
else
strcpy(printer_name, "lp");
sprintf(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);
}

110
usr.bin/doscmd/int1a.c Normal file
View File

@ -0,0 +1,110 @@
/*
* 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
*
* $Id: int1a.c,v 1.3 1996/09/22 15:42:56 miff Exp $
*/
#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;
long value;
static long midnight = 0;
R_FLAGS &= ~PSL_C;
switch (R_AH) {
case 0x00:
gettimeofday(&tod, &zone);
if (midnight == 0) {
tm = localtime(&boot_time.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) {
tm = localtime(&boot_time.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 */
tm = localtime(&boot_time.tv_sec);
midnight = boot_time.tv_sec - (((tm->tm_hour * 60)
+ tm->tm_min) * 60 + tm->tm_sec);
break;
case 0x02:
gettimeofday(&tod, &zone);
tm = localtime(&tod.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);
tm = localtime(&tod.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;
}
}

167
usr.bin/doscmd/int2f.c Normal file
View File

@ -0,0 +1,167 @@
/*
* 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
*
* $Id: int2f.c,v 1.4 1996/09/22 15:42:56 miff Exp $
*/
#include "doscmd.h"
#include "dispatch.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;
}
/*
** 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 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 index;
/* look up the handler for the current function */
index = intfunc_search(int2f_table, R_AH, R_AL);
if (index >= 0) { /* respond on multiplex chain */
int2f_table[index].handler(REGS);
} else {
unknown_int2(0x2f, R_AH, REGS);
}
}

805
usr.bin/doscmd/intff.c Normal file
View File

@ -0,0 +1,805 @@
/*
* 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
*
* $Id: intff.c,v 1.8 1996/09/23 09:59:25 miff Exp $
*/
#include "doscmd.h"
#include <sys/param.h>
#include <ctype.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)
{
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)
{
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 %d\n", r_sft->offset);
return(0);
}
/*
** 2f:11:c
**
** Get free space (like 21:36)
*/
static int
int2f11_free(regcontext_t *REGS)
{
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)
{
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 *)N_GETPTR(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)
{
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)
{
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 = (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,*tname;
int savedrive;
int error;
return(PATH_NOT_FOUND);
savedrive = diskdrive; /* to get CWD for network drive */
diskdrive = n_drive;
fname = (char *)N_GETPTR(R_DS, R_SI); /* path pointers */
tname = (char *)N_GETPTR(R_ES, R_DI);
error = dos_makepath(fname, tname);
if (error)
tname = "(failed)";
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)
{
return(0);
}
/*
** 2f:11:??
**
** no function - not handled here (error)
*/
static int
int2f11_NOFUNC(regcontext_t *REGS)
{
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;
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 *)N_GETPTR(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 *)N_GETPTR(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 = toupper(path[0]) - 'A';
} 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, 'A'+r_drive, func, doit?"":"not ");
/* so do we deal with this one? */
return(doit);
}
int
int2f_11(regcontext_t *REGS)
{
int index;
int error;
char *fname;
if (!sda) { /* not initialised yet */
error = FUNC_NUM_IVALID;
} else {
index = intfunc_find(int2f11_table, int2f11_fastlookup, R_AL, 0);
if (index == -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[index].func, int2f11_table[index].desc);
/* call the handler */
error = int2f11_table[index].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",
drive + 'A', lol->lastdrive - 1 + 'A');
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", drive + 'A');
return;
}
#endif
debug(D_REDIR, "Installing %c: as %s\n", drive + 'A', path);
cds->flag |= CDS_remote | CDS_ready | CDS_notnet;
cds->path[0] = drive + 'A';
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)) /* 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\n");
return;
}
lol = (LOL *)N_GETPTR(R_ES, R_DI); /* where DOS keeps its goodies */
sda = (SDA *)N_GETPTR(R_DS, R_SI);
init_drives();
/* initialise dispatcher */
intfunc_init(int2f11_table, int2f11_fastlookup);
}

325
usr.bin/doscmd/mem.c Normal file
View File

@ -0,0 +1,325 @@
/*
* 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
*
* $Id: mem.c,v 1.4 1996/09/22 15:42:57 miff Exp $
*/
#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, "%05x: 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 = 0x%x 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;
int delta, nxtsiz;
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 */

300
usr.bin/doscmd/mouse.c Normal file
View File

@ -0,0 +1,300 @@
/*
* 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
*
* $Id: mouse.c,v 1.3 1996/09/22 15:42:58 miff Exp $
*/
#include "doscmd.h"
#include "mouse.h"
mouse_t mouse_status;
u_char *mouse_area = 0;
int nmice = 0;
static void
mouse_probe(void)
{
}
void
int33(regcontext_t *REGS)
{
u_long vec;
u_short mask;
void *addr;
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;
mouse_status.lastx - mouse_status.x;
mouse_status.lasty - mouse_status.y;
break;
case 0x0c: /* Set event handler */
mouse_status.mask = R_CX;
mouse_status.handler = N_GETVEC(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 = GETVEC(R_ES, R_DX);
R_CX = mask;
N_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 *)N_GETPTR(R_ES, R_DX), &mouse_status,
sizeof(mouse_status));
break;
case 0x17: /* Restore mouse buffer */
memcpy(&mouse_status, (char *)N_GETPTR(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] = N_GETVEC(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;
N_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: /* set 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) {
N_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;
}

68
usr.bin/doscmd/mouse.h Normal file
View File

@ -0,0 +1,68 @@
/*
* 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
*
* $Id: mouse.h,v 1.3 1996/09/22 15:42:58 miff Exp $
*/
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;

34
usr.bin/doscmd/net.c Normal file
View File

@ -0,0 +1,34 @@
/*
** No copyright!
**
** $Id: net.c,v 1.3 1996/09/22 15:42:58 miff Exp $
**
** NetBIOS etc. hooks.
*/
#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");
}

405
usr.bin/doscmd/port.c Normal file
View File

@ -0,0 +1,405 @@
/*
* 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
*
* $Id: port.c,v 1.2 1996/09/22 05:53:08 miff Exp $
*/
#include "doscmd.h"
#define MINPORT 0x000
#define MAXPORT_MASK (MAXPORT - 1)
#include <sys/ioctl.h>
#include <machine/sysarch.h>
static int consfd = -1;
#define in(port) \
({ \
register int _inb_result; \
\
asm volatile ("xorl %%eax,%%eax; inb %%dx,%%al" : \
"=a" (_inb_result) : "d" (port)); \
_inb_result; \
})
#define out(port, data) \
asm volatile ("outb %%al,%%dx" : : "a" (data), "d" (port))
FILE *iolog = 0;
u_long ioports[MAXPORT/32];
#ifdef __FreeBSD__
static void
iomap(int port, int cnt)
{
fatal("iomap not supported");
}
static void
iounmap(int port, int cnt)
{
fatal("iomap not supported");
}
#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);
}
/*
* Fake input/output ports
*/
static void
outb_nullport(int port, unsigned char byte)
{
/*
debug(D_PORT, "outb_nullport called for port 0x%03X = 0x%02X.\n",
port, byte);
*/
}
static unsigned char
inb_nullport(int port)
{
/*
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 *)N_GETPTR(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 *)N_GETPTR(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 *)N_GETPTR(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 *)N_GETPTR(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 *)N_GETPTR(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 *)N_GETPTR(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, 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)
{
/* 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);
}

222
usr.bin/doscmd/register.h Normal file
View File

@ -0,0 +1,222 @@
/*
** 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.
**
** $Id: register.h,v 1.4 1997/03/18 02:36:56 msmith Exp $
*/
/******************************************************************************
** Abstractions to hide register access methods across different platforms.
**
*/
#define NEW_REGISTERS
#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 pad[2];
reg86_t esp;
reg86_t ebp;
reg86_t isp;
reg86_t eip;
reg86_t efl;
reg86_t es;
reg86_t ds;
reg86_t cs;
reg86_t ss;
reg86_t edi;
reg86_t esi;
reg86_t ebx;
reg86_t edx;
reg86_t ecx;
reg86_t eax;
reg86_t gs;
reg86_t fs;
} registers_t;
typedef union
{
struct sigcontext 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 N_PUTVEC(s, o, x) ((s) = ((x) >> 16), (o) = (x) & 0xffff)
#define MAKEVEC(s, o) (((s) << 16) + (o)) /* XXX these two should be combined */
#define N_GETVEC(s, o) (((s) << 16) + (o))
#define N_PUTPTR(s, o, x) (((s) = ((x) & 0xf0000) >> 4), (o) = (x) & 0xffff)
#define MAKEPTR(s, o) (((s) << 4) + (o)) /* XXX these two should be combined */
#define N_GETPTR(s, o) (((s) << 4) + (o))
#define VECPTR(x) MAKEPTR((x) >> 16, (x) & 0xffff)
#if 0
#define N_REGISTERS regcontext_t *_regcontext
#define N_REGS _regcontex
#endif
inline static void
N_PUSH(u_short x, regcontext_t *REGS)
{
R_SP -= 2;
*(u_short *)N_GETPTR(R_SS, R_SP) = (x);
}
inline static u_short
N_POP(regcontext_t *REGS)
{
u_short x;
x = *(u_short *)N_GETPTR(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
/******************************************************************************
** older stuff below here
*/
#define REGISTERS struct sigcontext *sc
#define GET16(x) (x & 0xffff)
#define GET8L(x) (x & 0xff)
#define GET8H(x) ((x >> 8) & 0xff)
#define SET16(x, y) (x = (x & ~0xffff) | (y & 0xffff))
#define SET8L(x, y) (x = (x & ~0xff) | (y & 0xff))
#define SET8H(x, y) (x = (x & ~0xff00) | ((y & 0xff) << 8))
#define PUTVEC(s, o, x) (SET16(s, x >> 16), SET16(o, x))
#define GETVEC(s, o) MAKEVEC(GET16(s), GET16(o))
#define PUTPTR(s, o, x) (SET16(s, (x & 0xf0000) >> 4), SET16(o, x))
#define GETPTR(s, o) MAKEPTR(GET16(s), GET16(o))
#define VECPTR(x) MAKEPTR((x) >> 16, (x) & 0xffff)
inline static void
PUSH(u_short x, struct sigcontext *sc)
{
SET16(sc->sc_esp, GET16(sc->sc_esp) - 2);
*(u_short *)GETPTR(sc->sc_ss, sc->sc_esp) = x;
}
inline static u_short
POP(struct sigcontext *sc)
{
u_short x;
x = *(u_short *)GETPTR(sc->sc_ss, sc->sc_esp);
SET16(sc->sc_esp, GET16(sc->sc_esp) + 2);
return (x);
}

79
usr.bin/doscmd/setver.c Normal file
View File

@ -0,0 +1,79 @@
/*
* 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
*
* $Id: setver.c,v 1.2 1996/09/22 05:53:09 miff Exp $
*/
#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);
}

114
usr.bin/doscmd/signal.c Normal file
View File

@ -0,0 +1,114 @@
/*
* 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
*
* $Id: signal.c,v 1.5 1997/03/18 02:36:56 msmith Exp $
*/
#include "doscmd.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)
{
#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_sc.sc_efl & PSL_VM) {
saved_sigframe = &sf;
saved_regcontext = (regcontext_t *)&(sf.sf_sc);
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;
sigset_t set;
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;
sa.sa_mask = sigmask(SIGIO) | sigmask(SIGALRM);
sa.sa_flags = SA_ONSTACK;
sigaction(s, &sa, NULL);
sigaddset(&set, s);
sigprocmask(SIG_UNBLOCK, &set, 0);
}
}

50
usr.bin/doscmd/timer.c Normal file
View File

@ -0,0 +1,50 @@
/*
** No copyright?!
**
** $Id: timer.c,v 1.3 1996/09/22 15:42:59 miff Exp $
*/
#include "doscmd.h"
static void
int08(regcontext_t *REGS)
{
softint(0x1c);
}
static void
int1c(regcontext_t *REGS)
{
}
unsigned char timer;
static u_char
inb_timer(int port)
{
return (--timer);
}
void
timer_init(void)
{
u_long vec;
struct itimerval itv;
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);
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);
}

249
usr.bin/doscmd/trace.c Normal file
View File

@ -0,0 +1,249 @@
/*
* 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
*
* $Id: trace.c,v 1.3 1996/09/25 00:03:44 miff Exp $
*/
#include "doscmd.h"
#include "trap.h"
extern FILE *debugf;
int tmode = 0;
static u_short *saddr;
static u_char *iaddr, ibyte;
/* locals */
static void printtrace(regcontext_t *REGS, char *buf);
/*
* 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 enterint from VM86 mode:
* 1) Restore the trap flag from our saved flag state.
* 2) If we just finished a POPF or IRET unstruction, 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 *)N_GETPTR(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 *)N_GETPTR(R_SS, R_SP))[0],
((u_short *)N_GETPTR(R_SS, R_SP))[1],
((u_short *)N_GETPTR(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;
}
}
inline
showstate(long flags, long flag, char f)
{
putc((flags & flag) ? f : ' ', debugf);
}
static void
printtrace(regcontext_t *REGS, char *buf)
{
static int first = 1;
u_char *addr = (u_char *)N_GETPTR(R_CS, R_IP);
char *bigfmt = "%04x:%04x "
#if BIG_DEBUG
"%02x %02x %02x %02x %02x %02x "
#endif
"%-30s "
"%04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x ";
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, bigfmt,
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);
}

612
usr.bin/doscmd/trap.c Normal file
View File

@ -0,0 +1,612 @@
/*
* 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
*
* $Id: trap.c,v 1.10 1996/10/02 00:31:43 miff Exp $
*/
#include "doscmd.h"
#include "trap.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/%08x\n",
intnum, R_AH, R_CS, R_IP, ivec[intnum]);
switch (intnum) {
case 0x2f: /* multiplex interrupt */
int2f(&REGS->sc);
break;
case 0xff: /* doscmd special */
intff(REGS);
break;
default: /* should not get here */
if (vflag) dump_regs(REGS);
fatal("no interrupt set up for 0x%02x\n", intnum);
}
debug (D_ITRAPS|intnum, "\n");
return;
}
user_int:
debug (D_TRAPS|intnum, "INT %02x:%02x [%04x:%04x] %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 *)N_GETPTR(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 */
N_PUSH((R_FLAGS & ~PSL_I) | (R_EFLAGS & PSL_VIF ? PSL_I : 0), REGS);
N_PUSH(R_CS, REGS);
N_PUSH(R_IP, REGS);
R_EFLAGS &= ~PSL_VIF; /* disable interrupts */
N_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 *)GETPTR(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_sc);
if (!(R_EFLAGS && PSL_VM))
fatal("SIGBUS in the emulator\n");
if (sf->sf_code != 0) {
fatal("SIGBUS code %d, trapno: %d, err: %d\n",
sf->sf_code, sf->sf_sc.sc_trapno, sf->sf_sc.sc_err);
}
addr = (u_char *)GETPTR(R_CS, R_IP);
if (tmode)
resettrace(REGS);
if ((R_EFLAGS & (PSL_VIP | PSL_VIF)) == (PSL_VIP | PSL_VIF)) {
if (n_pending < 1) {
fatal("Pending interrupts out of sync\n");
exit(1);
}
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%x\n", R_EFLAGS);
R_IP++;
N_PUSH((R_FLAGS & ~PSL_I) | (R_EFLAGS & PSL_VIF ? PSL_I : 0), REGS);
break;
case IRET:
R_IP = N_POP(REGS); /* get new cs:ip off the stack */
R_CS = N_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++;
tempflags = N_POP(REGS); /* get flags from stack */
okflags = (PSL_ALLCC | PSL_T | PSL_D | PSL_V); /* flags we consider OK */
R_FLAGS = ((R_FLAGS & ~okflags) | /* keep state of non-OK flags */
(tempflags & okflags)); /* pop state of OK flags */
IntState = tempflags & PSL_I; /* restore pseudo PSL_I flag */
debug(D_TRAPS2, "popf -> 0x%x\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(N_GETVEC(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;
/* } */
/* FALLTHRU */
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_sc);
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_sc);
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 = sf->sf_code; /* XXX GROSTIC HACK ALERT */
#else
trapno = sc->sc_trapno;
#endif
if (trapno == T_BPTFLT)
intnum = 3;
else
intnum = 1;
N_PUSH((R_FLAGS & ~PSL_I) | (R_EFLAGS & PSL_VIF ? PSL_I : 0), REGS);
N_PUSH(R_CS, REGS);
N_PUSH(R_IP, REGS);
R_FLAGS &= ~PSL_T;
N_PUTVEC(R_CS, R_IP, ivec[intnum]);
doh:
if (tmode)
tracetrap(REGS);
}
void
breakpoint(struct sigframe *sf)
{
regcontext_t *REGS = (regcontext_t *)(&sf->sf_sc);
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_sc);
if (tmode)
resettrace(REGS);
/* debug(D_ALWAYS,"tick %d", update_counter); */
update_counter = 0; /* remember we've updated */
video_update(&REGS->sc);
hardint(0x08);
/* debug(D_ALWAYS,"\n"); */
if (tmode)
tracetrap(REGS);
}
void
sigill(struct sigframe *sf)
{
regcontext_t *REGS = (regcontext_t *)(&sf->sf_sc);
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_sc);
if (R_EFLAGS & PSL_VM) {
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);
}

83
usr.bin/doscmd/trap.h Normal file
View File

@ -0,0 +1,83 @@
/*
* 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
*
* $Id: trap.h,v 1.2 1996/09/22 05:53:11 miff Exp $
*/
#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 */

2193
usr.bin/doscmd/tty.c Normal file

File diff suppressed because it is too large Load Diff

154
usr.bin/doscmd/video.h Normal file
View File

@ -0,0 +1,154 @@
/*
* 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
*
* $Id: video.h,v 1.2 1996/09/22 05:53:12 miff Exp $
*/
/*
* Motorola 6845 Video Controller registers
*
* They are read by
* OUT port,code
* IN port+1,res
*
* They are written by
* OUT port,code
* OUT port+1,value
*/
#define MVC_TotHorzChar 0x00 /* Total Horizontal Character */
#define MVC_DispHorzChar 0x01 /* Display Horizontal Character */
#define MVC_HorzSyncChar 0x02 /* Horizontal sync signal after ...char */
#define MVC_HorzSyncDur 0x03 /* Duration of horizontal sync signal in char */
#define MVC_TotVertChar 0x04 /* Total Vertical Character */
#define MVC_AdjVertChar 0x05 /* Adjust Veritcal Character */
#define MVC_DispVertChar 0x06 /* Display Vertical Charcter */
#define MVC_VertSyncChar 0x07 /* Vertical sync signal after .. char */
#define MVC_InterlaceMode 0x08 /* Interlace Mode */
#define MVC_ScanLines 0x09 /* Number of scan lines per screen line */
#define MVC_CurStartLine 0x0a /* Starting line of screen cursor */
#define MVC_CurEndLine 0x0b /* Ending line of screen cursor */
#define MVC_CurHigh 0x0e /* High byte of cursor position */
#define MVC_CurLow 0x0f /* High byte of cursor position */
/*
* Additional MDA register
*/
#define MDA_StartDispPageLo 0x0c /* Starting address of displayed screen page (lo byte) */
#define MDA_StartDispPageHi 0x0d /* Starting address of displayed screen page (hi byte) */
#define MDA_BlinkCurAddrHi 0x0e /* Character address of blinking screen cursor (hi byte) */
#define MDA_BlinkCurAddrLo 0x0f /* Character address of blinking screen cursor (lo byte) */
#define MDA_LightPenHi 0x10 /* Light Pen Position (hi byte) */
#define MDA_LightPenLo 0x11 /* Light Pen Position (lo byte) */
#define MDA_Control 0x03b8 /* MDA Control Register Port */
#define MVC_Address 0x03b4 /* MVC Address Register */
#define MVC_Data 0x03b5 /* MVC Data Register */
#define MDA_VideoSeg 0xb800 /* Segmet address of video ram */
#define CGA_Control 0x03d8 /* CGA Control Register Port */
#define CGA_Status 0x03da /* CGA Control Register Port */
#define CVC_Address 0x03d4 /* CVC Address Register */
#define CVC_Data 0x03d5 /* CVC Data Register */
#define CGA_Black 0x0
#define CGA_Blue 0x1
#define CGA_Green 0x2
#define CGA_Cyan 0x3
#define CGA_Red 0x4
#define CGA_Magenta 0x5
#define CGA_Brown 0x6
#define CGA_LightGray 0x7
#define CGA_DarkGray 0x8
#define CGA_LightBlue 0x9
#define CGA_LightGreen 0xa
#define CGA_LightCyan 0xb
#define CGA_LightRed 0xc
#define CGA_LightMagenta 0xd
#define CGA_Yellow 0xe
#define CGA_White 0xf
#define VGA_Segment 0xa000 /* Starting Segment of VGA Memory */
#define V_int 0x10 /* interrupt for dealing with screen */
#define V_mode 0 /* code for setting new screen mode */
#define V_curtype 1 /* code for setting new cursor type */
#define V_setcur 2 /* code for addressing cursor */
#define V_readcur 3 /* code for reading cursor location */
#define V_readlp 4 /* code for reading light pen position */
#define V_setpage 5 /* code to select active page */
#define V_scrollup 6 /* code to scroll screen up */
#define V_scrolldn 7 /* code to scroll screen nown */
#define V_readch 8 /* code to read a character from screen */
#define V_writeach 9 /* code to write char and attributes */
#define V_writech 10 /* code to write character only */
#define V_setpal 11 /* code to set new setpal or border */
#define V_wdot 12 /* code to write a dot */
#define V_rdot 13 /* code to read a dot */
#define V_wtty 14 /* code to write as if teletype */
#define V_state 15 /* code to find current screen status */
#define VM_40x25 0x00
#define VM_80x25 0x02
#define VM_320x200x4 0x04
#define VM_640x200x2 0x06
#define VM_80x25mono 0x07
#define VM_320x200x16 0x0d
#define VM_640x200x16 0x0e
#define VM_640x350mono 0x0f
#define VM_640x350x16 0x10
#define VM_640x480x2 0x11
#define VM_640x480x16 0x12
#define VM_320x200x256 0x13
#define VM_80x30 0x50
#define VM_80x43 0x51
#define VM_80x60 0x52
#define VM_132x25 0x53
#define VM_132x30 0x54
#define VM_132x43 0x55
#define VM_132x60 0x56
#define VM_132x25h 0x57
#define VM_132x30h 0x58
#define VM_132x43h 0x59
#define VM_132x60h 0x5a
#define VM_800x600x16 0x5b
#define VM_640x400x256 0x5c
#define VM_640x480x256 0x5d
#define VM_800x600x256 0x5e
#define VM_1024x768x16 0x5f
#define VM_1024x768x4 0x60
#define VM_768x1024x16 0x61
#define VM_1024x768x256 0x62
#define VM_VGA VM_640x480x256
#define VM_EVGA VM_800x600x256
#define VM_SVGAportrait VM_768x1024x16
#define VM_SVGA16 VM_1024x768x16
#define VM_SVGA256 VM_1024x768x256

322
usr.bin/doscmd/vparams.h Normal file
View File

@ -0,0 +1,322 @@
/*
* 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
*/
unsigned char videoparams[][64] = {
{ 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, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13, 0x14,
0x15, 0x16, 0x17, 0x08, 0x00, 0x0f, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, 0xff,
},
{ 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, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13, 0x14,
0x15, 0x16, 0x17, 0x08, 0x00, 0x0f, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, 0xff,
},
{ 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, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13, 0x14,
0x15, 0x16, 0x17, 0x08, 0x00, 0x0f, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, 0xff,
},
{ 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, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13, 0x14,
0x15, 0x16, 0x17, 0x08, 0x00, 0x0f, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, 0xff,
},
{ 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,
},
{ 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,
},
{ 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,
},
{ 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,
},
{ 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,
},
{ 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,
},
{ 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,
},
{ 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,
},
{ 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,
},
{ 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,
},
{ 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,
},
{ 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,
},
{ 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,
},
{ 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,
},
{ 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,
},
{ 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,
},
{ 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,
},
{ 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,
},
{ 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,
},
{ 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,
},
{ 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,
},
{ 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,
},
{ 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,
},
{ 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,
},
{ 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,
},
};

65
usr.bin/doscmd/xms.c Normal file
View File

@ -0,0 +1,65 @@
/*
** No copyright?!
**
** $Id: xms.c,v 1.3 1996/09/22 15:43:01 miff Exp $
*/
#include "doscmd.h"
u_long xms_vector;
int
int2f_43(regcontext_t *REGS)
{
switch (R_AL) {
case 0x00: /* installation check */
R_AL = 0x80;
break;
case 0x10: /* get handler address */
N_PUTVEC(R_ES, R_BX, xms_vector);
break;
default:
return (0);
}
return (1);
}
/*
** XXX DANGER WILL ROBINSON!
*/
static void
xms_entry(regcontext_t *REGS)
{
switch (R_AH) {
case 0x00: /* get version number */
R_AX = 0x0300; /* 3.0 */
R_BX = 0x0001; /* internal revision 0.1 */
R_DX = 0x0001; /* HMA exists */
break;
default:
debug(D_ALWAYS, "XMS %02x\n", R_AH);
R_AX = 0;
break;
}
}
static u_char xms_trampoline[] = {
0xeb, /* JMP 5 */
0x03,
0x90, /* NOP */
0x90, /* NOP */
0x90, /* NOP */
0xf4, /* HLT */
0xcb, /* RETF */
};
void
xms_init(void)
{
xms_vector = insert_generic_trampoline(
sizeof(xms_trampoline), xms_trampoline);
register_callback(xms_vector + 5, xms_entry, "xms");
}