mvbg

VM_RET_FAR_N

VM_RET_FAR_N is a GBVM instruction used to return from a far call (a subroutine located in a different memory bank) and simultaneously remove a specified number of arguments from the stack.

Purpose: When you use VM_CALL_FAR to jump to a subroutine in another memory bank, you often pass arguments to that subroutine on the stack. After the subroutine has completed its task, it needs to return control to the calling script and clean up the arguments it received from the stack. VM_RET_FAR_N handles both of these actions:

This instruction is crucial for proper function call conventions and stack management when dealing with inter-bank subroutine calls, ensuring that the stack remains balanced and that arguments are correctly removed after use.

Syntax:

VM_RET_FAR_N N

Usage Example: Returning from a Scene Initialization Routine with Cleanup

Let’s revisit the TOWN_SCENE_INIT example from VM_CALL_FAR. Imagine this routine also takes a PLAYER_SPAWN_X and PLAYER_SPAWN_Y as arguments to position the player upon entering the scene.

; In Bank 1 (e.g., main game logic bank)

; Push arguments for the scene initialization
VM_PUSH_CONST 80 ; Player Spawn X
VM_PUSH_CONST 64 ; Player Spawn Y

; Call the initialization routine for the Town Scene, located in Bank 2
VM_CALL_FAR BANK(TOWN_SCENE_INIT), TOWN_SCENE_INIT

; After TOWN_SCENE_INIT returns, execution continues here.
; The arguments (80 and 64) have been removed from the stack by VM_RET_FAR_N.

; ... rest of main game logic ...

; In Bank 2 (e.g., scene data bank)

TOWN_SCENE_INIT:
  ; The arguments (Player Spawn X, Player Spawn Y) are now on the stack
  ; We need to retrieve them.
  VM_GET_TLOCAL VAR_PLAYER_SPAWN_Y, 0 ; Get Y (top of stack, index 0)
  VM_GET_TLOCAL VAR_PLAYER_SPAWN_X, 1 ; Get X (next on stack, index 1)

  ; Load town background
  VM_LOAD_TILESET TILESET_TOWN
  ; Place player at spawn coordinates
  VM_ACTOR_SET_POS PLAYER_ACTOR, VAR_PLAYER_SPAWN_X, VAR_PLAYER_SPAWN_Y
  ; ... other town-specific setup ...

  VM_RET_FAR_N 2 ; Return from the far call and remove 2 arguments from stack
; The '2' here corresponds to the 2 arguments (X and Y) that were passed.

In this example, VM_CALL_FAR pushes the return address and then the arguments. Inside TOWN_SCENE_INIT, the arguments are retrieved. Finally, VM_RET_FAR_N 2 ensures that when the routine returns to Bank 1, the two arguments (80 and 64) are popped from the stack, leaving it clean for subsequent operations.

Analogy to other programming languages: This is analogous to a function returning in C/C++ where the calling convention dictates that the callee (the function being called) is responsible for cleaning up the arguments from the stack. For example, in __stdcall calling convention on x86, the RET N instruction (where N is the number of bytes of arguments) handles both returning and stack cleanup. It ensures that the stack is properly unwound after a cross-module or cross-segment function call.