Esempio n. 1
0
 protected CpuTestBase()
 {
     mbbsEmuMemoryCore   = new MemoryCore();
     mbbsEmuCpuRegisters = new CpuRegisters();
     mbbsEmuCpuCore      = new CpuCore();
     mbbsEmuCpuCore.Reset(mbbsEmuMemoryCore, mbbsEmuCpuRegisters, null);
 }
Esempio n. 2
0
        protected override async void OnCreateControl()
        {
            base.OnCreateControl();

            DoubleBuffered = true;

            _resizeGripRect = new Rectangle(Width - 12, Height - 12, 11, 11);

            int y = CpuMonitor.Properties.Settings.Default.BorderSize;


            int nCores = await CpuCore.GetCpuCores();

            for (int i = 0; i < nCores; i++)
            {
                var coreControl = new CpuControl(i);

                _cpuCores.Add(coreControl);
                Controls.Add(coreControl);

                coreControl.Top   = y;
                coreControl.Left  = CpuMonitor.Properties.Settings.Default.BorderSize;
                coreControl.Width = Width - (CpuMonitor.Properties.Settings.Default.BorderSize * 2);

                y += coreControl.Height;
            }
        }
Esempio n. 3
0
        public static void InfoRegisters(this ILogger l, CpuCore cpu)
        {
            var output = new StringBuilder();

            output.Append($"AX={cpu.Registers.AX:X4}  ");
            output.Append($"BX={cpu.Registers.BX:X4}  ");
            output.Append($"CX={cpu.Registers.CX:X4}  ");
            output.Append($"DX={cpu.Registers.DX:X4}  ");
            output.Append($"DS={cpu.Registers.DS:X4}  ");
            output.AppendLine($"ES={cpu.Registers.ES:X4}");
            output.Append($"SI={cpu.Registers.SI:X4}  ");
            output.Append($"DI={cpu.Registers.DI:X4}  ");
            output.Append($"SS={cpu.Registers.SS:X4}  ");
            output.Append($"IP={cpu.Registers.IP:X4}  ");
            output.Append($"SP={cpu.Registers.SP:X4}  ");
            output.AppendLine($"BP={cpu.Registers.BP:X4}");

            output.Append(cpu.Registers.F.IsFlagSet(EnumFlags.CF) ? "C" : "c");
            output.Append(cpu.Registers.F.IsFlagSet(EnumFlags.PF) ? "P" : "p");
            output.Append(cpu.Registers.F.IsFlagSet(EnumFlags.ZF) ? "Z" : "z");
            output.Append(cpu.Registers.F.IsFlagSet(EnumFlags.SF) ? "S" : "s");
            output.Append(cpu.Registers.F.IsFlagSet(EnumFlags.OF) ? "O" : "o");

            foreach (var line in output.ToString().Split("\r\n"))
            {
                l.Info(line);
            }
        }
        protected ExportedModuleTestBase(string modulePath)
        {
            mbbsEmuMemoryCore   = new MemoryCore();
            mbbsEmuCpuRegisters = new CpuRegisters();
            mbbsEmuCpuCore      = new CpuCore();
            mbbsModule          = new MbbsModule(FileUtility.CreateForTest(), _serviceResolver.GetService <ILogger>(), null, modulePath, mbbsEmuMemoryCore);

            testSessions = new PointerDictionary <SessionBase>();
            testSessions.Allocate(new TestSession(null));
            testSessions.Allocate(new TestSession(null));

            majorbbs = new HostProcess.ExportedModules.Majorbbs(
                _serviceResolver.GetService <ILogger>(),
                _serviceResolver.GetService <AppSettings>(),
                _serviceResolver.GetService <IFileUtility>(),
                _serviceResolver.GetService <IGlobalCache>(),
                mbbsModule,
                testSessions,
                _serviceResolver.GetService <IAccountKeyRepository>(),
                _serviceResolver.GetService <IAccountRepository>());

            galgsbl = new HostProcess.ExportedModules.Galgsbl(
                _serviceResolver.GetService <ILogger>(),
                _serviceResolver.GetService <AppSettings>(),
                _serviceResolver.GetService <IFileUtility>(),
                _serviceResolver.GetService <IGlobalCache>(),
                mbbsModule,
                testSessions);

            mbbsEmuCpuCore.Reset(mbbsEmuMemoryCore, mbbsEmuCpuRegisters, ExportedFunctionDelegate);
        }
