I know some of the answers about VRAM reads, as I've done a lot of hardware tests on port access and FIFO behaviour on the VDP. Here's what I can say from my testing:
-VRAM reads are moved through the same 4-word FIFO as VRAM writes.
-When a VRAM read is requested via a control port write, the read is pre-cached in the oldest entry in the FIFO. IE, if four words are written to the VRAM, 0x1111, 0x2222, 0x3333, 0x4444, and a VRAM read follows, the data read will use the FIFO buffer entry which previously held the 0x1111 value.
-Note that the FIFO is a ring-buffer, not a stack. If two writes are made to VRAM, the FIFO will be advanced two positions, regardless of whether both writes were held in the FIFO at once, or if the first write was moved out of the FIFO before the second write was made.
-Since a VRAM read uses the oldest entry in the FIFO to cache the read data, a VRAM read can only be setup if the FIFO is empty, otherwise the VDP wouldn't know which slot to retrieve the cached data from if the FIFO was advanced.
-If the FIFO is not empty when a control port write is made to setup a VRAM read operation, I'm currently not sure if the VDP stalls the write to the control port, or if the VDP stalls the read from the control port until the first byte of the read has been pre-cached. Either way, all writes are committed before the read is processed.
-Note that when performing a VRAM read from CRAM or VSRAM, only the valid bits from those memory buffers are set in the FIFO buffer entry being used to cache the read. The previous state of the unused bits retain their previous values. It's possible to use this phenomenon to observe the way the VDP uses the FIFO, since some bits of the FIFO buffer can be read without updating their contents. Here is the 16-bit mask for the valid bits in the CRAM buffer: 0000 1110 1110 1110. And here is the 16-but mask for the valid bits in the VSRAM buffer: 0000 0111 1111 1111.
A couple more questions I can answer:
1) Does setting the code to a write command (0x01, 0x03, 0x05) and then doing a read actually set VRAM,CRAM,VSRAM to some junk value? Can be easily tested
Reads can only be performed from the following command values:
0000b : VRAM read
0100b : VSRAM read
1000b : CRAM read
1100b : *8-bit VRAM read (see notes)
The last setting performs a normal read from VRAM, except that the upper 8 bits are forced to 0. In other words, the lower byte returns the same value as a normal VRAM read, while the upper 8 bits always return 0. Reads from any other targets cause the VDP to completely lock up. Resetting the console from this state has no effect, it needs to be power-cycled to restore the VDP.
2) Does setting the code to a read command and then doing a write set the internal read buffer? (Z80 read could prove this)
The VDP uses the 4-word FIFO to cache read data. Performing a write to an invalid write target (such as a read target) does write the data to the FIFO, but it doesn't get written anywhere. IE, the data is written to the FIFO, but the actual write is ignored.