I can't tell if this is a bug or intended and I have to work around it.
I've set both the data lines to auto increment, just read from 0 and write to 1
here is the step by step of the values:
VRAM:
0000: FF 00 00 00
Data0 addr: 0000
Data1 addr: 0001
Data0: FF
Data1: 00
-----------------
Read Data0
-----------------
VRAM:
0000: FF 00 00 00
Data0 addr: 0001
Data1 addr: 0001
Data0: 00
Data1: 00
-----------------
Write Data1
-----------------
VRAM:
0000: FF FF 00 00
Data0 addr: 0001
Data1 addr: 0002
Data0: 00 <- Previous Value, not VRAM 0002 Value: Why is this not FF?
Data1: 00
It's like the values are latched after reads, which may be intended.
but the docs say "the data on that VRAM address can be read from or written to via the DATA0/1 register"
I took that as it would read from VRAM and not some stored value, IDK.
VERA behavior
Re: VERA behavior
The last time I checked the verilog code for the VERA (which admittedly was a while ago so I might be wrong), the way the ports worked was, anytime the address is updated, the value at that address is latched, and that latched value is what you get when you read the port.
So, when reading, you don't get the "current" value, you instead get whatever value was there at the time the address of the port was updated, and you just happened to stumble on the one situation where this strategy causes a problem.
So, when reading, you don't get the "current" value, you instead get whatever value was there at the time the address of the port was updated, and you just happened to stumble on the one situation where this strategy causes a problem.
Re: VERA behavior
Thanks for the input
So is this how the hardware works too or an emulator optimization?
Why is that not documented? I wasted alot of time tracking down the issue.
So is this how the hardware works too or an emulator optimization?
Why is that not documented? I wasted alot of time tracking down the issue.
Re: VERA behavior
I don't think it's an emulator optimization. A read is a read and takes X cycles now or somewhere down the line. Yes, there should be some tiny gain if memory is read immediately after incrementing the address just because the address (or in the case of the emulator, an offset into the VERA memory buffer) is already present in a register, but I doubt that was the reasoning.
It's probably a hardware optimization because the reads from VERA's memory have to be divided between the VERA "renderer" and the machine (X16 in this case). I think latching the contents of the memory address upon updating the address register makes it easier to organize memory read accesses, so that upon reading the data register, the result is immediately available, instead of possibly having to wait for the next free memory read cycle. And since VERA internally runs at 25MHz, and 6502 needs a few cycles to fetch and decode the next LD(A/X/Y) instruction, there's plenty of time to latch that value into the data register so that it's immediately available for the next read.
In any case, the emulator should closely follow the hardware, not the other way around
It's probably a hardware optimization because the reads from VERA's memory have to be divided between the VERA "renderer" and the machine (X16 in this case). I think latching the contents of the memory address upon updating the address register makes it easier to organize memory read accesses, so that upon reading the data register, the result is immediately available, instead of possibly having to wait for the next free memory read cycle. And since VERA internally runs at 25MHz, and 6502 needs a few cycles to fetch and decode the next LD(A/X/Y) instruction, there's plenty of time to latch that value into the data register so that it's immediately available for the next read.
In any case, the emulator should closely follow the hardware, not the other way around
Re: VERA behavior
It's how the VERA itself was designed.
The VERA needs periodic access to its RAM as part of rendering the screen, so blocking the RAM off while the CPU is accessing one of the ports would cause visual glitches, kinda like the "snow" on earlier CGA cards.
The way it caches the byte after the address changes gives enough time for the VERA to sneak the cache fetch in before the CPU can finish decoding and executing its next opcode, which may be a read from that port.
Then, when the CPU reads the port, the cached byte's ready to go, the correct bus timing can be achieved, and it doesn't interrupt rendering (no visual glitches!).
Since the data ports are the only things that can modify VERA RAM (AFAIK), that cached byte will be correct most of the time, and the times where it isn't are predictable (i.e., when one data port overwrites the value at the address the other port is pointing to).
And I agree, if this caching behavior isn't already noted in the documentation, it should be added, assuming this is still how the VERA works.
The VERA needs periodic access to its RAM as part of rendering the screen, so blocking the RAM off while the CPU is accessing one of the ports would cause visual glitches, kinda like the "snow" on earlier CGA cards.
The way it caches the byte after the address changes gives enough time for the VERA to sneak the cache fetch in before the CPU can finish decoding and executing its next opcode, which may be a read from that port.
Then, when the CPU reads the port, the cached byte's ready to go, the correct bus timing can be achieved, and it doesn't interrupt rendering (no visual glitches!).
Since the data ports are the only things that can modify VERA RAM (AFAIK), that cached byte will be correct most of the time, and the times where it isn't are predictable (i.e., when one data port overwrites the value at the address the other port is pointing to).
And I agree, if this caching behavior isn't already noted in the documentation, it should be added, assuming this is still how the VERA works.
Re: VERA behavior
Thanks for the explanations
I was implementing an unpacker for LZ4 in VRAM, which copies data and then uses a delta offset to copy previous data.
I turn off incrementing when the delta is 1, and appears to be working now.
I was implementing an unpacker for LZ4 in VRAM, which copies data and then uses a delta offset to copy previous data.
I turn off incrementing when the delta is 1, and appears to be working now.