BizHawk/BizHawk.Emulation.Cores/CPUs/Intel8048/OP_Tables.cs

491 lines
7.3 KiB
C#
Raw Normal View History

2019-10-31 13:43:25 +00:00
using System;
using BizHawk.Common.NumberExtensions;
2020-01-12 21:18:22 +00:00
namespace BizHawk.Emulation.Cores.Components.I8048
2019-10-31 13:43:25 +00:00
{
public partial class I8048
{
// this contains the vectors of instrcution operations
// NOTE: This list is NOT confirmed accurate for each individual cycle
public void ILLEGAL()
{
PopulateCURINSTR(IDLE,
IDLE,
IDLE,
IDLE);
IRQS = 4;
Console.WriteLine("EXCEPTION");
2019-10-31 13:43:25 +00:00
}
public void OP_IMP(ushort oper)
{
PopulateCURINSTR(IDLE,
IDLE,
IDLE,
oper);
IRQS = 4;
}
2019-12-27 21:18:26 +00:00
// Slightly different timing for these instructions
public void OP_IMP2(ushort oper)
{
PopulateCURINSTR(IDLE,
IDLE,
oper,
IDLE);
IRQS = 4;
}
2019-10-31 13:43:25 +00:00
public void OP_R_IMP(ushort oper, ushort reg)
{
PopulateCURINSTR(IDLE,
IDLE,
IDLE,
2019-11-12 03:19:41 +00:00
oper, (ushort)(reg + RB));
2019-10-31 13:43:25 +00:00
IRQS = 4;
}
public void OP_A_R(ushort oper, ushort reg)
{
PopulateCURINSTR(IDLE,
IDLE,
IDLE,
2019-11-12 03:19:41 +00:00
oper, A, (ushort)(reg + RB));
2019-10-31 13:43:25 +00:00
IRQS = 4;
}
2019-11-18 03:29:17 +00:00
public void OP_IR(ushort oper, ushort reg)
2019-11-09 15:10:35 +00:00
{
PopulateCURINSTR(IDLE,
IDLE,
IDLE,
oper, (ushort)(reg + RB));
2019-11-09 15:10:35 +00:00
IRQS = 4;
}
2019-11-18 03:29:17 +00:00
public void OP_A_IR(ushort oper, ushort reg)
2019-11-09 15:10:35 +00:00
{
PopulateCURINSTR(IDLE,
IDLE,
2019-11-18 03:29:17 +00:00
MEM_ALU, (ushort)(reg + RB),
oper, A, ALU);
2019-11-09 15:10:35 +00:00
IRQS = 4;
}
public void OP_DIR_IR(ushort oper, ushort reg)
{
PopulateCURINSTR(IDLE,
IDLE,
IDLE,
RD, ALU, PC,
INC11, PC,
IDLE,
IDLE,
IDLE,
oper, (ushort)(reg + RB), ALU);
IRQS = 9;
}
2019-12-27 21:18:26 +00:00
public void IN_P_A(ushort oper, ushort port)
2019-11-09 15:10:35 +00:00
{
PopulateCURINSTR(IDLE,
IDLE,
IDLE,
IDLE,
IDLE,
2019-12-27 21:18:26 +00:00
oper, A, port,
2019-11-09 15:10:35 +00:00
IDLE,
IDLE,
2019-12-27 21:18:26 +00:00
IDLE);
2019-11-18 03:29:17 +00:00
2019-12-14 16:46:45 +00:00
IRQS = 9;
2019-11-18 03:29:17 +00:00
}
public void MOV_R(ushort dest, ushort src)
{
PopulateCURINSTR(IDLE,
2019-11-09 15:10:35 +00:00
IDLE,
IDLE,
2019-11-18 03:29:17 +00:00
MOV, dest, src);
2019-11-09 15:10:35 +00:00
2019-11-18 03:29:17 +00:00
IRQS = 4;
2019-11-09 15:10:35 +00:00
}
public void BUS_PORT_IN()
2019-11-09 15:10:35 +00:00
{
PopulateCURINSTR(IDLE,
IDLE,
IDLE,
IDLE,
IDLE,
2019-12-27 21:18:26 +00:00
RD_P, A, 0,
2019-11-09 15:10:35 +00:00
IDLE,
IDLE,
2019-12-27 21:18:26 +00:00
IDLE);
IRQS = 9;
// Console.WriteLine("IN "+ TotalExecutedCycles);
}
public void BUS_PORT_OUT()
{
PopulateCURINSTR(IDLE,
IDLE,
IDLE,
2019-12-27 21:18:26 +00:00
WR_P, 0, A,
IDLE,
IDLE,
IDLE,
IDLE,
2019-12-27 21:18:26 +00:00
IDLE);
2019-11-09 15:10:35 +00:00
IRQS = 9;
Console.WriteLine("OUT");
2019-11-09 15:10:35 +00:00
}
2019-11-11 01:22:38 +00:00
public void OUT_P(ushort port)
{
PopulateCURINSTR(IDLE,
IDLE,
IDLE,
2019-12-27 21:18:26 +00:00
WR_P, port, A,
2019-11-11 01:22:38 +00:00
IDLE,
IDLE,
IDLE,
IDLE,
2019-12-27 21:18:26 +00:00
IDLE);
2019-11-11 01:22:38 +00:00
IRQS = 9;
2019-11-11 01:22:38 +00:00
}
public void RET()
{
PopulateCURINSTR(IDLE,
IDLE,
IDLE,
IDLE,
PULL_PC,
2019-11-11 01:22:38 +00:00
IDLE,
IDLE,
IDLE,
IDLE);
IRQS = 9;
}
public void RETR()
{
PopulateCURINSTR(IDLE,
IDLE,
IDLE,
IDLE,
PULL,
2019-12-09 21:45:36 +00:00
EM,
2019-11-11 01:22:38 +00:00
IDLE,
IDLE,
IDLE);
IRQS = 9;
}
public void MOV_A_P4(ushort port)
{
PopulateCURINSTR(IDLE,
IDLE,
IDLE,
IDLE,
IDLE,
IDLE,
IDLE,
IDLE,
IDLE);
IRQS = 9;
}
public void MOV_P4_A(ushort port)
{
PopulateCURINSTR(IDLE,
IDLE,
IDLE,
IDLE,
IDLE,
IDLE,
IDLE,
IDLE,
IDLE);
IRQS = 9;
}
public void MOV_A_A()
{
PopulateCURINSTR(IDLE,
TR, ALU, PC,
2019-11-11 01:22:38 +00:00
IDLE,
SET_ADDR_8, ALU, A,
2019-11-11 01:22:38 +00:00
IDLE,
IDLE,
IDLE,
IDLE,
RD, A, ALU);
2019-11-11 01:22:38 +00:00
IRQS = 9;
}
public void MOV3_A_A()
{
PopulateCURINSTR(IDLE,
TR, ALU, PC,
2019-11-11 01:22:38 +00:00
IDLE,
SET_ADDR_8, ALU, A,
2019-11-11 01:22:38 +00:00
IDLE,
SET_ADDR_M3,
2019-11-11 01:22:38 +00:00
IDLE,
IDLE,
RD, A, ALU);
2019-11-11 01:22:38 +00:00
IRQS = 9;
}
public void MOVX_A_R(ushort reg)
{
2019-12-27 21:18:26 +00:00
PopulateCURINSTR(EEA,
2019-11-30 14:28:53 +00:00
WR_P, 0, (ushort)(reg + RB),
DEA,
2019-11-11 01:22:38 +00:00
IDLE,
IDLE,
2019-12-27 21:18:26 +00:00
RD_P, A, 0,
2019-11-11 01:22:38 +00:00
IDLE,
2019-12-27 21:18:26 +00:00
IDLE,
IDLE);
2019-11-11 01:22:38 +00:00
IRQS = 9;
}
public void MOVX_R_A(ushort reg)
{
2019-12-27 21:18:26 +00:00
PopulateCURINSTR(EEA,
2019-11-19 03:17:29 +00:00
WR_P, 0, (ushort)(reg + RB),
DEA,
2019-12-27 21:18:26 +00:00
WR_P, 0, A,
2019-11-11 01:22:38 +00:00
IDLE,
IDLE,
IDLE,
2019-12-27 21:18:26 +00:00
IDLE,
IDLE);
2019-11-11 01:22:38 +00:00
IRQS = 9;
}
2019-10-31 13:43:25 +00:00
public void OP_A_DIR(ushort oper)
{
PopulateCURINSTR(IDLE,
IDLE,
IDLE,
RD, ALU, PC,
2019-11-18 03:29:17 +00:00
INC11, PC,
2019-10-31 13:43:25 +00:00
IDLE,
IDLE,
IDLE,
oper, A, ALU);
IRQS = 9;
}
2019-11-09 15:10:35 +00:00
public void OP_R_DIR(ushort oper, ushort reg)
{
PopulateCURINSTR(IDLE,
IDLE,
IDLE,
RD, ALU, PC,
2019-11-18 03:29:17 +00:00
INC11, PC,
2019-11-09 15:10:35 +00:00
IDLE,
IDLE,
IDLE,
2019-11-18 23:36:51 +00:00
oper, (ushort)(reg + RB), ALU);
2019-11-09 15:10:35 +00:00
IRQS = 9;
}
2019-11-30 14:28:53 +00:00
// TODO: This should only write back to the port destination if directly wired, otherwise we should wait for a write pulse
// TODO: for O2, P1 is tied direct to CTRL outputs so this is ok, BUS and P2 should do something else though
2019-10-31 13:43:25 +00:00
public void OP_PB_DIR(ushort oper, ushort reg)
{
2019-11-30 14:28:53 +00:00
if (reg == 1)
{
PopulateCURINSTR(IDLE,
2019-12-27 21:18:26 +00:00
IDLE,
2019-11-30 14:28:53 +00:00
IDLE,
IDLE,
RD, ALU, PC,
INC11, PC,
oper, (ushort)(reg + PX), ALU,
2019-12-27 21:18:26 +00:00
WR_P, reg, (ushort)(reg + PX),
IDLE);
2019-11-30 14:28:53 +00:00
}
else
{
PopulateCURINSTR(IDLE,
2019-12-27 21:18:26 +00:00
IDLE,
2019-11-30 14:28:53 +00:00
IDLE,
IDLE,
RD, ALU, PC,
INC11, PC,
oper, (ushort)(reg + PX), ALU,
IDLE,
IDLE);
}
2019-10-31 13:43:25 +00:00
IRQS = 9;
}
public void OP_EXP_A(ushort oper, ushort reg)
{
// Lower 4 bits only
PopulateCURINSTR(IDLE,
IDLE,
IDLE,
TR, ALU, A,
IDLE,
IDLE,
MSK, ALU,
IDLE,
oper, reg, ALU);
IRQS = 9;
}
public void CALL(ushort dest_h)
{
// Lower 4 bits only
PopulateCURINSTR(IDLE,
2019-12-27 21:18:26 +00:00
IDLE,
2019-10-31 13:43:25 +00:00
IDLE,
IDLE,
RD, ALU, PC,
INC11, PC,
PUSH,
2019-10-31 13:43:25 +00:00
IDLE,
SET_ADDR, PC, ALU, dest_h);
2019-10-31 13:43:25 +00:00
IRQS = 9;
}
2019-11-08 15:44:00 +00:00
public void DJNZ(ushort reg)
{
2019-11-18 23:36:51 +00:00
if ((Regs[reg + RB] - 1) == 0)
2019-11-08 15:44:00 +00:00
{
PopulateCURINSTR(IDLE,
IDLE,
2019-11-18 23:36:51 +00:00
DEC8, (ushort)(reg + RB),
RD, ALU, PC,
INC11, PC,
2019-11-08 15:44:00 +00:00
IDLE,
IDLE,
IDLE,
IDLE);
}
else
{
PopulateCURINSTR(IDLE,
IDLE,
2019-11-18 23:36:51 +00:00
DEC8, (ushort)(reg + RB),
RD, ALU, PC,
INC11, PC,
2019-11-08 15:44:00 +00:00
IDLE,
IDLE,
IDLE,
2019-11-18 23:36:51 +00:00
SET_ADDR_8, PC, ALU);
2019-11-08 15:44:00 +00:00
}
IRQS = 9;
}
2019-11-18 03:29:17 +00:00
public void JP_A()
{
PopulateCURINSTR(IDLE,
IDLE,
2019-12-17 22:40:57 +00:00
SET_ADDR_8, PC, A,
RD, ALU, PC,
2019-11-18 03:29:17 +00:00
IDLE,
IDLE,
IDLE,
IDLE,
SET_ADDR_8, PC, ALU);
IRQS = 9;
}
2019-11-08 15:44:00 +00:00
public void JPB(ushort Tebit)
{
if (Regs[A].Bit(Tebit))
{
PopulateCURINSTR(IDLE,
IDLE,
IDLE,
2019-11-18 03:29:17 +00:00
RD, ALU, PC,
INC11, PC,
2019-11-08 15:44:00 +00:00
IDLE,
IDLE,
IDLE,
2019-11-18 03:29:17 +00:00
SET_ADDR_8, PC, ALU);
2019-11-08 15:44:00 +00:00
}
else
{
PopulateCURINSTR(IDLE,
IDLE,
IDLE,
2019-11-18 03:29:17 +00:00
RD, ALU, PC,
INC11, PC,
2019-11-08 15:44:00 +00:00
IDLE,
IDLE,
IDLE,
IDLE);
}
IRQS = 9;
}
2019-12-27 21:18:26 +00:00
public void JP_COND(ushort COND, ushort SPEC)
2019-11-08 15:44:00 +00:00
{
2019-12-27 21:18:26 +00:00
PopulateCURINSTR(IDLE,
TEST_COND, COND,
IDLE,
IDLE,
RD, ALU, PC,
INC11, PC,
SPEC,
IDLE,
SET_ADDR_8, PC, ALU);
2019-11-08 15:44:00 +00:00
2019-12-27 21:18:26 +00:00
IRQS = 9;
2019-11-08 15:44:00 +00:00
}
public void JP_2k(ushort high_addr)
{
PopulateCURINSTR(IDLE,
IDLE,
IDLE,
2019-11-18 03:29:17 +00:00
RD, ALU, PC,
INC11, PC,
2019-11-08 15:44:00 +00:00
IDLE,
IDLE,
IDLE,
2019-11-18 03:29:17 +00:00
SET_ADDR, PC, ALU, high_addr);
2019-11-08 15:44:00 +00:00
IRQS = 9;
}
2019-10-31 13:43:25 +00:00
}
}