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:
parent
a98421fc82
commit
90c38ed200
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=27999
342
usr.bin/doscmd/AsyncIO.c
Normal file
342
usr.bin/doscmd/AsyncIO.c
Normal 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
50
usr.bin/doscmd/AsyncIO.h
Normal 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
21
usr.bin/doscmd/PROBLEMS
Normal 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
|
89
usr.bin/doscmd/ParseBuffer.c
Normal file
89
usr.bin/doscmd/ParseBuffer.c
Normal 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
37
usr.bin/doscmd/README
Normal 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
|
89
usr.bin/doscmd/README.booting_dos
Normal file
89
usr.bin/doscmd/README.booting_dos
Normal 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
329
usr.bin/doscmd/bios.c
Normal 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
120
usr.bin/doscmd/callback.c
Normal 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
13
usr.bin/doscmd/callback.h
Normal 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
291
usr.bin/doscmd/cmos.c
Normal 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
167
usr.bin/doscmd/com.h
Normal 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
265
usr.bin/doscmd/config.c
Normal 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
70
usr.bin/doscmd/cpu.c
Normal 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
43
usr.bin/doscmd/crt0.c
Normal 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
970
usr.bin/doscmd/cwd.c
Normal 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
109
usr.bin/doscmd/cwd.h
Normal 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
193
usr.bin/doscmd/debug.c
Normal 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
100
usr.bin/doscmd/disktab.c
Normal 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
110
usr.bin/doscmd/dispatch.h
Normal 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
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
402
usr.bin/doscmd/dos.h
Normal 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
892
usr.bin/doscmd/doscmd.c
Normal 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 *)≻
|
||||
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
272
usr.bin/doscmd/doscmd.h
Normal 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);
|
||||
|
98
usr.bin/doscmd/doscmd_loader.c
Normal file
98
usr.bin/doscmd/doscmd_loader.c
Normal 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
423
usr.bin/doscmd/exe.c
Normal 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
407
usr.bin/doscmd/font.h
Normal 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
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
55
usr.bin/doscmd/instbsdi.c
Normal 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
139
usr.bin/doscmd/int.c
Normal 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
277
usr.bin/doscmd/int10.c
Normal 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
873
usr.bin/doscmd/int13.c
Normal 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
510
usr.bin/doscmd/int14.c
Normal 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
140
usr.bin/doscmd/int16.c
Normal 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
191
usr.bin/doscmd/int17.c
Normal 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
110
usr.bin/doscmd/int1a.c
Normal 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
167
usr.bin/doscmd/int2f.c
Normal 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
805
usr.bin/doscmd/intff.c
Normal 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
325
usr.bin/doscmd/mem.c
Normal 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
300
usr.bin/doscmd/mouse.c
Normal 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
68
usr.bin/doscmd/mouse.h
Normal 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
34
usr.bin/doscmd/net.c
Normal 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
405
usr.bin/doscmd/port.c
Normal 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
222
usr.bin/doscmd/register.h
Normal 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
79
usr.bin/doscmd/setver.c
Normal 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
114
usr.bin/doscmd/signal.c
Normal 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
50
usr.bin/doscmd/timer.c
Normal 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
249
usr.bin/doscmd/trace.c
Normal 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
612
usr.bin/doscmd/trap.c
Normal 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(®S->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(®S->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
83
usr.bin/doscmd/trap.h
Normal 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
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
154
usr.bin/doscmd/video.h
Normal 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
322
usr.bin/doscmd/vparams.h
Normal 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
65
usr.bin/doscmd/xms.c
Normal 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");
|
||||
}
|
Loading…
Reference in New Issue
Block a user