diff --git a/cdrom.jam b/cdrom.jam index a7bb845..867e031 100644 --- a/cdrom.jam +++ b/cdrom.jam @@ -142,12 +142,6 @@ pub const Cdrom = struct { pendingSpeedSwitch: u32, // psxe pending_speed_switch_delay (1x<->2x resync) dataRidx: u32, dataWidx: u32, - // TEMP FMV probe: handleRead calls / XA-audio-filtered / INT1-delivered / - // FIFO-drained reads (readData hit rIdx>=wIdx -> returned 0 = underflow). - dbgHr: u32, - dbgXa: u32, - dbgInt1: u32, - dbgDrain: u32, // XA-ADPCM per-channel history (2 i32 each). Persists across // sectors so block-N's predictor sees block-(N-1)'s tail. xaLh: [2]i32, @@ -177,7 +171,6 @@ pub const Cdrom = struct { // so 0 would read a negative offset (zero pregap), not sector 0. delay: 0, lba: 150, pendingLba: 150, pendingSpeedSwitch: 0, dataRidx: 0, dataWidx: 0, - dbgHr: 0, dbgXa: 0, dbgInt1: 0, dbgDrain: 0, xaLh: [0, 0], xaRh: [0, 0], paramFifo: [0; 32], @@ -882,7 +875,6 @@ pub const Cdrom = struct { } pub fn handleRead(self: mut Self, disc: *mut[] Disc, spu: *mut[] u8) { - self.dbgHr = self.dbgHr + 1; self.processSetloc(); if (self.hasDisc == 0) { // psxe reports no-disc as SHELLOPEN (0x10), giving INT5(11h,80h) @@ -909,7 +901,6 @@ pub const Cdrom = struct { const submode: u32 = self.dataBuf[18] as u32; const isXaAudio: bool = (submode & 0x04) != 0 && (submode & 0x40) != 0; if ((self.mode as u32 & MODE_XA_ADPCM) != 0 && isXaAudio) { - self.dbgXa = self.dbgXa + 1; self.tryDecodeXa(spu); // SPU CD-audio; fall through to deliver INT1 } @@ -923,7 +914,6 @@ pub const Cdrom = struct { self.dataWidx = wEnd; self.ifr = 1; - self.dbgInt1 = self.dbgInt1 + 1; self.pushResp(self.getStat()); self.pendingLba = lba + 1; // psxe cdrom_handle_read: deferred via pending_lba, lba promoted on next process_setloc (GetLocL/P returns current sector, not next) @@ -983,37 +973,12 @@ pub const Cdrom = struct { return discRead(disc, lba, self.dataBuf.asMutPtr()); } - // Debug: expose read position + packed state so the FMV probe can - // tell whether the drive is actively streaming sectors or idle. - pub fn dbgLba(self: mut Self) u32 { return self.lba; } - pub fn dbgInfo(self: mut Self) u32 { - return (self.state as u32) - | ((self.readOngoing as u32) << 8) - | ((self.mode as u32) << 16) - | ((self.ifr as u32) << 24); - } - // TEMP FMV probe getters: handleRead calls / XA-filtered / INT1-delivered. - pub fn dbgHrCount(self: mut Self) u32 { return self.dbgHr; } - pub fn dbgXaCount(self: mut Self) u32 { return self.dbgXa; } - pub fn dbgInt1Count(self: mut Self) u32 { return self.dbgInt1; } - pub fn dbgDrainCount(self: mut Self) u32 { return self.dbgDrain; } - // TEMP: pack FIFO state — dataReq(bit28) | dataWidx(<<12) | dataRidx. - pub fn dbgFifo(self: mut Self) u32 { - return self.dataRidx | (self.dataWidx << 12) | ((self.dataReq as u32) << 28); - } - // TEMP CD-state trace: the delay countdown, and pending cmd | prevState. - pub fn dbgDelay(self: mut Self) u32 { return self.delay; } - pub fn dbgPend(self: mut Self) u32 { - return (self.pendingCmd as u32) | ((self.prevState as u32) << 8) - | ((self.busy as u32) << 16); - } - // Read one byte from the data FIFO (the 0x1F801802 register). pub fn readData(self: mut Self) u32 { if (self.dataReq == 0) { return 0; } var rIdx: u32 = self.dataRidx; const wIdx: u32 = self.dataWidx; - if (rIdx >= wIdx) { self.dbgDrain = self.dbgDrain + 1; return 0; } + if (rIdx >= wIdx) { return 0; } const v: u8 = self.dataBuf[rIdx]; self.dataRidx = rIdx + 1; return v as u32; diff --git a/cpu.jam b/cpu.jam index 9de1b71..5ea1c7f 100644 --- a/cpu.jam +++ b/cpu.jam @@ -63,8 +63,6 @@ const Cpu = struct { diagDumped: u32, diagExcCount: u32, diagWalkCount: u32, - // TEMP FMV probe: last BIOS call, vector id in high byte function in low. - lastBiosCall: u32, }; // COP0 register indices. @@ -121,7 +119,6 @@ pub fn freshCpu() Cpu { branch: 0, delaySlot: 0, branchTaken: 0, halted: 0, cycles: 0, diagDumped: 0, diagExcCount: 0, diagWalkCount: 0, - lastBiosCall: 0, }; return c; } @@ -1177,11 +1174,6 @@ pub fn step(c: mut Cpu, bus: Bus, regs: *mut[] u32, cop0: *mut[] u32) { raiseException(c, cop0, CAUSE_IBE); return; } - // TEMP FMV probe: capture BIOS calls (A0/B0/C0 vectors) + the function - // number in $t1 ($9). vector_id: 1=A0 2=B0 3=C0. - if (pcPhys == 0xA0) { c.lastBiosCall = 0x100 | (gprRead(regs, 9) & 0xFF); } - else if (pcPhys == 0xB0) { c.lastBiosCall = 0x200 | (gprRead(regs, 9) & 0xFF); } - else if (pcPhys == 0xC0) { c.lastBiosCall = 0x300 | (gprRead(regs, 9) & 0xFF); } // Take an external interrupt before issuing the next instruction — // matches psxe's check at the top of psx_cpu_cycle, after fetch and diff --git a/dma.jam b/dma.jam index 936e104..c4b0a05 100644 --- a/dma.jam +++ b/dma.jam @@ -30,9 +30,8 @@ const SPU_TFIFO_OFF: u32 = 0x1A8; // channel stay "busy" while the test polls CHCR — ps1-tests // spu/memory-transfer testDMAWriteTiming asserts that the // transfer is observable in-flight (loopCount > 0). -const DMA_STATE_WORDS: u32 = 39; // [32]=CD-DMA cnt [33]=STR-magic cnt [34]=last hdr [35]=CD sync [36]=CD BCR [37]=STR word1 [38]=STR word2 (TEMP FMV probe) +const DMA_STATE_WORDS: u32 = 30; const F_SPU_REMAIN: u32 = 29; -// TEMP FMV probe: d[30]=mdecIn call count, d[31]=mdecOut call count. const F_MADR: u32 = 0; const F_BCR: u32 = 1; @@ -324,7 +323,6 @@ pub fn dmaDoMdecIn(d: *mut[] u32, bus: Bus) { d[chBase(0) + F_CHCR] = 0; d[chBase(0) + F_BCR] = 0; d[23] = size; - d[30] = d[30] + 1; // TEMP FMV probe: MDEC-in DMA fire count } // DMA1: MDEC output port → RAM. Match psxe exactly (dma.c:208-235). @@ -344,7 +342,6 @@ pub fn dmaDoMdecOut(d: *mut[] u32, bus: Bus) { d[chBase(1) + F_CHCR] = 0; d[chBase(1) + F_BCR] = 0; d[24] = size; - d[31] = d[31] + 1; // TEMP FMV probe: MDEC-out DMA fire count } // CD-ROM → RAM transfer. Each "word" in BCR.size is 4 bytes from the @@ -367,27 +364,15 @@ pub fn dmaDoCdrom(d: *mut[] u32, bus: Bus) { 1 { size = bcrSize(d, 3) * bcrBlocks(d, 3); } _ { return; } } - // TEMP FMV probe: CD DMA sync mode + raw BCR (blocksize | blocks<<16). - d[35] = chcrSync(d, 3); - d[36] = d[chBase(3) + F_BCR]; var addr: u32 = d[chBase(3) + F_MADR]; const step: u32 = chcrStep(d, 3); var i: u32 = 0; - var capVid: u32 = 0; // TEMP: this DMA's sector is an STR video sector while (i < size) { const b0: u32 = bus.cdrom.readData(); const b1: u32 = bus.cdrom.readData(); const b2: u32 = bus.cdrom.readData(); const b3: u32 = bus.cdrom.readData(); const w: u32 = b0 | (b1 << 8) | (b2 << 16) | (b3 << 24); - if (i == 0) { // TEMP FMV probe: STR header word of each read sector - d[34] = w; - if ((w & 0xFFFF) == 0x0160) { d[33] = d[33] + 1; capVid = 1; } - } - // TEMP: STR frame header words 1 (chunkNo|chunksInFrame) and 2 of - // the last video sector — to see whether frame assembly can complete. - if (capVid != 0 && i == 1) { d[37] = w; } - if (capVid != 0 && i == 2) { d[38] = w; } ramWrite32(bus, addr, w); addr = addr + step; i = i + 1; @@ -396,7 +381,6 @@ pub fn dmaDoCdrom(d: *mut[] u32, bus: Bus) { d[chBase(3) + F_CHCR] = 0; d[chBase(3) + F_BCR] = 0; d[26] = 1; - d[32] = d[32] + 1; // TEMP FMV probe: CD->RAM DMA fire count } // SPU DMA (channel 4). psxe dma.c:375-437 pipes each 32-bit word through diff --git a/main.jam b/main.jam index 264a4ff..5fad58e 100644 --- a/main.jam +++ b/main.jam @@ -101,7 +101,6 @@ const Cpu = struct { diagDumped: u32, diagExcCount: u32, diagWalkCount: u32, - lastBiosCall: u32, }; const Sdl = struct { @@ -634,7 +633,6 @@ fn main() { // the drift an integer-ms target would introduce. const FRAME_MS: f64 = 1000.0 / 59.94; var nextFrameMs: f64 = SDL_GetTicks() as f64; - var probeN: u32 = 0; // TEMP: FMV display probe rate-limiter while (!quit) { // Game-EXE side-load. Two trigger paths: // 1. BIOS jumps to 0x80030000 (real-disc boot handoff). @@ -684,132 +682,6 @@ fn main() { bus.timer.setDotclock(dm); const is24bpp: bool = (dm & 0x10) != 0; const displayOff: bool = (gpuState[46] & 0x00800000) != 0; - // TEMP FMV display probe — ~1x/sec, dump the display config + whether - // VRAM holds data at the display origin. Pinpoints "black video": - // off=1 -> display disabled (re-enable not seen) - // 24bpp=0 in FMV -> game/jamstation not in 24bpp mode - // vramNZ=0 -> frame not at (dispX,dispY): wrong origin / no upload - // vramNZ>0 + black -> 24bpp readout (sdlBlit) bug - probeN = probeN + 1; - if (probeN >= 60) { - probeN = 0; - var b24: u32 = 0; - if (is24bpp) { b24 = 1; } - var boff: u32 = 0; - if (displayOff) { boff = 1; } - const base: u32 = (dispY as u32) * 2048 + (dispX as u32) * 2; - var nz: u32 = 0; - if (base + 256 < 1048576) { - var k: u32 = 0; - while (k < 256) { - if (vram[base + k] != 0) { nz = nz + 1; } - k = k + 1; - } - } - // MDEC DMA fire counts (wired in dma.jam) + locate the VRAM row - // holding the most data (where the decoded frame actually lands). - var dmaP: *mut[] u32 = bus.dma.ptr; - const d30: u32 = dmaP[30]; - const d31: u32 = dmaP[31]; - const cdDma: u32 = dmaP[32]; // CD->RAM DMA fire count - const strMagic: u32 = dmaP[33]; // sectors read with STR magic 0x0160 - const lastHdr: u32 = dmaP[34]; // last read sector's first word - const cdSync: u32 = dmaP[35]; // CD DMA sync mode (0 burst / 1 block) - const cdBcr: u32 = dmaP[36]; // CD DMA raw BCR (blocksize | blocks<<16) - const strW1: u32 = dmaP[37]; // STR frame header word1 (chunkNo | chunksInFrame<<16) - const strW2: u32 = dmaP[38]; // STR frame header word2 - var bestY: u32 = 0; - var bestNz: u32 = 0; - var yy: u32 = 0; - while (yy < 512) { - const rb: u32 = yy * 2048; - var rnz: u32 = 0; - var j: u32 = 0; - while (j < 256) { - if (vram[rb + j] != 0) { rnz = rnz + 1; } - j = j + 1; - } - if (rnz > bestNz) { bestNz = rnz; bestY = yy; } - yy = yy + 16; - } - // MDEC status (read32 off=4 is a pure read): wordsRem (bits - // 0-15), bit27 Data-Out-Req, bit29 busy, bit31 Data-Out-empty. - // Tells us WHY DMA1 never fires: output empty (no decode) vs - // stuck waiting for input (wordsRem>0/busy) vs ready-but-ignored. - const mst: u32 = bus.mdec.read32(bus.mdecOut.ptr, 4); - const mWords: u32 = mst & 0xFFFF; - const mB27: u32 = (mst >> 27) & 1; - const mB31: u32 = (mst >> 31) & 1; - // Monotonic decode counter + last outputWords stashed by the MDEC - // at the output-buffer tail (offsets 0xFFFFC / 0xFFFF8). - var mo: *mut[] u8 = bus.mdecOut.ptr; - const decCount: u32 = (mo[0xFFFFC] as u32) | ((mo[0xFFFFD] as u32) << 8) - | ((mo[0xFFFFE] as u32) << 16) | ((mo[0xFFFFF] as u32) << 24); - const lastOW: u32 = (mo[0xFFFF8] as u32) | ((mo[0xFFFF9] as u32) << 8) - | ((mo[0xFFFFA] as u32) << 16) | ((mo[0xFFFFB] as u32) << 24); - // DECODE/SET_QT/SET_ST command-STARTED counts (op*4 @ 0xFFF00). - const cmdDec: u32 = (mo[0xFFF04] as u32) | ((mo[0xFFF05] as u32) << 8) - | ((mo[0xFFF06] as u32) << 16) | ((mo[0xFFF07] as u32) << 24); - const cmdQt: u32 = (mo[0xFFF08] as u32) | ((mo[0xFFF09] as u32) << 8) - | ((mo[0xFFF0A] as u32) << 16) | ((mo[0xFFF0B] as u32) << 24); - const cmdSt: u32 = (mo[0xFFF0C] as u32) | ((mo[0xFFF0D] as u32) << 8) - | ((mo[0xFFF0E] as u32) << 16) | ((mo[0xFFF0F] as u32) << 24); - print("FMV: 24bpp={b24} cdDma={cdDma} strMagic={strMagic} lastHdr={lastHdr} in={d30} out={d31} | cmdDecode={cmdDec} cmdQt={cmdQt} cmdSt={cmdSt} done={decCount}\n"); - // CD read pump probe: is handleRead still running during the FMV, - // and is the XA filter eating sectors? state(3=READ) / mode / - // handleRead-calls / XA-filtered / INT1-delivered. - const cdInfo: u32 = bus.cdrom.dbgInfo(); - const cdState: u32 = cdInfo & 0xFF; - const cdMode: u32 = (cdInfo >> 16) & 0xFF; - const hrN: u32 = bus.cdrom.dbgHrCount(); - const xaN: u32 = bus.cdrom.dbgXaCount(); - const i1N: u32 = bus.cdrom.dbgInt1Count(); - const drN: u32 = bus.cdrom.dbgDrainCount(); - print("CD: state={cdState} mode={cdMode} hr={hrN} xaFilt={xaN} int1={i1N} drain={drN} | sync={cdSync} bcr={cdBcr} str1={strW1} str2={strW2}\n"); - // Where is the CPU spinning during the stall, and the last BIOS - // call it made (1xx=A0 2xx=B0 3xx=C0, low byte = function number). - const pcNow: u32 = c.pc; - const biosCall: u32 = c.lastBiosCall; - print("CPU: pc={pcNow} lastBios={biosCall}\n"); - // The FMV player polls bit24 of *[0x80107DC0] and only advances - // its progress counter [0x8010BCD4] when set. Dump the register - // pointer, the value it reads, the counter, and the queue index - // [0x8010D604] to see what hardware bit it's stuck waiting on. - // STR ring/queue state: base ptr, write/read indices, the player - // state code [0x80107de8], the gate spin-counter [0x80109b2c], and - // the state field of the first 4 slots (0=empty, 1/2/4=in use). - // Shows whether the sector processor is FILLING the ring at all. - const sbase: u32 = busRead32(bus, 0x8010D6FC); - const widx: u32 = busRead32(bus, 0x8010D5F4); - const ridx: u32 = busRead32(bus, 0x8010D604); - const sstate: u32 = busRead32(bus, 0x80107DE8); - const gctr: u32 = busRead32(bus, 0x80109B2C); - const sl0: u32 = busRead32(bus, sbase) & 0xFFFF; - const sl1: u32 = busRead32(bus, sbase + 32) & 0xFFFF; - const sl2: u32 = busRead32(bus, sbase + 64) & 0xFFFF; - const sl3: u32 = busRead32(bus, sbase + 96) & 0xFFFF; - print("STR: base={sbase} w={widx} r={ridx} state={sstate} gctr={gctr} slots={sl0},{sl1},{sl2},{sl3}\n"); - // Map the producer's register-pointer table: the DMA CHCR it spin- - // waits on [0x80107dd0], and its register write targets [0x80107db0] - // / [0x80107db4] / [0x80107dc0]=DMA1CHCR. Reveals which DMA channels - // drive the pipeline (to confirm the bit24/synchronous-DMA theory). - const rdd0: u32 = busRead32(bus, 0x80107DD0); - const rdb0: u32 = busRead32(bus, 0x80107DB0); - const rdb4: u32 = busRead32(bus, 0x80107DB4); - const rda8: u32 = busRead32(bus, 0x80107DA8); - print("REG: waitCHCR={rdd0} wr0={rdb0} wr4={rdb4} rda8={rda8}\n"); - // De-interleaver ground-truth: MODE flag [0x8010d6e0], the decode - // callback ptr [0x80109eac] (0 => decode never invoked), the frame - // threshold [0x8010d6ec], and the ridx slot's header (field0=state, - // word at +4 = chunkIndex|chunksInFrame<<16). - const diMode: u32 = busRead32(bus, 0x8010D6E0); - const diCb: u32 = busRead32(bus, 0x80109EAC); - const diThr: u32 = busRead32(bus, 0x8010D6EC); - const rslot: u32 = sbase + ridx * 32; - const rsHdr0: u32 = busRead32(bus, rslot); - const rsHdr4: u32 = busRead32(bus, rslot + 4); - print("DI: mode={diMode} cb={diCb} thr={diThr} rslot0={rsHdr0} rslot4={rsHdr4}\n"); - } if (fullVram) { sdlBlit(sdl, vram, 0, 0, VRAM_WIDTH, VRAM_HEIGHT, false, displayOff); diff --git a/mcd.jam b/mcd.jam index eeb8ebc..5faaaae 100644 --- a/mcd.jam +++ b/mcd.jam @@ -73,7 +73,7 @@ pub const Mcd = struct { flag: u8, msb: u8, lsb: u8, - addr: u32, + addr: u16, pend: u16, checksum: u8, pad: [16]u8, @@ -109,101 +109,101 @@ pub const Mcd = struct { // Returns the byte the host should latch into SIO0's RX register. pub fn read(self: mut Self, ram: *mut[] u8) u32 { const st: u32 = self.state as u32; - if (st == MCD_TX_HIZ) { - self.txData = 0xFF; - } else if (st == MCD_TX_FLG) { - // psxe patch: if the host's last RX was 0x81/0x01 the card - // bails out — game-side probe code expects 0xFF when it - // tries to ping us by sending the dest byte twice. - const rx: u32 = self.rxData as u32; - if (rx == 0x81 || rx == 0x01) { + match (st) { + MCD_TX_HIZ { self.txData = 0xFF; } + MCD_TX_FLG { + // psxe patch: if the host's last RX was 0x81/0x01 the card + // bails out — game-side probe code expects 0xFF when it + // tries to ping us by sending the dest byte twice. + const rx: u32 = self.rxData as u32; + if (rx == 0x81 || rx == 0x01) { + self.txReady = 1; + self.txData = 0xFF; + self.state = MCD_TX_HIZ as u8; + return 0xFF; + } + self.txData = self.flag; + self.flag = 0; // "first access" flag is one-shot + } + MCD_TX_ID1 { self.txData = 0x5A; } + MCD_TX_ID2 { + // Choose subprotocol based on the mode byte the host sent + // earlier. self.txReady = 1; - self.txData = 0xFF; - self.state = MCD_TX_HIZ as u8; - return 0xFF; + self.txData = 0x5D; + const m: u32 = self.mode as u32; + if (m == 0x52) { // 'R' = read + self.state = MCD_R_RX_MSB as u8; + } else if (m == 0x57) { // 'W' = write + self.state = MCD_W_RX_MSB as u8; + } else if (m == 0x53) { // 'S' = status + self.state = MCD_S_TX_ACK1 as u8; + } else { + // Unknown mode — drop the slot. + self.txReady = 0; + self.txData = 0xFF; + self.state = MCD_TX_HIZ as u8; + } + return self.txData as u32; + } + MCD_R_RX_MSB { self.txData = 0x00; } + MCD_R_RX_LSB { self.txData = self.msb; } + MCD_R_TX_ACK1 { self.txData = 0x5C; } + MCD_R_TX_ACK2 { self.txData = 0x5D; } + MCD_R_TX_MSB { + self.txData = self.msb; + self.checksum = self.msb; + } + MCD_R_TX_LSB { + self.txData = self.lsb; + self.checksum = self.checksum ^ self.lsb; + self.pend = 128; + } + MCD_R_TX_DATA { + const pend: u32 = self.pend as u32; + const addr: u32 = self.addr as u32; + const b: u8 = ram[addr]; + self.addr = (addr + 1) as u16; + self.checksum = self.checksum ^ b; + self.pend = (pend - 1) as u16; + if (pend - 1 == 0) { + self.txData = b; + } else { + return b as u32; + } } - self.txData = self.flag; - self.flag = 0; // "first access" flag is one-shot - } else if (st == MCD_TX_ID1) { - self.txData = 0x5A; - } else if (st == MCD_TX_ID2) { - // Choose subprotocol based on the mode byte the host sent - // earlier. - self.txReady = 1; - self.txData = 0x5D; - const m: u32 = self.mode as u32; - if (m == 0x52) { // 'R' = read - self.state = MCD_R_RX_MSB as u8; - } else if (m == 0x57) { // 'W' = write - self.state = MCD_W_RX_MSB as u8; - } else if (m == 0x53) { // 'S' = status - self.state = MCD_S_TX_ACK1 as u8; - } else { - // Unknown mode — drop the slot. + MCD_R_TX_CHK { self.txData = self.checksum; } + MCD_R_TX_MEB { self.txReady = 0; - self.txData = 0xFF; self.state = MCD_TX_HIZ as u8; + return 0x47; // 'G' = good end marker } - return self.txData as u32; - } else if (st == MCD_R_RX_MSB) { - self.txData = 0x00; - } else if (st == MCD_R_RX_LSB) { - self.txData = self.msb; - } else if (st == MCD_R_TX_ACK1) { - self.txData = 0x5C; - } else if (st == MCD_R_TX_ACK2) { - self.txData = 0x5D; - } else if (st == MCD_R_TX_MSB) { - self.txData = self.msb; - self.checksum = self.msb; - } else if (st == MCD_R_TX_LSB) { - self.txData = self.lsb; - self.checksum = self.checksum ^ self.lsb; - self.pend = 128; - } else if (st == MCD_R_TX_DATA) { - const pend: u32 = self.pend as u32; - const addr: u32 = self.addr as u32; - const b: u8 = ram[addr]; - self.addr = addr + 1; - self.checksum = self.checksum ^ b; - self.pend = (pend - 1) as u16; - if (pend - 1 == 0) { - self.txData = b; - } else { - return b as u32; + MCD_W_RX_MSB { self.txData = 0x00; } + MCD_W_RX_LSB { + self.txData = self.msb; + self.pend = 128; } - } else if (st == MCD_R_TX_CHK) { - self.txData = self.checksum; - } else if (st == MCD_R_TX_MEB) { - self.txReady = 0; - self.state = MCD_TX_HIZ as u8; - return 0x47; // 'G' = good end marker - } else if (st == MCD_W_RX_MSB) { - self.txData = 0x00; - } else if (st == MCD_W_RX_LSB) { - self.txData = self.msb; - self.pend = 128; - } else if (st == MCD_W_RX_DATA) { - const pend: u32 = self.pend as u32; - const addr: u32 = self.addr as u32; - ram[addr] = self.rxData; - self.addr = addr + 1; - self.pend = (pend - 1) as u16; - if (pend - 1 == 0) { - self.txData = self.rxData; - } else { - return self.rxData as u32; + MCD_W_RX_DATA { + const pend: u32 = self.pend as u32; + const addr: u32 = self.addr as u32; + ram[addr] = self.rxData; + self.addr = (addr + 1) as u16; + self.pend = (pend - 1) as u16; + if (pend - 1 == 0) { + self.txData = self.rxData; + } else { + return self.rxData as u32; + } } - } else if (st == MCD_W_RX_CHK || st == MCD_W_RX_CHK2) { - self.txData = self.rxData; - } else if (st == MCD_W_TX_ACK1) { - self.txData = 0x5C; - } else if (st == MCD_W_TX_ACK2) { - self.txData = 0x5D; - } else if (st == MCD_W_TX_MEB) { - self.txReady = 0; - self.state = MCD_TX_HIZ as u8; - return 0x47; + MCD_W_RX_CHK | MCD_W_RX_CHK2 { self.txData = self.rxData; } + MCD_W_TX_ACK1 { self.txData = 0x5C; } + MCD_W_TX_ACK2 { self.txData = 0x5D; } + MCD_W_TX_MEB { + self.txReady = 0; + self.state = MCD_TX_HIZ as u8; + return 0x47; + } + _ { } } self.txReady = 1; self.state = (self.state + 1) as u8; @@ -216,18 +216,15 @@ pub const Mcd = struct { const d: u8 = (data & 0xFF) as u8; self.rxData = d; const st: u32 = self.state as u32; - if (st == MCD_TX_FLG) { - self.mode = d; - } else if (st == MCD_R_RX_MSB || st == MCD_W_RX_MSB) { - self.msb = d; - } else if (st == MCD_R_RX_LSB) { - self.lsb = d; - const a: u32 = ((self.msb as u32) << 8) | (d as u32); - self.addr = (a & 0x3FF) << 7; - } else if (st == MCD_W_RX_LSB) { - self.lsb = d; - const a: u32 = ((self.msb as u32) << 8) | (d as u32); - self.addr = (a & 0x3FF) << 7; + match (st) { + MCD_TX_FLG { self.mode = d; } + MCD_R_RX_MSB | MCD_W_RX_MSB { self.msb = d; } + MCD_R_RX_LSB | MCD_W_RX_LSB { + self.lsb = d; + const a: u32 = ((self.msb as u32) << 8) | (d as u32); + self.addr = (a << 7) as u16; + } + _ { } } } }; diff --git a/mdec.jam b/mdec.jam index f39fa72..1d28442 100644 --- a/mdec.jam +++ b/mdec.jam @@ -311,10 +311,6 @@ pub const Mdec = struct { } self.outputWords = outBytes / 4; - // TEMP FMV probe: monotonic decode counter + last outputWords stashed - // at the tail of the 1 MB output buffer (a frame is <256 KB, no clash). - writeU32(output, 0xFFFFC, readU32(output, 0xFFFFC) + 1); - writeU32(output, 0xFFFF8, self.outputWords); self.outputEmpty = 0; self.outputIndex = 0; } @@ -461,9 +457,6 @@ pub const Mdec = struct { self.inputFull = 0; self.busy = 1; const op: u32 = (val >> 29) & 7; - // TEMP FMV probe: count command words started, per op, at the - // output-buffer tail (0xFFF00 + op*4). cmd[1]=DECODE started. - writeU32(output, 0xFFF00 + op * 4, readU32(output, 0xFFF00 + op * 4) + 1); var newWords: u32 = 0; if (op == MDEC_CMD_NOP) { self.busy = 0; diff --git a/tests.jam b/tests.jam index a7c27b7..b8e1f27 100644 --- a/tests.jam +++ b/tests.jam @@ -65,7 +65,6 @@ const Cpu = struct { diagDumped: u32, diagExcCount: u32, diagWalkCount: u32, - lastBiosCall: u32, }; diff --git a/timer.jam b/timer.jam index bd0d0b9..86c2c46 100644 --- a/timer.jam +++ b/timer.jam @@ -258,12 +258,6 @@ pub const Timer = struct { self.updateCyc(ic, cop0, 2); } - // TEMP REG_TRACE: truncated counter (as the game reads it) for the - // psxe divergence diff, to pin which timer's value drifts. - pub fn dbgTimerCounter(self: mut Self, i: u32) u32 { - return self.channels[i].counter as u32; - } - pub fn updateCyc(self: mut Self, ic: *mut[] u32, cop0: *mut[] u32, cyc: u32) { // psxe's psx_timer_update (timer.c:338-345) IGNORES its cyc arg and