mirror of
https://gitee.com/anod/open_agb_firm.git
synced 2025-05-09 15:24:09 +08:00
135 lines
5.2 KiB
C
135 lines
5.2 KiB
C
#pragma once
|
|
|
|
/*
|
|
* This file is part of libn3ds
|
|
* Copyright (C) 2024 profi200
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "types.h"
|
|
#include "mem_map.h"
|
|
|
|
|
|
#ifdef __cplusplus
|
|
extern "C"
|
|
{
|
|
#endif
|
|
|
|
#define LGY9_ARM7_STUB_LOC (0x3007E00u)
|
|
#define LGY9_ARM7_STUB_LOC9 (AHB_RAM_BASE + 0xBFE00u)
|
|
#define LGY9_SAVE_LOC (AHB_RAM_BASE + 0x80000u)
|
|
|
|
|
|
#define LGY9_REGS_BASE (IO_AHB_BASE + 0x18000)
|
|
|
|
typedef struct
|
|
{
|
|
vu16 mode;
|
|
u8 _0x2[0x7e];
|
|
vu32 a7_vector[8]; // ARM7 vector override 32 bytes. Writable at runtime.
|
|
u8 _0xa0[0x60];
|
|
vu16 gba_save_type;
|
|
u8 _0x102[2];
|
|
vu8 gba_save_map; // Remaps the GBA save to ARM9 if set to 1.
|
|
u8 _0x105[3];
|
|
vu16 gba_rtc_cnt;
|
|
u8 _0x10a[6];
|
|
vu32 gba_rtc_bcd_date;
|
|
vu32 gba_rtc_bcd_time;
|
|
vu32 gba_rtc_toffset; // Writing bit 7 completely hangs all(?) GBA hardware.
|
|
vu32 gba_rtc_doffset;
|
|
vu32 gba_save_timing[4];
|
|
} Lgy9;
|
|
static_assert(offsetof(Lgy9, gba_save_timing) == 0x120, "Error: Member gba_save_timing of Lgy9 is not at offset 0x120!");
|
|
|
|
ALWAYS_INLINE Lgy9* getLgy9Regs(void)
|
|
{
|
|
return (Lgy9*)LGY9_REGS_BASE;
|
|
}
|
|
|
|
|
|
// REG_LGY9_MODE
|
|
// See lgy_common.h LGY_MODE_...
|
|
|
|
// REG_LGY9_GBA_SAVE_TYPE
|
|
// See lgy_common.h SAVE_TYPE_...
|
|
|
|
// REG_LGY9_GBA_SAVE_MAP
|
|
#define LGY9_SAVE_MAP_7 (0u)
|
|
#define LGY9_SAVE_MAP_9 BIT(0)
|
|
|
|
// REG_LGY9_GBA_RTC_CNT
|
|
#define LGY9_RTC_CNT_WR BIT(0) // Write date and time.
|
|
#define LGY9_RTC_CNT_RD BIT(1) // Read date and time.
|
|
#define LGY9_RTC_CNT_WR_ERR BIT(14) // Write error (wrong date/time).
|
|
#define LGY9_RTC_CNT_BUSY BIT(15)
|
|
|
|
// REG_LGY9_GBA_RTC_BCD_DATE
|
|
// Shifts
|
|
#define LGY9_RTC_BCD_Y_SHIFT (0u)
|
|
#define LGY9_RTC_BCD_MON_SHIFT (8u)
|
|
#define LGY9_RTC_BCD_D_SHIFT (16u)
|
|
#define LGY9_RTC_BCD_W_SHIFT (24u)
|
|
// Masks
|
|
#define LGY9_RTC_BCD_Y_MASK (0xFFu<<LGY_RTC_BCD_Y_SHIFT)
|
|
#define LGY9_RTC_BCD_MON_MASK (0x1Fu<<LGY_RTC_BCD_M_SHIFT)
|
|
#define LGY9_RTC_BCD_D_MASK (0x3Fu<<LGY_RTC_BCD_D_SHIFT)
|
|
#define LGY9_RTC_BCD_W_MASK (0x07u<<LGY_RTC_BCD_W_SHIFT)
|
|
|
|
// REG_LGY9_GBA_RTC_BCD_TIME
|
|
// Shifts
|
|
#define LGY9_RTC_BCD_H_SHIFT (0u)
|
|
#define LGY9_RTC_BCD_MIN_SHIFT (8u)
|
|
#define LGY9_RTC_BCD_S_SHIFT (16u)
|
|
// Masks
|
|
#define LGY9_RTC_BCD_H_MASK (0x3Fu<<LGY_RTC_BCD_H_SHIFT)
|
|
#define LGY9_RTC_BCD_MIN_MASK (0x7Fu<<LGY_RTC_BCD_MIN_SHIFT)
|
|
#define LGY9_RTC_BCD_S_MASK (0x7Fu<<LGY_RTC_BCD_S_SHIFT)
|
|
|
|
// REG_LGY9_GBA_RTC_TOFFSET
|
|
// Useful reference: Seiko S-3511A Real-Time Clock. The bit order is different and it has time data mixed in.
|
|
// Shifts
|
|
#define LGY9_RTC_TOFFS_S_SHIFT (0u)
|
|
#define LGY9_RTC_TOFFS_POWER_SHIFT (7u)
|
|
#define LGY9_RTC_TOFFS_MIN_SHIFT (8u)
|
|
#define LGY9_RTC_TOFFS_12H24H_SHIFT (15u)
|
|
#define LGY9_RTC_TOFFS_H_SHIFT (16u)
|
|
#define LGY9_RTC_TOFFS_DOW_SHIFT (24u)
|
|
#define LGY9_RTC_TOFFS_INTFE_SHIFT (28u)
|
|
#define LGY9_RTC_TOFFS_INTME_SHIFT (29u)
|
|
#define LGY9_RTC_TOFFS_INTAE_SHIFT (30u)
|
|
#define LGY9_RTC_TOFFS_UNK31_SHIFT (31u)
|
|
// Bits
|
|
#define LGY9_RTC_TOFFS_POWER_LOST BIT(LGY9_RTC_TOFFS_POWER_SHIFT) // RTC power lost flag (Seiko/GBA RO, 3DS RW/set once). The RTC will generate IRQs when this is set which can trigger cart removal detection in some games.
|
|
#define LGY9_RTC_TOFFS_12H (0u) // Format 12h fomrat.
|
|
#define LGY9_RTC_TOFFS_24H BIT(LGY9_RTC_TOFFS_12H24H_SHIFT) // Format 24h fomrat.
|
|
#define LGY9_RTC_TOFFS_INTFE_1 BIT(LGY9_RTC_TOFFS_INTFE_SHIFT) // 0 = alarm/per-minute edge IRQ, 1 = 50% duty cycle (minute) or frequency (if INTME/INTAE = 0) IRQ.
|
|
#define LGY9_RTC_TOFFS_INTME_1 BIT(LGY9_RTC_TOFFS_INTME_SHIFT) // 0 = other modes, 1 = per-minute IRQ.
|
|
#define LGY9_RTC_TOFFS_INTAE_1 BIT(LGY9_RTC_TOFFS_INTAE_SHIFT) // 0 = alarm IRQ disabled, 1 = alarm IRQ enabled (if INTME/INTFE = 0).
|
|
#define LGY9_RTC_TOFFS_UNK31 BIT(LGY9_RTC_TOFFS_UNK31_SHIFT) // Unknown. Maybe time/date offset format (decimal or BCD)?
|
|
// Masks
|
|
#define LGY9_RTC_TOFFS_S_MASK (0x7F<<LGY9_RTC_TOFFS_S_SHIFT) // Seconds offset mask. Not on Seiko chip.
|
|
#define LGY9_RTC_TOFFS_MIN_MASK (0x7F<<LGY9_RTC_TOFFS_MIN_SHIFT) // Minutes offset mask. Not on Seiko chip.
|
|
#define LGY9_RTC_TOFFS_H_MASK (0x3F<<LGY9_RTC_TOFFS_H_SHIFT) // Hours offset mask. Not on Seiko chip.
|
|
#define LGY9_RTC_TOFFS_DOW_MASK (0xF<<LGY9_RTC_TOFFS_DOW_SHIFT) // Day of week offset mask. Not on Seiko chip.
|
|
|
|
// REG_LGY9_GBA_RTC_DOFFSET
|
|
#define LGY9_RTC_DOFFS_D_MASK (0xFFFFu) // Day offset mask. Allowed range: 0-0x8EAC. 100 years.
|
|
|
|
// REGs_LGY9_GBA_SAVE_TIMING
|
|
|
|
#ifdef __cplusplus
|
|
} // extern "C"
|
|
#endif |