Skip to content

Commit

Permalink
Added support for BG affine transforms, fixed a issue on Objects with…
Browse files Browse the repository at this point in the history
… unaligned tile addresses in 256 colors mode
  • Loading branch information
gdkchan committed Jan 9, 2017
1 parent 73baec7 commit 42373de
Show file tree
Hide file tree
Showing 7 changed files with 234 additions and 127 deletions.
14 changes: 8 additions & 6 deletions arm.c
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ static bool arm_in_thumb() {

static uint16_t arm_fetchh(access_type_e at) {
switch (arm_r.r[15] >> 24) {
case 0x0: arm_cycles += 1; return (bios_op = *(uint16_t *)(bios + (arm_r.r[15] & 0x3fff)));
case 0x2: arm_cycles += 3; return *(uint16_t *)(wram + (arm_r.r[15] & 0x3ffff));
case 0x3: arm_cycles += 1; return *(uint16_t *)(iwram + (arm_r.r[15] & 0x7fff));
case 0x5: arm_cycles += 1; return *(uint16_t *)(pram + (arm_r.r[15] & 0x3ff));
Expand Down Expand Up @@ -297,6 +298,7 @@ static uint16_t arm_fetchh(access_type_e at) {

static uint32_t arm_fetch(access_type_e at) {
switch (arm_r.r[15] >> 24) {
case 0x0: arm_cycles += 1; return (bios_op = *(uint32_t *)(bios + (arm_r.r[15] & 0x3fff)));
case 0x2: arm_cycles += 6; return *(uint32_t *)(wram + (arm_r.r[15] & 0x3ffff));
case 0x3: arm_cycles += 1; return *(uint32_t *)(iwram + (arm_r.r[15] & 0x7fff));
case 0x5: arm_cycles += 1; return *(uint32_t *)(pram + (arm_r.r[15] & 0x3ff));
Expand Down Expand Up @@ -2217,7 +2219,7 @@ static void arm_ldr_reg() {
}

static void t16_ldr_imm5() {
arm_memio_ldr(t16_memio_imm5_op(4));
arm_memio_ldr(t16_memio_imm5_op(ARM_WORD_SZ));
}

static void t16_ldr_sp8() {
Expand All @@ -2242,7 +2244,7 @@ static void arm_ldrb_reg() {
}

static void t16_ldrb_imm5() {
arm_memio_ldrb(t16_memio_imm5_op(1));
arm_memio_ldrb(t16_memio_imm5_op(ARM_BYTE_SZ));
}

static void t16_ldrb_reg() {
Expand Down Expand Up @@ -2277,7 +2279,7 @@ static void arm_ldrh_reg() {
}

static void t16_ldrh_imm5() {
arm_memio_ldrh(t16_memio_imm5_op(2));
arm_memio_ldrh(t16_memio_imm5_op(ARM_HWORD_SZ));
}

static void t16_ldrh_reg() {
Expand Down Expand Up @@ -2681,7 +2683,7 @@ static void arm_str_reg() {
}

static void t16_str_imm5() {
arm_memio_str(t16_memio_imm5_op(4));
arm_memio_str(t16_memio_imm5_op(ARM_WORD_SZ));
}

static void t16_str_sp8() {
Expand All @@ -2702,7 +2704,7 @@ static void arm_strb_reg() {
}

static void t16_strb_imm5() {
arm_memio_strb(t16_memio_imm5_op(1));
arm_memio_strb(t16_memio_imm5_op(ARM_BYTE_SZ));
}

static void t16_strb_reg() {
Expand Down Expand Up @@ -2737,7 +2739,7 @@ static void arm_strh_reg() {
}

static void t16_strh_imm5() {
arm_memio_strh(t16_memio_imm5_op(2));
arm_memio_strh(t16_memio_imm5_op(ARM_HWORD_SZ));
}

static void t16_strh_reg() {
Expand Down
67 changes: 31 additions & 36 deletions arm_mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ flash_mode_e flash_mode = IDLE;

bool flash_id_mode = false;

bool eeprom_write = false;
uint32_t eeprom_mask = 0;
bool eeprom_write = false;

static const uint8_t bus_size_lut[16] = { 4, 4, 2, 4, 4, 2, 2, 4, 2, 2, 2, 2, 2, 2, 1, 1 };

Expand Down Expand Up @@ -52,19 +51,11 @@ void arm_access_bus(uint32_t address, uint8_t size, access_type_e at) {
}

//Memory read
uint32_t bios_op;

static uint8_t bios_read(uint32_t address) {
uint8_t bios_val;

if ((address | arm_r.r[15]) < 0x4000) {
bios_val = bios[address & 0x3fff];
bios_op |= bios_val << (address & 3) * 8;
} else {
bios_val = bios_op >> (address & 3) * 8;
}

return bios_val;
if ((address | arm_r.r[15]) < 0x4000)
return bios[address & 0x3fff];
else
return bios_op;
}

static uint8_t wram_read(uint32_t address) {
Expand Down Expand Up @@ -92,13 +83,9 @@ static uint8_t rom_read(uint32_t address) {
}

static uint32_t rom_eep_read(uint32_t address) {
/*
* On 16 MiB carts, EEPROM is accessed through 0x0D000000 ~ 0x0DFFFFFF (since this area is unused anyway)
* On bigger than 16 MiB carts, it can only be accessed at 0x0DFFFF00 ~ 0x0DFFFFFF
* We guess that using the Address it writes to the EEPROM (probably would be better to use the cart size directly)
* This is also useful to know if the game uses EEPROM (since only those games will try writing to GamePak area?)
*/
if (eeprom_write && ((address & eeprom_mask) == eeprom_mask))
if (eeprom_write &&
((cart_rom_size > 0x1000000 && (address >> 8) == 0x0dffff) ||
(cart_rom_size <= 0x1000000 && (address >> 24) == 0x00000d)))
return 1; //Read from EEPROM, this returns 1 (when ready) on Write requests, or (TODO) Data on Read requests
else
return rom_read(address);
Expand Down Expand Up @@ -153,27 +140,35 @@ static uint8_t arm_readb(uint32_t address) {
}

static uint32_t arm_readh(uint32_t address) {
uint32_t a = address & ~1;
uint8_t s = address & 1;
if (address < 0x4000 && arm_r.r[15] >= 0x4000) {
return bios_op;
} else {
uint32_t a = address & ~1;
uint8_t s = address & 1;

uint32_t value =
arm_read_(a | 0) << 0 |
arm_read_(a | 1) << 8;
uint32_t value =
arm_read_(a | 0) << 0 |
arm_read_(a | 1) << 8;

return ROR(value, s << 3);
return ROR(value, s << 3);
}
}

static uint32_t arm_read(uint32_t address) {
uint32_t a = address & ~3;
uint8_t s = address & 3;
if (address < 0x4000 && arm_r.r[15] >= 0x4000) {
return bios_op;
} else {
uint32_t a = address & ~3;
uint8_t s = address & 3;

uint32_t value =
arm_read_(a | 0) << 0 |
arm_read_(a | 1) << 8 |
arm_read_(a | 2) << 16 |
arm_read_(a | 3) << 24;
uint32_t value =
arm_read_(a | 0) << 0 |
arm_read_(a | 1) << 8 |
arm_read_(a | 2) << 16 |
arm_read_(a | 3) << 24;

return ROR(value, s << 3);
return ROR(value, s << 3);
}
}

uint8_t arm_readb_n(uint32_t address) {
Expand Down Expand Up @@ -302,7 +297,7 @@ static void arm_write_(uint32_t address, uint8_t value) {

case 0xd:
eeprom_write = true;
eeprom_mask = address & 0xffff00 ? 0xffff00 : 0;
//TODO
break;

case 0xe:
Expand Down
4 changes: 4 additions & 0 deletions arm_mem.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ uint8_t *flash;

uint32_t palette[0x200];

uint32_t bios_op;

int64_t cart_rom_size;

typedef enum {
NON_SEQ,
SEQUENTIAL
Expand Down
100 changes: 83 additions & 17 deletions io.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,23 +203,89 @@ void io_write(uint32_t address, uint8_t value) {
case 0x0400001e: bg[3].yofs.b.b0 = value; break;
case 0x0400001f: bg[3].yofs.b.b1 = value; break;

case 0x04000028: bg_refxl[2].b.b0 = value; break;
case 0x04000029: bg_refxl[2].b.b1 = value; break;
case 0x0400002a: bg_refxh[2].b.b0 = value; break;
case 0x0400002b: bg_refxh[2].b.b1 = value; break;
case 0x0400002c: bg_refyl[2].b.b0 = value; break;
case 0x0400002d: bg_refyl[2].b.b1 = value; break;
case 0x0400002e: bg_refyh[2].b.b0 = value; break;
case 0x0400002f: bg_refyh[2].b.b1 = value; break;

case 0x04000038: bg_refxl[3].b.b0 = value; break;
case 0x04000039: bg_refxl[3].b.b1 = value; break;
case 0x0400003a: bg_refxh[3].b.b0 = value; break;
case 0x0400003b: bg_refxh[3].b.b1 = value; break;
case 0x0400003c: bg_refyl[3].b.b0 = value; break;
case 0x0400003d: bg_refyl[3].b.b1 = value; break;
case 0x0400003e: bg_refyh[3].b.b0 = value; break;
case 0x0400003f: bg_refyh[3].b.b1 = value; break;
case 0x04000020: bg_pa[2].b.b0 = value; break;
case 0x04000021: bg_pa[2].b.b1 = value; break;
case 0x04000022: bg_pb[2].b.b0 = value; break;
case 0x04000023: bg_pb[2].b.b1 = value; break;
case 0x04000024: bg_pc[2].b.b0 = value; break;
case 0x04000025: bg_pc[2].b.b1 = value; break;
case 0x04000026: bg_pd[2].b.b0 = value; break;
case 0x04000027: bg_pd[2].b.b1 = value; break;

case 0x04000028:
bg_refxe[2].b.b0 =
bg_refxi[2].b.b0 = value;
break;
case 0x04000029:
bg_refxe[2].b.b1 =
bg_refxi[2].b.b1 = value;
break;
case 0x0400002a:
bg_refxe[2].b.b2 =
bg_refxi[2].b.b2 = value;
break;
case 0x0400002b:
bg_refxe[2].b.b3 =
bg_refxi[2].b.b3 = value;
break;
case 0x0400002c:
bg_refye[2].b.b0 =
bg_refyi[2].b.b0 = value;
break;
case 0x0400002d:
bg_refye[2].b.b1 =
bg_refyi[2].b.b1 = value;
break;
case 0x0400002e:
bg_refye[2].b.b2 =
bg_refyi[2].b.b2 = value;
break;
case 0x0400002f:
bg_refye[2].b.b3 =
bg_refyi[2].b.b3 = value;
break;

case 0x04000030: bg_pa[3].b.b0 = value; break;
case 0x04000031: bg_pa[3].b.b1 = value; break;
case 0x04000032: bg_pb[3].b.b0 = value; break;
case 0x04000033: bg_pb[3].b.b1 = value; break;
case 0x04000034: bg_pc[3].b.b0 = value; break;
case 0x04000035: bg_pc[3].b.b1 = value; break;
case 0x04000036: bg_pd[3].b.b0 = value; break;
case 0x04000037: bg_pd[3].b.b1 = value; break;

case 0x04000038:
bg_refxe[3].b.b0 =
bg_refxi[3].b.b0 = value;
break;
case 0x04000039:
bg_refxe[3].b.b1 =
bg_refxi[3].b.b1 = value;
break;
case 0x0400003a:
bg_refxe[3].b.b2 =
bg_refxi[3].b.b2 = value;
break;
case 0x0400003b:
bg_refxe[3].b.b3 =
bg_refxi[3].b.b3 = value;
break;
case 0x0400003c:
bg_refye[3].b.b0 =
bg_refyi[3].b.b0 = value;
break;
case 0x0400003d:
bg_refye[3].b.b1 =
bg_refyi[3].b.b1 = value;
break;
case 0x0400003e:
bg_refye[3].b.b2 =
bg_refyi[3].b.b2 = value;
break;
case 0x0400003f:
bg_refye[3].b.b3 =
bg_refyi[3].b.b3 = value;
break;

case 0x04000048: win_in.b.b0 = value; break;
case 0x04000049: win_in.b.b1 = value; break;
Expand Down
14 changes: 10 additions & 4 deletions io.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,16 @@ typedef struct {

bg_t bg[4];

io_reg bg_refxl[4];
io_reg bg_refxh[4];
io_reg bg_refyl[4];
io_reg bg_refyh[4];
io_reg bg_pa[4];
io_reg bg_pb[4];
io_reg bg_pc[4];
io_reg bg_pd[4];

io_reg bg_refxe[4];
io_reg bg_refye[4];

io_reg bg_refxi[4];
io_reg bg_refyi[4];

io_reg win_in;
io_reg win_out;
Expand Down
6 changes: 3 additions & 3 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@ int main(int argc, char* argv[]) {

fseek(image, 0, SEEK_END);

int64_t size = ftell(image);
cart_rom_size = ftell(image);

if (size > max_rom_sz) size = max_rom_sz;
if (cart_rom_size > max_rom_sz) cart_rom_size = max_rom_sz;

fseek(image, 0, SEEK_SET);
fread(rom, size, 1, image);
fread(rom, cart_rom_size, 1, image);

fclose(image);

Expand Down
Loading

0 comments on commit 42373de

Please sign in to comment.