Support higher resolutions
This works in cursory testing in the finder at e.g. 1280x720 (115200 bytes of screen RAM) Widths 1024 pixels and above need extra patching because of sites where the row width in bytes is loaded with signed 8-bit moveq. The existing simpler patches are preserved when this is not needed, especially as hidecursor now does a fair amount of extra work re-loading d0 in every iteration of the hide loop, which simplified the patch.
This commit is contained in:
parent
bb9f2470a6
commit
6cba995c88
2 changed files with 68 additions and 15 deletions
81
src/rom.c
81
src/rom.c
|
|
@ -55,6 +55,18 @@ static const uint8_t sony_driver[] = {
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
static int rom_patch1(uint8_t *rom_base, int disp_width, int disp_height, int mem_size);
|
||||
#if !defined(UMAC_STANDALONE_PATCHER)
|
||||
int rom_patch(uint8_t *rom_base) {
|
||||
return rom_patch1(rom_base, DISP_WIDTH, DISP_HEIGHT, UMAC_MEMSIZE * 1024);
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef DISP_WIDTH
|
||||
#undef DISP_HEIGHT
|
||||
#undef UMAC_MEMSIZE
|
||||
|
||||
static uint32_t rom_get_version(uint8_t *rom_base)
|
||||
{
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
|
|
@ -124,12 +136,8 @@ static int rom_patch_plusv3(uint8_t *rom_base, int disp_width, int disp_heig
|
|||
if(disp_width != 512 || disp_height != 342) {
|
||||
int screen_size = (disp_width*disp_height/8);
|
||||
int screen_distance_from_top = screen_size + 0x380;
|
||||
if (screen_distance_from_top >= 65536) {
|
||||
RERR("rom.c: screen res patching maths won't work for a screen this large");
|
||||
return -1;
|
||||
}
|
||||
int screen_base = 0x400000-screen_distance_from_top;
|
||||
int screen_base_l16 = screen_base & 0xffff;
|
||||
printf("screen size=%d screen_base=%x\n", screen_size, screen_base);
|
||||
#define SBCOORD(x, y) (screen_base + ((disp_width/8)*(y)) + ((x)/8))
|
||||
|
||||
/* Changing video res:
|
||||
|
|
@ -152,11 +160,44 @@ static int rom_patch_plusv3(uint8_t *rom_base, int disp_width, int disp_heig
|
|||
/* Now 0x46-0x57 can be used */
|
||||
unsigned int patch_0 = 0x46;
|
||||
ROM_WR16(patch_0 + 0, 0x9bfc); /* suba.l #imm32, A5 */
|
||||
ROM_WR16(patch_0 + 2, 0); /* (Could add more here) */
|
||||
ROM_WR16(patch_0 + 4, screen_distance_from_top);
|
||||
ROM_WR32(patch_0 + 2, screen_distance_from_top);
|
||||
ROM_WR16(patch_0 + 6, 0x6000); /* bra */
|
||||
ROM_WR16(patch_0 + 8, 0x3a4 - (patch_0 + 8)); /* Return to 3a4 */
|
||||
|
||||
// Additional patches needed if DISP_WIDTH is 1024 or above
|
||||
|
||||
unsigned int patch_2 = 0x32;
|
||||
unsigned int patch_1 = patch_0 + 10;
|
||||
if ((disp_width / 8) >= 128) {
|
||||
ROM_WR16(patch_1 + 0, 0x3a3c); /* move.l ..., D5 */
|
||||
ROM_WR16(patch_1 + 2, disp_width / 8); /* ^^^ */
|
||||
ROM_WR16(patch_1 + 4, 0xc2c5); /* mulu D5, D1 */
|
||||
ROM_WR16(patch_1 + 6, 0x4e75); /* rts */
|
||||
if (patch_1 + 8 > 0x57) {
|
||||
RERR("patch_1 extends too far (0x%x > 0x57)\n", patch_1 + 8);
|
||||
RERR("but yolo\n");
|
||||
// return -1;
|
||||
}
|
||||
|
||||
// is this the illegal instruction handler entry? if it is, it
|
||||
// eventually falls through to 'check if test software exists',
|
||||
// below.... @sc's annotated disassembly suggests "never called by the mac plus"
|
||||
// but it looks to me like 0x2e is in the vector table at 0x16...
|
||||
// patch it to jump down to after the test software check too.
|
||||
ROM_WR16(0x2e, 0x6000); /* bra */
|
||||
ROM_WR16(0x30, 0x62-0x30); /* offset */
|
||||
|
||||
ROM_WR16(patch_2 + 0, 0x303c); /* move.l ..., D0 */
|
||||
ROM_WR16(patch_2 + 2, disp_width / 8); /* ^^^ */
|
||||
ROM_WR16(patch_2 + 4, 0x2298); /* Move.l (A0+), (A1) */
|
||||
ROM_WR16(patch_2 + 6, 0x6000); /* bra */
|
||||
ROM_WR16(patch_2 + 8, 0x1cd4 - (patch_2 + 8)); /* Return to 1cd4 */
|
||||
if (patch_2 + 8 > 0x41) {
|
||||
RERR("patch_2 extends too far (0x%x > 0x41)\n", patch_2);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Magic screen-related locations in Mac Plus ROM 4d1f8172:
|
||||
*
|
||||
* 8c : screen base addr (usually 3fa700, now 3f6680)
|
||||
|
|
@ -189,8 +230,8 @@ static int rom_patch_plusv3(uint8_t *rom_base, int disp_width, int disp_heig
|
|||
* 1e6e : x
|
||||
* 1e82 : y
|
||||
*/
|
||||
ROM_WR16(0x8c, screen_base_l16);
|
||||
ROM_WR16(0x148, screen_base_l16);
|
||||
ROM_WR32(0x8a, screen_base);
|
||||
ROM_WR32(0x146, screen_base);
|
||||
ROM_WR32(0x164, SBCOORD(disp_width/2 - (48/2), disp_height/2 + 8));
|
||||
ROM_WR16(0x188, disp_width/8);
|
||||
ROM_WR16(0x194, disp_width/8);
|
||||
|
|
@ -221,13 +262,29 @@ static int rom_patch_plusv3(uint8_t *rom_base, int disp_width, int disp_heig
|
|||
ROM_WR16(0xee2, (disp_width/8)-4); /* tPutIcon bytes per row, minus 4 */
|
||||
ROM_WR16(0xef2, disp_width/8); /* tPutIcon bytes per row */
|
||||
ROM_WR16(0xf36, (disp_width/8)-2); /* tPutIcon bytes per row, minus 2 */
|
||||
ROM_WR8(0x1cd1, disp_width/8); /* hidecursor */
|
||||
|
||||
// getting the stride of the framebuffer for hidecursor
|
||||
if ((disp_width / 8) >= 128) {
|
||||
ROM_WR16(0x1cd0, 0x6000); /* (hidecursor) bra */
|
||||
ROM_WR16(0x1cd2, patch_2 - 0x1cd2); /* .. to patch1, returns at 1cd4 */
|
||||
ROM_WR16(0x1cd8, 0x6ef6); /* loop back a bit further, argh */
|
||||
} else {
|
||||
ROM_WR8(0x1cd1, disp_width/8); /* hidecursor */
|
||||
}
|
||||
|
||||
ROM_WR16(0x1d48, disp_width-32); /* 1d46+2 was originally 512-32 rite? */
|
||||
ROM_WR16(0x1d4e, disp_width-32); /* 1d4c+2 is 480, same */
|
||||
ROM_WR16(0x1d6e, disp_height-16); /* showcursor (YESS fixed Y crash bug!) */
|
||||
ROM_WR16(0x1d74, disp_height); /* showcursor */
|
||||
ROM_WR8(0x1d93, disp_width/8); /* showcursor */
|
||||
ROM_WR16(0x1e68, disp_height); /* mScrnSize */
|
||||
// getting the stride of the framebuffer for showcursor
|
||||
if ((disp_width / 8) >= 128) {
|
||||
ROM_WR16(0x1d92, 0x4eba); /* jsr */
|
||||
ROM_WR16(0x1d94, patch_1 - 0x1d94); /* .. to patch1, returns at 1d96 */
|
||||
} else {
|
||||
ROM_WR8(0x1d93, disp_width/8); /* showcursor */
|
||||
}
|
||||
ROM_WR16(0x1e6e, disp_width); /* mScrnSize */
|
||||
ROM_WR16(0x1e82, disp_height); /* tScrnBitMap */
|
||||
}
|
||||
|
|
@ -349,8 +406,4 @@ int main(int argc, char **argv) {
|
|||
fclose(ofd);
|
||||
}
|
||||
}
|
||||
#else
|
||||
int rom_patch(uint8_t *rom_base) {
|
||||
return rom_patch1(rom_base, DISP_WIDTH, DISP_HEIGHT, UMAC_MEMSIZE * 1024);
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ static void print_help(char *n)
|
|||
"\t-i\t\t\tDisassembled instruction trace\n", n);
|
||||
}
|
||||
|
||||
#define DISP_SCALE 2
|
||||
#define DISP_SCALE (DISP_WIDTH < 800 && DISP_HEIGHT < 600 ? 2 : 1)
|
||||
|
||||
static uint32_t framebuffer[DISP_WIDTH*DISP_HEIGHT];
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue