I have been trying to modify the ICE program-launching source code to allow it to execute another program after the execution of the one it called is complete. The only problem is I am really bad overall at ASM. It launches the program correctly, but when the program it launched completes I get the following error
Quote:
NMI reset caused by writing to the stack limit at address 0xd19881. Hint: Probably a stack overflow (aka too much recursion).

I'm not sure what I'm doing wrong, because, again, I still don't completely understand ASM.

Here is the source code (and I apologize for my badly-formatted, probably redundant code):

Code:
public _RunPrgm

extern __exitsp

_RunPrgm:
   call   0021A3Ch      ; _DrawStatusBar
   ld   de, 0D09466h      ; plotSScreen
   ld   hl, StartRunProgram
   ld   bc, EndRunProgram - StartRunProgram
   ldir
   jp   0D09466h      ; plotSScreen
   
StartRunProgram:
; Copy the name to OP1
   pop   hl
   pop   hl         ; HL points to the program name
   ld   de, 0D005F9h      ; OP1 + 1
   push   de
   ld   bc, 8
   ldir
   pop   hl
   dec   hl
   ld   (hl), 5         ; ProgObj
   
; Cleanup C things
   ld   sp, (__exitsp + 1);
   pop   iy
   pop   af
   ex   (sp), hl
   ld   (hl), a
   call   00004F0h      ; usb_ResetTimers
   pop   hl
   
; Remove CESH from UserMem
   ld   hl, 0D1A881h      ; userMem
   ld   de, (0D0118Ch)      ; asm_prgm_size
   call   0020590h      ; _DelMem
   
; Copy the new program to UserMem and jump to it
   call   002050Ch      ; _ChkFindSym
   ex   de, hl
   call   0021D9Ch      ; _LoadDEInd_s
   inc   hl
   inc   hl
   push   hl
   push   de
   ex   de, hl
   call   002072Ch      ; _ErrNotEnoughMem
   pop   hl
   ld   (0D0118Ch), hl      ; asm_prgm_size
   ld   de, 0D1A881h      ; userMem
   push   de
   call   0020514h      ; _InsertMem
   pop   de
   pop   hl
   ld   bc, (0D0118Ch)      ; asm_prgm_size
   add   hl, bc
   ldir
    ld hl, RunShell
    ld bc, EndRunShell - RunShell
    ldir
   
; And finally run the program!
   jp   0D1A881h      ; userMem
EndRunProgram:

RunShell:
   call   0021A3Ch      ; _DrawStatusBar
   ld   de, 0D09466h      ; plotSScreen
   ld   hl, StartRunShell
   ld   bc, EndRunShell - StartRunShell
   ldir
   ld hl, de
    dec hl
    dec hl
    dec hl
    dec hl
    dec hl
   jp   0D09466h      ; plotSScreen
   
StartRunShell:
; Copy the name to OP1
   ld   de, 0D005F9h      ; OP1 + 1
   push   de
   ld   bc, 8
   ldir
   pop   hl
   dec   hl
   ld   (hl), 5         ; ProgObj
   
; Remove current program from UserMem
   ld   hl, 0D1A881h      ; userMem
   ld   de, (0D0118Ch)      ; asm_prgm_size
   call   0020590h      ; _DelMem
   
; Copy the shell to UserMem and jump to it
   call   002050Ch      ; _ChkFindSym
   ex   de, hl
   call   0021D9Ch      ; _LoadDEInd_s
   inc   hl
   inc   hl
   push   hl
   push   de
   ex   de, hl
   call   002072Ch      ; _ErrNotEnoughMem
   pop   hl
   ld   (0D0118Ch), hl      ; asm_prgm_size
   ld   de, 0D1A881h      ; userMem
   push   de
   call   0020514h      ; _InsertMem
   pop   de
   pop   hl
   ld   bc, (0D0118Ch)      ; asm_prgm_size
   add   hl, bc
   ldir
   
; And finally run the shell!
   jp   0D1A881h      ; userMem
    db "CESH",0,0,0,0
EndRunShell:
Did you write the code yourself, or copy and paste? If so, where is it from (I know some of it is from ICE)?
I copy-pasted this: https://github.com/PeterTillema/ICE/blob/master/src/asm/runprogram.asm, but then I did some heavy modification to try to get it to work the way I wanted, so basically, everything above 'ld hl, RunShell' is directly from ICE, and almost everything else is stuff I attempted (poorly) to hack together.
plz don't use ICE code k thx
But the actual ICE code works - It's my crappy code that doesn't
The primary goal of ICE is not to open and execute programs, so I didn't put a lot of effort into it. You're better off looking at how Cesium does it.
PT_ wrote:
The primary goal of ICE is not to open and execute programs, so I didn't put a lot of effort into it. You're better off looking at how Cesium does it.

I have nothing against how ICE executes programs and it works fine enough for what it does, but this is the fourth time someone has taken this exact snippet of code and asked "why it no work".

For reference, here's a link on how to do this properly. I've put the quote below, modified to include differences between running a ti-basic and assembly program:

Quote:
Delete the current C program from usermem
Push context and stub handler to the stack
Push error handlers pointing to the stub
If an assembly program, find the program and copy to usermem
If a basic program, check if unsquished. if so, squish and copy to usermem
Launch program -- if asm, jump to usermem, if basic, call ti.ParseInp
Return to stub
Lookup C program
Copy C program to usermem and jump to it


EDIT: if you scroll down and read the post, you'll see that I also included the code for running assembly programs, not just basic programs here
So I understand the general idea of what you are saying, but how would I perform the last 3 steps?
The idea I'm having the most trouble with is how to inject code at the end of the program I want to run so that it will execute upon completion. Is that even the correct way to do it, or is there some other way to return to my code?
You don't "inject code", you just push the return address to the stub on the stack.
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement