ref: 2c93171f461b593b81e161eb6208689337a1e8be
parent: 478a6bd0cd359b42614c125b9d1c8f275e551715
author: allkern <lisandroaalarcon@gmail.com>
date: Sun Aug 6 10:00:03 EDT 2023
Implement `mdec_in` Stub quant and scale table recv
--- a/psx/bus.c
+++ b/psx/bus.c
@@ -267,7 +267,7 @@
bus->pad = pad;
}
-void psx_bus_init_pad(psx_bus_t* bus, psx_mdec_t* mdec) {+void psx_bus_init_mdec(psx_bus_t* bus, psx_mdec_t* mdec) {bus->mdec = mdec;
}
--- a/psx/dev/dma.c
+++ b/psx/dev/dma.c
@@ -147,9 +147,29 @@
"reserved"
};
-void psx_dma_do_mdec_in(psx_dma_t* dma) { log_error("MDEC_IN DMA channel unimplemented"); }-void psx_dma_do_mdec_out(psx_dma_t* dma) { log_error("MDEC_OUT DMA channel unimplemented"); }+void psx_dma_do_mdec_in(psx_dma_t* dma) {+ if (!CHCR_BUSY(mdec_in))
+ return;
+ for (int i = 0; i < BCR_SIZE(mdec_in); i++) {+ uint32_t data = psx_bus_read32(dma->bus, dma->gpu.madr);
+
+ psx_bus_write32(dma->bus, 0x1f801820, data);
+
+ dma->gpu.madr += CHCR_STEP(mdec_in) ? -4 : 4;
+ }
+
+ dma->mdec_in.chcr &= ~(CHCR_BUSY_MASK | CHCR_TRIG_MASK);
+ dma->mdec_in.bcr = 0;
+}
+
+void psx_dma_do_mdec_out(psx_dma_t* dma) {+ if (!CHCR_BUSY(mdec_out))
+ return;
+
+ log_fatal("MDEC_OUT DMA channel unimplemented");+}
+
void psx_dma_do_gpu_linked(psx_dma_t* dma) {uint32_t hdr = psx_bus_read32(dma->bus, dma->gpu.madr);
uint32_t size = hdr >> 24;
@@ -224,13 +244,13 @@
if (!CHCR_BUSY(gpu))
return;
- log_error("GPU DMA transfer: madr=%08x, dir=%s, sync=%s (%u), step=%s, size=%x",- dma->gpu.madr,
- CHCR_TDIR(gpu) ? "to device" : "to RAM",
- g_psx_dma_sync_type_name_table[CHCR_SYNC(gpu)], CHCR_SYNC(gpu),
- CHCR_STEP(gpu) ? "decrementing" : "incrementing",
- BCR_SIZE(gpu)
- );
+ // log_error("GPU DMA transfer: madr=%08x, dir=%s, sync=%s (%u), step=%s, size=%x",+ // dma->gpu.madr,
+ // CHCR_TDIR(gpu) ? "to device" : "to RAM",
+ // g_psx_dma_sync_type_name_table[CHCR_SYNC(gpu)], CHCR_SYNC(gpu),
+ // CHCR_STEP(gpu) ? "decrementing" : "incrementing",
+ // BCR_SIZE(gpu)
+ // );
g_psx_dma_gpu_table[CHCR_SYNC(gpu)](dma);
@@ -243,20 +263,20 @@
if (!CHCR_BUSY(cdrom))
return;
- log_fatal("CDROM DMA transfer: madr=%08x, dir=%s, sync=%s (%u), step=%s, size=%x",- dma->cdrom.madr,
- CHCR_TDIR(cdrom) ? "to device" : "to RAM",
- g_psx_dma_sync_type_name_table[CHCR_SYNC(cdrom)], CHCR_SYNC(cdrom),
- CHCR_STEP(cdrom) ? "decrementing" : "incrementing",
- BCR_SIZE(cdrom)
- );
+ // log_fatal("CDROM DMA transfer: madr=%08x, dir=%s, sync=%s (%u), step=%s, size=%x",+ // dma->cdrom.madr,
+ // CHCR_TDIR(cdrom) ? "to device" : "to RAM",
+ // g_psx_dma_sync_type_name_table[CHCR_SYNC(cdrom)], CHCR_SYNC(cdrom),
+ // CHCR_STEP(cdrom) ? "decrementing" : "incrementing",
+ // BCR_SIZE(cdrom)
+ // );
- 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
- );
+ // 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(cdrom);
@@ -295,20 +315,20 @@
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("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
- );
+ // 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);
@@ -334,13 +354,13 @@
if (!CHCR_TRIG(otc))
return;
- log_error("OTC DMA transfer: madr=%08x, dir=%s, sync=%s, step=%s, size=%x",- dma->otc.madr,
- CHCR_TDIR(otc) ? "to device" : "to RAM",
- CHCR_SYNC(otc) ? "other" : "burst",
- CHCR_STEP(otc) ? "decrementing" : "incrementing",
- BCR_SIZE(otc)
- );
+ // log_error("OTC DMA transfer: madr=%08x, dir=%s, sync=%s, step=%s, size=%x",+ // dma->otc.madr,
+ // CHCR_TDIR(otc) ? "to device" : "to RAM",
+ // CHCR_SYNC(otc) ? "other" : "burst",
+ // CHCR_STEP(otc) ? "decrementing" : "incrementing",
+ // BCR_SIZE(otc)
+ // );
for (int i = BCR_SIZE(otc); i > 0; i--) {uint32_t addr = (i != 1) ? (dma->otc.madr - 4) : 0xffffff;
--- a/psx/dev/mdec.c
+++ b/psx/dev/mdec.c
@@ -5,6 +5,68 @@
#include <string.h>
#include <stdlib.h>
+void mdec_nop(psx_mdec_t* mdec) { /* Do nothing */ }+
+void mdec_decode_macroblock(psx_mdec_t* mdec) {+ // To-do
+}
+
+void mdec_set_iqtab(psx_mdec_t* mdec) {+ mdec->state = mdec->cmd & 1 ? MDEC_RECV_QUANT_COLOR : MDEC_RECV_QUANT;
+ mdec->data_remaining = mdec->cmd & 1 ? 32 : 16;
+ mdec->index = 0;
+}
+
+void mdec_set_scale(psx_mdec_t* mdec) {+ mdec->state = MDEC_RECV_SCALE;
+ mdec->data_remaining = 32;
+ mdec->index = 0;
+}
+
+mdec_fn_t g_mdec_cmd_table[] = {+ mdec_nop,
+ mdec_decode_macroblock,
+ mdec_set_iqtab,
+ mdec_set_scale,
+ mdec_nop,
+ mdec_nop,
+ mdec_nop,
+ mdec_nop
+};
+
+void mdec_recv_cmd(psx_mdec_t* mdec) {+ log_fatal("MDEC command %u (%08x)", mdec->cmd >> 29, mdec->cmd);+
+ g_mdec_cmd_table[mdec->cmd >> 29](mdec);
+}
+void mdec_recv_block(psx_mdec_t* mdec) {}+void mdec_recv_quant(psx_mdec_t* mdec) {+ mdec->data_remaining--;
+
+ if (!mdec->data_remaining)
+ mdec->state = MDEC_RECV_CMD;
+}
+void mdec_recv_quant_color(psx_mdec_t* mdec) {+ mdec->data_remaining--;
+
+ if (!mdec->data_remaining)
+ mdec->state = MDEC_RECV_CMD;
+}
+void mdec_recv_scale(psx_mdec_t* mdec) {+ mdec->data_remaining--;
+
+ if (!mdec->data_remaining)
+ mdec->state = MDEC_RECV_CMD;
+}
+
+mdec_fn_t g_mdec_recv_table[] = {+ mdec_recv_cmd,
+ mdec_recv_block,
+ mdec_recv_quant,
+ mdec_recv_quant_color,
+ mdec_recv_scale
+};
+
psx_mdec_t* psx_mdec_create() {return (psx_mdec_t*)malloc(sizeof(psx_mdec_t));
}
@@ -14,10 +76,17 @@
mdec->io_base = PSX_MDEC_BEGIN;
mdec->io_size = PSX_MDEC_SIZE;
+
+ mdec->state = MDEC_RECV_CMD;
}
uint32_t psx_mdec_read32(psx_mdec_t* mdec, uint32_t offset) {- log_fatal("32-bit MDEC read offset=%u", offset);+ switch (offset) {+ case 0: {+
+ } break;
+ case 4: return mdec->status;
+ }
}
uint16_t psx_mdec_read16(psx_mdec_t* mdec, uint32_t offset) {@@ -33,6 +102,22 @@
}
void psx_mdec_write32(psx_mdec_t* mdec, uint32_t offset, uint32_t value) {+ switch (offset) {+ case 0: {+ mdec->cmd = value;
+
+ g_mdec_recv_table[mdec->state](mdec);
+ } break;
+
+ case 4: {+ if (value & 0x80000000)
+ mdec->status = 0x80040000;
+
+ mdec->status &= 0xe7ffffff;
+ mdec->status |= (value & 0x60000000) >> 2;
+ } break;
+ }
+
log_fatal("32-bit MDEC write offset=%u, value=%08x", offset, value);}
--- a/psx/dev/mdec.h
+++ b/psx/dev/mdec.h
@@ -9,8 +9,24 @@
#define PSX_MDEC_BEGIN 0x1f801820
#define PSX_MDEC_END 0x1f801827
+enum {+ MDEC_RECV_CMD,
+ MDEC_RECV_BLOCK,
+ MDEC_RECV_QUANT,
+ MDEC_RECV_QUANT_COLOR,
+ MDEC_RECV_SCALE
+};
+
typedef struct {uint32_t io_base, io_size;
+
+ uint32_t cmd;
+
+ int state;
+ int data_remaining;
+ int index;
+
+ uint32_t status;
} psx_mdec_t;
psx_mdec_t* psx_mdec_create();
@@ -22,5 +38,7 @@
void psx_mdec_write16(psx_mdec_t*, uint32_t, uint16_t);
void psx_mdec_write8(psx_mdec_t*, uint32_t, uint8_t);
void psx_mdec_destroy(psx_mdec_t*);
+
+typedef void (*mdec_fn_t)(psx_mdec_t*);
#endif
\ No newline at end of file
--
⑨