Esempio n. 5
0
 static Program()
 {
     mbbsEmuMemoryCore   = new MemoryCore();
     mbbsEmuCpuRegisters = new CpuRegisters();
     mbbsEmuCpuCore      = new CpuCore();
     mbbsEmuCpuCore.Reset(mbbsEmuMemoryCore, mbbsEmuCpuRegisters, null);
 }
Esempio n. 6
0
        public static void InfoRegisters(this ILogger l, CpuCore cpu)
        {
            var output = new StringBuilder();

            output.Append($"AX={cpu.Registers.AX:X4}  ");
            output.Append($"BX={cpu.Registers.BX:X4}  ");
            output.Append($"CX={cpu.Registers.CX:X4}  ");
            output.Append($"DX={cpu.Registers.DX:X4}  ");
            output.Append($"DS={cpu.Registers.DS:X4}  ");
            output.AppendLine($"ES={cpu.Registers.ES:X4}");
            output.Append($"SI={cpu.Registers.SI:X4}  ");
            output.Append($"DI={cpu.Registers.DI:X4}  ");
            output.Append($"SS={cpu.Registers.SS:X4}  ");
            output.Append($"IP={cpu.Registers.IP:X4}  ");
            output.Append($"SP={cpu.Registers.SP:X4}  ");
            output.AppendLine($"BP={cpu.Registers.BP:X4}");

            output.Append(cpu.Registers.CarryFlag ? "C" : "c");
            //output.Append(cpu.Registers.Parity ? "P" : "p");
            output.Append(cpu.Registers.ZeroFlag ? "Z" : "z");
            output.Append(cpu.Registers.SignFlag ? "S" : "s");
            output.Append(cpu.Registers.OverflowFlag ? "O" : "o");

            foreach (var line in output.ToString().Split("\r\n"))
            {
                l.Info(line);
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Fx0A - LD Vx, K
        ///Wait for a key press, store the value of the key in Vx.
        ///
        ///All execution stops until a key is pressed, then the value of that key is stored in Vx.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="instruction"></param>
        /// <returns></returns>
        private static bool LDK(CpuCore context, Instruction instruction)
        {
            var key = context.Input.WaitUntilKeyDown();

            context.GPR[instruction.X] = ( byte )key;
            return(true);
        }
Esempio n. 8
0
 public Emulator(EmulatorConfig config)
 {
     Memory  = new Memory();
     Display = new ConsoleDisplayDevice();
     Sound   = new WindowsBeepSoundDevice();
     Input   = new WindowsKeyboardInputDevice();
     Cpu     = new CpuCore(Memory, Display, Sound, Input, new InstructionInterpreter());
 }
Esempio n. 9
0
 protected MajorbbsTestBase()
 {
     mbbsEmuMemoryCore   = new MemoryCore();
     mbbsEmuCpuRegisters = new CpuRegisters();
     mbbsEmuCpuCore      = new CpuCore();
     majorbbs            = new HostProcess.ExportedModules.Majorbbs(new MbbsModule(null, string.Empty, mbbsEmuMemoryCore), new PointerDictionary <Session.SessionBase>());
     mbbsEmuCpuCore.Reset(mbbsEmuMemoryCore, mbbsEmuCpuRegisters, MajorbbsFunctionDelegate);
 }
Esempio n. 10
0
        /// <summary>
        /// 3xkk - SE Vx, byte
        ///Skip next instruction if Vx = kk.
        ///
        ///The interpreter compares register Vx to kk, and if they are equal, increments the program counter by 2.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="instruction"></param>
        /// <returns></returns>
        private static bool SEIMM(CpuCore context, Instruction instruction)
        {
            if (context.GPR[instruction.X] == instruction.KK)
            {
                context.PC += Instruction.SIZE;
            }

            return(true);
        }
Esempio n. 11
0
        /// <summary>
        /// 9xy0 - SNE Vx, Vy
        ///Skip next instruction if Vx != Vy.
        ///
        ///The values of Vx and Vy are compared, and if they are not equal, the program counter is increased by 2.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="instruction"></param>
        /// <returns></returns>
        private static bool SNE(CpuCore context, Instruction instruction)
        {
            if (context.GPR[instruction.X] != context.GPR[instruction.Y])
            {
                context.PC += Instruction.SIZE;
            }

            return(true);
        }
Esempio n. 12
0
        /// <summary>
        /// 1nnn - JP addr
        ///Jump to location nnn.
        ///
        ///The interpreter sets the program counter to nnn.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="instruction"></param>
        /// <returns></returns>
        private static bool JP(CpuCore context, Instruction instruction)
        {
            if (context.PC == instruction.NNN)
            {
                Debug.WriteLine("JP: Branch to self");
            }

            context.PC = instruction.NNN;
            return(false);
        }
Esempio n. 13
0
        /// <summary>
        /// Fx65 - LD Vx, [I]
        ///Read registers V0 through Vx from memory starting at location I.
        ///
        ///The interpreter reads values from memory starting at location I into registers V0 through Vx.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="instruction"></param>
        /// <returns></returns>
        private static bool LDRS(CpuCore context, Instruction instruction)
        {
            var count = instruction.X + 1;

            for (int i = 0; i < count; i++)
            {
                context.GPR[i] = context.Memory.ReadByte(( ushort )(context.I + i));
            }

            return(true);
        }
Esempio n. 14
0
        /// <summary>
        /// ExA1 - SKNP Vx
        ///Skip next instruction if key with the value of Vx is not pressed.
        ///
        ///Checks the keyboard, and if the key corresponding to the value of Vx is currently in the up position, PC is increased by 2.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="instruction"></param>
        /// <returns></returns>
        private static bool SKNP(CpuCore context, Instruction instruction)
        {
            var key = context.GPR[instruction.X];

            if (!context.Input.IsKeyDown(( Key )key))
            {
                context.PC += Instruction.SIZE;
            }

            return(true);
        }
Esempio n. 15
0
        /// <summary>
        /// Bnnn - JP V0, addr
        ///Jump to location nnn + V0.
        ///
        ///The program counter is set to nnn plus the value of V0.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="instruction"></param>
        /// <returns></returns>
        private static bool JPV0(CpuCore context, Instruction instruction)
        {
            var pc = ( ushort )(instruction.NNN + context.V0);

            if (context.PC == pc)
            {
                Debug.WriteLine("JPV0: Branch to self");
            }

            context.PC = pc;
            return(false);
        }
Esempio n. 16
0
        /// <summary>
        /// Fx33 - LD B, Vx
        ///Store BCD representation of Vx in memory locations I, I+1, and I+2.
        ///
        ///The interpreter takes the decimal value of Vx, and places the hundreds digit in memory at location in I, the tens digit at location I+1, and the ones digit at location I+2.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="instruction"></param>
        /// <returns></returns>
        private static bool LDBCD(CpuCore context, Instruction instruction)
        {
            var vx       = context.GPR[instruction.X];
            var hundreds = ( byte )((vx / 100) % 10);
            var tens     = ( byte )(vx / 10);
            var ones     = ( byte )(vx % 10);

            context.Memory.WriteByte(context.I, hundreds);
            context.Memory.WriteByte((ushort)(context.I + 1), tens);
            context.Memory.WriteByte((ushort)(context.I + 2), ones);
            return(true);
        }
Esempio n. 17
0
        /// <summary>
        /// 00EE - RET
        ///Return from a subroutine.
        ///
        ///The interpreter sets the program counter to the address at the top of the stack, then subtracts 1 from the stack pointer.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="instruction"></param>
        /// <returns></returns>
        private static bool RET(CpuCore context, Instruction instruction)
        {
            if (context.SP == 0)
#if DEBUG
            { throw new StackUnderflowException(); }
#else
            { return(true); }
#endif

            context.PC = context.Stack[context.SP--];
            return(true);
        }
Esempio n. 18
0
        /// <summary>
        /// 2nnn - CALL addr
        ///Call subroutine at nnn.
        ///
        ///The interpreter increments the stack pointer, then puts the current PC on the top of the stack. The PC is then set to nnn.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="instruction"></param>
        /// <returns></returns>
        private static bool CALL(CpuCore context, Instruction instruction)
        {
            if (context.SP + 1 >= context.Stack.Length)
#if DEBUG
            { throw new StackOverflowException(); }
#else
            { return(true); }
#endif

            context.Stack[++context.SP] = context.PC;
            context.PC = instruction.NNN;
            return(false);
        }
Esempio n. 19
0
 protected MajorbbsTestBase()
 {
     mbbsEmuMemoryCore   = new MemoryCore();
     mbbsEmuCpuRegisters = new CpuRegisters();
     mbbsEmuCpuCore      = new CpuCore();
     mbbsModule          = new MbbsModule(FileUtility.CreateForTest(), _serviceResolver.GetService <ILogger>(), null, string.Empty, mbbsEmuMemoryCore);
     majorbbs            = new HostProcess.ExportedModules.Majorbbs(
         _serviceResolver.GetService <ILogger>(),
         _serviceResolver.GetService <IConfiguration>(),
         _serviceResolver.GetService <IFileUtility>(),
         _serviceResolver.GetService <IGlobalCache>(),
         mbbsModule,
         new PointerDictionary <Session.SessionBase>());
     mbbsEmuCpuCore.Reset(mbbsEmuMemoryCore, mbbsEmuCpuRegisters, MajorbbsFunctionDelegate);
 }
Esempio n. 20
0
        public Kernel(Xbox box)
        {
            Box = box;
            Cpu = box.Cpu;
            foreach (var method in typeof(Kernel).GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public))
            {
                var attr = method.GetCustomAttribute <ExportAttribute>();
                if (attr != null)
                {
                    Functions[attr.Number] = MakeWrapper(method, attr.CallingConvention);
                }
            }

            Console.WriteLine($"Implemented {Functions.Count}/366 kernel functions");
        }
Esempio n. 21
0
        private void Execute(string[] args)
        {
            var realMode = args.Length == 1 && (args[0].Equals("-realmode") || args[0].Equals("-real"));

            if (realMode)
            {
                memoryCore = realModeMemoryCore = new RealModeMemoryCore(logger: null);
            }
            else
            {
                memoryCore = protectedModeMemoryCore = new ProtectedModeMemoryCore(null);
            }

            mbbsEmuCpuCore      = new CpuCore(logger: null);
            mbbsEmuCpuRegisters = (ICpuRegisters)mbbsEmuCpuCore;
            mbbsEmuCpuCore.Reset(memoryCore, null, null, null);

            // Reset
            mbbsEmuCpuRegisters.Zero();
            mbbsEmuCpuCore.Reset();
            memoryCore.Clear();
            mbbsEmuCpuCore.Registers.CS = 0x1000;
            mbbsEmuCpuCore.Registers.DS = 2;
            mbbsEmuCpuCore.Registers.IP = 0;

            var instructions = new Assembler(16);
            var label_start  = instructions.CreateLabel();
            var label_loop   = instructions.CreateLabel();

            instructions.Label(ref label_start);
            instructions.mov(__word_ptr[0], 1);
            instructions.Label(ref label_loop);
            instructions.mov(ax, __word_ptr[0]);
            instructions.cmp(ax, 0x7FFF);
            instructions.je(label_start);
            instructions.inc(__word_ptr[0]);
            instructions.jmp(label_loop);

            CreateCodeSegment(instructions);
            CreateDataSegment(new ReadOnlySpan <byte>());

            _isRunning = true;
            new Thread(RunThread).Start();
            new Thread(MonitorThread).Start();

            Console.ReadKey();
            _isRunning = false;
        }
Esempio n. 22
0
        /// <summary>
        /// 8xy4 - ADD Vx, Vy
        ///Set Vx = Vx + Vy, set VF = carry.
        ///
        ///The values of Vx and Vy are added together. If the result is greater than 8 bits (i.e., &gt; 255,) VF is set to 1, otherwise 0. Only the lowest 8 bits of the result are kept, and stored in Vx.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="instruction"></param>
        /// <returns></returns>
        private static bool ADD(CpuCore context, Instruction instruction)
        {
            var res = context.GPR[instruction.X] + context.GPR[instruction.Y];

            if (res > byte.MaxValue)
            {
                context.VF = 1;
            }
            else
            {
                context.VF = 0;
            }

            context.GPR[instruction.X] = ( byte )res;
            return(true);
        }
Esempio n. 23
0
        /// <summary>
        /// 8xy6 - SHR Vx {, Vy}
        ///Set Vx = Vx SHR 1.
        ///
        ///If the least-significant bit of Vx is 1, then VF is set to 1, otherwise 0. Then Vx is divided by 2.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="instruction"></param>
        /// <returns></returns>
        private static bool SHR(CpuCore context, Instruction instruction)
        {
            var x = instruction.X;

            if ((context.GPR[x] & 1) == 1)
            {
                context.VF = 1;
            }
            else
            {
                context.VF = 0;
            }

            context.GPR[x] /= 2;
            return(true);
        }
Esempio n. 24
0
        /// <summary>
        /// 8xyE - SHL Vx {, Vy}
        ///Set Vx = Vx SHL 1.
        ///
        ///If the most-significant bit of Vx is 1, then VF is set to 1, otherwise to 0. Then Vx is multiplied by 2.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="instruction"></param>
        /// <returns></returns>
        private static bool SHL(CpuCore context, Instruction instruction)
        {
            var x = instruction.X;

            if ((context.GPR[x] & 0x80) == 0x80)
            {
                context.VF = 1;
            }
            else
            {
                context.VF = 0;
            }

            context.GPR[x] *= 2;
            return(true);
        }
Esempio n. 25
0
        protected ExportedModuleTestBase(string modulePath)
        {
            _serviceResolver = new ServiceResolver(fakeClock, SessionBuilder.ForTest($"MBBSDb_{RANDOM.Next()}"));
            var textVariableService = _serviceResolver.GetService <ITextVariableService>();

            mbbsEmuMemoryCore   = mbbsEmuProtectedModeMemoryCore = new ProtectedModeMemoryCore(_serviceResolver.GetService <ILogger>());
            mbbsEmuCpuCore      = new CpuCore(_serviceResolver.GetService <ILogger>());
            mbbsEmuCpuRegisters = mbbsEmuCpuCore;

            var testModuleConfig = new ModuleConfiguration {
                ModulePath = modulePath, ModuleEnabled = true
            };

            mbbsModule = new MbbsModule(FileUtility.CreateForTest(), fakeClock, _serviceResolver.GetService <ILogger>(), testModuleConfig, mbbsEmuProtectedModeMemoryCore);

            testSessions = new PointerDictionary <SessionBase>();
            testSessions.Allocate(new TestSession(null, textVariableService));
            testSessions.Allocate(new TestSession(null, textVariableService));

            majorbbs = new HostProcess.ExportedModules.Majorbbs(
                _serviceResolver.GetService <IClock>(),
                _serviceResolver.GetService <ILogger>(),
                _serviceResolver.GetService <AppSettings>(),
                _serviceResolver.GetService <IFileUtility>(),
                _serviceResolver.GetService <IGlobalCache>(),
                mbbsModule,
                testSessions,
                _serviceResolver.GetService <IAccountKeyRepository>(),
                _serviceResolver.GetService <IAccountRepository>(),
                textVariableService);

            galgsbl = new HostProcess.ExportedModules.Galgsbl(
                _serviceResolver.GetService <IClock>(),
                _serviceResolver.GetService <ILogger>(),
                _serviceResolver.GetService <AppSettings>(),
                _serviceResolver.GetService <IFileUtility>(),
                _serviceResolver.GetService <IGlobalCache>(),
                mbbsModule,
                testSessions,
                textVariableService);

            mbbsEmuCpuCore.Reset(
                mbbsEmuMemoryCore,
                (ordinal, functionOrdinal) => ExportedFunctionDelegate(ordinal, functionOrdinal, offsetsOnly: false),
                null,
                null);
        }
Esempio n. 26
0
        /// <summary>
        /// 8xy5 - SUB Vx, Vy
        ///Set Vx = Vx - Vy, set VF = NOT borrow.
        ///
        ///If Vx &gt; Vy, then VF is set to 1, otherwise 0. Then Vy is subtracted from Vx, and the results stored in Vx.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="instruction"></param>
        /// <returns></returns>
        private static bool SUB(CpuCore context, Instruction instruction)
        {
            var x = instruction.X;
            var y = instruction.Y;

            if (context.GPR[x] > context.GPR[y])
            {
                context.VF = 1;
            }
            else
            {
                context.VF = 0;
            }

            context.GPR[x] -= context.GPR[y];
            return(true);
        }
Esempio n. 27
0
        /// <summary>
        /// 8xy7 - SUBN Vx, Vy
        ///Set Vx = Vy - Vx, set VF = NOT borrow.
        ///
        ///If Vy &gt; Vx, then VF is set to 1, otherwise 0. Then Vx is subtracted from Vy, and the results stored in Vx.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="instruction"></param>
        /// <returns></returns>
        private static bool SUBN(CpuCore context, Instruction instruction)
        {
            var x = instruction.X;
            var y = instruction.Y;

            if (context.GPR[y] > context.GPR[x])
            {
                context.VF = 1;
            }
            else
            {
                context.VF = 0;
            }

            context.GPR[x] = ( byte )(context.GPR[y] - context.GPR[x]);
            return(true);
        }
Esempio n. 28
0
        /// <summary>
        /// Dxyn - DRW Vx, Vy, nibble
        /// Display n-byte sprite starting at memory location I at (Vx, Vy), set VF = collision.
        ///
        /// The interpreter reads n bytes from memory, starting at the address stored in I.
        /// These bytes are then displayed as sprites on screen at coordinates (Vx, Vy). Sprites are XORed onto the existing screen.
        /// If this causes any pixels to be erased, VF is set to 1, otherwise it is set to 0.
        /// If the sprite is positioned so part of it is outside the coordinates of the display, it wraps around to the opposite side of the screen.
        /// See instruction 8xy3 for more information on XOR, and section 2.4, Display, for more information on the Chip-8 screen and sprites.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="instruction"></param>
        /// <returns></returns>
        private static bool DRW(CpuCore context, Instruction instruction)
        {
            var x     = context.GPR[instruction.X];
            var y     = context.GPR[instruction.Y];
            var bytes = context.Memory.ReadBytes(context.I, instruction.N);

            if (context.Display.DrawSprite(x, y, bytes))
            {
                context.VF = 1;
            }
            else
            {
                context.VF = 0;
            }

            return(true);
        }
Esempio n. 29
0
        private static List <CpuCore> GetCpuCoreList()
        {
            List <CpuCore> cpuCoreList = new List <CpuCore>();

            using ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win32_PerfFormattedData_PerfOS_Processor WHERE Name != '_Total'");

            foreach (ManagementObject mo in mos.Get())
            {
                CpuCore core = new CpuCore
                {
                    Name = GetPropertyString(mo["Name"]),
                    PercentProcessorTime = GetPropertyValue <ulong>(mo["PercentProcessorTime"])
                };

                cpuCoreList.Add(core);
            }

            return(cpuCoreList);
        }
Esempio n. 30
0
        protected CpuTestBase()
        {
            mbbsEmuMemoryCore   = mbbsEmuProtectedModeMemoryCore = new ProtectedModeMemoryCore(logger: null);
            mbbsEmuCpuCore      = new CpuCore(logger: null);
            mbbsEmuCpuRegisters = mbbsEmuCpuCore;

            pit = new ProgrammableIntervalTimer(logger: null, fakeClock, mbbsEmuCpuCore);

            mbbsEmuCpuCore.Reset(
                mbbsEmuMemoryCore,
                null,
                null,
                new Dictionary <int, IIOPort>
            {
                { 0x40, pit },
                { 0x41, pit },
                { 0x42, pit },
                { 0x43, pit },
            });
        }