Omnimaga

Calculator Community => TI Calculators => Axe => Topic started by: Matrefeytontias on December 11, 2012, 01:58:02 pm

Title: [Tutorial] Using the PageSwap axiom
Post by: Matrefeytontias on December 11, 2012, 01:58:02 pm
PageSwap (http://ourl.ca/17182) is an Axiom made by myself which allows you to use Axe subroutines you defined in another program and compiled separately as an app directly in your classic Axe program.

What's the benefit for it ? Well, imagine that your Axe program is so large that it can't fit in the RAM, even if it's all free (this means that your program is greater than 24K). You can write 16K of code in an app as subroutines, make a 8k program and use PageSwap to access this last app and use the functions you defined in it. The result is 24K of executable code which take only 8k of RAM. You can even use CrabCake by Hot_Dog (http://ourl.ca/11085) or FullRene by thepenguin77 (http://ourl.ca/13513) to overpass the 8K limit, to have still moar executable code ! And more of that, you can also use PageSwap with several apps, which is 16K of executable code per app !

So, how to use this axiom ? It can be pretty complicated due to all the things you have to beware when you use that.

First, we need an API. It's an Axe program you'll compile into an app and which will contain all of your subroutines. Let's call it AppTest (app names can contain lowercase). Then we need a program to use these subroutines, let's call it APPTEST in uppercase (yeah, I'm lacking names). That's all what we need.

So, our app needs to have a specific format. Since it's a lib, it must contains functions. And in order to know where are located all of these functions, we do a jump table.

:.AppTest
:
:Goto Func1
:Goto Func2
:Goto Func3
:.and so on
:
:Lbl Func1
:. code here
:Return
:
:Lbl Func2
:.same
:Return
:
:Lbl Func3
:.same again
:Return
:
:.and so on


So when in your code you need to call one of these funcs, you'll just have to call the corresponding Goto (which has a fixed address the axiom knows).

But wait, we must not run this app ! So let's write a Start function that exits the app when the user launches it :

:.AppTest
:
:.Execution will start here
:Goto Start
:Goto Func1
:Goto Func2
:Goto Func3
:.and so on
:
:Lbl Start
:ClrHome
:Text(0,,"This app is an Axe lib
:Text(0,8,"It's not meant to be ran
:Text(0,16,"Press any key to quit
:getKeyr
:Return
:
:Lbl Func1
:. code here
:Return
:
:Lbl Func2
:.same
:Return
:
:Lbl Func3
:.same again
:Return
:
:.and so on


Okay, now we have a pattern for our API !

You can write your subroutines the same way you write ones in a classic Axe source. So you can use r1 to r6, static pointers (GDB, Pic ...) and so on.

When, let's fill these routines with something so we'll can use them.

:.AppTest
:
:Goto Start
:Goto Func1
:Goto Func2
:Goto Func3
:
:Lbl Start
:ClrHome
:Text(0,,"This app is an Axe lib
:Text(0,8,"It's not meant to be ran
:Text(0,16,"Press any key to quit
:getKeyr
:Return
:
:Lbl Func1
:Pt-On(r1,r2,r3
:Return
:
:Lbl Func2
:Text(r1,r2,r3
:Return
:
:Lbl Func3
:DispGraph
:Return


Now, let's write our prgmAPPTEST program. First, let's include PageSwap.

:.APPTEST
:
:#Axiom(PAGESWAP)


Now, you can start working with PageSwap.

Using PageSwap is a bit complicated since it works with really low level things : app pages. When you launch a regular program (I mean not an app), it's usually from the page 0, which is the RAM. Now, you want to access your lib which is an app, but apps aren't stored in page 0. So, you'll need to go to the page of your app, use the routines inside, and when you're done with it go back to the page 0 before exit your program.

You'll say "hey, but what if I launch my program from flash using a shell ?" In fact that remains the same : the program must exit in the same page as the one which he started. So at the start of APPTEST, just save your current page by using PageSwap's getCurPage (all the PageSwap commands are the Angle menu [2nd] [apps]).

:.APPTEST
:#Axiom(PAGESWAP)
:
:getCurPage?P
:
:.code here


Then, to change the current app page, use the well-named setCurPage() :P

But which page must we go in ? You know that we want to access AppTest to be able to use the subroutines in it. So search for your app by using getAppPage("APP"), and then set the current page to it.

:.APPTEST
:#Axiom(PAGESWAP)
:
:getCurPage?P
:setCurPage(getAppPage("AppTest"))
:
:.Don't forget to restore the initial page before quitting !
:setCurPage(P)


Now that you're in the page of your app, you can use its functions ! Well, in fact you don't know the addresses of your functions ... but PageSwap does ! Just retrieve the address of the Nth function of your app by using appFunc(N), then call it with Axe's (ADDR)(ARGS). Beware, the 0th function is the Start function !

:.APPTEST
:#Axiom(PAGESWAP)
:
:getCurPage?P
:setCurPage(getAppPage("AppTest"))
:
:.You have to remember which function does what
:(appFunc(1))(0,8,[3C4281818181423C])
:(appFunc(3))()
:(appFunc(2))(0,0,"Over 9000!")
:getKeyr
:
:setCurPage(P)


Now compile AppTest into an app, APPTEST into Noshell, try to run AppTest, run APPTEST, and see !

And that's all, now you know how to use PageSwap !

Now, go make a 40KB-large program ! :P
Title: Re: [Tutorial] Using the PageSwap axiom
Post by: V1mes on December 11, 2012, 02:17:32 pm
Now, go make a 40KB-large program ! :P

Yessir!

Awesome axiom, nice work!
Title: Re: [Tutorial] Using the PageSwap axiom
Post by: V1mes on December 14, 2012, 07:37:26 am
Hmm can I call Goto within the functions in the lib?
E.g.

Lbl Func1
If ...
Goto Func2
End
Return
Title: Re: [Tutorial] Using the PageSwap axiom
Post by: Xeda112358 on December 14, 2012, 07:50:35 am
Very cool, Matrefeytontias :D This will make it much easier for people to use Apps :D I am curious, though, do Axe apps not start at 4080h? (I think when I tested it, it was 408Ch or something .__.)

@V1mes: I am pretty sure you can :) It won't cause any problems :D
Title: Re: [Tutorial] Using the PageSwap axiom
Post by: V1mes on December 14, 2012, 08:01:03 am
@Xeda... thank you!
Title: Re: [Tutorial] Using the PageSwap axiom
Post by: Matrefeytontias on December 14, 2012, 08:05:31 am
@Xeda Lbl Start is at $408B as far as I remember.

@V1mes yeah, you can :)
Title: Re: [Tutorial] Using the PageSwap axiom
Post by: Xeda112358 on December 14, 2012, 08:19:00 am
Ah, thanks much Matrefeytontias :D I wonder why there are 11 extra bytes? o_O It's probably to identify it as an Axe App.
Title: Re: [Tutorial] Using the PageSwap axiom
Post by: Sorunome on December 15, 2012, 06:30:15 pm
wow, this is pretty epic, i'll soooooooooooooooooo use it! :D
Title: Re: [Tutorial] Using the PageSwap axiom
Post by: DJ Omnimaga on December 15, 2012, 11:13:08 pm
Interesting, although for a massive game, if there are multiple apps showing up in the Axe menu, that might be a bit confusing for the player, since he might run apps he shouldn't. :P (unless it's possible through your axiom to hide/unhide specific apps from the menu?)
Title: Re: [Tutorial] Using the PageSwap axiom
Post by: thepenguin77 on December 15, 2012, 11:33:38 pm
After you are happy with your tutorial, you should cross post it

(http://img.removedfromgame.com/imgs/da_here.png)

I'm not sure how many people actually go to those sections, but it's better than getting buried in all the threads.
Title: Re: [Tutorial] Using the PageSwap axiom
Post by: Matrefeytontias on December 16, 2012, 02:40:11 am
@DJ_O that's true, but you can specify in your Start func the name of the prgm to launch. And no, I can't hide/unhide apps.

@thepenguin77 yeah I'd love to, but idk how to do :P
Title: Re: [Tutorial] Using the PageSwap axiom
Post by: V1mes on December 19, 2012, 08:16:37 am
Another trivial question:

Say I have

Code: [Select]
Goto Start
Goto Func1
Goto Func2
Goto Func4

Lbl Start
...
Return

Lbl Func1
...
Return

Lbl Func2
...
sub(Func3)
...
Return

Lbl Func3
...
Return

Lbl Func4
...
Return
in my lib app.

will appFunc(3)(r1,r2,...) execute Func4 or Func3?
Title: Re: [Tutorial] Using the PageSwap axiom
Post by: stevon8ter on December 19, 2012, 12:35:06 pm
No, the Func3 is a routine on itself, so even running it within another routine... You can still run it alone...
Title: Re: [Tutorial] Using the PageSwap axiom
Post by: V1mes on December 19, 2012, 12:46:39 pm
I'm sorry I don't understand your answer  :-\
Title: Re: [Tutorial] Using the PageSwap axiom
Post by: stevon8ter on December 19, 2012, 12:51:38 pm
Well, you've got 4 routines... Func1,2,3,4
And Func3 is just used in Func2 as well... But that doesn't make the Func3 dissapear... So the appFunc3 = Func3


Ooh or i missunderstood you're question, you mean like: is appFunc0 = Func1
And appFunc1 = Func2

Hmm that idk, you'dd have to find it out.. Just test with a little program and you'll know..
Title: Re: [Tutorial] Using the PageSwap axiom
Post by: V1mes on December 19, 2012, 01:05:42 pm
Ok i made a small mistake thanks for pointing it out. I edited my question  :angel:
Title: Re: [Tutorial] Using the PageSwap axiom
Post by: DJ Omnimaga on December 19, 2012, 01:45:53 pm

@thepenguin77 yeah I'd love to, but idk how to do :P
Click the link he pointed to, then navigate to the tutorials section you want (eg Axe), then at the bottom of the page, click "Add article". Just make sure to include a link to this topic at the end of your tutorial. You just have to copy the content of your post there.
Title: Re: [Tutorial] Using the PageSwap axiom
Post by: Matrefeytontias on December 19, 2012, 01:51:19 pm
Remember that appFunc(0) is the Start function. So in your code (appFunc(3))() will call Func3, and (appFunc(4))() will call Func4 (and btw (appFunc(0))() will call Start).
Title: Re: [Tutorial] Using the PageSwap axiom
Post by: V1mes on December 19, 2012, 02:05:49 pm
Does it not matter then that i have not included func3 in the jump table?