#define io_SerFlags 0x4f /* UBYTE see SerFlags bit definitions below */
#define io_Status 0x50 /* UWORD */
+#define SEXTF_MSPON 2
+#define SEXTF_MARK 1
+
#define IOExtSerSize 82
/* status of serial port, as follows:
static int setparams(TrapContext *ctx, struct devstruct *dev, uae_u8 *req)
{
- int v;
- int rbuffer, baud, rbits, wbits, sbits, rtscts, parity, xonxoff;
+ uae_u32 extFlags, serFlags;
+ int rbuffer, baud, rbits, wbits, sbits, rtscts, parity, xonxoff, err;
rbuffer = get_long_host(req + io_RBufLen);
- v = get_long_host(req + io_ExtFlags);
- if (v) {
- write_log (_T("UAESER: io_ExtFlags=%08x, not supported\n"), v);
- return 5;
- }
+ extFlags = get_long_host(req + io_ExtFlags);
baud = get_long_host(req + io_Baud);
- v = get_byte_host(req + io_SerFlags);
- if (v & SERF_EOFMODE) {
- write_log (_T("UAESER: SERF_EOFMODE not supported\n"));
- return 5;
- }
- xonxoff = (v & SERF_XDISABLED) ? 0 : 1;
+ serFlags = get_byte_host(req + io_SerFlags);
+ xonxoff = (serFlags & SERF_XDISABLED) ? 0 : 1;
if (xonxoff) {
xonxoff |= (get_long_host(req + io_CtlChar) << 8) & 0x00ffff00;
}
- rtscts = (v & SERF_7WIRE) ? 1 : 0;
+ rtscts = (serFlags & SERF_7WIRE) ? 1 : 0;
parity = 0;
- if (v & SERF_PARTY_ON)
- parity = (v & SERF_PARTY_ODD) ? 1 : 2;
+ if (extFlags & SEXTF_MSPON) {
+ parity = (extFlags & SEXTF_MARK) ? 3 : 4;
+ if (!(serFlags & SERF_PARTY_ON)) {
+ put_byte_host(req + io_SerFlags, serFlags | SERF_PARTY_ON);
+ }
+ } else if (serFlags & SERF_PARTY_ON) {
+ parity = (serFlags & SERF_PARTY_ODD) ? 1 : 2;
+ }
rbits = get_byte_host(req + io_ReadLen);
wbits = get_byte_host(req + io_WriteLen);
sbits = get_byte_host(req + io_StopBits);
write_log (_T("%s:%d BAUD=%d BUF=%d BITS=%d+%d RTSCTS=%d PAR=%d XO=%06X\n"),
getdevname(), dev->unit,
baud, rbuffer, rbits, sbits, rtscts, parity, xonxoff);
- v = uaeser_setparams (dev->sysdata, baud, rbuffer,
+ err = uaeser_setparams (dev->sysdata, baud, rbuffer,
rbits, sbits, rtscts, parity, xonxoff);
- if (v) {
- write_log (_T("->failed\n"));
- return v;
+ if (err) {
+ write_log (_T("->failed %d\n"), err);
+ return err;
}
return 0;
}
uae_sem_post(&pipe_sem);
}
+static bool eofmatch(uae_u8 v, uae_u32 term0, uae_u32 term1)
+{
+ return v == (term0 >> 24) || v == (term0 >> 16) || v == (term0 >> 8) || v == (term0 >> 0)
+ || v == (term1 >> 24) || v == (term1 >> 16) || v == (term1 >> 8) || v == (term1 >> 0);
+}
+
void uaeser_signal (void *vdev, int sigmask)
{
TrapContext *ctx = NULL;
uae_u8 *request = ar->request;
uae_u32 io_data = get_long_host(request + 40); // 0x28
uae_u32 io_length = get_long_host(request + 36); // 0x24
+ uae_u8 serFlags = get_byte_host(request + io_SerFlags);
int command = get_word_host(request + 28);
uae_u32 io_error = 0, io_actual = 0;
int io_done = 0;
+ uae_u32 term0 = 0, term1 = 0;
switch (command)
{
if (sigmask & 1) {
uae_u8 tmp[RTAREA_TRAP_DATA_EXTRA_SIZE];
io_done = 1;
- while (io_length > 0) {
- int size = io_length > sizeof(tmp) ? sizeof(tmp) : io_length;
+ if (serFlags & SERF_EOFMODE) {
+ term0 = get_long_host(request + io_TermArray0);
+ term1 = get_long_host(request + io_TermArray1);
+ }
+ while (io_length) {
+ int size = 1;
+ if (!(serFlags & SERF_EOFMODE)) {
+ size = io_length > sizeof(tmp) ? sizeof(tmp) : io_length;
+ }
int status = uaeser_read(dev->sysdata, tmp, size);
if (status > 0) {
trap_put_bytes(ctx, tmp, io_data, size);
io_actual += size;
io_data += size;
io_length -= size;
+ if ((serFlags & SERF_EOFMODE) && eofmatch(tmp[0], term0, term1)) {
+ io_length = 0;
+ }
} else if (status == 0) {
if (io_actual == 0)
io_done = 0;
case CMD_WRITE:
if (sigmask & 2) {
uae_u8 tmp[RTAREA_TRAP_DATA_EXTRA_SIZE];
- while (io_length > 0) {
- int size = io_length > sizeof(tmp) ? sizeof(tmp) : io_length;
- trap_get_bytes(ctx, tmp, io_data, size);
- if (!uaeser_write(dev->sysdata, tmp, size))
- break;
- io_actual += size;
- io_data += size;
- io_length -= size;
+ bool done = false;
+ if (serFlags & SERF_EOFMODE) {
+ term0 = get_long_host(request + io_TermArray0);
+ term1 = get_long_host(request + io_TermArray1);
+ }
+ while (io_length && !done) {
+ uae_u32 size = 0;
+ if (io_length == 0xffffffff) {
+ while (size < sizeof(tmp)) {
+ tmp[size] = trap_get_byte(ctx, io_data + size);
+ if (!tmp[size]) {
+ done = true;
+ break;
+ }
+ if ((serFlags & SERF_EOFMODE) && eofmatch(tmp[size], term0, term1)) {
+ done = true;
+ break;
+ }
+ size++;
+ }
+ if (size > 0) {
+ if (!uaeser_write(dev->sysdata, tmp, size)) {
+ done = true;
+ break;
+ }
+ }
+ io_actual += size;
+ io_data += size;
+ } else {
+ size = io_length > sizeof(tmp) ? sizeof(tmp) : io_length;
+ trap_get_bytes(ctx, tmp, io_data, size);
+ if (serFlags & SERF_EOFMODE) {
+ for (int i = 0; i < size; i++) {
+ if (eofmatch(tmp[i], term0, term1)) {
+ size = i;
+ io_length = size;
+ break;
+ }
+ }
+ }
+ if (!uaeser_write(dev->sysdata, tmp, size)) {
+ done = true;
+ break;
+ }
+ io_actual += size;
+ io_data += size;
+ io_length -= size;
+ }
}
io_done = 1;
}
static void cmd_reset(TrapContext *ctx, struct devstruct *dev, uae_u8 *req)
{
- while (dev->ar)
+ while (dev->ar) {
abort_async(ctx, dev, dev->ar->arequest);
+ }
put_long_host(req + io_RBufLen, 8192);
put_long_host(req + io_ExtFlags, 0);
put_long_host(req + io_Baud, 57600);