- Adding SCHIP instructions
SDL2:
- Sorting out Joystick/Gamepad/Whatever
Util:
- Disassembler in progress
This commit is contained in:
Trevor Merritt 2024-10-19 08:24:43 -04:00
parent be6e652982
commit dea4b1aa92
8 changed files with 416 additions and 136 deletions

129
Cargo.lock generated
View File

@ -226,6 +226,55 @@ dependencies = [
"libc",
]
[[package]]
name = "anstream"
version = "0.6.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1"
[[package]]
name = "anstyle-parse"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a"
dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8"
dependencies = [
"anstyle",
"windows-sys 0.52.0",
]
[[package]]
name = "anyhow"
version = "1.0.89"
@ -758,6 +807,46 @@ dependencies = [
"windows-targets 0.52.6",
]
[[package]]
name = "clap"
version = "4.5.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.5.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim 0.11.1",
]
[[package]]
name = "clap_derive"
version = "4.5.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn 2.0.79",
]
[[package]]
name = "clap_lex"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
[[package]]
name = "clipboard-win"
version = "3.1.1"
@ -848,6 +937,12 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
[[package]]
name = "colorchoice"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0"
[[package]]
name = "com"
version = "0.6.0"
@ -1095,7 +1190,7 @@ dependencies = [
"ident_case",
"proc-macro2",
"quote",
"strsim",
"strsim 0.10.0",
"syn 1.0.109",
]
@ -1734,6 +1829,14 @@ dependencies = [
"gemma",
]
[[package]]
name = "gemmautil"
version = "0.1.0"
dependencies = [
"clap",
"gemma",
]
[[package]]
name = "generic-array"
version = "0.14.7"
@ -2068,6 +2171,12 @@ dependencies = [
"winapi",
]
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "hermit-abi"
version = "0.4.0"
@ -2269,6 +2378,12 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "jni"
version = "0.21.1"
@ -3804,6 +3919,12 @@ version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "syn"
version = "1.0.109"
@ -4091,6 +4212,12 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "vec_map"
version = "0.8.2"

View File

@ -1,5 +1,5 @@
[workspace]
members = ["gemma", "gemmaegui", "gemmaimgui", "gemmatelnet", "gemmasdl2" ]
members = ["gemma", "gemmaegui", "gemmaimgui", "gemmatelnet", "gemmasdl2", "gemmautil" ]
resolver = "2"
[workspace.dependencies]

View File

