VM_GET_FAR
is a GBVM instruction used to retrieve a byte or a word (16-bit value) from a specific memory address located in a potentially different memory bank.
Purpose:
Similar to VM_CALL_FAR
for routines, VM_GET_FAR
is essential for accessing data that is stored in memory banks other than the one currently active. On the Game Boy, large amounts of game data (like level layouts, character stats, item properties, or dialogue text) are often stored in separate ROM banks to overcome memory limitations. VM_GET_FAR
provides the mechanism to read this data from anywhere in the game’s ROM.
This instruction is crucial for:
Syntax:
VM_GET_FAR IDX, SIZE, BANK, ADDR
IDX
: The target variable (a GBVM variable) where the retrieved byte or word will be stored.SIZE
: Specifies the size of the data to be read:
.GET_BYTE
: Read an 8-bit value..GET_WORD
: Read a 16-bit value.BANK
: The memory bank number where the data (ADDR
) is located.ADDR
: The address (label) of the data within that bank.Usage Example: Reading Player Stats from a Data Bank
Imagine you have a table of player starting stats (e.g., initial health, attack, defense) stored in a separate data bank. When a new game starts, you want to load these stats into your player’s variables.
; In Bank 1 (e.g., game initialization script)
; Variables to store player stats
VAR_PLAYER_HEALTH:
.R_INT16 0
VAR_PLAYER_ATTACK:
.R_INT8 0
VAR_PLAYER_DEFENSE:
.R_INT8 0
; Load initial player health (16-bit word) from Bank 3, at label INITIAL_HEALTH
VM_GET_FAR VAR_PLAYER_HEALTH, .GET_WORD, BANK(PLAYER_STATS_DATA), INITIAL_HEALTH
; Load initial player attack (8-bit byte) from Bank 3, at label INITIAL_ATTACK
VM_GET_FAR VAR_PLAYER_ATTACK, .GET_BYTE, BANK(PLAYER_STATS_DATA), INITIAL_ATTACK
; Load initial player defense (8-bit byte) from Bank 3, at label INITIAL_DEFENSE
VM_GET_FAR VAR_PLAYER_DEFENSE, .GET_BYTE, BANK(PLAYER_STATS_DATA), INITIAL_DEFENSE
; ... rest of game initialization ...
; In Bank 3 (e.g., player_stats_data.s)
SECTION "Player Stats Data", ROMX
PLAYER_STATS_DATA:
INITIAL_HEALTH:
.WORD 100 ; Initial health value (16-bit)
INITIAL_ATTACK:
.BYTE 15 ; Initial attack value (8-bit)
INITIAL_DEFENSE:
.BYTE 10 ; Initial defense value (8-bit)
In this example, VM_GET_FAR
is used to read different sized values (word for health, byte for attack/defense) from a data section located in BANK(PLAYER_STATS_DATA)
. This allows you to keep your game logic separate from your game data, making it easier to manage and update.
Analogy to other programming languages: This is similar to reading data from a file on disk in a modern operating system, where the file is not directly in your program’s active memory. You specify the file (bank) and the offset/position within the file (address) to retrieve the data. In C/C++, it’s like reading from a memory-mapped file or accessing a global variable that might be linked from a different compilation unit, where the linker resolves the “far” address.