2019-10-31 13:43:25 +00:00
|
|
|
using System;
|
|
|
|
using BizHawk.Common.NumberExtensions;
|
|
|
|
|
|
|
|
namespace BizHawk.Emulation.Common.Components.I8048
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void OP_IMP(ushort oper)
|
|
|
|
{
|
|
|
|
PopulateCURINSTR(IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
|
|
|
oper);
|
|
|
|
|
|
|
|
IRQS = 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
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,
|
2019-12-10 18:52:33 +00:00
|
|
|
oper, (ushort)(reg + RB), A);
|
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;
|
|
|
|
}
|
|
|
|
|
2019-12-10 18:52:33 +00:00
|
|
|
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-11-18 03:29:17 +00:00
|
|
|
public void IN_OUT_A(ushort oper, ushort port)
|
2019-11-09 15:10:35 +00:00
|
|
|
{
|
|
|
|
PopulateCURINSTR(IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
2019-11-18 03:29:17 +00:00
|
|
|
oper, A, port);
|
|
|
|
|
|
|
|
IRQS = 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2019-11-11 01:22:38 +00:00
|
|
|
public void IN_OUT_BUS(ushort oper)
|
2019-11-09 15:10:35 +00:00
|
|
|
{
|
|
|
|
PopulateCURINSTR(IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
|
|
|
oper, A);
|
|
|
|
|
|
|
|
IRQS = 9;
|
|
|
|
}
|
|
|
|
|
2019-11-11 01:22:38 +00:00
|
|
|
public void OUT_P(ushort port)
|
|
|
|
{
|
|
|
|
PopulateCURINSTR(IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
|
|
|
port, A);
|
|
|
|
|
|
|
|
IRQS = 9;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void RET()
|
|
|
|
{
|
|
|
|
PopulateCURINSTR(IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
2019-11-18 22:33:55 +00:00
|
|
|
PULL_PC,
|
2019-11-11 01:22:38 +00:00
|
|
|
IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE);
|
|
|
|
|
|
|
|
IRQS = 9;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void RETR()
|
|
|
|
{
|
|
|
|
PopulateCURINSTR(IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
2019-11-18 22:33:55 +00:00
|
|
|
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,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE);
|
|
|
|
|
|
|
|
IRQS = 9;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void MOV3_A_A()
|
|
|
|
{
|
|
|
|
PopulateCURINSTR(IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE);
|
|
|
|
|
|
|
|
IRQS = 9;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void MOVX_A_R(ushort reg)
|
|
|
|
{
|
|
|
|
PopulateCURINSTR(IDLE,
|
|
|
|
IDLE,
|
2019-11-30 14:28:53 +00:00
|
|
|
EEA,
|
|
|
|
WR_P, 0, (ushort)(reg + RB),
|
|
|
|
DEA,
|
2019-11-11 01:22:38 +00:00
|
|
|
IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
2019-11-30 14:28:53 +00:00
|
|
|
RD_P, A, 0);
|
2019-11-11 01:22:38 +00:00
|
|
|
|
|
|
|
IRQS = 9;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void MOVX_R_A(ushort reg)
|
|
|
|
{
|
|
|
|
PopulateCURINSTR(IDLE,
|
|
|
|
IDLE,
|
2019-11-19 03:17:29 +00:00
|
|
|
EEA,
|
|
|
|
WR_P, 0, (ushort)(reg + RB),
|
|
|
|
DEA,
|
2019-11-11 01:22:38 +00:00
|
|
|
IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
2019-11-19 03:17:29 +00:00
|
|
|
WR_P, 0, A);
|
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,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
|
|
|
RD, ALU, PC,
|
|
|
|
INC11, PC,
|
|
|
|
oper, (ushort)(reg + PX), ALU,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
|
|
|
WR_P, reg, (ushort)(reg + PX));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PopulateCURINSTR(IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
|
|
|
RD, ALU, PC,
|
|
|
|
INC11, PC,
|
|
|
|
oper, (ushort)(reg + PX), ALU,
|
|
|
|
IDLE,
|
|
|
|
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,
|
|
|
|
IDLE,
|
|
|
|
IDLE,
|
2019-11-18 22:33:55 +00:00
|
|
|
RD, ALU, PC,
|
|
|
|
INC11, PC,
|
2019-10-31 13:43:25 +00:00
|
|
|
IDLE,
|
2019-11-18 22:33:55 +00:00
|
|
|
PUSH,
|
2019-10-31 13:43:25 +00:00
|
|
|
IDLE,
|
2019-11-18 22:33:55 +00:00
|
|
|
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,
|
|
|
|
IDLE,
|
|
|
|
MEM_ALU, A,
|
|
|
|
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-11-09 15:10:35 +00:00
|
|
|
public void JP_COND(bool cond, ushort SPEC)
|
2019-11-08 15:44:00 +00:00
|
|
|
{
|
|
|
|
if (cond)
|
|
|
|
{
|
|
|
|
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-09 15:10:35 +00:00
|
|
|
SPEC,
|
2019-11-08 15:44:00 +00:00
|
|
|
IDLE,
|
|
|
|
IDLE,
|
|
|
|
IDLE);
|
|
|
|
}
|
|
|
|
|
|
|
|
IRQS = 9;
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
}
|