shithub: psxe

Download patch

ref: 99be385e3fd8ba853017925aa3c45566be233044
parent: 0117a772af8a27001190af2efed25fe38c2ee78b
author: allkern <lisandroaalarcon@gmail.com>
date: Sun Oct 29 15:19:06 EDT 2023

Major timings rework

--- a/psx/bus.c
+++ b/psx/bus.c
@@ -24,18 +24,18 @@
 }
 
 #define HANDLE_READ(dev, bits) \
-    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);
-
+    if (RANGE(addr, bus->dev->io_base, (bus->dev->io_base + bus->dev->io_size))) { \
+        bus->access_cycles = bus->dev->bus_delay; \
+        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))) { \
+        bus->access_cycles = bus->dev->bus_delay; \
         psx_ ## dev ## _write ## bits (bus->dev, addr - bus->dev->io_base, value); \
         return; \
     }
 
 uint32_t psx_bus_read32(psx_bus_t* bus, uint32_t addr) {
-    bus->access_cycles = 2;
-
     uint32_t vaddr = addr;
 
     addr &= g_psx_bus_region_mask_table[addr >> 29];
--- a/psx/cpu.c
+++ b/psx/cpu.c
@@ -774,7 +774,7 @@
 
     g_psx_cpu_primary_table[OP](cpu);
 
-    cpu->last_cycles = 2;
+    cpu->last_cycles = 2 + psx_bus_get_access_cycles(cpu->bus);
     cpu->total_cycles += cpu->last_cycles;
 
     cpu->r[0] = 0;
--- a/psx/dev/bios.c
+++ b/psx/dev/bios.c
@@ -14,6 +14,7 @@
 
     bios->io_base = PSX_BIOS_BEGIN;
     bios->io_size = PSX_BIOS_SIZE;
+    bios->bus_delay = 20;
 
     bios->buf = (uint8_t*)malloc(PSX_BIOS_SIZE);
 }
--- a/psx/dev/bios.h
+++ b/psx/dev/bios.h
@@ -10,6 +10,7 @@
 #define PSX_BIOS_END    0x1fc7ffff
 
 typedef struct {
+    uint32_t bus_delay;
     uint32_t io_base, io_size;
 
     uint8_t* buf;
--- a/psx/dev/cdrom.c
+++ b/psx/dev/cdrom.c
@@ -284,7 +284,9 @@
             int err = psx_disc_seek(cdrom->disc, msf);
 
             if (err) {
+                log_set_quiet(0);
                 log_fatal("CdlReadN: Out of bounds seek");
+                log_set_quiet(1);
 
                 cdrom->irq_delay = DELAY_1MS * 600;
                 cdrom->delayed_command = CDL_ERROR;
@@ -312,7 +314,9 @@
             // circumvent this detection code, but it will work
             // for most intents and purposes 
             if (!correct_msf) {
+                log_set_quiet(0);
                 log_fatal("CdlReadN: Audio read");
+                log_set_quiet(1);
 
                 cdrom->irq_delay = DELAY_1MS * 600;
                 cdrom->delayed_command = CDL_ERROR;
@@ -802,6 +806,18 @@
 
     switch (cdrom->state) {
         case CD_STATE_RECV_CMD: {
+            if (cdrom->pfifo_index) {
+                log_fatal("CdlSeekP: 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_SEEKP;
@@ -814,6 +830,18 @@
             cdrom->irq_delay = DELAY_1MS;
             cdrom->state = CD_STATE_SEND_RESP2;
             cdrom->delayed_command = CDL_SEEKP;
+
+            msf_t msf;
+
+            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);
+
+            cdrom->seek_pending = 0;
         } break;
 
         case CD_STATE_SEND_RESP2: {
@@ -1189,7 +1217,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,
@@ -1201,7 +1229,7 @@
         cdrom->pfifo[4],
         cdrom->pfifo[5]
     );
-    // log_set_quiet(1);
+    log_set_quiet(1);
 
     cdrom->command = value;
     cdrom->state = CD_STATE_RECV_CMD;
@@ -1240,8 +1268,14 @@
 }
 
 void cdrom_write_ifr(psx_cdrom_t* cdrom, uint8_t value) {
-    cdrom->ifr &= ~(value & 0x7);
+    cdrom->ifr &= ~(value & 0x1f);
 
+    // if (value & 0x7) {
+    //     log_set_quiet(0);
+    //     log_fatal("Acknowledge %02x", value & 0x7);
+    //     log_set_quiet(1);
+    // }
+
     // Clear Parameter FIFO
     if (value & 0x40) {
         cdrom->pfifo_index = 0;
@@ -1361,20 +1395,23 @@
         cdrom->irq_delay -= cyc;
 
         if (cdrom->irq_delay <= 0) {
-            if (cdrom->int_number) {
-                SET_BITS(ifr, IFR_INT, cdrom->int_number);
-
-                cdrom->int_number = 0;
-            }
-
-            log_fatal("CDROM INT%u", cdrom->ifr & 0x7);
             psx_ic_irq(cdrom->ic, IC_CDROM);
 
             cdrom->irq_delay = 0;
 
             if (cdrom->delayed_command) {
+                // log_set_quiet(0);
+                // log_fatal("%s(%02x) (Delayed)",
+                //     g_psx_cdrom_command_names[cdrom->delayed_command],
+                //     cdrom->delayed_command
+                // );
+                // log_set_quiet(1);
                 g_psx_cdrom_command_table[cdrom->delayed_command](cdrom);
             }
+
+            // log_set_quiet(0);
+            // log_fatal("CDROM INT%u", cdrom->ifr & 0x7);
+            // log_set_quiet(1);
         }
     }
 }
--- a/psx/dev/cdrom.h
+++ b/psx/dev/cdrom.h
@@ -11,6 +11,9 @@
 #include "../msf.h"
 #include "spu.h"
 
+// #define DELAY_1MS (0xc4e1)
+// #define READ_SINGLE_DELAY (0x6e1cd)
+// #define READ_DOUBLE_DELAY (0x36cd2)
 #define DELAY_1MS (PSX_CPU_CPS / 1000)
 #define READ_SINGLE_DELAY (PSX_CPU_CPS / 75)
 #define READ_DOUBLE_DELAY (PSX_CPU_CPS / (2 * 75))
@@ -149,6 +152,7 @@
 };
 
 typedef struct {
+    uint32_t bus_delay;
     uint32_t io_base, io_size;
 
     psx_ic_t* ic;
--- a/psx/dev/dma.h
+++ b/psx/dev/dma.h
@@ -17,6 +17,7 @@
 } dma_channel_t;
 
 typedef struct {
+    uint32_t bus_delay;
     uint32_t io_base, io_size;
 
     psx_bus_t* bus;
--- a/psx/dev/exp1.h
+++ b/psx/dev/exp1.h
@@ -10,6 +10,7 @@
 #define PSX_EXP1_END   0x1f080000
 
 typedef struct {
+    uint32_t bus_delay;
     uint32_t io_base, io_size;
 
     psx_mc1_t* mc1;
--- a/psx/dev/gpu.h
+++ b/psx/dev/gpu.h
@@ -86,6 +86,7 @@
 } rect_data_t;
 
 struct psx_gpu_t {
+    uint32_t bus_delay;
     uint32_t io_base, io_size;
 
     void* udata[4];
--- a/psx/dev/ic.h
+++ b/psx/dev/ic.h
@@ -10,19 +10,19 @@
 #define PSX_IC_END   0x1F801077
 
 /*
-  0     IRQ0 VBLANK (PAL=50Hz, NTSC=60Hz)
-  1     IRQ1 GPU   Can be requested via GP0(1Fh) command (rarely used)
-  2     IRQ2 CDROM
-  3     IRQ3 DMA
-  4     IRQ4 TMR0  Timer 0 aka Root Counter 0 (Sysclk or Dotclk)
-  5     IRQ5 TMR1  Timer 1 aka Root Counter 1 (Sysclk or H-blank)
-  6     IRQ6 TMR2  Timer 2 aka Root Counter 2 (Sysclk or Sysclk/8)
-  7     IRQ7 Controller and Memory Card - Byte Received Interrupt
-  8     IRQ8 SIO
-  9     IRQ9 SPU
-  10    IRQ10 Controller - Lightpen Interrupt (reportedly also PIO...?)
-  11-15 Not used (always zero)
-  16-31 Garbage
+    0     IRQ0 VBLANK (PAL=50Hz, NTSC=60Hz)
+    1     IRQ1 GPU   Can be requested via GP0(1Fh) command (rarely used)
+    2     IRQ2 CDROM
+    3     IRQ3 DMA
+    4     IRQ4 TMR0  Timer 0 aka Root Counter 0 (Sysclk or Dotclk)
+    5     IRQ5 TMR1  Timer 1 aka Root Counter 1 (Sysclk or H-blank)
+    6     IRQ6 TMR2  Timer 2 aka Root Counter 2 (Sysclk or Sysclk/8)
+    7     IRQ7 Controller and Memory Card - Byte Received Interrupt
+    8     IRQ8 SIO
+    9     IRQ9 SPU
+    10    IRQ10 Controller - Lightpen Interrupt (reportedly also PIO...?)
+    11-15 Not used (always zero)
+    16-31 Garbage
 */
 enum {
     IC_VBLANK       = 0x001,
@@ -39,11 +39,12 @@
 };
 
 /*
-  1F801070h 2    I_STAT - Interrupt status register
-  1F801074h 2    I_MASK - Interrupt mask register
+    1F801070h 2    I_STAT - Interrupt status register
+    1F801074h 2    I_MASK - Interrupt mask register
 */
 
 typedef struct {
+    uint32_t bus_delay;
     uint32_t io_base, io_size;
 
     uint16_t stat;
--- a/psx/dev/mc1.h
+++ b/psx/dev/mc1.h
@@ -8,6 +8,7 @@
 #define PSX_MC1_END   0x1f801023
 
 typedef struct {
+    uint32_t bus_delay;
     uint32_t io_base, io_size;
 
     uint32_t exp1_base;
--- a/psx/dev/mc2.h
+++ b/psx/dev/mc2.h
@@ -8,6 +8,7 @@
 #define PSX_MC2_END   0x1F801063
 
 typedef struct {
+    uint32_t bus_delay;
     uint32_t io_base, io_size;
 
     uint32_t ram_size;
--- a/psx/dev/mc3.h
+++ b/psx/dev/mc3.h
@@ -8,6 +8,7 @@
 #define PSX_MC3_END   0xfffe0133
 
 typedef struct {
+    uint32_t bus_delay;
     uint32_t io_base, io_size;
 
     uint32_t cache_control;
--- a/psx/dev/mdec.c
+++ b/psx/dev/mdec.c
@@ -347,6 +347,7 @@
             }
 
             mdec->cmd = value;
+            mdec->output_request = 0;
             mdec->output_empty = 1;
             mdec->output_bit15 = (value >> 25) & 1;
             mdec->output_signed = (value >> 26) & 1;
--- a/psx/dev/mdec.h
+++ b/psx/dev/mdec.h
@@ -42,6 +42,7 @@
 };
 
 typedef struct {
+    uint32_t bus_delay;
     uint32_t io_base, io_size;
 
     uint32_t cmd;
--- a/psx/dev/pad.h
+++ b/psx/dev/pad.h
@@ -126,6 +126,7 @@
 */
 
 typedef struct {
+    uint32_t bus_delay;
     uint32_t io_base, io_size;
 
     psx_ic_t* ic;
--- a/psx/dev/ram.h
+++ b/psx/dev/ram.h
@@ -13,6 +13,7 @@
 #define PSX_RAM_END     0x1effffff
 
 typedef struct {
+    uint32_t bus_delay;
     uint32_t io_base, io_size;
 
     psx_mc2_t* mc2;
--- a/psx/dev/scratchpad.h
+++ b/psx/dev/scratchpad.h
@@ -10,6 +10,7 @@
 #define PSX_SCRATCHPAD_END   0x1f8003ff
 
 typedef struct {
+    uint32_t bus_delay;
     uint32_t io_base, io_size;
 
     uint8_t* buf;
--- a/psx/dev/spu.h
+++ b/psx/dev/spu.h
@@ -34,6 +34,7 @@
 #define SPUR_MBASE   0x1a2
 
 typedef struct __attribute__((__packed__)) {
+    uint32_t bus_delay;
     uint32_t io_base, io_size;
 
     uint8_t* ram;
--- a/psx/dev/timer.h
+++ b/psx/dev/timer.h
@@ -58,6 +58,7 @@
 #define MODE_CLK 0x0080
 
 typedef struct {
+    uint32_t bus_delay;
     uint32_t io_base, io_size;
 
     psx_ic_t* ic;
--- a/psx/psx.c
+++ b/psx/psx.c
@@ -26,7 +26,7 @@
 
 void psx_update(psx_t* psx) {
     psx_cpu_cycle(psx->cpu);
-    psx_cdrom_update(psx->cdrom, psx->cpu->last_cycles);
+    psx_cdrom_update(psx->cdrom, 22);
     psx_gpu_update(psx->gpu, psx->cpu->last_cycles);
     psx_pad_update(psx->pad, psx->cpu->last_cycles);
     psx_timer_update(psx->timer, psx->cpu->last_cycles);
--