Several improvements

This commit is contained in:
allkern
2023-07-24 16:37:04 -03:00
parent 2e6491c20b
commit b81987ecac
6 changed files with 232 additions and 66 deletions
+104 -3
View File
@@ -306,8 +306,58 @@ void cdrom_cmd_setmode(psx_cdrom_t* cdrom) {
}
void cdrom_cmd_getlocl(psx_cdrom_t* cdrom) { log_fatal("getlocl: Unimplemented"); exit(1); }
void cdrom_cmd_getlocp(psx_cdrom_t* cdrom) { log_fatal("getlocp: Unimplemented"); exit(1); }
void cdrom_cmd_gettn(psx_cdrom_t* cdrom) { log_fatal("gettn: Unimplemented"); exit(1); }
void cdrom_cmd_gettd(psx_cdrom_t* cdrom) { log_fatal("gettd: Unimplemented"); exit(1); }
void cdrom_cmd_gettn(psx_cdrom_t* cdrom) {
switch (cdrom->state) {
case CD_STATE_CMD: {
if (cdrom->pfifo_index) {
log_fatal("CdlGetTN: Expected exactly 0 parameters");
return;
}
cdrom->irq_delay = DELAY_1MS;
cdrom->delayed_command = CDL_GETTN;
cdrom->state = CD_STATE_RESP1;
} break;
case CD_STATE_RESP1: {
SET_BITS(ifr, IFR_INT, IFR_INT3);
RESP_PUSH(0x14);
RESP_PUSH(0x01);
RESP_PUSH(cdrom->stat);
cdrom->delayed_command = CDL_NONE;
cdrom->state = CD_STATE_CMD;
} break;
}
}
void cdrom_cmd_gettd(psx_cdrom_t* cdrom) {
switch (cdrom->state) {
case CD_STATE_CMD: {
if (cdrom->pfifo_index != 1) {
log_fatal("CdlGetTD: Expected exactly 0 parameters");
return;
}
int track = PFIFO_POP;
cdrom->irq_delay = DELAY_1MS;
cdrom->delayed_command = CDL_GETTD;
cdrom->state = CD_STATE_RESP1;
} break;
case CD_STATE_RESP1: {
SET_BITS(ifr, IFR_INT, IFR_INT3);
RESP_PUSH(0x14);
RESP_PUSH(0x01);
RESP_PUSH(cdrom->stat);
cdrom->delayed_command = CDL_NONE;
cdrom->state = CD_STATE_CMD;
} break;
}
}
void cdrom_cmd_seekl(psx_cdrom_t* cdrom) {
switch (cdrom->state) {
case CD_STATE_CMD: {
@@ -427,7 +477,58 @@ void cdrom_cmd_getid(psx_cdrom_t* cdrom) {
} break;
}
}
void cdrom_cmd_reads(psx_cdrom_t* cdrom) { log_fatal("reads: Unimplemented"); exit(1); }
void cdrom_cmd_reads(psx_cdrom_t* cdrom) {
switch (cdrom->state) {
case CD_STATE_CMD: {
log_fatal("CdlReadS: CD_STATE_CMD");
cdrom->irq_delay = DELAY_1MS;
cdrom->state = CD_STATE_RESP1;
cdrom->delayed_command = CDL_READS;
} break;
case CD_STATE_RESP1: {
log_fatal("CdlReadS: CD_STATE_RESP1");
SET_BITS(ifr, IFR_INT, 3);
RESP_PUSH(GETSTAT_MOTOR);
fseek(cdrom->disc, cdrom->seek_offset, 0);
int double_speed = cdrom->mode & MODE_SPEED;
cdrom->irq_delay = double_speed ? READ_DOUBLE_DELAY : READ_SINGLE_DELAY;
cdrom->state = CD_STATE_RESP2;
cdrom->delayed_command = CDL_READS;
if (cdrom->spin_delay) {
cdrom->irq_delay += cdrom->spin_delay;
cdrom->spin_delay = 0;
}
} break;
case CD_STATE_RESP2: {
log_fatal("CdlReadS: CD_STATE_RESP2");
SET_BITS(ifr, IFR_INT, 1);
RESP_PUSH(GETSTAT_MOTOR | GETSTAT_READ);
log_fatal("Reading data from disc. offset=%02x:%02x:%02x (%08x, tellg=%08x)",
cdrom->seek_mm, cdrom->seek_ss, cdrom->seek_sect,
cdrom->seek_offset, ftell(cdrom->disc)
);
cdrom->dfifo_index = 0;
fread(cdrom->dfifo, 1, CD_SECTOR_SIZE, cdrom->disc);
int double_speed = cdrom->mode & MODE_SPEED;
cdrom->irq_delay = double_speed ? READ_DOUBLE_DELAY : READ_SINGLE_DELAY;
cdrom->state = CD_STATE_CMD;
cdrom->delayed_command = CDL_NONE;
} break;
}
}
void cdrom_cmd_readtoc(psx_cdrom_t* cdrom) { log_fatal("readtoc: Unimplemented"); exit(1); }
typedef void (*cdrom_cmd_t)(psx_cdrom_t*);
+34 -34
View File
@@ -106,8 +106,11 @@ void psx_dma_write32(psx_dma_t* dma, uint32_t offset, uint32_t value) {
dma->dicr &= ~(value & DICR_FLAGS);
// Write other fields
dma->dicr &= DICR_FLAGS;
uint32_t flags = dma->dicr & DICR_FLAGS;
dma->dicr &= ~DICR_FLAGS;
dma->dicr |= value & (~DICR_FLAGS);
dma->dicr |= flags;
} break;
default: {
@@ -122,7 +125,7 @@ void psx_dma_write16(psx_dma_t* dma, uint32_t offset, uint16_t value) {
default: {
log_fatal("Unhandled 16-bit DMA write at offset %08x (%04x)", offset, value);
exit(1);
//exit(1);
} break;
}
}
@@ -132,7 +135,7 @@ void psx_dma_write8(psx_dma_t* dma, uint32_t offset, uint8_t value) {
default: {
log_fatal("Unhandled 8-bit DMA write at offset %08x (%02x)", offset, value);
exit(1);
//exit(1);
} break;
}
}
@@ -152,6 +155,8 @@ void psx_dma_do_gpu_linked(psx_dma_t* dma) {
uint32_t size = hdr >> 24;
uint32_t addr = dma->gpu.madr;
int count = 0;
while (true) {
while (size--) {
addr = (addr + (CHCR_STEP(gpu) ? -4 : 4)) & 0x1ffffc;
@@ -161,6 +166,8 @@ void psx_dma_do_gpu_linked(psx_dma_t* dma) {
// Write to GP0
psx_bus_write32(dma->bus, 0x1f801810, cmd);
dma->gpu_irq_delay++;
}
addr = hdr & 0xffffff;
@@ -195,6 +202,8 @@ void psx_dma_do_gpu_request(psx_dma_t* dma) {
dma->gpu.madr += CHCR_STEP(gpu) ? -4 : 4;
}
}
dma->gpu_irq_delay = size;
}
void psx_dma_do_gpu_burst(psx_dma_t* dma) {
@@ -249,7 +258,7 @@ void psx_dma_do_cdrom(psx_dma_t* dma) {
(dma->dicr >> 24) & 0x7f
);
uint32_t size = BCR_SIZE(cdrom) * BCR_BCNT(cdrom);
uint32_t size = BCR_SIZE(cdrom);
if (!size) {
log_fatal("0 sized CDROM DMA");
@@ -310,23 +319,6 @@ void psx_dma_do_spu(psx_dma_t* dma) {
}
dma->spu_irq_delay = size * 4;
if (!CHCR_TDIR(spu)) {
for (int i = 0; i < size; i++) {
uint32_t data = 0;
data |= psx_bus_read8(dma->bus, 0x1f801802) << 0;
data |= psx_bus_read8(dma->bus, 0x1f801802) << 8;
data |= psx_bus_read8(dma->bus, 0x1f801802) << 16;
data |= psx_bus_read8(dma->bus, 0x1f801802) << 24;
psx_bus_write32(dma->bus, dma->spu.madr, data);
dma->spu.madr += CHCR_STEP(spu) ? -4 : 4;
}
} else {
log_fatal("Invalid SPU DMA transfer direction");
}
// Clear BCR and CHCR trigger and busy bits
dma->spu.chcr = 0;
@@ -358,6 +350,8 @@ void psx_dma_do_otc(psx_dma_t* dma) {
dma->otc.madr -= 4;
}
dma->otc_irq_delay = BCR_SIZE(otc);
// Clear BCR and CHCR trigger and busy bits
dma->otc.chcr = 0;
//dma->otc.chcr &= ~(CHCR_BUSY_MASK | CHCR_TRIG_MASK);
@@ -366,25 +360,31 @@ void psx_dma_do_otc(psx_dma_t* dma) {
void psx_dma_update(psx_dma_t* dma, int cyc) {
if (dma->cdrom_irq_delay) {
dma->cdrom_irq_delay -= cyc;
if (dma->dicr & DICR_DMA3EN)
dma->dicr |= DICR_DMA3FL;
if (dma->cdrom_irq_delay <= 0) {
if (dma->dicr & DICR_DMA3EN)
dma->dicr |= DICR_DMA3FL;
dma->cdrom_irq_delay = 0;
}
dma->cdrom_irq_delay = 0;
}
if (dma->spu_irq_delay) {
dma->spu_irq_delay -= cyc;
if (dma->dicr & DICR_DMA4EN)
dma->dicr |= DICR_DMA4FL;
dma->spu_irq_delay = 0;
}
if (dma->spu_irq_delay <= 0) {
if (dma->dicr & DICR_DMA4EN)
dma->dicr |= DICR_DMA4FL;
if (dma->gpu_irq_delay) {
if (dma->dicr & DICR_DMA2EN)
dma->dicr |= DICR_DMA2FL;
dma->spu_irq_delay = 0;
}
dma->gpu_irq_delay = 0;
}
if (dma->otc_irq_delay) {
if (dma->dicr & DICR_DMA6EN)
dma->dicr |= DICR_DMA6FL;
dma->otc_irq_delay = 0;
}
int prev_irq_signal = (dma->dicr & DICR_IRQSI) != 0;
+2
View File
@@ -32,6 +32,8 @@ typedef struct {
int cdrom_irq_delay;
int spu_irq_delay;
int gpu_irq_delay;
int otc_irq_delay;
uint32_t dpcr;
uint32_t dicr;
+81 -29
View File
@@ -62,6 +62,25 @@ uint32_t psx_gpu_read32(psx_gpu_t* gpu, uint32_t offset) {
gpu->c0_tsiz -= 2;
}
if (gpu->gp1_10h_req) {
switch (gpu->gp1_10h_req & 7) {
case 2: {
data = ((gpu->texw_oy / 8) << 15) | ((gpu->texw_ox / 8) << 10) | ((gpu->texw_my / 8) << 5) | (gpu->texw_mx / 8);
} break;
case 3: {
data = (gpu->draw_y1 << 10) | gpu->draw_x1;
} break;
case 4: {
data = (gpu->draw_y2 << 10) | gpu->draw_x2;
} break;
case 5: {
data = (gpu->off_y << 10) | gpu->off_x;
} break;
}
gpu->gp1_10h_req = 0;
}
return data;
} break;
case 0x04: return gpu->gpustat | 0x1c000000;
@@ -73,23 +92,15 @@ uint32_t psx_gpu_read32(psx_gpu_t* gpu, uint32_t offset) {
}
uint16_t psx_gpu_read16(psx_gpu_t* gpu, uint32_t offset) {
switch (offset) {
case 0x00: return 0xaaaa;
case 0x04: return gpu->gpustat;
}
log_fatal("Unhandled 16-bit GPU read at offset %08x", offset);
log_warn("Unhandled 16-bit GPU read at offset %08x", offset);
return 0x0;
exit(1);
}
uint8_t psx_gpu_read8(psx_gpu_t* gpu, uint32_t offset) {
switch (offset) {
case 0x00: return gpu->gpuread;
case 0x04: return gpu->gpustat;
}
log_fatal("Unhandled 8-bit GPU read at offset %08x", offset);
log_warn("Unhandled 8-bit GPU read at offset %08x", offset);
exit(1);
return 0x0;
}
@@ -445,6 +456,21 @@ void gpu_cmd_a0(psx_gpu_t* gpu) {
gpu->ysiz = ((gpu->ysiz - 1) & 0x1ff) + 1;
gpu->tsiz = ((gpu->xsiz * gpu->ysiz) + 1) & 0xfffffffe;
gpu->addr = gpu->xpos + (gpu->ypos * 1024);
//log_set_quiet(0);
log_fatal("pos=(%u, %u), siz=(%u, %u), tsiz=%08x, addr=%08x",
gpu->xpos, gpu->ypos,
gpu->xsiz, gpu->ysiz,
gpu->tsiz, gpu->addr
);
// system("pause > nul");
// if (gpu->event_cb_table[GPU_EVENT_VBLANK])
// gpu->event_cb_table[GPU_EVENT_VBLANK](gpu);
//log_set_quiet(1);
}
} break;
@@ -815,6 +841,36 @@ void gpu_cmd_02(psx_gpu_t* gpu) {
}
}
void gpu_cmd_80(psx_gpu_t* gpu) {
switch (gpu->state) {
case GPU_STATE_RECV_CMD: {
gpu->state = GPU_STATE_RECV_ARGS;
gpu->cmd_args_remaining = 3;
} break;
case GPU_STATE_RECV_ARGS: {
if (!gpu->cmd_args_remaining) {
gpu->state = GPU_STATE_RECV_DATA;
uint32_t srcx = gpu->buf[1] & 0xffff;
uint32_t srcy = gpu->buf[1] >> 16;
uint32_t dstx = gpu->buf[2] & 0xffff;
uint32_t dsty = gpu->buf[2] >> 16;
uint32_t xsiz = gpu->buf[3] & 0xffff;
uint32_t ysiz = gpu->buf[3] >> 16;
for (int y = 0; y < ysiz; y++) {
for (int x = 0; x < xsiz; x++) {
gpu->vram[(dstx + x) + (dsty + y) * 1024] = gpu->vram[(srcx + x) + (srcy + y) * 1024];
}
}
gpu->state = GPU_STATE_RECV_CMD;
}
} break;
}
}
void psx_gpu_update_cmd(psx_gpu_t* gpu) {
switch (gpu->buf[0] >> 24) {
case 0x00: /* nop */ break;
@@ -833,6 +889,7 @@ void psx_gpu_update_cmd(psx_gpu_t* gpu) {
case 0x65: gpu_cmd_64(gpu); break;
case 0x66: gpu_cmd_64(gpu); break;
case 0x68: gpu_cmd_68(gpu); break;
case 0x80: gpu_cmd_80(gpu); break;
case 0xa0: gpu_cmd_a0(gpu); break;
case 0xc0: gpu_cmd_c0(gpu); break;
case 0xe1: {
@@ -901,6 +958,11 @@ void psx_gpu_write32(psx_gpu_t* gpu, uint32_t offset, uint32_t value) {
uint8_t cmd = value >> 24;
switch (cmd) {
case 0x04: {
// log_set_quiet(0);
// log_fatal("GP1(04h) !!!!!!!!!!!!!!!!!");
// log_set_quiet(1);
} break;
case 0x08:
gpu->display_mode = value & 0xffffff;
@@ -908,23 +970,13 @@ void psx_gpu_write32(psx_gpu_t* gpu, uint32_t offset, uint32_t value) {
gpu->event_cb_table[GPU_EVENT_DMODE](gpu);
break;
case 0x10:
switch (value & 7) {
case 2:
gpu->gpuread = ((gpu->texw_oy / 8) << 15) | ((gpu->texw_ox / 8) << 10) | ((gpu->texw_my / 8) << 5) | (gpu->texw_mx / 8);
break;
case 3:
gpu->gpuread = (gpu->draw_y1 << 10) | gpu->draw_x1;
break;
case 4:
gpu->gpuread = (gpu->draw_y2 << 10) | gpu->draw_x2;
break;
case 5: // Drawing Offset
gpu->gpuread = (gpu->off_y << 10) | gpu->off_x;
break;
default:
break;
}
case 0x10: {
gpu->gp1_10h_req = value & 7;
// log_set_quiet(0);
// log_fatal("GP1(10h) %u !!!!!!!!!!!!!!!!!", value & 7);
// log_set_quiet(1);
} break;
}
log_error("GP1(%02Xh) args=%06x", value >> 24, value & 0xffffff);
+1
View File
@@ -78,6 +78,7 @@ struct psx_gpu_t {
uint32_t c0_addr;
int c0_xsiz, c0_ysiz;
int c0_tsiz;
int gp1_10h_req;
// GPU state
uint32_t state;
+10
View File
@@ -39,12 +39,22 @@ void psxi_sda_write(void* udata, uint16_t data) {
sda->tx_data = 0xff;
sda->state = SDA_STATE_WFR;
}
// Memory card access
if (data == 0x81) {
sda->tx_data_ready = 1;
sda->tx_data = 0xff;
sda->state = SDA_STATE_WFR;
}
} break;
case SDA_STATE_WFR: {
if (data == 'B') {
sda->tx_data = sda->model;
sda->state = SDA_STATE_TX_IDH;
} else if (data == 'R') {
sda->tx_data = 0xff;
sda->state = SDA_STATE_WFR;
}
} break;