I may be tired, I may be a 6502 noob... But I'm also VERY perplexed now.
The two snippets of code you see in the picture work differently.
The top one, currently commented, always consistently produce the correct result.
The one below, consistently produces garbage on the VDP, setting the wrong color or nothing at all.
@hkz C0Cx on the commented code, C08x on the constants?
@hkz (I have never written 6502 in my life so this is just a visual difference, no clue if there's anything functionally different here)
@gsuberland Absolute addressing, 0x40 in X gets added to the C08x constant, resulting in C0Cx ... Ideally.
@hkz oh, right, ldx. missed that lol
@hkz I'm not quite sure either. Could be something to do with macro expansion?
Could be the order in which the symbols are being interned by the macro processor?
What assembler are you using?
- replies
- 1
- announces
- 0
- likes
- 1
@vidak Calypsi toolchain, but I did try to just add an .equ of VDP_REG to 0xC081, same issue.
Also, I checked the resulting binary, it expanded the macro correctly to C081.
@hkz is it the right syntax for absolute addressing?
Sorry for questioning you, I used a fucked up 32 bit binary off the Atariage forums when I coded 6502... π
@vidak should be the right one. Wrote a full SD card SPI driver using that syntax...
@hkz I think it's something to do with that LDX before the whole codeblock.
Put the LDX before the commented , working code?
See if same error now?
@vidak working code keeps working regardless of the ldx
@hkz Two thoughts; a) The broken version I think is longer, is there space b) Those indexed sta's take an extra cycle each - I wonder if that's relevant at all?
@hkz could it be using zero page addressing in the VDP_REG case on the STA instruction? What does the STA instruction translate to in the binary?
"The address calculation wraps around if the sum of the base address and the register exceed $FF. "
@arnowi Nope, it translates to 9D 81 C0... but Vertigo just added an answer to my query explaining what most probably is the issue!
As I don't seem to be able to link it, I'll copy-paste it here:
---
The problem is that there is an implied read cycle in the evaluation of (address + X). The 6502 does NOT have idle bus cycles, so all cycles that are considered idle are expressed on the bus as read cycles. [...SNIP...]
More likely than not, the VDP is interpreting the read cycle, and by the time you write to the VDP, its internal state machine is no longer in sync with what your application expects.
@hkz π well, that sucks. Makes sense thoughβ¦ I think
@arnowi it does. The VDP has a state machine: reads and writes must be done in a specific sequence, if it picks an out of sequence read, it breaks
@hkz I have no experience with 6502s and VDPs. EEPROMs on SPI sometimes have finicky internal state machines. Usually solved with a reset or so π
@penguin42 as vertigo mentioned in one of their replies, it's probably the dummy read that happens in the extra cycle that gets detected by the VDP and breaks its state machine (given that you need to sequence reads and writes in a certain order).
The workaround is to always use absolute addressing.
Thanks to @vertigo that pointed me in the right direction.
Here I am, scoping A0 (that switches the MODE pin on the VDP, yellow) and the /CSR signal (blue).
As you can see, there is a spurious spike, most probably caused by propagation delay during a dummy read cycle with the absolute indexed access (this does not happen with absolute addressing alone).
It's small enough that I could probably try to filter this out with a bodged cap... nasty, but should work.

After a coffee, my brain started working a bit better.
The spike in the previous post could be AN issue, but is not THE issue.
That one can be fixed by slightly delaying (a 470pF cap works for this) the /CS signal from the '138 decoder.
But in this image you can see the real problem: the yellow is the /CSR signal (indicating the VDP that we want to read) and the blue is a /CSW signal.
But we are doing just writings here, no reads. The CPU is placing something on the address bus during the dummy read of the absolute indexed access, that triggers my '138 decoder, which in turn selects the read.

@hkz This is how the 6502 works. Every cycle is a bus cycle and it's known to a potential source of problems when doing memory mapped I/O.
It used to be even worse: the NMOS revision will actually *write* back the original value during the intermediate cycle of an RMW instruction - at least that got changed to a dummy Read on the 65C02 (the base address, for indexed modes). But it can still mess up state machines, as you're finding - especially when interfacing with non-6502 family chips.
I'd say you have to deal with it in the I/O code you write for that device.
@Retrograde yep! Seems I've learned that the hard way!
Thanks for the knowledge, this'll come real handy in the future.
Well, at least I can say that with absolute addressing the VDP can be used reliably.
Picture drawn in aseprite, converted using @tursilion 's Convert9918 tool and shown in multicolor mode from the TK2000.

@hkz Does it work if the VDP_REG constant is set to 0xC0C1 in the .equ statement? Wondering if the assembler is botching the addition at compile time.
@gerbilengineer it doesn't work. I did verifiy the binary output by hand, the output addresses are correct.
That is not the issue, alas. Turned out to be spurious reads caused by the dummy 6502 cycle during the internal absolute address + X addition.
The reads break the state machine in the VDP.
@hkz @Retrograde Thanks for bringing back some old painful memories, heh. I remember a friend telling me to use the CMOS 6502s for DIY projects because they fix a lot of the bugs.
@hkz Ah. The joys of working at the hardware level.
Ok, given that the test for this board has been a (painful) success, I am releasing the #TK2000 #VDP board for everyone to enjoy!
For those that just tuned in, it adds a TMS9918A to your TK2000 home computer.
Why?
Because why not!
https://codeberg.org/hkzlab/TK2000_VDPboard
This project was sponsored by #PCBWay , that kindly printed the boards for me, and they turned out great!
That said, components and consumables are not free, so every credit you might wish to send me at https://ko-fi.com/hkzlab is going to be greatly appreciated! β
