volatile uae_u32 active_write;
volatile uae_u32 read_offset;
volatile uae_u32 write_offset;
- volatile uae_u16 data[SERMAP_SIZE];
+ volatile uae_u32 data[SERMAP_SIZE];
};
static struct sermap_buffer *sermap1, *sermap2;
static HANDLE sermap_handle;
static uae_u8 *sermap_data;
static bool sermap_master;
static bool sermap_enabled;
+static uae_u32 sermap_flags;
static bool serloop_enabled;
static bool serempty_enabled;
static bool serxdevice_enabled;
#define SER_MEMORY_MAPPING _T("WinUAE_Serial")
-static void shmem_serial_send(uae_u16 data)
+static void shmem_serial_send(uae_u32 data)
{
uae_u32 v;
v &= (SERMAP_SIZE - 1);
sermap1->write_offset = v;
}
-static uae_u16 shmem_serial_receive(void)
+static uae_u32 shmem_serial_receive(void)
{
uae_u32 v;
- uae_u16 data;
+ uae_u32 data;
sermap2->active_read = true;
if (!sermap2->active_write)
- return 0xffff;
+ return 0xffffffff;
v = sermap2->read_offset;
if (v == sermap2->write_offset)
- return 0xffff;
+ return 0xffffffff;
data = sermap2->data[v];
v++;
v &= (SERMAP_SIZE - 1);
static void sermap_deactivate(void)
{
sermap_enabled = false;
+ sermap_flags = 0;
if (sermap1) {
sermap1->active_write = 0;
sermap1->write_offset = sermap1->read_offset;
return;
}
#ifdef SERIAL_MAP
- if (sermap_data && sermap_enabled)
+ if (sermap_data && sermap_enabled) {
shmem_serial_send(serdatshift);
+ }
#endif
#ifdef SERIAL_ENET
if (serial_enet) {
}
}
- if (lastbitcycle_active_hsyncs > 0)
+ if (lastbitcycle_active_hsyncs > 0) {
lastbitcycle_active_hsyncs--;
+ }
#ifdef SERIAL_MAP
- if (sermap2 && sermap_enabled && !data_in_serdatr) {
- uae_u16 v = shmem_serial_receive();
- if (v != 0xffff) {
- serdatr = v;
+ if (sermap2 && sermap_enabled) {
+ if (!data_in_serdatr) {
+ for (;;) {
+ uae_u32 v = shmem_serial_receive();
+ if (v == 0xffffffff) {
+ break;
+ }
+ if (!(v & 0xffff0000)) {
+ serdatr = (uae_u16)v;
+ serial_rx_irq();
+ break;
+ } else if ((v & 0x80000000) == 0x80000000) {
+ sermap_flags &= 0x0fff0000;
+ sermap_flags |= v & 0xffff;
+ } else if ((v & 0x40000000) == 0x40000000) {
+ if (v & (0x10000 | 0x20000)) {
+ sermap_flags &= ~(0x10000 | 0x20000);
+ sermap_flags |= v & (0x10000 | 0x20000);
+ break;
+ }
+ }
+ }
+ }
+ // break on
+ if (sermap_flags & 0x20000) {
+ break_in_serdatr = maxvpos;
+ }
+ if (break_in_serdatr) {
+ serdatr = 0;
+ if (break_delay == 0) {
+ serial_rx_irq();
+ break_delay = SERIAL_BREAK_TRANSMIT_DELAY;
+ }
+ if (break_delay > 0) {
+ break_delay--;
+ }
+ }
+ // break off
+ if (break_in_serdatr == 1) {
+ break_in_serdatr = 0;
+ break_delay = 0;
+ serdatr |= 0x100;
serial_rx_irq();
}
}
#endif
- if (data_in_serdatr)
+ if (data_in_serdatr) {
serdatr_last_got++;
- if (serial_period_hsyncs == 0)
+ }
+ if (serial_period_hsyncs == 0) {
return;
+ }
serial_period_hsync_counter++;
if (serial_period_hsyncs == 1 || (serial_period_hsync_counter % (serial_period_hsyncs - 1)) == 0) {
checkreceive_serial();
if (ri) {
status |= TIOCM_RI;
}
+#ifdef SERIAL_MAP
+ } else if (sermap_enabled) {
+ if (sermap_flags & 1) {
+ status |= TIOCM_DSR;
+ }
+ if (sermap_flags & 2) {
+ status |= TIOCM_CAR;
+ }
+ if (sermap_flags & 4) {
+ status |= TIOCM_CTS;
+ }
+#endif
} else if (currprefs.use_serial) {
#ifdef SERIAL_PORT
getserstat(&status);
}
}
+#ifdef SERIAL_MAP
+ if (sermap_data && sermap_enabled) {
+ uae_u32 flags = 0x80000000;
+ bool changed = false;
+ if (((oldserbits ^ newstate) & 0x80) && (dir & 0x80)) {
+ if (!(newstate & 0x80)) {
+ flags |= 1; // DSR
+ flags |= 2; // CD
+ }
+ changed = true;
+ }
+ if (!currprefs.serial_hwctsrts && (dir & 0x40)) {
+ if ((oldserbits ^ newstate) & 0x40) {
+ if (!(newstate & 0x40)) {
+ flags |= 4; // RTS
+ }
+ changed = true;
+ }
+ }
+ if (changed) {
+ shmem_serial_send(flags);
+ }
+ }
+#endif
+
+
oldserbits &= ~(0x80 | 0x40);
newstate &= 0x80 | 0x40;
oldserbits |= newstate;
return;
}
}
- if (alg_flag || currprefs.genlock_image >= 7 || cubo_enabled) {
+ if (alg_flag || currprefs.genlock_image >= 7 || cubo_enabled || sermap_enabled || rp_ismodem()) {
serxdevice_enabled = true;
}
serdev = 1;
void serial_uartbreak (int v)
{
+#ifdef SERIAL_MAP
+ if (sermap_data && sermap_enabled) {
+ shmem_serial_send(0x40000000 | (v ? 0x20000 : 0x10000));
+ }
+#endif
#ifdef SERIAL_PORT
serialuartbreak (v);
#endif