This chapter provides the basics of programming with ugBASIC. They are essential for the “skeleton” of programs, and to understand what does what and, above all, how things work.
If you are an experienced BASIC (or high-level scripting language) programmer this section is not essential because you are already familiar with these topics. Nonetheless, a brief glance can provide useful information on some specific aspects, such as the syntax of some constructs.
ugBASIC is designed to provide you with the simplest and most convenient way to control your programming needs, and while it provides very powerful programming capabilities, it has deliberately avoided introducing difficult concepts and terms.
A “string” is a number of characters strung together. A set of quotation marks is placed at either end of the string to “hold it” together and keep it separate from the rest of the program. Each string is also identified by its own name, so that it can be called up by that name, and used elsewhere in the program. The (optional) “dollar” character $
is usually attached to the tail of string name, so that ugBASIC will consider this name as a string.
Characters in a string can be letters, numbers, symbols or spaces. The following example creates a simple string
named a$
, and it is defined by letting the name of the string equal the characters enclosed in quotes, like this:
A$ = "ugBASIC"
Here is another example, using three different strings:
a$ = "UGBASIX": b$ = "is" : c$ = "a compiler" DEBUG a$ + b$ + c$
Strings are extremely useful, and they can act on their own or work together. Strings are covered in a dedicated section.
There are some elements of a computer program that are set aside to store the results of calculations: the place where they are stored is called “variables”. A variable is like the name of a place where a value resides, and where the value can change as a result of a calculation made by the computer. Variables are given names and, once a name is chosen, a value can be assigned, like this:
score = 42
This example creates a variable with the name score
and loads it with a value of 42.
There are a few rules for naming of a variable. First of all, all variable names must begin with a single alphabetical letter. So ok
is a good variable name while 42yesterday
is not.
Variable names can be as short as one character, and as long as 255 characters1), but they can never contain a blank space. So the next name is allowed:
okComputer=1
But this is an invalid variable name:
ok computer = 1
To introduce a space use a replacement character like the “underscore:
ok_computer = 1
Finally, you cannot use a variable name that “overlaps” a ugBASIC keyword, because this would confuse the compiler. This is an example:
OK = 42: REM this is ok! REM = 42: REM this is not ok!
If you try to use an illegal variable name, ugBASIC will emit a compilation error that has nothing to do with the error itself, since the compiler will try to parse the variable names as instructions.
A full list of the various keywords can be found in the keywords index. Take care that, for convention, keywords are all UPPERCASE. So it is very easy to avoid to overlap the keywords by using a mixed case or lower case variable names.
Finally: before using a variable, you should define it at least once. This can be done by a simple assignment. If you miss to do so, ugBASIC will define an integer variable for you.
Some values never change. In computer science these values are called constants. In ugBASIC there is a very convenient way to indicate this type of values, and that is to assign these values to labels, which can then be used instead of variables. This is an example:
CONST neverChange = 42
This example creates an integer constant with the name neverChange
and the value of 42.
The rules for naming constants are the same of naming a variable, so those are valid constant names:
okComputer=1 myConstantIsDifferent=1
But this is an invalid constant name:
my constant is different = 1
To introduce a space use a replacement character like the “underscore”:
my_constant_is_different = 1
If you try to use an illegal constant name, ugBASIC will give you a compilation error, since the compiler will try to parse the constant names as instructions. Again, a full list of the various keywords can be found in the keywords index. Take care that, for convention, keywords are all UPPERCASE. So it is very easy to avoid to overlap the keywords by using a mixed case or lower case constant names.
As a general rule, ugBASIC treat constants as 16 bit unsigned whole numbers (integers), and convert them automatically, before they are used. If they are prefixed by an hash (''#'') operator, they can be optimized by ugBASIC.
In ugBASIC there are various types of variables. The first is used to represent a “whole number”, like 1 or 4242. Whole numbers are called, technically, “integers”. They are perfect for holding the sort of values used in computer games or programs, for example:
hiscore = 1000
By default, integers in ugBASIC are 16 bits longs. This means that can take an integer value from 0 to 65535, inclusive. Also negative numbers are allowed, but they uses 15 bits (one bit is used for the sign).
To set a number as relative (so that it has negative values) it is sufficient to assign a negative value:
negative = -42 : ' so negative will be a SIGNED WORD!
Again, the number of bits can be changed at any time by specifying the variable type at the time of assignment:
hiscore = (32BIT) 1000: REM use a 32 bit variable hiscore = (8BIT) 100: REM use an 8 bit variable
From then on, the variable will be defined with that bitwidth.
Alongside these “mathematical” data types, there are also “logical” data types, which can be useful in the various calls to the various instructions:
ADDRESS
, a value that represents a position in memory;POSITION
, a value that represents a position on the screen;COLOR
, a value that represents an indexed color of a palette.The number handling is explained in a specific section.
All variables are stored in a memory area called “bank”. Simplifying, a bank is an area of memory that is dedicated to a specific purpose, that starts from a specific address and it is automatically filled with a certain type of data. Whenever a variable is defined, it will take up some space in a bank. In ugBASIC there is a specific BANK
for the variables, names (yup!) VARIABLES
and of the same type. You can, obviously, create new VARIABLES banks and assign variables to other banks.
For example, if you want to define variables starting from position 0xc000 (49152 as decimal) in memory, you can easily do so:
BANK VARIABLES AT $c000 x = 42: REM x will be stored at $c000 y = 84: REM y will be stored at $c002
You can change banks everytime you need.
BANK VARIABLES AT $c000 x = 42: REM x will be stored at $c000 y = 84: REM y will be stored at $c002 BANK VARIABLES AT $c200 z = 128: REM z will be stored at $c200
You can also mixup the banks, and assign a variable to a specific bank:
BANK VARIABLES bank1 AT $c000 BANK VARIABLES bank2 AT $c200 VAR x ON bank1: REM x will be stored at $c000 VAR y ON bank1: REM x will be stored at $c002 VAR z ON bank3: REM x will be stored at $c200
Banks are very powerful tools to optimize memory usage.
It is often necessary to use a whole set of similar variables for something like a table of soccer results or a catalogue for a record collection. Any set of variables can be grouped together in an “array”. Supposing you have 42 titles in your record collection, and you need to change the size of the table of variables needed for your array. There is a special command for setting up this dimension.
The DIM
command is used to dimension an array, and the variables in your record collection table could be set up with a first line like this:
DIM artist$(99), title$(99), year(99), price(99)
Each dimension in the table is held inside round brackets, and if there is more than one element in a dimension each number must be separated from the next by a comma. Element numbers in arrays always start from zero, so your first and last entries might contain these variables:
artist$(0)="Cindy Lauper" title$(0)="Girls Just Want To Have Fun" year(0)=1983 price(0)=10 artist$(99)="David Bowie" title$(99)="Space Oddity" year(99)=1967 price(99)=8
To extract elements from any array, you could then add something like this to your example program:
DEBUG title$(0): DEBUG price(0) DEBUG title$(99): DEBUG year(99): DEBUG price(99)
These tables can have as many dimensions as you like, and each dimension can have up to 256 elements. Here are some more modest examples:
DIM list(5),number(5,5,5),word$(5,5)
Arrays are also useful for multitasking programming, as you can see in the dedicated section.
There is a whole set of entities in ugBASIC that work with numbers and variables, in order to give a result. We call them “functions”. For example, this is the function that return a 16 bit random value:
number = RANDOM
ugBASIC provides ready-made functions.
In addition, it also provides functions available at compile time, which allow you to further optimize the developed code. This is very useful for computers that have few resources. For example, you can assign a value to a constant depending on the result of a processing:
CONST pictureToUse = IF( SCREEN WIDTH > 160, "large.png", "small.png" )
The values that are entered into an ugBASIC instruction or functions are known as “parameters”. Each instruction and function has its own syntax. Parameters cannot be left out.
Once a program is running, you are able to control what happens next. For example, you could stop it for a while. For this purpose you can use the WAIT
instruction. This command tells the computer to stop and wait for as long as you want before moving on to the next instruction. The number that follows it is the waiting time and the time units.
The following example forces the program to make a border of color yewllo, wait for two seconds (2000 ms), and then to change the border color to black:
COLOR BORDER YELLOW WAIT 2000 MS COLOR BORDER BLACK
As soon as the HALT
command is recognised, it stops the program.
Up now, individual commands have been issued in a separated way: infact, we typed them in and pressed the [ENTER] key to enter them on a new line of the program. Sometimes, programmer will want to place groups of related commands together on the same line of the program. This is achieved by separating instructions with a colon (:
) character. ugBASIC makes typing in instructions as simple as possible, and you will not normally have to worry about typing in correct spacings, as long as you follows the above rules.
COLOR BORDER WHITE:WAIT 2 SECONDS:COLOR BORDER BLACK
When a program is very complex, you need a way to remember where everything is or what anything is supposed to do. There is a simple and effective way of marking any part of an ugBASIC program: it is the inserting messages to remind yourself exactly what this section of program is for. These little comments or messages are known as “Rem statements” or remarks.
The beginning of a remark is marked by the keyword REM
or by the apostrophe (') character, which is simply a shortcut for the
REM
command.
' An example of comment REM Also this one is a comment!
A REM
statement can occupy their own line, or can be placed at the end of a line of the program, as long as they are. They must be separated from the last instruction by a colon. Remember that comments are for human eyes only, and when the compiler translate the BASIC program in an executable, the REM
statements are completely ignored by the computer.