I wanted to create a functions that allowed oxygen to run files, but snice oxygen is a library the name of the programs may vary. Therefore I can't have a static string.

(Code Provide by Espilon5)
Code:
public _RunAsmPrgm

include 'include/ez80.inc'
include 'include/tiformat.inc'
include 'include/ti84pceg.inc'

;rework this
_RunAsmPrgm:
copy_to_saferam:
   ;fix the return stuff
   ld   sp,(__exitsp)
   pop   iy,af,hl
   ld   (hl),a
   call   $04F0
   ld hl, run_asm_prgm_addr
   ld de, ti.vRam
   ld bc, lengthof code
   ldir
   call ti.PushOP1
   ld hl, program_name
   call ti.Mov9ToOP1
   ;OP1 to be reloaded later
   ld hl,(ti.OP1)
   ld (tmp0),hl
   ld hl, (ti.OP1 + 3)
   ld (tmp1),hl
   ld hl, (ti.OP1 + 6)
   ld (tmp2),hl
   ;this part will also copy the program to be run and its type to OP1
   call ti.PopOP1
   jp run_asm_prgm
program_name:
   db ti.ProtProgObj, "VYSION", 0
 
run_asm_prgm_addr:
   ;org   ti.vRam
   virtual at ti.vRam
run_asm_prgm:
   extern __exitsp
   ld   de,(ti.asm_prgm_size)
   ld hl, 0
   ld   (ti.asm_prgm_size), hl
   ld   hl,ti.userMem         ; delete the current program from usermem
   call   ti.DelMem
   ;attempt to copy the reloader to the stack and set up a return address
   ;not sure how to do negative numbers but maybe this would work?
   ;should end up with -(reloader_end - reloader_start)
   ld hl,reloader_start - reloader_end
   add hl,sp
   ld sp,hl
   ld (.returnaddr),hl
   ex de,hl
   ld hl,reloader_start
   ld bc,reloader_end - reloader_start
   ldir
   ld hl,reloader_error - reloader_start
   add hl,sp
   call ti.PushErrorHandler
   ;run the asm program
   ;we stored the name and type into OP1 earlier
   res 0,(iy + ti.asm_Flag2)
   set   ti.graphDraw,(iy + ti.graphFlags)
   set   ti.appTextSave,(iy + ti.appFlags)
   set   ti.progExecuting,(iy + ti.newDispF)
   set   ti.appAutoScroll,(iy + ti.appFlags)
   set   ti.cmdExec,(iy + ti.cmdFlags)
   res   ti.onInterrupt,(iy + ti.onFlags)
   xor   a,a
   ld   (ti.kbdGetKy),a
   call   ti.EnableAPD
   ei
.getprgm:
   call   ti.ChkFindSym
   jr   c,.error_not_found
   call   ti.ChkInRam
   ex   de,hl
   jr   z,.in_ram
   ld   bc,9
   add   hl,bc
   ld   c,(hl)
   add   hl,bc
   inc   hl
.in_ram:
   call   ti.LoadDEInd_s
   bit 0,(iy + ti.asm_Flag2)
   jr  z,.getsize
   push    de
   pop bc
   inc hl
   inc hl
   ld  de,ti.userMem
   ldir
   call   ti.DisableAPD
   di
   ;ld hl,reloader_end - reloader_start
   ;add hl,sp
   ;ld sp,hl
   ld hl,0
.returnaddr := $-3
   push hl
   ;jq   ti.ParseInp
   jq ti.userMem
.getsize:
   push    de
   ex  de,hl
   call   ti.EnoughMem
   pop hl
   jr   c,.error_mem
   push    hl
   ld   de,ti.userMem
   call   ti.InsertMem
   pop   bc
   ld   (ti.asm_prgm_size),bc
   set 0,(iy + ti.asm_Flag2)
   jr  .getprgm
.error_mem:
.error_not_found:
.error_on:
   ;di
   ;ld hl,reloader_end - reloader_start
   ;add hl,sp
   ;ld sp,hl
   ret
 
reloader_start:
   call    ti.PopErrorHandler
