Jump to content

Photo

XB RUN a program with a variable

Extended BASIC XB

11 replies to this topic

#1 InsaneMultitasker OFFLINE  

InsaneMultitasker

    River Patroller

  • 2,428 posts

Posted Sat Nov 26, 2016 9:32 PM

I am looking for a routine that will run an Extended BASIC program based on a variable.  A few years back I cobbled something together but can not find the disk or image where it was saved.

 

During my 'hunt' I found two routines that come close.  The caveat is that I need the program lines left intact in case of an error, so that ON ERROR can recover an report back if the program load fails.  Variable and other space should also remain intact to ensure execution continues successfully.

 

This one doesn't work very well if at all.

100 CALL INIT
110 FOR Z=1 TO LEN(A$) :: CALL LOAD(-41+Z,ASC(SEG$(A$,Z,1)),0) :: NEXT Z :: CALL LOAD(-41,LEN(A$)) :: CALL LOAD(-44,4+LEN(A$))
120 RUN "DSKx.1234567890"

 

This routine works but it destroys the SUBEND in line 32767.  I extended the RUN filename reserved space to allow for hard drive paths.

32765 SUB EXEC(A$) :: CALL PEEK(-31952,AC,AD) :: CALL PEEK(AC*256+AD-65534,AC,AD) :: AF=AC*256+AD-65534 :: CALL LOAD(AF,LEN(A$))
32766 FOR AC=1 TO LEN(A$) :: CALL LOAD(AF+AC,ASC(SEG$(A$,AC,1))) :: NEXT AC :: CALL LOAD(AF+AC,0)
32767 RUN "DSK1.FILENAME011234567890123456789012345678901234567890" :: SUBEND

 

 



#2 RXB OFFLINE  

RXB

    River Patroller

  • 3,583 posts
  • Location:Vancouver, Washington, USA

Posted Sun Nov 27, 2016 3:40 AM

Nice but a ton of code.

 

RXB has a subroutine that makes RUN look like crap

 

CALL XBPGM("WDS.VOLUME.SUBVOLUME.PROGRAM",2)

 

The 2 at the end does a NEW and CALL FILES(2) before it loads the program.

 

So the result is like you did this:

NEW

CALL FILES(2)

RUN "WDS.VOLUME.SUBVOLUME.PROGRAM"


Edited by RXB, Sun Nov 27, 2016 3:42 AM.


#3 Lee Stewart OFFLINE  

Lee Stewart

    River Patroller

  • 3,967 posts
  • Location:Silver Run, Maryland

Posted Sun Nov 27, 2016 8:00 AM

...

This routine works but it destroys the SUBEND in line 32767.  I extended the RUN filename reserved space to allow for hard drive paths.

32765 SUB EXEC(A$) :: CALL PEEK(-31952,AC,AD) :: CALL PEEK(AC*256+AD-65534,AC,AD) :: AF=AC*256+AD-65534 :: CALL LOAD(AF,LEN(A$))
32766 FOR AC=1 TO LEN(A$) :: CALL LOAD(AF+AC,ASC(SEG$(A$,AC,1))) :: NEXT AC :: CALL LOAD(AF+AC,0)
32767 RUN "DSK1.FILENAME011234567890123456789012345678901234567890" :: SUBEND

 

Does SUBEND still get destroyed if it is on a line by itself?

 

...lee



#4 Sinphaltimus OFFLINE  

Sinphaltimus

    River Patroller

  • 2,521 posts
  • Distracted at the Keyboard
  • Location:Poconos, PA

Posted Sun Nov 27, 2016 9:12 AM

I am looking for a routine that will run an Extended BASIC program based on a variable.  A few years back I cobbled something together but can not find the disk or image where it was saved.

 

During my 'hunt' I found two routines that come close.  The caveat is that I need the program lines left intact in case of an error, so that ON ERROR can recover an report back if the program load fails.  Variable and other space should also remain intact to ensure execution continues successfully.

 

This one doesn't work very well if at all.

100 CALL INIT
110 FOR Z=1 TO LEN(A$) :: CALL LOAD(-41+Z,ASC(SEG$(A$,Z,1)),0) :: NEXT Z :: CALL LOAD(-41,LEN(A$)) :: CALL LOAD(-44,4+LEN(A$))
120 RUN "DSKx.1234567890"

