forge Documentation

statements

Statements

Complete reference for all FORGE statements, organized by category.

In the following descriptions, statement usage is presented and the abbreviation is given after a /.

Console Print and Input Statements

GET var / GE.

Reads Key From Keyboard

Waits for a key press and writes the key value to var, which can be a variable name or an array position (like "array(123)").

Note: Some keys on the Atari -- the console keys START, SELECT, and OPTION; modifiers SHIFT and CONTROL; and the HELP, BREAK, and RESET keys -- are not handled in the same way as the main keyboard, and cannot be read by GET.

Hints:

  • The status of all three console keys may be read via the GTIA CONSOL register, PEEK(53279).
  • Whether the HELP key is pressed can be detected via the POKEY KBCODE register, PEEK(53769).
  • Whether either SHIFT key is pressed can be detected via the POKEY SKCTL register, PEEK(53775).

Example:

GET K
? "You pressed: "; K

INPUT var / I.

INPUT "prompt"; var

INPUT "prompt", var

INPUT ; var

Input Variable Or String

Reads from keyboard/screen and stores the value in var.

A "?" sign is printed to the screen before input, or the "prompt" if given. Also, if there is a comma after the prompt, spaces are printed to align to a column multiple of 10 (similar to how a comma works in PRINT). In the case you don't want any prompt, you can use a semicolon alone.

If the value can't be read because input errors, the error is stored in ERR(). Valid errors are 128 if BREAK key is pressed and 136 if CONTROL-3 is pressed.

In case of a numeric variable, if the value can't be converted to a number, the value 18 is stored in ERR().

Example:

INPUT "Enter your name: "; NAME$
INPUT "Enter age: ", AGE

See the Device Input and Output Statements section for the INPUT # usage.

POSITION column, row / POS.

Moves The Screen Cursor

Moves the screen cursor position to the given column and row, so the next PRINT statement outputs at that position.

Rows and columns are numerated from 0.

Example:

POSITION 10, 5
PRINT "At position 10,5"

PRINT expr, ... / ?

PRINT expr TAB(expr) ...

PRINT RTAB(expr) ...

PRINT COLOR(expr) ...

PRINT expr ; ...

Print Strings And Numbers

Outputs strings and numbers to the screen or other output device.

Each expr can be a constant string, a string variable or any complex expression, with commas or semicolons between each expression.

If the first expression is a device I/O channel (e.g., PRINT #1,"HELLO") the output will be sent to that device. In GRAPHICS modes other than 0 (e.g., large text GRAPHICS 2, multicolor text GRAPHICS 12, or even bitmapped graphics modes), use #6 to write to that part of the screen.

After writing the last expression, the cursor advanced to a new line, except if the statement ends in a comma, semicolon or TAB, where the cursor stays in the last position.

If there is a comma before any expression, spaces are printed to advance the printing column to the next multiple of 10, allowing easy printing of tabulated data.

The COLOR function alters the color the text that follows, until the end of the statement, depending on the graphics mode. This is abbreviated C.. Use 0 or 128 in graphics 0, for normal or inverse video. Use 0, 32, 128 or 160 in graphics mode 1 and 2 for the four available text colors.

Example:

' In GRAPHICS 0:
? "NORMAL"; COLOR(128) "INVERSE"

' In GRAPHICS 2:
S = 1234
? #6, "SCORE: "; COLOR(32) S

The TAB function advances the position to a column multiple of the argument, so that TAB(10) is the same as using a comma to separate arguments. This is abbreviated T..

The RTAB function, abbreviated RT., advances the position so that the next argument to print ends just before a column multiple of the argument, right aligning the printing of the data. This function must be immediately followed by a variable or a string to align.

Note that ,, TAB and RTAB always print at least one space, and that to separate TAB or RTAB and the previous and next arguments you can use a ; or simply a space.

Example:

FOR i=0 TO 10
  n = i*(9-2*i)*134
  ? TAB(8) "Val:" RTAB(20) n
NEXT

Advanced Notes:

  • To implement the spacing on ,, TAB and RTAB, FORGE uses the current column in the OS, so that POSITION and printing to a graphics screen will work ok, unlike Atari BASIC; but when printing to a file or other devices the number of spaces will not be correct. Avoid using the functions to print to any device except the screen.
  • The COLOR function does an exclusive or of the given value with the value of each character in the original string before printing.
  • When writing abbreviated code, you can omit the semicolon in almost all places, and just join the values together. Avoid doing this in common code for better readability.

PUT num / PU.

Writes A Character To Screen

Outputs one character to the screen, given by it's ATASCII code.

Example:

PUT 65  ' Prints "A"

CLS

Clears The Screen

Clears the text screen. This is the same as PUT 125. For clearing the graphics screen, you can use CLS #6.

Example:

CLS      ' Clear text screen
CLS #6   ' Clear graphics screen

Control Statements

DO ... LOOP / L.

Endless Loops

Starts and ends an endless repetition. When reaching the LOOP statement the program begins again, executing from the DO statement.

The only way to terminate the loop is via an EXIT statement.

Example:

DO
  ? "Looping..."
  IF KEY() THEN EXIT
LOOP

EXEC name num1, ... / EXE. / @

Calls A Subroutine

Calls the subroutine name, with the optional parameters num1 and so on, separated by commas.

Note that you must use the same number of parameters in the FUNC definition, before or after the call.

Instead of EXEC you can simply use a @ in front of the function name. (i.e., these are equivalent: EXEC greet and @greet.)

Example:

FUNC greet name
  ? "Hello, "; name
ENDFUNC

EXEC greet "World"
@greet "FORGE"

EXIT / EX.

Exits From Loop Or Procedure

Exits current loop or subroutine by jumping to the end.

In case of loops, the program continues after the last statement of the loop. In case of FUNC, the program returns to the calling EXEC.

Example:

DO
  IF condition THEN EXIT
LOOP

FOR var=value TO end [STEP step] / F. T. S.

NEXT var / N.

Loop Over Values Of A Variable

FOR loop allows performing a loop a specified number of times while keeping a counting variable.

First assigns the value to var, and starts iterations. var can be any variable name or a word array position (like "array(2)").

In each iteration, the command first compares the value of var with end, if the value is past the end it terminates the loop.

At the end of the loop, var is incremented by step (or 1 if STEP is omitted) and the loops repeats.

An EXIT statement also terminates the loop and skips to the end.

Note that if step is positive, the iteration ends when the value of var is bigger than end, but if step is negative, the iteration ends if value of var is less than end.

Also, end and step are evaluated only once at beginning of the loop; that value is stored and used for all loop iterations.

If at the start of the loop value is already past end, the loop is completely skipped.

A slightly modified usage of the FOR / NEXT loop allows for excluding the variable name from NEXT; this is required if var is an array.

Example:

FOR i=0 TO 1000 STEP 100
  ? i
NEXT

IF condition THEN statement / I. T.

IF condition ... ELIF condition / ELI. ... ELSE / EL. ... ENDIF / E.

Conditional Execution

The first form (with THEN) executes one statement if the condition is true.

This differs from Atari BASIC, TurboBASIC XL, and others, which will execute all statements after THEN until the end of the line.

Example:

A=1
IF A=0 THEN ? "ZERO":? "THE END"

Results in THE END being printed in FORGE, whereas nothing would be printed in Atari BASIC.

The second form executes all statements following the IF (up until an ELIF, ELSE, or ENDIF) only if the condition is true.

If the condition is false, optional statements following the ELSE (until an ENDIF) are executed.

In case of an ELIF, the new condition is tested and acts like a nested IF until an ELSE or ENDIF.

Example:

IF condition-1
  ' Statements executed if condition-1 is true
ELIF condition-2
  ' Statements executed if condition-1 is false but condition-2 is true
ELIF condition-3
  ' Also, if condition-1 and condition-2 are false but condition-3 is true
ELSE
  ' Executed if all of the above conditions are false
ENDIF

FUNC name var1 ... / FU. ... ENDFUNC / ENDF.

Define A Function Or Procedure

FUNC statement starts the definition of a function or procedure that can be called via EXEC, @, or in expressions.

You can pass a list of integer variables separated by spaces after the FUNC name to specify a number of parameters, the variables will be set to the values passed by the EXEC call. Those variable names are always global, so the values set are seen outside the FUNC.

The number of parameters in the FUNC definition and in all the EXEC calls must be the same.

Procedures (no return value):

If a FUNC does not have a return type (no $ suffix for strings), it behaves like a procedure. Use ENDFUNC to end the function, which automatically emits a return.

Procedures can modify their parameters, which are passed by reference. This allows procedures to return multiple values through parameters.

Example - Simple procedure:

FUNC greet name
  ? "Hello, "; name
ENDFUNC

@greet "World"
EXEC greet "FORGE"

Example - Procedure with output parameter:

FUNC factorial n result
  IF n <= 1
    result = 1
  ELSE
    @factorial n-1, result
    result = result * n
  ENDIF
ENDFUNC

FACT_RESULT = 0
@factorial 5, FACT_RESULT
? "5! = "; FACT_RESULT  ' Prints 120

Functions (with return value):

To return a value from the function, use the RETURN statement followed by an expression. The function will return that value to the caller. Functions can be called in expressions.

Example:

FUNC add x y
  RETURN x + y
ENDFUNC

result = add(10, 20)
? result  ' Prints 30

String functions:

For string-returning functions, add a $ suffix to the function name:

FUNC greet$ name
  RETURN "Hello, " + name
ENDFUNC

message$ = greet$("World")
? message$  ' Prints "Hello, World"

Note that if the FUNC statement is encountered while executing surrounding code, the full function definition is skipped, so FUNC / ENDFUNC can appear any place in the program.

RETURN expr / RE.

Return From Function

Returns a value from a function. The expression expr is evaluated and returned to the caller.

RETURN can only be used inside a FUNC definition. When RETURN is executed, the function immediately exits and returns the value.

If a function does not contain a RETURN statement, it behaves as a procedure (no return value). The ENDFUNC statement automatically handles the return based on whether the function has a return type.

Example:

FUNC add x y
  RETURN x + y
ENDFUNC

result = add(10, 20)  ' result = 30

Note: For string-returning functions, use RETURN with a string expression:

FUNC greet$ name
  RETURN "Hello, " + name
ENDFUNC

message$ = greet$("World")

INCLUDE "filename" / IN.

INCLUDE ONCE "filename" / IN. ON.

#include "filename"

#INCLUDE "filename"

Include Another Source File

The INCLUDE directive inserts the contents of another source file into the current file at compile time, as if the included file's contents were typed directly at that location.

This allows you to organize your code into multiple files and build libraries of reusable procedures and functions.

The filename must be enclosed in double quotes. If the filename doesn't have an extension, .bas is automatically appended.

Path resolution order:

  1. Directory of the current file
  2. Include search paths (specified with -I option on command line)
  3. Current working directory

Both forward slashes (/) and backslashes (\) are accepted as path separators for cross-platform compatibility.

The INCLUDE ONCE variant ensures that a file is included only once, even if multiple INCLUDE statements reference it. This is useful for library files that might be included from multiple places.

You can also use C-style syntax with #include or #INCLUDE (case insensitive), which behaves exactly like INCLUDE.

Example:

' main.bas
INCLUDE "lib/math.bas"
INCLUDE "lib/graphics.bas"

FUNC main
  ? add(5, 3)
ENDFUNC

@main

The compiler detects circular includes and will report an error if a file includes itself (directly or indirectly). The maximum include depth is 32 levels.

Note: INCLUDE is a compile-time directive. It only works when compiling with the command-line compiler, not in the IDE interpreter.

REPEAT / R. ... UNTIL condition / U.

Loop Until Condition Is True

The REPEAT loop allows looping with a condition evaluated at the end of each iteration.

Executes statements between REPEAT and UNTIL once, then evaluates the condition. If false, the loop is executed again, if true the loop ends.

An EXIT statement also terminates the loop and skips to the end.

Example:

REPEAT
  ? "Enter password:"
  INPUT PASSWORD$
UNTIL PASSWORD$ = "secret"

WHILE condition / W. ... WEND / WE.

Loop While Condition Is True

The WHILE loop allows looping with a condition evaluated at the beginning of each iteration.

Firstly it evaluates the condition. If false, it skips the whole loop to the end. If true, it executes the statements between WHILE and WEND and returns to the top to test the condition again.

An EXIT statement also terminates the loop and skips to the end.

Example:

I = 0
WHILE I < 10
  ? I
  INC I
WEND

Graphic and Sound Statements

COLOR num / C.

Set Color Number

Changes the color of PLOT, DRAWTO and the line color on FILLTO to num.

Example:

COLOR 1
PLOT 10, 10

DRAWTO x, y / DR.

Draws A Line

Draws a line from the last position to the given x and y positions.

Example:

PLOT 0, 0
DRAWTO 100, 100

FCOLOR num / FC.

Sets Fill Color Number

Changes the filling color of FILLTO operation to num.

Example:

FCOLOR 2
FILLTO 50, 50

FILLTO x, y / FI.

Fill From Line To The Right

Draws a line from the last position to the given x and y position using COLOR number. For each plotted point it also paints all points to the right with the FCOLOR number, until a point with different color than the first is reached.

Example:

COLOR 1
FCOLOR 2
PLOT 10, 10
FILLTO 50, 10

GRAPHICS num / G.

Sets Graphic Mode

Sets the graphics mode for graphics operations. Below is a basic chart of GRAPHICS modes, their full screen resolution and number of available colors.

Text modes:

ModeResolution# Of Colors
GR. 040x242
GR. 120x245
GR. 220x125
GR. 1240x245
GR. 1340x125

Bitmapped graphics modes:

ModeResolution# Of Colors
GR. 340x244
GR. 480x482
GR. 580x484
GR. 6160x962
GR. 7160x964
GR. 8320x1922
GR. 980x19216 shades
GR. 1080x1929
GR. 1180x19216 hues
GR. 14160x1922
GR. 15160x1924

Notes:

  • GRAPHICS 0 and GRAPHICS 8 offer two colors, where the "on" pixels may be a different shade (luminance) of the background color's hue, but cannot have its own hue. (Television color artifacting effects can be utilized to simulate two additional colors.)
  • Mode 0 (and the text window found at the bottom of most other modes) can render 128 different characters (from a character set, aka font) in both normal video, and inverse video, based on whether the high bit of the character is set. See PRINT COLOR().
  • Modes 1 and 2 are text modes that offer multiple colors, but only a single color (plus the background) may be used by any given character cell. The colors are chosen by the two high bits of the character.
  • Modes 12 and 13 are multicolor text modes, where every pair of two bits in a character's bitmap data are used to represent one of four colors.
  • The so-called "GTIA modes" -- 9, 10, and 11 -- offer 16 shades of the given background color, all nine color registers, or 15 hues of a particular brightness, respectively.

For graphics modes which include a 4-line GRAPHICS 0 style text window at the bottom (all but 0, 9, 10, and 11), add 16 to the mode number to disable the text window. (e.g., GRAPHICS 2+16)

Add 32 to the mode number to prevent the graphics data from being cleared. (Note: Some graphics data may be replaced when changing modes.)

Example:

GRAPHICS 8
GRAPHICS 2+16  ' Disable text window

LOCATE x, y, var / LOC.

Get Color Of Pixel

Reads the color of pixel in the specified x and y coordinates and store into variable var.

Example:

LOCATE 10, 10, C
? "Color at 10,10 is "; C

PLOT x, y / PL.

Plots A Single Point

Plots a point in the specified x and y coordinates, with the current COLOR number.

Example:

COLOR 1
PLOT 10, 10

PMGRAPHICS num / PMG.

Player/Missile Graphics Mode

Set up Atari Player / Missile graphics. A value of 0 disables all player and missiles; a value of 1 sets up single line resolution; a value of 2 sets up double line resolution.

Single line mode uses 256 bytes per player, while double line uses 128 bytes per player. (Note that all four missiles share the same data.)

For retrieving the memory address of the player or missile data use the PMADR() function.

Example:

PMGRAPHICS 2  ' Double line resolution
ADDR = PMADR(0)  ' Address of Player 0

PMHPOS num,pos / PM.

Player/Missile Horizontal Move

Set the horizontal position register for the player or missile num to pos.

Players 0 to 3 correspond to values 0 to 3 of num; missiles 0 to 3 correspond to the values 4 to 7, respectively.

This is the same as writing: POKE $D000 + num , pos

Note: Player/Missile graphics on the Atari are strips that are as tall as the screen, and therefore to move a shape vertically its data must be moved within their 128- or 256-byte buffer (using the MOVE statement, for example).

Example:

PMHPOS 0, 80  ' Move Player 0 to horizontal position 80

SETCOLOR num, hue, lum / SE.

Sets Displayed Color

Alters the color registers so that color number num has the given hue and luminance.

To set Player/Missile colors use negative values of num, -4 for player 0, -3 for player 1, -2 for player 2, and -1 for player 3.

Missiles share the same color as their player, unless you combine them into a "5th Player" by setting bit number 4 of the GPRIOR register, e.g.: POKE 623,16. (You must also move them horizontally in unison if you wish to use them as a true 5th Player.)

It is possible to cause pixels of certain overlapping players to produce a third color (or black) by setting bit number 5 of the GPRIOR register, e.g. POKE 623,32.

Example:

SETCOLOR 0, 4, 8  ' Set color 0 to hue 4, luminance 8
SETCOLOR -4, 2, 10  ' Set Player 0 color

SOUND voice, pitch, dist, vol / S.

SOUND voice

SOUND

Adjust Voice Sound Parameters

Adjusts sound parameters for voice (from 0 to 3) of the given pitch, distortion and volume.

If only the voice parameter is present, that voice is cleared so no sound is produced by that voice.

If no parameters are given, it clears all voices so that no sounds are produced.

Note: TurboBASIC XL offers a DSOUND statement to pair sound channels for increased (16-bit) frequency range. This is not available in FORGE.

Example:

SOUND 0, 121, 10, 8  ' Voice 0, pitch 121, distortion 10, volume 8
SOUND 0  ' Clear voice 0
SOUND    ' Clear all voices

Device Input and Output Statements

BGET #iochn,address,len / BG.

Binary Read From File

Reads length bytes from the channel iochn and writes the bytes to address.

For example, to read to a byte array, use ADR(array) to specify the address.

On any error, ERR() will hold an error code, on success ERR() reads 1.

Example:

DIM buffer(256) BYTE
BGET #1, ADR(buffer), 256

BPUT #iochn,address,len / BP.

Binary Write To File

Similar to BGET, but writes length bytes from memory at address to the channel iochn.

On any error, ERR() will hold an error code, on success ERR() reads 1.

Example:

DIM buffer(256) BYTE
BPUT #1, ADR(buffer), 256

CLOSE #iochn / CL.

Close Channel

Closes the input output channel iochn, finalizing all read/write operations.

On any error, ERR() will hold an error code, on success ERR() reads 1.

Note that it is important to read the value of ERR() after close to ensure that written data is really on disk.

Example:

CLOSE #1
IF ERR() <> 1 THEN ? "Error closing file"

GET #iochn, var, ...

Reads Bytes From File

Reads one byte from channel iochn and writes the value to var.

var can be a variable name or an array position (like array(123))

In case of any error, ERR() returns the error value.

Example:

GET #1, BYTE_VAL

INPUT #iochn, var / IN.

Input Variable Or String From File

Reads a line from channel iochn and stores to var.

If var is a string variable, the full line is stored.

If var is a numeric variable, the line is converted to a number first.

On any error, ERR() will hold an error code, on success ERR() reads 1.

Example:

INPUT #1, LINE$
INPUT #1, NUMBER

OPEN #ioc,mode,ax,dev / O.

Opens I/O Channel

Opens I/O channel ioc with mode, aux, over device dev.

To open a disk file for writing, mode should be 8, aux 0 and dev the file name as "D:name.ext".

To open a disk file for reading, mode should be 4, aux 0 and dev the file name as "D:name.ext".

See Atari BASIC manual for more documentation in the open modes, aux values, and device names.

On any error, ERR() will hold an error code, on success ERR() reads 1.

Example:

OPEN #1, 4, 0, "D:FILE.TXT"  ' Open for reading
OPEN #2, 8, 0, "D:OUTPUT.TXT"  ' Open for writing

PRINT #iochn, ... / ?

Print Strings And Numbers To A File

Uses the same rules as the normal print, but all the output is to the channel iochn. Note that you must put a comma after the channel number, not a semicolon.

On any error, ERR() will hold an error code, on success ERR() reads 1.

Note that you can only read the error for the last element printed.

Example:

PRINT #1, "Hello, World"
PRINT #1, "Number: ", 42

PUT #iochn, num / PU.

Outputs One Byte To The File

Outputs one byte num to the channel iochn.

On any error, ERR() will hold an error code, on success ERR() reads 1.

Example:

PUT #1, 65  ' Write byte value 65

NOTE #iochn, sectVar, byteVar / NO.

Get Current File Position

Gets the current file position for channel iochn and stores the sector number (16-bit) into sectVar and the byte offset within the sector (8-bit) into byteVar.

This is used for building indexes for random-access file operations. The position returned represents where the next read or write operation will occur.

sectVar and byteVar must be word variables. The sector value ranges from 0 to 65535, and the byte value ranges from 0 to 255.

On any error, ERR() will hold an error code, on success ERR() reads 1.

Example:

NOTE #1, SEC, BYT
PRINT #1, "Record data"

See NOTE/POINT for detailed documentation.

POINT #iochn, sectExpr, byteExpr / PO.

Set File Position

Sets the file position for channel iochn to the specified sector sectExpr (16-bit) and byte offset byteExpr (8-bit) within that sector.

This enables random-access file operations by jumping to a previously saved position (obtained with NOTE).

The sector value ranges from 0 to 65535, and the byte value ranges from 0 to 255.

On any error, ERR() will hold an error code, on success ERR() reads 1.

Example:

POINT #1, SEC, BYT
INPUT #1, A$

Note: NOTE and POINT automatically preserve the AUX1 mode that was set when the file was opened with OPEN, ensuring compatibility with DOS file operations.

These commands work with disk files (D:) and other devices that support random access. They are undefined or may cause errors on devices that don't support positioning, such as the screen editor (E:) or keyboard (K:).

See NOTE/POINT for detailed documentation.

STATUS #iochn, statusVar / ST.

Get Device Status

Gets the status of the device on channel iochn and stores the CIO status code into statusVar.

This command calls the CIO STATUS operation (command 13) on the specified channel. The status code indicates whether the STATUS operation itself succeeded (1 = success, >127 = error).

After a successful STATUS call, the device handler places device-specific status information into the DVSTAT buffer (memory locations 746-749). Use the DVSTAT() function or helper functions to read this information.

statusVar must be a word variable.

On any error, ERR() will hold an error code, on success ERR() reads 1.

Example:

STATUS #1, ST
IF ST = 1 THEN
  ERR_BITS = DVSTAT(0)
  SENSE = DVSTAT(1)
ENDIF

This command is particularly useful with R: devices (Atari 850, R:Verter, BOB-Verter) for checking carrier status, error bits, and buffer counts.

XIO #iochn, cmd, aux1, aux2, dev / X.

Generic I/O Operation

Performs a general input/output operation on device dev, over channel ioc, with the command cmd and auxiliary bytes aux1 and aux2.

Note that the arguments of XIO statements are in different order than Atari BASIC, for consistency with other statements the iochn is the first argument.

Example:

XIO #1, 33, 0, 0, "D:FILE.TXT"  ' Delete file

See XIO Reference for complete XIO command codes.

General Statements

' / .

Line Comments

Any line starting with a dot or an apostrophe will be ignored. This is analogous to REM in Atari BASIC.

Example:

' This is a comment
. This is also a comment
PRINT "Hello"  ' Inline comment

CLR

Clears Variables And Free Memory

Clears all integer and floating-point variables to 0, all strings to empty strings and frees all memory associated with arrays.

After CLR you can't access arrays without allocating again with DIM.

Example:

CLR  ' Clear all variables and arrays

DATA arr() [type] = n1,n2, ... / DA.

Defines Array With Initial Values

This statement defines an array of fixed length with the values given.

The array name should not be used before, and type can be BYTE (abbreviated B.) or WORD (abbreviated W.). If no type is given, a word data is assumed.

If the name arr ends with a % symbol, this defines a floating point array, in this case you can't specify a type. It is important that at least the first element of each line in the data has a decimal point to force storing the data as floating point.

If you end the DATA statement with a comma, the following line must be another DATA statement without the array name, and so on until the last line.

Example:

DATA big() byte = $12,$23,$45,
DATA       byte = $08,$09,$15

Note that the array can be modified afterwards like a normal array.

Advanced Usage:

Byte DATA arrays can be used to include assembler routines (to call via USR), display lists and any other type of binary data.

To facilitate this, you can include constant strings and the address of other byte DATA array by name.

All the bytes of the string, including the initial length byte are included into the DATA array.

Example:

DATA str() B. = "Hello", "World"
X = ADR(str)
? $(X), $(X+6)
DATA ad() B. = $AD,str,$A2,0,$60
? USR(ADR(ad)), str(0)

Loading Data From A File:

The cross-compiler also supports loading data from a file directly into the program, using the BYTEFILE (abbreviated BYTEF.) and WORDFILE (abbreviated WORDF. or simply F.) types and a file name enclosed in double quotes.

Example:

DATA img() bytefile "img.raw"
DATA pos() wordfile "pos.bin"

The compiler will search the file in the same folder than the current basic source.

Storing Data Into ROM:

In addition to the above, the cross compiler allows to specify that the data should be stored in ROM, instead of the default in RAM. This means that the data can't be modified in targets that use ROM (cartridges), but will lower RAM usage.

To specify this, simply add the ROM word after the type:

DATA img() ROM 1234,5678
DATA pos() BYTE ROM 1,2,3,4

DEC var / DE.

Decrements Variable By 1

Decrements the variable by 1; this is equivalent to "var = var - 1", but faster.

var can be any integer variable or integer array element.

Example:

DEC COUNTER

DIM arr(size) [type], ... / DI.

DIM var, var$, var% ...

Allocate An Array / Define Var

The DIM statement allows defining arrays of specified length, and declaring variables explicitly, without assigning a value.

The type must be BYTE (abbreviated B.) to define a byte array, with numbers from 0 to 255, or WORD (can be left out) to define an array with integers from -32768 to 32767.

If the name arr ends with a $ or a % symbol, this defines a string array or floating point array respectively, in this case you can't specify a type.

The size of the array is the number of elements plus one, the elements are numerated from 0, so that an array dimensioned to 10 holds 11 values, from 0 to 10.

The array is cleared after the DIM, so all elements are 0 or an empty string.

In the second form, the variables given in the list are defined with the correct type, without giving a default value. The variables can be defined multiple times without an error if the types are always the same.

You can DIM more than one array or variable by separating the names with commas.

Example:

DIM A(10), X, T$
? A(5), X

END

Ends Program

Terminates current program. END is only valid at end of input.

Example:

IF DONE THEN END

INC var

Increments Variable By 1

Increments the variable by 1, this is equivalent to "var = var + 1", but faster.

var can be any integer variable or integer array element.

Example:

INC COUNTER

PAUSE num / PA.

PAUSE

Pauses Execution

Stops the current execution for the specified amount of time.

num is the time to pause in "jiffies", this is the number of TV scans in the system; 60 per second in NTSC or 50 per second in PAL.

Omitting num is the same as giving a value of 0, and pauses until the vertical retrace. This is useful for synchronization to the TV refresh and for fluid animation.

Example:

PAUSE 60  ' Pause for 1 second (NTSC)
PAUSE    ' Wait for vertical retrace

TIMER / T.

Resets Internal Timer

Resets value returned by TIME function to 0.

Example:

TIMER
? TIME  ' Will show 0

Floating Point Statements

Those statements are only available in the floating point version.

DEG

Sets "Degrees" Mode

Makes all trigonometric functions operate in degrees, so that 360 is the full circle.

Example:

DEG
? SIN(90)  ' Returns 1.0 (sine of 90 degrees)

RAD

Sets "Radians" Mode

Makes all trigonometric functions operate in radians, so that 2pi is the full circle.

This mode is the default on startup.

Example:

RAD
? SIN(3.14159/2)  ' Returns approximately 1.0

Low Level Statements

These are statements that directly modify memory. Use with care!

DPOKE address, value / D.

Writes A 16-Bit Number To Memory

Writes the value to the memory location at address and address+1, using standard CPU order (low byte first).

Example:

DPOKE 560, $4000  ' Write 16-bit value at address 560

MOVE from, to, length / M.

-MOVE from, to, length / -.

Copies Bytes In Memory

Copies length bytes in memory at address from to address to.

The MOVE version copies from the lower address to the upper address; the -MOVE version copies from upper address to lower address.

The difference between the two MOVE statements is in case the memory ranges overlap; if from is lower in memory than to, you need to use -MOVE, else you need to use MOVE, otherwise the result will not be a copy.

MOVE a, b, c is equivalent to:

FOR I=0 to c-1
  POKE b+I, PEEK(a+I)
NEXT I

On the other hand, -MOVE a, b, c is instead:

FOR I=c-1 to 0 STEP -1
  POKE b+I, PEEK(a+I)
NEXT I

Example:

MOVE $4000, $5000, 256  ' Copy 256 bytes forward
-MOVE $5000, $4000, 256  ' Copy 256 bytes backward (overlapping)

MSET address, length, value / MS.

Sets Memory To A Value

Writes length bytes in memory at given address with value.

This is useful to clear graphics or P/M data, or simply to set a string to a repeated value.

MSET a, b, c is equivalent to:

FOR I=0 to b-1
  POKE a+I, c
NEXT I

Example:

MSET $4000, 1024, 0  ' Clear 1KB of memory

POKE address, value / P.

Writes A Byte To Memory

Writes the value (modulo 256) to the memory location at address.

Example:

POKE 710, 0  ' Set color register 2

Display List Interrupts

Note: This is an advanced topic. See Display List Interrupts for complete documentation.

DLI SET name = op1, op2, ... / DLIS.

Define A New DLI

Setups a new DLI with the given name and performing the op operations.

Each operation is of the form: data INTO address or data WSYNC INTO address.

data is one constant byte or the name of a DATA BYTE array, and address is a memory location to modify.

If data is a DATA array, the first element (at index 0) will be used at the first line with DLI active in the screen, the second element at the second active line, etc.

The WSYNC word advances one line in the display area (this is done by writing to the WSYNC ANTIC register), so the value is set in the next screen line. You can put the WSYNC word multiple times to advance more than one line. This allows one DLI to modify multiple lines at the screen.

Multiple INTO words can be used to write more than one register with the same value.

INTO can be abbreviated to I. and WSYNC to W..

You can specify any number of operations, but as each one takes some time you could see display artifacts if you use too many.

Note that by defining a DLI you are simply giving it a name, you need to activate the DLI afterwards.

You can split a DLI definition over multiple lines, just like DATA by ending a line with a comma and starting the next line with DLI =

Example:

DLI SET d1 = $24 INTO $D01A
GRAPHICS 0
POKE DPEEK(560) + 16, 130
DLI d1

DLI name / DL.

DLI / DL.

Enable/Disable A DLI

This statement enables the DLI with the given name, the DLI must be defined before in the program.

This setups the OS DLI pointer to the named DLI and activates the interrupt bit in the display processor (the ANTIC chip), but does not activates on which lines the DLI must be called.

To define on which lines the DLI is active you must modify the Display List, see the examples in the Display List Interrupts section.

You can also pass the name of a DATA BYTE array with a custom machine language routine to the DLI statement, the routine must begin with a PHA and end with PLA and RTI.

When called without a name, this statement simply disables the DLI, returning the display to the original state.

Example:

DLI d1  ' Enable DLI named d1
DLI     ' Disable DLI

Atari SIO Statements

The Atari Serial Input Output interface is the low-level interface between the Atari 8-bit computers and the serial peripherals, like disk-drives and modems.

SIO ddevic, dunit, dcomnd, dstats, dbuf, dtimlo, dbyt, daux1, daux2

Send Any Command Over SIO

This function can be used to send any SIO command to any SIO device. For example, this command is used to read or write one sector in a floppy disk, or send special commands to a FujiNet network device.

ParameterDescription
DDEVICDevice # (e.g. $71)
DUNITUnit #
DCOMNDCommand # ($00-$FF)
DSTATSRead($40) / Write($80)
DBUFTarget buffer address
DTIMLOTimeout value
DBYT# of bytes in payload
DAUX1First Aux parameter
DAUX2Second Aux parameter

The meanings of each of these is highly dependent on the target device.

See SIO Operations for more details.

SERR() / SE.

Get Last SIO Error Function

This function returns the value in DSTATS, which contains the error of the last SIO operation from the device.

In the context of the FujiNet device, can be used, along with DVSTAT+4 to determine any error from a network operation.

Example:

SIO $71, 1, $FF, $40, ADR(buffer), 64, 0, 0, 0
IF SERR() <> 1 THEN ? "SIO error: "; SERR()

FujiNet Statements

NOTE: The FujiNet Statements are not available in the integer-only version.

These are statements that talk to the FujiNet network adapter, and can be used to open network connections, using any protocol supported.

Each of these statements require a unit number, of which 8 are available, numbered 1-8.

The general flow of use is:

  • NOPEN a connection
  • In a loop
    • Check for any traffic with NSTATUS
    • NGET if needed
    • Send any traffic with NPUT
  • When done, NCLOSE.

NOPEN unit, mode, trans, url / NO.

Open A Network Connection

Uses N: unit to open a connection to url using the desired mode and trans settings.

Example URLs:

  • N:HTTPS://www.gnu.org/licenses/gpl-3.0.txt

Common modes:

  • 4: READ, mapped e.g. to GET in HTTP
  • 6: DIRECTORY, e.g. PROPFIND in HTTP
  • 8: WRITE, mapped e.g. to PUT in HTTP
  • 12: READ/WRITE, e.g. for TCP
  • 13: Mapped to POST in HTTP

Common trans:

  • 0: No translation of characters.
  • 1: Change CR to ATASCII EOL.
  • 2: Change LF to ATASCII EOL.
  • 3: Change CR and LF to EOL.

Example:

NOPEN 1, 4, 0, "N:HTTPS://example.com/file.txt"

NCLOSE unit / NC.

Close A Network Connection

Closes a network connection unit previously opened by NOPEN.

Example:

NCLOSE 1

NSTATUS unit / NS.

Get Network Connection Status

Queries the status of specified network unit. The result is stored in DVSTAT starting at $02EA, and has the format:

AddressDescription
$02EA# of bytes waiting (LO)
$02EB# of bytes waiting (HI)
$02ECConnected? (0 or 1)
$02EDMost recent error #

You can easily get the # of bytes waiting by doing the following:

NSTATUS 1
BW = DPEEK($02EA)

NGET unit, addr, len / NG.

Read Bytes From Network To addr

Reads len bytes from the network connection and stores them at memory address addr.

When reading, len must be less than, or equal to the number of bytes waiting to be received, or an SIO error will result. Therefore, it is a good idea to figure out how many bytes are waiting using the NSTATUS command.

Example:

DIM buffer(1024) BYTE
NSTATUS 1
BYTES = DPEEK($02EA)
IF BYTES > 0 THEN
  NGET 1, ADR(buffer), BYTES
ENDIF

NPUT unit, addr, len / NP.

Write Bytes To Network From addr

Writes len bytes to the network connection from memory address addr.

When writing, len must be less than, or equal to the number of bytes in the source buffer.

Example:

DIM data(100) BYTE
NPUT 1, ADR(data), 100

For complete documentation, see FujiNet.

For example all of the available SIO commands for FujiNet Network at this link: SIO Commands for FujiNet Devices

Next Steps