NV2A : Copied over all PGRAPH code from XQEMU / OpenXbox. All OpenGL-calls are still disabled.
This commit is contained in:
parent
0ac96332a7
commit
4e07867c47
|
@ -642,6 +642,10 @@ static void nv2a_vblank_thread(NV2AState *d)
|
|||
}
|
||||
}
|
||||
|
||||
// See NV2ABlockInfo regions[] PRAMIN
|
||||
#define NV_PRAMIN_ADDR 0x00700000
|
||||
#define NV_PRAMIN_SIZE 0x100000
|
||||
|
||||
void CxbxReserveNV2AMemory(NV2AState *d)
|
||||
{
|
||||
// Reserve NV2A memory :
|
||||
|
@ -673,7 +677,7 @@ void CxbxReserveNV2AMemory(NV2AState *d)
|
|||
}
|
||||
|
||||
printf("[0x%.4X] INIT: Allocated %d MiB of Xbox NV2A PRAMIN memory at 0x%.8X to 0x%.8X\n",
|
||||
GetCurrentThreadId(), NV_PRAMIN_SIZE / ONE_MB, NV2A_ADDR + NV_PRAMIN_ADDR, NV2A_ADDR + NV_PRAMIN_ADDR + NV_PRAMIN_SIZE - 1);
|
||||
GetCurrentThreadId(), d->pramin.ramin_size / ONE_MB, d->pramin.ramin_ptr, d->pramin.ramin_ptr + d->pramin.ramin_size - 1);
|
||||
}
|
||||
|
||||
void EmuNV2A_Init()
|
||||
|
@ -682,6 +686,7 @@ void EmuNV2A_Init()
|
|||
|
||||
d->pcrtc.start = 0;
|
||||
|
||||
d->vram_ptr = (uint8_t*)MM_SYSTEM_PHYSICAL_MAP;
|
||||
d->vram_size = (g_bIsChihiro || g_bIsDebug) ? CONTIGUOUS_MEMORY_CHIHIRO_SIZE : CONTIGUOUS_MEMORY_XBOX_SIZE;
|
||||
|
||||
d->pramdac.core_clock_coeff = 0x00011c01; /* 189MHz...? */
|
||||
|
|
|
@ -36,13 +36,13 @@ DEVICE_READ32(PFIFO)
|
|||
SET_MASK(result, NV_PFIFO_CACHE1_PUSH1_CHID, d->pfifo.cache1.channel_id);
|
||||
SET_MASK(result, NV_PFIFO_CACHE1_PUSH1_MODE, d->pfifo.cache1.mode);
|
||||
break;
|
||||
case NV_PFIFO_CACHE1_STATUS: {
|
||||
case NV_PFIFO_CACHE1_STATUS:
|
||||
d->pfifo.cache1.cache_lock.lock();
|
||||
if (d->pfifo.cache1.cache.empty()) {
|
||||
result |= NV_PFIFO_CACHE1_STATUS_LOW_MARK; /* low mark empty */
|
||||
}
|
||||
d->pfifo.cache1.cache_lock.unlock();
|
||||
} break;
|
||||
break;
|
||||
case NV_PFIFO_CACHE1_DMA_PUSH:
|
||||
SET_MASK(result, NV_PFIFO_CACHE1_DMA_PUSH_ACCESS,
|
||||
d->pfifo.cache1.dma_push_enabled);
|
||||
|
@ -76,18 +76,18 @@ DEVICE_READ32(PFIFO)
|
|||
result = d->pfifo.cache1.subroutine_return
|
||||
| d->pfifo.cache1.subroutine_active;
|
||||
break;
|
||||
case NV_PFIFO_CACHE1_PULL0: {
|
||||
case NV_PFIFO_CACHE1_PULL0:
|
||||
d->pfifo.cache1.cache_lock.lock();
|
||||
result = d->pfifo.cache1.pull_enabled;
|
||||
d->pfifo.cache1.cache_lock.unlock();
|
||||
} break;
|
||||
case NV_PFIFO_CACHE1_ENGINE: {
|
||||
break;
|
||||
case NV_PFIFO_CACHE1_ENGINE:
|
||||
d->pfifo.cache1.cache_lock.lock();
|
||||
for (int i = 0; i < NV2A_NUM_SUBCHANNELS; i++) {
|
||||
result |= d->pfifo.cache1.bound_engines[i] << (i * 2);
|
||||
}
|
||||
d->pfifo.cache1.cache_lock.unlock();
|
||||
} break;
|
||||
break;
|
||||
case NV_PFIFO_CACHE1_DMA_DCOUNT:
|
||||
result = d->pfifo.cache1.dcount;
|
||||
break;
|
||||
|
@ -110,6 +110,8 @@ DEVICE_READ32(PFIFO)
|
|||
|
||||
DEVICE_WRITE32(PFIFO)
|
||||
{
|
||||
int i;
|
||||
|
||||
switch(addr) {
|
||||
case NV_PFIFO_INTR_0:
|
||||
d->pfifo.pending_interrupts &= ~value;
|
||||
|
@ -128,22 +130,31 @@ DEVICE_WRITE32(PFIFO)
|
|||
assert(d->pfifo.cache1.channel_id < NV2A_NUM_CHANNELS);
|
||||
break;
|
||||
case NV_PFIFO_CACHE1_DMA_PUSH:
|
||||
d->pfifo.cache1.dma_push_enabled = GET_MASK(value, NV_PFIFO_CACHE1_DMA_PUSH_ACCESS);
|
||||
if (d->pfifo.cache1.dma_push_suspended && !GET_MASK(value, NV_PFIFO_CACHE1_DMA_PUSH_STATUS)) {
|
||||
d->pfifo.cache1.dma_push_enabled =
|
||||
GET_MASK(value, NV_PFIFO_CACHE1_DMA_PUSH_ACCESS);
|
||||
if (d->pfifo.cache1.dma_push_suspended
|
||||
&& !GET_MASK(value, NV_PFIFO_CACHE1_DMA_PUSH_STATUS)) {
|
||||
d->pfifo.cache1.dma_push_suspended = false;
|
||||
pfifo_run_pusher(d);
|
||||
}
|
||||
d->pfifo.cache1.dma_push_suspended = GET_MASK(value, NV_PFIFO_CACHE1_DMA_PUSH_STATUS);
|
||||
d->pfifo.cache1.dma_push_suspended =
|
||||
GET_MASK(value, NV_PFIFO_CACHE1_DMA_PUSH_STATUS);
|
||||
break;
|
||||
case NV_PFIFO_CACHE1_DMA_STATE:
|
||||
d->pfifo.cache1.method_nonincreasing = GET_MASK(value, NV_PFIFO_CACHE1_DMA_STATE_METHOD_TYPE);
|
||||
d->pfifo.cache1.method = GET_MASK(value, NV_PFIFO_CACHE1_DMA_STATE_METHOD) << 2;
|
||||
d->pfifo.cache1.subchannel = GET_MASK(value, NV_PFIFO_CACHE1_DMA_STATE_SUBCHANNEL);
|
||||
d->pfifo.cache1.method_count = GET_MASK(value, NV_PFIFO_CACHE1_DMA_STATE_METHOD_COUNT);
|
||||
d->pfifo.cache1.error = GET_MASK(value, NV_PFIFO_CACHE1_DMA_STATE_ERROR);
|
||||
d->pfifo.cache1.method_nonincreasing =
|
||||
GET_MASK(value, NV_PFIFO_CACHE1_DMA_STATE_METHOD_TYPE);
|
||||
d->pfifo.cache1.method =
|
||||
GET_MASK(value, NV_PFIFO_CACHE1_DMA_STATE_METHOD) << 2;
|
||||
d->pfifo.cache1.subchannel =
|
||||
GET_MASK(value, NV_PFIFO_CACHE1_DMA_STATE_SUBCHANNEL);
|
||||
d->pfifo.cache1.method_count =
|
||||
GET_MASK(value, NV_PFIFO_CACHE1_DMA_STATE_METHOD_COUNT);
|
||||
d->pfifo.cache1.error =
|
||||
GET_MASK(value, NV_PFIFO_CACHE1_DMA_STATE_ERROR);
|
||||
break;
|
||||
case NV_PFIFO_CACHE1_DMA_INSTANCE:
|
||||
d->pfifo.cache1.dma_instance = GET_MASK(value, NV_PFIFO_CACHE1_DMA_INSTANCE_ADDRESS_MASK) << 4;
|
||||
d->pfifo.cache1.dma_instance =
|
||||
GET_MASK(value, NV_PFIFO_CACHE1_DMA_INSTANCE_ADDRESS_MASK) << 4;
|
||||
break;
|
||||
case NV_PFIFO_CACHE1_DMA_PUT:
|
||||
d->user.channel_control[d->pfifo.cache1.channel_id].dma_put = value;
|
||||
|
@ -152,12 +163,13 @@ DEVICE_WRITE32(PFIFO)
|
|||
d->user.channel_control[d->pfifo.cache1.channel_id].dma_get = value;
|
||||
break;
|
||||
case NV_PFIFO_CACHE1_DMA_SUBROUTINE:
|
||||
d->pfifo.cache1.subroutine_return = (value & NV_PFIFO_CACHE1_DMA_SUBROUTINE_RETURN_OFFSET);
|
||||
d->pfifo.cache1.subroutine_active = (value & NV_PFIFO_CACHE1_DMA_SUBROUTINE_STATE);
|
||||
d->pfifo.cache1.subroutine_return =
|
||||
(value & NV_PFIFO_CACHE1_DMA_SUBROUTINE_RETURN_OFFSET);
|
||||
d->pfifo.cache1.subroutine_active =
|
||||
(value & NV_PFIFO_CACHE1_DMA_SUBROUTINE_STATE);
|
||||
break;
|
||||
case NV_PFIFO_CACHE1_PULL0: {
|
||||
case NV_PFIFO_CACHE1_PULL0:
|
||||
d->pfifo.cache1.cache_lock.lock();
|
||||
|
||||
if ((value & NV_PFIFO_CACHE1_PULL0_ACCESS)
|
||||
&& !d->pfifo.cache1.pull_enabled) {
|
||||
d->pfifo.cache1.pull_enabled = true;
|
||||
|
@ -169,19 +181,21 @@ DEVICE_WRITE32(PFIFO)
|
|||
d->pfifo.cache1.pull_enabled = false;
|
||||
}
|
||||
d->pfifo.cache1.cache_lock.unlock();
|
||||
} break;
|
||||
case NV_PFIFO_CACHE1_ENGINE: {
|
||||
break;
|
||||
case NV_PFIFO_CACHE1_ENGINE:
|
||||
d->pfifo.cache1.cache_lock.lock();
|
||||
for (int i = 0; i < NV2A_NUM_SUBCHANNELS; i++) {
|
||||
for (i=0; i < NV2A_NUM_SUBCHANNELS; i++) {
|
||||
d->pfifo.cache1.bound_engines[i] = (FIFOEngine)((value >> (i * 2)) & 3);
|
||||
}
|
||||
d->pfifo.cache1.cache_lock.unlock();
|
||||
} break;
|
||||
break;
|
||||
case NV_PFIFO_CACHE1_DMA_DCOUNT:
|
||||
d->pfifo.cache1.dcount = (value & NV_PFIFO_CACHE1_DMA_DCOUNT_VALUE);
|
||||
d->pfifo.cache1.dcount =
|
||||
(value & NV_PFIFO_CACHE1_DMA_DCOUNT_VALUE);
|
||||
break;
|
||||
case NV_PFIFO_CACHE1_DMA_GET_JMP_SHADOW:
|
||||
d->pfifo.cache1.get_jmp_shadow = (value & NV_PFIFO_CACHE1_DMA_GET_JMP_SHADOW_OFFSET);
|
||||
d->pfifo.cache1.get_jmp_shadow =
|
||||
(value & NV_PFIFO_CACHE1_DMA_GET_JMP_SHADOW_OFFSET);
|
||||
break;
|
||||
case NV_PFIFO_CACHE1_DMA_RSVD_SHADOW:
|
||||
d->pfifo.cache1.rsvd_shadow = value;
|
||||
|
@ -197,6 +211,7 @@ DEVICE_WRITE32(PFIFO)
|
|||
DEVICE_WRITE32_END(PFIFO);
|
||||
}
|
||||
|
||||
|
||||
/* pusher should be fine to run from a mimo handler
|
||||
* whenever's it's convenient */
|
||||
static void pfifo_run_pusher(NV2AState *d) {
|
||||
|
@ -215,6 +230,7 @@ static void pfifo_run_pusher(NV2AState *d) {
|
|||
|
||||
if (!state->push_enabled) return;
|
||||
|
||||
|
||||
/* only handling DMA for now... */
|
||||
|
||||
/* Channel running DMA */
|
||||
|
@ -230,12 +246,13 @@ static void pfifo_run_pusher(NV2AState *d) {
|
|||
|
||||
dma = (uint8_t*)nv_dma_map(d, state->dma_instance, &dma_len);
|
||||
|
||||
printf("DMA pusher: max 0x%08X, 0x%08X - 0x%08X\n",
|
||||
NV2A_DPRINTF("DMA pusher: max 0x%08X, 0x%08X - 0x%08X\n",
|
||||
dma_len, control->dma_get, control->dma_put);
|
||||
|
||||
/* based on the convenient pseudocode in envytools */
|
||||
while (control->dma_get != control->dma_put) {
|
||||
if (control->dma_get >= dma_len) {
|
||||
|
||||
state->error = NV_PFIFO_CACHE1_DMA_STATE_ERROR_PROTECTION;
|
||||
break;
|
||||
}
|
||||
|
@ -247,7 +264,7 @@ static void pfifo_run_pusher(NV2AState *d) {
|
|||
/* data word of methods command */
|
||||
state->data_shadow = word;
|
||||
|
||||
command = (CacheEntry*)calloc(1, sizeof(CacheEntry));
|
||||
command = (CacheEntry*)malloc(sizeof(CacheEntry));
|
||||
command->method = state->method;
|
||||
command->subchannel = state->subchannel;
|
||||
command->nonincreasing = state->method_nonincreasing;
|
||||
|
@ -271,15 +288,13 @@ static void pfifo_run_pusher(NV2AState *d) {
|
|||
/* old jump */
|
||||
state->get_jmp_shadow = control->dma_get;
|
||||
control->dma_get = word & 0x1fffffff;
|
||||
printf("pb OLD_JMP 0x%08X\n", control->dma_get);
|
||||
}
|
||||
else if ((word & 3) == 1) {
|
||||
NV2A_DPRINTF("pb OLD_JMP 0x%08X\n", control->dma_get);
|
||||
} else if ((word & 3) == 1) {
|
||||
/* jump */
|
||||
state->get_jmp_shadow = control->dma_get;
|
||||
control->dma_get = word & 0xfffffffc;
|
||||
printf("pb JMP 0x%08X\n", control->dma_get);
|
||||
}
|
||||
else if ((word & 3) == 2) {
|
||||
NV2A_DPRINTF("pb JMP 0x%08X\n", control->dma_get);
|
||||
} else if ((word & 3) == 2) {
|
||||
/* call */
|
||||
if (state->subroutine_active) {
|
||||
state->error = NV_PFIFO_CACHE1_DMA_STATE_ERROR_CALL;
|
||||
|
@ -288,9 +303,8 @@ static void pfifo_run_pusher(NV2AState *d) {
|
|||
state->subroutine_return = control->dma_get;
|
||||
state->subroutine_active = true;
|
||||
control->dma_get = word & 0xfffffffc;
|
||||
printf("pb CALL 0x%08X\n", control->dma_get);
|
||||
}
|
||||
else if (word == 0x00020000) {
|
||||
NV2A_DPRINTF("pb CALL 0x%08X\n", control->dma_get);
|
||||
} else if (word == 0x00020000) {
|
||||
/* return */
|
||||
if (!state->subroutine_active) {
|
||||
state->error = NV_PFIFO_CACHE1_DMA_STATE_ERROR_RETURN;
|
||||
|
@ -298,9 +312,8 @@ static void pfifo_run_pusher(NV2AState *d) {
|
|||
}
|
||||
control->dma_get = state->subroutine_return;
|
||||
state->subroutine_active = false;
|
||||
printf("pb RET 0x%08X\n", control->dma_get);
|
||||
}
|
||||
else if ((word & 0xe0030003) == 0) {
|
||||
NV2A_DPRINTF("pb RET 0x%08X\n", control->dma_get);
|
||||
} else if ((word & 0xe0030003) == 0) {
|
||||
/* increasing methods */
|
||||
state->method = word & 0x1fff;
|
||||
state->subchannel = (word >> 13) & 7;
|
||||
|
@ -315,9 +328,8 @@ static void pfifo_run_pusher(NV2AState *d) {
|
|||
state->method_count = (word >> 18) & 0x7ff;
|
||||
state->method_nonincreasing = true;
|
||||
state->dcount = 0;
|
||||
}
|
||||
else {
|
||||
printf("pb reserved cmd 0x%08X - 0x%08X\n",
|
||||
} else {
|
||||
NV2A_DPRINTF("pb reserved cmd 0x%08X - 0x%08X\n",
|
||||
control->dma_get, word);
|
||||
state->error = NV_PFIFO_CACHE1_DMA_STATE_ERROR_RESERVED_CMD;
|
||||
break;
|
||||
|
@ -325,11 +337,11 @@ static void pfifo_run_pusher(NV2AState *d) {
|
|||
}
|
||||
}
|
||||
|
||||
printf("DMA pusher done: max 0x%08X, 0x%08X - 0x%08X\n",
|
||||
NV2A_DPRINTF("DMA pusher done: max 0x%08X, 0x%08X - 0x%08X\n",
|
||||
dma_len, control->dma_get, control->dma_put);
|
||||
|
||||
if (state->error) {
|
||||
printf("pb error: %d\n", state->error);
|
||||
NV2A_DPRINTF("pb error: %d\n", state->error);
|
||||
assert(false);
|
||||
|
||||
state->dma_push_suspended = true;
|
||||
|
@ -345,6 +357,8 @@ int pfifo_puller_thread(NV2AState *d)
|
|||
|
||||
Cache1State *state = &d->pfifo.cache1;
|
||||
|
||||
// glo_set_current(d->pgraph.gl_context);
|
||||
|
||||
while (true) {
|
||||
state->cache_lock.lock();
|
||||
while (state->cache.empty() || !state->pull_enabled) {
|
||||
|
@ -411,7 +425,8 @@ int pfifo_puller_thread(NV2AState *d)
|
|||
switch (engine) {
|
||||
case ENGINE_GRAPHICS:
|
||||
pgraph_wait_fifo_access(d);
|
||||
pgraph_method(d, command->subchannel, command->method, parameter);
|
||||
pgraph_method(d, command->subchannel,
|
||||
command->method, parameter);
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
|
@ -425,17 +440,17 @@ int pfifo_puller_thread(NV2AState *d)
|
|||
|
||||
free(command);
|
||||
}
|
||||
}
|
||||
|
||||
d->pgraph.lock.unlock();
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t ramht_hash(NV2AState *d, uint32_t handle)
|
||||
{
|
||||
unsigned int ramht_size = 1 << (GET_MASK(d->pfifo.regs[NV_PFIFO_RAMHT], NV_PFIFO_RAMHT_SIZE_MASK) + 12);
|
||||
unsigned int ramht_size =
|
||||
1 << (GET_MASK(d->pfifo.regs[NV_PFIFO_RAMHT], NV_PFIFO_RAMHT_SIZE_MASK) + 12);
|
||||
|
||||
/* XXX: Think this is different to what nouveau calculates... */
|
||||
unsigned int bits = ffs(ramht_size) - 2;
|
||||
|
@ -452,7 +467,8 @@ static uint32_t ramht_hash(NV2AState *d, uint32_t handle)
|
|||
|
||||
static RAMHTEntry ramht_lookup(NV2AState *d, uint32_t handle)
|
||||
{
|
||||
unsigned int ramht_size = 1 << (GET_MASK(d->pfifo.regs[NV_PFIFO_RAMHT], NV_PFIFO_RAMHT_SIZE_MASK) + 12);
|
||||
unsigned int ramht_size =
|
||||
1 << (GET_MASK(d->pfifo.regs[NV_PFIFO_RAMHT], NV_PFIFO_RAMHT_SIZE_MASK) + 12);
|
||||
|
||||
uint32_t hash = ramht_hash(d, handle);
|
||||
assert(hash * 8 < ramht_size);
|
||||
|
@ -475,4 +491,3 @@ static RAMHTEntry ramht_lookup(NV2AState *d, uint32_t handle)
|
|||
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -44,8 +44,7 @@ DEVICE_WRITE32(PRAMDAC)
|
|||
|
||||
if (m == 0) {
|
||||
d->pramdac.core_clock_freq = 0;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
d->pramdac.core_clock_freq = (NV2A_CRYSTAL_FREQ * n)
|
||||
/ (1 << p) / m;
|
||||
}
|
||||
|
|
|
@ -1,21 +1,13 @@
|
|||
DEVICE_READ32(PRAMIN)
|
||||
{
|
||||
DEVICE_READ32_SWITCH() {
|
||||
default:
|
||||
DEVICE_READ32_REG(pramin);
|
||||
break;
|
||||
}
|
||||
uint32_t result = *((uint32_t*)(d->pramin.ramin_ptr + addr));
|
||||
|
||||
DEVICE_READ32_END(PRAMIN);
|
||||
}
|
||||
|
||||
DEVICE_WRITE32(PRAMIN)
|
||||
{
|
||||
switch (addr) {
|
||||
default:
|
||||
DEVICE_WRITE32_REG(pramin);
|
||||
break;
|
||||
}
|
||||
*((uint32_t*)(d->pramin.ramin_ptr + addr)) = value;
|
||||
|
||||
DEVICE_WRITE32_END(PRAMIN);
|
||||
}
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
/*
|
||||
static void pvideo_vga_invalidate(NV2AState *d)
|
||||
{
|
||||
int y1 = GET_MASK(d->pvideo.regs[NV_PVIDEO_POINT_OUT],
|
||||
int y1 = GET_MASK(d->pvideo.regs[NV_PVIDEO_POINT_OUT(0)],
|
||||
NV_PVIDEO_POINT_OUT_Y);
|
||||
int y2 = y1 + GET_MASK(d->pvideo.regs[NV_PVIDEO_SIZE_OUT],
|
||||
int y2 = y1 + GET_MASK(d->pvideo.regs[NV_PVIDEO_SIZE_OUT(0)],
|
||||
NV_PVIDEO_SIZE_OUT_HEIGHT);
|
||||
NV2A_DPRINTF("pvideo_vga_invalidate %d %d\n", y1, y2);
|
||||
vga_invalidate_scanlines(&d->vga, y1, y2);
|
||||
// TODO : vga_invalidate_scanlines(&d->vga, y1, y2);
|
||||
}
|
||||
|
||||
*/
|
||||
DEVICE_READ32(PVIDEO)
|
||||
{
|
||||
DEVICE_READ32_SWITCH() {
|
||||
|
@ -30,13 +28,13 @@ DEVICE_WRITE32(PVIDEO)
|
|||
switch (addr) {
|
||||
case NV_PVIDEO_BUFFER:
|
||||
d->pvideo.regs[addr] = value;
|
||||
// TODO: vga.enable_overlay = true;
|
||||
// pvideo_vga_invalidate(d);
|
||||
// TODO : d->vga.enable_overlay = true;
|
||||
pvideo_vga_invalidate(d);
|
||||
break;
|
||||
case NV_PVIDEO_STOP:
|
||||
d->pvideo.regs[NV_PVIDEO_BUFFER] = 0;
|
||||
// TODO: vga.enable_overlay = false;
|
||||
//pvideo_vga_invalidate(d);
|
||||
// TODO : d->vga.enable_overlay = false;
|
||||
pvideo_vga_invalidate(d);
|
||||
break;
|
||||
default:
|
||||
DEVICE_WRITE32_REG(pvideo);
|
||||
|
|
|
@ -60,8 +60,7 @@ DEVICE_WRITE32(USER)
|
|||
DEBUG_WRITE32_UNHANDLED(USER);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
/* PIO Mode */
|
||||
assert(false);
|
||||
}
|
||||
|
|
|
@ -57,12 +57,13 @@
|
|||
#define NV_PGRAPH_SIZE 0x002000
|
||||
#define NV_PCRTC_SIZE 0x001000
|
||||
#define NV_PRAMDAC_SIZE 0x001000
|
||||
#define NV_PRAMIN_ADDR 0x00700000
|
||||
#define NV_PRAMIN_SIZE 0x100000
|
||||
|
||||
typedef xbaddr hwaddr; // Compatibility; Cxbx uses xbaddr, xqemu and OpenXbox use hwaddr
|
||||
typedef uint32_t value_t; // Compatibility; Cxbx values are uint32_t (xqemu and OpenXbox use uint64_t)
|
||||
|
||||
#define NV2A_DPRINTF printf // Compatibility; TODO : Replace this by something equivalent
|
||||
#define NV2A_GL_DPRINTF EmuWarning // Compatibility; TODO : Replace this by something equivalent
|
||||
#define VSH_TOKEN_SIZE 4 // Compatibility; TODO : Move this to nv2a_vsh.h
|
||||
//#define MAX(a,b) ((a)>(b) ? (a) : (b)) // Compatibility
|
||||
|
||||
#define USE_TEXTURE_CACHE
|
||||
|
||||
|
@ -123,12 +124,27 @@ inline int SET_MASK(int v, int mask, int val) {
|
|||
return (v) |= ((__val) << (ffs(__mask)-1)) & (__mask);
|
||||
}
|
||||
|
||||
#define CASE_4(v, step) \
|
||||
case (v): \
|
||||
case (v)+(step) : \
|
||||
case (v)+(step) * 2: \
|
||||
case (v)+(step) * 3
|
||||
// Power-of-two CASE statements
|
||||
#define CASE_1(v, step) case (v)
|
||||
#define CASE_2(v, step) CASE_1(v, step) : CASE_1(v + (step) * 1, step)
|
||||
#define CASE_4(v, step) CASE_2(v, step) : CASE_2(v + (step) * 2, step)
|
||||
#define CASE_8(v, step) CASE_4(v, step) : CASE_4(v + (step) * 4, step)
|
||||
#define CASE_16(v, step) CASE_8(v, step) : CASE_8(v + (step) * 8, step)
|
||||
#define CASE_32(v, step) CASE_16(v, step) : CASE_16(v + (step) * 16, step)
|
||||
#define CASE_64(v, step) CASE_32(v, step) : CASE_32(v + (step) * 32, step)
|
||||
#define CASE_128(v, step) CASE_64(v, step) : CASE_64(v + (step) * 64, step)
|
||||
|
||||
// Non-power-of-two CASE statements
|
||||
#define CASE_3(v, step) CASE_2(v, step) : CASE_1(v + (step) * 2, step)
|
||||
#define CASE_12(v, step) CASE_8(v, step) : CASE_4(v + (step) * 8, step)
|
||||
#define CASE_13(v, step) CASE_8(v, step) : CASE_3(v + (step) * 8, step)
|
||||
#define CASE_28(v, step) CASE_16(v, step) : CASE_12(v + (step) * 16, step)
|
||||
#define CASE_29(v, step) CASE_16(v, step) : CASE_13(v + (step) * 16, step)
|
||||
#define CASE_61(v, step) CASE_32(v, step) : CASE_29(v + (step) * 32, step)
|
||||
#define CASE_78(v, step) CASE_64(v, step) : CASE_12(v + (step) * 64, step)
|
||||
#define CASE_125(v, step) CASE_64(v, step) : CASE_61(v + (step) * 64, step)
|
||||
#define CASE_132(v, step) CASE_128(v, step) : CASE_4(v + (step) * 128, step)
|
||||
#define CASE_253(v, step) CASE_128(v, step) : CASE_125(v + (step) * 128, step)
|
||||
|
||||
#define NV2A_DEVICE(obj) \
|
||||
OBJECT_CHECK(NV2AState, (obj), "nv2a")
|
||||
|
@ -339,7 +355,7 @@ typedef struct PGRAPHState {
|
|||
|
||||
bool enable_vertex_program_write;
|
||||
|
||||
//uint32_t program_data[NV2A_MAX_TRANSFORM_PROGRAM_LENGTH][VSH_TOKEN_SIZE];
|
||||
uint32_t program_data[NV2A_MAX_TRANSFORM_PROGRAM_LENGTH][VSH_TOKEN_SIZE];
|
||||
|
||||
uint32_t vsh_constants[NV2A_VERTEXSHADER_CONSTANTS][4];
|
||||
bool vsh_constants_dirty[NV2A_VERTEXSHADER_CONSTANTS];
|
||||
|
@ -449,7 +465,6 @@ typedef struct NV2AState {
|
|||
struct {
|
||||
uint8_t *ramin_ptr;
|
||||
size_t ramin_size;
|
||||
uint32_t regs[NV_PRAMIN_SIZE]; // TODO : union
|
||||
} pramin;
|
||||
|
||||
// MemoryRegion mmio;
|
||||
|
@ -458,7 +473,7 @@ typedef struct NV2AState {
|
|||
struct {
|
||||
uint32_t pending_interrupts;
|
||||
uint32_t enabled_interrupts;
|
||||
uint32_t regs[NV_PMC_SIZE]; // TODO : union
|
||||
uint32_t regs[NV_PMC_SIZE]; // Not in xqemu/openxbox? TODO : union
|
||||
} pmc;
|
||||
|
||||
struct {
|
||||
|
@ -479,7 +494,7 @@ typedef struct NV2AState {
|
|||
uint32_t numerator;
|
||||
uint32_t denominator;
|
||||
uint32_t alarm_time;
|
||||
uint32_t regs[NV_PTIMER_SIZE]; // TODO : union
|
||||
uint32_t regs[NV_PTIMER_SIZE]; // Not in xqemu/openxbox? TODO : union
|
||||
} ptimer;
|
||||
|
||||
struct {
|
||||
|
@ -492,7 +507,7 @@ typedef struct NV2AState {
|
|||
uint32_t pending_interrupts;
|
||||
uint32_t enabled_interrupts;
|
||||
hwaddr start;
|
||||
uint32_t regs[NV_PCRTC_SIZE]; // TODO : union
|
||||
uint32_t regs[NV_PCRTC_SIZE]; // Not in xqemu/openxbox? TODO : union
|
||||
} pcrtc;
|
||||
|
||||
struct {
|
||||
|
@ -500,7 +515,7 @@ typedef struct NV2AState {
|
|||
uint64_t core_clock_freq;
|
||||
uint32_t memory_clock_coeff;
|
||||
uint32_t video_clock_coeff;
|
||||
uint32_t regs[NV_PRAMDAC_SIZE]; // TODO : union
|
||||
uint32_t regs[NV_PRAMDAC_SIZE]; // Not in xqemu/openxbox? TODO : union
|
||||
} pramdac;
|
||||
|
||||
struct {
|
||||
|
@ -511,9 +526,9 @@ typedef struct NV2AState {
|
|||
struct {
|
||||
uint8_t cr_index;
|
||||
uint8_t cr[256]; /* CRT registers */
|
||||
} prmcio;
|
||||
} prmcio; // Not in xqemu/openxbox?
|
||||
|
||||
std::mutex io_lock;
|
||||
std::mutex io_lock; // TODO ? std::unique_lock<std::mutex>
|
||||
//SDL_Window *sdl_window;
|
||||
|
||||
} NV2AState;
|
||||
|
|
Loading…
Reference in New Issue