]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
uaeserial.device MARK and SPACE parity, EOFMODE, CMD_WRITE with io_Length=-1 support.
authorToni Wilen <twilen@winuae.net>
Sat, 6 Mar 2021 15:00:27 +0000 (17:00 +0200)
committerToni Wilen <twilen@winuae.net>
Sat, 6 Mar 2021 15:00:27 +0000 (17:00 +0200)
od-win32/parser.cpp
uaeserial.cpp

index 09a852415cc191511d63acb5ce9415961fd8979e..3c369aed6fe3fdd7660c8b23432f18be3ab1d786 100644 (file)
@@ -622,7 +622,24 @@ int uaeser_setparams (void *vsd, int baud, int rbuffer, int bits, int sbits, int
        dcb.fBinary = TRUE;
        dcb.BaudRate = baud;
        dcb.ByteSize = bits;
-       dcb.Parity = parity == 0 ? NOPARITY : (parity == 1 ? ODDPARITY : EVENPARITY);
+       switch (parity)
+       {
+       case 1:
+               dcb.Parity = ODDPARITY;
+               break;
+       case 2:
+               dcb.Parity = EVENPARITY;
+               break;
+       case 3:
+               dcb.Parity = MARKPARITY;
+               break;
+       case 4:
+               dcb.Parity = SPACEPARITY;
+               break;
+       default:
+               dcb.Parity = NOPARITY;
+               break;
+       }
        dcb.fParity = FALSE;
        dcb.StopBits = sbits == 1 ? ONESTOPBIT : TWOSTOPBITS;
 
index 65e2afdc249910a7d723aae372dc1814f877b563..29e5aa1e56df24146fa61578dd7a990459e1da2d 100644 (file)
@@ -83,6 +83,9 @@ int log_uaeserial = 0;
 #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:
@@ -214,29 +217,27 @@ static void resetparams(TrapContext *ctx, struct devstruct *dev, uae_u8 *req)
 
 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);
@@ -247,11 +248,11 @@ static int setparams(TrapContext *ctx, struct devstruct *dev, uae_u8 *req)
        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;
 }
@@ -409,6 +410,12 @@ static void abort_async(TrapContext *ctx, struct devstruct *dev, uaecptr areques
        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;
@@ -423,9 +430,11 @@ void uaeser_signal (void *vdev, int sigmask)
                        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)
                        {
@@ -439,14 +448,24 @@ void uaeser_signal (void *vdev, int sigmask)
                                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;
@@ -461,14 +480,54 @@ void uaeser_signal (void *vdev, int sigmask)
                        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;
                                }
@@ -500,8 +559,9 @@ void uaeser_signal (void *vdev, int sigmask)
 
 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);