public byte Read(byte[] saveRAM)
        {
            switch (ReadMode)
            {
            case EEPROMReadMode.ReadNew:
                // A new value clocking out

                ReadMode = EEPROMReadMode.ReadOld;
                byte ret = Read(saveRAM);

                if (++BitsRead == 8)
                {
                    // Increment address
                    BitsRead = 0;
                    ++Address;

                    if (Address % 2 == 0)
                    {
                        WriteMode   = EEPROMWriteMode.Instruction;
                        ReadMode    = EEPROMReadMode.Hold;
                        BitsWritten = 0;
                        Value       = 0;
                    }
                }

                return(ret);

            case EEPROMReadMode.ReadOld:
                // repeat old value

                byte bit = (byte)((saveRAM[Address % saveRAM.Length] >> (7 - BitsRead)) & 1);

                return((byte)((byte)(Flags | EEPROMFlags.Clock) | bit));

            default:
                // ready/busy flag is always ready in this emulation
                return((byte)(Flags | EEPROMFlags.Clock | EEPROMFlags.Ready));
            }
        }
        public void Write(byte bit, byte[] saveRAM)
        {
            // new instruction?
            if ((bit & 4) == 0)
            {
                WriteMode   = EEPROMWriteMode.Instruction;
                ReadMode    = EEPROMReadMode.Hold;
                BitsWritten = 0;
                Value       = 0;

                Flags = (EEPROMFlags)bit & ~EEPROMFlags.Ready;
                return;
            }

            // clock low to high?
            if ((bit & (byte)EEPROMFlags.Clock) != 0 && (Flags & EEPROMFlags.Clock) == 0)
            {
                // all modes shift in a larger value
                Value = (ushort)((Value << 1) | (bit & 1));
                ++BitsWritten;

                switch (WriteMode)
                {
                case EEPROMWriteMode.Instruction:
                    // Process opcode including start bit

                    // check start bit
                    if ((Value & 0x100) == 0)
                    {
                        return;
                    }

                    byte op = (byte)Value;
                    Value       = 0;
                    BitsWritten = 0;

                    switch (op & 0xC0)
                    {
                    case 0x00:
                        // non-addressed commands
                        switch (op & 0xF0)
                        {
                        case 0x00:
                            // EWDS: write disable
                            WriteEnable = false;
                            return;

                        case 0x10:
                            // WRAL: write to all addresses (silly)
                            WriteMode = EEPROMWriteMode.WriteAll;
                            ReadMode  = EEPROMReadMode.Hold;
                            return;

                        case 0x20:
                            // ERAL: erase all addresses
                            if (WriteEnable)
                            {
                                for (int i = 0; i < saveRAM.Length; ++i)
                                {
                                    saveRAM[i] = 0xFF;
                                }
                            }
                            ReadMode = EEPROMReadMode.Hold;
                            return;

                        case 0x30:
                            // EWEN: write enable
                            WriteEnable = true;
                            return;

                        default:
                            // impossible
                            return;
                        }

                    case 0x40:
                        // WRITE
                        Address   = (ushort)((op & 0x3F) << 1);
                        WriteMode = EEPROMWriteMode.WriteData;
                        ReadMode  = EEPROMReadMode.Hold;
                        return;

                    case 0x80:
                        // READ
                        Address   = (ushort)((op & 0x3F) << 1);
                        ReadMode  = EEPROMReadMode.Hold;
                        WriteMode = EEPROMWriteMode.Read;
                        BitsRead  = 0;
                        return;

                    case 0xC0:
                        // ERASE
                        Address = (ushort)((op & 0x3F) << 1);
                        if (WriteEnable)
                        {
                            saveRAM[Address % saveRAM.Length]       = 0xFF;
                            saveRAM[(Address + 1) % saveRAM.Length] = 0xFF;
                        }
                        ReadMode = EEPROMReadMode.Hold;
                        return;

                    default:
                        // impossible
                        return;
                    }

                case EEPROMWriteMode.WriteData:
                    // Write bits

                    if (BitsWritten < 16)
                    {
                        return;
                    }

                    if (WriteEnable)
                    {
                        saveRAM[Address % saveRAM.Length]       = (byte)(Value >> 8);
                        saveRAM[(Address + 1) % saveRAM.Length] = (byte)Value;
                    }
                    WriteMode = EEPROMWriteMode.Instruction;

                    Value       = 0;
                    BitsWritten = 0;
                    return;

                case EEPROMWriteMode.WriteAll:
                    // write to ALL addresses

                    if (BitsWritten < 16)
                    {
                        return;
                    }

                    Value       = 0;
                    BitsWritten = 0;

                    if (WriteEnable)
                    {
                        for (int i = 0; i < saveRAM.Length; i += 2)
                        {
                            saveRAM[i % saveRAM.Length]       = (byte)Value;
                            saveRAM[(i + 1) % saveRAM.Length] = (byte)(Value >> 8);
                        }
                    }
                    WriteMode = EEPROMWriteMode.Instruction;
                    return;

                case EEPROMWriteMode.Read:
                    // Clock a new value out
                    ReadMode = EEPROMReadMode.ReadNew;

                    return;
                }
            }

            Flags = (EEPROMFlags)bit & ~EEPROMFlags.Ready;
        }