Jump to content
IGNORED

Getting substrings in IntyBASIC - is there a way to do this?"


Recommended Posts

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! ;)

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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 by DZ-Jay
Link to comment
Share on other sites

  • 7 months later...

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 by First Spear
Link to comment
Share on other sites

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 by catsfolly
  • Like 2
Link to comment
Share on other sites

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"

Link to comment
Share on other sites

(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.
  • Like 1
Link to comment
Share on other sites

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.

 

Link to comment
Share on other sites

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.

  • Like 1
Link to comment
Share on other sites

 

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.
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

Link to comment
Share on other sites

 

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

  • Like 1
Link to comment
Share on other sites

I wrote the Trollish Comment Generator years ago before IntyBasic had varptrs (or even strings!).

 

post-14916-0-66294100-1481449576_thumb.gif

 

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 by catsfolly
  • Like 1
Link to comment
Share on other sites

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.

  • Like 2
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...