Emulator Simulator [C# code]

bmgjet

#1 ◈ 2025-10-06

Thought id share this little .net core app that lets you simulate with software a couple different emulators.
Makes it easy to debug if your writing a program that interfaces with them,
PS iv removed the encrypted transfere functions since that could be used to rip bins from certain programs.

Code:
using System;
using System.IO;
using System.IO.Ports;
using System.Text;
using System.Threading;
namespace EmulatorSimulator
{
    class Program
    {
        public static string Header = @"
        ███████╗███╗   ███╗██╗   ██╗███████╗██╗███╗   ███╗
        ██╔════╝████╗ ████║██║   ██║██╔════╝██║████╗ ████║
        █████╗  ██╔████╔██║██║   ██║███████╗██║██╔████╔██║
        ██╔══╝  ██║╚██╔╝██║██║   ██║╚════██║██║██║╚██╔╝██║
        ███████╗██║ ╚═╝ ██║╚██████╔╝███████║██║██║ ╚═╝ ██║
        ╚══════╝╚═╝     ╚═╝ ╚═════╝ ╚══════╝╚═╝╚═╝     ╚═╝
        BMGJET 2020" + "\n"; //Header image
        public static string HS = " Emulator Simulator 0.1\n\n"; //Header string
        public static string FS = "\n(Enter The Number To Select Option)"; //Help tip.
        public static bool NoDelay = false;
        private static SerialPort serialPort_0;
        public static byte Protocol;
        public static byte[] Bin;
        public static byte[] Version;
        public static int TimeOut = 60;
        public static string BinFile;
        public static byte[] OK = new byte[] { 0x4F };
        public static byte[] Serial = new byte[] { 0x04, 0x01, 0x02, 0x08, 0x08, 0x01, 0x04, 0x05, 0x06, 0x07  };
        public static byte[] EEPROM = new byte[] { 0x42, 0x4d, 0x47, 0x4a, 0x45, 0x54, 0x20, 0x32, 0x30, 0x32, 0x30 };
        //███████╗██╗   ██╗███╗   ██╗ ██████╗████████╗██╗ ██████╗ ███╗   ██╗███████╗
        //██╔════╝██║   ██║████╗  ██║██╔════╝╚══██╔══╝██║██╔═══██╗████╗  ██║██╔════╝
        //█████╗  ██║   ██║██╔██╗ ██║██║        ██║   ██║██║   ██║██╔██╗ ██║███████╗
        //██╔══╝  ██║   ██║██║╚██╗██║██║        ██║   ██║██║   ██║██║╚██╗██║╚════██║
        //██║     ╚██████╔╝██║ ╚████║╚██████╗   ██║   ██║╚██████╔╝██║ ╚████║███████║
        //╚═╝      ╚═════╝ ╚═╝  ╚═══╝ ╚═════╝   ╚═╝   ╚═╝ ╚═════╝ ╚═╝  ╚═══╝╚══════╝

        static bool LoadBin()
        {
            //Loads bin that was dragged onto application.
            try
            {
                byte[] file = System.IO.File.ReadAllBytes(BinFile);
                if (file.Length == 32768L)
                {
                    Bin = new byte[32768]; //Sets byte array size 32K
                    Bin = file;
                    Console.WriteLine("Loaded 32K");
                    return true;
                }
                else if (file.Length == 65536L)
                {
                    Bin = new byte[65536]; //Sets byte array size 64K
                    Bin = file;
                    Console.WriteLine("Loaded 64K");
                    return true;
                }

                return false; //Unsupported size fail.
            }
            catch
            {
                return false; //Something had issue fail.
            }
        }

        public static void SetNoDelay() //Disables delay that emulates bluetooth speed.
        {
            NoDelay = !NoDelay;
            Console.WriteLine("No Delay Mode: "+ NoDelay);
        }

        static byte Setup()
        {
            //Define what protocol to use.
            int P = 0;
            Console.WriteLine("\nWhat Protocol To Emulate: \n(1) Moates Ostrich 1.0\n(2) Moates Ostrich 2.0\n(3) CobraRTP\n(4) ECUTamer\n(0) Moates Demon(WIP)" + FS);
            FS = "";
            int.TryParse(Console.ReadLine(), out P);
            switch (P)  //Switch version array for what emulator your using.
            {
                case 0:
                    Console.WriteLine("Protocol: Moates Demon");
                    Version = new byte[] { 0x01, 0x09, 0x44 };
                    break;
                case 1:
                    Console.WriteLine("Protocol: Moates Ostrich 1.0");
                    Version = new byte[] { 0x10, 0x07, 0x4F };
                    break;
                case 2:
                    Console.WriteLine("Protocol: Moates Ostrich 2.0");
                    Version = new byte[] { 0x14, 0x09, 0x4F };
                    break;
                case 3:
                    Console.WriteLine("Protocol: CobraRTP");
                    Version = new byte[] { 0x14, 0x18, 0x43 };
                    break;
                default:
                    Console.WriteLine("Protocol: ECUTamer");
                    Version = new byte[] { 0x01, 0x28, 0x4F };
                    break;
            }
            try
            {
                Console.WriteLine("\nSelect Port:");
                //Builds list of avaliable COMPorts
                foreach (string s in SerialPort.GetPortNames())
                {
                    Console.WriteLine(s);
                }
            }
            catch { Console.WriteLine("No Avaliable ComPorts"); }

            //Read back COMPORT selection.
            bool NC = true;
            while (NC)
            {
                string CP = Console.ReadLine().ToUpper();
                if (CP.Contains("COM"))
                {
                    serialPort_0 = new SerialPort();
                    //Setup Baud rate
                    Console.WriteLine("\nWhat Baud Rate:\n(1) 115.2K\n(2) 921.6K");
                    int B = 1;
                    int.TryParse(Console.ReadLine(), out B);
                    if (B == 2)
                    {
                        serialPort_0.BaudRate = 921600;
                    }
                    else
                    {
                        serialPort_0.BaudRate = 115200;
                    }
                    serialPort_0.ReadBufferSize = 64000;
                    serialPort_0.PortName = CP;
                    serialPort_0.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
                    NC = false;
                }
                else
                {
                    Console.WriteLine("Must Use Format COM# (#=number)");
                }
            }
            return (byte)P; //Returns protocol selection.
        }


        static bool MakeBin()
        {
            BinFile = Directory.GetCurrentDirectory() + "\\EMUSIM.bin";
            if (File.Exists(BinFile)) //Checks if old file already exsists.
            {
                Console.WriteLine("Found a exsisting bin file:\n" + BinFile);
                if (!LoadBin()) //Trys to load the file.
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
            else
            {
                //Makes a Bin File if one not opened.
                int P;
                Console.WriteLine("No Bin Loaded\nCreating Blank ECUSIM.bin\nWhat Chip Size Fo You Want To Emulate\n(1) 32KB\n(2) 64KB" + FS);
                FS = "";
                int.TryParse(Console.ReadLine(), out P);
                switch (P)
                {
                    case 2:
                        Console.WriteLine("Creating 64KB");
                        Bin = new byte[65536];
                        break;
                    default:
                        Console.WriteLine("Creating 32KB");
                        Bin = new byte[32768];
                        break;
                }
                try
                {

                    File.WriteAllBytes(BinFile, Bin);
                    return true;
                }
                catch
                {
                    Console.WriteLine("Failed to create temp file EMUSIM.bin");
                    return false;
                }
            }
        }

        public static void SaveFile()
        {
            //Saves file to opened file or blank file.
            try
            {
                System.IO.File.WriteAllBytes(BinFile, Bin);
                Console.WriteLine("Saved Bytes To Bin: " + BinFile);
            }
            catch
            {
                Console.WriteLine("Failed To Saved Bytes To Bin: " + BinFile);
            }
        }

        //Erases byte array memory.
        public static void ClearFile()
        {
            Array.Clear(Bin, 0, Bin.Length);
            Console.WriteLine("Zeroed Bin Memory.");
        }

        //Help prompts
        public static void HELP()
        {
            string HelpHeader = @"
                ██╗  ██╗███████╗██╗     ██████╗
                ██║  ██║██╔════╝██║     ██╔══██╗
                ███████║█████╗  ██║     ██████╔╝
                ██╔══██║██╔══╝  ██║     ██╔═══╝
                ██║  ██║███████╗███████╗██║     
                ╚═╝  ╚═╝╚══════╝╚══════╝╚═╝" + "\n";
            string keys = "ESC = Exit Program\nSpace = Save Memory to File\nBackspace = Clear Memory\nF1 = Toggle Bluetooth Delay";
            ConsoleKey H = Console.ReadKey().Key;
            switch (H)
            {
                case ConsoleKey.Escape:
                    Environment.Exit(0);
                    break;
                case ConsoleKey.Spacebar:
                    SaveFile();
                    break;
                case ConsoleKey.Backspace:
                    ClearFile();
                    break;
                case ConsoleKey.F1:
                    SetNoDelay();
                    break;
                default:
                    Console.WriteLine(HelpHeader + Encoding.ASCII.GetString(EEPROM) + HS + keys);
                    break;
            }
        }

        // ██████╗ ██████╗ ███╗   ███╗
        //██╔════╝██╔═══██╗████╗ ████║
        //██║     ██║   ██║██╔████╔██║
        //██║     ██║   ██║██║╚██╔╝██║
        //╚██████╗╚██████╔╝██║ ╚═╝ ██║
        // ╚═════╝ ╚═════╝ ╚═╝     ╚═╝
        public static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
        {
            //Handles Incoming data.
            SerialPort sp = (SerialPort)sender;
            if (!NoDelay)
            {
                Thread.Sleep(TimeOut);// Delay to allow bluetooth buffer to fill before reading.
            }
            else
            {
                Thread.Sleep(20);// Delay 20ms to reduce cpu load.
            }
            byte[] inputbytes = new byte[sp.BytesToRead];
            sp.Read(inputbytes, 0, inputbytes.Length);
            if (inputbytes.Length != 0)
            {
                if (Protocol == 0) //Trys parse the Demon protocol
                {
                    if (!DemonAPI(inputbytes, sp))
                    {
                        ErrorLog(Encoding.Default.GetString(inputbytes));
                    }
                }
                else
                {
                    if (!OstrichAPI(inputbytes, sp)) //Trys parse the Ostrich protocol
                    {
                        ErrorLog(Encoding.Default.GetString(inputbytes));
                    }
                }
            }
        }

        private static void ErrorLog(string Debug)
        {
            if (Debug.Length > 16)
            {
                Debug = Debug.Substring(0, 16); //limited to 16 char
            }
            Console.Write("SD: " + Debug); //Dump string that failed
        }
   


        //Handles outgoing data
        public static void DataSender(byte[] DataByte, SerialPort sp)
        {
            if (sp.IsOpen)
            {
                sp.Write(DataByte, 0, DataByte.Length);
            }
        }

        //███╗   ███╗ █████╗ ██╗███╗   ██╗
        //████╗ ████║██╔══██╗██║████╗  ██║
        //██╔████╔██║███████║██║██╔██╗ ██║
        //██║╚██╔╝██║██╔══██║██║██║╚██╗██║
        //██║ ╚═╝ ██║██║  ██║██║██║ ╚████║
        //╚═╝     ╚═╝╚═╝  ╚═╝╚═╝╚═╝  ╚═══╝
        static void Main(string[] args)
        {
            //Code starts here
            Console.WriteLine(Header);

            //Checks if file has been dragged onto application.
            if (args.Length > 0 && File.Exists(args[0]))
            {
                BinFile = args[0];
                Console.WriteLine("Loading Bin:" + BinFile);
                if (!LoadBin()) //Trys to load the file.
                {
                    Console.WriteLine("Failed to load to byte array.");
                    if (!MakeBin()) //Trys to make new temp file.
                    {
                        Console.WriteLine("Complete Fail, Will close.");
                        Console.ReadKey();
                        Environment.Exit(0);
                    }
                }
            }
            else
            {
                if (!MakeBin()) //Trys to make new temp file.
                {
                    Console.WriteLine("Complete Fail, Will close.");
                    Console.ReadKey();
                    Environment.Exit(0);
                }
            }

            Protocol = Setup(); //Sets up Protocol
            serialPort_0.Open(); //Open COMPort
            if (serialPort_0.IsOpen)
            {
                Console.WriteLine(@"
██████╗ ██╗   ██╗███╗   ██╗███╗   ██╗██╗███╗   ██╗ ██████╗         
██╔══██╗██║   ██║████╗  ██║████╗  ██║██║████╗  ██║██╔════╝         
██████╔╝██║   ██║██╔██╗ ██║██╔██╗ ██║██║██╔██╗ ██║██║  ███╗         
██╔══██╗██║   ██║██║╚██╗██║██║╚██╗██║██║██║╚██╗██║██║   ██║         
██║  ██║╚██████╔╝██║ ╚████║██║ ╚████║██║██║ ╚████║╚██████╔╝██╗██╗██╗
╚═╝  ╚═╝ ╚═════╝ ╚═╝  ╚═══╝╚═╝  ╚═══╝╚═╝╚═╝  ╚═══╝ ╚═════╝ ╚═╝╚═╝╚═╝
Press Enter Key To See Command List.
");
            }
            else
            {
                Console.WriteLine(@"
███████╗ █████╗ ██╗██╗     ███████╗██████╗         
██╔════╝██╔══██╗██║██║     ██╔════╝██╔══██╗         
█████╗  ███████║██║██║     █████╗  ██║  ██║         
██╔══╝  ██╔══██║██║██║     ██╔══╝  ██║  ██║         
██║     ██║  ██║██║███████╗███████╗██████╔╝██╗██╗██╗
╚═╝     ╚═╝  ╚═╝╚═╝╚══════╝╚══════╝╚═════╝ ╚═╝╚═╝╚═╝
Press Any Key To Close!
");
                Console.ReadKey();
                Environment.Exit(0);
            }
            while (true)
            {
                HELP();
            }
        }


        //██████╗ ███████╗███╗   ███╗ ██████╗ ███╗   ██╗
        //██╔══██╗██╔════╝████╗ ████║██╔═══██╗████╗  ██║
        //██║  ██║█████╗  ██╔████╔██║██║   ██║██╔██╗ ██║
        //██║  ██║██╔══╝  ██║╚██╔╝██║██║   ██║██║╚██╗██║
        //██████╔╝███████╗██║ ╚═╝ ██║╚██████╔╝██║ ╚████║
        //╚═════╝ ╚══════╝╚═╝     ╚═╝ ╚═════╝ ╚═╝  ╚═══╝

        public static bool DemonAPI(byte[] bytearray, SerialPort sp)
        {
            if (VersionRequested(bytearray, sp)) //Version request VV
            { return true; }
            if (EnableOnboard(bytearray, sp)) //Enable onboard datalogging.
            { return true; }
            if (!StandardCheckSum(bytearray)) //Checksum
            { return false; }
            if (SlowRead(bytearray, sp)) //Read bin bytes slow
            {
                TimeOut = 60;
                return true;
            }
            if (SlowWrite(bytearray, sp)) //Write bin bytes slow
            {
                TimeOut = 120;
                return true;
            }
            if (FastRead(bytearray, sp)) //Read bin bytes Fast
            {
                TimeOut = 60;
                return true;
            }
            if (FastWrite(bytearray, sp)) //Write bin bytes Fast
            {
                TimeOut = 600;
                return true;
            }
            if (SerialRequest(bytearray, sp)) //Serial number request
            { return true; }
            if (QCSRequest(bytearray, sp)) //Quick CheckSum request BMGJET Protocol
            { return true; }
            if (EEPROMRequest(bytearray, sp)) //EEPROM Information requested
            { return true; }
            if (EEPROMRequest2(bytearray, sp)) //EEPROM Information requested
            { return true; }
            if (BankActive(bytearray, sp)) //Select Active Emulation Bank.
            { return true; }
            if (BankStatic(bytearray, sp)) //Select Static Emulation Bank.
            { return true; }

            return false; //No valid commands found.
        }

        // ██████╗ ███████╗████████╗██████╗ ██╗ ██████╗██╗  ██╗
        //██╔═══██╗██╔════╝╚══██╔══╝██╔══██╗██║██╔════╝██║  ██║
        //██║   ██║███████╗   ██║   ██████╔╝██║██║     ███████║
        //██║   ██║╚════██║   ██║   ██╔══██╗██║██║     ██╔══██║
        //╚██████╔╝███████║   ██║   ██║  ██║██║╚██████╗██║  ██║
        // ╚═════╝ ╚══════╝   ╚═╝   ╚═╝  ╚═╝╚═╝ ╚═════╝╚═╝  ╚═╝
        public static bool OstrichAPI(byte[] bytearray, SerialPort sp)
        {
            if(VersionRequested(bytearray, sp)) //Version request VV
            {return true;}
            if (!StandardCheckSum(bytearray)) //Checksum
            {return false;}
            if (SlowRead(bytearray, sp)) //Read bin bytes slow
            {
                TimeOut = 60;
                return true;
            }
            if (SlowWrite(bytearray, sp)) //Write bin bytes slow
            {
                TimeOut = 120;
                return true;
            }
            if (FastRead(bytearray, sp)) //Read bin bytes Fast
            {
                TimeOut = 60;
                return true;
            }
            if (FastWrite(bytearray, sp)) //Write bin bytes Fast
            {
                TimeOut = 600;
                return true;
            }
            if (SerialRequest(bytearray, sp)) //Serial number request
            {return true;}
            if (QCSRequest(bytearray, sp)) //Quick CheckSum request BMGJET Protocol
            { return true; }
            if (EEPROMRequest(bytearray, sp)) //EEPROM Information requested
            { return true; }
            if (EEPROMRequest2(bytearray, sp)) //EEPROM Information requested
            { return true; }
            if (BankActive(bytearray, sp)) //Select Active Emulation Bank.
            { return true; }
            if (BankStatic(bytearray, sp)) //Select Static Emulation Bank.
            { return true; }
            return false; //No valid commands found.
        }

        //███╗   ███╗ ██████╗  █████╗ ████████╗███████╗███████╗
        //████╗ ████║██╔═══██╗██╔══██╗╚══██╔══╝██╔════╝██╔════╝
        //██╔████╔██║██║   ██║███████║   ██║   █████╗  ███████╗
        //██║╚██╔╝██║██║   ██║██╔══██║   ██║   ██╔══╝  ╚════██║
        //██║ ╚═╝ ██║╚██████╔╝██║  ██║   ██║   ███████╗███████║
        //╚═╝     ╚═╝ ╚═════╝ ╚═╝  ╚═╝   ╚═╝   ╚══════╝╚══════╝
        public static bool VersionRequested(byte[] bytearray, SerialPort sp)
        {
            //VV request
            if (bytearray[0] == 0x56 && bytearray[1] == 0x56)
            {
                TimeOut = 600;
                Console.WriteLine("Version Requested.");
                DataSender(Version, sp);
                return true;
            }
            return false;
        }
        public static bool BankStatic(byte[] bytearray, SerialPort sp)
        {
            //Get Static Emulation Bank
            //42 45 53 DA write
            //oo read
            if (bytearray[0] == 0x42 && bytearray[1] == 0x45 && bytearray[2] == 0x53 && bytearray[3] == 0xDA)
            {
                Console.WriteLine("Static Bank Info Requested");
                byte[] BANKINFO = new byte[] { 0x00 };
                DataSender(BANKINFO, sp);
                return true;
            }
            return false;
        }
        public static bool BankActive(byte[] bytearray, SerialPort sp)
        {
            //Get Active Emulation Bank Succeeded: Bank 0
            //42 52 52 Bank write
            //00            read
            if (bytearray[0] == 0x42 && bytearray[1] == 0x52)
            {
                Console.WriteLine("Active Bank Info Requested");
                byte[] BANKINFO = new byte[] { 0x00 };
                DataSender(BANKINFO, sp);
                return true;
            }
            if (bytearray[0] == 0x42 && bytearray[1] == 0x53)
            {
                Console.WriteLine("Active Bank Info Requested");
                DataSender(OK, sp);
                return true;
            }
            return false;
        }

        public static bool EEPROMRequest(byte[] bytearray, SerialPort sp)
        {
            //EEPROM Information requested
            if (bytearray[0] == 0x45 && bytearray[1] == 0x07 && bytearray[3] == 0x01)
            {
                Console.WriteLine("EEPROM Info Requested");
                byte[] EEPROMINFO = new byte[] { 0x50, 0x02, 0x00, 0x55, 0x02, 0x01, 0x10 };
                DataSender(EEPROMINFO, sp);
                return true;
            }
            return false;
        }


        public static bool EEPROMRequest2(byte[] bytearray, SerialPort sp)
        {
            //EEPROM Information requested
            if (bytearray[0] == 0x48 && bytearray[1] == 0x52 && bytearray[2] == 0x07 && bytearray[4] == 0x01 && bytearray[5] == 0xA2)
            {
                Console.WriteLine("EEPROM Info Requested");
                byte[] EEPROMINFO = new byte[] { 0x50, 0x02, 0x00, 0x55, 0x02, 0x01, 0x10 };
                if (Protocol == 0)
                {
                   EEPROMINFO[0] = 0x44;
                }
                DataSender(EEPROMINFO, sp);
                return true;
            }
            return false;
        }

        public static bool SerialRequest(byte[] bytearray, SerialPort sp)
        {
            if (bytearray[0] == 0x4E && bytearray[1] == 0x53)
            {
                Console.WriteLine("Serial Number Requested");
                DataSender(Serial, sp);
                return true;
            }
            return false;
        }

        public static bool StandardCheckSum(byte[] bytearray)
        {
            //Checksum used on most packets.
            byte Tchecksum = 0;
            int bytelen = bytearray.Length;
            byte Cchecksum = bytearray[bytelen - 1];
            //Calculate checksum
            for (int i = 0; i <= bytelen - 2; i++)
            {
                Tchecksum += bytearray[i];
            }

            //Check valid checksum.
            if (Tchecksum != Cchecksum)
            {
                Console.WriteLine("CheckSum Failed");
                return false; //Not valid stop processing
            }
            return true;
        }

        //Fast Write
        public static void BinFastWrite(byte[] bytearray, SerialPort sp)
        {
            int BlockSize = (256 * (bytearray[2]));

            if (bytearray.Length == BlockSize + 6) //normal
            {
                int Address = GetAddress(bytearray[3], bytearray[4]);

                //Pack bin with write bytes.
                for (int i = 0; i < BlockSize; i++)
                {
                    Bin[Address + i] = bytearray[i + 5];
                }
                byte[] OK = new byte[] { 0x4F };
                Console.WriteLine(BlockSize + " Bytes written to " + Address);
                DataSender(OK, sp);
            }
            else if (bytearray.Length == BlockSize + 8) //encrypt byte 3/4 random encrypt bytes
            {
                //Removed function to protect intellectual property
                Console.WriteLine("Encrypted fast write transfere");
                DataSender(OK, sp);
            }

        }

        //Slow Write
        public static void BinWrite(byte[] bytearray, SerialPort sp)
        {
            int BlockSize = GetBlockSize(bytearray[1]);

            if (bytearray.Length == BlockSize + 5)
            {
                int Address = GetAddress(bytearray[3], bytearray[2]);

                //Pack bin with write bytes.
                for (int i = 0; i < BlockSize; i++)
                {
                    Bin[Address + i] = bytearray[i + 4];
                }
                byte[] OK = new byte[] { 0x4F };
                Console.WriteLine(BlockSize + " Bytes written to " + Address);
                DataSender(OK, sp);
            }
            else if (bytearray.Length == 8) //encrypted slow write
            {
                //Removed function to protect intellectual property
                Console.WriteLine("Encrypted slow write transfere");
                DataSender(OK, sp);
            }

            }

        //Slow Read
        public static void BinRead(byte[] bytearray, SerialPort sp)
        {
            int BlockSize = GetBlockSize(bytearray[1]);
            if (bytearray.Length == 6) //normal
            {
                //Setup buffer
                byte[] Binbuff = new byte[BlockSize];
                int Address = GetAddress(bytearray[3], bytearray[2]);

                //Pack the buffer
                for (int i = 0; i <= BlockSize - 1; i++)
                {
                    Binbuff[i] = Bin[Address + i];
                }
                //Output buffer.
                Console.WriteLine(BlockSize + " Bytes read from " + Address);
                DataSender(checksum(Binbuff), sp);
            }
            else if (bytearray.Length == 8) //encrypted fast read
            {
                //Removed function to protect intellectual property
                Console.WriteLine("Encrypted slow read transfere");
                DataSender(OK, sp);
            }

        }
        //Fast read
        public static void BinFastRead(byte[] bytearray, SerialPort sp)
        {
            int BlockSize = (256 * (bytearray[2]));

             if (bytearray.Length == 5) //fast read
            {
                int Address = GetAddress(bytearray[3], bytearray[4]);

            //Setup buffer
            byte[] Binbuff = new byte[BlockSize];

            //Pack the buffer
            for (int i = 0; i <= BlockSize - 1; i++)
            {
                Binbuff[i] = Bin[Address + i];
            }
            //Output buffer.
            Console.WriteLine(BlockSize + " Bytes read from " + Address);
            DataSender(checksum(Binbuff), sp);
        }
            else if (bytearray.Length == 8) //encrypted fast read
            {
                //Removed function to protect intellectual property
                Console.WriteLine("Encrypted fast read transfere");
                DataSender(OK, sp);
            }
        }

        //Block size correction.
        public static int GetBlockSize(int BlockSize)
        {
            if (BlockSize == 0)
            {
                BlockSize = 256;
            }
            return BlockSize;
        }

        //Get byte array address
        public static int GetAddress(int MSB, int LSB)
        {
            int Address = (MSB | LSB << 8);
            if (Address >= Bin.Length)
            {
                Address -= 32768; //Resize 64K back to 32K.
            }
            return Address;
        }

        //Calculate Checksum and create new byte array with it added on.
        public static byte[] checksum(byte[] bArray)
        {
            byte cs = 0;
            foreach (byte raw in bArray)
            {
                cs += raw;
            }
            byte[] newArray = new byte[bArray.Length + 1];
            bArray.CopyTo(newArray, 0);
            newArray[newArray.Length - 1] = cs;
            return newArray;
        }
        public static bool SlowRead(byte[] bytearray, SerialPort sp)
        {
            if (bytearray[0] == 0x52 && bytearray.Length == 5) //R
            {
                BinRead(bytearray, sp);
                return true;
            }
            return false;
        }
        public static bool SlowWrite(byte[] bytearray, SerialPort sp) //W
        {
            if (bytearray[0] == 0x57)
            {
                BinWrite(bytearray, sp);
                return true;
            }
            return false;
        }
        public static bool FastRead(byte[] bytearray, SerialPort sp) //ZR
        {
            if (bytearray[0] == 0x5A && bytearray[1] == 0x52)
            {
                BinFastRead(bytearray, sp);
                return true;
            }
            return false;
        }
        public static bool FastWrite(byte[] bytearray, SerialPort sp) //ZW
        {
            if (bytearray[0] == 0x5A && bytearray[1] == 0x57)
            {
                BinFastWrite(bytearray, sp);
                return true;
            }
            return false;
        }

        public static bool EnableOnboard(byte[] bytearray, SerialPort sp) //DOLY Enable onboard
        {
            if (bytearray[0] == 0x44 && bytearray[1] == 0x4F && bytearray[2] == 0x4C  && bytearray[3] == 0x59)
            {
                DataSender(OK, sp);
                return true;
            }
            if (bytearray[0] == 0x44 && bytearray[1] == 0x4F && bytearray[2] == 0x4C && bytearray[3] == 0x79)
            {
                DataSender(OK, sp);
                return true;
            }
            return false;
        }


        //███████╗██╗  ██╗████████╗██████╗  █████╗
        //██╔════╝╚██╗██╔╝╚══██╔══╝██╔══██╗██╔══██╗
        //█████╗   ╚███╔╝    ██║   ██████╔╝███████║
        //██╔══╝   ██╔██╗    ██║   ██╔══██╗██╔══██║
        //███████╗██╔╝ ██╗   ██║   ██║  ██║██║  ██║
        //╚══════╝╚═╝  ╚═╝   ╚═╝   ╚═╝  ╚═╝╚═╝  ╚═╝

        //Quick Check Sum
        //5a 43 53 PacketCS     write
        //MemoryCS              read
        public static bool QCSRequest(byte[] bytearray, SerialPort sp)
        {
            if (bytearray[0] == 0x5A && bytearray[1] == 0x43 && bytearray[2] == 0x53)
            {
                QuckCS(sp);
                return true;
            }
            return false;
        }
        public static void QuckCS(SerialPort sp)
        {
            //Sum of Emulator Memory.
            byte[] QCS = new byte[1];
            foreach (byte B in Bin)
            {
                QCS[0] += B;
            }
            Console.WriteLine("Quick CheckSum: " + QCS[0].ToString("X2"));
            DataSender(QCS, sp);
        }
    }
}

yosupra13

#2 ◈ 2025-10-06

Re: Emulator Simulator [C# code]

Thank you !!!