Post by hydrophilic on Jul 24, 2014 5:16:06 GMT
I'm posting this here because I tend to forget, and hate researching my own source code... as a bonus, other programmers should find this info important!
So CBM documentation (and other sources) tell us how important it is to check the VDC "read bit" (bit 7 of $d600) before accessing the VDC data register (read or write $d601).
On the other hand, this will needlessly slow down your software and make it larger in many cases. So, for optimal speed and size, you should only test the "ready bit" when needed. When is that? Good question! Discussed below.
Another important thing not mentioned in documentation by CBM (and only implied by other sources) is that some (internal) registers pairs must be written in a specific order!
So based on my experience with VDC (some games, BASIC 7.80, and image viewer), here is Hydro's recommendations:
Okay to read any internal VDC register, at any time and in any order, EXCEPT for :
The last two, the pointers used to read/write/copy/fill data in VDC RAM may be read without checking the "ready bit" if you know the VDC is not currently performing a block copy or block fill. In that case, you should check (I don't know what would happen otherwise). Also I don't think the order is important, but it may be... I haven't had any problem, but I haven't tested all cases.
For the first listed register, VDC RAM, it is imperative you check the "ready bit" or you will "randomly" re-read the last requested byte (instead of the correct one pointed to by registers 18,19). Decreasing the DRAM refresh rate (or the size of the displayed VDC image) will reduce the "random errors" if you fail to test "ready bit", but will not eliminate them.
Okay to write any internal VDC register, at any time and in any order, EXCEPT for :
The last two, the pointers used to read/write/copy/fill data in VDC RAM must be written with the high byte first (the shown register numbers), and then the next-higher internal VDC register (the low byte) must be written. This seems to be because (although never documented by CBM) the VDC contains a latch of the high-byte, which it writes the "real/secret" internal register only after the low byte (next higher-register) is written. If you write them out-of-order (in the 6502 convenient fashion of low-byte-first) then the VDC will do strange things... probably due to hypothetical latch.
When writing the high-byte register (the ones listed above), you must also check the "ready bit"... I'm not sure why... I guess the hypothetical latch won't function if the VDC is not ready? However, you do not need to check the "ready bit" to write the next-higher register (the low byte)... well this assumes you actually waited and stored a value to the high-byte. Writing only the low-byte can result in strange things.. I think this is due to the auto-increment mis-feature moving to a new page (new high byte) but the old/wrong high-byte gets re-written by the hypothetical latch when you write the low-byte.
The RAM register (31) should only be accessed after checking the "ready bit". Otherwise you will "randomly" loose a byte... I imagine this loss actually happens when you later write a byte to the RAM register, but before the VDC could write the first/lost byte. Again, reducing the DRAM rate or image size will reduce the occurance of "random" losses, but not completely eliminate them. So always check the "ready bit".
Those are my recommendations. Ignore them at your own risk.
In particular, I can't guarantee those are the only exceptions you need to watch out for. And you may be able to break those rules in certain cases. If you can demonstrate a reliable way to break any of those rules, please share!
So CBM documentation (and other sources) tell us how important it is to check the VDC "read bit" (bit 7 of $d600) before accessing the VDC data register (read or write $d601).
On the other hand, this will needlessly slow down your software and make it larger in many cases. So, for optimal speed and size, you should only test the "ready bit" when needed. When is that? Good question! Discussed below.
Another important thing not mentioned in documentation by CBM (and only implied by other sources) is that some (internal) registers pairs must be written in a specific order!
So based on my experience with VDC (some games, BASIC 7.80, and image viewer), here is Hydro's recommendations:
Okay to read any internal VDC register, at any time and in any order, EXCEPT for :
- VDC RAM, register 31 ($1f)
- VDC update RAM pointer, registers 18 and 19 ($12 and $13)
- VDC source RAM pointer, registers 32 and 33 ($20 and $21)
The last two, the pointers used to read/write/copy/fill data in VDC RAM may be read without checking the "ready bit" if you know the VDC is not currently performing a block copy or block fill. In that case, you should check (I don't know what would happen otherwise). Also I don't think the order is important, but it may be... I haven't had any problem, but I haven't tested all cases.
For the first listed register, VDC RAM, it is imperative you check the "ready bit" or you will "randomly" re-read the last requested byte (instead of the correct one pointed to by registers 18,19). Decreasing the DRAM refresh rate (or the size of the displayed VDC image) will reduce the "random errors" if you fail to test "ready bit", but will not eliminate them.
Okay to write any internal VDC register, at any time and in any order, EXCEPT for :
- VDC RAM, register 31 ($1f)
- VDC update RAM pointer (high byte), register 18 ($12)
- VDC source RAM pointer (high byte), register 32 ($20)
The last two, the pointers used to read/write/copy/fill data in VDC RAM must be written with the high byte first (the shown register numbers), and then the next-higher internal VDC register (the low byte) must be written. This seems to be because (although never documented by CBM) the VDC contains a latch of the high-byte, which it writes the "real/secret" internal register only after the low byte (next higher-register) is written. If you write them out-of-order (in the 6502 convenient fashion of low-byte-first) then the VDC will do strange things... probably due to hypothetical latch.
When writing the high-byte register (the ones listed above), you must also check the "ready bit"... I'm not sure why... I guess the hypothetical latch won't function if the VDC is not ready? However, you do not need to check the "ready bit" to write the next-higher register (the low byte)... well this assumes you actually waited and stored a value to the high-byte. Writing only the low-byte can result in strange things.. I think this is due to the auto-increment mis-feature moving to a new page (new high byte) but the old/wrong high-byte gets re-written by the hypothetical latch when you write the low-byte.
The RAM register (31) should only be accessed after checking the "ready bit". Otherwise you will "randomly" loose a byte... I imagine this loss actually happens when you later write a byte to the RAM register, but before the VDC could write the first/lost byte. Again, reducing the DRAM rate or image size will reduce the occurance of "random" losses, but not completely eliminate them. So always check the "ready bit".
Those are my recommendations. Ignore them at your own risk.
In particular, I can't guarantee those are the only exceptions you need to watch out for. And you may be able to break those rules in certain cases. If you can demonstrate a reliable way to break any of those rules, please share!