2017-07-23 21:45:16 +00:00
|
|
|
|
using System;
|
|
|
|
|
|
|
|
|
|
namespace Emux.GameBoy.Cpu
|
|
|
|
|
{
|
2017-07-26 23:56:17 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Represents an instruction in the Z80 instruction set.
|
|
|
|
|
/// </summary>
|
2017-07-23 21:45:16 +00:00
|
|
|
|
public class Z80Instruction
|
|
|
|
|
{
|
|
|
|
|
public Z80Instruction(ushort offset, Z80OpCode opCode, byte[] operand)
|
2020-04-18 19:21:49 +00:00
|
|
|
|
{
|
|
|
|
|
Set(offset, opCode, operand);
|
|
|
|
|
}
|
|
|
|
|
public void Set(ushort offset, Z80OpCode opCode, byte[] operand)
|
2017-07-23 21:45:16 +00:00
|
|
|
|
{
|
|
|
|
|
Offset = offset;
|
|
|
|
|
OpCode = opCode;
|
|
|
|
|
RawOperand = operand;
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-26 23:56:17 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// The memory address the instruction is located at.
|
|
|
|
|
/// </summary>
|
2017-07-23 21:45:16 +00:00
|
|
|
|
public ushort Offset
|
|
|
|
|
{
|
|
|
|
|
get;
|
2020-04-18 19:21:49 +00:00
|
|
|
|
private set;
|
2017-07-23 21:45:16 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-07-26 23:56:17 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// The operation code of the instructon.
|
|
|
|
|
/// </summary>
|
2017-07-23 21:45:16 +00:00
|
|
|
|
public Z80OpCode OpCode
|
|
|
|
|
{
|
|
|
|
|
get;
|
2020-04-18 19:21:49 +00:00
|
|
|
|
private set;
|
2017-07-23 21:45:16 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-07-26 23:56:17 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// The bytes that form the operand of the instruction.
|
|
|
|
|
/// </summary>
|
2017-07-23 21:45:16 +00:00
|
|
|
|
public byte[] RawOperand
|
|
|
|
|
{
|
|
|
|
|
get;
|
2020-04-18 19:21:49 +00:00
|
|
|
|
private set;
|
2017-07-23 21:45:16 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-07-26 23:56:17 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// The operand interpreted as a single unsigned 8 bit integer.
|
|
|
|
|
/// </summary>
|
2020-04-18 19:21:49 +00:00
|
|
|
|
public byte Operand8 => RawOperand[0];
|
2017-07-23 21:45:16 +00:00
|
|
|
|
|
2017-07-26 23:56:17 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// The operand interpreted as an unsigned 16 bit integer.
|
|
|
|
|
/// </summary>
|
2020-04-18 19:21:49 +00:00
|
|
|
|
public ushort Operand16 => BitConverter.ToUInt16(RawOperand, 0);
|
2017-07-23 21:45:16 +00:00
|
|
|
|
|
2017-08-08 22:39:17 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets the assembler code representing the instruction.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string Disassembly
|
2017-07-23 21:45:16 +00:00
|
|
|
|
{
|
2017-08-08 22:39:17 +00:00
|
|
|
|
get
|
2017-07-23 21:45:16 +00:00
|
|
|
|
{
|
2017-08-08 22:39:17 +00:00
|
|
|
|
switch (RawOperand.Length)
|
|
|
|
|
{
|
|
|
|
|
default:
|
|
|
|
|
return OpCode.Disassembly;
|
|
|
|
|
case 1:
|
|
|
|
|
return string.Format(OpCode.Disassembly, Operand8);
|
|
|
|
|
case 2:
|
|
|
|
|
return string.Format(OpCode.Disassembly, Operand16);
|
|
|
|
|
}
|
2017-07-23 21:45:16 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-18 19:21:49 +00:00
|
|
|
|
public override string ToString() => Offset.ToString("X4") + ": " + Disassembly;
|
2017-08-08 22:39:17 +00:00
|
|
|
|
|
2017-07-26 23:56:17 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Executes the instruction on the given device.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="device">The device to execute the instruction on.</param>
|
|
|
|
|
/// <returns>The clock cycles it took to evaluate the instruction.</returns>
|
2020-04-18 19:21:49 +00:00
|
|
|
|
public int Execute(GameBoy device) => OpCode.Operation(device, this);
|
2017-07-23 21:45:16 +00:00
|
|
|
|
}
|
|
|
|
|
}
|