nyeh
This commit is contained in:
		
							parent
							
								
									4d8fc5814b
								
							
						
					
					
						commit
						5be7d9ce1a
					
				
							
								
								
									
										84
									
								
								source/app.d
								
								
								
								
							
							
						
						
									
										84
									
								
								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++];
 | 
			
		||||
						}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue