Skip to content

Commit

Permalink
start print and data watch
Browse files Browse the repository at this point in the history
  • Loading branch information
pm100 committed Dec 30, 2023
1 parent 87905bd commit 98336aa
Show file tree
Hide file tree
Showing 9 changed files with 301 additions and 197 deletions.
74 changes: 37 additions & 37 deletions src/cpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,28 @@
Wrapper around the sim65 emulator.
Provides the calls from db65 to 6502.c
- execute_insn to execute one instruction
- read_registers to get a pointer to the register block.
- ExecuteInsn to execute one instruction
- ReadRegisters to get a pointer to the register block.
- Reset to reset the cpu
Provides the service routines that 6502.c needs
- read and write ram
- paravirt call backs
- runtime warnings and errors
Lots of unsafe code here becuase
Lots of unsafe code here because
- we are doing c calls
- we have a read / write singleton
The unsafe is limited to this file
*/

use crate::paravirt::ParaVirt;
use bitflags::bitflags;
use std::{fmt, os::raw::c_char};

// the one cpu instance
// this is because the calls to us are 'naked' c calls
static mut THECPU: Cpu = Cpu {
ram: [0; 65536],
shadow: [0; 65536],
Expand All @@ -31,15 +35,14 @@ static mut THECPU: Cpu = Cpu {
arg_array: Vec::new(),
};
pub struct Cpu {
ram: [u8; 65536],
shadow: [u8; 65536],
// registers
regs: *mut CPURegs,
exit: bool,
exit_code: u8,
sp65_addr: u8,
memcheck: Option<u16>,
arg_array: Vec<String>,
ram: [u8; 65536], // the actual 6502 ram
shadow: [u8; 65536], // a shadow of the ram, used for memcheck
regs: *mut CPURegs, // a pointer to the register block
exit: bool, // set to true when the 6502 wants to exit
exit_code: u8, // the exit code
sp65_addr: u8, // the location of the cc65 'stack' pointer
memcheck: Option<u16>, // the address of the last memcheck failure
arg_array: Vec<String>, // the command line arguments
}

// our callable functions into sim65
Expand All @@ -61,7 +64,6 @@ extern "C" fn MemWriteByte(_addr: u32, _val: u8) {
THECPU.shadow[_addr as usize] = 1;
}
}

