コード例 #1
0
        private void StartInstruction(Instruction instruction)
        {
            if (instruction == Instruction.RESET)
            {
                // Instruction count should be zero after a RESET
                instructionCounter = 0;
            }
            else
            {
                // Any other internal instruction increments the instruction counter
                instructionCounter++;
            }

            if (instruction == Instruction.FetchNewInstruction)
            {
                instructionOrigin = new InstructionOrigin(InstructionSource.Memory, null, PC);
            }
            else
            {
                instructionOrigin = InstructionOrigin.Internal;
            }
            currentInstruction = instruction;
            DecodeInstructionExecutionMethod();
        }
コード例 #2
0
        // Reset CPU control section and instruction decoder internal state
        private void ResetCPUControlState()
        {
            // Z80CPU.cs internal state
            tStateCounter = 0;
            machineCycleCounter = 0;
            instructionCounter = 0;
            instructionOrigin = null;
            currentInstruction = null;
            executeInstruction = null;
            halfTStateIndex = 0;
            machineCycleIndex = 0;
            machineCycleCountAfterInstruction = 0;
            currentMachineCycle = null;
            executeMachineCycle = null;

            // Z80CPU_Instruction_Decoder.cs internal state
            opcodeTableIndex = 0;

            // Z80CPU_ExternalControl.cs internal state
            busRequestPending = false;
            maskableInterruptPending = false;
            nonMaskableInterruptPending = false;
        }
コード例 #3
0
        // Read instruction register and decode instruction
        private void DecodeInstruction()
        {
            if (instructionOrigin.Source != InstructionSource.Internal) // internal instruction already decoded, nothing to do
            {
                InstructionCode candidateInstructionCode = Z80OpCodes.Tables[opcodeTableIndex, IR];

                // Ignore DD and FD prefixes if the second byte of the opcode does not lead to a valid instruction
                if (candidateInstructionCode.FetchMoreBytes == 0 && candidateInstructionCode.SwitchToTableNumber == 0)
                {
                    // Ignore the prefix and try to find the candidate instruction in the first opcode table
                    candidateInstructionCode = Z80OpCodes.Tables[0, IR];

                    // The previous machine cycle did not contribute to the new instruction
                    machineCycleIndex--;
                    instructionOrigin.Address++;
                }

                // An opcode was recognized, decode it and prepare its execution
                if (candidateInstructionCode.FetchMoreBytes == 0 && candidateInstructionCode.SwitchToTableNumber == null)
                {
                    opcodeTableIndex = 0;
                    InstructionCode instructionCode = candidateInstructionCode;

                    // Register decoded instruction
                    instructionOrigin.OpCode = instructionCode;
                    currentInstruction = new Instruction(instructionCode.InstructionTypeIndex, instructionCode.InstructionTypeParamVariant);
                    DecodeInstructionExecutionMethod();

                    // Correct the actual duration of the current opcode fetch cycle (depends on the instruction)
                    currentMachineCycle = currentInstruction.ExecutionTimings.MachineCycles[machineCycleIndex];
                }
                // We need to read more bytes to recognize a multi-byte opcode
                else if (candidateInstructionCode.FetchMoreBytes > 0)
                {
                    opcodeTableIndex = candidateInstructionCode.SwitchToTableNumber.Value;
                }
            }

            if (TraceMicroInstructions)
            {
                TraceMicroInstruction(new MicroInstruction(Z80MicroInstructionTypes.CPUControlDecodeInstruction));
            }
        }
コード例 #4
0
 private void EndInstruction()
 {
     instructionOrigin = null;
     currentInstruction = null;
     executeInstruction = null;
 }
コード例 #5
0
        private void DecodeInterruptingDeviceInstruction()
        {
            // The interrupting device inserts an instruction code on the data bus
            InstructionCode candidateInstructionCode = Z80OpCodes.Tables[0, InternalDataBus];

            // An opcode was recognized, decode it and prepare its execution
            if (candidateInstructionCode.FetchMoreBytes == 0 && candidateInstructionCode.SwitchToTableNumber == null)
            {
                InstructionCode instructionCode = candidateInstructionCode;

                // Register decoded instruction
                instructionOrigin = new InstructionOrigin(InstructionSource.InterruptingDevice, instructionCode, 0);
                currentInstruction = new Instruction(instructionCode.InstructionTypeIndex, instructionCode.InstructionTypeParamVariant);
                DecodeInstructionExecutionMethod();

                // Correct the actual duration of the current opcode fetch cycle (depends on the instruction)
                currentMachineCycle = currentInstruction.ExecutionTimings.MachineCycles[machineCycleIndex];

                // Decrease the half T state index to execute the decoded instruction as if it was fetched from memory
                halfTStateIndex = 4;
            }
            // We need to read more bytes to recognize a multi-byte opcode
            else
            {
                throw new NotSupportedException("Multi bytes opcodes are not supported in interrupt mode 0 by this simulator");
            }

            if (TraceMicroInstructions)
            {
                TraceMicroInstruction(new MicroInstruction(Z80MicroInstructionTypes.CPUControlDecodeInterruptingDeviceInstruction));
            }
        }