Appvars

Introduction

In the last tutorial we pointed out that you can not create permanent self modifying code. So, how do you save important data? The answer is in AppVars. They are a special kind of variable that can only be edited in assembly, and serve as a "permanent" saving point for app data (note that they can be deleted from the memory menu).

Creating AppVars

To create AppVars, we will use the _CreateAppVar ROM call. It's inputs are appvar name in op1 and size in HL. Note that when created it will be in RAM.

;omit header
 ld hl,AppVarName 
 rst rMOV9TOOP1 
 ld hl,32 
 bcall(_CreateAppVar)

AppVarName:
.db AppVarObj,"AVDATA",0

Data Structure

The data in AppVars goes like this: the first two bytes are for size, and then everything else is defined by the program accessing the AppVar.

AppVar Identifier

Generally, it is a very good idea to create an identifier for your AppVar. It can be anything you want and any length you want, so long as your program can identify it later. It is good practice to put it right after the size bytes, but you don't have to if you don't want to.

Creation

Creating an identifier is as simple as ldir-ing into the AppVar.

;load our identifier
 inc de                                    ;get over size bytes
 inc de
 ld hl,identifier
 ld bc,9
 ldir 
identifier:
.db "Identify",0

Detection

First it must be located. See External Levels and Files for more info.
Detection is as simple as checking for any variants between the identifier and the data in the AppVar.

;check for valid AppVar
;assuming de is pointing to start of AppVar Data
 inc de                                    ;get over size bytes
 inc de

 ld hl,identifier
 ex de, hl
iloop:
 ld a,(de)
 cp (hl)
 jr nz,invalid
 or a
 jr z,valid
 inc de
 inc hl
 jr iloop
invalid:
;... in case identifiers don't match
vald:
;... everything matches!
identifier:
.db "identify",0

Changing AppVar Size

It's usually a good idea to create AppVars of the correct size to begin with. However, sometimes this isn't possible. So, to do so we just need to insert memory into the appvar and update the size bytes.

;assuming that DE points to size byte and that we have enough memory
 push de

 push de                    ;copy de into hl
 pop hl

 ld a,(de)                    ;ld de,(de)
 ld b,a
 inc de
 ld a,(de)
 ld d,a
 ld e,b

 add hl,de
 ex de,hl                    ;end of program now in de
 ld hl,20                    ;insert 20 bytes to the end
 bcall(_insertMem)
 pop de
 add hl,de                    ;update size
 ld a,l
 ld (de),a
 inc de
 ld a,h
 ld (de),a

Note that this process is the exact same process you go through to insert memory into program variables, too.

Conclusion

AppVars are really useful tools for saving data between application uses. It is interesting to note that regular assembly programs can also access AppVars, and use them in the exact same way that flash applications use them.

Unless otherwise stated, the content of this page is licensed under GNU Free Documentation License.