gsplus/src/scc_macdriver.c

200 lines
4.3 KiB
C
Raw Permalink Normal View History

2015-11-05 20:23:46 +00:00
/*
GSPLUS - Advanced Apple IIGS Emulator Environment
Based on the KEGS emulator written by Kent Dickey
See COPYRIGHT.txt for Copyright information
See LICENSE.txt for license (GPL v2)
*/
2015-11-05 20:23:46 +00:00
/* This file contains the Mac serial calls */
#ifdef MAC
2015-11-05 20:23:46 +00:00
#include "defc.h"
#include "scc.h"
#include <termios.h>
2015-11-05 20:23:46 +00:00
extern Scc scc_stat[2];
extern word32 g_c025_val;
int scc_serial_mac_init(int port) {
char str_buf[1024];
Scc *scc_ptr;
int state;
int fd;
2015-11-05 20:23:46 +00:00
scc_ptr = &(scc_stat[port]);
2015-11-05 20:23:46 +00:00
scc_ptr->state = 0; /* mark as uninitialized */
2015-11-05 20:23:46 +00:00
/*sprintf(&str_buf[0], "/dev/tty.USA19QW11P1.1"); */
sprintf(&str_buf[0], "/dev/tty.USA19H181P1.1");
/* HACK: fix this... */
2015-11-05 20:23:46 +00:00
fd = open(&str_buf[0], O_RDWR | O_NONBLOCK);
2015-11-05 20:23:46 +00:00
scc_ptr->host_handle = (void *)fd;
scc_ptr->host_handle2 = 0;
2015-11-05 20:23:46 +00:00
printf("scc_serial_mac_init %d called, fd: %d\n", port, fd);
2015-11-05 20:23:46 +00:00
if(fd < 0) {
scc_ptr->host_handle = (void *)-1;
return -1;
}
2015-11-05 20:23:46 +00:00
scc_serial_mac_change_params(port);
2015-11-05 20:23:46 +00:00
state = 2; /* raw serial */
scc_ptr->state = state;
2015-11-05 20:23:46 +00:00
return state;
2015-11-05 20:23:46 +00:00
}
void scc_serial_mac_change_params(int port) {
struct termios termios_buf;
Scc *scc_ptr;
int fd;
int csz;
int ret;
2015-11-05 20:23:46 +00:00
scc_ptr = &(scc_stat[port]);
2015-11-05 20:23:46 +00:00
fd = (intptr_t)scc_ptr->host_handle;
printf("scc_serial_mac_change_parms port: %d, fd: %d\n", port, fd);
if(fd <= 0) {
return;
}
2015-11-05 20:23:46 +00:00
ret = tcgetattr(fd, &termios_buf);
if(ret != 0) {
printf("tcgetattr port%d ret: %d\n", port, ret);
}
2015-11-05 20:23:46 +00:00
#if 1
printf("baudrate: %d, iflag:%x, oflag:%x, cflag:%x, lflag:%x\n",
(int)termios_buf.c_ispeed, (int)termios_buf.c_iflag,
(int)termios_buf.c_oflag, (int)termios_buf.c_cflag,
(int)termios_buf.c_lflag);
2015-11-05 20:23:46 +00:00
#endif
memset(&termios_buf, 0, sizeof(struct termios));
cfmakeraw(&termios_buf);
cfsetspeed(&termios_buf, scc_ptr->baud_rate);
csz = scc_ptr->char_size;
termios_buf.c_cflag = CREAD | CLOCAL;
termios_buf.c_cflag |= (csz == 5) ? CS5 :
(csz == 6) ? CS6 :
(csz == 7) ? CS7 :
CS8;
switch((scc_ptr->reg[4] >> 2) & 0x3) {
case 2: // 1.5 stop bits
termios_buf.c_cflag |= CSTOPB; /* no 1.5 stop bit setting.*/
break;
case 3: // 2 stop bits
termios_buf.c_cflag |= CSTOPB;
break;
}
switch((scc_ptr->reg[4]) & 0x3) {
case 1: // Odd parity
termios_buf.c_cflag |= (PARENB | PARODD);
break;
case 3: // Even parity
termios_buf.c_cflag |= PARENB;
break;
}
/* always enabled DTR and RTS control */
termios_buf.c_cflag |= CDTR_IFLOW | CRTS_IFLOW;
printf("fd: %d, baudrate: %d, iflag:%x, oflag:%x, cflag:%x, lflag:%x\n",
fd, (int)termios_buf.c_ispeed, (int)termios_buf.c_iflag,
(int)termios_buf.c_oflag, (int)termios_buf.c_cflag,
(int)termios_buf.c_lflag);
ret = tcsetattr(fd, TCSANOW, &termios_buf);
if(ret != 0) {
printf("tcsetattr ret: %d\n", ret);
}
2015-11-05 20:23:46 +00:00
}
void scc_serial_mac_fill_readbuf(int port, int space_left, double dcycs) {
byte tmp_buf[256];
Scc *scc_ptr;
int fd;
int i;
int ret;
scc_ptr = &(scc_stat[port]);
fd = (intptr_t)scc_ptr->host_handle;
if(fd <= 0) {
return;
}
/* Try reading some bytes */
space_left = MIN(space_left, 256);
ret = read(fd, tmp_buf, space_left);
if(ret > 0) {
for(i = 0; i < ret; i++) {
scc_add_to_readbuf(port, tmp_buf[i], dcycs);
}
}
2015-11-05 20:23:46 +00:00
}
void scc_serial_mac_empty_writebuf(int port) {
Scc *scc_ptr;
int fd;
int rdptr;
int wrptr;
int done;
int ret;
int len;
scc_ptr = &(scc_stat[port]);
fd = (intptr_t)scc_ptr->host_handle;
if(fd <= 0) {
return;
}
/* Try writing some bytes */
done = 0;
while(!done) {
rdptr = scc_ptr->out_rdptr;
wrptr = scc_ptr->out_wrptr;
if(rdptr == wrptr) {
//printf("...rdptr == wrptr\n");
done = 1;
break;
}
len = wrptr - rdptr;
if(len < 0) {
len = SCC_OUTBUF_SIZE - rdptr;
}
if(len > 32) {
len = 32;
}
if(len <= 0) {
done = 1;
break;
}
ret = write(fd, &(scc_ptr->out_buf[rdptr]), len);
if(ret <= 0) {
done = 1;
break;
} else {
rdptr = rdptr + ret;
if(rdptr >= SCC_OUTBUF_SIZE) {
rdptr = rdptr - SCC_OUTBUF_SIZE;
}
scc_ptr->out_rdptr = rdptr;
}
}
2015-11-05 20:23:46 +00:00
}
#endif /* MAC */