ref: 32088d682e8b0f1005d012c3313054b852df87c9
parent: 0670e53ade035499045de505dc80f48aca2a3ef4
author: allkern <lisandroaalarcon@gmail.com>
date: Fri Sep 15 14:33:39 EDT 2023
Several fixes RAM mirroring implemented DMA IRQ signal fix
--- a/frontend/main.c
+++ b/frontend/main.c
@@ -25,7 +25,7 @@
psxe_screen_t* screen = psxe_screen_create();
psxe_screen_init(screen, psx);
- psxe_screen_set_scale(screen, 2);
+ psxe_screen_set_scale(screen, 3);
psxe_screen_reload(screen);
psx_gpu_t* gpu = psx_get_gpu(psx);
--- a/psx/bus.c
+++ b/psx/bus.c
@@ -24,11 +24,11 @@
}
#define HANDLE_READ(dev, bits) \
- if (RANGE(addr, bus->dev->io_base, bus->dev->io_base + bus->dev->io_size)) \
+ if (RANGE(addr, bus->dev->io_base, (bus->dev->io_base + bus->dev->io_size))) \
return psx_ ## dev ## _read ## bits (bus->dev, addr - bus->dev->io_base);
#define HANDLE_WRITE(dev, bits) \
- if (RANGE(addr, bus->dev->io_base, bus->dev->io_base + bus->dev->io_size)) { \+ if (RANGE(addr, bus->dev->io_base, (bus->dev->io_base + bus->dev->io_size))) { \psx_ ## dev ## _write ## bits (bus->dev, addr - bus->dev->io_base, value); \
return; \
}
@@ -41,7 +41,7 @@
addr &= g_psx_bus_region_mask_table[addr >> 29];
if (addr & 0x3) {- log_warn("Unaligned 32-bit read from %08x:%08x", vaddr, addr);+ log_fatal("Unaligned 32-bit read from %08x:%08x", vaddr, addr);}
HANDLE_READ(bios, 32);
@@ -60,8 +60,10 @@
HANDLE_READ(pad, 32);
HANDLE_READ(mdec, 32);
- log_warn("Unhandled 32-bit read from %08x:%08x", vaddr, addr);+ log_fatal("Unhandled 32-bit read from %08x:%08x", vaddr, addr);+ exit(1);
+
return 0x00000000;
}
@@ -73,7 +75,7 @@
addr &= g_psx_bus_region_mask_table[addr >> 29];
if (addr & 0x1) {- log_warn("Unaligned 16-bit read from %08x:%08x", vaddr, addr);+ log_fatal("Unaligned 16-bit read from %08x:%08x", vaddr, addr);}
HANDLE_READ(bios, 16);
@@ -92,8 +94,10 @@
HANDLE_READ(pad, 16);
HANDLE_READ(mdec, 16);
- log_warn("Unhandled 16-bit read from %08x:%08x", vaddr, addr);+ log_fatal("Unhandled 16-bit read from %08x:%08x", vaddr, addr);+ exit(1);
+
return 0x0000;
}
@@ -120,8 +124,10 @@
HANDLE_READ(pad, 8);
HANDLE_READ(mdec, 8);
- log_warn("Unhandled 8-bit read from %08x:%08x", vaddr, addr);+ log_fatal("Unhandled 8-bit read from %08x:%08x", vaddr, addr);+ //exit(1);
+
return 0x00;
}
@@ -133,7 +139,7 @@
addr &= g_psx_bus_region_mask_table[addr >> 29];
if (addr & 0x3) {- log_warn("Unaligned 32-bit write to %08x:%08x (%08x)", vaddr, addr, value);+ log_fatal("Unaligned 32-bit write to %08x:%08x (%08x)", vaddr, addr, value);}
HANDLE_WRITE(bios, 32);
@@ -152,7 +158,9 @@
HANDLE_WRITE(pad, 32);
HANDLE_WRITE(mdec, 32);
- log_warn("Unhandled 32-bit write to %08x:%08x (%08x)", vaddr, addr, value);+ log_fatal("Unhandled 32-bit write to %08x:%08x (%08x)", vaddr, addr, value);+
+ exit(1);
}
void psx_bus_write16(psx_bus_t* bus, uint32_t addr, uint16_t value) {@@ -163,7 +171,7 @@
addr &= g_psx_bus_region_mask_table[addr >> 29];
if (addr & 0x1) {- log_warn("Unaligned 16-bit write to %08x:%08x (%04x)", vaddr, addr, value);+ log_fatal("Unaligned 16-bit write to %08x:%08x (%04x)", vaddr, addr, value);}
HANDLE_WRITE(bios, 16);
@@ -182,7 +190,9 @@
HANDLE_WRITE(pad, 16);
HANDLE_WRITE(mdec, 16);
- log_warn("Unhandled 16-bit write to %08x:%08x (%04x)", vaddr, addr, value);+ log_fatal("Unhandled 16-bit write to %08x:%08x (%04x)", vaddr, addr, value);+
+ //exit(1);
}
void psx_bus_write8(psx_bus_t* bus, uint32_t addr, uint8_t value) {@@ -208,7 +218,9 @@
HANDLE_WRITE(pad, 8);
HANDLE_WRITE(mdec, 8);
- log_warn("Unhandled 8-bit write to %08x:%08x (%02x)", vaddr, addr, value);+ log_fatal("Unhandled 8-bit write to %08x:%08x (%02x)", vaddr, addr, value);+
+ //exit(1);
}
void psx_bus_init_bios(psx_bus_t* bus, psx_bios_t* bios) {--- a/psx/cpu.c
+++ b/psx/cpu.c
@@ -1444,7 +1444,7 @@
void psx_cpu_i_gte(psx_cpu_t* cpu) {DO_PENDING_LOAD;
- g_psx_gte_table[cpu->opcode & 0x3f](cpu);
+ // g_psx_gte_table[cpu->opcode & 0x3f](cpu);
}
void psx_gte_i_invalid(psx_cpu_t* cpu) {--- a/psx/dev/cdrom.c
+++ b/psx/dev/cdrom.c
@@ -128,9 +128,9 @@
// Read ongoing
case CD_STATE_SEND_RESP2: {- log_set_quiet(0);
+ // log_set_quiet(0);
log_fatal("SETLOC WHILE READN");- log_set_quiet(1);
+ // log_set_quiet(0+0);
int f = PFIFO_POP;
int s = PFIFO_POP;
@@ -193,6 +193,34 @@
return;
}
+ psx_disc_read_sector(cdrom->disc, cdrom->dfifo);
+
+ msf_t sector_msf;
+
+ sector_msf.m = cdrom->dfifo[0x0c];
+ sector_msf.s = cdrom->dfifo[0x0d];
+ sector_msf.f = cdrom->dfifo[0x0e];
+
+ int correct_msf = (cdrom->seek_mm == sector_msf.m) &&
+ (cdrom->seek_ss == sector_msf.s) &&
+ (cdrom->seek_ff == sector_msf.f);
+
+ // Most probably audio sector:
+ // Purposefully constructed audio data could
+ // circumvent this detection code, but it will work
+ // for most intents and purposes
+ if (!correct_msf) {+ log_fatal("CdlReadN: Audio read");+
+ cdrom->irq_delay = DELAY_1MS * 600;
+ cdrom->delayed_command = CDL_ERROR;
+ cdrom->state = CD_STATE_ERROR;
+ cdrom->error = ERR_SEEK;
+ cdrom->error_flags = GETSTAT_SEEKERROR;
+
+ return;
+ }
+
int double_speed = cdrom->mode & MODE_SPEED;
cdrom->irq_delay = double_speed ? READ_DOUBLE_DELAY : READ_SINGLE_DELAY;
@@ -219,42 +247,25 @@
psx_disc_seek(cdrom->disc, msf);
psx_disc_read_sector(cdrom->disc, cdrom->dfifo);
- msf_t sector_msf;
+ // printf("Sector header: msf=%02x:%02x:%02x, mode=%02x, subheader=%02x,%02x,%02x,%02x\n",+ // cdrom->dfifo[0x0c],
+ // cdrom->dfifo[0x0d],
+ // cdrom->dfifo[0x0e],
+ // cdrom->dfifo[0x0f],
+ // cdrom->dfifo[0x10],
+ // cdrom->dfifo[0x11],
+ // cdrom->dfifo[0x12],
+ // cdrom->dfifo[0x13]
+ // );
- sector_msf.m = cdrom->dfifo[0x0c];
- sector_msf.s = cdrom->dfifo[0x0d];
- sector_msf.f = cdrom->dfifo[0x0e];
-
- if ((cdrom->seek_mm != sector_msf.m) ||
- (cdrom->seek_ss != sector_msf.s) ||
- (cdrom->seek_ff != sector_msf.f)) {-
- log_set_quiet(0);
- log_fatal("Mismatched sector and loc");- log_set_quiet(1);
-
- exit(1);
- }
-
if (cdrom->dfifo[0x12] & 0x20) {- log_set_quiet(0);
+ // log_set_quiet(0);
log_fatal("Unimplemented XA Form2 Sector");- log_set_quiet(1);
+ // log_set_quiet(0+0);
- exit(1);
+ // exit(1);
}
- printf("Sector header: msf=%02x:%02x:%02x, mode=%02x, subheader=%02x,%02x,%02x,%02x\n",- cdrom->dfifo[0x0c],
- cdrom->dfifo[0x0d],
- cdrom->dfifo[0x0e],
- cdrom->dfifo[0x0f],
- cdrom->dfifo[0x10],
- cdrom->dfifo[0x11],
- cdrom->dfifo[0x12],
- cdrom->dfifo[0x13]
- );
-
cdrom->seek_ff++;
if ((cdrom->seek_ff & 0xF) == 10) { cdrom->seek_ff += 0x10; cdrom->seek_ff &= 0xF0; }@@ -317,6 +328,14 @@
cdrom->state = CD_STATE_SEND_RESP1;
cdrom->delayed_command = CDL_INIT;
cdrom->read_ongoing = 0;
+ cdrom->mode = 0;
+ cdrom->dfifo_index = 0;
+ cdrom->dfifo_full = 0;
+ cdrom->pfifo_index = 0;
+ cdrom->rfifo_index = 0;
+ cdrom->seek_mm = 0;
+ cdrom->seek_ss = 0;
+ cdrom->seek_ff = 0;
} break;
case CD_STATE_SEND_RESP1: {@@ -435,7 +454,7 @@
cdrom->delayed_command = CDL_NONE;
SET_BITS(ifr, IFR_INT, IFR_INT3);
- RESP_PUSH(cdrom->stat);
+ RESP_PUSH(GETSTAT_MOTOR);
cdrom->state = CD_STATE_RECV_CMD;
} break;
@@ -528,6 +547,18 @@
switch (cdrom->state) { case CD_STATE_RECV_CMD: {+ if (cdrom->pfifo_index) {+ log_fatal("CdlSeekL: Expected exactly 0 parameters");+
+ cdrom->irq_delay = DELAY_1MS;
+ cdrom->delayed_command = CDL_ERROR;
+ cdrom->state = CD_STATE_ERROR;
+ cdrom->error = ERR_PCOUNT;
+ cdrom->error_flags = GETSTAT_ERROR;
+
+ return;
+ }
+
cdrom->irq_delay = DELAY_1MS;
cdrom->state = CD_STATE_SEND_RESP1;
cdrom->delayed_command = CDL_SEEKL;
@@ -551,7 +582,34 @@
} break;
}
}
-void cdrom_cmd_seekp(psx_cdrom_t* cdrom) { log_fatal("seekp: Unimplemented"); exit(1); }+void cdrom_cmd_seekp(psx_cdrom_t* cdrom) {+ cdrom->delayed_command = CDL_NONE;
+
+ switch (cdrom->state) {+ case CD_STATE_RECV_CMD: {+ cdrom->irq_delay = DELAY_1MS;
+ cdrom->state = CD_STATE_SEND_RESP1;
+ cdrom->delayed_command = CDL_SEEKP;
+ } break;
+
+ case CD_STATE_SEND_RESP1: {+ SET_BITS(ifr, IFR_INT, 3);
+ RESP_PUSH(GETSTAT_MOTOR);
+
+ cdrom->irq_delay = DELAY_1MS;
+ cdrom->state = CD_STATE_SEND_RESP2;
+ cdrom->delayed_command = CDL_SEEKP;
+ } break;
+
+ case CD_STATE_SEND_RESP2: {+ SET_BITS(ifr, IFR_INT, 2);
+ RESP_PUSH(GETSTAT_MOTOR);
+
+ cdrom->state = CD_STATE_RECV_CMD;
+ cdrom->delayed_command = CDL_NONE;
+ } break;
+ }
+}
void cdrom_cmd_test(psx_cdrom_t* cdrom) {cdrom->delayed_command = CDL_NONE;
@@ -660,13 +718,14 @@
void cdrom_cmd_reads(psx_cdrom_t* cdrom) { log_fatal("reads: Unimplemented");- exit(1);
+ //exit(1);
cdrom->delayed_command = CDL_NONE;
+ cdrom->read_ongoing = 1;
switch (cdrom->state) { case CD_STATE_RECV_CMD: {- log_fatal("CdlReadS: CD_STATE_RECV_CMD");+ log_fatal("CdlReadN: CD_STATE_RECV_CMD");cdrom->irq_delay = DELAY_1MS;
cdrom->state = CD_STATE_SEND_RESP1;
cdrom->delayed_command = CDL_READS;
@@ -673,11 +732,61 @@
} break;
case CD_STATE_SEND_RESP1: {- log_fatal("CdlReadS: CD_STATE_SEND_RESP1");+ log_fatal("CdlReadN: CD_STATE_SEND_RESP1");- SET_BITS(ifr, IFR_INT, 3);
+ SET_BITS(ifr, IFR_INT, IFR_INT3);
RESP_PUSH(GETSTAT_MOTOR);
+ msf_t msf;
+
+ msf.m = cdrom->seek_mm;
+ msf.s = cdrom->seek_ss;
+ msf.f = cdrom->seek_ff;
+
+ msf_from_bcd(&msf);
+
+ int err = psx_disc_seek(cdrom->disc, msf);
+
+ if (err) {+ log_fatal("CdlReadN: Out of bounds seek");+
+ cdrom->irq_delay = DELAY_1MS * 600;
+ cdrom->delayed_command = CDL_ERROR;
+ cdrom->state = CD_STATE_ERROR;
+ cdrom->error = ERR_INVSUBF;
+ cdrom->error_flags = GETSTAT_SEEKERROR;
+
+ return;
+ }
+
+ psx_disc_read_sector(cdrom->disc, cdrom->dfifo);
+
+ msf_t sector_msf;
+
+ sector_msf.m = cdrom->dfifo[0x0c];
+ sector_msf.s = cdrom->dfifo[0x0d];
+ sector_msf.f = cdrom->dfifo[0x0e];
+
+ int correct_msf = (cdrom->seek_mm == sector_msf.m) &&
+ (cdrom->seek_ss == sector_msf.s) &&
+ (cdrom->seek_ff == sector_msf.f);
+
+ // Most probably audio sector:
+ // Purposefully constructed audio data could
+ // circumvent this detection code, but it will work
+ // for most intents and purposes
+ if (!correct_msf) {+ log_fatal("CdlReadN: Audio read");+
+ cdrom->irq_delay = DELAY_1MS * 600;
+ cdrom->delayed_command = CDL_ERROR;
+ cdrom->state = CD_STATE_ERROR;
+ cdrom->error = ERR_SEEK;
+ cdrom->error_flags = GETSTAT_SEEKERROR;
+
+ return;
+ }
+
int double_speed = cdrom->mode & MODE_SPEED;
cdrom->irq_delay = double_speed ? READ_DOUBLE_DELAY : READ_SINGLE_DELAY;
@@ -691,25 +800,55 @@
} break;
case CD_STATE_SEND_RESP2: {- log_fatal("CdlReadS: CD_STATE_SEND_RESP2");+ log_fatal("CdlReadN: CD_STATE_SEND_RESP2");- SET_BITS(ifr, IFR_INT, 1);
- RESP_PUSH(GETSTAT_MOTOR | GETSTAT_READ);
+ msf_t msf;
- // log_fatal("Reading data from disc. offset=%02x:%02x:%02x (%08x, tellg=%08x)",- // cdrom->seek_mm, cdrom->seek_ss, cdrom->seek_ff,
- // cdrom->seek_offset, ftell(cdrom->disc)
+ msf.m = cdrom->seek_mm;
+ msf.s = cdrom->seek_ss;
+ msf.f = cdrom->seek_ff;
+
+ msf_from_bcd(&msf);
+
+ psx_disc_seek(cdrom->disc, msf);
+ psx_disc_read_sector(cdrom->disc, cdrom->dfifo);
+
+ // printf("Sector header: msf=%02x:%02x:%02x, mode=%02x, subheader=%02x,%02x,%02x,%02x\n",+ // cdrom->dfifo[0x0c],
+ // cdrom->dfifo[0x0d],
+ // cdrom->dfifo[0x0e],
+ // cdrom->dfifo[0x0f],
+ // cdrom->dfifo[0x10],
+ // cdrom->dfifo[0x11],
+ // cdrom->dfifo[0x12],
+ // cdrom->dfifo[0x13]
// );
- cdrom->dfifo_index = 0;
+ if (cdrom->dfifo[0x12] & 0x20) {+ // log_set_quiet(0);
+ log_fatal("Unimplemented XA Form2 Sector");+ // log_set_quiet(0+0);
- //fread(cdrom->dfifo, 1, CD_SECTOR_SIZE, cdrom->disc);
+ // exit(1);
+ }
+ cdrom->seek_ff++;
+
+ if ((cdrom->seek_ff & 0xF) == 10) { cdrom->seek_ff += 0x10; cdrom->seek_ff &= 0xF0; }+ if (cdrom->seek_ff == 0x75) { cdrom->seek_ss++; cdrom->seek_ff = 0; }+ if ((cdrom->seek_ss & 0xF) == 10) { cdrom->seek_ss += 0x10; cdrom->seek_ss &= 0xF0; }+ if (cdrom->seek_ss == 0x60) { cdrom->seek_mm++; cdrom->seek_ss = 0; }+ if ((cdrom->seek_mm & 0xF) == 10) { cdrom->seek_mm += 0x10; cdrom->seek_mm &= 0xF0; }+
int double_speed = cdrom->mode & MODE_SPEED;
cdrom->irq_delay = double_speed ? READ_DOUBLE_DELAY : READ_SINGLE_DELAY;
- cdrom->state = CD_STATE_RECV_CMD;
- cdrom->delayed_command = CDL_NONE;
+ cdrom->state = CD_STATE_SEND_RESP2;
+ cdrom->delayed_command = CDL_READN;
+ cdrom->dfifo_index = 0;
+
+ SET_BITS(ifr, IFR_INT, IFR_INT1);
+ RESP_PUSH(GETSTAT_MOTOR | GETSTAT_READ);
} break;
}
}
@@ -841,7 +980,7 @@
}
void cdrom_write_cmd(psx_cdrom_t* cdrom, uint8_t value) {- log_set_quiet(0);
+ // log_set_quiet(0);
log_fatal("%s(%02x) %u params=[%02x, %02x, %02x, %02x, %02x, %02x]",g_psx_cdrom_command_names[value],
value,
@@ -853,7 +992,7 @@
cdrom->pfifo[4],
cdrom->pfifo[5]
);
- log_set_quiet(1);
+ // log_set_quiet(0+0);
cdrom->command = value;
cdrom->state = CD_STATE_RECV_CMD;
--- a/psx/dev/dma.c
+++ b/psx/dev/dma.c
@@ -356,7 +356,6 @@
// Clear BCR and CHCR trigger and busy bits
dma->spu.chcr = 0;
- //dma->otc.chcr &= ~(CHCR_BUSY_MASK | CHCR_TRIG_MASK);
dma->spu.bcr = 0;
}
@@ -430,7 +429,7 @@
int force_irq = (dma->dicr & DICR_FORCE) != 0;
int irq = (dma->dicr & DICR_FLAGS) != 0;
- int irq_signal = force_irq || (irq && irq_on_flags);
+ int irq_signal = force_irq || ((irq & irq_on_flags) != 0);
if (irq_signal && !prev_irq_signal)
psx_ic_irq(dma->ic, IC_DMA);
--- a/psx/dev/gpu.c
+++ b/psx/dev/gpu.c
@@ -447,6 +447,10 @@
} break;
case GPU_STATE_RECV_DATA: {+ uint32_t addr = gpu->addr + (gpu->xcnt + (gpu->ycnt * 1024));
+
+ addr %= PSX_GPU_VRAM_SIZE;
+
gpu->vram[gpu->addr + (gpu->xcnt + (gpu->ycnt * 1024))] = gpu->recv_data & 0xffff;
gpu->xcnt += 1;
@@ -455,6 +459,9 @@
gpu->ycnt += 1;
gpu->xcnt = 0;
}
+
+ addr = gpu->addr + (gpu->xcnt + (gpu->ycnt * 1024));
+ addr %= PSX_GPU_VRAM_SIZE;
gpu->vram[gpu->addr + (gpu->xcnt + (gpu->ycnt * 1024))] = gpu->recv_data >> 16;
--- a/psx/dev/ram.c
+++ b/psx/dev/ram.c
@@ -22,26 +22,38 @@
}
uint32_t psx_ram_read32(psx_ram_t* ram, uint32_t offset) {+ offset &= 0x1fffff;
+
return *((uint32_t*)(ram->buf + offset));
}
uint16_t psx_ram_read16(psx_ram_t* ram, uint32_t offset) {+ offset &= 0x1fffff;
+
return *((uint16_t*)(ram->buf + offset));
}
uint8_t psx_ram_read8(psx_ram_t* ram, uint32_t offset) {+ offset &= 0x1fffff;
+
return ram->buf[offset];
}
void psx_ram_write32(psx_ram_t* ram, uint32_t offset, uint32_t value) {+ offset &= 0x1fffff;
+
*((uint32_t*)(ram->buf + offset)) = value;
}
void psx_ram_write16(psx_ram_t* ram, uint32_t offset, uint16_t value) {+ offset &= 0x1fffff;
+
*((uint16_t*)(ram->buf + offset)) = value;
}
void psx_ram_write8(psx_ram_t* ram, uint32_t offset, uint8_t value) {+ offset &= 0x1fffff;
+
ram->buf[offset] = value;
}
--- a/psx/dev/ram.h
+++ b/psx/dev/ram.h
@@ -6,9 +6,11 @@
#include "../log.h"
#include "mc2.h"
-#define PSX_RAM_SIZE 0x200000
+//#define PSX_RAM_SIZE 0x200000
+#define PSX_RAM_SIZE 0x1f000000
#define PSX_RAM_BEGIN 0x00000000
-#define PSX_RAM_END 0x001fffff
+//#define PSX_RAM_END 0x001fffff
+#define PSX_RAM_END 0x1effffff
typedef struct {uint32_t io_base, io_size;
--- a/psx/dev/timer.c
+++ b/psx/dev/timer.c
@@ -63,6 +63,8 @@
log_fatal("Unhandled 32-bit TIMER read at offset %08x", offset);+ exit(1);
+
return 0x0;
}
@@ -84,6 +86,8 @@
log_fatal("Unhandled 16-bit TIMER read at offset %08x", offset);+ exit(1);
+
return 0x0;
}
@@ -90,6 +94,8 @@
uint8_t psx_timer_read8(psx_timer_t* timer, uint32_t offset) { log_fatal("Unhandled 8-bit TIMER read at offset %08x", offset);+ exit(1);
+
return 0x0;
}
@@ -112,9 +118,13 @@
}
log_fatal("Unhandled 32-bit TIMER write at offset %08x (%02x)", offset, value);+
+ exit(1);
}
void psx_timer_write16(psx_timer_t* timer, uint32_t offset, uint16_t value) {+ return;
+
int index = offset >> 4;
int reg = offset & 0xf;
@@ -135,10 +145,14 @@
}
log_fatal("Unhandled 16-bit TIMER write at offset %08x (%02x)", offset, value);+
+ exit(1);
}
void psx_timer_write8(psx_timer_t* timer, uint32_t offset, uint8_t value) { log_fatal("Unhandled 8-bit TIMER write at offset %08x (%02x)", offset, value);+
+ exit(1);
}
void timer_update_timer0(psx_timer_t* timer, int cyc) {--
⑨