shithub: psxe

Download patch

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();
+		}
 	}
 }
--