mvbg

VM_CALL

VM_CALL is a fundamental GBVM instruction used to call a subroutine (function) within the same memory bank. It is analogous to a function call in traditional programming languages.

Purpose: VM_CALL allows you to organize your GBVM scripts into modular, reusable blocks of code. When VM_CALL is executed, the GBVM:

  1. Saves the current execution point: It pushes the address of the instruction immediately following VM_CALL onto an internal stack. This is crucial for knowing where to return to after the subroutine finishes.
  2. Jumps to the subroutine: It then transfers control to the specified ADDR (the start of the subroutine).

After the subroutine completes its execution (typically by encountering a VM_RET instruction), the GBVM pops the saved address from the stack and resumes execution from that point. This mechanism enables structured programming and avoids code duplication.

Syntax:

VM_CALL ADDR

Usage Example: Reusable Dialogue Function

Imagine you have several NPCs in your game, and each time the player interacts with them, a common dialogue sequence needs to play, perhaps with slight variations. You can create a DISPLAY_DIALOGUE subroutine.

; Main game script

; Player interacts with NPC 1
VM_CALL DISPLAY_DIALOGUE
; ... continue main script after dialogue ...

; Player interacts with NPC 2
VM_CALL DISPLAY_DIALOGUE
; ... continue main script after dialogue ...

; --- Subroutine Definition ---
DISPLAY_DIALOGUE:
  ; Assume a global variable or a passed argument determines the specific text
  VM_LOAD_TEXT DIALOGUE_TEXT_VAR
  VM_DISPLAY_TEXT
  VM_INPUT_WAIT ; Wait for player input to dismiss dialogue
  VM_RET        ; Return to where VM_CALL was made

; Dialogue text definitions (example)
DIALOGUE_TEXT_VAR:
  .R_REF DIALOGUE_NPC1_GREETING

DIALOGUE_NPC1_GREETING:
  .TEXT "Hello, adventurer!"
  .TEXT_END

; ... other dialogue texts ...

In this example, VM_CALL DISPLAY_DIALOGUE is used multiple times. Each time it’s called, the GBVM jumps to the DISPLAY_DIALOGUE subroutine, executes the dialogue logic, and then returns to the exact point in the main script where it was called. This makes the dialogue logic reusable and easy to manage.

Analogy to other programming languages: This is directly analogous to calling a function or method in almost any programming language:

The concept of pushing the return address onto a stack and then jumping to the function’s entry point is a fundamental mechanism for subroutine calls across many architectures and languages.