flag handling
This commit is contained in:
parent
4c8a4a7ddf
commit
9277a1c3fd
|
@ -32,7 +32,7 @@ yayacemu [PATH_TO_YOUR_ROM]
|
|||
### Todo
|
||||
- [x] Graphics
|
||||
- [x] Corax+ Required Instructions
|
||||
- [ ] Proper Flag Handling
|
||||
- [x] Proper Flag Handling
|
||||
- [ ] Working Input
|
||||
- [ ] More Instructions
|
||||
- [ ] Tetris Working Running
|
||||
|
@ -46,3 +46,4 @@ yayacemu [PATH_TO_YOUR_ROM]
|
|||
![Chip 8 Logo Demo](https://github.com/nickorlow/yayacemu/blob/main/screenshots/chip8-logo.png?raw=true)
|
||||
![IBM Logo Demo](https://github.com/nickorlow/yayacemu/blob/main/screenshots/ibm-logo.png?raw=true)
|
||||
![CORAX+ Test Demo](https://github.com/nickorlow/yayacemu/blob/main/screenshots/corax.png?raw=true)
|
||||
![Flag Test Demo](https://github.com/nickorlow/yayacemu/blob/main/screenshots/flags.png?raw=true)
|
||||
|
|
BIN
screenshots/flags.png
Normal file
BIN
screenshots/flags.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.7 KiB |
BIN
tests/4-flags.ch8
Normal file
BIN
tests/4-flags.ch8
Normal file
Binary file not shown.
|
@ -14,6 +14,7 @@
|
|||
|
||||
#define SCREEN_WIDTH 64
|
||||
#define SCREEN_HEIGHT 32
|
||||
#define EMULATION_HZ 480
|
||||
|
||||
FILE *rom_file;
|
||||
SDL_Window *window;
|
||||
|
@ -89,10 +90,10 @@ int main(int argc, char** argv) {
|
|||
contextp->commandArgs(argc, argv);
|
||||
Vyayacemu* top = new Vyayacemu{contextp};
|
||||
//while (!contextp->gotFinish()) {
|
||||
for (int i = 0; i < 20000; i++) {
|
||||
for (int i = 0; i < 2000; i++) {
|
||||
top->clk_in ^= 1;
|
||||
top->eval();
|
||||
usleep(500);
|
||||
usleep(1000000/EMULATION_HZ);
|
||||
}
|
||||
printf("TB : Testbench has reached end of simulation. Pausing for 10 seconds before exiting");
|
||||
fflush(stdout);
|
||||
|
|
131
yayacemu.sv
131
yayacemu.sv
|
@ -8,16 +8,22 @@ module yayacemu (
|
|||
wire [7:0] registers [0:15];
|
||||
logic [3:0] stack_pointer;
|
||||
wire [15:0] stack [0:15];
|
||||
logic [7:0] delay_timer;
|
||||
logic [7:0] sound_timer;
|
||||
int cycle_counter;
|
||||
|
||||
logic [15:0] index_reg;
|
||||
logic rom_ready;
|
||||
logic [15:0] program_counter;
|
||||
|
||||
rom_loader rl (memory, rom_ready);
|
||||
chip8_cpu cpu (memory, clk_in, vram, stack, index_reg, stack_pointer, registers, program_counter);
|
||||
chip8_cpu cpu (memory, clk_in, vram, stack, index_reg, stack_pointer, registers, delay_timer, sound_timer, cycle_counter, program_counter);
|
||||
chip8_gpu gpu (vram);
|
||||
|
||||
initial begin
|
||||
sound_timer = 0;
|
||||
delay_timer = 0;
|
||||
cycle_counter = 0;
|
||||
program_counter = 'h200;
|
||||
stack_pointer = 4'b0000;
|
||||
init_screen();
|
||||
|
@ -33,13 +39,20 @@ module chip8_cpu(
|
|||
output wire [15:0] index_reg,
|
||||
output wire [3:0] stack_pointer,
|
||||
output wire [7:0] registers [0:15],
|
||||
output logic [7:0] delay_timer,
|
||||
output logic [7:0] sound_timer,
|
||||
output int cycle_counter,
|
||||
output wire [15:0] program_counter
|
||||
);
|
||||
|
||||
logic [15:0] opcode;
|
||||
|
||||
logic [15:0] scratch;
|
||||
logic [15:0] scratch2;
|
||||
|
||||
logic [7:0] scratch_8;
|
||||
logic [7:0] scratch_82;
|
||||
|
||||
logic [31:0] x_cord;
|
||||
logic [31:0] y_cord;
|
||||
logic [7:0] size;
|
||||
|
@ -56,6 +69,14 @@ module chip8_cpu(
|
|||
$display("HW : opcode is 0x%h (%b)", opcode, opcode);
|
||||
$display("HW : PC %0d 0x%h", program_counter, program_counter);
|
||||
|
||||
// 480Hz / 8 = 60 Hz
|
||||
if (cycle_counter % 8 == 0) begin
|
||||
if (delay_timer > 0)
|
||||
delay_timer--;
|
||||
if (sound_timer > 0)
|
||||
sound_timer--;
|
||||
end
|
||||
|
||||
casez(opcode)
|
||||
'h00E0: begin
|
||||
$display("HW : INSTR CLS");
|
||||
|
@ -127,28 +148,57 @@ module chip8_cpu(
|
|||
end
|
||||
'h8??4: begin
|
||||
$display("HW : INSTR ADD Vx, Vy");
|
||||
scratch_8 = registers[(opcode & 'h0F00) >> 8];
|
||||
registers[(opcode & 'h0F00) >> 8] += registers[(opcode & 'h00F0) >> 4];
|
||||
registers[15] = {7'b0000000, scratch_8 > registers[(opcode & 'h0F00) >> 8]};
|
||||
end
|
||||
'h8??5: begin
|
||||
$display("HW : INSTR SUB Vx, Vy");
|
||||
scratch_8 = registers[(opcode & 'h0F00) >> 8];
|
||||
registers[(opcode & 'h0F00) >> 8] -= registers[(opcode & 'h00F0) >> 4];
|
||||
registers[15] = {7'b0000000, scratch_8 >= registers[(opcode & 'h0F00) >> 8]};
|
||||
end
|
||||
'h8??6: begin
|
||||
$display("HW : INSTR SHR Vx {, Vy}");
|
||||
scratch_8 = registers[(opcode & 'h0F00) >> 8];
|
||||
registers[(opcode & 'h0F00) >> 8] = registers[(opcode & 'h00F0) >> 4]>> 1;
|
||||
registers[15] = {7'b0000000, ((scratch_8 & 8'h01) == 8'h01)};
|
||||
end
|
||||
'h8??7: begin
|
||||
$display("HW : INSTR SUBN Vx, Vy");
|
||||
scratch_8 = registers[(opcode & 'h00F0) >> 4];
|
||||
scratch_82 = registers[(opcode & 'h0F00) >> 8];
|
||||
registers[(opcode & 'h0F00) >> 8] = registers[(opcode & 'h00F0) >> 4] - registers[(opcode & 'h0F00) >> 8];
|
||||
registers[15] = {7'b0000000, (scratch_8 >= scratch_82)};
|
||||
end
|
||||
'h8??E: begin
|
||||
$display("HW : INSTR SHL Vx {, Vy}");
|
||||
scratch_8 = registers[(opcode & 'h0F00) >> 8];
|
||||
registers[(opcode & 'h0F00) >> 8] = registers[(opcode & 'h00F0) >> 4]<< 1;
|
||||
|
||||
registers[15] = {7'b0000000, (scratch_8[7]) };
|
||||
end
|
||||
'h9??0: begin
|
||||
$display("HW : INSTR SNE Vx, Vy");
|
||||
if (registers[(opcode & 'h00F0) >> 4] != registers[(opcode & 'h0F00) >> 8]) begin
|
||||
program_counter += 2;
|
||||
end
|
||||
end
|
||||
'hA???: begin
|
||||
$display("HW : INSTR LD I, addr");
|
||||
index_reg = (opcode & 'h0FFF);
|
||||
end
|
||||
'hb???: begin
|
||||
$display("HW : INSTR JP V0, addr");
|
||||
program_counter = {8'h00, registers[0]} + (opcode & 'h0FFF) - 2;
|
||||
end
|
||||
'hc???: begin
|
||||
$display("HW : RND Vx, addr");
|
||||
// TODO: use a real RNG module, this is not synthesizeable
|
||||
scratch = {$urandom()%256}[15:0];
|
||||
scratch2 = (opcode & 'h00FF);
|
||||
registers[(opcode & 'h0F00) >> 8] = scratch[7:0] & scratch2[7:0];
|
||||
end
|
||||
'hD???: begin
|
||||
$display("HW : INSTR DRW Vx, Vy, nibble");
|
||||
x_cord = {24'h000000, registers[(opcode & 'h0F00) >> 8]};
|
||||
|
@ -174,45 +224,58 @@ module chip8_cpu(
|
|||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
'hF?33: begin
|
||||
$display("HW : INSTR LD B, Vx");
|
||||
scratch = {8'h00, registers[(opcode & 'h0F00) >> 8]};
|
||||
scratch2 = scratch % 10;
|
||||
memory[index_reg + 2] = scratch2[7:0];
|
||||
scratch /= 10;
|
||||
scratch2 = scratch % 10;
|
||||
memory[index_reg + 1] = scratch2[7:0];
|
||||
scratch /= 10;
|
||||
scratch2 = scratch % 10;
|
||||
memory[index_reg + 0] = scratch2[7:0];
|
||||
end
|
||||
'hF?07: begin
|
||||
$display("HW : INSTR LD Vx, DT");
|
||||
registers[(opcode & 'h0F00) >> 8] = delay_timer;
|
||||
end
|
||||
'hF?15: begin
|
||||
$display("HW : INSTR LD DT, Vx");
|
||||
delay_timer = registers[(opcode & 'h0F00) >> 8];
|
||||
end
|
||||
'hF?18: begin
|
||||
$display("HW : INSTR LD ST, Vx");
|
||||
sound_timer = registers[(opcode & 'h0F00) >> 8];
|
||||
end
|
||||
'hF?1E: begin
|
||||
$display("HW : INSTR ADD I, Vx");
|
||||
index_reg = index_reg + {8'h00, registers[(opcode & 'h0F00) >> 8]};
|
||||
end
|
||||
'hF?33: begin
|
||||
$display("HW : INSTR LD B, Vx");
|
||||
scratch = {8'h00, registers[(opcode & 'h0F00) >> 8]};
|
||||
scratch2 = scratch % 10;
|
||||
memory[index_reg + 2] = scratch2[7:0];
|
||||
scratch /= 10;
|
||||
scratch2 = scratch % 10;
|
||||
memory[index_reg + 1] = scratch2[7:0];
|
||||
scratch /= 10;
|
||||
scratch2 = scratch % 10;
|
||||
memory[index_reg + 0] = scratch2[7:0];
|
||||
end
|
||||
'hF?55: begin
|
||||
$display("HW : INSTR LD [I], Vx");
|
||||
scratch = (opcode & 'h0F00) >> 8;
|
||||
for (i8 = 0; i8 <= scratch[7:0]; i8++) begin
|
||||
scratch2 = index_reg + {8'h00, i8};
|
||||
memory[scratch2[11:0]] = registers[i8[3:0]];
|
||||
end
|
||||
'hF?55: begin
|
||||
$display("HW : INSTR LD [I], Vx");
|
||||
scratch = (opcode & 'h0F00) >> 8;
|
||||
for (i8 = 0; i8 <= scratch[7:0]; i8++) begin
|
||||
scratch2 = index_reg + {8'h00, i8};
|
||||
memory[scratch2[11:0]] = registers[i8[3:0]];
|
||||
end
|
||||
index_reg++;
|
||||
end
|
||||
'hF?65: begin
|
||||
$display("HW : INSTR LD Vx, [I]");
|
||||
scratch = (opcode & 'h0F00) >> 8;
|
||||
for (i8 = 0; i8 <= scratch[7:0]; i8++) begin
|
||||
scratch2 = index_reg + {8'h00, i8};
|
||||
registers[i8[3:0]] = memory[scratch2[11:0]];
|
||||
end
|
||||
index_reg++;
|
||||
end
|
||||
'hF?1E: begin
|
||||
$display("HW : INSTR ADD I, Vx");
|
||||
index_reg = index_reg + {8'h00, registers[(opcode & 'h0F00) >> 8]};
|
||||
index_reg++;
|
||||
end
|
||||
'hF?65: begin
|
||||
$display("HW : INSTR LD Vx, [I]");
|
||||
scratch = (opcode & 'h0F00) >> 8;
|
||||
for (i8 = 0; i8 <= scratch[7:0]; i8++) begin
|
||||
scratch2 = index_reg + {8'h00, i8};
|
||||
registers[i8[3:0]] = memory[scratch2[11:0]];
|
||||
end
|
||||
index_reg++;
|
||||
end
|
||||
default: $display("HW : ILLEGAL INSTRUCTION");
|
||||
endcase
|
||||
|
||||
program_counter += 2;
|
||||
cycle_counter++;
|
||||
end
|
||||
endmodule
|
||||
|
||||
|
|
Loading…
Reference in a new issue