Jump to content
IGNORED

Need help understanding how to utilize SAMS memory in RXB


majestyx

Recommended Posts

2 hours ago, atari1byte said:

I want to convert this program for TI 
with 8001elements
i will leave you the GW-Basic program:

 


1 VOLUME = 8000 
2 DIM FLAGS(8001) 
3 PRINT "Only 1 iteration" 
5 COUNT = 0 
6 FOR I = 0 TO VOLUME
7 FLAGS(I) = 1 
8 NEXT I 
9 FOR I = 0 TO VOLUME 
10 IF FLAGS(I) = 0 THEN 18 
11 PRIME = 1+1 + 3 
12 K = I + PRIME 
13 IF K > VOLUME THEN 17 
14 FLAGS(K) = 0 
15 K = K + PRIME 
16 GOTO 13 
17 COUNT = COUNT + 1 
18 NEXT I 
19 PRINT COUNT," PRIMES"

Using TI99/4A if you change 8001 to 3001 you only have 115 bytes of program space free in the upper 24K of XB after you run the program.

TI Basic has even less memory then XB by less than 1/4 as much memory so not even remotely possible with TI Basic.

 

If you used the SAMS you could use the 1Meg minus the 32K to do way past 8001.

If you use RXB command CALL MOVES("$R",255,FLAG$,ADDRESS) this would move a 255 byte string that has your number to a RAM address in SAMS.

So to convert FLAGS(I) you would use FLAG$ instead of a Dimension value as in FLAG$=STR$(I)

So you would have to write a routine to set SAMS pages, and swap them when full and keep all the values you find but up to Primes 255 bytes in digits.

Of course this would slow program but it would allow you up to 1Meg of memory use way past 8001 dims.

 

  • Like 1
Link to comment
Share on other sites

On 8/7/2019 at 10:42 AM, Asmusr said:

I believe you would have to use CALL LOAD and CALL PEEK to store and fetch variables in SAMS from RXB.  Quite cumbersome and slow - especially for floating point numbers.

 

I once thought about how to improve this, and suggested an XB extension to provide rudimentary array support:

https://atariage.com/forums/topic/261030-dungeons-of-asgard-game-under-development/?do=findComment&comment=4218621

Actually there is also a command CALL MOVES that moves any type of memory including strings to any type of memory so little more useful then CALL LOAD or CALL PEEK

CALL MOVES("$R",255,X$,ADDRESS) would move 255 bytes from string X$ to a RAM ADDRESS

This makes CALL LOAD and CALL PEEK look pretty clunky!

Link to comment
Share on other sites

5 hours ago, RXB said:

Actually there is also a command CALL MOVES that moves any type of memory including strings to any type of memory so little more useful then CALL LOAD or CALL PEEK

CALL MOVES("$R",255,X$,ADDRESS) would move 255 bytes from string X$ to a RAM ADDRESS

This makes CALL LOAD and CALL PEEK look pretty clunky!

How can this be used to solve Atari1byte's problem?

 

Link to comment
Share on other sites

Since elements in the FLAGS( ) array can only be 1 or 0, it is practical to set up your own array in an unused part of ram, using only 1 byte per element and accessed with CALL LOAD and CALL PEEK.

The low memory part of the 32K starts at 8192 and has 8192 bytes, which is just over what you need. You must start at 8200 to avoid overwriting the first 8 bytes which are used by XB. I forgot to include CALL INIT in line 1. I believe this works exactly the same as your program. I will admit to not understanding the program. With VOLUME=100, both programs give 5 and there are more than 5 primes from 0 to 100.

1 VOLUME=8000
2 FLAGS=8200 !DIM FLAGS(8000)
3 PRINT "Only 1 iteration"
5 COUNT=0
6 FOR I=0 TO VOLUME
7 CALL LOAD(FLAGS+I,1)!FLAGS(I)=1
8 NEXT I
9 FOR I=0 TO VOLUME
10 CALL PEEK(FLAGS+I,X):: IF X=0 THEN 18 !IF FLAGS(I)=0 THEN 18
11 PRIME=1+1+3
12 K=I+PRIME
13 IF K>VOLUME THEN 17
14 CALL LOAD(FLAGS+K,0)!FLAGS(K)=0
15 K=K+PRIME
16 GOTO 13
17 COUNT=COUNT+1
18 NEXT I
19 PRINT COUNT," PRIMES"

 

Edited by senior_falcon
  • Like 2
Link to comment
Share on other sites

