[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