Author |
Message |
|
CobyWalker
Newbie
Joined: 03 Jul 2008 Posts: 22
|
Posted: 25 Aug 2008 07:53:27 pm Post subject: |
|
|
Quote: Arrays
An array is an collection of data structures, each exactly the same. The data structure you use can be as simple as a single byte or as complex as a set of records, as long as you are consistent with regards to handling the array. Each of these data structures is otherwise unique and is referred to as an array element, distinguished from each other with an index, which will range from zero to some number. The elements should be contiguous in memory (though this is by no means required, just more efficient).
1-D Arrays
A one-dimensional array can be though of as a list of elements. To access an element, you need a function to convert an element's index into that element's address:
element_address = base_address + (index × element_size)
Where base_address is the address of the array's first element, index is the element you want to get (starting from zero), and element_size is the size (in bytes) of each element.
Example, using this array, and considering each element to be an 8-bit number...
Base Address: $8000
Element Size: One Byte Address $8000 $8001 $8002 $8003 $8004 $8005 $8006 $8007 $8008 $8009 $800A $800B
Element No 0 1 2 3 4 5 6 7 8 9 10 11
Value 232 37 131 103 187 11 86 254 51 204 243 56
...access the 5th element and store it into C:
array_base .EQU $8000
element_size .EQU 3
LD A, (array_base+(4*element_size))
LD C, A
If the index is in a register, you have a bit more work to do.
LD A, 3 ; Put index in A
LD B, A ; Multiply by element size
ADD A, A
ADD A, B
LD D, 0
LD E, A ; Put A in DE
LD HL, array_base ; Add index to base
ADD HL, DE
LD C, (HL)
Look at this above.
Is it possible to make an array over something in the ram?
could this corrupt other data, or can I make it anywhere?
Also if yes, wheres a good place to put it? |
|
Back to top |
|
|
tr1p1ea
Elite
Joined: 03 Aug 2003 Posts: 870
|
Posted: 25 Aug 2008 09:52:09 pm Post subject: |
|
|
You can put data in certain RAM areas, but yeah you do have to be careful. There are special places known affectionately as 'saferam' areas. Here is some info on them courtesy of MV:
Quote: Saferam Areas
-------------
Michael Vincent - michael@radicalsoft.org
** IMPORTANT!
This document merely lists all areas available if your ASM program was running in the TI-OS. Ion, TSE, and MirageOS all use at least one of these areas for themselves. So check your documentation before using an area.
** Areas defined by TI:
OP registers - 8478h - 66 bytes. Don't use any math calls.
textmem - 8508h - 128 bytes. Used to keep a copy of the large font on screen by the TI-OS, but that's not needed in your program.
cmdshadow - 966Eh - 128 bytes. Not sure, but it's safe to use.
tempSwapArea - 82A5h - 323 bytes. If used, AVOID archiving variables in your program. (that's what this area is used for)
iMathPtr1 - 84D3h - 10 bytes. Don't use math calls in your program.
savesscreen - 86ECh - 768 bytes. Used during APD, disable APD in your program first with bcall(_disableapd).
statvars - 8A3Ah - 531 bytes. Don't use statistics, and invalidate the results with bcall(_delres).
appbackupscreen - 9872h - 768 bytes. Free to use.
** Undefined areas, possibly risky
8000h-8100h - 256 bytes - My examination seems to show that this area is only used during garbage collection. So don't archive any variables.
1087 bytes at appData
8100h-8225h - 303 bytes - ramCode, safe to use apparently :)
FE6Ah-FF50h - 230 bytes - This is part of the 400 byte reserved stack space. Sort of a gamble that the stack doesn't need that much space. Most programs will never have enough calls or pushes to get the stack pointer down to FF50h so you can try it. If you have a lot of pushes on at one time (like 20 or so) then you might not want to store data up to FF50h. But you could go to FF00h or so, try with each program to see how much stack space you actually need.
** TOTAL FREE RAM
If you add the space of every area listed in this document, and you run your ASM program from the TI-OS so you can use each one, you have 3 KB of free memory to use. That should be plenty for most ASM programs. |
|
Back to top |
|
|
Liazon title goes here
Bandwidth Hog
Joined: 01 Nov 2005 Posts: 2007
|
Posted: 26 Aug 2008 02:50:41 pm Post subject: |
|
|
if you're writing an app, there's also the _insertmem _delmem trick. just insert the mem at $9d95, which is pretty convenient. |
|
Back to top |
|
|
FloppusMaximus
Advanced Member
Joined: 22 Aug 2008 Posts: 472
|
Posted: 26 Aug 2008 05:49:25 pm Post subject: |
|
|
Well, that works, but you can't just call InsertMem, you also have to check for free memory, and set up a putaway handler to clean up when you're done. Memory leaks are no fun.
I tend to prefer simply using the free space between the FPS and OPS, or placing data in the FPS itself if I need to be able to do math or variable manipulation.
I'd also like to add to what Michael wrote, not to take anything away from his brilliance:
- appData is the area used for ONSCRPT and OFFSCRPT; you must disable scripts if you want to use this area and you use GetKey in your app.
- ramCode is used by a lot of system routines. If you're using more than the most basic B_CALLs in your app, expect ramCode to be overwritten often.
- cmdShadow, of course, is the homescreen. If you use it, overwrite it with spaces and set (cmdShadCur) to 0,0 when you're done.
- tmpSwapArea is a funny one. I'm pretty sure someone at TI made a mistake at some point, and it was intended to be only 232 bytes, not 323. With that said, pretty much the entire area from 8251 to 83E8 is probably about as safe to use as is tempSwapArea proper (i.e., not during archiving, linking, BASIC interpreting, or other advanced OS functions.)
- Michael didn't mention what I'm sure is the most commonly used "saferam" area - plotSScreen, the graph buffer. Of course you may be using it for a screen buffer of some kind, but it's another 768 bytes that shouldn't be ignored. |
|
Back to top |
|
|
sgm
Calc Guru
Joined: 04 Sep 2003 Posts: 1265
|
Posted: 26 Aug 2008 06:34:54 pm Post subject: |
|
|
You can also just plop a bunch of bytes down into your program as a sort of BSS section. Which is pretty much like using the free RAM area anyway, but less clean up is involved. |
|
Back to top |
|
|
calc84maniac
Elite
Joined: 22 Jan 2007 Posts: 770
|
Posted: 26 Aug 2008 07:40:36 pm Post subject: |
|
|
sgm wrote: You can also just plop a bunch of bytes down into your program as a sort of BSS section. Which is pretty much like using the free RAM area anyway, but less clean up is involved.
[post="126412"]<{POST_SNAPBACK}>[/post]
But then it takes up more space... |
|
Back to top |
|
|
DarkerLine ceci n'est pas une |
Super Elite (Last Title)
Joined: 04 Nov 2003 Posts: 8328
|
Posted: 26 Aug 2008 08:16:03 pm Post subject: |
|
|
calc84maniac wrote: sgm wrote: You can also just plop a bunch of bytes down into your program as a sort of BSS section. Which is pretty much like using the free RAM area anyway, but less clean up is involved.
[post="126412"]<{POST_SNAPBACK}>[/post]
But then it takes up more space...
[post="126416"]<{POST_SNAPBACK}>[/post]
It's useful if you want the data to be saved between running the program (though you have to add code for write-back if you're not using a shell). |
|
Back to top |
|
|
FloppusMaximus
Advanced Member
Joined: 22 Aug 2008 Posts: 472
|
Posted: 26 Aug 2008 08:34:35 pm Post subject: |
|
|
Whereas if you are using a shell and you don't need to save the data, you have to clear it when you're done, or the shell will detect it as write-back, resulting in unnecessary re-archiving of the program.
I wouldn't recommend using that method for non-write-back data. If it's just a few variables, you should be able to put them in saferam. If it's a large buffer, then even adding the necessary code to allocate it dynamically, the program will still be smaller in the end.
As a side note, the TI-83 had a feature vaguely similar to TSE, whereby the OS would automatically allocate an extra (uninitialized) data segment at the end of the program code. Of course, that was only for unsquished programs... talk about wasting memory |
|
Back to top |
|
|
asdf
Advanced Newbie
Joined: 17 Aug 2008 Posts: 73
|
Posted: 27 Aug 2008 03:56:38 am Post subject: |
|
|
FloppusMaximus wrote: - appData is the area used for ONSCRPT and OFFSCRPT; you must disable scripts if you want to use this area and you use GetKey in your app. What is appData used for and what are scripts? |
|
Back to top |
|
|
Liazon title goes here
Bandwidth Hog
Joined: 01 Nov 2005 Posts: 2007
|
Posted: 27 Aug 2008 06:01:38 pm Post subject: |
|
|
FloppusMaximus wrote: Well, that works, but you can't just call InsertMem, you also have to check for free memory, and set up a putaway handler to clean up when you're done. Memory leaks are no fun.
why do I keep forgetting to tell people that when I make this suggestion. I guess it's almost a habit for me to check space that I assume others will do so too. my apologies.
just wondering, what would happen if you used _insertmem from a RAM program on say the end of the running program? |
|
Back to top |
|
|
fourchanb
Advanced Newbie
Joined: 24 Sep 2006 Posts: 93
|
Posted: 27 Aug 2008 07:06:35 pm Post subject: |
|
|
I always make temporary appvars, then use these as safe RAM areas. The downside is that you never know where they will show up, but that is usually not a problem with buffers and such. |
|
Back to top |
|
|
Iambian
Advanced Member
Joined: 13 Mar 2004 Posts: 423
|
Posted: 27 Aug 2008 07:25:55 pm Post subject: |
|
|
I recall that there was a special romcall that needed to be used if one were to use all 1087 bytes starting at appData if a FlashAPP needed to quit afterward.
Since I'm trying to write such an application, I'd appreciate it if someone could tell me what that is (if even necessary), since I've grown frustrated searching this forum and Detached Solution's forums, not to mention several fruitless Google searches.
( I don't have access to the IRC logs that would contain the information I'm looking for. ) |
|
Back to top |
|
|
FloppusMaximus
Advanced Member
Joined: 22 Aug 2008 Posts: 472
|
Posted: 27 Aug 2008 10:40:26 pm Post subject: |
|
|
To use 1087 (decimal, I assume) bytes from 8000 to 843F? I would assume you can't. That includes baseAppBrTab and arcInfo. (While the OS presumably does have code to regenerate them when the calculator is reset, and for all I know there's even a B_CALL to do so, it sounds like a bad idea. For one thing, isn't baseAppBrTab needed to look up the app header whenever a hook is called?) It also includes ramCode, which (as I noted above) gets overwritten all the time.
ONSCRPT and OFFSCRPT are appvars that you can create which will be run when the OS turns the calculator on and off. ONSCRPT is enabled by 0,(iy+33h) and OFFSCRPT by 1,(iy+33h). ONSCRPT is run only when waking up from APD; OFFSCRPT is run both after 2nd+Off and before APD. In both cases the OS copies the contents of the appvar to 8001 (if I remember correctly) and runs it. Thus, if APD is enabled, there's a possiblity that these scripts could be run at any time. (This isn't just a theoretical question; TI's Start-Up app uses OFFSCRPT, as does Krolypto, so many users will have these scripts installed and enabled.)
Anyway, if you save, clear, and restore (with a putaway handler if necessary) those two flags, using appData should be just fine. The area is also used for cryptography stuff, which most apps will never run into. I use appData fairly often -- it's very convenient for a lookup table.
Inserting memory at the end of your program: I think there's a way to do this safely; I don't remember how, but I believe the OS stores the size of the assembly program somewhere, so you can find that value and update it. Needless to say it won't work if you're running in a shell; every shell handles program loading differently. |
|
Back to top |
|
|
brandonw
Advanced Member
Joined: 12 Jan 2007 Posts: 455
|
Posted: 28 Aug 2008 09:38:38 am Post subject: |
|
|
FloppusMaximus wrote: To use 1087 (decimal, I assume) bytes from 8000 to 843F? I would assume you can't. That includes baseAppBrTab and arcInfo. (While the OS presumably does have code to regenerate them when the calculator is reset, and for all I know there's even a B_CALL to do so, it sounds like a bad idea. For one thing, isn't baseAppBrTab needed to look up the app header whenever a hook is called?) It also includes ramCode, which (as I noted above) gets overwritten all the time.
ONSCRPT and OFFSCRPT are appvars that you can create which will be run when the OS turns the calculator on and off. ONSCRPT is enabled by 0,(iy+33h) and OFFSCRPT by 1,(iy+33h). ONSCRPT is run only when waking up from APD; OFFSCRPT is run both after 2nd+Off and before APD. In both cases the OS copies the contents of the appvar to 8001 (if I remember correctly) and runs it. Thus, if APD is enabled, there's a possiblity that these scripts could be run at any time. (This isn't just a theoretical question; TI's Start-Up app uses OFFSCRPT, as does Krolypto, so many users will have these scripts installed and enabled.)
Anyway, if you save, clear, and restore (with a putaway handler if necessary) those two flags, using appData should be just fine. The area is also used for cryptography stuff, which most apps will never run into. I use appData fairly often -- it's very convenient for a lookup table.
Inserting memory at the end of your program: I think there's a way to do this safely; I don't remember how, but I believe the OS stores the size of the assembly program somewhere, so you can find that value and update it. Needless to say it won't work if you're running in a shell; every shell handles program loading differently.
[post="126435"]<{POST_SNAPBACK}>[/post]
It's obviously not the most ideal thing to do, but if you're not using anything which uses that area of RAM, you can use it. The BCALL is 5011h, by the way. |
|
Back to top |
|
|
FloppusMaximus
Advanced Member
Joined: 22 Aug 2008 Posts: 472
|
Posted: 28 Aug 2008 09:04:53 pm Post subject: |
|
|
In other words, if you use your own ISR and never use any OS code, ever. |
|
Back to top |
|
|
Iambian
Advanced Member
Joined: 13 Mar 2004 Posts: 423
|
Posted: 28 Aug 2008 09:32:30 pm Post subject: |
|
|
Thanks for the info, brandonw. As far as the code is going, I will be using my own ISR and I won't be using using any OS code for the duration of what I'll be needing the buffer for, save for that one romcall to put it all back together when I'm finished.
btw, this application is going towards a game that I haven't really announced anywhere but on a channel on IRC. |
|
Back to top |
|
|
brandonw
Advanced Member
Joined: 12 Jan 2007 Posts: 455
|
Posted: 29 Aug 2008 12:17:36 am Post subject: |
|
|
FloppusMaximus wrote: In other words, if you use your own ISR and never use any OS code, ever.
[post="126444"]<{POST_SNAPBACK}>[/post]
That block of memory isn't used by the interrupt. It's safer than it appears. |
|
Back to top |
|
|
FloppusMaximus
Advanced Member
Joined: 22 Aug 2008 Posts: 472
|
Posted: 29 Aug 2008 04:06:00 pm Post subject: |
|
|
Off the top of my head, the ISR can call the cursor hook, the USB hook, and can APD. Even if you turn all those things off, you're still betting that TI never adds any new functionality to the ISR. |
|
Back to top |
|
|
|