Continue working on DMA sound.
Cleanup timer.rs run cargo fmt restore debugging continue&frame commands Fix bug introduced in previous commit causing the bios animation to hang Former-commit-id: 188acaa1121503a97f2d3be816f6f57835e17fe1
This commit is contained in:
parent
70cb99161d
commit
fefeddbc40
|
@ -57,6 +57,8 @@ pub struct Core {
|
|||
pub verbose: bool,
|
||||
|
||||
pub trace_opcodes: bool,
|
||||
|
||||
pub trace_exceptions: bool,
|
||||
}
|
||||
|
||||
pub type CpuExecResult = CpuResult<()>;
|
||||
|
|
|
@ -30,7 +30,7 @@ impl Core {
|
|||
Irq => (CpuMode::Irq, true, false),
|
||||
Fiq => (CpuMode::Fiq, true, true),
|
||||
};
|
||||
if self.verbose {
|
||||
if self.trace_exceptions {
|
||||
println!(
|
||||
"{}: {:?}, pc: {:#x}, new_mode: {:?} old_mode: {:?}",
|
||||
"Exception".cyan(),
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use std::collections::VecDeque;
|
||||
|
||||
use super::arm7tdmi::{Addr, Bus};
|
||||
use super::iodev::consts::{REG_FIFO_A, REG_FIFO_B};
|
||||
use super::sysbus::SysBus;
|
||||
use super::{Interrupt, IrqBitmask};
|
||||
|
||||
|
@ -99,7 +100,10 @@ impl DmaChannel {
|
|||
self.internal.src_addr = self.src;
|
||||
self.internal.dst_addr = self.dst;
|
||||
self.internal.count = self.wc;
|
||||
self.fifo_mode = timing == 3 && (self.id == 0 || self.id == 1);
|
||||
self.fifo_mode = timing == 3
|
||||
&& ctrl.repeat()
|
||||
&& (self.id == 1 || self.id == 2)
|
||||
&& (self.dst == REG_FIFO_A || self.dst == REG_FIFO_B);
|
||||
}
|
||||
self.ctrl = ctrl;
|
||||
return start_immediately;
|
||||
|
@ -133,11 +137,10 @@ impl DmaChannel {
|
|||
let fifo_mode = self.fifo_mode;
|
||||
|
||||
if fifo_mode {
|
||||
println!("FIFO Tranfer");
|
||||
for _ in 0..count {
|
||||
let v = sb.read_16(self.internal.src_addr);
|
||||
sb.write_16(self.internal.dst_addr, v);
|
||||
self.internal.src_addr += 2;
|
||||
for _ in 0..4 {
|
||||
let v = sb.read_32(self.internal.src_addr);
|
||||
sb.write_32(self.internal.dst_addr, v);
|
||||
self.internal.src_addr += 4;
|
||||
}
|
||||
} else if word_size == 4 {
|
||||
for _ in 0..count {
|
||||
|
|
|
@ -8,9 +8,6 @@ use super::gpu::*;
|
|||
use super::interrupt::*;
|
||||
use super::iodev::*;
|
||||
use super::sysbus::SysBus;
|
||||
use super::timer::TimerEvent;
|
||||
|
||||
use super::SyncedIoDevice;
|
||||
|
||||
use super::super::{AudioInterface, InputInterface, VideoInterface};
|
||||
|
||||
|
@ -51,8 +48,13 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub fn frame(&mut self) {
|
||||
#[inline]
|
||||
pub fn key_poll(&mut self) {
|
||||
self.sysbus.io.keyinput = self.input_device.borrow_mut().poll();
|
||||
}
|
||||
|
||||
pub fn frame(&mut self) {
|
||||
self.key_poll();
|
||||
while self.sysbus.io.gpu.state != GpuState::VBlank {
|
||||
self.step();
|
||||
}
|
||||
|
@ -114,7 +116,7 @@ where
|
|||
0
|
||||
};
|
||||
|
||||
io.timers.tick(cycles, &mut self.sysbus, &mut irqs);
|
||||
io.timers.step(cycles, &mut self.sysbus, &mut irqs);
|
||||
|
||||
if let Some(new_gpu_state) = io.gpu.step(cycles, &mut self.sysbus, &mut irqs) {
|
||||
match new_gpu_state {
|
||||
|
|
|
@ -28,7 +28,6 @@ pub struct IoDevices {
|
|||
pub post_boot_flag: bool,
|
||||
pub waitcnt: WaitControl, // TODO also implement 4000800
|
||||
pub haltcnt: HaltState,
|
||||
pub sound_bias: u16,
|
||||
|
||||
mem: BoxedMemory,
|
||||
}
|
||||
|
@ -46,7 +45,6 @@ impl IoDevices {
|
|||
haltcnt: HaltState::Running,
|
||||
keyinput: keypad::KEYINPUT_ALL_RELEASED,
|
||||
waitcnt: WaitControl(0),
|
||||
sound_bias: 0x200,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -87,30 +85,20 @@ impl Bus for IoDevices {
|
|||
REG_IE => io.intc.interrupt_enable.0 as u16,
|
||||
REG_IF => io.intc.interrupt_flags.0 as u16,
|
||||
|
||||
REG_TM0CNT_L => io.timers[0].timer_data,
|
||||
REG_TM0CNT_H => io.timers[0].timer_ctl.0,
|
||||
REG_TM1CNT_L => io.timers[1].timer_data,
|
||||
REG_TM1CNT_H => io.timers[1].timer_ctl.0,
|
||||
REG_TM2CNT_L => io.timers[2].timer_data,
|
||||
REG_TM2CNT_H => io.timers[2].timer_ctl.0,
|
||||
REG_TM3CNT_L => io.timers[3].timer_data,
|
||||
REG_TM3CNT_H => io.timers[3].timer_ctl.0,
|
||||
REG_TM0CNT_L..=REG_TM3CNT_H => io.timers.handle_read(io_addr),
|
||||
|
||||
REG_SOUND1CNT_L..DMA_BASE => io.sound.handle_read(io_addr),
|
||||
REG_DMA0CNT_H => io.dmac.channels[0].ctrl.0,
|
||||
REG_DMA1CNT_H => io.dmac.channels[1].ctrl.0,
|
||||
REG_DMA2CNT_H => io.dmac.channels[2].ctrl.0,
|
||||
REG_DMA3CNT_H => io.dmac.channels[3].ctrl.0,
|
||||
|
||||
REG_SOUNDBIAS => io.sound_bias,
|
||||
|
||||
REG_WAITCNT => io.waitcnt.0,
|
||||
|
||||
REG_POSTFLG => io.post_boot_flag as u16,
|
||||
REG_HALTCNT => 0,
|
||||
REG_KEYINPUT => io.keyinput as u16,
|
||||
|
||||
REG_SOUND1CNT_L..=DMA_BASE => io.sound.handle_read(io_addr),
|
||||
|
||||
_ => {
|
||||
// println!(
|
||||
// "Unimplemented read from {:x} {}",
|
||||
|
@ -216,29 +204,11 @@ impl Bus for IoDevices {
|
|||
REG_IE => io.intc.interrupt_enable.0 = value,
|
||||
REG_IF => io.intc.interrupt_flags.0 &= !value,
|
||||
|
||||
REG_TM0CNT_L => {
|
||||
io.timers[0].timer_data = value;
|
||||
io.timers[0].initial_data = value;
|
||||
}
|
||||
REG_TM0CNT_H => io.timers.write_timer_ctl(0, value),
|
||||
REG_TM0CNT_L..=REG_TM3CNT_H => io.timers.handle_write(io_addr, value),
|
||||
|
||||
REG_TM1CNT_L => {
|
||||
io.timers[1].timer_data = value;
|
||||
io.timers[1].initial_data = value;
|
||||
REG_SOUND1CNT_L..DMA_BASE => {
|
||||
io.sound.handle_write(io_addr, value);
|
||||
}
|
||||
REG_TM1CNT_H => io.timers.write_timer_ctl(1, value),
|
||||
|
||||
REG_TM2CNT_L => {
|
||||
io.timers[2].timer_data = value;
|
||||
io.timers[2].initial_data = value;
|
||||
}
|
||||
REG_TM2CNT_H => io.timers.write_timer_ctl(2, value),
|
||||
|
||||
REG_TM3CNT_L => {
|
||||
io.timers[3].timer_data = value;
|
||||
io.timers[3].initial_data = value;
|
||||
}
|
||||
REG_TM3CNT_H => io.timers.write_timer_ctl(3, value),
|
||||
|
||||
DMA_BASE..=REG_DMA3CNT_H => {
|
||||
let ofs = io_addr - DMA_BASE;
|
||||
|
@ -246,8 +216,6 @@ impl Bus for IoDevices {
|
|||
io.dmac.write_16(channel_id, ofs % 12, value)
|
||||
}
|
||||
|
||||
REG_SOUNDBIAS => io.sound_bias = value & 0xc3fe,
|
||||
|
||||
REG_WAITCNT => io.waitcnt.0 = value,
|
||||
|
||||
REG_POSTFLG => io.post_boot_flag = value != 0,
|
||||
|
@ -260,9 +228,6 @@ impl Bus for IoDevices {
|
|||
}
|
||||
}
|
||||
|
||||
REG_SOUND1CNT_L..=DMA_BASE => {
|
||||
io.sound.handle_write(io_addr, value);
|
||||
}
|
||||
_ => {
|
||||
// println!(
|
||||
// "Unimplemented write to {:x} {}",
|
||||
|
|
|
@ -36,6 +36,12 @@ impl Default for DmaSound {
|
|||
}
|
||||
}
|
||||
|
||||
const REG_FIFO_A_L: u32 = REG_FIFO_A;
|
||||
const REG_FIFO_A_H: u32 = REG_FIFO_A + 2;
|
||||
|
||||
const REG_FIFO_B_L: u32 = REG_FIFO_B;
|
||||
const REG_FIFO_B_H: u32 = REG_FIFO_B + 2;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SoundController {
|
||||
sample_rate_to_cpu_freq: usize, // how many "cycles" are a sample?
|
||||
|
@ -66,6 +72,8 @@ pub struct SoundController {
|
|||
sqr1_initial_vol: usize,
|
||||
sqr1_cur_vol: usize,
|
||||
|
||||
sound_bias: u16,
|
||||
|
||||
sound_a: DmaSound,
|
||||
sound_b: DmaSound,
|
||||
}
|
||||
|
@ -95,6 +103,7 @@ impl SoundController {
|
|||
sqr1_step_increase: false,
|
||||
sqr1_initial_vol: 0,
|
||||
sqr1_cur_vol: 0,
|
||||
sound_bias: 0x200,
|
||||
sound_a: Default::default(),
|
||||
sound_b: Default::default(),
|
||||
}
|
||||
|
@ -137,6 +146,8 @@ impl SoundController {
|
|||
| cbit(14, self.sound_b.timer_select != 0)
|
||||
}
|
||||
|
||||
REG_SOUNDBIAS => self.sound_bias,
|
||||
|
||||
_ => {
|
||||
println!(
|
||||
"Unimplemented read from {:x} {}",
|
||||
|
@ -174,7 +185,7 @@ impl SoundController {
|
|||
}
|
||||
|
||||
if !self.mse {
|
||||
println!("MSE disabled, refusing to write");
|
||||
// println!("MSE disabled, refusing to write");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -227,16 +238,18 @@ impl SoundController {
|
|||
}
|
||||
}
|
||||
|
||||
REG_FIFO_A => {
|
||||
self.sound_a.fifo.write((value & 0xff00 >> 8) as i8);
|
||||
REG_FIFO_A_L | REG_FIFO_A_H => {
|
||||
self.sound_a.fifo.write(((value >> 8) & 0xff) as i8);
|
||||
self.sound_a.fifo.write((value & 0xff) as i8);
|
||||
}
|
||||
|
||||
REG_FIFO_B => {
|
||||
self.sound_b.fifo.write((value & 0xff00 >> 8) as i8);
|
||||
REG_FIFO_B_L | REG_FIFO_B_H => {
|
||||
self.sound_b.fifo.write(((value >> 8) & 0xff) as i8);
|
||||
self.sound_b.fifo.write((value & 0xff) as i8);
|
||||
}
|
||||
|
||||
REG_SOUNDBIAS => self.sound_bias = value & 0xc3fe,
|
||||
|
||||
_ => {
|
||||
println!(
|
||||
"Unimplemented write to {:x} {}",
|
||||
|
|
|
@ -1,29 +1,23 @@
|
|||
use super::interrupt::{Interrupt, IrqBitmask};
|
||||
use super::iodev::consts::*;
|
||||
use super::sysbus::SysBus;
|
||||
use super::SyncedIoDevice;
|
||||
|
||||
use num::FromPrimitive;
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
#[derive(Debug)]
|
||||
pub struct Timer {
|
||||
// registers
|
||||
pub timer_ctl: TimerCtl,
|
||||
pub timer_data: u16,
|
||||
pub ctl: TimerCtl,
|
||||
pub data: u16,
|
||||
|
||||
irq: Interrupt,
|
||||
|
||||
timer_id: usize,
|
||||
reg: u32,
|
||||
target: u32,
|
||||
fired: bool,
|
||||
pub initial_data: u16,
|
||||
|
||||
pub cycles: usize,
|
||||
}
|
||||
|
||||
pub enum TimerEvent {
|
||||
Overflow(usize, usize),
|
||||
Increment(usize),
|
||||
}
|
||||
|
||||
impl Timer {
|
||||
pub fn new(timer_id: usize) -> Timer {
|
||||
if timer_id > 3 {
|
||||
|
@ -31,16 +25,16 @@ impl Timer {
|
|||
}
|
||||
Timer {
|
||||
timer_id: timer_id,
|
||||
..Timer::default()
|
||||
irq: Interrupt::from_usize(timer_id + 8).unwrap(),
|
||||
data: 0,
|
||||
ctl: TimerCtl(0),
|
||||
initial_data: 0,
|
||||
cycles: 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_irq(&self) -> Interrupt {
|
||||
Interrupt::from_usize(self.timer_id + 8).unwrap()
|
||||
}
|
||||
|
||||
fn frequency(&self) -> usize {
|
||||
match self.timer_ctl.prescalar() {
|
||||
match self.ctl.prescalar() {
|
||||
0 => 1,
|
||||
1 => 64,
|
||||
2 => 256,
|
||||
|
@ -48,29 +42,6 @@ impl Timer {
|
|||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_cycles(&mut self, cycles: usize, irqs: &mut IrqBitmask) -> TimerEvent {
|
||||
let mut num_overflows = 0;
|
||||
self.cycles += cycles;
|
||||
|
||||
let frequency = self.frequency();
|
||||
while self.cycles >= frequency {
|
||||
self.cycles -= frequency;
|
||||
self.timer_data = self.timer_data.wrapping_add(1);
|
||||
if self.timer_data == 0 {
|
||||
if self.timer_ctl.irq_enabled() {
|
||||
irqs.add_irq(self.get_irq());
|
||||
}
|
||||
self.timer_data = self.initial_data;
|
||||
num_overflows += 1;
|
||||
}
|
||||
}
|
||||
if num_overflows > 0 {
|
||||
return TimerEvent::Overflow(self.timer_id, num_overflows);
|
||||
} else {
|
||||
return TimerEvent::Increment(self.timer_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -96,14 +67,14 @@ impl Timers {
|
|||
pub fn new() -> Timers {
|
||||
Timers {
|
||||
timers: [Timer::new(0), Timer::new(1), Timer::new(2), Timer::new(3)],
|
||||
trace: false,
|
||||
trace: true,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_timer_ctl(&mut self, id: usize, value: u16) {
|
||||
let old_enabled = self[id].timer_ctl.enabled();
|
||||
self[id].timer_ctl.0 = value;
|
||||
let new_enabled = self[id].timer_ctl.enabled();
|
||||
let old_enabled = self[id].ctl.enabled();
|
||||
self[id].ctl.0 = value;
|
||||
let new_enabled = self[id].ctl.enabled();
|
||||
if self.trace && old_enabled != new_enabled {
|
||||
println!(
|
||||
"TMR{} {}",
|
||||
|
@ -113,36 +84,88 @@ impl Timers {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn tick(
|
||||
&mut self,
|
||||
cycles: usize,
|
||||
sb: &mut SysBus,
|
||||
irqs: &mut IrqBitmask,
|
||||
) -> Option<TimerEvent> {
|
||||
for i in 0..4 {
|
||||
if self[i].timer_ctl.enabled() && !self[i].timer_ctl.cascade() {
|
||||
let event = self[i].add_cycles(cycles, irqs);
|
||||
match event {
|
||||
TimerEvent::Overflow(_, num_overflows) => {
|
||||
pub fn handle_read(&self, io_addr: u32) -> u16 {
|
||||
match io_addr {
|
||||
REG_TM0CNT_L => self.timers[0].data,
|
||||
REG_TM0CNT_H => self.timers[0].ctl.0,
|
||||
REG_TM1CNT_L => self.timers[1].data,
|
||||
REG_TM1CNT_H => self.timers[1].ctl.0,
|
||||
REG_TM2CNT_L => self.timers[2].data,
|
||||
REG_TM2CNT_H => self.timers[2].ctl.0,
|
||||
REG_TM3CNT_L => self.timers[3].data,
|
||||
REG_TM3CNT_H => self.timers[3].ctl.0,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_write(&mut self, io_addr: u32, value: u16) {
|
||||
match io_addr {
|
||||
REG_TM0CNT_L => {
|
||||
self.timers[0].data = value;
|
||||
self.timers[0].initial_data = value;
|
||||
}
|
||||
REG_TM0CNT_H => self.write_timer_ctl(0, value),
|
||||
|
||||
REG_TM1CNT_L => {
|
||||
self.timers[1].data = value;
|
||||
self.timers[1].initial_data = value;
|
||||
}
|
||||
REG_TM1CNT_H => self.write_timer_ctl(1, value),
|
||||
|
||||
REG_TM2CNT_L => {
|
||||
self.timers[2].data = value;
|
||||
self.timers[2].initial_data = value;
|
||||
}
|
||||
REG_TM2CNT_H => self.write_timer_ctl(2, value),
|
||||
|
||||
REG_TM3CNT_L => {
|
||||
self.timers[3].data = value;
|
||||
self.timers[3].initial_data = value;
|
||||
}
|
||||
REG_TM3CNT_H => self.write_timer_ctl(3, value),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn update_timer(&mut self, id: usize, cycles: usize, sb: &mut SysBus, irqs: &mut IrqBitmask) {
|
||||
let timer = &mut self.timers[id];
|
||||
timer.cycles += cycles;
|
||||
let mut num_overflows = 0;
|
||||
let freq = timer.frequency();
|
||||
while timer.cycles >= freq {
|
||||
timer.cycles -= freq;
|
||||
timer.data = timer.data.wrapping_add(1);
|
||||
if timer.data == 0 {
|
||||
if self.trace {
|
||||
println!("TMR{} overflown!", i);
|
||||
println!("TMR{} overflown!", id);
|
||||
}
|
||||
if i != 3 {
|
||||
let next_i = i + 1;
|
||||
if self[next_i].timer_ctl.cascade() {
|
||||
self[next_i].add_cycles(num_overflows, irqs);
|
||||
if timer.ctl.irq_enabled() {
|
||||
irqs.add_irq(timer.irq);
|
||||
}
|
||||
timer.data = timer.initial_data;
|
||||
num_overflows += 1;
|
||||
}
|
||||
}
|
||||
if i == 0 || i == 1 {
|
||||
sb.io.sound.handle_timer_overflow(&mut sb.io.dmac, i);
|
||||
|
||||
if num_overflows > 0 {
|
||||
if id != 3 {
|
||||
let next_timer = &mut self.timers[id + 1];
|
||||
if next_timer.ctl.cascade() {
|
||||
self.update_timer(id + 1, num_overflows, sb, irqs);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
return Some(event);
|
||||
if id == 0 || id == 1 {
|
||||
sb.io.sound.handle_timer_overflow(&mut sb.io.dmac, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn step(&mut self, cycles: usize, sb: &mut SysBus, irqs: &mut IrqBitmask) {
|
||||
for i in 0..4 {
|
||||
if self.timers[i].ctl.enabled() && !self.timers[i].ctl.cascade() {
|
||||
self.update_timer(i, cycles, sb, irqs);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ bitflags! {
|
|||
const TRACE_OPCODE = 0b00000010;
|
||||
const TRACE_DMA = 0b00000100;
|
||||
const TRACE_TIMERS = 0b000001000;
|
||||
const TRACE_EXCEPTIONS = 0b000001000;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,31 +109,30 @@ where
|
|||
}
|
||||
println!("{}\n", self.gba.cpu);
|
||||
}
|
||||
// Continue => {
|
||||
// self.ctrlc_flag.store(true, Ordering::SeqCst);
|
||||
// while self.ctrlc_flag.load(Ordering::SeqCst) {
|
||||
// let start_time = time::Instant::now();
|
||||
// self.gba.update_key_state();
|
||||
// match self.gba.check_breakpoint() {
|
||||
// Some(addr) => {
|
||||
// println!("Breakpoint reached! @{:x}", addr);
|
||||
// break;
|
||||
// }
|
||||
// _ => {
|
||||
// self.gba.step();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// Frame(count) => {
|
||||
// use super::time::PreciseTime;
|
||||
// let start = PreciseTime::now();
|
||||
// for _ in 0..count {
|
||||
// self.gba.frame();
|
||||
// }
|
||||
// let end = PreciseTime::now();
|
||||
// println!("that took {} seconds", start.to(end));
|
||||
// }
|
||||
Continue => {
|
||||
self.ctrlc_flag.store(true, Ordering::SeqCst);
|
||||
while self.ctrlc_flag.load(Ordering::SeqCst) {
|
||||
self.gba.key_poll();
|
||||
match self.gba.check_breakpoint() {
|
||||
Some(addr) => {
|
||||
println!("Breakpoint reached! @{:x}", addr);
|
||||
break;
|
||||
}
|
||||
_ => {
|
||||
self.gba.step();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Frame(count) => {
|
||||
use super::time::PreciseTime;
|
||||
let start = PreciseTime::now();
|
||||
for _ in 0..count {
|
||||
self.gba.frame();
|
||||
}
|
||||
let end = PreciseTime::now();
|
||||
println!("that took {} seconds", start.to(end));
|
||||
}
|
||||
HexDump(addr, nbytes) => {
|
||||
let bytes = self.gba.sysbus.get_bytes(addr..addr + nbytes);
|
||||
hexdump::hexdump(&bytes);
|
||||
|
@ -205,6 +205,17 @@ where
|
|||
}
|
||||
)
|
||||
}
|
||||
if flags.contains(TraceFlags::TRACE_EXCEPTIONS) {
|
||||
self.gba.cpu.trace_exceptions = !self.gba.cpu.trace_exceptions;
|
||||
println!(
|
||||
"[*] exception tracing {}",
|
||||
if self.gba.cpu.trace_exceptions {
|
||||
"on"
|
||||
} else {
|
||||
"off"
|
||||
}
|
||||
)
|
||||
}
|
||||
if flags.contains(TraceFlags::TRACE_DMA) {
|
||||
println!("[*] dma tracing not implemented");
|
||||
}
|
||||
|
@ -420,7 +431,7 @@ where
|
|||
"r" | "reset" => Ok(Command::Reset),
|
||||
"trace" => {
|
||||
let usage = DebuggerError::InvalidCommandFormat(String::from(
|
||||
"trace [sysbus|opcode|dma|all]",
|
||||
"trace [sysbus|opcode|dma|all|exceptions]",
|
||||
));
|
||||
if args.len() != 1 {
|
||||
Err(usage)
|
||||
|
@ -429,6 +440,7 @@ where
|
|||
let flags = match flag_str.as_ref() {
|
||||
"sysbus" => TraceFlags::TRACE_SYSBUS,
|
||||
"opcode" => TraceFlags::TRACE_OPCODE,
|
||||
"exceptions" => TraceFlags::TRACE_EXCEPTIONS,
|
||||
"dma" => TraceFlags::TRACE_DMA,
|
||||
"timers" => TraceFlags::TRACE_TIMERS,
|
||||
"all" => TraceFlags::all(),
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#![feature(asm)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(exclusive_range_pattern)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate enum_primitive_derive;
|
||||
|
|
|
@ -11,9 +11,9 @@ extern crate clap;
|
|||
|
||||
#[macro_use]
|
||||
extern crate rustboyadvance_ng;
|
||||
use rustboyadvance_ng::core::keypad;
|
||||
use rustboyadvance_ng::prelude::*;
|
||||
use rustboyadvance_ng::util::FpsCounter;
|
||||
use rustboyadvance_ng::core::keypad;
|
||||
|
||||
extern crate bit;
|
||||
use bit::BitIndex;
|
||||
|
@ -80,7 +80,6 @@ impl AudioInterface for MiniFb {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
let yaml = load_yaml!("cli.yml");
|
||||
let matches = clap::App::from_yaml(yaml).get_matches();
|
||||
|
@ -118,8 +117,14 @@ fn main() {
|
|||
}));
|
||||
|
||||
let mut fps_counter = FpsCounter::default();
|
||||
let mut gba: GameBoyAdvance<MiniFb, MiniFb, MiniFb> =
|
||||
GameBoyAdvance::new(cpu, bios_bin, cart, minifb.clone(), minifb.clone(), minifb.clone());
|
||||
let mut gba: GameBoyAdvance<MiniFb, MiniFb, MiniFb> = GameBoyAdvance::new(
|
||||
cpu,
|
||||
bios_bin,
|
||||
cart,
|
||||
minifb.clone(),
|
||||
minifb.clone(),
|
||||
minifb.clone(),
|
||||
);
|
||||
|
||||
if debug {
|
||||
gba.cpu.set_verbose(true);
|
||||
|
|
Reference in a new issue