Added george binary, asm, and memory config for ld65
This commit is contained in:
parent
17b399f98b
commit
b9edce9bbd
Binary file not shown.
|
@ -0,0 +1,6 @@
|
|||
.setcpu "65C02"
|
||||
.segment "CODE"
|
||||
LDA #$25
|
||||
LDY #$25
|
||||
STY $2000
|
||||
ADC $2000
|
|
@ -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;
|
||||
}
|
89
src/main.rs
89
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<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,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(_) => {}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue