Compare commits

..

No commits in common. "5b9312f6431523caacd47f5e14a9168a9bc3c21d" and "78dad90fc9c896e908b6fa298e171483e4c84f80" have entirely different histories.

13 changed files with 98 additions and 281 deletions

86
Cargo.lock generated
View File

@ -8,31 +8,6 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 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]] [[package]]
name = "bitflags" name = "bitflags"
version = "1.3.2" version = "1.3.2"
@ -45,18 +20,6 @@ version = "2.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" 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]] [[package]]
name = "bumpalo" name = "bumpalo"
version = "3.14.0" version = "3.14.0"
@ -115,12 +78,6 @@ version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
[[package]]
name = "funty"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
[[package]] [[package]]
name = "futures" name = "futures"
version = "0.3.30" version = "0.3.30"
@ -214,8 +171,6 @@ dependencies = [
name = "georgeemu" name = "georgeemu"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"bdf",
"bitvec",
"minifb", "minifb",
] ]
@ -392,12 +347,6 @@ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]]
name = "radium"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
[[package]] [[package]]
name = "raw-window-handle" name = "raw-window-handle"
version = "0.4.3" version = "0.4.3"
@ -504,12 +453,6 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "tap"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
[[package]] [[package]]
name = "tempfile" name = "tempfile"
version = "3.9.0" version = "3.9.0"
@ -523,26 +466,6 @@ dependencies = [
"windows-sys 0.52.0", "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]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.12" version = "1.0.12"
@ -858,15 +781,6 @@ version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
[[package]]
name = "wyz"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed"
dependencies = [
"tap",
]
[[package]] [[package]]
name = "x11-dl" name = "x11-dl"
version = "2.21.0" version = "2.21.0"

View File

@ -6,6 +6,4 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
bdf = "0.6.0"
bitvec = "1.0.1"
minifb = "0.25.0" minifb = "0.25.0"

Binary file not shown.

View File

@ -53,8 +53,8 @@ impl Cpu {
} }
pub fn reset(&mut self) -> Result<(), ExecutionError> { pub fn reset(&mut self) -> Result<(), ExecutionError> {
let reset_vector_pointer = self.read_word(0xFFFC)?; let reset_vector_pointer = self.read_word(0xFFFC)?;
self.pc = reset_vector_pointer;
self.pending_cycles = 8; self.pending_cycles = 8;
self.pc = reset_vector_pointer;
Ok(()) Ok(())
} }
pub fn read(&self, address: Word) -> Result<Byte, MemoryError> { pub fn read(&self, address: Word) -> Result<Byte, MemoryError> {
@ -212,11 +212,8 @@ impl Cpu {
let instruction = get_instruction(opcode); let instruction = get_instruction(opcode);
match instruction { match instruction {
Instruction::Valid(valid_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!("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!(
"Instruction: {:?}, {:#04x}",
valid_instruction.opcode, opcode
);
println!(""); println!("");
self.pc += 1; self.pc += 1;
match valid_instruction.opcode.call(self) { match valid_instruction.opcode.call(self) {

View File

@ -3,7 +3,6 @@ pub enum GeorgeErrorKind {
Memory(MemoryError), Memory(MemoryError),
Execution(ExecutionError), Execution(ExecutionError),
AddrMode(AddressingModeError), AddrMode(AddressingModeError),
Mapping(MappingError),
} }
impl From<MemoryError> for GeorgeErrorKind { impl From<MemoryError> for GeorgeErrorKind {

Binary file not shown.

View File

@ -1,25 +1,9 @@
.setcpu "65C02" .setcpu "65C02"
.segment "CODE" .segment "CODE"
LDA #$60
STA $01
LDY #$0
fill:
LDA #$20
STY $00
STA ($00)
INY
CPY #$ff
BNE fill
main: main:
LDY #$0 LDA #$25
STY $6000 LDY #$2F
LDY #$1 STY $7000
STY $6001 STY $7001
LDY #$2 STY $7002
STY $6002
LDY #$1
STY $6003
LDY #$3
STY $6004
JMP main JMP main

View File

@ -1,11 +1,10 @@
MEMORY { MEMORY {
RAM: start = $0000, size = $0200, type = rw, fill = true; RAM: start = $0000, size = $4000, type = rw, fill = true;
PROGRAM: start = $0200, size = $3E00, type = rw, fill = true;
CTRL: start = $4000, size = $2000, type = rw, fill = true; CTRL: start = $4000, size = $2000, type = rw, fill = true;
VRAM: start = $6000, size = $8000, type = rw, fill = true; VRAM: start = $6000, size = $8000, type = rw, fill = true;
ROM: start = $E000, size = $2000, type = ro, fill = true; ROM: start = $E000, size = $2000, type = ro, fill = true;
} }
SEGMENTS { SEGMENTS {
CODE: load = "PROGRAM", type = rw; CODE: load = "RAM", type = rw;
} }

View File

@ -8,7 +8,7 @@
# column #3 the Unicode name (follows a comment sign, '#') # column #3 the Unicode name (follows a comment sign, '#')
0x00 0x0295 # ʕ 0x00 0x0295 # ʕ
0x01 0x00B7 # Middle Dot 0x01 0x0097 # Middle Dot
0x02 0x1D25 # ᴥ 0x02 0x1D25 # ᴥ
0x03 0x0294 # ʔ 0x03 0x0294 # ʔ
0x04 0x2661 # White heart 0x04 0x2661 # White heart
@ -27,18 +27,18 @@
0x11 0x266A # Eighth note 0x11 0x266A # Eighth note
0x12 0x266B # Beamed eighth notes 0x12 0x266B # Beamed eighth notes
0x13 0x266C # Beamed sixteenth notes 0x13 0x266C # Beamed sixteenth notes
0x14 0xFC5D # 0x14 0x0020 #
0x15 0xF026 # 0x15 0x0020 #
0x16 0xF027 # 0x16 0x0020 #
0x17 0xF028 # 0x17 0x0020 #
0x18 0xFA7E # 0x18 0x0020 #
0x19 0xFA7F # 0x19 0x0020 #
0x1A 0xFA80 # 0x1A 0x0020 #
0x1B 0xFC5C # 0x1B 0x0020 #
0x1C 0xFC5B # 0x1C 0x0020 #
0x1D 0xF0AC # 0x1D 0x0020 #
0x1E 0xF04B # 0x1E 0x0020 #
0x1F 0xF04D # 0x1F 0x0020 #
0x20 0x0020 # SPACE 0x20 0x0020 # SPACE
0x21 0x0021 # EXCLAMATION MARK 0x21 0x0021 # EXCLAMATION MARK
0x22 0x0022 # QUOTATION MARK 0x22 0x0022 # QUOTATION MARK
@ -161,11 +161,11 @@
0x97 0x2566 # 0x97 0x2566 #
0x98 0x2569 # 0x98 0x2569 #
0x99 0x256C # 0x99 0x256C #
0x9A 0xF04E # 0x9A 0x0020 #
0x9B 0xF050 # 0x9B 0x0020 #
0x9C 0xF051 # 0x9C 0x0020 #
0x9D 0xF052 # 0x9D 0x0020 #
0x9E 0xF048 # 0x9E 0x0020 #
0x9F 0xE0B0 # 0x9F 0xE0B0 #
0xA0 0xE0B2 # 0xA0 0xE0B2 #
0xA1 0xE0B4 # 0xA1 0xE0B4 #
@ -214,52 +214,52 @@
0xCC 0x2B81 # 0xCC 0x2B81 #
0xCD 0x2B82 # 0xCD 0x2B82 #
0xCE 0x2B83 # 0xCE 0x2B83 #
0xCF 0xF049 # 0xCF 0x0020 #
0xD0 0xF04A # 0xD0 0x0020 #
0xD1 0x23F3 # 0xD1 0x0020 #
0xD2 0xF07B # 0xD2 0x0020 #
0xD3 0xF07C # 0xD3 0x0020 #
0xD4 0xF114 # 0xD4 0x0020 #
0xD5 0xF115 # 0xD5 0x0020 #
0xD6 0xF250 # 0xD6 0x0020 #
0xD7 0xF251 # 0xD7 0x0020 #
0xD8 0xF253 # 0xD8 0x0020 #
0xD9 0xF254 # 0xD9 0x0020 #
0xDA 0xF461 # 0xDA 0x0020 #
0xDB 0xF016 # 0xDB 0x0020 #
0xDC 0xF401 # 0xDC 0x0020 #
0xDD 0x1F52E # 0xDD 0x0020 #
0xDE 0xF2DB # 0xDE 0x0020 #
0xDF 0xF008 # 0xDF 0x0020 #
0xE0 0x25C7 # 0xE0 0x0020 #
0xE1 0x25C8 # 0xE1 0x0020 #
0xE2 0x1F311 # 0xE2 0x0020 #
0xE3 0x1F312 # 0xE3 0x0020 #
0xE4 0x1F313 # 0xE4 0x0020 #
0xE5 0x1F314 # 0xE5 0x0020 #
0xE6 0x1F315 # 0xE6 0x0020 #
0xE7 0x1F316 # 0xE7 0x0020 #
0xE8 0x1F317 # 0xE8 0x0020 #
0xE9 0x1F318 # 0xE9 0x0020 #
0xEA 0xF04C # 0xEA 0x0020 #
0xEB 0x2714 # 0xEB 0x0020 #
0xEC 0x2718 # 0xEC 0x0020 #
0xED 0x25C6 # 0xED 0x0020 #
0xEE 0xF15D # 0xEE 0x0020 #
0xEF 0xF15E # 0xEF 0x0020 #
0xF0 0xF071 # 0xF0 0x0020 #
0xF1 0xF449 # 0xF1 0x0020 #
0xF2 0xF529 # 0xF2 0x0020 #
0xF3 0xF658 # 0xF3 0x0020 #
0xF4 0xF659 # 0xF4 0x0020 #
0xF5 0x0020 # 0xF5 0x0020 #
0xF6 0x1f381 # Space 0xF6 0x0020 #
0xF7 0xf05a # Space 0xF7 0x0020 #
0xF8 0xf06a # Space 0xF8 0x0020 #
0xF9 0xf834 # Space 0xF9 0x0020 #
0xFA 0xf835 # Space 0xFA 0x0020 #
0xFB 0x2690 # Space 0xFB 0x0020 #
0xFC 0x2691 # Space 0xFC 0x0020 #
0xFD 0xf8d7 # Space 0xFD 0x0020 #
0xFE 0xf0e7 # Space 0xFE 0x0020 #
0xFF 0xf7d9 # Space 0xFF 0x0020 #

View File

@ -1870,7 +1870,7 @@ fn get_address(
fn zero_page(cpu: &mut Cpu) -> Result<AddressingModeValue, ExecutionError> { fn zero_page(cpu: &mut Cpu) -> Result<AddressingModeValue, ExecutionError> {
// zp // zp
let address = cpu.read(cpu.pc)?; let address = cpu.read(cpu.pc)?;
cpu.pc += 1; cpu.pc += 2;
Ok(AddressingModeValue::Absolute(address as Word)) Ok(AddressingModeValue::Absolute(address as Word))
} }
@ -1934,16 +1934,6 @@ fn get_address(
Ok(AddressingModeValue::Absolute(address)) Ok(AddressingModeValue::Absolute(address))
} }
fn zero_page_indirect(
// (zp)
cpu: &mut Cpu,
) -> Result<AddressingModeValue, ExecutionError> {
let byte: Byte = cpu.read(cpu.pc)?;
let address: Word = cpu.read_word(byte as Word)?;
cpu.pc += 1;
Ok(AddressingModeValue::Absolute(address as Word))
}
fn zero_page_indexed_indirect( fn zero_page_indexed_indirect(
// (zp, x) // (zp, x)
cpu: &mut Cpu, cpu: &mut Cpu,
@ -1995,7 +1985,7 @@ fn get_address(
AddressingMode::ZeroPage => zero_page(cpu), AddressingMode::ZeroPage => zero_page(cpu),
AddressingMode::ZeroPageIndexedWithX => zero_page_indexed_with_x(cpu), AddressingMode::ZeroPageIndexedWithX => zero_page_indexed_with_x(cpu),
AddressingMode::ZeroPageIndexedWithY => zero_page_indexed_with_y(cpu), AddressingMode::ZeroPageIndexedWithY => zero_page_indexed_with_y(cpu),
AddressingMode::ZeroPageIndirect => zero_page_indirect(cpu), AddressingMode::ZeroPageIndirect => todo!(),
AddressingMode::ZeroPageIndexedIndirect => zero_page_indexed_indirect(cpu), AddressingMode::ZeroPageIndexedIndirect => zero_page_indexed_indirect(cpu),
AddressingMode::ZeroPageIndirectIndexedWithY => zero_page_indirect_indexed_with_y(cpu), AddressingMode::ZeroPageIndirectIndexedWithY => zero_page_indirect_indexed_with_y(cpu),
AddressingMode::Accumulator => Ok(accumulator(cpu)), AddressingMode::Accumulator => Ok(accumulator(cpu)),
@ -2635,10 +2625,9 @@ impl Opcode {
| AddressingMode::AbsoluteA => { | AddressingMode::AbsoluteA => {
let address = get_address(mode, cpu)?; let address = get_address(mode, cpu)?;
let byte = cpu.read(address.try_into()?)?; let byte = cpu.read(address.try_into()?)?;
println!("{byte:#04x}");
cpu.set_flag(StatusFlag::Carry, cpu.y >= byte); cpu.set_flag(StatusFlag::Carry, cpu.y >= byte);
cpu.set_flag(StatusFlag::Zero, cpu.y == byte); cpu.set_flag(StatusFlag::Zero, cpu.y == byte);
cpu.set_flag(StatusFlag::Negative, cpu.y <= byte); cpu.set_flag(StatusFlag::Negative, cpu.is_negative(cpu.y - byte));
Ok(()) Ok(())
} }
_ => Err(GeorgeErrorKind::AddrMode( _ => Err(GeorgeErrorKind::AddrMode(
@ -2709,9 +2698,9 @@ impl Opcode {
| AddressingMode::AbsoluteIndexedWithX => { | AddressingMode::AbsoluteIndexedWithX => {
let address = get_address(mode, cpu)?; let address = get_address(mode, cpu)?;
let byte = cpu.read(address.try_into()?)?; let byte = cpu.read(address.try_into()?)?;
cpu.set_flag(StatusFlag::Zero, byte.wrapping_add(1) == 0); cpu.set_flag(StatusFlag::Zero, byte + 1 == 0);
cpu.set_flag(StatusFlag::Negative, cpu.is_negative(byte.wrapping_add(1))); cpu.set_flag(StatusFlag::Negative, cpu.is_negative(byte + 1));
cpu.write(address.try_into()?, byte.wrapping_add(1))?; cpu.write(address.try_into()?, byte + 1)?;
Ok(()) Ok(())
} }
_ => Err(GeorgeErrorKind::AddrMode( _ => Err(GeorgeErrorKind::AddrMode(

View File

@ -24,13 +24,13 @@ fn main() {
let rom = MemMappedDevice::new(0xE000, 0xFFFF, 4, "rom".into()); let rom = MemMappedDevice::new(0xE000, 0xFFFF, 4, "rom".into());
let mut memory = Mem::new(ram); let mut memory = Mem::new(ram);
if let Err(error) = memory.add_area(control) { if let Err(error) = memory.add_area(control) {
println!("Error adding vram: {:?}", error.desc); println!("Error adding vram: {:?}", error);
}; };
if let Err(error) = memory.add_area(vram) { if let Err(error) = memory.add_area(vram) {
println!("Error adding vram: {:?}", error.desc); println!("Error adding vram: {:?}", error);
}; };
if let Err(error) = memory.add_area(rom) { if let Err(error) = memory.add_area(rom) {
println!("Error adding rom: {:?}", error.desc); println!("Error adding rom: {:?}", error);
}; };
let binary = match std::fs::File::open(PathBuf::from( let binary = match std::fs::File::open(PathBuf::from(
"/Users/kline/projects/winter/george-emu/src/george", "/Users/kline/projects/winter/george-emu/src/george",
@ -41,8 +41,6 @@ fn main() {
if let Err(error) = memory.read_from_bin(binary) { if let Err(error) = memory.read_from_bin(binary) {
println!("{:?}", error); println!("{:?}", error);
}; };
memory.write(0xFFFC, 0x00).unwrap();
memory.write(0xFFFD, 0x02).unwrap();
let shared_memory = Arc::new(RwLock::new(memory)); let shared_memory = Arc::new(RwLock::new(memory));
let cpu_memory = shared_memory.clone(); let cpu_memory = shared_memory.clone();

View File

@ -59,16 +59,10 @@ impl Mem {
pub fn new(area: MemMappedDevice) -> Self { pub fn new(area: MemMappedDevice) -> Self {
Self { areas: vec![area] } Self { areas: vec![area] }
} }
pub fn add_area(&mut self, area: MemMappedDevice) -> Result<(), GeorgeError> { pub fn add_area(&mut self, area: MemMappedDevice) -> Result<(), MappingError> {
for existing_area in &self.areas { for existing_area in &self.areas {
if existing_area.contains(area.end) || existing_area.contains(area.start) { if existing_area.contains(area.end) || existing_area.contains(area.start) {
return Err(GeorgeError { return Err(MappingError::RegionOccupied);
desc: format!(
"Tried to assign an area already allocated to {:?}",
existing_area
),
kind: GeorgeErrorKind::Mapping(MappingError::RegionOccupied),
});
} }
} }
self.areas.push(area); self.areas.push(area);

View File

@ -1,89 +1,27 @@
use crate::Mem; use crate::Mem;
use minifb::{Window, WindowOptions}; use minifb::{Window, WindowOptions};
use std::{ use std::{
fs::File,
io::Read,
sync::{Arc, RwLock}, sync::{Arc, RwLock},
thread::sleep, thread::sleep,
time::{Duration, Instant}, time::{Duration, Instant},
}; };
const FG_COLOR: u32 = 0xFFCC00;
const BG_COLOR: u32 = 0x110500;
pub struct Crtc { pub struct Crtc {
memory: Arc<RwLock<Mem>>, memory: Arc<RwLock<Mem>>,
buffer: Vec<u32>, buffer: Vec<u32>,
window: minifb::Window, 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 { impl Crtc {
pub fn new(memory: Arc<RwLock<Mem>>) -> Self { pub fn new(memory: Arc<RwLock<Mem>>) -> Self {
let window = Window::new("screen", 512, 380, WindowOptions::default()).unwrap(); let window = Window::new("screen", 512, 380, WindowOptions::default()).unwrap();
let char_rom = get_char_bin("./src/cozette.bin");
Self { Self {
memory, memory,
buffer: vec![0; 512 * 380], buffer: vec![0; 512 * 380],
window, window,
char_rom,
} }
} }
fn draw(&mut self) { 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_row in 0..29 {
for char_col in 0..64 {
let ascii = memory
.read(0x6000 + (char_row as u16 * char_col as u16))
.unwrap();
for row in 0..13 {
let byte = self.char_rom[ascii as usize + (row * 0x101)];
for i in (0..8).rev() {
let buffer_index = ((char_row) * 13 + (row)) * 512 + (char_col * 8 + i);
if (byte << i) & 0x80 == 0x80 {
self.buffer[buffer_index] = FG_COLOR;
} else {
self.buffer[buffer_index] = BG_COLOR;
}
}
}
}
}
}
fn draw_hires(&mut self) {
let memory = match self.memory.try_read() { let memory = match self.memory.try_read() {
Ok(read) => read, Ok(read) => read,
Err(_) => { Err(_) => {
@ -91,17 +29,24 @@ impl Crtc {
return; 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 { for addr in 0x6000..0xBF00 {
// TODO: eventually this will access memory in the weird interleaved way the hardware is // TODO: eventually this will access memory in the weird interleaved way the hardware is
// designed, but this is easiest to implement for now // designed, but this is easiest to implement for now
let byte = memory.read(addr).unwrap(); let byte = memory.read(addr).unwrap();
for i in 0..8 { for (i, mask) in bitmask.iter().enumerate() {
match byte & 0x80 >> i == 0 { match byte & mask == 0 {
true => self.buffer[(addr - 0x6000) as usize * 8 + i] = BG_COLOR, true => self.buffer[(addr - 0x6000) as usize * 8 + i] = 0x110500,
false => self.buffer[(addr - 0x6000) as usize * 8 + i] = FG_COLOR, false => self.buffer[(addr - 0x6000) as usize * 8 + i] = 0xFFCC00,
} }
} }
} }
self.window
.update_with_buffer(&self.buffer, 512, 380)
.unwrap();
} }
pub fn run(&mut self) { pub fn run(&mut self) {
let frame_duration = Duration::from_millis(16); let frame_duration = Duration::from_millis(16);