i'm so happy she works :))))) we can display text for realll :)))))))))
This commit is contained in:
parent
95acceeabd
commit
5b9312f643
Binary file not shown.
11
src/cpu.rs
11
src/cpu.rs
|
@ -53,8 +53,8 @@ impl Cpu {
|
||||||
}
|
}
|
||||||
pub fn reset(&mut self) -> Result<(), ExecutionError> {
|
pub fn reset(&mut self) -> Result<(), ExecutionError> {
|
||||||
let reset_vector_pointer = self.read_word(0xFFFC)?;
|
let reset_vector_pointer = self.read_word(0xFFFC)?;
|
||||||
self.pending_cycles = 8;
|
|
||||||
self.pc = reset_vector_pointer;
|
self.pc = reset_vector_pointer;
|
||||||
|
self.pending_cycles = 8;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
pub fn read(&self, address: Word) -> Result<Byte, MemoryError> {
|
pub fn read(&self, address: Word) -> Result<Byte, MemoryError> {
|
||||||
|
@ -212,9 +212,12 @@ 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!("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!("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!("");
|
"Instruction: {:?}, {:#04x}",
|
||||||
|
valid_instruction.opcode, opcode
|
||||||
|
);
|
||||||
|
println!("");
|
||||||
self.pc += 1;
|
self.pc += 1;
|
||||||
match valid_instruction.opcode.call(self) {
|
match valid_instruction.opcode.call(self) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
|
|
BIN
src/george
BIN
src/george
Binary file not shown.
|
@ -1,11 +1,25 @@
|
||||||
.setcpu "65C02"
|
.setcpu "65C02"
|
||||||
.segment "CODE"
|
.segment "CODE"
|
||||||
LDA #$0
|
LDA #$60
|
||||||
STA $4000
|
STA $01
|
||||||
|
LDY #$0
|
||||||
|
fill:
|
||||||
|
LDA #$20
|
||||||
|
STY $00
|
||||||
|
STA ($00)
|
||||||
|
INY
|
||||||
|
CPY #$ff
|
||||||
|
BNE fill
|
||||||
|
|
||||||
main:
|
main:
|
||||||
LDA #$25
|
LDY #$0
|
||||||
LDY #$2F
|
STY $6000
|
||||||
STY $7000
|
LDY #$1
|
||||||
STY $7001
|
STY $6001
|
||||||
STY $7002
|
LDY #$2
|
||||||
|
STY $6002
|
||||||
|
LDY #$1
|
||||||
|
STY $6003
|
||||||
|
LDY #$3
|
||||||
|
STY $6004
|
||||||
JMP main
|
JMP main
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
MEMORY {
|
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;
|
CTRL: start = $4000, size = $2000, type = rw, fill = true;
|
||||||
VRAM: start = $6000, size = $8000, type = rw, fill = true;
|
VRAM: start = $6000, size = $8000, type = rw, fill = true;
|
||||||
ROM: start = $E000, size = $2000, type = ro, fill = true;
|
ROM: start = $E000, size = $2000, type = ro, fill = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
SEGMENTS {
|
SEGMENTS {
|
||||||
CODE: load = "RAM", type = rw;
|
CODE: load = "PROGRAM", type = rw;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1870,7 +1870,7 @@ fn get_address(
|
||||||
fn zero_page(cpu: &mut Cpu) -> Result<AddressingModeValue, ExecutionError> {
|
fn zero_page(cpu: &mut Cpu) -> Result<AddressingModeValue, ExecutionError> {
|
||||||
// zp
|
// zp
|
||||||
let address = cpu.read(cpu.pc)?;
|
let address = cpu.read(cpu.pc)?;
|
||||||
cpu.pc += 2;
|
cpu.pc += 1;
|
||||||
Ok(AddressingModeValue::Absolute(address as Word))
|
Ok(AddressingModeValue::Absolute(address as Word))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1934,6 +1934,16 @@ fn get_address(
|
||||||
Ok(AddressingModeValue::Absolute(address))
|
Ok(AddressingModeValue::Absolute(address))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn zero_page_indirect(
|
||||||
|
// (zp)
|
||||||
|
cpu: &mut Cpu,
|
||||||
|
) -> Result<AddressingModeValue, ExecutionError> {
|
||||||
|
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(
|
fn zero_page_indexed_indirect(
|
||||||
// (zp, x)
|
// (zp, x)
|
||||||
cpu: &mut Cpu,
|
cpu: &mut Cpu,
|
||||||
|
@ -1985,7 +1995,7 @@ fn get_address(
|
||||||
AddressingMode::ZeroPage => zero_page(cpu),
|
AddressingMode::ZeroPage => zero_page(cpu),
|
||||||
AddressingMode::ZeroPageIndexedWithX => zero_page_indexed_with_x(cpu),
|
AddressingMode::ZeroPageIndexedWithX => zero_page_indexed_with_x(cpu),
|
||||||
AddressingMode::ZeroPageIndexedWithY => zero_page_indexed_with_y(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::ZeroPageIndexedIndirect => zero_page_indexed_indirect(cpu),
|
||||||
AddressingMode::ZeroPageIndirectIndexedWithY => zero_page_indirect_indexed_with_y(cpu),
|
AddressingMode::ZeroPageIndirectIndexedWithY => zero_page_indirect_indexed_with_y(cpu),
|
||||||
AddressingMode::Accumulator => Ok(accumulator(cpu)),
|
AddressingMode::Accumulator => Ok(accumulator(cpu)),
|
||||||
|
@ -2625,9 +2635,10 @@ impl Opcode {
|
||||||
| AddressingMode::AbsoluteA => {
|
| AddressingMode::AbsoluteA => {
|
||||||
let address = get_address(mode, cpu)?;
|
let address = get_address(mode, cpu)?;
|
||||||
let byte = cpu.read(address.try_into()?)?;
|
let byte = cpu.read(address.try_into()?)?;
|
||||||
|
println!("{byte:#04x}");
|
||||||
cpu.set_flag(StatusFlag::Carry, cpu.y >= byte);
|
cpu.set_flag(StatusFlag::Carry, cpu.y >= byte);
|
||||||
cpu.set_flag(StatusFlag::Zero, 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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
_ => Err(GeorgeErrorKind::AddrMode(
|
_ => Err(GeorgeErrorKind::AddrMode(
|
||||||
|
@ -2698,9 +2709,9 @@ impl Opcode {
|
||||||
| AddressingMode::AbsoluteIndexedWithX => {
|
| AddressingMode::AbsoluteIndexedWithX => {
|
||||||
let address = get_address(mode, cpu)?;
|
let address = get_address(mode, cpu)?;
|
||||||
let byte = cpu.read(address.try_into()?)?;
|
let byte = cpu.read(address.try_into()?)?;
|
||||||
cpu.set_flag(StatusFlag::Zero, byte + 1 == 0);
|
cpu.set_flag(StatusFlag::Zero, byte.wrapping_add(1) == 0);
|
||||||
cpu.set_flag(StatusFlag::Negative, cpu.is_negative(byte + 1));
|
cpu.set_flag(StatusFlag::Negative, cpu.is_negative(byte.wrapping_add(1)));
|
||||||
cpu.write(address.try_into()?, byte + 1)?;
|
cpu.write(address.try_into()?, byte.wrapping_add(1))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
_ => Err(GeorgeErrorKind::AddrMode(
|
_ => Err(GeorgeErrorKind::AddrMode(
|
||||||
|
|
|
@ -41,6 +41,8 @@ fn main() {
|
||||||
if let Err(error) = memory.read_from_bin(binary) {
|
if let Err(error) = memory.read_from_bin(binary) {
|
||||||
println!("{:?}", error);
|
println!("{:?}", error);
|
||||||
};
|
};
|
||||||
|
memory.write(0xFFFC, 0x00).unwrap();
|
||||||
|
memory.write(0xFFFD, 0x02).unwrap();
|
||||||
|
|
||||||
let shared_memory = Arc::new(RwLock::new(memory));
|
let shared_memory = Arc::new(RwLock::new(memory));
|
||||||
let cpu_memory = shared_memory.clone();
|
let cpu_memory = shared_memory.clone();
|
||||||
|
|
54
src/video.rs
54
src/video.rs
|
@ -1,18 +1,15 @@
|
||||||
use crate::{memory, Mem};
|
use crate::Mem;
|
||||||
use minifb::{Window, WindowOptions};
|
use minifb::{Window, WindowOptions};
|
||||||
use std::{
|
use std::{
|
||||||
char,
|
|
||||||
fs::File,
|
fs::File,
|
||||||
io::Read,
|
io::Read,
|
||||||
process::exit,
|
sync::{Arc, RwLock},
|
||||||
sync::{Arc, RwLock, RwLockReadGuard},
|
|
||||||
thread::sleep,
|
thread::sleep,
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
|
|
||||||
const FG_COLOR: u32 = 0xFFCC00;
|
const FG_COLOR: u32 = 0xFFCC00;
|
||||||
//const BG_COLOR: u32 = 0x110500;
|
const BG_COLOR: u32 = 0x110500;
|
||||||
const BG_COLOR: u32 = 0x22BB00;
|
|
||||||
|
|
||||||
pub struct Crtc {
|
pub struct Crtc {
|
||||||
memory: Arc<RwLock<Mem>>,
|
memory: Arc<RwLock<Mem>>,
|
||||||
|
@ -67,43 +64,24 @@ impl Crtc {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
for char_col in 0..65 {
|
for char_row in 0..29 {
|
||||||
let pixel_col = char_col * 8;
|
for char_col in 0..64 {
|
||||||
for char_row in 0..30 {
|
let ascii = memory
|
||||||
let pixel_row = char_row * 13;
|
.read(0x6000 + (char_row as u16 * char_col as u16))
|
||||||
|
.unwrap();
|
||||||
for row in 0..13 {
|
for row in 0..13 {
|
||||||
for i in 0..8 {
|
let byte = self.char_rom[ascii as usize + (row * 0x101)];
|
||||||
let address: usize = ((pixel_col * pixel_row + row * 13) + i) * 8;
|
for i in (0..8).rev() {
|
||||||
self.buffer[address] = BG_COLOR;
|
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) {
|
fn draw_hires(&mut self) {
|
||||||
let memory = match self.memory.try_read() {
|
let memory = match self.memory.try_read() {
|
||||||
|
|
Loading…
Reference in New Issue