Open sikthehedgehog opened 1 month ago
Edited first post because I just realized the notes talked about bit 1 when it really meant bit 0. Doesn't really change the situation though, but leaving it here for those getting email notifications.
Looks like there's no inversion at all, the VRAM address is just used as-is. What seems to be going on however is byteswapping, giving the impression that the bottom bit is flipped.
It makes sense in hindsight:
This leaves the question about how does this work with the Z80 in SMS mode, or with mode 4 in MD mode. Also, it seems like DMA fill and DMA copy may expose this discrepancy when autoincrement is larger than 1.
Well, screw me:
(w275 ? { l35[16:1], ~l35[0] } : 17'h1ffff) &
…or so I thought.
l35
holds the current VRAM address (!!) and it comes from the FIFO/DMA block, so at a glance it would seem like the VDP is indeed inverting the address LSB all along, just not where expected. But look where l35
actually comes from:
ym_slatch #(.DATA_WIDTH(17)) sl35(.MCLK(MCLK), .en(w299), .inp(vram_address), .val(l35));
ym_slatch #(.DATA_WIDTH(17)) sl36(.MCLK(MCLK), .en(w294), .inp(reg_data_l2), .val(l36));
ym_slatch #(.DATA_WIDTH(17)) sl37(.MCLK(MCLK), .en(w293), .inp(reg_data_l2), .val(l37));
ym_slatch #(.DATA_WIDTH(17)) sl38(.MCLK(MCLK), .en(w292), .inp(reg_data_l2), .val(l38));
ym_slatch #(.DATA_WIDTH(17)) sl39(.MCLK(MCLK), .en(w291), .inp(reg_data_l2), .val(l39));
l36
to l39
are the VRAM address in the FIFO entries. This means that l35
is likely the address used by DMA copy (which by-passes the FIFO), which would mean that the LSB inversion is exclusive to DMA. Considering how DMA doesn't let you specify the write size, it would make sense that they apply this kludge there. It also explains why it doesn't bother to check with mode 4, since DMA doesn't work there.
In short: what I've reported before about the FIFO writes being little endian still seems to be true, but now we know how it's dealt with when the FIFO is by-passed.
According to kabuto's notes, VRAM address bit 0 is inverted in mode 5 64K:
EDIT: he meant address bit 0, argh
Emulating this properly is also required to prevent glitches in Road Rash during a mid-screen write.
The problem is… VDP doesn't seem to be inverting that bit in the circuit that scrambles the address bits.
and then that's used inw1010
takes address bit 0 as-is (when in mode 5), that's passed tow1011
intact,w1012
in 64KB mode. The only stuff after that is latching the result and muxing to determine which set of bits goes on the bus.~~EDIT: I'm dumb and the doc actually meant address bit 0 all this time… but that one is still used as-is right in
w1012
, so the point stands.So the VDP doesn't seem to be inverting it, despite the fact that we seemingly have proof to the contrary. We need to figure out what is it doing that leads to a similar effect. My guess would be that it's done at the CPU interface level? Or we have the wrong idea of what are the "upper" and "lower" bytes for the VDP?