Cisano Posted February 5 Share Posted February 5 On real hardware, what happen if I read an inexistent Ram address? For example: LDA $70 The accumulator load 0 or an undetermined value? Thanks Quote Link to comment Share on other sites More sharing options...
JetSetIlly Posted February 5 Share Posted February 5 Great question. In the Atari 2600 not all addresses map to RAM locations. Many point to special registers in the support chips. For example, the memory address $70 is a mirror address of $00 which is the the CXM0P register in the TIA chip. The nature of the value that is loaded from addresses like these depends on the register but in the case of values read from the TIA we should be aware that many of the bits in the loaded value will be "undeterminable". So we should apply a bit mask or be otherwise very careful how we treat these values. The vcs.h file indicates which pins are "driven" and which are "undriven". For example, in the case of the CXM0P register the two most significant bits are "driven" and the remainder are "undriven". CXM0P ds 1 ; $00 xx00 0000 Read Collision M0-P1 M0-P0 CXM1P ds 1 ; $01 xx00 0000 M1-P0 M1-P1 CXP0FB ds 1 ; $02 xx00 0000 P0-PF P0-BL CXP1FB ds 1 ; $03 xx00 0000 P1-PF P1-BL CXM0FB ds 1 ; $04 xx00 0000 M0-PF M0-BL CXM1FB ds 1 ; $05 xx00 0000 M1-PF M1-BL CXBLPF ds 1 ; $06 x000 0000 BL-PF ----- CXPPMM ds 1 ; $07 xx00 0000 P0-P1 M0-M1 INPT0 ds 1 ; $08 x000 0000 Read Pot Port 0 INPT1 ds 1 ; $09 x000 0000 Read Pot Port 1 INPT2 ds 1 ; $0A x000 0000 Read Pot Port 2 INPT3 ds 1 ; $0B x000 0000 Read Pot Port 3 INPT4 ds 1 ; $0C x000 0000 Read Input (Trigger) 0 INPT5 ds 1 ; $0D x000 0000 Read Input (Trigger) 1 To be absolutely clear about this, the "x" symbol represents a "driven" bit and the "0" symbol represents an "undriven" bit. xx00 0000 Now, if you were to load one of these values on an emulator, you will very likely just get values of 0 for the undriven bits. However, this can lead to ROM files that don't work as expected on real hardware. To help, good emulators include a way of setting these undriven bits to a random value, thereby emulating what might happen in the real case. You're most likely using Stella so find the Options window and click the "Developer" button. This will option will allow you to set the "Drive unused TIA pins..." checkbox. A very common mistake that is very easy to make is to load the $00 register (which we've learned is the CXM0P register) instead of the value $00. For example, a programmer might write: LDA $00 Instead of: LDA #$00 This will produce code that seems to be correct when run under emulation unless the "drive unused TIA pins" option is enabled. It's a very good idea to have this option enabled when developing a new game. You should also be aware that reading from some non-RAM addresses may have side-effects in addition to loading the CPU with a value. For example, reading the INTIM register (part of the RIOT chip) resets the timer divider. 2 Quote Link to comment Share on other sites More sharing options...
glurk Posted February 5 Share Posted February 5 Is not this correct? $0040 - $007F = mirror of $0000 - $003F So $70 would be mirror of $30 ? Quote Link to comment Share on other sites More sharing options...
+MarcoJ Posted February 5 Share Posted February 5 4 hours ago, glurk said: Is not this correct? $0040 - $007F = mirror of $0000 - $003F So $70 would be mirror of $30 ? It depends on from who's point of view. From the TIA chip inside the console, yes those are addresses are read as the same address (a mirror). From the cartridge's point of view though, no, those are all different addresses, since the cartridge gets all the 12 address pins. The TIA only gets a limited number of address pins wired to it, so therefore when the unwired pins change state, it doens't see the change and logically the address change is a "mirror". There are a few unused addresses within the TIA space which aren't used by anything, such as $3E,$3F,$7E and $7F. Some bankswitching schemes use them as an agreed zeropage location to switch banks. For example $13E,$23E...$F3E are all separate addresses according to the cartridge. 1 Quote Link to comment Share on other sites More sharing options...
+MarcoJ Posted February 5 Share Posted February 5 8 hours ago, Cisano said: On real hardware, what happen if I read an inexistent Ram address? For example: LDA $70 As @JetSetIlly said above, that is a mirror of one of the collision registers. As for the unused "Floating" $3E,$13E etc addresses above, it can vary console to console, and emulator to emulator, flash cart to flash cart. I have found them to read value 0x00 in my consoles. It is better practice to guard code against reading the addresses, even if every console behaves the same. Emulators in developer mode can help you find the situations by selecting the "drive pin to random" function, your program will behave erratic with that enabled. Most developers who will be running on developer mode and when they try out your game it will do weird things like roll the screen, drift sideways, have uneven scanlines, etc. 1 Quote Link to comment Share on other sites More sharing options...
JetSetIlly Posted February 5 Share Posted February 5 (edited) 5 hours ago, glurk said: Is not this correct? $0040 - $007F = mirror of $0000 - $003F So $70 would be mirror of $30 ? $70 and $30 are both mirrors of $00 on edit: To clarify, when reading an address with the intention of loading a value into a CPU register, $70 and $30 are mirrors of $00. Edited February 5 by JetSetIlly 2 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.