Jump to content

Discussion: RAM Management


Recommended Posts

Posting this here in a new thread.  I saw the topic of RAM management mentioned in another thread, but I didn't want to hijack it.  Obviously there are many ways to skin a cat, to each their own.  I wanted to share how I like to do it.  I would love to hear how the rest of you do this, as well.


For my projects, RAM typically falls into 1 of 3 categories, global, local, or temporary:

Global RAM:  Exactly what it sounds like.  This is everything that needs to be accessible throughout the project.  Your global frame counter should be here, current score, high score, etc.

Local RAM:  These are variables that are specific to a particular game mode, display kernel, menu, etc.  They only need to be used in one area of code, and they can be recycled elsewhere.

Temporary RAM:  Technically, this shouldn't normally be needed.  Each set of local variables should probably define their own temporary variables.  But if you want to create subroutines that can be accessed from multiple areas, for example, a text display kernel, it may be best to define a space in RAM that is known to be available, regardless of the current local variables.


The way I implement this is by defining each section of RAM in a separate file, for organization.


First, I define all the global variables:

filename: ram_global.asm

RamGlobal	; start of global RAM

Frame		ds 1
Variation	ds 1
Score		ds 6
Rand16		ds 2

RamLocal	; start of local RAM

Next, I define local variables in separate files:

filename: ram_game.asm

	RORG RamLocal	; reset RAM position to local RAM

SomePointer	ds 2
PlayerColor	ds 1
BallPosX	ds 1
BallPosY	ds 1
Temp		ds 1

And I tie it all together in another file:

filename: variables.asm

	SEG.U VARS	; create a segment of labels that isn't output into the binary
	RORG $80

	include ram_global.asm
	include ram_menu.asm
	include ram_game.asm
	include ram_credits.asm
	include ram_temp.asm


Edited by JeremiahK
  • Like 4
  • Thanks 1
Link to comment
Share on other sites

I might steal that.


The method I've used with my one and only 2600 game is I have a few sections:

  • Persistent globals: game state that persists between game rounds; reset when powered on or pressing Game Reset
  • Game globals: game state exists only for a single round; reset in a loop
  • Temporary variables: these overlap with the stack
  • Stack: subroutines and some special purpose uses

My game global section is reset with a loop:

    ldx #0
    ldy #(MemBlockEnd - MemBlockStart)
    stx MemBlockStart,y
    bpl .Memset


I make sure to check my subroutine call depth before using some of the temporary variables or before nesting another subroutine call. I've had to refactor a few subroutines, because my call depth was getting a bit too much. My game is not CPU intensive, so I have the luxury using lots of subroutine calls and pushing data onto the stack for a few special cases. I'll probably use the stack more in the future. I like using it.


  • Like 1
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.

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.

  • Recently Browsing   0 members

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