reloader_error:
   ld iy,ti.flags
   ld hl,ti.userMem
   ld de,(ti.asm_prgm_size)
   call ti.DelMem
   di
   res   ti.progExecuting,(iy + ti.newDispF)
   res   ti.cmdExec,(iy + ti.cmdFlags)
   bit   ti.onInterrupt,(iy + ti.onFlags)
   jr  nz,.error_on
   ld hl, 0
tmp0 := $-3
   ld (ti.OP1),hl
   ld hl,0
tmp1 := $-3
   ld (ti.OP1 + 3),hl
   ld hl,0
tmp2 := $-3
   ld (ti.OP1 + 6), hl
   res 0,(iy + ti.asm_Flag2)
.getprgm:
   call   ti.ChkFindSym
   jr   c,.error_not_found
   call   ti.ChkInRam
   ex   de,hl
   jr   z,.in_ram
   ld   bc,9
   add   hl,bc
   ld   c,(hl)
   add   hl,bc
   inc   hl
.in_ram:
   call   ti.LoadDEInd_s
   bit 0,(iy + ti.asm_Flag2)
   jr  z,.getsize
   push    de
   pop bc
   inc hl
   inc hl
   ld  de,ti.userMem
   ldir
   call   ti.DisableAPD
   di
   ld hl,reloader_end - reloader_start
   add hl,sp
   ld sp,hl
   jp  ti.userMem
.getsize:
   push    de
   ex  de,hl
   call   ti.EnoughMem
   pop hl
   jr   c,.error_mem
   push    hl
   ld   de,ti.userMem
   call   ti.InsertMem
   pop   bc
   ld   (ti.asm_prgm_size),bc
   set 0,(iy + ti.asm_Flag2)
   jr  .getprgm
.error_mem:
.error_not_found:
.error_on:
   di
   ld hl,reloader_end - reloader_start
   add hl,sp
   ld sp,hl
   ret
reloader_end:
   load code: $-run_asm_prgm from run_asm_prgm
   end virtual
   db code
run_asm_prgm_end:


This is where the error is

Code:
 program_name:
 db ti.ProtProgObj, "VYSION", 0


"vysion" is what the program will return to after running, there is a slight error because"vysion" is a static string. How can I use C to create a varible to replace "vysion"?

Could I attempt append the return_program name string to OP1 or OP2?

Here is the function for runing a program with oxygen:

Code:
// Espilon5 WROTE THE NEXT 3 FUNCTIONS BELLOW (oxy_SetOP1, oxy_RunFile, oxy_EditFile)
void oxy_SetOP1(uint8_t type, const char name[], const char return_prgm[])
{
   char temp[19] = " ";
   
    temp[0] = type;
   
   strcat(temp, name);
   
   strcat(temp, return_prgm);
   
   memcpy(os_OP1, temp, strlen(temp)+1);
   
   return;
}

void oxy_RunFile(const char *name, uint8_t type, const char *return_prgm)
{
   ti_var_t slot;
   
   oxy_SaveAll();
   gfx_End();
   os_ClrHomeFull();
   
   if ((slot = ti_OpenVar(name,"r", type))){
      
      oxy_SetOP1(type, name, return_prgm);
      
      switch (type){
         case TI_PRGM_TYPE:
            InstallFixStopHook();
            RunPrgm();
            break;
         
         case TI_PPRGM_TYPE: 
            RunAsmPrgm();
            break;
      }
   }
   
   return;
}
argv[0] contains the name of the program executing.

That code is horrible, I wouldn't touch it with a ten foot pole.
MateoConLechuga wrote:
argv[0] contains the name of the program executing.

That code is horrible, I wouldn't touch it with a ten foot pole.

I absolutely agree with Mateo on this one.
Solution:
MateoC wrote:
Alvajoy123: extern char *program_name;
then in the asm: public _program_name \ _program_name:
Alvajoy123, If you ever publish this library, I will definitely use it! Running asm programs would be a very very useful thing!
Just a general tip: strcat is unsafe; you should use strncat instead unless you're absolutely sure you won't get a buffer overflow.
randomguy wrote:
Alvajoy123, If you ever publish this library, I will definitely use it! Running asm programs would be a very very useful thing!

I agree, So far running programs works but returning from a program seem to be a hassle.

Michael0x18 wrote:
Just a general tip: strcat is unsafe; you should use strncat instead unless you're absolutely sure you won't get a buffer overflow.

Ahh yes, I'll implement this thanks for the tip Razz



Quick Code update:

main.c

Code:
#define PRGM_NAME "DEMO"
#define RUN_PRGM "FLIPFROG"

void main(void)
{
   gfx_Begin();
   gfx_SetDraw(1);
   
   gfx_SetTextFGColor(0);
   gfx_PrintStringXY("TEST: RUNNING FLIPFROG", 1, 1);
   gfx_Blit(1);
   
   delay(2000);
   
   oxy_RunFile(RUN_PRGM, TI_PPRGM_TYPE, PRGM_NAME);
   
    return;
}


oxy_file.h snippet

Code:
void oxy_SetOP1(const uint8_t type, const char name[])
{
   char temp[10] = " ";
    temp[0] = type;
   strncat(temp, name, strlen(name));
   memcpy(os_OP1, temp, strlen(temp));
   return;
}

void oxy_RunFile(const char *name, uint8_t type, char *return_prgm)
{
   ti_var_t slot;
   program_name = NULL;
   
   oxy_SaveAll();
   gfx_End();
   os_ClrHomeFull();
   
   if ((slot = ti_OpenVar(name, "r", type))) {
      ti_Close(slot); // Close Slot for Reading
      
      oxy_SetOP1(type, name); // Begin by setting OP1
      strcpy(program_name, return_prgm); // Store the users return program
      
      switch (type){ // Check the type.
         case TI_PRGM_TYPE:
            InstallFixStopHook();
            RunPrgm();
            break;
         
         case TI_PPRGM_TYPE:
            RunAsmPrgm();
            break;
      }
      
   }
   
   return;
}


Asm code

Code:
public _RunAsmPrgm
public _program_name

include 'include/ez80.inc'
include 'include/tiformat.inc'
include 'include/ti84pceg.inc'

;rework this
_RunAsmPrgm:
copy_to_saferam:
   ;fix the return stuff
   ld   sp,(__exitsp)
   pop   iy,af,hl
   ld   (hl),a
   call   $04F0
   ld hl, run_asm_prgm_addr
   ld de, ti.vRam
   ld bc, lengthof code
   ldir
   call ti.PushOP1
   ld hl, _program_name
   call ti.Mov9ToOP1
   ;OP1 to be reloaded later
   ld hl,(ti.OP1)
   ld (tmp0),hl
   ld hl, (ti.OP1 + 3)
   ld (tmp1),hl
   ld hl, (ti.OP1 + 6)
   ld (tmp2),hl
   ;this part will also copy the program to be run and its type to OP1
   call ti.PopOP1
   jp run_asm_prgm
_program_name:

 
run_asm_prgm_addr:
   ;org   ti.vRam
   virtual at ti.vRam
run_asm_prgm:
   extern __exitsp
   ld   de,(ti.asm_prgm_size)
   ld hl, 0
   ld   (ti.asm_prgm_size), hl
   ld   hl,ti.userMem         ; delete the current program from usermem
   call   ti.DelMem
   ;attempt to copy the reloader to the stack and set up a return address
   ;not sure how to do negative numbers but maybe this would work?
   ;should end up with -(reloader_end - reloader_start)
   ld hl,reloader_start - reloader_end
   add hl,sp
   ld sp,hl
   ld (.returnaddr),hl
   ex de,hl
   ld hl,reloader_start
   ld bc,reloader_end - reloader_start
   ldir
   ld hl,reloader_error - reloader_start
   add hl,sp
   call ti.PushErrorHandler
   ;run the asm program
   ;we stored the name and type into OP1 earlier
   res 0,(iy + ti.asm_Flag2)
   set   ti.graphDraw,(iy + ti.graphFlags)
   set   ti.appTextSave,(iy + ti.appFlags)
   set   ti.progExecuting,(iy + ti.newDispF)
   set   ti.appAutoScroll,(iy + ti.appFlags)
   set   ti.cmdExec,(iy + ti.cmdFlags)
   res   ti.onInterrupt,(iy + ti.onFlags)
   xor   a,a
   ld   (ti.kbdGetKy),a
   call   ti.EnableAPD
   ei
