[TI-ASM] Memory allocation and management

Got questions? Got answers? Go here for both.

Moderator: MaxCoderz Staff

User avatar
benryves
Maxcoderz Staff
Posts: 3089
Joined: Thu 16 Dec, 2004 10:06 pm
Location: Croydon, England
Contact:

Post by benryves »

brandonw wrote:If you're dead set on that, you COULD just find a variable that's at least 768 bytes big, copy its contents to a saferam area (and its VAT entry) [...] That's also guaranteeing there's a variable on the calculator that's at least 768 bytes big, but you could put some logic in to take lots of small variables, too.
I have no qualms about creating a temporary variable (that was my intention); it's more the question of how one guarantees it is located at 9D95. (Usually I have access to the code so I can live with the TI-OS putting the variable anywhere in RAM).

I guess I should look at the source to a shell. :)
brandonw
New Member
Posts: 17
Joined: Thu 21 Jun, 2007 1:11 pm

Post by brandonw »

Yeah, it's swapped in 768 bytes at a time to userMem by repeated calls to _InsertMem and _DelMem, to relocate it to userMem.
User avatar
Dwedit
Maxcoderz Staff
Posts: 579
Joined: Wed 15 Dec, 2004 6:06 am
Location: Chicago!
Contact:

Post by Dwedit »

Venus doesn't do it that way, it instead uses a fast swapping algorithm to swap data, then it calls the undocumented _delmemupdate.
You know your hexadecimal output routine is broken when it displays the character 'G'.
User avatar
benryves
Maxcoderz Staff
Posts: 3089
Joined: Thu 16 Dec, 2004 10:06 pm
Location: Croydon, England
Contact:

Post by benryves »

OK, so, er, how do you relocate a variable to $9D95?

You mention InsertMem and DelMem, but those surely depend on having a variable in the right place to locate the variable to? I couldn't just call InsertMem with DE = $9D95 and HL = 874 to make sure TI-OS doesn't decide to do anything in the area between $9D95 and $A0FF? Where exactly would you need to delete the memory from and insert it to? :|

Sorry if this should be obvious, but I really have no idea what I need to be doing.
User avatar
Dwedit
Maxcoderz Staff
Posts: 579
Joined: Wed 15 Dec, 2004 6:06 am
Location: Chicago!
Contact:

Post by Dwedit »

They do not depend on a variable being located at 9D95. Everything located at 9D95 and after will be pushed forward in RAM.

edit: not completely sure about this post anymore...
Last edited by Dwedit on Tue 03 Jun, 2008 11:08 pm, edited 1 time in total.
You know your hexadecimal output routine is broken when it displays the character 'G'.
User avatar
Dwedit
Maxcoderz Staff
Posts: 579
Joined: Wed 15 Dec, 2004 6:06 am
Location: Chicago!
Contact:

Post by Dwedit »

Here's a possibly useful (and mostly unused) romcall!
DelVar3DC (bcall $4360)
hl = insertion location, bc = number of bytes to 'insert'
Updates VAT entries as if insertmem was called, but does not insert memory
Not sure if it does negative values as well, I think it might.
This means you can use the really fast Venus method of relocating RAM variables on a TI83+.

Venus's algorithm:
(C version, you can also look at venus's source code to get the asm version)

Code: Select all

void swapmem (u8* A, u8*B, int Asize)
{
//relocates A's memory block to location B
//for overlapping memory regions
//B is a base, and A appears in memory after B
	int i;
	u8 t;
	int Bsize;
	do
	{
		for (i=0;i<Asize;i++)
		{
			t=*A;
			*A=*B;
			*B=t;
			A++;
			B++;
		}
		Bsize=A-B;
		Asize=Asize % Bsize;
		A=B+Bsize-Asize;
	} while (Asize!=0);
}
You know your hexadecimal output routine is broken when it displays the character 'G'.
brandonw
New Member
Posts: 17
Joined: Thu 21 Jun, 2007 1:11 pm

Post by brandonw »

When you _InsertMem at 9D95h, you're stealing that RAM temporarily. You can do with it as you like, then when you're done, _DelMem at 9D95h the same amount you inserted.
It can also be used on the data area of variables, so you can _DelMem from the data area of the variable, and _InsertMem the same chunk of memory to 9D95h. So in a way, you're shrinking the size of the program and copying the data you ripped out, to 9D95h. Then to relocate it back, you'd enlarge the program's data area, and stick the stuff from 9D95h into it. Then delete the "copy" from 9D95h.

I don't guess it's a simple thing to explain, which is why it's not written down anywhere. If you want code to look at, you could check one of the open source shells...I don't know which ones are open, but CrunchyOS possibly, and Noshell.

EDIT: And DoorsCS.
User avatar
benryves
Maxcoderz Staff
Posts: 3089
Joined: Thu 16 Dec, 2004 10:06 pm
Location: Croydon, England
Contact:

Post by benryves »

Oh, so it really is that easy. :) Cheers!
When you _InsertMem at 9D95h, you're stealing that RAM temporarily. You can do with it as you like, then when you're done, _DelMem at 9D95h the same amount you inserted.
The TI docs refer to using InsertMem/DelMem with existing variables, hence my confusion.