@ -143,6 +143,8 @@ pub enum Chip8CpuInstructions {
/// Dxyn
/// Display n-byte sprite starting at memory location I at (Vx, Vy), set VF = collision.
///
/// In Chip-8,
///
/// The interpreter reads n bytes from memory, starting at the address stored in I.
/// These bytes are then displayed as sprites on screen at coordinates (Vx, Vy).
/// Sprites are XORed onto the existing screen. If this causes any pixels to be erased,
@ -150,6 +152,11 @@ pub enum Chip8CpuInstructions {
/// it is outside the coordinates of the display, it wraps around to the opposite side
/// of the screen. See instruction 8xy3 for more information on XOR, and section 2.4,
/// Display, for more information on the Chip-8 screen and sprites.
///
/// In SCHIP
///
/// Show N-byte sprite from M(I) at Coords (VX,VY) VF = Collision.
/// If N=0 AND ExtendedMode, 16x16 sprite
DrawVxVyNibble(u8, u8, u8),
/// Ex9E
/// Skip next instruction if key with the value of Vx is pressed.
@ -213,119 +220,93 @@ pub enum Chip8CpuInstructions {
/// V0 through Vx.
LdVxI(u8),
XXXXERRORINSTRUCTION,
/* START OF SCHIP-8 */
/// 00CN
///
/// Scrolll Display N Lines Down
ScrDn(u8),
/// 00FB
///
/// Scroll 4 lines Right
ScrRt,
/// 00FC
///
/// Scroll 4 lines Left
ScrLf,
/// 00FE
///
/// Disable Extended Mode
VidDis,
/// 00FF
///
/// Enable Extended Mode
VidEna,
/// 00FD
///
/// Exit App
Exit,
/// FX30
///
/// Point I to 10 yte font sprite for digit VX (0..9)
LdFVx10(u8),
/// FX75
///
/// Store V0..VX in RPL user flags (X <= 7
StRpl(u8),
/// FX85
///
/// Load V0..VX from RPL user flags (X <= 7)
LdRpl(u8),
}
impl Chip8CpuInstructions {
pub fn name(&self) -> &str {
match self {
Chip8CpuInstructions::SysAddr(_) => {
"SYS"
}
Chip8CpuInstructions::CLS => {
"CLS"
}
Chip8CpuInstructions::RET => {
"RET"
}
Chip8CpuInstructions::JpAddr(_) => {
"JPA"
}
Chip8CpuInstructions::CallAddr(_) => {
"CALL"
}
Chip8CpuInstructions::SeVxByte(_, _) => {
"SeVxByte"
}
Chip8CpuInstructions::SneVxByte(_, _) => {
"SneVxByte"
}
Chip8CpuInstructions::SeVxVy(_, _) => {
"SeVeVy"
}
Chip8CpuInstructions::LdVxByte(_, _) => {
"LdVxByte"
}
Chip8CpuInstructions::AddVxByte(_, _) => {
"AddVxByte"
}
Chip8CpuInstructions::LdVxVy(_, _) => {
"LdVxVy"
}
Chip8CpuInstructions::OrVxVy(_, _) => {
"OrVxVy"
}
Chip8CpuInstructions::AndVxVy(_, _) => {
"AndVxVy"
}
Chip8CpuInstructions::XorVxVy(_, _) => {
"XorVxVy"
}
Chip8CpuInstructions::AddVxVy(_, _) => {
"AddVxVy"
}
Chip8CpuInstructions::SubVxVy(_, _) => {
"SubVxVy"
}
Chip8CpuInstructions::ShrVxVy(_, _) => {
"ShrVxVy"
}
Chip8CpuInstructions::SubnVxVy(_, _) => {
"SubnVxVy"
}
Chip8CpuInstructions::ShlVxVy(_, _) => {
"ShlVxVy"
}
Chip8CpuInstructions::SneVxVy(_, _) => {
"SneVxVy"
}
Chip8CpuInstructions::LdIAddr(_) => {
"LdIAddr"
}
Chip8CpuInstructions::JpV0Addr(_) => {
"JpV0Addr"
}
Chip8CpuInstructions::RndVxByte(_, _) => {
"RndVxByte"
}
Chip8CpuInstructions::DrawVxVyNibble(_, _, _) => {
"DrawVxVyNibble"
}
Chip8CpuInstructions::SkpVx(_) => {
"SkpVx"
}
Chip8CpuInstructions::SnkpVx(_) => {
"SnkpVx"
}
Chip8CpuInstructions::LdVxDt(_) => {
"LdVxDt"
}
Chip8CpuInstructions::LdVxK(_) => {
"LdVxK"
}
Chip8CpuInstructions::LdDtVx(_) => {
"LdDtVx"
}
Chip8CpuInstructions::LdStVx(_) => {
"LdStVx"
}
Chip8CpuInstructions::AddIVx(_) => {
"AddIVx"
}
Chip8CpuInstructions::LdFVx(_) => {
"LdFVx"
}
Chip8CpuInstructions::LdBVx(_) => {
"LdBVx"
}
Chip8CpuInstructions::LdIVx(_) => {
"LdIVx"
}
Chip8CpuInstructions::LdVxI(_) => {
"LdVxI"
}
XXXXERRORINSTRUCTION => {
"XX ERROR XX"
}
Chip8CpuInstructions::AddIVx(_) => "AddIVx",
Chip8CpuInstructions::AddVxByte(_, _) => "AddVxByte",
Chip8CpuInstructions::AddVxVy(_, _) => "AddVxVy",
Chip8CpuInstructions::AndVxVy(_, _) => "AndVxVy",
Chip8CpuInstructions::CLS => "CLS",
Chip8CpuInstructions::CallAddr(_) => "CALL",
Chip8CpuInstructions::DrawVxVyNibble(_, _, _) => "DrawVxVyNibble",
Chip8CpuInstructions::Exit => "EXIT",
Chip8CpuInstructions::JpAddr(_) => "JPA",
Chip8CpuInstructions::JpV0Addr(_) => "JpV0Addr",
Chip8CpuInstructions::LdBVx(_) => "LdBVx",
Chip8CpuInstructions::LdDtVx(_) => "LdDtVx",
Chip8CpuInstructions::LdFVx(_) => "LdFVx",
Chip8CpuInstructions::LdFVx10(x) => "LdFVx10",
Chip8CpuInstructions::LdIAddr(_) => "LdIAddr",
Chip8CpuInstructions::LdIVx(_) => "LdIVx",
Chip8CpuInstructions::LdRpl(x) => "LdRpl",
Chip8CpuInstructions::LdStVx(_) => "LdStVx",
Chip8CpuInstructions::LdVxByte(_, _) => "LdVxByte",
Chip8CpuInstructions::LdVxDt(_) => "LdVxDt",
Chip8CpuInstructions::LdVxI(_) => "LdVxI",
Chip8CpuInstructions::LdVxK(_) => "LdVxK",
Chip8CpuInstructions::LdVxVy(_, _) => "LdVxVy",
Chip8CpuInstructions::OrVxVy(_, _) => "OrVxVy",
Chip8CpuInstructions::RET => "RET",
Chip8CpuInstructions::RndVxByte(_, _) => "RndVxByte",
Chip8CpuInstructions::ScrDn(_) => "ScrDn",
Chip8CpuInstructions::ScrLf => "ScrLf",
Chip8CpuInstructions::ScrRt => "ScrRt",
Chip8CpuInstructions::SeVxByte(_, _) => "SeVxByte",
Chip8CpuInstructions::SeVxVy(_, _) => "SeVeVy",
Chip8CpuInstructions::ShlVxVy(_, _) => "ShlVxVy",
Chip8CpuInstructions::ShrVxVy(_, _) => "ShrVxVy",
Chip8CpuInstructions::SkpVx(_) => "SkpVx",
Chip8CpuInstructions::SneVxByte(_, _) => "SneVxByte",
Chip8CpuInstructions::SneVxVy(_, _) => "SneVxVy",
Chip8CpuInstructions::SnkpVx(_) => "SnkpVx",
Chip8CpuInstructions::StRpl(x) => "StRpl",
Chip8CpuInstructions::SubVxVy(_, _) => "SubVxVy",
Chip8CpuInstructions::SubnVxVy(_, _) => "SubnVxVy",
Chip8CpuInstructions::SysAddr(_) => "SYS",
Chip8CpuInstructions::VidDis => "VidDis",
Chip8CpuInstructions::VidEna => "VidEna",
Chip8CpuInstructions::XorVxVy(_, _) => "XorVxVy",
XXXXERRORINSTRUCTION => "XX ERROR XX",
}
}
@ -336,14 +317,14 @@ impl Chip8CpuInstructions {
Chip8CpuInstructions::JpAddr(addr) |
Chip8CpuInstructions::LdIAddr(addr) |
Chip8CpuInstructions::CallAddr(addr) => {
format!("{addr:04x}")
format!("0x{addr:04x}")
}
Chip8CpuInstructions::SeVxByte(x, byte) |
Chip8CpuInstructions::SneVxByte(x, byte) |
Chip8CpuInstructions::LdVxByte(x, byte) |
Chip8CpuInstructions::RndVxByte(x, byte) |
Chip8CpuInstructions::AddVxByte(x, byte) => {
format!("{x:02x}, {byte:04x}")
format!("0x{x:02x}, 0x{byte:02x}")
}
Chip8CpuInstructions::SeVxVy(x, y) |
Chip8CpuInstructions::LdVxVy(x, y) |
@ -356,10 +337,10 @@ impl Chip8CpuInstructions {
Chip8CpuInstructions::SubnVxVy(x, y) |
Chip8CpuInstructions::ShlVxVy(x, y) |
Chip8CpuInstructions::SneVxVy(x, y) => {
format!("{x:02x}, {y:02x}")
format!("0x{x:02x}, 0x{y:02x}")
}
Chip8CpuInstructions::DrawVxVyNibble(x, y, nibble) => {
format!("{x:02x}, {y:02x}, {nibble:02x}")
format!("0x{x:02x}, 0x{y:02x}, 0x{nibble:02x}")
}
Chip8CpuInstructions::LdDtVx(x) |
Chip8CpuInstructions::LdStVx(x) |
@ -371,12 +352,13 @@ impl Chip8CpuInstructions {
Chip8CpuInstructions::LdVxDt(x) |
Chip8CpuInstructions::LdVxK(x) |
Chip8CpuInstructions::LdVxI(x) |
Chip8CpuInstructions::LdFVx10(x) |
Chip8CpuInstructions::StRpl(x) |
Chip8CpuInstructions::LdRpl(x) |
Chip8CpuInstructions::SnkpVx(x) => {
format!("{x:02x}")
}
_ => {
"".parse().unwrap()
format!("0x{x:02x}")
}
_ => { String::new() }
}
}
}
@ -427,7 +409,16 @@ impl Chip8CpuInstructions {
Chip8CpuInstructions::LdBVx(x_register) => 0xF033 | ((*x_register as u16) << 8),
Chip8CpuInstructions::LdIVx(x_register) => 0xF055 | ((*x_register as u16) << 8),
Chip8CpuInstructions::LdVxI(x_register) => 0xF065 | ((*x_register as u16) << 8),
XXXXERRORINSTRUCTION => 0xFFFF,
Chip8CpuInstructions::ScrDn(x_register) => 0x00C0 | (*x_register as u16),
Chip8CpuInstructions::ScrRt => 0x00FB,
Chip8CpuInstructions::ScrLf => 0x00FC,
Chip8CpuInstructions::VidDis => 0x00FE,
Chip8CpuInstructions::VidEna => 0x00FF,
Chip8CpuInstructions::Exit => 0x00FD,
Chip8CpuInstructions::LdFVx10(x_register) => 0xF030 | ((*x_register as u16) << 8),
Chip8CpuInstructions::StRpl(x_register) => 0xF075 | ((*x_register as u16) << 8),
Chip8CpuInstructions::LdRpl(x_register) => 0xF085 | ((*x_register as u16) << 8),
XXXXERRORINSTRUCTION => 0xFFFF
}
}
pub fn decode(input: u16) -> Chip8CpuInstructions {
@ -441,8 +432,14 @@ impl Chip8CpuInstructions {
let last_nibble = (input & 0xF) as u8;
match input {
0x00C0..=0x00CF => Chip8CpuInstructions::ScrDn(last_nibble),
0x00E0 => Chip8CpuInstructions::CLS,
0x00EE => Chip8CpuInstructions::RET,
0x00FB => Chip8CpuInstructions::ScrRt,
0x00FC => Chip8CpuInstructions::ScrLf,
0x00FD => Chip8CpuInstructions::Exit,
0x00FE => Chip8CpuInstructions::VidDis,
0x00FF => Chip8CpuInstructions::VidEna,
0x0000..=0x0FFF => Chip8CpuInstructions::SysAddr(addr_param),
0x1000..=0x1FFF => Chip8CpuInstructions::JpAddr(addr_param),
0x2000..=0x2FFF => Chip8CpuInstructions::CallAddr(addr_param),
@ -480,9 +477,12 @@ impl Chip8CpuInstructions {
0x18 => Chip8CpuInstructions::LdStVx(ubln),
0x1E => Chip8CpuInstructions::AddIVx(ubln),
0x29 => Chip8CpuInstructions::LdFVx(ubln),
0x30 => Chip8CpuInstructions::LdFVx10(ubln),
0x33 => Chip8CpuInstructions::LdBVx(ubln),
0x55 => Chip8CpuInstructions::LdIVx(ubln),
0x65 => Chip8CpuInstructions::LdVxI(ubln),
0x75 => Chip8CpuInstructions::StRpl(ubln),
0x85 => Chip8CpuInstructions::LdRpl(ubln),
_ => XXXXERRORINSTRUCTION
}
_ => XXXXERRORINSTRUCTION
@ -865,6 +865,33 @@ impl Chip8CpuInstructions {
input.registers.poke_i(offset + 1);
}
Chip8CpuInstructions::XXXXERRORINSTRUCTION => {}
Chip8CpuInstructions::ScrDn(x) => {
println!("SCROLLING DOWN {x} LINES");
}
Chip8CpuInstructions::ScrRt => {
println!("SCROLING RIGHT 4 LINES");
}
Chip8CpuInstructions::ScrLf => {
println!("SCROLLING LEFT 4 LINES");
}
Chip8CpuInstructions::VidDis => {
println!("DISABLE VIDEO MODE");
}
Chip8CpuInstructions::VidEna => {
println!("ENABLE VIDEO MODE");
}
Chip8CpuInstructions::Exit => {
println!("EXIT INTERPRETER");
}
Chip8CpuInstructions::LdFVx10(x) => {
println!("POINTING TO FONT AT {x:02x}");
}
Chip8CpuInstructions::StRpl(x) => {
println!("STORING FROM RPL FOR {x}");
}
Chip8CpuInstructions::LdRpl(x) => {
println!("LOADING FROM RPL FOR {x}");
}
};
let cycle_time = Instant::now().duration_since(start_time).as_nanos();
// println!("\t\tTook {cycle_time}ms");
@ -920,6 +947,26 @@ mod test {
assert_eq!(Chip8CpuInstructions::LdBVx(0xd).encode(), 0xfd33);
assert_eq!(Chip8CpuInstructions::LdIVx(0xe).encode(), 0xfe55);
assert_eq!(Chip8CpuInstructions::LdVxI(0x3).encode(), 0xf365);
assert_eq!(Chip8CpuInstructions::ScrDn(0x1).encode(), 0x00C1);
assert_eq!(Chip8CpuInstructions::ScrLf.encode(), 0x00FC);
assert_eq!(Chip8CpuInstructions::ScrRt.encode(), 0x00FB);
assert_eq!(Chip8CpuInstructions::Exit.encode(), 0x00FD);
assert_eq!(Chip8CpuInstructions::VidEna.encode(), 0x00FF);
assert_eq!(Chip8CpuInstructions::VidDis.encode(), 0x00FE);
assert_eq!(Chip8CpuInstructions::LdFVx10(0).encode(), 0xF030);
assert_eq!(Chip8CpuInstructions::StRpl(1).encode(), 0xF175);
assert_eq!(Chip8CpuInstructions::LdRpl(1).encode(), 0xF185);
assert!(matches!(Chip8CpuInstructions::decode(0xF175), Chip8CpuInstructions::StRpl(1)));
assert!(matches!(Chip8CpuInstructions::decode(0xF185), Chip8CpuInstructions::LdRpl(1)));
assert!(matches!(Chip8CpuInstructions::decode(0x00C1u16), Chip8CpuInstructions::ScrDn(0x01)));
assert!(matches!(Chip8CpuInstructions::decode(0x00FCu16), Chip8CpuInstructions::ScrLf));
assert!(matches!(Chip8CpuInstructions::decode(0x00FBu16), Chip8CpuInstructions::ScrRt));
assert!(matches!(Chip8CpuInstructions::decode(0x00FDu16), Chip8CpuInstructions::Exit));
assert!(matches!(Chip8CpuInstructions::decode(0x00FEu16), Chip8CpuInstructions::VidDis));
assert!(matches!(Chip8CpuInstructions::decode(0x00FFu16), Chip8CpuInstructions::VidEna));
assert!(matches!(Chip8CpuInstructions::decode(0xF030u16), Chip8CpuInstructions::LdFVx10(0)));
assert!(matches!(Chip8CpuInstructions::decode(0x00E0u16), Chip8CpuInstructions::CLS));
assert!(matches!(Chip8CpuInstructions::decode(0x00EEu16), Chip8CpuInstructions::RET));
assert!(matches!(Chip8CpuInstructions::decode(0x0123), Chip8CpuInstructions::SysAddr(0x123)));

View File

@ -1,10 +1,18 @@
use log::{debug};
use crate::chip8::video::Chip8VideoModes::{HighRes, LowRes};
use crate::constants::{CHIP8_VIDEO_MEMORY, CHIP8_VIDEO_WIDTH};
#[derive(Clone, Copy)]
enum Chip8VideoModes {
LowRes,
HighRes
}
#[derive(Clone, Copy)]
pub struct Chip8Video {
memory: [bool; CHIP8_VIDEO_MEMORY],
pub has_frame_changed: bool,
current_res: Chip8VideoModes
}
impl Chip8Video {
@ -13,9 +21,29 @@ impl Chip8Video {
self.start_frame();
}
pub fn set_highres(&mut self) {
self.current_res = HighRes
}
pub fn set_lowres(&mut self) {
self.current_res = LowRes
}
pub fn get_screen_resolution(&mut self) -> Chip8VideoModes {
self.current_res
}
pub fn cls(&mut self) {
match self.current_res {
LowRes => {
self.memory = [false; CHIP8_VIDEO_MEMORY];
}
HighRes => {
// self.memory = [0u8; ]
}
}
}
pub fn start_frame(&mut self) {
self.has_frame_changed = false;
@ -25,6 +53,7 @@ impl Chip8Video {
Self {
memory: initial_configuration,
has_frame_changed: false,
current_res: Chip8VideoModes::LowRes,
}
}
@ -85,7 +114,7 @@ impl Chip8Video {
impl Default for Chip8Video {
fn default() -> Self {
Chip8Video { memory: [false; CHIP8_VIDEO_MEMORY], has_frame_changed: false }
Chip8Video { memory: [false; CHIP8_VIDEO_MEMORY], has_frame_changed: false, current_res: Chip8VideoModes::LowRes }
}
}

View File

@ -12,3 +12,6 @@ pub const CHIP8_KEYBOARD: [[u8; 4]; 4] = [
[0x0A, 0x00, 0x0B, 0x0F]
];
pub const SCHIP_VIDEO_HEIGHT: i32 = 64;
pub const SCHIP_VIDEO_WIDTH: i32 = 128;
pub const SCHIP_VIDE_MEMORY: usize = (SCHIP_VIDEO_HEIGHT * SCHIP_VIDEO_WIDTH) as usize;

View File

@ -17,7 +17,6 @@ async fn run() -> anyhow::Result<String> {
let sdl = sdl2::init().map_err(|e| anyhow::anyhow!("Failed to create SDL context: {}", e))?;
let mut video = sdl.video().map_err(|e| anyhow::anyhow!("Failed to initialize SDL video subsystem: {}", e))?;
// Create SDL2 window and OpenGL context
let window = video.window("Window", SCREEN_WIDTH, SCREEN_HEIGHT)
.opengl()
@ -114,6 +113,12 @@ async fn run() -> anyhow::Result<String> {
Event::ControllerButtonDown { button, .. } => {
println!("BUTTON {:?}", button);
}
Event::JoyButtonDown {button_idx, .. } => {
println!("JoyButtonDown {}", button_idx);
}
Event::JoyAxisMotion { which, axis_idx, .. } => {
println!("JoyAxismotion {which} {axis_idx}");
}
_ => platform.handle_event(&event, &sdl, &video),
}
}
@ -122,6 +127,9 @@ async fn run() -> anyhow::Result<String> {
if let Some(fps) = timestep.frame_rate() {
println!("{:?} fps", fps);
}
let num_js = sdl.joystick().unwrap().num_joysticks().unwrap();
println!("NUM JS = {num_js}");
}
Ok(("").parse()?)

8
gemmautil/Cargo.toml Normal file
View File

@ -0,0 +1,8 @@
[package]
name = "gemmautil"
version = "0.1.0"
edition = "2021"
[dependencies]
gemma = { path = "../gemma" }
clap = { version = "4.5.20", features = ["derive"] }

View File

@ -0,0 +1,58 @@
use std::path::Path;
use clap::{command, Parser};
use gemma::chip8::instructions::Chip8CpuInstructions;
use gemma::chip8::instructions::Chip8CpuInstructions::XXXXERRORINSTRUCTION;
/// ch8disasm
///
/// Provide disassembled version of the CH8 file provided.
#[derive(Parser)]
#[command(version, about, long_about = None)]
struct DisassemblerApp {
#[arg(short)]
input_file: Box<Path>,
#[arg(short)]
output_file: Option<Box<Path>>
}
fn main() {
println!("Taxation is Theft");
let result = DisassemblerApp::parse();
println!("PREPARING TO DISASSEMBLE {:?}", result.input_file.file_name());
let mut last_byte: u8 = 0x00;
let mut working_instruction: u16 = 0x0000;
// read the input file and loop through it byte by byte.
for (offset, byte) in std::fs::read(result.input_file).unwrap().iter().enumerate() {
working_instruction = (working_instruction << 8) | (*byte as u16);
if offset % 2 != 0 {
// println!("ODD BYTE -> {:02x} / WORKING: {working_instruction:04x}", *byte as u16);
let decoded = Chip8CpuInstructions::decode(working_instruction);
match decoded {
XXXXERRORINSTRUCTION => {
println!("\t\t; ERROR: BYTES: {} OFFSET: {}", working_instruction, offset);
println!("FOUND ERROR INSTRUCTION. LIKELY DATA.");
}
Chip8CpuInstructions::JpAddr(x) => {
if x == (offset + 0x1ff) as u16 {
println!("FOUND JUMP TO SELF. INFINITE LOOP DETECTED.");
}
}
_ => {
println!("{}\t\t; Bytes [{:04x}] ending offset [{:04x}]", decoded, working_instruction, offset);
}
}
working_instruction = 0x0000;
}
}
match result.output_file {
None => {
println!("Output to console.");
}
Some(target) => {
println!("Output to {:?}", target);
}
}
}