.getprgm:
   call   ti.ChkFindSym
   jr   c,.error_not_found
   call   ti.ChkInRam
   ex   de,hl
   jr   z,.in_ram
   ld   bc,9
   add   hl,bc
   ld   c,(hl)
   add   hl,bc
   inc   hl
.in_ram:
   call   ti.LoadDEInd_s
   bit 0,(iy + ti.asm_Flag2)
   jr  z,.getsize
   push    de
   pop bc
   inc hl
   inc hl
   ld  de,ti.userMem
   ldir
   call   ti.DisableAPD
   di
   ;ld hl,reloader_end - reloader_start
   ;add hl,sp
   ;ld sp,hl
   ld hl,0
.returnaddr := $-3
   push hl
   ;jq   ti.ParseInp
   jq ti.userMem
.getsize:
   push    de
   ex  de,hl
   call   ti.EnoughMem
   pop hl
   jr   c,.error_mem
   push    hl
   ld   de,ti.userMem
   call   ti.InsertMem
   pop   bc
   ld   (ti.asm_prgm_size),bc
   set 0,(iy + ti.asm_Flag2)
   jr  .getprgm
.error_mem:
.error_not_found:
.error_on:
   ;di
   ;ld hl,reloader_end - reloader_start
   ;add hl,sp
   ;ld sp,hl
   ret
 
reloader_start:
   call    ti.PopErrorHandler
reloader_error:
   ld iy,ti.flags
   ld hl,ti.userMem
   ld de,(ti.asm_prgm_size)
   call ti.DelMem
   di
   res   ti.progExecuting,(iy + ti.newDispF)
   res   ti.cmdExec,(iy + ti.cmdFlags)
   bit   ti.onInterrupt,(iy + ti.onFlags)
   jr  nz,.error_on
   ld hl, 0
tmp0 := $-3
   ld (ti.OP1),hl
   ld hl,0
tmp1 := $-3
   ld (ti.OP1 + 3),hl
   ld hl,0
tmp2 := $-3
   ld (ti.OP1 + 6), hl
   res 0,(iy + ti.asm_Flag2)
.getprgm:
   call   ti.ChkFindSym
   jr   c,.error_not_found
   call   ti.ChkInRam
   ex   de,hl
   jr   z,.in_ram
   ld   bc,9
   add   hl,bc
   ld   c,(hl)
   add   hl,bc
   inc   hl
.in_ram:
   call   ti.LoadDEInd_s
   bit 0,(iy + ti.asm_Flag2)
   jr  z,.getsize
   push    de
   pop bc
   inc hl
   inc hl
   ld  de,ti.userMem
   ldir
   call   ti.DisableAPD
   di
   ld hl,reloader_end - reloader_start
   add hl,sp
   ld sp,hl
   jp  ti.userMem
.getsize:
   push    de
   ex  de,hl
   call   ti.EnoughMem
   pop hl
   jr   c,.error_mem
   push    hl
   ld   de,ti.userMem
   call   ti.InsertMem
   pop   bc
   ld   (ti.asm_prgm_size),bc
   set 0,(iy + ti.asm_Flag2)
   jr  .getprgm
.error_mem:
.error_not_found:
.error_on:
   di
   ld hl,reloader_end - reloader_start
   add hl,sp
   ld sp,hl
   ret
reloader_end:
   load code: $-run_asm_prgm from run_asm_prgm
   end virtual
   db code
run_asm_prgm_end:




There still seems to be an issue, I don't think I'm setting the "extern char *program_name" correctly.
I am not sure if this is your issue, but I don't think that initializing temp with spaces is what you need. If the program name is eight characters long, copying it into temp will add an extra space at the end.

Code:
void oxy_SetOP1(const uint8_t type, const char name[])
{
   char temp[10] = " ";       // Replace with char temp[10] = "\0";
    temp[0] = type;
   strncat(temp, name, strlen(name));
   memcpy(os_OP1, temp, strlen(temp));
   return;
}


On a side note, if the <name> argument is ever longer than nine characters, you will get a buffer overflow since strncat() is using the length of <name> without checking to see if it will fit in <temp>. A better approach would be to define a constant like OP1_NAME_LEN, set it equal to 8, and then compare the <name> length to it.

Hope this helps! Smile
Well, the buffer could be expanded slightly to avoid that. Then strncat would be perfectly safe.
  
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