//TODO: I need to implement this part // use ReadWord() to read the instruction at location addr, and return true if // bit is 1 in the instruction, or false if 0 (bit should be in the range [0..31]) public bool TestFlag(uint address, uint bit) { if (31 < bit) // bit not in the range [0..31]) { Console.WriteLine("Cant testFlag: bit is out of range"); return(false); } uint num1 = ReadWord(address); num1 = BarrelShifter.lsl(num1, 31 - bit); num1 = BarrelShifter.lsr(num1, 31); if (num1 == 1) { return(true); } else { return(false); } }
public static void runTests() { Console.WriteLine("Testing BarrelShifter class methods"); Console.WriteLine("------------------------------"); // use http://www.binaryhexconverter.com/decimal-to-hex-converter to convert between hex, dec, and bin Console.WriteLine("Testing: lsl(int instruct, int num)..."); uint i1 = 0xffff; uint i2 = 0xf; uint i3 = 0xa; uint i4 = 0x1; uint i5 = 0xfffffff; Debug.Assert(BarrelShifter.lsl(i1, 2) == 0x3fffc); Debug.Assert(BarrelShifter.lsl(i1, 1) == 0x1fffe); Debug.Assert(BarrelShifter.lsl(i1, 4) == 0xffff0); Debug.Assert(BarrelShifter.lsl(i5, 2) == 0x3ffffffc); Debug.Assert(BarrelShifter.lsl(i4, 3) == 0x8); Debug.Assert(BarrelShifter.lsl(i3, 8) == 0xa00); Debug.Assert(BarrelShifter.lsl(i2, 6) == 0x3c0); i1 = 0xFFFFFFFE; // 2's comp = FFFF FFFE = -0x2; i2 = 0xFFFFFFF1; // 2's comp = FFFF FFF1 = -0xf; i3 = 0xFFFFFFF6; // 2's comp = FFFF FFF6 = -0xa; i4 = 0xFF000100; // 2's comp = FF00 0100 = -0xffff00; i5 = 0xF0000001; // 2's comp = F000 0001 = -0xfffffff; Debug.Assert(BarrelShifter.lsl(i1, 2) == 0xfffffff8); Debug.Assert(BarrelShifter.lsl(i1, 1) == 0xfffffffc); Debug.Assert(BarrelShifter.lsl(i1, 8) == 0xfffffe00); Debug.Assert(BarrelShifter.lsl(i2, 4) == 0xffffff10); Debug.Assert(BarrelShifter.lsl(i3, 8) == 0xfffff600); Debug.Assert(BarrelShifter.lsl(i4, 8) == 0x00010000); Debug.Assert(BarrelShifter.lsl(i5, 12) == 0x00001000); Debug.Assert(BarrelShifter.lsl(i5, 31) == 0x80000000); Debug.Assert(BarrelShifter.lsl(i5, 32) == 0x00000000); Debug.Assert(BarrelShifter.lsl(i5, 100) == 0x00000000); Console.WriteLine("Testing: lsr(int instruct, int num)..."); i1 = 0x2; i2 = 0xf; i3 = 0xa; i4 = 0xffff00; i5 = 0xfffffff; Debug.Assert(BarrelShifter.lsr(i1, 2) == 0x0); Debug.Assert(BarrelShifter.lsr(i1, 1) == 0x1); Debug.Assert(BarrelShifter.lsr(i1, 8) == 0x0); Debug.Assert(BarrelShifter.lsr(i2, 2) == 0x3); Debug.Assert(BarrelShifter.lsr(i3, 3) == 0x1); Debug.Assert(BarrelShifter.lsr(i4, 8) == 0xffff); Debug.Assert(BarrelShifter.lsr(i5, 6) == 0x3fffff); i1 = 0xFFFFFFFE; // 2's comp = FFFF FFFE = -0x2; i2 = 0xFFFFFFF1; // 2's comp = FFFF FFF1 = -0xf; i3 = 0xFFFFFFF6; // 2's comp = FFFF FFF6 = -0xa; i4 = 0xFF000100; // 2's comp = FF00 0100 = -0xffff00; i5 = 0xF0000001; // 2's comp = F000 0001 = -0xfffffff; Debug.Assert(BarrelShifter.lsr(i1, 1) == 0x7fffffff); Debug.Assert(BarrelShifter.lsr(i1, 2) == 0x3fffffff); Debug.Assert(BarrelShifter.lsr(i1, 8) == 0x00ffffff); Debug.Assert(BarrelShifter.lsr(i2, 4) == 0x0fffffff); Debug.Assert(BarrelShifter.lsr(i2, 4) == 0x0fffffff); Debug.Assert(BarrelShifter.lsr(i3, 8) == 0x00ffffff); Debug.Assert(BarrelShifter.lsr(i4, 12) == 0x000ff000); Debug.Assert(BarrelShifter.lsr(i5, 16) == 0x0000f000); Console.WriteLine("Testing: asr(int instruct, int num)..."); i1 = 0x2; i2 = 0xf; i3 = 0xa; i4 = 0xffff00; i5 = 0xfffffff; Debug.Assert(BarrelShifter.asr(i1, 1) == 0x1); Debug.Assert(BarrelShifter.asr(i1, 2) == 0x0); Debug.Assert(BarrelShifter.asr(i1, 8) == 0x0); Debug.Assert(BarrelShifter.asr(i2, 4) == 0x0); Debug.Assert(BarrelShifter.asr(i3, 4) == 0x0); Debug.Assert(BarrelShifter.asr(i4, 8) == 0xffff); Debug.Assert(BarrelShifter.asr(i5, 12) == 0xffff); i1 = 0xFFFFFFFE; // 2's comp = FFFF FFFE = -0x2; i2 = 0xFFFFFFF1; // 2's comp = FFFF FFF1 = -0xf; i3 = 0xFFFFFFF6; // 2's comp = FFFF FFF6 = -0xa; i4 = 0xFF000100; // 2's comp = FF00 0100 = -0xffff00; i5 = 0xF0000001; // 2's comp = F000 0001 = -0xfffffff; Debug.Assert(BarrelShifter.asr(i1, 1) == 0xffffffff); Debug.Assert(BarrelShifter.asr(i1, 2) == 0xffffffff); Debug.Assert(BarrelShifter.asr(i1, 8) == 0xffffffff); Debug.Assert(BarrelShifter.asr(i2, 4) == 0xffffffff); Debug.Assert(BarrelShifter.asr(i2, 2) == 0xfffffffc); Debug.Assert(BarrelShifter.asr(i3, 4) == 0xffffffff); Debug.Assert(BarrelShifter.asr(i4, 8) == 0xffff0001); Debug.Assert(BarrelShifter.asr(i5, 12) == 0xffff0000); Console.WriteLine("Testing: asl(int instruct, int num)..."); i1 = 0x2; i2 = 0xf; i3 = 0xa; i4 = 0xffff00; i5 = 0xfffffff; Debug.Assert(BarrelShifter.asl(i1, 2) == 0x8); Debug.Assert(BarrelShifter.asl(i1, 1) == 0x4); Debug.Assert(BarrelShifter.asl(i1, 8) == 0x200); Debug.Assert(BarrelShifter.asl(i2, 2) == 0x3c); Debug.Assert(BarrelShifter.asl(i3, 3) == 0x50); Debug.Assert(BarrelShifter.asl(i4, 8) == 0xffff0000); Debug.Assert(BarrelShifter.asl(i5, 4) == 0xfffffff0); i1 = 0xFFFFFFFE; // 2's comp = FFFF FFFE = -0x2; i2 = 0xFFFFFFF1; // 2's comp = FFFF FFF1 = -0xf; i3 = 0xFFFFFFF6; // 2's comp = FFFF FFF6 = -0xa; i4 = 0xFF000100; // 2's comp = FF00 0100 = -0xffff00; i5 = 0xF0000001; // 2's comp = F000 0001 = -0xfffffff; Debug.Assert(BarrelShifter.asl(i1, 2) == 0xfffffff8); Debug.Assert(BarrelShifter.asl(i1, 1) == 0xfffffffc); Debug.Assert(BarrelShifter.asl(i1, 8) == 0xfffffe00); Debug.Assert(BarrelShifter.asl(i2, 4) == 0xffffff10); Debug.Assert(BarrelShifter.asl(i3, 8) == 0xfffff600); Debug.Assert(BarrelShifter.asl(i4, 8) == 0x00010000); Debug.Assert(BarrelShifter.asl(i5, 12) == 0x00001000); Console.WriteLine("Testing: ror(int instruct, int num)..."); i1 = 0x2; i2 = 0xf; i3 = 0xa; i4 = 0x00ffff00; i5 = 0x0fffffff; Debug.Assert(BarrelShifter.ror(i1, 0) == 0x2); Debug.Assert(BarrelShifter.ror(i1, 4) == 0x20000000); Debug.Assert(BarrelShifter.ror(i1, 8) == 0x02000000); Debug.Assert(BarrelShifter.ror(i2, 8) == 0x0f000000); Debug.Assert(BarrelShifter.ror(i3, 4) == 0xa0000000); Debug.Assert(BarrelShifter.ror(i4, 12) == 0xf0000fff); Debug.Assert(BarrelShifter.ror(i5, 16) == 0xffff0fff); i1 = 0xFFFFFFFE; // 2's comp = FFFF FFFE = -0x2; i2 = 0xFFFFFFF1; // 2's comp = FFFF FFF1 = -0xf; i3 = 0xFFFFFFF6; // 2's comp = FFFF FFF6 = -0xa; i4 = 0xFF000100; // 2's comp = FF00 0100 = -0xffff00; i5 = 0xF0000001; // 2's comp = F000 0001 = -0xfffffff; Debug.Assert(BarrelShifter.ror(i1, 0) == 0xfffffffe); Debug.Assert(BarrelShifter.ror(i1, 4) == 0xefffffff); Debug.Assert(BarrelShifter.ror(i1, 8) == 0xfeffffff); Debug.Assert(BarrelShifter.ror(i2, 4) == 0x1fffffff); Debug.Assert(BarrelShifter.ror(i3, 8) == 0xf6ffffff); Debug.Assert(BarrelShifter.ror(i4, 8) == 0x00ff0001); Debug.Assert(BarrelShifter.ror(i5, 12) == 0x001f0000); Debug.Assert(BarrelShifter.ror(i5, 32) == 0xf0000001); Debug.Assert(BarrelShifter.ror(i5, 64) == 0xf0000001); }
private static void startCVersionTests() { Memory mem = new Memory(); // 32 KB Registers regs = new Registers(); CPU cpu = new CPU(mem, regs); //************************************ C Version Tests ********************************// //************************************ testing MOV *********************************// // At memory slot 0 // WriteWord(memAddress, Value) mem.WriteWord(0, 0xe3a02030); // e3a02030 = MOV R2, #48 cpu.fetch(); cpu.decode(); cpu.execute(); //adds a instruction string to CPUInstructionRowList Debug.Assert(regs.getRegNValue(2) == 48); Debug.Assert(cpu.getTopInstAddrDisString() == "0x00000000: e3a02030: mov r2, #48"); // a whole instruction string gets saved in a one row // At memory slot 4 mem.WriteWord(4, 0xe1a0476d); // 0xe1a0476d = MOV R4, R13, ROR #14 regs.updateRegisterN(13, 1); cpu.fetch(); cpu.decode(); cpu.execute(); //adds a instruction string to CPUInstructionRowList Debug.Assert(regs.getRegNValue(4) == BarrelShifter.ror(1, 14)); Debug.Assert(cpu.getTopInstAddrDisString() == "0x00000004: e1a0476d: mov r4, sp, ror #14"); //************************************ testing MVN *********************************// // At memory slot 8 mem.WriteWord(8, 0xe1e09442); // 0xe1e09442 = MVN R9, R2, ASR #8 regs.updateRegisterN(2, 2); regs.updateRegisterN(9, 9); cpu.fetch(); cpu.decode(); cpu.execute(); //adds a instruction string to CPUInstructionRowList Debug.Assert(regs.getRegNValue(9) == ~(BarrelShifter.asr(2, 8))); Debug.Assert(regs.getRegNValue(2) == 2); Debug.Assert(cpu.getTopInstAddrDisString() == "0x00000008: e1e09442: mvn r9, r2, asr #8"); // At memory slot 12 mem.WriteWord(12, 0xE1E0D18B); // 0xE1E0D18B = MVN R13, R11, LSL #3 regs.updateRegisterN(13, 13); regs.updateRegisterN(11, 11); cpu.fetch(); cpu.decode(); cpu.execute(); //adds a instruction string to CPUInstructionRowList Debug.Assert(regs.getRegNValue(13) == ~(BarrelShifter.lsl(11, 3))); Debug.Assert(regs.getRegNValue(11) == 11); Debug.Assert(cpu.getTopInstAddrDisString() == "0x0000000C: e1e0d18b: mvn sp, fp, lsl #3"); // At memory slot 16 mem.WriteWord(16, 0xE3E0E0FF); // 0xE3E0E0FF = MVN R14, #255 regs.updateRegisterN(14, 14); cpu.fetch(); cpu.decode(); cpu.execute(); //adds a instruction string to CPUInstructionRowList Debug.Assert(regs.getRegNValue(14) == ~((uint)255)); Debug.Assert(cpu.getTopInstAddrDisString() == "0x00000010: e3e0e0ff: mvn lr, #255"); //************************************ testing ADD *********************************// // At memory slot 20 mem.WriteWord(20, 0XE28100FF); // 0XE28100FF = ADD RO, R1, #255 // Immediate regs.updateRegisterN(0, 0); regs.updateRegisterN(1, 1); cpu.fetch(); cpu.decode(); cpu.execute(); //adds a instruction string to CPUInstructionRowList Debug.Assert(regs.getRegNValue(0) == 256); Debug.Assert(regs.getRegNValue(1) == 1); //Console.WriteLine("0x00000014\t ADD RO, R1, #255"); //Console.WriteLine(cpu.getCPUInstructionRowListLastItem()); Debug.Assert(cpu.getTopInstAddrDisString() == "0x00000014: e28100ff: add r0, r1, #255"); //************************************ Tests for ctests.exe ********************************// // set up for test cases mem.clearMemory(); regs.clearRegisters(); cpu.clearInstAddrDisLists(); // INSTRUCTION ADDRESS DISASSEMBLED uint[] instLst = { 0xe3a00fb5, // 1000: e3a00fb5 mov r0, #724 ; 0x2d4 0xe3a014a1, // 1004: e3a014a1 mov r1, #-1593835520 ; 0xa1000000 0xe1a02000, // 1008: e1a02000 mov r2, r0 0xe1a0200f, // 100c: e1a0200f mov r2, pc 0xe1a02141, // 1010: e1a02141 asr r2, r1, #2 0xe1a02121, // 1014: e1a02121 lsr r2, r1, #2 0xe1a02081, // 1018: e1a02081 lsl r2, r1, #1 0xe1a02260, // 101c: e1a02260 ror r2, r0, #4 0xe3e03001, // 1020: e3e03001 mvn r3, #1 0xe3a04004, // 1024: e3a04004 mov r4, #4 0xe2445003, // 1028: e2445003 sub r5, r4, #3 0xe2445003, // 102c: e2445003 sub r5, r4, #3 0xe2645003, // 1030: e2645003 rsb r5, r4, #3 0xe20020ff, // 1034: e20020ff and r2, r0, #255 ; 0xff 0xe3802012, // 1038: e3802012 orr r2, r0, #18 0xe2202fb7, // 103c: e2202fb7 eor r2, r0, #732 ; 0x2dc 0xe20020ff, // 1040: e20020ff and r2, r0, #255 ; 0xff 0xe3a02002, // 1044: e3a02002 mov r2, #2 0xe0050291, // 1048: e0050291 mul r5, r1, r2 0xef000011 // 104c: ef000011 svc 0x00000011 }; // writing instruction into memory starting at 0x1000 for (uint i = 0, addr = 0x1000; i < instLst.Length; i++) { mem.WriteWord(addr, instLst[i]); addr += 4; } regs.updateProgramCounter(0x1000); // set PC //************************************ MOV ********************************// // Strings of decoded instructions are in this format: 1000: e3a00fb5 \tmov r0, #724 // Addr Instruct // 1000: e3a00fb5 mov r0, #724 ; 0x2d4 cpu.fetch(); cpu.decode(); cpu.execute(); //adds a instruction string to CPUInstructionRowList Debug.Assert(regs.getRegNValue(0) == 724); Debug.Assert(cpu.getTopInstAddrDisString() == "0x00001000: e3a00fb5: mov r0, #724"); // 1004: e3a014a1 mov r1, #-1593835520 ; 0xa1000000 regs.updateRegisterN(1, 1); cpu.fetch(); cpu.decode(); cpu.execute(); //adds a instruction string to CPUInstructionRowList Debug.Assert(regs.getRegNValue(1) == 0xa1000000); Debug.Assert(cpu.getTopInstAddrDisString() == "0x00001004: e3a014a1: mov r1, #-1593835520"); // 1008: e1a02000 mov r2, r0 cpu.fetch(); cpu.decode(); cpu.execute(); //adds a instruction string to CPUInstructionRowList Debug.Assert(regs.getRegNValue(0) == 724); Debug.Assert(regs.getRegNValue(2) == 724); Debug.Assert(cpu.getTopInstAddrDisString() == "0x00001008: e1a02000: mov r2, r0"); // 100c: e1a0200f mov r2, pc cpu.fetch(); cpu.decode(); cpu.execute(); //adds a instruction string to CPUInstructionRowList Debug.Assert(regs.getRegNValue(2) == cpu.getCPUCurrentAddr() + 8); Debug.Assert(regs.getRegNValue(15) == cpu.getCPUCurrentAddr() + 4); Debug.Assert(cpu.getTopInstAddrDisString() == "0x0000100C: e1a0200f: mov r2, pc"); // 1010: e1a02141 asr r2, r1, #2 = mov r2, r1, asr #2 cpu.fetch(); cpu.decode(); cpu.execute(); //adds a instruction string to CPUInstructionRowList Debug.Assert(regs.getRegNValue(1) == 0xa1000000); Debug.Assert(regs.getRegNValue(2) == BarrelShifter.asr(0xa1000000, 2)); Debug.Assert(cpu.getTopInstAddrDisString() == "0x00001010: e1a02141: mov r2, r1, asr #2"); // 1014: e1a02121 lsr r2, r1, #2 = mov r2, r1, lsr #2 cpu.fetch(); cpu.decode(); cpu.execute(); //adds a instruction string to CPUInstructionRowList Debug.Assert(regs.getRegNValue(1) == 0xa1000000); Debug.Assert(regs.getRegNValue(2) == BarrelShifter.lsr(0xa1000000, 2)); Debug.Assert(cpu.getTopInstAddrDisString() == "0x00001014: e1a02121: mov r2, r1, lsr #2"); // 1018: e1a02081 lsl r2, r1, #1 = mov r2, r1, lsl #1 cpu.fetch(); cpu.decode(); cpu.execute(); //adds a instruction string to CPUInstructionRowList Debug.Assert(regs.getRegNValue(1) == 0xa1000000); Debug.Assert(regs.getRegNValue(2) == BarrelShifter.lsl(0xa1000000, 1)); Debug.Assert(cpu.getTopInstAddrDisString() == "0x00001018: e1a02081: mov r2, r1, lsl #1"); // 101c: e1a02260 ror r2, r0, #4 = mov r2, r0, ror #4 cpu.fetch(); cpu.decode(); cpu.execute(); //adds a instruction string to CPUInstructionRowList Debug.Assert(regs.getRegNValue(0) == 724); Debug.Assert(regs.getRegNValue(2) == BarrelShifter.ror(724, 4)); Debug.Assert(cpu.getTopInstAddrDisString() == "0x0000101C: e1a02260: mov r2, r0, ror #4"); // 1020: e3e03001 mvn r3, #1 cpu.fetch(); cpu.decode(); cpu.execute(); //adds a instruction string to CPUInstructionRowList Debug.Assert(regs.getRegNValue(3) == ~(uint)1); Debug.Assert(cpu.getTopInstAddrDisString() == "0x00001020: e3e03001: mvn r3, #1"); // 1024: e3a04004 mov r4, #4 cpu.fetch(); cpu.decode(); cpu.execute(); //adds a instruction string to CPUInstructionRowList Debug.Assert(regs.getRegNValue(4) == 4); Debug.Assert(cpu.getTopInstAddrDisString() == "0x00001024: e3a04004: mov r4, #4"); // 1028: e2445003 sub r5, r4, #3 cpu.fetch(); cpu.decode(); cpu.execute(); //adds a instruction string to CPUInstructionRowList Debug.Assert(regs.getRegNValue(4) == 4); Debug.Assert(regs.getRegNValue(5) == 1); Debug.Assert(cpu.getTopInstAddrDisString() == "0x00001028: e2445003: sub r5, r4, #3"); // 102c: e2445003 sub r5, r4, #3 cpu.fetch(); cpu.decode(); cpu.execute(); //adds a instruction string to CPUInstructionRowList Debug.Assert(regs.getRegNValue(4) == 4); Debug.Assert(regs.getRegNValue(5) == 1); Debug.Assert(cpu.getTopInstAddrDisString() == "0x0000102C: e2445003: sub r5, r4, #3"); // 1030: e2645003 rsb r5, r4, #3 cpu.fetch(); cpu.decode(); cpu.execute(); //adds a instruction string to CPUInstructionRowList Debug.Assert(regs.getRegNValue(4) == 4); Debug.Assert((int)regs.getRegNValue(5) == 3 - 4); Debug.Assert(cpu.getTopInstAddrDisString() == "0x00001030: e2645003: rsb r5, r4, #3"); // 1034: e20020ff and r2, r0, #255 ; 0xff cpu.fetch(); cpu.decode(); cpu.execute(); //adds a instruction string to CPUInstructionRowList Debug.Assert(regs.getRegNValue(0) == 0x2d4); Debug.Assert(regs.getRegNValue(2) == 0xd4); Debug.Assert(cpu.getTopInstAddrDisString() == "0x00001034: e20020ff: and r2, r0, #255"); // 1038: e3802012 orr r2, r0, #18 cpu.fetch(); cpu.decode(); cpu.execute(); //adds a instruction string to CPUInstructionRowList Debug.Assert(regs.getRegNValue(0) == 0x2d4); Debug.Assert(regs.getRegNValue(2) == 0x2d6); Debug.Assert(cpu.getTopInstAddrDisString() == "0x00001038: e3802012: orr r2, r0, #18"); // 103c: e2202fb7 eor r2, r0, #732 ; 0x2dc cpu.fetch(); cpu.decode(); cpu.execute(); //adds a instruction string to CPUInstructionRowList Debug.Assert(regs.getRegNValue(0) == 0x2d4); Debug.Assert(regs.getRegNValue(2) == 0x8); Debug.Assert(cpu.getTopInstAddrDisString() == "0x0000103C: e2202fb7: eor r2, r0, #732"); // 1040: e20020ff and r2, r0, #255 ; 0xff cpu.fetch(); cpu.decode(); cpu.execute(); //adds a instruction string to CPUInstructionRowList Debug.Assert(regs.getRegNValue(0) == 0x2d4); Debug.Assert(regs.getRegNValue(2) == 0xd4); Debug.Assert(cpu.getTopInstAddrDisString() == "0x00001040: e20020ff: and r2, r0, #255"); // 1044: e3a02002 mov r2, #2 cpu.fetch(); cpu.decode(); cpu.execute(); //adds a instruction string to CPUInstructionRowList Debug.Assert(regs.getRegNValue(2) == 2); Debug.Assert(cpu.getTopInstAddrDisString() == "0x00001044: e3a02002: mov r2, #2"); // 1048: e0050291 mul r5, r1, r2 cpu.fetch(); cpu.decode(); cpu.execute(); //adds a instruction string to CPUInstructionRowList Debug.Assert(regs.getRegNValue(2) == 2); Debug.Assert(regs.getRegNValue(1) == 0xa1000000); uint n1 = 0xa1000000; uint n2 = 2; Debug.Assert(regs.getRegNValue(5) == n1 * n2); Debug.Assert(cpu.getTopInstAddrDisString() == "0x00001048: e0050291: mul r5, r1, r2"); // 104c: ef000011 svc 0x00000011 cpu.fetch(); cpu.decode(); cpu.execute(); //adds a instruction string to CPUInstructionRowList Debug.Assert(regs.getRegNValue(2) == 2); Debug.Assert(cpu.getTopInstAddrDisString() == "0x0000104C: ef000011: svc 0x00000011"); cpu.traceLogFlush(); cpu.traceLogClose(); // Helper code to test //Console.WriteLine(cpu.getCPUInstructionRowListLastItem()); /********************************************/ //Console.WriteLine(regs.getRegNValue(15)); /********************************************/ //Console.WriteLine(cpu.getCPUCurrentAddr() + 4); /********************************************/ return; }