#[no_mangle]
extern "C" fn MemReadWord(addr: u32) -> u32 {
unsafe {
Expand All @@ -71,7 +73,6 @@ extern "C" fn MemReadWord(addr: u32) -> u32 {
} else if THECPU.shadow[(addr + 1) as usize] == 0 {
THECPU.memcheck = Some(addr as u16 + 1);
}

w
}
}
Expand All @@ -87,7 +88,6 @@ extern "C" fn MemReadByte(addr: u32) -> u8 {
}
#[no_mangle]
extern "C" fn MemReadZPWord(mut addr: u8) -> u16 {
//println!("MemReadZPWord");
unsafe {
let b1 = THECPU.inner_read_byte(addr as u16) as u16;
addr = addr.wrapping_add(1);
Expand All @@ -106,11 +106,10 @@ extern "C" fn Error(_format: *const c_char, _x: u32, _y: u32) -> u32 {
return 0;
}
#[no_mangle]

extern "C" fn ParaVirtHooks(_regs: *mut CPURegs) {
let _pc = Cpu::read_pc();
ParaVirt::pv_hooks();
}
// the structure we gtr a pointer to with ReadRegisters
#[repr(C)]
pub struct CPURegs {
pub ac: u32, /* Accumulator */
Expand Down Expand Up @@ -269,26 +268,7 @@ impl Cpu {
self.ram[(addr + 1) as usize] = (val >> 8) as u8;
}
}
#[test]
fn regreadwrite() {
Cpu::reset();
Cpu::write_ac(1);
Cpu::write_xr(2);
Cpu::write_yr(3);
Cpu::write_zr(4);
Cpu::write_sr(5);
Cpu::write_sp(6);
Cpu::write_pc(0x7777);

assert_eq!(Cpu::read_ac(), 1);
assert_eq!(Cpu::read_xr(), 2);
assert_eq!(Cpu::read_yr(), 3);
assert_eq!(Cpu::read_zr(), 4);
assert_eq!(Cpu::read_sr(), 5);
assert_eq!(Cpu::read_sp(), 6);
assert_eq!(Cpu::read_pc(), 0x7777);
}
use bitflags::bitflags;
bitflags! {
#[derive(Copy, Clone, Default)]
pub(crate) struct Status:u8{
Expand Down Expand Up @@ -347,3 +327,23 @@ impl fmt::Debug for Status {
write!(f, "{}", str)
}
}

#[test]
fn regreadwrite() {
Cpu::reset();
Cpu::write_ac(1);
Cpu::write_xr(2);
Cpu::write_yr(3);
Cpu::write_zr(4);
Cpu::write_sr(5);
Cpu::write_sp(6);
Cpu::write_pc(0x7777);

assert_eq!(Cpu::read_ac(), 1);
assert_eq!(Cpu::read_xr(), 2);
assert_eq!(Cpu::read_yr(), 3);
assert_eq!(Cpu::read_zr(), 4);
assert_eq!(Cpu::read_sr(), 5);
assert_eq!(Cpu::read_sp(), 6);
assert_eq!(Cpu::read_pc(), 0x7777);
}
37 changes: 26 additions & 11 deletions src/debugger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,8 @@ use crate::{cpu::Cpu, execute::StopReason, loader};
pub struct Debugger {
symbols: HashMap<String, u16>,
pub break_points: HashMap<u16, BreakPoint>,
//pub break_points: HashMap<u16, BreakPoint>,
// pub(crate) watch_points: HashMap<u16, WatchPoint>,
pub(crate) next_bp: Option<u16>,
_loader_sp: u8,
loader_start: u16,
pub(crate) dis_line: String,
pub(crate) ticks: usize,
Expand All @@ -45,13 +44,24 @@ pub struct BreakPoint {
pub(crate) number: usize,
pub(crate) temp: bool,
}
pub enum WatchType {
Read,
Write,
ReadWrite,
}
pub struct WatchPoint {
pub(crate) addr: u16,
pub(crate) symbol: String,
pub(crate) number: usize,
pub(crate) Watch: bool,
}
impl Debugger {
pub fn new() -> Self {
Cpu::reset();
Self {
symbols: HashMap::new(),
break_points: HashMap::new(),
_loader_sp: 0,

loader_start: 0,
dis_line: String::new(),
ticks: 0,
Expand Down Expand Up @@ -145,11 +155,9 @@ impl Debugger {
self.break_points.iter().map(|bp| bp.1.addr).collect()
}
pub fn go(&mut self) -> Result<StopReason> {
self.core_run()
}
fn state(&self) {
println!("pc={:04x}", Cpu::read_pc());
self.execute(0) // 0 = forever
}

pub fn next(&mut self) -> Result<StopReason> {
let next_inst = Cpu::read_byte(Cpu::read_pc());
let reason = if next_inst == 0x20 {
Expand All @@ -170,9 +178,7 @@ impl Debugger {
pub fn step(&mut self) -> Result<StopReason> {
self.execute(1)
}
fn core_run(&mut self) -> Result<StopReason> {
self.execute(0) // 0 = forever
}

pub fn run(&mut self, cmd_args: Vec<&String>) -> Result<StopReason> {
Cpu::write_word(0xFFFC, self.loader_start);
Cpu::reset();
Expand All @@ -181,7 +187,7 @@ impl Debugger {
Cpu::push_arg(&cmd_args[i])
}
self.stack_frames.clear();
self.core_run()
self.execute(0) // 0 = forever
}
pub fn get_chunk(&self, addr: u16, mut len: u16) -> Result<Vec<u8>> {
let mut v = Vec::new();
Expand All @@ -192,6 +198,11 @@ impl Debugger {
}
Ok(v)
}

// converts a string representing an address into an address
// if string starts with '.' it is a symbol lookup
// if string starts with '$' it is a hex number
// else it is a decimal number
pub fn convert_addr(&self, addr_str: &str) -> Result<u16> {
if let Some(sym) = self.symbols.get(addr_str) {
return Ok(*sym);
Expand All @@ -203,6 +214,10 @@ impl Debugger {
}
Ok(u16::from_str_radix(addr_str, 10)?)
}

// reverse of convert_addr.
// tried to find a symbol matching an address
// if not found it returns a numberic string
pub fn symbol_lookup(&self, addr: u16) -> String {
for (name, sym_addr) in &self.symbols {
if *sym_addr == addr {
Expand Down
2 changes: 2 additions & 0 deletions src/dis.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/*
Disassembler portion of db65. Placed in a separate file for clarity
liberally copied from pm100/v65
*/

use crate::debugger::Debugger;
Expand Down
18 changes: 16 additions & 2 deletions src/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,17 @@ impl Debugger {
let counting = count > 0;
let reason = loop {
let pc = Cpu::read_pc();
// is this a stack manipulation instruction?
/*
Stack tracking code
if we hit a jsr, we push the return address and the stack pointer
onto our own tracking stack. If we hit a rts, we pop the frame
Also tracks push and pulls
Does not deal with interrupts since sim65 does not support them
Includes stack balance check logic
*/
let inst = Cpu::read_byte(pc);
match inst {
0x20 => {
Expand Down Expand Up @@ -88,7 +98,11 @@ impl Debugger {
}
_ => {}
};

// Now execute the instruction
self.ticks += Cpu::execute_insn() as usize;

// invalid memory read check
if self.enable_mem_check {
if let Some(addr) = Cpu::get_memcheck() {
Cpu::clear_memcheck();
Expand Down Expand Up @@ -116,7 +130,7 @@ impl Debugger {
}
break StopReason::BreakPoint(pc);
}

// PVExit called?
if let Some(exit_code) = Cpu::exit_done() {
break StopReason::Exit(exit_code);
}
Expand Down
4 changes: 4 additions & 0 deletions src/loader.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
reads binary and loads it into RAM
*/

use anyhow::{bail, Result};
use std::fs::File;
use std::io::{BufReader, Bytes, Read};
Expand Down
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ mod execute;
mod loader;
mod paravirt;
mod shell;
mod syntax;
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
struct Cli {
Expand Down
Loading

0 comments on commit 98336aa

Please sign in to comment.