PageSwap 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 or
FullRene by thepenguin77 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 onSo 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 onOkay, 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 r
1 to r
6, 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
:ReturnNow, 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 hereThen, to change the current app page, use the well-named
setCurPage() 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 !