diff --git a/source/app.d b/source/app.d index 7e61b5b..26643ba 100644 --- a/source/app.d +++ b/source/app.d @@ -466,7 +466,8 @@ struct Chip8Status { igText("OpCode: 0x%04X", emu_.cpu.opcode); igText("PC:"); igSameLine(); - igDragInt("##pc", cast(int*)&emu_.cpu.pc, 0.5f, 0, emu_.ram.length); + igText("pc: 0x%04X (%hu)", emu_.cpu.pc, emu_.cpu.pc); + // igDragInt("##pc", cast(int*)&emu_.cpu.pc, 0.5f, 0, emu_.ram.length); igText("Registers (v0 - vF)"); igColumns(4, null, false); @@ -629,9 +630,9 @@ struct Chip8 { void step() { cpu.opcode = ram[cpu.pc] << 8 | ram[cpu.pc + 1]; - auto pc_target = cast(ProgramCounter)(cpu.pc + 2); + ushort pc_target = cast(ProgramCounter)(cpu.pc + 2u); - writefln("opcode: 0x%X", cpu.opcode); + // writefln("opcode: 0x%X, pc: 0x%X : %d", cpu.opcode, cpu.pc, cpu.pc); switch (cpu.opcode & 0xF000) with (cpu) { @@ -669,7 +670,7 @@ struct Chip8 { case 0x3000: // 0x3XNN Skips the next instruction if VX equals NN. if (cpu.v[cpu.opcode.x] == (cpu.opcode.nn)) { - pc_target += 2; + pc_target += 2u; } break; @@ -677,7 +678,7 @@ struct Chip8 { case 0x4000: // 0x4XNN Skips the next instruction if VX doesn't equal NN. if (cpu.v[cpu.opcode.x] != (cpu.opcode.nn)) { - pc_target += 2; + pc_target += 2u; } break; @@ -685,13 +686,12 @@ struct Chip8 { case 0x5000: // 0x5XYO Skips the next instruction if VX equals VY. if (cpu.v[cpu.opcode.x] == cpu.v[cpu.opcode.y]) { - pc_target += 2; + pc_target += 2u; } break; case 0x6000: // 0x6XNN Sets VX to NN. - writefln("%d, %d", cpu.opcode.x, cpu.opcode & 0x00FF); cpu.v[cpu.opcode.x] = cpu.opcode.nn; break; @@ -701,8 +701,8 @@ struct Chip8 { case 0x8000: - auto x = cpu.opcode.x; - auto y = cpu.opcode.y; + ubyte x = cpu.opcode.x; + ubyte y = cpu.opcode.y; switch (cpu.opcode.n) { @@ -723,8 +723,8 @@ struct Chip8 { break; case 0x0004: // 0x8XY4 Adds VY to VX. VF is set to 1 when there's a carry, and to 0 when there isn't. - auto vx = cpu.v[x]; - auto vy = cpu.v[y]; + ubyte vx = cpu.v[x]; + ubyte vy = cpu.v[y]; if (cast(ushort)vx + cast(ushort)vy > 255) { cpu.v[0xF] = 1; } else { @@ -734,8 +734,8 @@ struct Chip8 { break; case 0x0005: // 0x8XY5 VY is subtracted from VX. VF is set to 0 when there's a borrow, and 1 when there isn't. - auto vx = cpu.v[x]; - auto vy = cpu.v[y]; + ubyte vx = cpu.v[x]; + ubyte vy = cpu.v[y]; if (vx > vy) { cpu.v[0xF] = 1; } else { @@ -746,26 +746,26 @@ struct Chip8 { case 0x0006: // 0x8XY6 Shifts VX right by one. VF is set to the value of the least significant bit of VX before the shift. - auto vx = cpu.v[x]; - cpu.v[0xF] = (vx & 0b10000000) >> 7; + ubyte vx = cpu.v[x]; + cpu.v[0xF] = vx & 0x1; cpu.v[x] >>= 1; break; case 0x0007: // 0x8XY7 Sets VX to VY minus VX. VF is set to 0 when there's a borrow, and 1 when there isn't. - auto vx = cpu.v[x]; - auto vy = cpu.v[y]; + ubyte vx = cpu.v[x]; + ubyte vy = cpu.v[y]; if (vy > vx) { cpu.v[0xF] = 1; } else { cpu.v[0xF] = 0; } - cpu.v[x] = cast(Register)(vy - vx); // TODO borrow flag + cpu.v[x] = cast(Register)(vy - vx); break; case 0x000E: // 0x8XYE Shifts VX left by one. VF is set to the value of the most significant bit of VX before the shift. - auto vx = cpu.v[x]; - cpu.v[0xF] = (vx & 0b10000000) >> 7; + ubyte vx = cpu.v[x]; + cpu.v[0xF] = vx >> 7; cpu.v[x] <<= 1; break; @@ -780,7 +780,7 @@ struct Chip8 { case 0x9000: // 0x9XYO Skips the next instruction if VX doesn't equal VY. if (cpu.v[cpu.opcode.x] != cpu.v[cpu.opcode.y]) { - pc_target += 2; // do skip yes + pc_target += 2u; // do skip yes } break; @@ -796,7 +796,7 @@ struct Chip8 { case 0xC000: // 0xCXNN Sets VX to the result of a bitwise and operation on a random number and NN. import std.random : uniform; - auto x = cpu.opcode.x; + ubyte x = cpu.opcode.x; cpu.v[x] = uniform(Register.min, Register.max) & (cpu.opcode & 0x00FF); break; @@ -808,29 +808,25 @@ struct Chip8 { // If N is greater than 1, second line continues at position VX, VY+1, and so on. case 0xD000: - auto spr_addr = cpu.i; - auto x = cpu.opcode.x; - auto y = cpu.opcode.y; - auto n = cpu.opcode.n; + ProgramCounter spr_addr = cpu.i; + ubyte x = cpu.opcode.x; + ubyte y = cpu.opcode.y; + ubyte n = cpu.opcode.n; foreach(int row; 0 .. n) { ushort pixel = ram[spr_addr + row]; foreach (int col; 0 .. 8) { - if ((pixel & 0x80) > 0) { - auto x_off = (x + col) % 64; - auto y_off = (y + row) % 32; - auto offset = x_off + (y_off * 64); + if ((pixel & (0x80 >> col)) != 0) { + ubyte x_off = cast(ubyte)((x + col) % 64); + ubyte y_off = cast(ubyte)((y + row) % 32); + ushort offset = x_off + (y_off * 64); if (screen_buf[offset] == 1) { cpu.v[0xF] = 1; - } else { - cpu.v[0xF] = 0; } screen_buf[offset] ^= 1; - writefln("write to offset: %d", offset); } - pixel <<= 1; } } @@ -841,8 +837,8 @@ struct Chip8 { case 0xE000: - auto x = cpu.opcode.x; - auto key = cpu.v[x]; + ubyte x = cpu.opcode.x; + ubyte key = cpu.v[x]; switch (cpu.opcode & 0x000F) { @@ -883,13 +879,19 @@ struct Chip8 { break; case 0x001E: // 0xFX1E Adds VX to I. + if (cpu.i + cpu.v[cpu.opcode.x] > 0xFF) { + cpu.v[0xF] = 1; + } else { + cpu.v[0xF] = 0; + } cpu.i += cpu.v[cpu.opcode.x]; break; case 0x0029: // 0xFX29 Sets I to the location of the sprite for the character in VX. - auto vx = cpu.v[cpu.opcode.x]; - ushort char_addr = 0x200 + (vx * 40); // base of char sprites + value of vx * bits per character + ubyte vx = cpu.v[cpu.opcode.x]; + // ushort char_addr = 0x200 + (vx * 40); // base of char sprites + value of vx * bits per character + ushort char_addr = vx * 0x5; cpu.i = char_addr; break; @@ -898,7 +900,7 @@ struct Chip8 { // the middle digit at I plus 1, and the least significant digit at I plus 2. case 0x0033: - auto vx = cpu.v[cpu.opcode.x]; + ubyte vx = cpu.v[cpu.opcode.x]; ram[cpu.i] = vx / 100; ram[cpu.i + 1] = (vx / 10) % 10; ram[cpu.i + 2] = (vx % 100) % 10; @@ -906,7 +908,7 @@ struct Chip8 { case 0x0055: // 0xFX55 Stores V0 to VX in memory starting at address I. - auto addr = cpu.i; + IndexRegister addr = cpu.i; foreach (reg; cpu.v) { ram[addr++] = reg; } @@ -915,7 +917,7 @@ struct Chip8 { case 0x0065: // 0xFX65 Fills V0 to VX with values from memory starting at address I. - auto addr = cpu.i; + IndexRegister addr = cpu.i; foreach (ref reg; cpu.v) { reg = ram[addr++]; }