275 lines
6.2 KiB
C
275 lines
6.2 KiB
C
#include <gint/display.h>
|
|
#include <gint/keyboard.h>
|
|
#include <gint/mpu/spu.h>
|
|
|
|
#include <gintctl/gint.h>
|
|
#include <gintctl/util.h>
|
|
|
|
#define SPU SH7305_SPU
|
|
|
|
//---
|
|
// Logic and save/restore RAM data
|
|
//---
|
|
|
|
static int bank_number(volatile uint32_t *area)
|
|
{
|
|
/* Check that the address is writable */
|
|
uint32_t save = *area;
|
|
*area = save ^ 0xffffff00;
|
|
uint32_t read = *area;
|
|
*area = save;
|
|
|
|
if(read != (save ^ 0xffffff00)) return -1;
|
|
return save >> 24;
|
|
}
|
|
|
|
static void save_and_setup(volatile uint32_t *area, uint32_t *save, int pages)
|
|
{
|
|
for(int i = 0; i < pages; i++)
|
|
{
|
|
save[i] = area[i * 0x2000];
|
|
area[i * 0x2000] = (i << 24);
|
|
}
|
|
}
|
|
|
|
static void restore(volatile uint32_t *area, uint32_t *save, int pages)
|
|
{
|
|
for(int i = 0; i < pages; i++)
|
|
{
|
|
area[i * 0x2000] = save[i];
|
|
}
|
|
}
|
|
|
|
#ifdef FX9860G
|
|
static void render_header(int y, GUNUSED int bank_count)
|
|
{
|
|
y = 9 + 6*y;
|
|
dtext( 1, 9, C_BLACK, "Area");
|
|
dtext(24, 9, C_BLACK, "Address");
|
|
dtext(60, 9, C_BLACK, "Visible pages");
|
|
}
|
|
|
|
static void render_area(int y, char const *name, uint32_t *area)
|
|
{
|
|
y = 9 + 6*y;
|
|
dprint( 1, y, C_BLACK, "%s", name);
|
|
dprint(24, y, C_BLACK, "%08X", (uint32_t)area);
|
|
|
|
int b = 0, bank = 0;
|
|
while(1)
|
|
{
|
|
bank = bank_number(area);
|
|
if(b == 7) break;
|
|
|
|
dprint(60+8*b, y, C_BLACK, bank >= 0 ? "%d" : "-", bank);
|
|
area += 0x2000;
|
|
b++;
|
|
}
|
|
}
|
|
|
|
static void render_bank(int y, char const *name, volatile uint32_t *bank,
|
|
int banks, int dsp, int focus)
|
|
{
|
|
y = 9 + 6*y;
|
|
dprint( 1, y, C_BLACK, "%s", name);
|
|
dprint(29, y, C_BLACK, "=%02X", *bank);
|
|
|
|
for(int b = 0; b < banks; b++)
|
|
{
|
|
int active = *bank & (1 << b);
|
|
|
|
int x = 50 + 8*b - 1;
|
|
int ry = y + (dsp==0) - 1;
|
|
|
|
int fill = active ? C_BLACK : C_WHITE;
|
|
int border = (focus == b) ? C_BLACK : C_WHITE;
|
|
drect_border(x, ry, x+7, ry+5, fill, 1, border);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#ifdef FXCG50
|
|
static void render_header(int y, int bank_count)
|
|
{
|
|
dtext(row_x(2), row_y(y), C_BLACK, "Area:");
|
|
dtext(row_x(9), row_y(y), C_BLACK, "Address:");
|
|
|
|
for(int b = 0; b < bank_count; b++)
|
|
{
|
|
row_print(y, 20+4*b, "%d:", b*32);
|
|
}
|
|
}
|
|
|
|
static void render_area(int y, char const *name, uint32_t *area)
|
|
{
|
|
row_print(y, 2, "%s", name);
|
|
row_print(y, 9, "%08X", (uint32_t)area);
|
|
|
|
int b = 0, bank = 0;
|
|
while(1)
|
|
{
|
|
bank = bank_number(area);
|
|
if(bank == -1) break;
|
|
|
|
row_print(y, 20+4*b, "%d", bank);
|
|
area += 0x2000;
|
|
b++;
|
|
}
|
|
}
|
|
|
|
static void render_bank(int y, char const *name, volatile uint32_t *bank,
|
|
int banks, int dsp, int focus)
|
|
{
|
|
row_print(y, 2, "%s", name);
|
|
row_print(y, 10, "= %02X", *bank);
|
|
|
|
for(int b = 0; b < banks; b++)
|
|
{
|
|
int active = *bank & (1 << b);
|
|
|
|
int w = row_x(3) - row_x(0);
|
|
int x = row_x(20 + 4*b) - 2;
|
|
int h = row_y(1) - row_y(0) - 2;
|
|
int ry = row_y(y) + 2*(dsp==0) - 4;
|
|
|
|
int fill = C_RGB(24,24,24);
|
|
if(active) fill = dsp ? C_RGB(31,24,0) : C_GREEN;
|
|
int border = (focus == b) ? C_BLACK : C_RGB(16,16,16);
|
|
drect_border(x, ry, x+w, ry+h, fill, 1, border);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/* gintctl_gint_spuram(): SPU memory access, banking, and DMA */
|
|
void gintctl_gint_spuram(void)
|
|
{
|
|
extern int spu_zero(void);
|
|
spu_zero();
|
|
int key = 0;
|
|
|
|
uint32_t *PRAM0 = (void *)0xfe200000;
|
|
uint32_t *XRAM0 = (void *)0xfe240000;
|
|
uint32_t *YRAM0 = (void *)0xfe280000;
|
|
uint32_t *PRAM1 = (void *)0xfe300000;
|
|
uint32_t *XRAM1 = (void *)0xfe340000;
|
|
uint32_t *YRAM1 = (void *)0xfe380000;
|
|
|
|
/* Save values for all banks for all areas */
|
|
uint32_t saves[6][8];
|
|
save_and_setup(PRAM0, saves[0], 5);
|
|
save_and_setup(XRAM0, saves[1], 7);
|
|
save_and_setup(YRAM0, saves[2], 4);
|
|
save_and_setup(PRAM1, saves[3], 5);
|
|
save_and_setup(XRAM1, saves[4], 7);
|
|
save_and_setup(YRAM1, saves[5], 4);
|
|
|
|
int cur_bank = 0;
|
|
int cur_page = 0;
|
|
|
|
int switch_key = _(KEY_F6, KEY_F1);
|
|
|
|
#ifdef FX9860G
|
|
int tab = 0;
|
|
#endif
|
|
|
|
while(key != KEY_EXIT)
|
|
{
|
|
dclear(C_WHITE);
|
|
|
|
#ifdef FX9860G
|
|
row_title("SPU memory banking");
|
|
|
|
extern font_t font_hexa;
|
|
font_t const *old_font = dfont(&font_hexa);
|
|
|
|
if(tab == 0)
|
|
{
|
|
render_header(0, 7);
|
|
render_area(1, "PRAM0", PRAM0);
|
|
render_area(2, "XRAM0", XRAM0);
|
|
render_area(3, "YRAM0", YRAM0);
|
|
render_area(4, "PRAM1", PRAM1);
|
|
render_area(5, "XRAM1", XRAM1);
|
|
render_area(6, "YRAM1", YRAM1);
|
|
}
|
|
else if(tab == 1)
|
|
{
|
|
render_bank(1, "PBANKC0", &SPU.PBANKC0, 5, 0,
|
|
(cur_bank == 0) ? cur_page : -1);
|
|
render_bank(2, "PBANKC1", &SPU.PBANKC1, 5, 1,
|
|
(cur_bank == 0) ? cur_page : -1);
|
|
render_bank(4, "XBANKC0", &SPU.XBANKC0, 7, 0,
|
|
(cur_bank == 1) ? cur_page : -1);
|
|
render_bank(5, "XBANKC1", &SPU.XBANKC1, 7, 1,
|
|
(cur_bank == 1) ? cur_page : -1);
|
|
}
|
|
|
|
dfont(old_font);
|
|
extern bopti_image_t img_opt_gint_spuram;
|
|
dsubimage(0, 56, &img_opt_gint_spuram, 0, 0,
|
|
(tab == 1 ? 128 : 107), 8, DIMAGE_NONE);
|
|
#endif
|
|
|
|
#ifdef FXCG50
|
|
row_title("SPU memory: PRAM0, XRAM0, YRAM0, YRAM");
|
|
row_print(1, 1, "Pages layout in memory (offsets in kiB):");
|
|
|
|
render_header(2, 7);
|
|
render_area(3, "PRAM0", PRAM0);
|
|
render_area(4, "XRAM0", XRAM0);
|
|
render_area(5, "YRAM0", YRAM0);
|
|
render_area(6, "PRAM1", PRAM1);
|
|
render_area(7, "XRAM1", XRAM1);
|
|
render_area(8, "YRAM1", YRAM1);
|
|
|
|
row_print(9, 1, "Bank settings for DSP0 and DSP1:");
|
|
render_bank(10, "PBANKC0", &SPU.PBANKC0, 5, 0,
|
|
(cur_bank == 0) ? cur_page : -1);
|
|
render_bank(11, "PBANKC1", &SPU.PBANKC1, 5, 1,
|
|
(cur_bank == 0) ? cur_page : -1);
|
|
render_bank(12, "XBANKC0", &SPU.XBANKC0, 7, 0,
|
|
(cur_bank == 1) ? cur_page : -1);
|
|
render_bank(13, "XBANKC1", &SPU.XBANKC1, 7, 1,
|
|
(cur_bank == 1) ? cur_page : -1);
|
|
|
|
fkey_button(1, "SWITCH");
|
|
#endif
|
|
|
|
dupdate();
|
|
key = getkey().key;
|
|
|
|
if(key == KEY_LEFT && cur_page > 0)
|
|
cur_page--;
|
|
if(key == KEY_RIGHT && cur_page < (cur_bank ? 7 : 5) - 1)
|
|
cur_page++;
|
|
if(key == KEY_UP && cur_bank == 1 && cur_page < 5)
|
|
cur_bank--;
|
|
if(key == KEY_DOWN && cur_bank == 0)
|
|
cur_bank++;
|
|
|
|
if(key == switch_key && cur_bank == 0 && _(tab == 1, 1))
|
|
{
|
|
SPU.PBANKC0 ^= (1 << cur_page);
|
|
SPU.PBANKC1 ^= (1 << cur_page);
|
|
}
|
|
if(key == switch_key && cur_bank == 1 && _(tab == 1, 1))
|
|
{
|
|
SPU.XBANKC0 ^= (1 << cur_page);
|
|
SPU.XBANKC1 ^= (1 << cur_page);
|
|
}
|
|
|
|
#ifdef FX9860G
|
|
if(key == KEY_F1) tab = 0;
|
|
if(key == KEY_F2) tab = 1;
|
|
#endif
|
|
}
|
|
|
|
/* Restore the values we saved before altering page data */
|
|
restore(PRAM0, saves[0], 5);
|
|
restore(XRAM0, saves[1], 7);
|
|
restore(YRAM0, saves[2], 4);
|
|
restore(PRAM1, saves[3], 5);
|
|
restore(XRAM1, saves[4], 7);
|
|
restore(YRAM1, saves[5], 4);
|
|
}
|