shithub: psxe

Download patch

ref: 32088d682e8b0f1005d012c3313054b852df87c9
parent: 0670e53ade035499045de505dc80f48aca2a3ef4
author: allkern <lisandroaalarcon@gmail.com>
date: Fri Sep 15 14:33:39 EDT 2023

Several fixes

RAM mirroring implemented
DMA IRQ signal fix

--- a/frontend/main.c
+++ b/frontend/main.c
@@ -25,7 +25,7 @@
 
     psxe_screen_t* screen = psxe_screen_create();
     psxe_screen_init(screen, psx);
-    psxe_screen_set_scale(screen, 2);
+    psxe_screen_set_scale(screen, 3);
     psxe_screen_reload(screen);
 
     psx_gpu_t* gpu = psx_get_gpu(psx);
--- a/psx/bus.c
+++ b/psx/bus.c
@@ -24,11 +24,11 @@
 }
 
 #define HANDLE_READ(dev, bits) \
-    if (RANGE(addr, bus->dev->io_base, bus->dev->io_base + bus->dev->io_size)) \
+    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);
 
 #define HANDLE_WRITE(dev, bits) \
-    if (RANGE(addr, bus->dev->io_base, bus->dev->io_base + bus->dev->io_size)) { \
+    if (RANGE(addr, bus->dev->io_base, (bus->dev->io_base + bus->dev->io_size))) { \
         psx_ ## dev ## _write ## bits (bus->dev, addr - bus->dev->io_base, value); \
         return; \
     }
@@ -41,7 +41,7 @@
     addr &= g_psx_bus_region_mask_table[addr >> 29];
 
     if (addr & 0x3) {
-        log_warn("Unaligned 32-bit read from %08x:%08x", vaddr, addr);
+        log_fatal("Unaligned 32-bit read from %08x:%08x", vaddr, addr);
     }
 
     HANDLE_READ(bios, 32);
@@ -60,8 +60,10 @@
     HANDLE_READ(pad, 32);
     HANDLE_READ(mdec, 32);
 
-    log_warn("Unhandled 32-bit read from %08x:%08x", vaddr, addr);
+    log_fatal("Unhandled 32-bit read from %08x:%08x", vaddr, addr);
 
+    exit(1);
+
     return 0x00000000;
 }
 
@@ -73,7 +75,7 @@
     addr &= g_psx_bus_region_mask_table[addr >> 29];
 
     if (addr & 0x1) {
-        log_warn("Unaligned 16-bit read from %08x:%08x", vaddr, addr);
+        log_fatal("Unaligned 16-bit read from %08x:%08x", vaddr, addr);
     }
 
     HANDLE_READ(bios, 16);
@@ -92,8 +94,10 @@
     HANDLE_READ(pad, 16);
     HANDLE_READ(mdec, 16);
 
-    log_warn("Unhandled 16-bit read from %08x:%08x", vaddr, addr);
+    log_fatal("Unhandled 16-bit read from %08x:%08x", vaddr, addr);
 
+    exit(1);
+
     return 0x0000;
 }
 
@@ -120,8 +124,10 @@
     HANDLE_READ(pad, 8);
     HANDLE_READ(mdec, 8);
 
-    log_warn("Unhandled 8-bit read from %08x:%08x", vaddr, addr);
+    log_fatal("Unhandled 8-bit read from %08x:%08x", vaddr, addr);
 
+    //exit(1);
+
     return 0x00;
 }
 
@@ -133,7 +139,7 @@
     addr &= g_psx_bus_region_mask_table[addr >> 29];
 
     if (addr & 0x3) {
-        log_warn("Unaligned 32-bit write to %08x:%08x (%08x)", vaddr, addr, value);
+        log_fatal("Unaligned 32-bit write to %08x:%08x (%08x)", vaddr, addr, value);
     }
 
     HANDLE_WRITE(bios, 32);
@@ -152,7 +158,9 @@
     HANDLE_WRITE(pad, 32);
     HANDLE_WRITE(mdec, 32);
 
-    log_warn("Unhandled 32-bit write to %08x:%08x (%08x)", vaddr, addr, value);
+    log_fatal("Unhandled 32-bit write to %08x:%08x (%08x)", vaddr, addr, value);
+
+    exit(1);
 }
 
 void psx_bus_write16(psx_bus_t* bus, uint32_t addr, uint16_t value) {
@@ -163,7 +171,7 @@
     addr &= g_psx_bus_region_mask_table[addr >> 29];
 
     if (addr & 0x1) {
-        log_warn("Unaligned 16-bit write to %08x:%08x (%04x)", vaddr, addr, value);
+        log_fatal("Unaligned 16-bit write to %08x:%08x (%04x)", vaddr, addr, value);
     }
 
     HANDLE_WRITE(bios, 16);
@@ -182,7 +190,9 @@
     HANDLE_WRITE(pad, 16);
     HANDLE_WRITE(mdec, 16);
 
-    log_warn("Unhandled 16-bit write to %08x:%08x (%04x)", vaddr, addr, value);
+    log_fatal("Unhandled 16-bit write to %08x:%08x (%04x)", vaddr, addr, value);
+
+    //exit(1);
 }
 
 void psx_bus_write8(psx_bus_t* bus, uint32_t addr, uint8_t value) {
@@ -208,7 +218,9 @@
     HANDLE_WRITE(pad, 8);
     HANDLE_WRITE(mdec, 8);
 
-    log_warn("Unhandled 8-bit write to %08x:%08x (%02x)", vaddr, addr, value);
+    log_fatal("Unhandled 8-bit write to %08x:%08x (%02x)", vaddr, addr, value);
+
+    //exit(1);
 }
 
 void psx_bus_init_bios(psx_bus_t* bus, psx_bios_t* bios) {
--- a/psx/cpu.c
+++ b/psx/cpu.c
@@ -1444,7 +1444,7 @@
 void psx_cpu_i_gte(psx_cpu_t* cpu) {
     DO_PENDING_LOAD;
 
-    g_psx_gte_table[cpu->opcode & 0x3f](cpu);
+    // g_psx_gte_table[cpu->opcode & 0x3f](cpu);
 }
 
 void psx_gte_i_invalid(psx_cpu_t* cpu) {
--- a/psx/dev/cdrom.c
+++ b/psx/dev/cdrom.c
@@ -128,9 +128,9 @@
 
         // Read ongoing
         case CD_STATE_SEND_RESP2: {
-            log_set_quiet(0);
+            // log_set_quiet(0);
             log_fatal("SETLOC WHILE READN");
-            log_set_quiet(1);
+            // log_set_quiet(0+0);
 
             int f = PFIFO_POP;
             int s = PFIFO_POP;
@@ -193,6 +193,34 @@
                 return;
             }
 
+            psx_disc_read_sector(cdrom->disc, cdrom->dfifo);
+
+            msf_t sector_msf;
+
+            sector_msf.m = cdrom->dfifo[0x0c];
+            sector_msf.s = cdrom->dfifo[0x0d];
+            sector_msf.f = cdrom->dfifo[0x0e];
+
+            int correct_msf = (cdrom->seek_mm == sector_msf.m) && 
+                              (cdrom->seek_ss == sector_msf.s) &&
+                              (cdrom->seek_ff == sector_msf.f);
+            
+            // Most probably audio sector:
+            // Purposefully constructed audio data could
+            // circumvent this detection code, but it will work
+            // for most intents and purposes 
+            if (!correct_msf) {
+                log_fatal("CdlReadN: Audio read");
+
+                cdrom->irq_delay = DELAY_1MS * 600;
+                cdrom->delayed_command = CDL_ERROR;
+                cdrom->state = CD_STATE_ERROR;
+                cdrom->error = ERR_SEEK;
+                cdrom->error_flags = GETSTAT_SEEKERROR;
+
+                return;
+            }
+            
             int double_speed = cdrom->mode & MODE_SPEED;
 
             cdrom->irq_delay = double_speed ? READ_DOUBLE_DELAY : READ_SINGLE_DELAY;
@@ -219,42 +247,25 @@
             psx_disc_seek(cdrom->disc, msf);
             psx_disc_read_sector(cdrom->disc, cdrom->dfifo);
 
-            msf_t sector_msf;
+            // printf("Sector header: msf=%02x:%02x:%02x, mode=%02x, subheader=%02x,%02x,%02x,%02x\n",
+            //     cdrom->dfifo[0x0c],
+            //     cdrom->dfifo[0x0d],
+            //     cdrom->dfifo[0x0e],
+            //     cdrom->dfifo[0x0f],
+            //     cdrom->dfifo[0x10],
+            //     cdrom->dfifo[0x11],
+            //     cdrom->dfifo[0x12],
+            //     cdrom->dfifo[0x13]
+            // );
 
-            sector_msf.m = cdrom->dfifo[0x0c];
-            sector_msf.s = cdrom->dfifo[0x0d];
-            sector_msf.f = cdrom->dfifo[0x0e];
-
-            if ((cdrom->seek_mm != sector_msf.m) || 
-                (cdrom->seek_ss != sector_msf.s) ||
-                (cdrom->seek_ff != sector_msf.f)) {
-
-                log_set_quiet(0);
-                log_fatal("Mismatched sector and loc");
-                log_set_quiet(1);
-
-                exit(1);
-            }
-
             if (cdrom->dfifo[0x12] & 0x20) {
-                log_set_quiet(0);
+                // log_set_quiet(0);
                 log_fatal("Unimplemented XA Form2 Sector");
-                log_set_quiet(1);
+                // log_set_quiet(0+0);
 
-                exit(1);
+                // exit(1);
             }
 
-            printf("Sector header: msf=%02x:%02x:%02x, mode=%02x, subheader=%02x,%02x,%02x,%02x\n",
-                cdrom->dfifo[0x0c],
-                cdrom->dfifo[0x0d],
-                cdrom->dfifo[0x0e],
-                cdrom->dfifo[0x0f],
-                cdrom->dfifo[0x10],
-                cdrom->dfifo[0x11],
-                cdrom->dfifo[0x12],
-                cdrom->dfifo[0x13]
-            );
-
             cdrom->seek_ff++;
 
             if ((cdrom->seek_ff & 0xF) == 10) { cdrom->seek_ff += 0x10; cdrom->seek_ff &= 0xF0; }
@@ -317,6 +328,14 @@
             cdrom->state = CD_STATE_SEND_RESP1;
             cdrom->delayed_command = CDL_INIT;
             cdrom->read_ongoing = 0;
+            cdrom->mode = 0;
+            cdrom->dfifo_index = 0;
+            cdrom->dfifo_full = 0;
+            cdrom->pfifo_index = 0;
+            cdrom->rfifo_index = 0;
+            cdrom->seek_mm = 0;
+            cdrom->seek_ss = 0;
+            cdrom->seek_ff = 0;
         } break;
 
         case CD_STATE_SEND_RESP1: {
@@ -435,7 +454,7 @@
             cdrom->delayed_command = CDL_NONE;
     
             SET_BITS(ifr, IFR_INT, IFR_INT3);
-            RESP_PUSH(cdrom->stat);
+            RESP_PUSH(GETSTAT_MOTOR);
 
             cdrom->state = CD_STATE_RECV_CMD;
         } break;
@@ -528,6 +547,18 @@
 
     switch (cdrom->state) {
         case CD_STATE_RECV_CMD: {
+            if (cdrom->pfifo_index) {
+                log_fatal("CdlSeekL: 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_SEEKL;
@@ -551,7 +582,34 @@
         } break;
     }
 }
-void cdrom_cmd_seekp(psx_cdrom_t* cdrom) { log_fatal("seekp: Unimplemented"); exit(1); }
+void cdrom_cmd_seekp(psx_cdrom_t* cdrom) {
+    cdrom->delayed_command = CDL_NONE;
+
+    switch (cdrom->state) {
+        case CD_STATE_RECV_CMD: {
+            cdrom->irq_delay = DELAY_1MS;
+            cdrom->state = CD_STATE_SEND_RESP1;
+            cdrom->delayed_command = CDL_SEEKP;
+        } break;
+
+        case CD_STATE_SEND_RESP1: {
+            SET_BITS(ifr, IFR_INT, 3);
+            RESP_PUSH(GETSTAT_MOTOR);
+
+            cdrom->irq_delay = DELAY_1MS;
+            cdrom->state = CD_STATE_SEND_RESP2;
+            cdrom->delayed_command = CDL_SEEKP;
+        } break;
+
+        case CD_STATE_SEND_RESP2: {
+            SET_BITS(ifr, IFR_INT, 2);
+            RESP_PUSH(GETSTAT_MOTOR);
+
+            cdrom->state = CD_STATE_RECV_CMD;
+            cdrom->delayed_command = CDL_NONE;
+        } break;
+    }
+}
 void cdrom_cmd_test(psx_cdrom_t* cdrom) {
     cdrom->delayed_command = CDL_NONE;
 
@@ -660,13 +718,14 @@
 void cdrom_cmd_reads(psx_cdrom_t* cdrom) {
     log_fatal("reads: Unimplemented");
 
-    exit(1);
+    //exit(1);
 
     cdrom->delayed_command = CDL_NONE;
+    cdrom->read_ongoing = 1;
 
     switch (cdrom->state) {
         case CD_STATE_RECV_CMD: {
-            log_fatal("CdlReadS: CD_STATE_RECV_CMD");
+            log_fatal("CdlReadN: CD_STATE_RECV_CMD");
             cdrom->irq_delay = DELAY_1MS;
             cdrom->state = CD_STATE_SEND_RESP1;
             cdrom->delayed_command = CDL_READS;
@@ -673,11 +732,61 @@
         } break;
 
         case CD_STATE_SEND_RESP1: {
-            log_fatal("CdlReadS: CD_STATE_SEND_RESP1");
+            log_fatal("CdlReadN: CD_STATE_SEND_RESP1");
 
-            SET_BITS(ifr, IFR_INT, 3);
+            SET_BITS(ifr, IFR_INT, IFR_INT3);
             RESP_PUSH(GETSTAT_MOTOR);
 
+            msf_t msf;
+
+            msf.m = cdrom->seek_mm;
+            msf.s = cdrom->seek_ss;
+            msf.f = cdrom->seek_ff;
+
+            msf_from_bcd(&msf);
+
+            int err = psx_disc_seek(cdrom->disc, msf);
+
+            if (err) {
+                log_fatal("CdlReadN: Out of bounds seek");
+
+                cdrom->irq_delay = DELAY_1MS * 600;
+                cdrom->delayed_command = CDL_ERROR;
+                cdrom->state = CD_STATE_ERROR;
+                cdrom->error = ERR_INVSUBF;
+                cdrom->error_flags = GETSTAT_SEEKERROR;
+
+                return;
+            }
+
+            psx_disc_read_sector(cdrom->disc, cdrom->dfifo);
+
+            msf_t sector_msf;
+
+            sector_msf.m = cdrom->dfifo[0x0c];
+            sector_msf.s = cdrom->dfifo[0x0d];
+            sector_msf.f = cdrom->dfifo[0x0e];
+
+            int correct_msf = (cdrom->seek_mm == sector_msf.m) && 
+                              (cdrom->seek_ss == sector_msf.s) &&
+                              (cdrom->seek_ff == sector_msf.f);
+            
+            // Most probably audio sector:
+            // Purposefully constructed audio data could
+            // circumvent this detection code, but it will work
+            // for most intents and purposes 
+            if (!correct_msf) {
+                log_fatal("CdlReadN: Audio read");
+
+                cdrom->irq_delay = DELAY_1MS * 600;
+                cdrom->delayed_command = CDL_ERROR;
+                cdrom->state = CD_STATE_ERROR;
+                cdrom->error = ERR_SEEK;
+                cdrom->error_flags = GETSTAT_SEEKERROR;
+
+                return;
+            }
+            
             int double_speed = cdrom->mode & MODE_SPEED;
 
             cdrom->irq_delay = double_speed ? READ_DOUBLE_DELAY : READ_SINGLE_DELAY;
@@ -691,25 +800,55 @@
         } break;
 
         case CD_STATE_SEND_RESP2: {
-            log_fatal("CdlReadS: CD_STATE_SEND_RESP2");
+            log_fatal("CdlReadN: CD_STATE_SEND_RESP2");
 
-            SET_BITS(ifr, IFR_INT, 1);
-            RESP_PUSH(GETSTAT_MOTOR | GETSTAT_READ);
+            msf_t msf;
 
-            // log_fatal("Reading data from disc. offset=%02x:%02x:%02x (%08x, tellg=%08x)",
-            //     cdrom->seek_mm, cdrom->seek_ss, cdrom->seek_ff,
-            //     cdrom->seek_offset, ftell(cdrom->disc)
+            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);
+            psx_disc_read_sector(cdrom->disc, cdrom->dfifo);
+
+            // printf("Sector header: msf=%02x:%02x:%02x, mode=%02x, subheader=%02x,%02x,%02x,%02x\n",
+            //     cdrom->dfifo[0x0c],
+            //     cdrom->dfifo[0x0d],
+            //     cdrom->dfifo[0x0e],
+            //     cdrom->dfifo[0x0f],
+            //     cdrom->dfifo[0x10],
+            //     cdrom->dfifo[0x11],
+            //     cdrom->dfifo[0x12],
+            //     cdrom->dfifo[0x13]
             // );
 
-            cdrom->dfifo_index = 0;
+            if (cdrom->dfifo[0x12] & 0x20) {
+                // log_set_quiet(0);
+                log_fatal("Unimplemented XA Form2 Sector");
+                // log_set_quiet(0+0);
 
-            //fread(cdrom->dfifo, 1, CD_SECTOR_SIZE, cdrom->disc);
+                // exit(1);
+            }
 
+            cdrom->seek_ff++;
+
+            if ((cdrom->seek_ff & 0xF) == 10) { cdrom->seek_ff += 0x10; cdrom->seek_ff &= 0xF0; }
+            if (cdrom->seek_ff == 0x75) { cdrom->seek_ss++; cdrom->seek_ff = 0; }
+            if ((cdrom->seek_ss & 0xF) == 10) { cdrom->seek_ss += 0x10; cdrom->seek_ss &= 0xF0; }
+            if (cdrom->seek_ss == 0x60) { cdrom->seek_mm++; cdrom->seek_ss = 0; }
+            if ((cdrom->seek_mm & 0xF) == 10) { cdrom->seek_mm += 0x10; cdrom->seek_mm &= 0xF0; }
+
             int double_speed = cdrom->mode & MODE_SPEED;
 
             cdrom->irq_delay = double_speed ? READ_DOUBLE_DELAY : READ_SINGLE_DELAY;
-            cdrom->state = CD_STATE_RECV_CMD;
-            cdrom->delayed_command = CDL_NONE;
+            cdrom->state = CD_STATE_SEND_RESP2;
+            cdrom->delayed_command = CDL_READN;
+            cdrom->dfifo_index = 0;
+
+            SET_BITS(ifr, IFR_INT, IFR_INT1);
+            RESP_PUSH(GETSTAT_MOTOR | GETSTAT_READ);
         } break;
     }
 }
@@ -841,7 +980,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,
@@ -853,7 +992,7 @@
         cdrom->pfifo[4],
         cdrom->pfifo[5]
     );
-    log_set_quiet(1);
+    // log_set_quiet(0+0);
 
     cdrom->command = value;
     cdrom->state = CD_STATE_RECV_CMD;
--- a/psx/dev/dma.c
+++ b/psx/dev/dma.c
@@ -356,7 +356,6 @@
     
     // Clear BCR and CHCR trigger and busy bits
     dma->spu.chcr = 0;
-    //dma->otc.chcr &= ~(CHCR_BUSY_MASK | CHCR_TRIG_MASK);
     dma->spu.bcr = 0;
 }
 
@@ -430,7 +429,7 @@
     int force_irq = (dma->dicr & DICR_FORCE) != 0;
     int irq = (dma->dicr & DICR_FLAGS) != 0;
 
-    int irq_signal = force_irq || (irq && irq_on_flags);
+    int irq_signal = force_irq || ((irq & irq_on_flags) != 0);
 
     if (irq_signal && !prev_irq_signal)
         psx_ic_irq(dma->ic, IC_DMA);
--- a/psx/dev/gpu.c
+++ b/psx/dev/gpu.c
@@ -447,6 +447,10 @@
         } break;
 
         case GPU_STATE_RECV_DATA: {
+            uint32_t addr = gpu->addr + (gpu->xcnt + (gpu->ycnt * 1024));
+
+            addr %= PSX_GPU_VRAM_SIZE;
+
             gpu->vram[gpu->addr + (gpu->xcnt + (gpu->ycnt * 1024))] = gpu->recv_data & 0xffff;
 
             gpu->xcnt += 1;
@@ -455,6 +459,9 @@
                 gpu->ycnt += 1;
                 gpu->xcnt = 0;
             }
+
+            addr = gpu->addr + (gpu->xcnt + (gpu->ycnt * 1024));
+            addr %= PSX_GPU_VRAM_SIZE;
 
             gpu->vram[gpu->addr + (gpu->xcnt + (gpu->ycnt * 1024))] = gpu->recv_data >> 16;
 
--- a/psx/dev/ram.c
+++ b/psx/dev/ram.c
@@ -22,26 +22,38 @@
 }
 
 uint32_t psx_ram_read32(psx_ram_t* ram, uint32_t offset) {
+    offset &= 0x1fffff;
+
     return *((uint32_t*)(ram->buf + offset));
 }
 
 uint16_t psx_ram_read16(psx_ram_t* ram, uint32_t offset) {
+    offset &= 0x1fffff;
+
     return *((uint16_t*)(ram->buf + offset));
 }
 
 uint8_t psx_ram_read8(psx_ram_t* ram, uint32_t offset) {
+    offset &= 0x1fffff;
+
     return ram->buf[offset];
 }
 
 void psx_ram_write32(psx_ram_t* ram, uint32_t offset, uint32_t value) {
+    offset &= 0x1fffff;
+
     *((uint32_t*)(ram->buf + offset)) = value;
 }
 
 void psx_ram_write16(psx_ram_t* ram, uint32_t offset, uint16_t value) {
+    offset &= 0x1fffff;
+
     *((uint16_t*)(ram->buf + offset)) = value;
 }
 
 void psx_ram_write8(psx_ram_t* ram, uint32_t offset, uint8_t value) {
+    offset &= 0x1fffff;
+
     ram->buf[offset] = value;
 }
 
--- a/psx/dev/ram.h
+++ b/psx/dev/ram.h
@@ -6,9 +6,11 @@
 #include "../log.h"
 #include "mc2.h"
 
-#define PSX_RAM_SIZE    0x200000
+//#define PSX_RAM_SIZE    0x200000
+#define PSX_RAM_SIZE    0x1f000000
 #define PSX_RAM_BEGIN   0x00000000
-#define PSX_RAM_END     0x001fffff
+//#define PSX_RAM_END     0x001fffff
+#define PSX_RAM_END     0x1effffff
 
 typedef struct {
     uint32_t io_base, io_size;
--- a/psx/dev/timer.c
+++ b/psx/dev/timer.c
@@ -63,6 +63,8 @@
 
     log_fatal("Unhandled 32-bit TIMER read at offset %08x", offset);
 
+    exit(1);
+
     return 0x0;
 }
 
@@ -84,6 +86,8 @@
 
     log_fatal("Unhandled 16-bit TIMER read at offset %08x", offset);
 
+    exit(1);
+    
     return 0x0;
 }
 
@@ -90,6 +94,8 @@
 uint8_t psx_timer_read8(psx_timer_t* timer, uint32_t offset) {
     log_fatal("Unhandled 8-bit TIMER read at offset %08x", offset);
 
+    exit(1);
+
     return 0x0;
 }
 
@@ -112,9 +118,13 @@
     }
 
     log_fatal("Unhandled 32-bit TIMER write at offset %08x (%02x)", offset, value);
+
+    exit(1);
 }
 
 void psx_timer_write16(psx_timer_t* timer, uint32_t offset, uint16_t value) {
+    return;
+
     int index = offset >> 4;
     int reg = offset & 0xf;
 
@@ -135,10 +145,14 @@
     }
 
     log_fatal("Unhandled 16-bit TIMER write at offset %08x (%02x)", offset, value);
+
+    exit(1);
 }
 
 void psx_timer_write8(psx_timer_t* timer, uint32_t offset, uint8_t value) {
     log_fatal("Unhandled 8-bit TIMER write at offset %08x (%02x)", offset, value);
+
+    exit(1);
 }
 
 void timer_update_timer0(psx_timer_t* timer, int cyc) {
--