SummerCart64/sw/controller/src/cic.c
2023-12-14 19:26:54 +01:00

98 lines
2.2 KiB
C

#include "cic.h"
#include "fpga.h"
#include "hw.h"
#include "led.h"
#include "rtc.h"
typedef enum {
REGION_NTSC,
REGION_PAL,
__REGION_MAX
} cic_region_t;
static bool cic_initialized = false;
static void cic_irq_reset_falling (void) {
led_clear_error(LED_ERROR_CIC);
}
void cic_reset_parameters (void) {
cic_region_t region = rtc_get_region();
const uint8_t default_seed = 0x3F;
const uint64_t default_checksum = 0xA536C0F1D859ULL;
uint32_t cic_config_0 = (default_seed << CIC_SEED_BIT) | ((default_checksum >> 32) & 0xFFFF);
uint32_t cic_config_1 = (default_checksum & 0xFFFFFFFFUL);
if (region == REGION_PAL) {
cic_config_0 |= CIC_REGION;
}
fpga_reg_set(REG_CIC_0, cic_config_0);
fpga_reg_set(REG_CIC_1, cic_config_1);
}
void cic_set_parameters (uint32_t *args) {
uint32_t cic_config_0 = args[0] & (0x00FFFFFF);
uint32_t cic_config_1 = args[1];
cic_config_0 |= fpga_reg_get(REG_CIC_0) & (CIC_64DD_MODE | CIC_REGION);
if (args[0] & (1 << 24)) {
cic_config_0 |= CIC_DISABLED;
}
fpga_reg_set(REG_CIC_0, cic_config_0);
fpga_reg_set(REG_CIC_1, cic_config_1);
}
void cic_set_dd_mode (bool enabled) {
uint32_t cic_config_0 = fpga_reg_get(REG_CIC_0);
if (enabled) {
cic_config_0 |= CIC_64DD_MODE;
} else {
cic_config_0 &= ~(CIC_64DD_MODE);
}
fpga_reg_set(REG_CIC_0, cic_config_0);
}
void cic_init (void) {
hw_gpio_irq_setup(GPIO_ID_N64_RESET, GPIO_IRQ_FALLING, cic_irq_reset_falling);
}
void cic_process (void) {
if (!cic_initialized) {
if (rtc_is_initialized()) {
cic_reset_parameters();
cic_initialized = true;
} else {
return;
}
}
uint32_t cic_config_0 = fpga_reg_get(REG_CIC_0);
if (cic_config_0 & CIC_INVALID_REGION_DETECTED) {
cic_config_0 ^= CIC_REGION;
cic_config_0 |= CIC_INVALID_REGION_RESET;
fpga_reg_set(REG_CIC_0, cic_config_0);
if (cic_config_0 & CIC_REGION) {
rtc_set_region(REGION_PAL);
} else {
rtc_set_region(REGION_NTSC);
}
led_blink_error(LED_ERROR_CIC);
}
}