This routine works but it destroys the SUBEND in line 32767.  I extended the RUN filename reserved space to allow for hard drive paths.

32765 SUB EXEC(A$) :: CALL PEEK(-31952,AC,AD) :: CALL PEEK(AC*256+AD-65534,AC,AD) :: AF=AC*256+AD-65534 :: CALL LOAD(AF,LEN(A$))
32766 FOR AC=1 TO LEN(A$) :: CALL LOAD(AF+AC,ASC(SEG$(A$,AC,1))) :: NEXT AC :: CALL LOAD(AF+AC,0)
32767 RUN "DSK1.FILENAME011234567890123456789012345678901234567890" :: SUBEND

Is that double 1 supposed to be there or a typo? or does it not matter? DSK1.FILENAME011...



#5 Lee Stewart OFFLINE  

Lee Stewart

    River Patroller

  • 3,967 posts
  • Location:Silver Run, Maryland

Posted Sun Nov 27, 2016 11:51 AM

Is that double 1 supposed to be there or a typo? or does it not matter? DSK1.FILENAME011...

 

The string format is just programmer's bookkeeping.  That entire string is a placeholder to allow a device name (“DSK1.”) followed by, at least, a filename of up to 10 characters (“FILENAME01”).  The “12345678901 ...” counts off 40 more spaces for hard-disk subdirectories a user might need between the device name and the filename.  The whole string could have been 55 spaces or random characters, but it would make it difficult for the programmer (Tim) to read.

 

...lee



#6 InsaneMultitasker OFFLINE  

InsaneMultitasker

    River Patroller

  • Topic Starter
  • 2,428 posts

Posted Sun Nov 27, 2016 1:52 PM

 

Does SUBEND still get destroyed if it is on a line by itself?

 

...lee

No, portions of the previous line and/or statements get over-written by the filename and the RUN statement disappears. 



#7 senior_falcon OFFLINE  

senior_falcon

    Stargunner

  • 1,489 posts
  • Location:Lansing, NY, USA

Posted Sun Nov 27, 2016 8:47 PM

This should do the trick:

 
32764 SUB EXEC(A$):: CALL PEEK(-31952,AC,AD):: CALL PEEK(AC*256+AD-65530,AC,AD):: AF=AC*256+AD-65534 :: CALL LOAD(AF,LEN(A$))
32765 FOR AC=1 TO LEN(A$):: CALL LOAD(AF+AC,ASC(SEG$(A$,AC,1))):: NEXT AC :: CALL LOAD(AF+AC,0)
32766 RUN "DSK1.FILENAME011234567890123456789012345678901234567890"
32767 SUBEND
 
The SUBEND needs to be on a separate line.  The CALL LOAD(AF+AC,0) tells XB that it is at the end of the line when it comes to the zero, so the SUBEND is lost.  32766 should only have RUN "DSK1.etc".  Also if you change the line numbers, make sure these are the very last line numbers in the program  


#8 InsaneMultitasker OFFLINE  

InsaneMultitasker

    River Patroller

  • Topic Starter
  • 2,428 posts

Posted Sun Nov 27, 2016 9:19 PM

 

This should do the trick:

 
32764 SUB EXEC(A$):: CALL PEEK(-31952,AC,AD):: CALL PEEK(AC*256+AD-65530,AC,AD):: AF=AC*256+AD-65534 :: CALL LOAD(AF,LEN(A$))
32765 FOR AC=1 TO LEN(A$):: CALL LOAD(AF+AC,ASC(SEG$(A$,AC,1))):: NEXT AC :: CALL LOAD(AF+AC,0)
32766 RUN "DSK1.FILENAME011234567890123456789012345678901234567890"
32767 SUBEND
 
The SUBEND needs to be on a separate line.  The CALL LOAD(AF+AC,0) tells XB that it is at the end of the line when it comes to the zero, so the SUBEND is lost.  32766 should only have RUN "DSK1.etc".  Also if you change the line numbers, make sure these are the very last line numbers in the program  

 

Yes, this seems to do the trick!   When I run this subroutine, the RUN line 32766 changes (as does its length) and the program lines are intact.  I see you changed the PEEK offset in line 32764.  Is that to account for the extra line 32767 prior to the RUN statement? 

 

Also just for completeness, if I wanted to do the same thing without a subprogram, would I change the offset to the original number like this: 

 

32765 CALL PEEK(-31952,AC,AD):: CALL PEEK(AC*256+AD-65534,AC,AD):: AF=AC*256+AD-65534 :: CALL LOAD(AF,LEN(A$))
32766 FOR AC=1 TO LEN(A$):: CALL LOAD(AF+AC,ASC(SEG$(A$,AC,1))):: NEXT AC :: CALL LOAD(AF+AC,0)
32767 RUN "DSK1.FILENAME01234567890123456789012345678901234567890"

 

(I'm having trouble with ON ERROR but I have run out of time for tonight.)



#9 senior_falcon OFFLINE  

senior_falcon

    Stargunner

  • 1,489 posts
  • Location:Lansing, NY, USA

Posted Sun Nov 27, 2016 9:44 PM

Yes, this seems to do the trick!   When I run this subroutine, the RUN line 32766 changes (as does its length) and the program lines are intact.  I see you changed the PEEK offset in line 32764.  Is that to account for the extra line 32767 prior to the RUN statement? 

 

Also just for completeness, if I wanted to do the same thing without a subprogram, would I change the offset to the original number like this: 

32765 CALL PEEK(-31952,AC,AD):: CALL PEEK(AC*256+AD-65534,AC,AD):: AF=AC*256+AD-65534 :: CALL LOAD(AF,LEN(A$))
32766 FOR AC=1 TO LEN(A$):: CALL LOAD(AF+AC,ASC(SEG$(A$,AC,1))):: NEXT AC :: CALL LOAD(AF+AC,0)
32767 RUN "DSK1.FILENAME01234567890123456789012345678901234567890"

(I'm having trouble with ON ERROR but I have run out of time for tonight.)

Yep, the different PEEK offset is because you want to doctor the second to last line, hence the 4  byte difference.  I think the code you show would work if you use ON ERROR line number which should send you back into the program so you can enter a different string.  



#10 InsaneMultitasker OFFLINE  

InsaneMultitasker

    River Patroller

  • Topic Starter
  • 2,428 posts

Posted Sun Jan 8, 2017 5:15 PM

Yep, the different PEEK offset is because you want to doctor the second to last line, hence the 4  byte difference.  I think the code you show would work if you use ON ERROR line number which should send you back into the program so you can enter a different string.  

I recently had a chance to try ON ERROR within the EXEC subprogram.

 

32760 SUB EXEC(A$)

32761 ON ERROR 32762::GOTO 32764

32762 SUBEXIT

32764 CALL PEEK(-31952,AC,AD):: CALL PEEK(AC*256+AD-65530,AC,AD):: AF=AC*256+AD-65534 :: CALL LOAD(AF,LEN(A$))
32765 FOR AC=1 TO LEN(A$):: CALL LOAD(AF+AC,ASC(SEG$(A$,AC,1))):: NEXT AC :: CALL LOAD(AF+AC,0)
32766 RUN "DSK1.FILENAME011234567890123456789012345678901234567890"
32767 SUBEND

 

If the target file does not exist, an error is generated and XB transfers control to the specified line number.  However, XB then halts with an error, "MUST BE IN SUBPROGRAM IN 32762"

 

  I suspect the RUN statement does some housecleaning prior to loading the target program.  Deleting 32764,32765 and replacing line 32766 with "OPEN #1:"AA"", generates an IO error that is correctly trapped by the ON ERROR handler.

 

I might need to use a hard-coded RUN statement as a fail safe or trust that if the path is correct that the program will load.  I do have an assembly-based routine that will check for a file's existence, perhaps I need to pair them together instead of relying upon ON ERROR here.  If only TI had allowed a string variable here as they do with the DELETE command.   :woozy:

 

 



#11 mizapf OFFLINE  

mizapf

    River Patroller

  • 3,610 posts
  • Location:Germany

Posted Sun Jan 8, 2017 5:30 PM

Well, yes, just think about RUN A$ with A$="DSK1.SOMEPRG", which was the first proof of 1337-ness back in those days, if you managed to get that running or at least something similar. :) People came up with lots of wild CALL LOAD hacks for their catalogers.


  • RXB likes this

#12 RXB OFFLINE  

RXB

    River Patroller

  • 3,583 posts
  • Location:Vancouver, Washington, USA

Posted Mon Jan 9, 2017 1:01 AM

Also something I pointed out in Micropendium (forgot what year) is that these "TRICKS" all ignore it bypasses normal XB start and Random Numbers do not work properly for some programs.

 

There is a way to do this that no one seems to have tried:

***********************************************************
*        START EXECUTION OF A PROGRAM OR STATEMENT
* DATA:
*      RAM(START) points into line number table at the
*      first line to execute
*      @PGMFLG contains >FF if executing a program or zero
*      if imperative statement
***********************************************************
EXEC   CZ   @PRGFLG           If program
       BS   GA0AE
       DST  V@START,@EXTRAM   Line to start execution at
       DINCT @EXTRAM          Pointer to text pointer
       CALL INTRND            Initialize random number
EXEC1  ST   X2,@XPT           Initialize screen display
       BR   GA0B2
GA0AE  DST  CRNBUF,@PGMPTR    Executing out of crunch buffe
GA0B2  DST  EXEC20,@RTNG      Address of return from ALC
       DST  NUDTB,@NUDTAB     NUD table address for ALC
       XML  EXECG             Execute XB
EXEC20 CASE @ERRCOD+1         Check type of return
       BR   EXECND            0 - NORMAL END
       BR   EXECBK            1 - BREAKPOINT
       BR   EXECTR            2 - TRACE
       BR   ERORZ             3 - ERROR
       BR   WARNGZ            4 - WARNING
       BR   ONERR             5 - ON ERROR
       BR   UDF               6 - FUNCTION
       BR   ONBRK             7 - ON BREAK
       BR   CONCAT            8 - CONCATENATE STRINGS "&"
       BR   ONWARN            9 - ON WARNING
       BR   GPLCAL            A - CALL STATEMENT
WARNGZ CH   >B0,@SUBSTK
       BS   ERRSO
* Stack overflow
*                    ALLOW ROOM ON STACK FOR WARNING CALLS
WRNN01 CALL WARNZZ        ONLY WARNING MSG FROM XB SUPPORT
       BYTE 2       *         NUMERIC OVERFLOW
       BR   CLRRTN            Clear ERRCOD and return
*                    NORMAL END OF EXECUTION
EXECND CZ   @PRGFLG           If imperative mode
       BR   ERRRDY
       CALL CHRTAB            Load the default character se
       B    TOPL15            Return to top-level
ERRRDY CALL ERRZZ             Display * READY *
       BYTE 0
* TRACE-MODE turned on - display line number
EXECTR CLR  @VARW             Clear upper address byte
       ST   @XPT,@VARW+1      Get current x-pointer
       DADD NLNADD-3,@VARW    Make a valid screen address
       DCH  NLNADD+22,@VARW   If might go off screen
       BR   GA102
       XML  SCROLL            SCROLL to next line
       DST  NLNADD,@VARW      Re-initialize screen address
GA102  ST   LESS+OFFSET,V*VARW Display open bracket "("
       DINC @VARW             Increment screen address
       CALL ASC               Convert line # into ASCII
       ST   GREAT+OFFSET,V*VARW Display close bracket ")"
       DSUB NLNADD-4,@VARW    Update the x-pointer
       ST   @VARW+1,@XPT
CLRRTN DCLR @ERRCOD           Clear the return vector
       XML  RTNB              Return to ALC
* BREAKPOINT OR BREAK-KEY RECIEVED
EXECBK CZ   @PRGFLG           If break or program
       BS   ERRBRK
       DST  @EXTRAM,@FAC8     @FAC8 : Source addr in ERAM
       DDECT @FAC8            Point to the line #
       CALL UBSUB1            Reset the breakpoint
       SCAN                   Get break key out of queue
EXEC6C DST  @PGMPTR,V@SPGMPT  Save text pointer
EXEC6D DST  @EXTRAM,V@SEXTRM  Save line number table pointe
       DST  @VSPTR,V@SAVEVP   Save value stack pointer
       DST  @BUFLEV,V@SBUFLV  Save crunch buffer level
       DST  @LSUBP,V@SLSUBP   Save last subprogram on stack
       ST   @FLAG,V@SFLAG     Save FLAG for continue
       AND  >63,V@SFLAG       Only warning and break bits
ERRBRK CALL ERRZZ             * BREAKPOINT
       BYTE 1
***********************************************************
*               NUD / STATEMENT BRANCH TABLE
***********************************************************
NUDTB  BR   RECX              'RECORD'              0
       BR   NBREAK            'BREAK'               0
       BR   NUNBRK            'UNBREAK'             0
       BR   NTRACE            'TRACE'               0
       BR   NUNTRC            'UNTRACE'             0
       BR   NREADX            'READ'                0
       BR   PRINTX            'PRINT'               0
       BR   SZRUNX            'RUN'                 0
       BR   LINPUX            Reserved for LINPUT   1
       BR   RESTOX            'RESTORE'             1
       BR   NRNDMZ            'RANDOMIZE'           1
       BR   INPUTX            'INPUT'               1
       BR   OPENX             'OPEN'                1
       BR   CLOSEX            'CLOSE'               1
       BR   NPI               'PI'                  1
       BR   NMAX              'MAX'                 1
       BR   NMIN              'MIN'                 2
       BR   RPTZ01            'RPT$'                2
       BR   ACCEPX            'ACCEPT'              2
       BR   EOFX              'EOF'                 2
       BR   ASC01             'ASC'                 2
       BR   POS01             'POS'                 2
       BR   VAL01             'VAL'                 2
       BR   STRZ01            'STR$'                2
       BR   SEGZ01            'SEG$'                3
       BR   DELETX            'DELETE'              3
       BR   DISPLX            'DISPLAY'             3
       BR   LEN01             'LEN'                 3
       BR   CHRZ01            'CHR$'                3
*RXB PATCH CODE FOR BASIC RND REPLACEMENT ***********
       BR   NRND              'RND'                 3        
* The following are long branches to another GROM
EOFX   B    EOF
SZRUNX B    SZRUN
RECX   B    REC
NREADX B    NREAD
PRINTX B    PRINT
RESTOX B    RESTOR
INPUTX B    INPUT
OPENX  B    OPEN
CLOSEX B    CLOSE
ACCEPX B    ACCEPT
DISPLX B    DISPL1
DELETX B    DELET
LINPUX B    LINPUT
***********************************************************
* FLAGS USED IN EXECUTION MODE:    this needs to be checked
*  @FLAG   BIT   RESET               SET
*           0
*           1    Warning PRINT       PRINT off
*           2    Warning NEXT        STOP
*           3    Not in UDF          Executing a UDF
*           4    TRACE mode          Normal mode
*           5
*           6    BREAK allowed       BREAK not allowed
*           7    No LST/EDT protect  LIST/EDIT protected
***********************************************************
* ON WARNING {NEXT | STOP | PRINT}
* ON WARNING NEXT  - Causes warning messages to be ignored
*                    and execution to continue as if a
*                    warning never occurred
* ON WARNING STOP  - Causes a warning to be treated as an
*                    error - i.e. the message is displayed
*                    and execution is halted
* ON WARNING PRINT - Causes the default warning handling to
*                    be in effect, i.e. any warning
*                    messages are printed and execution
*                    continues
***********************************************************
ONWARN XML  PGMCHR            GET OPTION
       CEQ  PRINTZ,@CHAT      If print
       BR   GA1B7
       AND  >F9,@FLAG         Turn on print and contiue
       B    ONWRN5
GA1B7  CEQ  STOPZ,@CHAT
       BR   GA1C4
       AND  >FD,@FLAG         Turn on print
       OR   >04,@FLAG         Turn on stop
       BR   ONWRN5
GA1C4  CEQ  NEXTZ,@CHAT       * SYNTAX ERROR
       BR   ERRSYN
       OR   >02,@FLAG         Turn off print
       AND  >FB,@FLAG         Turn off stop
ONWRN5 XML  PGMCHR            Check for EOS
ONWRN7 CALL CHKEND            Error if not EOS
       BR   ERRSYN            If not EOS
       DCLR @ERRCOD
       XML  CONT              Continue
***********************************************************
* ON ERROR {line number | STOP}
* ON ERROR line number - causes the error routine to build
*                        an error stack entry and pass
*                        control to the line specified in
*                        the most-recently executed
*                        on-error-statement
* ON ERROR STOP - causes the default error handling
*                 conditions to be in effect. i.e. any
*                 errors that occur cause execution to halt
*                 an a message to be displayed
***********************************************************
ONERR  XML  PGMCHR            Get option
       CEQ  LNZ,@CHAT         If line # then find the line
       BR   GA20E
       XML  PGMCHR            Get upper byte
       ST   @CHAT,@FAC
       XML  PGMCHR            Get lower byte
       ST   @CHAT,@FAC1
       DST  @ENLN,@FAC2
       DSUB 3,@FAC2           Pointing to 1st line #
* Consider both ERAM and RAM cases to get line # from the
* line number table. Also reset the break bit.
ONERR2 CALL GRSUB3            Get 2 bytes from either RAM/E
       BYTE FAC2            * FAC2 has the address
       DCEQ @EEE1,@FAC        If found
       BS   ONERR4
       DCH  @STLN,@FAC2       Not found
       BR   ERRLNF
       DSUB 4,@FAC2           Goto next line
       BR   ONERR2
ONERR4 DINCT @FAC2
       DST  @FAC2,V@ERRLN
       BR   GA216
GA20E  CEQ  STOPZ,@CHAT       * SYNTAX ERROR
       BR   ERRSYN
       DCLR V@ERRLN           Back to default error handlin
GA216  BR   ONWRN5            Finish up same as ON WARNING
***********************************************************
* ON BREAK {NEXT | STOP}
* ON BREAK NEXT - Causes any breakpoints which have been
*                 set on statements to be ignored when the
*                 statement is encountered and also masks
*                 the shift-C key so that it is ignored
* ON BREAK STOP - Causes the default break handling to be
*                 in force., i.e. execution is halted and
*                 the BREAKPOINT message is displayed on
*                 the screen
***********************************************************
ONBRK  XML  PGMCHR            Get next char to find option
       CEQ  STOPZ,@CHAT       If stop option specified
       BR   GA225
       AND  >BF,@FLAG         break allowed
       B    GA22D             Don't change this to BR GA22D
GA225  CEQ  NEXTZ,@CHAT       If next option number
       BR   ERRSYN            specified then syntax error
       OR   >40,@FLAG         If next option specified then
*                              break NOT allowed
GA22D  BR   ONWRN5            Finish up same as ON WARNING
***********************************************************
* GPLCAL - If a call is made to a subprogram that does not
*  not exist either in the BASIC program itself or in the
*  internal GPL subprogram list then one final attempt is
*  made to find the subprogram at execution time by
*  searching for the subprogram in the console or a
*  peripheral. If not found there, then a
*  *SUBPROGRAM NOT FOUND error occurs
*
*  Input: the subprogram name is in the FAC and the length
*         of the name is in FAC15
***********************************************************
GPLCAL CZ   @RAMFLG           Can't try if CPU program
       BR   ERRSNF
       DSRL 8,@FAC15          Make name length a double
       DSUB @FAC15,@PGMPTR    Point back at name
       DDEC @PGMPTR           Point at name length
       DST  @PGMPTR,@FAC12    Set pointer to name
       CALL LINK              Issue 'Call Program Link'
       BYTE 10              * Search subprogram lists
       BR   ONWRN7            If all ok, check-end and rtn
       BR   ERRSNF            If not found, error
***********************************************************

The above code is the GPL XB code for EXEC for run a XB program line out of CRUNCH BUFFER (or line execute buffer like when you type in a line) but if you set the PRGFLG (>8344) to >FF 

which means PROGRAM mode (>00 is EDIT mode) this routine sets up everything properly and runs the program.







Also tagged with one or more of these keywords: Extended BASIC, XB

0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users