flag handling

This commit is contained in:
Nicholas Orlowsky 2024-01-31 12:05:04 -06:00
parent 4c8a4a7ddf
commit 9277a1c3fd
5 changed files with 104 additions and 39 deletions

View file

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

BIN
tests/4-flags.ch8 Normal file

Binary file not shown.

View file

@ -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);

View file

@ -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]};
@ -175,6 +225,22 @@ module chip8_cpu(
end
end
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]};
@ -205,14 +271,11 @@ module chip8_cpu(
end
index_reg++;
end
'hF?1E: begin
$display("HW : INSTR ADD I, Vx");
index_reg = index_reg + {8'h00, registers[(opcode & 'h0F00) >> 8]};
end
default: $display("HW : ILLEGAL INSTRUCTION");
endcase
program_counter += 2;
cycle_counter++;
end
endmodule