Vectrex: Indexed Addressing

This commit is contained in:
alyosha-tas 2019-03-31 16:33:02 -05:00
parent 33af0b7fee
commit ab1d47d756
6 changed files with 335 additions and 11 deletions

View File

@ -1532,6 +1532,7 @@
<Compile Include="CPUs\MC6809\NewDisassembler.cs" />
<Compile Include="CPUs\MC6809\Operations.cs" />
<Compile Include="CPUs\MC6809\Registers.cs" />
<Compile Include="CPUs\MC6809\Indexed_Modes.cs" />
<Compile Include="CPUs\MC6809\Tables_Direct.cs" />
<Compile Include="CPUs\LR35902\Execute.cs" />
<Compile Include="CPUs\LR35902\Interrupts.cs" />

View File

@ -71,10 +71,10 @@ namespace BizHawk.Emulation.Common.Components.MC6809
case 0x2D: BR_(FlagN ^ FlagV); break; // BLT (Relative)
case 0x2E: BR_((!FlagZ) & (FlagN == FlagV)); break; // BGT (Relative)
case 0x2F: BR_(FlagZ | (FlagN ^ FlagV)); break; // BLE (Relative)
case 0x30: JR_COND(!FlagC); break; // LEAX (Indexed)
case 0x31: ; break; // LEAY (Indexed)
case 0x32: ; break; // LEAS (Indexed)
case 0x33: ; break; // LEAU (Indexed)
case 0x30: INDEX_OP(LEAX); break; // LEAX (Indexed)
case 0x31: INDEX_OP(LEAY); break; // LEAY (Indexed)
case 0x32: INDEX_OP(LEAS); break; // LEAS (Indexed)
case 0x33: INDEX_OP(LEAU); break; // LEAU (Indexed)
case 0x34: ; break; // PSHS (Immediate)
case 0x35: ; break; // PULS (Immediate)
case 0x36: ; break; // PSHU (Immediate)

View File

@ -0,0 +1,290 @@
using System;
namespace BizHawk.Emulation.Common.Components.MC6809
{
public partial class MC6809
{
public const ushort LEAX = 0;
public const ushort LEAY = 1;
public const ushort LEAS = 2;
public const ushort LEAU = 3;
public const ushort JMP = 4;
public ushort indexed_op;
public ushort indexed_reg;
public ushort temp;
private void INDEX_OP(ushort oper)
{
indexed_op = oper;
PopulateCURINSTR(RD_INC_OP, ALU, PC, IDX_DCDE);
}
private void INDEX_OP_JMP()
{
PopulateCURINSTR(TR, PC, IDX_EA);
}
private void INDEX_OP_LEA(ushort dest)
{
PopulateCURINSTR(TR, dest, IDX_EA,
IDLE);
}
private void INDEX_OP_EX5()
{
PopulateCURINSTR(RD_INC_OP, ALU, PC, IDX_DCDE);
}
private void INDEX_OP_EX6()
{
PopulateCURINSTR(RD_INC_OP, ALU, PC, IDX_DCDE);
}
private void INDEX_OP_EX7()
{
PopulateCURINSTR(RD_INC_OP, ALU, PC, IDX_DCDE);
}
// ALU holds the post byte
public void Index_decode()
{
switch ((Regs[ALU] >> 5) & 3)
{
case 0: indexed_reg = X; break;
case 1: indexed_reg = Y; break;
case 2: indexed_reg = US; break;
case 3: indexed_reg = SP; break;
}
if ((Regs[ALU] & 0x80) == 0)
{
temp = (ushort)(Regs[ALU] & 0x1F);
if ((Regs[ALU] & 0x10) == 0x10)
{
temp |= 0xFFE0;
}
Regs[IDX_EA] = (ushort)(Regs[indexed_reg] + temp);
PopulateCURINSTR(IDX_OP_BLD);
}
else
{
if ((Regs[ALU] & 0x10) == 0x10)
{
switch (Regs[ALU] & 0xF)
{
case 0x0:
// Illegal
break;
case 0x1:
Regs[ADDR] = Regs[indexed_reg];
PopulateCURINSTR(INC16, indexed_reg,
INC16, indexed_reg,
RD_INC, ALU, ADDR,
RD_INC, ALU2, ADDR,
SET_ADDR, IDX_EA, ALU, ALU2,
IDX_OP_BLD);
break;
case 0x2:
// Illegal
break;
case 0x3:
Regs[ADDR] = (ushort)(Regs[indexed_reg] - 2);
PopulateCURINSTR(DEC16, indexed_reg,
DEC16, indexed_reg,
RD_INC, ALU, ADDR,
RD_INC, ALU2, ADDR,
SET_ADDR, IDX_EA, ALU, ALU2,
IDX_OP_BLD);
break;
case 0x4:
Regs[ADDR] = Regs[indexed_reg];
PopulateCURINSTR(RD_INC, ALU, ADDR,
RD_INC_OP, ALU2, ADDR, SET_ADDR, IDX_EA, ALU, ALU2,
IDX_OP_BLD);
break;
case 0x5:
Regs[ADDR] = (ushort)(Regs[indexed_reg] + (((Regs[B] & 0x80) == 0x80) ? (Regs[B] | 0xFF00) : Regs[B]));
PopulateCURINSTR(RD_INC, ALU, ADDR,
RD_INC, ALU2, ADDR,
SET_ADDR, IDX_EA, ALU, ALU2,
IDX_OP_BLD);
break;
case 0x6:
Regs[ADDR] = (ushort)(Regs[indexed_reg] + (((Regs[A] & 0x80) == 0x80) ? (Regs[A] | 0xFF00) : Regs[A]));
PopulateCURINSTR(RD_INC, ALU, ADDR,
RD_INC, ALU2, ADDR,
SET_ADDR, IDX_EA, ALU, ALU2,
IDX_OP_BLD);
break;
case 0x7:
// Illegal
break;
case 0x8:
Regs[ADDR] = Regs[indexed_reg];
PopulateCURINSTR(RD_INC_OP, ALU2, PC, ADD8BR, ADDR, ALU2,
RD_INC, ALU, ADDR,
RD_INC_OP, ALU2, ADDR, SET_ADDR, IDX_EA, ALU, ALU2,
IDX_OP_BLD);
break;
case 0x9:
Regs[ADDR] = Regs[indexed_reg];
PopulateCURINSTR(RD_INC, ALU, PC,
RD_INC, ALU2, PC,
SET_ADDR, IDX_EA, ALU, ALU2,
ADD16BR, ADDR, IDX_EA,
RD_INC, ALU, ADDR,
RD_INC_OP, ALU2, ADDR, SET_ADDR, IDX_EA, ALU, ALU2,
IDX_OP_BLD);
break;
case 0xA:
// Illegal
break;
case 0xB:
Regs[ADDR] = Regs[indexed_reg];
PopulateCURINSTR(IDLE,
IDLE,
SET_ADDR, IDX_EA, A, B,
ADD16BR, ADDR, IDX_EA,
RD_INC, ALU, ADDR,
RD_INC_OP, ALU2, ADDR, SET_ADDR, IDX_EA, ALU, ALU2,
IDX_OP_BLD);
break;
case 0xC:
indexed_reg = PC;
Regs[ADDR] = Regs[indexed_reg];
PopulateCURINSTR(RD_INC_OP, ALU2, PC, ADD8BR, ADDR, ALU2,
RD_INC, ALU, ADDR,
RD_INC_OP, ALU2, ADDR, SET_ADDR, IDX_EA, ALU, ALU2,
IDX_OP_BLD);
break;
case 0xD:
indexed_reg = PC;
Regs[ADDR] = Regs[indexed_reg];
PopulateCURINSTR(IDLE,
RD_INC, ALU, PC,
RD_INC, ALU2, PC,
SET_ADDR, IDX_EA, ALU, ALU2,
ADD16BR, ADDR, IDX_EA,
RD_INC, ALU, ADDR,
RD_INC_OP, ALU2, ADDR, SET_ADDR, IDX_EA, ALU, ALU2,
IDX_OP_BLD);
break;
case 0xE:
// Illegal
break;
case 0xF:
if ((Regs[ALU] >> 5) == 0)
{
PopulateCURINSTR(RD_INC, ALU, PC,
RD_INC_OP, ALU2, PC, SET_ADDR, ADDR, ALU, ALU2,
RD_INC, ALU, ADDR,
RD_INC_OP, ALU2, ADDR, SET_ADDR, IDX_EA, ALU, ALU2,
IDX_OP_BLD);
}
else
{
// illegal
}
break;
}
}
else
{
switch (Regs[ALU] & 0xF)
{
case 0x0:
Regs[IDX_EA] = Regs[indexed_reg];
PopulateCURINSTR(INC16, indexed_reg,
IDX_OP_BLD);
break;
case 0x1:
Regs[IDX_EA] = Regs[indexed_reg];
PopulateCURINSTR(INC16, indexed_reg,
INC16, indexed_reg,
IDX_OP_BLD);
break;
case 0x2:
Regs[IDX_EA] = (ushort)(Regs[indexed_reg] - 1);
PopulateCURINSTR(DEC16, indexed_reg,
IDX_OP_BLD);
break;
case 0x3:
Regs[IDX_EA] = (ushort)(Regs[indexed_reg] - 2);
PopulateCURINSTR(DEC16, indexed_reg,
DEC16, indexed_reg,
IDX_OP_BLD);
break;
case 0x4:
Regs[IDX_EA] = Regs[indexed_reg];
Index_Op_Builder();
break;
case 0x5:
Regs[IDX_EA] = (ushort)(Regs[indexed_reg] + (((Regs[B] & 0x80) == 0x80) ? (Regs[B] | 0xFF00) : Regs[B]));
PopulateCURINSTR(IDX_OP_BLD);
break;
case 0x6:
Regs[IDX_EA] = (ushort)(Regs[indexed_reg] + (((Regs[A] & 0x80) == 0x80) ? (Regs[A] | 0xFF00) : Regs[A]));
PopulateCURINSTR(IDX_OP_BLD);
break;
case 0x7:
// Illegal
break;
case 0x8:
PopulateCURINSTR(RD_INC_OP, ALU2, PC, EA_8);
break;
case 0x9:
PopulateCURINSTR(RD_INC, ALU, PC,
RD_INC, ALU2, PC,
SET_ADDR, ADDR, ALU, ALU2,
EA_16);
break;
case 0xA:
// Illegal
break;
case 0xB:
PopulateCURINSTR(IDLE,
IDLE,
SET_ADDR, ADDR, A, B,
EA_16);
break;
case 0xC:
indexed_reg = PC;
PopulateCURINSTR(RD_INC_OP, ALU2, PC, EA_8);
break;
case 0xD:
indexed_reg = PC;
PopulateCURINSTR(IDLE,
RD_INC, ALU, PC,
RD_INC, ALU2, PC,
SET_ADDR, ADDR, ALU, ALU2,
EA_16);
break;
case 0xE:
// Illegal
break;
case 0xF:
// Illegal
break;
}
}
}
}
public void Index_Op_Builder()
{
switch(indexed_op)
{
case LEAX: INDEX_OP_LEA(X); break; // LEAX
case LEAY: INDEX_OP_LEA(Y); break; // LEAY
case LEAS: INDEX_OP_LEA(SP); break; // LEAS
case LEAU: INDEX_OP_LEA(US); break; // LEAU
}
}
}
}

View File

@ -69,11 +69,16 @@ namespace BizHawk.Emulation.Common.Components.MC6809
public const ushort EXG = 55;
public const ushort TFR = 56;
public const ushort WR_DEC_LO = 57;
public const ushort WR_HI = 58;
public const ushort ADD8BR = 59;
public const ushort ABX = 60;
public const ushort MUL = 61;
public const ushort JPE = 62;
public const ushort WR_DEC_HI = 58;
public const ushort WR_HI = 59;
public const ushort ADD8BR = 60;
public const ushort ABX = 61;
public const ushort MUL = 62;
public const ushort JPE = 63;
public const ushort IDX_DCDE = 64;
public const ushort IDX_OP_BLD = 65;
public const ushort EA_8 = 66;
public const ushort EA_16 = 67;
public MC6809()
{
@ -215,6 +220,16 @@ namespace BizHawk.Emulation.Common.Components.MC6809
case JPE:
if (!FlagE) { instr_pntr = 35; };
break;
case IDX_DCDE:
Index_decode();
break;
case IDX_OP_BLD:
Index_Op_Builder();
break;
case EA_8:
Regs[IDX_EA] = (ushort)(Regs[indexed_reg] + (((Regs[ALU2] & 0x80) == 0x80) ? (Regs[ALU2] | 0xFF00) : Regs[ALU2]));
Index_Op_Builder();
break;
}
break;
case WR:
@ -223,6 +238,9 @@ namespace BizHawk.Emulation.Common.Components.MC6809
case WR_DEC_LO:
Write_Dec_Lo_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case WR_DEC_HI:
Write_Dec_HI_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case WR_HI:
Write_Hi_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
@ -232,6 +250,13 @@ namespace BizHawk.Emulation.Common.Components.MC6809
case EXG:
EXG_Func(cur_instr[instr_pntr++]);
break;
case IDX_OP_BLD:
Index_Op_Builder();
break;
case EA_16:
Regs[IDX_EA] = (ushort)(Regs[indexed_reg] + Regs[ADDR]);
Index_Op_Builder();
break;
case TFR:
TFR_Func(cur_instr[instr_pntr++]);
break;

View File

@ -65,6 +65,13 @@ namespace BizHawk.Emulation.Common.Components.MC6809
Regs[dest] -= 1;
}
public void Write_Dec_HI_Func(ushort dest, ushort src)
{
if (CDLCallback != null) CDLCallback(Regs[dest], eCDLogMemFlags.Write | eCDLogMemFlags.Data);
WriteMemory(Regs[dest], (byte)(Regs[src] >> 8));
Regs[dest] -= 1;
}
public void Write_Hi_Func(ushort dest, ushort src)
{
if (CDLCallback != null) CDLCallback(Regs[dest], eCDLogMemFlags.Write | eCDLogMemFlags.Data);

View File

@ -6,7 +6,7 @@ namespace BizHawk.Emulation.Common.Components.MC6809
public partial class MC6809
{
// registers
public ushort[] Regs = new ushort[12];
public ushort[] Regs = new ushort[14];
public const ushort PC = 0;
public const ushort US = 1;
@ -21,6 +21,7 @@ namespace BizHawk.Emulation.Common.Components.MC6809
public const ushort DP = 10;
public const ushort CC = 11;
public const ushort Dr = 12;
public const ushort IDX_EA = 13;
public ushort D
{
@ -78,7 +79,7 @@ namespace BizHawk.Emulation.Common.Components.MC6809
private void ResetRegisters()
{
for (int i = 0; i < 12; i++)
for (int i = 0; i < 14; i++)
{
Regs[i] = 0;
}