Skip to content

GOLDELOX Internal Functions

Introduction

The 4D Labs family of embedded graphics processors are powered by a highly optimised soft core virtual engine, E.V.E. (Extensible Virtual Engine).

EVE is a proprietary, high performance virtual processor with an extensive byte-code instruction set optimised to execute compiled 4DGL programs. 4DGL (4D Graphics Language) was specifically developed from ground up for the EVE engine core. It is a high-level language which is easy to learn and simple to understand yet powerful enough to tackle many embedded graphics applications.

GOLDELOX-GFX2 Internal Block Diagram

4DGL is a graphics-oriented language allowing rapid application development. An extensive library of graphics, text and file system functions and the ease of use of a language that combines the best elements and syntax structure of languages such as C, Basic, Pascal, etc. Programmers familiar with these languages will feel right at home with 4DGL. It includes familiar instructions such as IF..ELSE..ENDIF, WHILE..WEND, REPEAT..UNTIL, GOSUB..ENDSUB, GOTO and a wealth of (chip-resident) internal functions that include SERIN, SEROUT, GFX_LINE, GFX_CIRCLE and many more.

This document covers the internal (chip-resident) functions available for the GOLDELOX Processor. This document should be used in conjunction with the 4DGL Programmers Reference Manual.

GOLDELOX Internal functions can be categorized based on usage as listed below:

GOLDELOX-GFX2 Internal Block Diagram

GPIO Functions

pin_Set

GOLDELOX-GFX2 has limited but powerful I/O.

There are pre-defined constant for mode and pin:

Pin Constant Value
IO1 0
IO2 1

The following are the supported modes for the pins:

Mode Constant Value Description IO1 IO2
OUTPUT 0 Pin is set to an output Yes Yes
INPUT 1 Pin is set to an input Yes Yes
ANALOGUE_8 2 Pin is set to analogue input, 8 bit mode Yes Yes
ANALOGUE_10 3 Pin is set to analogue input, 10 bit mode Yes Yes
ONEWIRE 4 Pin is set as Dallas One Wire I/O mode Yes Yes
SOUND 5 Pin is set for RTTTL sound output Yes Yes

Syntax: pin_Set(mode, pin);

Arguments Description
mode A value (usually a constant) specifying the pin operation.
pin A value (usually a constant) specifying the pin munber.

Returns: None

Example

pin_Set(OUTPUT, IO2);                // set IO2 to be used as an output
pin_Set(ANALOGUE_10, IO1);           // set IO1 to be used as analogue input

pin_HI

Outputs a "High" level (logic 1) on the appropriate pin that was previously selected as an Output. If the pin is not already set to an output, it is automatically made an output.

Syntax: pin_Hi(pin);

Argument Description
pin A value (usually a constant) specifying the pin number.

Returns: None

Example

pin_HI(IO2);         // output a Logic 1 on IO2 pin

pin_LO

Outputs a "Low" level (logic 0) on the appropriate pin that was previously selected as an Output. If the pin is not already set to an output, it is automatically made an output.

Syntax: pin_LO(pin);

Argument Description
pin A value (usually a constant) specifying the pin number

Returns: None

Example

pin_LO(IO1);                  // output a Logic 0 on IO1 pin

pin_Read

Reads the logic state or the analogue value of the pin that was previously selected as an Input. Returns a "Low" (logic 0) or "High" (logic 1) or Analogue value n.

Syntax: pin_Read(pin);

Argument Description
pin A value (usually a constant) specifying the pin number.

Returns: Logic 1 (0x0001) or a Logic 0 (0x0000) or the analogue value of the input pin.

Example

if (pin_Read(IO1) < 200) // read the analogue value on IO1
    calc_Threshold();
endif

joystick

Returns the value of the Joystick position (5 position switch implementation). The JOYSTICK values are:

Value 0 1 2 3 4 5
Status Released UP LEFT DOWN RIGHT FIRE

Syntax: joystickk();

Return: The joystick value.

Example

joy := joystick(); // read the joystick
if (joy == 0) putstr("     ");
if (joy == 1) putstr("UP   ");
if (joy == 2) putstr("LEFT ");
if (joy == 3) putstr("DOWN ");
if (joy == 4) putstr("RIGHT");
if (joy == 5) putstr("FIRE ");

Note

The joystick input uses IO1 utilizing the A/D converter. Each switch is connected to junction of 2 resistors that form a unique voltage divider circuit. Refer to the GOLDELOX-GFX2 data sheet example schematics for the required resistor values.

OW_Reset

Resets a ONEWIRE device and returns the status. (refer to Dallas 1wired documentation for further information)

Syntax: OW_Reset();

Return: The status of the ONEWIRE device

Example

// This example will print a 0 if the device initialised successfully.
print ("result=", OW_Reset());

OW_Read

Reads the 8 bit value from a 1-Wire devices register. (refer to Dallas 1wired documentation for further information)

Syntax: OW_Reset();

Returns: A word holding the lower 8 bits contain data bits received from the 1-Wire device. |

Example

// read temperature from DS1821 device
var temp_buf; OW_Reset(); // reset the device
OW_Write(0xAA); // send the read command
temp_buf := OW_Read(); // read the device register

OW_Read9

Reads the 9 or more bit value from a 1-Wire devices register. (refer to Dallas 1wired documentation for further information)

Syntax: OW_Read9();

Returns: A word holding 9 or more data bits received from the 1-Wire device. |

Example

// read temperature from DS1821 device
var temp_buf; OW_Reset(); // reset the device
OW_Write(0xAA); // send the read command
temp_buf := OW_Read9(); // read the device register

OW_Write

Writes the 8 bit data to 1-Wire devices register. (refer to Dallas 1wired documentation for further information)

Syntax: OW_Write(data);

Argument Description
data The lower 8 bits of data are sent to the 1-Wire device.

Returns: None

Example

//===================================================================
// For this demo to work, a Dallas DS1821 must be connected to
// IO1 AND POWERED FROM
// DS1821 pin1 = Gnd / pin2 = data in/out / pin 3 = +5v
// Refer to the Dallas DS1821 for further information
//===================================================================
var temp_buf, stat_buf;

func main()
    pause(1000);
    txt_MoveCursor(0,0);
    pin_Set(ONEWIRE, PIN_1); // set either I/O pin to 1 wire mode
    if(OW_Reset()) // initialise and test
        print("No device detected");
        while(1);
    endif
    txt_Set(TEXT_COLOUR, LIGHTGREY);
    txt_Set(FONT_SIZE, FONT_LARGE);
    // refer to data sheet for continuous/polled mode
    // OW_Write(0x0C); // write status
    // OW_Write(0b01000010); // set continuous conversion
    repeat
        txt_MoveCursor(0, 0);
        print ("result=", OW_Reset());
        OW_Write(0xEE); // start conversion
        OW_Reset(); // reset
        OW_Write(0xAA); // get temperature
        temp_buf := OW_Read();
        OW_Reset(); // optional
        OW_Write( 0xAC); // optional read status
        stat_buf := OW_Read(); // optional 82 when DS1821 run
        txt_MoveCursor(1, 0);
        print ("temp_buf=0x", [HEX2] temp_buf);
        txt_MoveCursor(2, 0);
        print ("stat_buf=0x", [ HEX2] stat_buf);
    forever
endfunc

Memory Access Functions

peekB

This function returns the 8 bit value that is stored at address.

Syntax: peekB(address);

Argument Description
Address The address of a memory byte. The address is usually a pre-defined system register address constant

Returns: The 8 bit value stored at address.

Example

// This example places the width of the display
// (horizontal resolution in pixel units) in 'myvar'
var myvar;
myvar := peekB(GFX_XMAX ) + 1;

Note

The peekB(..) and pokeB(..) functions are usually only used with internal system byte registers using the pre-defined constants. If peekB(..) or pokeB(..) are used to access other locations, the address must be doubled to get the correct pointer address.

peekW

This function returns the 16 bit value that is stored at address.

Syntax: peekW(address);

Argument Description
address The address of a memory word. The address is usually a pre-defined system register address constant

Returns: The 16 bit value stored at address.

Example

/*
 * This example places the low word of the 32 bit system timer in 'myvar'.
 * The equivalent operation using a pointer is: myvar := *TIMER2;
 */
var myvar;
myvar := peekW(SYSTEM_TIMER_LO);

pokeB

This function writes a 8 bit value to a location specified by address.

Syntax: pokeB(address, byte_value);

Argument Description
address The address of a memory byte. The address is usually a pre-defined system register address constant
byte_value The lower 8 bits of byte_value will be stored at address.

Returns: If poke address was a legal address (usually ignored).

Example

// This example manually adjusts the top clipping point to 10 pixels down from top of screen.
pokeB(CLIP_TOP, 10);

Note

The peekB(..) and pokeB(..) functions are usually only used with internal system byte registers using the pre-defined constants. If peekB(..) or pokeB(..) are used to access other locations, the address must be doubled to get the correct pointer address.

pokeW

This function writes a 16 bit value to a location specified by address.

Syntax: pokeW(address, word_value);

Argument Description
address The address of a memory word. The address is usually a pre-defined system register address constant
word_value The 16 bit word_value will be stored at address.

Returns: If poke address was a legal address (usually ignored).

Example

// This example sets TIMER2 to 5 seconds.
pokeW(TIMER2, 5000);
// The equivalent operation using a pointer is:
//*TIMER2 := 5000;

bits_Set

This function sets the required bits at address by 'ORing' the mask with the value stored at address.

Syntax: bits_Set(address, mask);

Argument Description
address The address of a user memory location.
mask The 16 bit mask containing bits to be set.

Returns: None

Example

// This example sets bits 6 and 7 of myval
var myval;
myval := 3;
bits_Set(myval, 0xC0);
print([HEX], myval);

Note

The bits_Set, bits_Clear, bits_Flip and bits_Test functions can only be used for user memory and will not work with system register variables

bits_Clear

This function clears the required bits at address by 'ANDing' the inverted mask with the value stored at address.

Syntax: bits_Clear(address, mask);

Argument Description
address The address of a user memory location.
mask The 16 bit mask containing bits to be cleared.

Returns: None

Example

// This example clears bits 10, 11, 12 and 13 of myval
var myval;
myval := 0xFFFF;
bits_Clear(myval, 0x3C00);
print([HEX], myval);

Note

The bits_Set, bits_Clear, bits_Flip and bits_Test functions can only be used for user memory and will not work with system register variables.

bits_Flip

This function flips the required bits at address by 'XORing' the mask with the value stored at address.

Syntax: bits_Flip(address, mask);

Argument Description
address The address of a user memory location.
mask The 16 bit mask containing bits to be flipped.

Returns: None

Example

// This example clears bits 15, 11, and 1 of myval
var myval;
myval := 0xFFFF;
bits_Flip(myval, 0x8802);
print([HEX], myval);

Note

The bits_Set, bits_Clear, bits_Flip and bits_Test functions can only be used for user memory and will not work with system register variables.

bits_Test

This function tests the required bits at address using the mask with the original value. If any of the bits are set, the function returns 1. If none of the bits are set, the function returns 0.

Syntax: bits_Test(address, mask);

Argument Description
address The address of a user memory location.
mask The 16 bit mask containing bits to be tested.

Results: if any of the tested bits are set returns 1. If none of the tested bits are set return 0.

Example

// This example tests bits 8-15 in myval, if any bits are set, the result will be 1.
var myval,res;
myval = 0x1234;
res := bits_Test(myval, 0xFF00);
print(res);

Note

The bits_Set, bits_Clear, bits_Flip and bits_Test functions can only be used for user memory and will not work with system register variables.

User Stack Functions

EVE provides all the requirement for a user stack to aid in development of stack-based processing (e.g., for interpreters and fast raster drawings). The stack is at a fixed location (it is at the base of the user memory). The stack pointer always expects the stack to be here – it is hard micro-coded internally.

If none of the stack functions are used, the stack can be disregarded as it will not influence any other program dynamics – the memory can be used for other purposes. If a user stack is required, it must be configured as the first array in the user's program. The stack pointer always points to the current item on top of the stack.

Typically, your program will look like this:

// the user stack MUST be the first storage in you program
var mystack[20];            // A 20 word stack. The stack must be the first array in the program. 
var myvar1, myvar2;         // etc

Note

If the stack pointer is zero, there are no items on the stack.

setsp

The users stack pointer is zeroed at power up, but it is sometimes necessary to alter the stack pointer for various reasons, such as running multiple concurrent stacks, or resetting to a known position as part of an error recovery process.

Syntax: setsp(index);

Arguments Description
index This argument is used to set the users SP to the required position. The stack pointer is set to zero during power-up initialisation.

Returns: None

Example

// This example sets the users stack pointer to 'empty'
setsp(0); // reset the stack pointer

getsp

This function returns the current stack index into the stack array. If the index is zero, there are no items on the stack.

Syntx: getsp();

Returns: The current stack index.

Example

// This example will print '1' assuming there are no other items on the stack.
push(1234);
print(getsp()); // print the stack index

pop

This function returns the value at the current stack pointer index. The stack pointer is then decremented, so it now points to the item below. If the stack pointer is zero, (ie a pop was performed on an empty stack) the function returns 0 and the stack pointer is not altered (ie it remains at 0).

Syntax: pop();

Returns: The value at current stack pointer index.

Example

// This example prints '300' and the stack pointer is reduced by 2
push(100);
push(200);
print(pop()+ pop());

push

Increment the user stack pointer first and then places the item into the user stack array at the current position. The stack pointer is now pointing to this new item.

Syntax: push(value);

Argument Description
value Argument to be pushed to the user stack.

Returns: None

Example

// This example pushes 3 items to the user stack
myvar := 10;
push(1234);
push(5678);
push(myvar);

drop

Decrements the user stack pointer determined by the value n. If n exceeds the stack index, the stack pointer is zeroed.

Syntax: drop(n);

Argument Description
n Specifies the number of items to be dropped from the stack.

Returns: None

Example

// This example decrements the stack pointer by 2, effectively dropping
// 'myvar' and '5678' from the stack, the next pop would yield 1234.
myvar := 10;
push(1234);
push(5678);
push(myvar);
drop(2);

call

Calls the specified function, the arguments to the called function are from the stack. The stacked parameters are consumed and the stack pointer is altered to match the number of arguments that were consumed.

Syntax: call();

Returns: If the called function returns a value then it is available. |

Example

// takes the function argument count, function pointer, and argument pointer
// from the top of the stack and calls the function using the stacked parameters.
// The 7 arguments on the stack are discarded.
push(10);
push(10);
push(50);
push(50);
push(0xFFFF);
push(gfx_RectangleFilled); // push the function call address
push(5);                   // push the argument count
//~~~~~~
call();

exec

Calls the specified function, passing the arguments to the called function from the stack. The stack and stack pointer are not altered.

Syntax:: exec(functionPtr, argCount);

Argument Description
functionPtr A pointer to a function which will utilise the stacked arguments.
argCount The count of arguments on the stack that are to be passed to the function call.

Returns: If the called function returns a value then it is available.

Example

push(50);           // set some arbitrary values on the stack
push(50);
push(10);
push(YELLOW);

// Draws a circle using the stacked parameters.
// The stacked parameters and the stack pointer are not altered.
exec(gfx_Circle,4); // exec the circle function using
                    // the stacked parameters

Math Functions

ABS

This function returns the absolute value of value.

Syntax: ABS(value);

Argument Description
value a variable, array element, expression or constant.

Returns: The absolute value.

Example

// This example returns 500 in variable 'myvar'
var myvar, number;
myvar := ABS(number * 5);

MIN

This function returns the the smaller of value1 and value2.

Syntax: MIN(value1, value2);

Argument Description
value1 a variable, array element, expression or constant.
value2 a variable, array element, expression or constant.

Returns: The smaller of the two values.

Example

var myvar, number1, number2;
// This example returns 33 in variable 'myvar'
number1 := 33;
number2 := 66;
myvar := MIN(number1, number2);

MAX

This function returns the the larger of value1 and value2.

Syntax: MAX(value1, value2);

Argument Description
value1 a variable, array element, expression or constant.
value2 a variable, array element, expression or constant.

Returns: The larger of the two values.

Example

var myvar, number1, number2;
// This example returns 66 in variable 'myvar'.
number1 := 33;
number2 := 66;
myvar := MAX(number1, number2);

SWAP

Given the addresses of two variables (var1 and var2), the values at these addresses are swapped.

Syntax: SWAP(&var1, &var2);

Argument Description
&var1 The address of the first variable.
&var2 The address of the second variable.

Returns: None

Example

var myvar, number1, number2;
// This example swaps the values in 'number1' and 'number2'
number1 := 33;
number2 := 66;
myvar := MAX(number1, number2);
// 'number1' will hold 66, and 'number2' will hold 33.

SIN

This function returns the sine of an angle. The input value is automatically shifted to lie within 0-359 degrees.

The returned value range is from 127 to -127 which is a more useful representation for graphics work. The real sine values vary from 1.0 to -1.0 so appropriate scaling must be done in user code as required.

Syntax: SIN(angle);

Argument Description
angle The angle in degrees.

Returns: The sine in radians of an angle specified in degrees.

Example

var myvar, angle;
angle := 133;
// This example returns 92 in variable 'myvar'
myvar := SIN(angle);

COS

This function returns the cosine of an angle. The input value is automatically shifted to lie within 0-359 degrees

The returned value range is from 127 to -127 which is a more useful representation for graphics work. The real sine values vary from 1.0 to -1.0 so appropriate scaling must be done in user code as required.

Syntax: COS(angle);

Argument Description
angle The angle in degrees.

Returns: The cosine in radians of an angle specified in degrees

Example

var myvar, angle;
angle := 133;
// This example returns -86 in variable 'myvar'
myvar := COS(angle);

RAND

This function returns a pseudo random signed number ranging from -32768 to +32767.

Returns a pseudo random signed number ranging from -32768 to +32767 each time the function is called. The random number generator may first be seeded by using the SEED(number) function. The seed will generate a pseudo random sequence that is repeatable. You can use the modulo operator (%) to return a number within a certain range, eg n := RAND() % 100; will return a random number between -99 and +99. If you are using random number generation for random graphics points, or only require a positive number set, you will need to use the ABS function so only a positive number is returned, eg: X1 := ABS(RAND() % 100); will set co-ordinate X1 between 0 and 99. Note that if the random number generator is not seeded, the first number returned after reset or power up will be zero. This is normal behavior.

Syntax: RAND();

Returns: pseudo random signed number ranging from -32768 to +32767

Example

SEED(1234);
// This example will print '3558, 1960' to the display.
print(RAND(),", ",RAND());

SEED

This function seeds the pseudo random number generator so it will generate a new repeatable sequence. The seed value can be a positive or negative number.

Syntax: SEED(number);

Argument Description
number Specifies the seed value for the pseudo random number generator.

Returns: None

Example

SEED(-50);
// This example will print '30129, 27266' to the display.
print(RAND(),", ",RAND());

SQRT

This function returns the integer square root which is the greatest integer less than or equal to the square root of number.

Syntax: SQRT(number);

Argument Description
number Specifies the positive number for the SQRT function.

Returns: the integer square root of a number

Example

var myvar;
// returns 161 in  'myvar' which is the 'integer square root' of 26000
myvar := SQRT(26000);

OVF

This function returns the high order 16 bits from certain math and shift functions. It is extremely useful for calculating 32 bit address offsets for MEDIA access. It can be used with the shift operations, addition, subtraction, multiplication and modulus operations.

Syntax: OVF();

Returns: The high order 16 bits from certain math and shift functions.

Example

var loWord, hiWord;
loWord := 0x2710 * 0x2710; // (10000 * 10000 in hex format)
hiWord := OVF();
print("0x", [HEX] hiWord, [HEX] loWord);
// This example will print '0x05F5E100' to the display
// which is 100,000,000 in hexadecimal

Text and String Functions

txt_MoveCursor

Moves the origin to a screen position set by line and column parameters. The line and column position is calculated, based on the size and scaling factor for the currently selected font. When text is outputted to screen it will be displayed from this position. The text position could also be set with gfx_MoveTo(...); if required to set the text position to an exact pixel location.

Syntax: txt_MoveCursor(line, column);

Argument Description
line Holds a positive value for the required line position.
column Holds a positive value for the required column position.

Returns: None

Example

// This example moves the text origin to the 5th line and the 10th column.
txt_MoveCursor(4, 9);

Note

The lines and columns start from 0, so line 0 , column 0 is the top left corner of the display.

putch

This function prints single characters to the current output stream, usually the display.

Syntax: putch(char);

Argument Description
char Holds a positive value for the required character.

Returns: None

Example

var v;
v := 0x39;
putch(v);   // print the number 9 to the current display location
putch('\n'); // newline

putstr

This function prints a string to the current output stream, usually the display. The argument can be a string constant, a pointer to a string, a pointer to an array, or a pointer to a data statement. This is more efficient than print(...) function

  • A string constant is automatically terminated with a zero.
  • A string in a data statement is not automatically terminated with a zero.
  • All variables in 4DGL are 16-bit, if an array is used for holding 8-bit characters, each element stores 2 characters.

Syntax: putstr(pointer);

Argument Description
pointer A string constant or word pointer to a string.

Returns: Returns the pointer to the item that was printed.

Examples

putstr("HELLO\n");          //simply print a string constant at current origin
var p;                       // a var for use as a pointer
p := "String Constant\n";    // assign a string constant tp pointer s
putstr(p);                   // print the string using the pointer
#DATA
    word weekdays mon, tue, wed, thu, fri    // pointers to data items
    byte mon "Monday\n\0"
    byte tue "Tuesday\n\0"
    byte wed "Wednesday\n\0"
    byte thu "Thursday\n\0"
    byte fri "Friday\n\0"
#END

var n := 0;
while (n < 7) putstr(weekdays[n++]);      // print the days from Mon to Fri

Note

The output can be redirected to the communications port, the media, or memory using the to(...) function.

putnum

This function prints a 16bit number in various formats to the current output stream

List of Predefined Signed Decimal Formats

DEC DECZ DECZB HEX HEXZ HEXZB BIN BINZ BINZB
DEC1 DEC1Z DEC1ZB HEX1 HEX1Z HEX1ZB BIN1 BIN1Z BIN1ZB
DEC2 DEC2Z DEC2ZB HEX2 HEX2Z HEX1ZB BIN2 BIN2Z BIN2ZB
DEC3 DEC3Z DEC3ZB HEX3 HEX3Z HEX1ZB BIN3 BIN3Z BIN3ZB
DEC4 DEC4Z DEC4ZB HEX4 HEX4Z HEX1ZB BIN4 BIN4Z BIN4ZB
DEC5 DEC5Z DEC5ZB BIN5 BIN5Z BIN5ZB
UDEC UDECZ UDECZB BIN6 BIN6Z BIN6ZB
UDEC1 UDEC1Z UDEC1ZB BIN7 BIN7Z BIN7ZB
UDEC2 UDEC2Z UDEC2ZB BIN8 BIN8Z BIN8ZB
UDEC3 UDEC3Z UDEC3ZB BIN9 BIN9Z BIN9ZB
UDEC4 UDEC4Z UDEC4ZB BIN10 BIN10Z BIN10ZB
UDEC5 UDEC5Z UDEC5ZB BIN11 BIN11Z BIN11ZB
BIN12 BIN12Z BIN12ZB
BIN13 BIN13Z BIN13ZB
BIN14 BIN14Z BIN14ZB
BIN15 BIN15Z BIN15ZB
BIN16 BIN16Z BIN16ZB

Number Formatting Bit Format

bit 15 14 13 12 11 10 9  8  7  6  5  4  3  2  1  0
    |  |  |  |  \___ ____/  \__ __/  \_____ _____/
    |  |  |  |      V          V           V
    |  |  |  |      |          |           |
    |  |  |  |  (nb 0 = 16)    |           |____BASE (usually 2, 10 or 16)
    |  |  |  |   displayed     |           
    |  |  |  |   digit qty     |______reserved 
    |  |  |  |                 
    |  |  |  |______ 1 = leading zeros included                     
    |  |  |          0 = leading zeros suppressed             
    |  |  |      
    |  |  |_______ 1 = leading zero blanking                       
    |  |           0 = Show Zeros
    |  |  
    |  |_____ sign bit (0 = signed, 1 = unsigned)         
    |  
    |______ 1 = space before unsigned number
            0 = no space

Syntax: putnum(format, value);

Argument Description
format A constant that specifies the number format.
value The number to be printed.

Returns: The default width of the numeric field (digit count), usually ignored.

Example

var v;
v := 05678;
putnum(HEX, v);       // print the number as hex 4 digits
putnum(BIN, v);       // print the number as binary 16 digits

print

This function provides a verstaitle way to format numerics and strings to a formatted text. It can accept directives passed in square brackets to make it print in various ways.

For instance, if you wish to print a number in 4 digit hex, use the [HEX4] directive placed in front of the variable to be displayed within the print statement. Refer to List of Predefined Signed Decimal Formats for all the numeric representations available

[STR] and [CHR] are additional directives that are not part of the numeric set.

  • The [STR] directive expects a string pointer to follow.
  • The [CHR] directive prints the character value of a variable.

Syntax: print(...);

Returns: None

Example

// In it's simplest form, print will simply print a number as can be seen below:
myvar := 100;
print(myvar);
// print 100 to the current output device (usually the display in TEXT mode).

print("the value of myvar is :- ", myvar, "and its 8bit binary representation is:-", [BIN8]myvar);
// Note:   if you wish to add a string anywhere within a print(...) statement,
//         just place a quoted string expression and you will be able to mix strings
//         and numbers in a variety of formats.
s := "Hello World"; // assign a string constant to s 
print("myvar as a 4 digit HEX number is :- ", [HEX4]myvar);
print("Var 's' points to a string constant at address", s ," which is", [STR] s);
print("The third character of the string is '", [CHR] *(s+2));
print("The value of 'myvar' as an ASCII charater is '", [CHR] myvar);

Note

You can freely mix string pointers, strings, variables and expressions within a print statement. print(...) can also use the to(...) function to redirect it's output to a different output device other than the screen using the function (refer to the to(...) statement for further examples).

to

This function can be to to redirect the printouts that are normally printed on the screen.

Normally, print just sends its output to the display in TEXT mode which is the default, however, the output from print can be sent to COM0, and MDA (media) 'streams'. This function can also stream to a memory array to compose and store a string for later use.

Note that once the to(...) function has taken effect, the stream reverts back to the default stream which is TEXT as soon as putch, putstr, putnum or print has completed its action.

The APPEND argument is used to send the printed output to the same place as the previous redirection. This is most useful for building string arrays, or adding sequential data to a media stream.

The following are accepted outstream constants

Predefined Name Constant Redirection
APPEND 0x0000 Output is directed to the same stream that was previously assigned. Output is appended to user array if previous redirection was to an array.
COM0 0xFF04 Output is redirected to the COM (serial) port.
TEXT 0xFF08 Output is directed to the screen (default).
MDA 0xFF10 Output is directed to the SD/SDHC or FLASH media.

Alternaltively, a pointer (0x102 < 0x3FF) to a buffer/array can be used as outstream. In this case, the printouts is redirected to the memory location.

Syntax: to(outstream);

Argument Description
outstream A variable or constant specifying the destination for the putch, putstr, putnum and print functions.

Returns: None

Example

var buf[10];         // a buffer that will hold up to 20 bytes/chars
var s;               // a var for use as a pointer

to(buf); putstr("ONE "); // redirect putstr to the buffer
to(APPEND); putstr("TWO "); // and add a couple more items
to(APPEND); putstr("THREE\n");
putstr(buf); // print the result

while (media_Init() == 0) 0; // wait if no SD/SDHC card detected
media_SetSector(0, 2);      // at sector 2
//media_SetAdd(0, 1024);    // (alternatively, use media_SetAdd(),
                        // lower 9 bits
to(MDA); putstr("Hello World"); // now write a ascii test string
media_WriteByte('A');       // write a further 3 bytes
media_WriteByte('B');
media_WriteByte('C');
to(MDA); putstr(buf);       // write the buffer we prepared earlier
media_WriteByte(0);         // terminate with ASCII zero
media_Flush();
media_SetAdd(0, 1024);      // reset the media address
while(char:=media_ReadByte())
    to(COM0); putch(char);      // print the stored string to the COM port
wend

repeat forever

charwidth

charwidth is used to calculate the width in pixel units for a character, based on the currently selected font. The font can be proportional or mono-spaced. If the total width of the string exceeds 255 pixel units, the function will return the 'wrapped' (modulo 8) value.

Syntax: charwidth('char');

Argument Description
'char' The ascii character for the width calculation.

Returns: The width of a single character in pixel units.

Example

str := "HELLO\nTHERE";  // note that this string spans 2 lines due
                        // to the n.
width := strwidth(str); // get the width of the string, this will
                        // also capture the
height := strheight();  // note, invoking strwidth also calcs height
                        // which we can now
// The string above spans 2 lines, strheight() will calculate height
// correctly for multiple lines.
len := strlen(str);     // the strlen() function returns the number
                    // of characters in a string.
print(" nLength=",len); // NB: the n in "HELLO\nTHERE" is counted
                    // as a character.
txt_FontID(MS_SanSerif8x12);// select this font
w := charwidth('W');        // get a characters width
h := charheight('W');       // and height
txt_FontID(0);              // back to default font
print ("\n'W' is " ,w, " pixels wide"); // show width of a character
                                    // 'W' in pixel
print ("\n'W' is " ,h, " pixels high"); // show height of a character
                                        // 'W' in pixel

charheight

charheight(char) is used to calculate the height in pixel units for a character, based on the currently selected font. The font can be proportional or mono-spaced.

Syntax: charheight('char');

Argument Description
'char' The ascii character for the height calculation.

Returns: The height of a single character in pixel units.

Example: See example in charwidth()

strwidth

strwidth() returns the width of a zero terminated string in pixel units. Note that any string constants declared in your program are automatically terminated with a zero as an end marker by the compiler. Any string that you create in the DATA section or MEM section must have a zero added as a terminator for this function to work correctly.

Syntax: strwidth(pointer);

Argument Description
pointer The pointer to a zero (0x00) terminated string.

Returns: The width of a string in pixel units.

Example: See example in charwidth()

strheight

strheight() returns the height of a zero terminated string in pixel units. The strwidth() function must be called first which makes available width and height. Note that any string constants declared in your program are automatically terminated with a zero as an end marker by the compiler. Any string that you create in the DATA section or MEM section must have a zero added as a terminator for this function to work correctly.

Syntax: strheight();

Returns: The height of a string in pixel units.

Example: See example in charwidth()

strlen

strlen() returns the length of a zero terminated string in character units. Note that any string constants declared in your program are automatically terminated with a zero as an end marker by the compiler. Any string that you create in the DATA section or MEM section must have a zero added as a terminator for this function to work correctly.

Syntax: strlen(pointer);

Argument Description
pointer The pointer to a zero (0x00) terminated string.

Returns: The length of a string in character units.

Example: See example in charwidth()

txt_Set

Given a function number and a value, set the required text control parameter, such as size, colour, and other formatting controls. This function is extremely useful in a loop to select multiple parameters from a data statement or a control array. Note also that each function available for txt_Set has a single parameter 'shortcut' function that has the same effect. (see the Single parameter short-cuts for the txt_Set functions next page)

# Predefined Name Description value
0 TEXT_COLOUR Set the text foreground colour Colour 0-65535
1 TEXT_HIGHLIGHT Set the text background colour Colour 0-65535
2 FONT_ID Set the required font (0 = system font)
3 TEXT_WIDTH Set the text width multiplier 1 to 16
4 TEXT_HEIGHT Set the text height multiplier 1 to 16
5 TEXT_XGAP Set the pixel gap between characters 0 to n
6 TEXT_YGAP Set the pixel gap between lines 0 to n
7 TEXT_PRINTDELAY Set the delay between character printing (Default 0 msec)
8 TEXT_OPACITY Selects whether or not the 'background' pixels are drawn (default mode is OPAQUE) 0 or TRANSPARENT and 1 or OPAQUE
9 TEXT_BOLD Embolden text 0 or 1 (OFF or ON)
10 TEXT_ITALIC Italicise text 0 or 1 (OFF or ON)
11 TEXT_INVERSE Inverted text 0 or 1 (OFF or ON)
12 TEXT_UNDERLINED Underlined text 0 or 1 (OFF or ON)
13 TEXT_ATTRIBUTES Control of functions 9,10,11,12 grouped (bits can be combined by using logical 'or' of bits) nb:- bits 0-3 and 8-15 are reserved 16, 32, 64, 128 or (BOLD, ITALIC, INVERSE, UNDERLINED)

Single parameter short-cuts for the txt_Set(..) functions

Function Syntax Function Action value
txt_FGcolour(colour) Set the text foreground colour Colour 0-65535
txt_BGcolour(colour) Set the text background colour Colour 0-65535
txt_FontId(id) Set the required font (0 = system font)
txt_Width(multiplier) Set the text width multiplier 1 to 16
txt_Height(multiplier) Set the text height multiplier 1 to 16
txt_Xgap(pixelcount) Set the pixel gap between characters 0 to n
txt_Ygap(pixelcount) Set the pixel gap between lines 0 to n
txt_Delay(millisecs) Set the delay between character printing (Default 0 msec)
txt_Opacity(mode) Selects whether or not the 'background' pixels are drawn (default mode is OPAQUE) 0 or 1 (TRANSPARENT or OPAQUE)
txt_Bold(mode) Embolden text 0 or 1 (OFF or ON)
txt_Italic(mode) Italic text 0 or 1 (OFF or ON)
txt_Inverse(mode) Inverted text 0 or 1 (OFF or ON)
txt_Underlined(mode) Underlined text 0 or 1 (OFF or ON)
txt_Attributes(value) Control of functions 9, 10, 11, 12 grouped (bits can be combined by using logical 'OR' of bits) nb:- bits 0-3 and 8-15 are reserved 16, 32, 64, 128 or (BOLD, ITALIC, INVERSE, UNDERLINED)

Syntax: txt_Set(function, value);

Argument Description
function The function number determines the required action for various text control functions. Usually a constant, but can be a variable, array element, or expression. There are pre-defined constants for each of the functions.
value A variable, array element, expression or constant holding a value for the selected function.

Returns: None

Graphics Functions

gfx_Cls

Clear the screen using the current background colour

Syntax: gfx_Cls();

Returns: None

Example

// This example clears the entire display using colour DARKGRAY
gfx_BGcolour(DARKGRAY);
gfx_Cls();

gfx_ChangeColour

Changes all oldColour pixels to newColour within the clipping area.

Syntax: gfx_ChangeColour(oldColour, newColour);

Argument Description
oldColour specifies the sample colour to be changed within the clipping window.
newClour specifies the new colour to change all occurrences of old colour within the clipping window.

Returns: None

Example

// This example prints a test string, forces the clipping area to the extent
// of the text that was printed, then changes the background colour.
func main()
    txt_Width(3);
    txt_Height(5);
    gfx_MoveTo(8,20);
    print("TEST"); // print the string
    gfx_SetClipRegion(); // force clipping area to extents of text
                        // just printed.
    gfx_ChangeColour(BLACK, RED); // test change of background colour
    repeat forever
endfunc

gfx_Circle

Draws a circle with centre point x1, y1 with radius r using the specified colour.

Syntax: gfx_Circle(x, y, radius, colour);

Argument Description
x, y specifies the center of the circle.
rad specifies the radius of the circle.
colour specifies the colour of the circle.

Returns: None

Example

// assuming PEN_SIZE is OUTLINE
gfx_Circle(50, 50, 30, 0x001F);
// This example draws a BLUE circle outline centred
// at x=50, y=50 with a radius of 30 pixel units.

Note

The default PEN_SIZE is set to OUTLINE, however, if PEN_SIZE is set to SOLID, the circle will be drawn filled, if PEN_SIZE is set to OUTLINE, the circle will be drawn as an outline. If the circle is drawn as SOLID, the outline colour can be specified with gfx_OutlineColour(...). If OUTLINE_COLOUR is set to 0, no outline is drawn.

gfx_CircleFilled

Draws a SOLID circle with centre point x1, y1 with radius using the specified colour. The outline colour can be specified with gfx_OutlineColour(...). If OUTLINE_COLOUR is set to 0, no outline is drawn.

Syntax: gfx_CircleFilled(x, y, rad, colour);

Argument Description
x, y specifies the center of the circle.
rad specifies the radius of the circle.
colour specifies the colour of the circle.

Returns: None

Example

// This example draws a filled RED circle with a YELLOW outline
// at x=25, y=25 with a radius of 10 pixel units.
gfx_OutlineColour(0xFFE0);
gfx_CircleFilled(25,25,10, 0xF800);

Note

The PEN_SIZE is ignored, the circle is always drawn SOLID.

gfx_Line

Draws a line from x1,y1 to x2,y2 using the specified colour. The line is drawn using the current object colour. The current origin is not altered. The line may be tessellated with the gfx_LinePattern(...) function.

Syntax: gfx_Line(x1, y1, x2, y2, colour);

Argument Description
x1, y1 Specifies the starting coordinates of the line.
y2, y2 Specifies the ending coordinates of the line.
colour Specifies the colour of the line

Returns: None

Example

// This example draws a RED line from x1=10, y1=10 to x2=100, y2=100
gfx_Line(100, 100, 10, 10, 0xF800);

gfx_Hline

Syntax: gfx_Hline(y, x1, x2, colour);

Argument Description
y Specifies the vertical position of the horizontal line.
x1, x2 Specifies the horizontal end points of the line.
colour Specifies the colour of the horizontal line.

Returns: None

Example

// This example draws a fast RED horizontal line at y=50, from x1=10 to x2=80
gfx_Hline(50, 10, 880, 0xF800);

gfx_Vline

Draws a fast vertical line from y1 to y2 at horizontal co-ordinate x using colour.

Syntax: gfx_Vline(x, y1, y2, colour);

Argument Description
x Specifies the horizontal position of the vertical line.
y1, y2 Specifies the vertical end points of the line.
colour Specifies the colour of the vertical line.

Returns: None

Example

// This example draws a fast RED vertical line at x=20, from y1=30 to y2=70
gfx_Vline(20, 30, 70, 0xF800);

gfx_Rectangle

Draws a rectangle from x1, y1 to x2, y2 using the specified colour. The line may be tessellated with the gfx_LinePattern(...) function.

Syntax: gfx_Rectangle(x1, y1, x2, y2, colour);

Argument Description
x1, y1 Specifies the top left corner of the rectangle.
x2, y2 Specifies the bottom right corner of the rectangle.
colour Specifies the colour of the rectangle.

Returns: None

Example

// This example draws a GREEN rectangle from x1=10, y1=10 to x2=30, y2=30
gfx_Rectangle(10, 10, 30, 30, 0x07E0); // assuming PEN_SIZE is OUTLINE

Note

The default PEN_SIZE is set to OUTLINE, however, if PEN_SIZE is set to SOLID, the rectangle will be drawn filled, if PEN_SIZE is set to OUTLINE, the rectangle will be drawn as an outline. If the rectangle is drawn as SOLID, the outline colour can be specified with gfx_OutlineColour(...). If OUTLINE_COLOUR is set to 0, no outline is drawn. The outline may be tessellated with the gfx_LinePattern(...) function.

gfx_RectangleFilled

Draws a SOLID rectangle from x1, y1 to x2, y2 using the specified colour. The line may be tessellated with the gfx_LinePattern(...) function. The outline colour can be specified with gfx_OutlineColour(...). If OUTLINE_COLOUR is set to 0, no outline is drawn. The outline may be tessellated with the gfx_LinePattern(...) function.

Syntax: gfx_RectangleFilled(x1, y1, x2, y2, colour);

Argument Description
x1, y1 specifies the top left corner of the rectangle.
x2, y2 specifies the bottom right corner of the rectangle.
colour specifies the colour of the rectangle.

Returns: None

Example

// This example draws a filled RED rectangle with a YELLOW outline
// from x1=30,y1=30 to x2=80,y2=80
gfx_OutlineColour(0xFFE0);
gfx_RectangleFilled(30,30,80,80, 0xF800);

Note

The PEN_SIZE is ignored, the rectangle is always drawn SOLID.

gfx_Polyline

Plots lines between points specified by a pair of arrays using the specified colour. The lines may be tessellated with the gfx_LinePattern(...) function. gfx_Polyline can be used to create complex raster graphics by loading the arrays from serial input or from MEDIA with very little code requirement.

Syntax: gfx_Polyline(n, vx, vy, colour);

Argument Description
n specifies the number of elements in the x and y arrays specifying the vertices for the polyline.
vx specifies the addresses of the storage of the array of elements for the x coordinates of the vertices.
vy specifies the addresses of the storage of the array of elements for the y coordinates of the vertices.
colour Specifies the colour for the lines

Returns: None

Example

#inherit "4DGL_16bitColours.fnc"

var vx[20], vy[20];

func main()
    // This example draws a simple scene.
    vx[0] := 36; vy[0] := 110;
    vx[1] := 36; vy[1] := 80;
    vx[2] := 50; vy[2] := 80;
    vx[3] := 50; vy[3] := 110;

    vx[4] := 76; vy[4] := 104;
    vx[5] := 85; vy[5] := 80;
    vx[6] := 94; vy[6] := 104;

    vx[7] := 76; vy[7] := 70;
    vx[8] := 85; vy[8] := 76;
    vx[9] := 94; vy[9] := 70;

    vx[1 0] := 110; vy[10] := 66;
    vx[11] := 110; vy[11] := 80;
    vx[12] := 100; vy[12] := 90;
    vx[13] := 120; vy[13] := 90;
    vx[14] := 110; vy[14] := 80;

    vx[15] := 101; vy[15] := 70;
    vx[16] := 110; vy[16] := 76;
    vx[17] := 119; vy[17] := 70;

    // house
    gfx_Rectangle(6,50,66,110,RED);         // frame
    gfx_Triangle(6,50,36,9,66,50,YELLOW);   // roof
    gfx_Polyline(4, vx, vy, CYAN);          // door

    // man
    gfx_Circle(85, 56, 10, BLUE);           // head   
    gfx_Line(85, 66, 85, 80, BLUE);         // body
    gfx_Polyline(3, vx+4, vy+4, CYAN);      // legs
    gfx_Polyline(3, vx+7, vy+7, BLUE); // arms

    // woman
    gfx_Circle(110, 56, 10, PINK); // head
    gfx_Polyline(5, vx +10, vy+10, BROWN); // dress
    gfx_Line(104, 104, 106, 90, PINK); // left arm
    gfx_Line(112, 90, 116, 104, PINK); // right arm
    gfx_Polyline(3, vx+15, vy+15, SALMON); // dress

    repeat forever

endfunc

gfx_Polygon

Plots lines between points specified by a pair of arrays using the specified colour. The last point is drawn back to the first point, completing the polygon. The lines may be tessellated with the gfx_LinePattern(...) function. gfx_Polygon can be used to create complex raster graphics by loading the arrays from serial input or from MEDIA with very little code requirement.

Syntax: gfx_Polygon(n, vx, vy, colour);

Argument Description
n specifies the number of elements in the x and y arrays specifying the vertices for the polyline.
vx specifies the addresses of the storage of the array of elements for the x coordinates of the vertices.
vy specifies the addresses of the storage of the array of elements for the y coordinates of the vertices.
colour Specifies the colour for the lines

Returns: None

Example

var vx[7], vy[7];

func main()
    // This example draws a simple polygon.
    vx[0] := 10; vy[0] := 10;
    vx[1] := 35; vy[1] := 5;
    vx[2] := 80; vy[2] := 10;
    vx[3] := 60; vy[3] := 25;
    vx[4] := 80; vy[4] := 40;
    vx[5] := 35; vy[5] := 50;
    vx[6] := 10; vy[6] := 40;
    gfx_Polygon(7, vx, vy, RED);
    repeat forever
endfunc

gfx_Triangle

Draws a triangle outline between vertices x1,y1 , x2,y2 and x3,y3 using the specified colour. The line may be tessellated with the gfx_LinePattern(...) function.

Syntax: gfx_Triangle(x1, y1, x2, y2, x3, y3, colour);

Argument Description
x1, y1 specifies the first vertices of the triangle.
x2, y2 specifies the second vertices of the triangle.
x3, y3 specifies the third vertices of the triangle.
colour Specifies the colour for the triangle.

Returns: None

Example

// This example draws a CYAN triangular outline with vertices at 10,10 30,10 20,30
gfx_Triangle(10,10,30,10,20,30,0xFFE0);

gfx_Dot()

Draws a pixel at at the current origin using the current object colour

Syntax: gfx_Dot();

Returns: None

Example

// This example draws a RED pixel at 40,50
gfx_MoveTo(40,50);
gfx_ObjectColour(0xF800);
gfx_Dot();

gfx_Bullet

Draws a circle or 'bullet point' with radius r at at the current origin using the current object colour.

Syntax: gfx_Bullet(radius);

Argument Description
radius specifies the radius of the bullet.

Returns: None

Example

// assuming PEN_SIZE is TRANSPARENT and OBJECT_COLOUR is WHITE
// This example draws a WHITE circle outline at the current origin with a radius of 5 pixels
gfx_MoveTo(50,50);
gfx_Bullet(5);

Note

The default PEN_SIZE is set to OUTLINE, however, if PEN_SIZE is set to SOLID, the circle will be drawn filled, if PEN_SIZE is set to OUTLINE, the circle will be drawn as an outline. If the circle is drawn as SOLID, the outline colour can be specified with gfx_OutlineColour(...).

gfx_OrbitInit

Sets up the internal pointers for the gfx_Orbit(..) result variables. The &x_orb and &y_orb parameters are the addresses of the variables or array elements that are used to store the result from the gfx_Orbit(..) function.

Syntax: gfx_OrbitInit(&x_dest, &y_dest);

Argument Description
&x_dest, &y_dest specifies the addresses of the storage locations for the orbit calculation.

Returns: None

Example

// This example sets the variables that will receive the result from a gfx_Orbit function call
var targetX, targetY;
gfx_OrbitInit(&targetX, &targetY)

gfx_Orbit

Sets Prior to using this function, the destination address of variables for the calculated coordinates must be set using the gfx_OrbitInit(..) function. The gfx_Orbit(..) function calculates the x, y coordinates of a distant point relative to the current origin, where the only known parameters are the angle and the distance from the current origin. The new coordinates are calculated and then placed in the destination variables that have been previously set with the gfx_OrbitInit(..) function.

Syntax: gfx_Orbit(angle, distance);

Argument Description
angle specifies the angle from the origin to the remote point. The angle is specified in degrees.
distance specifies the distance from the origin to the remote point in pixel units.

Returns: None

Example

var targetX, targetY;
gfx_OrbitInit(&targetX, &targetY);
gfx_MoveTo(30, 30);
gfx_Bullet(5)           // mark the start point with a small WHITE circle
gfx_Orbit(30, 50);      // calculate a point 50 pixels away from origin at
                        // 30 degrees
gfx_CircleFilled(targetX,targetY,3,0xF800); // mark the target p oint
                                            // with a RED circle

Note

Result is stored in the variables that were specified with the gfx_OrbitInit(..) function.

gfx_PutPixel

Draws a pixel at position x,y using the specified colour.

Syntax: gfx_PutPixel(x, y, colour);

Argument Description
x, y specifies the screen coordinates of the pixel.
colour Specifies the colour of the pixel.

Returns: None

Example

// This example draws a WHITE pixel at x=32, y=32
gfx_PutPixel(32, 32, 0xFFFF);

gfx_GetPixel

Reads the colour value of the pixel at position x,y.

Syntax: gfx_GetPixel(x, y);

Argument Description
x, y specifies the screen coordinates of the pixel colour to be returned.

Returns: The 8 or 16bit colour of the pixel (default 16bit).

Example

// This example prints 1234, the colour of the pixel that was previously placed.
gfx_PutPixel(20, 20, 1234);
r := gfx_GetPixel(20, 20);
print(r);

gfx_MoveTo

Moves the origin to a new position.

Syntax: gfx_MoveTo(xpos, ypos);

Argument Description
xpos specifies the horizontal position of the new origin.
ypos specifies the vertical position of the new origin.

Returns: None

Example

// This example moves the origin to x=10, y=20 and draws a pixel.
gfx_MoveTo(10, 20);
gfx_Dot();

gfx_MoveRel

Moves the origin to a new position relative to the old position.

Syntax: gfx_MoveRel(xoffset, yoffset);

Argument Description
xoffset specifies the horizontal offset of the new origin.
yoffset specifies the vertical offset of the new origin.

Returns: None

Example

// This example draws a pixel using the current object colour at x=5, y=17
gfx_MoveTo(10, 20);
gfx_MoveRel(-5, -3);
gfx_Dot();

gfx_IncX

Increment the current X origin by 1 pixel unit. The original value is returned before incrementing. The return value can be useful if a function requires the current point before insetting occurs.

Syntax: gfx_IncX();

Returns: The current X origin before the increment.

Example

var n;
gfx_MoveTo(20,20);
n := 96;
// This example draws a simple rounded vertical gradient.
while (n--)
    gfx_ObjectColour(n/3);
    gfx_Bullet(2);
    gfx_IncX();
wend

gfx_IncY

Increment the current Y origin by 1 pixel unit. The original value is returned before incrementing. The return value can be useful if a function requires the current point before insetting occurs.

Syntax: gfx_IncY();

Returns: The current Y origin before the increment.

Example

var n;
gfx_MoveTo(20,20);
n := 96;
// This example draws a simple horizontal gradient using lines. 
while (n--)
    gfx_ObjectColour(n/3);
    gfx_LineRel(20, 0);
    gfx_IncY();
wend

gfx_LineTo

Draws a line from the current origin to a new position. The Origin is then set to the new position. The line is drawn using the current object colour. The line may be tessellated with gfx_LinePattern(...)

Syntax: gfx_LineTo(xpos, ypos);

Argument Description
xpos specifies the horizontal position of the line end as well as the new origin.
ypos specifies the vertical position of the line end as well as the new origin.

Returns: None

Example

// Draws a line between x1=10, y1=20 and x2=60, y2=70
gfx_MoveTo(10, 20);
gfx_LineTo(60, 70);
// The new origin is now set at x=60, y=70

gfx_LineRel

Draws a line from the current origin to a new position. The line is drawn using the current object colour. The current origin is not altered. The line may be tessellated with the gfx_LinePattern(...) function.

Syntax: gfx_LineRel(xpos, ypos);

Argument Description
xpos specifies the horizontal end point of the line.
ypos specifies the vertical end point of the line.

Returns: None

Exampple

// Draws a tessellated line using the current object colour between 10,20 and 50,50.
gfx_LinePattern(0b1100110011001100);
gfx_MoveTo(10, 20);
gfx_LineRel(50, 50);

Note

That gfx_LinePattern(0); must be used after this to return line drawing to normal solid lines.

gfx_BoxTo

Draws a rectangle from the current origin to the new point using the current object colour. The top left corner is anchored by the current origin (x1, y1), the bottom right corner is specified by x2, y2.

Syntax: gfx_BoxTo(x2, y2);

Argument Description
x2, y2 specifies the diagonally opposed corner of the rectangle to be drawn, the top left corner (assumed to be x1, y1) is anchored by the current origin.

Returns: None

Examples

gfx_MoveTo(40,40);
n := 10;
// This example draws 2 boxes, anchored from the current origin.
while (n--)
    gfx_BoxTo(50,50);
    gfx_BoxTo(30,30);
wend

Note

The default PEN_SIZE is set to OUTLINE, however, if PEN_SIZE is set to SOLID, the rectangle will be drawn filled, if PEN_SIZE is set to OUTLINE, the rectangle will be drawn as an outline. If the circle is drawn as SOLID, the outline colour can be specified with gfx_OutlineColour(...). If OUTLINE_COLOUR is set to 0, no outline is drawn.

gfx_SetClipRegion

Forces the clip region to the extent of the last text that was printed, or the last image that was shown.

Syntax: gfx_SetClipRegion();

Returns: None

Example

#constant NUMCOLOURS 6
var colour[NUMCOLOURS];
func main()
    var n, x, y, colr, x1, y1, x2, y2, w, h;
    // the colour set for the random pixels
    colour[0] := RED;
    colour[1] := GREEN;
    colour[2] := BLUE;
    colour[3] := YELLOW;
    colour[4] := CYAN;
    colour[5]:=MAGENTA;

    txt_Width(5); 
    txt_Height(7);
    gfx_MoveTo(6,20);
    txt_Bold(ON);
    txt_FGcolour(1);        // start with a very dark blue
    print("TEST");          // print the string
    gfx_SetClipRegion();    // force clipping area to extents of text just printed
    x1 := peekB(CLIP_LEFT_POS);     // get the cliiping area to local vars
    y1 := peekB(CLIP_TOP_POS);
    x2 := peekB(CLIP_RIGHT_POS);
    y2 := peekB(CLIP_BOTTOM_POS);
    w  := x2 - x1;                  // get t he width and height
    h  := y2 - y1;
    txt_MoveCursor(10,0);
    txt_FGcolour(SALMON);
    print("x1=",x1," y1=",y1," nx2=",x2," y2=",y2); // print the clipping region
    txt_FGcolour(GREEN);
    pause(1000);
    // This example prints a test string, forces the clipping area to the extent of
    // text that was printed, then changes the text colour randomly, pixel by pixel.
    repeat
        if (!*TIMER0)                       // if timer has expired
            *TIMER0 := 5000;                // reset the timer
            colr := colour[n++%NUMCOLOURS]; // select new colour every 5 seconds.
            txt_MoveCursor(14,0);
            print([DEC5ZB] n);              // print n
        endif
        x := ABS(RAND()%w) + x1; // get random pixel position within the clip region
        y := ABS(RAND()%h) + y1;
        if (gfx_GetPixel(x,y)) gfx_PutPixel(x,y, colr);  // update any non black pixels
    forever
endfunc

gfx_ClipWindow

Specifies a clipping window region on the screen such that any objects and text placed onto the screen will be clipped and displayed only within that region. For the clipping window to take effect, "Clipping" setting must be enabled separately using gfx_Set(CLIPPING, ON) or the shortcut gfx_Clipping(ON).

Syntax: gfx_ClipWindow(x1, y1, x2, y2);

Argument Description
x1, y1 specifies the horizontal and vertical position of the top left corner of the clipping window.
x2, y2, specifies the horizontal and vertical position of the bottom right corner of the clipping window.

Returns: None

Example

var n;
gfx_ClipWindow(10, 10, 50, 50 )
n := 50000;
// This example will draw 50000 random colour pixels,
// only the pixels within the clipping area will be visible.
while(n--)
    gfx_PutPixel(RAND()%100, RAND()%100, RAND());
wend
repeat forever

gfx_FocusWindow

Sets the display hardware GRAM access registers to the clipping area ready for reading or writing. The function also returns the pixel count of the selected area.

Syntax: gfx_FocusWindow();

Returns: The pixel count of the selected area.

Examples

// This example prints a test string, forces the clipping area to the extent
// of the text that was printed, then after a delay, fills the region with a colour.
// The count of pixels in the region is then shown.
func main()
    var pixelcount;
    txt_Height(4);
    gfx_MoveTo(20,20);
    print("TEST"); // print a string.
    gfx_SetClipRegion();    // force the clipping region to the
                            // extent of the
    Pixelcount:= gfx_FocusWindow(); // get the count, focus on region.
    pause(1000);
    disp_BlitPixelFill(BLUE, pixelcount); // fill the region.
    print(pixelcount, " pixels n"); //show the pixel count of region.
    repeat forever
endfunc
// This example fills a small screen area, then outputs each pixel of the selected area to the COM port.
func main()
    var pixels;
    putstr("Open the terminal n");
    putstr("Type any key to start n");
    while(serin() < 0); // wait for key from terminal before start
    gfx_ClipWindow(40,40,44,44); // within a small block on display
    pixels:=gfx_FocusWindow(); //focus GRAM and get pixel count
    disp_BlitPixelFill(0x4142, pixels); // fill the area, using ASCII
                                        // values so we can read easy
    disp_BlitPixelsToCOM(); // send all the pixel values to com port
    print("Done!");
    repeat forever
endfunc

gfx_Set

Given a function number and a value, set the required graphics control parameter, such as size, colour, and other parameters. (see the Single parameter short-cuts for the gfx_Set functions below).

Parameter/Function Table

# Predefined Name Description Value
0 PEN_SIZE Set the draw mode for gfx_LineTo, gfx_LineRel, gfx_Dot, gfx_Bullet and gfx_BoxTo (default mode is OUTLINE) nb:- pen size is set to OUTLINE for normal operation 0 or SOLID
1 or OUTLINE
1 BACKGROUND_COLOUR Set the screen background colour Colour, 0 - 65535
2 OBJECT_COLOUR Generic colour for gfx_LineTo(...), gfx_LineRel(...), gfx_Dot(), gfx_Bullet(...) and gfx_BoxTo(...) Colour, 0 - 65535
3 CLIPPING Turns clipping on/off. The clipping points are set with gfx_ClipWindow(...) 0 or ON
1 or OFF
4 TRANSPARENT_COLOUR Not implemented on GOLDELOX-GFX2 n/a
5 TRANSPARENCY Not implemented on GOLDELOX-GFX2 n/a
6 FRAME_DELAY Set the inter frame delay for media_Video(..) 0 to 255 msec
7 SCREEN_MODE Set required screen behaviour/orientation 0 or LANDSCAPE
1 or LANDSCAPE_R
2 or PORTRAIT
3 or PORTRAIT_R)
8 OUTLINE_COLOUR Outline colour for rectangles and circles. (Set to 0 for no effect) Colour, 0 - 65535
9 CONTRAST Set contrast value, 0 = display off, 1-16 = contrast level ( only available on GOLDELOX Engineering samples, must be implemented in users code for GOLDELOX-GFX2 with external initialisation tables, refer to individual display driver data sheets) 0 or OFF
1 to 16 for levels
10 LINE_PATTERN Sets the line draw pattern for line drawing. If set to zero, lines are solid, else each '1' bit represents a pixel that is turned off. See code examples for further reference. 0 bits for pixels ON
1 bits for pixels OFF
11 COLOUR_MODE Sets 8 or 16bit colour mode (only available on GOLDELOX Engineering samples, must be implemented in users code for GOLDELOX-GFX2 with external initialisation tables, refer to individual display driver data sheets) 0 or COLOUR16
1 or COLOUR8

Shorthand gfx_Set(..) Functions

Function Syntax Function Action Value
gfx_PenSize(mode) Set the draw mode for gfx_LineTo(...), gfx_LineRel(...), gfx_Dot(), gfx_Bullet(...) and gfx_BoxTo(...). Default, pen size is set to OUTLINE for normal operation 0 or SOLID
1 or OUTLINE
gfx_BGcolour(colour) Set the screen background colour Colour, 0 - 65535
gfx_ObjectColour(colour) Generic colour for gfx_LineTo(...), gfx_LineRel(...), gfx_Dot(), gfx_Bullet(...) and gfx_BoxTo(...) Colour, 0 - 65535
gfx_Clipping(mode) Turns clipping on/off. The clipping points are set with gfx_ClipWindow(...) 0 or ON
1 or OFF
gfx_FrameDelay(delay) Set the inter frame delay for media_Video(...) 0 to 255 msec
gfx_ScreenMode(mode) Set required screen behaviour/orientation. 0 or LANDSCAPE
1 or LANDSCAPE_R
2 or PORTRAIT
3 or PORTRAIT_R)
gfx_OutlineColour(colour) Outline colour for rectangles and circles. (set to 0 for no effect) Colour, 0 - 65535
gfx_Contrast(value) Set contrast value, 0 = display off, 1-16 = contrast level.(only available on GOLDELOX Engineering samples, must be implemented in users code for GOLDELOX-GFX2 with external initialisation tables, refer to individual display driver data sheets) 0 or OFF
1 to 16 for levels
gfx_LinePattern(pattern) Sets the line draw pattern for line drawing. If set to zero, lines are solid, else each '1' bit represents a pixel that is turned off. See code examples for further reference 0 bits for pixels ON
1 bits for pixels OFF
gfx_ColourMode(mode) Sets 8 or 16bit colour mode(only available on GOLDELOX Engineering samples, must be implemented in users code for GOLDELOX-GFX2 with external initialisation tables, refer to individual display driver data sheets) 0 or COLOUR16
1 or COLOUR8

Syntax: gfx_Set(function, value);

Argument Description
function The function number determines the required action for various graphics control functions. Usually a constant, but can be a variable, array element, or expression. There are pre-defined constants for each of the functions.
value A variable, array element, expression or constant holding a value for the selected function.

Returns: None

Display I/O Functions

These functions allow direct display access for fast blitting operations.

disp_Init

The GOLDELOX-GFX2 needs to be aware of all the display registers and how to access them. The initialisation and the state machine tables are necessary to achieve this. Refer to the individual display data sheet available from the display manufacturer.

Note

For hardware platform modules such as uOLED-96-G1(GFX), uOLED-128-G1(GFX), etc the disp_Init(,,) is not needed. The modules are factory set-up with their display specific configurations.

** Syntax **: disp_Init(initTable, stateMachine);

Argument Description
initTable A reference to the device initialisation table which is stored as a data statement.
stateMachine A reference to the device state machine table which is stored as a data statement.

Returns: None

Example

//============================================================================
// SD1339 Device Initialisation Procedure
//============================================================================

#DATA
byte initTable
// first 4 bytes of table hold
// display access information
    _DI SPLAY_X_MAX,                // width 1
    _DISPLAY_X_MAX,                 // height 1
    WRITE_GRAM,                     // write access register
    WRITE_GRAM,                     // read access register
    // now the display initialisation table
    0, DISPLAY_OFF, // Display OFF
    1, REMAP_COLOUR_SETTINGS, _65K_COLOURS, // Set Re map/Color Depth
    1, DISPLAY_START_LINE, 0x00,
    1, DISPLAY_OFFSET, 0x80,
    1, DUTY_CYCLE, 0x7F,                        // Duty 127+1 (0x80)
    0, DISPLAY_NORMAL,                          // Normal display
    1, MAS TER_CONFIGURE, 0x8E,                 // Set Master Configuration
    1, CONTRAST_MASTER, 0x0F,                   // Set master contrast
    3, CONTRAST_RGB, 0xFF, 0xFF, 0xFF,          // Set contrast current
    1, SET_VCOMH, 0x1F,                         // Set VcomH
    1, POWERSAVE_MODE, 0x05                     // Power saving mode
    3, PRECHARGE_VOLTAGE_RGB, 0x1C, 0x1C, 0x1C, // Set pre charge
                                                // voltage
    1, PHASE_PRECHARGE, 0x11,                   // Set pre & dis_charge
    1, CLOCK_FREQUENCY, 0x80,                   // clock & frequency (0xF0)
    0, SLEEP_MODE_OFF,                          // Display on
    2, SET_COLUMN_ADDRESS, 0x00, 0x7F,          // set full screen
    2, SET_ROW_ADDRESS, 0x00, 0x7F, 0xFF
#END

//=========================================================================
// GRAM access state machine for SSD1339 (on uOLED-128 G1(GFX))
//=========================================================================

#DATA
byte stateMachine
    WRITE_CONTROL_CONSTANT, SET_COLUMN_ADDRESS,
    WRITE_DATA_BYTE, _VX1,
    WRITE_DATA_BYTE, _VX2,
    WRITE_CONTROL_CONSTANT, SET_ROW_ADDRESS,
    WRITE_DATA_BYTE, _VY1,
    WRITE_DATA_BYTE, _VY2,
    WRITE_EXIT
#END

func main()
    disp_Init(initTable, stateMachine); // initialise the display
    txt_MoveCursor(0, 2);
    txt_Bold(1);
    txt_Italic(1);
    txt_Set(TEXT_COLOUR, WHITE);
    print("4D LABS");
    repeat forever
end

disp_WriteControl

Sends a single byte (which is the lower 8 bits of value) to the display bus. Refer to individual data sheets for the display for more information. This function is used to extend the capabilities of the user code to gain access to the the display hardware.

Syntax: disp_WriteControl(value);

Argument Description
value Specifies the value to be written to the display control register. Only the lower 8 bits are sent to the display.

Returns: None

Example

// a function to utilise the hardware circle draw function
// on a SD1339 display driver IC
#constant DRAW_CIRCLE 0x86
func myCircle(var x, var y, var r, var fillcolour, var linecolour)
    disp_WriteControl(DRAW_CIRCLE); // Draw Circle command
    disp_WriteByte(x);              // set x1
    disp_WriteByte(y);              // set y1
    disp_WriteByte(r);              // set x2
    disp_WriteByte(linecolour>>8);  // set outline col our Hi byte
    disp_WriteByte(linecolour);     // set outline colour Lo byte
    disp_WriteByte(fillcolour>>8);  // set fill colour Hi byte
    disp_WriteByte(fillcolour);     // set fill colour Lo byte
endfunc

disp_WriteByte

Sends a single byte (which is the lower 8 bits of value) to the display bus. Refer to individual data sheets for the display for more information. This function is used to extend the capabilities of the user code to gain access to the the display hardware.

Syntax: disp_WriteByte(value);

Argument Description
value Specifies the value to be written to the display data register. Only the lower 8 bits are sent to the display.

Returns: None

Example

// a function to utilise the hardware circle draw function
// on a SD1339 display driver IC
#constant DRAW_CIRCLE 0x86
func myCircle(var x, var y, var r, var fillcolour, var linecolour)
    disp_WriteControl(DRAW_CIRCLE); // Draw Circle command
    disp_WriteByte(x);              // set x1
    disp_WriteByte(y);              // set y1
    disp_WriteByte(r);              // set x2
    disp_WriteByte(linecolour>>8);  // set outline col our Hi byte
    disp_WriteByte(linecolour);     // set outline colour Lo byte
    disp_WriteByte(fillcolour>>8);  // set fill colour Hi byte
    disp_WriteByte(fillcolour);     // set fill colour Lo byte
endfunc

disp_WriteWord

Sends a 16 bit value to the display bus. Since the GOLDELOX-GFX2 display data bus is 8bits wide, the HIGH byte is sent first followed by the LOW byte. Refer to individual data sheets for the display for more information. This function is used to extend the capabilities of the user code to gain access to the the display hardware.

Syntax: disp_WriteWord(value);

Argument Description
value Specifies the value to be written to the display data register. Only the lower 8 bits are sent to the display.

Returns: None

Example

// a function to utilise the hardware circle draw function
// on a SD1339 display driver IC
#constant DRAW_CIRCLE 0x86
func myCircle(var x, var y, var r, var fillcolour, var linecolour)
    disp_WriteControl(DRAW_CIRCLE); // Draw Circle command
    disp_WriteByte(x);              // set x1
    disp_WriteByte(y);              // set y1
    disp_WriteByte(r);              // set x2
    disp_WriteWord(linecolour);     // set outline colour
    disp_WriteWord(fillcolour);     // set fill colour
endfunc

disp_ReadByte

Reads a byte from the display after an internal register or GRAM access has been set.

Syntax: disp_ReadByte();

Returns: Returns the 8bit data that was read from the display. Only the lower 8bits are valid.

Example

gfx_ClipWindow(40,40,44,44);    // within a small block on the display
gfx_FocusWindow();              // focus GRAM
pixel_Hi:= dispReadByte();      // read hi byte of first pixel
pixel_Lo:= dispReadByte();      // read lo byte of first pixel

disp_ReadWord

Reads a 16bit word from the display after an internal register or GRAM access has been set.

Syntax: disp_ReadWord();

Returns: Returns the 16bit data that was read from the display.

Example

gfx_ClipWindow(40,40,44,44);    // within a small block on the display
gfx_FocusWindow();              // focus GRAM
pixel := dispReadWord();        // read 1st pixel, HI:LO order

disp_BlitPixelFill

Fills a preselected GRAM screen area with the specified colour.

Syntax: disp_BlitPixelFill(colour, count);

Argument Description
colour Specifies the colour for the fill.
count Specifies the number of pixels to fill.

Returns: None

Example

gfx_ClipWindow(40,40,79,79);            // select a block on the display
count := gfx_FocusWindow();             // focus GRAM
myvar:=dispBlitPixelFill(RED,count);    // paint the area red

disp_BlitPixelsToMedia

Write the selected GRAM area to the media at the current media address.

Syntax: disp_BlitPixelsToMedia();

Returns: Returns the number of pixels that were written to the media.

Example

func main()
    var n; 
    while(!media_Init())
        putstr("Insert Card");          // init the card 
        pause(200);
        gfx_Cls(); 
        pause(200);
    wend 
    media_SetSector(0x0020,0x0000);     // we're going to write here
    gfx_ClipWindow(40,40,55,55);        // select 16x16 block on the display 
    n:=gfx_FocusWindow();               // focus GRAM
    while(n--) 
        disp_BlitPixelFill(RAND(),1);   // fill area with random pixels
    wend 
    n:=disp_BlitPixelsToMedia ();       // save it to sector
    print(n*2," bytes written\n"); 
    print("Done!");
    repeat forever 
endfunc

disp_BlitPixelsFromMedia

Read the required number of pixels consecutively from the current media stream and write them to the current display GRAM address. For 8bit colour mode, each pixel comprises a single 8bit value. For 16bit colour, each pixel is composed of 2 bytes, the high order byte is read first, the low order bye is read next.

Syntax: disp_BlitPixelsFromMedia(pixelcount);

Argument Description
pixelcount Specifying the number of pixels to be consecutively read from the media stream.

Returns: None

Example

media_SetAdd(0x0002, 0x3C00);   // point to required area of an image
disp_BlitPixelsFromMedia(20);   // write the next 20 pixels from
                                // media to the current GRAM pointer.

disp_SkipPixelsFromMedia

Skip the required number of pixels consecutively from the current media stream, discarding them. For 8bit colour mode, each pixel comprises a single 8bit value. For 16bit colour, each pixel is composed of 2 bytes, the high order byte is read first, the low order bye is read next.

Syntax: disp_SkipPixelsFromMedia(pixelcount);

Argument Description
pixelcount Specifying the number of pixels to be consecutively skipped from the media stream.

Returns: None

Example

disp_SkipPixelsFromMedia(20);   // skip the next 20 pixels from media
disp_BlitPixelsFromMedia(20);   // write the next 20 pixels from
                                // media to the current GRAM pointer.

disp_BlitPixelsToCOM

Write the selected GRAM area to the serial (COM) port.

Syntax: disp_BlitPixelsToCOM();

Returns: Returns the number of pixels that were written to the serial port. |

Example

// After downloading this program, open the Workshop Terminal and
// type any key to start the pixel upload. 
func main()
    var pixels; 
    putstr("Open the terminal\n");
    putstr("Type any key to start\n"); 
    while(serin() < 0);                 // wait for a key from terminal
                                        // before we start 
    gfx_ClipWindow(40,40,44,44);        // within a small block on the
                                        // display 
    pixels:=gfx_FocusWindow();          // focus GRAM and get pixel count
                                        // of area 
    disp_BlitPixelFill(0x4142, pixels); // fill the area using ASCII
                                        // values so we can read easily 
    disp_BlitPixelsToCOM();             // write the pixels to the COM port
    print("Done!"); 
    repeat forever
endfunc

disp_BlitPixelsFromCOM

Fills a preselected GRAM screen area with the specified colour.

Syntax: disp_BlitPixelsFromCOM(mode);

Argument Description
mode mode = 0 - specifies 16 bit pixels mode = pointer : specifies pointer to 16 element colour lookup table for each 4bit pixel value

Returns: None

Examples

// After downloading this program, open the Workshop Terminal and
// type 2 keys per pixel for 16bit colour mode. The colour will be
// determined by the ASCII values of the keys, it is only a simple
// test and you have very little control of what colour is actually
// displayed - it is simply a demo of disp_BlitPixelsFromCOM action.
// If all is good, you will see the GRAM area being filled with
// pixels.
// NB if using 8bit colour mode, the correct register in the display
// must be set to 8 bit mode, if you have done this correctly, you
// will notice that it only requires 1 key to write each pixel.
// If this is not done correctly, only half the gram area will be
// filled.

func main()
    gfx_ClipWindow(40,40,59,59);    // writing to a 40x40 block on the
                                    // display.
    gfx_FocusWindow();              // NB first focus is just so we can
                                    // get pixel count of area.
    print("Filling ",*IMG_PIXEL_COUNT," pixels");
    gfx_FocusWindow();
    disp_BlitPixelsFromCOM(0);      // get pixels from serial port,
    while(*IMG_PIXEL_COUNT);        // wait till all the pixels come in
    txt_MoveCursor(8,5); print("Done!");
    repeat forever
endfunc
// the next example uses disp_BlitPixelsFromCOM in 4bit CLUT mode
var CLUT1[16];
// If the argument to disp_BlitPixelsFromCOM(...) is non zero, it is
// expected to be a pointer to a 16 element colour lookup table in
// RAM.
// After downloading this program, open the Workshop Terminal and
// Each key typed will produce 2 pixels from the CLUT. The colour
// will be determined by the values in the CLUT, it is only a simple
// test and you have very little control of what colour is actually
// displayed - it is simply a demo of disp_BlitPixelsFromCOM action.
// If all is good, you will see the GRAM area being filled with
// pixels.

func main()
    // CLUT is set for monochrome mode, however
    // it can contain a colour set if required
    CLUT1[0] := 0x0000; // BLACK
    CLUT1[1] := 0x1082; // GRAY1
    CLUT1[2] := 0x2104; // GRAY2
    CLUT1[3] := 0x3186; // GRAY3
    CLUT1[4] := 0x4208; // GRAY4
    CLUT1[5] := 0x5285; // GRAY5
    CLUT1[6] := 0x630C; // GRAY6
    CLUT1[7] := 0x738E; // GRAY7
    CLUT1[8] := 0x8410; // GRAY8
    CLUT1[9] := 0x9492; // GRAY9
    CLUT1[10] := 0xA514; // GRAY10
    CLUT1[11] := 0xB596; // GRAY11
    CLUT1[12] := 0xC618; // GRAY12
    CLUT1[13] := 0xD69A; // GRAY13
    CLUT1[14] := 0xE71C; // GRAY14
    CLUT1[15] := 0xF79E; // ALMOST WHITE

    gfx_ClipWindow(40,40,59,59);    // writing to a 40x40 block on
                                // the display.
    gfx_FocusWindow();              // NB first focus is just so we can get
                                // pixel count of area.
    print("Filling ",*IMG_PIXEL_COUNT," pixels");
    gfx_FocusWindow();
    disp_BlitPixelsFromCOM(CLUT1);  // get pixels from COM port, 4 bit
                                // CLUT mode mode
    while(*IMG_PIXEL_COUNT);
    txt_MoveCursor(8,5);
    print("Done!");
    repeat forever
endfunc

Media (SD/SDHC card or Serial Flash chip) Functions

The media can be SD/SDHC, microSD or serial (NAND) flash device interfaced to the GOLDELOX-GFX2 SPI port.

media_Init

Initialise a uSD/SD/SDHC memory card for further operations. The SD card is connected to the SPI (serial peripheral interface) of the GOLDELOX-GFX2 chip.

Syntax: media_Init();

Returns:

  • 1 if memory card is present and successfully initialised
  • 0 if no card is present or not able to initialise

Example

// Waits for SD card to be inserted and initialised, flashing a message if no SD card detected.
while (!media_Init())
    gfx_Cls();
    pause(300);
    putstr(Please insert SD card);
    pause(300);
wend

Note

The media can be SD/SDHC, microSD or serial (NAND) flash device interfaced to the GOLDELOX-GFX2 SPI port.

media_SetAdd

Set media memory internal Address pointer for access at a non sector aligned byte address.

Syntax: media_SetAdd(HIword, LOword);

Argument Description
HIword specifies the high word (upper 2 bytes) of a 4 byte media memory byte address location.
LOword specifies the low word (lower 2 bytes) of a 4 byte media memory byte address location.

Returns: None

Example

// sets the media address to byte 513 (which is sector #1, 2nd byte in sector) for subsequent operations.
media_SetAdd(0, 513);

media_SetSector

Set media memory internal Address pointer for sector access.

Syntax: media_SetSector(HIword, LOword);

Argument Description
HIword specifies the high word (upper 2 bytes) of a 4 byte media memory byte address location.
LOword specifies the low word (lower 2 bytes) of a 4 byte media memory byte address location.

Returns: None

Example

// Sets the media address to the 11th sector for subsequent operations
// (which is also byte address 5120)
media_SetSector(0, 10);

media_ReadByte

Returns the byte value from the current media address. The internal byte address will then be internally incremented by one.

Syntax: media_ReadByte();

Returns: byte value

Example

var LObyte, HIbyte;
if (media_Init())                       // initialises the media
    media_SetAdd(0, 510);               // sets the media byte address to 510
    LObyte := media_ReadByte();         // reads the last 2 bytes from sector 0
    HIbyte := media_ReadByte();
    print([HEX2]HIbyte,[HEX2]LObyte);
    // If the card happens to be FAT formatted, the result will be “AA55”.
    // The media internal address is internally incremented for each of the byte operations.
endif
repeat forever

media_ReadWord

Returns the word value (2 bytes) from the current media address. The internal byte address will then be internally incremented by one. If the address is not aligned, the word will still be read correctly.

Syntax: media_ReadWord();

Returns: word value

Example

var myword;
if (media_Init())               // initialises the media
    media_SetAdd(0, 510);       // sets the media byte address to 510
    myword := media_ReadWord(); // reads the last word from sector 0
    print([HEX4]myword);    // If the card happens to be formatted, the result will be “AA55”
endif
repeat forever

media_WriteByte

Writes a byte to the current media address that was initially set with media_SetSector(...);

Syntax: media_WriteByte(byte_val);

Argument Description
byte_val The lower 8 bits specifies the byte to be written at the current media address location.

Returns: Non zero if write was successful.

Example

// This example initialises the media, writes some bytes to the required sector,
// then prints the result from the required location.
var n, char;
while (media_Init()==0);            // wait if no SD card detected
media_SetSector(0, 2);              // at sector 2
//media_SetAdd(0, 1024);            // (alternatively, use media_SetAdd(),
                                    // lower 9 bits
while (n < 10)
    media_WriteByte(n++ +'0');      // write ASCII '0123456789' to the
wend                                // first 10 locations.

to(MDA); putstr("Hello World");     // now write a ascii test string
media_WriteByte('A');               // write a further 3 bytes
media_WriteByte('B');
media_WriteByte('C');
media_WriteByte(0);                 // terminate with zero
media_Flush();                      // we're finished, close the sector

media_SetAdd(0, 1024+5);            // set the starting byte address
while(char:=media_ReadByte()) putch(char);  // print result, starting
                                            // from '5'
repeat forever

Note

Due to design constraints on the GOLDELOX-GFX2, there is no way of writing bytes or words within a media sector without starting from the beginning of the sector. All writes will start at the beginning of a sector and are incremental until the media_Flush() function is executed, or the sector address rolls over to the next sector. Any remaining bytes in the sector will be padded with 0xFF, destroying the previous contents. An attempt to use the media_SetAdd(..) function will result in the lower 9 bits being interpreted as zero. If the writing rolls over to the next sector, the media_Flush() function is issued automatically internally.

media_WriteWord

Writes a byte to the current media address that was initially set with media_SetSector(...).

Syntax: media_WriteWord(word_val);

Argument Description
word_val The 16 bit word to be written at the current media address location.

Returns: Non zero if write was successful.

Example

// This example initialises the media, writes some words to the required sector,
// then prints the result from the required location.
var n;
while (media_Init()==0);        // wait until a good SD card is found
n:=0;
media_SetAdd(0, 1536);          // set the starting byte address
while(n++ < 20)
    media_WriteWord(RAND());    // write 20 random words to first 20
wend                            // word locations.
n:=0;
while (n++ < 20)
    media_WriteWord(n++*1000);  // write sequence of 1000*n to next 20
wend                            // word locations.
media_Flush();                  // we're finished, close the sector

media_SetAdd(0, 1536+40);       // set the starting byte address
n:=0;
while(n++<8)                    // print result of fist 8 multiplication calcs
    print([HEX4] media_ReadWord()," n");
wend
repeat forever

Note

Due to design constraints on the GOLDELOX-GFX2, there is no way of writing bytes or words within a media sector without starting from the beginning of the sector. All writes will start at the beginning of a sector and are incremental until the media_Flush() function is executed, or the sector address rolls over to the next sector. Any remaining bytes in the sector will be padded with 0xFF, destroying the previous contents. An attempt to use the media_SetAdd(..) function will result in the lower 9 bits being interpreted as zero. If the writing rolls over to the next sector, the media_Flush() function is issued automatically internally.

media_Flush

After writing any data to a sector, media_Flush() should be called to ensure that the current sector that is being written is correctly stored back to the media else write operations may be unpredictable.

Syntax: media_Flush();

Returns: None

Example

See the media_WriteByte(..) and media_WriteWord(..) examples.

media_Image

Displays an image from the media storage at the specified co-ordinates. The image address is previously specified with the media_SetAdd(..) or **media_SetSector(...) function**. If the image is shown partially off screen, it is necessary to enable clipping for it to be displayed correctly.

Syntax: media_Image(x, y);

Argument Description
x, y specifies the top left position where the image will be displayed.

Returns: None

Example

// This example draws an image at several positions, showing the effects of clipping.
while (media_Init()==0);        // wait if no SD card detected
media_SetAdd(0x0001, 0xDA00);   // point to the books04 image
media_Image(10, 10);
gfx_Clipping(ON);               // turn off clipping to see the difference
media_Image(-12, 50);           // show image off screen to the left
media_Image(50, -12);           // show image o ff screen at the top
repeat forever

Note

It is assumed that the media has been loaded with the example images in GFX2DEMO.GCI loaded at sector 0. This can be loaded using the Graphics Composer (directly onto the memory card).

media_Video

Displays a video clip from the media storage device at the specified co-ordinates. The video address location in the media is previously specified with the media_SetAdd(..) or media_SetSector(...) function. If the video is shown partially off screen, it is necessary to enable clipping for it be displayed correctly. Note that showing a video blocks all other processes until the video has finished showing. See the media_VideoFrame(...) functions for alternatives.

Syntax: media_Video(x, y);

Argument Description
x, y specifies the top left position where the video clip will be displayed.

Returns: None

Example

// This example plays a video clip at several positions, showing the effects of clipping.
while (media_Init()==0);            // wait if no SD card detected
media_SetAdd(0x0001, 0x3C00);       // point to the 10 gear clip
media_Video(10, 10);
gfx_Clipping(ON);                   // turn off clipping to see the difference
media_Video(-12, 50);               // show video off screen to the left
media_Video(50, -12);               // show video off screen at the top
repeat forever

Note

It is assumed that the media has been loaded with the example video in GFX2DEMO.GCI loaded at sector 0. This can be loaded using the Graphics Composer directly onto the memory card.

media_VideoFrame

Displays a video from the media storage device at the specified co-ordinates. The video address is previously specified with the media_SetAdd(..) or media_SetSector(...) function. If the video is shown partially off screen, it is necessary to enable clipping for it be displayed correctly. The frames can be shown in any order. This function gives you great flexibility for showing various icons from an image strip, as well as showing videos while doing other tasks

Syntax: media_VideoFrame(x, y, frameNumber);

Argument Description
x, y specifies the top left position where the video clip will be displayed.
frameBuffer Specifies the required frame to be shown.

Returns: None

Examples

// This example shows how to display frames as required while possibly doing other tasks.
// Note that the frame timing (although not noticeable in this small example) is not correct
// as the delay commences after the image frame is shown, therefore adding the display
// overheads to the frame delay.

var frame;

while (media_Init()==0);        // wait if no SD card detected
media_SetAdd(0x0002, 0x3C00);   // point to the 10 gear image

repeat
    frame := 0;                 // start at frame 0
    repeat
        media_VideoFrame(30,30, frame++);   // display a frame
        pause(peekB(IMAGE_DELAY));          // pause for the time given in
                                            // the image header
    until(frame == peekW(IMG_FRAME_COUNT)); // loop until we've
                                            // shown all the frames
forever                                     // do it forever
// This example employs a timer for the framing delay, and shows the same movie simultaneously
// running forward and backwards with time left for other tasks as well. A number of videos
// (or animated icons) can be shown simultaneously using this method.


var framecount, frame, delay, colr;
frame := 0;
// show the first frame so we can get the video header info
// into the system variables, and then to our local variables.
media_VideoFrame(30,30, 0);

framecount := peekW(IMG_FRAME_COUNT);       // we can now set some local
                                            // values.
delay := peekB(IMAGE_DELAY);                // get the frame count and delay
repeat
    repeat
        pokeW(TIMER0, dela y);              // set a timer
        media_VideoFrame(30,30, frame++);   // show next frame
        gfx_MoveTo(64,35);
        print([DEC2Z] frame);               // print the frame number
        media_VideoFrame(30,80, framecount frame);  // show movie
                                                    // backwards.
        gfx_MoveTo(64,85);
        print([DEC2Z] framecount-frame);    // print the frame number
        if ((frame & 3) == 0)
            gfx_CircleFilled(80,20,2,colr); // a blinking circle fun
            colr := colr ^ 0xF800;          // alternate colour,
        endif                               // BLACK/RED using XOR
        // do more here if required
        while(peekW(TIMER0));               // wait for timer to expire
    until(frame == peekW(IMG_FRAME_COUNT));
    frame := 0;
forever

Note

It is assumed that the media has been loaded with the example video in GFX2DEMO.GCI loaded at sector 0. This can be loaded using the Graphics Composer directly onto the memory card.

Flash Memory Chip Functions

The functions in this section only apply to serial SPI (NAND) flash devices interfaced to the GOLDELOX-GFX2 SPI port.

flash_SIG

If a FLASH storage device is connected to the SPI port, and has been correctly initialised with the spi_Init(...) function, the Electronic Signature of the device can be read using this function. The only devices supported so far on the GOLDELOX-GFX2 are the M25Pxx range of devices which are 512Kbit to 32Mbit (2M x 8) Serial Flash Memory.

Syntax: flash_SIG();

Returns: Release from Deep Power-down, and Read Electronic Signature. Only the low order byte is valid, the upper byte is ignored.

Note

This functions only apply to serial SPI (NAND) flash devices interfaced to the GOLDELOX-GFX2 SPI port.

flash_ID

If a FLASH storage device is connected to the SPI port, and has been correctly initialised with the spi_Init(...) function, the memory type and capacity from the flash device can be read using this function. The only devices supported so far on the GOLDELOX-GFX2 are the M25Pxx range of devices which are 512Kbit to 32Mbit (2M x 8) Serial Flash Memory.

Syntax: flash_ID();

Returns: Reads the memory type and capacity from the serial FLASH device. Hi byte contains type, and low byte contains capacity. Refer to the device data sheet for further information.

Note

This functions only apply to serial SPI (NAND) flash devices interfaced to the GOLDELOX-GFX2 SPI port.

flash_BulkErase

If a FLASH storage device is connected to the SPI port, and has been correctly initialised with the spi_Init(...) function, the FLASH device can be completely erased using this function. The only devices supported so far on the GOLDELOX-GFX2 are the M25Pxx range of devices which are 512Kbit to 32Mbit (2M x 8) Serial Flash Memory.

Syntax: flash_BulkErase();

Returns: None

Note

  • This functions only apply to serial SPI (NAND) flash devices interfaced to the GOLDELOX-GFX2 SPI port.
  • Erases the entire flash media device. The function returns no value, and the operation can take up to 80 seconds depending on the size of the flash device.

flash_BlockErase

Syntax: flash_BlockErase(blockAddress);

Argument Description
blockAddress The address of the 64k FLASH block to be erased.

Returns: Erases the required block in a FLASH media device. The function returns no value, and the operation can take up to 3 milliseconds.

Note

This functions only apply to serial SPI (NAND) flash devices interfaced to the GOLDELOX-GFX2 SPI port.

SPI Control Functions

The SPI functions in this section apply to any general-purpose SPI device.

spi_Init

Sets up the GOLDELOX-GFX2 SPI port to communicate with SPI devices.

spi_Init

Syntax: spi_Init(speed, input_mode, output_mode);

Argument Description
speed Sets the speed of the SPI port.
input_mode Sets the input mode of the SPI port.
output_mode Sets the output mode of the SPI port.

Returns: None

Note

The SPI functions in this section are not necessary when using the memory card or serial flash chips interfaced to the SPI port. The SPI functions in this section are relevant to those devices other than the memory card and the serial flash chip used for media access.

spi_Read

This function allows a raw unadorned byte read from the SPI device.

Syntax: spi_Read();

Returns: Returns a single data byte from the SPI device.

Note

The Chip Select line (SDCS) is lowered automatically.

spi_Write

This function allows a raw unadorned byte write to the SPI device.

Syntax: spi_Write(byte);

Argument Descrption
byte specifies the data byte to be sent to the SPI device.

Returns: None

Note

The Chip Select line (SDCS) is lowered automatically.

spi_Disable

This function raises the Chip Select (SDCS) line of the SPI device, disabling it from further activity. The CS line will be automatically lowered next time the SPI functions spi_Read() or spi_Write(...) are used, and also by action of any of the media_ functions.

Syntax: spi_Disable();

Returns: None

Serial (UART) Communication Functions

serin

Receives a character from the Serial Port COM0. The transmission format is: No Parity, 1 Stop Bit, 8 Data Bits (N,8,1). The default Baud Rate is 115,200 bits per second or 115,200 baud. The baud rate can be changed under program control by using the setbaud(...) function.

Syntax: serin();

Returns:

  • -1 if no character is available
  • -2 if a framing error or over-run has occurred (auto cleared)
  • 0 or a positive value (up to 255) for a valid character received

Example

var char;
char := serin();            // test the com port
if (char >= 0)              // if a valid character is received
    process(char);          // process the character
endif

serout

Transmits a single byte from the Serial Port COM0. The transmission format is: No Parity, 1 Stop Bit, 8 Data Bits (N,8,1). The default Baud Rate is 115,200 bits per second or 115,200 baud. The baud rate can be changed under program control by using the setbaud(...) function.

Syntax: serout(char);

Argument Description
char specifies the data byte to be sent to the serial port.

Returns: None

setbaud

Use this function to set the required baud rate. The default baud rate is 115,200 baud. There are pre-defined baud rate constants for most common baud rates:

Pre Defined Constant Rate Divisor Error % Actual Baud Rate
BAUD_110 27272 0.00% 110
BAUD_300 9999 0.00% 300
BAUD_600 4999 0.00% 600
BAUD_1200 2499 0.00% 1200
BAUD_2400 1249 0.00% 2400
BAUD_4800 624 0.00% 4800
BAUD_9600 312 -0.16% 9584
BAUD_14400 207 0.16% 14423
BAUD_19200 155 0.16% 19230
BAUD_31250 95 0.00% 31250
MIDI 95 0.00% 31250
BAUD_38400 77 0.16% 38461
BAUD_56000 53 -0.79% 55555
BAUD_57600 51 0.16% 57692
BAUD_115200 25 0.16% 115384
BAUD_128000 12 1.90% 130434
BAUD_256000 11 -2.34% 250000
BAUD_300000 10 0.00% 300000
BAUD_375000 8 0.00% 375000
BAUD_500000 6 0.00% 500000
BAUD_600000 4 0.00% 600000

The baud rate divisor is calculated with the following formula, and can be used when non-constant defined baud rates are required:

Rate Divisor = (3000000 / baud ) – 1

The rate divisor of 200000baud for example, would be (3000000/200000)-1 = 14, so setbaud(14) will give you 200K baud rate.

Baud rates each have degree of accuracy for several reasons. The actual baud rate you would receive and relevant error% compared to the setting value, can be calculated.

ActualBaud = 3000000/(trunc(3000000/RequiredBaud))

Example for 115200 is, 3000000/115200 = 26.041, Trucated is 26. 3000000/26 = 115384 (rounded). Error% therefore is % difference between 115200 and 115384, therefore 0.16% It is desirable to only use a baud rate between 2 devices which has a difference of typically < 2%. Note both devices will have a degree of error, not just this 4D Processor, both need to be considered.

Syntax: setbaud(rate);

Argument Description
rate specifies the baud rate divisor value or pre-defined constant

Returns: None

com_AutoBaud

The com_AutoBaud function expects to receive an ascii 'U' (0x55) within a pre-determined time. If the function is successful, the COM port is configured to the closest speed possible, and the selected baud rate value is returned.

Syntax: com_AutoBaud(timeout);

Argument Description
timeout Sets the timeout delay for autobaud detection.

Returns: The divisor value selected for the baud rate generator, else returns 0.

Example

while (br:=com_AutoBaud(500))           // if we receive a 'U' ok
    doMyComms(); // now connected at br baud rate
wend

com_Init

This is the initialisation function for the serial communications buffered service. Once initialised, the service runs in the background capturing and buffering serial data without the user application having to constantly poll the serial port. This frees up the application to service other tasks. The service also transparently keeps a checksum (see the com_Checksum() function) which can be employed if required for robust error checking.

MODES OF OPERATION

No qualifier – simple ring buffer (aka circular queue)

If the qualifier is set to zero, the buffer is continually active as a simple circular queue. Characters when received from the host are placed in the circular queue (at the 'head' of the queue) Bytes may be removed from the circular queue (from the 'tail' of the queue) using the serin() function. If the tail is the same position as the head, there are no bytes in the queue, therefore serin() will return -1, meaning no character is available, also, the com_Count() function can be read at any time to determine the number of characters that are waiting between the tail and head of the queue. If the queue is not read frequently by the application, and characters are still being sent by the host, the head will eventually catch up with the tail setting the internal COM_FULL flag (which can be read with the com_Full() function) . Any further characters from the host are are now discarded, however, all the characters that were buffered up to this point are readable. This is a good way of reading a fixed size packet and not necessarily considered to be an error condition. If no characters are removed from the buffer until the COM_FULL flag (which can be read with the com_Full() function) becomes set, it is guaranteed that the bytes will be ordered in the buffer from the start position, therefore, the buffer can be treated as an array and can be read directly without using serin() at all. In the latter case, the correct action is to process the data from the buffer, re-initialise the buffer with the com_Init(..) function, or reset the buffered serial service by issuing the com_Reset() function (which will return serial reception to polled mode) , and send an acknowledgement to the host (traditionally a ACK or 6) to indicate that the application is ready to receive more data and the previous 'packet' has been dealt with, or conversely, the application may send a negative acknowledgement to indicate that some sort of error occurred, or the action could not be completed (traditionally a NAK or 15) .

If any low level errors occur during the buffering service (such as framing or over-run) the internal COM_ERROR flag will be set (which can be read with the com_Error() function).

Note

The COM_FULL flag will remain latched to indicate that the buffer did become full, and is not reset (even if all the characters are read) until the com_Init(..) or com_Reset() function is issued.

Using a qualifier

If a qualifier character is specified, after the buffer is initialised with com_Init(..) , the service will ignore all characters until the qualifier is received and only then initiate the buffer write sequence with incoming data. After that point, the behaviour is the same as above for the 'non qualified' mode.

Variable packet length

If the bufsize argument is set to zero, the first byte received (or the 2nd byte if a qualifier is employed) sets the count of characters that are to be received before the COM_FULL flag (which can be read with the com_Full() function) becomes set. This allows a host to send variable length packets, which will only alert the application that the packet is ready after the correct number of characters has been received. The number of bytes to be expected can be read using the com_PacketSize() function, which will indicate the packet size. In this mode, it is wise to make the buffer as large as possible due to the fact that if the 'size' parameter sent by the host is corrupted, more characters than expected (up to 255) can be receive inadvertently, crashing into any other program variables above the array.

Syntax: com_Init(buffer, bufsize, qualifier);

Argument Description
buffer specifies the address of a buffer used for the background buffering service.
bufsize specifies the byte size of the user array provided for the buffer (each array element holds 2 bytes). If the buffer size is zero, a buffer of 63 words (126 bytes) should be provided for automatic packet length mode (see below). Buffer of 63 words (126 bytes) is the maximum buffer size possible.
qualifier specifies the qualifying character that must be received to initiate serial data reception and buffer write. A zero (0x00) indicates no qualifier to be used.

Returns: None

Examples

//=======================================================================================
// Example #1 - no qualifier
// use the Workshop Terminal to test this example
// note that if 7 characters are exceeded, no more
// characters will be accepted as there is no action
// to take care of the com_Full situation
//=======================================================================================
var combuf[10];                                 // a buffer for up to 20 characters
putstr("Default 115.2kb");
com_Init(combuf, 7, 0);                         // initialize small circular queue of 7
                                                // bytes, no qualifier
repeat

    if (com_Count())                            // if there is a character available
        serout(serin());                        // echo it back t o host
    endif

    txt_MoveCursor(2,0);
    print("\ncom_Error ",[DEC2ZB] com_Error()); // 1 if error
    print("\ncom_Count ",[DEC2ZB] com_Count()); // show current count
    print("\ncom_Full ",[DEC2ZB] com_Full());   // 1 if full
    pause(1000);                                // a delay to slow things up        
forever
//=======================================================================================
// Example #2 - no qualifier
// use the Workshop Terminal to test this example
// note that if 7 characters are exceeded, the
// com_Full situat ion occurs, but is reset
// once all the pending characters are read
//=======================================================================================
var combuf[10];                                 // a buffer for up to 20 characters
putstr("Default 115.2kb");
com_Init(combuf, 7, 0);                         // initialize circular queue of 7 bytes,
                                                // no qualifier
repeat

    if (com_Count())                            // if there is a character available
        serout(serin());                        // echo it back to host
    endif
    txt_MoveCursor(2,0);
    print("\ncom_Error ",[DEC2ZB] com_Error()); // 1 if error
    print("\ncom_Count ",[DEC2ZB] com_Count()); // show current count
    print("\ncom_Full ",[DEC2ZB] com_Full());   // 1 if full
    pause(1000);                                // a delay to slow things up
    // if the buffer overflowed, and we have read
    // all the characters, then reset the buffer
    if (com_Full() & (com_Count() == 0)) com_Init(combuf, 7, '0');

forever
//=======================================================================================
// Example #3 - using qualifier (a colon character)
// use the Workshop Terminal to test this example
// note that once the qualifier is received, if 7
// characters are exceeded, the buffer is reset
// once all the pending characters are read
//=======================================================================================
var combuf[10];                                 // a buffer for up to 20 characters
putstr("Default 115.2kb");
com_Init(combuf, 7, ':');                       // initialize circular queue of 7 bytes,
                                                // ':' as qualifier
repeat
    if(com_Count())                             // if there is a character available
        serout(serin());                        // echo it back to host
    endif
    txt_MoveCursor(2,0);
    print("\ncom_Sync ",[DEC2ZB] com_Sync());   // 1 if qualified
    print("\ncom_Error ",[DEC2ZB] com_Error()); // 1 if error
    print("\ncom_Count ",[DEC2ZB] com_Count()); // show current count
    print("\ncom_Full ",[DEC2ZB] com_Full());   // 1 if fu ll
    pause(1000);                                // a delay to slow things up

    // if the buffer overflowed, if we have read
    // all the characters, then reset the buffer
    if (com_Full() & (com_Count() == 0)) com_Init(combuf, 5, ':');
forever
//=======================================================================================
// Example #4 - using qualified packet
// use the Workshop Terminal to test this example note that nothing
// happens until the qualifier followed by 10 characters is received.
// Then an acknowledgement is issued to the host, and the buffer is reset
//=======================================================================================
var combuf[10], chr;                                // a buffer for up to 20 characters
putstr("Default 115.2kb");
com_Init(combuf, 10, ':');                          // init buffer 10 bytes to receive

repeat
    repeat
        txt_MoveCursor(2,0);
        print("\ncom_Sync ",[DEC2ZB] com_Sync());   // 1 if qualified
        print("\ncom_Error ",[DEC2ZB] com_Error()); // 1 if error
        print("\ncom_Count ",[DEC2ZB] com_Count()); // show count
        print("\ncom_Full ",[DEC2ZB] com_Full());   // 1 if full
        pause(1000);                                // a delay to slow things up
    until(com_Full());                              // just loop until buffer is full

    // buffer is full, echo the characters
    while (chr:=serin()) >=0) serout(chr);          // echo back characters
    to(COM0); print(" OK n");                       // send an acknowledgement
    com_Init(combuf, 10, ':');                      // re init buffer 10 bytes to recei ve
forever                                             // do it all again
//=======================================================================================
// Example #5 - using qualified variable length packet use the Workshop Terminal to test
//
// NB: to make the example possible when just using a terminal to emulate a packet, the
// 'space bar' (ascii 32) is used to set the size of the packet to 32 characters, so you
// must send the':' qualifier then press the space bar (you will then see '32' for the
// packet size) then type 32 chars to complete the action. Under normal circumstances,
// the host will send whatever packet size is
//
// Note that nothing happens until the qualifier ':' followed by the space bar (to set
// the packet then the 32 characters are received. After the packet is received, the
// acknowledgement is issued to the host, and the buffer is reset.
// 
// This example also shows the running checksum calculation.
//=======================================================================================

putstr("Default 115.2kb")

repeat
    com_Init(combuf, 0, ':');                               // init. buffer 10 bytes to receive
    repeat
        txt_MoveCursor(2,0);
        print(" ncom_Sync ",[DEC2ZB] com_Sync());           // 1 if qualified
        print("\ncom_Error ",[DEC2ZB] com_Error());         // 1 if error
        print("\ncom_PacketSize ",[DEC2ZB] com_PacketSize());
        print("\ncom_Count ",[DEC2ZB] com_Count());         // show count
        print("\ncom_Checksum ",[HEX2ZB] com_Checksum());   // checksum
        print("\ncom_Full ",[DEC2ZB] com_Full());           // 1 if full
        pause(1000);                                        // a delay to slow things up
    until(com_Full());                                      // just loop until buffer is full
            // buffer is full, echo the characters
    while ( (chr:=serin()) >= 0 ) serout(chr);              // echo back the chars
    to(COM0); print(" OK n");                               // send a simple acknowledgement
forever                                                     // do it all ag ain

Note

  • Transparent to normal operation, a check summing system is operating. If the host sends one extra character (usually at the end of the packet) which is the negated value of the addition of all the previous characters in the packet , the checksum (which can be read with the com_Checksum() function) should read zero. com_Checksum() will retain the most recent value until com_Init(..) is called again to reset the buffer system. Note that the checksum is only valid after the com_Full() function reports a buffer full situation (ie the packet is fully received).

  • com_PacketSize() will indicate how large the packet is ONLY after the packet reception has started. Although it is usually not required to know the packet size until the packet has actually been read, if it is a requirement, the count is available as soon as com_Count() becomes non zero.

com_Reset

Resets the serial communications buffered service and returns it to the default polled mode.

Syntax: com_Reset();

Retruns: None

Example

com_Reset(); // reset to polled mode

com_Count

Can be read at any time (when in buffered communications is active) to determine the number of characters that are waiting in the buffer.

Syntax: com_Count();

Returns: Current count of characters in the communications buffer.

Example

n := com_Count(); // get the number of chars available in the buffer

com_Full

If the queue is not read frequently by the application, and characters are still being sent by the host, the head will eventually catch up with the tail setting the COM_FULL flag which is read with this function. If this flag is set, any further characters from the host are discarded, however, all the characters that were buffered up to this point are readable.

Syntax: com_Full();

Returns: 1 if buffer or queue has become full, or is overflowed, else returns 0

Example

if (com_Full() & (com_Count() == 0))
    com_Init(mybuf, 30, 0);             // buffer full, recovery
endif

com_Error

If any low level errors occur during the buffering service (such as framing or over-run) the internal COM_ERROR flag will be set which can be read with this function.

Syntax: com_Error();

Returns: 1 if any low level communications error occurred, else returns 0

Example

if(com_Error())                     // if there were low level comms errors,
    resetMySystem();                // take corrective action
endif

com_Sync

If a qualifier character is specified when using buffered communications, after the buffer is initialized with com_Init(..) , the service will ignore all characters until the qualifier is received and only then initiate the buffer write sequence with incoming data. com_Sync() is called to determine if the qualifier character has been received yet.

Syntax: com_Sync();

Returns: 1 if the qualifier character has been received, else returns 0.

Example

com_Sync(); // reset to polled mode

com_Checksum

Transparent to normal operation, a check summing system is operating. If the host sends one extra character as part of the packet (usually added at the end of the packet) which is the negated value of the addition of all the previous characters in the packet. Once the com_Full() function reports a buffer full situation (ie the packet is fully received) , the checksum can be read, and should read zero if the packet is not corrupted.

Syntax: com_Checksum();

Returns: 0 if checksum has been computed correctly.

Example

if(!com_Checksum())         // if checksum is ok
    processMyPacket();      // continue
else
    // do recovery action
endif

com_PacketSize

com_PacketSize() will indicate how large the packet is ONLY after the packet reception has started. Although it is usually not required to know the packet size until the packet has actually been read, if it is a requirement, the count is available as soon as com_Count() becomes non zero. If not in variable packet length mode, com_PacketSize() just returns the size of the specified buffer.

Syntax: com_PacketSize();

Returns: The size of a packet if in variable packet length mode, or just the size of the serial buffer if not variable packet length mode.

Example

If (!com_Count())
    print("Waiting....");
else
    print(com_PacketSize() com_Count()), bytes to go ""); 
endif

Sound and Tune (RTTTL) Functions

tune_Play

This function uses a variant of "Ring Tone Text Transfer Language" (RTTTL) developed by Nokia for ring tones. There are differences that need to be taken into account, and several additions that can be utilised. It is suggested to refer to the original format first. Here are some useful discussions:

With a little practice and minor modifications, most RTTTL tunes that can be downloaded off the web are playable with this function. Also, a wide range of sound effects can be made using standard RTTTL notation augmented with the additional 4DGL functions.

The 4DGL implementation:

  1. The "b=nnn" in 4DGL does not represent "beats per minute" (bpm), it represents "milliseconds per hemidemisemiquaver".

    e.g. 120 bpm is 2 beats per second = 128 demisemiquavers per second which is 7.8125msec per hemidemisemiquaver. Conversely, the default 4DGL value for b = 16msec per hemidemisemiquaver equates to 62.5 bpm.

  2. The original RTTTL format is a string divided into three sections: name, default value and data. While the 4DGL implementation does not have the name section.

  3. The 4DGL implementation does not require any spaces or colons anywhere.
  4. The 4DGL implementation allows default values to be changed anywhere in the string and does not need to be at the start.
  5. The optional default modifiers is a set of parameters separated by commas, where each value contains a key and a value separated by an '=' character, which describes certain defaults which will be adhered to during the execution of the ringtone string.

    d - duration, can be one of 1, 2, 4, 8, 16, 32 or 64 (64 = 1/64th, 1 = 1 whole unit).

    • 1 specifies a Semibreve (Whole Note),
    • 2 indicates it a Minim (Half Note),
    • 4 is a Crotchet (Quarter Note) etc up to 64 which is a hemidemisemiquaver (64th note).

    b - beat/tempo in milliseconds per demisemiquaver

    o - octave (scale) can be 4, 5, 6, or 7.

    If not specified, defaults are:

    • duration = 4 (same as d=4)
    • octave = 6 (same as o=6)
    • beat = 16 (same as b=16) close to 63bpm
4DGL extended default values:

r - set repeat point and counter (eg r=4)

  • min = 2, max = 255
  • default value = forever

p - set portamento value (eg p=5)

  • min = 1, max = 14
  • default value is 4

a - set arpeggiation step value (eg a=1)

  • min = 1, max = 16
  • default value is 1
4DGL extended commands associated with extended default values:

R - execute a repeat specified by r=. If no repeat count has been specified, the string will repeat forever

{ - turn portamento ON

} - turn portamento OFF (default)

+ - raise note as specified by arpeggiation step value

- - lower note as specified by arpeggiation step value

Syntax: tune_Play(tuneptr);

Argument Description
tuneptr Specifies a pointer to a data statement or a string constant containing RTTTL information.

Note

The argument passed to the tune_Play(...) function must be an ASCII string. If the string is passed as a pointer from a #DATA statement, it must be terminated with a zero (0x00). If a string is passed directly as a parameter, the '0' is automatically appended by the compiler as per normal strings.

Returns: None

Example

/*
 * This example shows how to use the RTTTL tunes to
 * generate complex sounds and music.
*/

#DATA
    // b=250
    byte Muppets "d=4,o=5,b=15,",
                "c6,c6,a,b,8a,b,g,p,c6,c6,a,8b,8a,8p,g.,p,e,e,g,
                8e,f,8c6,8c,8d,e,8e,8e,8p,8e,g,2p,c6,",
                "c6,a,b,8a,b,g,p,c6,c6,a,8b,a,g.,p,e,e,g,f,8e,
                8c6,8c,8d,e,8e,d,8d,c",0
    // part of haunted house theme
    byte HauntedHouse "d=4,o=5,b=20,",
                    "2a4,2e,2d#,2b4,2a4,2c,2d,2a#4,2e.,e,
                    1d#,2e.,d,2c.,b4,1a4", 0
    // simple scale with default settings
    byte SimpleScale "c,d,e,f,g,a,b,c7", 0
    // simple scale with default settings and portamento
    // Note the portamento speed change in the middle of the str ing,
    // and the curly braces that turn the portamento on and
    byte SimpleScaleP "b=50,{,c,d,e,f,p=7,g,a,},b,c7", 0
    // simple scale, much faster
    // note b=20 as default, so each note plays for 20msec when d=64
    byte Scale2 "d=64, c,d,e,f,g,a,b,c7", 0
    // simple scale, much faster with a repeat command set to 20
    // note b=20 as default, so each note plays for 20msec when d=
    // and we repeat 20 times
    byte ScaleRep "d=64,r=20,c,d,e,f,g,a,b,c7,R", 0
    // simple scale, at the fastest possible rate, repeat 200 times
    // note that b=1 and d=64 so each note plays for only 1msec
    byte ScaleRep2 "b=1,d=64,r=200,c,d,e,f,g,a,b,c7,R", 0
    // s imple scale using appregiation to increment the note step
    // note that commas can be left out to save space if there is no
    // indecision about delimit value
    byte ApprScale "a=1,c,+++++++++++ c,+++++++++++------------------------", 0
    // scale using appregiation to in crement the note step, and the
    // note step is larger
    // note that commas can be left out to save space if there is no
    // indecision about delimit value
    byte ApprScaleF "d=8,a=4,c,++++++++++++ c,++++++++++++------------------------", 0
    // same as above but demonst rates repeating instead of multiple
    // inc/dec operators
    // note that commas can be left out to save space if there is no
    // indecision about delimit value
    byte ApprScaleFR "d=8,a=4,c5,r=11,+,R,r=11, 11,--,R", 0
    // you can build your own scale sequencers
    byte COMPLEX_C "d=64,a=5,c4,r=8,+,R", 0
    byte COMPLEX_DSHARP "d=64,a=5,d#4,r=8,+,R", 0
    byte COMPLEX_G "d=64,a=5,g4,r=8,+,R", 0
    // just having a bit of fun
    byte DEMO "a=3,p= 3,o=5,d=4,b=5,
            {,a,r=20,+,R,},c,d=16,a=5,r=50,-,R, R",0 // forever
#END

//===============================================================================



#constant number_of_examples 13

var examples[number_of_examples];
var names[number_of_examples];

func main()
    var n;
    // pin_Set(SOUND, PIN_1); // sound on default pin
    // pin_Set(SOUND, PIN_
    // lookup table for the examples
    examples[0] := HauntedHouse;
    examples[1] := SimpleScale;
    examples[2] := SimpleScaleP;
    examples[3] := Scale2;
    examples[4] := ScaleRep;
    examples[5] := ScaleRep2;
    examples[6] := ApprScale;
    examples[7] := ApprScaleF;
    examples[8] := A pprScaleFR;
    examples[9] := COMPLEX_C;
    examples[10] := COMPLEX_DSHARP;
    examples[11] := COMPLEX_G;
    examples[12] := Muppets;
    // lookup table for the example names
    names[0] := "HauntedHouse";
    names[1] := "SimpleScale";
    names[2] := "Sim pleScaleP";
    names[3] := "Scale2";
    names[4] := "ScaleRep";
    names[5] := "ScaleRep2";
    names[6] := "ApprScale";
    names[7] := "ApprScaleF";
    names[8] := "ApprScaleFR";
    names[9] := "COMPLEX_C";
    names[10] := "COMPLEX_DSHARP";
    names[11] := "COMPLEX_G";
    names[12] := "Muppets";

    repeat
        n := 0;
        // play each demo, demonstrate multitasking while tune playing
        repeat
            gfx_Cls();
            txt_MoveCursor(0,8);
            tune_Play( examples[n] );
            txt_Set(TEXT_PRINTDELAY, 0);
            putstr( names[n++] );
            repeat
                txt_Set(TEXT_PRINTDELAY, 50);
                txt_MoveCursor(0,0);
                putstr("Playing");
                pause(150);
                txt_MoveCursor(0,0);
                putstr(" ");
            until (!(sys_Get(CONTROL) & PLAYING));// wait until the tune
                                                // string
            pause(1000); // then pause 5 seconds
        until (n == number_of_examples);

        gfx_Cls();
        txt_Set(TEXT_PRINTDELAY, 0);
        tune_Play( DEMO ); // last example plays forever
        putstr( "DEMO CONTINUOUS" );
        // the last demo endlessly loops, play for 10 seconds then pause
        pause(10000);
        tune_Pause();
        print("\nPaused....");
        pause(10000); // pause for 10 seconds
        tune_Continue(); // continue
        print("\nContinue....");
        pause(10000); // for 10 seconds
        tune_End(); // then end it
        print("\nEnd....");
        pause(10000); // wait for 10 seconds
    forever // then do it all again
endfunc

tune_Pause

Suspends any current tune from playing until a tune_Continue(), tune_Stop() or a new tune_Play("...") function is called. The oscillator is not stopped.

Syntax: tune_Pause();

Returns: None

Example: See example in tune_Play(..)

tune_Continue

Continues playing any previously stopped or paused tune.

Syntax: tune_Continue();

Returns: None

Example: See example in tune_Play(..)

tune_Stop

Pauses a tune and silences the oscillator until a tune_Continue(), tune_Stop(), tune_End() or a new tune_Play("...") function is called.

Syntax: tune_Stop();

Returns: None

Example: See example in tune_Play(..)

tune_End

Ends any current tune and resets the tune interpreter.

Syntax: tune_End();

Returns: None

Example: See example in tune_Play(..)

tune_Playing

Use this function to check for any current tunes being played. Returns 1 if tune is playing, 0 if no tune is playing.

Syntax: tune_Playing();

Returns: 1 if a tune is playing Returns: 0 if no tune is playing |

Example: See example in tune_Play(..)

beep

Simple utility to produce a single musical note for the required duration.

Syntax: beep(note, duration);

Argument Description
note A value (usually a constant) specifying the frequency of the note. Note could be between 0 and 64
duration Secifies the time in milliseconds that the note will be played for

Returns: None

Example

Beep(20, 50); // play note 20 for 50 milliseconds

General Purpose Functions

lookup8

Search a list of 8-bit constant values for a match with a search value key. If found, the index of the matching constant is returned in result, else result is set to 0. Thus, if the value is found first in the list, result is set to 1. If second in the list, result is set to 2 etc. If not found, result is returned with 0.

Syntax: lookup8(key, byteConstList);

Argument Description
key A byte value to search for in a fixed list of constants. The key argument can be a variable, array element, expression or constant.
byteConsList A comma separated list of constants and strings to be matched against key.

Returns: Index/Position of the matching constant starting with 1. 0 if 'key' doesn't exist

Example

func main()
    var key, r;

    key := 'a';
    r := lookup8(key, 0x4D, "abcd", 2, 'Z', 5);
    print("\nSearch value 'a' \nfound as index ", r);

    key := 5;
    r := lookup8(key, 0x4D, "abcd", 2, 'Z', 5);
    print("\nSearch value 5 \nfound at index ", r);
    putstr("\nScanning.. n");

    key := -12000;  // we will count from 12000 to +12000, only
                    // the hex ascii values will give a match value
    while (key <= 12000)
        r := lookup8(key, "0123456789ABCDEF" ); // hex lookup
        if (r) print([HEX1] r-1);   // only print if we got a match in the table
        key++;
    wend

    repeat forever
endfunc

Note

  • The list of constants cannot be re-directed.
  • This offers a versatile way for returning an index for a given value. This can be very useful for data entry filtering and parameter input checking and wherever you need to check the validity of certain inputs.
  • The entire search list field can be replaced with a single name if you use the $ operator in constant, eg: #constant HEXVALUES $"0123456789ABCDEF"

lookup16

Search a list of 16-bit constant values for a match with a search value key. If found, the index of the matching constant is returned in result, else result is set to 0. Thus, if the value is found first in the list, result is set to 1. If second in the list, result is set to 2 etc. If not found, result is returned with 0.

Syntax: lookup16(key, wordConstList);

Argument Description
key A word value to search for in a fixed list of constants. The key argument can be a variable, array element, expression or constant
wordConstList A comma separated list of constants to be matched against key.

Returns: Index/Position of the matching constant starting with 1. 0 if 'key' doesn't exist

Example

func main()
    var key, r;

    key := 5000;
    r := lookup16(key,5,10,20,50,100,200,500,1000,2000,5000,10000);
    //r := lookup16(key, LEGALVALS);

    if (r)
        print("\nSearch value 5000 \nfound at index ", r);
    else
        putstr("\nValue not found");
    endif

    print("\nOk"); // all done

    repeat forever
endfunc

Note

  • This offers a versatile way for returning an index for a given value. This can be very useful for data entry filtering and parameter input checking and wherever you need to check the validity of certain inputs.
  • The entire search list field can be replaced with a single name if you use the $ operator in constant, eg: #constant LEGALVALS $5,10,20,50,100,200,500,1000,2000,5000,10000

pause

Stop execution of the user program for a predetermined amount of time.

Syntax: pause(time);

Argument Description
time A value specifying the delay time in milliseconds.

Returns: None

Example

if (joystick() == FIRE)     // if fire button pressed
    pause(30)               // slow down the loop
emdif

System Registers Memory

8-bit Registers Memory Map

The following tables outline in detail the GOLDELOX 8-bit system registers and flags.

Label Address
DEC
Address
HEX
Usage Type
VX1 128 0x80 display hardware GRAM x1 pos SYSTEM
VY1 129 0x81 display hardware GRAM y1 pos SYSTEM
VX2 130 0x82 display hardware GRAM x2 pos SYSTEM
VY2 131 0x83 display hardware GRAM y2 pos SYSTEM
SYS_X_MAX 132 0x84 display hardware X res-1 SYSTEM
SYS_Y_MAX 133 0x85 display hardware Y res-1 SYSTEM
WRITE_GRAM_REG 134 0x86 display GRAM write address SYSTEM
READ_GRAM_REG 135 0x87 display GRAM read address SYSTEM
IMAGE_WIDTH 136 0x88 loaded image/animation width SYSTEM
IMAGE_HEIGHT 137 0x89 loaded image/animation height SYSTEM
IMAGE_DELAY 138 0x8A frame delay (if animation) USER
IMAGE_MODE 139 0x8B image/animation colour mode SYSTEM
CLIP_LEFT_POS 140 0x8C left clipping point setting USER
CLIP_TOP_POS 141 0x8D top clipping point setting USER
CLIP_RIGHT_POS 142 0x8E right clipping point setting USER
CLIP_BOTTOM_POS 143 0x8F bottom clipping point setting USER
CLIP_LEFT 144 0x90 left clipping point active USER
CLIP_TOP 145 0x91 top clipping point active USER
CLIP_RIGHT 146 0x92 right clipping point active USER
CLIP_BOTTOM 147 0x93 bottom clipping point active USER
FONT_TYPE 148 0x94 0 = fixed, 1 = proportional SYSTEM
FONT_MAX 149 0x95 number of chars in font set SYSTEM
FONT_OFFSET 150 0x96 ASCII offset (usually 0x20) SYSTEM
FONT_WIDTH 151 0x97 width of font (pixel units) SYSTEM
FONT_HEIGHT 152 0x98 height of font (pixel units) SYSTEM
TEXT_XMAG 153 0x99 text width magnification USER
TEXT_YMAG 154 0x9A text height magnification USER
TEXT_MARGIN 155 0x9B text place holder for CR SYSTEM
TEXT_DELAY 156 0x9C text delay effect (0-255msec) USER
TEXT_X_GAP 157 0x9D X pixel gap between chars USER
TEXT_Y_GAP 158 0x9E Y pixel gap between chars USER
GFX_XMAX 159 0x9F width of current orientation SYSTEM
GFX_YMAX 160 0xA0 height of current orientation SYSTEM
GFX_SCREENMODE 161 0xA1 Current screen mode (0-3) SYSTEM

Note

  • SYSTEM registers are maintained by internal system functions and should not be written to. They should only ever be read. DO NOT write to these registers.
  • USER registers are read/write (R/W) registers used to alter the system behaviour. Refer to the individual functions for information on the interaction with these registers.
  • These registers are accessible with peekB and pokeB functions.
  • Regiter Addresses 162-165 (or 0xA2 to 0xA5) are RESERVED 8-bit Registers

16-bit Registers Memory Map

The following tables outline in detail the GOLDELOX 16-bit system registers and flags.

Label Address
DEC
Address
HEX
Usage Type
SYS_OVERFLOW 83 0x53 16bit overflow register USER
SYS_COLOUR 84 0x54 internal variable for colour SYSTEM
SYS_RETVAL 85 0x55 return value of last function SYSTEM
GFX_BACK_COLOUR 86 0x56 screen background colour USER
GFX_OBJECT_COLOUR 87 0x57 graphics object colour USER
GFX_TEXT_COLOUR 88 0x58 text foreground colour USER
GFX_TEXT_BGCOLOUR 89 0x59 text background colour USER
GFX_OUTLINE_COLOUR 90 0x5A circle/rectangle outline USER
GFX_LINE_PATTERN 91 0x5B line draw tessellation USER
IMG_PIXEL_COUNT 92 0x5C count of pixels in image SYSTEM
IMG_FRAME_COUNT 93 0x5D count of frames in animation SYSTEM
MEDIA_HEAD 94 0x5E media sector head position SYSTEM
SYS_OUTSTREAM 95 0x5F Output stream handle SYSTEM
GFX_LEFT 96 0x60 image left real point SYSTEM
GFX_TOP 97 0x61 image top real point SYSTEM
GFX_RIGHT 98 0x62 image right real point SYSTEM
GFX_BOTTOM 99 0x63 image bottom real point SYSTEM
GFX_X1 100 0x64 image left clipped point SYSTEM
GFX_Y1 101 0x65 image top clipped point SYSTEM
GFX_X2 102 0x66 image right clipped point SYSTEM
GFX_Y2 103 0x67 image bottom clipped point SYSTEM
GFX_X_ORG 104 0x68 current X origin USER
GFX_Y_ORG 105 0x69 current Y origin USER
RANDOM_LO 106 0x6A random generator LO word SYSTEM
RANDOM_HI 107 0x6B random generator HI word SYSTEM
MEDIA_ADDR_LO 108 0x6C media byte address LO SYSTEM
MEDIA_ADDR_HI 109 0x6D media byte address HI SYSTEM
SECTOR_ADDR_LO 110 0x6E media sector address LO SYSTEM
SECTOR_ADDR_HI 111 0x6F media sector address HI SYSTEM
SYSTEM_TIMER_LO 112 0x70 1msec system timer LO word USER
SYSTEM_TIMER_HI 113 0x71 1msec system timer HI word USER
TIMER0 114 0x72 1msec user timer 0 USER
TIMER1 115 0x73 1msec user timer 1 USER
TIMER2 116 0x74 1msec user timer 2 USER
TIMER3 117 0x75 1msec user timer 3 USER
INCVAL 118 0x76 predec/preinc/postdec/postinc addend USER
TEMP_MEDIA_ADDRLO 119 0x77 temporary media address LO SYSTEM
TEMP_MEDIA_ADDRHI 120 0x78 temporary media address HI SYSTEM
GFX_TRANSPARENTCOLOUR 121 0x79 Image transparency colour USER
GFX_STRINGMETRIX 122 0x7A Low byte : string width
High byte : string height
SYSTEM
GFX_TEMPSTORE1 123 0x7B Low byte : last character printed
High byte : video frame timer over-ride
SYSTEM
reserved 124 0x7C reserved SYSTEM
reserved 125 0x7D reserved SYSTEM
SYS_FLAGS1 126 0x7E system control flags word 0 FLAGS
SYS_FLAGS2 127 0x7F system control flags word 1 FLAGS
USR_SP 128 0x80 User defined stack pointer USERSTACK
USR_MEM 129 0x81 255 user variables / array(s) MEMORY
SYS_STACK 384 0x180 128 level EVE machine stack SYSTEMSTACK

Note

  • SYSTEM registers are maintained by internal system functions and should not be written to. They should only ever be read. DO NOT write to these registers.
  • USER registers are read/write (R/W) registers used to alter the system behaviour. Refer to the individual functions for information on the interaction with these registers.
  • USERSTACK are used by the debugging and system extension utilities
  • MEMORY - 255-word size variables for users program
  • STACK - 128 word EVE system stack (STACK grows upwards)s
  • FLAGS are a mixture of bits that are either maintained by internal system functions or set/cleared by various system functions. Refer to the Flags Register Bit Map tables, and individual functions for further details.
  • These registers are accessible with peekW and pokeW functions.

SYS_FLAGS1 Bit Map

Bit Name Usage Value
Bit 0 _STREAMLOCK Used internally 0x0001
Bit 1 _PENSIZE Object, 0 = solid, 1 = outline 0x0002
Bit 2 _OPACITY Text, 0 = transparent, 1 = opaque 0x0004
Bit 3 _OUTLINED box/circle outline 0 = off, 1 = on 0x0008
Bit 4 _BOLD * text, 0 = normal, 1 = bold 0x0010
Bit 5 _ITALIC * Text, 0 = normal, 1 = italic 0x0020
Bit 6 _INVERSE * Text, 0 = normal, 1 = inverse 0x0040
Bit 7 _UNDERLINED * Text, 0 = normal, 1 = underlined 0x0080
Bit 8 _CLIPPING 0 = clipping off, 1 = clipping on 0x0100
Bit 9 _STRMODE Used internally 0x0200
Bit 10 _SERMODE Used internally 0x0400
Bit 11 _TXTMODE Used internally 0x0800
Bit 12 _MEDIAMODE Used internally 0x1000
Bit 13 _PATTERNED Used internally 0x2000
Bit 14 _COLOUR8 Display mode, 0 = 16bit, 1 = 8bit 0x4000
Bit 15 _MEDIAFONT 0 = internal font, 1 = media font 0x8000

SYS_FLAGS2 Bit Map

Bit Name Usage Value
Bit 0 _MEDIA_INSTALLED SD/SDHC or FLASH is detected/active 0x0001
Bit 1 _MEDIA_TYPE 0 = SD/SDHC, 1 = FLASH chip 0x0002
Bit 2 _MEDIA_READ 1 = MEDIA read in progress 0x0004
Bit 3 _MEDIA_WRITE 1 = MEDIA write in progress 0x0008
Bit 4 _OW_PIN 0 = IO1, 1 = IO2 (Dallas OW Pin) 0x0010
Bit 5 _PTR_TYPE Used internally 0x0020
Bit 6 _TEMP1 Used internally 0x0040
Bit 7 _TEMP2 Used internally 0x0080
Bit 8 _RUNMODE 1 = running pcode from media 0x0100
Bit 9 _SIGNED 0 = number printed '-' prepend 0x0200
Bit 10 _RUNFLAG 1 = EVE processor is running 0x0400
Bit 11 _SINGLESTEP 1 = set breakpoint for debugger 0x0800
Bit 12 _COMMINT 1 = buffered coms active 0x1000
Bit 13 _DUMMY16 1 = display needs 16bit dummy 0x2000
Bit 14 _DISP16 1 = display is 16bit interface 0x4000
Bit 15 _PROPFONT 1 = current font is proportional 0x8000

Example 4DGL Code

#platform "GOLDELOX-GFX2"

/*  4DGL Demo Application
    -- Scaled General Demo -
    -- Tested on uOLED-128-G1 -
    -- and uOLED160-G1 platforms -- 
    -- GOLDELOX GFX2 Platforms --
*/

#inherit "4DGL_16bitColours.fnc"

// define a custom font.
// Custom fonts can also be placed in MEDIA (ie on uSD/uSDHC card), however
// text blitting will run much faster from a data statement.
#DATA
    byte MS_SanSerif8x12
    2,            // Type 2, Char Width preceeds character; Table of widths also 
    96,           // Num chars 
    32,           // Starting Char 
    8,            // Font_Width 
    12,           // Font_Height 
    4, 4, 6, 8, 7, 8, 7, 3,     // Widths of chars 0x32 to 0x39
    4, 4, 5, 7, 4, 4, 4, 6,     // etc.
    7, 7, 7, 7, 7, 7, 7, 7,
    7, 7, 4, 4, 7, 7, 7, 7,
    8, 8, 8, 8, 8, 8, 7, 8,
    8, 4, 6, 8, 7, 8, 8, 8,
    8, 8, 8, 8, 8, 8, 8, 8,
    8, 8, 8, 4, 6, 4, 7, 7,
    4, 7, 7, 7, 7, 7, 4, 7,
    7, 3, 3, 7, 3, 9, 7, 7,
    7, 7, 4, 6, 4, 7, 7, 8,
    6, 6, 6, 5, 3, 5, 8, 4,
    4, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,   // 32 ' '
    4, 0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x40,0x00,   // 33 '!'
    6, 0x00,0x00,0x48,0x48,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,   // 34 '"'
    8, 0x00,0x00,0x24,0x24,0x7E,0x24,0x24,0x24,0x7E,0x24,0x24,0x00,   // 35 '#'
    7, 0x00,0x00,0x10,0x38,0x54,0x50,0x30,0x18,0x14,0x54,0x38,0x10,   // 36 '$'
    8, 0x00,0x00,0x30,0x49,0x32,0x04,0x08,0x10,0x26,0x49,0x06,0x00,   // 37 '%'
    7, 0x00,0x00,0x20,0x50,0x50,0x20,0x20,0x54,0x48,0x48,0x34,0x00,   // 38 '&'
    3, 0x00,0x00,0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,   // 39 '''
    4, 0x00,0x00,0x20,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,   // 40 '('
    4, 0x00,0x00,0x40,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,   // 41 ')'
    5, 0x00,0x00,0x00,0x50,0x20,0x50,0x00,0x00,0x00,0x00,0x00,0x00,   // 42 '*'
    7, 0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x00,   // 43 '+'
    4, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x40,   // 44 ','
    4, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,   // 45 '-'
    4, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,   // 46 '.'
    6, 0x00,0x00,0x08,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x00,   // 47 '/'
    7, 0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,   // 48 '0'
    7, 0x00,0x00,0x10,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,   // 49 '1'
    7, 0x00,0x00,0x38,0x44,0x04,0x04,0x08,0x10,0x20,0x40,0x7C,0x00,   // 50 '2'
    7, 0x00,0x00,0x38,0x44,0x04,0x04,0x18,0x04,0x04,0x44,0x38,0x00,   // 51 '3'
    7, 0x00,0x00,0x08,0x18,0x18,0x28,0x28,0x48,0x7C,0x08,0x08,0x00,   // 52 '4'
    7, 0x00,0x00,0x7C,0x40,0x40,0x78,0x44,0x04,0x04,0x44,0x38,0x00,   // 53 '5'
    7, 0x00,0x00,0x38,0x44,0x40,0x40,0x78,0x44,0x44,0x44,0x38,0x00,   // 54 '6'
    7, 0x00,0x00,0x7C,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x20,0x00,   // 55 '7'
    7, 0x00,0x00,0x38,0x44,0x44,0x44,0x38,0x44,0x44,0x44,0x38,0x00,   // 56 '8'
    7, 0x00,0x00,0x38,0x44,0x44,0x44,0x3C,0x04,0x04,0x44,0x38,0x00,   // 57 '9'
    4, 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x40,0x00,   // 58 ':'
    4, 0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x20,0x40,   // 59 ';'
    7, 0x00,0x00,0x00,0x00,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x00,   // 60 '<'
    7, 0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x7C,0x00,0x00,0x00,   // 61 '='
    7, 0x00,0x00,0x00,0x00,0x40,0x20,0x10,0x08,0x10,0x20,0x40,0x00,   // 62 '>'
    7, 0x00,0x00,0x38,0x44,0x04,0x04,0x08,0x10,0x10,0x00,0x10,0x00,   // 63 '?'
    8, 0x00,0x00,0x0C,0x32,0x21,0x4D,0x53,0x52,0x4C,0x20,0x31,0x0E,   // 64 '@'
    8, 0x00,0x00,0x10,0x10,0x28,0x28,0x44,0x44,0x7C,0x82,0x82,0x00,   // 65 'A'
    8, 0x00,0x00,0x78,0x44,0x44,0x44,0x78,0x44,0x44,0x44,0x78,0x00,   // 66 'B'
    8, 0x00,0x00,0x3C,0x42,0x40,0x40,0x40,0x40,0x40,0x42,0x3C,0x00,   // 67 'C'
    8, 0x00,0x00,0x78,0x44,0x42,0x42,0x42,0x42,0x42,0x44,0x78,0x00,   // 68 'D'
    8, 0x00,0x00,0x7C,0x40,0x40,0x40,0x78,0x40,0x40,0x40,0x7C,0x00,   // 69 'E'
    7, 0x00,0x00,0x7C,0x40,0x40,0x40,0x78,0x40,0x40,0x40,0x40,0x00,   // 70 'F'
    8, 0x00,0x00,0x3C,0x42,0x40,0x40,0x4E,0x42,0x42,0x46,0x3A,0x00,   // 71 'G'
    8, 0x00,0x00,0x42,0x42,0x42,0x42,0x7E,0x42,0x42,0x42,0x42,0x00,   // 72 'H'
    4, 0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,   // 73 'I'
    6, 0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x90,0x90,0x60,0x00,   // 74 'J'
    8, 0x00,0x00,0x44,0x48,0x50,0x60,0x60,0x50,0x48,0x44,0x42,0x00,   // 75 'K'
    7, 0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7C,0x00,   // 76 'L'
    8, 0x00,0x00,0x41,0x41,0x63,0x63,0x55,0x55,0x49,0x49,0x41,0x00,   // 77 'M'
    8, 0x00,0x00,0x42,0x62,0x62,0x52,0x52,0x4A,0x46,0x46,0x42,0x00,   // 78 'N'
    8, 0x00,0x00,0x3C,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,   // 79 'O'
    8, 0x00,0x00,0x7C,0x42,0x42,0x42,0x7C,0x40,0x40,0x40,0x40,0x00,   // 80 'P'
    8, 0x00,0x00,0x3C,0x42,0x42,0x42,0x42,0x42,0x4A,0x46,0x3C,0x02,   // 81 'Q'
    8, 0x00,0x00,0x7C,0x42,0x42,0x42,0x7C,0x42,0x42,0x42,0x42,0x00,   // 82 'R'
    8, 0x00,0x00,0x38,0x44,0x40,0x40,0x38,0x04,0x04,0x44,0x38,0x00,   // 83 'S'
    8, 0x00,0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,   // 84 'T'
    8, 0x00,0x00,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,   // 85 'U'
    8, 0x00,0x00,0x41,0x41,0x22,0x22,0x22,0x14,0x14,0x08,0x08,0x00,   // 86 'V'
    8, 0x00,0x00,0x41,0x41,0x41,0x22,0x2A,0x2A,0x1C,0x14,0x14,0x00,   // 87 'W'
    8, 0x00,0x00,0x41,0x41,0x22,0x14,0x08,0x14,0x22,0x41,0x41,0x00,   // 88 'X'
    8, 0x00,0x00,0x41,0x41,0x22,0x14,0x08,0x08,0x08,0x08,0x08,0x00,   // 89 'Y'
    8, 0x00,0x00,0x7F,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x7F,0x00,   // 90 'Z'
    4, 0x00,0x00,0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,   // 91 '['
    6, 0x00,0x00,0x40,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x00,   // 92 '\'
    4, 0x00,0x00,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,   // 93 ']'
    7, 0x00,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,   // 94 '^'
    7, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,   // 95 '_'
    4, 0x00,0x00,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,   // 96 '`'
    7, 0x00,0x00,0x00,0x00,0x00,0x38,0x04,0x3C,0x44,0x44,0x3C,0x00,   // 97 'a'
    7, 0x00,0x00,0x40,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x78,0x00,   // 98 'b'
    7, 0x00,0x00,0x00,0x00,0x00,0x38,0x44,0x40,0x40,0x44,0x38,0x00,   // 99 'c'
    7, 0x00,0x00,0x04,0x04,0x04,0x3C,0x44,0x44,0x44,0x44,0x3C,0x00,   // 100 'd'
    7, 0x00,0x00,0x00,0x00,0x00,0x38,0x44,0x7C,0x40,0x44,0x38,0x00,   // 101 'e'
    4, 0x00,0x00,0x20,0x40,0x40,0x60,0x40,0x40,0x40,0x40,0x40,0x00,   // 102 'f'
    7, 0x00,0x00,0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x3C,0x04,   // 103 'g'
    7, 0x00,0x00,0x40,0x40,0x40,0x58,0x64,0x44,0x44,0x44,0x44,0x00,   // 104 'h'
    3, 0x00,0x00,0x40,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x00,   // 105 'i'
    3, 0x00,0x00,0x40,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,   // 106 'j'
    7, 0x00,0x00,0x40,0x40,0x40,0x48,0x50,0x60,0x50,0x48,0x44,0x00,   // 107 'k'
    3, 0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,   // 108 'l'
    9, 0x00,0x00,0x00,0x00,0x00,0x76,0x49,0x49,0x49,0x49,0x49,0x00,   // 109 'm'
    7, 0x00,0x00,0x00,0x00,0x00,0x58,0x64,0x44,0x44,0x44,0x44,0x00,   // 110 'n'
    7, 0x00,0x00,0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x38,0x00,   // 111 'o'
    7, 0x00,0x00,0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x40,   // 112 'p'
    7, 0x00,0x00,0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x3C,0x04,   // 113 'q'
    4, 0x00,0x00,0x00,0x00,0x00,0x60,0x40,0x40,0x40,0x40,0x40,0x00,   // 114 'r'
    6, 0x00,0x00,0x00,0x00,0x00,0x30,0x48,0x20,0x10,0x48,0x30,0x00,   // 115 's'
    4, 0x00,0x00,0x00,0x40,0x40,0x60,0x40,0x40,0x40,0x40,0x20,0x00,   // 116 't'
    7, 0x00,0x00,0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x4C,0x34,0x00,   // 117 'u'
    7, 0x00,0x00,0x00,0x00,0x00,0x44,0x44,0x28,0x28,0x10,0x10,0x00,   // 118 'v'
    8, 0x00,0x00,0x00,0x00,0x00,0x49,0x49,0x55,0x55,0x22,0x22,0x00,   // 119 'w'
    6, 0x00,0x00,0x00,0x00,0x00,0x48,0x48,0x30,0x30,0x48,0x48,0x00,   // 120 'x'
    6, 0x00,0x00,0x00,0x00,0x00,0x48,0x48,0x48,0x48,0x30,0x20,0x20,   // 121 'y'
    6, 0x00,0x00,0x00,0x00,0x00,0x78,0x08,0x10,0x20,0x40,0x78,0x00,   // 122 'z'
    5, 0x00,0x10,0x20,0x20,0x20,0x20,0x40,0x20,0x20,0x20,0x20,0x10,   // 123 '{'
    3, 0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,   // 124 '|'
    5, 0x00,0x40,0x20,0x20,0x20,0x20,0x10,0x20,0x20,0x20,0x20,0x40,   // 125 '}'
    8, 0x00,0x00,0x00,0x32,0x4C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,   // 126 '~'
    4, 0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60    // 127 ''
