Using Appvars as "dlls"/executable
Moderator: MaxCoderz Staff
Using Appvars as "dlls"/executable
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"?
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"?
-
- Calc King
- Posts: 1513
- Joined: Sat 05 Aug, 2006 7:22 am
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.
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.
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.Are there any TI-OS executable protection thingys that will prevent such use of ASM to create "modularity"?
"If SOURCE is outlawed, only outlaws will have SOURCE."
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.
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.
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).Would archiving and unarchiving cause garbage collect and mess up a _chksym or findsym pointer?
"If SOURCE is outlawed, only outlaws will have SOURCE."
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.Gambit wrote: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).Would archiving and unarchiving cause garbage collect and mess up a _chksym or findsym pointer?
-
- Calc King
- Posts: 1513
- Joined: Sat 05 Aug, 2006 7:22 am
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>
<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>
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.
(and in case you're wondering why so late a reply, I had no 'net access since the last time I replied ).
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
"If SOURCE is outlawed, only outlaws will have SOURCE."
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 ^^
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 ^^