Allow in/out to work in DOS programs.

Submitted by: Parag Patel
PR: bin/8486
This commit is contained in:
imp 1999-10-13 23:48:35 +00:00
parent 83dbf59942
commit 54845d7d91
5 changed files with 94 additions and 3 deletions

View File

@ -238,6 +238,21 @@ read_config(FILE *fp)
fprintf(stderr, "Boot drive must be either A: or C:\n");
quit(1);
}
} else if (!strcasecmp(av[0], "portmap")) {
int p, c;
if (ac < 2 || ac > 3 || !isdigit(av[1][0]) ||
(ac == 3 && !isdigit(av[2][0]))) {
fprintf(stderr, "Usage: portmap port [count]\n");
quit(1);
}
p = strtol(av[1], 0, 0);
c = (ac == 3) ? strtol(av[2], 0, 0) : 1;
iomap_port(p, c);
while (c-- > 0) {
define_input_port_handler(p++, inb_port);
define_output_port_handler(p++, outb_port);
}
} else if (!strcasecmp(av[0], "setver")) {
int v;
if (ac != 3 || !(v = strtol(av[2], 0, 0))) {

View File

@ -188,6 +188,18 @@ to
.\"
.\"
.\"
.It Fl p Ar port Ns Xo
.Op : Ns Ar cnt
.Xc
Map the requested io
.Ar port
(with optional range up to to
.Ar port+cnt Ns No -1 )
to the real hardware I/O port(s).
This will likely require root privs to access them.
.\"
.\"
.\"
.It Fl P
Enable tracing of io port calls (such as
.Li inb ,
@ -434,6 +446,19 @@ This code is lightly tested and may not suit all needs.
.\"
.\"
.\"
.It Cm portmap Xo
.Ar port
.Op Ar count
.Xc
Map the requested io
.Ar port
(with optional range up to to
.Ar port+count Ns No -1 )
to the real hardware I/O port(s).
This will likely require root privs to access them.
.\"
.\"
.\"
.It Cm "setver command version"
Cause doscmd, when emulating DOS, to report
.Cm version

View File

@ -480,7 +480,7 @@ do_args(int argc, char *argv[])
FILE *fp;
char *col;
while ((c = getopt (argc, argv, "234Oc:TkCIEMPRLAU:S:HDtzvVxXYfbri:o:d:")) != -1) {
while ((c = getopt (argc, argv, "234Oc:TkCIEMPRLAU:S:HDtzvVxXYfbri:o:p:d:")) != -1) {
switch (c) {
case 'd':
if (fp = fopen(optarg, "w")) {
@ -515,6 +515,7 @@ do_args(int argc, char *argv[])
i = strtol(col, 0, 0);
}
p = strtol(optarg, 0, 0);
iomap_port(p, i);
while (i-- > 0)
define_input_port_handler(p++, inb_traceport);
@ -526,10 +527,25 @@ do_args(int argc, char *argv[])
i = strtol(col, 0, 0);
}
p = strtol(optarg, 0, 0);
iomap_port(p, i);
while (i-- > 0)
define_output_port_handler(p++, outb_traceport);
break;
case 'p':
i = 1;
if (col = strchr(optarg, ':')) {
*col++ = 0;
i = strtol(col, 0, 0);
}
p = strtol(optarg, 0, 0);
iomap_port(p, i);
while (i-- > 0) {
define_input_port_handler(p++, inb_port);
define_output_port_handler(p++, outb_port);
}
break;
case 'r':
raw_kbd = 1;
@ -834,6 +850,9 @@ struct io_range {
int enable;
};
/* This is commented out as it is never called. Turn it back on if needed.
*/
#if COMMENTED_OUT
static void
iomap_init(void)
{
@ -844,6 +863,7 @@ iomap_init(void)
{ 0x1c80, 2, 1 }, /* 0x1c80 - 0x1c81 */
{ 0x2c80, 2, 1 }, /* 0x2c80 - 0x2c81 */
{ 0x3c80, 2, 1 }, /* 0x3c80 - 0x3c81 */
{ 0x378, 8, 1 }, /* 0x378 - 0x37F */
{ 0x3c4, 2, 1 }, /* 0x3c4 - 0x3c5 */
{ 0x3c5, 2, 1 }, /* 0x3ce - 0x3cf */
#else
@ -851,8 +871,21 @@ iomap_init(void)
#endif
{ 0, 0, 0 }
};
for (i = 0; io[i].length; i++)
if (i386_set_ioperm(io[i].start, io[i].length, io[i].enable) < 0)
err(1, "i386_set_ioperm");
}
#endif
/* This is used to map in only the specified port range, instead of all
the ports or only certain port ranges.
*/
void
iomap_port(int port, int count)
{
if (i386_set_ioperm(port, count, 1) < 0)
err(1, "i386_set_ioperm");
debug(D_PORT,"mapped I/O port: port=%#x count=%d\n", port, count);
}

View File

@ -150,7 +150,8 @@ 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 *);
extern void iomap_port(int port, int count);
/* signal.c */
extern struct sigframe *saved_sigframe;
extern regcontext_t *saved_regcontext;
@ -288,4 +289,6 @@ void video_setborder(int);
void outb_traceport(int, unsigned char);
unsigned char inb_traceport(int);
void outb_port(int, unsigned char);
unsigned char inb_port(int);

View File

@ -158,6 +158,21 @@ inb_traceport(int port)
return(byte);
}
/*
* Real input/output to (hopefully) iomapped port
*/
void
outb_port(int port, unsigned char byte)
{
out(port, byte);
}
unsigned char
inb_port(int port)
{
return in(port);
}
/*
* Fake input/output ports
*/