Line 11 should be "PRIME=I+I+3"  (not "PRIME=1+1+3").

 

It should flag 45 primes (between 0 and 200 - the array only has to represent odd numbers). 

 

This does the same thing in CBASIC. Requires a SuperCart in this version to store the 8192 byte "array." Executes in 132 seconds on 16-bit console.

 

IMG_2077.thumb.jpeg.e51e0070dcdf85dd87fb2e01e5c89a97.jpeg

 

 

 

 

 

 

IMG_2077.jpeg

Edited by Reciprocating Bill
Any thoughts on how to remove duplicated image?
Link to comment
Share on other sites

1 hour ago, Reciprocating Bill said:

La riga 11 dovrebbe essere "PRIME=I+I+3" (non "PRIME=1+1+3").

 

Dovrebbe contrassegnare 45 numeri primi (tra 0 e 200 - l'array deve rappresentare solo numeri dispari).

 

Questo fa la stessa cosa in CBASIC. Richiede un SuperCart in questa versione per memorizzare l'"array" di 8192 byte. Viene eseguito in 132 secondi su console a 16 bit.

 

IMG_2077.thumb.jpeg.e51e0070dcdf85dd87fb2e01e5c89a97.jpeg

 

 

 

 

 

 

IMG_2077.jpeg

Hi everyone!

in fact it is PRIME=I+I+3!
copy paste from GW-basic emulator copied wrong sorry!

Great! thanks for code!

Link to comment
Share on other sites

11 hours ago, senior_falcon said:

Since elements in the FLAGS( ) array can only be 1 or 0, it is practical to set up your own array in an unused part of ram, using only 1 byte per element and accessed with CALL LOAD and CALL PEEK.

The low memory part of the 32K starts at 8192 and has 8192 bytes, which is just over what you need. You must start at 8200 to avoid overwriting the first 8 bytes which are used by XB. I forgot to include CALL INIT in line 1. I believe this works exactly the same as your program. I will admit to not understanding the program. With VOLUME=100, both programs give 5 and there are more than 5 primes from 0 to 100.


1 VOLUME=8000
2 FLAGS=8200 !DIM FLAGS(8000)
3 PRINT "Only 1 iteration"
5 COUNT=0
6 FOR I=0 TO VOLUME
7 CALL LOAD(FLAGS+I,1)!FLAGS(I)=1
8 NEXT I
9 FOR I=0 TO VOLUME
10 CALL PEEK(FLAGS+I,X):: IF X=0 THEN 18 !IF FLAGS(I)=0 THEN 18
11 PRIME=1+1+3
12 K=I+PRIME
13 IF K>VOLUME THEN 17
14 CALL LOAD(FLAGS+K,0)!FLAGS(K)=0
15 K=K+PRIME
16 GOTO 13
17 COUNT=COUNT+1
18 NEXT I
19 PRINT COUNT," PRIMES"

 

Great! Thanks a lot!

Link to comment
Share on other sites

44 minutes ago, Reciprocating Bill said:

The Extended BASIC version requires over three minutes to just initialize the array using CALL LOAD...not a very promising approach...

For an array of 1000 elements, it takes about 11 seconds to initialize.

To CALL LOAD 1000 times takes about 26 seconds

You can initialize faster this way:

10 FOR I=0 TO 1000 STEP 10::CALL LOAD(8200+I,1,1,1,1,1,1,1,1,1,1)::NEXT I

This takes about 8 seconds, so it is a little faster than using an array. Of course that is just to initialize; the actual program has to CALL PEEK and CALL LOAD a byte at a time.

 

The bottom line is that, to my knowledge, there is no easy way to fool the TI into using additional memory such as SAMS for XB programs that is as simple as just having more memory to start with.

Edited by senior_falcon
  • Thanks 2
Link to comment
Share on other sites

37 minutes ago, senior_falcon said:

For an array of 1000 elements, it takes about 11 seconds to initialize.

To CALL LOAD 1000 times takes about 26 seconds

You can initialize faster this way:

10 FOR I=0 TO 1000 STEP 10::CALL LOAD(8200+I,1,1,1,1,1,1,1,1,1,1)::NEXT I

This takes about 8 seconds, so it is a little faster than using an array. Of course that is just to initialize; the actual program has to CALL PEEK and CALL LOAD a byte at a time.

 

The bottom line is that, to my knowledge, there is no easy way to fool the TI into using additional memory such as SAMS for XB programs that is as simple as just having more memory to start with.

This would require you use SAMS and set up you own array map.

Basic and XB both use 8 bytes for Floating Point numbers thus first make a map of Floating Point 8 byte numbers indexed by skipping 8 each time in a loop into SAMS 

say at >2000 hex up to >3FFF hex or depending on size of XB program from >A000 to >DFFF and your XB program is under 8K.

Now the new problem is also adding in 4K page flipping of SAMS as you are going to need to keep doing this if using SAMS and RXB has that easy to cover.

As there is no easy way to put 8 byte Floating Point numbers into RAM using CALL LOAD would be tiresome and slow, I thought using RXB CALL MOVES would work better.

But then you need the address of that numeric variable used or turn it into a string using STR$(value) and save it that way into SAMS RAM.

Never side this was a piece of cake to do.

 

Guess I should include in RXB next version a command that tells you address of a numeric variable is in memory or a address of a string variable.

CALL ASSIGN(numeric-variable,return-address) or CALL ASSIGN(string-variable,return-address)

So this command will tell you where in memory a variable is located so you can manipulate it by changing it or coping it to SAMS or modify it.

Would be the perfect tool for setting up own array of any size in SAMS.

 

There is already a routine in XB ROMs to do this:

*************************************************************
* ASSGNV, callable from GPL or 9900 code, to assign a value *
* to a symbol (strings and numerics) . If numeric, the      *
* 8 byte descriptor is in the FAC. The descriptor block     *
* (8 bytes) for the destination variable is on the stack.   *
* There are two types of descriptor entries which are       *
* created by SMB in preparation for ASSGNV, one for         *
* numerics and one for strings.                             *
*                     NUMERIC                               *
* +-------------------------------------------------------+ *
* |S.T. ptr | 00 |       |Value ptr |                     | *
* +-------------------------------------------------------+ *
*                     STRING
* +-------------------------------------------------------+ *
* |Value ptr| 65 |       |String ptr|String length        | *
* +-------------------------------------------------------+ *
*                                                           *
* CRITICAL NOTE: Becuase of the BL @POPSTK below, if a      *
* string entry is popped and a garbage collection has taken *
* place while the entry was pushed on the stack, and the    *
* entry was a permanent string the pointer in FAC4 and FAC5 *
* will be messed up. A BL @VPOP would have taken care of    *
* the problem but would have taken a lot of extra code.     *
* Therefore, at ASSG50-ASSG54 it is assumed that the        *
* previous value assigned to the destination variable has   *
* been moved and the pointer must be reset by going back to *
* the symbol table and getting the correct value pointer.   *
*************************************************************
ASSG   MOV  R11,R10           Save the retun address
       BL   @ARGTST           Check arg and variable type
       STST R12               Save status of type
       BL   @POPSTK           Pop destination descriptor
*                              into ARG
       SLA  R12,3             Variable type numeric?
       JNC  ASSG70            Yes, handle it as such
* Assign a string to a string variable
       MOV  @ARG4,R1          Get destination pointer
*                             Dest have non-null  value?
       JEQ  ASSG54            No, null->never assigned
* Previously assigned - Must first free the old value
       BL   @GET              Correct for POPSTK above
       DATA ARG               Pointer is in ARG
*
       MOV  R1,@ARG4          Correct ARG+4,5 too
*-----------------------------------------------------------*
* Fix "Assigning a string to itself when memory is full can *
*      destroy the string" bug, 5/22/81                     *
* Add the following 2 lines and the label ASSG80            *
       C    R1,@FAC4          Do not do anything in assign- *
*                              ing a string to itself case  *
       JEQ  ASSG80            Detect A$=A$ case, exit       *
*-----------------------------------------------------------*
       CLR  R6                Clear for zeroing backpointer
       BL   @STVDP3           Free the string
ASSG54 MOV  @FAC6,R4          Is source string a null?
       JEQ  ASSG57            Yes, handle specially
       MOV  @FAC,R3           Get address of source pointer
       CI   R3,>001C          Got a temporay string?
       JNE  ASSG56            No, more complicated
       MOV  @FAC4,R4          Pick up direct ptr to string
* Common string code to set forward and back pointers
ASSG55 MOV  @ARG,R6           Ptr to symbol table pointer
       MOV  R4,R1             Pointer to source string
       BL   @STVDP3           Set the backpointer
ASSG57 MOV  @ARG,R1           Address of symbol table ptr
       MOV  R4,R6             Pointer to string
       BL   @STVDP            Set the forward pointer
ASSG80 B    *R10              Done, return
* Symbol-to-symbol assigments of strings
* Must create copy of string
ASSG56 MOV  @FAC6,@BYTE       Fetch length for GETSTR
* NOTE: FAC through FAC+7 cannot be destroyed
*       address^of string length^of string
       BL   @VPUSH            So save it on the stack
       MOV  R10,@FAC          Save return link in FAC since
*                              GETSTR does not destroy FAC
       BL   @GETSTR           Call GPL to do the GETSTR
       MOV  @FAC,R10          Restore return link
       BL   @VPOP             Pop the source info back
* Set up to copy the source string into destination
       MOV  @FAC4,R3          R3 is now copy-from
       MOV  @SREF,R5          R5 is now copy-to
       MOV  R5,R4             Save for pointer setting
* Registers to be used in the copy
* R1 - Used for a buffer
* R3 - Copy-from address
* R2 - # of bytes to be moved
* R5 - copy-to address
       MOV  @FAC6,R2          Fetch the length of the string
       ORI  R5,WRVDP          Enable the VDP write
ASSG59 BL   @GETV1            Get the character
       MOVB @R5LB,*R15        Load out destination address
       INC  R3                Increment the copy-from
       MOVB R5,*R15           1st byte of address to
       INC  R5                Increment for next character
       MOVB R1,@XVDPWD        Put the character out
       DEC  R2                Decrement count, finished?
       JGT  ASSG59            No, loop for more
       JMP  ASSG55            Yes, now set pointers
* Code to copy a numeric value into the symbol table
ASSG70 LI   R2,8              Need to assign 8 bytes
       MOV  @ARG4,R5          Destination pointer(R5)
*                              from buffer(R4), (R2)bytes
       MOV  @RAMTOP,R3        Does ERAM exist?
       JNE  ASSG77            Yes, write to ERAM
*                             No, write to VDP
       MOVB @R5LB,*R15        Load out 2nd byte of address
       ORI  R5,WRVDP          Enable the write to the VDP
       MOVB R5,*R15           Load out 1st byte of address
       LI   R4,FAC            Source is FAC
ASSG75 MOVB *R4+,@XVDPWD      Move a byte
       DEC  R2                Decrement the counter, done?
       JGT  ASSG75            No, loop for more
       B    *R10              Yes, return to the caller
ASSG77 LI   R4,FAC            Source is in FAC
ASSG79 MOVB *R4+,*R5+         Move a byte
       DEC  R2                Decrement the counter, done?
       JGT  ASSG79            No, loop for more
       B    *R10              Yes, return to caller
* Check for required token
SYNCHK MOVB *R13,R0           Read required token
*
       CB   R0,@CHAT          Have the required token?
       JEQ  PGMCH             Yes, read next character
       BL   @SETREG           Error return requires R8/R9 set
       B    @ERRSYN           * SYNTAX ERROR
*      PGMCH - GPL entry point for PGMCHR to set up registers
PGMCH  MOV  R11,R12           Save return address
       BL   @PGMCHR           Get the next character
       MOVB R8,@CHAT          Put it in for GPL
       B    *R12              Return to GPL
       RT                     And return to the caller
PUTV   MOV  *R11+,R4
       MOV  *R4,R4
PUTV1  MOVB @R4LB,*R15
       ORI  R4,WRVDP
       MOVB R4,*R15
       NOP
       MOVB R1,@XVDPWD
       RT
* MOVFAC - copies 8 bytes from VDP(@FAC4) or ERAM(@FAC4)
*          to FAC
MOVFAC MOV @FAC4,R1           Get pointer to source
       LI  R2,8               8 byte values
       LI  R3,FAC             Destination is FAC
       MOV @RAMTOP,R0         Does ERAM exist?
       JNE MOVFA2             Yes, from ERAM
*                             No, from VDP RAM
       SWPB R1
       MOVB R1,*R15           Load 2nd byte of address
       SWPB R1
       MOVB R1,*R15           Load 1st byte of address
       LI   R5,XVDPRD
MOVF1  MOVB *R5,*R3+          Move a byte
       DEC  R2                Decrement counter, done?
       JGT  MOVF1             No, loop for more
       RT                     Yes, return to caller
MOVFA2 MOVB *R1+,*R3+
       DEC  R2
       JNE  MOVFA2
       RT
       RT                     And return to caller
********************************************************************************

 

  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...