SuperBASIC: Difference between revisions
No edit summary |
(attempt to make the link at least work despite the security warning) |
||
(48 intermediate revisions by 8 users not shown) | |||
Line 3: | Line 3: | ||
* [[SuperBASIC Memory Map]] | * [[SuperBASIC Memory Map]] | ||
* Watch EMWhite's excellent intro series on YouTube: [https://www.youtube.com/playlist?list=PLeHjTvk7NPiSqGz4REMH-S4hjYpLS2YNR Full Playlist]. | * Watch EMWhite's excellent intro series on YouTube: [https://www.youtube.com/playlist?list=PLeHjTvk7NPiSqGz4REMH-S4hjYpLS2YNR Full Playlist]. | ||
* Read EMWhite's [https://apps.emwhite.org/shared-files/885/?Foenix-Rising-Issue-18-November-2024.pdf&download=1 Foenix Rising Issue 18] (November 2024) which goes into detail about a few of the gotchas of superbasic. | |||
=== An informal list of tips, "gotchas": === | |||
===== | ===== IF, THEN, ELSE ===== | ||
====== Source of this tip: Ernesto ====== | |||
* A regular <code>if then</code> condition can't contain an <code>else</code> statement, as in this example: | * A regular <code>if then</code> condition can't contain an <code>else</code> statement, as in this example: | ||
<code>10 if a=0 then x=10</code> | <code>10 if a=0 then x=10</code> | ||
Line 25: | Line 28: | ||
40 x=2 <br /> | 40 x=2 <br /> | ||
50 endif</code> | 50 endif</code> | ||
''Debugging hint: If you encounter an error like "open structure" or "endproc without a proc": do not trust the line number that you are given. The root of the problem is probably in a structure earlier on in the code.'' | |||
===== Evaluating multiple conditions in IF statements ===== | |||
SUPERBASIC doesn't have the dedicated keywords AND , OR so you have to use the bitwise operators to evaluate multiple conditions, please consider the following examples: | |||
* AND <code>if (a=1)&(b=2) then c=1</code> | |||
* OR <code>if (a=1)^(b=2) then c=1</code> | |||
This should work as long as you use parenthesis in all evaluated expressions (Since parenthesis makes bitwise operators behave like logical operators). | |||
===== Using procedures ===== | |||
* The <code>proc</code> keyword is only valid if it appears after an <code>end</code> statement. | |||
* When calling a procedure use the procedure name followed by parenthesis (), even if the procedure has no parameters. | |||
* Avoid any space between the procedure name and the parenthesis, else it will produce an error. | |||
===== Keyboard shortcuts ===== | |||
{| class="wikitable" | |||
|+ | |||
!Key combination | |||
!Effect | |||
|- | |||
|<code>ctrl-c</code> or <code>RUN STOP</code> on the F256K | |||
|Stops a listing or a running program | |||
|- | |||
|<code>ctrl-l</code> | |||
|Clears the screen | |||
|- | |||
|<code>ctrl-a</code> or <code>CLR/HOME</code> on the F256K | |||
|Move cursor to the first character in the current line | |||
|- | |||
|<code>ctrl-e</code> | |||
|Move cursor to the last character in the current line | |||
|- | |||
|<code>ctrl-i</code> | |||
|Move cursor 8 characters to the right | |||
|- | |||
|<code>ctrl-k</code> | |||
|Deletes characters from cursor position to line end | |||
|} | |||
===== Behaviour of load and bload ===== | |||
* The <code>bload</code> statement does not print <code>Completed</code> when loading is successfull whereas <code>load</code> does. | |||
* bload can load anywhere on memory not just under the first 64k | |||
* An exception is that bload can't load I/O parameters that reside in $C000 - $DFFF | |||
===== Control characters for cursor and colour control ===== | |||
In BASIC the following character codes can be used with <code>print</code> to control the cursor position and colours on the screen. | |||
{| class="wikitable" | |||
!Code | |||
!Effect | |||
|- | |||
|chr$(1) | |||
|Set cursor to leftmost position in current line | |||
|- | |||
|chr$(2) | |||
|Cursor left | |||
|- | |||
|chr$(5) | |||
|Set cursor to righmost position in current line | |||
|- | |||
|chr$(6) | |||
|Cursor right | |||
|- | |||
|chr$(11) | |||
|Deletes characters from cursor position to line end | |||
|- | |||
|chr$(12) | |||
|Clear screen and set cursor to upper left corner | |||
|- | |||
|chr$(13) | |||
|Move cursor to start of next line | |||
|- | |||
|chr$(14) | |||
|Cursor down | |||
|- | |||
|chr$(16) | |||
|Cursor up | |||
|- | |||
|chr$(128) - chr$(143) | |||
|Set foreground color. Code 128 is black 143 is white. The rest follows the sequence given below | |||
|- | |||
|chr$(144) - chr$(159) | |||
|Set background color. Code 144 is black 159 is white. The rest follows the sequence given below | |||
|} | |||
{| class="wikitable" | |||
!Colour code | |||
!Colour | |||
!Colour code | |||
!Colour | |||
|- | |||
|0 | |||
|Black | |||
|8 | |||
|Dark grey | |||
|- | |||
|1 | |||
|Grey | |||
|9 | |||
|Light grey (default foreground) | |||
|- | |||
|2 | |||
|Dark blue (default background colour) | |||
|10 | |||
|Blue | |||
|- | |||
|3 | |||
|Green | |||
|11 | |||
|Light green | |||
|- | |||
|4 | |||
|Purple | |||
|12 | |||
|Light purple | |||
|- | |||
|5 | |||
|Brown | |||
|13 | |||
|Red | |||
|- | |||
|6 | |||
|Orange | |||
|14 | |||
|Yellow | |||
|- | |||
|7 | |||
|Light blue | |||
|15 | |||
|White | |||
|} | |||
===== Character Set / Text matrix ===== | |||
* Access to the full character set can be obtained by using the <code>CPRINT</code> command instead of the normal <code>PRINT</code> command. | |||
* Characters can also be set on the screen text matrix using the <code>POKE</code> command starting at <code>$C000</code> providing the MMU I/O control is set to 2 by executing a <code>POKE 1,2</code> command first (remember to restore the MMU I/O once you're done). | |||
[[File:Full char set.png|thumb|104x104px|F256 Character Set|none]] | |||
* Color can also be set on the screen color matrix using the <code>POKE</code> command starting at <code>$C000</code> providing the MMU I/O control is set to 3 by executing a <code>POKE 1,3</code> command first (remember to restore the MMU I/O once you're done). | |||
* When poking colors on the screen, the high nibble is the character color and the low nibble is the background color. | |||
[[File:Colormatrix.png|alt=Default Colors|thumb|100x100px|Default Colors|none]] | |||
===== Memcopy lockup ===== | |||
* In certain situations the <code><big>memcopy</big></code> command can lockup. | |||
* A machine language utility that performs the same function as <code>memcopy</code> is available if <code>memcopy</code> fails. | |||
* <u>mlcopy</u> is a short routine that replaces <code>memcopy</code> and is more reliable. It can be loaded into memory with a BLOAD command in your program, or with a basic loader that can be added to your program. | |||
* In place of the <code>memcopy</code> command you would use 3 <code><big>POKEL</big></code> commands and a <code><big>CALL</big></code> command to engage the DMA engine. | |||
<code>POKEL $0903,data source</code> | |||
<code>POKEL $0906,destination</code> | |||
<code>POKEL $0909,number of bytes to copy</code> | |||
<code>CALL $0900</code> | |||
* [https://github.com/mcassera/F256-mlcopy mlcopy github page] | |||
===== Sprite Images ===== | |||
In BASIC you can access different SPRITE shapes through the IMAGE command as part of the sprite command: <code>SPRITE 0 IMAGE 1 TO 100,100</code>. Be aware that BASIC can only keep track of 64 Images, if you want to access and show more than 64 different shapes you need to poke the 3 bytes of the address where the image data resides into the correct sprite registers yourself. | |||
===== Sprite Coordinates ===== | |||
In BASIC all sprites are centered on the coordinate specified, this might produce some counterintuitive effects when using different size sprites, for example if you want to align the sprite edge with the top left side of the screen you would need different values depending on the sprite size | |||
<code>SPRITE 0 IMAGE 1 TO 4,4: REM "8x8 Sprite"</code></BR> | |||
<code>SPRITE 1 IMAGE 1 TO 8,8: REM "16x16 Sprite"</code></BR> | |||
<code>SPRITE 2 IMAGE 2 TO 12,12: REM "24x24 Sprite"</code></BR> | |||
<code>SPRITE 3 IMAGE 3 TO 16,16: REM "32x32 Sprite"</code></BR> | |||
Also, please note that you need to use the command <code>SPRITE X IMAGE Y</code> before setting the sprite coordinates or else BASIC will not know what size is the sprite, and will misalign it, for example the following code although it seems correct will misalign the sprite: | |||
<code>SPRITE 1 TO 8,8</code></BR> | |||
<code>SPRITE 1 IMAGE 1: REM "USe a 16x16 Sprite"</code></BR> |
Latest revision as of 19:11, 17 November 2024
SuperBASIC is inspired by BBC BASIC but offers quite a bit more.
- SuperBASIC Reference Manual.
- SuperBASIC Memory Map
- Watch EMWhite's excellent intro series on YouTube: Full Playlist.
- Read EMWhite's Foenix Rising Issue 18 (November 2024) which goes into detail about a few of the gotchas of superbasic.
An informal list of tips, "gotchas":[edit | edit source]
IF, THEN, ELSE[edit | edit source]
Source of this tip: Ernesto[edit | edit source]
- A regular
if then
condition can't contain anelse
statement, as in this example:
10 if a=0 then x=10
- If you need to do an
if then else
structure, you actually have to do anif else endif
structure like in the following example, skipping thethen
statement.
10 if a=0
20 x=1
30 else
40 x=2
50 endif
- If you do it in one line it needs to have some colons added, making it look weird like this:
10 if a=0:x=1:else:x=2:endif
- if you dare to omit the
endif
thinking that theif
statement won't need it, (mmm.., everything is in one line, so no need, right?) -Nope...all hell breaks loose!-
10 if a=0:x=1:else:x=2: REM "<-- Error, omited the endif"
- be careful not to add an extra
then
statement by mistake to anif else endif
structure, if you do -All hell breaks loose again!!-
10 if a=0 then : rem "<-- Error, THEN is not needed!!!"
20 x=1
30 else
40 x=2
50 endif
Debugging hint: If you encounter an error like "open structure" or "endproc without a proc": do not trust the line number that you are given. The root of the problem is probably in a structure earlier on in the code.
Evaluating multiple conditions in IF statements[edit | edit source]
SUPERBASIC doesn't have the dedicated keywords AND , OR so you have to use the bitwise operators to evaluate multiple conditions, please consider the following examples:
- AND
if (a=1)&(b=2) then c=1
- OR
if (a=1)^(b=2) then c=1
This should work as long as you use parenthesis in all evaluated expressions (Since parenthesis makes bitwise operators behave like logical operators).
Using procedures[edit | edit source]
- The
proc
keyword is only valid if it appears after anend
statement. - When calling a procedure use the procedure name followed by parenthesis (), even if the procedure has no parameters.
- Avoid any space between the procedure name and the parenthesis, else it will produce an error.
Keyboard shortcuts[edit | edit source]
Key combination | Effect |
---|---|
ctrl-c or RUN STOP on the F256K
|
Stops a listing or a running program |
ctrl-l
|
Clears the screen |
ctrl-a or CLR/HOME on the F256K
|
Move cursor to the first character in the current line |
ctrl-e
|
Move cursor to the last character in the current line |
ctrl-i
|
Move cursor 8 characters to the right |
ctrl-k
|
Deletes characters from cursor position to line end |
Behaviour of load and bload[edit | edit source]
- The
bload
statement does not printCompleted
when loading is successfull whereasload
does. - bload can load anywhere on memory not just under the first 64k
- An exception is that bload can't load I/O parameters that reside in $C000 - $DFFF
Control characters for cursor and colour control[edit | edit source]
In BASIC the following character codes can be used with print
to control the cursor position and colours on the screen.
Code | Effect |
---|---|
chr$(1) | Set cursor to leftmost position in current line |
chr$(2) | Cursor left |
chr$(5) | Set cursor to righmost position in current line |
chr$(6) | Cursor right |
chr$(11) | Deletes characters from cursor position to line end |
chr$(12) | Clear screen and set cursor to upper left corner |
chr$(13) | Move cursor to start of next line |
chr$(14) | Cursor down |
chr$(16) | Cursor up |
chr$(128) - chr$(143) | Set foreground color. Code 128 is black 143 is white. The rest follows the sequence given below |
chr$(144) - chr$(159) | Set background color. Code 144 is black 159 is white. The rest follows the sequence given below |
Colour code | Colour | Colour code | Colour |
---|---|---|---|
0 | Black | 8 | Dark grey |
1 | Grey | 9 | Light grey (default foreground) |
2 | Dark blue (default background colour) | 10 | Blue |
3 | Green | 11 | Light green |
4 | Purple | 12 | Light purple |
5 | Brown | 13 | Red |
6 | Orange | 14 | Yellow |
7 | Light blue | 15 | White |
Character Set / Text matrix[edit | edit source]
- Access to the full character set can be obtained by using the
CPRINT
command instead of the normalPRINT
command. - Characters can also be set on the screen text matrix using the
POKE
command starting at$C000
providing the MMU I/O control is set to 2 by executing aPOKE 1,2
command first (remember to restore the MMU I/O once you're done).
- Color can also be set on the screen color matrix using the
POKE
command starting at$C000
providing the MMU I/O control is set to 3 by executing aPOKE 1,3
command first (remember to restore the MMU I/O once you're done). - When poking colors on the screen, the high nibble is the character color and the low nibble is the background color.
Memcopy lockup[edit | edit source]
- In certain situations the
memcopy
command can lockup. - A machine language utility that performs the same function as
memcopy
is available ifmemcopy
fails. - mlcopy is a short routine that replaces
memcopy
and is more reliable. It can be loaded into memory with a BLOAD command in your program, or with a basic loader that can be added to your program. - In place of the
memcopy
command you would use 3POKEL
commands and aCALL
command to engage the DMA engine.
POKEL $0903,data source
POKEL $0906,destination
POKEL $0909,number of bytes to copy
CALL $0900
Sprite Images[edit | edit source]
In BASIC you can access different SPRITE shapes through the IMAGE command as part of the sprite command: SPRITE 0 IMAGE 1 TO 100,100
. Be aware that BASIC can only keep track of 64 Images, if you want to access and show more than 64 different shapes you need to poke the 3 bytes of the address where the image data resides into the correct sprite registers yourself.
Sprite Coordinates[edit | edit source]
In BASIC all sprites are centered on the coordinate specified, this might produce some counterintuitive effects when using different size sprites, for example if you want to align the sprite edge with the top left side of the screen you would need different values depending on the sprite size
SPRITE 0 IMAGE 1 TO 4,4: REM "8x8 Sprite"
SPRITE 1 IMAGE 1 TO 8,8: REM "16x16 Sprite"
SPRITE 2 IMAGE 2 TO 12,12: REM "24x24 Sprite"
SPRITE 3 IMAGE 3 TO 16,16: REM "32x32 Sprite"
Also, please note that you need to use the command SPRITE X IMAGE Y
before setting the sprite coordinates or else BASIC will not know what size is the sprite, and will misalign it, for example the following code although it seems correct will misalign the sprite:
SPRITE 1 TO 8,8
SPRITE 1 IMAGE 1: REM "USe a 16x16 Sprite"