From c2aef4f249fe557692b5c8a4a16228080e03255d Mon Sep 17 00:00:00 2001 From: august kline Date: Wed, 28 Aug 2024 21:32:19 -0400 Subject: [PATCH] asm fiddling and better debug info --- george.toml | 2 +- src/cpu.rs | 39 ++++- src/instructions.rs | 342 +++++++++++++++++++++++++++++++++++++----- src/keyboard.rs | 2 +- src/main.rs | 5 +- src/roms/george.asm | 133 ++++++++-------- src/roms/george.rom | Bin 32768 -> 32768 bytes src/roms/macro.inc | 2 +- src/roms/template.asm | 2 +- 9 files changed, 421 insertions(+), 106 deletions(-) diff --git a/george.toml b/george.toml index b6e611a..c9d237f 100644 --- a/george.toml +++ b/george.toml @@ -1,3 +1,3 @@ char_rom = "./src/roms/cozette.rom" rom = "./src/roms/george.rom" - +screen = "Window" diff --git a/src/cpu.rs b/src/cpu.rs index 890f607..1f171fe 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -1,13 +1,11 @@ -use crate::instructions::{get_instruction, Instruction}; +use crate::instructions::get_instruction; use crate::memory::{MemHandle, MemoryReader, MemoryWriter}; use std::fmt::Display; -use std::io::{self, Write}; -use std::process::exit; use std::sync::mpsc::{channel, Receiver, Sender}; use std::thread::sleep; use std::time::Duration; -use anyhow::Result; +use termion::cursor::Goto; #[derive(Clone, Copy)] pub enum StatusFlag { @@ -238,7 +236,7 @@ impl Cpu { self.receive_control(); if self.stopped & !self.cycle { - // self.set_flag(StatusFlag::IrqDisable, true); + self.set_flag(StatusFlag::IrqDisable, true); return; } self.cycle = false; @@ -264,4 +262,35 @@ impl Cpu { pub fn stop(&mut self) { self.stopped = true; } + pub fn breakpoint(&mut self) { + // 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!(""); + // println!( + // "{}{:#04x}: {:#02x}, {:#04x}: {:#02x}", + // Goto(1, 35), + // 0x20, + // self.read(0x20), + // 0x21, + // self.read(0x21) + // ); + // println!( + // "{}str_ptr {:#04x}: {:#02x}, {:#04x}: {:#02x}", + // Goto(1, 36), + // 0x30, + // self.read(0x30), + // 0x31, + // self.read(0x31) + // ); + // println!( + // "{}cursor - x: {:#02x}, y: {:#02x}", + // Goto(1, 37), + // self.read(0x300), + // self.read(0x301) + // ); + self.stop(); + } } diff --git a/src/instructions.rs b/src/instructions.rs index 9578ba4..18a9ffd 100644 --- a/src/instructions.rs +++ b/src/instructions.rs @@ -1,6 +1,7 @@ #![allow(clippy::upper_case_acronyms)] use core::panic; +use std::process::exit; use termion::cursor::Goto; use termion::{clear, color}; @@ -17,42 +18,51 @@ pub struct Instruction<'a> { pub address_fn: Option, pub cycles: u8, pub name: &'a str, + pub addr_mode: &'a str, } impl Instruction<'_> { pub fn call(&self, cpu: &mut Cpu) { - print!("{}{}instruction: {:?}, a: {a:#04x}, x: {x:#04x}, y: {y:#04x}, pc: {pc:#06x}, sp: {s:#04x}, sr: {p:#010b}, irq: {irq:?}, nmi: {nmi:?}", Goto(0, 31),clear::UntilNewline, self.name, a = cpu.a, x = cpu.x, y = cpu.y, pc = cpu.pc, s = cpu.s, p = cpu.p, irq = cpu.irq, nmi = cpu.nmi); + // TODO: add flag to print these + // print!("{}{}a: {a:#04x}, x: {x:#04x}, y: {y:#04x}, pc: {pc:#06x}, sp: {s:#04x}, sr: {p:#010b}, irq: {irq:?}, nmi: {nmi:?}", Goto(0, 31),clear::UntilNewline, a = cpu.a, x = cpu.x, y = cpu.y, pc = cpu.pc, s = cpu.s, p = cpu.p, irq = cpu.irq, nmi = cpu.nmi); // print!( // "{}instruction: {:?}, pc: {:#04x}", // Goto(0, 31), // self.name, // cpu.pc // ); - print!( - "{}{:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {}{}{:02x}{}{} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x}", - Goto(0, 32), - cpu.read(cpu.pc.wrapping_sub(8)), - cpu.read(cpu.pc.wrapping_sub(7)), - cpu.read(cpu.pc.wrapping_sub(6)), - cpu.read(cpu.pc.wrapping_sub(5)), - cpu.read(cpu.pc.wrapping_sub(4)), - cpu.read(cpu.pc.wrapping_sub(3)), - cpu.read(cpu.pc.wrapping_sub(2)), - cpu.read(cpu.pc.wrapping_sub(1)), - color::Bg(color::Rgb(0xFF, 0xCC, 0x00)), - color::Fg(color::Rgb(0x11, 0x05, 0x00)), - cpu.read(cpu.pc), - color::Fg(color::Rgb(0xFF, 0xCC, 0x00)), - color::Bg(color::Rgb(0x11, 0x05, 0x00)), - cpu.read(cpu.pc.wrapping_add(1)), - cpu.read(cpu.pc.wrapping_add(2)), - cpu.read(cpu.pc.wrapping_add(3)), - cpu.read(cpu.pc.wrapping_add(4)), - cpu.read(cpu.pc.wrapping_add(5)), - cpu.read(cpu.pc.wrapping_add(6)), - cpu.read(cpu.pc.wrapping_add(7)), - cpu.read(cpu.pc.wrapping_add(8)), - ); + // print!( + // "{}{}instruction: {:?}, mode: {:?}", + // Goto(0, 32), + // clear::UntilNewline, + // self.name, + // self.addr_mode + // ); + // print!( + // "{}{:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {}{}{:02x}{}{} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x}", + // Goto(0, 33), + // cpu.read(cpu.pc.wrapping_sub(8)), + // cpu.read(cpu.pc.wrapping_sub(7)), + // cpu.read(cpu.pc.wrapping_sub(6)), + // cpu.read(cpu.pc.wrapping_sub(5)), + // cpu.read(cpu.pc.wrapping_sub(4)), + // cpu.read(cpu.pc.wrapping_sub(3)), + // cpu.read(cpu.pc.wrapping_sub(2)), + // cpu.read(cpu.pc.wrapping_sub(1)), + // color::Bg(color::Rgb(0xFF, 0xCC, 0x00)), + // color::Fg(color::Rgb(0x11, 0x05, 0x00)), + // cpu.read(cpu.pc), + // color::Fg(color::Rgb(0xFF, 0xCC, 0x00)), + // color::Bg(color::Rgb(0x11, 0x05, 0x00)), + // cpu.read(cpu.pc.wrapping_add(1)), + // cpu.read(cpu.pc.wrapping_add(2)), + // cpu.read(cpu.pc.wrapping_add(3)), + // cpu.read(cpu.pc.wrapping_add(4)), + // cpu.read(cpu.pc.wrapping_add(5)), + // cpu.read(cpu.pc.wrapping_add(6)), + // cpu.read(cpu.pc.wrapping_add(7)), + // cpu.read(cpu.pc.wrapping_add(8)), + // ); cpu.pc = cpu.pc.wrapping_add(1); // read instruction byte match self.instr_fn { // existence of instr_fn means this is a valid instruction @@ -195,9 +205,11 @@ fn zero_page_indirect_indexed_with_y( // (zp), y cpu: &mut Cpu, ) -> u16 { - let byte: u8 = cpu.read(cpu.pc); - let address: u16 = cpu.read_word(byte.wrapping_add(cpu.y) as u16); + let zp: u8 = cpu.read(cpu.pc); + let address = cpu.read_word(zp as u16); + let address: u16 = address.wrapping_add(cpu.y as u16); cpu.pc = cpu.pc.wrapping_add(1); + println!("{}indirect addr: {:#04x}", Goto(1, 39), address); address } @@ -243,6 +255,10 @@ fn branch(cpu: &mut Cpu, condition: bool, address: u16) { cpu.pc = cpu.pc.wrapping_add(1); } +fn brkpt(cpu: &mut Cpu, address: Option) { + cpu.breakpoint() +} + fn adc(cpu: &mut Cpu, address: Option) { let address = address.unwrap(); let byte = cpu.read(address); @@ -926,1541 +942,1797 @@ pub fn get_instruction(opcode: u8) -> Instruction<'static> { OPCODES[opcode as usize] } -const OPCODES: [Instruction; 256] = [ +pub const OPCODES: [Instruction; 256] = [ Instruction { instr_fn: Some(brk), address_fn: None, cycles: 7, name: "brk", + addr_mode: "none", }, Instruction { instr_fn: Some(ora), address_fn: Some(zero_page_indexed_indirect), cycles: 6, name: "ora", + addr_mode: "zero_page_indexed_indirect", + }, + Instruction { + instr_fn: Some(brkpt), + address_fn: None, + cycles: 0, + name: "brkpt", + addr_mode: "none", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", - }, - Instruction { - instr_fn: None, - address_fn: None, - cycles: 0, - name: "none", + addr_mode: "none", }, Instruction { instr_fn: Some(tsb), address_fn: Some(zero_page), cycles: 5, name: "tsb", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(ora), address_fn: Some(zero_page), cycles: 3, name: "ora", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(asl), address_fn: Some(zero_page), cycles: 5, name: "asl", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(rmb0), address_fn: Some(zero_page), cycles: 5, name: "rmb0", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(php), address_fn: None, cycles: 3, name: "php", + addr_mode: "none", }, Instruction { instr_fn: Some(ora), address_fn: Some(immediate), cycles: 2, name: "ora", + addr_mode: "immediate", }, Instruction { instr_fn: Some(asl_a), address_fn: Some(accumulator), cycles: 2, name: "asl_a", + addr_mode: "accumulator", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: Some(tsb), address_fn: Some(absolute_a), cycles: 6, name: "tsb", + addr_mode: "absolute_a", }, Instruction { instr_fn: Some(ora), address_fn: Some(absolute_a), cycles: 4, name: "ora", + addr_mode: "absolute_a", }, Instruction { instr_fn: Some(asl), address_fn: Some(absolute_a), cycles: 6, name: "asl", + addr_mode: "absolute_a", }, Instruction { instr_fn: Some(bbr0), address_fn: Some(relative_test), cycles: 4, name: "bbr0", + addr_mode: "relative_test", }, Instruction { instr_fn: Some(bpl), address_fn: Some(relative), cycles: 2, name: "bpl", + addr_mode: "relative", }, Instruction { instr_fn: Some(ora), address_fn: Some(absolute_indexed_with_y), cycles: 5, name: "ora", + addr_mode: "absolute_indexed_with_y", }, Instruction { instr_fn: Some(ora), address_fn: Some(zero_page_indirect), cycles: 5, name: "ora", + addr_mode: "zero_page_indirect", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: Some(trb), address_fn: Some(zero_page), cycles: 5, name: "trb", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(ora), address_fn: Some(zero_page_indexed_with_x), cycles: 4, name: "ora", + addr_mode: "zero_page_indexed_with_x", }, Instruction { instr_fn: Some(asl), address_fn: Some(zero_page_indexed_with_x), cycles: 6, name: "asl", + addr_mode: "zero_page_indexed_with_x", }, Instruction { instr_fn: Some(rmb1), address_fn: Some(zero_page), cycles: 5, name: "rmb1", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(clc), address_fn: None, cycles: 2, name: "clc", + addr_mode: "none", }, Instruction { instr_fn: Some(ora), address_fn: Some(absolute_indexed_with_y), cycles: 4, name: "ora", + addr_mode: "absolute_indexed_with_y", }, Instruction { instr_fn: Some(inc_a), address_fn: Some(accumulator), cycles: 2, name: "inc_a", + addr_mode: "accumulator", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: Some(trb), address_fn: Some(absolute_a), cycles: 6, name: "trb", + addr_mode: "absolute_a", }, Instruction { instr_fn: Some(ora), address_fn: Some(absolute_indexed_with_x), cycles: 4, name: "ora", + addr_mode: "absolute_indexed_with_x", }, Instruction { instr_fn: Some(asl), address_fn: Some(absolute_indexed_with_x), cycles: 7, name: "asl", + addr_mode: "absolute_indexed_with_x", }, Instruction { instr_fn: Some(bbr1), address_fn: Some(relative_test), cycles: 4, name: "bbr1", + addr_mode: "relative_test", }, Instruction { instr_fn: Some(jsr), address_fn: Some(absolute_a), cycles: 6, name: "jsr", + addr_mode: "absolute_a", }, Instruction { instr_fn: Some(and), address_fn: Some(zero_page_indexed_indirect), cycles: 6, name: "and", + addr_mode: "zero_page_indexed_indirect", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: Some(bit), address_fn: Some(zero_page), cycles: 3, name: "bit", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(and), address_fn: Some(zero_page), cycles: 3, name: "and", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(rol), address_fn: Some(zero_page), cycles: 5, name: "rol", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(rmb2), address_fn: Some(zero_page), cycles: 5, name: "rmb2", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(plp), address_fn: None, cycles: 4, name: "plp", + addr_mode: "none", }, Instruction { instr_fn: Some(and), address_fn: Some(immediate), cycles: 2, name: "and", + addr_mode: "immediate", }, Instruction { instr_fn: Some(rol_a), address_fn: Some(accumulator), cycles: 2, name: "rol_a", + addr_mode: "accumulator", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: Some(bit), address_fn: Some(absolute_a), cycles: 4, name: "bit", + addr_mode: "absolute_a", }, Instruction { instr_fn: Some(and), address_fn: Some(absolute_a), cycles: 4, name: "and", + addr_mode: "absolute_a", }, Instruction { instr_fn: Some(rol), address_fn: Some(absolute_a), cycles: 6, name: "rol", + addr_mode: "absolute_a", }, Instruction { instr_fn: Some(bbr2), address_fn: Some(relative_test), cycles: 4, name: "bbr2", + addr_mode: "relative_test", }, Instruction { instr_fn: Some(bmi), address_fn: Some(relative), cycles: 2, name: "bmi", + addr_mode: "relative", }, Instruction { instr_fn: Some(and), address_fn: Some(zero_page_indirect_indexed_with_y), cycles: 5, name: "and", + addr_mode: "zero_page_indirect_indexed_with_y", }, Instruction { instr_fn: Some(and), address_fn: Some(zero_page_indirect), cycles: 5, name: "and", + addr_mode: "zero_page_indirect", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: Some(bit), address_fn: Some(zero_page_indexed_with_x), cycles: 3, name: "bit", + addr_mode: "zero_page_indexed_with_x", }, Instruction { instr_fn: Some(and), address_fn: Some(zero_page_indexed_with_x), cycles: 4, name: "and", + addr_mode: "zero_page_indexed_with_x", }, Instruction { instr_fn: Some(rol), address_fn: Some(zero_page_indexed_with_x), cycles: 6, name: "rol", + addr_mode: "zero_page_indexed_with_x", }, Instruction { instr_fn: Some(rmb3), address_fn: Some(zero_page), cycles: 5, name: "rmb3", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(sec), address_fn: None, cycles: 2, name: "sec", + addr_mode: "none", }, Instruction { instr_fn: Some(and), address_fn: Some(absolute_indexed_with_y), cycles: 4, name: "and", + addr_mode: "absolute_indexed_with_y", }, Instruction { instr_fn: Some(dec_a), address_fn: Some(accumulator), cycles: 2, name: "dec_a", + addr_mode: "accumulator", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: Some(bit), address_fn: Some(absolute_indexed_with_x), cycles: 4, name: "bit", + addr_mode: "absolute_indexed_with_x", }, Instruction { instr_fn: Some(and), address_fn: Some(absolute_indexed_with_x), cycles: 4, name: "and", + addr_mode: "absolute_indexed_with_x", }, Instruction { instr_fn: Some(rol), address_fn: Some(absolute_indexed_with_x), cycles: 7, name: "rol", + addr_mode: "absolute_indexed_with_x", }, Instruction { instr_fn: Some(bbr3), address_fn: Some(relative_test), cycles: 4, name: "bbr3", + addr_mode: "relative_test", }, Instruction { instr_fn: Some(rti), address_fn: None, cycles: 6, name: "rti", + addr_mode: "none", }, Instruction { instr_fn: Some(eor), address_fn: Some(zero_page_indexed_indirect), cycles: 6, name: "eor", + addr_mode: "zero_page_indexed_indirect", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: Some(eor), address_fn: Some(zero_page), cycles: 3, name: "eor", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(lsr), address_fn: Some(zero_page), cycles: 5, name: "lsr", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(rmb4), address_fn: Some(zero_page), cycles: 5, name: "rmb4", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(pha), address_fn: None, cycles: 3, name: "pha", + addr_mode: "none", }, Instruction { instr_fn: Some(eor), address_fn: Some(immediate), cycles: 2, name: "eor", + addr_mode: "immediate", }, Instruction { instr_fn: Some(lsr_a), address_fn: Some(accumulator), cycles: 2, name: "lsr_a", + addr_mode: "accumulator", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: Some(jmp), address_fn: Some(absolute_a), cycles: 3, name: "jmp", + addr_mode: "absolute_a", }, Instruction { instr_fn: Some(eor), address_fn: Some(absolute_a), cycles: 4, name: "eor", + addr_mode: "absolute_a", }, Instruction { instr_fn: Some(lsr), address_fn: Some(absolute_a), cycles: 6, name: "lsr", + addr_mode: "absolute_a", }, Instruction { instr_fn: Some(bbr4), address_fn: Some(relative_test), cycles: 4, name: "bbr4", + addr_mode: "relative_test", }, Instruction { instr_fn: Some(bvc), address_fn: Some(relative), cycles: 2, name: "bvc", + addr_mode: "relative", }, Instruction { instr_fn: Some(eor), address_fn: Some(zero_page_indirect_indexed_with_y), cycles: 5, name: "eor", + addr_mode: "zero_page_indirect_indexed_with_y", }, Instruction { instr_fn: Some(eor), address_fn: Some(zero_page_indirect), cycles: 5, name: "eor", + addr_mode: "zero_page_indirect", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: Some(eor), address_fn: Some(zero_page_indexed_with_x), cycles: 4, name: "eor", + addr_mode: "zero_page_indexed_with_x", }, Instruction { instr_fn: Some(lsr), address_fn: Some(zero_page_indexed_with_x), cycles: 6, name: "lsr", + addr_mode: "zero_page_indexed_with_x", }, Instruction { instr_fn: Some(rmb5), address_fn: Some(zero_page), cycles: 5, name: "rmb5", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(cli), address_fn: None, cycles: 2, name: "cli", + addr_mode: "none", }, Instruction { instr_fn: Some(eor), address_fn: Some(absolute_indexed_with_y), cycles: 4, name: "eor", + addr_mode: "absolute_indexed_with_y", }, Instruction { instr_fn: Some(phy), address_fn: None, cycles: 3, name: "phy", + addr_mode: "none", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: Some(eor), address_fn: Some(absolute_indexed_with_x), cycles: 4, name: "eor", + addr_mode: "absolute_indexed_with_x", }, Instruction { instr_fn: Some(lsr), address_fn: Some(absolute_indexed_with_x), cycles: 7, name: "lsr", + addr_mode: "absolute_indexed_with_x", }, Instruction { instr_fn: Some(bbr5), address_fn: Some(relative_test), cycles: 4, name: "bbr5", + addr_mode: "relative_test", }, Instruction { instr_fn: Some(rts), address_fn: None, cycles: 6, name: "rts", + addr_mode: "none", }, Instruction { instr_fn: Some(adc), address_fn: Some(zero_page_indexed_indirect), cycles: 6, name: "adc", + addr_mode: "zero_page_indexed_indirect", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: Some(stz), address_fn: Some(zero_page), cycles: 3, name: "stz", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(adc), address_fn: Some(zero_page), cycles: 3, name: "adc", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(ror), address_fn: Some(zero_page), cycles: 5, name: "ror", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(rmb6), address_fn: Some(zero_page), cycles: 5, name: "rmb6", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(pla), address_fn: None, cycles: 4, name: "pla", + addr_mode: "none", }, Instruction { instr_fn: Some(adc), address_fn: Some(immediate), cycles: 2, name: "adc", + addr_mode: "immediate", }, Instruction { instr_fn: Some(ror_a), address_fn: Some(accumulator), cycles: 2, name: "ror_a", + addr_mode: "accumulator", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: Some(jmp), address_fn: Some(absolute_indirect), cycles: 5, name: "jmp", + addr_mode: "absolute_indirect", }, Instruction { instr_fn: Some(adc), address_fn: Some(absolute_a), cycles: 4, name: "adc", + addr_mode: "absolute_a", }, Instruction { instr_fn: Some(ror), address_fn: Some(absolute_a), cycles: 6, name: "ror", + addr_mode: "absolute_a", }, Instruction { instr_fn: Some(bbr6), address_fn: Some(relative), cycles: 4, name: "bbr6", + addr_mode: "relative", }, Instruction { instr_fn: Some(bvs), address_fn: Some(relative), cycles: 2, name: "bvs", + addr_mode: "relative", }, Instruction { instr_fn: Some(adc), address_fn: Some(zero_page_indirect_indexed_with_y), cycles: 5, name: "adc", + addr_mode: "zero_page_indirect_indexed_with_y", }, Instruction { instr_fn: Some(adc), address_fn: Some(zero_page_indirect), cycles: 5, name: "adc", + addr_mode: "zero_page_indirect", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: Some(stz), address_fn: Some(zero_page_indexed_with_x), cycles: 4, name: "stz", + addr_mode: "zero_page_indexed_with_x", }, Instruction { instr_fn: Some(adc), address_fn: Some(zero_page_indexed_with_x), cycles: 4, name: "adc", + addr_mode: "zero_page_indexed_with_x", }, Instruction { instr_fn: Some(ror), address_fn: Some(zero_page_indexed_with_x), cycles: 6, name: "ror", + addr_mode: "zero_page_indexed_with_x", }, Instruction { instr_fn: Some(rmb7), address_fn: Some(zero_page), cycles: 5, name: "rmb7", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(sei), address_fn: None, cycles: 2, name: "sei", + addr_mode: "none", }, Instruction { instr_fn: Some(adc), address_fn: Some(absolute_indexed_with_y), cycles: 4, name: "adc", + addr_mode: "absolute_indexed_with_y", }, Instruction { instr_fn: Some(ply), address_fn: None, cycles: 4, name: "ply", + addr_mode: "none", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: Some(jmp), address_fn: Some(absolute_indexed_indirect), cycles: 6, name: "jmp", + addr_mode: "absolute_indexed_indirect", }, Instruction { instr_fn: Some(adc), address_fn: Some(absolute_indexed_with_x), cycles: 4, name: "adc", + addr_mode: "absolute_indexed_with_x", }, Instruction { instr_fn: Some(ror), address_fn: Some(absolute_indexed_with_x), cycles: 7, name: "ror", + addr_mode: "absolute_indexed_with_x", }, Instruction { instr_fn: Some(bbr7), address_fn: Some(relative_test), cycles: 4, name: "bbr7", + addr_mode: "relative_test", }, Instruction { instr_fn: Some(bra), address_fn: Some(relative), cycles: 3, name: "bra", + addr_mode: "relative", }, Instruction { instr_fn: Some(sta), address_fn: Some(zero_page_indexed_indirect), cycles: 6, name: "sta", + addr_mode: "zero_page_indexed_indirect", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: Some(sty), address_fn: Some(zero_page), cycles: 3, name: "sty", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(sta), address_fn: Some(zero_page), cycles: 3, name: "sta", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(stx), address_fn: Some(zero_page), cycles: 3, name: "stx", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(smb0), address_fn: Some(zero_page), cycles: 5, name: "smb0", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(dey), address_fn: None, cycles: 2, name: "dey", + addr_mode: "none", }, Instruction { instr_fn: Some(bit), address_fn: Some(immediate), cycles: 3, name: "bit", + addr_mode: "immediate", }, Instruction { instr_fn: Some(txa), address_fn: None, cycles: 2, name: "txa", + addr_mode: "none", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: Some(sty), address_fn: Some(absolute_a), cycles: 4, name: "sty", + addr_mode: "absolute_a", }, Instruction { instr_fn: Some(sta), address_fn: Some(absolute_a), cycles: 4, name: "sta", + addr_mode: "absolute_a", }, Instruction { instr_fn: Some(stx), address_fn: Some(absolute_a), cycles: 4, name: "stx", + addr_mode: "absolute_a", }, Instruction { instr_fn: Some(bbs0), address_fn: Some(relative_test), cycles: 4, name: "bbs0", + addr_mode: "relative_test", }, Instruction { instr_fn: Some(bcc), address_fn: Some(relative), cycles: 2, name: "bcc", + addr_mode: "relative", }, Instruction { instr_fn: Some(sta), address_fn: Some(zero_page_indirect_indexed_with_y), cycles: 6, name: "sta", + addr_mode: "zero_page_indirect_indexed_with_y", }, Instruction { instr_fn: Some(sta), address_fn: Some(zero_page_indirect), cycles: 5, name: "sta", + addr_mode: "zero_page_indirect", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: Some(sty), address_fn: Some(zero_page_indexed_with_x), cycles: 4, name: "sty", + addr_mode: "zero_page_indexed_with_x", }, Instruction { instr_fn: Some(sta), address_fn: Some(zero_page_indexed_with_x), cycles: 4, name: "sta", + addr_mode: "zero_page_indexed_with_x", }, Instruction { instr_fn: Some(stx), address_fn: Some(zero_page_indexed_with_y), cycles: 4, name: "stx", + addr_mode: "zero_page_indexed_with_y", }, Instruction { instr_fn: Some(smb1), address_fn: Some(zero_page), cycles: 5, name: "smb1", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(tya), address_fn: None, cycles: 2, name: "tya", + addr_mode: "none", }, Instruction { instr_fn: Some(sta), address_fn: Some(absolute_indexed_with_y), cycles: 5, name: "sta", + addr_mode: "absolute_indexed_with_y", }, Instruction { instr_fn: Some(txs), address_fn: None, cycles: 2, name: "txs", + addr_mode: "none", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: Some(stz), address_fn: Some(absolute_a), cycles: 4, name: "stz", + addr_mode: "absolute_a", }, Instruction { instr_fn: Some(sta), address_fn: Some(absolute_indexed_with_x), cycles: 5, name: "sta", + addr_mode: "absolute_indexed_with_x", }, Instruction { instr_fn: Some(stz), address_fn: Some(absolute_indexed_with_x), cycles: 5, name: "stz", + addr_mode: "absolute_indexed_with_x", }, Instruction { instr_fn: Some(bbs1), address_fn: Some(relative_test), cycles: 4, name: "bbs1", + addr_mode: "relative_test", }, Instruction { instr_fn: Some(ldy), address_fn: Some(immediate), cycles: 2, name: "ldy", + addr_mode: "immediate", }, Instruction { instr_fn: Some(lda), address_fn: Some(zero_page_indexed_indirect), cycles: 6, name: "lda", + addr_mode: "zero_page_indexed_indirect", }, Instruction { instr_fn: Some(ldx), address_fn: Some(immediate), cycles: 2, name: "ldx", + addr_mode: "immediate", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: Some(ldy), address_fn: Some(zero_page), cycles: 3, name: "ldy", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(lda), address_fn: Some(zero_page), cycles: 3, name: "lda", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(ldx), address_fn: Some(zero_page), cycles: 3, name: "ldx", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(smb2), address_fn: Some(zero_page), cycles: 5, name: "smb2", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(tay), address_fn: None, cycles: 2, name: "tay", + addr_mode: "none", }, Instruction { instr_fn: Some(lda), address_fn: Some(immediate), cycles: 2, name: "lda", + addr_mode: "immediate", }, Instruction { instr_fn: Some(tax), address_fn: None, cycles: 2, name: "tax", + addr_mode: "none", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: Some(ldy), address_fn: Some(absolute_a), cycles: 4, name: "ldy", + addr_mode: "absolute_a", }, Instruction { instr_fn: Some(lda), address_fn: Some(absolute_a), cycles: 4, name: "lda", + addr_mode: "absolute_a", }, Instruction { instr_fn: Some(ldx), address_fn: Some(absolute_a), cycles: 4, name: "ldx", + addr_mode: "absolute_a", }, Instruction { instr_fn: Some(bbs2), address_fn: Some(relative_test), cycles: 4, name: "bbs2", + addr_mode: "relative_test", }, Instruction { instr_fn: Some(bcs), address_fn: Some(relative), cycles: 2, name: "bcs", + addr_mode: "relative", }, Instruction { instr_fn: Some(lda), address_fn: Some(zero_page_indirect_indexed_with_y), cycles: 5, name: "lda", + addr_mode: "zero_page_indirect_indexed_with_y", }, Instruction { instr_fn: Some(lda), address_fn: Some(zero_page_indirect), cycles: 5, // Unsure, see https://cx16.dk/65c02/reference.html#LDA name: "lda", + addr_mode: "zero_page_indirect", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: Some(ldy), address_fn: Some(zero_page_indexed_with_x), cycles: 4, name: "ldy", + addr_mode: "zero_page_indexed_with_x", }, Instruction { instr_fn: Some(lda), address_fn: Some(zero_page_indexed_with_x), cycles: 4, name: "lda", + addr_mode: "zero_page_indexed_with_x", }, Instruction { instr_fn: Some(ldx), address_fn: Some(zero_page_indexed_with_y), cycles: 4, name: "ldx", + addr_mode: "zero_page_indexed_with_y", }, Instruction { instr_fn: Some(smb3), address_fn: Some(zero_page), cycles: 5, name: "smb3", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(clv), address_fn: None, cycles: 2, name: "clv", + addr_mode: "none", }, Instruction { instr_fn: Some(lda), address_fn: Some(absolute_indexed_with_y), cycles: 4, name: "lda", + addr_mode: "absolute_indexed_with_y", }, Instruction { instr_fn: Some(tsx), address_fn: None, cycles: 2, name: "tsx", + addr_mode: "none", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: Some(ldy), address_fn: Some(absolute_indexed_with_x), cycles: 4, name: "ldy", + addr_mode: "absolute_indexed_with_x", }, Instruction { instr_fn: Some(lda), address_fn: Some(absolute_indexed_with_x), cycles: 4, name: "lda", + addr_mode: "absolute_indexed_with_x", }, Instruction { instr_fn: Some(ldx), address_fn: Some(absolute_indexed_with_y), cycles: 4, name: "ldx", + addr_mode: "absolute_indexed_with_y", }, Instruction { instr_fn: Some(bbs3), address_fn: Some(relative_test), cycles: 4, name: "bbs3", + addr_mode: "relative_test", }, Instruction { instr_fn: Some(cpy), address_fn: Some(immediate), cycles: 2, name: "cpy", + addr_mode: "immediate", }, Instruction { instr_fn: Some(cmp), address_fn: Some(zero_page_indexed_indirect), cycles: 6, name: "cmp", + addr_mode: "zero_page_indexed_indirect", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: Some(cpy), address_fn: Some(zero_page), cycles: 3, name: "cpy", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(cmp), address_fn: Some(zero_page), cycles: 3, name: "cmp", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(dec), address_fn: Some(zero_page), cycles: 5, name: "dec", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(smb4), address_fn: Some(zero_page), cycles: 5, name: "smb4", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(iny), address_fn: None, cycles: 2, name: "iny", + addr_mode: "none", }, Instruction { instr_fn: Some(cmp), address_fn: Some(immediate), cycles: 2, name: "cmp", + addr_mode: "immediate", }, Instruction { instr_fn: Some(dex), address_fn: None, cycles: 2, name: "dex", + addr_mode: "none", }, Instruction { instr_fn: Some(wai), address_fn: None, cycles: 3, name: "wai", + addr_mode: "none", }, Instruction { instr_fn: Some(cpy), address_fn: Some(absolute_a), cycles: 4, name: "cpy", + addr_mode: "absolute_a", }, Instruction { instr_fn: Some(cmp), address_fn: Some(absolute_a), cycles: 4, name: "cmp", + addr_mode: "absolute_a", }, Instruction { instr_fn: Some(dec), address_fn: Some(absolute_a), cycles: 6, name: "dec", + addr_mode: "absolute_a", }, Instruction { instr_fn: Some(bbs4), address_fn: Some(relative_test), cycles: 4, name: "bbs4", + addr_mode: "relative_test", }, Instruction { instr_fn: Some(bne), address_fn: Some(relative), cycles: 2, name: "bne", + addr_mode: "relative", }, Instruction { instr_fn: Some(cmp), address_fn: Some(zero_page_indirect_indexed_with_y), cycles: 5, name: "cmp", + addr_mode: "zero_page_indirect_indexed_with_y", }, Instruction { instr_fn: Some(cmp), address_fn: Some(zero_page_indirect), cycles: 5, // Unsure, look here: https://cx16.dk/65c02/reference.html#CMP name: "cmp", + addr_mode: "zero_page_indirect", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: Some(cmp), address_fn: Some(zero_page_indexed_with_x), cycles: 4, name: "cmp", + addr_mode: "zero_page_indexed_with_x", }, Instruction { instr_fn: Some(dec), address_fn: Some(zero_page_indexed_with_x), cycles: 6, name: "dec", + addr_mode: "zero_page_indexed_with_x", }, Instruction { instr_fn: Some(smb5), address_fn: Some(zero_page), cycles: 5, name: "smb5", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(cld), address_fn: None, cycles: 2, name: "cld", + addr_mode: "none", }, Instruction { instr_fn: Some(cmp), address_fn: Some(absolute_indexed_with_y), cycles: 4, name: "cmp", + addr_mode: "absolute_indexed_with_y", }, Instruction { instr_fn: Some(phx), address_fn: None, cycles: 3, name: "phx", + addr_mode: "none", }, Instruction { instr_fn: Some(stp), address_fn: None, cycles: 3, name: "stp", + addr_mode: "none", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: Some(cmp), address_fn: Some(absolute_indexed_with_x), cycles: 4, name: "cmp", + addr_mode: "absolute_indexed_with_x", }, Instruction { instr_fn: Some(dec), address_fn: Some(absolute_indexed_with_x), cycles: 7, name: "dec", + addr_mode: "absolute_indexed_with_x", }, Instruction { instr_fn: Some(bbs5), address_fn: Some(relative_test), cycles: 4, name: "bbs5", + addr_mode: "relative_test", }, Instruction { instr_fn: Some(cpx), address_fn: Some(immediate), cycles: 2, name: "cpx", + addr_mode: "immediate", }, Instruction { instr_fn: Some(sbc), address_fn: Some(zero_page_indexed_indirect), cycles: 6, name: "sbc", + addr_mode: "zero_page_indexed_indirect", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: Some(cpx), address_fn: Some(zero_page), cycles: 3, name: "cpx", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(sbc), address_fn: Some(zero_page), cycles: 3, name: "sbc", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(inc), address_fn: Some(zero_page), cycles: 5, name: "inc", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(smb6), address_fn: Some(zero_page), cycles: 5, name: "smb6", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(inx), address_fn: None, cycles: 2, name: "inx", + addr_mode: "none", }, Instruction { instr_fn: Some(sbc), address_fn: Some(immediate), cycles: 2, name: "sbc", + addr_mode: "immediate", }, Instruction { instr_fn: Some(nop), address_fn: None, cycles: 2, name: "nop", + addr_mode: "none", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: Some(cpx), address_fn: Some(absolute_a), cycles: 4, name: "cpx", + addr_mode: "absolute_a", }, Instruction { instr_fn: Some(sbc), address_fn: Some(absolute_a), cycles: 4, name: "sbc", + addr_mode: "absolute_a", }, Instruction { instr_fn: Some(inc), address_fn: Some(absolute_a), cycles: 6, name: "inc", + addr_mode: "absolute_a", }, Instruction { instr_fn: Some(bbs6), address_fn: Some(relative_test), cycles: 4, name: "bbs6", + addr_mode: "relative_test", }, Instruction { instr_fn: Some(beq), address_fn: Some(relative), cycles: 2, name: "beq", + addr_mode: "relative", }, Instruction { instr_fn: Some(sbc), address_fn: Some(zero_page_indirect_indexed_with_y), cycles: 5, name: "sbc", + addr_mode: "zero_page_indirect_indexed_with_y", }, Instruction { instr_fn: Some(sbc), address_fn: Some(zero_page_indirect), cycles: 5, name: "sbc", + addr_mode: "zero_page_indirect", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: Some(sbc), address_fn: Some(zero_page_indexed_with_x), cycles: 4, name: "sbc", + addr_mode: "zero_page_indexed_with_x", }, Instruction { instr_fn: Some(inc), address_fn: Some(zero_page_indexed_with_x), cycles: 6, name: "inc", + addr_mode: "zero_page_indexed_with_x", }, Instruction { instr_fn: Some(smb7), address_fn: Some(zero_page), cycles: 5, name: "smb7", + addr_mode: "zero_page", }, Instruction { instr_fn: Some(sed), address_fn: None, cycles: 2, name: "sed", + addr_mode: "none", }, Instruction { instr_fn: Some(sbc), address_fn: Some(absolute_indexed_with_y), cycles: 4, name: "sbc", + addr_mode: "absolute_indexed_with_y", }, Instruction { instr_fn: Some(plx), address_fn: None, cycles: 4, name: "plx", + addr_mode: "none", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: None, address_fn: None, cycles: 0, name: "none", + addr_mode: "none", }, Instruction { instr_fn: Some(sbc), address_fn: Some(absolute_indexed_with_x), cycles: 4, name: "sbc", + addr_mode: "absolute_indexed_with_x", }, Instruction { instr_fn: Some(inc), address_fn: Some(absolute_indexed_with_x), cycles: 7, name: "inc", + addr_mode: "absolute_indexed_with_x", }, Instruction { instr_fn: Some(bbs7), address_fn: Some(relative_test), cycles: 4, name: "bbs7", + addr_mode: "relative_test", }, ]; diff --git a/src/keyboard.rs b/src/keyboard.rs index 82f072f..ba9fbd3 100644 --- a/src/keyboard.rs +++ b/src/keyboard.rs @@ -178,7 +178,7 @@ impl Keyboard { impl MemoryWriter for Keyboard { fn write(&self, address: u16, data: u8) { if data != 0x00 { - println!("wrote {:02x} to address {:04x}", data, address); + // println!("wrote {:02x} to address {:04x}", data, address); } self.memory.write(address, data); } diff --git a/src/main.rs b/src/main.rs index 78700d8..1bb2206 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,15 +15,14 @@ use crate::video::Screen; use cli::get_input; use crossterm::cursor; use memory::MemHandle; -use std::io::{stdout, Read, Result, Write}; +use std::io::stdout; use std::thread::{self, sleep}; use std::time::Duration; use termion::cursor::Goto; use termion::event::Key; use termion::input::TermRead; use termion::raw::IntoRawMode; -use termion::screen::IntoAlternateScreen; -use termion::{async_stdin, clear, screen}; +use termion::{async_stdin, clear}; fn main() { let _stdout = stdout().into_raw_mode(); diff --git a/src/roms/george.asm b/src/roms/george.asm index 2ed46e1..56c2b6b 100644 --- a/src/roms/george.asm +++ b/src/roms/george.asm @@ -20,7 +20,7 @@ reset: ldx #0; initialize data stack pointer initdisplay: - lda #$20 + lda #0 ldy #0 cleardisplay: @@ -36,6 +36,13 @@ cleardisplay: bne cleardisplay cli +print_test: + lda #0 + sta key_row + lda #5 + sta key_col + push_coords #5, #5 + main: ; jsr printtext ; key_zero: @@ -45,74 +52,82 @@ main: ; fim: ; cli ; bra fim - jsr keyboard + jsr print + ; jsr print jmp main -keyboard: - ldy #0 - .check_row: ; loop through each row - lda kb_row, y - beq .skip_row ; if row has no key pressed, skip checking which key - ; jmp key_down - sta kb_row_cache, y ; if key pressed, cache it - lda kb_row, y - cmp kb_row_cache, y ; has key changed? - beq key_down - .skip_row: - iny - cpy #5 - bne .check_row - rts +; keyboard: ; reads keyboard registers and stores the column and row of the first key found +; ; TODO: make this routine store up to 8 indices (for 8 key rollover) +; ldy #0 +; .check_row: ; loop through each row +; lda kb_row, y +; beq .skip_row ; if row has no key pressed, skip checking which key +; ; jmp key_down +; sta kb_row_cache, y ; if key pressed, cache it +; lda kb_row, y +; cmp kb_row_cache, y ; has key changed? +; beq key_down +; .skip_row: +; iny +; cpy #5 +; bne .check_row +; rts -key_down: ; a is loaded with the row byte - phy - sty key_row ; store character row - ldy #0 - .find_col: ; test each row bit, store column if key pressed - lsr ; test bit 7 - bcs store_col ; if unset, don't go store character columnb - .skip: - iny - cpy #8 - bne .find_col ; loop until we've checked each bit +; key_down: ; a is loaded with the row byte +; phy +; sty key_row ; store character row +; ldy #0 +; .find_col: ; test each row bit, store column if key pressed +; lsr ; test bit 7 +; bcs store_col ; if unset, don't go store character columnb +; .skip: +; iny +; cpy #8 +; bne .find_col ; loop until we've checked each bit +; rts -store_col: - sty key_col +; store_col: +; sty key_col +; jsr print +; rts -keymap_index: - push - lda key_col - stz 1, x - sta 0, x - push - lda #8 - stz 1, x - sta 0, x - push - lda key_row - stz 1, x - sta 0, x - jsr mult - jsr plus - lda 0, x - tay -print: ; we've stored the character position, now let's + + +print: ; x y -- prints the key indexed with key_col and key_row at position x, y + + keymap_index: + push + lda key_col + stz 1, x + sta 0, x + push + lda #8 + stz 1, x + sta 0, x + push + lda key_row + stz 1, x + sta 0, x + jsr mult + jsr plus + lda 0, x + tay lda keymap, y - ldy cursor - sta $6000, y - inc cursor - ply + push + sta 0, x + stz 1, x + jsr draw_char rts -keymap: - .byte "?outrew?" - .byte "?piygsq?" - .byte "a??khvd?" - .byte "42ljbfz?" - .byte "31?mncx?" - .byte "????? m" + keymap: + .byte "?outrew?" + .byte "?piygsq?" + .byte "a??khvd?" + .byte "42ljbfz?" + .byte "31?mncx?" + .byte "????? m" draw: ; push_coords #0, #0 diff --git a/src/roms/george.rom b/src/roms/george.rom index a7091a8e00f88ed2a0ebac52c736b2d67e2d90a0..e4c3dc3e846b8472efaa53609b9691a1581e37a0 100644 GIT binary patch delta 186 zcmZo@U}|V!s;^kYu##Z`!%T*RnGA_D8Ioo)B+q0>naPkklOb&;L;8sePa{?`^fEB5 zWbI`H5~og0Whh~U(F)EDKDG^~POW8RDq)<;aO%`b4hX%L0W6^Kq(R|I!&ZhBJBxv; zKsptcG$h#PmzETzmfPDGWL8c*s-?WHp^+iMW2FOB1z69@1R#&GgaN2MBSB%^W+BGc Ob(0Gi-IyEBHUI$V@Ja6g delta 239 zcmZo@U}|V!s;^kYuu@?G!%T*RnGA_D8Ioo)B+q0>naPkklOb&;L;8sePa_mG8+?=- z7BK8&aQWaklbH!fzak6VWM=xncH#i*g{=uuJq%0>7`!%EvYt4=ap6Y~Bh#rw5EHYRA($L6|;IY!-)TyZq eC5#YtD-(b`#u5ggmW%|2FB{Liu48TxZUg`luy{ZK diff --git a/src/roms/macro.inc b/src/roms/macro.inc index ec1d950..96a3471 100644 --- a/src/roms/macro.inc +++ b/src/roms/macro.inc @@ -1,7 +1,7 @@ .macro breakpoint ; $02 isn't a valid instruction, the emulator will see this and halt, dump memory contents .byte $02 .endm - + .macro pop ; drops a data stack cell inx inx diff --git a/src/roms/template.asm b/src/roms/template.asm index dd200e9..5d3029e 100644 --- a/src/roms/template.asm +++ b/src/roms/template.asm @@ -27,7 +27,7 @@ cleardisplay: cli main: - jmp draw + jsr draw jmp main draw: