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