good god that took way to long but this kinda works
This commit is contained in:
parent
78dad90fc9
commit
95acceeabd
|
@ -8,6 +8,31 @@ version = "1.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bdf"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f550a6818e6f42ccd5883f44e45fff4f68415a0d09abdc81e7d1d78e0780af14"
|
||||
dependencies = [
|
||||
"bit-set",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bit-set"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "84527c7b0452f22545cc010e72d366a435561d2b28b978035550b3778c4d428d"
|
||||
dependencies = [
|
||||
"bit-vec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bit-vec"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
|
@ -20,6 +45,18 @@ version = "2.4.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
|
||||
|
||||
[[package]]
|
||||
name = "bitvec"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c"
|
||||
dependencies = [
|
||||
"funty",
|
||||
"radium",
|
||||
"tap",
|
||||
"wyz",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.14.0"
|
||||
|
@ -78,6 +115,12 @@ version = "2.0.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
|
||||
|
||||
[[package]]
|
||||
name = "funty"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.30"
|
||||
|
@ -171,6 +214,8 @@ dependencies = [
|
|||
name = "georgeemu"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bdf",
|
||||
"bitvec",
|
||||
"minifb",
|
||||
]
|
||||
|
||||
|
@ -347,6 +392,12 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "radium"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
|
||||
|
||||
[[package]]
|
||||
name = "raw-window-handle"
|
||||
version = "0.4.3"
|
||||
|
@ -453,6 +504,12 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tap"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.9.0"
|
||||
|
@ -466,6 +523,26 @@ dependencies = [
|
|||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.56"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.56"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
|
@ -781,6 +858,15 @@ version = "0.52.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
|
||||
|
||||
[[package]]
|
||||
name = "wyz"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed"
|
||||
dependencies = [
|
||||
"tap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "x11-dl"
|
||||
version = "2.21.0"
|
||||
|
|
|
@ -6,4 +6,6 @@ edition = "2021"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
bdf = "0.6.0"
|
||||
bitvec = "1.0.1"
|
||||
minifb = "0.25.0"
|
||||
|
|
|
@ -212,9 +212,9 @@ impl Cpu {
|
|||
let instruction = get_instruction(opcode);
|
||||
match instruction {
|
||||
Instruction::Valid(valid_instruction) => {
|
||||
println!("Instruction: {:?}, {:?}", valid_instruction.opcode, opcode);
|
||||
println!("a: {a:#04x}, x: {x:#04x}, y: {y:#04x}, pc: {pc:#06x}, sp: {s:#04x}, sr: {p:#010b}, irq: {irq:?}, nmi: {nmi:?}", a = self.a, x = self.x, y = self.y, pc = self.pc, s = self.s, p = self.p, irq = self.irq, nmi = self.nmi);
|
||||
println!("");
|
||||
//println!("Instruction: {:?}, {:?}", valid_instruction.opcode, opcode);
|
||||
//println!("a: {a:#04x}, x: {x:#04x}, y: {y:#04x}, pc: {pc:#06x}, sp: {s:#04x}, sr: {p:#010b}, irq: {irq:?}, nmi: {nmi:?}", a = self.a, x = self.x, y = self.y, pc = self.pc, s = self.s, p = self.p, irq = self.irq, nmi = self.nmi);
|
||||
//println!("");
|
||||
self.pc += 1;
|
||||
match valid_instruction.opcode.call(self) {
|
||||
Ok(_) => {
|
||||
|
|
|
@ -3,6 +3,7 @@ pub enum GeorgeErrorKind {
|
|||
Memory(MemoryError),
|
||||
Execution(ExecutionError),
|
||||
AddrMode(AddressingModeError),
|
||||
Mapping(MappingError),
|
||||
}
|
||||
|
||||
impl From<MemoryError> for GeorgeErrorKind {
|
||||
|
|
BIN
src/george
BIN
src/george
Binary file not shown.
|
@ -1,5 +1,7 @@
|
|||
.setcpu "65C02"
|
||||
.segment "CODE"
|
||||
LDA #$0
|
||||
STA $4000
|
||||
main:
|
||||
LDA #$25
|
||||
LDY #$2F
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
# column #3 the Unicode name (follows a comment sign, '#')
|
||||
|
||||
0x00 0x0295 # ʕ
|
||||
0x01 0x0097 # Middle Dot
|
||||
0x01 0x00B7 # Middle Dot
|
||||
0x02 0x1D25 # ᴥ
|
||||
0x03 0x0294 # ʔ
|
||||
0x04 0x2661 # White heart
|
||||
|
@ -27,18 +27,18 @@
|
|||
0x11 0x266A # Eighth note
|
||||
0x12 0x266B # Beamed eighth notes
|
||||
0x13 0x266C # Beamed sixteenth notes
|
||||
0x14 0x0020 #
|
||||
0x15 0x0020 #
|
||||
0x16 0x0020 #
|
||||
0x17 0x0020 #
|
||||
0x18 0x0020 #
|
||||
0x19 0x0020 #
|
||||
0x1A 0x0020 #
|
||||
0x1B 0x0020 #
|
||||
0x1C 0x0020 #
|
||||
0x1D 0x0020 #
|
||||
0x1E 0x0020 #
|
||||
0x1F 0x0020 #
|
||||
0x14 0xFC5D #
|
||||
0x15 0xF026 #
|
||||
0x16 0xF027 #
|
||||
0x17 0xF028 #
|
||||
0x18 0xFA7E #
|
||||
0x19 0xFA7F #
|
||||
0x1A 0xFA80 #
|
||||
0x1B 0xFC5C #
|
||||
0x1C 0xFC5B #
|
||||
0x1D 0xF0AC #
|
||||
0x1E 0xF04B #
|
||||
0x1F 0xF04D #
|
||||
0x20 0x0020 # SPACE
|
||||
0x21 0x0021 # EXCLAMATION MARK
|
||||
0x22 0x0022 # QUOTATION MARK
|
||||
|
@ -161,11 +161,11 @@
|
|||
0x97 0x2566 #
|
||||
0x98 0x2569 #
|
||||
0x99 0x256C #
|
||||
0x9A 0x0020 #
|
||||
0x9B 0x0020 #
|
||||
0x9C 0x0020 #
|
||||
0x9D 0x0020 #
|
||||
0x9E 0x0020 #
|
||||
0x9A 0xF04E #
|
||||
0x9B 0xF050 #
|
||||
0x9C 0xF051 #
|
||||
0x9D 0xF052 #
|
||||
0x9E 0xF048 #
|
||||
0x9F 0xE0B0 #
|
||||
0xA0 0xE0B2 #
|
||||
0xA1 0xE0B4 #
|
||||
|
@ -214,52 +214,52 @@
|
|||
0xCC 0x2B81 #
|
||||
0xCD 0x2B82 #
|
||||
0xCE 0x2B83 #
|
||||
0xCF 0x0020 #
|
||||
0xD0 0x0020 #
|
||||
0xD1 0x0020 #
|
||||
0xD2 0x0020 #
|
||||
0xD3 0x0020 #
|
||||
0xD4 0x0020 #
|
||||
0xD5 0x0020 #
|
||||
0xD6 0x0020 #
|
||||
0xD7 0x0020 #
|
||||
0xD8 0x0020 #
|
||||
0xD9 0x0020 #
|
||||
0xDA 0x0020 #
|
||||
0xDB 0x0020 #
|
||||
0xDC 0x0020 #
|
||||
0xDD 0x0020 #
|
||||
0xDE 0x0020 #
|
||||
0xDF 0x0020 #
|
||||
0xE0 0x0020 #
|
||||
0xE1 0x0020 #
|
||||
0xE2 0x0020 #
|
||||
0xE3 0x0020 #
|
||||
0xE4 0x0020 #
|
||||
0xE5 0x0020 #
|
||||
0xE6 0x0020 #
|
||||
0xE7 0x0020 #
|
||||
0xE8 0x0020 #
|
||||
0xE9 0x0020 #
|
||||
0xEA 0x0020 #
|
||||
0xEB 0x0020 #
|
||||
0xEC 0x0020 #
|
||||
0xED 0x0020 #
|
||||
0xEE 0x0020 #
|
||||
0xEF 0x0020 #
|
||||
0xF0 0x0020 #
|
||||
0xF1 0x0020 #
|
||||
0xF2 0x0020 #
|
||||
0xF3 0x0020 #
|
||||
0xF4 0x0020 #
|
||||
0xF5 0x0020 #
|
||||
0xF6 0x0020 #
|
||||
0xF7 0x0020 #
|
||||
0xF8 0x0020 #
|
||||
0xF9 0x0020 #
|
||||
0xFA 0x0020 #
|
||||
0xFB 0x0020 #
|
||||
0xFC 0x0020 #
|
||||
0xFD 0x0020 #
|
||||
0xFE 0x0020 #
|
||||
0xFF 0x0020 #
|
||||
0xCF 0xF049 #
|
||||
0xD0 0xF04A #
|
||||
0xD1 0x23F3 #
|
||||
0xD2 0xF07B #
|
||||
0xD3 0xF07C #
|
||||
0xD4 0xF114 #
|
||||
0xD5 0xF115 #
|
||||
0xD6 0xF250 #
|
||||
0xD7 0xF251 #
|
||||
0xD8 0xF253 #
|
||||
0xD9 0xF254 #
|
||||
0xDA 0xF461 #
|
||||
0xDB 0xF016 #
|
||||
0xDC 0xF401 #
|
||||
0xDD 0x1F52E #
|
||||
0xDE 0xF2DB #
|
||||
0xDF 0xF008 #
|
||||
0xE0 0x25C7 #
|
||||
0xE1 0x25C8 #
|
||||
0xE2 0x1F311 #
|
||||
0xE3 0x1F312 #
|
||||
0xE4 0x1F313 #
|
||||
0xE5 0x1F314 #
|
||||
0xE6 0x1F315 #
|
||||
0xE7 0x1F316 #
|
||||
0xE8 0x1F317 #
|
||||
0xE9 0x1F318 #
|
||||
0xEA 0xF04C #
|
||||
0xEB 0x2714 #
|
||||
0xEC 0x2718 #
|
||||
0xED 0x25C6 #
|
||||
0xEE 0xF15D #
|
||||
0xEF 0xF15E #
|
||||
0xF0 0xF071 #
|
||||
0xF1 0xF449 #
|
||||
0xF2 0xF529 #
|
||||
0xF3 0xF658 #
|
||||
0xF4 0xF659 #
|
||||
0xF5 0x0020 #
|
||||
0xF6 0x1f381 # Space
|
||||
0xF7 0xf05a # Space
|
||||
0xF8 0xf06a # Space
|
||||
0xF9 0xf834 # Space
|
||||
0xFA 0xf835 # Space
|
||||
0xFB 0x2690 # Space
|
||||
0xFC 0x2691 # Space
|
||||
0xFD 0xf8d7 # Space
|
||||
0xFE 0xf0e7 # Space
|
||||
0xFF 0xf7d9 # Space
|
||||
|
|
|
@ -24,13 +24,13 @@ fn main() {
|
|||
let rom = MemMappedDevice::new(0xE000, 0xFFFF, 4, "rom".into());
|
||||
let mut memory = Mem::new(ram);
|
||||
if let Err(error) = memory.add_area(control) {
|
||||
println!("Error adding vram: {:?}", error);
|
||||
println!("Error adding vram: {:?}", error.desc);
|
||||
};
|
||||
if let Err(error) = memory.add_area(vram) {
|
||||
println!("Error adding vram: {:?}", error);
|
||||
println!("Error adding vram: {:?}", error.desc);
|
||||
};
|
||||
if let Err(error) = memory.add_area(rom) {
|
||||
println!("Error adding rom: {:?}", error);
|
||||
println!("Error adding rom: {:?}", error.desc);
|
||||
};
|
||||
let binary = match std::fs::File::open(PathBuf::from(
|
||||
"/Users/kline/projects/winter/george-emu/src/george",
|
||||
|
|
|
@ -59,10 +59,16 @@ impl Mem {
|
|||
pub fn new(area: MemMappedDevice) -> Self {
|
||||
Self { areas: vec![area] }
|
||||
}
|
||||
pub fn add_area(&mut self, area: MemMappedDevice) -> Result<(), MappingError> {
|
||||
pub fn add_area(&mut self, area: MemMappedDevice) -> Result<(), GeorgeError> {
|
||||
for existing_area in &self.areas {
|
||||
if existing_area.contains(area.end) || existing_area.contains(area.start) {
|
||||
return Err(MappingError::RegionOccupied);
|
||||
return Err(GeorgeError {
|
||||
desc: format!(
|
||||
"Tried to assign an area already allocated to {:?}",
|
||||
existing_area
|
||||
),
|
||||
kind: GeorgeErrorKind::Mapping(MappingError::RegionOccupied),
|
||||
});
|
||||
}
|
||||
}
|
||||
self.areas.push(area);
|
||||
|
|
103
src/video.rs
103
src/video.rs
|
@ -1,27 +1,111 @@
|
|||
use crate::Mem;
|
||||
use crate::{memory, Mem};
|
||||
use minifb::{Window, WindowOptions};
|
||||
use std::{
|
||||
sync::{Arc, RwLock},
|
||||
char,
|
||||
fs::File,
|
||||
io::Read,
|
||||
process::exit,
|
||||
sync::{Arc, RwLock, RwLockReadGuard},
|
||||
thread::sleep,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
const FG_COLOR: u32 = 0xFFCC00;
|
||||
//const BG_COLOR: u32 = 0x110500;
|
||||
const BG_COLOR: u32 = 0x22BB00;
|
||||
|
||||
pub struct Crtc {
|
||||
memory: Arc<RwLock<Mem>>,
|
||||
buffer: Vec<u32>,
|
||||
window: minifb::Window,
|
||||
char_rom: Vec<u8>,
|
||||
}
|
||||
|
||||
pub fn get_char_bin(path: &str) -> Vec<u8> {
|
||||
let mut file = File::open(path).unwrap();
|
||||
let mut buffer = vec![0; 0xFFFF];
|
||||
file.read_exact(&mut buffer).unwrap();
|
||||
buffer
|
||||
}
|
||||
|
||||
impl Crtc {
|
||||
pub fn new(memory: Arc<RwLock<Mem>>) -> Self {
|
||||
let window = Window::new("screen", 512, 380, WindowOptions::default()).unwrap();
|
||||
let char_rom = get_char_bin("./src/cozette.bin");
|
||||
Self {
|
||||
memory,
|
||||
buffer: vec![0; 512 * 380],
|
||||
window,
|
||||
char_rom,
|
||||
}
|
||||
}
|
||||
fn draw(&mut self) {
|
||||
match &mut self.memory.clone().try_read() {
|
||||
Ok(memory) => {
|
||||
let hw_ctrl = memory.read(0x4000).unwrap();
|
||||
match hw_ctrl & 0b0000_1000 == 0b0000_1000 {
|
||||
false => self.draw_chars(),
|
||||
true => self.draw_hires(),
|
||||
};
|
||||
}
|
||||
Err(_) => {
|
||||
println!("Couldn't acquire read on shared memory in main thread");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
self.window
|
||||
.update_with_buffer(&self.buffer, 512, 380)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
fn draw_chars(&mut self) {
|
||||
let memory = match self.memory.try_read() {
|
||||
Ok(read) => read,
|
||||
Err(_) => {
|
||||
println!("Couldn't acquire read on shared memory in main thread");
|
||||
return;
|
||||
}
|
||||
};
|
||||
for char_col in 0..65 {
|
||||
let pixel_col = char_col * 8;
|
||||
for char_row in 0..30 {
|
||||
let pixel_row = char_row * 13;
|
||||
for row in 0..13 {
|
||||
for i in 0..8 {
|
||||
let address: usize = ((pixel_col * pixel_row + row * 13) + i) * 8;
|
||||
self.buffer[address] = BG_COLOR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//for char_col in 0..64 {
|
||||
// for char_row in 0..29 {
|
||||
// let ascii = memory.read(0x6000 + char_row * char_col).unwrap();
|
||||
// for row in 0..13 {
|
||||
// for char in 0..=255 {
|
||||
// if ascii == char {
|
||||
// let byte = self.char_rom[char as usize + (row * 0xFF)];
|
||||
// for i in 0..8 {
|
||||
// let address: usize = ((char_col as usize * 64 + (8 * i))
|
||||
// + (char_row as usize + (13 * row) * 29))
|
||||
// * 8
|
||||
// + i;
|
||||
// if (byte >> i) & 0b1 == 1 {
|
||||
// self.buffer[address] = FG_COLOR;
|
||||
// } else {
|
||||
// self.buffer[address] = BG_COLOR;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
println!("{:?}", self.buffer);
|
||||
//exit(0);
|
||||
}
|
||||
fn draw_hires(&mut self) {
|
||||
let memory = match self.memory.try_read() {
|
||||
Ok(read) => read,
|
||||
Err(_) => {
|
||||
|
@ -29,24 +113,17 @@ impl Crtc {
|
|||
return;
|
||||
}
|
||||
};
|
||||
// let bitmask = [128, 64, 32, 16, 8, 4, 2, 1];
|
||||
let bitmask = [1, 2, 4, 8, 16, 32, 64, 128]; // I think this is how the bytes will be
|
||||
// serialized? low bits first?
|
||||
|
||||
for addr in 0x6000..0xBF00 {
|
||||
// TODO: eventually this will access memory in the weird interleaved way the hardware is
|
||||
// designed, but this is easiest to implement for now
|
||||
let byte = memory.read(addr).unwrap();
|
||||
for (i, mask) in bitmask.iter().enumerate() {
|
||||
match byte & mask == 0 {
|
||||
true => self.buffer[(addr - 0x6000) as usize * 8 + i] = 0x110500,
|
||||
false => self.buffer[(addr - 0x6000) as usize * 8 + i] = 0xFFCC00,
|
||||
for i in 0..8 {
|
||||
match byte & 0x80 >> i == 0 {
|
||||
true => self.buffer[(addr - 0x6000) as usize * 8 + i] = BG_COLOR,
|
||||
false => self.buffer[(addr - 0x6000) as usize * 8 + i] = FG_COLOR,
|
||||
}
|
||||
}
|
||||
}
|
||||
self.window
|
||||
.update_with_buffer(&self.buffer, 512, 380)
|
||||
.unwrap();
|
||||
}
|
||||
pub fn run(&mut self) {
|
||||
let frame_duration = Duration::from_millis(16);
|
||||
|
|
Loading…
Reference in New Issue