-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.rs
126 lines (109 loc) · 3.54 KB
/
main.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
use std::fs;
use bus::Bus;
use catridge::Rom;
use cpu::{Mem, CPU};
use rand::Rng;
use sdl2::{event::Event, keyboard::Keycode, pixels::Color, pixels::PixelFormatEnum, EventPump};
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate bitflags;
pub mod bus;
pub mod catridge;
pub mod cpu;
pub mod opcodes;
pub mod tests;
pub mod trace;
fn main() {
/*
let sdl_context = sdl2::init().unwrap();
let video_subsystem = sdl_context.video().unwrap();
let window = video_subsystem
.window("Snake Game", 320, 320)
.position_centered()
.build()
.unwrap();
let mut canvas = window.into_canvas().present_vsync().build().unwrap();
let mut event_pump = sdl_context.event_pump().unwrap();
canvas.set_scale(10.0, 10.0).unwrap();
let creator = canvas.texture_creator();
let mut texture = creator
.create_texture_target(PixelFormatEnum::RGB24, 32, 32)
.unwrap();
*/
let game = fs::read("cartridges/nestest.nes").expect("should be able to read file");
let mut cpu = CPU::new(Bus::new(Rom::new(&game).unwrap()));
cpu.reset();
/*
let mut screen_state = [0 as u8; 32 * 3 * 32];
let mut rng = rand::thread_rng();
cpu.run_with_callback(move |cpu| {
handle_user_input(cpu, &mut event_pump);
cpu.mem_write(0xfe, rng.gen_range(1..16));
if read_screen_state(cpu, &mut screen_state) {
texture.update(None, &screen_state, 32 * 3).unwrap();
canvas.copy(&texture, None, None).unwrap();
canvas.present();
}
::std::thread::sleep(std::time::Duration::new(0, 70_000));
})
*/
cpu.run_with_callback(move |cpu| println!("{}", trace::trace(cpu)))
}
fn handle_user_input(cpu: &mut CPU, event_pump: &mut EventPump) {
for event in event_pump.poll_iter() {
match event {
Event::Quit { .. }
| Event::KeyDown {
keycode: Some(Keycode::Escape),
..
} => std::process::exit(0),
Event::KeyDown {
keycode: Some(Keycode::W),
..
} => cpu.mem_write(0xff, 0x77),
Event::KeyDown {
keycode: Some(Keycode::S),
..
} => cpu.mem_write(0xff, 0x73),
Event::KeyDown {
keycode: Some(Keycode::A),
..
} => cpu.mem_write(0xff, 0x61),
Event::KeyDown {
keycode: Some(Keycode::D),
..
} => cpu.mem_write(0xff, 0x64),
_ => { /* do nothing */ }
}
}
}
fn color(byte: u8) -> Color {
match byte {
0 => sdl2::pixels::Color::BLACK,
1 => sdl2::pixels::Color::WHITE,
2 | 9 => sdl2::pixels::Color::GREY,
3 | 10 => sdl2::pixels::Color::RED,
4 | 11 => sdl2::pixels::Color::GREEN,
5 | 12 => sdl2::pixels::Color::BLUE,
6 | 13 => sdl2::pixels::Color::MAGENTA,
7 | 14 => sdl2::pixels::Color::YELLOW,
_ => sdl2::pixels::Color::CYAN,
}
}
fn read_screen_state(cpu: &CPU, frame: &mut [u8; 32 * 3 * 32]) -> bool {
let mut frame_idx = 0;
let mut update = false;
for i in 0x200..0x600 {
let color_idx = cpu.mem_read(i as u16);
let (b1, b2, b3) = color(color_idx).rgb();
if frame[frame_idx] != b1 || frame[frame_idx + 1] != b2 || frame[frame_idx + 2] != b3 {
frame[frame_idx] = b1;
frame[frame_idx + 1] = b2;
frame[frame_idx + 2] = b3;
update = true;
}
frame_idx += 3;
}
update
}