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)]
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<MemArea>,
areas: Vec<MemMappedDevice>,
}
#[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,19 +255,19 @@ impl Cpu {
unimplemented!()
}
//fn handle_interrupt(&mut self) -> Result<(), ExecutionError> {
// fn handle_interrupt(&mut self) -> Result<(), ExecutionError> {
// match self.get_flag(StatusFlag::IrqDisable) {
// // Check that interrupts aren't disabled
// true => Err(ExecutionError::InterruptsDisabled),
// true => Ok(self.execute()),
// false => {
// if self.irq {
// let irq_vector = 0xFFFC;
// 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) => self.execute(opcode),
// Ok(_opcode) => Ok(self.execute()),
// Err(error) => Err(ExecutionError::MemoryError(error)),
// }
// }
@ -273,7 +277,7 @@ impl Cpu {
// }
// }
// }
//}
// }
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(_) => {}
};