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);
--
⑨