enabled piping a program from stdin
This commit is contained in:
parent
7d0b66f418
commit
f464dbfaf1
|
@ -86,7 +86,11 @@ fn help(command: Option<String>) {
|
|||
println!(" rom, -r, --rom <path>: load a rom/binary from path");
|
||||
println!(" screen, -s, --screen <type>: use the \"terminal\" or \"window\" display type");
|
||||
println!("\nconfiguration:");
|
||||
println!(" george-emu searches for a `george.toml` in the current directory.\n in `george.toml` you can specify a path for the character rom using the key `char_rom` and the main rom/binary with the key `rom`");
|
||||
println!(" george-emu searches for a `george.toml` in the current directory.\n in `george.toml` you can specify a path for the character rom\n using the key `char_rom` and the main rom/binary with the key `rom`");
|
||||
println!("\ndebugging:");
|
||||
println!(" you can pipe in a rom for george to evaluate.");
|
||||
println!(" she'll read it until she reaches a breakpoint (`0x02`) or `stp` instruction,");
|
||||
println!(" then will dump her memory to stdout <3");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,36 @@
|
|||
use std::io::{self, stdin, IsTerminal};
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
mod cli;
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use cli::get_input;
|
||||
use georgeemu::memory::{Mem, MemHandle};
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use georgeemu::GeorgeEmu;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use minifb::{Scale, ScaleMode, Window, WindowOptions};
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
fn main() {
|
||||
use std::{fs::File, io::Read};
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
fn main() -> io::Result<()> {
|
||||
use std::io::{stdout, Write};
|
||||
|
||||
use georgeemu::cpu::Cpu;
|
||||
|
||||
let mut input = stdin();
|
||||
|
||||
if !input.is_terminal() {
|
||||
let mut bytes = [0u8; 0x8000];
|
||||
input.read_exact(&mut bytes).unwrap();
|
||||
let memory = make_memory(&bytes);
|
||||
let mut cpu = Cpu::new(memory);
|
||||
let final_output = cpu.run_to_end();
|
||||
|
||||
let _ = stdout().write_all(&final_output);
|
||||
Ok(())
|
||||
} else {
|
||||
let window = Window::new(
|
||||
"ʕ·ᴥ·ʔ-☆",
|
||||
512,
|
||||
|
@ -35,14 +54,22 @@ fn main() {
|
|||
let mut file = File::open(path).unwrap();
|
||||
let mut bin = vec![0; 0x8000];
|
||||
file.read_exact(&mut bin).unwrap();
|
||||
// println!("reading char rom");
|
||||
bin.try_into().unwrap()
|
||||
}
|
||||
None => *include_bytes!("../roms/george.rom"),
|
||||
None => *include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/roms/george.rom")),
|
||||
};
|
||||
let mut emu = GeorgeEmu::builder().rom(rom).window(window).build();
|
||||
|
||||
emu.run();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
fn make_memory(bytes: &[u8]) -> MemHandle {
|
||||
let mut memory = Mem::new();
|
||||
memory.load_bytes(bytes);
|
||||
MemHandle::new(memory)
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
|
|
34
src/cpu.rs
34
src/cpu.rs
|
@ -97,11 +97,18 @@ impl MemoryWriter for Cpu {
|
|||
|
||||
impl Cpu {
|
||||
pub fn new(memory: MemHandle) -> Self {
|
||||
// reset the cpu on initialization so we don't
|
||||
// scream and cry for two days trying to figure
|
||||
// out why george isn't working <3
|
||||
let low_byte = memory.read(0xFFFC);
|
||||
let high_byte = memory.read(0xFFFD);
|
||||
let pc = (high_byte as u16) << 8 | (low_byte as u16);
|
||||
|
||||
Cpu {
|
||||
a: 0x00,
|
||||
x: 0x00,
|
||||
y: 0x00,
|
||||
pc: 0x0000,
|
||||
pc,
|
||||
s: 0xFF,
|
||||
p: 0b0010_0100,
|
||||
irq: false,
|
||||
|
@ -111,8 +118,7 @@ impl Cpu {
|
|||
debug: false,
|
||||
stopped: false,
|
||||
pending_cycles: 0,
|
||||
cycle: false, // cycle_count: 0,
|
||||
// state_tx,
|
||||
cycle: false,
|
||||
}
|
||||
}
|
||||
pub fn with_receiver(mut self, receiver: CpuReceiver) -> Self {
|
||||
|
@ -265,4 +271,26 @@ impl Cpu {
|
|||
self.stop();
|
||||
}
|
||||
}
|
||||
|
||||
fn quick_cycle(&mut self) {
|
||||
if !self.get_flag(StatusFlag::IrqDisable) && self.irq {
|
||||
self.interrupt();
|
||||
}
|
||||
let opcode = self.read(self.pc);
|
||||
let instruction = get_instruction(opcode);
|
||||
instruction.call(self);
|
||||
}
|
||||
|
||||
pub fn run_to_end(&mut self) -> [u8; 0x10000] {
|
||||
self.quick_cycle();
|
||||
while self.pending_cycles != 0 {
|
||||
let opcode = self.read(self.pc);
|
||||
let instruction = get_instruction(opcode);
|
||||
match instruction.name {
|
||||
"stp" | "breakpoint" => return self.memory.dump(),
|
||||
_ => self.quick_cycle(),
|
||||
}
|
||||
}
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1028,14 +1028,14 @@ pub const OPCODES: [Instruction; 256] = [
|
|||
instr_fn: Some(breakpoint),
|
||||
address_fn: None,
|
||||
cycles: 0,
|
||||
name: "none",
|
||||
name: "breakpoint",
|
||||
addr_mode: "implied",
|
||||
},
|
||||
Instruction {
|
||||
instr_fn: None,
|
||||
address_fn: None,
|
||||
cycles: 0,
|
||||
name: "none",
|
||||
name: "end",
|
||||
addr_mode: "implied",
|
||||
},
|
||||
Instruction {
|
||||
|
|
Loading…
Reference in New Issue