Jump to content
IGNORED

Reading an inexistent Ram address


Recommended Posts

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.

 

image.png.64c17277688201e90c014aed7d61e256.png

 

 

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.

 

 

  • Like 2
Link to comment
Share on other sites

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. 

 

  • Like 1
Link to comment
Share on other sites

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. 

 

  • Like 1
Link to comment
Share on other sites

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 by JetSetIlly
  • Like 2
Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...