Skip to content

Commit

Permalink
weird bug
Browse files Browse the repository at this point in the history
  • Loading branch information
Lokathor committed Jun 3, 2024
1 parent d3fdb93 commit e4024d6
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 7 deletions.
16 changes: 9 additions & 7 deletions dump.bat
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
cargo build --examples

arm-none-eabi-objdump --headers --disassemble --demangle --architecture=armv4t --no-show-raw-insn -Mreg-names-std target/thumbv4t-none-eabi/debug/examples/basic_keyinput >target/ex-basic_keyinput.txt
arm-none-eabi-objdump --headers --disassemble --demangle --architecture=armv4t --no-show-raw-insn -Mreg-names-std --visualize-jumps target/thumbv4t-none-eabi/debug/examples/basic_keyinput >target/ex-basic_keyinput.txt

arm-none-eabi-objdump --headers --disassemble --demangle --architecture=armv4t --no-show-raw-insn -Mreg-names-std target/thumbv4t-none-eabi/debug/examples/do_nothing >target/ex-do_nothing.txt
arm-none-eabi-objdump --headers --disassemble --demangle --architecture=armv4t --no-show-raw-insn -Mreg-names-std --visualize-jumps target/thumbv4t-none-eabi/debug/examples/do_nothing >target/ex-do_nothing.txt

arm-none-eabi-objdump --headers --disassemble --demangle --architecture=armv4t --no-show-raw-insn -Mreg-names-std target/thumbv4t-none-eabi/debug/examples/mode0 >target/ex-mode0.txt
arm-none-eabi-objdump --headers --disassemble --demangle --architecture=armv4t --no-show-raw-insn -Mreg-names-std --visualize-jumps target/thumbv4t-none-eabi/debug/examples/mode0 >target/ex-mode0.txt

arm-none-eabi-objdump --headers --disassemble --demangle --architecture=armv4t --no-show-raw-insn -Mreg-names-std target/thumbv4t-none-eabi/debug/examples/mode3 >target/ex-mode3.txt
arm-none-eabi-objdump --headers --disassemble --demangle --architecture=armv4t --no-show-raw-insn -Mreg-names-std --visualize-jumps target/thumbv4t-none-eabi/debug/examples/mode3 >target/ex-mode3.txt

arm-none-eabi-objdump --headers --disassemble --demangle --architecture=armv4t --no-show-raw-insn -Mreg-names-std target/thumbv4t-none-eabi/debug/examples/mode4 >target/ex-mode4.txt
arm-none-eabi-objdump --headers --disassemble --demangle --architecture=armv4t --no-show-raw-insn -Mreg-names-std --visualize-jumps target/thumbv4t-none-eabi/debug/examples/mode4 >target/ex-mode4.txt

arm-none-eabi-objdump --headers --disassemble --demangle --architecture=armv4t --no-show-raw-insn -Mreg-names-std target/thumbv4t-none-eabi/debug/examples/mode5 >target/ex-mode5.txt
arm-none-eabi-objdump --headers --disassemble --demangle --architecture=armv4t --no-show-raw-insn -Mreg-names-std --visualize-jumps target/thumbv4t-none-eabi/debug/examples/mode5 >target/ex-mode5.txt

arm-none-eabi-objdump --headers --disassemble --demangle --architecture=armv4t --no-show-raw-insn -Mreg-names-std target/thumbv4t-none-eabi/debug/examples/paddle_ball >target/ex-paddle_ball.txt
arm-none-eabi-objdump --headers --disassemble --demangle --architecture=armv4t --no-show-raw-insn -Mreg-names-std --visualize-jumps target/thumbv4t-none-eabi/debug/examples/paddle_ball >target/ex-paddle_ball.txt

arm-none-eabi-objdump --headers --disassemble --demangle --architecture=armv4t --no-show-raw-insn -Mreg-names-std --visualize-jumps target/thumbv4t-none-eabi/debug/examples/timer >target/ex-timer.txt
43 changes: 43 additions & 0 deletions examples/timer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#![no_std]
#![no_main]

use gba::{
asm_runtime::USER_IRQ_HANDLER,
bios::VBlankIntrWait,
gba_cell::GbaCell,
mmio::{BACKDROP_COLOR, DISPCNT, DISPSTAT, IE, IME, TIMER0_CONTROL},
timers::{CpusPerTick, TimerControl},
video::{Color, DisplayControl, DisplayStatus},
IrqBits,
};

static SECONDS: GbaCell<u32> = GbaCell::new(0);

gba::panic_handler!(mgba_log_err);

#[no_mangle]
extern "C" fn main() -> ! {
USER_IRQ_HANDLER.write(Some(irq_handler));
IE.write(IrqBits::new().with_vblank(true).with_timer0(true));
IME.write(true);
DISPSTAT.write(DisplayStatus::new().with_vblank_irq(true));

TIMER0_CONTROL.write(
TimerControl::new()
.with_enabled(true)
.with_send_irq(true)
// .with_cpus_per_tick(CpusPerTick::_64),
);

DISPCNT.write(DisplayControl::new().with_bg_mode(3));
loop {
VBlankIntrWait();
BACKDROP_COLOR.write(Color(SECONDS.read() as u16));
}
}

extern "C" fn irq_handler(bits: IrqBits) {
if bits.timer0() {
SECONDS.write(SECONDS.read().wrapping_add(1));
}
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ pub mod per_project_setup;
pub mod per_system_setup;
pub mod random;
pub mod sample_art;
pub mod timers;
pub mod video;

#[cfg(feature = "critical-section")]
Expand Down
40 changes: 40 additions & 0 deletions src/mmio/peripheral_controls.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use crate::timers::TimerControl;

use super::*;

/// Display Control setting.
Expand Down Expand Up @@ -125,6 +127,44 @@ pub const DMA3_TRANSFER_COUNT: VolAddress<u16, (), Unsafe> =
pub const DMA3_CONTROL: VolAddress<DmaControl, SOGBA, Unsafe> =
unsafe { VolAddress::new(0x0400_00DE) };

/// Timer0's current counter value.
pub const TIMER0_COUNTER: RoAddr<u16> = unsafe { VolAddress::new(0x0400_0100) };
/// Timer1's current counter value.
pub const TIMER1_COUNTER: RoAddr<u16> = unsafe { VolAddress::new(0x0400_0104) };
/// Timer2's current counter value.
pub const TIMER2_COUNTER: RoAddr<u16> = unsafe { VolAddress::new(0x0400_0108) };
/// Timer3's current counter value.
pub const TIMER3_COUNTER: RoAddr<u16> = unsafe { VolAddress::new(0x0400_010C) };

/// The value for Timer0 to reload on overflow on when the `start` bit is newly
/// set.
pub const TIMER0_RELOAD: WoAddr<u16> = unsafe { VolAddress::new(0x0400_0100) };
/// The value for Timer1 to reload on overflow on when the `start` bit is newly
/// set.
pub const TIMER1_RELOAD: WoAddr<u16> = unsafe { VolAddress::new(0x0400_0104) };
/// The value for Timer2 to reload on overflow on when the `start` bit is newly
/// set.
pub const TIMER2_RELOAD: WoAddr<u16> = unsafe { VolAddress::new(0x0400_0108) };
/// The value for Timer3 to reload on overflow on when the `start` bit is newly
/// set.
pub const TIMER3_RELOAD: WoAddr<u16> = unsafe { VolAddress::new(0x0400_010C) };

/// Control bits for Timer 0.
pub const TIMER0_CONTROL: PlainAddr<TimerControl> =
unsafe { VolAddress::new(0x0400_0102) };

/// Control bits for Timer 1.
pub const TIMER1_CONTROL: PlainAddr<TimerControl> =
unsafe { VolAddress::new(0x0400_0106) };

/// Control bits for Timer 2.
pub const TIMER2_CONTROL: PlainAddr<TimerControl> =
unsafe { VolAddress::new(0x0400_010A) };

/// Control bits for Timer 3.
pub const TIMER3_CONTROL: PlainAddr<TimerControl> =
unsafe { VolAddress::new(0x0400_010E) };

/// Key Input (read-only).
///
/// Gives the low-active button state of all system buttons.
Expand Down
49 changes: 49 additions & 0 deletions src/timers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//! Timer related data types.

use bitfrob::{u8_with_bit, u8_with_region};

/// Control bits for one of the GBA's four timers.
#[derive(Debug, Clone, Copy)]
#[repr(transparent)]
pub struct TimerControl(u8);
impl TimerControl {
/// A new, zeroed value.
#[inline]
pub const fn new() -> Self {
Self(0)
}
/// The number of CPU cycles per timer tick.
#[inline]
pub const fn with_cpus_per_tick(self, cpus: CpusPerTick) -> Self {
Self(u8_with_region(0, 1, self.0, cpus as u8))
}
/// If the timer should *only* tick when the lower-number timer overflows.
///
/// * When set, this **overrides** the `cpus_per_tick` value and Timer N will
/// instead tick once per overflow of Timer (N-1).
/// * This has no effect for Timer 0, since it has no lower numbered timer.
#[inline]
pub const fn cascade_ticks(self, cascade: bool) -> Self {
Self(u8_with_bit(2, self.0, cascade))
}
/// If an overflow of this timer should send an interrupt.
#[inline]
pub const fn with_send_irq(self, irq: bool) -> Self {
Self(u8_with_bit(6, self.0, irq))
}
/// If this timer is enabled.
#[inline]
pub const fn with_enabled(self, enabled: bool) -> Self {
Self(u8_with_bit(7, self.0, enabled))
}
}

/// How many CPU cycles per timer tick.
#[repr(u8)]
#[allow(missing_docs)]
pub enum CpusPerTick {
_1 = 0,
_64 = 1,
_256 = 2,
_1024 = 3,
}

0 comments on commit e4024d6

Please sign in to comment.