ticalc.org
Basics Archives Community Services Programming
Hardware Help About Search Your Account
   Home :: Archives :: News :: Feature: Using Writeback To Save Program Data

Feature: Using Writeback To Save Program Data
Posted by Nick on 28 March 2000, 05:54 GMT

Jonah Cohen has written a feature on using a technique called "writeback" to save data for things such as high scores.


Using Writeback to Save Program Data
by Jonah Cohen

Note that all references here are for TI-86 assembly, but the concept is very similar on other z80 calculators.

Writeback, for those of you unfamiliar with the concept, is a method of saving data within a program so that it remains there after the program exits. On the TI-86, when asm programs are executed, they are copied to _asm_exec_ram ($D748) before being run. However, once they exit, they are not copied back to their original location. Thus any changes to the data in the program are not saved.

So what can you do about this? Well, there are a number of methods of saving information:

  1. Save the data in a string or other external data file.
  2. Save the data in a RAM location that is reasonably safe.
  3. Using writeback to save the data to the original program.
The first two options are not very useful (the first has no advantages over the third and the second is not very safe). Thus, I will only go into depth describing the third method--using rom calls to copy data from the executed code in _asm_exec_ram back to the original program file. Here is an example writeback routine:

 1. ld hl,_asapvar
 2. rst 20h
 3. rst 10h
 4. xor a
 5. ld hl,data_start-_asm_exec_ram+4
 6. add hl,de
 7. adc a,b
 8. call _SET_ABS_DEST_ADDR
 9. xor a
10. ld hl,data_start
11. call _SET_ABS_SRC_ADDR
12. ld hl,data_end-data_start
13. call _SET_MM_NUM_BYTES
14. call _MM_LDIR

A line by line explanation of the routine:
  1. Point hl to _asapvar, the name of the currently executing program in variable name format.
  2. Copy the variable name from _asapvar to _OP1.
  3. Shortcut to _findsym, which looks up the variable name in _OP1 and returns the absolute pointer (24-bit) in bde.
  4. Register a=0
  5. Point hl to the offset into the program that the data starts. Notice that we subtract _asm_exec_ram so it's only an offset, not a full address. The extra 4 bytes we're adding are because every asm program has a 4 byte header--a size word and a signature word.
  6. Since bde contains the pointer to the original program, we can add the offset in that program by doing add hl,de.
  7. Remember: the addressing is 24-bit. Thus, if the offset into the original program is greater than 16 bits can represent, we need to add the carry flag (adc=add with carry) to the original pointer. After executing this line, ahl points to the first byte in the original program where we want to copy the data to.
  8. Use the ROM call to set ahl to be the absolute source address.
  9. Register a=0
  10. Now point hl to the data again. Since _asm_exec_ram is in $c000-$ffff, this time we use normal 16-bit addressing (hence why a=0).
  11. Now set this as the source address. See how this works? We copy from the current program data in _asm_exec_ram back to the original program data, which we got the address to by using _findsym.
  12. Put the size of the data to be copied in hl.
  13. Set that as the number of bytes.
  14. The ROM call _MM_LDIR (_mm_ldir in some include files) simulates the z80 opcode ldir using 24-bit addressing. It copies _MM_NUM_BYTES bytes from _ABS_SRC_ADDR to _ABS_DEST_ADDR. This is the command that does the bulk of the work. It uses the addresses we generated earlier to copy all of the data between data_start and data_end back to the original program.

So what good does this do, you may ask? Well, a lot! By defining data inside the program, we can then modify it to store high scores, names, speed preferences, and other things, all of which can be saved the next time the user runs the program. Here's an example:

exit_program:
 ld de,(score)
 ld hl,(highscore)
 call _cphlde
 jr nc,no_highscore

;user got a high score
 ld (highscore),de
 ld hl,_asapvar
 rst 20h
 rst 10h
 xor a
 ld hl,data_start-_asm_exec_ram+4
 add hl,de
 adc a,b
 call _SET_ABS_DEST_ADDR
 xor a
 ld hl,data_start
 call _SET_ABS_SRC_ADDR
 ld hl,data_end-data_start
 call _SET_MM_NUM_BYTES
 call _MM_LDIR

no_highscore:
 jp _clrScrn ;quit to homescreen

data_start:
highscore: .dw 0
data_end:

You can use this method to store any type of data you want, and even modified code (though that's much less useful). Now go out and write a game with high scores, initials, saved games, and the works!

 


The comments below are written by ticalc.org visitors. Their views are not necessarily those of ticalc.org, and ticalc.org takes no responsibility for their content.


Re: Feature: Using Writeback To Save Program Data
Patrick H
(Web Page)

Great job Jonah!

     28 March 2000, 06:01 GMT

Re: Feature: Using Writeback To Save Program Data
EV9D93  Account Info
(Web Page)

Cool, I never knew exactly what write-back was.
A question... Why do you think my calc sometimes just stops saving high scores untill I reset it?

     28 March 2000, 07:29 GMT

Re: Re: Feature: Using Writeback To Save Program Data
Ciaran McCreesh  Account Info
(Web Page)

Could be that something messes up the VAT, some games do that. Otherwise there's a bug in ROM versions 1.3 and 1.4 (?) that could theoretically return an incorrect pointer for a variable, this might not be detected by all programs. It seems to occur if something starts dead on a new page and you findysm it, it returns a pointer to $c000 and one page too low.

Ciaran

     28 March 2000, 19:25 GMT


Re: Re: Re: Feature: Using Writeback To Save Program Data
brentes
(Web Page)

Actually when you have a sqrt program installed on the calculator writeback doesn't work.

     29 March 2000, 01:17 GMT


Re: Re: Re: Re: Feature: Using Writeback To Save Program Data
Ciaran McCreesh  Account Info
(Web Page)

That's a different problem.

     29 March 2000, 19:25 GMT


Re: Re: Feature: Using Writeback To Save Program Data
Jonah Cohen  Account Info
(Web Page)

Perhaps you renamed the programs? Or maybe you're using AShell or Iridus, both of which can interfere with writeback. It normally shouldn't be an issue...

     29 March 2000, 17:01 GMT

Re: Feature: Using Writeback To Save Program Data
nova  Account Info

An 89 with AMS 2.03 has problems keeping high scores.
Has anyone else noticed it?

     28 March 2000, 09:00 GMT

Re: Re: Feature: Using Writeback To Save Program Data
Frederic Merizen  Account Info

Yawn - I guess they changed the VAT once again :(

     28 March 2000, 13:11 GMT

Re: Re: Feature: Using Writeback To Save Program Data
cjk00  Account Info

an 89 with ams 2.03 and doors II .95 does not keep track of high scores for achived progs because userlib, the library that executes the progs, only copies the prog to ram and then deletes it rather than unarchiving it and then archiveing it back as the good old doors final beta 2 did.

colin king

     28 March 2000, 18:29 GMT


Re: Re: Re: Feature: Using Writeback To Save Program Data
Kevin McCollum  Account Info
(Web Page)

How does in pheonix. when you exit (even when the game is archived) it knows where you left off. Did P. Davision use writeback to accoplish this. Im asking this because. If Pheonix can go back to where you left off last even when its archive. there must be a way to save highscores when archived.

     2 April 2000, 17:54 GMT


Re: Re: Feature: Using Writeback To Save Program Data
Amalfi Marini  Account Info

It happended to me with tetris , and some games recorded the highscore , but not the name

     28 March 2000, 19:22 GMT

Re: Feature: Using Writeback To Save Program Data
rabidcow
(Web Page)

replace the last two calls with this one:
call _MM_LDIR_SET_SIZE
it will perform both operations in one call.

_MM_LDIR_SET_SIZE equ 524Dh

     28 March 2000, 09:14 GMT

Re: Feature: Using Writeback To Save Program Data
Kerey Roper  Account Info
(Web Page)

Using external files to save does have some advantages over program writeback, although it is larger and more difficult to use. It allows people to trade saved games, even to different types of calculators, such as 83 to 83+, send the game to someone else without sending save files, and back up a saved game without having to save all of them.

Program writeback is the best choice for high scores though.

     28 March 2000, 23:10 GMT

Re: Feature: Using Writeback To Save Program Data
natefanaro  Account Info
(Web Page)

Will this method work on an 82? or only on the 86?

     29 March 2000, 06:09 GMT

Re: Feature: Using Writeback To Save Program Data
Huub Heerink  Account Info
(Web Page)

That's a great job, I never could have done this. Thanks!

     31 March 2000, 21:03 GMT

  Copyright © 1996-2011, the ticalc.org project. All rights reserved. | Contact Us | Disclaimer