diff --git a/src/george b/src/george new file mode 100644 index 0000000..6abc380 Binary files /dev/null and b/src/george differ diff --git a/src/george.asm b/src/george.asm new file mode 100644 index 0000000..0fca809 --- /dev/null +++ b/src/george.asm @@ -0,0 +1,6 @@ +.setcpu "65C02" +.segment "CODE" + LDA #$25 + LDY #$25 + STY $2000 + ADC $2000 diff --git a/src/george.config b/src/george.config new file mode 100644 index 0000000..622cd4d --- /dev/null +++ b/src/george.config @@ -0,0 +1,10 @@ +MEMORY { + RAM: start = $0000, size = $4000, type = rw, fill = true; + CTRL: start = $4000, size = $2000, type = rw, fill = true; + VRAM: start = $6000, size = $8000, type = rw, fill = true; + ROM: start = $E000, size = $2000, type = ro, fill = true; + } + +SEGMENTS { + CODE: load = "RAM", type = rw; + } diff --git a/src/main.rs b/src/main.rs index a762028..8698927 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ #![allow(dead_code)] +use core::panic; use std::{ collections::HashMap, fs::{self, File}, @@ -13,7 +14,7 @@ type Byte = u8; type Word = u16; #[derive(Debug)] -struct MemArea { +struct MemMappedDevice { start: Word, end: Word, pages: usize, @@ -22,19 +23,19 @@ struct MemArea { label: String, } -impl MemArea { +impl MemMappedDevice { fn new(start: Word, end: Word, pages: usize, label: String) -> Self { Self { start, end, pages, page: 0, - data: vec![0x00; end as usize - start as usize], + data: vec![0x00; (end as usize + 1 - start as usize) * pages], label, } } fn contains(&self, address: Word) -> bool { - self.start <= address && self.end > address + self.start <= address && self.end >= address } fn swap_page(&mut self, page: usize) -> Result<(), MappingError> { match page > self.pages { @@ -45,15 +46,18 @@ impl MemArea { } } } + fn size(&self) -> Word { + self.end - self.start + 1 + } fn translate_address(&self, address: Word) -> Word { - address - self.start + (address - self.start) + self.size() * (self.page as Word) } // This needs to translate memory address from CPU land to local land, so // for rom an address like 0xFFFF needs to be translated to Page X, 0xFFF } #[derive(Debug)] struct Mem { - areas: Vec, + areas: Vec, } #[derive(Debug)] @@ -70,10 +74,10 @@ enum MappingError { } impl Mem { - fn new(area: MemArea) -> Self { + fn new(area: MemMappedDevice) -> Self { Self { areas: vec![area] } } - fn add_area(&mut self, area: MemArea) -> Result<(), MappingError> { + fn add_area(&mut self, area: MemMappedDevice) -> Result<(), MappingError> { for existing_area in &self.areas { if existing_area.contains(area.end) || existing_area.contains(area.start) { return Err(MappingError::RegionOccupied); @@ -107,7 +111,7 @@ impl Mem { Err(MemoryError::Unmapped) } - fn from_bin(&mut self, f: File) -> Result<(), MemoryError> { + fn read_from_bin(&mut self, f: File) -> Result<(), MemoryError> { let bytes = f.bytes(); for (address, byte) in bytes.enumerate() { match byte { @@ -251,29 +255,29 @@ impl Cpu { unimplemented!() } - //fn handle_interrupt(&mut self) -> Result<(), ExecutionError> { - // match self.get_flag(StatusFlag::IrqDisable) { - // // Check that interrupts aren't disabled - // true => Err(ExecutionError::InterruptsDisabled), - // false => { - // if self.irq { - // let irq_vector = 0xFFFC; - // match self.read_word(irq_vector) { - // Err(error) => Err(ExecutionError::MemoryError(error)), - // Ok(address) => { - // let isr_address = address; - // match self.read(isr_address) { - // Ok(opcode) => self.execute(opcode), - // Err(error) => Err(ExecutionError::MemoryError(error)), - // } - // } - // } - // } else { - // Ok(()) - // } - // } - // } - //} + // fn handle_interrupt(&mut self) -> Result<(), ExecutionError> { + // match self.get_flag(StatusFlag::IrqDisable) { + // // Check that interrupts aren't disabled + // true => Ok(self.execute()), + // false => { + // if self.irq { + // let irq_vector = 0xFFFE; + // match self.read_word(irq_vector) { + // Err(error) => Err(ExecutionError::MemoryError(error)), + // Ok(address) => { + // let isr_address = address; + // match self.read(isr_address) { + // Ok(_opcode) => Ok(self.execute()), + // Err(error) => Err(ExecutionError::MemoryError(error)), + // } + // } + // } + // } else { + // Ok(()) + // } + // } + // } + // } fn stop(&mut self) { unimplemented!() } @@ -309,7 +313,10 @@ impl Cpu { let instruction = get_instruction(opcode); match instruction { Instruction::Valid(valid_instruction) => { - println!("accumulator: {a:#04x}, x: {x:#04x}, y: {y:#04x}, program counter: {pc:#06x}, stack pointer: {s:#04x}, status register: {p:#04x}, irq pin: {irq:?}, nmi pin: {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: {:?}", valid_instruction.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(_) => { self.pending_cycles += valid_instruction.cycles as usize; @@ -394,7 +401,7 @@ fn get_instruction(opcode: u8) -> Instruction { ( 0x00, Instruction::Valid(ValidInstruction { - opcode: Opcode::BRK(AddressingMode::Stack), + opcode: Opcode::BRK(AddressingMode::Implied), cycles: 7, }), ), @@ -2648,7 +2655,7 @@ impl Opcode { Opcode::BRK(mode) => match mode { AddressingMode::Implied => { cpu.set_flag(StatusFlag::Brk, true); - Ok(()) + panic!("Interrupts unimplemented!"); } _ => Err(ExecutionError::IncompatibleAddrMode), }, @@ -3417,10 +3424,10 @@ impl Opcode { } fn main() { - let ram = MemArea::new(0x0000, 0x3FFF, 2, "ram".into()); - let control = MemArea::new(0x4000, 0x5FFF, 4, "rom".into()); - let vram = MemArea::new(0x6000, 0xDFFF, 1, "vram".into()); - let rom = MemArea::new(0xE000, 0xFFFF, 4, "rom".into()); + let ram = MemMappedDevice::new(0x0000, 0x3FFF, 2, "ram".into()); + let control = MemMappedDevice::new(0x4000, 0x5FFF, 4, "control".into()); + let vram = MemMappedDevice::new(0x6000, 0xDFFF, 1, "vram".into()); + let rom = MemMappedDevice::new(0xE000, 0xFFFF, 4, "rom".into()); let mut memory = Mem::new(ram); match memory.add_area(control) { Err(error) => println!("Error adding vram: {:?}", error), @@ -3435,12 +3442,12 @@ fn main() { Ok(()) => {} }; let binary = match fs::File::open(PathBuf::from( - "/Users/kline/projects/winter/georgeemu/src/george.bin", + "/Users/kline/projects/winter/georgeemu/src/george", )) { Ok(file) => file, Err(error) => panic!("Couldn't open binary file! {:?}", error), }; - match memory.from_bin(binary) { + match memory.read_from_bin(binary) { Err(error) => println!("{:?}", error), Ok(_) => {} };