|
|
@@ -1,58 +1,90 @@ |
|
|
|
use offbrand::prelude::*; |
|
|
|
use std::path::PathBuf; |
|
|
|
use structopt::StructOpt; |
|
|
|
|
|
|
|
// result type |
|
|
|
pub type Result<T> = std::result::Result<T, CeresError>; |
|
|
|
|
|
|
|
#[derive(Debug, thiserror::Error)] |
|
|
|
pub enum CeresError { |
|
|
|
#[error(transparent)] |
|
|
|
CeresAsm(#[from] ceres_asm::CeresAsmError), |
|
|
|
#[error(transparent)] |
|
|
|
StdIo(#[from] std::io::Error), |
|
|
|
#[error(transparent)] |
|
|
|
Offbrand(#[from] offbrand::Error), |
|
|
|
} |
|
|
|
|
|
|
|
#[derive(StructOpt)] |
|
|
|
#[structopt(name = "CERES-16", about = "16bit fantasy console")] |
|
|
|
struct Opt { |
|
|
|
/// times the screen should be scaled by |
|
|
|
/// how much the screen should be scaled by |
|
|
|
#[structopt(short = "s", long = "scale", default_value = "4")] |
|
|
|
_scale_factor: usize, |
|
|
|
scale_factor: usize, |
|
|
|
|
|
|
|
/// assemble some source |
|
|
|
#[structopt(short = "a", long = "assemble")] |
|
|
|
source_path: Option<PathBuf>, |
|
|
|
|
|
|
|
/// output file for assembly |
|
|
|
#[structopt(short = "o", long = "output")] |
|
|
|
output_path: Option<PathBuf>, |
|
|
|
} |
|
|
|
|
|
|
|
fn wrapper() -> Result<()> { |
|
|
|
// load options |
|
|
|
let _opt = Opt::from_args(); |
|
|
|
|
|
|
|
// initialize the system |
|
|
|
let _sys = ceres_sys::System::init(); |
|
|
|
|
|
|
|
let data = std::fs::read_to_string("test.asm").unwrap(); |
|
|
|
let mut assembler = ceres_asm::Assembler::new(&data); |
|
|
|
let asm = assembler.assemble().unwrap(); |
|
|
|
asm.0.iter().for_each(|instruction| println!("0b{:032b}", instruction)); |
|
|
|
asm.write_to_file(None).unwrap(); |
|
|
|
|
|
|
|
/* |
|
|
|
// create a new graphics context |
|
|
|
let mut ctx = offbrand::Context::new( |
|
|
|
ceres_sys::SCREEN_WIDTH, |
|
|
|
ceres_sys::SCREEN_HEIGHT, |
|
|
|
"CERES-16".to_owned(), |
|
|
|
Some(opt.scale_factor), |
|
|
|
)?; |
|
|
|
|
|
|
|
// loop while the context window is open |
|
|
|
while ctx.is_open() { |
|
|
|
// clear the context |
|
|
|
ctx.clear(None); |
|
|
|
|
|
|
|
// print a pixel for ever word in the video memory buffer |
|
|
|
for x in 0..ceres_sys::SCREEN_WIDTH { |
|
|
|
for y in 0..ceres_sys::SCREEN_HEIGHT { |
|
|
|
let color = |
|
|
|
color_from_u16(sys.video_memory[(y * ceres_sys::SCREEN_WIDTH + x) as u16]); |
|
|
|
ctx.insert_pixel(x, y, color); |
|
|
|
let opt = Opt::from_args(); |
|
|
|
|
|
|
|
if let Some(path) = opt.source_path { |
|
|
|
// if assmebly flag provided assemble the code |
|
|
|
let data = std::fs::read_to_string(path)?; |
|
|
|
let mut assembler = ceres_asm::Assembler::new(&data); |
|
|
|
let asm = assembler.assemble()?; |
|
|
|
asm.write_to_file(opt.output_path)?; |
|
|
|
} else { |
|
|
|
// otherwise start the console |
|
|
|
|
|
|
|
// initialize the system |
|
|
|
let sys = ceres_sys::System::init(); |
|
|
|
|
|
|
|
// create a new graphics context |
|
|
|
let mut ctx = offbrand::Context::new( |
|
|
|
ceres_sys::SCREEN_WIDTH, |
|
|
|
ceres_sys::SCREEN_HEIGHT, |
|
|
|
"CERES-16".to_owned(), |
|
|
|
Some(opt.scale_factor), |
|
|
|
)?; |
|
|
|
|
|
|
|
// loop while the context window is open |
|
|
|
while ctx.is_open() { |
|
|
|
// clear the context |
|
|
|
ctx.clear(None); |
|
|
|
|
|
|
|
// print a pixel for ever word in the video memory buffer |
|
|
|
for x in 0..ceres_sys::SCREEN_WIDTH { |
|
|
|
for y in 0..ceres_sys::SCREEN_HEIGHT { |
|
|
|
let color = |
|
|
|
color_from_u16(sys.video_memory[(y * ceres_sys::SCREEN_WIDTH + x) as u16]); |
|
|
|
ctx.insert_pixel(x, y, color); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// render the context |
|
|
|
ctx.present()?; |
|
|
|
// render the context |
|
|
|
ctx.present()?; |
|
|
|
} |
|
|
|
} |
|
|
|
*/ |
|
|
|
|
|
|
|
Ok(()) |
|
|
|
} |
|
|
|
|
|
|
|
// convert a color from u16 |
|
|
|
fn color_from_u16(color: u16) -> Color { |
|
|
|
let r = (((color >> 8) & 0x000f) as u8) * 17; |
|
|
|
let g = (((color >> 4) & 0x000f) as u8) * 17; |
|
|
|
let b = ((color & 0x000f) as u8) * 17; |
|
|
|
Color { r, g, b } |
|
|
|
} |
|
|
|
|
|
|
|
fn main() { |
|
|
|
if let Err(err) = wrapper() { |
|
|
|
eprintln!("error: {:?}", err); |
|
|
|