diff --git a/src/chip8.v b/src/chip8.v index 1ec5ad3..7532d1d 100644 --- a/src/chip8.v +++ b/src/chip8.v @@ -63,6 +63,7 @@ const num_of_registers = 16 const f = 15 struct Chip8{ + cpu_clock u8 = 9 pub mut: ram [mem_size]u8 v [num_of_registers]u8 @@ -74,6 +75,7 @@ struct Chip8{ sound_timer u8 is_draw bool key u8 + cycles u8 } fn (mut chip Chip8) start_cpu(){ @@ -202,7 +204,7 @@ fn (mut chip Chip8) decode_and_run(instruction u16) { } 0x6000 { - x = (instruction & 0xF00) >> 8 + x = (instruction & 0x0F00) >> 8 nn = instruction & 0x00FF chip.v[x] = u8(nn) @@ -210,7 +212,7 @@ fn (mut chip Chip8) decode_and_run(instruction u16) { } 0x7000 { - x = (instruction & 0xF00) >> 8 + x = (instruction & 0x0F00) >> 8 nn = instruction & 0x00FF chip.v[x] += u8(nn) @@ -253,25 +255,30 @@ fn (mut chip Chip8) decode_and_run(instruction u16) { chip.v[f] = 0 } - chip.v[x] = xy + chip.v[x] = (xy & 0xFF) // Adds VY to VX. VF is set to 1 when there's an overflow, and to 0 when there is not. } 0x05 { - xy := chip.v[x] - chip.v[y] - if chip.v[x] >= chip.v[y] { + if chip.v[x] > chip.v[y] { chip.v[f] = 1 }else{ chip.v[f] = 0 } - chip.v[x] = xy + chip.v[x] -= chip.v[y] // VY is subtracted from VX. VF is set to 0 when there's an underflow, and 1 when there is not. (i.e. VF set to 1 if VX >= VY and 0 if not) } 0x06 { - chip.v[f] = (chip.v[x] & 0xF0) >> 7 + if chip.v[x] % 2 == 1 { + chip.v[f] = 1; + } + else { + chip.v[f] = 0; + } + chip.v[x] = chip.v[x] >> 1 // Stores the least significant bit of VX in VF and then shifts VX to the right by 1 } @@ -280,7 +287,7 @@ fn (mut chip Chip8) decode_and_run(instruction u16) { xy := chip.v[y] - chip.v[x] - if chip.v[y] >= chip.v[x] { + if chip.v[y] > chip.v[x] { chip.v[f] = 1 }else{ chip.v[f] = 0 @@ -292,9 +299,14 @@ fn (mut chip Chip8) decode_and_run(instruction u16) { 0x0E { - chip.v[f] = (chip.v[x] & 0xF0) >> 7 + if (chip.v[x] & 10000000) == 1 { + chip.v[f] = 1; + } + else { + chip.v[f] = 0; + } - chip.v[x] = chip.v[x] >> 1 + chip.v[x] = chip.v[x] << 1 // Stores the most significant bit of VX in VF and then shifts VX to the left by 1. } @@ -341,8 +353,8 @@ fn (mut chip Chip8) decode_and_run(instruction u16) { y = (instruction & 0x00F0) >> 4 n = (instruction & 0x000F) - mut regvy := u16(chip.v[y] % chip.screen.display_height) - mut regvx := u16(chip.v[x] % chip.screen.display_width) + mut regvy := u16(chip.v[y]) + mut regvx := u16(chip.v[x]) chip.v[f] = 0 @@ -406,35 +418,36 @@ fn (mut chip Chip8) decode_and_run(instruction u16) { 0x18{ chip.sound_timer = chip.v[x] - } + } 0x1E{ chip.i += chip.v[x] } 0x29{ - chip.i = chip.v[x] * 5 + chip.i = u16(chip.v[x] * 0x5) } 0x33{ - chip.ram[chip.i] = chip.v[x] / 100; - chip.ram[chip.i + 1] = (chip.v[x] / 10) % 10 - chip.ram[chip.i + 2] = chip.v[x] % 10; + + chip.ram[chip.i] = u8(chip.v[x] / 100) + chip.ram[chip.i + 1] = u8((u8(chip.v[x] / 10)) % 10) + chip.ram[chip.i + 2] = u8(chip.v[x] % 100) % 10 } 0x55{ - for i := 0; i <= x; i++ { + for i := chip.v[0]; i <= x; i++ { chip.ram[chip.i + i] = chip.v[i] } - chip.i = u16(chip.i + x + 1) + chip.i = u16(x + 1) } 0x65{ - for i := 0; i <= x; i++ { - chip.v[x] = chip.ram[chip.i + x] + for i := chip.v[0]; i <= x; i++ { + chip.v[x] = chip.ram[chip.i + i] } - chip.i = u16(chip.i + x + 1) + chip.i = u16(x + 1) } else { @@ -450,6 +463,10 @@ fn (mut chip Chip8) decode_and_run(instruction u16) { if !is_jump { chip.pc += 2 } } +fn (mut chip Chip8) update_timers(){ + if chip.delay_timer > 0 { chip.delay_timer-- } + if chip.sound_timer > 0 { chip.sound_timer-- } +} fn (mut chip Chip8) set_key(key int){ chip.key = u8(keyboard[key]) diff --git a/src/main.v b/src/main.v index 94f60f7..a4ba043 100644 --- a/src/main.v +++ b/src/main.v @@ -13,7 +13,7 @@ struct Emulator{ } fn (mut emulator Emulator) draw_block(i f32, j f32) { - emulator.graphic.draw_rect_filled(j,i, f32(20-1), f32(20-1), gx.rgb(0,255,0)) + emulator.graphic.draw_rect_filled(j,i, f32(20), f32(20), gx.rgb(0,255,0)) } fn (mut emulator Emulator) load_rom() !{ @@ -44,20 +44,27 @@ fn frame(mut emulator Emulator){ emulator.graphic.begin() emulator.chip8.run() - + emulator.chip8.cycles++; + emulator.chip8.update_timers() + display_height := emulator.chip8.screen.display_height display_width := emulator.chip8.screen.display_width - + for y := 0; y < display_height; y++ { for x := 0; x < display_width; x++ { pixel := emulator.chip8.screen.display[y][x] if pixel == 1 { - emulator.draw_block(f32((y-1)*20), f32((x-1)*20)) + emulator.draw_block(f32((y)*20), f32((x)*20)) } } } + + if emulator.chip8.cpu_clock == emulator.chip8.cycles { + emulator.chip8.cycles = 0 + } + emulator.graphic.end() } @@ -65,80 +72,6 @@ fn (mut emulator Emulator) show_display(){ emulator.graphic.run() } -//fn (emulator Emulator) keyboard(input string) !string{ -// -// match input { -// '1' { -// return 0x0001 -// }, -// -// '2' { -// -// }, -// -// '3' { -// -// }, -// -// '4' { -// -// }, -// -// 'Q', 'q' { -// -// }, -// -// 'W', 'w' { -// -// }, -// -// 'E', 'e' { -// -// }, -// -// 'R', 'r' { -// -// }, -// -// 'A', 'a' { -// -// }, -// -// 'S', 's' { -// -// }, -// -// 'D', 'd' { -// -// }, -// -// 'F', 'f' { -// -// }, -// -// 'Z', 'z' { -// -// }, -// -// 'X', 'x' { -// -// }, -// -// 'C', 'c' { -// -// }, -// -// 'V', 'v' { -// -// }, -// -// else { -// panic('Invalid key!') -// } -// } -// -//} - fn is_graphic() bool{ return os.environ()['DISPLAY'] != '' }