Omnimaga

Calculator Community => TI Calculators => Axe => Topic started by: thepenguin77 on February 17, 2012, 04:47:13 pm

Title: Calling one axe program from another
Post by: thepenguin77 on February 17, 2012, 04:47:13 pm
Bet you didn't think you'd see a topic from me.

In any case, we just discussed it on IRC, and there's a pretty simple way to call one axe program from another.

Code: [Select]
Copy("prgmNAME",33912,9
asm(EF7C4E)

This will work as long as prgmNAME is in ram, so if it's not, you'll have to unarchive it first. Hopefully someone has fun with this.

Edit:
   And here's (http://ourl.ca/9465/181010) how you do Basic programs.
Title: Re: Calling one axe program from another
Post by: squidgetx on February 17, 2012, 09:14:00 pm
Woah, that's pretty nice. I knew that you could do it from an app, but I didn't imagine that it could work from program-to-program.

Incidentally, where is 33912?  Does it corrupt any other data? And would using Return in the called program return to the homescreen or return to the parent program?
Title: Re: Calling one axe program from another
Post by: DJ Omnimaga on February 17, 2012, 09:14:58 pm
Nice, I totally forgot about the BASIC one until it was linked to on IRC earlier. Glad to see an Axe one. Can conflict happen between programs?
Title: Re: Calling one axe program from another
Post by: chattahippie on February 17, 2012, 09:58:13 pm
Woah, that's pretty nice. I knew that you could do it from an app, but I didn't imagine that it could work from program-to-program.

Incidentally, where is 33912?  Does it corrupt any other data? And would using Return in the called program return to the homescreen or return to the parent program?

According to thepenguin77, 33912 is the location of OP1
Title: Re: Calling one axe program from another
Post by: Yeong on February 18, 2012, 12:23:04 pm
can you call the program within the program that is being called?
Title: Re: Calling one axe program from another
Post by: thepenguin77 on February 20, 2012, 04:02:26 pm
can you call the program within the program that is being called?

I assume you are asking if a program can call itself? The answer is yes, but only if the program was not run with a shell. If it was run with a shell, you are going to run into problems.
Title: Re: Calling one axe program from another
Post by: thydowulays on February 20, 2012, 06:40:54 pm
Does this work with any ASM program or just ones compiled with Axe?
Title: Re: Calling one axe program from another
Post by: Xeda112358 on February 20, 2012, 06:53:38 pm
It should work with all Asm programs :) (but you might need to wait for confirmation)
Title: Re: Calling one axe program from another
Post by: calc84maniac on February 20, 2012, 07:04:39 pm
If you want a program to call itself, just put a label at the beginning of the program and call it using a normal subroutine, I'd say.
Title: Re: Calling one axe program from another
Post by: kindermoumoute on February 24, 2012, 11:44:56 am
It doesn't work... it always crash.
Title: Re: Calling one axe program from another
Post by: chattahippie on February 24, 2012, 04:19:17 pm
It doesn't work... it always crash.
Make sure the Asm program is compiled for No Shell, or else it will crash
Title: Re: Calling one axe program from another
Post by: kindermoumoute on February 24, 2012, 05:18:29 pm
I'm sure, have you tested it ? Please show me a screen if you think it work, but I tested twice : on my real 83+ and on wabbitemu (84+SE). :/
Title: Re: Calling one axe program from another
Post by: DrDnar on February 24, 2012, 05:32:48 pm
Yes, it's OP1. Yes, control is returned the caller. This code just calls the OS routine that runs assembly programs. You can even run unsquished programs this way. (Ignore the last statement if you don't know what a squished program is.)

However, keep in mind a few things:
Title: Re: Calling one axe program from another
Post by: kindermoumoute on February 24, 2012, 05:54:08 pm
Have you tested it ? Does it work with your calc ? O_o

Damn, where is the problem on my code ?
Title: Re: Calling one axe program from another
Post by: DrDnar on February 24, 2012, 06:22:44 pm
Huh. . . . it looks like you're doing nothing wrong. I wrote a test program myself and found a problem in the disassembly:

