Browse Source

added support for win32 systems

HenryDane 1 year ago
parent
commit
56a18e72cf
1 changed files with 331 additions and 0 deletions
  1. 331 0
      mym2serial_win32.c

+ 331 - 0
mym2serial_win32.c

@@ -0,0 +1,331 @@
+/*******************************************************************
+ *                     MYM Player to Serial port
+ *                 (c) 2014 Manoel "Godzil" Trapier
+ *
+ * This file is base on the mym2ym by 
+ * Marq/Lieves!Tuore & Fit (marq@iki.fi)
+ *
+ * The YM writing part have been removed and replaced by code to 
+ * send register dump to the serial port.
+ **************************** Licence ******************************
+ * This file is licenced under the licence:
+ *                    WTFPL v2 Postal Card Edition:
+ *
+ *             DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+ *                    Version 2, December 2004
+ *
+ * Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
+ *
+ * Everyone is permitted to copy and distribute verbatim or modified
+ * copies of this license document, and changing it is allowed as long
+ * as the name is changed.
+ *
+ *            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+ *   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+ *
+ *  0. You just DO WHAT THE FUCK YOU WANT TO.
+ *  1. If you like this software you can send me a (virtual) postals
+ *     card. Details bellow:
+ *
+ *             < godzil-nospambot at godzil dot net >
+ *
+ * If you want to send a real postal card, send me an email, I'll
+ * give you my address. Of course remove the -nospambot from my
+ * e-mail address.
+ *
+ ******************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+// #include <unistd.h> (replaced w/ void usleep(__int64 usec) )
+#include <fcntl.h>
+/*
+this is the i/o tool popular with linux, porting to windows is very hard
+#include <termios.h> //does not exist on windows
+*/
+
+#include <windows.h>
+
+#include <errno.h>
+
+#define REGS 14
+#define FRAG 128    /*  Nuber of rows to compress at a time   */
+#define OFFNUM 14   /*  Bits needed to store off+num of FRAG  */
+
+unsigned readbits(int bits,FILE *f);
+void usleep(__int64 usec);
+int set_interface_attribs (int fd, int speed, int parity);
+void set_blocking (int fd, int should_block); 
+
+int main(int argc,char *argv[])
+{
+    unsigned char   *data[REGS],    /*  The unpacked YM data    */
+                    c;
+    int serial_fd;
+
+
+    unsigned    current[REGS];
+
+    FILE    *f;
+
+    long    n,i,row,index,compoff,compnum,
+            bytes=0,
+            regbits[REGS]={8,4,8,4, 8,4,5,8, 5,5,5,8, 8,8}; /* Bits per PSG reg */
+
+    unsigned long   rows;
+	
+	HANDLE hComPort;
+	
+	int Status;
+	
+	DWORD dNoOfBytesWritten  = 0;
+	
+	char tmp[80];
+	strcpy(tmp, "\\\\.\\");
+	strcat(tmp, argv[2]);
+	printf("%s \n", tmp);
+	
+	hComPort = CreateFile(tmp,         //port name
+					GENERIC_READ | GENERIC_WRITE, //Read/Write
+					0,                            // No Sharing
+					NULL,                         // No Security
+					OPEN_EXISTING,				  // Open existing port only
+					0,            				  // Non Overlapped I/O
+					NULL);        				  // Null for Comm Devices
+
+	if (hComPort == INVALID_HANDLE_VALUE)
+	{
+		printf("Error in opening serial port");
+		CloseHandle(hComPort);
+		return -1;
+	}
+	else 
+	{
+        printf("opening serial port successful");
+	}
+	
+	// set up com port windows style
+	DCB dcbSerialParams = { 0 }; // Initializing DCB structure
+	dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
+	
+	// read state
+	Status = GetCommState(hComPort, &dcbSerialParams);
+	
+	// set state
+	dcbSerialParams.BaudRate = CBR_9600;  // Setting BaudRate = 9600
+	dcbSerialParams.ByteSize = 8;         // Setting ByteSize = 8
+	dcbSerialParams.StopBits = ONESTOPBIT;// Setting StopBits = 1
+	dcbSerialParams.Parity   = NOPARITY;  // Setting Parity = None
+	
+	// write state
+	SetCommState(hComPort, &dcbSerialParams);
+					
+    if(argc!=3)
+    {
+        printf("Usage: mym2serial source.mym /dev/serial\n");
+        return(EXIT_FAILURE);
+    }
+
+    if((f=fopen(argv[1],"rb"))==NULL)
+    {
+        printf("File open error.\n");
+        return(EXIT_FAILURE);
+    }
+
+    rows=fgetc(f);    /*  Read the number of rows */
+    rows+=fgetc(f)<<8u;
+
+    for(n=0;n<REGS;n++)     /*  Allocate memory for rows    */
+    {
+        if((data[n]=(unsigned char *)malloc(rows+FRAG))==NULL)
+        {
+            printf("Out of memory.\n");
+            exit(EXIT_FAILURE);
+        }
+    }
+
+    for(n=0;n<rows;n+=FRAG) /*  Go through rows...  */
+    {
+        for(i=0;i<REGS;i++) /*  ... and registers   */
+        {
+            index=0;
+            if(!readbits(1,f))  /*  Totally unchanged fragment */
+            {
+                for(row=0;row<FRAG;row++)
+                    data[i][n+row]=current[i];
+                continue;
+            }
+
+            while(index<FRAG)   /*  Packed fragment */
+            {
+                if(!readbits(1,f))  /*  Unchanged register  */
+                {
+                    
+                    data[i][n+index]=current[i];
+                    index++;
+                }
+                else
+                {
+                    if(readbits(1,f))   /*  Raw data    */
+                    {
+                        c=readbits(regbits[i],f);
+                        current[i]=data[i][n+index]=c;
+                        index++;
+                    }
+                    else    /*  Reference to previous data */
+                    {
+                        compoff=readbits(OFFNUM/2,f)+index;
+                        compnum=readbits(OFFNUM/2,f)+1;
+
+                        for(row=0;row<compnum;row++)
+                        {
+                            c=data[i][n-FRAG+compoff+row];
+                            data[i][n+index]=current[i]=c;
+                            index++;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    fclose(f);
+	
+    //serial_fd = open (argv[2], O_RDWR | O_NOCTTY | O_SYNC);
+    if (/*serial_fd > 0*/ 1 )
+    {
+        char buffer[14];
+        printf("Serial opened...\n");
+        // set_interface_attribs (serial_fd, B115200, 0); // 115200 8n1
+        // set_blocking (serial_fd, 0);
+        /* Wait a little bit to be sure that the other end is ready... */
+        usleep(2000); //sleep(2);
+        printf("Playing now!\n");
+        for(n=0;n<rows;n++)
+        {
+            for(i=0;i<REGS;i++)
+            {
+                buffer[i] = data[i][n];
+            }
+            //write(serial_fd, buffer, 14);
+			Status = WriteFile(hComPort,        // Handle to the Serial port
+							buffer,     		// Data to be written to the port
+							14,  				//No of bytes to write
+							&dNoOfBytesWritten, //Bytes written
+							NULL);
+            // 50Hz so wait a little bit...
+            printf("\rVBL%ld ", n);
+            fflush(stdout);
+            usleep(1000*20); /* 50Hz */
+        }
+        printf("\n");
+    }
+    else
+    {
+        printf("Opening error...\n");
+    }
+	
+	CloseHandle(hComPort);
+
+    return(EXIT_SUCCESS);
+}
+
+/*  Reads bits from a while */
+unsigned readbits(int bits,FILE *f)
+{
+    static unsigned char    byte;
+
+    static int  off=7;
+
+    unsigned    n,data=0;
+
+    /* Go through the bits and read a whole byte if needed */
+    for(n=0;n<bits;n++) 
+    {
+        data<<=1;
+        if(++off==8)
+        {
+            byte=fgetc(f);
+            off=0;
+        }
+        
+        if(byte&(0x80>>off))
+            data++;
+    }
+    return(data);
+}
+
+void usleep(__int64 usec) 
+{ 
+    HANDLE timer; 
+    LARGE_INTEGER ft; 
+
+    ft.QuadPart = -(10*usec); // Convert to 100 nanosecond interval, negative value indicates relative time
+
+    timer = CreateWaitableTimer(NULL, TRUE, NULL); 
+    SetWaitableTimer(timer, &ft, 0, NULL, NULL, 0); 
+    WaitForSingleObject(timer, INFINITE); 
+    CloseHandle(timer); 
+}
+
+/*
+int set_interface_attribs (int fd, int speed, int parity)
+{
+    struct termios tty;
+    memset (&tty, 0, sizeof tty);
+    if (tcgetattr (fd, &tty) != 0)
+    {
+        printf("error %d from tcgetattr", errno);
+        return -1;
+    }
+
+    cfsetospeed (&tty, speed);
+    cfsetispeed (&tty, speed);
+
+    tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8;     // 8-bit chars
+    // disable IGNBRK for mismatched speed tests; otherwise receive break
+    // as \000 chars
+    tty.c_iflag &= ~IGNBRK;         // disable break processing
+    tty.c_lflag = 0;                // no signaling chars, no echo,
+                                    // no canonical processing
+    tty.c_oflag = 0;                // no remapping, no delays
+    tty.c_cc[VMIN]  = 0;            // read doesn't block
+    tty.c_cc[VTIME] = 5;            // 0.5 seconds read timeout
+
+    tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl
+
+    tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
+                                        // enable reading
+    tty.c_cflag &= ~(PARENB | PARODD);      // shut off parity
+    tty.c_cflag |= parity;
+    tty.c_cflag &= ~CSTOPB;
+    tty.c_cflag &= ~CRTSCTS;
+
+    if (tcsetattr (fd, TCSANOW, &tty) != 0)
+    {
+        printf ("error %d from tcsetattr", errno);
+        return -1;
+    }
+    return 0;
+}
+*/
+
+/*
+void set_blocking (int fd, int should_block)
+{
+    struct termios tty;
+    memset (&tty, 0, sizeof tty);
+    if (tcgetattr (fd, &tty) != 0)
+    {
+        printf ("error %d from tggetattr", errno);
+        return;
+    }
+
+    tty.c_cc[VMIN]  = should_block ? 1 : 0;
+    tty.c_cc[VTIME] = 5;            // 0.5 seconds read timeout
+
+    if (tcsetattr (fd, TCSANOW, &tty) != 0)
+        printf ("error %d setting term attributes", errno);
+}
+*/