Compare commits
2 Commits
f3d3310965
...
0424fa56b1
| Author | SHA1 | Date |
|---|---|---|
|
|
0424fa56b1 | |
|
|
961212808d |
236
src/chip8.v
236
src/chip8.v
|
|
@ -1,37 +1,25 @@
|
|||
import rand
|
||||
|
||||
const keyboard := {
|
||||
0x1 : 0x1 //1 - 1
|
||||
0x2 : 0x2 //2 - 2
|
||||
0x3 : 0x3 //3 - 3
|
||||
0x4 : 0x43 //4 - C
|
||||
0x51 : 0x4 //Q - 4
|
||||
0x71 : 0x4 //q - 4
|
||||
0x57 : 0x5 //W - 5
|
||||
0x77 : 0x5 //w - 5
|
||||
0x45 : 0x6 //E - 6
|
||||
0x65 : 0x6 //e - 6
|
||||
0x52 : 0x44 //R - D
|
||||
0x72 : 0x44 //r - D
|
||||
0x41 : 0x7 //A - 7
|
||||
0x61 : 0x7 //a - 7
|
||||
0x53 : 0x8 //S - 8
|
||||
0x73 : 0x8 //s - 8
|
||||
0x44 : 0x9 //D - 9
|
||||
0x64 : 0x9 //d - 9
|
||||
0x46 : 0x45 //F - E
|
||||
0x66 : 0x45 //f - E
|
||||
0x5A : 0x41 //Z - A
|
||||
0x7A : 0x41 //z - A
|
||||
0x58 : 0x30 //X - 0
|
||||
0x78 : 0x30 //x - 0
|
||||
0x43 : 0x42 //C - B
|
||||
0x63 : 0x42 //c - B
|
||||
0x56 : 0x46 //V - F
|
||||
0x76 : 0x46 //v - F
|
||||
const keyboard = {
|
||||
0x31: 0x01 // keycode 1 - 1
|
||||
0x32: 0x02 // keycode 2 - 2
|
||||
0x33: 0x03 // keycode 3 - 3
|
||||
0x34: 0x0C // keycode 4 - C
|
||||
0x51: 0x04 // keycode Q - 4
|
||||
0x57: 0x05 // keycode W - 5
|
||||
0x45: 0x06 // keycode E - 6
|
||||
0x52: 0x0D // keycode R - D
|
||||
0x41: 0x07 // keycode A - 7
|
||||
0x53: 0x08 // keycode S - 8
|
||||
0x44: 0x09 // keycode D - 9
|
||||
0x46: 0x0E // keycode F - E
|
||||
0x5A: 0x0A // keycode Z - A
|
||||
0x58: 0x00 // keycode X - 0
|
||||
0x43: 0x0B // keycode C - B
|
||||
0x56: 0x0F // keycode V - F
|
||||
}
|
||||
|
||||
const font := [
|
||||
const font = [
|
||||
[u8(0xF0), u8(0x90), u8(0x90), u8(0x90), u8(0xF0)], // 0
|
||||
[u8(0x20), u8(0x60), u8(0x20), u8(0x20), u8(0x70)], // 1
|
||||
[u8(0xF0), u8(0x10), u8(0xF0), u8(0x80), u8(0xF0)], // 2
|
||||
|
|
@ -50,11 +38,11 @@ const font := [
|
|||
[u8(0xF0), u8(0x80), u8(0xF0), u8(0x80), u8(0x80)], // F
|
||||
]
|
||||
|
||||
struct Screen{
|
||||
pub:
|
||||
struct Screen {
|
||||
pub:
|
||||
display_width int = 64
|
||||
display_height int = 32
|
||||
mut:
|
||||
mut:
|
||||
display [32][64]u8
|
||||
}
|
||||
|
||||
|
|
@ -62,9 +50,9 @@ const mem_size = 4096
|
|||
const num_of_registers = 16
|
||||
const f = 15
|
||||
|
||||
struct Chip8{
|
||||
struct Chip8 {
|
||||
cpu_clock u8 = 9
|
||||
pub mut:
|
||||
pub mut:
|
||||
ram [mem_size]u8
|
||||
v [num_of_registers]u8
|
||||
screen Screen
|
||||
|
|
@ -78,8 +66,7 @@ struct Chip8{
|
|||
cycles u8
|
||||
}
|
||||
|
||||
fn (mut chip Chip8) start_cpu(){
|
||||
|
||||
fn (mut chip Chip8) start_cpu() {
|
||||
chip.screen = Screen{}
|
||||
|
||||
// load font in the memory
|
||||
|
|
@ -88,39 +75,33 @@ fn (mut chip Chip8) start_cpu(){
|
|||
}
|
||||
}
|
||||
|
||||
fn (mut chip Chip8) run(){
|
||||
fn (mut chip Chip8) run() {
|
||||
mut instruction := chip.fetch()
|
||||
chip.decode_and_run(instruction)
|
||||
}
|
||||
|
||||
|
||||
@[direct_array_access]
|
||||
fn (mut chip Chip8) set_ram(instructions []u8, index u16) {
|
||||
|
||||
mut j := index
|
||||
|
||||
for i := 0; i < instructions.len; i++ {
|
||||
chip.ram[j] = instructions[i]
|
||||
j++
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut chip Chip8) fetch() u16{
|
||||
|
||||
@[direct_array_access]
|
||||
fn (mut chip Chip8) fetch() u16 {
|
||||
mut instruction := u16(0x00)
|
||||
|
||||
mut half_instruction := chip.ram[chip.pc]
|
||||
|
||||
instruction = instruction | half_instruction
|
||||
instruction = instruction << 8
|
||||
half_instruction = chip.ram[chip.pc + 1]
|
||||
|
||||
instruction = instruction | half_instruction
|
||||
|
||||
return instruction
|
||||
}
|
||||
|
||||
@[direct_array_access]
|
||||
fn (mut chip Chip8) decode_and_run(instruction u16) {
|
||||
|
||||
mut nnn, mut nn, mut n, mut x, mut y := 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
|
||||
mut opcode_msb := instruction & 0xF000
|
||||
|
|
@ -128,49 +109,45 @@ fn (mut chip Chip8) decode_and_run(instruction u16) {
|
|||
mut is_jump := false
|
||||
chip.is_draw = false
|
||||
|
||||
if chip.delay_timer > 0 { chip.delay_timer-- }
|
||||
if chip.sound_timer > 0 { chip.sound_timer-- }
|
||||
|
||||
match opcode_msb{
|
||||
if chip.delay_timer > 0 {
|
||||
chip.delay_timer--
|
||||
}
|
||||
if chip.sound_timer > 0 {
|
||||
chip.sound_timer--
|
||||
}
|
||||
|
||||
match opcode_msb {
|
||||
0x0000 {
|
||||
|
||||
match opcode_lsb {
|
||||
0xEE {
|
||||
chip.pc = chip.stack.pop() or { panic(err) }
|
||||
// Returns from a subroutine
|
||||
}
|
||||
|
||||
0xE0 {
|
||||
chip.is_draw = true
|
||||
for i := 0; i < chip.screen.display_height; i++{
|
||||
for i := 0; i < chip.screen.display_height; i++ {
|
||||
for j := 0; j < chip.screen.display_width; j++ {
|
||||
chip.screen.display[i][j] = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//0NNN {
|
||||
// 0NNN {
|
||||
// nnn = instruction & 0x0FFF
|
||||
// Calls machine code routine
|
||||
//}
|
||||
|
||||
else{
|
||||
else {
|
||||
nnn = instruction & 0x0FFF
|
||||
//panic('Invalid instruction! 0x${instruction.hex()}')
|
||||
// panic('Invalid instruction! 0x${instruction.hex()}')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
0x1000 {
|
||||
nnn = instruction & 0x0FFF
|
||||
chip.pc = u16(nnn)
|
||||
is_jump = true
|
||||
// Jumps to address NNN
|
||||
}
|
||||
|
||||
0x2000 {
|
||||
|
||||
nnn = instruction & 0x0FFF
|
||||
|
||||
chip.stack.push(chip.pc)
|
||||
|
|
@ -178,31 +155,33 @@ fn (mut chip Chip8) decode_and_run(instruction u16) {
|
|||
is_jump = true
|
||||
// Calls subroutine at NNN
|
||||
}
|
||||
|
||||
0x3000 {
|
||||
x = (instruction & 0x0F00) >> 8
|
||||
nn = instruction & 0x00FF
|
||||
|
||||
if chip.v[x] == nn { chip.pc += 2 }
|
||||
if chip.v[x] == nn {
|
||||
chip.pc += 2
|
||||
}
|
||||
// Skips the next instruction if VX equals NN
|
||||
}
|
||||
|
||||
0x4000 {
|
||||
x = (instruction & 0x0F00) >> 8
|
||||
nn = instruction & 0x00FF
|
||||
|
||||
if chip.v[x] != nn { chip.pc += 2 }
|
||||
if chip.v[x] != nn {
|
||||
chip.pc += 2
|
||||
}
|
||||
// Skips the next instruction if VX does not equal NN
|
||||
}
|
||||
|
||||
0x5000 {
|
||||
x = (instruction & 0x0F00) >> 8
|
||||
y = (instruction & 0x00F0) >> 4
|
||||
|
||||
if chip.v[x] == chip.v[y] { chip.pc += 2 }
|
||||
if chip.v[x] == chip.v[y] {
|
||||
chip.pc += 2
|
||||
}
|
||||
// Skips the next instruction if VX equals VY
|
||||
}
|
||||
|
||||
0x6000 {
|
||||
x = (instruction & 0x0F00) >> 8
|
||||
nn = instruction & 0x00FF
|
||||
|
|
@ -210,7 +189,6 @@ fn (mut chip Chip8) decode_and_run(instruction u16) {
|
|||
chip.v[x] = u8(nn)
|
||||
// Sets VX to NN
|
||||
}
|
||||
|
||||
0x7000 {
|
||||
x = (instruction & 0x0F00) >> 8
|
||||
nn = instruction & 0x00FF
|
||||
|
|
@ -218,7 +196,6 @@ fn (mut chip Chip8) decode_and_run(instruction u16) {
|
|||
chip.v[x] += u8(nn)
|
||||
// Adds NN to VX (carry flag is not changed)
|
||||
}
|
||||
|
||||
0x8000 {
|
||||
x = (instruction & 0x0F00) >> 8
|
||||
y = (instruction & 0x00F0) >> 4
|
||||
|
|
@ -229,114 +206,96 @@ fn (mut chip Chip8) decode_and_run(instruction u16) {
|
|||
chip.v[x] = chip.v[y]
|
||||
// Sets VX to the value of VY
|
||||
}
|
||||
|
||||
0x01 {
|
||||
chip.v[x] |= chip.v[y]
|
||||
// Sets VX to VX or VY. (bitwise OR operation).
|
||||
}
|
||||
|
||||
0x02 {
|
||||
chip.v[x] &= chip.v[y]
|
||||
// Sets VX to VX and VY. (bitwise AND operation)
|
||||
}
|
||||
|
||||
0x03 {
|
||||
chip.v[x] ^= chip.v[y]
|
||||
// Sets VX to VX xor VY
|
||||
}
|
||||
|
||||
0x04 {
|
||||
|
||||
xy := chip.v[x] + chip.v[y]
|
||||
|
||||
if xy > 255 {
|
||||
chip.v[f] = 1
|
||||
}else{
|
||||
} else {
|
||||
chip.v[f] = 0
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
if chip.v[x] > chip.v[y] {
|
||||
chip.v[f] = 1
|
||||
}else{
|
||||
} else {
|
||||
chip.v[f] = 0
|
||||
}
|
||||
|
||||
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 {
|
||||
if chip.v[x] % 2 == 1 {
|
||||
chip.v[f] = 1;
|
||||
}
|
||||
else {
|
||||
chip.v[f] = 0;
|
||||
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
|
||||
}
|
||||
|
||||
0x07 {
|
||||
|
||||
xy := chip.v[y] - chip.v[x]
|
||||
|
||||
if chip.v[y] > chip.v[x] {
|
||||
chip.v[f] = 1
|
||||
}else{
|
||||
} else {
|
||||
chip.v[f] = 0
|
||||
}
|
||||
|
||||
chip.v[x] = xy
|
||||
// Sets VX to VY minus VX. VF is set to 0 when there's an underflow, and 1 when there is not. (i.e. VF set to 1 if VY >= VX).
|
||||
}
|
||||
|
||||
0x0E {
|
||||
|
||||
if (chip.v[x] & 10000000) == 1 {
|
||||
chip.v[f] = 1;
|
||||
}
|
||||
else {
|
||||
chip.v[f] = 0;
|
||||
chip.v[f] = 1
|
||||
} else {
|
||||
chip.v[f] = 0
|
||||
}
|
||||
|
||||
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.
|
||||
}
|
||||
|
||||
else{
|
||||
else {
|
||||
panic('Invalid instruction! 0x${instruction.hex()}')
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
0x9000 {
|
||||
x = (instruction & 0x0F00) >> 8
|
||||
y = (instruction & 0x00F0) >> 4
|
||||
|
||||
if chip.v[x] != chip.v[y] { chip.pc += 2 }
|
||||
if chip.v[x] != chip.v[y] {
|
||||
chip.pc += 2
|
||||
}
|
||||
}
|
||||
|
||||
0xA000 {
|
||||
nnn = instruction & 0x0FFF
|
||||
|
||||
chip.i = u16(nnn)
|
||||
}
|
||||
|
||||
0xB000 {
|
||||
nnn = instruction & 0x0FFF
|
||||
|
||||
chip.pc = u16(nnn + chip.v[0])
|
||||
is_jump = true
|
||||
}
|
||||
|
||||
0xC000 {
|
||||
x = (instruction & 0x0F00) >> 8
|
||||
nn = instruction & 0x00FF
|
||||
|
|
@ -345,9 +304,7 @@ fn (mut chip Chip8) decode_and_run(instruction u16) {
|
|||
|
||||
chip.v[x] = u8(randint & nn)
|
||||
}
|
||||
|
||||
0xD000 {
|
||||
|
||||
chip.is_draw = true
|
||||
x = (instruction & 0x0F00) >> 8
|
||||
y = (instruction & 0x00F0) >> 4
|
||||
|
|
@ -359,12 +316,11 @@ fn (mut chip Chip8) decode_and_run(instruction u16) {
|
|||
chip.v[f] = 0
|
||||
|
||||
for y_coord := 0; y_coord < n; y_coord++ {
|
||||
|
||||
pixel := chip.ram[chip.i + y_coord]
|
||||
|
||||
for x_coord := 0; x_coord < 8; x_coord++ {
|
||||
|
||||
if (regvy + y_coord) < chip.screen.display_height && (regvx + x_coord) < chip.screen.display_width {
|
||||
if (regvy + y_coord) < chip.screen.display_height
|
||||
&& (regvx + x_coord) < chip.screen.display_width {
|
||||
if (pixel & (0x80 >> x_coord)) != 0 {
|
||||
if chip.screen.display[regvy + y_coord][regvx + x_coord] == 1 {
|
||||
chip.v[f] = 1
|
||||
|
|
@ -376,98 +332,90 @@ fn (mut chip Chip8) decode_and_run(instruction u16) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
0xE000 {
|
||||
x = (instruction & 0x0F00) >> 8
|
||||
opcode_lsb = instruction & 0x00FF
|
||||
|
||||
match opcode_lsb {
|
||||
|
||||
0x9E {
|
||||
|
||||
if chip.key == chip.v[x] { chip.pc += 2 }
|
||||
if chip.key == chip.v[x] {
|
||||
chip.pc += 2
|
||||
}
|
||||
}
|
||||
|
||||
0xA1 {
|
||||
|
||||
if chip.key != chip.v[x] { chip.pc += 2 }
|
||||
if chip.key != chip.v[x] {
|
||||
chip.pc += 2
|
||||
}
|
||||
|
||||
else{
|
||||
}
|
||||
else {
|
||||
panic('Invalid instruction 0x${instruction.hex()}')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
0xF000 {
|
||||
x = (instruction & 0x0F00) >> 8
|
||||
opcode_lsb = instruction & 0x00FF
|
||||
|
||||
match opcode_lsb {
|
||||
0x07{
|
||||
0x07 {
|
||||
chip.v[x] = chip.delay_timer
|
||||
}
|
||||
|
||||
0x0A{
|
||||
0x0A {
|
||||
chip.v[x] = chip.key
|
||||
}
|
||||
|
||||
0x15{
|
||||
0x15 {
|
||||
chip.delay_timer = chip.v[x]
|
||||
}
|
||||
|
||||
0x18{
|
||||
0x18 {
|
||||
chip.sound_timer = chip.v[x]
|
||||
}
|
||||
|
||||
0x1E{
|
||||
0x1E {
|
||||
chip.i += chip.v[x]
|
||||
}
|
||||
|
||||
0x29{
|
||||
0x29 {
|
||||
chip.i = u16(chip.v[x] * 0x5)
|
||||
}
|
||||
|
||||
0x33{
|
||||
|
||||
0x33 {
|
||||
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{
|
||||
|
||||
0x55 {
|
||||
for i := chip.v[0]; i <= x; i++ {
|
||||
chip.ram[chip.i + i] = chip.v[i]
|
||||
}
|
||||
chip.i = u16(x + 1)
|
||||
}
|
||||
|
||||
0x65{
|
||||
0x65 {
|
||||
for i := chip.v[0]; i <= x; i++ {
|
||||
chip.v[x] = chip.ram[chip.i + i]
|
||||
}
|
||||
chip.i = u16(x + 1)
|
||||
}
|
||||
|
||||
else {
|
||||
panic('Invalid instruction! 0x${instruction.hex()}')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
panic('Invalid instruction! 0x${instruction.hex()}')
|
||||
}
|
||||
}
|
||||
if !is_jump { chip.pc += 2 }
|
||||
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) 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){
|
||||
@[direct_array_access]
|
||||
fn (mut chip Chip8) set_key(key int) {
|
||||
chip.key = u8(keyboard[key])
|
||||
}
|
||||
102
src/main.v
102
src/main.v
|
|
@ -3,107 +3,85 @@ module main
|
|||
import os
|
||||
import gg
|
||||
import gx
|
||||
import time
|
||||
|
||||
struct Emulator{
|
||||
|
||||
pub mut:
|
||||
struct Emulator {
|
||||
pub mut:
|
||||
chip8 Chip8
|
||||
graphic &gg.Context = unsafe { nil }
|
||||
is_graphic bool = is_graphic()
|
||||
}
|
||||
|
||||
fn (mut emulator Emulator) draw_block(i f32, j f32) {
|
||||
emulator.graphic.draw_rect_filled(j,i, f32(20), f32(20), 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() !{
|
||||
|
||||
arguments := os.args.clone()
|
||||
|
||||
if arguments.len > 1 {
|
||||
|
||||
mut file := os.open(arguments[1])!
|
||||
fn (mut emulator Emulator) load_rom() ! {
|
||||
if os.args.len <= 1 {
|
||||
return error('ROM path not especified!')
|
||||
}
|
||||
mut file := os.open(os.args[1])!
|
||||
defer { file.close() }
|
||||
|
||||
println(' Loading ROM in the memory...\n')
|
||||
load_animate()
|
||||
|
||||
println('Loading ROM in the memory...')
|
||||
mut instructions := file.read_bytes(1024)
|
||||
mut index := u16(0x200)
|
||||
emulator.chip8.set_ram(instructions, index)
|
||||
|
||||
println('ROM successfully loaded into memory!')
|
||||
|
||||
}else{
|
||||
panic('ROM path not especified!')
|
||||
}
|
||||
}
|
||||
|
||||
fn frame(mut emulator Emulator){
|
||||
|
||||
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++ {
|
||||
|
||||
for y in 0 .. emulator.chip8.screen.display_height {
|
||||
for x in 0 .. emulator.chip8.screen.display_width {
|
||||
pixel := emulator.chip8.screen.display[y][x]
|
||||
|
||||
if pixel == 1 {
|
||||
emulator.draw_block(f32((y)*20), f32((x)*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()
|
||||
}
|
||||
|
||||
fn (mut emulator Emulator) show_display(){
|
||||
emulator.graphic.run()
|
||||
fn (mut emulator Emulator) run(ms_per_tick int) {
|
||||
for {
|
||||
emulator.chip8.run()
|
||||
emulator.chip8.cycles++
|
||||
emulator.chip8.update_timers()
|
||||
if emulator.chip8.cpu_clock == emulator.chip8.cycles {
|
||||
emulator.chip8.cycles = 0
|
||||
}
|
||||
time.sleep(ms_per_tick * time.millisecond)
|
||||
}
|
||||
}
|
||||
|
||||
fn is_graphic() bool{
|
||||
return os.environ()['DISPLAY'] != ''
|
||||
fn on_event(e &gg.Event, mut emulator Emulator) {
|
||||
if e.typ == .key_down {
|
||||
x := int(e.key_code)
|
||||
// eprintln('>>> e.typ: ${e.typ} | e.key_code: ${e.key_code} | x: ${x} | x.hex(): ${x.hex()}')
|
||||
emulator.chip8.set_key(x)
|
||||
}
|
||||
if e.typ == .key_up {
|
||||
emulator.chip8.set_key(0)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
||||
mut emulator := &Emulator{
|
||||
chip8 : Chip8{}
|
||||
chip8: Chip8{}
|
||||
}
|
||||
|
||||
if emulator.is_graphic {
|
||||
|
||||
emulator.load_rom()!
|
||||
emulator.chip8.start_cpu()
|
||||
|
||||
emulator.graphic = gg.new_context(
|
||||
bg_color: gx.rgb(0, 0, 0)
|
||||
width: 1280
|
||||
height: 640
|
||||
window_title: 'V CHIP-8 Emulator'
|
||||
user_data: emulator
|
||||
frame_fn : frame
|
||||
frame_fn: frame
|
||||
event_fn: on_event
|
||||
)
|
||||
|
||||
emulator.show_display()
|
||||
|
||||
}else{
|
||||
panic('System is not graphic!')
|
||||
}
|
||||
}
|
||||
|
||||
fn on_event(e &gg.Event, mut emulator Emulator){
|
||||
emulator.chip8.set_key(e.char_code)
|
||||
// Ensure a constant rate of updates to the emulator, no matter
|
||||
// what the refresh rate is, by running the updates in a separate
|
||||
// independent thread:
|
||||
spawn emulator.run(8)
|
||||
emulator.graphic.run()
|
||||
}
|
||||
31
src/utils.v
31
src/utils.v
|
|
@ -1,40 +1,29 @@
|
|||
module main
|
||||
|
||||
import time
|
||||
|
||||
struct Stack{
|
||||
pub mut:
|
||||
struct Stack {
|
||||
pub mut:
|
||||
addresses [16]u16
|
||||
i_control int
|
||||
}
|
||||
|
||||
fn (stack Stack) is_empty() bool{
|
||||
fn (stack Stack) is_empty() bool {
|
||||
return stack.i_control == 0
|
||||
}
|
||||
|
||||
fn (mut stack Stack) push(address u16){
|
||||
@[direct_array_access]
|
||||
fn (mut stack Stack) push(address u16) {
|
||||
stack.addresses[stack.i_control] = address
|
||||
stack.i_control++
|
||||
}
|
||||
|
||||
fn (mut stack Stack) pop() !u16{
|
||||
@[direct_array_access]
|
||||
fn (mut stack Stack) pop() !u16 {
|
||||
if stack.is_empty() {
|
||||
return error('Stack is empty!')
|
||||
}else{
|
||||
val := stack.addresses[stack.i_control-1]
|
||||
stack.addresses[stack.i_control-1] = 0
|
||||
} else {
|
||||
val := stack.addresses[stack.i_control - 1]
|
||||
stack.addresses[stack.i_control - 1] = 0
|
||||
stack.i_control--
|
||||
return val
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn load_animate() {
|
||||
|
||||
mut bars := ['|','/','-','\\']
|
||||
|
||||
for i := 0; i < 4000; i++ {
|
||||
print('[${bars[i%4]}]\r ')
|
||||
time.sleep(400000)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue