diff --git a/src/cozette.bin b/src/cozette.bin new file mode 100644 index 0000000..df64451 Binary files /dev/null and b/src/cozette.bin differ diff --git a/src/cpu.rs b/src/cpu.rs index 116069b..6048e36 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -53,8 +53,8 @@ impl Cpu { } pub fn reset(&mut self) -> Result<(), ExecutionError> { let reset_vector_pointer = self.read_word(0xFFFC)?; - self.pending_cycles = 8; self.pc = reset_vector_pointer; + self.pending_cycles = 8; Ok(()) } pub fn read(&self, address: Word) -> Result { @@ -212,9 +212,12 @@ impl Cpu { let instruction = get_instruction(opcode); match instruction { Instruction::Valid(valid_instruction) => { - //println!("Instruction: {:?}, {:?}", valid_instruction.opcode, 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!(""); + 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!( + "Instruction: {:?}, {:#04x}", + valid_instruction.opcode, opcode + ); + println!(""); self.pc += 1; match valid_instruction.opcode.call(self) { Ok(_) => { diff --git a/src/george b/src/george index 1ca1b4f..2e825e9 100644 Binary files a/src/george and b/src/george differ diff --git a/src/george.asm b/src/george.asm index 3914634..4672a97 100644 --- a/src/george.asm +++ b/src/george.asm @@ -1,11 +1,25 @@ .setcpu "65C02" .segment "CODE" -LDA #$0 -STA $4000 +LDA #$60 +STA $01 +LDY #$0 +fill: + LDA #$20 + STY $00 + STA ($00) + INY + CPY #$ff + BNE fill + main: - LDA #$25 - LDY #$2F - STY $7000 - STY $7001 - STY $7002 + LDY #$0 + STY $6000 + LDY #$1 + STY $6001 + LDY #$2 + STY $6002 + LDY #$1 + STY $6003 + LDY #$3 + STY $6004 JMP main diff --git a/src/george.config b/src/george.config index 622cd4d..7505a5e 100644 --- a/src/george.config +++ b/src/george.config @@ -1,10 +1,11 @@ MEMORY { - RAM: start = $0000, size = $4000, type = rw, fill = true; + RAM: start = $0000, size = $0200, type = rw, fill = true; + PROGRAM: start = $0200, size = $3E00, 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; + CODE: load = "PROGRAM", type = rw; } diff --git a/src/instructions.rs b/src/instructions.rs index e7a6493..14a77e2 100644 --- a/src/instructions.rs +++ b/src/instructions.rs @@ -1870,7 +1870,7 @@ fn get_address( fn zero_page(cpu: &mut Cpu) -> Result { // zp let address = cpu.read(cpu.pc)?; - cpu.pc += 2; + cpu.pc += 1; Ok(AddressingModeValue::Absolute(address as Word)) } @@ -1934,6 +1934,16 @@ fn get_address( Ok(AddressingModeValue::Absolute(address)) } + fn zero_page_indirect( + // (zp) + cpu: &mut Cpu, + ) -> Result { + let byte: Byte = cpu.read(cpu.pc)?; + let address: Word = cpu.read_word(byte as Word)?; + cpu.pc += 1; + Ok(AddressingModeValue::Absolute(address as Word)) + } + fn zero_page_indexed_indirect( // (zp, x) cpu: &mut Cpu, @@ -1985,7 +1995,7 @@ fn get_address( AddressingMode::ZeroPage => zero_page(cpu), AddressingMode::ZeroPageIndexedWithX => zero_page_indexed_with_x(cpu), AddressingMode::ZeroPageIndexedWithY => zero_page_indexed_with_y(cpu), - AddressingMode::ZeroPageIndirect => todo!(), + AddressingMode::ZeroPageIndirect => zero_page_indirect(cpu), AddressingMode::ZeroPageIndexedIndirect => zero_page_indexed_indirect(cpu), AddressingMode::ZeroPageIndirectIndexedWithY => zero_page_indirect_indexed_with_y(cpu), AddressingMode::Accumulator => Ok(accumulator(cpu)), @@ -2625,9 +2635,10 @@ impl Opcode { | AddressingMode::AbsoluteA => { let address = get_address(mode, cpu)?; let byte = cpu.read(address.try_into()?)?; + println!("{byte:#04x}"); cpu.set_flag(StatusFlag::Carry, cpu.y >= byte); cpu.set_flag(StatusFlag::Zero, cpu.y == byte); - cpu.set_flag(StatusFlag::Negative, cpu.is_negative(cpu.y - byte)); + cpu.set_flag(StatusFlag::Negative, cpu.y <= byte); Ok(()) } _ => Err(GeorgeErrorKind::AddrMode( @@ -2698,9 +2709,9 @@ impl Opcode { | AddressingMode::AbsoluteIndexedWithX => { let address = get_address(mode, cpu)?; let byte = cpu.read(address.try_into()?)?; - cpu.set_flag(StatusFlag::Zero, byte + 1 == 0); - cpu.set_flag(StatusFlag::Negative, cpu.is_negative(byte + 1)); - cpu.write(address.try_into()?, byte + 1)?; + cpu.set_flag(StatusFlag::Zero, byte.wrapping_add(1) == 0); + cpu.set_flag(StatusFlag::Negative, cpu.is_negative(byte.wrapping_add(1))); + cpu.write(address.try_into()?, byte.wrapping_add(1))?; Ok(()) } _ => Err(GeorgeErrorKind::AddrMode( diff --git a/src/main.rs b/src/main.rs index bd0d4c9..7b7c35c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -41,6 +41,8 @@ fn main() { if let Err(error) = memory.read_from_bin(binary) { println!("{:?}", error); }; + memory.write(0xFFFC, 0x00).unwrap(); + memory.write(0xFFFD, 0x02).unwrap(); let shared_memory = Arc::new(RwLock::new(memory)); let cpu_memory = shared_memory.clone(); diff --git a/src/video.rs b/src/video.rs index e996848..f5c5865 100644 --- a/src/video.rs +++ b/src/video.rs @@ -1,18 +1,15 @@ -use crate::{memory, Mem}; +use crate::Mem; use minifb::{Window, WindowOptions}; use std::{ - char, fs::File, io::Read, - process::exit, - sync::{Arc, RwLock, RwLockReadGuard}, + sync::{Arc, RwLock}, thread::sleep, time::{Duration, Instant}, }; const FG_COLOR: u32 = 0xFFCC00; -//const BG_COLOR: u32 = 0x110500; -const BG_COLOR: u32 = 0x22BB00; +const BG_COLOR: u32 = 0x110500; pub struct Crtc { memory: Arc>, @@ -67,43 +64,24 @@ impl Crtc { return; } }; - for char_col in 0..65 { - let pixel_col = char_col * 8; - for char_row in 0..30 { - let pixel_row = char_row * 13; + for char_row in 0..29 { + for char_col in 0..64 { + let ascii = memory + .read(0x6000 + (char_row as u16 * char_col as u16)) + .unwrap(); for row in 0..13 { - for i in 0..8 { - let address: usize = ((pixel_col * pixel_row + row * 13) + i) * 8; - self.buffer[address] = BG_COLOR; + let byte = self.char_rom[ascii as usize + (row * 0x101)]; + for i in (0..8).rev() { + let buffer_index = ((char_row) * 13 + (row)) * 512 + (char_col * 8 + i); + if (byte << i) & 0x80 == 0x80 { + self.buffer[buffer_index] = FG_COLOR; + } else { + self.buffer[buffer_index] = BG_COLOR; + } } } } } - //for char_col in 0..64 { - // for char_row in 0..29 { - // let ascii = memory.read(0x6000 + char_row * char_col).unwrap(); - // for row in 0..13 { - // for char in 0..=255 { - // if ascii == char { - // let byte = self.char_rom[char as usize + (row * 0xFF)]; - // for i in 0..8 { - // let address: usize = ((char_col as usize * 64 + (8 * i)) - // + (char_row as usize + (13 * row) * 29)) - // * 8 - // + i; - // if (byte >> i) & 0b1 == 1 { - // self.buffer[address] = FG_COLOR; - // } else { - // self.buffer[address] = BG_COLOR; - // } - // } - // } - // } - // } - // } - //} - println!("{:?}", self.buffer); - //exit(0); } fn draw_hires(&mut self) { let memory = match self.memory.try_read() {