Adding extra string manipulation techniques to BASIC

By default Sinclair BASIC provides very limited string manipulation techniques. However, you can easily add more functionality via the following methods.

The following methods are taken from an original World of Spectrum Forum thread,  started by Andrew Owen. However, I’ve added some details for better explanation of each method.

The earlier versions of UPPER$ and LOWER$ didn’t work as expected and Alvin Albrecht was kind enough to provide the corrected versions.

LEFT$(string, number)

DEF FN L$(s$, x) = s$( to x)

Given a string, the L$ function will return a string starting from the leftmost character (hence called LEFT$ in some BASIC implementations) and up to x characters to the right. Therefore, if you have a string, say “Hello” and wish to extract just “Hell” from it, you can do FN L$(a$, 4), where a$ is the string holding “Hello”. A typical example in BASIC would be:

05 DEF FN L$(s$, x) = s$( to x)
10 LET a$ = "Hello"
20 LET b$ = FN L$(a$, 4)
30 PRINT b$

The above BASIC example is easily modified for the rest of the functions that follow.

RIGHT$(string, number)

DEF FN R$(s$, x) = s$(LEN s$ + 1 – x TO LEN s$)

Given a string, the R$ function will return a string starting from the rightmost character (hence called RIGHT$ in some BASIC implementations) and up to x characters to the left. Therefore, if you have a string, say “Hello” and wish to extract just “ello” from it, you can do FN R$(a$, 4), where a$ is the string holding “Hello”.

MID$(string, number1, number2)

DEF FN M$(s$, x,y) = s$(x TO x – 1 + y)

Given a string, the M$ function will return a string starting from anywhere in the string x and up to y characters to the right (hence called MID$ in some BASIC implementations). Therefore, if you have a string, say “Hello” and wish to extract just “ell” from it, you can do FN M$(a$, 2,4), where a$ is the string holding “Hello”.

LOWER$(string)

DEF FN D$(s$) = VAL$ “CHR$ ((CODE s$)+(32 AND CODE s$ > 64 AND CODE s$ < 92))+FN D$(s$(2 TO ))”( TO 27+12*(LEN s> 1))

Given a string, the D$ function will return a string with all characters converted to lower case (hence called LOWER$ in some BASIC implementations). Therefore, if you have a string, say “Hello” and wish to convert all of it to lower case (“hello”), you can do FN D$(a$), where a$ is the string holding “Hello”.

UPPER$(string)

DEF FN U$(s$) = VAL$ “CHR$ ((CODE s$)-(32 AND CODE s$ > 96 AND CODE s$ < 124))+FN u$(s$(2 TO ))”( TO 28+12*(LEN s$> 1))

Given a string, the D$ function will return a string with all characters converted to upper case (hence called UPPER$ in some BASIC implementations). Therefore, if you have a string, say “Hello” and wish to convert all of it to upper case (“HELLO”), you can do FN U$(a$), where a$ is the string holding “Hello”.

Using the Kempston Joystick in your own BASIC programs

Traditionally, games in BASIC use the keyboard for player input and act accordingly. For eg, the keys Q, A, O and P may be used to move the player character around and M may be used to fire or other action. However, as anyone who has played ‘professional’ games (i.e written using machine code) on the speccy would know, using a joystick is a far better alternative especially in fast action games.

This article will tell you how to use the popular Kempston Joystick in your games for that ‘professional’ touch. 😉

To begin with, inputs from the Kempston Joystick are read via port 31. The Spectrum manual has more information on what a ‘port’ is and so I won’t be covering it here. Suffice to say, any external device connected to the speccy reads through a specific port, numbered 1 to 255. The Kempston Joystick uses port 31.

To read the ‘value’ in port 31 you simply do: LET kj = IN 31. Depending on what state the joystick is in, kj will hold a very specific value that can be interpreted as desired. Now then, the Kempston joystick  has only 5 states to deal with, namely ‘Fire’ (any of the fire buttons pressed), ‘Up’ (joystick pulled back), ‘Down’ (joystick pushed forward), ‘Left’ (joystick to the left) and ‘Right’ (joystick to the right).

This information is packed into a single byte in the following format: 000FUDLR. As you can see only the lower 5 bits are of interest to us, which means we can ignore any value of kj above 31. Depending on which bit is set (value of 1) we can assume the joystick is in that state. Multiple states are also possible – firing and moving for example, or moving diagonally for example. Obviously you can’t have states of ‘Up’ & ‘Down’ or ‘Left’ & ‘Right’ occurring simultaneously!

The table of basic values that we need to test is given below:

kj (IN 31) Bit pattern (lower 5 bits only) State
1 00001 Right
2 00010 Left
4 00100 Down
8 01000 Up
16 10000 Fire

For the purpose of this tutorial I’m going to ignore multiple directional states because BASIC doesn’t support the kind of bit level manipulation we would like to achieve detection of that. However, it will be useful to detect if we’re firing and moving so that will be on the agenda.

Let’s get the simple detection out of the way first!

10 LET x=10: LET y=10
20 LET kj=IN 31: REM get the state of joystick
30 PRINT AT y,x;"*"
40 IF (kj>31) OR (kj=0) THEN GO TO 20: REM ignore spurious inputs
45 BORDER 1: PRINT AT y,x;" ": REM overwrite at old position
50 IF kj=1 THEN LET x=x+1: REM left
60 IF kj=2 THEN LET x=x-1: REM right
70 IF kj=4 THEN LET y=y+1: REM Down
80 IF kj=8 THEN LET y=y-1: REM Up
90 IF kj=16 THEN BORDER 2: REM Fire
100 GO TO 20

The code is pretty simple. To see it in action we will print an asterisk on the screen that can be moved about by manipulating the joystick. Screen boundaries aren’t checked though to keep the code simple. We’ll also set the border to Red if the fire button is pressed. That’s it really.

To check for the event of fire and moving we’ll have to perform a simple trick. When firing and moving, kj will have bit 5 (for fire) and the bits for movement (any of them from 1 to 4) to be set, leading to a number  that is greater than 16 (since fire by alone is itself 16). So all we do then is check for this fact (kj > 16) and if so, note that the fire is being pressed and then subtract 16 from kj so that we can continue to check for the movement keys as normal.

The above code can be modified so (changed lines in blue):

10 LET x=10: LET y=10
20 LET fire=0: LET kj=IN 31: REM note: reset fire event every time!
30 PRINT AT y,x;"*"
40 IF (kj>31) OR (kj=0) THEN GO TO 20
45 BORDER 1: PRINT AT y,x;" "
46 IF kj>16 THEN LET kj=kj-16: LET fire=1: REM Check if firing AND moving
50 IF kj=1 THEN LET x=x+1
60 IF kj=2 THEN LET x=x-1
70 IF kj=4 THEN LET y=y+1
80 IF kj=8 THEN LET y=y-1
90 IF kj=16 OR fire THEN BORDER 2: REM fire by itself or firing and moving? If so red border
100 GO TO 20

That’s about it really. Doing the above in machine code is, in fact, easier because it has all the necessary operators to perform low level bit manipulation which you really need if you want to check for multiple states of the joystick. However, I believe the above will do very nicely for those BASIC games that do not need diagonal movement!

Experiment and enjoy!