RXB Posted July 3, 2022 Share Posted July 3, 2022 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. 1 Quote Link to comment Share on other sites More sharing options...
RXB Posted July 3, 2022 Share Posted July 3, 2022 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! Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted July 4, 2022 Share Posted July 4, 2022 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? Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted July 4, 2022 Share Posted July 4, 2022 (edited) 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 July 4, 2022 by senior_falcon 2 Quote Link to comment Share on other sites More sharing options...
Reciprocating Bill Posted July 4, 2022 Share Posted July 4, 2022 (edited) 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. Edited July 4, 2022 by Reciprocating Bill Any thoughts on how to remove duplicated image? Quote Link to comment Share on other sites More sharing options...
Reciprocating Bill Posted July 4, 2022 Share Posted July 4, 2022 The Extended BASIC version requires over three minutes to just initialize the array using CALL LOAD...not a very promising approach... Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted July 4, 2022 Share Posted July 4, 2022 (edited) 13 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... Yes, CALLs tend to be slow. Edited July 4, 2022 by senior_falcon Quote Link to comment Share on other sites More sharing options...
atari1byte Posted July 4, 2022 Share Posted July 4, 2022 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. Hi everyone! in fact it is PRIME=I+I+3! copy paste from GW-basic emulator copied wrong sorry! Great! thanks for code! Quote Link to comment Share on other sites More sharing options...
atari1byte Posted July 4, 2022 Share Posted July 4, 2022 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! Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted July 4, 2022 Share Posted July 4, 2022 (edited) 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 July 4, 2022 by senior_falcon 2 Quote Link to comment Share on other sites More sharing options...
RXB Posted July 4, 2022 Share Posted July 4, 2022 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 ******************************************************************************** 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.