-
Notifications
You must be signed in to change notification settings - Fork 6
Miskatino Basic Manual
- Overview
- Simple commands and program
- Expressions and Variables
- Commands explanation
- Operations in expressions
- Built-in Functions
- System Commands
Miskatino Basic allows you to interact with microcontroller in "live mode". You may either enter commands to be executed at once, or store them as a program memory and launch as a whole when the program is completed.
It is not the greatest thing for large and complicated programs, but will suit well smaller applications (like driving simple robots, Christmas illumination etc) and may serve good for education purpose.
Normally you connect to Miskatino via UART (also USB bridge or Bluetooth module attached to UART) with the following settings: echo should be off, baud rate is 115200 - and others are pretty default (8 data bits, no parity, 1 stop bit, no hardware flow control).
As soon as you have connected to the chip via serial link, you can try to type the command:
INFO
and hit enter to execute it. You may see the response like this:
code: 2
vars: 0
next: 1
which, besides showing that controller is working, briefly gives some information on the state of memory etc (details would be given later).
If you couldn't see anything being typed, then either Miskatino is not connected properly, or is already running a command. You may try to execute BREAK (with Ctrl-C or dedicated zigzag-like button on a android bluetooth terminal). If it works, Miskatino will print BREAK
and should then respond to your commands.
Let's try a few simple commands. Start with well-known PRINT
:
PRINT 20 * 10 + 18
After hitting enter key Miskatino should respond printing the result of the expression: 2018
. We can also define variable and use it in expression:
X = 13
PRINT X*X*X
The first line adds a variable into memory with name X
and value 13
. Then it is used to print 2197
.
Now, to create a program, we enter commands prefixed by line numbers. They are organized in the memory according to order of these numbers and then executed one by one. Let's try:
10 X = 9
20 PRINT X
30 Y = 15
40 PRINT X*Y
When you enter program lines, they are not executed immediately. But you then can use LIST
and RUN
commands to either view the current program or launch its execution. In the latter case you should see something like this:
RUN
135
End of code
A few more words on expressions and variables, which were presented to us above. All expressions in Miskatino Basic are calculated in integers, as floating point variables are comparatively rarely needed in microcontrollers world, and as their calculation is slower on small processors.
Integer values are in range between +/- 2 billions for STM32 and Linux version (4 bytes signed), and only -32768 ... 32767
for Arduino port (2 bytes signed).
Expressions may consist of numbers, variables, operations (like +
, -
, *
, /
, %
, <
, >
- see full list below) and function calls.
Variables are distinguished by the first two letters, so it usually makes sense to keep them short (especially in platforms with small memory, like Arduino).
Array variables should use only single letter (so there should be no more than 26 arrays, but given small microcontroller memory it would be enough anyway).
Numbers could be entered in decimal, hexadecimal, binary, octal formats and also as character constants:
PRINT 65; " decimal"
PRINT 0x41; " hex"
PRINT 0b1000001; " bin"
PRINT 0101; " octal"
PRINT 'A; " char constant"
All these commands will print value of 65
. However there is no straight way to print value non-decimal form.
PRINT - prints value of the given expression or constant string (double-quoted) to serial console; several expressions (probably, mixed with strings) could be given separated by semicolons:
PRINT 13
13
PRINT "Happy New Year!"
Happy New Year!
PRINT "Your age is less than: "; 7*11*13; " years"
Your age is less than 1001 years
INPUT - allows to read integer value into variable:
INPUT a
? 11
PRINT a; " squared is "; a*a
11 squared is 121
Older versions supported reading several variables, but later this was removed as virtually useless feature.
REM - just a comment line, everything in the line is ignored. On platforms with small memory (like Arduino) you will not like adding many comments as they consume proportional amount of RAM.
REM Program for driving robot via Bluetooth REM (c) 2018, Humpty-Dumpty & Sons
IF - conditional execution; it takes expression and another command, separated by semicolon (instead of "then"); the command is executed if expression calculates to non-zero (relational operations execute to non-zero if relation is correct):
IF X % 2 = 1; PRINT "odd number"
IF X % 2; PRINT "odd number"
IF X < 0; PRINT "negative"
DELAY - makes execution pause for given amount of milliseconds; e.g. here is waiting for 5 seconds:
DELAY 5000
GOTO - jump to the line with the given number and continue execution from there; the main instrument for looping and branching:
10 X = 1
20 PRINT X
30 X = X + 1
40 GOTO 20
PIN - to control the pin output signal (0, 1) or make it input (-1); also values (-2) for pull-up input and (-3) pull-down input are recognized if hardware support such input configuration:
10 REM Blinking example
20 PIN 9; 1
30 DELAY 500
40 PIN 9; 0
50 DELAY 800
60 GOTO 20
END - stop execution; useful for inserting debug breaks or to prevent main program run into subroutine (see below)
RETURN - return from subroutine (see below)
GOSUB - subroutine call; works like GOTO
, but stores the next (by order) line number, so that execution can return to it later with RETURN
command:
10 X = 50
20 GOSUB 100
30 X = 500
40 GOSUB 100
50 END
100 REM Subroutine to blink the led X times
...
190 RETURN
DIM - allocate an array with given variable name and size, optionally letter B
could be added to specify that byte-array is needed (which takes 4 or 2 times less memory)
DIM A 100
DIM Y 30 B
DATA - loads values to the most recent allocated array; usually you execute it immediately after DIM; several commands could be added if many values are necessary; String constants are also allowed (in this case ASCII codes are stored in array):
DIM P 12
DATA 3 1 4 1 5 9
DATA 2 6 5 3 5 8
PRINT P(0); "..."; P(11)
3...8
DIM C 20 B
DATA "Hi, Friends!" 13 10 0
EMIT - similar to PRINT
, but outputs character for given ASCII-codes; it is useful to output character with code 10
at the end as a newline:
EMIT 65; 10
A
EMIT 'A + 5; 'A + 0x25; 10
Ff
POKE - puts data byte into memory address (register, or io-port) - is mainly useful to control special hardware of microcontroller, according to specification of given chip; 32-bit versions also have POKE2 and POKE4 commands, which work with 2 and 4-byte values respectively.
POKE 0x80002540; 0b11001001
Binary arithmetic operations
+
, -
, *
, /
- all work as expected, division is integer; %
is modulo operation
Relational operations
<
, <=
, =
, <>
, >=
, >
- all return 1
if the condition is true and 0
otherwise
Unary operators
-
and !
- are arithmetic negation and logic inversion respectively
Logic operators
&
and |
could be used in logic expressions for AND
and OR
respectively
ABS - absolute value of an argument
PRINT ABS(8-13)
5
KEY - reads character from console (UART), in non-blocking fashion; returns either ASCII-code or -1
; useful for interactive control of robots, leds etc; argument should be non-zero if character should be removed from input; the following code waits while some key is pressed and then prints its code:
10 IF KEY(0) < 0; GOTO 10
20 PRINT KEY(1)
MS - returns current time in milliseconds (e.g. from the last reset, but depends on platform), divided by the value passed as argument (or "as is" if divisor is less than 2). The following will print values incrementing every second:
10 PRINT MS(1000)
20 DELAY 310
30 GOTO 10
PEEK - reads byte from given memory address (register, or io-port) - so it is complementary to POKE
; on 32-bit platforms PEEK2 and PEEK4 versions are available for fetching 2-byte and 4-byte values from memory:
PRINT PEEK(0x86)
PIN - reads logical signal (0, 1) from the given pin
10 IF PIN(8) <> 0; GOTO 10
ADC - reads voltage from given analog input; value range is specific to platform - it is 0...1023
on Arduino and 0...4095
on STM32; ADC(-1) returns supply voltage measured in millivolts
PRINT ADC(-1)
2856
There are commands which could only be executed directly, not as lines of program:
LIST
- lists the lines of program in memory, optionally starting line and page size could be specified (e.g. LIST 1 10
- print up to ten lines from the very first); without arguments in prints each time the next page until program ends.
SAVE
- saves the program into persistent memory, so it could be loaded later (and after reset / power off).
LOAD
- loads previously saved program; current program in memory is lost.
RESET
- clears memory, forgetting current program (but it doesn't remove it from persistent memory, unless SAVE
is executed after).
RUN
- runs the program; it saves program before run, so it is not lost if anything goes wrong; program already running could be interrupted with Ctrl-C
(char with ascii code 3).
STEP
- executes single (next) line of code; optional numeric argument could be given to execute several lines
at once.
INFO
- prints how much bytes of memory is taken currently by program and by data; note that until assignment or DIM statements are executed, the memory is not reserved for their variables (i.e. just adding them to program without running does not yet consume memory); also prints the number of next line to be executed by STEP
.
QUIT
- return to OS - this is only supported in linux version (as one has nowhere to quit when running on the real chip).