1
0
mirror of https://github.com/pevans/erc-c.git synced 2024-06-11 05:29:33 +00:00

Implement the TRB (Test and Reset Bits) instruction

This commit is contained in:
Peter Evans 2018-02-22 00:39:33 -06:00
parent 807362e871
commit a4c3d1c4ef
7 changed files with 55 additions and 3 deletions

View File

@ -125,6 +125,7 @@ enum instruction {
STZ, // STore Zero
TAX, // Transfer Accumulator to X
TAY, // Transfer Accumulator to Y
TRB, // Test and Reset Bits
TSX, // Transfer Stack register to X
TXA, // Transfer X to Accumulator
TXS, // Transfer X to Stack register

View File

@ -234,6 +234,7 @@ DECL_INST(sty);
DECL_INST(stz);
DECL_INST(tax);
DECL_INST(tay);
DECL_INST(trb);
DECL_INST(tsx);
DECL_INST(txa);
DECL_INST(txs);

View File

@ -20,7 +20,7 @@
static int addr_modes[] = {
// 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
IMP, IDX, NOA, NOA, NOA, ZPG, ZPG, NOA, IMP, IMM, ACC, NOA, NOA, ABS, ABS, NOA, // 0x
REL, IDY, ZPG, NOA, NOA, ZPX, ZPX, NOA, IMP, ABY, ACC, NOA, NOA, ABX, ABX, NOA, // 1x
REL, IDY, ZPG, NOA, ZPG, ZPX, ZPX, NOA, IMP, ABY, ACC, NOA, ABS, ABX, ABX, NOA, // 1x
ABS, IDX, NOA, NOA, ZPG, ZPG, ZPG, NOA, IMP, IMM, ACC, NOA, ABS, ABS, ABS, NOA, // 2x
REL, IDY, ZPG, NOA, ZPX, ZPX, ZPX, NOA, IMP, ABY, ACC, NOA, ABX, ABX, ABX, NOA, // 3x
IMP, IDX, NOA, NOA, NOA, ZPG, ZPG, NOA, IMP, IMM, ACC, NOA, ABS, ABS, ABS, NOA, // 4x

View File

@ -28,7 +28,7 @@
static int instructions[] = {
// 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
BRK, ORA, BAD, BAD, BAD, ORA, ASL, BAD, PHP, ORA, ASL, BAD, BAD, ORA, ASL, BAD, // 0x
BPL, ORA, ORA, BAD, BAD, ORA, ASL, BAD, CLC, ORA, INC, BAD, BAD, ORA, ASL, BAD, // 1x
BPL, ORA, ORA, BAD, TRB, ORA, ASL, BAD, CLC, ORA, INC, BAD, TRB, ORA, ASL, BAD, // 1x
JSR, AND, BAD, BAD, BIT, AND, ROL, BAD, PLP, AND, ROL, BAD, BIT, AND, ROL, BAD, // 2x
BMI, AND, AND, BAD, BIT, AND, ROL, BAD, SEC, AND, DEC, BAD, BIT, AND, ROL, BAD, // 3x
RTI, EOR, BAD, BAD, BAD, EOR, LSR, BAD, PHA, EOR, LSR, BAD, JMP, EOR, LSR, BAD, // 4x
@ -117,6 +117,7 @@ static mos6502_instruction_handler instruction_handlers[] = {
INST_HANDLER(stz),
INST_HANDLER(tax),
INST_HANDLER(tay),
INST_HANDLER(trb),
INST_HANDLER(tsx),
INST_HANDLER(txa),
INST_HANDLER(txs),
@ -131,7 +132,7 @@ static mos6502_instruction_handler instruction_handlers[] = {
static int cycles[] = {
// 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
7, 6, 0, 0, 0, 3, 5, 0, 3, 2, 2, 0, 0, 4, 6, 0, // 0x
2, 5, 5, 0, 0, 4, 6, 0, 2, 4, 2, 0, 0, 4, 7, 0, // 1x
2, 5, 5, 0, 5, 4, 6, 0, 2, 4, 2, 0, 6, 4, 7, 0, // 1x
6, 6, 0, 0, 3, 3, 5, 0, 4, 2, 2, 0, 4, 4, 6, 0, // 2x
2, 5, 5, 0, 4, 4, 6, 0, 2, 4, 2, 0, 4, 4, 7, 0, // 3x
6, 6, 0, 0, 0, 3, 5, 0, 3, 2, 2, 0, 3, 4, 6, 0, // 4x

View File

@ -101,6 +101,7 @@ static char *instruction_strings[] = {
"STZ",
"TAX",
"TAY",
"TRB",
"TSX",
"TXA",
"TXS",

View File

@ -156,6 +156,37 @@ DEFINE_INST(tay)
cpu->Y = cpu->A;
}
/*
* This is a really funky instruction. And not in the good, dancy kinda
* way.
*
* First, it does a BIT-style test to see if A & oper are zero; if so,
* it sets the Z flag.
*
* Second, it clears all bits in eff_addr where A's corresponding bits
* are set to 1. It ignores all bits in eff_addr where A's bits are
* zero.
*
* E.g.:
*
* A: 01011001 (accumulator)
* M: 11111111 (value in memory)
* R: 10100110 (result)
*
* And, as following that, the Z flag should be zero because A&M is a
* non-zero result.
*/
DEFINE_INST(trb)
{
cpu->P &= ~MOS_ZERO;
if (!(cpu->A & oper)) {
cpu->P |= MOS_ZERO;
}
mos6502_set(cpu, cpu->eff_addr,
(cpu->A ^ 0xff) & oper);
}
/*
* Transfer the stack pointer (S register) to X.
*/

View File

@ -140,6 +140,23 @@ Test(mos6502_loadstor, tay)
cr_assert_eq(cpu->Y, 111);
}
Test(mos6502_loadstor, trb)
{
cpu->A = 6;
mos6502_handle_trb(cpu, 3);
cr_assert_eq(cpu->P & MOS_ZERO, 0);
cpu->A = 9;
mos6502_handle_trb(cpu, 2);
cr_assert_eq(cpu->P & MOS_ZERO, MOS_ZERO);
cpu->eff_addr = 111;
mos6502_set(cpu, cpu->eff_addr, 123);
mos6502_handle_trb(cpu, 123);
cr_assert_eq(mos6502_get(cpu, cpu->eff_addr),
(cpu->A ^ 0xff) & 123);
}
Test(mos6502_loadstor, tsx)
{
cpu->S = 111;