[SC64][SW] Menu preparations

This commit is contained in:
Mateusz Faderewski 2023-02-02 19:03:01 +01:00
parent 285d5d6a6f
commit 4f7ee06e09
8 changed files with 103 additions and 91 deletions

View File

@ -37,7 +37,7 @@ static io32_t *boot_get_device_base (boot_info_t *info) {
return device_base_address; return device_base_address;
} }
bool boot_get_tv_type (boot_info_t *info) { static bool boot_get_tv_type (boot_info_t *info) {
io32_t *base = boot_get_device_base(info); io32_t *base = boot_get_device_base(info);
char region = ((pi_io_read(&base[15]) >> 8) & 0xFF); char region = ((pi_io_read(&base[15]) >> 8) & 0xFF);
@ -64,7 +64,7 @@ bool boot_get_tv_type (boot_info_t *info) {
return true; return true;
} }
bool boot_get_cic_seed_version (boot_info_t *info) { static bool boot_get_cic_seed_version (boot_info_t *info) {
io32_t *base = boot_get_device_base(info); io32_t *base = boot_get_device_base(info);
uint32_t ipl3[1008] __attribute__((aligned(8))); uint32_t ipl3[1008] __attribute__((aligned(8)));
@ -84,47 +84,56 @@ bool boot_get_cic_seed_version (boot_info_t *info) {
return false; return false;
} }
void boot (boot_info_t *info) { void boot (boot_info_t *info, bool detect_tv_type, bool detect_cic_seed_version) {
if (detect_tv_type && !boot_get_tv_type(info)) {
info->tv_type = OS_INFO->tv_type;
}
if (detect_cic_seed_version && !boot_get_cic_seed_version(info)) {
info->cic_seed = 0x3F;
info->version = 0;
}
OS_INFO->mem_size_6105 = OS_INFO->mem_size; OS_INFO->mem_size_6105 = OS_INFO->mem_size;
while (!(io_read(&SP->SR) & SP_SR_HALT)); while (!(cpu_io_read(&SP->SR) & SP_SR_HALT));
io_write(&SP->SR, SP_SR_CLR_INTR | SP_SR_SET_HALT); cpu_io_write(&SP->SR, SP_SR_CLR_INTR | SP_SR_SET_HALT);
while (io_read(&SP->DMA_BUSY)); while (cpu_io_read(&SP->DMA_BUSY));
io_write(&PI->SR, PI_SR_CLR_INTR | PI_SR_RESET); cpu_io_write(&PI->SR, PI_SR_CLR_INTR | PI_SR_RESET);
io_write(&VI->V_INTR, 0x3FF); cpu_io_write(&VI->V_INTR, 0x3FF);
io_write(&VI->H_LIMITS, 0); cpu_io_write(&VI->H_LIMITS, 0);
io_write(&VI->CURR_LINE, 0); cpu_io_write(&VI->CURR_LINE, 0);
io_write(&AI->MADDR, 0); cpu_io_write(&AI->MADDR, 0);
io_write(&AI->LEN, 0); cpu_io_write(&AI->LEN, 0);
io32_t *base = boot_get_device_base(info); io32_t *base = boot_get_device_base(info);
uint32_t pi_config = pi_io_read(base); uint32_t pi_config = pi_io_read(base);
io_write(&PI->DOM[0].LAT, pi_config & 0xFF); cpu_io_write(&PI->DOM[0].LAT, pi_config & 0xFF);
io_write(&PI->DOM[0].PWD, pi_config >> 8); cpu_io_write(&PI->DOM[0].PWD, pi_config >> 8);
io_write(&PI->DOM[0].PGS, pi_config >> 16); cpu_io_write(&PI->DOM[0].PGS, pi_config >> 16);
io_write(&PI->DOM[0].RLS, pi_config >> 20); cpu_io_write(&PI->DOM[0].RLS, pi_config >> 20);
if (io_read(&DPC->SR) & DPC_SR_XBUS_DMEM_DMA) { if (cpu_io_read(&DPC->SR) & DPC_SR_XBUS_DMEM_DMA) {
while (io_read(&DPC->SR) & DPC_SR_PIPE_BUSY); while (cpu_io_read(&DPC->SR) & DPC_SR_PIPE_BUSY);
} }
uint32_t *ipl2_src = &ipl2; uint32_t *ipl2_src = &ipl2;
io32_t *ipl2_dst = SP_MEM->IMEM; io32_t *ipl2_dst = SP_MEM->IMEM;
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
io_write(&ipl2_dst[i], ipl2_src[i]); cpu_io_write(&ipl2_dst[i], ipl2_src[i]);
} }
io32_t *ipl3_src = base; io32_t *ipl3_src = base;
io32_t *ipl3_dst = SP_MEM->DMEM; io32_t *ipl3_dst = SP_MEM->DMEM;
for (int i = 16; i < 1024; i++) { for (int i = 16; i < 1024; i++) {
io_write(&ipl3_dst[i], pi_io_read(&ipl3_src[i])); cpu_io_write(&ipl3_dst[i], pi_io_read(&ipl3_src[i]));
} }
register void (*entry_point)(void) asm ("t3"); register void (*entry_point)(void) asm ("t3");

View File

@ -32,9 +32,7 @@ typedef struct {
} boot_info_t; } boot_info_t;
bool boot_get_tv_type (boot_info_t *info); void boot (boot_info_t *info, bool detect_tv_type, bool detect_cic_seed_version);
bool boot_get_cic_seed_version (boot_info_t *info);
void boot (boot_info_t *info);
#endif #endif

View File

@ -75,7 +75,7 @@ static void display_decompress_background (uint32_t *background) {
(background_data[4]) (background_data[4])
); );
for (int i = 0; i < pixel_repeat; i++) { for (int i = 0; i < pixel_repeat; i++) {
io_write(framebuffer++, pixel_value); cpu_io_write(framebuffer++, pixel_value);
} }
pixels_painted += pixel_repeat; pixels_painted += pixel_repeat;
background_data += 5; background_data += 5;
@ -84,7 +84,7 @@ static void display_decompress_background (uint32_t *background) {
static void display_clear_background (void) { static void display_clear_background (void) {
for (int i = 0; i < (SCREEN_WIDTH * SCREEN_HEIGHT); i++) { for (int i = 0; i < (SCREEN_WIDTH * SCREEN_HEIGHT); i++) {
io_write(&display_framebuffer[i], BACKGROUND_COLOR); cpu_io_write(&display_framebuffer[i], BACKGROUND_COLOR);
} }
} }
@ -114,7 +114,7 @@ static void display_draw_character (char c) {
if (font_data[c - ' '][i / 8] & (1 << (i % 8))) { if (font_data[c - ' '][i / 8] & (1 << (i % 8))) {
int screen_offset = c_x + (c_y * SCREEN_WIDTH); int screen_offset = c_x + (c_y * SCREEN_WIDTH);
io_write(&display_framebuffer[screen_offset], TEXT_COLOR); cpu_io_write(&display_framebuffer[screen_offset], TEXT_COLOR);
} }
} }
@ -140,20 +140,20 @@ void display_init (uint32_t *background) {
display_clear_background(); display_clear_background();
} }
io_write(&VI->MADDR, (uint32_t) (display_framebuffer)); cpu_io_write(&VI->MADDR, (uint32_t) (display_framebuffer));
io_write(&VI->H_WIDTH, cfg->H_WIDTH); cpu_io_write(&VI->H_WIDTH, cfg->H_WIDTH);
io_write(&VI->V_INTR, cfg->V_INTR); cpu_io_write(&VI->V_INTR, cfg->V_INTR);
io_write(&VI->CURR_LINE, cfg->CURR_LINE); cpu_io_write(&VI->CURR_LINE, cfg->CURR_LINE);
io_write(&VI->TIMING, cfg->TIMING); cpu_io_write(&VI->TIMING, cfg->TIMING);
io_write(&VI->V_SYNC, cfg->V_SYNC); cpu_io_write(&VI->V_SYNC, cfg->V_SYNC);
io_write(&VI->H_SYNC, cfg->H_SYNC); cpu_io_write(&VI->H_SYNC, cfg->H_SYNC);
io_write(&VI->H_SYNC_LEAP, cfg->H_SYNC_LEAP); cpu_io_write(&VI->H_SYNC_LEAP, cfg->H_SYNC_LEAP);
io_write(&VI->H_LIMITS, cfg->H_LIMITS); cpu_io_write(&VI->H_LIMITS, cfg->H_LIMITS);
io_write(&VI->V_LIMITS, cfg->V_LIMITS); cpu_io_write(&VI->V_LIMITS, cfg->V_LIMITS);
io_write(&VI->COLOR_BURST, cfg->COLOR_BURST); cpu_io_write(&VI->COLOR_BURST, cfg->COLOR_BURST);
io_write(&VI->H_SCALE, cfg->H_SCALE); cpu_io_write(&VI->H_SCALE, cfg->H_SCALE);
io_write(&VI->V_SCALE, cfg->V_SCALE); cpu_io_write(&VI->V_SCALE, cfg->V_SCALE);
io_write(&VI->CR, cfg->CR); cpu_io_write(&VI->CR, cfg->CR);
} }
void display_vprintf (const char *fmt, va_list args) { void display_vprintf (const char *fmt, va_list args) {

View File

@ -26,55 +26,55 @@ void cache_inst_hit_invalidate (void *address, size_t length) {
cache_operation(HIT_INVALIDATE_I, CACHE_LINE_SIZE_I, address, length); cache_operation(HIT_INVALIDATE_I, CACHE_LINE_SIZE_I, address, length);
} }
uint32_t io_read (io32_t *address) { uint32_t cpu_io_read (io32_t *address) {
io32_t *uncached = UNCACHED(address); io32_t *uncached = UNCACHED(address);
uint32_t value = *uncached; uint32_t value = *uncached;
return value; return value;
} }
void io_write (io32_t *address, uint32_t value) { void cpu_io_write (io32_t *address, uint32_t value) {
io32_t *uncached = UNCACHED(address); io32_t *uncached = UNCACHED(address);
*uncached = value; *uncached = value;
} }
uint32_t pi_busy (void) { uint32_t pi_busy (void) {
return (io_read(&PI->SR) & (PI_SR_IO_BUSY | PI_SR_DMA_BUSY)); return (cpu_io_read(&PI->SR) & (PI_SR_IO_BUSY | PI_SR_DMA_BUSY));
} }
uint32_t pi_io_read (io32_t *address) { uint32_t pi_io_read (io32_t *address) {
return io_read(address); return cpu_io_read(address);
} }
void pi_io_write (io32_t *address, uint32_t value) { void pi_io_write (io32_t *address, uint32_t value) {
io_write(address, value); cpu_io_write(address, value);
while (pi_busy()); while (pi_busy());
} }
void pi_dma_read (io32_t *address, void *buffer, size_t length) { void pi_dma_read (io32_t *address, void *buffer, size_t length) {
cache_data_hit_writeback_invalidate(buffer, length); cache_data_hit_writeback_invalidate(buffer, length);
io_write(&PI->PADDR, (uint32_t) (PHYSICAL(address))); cpu_io_write(&PI->PADDR, (uint32_t) (PHYSICAL(address)));
io_write(&PI->MADDR, (uint32_t) (PHYSICAL(buffer))); cpu_io_write(&PI->MADDR, (uint32_t) (PHYSICAL(buffer)));
io_write(&PI->WDMA, length - 1); cpu_io_write(&PI->WDMA, length - 1);
while (pi_busy()); while (pi_busy());
} }
void pi_dma_write (io32_t *address, void *buffer, size_t length) { void pi_dma_write (io32_t *address, void *buffer, size_t length) {
cache_data_hit_writeback(buffer, length); cache_data_hit_writeback(buffer, length);
io_write(&PI->PADDR, (uint32_t) (PHYSICAL(address))); cpu_io_write(&PI->PADDR, (uint32_t) (PHYSICAL(address)));
io_write(&PI->MADDR, (uint32_t) (PHYSICAL(buffer))); cpu_io_write(&PI->MADDR, (uint32_t) (PHYSICAL(buffer)));
io_write(&PI->RDMA, length - 1); cpu_io_write(&PI->RDMA, length - 1);
while (pi_busy()); while (pi_busy());
} }
uint32_t si_busy (void) { uint32_t si_busy (void) {
return (io_read(&SI->SR) & (SI_SR_IO_BUSY | SI_SR_DMA_BUSY)); return (cpu_io_read(&SI->SR) & (SI_SR_IO_BUSY | SI_SR_DMA_BUSY));
} }
uint32_t si_io_read (io32_t *address) { uint32_t si_io_read (io32_t *address) {
return io_read(address); return cpu_io_read(address);
} }
void si_io_write (io32_t *address, uint32_t value) { void si_io_write (io32_t *address, uint32_t value) {
io_write(address, value); cpu_io_write(address, value);
while (si_busy()); while (si_busy());
} }

View File

@ -245,8 +245,8 @@ typedef struct {
#define OS_INFO ((os_info_t *) OS_INFO_BASE) #define OS_INFO ((os_info_t *) OS_INFO_BASE)
uint32_t io_read (io32_t *address); uint32_t cpu_io_read (io32_t *address);
void io_write (io32_t *address, uint32_t value); void cpu_io_write (io32_t *address, uint32_t value);
uint32_t pi_busy (void); uint32_t pi_busy (void);
uint32_t pi_io_read (io32_t *address); uint32_t pi_io_read (io32_t *address);
void pi_io_write (io32_t *address, uint32_t value); void pi_io_write (io32_t *address, uint32_t value);

View File

@ -30,27 +30,15 @@ void main (void) {
break; break;
} }
bool detect_tv_type = (sc64_boot_info.tv_type == TV_TYPE_UNKNOWN);
bool detect_cic_seed_version = (sc64_boot_info.cic_seed == CIC_SEED_UNKNOWN);
boot_info.reset_type = OS_INFO->reset_type; boot_info.reset_type = OS_INFO->reset_type;
if (sc64_boot_info.tv_type != TV_TYPE_UNKNOWN) {
boot_info.tv_type = sc64_boot_info.tv_type; boot_info.tv_type = sc64_boot_info.tv_type;
} else {
if (!boot_get_tv_type(&boot_info)) {
boot_info.tv_type = OS_INFO->tv_type;
}
}
if (sc64_boot_info.cic_seed != CIC_SEED_UNKNOWN) {
boot_info.cic_seed = sc64_boot_info.cic_seed & 0xFF; boot_info.cic_seed = sc64_boot_info.cic_seed & 0xFF;
boot_info.version = (sc64_boot_info.cic_seed >> 8) & 0x01; boot_info.version = (sc64_boot_info.cic_seed >> 8) & 0x01;
} else {
if (!boot_get_cic_seed_version(&boot_info)) {
boot_info.cic_seed = 0x3F;
boot_info.version = 0;
}
}
deinit(); deinit();
boot(&boot_info); boot(&boot_info, detect_tv_type, detect_cic_seed_version);
} }

View File

@ -52,50 +52,60 @@ typedef enum {
SD_CARD_OP_GET_INFO = 3, SD_CARD_OP_GET_INFO = 3,
} sd_card_op_t; } sd_card_op_t;
static sc64_pi_io_t pi_io = {
.read = pi_io_read,
.write = pi_io_write
};
static bool sc64_wait_cpu_busy (void) { static bool sc64_wait_cpu_busy (void) {
uint32_t sr; uint32_t sr;
do { do {
sr = pi_io_read(&SC64_REGS->SR_CMD); sr = pi_io.read(&SC64_REGS->SR_CMD);
} while (sr & SC64_SR_CPU_BUSY); } while (sr & SC64_SR_CPU_BUSY);
return (sr & SC64_SR_CMD_ERROR); return (sr & SC64_SR_CMD_ERROR);
} }
static bool sc64_execute_cmd (uint8_t cmd, uint32_t *args, uint32_t *result) { static bool sc64_execute_cmd (uint8_t cmd, uint32_t *args, uint32_t *result) {
if (args != NULL) { if (args != NULL) {
pi_io_write(&SC64_REGS->DATA[0], args[0]); pi_io.write(&SC64_REGS->DATA[0], args[0]);
pi_io_write(&SC64_REGS->DATA[1], args[1]); pi_io.write(&SC64_REGS->DATA[1], args[1]);
} }
pi_io_write(&SC64_REGS->SR_CMD, ((uint32_t) (cmd)) & 0xFF); pi_io.write(&SC64_REGS->SR_CMD, ((uint32_t) (cmd)) & 0xFF);
bool error = sc64_wait_cpu_busy(); bool error = sc64_wait_cpu_busy();
if (result != NULL) { if (result != NULL) {
result[0] = pi_io_read(&SC64_REGS->DATA[0]); result[0] = pi_io.read(&SC64_REGS->DATA[0]);
result[1] = pi_io_read(&SC64_REGS->DATA[1]); result[1] = pi_io.read(&SC64_REGS->DATA[1]);
} }
return error; return error;
} }
void sc64_set_pi_io_functions (sc64_pi_io_t functions) {
pi_io.read = functions.read;
pi_io.write = functions.write;
}
sc64_error_t sc64_get_error (void) { sc64_error_t sc64_get_error (void) {
if (pi_io_read(&SC64_REGS->SR_CMD) & SC64_SR_CMD_ERROR) { if (pi_io.read(&SC64_REGS->SR_CMD) & SC64_SR_CMD_ERROR) {
return (sc64_error_t) (pi_io_read(&SC64_REGS->DATA[0])); return (sc64_error_t) (pi_io.read(&SC64_REGS->DATA[0]));
} }
return SC64_OK; return SC64_OK;
} }
void sc64_unlock (void) { void sc64_unlock (void) {
pi_io_write(&SC64_REGS->KEY, SC64_KEY_RESET); pi_io.write(&SC64_REGS->KEY, SC64_KEY_RESET);
pi_io_write(&SC64_REGS->KEY, SC64_KEY_UNLOCK_1); pi_io.write(&SC64_REGS->KEY, SC64_KEY_UNLOCK_1);
pi_io_write(&SC64_REGS->KEY, SC64_KEY_UNLOCK_2); pi_io.write(&SC64_REGS->KEY, SC64_KEY_UNLOCK_2);
} }
void sc64_lock (void) { void sc64_lock (void) {
pi_io_write(&SC64_REGS->KEY, SC64_KEY_RESET); pi_io.write(&SC64_REGS->KEY, SC64_KEY_RESET);
pi_io_write(&SC64_REGS->KEY, SC64_KEY_LOCK); pi_io.write(&SC64_REGS->KEY, SC64_KEY_LOCK);
} }
bool sc64_check_presence (void) { bool sc64_check_presence (void) {
uint32_t version = pi_io_read(&SC64_REGS->VERSION); uint32_t version = pi_io.read(&SC64_REGS->VERSION);
if (version == SC64_VERSION_2) { if (version == SC64_VERSION_2) {
sc64_wait_cpu_busy(); sc64_wait_cpu_busy();
return true; return true;
@ -104,14 +114,14 @@ bool sc64_check_presence (void) {
} }
bool sc64_irq_pending (void) { bool sc64_irq_pending (void) {
if (pi_io_read(&SC64_REGS->SR_CMD) & SC64_SR_IRQ_PENDING) { if (pi_io.read(&SC64_REGS->SR_CMD) & SC64_SR_IRQ_PENDING) {
return true; return true;
} }
return false; return false;
} }
void sc64_irq_clear (void) { void sc64_irq_clear (void) {
pi_io_write(&SC64_REGS->VERSION, 0); pi_io.write(&SC64_REGS->VERSION, 0);
} }
uint32_t sc64_get_config (cfg_id_t id) { uint32_t sc64_get_config (cfg_id_t id) {

View File

@ -109,6 +109,13 @@ typedef struct {
#define SC64_BUFFERS_BASE (0x1FFE0000UL) #define SC64_BUFFERS_BASE (0x1FFE0000UL)
#define SC64_BUFFERS ((sc64_buffers_t *) SC64_BUFFERS_BASE) #define SC64_BUFFERS ((sc64_buffers_t *) SC64_BUFFERS_BASE)
typedef struct {
uint32_t (*read)(io32_t *address);
void (*write)(io32_t *address, uint32_t value);
} sc64_pi_io_t;
void sc64_set_pi_io_functions (sc64_pi_io_t functions);
sc64_error_t sc64_get_error (void); sc64_error_t sc64_get_error (void);