Packages

ALEx lets you run the Arcade Learning Environment from Elixir.

Current section

Files

Jump to
alex csrc ale src games RomUtils.cpp
Raw

csrc/ale/src/games/RomUtils.cpp

/* *****************************************************************************
* A.L.E (Arcade Learning Environment)
* Copyright (c) 2009-2013 by Yavar Naddaf, Joel Veness, Marc G. Bellemare and
* the Reinforcement Learning and Artificial Intelligence Laboratory
* Released under the GNU General Public License; see License.txt for details.
*
* Based on: Stella -- "An Atari 2600 VCS Emulator"
* Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team
*
* *****************************************************************************
*
* RomUtils.hpp
*
* Additional utilities to operate on RAM.
* *****************************************************************************
*/
#include "RomUtils.hpp"
#include "System.hxx"
namespace ale {
/* reads a byte at a memory location between 0 and 128 */
int readRam(const System* system, int offset) {
// peek modifies data-bus state, but is logically const from
// the point of view of the RL interface
System* sys = const_cast<System*>(system);
return sys->peek((offset & 0x7F) + 0x80);
}
// Reads a byte from anywhere in the memory map between 0x0000 and 0xffff.
// Note that the 6507 CPU used in the Atari 2600 only has 13 address lines
// physically connected. According to documentation by Chris Wilkson found
// at: https://atariage.com/forums/topic/192418-mirrored-memory/
//
// The address ranges are therefore mirrored in the following way:
//
// ***************************************************
// * $0000-$003F = TIA Addresses $00-$3F (zero page) *
// * ----------------------------------------------- *
// * mirror: $xyz0 *
// * x = {even} *
// * y = {anything} *
// * z = {0, 4} *
// ***************************************************
//
// **************************************
// * $0080-$00FF = RIOT RAM (zero page) *
// * ---------------------------------- *
// * mirror: $xy80 *
// * x = {even} *
// * y = {0,1,4,5,8,9,$C,$D} *
// **************************************
//
// ****************************************
// * $0280-$029F = RIOT Addresses $00-$1F *
// * ------------------------------------ *
// * mirror: $xyz0 *
// * x = {even} *
// * y = {2,3,6,7,$A,$B,$E,$F} *
// * z = {8,$A,$C,$E} *
// ****************************************
//
// *****************************************
// * $1000-$1FFF = ROM Addresses $000-$FFF *
// * ------------------------------------- *
// * mirror: $x000 *
// * x = {odd} *
// *****************************************
//
int readMappedRam(const System* system, int offset) {
// peek modifies data-bus state, but is logically const from
// the point of view of the RL interface
System* sys = const_cast<System*>(system);
return sys->peek(offset);
}
/* extracts a decimal value from a byte */
int getDecimalScore(int index, const System* system) {
int score = 0;
int digits_val = readRam(system, index);
int right_digit = digits_val & 15;
int left_digit = digits_val >> 4;
score += ((10 * left_digit) + right_digit);
return score;
}
/* extracts a decimal value from 2 bytes */
int getDecimalScore(int lower_index, int higher_index, const System* system) {
int score = 0;
int lower_digits_val = readRam(system, lower_index);
int lower_right_digit = lower_digits_val & 15;
int lower_left_digit = (lower_digits_val - lower_right_digit) >> 4;
score += ((10 * lower_left_digit) + lower_right_digit);
if (higher_index < 0) {
return score;
}
int higher_digits_val = readRam(system, higher_index);
int higher_right_digit = higher_digits_val & 15;
int higher_left_digit = (higher_digits_val - higher_right_digit) >> 4;
score += ((1000 * higher_left_digit) + 100 * higher_right_digit);
return score;
}
/* extracts a decimal value from 3 bytes */
int getDecimalScore(int lower_index, int middle_index, int higher_index,
const System* system) {
int score = getDecimalScore(lower_index, middle_index, system);
int higher_digits_val = readRam(system, higher_index);
int higher_right_digit = higher_digits_val & 15;
int higher_left_digit = (higher_digits_val - higher_right_digit) >> 4;
score += ((100000 * higher_left_digit) + 10000 * higher_right_digit);
return score;
}
} // namespace ale