I allocate from $9D95 to min($BFFF, $9D95 + free RAM) using this method, and it appears to work fine.
User avatar
driesguldolf
Extreme Poster
Posts: 395
Joined: Thu 17 May, 2007 4:49 pm
Location: $4080
Contact:

Post by driesguldolf »

Heh, I'll just confirm what brandonw said (as he is the one that told me sometime I think...)

Code: Select all

; Allocate space for smc routines
	ld hl, smcsize
	B_CALL(_enoughmem)
	jp nc, +
	B_JUMP(_errmemory)
+
	ex de, hl
	ld de, $9D95
	B_CALL(_insertmem)

; Copy routines that use SMC to RAM
	ld hl, libs_end
	ld de, $9D95
	ld bc, libs_endsmc - libs_startsmc
	ldir
And to quit:

Code: Select all

exitapp:
; Release memory used by smc routines
	ld hl, $9D95
	ld de, smcsize
	B_CALL(_delmem)

; Invalidate some stuff
; Invalidate graph is handy in class when you just pressed the teacher key and you have to show the teacher your graph
; You won't be able to get screenshots this way, make it an option?
	;set graphdraw, (iy + graphflags)
	res statsvalid, (iy + statflags)

; Sync tios with hardware (A bit unneeded but hey, it's fancy :P)
; The halt is needed because tios checks the keys during an interrupt
	im 1
	ei
	halt
	B_CALL(_getcsc)

; And quit to the home screen
; Apparently stack level doesn't matter...
	B_JUMP(_jforcecmdnochar)
Is what I use, it works like a charm.
Apparently TIOS uses $9D95 and following to store Ans/ Input buffer related stuff since that got messed up when I didn't initialized that RAM.
User avatar
Dwedit
Maxcoderz Staff
Posts: 579
Joined: Wed 15 Dec, 2004 6:06 am
Location: Chicago!
Contact:

Post by Dwedit »

9D95 is used for whatever variable is located there. It could be Ans, it could be a program, etc. If you move a program to 9D95, it will stay there until it's deleted or another program gets moved to 9D95.

If you're using an app, and need memory at a specific location, I strongly recommend using a temporary variable, and relocating it to 9D95. Then you just have the two size bytes at 9D95, then the rest of the variable follows. This way, you avoid memory leaks if the application does not quit naturally. Turning the calc off while inside a Getkey is an easy way to get memory leaks.
You know your hexadecimal output routine is broken when it displays the character 'G'.
User avatar
benryves
Maxcoderz Staff
Posts: 3089
Joined: Thu 16 Dec, 2004 10:06 pm
Location: Croydon, England
Contact:

Post by benryves »

This way, you avoid memory leaks if the application does not quit naturally.
I suppose there are some advantages to not using the TI-OS for anything other than the variable manipulation routines. :)
User avatar
driesguldolf
Extreme Poster
Posts: 395
Joined: Thu 17 May, 2007 4:49 pm
Location: $4080
Contact:

Post by driesguldolf »

benryves wrote:
Dwedit wrote:This way, you avoid memory leaks if the application does not quit naturally.
I suppose there are some advantages to not using the TI-OS for anything other than the variable manipulation routines. :)
Agreed,
I'm also one of those people who think TIOS is the worst thing ever made. 8)

And the only way I quit is via exitapp (which shouldn't leak memory) or by removing a battery. :P
brandonw
New Member
Posts: 17
Joined: Thu 21 Jun, 2007 1:11 pm

Post by brandonw »

If you were using the OS properly, you'd use PutAway and the other monitor vectors for cleanup code in cases like turning off from GetKey.

You have to give the OS some credit...horrible as it can be under the hood, it does its job well.
Post Reply