From: Toni Wilen Date: Wed, 7 Dec 2022 18:24:52 +0000 (+0200) Subject: rpmodem X-Git-Tag: 41000~14 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=870f3c9e1d9923b9912518103f214f2a7fc25e59;p=francis%2Fwinuae.git rpmodem --- diff --git a/cia.cpp b/cia.cpp index 1ed9cb97..ec861382 100644 --- a/cia.cpp +++ b/cia.cpp @@ -1797,10 +1797,7 @@ static uae_u8 ReadCIAB(uae_u32 addr, uae_u32 *flags) 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) { @@ -2049,8 +2046,7 @@ static void WriteCIAB(uae_u16 addr, uae_u8 val, uae_u32 *flags) 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) { diff --git a/include/serial.h b/include/serial.h index a0d782df..a9f80c67 100644 --- a/include/serial.h +++ b/include/serial.h @@ -18,12 +18,11 @@ extern void serial_dtr_off (void); 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; @@ -36,7 +35,6 @@ extern void serial_hsynchandler(void); 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); diff --git a/od-win32/cloanto/RetroPlatformIPC.h b/od-win32/cloanto/RetroPlatformIPC.h index a4cbb70d..56346816 100644 --- a/od-win32/cloanto/RetroPlatformIPC.h +++ b/od-win32/cloanto/RetroPlatformIPC.h @@ -9,7 +9,7 @@ : 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 *****************************************************************************/ @@ -78,6 +78,7 @@ #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 @@ -128,6 +129,8 @@ #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 @@ -646,6 +649,16 @@ typedef struct RPExecuteResult #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 diff --git a/od-win32/rp.cpp b/od-win32/rp.cpp index 66d98f55..b69e9353 100644 --- a/od-win32/rp.cpp +++ b/od-win32/rp.cpp @@ -48,9 +48,11 @@ int rp_rpescapeholdtime = 600; 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; @@ -165,6 +167,8 @@ static const TCHAR *getmsg (int msg) 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"); } } @@ -1282,6 +1286,47 @@ static void dos_execute_callback(uae_u32 id, uae_u32 status, uae_u32 flags, cons } } +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); @@ -1536,6 +1581,10 @@ static LRESULT CALLBACK RPHostMsgFunction2 (UINT uMessage, WPARAM wParam, LPARAM 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; } @@ -2379,6 +2428,49 @@ void rp_reset(void) 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) { @@ -2390,8 +2482,9 @@ bool rp_isprinteropen(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) { diff --git a/od-win32/rp.h b/od-win32/rp.h index efff0177..be86d77b 100644 --- a/od-win32/rp.h +++ b/od-win32/rp.h @@ -27,6 +27,11 @@ extern void rp_test(void); 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; @@ -34,6 +39,7 @@ extern int rp_rpescapeholdtime; 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); diff --git a/od-win32/serial_win32.cpp b/od-win32/serial_win32.cpp index c757b5c8..8c871f0b 100644 --- a/od-win32/serial_win32.cpp +++ b/od-win32/serial_win32.cpp @@ -24,6 +24,10 @@ #include "serial.h" #include "enforcer.h" #include "arcadia.h" +#include "parallel.h" +#ifdef RETROPLATFORM +#include "rp.h" +#endif #include "parser.h" @@ -57,6 +61,8 @@ static bool serempty_enabled; 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") @@ -312,6 +318,39 @@ static void serial_rx_irq(void) } } +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) { @@ -331,6 +370,7 @@ void serial_rethink(void) INTREQ_INT(11, 0); } } + receive_next_buffered(); } static TCHAR docharlog(int v) @@ -555,6 +595,11 @@ static void checksend(void) if (cubo_enabled) { touch_serial_read(serdatshift); } +#ifdef RETROPLATFORM + if (rp_ismodem()) { + rp_writemodem(serdatshift & 0xff); + } +#endif if (serempty_enabled && !serxdevice_enabled) { return; } @@ -631,7 +676,6 @@ static void sersend_serloop(uae_u32 v) event2_newevent_xx(-1, v * CYCLE_UNIT, 0, sersend_end); } - static void sersend_ce(uae_u32 v) { if (checkshiftempty()) { @@ -886,6 +930,7 @@ uae_u16 SERDATR(void) 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; } @@ -903,28 +948,38 @@ void serial_rbf_clear(void) 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 } @@ -944,7 +999,7 @@ static void serial_status_debug(const TCHAR *s) #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; @@ -956,10 +1011,27 @@ uae_u8 serial_readstatus (uae_u8 dir) 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)) { @@ -1010,13 +1082,31 @@ uae_u8 serial_readstatus (uae_u8 dir) } } - 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) @@ -1026,28 +1116,30 @@ 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)) @@ -1060,21 +1152,28 @@ uae_u8 serial_writestatus (uae_u8 newstate, uae_u8 dir) 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; } @@ -1129,6 +1228,18 @@ void serial_close(void) 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; diff --git a/od-win32/win32.cpp b/od-win32/win32.cpp index 8307de5c..1f964760 100644 --- a/od-win32/win32.cpp +++ b/od-win32/win32.cpp @@ -6658,6 +6658,10 @@ static int parseargs(const TCHAR *argx, const TCHAR *np, const TCHAR *np2) rp_printer = 1; return 1; } + if (!_tcscmp(arg, _T("rpmodem"))) { + rp_modem = 1; + return 1; + } if (!np) return 0;