Added george binary, asm, and memory config for ld65

This commit is contained in:
august kline 2024-02-02 13:49:24 -05:00
parent 17b399f98b
commit b9edce9bbd
4 changed files with 64 additions and 41 deletions

BIN
src/george Normal file

Binary file not shown.

6
src/george.asm Normal file
View File

@ -0,0 +1,6 @@
.setcpu "65C02"
.segment "CODE"
LDA #$25
LDY #$25
STY $2000
ADC $2000

10
src/george.config Normal file
View File

@ -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;
}

View File

@ -1,4 +1,5 @@
#![allow(dead_code)] #![allow(dead_code)]
use core::panic;
use std::{ use std::{
collections::HashMap, collections::HashMap,
fs::{self, File}, fs::{self, File},
@ -13,7 +14,7 @@ type Byte = u8;
type Word = u16; type Word = u16;
#[derive(Debug)] #[derive(Debug)]
struct MemArea { struct MemMappedDevice {
start: Word, start: Word,
end: Word, end: Word,
pages: usize, pages: usize,
@ -22,19 +23,19 @@ struct MemArea {
label: String, label: String,
} }
impl MemArea { impl MemMappedDevice {
fn new(start: Word, end: Word, pages: usize, label: String) -> Self { fn new(start: Word, end: Word, pages: usize, label: String) -> Self {
Self { Self {
start, start,
end, end,
pages, pages,
page: 0, page: 0,
data: vec![0x00; end as usize - start as usize], data: vec![0x00; (end as usize + 1 - start as usize) * pages],
label, label,
} }
} }
fn contains(&self, address: Word) -> bool { 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> { fn swap_page(&mut self, page: usize) -> Result<(), MappingError> {
match page > self.pages { 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 { 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 } // 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 // for rom an address like 0xFFFF needs to be translated to Page X, 0xFFF
} }
#[derive(Debug)] #[derive(Debug)]
struct Mem { struct Mem {
areas: Vec<MemArea>, areas: Vec<MemMappedDevice>,
} }
#[derive(Debug)] #[derive(Debug)]
@ -70,10 +74,10 @@ enum MappingError {
} }
impl Mem { impl Mem {
fn new(area: MemArea) -> Self { fn new(area: MemMappedDevice) -> Self {
Self { areas: vec![area] } 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 { 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(MappingError::RegionOccupied); return Err(MappingError::RegionOccupied);
@ -107,7 +111,7 @@ impl Mem {
Err(MemoryError::Unmapped) 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(); let bytes = f.bytes();
for (address, byte) in bytes.enumerate() { for (address, byte) in bytes.enumerate() {
match byte { match byte {
@ -251,29 +255,29 @@ impl Cpu {
unimplemented!() unimplemented!()
} }
//fn handle_interrupt(&mut self) -> Result<(), ExecutionError> { // fn handle_interrupt(&mut self) -> Result<(), ExecutionError> {
// match self.get_flag(StatusFlag::IrqDisable) { // match self.get_flag(StatusFlag::IrqDisable) {
// // Check that interrupts aren't disabled // // Check that interrupts aren't disabled
// true => Err(ExecutionError::InterruptsDisabled), // true => Ok(self.execute()),
// false => { // false => {
// if self.irq { // if self.irq {
// let irq_vector = 0xFFFC; // let irq_vector = 0xFFFE;
// match self.read_word(irq_vector) { // match self.read_word(irq_vector) {
// Err(error) => Err(ExecutionError::MemoryError(error)), // Err(error) => Err(ExecutionError::MemoryError(error)),
// Ok(address) => { // Ok(address) => {
// let isr_address = address; // let isr_address = address;
// match self.read(isr_address) { // match self.read(isr_address) {
// Ok(opcode) => self.execute(opcode), // Ok(_opcode) => Ok(self.execute()),
// Err(error) => Err(ExecutionError::MemoryError(error)), // Err(error) => Err(ExecutionError::MemoryError(error)),
// } // }
// } // }
// } // }
// } else { // } else {
// Ok(()) // Ok(())
// } // }
// } // }
// } // }
//} // }
fn stop(&mut self) { fn stop(&mut self) {
unimplemented!() unimplemented!()
} }
@ -309,7 +313,10 @@ 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!("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) { match valid_instruction.opcode.call(self) {
Ok(_) => { Ok(_) => {
self.pending_cycles += valid_instruction.cycles as usize; self.pending_cycles += valid_instruction.cycles as usize;
@ -394,7 +401,7 @@ fn get_instruction(opcode: u8) -> Instruction {
( (
0x00, 0x00,
Instruction::Valid(ValidInstruction { Instruction::Valid(ValidInstruction {
opcode: Opcode::BRK(AddressingMode::Stack), opcode: Opcode::BRK(AddressingMode::Implied),
cycles: 7, cycles: 7,
}), }),
), ),
@ -2648,7 +2655,7 @@ impl Opcode {
Opcode::BRK(mode) => match mode { Opcode::BRK(mode) => match mode {
AddressingMode::Implied => { AddressingMode::Implied => {
cpu.set_flag(StatusFlag::Brk, true); cpu.set_flag(StatusFlag::Brk, true);
Ok(()) panic!("Interrupts unimplemented!");
} }
_ => Err(ExecutionError::IncompatibleAddrMode), _ => Err(ExecutionError::IncompatibleAddrMode),
}, },
@ -3417,10 +3424,10 @@ impl Opcode {
} }
fn main() { fn main() {
let ram = MemArea::new(0x0000, 0x3FFF, 2, "ram".into()); let ram = MemMappedDevice::new(0x0000, 0x3FFF, 2, "ram".into());
let control = MemArea::new(0x4000, 0x5FFF, 4, "rom".into()); let control = MemMappedDevice::new(0x4000, 0x5FFF, 4, "control".into());
let vram = MemArea::new(0x6000, 0xDFFF, 1, "vram".into()); let vram = MemMappedDevice::new(0x6000, 0xDFFF, 1, "vram".into());
let rom = MemArea::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);
match memory.add_area(control) { match memory.add_area(control) {
Err(error) => println!("Error adding vram: {:?}", error), Err(error) => println!("Error adding vram: {:?}", error),
@ -3435,12 +3442,12 @@ fn main() {
Ok(()) => {} Ok(()) => {}
}; };
let binary = match fs::File::open(PathBuf::from( 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, Ok(file) => file,
Err(error) => panic!("Couldn't open binary file! {:?}", error), Err(error) => panic!("Couldn't open binary file! {:?}", error),
}; };
match memory.from_bin(binary) { match memory.read_from_bin(binary) {
Err(error) => println!("{:?}", error), Err(error) => println!("{:?}", error),
Ok(_) => {} Ok(_) => {}
}; };