ref: 2e6491c20b71356eb4450b1180a6a11fb1df13bb
parent: dd6976f79391a1d98690efa28a77d8674c2d746b
author: allkern <lisandroaalarcon@gmail.com>
date: Sun Jul 23 10:08:32 EDT 2023
Stub SPU space and SPU DMA IRQ
--- a/psx/dev/dma.c
+++ b/psx/dev/dma.c
@@ -225,18 +225,6 @@
g_psx_dma_gpu_table[CHCR_SYNC(gpu)](dma);
- // if (dma->dicr & 0x00040000) {- // dma->dicr |= 0x04000000;
-
- // if ((dma->dicr & 0x8000) || ((dma->dicr & 0x800000) && (dma->dicr & 0x7f000000))) {- // dma->dicr |= 0x80000000;
-
- // psx_ic_irq(dma->ic, IC_DMA);
- // } else {- // dma->dicr &= 0x7fffffff;
- // }
- // }
-
// Clear BCR and CHCR trigger and busy bits
dma->gpu.chcr &= ~(CHCR_BUSY_MASK | CHCR_TRIG_MASK);
dma->gpu.bcr = 0;
@@ -295,11 +283,59 @@
}
void psx_dma_do_spu(psx_dma_t* dma) {- log_error("SPU DMA channel unimplemented"); exit(1);+ if (!CHCR_BUSY(spu))
+ return;
+
+ log_fatal("SPU DMA transfer: madr=%08x, dir=%s, sync=%s (%u), step=%s, size=%x",+ dma->spu.madr,
+ CHCR_TDIR(spu) ? "to device" : "to RAM",
+ g_psx_dma_sync_type_name_table[CHCR_SYNC(spu)], CHCR_SYNC(spu),
+ CHCR_STEP(spu) ? "decrementing" : "incrementing",
+ BCR_SIZE(spu)
+ );
+
+ log_fatal("DICR: force=%u, en=%02x, irqen=%u, flags=%02x",+ (dma->dicr >> 15) & 1,
+ (dma->dicr >> 16) & 0x7f,
+ (dma->dicr >> 23) & 1,
+ (dma->dicr >> 24) & 0x7f
+ );
+
+ uint32_t size = BCR_SIZE(spu) * BCR_BCNT(spu);
+
+ if (!size) {+ log_fatal("0 sized SPU DMA");+
+ exit(1);
+ }
+
+ 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;
+ //dma->otc.chcr &= ~(CHCR_BUSY_MASK | CHCR_TRIG_MASK);
+ dma->spu.bcr = 0;
}
void psx_dma_do_pio(psx_dma_t* dma) {- log_error("PIO DMA channel unimplemented"); exit(1);+ log_fatal("PIO DMA channel unimplemented"); exit(1);}
void psx_dma_do_otc(psx_dma_t* dma) {@@ -337,6 +373,17 @@
dma->dicr |= DICR_DMA3FL;
dma->cdrom_irq_delay = 0;
+ }
+ }
+
+ if (dma->spu_irq_delay) {+ dma->spu_irq_delay -= cyc;
+
+ if (dma->spu_irq_delay <= 0) {+ if (dma->dicr & DICR_DMA4EN)
+ dma->dicr |= DICR_DMA4FL;
+
+ dma->spu_irq_delay = 0;
}
}
--- a/psx/dev/dma.h
+++ b/psx/dev/dma.h
@@ -31,6 +31,7 @@
dma_channel_t otc;
int cdrom_irq_delay;
+ int spu_irq_delay;
uint32_t dpcr;
uint32_t dicr;
--- a/psx/dev/spu.c
+++ b/psx/dev/spu.c
@@ -14,38 +14,37 @@
spu->io_base = PSX_SPU_BEGIN;
spu->io_size = PSX_SPU_SIZE;
+
+ spu->ram = (uint8_t*)malloc(PSX_SPU_RAM_SIZE);
}
uint32_t psx_spu_read32(psx_spu_t* spu, uint32_t offset) {- //log_warn("Unhandled 32-bit SPU read at offset %08x", offset);-
- return 0x0;
+ return *(uint32_t*)(&spu->r[offset]);
}
uint16_t psx_spu_read16(psx_spu_t* spu, uint32_t offset) {- //log_warn("Unhandled 16-bit SPU read at offset %08x", offset);-
- return 0x0;
+ return *(uint16_t*)(&spu->r[offset]);
}
uint8_t psx_spu_read8(psx_spu_t* spu, uint32_t offset) {- //log_warn("Unhandled 8-bit SPU read at offset %08x", offset);+ log_fatal("Unhandled 8-bit SPU read at offset %08x", offset);return 0x0;
}
void psx_spu_write32(psx_spu_t* spu, uint32_t offset, uint32_t value) {- //log_warn("Unhandled 32-bit SPU write at offset %08x (%08x)", offset, value);+ *(uint32_t*)(&spu->r[offset]) = value;
}
void psx_spu_write16(psx_spu_t* spu, uint32_t offset, uint16_t value) {- //log_warn("Unhandled 16-bit SPU write at offset %08x (%04x)", offset, value);+ *(uint16_t*)(&spu->r[offset]) = value;
}
void psx_spu_write8(psx_spu_t* spu, uint32_t offset, uint8_t value) {- //log_warn("Unhandled 8-bit SPU write at offset %08x (%02x)", offset, value);+ log_fatal("Unhandled 8-bit SPU write at offset %08x (%02x)", offset, value);}
void psx_spu_destroy(psx_spu_t* spu) {+ free(spu->ram);
free(spu);
}
\ No newline at end of file
--- a/psx/dev/spu.h
+++ b/psx/dev/spu.h
@@ -7,8 +7,31 @@
#define PSX_SPU_SIZE 0x400
#define PSX_SPU_END 0x1f801fff
+#define PSX_SPU_RAM_SIZE 0x80000
+
typedef struct {uint32_t io_base, io_size;
+
+ uint8_t* ram;
+
+ uint8_t r[0x400];
+
+ uint32_t current_addr;
+
+ // struct {+ // uint16_t volumel;
+ // uint16_t volumer;
+ // uint16_t adsampr;
+ // uint16_t adsaddr;
+ // uint16_t envctl1;
+ // uint16_t envctl2;
+ // uint16_t envcvol;
+ // uint16_t adraddr;
+ // } voice[24];
+
+ // uint16_t mainvol[2];
+ // uint16_t echovol[2];
+ // uint32_t flags[3];
} psx_spu_t;
psx_spu_t* psx_spu_create();
--
⑨