示例#1
0
 /// <summary>
 /// Injects code into the memory
 /// </summary>
 /// <param name="addr">Start address</param>
 /// <param name="code">Code to inject</param>
 /// <remarks>The code leaves the ROM area untouched.</remarks>
 public void InjectCodeToMemory(ushort addr, IReadOnlyCollection <byte> code)
 {
     foreach (var codeByte in code)
     {
         MemoryDevice.Write(addr++, codeByte);
     }
 }
示例#2
0
        /// <summary>
        /// Prepares the custom code for running, as if it were started
        /// with the RUN command
        /// </summary>
        public void PrepareRunMode()
        {
            // --- Set the keyboard in "L" mode
            var flags = MemoryDevice.Read(0x5C3B);

            flags |= 0x08;
            MemoryDevice.Write(0x5C3B, flags);
        }
示例#3
0
 /// <summary>
 /// Prepares the custom code for running, as if it were started
 /// with the RUN command
 /// </summary>
 public void PrepareRunMode(HashSet <string> options)
 {
     if (!options.Contains("cursork"))
     {
         // --- Set the keyboard in "L" mode
         var flags = MemoryDevice.Read(0x5C3B);
         flags |= 0x08;
         MemoryDevice.Write(0x5C3B, flags);
     }
 }
示例#4
0
        /// <summary>
        /// Prepares the custom code for running, as if it were started
        /// with the RUN command
        /// </summary>
        public void PrepareRunMode()
        {
            // --- Set the keyboard in "L" mode
            var flags = MemoryDevice.Read(0x5C3B);

            flags |= 0x08;
            MemoryDevice.Write(0x5C3B, flags);

            // --- Allow interrupts
            RunsInMaskableInterrupt = false;
        }
示例#5
0
 /// <summary>
 /// Clears the screep
 /// </summary>
 public void ClearScreen()
 {
     // --- Clear the screen
     for (var i = 0; i < 0x1800; i++)
     {
         MemoryDevice.Write((ushort)(0x4000 + i), 0x00);
     }
     for (var i = 0; i < 0x300; i++)
     {
         MemoryDevice.Write((ushort)(0x5800 + i), 0x38);
     }
 }
示例#6
0
        /// <summary>
        /// Injects code into the memory
        /// </summary>
        /// <param name="addr">Start address</param>
        /// <param name="code">Code to inject</param>
        /// <remarks>The code leaves the ROM area untouched.</remarks>
        public void InjectCodeToMemory(ushort addr, IReadOnlyCollection <byte> code)
        {
            // --- Clear the screen
            for (var i = 0; i < 0x1800; i++)
            {
                MemoryDevice.Write((ushort)(0x4000 + i), 0x00);
            }
            for (var i = 0; i < 0x300; i++)
            {
                MemoryDevice.Write((ushort)(0x5800 + i), 0x38);
            }

            // --- Now, inject the code
            foreach (var codeByte in code)
            {
                MemoryDevice.Write(addr++, codeByte);
            }
        }
示例#7
0
 /// <summary>
 /// Writes a byte to the memory
 /// </summary>
 /// <param name="addr">Memory address</param>
 /// <param name="value">Data byte</param>
 public void WriteSpectrumMemory(ushort addr, byte value) =>
 MemoryDevice.Write(addr, value);
示例#8
0
        /// <summary>
        /// Loads an .srec into memory.
        /// Based on description at http://en.wikipedia.org/wiki/SREC_(file_format)
        /// </summary>
        /// <param name="stream">The stream to read the .srec from.</param>
        /// <returns>The number of words loaded.</returns>
        public uint LoadSrec(Stream stream)
        {
            StreamReader reader      = new StreamReader(stream);
            uint         wordsLoaded = 0;

            //Note: All hex values are big endian.

            //Read records
            while (!reader.EndOfStream)
            {
                string line     = reader.ReadLine();
                int    index    = 0;
                int    checksum = 0;

                //Start code, always 'S'
                if (line[index++] != 'S')
                {
                    throw new InvalidDataException("Expecting 'S'");
                }

                //Record type, 1 digit, 0-9, defining the data field
                //0: Vendor-specific data
                //1: 16-bit data sequence
                //2: 24 bit data sequence
                //3: 32-bit data sequence
                //5: Count of data sequences in the file. Not required.
                //7: Starting address for the program, 32 bit address
                //8: Starting address for the program, 24 bit address
                //9: Starting address for the program, 16 bit address
                int recordType    = Convert.ToInt32(line[index++].ToString(), 16);
                int addressLength = 0;
                switch (recordType)
                {
                case 0:
                case 1:
                case 5:
                case 9:
                    addressLength = 2;
                    break;

                case 2:
                case 8:
                    addressLength = 3;
                    break;

                case 3:
                case 7:
                    addressLength = 4;
                    break;

                default:
                    throw new InvalidDataException("Unknown record type");
                }

                //Byte count, 2 digits, number of bytes (2 hex digits) that follow (in address, data, checksum)
                int byteCount = Convert.ToInt32(line.Substring(index, 2), 16);
                index    += 2;
                checksum += byteCount;

                //Address, 4, 6 or 8 hex digits determined by the record type
                for (int i = 0; i < addressLength; i++)
                {
                    string ch = line.Substring(index + i * 2, 2);
                    checksum += Convert.ToInt32(ch, 16);
                }

                int address = Convert.ToInt32(line.Substring(index, addressLength * 2), 16);
                index     += addressLength * 2;
                byteCount -= addressLength;

                //Data, a sequence of bytes.
                byte[] data = new byte[byteCount - 1];
                for (int i = 0; i < data.Length; i++)
                {
                    data[i]   = (byte)Convert.ToInt32(line.Substring(index, 2), 16);
                    index    += 2;
                    checksum += data[i];
                }

                //Checksum, two hex digits. Inverted LSB of the sum of values, including byte count, address and all data.
                int readChecksum = (byte)Convert.ToInt32(line.Substring(index, 2), 16);
                checksum = (~checksum & 0xFF);
                if (readChecksum != checksum)
                {
                    throw new InvalidDataException("Failed Checksum!");
                }

                //Put in memory
                Debug.Assert(data.Length % 4 == 0, "Data should only contain full 32-bit words.");
                switch (recordType)
                {
                case 3:     //data intended to be stored in memory.
                    List <uint> memContents = new List <uint>();
                    for (int i = 0; i < data.Length; i += 4)
                    {
                        uint val = 0;
                        for (int j = i; j < i + 4; j++)
                        {
                            val <<= 8;
                            val  |= data[j];
                        }
                        memContents.Add(val);
                    }

                    mAddressBus.IsWrite = true;
                    for (int i = 0; i < memContents.Count; i++)
                    {
                        mDataBus.Write(memContents[i]);
                        mAddressBus.Write((uint)(i + address));
                        RAM.Write();
                        ROM.Write();
                        wordsLoaded++;
                    }
                    break;

                case 7:     //entry point for the program.
                    CPU.PC = (uint)address;
                    break;
                }
            }

            return(wordsLoaded);
        }