Added george binary, asm, and memory config for ld65
This commit is contained in:
parent
8422925312
commit
e69a79b5a4
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;
|
||||||
|
}
|
49
src/main.rs
49
src/main.rs
|
@ -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 {
|
||||||
|
@ -254,16 +258,16 @@ impl Cpu {
|
||||||
// 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)),
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
@ -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(_) => {}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue