forge Documentation

functions

Functions

Functions take parameters (normally between parentheses) and return a result.

Function Syntax

Abbreviations

Functions can be abbreviated by using a shorter name ended in a dot, for example you can write R.(10) instead of RAND(10).

Parentheses

You can also omit parentheses on functions that take only one argument, for example, RAND 10.

Note: This is not possible when the function accepts a variable number of arguments (as with USR), or with the ADR function.

Parameterless Functions

Some functions don't take parameters, and you must provide a set of parentheses, like KEY(). However, when abbreviated, you can omit the parenthesis, like K. for KEY().

Standard Functions

Following is a list of all the general purpose functions supported by FORGE. Shown are the full syntax and the abbreviated syntax.

TIME / T.

Returns the current time in "jiffies." This is about 60 times per second in NTSC systems or 50 times per second in PAL systems. Use TIMER statement to reset to 0.

Remember that this function returns an integer, so the maximum value is 32767, or about 9 minutes in NTSC, and a little less than 11 minutes in PAL, after this the value will become negative. If you need to measure more than this amount, consider using the floating-point version %TIME.

Note: TIME is special, and does not need parentheses.

Example:

TIMER
REPEAT
  ? TIME
  PAUSE 60
UNTIL TIME > 300

ABS(num) / A.(num)

Returns the absolute value of num (e.g., ABS(5) and ABS(-5) both result in 5). Can be used with integers and floating point.

Example:

? ABS(-10)  ' Prints 10
? ABS(10)   ' Prints 10

SGN(num) / SG.(num)

Returns the sign of num, this is 1 if positive, -1 if negative or 0 if num is 0. Can be used with integers and floating point.

Example:

? SGN(10)   ' Prints 1
? SGN(-5)   ' Prints -1
? SGN(0)    ' Prints 0

RAND(num) / R.(num)

Returns a random, non negative number, a maximum of 1 less than num. (e.g., RAND(3) will result in 0, 1, or 2.)

See also: RND() for floating point random numbers.

Example:

DICE = RAND(6) + 1  ' Random number 1-6

FRE() / F.

Returns the free memory available in bytes.

Example:

? "Free memory: "; FRE(); " bytes"

ERR() / E.

Returns the last Input/Output error value, or 1 if no error was registered.

Example:

OPEN #1, 4, 0, "D:FILE.TXT"
IF ERR() <> 1 THEN
  ? "Error opening file: "; ERR()
ENDIF

LEN(string) / L.(string)

Returns the length of the string.

Example:

A$ = "Hello"
? LEN(A$)  ' Prints 5

VAL(string) / V.(string)

Converts string to a number. If no conversion is possible, ERR() is set to 18. Can be used with integers and floating point.

Example:

A$ = "123"
N = VAL(A$)
? N  ' Prints 123

ASC(string) / AS.(string)

Returns the ATASCII code of the first character of the string.

Example:

? ASC("A")  ' Prints 65

Atari Specific Functions

The following functions allow interacting with the Atari hardware to read controller and keyboard input and to program with Player/Missile graphics.

PADDLE(n) / PA.(n)

Returns the value of the PADDLE controller n.

Example:

P0 = PADDLE(0)  ' Horizontal axis of paddle 0
P1 = PADDLE(1)  ' Vertical axis of paddle 0

PMADR(n) / PM.(n)

Returns the address of the data for Player n or the address of the Missiles with n = -1.

Example:

PMGRAPHICS 2
ADDR = PMADR(0)  ' Address of Player 0 data

PTRIG(n) / PT.(n)

Returns 0 if the PADDLE controller n button is pressed, 1 otherwise.

Example:

IF PTRIG(0) = 0 THEN ? "Button pressed"

STICK(n) / S.(n)

Returns the JOYSTICK controller n position. STICK(_n_) values are:

10  14   6

11  15   7

 9  13   5

Example:

DIR = STICK(0)
IF DIR = 14 THEN ? "Up"
IF DIR = 13 THEN ? "Down"

STRIG(n) / STR.(n)

Returns 0 if JOYSTICK controller n button is pressed, 1 otherwise.

Example:

IF STRIG(0) = 0 THEN ? "Fire!"

KEY() / K.

Returns 0 if no key was pressed, or a key code. The returned value only goes to 0 after reading the key in the OS (via a GET or POKE 764, 255 statement).

Hint: The value returned is actually the same as (PEEK(764) EXOR 255).

Example:

PRINT "Press keys, exit with ESC"
REPEAT
  REPEAT : UNTIL KEY()
  PRINT "Key code: "; KEY()
  GET K
  PRINT "ATASCII code: "; K
UNTIL K=27

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).

R: Device Status Functions

The following functions provide easy access to status information for R: devices (Atari 850 Interface Module, R:Verter, BOB-Verter). These functions automatically call STATUS on the specified channel and return the requested information from the DVSTAT buffer.

All functions take a channel number as their parameter and return 0 if the STATUS call fails.

Checking Carrier Status

To check if carrier is active, use (PEEK(747) AND 8) <> 0 after calling STATUS. This checks bit 3 of DVSTAT[1], which works with both Atari 850 and verter-style handlers.

Example:

OPEN #1,12,0,"R1:"
STATUS #1, ST
IF ST = 1 AND (PEEK(747) AND 8) <> 0 THEN
  ? "Connection active"
ELSE
  ? "No carrier"
ENDIF

Error Bits

To get error bits, use PEEK(746) after calling STATUS. Each bit represents a different error condition (bit 7=framing, bit 6=overrun, bit 5=parity, bit 4=overflow, etc.).

Sense Byte

To get the sense byte, use PEEK(747) after calling STATUS. The meaning depends on whether concurrent mode is active.

Buffer Counts

To get buffer counts when concurrent mode is active, use PEEK(747) + 256 * PEEK(748) for input buffer count and PEEK(749) for output buffer count after calling STATUS.

Floating Point Functions

These functions use floating point values, and are only available in the floating point version.

In case of errors (such as logarithm or square root of negative numbers and overflow in the results), the functions will return an invalid value, and the ERR() function returns 3.

ATN(n) / AT.(n)

Arc-Tangent of n.

Example:

ANGLE = ATN(1.0)  ' Returns approximately PI/4

COS(n) / CO.(n)

Cosine of n.

Example:

V = COS(0)  ' Returns 1.0

EXP(n)

Natural exponentiation (e raised to n).

Example:

V = EXP(1.0)  ' Returns approximately 2.718

EXP10(n) / EX.(n)

Returns ten raised to n.

Example:

V = EXP10(2)  ' Returns 100.0

INT(num) / I.(num)

Converts the floating point number num to the nearest integer from -32768 to 32767.

Example:

N = INT(3.7)  ' Returns 4
N = INT(-3.7) ' Returns -4

LOG(n)

Natural logarithm of n.

Example:

V = LOG(2.718)  ' Returns approximately 1.0

LOG10(n) / LO.(n)

Decimal logarithm of n.

Example:

V = LOG10(100)  ' Returns 2.0

RND() / RN.

Returns a random positive number strictly less than 1.

See also: RAND() for integer random numbers.

Example:

R = RND()  ' Random number 0.0 to 0.999...

SIN(n) / SI.(n)

Sine of n.

Example:

V = SIN(0)  ' Returns 0.0

SQR(n) / SQ.(n)

Square root of n.

Example:

V = SQR(16)  ' Returns 4.0

%TIME / %T.

This is the same as the TIME integer function, but returning a 24 bit number that does not wrap until more than 3 days.

Note: Don't use the TIMER statement if you are using this function, as the returned value will be invalid.

Example:

TIMER
? %TIME  ' 24-bit time value

String Functions

STR$(num)

Returns a string with a printable value for num. Can be used with integers and floating point.

Note: This function can't be used at both sides of a comparison, as the resulting string is overwritten each time it is called.

Example:

A$ = STR$(123)  ' A$ = "123"
B$ = STR$(3.14) ' B$ = "3.14"

CHR$(num)

Converts num to a one character string with the ATASCII value.

Example:

A$ = CHR$(65)  ' A$ = "A"

Low Level Functions

The following functions are called "low level" because they interact directly with the hardware. Use with care!

ADR(arr) / &arr

Returns the address of the first element of arr in memory. Following elements of the array occupy adjacent memory locations.

Instead of ADR(X) you can simply type &X.

Example:

DIM A(10)
ADDR = ADR(A)  ' or ADDR = &A

ADR(str) / &str

Returns the address of the string in memory. The first memory location contains the length of the string, and following locations contain the string characters.

Note: This differs from Atari BASIC and TurboBASIC XL, where the address returned points to the first character of the string.

Example:

A$ = "Hello"
ADDR = ADR(A$)  ' Address of string structure

ADR(var) / &var

Returns the address of the variable in memory.

Example:

X = 100
ADDR = ADR(X)  ' Address of variable X

DPEEK(addr) / D.(addr)

Returns the value of memory location addr and addr+1 as a 16 bit integer.

This is the same as doing PEEK(_addr_)+PEEK(_addr_+1)*256.

Example:

V = DPEEK(560)  ' Read 16-bit value at address 560

DVSTAT(index) / DVS.(index)

Reads a byte from the DVSTAT buffer (device status buffer at memory locations 746-749). The index parameter must be 0, 1, 2, or 3, corresponding to DVSTAT[0] through DVSTAT[3].

This function is used to read device-specific status information after calling STATUS on a device channel. The meaning of each byte depends on the device handler:

  • DVSTAT(0) - Error bits (bitfield)
  • DVSTAT(1) - Sense byte or buffer count low byte
  • DVSTAT(2) - Buffer count high byte (usually 0)
  • DVSTAT(3) - Output buffer count

For R: devices (Atari 850, R:Verter, BOB-Verter), see the helper functions above for easier access to common status information.

Example:

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

PEEK(address) / P.(address)

Returns the value of memory location at address.

Example:

V = PEEK(53279)  ' Read CONSOL register

USR(address[,num1 ...])

Low level function that calls the user supplied machine code subroutine at address.

Parameters are pushed to the CPU stack, with the LOW part pushed first, so the first PLA returns the HIGH part of the last parameter, and so on.

The value of A and X registers is used as a return value of the function, with A the low part and X the high part.

Example:

' PLA / EOR $FF / TAX / PLA / EOR $FF / RTS
DATA ml() byte = $68,$49,$FF,$AA,$68,$49,$FF,$60
FOR i=0 TO 1000 STEP 100
  ? i, USR(ADR(ml),i)
NEXT i

$(addr)

Returns the string at memory address addr.

This is the inverse of ADR(), and can be used to create arbitrary strings in memory.

Example:

DATA x() byte = 2, $41, $42
? $( ADR(x) )  ' Prints "AB"

You can also store string addresses to reuse later, using less memory than copying the full string:

x = ADR("Hello")
? $( x )  ' Prints "Hello"

%(n)

This returns the floating-point value stored at memory address n.

This function is special, as it is possible to use it also at the left side of an assignment, to store a floating point into an address:

%(1536) = 0.1234
? %(1536)  ' Prints 0.1234

Function Reference Table

FunctionAbbreviationTypeParametersDescription
TIMET.IntegerNoneCurrent time in jiffies
ABSA.NumericNumberAbsolute value
SGNSG.NumericNumberSign (-1, 0, or 1)
RANDR.IntegerMaxRandom integer
FREF.IntegerNoneFree memory in bytes
ERRE.IntegerNoneLast I/O error
LENL.IntegerStringString length
VALV.NumericStringConvert string to number
ASCAS.IntegerStringATASCII code of first char
PADDLEPA.IntegerController #Paddle value
PMADRPM.IntegerPlayer #Player/Missile address
PTRIGPT.IntegerController #Paddle trigger state
STICKS.IntegerController #Joystick position
STRIGSTR.IntegerController #Joystick trigger state
KEYK.IntegerNoneKey code
ATNAT.FloatNumberArc-tangent
COSCO.FloatNumberCosine
EXP-FloatNumberNatural exponent
EXP10EX.FloatNumber10 raised to power
INTI.IntegerFloatConvert to integer
LOG-FloatNumberNatural logarithm
LOG10LO.FloatNumberDecimal logarithm
RNDRN.FloatNoneRandom 0.0-1.0
SINSI.FloatNumberSine
SQRSQ.FloatNumberSquare root
%TIME%T.IntegerNone24-bit time
STR$-StringNumberConvert to string
CHR$-StringNumberATASCII to character
ADR&IntegerVariableMemory address
DPEEKD.IntegerAddressRead 16-bit value
DVSTATDVS.IntegerIndexDVSTAT buffer byte
PEEKP.IntegerAddressRead byte
USR-IntegerAddress, ...Call machine code
$-StringAddressString at address
%-FloatAddressFloat at address

Next Steps