Omikron BASIC 3.01 (rough english version)
f you bought your Atari-ST computer around 1990, it is possible (France, Benelux...) that Omikron 3.01 BASIC was given, with an approximate literature. This page should fix it.
The Omikron 3.01 BASIC was written out by Artur Södler (and Thomas Kemp for the mathematical routines) in 68000 assembly language, a very concise one: the application is only 106KB large. With that you're able to do about anything you want. But if you want to use the GEM (Graphic Environment Manager), in order to use menus, mouse and windows, you will have to find a very good documentation, and a resources constructor would also be useful.
You don't have anymore ST, TT or Falcon? It is currently possible to use this BASIC on Atari emulation (.fr): Aranym means 'Atari runs on any machine', and so does Hatari...
1. Editors and commands
2 Variables and values
1. Editors and commands ( → .fr)
Omikron 3.01 has two editors.
1.1 The standard editor ( → .fr)
The first editor looks like the traditional editors such as they existed on the first platforms (Commodore 64), where each line of code is prefixed by a number.
Type 10 print "Hulloder!" (and [Return]) and your first code line is recorded. Type LIST and 10 PRINT "Hulloder! appears.
LIST lists the whole program in the order of the numbers of line
LIST n only lists line n
LIST -n lists the program up to line n
LIST m- lists the program starting from line m
LIST m-n lists the lines of programme from m to n
RENUM renumbers the lines of the program, 10 by 10
RENUM m ...by specifying the number of the first line
RENUM l, m, n the line m becomes l , the following ones n by n
CLS erases the screen and places the cursor in the top left corner
CLEAR puts the variables at the 0, close all files, checks the loops and disconnects the conditional subroutines
NEW ! CAUTION: erase a *.BAS-file in memory
QUIT or SYSTEM leaves the interpreter. You will be asked to confirm.
RUN puts the variables at 0, checks and runs the program
RUN 100 , RUN Aum ...starting from line 100 or at the label -Aum
GOTO n runs a program from then line n without putting the variables at 0.
Keys specific to the standard editor ( → .fr)
[Enter] or [Return] validates a line of program
[ClrHome] place the text-cursor in the left top of the screen
[Ctrl]-[ClrH] erases the screen (LIST to list out the program)
[Ctrl]-[Del] erases the line after the cursor.
[Ctrl]-[Arrow-Up] erase the cursor line, and pull up the following ones
[Ctrl]-[Arrow-Dn] inserts a line and push down the following ones
[Ctrl]-[Arrow-Lf] sets the left-higher corner of a window (=CHR$(4))
[Ctrl]-[Arrow-Rg] sets the right-lower corner of the window (=CHR$(5))
[ClrH] [ClrH] cancels the frame set by the the two previous key-combinations
[Ctrl]-[S] suspends a running program
[Ctrl]-[Q] start again a suspended program
[Ctrl]-[C] stops a program
[Sft]-[Sft] allows a command during a running program (63 characters buffer)
[Ctrl]-[Alt] erases the content of the keyboard-buffer
KEY n defines the 20 function-keys (KEY 13= [Sft]-[F3])
KEY 10=CHR$(27)+"E" '= CLS (here 2 characters, maximum 32)
KEY 10="quit"+CHR$(13)+"y" to quit Omikron from standard editor
KEY LIST lists the 20 function-key of the standard editor. Do use the super-editor menu in order to save the function-key definitions: /mode/save settings .
To use a function-key in a program, watch its scancode: $3B to $44 for [F1] to [F10]; $70 to $79 for [Sft]-[F1] to [Sft]-[F10]
1.2 The graphical editor ( → .fr)
The graphical editor has a menu-system and manages the mouse. It also makes it possible hide off the line numbers. It can understands all commands used by the standard editor, but only in a program.
[F1] goes to a precise numberline|
[F1] [Arrow-Up] goes to the top of the screen
[F1] [Arrow-Dn] goes to the bottom of the screen
[Sft]-[F1] divides the screen
[Sft]-[F2] passage from a window to the other
[Sft]-[F3] changes the police height
[F3] [F2] replaces a string
[F3] [F3] replaces all the strings
[F6][n] repeats n time the last character
[Sft]-[F6] [F9] cuts a line|
[Sft]-[F6] [Sft]-[F9] pastes two lines
[F7] [F8] saves the block in ASCII
[F7] [Sft]-[F8] loads a block in ASCII
[F8] saves a program
[Sft]-[F8] loads a program
[F9] inserts a line
[Sft]-[F9] removes a line
[F10] displays the following page
[Sft]-[F10] displays the previous page
[Sft]-[F7] allows to define the keys [F4], [Sft]-[F4], [F5], [Sft]-[F5]
and the right mousebutton:
[Sft]-[F7] [key-to-define] [c] [o] [m] [m] [a] [n] [d] [Sft]-[F7]
By default, the right mousebutton inserts a selected block, very useful.
[Ctrl]-[Return] cuts a code line
[Ctrl]-[ClrHome] displays/hides the line-numbers
[Ctrl]-[Arrow-Up]/[Arrow-Dn] sends the cursor on previous/following page
[Ctrl]-[Sft]-[Arrow-Up]/[Arrow-Dn] sends the cursor on the first/last line
[Ctrl]-[Arrow-Lf]/[Arrow-Rg] sends the cursor on the preceding/following word
[Ctrl]-[Sft]-[Arrow-Lf]/[Arrow-Rg] sends the cursor at the beginning/end of the line
In a program ( → .fr)
STOP or [Ctrl]-[C] is written in a program to have a pause
DUMP it's then possible to display the variables and their value
DUMP V, W... ...only beginning by V, W, ...
CONT in the standard editor, will take again the program stopped by STOP or [Ctrl]-[C]
CONT TO n takes again the program to stop with line n
CONT m TO n takes again the program in m until n
REM makes it possible to write a remark. Replaceable by one ' single quotation mark
END finishes the program and closes all the files
2. Variables ( → .fr)
Any string of letters (with no accent) including or not figures or underline "_" but not starting with a figure, can be a variable, with the proviso of not being an instruction, procedure nor function.
2.1 Numerical variables ( → .fr)
Omikron processes various types of numbers. To avoid problems, it is necessary to be attentive to use the adequate variables. For example calculation: V=.1: PRINT 1/V produces the error "Division by zero" because the BASIC interprets the variable V like an integer and rounds it to 0. To prevent this error, use a "real" variable:
V!=.1: PRINT 1/V!
V% (or V%W) is a short integer, 16 bits/2 bytes, and contains values from -32 768 to 32 767
V (or V%L) is a long integer, 32 bits/4 bytes, and contains values from -2 147 483 648 to 2 147 483 647
V! is a "single precision" real, taking 6 bytes in memory
V# is a "double precision" real, taking 10 bytes in memory
Single and double-precision "reals" have an exponent of -4 931 to 4 941, and only differ by the precision of their mantissa: 9 significant figures for the first, 19 for the second.
V%F is a Boolean variable, that is to say a bit of value of 0 or -1
V%B is a variable representing a byte, that is to say 8 bits, having for possible value from 0 to 255
These two lattest formats can only be used in arrays.
It's possible to break up a long integer into two short ones:
?HIGH($12345678) returns 4660 ($1234 converted into decimal), word of "strong weight"
?LOW($12345678) returns 22136 ($5678), word of "weak weight".
Omikron uses to convert the type of the results. For example ?LN (3) will give a real. But it happens that it is necessary to specify the result type (attention to round-offs and capacity overflows):
V#=CDBL() converts into single Real
V!=CSNG() converts into double Real
V%=CINT() converts into short Integer
V=CINTL() converts into long integer
Type declaration ( → .fr)
It is not mandatory to declare the variables at the beginning of a program, as it is common for other languages, but it is possible to declare a priori the type of the variables used.
DEFINT "Q" all variables starting with Q will be short integers, without % nor %W
DEFINTL "R" all variables starting with R will be long integers, without %L (default)
DEFSNG "C, L" C... and L... will be 'single' reals, without !
DEFDBL "D-H" D... E... F... G... and H... will be 'double' reals, without #
The DEF... must be written before any programming! If not, it is necessary to add them at the beginning of program, to save in ASCII with SAVE "NOM.BAS", A (no LIST !), then to reload the file with LOAD .
2.2 Numerical bases ( → .fr)
% (or &B ) binary with its characters 0 and 1 : %1000101
& (or &0 ) octal with its characters from 0 to 7 : &7532136
nothing (or &d ) decimal (mode by default)
$ (or &h ) hexadecimal (from 0 to 9 and A to F ): $-7f3ad5
47= $2F (2*16+15)= &57 (5*8+7)= %101111 (32+8+4+2+1)
&b , &o , &d and &h ensure compatibility with other BASICS.
It is possible to convert the base of an unspecified number, with the proviso of respecting the limits imposed on the long integers:
BIN$() converts into %binaire: PRINT BIN$(25) is 11001
OCT$() converts into &octal: PRINT OCT$(35) is 43
HEX$() converts into $hexadecimal: PRINT HEX$(72) is 48
VAL("") converts into decimal PRINT VAL("$7fff") is 32767
It is possible to convert binary, octal or hexadecimal numbers to decimal ones by the function VAL even if they are not integer. The reverse is not possible.
2.3 Operators ( → .fr)
LET allocate a number or a string to a variable: LET Var=43
LET Var$ A$=A$+"43" is also possible: adds the strin "43" to the first.
LET is not necessary, but kept for compatibility with other basics. It's necessary to pay attention to variable type:
Var=3.14159 will only allocate 3 , because it's entire.
In A=B=6 , A is -1 (logical "true") if B is equal to 6 , 0 else ("false").
+, -, *, / as usual
\ entire division: the result is integer: 43/5= 8
MOD modulo: the rest of a division 43\5= 3
ABS absolue value or a real: ?ABS(-43)= 43
SGN gives the sign of a number: ?SGN(-43)= -1 , ?SGN(43)= 1
FRAC returns la partie décimale d'un réel: ?FRAC(4.3)=.3
FIX returs la partie entière d'un réel: ?FIX(4.3)= 4
INT rounds to the roof integer: ?INT(-4.3)= -5
= is also used as equality comparator
< strictly lesser than, <= ou=< lesser or equal
> strictly greater than, >= ou=> greater or equal
?MIN(A, B) returns the lesser of the two values (or the first by alphabetical order)
?MIN(A, B) returns the greater of the two values (or the second by alphabetical order)
2.4 Mathematical functions ( → .fr)
Trigonometry ( → .fr)
DEG if you want to work with degrees
RAD sets back in radian mode (by default)
PI returns PI (double precision: 3.1415926535897932...)
Omikron knows the main trigonometrical functions:
SIN - COS - TAN - COT - SEC - COSEC - - ARCSIN - ARCCOS - ARCTAN (ou ATN) - ARCCOT
SINH - COSH - TANH - COTH - SECH - COSECH - - ARSINH - ARTANH - ARCOTH
Power and logarithm ( → .fr)
^ power: 2^16= 65536
LOG(A, B) logarithm base A for the number B LOG(2, 8)= 3
SQR(n) SQuare Root of n : ?SQR(7744)= 88
EXP(n) exponentia1 (base e) of the number n
LN(n) natural logarithm (base e= 2.7182818287983537...)
n must be greater than 0
FACT(n) factorial of n (integer). FACT(5) gives 120 (5*4*3*2*1)
Random ( → .fr)
RND(1) returns a random value between 0 and .99999999
RND(n) returns an integer value between 0 and n-1
-RND(-n) returns an integer value between 1 and n
RND(0) returns the last given random number
RND(6)+1 ou -RND(-6) is the same as a six-faced dice play
-RND(-6)-RND(-6) two six-faced dices play, which is bnot the same as -RND(-12) nor 1-RND(-11) , since the 11 results don't have the same chance to come.
XBIOS(R, 17) the R variable returns a 24 bits semi-random number
2.5 Character strings ( → .fr)
The string character are surrounded by quotation marks. The variables which represent them and the instructions which return strings must have the suffix $ (but not LEN() nor INSTR() which return a number). As for the numerical variables, it is possible to define string-variable at the beginning of program: DEFSTR A .
A$= "Holy": B$= "Graal": ? A$ +B$ gives HolyGraal (without space)
"Ni!"*3 gives Ni!Ni!Ni! (the multiplier must be written after the string)
B$= SPACE$(n) or SPC(n) builds a string of n spaces
STRING$(3, "6") gives 666 multiplies 3 times one (only) character...
STRING$(n, asc) character is defined here by its ASCII code
LEN("Camelot") gives 7 , the number of characters of a string. Caution: a positive numerical string can have one character more, the sign "plus", even undisplayed: PRINT LEN(STR$(123)) returns 4.
LEFT$("Aaaargh", 3) give Aaa , the three characters of left
RIGHT$("Aaaargh", 4) give argh , the four characters of right-hand side
INSTR(n, A$, B$) return the position of the 1st character of the B$ string if it is found in the A$ string, while seeking starting from position n (0 if it is not there)
MID$("Camelot", 3) returns melot , all the characters starting from the 3rd letter
MID$("Camelot", 3, 4) returns melo , 4 characters starting from the 3rd letter. This function can determine them in the following way:
V$= "Spam": IF MID$(V$, 3, 1)= "a" THEN MID$(V$, 3, 1)= "i": ?V$
MIRROR$("Spam") returns mapS , inverts the order of the characters
LOWER$("SPAM") returns spam , transforms capital letters in small letters
UPPER$("spam") returns SPAM , transforms small ones in capital letters
2.6 Types conversions ( → .fr)
CVI("") converts a two-character string into a short integer
CVIL("") converts a four-character string into a long integer
CVS("") converts a six-character string into a single precision real
CVD("") converts a ten-character string into a double precision real
ASC("") gives the ASCII code of the 1st character of the string
VAL("") converts a number-string into its numerical value, when it is possible:
?VAL("&63") , VAL("$FF") , VAL("%1011") but not ?VAL("1A") nor ?VAL("$1g")
MKI$(V%W) converts an short integer into two character string
MKIL$(V%L) converts a long integer into four character string
MKSS(V!) converts a single precision real into six character string
MKD$(V#) converts a double precision real into ten character string
STR$(V) converts a numerical expression into a string
CHR$(n) returns one of the 256 ASCII characters, n from 0 to 255:
FOR A= 32 TO 255 ' from 0 to 31 non-printable characters, use CHR$(1)+CHR$(n) PRINT USING "####"; @(4+A MOD 16, 5*((A\16)-2));A;CHR$(A) NEXT
2.7 Arrays and matrices ( → .fr)
DIM T#(11) dimensions an array of 12 double-precision real (t#(0) is the first element).
Without DIM dimensions is by default 10*10
DIM Goban%B(18, 18) contains the 19*19 intersections of a Go-ban
Aum%(3, 4)=29 indicates that the element 4th line/5th column array is 29
MAT CLEAR Chess%B(7, 7) erases the mentioned array
MAT CLEAR T(n) erases an array of numbers to a dimension until T(n)
SWAP V$, W$ exchanges the standard contents of 2 variables in the same way
SORT T$(0) sorts all the types of arrays to a dimension
SORT ASC A$(0) sorts an array of strings according to the ASCII code
SORT T(0) TO V(0) sorts the array V(0) according to the order of the array T(0)
Matrices ( → .fr)
Matrices are two-dimension real-arrays:
MAT A#(l, c)*n multiplies each element of the matrix by N
MAT A!(m, n)=B!(m, p)*C!(p, n) multiplies two matrices. The number of columns of the 1st matrix must be the same as the number of lines of the 2nd one
For square matrices only:
MAT A#(n, n)=INV B#(n, n) inverts a square matrix (columns become lines, lines become columns)
MAT A#(n, n)=1 makes it possible to generate a unit-matrix
X!=DET(A!(n, n)) returns the matrix determinant
2.8 Logical operators ( → .fr)
The logical operations concern the bits: numbers are written in binary.
NOT reverses the contents of the bits:
NOT %10=...11111111101= -3
(a number is negative if the more significant bit is 1)
AND selects the common '1' bits of two numbers:
%1100 AND %1010 are %1000
OR accepts that a bit is positioned for one or the other number:
%1100 OR %1010 is %1110
XOR excludes the common bits from two numbers:
%1100 XOR %1010 are %0110
NAND excludes the simultaneous veracity from the bits of two binary:
%1100 NAND %1010 are -9 (or NOT %1000, is NOT AND)
NOR the non-veracity of the bits checks two binary:
%1100 NOR %1010 is -15 (or NOT %1110, is NOT OR)
EQV admits the veracity or the non-veracity of the bits of 2 binary:
%1100 EQV %1010 are -7 (or NOT %110, is NOT(A XOR B)
IMP is the logical implication: A implies B means that A cannot be true when B is not. A IMP B is equivalent to NOT(A AND NOT(B)) :
%... 001100 IMP %...001010 is -5 (or NOT %...00100, is %...11011)
|With||B||NOT(B)||With AND NOT(B)||NOT(A AND NOT(B))|
BIT(n, A) returns value 0/-1 of bit n of A: ?BIT(3, %11001)= -1 (bit 0 is the first from right)
SHR(n) (Right Shift): shifts the bits of a number n times towards the right, which is equivalent to n divisions by 2.
SHL(n) (Shift Left): shifts the bits of a number n times towards the left, which is equivalent to n multiplication by 2.
3. Structures ( → .fr)
3.1 Conditions ( → .fr)
IF condition THEN commands ELSE commands : ENDIF
The instruction IF tests a condition and orders what follows THEN if the condition is true. ELSE (optional) permits what follows it in the event of condition not met. ENDIF is mandatory if a sequence IF/THEN/ELSE is written on several lines or if THEN is followed by a ": ". Two or more conditions can be imbricated.
10 N= -RND(-100): B=1 100 REPEAT 110 INPUT "a number from 1 to 100: "; A 120 IF A=N THEN PRINT "Found in"; B;" time ": END 130 IF A < N THEN 140 PRINT "A little more..." 150 ELSE 160 PRINT "A little less..." 170 ENDIF 180 B=B+1 190 UNTIL 0 ' 0 is logic 'false': condition never true
3.2 Loops ( → .fr)
The loops are portions of code which allow a repetitive work.
FOR V= n TO m (STEP p): commands : NEXT V ( → .fr)
V varies from n to m with each reiteration. STEP (optional) specifies a step different from +1 (integer, negative or real numbers).
FOR A= 0 TO 31 Ligne=8+A MOD 8: Column= 12+9*(A\8) PRINT USING "###"; @(Line, Column); A; " "; CHR$(1)+ CHR$(A) NEXT
REPEAT commands UNTIL condition ( → .fr)
The program repeats the instructions which follow REPEAT until the condition written after UNTIL is met.
REPEAT PRINT @(RND(24), RND(79));"*" UNTIL MOUSEBUT= 2
WHILE condition: commands WEND ( → .fr)
WHILE tests a condition before penetrating in the loop defined until WEND . For an infinite loop: WHILE -1 ('always true')
WHILE MOUSEBUT < 2 ' right button to leave the loop DRAW 320, 200 TO MOUSEX, MOUSEY WEND
EXIT ( → .fr)
Leaves, closes and jumps at the end of a loop although the 'while' or 'until' condition is not true.
WHILE -1 instructions IF condition THEN EXIT WEND
EXIT TO -Lbl leaves, closes and jumps at the label Lbl (compound of EXIT and GOTO .
3.3 Procedures ( → .fr)
The procedures are subroutines, callable directly by their name. One can define local variables by LOCAL V$=, W$= which will not interfere with the aggregate variables of the same name, which makes it possible to call programs with CHAIN MERGE without being concerned with possible homonymies of the variables.
A procedure can call another of them. In order to avoid the error "Direct Illegal", the procedures are defined after END .
10 INPUT "Radius and Height: "; R!, H!: Cone ' call of procedure 20 PRINT "the volume of the cone is: "; V! 30 END 1000 DEF PROC Cone 1010 V!= R!^2 * PI * H!/3 1020 RETURN
A procedure can return parameters:
10 INPUT "A!, B!"; A!, B! : Rapport(A, B) ' call of procedure 20 PRINT A!, B! 30 END 1000 DEF PROC Rapport(R X!, R Y!) ' R for Return 1010 X!= X!/Y!: Y!= 1/X! 1020 RETURN
3.4 User-function ( → .fr)
The functions are defined according to the principle of the procedures, but returns one (and only one) value, specified after RETURN . They are called by FN Nom$ . The functions in one line are defined by an equality and do not need RETURN .
10 PRINT FN Hasard 20 END 100 DEF FN Hasard= -RND(-6) -RND(-6) ' different from -RND(-12)
Another example, returning a string:
10 A$= "Black night": PRINT FN Inverse$ 20 END 100 DEF FN Inverse$ ' $ since it returns a string 110 A$= CHR$(27)+ "p"+ A$+ CHR$(27)+ "q" 120 RETURN A$
A very traditional example, where the function uses recursivity:
10 TRON: INPUT "X: "; X ' for X not too large 20 PRINT FN Factor(X): TROFF 30 END 100 DEF FN Factor(X) 110 IF X=0 THEN RETURN 120 RETURN X * FN Factorielle(X-1)
The function calls upon itself as long as the decrementation of X does not reach 0
3.5 Data exploitation ( → .fr)
DATA expresses data (expressions, variables, arrays)
READ V$, W$ reads one or more data in the line of DATA
10 CIRCLE 250, 136, 40: DRAW 300, 50 20 FOR I=1 TO 6: READ X, Y: DRAW TO X, Y: NEXT 30 DATA 200, 50, 150, 136, 200, 222, 300, 222, 350, 136, 300, 50
RESTORE replaces the pointer on the 1st line of DATA
RESTORE 1000 or RESTORE Etiqu after the line 1000 or -Etiqu
ON n RESTORE Et1, Et2... sends the pointer on DATA according to the label chosen according to n
10 INPUT "Spanish=1, English=2, Dutch=3:"; Language 20 INPUT "Which figure? "; C 30 ON Language RESTORE Cifras, Digits, Cijfers ' choose the line 40 FOR I= 0 TO C: READ Word$: NEXT I' chooses the data 50 PRINT "the figure"; C; " is "; Word$: END 100 -Cifras: DATA "Cero", "Uno", "Dos", "Tres", "Quatro" 110 DATA "Cinco", "Seis", "Siete", "Ocho", "Nueve" 120 -Digits: DATA "Zero", "One", "Two", "Three", "Four", "Five" 130 DATA "Six", "Seven", "Eight", "Nine" 140 -Cijfers: DATA "Nul", "Één", "Twee", "Drie", "Vier", "Vijf" 150 DATA "Zes", "Zeven", "Acht", "Negen"
3.6 Connections ( → .fr)
GOTO 300 have the program jumped to line 300
GOTO Aum goes directly to the label -Aum . A label is preceded by an hyphen
GOTO 500+n operations are possible
GOTO (V) or (V$) a variable can contain a number or a label
ON n GOTO n1, n2... for n from 1 to X, the program will jump to the line n1, n2... or nx
RENUM respects the connections, the desactivation of the number of lines in the super-editor not: use labels. For a better legibility of the program, do use loops and EXIT TO to leave there, which gives the meter of the loop to 0.
3.7 Routines ( → .fr)
GOSUB Aum sends to a subroutine, with the label -Aum
ON n GOSUB n1, n2, chooses the subroutine according to n
RETURN returns to the instruction according to the appealing GOSUB
The subroutines (or routines) are written at the end of the program after END so that the program does not meet RETURN without to be sent to the subroutine by GOSUB .
In a general way, one will prefer procedures and functions.
Conditional subroutines ( → .fr)
These four comands are to be written out in the beginning of the program.
ON TIMER n GOSUB Etiq reacts every n seconds
ON MOUSEBUT GOSUB Etiq reacts if a mouse button is clicked
ON HELP GOSUB Etiq reacts if the [Help]-key is clicked
ON KEY GOSUB Etiq reacts is any key is typed
This last command keeps the key in the buffer: you must clear it with V$=INKEY$ or V$=INPUT$(1) in the subroutine in order to avoid a recursive call.
To set off a conditional subroutine: ON < > GOSUB 0
See also ON TRON GOSUB et ON ERROR GOTO at Error processing.
4. Devices ( → .fr)
The BIOS has low-level functions to send a byte to a device (or to receive from). You normally should/would never use it, but who knows? For P: 0=parallel-port printer, 1=Serial port RS232, 2=console (screen), 3=MIDI, 4=keyboard-processor:
BIOS(R, 1, P) returns -1 if the device (1-2-3) has got a byte to send
BIOS(R, 2, P) reads a byte from the device (0-1-2-3)
BIOS(R, 8, P) returns -1 if the device (0-1-3-4) can receive a byte
BIOS(, 3, P, n) sends a byte to the device (0-1-2-3-4)
4.1 Screens ( → .fr)
Omikron 3.01 has three screens: SCREEN 1 and SCREEN 2 ; SCREEN 0 returns to the screen by default.
Addr=(MEMORY(32256) AND $FFFF00)+256: SCREEN 1, Addr
Note: for TOS <1.6, a screen address must be a multiple of 256 (i.e. must end with 00 in hexadecimal). To adjust a screen address, you have to prepare a little greater memory amount, shorten the address by AND $FFFF00 and add 256 bytes in order not to spoil the datas staying before the new address.
Only with screen 0 (by default)
PRINT CHR$(1) helps to type [Ctrl]-[A] [Ctrl]-[Lettre] or ?CHR$(1)+CHR$(1 to 31)
PRINT CHR$(2) inserts a character into the place of the cursor
PRINT CHR$(3) erases one of them (= [Ctrl]-[C] if IPL 3 + (1 SHL 31) )
Only with screen 1 and 2
? CHR$(27);"w" cancels the automatic follow-up
? CHR$(27);"v" automatic follow-up at the end of the line
With the three screens
PRINT CHR$(4) the position of the cursor defines the top-left corner
PRINT CHR$(5) the position of the cursor defines the bottom-right corner
[ClrH] [ClrH] back to the normal
PRINT CHR$(7) gives a 'shping!'
PRINT CHR$(8) moves the cursor on the left while erasing (= [BackSp])
PRINT CHR$(9) the position of the cursor to the following tabulation (every 8 columns)
PRINT CHR$(10) moves the cursor a line lower (= CHR$(11) and CHR$(12))
PRINT CHR$(13) moves the cursor at the beginning of line, but [Ctrl]-[M]=[Enter]
GEMDOS(R, 16) R=$FFFF if the screen is ready to display, otherwise R=0
XBIOS(R, 2) returns the screen physical address (which is displayed)
XBIOS(R, 3) returns the screen logical address (where you print your graphical functions)
XBIOS(Rez, 4) Rez= 0 for low; 1 for medium; 2 for high resolution
XBIOS(, 5, L Log, L Ph, Rez) sets theses 3 parameters (-1 for unchanged). For the TOS < 1.60, the screen address is to be a multiple of 256:
Addr=(MEMORY(32256) AND $FFFF00)+256
XBIOS 5 is used to manage different screens at the same time, e.g. displaying the physical screen while using graphical functions on the logical one, giving more comfort to the eyes.
Addr1=( MEMORY(32256) AND $FFFF00)+256 ' useful to adjust the screen memory to $xxxx00 Addr2=( MEMORY(32256) AND $FFFF00)+256 PRINT CHR$(27)+"f" ' text cursor off (default is ON in Omikron 3.01) WHILE MOUSEBUT <2 ' right button to end XBIOS (,5,L Addr1,L Addr2,-1) ' display on Addr2, work on Addr1 FILL STYLE =2, RND(24) ' random filling mode PBOX RND(10)*50, RND(10)*30,50,50 ' filled square at random place on screen WHILE MOUSEBUT >0: WEND ' waiting for no clic WHILE MOUSEBUT =0: WEND ' waiting for a left or right clic XBIOS (,5,L Addr2,L Addr1,-1) ' display on Addr1, work on Addr2 FILL STYLE =2, RND(24) PCIRCLE 40+ RND(10)*55,40+ RND(10)*30,35 ' filled circle at random place on screen WHILE MOUSEBUT >0: WEND WHILE MOUSEBUT =0: WEND ' waiting for a clic, right one to exit the main loop WEND
XBIOS(R, 7, c, n) sets the colour c, n from $000 to $777; reads if n=-1. See PALETTE for the 16 color levels (STE).
4.2 Console out ( → .fr)
CLS CLear the Screen and place the text-cursor top-left
PRINT @(line, column); place the text-cursor at a precise place
?CSRLIN gives the number of line of the cursor (from 1 to 25!)
?POS(0) the number of column of the cursor gives, (0) obligatory
LOCATE line, column place the cursor at a precise place (line from 1 to 25)
PRINT CHR$(27)+"f" hides the text cursor
PRINT CHR$(27)+"e" shows the text cursor
PRINT "the square of A is:"; A^2 displays a text and a result
PRINT COS(PI/4) displays the result of the function cosine
PRINT "COS(PI/4)" displays COS(PI/4) (without the quotation marks)
WRITE "Text" displays "TEXT" (preserves the quotation marks)
PRINT 3*5;"H"*2 displays 15HH without separation (semicolon)
PRINT COS(0), "*" displays 1, * separated by a tabulation (since comma)
PRINT A$;:PRINT B$ ";" force the displaying of B$ following A$
PRINT CHR$(34);"3";chr$(34) displays "3" , CHR$(34) coding the quotation mark
PRINT SPC(n);"&" displays n spaces before & (see Strings)
PRINT TAB(c);V$ displays with the column defined by
PRINT @(l, c);V$ displays with the line and the column indicated
PRINT @(l, c);V$; to finish by a semicolon makes it possible to avoid the alinea
10 CLS: DEG ' programs including @(l, c) in a string 20 FOR X=0 TO 78 30 Y!=SIN(X*5)+SIN(X*13):Sin$=Sin$+@(Y!*6+12, X)+ "W" 40 NEXT: PRINT Sin$
PRINT CHR$(n) displays characters from 32 to 255
PRINT CHR$(1)+CHR$(n) displays characters from 1 to 31
The address $484 keeps a byte which bits represents: 3°: [Ctrl] and [Alt] - 2°: "Ping" - 1°: repetition - 0°: "Tik"
POKE $484, %1010 unsets key-"tik" and error-"ping" (bit 0 is the right one)
XBIOS(R, 16, L Addr1, L Addr2, L Addr3) sets the 3 character-tables for the keyboard, three 128-bytes strings following the Scancode. Addr1 pour unshifted keys, Addr2 for the shifted ones, Addr3 with CapsLock, -1 for no change
XBIOS(, 24) undoes all XBIOS 16 modifications (standard keyboard)
XBIOS(, 25, n-1, L Addr) sends a command to the keyboard-processor.
PRINT ... USING ( → .fr)
USING format decimal displaying for instruction PRINT
USING "####" next PRINTs will display a 4 character integer. Prints % if the integer is larger
USING "####.##" displays two digits after the decimal point
USING ", ####.###" the comma separates the thousands
USING ".#####, ####" commas and points are inverted
USING "+#####.####" displays the sign (even '+')
USING "####, ###+" '+' or '-' will be displayed after the number
USING "####, ###-" only '-' will be displayed after the number
USING "# # #. # #" separates the characters as indicated
USING "*$#######, ##" what follows * will fill blank characters
USING "##_+.##" forces displaying of what follows the _
USING "###^^^^" leaves 4 places for the scientific notation
PRINT USING "# # #, ###", V! formats only display of this PRINT
USING "##, ##" formats any displaying with PRINT , STR$ and PRINT #
USING without argument cancels any USING "####"
10 USING "+*@## ###, ##": PRINT SQR(2000000) ' displays @@@+1 414, 21 20 USING: PRINT SQR(2000000) ' displays 1414.2136
4.3 Console in ( → .fr)
When the program arrives at a intruction INPUT type, it prints the text written between quotation marks (or a question mark by default of text) and waits for a data:
INPUT A prints a question tag and waits for a number (and [Enter])
INPUT "A:"; A prints A: , the seizure of a long integer waits
INPUT Nom$ $ to enter a character string
INPUT @(l, c);"Texte: ";V$ displays the text at the place indicated
INPUT A, B, C 3 integers to enter, separated by commas
LINE A$ INPUT makes it possible to enter one (only) string with commas
A$= INPUT$(n) awaits n characters and [Return] before continuing
INKEY$ returns a string of 4 characters:
the 4th contains the ASCII code|
the 3rd is empty
the 2nd contains Scancode (code of the key)
|the 1st contains five bits:||
bit 0 is on: [Shift-Right] is pressed|
bit 1 is on: [Shift-Left] is pressed
bit 2 is on: [Ctrl] is pressed
bit 3 is on: [Alt] is pressed
bit 4 is on: [CapsLock] is pressed
This instruction does not wait, it must be put in loop:
10 A$= "" 20 REPEAT 30 A$= INKEY$ 40 UNTIL A$ > "" 50 Ascii$= RIGHT$(A$, 1): PRINT ASC(Ascii$) 60 Scan$= MID$(A$, 2, 1): PRINT ASC(Scan$) 70 Key$= LEFT$(A$, 1): PRINT(BIN(ASC(Key$)))
XBIOS(R, 35, D, V) sets the time before repetition et repetition speed of a maintained key (expressed in 1/50 sec). If D and V=-1 , R returns 1 byte for D and one for V
INPUT ... USING ... ( → .fr)
INPUT @(l, c);"Text"; V$ USING "Command", R, N, asc, P
"Command" allows or prohibits some characters:
0 allow all digits
A allows all letters, accentuated or not
% allows the special characters (%, !, ?, &, @...)
^ allows them [Ctrl]-[Key]
U (Upper) displays in capital letter, L (Lower) into small one
+ the character authorizes which follows (space, for example)
- prohibited the character which follows
C&% replace the first sign by the second (& by %)
< the left arrows has the [Return] effect
> the right arrows has the [Return] effect
ax_ " the specified character _ has the [Return] effect
+"x"+CHR$(A) or by its ASCII code
+"s"+CHR$(S) or by the key which Scanscode is defined
R returns CVIL(INKEY$) of the key which allowed the seizure, or
0 for [Enter],
-1 for > (going beyond by the line)
-2 for < (left by the left)
N is the length of the string to enter (255 max and per default)
asc is the ASCII code of the filling character ("_" by default)
P is the Position of the cursor on the string at the exit
INPUT A$ USING "0+, C., s"+CHR(1), R, 10, , P"
allows figures and comma, changes the point into comma, and allows [Esc]-key (scancode 1). Fields length is up to 10 characters ("_", by default).
4.4 Other devices ( → .fr)
Printer ( → .fr)
LPRINT prints a string on the parallel printer ([Alt]-[L])
LLIST list the BASIC program on the parallel printer
LDUMP prints all variables ont the printer
MODE LPRINT "F" sets accent-mode for a daisy-printer
LPOS(0) character-mode: gives the position of the printer-head
HCOPY prints the screen
HCOPY TEXT prints the screen, without any graphism
LPRINT "" sends a string to parallel port, generally to the printer
GEMDOS(R, 17) R=0 if the printer is not readyr
GEMDOS(, 5, n) sends a byte to the parallel port
XBIOS(, 33, F) F sets the printer category (twenty years ago!):
Serial port RS232 ( → .fr)
GEMDOS(R, 18) R=0 if the serial ports doesn't have a byte to deliver
GEMDOS(R, 3) reads a byte form the serial port RS232
GEMDOS(R, 19) R=0 if the RS232 is not ready
GEMDOS(R, 4) sends a character to the serial port RS232
XBIOS(, 15, Baud, Mod, Ucr, Rsr, Tsr, Scr) sets the parameters of the serial port RS232:
Baud: 0 to 15 transfert-rates 19200-9600-4800-3600-2400-2000-1800-1200-600-300-200-150-134-110-75-50
Mod: 0: no handshake; 1: XON/XOFF; 2: RTS/CTS; 3=1+2
Ucr: bit 1= 0/1 odd/even; bit 2= 0/1 non parity/parity
bits 3-4: 0=synchr; 1=1 stopbit; 2=1.5; 3=2 stopbits
bits 5-6: 0=8 bits; 1=7 bits; 2=6 bits; 3=5 bits
bit 1: if synchr: 1/0 divides the frequency, or not
Rsr: bit 0=1 active reception; bit 1=1 to receive
Tsr: bit 0=1 active emission; bit 1=1 to emit
Scr contains the synchronisation byte
-1 let a parameter unchanged
MIDI Port ( → .fr)
XBIOS R, 12, n, L Addr sends n (short integer) bytes at Addr to the MIDI-processor
Addr= MEMORY(20) FOR I= 0 TO 19: READ Byt: POKE Addr+I, Byt: NEXT XBIOS , 12, n, L Addr DATA ...20 bytes, comma-separated
4.5 Sound Yamaha 2149 and MIDI ( → .fr)
PRINT CHR$(7) gives a 'beep' corresponding to TUNE 1, 52
TUNE 1, n, 2, m, 3, p defines a height of sound for at least a way (3 maximum), which goes from acutest (1) to most serious (4095). 440= 125000/440=282
TUNE 1, 0, 2, 0, 3, 0 extinct all
VOLUME W, n sets a continuous sound, volume 0 to 15 for each Way
VOLUME v, e, d defines the type of envelope and its duration (only one type of envelope for the 3 ways). The 2 syntaxes of VOLUME are excluded for the same way.
|d= 7860||gives an approximate duration of 1 second|
e= 9 and 0, 1, 2, 3 |
15 and 4, 5, 6, 7
are of piano type: peak then descent|
are opposite: rises then collapse
is a repeated "piano" (9+9+9+...)
is a repeated "opposite" (15+15+15+...)
is a mountain: rises then descent
is a piano plus a mountain (0+14)
is a rise without descent
is a piano then a maintained sound
NOISE m, f the ways concerned with the noise (V1=1, V2=2, V3=4) are added to define the
mask (from 1 to 7), f chooses a frequency filter
NOISE 0, 0 cancels.
5 Storage ( → .fr)
5.1 File system ( → .fr)
* replaces name or an extension, ? a letter:
"A*.*" relates to all the files starting with an A
"*.PI?" relates to any file "*.PI1", "*.PI3", "*.PIC", aso.
FILES "A:\*.*" display the contents of the disc of the specified way
FILES "A:\DIRECTO\*.BAS" displays every *.BAS file of the directory DIRECTO of "A:"
Copy "A:\file" TO "C:\director \" copy a file of A: on C:
NAME "name.ext" AS "other.ext" rename a file
BACKUP "NAME" backup copy *.BAK of the preceding version
KILL "A:\director\filename" removes the file (according to the specified way)
KILL "A:\director\*.*" removes all the files of the aforesaid directory
MKDIR "A:\director" creates a directory on the specified reader
RMDIR "C:\director" erases a directory, but only if it is empty
CHDIR "director" enters the file doss
CHDIR "C:\director" or CHDIR "a:\" defines the active access path
CHDIR ".." leaves a under-directory and goes up towards the parent one
BIOS(R, 9, Lect) floppy change? 0: no; 1: maybe; 2: yes
BIOS(R, 1O) connected disks: bit 0=A:, 1=B:, 2=C:, as LPEEK($4C2)
GEMDOS(R, 14, Lect) sets the default disk (0=A:, 1=B:, 2=C:...)
GEMDOS(R, 25) returns the default disk (GEMDOS 14 format)
GEMDOS(R, 59, L Path) sets the default path, from a string null-terminated at address Path .
5.2 SAVE and LOAD ( → .fr)
SAVE "*.*" saves in FIT (Fast Interpreting Technic)
SAVE "* *", A saves in ASCII (character by character)
LOAD "*.*" charges a file saved in FIT or ASCII
LOAD "A:\SOME\*.*" specifies the way of the required file
RUN "*.*" charges and carries out the specified program
MERGE "Name" adds an ASCII program without crushing the precedent except if the numbers of
lines are the same ones
CHAIN "Nom", n chains a program, and erases the precedent
CHAIN MERGE "Nom", n chains a program, without crushing the precedent, n to specify the beginning of it
COMMON V$, W$... to preserve the variables of a chained program. The instruction must be on the first line of each program concerned
LIBRARY GEM, "A:\GEM\GEM.LIB" charges library GEM
BSAVE "Name" saves the complete screen (bit by bit) on floppy
BSAVE "Name", Addr, n save the number of bytes starting from the Address
BLOAD "Name" loads a file on the screen (eg: image in BITMAP)
BLOAD "Name", Addr loads a file in memory with the Addr indicated
5.3 Sequential files ( → .fr)
OPEN "O", channel, "Name" creates and opens a file with the writing (crushes it if there already
exists!) and allots to him a channel from 1 to 16
PRINT #channel, A$, B$ writes data on the specified channel
WRITE #channel, A$, "Aum" allows the writing with quotation marks and commas
CLOSE channel writes the data on the diskette and closes the channel
OPEN "A", 5, "Nom.Ext" open an existing file to add data to it
OPEN "I", 16, "Name" opens a file only with the purpose of reading
INPUT #16, V$, W$ reads one or more data (separated by commas)
LINE INPUT #16, V$ load a text containing commas
A$=INPUT$(n, channel) reads n characters on the specified channel
?EOF(channel) returns -1 when the specified file was completely read
?LOF(channel) returns the number of bytes of the file open on the specified channel, including the byte of end of file
Other sequential files ( → .fr)
OPEN "K", channel sends commands to the processor-keyboard (keyboard)
OPEN "P", channel printer (printer)
OPEN "V", channel Modem
OPEN "M", channel MIDI port
OPEN "C", channel screen (console).
CMD canal redirects output-instructions to an open sequential file. Can be useful during a program development:
OPEN "O", 1, "liste.txt" CMD 1 PRINT "My program in ascii" ' normally to the screen LLIST ' but also to the printer CLOSE
5.4 Random files ( → .fr)
OPEN "R", channel, "FILENAME", l open a random file of total field of size L
FIELD channel, long1 AS V$, long2 AS W$ determine the field (the length) of each Variable-buffer. A field can be not allotted.
PUT channel, n write in recording n channel the data of FIELD
GET channel, n reads recording n and sends it on the FIELD
GET channel, 0 ... gives the n° file following that which was read
SEEK channel, n, mode move the pointer of n recordings (mode=0: starting from the beginning of the file; 1: displacement starting from the current recording; 2: starting from the end)
LSET V$="Ugh" formate the string for the variable-plug by the left (excess on the right is
cut off, the default is filled)
RSET W$= B$ formates B$ for W$ in the same way
?LOF(channel) gives the number of recordings of the relative file
?LOC(channel) returns the pointer of the last recording read or written
CLOSED channel writes the changes on the disc
Other random files
OPEN "U", channel, "FILENAME" ("U" for User) opens (for reading or wrinting) a random file with no fixed lengths of field ; PUT, GET and SEEK work
OPEN "F", channel, "C:\atari\*.*", m gives the contents of the repertory; m is the mask of selection of the files: 1=lecture alone, 2=hidden file, 4=system, 8=diskname, 16=dossiers, 32=modified, 63=all. Here an example of use (note that the first 14 bytes of the FIELDS are not used):
OPEN "F", 3, "C:\*.*", 63 # one open on the channel 3 FIELD 3, 14, 2 AS Z$, 4, 1 AS Mask$, 1 AS Type$, 4, 4 AS L$, 14 AS Nom$ FOR I=0 TO LOF(1)-1 GET 3, I: PRINT CVI(Z$), ASC(Mask$), ASC(Type$), CVIL(L$), Nom$ NEXT I
GEMDOS(R, 47) R returns the Disk Transfert Address (OPEN "F")
GEMDOS(, 26, L Buffer) write a DTA data (44 octets):
byte 21: file attribute
bytes 22-23: file creation time
bytes 24-25: file creation date
bytes 26-29: file length
bytes 30-43: file name and extension
5.5 Disks ( → .fr)
All that follows is floppy-oriented, but you could adapt it to harddisks.
GEMDOS(R, 54, L Buffer, Lect) R returns 4 long integers on the disk at Buffer address:
1°: number of data clusters
2°: number of free clusters
3°: disk: 0= default, 1=A:, 2=B:, 3=C:, nbr of byte per sector
4°: number of sectors per cluster
BIOS(R, 7, Lect) R returns an address of 13 short integers:
1°: byte amount per secteur (512)
2°: sector amount per cluster (2)
3°: byte amount per cluster (1024)
4°: sector amount for directory
5°: sector number of the File Allocation Table
6°: sector number of the second FAT
7°: 1° data cluster number
8°: data cluster amount
9°: empty or flags?
10°: face amount (1 or 2)
11°: track amount per side (40 or 80)
12°: sector amount per track (9 or 10)
13°: see Inter for next XBIOS 10
BIOS(R, 4, F, L Addr, N, Start, Disk) reads or writes N sectors at Address from Start
F =0 or 2 to read, 1 or 3 to write, 2 and 3 ignore disk changes
XBIOS(R, 8, L Addr, 0, 0, Disk, Sect, Track, Side, N) reads N sectors
Addr=MEMORY(512) for 1 sector
Disk = 0, 1, 2, for A:, B:, C:,
Sect from 1 to 9 or 10 following formating
Track from 0 to 79
Side 0 or 1 for doub1e sided floppies, 0 only for one-sided floppies
XBIOS(R, 9, L Addr, 0, 0, Disk, Sect, Track, Side, N) writes N sectors
XBIOS(R, 19, L Addr, 0, 0, Disk, Sect, Track, Side, N) verifies N sectors
XBIOS(R, 10, L Addr, 0, 0, Disk, Sect, Track, Side, Inter, L 987654321, Oct) formats a track, same as above, excepted:
Addr= MEMORY(9216) or MEMORY(10240) for 9 or 10 sectors per side
Sect 9 or 10
Inter 1 (123456789 order for sectors) or 2 (135792468 order)
Byte written byte value, often $E5 (avoid $F0 and $F5)
R returns 0 or an error number (see then Addr)
XBIOS(R, 18, L Addr, L Serie, Type, Exec) writes a boot-sector
Serie is a 24 bits serial number
Type : 0: 1 side of 40 tracks - 1: 2 sides of 40 pistes - 2: 1 side of 8O tracks - 3: 2 sides of 80 tracks
Exec : 0: non-executable boot-sector, 1; executab1e
-1 leaves unchanged parameter for each sector
6. Graphics ( → .fr)
New unit: pixel (picture element), a dot on the screen. The ST (TT and Falcon have more screen dimensions), there are 640*400 pixe1s in high resolution, 640*200 in medium and 320*200 in low resolution. (0, 0) is the upper-left pixel: the first number is the distance from the left and the second one the distance form the top (negative height). You always shoud set off the mouse (MOUSEOFF) before any graphical display.
CLIP x, y TO u, v ou CLIP x, y, l, h nothing can be displayed outside this rectangle
CLIP alone to cancel a previous one
CLIP 0, 0, 320, 200 sets the exact limits to low resolution, very safe, not to invade and spoil the RAM (screen is a part of the common RAM: a bit 'set' is black)
There are four superposition modes of graphical display:
MODE=1 replace (black and white cover a former drawing; by default)
MODE=2 transparent (white does not cover, as OR)
MODE=3 exclusif (black on black gives white; as XOR)
MODE=4 transparent inverse
WVBL waits for the new screen wave, for a more stable display
NDC x, y, l, h towards virtual coordonnates. Every display will be reduced to a rectangle defined by the
coordinate. 0, 0 is the left bottom of this rectagle and 32767, 32767 the right top of the rectangle
NDC back to the normal mode.
6.1 Mouse and joystick ( → .fr)
MOUSEON sets the mouse cursor (before displaying a dialog box)
MOUSEOFF hides the mouse cursor (before graphic display)
Inside a program, a MOUSEOFF is enough to to cancel three MOUSEON, but 4 MOUSEON are necessary after 3 MOUSEOFF
MOUSEBUT contains the state of the mouse, 0: no button; 1: left button; 2: right button; 3: both buttons
WHILE MOUSEBUT <2: WEND ' awaits right-button click
MOUSEX horizontal position of the mouse in pixels
MOUSEY vertical (negative) position of the mouse in pixels
JOYSTICK(n) returns the state of JOYSTICK (N= 0 or 1):
10 Addr= MEMORY(CHR$(20)): XBIOS(, 25, 0, L AD) ' XBIOS 25 allows to potentiate 20 WHILE -1: PRINT BIN$(JOYSTICK(0)): WEND ' the button of shooting 30 Addr= MEMORY(CHR$(8)): XBIOS(, 25, 0, L AD) ' [Ctrl]-[C] to stop
6.2 Alert boxes and File selector ( → .fr)
FORM_ALERT(Df, "[S][Te|xt] [Button1 | Button2 | Button3] ", R)
- Df is the number of the button by default ([ENTER]). 0 if none
- S tells the symbol to use - 0: none ; 1: "!" ; 2: "?" ; 3: "STOP"
- The text can be written in 5 lines up to 31 characters (spaces included), the separator of line being the character '|'. The quotation marks are written via CHR$(34). To display hooks: [ to open, ]] to close. To display a vertical bar, write it double: ||
- Three button choices are definable, separate also by one | ; only a line of 31 characters, or 2 or 3 up to 10 characters
- R (optional) returns the sequence number of the selected choice
FILESELECT (Chemin$, Nom$, R) calls a selection-box. R returns 0 for [cancel] or 1 for [Confirm]
Addr=MEMORY(13200): BITBLT 157, 54, 328, 312 TO Addr ' saves the part of screen in high resolution MOUSEON Path$="A:\*.*" ' no literal string, which is dedicated to change! FILESELECT (Path$, File$, R) MOUSEOFF BITBLT Addr TO 157, 54, 328, 312 ' reinstalls the Addr block FRE(Addr) ' frees memory PRINT File$, R
6.3 Graphical text ( → .fr)
TEXT allows specialized style: height, direction and color, with a more precise co-ordinate than PRINT@(l, c) :
TEXT x, y, V$ displays a text at the point x, y (expressed in pixels)
TEXT x, y, "Texte", L, m, c L defines the length reserved in the text
m=1 and c=0: the words remain compact
m=0 and c=1, all the characters are spaced
The three functions which follow are valid until a new specification (to restore before finishing a program)
TEXT STYLE=n sets a style for a TEXT (to cancel: TEXT STYLE=0 )
1: bold - 2: grayed - 4: italic - 8: underlined - 16: outlined
The styles are combined by addition of the parameters: 13 gives an underlined, ialic and bold text (8+4+1)
TEXT HEIGHT=n sets the height in pixel of the displayed TEXT
1 to 3: completely unreadable text
4: just readable and well proportioned
6: same width as the standard, middle height
9: pretty intermediary
12: same height as the standard, double width
13: standard body (back to the normal)
26: double width, double height: maximal size
The intermediate heights are possible, but not all pretty. On medium and low resolutions, the standard body is 6
TEXT ROTATION= 900 from bottom to top
TEXT ROTATION= 1800 upside down
TEXT ROTATION= 2700 from top to bottom
TEXT ROTATION= 0 back to the normal (by default)
6.4 Dots and lines ( → .fr)
DRAW x, y displays a pixel at the definite point ((0, 0) is upper-left)
DRAW x, y TO u, v [TO...] draws a line from x, y to u, v [to...]
DRAW TO x, y connects the last point drawn to the point x, y, especially used in loop
CLIP 0, 0, 640, 400 DRAW 200, 50 TO 200, 350: DRAW 100, 100 TO 400, 100 FOR I!=2 TO .01 STEP -.01 DRAW TO 100*(2+I!), 100*(1-LOG(10, I!)) ' do test DRAW without TO NEXT
LINE WIDTH=n (odd, up to 39) sets the line width
LINE STYLE=n sets the line style:
0 white (MODE=1) or invisible (MODE=3)
1 **************** full
2 ************ long dash
3 ** ** dotted
4 ******** ** dash and dot
5 ******** discontinuous
6 ***** ** * composite
7 user-defined with LINE PATTERN
LINE PATTERN=n where n is an short integer (16 bits), expressed into binary %0110110100101111 (one digit is one pixel), or into hexadecimal: $6D2F, where each character represents 4 pixels: 0=0000, 1=0001, 2=0010, 3=0011, 4=0100, 5=0101, 6=0110, 7=0111, 8=1000, 9=1001, A=1010, B=1011, C=1100, D=1101, E=1110, F=1111
6.5 Geometrical figures ( → .fr)
BOX x, y TO U, V defines a rectangle according to two opposite corners
BOX x, y, w, h defines a rectangle a according to the left higher top and dimensions
RBOX x, y TO u, v defines a rectangle with rounded corners
CIRCLE x, y, r defines a circle of centre (x, y) and r
CIRCLE x, y, r, D, A defines an arc of circle whose D is the starting angle and A is the angle of arrival (in 1/10 of degrees)
ELLIPSE x, y, r1, r2 defines an ellipse: r1= horizontal radius, r2= vertical radius
ELLIPSE x, y, r1, r2, D, A defines an arc of ellipse (see CIRCLE)
POLYGON T(0, 2*n+2) defines a polygon up to 63 sides. A dodecagon needs an array with 1*26 elements: 2*sides +2 (for the repeated coordonate)
CLIP 0, 0, 640, 400: CLS: DIM P%(0, 26) MOUSEON FOR I=0 TO 11 WHILE MOUSEBUT=0: WEND ' waits for a mousebutton click P%(0, I*2)= MOUSEX: P%(0, I*2+1)= MOUSEY WHILE MOUSEBUT >< 0: WEND ' awaits a relaxing a mouse button NEXT P%(0, 24)=P%(0, 0): P%(0, 25)=P%(0, 1) ' repeats the 1st coordonates MOUSEOFF: POLYGON P%(0, 26) ' call of the polygon
6.6 Fillings ( → .fr)
PBOX, PRBOX, PCIRCLE, PELLIPSE, PPOLYGON accept a filling.
OUTLINE OFF omits the border of the filled figures
OUTLINE ON cancels the former instruction
0, 1 white|
1, 1 black (default)
2, 1 to 2, 24 24 built-in drawings, see below
3, 1 to 3, 12 24 built-in lines, see below
4, 1 ATARI logo, or to define with FILL PATTERN
Note: FILL STYLE 3, 12 should be 3, 10 + 3, 11, but is NOT in the 1.XX TOSes
FILL X, Y, -1 fills a surface containing the point (x, y). Surface must be delimited
CLS: CLIP 0, 0, 640, 400 ' highly recommanded! BOX 100, 100, 440, 200 FILL STYLE= 2, 20: PRBOX 150, 150, 340, 100 FILL STYLE= 2, 13: FILL 120, 120, -1
FILL PATTERN= Array%(0) works like LINE PATTERN, but with 16 Short integers in one Array% of 16 elements
To determine the numbers to enter in the array, draw a "checkerwork" of 16*16. Each line will be a binary number, ('1' for black, '0' for white) converted into hexadecimal (see LINE PATTERN in 6.4) is an element of the array. Do use LOW if the number exceeds $7FFF: LOW($FFFF) returns -1, the right way to draw a full line.
6.7 BITBLT, Bit-Block-Transfer ( → .fr)
BITBLT x, y, l, h TO u, v, m, n copies a part of the screen defined by x, y, w, h to u, v
BITBLT x, y, w, h TO Addr saves in memory a part of the screen
BITBLT Addr TO x, y, l, h, mode displays the part of screen memorized, mode is the mode of which it is printed (3 covers: mode by default)
The 15 other modes are, for S=Source and C=Cible:
1= S AND C
2= S AND (NOT C)
4= (NOT S) AND C
6= S XOR C|
7= S OR C
8= NOT(S OR C)
9= NOT(S XOR C)
10= NOT C
11= S OR (NOT C)|
12= NOT S
13= (NOT S) OR C
14= NOT (S OR C)
CLS: PRINT @(0, 0); "*" Addr=MEMORY(28) BITBLT 0, 1, 7, 11 TO Addr REPEAT BITBLT Addr TO 10+RND(610), 10+RND(365), 10, 11, 7 ' or 3... UNTIL MOUSEBUT=2
Determination of the memory to be reserved: The BITBLT includes in memory a short integer (whose values are: 2 for the high resolution, 4 for the middle one and 8 for the low one), a short integer the width of the image, a third one for its height. For the high resolution, there is always an even number of bytes for a line: for an image of X pixels-width and Y pixels-height, you will need 6 + ((X-1)\16 +1) *2 *Y bytes.
6.8 Sprites ( → .fr)
A sprite is a small drawing very easy to handle (the bee, the arrow...). There are in Omikron small and large sprites for each resolution. It is necessary to reserve memory for the hidden part of the screen and the drawing itself. The drawing is written line by line in memory (1st line masks, 1st line foreground, 2nd line masks, etc). The mask is used to emphasize the foreground and to avoid to show the sprite as in MODE=3 (XOR, black on black gives white).
DEF SPRITE n, dim, Backgr
sets a sprite (1 to 6), Backgr is the address in memory 'caching' the part of the screen hidden by the sprite, and dim is the dimension:
low: dim= 1 (small: 16 bytes) or 2 (large: 64 bytes)
average: dim= 3 (small: 32 bytes) or 4 (large: 128 bytes)
high: dim= 5 (small: 64 bytes) or 6 (large: 256 bytes)
SPRITE n, x, y, Dess, Cm, Cd
displays sprite n, with the coordonates x, y whose drawing was registered beforehand with Dess address, Cm and Cd are the colors of the mask and the foreground.
DEF SPRITE n, 0 erases the sprite (useful in the course of program)
6.9 Colours ( → .fr, much more complete, I apologize)
Addr= MEMORY(32256) : SCREEN 1, Addr, 4 allows the passage of the low resolution (320*200) on middle resolution (640*200). Don't forget 32256 bytes in memory for Addr.
LINE COLOR=n to define the 'Hardware' colour of the line
FILL COLOR=n to define the 'Hardware' colour of the filling
TEXT COLOR=n to define the 'Hardware' colour of the text
«Hardware» colors are those of Control Panel accessory CONTROL.ACC (ST):
777 white - 000 black - 700 red - 070 green - 007 blue - 400 marine - 420 brown - 040 meadow - 555 light gray - 222 dark gray - 077 cyan - 044 steel - 707 magenta - 404 purple - 440 sand - 770 yellow
From the STE (TOS 1.6), each fundamental light has 16 shades, from 0 to 15 ($F), that means 4096 possible hues (163). In order to keep the compatibility with the ST colours, the additional grades (half intensities) are indicated by adding the number 8: 0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7 and 15, or binary: %0000, %1000, %0001, %1001, %0010, %1010, %0011, %1011... where bit 3 (the first left) is set for the halftones. See XCONTROL.ACC control panel:
FFF white - 000 black - F00 red - 0F0 green - 00F blue - 800 marine - 840 brown - 080 meadow - AAA light gray - 444 dark gray - 0FF cyan - 088 steel - F0F magenta - 808 purple - FF0 yellow - 880 sand
«VDI» order of the colors defined by PALETTE does not correspond to the «hardware» one. In low resolution:
PALETTE 0, 2, 3, 6, 4, 7, 5, 8, 9, 10, 11, 14, 12, 15, 13, 1
PALETTE 0, 2, 3, 1
For instance, to set other colors than traditional ones of the middle resolution (white, red, green and black):
PALETTE $777, $707, $077, $555 gives white, magenta, cyan and anthracite.
PRINT POINT(x, y) tests and returns the n° of color «VDI» of the point x, y
PRINT CHR$(27); "b"; CHR$(n) sets a «VDI» color for the foreground (n goes from 0 to 15)
PRINT CHR$(27); "c"; CHR$(n) sets a «VDI» color for the background
PALETTE $a, $b, $c, $d, $eE... sets a color. Each parameter is composed of three digits, each one from 0 to 7. The first proportions the red, the second the green and the third blue. Note: STE (TOS 1.6) has 16 nuances of colors, 0 to 15. The half-intensities are indicated by the addition of 8: 0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7 and 15. In binary: %0000, %1000, %0001, %1001, %0010, %1010, %0011, %1011... where bit 3 (the first on the left) gives the half-tones.
7. System ( → .fr)
7.1 Memory ( → .fr)
CLEAR m reserves a global amount of m bytes for MEMORY (64 Kb by default)
CLEAR m, n reserves also n bytes for the stack, meter of loops, procedure calls, aso
Addr=MEMORY(n) reserves n bytes, Addr returns the address of the beginning
Addr=MEMORY("Monty Python") puts a string at a precise address
FRE(Addr) frees the amount of bytes formerly reserved
FRE("C:") returns the free place on a disk
FRE(0) returns the free place in memory
FRE("") does first a "garbage collection": frees memory used for the string processing:
PRINT FRE(0) A$="1": B$="=100" FOR I=1 TO 99: A$=A$+"+1": NEXT PRINT A$;B$ PRINT FRE(0) ' 10710 bytes are used PRINT FRE("") ' 10594 are now freed: the final string uses 216 bytes.
Byte=PEEK(Addr) reads a byte at the given address
Word=WPEEK(Addr) reads a short integer (two bytes) at the given address
Long=LPEEK(Addr) reads a long integer (four bytes) at the given address
POKE Addr, Byte writes a byte at the given address
WPOKE Addr, Word writes a short integer (two bytes) at the given address
LPOKE Addr, Long writes a long integer (four bytes) at the given address
MEMORY_MOVE n, Dep TO Targ copies n bytes form Dep address to Targ address (even addresses)
MEMORY_MOVEB n, Dep TO Targ makes it possible to use odd addresses (slower)
MEMORY_BLOCK xx, n, Addr reserves n bytes with variable-Addresses (xx from 00 to 99, no variable) which will be saved within the program. It's then possible to BLOAD a file at the address. Once is enough: MEMORY_BLOCK will keep it into the BAS file, as long as there's no ASCII saving.
VARPTR(V) returns the address of the indicated variable
SEGPTR gives the address of the SEGment PoinTR array, which contains pointers (addresses):
+0 byte n° of lines
+4 beginning of the program
+8 pointers of variables
+24 file buffer
+36 executed order
+40 garbage top
+44 garbage bottom
+48 garbage high
+52 value max of the stack
+56 bottoms of the stack
+60 the largest address of the memory
?VARPTR(A$) returns the relative address of the string, starting from address SEGPTR+28:
Interruptions ( → .fr)
IPL n sets the interrupt level of the system, from 0 to 7:
IPL 3 standard level
IPL 3+(1 SHL 31) sets off [Ctrl]-[C]
IPL 4 cold screen
IPL 6 ...nor keyboard, WAIT or TIMER (no more control, but faster): don't forget to set it back to IPL 3 when the task is over.
7.2 Binary routines ( → .fr)
Machine subroutines are useful for speed or special programming methods.
INLINE "A009" enters a line of binary code in hexadecimal. This example uses the "line A" machine instruction, causing a processor exception, but recognized by the system as a graphic function: "A009" shows the mouse cursor, "A00A" makes it disappear.
DEF USR=Addr sets the address of a binary routine
Ret= USR(Val) calls the function. The Val ue is placed onto the register D0 (4 bytes); when the routine ends, the D0 value is returned to Ret .
Ad= MEMORY(6)' 6 bytes reservation for the routine LPOKE Ad, $06000009' add.b #9, d0 WPOKE Ad+4, $4E75' rts DEF USR=Addr' sets the memory address of the routine PRINT USR(16)' calls the routine with a 16-value in d0; 25 will be printed
CALL Addr(L param1, param2...) calls a binary routine, loaded at an addr ess with parameters. The routine will find them from 4(A7) on. 4(A7) means the address indicated by the value of the stack (A7) + 4.
It's rather long (8:) to build by hand the machine code instructions. Therefore, you should have an 68000 assembler. The resulting binary file can be loaded with BASIC BLOAD "File", Addr (see BLOAD). It is also possible to include in the binary routine with MEMORY_BLOCK 00, L, Addr (see previous section). Warning:
- you have to assemble your code in an other way than for executables, whose first 512 bytes are used by the system.
- the routine must end with rts (return from subroutine);
- Omikron BASIC works in supervisor mode: the routine must not attempt to turn to it.
7.3 Time ( → .fr)
TIME$ contains the machine time
TIME$="15:58:12" sets the time to the machine
TIMER returns the number of 1/200 seconds since the machine is on, quite the same as LPEEK($4BA)
WAIT n waits n seconds, precision: 1/200
DATE$ returns the machine known date
DATE$="" sets the date following the mode:
MODE"USA" months/days/years: "02/14/2007" (by default)
MODE"GB" days/months/years: "14/02/2007" (MODE"F" )
MODE"D" days.months.years: "14.02.2007"
BIOS(R, 6) gives the delay (milliseconds) between two clock-top
GEMDOS(R, 42) returns the date:
Bits 15-9: years if 1980 is added (2007=27)
Bits 8-5: months (1 à 12)
Bit 4-0: days (1 à 31)
GEMDOS(, 43, Date) Date is a short integer as described in GEMDOS 42
GEMDOS(R, 44) returns the hour:
Bit 15-11: hours ; Bit 10-5: minutes;
Bit: 4-0 double-seconds (0=0s, 1=2s, 2=4s...)
GEMDOS(, 45, Heure) Heure is a short integer as described in GEMDOS 44
XBIOS(, 22, L Addr) sets the time. Addr must contain two short integers: the date and the hour
XBIOS(R, 23) returns hour and date at the XBIOS 22 format
GEMDOS 42, 43, 44 and 45 and XBIOS 22 and 23 are not linked
Look out: GEMDOS 43 accepts the date 31/2, but not 32/1
7.4 Error processing ( → .fr)
ERR last error number ; to use with IF ERR=n THEN ...
ERR$ last error message
ERL last error line, or -1 in direct mode
LIST ERL lists the program line error
ON ERROR GOTO sends to an error processing routine
RESUME leaves an error processing routine and tries again the problematic command
RESUME NEXT goes to the instruction following the error
RESUME Lbl goes to the line containing the label -Lbl
ERROR n provokes the error n , to work out an error processing routine
The loop-meter is safe after a RESUME: you need an EXIT to reset it at zero. If ON ERROR GOTO is off with CLEAR or is interrupted by [Ctrl]-[C], the error message is shown.
TRON (TRace ON) sets the TRACE mode: shows the line-number and every executed instruction
TROFF gives up the TRACE mode (is there a meter for the number of TRON and TROFF?)
ON TRON GOSUB is TRON is set, goes to a routine at every instruction
Interpretor's errors ( → .fr)
- Structure too long a procedure or a loop is more than 64 Ko
- Syntax error
- RETURN without GOSUB subroutines should be placed after an END
- Out of DATA more DATA needed for READ
- Illegal function call
- Overflow the numerical variables are limited
- Out of memory GEMDOS or the stack need more memory: CLEAR morememory
- Undefined Statement GOTO or GOSUB send to nowhere
- Subscript out of range arrays are limited
- Duplicate definition several procedures or functions have the same name
- Division by zero
- Illegal direct a function or procedure is met without a call
- Type mismatch don't mix strings and numbers
- RETURN without function your program meets a RETURN out of a function , procedure of subroutine
- String too long a string longer than 32767 characters?
- Formula too complex the stack must remember inclusion you wrote. Too many here.
- Can't continue CONT after a STOP doesn't stand a change in your program
- Undefined user function a name without function, token or procedure
- No RESUME an error processing routine misses a RESUME
- RESUME without error RESUME is met out of an error processing routine
- Use EXIT often when IF/THEN misses an ENDIF in a loop
- Missing operand nothing after an operator or a comma
- Line buffer overflow too long line
- REPEAT without UNTIL
- UNTIL without REPEAT
- FOR without NEXT
- NEXT without FOR
- IF without THEN or EXIT an IF misses a THEN or an ENDIF
- WHILE without END
- END without WHILE
THEN, ELSE or ENDIF without IF or THEN you should structure your imbricated loops:
REPEAT FOR I=-5 TO 5 IF I=0 THEN PRINT I; " is greater than zero" ELSE PRINT I; " is not greater than zero" ENDIF NEXT I PRINT "A mouse-click to stop" UNTIL MOUSEBUT=0
- ERROR 32 [Enter] gives the Omikron copyright
- RESET Omikron didn't die after a RESET. It's normal, but don't abuse.
- Bus error a POKE in a forbidden memory address
- Address error addressing error (a Word at an odd address)
- Unknow opcode unknow instruction for the processor
- Out of memory. Save or re-CLEAR immediatly try to save!
- EXIT without structure from which LOOP to go out?
- Use EXIT TO in functions from several depth loops
- Matrix not regular some matrices must be square-ones
- Bad file number you can't open more than 16 files
- Fie1d overflow DATA doesn't fit in a FIELD
- Internal error fatal error - cold RESET
- Bad file number only 16 file-channels
- File not found
- Bad file mode illegal instruction on a file
- File already open
- File not open
- TOS Error n see next section
- File already exists
- File type mismatch
- Bad disk
- Disk full
- Input past end tries to read after the End Of File. LOF(channel) can help
- Bad record number
- Bad file name forbidden character in a filename
- Path not found
- Direct statement in file a file to load does not have linenumbers: use 'Load Block' of 'Files' menu
- Too many file in a directory?
- Write error
- Read error
- Disk-write protected
System errors ( → .fr)
7.5 System programming ( → .fr)
BIOS (BASIC Input/Output System), XBIOS (eXtended BIOS, and GEMDOS (Disk Operating System) functions are included in this page, insofar as they are not exploited in the traditional instructions.
R is always a Return-value, which is not always useful (do nevertheless preserve the comma). It can contain an address, a TOS error, a device number or a file handle.
It is necessary to reserve memory before calling the functions processing a certain amount of bytes, by the intermediary of an address. Functions PEEK make it possible to read them. On the contrary, functions POKE makes it possible to write data on an address reserved in memory before calling a function. The most practical manner to write a string in memory and to know its address is:
the most traditional is:
where LPEEK(SEGPTR+28) is a PoinTeR towards the place of the strings in memory and LPEEK(VARPTR(V$)) the span to the pointer for the V$ chain. You can PEEK(Addr), PEEK (addr+1) aso. the characters.
These functions are close to the language of 68000 procesor: the parameters must be short integers and the address of a buffer must break up into HIGH(Addr) and LOW(Addr) . Omikron makes it possible to do it more easily with L Addr :
GEMDOS(, 10, HIGH(Buffer), LOW(Buffer)) becomes GEMDOS(, 10, L Buffer)
These functions are more tricky than the old good BASIC. For instance, XBIOS 0 (for the mouse) requires additional information, and largely exceeds the object of this page. Below, GEMDOS 10 will make it possible to be convinced of the comfort of the traditional BASIC. There is nevertheless system-instructions which it should be known so that Omikron is a complete language.
GEMDOS(R, 48) value R divided by 256 returns the version of the GEMDOS.
GEMDOS(R, 10, L Buffer) allows the input of a line. The first two bytes contains the maximum and effective length chain, finished by CHR$(13):
Saisie(12, Ch$): PRINT Ch$: END DEF PROC (N, R T$) ' R to turn over a T$ String=CHR$(N) CHR$(0)*(N+2) ' 1st two bytes and bed of null bytes Addr= LPEEK(SEGPTR 28)+ LPEEK (VARPTR(T$) ' addresses string GEMDOS (, 10, L Addr) ' awaits n characters maximum or [Enter] T$=MID$(T$, 3, ASC(MID$(T$, 2))) ' returns the text starting from the 3rd character RETURN ' INPUT$ or INPUT (USING) is quite more practical!
7.6 Some useful precautions ( → .fr)
- Reserve sufficient memory (with CLEAR n ) for the SCREEN, BITBLT, SPRITE... and for the GEMDOS which must assume all that
- Don't put MOUSEON, TRON, OUTLINE ON in a loop without ~OFF: that saturates the stack.
- EXIT (TO) is better than GOTO to leave a loop: the meter of the loop (in the stack) is given to zero.
- Limit the screen by a CLIP to preserve the active memory, which could be invaded by a FILL , which brings: INTERNAL ERROR #023000ED02 51 and a cold RESET (!).
- Set the MOUSEON before using FORM_ALERT and FILESELECT .
- Commands RUN - CLEAR - NEW erases the contents of the variables and cancels the instruction DEG , but have no effect on STYLE - COLOR - TEXT - LINE - MODE - CLIP - TRON - MOUSEON - USING
7.7 Omikron BASIC 3.01 bugs and weaknesses ( → .fr)
- By default, a *.BAS-file searchs other files through the path of the OM-BASIC.PRG: it is absolutely necessary to specify an address. There is no problem after compilation: ST takes care and does it very well.
- The option "Cancel" of selection box of Omikron super-editor does not work! An actual cancel is to erase the filename before the second confirmation by [Enter] .
- Be sure the floppy is in 'write' position before saving a *.BAS-program in the Super-Editor: the program would freeze by the following attempt. The only way is a warm RESET and generally doesn't lose the program.
- The RND(2) function shows a light drift towards zero (50, 1%-49.9%)
- The error message 'USE EXIT' appears trying to run a file with an incomplete IF/THEN sequence in a loop.
- POLYGON functions looks sometimes messy after compilation.
- ø, ä, ó... cannot be obtained directly with the keyboard. CHR$(131)-CHR$(136) aso should be used... No problem after compilation and CUTLIB. One can use the function keys: KEY 1=CHR$(136) for example.