summaryrefslogtreecommitdiffstats
path: root/usr.bin/doscmd
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>1999-10-13 23:48:35 +0000
committerimp <imp@FreeBSD.org>1999-10-13 23:48:35 +0000
commit54845d7d91ede831c0515e3331be2f1317c7b214 (patch)
tree3fe2565dcb8749da3cfbcc041bf04838e5f0a964 /usr.bin/doscmd
parent83dbf599426ca60aaee525e0e5f34b80b2cb8ca8 (diff)
downloadFreeBSD-src-54845d7d91ede831c0515e3331be2f1317c7b214.zip
FreeBSD-src-54845d7d91ede831c0515e3331be2f1317c7b214.tar.gz
Allow in/out to work in DOS programs.
Submitted by: Parag Patel PR: bin/8486
Diffstat (limited to 'usr.bin/doscmd')
-rw-r--r--usr.bin/doscmd/config.c15
-rw-r--r--usr.bin/doscmd/doscmd.125
-rw-r--r--usr.bin/doscmd/doscmd.c37
-rw-r--r--usr.bin/doscmd/doscmd.h5
-rw-r--r--usr.bin/doscmd/port.c15
5 files changed, 94 insertions, 3 deletions
diff --git a/usr.bin/doscmd/config.c b/usr.bin/doscmd/config.c
index d20aa15..dd1316f 100644
--- a/usr.bin/doscmd/config.c
+++ b/usr.bin/doscmd/config.c
@@ -238,6 +238,21 @@ init_hard:
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))) {
diff --git a/usr.bin/doscmd/doscmd.1 b/usr.bin/doscmd/doscmd.1
index 4d039a4..0fa73f4 100644
--- a/usr.bin/doscmd/doscmd.1
+++ b/usr.bin/doscmd/doscmd.1
@@ -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
diff --git a/usr.bin/doscmd/doscmd.c b/usr.bin/doscmd/doscmd.c
index 77b9e13..4340731 100644
--- a/usr.bin/doscmd/doscmd.c
+++ b/usr.bin/doscmd/doscmd.c
@@ -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);
+}
diff --git a/usr.bin/doscmd/doscmd.h b/usr.bin/doscmd/doscmd.h
index 44d06c9..8d5af631 100644
--- a/usr.bin/doscmd/doscmd.h
+++ b/usr.bin/doscmd/doscmd.h
@@ -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);
diff --git a/usr.bin/doscmd/port.c b/usr.bin/doscmd/port.c
index 9159321..fe5b5a8 100644
--- a/usr.bin/doscmd/port.c
+++ b/usr.bin/doscmd/port.c
@@ -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
*/
OpenPOWER on IntegriCloud