prgmA
Code: [Select]
.AAA
Disp "ONE...",i
Copy("prgmAAAA",33912,9
Asm(EF7C4E
Disp "...ONE.",i
Pause 2000

prgmAA
Code: [Select]
.AAAA
Disp "TWO",i

Disassembly:
prgmAAA
Code: [Select]
9D95: ld hl, 9DC3 ; Disp "ONE...",i
bcall(_450A)
bcall(_452E)
ld hl, 9DCAh ; Copy("prgmAAAA",33912,9
push hl ; Load arguments in a complicated fashion
ld hl, 8478h
ld bc, 0009
ex de, hl
pop hl
ldir ; Copy the data
ldir ; Clobber all of RAM
ld c, (hl) ; ???
ld hl, 9DD0h ; Disp "...ONE.",i
bcall(_450A)
bcall(_452E)
ld hl, 07D0h ; Pause 2000
9DBB: djnz 9DBB
dec hl
ld a, l
or h
jr nz, 9DBB
ret ; End of program code
9DC3: .db "ONE...", 0
9DCB: .db ProgObj, "AAAA", 0
9DD0: .db "...ONE.", 0

prgmAAAA
Code: [Select]
9D95: ld hl, 9D9F ; Disp "TWO",i
bcall(_450A)
bcall(_452E)
ret ; End of program code
9D9F: .db "TWO", 0

For some reason, Axe 1.1.2 is inserting the ldir twice, clobbering all of RAM. NOPing one of the ldirs out fixes it.


EDIT: Runer112 has a workaround for you:
Quote
(6:43:18 PM) DrDnar: Runer112: I found an Axe bug, see http://ourl.ca/15239/286978
(6:43:32 PM) Runer112: I saw
(6:43:39 PM) DrDnar: k
(6:43:53 PM) Runer112: I can tell you it's a peephole optimizer problem
(6:44:00 PM) Runer112: so you can fix it by compiling without peephole opts [Use ZOOM---DrDnar]
(6:44:08 PM) Runer112: but I can't tell you why it's happening
(6:44:48 PM) Runer112: I'm sure Quigibo will know it's a peephole optimizer problem too
(6:44:51 PM) Runer112: it's pretty clear
Title: Re: Calling one axe program from another
Post by: chattahippie on February 24, 2012, 06:44:07 pm
So is there a way to easily (on calc) fix this, manually or auto?  Or does it require changing it on the computer?
Title: Re: Calling one axe program from another
Post by: kindermoumoute on February 24, 2012, 06:47:35 pm
To conclude, how to to fix it ?
Title: Re: Calling one axe program from another
Post by: chattahippie on February 24, 2012, 06:48:23 pm
On IRC, Runer suggested Zoom compiling the source, and it seems to work
Title: Re: Calling one axe program from another
Post by: DrDnar on February 24, 2012, 11:39:17 pm
I've got an epic solution and optimization for you all. I can both eliminate the problem with Copy( and reduce the code size by about ten bytes.
Code: [Select]
"prgmNAME"Asm(E7EF7C4EBAM! One-liner.
EDIT: This code causes a memory leak; see below (http://ourl.ca/15239/288877) for the fix.

For the curious:
Code: [Select]
ld hl, ptrToName
rst rMOV9TOOP1
bcall(_ExecutePrgm)


Also, to recap: The peep-hold optimizer is causing crashes with the Copy( command sometimes. You can stop Axe from doing the peep-hole optimization with ZOOM. However, it's all a moot point since I just replaced the Copy( command with the single assembly instruction rst rMOV9TOOP1.
Title: Re: Calling one axe program from another
Post by: chattahippie on February 25, 2012, 12:41:17 am
I've got an epic solution and optimization for you all. I can both eliminate the problem with Copy( and reduce the code size by about ten bytes.
Code: [Select]
"prgmNAME"Asm(E7EF7C4EBAM! One-liner.

For curious:
Code: [Select]
ld hl, ptrToName
rst rMOV9TOOP1
bcall(_ExecutePrgm)


Also, to recap: The peep-hold optimizer is causing crashes with the Copy( command sometimes. You can stop Axe from doing the peep-hole optimization with ZOOM. However, it's all a moot point since I just replaced the Copy( command with the single assembly instruction rst rMOV9TOOP1.
Thanks for the fix :D
Title: Re: Calling one axe program from another
Post by: Jonius7 on February 25, 2012, 06:01:58 am
Could this somehow be added to the next version of Axe? Good thought for starting this topic, penguin77.
Title: Re: Calling one axe program from another
Post by: kindermoumoute on February 25, 2012, 06:30:48 am
Damn, is work perfectly ! :D

* kindermoumoute wonder if there is a way to start asm program compatible with shells...
Title: Re: Calling one axe program from another
Post by: Quigibo on February 28, 2012, 02:55:57 am
Yeah sorry about that, I've fixed this problem but haven't released the update yet.
Title: Re: Calling one axe program from another
Post by: chattahippie on March 01, 2012, 08:35:30 pm
I think I found a bug with this... it causes my RAM to steadily decrease
I tried running both programs seperately, took out the "prgmNAME"Asm(E7EF7C4E) command, chose the same options on the menu (except no program was run from it), and no memory was lost ???

As you can see in the screenie, nothing was created, yet about 5000 bytes of memory disappeared (15000 at start to 10000 at finish) :(
Title: Re: Calling one axe program from another
Post by: Yeong on March 01, 2012, 09:10:09 pm
You can try this:

Type 1 in homescreen, press enter, and check memory again.
Title: Re: Calling one axe program from another
Post by: chattahippie on March 01, 2012, 09:16:32 pm
You can try this:

Type 1 in homescreen, press enter, and check memory again.

Tried that, it doesn't fix it
Still about 2000-2500 bytes lost per run :(
Title: Re: Calling one axe program from another
Post by: DrDnar on March 03, 2012, 12:18:29 am
How are you quitting from the second program? It looks like the subprogram is quitting in a manner that prevents the memory being used by the caller from being freed.
Title: Re: Calling one axe program from another
Post by: DrDnar on March 03, 2012, 04:29:36 pm
Update: I blame thepenguin77's for this one. Looking at the disassembly of _ExecutePrgm, it's clear that the OS does not save the value in 89ECh (a.k.a. asm_prgm_size) before modifying it, so it turns out that the memory used by the caller will never be properly freed, unless you save it yourself. Fortunately, that's easy to do, so here's the new version:
Code: [Select]
"prgmNAME"Asm(E72AEC89E5EF7C4EE122EC89Edit: calc84maniac suggested rearranging the assembly instruction sequence to make it less ugly, though no smaller or faster.

So, once again, keep these points in mind:


OS Disassembly:
Code: [Select]
OS 2.55MP _ExecutePrgm disassembly
07:5758:
ld a, 03h
call 3891h
ld a, 38h
jp nz, 2793h
call 178Bh
ex de, hl
ld c, (hl)
inc hl
ld b, (hl)
inc hl
ld a, (hl)
cp 0BBh
jp nz, 2729h
inc hl
ld a, (hl)
cp 6Dh
jr nz, 57D4h
inc hl
push hl
push bc
pop de
push de
ld hl, 2000h
or a
sbc hl, de
jp c, 2729h
ex de, hl
call 1735h
pop hl
push hl
ld de, 9D95h
call 0F81h
pop hl
ld (89ECh), hl
pop hl
ld de, 9D95h
ld bc, (89ECh)
add hl, bc
ldir
579Fh: call 1837h
jr nz, 57AEh
in a, (20)
push af
bit 5, (iy+24h)
call 0DCBh
57AEh: ld hl, 5800h
call 27DAh
call 57FDh
call 2800h
call 1837h
jr nz, 57C4h
pop af
and 01
out (20), a
57C4h: ld de, (89ECh)
ld hl, 0000h
ld (89ECh), hl
ld hl, 9D95h
jp 1368h
57D4h: rst 18h ;rPUSHREALO1
call 5717h
ld hl, 2000h
or a
sbc hl, de
jp c, 2729h
ex de, hl
push hl
call 1735h
pop hl
push hl
ld de, 9D95h
call 0F81h
pop hl
ld (89ECh), hl
call 150Fh
ld de, 9D95h
call 5734h
jr 579Fh
57FDh: jp 9D95h
5800h: call 1837h
jr nz, 580Ah
pop af
and 01
out (20), a
580Ah: ld de, (89ECh)
ld hl, 0000h
ld (89ECh), hl
ld hl, 9D95h
call 1368h
jp 2799h