ref: bbe05479f90ed2d8404f1d4b379687082d099548
parent: 0f41e84591f3ecba3e53789a891b6f43746abf27
author: Jean-André Santoni <jean.andre.santoni@gmail.com>
date: Sat Mar 7 21:41:29 EST 2026
Make it work
--- a/dat.h
+++ b/dat.h
@@ -58,5 +58,7 @@
psx_spu_t* psx_spu_create(void);
void psx_spu_init(psx_spu_t*, psx_ic_t*);
void psx_spu_destroy(psx_spu_t*);
+void psx_spu_update_cdda_buffer(psx_spu_t*, void*);
+uint32_t psx_spu_get_sample(psx_spu_t*);
#endif
--- a/psx/cpu_debug.h
+++ b/psx/cpu_debug.h
@@ -324,7 +324,7 @@
log_trace("%08x: %-7s $%s, $%s, 0x%04x", cpu->pc-8, m, g_mips_cc_register_names[T], g_mips_cc_register_names[S], IMM16)#define TRACE_I5D(m) \
- log_trace("%08x: %-7s $%s, $%s, %u", cpu->pc-8, m, g_mips_cc_register_names[D], g_mips_cc_register_names[T], IMM5)+ log_trace("%08x: %-7s $%s, $%s, %d", cpu->pc-8, m, g_mips_cc_register_names[D], g_mips_cc_register_names[T], IMM5)#define TRACE_I26(m) \
log_trace("%08x: %-7s 0x%07x", cpu->pc-8, m, ((cpu->pc & 0xf0000000) | (IMM26 << 2)))@@ -336,10 +336,10 @@
log_trace("%08x: %-7s $%s, $%s", cpu->pc-8, m, g_mips_cc_register_names[T], g_mips_cop0_register_names[D])#define TRACE_C2M(m) \
- log_trace("%08x: %-7s $%s, $cop2_r%u", cpu->pc-8, m, g_mips_cc_register_names[T], D)+ log_trace("%08x: %-7s $%s, $cop2_r%d", cpu->pc-8, m, g_mips_cc_register_names[T], D)#define TRACE_C2MC(m) \
- log_trace("%08x: %-7s $%s, $cop2_r%u", cpu->pc-8, m, g_mips_cc_register_names[T], D + 32)+ log_trace("%08x: %-7s $%s, $cop2_r%d", cpu->pc-8, m, g_mips_cc_register_names[T], D + 32)#define TRACE_B(m) \
log_trace("%08x: %-7s $%s, $%s, %-i", cpu->pc-8, m, g_mips_cc_register_names[S], g_mips_cc_register_names[T], IMM16S << 2)@@ -425,4 +425,4 @@
#define TRACE_MD(m)
#define TRACE_I20(m)
#define TRACE_N(m)
-#endif
\ No newline at end of file
+#endif
--- a/psx/dev/cdrom/cdrom.h
+++ b/psx/dev/cdrom/cdrom.h
@@ -202,9 +202,10 @@
};
struct psx_cdrom_t {- int mute;
+ /* Must stay first: bus_probe() reads these via common iomap layout. */
uint32_t bus_delay;
uint32_t io_base, io_size;
+ int mute;
psx_disc_t* disc;
psx_ic_t* ic;
int disc_type;
--- a/psx/dev/dma.c
+++ b/psx/dev/dma.c
@@ -29,8 +29,40 @@
psx_dma_do_otc
};
-#define CR(c, r) *((&dma->mdec_in.madr) + (c * 3) + r)
+static dma_channel_t*
+dma_get_channel(psx_dma_t* dma, int channel) {+ switch (channel) {+ case 0: return &dma->mdec_in;
+ case 1: return &dma->mdec_out;
+ case 2: return &dma->gpu;
+ case 3: return &dma->cdrom;
+ case 4: return &dma->spu;
+ case 5: return &dma->pio;
+ case 6: return &dma->otc;
+ default: return nil;
+ }
+}
+static uint32_t
+dma_read_channel_reg(dma_channel_t* ch, int reg) {+ switch (reg) {+ case 0: return ch->madr;
+ case 1: return ch->bcr;
+ case 2: return ch->chcr;
+ default: return 0;
+ }
+}
+
+static int
+dma_write_channel_reg(dma_channel_t* ch, int reg, uint32_t value) {+ switch (reg) {+ case 0: ch->madr = value; return 0;
+ case 1: ch->bcr = value; return 0;
+ case 2: ch->chcr = value; return 0;
+ default: return -1;
+ }
+}
+
void psx_dma_init(psx_dma_t* dma, psx_bus_t* bus, psx_ic_t* ic) {memset(dma, 0, sizeof(psx_dma_t));
@@ -45,16 +77,26 @@
uint32_t psx_dma_read32(psx_dma_t* dma, uint32_t offset) { if (offset < 0x70) {+ dma_channel_t* ch;
int channel = (offset >> 4) & 0x7;
int reg = (offset >> 2) & 0x3;
- uint32_t cr = CR(channel, reg);
+ uint32_t cr;
+ ch = dma_get_channel(dma, channel);
+
+ if (!ch) {+ log_error("Unhandled DMA channel %d register %d (%08x) read", channel, reg, PSX_DMAR_BEGIN + offset);+ return 0x0;
+ }
+
+ cr = dma_read_channel_reg(ch, reg);
+
if (reg == 2) {cr |= g_psx_dma_ctrl_hw_1_table[channel];
cr &= g_psx_dma_ctrl_hw_0_table[channel];
}
- log_error("DMA channel %u register %u (%08x) read %08x", channel, reg, PSX_DMAR_BEGIN + offset, cr);+ log_error("DMA channel %d register %d (%08x) read %08x", channel, reg, PSX_DMAR_BEGIN + offset, cr);return cr;
} else {@@ -115,12 +157,23 @@
void psx_dma_write32(psx_dma_t* dma, uint32_t offset, uint32_t value) { if (offset < 0x70) {+ dma_channel_t* ch;
int channel = (offset >> 4) & 0x7;
int reg = (offset >> 2) & 0x3;
- CR(channel, reg) = value;
+ ch = dma_get_channel(dma, channel);
- log_error("DMA channel %u register %u write (%08x) %08x", channel, reg, PSX_DMAR_BEGIN + offset, value);+ if (!ch) {+ log_error("Unhandled DMA channel %d register %d write (%08x) %08x", channel, reg, PSX_DMAR_BEGIN + offset, value);+ return;
+ }
+
+ if (dma_write_channel_reg(ch, reg, value)) {+ log_error("Unhandled DMA channel %d register %d write (%08x) %08x", channel, reg, PSX_DMAR_BEGIN + offset, value);+ return;
+ }
+
+ log_error("DMA channel %d register %d write (%08x) %08x", channel, reg, PSX_DMAR_BEGIN + offset, value);if (reg == 2)
g_psx_dma_do_table[channel](dma);
--- a/psxe.c
+++ b/psxe.c
@@ -2,7 +2,22 @@
#include "fns.h"
Emu emu;
+static int audfd = -1;
+static s16int audbuf[735 * 2];
+static int needflush;
+static int
+fileexists(char *path)
+{+ int fd;
+
+ fd = open(path, OREAD);
+ if(fd < 0)
+ return 0;
+ close(fd);
+ return 1;
+}
+
static u32int
bgr555toxrgb32(u16int c)
{@@ -146,7 +161,56 @@
int
audioout(void)
{- return -1;
+ psx_cdrom_t *cdrom;
+ psx_spu_t *spu;
+ int i;
+ int nsamp;
+
+ if(emu.psx == nil)
+ return -1;
+ if(audfd < 0){+ audfd = open("/dev/audio", OWRITE);+ if(audfd < 0)
+ return -1;
+ }
+
+ cdrom = psx_get_cdrom(emu.psx);
+ spu = psx_get_spu(emu.psx);
+ nsamp = nelem(audbuf) / 2;
+
+ memset(audbuf, 0, sizeof audbuf);
+ psx_cdrom_get_audio_samples(cdrom, audbuf, sizeof audbuf);
+ psx_spu_update_cdda_buffer(spu, cdrom->cdda_buf);
+
+ for(i = 0; i < nsamp; i++){+ u32int sample;
+ int l, r;
+
+ sample = psx_spu_get_sample(spu);
+
+ l = audbuf[i * 2 + 0] + (s16int)(sample & 0xffff);
+ r = audbuf[i * 2 + 1] + (s16int)(sample >> 16);
+
+ if(l > 32767)
+ l = 32767;
+ else if(l < -32768)
+ l = -32768;
+ if(r > 32767)
+ r = 32767;
+ else if(r < -32768)
+ r = -32768;
+
+ audbuf[i * 2 + 0] = l;
+ audbuf[i * 2 + 1] = r;
+ }
+
+ if(warp10)
+ return 0;
+
+ if(write(audfd, audbuf, sizeof audbuf) < 0)
+ return -1;
+
+ return 0;
}
void
@@ -160,8 +224,8 @@
void
psxe_gpu_vblank_event_cb(psx_gpu_t *gpu)
{- blitframe();
- flush();
+ USED(gpu);
+ needflush = 1;
psxe_gpu_vblank_timer_event_cb(gpu);
}
@@ -168,7 +232,7 @@
void
usage(void)
{- fprint(2, "usage: %s [-x scale] [-e expansion] bios [disc]\n", argv0);
+ print("usage: %s [-x scale] [-e expansion] bios [disc]\n", argv0); exits("usage");}
@@ -218,7 +282,7 @@
emu.pad = psx_get_pad(emu.psx);
if(disc != nil && !psx_cdrom_open(psx_get_cdrom(emu.psx), disc))
- fprint(2, "warning: cannot open disc %s\n", disc);
+ print("warning: cannot open disc %s\n", disc);input = psx_input_create();
psx_input_init(input);
@@ -228,8 +292,14 @@
psxi_sda_init_input(controller, input);
psx_pad_attach_joy(emu.pad, 0, input);
- psx_pad_attach_mcd(emu.pad, 0, "slot1.mcd");
- psx_pad_attach_mcd(emu.pad, 1, "slot2.mcd");
+ if(fileexists("slot1.mcd"))+ psx_pad_attach_mcd(emu.pad, 0, "slot1.mcd");
+ else
+ print("warning: slot1.mcd not found, memory card 1 disabled\n");+ if(fileexists("slot2.mcd"))+ psx_pad_attach_mcd(emu.pad, 1, "slot2.mcd");
+ else
+ print("warning: slot2.mcd not found, memory card 2 disabled\n");gpu = psx_get_gpu(emu.psx);
@@ -250,5 +320,10 @@
}
process_inputs();
psx_update(emu.psx);
+ if(needflush){+ needflush = 0;
+ blitframe();
+ flush();
+ }
}
}
--
⑨