Initial commit:
Created outline of emulator:
The emulator has a Bus, which attaches a CPU to some Memory (Mapped Devices)
The design isn't particularly efficient, but the interpreter only needs to
run at ~500Hz or so. It's Rust. It can do that.
Instructions yet to be implemented:
Cxbb: "Store a random number, masked by bitmask bb, into vX"
Dxyn: "Draw an 8 by n sprite to the screen at coordinates (x, y)"
Fx0A: "Wait for a key, then set vX to the value of the pressed key"
Fx33: "BCD convert X, storing the results in &I[0..3]"
Thoughts going forward:
- It's probably a good idea to parse instructions out into an enum.
I had this in an earlier design, but it didn't really look that good.
However, I haven't read many other emulators before, so I don't know the
style people generally go for.
- I haven't used a native graphics library before, and my cg class was done
entirely in a web browser. That kinda sucks, honestly. Sure the skill
might transfer well, but, >JS
2023-03-08 12:07:33 +00:00
|
|
|
//! Dumps data to stdout
|
|
|
|
use std::ops::Range;
|
|
|
|
|
|
|
|
/// Prints a hexdump of a range within the `Dumpable`
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
/// ```rust
|
2023-03-10 21:33:36 +00:00
|
|
|
/// # use chumpulator::prelude::*;
|
Initial commit:
Created outline of emulator:
The emulator has a Bus, which attaches a CPU to some Memory (Mapped Devices)
The design isn't particularly efficient, but the interpreter only needs to
run at ~500Hz or so. It's Rust. It can do that.
Instructions yet to be implemented:
Cxbb: "Store a random number, masked by bitmask bb, into vX"
Dxyn: "Draw an 8 by n sprite to the screen at coordinates (x, y)"
Fx0A: "Wait for a key, then set vX to the value of the pressed key"
Fx33: "BCD convert X, storing the results in &I[0..3]"
Thoughts going forward:
- It's probably a good idea to parse instructions out into an enum.
I had this in an earlier design, but it didn't really look that good.
However, I haven't read many other emulators before, so I don't know the
style people generally go for.
- I haven't used a native graphics library before, and my cg class was done
entirely in a web browser. That kinda sucks, honestly. Sure the skill
might transfer well, but, >JS
2023-03-08 12:07:33 +00:00
|
|
|
/// let mem = Mem::new(0x50);
|
|
|
|
/// // Dumps the first 0x10 bytes
|
|
|
|
/// mem.dump(0x00..0x10);
|
|
|
|
/// ```
|
|
|
|
pub trait Dumpable {
|
|
|
|
/// Prints a hexdump of a range within the object
|
|
|
|
fn dump(&self, range: Range<usize>);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Prints a binary dump of a range within the `Dumpable`
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
/// ```rust
|
2023-03-10 21:33:36 +00:00
|
|
|
/// # use chumpulator::prelude::*;
|
Initial commit:
Created outline of emulator:
The emulator has a Bus, which attaches a CPU to some Memory (Mapped Devices)
The design isn't particularly efficient, but the interpreter only needs to
run at ~500Hz or so. It's Rust. It can do that.
Instructions yet to be implemented:
Cxbb: "Store a random number, masked by bitmask bb, into vX"
Dxyn: "Draw an 8 by n sprite to the screen at coordinates (x, y)"
Fx0A: "Wait for a key, then set vX to the value of the pressed key"
Fx33: "BCD convert X, storing the results in &I[0..3]"
Thoughts going forward:
- It's probably a good idea to parse instructions out into an enum.
I had this in an earlier design, but it didn't really look that good.
However, I haven't read many other emulators before, so I don't know the
style people generally go for.
- I haven't used a native graphics library before, and my cg class was done
entirely in a web browser. That kinda sucks, honestly. Sure the skill
might transfer well, but, >JS
2023-03-08 12:07:33 +00:00
|
|
|
/// let mem = bus! {
|
|
|
|
/// "mem" [0..0x10] = Mem::new(0x10)
|
|
|
|
/// };
|
|
|
|
/// // Dumps the first 0x10 bytes
|
|
|
|
/// mem.bin_dump(0x00..0x10);
|
|
|
|
/// ```
|
|
|
|
pub trait BinDumpable {
|
|
|
|
/// Prints a binary dump of a range within the object
|
|
|
|
fn bin_dump(&self, _range: Range<usize>) {}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn as_hexdump(index: usize, byte: u8) {
|
|
|
|
use owo_colors::OwoColorize;
|
|
|
|
let term: owo_colors::Style = owo_colors::Style::new().bold().green().on_black();
|
|
|
|
|
|
|
|
if index % 2 == 0 {
|
|
|
|
print!(" ")
|
|
|
|
}
|
|
|
|
if index % 8 == 0 {
|
|
|
|
print!(" ")
|
|
|
|
}
|
|
|
|
if index % 16 == 0 {
|
|
|
|
print!("{:>03x}{} ", index.style(term), ":".style(term));
|
|
|
|
}
|
|
|
|
print!("{byte:02x}");
|
|
|
|
if index % 16 == 0xf {
|
|
|
|
println!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn as_bindump(index: usize, byte: u8) {
|
|
|
|
use owo_colors::OwoColorize;
|
|
|
|
let term: owo_colors::Style = owo_colors::Style::new().bold().green().on_black();
|
|
|
|
if index % 8 == 0 {
|
|
|
|
print!("{:>03x}{} ", index.style(term), ":".style(term));
|
|
|
|
}
|
|
|
|
print!("{byte:08b} ");
|
|
|
|
if index % 8 == 7 {
|
|
|
|
println!()
|
|
|
|
}
|
|
|
|
}
|