Hi,

I'm currently working on a new asm project which is already pretty big (around 21 Kb).

Each level is more than 6 Kb and I will not finish the programs without a solution because there's not as many RAM as I need.
My question is simple :
How to export levels into a separate program (1 program for all levels or 1 program per level) which will be in archive memory?

How to create 8xp files which will be stored automatically into archive memory and how to access "easily" these levels (basically it's "map_something :" followed by tilemap data).
What method is usually used by guru asm programmers Very Happy

Thank you for your help.

Regards.

Thibault
I think you can really just put the data into your program like you normally would with a header (something the main program searches for at the start of the program) that tells the program it's a game level. Just compile the data in a .asm file as if it were a normal program. When the program wants to load the map, we can load the map into RAM somewhere (if it's archived).
You can indeed just build programs containing mostly data, but you'll want to add some safeguards to keep users from trying to run them, as well as some sort of signature:

Code:
    ret
; Signature (change to whatever you want)
    .db 0x55, 0x55
; Data here
    .db 0,0,0,0,0,0,0,0
; ...
Of course be sure to check those first three bytes when attempting to load data to ensure it's actually data for your program.

I'd prefer to use appvars so you don't have meaningless (to the user) programs cluttering up the program menus, and you can save a byte by removing the leading ret. Not sure if there are any tools capable of packing binaries into appvars, but it should be an easy modification to (for example) binpac8x if necessary.
Thank you.
I think I will not use flashapp, but archiving levels should be enough.

How to locate the archiving programs?
Using bcall(_ChkFindSym) and test the firsts bytes from the adress resulting in de is sufficient?
thepenguin77 recently explained it to me over at Omnimaga:
http://ourl.ca/95860

EDIT: Also, programs can use AppVars, too, so that's another option, though apart from BASIC programmers, who ever really looks at the program menu? I thought everything was pretty much done through a (FlashAPP) shell nowadays, you don't even need to look for prgmA anymore Wink
For reading from the archive, you'll need to do a little more than just find the variable, but that's basically how it goes. General idea of how I'd do it:
  1. Find variable with ChkFindSym.
  2. If A=0, it's in RAM. Skip to step 4.
  3. Read variable data into RAM (with FlashToRAM). You'll need to allocate some sort of buffer for it.
  4. Check the first few bytes of the data for your signature
I maintain that you should use appvars rather than programs (just change the type byte), since even if you don't look at the TI-OS program menu, there are still shells that show everything, such as DCS.
Ah, i didn't know that about DCS. It's not a difficult thing to do (well, no moreso than using a .8xp file) so if we decide to go that route (external levels) we may as well.
I already decreased the size per factor 2 by using a rle decompression routine Smile

Anyway, I'm always interested in finding ways to separate core application from data into a different.
Compiling data as a separate asm file with an header (app header found on the TI website) with spasm levels.asm levels.8xk then signing this file using rabbitsign (I need to convert it to intelhex file format it seems) is the good method ?
Then just load each level by using a ldir or something with a bcall...
How do you exactly do a flashapp guys?
It seems to me that you should put your levels in archives programs or archived Appvars, then just directly RLE unpack them into your RAM level area. As I told you on IRC, I have Doors CS routines that make it simple to iterate over variables in Flash just as if they were in RAM, fetching one byte at a time. I think trying to pack your levels into a separate App is going to make your life much harder, though, unless I misunderstand what you're saying.

Anyway, variables in Flash are, unlike variables in RAM, stored with a copy of their VAT entries before the actual data. The purpose of this is to make it easy to rebuild the VAT on a RAM Clear: simply iterate through all user Flash pages, copy out each VAT entry found into a new VAT, point it to the right place, and voila, a proper list of all the Archived variables. Anyway, for my routines, you first need to do a ChkFindSym, to set up hl and de. As Tari said, this will fill in register b with the page of the variable (or 0 for RAM), and a with 0 if in RAM, non-zero otherwise. The following routines are built to work the same regardless of whether the variable is in RAM or Flash:


Code:
SetUpROM:
   ld a,(CurROMPage)
   or a
   ret z
   push de
      ld de,9
      add hl,de
      call GetArcProgByte
      ld d,0
      inc a
      ld e,a
      add hl,de
      pop de
   ret
GetArcProgByte:
   push de
   push bc
   push hl
   ld a,(CurROMPage)
   or a
   jr z,GetArcProgByteReg
   ld b,a
   call AutoArcPtrUpdate
   bcall(_LoadCIndPaged)
   ld a,c
GetArcProgByteFinishHL:
   pop hl
GetArcProgByteFinish:
   pop bc
   pop de
   ret
GetArcProgByteReg:
   pop hl
   ld a,(hl)
   jr GetArcProgByteFinish

GetArcProgByteDE:
   push de
   push bc
   push hl
   ld a,(CurROMPage)
   or a
   jr z,GetArcProgByteRegDE
   ld b,a
   ex de,hl
   call AutoArcPtrUpdate
   bcall(_LoadCIndPaged)
   ld a,c
   jr GetArcProgByteFinishHL
GetArcProgByteRegDE:
   pop hl
   pop bc
   pop de
   ld a,(de)
   ret
GetArcProgWord:
   push de
   push bc
   ld a,(CurROMPage)
   or a
   jr z,GetArcProgWordReg
   ld b,a
   call AutoArcPtrUpdate
   bcall(_LoadDEIndPaged)
   ex de,hl
   pop bc
   pop de
   ret
GetArcProgWordReg:
   pop bc
   pop de

   ld a,(hl)
   inc hl
   ld h,(hl)
   ld l,a               ;_ldhlind

   ret
AutoArcPtrUpdate:
   bit 7,h
   ret z
   inc b
   res 7,h
   set 6,h
   ret


Important notes:
:: Please excuse any inefficiencies. I wrote these many years ago.
:: I use a one-byte variable, (CurROMPage), to store the page of the current variable, which may change as you read forward, if you hit a page boundary. It you use my routines verbatim, load b into (CurROMPage) after you ChkFindSym.
:: GetArcProgByte gets 1 byte into a and increments the read pointer. GetArcProgWord gets 1 byte into hl and increments the read pointer twice. GetArcProgByteDE looks like something I should have optimized out years ago...

Let me know if you have any questions.
*bump* Just wanted to make sure you saw this. Smile Feel free to ask any follow-up questions.
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement