Using Appvars as "dlls"/executable

Got questions? Got answers? Go here for both.

Moderator: MaxCoderz Staff

Post Reply
Liazon
Calc Guru
Posts: 962
Joined: Thu 27 Oct, 2005 8:28 pm

Using Appvars as "dlls"/executable

Post by Liazon »

the main program is an APP.

I was wondering, can I store executable code in hex form into an APPvar, and then when I need it, can I copy it into RAM and actually execute it like a RAM call?

the executable is somewhat short, and all it does is mainpulate some data, check for error/bounds, and then call higher level graphics routines in the main APP to update the screen and stuff.

Are there any TI-OS executable protection thingys that will prevent such use of ASM to create "modularity"?
Image Image Image
User avatar
tr1p1ea
Maxcoderz Staff
Posts: 4141
Joined: Thu 16 Dec, 2004 10:06 pm
Location: I cant seem to get out of this cryogenic chamber!
Contact:

Post by tr1p1ea »

Yes you can do that, and im certain that people are already doing something similar. xLIB doesnt use appvars because any routines it needs to run in RAM (because of SMC) are no bigger than 768 bytes, therefore i just copy the routine to a saferam area and run it from there.
"My world is Black & White. But if I blink fast enough, I see it in Grayscale."
Image
Image
User avatar
Dwedit
Maxcoderz Staff
Posts: 579
Joined: Wed 15 Dec, 2004 6:06 am
Location: Chicago!
Contact:

Post by Dwedit »

I'd say why bother with hex, when you can just go straight to binary. If you take it further, you could relocate the appvar to the beginning of user memory, and run it just like an assembly shell does.
You know your hexadecimal output routine is broken when it displays the character 'G'.
King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

Post by King Harold »

Not long ago I asked how one could call/jump to a program, as found with _ChkFindSym or if you're making an app anyway you can find it yourself a little faster.
http://kvince83.tengun.net/maxboard/vie ... php?t=2002

Keep in mind that all non-relative adresses that should point someone in the program will now point to either a piece of crap or absolutely nothing (=long row of NOP's) so that would be a little difficult if you're calling big complicated programs, but if its small and with only jr's and no jp's... otherwise you should copy it to the normal location $9d95 or something..

but if its smaller then 768 bytes anyway you could just copy it to saferam when you need it, like tr1p said. But remember to relocate the whole lib if you do that.
Gambit
Sir Posts-A-Lot
Posts: 252
Joined: Mon 21 Feb, 2005 5:34 am
Location: Laveen, Arizona

Post by Gambit »

Are there any TI-OS executable protection thingys that will prevent such use of ASM to create "modularity"?
Other than the hardware limit, not particularly (iirc). As implied before, you'll have to research the various methods of relocation if you want "true" modularity.
"If SOURCE is outlawed, only outlaws will have SOURCE."
Liazon
Calc Guru
Posts: 962
Joined: Thu 27 Oct, 2005 8:28 pm

Post by Liazon »

well, the reason I'd like APPvars is that I'd like to give people the option to fill up their entire calc w/ dlls if they wanted to. If they were ram programs, or something that has to be in ram, I would have to go through the trouble of moving things around a lot between RAM and ROM. Would archiving and unarchiving cause garbage collect and mess up a _chksym or findsym pointer? Cuz that's what happens on 68k.

I'm guessing I can't simply call or bcall using a pointer to the part of the appvar. Well, I guess that means no gs because I'll need lots of spare ram to handle routine switching, and reduce having to keep switching routines. Appvar can be as big as you want right? i forget sorry.

I think I have a semi vague idea of how I will handle this, it's just a question of whether the hardware or the TI-OS will let me, and then I need to figure out how to do this.

I was thinking of making the first byte the # of routines, and then #routines words after that are for some kind of jump table or offset table for the Appvar's address.

Still in the planning stage... and waiting for calc.

edit: i do have one complaint though, but no offense to Kevin Kofler. I was asking how to do this w/ TIGCC, but he told me that dlls in TIGCC were never designed for this purpose. But he did say that I could probably use a basic program hack to achieve something. Right now, I think I have a better idea of how to implement this on z80 only because I'm somewhat familiar w/ z80 ASM, but the amount of data might fit better on 68k. But hey, I'm trying to design this dll system so that people don't have to put the Kamigawa block on their calc if they don't want it.
Image Image Image
User avatar
Dwedit
Maxcoderz Staff
Posts: 579
Joined: Wed 15 Dec, 2004 6:06 am
Location: Chicago!
Contact:

Post by Dwedit »

Warning: Archived variables may be stored accross flash page boundaries. That's why no one executes code directly from the archive, that and the lack of a origin address.
You know your hexadecimal output routine is broken when it displays the character 'G'.
Gambit
Sir Posts-A-Lot
Posts: 252
Joined: Mon 21 Feb, 2005 5:34 am
Location: Laveen, Arizona

Post by Gambit »

Would archiving and unarchiving cause garbage collect and mess up a _chksym or findsym pointer?
Yes, you'll have to re-look it up. However, if I were you, I wouldn't archive/unarchive everytime you wanted to "load" a dll; instead I would use FlashToRAM or some variant thereof (reason being Dwedit's warning).
"If SOURCE is outlawed, only outlaws will have SOURCE."
Liazon
Calc Guru
Posts: 962
Joined: Thu 27 Oct, 2005 8:28 pm

Post by Liazon »

Gambit wrote:
Would archiving and unarchiving cause garbage collect and mess up a _chksym or findsym pointer?
Yes, you'll have to re-look it up. However, if I were you, I wouldn't archive/unarchive everytime you wanted to "load" a dll; instead I would use FlashToRAM or some variant thereof (reason being Dwedit's warning).
how would i find the offset to use flashtoram? _chkfindsym? because I thought it only gives you the start of the variable's data area if it's in RAM, otherwise, just a pointer to the start of it's sym table entry.
Image Image Image
King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

Post by King Harold »

dont forget archived stuff is stored with a copy of the symtable entry, i know its annoying, especially because it doesnt have a fixed size (you'll have to calc something with the namelength)
<crazy idea>What if you copy a block of 768 bytes to saferam, execute it, and then copy the next block, etc? or if you want to use the saferam, copy it to a temporary unarchived thing (appvar probebly) and execute that?<crazy>
Gambit
Sir Posts-A-Lot
Posts: 252
Joined: Mon 21 Feb, 2005 5:34 am
Location: Laveen, Arizona

Post by Gambit »

Yeah, ChkFindSym returns a valid pointer whether archived or not, but if it's archived, you have to watch out for that annoying symbol table stuff, as King Harold said. :)

To help you get started with FlashToRam, here's an excerpt of code from a half-finished old project of mine, PicIDE, which supports loading archived pictures. I added a constant $000C since it was a constant offset, but you'll have to keep track of this number (see KH's post).

And let me just say that it's a good thing this was decently commented. ;)

Code: Select all

	call setOP1Pic			;OP1 = Pic
	;rst rFINDSYM			;b_call(_FindSym)
	rst 10h
	jr c,fileImportNotFound		;carry = reset if found
	;it's found, so copy de to plotSScreen
	call copyDEplotSScreen		;(plotSScreen) has picture

Code: Select all

copyDEplotSScreen:
; -----------------------------------------------------------------------------------------
; Copys (de) to (plotSScreen) # specified by the first 2 bytes of (de)
; Inputs:
;   b - Archive status. 0 if in RAM 
;   de - Address of first byte of data 
; Outputs:
;   (plotSScreen) - data copied
; Destroys:
;   AF BC DE HL
; Takes into account if archived or not
; -----------------------------------------------------------------------------------------
	ld a,b
	cp 0
	jr nz,copyDEplotSScreenArchive
	ld h,d
	ld l,e
	ld c,(hl)
	inc hl
	ld b,(hl)		;bc = size
	inc hl			;hl -> first byte of picture
	ld de,plotSScreen	;de -> plotSScreen
	ldir
	ret
copyDEplotSScreenArchive:
				;b - ROM page
	ex de,hl		;hl -> first byte of data
	;add $000E to skip size
	;add $000C to not skip size
	ld de,$000C		;Skip symbol stuff...
	call BHL_Plus_DE	;hl -> size
	call LoadDEIndPaged_inc	;de - size; b,hl - ROM page and next byte
	ld a,b			;a - ROM page
	ld b,d			;hl - offset of byte in ROM page
	ld c,e			;bc - size of picture
	ld de,plotSScreen	;de - RAM destination
	b_call(_FlashToRam)	;copy flash to ram
	ret

setOP1Pic:
; -----------------------------------------------------------------------------------------
; Initializes OP1 with the Picture variable
; Inputs:
;   a - picture # (Pic1 = 0, Pic0 = 9)
; Outputs:
;   OP1 - picture #
; Destroys:
;   AF BC DE HL
; OP1 = PictObj, tVarPict, tPic#, $00, ??, ??, ??, ??, ?? 
; -----------------------------------------------------------------------------------------
	ld h,0
	ld l,a			;hl = a
	ld a,PictObj
	ld (OP1),a
	ld a,tVarPict
	ld (OP1+1),a
	ld de,NumPicTable
	add hl,de		;hl -> tPic#
	ld a,(hl)		;a = tPic#
	ld (OP1+2),a
	xor a			;a = 0
	ld (OP1+3),a
	ret
	
NumPicTable:
	.db tPic1,tPic2,tPic3,tPic4,tPic5,tPic6,tPic7,tPic8,tPic9,tPic0

LoadDEIndPaged_inc:
	b_call(_LoadDEIndPaged)
inc_BHL:
	inc hl			;increment offset in page
	bit 7,h			;cross page boundary?
	ret z			;no, b, hl - ROM page and offset
	
	inc b			;increase ROM page number
	res 7,h
	set 6,h			;adjust offset to be in $4000 to $7FFF
	ret

BHL_Plus_DE:
	add hl,de
	bit 7,h			;cross page boundary?
	ret z			;no, b, hl - ROM page and offset
	
	inc b			;increase ROM page number
	res 7,h
	set 6,h			;adjust offset to be in $4000 to $7FFF
	ret
(and in case you're wondering why so late a reply, I had no 'net access since the last time I replied :().
"If SOURCE is outlawed, only outlaws will have SOURCE."
Liazon
Calc Guru
Posts: 962
Joined: Thu 27 Oct, 2005 8:28 pm

Post by Liazon »

thanks for the reply

The reason why I asked the question was because I was trying to figure out a method to create the entire Magic: The Gathering card game on a ti-calc, but after reviewing the just the core rules alone, I've realized that there are a LOT of unique features. It would be really hard to design a core engine that would easily be suplemented by dlls for each card set used. Not to mention the fact that the dlls have to be written so that it can handle what to do on both calcs, regardless of whether both had the dll.

The other method would be to create a core dll, kinda like the FAT engine on 68k (actually this might be a good way to implement Magic on 68k) and then write executables for each cardset block.

Either way, the idea is still very hard to implement.

Sorry kv83, I guess I'll have to defer this project to someone else :(

edit: though I'm very grateful to know that it is possible. I don't see any future applications though. Maybe kerm chould code DCS to allow plugins ^^
Image Image Image
User avatar
kv83
Maxcoderz Staff
Posts: 2735
Joined: Wed 15 Dec, 2004 7:26 pm
Location: The Hague, Netherlands
Contact:

Post by kv83 »

Heh, yeah well... there was a good reason why I never tried to do it until now. The only thing that could've worked, if you were using the Starter Sets, instead of Advanced or Core sets. Those are much more simpler cards, yet can give a "good" Magic experience...
Image
Post Reply