extern "C" {\r
#endif\r
\r
+#include <pico/pico_port.h>\r
+\r
/******************************/\r
/* Compiler dependant defines */\r
/******************************/\r
\r
#ifndef UINT8\r
-#define UINT8 unsigned char\r
+#define UINT8 u8\r
#endif\r
\r
#ifndef INT8\r
-#define INT8 signed char\r
+#define INT8 s8\r
#endif\r
\r
#ifndef UINT16\r
-#define UINT16 unsigned short\r
+#define UINT16 u16\r
#endif\r
\r
#ifndef INT16\r
-#define INT16 signed short\r
+#define INT16 s16\r
#endif\r
\r
#ifndef UINT32\r
-#define UINT32 unsigned int\r
+#define UINT32 u32\r
#endif\r
\r
#ifndef INT32\r
-#define INT32 signed int\r
+#define INT32 s32\r
#endif\r
\r
#ifndef FPTR\r
-#define FPTR uintptr_t\r
+#define FPTR uptr\r
#endif\r
\r
/*************************************/\r
#define CZ80_FETCH_SFT (16 - CZ80_FETCH_BITS)\r
#define CZ80_FETCH_BANK (1 << CZ80_FETCH_BITS)\r
\r
-#define PICODRIVE_HACKS 1\r
-#define CZ80_LITTLE_ENDIAN 1\r
+#define PICODRIVE_HACKS 1\r
+#define CZ80_LITTLE_ENDIAN CPU_IS_LE\r
#define CZ80_USE_JUMPTABLE 1\r
-#define CZ80_BIG_FLAGS_ARRAY 1\r
+#define CZ80_BIG_FLAGS_ARRAY 1\r
//#ifdef BUILD_CPS1PSP\r
//#define CZ80_ENCRYPTED_ROM 1\r
//#else\r
#define CZ80_ENCRYPTED_ROM 0\r
//#endif\r
-#define CZ80_EMULATE_R_EXACTLY 1\r
+#define CZ80_EMULATE_R_EXACTLY 1\r
\r
#define zR8(A) (*CPU->pzR8[A])\r
#define zR16(A) (CPU->pzR16[A]->W)\r
#define READ_OP() GET_OP(); PC++\r
\r
#define READ_ARG() (*(UINT8 *)PC++)\r
-#if CZ80_LITTLE_ENDIAN\r
#define READ_ARG16() (*(UINT8 *)PC | (*(UINT8 *)(PC + 1) << 8)); PC += 2\r
-#else\r
-#define READ_ARG16() (*(UINT8 *)(PC + 1) | (*(UINT8 *)PC << 8)); PC += 2\r
-#endif\r
\r
//#ifndef BUILD_CPS1PSP\r
//#define READ_MEM8(A) memory_region_cpu2[(A)]\r
#define READ_MEM8(A) CPU->Read_Byte(A)\r
#endif\r
//#endif\r
-#if CZ80_LITTLE_ENDIAN\r
#define READ_MEM16(A) (READ_MEM8(A) | (READ_MEM8((A) + 1) << 8))\r
-#else\r
-#define READ_MEM16(A) ((READ_MEM8(A) << 8) | READ_MEM8((A) + 1))\r
-#endif\r
\r
#if PICODRIVE_HACKS\r
#define WRITE_MEM8(A, D) { \\r
#else\r
#define WRITE_MEM8(A, D) CPU->Write_Byte(A, D);\r
#endif\r
-#if CZ80_LITTLE_ENDIAN\r
#define WRITE_MEM16(A, D) { WRITE_MEM8(A, D); WRITE_MEM8((A) + 1, (D) >> 8); }\r
-#else\r
-#define WRITE_MEM16(A, D) { WRITE_MEM8((A) + 1, D); WRITE_MEM8(A, (D) >> 8); }\r
-#endif\r
\r
#define PUSH_16(A) { UINT32 sp; zSP -= 2; sp = zSP; WRITE_MEM16(sp, A); }\r
#define POP_16(A) { UINT32 sp; sp = zSP; A = READ_MEM16(sp); zSP = sp + 2; }\r
/* Data definition */\r
/*******************/\r
\r
-#include <pico/pico_types.h>\r
-/*\r
-#ifdef u8\r
-#undef u8\r
-#endif\r
-\r
-#ifdef s8\r
-#undef s8\r
-#endif\r
-\r
-#ifdef u16\r
-#undef u16\r
-#endif\r
-\r
-#ifdef s16\r
-#undef s16\r
-#endif\r
-\r
-#ifdef u32\r
-#undef u32\r
-#endif\r
-\r
-#ifdef s32\r
-#undef s32\r
-#endif\r
-\r
-#ifdef uptr\r
-#undef uptr\r
-#endif\r
-\r
-#define u8 unsigned char\r
-#define s8 signed char\r
-#define u16 unsigned short\r
-#define s16 signed short\r
-#define u32 unsigned int\r
-#define s32 signed int\r
-#define uptr uintptr_t\r
-*/\r
+#include <pico/pico_port.h>\r
\r
/*\r
typedef unsigned char u8;\r
\r
typedef union\r
{\r
- u8 B;\r
- s8 SB;\r
- u16 W;\r
- s16 SW;\r
+ u8 B[4];\r
+ s8 SB[4];\r
+ u16 W[2];\r
+ s16 SW[2];\r
u32 D;\r
s32 SD;\r
} famec_union32;\r
// internals core macros\r
/////////////////////////\r
\r
+#define XB MEM_LE4(0)\r
+#define XW MEM_LE2(0)\r
+\r
#define DREG(X) (ctx->dreg[(X)].D)\r
#define DREGu32(X) (ctx->dreg[(X)].D)\r
#define DREGs32(X) (ctx->dreg[(X)].SD)\r
-#define DREGu16(X) (ctx->dreg[(X)].W)\r
-#define DREGs16(X) (ctx->dreg[(X)].SW)\r
-#define DREGu8(X) (ctx->dreg[(X)].B)\r
-#define DREGs8(X) (ctx->dreg[(X)].SB)\r
+#define DREGu16(X) (ctx->dreg[(X)].W[XW])\r
+#define DREGs16(X) (ctx->dreg[(X)].SW[XW])\r
+#define DREGu8(X) (ctx->dreg[(X)].B[XB])\r
+#define DREGs8(X) (ctx->dreg[(X)].SB[XB])\r
\r
#define AREG(X) (ctx->areg[(X)].D)\r
#define AREGu32(X) (ctx->areg[(X)].D)\r
#define AREGs32(X) (ctx->areg[(X)].SD)\r
-#define AREGu16(X) (ctx->areg[(X)].W)\r
-#define AREGs16(X) (ctx->areg[(X)].SW)\r
+#define AREGu16(X) (ctx->areg[(X)].W[XW])\r
+#define AREGs16(X) (ctx->areg[(X)].SW[XW])\r
\r
#define ASP (ctx->asp)\r
\r
// ---------------------------------------------------------------
+// swap 32 bit value read from mem in generated code (same as CPU_BE2)
+static void emit_le_swap(int cond, int r)
+{
+#if CPU_IS_LE
+ if (cond == -1)
+ emith_ror(r, r, 16);
+ else
+ emith_ror_c(cond, r, r, 16);
+#endif
+}
+
+// fix memory byte ptr in generated code (same as MEM_BE2)
+static void emit_le_ptr8(int cond, int r)
+{
+#if CPU_IS_LE
+ if (cond == -1)
+ emith_eor_r_imm_ptr(r, 1);
+ else
+ emith_eor_r_imm_ptr_c(cond, r, 1);
+#endif
+}
+
// NB may return either REG or TEMP
static int emit_get_rbase_and_offs(SH2 *sh2, sh2_reg_e r, int rmode, u32 *offs)
{
// if r is in rcache or needed soon anyway, and offs is relative to region,
// and address translation fits in add_ptr_imm (s32), then use rcached const
- if (la == (s32)la && !(*offs & ~mask) && rcache_is_cached(r)) {
- u32 odd = a & 1; // need to fix odd address for correct byte addressing
- la -= (s32)((a & ~mask) - *offs - odd); // diff between reg and memory
+ if (la == (s32)la && !(((a & mask) + *offs) & ~mask) && rcache_is_cached(r)) {
+#if CPU_IS_LE // need to fix odd address for correct byte addressing
+ if (a & 1) *offs += (*offs&1) ? 2 : -2;
+#endif
+ la -= (s32)((a & ~mask) - *offs); // diff between reg and memory
hr = hr2 = rcache_get_reg(r, rmode, NULL);
if ((s32)a < 0) emith_uext_ptr(hr2);
- if ((la & ~omask) - odd) {
+ if (la & ~omask) {
hr = rcache_get_tmp();
- emith_add_r_r_ptr_imm(hr, hr2, (la & ~omask) - odd);
+ emith_add_r_r_ptr_imm(hr, hr2, la & ~omask);
rcache_free(hr2);
}
*offs = (la & omask);
else
hr2 = rcache_get_reg(rd, RC_GR_WRITE, NULL);
switch (size & MF_SIZEMASK) {
- case 0: emith_read8s_r_r_offs(hr2, hr, offs ^ 1); break; // 8
- case 1: emith_read16s_r_r_offs(hr2, hr, offs); break; // 16
- case 2: emith_read_r_r_offs(hr2, hr, offs); emith_ror(hr2, hr2, 16); break;
+ case 0: emith_read8s_r_r_offs(hr2, hr, MEM_BE2(offs)); break; // 8
+ case 1: emith_read16s_r_r_offs(hr2, hr, offs); break; // 16
+ case 2: emith_read_r_r_offs(hr2, hr, offs); emit_le_swap(-1, hr2); break;
}
rcache_free(hr);
if (size & MF_POSTINCR)
emith_sh2_rcall(arg0, arg1, arg2, arg3);
EMITH_SJMP_START(DCOND_CS);
emith_and_r_r_c(DCOND_CC, arg0, arg3);
- emith_eor_r_imm_ptr_c(DCOND_CC, arg0, 1);
+ emit_le_ptr8(DCOND_CC, arg0);
emith_read8s_r_r_r_c(DCOND_CC, RET_REG, arg2, arg0);
emith_ret_c(DCOND_CC);
EMITH_SJMP_END(DCOND_CS);
EMITH_SJMP_START(DCOND_CS);
emith_and_r_r_c(DCOND_CC, arg0, arg3);
emith_read_r_r_r_c(DCOND_CC, RET_REG, arg2, arg0);
- emith_ror_c(DCOND_CC, RET_REG, RET_REG, 16);
+ emit_le_swap(DCOND_CC, RET_REG);
emith_ret_c(DCOND_CC);
EMITH_SJMP_END(DCOND_CS);
emith_move_r_r_ptr(arg1, CONTEXT_REG);
emith_abijump_reg_c(DCOND_CS, arg2);
EMITH_SJMP_END(DCOND_CC);
emith_and_r_r_r(arg1, arg0, arg3);
- emith_eor_r_imm_ptr(arg1, 1);
+ emit_le_ptr8(-1, arg1);
emith_read8s_r_r_r(arg1, arg2, arg1);
emith_push_ret(arg1);
emith_move_r_r_ptr(arg2, CONTEXT_REG);
EMITH_SJMP_END(DCOND_CC);
emith_and_r_r_r(arg1, arg0, arg3);
emith_read_r_r_r(arg1, arg2, arg1);
- emith_ror(arg1, arg1, 16);
+ emit_le_swap(-1, arg1);
emith_push_ret(arg1);
emith_move_r_r_ptr(arg2, CONTEXT_REG);
emith_abicall(p32x_sh2_poll_memory32);
emu_32x_startup();
}
-#define HWSWAP(x) (((x) << 16) | ((x) >> 16))
void p32x_reset_sh2s(void)
{
elprintf(EL_32X, "sh2 reset");
unsigned int vbr;
// initial data
- idl_src = HWSWAP(*(unsigned int *)(Pico.rom + 0x3d4)) & ~0xf0000000;
- idl_dst = HWSWAP(*(unsigned int *)(Pico.rom + 0x3d8)) & ~0xf0000000;
- idl_size= HWSWAP(*(unsigned int *)(Pico.rom + 0x3dc));
+ idl_src = CPU_BE2(*(unsigned int *)(Pico.rom + 0x3d4)) & ~0xf0000000;
+ idl_dst = CPU_BE2(*(unsigned int *)(Pico.rom + 0x3d8)) & ~0xf0000000;
+ idl_size= CPU_BE2(*(unsigned int *)(Pico.rom + 0x3dc));
if (idl_size > Pico.romsize || idl_src + idl_size > Pico.romsize ||
idl_size > 0x40000 || idl_dst + idl_size > 0x40000 || (idl_src & 3) || (idl_dst & 3)) {
elprintf(EL_STATUS|EL_ANOMALY, "32x: invalid initial data ptrs: %06x -> %06x, %06x",
memcpy(Pico32xMem->sdram + idl_dst, Pico.rom + idl_src, idl_size);
// VBR
- vbr = HWSWAP(*(unsigned int *)(Pico.rom + 0x3e8));
+ vbr = CPU_BE2(*(unsigned int *)(Pico.rom + 0x3e8));
sh2_set_vbr(0, vbr);
// checksum and M_OK
unsigned int vbr;
// GBR/VBR
- vbr = HWSWAP(*(unsigned int *)(Pico.rom + 0x3ec));
+ vbr = CPU_BE2(*(unsigned int *)(Pico.rom + 0x3ec));
sh2_set_gbr(1, 0x20004000);
sh2_set_vbr(1, vbr);
// program will set S_OK
int i = 320; \
while (i > 0) { \
for (; i > 0 && (*pmd & 0x3f) == mdbg; pd++, pmd++, i--) { \
- t = pal[*(unsigned char *)((uintptr_t)(p32x++) ^ 1)]; \
+ t = pal[*(unsigned char *)(MEM_BE2((uintptr_t)(p32x++)))]; \
*pd = t; \
} \
for (; i > 0 && (*pmd & 0x3f) != mdbg; pd++, pmd++, i--) { \
- t = pal[*(unsigned char *)((uintptr_t)(p32x++) ^ 1)]; \
+ t = pal[*(unsigned char *)(MEM_BE2((uintptr_t)(p32x++)))]; \
if (t & PXPRIO) \
*pd = t; \
else \
static void (*m68k_write16_io)(u32 a, u32 d);
// addressing byte in 16bit reg
-#define REG8IN16(ptr, offs) ((u8 *)ptr)[(offs) ^ 1]
+#define REG8IN16(ptr, offs) ((u8 *)ptr)[MEM_BE2(offs)]
// poll detection
#define POLL_THRESHOLD 5
// TODO: verify
if ((a & 0xfe00) == 0x5200) { // a15200
elprintf(EL_32X|EL_ANOMALY, "m68k 32x PAL w8 [%06x] %02x @%06x", a, d & 0xff, SekPc);
- ((u8 *)Pico32xMem->pal)[(a & 0x1ff) ^ 1] = d;
+ ((u8 *)Pico32xMem->pal)[MEM_BE2(a & 0x1ff)] = d;
Pico32x.dirty_pal = 1;
return;
}
if (PicoIn.opt & POPT_EN_32X) {
if ((a & 0xffc0) == 0x5100) { // a15100
// regs are always readable
- d = ((u8 *)Pico32x.regs)[(a & 0x3f) ^ 1];
+ d = ((u8 *)Pico32x.regs)[MEM_BE2(a & 0x3f)];
goto out;
}
// allow only COMM for now
if ((a & 0x30) == 0x20) {
u8 *r8 = (u8 *)r;
- r8[a ^ 1] = d;
+ r8[MEM_BE2(a)] = d;
}
return;
}
#define sh2_write8_dramN(p, a, d) \
if ((d & 0xff) != 0) { \
u8 *dram = (u8 *)p; \
- dram[(a & 0x1ffff) ^ 1] = d; \
+ dram[MEM_BE2(a & 0x1ffff)] = d; \
}
static void m68k_write8_dram0_ow(u32 a, u32 d)
static void PicoWrite8_hint(u32 a, u32 d)
{
if ((a & 0xfffc) == 0x0070) {
- Pico32xMem->m68k_rom[a ^ 1] = d;
+ Pico32xMem->m68k_rom[MEM_BE2(a)] = d;
return;
}
// TODO: mirroring?
if (!sh2->is_slave && a < sizeof(Pico32xMem->sh2_rom_m))
- d = Pico32xMem->sh2_rom_m.b[a ^ 1];
+ d = Pico32xMem->sh2_rom_m.b[MEM_BE2(a)];
else if (sh2->is_slave && a < sizeof(Pico32xMem->sh2_rom_s))
- d = Pico32xMem->sh2_rom_s.b[a ^ 1];
+ d = Pico32xMem->sh2_rom_s.b[MEM_BE2(a)];
else
d = sh2_read8_unmapped(a, sh2);
goto out;
{
u32 bank = carthw_ssf2_banks[(a >> 19) & 7] << 19;
s8 *p = sh2->p_rom;
- return p[(bank + (a & 0x7ffff)) ^ 1];
+ return p[MEM_BE2(bank + (a & 0x7ffff))];
}
// read16
u32 bank = carthw_ssf2_banks[(a >> 19) & 7] << 19;
u32 *p = sh2->p_rom;
u32 d = p[(bank + (a & 0x7fffc)) / 4];
- return (d << 16) | (d >> 16);
+ return CPU_BE2(d);
}
// writes
if ((a & 0x3fe00) == 0x4200) {
sh2->poll_cnt = 0;
- ((u8 *)Pico32xMem->pal)[(a & 0x1ff) ^ 1] = d;
+ ((u8 *)Pico32xMem->pal)[MEM_BE2(a & 0x1ff)] = d;
Pico32x.dirty_pal = 1;
goto out;
}
static void REGPARM(3) sh2_write8_sdram(u32 a, u32 d, SH2 *sh2)
{
- u32 a1 = (a & 0x3ffff) ^ 1;
+ u32 a1 = MEM_BE2(a & 0x3ffff);
((u8 *)sh2->p_sdram)[a1] = d;
#ifdef DRC_SH2
u8 *p = sh2->p_drcblk_ram;
static void REGPARM(3) sh2_write8_da(u32 a, u32 d, SH2 *sh2)
{
- u32 a1 = (a & 0xfff) ^ 1;
+ u32 a1 = MEM_BE2(a & 0xfff);
sh2->data_array[a1] = d;
#ifdef DRC_SH2
u8 *p = sh2->p_drcblk_da;
#define sh2_write32_dramN(p, a, d) \
u32 *pd = &((u32 *)p)[(a & 0x1ffff) / 4]; \
if (!(a & 0x20000)) { \
- *pd = (d << 16) | (d >> 16); \
+ *pd = CPU_BE2(d); \
} else { \
/* overwrite */ \
- u32 v = *pd, m = 0; d = (d << 16) | (d >> 16) ; \
+ u32 v = *pd, m = 0; d = CPU_BE2(d); \
if (!(d & 0x000000ff)) m |= 0x000000ff; \
if (!(d & 0x0000ff00)) m |= 0x0000ff00; \
if (!(d & 0x00ff0000)) m |= 0x00ff0000; \
static void REGPARM(3) sh2_write32_sdram(u32 a, u32 d, SH2 *sh2)
{
u32 a1 = a & 0x3fffc;
- *(u32 *)((char*)sh2->p_sdram + a1) = (d << 16) | (d >> 16);
+ *(u32 *)((char*)sh2->p_sdram + a1) = CPU_BE2(d);
#ifdef DRC_SH2
u8 *p = sh2->p_drcblk_ram;
u32 t = p[a1 >> SH2_DRCBLK_RAM_SHIFT];
static void REGPARM(3) sh2_write32_da(u32 a, u32 d, SH2 *sh2)
{
u32 a1 = a & 0xffc;
- *((u32 *)sh2->data_array + a1/4) = (d << 16) | (d >> 16);
+ *((u32 *)sh2->data_array + a1/4) = CPU_BE2(d);
#ifdef DRC_SH2
u8 *p = sh2->p_drcblk_da;
u32 t = p[a1 >> SH2_DRCBLK_DA_SHIFT];
sh2_map += SH2MAP_ADDR2OFFS_R(a);
p = sh2_map->addr;
if (!map_flag_set(p))
- return *(s8 *)((p << 1) + ((a & sh2_map->mask) ^ 1));
+ return *(s8 *)((p << 1) + MEM_BE2(a & sh2_map->mask));
else
return ((sh2_read_handler *)(p << 1))(a, sh2);
}
p = sh2_map->addr;
if (!map_flag_set(p)) {
u32 *pd = (u32 *)((p << 1) + (a & sh2_map->mask));
- return (*pd << 16) | (*pd >> 16);
+ return CPU_BE2(*pd);
} else
return ((sh2_read_handler *)(p << 1))(a, sh2);
}
// align dst to halfword
if (dst & 1) {
- p32x_sh2_write8(dst, *(u8 *)((uptr)ps ^ 1), sh2);
+ p32x_sh2_write8(dst, *(u8 *)MEM_BE2((uptr)ps), sh2);
ps++, dst++, len --;
}
u16 dl, dh = *sp++;
for (i = 0; i < (len & ~1); i += 2, dst += 2, sp++) {
dl = dh, dh = *sp;
+#if CPU_IS_LE
p32x_sh2_write16(dst, (dh >> 8) | (dl << 8), sh2);
+#else
+ p32x_sh2_write16(dst, (dl >> 8) | (dh << 8), sh2);
+#endif
}
if (len & 1)
p32x_sh2_write8(dst, dh, sh2);
u32 d;
for (i = 0; i < (len & ~3); i += 4, dst += 4, sp += 2) {
d = *(u32 *)sp;
- p32x_sh2_write32(dst, (d << 16) | (d >> 16), sh2);
+ p32x_sh2_write32(dst, CPU_BE2(d), sh2);
}
}
if (len & 2) {
dst += 2;
}
if (len & 1)
- p32x_sh2_write8(dst, *sp >> 8, sh2);
+ p32x_sh2_write8(dst, ((u8 *)sp)[MEM_BE2(0)], sh2);
}
return count;
0x2400, 0x0018, // 23c _start_cd
};
-#define HWSWAP(x) (((u16)(x) << 16) | ((x) >> 16))
static void get_bios(void)
{
u16 *ps;
ps = (u16 *)Pico32xMem->m68k_rom;
pl = (u32 *)ps;
for (i = 1; i < 0xc0/4; i++)
- pl[i] = HWSWAP(0x880200 + (i - 1) * 6);
+ pl[i] = CPU_BE2(0x880200 + (i - 1) * 6);
pl[0x70/4] = 0;
// fill with nops
// fill exception vector table to our trap address
for (i = 0; i < 128; i++)
- pl[i] = HWSWAP(0x200);
+ pl[i] = CPU_BE2(0x200);
// start
- pl[0] = pl[2] = HWSWAP(0x204);
+ pl[0] = pl[2] = CPU_BE2(0x204);
// reset SP
- pl[1] = pl[3] = HWSWAP(0x6040000);
+ pl[1] = pl[3] = CPU_BE2(0x6040000);
// startup code
memcpy(&Pico32xMem->sh2_rom_m.b[0x200], msh2_code, sizeof(msh2_code));
// fill exception vector table to our trap address
for (i = 0; i < 128; i++)
- pl[i] = HWSWAP(0x200);
+ pl[i] = CPU_BE2(0x200);
// start
- pl[0] = pl[2] = HWSWAP(0x204);
+ pl[0] = pl[2] = CPU_BE2(0x204);
// reset SP
- pl[1] = pl[3] = HWSWAP(0x603f800);
+ pl[1] = pl[3] = CPU_BE2(0x603f800);
// startup code
memcpy(&Pico32xMem->sh2_rom_s.b[0x200], ssh2_code, sizeof(ssh2_code));
u32 d;
a &= 0x1fe;
- d = r[(a / 2) ^ 1];
+ d = r[MEM_BE2(a / 2)];
elprintf_sh2(sh2, EL_32XP, "peri r16 [%08x] %04x @%06x",
a | ~0x1ff, d, sh2_pc(sh2));
return;
}
- r[(a / 2) ^ 1] = d;
+ r[MEM_BE2(a / 2)] = d;
if ((a & 0x1c0) == 0x140)
p32x_sh2_poll_event(sh2, SH2_STATE_CPOLL, SekCyclesDone());
}
\r
if (fread(&cso->header, 1, sizeof(cso->header), f) != sizeof(cso->header))\r
goto cso_failed;\r
+ cso->header.block_size = CPU_LE4(cso->header.block_size);\r
+ cso->header.total_bytes = CPU_LE4(cso->header.total_bytes);\r
+ cso->header.total_bytes_high = CPU_LE4(cso->header.total_bytes_high);\r
\r
if (strncmp(cso->header.magic, "CISO", 4) != 0) {\r
elprintf(EL_STATUS, "cso: bad header");\r
// byteswap, data needs to be int aligned, src can match dst\r
void Byteswap(void *dst, const void *src, int len)\r
{\r
+#if CPU_IS_LE\r
const unsigned int *ps = src;\r
unsigned int *pd = dst;\r
int i, m;\r
unsigned int t = ps[i];\r
pd[i] = ((t & m) << 8) | ((t & ~m) >> 8);\r
}\r
+#endif\r
}\r
\r
// Interleve a 16k block and byteswap\r
static int InterleveBlock(unsigned char *dest,unsigned char *src)\r
{\r
int i=0;\r
- for (i=0;i<0x2000;i++) dest[(i<<1) ]=src[ i]; // Odd\r
- for (i=0;i<0x2000;i++) dest[(i<<1)+1]=src[0x2000+i]; // Even\r
+ for (i=0;i<0x2000;i++) dest[(i<<1)+MEM_BE2(1)]=src[ i]; // Odd\r
+ for (i=0;i<0x2000;i++) dest[(i<<1)+MEM_BE2(0)]=src[0x2000+i]; // Even\r
return 0;\r
}\r
\r
// This will hang the emu, but will prevent nasty crashes.\r
// note: 4 bytes are padded to every ROM\r
if (rom != NULL)\r
- *(unsigned long *)(rom+romsize) = 0xFFFE4EFA; // 4EFA FFFE byteswapped\r
+ *(unsigned long *)(rom+romsize) = CPU_BE2(0x4EFAFFFE);\r
\r
Pico.rom=rom;\r
Pico.romsize=romsize;\r
if (rom_offset + len > Pico.romsize)\r
return 0;\r
for (i = 0; i < len; i++)\r
- if (s1[i] != s_rom[(i + rom_offset) ^ 1])\r
+ if (s1[i] != s_rom[MEM_BE2(i + rom_offset)])\r
return 1;\r
return 0;\r
}\r
}
elprintf(EL_UIO, "pier r8 [%06x] @%06x", a, SekPc);
- return Pico.rom[(a & 0x7fff) ^ 1];
+ return Pico.rom[MEM_BE2(a & 0x7fff)];
}
static void carthw_pier_mem_setup(void)
#define int16 s16\r
#define int32 s32\r
\r
-#define READ_BYTE(BASE, ADDR) (BASE)[(ADDR)^1]\r
-#define WRITE_BYTE(BASE, ADDR, VAL) (BASE)[(ADDR)^1] = (VAL)\r
+#define READ_BYTE(BASE, ADDR) (BASE)[MEM_BE2(ADDR)]\r
+#define WRITE_BYTE(BASE, ADDR, VAL) (BASE)[MEM_BE2(ADDR)] = (VAL)\r
\r
#define load_param(param, size) \\r
memcpy(param, &state[bufferptr], size); \\r
static u32 PicoReadM68k8_cell0(u32 a)\r
{\r
a = (a&3) | (cell_map(a >> 2) << 2); // cell arranged\r
- return Pico_mcd->word_ram1M[0][a ^ 1];\r
+ return Pico_mcd->word_ram1M[0][MEM_BE2(a)];\r
}\r
\r
static u32 PicoReadM68k8_cell1(u32 a)\r
{\r
a = (a&3) | (cell_map(a >> 2) << 2);\r
- return Pico_mcd->word_ram1M[1][a ^ 1];\r
+ return Pico_mcd->word_ram1M[1][MEM_BE2(a)];\r
}\r
\r
static u32 PicoReadM68k16_cell0(u32 a)\r
static void PicoWriteM68k8_cell0(u32 a, u32 d)\r
{\r
a = (a&3) | (cell_map(a >> 2) << 2);\r
- Pico_mcd->word_ram1M[0][a ^ 1] = d;\r
+ Pico_mcd->word_ram1M[0][MEM_BE2(a)] = d;\r
}\r
\r
static void PicoWriteM68k8_cell1(u32 a, u32 d)\r
{\r
a = (a&3) | (cell_map(a >> 2) << 2);\r
- Pico_mcd->word_ram1M[1][a ^ 1] = d;\r
+ Pico_mcd->word_ram1M[1][MEM_BE2(a)] = d;\r
}\r
\r
static void PicoWriteM68k16_cell0(u32 a, u32 d)\r
static void PicoWriteS68k8_prgwp(u32 a, u32 d)\r
{\r
if (a >= (Pico_mcd->s68k_regs[2] << 9))\r
- Pico_mcd->prg_ram[a ^ 1] = d;\r
+ Pico_mcd->prg_ram[MEM_BE2(a)] = d;\r
}\r
\r
static void PicoWriteS68k16_prgwp(u32 a, u32 d)\r
// decode (080000 - 0bffff, in 1M mode)\r
static u32 PicoReadS68k8_dec0(u32 a)\r
{\r
- u32 d = Pico_mcd->word_ram1M[0][((a >> 1) ^ 1) & 0x1ffff];\r
+ u32 d = Pico_mcd->word_ram1M[0][MEM_BE2(a >> 1) & 0x1ffff];\r
if (a & 1)\r
d &= 0x0f;\r
else\r
\r
static u32 PicoReadS68k8_dec1(u32 a)\r
{\r
- u32 d = Pico_mcd->word_ram1M[1][((a >> 1) ^ 1) & 0x1ffff];\r
+ u32 d = Pico_mcd->word_ram1M[1][MEM_BE2(a >> 1) & 0x1ffff];\r
if (a & 1)\r
d &= 0x0f;\r
else\r
\r
static u32 PicoReadS68k16_dec0(u32 a)\r
{\r
- u32 d = Pico_mcd->word_ram1M[0][((a >> 1) ^ 1) & 0x1ffff];\r
+ u32 d = Pico_mcd->word_ram1M[0][MEM_BE2(a >> 1) & 0x1ffff];\r
d |= d << 4;\r
d &= ~0xf0;\r
return d;\r
\r
static u32 PicoReadS68k16_dec1(u32 a)\r
{\r
- u32 d = Pico_mcd->word_ram1M[1][((a >> 1) ^ 1) & 0x1ffff];\r
+ u32 d = Pico_mcd->word_ram1M[1][MEM_BE2(a >> 1) & 0x1ffff];\r
d |= d << 4;\r
d &= ~0xf0;\r
return d;\r
#define mk_decode_w8(bank) \\r
static void PicoWriteS68k8_dec_m0b##bank(u32 a, u32 d) \\r
{ \\r
- u8 *pd = &Pico_mcd->word_ram1M[bank][((a >> 1) ^ 1) & 0x1ffff]; \\r
+ u8 *pd = &Pico_mcd->word_ram1M[bank][MEM_BE2(a >> 1) & 0x1ffff];\\r
\\r
if (!(a & 1)) \\r
*pd = (*pd & 0x0f) | (d << 4); \\r
\\r
static void PicoWriteS68k8_dec_m1b##bank(u32 a, u32 d) \\r
{ \\r
- u8 *pd = &Pico_mcd->word_ram1M[bank][((a >> 1) ^ 1) & 0x1ffff]; \\r
+ u8 *pd = &Pico_mcd->word_ram1M[bank][MEM_BE2(a >> 1) & 0x1ffff];\\r
u8 mask = (a & 1) ? 0x0f : 0xf0; \\r
\\r
if (!(*pd & mask) && (d & 0x0f)) /* underwrite */ \\r
#define mk_decode_w16(bank) \\r
static void PicoWriteS68k16_dec_m0b##bank(u32 a, u32 d) \\r
{ \\r
- u8 *pd = &Pico_mcd->word_ram1M[bank][((a >> 1) ^ 1) & 0x1ffff]; \\r
+ u8 *pd = &Pico_mcd->word_ram1M[bank][MEM_BE2(a >> 1) & 0x1ffff];\\r
\\r
d &= 0x0f0f; \\r
*pd = d | (d >> 4); \\r
\\r
static void PicoWriteS68k16_dec_m1b##bank(u32 a, u32 d) \\r
{ \\r
- u8 *pd = &Pico_mcd->word_ram1M[bank][((a >> 1) ^ 1) & 0x1ffff]; \\r
+ u8 *pd = &Pico_mcd->word_ram1M[bank][MEM_BE2(a >> 1) & 0x1ffff];\\r
\\r
d &= 0x0f0f; /* underwrite */ \\r
if (!(*pd & 0xf0)) *pd |= d >> 4; \\r
\\r
static void PicoWriteS68k16_dec_m2b##bank(u32 a, u32 d) \\r
{ \\r
- u8 *pd = &Pico_mcd->word_ram1M[bank][((a >> 1) ^ 1) & 0x1ffff]; \\r
+ u8 *pd = &Pico_mcd->word_ram1M[bank][MEM_BE2(a >> 1) & 0x1ffff];\\r
\\r
d &= 0x0f0f; /* overwrite */ \\r
d |= d >> 4; \\r
\r
pal = ((code>>9)&0x30) | sh; // shadow\r
\r
- pack = *(u32 *)(PicoMem.vram + addr);\r
+ pack = CPU_LE2(*(u32 *)(PicoMem.vram + addr));\r
if (!pack)\r
blank = code;\r
}\r
}\r
\r
pack = (code & 0x1000 ? ty^0xe : ty); // Y-flip\r
- pack = *(u32 *)(PicoMem.vram + addr+pack);\r
+ pack = CPU_LE2(*(u32 *)(PicoMem.vram + addr+pack));\r
if (!pack)\r
blank = code;\r
\r
\r
pal = ((code>>9)&0x30) | sh; // shadow\r
\r
- pack = *(u32 *)(PicoMem.vram + addr);\r
+ pack = CPU_LE2(*(u32 *)(PicoMem.vram + addr));\r
if (!pack)\r
blank = code;\r
}\r
addr=(code&0x7ff)<<4;\r
if (code&0x1000) addr+=14-ty; else addr+=ty; // Y-flip\r
\r
- pack = *(u32 *)(PicoMem.vram + addr);\r
+ pack = CPU_LE2(*(u32 *)(PicoMem.vram + addr));\r
if (!pack) {\r
blank = code;\r
continue;\r
addr=(code&0x7ff)<<4;\r
if (code&0x1000) addr+=14-ty; else addr+=ty; // Y-flip\r
\r
- pack = *(u32 *)(PicoMem.vram + addr);\r
+ pack = CPU_LE2(*(u32 *)(PicoMem.vram + addr));\r
if (!pack) {\r
blank = code;\r
continue;\r
if(sx<=0) continue;\r
if(sx>=328) break; // Offscreen\r
\r
- pack = *(u32 *)(PicoMem.vram + (tile & 0x7fff));\r
+ pack = CPU_LE2(*(u32 *)(PicoMem.vram + (tile & 0x7fff)));\r
fTileFunc(pd + sx, pack, pal);\r
}\r
}\r
int sx, sy;\r
\r
// parse the sprite data\r
- sy=sprite[0];\r
+ sy=CPU_LE2(sprite[0]);\r
height=sy>>24;\r
sy=(sy&0x3ff)-0x100; // Y\r
width=(height>>2)&3; height&=3;\r
\r
row=(Pico.est.DrawScanline<<1)-sy; // Row of the sprite we are on\r
\r
- code=sprite[1];\r
+ code=CPU_LE2(sprite[1]);\r
sx=((code>>16)&0x1ff)-0x78; // X\r
\r
if (code&0x1000) row^=(16<<height)-1; // Flip Y\r
if(sx<=0) continue;\r
if(sx>=328) break; // Offscreen\r
\r
- pack = *(u32 *)(PicoMem.vram + (tile & 0x7fff));\r
+ pack = CPU_LE2(*(u32 *)(PicoMem.vram + (tile & 0x7fff)));\r
if (code & 0x0800) TileFlip(pd + sx, pack, pal);\r
else TileNorm(pd + sx, pack, pal);\r
}\r
sprite=(u32 *)(PicoMem.vram+((table+(link<<2))&0x7ffc)); // Find sprite\r
\r
// get sprite info\r
- code = sprite[0];\r
- sx = sprite[1];\r
+ code = CPU_LE2(sprite[0]);\r
+ sx = CPU_LE2(sprite[1]);\r
if(((sx>>15)&1) != pri) goto nextsprite; // wrong priority sprite\r
\r
// check if it is on this line\r
if(sx<=0) continue;\r
if(sx>=328) break; // Offscreen\r
\r
- pack = *(u32 *)(PicoMem.vram + (tile & 0x7fff));\r
+ pack = CPU_LE2(*(u32 *)(PicoMem.vram + (tile & 0x7fff)));\r
fTileFunc(pd + sx, pack, pal);\r
}\r
}\r
\r
if(sx>=328) break; // Offscreen\r
\r
- pack = *(u32 *)(PicoMem.vram + (tile & 0x7fff));\r
+ pack = CPU_LE2(*(u32 *)(PicoMem.vram + (tile & 0x7fff)));\r
\r
m |= mp[1] << 8; // next mask byte\r
// shift mask bits to bits 8-15 for easier load/store handling\r
pal = (code>>9)&0x30;\r
}\r
\r
- pack = *(u32 *)(PicoMem.vram + addr);\r
+ pack = CPU_LE2(*(u32 *)(PicoMem.vram + addr));\r
\r
if (code & 0x0800) TileFlip_and(pd + dx, pack, pal);\r
else TileNorm_and(pd + dx, pack, pal);\r
}\r
\r
pack = code & 0x1000 ? ty^0xe : ty; // Y-flip\r
- pack = *(u32 *)(PicoMem.vram + addr+pack);\r
+ pack = CPU_LE2(*(u32 *)(PicoMem.vram + addr+pack));\r
\r
if (code & 0x0800) TileFlip_and(pd + dx, pack, pal);\r
else TileNorm_and(pd + dx, pack, pal);\r
\r
pal = (code>>9)&0x30; // shadow\r
\r
- pack = *(u32 *)(PicoMem.vram + addr);\r
+ pack = CPU_LE2(*(u32 *)(PicoMem.vram + addr));\r
}\r
\r
if (code & 0x0800) TileFlip_and(pd + dx, pack, pal);\r
mp = mb+(sx>>3);\r
for (m = *mp; width; width--, sx+=8, tile+=delta, *mp++ = m, m >>= 8)\r
{\r
- unsigned int pack;\r
+ u32 pack;\r
\r
if(sx>=328) break; // Offscreen\r
\r
- pack = *(u32 *)(PicoMem.vram + (tile & 0x7fff));\r
+ pack = CPU_LE2(*(u32 *)(PicoMem.vram + (tile & 0x7fff)));\r
\r
m |= mp[1] << 8; // next mask byte\r
// shift mask bits to bits 8-15 for easier load/store handling\r
\r
// parse sprite info. the 1st half comes from the VDPs internal cache,\r
// the 2nd half is read from VRAM\r
- code = VdpSATCache[link]; // normally but not always equal to sprite[0]\r
+ code = CPU_LE2(VdpSATCache[link]); // normally same as sprite[0]\r
sy = (code&0x1ff)-0x80;\r
hv = (code>>24)&0xf;\r
height = (hv&3)+1;\r
width = (hv>>2)+1;\r
\r
- code2 = sprite[1];\r
+ code2 = CPU_LE2(sprite[1]);\r
sx = (code2>>16)&0x1ff;\r
sx -= 0x78; // Get X coordinate + 8\r
\r
\r
// XXX: this is banking unfriendly\r
if (a < Pico.romsize)\r
- return Pico.rom[a ^ 1];\r
+ return Pico.rom[MEM_BE2(a)];\r
\r
return m68k_unmapped_read8(a);\r
}\r
if (map_flag_set(v)) \
return ((cpu68k_read_f *)(v << 1))(a); \
else \
- return *(u8 *)((v << 1) + (a ^ 1)); \
+ return *(u8 *)((v << 1) + MEM_BE2(a)); \
}
#define MAKE_68K_READ16(name, map) \
if (map_flag_set(v)) \
((cpu68k_write_f *)(v << 1))(a, d); \
else \
- *(u8 *)((v << 1) + (a ^ 1)) = d; \
+ *(u8 *)((v << 1) + MEM_BE2(a)) = d; \
}
#define MAKE_68K_WRITE16(name, map) \
for (i = s = 0; i < 64; i++)
{
int y;
- y = sat[i] + 1;
+ y = sat[MEM_LE2(i)] + 1;
if (y == 0xd1)
break;
if (y + h <= scanline || scanline < y)
break;
}
- sprites_x[s] = xoff + sat[0x80 + i*2];
- sprites_addr[s] = sprite_base + ((sat[0x80 + i*2 + 1] & addr_mask) << (5-1)) +
+ sprites_x[s] = xoff + sat[MEM_LE2(0x80 + i*2)];
+ sprites_addr[s] = sprite_base + ((sat[MEM_LE2(0x80 + i*2 + 1)] & addr_mask) << (5-1)) +
((scanline - y) << (2-1));
s++;
}
// now draw all sprites backwards
for (--s; s >= 0; s--) {
- pack = *(u32 *)(PicoMem.vram + sprites_addr[s]);
+ pack = CPU_LE2(*(u32 *)(PicoMem.vram + sprites_addr[s]));
TileNormM4(sprites_x[s], pack, 0x10);
}
}
pal = (code>>7) & 0x10;
}
- pack = *(u32 *)(PicoMem.vram + addr); /* Get 4 bitplanes / 8 pixels */
+ pack = CPU_LE2(*(u32 *)(PicoMem.vram + addr)); /* Get 4 bitplanes / 8 pixels */
if (pack == 0) TileBGM4(dx, pal);
else if (code & 0x0200) TileFlipM4Low(dx, pack, pal);
else TileNormM4Low(dx, pack, pal);
pal = (code>>7) & 0x10;
}
- pack = *(u32 *)(PicoMem.vram + addr); /* Get 4 bitplanes / 8 pixels */
+ pack = CPU_LE2(*(u32 *)(PicoMem.vram + addr)); /* Get 4 bitplanes / 8 pixels */
if (pack == 0) {
blank = code;
continue;
#define P32XI_CMD (1 << 8/2)\r
#define P32XI_PWM (1 << 6/2)\r
\r
-// peripheral reg access\r
-#define PREG8(regs,offs) ((unsigned char *)regs)[offs ^ 3]\r
+// peripheral reg access (32 bit regs)\r
+#define PREG8(regs,offs) ((unsigned char *)regs)[MEM_BE4(offs)]\r
\r
#define DMAC_FIFO_LEN (4*2)\r
#define PWM_BUFF_LEN 1024 // in one channel samples\r
#if !(defined(_MSC_VER) && _MSC_VER < 1800)
#include <stdint.h>
#endif
+#include "pico_types.h"
#if defined(__GNUC__) && defined(__i386__)
#define REGPARM(x) __attribute__((regparm(x)))
#define strdup _strdup
#endif
+
+// There's no standard way to determine endianess at compile time.
+// Do not bother with mixed endian platforms, no one will ever compile on that.
+#if defined __BYTE_ORDER__
+#define CPU_IS_LE __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#elif defined _BYTE_ORDER
+#define CPU_IS_LE __BYTE_ORDER == __LITTLE_ENDIAN
+#elif defined __BIG_ENDIAN__ || defined _M_PPC // Windows on PPC was big endian
+#define CPU_IS_LE 0
+#elif defined __LITTLE_ENDIAN__ || defined _WIN32 // all other Windows is LE
+#define CPU_IS_LE 1
+#else
+#warning "can't detect byte order, assume little endian"
+#define CPU_IS_LE 1
+#endif
+
+#if CPU_IS_LE
+// address/offset operations
+#define MEM_BE2(a) ((a)^1) // addr/offs of u8 in u16, or u16 in u32
+#define MEM_BE4(a) ((a)^3) // addr/offs of u8 in u32
+#define MEM_LE2(a) (a)
+#define MEM_LE4(a) (a)
+// swapping
+#define CPU_BE2(v) (((v)<<16)|((v)>>16))
+#define CPU_BE4(v) (((u32)(v)>>24)|(((v)>>8)&0x00ff00)| \
+ (((v)<<8)&0xff0000)|(u32)((v)<<24))
+#define CPU_LE2(v) (v) // swap of 2*u16 in u32
+#define CPU_LE4(v) (v) // swap of 4*u8 in u32
+#else
+// address/offset operations
+#define MEM_BE2(a) (a)
+#define MEM_BE4(a) (a)
+#define MEM_LE2(a) ((a)^1)
+#define MEM_LE4(a) ((a)^3)
+// swapping
+#define CPU_BE2(v) (v)
+#define CPU_BE4(v) (v)
+#define CPU_LE2(v) (((v)<<16)|((v)>>16))
+#define CPU_LE4(v) (((u32)(v)>>24)|(((v)>>8)&0x00ff00)| \
+ (((v)<<8)&0xff0000)|(u32)((v)<<24))
+#endif
+
#endif // PICO_PORT_INCLUDED
struct PicoVideo *pv = &Pico.video;
unsigned char d;
- d = PicoMem.vramb[pv->addr];
+ d = PicoMem.vramb[MEM_LE2(pv->addr)];
pv->addr = (pv->addr + 1) & 0x3fff;
pv->pending = 0;
return d;
if (PicoMem.cram[pv->addr & 0x1f] != d) Pico.m.dirtyPal = 1;
PicoMem.cram[pv->addr & 0x1f] = d;
} else {
- PicoMem.vramb[pv->addr] = d;
+ PicoMem.vramb[MEM_LE2(pv->addr)] = d;
}
pv->addr = (pv->addr + 1) & 0x3fff;
#include "plat_sdl.h"
#include "version.h"
-#include <pico/pico.h>
+#include <pico/pico_int.h>
static void *shadow_fb;
int r = (i >> 11) & 0x1f, g = (i >> 6) & 0x1f, b = (i >> 0) & 0x1f;
int y = (yuv_ry[r] + yuv_gy[g] + yuv_by[b]) >> 16;
yuv_uyvy[i].y = yuv_y[y];
+#if CPU_IS_LE
yuv_uyvy[i].vyu = (yuv_v[r-y + 32] << 16) | (yuv_y[y] << 8) | yuv_u[b-y + 32];
+#else
+ yuv_uyvy[i].vyu = (yuv_v[b-y + 32] << 16) | (yuv_y[y] << 8) | yuv_u[r-y + 32];
+#endif
}
}
{
struct uyvy *uyvy0 = yuv_uyvy + src[0], *uyvy1 = yuv_uyvy + src[1];
struct uyvy *uyvy2 = yuv_uyvy + src[2], *uyvy3 = yuv_uyvy + src[3];
+#if CPU_IS_LE
dst[0] = (uyvy0->y << 24) | uyvy0->vyu;
dst[1] = (uyvy1->y << 24) | uyvy1->vyu;
dst[2] = (uyvy2->y << 24) | uyvy2->vyu;
dst[3] = (uyvy3->y << 24) | uyvy3->vyu;
+#else
+ dst[0] = uyvy0->y | (uyvy0->vyu << 8);
+ dst[1] = uyvy1->y | (uyvy1->vyu << 8);
+ dst[2] = uyvy2->y | (uyvy2->vyu << 8);
+ dst[3] = uyvy3->y | (uyvy3->vyu << 8);
+#endif
} else
for (; pixels > 0; src += 4, dst += 2, pixels -= 4)
{
struct uyvy *uyvy0 = yuv_uyvy + src[0], *uyvy1 = yuv_uyvy + src[1];
struct uyvy *uyvy2 = yuv_uyvy + src[2], *uyvy3 = yuv_uyvy + src[3];
+#if CPU_IS_LE
dst[0] = (uyvy1->y << 24) | uyvy0->vyu;
dst[1] = (uyvy3->y << 24) | uyvy2->vyu;
+#else
+ dst[0] = uyvy1->y | (uyvy0->vyu << 8);
+ dst[1] = uyvy3->y | (uyvy2->vyu << 8);
+#endif
}
}