case 0:
tmp = (c->pra & c->dra) | (c->dra ^ 0xff);
#ifdef SERIAL_PORT
- if (currprefs.use_serial) {
- tmp &= 7;
- tmp |= serial_readstatus(c->dra) & 0xf8;
- }
+ tmp |= serial_readstatus(tmp, c->dra);
#endif
#ifdef PARALLEL_PORT
if (isprinter() > 0) {
write_ciab_serial(val, c->pra, c->dra, c->dra);
c->pra = val;
#ifdef SERIAL_PORT
- if (currprefs.use_serial)
- serial_writestatus(c->pra, c->dra);
+ serial_writestatus(c->pra, c->dra);
#endif
#ifdef PARALLEL_PORT
if (isprinter() < 0) {
extern void serial_dtr_on (void);
extern uae_u16 SERDATR (void);
-extern int SERDATS (void);
extern void SERPER (uae_u16 w);
extern void SERDAT (uae_u16 w);
extern uae_u8 serial_writestatus (uae_u8, uae_u8);
-extern uae_u8 serial_readstatus (uae_u8);
+extern uae_u8 serial_readstatus (uae_u8, uae_u8);
extern void serial_uartbreak (int);
extern void serial_rbf_clear (void);
extern uae_u16 serdat;
extern void serial_rethink(void);
extern int uaeser_getdatalength (void);
-extern int uaeser_getbytespending (void*);
extern int uaeser_open (void*, void*, int);
extern void uaeser_close (void*);
extern int uaeser_read (void*, uae_u8 *data, uae_u32 len);
: Software Foundation.
Authors : os, m
Created : 2007-08-27 13:55:49
- Updated : 2022-12-03 11:27:12
+ Updated : 2022-12-06 12:23:10
Comment : RetroPlatform Player interprocess communication include file
*****************************************************************************/
#define RP_IPC_TO_HOST_DEVICEWRITEBYTE (WM_APP + 48) // introduced in RetroPlatform API 10.0
#define RP_IPC_TO_HOST_PRIVATE_CANTYPECLIPB (WM_APP + 49) // introduced in RetroPlatform API 10.0
#define RP_IPC_TO_HOST_DEVICEWRITEBYTES (WM_APP + 50) // introduced in RetroPlatform API 10.1
+#define RP_IPC_TO_HOST_DEVICESETSIGNALS (WM_APP + 51) // introduced in RetroPlatform API 10.1
// ****************************************************************************
// Host-to-Guest Messages
#define RP_IPC_TO_GUEST_SETCURSORPOSITION (WM_APP + 246) // introduced in RetroPlatform API 7.9
#define RP_IPC_TO_GUEST_PRIVATE_TEXTSELMENU (WM_APP + 247) // introduced in RetroPlatform API 7.10
#define RP_IPC_TO_GUEST_EXECUTE (WM_APP + 248) // introduced in RetroPlatform API 10.0
+#define RP_IPC_TO_GUEST_DEVICEWRITEBYTE (WM_APP + 249) // introduced in RetroPlatform API 10.1
+#define RP_IPC_TO_GUEST_DEVICESETSIGNALS (WM_APP + 250) // introduced in RetroPlatform API 10.1
// ****************************************************************************
// Message Data Structures and Defines
#define RP_READBYTE_BYTEMASK 0x000000FF // byte mask
+// RP_IPC_TO_GUEST_DEVICESETSIGNALS flags
+#define RP_SIGNAL_CTS 0x00000001 // Clear To Send
+#define RP_SIGNAL_CD 0x00000002 // Carrier Detect
+#define RP_SIGNAL_DSR 0x00000004 // Data Set Ready
+#define RP_SIGNAL_RI 0x00000008 // Ring Indicator
+// RP_IPC_TO_HOST_DEVICESETSIGNALS flags
+#define RP_SIGNAL_RTS 0x00000010 // Request To Send
+#define RP_SIGNAL_DTR 0x00000020 // Data Terminal Ready
+
+
// Legacy Compatibility
#ifndef RP_NO_LEGACY
// Changed in 7.0
int rp_screenmode = 0;
int rp_inputmode = 0;
int rp_printer = 0;
+int rp_modem = 0;
int log_rp = 2;
static int rp_revision, rp_version, rp_build;
static int rp_printeropen = 0;
+static int rp_modemopen = 0;
static int max_horiz_dbl = RES_HIRES;
static int max_vert_dbl = VRES_DOUBLE;
case RP_IPC_TO_GUEST_SENDMOUSEEVENTS: return _T("RP_IPC_TO_GUEST_SENDMOUSEEVENTS");
case RP_IPC_TO_GUEST_SHOWDEBUGGER: return _T("RP_IPC_TO_GUEST_SHOWDEBUGGER");
case RP_IPC_TO_GUEST_EXECUTE: return _T("RP_IPC_TO_GUEST_EXECUTE");
+ case RP_IPC_TO_GUEST_DEVICEWRITEBYTE: return _T("RP_IPC_TO_GUEST_DEVICEWRITEBYTE");
+ case RP_IPC_TO_GUEST_DEVICESETSIGNALS: return _T("RP_IPC_TO_GUEST_DEVICESETSIGNALS");
default: return _T("UNKNOWN");
}
}
}
}
+extern bool serreceive_external(uae_u16);
+static int rp_readmodemint(WPARAM wp, LPARAM lp)
+{
+ if (wp != MAKEWORD(RP_DEVICECATEGORY_MODEM, 0)) {
+ return 0;
+ }
+ uae_u8 b = (uae_u8)lp;
+ bool v = serreceive_external(b | 0x100);
+ return v ? 1 : -1;
+}
+
+static bool modem_cts, modem_cd, modem_ri, modem_dsr;
+void rp_readmodemstatus(bool *dsr, bool *cd, bool *cts, bool *ri)
+{
+ *dsr = modem_dsr;
+ *cd = modem_cd;
+ *cts = modem_cts;
+ *ri = modem_ri;
+}
+static int rp_readmodemstatusint(WPARAM wp, LPARAM lp)
+{
+ if (wp != MAKEWORD(RP_DEVICECATEGORY_MODEM, 0)) {
+ return 0;
+ }
+ uae_u16 mask = LOWORD(lp);
+ uae_u16 val = HIWORD(lp);
+ if (mask & RP_SIGNAL_CTS) {
+ modem_cts = (val & RP_SIGNAL_CTS) != 0;
+ }
+ if (mask & RP_SIGNAL_RI) {
+ modem_ri = (val & RP_SIGNAL_RI) != 0;
+ }
+ if (mask & RP_SIGNAL_DSR) {
+ modem_dsr = (val & RP_SIGNAL_DSR) != 0;
+ }
+ if (mask & RP_SIGNAL_CD) {
+ modem_cd = (val & RP_SIGNAL_CD) != 0;
+ }
+ return 1;
+}
+
static int dosexecute(TCHAR *file, TCHAR *currentdir, TCHAR *parms, uae_u32 stack, uae_s32 priority, uae_u32 id, uae_u32 flags, uae_u8 *bin, uae_u32 binsize)
{
int ret = filesys_shellexecute2(file, currentdir, parms, stack, priority, id, flags, bin, binsize, dos_execute_callback, NULL);
return 1;
case RP_IPC_TO_GUEST_EXECUTE:
return execute(pData);
+ case RP_IPC_TO_GUEST_DEVICEWRITEBYTE:
+ return rp_readmodemint(wParam, lParam);
+ case RP_IPC_TO_GUEST_DEVICESETSIGNALS:
+ return rp_readmodemstatusint(wParam, lParam);
}
return FALSE;
}
device_add_vsync_pre(rp_vsync);
}
+bool rp_ismodem(void)
+{
+ return rp_modem != 0;
+}
+void rp_writemodem(uae_u8 v)
+{
+ if (!initialized) {
+ return;
+ }
+ if (!rp_modemopen) {
+ rp_modemstate(1);
+ }
+ WPARAM unit = MAKEWORD(RP_DEVICECATEGORY_MODEM, 0);
+ RPSendMessagex(RP_IPC_TO_HOST_DEVICEWRITEBYTE, unit, v, NULL, 0, &guestinfo, NULL);
+}
+void rp_modemstate(int state)
+{
+ if (!initialized) {
+ return;
+ }
+ if (state == rp_modemopen) {
+ return;
+ }
+ WPARAM unit = MAKEWORD(RP_DEVICECATEGORY_MODEM, 0);
+ if (state) {
+ write_log(_T("RP: modem open\n"));
+ RPSendMessagex(RP_IPC_TO_HOST_DEVICEOPEN, unit, 0, NULL, 0, &guestinfo, NULL);
+ } else {
+ write_log(_T("RP: modem close\n"));
+ RPSendMessagex(RP_IPC_TO_HOST_DEVICECLOSE, unit, 0, NULL, 0, &guestinfo, NULL);
+ }
+ rp_modemopen = state;
+}
+void rp_writemodemstatus(bool rts, bool rtschanged, bool dtr, bool dtrchanged)
+{
+ if (!initialized) {
+ return;
+ }
+ WPARAM unit = MAKEWORD(RP_DEVICECATEGORY_MODEM, 0);
+ LPARAM l = MAKELONG((rtschanged ? RP_SIGNAL_RTS :0) | (dtrchanged ? RP_SIGNAL_DTR : 0), (rts ? RP_SIGNAL_RTS : 0) | (dtr ? RP_SIGNAL_DTR : 0));
+ RPSendMessagex(RP_IPC_TO_HOST_DEVICESETSIGNALS, unit, l, NULL, 0, &guestinfo, NULL);
+
+}
bool rp_isprinter(void)
{
}
void rp_writeprinter(uae_char *b, int len)
{
- if (!initialized)
+ if (!initialized) {
return;
+ }
WPARAM unit = MAKEWORD(RP_DEVICECATEGORY_PRINTER, 0);
if (!b) {
if (rp_printeropen) {
extern bool rp_isprinter(void);
extern bool rp_isprinteropen(void);
extern void rp_writeprinter(uae_char*, int);
+extern bool rp_ismodem(void);
+extern void rp_writemodem(uae_u8);
+extern void rp_modemstate(int);
+extern void rp_writemodemstatus(bool, bool, bool, bool);
+extern void rp_readmodemstatus(bool*,bool*,bool*,bool*);
extern TCHAR *rp_param;
extern int rp_rpescapekey;
extern int rp_screenmode;
extern int rp_inputmode;
extern int rp_printer;
+extern int rp_modem;
extern int log_rp;
extern void rp_input_change (int num);
#include "serial.h"
#include "enforcer.h"
#include "arcadia.h"
+#include "parallel.h"
+#ifdef RETROPLATFORM
+#include "rp.h"
+#endif
#include "parser.h"
static bool serxdevice_enabled;
static uae_u8 serstatus;
static bool ser_accurate;
+static uae_u16 *receive_buf;
+static int receive_buf_size, receive_buf_count;
#define SER_MEMORY_MAPPING _T("WinUAE_Serial")
}
}
+bool serreceive_external(uae_u16 v)
+{
+ if (data_in_serdatr) {
+ if (!receive_buf) {
+ receive_buf_size = 200;
+ receive_buf = xcalloc(uae_u16, receive_buf_size);
+ if (!receive_buf) {
+ return false;
+ }
+ }
+ if (receive_buf_count >= receive_buf_size) {
+ return false;
+ }
+ receive_buf[receive_buf_count++] = v;
+ return true;
+ }
+ serdatr = v;
+ serial_rx_irq();
+ return true;
+}
+
+static void receive_next_buffered(void)
+{
+ if (receive_buf && receive_buf_count > 0 && !(intreq & (1 << 11))) {
+ uae_u16 v = receive_buf[0];
+ receive_buf_count--;
+ if (receive_buf_count > 0) {
+ memmove(receive_buf, receive_buf + 1, receive_buf_count * sizeof(uae_u16));
+ }
+ serreceive_external(v);
+ }
+}
+
void serial_rethink(void)
{
if (data_in_serdatr) {
INTREQ_INT(11, 0);
}
}
+ receive_next_buffered();
}
static TCHAR docharlog(int v)
if (cubo_enabled) {
touch_serial_read(serdatshift);
}
+#ifdef RETROPLATFORM
+ if (rp_ismodem()) {
+ rp_writemodem(serdatshift & 0xff);
+ }
+#endif
if (serempty_enabled && !serxdevice_enabled) {
return;
}
event2_newevent_xx(-1, v * CYCLE_UNIT, 0, sersend_end);
}
-
static void sersend_ce(uae_u32 v)
{
if (checkshiftempty()) {
write_log (_T("SERIAL: read 0x%04x (%c) %x\n"), serdatr, dochar (serdatr), M68K_GETPC);
#endif
data_in_serdatr = 0;
+ receive_next_buffered();
return serdatr;
}
ovrun = 0;
}
-void serial_dtr_on (void)
+void serial_dtr_on(void)
{
#if SERIALHSDEBUG > 0
write_log ( "SERIAL: DTR on\n" );
+#endif
+#ifdef RETROPLATFORM
+ if (rp_ismodem()) {
+ rp_modemstate(1);
+ }
#endif
dtr = 1;
if (currprefs.serial_demand)
- serial_open ();
+ serial_open();
#ifdef SERIAL_PORT
setserstat(TIOCM_DTR, dtr);
#endif
}
-void serial_dtr_off (void)
+void serial_dtr_off(void)
{
#if SERIALHSDEBUG > 0
write_log ( "SERIAL: DTR off\n" );
+#endif
+#ifdef RETROPLATFORM
+ if (rp_ismodem()) {
+ rp_modemstate(0);
+ }
#endif
dtr = 0;
#ifdef SERIAL_PORT
if (currprefs.serial_demand)
- serial_close ();
+ serial_close();
setserstat(TIOCM_DTR, dtr);
#endif
}
#endif
}
-uae_u8 serial_readstatus (uae_u8 dir)
+uae_u8 serial_readstatus(uae_u8 v, uae_u8 dir)
{
int status = 0;
uae_u8 serbits = oldserbits;
if (serstatus & 0x10) { // RTS -> CTS
status |= TIOCM_CTS;
}
- } else {
+ } else if (rp_ismodem()) {
+ bool dsr, cd, cts, ri;
+ rp_readmodemstatus(&dsr, &cd, &cts, &ri);
+ if (dsr) {
+ status |= TIOCM_DSR;
+ }
+ if (cd) {
+ status |= TIOCM_CAR;
+ }
+ if (cts) {
+ status |= TIOCM_CTS;
+ }
+ if (ri) {
+ status |= TIOCM_RI;
+ }
+ } else if (currprefs.use_serial) {
#ifdef SERIAL_PORT
getserstat(&status);
#endif
+ } else {
+ return v;
}
if (!(status & TIOCM_CAR)) {
}
}
- serbits &= 0x08 | 0x10 | 0x20;
- oldserbits &= ~(0x08 | 0x10 | 0x20);
+ if (!isprinter()) {
+ // SEL == RI
+ v |= 4;
+ serbits |= 0x04;
+ } else {
+ serbits &= ~0x04;
+ serbits |= v & 0x04;
+ }
+
+ if (status & TIOCM_RI) {
+ if (serbits & 0x04) {
+ serbits &= ~0x04;
+#if SERIALHSDEBUG > 0
+ write_log("SERIAL: RI on\n");
+#endif
+ }
+ }
+
+ serbits &= 0x04 | 0x08 | 0x10 | 0x20;
+ oldserbits &= ~(0x04 | 0x08 | 0x10 | 0x20);
oldserbits |= serbits;
serial_status_debug (_T("read"));
- return oldserbits;
+ return (v & (0x80 | 0x40 | 0x02 | 0x01)) | serbits;
}
uae_u8 serial_writestatus (uae_u8 newstate, uae_u8 dir)
serstatus = newstate & dir;
#ifdef SERIAL_PORT
- if (((oldserbits ^ newstate) & 0x80) && (dir & 0x80)) {
- if (newstate & 0x80)
- serial_dtr_off();
- else
- serial_dtr_on();
- }
-
- if (!currprefs.serial_hwctsrts && (dir & 0x40)) {
- if ((oldserbits ^ newstate) & 0x40) {
- if (newstate & 0x40) {
- setserstat (TIOCM_RTS, 0);
+ if (currprefs.use_serial) {
+ if (((oldserbits ^ newstate) & 0x80) && (dir & 0x80)) {
+ if (newstate & 0x80)
+ serial_dtr_off();
+ else
+ serial_dtr_on();
+ }
+ if (!currprefs.serial_hwctsrts && (dir & 0x40)) {
+ if ((oldserbits ^ newstate) & 0x40) {
+ if (newstate & 0x40) {
+ setserstat(TIOCM_RTS, 0);
#if SERIALHSDEBUG > 0
- write_log (_T("SERIAL: RTS cleared\n"));
+ write_log(_T("SERIAL: RTS cleared\n"));
#endif
- } else {
- setserstat (TIOCM_RTS, 1);
+ } else {
+ setserstat(TIOCM_RTS, 1);
#if SERIALHSDEBUG > 0
- write_log (_T("SERIAL: RTS set\n"));
+ write_log(_T("SERIAL: RTS set\n"));
#endif
+ }
}
}
}
+#endif
#if 0 /* CIA io-pins can be read even when set to output.. */
if ((newstate & 0x20) != (oldserbits & 0x20) && (dir & 0x20))
if (logcnt > 0) {
if (((newstate ^ oldserbits) & 0x40) && !(dir & 0x40)) {
- write_log (_T("SERIAL: warning, program tries to use RTS as an input! PC=%x\n"), M68K_GETPC);
+ write_log(_T("SERIAL: warning, program tries to use RTS as an input! PC=%x\n"), M68K_GETPC);
logcnt--;
}
if (((newstate ^ oldserbits) & 0x80) && !(dir & 0x80)) {
- write_log (_T("SERIAL: warning, program tries to use DTR as an input! PC=%x\n"), M68K_GETPC);
+ write_log(_T("SERIAL: warning, program tries to use DTR as an input! PC=%x\n"), M68K_GETPC);
logcnt--;
}
}
-#endif
+ if (rp_ismodem()) {
+ if ((oldserbits & (0x80 | 0x40)) != (newstate & (0x80 | 0x40))) {
+ rp_writemodemstatus(
+ (newstate & 0x40) != 0, (oldserbits & 0x40) != (newstate & 0x40),
+ (newstate & 0x80) != 0, (oldserbits & 0x80) != (newstate & 0x80));
+ }
+ }
oldserbits &= ~(0x80 | 0x40);
newstate &= 0x80 | 0x40;
oldserbits |= newstate;
- serial_status_debug (_T("write"));
+
+ serial_status_debug(_T("write"));
return oldserbits;
}
sermap_deactivate();
#endif
#endif
+#ifdef RETROPLATFORM
+ if (rp_ismodem()) {
+ rp_modemstate(0);
+ }
+#endif
+ if (receive_buf) {
+ xfree(receive_buf);
+ receive_buf = NULL;
+ }
+ receive_buf_size = 0;
+ receive_buf_count = 0;
+
serloop_enabled = false;
serempty_enabled = false;
serxdevice_enabled = false;
rp_printer = 1;
return 1;
}
+ if (!_tcscmp(arg, _T("rpmodem"))) {
+ rp_modem = 1;
+ return 1;
+ }
if (!np)
return 0;