/* TestChangeBlock9900.java (c) 2014-2016 Edward Swartz All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html */ package v9t9.machine.common.tests; import static org.junit.Assert.*; import org.junit.Before; import org.junit.Test; import v9t9.common.client.ISettingsHandler; import v9t9.common.cpu.IChangeElement; import v9t9.common.cpu.ICpu; import v9t9.common.machine.IMachine; import v9t9.common.machine.IMachineModel; import v9t9.common.settings.BasicSettingsHandler; import v9t9.machine.ti99.cpu.ChangeBlock9900; import v9t9.machine.ti99.cpu.Changes.AdvancePC; import v9t9.machine.ti99.cpu.Changes.ReadIncrementRegister; import v9t9.machine.ti99.cpu.Changes.ReadIndirectRegister; import v9t9.machine.ti99.cpu.Changes.ReadRegister; import v9t9.machine.ti99.cpu.Changes.ReadRegisterOffset; import v9t9.machine.ti99.cpu.Cpu9900; import v9t9.machine.ti99.cpu.CpuState9900; import v9t9.machine.ti99.cpu.MachineOperand9900; /** * @author ejs * */ public class TestChangeBlock9900 { private ICpu cpu; private int origWP; private int origPC; @Before public void setup() throws Exception { IMachineModel model = new Basic9900MachineModelTest(); ISettingsHandler settings = new BasicSettingsHandler(); IMachine machine = model.createMachine(settings); cpu = machine.getCpu(); for (int i = 0; i < 65536; i += 2) { cpu.getConsole().flatWriteWord(i, (short) 0xffff); } origWP = 0x8000; origPC = 0x400; cpu.getState().setRegister(Cpu9900.REG_WP, origWP); cpu.getState().setRegister(Cpu9900.REG_PC, origPC); cpu.getState().setRegister(Cpu9900.REG_ST, 0); } @Test public void testNoChange() throws Exception { ChangeBlock9900 change = new ChangeBlock9900(cpu); ChangeBlock9900 change2 = new ChangeBlock9900(cpu); assertEquals(change, change2); } protected void writeInstruction(int pc, int... words) { for (int i = 0; i < words.length; i++) cpu.getConsole().writeWord(pc + i * 2, (short) words[i]); } private void assertChange(ChangeBlock9900 change, int index, Class<? extends IChangeElement> klass, int... args) { IChangeElement el = change.getElement(index); assertTrue("expected " + klass.getSimpleName() + " got " + el.toString() , klass.isAssignableFrom(el.getClass())); // if (index == 0) // assertEquals(cpu, el.getParent()); // else // assertEquals(change.getElement(index-1), el.getParent()); if (klass == AdvancePC.class) { assertEquals(args[0] & 0xffff, ((AdvancePC) el).value & 0xffff); } else if (klass == ReadRegister.class) { assertEquals(args[0] & 0xffff, ((MachineOperand9900)((ReadRegister) el).state.mop).val & 0xffff); } // else if (klass == ReadWord.class) { // if (args.length > 0) // assertEquals(args[0] & 0xffff, ((ReadWord) el).state.ea & 0xffff); // } // else if (klass == WriteWord.class) { // assertEquals(args[0] & 0xffff, ((WriteWord) el).state.ea & 0xffff); // assertEquals(args[1] & 0xffff, ((WriteWord) el).state.value & 0xffff); // } } @Test public void testOpWithImmediate() throws Exception { writeInstruction(origPC, 0x204, 0x123); // LI R4,>123 ChangeBlock9900 change = new ChangeBlock9900(cpu); change.appendOperandFetch(); int curPC = cpu.getState().getPC(); assertEquals(origPC, curPC); // no changes fetching assertNotNull(change.inst); assertNull(change.xInst); assertNotNull(change.last()); assertEquals(2, change.getCount()); assertChange(change, 0, AdvancePC.class, 4); assertChange(change, 1, ReadRegister.class, 4); assertEquals((short)0xffff, cpu.getState().getRegister(4)); // no change yet change.apply(cpu); assertEquals((short)0xffff, cpu.getState().getRegister(4)); // still no change -- just operand fetches int newPC = cpu.getState().getPC(); assertEquals(0x404, newPC); } @Test public void testOpWithOneAddr() throws Exception { writeInstruction(0x400, 0xd800, 0x00c0); // MOVB R0, @>C0 int curPC = cpu.getState().getPC(); ChangeBlock9900 change = new ChangeBlock9900(cpu); change.appendOperandFetch(); assertEquals(0x400, curPC); // no changes fetching assertNotNull(change.inst); assertNull(change.xInst); assertNotNull(change.last()); assertEquals(3, change.getCount()); assertChange(change, 0, AdvancePC.class, 4); assertChange(change, 1, ReadRegister.class, 0); assertChange(change, 2, ReadRegisterOffset.class, 0xc0); change.apply(cpu); int newPC = cpu.getState().getPC(); assertEquals(0x404, newPC); } @Test public void testOpWithTwoAddrs() throws Exception { writeInstruction(0x400, 0xd820, 0x00c0, 0xff00); // MOVB @>c0, @>ff00 int curPC = cpu.getState().getPC(); ChangeBlock9900 change = new ChangeBlock9900(cpu); change.appendOperandFetch(); assertEquals(0x400, curPC); // no changes fetching assertNotNull(change.inst); assertNull(change.xInst); assertNotNull(change.last()); assertEquals(3, change.getCount()); assertChange(change, 0, AdvancePC.class, 6); assertChange(change, 1, ReadRegisterOffset.class, 0xc0); assertChange(change, 2, ReadRegisterOffset.class, 0xff00); change.apply(cpu); int newPC = cpu.getState().getPC(); assertEquals(0x406, newPC); assertEquals(0xff, ((ReadRegisterOffset) change.getElement(1)).state.value); assertEquals(0xff, ((ReadRegisterOffset) change.getElement(2)).state.value); } @Test public void testOpWithAutoInc() throws Exception { writeInstruction(0x400, 0xcf03); // MOV 3, *12+ int curPC = cpu.getState().getPC(); ChangeBlock9900 change = new ChangeBlock9900(cpu); change.appendOperandFetch(); assertEquals(0x400, curPC); // no changes fetching assertNotNull(change.inst); assertNull(change.xInst); assertNotNull(change.last()); assertEquals(3, change.getCount()); assertChange(change, 0, AdvancePC.class, 2); assertChange(change, 1, ReadRegister.class, 3); assertChange(change, 2, ReadIncrementRegister.class, origWP + 12 * 2); change.apply(cpu); assertEquals(0x402, cpu.getState().getPC()); assertEquals((short)0x0001, cpu.getState().getRegister(12)); change.revert(cpu); assertEquals(0x400, cpu.getState().getPC()); assertEquals((short)-1, cpu.getState().getRegister(12)); } @Test public void testOpWithTwoAutoInc() throws Exception { writeInstruction(0x400, 0xdcb1); // MOVB *1+, *2+ int curPC = cpu.getState().getPC(); ChangeBlock9900 change = new ChangeBlock9900(cpu); change.appendOperandFetch(); assertEquals(0x400, curPC); // no changes fetching assertNotNull(change.inst); assertNull(change.xInst); assertNotNull(change.last()); assertEquals(3, change.getCount()); assertChange(change, 0, AdvancePC.class, 2); assertChange(change, 1, ReadIncrementRegister.class, origWP + 1 * 2); assertChange(change, 2, ReadIncrementRegister.class, origWP + 2 * 2); change.apply(cpu); assertEquals(0x402, (int) cpu.getState().getPC()); assertEquals((short)0x0000, cpu.getState().getRegister(1)); assertEquals((short)0x0000, cpu.getState().getRegister(2)); change.revert(cpu); assertEquals(0x400, (int) cpu.getState().getPC()); assertEquals((short)-1, cpu.getState().getRegister(1)); assertEquals((short)-1, cpu.getState().getRegister(2)); } @Test public void testOpWithAutoIncModify1() throws Exception { writeInstruction(0x400, 0xc33a); // MOV *12+,12 cpu.getState().setRegister(12, origWP + 12*2); // this will set R12 to itself; increment is lost ChangeBlock9900 change = new ChangeBlock9900(cpu); change.appendOperandFetch(); assertEquals(3, change.getCount()); assertChange(change, 0, AdvancePC.class, 2); assertChange(change, 1, ReadIncrementRegister.class, origWP + 12 * 2); assertChange(change, 2, ReadRegister.class, 12); change.apply(cpu); assertEquals(0x402, (int) cpu.getState().getPC()); assertEquals((short)(origWP + 12*2), cpu.getState().getRegister(12)); change.revert(cpu); assertEquals(0x400, (int) cpu.getState().getPC()); assertEquals((short)(origWP + 12*2), cpu.getState().getRegister(12)); } @Test public void testOpWithAutoIncModify2() throws Exception { writeInstruction(0x400, 0xcf3c); // MOV *12+,*12+ cpu.getState().setRegister(12, origWP + 12*2); // read R12 (@R12) // incr R12 // read R12 (@R13) // incr R12 (@R14) // sets R13 = @R12 ChangeBlock9900 change = new ChangeBlock9900(cpu); change.appendOperandFetch(); assertEquals(3, change.getCount()); assertChange(change, 0, AdvancePC.class, 2); assertChange(change, 1, ReadIncrementRegister.class, origWP + 12 * 2); assertChange(change, 2, ReadIncrementRegister.class, origWP + 12 * 2); change.apply(cpu); assertEquals(0x402, (int) cpu.getState().getPC()); assertEquals((short)(origWP + 14*2), cpu.getState().getRegister(12)); // assertEquals((short)(origWP + 12*2), cpu.getState().getRegister(13)); // MOV not executed assertEquals((short)(origWP + 12*2), ((ReadIncrementRegister) change.getElement(1)).state.value); change.revert(cpu); assertEquals(0x400, (int) cpu.getState().getPC()); assertEquals((short)(origWP + 12*2), cpu.getState().getRegister(12)); assertEquals((short)-1, cpu.getState().getRegister(13)); } @Test public void testOpJump() throws Exception { writeInstruction(0x400, 0x10fe); // JMP $-2 ChangeBlock9900 change = new ChangeBlock9900(cpu); change.appendOperandFetch(); assertEquals(1, change.getCount()); assertChange(change, 0, AdvancePC.class, 2); change.apply(cpu); // not taken assertEquals(0x402, (int) cpu.getState().getPC()); change.revert(cpu); assertEquals(0x400, (int) cpu.getState().getPC()); } @Test public void testInstrJump() throws Exception { writeInstruction(0x400, 0x10fe); // JMP $-2 ChangeBlock9900 change = new ChangeBlock9900(cpu); change.generate(); change.apply(cpu); assertEquals(0x3fe, (int) cpu.getState().getPC()); change.revert(cpu); assertEquals(0x400, (int) cpu.getState().getPC()); } @Test public void testInstrJumpCond() throws Exception { writeInstruction(0x400, 0x137f); // JEQ $+256 ChangeBlock9900 change = new ChangeBlock9900(cpu); change.generate(); //// taken cpu.getState().setST((short) 0x2000); change.apply(cpu); assertEquals(0x500, (int) cpu.getState().getPC()); change.revert(cpu); assertEquals(0x400, (int) cpu.getState().getPC()); //// not taken cpu.getState().setST((short) 0); change.apply(cpu); assertEquals(0x402, (int) cpu.getState().getPC()); change.revert(cpu); assertEquals(0x400, (int) cpu.getState().getPC()); } @Test public void testOpBranch() throws Exception { writeInstruction(0x400, 0x45b); // B *R11 cpu.getState().setRegister(11, 0x800); ChangeBlock9900 change = new ChangeBlock9900(cpu); change.appendOperandFetch(); assertEquals(2, change.getCount()); assertChange(change, 0, AdvancePC.class, 2); assertChange(change, 1, ReadIndirectRegister.class, 11); change.apply(cpu); // assertEquals(0x800, (int) cpu.getState().getPC()); change.revert(cpu); assertEquals(0x400, (int) cpu.getState().getPC()); } @Test public void testInstrLi() throws Exception { writeInstruction(0x400, 0x204, 0x123); // LI R4,>123 ChangeBlock9900 change = new ChangeBlock9900(cpu); change.generate(); assertEquals((short)0xffff, cpu.getState().getRegister(4)); // no change yet cpu.getState().setST((short) 0x0024); change.apply(cpu); assertEquals((short)0x123, cpu.getState().getRegister(4)); assertEquals(0x404, (int) cpu.getState().getPC()); assertTrue(cpu.getState().getStatus().isGT()); assertTrue(cpu.getState().getStatus().isH()); assertFalse(cpu.getState().getStatus().isC()); assertEquals(4, cpu.getState().getStatus().getIntMask()); // change.revert(cpu); assertEquals((short)-1, cpu.getState().getRegister(4)); assertEquals(0x400, (int) cpu.getState().getPC()); assertEquals((short) 0x0024, cpu.getState().getStatus().flatten()); } @Test public void testInstrAi() throws Exception { writeInstruction(0x400, 0x224, 0x123); // AI R4,>123 ChangeBlock9900 change = new ChangeBlock9900(cpu); change.generate(); cpu.getState().setST((short) 0x0024); change.apply(cpu); assertEquals((short)0x122, cpu.getState().getRegister(4)); assertEquals(0x404, (int) cpu.getState().getPC()); assertTrue(cpu.getState().getStatus().isGT()); assertTrue(cpu.getState().getStatus().isH()); assertTrue(cpu.getState().getStatus().isC()); assertEquals(4, cpu.getState().getStatus().getIntMask()); // change.revert(cpu); assertEquals((short)-1, cpu.getState().getRegister(4)); assertEquals(0x400, (int) cpu.getState().getPC()); assertEquals((short) 0x0024, cpu.getState().getStatus().flatten()); } @Test public void testInstrCi() throws Exception { writeInstruction(0x400, 0x284, 0x123); // CI R4,>123 ChangeBlock9900 change = new ChangeBlock9900(cpu); change.generate(); cpu.getState().setST((short) 0xe024); change.apply(cpu); assertEquals((short)-1, cpu.getState().getRegister(4)); // no change assertEquals(0x404, (int) cpu.getState().getPC()); assertFalse(cpu.getState().getStatus().isGT()); assertTrue(cpu.getState().getStatus().isH()); assertFalse(cpu.getState().getStatus().isC()); assertEquals(4, cpu.getState().getStatus().getIntMask()); // change.revert(cpu); assertEquals((short)-1, cpu.getState().getRegister(4)); assertEquals(0x400, (int) cpu.getState().getPC()); assertEquals((short) 0xe024, cpu.getState().getStatus().get()); } @Test public void testInstrLwpi() throws Exception { writeInstruction(0x400, 0x2e0, 0xcc01); // LWPI >CC01 ChangeBlock9900 change = new ChangeBlock9900(cpu); change.generate(); change.apply(cpu); assertEquals((short) 0xcc01, ((CpuState9900) cpu.getState()).getWP()); assertEquals(0x404, (int) cpu.getState().getPC()); // change.revert(cpu); assertEquals((short)origWP, ((CpuState9900) cpu.getState()).getWP()); assertEquals(0x400, (int) cpu.getState().getPC()); } @Test public void testInstrRt() throws Exception { writeInstruction(0x400, 0x45b); // B *R11 cpu.getState().setRegister(11, 0x800); ChangeBlock9900 change = new ChangeBlock9900(cpu); change.generate(); change.apply(cpu); assertEquals((short) 0x800, cpu.getState().getRegister(11)); // no change assertEquals(0x800, (int) cpu.getState().getPC()); // change.revert(cpu); assertEquals((short) 0x800, cpu.getState().getRegister(11)); assertEquals(0x400, (int) cpu.getState().getPC()); } @Test public void testInstrBl() throws Exception { writeInstruction(0x400, 0x691); // BL *1 cpu.getState().setRegister(11, 0x800); cpu.getState().setRegister(1, 0xc00); ChangeBlock9900 change = new ChangeBlock9900(cpu); change.generate(); change.apply(cpu); assertEquals((short) 0x402, cpu.getState().getRegister(11)); assertEquals(0xc00, (int) cpu.getState().getPC()); // change.revert(cpu); assertEquals((short) 0x800, cpu.getState().getRegister(11)); assertEquals(0x400, (int) cpu.getState().getPC()); } @Test public void testInstrBlR11() throws Exception { writeInstruction(0x400, 0x69B); // BL *11 cpu.getState().setRegister(11, 0x800); ChangeBlock9900 change = new ChangeBlock9900(cpu); change.generate(); change.apply(cpu); assertEquals((short) 0x402, cpu.getState().getRegister(11)); assertEquals(0x800, (int) cpu.getState().getPC()); // change.revert(cpu); assertEquals((short) 0x800, cpu.getState().getRegister(11)); assertEquals(0x400, (int) cpu.getState().getPC()); } @Test public void testInstrBlwp() throws Exception { writeInstruction(0x400, 0x420, 0x800); // BLWP @>800 cpu.getConsole().writeWord(0x800, (short) 0x9000); cpu.getConsole().writeWord(0x802, (short) 0x804); cpu.getState().setRegister(11, 0x0); cpu.getState().setRegister(13, 0x1); cpu.getState().setRegister(14, 0x2); cpu.getState().setRegister(15, 0x3); cpu.getConsole().writeWord(0x9000 + 11*2, (short) 0x10); cpu.getConsole().writeWord(0x9000 + 13*2, (short) 0x11); cpu.getConsole().writeWord(0x9000 + 14*2, (short) 0x12); cpu.getConsole().writeWord(0x9000 + 15*2, (short) 0x13); ChangeBlock9900 change = new ChangeBlock9900(cpu); change.generate(); cpu.getState().setST((short) 0x1034); change.apply(cpu); // no change assertEquals(0x0, cpu.getConsole().readWord(origWP + 11 * 2)); assertEquals(0x1, cpu.getConsole().readWord(origWP + 13 * 2)); assertEquals(0x2, cpu.getConsole().readWord(origWP + 14 * 2)); assertEquals(0x3, cpu.getConsole().readWord(origWP + 15 * 2)); assertEquals((short) 0x9000, cpu.getConsole().readWord(0x800)); assertEquals((short) 0x804, cpu.getConsole().readWord(0x802)); // actual context switch assertEquals(0x804, cpu.getState().getPC()); assertEquals((short) 0x9000, ((CpuState9900) cpu.getState()).getWP()); assertEquals(0x1034, cpu.getState().getST()); assertEquals((short) origWP, (int) cpu.getState().getRegister(13)); assertEquals(0x404, (int) cpu.getState().getRegister(14)); assertEquals(0x1034, (int) cpu.getState().getRegister(15)); // change.revert(cpu); assertEquals((short) origWP, ((CpuState9900) cpu.getState()).getWP()); assertEquals(0x0, cpu.getState().getRegister(11)); assertEquals(0x400, (int) cpu.getState().getPC()); assertEquals(0, cpu.getState().getRegister(11)); assertEquals(1, cpu.getState().getRegister(13)); assertEquals(2, cpu.getState().getRegister(14)); assertEquals(3, cpu.getState().getRegister(15)); // and old WS restored assertEquals(0x10, cpu.getConsole().readWord(0x9000 + 11 * 2)); assertEquals(0x11, cpu.getConsole().readWord(0x9000 + 13 * 2)); assertEquals(0x12, cpu.getConsole().readWord(0x9000 + 14 * 2)); assertEquals(0x13, cpu.getConsole().readWord(0x9000 + 15 * 2)); } @Test public void testInstrRtwp() throws Exception { writeInstruction(0x400, 0x380); // RTWP cpu.getState().setRegister(11, 0x0); cpu.getState().setRegister(13, 0x5000); cpu.getState().setRegister(14, 0x204); cpu.getState().setRegister(15, 0xffff); ChangeBlock9900 change = new ChangeBlock9900(cpu); change.generate(); cpu.getState().setST((short) 0x1034); change.apply(cpu); // no change assertEquals(0x0, cpu.getConsole().readWord(origWP + 11 * 2)); assertEquals(0x5000, cpu.getConsole().readWord(origWP + 13 * 2)); assertEquals(0x204, cpu.getConsole().readWord(origWP + 14 * 2)); assertEquals((short)0xffff, cpu.getConsole().readWord(origWP + 15 * 2)); // actual context switch assertEquals(0x204, cpu.getState().getPC()); assertEquals((short) 0x5000, ((CpuState9900) cpu.getState()).getWP()); assertEquals((short) 0xffff, cpu.getState().getStatus().get()); // change.revert(cpu); assertEquals((short) origWP, ((CpuState9900) cpu.getState()).getWP()); assertEquals(0x0, cpu.getState().getRegister(11)); assertEquals(0x400, (int) cpu.getState().getPC()); assertEquals(0, cpu.getState().getRegister(11)); assertEquals(0x5000, cpu.getState().getRegister(13)); assertEquals(0x204, cpu.getState().getRegister(14)); assertEquals((short) 0xffff, cpu.getState().getRegister(15)); } @Test public void testInstrXop() throws Exception { // rSP *R TERM^ ,XOP #t.ttystr , writeInstruction(0x400, 0x2c5a); // XOP *10, 1 cpu.getConsole().writeWord(0x44, (short) 0x9000); cpu.getConsole().writeWord(0x46, (short) 0x804); cpu.getState().setRegister(10, 0x4000); cpu.getState().setRegister(11, 0x0); cpu.getState().setRegister(13, 0x1); cpu.getState().setRegister(14, 0x2); cpu.getState().setRegister(15, 0x3); cpu.getConsole().writeWord(0x9000 + 11*2, (short) 0x10); cpu.getConsole().writeWord(0x9000 + 13*2, (short) 0x11); cpu.getConsole().writeWord(0x9000 + 14*2, (short) 0x12); cpu.getConsole().writeWord(0x9000 + 15*2, (short) 0x13); ChangeBlock9900 change = new ChangeBlock9900(cpu); change.generate(); cpu.getState().setST((short) 0x1034); change.apply(cpu); // no change assertEquals(0x4000, cpu.getConsole().readWord(origWP + 10 * 2)); assertEquals(0x0, cpu.getConsole().readWord(origWP + 11 * 2)); assertEquals(0x1, cpu.getConsole().readWord(origWP + 13 * 2)); assertEquals(0x2, cpu.getConsole().readWord(origWP + 14 * 2)); assertEquals(0x3, cpu.getConsole().readWord(origWP + 15 * 2)); assertEquals((short) 0x9000, cpu.getConsole().readWord(0x44)); assertEquals((short) 0x804, cpu.getConsole().readWord(0x46)); // actual context switch assertEquals((short) 0x9000, ((CpuState9900) cpu.getState()).getWP()); assertEquals((short) 0x1234, ((CpuState9900) cpu.getState()).getST()); // XOP bit assertEquals(0x804, cpu.getState().getPC()); assertEquals((short) origWP, (int) cpu.getState().getRegister(13)); assertEquals(0x402, (int) cpu.getState().getRegister(14)); assertEquals(0x1034, (int) cpu.getState().getRegister(15)); // no XOP bit // argument -- address in *R15 assertEquals((short) 0x4000, (int) cpu.getState().getRegister(11)); // change.revert(cpu); assertEquals((short) origWP, ((CpuState9900) cpu.getState()).getWP()); assertEquals((short) 0x1034, ((CpuState9900) cpu.getState()).getST()); assertEquals(0x0, cpu.getState().getRegister(11)); assertEquals(0x400, (int) cpu.getState().getPC()); assertEquals(0x4000, cpu.getState().getRegister(10)); assertEquals(0, cpu.getState().getRegister(11)); assertEquals(1, cpu.getState().getRegister(13)); assertEquals(2, cpu.getState().getRegister(14)); assertEquals(3, cpu.getState().getRegister(15)); // and old WS restored assertEquals(0x10, cpu.getConsole().readWord(0x9000 + 11 * 2)); assertEquals(0x11, cpu.getConsole().readWord(0x9000 + 13 * 2)); assertEquals(0x12, cpu.getConsole().readWord(0x9000 + 14 * 2)); assertEquals(0x13, cpu.getConsole().readWord(0x9000 + 15 * 2)); } @Test public void testMpy() throws Exception { writeInstruction(0x400, 0x38a0, 0xff00); // MPY @>FF00, r2 cpu.getConsole().writeWord(0xff00, (short) 0x90); cpu.getState().setRegister(2, 0x4001); cpu.getState().setRegister(3, 0xffff); ChangeBlock9900 change = new ChangeBlock9900(cpu); change.generate(); cpu.getState().setST((short) 0x1034); change.apply(cpu); assertEquals((short) 0x1034, (int) cpu.getState().getST()); assertEquals((short) 0x24, cpu.getState().getRegister(2)); assertEquals((short) 0x90, cpu.getState().getRegister(3)); // change.revert(cpu); assertEquals((short) 0x4001, cpu.getState().getRegister(2)); assertEquals((short) 0xffff, cpu.getState().getRegister(3)); } @Test public void testDiv1() throws Exception { writeInstruction(0x400, 0x3c60, 0xff00); // DIV @>FF00, r1 cpu.getConsole().writeWord(0xff00, (short) 0x9012); cpu.getState().setRegister(1, 0x4001); cpu.getState().setRegister(2, 0xffff); ChangeBlock9900 change = new ChangeBlock9900(cpu); change.generate(); cpu.getState().setST((short) 0x1034); change.apply(cpu); assertEquals((short) 0x1034, (int) cpu.getState().getST()); assertEquals((short) 0x71bc, cpu.getState().getRegister(1)); assertEquals((short) 0x40c7, cpu.getState().getRegister(2)); // change.revert(cpu); assertEquals((short) 0x4001, cpu.getState().getRegister(1)); assertEquals((short) 0xffff, cpu.getState().getRegister(2)); } @Test public void testDiv2() throws Exception { writeInstruction(0x400, 0x3c60, 0xff00); // DIV @>FF00, r1 cpu.getConsole().writeWord(0xff00, (short) 0x90); cpu.getState().setRegister(1, 0x4001); cpu.getState().setRegister(2, 0xffff); ChangeBlock9900 change = new ChangeBlock9900(cpu); change.generate(); cpu.getState().setST((short) 0x1034); change.apply(cpu); assertEquals((short) 0x1834, (int) cpu.getState().getST()); assertEquals((short) 0x4001, cpu.getState().getRegister(1)); assertEquals((short) 0xffff, cpu.getState().getRegister(2)); // change.revert(cpu); assertEquals((short) 0x4001, cpu.getState().getRegister(1)); assertEquals((short) 0xffff, cpu.getState().getRegister(2)); } @Test public void testX1() throws Exception { writeInstruction(0x400, 0x484); // X R4 cpu.getState().setRegister(4, 0x603); // DEC R3 cpu.getState().setRegister(3, 0); ChangeBlock9900 change = new ChangeBlock9900(cpu); change.generate(); cpu.getState().setST((short) 0x1034); change.apply(cpu); assertEquals((short) 0x603, cpu.getState().getRegister(4)); assertEquals((short) 0xffff, cpu.getState().getRegister(3)); assertEquals((short) 0x8034, (int) cpu.getState().getST()); // change.revert(cpu); assertEquals((short) 0x603, cpu.getState().getRegister(4)); assertEquals((short) 0x0, cpu.getState().getRegister(3)); } @Test public void testX2() throws Exception { writeInstruction(0x400, 0x484, 0x1234); // X R4 cpu.getState().setRegister(4, 0x201); // LI R1, ... cpu.getState().setRegister(1, 0); ChangeBlock9900 change = new ChangeBlock9900(cpu); change.generate(); cpu.getState().setST((short) 0x1034); change.apply(cpu); assertEquals((short) 0x1234, cpu.getState().getRegister(1)); assertEquals((short) 0x201, cpu.getState().getRegister(4)); assertEquals((short) 0xd034, (int) cpu.getState().getST()); assertEquals((short) 0x404, cpu.getState().getPC()); // change.revert(cpu); assertEquals((short) 0x201, cpu.getState().getRegister(4)); assertEquals((short) 0x0, cpu.getState().getRegister(1)); assertEquals((short) 0x400, cpu.getState().getPC()); } @Test public void testX3() throws Exception { writeInstruction(0x400, 0x484, 0x1234); // X R4 cpu.getConsole().writeWord(0x1234, (short) 0x9000); cpu.getState().setRegister(4, 0xc120); // MOV @>...., R4 ChangeBlock9900 change = new ChangeBlock9900(cpu); change.generate(); change.apply(cpu); assertEquals((short) 0x9000, cpu.getState().getRegister(4)); assertEquals((short) 0x404, cpu.getState().getPC()); // change.revert(cpu); assertEquals((short) 0xc120, cpu.getState().getRegister(4)); assertEquals((short) 0x400, cpu.getState().getPC()); } @Test public void testX4() throws Exception { writeInstruction(0x400, 0x4b4, 0x1234); // X *R4+ cpu.getConsole().writeWord(0x1234, (short) 0x9000); cpu.getConsole().writeWord(0xaaaa, (short) 0xc120); cpu.getState().setRegister(4, 0xaaaa); ChangeBlock9900 change = new ChangeBlock9900(cpu); change.generate(); change.apply(cpu); assertEquals((short) 0x9000, cpu.getState().getRegister(4)); // change.revert(cpu); assertEquals((short) 0xaaaa, cpu.getState().getRegister(4)); } }