notaz.gp2x.de
/
pcsx_rearmed.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
drc: try to prevent wrong eviction
[pcsx_rearmed.git]
/
plugins
/
gpulib
/
gpu.c
diff --git
a/plugins/gpulib/gpu.c
b/plugins/gpulib/gpu.c
index
ed37b71
..
ed04d73
100644
(file)
--- a/
plugins/gpulib/gpu.c
+++ b/
plugins/gpulib/gpu.c
@@
-54,12
+54,13
@@
static noinline void do_cmd_reset(void)
static noinline void do_reset(void)
{
unsigned int i;
static noinline void do_reset(void)
{
unsigned int i;
+
do_cmd_reset();
memset(gpu.regs, 0, sizeof(gpu.regs));
for (i = 0; i < sizeof(gpu.ex_regs) / sizeof(gpu.ex_regs[0]); i++)
gpu.ex_regs[i] = (0xe0 + i) << 24;
do_cmd_reset();
memset(gpu.regs, 0, sizeof(gpu.regs));
for (i = 0; i < sizeof(gpu.ex_regs) / sizeof(gpu.ex_regs[0]); i++)
gpu.ex_regs[i] = (0xe0 + i) << 24;
- gpu.status
.reg
= 0x14802000;
+ gpu.status = 0x14802000;
gpu.gp0 = 0;
gpu.regs[3] = 1;
gpu.screen.hres = gpu.screen.w = 256;
gpu.gp0 = 0;
gpu.regs[3] = 1;
gpu.screen.hres = gpu.screen.w = 256;
@@
-80,7
+81,7
@@
static noinline void update_height(void)
{
// TODO: emulate this properly..
int sh = gpu.screen.y2 - gpu.screen.y1;
{
// TODO: emulate this properly..
int sh = gpu.screen.y2 - gpu.screen.y1;
- if (gpu.status
.dheight
)
+ if (gpu.status
& PSX_GPU_STATUS_DHEIGHT
)
sh *= 2;
if (sh <= 0 || sh > gpu.screen.vres)
sh = gpu.screen.vres;
sh *= 2;
if (sh <= 0 || sh > gpu.screen.vres)
sh = gpu.screen.vres;
@@
-90,6
+91,8
@@
static noinline void update_height(void)
static noinline void decide_frameskip(void)
{
static noinline void decide_frameskip(void)
{
+ *gpu.frameskip.dirty = 1;
+
if (gpu.frameskip.active)
gpu.frameskip.cnt++;
else {
if (gpu.frameskip.active)
gpu.frameskip.cnt++;
else {
@@
-97,7
+100,9
@@
static noinline void decide_frameskip(void)
gpu.frameskip.frame_ready = 1;
}
gpu.frameskip.frame_ready = 1;
}
- if (!gpu.frameskip.active && *gpu.frameskip.advice)
+ if (*gpu.frameskip.force)
+ gpu.frameskip.active = 1;
+ else if (!gpu.frameskip.active && *gpu.frameskip.advice)
gpu.frameskip.active = 1;
else if (gpu.frameskip.set > 0 && gpu.frameskip.cnt < gpu.frameskip.set)
gpu.frameskip.active = 1;
gpu.frameskip.active = 1;
else if (gpu.frameskip.set > 0 && gpu.frameskip.cnt < gpu.frameskip.set)
gpu.frameskip.active = 1;
@@
-117,7
+122,7
@@
static noinline int decide_frameskip_allow(uint32_t cmd_e3)
// but not for interlace since it'll most likely always do that
uint32_t x = cmd_e3 & 0x3ff;
uint32_t y = (cmd_e3 >> 10) & 0x3ff;
// but not for interlace since it'll most likely always do that
uint32_t x = cmd_e3 & 0x3ff;
uint32_t y = (cmd_e3 >> 10) & 0x3ff;
- gpu.frameskip.allow =
gpu.status.interlace
||
+ gpu.frameskip.allow =
(gpu.status & PSX_GPU_STATUS_INTERLACE)
||
(uint32_t)(x - gpu.screen.x) >= (uint32_t)gpu.screen.w ||
(uint32_t)(y - gpu.screen.y) >= (uint32_t)gpu.screen.h;
return gpu.frameskip.allow;
(uint32_t)(x - gpu.screen.x) >= (uint32_t)gpu.screen.w ||
(uint32_t)(y - gpu.screen.y) >= (uint32_t)gpu.screen.h;
return gpu.frameskip.allow;
@@
-132,14
+137,13
@@
static noinline void get_gpu_info(uint32_t data)
gpu.gp0 = gpu.ex_regs[data & 7] & 0xfffff;
break;
case 0x05:
gpu.gp0 = gpu.ex_regs[data & 7] & 0xfffff;
break;
case 0x05:
- case 0x06:
gpu.gp0 = gpu.ex_regs[5] & 0x3fffff;
break;
case 0x07:
gpu.gp0 = 2;
break;
default:
gpu.gp0 = gpu.ex_regs[5] & 0x3fffff;
break;
case 0x07:
gpu.gp0 = 2;
break;
default:
- gpu.gp0 = 0;
+ // gpu.gp0 unchanged
break;
}
}
break;
}
}
@@
-285,10
+289,14
@@
void GPUwriteStatus(uint32_t data)
do_cmd_reset();
break;
case 0x03:
do_cmd_reset();
break;
case 0x03:
- gpu.status.blanking = data & 1;
+ if (data & 1)
+ gpu.status |= PSX_GPU_STATUS_BLANKING;
+ else
+ gpu.status &= ~PSX_GPU_STATUS_BLANKING;
break;
case 0x04:
break;
case 0x04:
- gpu.status.dma = data & 3;
+ gpu.status &= ~PSX_GPU_STATUS_DMA_MASK;
+ gpu.status |= PSX_GPU_STATUS_DMA(data & 3);
break;
case 0x05:
gpu.screen.x = data & 0x3ff;
break;
case 0x05:
gpu.screen.x = data & 0x3ff;
@@
-312,9
+320,9
@@
void GPUwriteStatus(uint32_t data)
update_height();
break;
case 0x08:
update_height();
break;
case 0x08:
- gpu.status
.reg = (gpu.status.reg
& ~0x7f0000) | ((data & 0x3F) << 17) | ((data & 0x40) << 10);
- gpu.screen.hres = hres[(gpu.status
.reg
>> 16) & 7];
- gpu.screen.vres = vres[(gpu.status
.reg
>> 19) & 3];
+ gpu.status
= (gpu.status
& ~0x7f0000) | ((data & 0x3F) << 17) | ((data & 0x40) << 10);
+ gpu.screen.hres = hres[(gpu.status >> 16) & 7];
+ gpu.screen.vres = vres[(gpu.status >> 19) & 3];
update_width();
update_height();
renderer_notify_res_change();
update_width();
update_height();
renderer_notify_res_change();
@@
-428,9
+436,9
@@
static void start_vram_transfer(uint32_t pos_word, uint32_t size_word, int is_re
renderer_flush_queues();
if (is_read) {
renderer_flush_queues();
if (is_read) {
- gpu.status
.img = 1
;
+ gpu.status
|= PSX_GPU_STATUS_IMG
;
// XXX: wrong for width 1
// XXX: wrong for width 1
-
memcpy(&gpu.gp0, VRAM_MEM_XY(gpu.dma.x, gpu.dma.y), 4
);
+
gpu.gp0 = LE32TOH(*(uint32_t *) VRAM_MEM_XY(gpu.dma.x, gpu.dma.y)
);
gpu.state.last_vram_read_frame = *gpu.state.frame_count;
}
gpu.state.last_vram_read_frame = *gpu.state.frame_count;
}
@@
-441,7
+449,7
@@
static void start_vram_transfer(uint32_t pos_word, uint32_t size_word, int is_re
static void finish_vram_transfer(int is_read)
{
if (is_read)
static void finish_vram_transfer(int is_read)
{
if (is_read)
- gpu.status
.img = 0
;
+ gpu.status
&= ~PSX_GPU_STATUS_IMG
;
else
renderer_update_caches(gpu.dma_start.x, gpu.dma_start.y,
gpu.dma_start.w, gpu.dma_start.h);
else
renderer_update_caches(gpu.dma_start.x, gpu.dma_start.y,
gpu.dma_start.w, gpu.dma_start.h);
@@
-456,12
+464,12
@@
static noinline int do_cmd_list_skip(uint32_t *data, int count, int *last_cmd)
while (pos < count && skip) {
uint32_t *list = data + pos;
while (pos < count && skip) {
uint32_t *list = data + pos;
- cmd =
list[0]
>> 24;
+ cmd =
LE32TOH(list[0])
>> 24;
len = 1 + cmd_lengths[cmd];
switch (cmd) {
case 0x02:
len = 1 + cmd_lengths[cmd];
switch (cmd) {
case 0x02:
- if ((
int)(list[2] & 0x3ff) > gpu.screen.w || (int)((list[2]
>> 16) & 0x1ff) > gpu.screen.h)
+ if ((
LE32TOH(list[2]) & 0x3ff) > gpu.screen.w || ((LE32TOH(list[2])
>> 16) & 0x1ff) > gpu.screen.h)
// clearing something large, don't skip
do_cmd_list(list, 3, &dummy);
else
// clearing something large, don't skip
do_cmd_list(list, 3, &dummy);
else
@@
-472,12
+480,12
@@
static noinline int do_cmd_list_skip(uint32_t *data, int count, int *last_cmd)
case 0x34 ... 0x37:
case 0x3c ... 0x3f:
gpu.ex_regs[1] &= ~0x1ff;
case 0x34 ... 0x37:
case 0x3c ... 0x3f:
gpu.ex_regs[1] &= ~0x1ff;
- gpu.ex_regs[1] |=
list[4 + ((cmd >> 4) & 1)]
& 0x1ff;
+ gpu.ex_regs[1] |=
LE32TOH(list[4 + ((cmd >> 4) & 1)])
& 0x1ff;
break;
case 0x48 ... 0x4F:
for (v = 3; pos + v < count; v++)
{
break;
case 0x48 ... 0x4F:
for (v = 3; pos + v < count; v++)
{
- if ((list[v] &
0xf000f000) == 0x50005000
)
+ if ((list[v] &
HTOLE32(0xf000f000)) == HTOLE32(0x50005000)
)
break;
}
len += v - 3;
break;
}
len += v - 3;
@@
-485,16
+493,16
@@
static noinline int do_cmd_list_skip(uint32_t *data, int count, int *last_cmd)
case 0x58 ... 0x5F:
for (v = 4; pos + v < count; v += 2)
{
case 0x58 ... 0x5F:
for (v = 4; pos + v < count; v += 2)
{
- if ((list[v] &
0xf000f000) == 0x50005000
)
+ if ((list[v] &
HTOLE32(0xf000f000)) == HTOLE32(0x50005000)
)
break;
}
len += v - 4;
break;
default:
if (cmd == 0xe3)
break;
}
len += v - 4;
break;
default:
if (cmd == 0xe3)
- skip = decide_frameskip_allow(
list[0]
);
+ skip = decide_frameskip_allow(
LE32TOH(list[0])
);
if ((cmd & 0xf8) == 0xe0)
if ((cmd & 0xf8) == 0xe0)
- gpu.ex_regs[cmd & 7] =
list[0]
;
+ gpu.ex_regs[cmd & 7] =
LE32TOH(list[0])
;
break;
}
break;
}
@@
-529,7
+537,7
@@
static noinline int do_cmd_buffer(uint32_t *data, int count)
break;
}
break;
}
- cmd =
data[pos]
>> 24;
+ cmd =
LE32TOH(data[pos])
>> 24;
if (0xa0 <= cmd && cmd <= 0xdf) {
if (unlikely((pos+2) >= count)) {
// incomplete vram write/read cmd, can't consume yet
if (0xa0 <= cmd && cmd <= 0xdf) {
if (unlikely((pos+2) >= count)) {
// incomplete vram write/read cmd, can't consume yet
@@
-538,13
+546,13
@@
static noinline int do_cmd_buffer(uint32_t *data, int count)
}
// consume vram write/read cmd
}
// consume vram write/read cmd
- start_vram_transfer(
data[pos + 1], data[pos + 2]
, (cmd & 0xe0) == 0xc0);
+ start_vram_transfer(
LE32TOH(data[pos + 1]), LE32TOH(data[pos + 2])
, (cmd & 0xe0) == 0xc0);
pos += 3;
continue;
}
// 0xex cmds might affect frameskip.allow, so pass to do_cmd_list_skip
pos += 3;
continue;
}
// 0xex cmds might affect frameskip.allow, so pass to do_cmd_list_skip
- if (gpu.frameskip.active && (gpu.frameskip.allow || ((
data[pos]
>> 24) & 0xf0) == 0xe0))
+ if (gpu.frameskip.active && (gpu.frameskip.allow || ((
LE32TOH(data[pos])
>> 24) & 0xf0) == 0xe0))
pos += do_cmd_list_skip(data + pos, count - pos, &cmd);
else {
pos += do_cmd_list(data + pos, count - pos, &cmd);
pos += do_cmd_list_skip(data + pos, count - pos, &cmd);
else {
pos += do_cmd_list(data + pos, count - pos, &cmd);
@@
-556,9
+564,9
@@
static noinline int do_cmd_buffer(uint32_t *data, int count)
break;
}
break;
}
- gpu.status
.reg
&= ~0x1fff;
- gpu.status
.reg
|= gpu.ex_regs[1] & 0x7ff;
- gpu.status
.reg
|= (gpu.ex_regs[6] & 3) << 11;
+ gpu.status &= ~0x1fff;
+ gpu.status |= gpu.ex_regs[1] & 0x7ff;
+ gpu.status |= (gpu.ex_regs[6] & 3) << 11;
gpu.state.fb_dirty |= vram_dirty;
gpu.state.fb_dirty |= vram_dirty;
@@
-593,12
+601,12
@@
void GPUwriteDataMem(uint32_t *mem, int count)
void GPUwriteData(uint32_t data)
{
log_io("gpu_write %08x\n", data);
void GPUwriteData(uint32_t data)
{
log_io("gpu_write %08x\n", data);
- gpu.cmd_buffer[gpu.cmd_len++] =
data
;
+ gpu.cmd_buffer[gpu.cmd_len++] =
HTOLE32(data)
;
if (gpu.cmd_len >= CMD_BUFFER_LEN)
flush_cmd_buffer();
}
if (gpu.cmd_len >= CMD_BUFFER_LEN)
flush_cmd_buffer();
}
-long GPUdmaChain(uint32_t *rambase, uint32_t start_addr)
+long GPUdmaChain(uint32_t *rambase, uint32_t start_addr
, uint32_t *progress_addr
)
{
uint32_t addr, *list, ld_addr = 0;
int len, left, count;
{
uint32_t addr, *list, ld_addr = 0;
int len, left, count;
@@
-614,22
+622,36
@@
long GPUdmaChain(uint32_t *rambase, uint32_t start_addr)
for (count = 0; (addr & 0x800000) == 0; count++)
{
list = rambase + (addr & 0x1fffff) / 4;
for (count = 0; (addr & 0x800000) == 0; count++)
{
list = rambase + (addr & 0x1fffff) / 4;
- len =
list[0]
>> 24;
- addr =
list[0]
& 0xffffff;
+ len =
LE32TOH(list[0])
>> 24;
+ addr =
LE32TOH(list[0])
& 0xffffff;
preload(rambase + (addr & 0x1fffff) / 4);
cpu_cycles += 10;
if (len > 0)
cpu_cycles += 5 + len;
preload(rambase + (addr & 0x1fffff) / 4);
cpu_cycles += 10;
if (len > 0)
cpu_cycles += 5 + len;
- log_io(".chain %08x #%d\n", (list - rambase) * 4, len);
+ log_io(".chain %08lx #%d+%d\n",
+ (long)(list - rambase) * 4, len, gpu.cmd_len);
+ if (unlikely(gpu.cmd_len > 0)) {
+ memcpy(gpu.cmd_buffer + gpu.cmd_len, list + 1, len * 4);
+ gpu.cmd_len += len;
+ flush_cmd_buffer();
+ continue;
+ }
if (len) {
left = do_cmd_buffer(list + 1, len);
if (len) {
left = do_cmd_buffer(list + 1, len);
- if (left)
- log_anomaly("GPUdmaChain: discarded %d/%d words\n", left, len);
+ if (left) {
+ memcpy(gpu.cmd_buffer, list + 1 + len - left, left * 4);
+ gpu.cmd_len = left;
+ log_anomaly("GPUdmaChain: %d/%d words left\n", left, len);
+ }
}
}
+ if (progress_addr) {
+ *progress_addr = addr;
+ break;
+ }
#define LD_THRESHOLD (8*1024)
if (count >= LD_THRESHOLD) {
if (count == LD_THRESHOLD) {
#define LD_THRESHOLD (8*1024)
if (count >= LD_THRESHOLD) {
if (count == LD_THRESHOLD) {
@@
-640,7
+662,7
@@
long GPUdmaChain(uint32_t *rambase, uint32_t start_addr)
// loop detection marker
// (bit23 set causes DMA error on real machine, so
// unlikely to be ever set by the game)
// loop detection marker
// (bit23 set causes DMA error on real machine, so
// unlikely to be ever set by the game)
- list[0] |=
0x800000
;
+ list[0] |=
HTOLE32(0x800000)
;
}
}
}
}
@@
-650,8
+672,8
@@
long GPUdmaChain(uint32_t *rambase, uint32_t start_addr)
addr = ld_addr & 0x1fffff;
while (count-- > 0) {
list = rambase + addr / 4;
addr = ld_addr & 0x1fffff;
while (count-- > 0) {
list = rambase + addr / 4;
- addr =
list[0]
& 0x1fffff;
- list[0] &=
~0x800000
;
+ addr =
LE32TOH(list[0])
& 0x1fffff;
+ list[0] &=
HTOLE32(~0x800000)
;
}
}
}
}
@@
-682,8
+704,11
@@
uint32_t GPUreadData(void)
flush_cmd_buffer();
ret = gpu.gp0;
flush_cmd_buffer();
ret = gpu.gp0;
- if (gpu.dma.h)
+ if (gpu.dma.h) {
+ ret = HTOLE32(ret);
do_vram_io(&ret, 1, 1);
do_vram_io(&ret, 1, 1);
+ ret = LE32TOH(ret);
+ }
log_io("gpu_read %08x\n", ret);
return ret;
log_io("gpu_read %08x\n", ret);
return ret;
@@
-696,7
+721,7
@@
uint32_t GPUreadStatus(void)
if (unlikely(gpu.cmd_len > 0))
flush_cmd_buffer();
if (unlikely(gpu.cmd_len > 0))
flush_cmd_buffer();
- ret = gpu.status
.reg
;
+ ret = gpu.status;
log_io("gpu_read_status %08x\n", ret);
return ret;
}
log_io("gpu_read_status %08x\n", ret);
return ret;
}
@@
-722,14
+747,14
@@
long GPUfreeze(uint32_t type, struct GPUFreeze *freeze)
memcpy(freeze->psxVRam, gpu.vram, 1024 * 512 * 2);
memcpy(freeze->ulControl, gpu.regs, sizeof(gpu.regs));
memcpy(freeze->ulControl + 0xe0, gpu.ex_regs, sizeof(gpu.ex_regs));
memcpy(freeze->psxVRam, gpu.vram, 1024 * 512 * 2);
memcpy(freeze->ulControl, gpu.regs, sizeof(gpu.regs));
memcpy(freeze->ulControl + 0xe0, gpu.ex_regs, sizeof(gpu.ex_regs));
- freeze->ulStatus = gpu.status
.reg
;
+ freeze->ulStatus = gpu.status;
break;
case 0: // load
renderer_sync();
memcpy(gpu.vram, freeze->psxVRam, 1024 * 512 * 2);
memcpy(gpu.regs, freeze->ulControl, sizeof(gpu.regs));
memcpy(gpu.ex_regs, freeze->ulControl + 0xe0, sizeof(gpu.ex_regs));
break;
case 0: // load
renderer_sync();
memcpy(gpu.vram, freeze->psxVRam, 1024 * 512 * 2);
memcpy(gpu.regs, freeze->ulControl, sizeof(gpu.regs));
memcpy(gpu.ex_regs, freeze->ulControl + 0xe0, sizeof(gpu.ex_regs));
- gpu.status
.reg
= freeze->ulStatus;
+ gpu.status = freeze->ulStatus;
gpu.cmd_len = 0;
for (i = 8; i > 0; i--) {
gpu.regs[i] ^= 1; // avoid reg change detection
gpu.cmd_len = 0;
for (i = 8; i > 0; i--) {
gpu.regs[i] ^= 1; // avoid reg change detection
@@
-749,7
+774,7
@@
void GPUupdateLace(void)
flush_cmd_buffer();
renderer_flush_queues();
flush_cmd_buffer();
renderer_flush_queues();
- if (gpu.status
.blanking
) {
+ if (gpu.status
& PSX_GPU_STATUS_BLANKING
) {
if (!gpu.state.blanked) {
vout_blank();
gpu.state.blanked = 1;
if (!gpu.state.blanked) {
vout_blank();
gpu.state.blanked = 1;
@@
-781,7
+806,8
@@
void GPUupdateLace(void)
void GPUvBlank(int is_vblank, int lcf)
{
int interlace = gpu.state.allow_interlace
void GPUvBlank(int is_vblank, int lcf)
{
int interlace = gpu.state.allow_interlace
- && gpu.status.interlace && gpu.status.dheight;
+ && (gpu.status & PSX_GPU_STATUS_INTERLACE)
+ && (gpu.status & PSX_GPU_STATUS_DHEIGHT);
// interlace doesn't look nice on progressive displays,
// so we have this "auto" mode here for games that don't read vram
if (gpu.state.allow_interlace == 2
// interlace doesn't look nice on progressive displays,
// so we have this "auto" mode here for games that don't read vram
if (gpu.state.allow_interlace == 2
@@
-805,6
+831,8
@@
void GPUrearmedCallbacks(const struct rearmed_cbs *cbs)
{
gpu.frameskip.set = cbs->frameskip;
gpu.frameskip.advice = &cbs->fskip_advice;
{
gpu.frameskip.set = cbs->frameskip;
gpu.frameskip.advice = &cbs->fskip_advice;
+ gpu.frameskip.force = &cbs->fskip_force;
+ gpu.frameskip.dirty = &cbs->fskip_dirty;
gpu.frameskip.active = 0;
gpu.frameskip.frame_ready = 1;
gpu.state.hcnt = cbs->gpu_hcnt;
gpu.frameskip.active = 0;
gpu.frameskip.frame_ready = 1;
gpu.state.hcnt = cbs->gpu_hcnt;