LowRes NX is a simulated retro game console, which can be programmed in the classic BASIC language. It has its own technical specifications, but it's very much inspired by actual 8-bit and 16-bit game consoles. It doesn't only look and sound retro, but actually works like classic hardware.
LowRes NX simulates graphics, sound and I/O chips and makes their hardware registers accessable in its memory map. Although most of the features are available via simple BASIC commands, it's possible to program video, audio and I/O directly by accessing the memory.
Imagine LowRes NX as a handheld game console with a d-pad, two action buttons and a little rubber keyboard below a slidable touchscreen.
Create a new program using the Plus button and type these lines:
PRINT "WELCOME!" PRINT "WHAT IS YOUR NAME?" INPUT ">";N$ PRINT "HELLO ";N$;"!"
Now tap the Play button to run your program! This is a little example using the keyboard. Let's try something with a gamepad. Create another new program and type this:
GAMEPAD 1 X=76 Y=60 DO IF UP(0) THEN Y=Y-1 IF DOWN(0) THEN Y=Y+1 IF LEFT(0) THEN X=X-1 IF RIGHT(0) THEN X=X+1 SPRITE 0,X,Y,225 WAIT VBL LOOP
Run this program and you will see an "A" on the screen which you can move around using the gamepad. With the program still running, tap the menu button on the top right and select "Capture Program Icon".
Now exit the program and return to the "My Programs" screen. There you will see your program with a new image. Long tap the icon and select "Rename..." to give it a better name.
A program file contains a complete game or application, including all its data, stored as simple text. The first part is the BASIC source code. Please read the programming chapters for further explanation.
The second part are the cartridge ROM entries. These are up to 16 numbered data blocks, which can contain any kind of binary data, for example graphics, level maps, music, etc. When the program is running, all ROM entries are accessable in the first 32 KB of the memory.
To create and edit ROM entries, just open your program, tap the Tools button and select a program. It will run and use your current program as a virtual disk to load and save data. Tools don't save automatically, so don't forget to save before you exit them.
Open your previous program with the moving "A" and select "Character Designer" from the Tools menu. Draw something as character #1 (keep #0 empty), then tap on "Disk" and save as file 2 ("Main Characters"). Now exit the Character Designer and you will see some hexadecimal data below your program. This is your image! To see it, change the line
SPRITE 0,X,Y,225
to
SPRITE 0,X,Y,1
and run your program. There it is!
For an easy start you should use the ROM entry numbers of the following table. Their data is made ready for use automatically.
#0 | Keep empty for default font |
#1 | Color palettes |
#2 | Characters (sprites, tiles) |
#3 | Background (tile map) |
If cartridge ROM entry 0 is not used by a program, the compiler adds character data for the default font. It occupies the characters 192-255 and is automatically copied to video RAM on program start. If you want to use the default font, make sure to keep ROM entry 0 unused.
Use the Character Designer to draw your sprites and background tiles. It shows images in grayscale only, black is used as transparent background. Color palettes can be created later in the Background Designer.
The Character Designer loads file number 2 on startup, but keep in mind that it does not save automatically.
In the bottom part you see the 256 characters split into four pages. There you can select the current one for editing. Keep the last page empty, if you want to use the default font. Also character #0 should be empty for a clean background.
The top left square is for drawing the current character using the selected color.
CLR | Clear the current character with the selected color. |
CUT | Copy and clear the current character. |
COP | Copy the current character. |
PAS | Paste the copied character. |
DISK | Go to the disk menu. |
16*16 | Go to the 16x16-pixel edit screen. |
FON | Copy the standard font to the current page. |
NEW | Clear all characters. |
The list shows all 16 files of the current virtual disk, or in other words the ROM entries of the program you are editing. Select one (usually number 2) and tap on Load or Save.
The Background Designer allows you to create tile-based screens or level maps of different sizes. Additionally it's for creating color palettes. On the bottom right there are three tabs for the different sections of the program: The map editor, the selection screen and the disk menu.
The Background Designer loads the main characters (file 1), palettes (file 2) and background (file 3) on startup, but keep in mind that it doesn't save automatically.
On the top there is the character selector. Drag to select several characters at once. In the box at the left you select the current color palette. On the right you can edit each color of the current palette using the RGB sliders. The first color is usually transparent and unused, except the first color of palette 0, which is used as the screen backdrop color.
Here you draw your background using the character and color palette currently selected on the selection screen. On the bottom appear some tools:
Pan | Drag the visible map area. |
Stamp | Draw with the selected character and color palette, using the selected flip and priority attributes. |
Paint | Change the color palette only. |
Priority | Change the priority only. Cells with priority 1 are shown in green, all others in red. |
FLIP | Toggles the X/Y flip attributes. |
PRI | Toggles the priority attribute. |
From here you load and save characters, color palettes and the background separately. There is no option to save everything at once. For the background there are two additional options:
NEW | Clear the complete background (keeping its size). |
SIZE | Go to the size menu, where you can choose the width and height of the background (in cells), as well as the cell size (8x8 or 16x16 pixels). |
The programming language of LowRes NX is based on second-generation, structured BASIC (1985 style).
Available data types are strings and numbers (floating point). Variable names can contain letters (A-Z), digits (0-9) and underscores (_), but cannot begin with a digit. Reserved keywords cannot be used as names, but they can contain them, for example:
Valid: ENDING
Invalid: END
String variable names must end with a $ symbol, for example:
NAME$
Variables are not explicitly declared, but they need to be initialized with a value before you can read from them. Values are assigned to variables using the equal symbol:
NAME$="LOWRES NX" LIVES=3
Hexadecimal and binary notation can be used for number values:
$FF02 %11001011
DIM [GLOBAL] var-list
Defines arrays with the highest index for each dimension:
DIM A(100) DIM MAP(31,23,1),NAMES$(9),SCORES(9)
Access elements from arrays, indices start from 0:
SCORES(0)=100 SCORES(9)=5 PRINT SCORES(0),SCORES(9)
All elements of arrays are automatically initialized, using zeros (0) or empty strings ("").
With the optional GLOBAL keyword the arrays will be accessable from all subprograms.
A label marks a position in a program and is used for commands like GOTO. It consists of a name, using the same rules as for variables, followed by a colon:
GAMEOVER:
Symbol | Example | Purpose |
---|---|---|
- | -B | Negation |
^ | X^3 | Exponentiation |
* | 2*Y | Multiplication |
/ | X/2 | Division |
\ | X\2 | Integer Division |
+ | C+2 | Addition |
- | 100-D | Subtraction |
MOD | X MOD 2 | Modulo |
Operations are performed in mathematical order, for example multiplications and divisions are performed before additions and subtractions. The order can be specified explicitly through the use of parentheses, for example: (3+4*3)/5
Symbol | Example | Purpose |
---|---|---|
= | A=10 | Equal |
<> | A<>100 | Not equal |
> | B>C | Greater than |
< | 5<X | Less than |
>= | X>=20 | Greater than or equal |
<= | X<=30 | Less than or equal |
Relational operator expressions have a value of true (-1) or false (0). For example: (2=3)=0, (4=4)=-1, (1<3)=-1
Symbol | Example | Purpose |
---|---|---|
NOT | NOT (X=15) | "Not" |
AND | A=1 AND B=12 | "And" |
OR | X=10 OR Y=0 | "Or" |
XOR | A XOR B | "Exclusive Or" |
All operators are available for numbers. Relational and addition operators are usable with strings, too:
SUM=1+3 IF SUM<5 THEN PRINT "LESS THAN 5" NAME$="LOWRES NX" GREET$="HELLO "+NAME$+"!" IF NAME$>"LOWRES" THEN PRINT GREET$
REM remark ' remark
Allows you to put comments into your program. REM lines are not executed. You can use an apostrophe (') in place of the word REM.
IF expr THEN command [ELSE command]
Checks if the given expression is true or false. If it's true, the command after THEN is executed, otherwise the one after ELSE. The ELSE part is optional.
If you want to execute more than one command, you can use the block version of the IF command. It must be closed with the line END IF.
IF expression THEN commands [ELSE IF expression THEN] commands [ELSE] commands END IF
GOTO label
Jumps to the given label and continues the program execution there.
GOSUB label
Adds the current program position to a stack and jumps to the given label. The program after the label is called a subroutine and must be finished using RETURN.
NOTE: Subroutines exist mostly for historical reasons. You should prefer the more powerful and safer subprograms.
RETURN
Jumps back to the position of the last call of GOSUB and removes it from the stack.
RETURN label
Works like GOTO, but clears the whole stack. Use this to exit from a subroutine, if you want to continue your program somewhere else.
END
Stops the program from any position. The program is also stopped automatically after the last line of code.
WAIT VBL
Waits for the next frame. This (or WAIT n) should be the last command in all loops which do animations and/or handle input, like the main game loop.
WAIT n
Waits n frames (n/60 seconds).
FOR var=a TO b [STEP s] commands NEXT var
Performs a series of commands in a loop a given number of times. The FOR command uses the variable var as a counter, starting with the value a. All commands until NEXT are executed, then the counter is increased by s (or +1 if STEP is omitted). A check is performed to see if the counter is now greater than b. If not, the process is repeated. If it is greater, the program continues with the lines after NEXT. If STEP s is negative, the loop is executed until the counter is less than value b.
DO commands LOOP
Performs commands in an endless loop. You can use GOTO to exit it.
REPEAT commands UNTIL expression
Executes the commands in a loop until the given expression is true. The loop is executed at least once.
WHILE expression commands WEND
Executes the commands in a loop as long as the given expression is true.
SUB name [(parameter-list)] commands END SUB
Defines a subprogram with the given name. The optional parameter list can contain two types of entries: simple variables and array variables (followed by an empty parentheses pair). Entries are separated by commas. By default all variables inside the subprogram are local.
NOTE: Don't use GOTO or GOSUB to jump out of a subprogram!
CALL name [(argument-list)]
Executes the subprogram with the given name and returns to the current position after finishing it. The argument list must match the parameters of the SUB definition. Simple variables, single array elements and entire arrays (followed by an empty parentheses pair) are passed by reference to the subprogram. Other expressions are passed by value.
EXIT SUB
Exits a subprogram before END SUB is reached.
GLOBAL variable-list
Makes variables from the main program available to all subprograms. The list can contain simple variables only. For arrays you should use DIM GLOBAL. This command cannot be used within a subprogram.
PRINT expression-list
Outputs text to the current window. Expressions can be strings or numbers, separated by commas or semicolons. A comma separates the output with a space, a semicolon outputs without space. End the list with a comma or semicolon to keep the cursor at the end of the output, otherwise a new line is started.
INPUT ["prompt";]var
Lets the user enter a text or number on the keyboard and stores it in the variable var. Optionally it can show a prompt text before (cannot be a variable). This enables automatically the keyboard.
LOCATE x,y
Moves the text cursor to column x and row y inside the current window.
WINDOW x,y,w,h,b
Sets the text output window to cell position x,y and sets the size to w columns and h rows. Text will be written to background b (0 or 1).
CLW
Clears the window with spaces and resets the text cursor position.
GAMEPAD n
Enables gamepads for n players. A maximum of 2 players are supported. This disables touchscreen/mouse support.
GAMEPAD OFF
Disables all gamepads and enables touchscreen/mouse support.
UP(p) DOWN(p) LEFT(p) RIGHT(p)
Returns true if the given direction is currently pressed on the direction pad of player p (0/1).
UP TAP(p) DOWN TAP(p) LEFT TAP(p) RIGHT TAP(p)
With the optional TAP keyword, this function returns true only for the first frame the button is pressed.
BUTTON(p,n)
Returns true if button A (n=0) or B (n=1) is currently pressed by player p (0/1).
BUTTON TAP(p,n)
With the optional TAP keyword, this function returns true only for the first frame the button is pressed.
PAUSE ON PAUSE OFF
Enables or disables the automatic pause handling. By default it's enabled, so if you press the pause button, the program stops and shows "PAUSE" on the screen, until the button is pressed again.
PAUSE
Pauses the program and shows the default "PAUSE" screen, even if automatic pause handling is disabled.
PAUSE
Returns true if the pause button was pressed, otherwise false. After calling this function its value is cleared, so it returns each button tap only once. The automatic pause handling needs to be disabled for this function.
Use touch support only if you think it will work well with a computer mouse, too. If you want to create your own game buttons, keep in mind that your game might be unplayable on a computer, because it won't support the keyboard or a real gamepad. Always consider using the standard gamepad functions.
TOUCH.X TOUCH.Y
Returns the current X or Y pixel position where the user touches the screen, or where it was touched the last time.
TOUCH
Returns true if the screen is currently touched.
TAP
Returns true if the screen is currently touched and was not touched the last frame.
KEYBOARD ON KEYBOARD OFF
Enables or disables the keyboard.
INKEY$
Returns the last pressed key as a string. If no key was pressed, it returns an empty string (""). After calling this function its value is cleared, so it returns each pressed key only once. The keyboard needs to be enabled for this function.
All graphics in LowRes NX are based on characters. A character is an 8x8-pixel image with 3 colors plus transparent. They are usually designed in black and white, but are displayed with one of the 8 programmable color palettes.
At program start all characters from ROM entry 2 are copied to video RAM to make them immediately usable.
The display is composed of 3 layers, which are from back to front:
Each sprite and background cell has an attribute called "priority". By setting it, the cell or sprite will appear on a higher display layer. Actually there are 6 layers, from back to front:
Sprites are independent objects, which can be freely moved on the screen. They can have a size of 8x8 pixels (one character) or up to 32x32 pixels by grouping several characters. Each sprite has the standard character attributes (color palette, flip X/Y, priority) and additionally its size.
SPRITE n,x,y,c
Sets the position (x,y) and character (c) of sprite n (0-63). All parameters can be omitted to keep their current settings.
SPRITE OFF [n] SPRITE OFF a TO b
Hides one or more sprites. If all parameters are omitted, all sprites (0 - 63) are hidden. With one parameter only the given sprite is hidden. The last option is to hide sprites in the range from a to b.
SPRITE.A n,(pal,fx,fy,pri,s)
Sets the attributes of sprite n (0-63). All attribute parameters can be omitted to keep their current settings.
pal | palette number (0-7) |
fx | flip horizontally (0/1) |
fy | flip vertically (0/1) |
pri | priority flag (0/1) |
s | size (0-3): 0: 1 character (8x8 px) 1: 2x2 characters (16x16 px) 2: 3x3 characters (24x24 px) 3: 4x4 characters (32x32 px) |
SPRITE.A n,a
Allows setting the attributes as a single 8-bit value.
SPRITE.X(n) SPRITE.Y(n)
Return the position of sprite n.
SPRITE.C(n)
Returns the character of sprite n.
SPRITE.A(n)
Returns the attributes of sprite n as an 8-bit value.
SPRITE HIT(n[,a [TO b]])
Returns true if sprite n collides with another sprite (which means that pixels overlap). If no more parameters are given, it will check with all other visible sprites. If the a parameter is added, it will check only with that sprite a. If all parameters are given, it will check with all sprites from number a to number b.
HIT
Returns the number of the sprite which collided with the sprite of the last call of SPRITE HIT.
A background is a map of 32x32 character cells, which is used for text
and tile based maps or images. Each cell has the information of which
character it contains and additional attributes (color palette, flip
X/Y, priority).
As a character has the size of 8x8 pixels, the resulting background
size is 256x256 pixels, which is larger than the actual screen
(160x128). By modifying the scroll offset of a background, the visible
area can be moved.
If the visible area moves out of the borders of the background, the
display wraps around the edges. This can be used to achieve endless
scrolling.
There is a mode for 16x16-pixel cells. When active, each cell will show
2x2 characters, similar to big sprites. This mode also increases the
background size to 512x512 pixels. Use the DISPLAY command to enable
it.
CLS
Clears both backgrounds with character 0 and resets the current window to the default one.
CLS b
Clears background b with character 0.
ATTR (pal,fx,fy,pri,s)[,m]
Sets the current attributes for cell and text commands. All attribute parameters can be omitted to keep their current settings.
pal | palette number (0-7) |
fx | flip horizontally (0/1) |
fy | flip vertically (0/1) |
pri | priority flag (0/1) |
s | unused (0-3) |
The optional parameter m is an 8-bit binary number used as a mask. It defines which bits of a cell attribute should actually be changed.
ATTR a[,m]
Allows setting the attributes as a single 8-bit value.
BG n
Sets the current background (0 or 1).
CELL x,y,[c]
Sets the cell at position x,y of the current background to character c. If c is omitted, only the attributes of the cell get changed.
CELL.C(x,y)
Returns the character of the cell at position x,y of the current background.
CELL.A(x,y)
Returns the attributes of the cell at position x,y of the current background as an 8-bit value.
BG FILL x1,y1 TO x2,y2 [CHAR c]
Sets all cells in the area from x1,y1 to x2,y2 of the current background to character c. If CHAR c is omitted, only the attributes of the cells get changed.
BG SOURCE a[,w]
Sets the current source for the BG COPY command. The two- dimensional map starts at memory address "a" and has a width of w cells.
Without the width parameter, Background Designer's data format is assumed: The width is read from address a+2 and the actual map data starts at a+4.
By default ROM entry 3 is used as source.
BG COPY x1,y1,w,h TO x2,y2
Copies a two-dimensional part of the current source to the current background. The destination co-ordinates can be outside of the background size (32x32), but they will be wrapped around the edges (32->0, 33->1, etc.).
BG SCROLL x1,y1 TO x2,y2 STEP dx,dy
Moves the content of all cells in the area from x1,y1 to x2,y2 horizontally by dx and vertically by dy cells.
TEXT x,y,s$
Outputs the string s$ to the current background at cell position x,y.
NUMBER x,y,n,d
Outputs the number n to the current background at cell position x,y. The number is formatted to show always d digits. This command is preferred over TEXT to show numbers, as it doesn't need to convert numbers to strings.
FONT c
Sets the current character range used for text output. c is the character where the font starts (space).
The default value is 192, which points to the standard font, if available.
SCROLL b,x,y
Sets the scroll offset of background b (0/1) to pixel co-ordinates x,y.
SCROLL.X(b) SCROLL.Y(b)
Return the scroll offset of background b.
DISPLAY (s,b0,b1,c0,c1)
Sets the display attributes. All attribute parameters can be omitted to keep their current settings.
s | sprites enabled (0/1) |
b0 | background 0 enabled (0/1) |
b1 | background 1 enabled (0/1) |
c0 | BG 0 cell size, |
c1 | BG 1 cell size: 0: 1 character (8x8 pixels) 1: 2x2 characters (16x16 pixels) |
DISPLAY a
Allows setting the attributes as a single 8-bit value.
DISPLAY
Returns the display attributes as an 8-bit value.
PALETTE n,c0,c1,c2,c3
Sets all four colors of palette n (0-7). Color 0 is only used for palette 0 and shown as the screen's backdrop color. The color parameters can be omitted to keep their current settings. Valid color values are 0-63 and can be calculated like this:
VALUE = RED * 16 + GREEN * 4 + BLUE
RED, GREEN and BLUE are values from 0 to 3.
By default all palettes are read from ROM entry 1.
COLOR(p,n)
Returns the value of color n (0-3) from palette p (0-7). You can get the RED, GREEN and BLUE values like this:
RED = INT(VALUE / 16) GREEN = INT(VALUE / 4) MOD 4 BLUE = VALUE MOD 4
ON RASTER CALL name
Sets a subprogram which is executed for every screen line before it's drawn. Usually used to change color palettes or scroll offsets to achieve graphical effects. Raster subprograms must be short.
ON RASTER OFF
Removes the current subprogram.
RASTER
Returns the current screen line (y position). Use this in a raster subprogram.
ON VBL CALL name
Sets a subprogram which is executed after each frame. Can be used to update animations or sounds, even if the main program is blocked by WAIT or INPUT.
ON VBL OFF
Removes the current subprogram.
TIMER
Returns the number of frames shown since LowRes NX was started. The value wraps to 0 when 5184000 is reached, which is about 24 hours.
Coming soon.
DATA constant-list
Stores comma separated numeric and string constants (values, but no variables or expressions) that are accessed by the READ command. DATA commands are not executed and may be placed anywhere in the program.
READ commands access DATA in order, from the top of a program until the bottom. All constants of all DATA commands are read as one continuous list of items.
READ var-list
Reads values from DATA commands and assigns them to the comma separated variables in var-list. The program has an internal pointer to the current DATA value. With each value read, the pointer will move to the next DATA value.
RESTORE [label]
Changes the internal read pointer to another position. This allows to reread data or to select specific data. If the label parameter is omitted, READ will start again from the top of the program. Otherwise the pointer will be set to the jump label.
PEEK(a)
Returns the current 8-bit value (0-255) at memory address a.
POKE a,v
Sets the memory at address a to value v. v can be any integer number, but only the lowest 8 bits are written to memory.
COPY a,n TO d
Copies n bytes starting from memory address a to address d. The source and the destination areas may overlap.
FILL a,n[,v]
Sets n bytes starting from memory address a to value v, or 0 if the parameter is omitted.
ROM(n)
Returns the memory address of ROM entry n.
SIZE(n)
Returns the number of bytes of ROM entry n.
LOAD f,a
Loads the file number f from the current virtual disk to memory starting at address a.
LOAD is meant to be used for tools only. Use ROM entries for game data.
SAVE f,c$,a,n
Saves n bytes starting at memory address a to the current virtual disk as a file number f (0-15) with comment c$ (up to 31 characters).
If this file was loaded before, consider keeping its original comment or allow the user to edit it before saving. If the file is new, the comment should contain at least the type of data, e.g. "CHARACTERS" or "MUSIC".
SAVE is meant to be used for tools only. Use persistent memory to store game states.
The file commands can be used to store data on a virtual disk, which can contain up to 16 files. Its format is the same as the ROM entries part in a program file. This makes it possible to use any NX program directly as a virtual disk to edit its data.
Virtual disks are meant to be used for development tools only, for example image and map editors or music programs. Games should use persistent memory instead. Imagine that the standard LowRes NX console wouldn't have a disk drive.
FILES
Loads the current file directory for use with FILES$.
FILE$(f)
Returns the comment string of file number f. Call FILES before accessing the file directory to update its content, or use FILE$ directly after LOAD or SAVE.
TRACE expression-list
Outputs text to the debugging window. Expressions can be strings or numbers, separated by commas. This command is ignored if the debugging mode is not enabled.
PI
PI is the ratio of the circumference of a circle to its diameter: 3.1415926535...
SIN(x)
The sine of x, where x is in radians.
COS(x)
The cosine of x, where x is in radians.
TAN(x)
The tangent of x, where x is in radians.
ATN(x)
The arctangent of x in radians, i.e. the angle whose tangent is x. The range of the function is -(PI/2) < ATN(X) < (PI/2).
ABS(x)
The absolute value of x.
SGN(x)
The sign of x: -1 if x < 0, 0 if x = 0 and +1 if x > 0.
INT(x)
The largest integer not greater than x; e.g. INT(1.3) = 1 and INT(-1.3) = -2.
EXP(x)
The exponential of x, i.e. the value of the base of natural logarithms (e = 2,71828...) raised to the power x.
LOG(x)
The natural logarithm of x; x must be greater than zero.
SQR(x)
The nonnegative square root of x; x must be nonnegative.
RND
The next number in a sequence of random numbers uniformly distributed in the range 0 <= RND < 1.
RANDOMIZE x
Sets the seed for random numbers to x, which should be an integer value. By default a program starts with seed 0, so the sequence of random numbers is always the same.
RANDOMIZE TIMER
If you want different random numbers each time you run your program, you should insert this line at the beginning.
MIN(x,y)
The MIN function returns the smallest value of two expressions.
MAX(x,y)
The MAX function returns the largest value of two expressions.
SWAP var1,var2
Swaps the data between any two variables of the same type.
LEFT$(s$,n)
Returns a new string with the first n characters of s$.
LEFT$(s$,n)=a$
Overwrites the first characters in the variable s$ with the first n characters of a$.
RIGHT$(s$,n)
Returns a new string with the last n characters of s$.
RIGHT$(s$,n)=a$
Overwrites the last characters in the variable s$ with the last n characters of a$.
MID$(s$,p,n)
Returns a new string with n characters of s$, starting at character p. The first character has the position 1.
MID$(s$,p,n)=a$
Overwrites the given text range in the variable s$ with the first n characters of a$.
INSTR(d$,s$[,p])
Searches the first occurrence of s$ inside of d$ and returns its start position. If it's not found, the function returns 0. Usually the function starts searching at the beginning of the string. Optionally it can start searching at position p.
CHR$(n)
Returns a string containing one character with ASCII code n.
ASC(a$)
Supplies you with the ASCII code of the first character of a$.
LEN(a$)
Returns the number of characters in a$.
VAL(a$)
Converts a number written in a$ into a numeric value.
STR$(n)
Converts the number n into a string.
BIN$(n)
Converts the number n into a binary string.
HEX$(n)
Converts the number n into a hexadecimal string.
LowRes NX has a simplified simulation of CPU cycles. There is a fixed limit of cycles per frame. This assures the same program execution speed on all devices, so if you optimize your program on your device to run smoothly, it will run the same on all other devices.
Each execution of a command, function or operator, as well as access to a variable or a constant count 1 cycle. Some operations have additional costs:
Total cycles per frame | 17556 |
Cycles per VBL interrupt | 1140 |
Cycles per raster interrupt | 51 |
The main program may spend any number of cycles, but when the limit is reached before a WAIT VBL or WAIT command, the execution continues in the next frame. Interrupts have hard limits. If they are exceeded, the program stops with an error.
$0000 - Cartridge ROM (32 KB) $8000 - Character Data (4 KB) $9000 - BG0 Data (2 KB) $9800 - BG1 Data (2 KB) $A000 - Working RAM (16 KB) $E000 - Persistent RAM (256 B) (not available yet) $FE00 - Sprite Registers (256 B) $FF00 - Color Registers (32 B) $FF20 - Video Registers $FF40 - Audio Registers $FF60 - I/O Registers
A character is an 8x8-pixel image with 2 bits per pixel, with a resulting size of 16 bytes. The video RAM has space for 256 characters.
The first 8 bytes of a character contain the low bits of all its pixels, followed by 8 more bytes containing the high bits of all pixels.
A background is a map of 32x32 character cells. Each cell occupies two bytes:
- Character number - Attributes: Bit Purpose 0-2 Palette number 3 Flip X 4 Flip Y 5 Priority 6-7 Unused
There are 64 sprites available, each occupies 4 bytes:
- X position - Y position - Character number - Attributes: Bit Purpose 0-2 Palette number 3 Flip X 4 Flip Y 5 Priority 6-7 Size: 0: 1 character (8x8 px) 1: 2x2 characters (16x16 px) 2: 3x3 characters (24x24 px) 3: 4x4 characters (32x32 px)
Note: X and Y sprite position registers have an offset of 32, so they can move out of the top/left screen borders without using negative numbers. Using the BASIC commands, this offset is removed for convenience.
There are 8 palettes of each 4 colors. One color is one byte:
Bits Component 0-1 Blue 2-3 Green 4-5 Red
$FF20 - Attributes: Bit Purpose 0 Sprites enabled 1 BG0 enabled 2 BG1 enabled 3 BG0 cell size, 4 BG1 cell size: 0: 1 character (8x8 px) (BG 256x256 px) 1: 2x2 characters (16x16 px) (BG 512x512 px) $FF21 - BG0 scroll offset X $FF22 - BG0 scroll offset Y $FF23 - BG1 scroll offset X $FF24 - BG1 scroll offset Y $FF25 - Scroll offset MSB (most significant bits) used for big cell size only: Bit Purpose 0 BG0 X+256 1 BG0 Y+256 2 BG1 X+256 3 BG1 Y+256 $FF26 - Raster line
- Not yet defined -
$FF60 - Gamepad 0 status $FF61 - Gamepad 1 status Gamepad status: Bit Purpose 0 Up 1 Down 2 Left 3 Right 4 Button A 5 Button B $FF62 - Last touch X position $FF63 - Last touch Y position $FF64 - Last pressed key (ASCII code) $FF65 - Status: Bit Purpose 0 Pause button 1 Touch $FF66 - Attributes: Bit Purpose 0-1 Gamepads enabled: 0: off (touchscreen enabled) 1: 1 player (touch disabled) 2: 2 players (touch disabled) 2 Keyboard enabled