[Coco] os9/drivewire driver: success!
John W. Linville
linville at tuxdriver.com
Mon Nov 9 15:12:52 EST 2009
On Mon, Nov 09, 2009 at 01:53:47PM -0500, Aaron Wolfe wrote:
> I think a PTY is a great idea. Doing the terminal support in a
> proper terminal program like minicom makes more sense than writing
> my own client. My only concern is that im not sure if Windows users
> will be left out in the cold, but that doesnt bother me too much tbh.
> Mac os x should support pty with a little wrangling.
I'm pretty sure OSX has at least some version of PTY support.
I Googled a bit for win32 APIs (of which I am blissfully ignorant)
but didn't find anything specific. However, there seem to be some
implementations out ther -- maybe cygwin or uwin or something would
support it?
> If you have anything in c that does a pty, i'd love to see the code.
> I'm much more comfortable in c than in os9 assembler, but no need to
> duplicate work if i don't have to.
I'll attach the source for the MESS code I use. It seems reasonably
clear, but feel free to ask questions if you haven't MESSed your
brain yet. :-)
> Thanks, i should have thought of using a pty, glad you did!
Hey, anything I can do to get you to make my life better... :-)
John
--
John W. Linville Someday the world will need a hero, and you
linville at tuxdriver.com might be all we have. Be ready.
-------------- next part --------------
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/select.h>
#include "driver.h"
#include "pseudotty.h"
struct pseudotty pty[MAX_PTY] = { {0, }, };
void pseudotty_alloc(running_machine *machine, int which)
{
char msg[20];
char *slave;
struct pseudotty *p = pty + which;
p->fd = posix_openpt(O_RDWR);
grantpt(p->fd);
unlockpt(p->fd);
slave = ptsname(p->fd);
printf("Debug pseudo-terminal %d slave is %s\n", which, slave);
sprintf(msg, "MAME debug port %d\n", which);
write(p->fd, msg, strlen(msg));
/* request callback upon exiting */
add_exit_callback(machine, pseudotty_exit);
}
void pseudotty_exit(running_machine *machine)
{
int which;
for (which = 0; which < MAX_PTY; which++) {
close(pty[which].fd);
}
}
int pseudotty_read(int which, int offset)
{
char line[80];
char data = 0x5a;
struct timeval timeout;
fd_set readfds;
struct pseudotty *p = pty + which;
switch (offset) {
case PTY_DATA:
if (!p->rx_pending) {
fprintf(stderr, "%s: buffer underrun on %d\n",
__func__, which);
break;
}
data = p->buf[p->head++];
p->rx_pending--;
break;
case PTY_CONTROL:
if (!p->rx_pending) {
/* Try to read from pty */
FD_ZERO(&readfds);
FD_SET(p->fd, &readfds);
timeout.tv_sec = timeout.tv_usec = 0;
if (select(p->fd + 1, &readfds, NULL, NULL, &timeout)
< 0) {
sprintf(line, "%s : %s : %d ", __func__,
__FILE__, __LINE__);
perror(line);
} else if (FD_ISSET(p->fd, &readfds)) {
p->head = 0;
p->rx_pending = read(p->fd, p->buf,
sizeof(p->buf));
if (p->rx_pending == -1) {
p->rx_pending = 0;
sprintf(line, "%s : %s : %d ", __func__,
__FILE__, __LINE__);
perror(line);
}
}
}
data = p->rx_pending;
break;
default:
fprintf(stderr, "%s: read from bad offset %d on %d\n", __FILE__,
offset, which);
}
return (int)data;
}
void pseudotty_write(int which, int offset, int data)
{
char d = (char)data;
struct pseudotty *p = pty + which;
switch (offset) {
case PTY_DATA:
write(p->fd, &d, 1);
break;
case PTY_CONTROL:
p->rx_pending = p->head = 0;
break;
default:
fprintf(stderr, "%s: write to bad offset %d on %d\n", __FILE__,
offset, which);
}
}
READ8_HANDLER( pseudotty_0_r ) { return pseudotty_read(0, offset); }
READ8_HANDLER( pseudotty_1_r ) { return pseudotty_read(1, offset); }
WRITE8_HANDLER( pseudotty_0_w ) { pseudotty_write(0, offset, data); }
WRITE8_HANDLER( pseudotty_1_w ) { pseudotty_write(1, offset, data); }
More information about the Coco
mailing list