示例#1
0
文件: Z80CPU.cs 项目: wchill/Z80Sharp
        private void HandleINT()
        {
            // TODO: Check if INT is supposed to be able to fire during this push and other memory operations
            var opcode = AcknowledgeInterrupt();

            if (Registers.InterruptMode == Z80InterruptMode.External)
            {
                var instr = InstructionDecoder.DecodeNextInstruction(this, opcode);
                instr.Execute(this, instr.InstructionBytes);
            }
            else if (Registers.InterruptMode == Z80InterruptMode.FixedAddress)
            {
                PushWord(Registers.PC);
                Registers.PC = 0x38;
            }
            else if (Registers.InterruptMode == Z80InterruptMode.Vectorized)
            {
                var upper = Registers.I;
                var lower = opcode;
                var addr  = Utilities.LETo16Bit(lower, upper);
                PushWord(Registers.PC);
                var jumpAddr = ReadWord(addr);
                Registers.PC = jumpAddr;
            }
        }
示例#2
0
        public List <DisassembledInstruction> Disassemble(ushort address)
        {
            Registers.PC = address;
            var instructions = new List <DisassembledInstruction>();
            DisassembledInstruction instruction;

            do
            {
                instruction = InstructionDecoder.DecodeNextInstruction(this);
                instructions.Add(instruction);
            } while (!instruction.ControlInstruction);

            return(instructions);
        }
示例#3
0
文件: Z80CPU.cs 项目: wchill/Z80Sharp
        public void ExecuteNextInstruction()
        {
            if (Registers.PC == 0)
            {
                throw new InvalidOperationException("Hit address 0");
            }
            if (Registers.PC == 5)
            {
                // Handle CP/M syscalls
                switch (Registers.C)
                {
                case 2:
                {
                    var inputByte  = Registers.E;
                    var outputChar = Encoding.ASCII.GetString(new[] { inputByte })[0];
                    Console.Write(outputChar);
                    break;
                }

                case 9:
                {
                    var  strAddress = Registers.DE;
                    var  inputBytes = new List <byte>();
                    byte inputByte;
                    _cycleCount += 3;
                    while ((inputByte = ReadMemory(strAddress)) != '$')
                    {
                        _cycleCount += 3;
                        inputBytes.Add(inputByte);
                        strAddress++;
                    }
                    var outputChar = Encoding.ASCII.GetString(inputBytes.ToArray());
                    Console.Write(outputChar);
                    break;
                }

                default:
                    // throw new NotImplementedException($"Unimplemented syscall {Registers.C}");
                    break;
                }

                FetchOpcode();
                _cycleCount += Z80Instructions.RET(this, null);
            }

            var instruction = InstructionDecoder.DecodeNextInstruction(this);

            var beforeCount = _cycleCount;

            _cycleCount += instruction.Execute(this, instruction.InstructionBytes);

            if (_cycleCount != ControlLines.SystemClock.Ticks)
            {
                throw new InvalidOperationException($"Cycle mismatch when executing instruction {instruction.Mnemonic} - expected {_cycleCount - beforeCount} but got {ControlLines.SystemClock.Ticks - beforeCount} cycles");
            }

            if (Registers.IFF1 && ControlLines.INT.Value == TristateWireState.LogicLow)
            {
                HandleINT();
            }
        }