mostly complete
This commit is contained in:
parent
9277a1c3fd
commit
b1fa17ffcf
BIN
5-quirks.ch8
Normal file
BIN
5-quirks.ch8
Normal file
Binary file not shown.
BIN
6-keypad.ch8
Normal file
BIN
6-keypad.ch8
Normal file
Binary file not shown.
13
README.md
13
README.md
|
@ -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
BIN
screenshots/quirks.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.8 KiB |
BIN
screenshots/tetris.png
Normal file
BIN
screenshots/tetris.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5 KiB |
BIN
tests/5-quirks.ch8
Normal file
BIN
tests/5-quirks.ch8
Normal file
Binary file not shown.
BIN
tests/6-keypad.ch8
Normal file
BIN
tests/6-keypad.ch8
Normal file
Binary file not shown.
BIN
tests/tetris.ch8
Normal file
BIN
tests/tetris.ch8
Normal file
Binary file not shown.
57
yayacemu.cpp
57
yayacemu.cpp
|
@ -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);
|
||||
|
|
80
yayacemu.sv
80
yayacemu.sv
|
@ -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,6 +252,8 @@ 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);
|
||||
|
||||
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue