mostly complete

This commit is contained in:
Nicholas Orlowsky 2024-01-31 13:09:58 -06:00
parent 9277a1c3fd
commit b1fa17ffcf
10 changed files with 139 additions and 13 deletions

BIN
5-quirks.ch8 Normal file

Binary file not shown.

BIN
6-keypad.ch8 Normal file

Binary file not shown.

View file

@ -33,13 +33,14 @@ yayacemu [PATH_TO_YOUR_ROM]
- [x] Graphics
- [x] Corax+ Required Instructions
- [x] Proper Flag Handling
- [ ] Working Input
- [ ] More Instructions
- [ ] Tetris Working Running
- [ ] Pass Quirks Test
- [x] Working Input
- [x] More Instructions
- [x] Tetris Working Running
- [x] Pass Quirks Test
- [ ] Add beeper (instead of sound, screen becomes red)
- [ ] Implement a real random module
- [ ] Code cleanup
- [ ] All Instructions
- [x] All Instructions
### Screenshots
@ -47,3 +48,5 @@ yayacemu [PATH_TO_YOUR_ROM]
![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)
![Quirk Test Demo](https://github.com/nickorlow/yayacemu/blob/main/screenshots/quirks.png?raw=true)
![Tetris Demo](https://github.com/nickorlow/yayacemu/blob/main/screenshots/tetris.png?raw=true)

BIN
screenshots/quirks.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

BIN
screenshots/tetris.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5 KiB

BIN
tests/5-quirks.ch8 Normal file

Binary file not shown.

BIN
tests/6-keypad.ch8 Normal file

Binary file not shown.

BIN
tests/tetris.ch8 Normal file

Binary file not shown.

View file

@ -14,7 +14,7 @@
#define SCREEN_WIDTH 64
#define SCREEN_HEIGHT 32
#define EMULATION_HZ 480
#define EMULATION_HZ 4000
FILE *rom_file;
SDL_Window *window;
@ -80,6 +80,59 @@ int get_num() {
return 1;
}
svBitVecVal get_key() {
SDL_Event event;
uint8_t down = 0;
while(SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_KEYDOWN:
down = 128;
case SDL_KEYUP:
switch(event.key.keysym.sym) {
case SDLK_0:
return down | (uint8_t) 0;
case SDLK_1:
return down | (uint8_t) 1;
case SDLK_2:
return down | (uint8_t) 2;
case SDLK_3:
return down | (uint8_t) 3;
case SDLK_4:
return down | (uint8_t) 4;
case SDLK_5:
return down | (uint8_t) 5;
case SDLK_6:
return down | (uint8_t) 6;
case SDLK_7:
return down | (uint8_t) 7;
case SDLK_8:
return down | (uint8_t) 8;
case SDLK_9:
return down | (uint8_t) 9;
case SDLK_a:
return down | (uint8_t) 10;
case SDLK_b:
return down | (uint8_t) 11;
case SDLK_c:
return down | (uint8_t) 12;
case SDLK_d:
return down | (uint8_t) 13;
case SDLK_e:
return down | (uint8_t) 14;
case SDLK_f:
return down | (uint8_t) 15;
default:
return 255;
}
default:
return 255;
}
}
return 255;
}
int main(int argc, char** argv) {
if (argc < 2) {
printf("Use: yayacemu [ROM_NAME]");
@ -90,7 +143,7 @@ int main(int argc, char** argv) {
contextp->commandArgs(argc, argv);
Vyayacemu* top = new Vyayacemu{contextp};
//while (!contextp->gotFinish()) {
for (int i = 0; i < 2000; i++) {
for (int i = 0; ; i++) {
top->clk_in ^= 1;
top->eval();
usleep(1000000/EMULATION_HZ);

View file

@ -10,17 +10,27 @@ module yayacemu (
wire [15:0] stack [0:15];
logic [7:0] delay_timer;
logic [7:0] sound_timer;
bit keyboard [15:0];
int cycle_counter;
bit halt;
int watch_key;
logic [15:0] index_reg;
logic rom_ready;
logic [15:0] program_counter;
keyboard kb(clk_in, keyboard);
rom_loader rl (memory, rom_ready);
chip8_cpu cpu (memory, clk_in, vram, stack, index_reg, stack_pointer, registers, delay_timer, sound_timer, cycle_counter, program_counter);
chip8_cpu cpu (memory, clk_in, keyboard, vram, stack, index_reg, stack_pointer, registers, delay_timer, sound_timer, cycle_counter, program_counter, halt, watch_key);
chip8_gpu gpu (vram);
int i;
initial begin
watch_key = 255;
halt = 0;
for(i = 0; i < 15; i++) begin
keyboard[i] = 0;
end
sound_timer = 0;
delay_timer = 0;
cycle_counter = 0;
@ -31,9 +41,29 @@ module yayacemu (
endmodule
module keyboard (
input wire clk_in,
output bit keyboard [15:0]
);
int i;
import "DPI-C" function bit [7:0] get_key();
bit[7:0] keyval;
always_ff @(posedge clk_in) begin
keyval = get_key();
if (keyval != 8'b11111111) begin
keyboard[keyval[3:0]] = keyval[7];
end
$display("%b", keyval);
for (i = 0; i < 16; i++) begin
$display("%0d %b", i, keyboard[i]);
end
end
endmodule
module chip8_cpu(
output bit [7:0] memory [0:4095],
input wire clk_in,
input wire keyboard [15:0],
output wire [31:0] vram [0:2047],
output wire [15:0] stack [0:15],
output wire [15:0] index_reg,
@ -42,7 +72,9 @@ module chip8_cpu(
output logic [7:0] delay_timer,
output logic [7:0] sound_timer,
output int cycle_counter,
output wire [15:0] program_counter
output wire [15:0] program_counter,
output bit halt,
output int watch_key
);
logic [15:0] opcode;
@ -70,7 +102,7 @@ module chip8_cpu(
$display("HW : PC %0d 0x%h", program_counter, program_counter);
// 480Hz / 8 = 60 Hz
if (cycle_counter % 8 == 0) begin
if (cycle_counter % 20 == 0) begin
if (delay_timer > 0)
delay_timer--;
if (sound_timer > 0)
@ -137,14 +169,17 @@ module chip8_cpu(
'h8??1: begin
$display("HW : INSTR OR Vx, Vy");
registers[(opcode & 'h0F00) >> 8] |= registers[(opcode & 'h00F0) >> 4];
registers[15] = 0;
end
'h8??2: begin
$display("HW : INSTR AND Vx, Vy");
registers[(opcode & 'h0F00) >> 8] &= registers[(opcode & 'h00F0) >> 4];
registers[15] = 0;
end
'h8??3: begin
$display("HW : INSTR XOR Vx, Vy");
registers[(opcode & 'h0F00) >> 8] ^= registers[(opcode & 'h00F0) >> 4];
registers[15] = 0;
end
'h8??4: begin
$display("HW : INSTR ADD Vx, Vy");
@ -200,6 +235,10 @@ module chip8_cpu(
registers[(opcode & 'h0F00) >> 8] = scratch[7:0] & scratch2[7:0];
end
'hD???: begin
if (cycle_counter % 20 != 0) begin
halt = 1;
end else begin
halt = 0;
$display("HW : INSTR DRW Vx, Vy, nibble");
x_cord = {24'h000000, registers[(opcode & 'h0F00) >> 8]};
y_cord = {24'h000000, registers[(opcode & 'h00F0) >> 4]};
@ -213,9 +252,11 @@ module chip8_cpu(
for (r = 0; r < size; r++) begin
for ( c = 0; c < 8; c++) begin
if (r + y_cord >= 32 || x_cord + c >= 64)
continue;
screen_pixel = vram[((r + y_cord) * 64) + (x_cord + c)];
sprite_pixel = memory[{16'h0000, index_reg} + r] & ('h80 >> c);
if (|sprite_pixel) begin
if (screen_pixel == 32'hFFFFFFFF) begin
registers[15] = 1;
@ -225,10 +266,39 @@ module chip8_cpu(
end
end
end
end
'hE?9E: begin
$display("HW : INSTR SKP Vx");
if (keyboard[{registers[(opcode & 'h0F00) >> 8]}[3:0]] == 1) begin
program_counter += 2;
end
end
'hE?A1: begin
$display("HW : INSTR SNE Vx");
if (keyboard[{registers[(opcode & 'h0F00) >> 8]}[3:0]] != 1) begin
program_counter += 2;
end
end
'hF?07: begin
$display("HW : INSTR LD Vx, DT");
registers[(opcode & 'h0F00) >> 8] = delay_timer;
end
'hF?0A: begin
$display("HW : INSTR LD Vx, K");
halt = 1;
for(i = 0; i < 16; i++) begin
if (watch_key == 255) begin
if (keyboard[i]) begin
watch_key = i;
end
end else begin
if (!keyboard[watch_key]) begin
halt = 0;
watch_key = 255;
end
end
end
end
'hF?15: begin
$display("HW : INSTR LD DT, Vx");
delay_timer = registers[(opcode & 'h0F00) >> 8];
@ -273,8 +343,8 @@ module chip8_cpu(
end
default: $display("HW : ILLEGAL INSTRUCTION");
endcase
program_counter += 2;
if (!halt)
program_counter += 2;
cycle_counter++;
end
endmodule