+DZ-Jay Posted April 29, 2016 Share Posted April 29, 2016 Correct! When the IntyBASIC string length/terminator is defined the len command could be made to work with inline strings then. They are duplicated in the source code, but only one is present in the binary. They are only duplicated because IntyBASIC does not support string constants... but just you wait! Quote Link to comment Share on other sites More sharing options...
freewheel Posted April 30, 2016 Share Posted April 30, 2016 They are duplicated in the source code, but only one is present in the binary. Oh really? Neat Does the compiler do an in-line analysis for duplicates and deal with them via addressing tricks? Quote Link to comment Share on other sites More sharing options...
carlsson Posted April 30, 2016 Share Posted April 30, 2016 In this particular case, I understand that LEN is evaluated during compile time and the actual string length is passed on to the assembler. If you use the same string twice in e.g. PRINT statements, I'm not sure that it replaces either instance with a reference. Quote Link to comment Share on other sites More sharing options...
freewheel Posted April 30, 2016 Share Posted April 30, 2016 Oh, that makes sense. Cuz it's a macro etc. Like they keep explaining Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted May 1, 2016 Share Posted May 1, 2016 (edited) In this particular case, I understand that LEN is evaluated during compile time and the actual string length is passed on to the assembler. If you use the same string twice in e.g. PRINT statements, I'm not sure that it replaces either instance with a reference. I do that in P-Machinery, by building string lists and generating a single string table at the end of pre-processing the assembly source. Perhaps IntyBASIC could do something similar? I'm sure it would be much easier to do in C than in as1600 macros! Edited May 1, 2016 by DZ-Jay Quote Link to comment Share on other sites More sharing options...
First Spear Posted December 9, 2016 Share Posted December 9, 2016 (edited) I am using the 1.2.8 IntyBASIC bits. I thought that this simple program would display "A" or "AWESOME" but it displays a "$" instead. What did I miss? INCLUDE "constants.bas" Mode 0,STACK_BROWN,STACK_BROWN,STACK_BROWN,STACK_BROWN Wait Print at 20 , "X" #myda = label1(0) Print at 22 , #myda LoopMain: Goto LoopMain label1: DATA "AWESOME" [snip]encoding your strings as DATA statements. Put a label on them, and then you can address into the DATA statement however you like. For example: label1: DATA "THIS IS MY STRING" label2: DATA "AND THIS IS ANOTHER" Then you can address label1 or label 2 like an array: label1(5) points to the i in IS, for example. label2(12) points to the a in ANOTHER. Etc. If you REALLY want to get clever, you can encode 2 letters in a single 16-bit word, and pick them apart 2 letters at a time that way. This saves ROM space (not usually a concern for most games) but can get complicated if you need to address an odd-numbered character. Thanks. Edited December 9, 2016 by First Spear Quote Link to comment Share on other sites More sharing options...
catsfolly Posted December 9, 2016 Share Posted December 9, 2016 (edited) I am using the 1.2.8 IntyBASIC bits. I thought that this simple program would display "A" or "AWESOME" but it displays a "$" instead. What did I miss? INCLUDE "constants.bas" Mode 0,STACK_BROWN,STACK_BROWN,STACK_BROWN,STACK_BROWN Wait Print at 20 , "X" #myda = label1(0) Print at 22 , #myda LoopMain: Goto LoopMain label1: DATA "AWESOME" Thanks. Apparently, when you "print" a numerical value, the print command just pokes that number into backtab. So, you have to change line 5 to: 5. #myda = (label1(0) * + CS_WHITE To get it to work. In color stack mode, backtab looks like this: ;;--------------------------------------------------------------------------;; ;; Useful bits for Color Stack Mode ;; ;; ;; ;; Display format word layout in Color Stack Mode: ;; ;; 13 12 11 10 9 8 7 6 5 4 3 2 1 0 ;; ;; +----+-----+----+----+----+----+----+----+----+----+----+----+----+----+ ;; ;; |Adv.|FG |GRAM| GRAM/GROM Card # | FG Color | ;; ;; |col |Bit3/|GROM| (0-255 for GROM, 0-63 for GRAM) | Bits 0-2 | ;; ;; |stck|----------| | | ;; ;; | |col. sqr. | | | ;; ;; | |mode slct.| | | ;; ;; +----+-----+----+----+----+----+----+----+----+----+----+----+----+----+ ;; ;; ;; The numbers in the string are ascii codes - 32. They need to be shifted by 8 and have a color added to show up properly on the screen. Does this make sense? Catsfolly P.S. This prints "awesome". INCLUDE "constants.bas" Mode 0,STACK_BROWN,STACK_BROWN,STACK_BROWN,STACK_BROWN Wait Print at 20 , "X " for i = 0 to 6 #myda = (label1(i) * + CS_WHITE Print #myda next i LoopMain: Goto LoopMain label1: DATA "AWESOME" Edited December 9, 2016 by catsfolly 2 Quote Link to comment Share on other sites More sharing options...
First Spear Posted December 9, 2016 Share Posted December 9, 2016 Great. What about mixing with the ScreenPos function from the new constants.bas ? INCLUDE "constants.bas" Mode 0,STACK_BROWN,STACK_BROWN,STACK_BROWN,STACK_BROWN Wait #hpos = 20 while ( #hpos < 40 ) for i = 0 to 6 #myda = (label1(i) * + CS_WHITE Print at screenpos(#hpos,4) #myda #hpos = #hpos + 1 next i wend LoopMain: Goto LoopMain label1: DATA "Awesome","sauce" (does not work, trying to understand the relationship between ScreenPos and PRINT) Apparently, when you "print" a numerical value, the print command just pokes that number into backtab. So, you have to change line 5 to: 5. #myda = (label1(0) * + CS_WHITE To get it to work. In color stack mode, backtab looks like this: ;;--------------------------------------------------------------------------;; ;; Useful bits for Color Stack Mode ;; ;; ;; ;; Display format word layout in Color Stack Mode: ;; ;; 13 12 11 10 9 8 7 6 5 4 3 2 1 0 ;; ;; +----+-----+----+----+----+----+----+----+----+----+----+----+----+----+ ;; ;; |Adv.|FG |GRAM| GRAM/GROM Card # | FG Color | ;; ;; |col |Bit3/|GROM| (0-255 for GROM, 0-63 for GRAM) | Bits 0-2 | ;; ;; |stck|----------| | | ;; ;; | |col. sqr. | | | ;; ;; | |mode slct.| | | ;; ;; +----+-----+----+----+----+----+----+----+----+----+----+----+----+----+ ;; ;; ;; The numbers in the string are ascii codes - 32. They need to be shifted by 8 and have a color added to show up properly on the screen. Does this make sense? Catsfolly P.S. This prints "awesome". INCLUDE "constants.bas" Mode 0,STACK_BROWN,STACK_BROWN,STACK_BROWN,STACK_BROWN Wait Print at 20 , "X " for i = 0 to 6 #myda = (label1(i) * + CS_WHITE Print #myda next i LoopMain: Goto LoopMain label1: DATA "AWESOME" Quote Link to comment Share on other sites More sharing options...
GroovyBee Posted December 9, 2016 Share Posted December 9, 2016 (does not work, trying to understand the relationship between ScreenPos and PRINT)You will have to use :- poke screenaddr(#hpos,4), #myda Instead. Don't forget that #hpos must be in the range 0 to 19 due to the hidden multiply in the DEF FN. The poke command is likely to be more efficient too, since it does not have to update the _screen IntyBASIC internal variable. 1 Quote Link to comment Share on other sites More sharing options...
First Spear Posted December 9, 2016 Share Posted December 9, 2016 Cool! A follow on question is to know how many elements are in a DATA Label? I understand that string length per item is non-trivial at this point, but is knowing the quantity of items possible? Thanks. You will have to use :- poke screenaddr(#hpos,4), #myda Instead. Don't forget that #hpos must be in the range 0 to 19 due to the hidden multiply in the DEF FN. The poke command is likely to be more efficient too, since it does not have to update the _screen IntyBASIC internal variable. Quote Link to comment Share on other sites More sharing options...
GroovyBee Posted December 9, 2016 Share Posted December 9, 2016 Cool! A follow on question is to know how many elements are in a DATA Label? I understand that string length per item is non-trivial at this point, but is knowing the quantity of items possible? Thanks. There is no official EOL marker in IntyBASIC. One way to solve the problem would be to leave the calculation to AS1600 by using the following code :- label1: asm DECLE @@label1End - @@label1 asm @@label1: DATA "Awesome","sauce" asm @@label1End: Thus the first value in the string existing at label1 would contain the length (the assembler pokes it in for you). This is how strings are stored in PASCAL. You would change asm @@label1: to asm @@label2: and so on for each string's start. You'd also change asm @@label1End: to asm @@label2End: and so on. Unlike IntyBASIC, AS1600 labels are case sensitive so you need to make sure you keep the label case consistent between the "domains". Labels that start with @@ are considered to be local in AS1600 and will not clash with IntyBASIC's auto-generated label format either. I did experiment with varptr in a data statement but that didn't work as I expected. 1 Quote Link to comment Share on other sites More sharing options...
First Spear Posted December 9, 2016 Share Posted December 9, 2016 Interesting. Thanks for digging deep. From a functional standpoint, maybe it is then better to put all of strings into an array. I would then know the number of elements and could grab one from any position. Is that correct? There is no official EOL marker in IntyBASIC. One way to solve the problem would be to leave the calculation to AS1600 by using the following code :- label1: asm DECLE @@label1End - @@label1 asm @@label1: DATA "Awesome","sauce" asm @@label1End: Thus the first value in the string existing at label1 would contain the length (the assembler pokes it in for you). This is how strings are stored in PASCAL.You would change asm @@label1: to asm @@label2: and so on for each string's start. You'd also change asm @@label1End: to asm @@label2End: and so on. Unlike IntyBASIC, AS1600 labels are case sensitive so you need to make sure you keep the label case consistent between the "domains". Labels that start with @@ are considered to be local in AS1600 and will not clash with IntyBASIC's auto-generated label format either. I did experiment with varptr in a data statement but that didn't work as I expected. Quote Link to comment Share on other sites More sharing options...
GroovyBee Posted December 9, 2016 Share Posted December 9, 2016 From a functional standpoint, maybe it is then better to put all of strings into an array. You mean like the following: LabelArray: DATA varptr Label1(0),varptr Label2(0),varptr Label3(0) Label1: DATA "Hello" Label2: DATA "Intellivision" Label3: DATA "World" I would then know the number of elements and could grab one from any position. Is that correct? Arrays can only be one dimensional in IntyBASIC. Quote Link to comment Share on other sites More sharing options...
catsfolly Posted December 10, 2016 Share Posted December 10, 2016 Interesting. Thanks for digging deep. From a functional standpoint, maybe it is then better to put all of strings into an array. I would then know the number of elements and could grab one from any position. Is that correct? I don't really see how putting the strings in an array gains you anything. The strings do have a fixed length that you declare when you create them, but as far as I know there is no way for the program to ask a string "How long are you?", so the information will have to be made available another way, like a table of constants... If you put the strings in data statements, you can either: 1. Use Groovy's method to put a string length at the start of each string, or 2. Define your own string terminator code and add it to the end of each string. CONST string_terminator = ($1234) ' any number larger than 2 digits i = 0 loop: if label1(i) = string_terminator then goto done #myda = (label1(i) * + CS_WHITE Print #myda i = i + 1 goto loop done: label1: DATA "AWESOME" DATA "string_terminator Catsfolly Quote Link to comment Share on other sites More sharing options...
First Spear Posted December 10, 2016 Share Posted December 10, 2016 Sorry Mr Folly, I wasn't clear I don't think. I want to have a data set of strings, and arbitrarily pick one of the strings from the list and print it to the screen. I can make them all the same length if I have to. I don't really see how putting the strings in an array gains you anything. The strings do have a fixed length that you e {snip} Catsfolly 1 Quote Link to comment Share on other sites More sharing options...
GroovyBee Posted December 10, 2016 Share Posted December 10, 2016 Created an example of handling an array of strings here. Quote Link to comment Share on other sites More sharing options...
catsfolly Posted December 11, 2016 Share Posted December 11, 2016 (edited) I wrote the Trollish Comment Generator years ago before IntyBasic had varptrs (or even strings!). I used a simplistic approach - I put all my strings in one big data list, with a string terminator at the end of each string. When I wanted to print the nth string, I just read through my big data list until I counted "n" string terminators. The next word in the list was the start of my string. I then printed the string characters until I reached the next string terminator. The advantage of this brute force approach is that it only requires one simple data structure, so it easy to add and change strings. The disadvantage in that it is slow (at run time). It takes a lot of processor time to step through all the strings. But for my application I didn't care about speed. I even added a bunch of waits to the character output routine to slow things down. Just some input, Catsfolly "They call me MR. FOLLY!" Edited December 11, 2016 by catsfolly 1 Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted December 11, 2016 Share Posted December 11, 2016 In P-Machinery 2.0 I use a different approach that perhaps may work on IntyBASIC: I put strings in a large table, packed two characters per word, with the length on the first byte (a la Pascal strings). I then build an index table with a pointer to the beginning of each string. The string library uses the index to find the strings in the table, and dereferences it directly. I do all this in one go with macros, but I guess in IntyBASIC you could build the index using labels within the table. Picking one at random is as simple as picking a random number between 0 and the length of the index array and using it as the index to the table. -dZ. 2 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.