#END

// a message for the moving banner
#DATA 
    byte message "......GOLDELOX GFX2 Graphics......",0
#END

// the 'wall' colours
#CONST 
    LEFTCOLOUR      0xF800
    RIGHTCOLOUR     0xFFFF
    TOPCOLOUR       0x001F
    BOTTOMCOLOUR    0x07E0
#END

// constants for the view-port
// These may need adjusting for smaller displays
#CONST
    windowXpos      30
    windowYpos      30
    windowWidth     110
    windowHeight    60
#END

// object types.
// 2,3,4,5 and 6 doubles as polygon vertices counts
#CONST 
    RANDOM          0
    CIRCLE          1
    LINE            2
    TRIANGLE        3
    RECTANGLE       4
    PENTAGON        5
    HEXAGON         6
#END



// 'ball' speed factors determine
// how many pixels to jump per movement
#constant XSPEED        3
#constant YSPEED        2

// the width of the side walls
#constant WALLWIDTH     2

// 'ball' object radius
#constant BALLSIZE 4  

// global working variables
var ball_x, ball_y, ball_r, ball_colour;
var xdir, ydir, xspeed, yspeed;
var screenwidth, screenheight, xc, yc;
var tophit, bottomhit, lefthit, righthit;
var windowLeft, windowTop, windowRight, windowBottom;
var angle, newseed;

// global variables for the polygon generator
var Xcoords[6], Ycoords[6];     // big enough for a hexagon
var targetX, targetY;           // targets for orbit

// array of pointers for text messages
var messages[4];


// polyline array for scope
#constant SAMPLES 20
var ScopeBufX[SAMPLES];
var ScopeBufY[SAMPLES];
var freq[4];

var mediaflag;      // set to 1 if uSD/uSDHC card detected

//==============================================================================
// draw random waveform
//==============================================================================
func doRandScope(var samples, var colr, var smpl)
    var w,h,n,xstep,yoffs,x,yscale,xoffs,seedoffs;
    w := windowRight-windowLeft;
    h := windowBottom-windowTop;
    xstep:=w/samples+1;
    yscale:=h/2;
    yoffs:=h/2+windowTop;
    SEED(smpl);
    x:=windowLeft;
    while (n<samples)
    // undraw the old sample as we create new one (looks better, less flicker)
        gfx_Line(ScopeBufX[n],ScopeBufY[n],ScopeBufX[n+1],ScopeBufY[n+1],BLACK);     
        ScopeBufY[n]:=(RAND()%yscale)+yoffs;
        ScopeBufX[n]:=x;
        x := x+xstep;
        n++;
    wend
    gfx_Polyline(samples, ScopeBufX, ScopeBufY, colr);  // draw the new sample
endfunc
//==============================================================================
// draw a sinewave
//==============================================================================
func doSineScope(var samples, var colr, var smpl)
    var w,h,n,xstep,yoffs,x,yscale,xoffs,seedoffs;
    w := windowRight-windowLeft;
    h := windowBottom-windowTop;
    xstep:=w/samples+1;
    yscale:=h/2;
    yoffs:=h/2+windowTop;
    x:=windowLeft;
    gfx_Polyline(samples, ScopeBufX, ScopeBufY, BLACK);  // undraw the old
                                                         // buffer first
    while (n<samples)
        ScopeBufY[n]:=SIN(xoffs)/4+yoffs;
        ScopeBufX[n]:=x;
        x := x+xstep;
        xoffs := xoffs+smpl;
        n++;
    wend
    gfx_Polyline(samples, ScopeBufX, ScopeBufY, colr);;  // draw the new sample
endfunc


//==============================================================================
// build a polygon with a number of sides determined by var "sides"
// around the current origin. The distance from the origin to the
// equidistent vertices from origin determined
// by var "distance". var "angle" is the starting angle for the
// first virtices. Draws the polygon in colour var "colr"
// NB make sure the array is big enough for the required number of sides
//==============================================================================
func MakePolygon(var angle, var sides, var distance, var colr)
    var index, step;
    index := 0;
    step := 360/sides;                 // work out the step size
    while (sides < 360)                // until we do a complete polygon
        gfx_Orbit(angle, distance);
        Xcoords[index] := targetX;     // build a polygon in the matrix
        Ycoords[index] := targetY;
        index++;
        angle := angle + step;
        sides := sides + step;
    wend
    gfx_Polygon(index, Xcoords, Ycoords, colr);
endfunc


//==============================================================================
// ball object control
//==============================================================================
func DrawBall(var type, var colour)
    var count;

    gosub(type),(
                circle, 
                text, 
                triangle,
                rectangle, 
                pentagon,
                hexagon, 
                random 
                );
                goto default;  // unknown type default exit

// case circle
circle:
    gfx_CircleFilled(ball_x, ball_y, BALLSIZE, colour);   // redraw the ball
    endsub;

// case text
text:
    txt_Opacity(TRANSPARENT);   // transparent text
    txt_FontID(0);              // default small font   
    //txt_FGcolour(RAND());
    txt_FGcolour(colour);
    gfx_MoveTo(ball_x, ball_y);    // draw a pixel trail
    putstr("4DGL");
    endsub;


// these cases same, type is used to determine number of sides
triangle:
rectangle:
pentagon:
hexagon:
    gfx_MoveTo(ball_x, ball_y);             // using the balls origin
    MakePolygon(angle, type, 10, colour);   // make 3 sided polygon = triangle
    endsub;

// case random
random:
    if (colour)
        SEED(newseed);
        gfx_ObjectColour(RAND()|0x8408);    // ensure hi colours
    else
        SEED(newseed++);
        RAND();            // RAND here to compensate so we get  repeat sequence
        gfx_ObjectColour(BLACK);
    endif

    count := 5;
    while (count--)
        gfx_MoveTo(ball_x+RAND()%15, ball_y+RAND()%15);    
        //gfx_Dot();                                      // draw a pixel trail
        gfx_Bullet(3);                                    // draw random circles
        //gfx_BoxTo(ball_x, ball_y);                      // draw random boxes   
    wend
    endsub;

default:    

endfunc

//==============================================================================
// part of intro, fill clipped area with pixels then remove in same orded
//==============================================================================
func doDots()    
    var n,x,y,w,h;
    // random dots
    SEED(1234);
    w := windowRight - windowLeft;
    h := windowBottom - windowTop;
    n := -3000;
    while (n++<3000)
        x := ABS(RAND()%w) + windowLeft+1;
        y := ABS(RAND()%h) + windowTop+1;
        gfx_PutPixel(x , y , RAND());
    wend

    // undraw the dots
    SEED(1234);
    n := -3000;
    while (n++<3000)
        x := ABS(RAND()%w) + windowLeft+1;
        y := ABS(RAND()%h) + windowTop+1;
        RAND();
        gfx_PutPixel(x , y , 0);
    wend
endfunc

//==============================================================================
// part of intro, fill entire screen with lines then remove in same orded
// Note that clipping will take care of line endpoints outside to clipping area
//==============================================================================
func doLines()
    var n;
    // random lines
    SEED(9876);
    n := -200;
    while (n++<200)
        gfx_Line(ABS(RAND()%screenwidth), ABS(RAND()%screenheight), ABS(RAND()
        %screenwidth), ABS(RAND()%screenheight), RAND());
    wend

    // undraw the lines
    SEED(9876);
    n := -200;
    while (n++<200)
        gfx_Line(ABS(RAND()%screenwidth), ABS(RAND()%screenheight), ABS(RAND()
        %screenwidth), ABS(RAND()%screenheight), 0);
        RAND();
    wend
endfunc

//==============================================================================
// Check the baal position against the walls.
// Change direction registers accordingly.
//==============================================================================
func collision()
    if(ball_x <= lefthit)
       ball_x := lefthit;
       ball_colour := LEFTCOLOUR;
       xdir := -xdir;
    endif

    if(ball_x >= righthit)
       ball_x := righthit;
       ball_colour := RIGHTCOLOUR;
       xdir := -xdir;
    endif

    if (ball_y <= tophit) 
       ball_y := tophit;
       ball_colour := TOPCOLOUR;
       ydir := -ydir;
    endif

    if(ball_y >= bottomhit)
       ball_y := bottomhit;
       ball_colour := BOTTOMCOLOUR;
       ydir := -ydir;
    endif
endfunc

//==============================================================================
// EVE starts executing code from here
//==============================================================================
func main()
    var mode, timer, obj, scrollpos, n, linepattern, intro, intronum, scopeloop;

    if (media_Init() == 0)               // initialise and test the uSD/uSDHC card
        print("No uSD CARD Installed\n");
        print("Some demo's are disabled");
        pause(2000);
        gfx_Cls();
    endif

    mode := 0;    
    linepattern := 0xF0F0;
    messages[0] := " LANDSCAPE";
    messages[1] := "LANDSCAPE_R";
    messages[2] := " PORTRAIT";
    messages[3] := "PORTRAIT_R";     

    //gfx_Set(CONTRAST, 16);
    gfx_Contrast(16);   // max. brightness
    gfx_Cls();

    // set generic target variables for the orbit command
    gfx_OrbitInit(&targetX, &targetY);
    txt_Set(FONT_ID, MS_SanSerif8x12);   // don't use default system font, use
                                         // font provided
    repeat

        timer := 0;                         // timer for SCREEN_MODE switching
        gfx_Cls();
        gfx_Set(SCREEN_MODE, mode);     // set required screen mode

        // this is mainly for 'non square' display to make the ball speed realistic
        if (mode < 2)
            xspeed := XSPEED;           // keep correct ball speed aspect
            yspeed := YSPEED;
        else
            xspeed := YSPEED;
            yspeed := XSPEED;
        endif    

        // get the display parameters
        screenwidth := peekB(GFX_XMAX);            
        screenheight := peekB(GFX_YMAX);

        // determine the centre point
        xc := screenwidth >> 1;                     
        yc := screenheight >> 1;
        ball_colour := WHITE;                       // initial ball colour
        xdir := 1; ydir := 1;                       // initial ball direction
        ball_x := 20; ball_y := 20;                 // initial ball position

        // draw the walls
        // draw Top Wall
        gfx_RectangleFilled(0, 0, screenwidth-1, WALLWIDTH-1, TOPCOLOUR);

        // Draw Bottom Wall
        gfx_RectangleFilled(0, screenheight-WALLWIDTH, screenwidth-1, screenheight-1, BOTTOMCOLOUR);                    

        // Draw Left Wall    
        gfx_RectangleFilled(0, WALLWIDTH-1, WALLWIDTH-1, screenheight-WALLWIDTH-1, LEFTCOLOUR);  

        // Draw Right Wall
        gfx_RectangleFilled(screenwidth-WALLWIDTH, WALLWIDTH, screenwidth-1, screenheight-WALLWIDTH-1, RIGHTCOLOUR);

        // calculate the collision positions
        tophit := WALLWIDTH+BALLSIZE;
        bottomhit := screenheight-WALLWIDTH-BALLSIZE-1;
        lefthit := WALLWIDTH+BALLSIZE;
        righthit := screenwidth-WALLWIDTH-BALLSIZE-1;

        // set clipping area
        windowLeft := lefthit; 
        windowTop := tophit+10; 
        windowRight := righthit - 16;
        windowBottom := bottomhit -40; 

        // preset the clipping area, activated later...
        gfx_ClipWindow(windowLeft, windowTop, windowRight, windowBottom);  

        // draw a rectangle around the clipped area
        gfx_Rectangle(windowLeft-1, windowTop-1, windowRight+1, windowBottom+1, 
        YELLOW);     
        //  test: draw a small outline rectangle outside
        gfx_Rectangle(windowLeft+5, windowBottom+10, windowLeft+15, windowBottom+20, 
        RED);     
        // test: draw a small solid rectangle outside
        gfx_RectangleFilled(windowLeft+20, windowBottom+10, windowLeft+30,
        windowBottom+20, GREEN);     

        // test: draw a small outline circle
        gfx_Circle(windowLeft+40, windowBottom+15, 5, BLUE);     

        // test: draw a small filled circle
        gfx_CircleFilled(windowLeft+60, windowBottom+15, 5, YELLOW);     

        gfx_Set(CLIPPING, OFF);      // turn off clipping so we can print outside 
                                    // the clip region              
        txt_FGcolour(RED);
        txt_BGcolour(YELLOW);
        txt_Bold(ON);
        //txt_FontID(2); 
        //txt_Set(TEXT_ITALIC, ON);
        //txt_Set(TEXT_OPACITY, TRANSPARENT);    // transparent text is faster
        //gfx_MoveTo(xc-50, yc+20);
        gfx_MoveTo(xc-50, bottomhit -12);
        print(mode," ",[STR] messages[mode]);
        gfx_Set(CLIPPING, ON);                   // turn on clipping                  

        // decide which intro we use for the next screen
        if (intro)
            intro := 0;
            // clear the clipped area
            gfx_RectangleFilled(windowLeft,windowTop,windowRight,windowBottom, BLACK);     
            intronum++;
            if (intronum == 1)
                n:=-180;
                while(n<180)            
                    doSineScope(SAMPLES, YELLOW, n++);
                    n++;
                    //pause(10);
                wend
            else if (intronum == 2)
                n:=200;
                while(n)            
                    doRandScope(SAMPLES, BLUE, n--);
                    //pause(10);
                wend
            else if (intronum == 3)
                doLines();
            else
                doDots();
                intronum := 0;
            endif
            gfx_RectangleFilled(windowLeft,windowTop,windowRight,windowBottom,BLACK);     
        endif

        // timer0 is the screen mode change timer
        *TIMER0 := 7000;
        repeat
            // draw a cross through the clipped area box
            gfx_LinePattern(linepattern);
            gfx_Line(windowLeft+1,windowTop+1,windowRight-1,windowBottom-1, MAGENTA);     
            gfx_Line(windowLeft+1,windowBottom-1,windowRight-1,windowTop+1, MAGENTA);     
            gfx_LinePattern(0);

            // timer2 is used for the banner scrolling
            if (!*TIMER2)
                *TIMER2 := 50;
                txt_Opacity(OPAQUE);            // transparent text
                txt_FontID(0);                  // default system font
                gfx_Clipping(OFF);
                gfx_ClipWindow(windowLeft+10,WALLWIDTH,windowRight-10,WALLWIDTH+8);
                gfx_Clipping(ON);
                scrollpos := scrollpos-1;  
                n:=strwidth(message);                           
                if(scrollpos < windowLeft+10-n) scrollpos := windowRight-10;
                gfx_MoveTo(scrollpos, WALLWIDTH+2);                 
                txt_FGcolour(WHITE);
                txt_BGcolour(DARKGREEN);
                //txt_Italic(ON);
                txt_Bold(ON);
                putstr(message);
                gfx_Clipping(OFF);
                gfx_ClipWindow(windowLeft, windowTop+1, windowRight, windowBottom);  
                gfx_Clipping(ON);
            endif

            // timer3 is used to shift the line pattern
            if(!*TIMER3)
                *TIMER3 := 100;
                linepattern := linepattern << 1;
                if (OVF())  linepattern := linepattern | 1;
            endif

            // timer 0 is for ball timing
            if(!*TIMER1)
                *TIMER1 := 30;            
                DrawBall(obj, BLACK);                 // erase the ball object
                angle := angle + 10;

                ball_x := ball_x + xdir * xspeed;
                ball_y := ball_y + ydir * yspeed;

                collision();                          // detect collision
                DrawBall(obj, ball_colour);           // redraw the ball object
                //DrawBall(obj, RAND());              // redraw the ball object
            endif
        until (!*TIMER0)

        scrollpos := windowLeft+10; // reset the banner
        if (++mode > 3) 
            mode := 0;                               // next screen mode
            if (obj++ > HEXAGON) obj:=0;            // nextball object
            intro := 1;                             // set flag so we do the intro
        endif

    forever  // start again
endfunc
//==============================================================================

Hardware Tools

The following hardware tools are required for full control of the GOLDELOX Processor.

Programming Tools

The 4D Programming Cable, uUSB-PA5-II and 4D-UPA Programming Adaptors are essential hardware tools to program, customise and test the GOLDELOX Processor.

The 4D programming interfaces are used to program a new Firmware/PmmC, Display Driver and for downloading compiled 4DGL code into the processor. They even serve as an interface for communicating serial data to the PC.

The 4D Programming Cable, uUSB-PA5 and gen4-PA Programming Adaptor are available from 4D Systems.

Using a non-4D programming interface could damage your processor and void your Warranty.

4D Programming Cable

4D Programming Cable

uUSB-PA5-II

uUSB-PA5-II

4D-UPA

4D-UPA

Note

Any of the 4D Programming Cable, uUSB-PA5-II or 4D-UPA Programming Adaptor can be used, along with previous generation 4D programmers too.

Display Modules

The following modules, available from 4D Systems, can be used for evaluation purposes to discover what the GOLDELOX processor has to offer.

uOLED-128-G2

uOLED-128-G2

Other modules, such as the 0.96” and 1.7” OLED, or 1.44” LCD versions are also available. Please contact 4D Systems for more information, or visit the 4D Systems website.

Software Tools

Workshop4 is a comprehensive software IDE that provides an integrated software development platform for all the 4D family of processors and modules. The IDE combines the Editor, Compiler, Linker and Down- Loader to develop complete 4DGL application code. All user application code is developed within the Workshop4 IDE.

WS4 Recent Page

The Workshop4 IDE supports multiple development environments for the user, to cater for different user requirements and skill level.

  • The Designer environment enables the user to write 4DGL code in its natural form to program the GOLDELOX module.
  • A visual programming experience, suitably called ViSi, enables drag-and-drop type placement of objects to assist with 4DGL code generation and allows the user to visualise how the display will look while being developed.
  • A Serial environment is also provided to transform the GOLDELOX module into a slave serial module, allowing the user to control the display from any host microcontroller or device with a serial port.

For a comprehensive manual on the Workshop4 IDE Software along with other documents, refer to the Workshop4 User Manual.

Revision History

Document Revision

Revision Date Content
1.0 12/09/2009 First Release
4.0 08/03/2012 Fixed typing errors several sections of the document
6.0 13/09/2012 Reformatted, minor document updates
6.1 16/11/2012 Fixed minor TOC numbering error
6.2 30/01/2013 Added range for the Beep function, 0-64
6.3 04/02/2013 SCREEN_MODE constants changed, documented incorrectly
6.4 07/02/2013 com_Init buffer size corrected
7.0 01/05/2017 Updated formatting and contents
7.1 22/03/2019 Updated Formatting, minor putnum and putstr description updates, Fixed inverted states relating to BOLD, ITALIC, TEXT INVERSE, TEXT ITALIC in txt_Set()
7.2 21/12/2020 Updated setbaud() function with a description on how you set custom baud rates, along with explaining Actual Baud rate and Error% and how they are calculated.
7.3 16/07/2021 Erroneous references in txt_Set function removed.
7.4 11/02/2023 Modified manual for web-based documentation