Windless Posted December 17, 2021 Share Posted December 17, 2021 (edited) Hi, I think I remember reading somewhere that bits which are unpopulated are in high impedance state and trying to read them will return whatever is on the bus, which due to capacity of the port will probably be last thing you read or wrote there if it's not too long ago. I am interested in the reading the CXM1P, which only populated bits 7 and 6. Is it reliable to assume that : lda #%00000000 ldx CXM1P will give a value for `x` that will have all its 6 lower bits at `0` at least 99 times out of 100 ? Thanks, Windless. (I only have emulators here, can't test on real hardware for now ) Edited December 17, 2021 by Windless Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted December 17, 2021 Share Posted December 17, 2021 I suppose bits 0..5 will be the value of CXM1P. Quote Link to comment Share on other sites More sharing options...
glurk Posted December 18, 2021 Share Posted December 18, 2021 I'm definitely no expert on this, but I'm pretty certain that the unpopulated/unused bits of ANY of the collision registers will ALWAYS read 0. (I think you are asking if they will "briefly" hold some other values that were previously on the bus, and I think they will not) Quote Link to comment Share on other sites More sharing options...
Windless Posted December 18, 2021 Author Share Posted December 18, 2021 (edited) . Edited December 18, 2021 by Windless I missed an answer :) Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted December 18, 2021 Share Posted December 18, 2021 6 hours ago, glurk said: I'm definitely no expert on this, but I'm pretty certain that the unpopulated/unused bits of ANY of the collision registers will ALWAYS read 0. (I think you are asking if they will "briefly" hold some other values that were previously on the bus, and I think they will not) What makes you thing so? For other unused bits, this is regularly the case (on most consoles). That is why buggy code like lda $0 instead of lda #$0 works. Quote Link to comment Share on other sites More sharing options...
glurk Posted December 18, 2021 Share Posted December 18, 2021 Well, I find it to be an interesting question. But I actually find both the OP's question and your answer to be unclear. At least on 8-bit systems, code regularly does things like LDA P0PF, BEQ LABEL. And P0PF is a collision register with unused bits. I've tested that on real hardware, and it works, the unused bits always equal 0. So I DID ASSUME that the 2600 would work the same way. Are you saying this is not the case on the 2600? Or are you saying that it is the case? As a coding best practice, I always try to code to read the defined bits, and mask off the others. But I suppose one could write tighter code if the state of the undefined bits is actually guaranteed. So I find it interesting in that regard, hence my posting. Quote Link to comment Share on other sites More sharing options...
alex_79 Posted December 18, 2021 Share Posted December 18, 2021 The TIA only drives bits 6 and 7. Those two bits (and only those!) are 0 if unused by the register. E.g. CXBLPF, only uses bit 7. Bit 6 will always read 0 in that case. If you read from addresses $1e and $1f, which do not correspond to any of the TIA read registers, both bits 6 and 7 are 0. Bits 5 to 0 are floating when reading from the TIA, so nothing is driving them, and their state is usually the last byte that was on the bus (e.g. the address of the register itself, if you're using zero page addressing mode). Anyway this is unstable and so you must not rely on the state of those 6 bits when reading the TIA, else the code can fail unpredictably. You can see that the tri-state drivers are only on data pins d6 and d7 on page 2 of the TIA schematics. https://atariage.com/2600/archives/schematics_tia/index.html A better description here: https://atariage.com/forums/blogs/entry/2715-introduction-to-processor-hardware/ 1 Quote Link to comment Share on other sites More sharing options...
JetSetIlly Posted December 18, 2021 Share Posted December 18, 2021 1 hour ago, glurk said: Well, I find it to be an interesting question. But I actually find both the OP's question and your answer to be unclear. At least on 8-bit systems, code regularly does things like LDA P0PF, BEQ LABEL. And P0PF is a collision register with unused bits. I've tested that on real hardware, and it works, the unused bits always equal 0. So I DID ASSUME that the 2600 would work the same way. Are you saying this is not the case on the 2600? Or are you saying that it is the case? As a coding best practice, I always try to code to read the defined bits, and mask off the others. But I suppose one could write tighter code if the state of the undefined bits is actually guaranteed. So I find it interesting in that regard, hence my posting. From the Stella Programmer's Guide. Only the bits where there is a 1 in the column will be set by the reading of that register. The other bits will be set to whatever the most recent value on the bus was. This will vary depending on which TIA register mirror you are reading. For example, reading CXM1P LDA $01 Assuming there is no collision, the A register will contain 00000001 If we use a mirror of the CXM1P however, LDA $11 The A register will contain 00010001 This is because in the first cases the most recent value on the bus was $01 and in the second case the most recent value was $11. The most significant bits are set to the value in the TIA register, but the other bits are untouched. Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted December 18, 2021 Share Posted December 18, 2021 8 minutes ago, JetSetIlly said: The other bits will be set to whatever the most recent value on the bus was. Yes, but not 100% reliable on all consoles. Quote Link to comment Share on other sites More sharing options...
JetSetIlly Posted December 18, 2021 Share Posted December 18, 2021 Just now, Thomas Jentzsch said: Yes, but not 100% reliable on all consoles. Indeed. An important detail I missed out. Out of curiosity, do we know the specifics of which consoles are affected and specifically why? Quote Link to comment Share on other sites More sharing options...
alex_79 Posted December 18, 2021 Share Posted December 18, 2021 1 hour ago, JetSetIlly said: Out of curiosity, do we know the specifics of which consoles are affected and specifically why? Not that I'm aware of. IIRC, I've seen bugs related to undriven bits most often reported for 6-switch consoles. But I don't think there are enough reports to really draw conclusions. Moreover I guess that the console itself isn't the only factor that needs to be considered. It seems (as also suggested in the last paragraph of the blog I linked above), that eproms are more likely to affect undriven bits than mask roms, and in fact homebrews seem to be more prone to glitch because of this. On the other hand, while many old commercial games have the "zero page instead of immediate" bug and fail in emulation if you randomize the undriven pins, I only remember a couple of reports of them failing on real hardware. (e.g. here) So the same code can behave differently on the same console depending on the cartridge hardware. 2 Quote Link to comment Share on other sites More sharing options...
Windless Posted December 18, 2021 Author Share Posted December 18, 2021 (edited) Apparently, emulators seems to agree that when reading e.g. XCM1P, the last thing on the data bus is the address of XCM1P (e.g. %00000010) (because the opcode which ends with the address has just been read as data), and reading will only modify the two first bits, hence reading %xx000010. Reading XCM0P (address %00000000) will read reading %xx000000. If someone wants to check the actual behaviour on a 2600, here are the code and rom. Just ask if womeone needs a PAL/SECAM version. The expected result is a blue screen with 3 green lines and a black line. Thanks you, Windless. Edit : I missed all your answers while I was coding, thank you! I'll leave my test code here anyway unimplemented_read_test.asm unimplemented_read_test.rom Edited December 18, 2021 by Windless Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted December 18, 2021 Share Posted December 18, 2021 (edited) Please enable the developer options in Stella. Then your code will break. Edited December 18, 2021 by Thomas Jentzsch Quote Link to comment Share on other sites More sharing options...
Windless Posted December 18, 2021 Author Share Posted December 18, 2021 25 minutes ago, Thomas Jentzsch said: Please enable the developer options in Stella. Then your code will break. Yes, I've tried this already, but I was wondering how reliably the non-developer-option reflects the actual behaviour. Some answer were given in this thread by Alex_79. Quote Link to comment Share on other sites More sharing options...
+Karl G Posted December 18, 2021 Share Posted December 18, 2021 I'm curious what prompted the question? Are you writing something that would require less cycles if you can assume that undefined bits are read as zero? Quote Link to comment Share on other sites More sharing options...
Windless Posted December 18, 2021 Author Share Posted December 18, 2021 Just now, Karl G said: I'm curious what prompted the question? Are you writing something that would require less cycles if you can assume that undefined bits are read as zero? I was trying to find different ways to gain 1 cycle on a routines that can't work without it, and I came to that question (thought it wouldn't solve my problem anyway ) Quote Link to comment Share on other sites More sharing options...
+Karl G Posted December 18, 2021 Share Posted December 18, 2021 4 minutes ago, Windless said: I was trying to find different ways to gain 1 cycle on a routines that can't work without it, and I came to that question (thought it wouldn't solve my problem anyway ) If there's a portion of code you would be willing to share, there are a lot of clever people who enjoy the challenge of shaving off a few cycles. There might be something that you haven't considered (I'd make a new topic for it, though). 1 Quote Link to comment Share on other sites More sharing options...
Windless Posted December 18, 2021 Author Share Posted December 18, 2021 I'll probably share it once I've solved it or when I decide I've serached enough Quote Link to comment Share on other sites More sharing options...
+splendidnut Posted December 20, 2021 Share Posted December 20, 2021 If you're going to be branching based on the collision bits, you might want to look at the BIT instruction: Quote BIT sets the Z flag as though the value in the address tested were ANDed with the accumulator. The N and V flags are set to match bits 7 and 6 respectively in the value stored at the tested address. (from http://www.6502.org/tutorials/6502opcodes.html#BIT ) For example, if you do BIT CXM1P, then you can use BMI to branch when there's a M1P0 collision, and BVS to branch when there's a M1P1 collision. 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.