+static void psxBios_EnqueueCdIntr_(void)
+{
+ u32 *ram32 = (u32 *)psxM;
+
+ // traps should already be installed by write_chain()
+ ram32[0x91d0/4] = 0;
+ ram32[0x91d4/4] = SWAP32(0xbfc0506c);
+ ram32[0x91d8/4] = SWAP32(0xbfc04dec);
+ psxBios_SysEnqIntRP_(0, 0x91d0);
+ ram32[0x91e0/4] = 0;
+ ram32[0x91e4/4] = SWAP32(0xbfc050a4);
+ ram32[0x91e8/4] = SWAP32(0xbfc04fbc);
+ psxBios_SysEnqIntRP_(0, 0x91e0);
+ use_cycles(31);
+}
+
+static void setup_cd_irq_and_events(void)
+{
+ u16 specs[] = { 0x10, 0x20, 0x40, 0x80, 0x8000 };
+ size_t i;
+
+ psxBios_EnqueueCdIntr_();
+
+ for (i = 0; i < sizeof(specs) / sizeof(specs[0]); i++) {
+ u32 h = OpenEvent(0xf0000003, specs[i], EvMdMARK, 0);
+ // no error checks
+ storeRam32(A_CD_EVENTS + i * 4, h);
+ EnableEvent(h, 0);
+ }
+}
+
+static void psxBios_CdReset_() {
+ psxRegs.CP0.n.SR &= ~0x404; // disable interrupts
+
+ cdrom_sync(1);
+ cdrWrite0(1);
+ cdrWrite2(0x1f); // unmask
+ cdrom_cmd_and_wait(0x0a, 0, 2); // CdlReset
+ cdrom_cmd_and_wait(0x0e, 1, 1, 0x80u); // CdlSetmode
+
+ // todo(?): should read something (iso root directory?)
+ // from { 0, 2, 16 } to somewhere and pause
+
+ mips_return(1);
+ psxHwWrite16(0x1f801070, ~4);
+ MTC0(&psxRegs, 12, psxRegs.CP0.n.SR | 0x404);
+ DeliverEvent(0xf0000003, 0x0020);
+}
+
+static void psxBios_CdInit() { // 54, 71
+ PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x71]);
+ setup_cd_irq_and_events();
+
+ psxBios_CdReset_();
+
+ // this function takes pretty much forever
+ mips_return_c(0, 50000*11);
+}
+