package se.raek.cdp1802.sim;

import static org.junit.Assert.*;

import org.junit.Before;
import org.junit.Test;

import se.raek.cdp1802.util.ArrayMemory;
import se.raek.cdp1802.util.MemoryMapper;
import se.raek.cdp1802.util.MemoryWriteProtector;
import se.raek.cdp1802.util.Utils;

public class InstructionTest {

	private Cpu.State s;
	private Memory rom;
	private Memory ram;
	private Io io;
	private Cpu cpu;

	@Before
	public void setUp() {
		s = new Cpu.State();
		rom = new ArrayMemory(0x100);
		ram = new ArrayMemory(0x100);
		MemoryMapper mm = new MemoryMapper();
		mm.map(0x0000, 0x100, new MemoryWriteProtector(rom));
		mm.map(0x0100, 0x100, ram);
		io = new MockIo();
		cpu = new Cpu(s, mm, io);
	}

	private void loadRom(String hexString) {
		Utils.loadHex(rom, hexString);
	}

	private void runUntilIdle() {
		while (!s.idle) {
			cpu.tick();
		}
	}

	private void singleStep() {
		cpu.tick();
	}

	@Test
	public void testIncDecWrapAround() {
		loadRom("2414");
		assertEquals(0x0000, s.r[0x4]);
		singleStep();
		assertEquals(0xFFFF, s.r[0x4]);
		singleStep();
		assertEquals(0x0000, s.r[0x4]);
	}

	@Test
	public void testReq() {
		loadRom("7B7A00");
		runUntilIdle();
		assertFalse(s.q);
	}

	@Test
	public void testSeq() {
		loadRom("7B00");
		runUntilIdle();
		assertTrue(s.q);
	}

	@Test
	public void testGloGhiPloPhi() {
		loadRom("F812B4F834A494B584A5");
		singleStep();
		singleStep();
		assertEquals(0x1200, s.r[0x4]);
		singleStep();
		singleStep();
		assertEquals(0x1234, s.r[0x4]);
		singleStep();
		assertEquals(0x12, s.d);
		singleStep();
		assertEquals(0x1200, s.r[0x5]);
		singleStep();
		assertEquals(0x34, s.d);
		singleStep();
		assertEquals(0x1234, s.r[0x5]);
	}

	@Test
	public void testLdi() {
		loadRom("F8A500");
		runUntilIdle();
		assertEquals(0xA5, s.d);
	}

}

@@ -23,16 +23,53 @@
 2.sim;%0A%0A
+import static org.mockito.Mockito.*;%0A
 import s
@@ -94,16 +94,16 @@
 sert.*;%0A
-
 %0Aimport 
@@ -142,16 +142,44 @@
 it.Test;
+%0Aimport org.mockito.InOrder;
 %0A%0Aimport
@@ -728,19 +728,21 @@
 o = 
-new M
+m
 ock
+(
 Io
-(
+.class
 );%0A%09
@@ -1128,32 +1128,32 @@
 %09%09singleStep();%0A
-
 %09%09assertEquals(0
@@ -1166,32 +1166,287 @@
  s.r%5B0x4%5D);%0A%09%7D%0A%0A
+%09@Test%0A%09public void testOut() %7B%0A%09%09loadRom(%22611162226333644465556666677700%22);%0A%09%09runUntilIdle();%0A%09%09InOrder inOrder = inOrder(io);%0A%09%09for (int i = 1; i %3C= 7; i++) %7B%0A%09%09%09inOrder.verify(io).output(i, (i %3C%3C 4) %7C i);%09%0A%09%09%7D%0A%09%09inOrder.verifyNoMoreInteractions();%0A%09%7D%0A%0A
 %09@Test%0A%09public v

Use Mockito to test Io behavior for OUT instructions