Logo Amigan Software
Signetics-based Machines Coding/Gaming Guide

This document was written on 29/8/08, and last updated on 2/11/25, by James Jacobs of Amigan Software. Information herein is believed to be generally accurate, though some is tentative. If you have anything to contribute, please email us.

This page is part of Emerson Arcadia 2001 Central. Emulators, ROMs, manuals and other resources can be found there.

Emerson Arcadia 2001
├ Paddles
├ Graphics
├ Sound
├ Timing
├ Compiler 2001
├ Compatibility Notes
└ Gaming Guide
Interton VC 4000
├ 
Graphics
├ Compatibility Notes
└ Gaming Guide
Elektor TV Games Computer
├ 
Monitor BIOS
├ Signetics EOF (Elektor Object Format)
├ Magazine Articles
├ Compatibility Notes
└ Gaming Guide
PIPBUG/BINBUG-based machines
├ Teletype I/O
├ Cassette I/O
├ Papertape I/O
├ Printer I/O
├ Unarchived Software
├ BINBUG Hardware
├ BINBUG BIOS
├ Floppy Disk I/O
└ Game Help
Signetics Instructor 50
├ I/O Devices
├ USE BIOS
└ Game Help
Signetics TWIN
└ I/O Ports
Central Data 2650
├ Supervisor BIOS
├ DOSes
├ Unarchived Software
└ Game Help
PHUNSY
├ Mini-PHUNSY
└ Game Help
Ravensburger Selbstbaucomputer
├ Monitor BIOS
└ Game Help
MIKIT 2650
└ Game Help
Coin-ops
├ Malzak
├ Astro Wars & Galaxia
├ Laser Battle & Lazarian
├ Zaccaria Pinball for Android
├ Zaccaria Pinball for Switch
└ Zaccaria Pinball for Windows
Multiplatform
├ 
Comparative Tables
├ 2650 CPU
├ 
Project Numbers
├ 
Component Numbers
├ 
Programming Languages Overview
├ 
File Formats Overview
└ 
Signetics AOF (Absolute Object Format)

Emerson Arcadia 2001

Region Size Emerson Arcadia 2001 Tele-Fever Palladium
$0000..$0FFF 4K cartridge ROM
$1000..$10FF 256 bytes mirror of $1800..$18FF CPU RAM cartridge ROM
$1100..$11FF 256 bytes mirror of $1900..$19FF cartridge ROM
$1200..$12FF 256 bytes mirror of $1A00..$1AFF CPU RAM cartridge ROM
$1300..$13FF 256 bytes mirror of $1B00..$1BFF cartridge ROM
$1400..$17FF 1K mirror of $1000..$13FF cartridge ROM
$1800..$1AFF 768 bytes CPU+UVI RAM:
$1800..$18CF 208 bytes upper screen
$18D0..$18EF 32 bytes user RAM
$18F0..$18F7 8 bytes hardware registers
$18F8..$18FB 4 bytes user RAM
$18FC..$18FF 4 bytes hardware registers
$1900..$1908 9 bytes hardware registers
$1909..$190F 7 bytes unmapped
$1910..$191F 16 bytes mirror of $1900..$190F?
$1920..$192F 16 bytes mirror of $1900..$190F?
$1930..$193F 16 bytes mirror of $1900..$190F?
$1940..$194F 16 bytes mirror of $1900..$190F?
$1950..$195F 16 bytes mirror of $1900..$190F?
$1960..$196F 16 bytes mirror of $1900..$190F?
$1970..$197F 16 bytes mirror of $1900..$190F?
$1980..$19BF 64 bytes hardware registers (sprite and UDG imagery)
$19C0..$19F7 56 bytes unmapped
$19F8..$19FF 8 bytes hardware registers
$1A00..$1ACF 208 bytes lower screen
$1AD0..$1AFF 48 bytes user RAM
$1B00..$1BFF 256 bytes mirror of $1900..$19FF
$1C00..$1FFF 1K mirror of $1800..$1BFF cartridge ROM
$2000..$2FFF 4K cartridge ROM
$3000..$3FFF 4K mirror of $1000..$1FFF cartridge ROM
$4000..$4FFF 4K mirror of $0000..$0FFF? cartridge ROM
$5000..$5FFF 4K mirror of $1000..$1FFF cartridge ROM
$6000..$6FFF 4K mirror of $0000..$0FFF? cartridge ROM
$7000..$7FFF 4K mirror of $1000..$1FFF cartridge ROM

Hardware equates/memory map

The architecture of the system is quite straightforward. A Signetics 2650 or 2650A CPU runs the programs and a Signetics 2637 UVI handles input and output. There are a pair of 2114 RAM chips. (There are also a few "glue" chips but these are irrelevant to programming (or emulating) the system.)

The ROM (game cartridge) is mapped to memory as already described. Execution starts from address $0000. (The CPU branches to address $0003 if an interrupt is generated at any time.) Addresses $1800..$1AFF are mapped to the UVI, I/O hardware and/or RAM. The game is not copied to RAM; it is instead run directly from ROM.

The chips may be in any state after a reset, and thus their contents should be cleared to known values at the start of the program to ensure proper operation.

The display is drawn by the UVI 60 times per second (for NTSC). The display is character-based (each character measuring 8*8 pixels), with programmable vertical and horizontal offsets. A choice of two resolutions (128*104 pixels or 16*13 characters, and 128*208 pixels or 16*26 characters) is available. The display is character-mapped, and thus does not need to be generated on the fly. There are 8 colours in the palette: black, white, red, green, blue, yellow, cyan and purple.

There are 56 characters stored in ROM, and 4 which are stored in RAM (and thus user-definable). Lowercase letters and most punctuation marks are not available. There is also a set of 64 "block graphics" characters which can be effectively "swapped in". Each character is displayed in a foreground and background colour. In mode 0 ("normal mode"), there are 4 foreground colours and 1 background colour available. In mode 1 ("board mode"), there are 2 foreground colours and 2 background colours available.

There are also four user-definable single-colour 8*8 sprites which can be freely positioned independently of the character display. The four sprite image definitions can also be used as user-defined graphics, just as with the four "true" user-defined graphics.

There are three buttons on the master console which can be detected by software. There are also twelve or more distinct buttons on each of the two controllers. Each controller also has a paddle, which can be digital or analogue.

There are two sound channels: a square wave channel (with 128 different frequencies possible), and a white noise channel (with 128 different modulations possible). There are 8 volume levels available.

Games are synchronized with the raster beam, as is usual for most systems. Many of the UVI registers can only be read or written at certain points in the frame. The vertical retrace status is available in the Sense pin of the CPU. (The Flag pin of the CPU can be used to invert the colours of all or part of the display.) All other UVI data is mapped to memory locations; specialized I/O commands are not used. The current character row being drawn by the UVI is available as a UVI register (mapped to a memory location). The current raster line being drawn by the UVI is not available but can of course be deduced by cycle counting. Horizontal retrace status is not available (but would deducable if bus DMA contention timings were known).

Arcadia-family BINs are stored and loaded as follows:

ROM Size On disk In memory ORG
4K $0000..$0FFF 1st 4K chunk $0000..$0FFF 1st half of 1st page $0000
8K $1000..$1FFF 2nd 4K chunk $2000..$2FFF 1st half of 2nd page $0000
12K $2000..$0FFF 3rd 4K chunk $4000..$4FFF 1st half of 3rd page $0000
16K $3000..$0FFF 4th 4K chunk $6000..$6FFF 1st half of 4th page $0000
20K $4000..$0FFF 5th 4K chunk $3000..$3FFF 2nd half of 2nd page $1000
24K $5000..$0FFF 6th 4K chunk $5000..$5FFF 2nd half of 3rd page $1000
28K $6000..$0FFF 7th 4K chunk $7000..$7FFF 2nd half of 4th page $1000
30K $7000..$77FF 2K chunk $1000..$17FF 3rd quarter of 1st page $1000
31K $7800..$7BFF 1K chunk $1C00..$1FFF 8th eighth of 1st page $1C00

Since no cartridges larger than 12K are known, this is somewhat arbitrary beyond 12K and definitely arbitrary beyond 16K.
Although Palladium supports up to 31K ROMs (presumably), Emerson and probably Tele-Fever support only up to 8K ROMs.
Cartridge RAM is not possible on any of these machines.
It is not possible to load from a cartridge into the 7th eighth of the 1st page ($1800..$1BFF); thus 32K ROMs are not possible.

Valid programs have certain startup requirements. Omitting these will not cause problems on most emulators but will cause problems on the genuine console. The machine at startup cannot be assumed to be in a known state; you should explicitly initialize it. A soft reset does not reinitialize the contents and status of the UVI, RAM, or even the CPU.
The fourth byte (ie. byte 3) should be $17, which is a RETC,UN instruction. You should use bytes 0..2 to jump past that byte. You would then typically clear then set the PSU and PSL, then wait, then clear memory.
Your code can begin immediately following this code, at byte $20 (32). Of course, some programs use a zero page jump table, so will have this routine stored elsewhere.

Standard bootstrap

Corrections to some common misconceptions about these machines:

There are 8 colours in the palette, not 9.

There is a clock of 3,579,545Hz at the 2621 USG (pin 12 clock). At pin 11 (PCK) there is a 3,579,545Hz clock which is connected to the 2637 UVI. At pin 10 (CK4) the 2650 is connected with a frequency of 894,886.25Hz, because the output divides the input frequency by 4. The frequency measured at the input pin of the 2650 is still the same.
Therefore, the effective speed is approx. 0.89MHz (approx. 3.58MHz÷4), the same as the Interton VC 4000 has.

RAM is 1K (but Emerson-type has access to only half of this), not 28K.
"The Arcadia's makers didn't hook up the highest address line on their pair of 2114 RAM chips; so what should be 1K of RAM is only ½K of RAM." - Ward Shrake.
Even Tele-Fever and Palladium don't appear to have any way to access more than 768 bytes (the last 256 bytes should be mapped to $1B00..$1BFF but is not, and is thus wasted).

The are two sound channels (one tone and one noise), not one.

The "White MPT-03": there is no such system. This misconception arises from erroneous stickers affixed to some MPT-03 games, saying: "For use White Intelligent Game MPT-03". The intended meaning is "For use with Intelligent Game MPT-03".

Paddles

"The potentiometers [ie. P1PADDLE and P2PADDLE] read from $00 to $FE, and going to $FF when VRESET is low. I would assume the other Arcadia titles check to see if the potentiometer is [much] higher than $80 rather than simply looking for a value of $FF which doesn't happen on the real machine."

There are two paddles available. At any given moment they will either both contain X-coordinates or they will both contain Y-coordinates. Bit 6 of BGCOLOUR controls the paddle interpolation for both paddles. If this bit is 0, the Y-coordinates are available for reading. If it is 1, the X- coordinates are available. It seems that read the coordinates and then you set bit 6 of BGCOLOUR for which axis you want to read *next* frame. If you are only interested in one axis there is no need to flip the bit every frame, of course. You can only read the coordinates during vertical blank; reading them while the screen is being drawn will always give $FF.

Also, the Emerson and Schmid (at least) have ports to connect up to two additional hand controllers. The MPT-03 (at least) does not. No known games seem to support these. The hardware in question (unpluggable hand controllers) does not seem to have ever been officially produced, though it would presumably be trivial to develop such hardware, or to modify a "non-unpluggable" hand controller (by cutting the cable and adding a plug) for the purpose. The memory addresses at which these hand controllers would appear is not known (most likely somewhere in the $1909..$190F and/ or $19C0..$19F7 regions). Support for these hand controllers could be added to the emulators if the addresses were known.

The ranges used by each game for each direction are somewhat different. The values returned by the paddles are in fact different on each individual machine, and probably somewhat different for each individual hand controller. A value of $66 or $6A for a centred paddle appears most common.

Game Left/Up Centred Right/Down
Alien Invaders $00..$35 $36..$7D $7E..$FE
Circus $00..$3A $3B..$93 $94..$FE
Hobo $00..$37 $38..$98 $99..$FE
Space Squadron $00..$2F $30..$A8 $A9..$FE

Only rough values are used in the table below:

     X      Y     Paddle is being pushed
    ------------------------------------
    $00    $00    up and left
    $70    $00    up                 +---------+---------+---------+
    $FE    $00    up and right       |   0,0   | $70,0   | $FE,0   |
    $00    $70    left               +---------+---------+---------+
    $70    $70    centred            |   0,$70 | $70,$70 | $FE,$70 |
    $FE    $70    right              +---------+---------+---------+
    $00    $FE    down and left      |   0,$FE | $70,$FE | $FE,$FE |
    $70    $FE    down               +---------+---------+---------+
    $FE    $FE    down and right

Note that these are read-once registers: they can only be read (once) during vblank, and can never be written.

$19FE: P2PADDLE: Right paddle status (8 bits) (read-once)
$19FF: P1PADDLE: Left paddle status (8 bits) (read-once)
During VRST, returns $00..$FE
When mux=0: about $00=up, about $70=middle, about $f1=down
When mux=1: about $07=left, about $70=middle, about $f1=right
While not in VRST, returns $FF

Graphics

3-bit colour codes (eg. as used for background and sprite colours) are as follows (referred to as "standard format" hereafter):

GRB With Flag off With Flag on
%000 White Black
%001 Yellow Blue
%010 Cyan Red
%011 Green Purple (magenta)
%100 Purple (magenta) Green
%101 Red Cyan
%110 Blue Yellow
%111 Black White

Other colours are not available but can of course be simulated by dithering or multiplexing across multiple pixels or frames, eg.:

black + white = grey
red + white = pink
red + yellow = orange
black + yellow = dark yellow
black + yellow + red = brown

Colour artefacting also occurs on the real machine (even in PAL). This is especially noticeable for eg. Robot Killer walls and Parashooter player sprite.

There are two colour modes, selected by the high bit (bit 7) of PITCH ($18FD). Mode 0 allows four character colours over one background colour. Mode 1 ("board mode") allows two character colours over two background colours.

In mode 0 (non-board mode):

bits 5..4 of BGCOLOUR are unused.
bit  3    of BGCOLOUR chooses foreground colour set (see table below).
bits 0..2 of BGCOLOUR are background colour (in standard format).
bits 5..0 of GFXMODE  are unused.

In this mode, foreground colours are:

Screen contents (with Flag off) Screen contents (with Flag on)
$00..$3F $40..$7F $80..$BF $C0..$FF $00..$3F $40..$7F $80..$BF $C0..$FF
BGCOLOUR of %x,x,xx0,xxx White Cyan Purple Blue Black Red Green Yellow
BGCOLOUR of %x,x,xx1,xxx Yellow Green Red Black Blue Purple Cyan White

In mode 1 (board mode):

bits 5..3 of BGCOLOUR are 2nd   foreground colour (in standard format).
bits 0..2 of BGCOLOUR are outer background colour (in standard format).
bits 5..3 of GFXMODE  are 1st   foreground colour (in standard format).
bits 0..2 of GFXMODE  are inner background colour (in standard format).

In this mode, foreground and background colours are:

Screen contents of
$00..$3F $40..$7F $80..$BF $C0..$FF
Foreground colour 1st 2nd 1st 2nd
Background colour Inner Outer

In this mode, the screen is filled with the inner background colour, but is surrounded by a border filled with the outer background colour (although of course if the inner and outer background colours are the same the border will not be apparent). The two background and two foreground colours can all be chosen and used freely. Bit 7 of each character specify whether to use the inner (%0) or outer (%1) background colour for the background (off bits in the image definition). Bit 6 of each character specify whether to use the 1st (%0) or 2nd (%1) foreground colour for the foreground (on bits in the image definition).

Block graphics mode can be set by a $C0 at the start of a line, and terminated by a $40 at the start of a line, or controlled by the high bit (bit 7) of GFXMODE ($19F8). The format is:

    22211100
    22211100
    22211100
    22211100
    55544433
    55544433
    55544433
    55544433

where each digit is the bit position corresponding with that pixel. Bits 7..6 are the colour, as normal. Examples:

    %xx000001   %xx000010   %xx000011   %xx000100   %xx000101   %xx000110
    ......##    ...###..    ...#####    ###.....    ###...##    ######..
    ......##    ...###..    ...#####    ###.....    ###...##    ######..
    ......##    ...###..    ...#####    ###.....    ###...##    ######..
    ......##    ...###..    ...#####    ###.....    ###...##    ######..
    ........    ........    ........    ........    ........    ........
    ........    ........    ........    ........    ........    ........
    ........    ........    ........    ........    ........    ........
    ........    ........    ........    ........    ........    ........

Character vs. block mode, and mode 0 vs. mode 1, are separate issues, and thus the modes can be freely combined.
If you want low-res mode, you should set:

    GFXMODE  as %x,0,xxx,xxx
and BGCOLOUR as %0,x,xxx,xxx

If you want hi-res mode, you should set:

    GFXMODE  as %x,1,xxx,xxx
and BGCOLOUR as %1,x,xxx,xxx

Although it is possible to set them independently, it is generally pointless. The exception would be if you wanted low-resolution mode but did want the $1A00..$1ACF region drawn, and were using VSCROLL to vertically scroll the screen to reveal that area.

VSCROLL ($18FC) is "the complement of the number of lines from the trailing edge of vertical drive to start character display". In other words, you use this register to vertically scroll the entire display. All 8 bits of the register are used for this. Higher values indicate positions towards the top of the screen, lower values indicate positions towards the bottom of the screen (as for sprites).
$FF pushes the display to the top of the screen.
$ED seems to be used by most games.
$DF is the lowest which will show the entire display under MESS V2.

CHARLINE ($18FF) is a read-only hardware register.
Bits 7..4 are apparently unused? (these bits are always set?)
Bits 3..0 indicate the current character line (row) being rendered:

    0..12      = which line
       13 ($D) = end of DMA (ie. start of vertical blank)
       14 ($E) = unused?
       15 ($F) = beginning of DMA (ie. end of vertical blank)

Note that BGCOLOUR appears to be latched during the entire $F0..$FC CHARLINE period; writes to it (to eg. change the background colour) do not take immediate effect. (However, you can switch black/white (eg. 3D Bowling), red/cyan, green/purple (eg. Ocean Battle) or blue/yellow (eg. Dr. Slump, Horse Racing, Pleiades) at any time by toggling the flag pin.) Therefore, blue water with black road in Frogger is not actually possible.

The horizontal resolution is 128 pixels; 16 tiles per row. The vertical resolution is either 104 (13 tiles per column) or 208 (26 tiles per column) pixels tall, Each tile is 8x8 in size. Graphics are character- based (ie. tile-based), not bitmapped. The screen is organized as a 16*13 or 16*26 grid of tiles, one byte per tile. There are also four freely positionable monochrome sprites. You can offset the display horizontally on a per-row (8 rasters) basis and vertically on a per-frame basis.

The "upper screen" is stored from $1800..$18CF; the top row is $1800.. $1810, the 2nd row is $1810..$181F, etc., to the 13th row from $18C0.. $18CF. In low-resolution mode this is all that is used. However, in high- resolution mode, the 13 rows of the "lower screen", stored from $1A00.. $1ACF, are also shown. These 208 "lower screen" bytes are available for use as extra RAM in low-resolution mode.

There are 64 characters In the character set. In non-block mode, these consist of 56 PDGs and 8 UDGs:

Decimal Hex Description
0 $00 built-in empty space (' ')
1..2 $01..$02 built-in diagonal lines ('/', '\')
3 $03 built-in solid ('■')
4..7 $04..$07 built-in side lines
8..11 $08..$0B built-in corners ('┐', '┌', '└', '┘')
12..15 $0C..$0F built-in right-angled triangles ('◢', '◣', '◤', '◥')
16..25 $10..$19 built-in numbers 0..9
26..51 $1A..$33 built-in uppercase letters A..Z
52..55 $34..$37 built-in punctuation ('.', ',', '+', '$')
56..59 $38..$3B sprites #0..#3
60..63 $3C..$3F user defined graphics #0..#3

    $0123456789ABCDEF
     -----------------
$00:  /\#il_jwqasrtgf    $00           : space
$10: 0123456789ABCDEF    $01-$0F       : graphics characters
$20: GHIJKLMNOPQRSTUV    $38-$3B (zxcv): sprites 0-3
$30: WXYZ.,+$zxcvbnmh    $3C-$3F (bnmh): user defined graphics 0-3

$00 ( ): ........ $01 (/): .......# $02 (\): #....... $03 (#): ########
         ........          ......#.          .#......          ########
         ........          .....#..          ..#.....          ########
         ........          ....#...          ...#....          ########
         ........          ...#....          ....#...          ########
         ........          ..#.....          .....#..          ########
         ........          .#......          ......#.          ########
         ........          #.......          .......#          ########

$04 (i): ######## $05 (l): ......## $06 (_): ........ $07 (j): ##......
         ########          ......##          ........          ##......
         ........          ......##          ........          ##......
         ........          ......##          ........          ##......
         ........          ......##          ........          ##......
         ........          ......##          ........          ##......
         ........          ......##          ########          ##......
         ........          ......##          ########          ##......

$08 (w): ######## $09 (q): ######## $0A (a): ##...... $0B (s): ......##
         ########          ########          ##......          ......##
         ......##          ##......          ##......          ......##
         ......##          ##......          ##......          ......##
         ......##          ##......          ##......          ......##
         ......##          ##......          ##......          ......##
         ......##          ##......          ########          ########
         ......##          ##......          ########          ########

$0C (r): .......# $0D (t): #....... $0E (g): ######## $0F (f): ########
         ......##          ##......          #######.          .#######
         .....###          ###.....          ######..          ..######
         ....####          ####....          #####...          ...#####
         ...#####          #####...          ####....          ....####
         ..######          ######..          ###.....          .....###
         .#######          #######.          ##......          ......##
         ########          ########          #.......          .......#

These occupy the low 6 bits (bits 5..0) of the byte. The upper 2 bits (bits 7..6) are used for the foreground colour, as previously described. Block mode is no different, except that a different set of image definitions is used (as previously described), and these occupy all characters 0..63; therefore sprite and UDG imagery cannot be used in block mode.

Strictly speaking there are eight UDGs (User Defined Graphics), but the first four of them always have the same imagery as the four sprites.
The sprite UDGs (imagery at $1980..$199F) are characters $38..$3B/$78..$7B/$B8..$BB/$F8..$FB. The sprite colours, as stored in SPRnnCTRL, have no influence on the colours of these when used as UDGs (only when used as actual sprites); the colours used will be determined in the same way as for any other tile.
The four dedicated UDGs (imagery $19A0..$19BF) are characters $3C..$3F/$7C..$7F/$BC..$BF/$FC..$FF, and are not usable as sprites.

Most consoles implement the Flag line (bit 7 of the PSU): while this is set, all colours are inverted. This even applies to sprites. The Tempest MPT-03 (and presumably all other MPT-03s) and Australian Emerson Arcadia 2001, for example, definitely do implement this. However, some consoles, such as the American Emerson Arcadia 2001, do not implement this and therefore the colours will never be inverted on such machines.

The Sense pin (bit 6 of the PSU) is read-only. It is set (to 1) as described elsewhere, to signify that the vertical retrace interval has begun, and cleared (to 0) to signify that the interval has ended.

Only 84 bytes are assigned for use exclusively as user RAM. There is a 32- byte block from $18D0..$18EF, a 4-byte block from $18F8..$18FB, and a 48- byte block from $1AD0..$1AFF. However, as the screen memory can be read and written to it is also possible to use that for storage; eg. in low- resolution the lower screen memory at $1A00..$1ACF will not be displayed and there is no reason in that case not to use it as 208 bytes of extra RAM, increasing the total available to 292 bytes.

There are 4 sprites, each measuring 8*8 pixels. Their colours and position are independent of the underlying character display. Similar to the way the character display can be vertically "squashed" or "stretched" with bit 7 of BGCOLOUR, each sprite can be vertically "squashed" or "stretched" independently of the character display and the other sprites (using bit 7 or 6 of SPRITESnnCTRL).

The foreground colour (1 bits in the image definition) of a sprite is chosen with bits 5..3 or 2..0 of SPRITESnnCTRL; all of the 8 colours are available. The background of a sprite (0 bits in the image definition) is transparent and thus never drawn (and not collision-checked either).

The coordinates of each sprite are relative to the bottom-left corner of the screen. That is to say, lower Y-coordinates are near the bottom of the screen, and higher Y-coordinates are near the top of the screen. Lower X- coordinates are near the left of the screen, and higher X-coordinates are near the right of the screen.

$18F0: SPRITE0Y
$18F1: SPRITE0X
$18F2: SPRITE1Y
$18F3: SPRITE1X
$18F4: SPRITE2Y
$18F5: SPRITE2X
$18F6: SPRITE3Y
$18F7: SPRITE3X (all read/write)
The horizontal and vertical coordinates of the four sprites will be accessed by the UVI at DMA 15.

$18FC: VSCROLL (read/write)
The vertical offset will be accessed by the UVI at DMA 15.

$18FF: CHARLINE: Row status - last DMA number (4 bits) (read-only)
The status can be accessed anytime in the field when the microprocessor is not paused.
The sequence in 13-row mode is (from start to end of frame):
$FF, $F0, $F1, $F2, $F3, $F4, $F5, $F6, $F7, $F8, $F9, $FA, $FB, $FC, $FD, $FF
The sequence in 26-row mode is (from start to end of frame):
$FF, $F0, $F1, $F2, $F3, $F4, $F5, $F6, $F7, $F8, $F9, $FA, $FB, $FC, $F0, $F1, $F2, $F3, $F4, $F5, $F6, $F7, $F8, $F9, $FA, $FB, $FC, $FD, $FF

$19FA: SPRITES23CTRL (8 bits) (write-only)
Bit 7 : sprite #2 height (0=tall, 1=short)
Bit 6 : sprite #3 height (0=tall, 1=short)
Bits 5..3: sprite #2 colours
Bits 2..0: sprite #3 colours

$19FB: SPRITES01CTRL (8 bits) (write-only)
Bit 7 : sprite #0 height (0=tall, 1=short)
Bit 6 : sprite #1 height (0=tall, 1=short)
Bits 5..3: sprite #0 colours
Bits 2..0: sprite #1 colours

$19FC: BGCOLLIDE: Sprite collision with characters (4 bits) (read-once)
Bits 7..4: always %1111
Bit 3: sprite #3 collision with any character (%0=hit, %1=miss)
Bit 2: sprite #2 collision with any character (%0=hit, %1=miss)
Bit 1: sprite #1 collision with any character (%0=hit, %1=miss)
Bit 0: sprite #0 collision with any character (%0=hit, %1=miss)

It should be read during the vertical reset period.
The bits are reset (to 0) on collision and set (to 1) by reading or the trailing edge of VRST.
Each bit is set to 1 when the AND of the appropriate sprite and background videos is high. Each bit is reset to 0 when accessed or at the end of the vertical blanking period.
Waiting until CHARLINE is $FD or $FF does not seem to work reliably on the real machine. It seems necessary to wait for the Sense bit (like eg. Combat does).

$19FD: SPRITECOLLIDE: Inter-sprite collision (6 bits) (read-once)
Bits 7..6: always %11
Bit 5: sprites #2/#3 collision (%0=hit, %1=miss)
Bit 4: sprites #1/#3 collision (%0=hit, %1=miss)
Bit 3: sprites #1/#2 collision (%0=hit, %1=miss)
Bit 2: sprites #0/#3 collision (%0=hit, %1=miss)
Bit 1: sprites #0/#2 collision (%0=hit, %1=miss)
Bit 0: sprites #0/#1 collision (%0=hit, %1=miss)

It should be read during the vertical reset period.
The bits are reset (to 0) on collision and set (to 1) by reading or the trailing edge of VRST.
Each bit is set to 0 when the AND of the appropriate two sprite videos is high. Each bit is reset to 1 when accessed or at the end of the vertical blanking period.

When multiple sprites are overlain atop one another, and the flag line is off, the RGB values of the overlapping pixels are ANDed together, ie.:

1st colour 2nd colour
Black (rgb) Blue (rgB) Green (rGb) Cyan (rGB) Red (Rgb) Purple (RgB) Yellow (RGb) White (RGB)
Black (rgb) rgb & rgb = rgb rgb & rgB = rgb rgb & rGb = rgb rgb & rGB = rgb rgb & Rgb = rgb rgb & RgB = rgb rgb & RGb = rgb rgb & RGB = rgb
Blue (rgB) rgB & rgb = rgb rgB & rgB = rgB rgB & rGb = rgb rgB & rGB = rgB rgB & Rgb = rgb rgB & RgB = rgB rgB & RGb = rgb rgB & RGB = rgB
Green (rGb) rGb & rgb = rgb rGb & rgB = rgb rGb & rGb = rGb rGb & rGB = rGb rGb & Rgb = rgb rGb & RgB = rgb rGb & RGb = rGb rGb & RGB = rgb
Cyan (rGB) rGB & rgb = rgb rGB & rgB = rgB rGB & rGb = rGb rGB & rGB = rGB rGB & Rgb = rgb rGB & RgB = rgB rGB & RGb = rGb rGB & RGB = rGB
Red (Rgb) Rgb & rgb = rgb Rgb & rgB = rgb Rgb & rGb = rgb Rgb & rGB = rgb Rgb & Rgb = Rgb Rgb & RgB = Rgb Rgb & RGb = Rgb Rgb & RGB = Rgb
Purple (RgB) RgB & rgb = rgb RgB & rgB = rgB RgB & rGb = rgb RgB & rGB = rgB RgB & Rgb = Rgb RgB & RgB = RgB RgB & RGb = Rgb RgB & RGB = RgB
Yellow (RGb) RGb & rgb = rgb RGb & rgB = rgb RGb & rGb = rGb RGb & rGB = rGb RGb & Rgb = Rgb RGb & RgB = Rgb RGb & RGb = RGb RGb & RGB = RGb
White (RGB) RGB & rgb = rgb RGB & rgB = rgB RGB & rGb = rGb RGB & rGB = rGB RGB & Rgb = Rgb RGB & RgB = RbG RGB & RGb = RGb RGB & RGB = RGB

Set bits are uppercase, clear bits are lowercase.
Sprite colours are only affected by the colours of other sprites, never by the colours of the background or of PDG/UDG character tiles.
With the flag line on, the RGB values are OR'd together instead, ie.:

1st colour 2nd colour
White (RGB) Yellow (RGb) Purple (RgB) Red (Rgb) Cyan (rGB) Green (rGb) Blue (rgB) Black (rgb)
White (RGB) RGB | RGB = RGB RGB | RGb = RGB RGB | RgB = RGB RGB | Rgb = RGB RGB | rGB = RGB RGB | rGb = RGB RGB | rgB = RGB RGB | rgb = RGB
Yellow (RGb) RGb | RGB = RGB RGb | RGb = RGb RGb | RgB = RGB RGb | Rgb = RGb RGb | rGB = RGB RGb | rGb = RGb RGb | rgB = RGB RGb | rgb = RGb
Purple (RgB) RgB | RGB = RGB RgB | RGb = RGB RgB | RgB = RgB RgB | Rgb = RgB RgB | rGB = RGB RgB | rGb = RGB RgB | rgB = RgB RgB | rgb = RgB
Red (Rgb) Rgb | RGB = RGB Rgb | RGb = RGb Rgb | RgB = RgB Rgb | Rgb = Rgb Rgb | rGB = RGB Rgb | rGb = RGb Rgb | rgB = RgB Rgb | rgb = Rgb
Cyan (rGB) rGB | RGB = RGB rGB | RGb = RGB rGB | RgB = RGB rGB | Rgb = RGB rGB | rGB = rGB rGB | rGb = rGB rGB | rgB = rGB rGB | rgb = rGB
Green (rGb) rGb | RGB = RGB rGb | RGb = RGb rGb | RgB = RGB rGb | Rgb = RGb rGb | rGB = rGB rGb | rGb = rGb rGb | rgB = rGB rGb | rgb = rGb
Blue (rgB) rgB | RGB = RGB rgB | RGb = RGB rgB | RgB = RgB rgB | Rgb = RgB rgB | rGB = rGB rgB | rGb = rGB rgB | rgB = rgB rgB | rgb = rgB
Black (rgb) rgb | RGB = RGB rgb | RGb = RGb rgb | RgB = RgB rgb | Rgb = Rgb rgb | rGB = rGB rgb | rGb = rGb rgb | rgB = rgB rgb | rgb = rgb

Thus, the number of colour combinations yielding each final colour are:

Final colour For 1 sprite For 2 sprites For 3 sprites For 4 sprites
Flag off Flag on
Black White 1 (12.5%) 27 (42.1875%) 343 (~66.99219%) 3375 (~82.39746%)
Blue Yellow 1 (12.5%) 9 (14.0625%) 49 (~9.57031%) 225 (~5.49316%)
Green Purple 1 (12.5%) 9 (14.0625%) 49 (~9.57031%) 225 (~5.49316%)
Cyan Red 1 (12.5%) 3 (4.6875%) 7 (~1.36719%) 15 (~0.36621%)
Red Cyan 1 (12.5%) 9 (14.0625%) 49 (~9.57031%) 225 (~5.49316%)
Purple Green 1 (12.5%) 3 (4.6875%) 7 (~1.36719%) 15 (~0.36621%)
Yellow Blue 1 (12.5%) 3 (4.6875%) 7 (~1.36719%) 15 (~0.36621%)
White Black 1 (12.5%) 1 (1.5625%) 1 (~0.19531%) 1 (~0.02441%)
Total combinations 8 (100%) 64 (100%) 512 (100%) 4096 (100%)

Sound

This section also applies to Interton and Elektor, not just Arcadia.

Here are the optimal PITCH register values for harmonic melodies:

PITCH Actual NTSC Actual PAL Ideal NTSC Ideal PAL
$FF30.7578130.5176b0?
$FE30.8784330.6373B0 (30.868 Hz)?
$FD31.0000030.7579b0?
$FC31.1225330.8794b0B0 (30.868 Hz)
$FB31.2460331.0020b0?
$FA31.3705231.1255b0?
$F931.4960031.2500b0?
$F831.6224931.3755b0?
$F731.7500031.5020c1?
$F631.8785431.6296c1?
$F532.0081331.7581c1?
$F432.1387731.8878c1?
$F332.2704932.0184c1?
$F232.4032932.1502c1?
$F132.5371932.2831c1?
$F032.6722032.4170C1 (32.703 Hz)?
$EF32.8083332.5521c1?
$EE32.9456132.6883c1C1 (32.703 Hz)
$ED33.0840332.8256c1?
$EC33.2236332.9641c1?
$EB33.3644133.1038c1?
$EA33.5063833.2447c1?
$E933.6495733.3868c#1/d♭1?
$E833.7939933.5300c#1/d♭1?
$E733.9396633.6746c#1/d♭1?
$E634.0865833.8203c#1/d♭1?
$E534.2347833.9674c#1/d♭1?
$E434.3842834.1157c#1/d♭1?
$E334.5350934.2654c#1/d♭1?
$E234.6872334.4163C#1/D♭1 (34.648 Hz)?
$E134.8407134.5686c#1/d♭1?
$E034.9955634.7222c#1/d♭1C#1 (34.648 Hz)
$DF35.1517934.8772c#1/d♭1?
$DE35.3094235.0336c#1/d♭1?
$DD35.4684735.1914c#1/d♭1?
$DC35.6289635.3507d1?
$DB35.7909135.5114d1?
$DA35.9543435.6735d1?
$D936.1192735.8372d1?
$D836.2857136.0023d1?
$D736.4537036.1690d1?
$D636.6232636.3372D1 (36.708 Hz)?
$D536.7943936.5070d1?
$D436.9671436.6784d1D1 (36.708 Hz)
$D337.1415136.8514d1?
$D237.3175437.0261d1?
$D137.4952437.2024d1?
$D037.6746437.3804d1?
$CF37.8557737.5601d#1/e♭1?
$CE38.0386537.7415d#1/e♭1?
$CD38.2233037.9248d#1/e♭1?
$CC38.4097638.1098d#1/e♭1?
$CB38.5980438.2966d#1/e♭1?
$CA38.7881838.4852d#1/e♭1?
$C938.9802038.6757D#1/e♭1 (38.891 Hz)?
$C839.1741338.8682d#1/e♭1D#1/E♭1 (38.891 Hz)
$C739.3700039.0625d#1/e♭1?
$C639.5678439.2588d#1/e♭1?
$C539.7676839.4571d#1/e♭1?
$C439.9695439.6574d#1/e♭1?
$C340.1734739.8597e1?
$C240.3794940.0641e1?
$C140.5876340.2706e1?
$C040.7979340.4793e1?
$BF41.0104240.6901e1?
$BE41.2251340.9031E1 (41.203 Hz)?
$BD41.4421041.1184e1E1 (41.203 Hz)
$BC41.6613841.3360e1?
$BB41.8829841.5559e1?
$BA42.1069541.7781e1?
$B942.3333342.0027e1?
$B842.5621642.2297f1?
$B742.7934842.4592f1?
$B643.0273242.6913f1?
$B543.2637442.9258f1?
$B443.5027643.1630f1?
$B343.7444543.4028F1 (43.654 Hz)?
$B243.9888343.6453f1F1 (43.654 Hz)
$B144.2359543.8904f1?
$B044.4858744.1384f1?
$AF44.7386444.3892f1?
$AE44.9942944.6429f1?
$AD45.2528744.8994f#1/g♭1?
$AC45.5144545.1590f#1/g♭1?
$AB45.7790745.4215f#1/g♭1?
$AA46.0467845.6871f#1/g♭1?
$A946.3176545.9559F#1/G♭1 (46.249 Hz)?
$A846.5917246.2278f#1/g♭1F#1/G♭1 (46.249 Hz)
$A746.8690546.5030f#1/g♭1?
$A647.1497046.7814f#1/g♭1?
$A547.4337347.0633f#1/g♭1?
$A447.7212147.3485f#1/g♭1?
$A348.0122047.6372g1?
$A248.3067547.9294g1?
$A148.6049448.2253g1?
$A048.9068348.5248G1 (48.999 Hz)?
$9F49.2125048.8281g1?
$9E49.5220149.1352g1G1 (48.999 Hz)
$9D49.8354449.4462g1?
$9C50.1528749.7611g1?
$9B50.4743650.0801g1?
$9A50.8000050.4032g#1/a♭1?
$9951.1298750.7305g#1/a♭1?
$9851.4640551.0621g#1/a♭1?
$9751.8026351.3980G#1/A♭1 (51.913 Hz)?
$9652.1456951.7384g#1/a♭1?
$9552.4933352.0833g#1/a♭1G#1/A♭1 (51.913 Hz)
$9452.8456452.4329g#1/a♭1?
$9353.2027052.7872g#1/a♭1?
$9253.5646253.1463a1?
$9153.9315153.5103a1?
$9054.3034553.8793a1?
$8F54.6805654.2535a1?
$8E55.0629454.6329A1 (55.000 Hz)?
$8D55.4507055.0176a1A1 (55.000 Hz)
$8C55.8439755.4078a1?
$8B56.2428655.8036a1?
$8A56.6474856.2050a1?
$8957.0579756.6123a#1/b♭1?
$8857.4744557.0255a#1/b♭1?
$8757.8970657.4449a#1/b♭1?
$8658.3259357.8704A#1/B♭1 (58.270 Hz)?
$8558.7611958.3022a#1/b♭1A#1/B♭1 (58.270 Hz)
$8459.2030158.7406a#1/b♭1?
$8359.6515259.1856a#1/b♭1?
$8260.1068759.6374a#1/b♭1?
$8160.5692360.0962a#1/b♭1?
$8061.0387660.5620b1?
$7F61.5261.0352B1 (61.735 Hz)b1
$7E62.0061.5157b1B1 (61.735 Hz)
$7D62.4962.0040b1b1
$7C62.9962.5000b1b1
$7B63.5063.0040b1b1
$7A64.0263.5163c2c2
$7964.5464.0369c2c2
$7865.0764.5661c2c2
$7765.6265.1042C2 (65.406 Hz)c2
$7666.1765.6513c2C2 (65.406 Hz)
$7566.7366.2076c2?
$7467.3066.7735c2?
$7367.8867.3491c#2/d♭2?
$7268.4767.9348c#2/d♭2?
$7169.0768.5307c#2/d♭2?
$7069.6869.1372C#2/D♭2 (69.296 Hz)C#2/D♭2 (69.296 Hz)
$6F70.3069.7545c#2/d♭2?
$6E70.9470.3829c#2/d♭2?
$6D71.5871.0227d2?
$6C72.2471.6743d2?
$6B72.9172.3380D2 (73.416 Hz)?
$6A73.5973.0140d2?
$6974.2873.7028d2D2 (73.416 Hz)
$6874.9974.4048d2?
$6775.7175.1202d2?
$6676.4575.8495d#2/e♭2?
$6577.2076.5931d#2/e♭2?
$6477.9677.3515D#2/E♭2 (77.782 Hz)D#2/E♭2 (77.782 Hz)
$6378.7478.1250d#2/e♭2?
$6279.5478.9141d#2/e♭2?
$6180.3579.7194e2?
$6081.1880.5412e2?
$5F82.0281.3802E2 (82.407 Hz)?
$5E82.8882.2368e2E2 (82.407 Hz)
$5D83.7783.1117e2?
$5C84.6784.0054e2?
$5B85.5984.9185f2?
$5A86.5385.8516f2?
$5987.4986.8056F2 (87.307 Hz)?
$5888.4787.7809f2F2 (87.307 Hz)
$5789.4888.7784f2?
$5690.5189.7989f#2?
$5591.5690.8430f#2?
$5492.6491.9118F#2/G♭2 (92.499 Hz)?
$5393.7493.0060f#2F#2/G♭2 (92.499 Hz)
$5294.8794.1265g2?
$5196.0295.2744g2?
$5097.2196.4506g2?
$4F98.4297.6563G2 (97.999 Hz)G2 (97.999 Hz)
$4E99.6798.8924g2?
$4D100.95100.160g#2/a♭2?
$4C102.26101.461g#2/a♭2?
$4B103.61102.796G#2/A♭2 (103.826 Hz)?
$4A104.99104.167g#2/a♭2G#2/A♭2 (103.826 Hz)
$49106.41105.574g#2/a♭2?
$48107.86107.021a2?
$47109.36108.507a2?
$46110.90110.035A2 (110.000 Hz)A2 (110.000 Hz)
$45112.49111.607a2?
$44114.12113.225a#2/b♭2?
$43115.79114.890a#2/b♭2?
$42117.52116.604A#2/B♭2 (116.541 Hz)A#2/B♭2 (116.541 Hz)
$41119.30118.371a#2/b♭2?
$40121.14120.192a#2/b♭2?
$3F123.03122.070B2 (123.471 Hz)B2 (123.471 Hz)
$3E124.98124.008b2?
$3D127.00126.008c3?
$3C129.08128.074c3?
$3B131.23130.208C3 (130.813 Hz)C3 (130.813 Hz)
$3A133.46132.415c#3-
$39135.76134.698c#3-
$38138.14137.061C#3/D♭3 (138.591 Hz)?
$37140.61139.509c#3C#3/D♭3 (138.591 Hz)
$36143.16142.045d3?
$35145.81144.676D3 (146.832 Hz)?
$34148.57147.406d3D3 (146.832 Hz)
$33151.42150.240d3?
$32154.39153.186d#3/e♭3?
$31157.48156.250D#3/E♭3 (155.563 Hz)
$30160.69159.439d#3/e♭3?
$2F164.04162.760E3 (164.814 Hz)?
$2E167.53166.223e3E3 (164.814 Hz)
$2D171.17169.837f3?
$2C174.98173.611F3 (174.614 Hz)
$2B178.95177.557f3?
$2A183.12181.686F#3/G♭3 (184.997 Hz)?
$29187.48186.012f#3/g♭3F#3/G♭3 (184.997 Hz)
$28192.05190.549g3?
$27196.85195.313G3 (195.998 Hz)
$26201.90200.321g3?
$25207.21205.592G#3/A♭3 (207.652 Hz)
$24212.81211.149g#3/a♭3?
$23218.72217.014A3 (220.000 Hz)
$22224.97223.214a3?
$21231.59229.779A#3/B♭3 (233.082 Hz)
$20238.61236.742a#3/b♭3?
$1F246.06244.141B3 (246.942 Hz)
$1E254.00252.016b3?
$1D262.47260.417C4 (261.626 Hz)
$1C271.52269.397c#4/d♭4?
$1B281.21279.018C#4/D♭4 (277.183 Hz)
$1A291.63289.352D4 (293.665 Hz)
$19302.84300.481d4?
$18314.96312.500D#4/E♭4 (311.127 Hz)
$17328.08325.521E4 (329.628 Hz)
$16342.35339.674f4?
$15357.91355.114F4 (349.228 Hz)
$14374.95372.024F#4/G♭4 (369.994 Hz)
$13393.70390.625G4 (391.995 Hz)
$12414.42411.184G#4/A♭4 (415.305 Hz)
$11437.44434.028A4 (440.000 Hz)
$10463.18459.559A#4/B♭4 (466.164 Hz)
$0F492.12488.281B4 (493.883 Hz)
$0E524.93520.833C5 (523.251 Hz)
$0D562.43558.036C#5/D♭5 (554.365 Hz)
D5 (587.33 Hz)
$0C605.69600.962D#5 (622.254 Hz)D5 (587.33 Hz)
$0B656.17651.042E5 (659.255 Hz)
$0A715.82710.227F5 (698.456 Hz)
F#5/G♭5 (739.99 Hz)
$09787.40781.250G5 (783.991)
G#5/A♭5 (830.61 Hz)
$08874.89868.056A5 (880.000 Hz)
A#5/B♭5 (932.30 Hz)
$07984.25976.562B5 (987.767 Hz)
C6 (1046.50 Hz)
$061124.861116.071C#6/D♭6 (1108.731 Hz)
D6 (1174.70 Hz)
D#6/E♭6 (1244.50 Hz)
$051312.331302.083E6 (1318.510 Hz)
F6 (1396.90 Hz)
F#6/G♭6 (1480.00 Hz)
$041574.801562.500G6 (1567.982 Hz)
G#6/A♭6 (1661.20 Hz)
A6 (1760.00 Hz)
A#6/B♭6 (1864.66 Hz)
$031968.501953.125B6 (1975.53 Hz)
C7 (2093.00 Hz)
C#7/D♭7 (2217.46 Hz)
D7 (2349.32 Hz)
D#7/E♭7 (2489.02 Hz)
$022624.672604.167E7 (2637.02 Hz)
F7 (2793.83 Hz)
F#7/G♭7 (2959.96 Hz)
G7 (3135.96 Hz)
G#7/A♭7 (3322.44 Hz)
A7 (3520.00 Hz)
A#7/B♭7 (3729.31 Hz)
$013937.003906.250B7 (3951.07 Hz)
$00Rest

This should assist in illustrating why tones are off-key.
High-pitched notes (3..1) cause aliasing effects.
Arcadia can only play notes $00..$7F (shown in green). Interton and Elektor can play all notes $00..$FF (shown in yellow and green). Note that as all Intertons and Elektors are PAL, the NTSC information for $80..$FF is only of theoretical interest.

For Arcadia, the algorithm for tone generation is:

frequency = 7874  ÷ ((PITCH & %01111111) + 1); (NTSC)
frequency = 7812½ ÷ ((PITCH & %01111111) + 1); (PAL )
frequency =    2  * ((PITCH & %01111111) + 1) * horizontal line period;

For Interton/Elektor, the algorithm for tone generation is:

frequency = 7874  ÷ ( PITCH              + 1); (NTSC)
frequency = 7812½ ÷ ( PITCH              + 1); (PAL )
frequency =    2  * ( PITCH              + 1) * horizontal line period;

so for NTSC $01, at 3937 Hz:

1÷3937      = 2 * (1 + 1) * horizontal line period
0.000254    =           4 * horizontal line period
0.0000635   =               horizontal line period

and for NTSC $02, at ~2624 Hz:

1÷2624      = 2 * (2 + 1) * horizontal line period
0.000381    =           6 * horizontal line period
0.0000635   =               horizontal line period

and for PAL $01, at 3906.250 Hz:

1÷3906.25   = 2 * (1 + 1) * horizontal line period
0.000256    =           4 * horizontal line period
0.000064    =               horizontal line period

Thus, horizontal line period is 63.5 µS (NTSC) or 64 µS (PAL).

The table below is similar to the table above, but is laid out as a piano-style keyboard (with unusable keys omitted):

Low Notes
Note B0 C1 C#1
D♭1
D1 D#1
E♭1
E1 F1 F#1
G♭1
G1 G#1
A♭1
A1 A#1
B♭1
B1 C2 C#2
D♭2
D2 D#2
E♭2
E2 F2 F#2
G♭2
G2 G#2
A♭2
A2 A#2
B♭2
B2 C3 C#3
D♭3
D3 D#3
E♭3
E3 F3 F#3
G♭3
NTSC PITCH FE F0 E2 D6 C9 BE B3 A9 A0 97 8E 86 7F 77 70 6D 64 5F 59 54 4F 4B 46 42 3F 3B 38 35 31 2F 2C 2A
PAL PITCH FC EE E0 D4 C8 BD B2 A8 9E 95 8D 85 7E 76 70 69 64 5E 58 53 4F 4A 46 42 3F 3B 37 34 31 2E 2C 29
High Notes
Note G3 G#3
A♭3
A3 A#3
B♭3
B3 C4 C#4
D♭4
D4 D#4
E♭4
E4 F4 F#4
G♭4
G4 G#4
A♭4
A4 A#4
B♭4
B4 C5 C#5
D♭5
D5 D#5
E♭5
E5 F5 G5 A5 B5 C#6
D♭6
E6 G6 B6 E7 B7
NTSC PITCH 27 25 23 21 1F 1D 1B 1A 18 17 15 14 13 12 11 10 0F 0E 0D - 0C 0B 0A 09 08 07 06 05 04 03 02 01
PAL PITCH 27 25 23 21 1F 1D 1B 1A 18 17 15 14 13 12 11 10 0F 0E 0D 0C - 0B 0A 09 08 07 06 05 04 03 02 01

The noise generator works much like the tone generator. As with the tone generator, it only ever generates square waves (ie. the speaker is only ever at maximum plus or maximum minus (here designated as +127 and -128 for convenience), not any intermediate values). However, whereas the tone generator flips from +127 to -127 and vice versa at regular, predictable intervals, the noise generator only flips, on average, on half of those occasions; the rest of the time, the output value is held steady.
Or, to put it a different way, the difference is that whenever the tone generator would flip the amplitude (eg. change from -127 to +127 or vice versa), the amplitude will be randomly chosen to be -127 or +127.
Eg. if you set a noise of $40, this is equivalent to 121.1385Hz. So, approximately every 121th of a second, the following pseudocode would be executed:

    if ((rand() % 2) == 0) value = 127; else value = -127;

So, whereas a tone waveform might look like this:

       _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _
    | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
    | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
    | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
    |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |

a noise waveform of the same frequency might look like this:

       ___   _   _     ___   _____   _   _     _     ___   _   ___   _
    | |   | | | | |   |   | |     | | | | |   | |   |   | | | |   | | | |
    | |   | | | | |   |   | |     | | | | |   | |   |   | | | |   | | | |
    | |   | | | | |   |   | |     | | | | |   | |   |   | | | |   | | | |
    |_|   |_| |_| |___|   |_|     |_| |_| |___| |___|   |_| |_|   |_| |_|

The higher the pitch (frequency), the more random the noise will sound. Ie. lower values are more regular and rhythmic.

Sample values are (with acknowledgements to Tom Pittman):

$7F = static
$10 = rocket exhaust
$04 = machine gun
$02 = engine racing
$00 = silence

Note that the preceding discussion of the noise hardware also applies to systems such as the Interton VC 4000 and expanded Elektor TVGC.

Arcadia sound is inferior to Interton sound in three ways:

Lowest pitches are not possible on Arcadia;
Only 8 volume levels on Arcadia instead of 16; and
No explosion circuit ("banger").

Timing

Anything in this section that contradicts the information here is probably wrong.

3D Bowling waits for approximately 284 CPU cycles for a scanline?

Circus exhibits different behaviour depending on whether the vertical blanking interval takes <= 621 CPU cycles or not (<= approx. 32 rastlines).
Green background (or purple, if theres is no Flag pin) is when the CPU is slow and the UVI is fast (vblank done in not many CPU cycles) (NTSC),
Black background (or white, if there is no Flag pin) is when the CPU is fast and the UVI is slow (vblank takes a lot of CPU cycles) (PAL).

NTSC vertical blank takes 18.91667 CPU cycles per rastline * 20 rastlines = 378.3' CPU cycles per vblank.
PAL vertical blank takes 18.91667 CPU cycles per rastline * 43 rastlines = 813.41681 CPU cycles per vblank.

This is based on information found in the 2637 UVI manual:

While drawing the top area (ie. VOFFSET area):
DMA is $FF.
UVI and RAM are accessible.
Sense is probably pulled low now.
Sprite coordinates and vertical offset are read now.
UDGs may be changed now.

While drawing main area:
DMA is $F0..$FC.
UVI is inaccessible.
RAM may be locked out.
Sense is pulled low now if it wasn't already.

After drawing main area, now it is drawing the bottom area (ie. rest of VOFFSET area):
DMA is $FD.
UVI is accessible.
Sense is maybe pulled high now.
RAM may be locked out.

Now it is doing 3 more (undisplayed) rasters. During this time the electron beam is actually moving diagonally up the screen in preparation for drawing the next frame (ie. this is the true vertical retrace interval):
UVI and RAM are accessible.
DMA is $FF.
Sense is pulled high now if it wasn't already.
UDGs may be changed now.

To wait for the START of the vertical blank period, the usual method is:

WAITVBLSTART:
;start of loop
    tpsu    $80          ;test bits %10000000 of PSU;
    bcfr,eq WAITVBLSTART ;if != goto WAITVBLSTART;
;end of loop

To wait for the END of the vertical blank period, the usual method is:

WAITVBLEND:
;start of loop
    tpsu    $80          ;test bits %10000000 of PSU;
    bctr,eq WAITVBLEND   ;if == goto WAITVBLEND;
;end of loop

So, BCFR is used when waiting for the START of vertical blank (ie. the END of the display frame), and BCTR is used when waiting for the END of vertical blank (ie. the START of the display frame).

To wait for a specified CHARLINE, the usual method is:

WAITLINE:
;start of loop
    loda,r0 CHARLINE
    andi,r0 $0F
    comi,r0 $03          ;change the operand according to desired line
    bcfr,eq WAITLINE ;end of loop

The example above waits until line 3 (ie. CHARLINE == $F3). Change the operand of the COMI instruction as appropriate for other lines.

Compiler 2001

Here is a dissassembly of sync_example.bin, with corresponding source lines shown.
Note that the raw output of Compiler 2001 is encrypted and requires decrypting into ordinary 2650 code. Also, its output is buggy, as indicated below.

cls:
    EORZ    r0       ;$00
    LODI,r1 $D0      ;$01..$02
cls_1:
    STRA,r0 $17FF,r1 ;$03..$05
    BDRR,r1 CLS_1    ;$06..$07
    EORZ    r0       ;$08 (useless!)
    LODI,r1 $D0      ;$09..$0A
cls_2:
    STRA,r0 $19FF,r1 ;$0B..$0D
    BDRR,r1 CLS_2    ;$0E..$0F

set sound off (actual):           set sound off (corrected):
    LODA,r3 PITCH    ;$10..$12        LODA,r3 VOLUME
    ANDI,r3 $F7      ;$13..$14        ANDI,r3 $F7
                                      STRA,r3 VOLUME

set noise off (actual):           set noise off (corrected):
    LODA,r3 PITCH    ;$15..$17        LODA,r3 VOLUME
    ANDI,r3 $EF      ;$18..$19        ANDI,r3 $10
                                      STRA,r3 VOLUME

set text mode (actual):           set text mode (corrected):
    LODA,r0 GFXMODE  ;$1A..$1C        LODA,r0 GFXMODE
    ANDI,r0 $7F      ;$1D..$1E        ANDI,r0 $7F
    STRA,r0 $1918    ;$1F..$21        STRA,r0 GFXMODE

set hi resolution:
    LODA,r3 BGCOLOUR ;$22..$24
    IORI,r3 $80      ;$25..$26
    STRA,r3 BGCOLOUR ;$27..$29

set vertical scroll n:
    LODI,r3 n        ;$2A..$2B
    STRA,r3 VSCROLL  ;$2C..$2E

set horizontal scroll n:
    LODA,r3 VOLUME   ;$2F..$31
    ANDI,r3 $0F      ;$32..$33
    IORI,r3 n        ;$34..$35
    STRA,r3 VOLUME   ;$36..$38

set extended colour mode off      set extended colour mode off
(actual):                         (corrected):
    LODA,r3 PITCH    ;$39..$3B        LODA,r3 PITCH
    ANDI,r3 $7F      ;$3C..$3D        ANDI,r3 $7F
                                      STRA,r3 PITCH

repeat:
set screen colour green
set screen colour blue
forever
LODA,r3 BGCOLOUR
ANDI,r3 $F8
IORI,r3 green [3]
STRA,r3 BGCOLOUR
LODA,r3 BGCOLOUR
ANDI,r3 $F8
IORI,r3 blue [6]
STRA,r3 BGCOLOUR
BCTA,un repeat

Built-in constants:

WHITE=0
YELLOW=1
CYAN=2
GREEN=3
PURPLE=4
RED=5
BLUE=6
BLACK=7

Label styles:

label code
label
.label

Comment styles:

REM comment
/comment

Endless loop styles:

DO
    body
LOOP
REPEAT
    body
FOREVER

Miscellaneous:

: statement separator (same as in BASIC)
variable=value LODI,r0 value
STRA,r0 variable
constant=value constant EQU value

Statements:

BRANCH address BCTA,un
BRANCH SUB address BSTA,un
RETURN RETC,un
DIM variable AS BYTE|INTEGER ?
CLS ?
SCREEN colour Same as SET SCREEN COLOR colour?
SET SOUND OFF ?
SET NOISE OFF ?
SET TEXT MODE ?
SET HI RESOLUTION ?
SET VERTICAL SCROLL 0..255 ?
SET HORIZONTAL SCROLL 0..7 ?
SET EXTENDED COLOR MODE ON|OFF ?
SET SCREEN COLOR colour Same as SCREEN colour?
SYNC ?
SYNC number DMA line, eg. 1 or 25

Compatibility Notes

Observations from a real Australian PAL Emerson Arcadia 2001:

The Flag line is enabled (so colours can be inverted by games).
Joysticks are purely digital; no analog is possible. They are self-centring.
The plastic tab on the left side of cartridge slot must be snapped off for compatibility with American Emerson Arcadia 2001 cartridges.
The paddles return the following values for their extreme and centred positions:

Left player Right player
$07,$00 $68,$00 $FE,$00 $07,$00 $63..$64,$00 $FE,$00
$07,$70..$71 $68,$70..$71 $FE,$70..$71 $07,$69..$6A $63..$64,$69..$6A $FE,$69..$6A
$07,$FE $68,$FE $FE,$FE $07,$FE $63..$64,$FE $FE,$FE

8 Sprites: It doesn't work on the emulator or the real machine. It needs $7Ds at addresses $E and $12 changed to $7Cs. Failing that, it is dependent on the value of r0.

Circus: It has a black background on a real Australian PAL Emerson Arcadia (means PAL detected; green background means NTSC detected).

Counter, Message: These don't fully initialize the system at startup. You will need to issue a POKE VSCROLL $FF command to be able to see the on-screen text.

Frogger 1.4:: On Ami/WinArcadia 34.32, at least, on NTSC, on level 2, collision detection is bad (empty road killing frog sometimes, snakes taking two lives). It is unknown whether this happens on a real NTSC machine. On a real PAL machine, at least, some movement clicks are inaudible (presumably their duration is too short).

Multiplex:: P1PADDLE is always reading as $FF; presumably it is being read at the wrong moment. (So the sprite constantly moves down and right).

Target 1:: It doesn't work on the emulator or the real machine. He is turning on block mode for some reason; it works if that is changed (change byte $0009 from $BF to $03).

Tester1..3:: See the relevant source code (TESTER?.ASM in the Homebrews Pack) for results.

VScroll:: The range of values that are completely visible on the TV is $CC..$FB.

Definite emulator compatibility issues as at V34.32 (these don't happen on real machine):

Doraemon: There is sometimes a blank line between your head and body when moving down.

Dr. Slump: There is sometimes a flickering horizontal line at the top of the "tea-can" and "tea-can man".

Parashooter, Pleiades: The sound is different.

Possible emulator compatibility issues (not retested on emulator nor real machine recently):

Baseball: There are very occasional graphics/collision problems?

Jungler: Some of your bullets are ineffective?

Parashooter: There are graphics glitches when losing a life?

Space Attack: Enemies glitch sometimes when attacking?

Space Raiders, Space Squadron: These occasionally "drop" frames, especially when the action is busy? Player bullets sometimes pass through aliens (the yellow enemies)? Does it ever happen when we are a reasonable distance from them, and alive? If so, it is an emulator bug.

Interton VC 4000

See also the document here.

Also, parts of the Elektor section are applicable. For sound programming, see here.

There are four different cartridge configurations known:

Region Size 2K ROM/EPROM + 0K RAM 4K ROM/EPROM + 0K RAM 4K ROM + 1K RAM1 6K ROM + 1K RAM2
$0000..$07FF 2K game ROM/EPROM
$0800..$0FFF 2K unused game ROM/EPROM
$1000..$13FF 1K unused cartridge RAM game ROM/EPROM
$1400..$15FF ½K unused mirror of $1000..$11FF
$1600..$17FF ½K mirror of $1E00..$1FFF mirror of $1E00..$1FFF (obscures ½K of game ROM/EPROM)
$1800..$1BFF 1K unused mirror of $1000..$13FF cartridge RAM
$1C00..$1DFF ½K unused mirror of $1400..$15FF mirror of $1800..$19FF
$1E00..$1EFF ¼K I/O area
$1F00..$1FFF ¼K PVI area (see Elektor memory map, except that randomizers are never present)
$2000..$7FFF 24K 3 mirrors of $0000..$1FFF

1Backgammon, Chess 1 and Draughts only.
2Chess 2 only.

Hardware equates/memory map

Note that writes to $1E80..$1EFF affect the NOISE register ($1E80). Reads within this range are handled as shown above. (This applies to both Interton and Elektor.)
Vertical and horizontal grid registers are of course usable as ordinary user RAM by games which do not use the grid (such games do not set the "grid/background enable" flag in BGCOLOUR, or set the grid colour to be the same as the screen (background) colour).
Some addresses are read-once. "The object descriptor areas and background definition range can also be read at all times in the normal way. In the I/O and control section, however, reading data causes that location to be reset to $00." - 2636 PVI datasheet.
The Flag pin of the PSU (in the 2650 CPU) controls the paddle interpolation (ie. whether horizontal or vertical).

The following code fragments relevant to the white-noise generator are given in the "TV Games Computer" book, p. 187:

;"sound off"
;NOISE = 0;
eorz    r0
stra,r0 NOISE

;"sound off"
;NOISE = 0;
lodi,r0 0
stra,r0 NOISE

;"PVI sound on"
;NOISE = 4;
lodi,r0 4
stra,r0 NOISE

;"noise (ie. explosion) on"
;NOISE = $10;
lodi,r0 $10
stra,r0 NOISE

Note that "noise", in the discussion in that chapter, refers to the explosion generator ("banger"), not the white-noise generator.

Interton-family BINs are stored and loaded as follows:

ROM Size On disk In memory ORG
2K $0000..$07FF 1st 2K chunk $0000..$07FF 1st quarter of 1st page $0000
4K $0800..$0FFF 2nd 2K chunk $0000..$07FF 2nd quarter of 1st page $0000
6K $1000..$17FF* 3rd 2K chunk $1000..$15FF* 9th..11th sixteenths of 2nd page $0000

* The last 512 bytes of a 6K ROM ($1600..$17FF) is obscured by the mirror there of $1E00..$1FFF; therefore the usable size is limited to 5½K.
Since games are not able to be any larger you don't need to worry about CPU page issues because you will only be using the first page anyway.

Corrections to some common misconceptions about these machines:

The Interton VC 4000 was supposedly made from 1974 but not sold until 1978. However, the Signetics 2650 CPU was only made from 1975; therefore, the Interton VC 4000 could not have been made from 1974.

There are 16 colours, not 9.

There are no multicoloured sprites. All sprites are single-colour (although the same effect can of course be achieved by superimposing multiple sprites atop one another).

Graphics

3-bit colour codes (eg. as used for background and sprite colours) are:

RGB Bright colour Dark colour
%000 Black #1 Black #2
%001 Blue Dark blue
%010 Green Dark green
%011 Cyan Dark cyan
%100 Red Dark red
%101 Purple (magenta) Dark purple
%110 Yellow Dark yellow
%111 White Grey

Colours 0..7 are fullbrite (FB). Colours 8..15 are halfbrite (HB).

For halfbrite machines:

Background colour is:  8 +  (bits 2..0 of BGCOLOUR    )       (ie. 8..15)
Grid colour is:        8 + ((bits 6..4 of BGCOLOUR    ) >> 4) (ie. 8..15)

For fullbrite machines:

Background colour is:       (bits 2..0 of BGCOLOUR    )       (ie. 0..7)
Grid colour is:            ((bits 6..4 of BGCOLOUR    ) >> 4) (ie. 0..7)

For all machines:

Digit colours are:     7 - ((bits 6..4 of BGCOLOUR    ) >> 4) (ie. 0..7)
Sprite #0 colours are: 7 - ((bits 5..3 of SPR01COLOURS) >> 3) (ie. 0..7)
Sprite #1 colours are: 7 -  (bits 2..0 of SPR01COLOURS)       (ie. 0..7)
Sprite #2 colours are: 7 - ((bits 5..3 of SPR23COLOURS) >> 3) (ie. 0..7)
Sprite #3 colours are: 7 -  (bits 2..0 of SPR23COLOURS)       (ie. 0..7)

The digit colour is always dependent on the grid colour, and vice versa, as shown:

BGCOLOUR Grid (fullbrite) Grid (halfbrite) Digits
%x000xxxx Black #1 Black #2 White
%x001xxxx Blue Dark blue Yellow
%x010xxxx Green Dark green Purple
%x011xxxx Cyan Dark cyan Red
%x100xxxx Red Dark red Cyan
%x101xxxx Purple Dark purple Green
%x110xxxx Yellow Dark yellow Blue
%x111xxxx White Grey Black #1

Some Interton VC 4000 family members, such as the Fountain, apparently use fullbrite mode rather than halfbrite mode.
Elektor TVGC seems to use halfbrite mode for at least some games, eg. Catapult. Fullbrite mode may also perhaps be available.

Each digit is 12*20 pixels.
Digit Y-area is 20..39 and/or 200..219, depending on SCORECTRL.
1st digit X-area is 60.. 71.
2nd digit X-area is 76.. 87.
3rd digit X-area is 92..103 or 108..119, depending on SCORECTRL.
4th digit X-area is 108..119 or 124..135, depending on SCORECTRL.

Table of bits controlling which grid segments are lit:

Addresses (hexadecimal) Row Set
1F80:7 1F80:6 1F80:5 1F80:4 1F80:3 1F80:2 1F80:1 1F80:0 1F81:7 1F81:6 1F81:5 1F81:4 1F81:3 1F81:2 1F81:1 1F81:0 0 (raster 20) 1
1
1F82:7 1F82:6 1F82:5 1F82:4 1F82:3 1F82:2 1F82:1 1F82:0 1F83:7 1F83:6 1F83:5 1F83:4 1F83:3 1F83:2 1F83:1 1F83:0 2 2a
3
4
5
6
7
8
9
10
11 2b
12
13
14
15
16
17
18
19 (raster 39)
: : :
1FA4:7 1FA4:6 1FA4:5 1FA4:4 1FA4:3 1FA4:2 1FA4:1 1FA4:0 1FA5:7 1FA5:6 1FA5:5 1FA5:4 1FA5:3 1FA5:2 1FA5:1 1FA5:0 180 (raster 200) 19
181
1FA6:7 1FA6:6 1FA6:5 1FA6:4 1FA6:3 1FA6:2 1FA6:1 1FA6:0 1FA7:7 1FA7:6 1FA7:5 1FA7:4 1FA7:3 1FA7:2 1FA7:1 1FA7:0 182 20a
183
184
185
186
187
188
189
190
191 20b
192
193
194
195
196
197
198
199 (raster 219)

Table of bits controlling segment widths:

$1FA8:7..6: %00 or %10 = 1x       width for sets  1.. 4 (except where overridden by $1FA8:5..0)
            %01        = 2x       width for sets  1.. 4 (except where overridden by $1FA8:5..0)
            %11        = 4x       width for sets  1.. 4 (except where overridden by $1FA8:5..0)
$1FA8:5:    %0         = 1x/2x/4x width for set   4b    (depending on $1FA8:7..6)
            %1         = 8x       width for set   4b
$1FA8:4:    %0         = 1x/2x/4x width for set   4a    (depending on $1FA8:7..6)
            %1         = 8x       width for set   4a
$1FA8:3:    %0         = 1x/2x/4x width for set   3     (depending on $1FA8:7..6)
            %1         = 8x       width for set   3
$1FA8:2:    %0         = 1x/2x/4x width for set   2b    (depending on $1FA8:7..6)
            %1         = 8x       width for set   2b
$1FA8:1:    %0         = 1x/2x/4x width for set   2a    (depending on $1FA8:7..6)
            %1         = 8x       width for set   2a
$1FA8:0:    %0         = 1x/2x/4x width for set   1     (depending on $1FA8:7..6)
            %1         = 8x       width for set   1
: : :
$1FAC:7..6: %00 or %10 = 1x       width for sets 17..20 (except where overridden by $1FAC:5..0)
            %01        = 2x       width for sets 17..20 (except where overridden by $1FAC:5..0)
            %11        = 4x       width for sets 17..20 (except where overridden by $1FAC:5..0)
$1FAC:5:    %0         = 1x/2x/4x width for set  20b    (depending on $1FAC:7..6)
            %1         = 8x       width for set  20b
$1FAC:4:    %0         = 1x/2x/4x width for set  20a    (depending on $1FAC:7..6)
            %1         = 8x       width for set  20a
$1FAC:3:    %0         = 1x/2x/4x width for set  19     (depending on $1FAC:7..6)
            %1         = 8x       width for set  19
$1FAC:2:    %0         = 1x/2x/4x width for set  18b    (depending on $1FAC:7..6)
            %1         = 8x       width for set  18b
$1FAC:1:    %0         = 1x/2x/4x width for set  18a    (depending on $1FAC:7..6)
            %1         = 8x       width for set  18a
$1FAC:0:    %0         = 1x/2x/4x width for set  17     (depending on $1FAC:7..6)
            %1         = 8x       width for set  17

The top left corner of the grid section is at 81,63 in 2621 USG coordinates or 32,20 in 2636 PVI coordinates.
The PVI datasheet is wrong to imply that the last raster in which imagery is displayable is 251 (p. 6), ie. 252 visible rasters. Experimental results (eg. Elektor Tester1) show that at least 268 rasters are visible (for PAL, of course).

The "Tools|Screen editor" function of the emulator is an easy way to experiment and to create game displays.

SPRITEnAX: "If SPRITEnAX is changed during the time that the corresponding object video is being displayed, the portion of the object not yet displayed will be displaced to the new horizontal position." Ie. it is resampled every pixel (at least whilst the sprite is being displayed).

SPRITEnAY: "The value of SPRITEnAY is 'remembered' at the trailing edge of VRST. Thus, if SPRITEnAY is changed during the active scan, the vertical object position change will not be effective until the next active scan." Ie. it is sampled once per frame (at the end of vertical blank).

SPRITEnBY is when to redraw (reuse) the sprite:

    $FF means   0 rastlines gap
    $00 means   1 rastline  gap
    $01 means   2 rastlines gap
    $02 means   3 rastlines gap
    $FC means 253 rastlines gap
    $FD means "never" (but this register will still be reexamined each rastline?)
    $FE means "never" (but this register will still be reexamined each rastline?)

According to the 2636 PVI datasheet:

    Sprite X = SPRITEAXn + 1 (assuming leftmost clock  is 0)
    Sprite Y = SPRITEAYn + 1 (assuming topmost  raster is 0)

SPRITEAXn of >= 228 is not displayed.
SPRITEAYn of >= 253 is not displayed.

SPRITEAXn is not cached (or is cached during HRST).
SPRITEAYn must be changed by (ie. it is cached at) the end of VRST.
SPRITEBXn is cached during HRST.
SPRITEBY is sampled just prior to displaying the last line of the (original or duplicate) object. That sampling presumably wouldn't affect the last line itself.

"The interrupt generation occurs during the horizontal sync at the end of the last line of the sprite display." - Manfred Schneider.

2636 PVI datasheet example:

SPRITE1AX = 42
SPRITE1AY = 36
SPRITE1BX = 30
SPRITE1BY =  9 (10 line gap)

Sprite #1 ( original) is shown at 42..49, 36.. 45.
Sprite #1 ( 1st dup.) is shown at 30..37, 56.. 65.
Sprite #1 ( 2nd dup.) is shown at 30..37, 76.. 85.
Sprite #1 ( 3rd dup.) is shown at 30..37, 96..105.
Sprite #1 ( 4th dup.) is shown at 30..37,116..125.
Sprite #1 ( 5th dup.) is shown at 30..37,136..145.
Sprite #1 ( 6th dup.) is shown at 30..37,156..165.
Sprite #1 ( 7th dup.) is shown at 30..37,176..185.
Sprite #1 ( 8th dup.) is shown at 30..37,196..205.
Sprite #1 ( 9th dup.) is shown at 30..37,216..225.
Sprite #1 (10th dup.) is shown at 30..37,236..245.

Either 250 or 251 is the last displayable rastline.

SPRITE2AX = 62
SPRITE2AY = 20
SPRITE2BX = 88
SPRITE2BY = 27 (28 line gap)

Sprite #2 ( original) is shown at 62..69, 20.. 29.
Sprite #2 ( 1st dup.) is shown at 88..95, 58.. 67.
Sprite #2 ( 2nd dup.) is shown at 88..95, 96..105.
Sprite #2 ( 3rd dup.) is shown at 88..95,134..143.
Sprite #2 ( 4th dup.) is shown at 88..95,172..181.
Sprite #2 ( 5th dup.) is shown at 88..95,210..219.
Sprite #2 ( 6th dup.) is shown at 88..95,248..250/251?

Compatibility Notes

Resolved questions:

Q. Are mid-sprite changes to SPRITEnAX effective?

A. Tester2 confirms that they are.
"If SPRITEnAX is changed during the time that the corresponding object video is being displayed, the portion of the object not yet displayed will be displaced to the new horizontal position." - PVI manual, p. 5.
"Unlike SPRITEnAX and SPRITEnAY, SPRITEnBX and SPRITEnBY may be changed during the scan and such changes will be effected on the current scan." - PVI manual, p. 5.
The first statement is correct. The second statement should be amended to "Unlike SPRITEnAY, SPRITEnBX and SPRITEnBY may be changed during the scan and such changes will be effected on the current scan."

Q.. How do sprite coordinates relate to eg. grid coordinates?
eg. SPRITEnAX=31,SPRITEnAY=19 is top left of grid (according to 2636 PVI datasheet, p. 5)
or is above and to the left of the top left grid (according to 2636 PVI datasheet, p. 6)

A. SPRITEnAY = $FF aligns the sprite to raster 0
SPRITEnAY = $00 aligns the sprite to raster 1
SPRITEnAY = $01 aligns the sprite to raster 2
etc. This is demonstrated by eg. Interton Blackjack.

Unresolved questions:

exactly what the latching behaviour of the PVI is (eg. exactly how often and at what x,y points in the frame the PVI reads or writes each of its registers);
bus contention (each time the PVI accesses memory the CPU is blocked and enters a wait state if it tries to access memory at the same time);
exact state of the system at startup (values of the memory contents).
mirroring: what actual addresses reads and writes are resolved to;
exactly what happens when the CPU executes each of the undocumented CPU instructions.

Test programs could be written in the future to answer those questions.

Interton VC 4000: assumed behaviour is that the low nybbles of CONSOLE and PnFOOKEYS are set to %1111, the same as is proven to occur on an Elektor TVGC.

Gridlines that are the same colour as the background (ie. invisible) don't register collisions. This seems to be the correct behaviour.

Based on the behaviour of Catapult, Destroyer and Submarine+Racing (all for Elektor), the real PVI probably doesn't involve the digits in collision detection.

ESS-011-7-OmegaLanding and ESS-011-D-Painting seem to expect collisions at the far left (< 9) to not register.

"Unlike SPRITEnAX and SPRITEnAY, SPRITEnBX and SPRITEnBY may be changed during the scan [(frame)] and such changes will be effected on the current scan [(frame)]. SPRITEnBX is sampled during each HRST [(horizontal reset)]. Thus, if SPRITEnBX is changed during the display of a duplicate, a portion of the object will be displaced horizontally. For proper operation, SPRITEnBX should be changed only *after* the 'Object Video Completion' status bit [in BGCOLLIDE] indicates completion of the object. SPRITEnBY is sampled just prior to displaying the last line of the object. To effect a change in the vertical offset to the next duplicate, SPRITEnBY must be changed *before* the 'Object Video Completion' status bit [in BGCOLLIDE] indicates completion of the object." - PVI manual, p. 5. But that is incorrect as Circus relies on being able to change SPRITEnAX so that the balloons are drawn properly.

Munch & Crunch: "I have found a bug in Munch & Crunch which no doubt explains the occasional glitches I have seen. It's in my simplistic return from interrupt:

    loda,r0 STOREPSL
    lpsl
    loda,r0 STORER0
    rete,un

The problem of course is that the condition code in the PSL gets changed by the final load instruction. Having looked at other disassemblies I must say that I'm impressed by how the AND $C0 to a copy of PSL correctly restores the condition code. The condition codes were obviously carefully chosen when designing the processor.
From Blackjack:

    loda,r0 PRESERVEPSL  ;r0 = PRESERVEPSL
    strz    r4           ;r4 = r0;
    lpsl                 ;PSL = r0; restores psl but with bank 1
    loda,r0 PRESERVER0   ;restore r0
    andi,r4 $C0
    cpsl    $10          ;Bank 0
    rete,un

The 2650B with its LDPL and STPL instructions was a big improvement." - Derek Andrews.

Elektor TV Games Computer

Parts of the Interton section are applicable. For sound programming, see here.

These are the components of a basic system:

motherboard
power supply
keyboard
joysticks
speaker
cassette interface
cassette deck
VHF/UHF modulator
TV (television)

There are two versions of the Elektor TV Games Computer: the standard "base" or "basic" version, and the "extended" version. The base and extended versions have 2K and 5K of RAM, respectively. There are also other differences. The Rapid Loading Games (RLG) expansion can be added to the extended version. They use the following memory maps:

Region Size Basic Expanded Expanded + RLG
$0000..$07FF 2K monitor (BIOS) ROM
$0800..$08BF 192 bytes motherboard RAM (for use by monitor):
$08B9..$08BA: interrupt vector
$08BE..$08BF: start address of game
motherboard RAM (used for data for RLG load routine)
$08C0..$0FFF 1856 bytes motherboard RAM (for storage of and use by games)
$1000..$15FF 1½K unused motherboard RAM (for storage of and use by games)
$1600..$17FF ½K mirror of $1E00..$1FFF
$1800..$187F 128 bytes mirror of $1D00..$1D7F
$1880..$189F 32 bytes 8 mirrors of $1D9C..$1D9F (input lines 0..3)
$18A0..$18BF 32 bytes 8 mirrors of $1DBC..$1DBF (input lines 4..7)
$18C0..$18DF 32 bytes 8 mirrors of $1DDC..$1DDF (output lines 0..3)
$18E0..$18FF 32 bytes 8 mirrors of $1DFC..$1DFF (output lines 4..7)
$1900..$197F 128 bytes mirror of $1D00..$1D7F
$1980..$199B 28 bytes 7 mirrors of $1D9C..$1D9F (input lines 0..3)
$199C..$199F 4 bytes mirror of $1D9C..$1D9F (input lines 0..3) if (*($73E) == $19) mirror of $1D9C..$1D9F (obscures 4 bytes of RAM)
if (*($73E) == $1D) motherboard RAM (for storage of and use by games)
$19A0..$19BB 28 bytes 7 mirrors of $1DBC..$1DBF (input lines 4..7) motherboard RAM (for storage of and use by games)
$19BC..$19BF 4 bytes mirror of $1DBC..$1DBF (input lines 4..7) if (*($73E) == $19) mirror of $1DBC..$1DBF (obscures 4 bytes of RAM)
if (*($73E) == $1D) motherboard RAM (for storage of and use by games)
$19C0..$19DF 32 bytes 8 mirrors of $1DDC..$1DDF (output lines 0..3) motherboard RAM (for storage of and use by games)
$19E0..$19FF 32 bytes 8 mirrors of $1DFC..$1DFF (output lines 4..7)
$1A00..$1A7F 128 bytes mirror of $1D00..$1D7F
$1A80..$1A9F 32 bytes 8 mirrors of $1D9C..$1D9F (input lines 0..3)
$1AA0..$1ABF 32 bytes 8 mirrors of $1DBC..$1DBF (input lines 4..7)
$1AC0..$1ADF 32 bytes 8 mirrors of $1DDC..$1DDF (output lines 0..3)
$1AE0..$1AFF 32 bytes 8 mirrors of $1DFC..$1DFF (output lines 4..7)
$1B00..$1B7F 128 bytes mirror of $1D00..$1D7F
$1B80..$1B9F 32 bytes 8 mirrors of $1D9C..$1D9F (input lines 0..3)
$1BA0..$1BBF 32 bytes 8 mirrors of $1DBC..$1DBF (input lines 4..7)
$1BC0..$1BCF 16 bytes 4 mirrors of $1DDC..$1DDF (output lines 0..3)
$1BD0..$1BDF 16 bytes 4 mirrors of $1DDC..$1DDF (output lines 0..3) motherboard RAM (for storage of and use by games) motherboard RAM? (data for/from RLG saver/calculation routines)
$1BE0..$1BFF 32 bytes 8 mirrors of $1DFC..$1DFF (output lines 4..7)
$1C00..$1C1F 32 bytes mirror of $1D00..$1D1F unused EPROM (RLG loader or saver routine)
$1C20..$1C7F 96 bytes mirror of $1D20..$1D7F
$1C80..$1C9F 32 bytes 8 mirrors of $1D9C..$1D9F (input lines 0..3)
$1CA0..$1CBF 32 bytes 8 mirrors of $1DBC..$1DBF (input lines 4..7)
$1CC0..$1CDF 32 bytes 8 mirrors of $1DDC..$1DDF (output lines 0..3)
$1CE0..$1CFF 32 bytes 8 mirrors of $1DFC..$1DFF (output lines 4..7)
$1D00..$1D3F 64 bytes I/O #0 $1D00..$1D0F: I/O #0: 1st PSG (Programmable Sound Generator)
$1D10..$1D1F: I/O #0: 2nd PSG (Programmable Sound Generator)
$1D20: I/O #0: optional random number generator #2
·suggested in English book, p. 161
·suggested in English magazine (Sep 1981), p. 24
·suggested in German book, p. 173
·suggested in German magazine (Sep 1981), p. 49
$1D40..$1D7F 64 bytes I/O #1
$1D80..$1D9B 28 bytes 7 mirrors of $1D9C..$1D9F (input lines 0..3)
$1D9C..$1D9F 4 bytes input lines 0..3
$1DA0..$1DBB 28 bytes 7 mirrors of $1DBC..$1DBF (input lines 4..7)
$1DBC..$1DBF 4 bytes input lines 4..7 (input line 7 ($1DBF) is CASIN)
$1DC0..$1DDB 28 bytes 7 mirrors of $1DDC..$1DDF (output lines 0..3)
$1DDC..$1DDF 4 bytes output lines 0..3
$1DE0..$1DFB 28 bytes 7 mirrors of $1DFC..$1DFF (output lines 4..7)
$1DFC..$1DFF 4 bytes output lines 4..7 (output line 7 ($1DFF) is CASOUT)
$1E00..$1E7F 128 bytes unmapped EPROM (RLG loader or saver routine)
$1E80 1 byte optional Interton-style noise generator
$1E81..$1E87 7 bytes unmapped
$1E88..$1E8E 7 bytes keypads and console
$1E8F..$1E97 8 bytes unmapped
$1E98..$1E9B 4 bytes mirror of $1E88..$1E8B
$1E9C..$1EA7 12 bytes unmapped
$1EA8..$1EAE 7 bytes mirror of $1E88..$1E8E
$1EAF..$1EB7 8 bytes unmapped
$1EB8..$1EBB 4 bytes mirror of $1E88..$1E8B
$1EBC..$1EC7 12 bytes unmapped
$1EC8..$1ECE 7 bytes mirror of $1E88..$1E8E
$1ECF..$1ED7 8 bytes unmapped
$1ED8..$1EDB 4 bytes mirror of $1E88..$1E8B
$1EDC..$1EE7 12 bytes unmapped
$1EE8..$1EEE 7 bytes mirror of $1E88..$1E8E
$1EEF..$1EF7 8 bytes unmapped
$1EF8..$1EFB 4 bytes mirror of $1E88..$1E8B
$1EFC..$1EFF 4 bytes unmapped
$1F00..$1FFF ¼K PVI area:
$1F00..$1F0D 14 bytes Sprite #0 imagery & registers
$1F0E..$1F0F 2 bytes PVI RAM
$1F10..$1F1D 14 bytes Sprite #1 imagery & registers
$1F1E..$1F1F 2 bytes PVI RAM
$1F20..$1F2D 14 bytes Sprite #2 imagery & registers
$1F2E..$1F3F 18 bytes unmapped
$1F40..$1F4D 14 bytes Sprite #3 imagery & registers
$1F4E..$1F6D 32 bytes PVI RAM
$1F6E..$1F7F 18 bytes unmapped
$1F80..$1FAC 44 bytes grid
$1FAD 1 byte PVI RAM
$1FAE..$1FBF 18 bytes unmapped
$1FC0..$1FBF 18 bytes unmapped
$1FC0..$1FC3 4 bytes write-only PVI registers (SIZES, SPR01COLOURS, SPR23COLOURS, SCORECTRL)
$1FC4..$1FC5 2 bytes unmapped
$1FC6..$1FC9 4 bytes write-only PVI registers (BGCOLOUR, PITCH, SCORELT, SCORERT)
$1FCA..$1FCD 4 bytes read-only PVI registers (BGCOLLIDE, SPRITECOLLIDE, P1PADDLE, P2PADDLE)
$1FCE..$1FCF 2 bytes unmapped
$1FD0..$1FEF 32 bytes 2 semi-mirrors of $1FC0..$1FCF
$1FF0..$1FF9 10 bytes semi-mirror of $1FC0..$1FC9
$1FFA 1 byte 1st German randomizer? (RANDOM1G)
$1FFB..$1FFE 4 bytes semi-mirror of $1FCB..$1FCE
$1FFF 1 byte 1st English randomizer? (RANDOM1E)
$2000..$21FF ½K mirror of $0000..$01FF unused EPROM (RLG calculation routine)
$2200..$3FFF 7½K mirror of $0200..$1FFF EPROM (RLG games storage area)
$4000..$5FFF 8K mirror of $0000..$1FFF
$6000..$7FFF 8K mirror of $0000..$1FFF

Hardware equates/memory map (basic TVGC)
Hardware equates/memory map (expanded TVGC)

"$2000..$7FFF: It is not used by any other known hardware extension, but it could be used. In fact in one of the Elektor magazines is a project from them which uses this area. It is called in the German Elektor magazine "Schnelle Spiele", meaning fast games. It was developed by Elektor for computer fairs where they presented the TVGC. They didn't want to load the games from cassette, because this would take too long for loading during the fair. So they decided to build this which loads them out of EPROMs instead from tape. It is connected to the Interton-connector of the extension board and a couple of other wires. The Interton-connector was also modified. They connected address lines A13 and A14 onto pins which they didn't use. The new board then has access to the address ranges $2000..$7FFF and $1C00..$1C7F and $1E00..$1E7F." - Manfred Schneider. For more details about the "rapid loading games" enhancement, see the relevant article in Elektor magazine.

Regarding semi-mirroring (note that this also applies to the Interton): "The 'I/O and control' field is actually repeated four times: $1FC0.. $1FCD, $1FD0..$1FDF, $1FE0..$1FEF, $1FF0..$1FFF. This proves of particular interest for the data stored at addresses $1FCA and $1FCB (collisions, VRLE, etc.). Both of these bytes are cleared when read, which can be a nuisance. However, one reader has pointed out that reading $1FCA, say, only clears this one byte - it does not clear $1FDA, $1FEA or $1FFA! This means that a different address can be used for retrieving data for each object, as required, without affecting the information required later on for one of the other objects. Useful!" - Elektor magazine.

The NOISE generator ($1E80) is optional. The base machine generally does not have it, and the expanded machine generally does. However, many games which are nominally intended for the base machine do access this register; thus, it is included in both memory maps.

For PSG sound, the ENABLEn bits are:

Bits 7..6: unused
Bit  5   : noise C (%1=off, %0=on)
Bit  4   : noise B (%1=off, %0=on)
Bit  3   : noise A (%1=off, %0=on)
Bit  2   : tone  C (%1=off, %0=on)
Bit  1   : tone  B (%1=off, %0=on)
Bit  0   : tone  A (%1=off, %0=on)

Eg. Tiny Tim uses the ENABLEn registers as follows:

ENABLE1:
$FF %11,111,111 no sound
$F8 %11,111,000 all noises off
                all tones on
$FD %11,111,101 all noises off
                tone B is on

ENABLE2:
$3B %00,111,011 while falling
                tone C is on, all other channels are off
$07 %00,000,111 when you hit the ground
                all noises on
                all tones off

See also the "TV Games Computer" book, p. 176-184, 204-205.

The keyboard is laid out as follows (see "TV Games Computer" book, p. 31-32):

$1E8B $1E88 $1E89 $1E8A $1E8C $1E8D $1E8E Key bit
UC RCAS WCAS C D E F bit 7 ($80)
START BP1/2 REG 8 9 A B bit 6 ($40)
LC PC MEM 4 5 6 7 bit 5 ($20)
RESET - + 0 1 2 3 bit 4 ($10)

Eg. the "9" key corresponds to bit 6 of $1E8C. Bits are active high (%0=unpressed, %1=pressed). Bits 3..0 are always set.

Monitor BIOS

Monitor BIOS variables are:

Region Size Label Description
$800..$88F 144 bytes MONOB monitor object images (see diagram below):
$800..$817 24 bytes 1st character row (original sprites)
$818..$82F 24 bytes 2nd character row (1st duplicate sprites)
$830..$847 24 bytes 3rd character row (2nd duplicate sprites)
$848..$85F 24 bytes 4th character row (3rd duplicate sprites)
$860..$877 24 bytes 5th character row (4th duplicate sprites)
$878..$88F 24 bytes 6th character row (5th duplicate sprites)
$890..$897 8 bytes MLINE text line
$898 1 byte FSEQ or SILENC function sequence indicator (BP1/2)
$899 1 byte ENTM +, - ENTER key memory
$89A 1 byte MFUNC monitor function index
$89B..$89C 2 bytes MSCR scratch RAM for keyboard routine
$89D 1 byte RKBST right keyboard status
$89E 1 byte LKBST left keyboard status
$89F 1 byte MKBST monitor keyboard status
$8A0..$8AB 12 bytes FSCRM function scratch memory:
$8A0..$8A1 2 bytes ? ?
$8A2..$8A3 2 bytes SADR start address of write file
$8A4..$8A5 2 bytes BEGA memory begin address
$8A6..$8A7 2 bytes ? ?
$8A8..$8A9 2 bytes ENDA memory end address
$8AA 1 byte BCC check char for read and write
$8AB 1 byte MCNT block byte count for read and write
$8AC..$8B4 9 bytes REGM 2650 register status:
$8AC..$8B2 7 bytes r0..r6 respectively
$8B3 1 byte PSL
$8B4 1 byte PSU
$8B5..$8B6 2 bytes BK1 breakpoint address 1
$8B7..$8B8 2 bytes BK2 breakpoint address 2
$8B9..$8BD 5 bytes INTADR space for startup program
$8BE..$8BF 2 bytes PC 2650 program counter (ie. IAR)

The BIOS character set is:

    0/O     1     2/Z     3      4     5/S     6      7
    $00    $01    $02    $03    $04    $05    $06    $07
    ---    ---    ---    ---    ---    ---    ---    ---
    ###    ..#    ###    ###    #.#    ###    ###    ###
    #.#    .##    ..#    ..#    #.#    #..    #..    ..#
    #.#    ..#    ###    ###    #.#    ###    #..    ..#
    #.#    ..#    #..    ..#    ###    ..#    ###    ..#
    #.#    ..#    #..    ..#    ..#    ..#    #.#    ..#
    ###    ..#    ###    ###    ..#    ###    ###    ..#
    $27B..$280    $281..$286    $287..$28C    $28D..$292

     8      9      A      b      C      d      E      F
    $08    $09    $0A    $0B    $0C    $0D    $0E    $0F
    ---    ---    ---    ---    ---    ---    ---    ---
    ###    ###    ###    #..    ###    ..#    ###    ###
    #.#    #.#    #.#    #..    #..    ..#    #..    #..
    ###    ###    ###    ###    #..    ###    ###    ###
    #.#    ..#    #.#    #.#    #..    #.#    #..    #..
    #.#    ..#    #.#    #.#    #..    #.#    #..    #..
    ###    ###    #.#    ###    ###    ###    ###    #..
    $293..$298    $299..$29E    $29F..$2A4    $2A5..$2AA

     G      L      I      n      P      r      =       +
    $10    $11    $12    $13    $14    $15    $16    $17
    ---    ---    ---    ---    ---    ---    ---    ---
    ###    #..    ###    ...    ###    ...    ...    ...
    #..    #..    .#.    ...    #.#    ...    ...    ...
    #..    #..    .#.    ###    ###    ###    ...    ...
    #..    #..    .#.    #.#    #..    #..    ###    ...
    #.#    #..    .#.    #.#    #..    #..    ...    ...
    ###    ###    ###    #.#    #..    #..    ###    ...
    $2AB..$2B0    $2B1..$2B6    $2B7..$2BC    $2BD..$2C2

     +      -      :      x      ?      _      !      N
    $18    $19    $1A    $1B    $5F    $8A    $A2    $AA
    ---    ---    ---    ---    ---    ---    ---    ---
    .#.    ...    ...    ...    ###    ...    .#.    ...
    .#.    ...    .#.    #.#    ..#    ...    .#.    ###
    ###    ###    ...    .#.    ..#    ...    ...    #.#
    .#.    ...    .#.    #.#    ###    ...    .#.    #.#
    .#.    ...    ...    ...    #..    ...    ...    #.#
    ...    ...    ...    ...    #..    #.#    ...    #.#
    $2C3..$2C8    $2C9..$2CE

     l      T      i      :      .
    $BB    $BC    $DF    $E6    $F7
    ---    ---    ---    ---    ---
    #..    ###    ..#    ##.    ...
    #..    ###    ...    ##.    ...
    #..    .#.    .##    ...    ...
    #..    .#.    ..#    ...    ...
    #..    .#.    ..#    ##.    ...
    #..    .#.    ..#    ##.    .#.

Case-insensitive:
Present: ABCDEFG I  L NOP RST   X Z
Missing:        H JK M   Q   UVW Y
Uppercase:
Present: A C EFG I  L NOP  ST     Z
Missing:  B D   H JK M   QR  UVWXY
Lowercase:
Present:  b d    i  l n   r     x
Missing: a c efgh jk m opq stuvw yz

Character imagery is stored from $27B..$580. $27B..$2CE are intentional, $2CF..$580 are unintentional. It is stored left-justified, two characters per byte (ie. one character per nybble). Each character requires 6 nybbles. Eg. "0" and "1" are stored as follows:

    $27B: $E2    ###. ..#.
    $27C: $A6    #.#. .##.
    $27D: $A2    #.#. ..#.
    $27E: $A2    #.#. ..#.
    $27F: $A2    #.#. ..#.
    $280: $E2    ###. ..#.

and are followed by the "2" and "3" pair at $281..$286, and so on. You can determine the ROM storage area of a character with this formula (assuming integer division; ie. round fractions down):

    startaddress = $27B + ((character ÷ 2) * 6)
    endaddress   = $280 + ((character ÷ 2) * 6)

Therefore, for "?" ($5F = 95):

    startaddress = $27B + (( 95 / 2) * 6)
                 = $27B + (  47      * 6)
                 = $27B +   282
                 = $27B +  $11A
                 = $395

and for "T" ($BC = 188):

    startaddress = $27B + ((188 / 2) * 6)
                 = $27B + (  94      * 6)
                 = $27B +   564
                 = $27B +  $234
                 = $4AF

and for "5" ($05 = 5):

    startaddress = $27B + ((  5 / 2) * 6)
                 = $27B + (   2      * 6)
                 = $27B +    12
                 = $27B +    $C
                 = $287

The MONOB RAM area lays out the characters on the screen as follows:

--sprite #0--    --sprite #1--    --sprite #2--    --sprite #3--
###..... $800    ###.###. $806    ###.###. $80C    ###.###. $812 ]
#.#..... $801    #.#.#... $807    ###..#.. $80D    #...#... $813 ]
###.###. $802    ###.#... $808    .#...#.. $80E    #...###. $814 ] original
#...#... $803    #.#.#... $809    .#...#.. $80F    #...#... $815 ] sprites
#...#... $804    #.#.#... $80A    .#...#.. $810    #...#... $816 ]
#...#... $805    #.#.###. $80B    .#..###. $811    ###.###. $817 ]

###..... $818    ###.###. $81E    ###.###. $824    ###.###. $82A ]
#.#..... $819    #.#.#... $81F    ###..#.. $825    #...#... $82B ]
###.###. $81A    ###.#... $820    .#...#.. $826    #...###. $82C ] 1st dup.
#...#... $81B    #.#.#... $821    .#...#.. $827    #...#... $82D ]
#...#... $81C    #.#.#... $822    .#...#.. $828    #...#... $82E ]
#...#... $81D    #.#.###. $823    .#..###. $829    ###.###. $82F ]

###..... $830    ###.###. $836    ###.###. $83C    ###.###. $842 ]
#.#..... $831    #.#.#... $837    ###..#.. $83D    #...#... $843 ]
###.###. $832    ###.#... $838    .#...#.. $83E    #...###. $844 ] 2nd dup.
#...#... $833    #.#.#... $839    .#...#.. $83F    #...#... $845 ]
#...#... $834    #.#.#... $83A    .#...#.. $840    #...#... $846 ]
#...#... $835    #.#.###. $83B    .#..###. $841    ###.###. $847 ]

###..... $848    ###.###. $84E    ###.###. $854    ###.###. $85A ]
#.#..... $849    #.#.#... $84F    ###..#.. $855    #...#... $85B ]
###.###. $84A    ###.#... $850    .#...#.. $856    #...###. $85C ] 3rd dup.
#...#... $84B    #.#.#... $851    .#...#.. $857    #...#... $85D ]
#...#... $84C    #.#.#... $852    .#...#.. $858    #...#... $85E ]
#...#... $84D    #.#.###. $853    .#..###. $859    ###.###. $85F ]

###..... $860    ###.###. $866    ###.###. $86C    ###.###. $872 ]
#.#..... $861    #.#.#... $867    ###..#.. $86D    #...#... $873 ]
###.###. $862    ###.#... $868    .#...#.. $86E    #...###. $874 ] 4th dup.
#...#... $863    #.#.#... $869    .#...#.. $86F    #...#... $875 ]
#...#... $864    #.#.#... $86A    .#...#.. $870    #...#... $876 ]
#...#... $865    #.#.###. $86B    .#..###. $871    ###.###. $877 ]

###..... $878    ###.###. $87E    ###.###. $884    ###.###. $88A ]
#.#..... $879    #.#.#... $87F    ###..#.. $885    #...#... $88B ]
###.###. $87A    ###.#... $880    .#...#.. $886    #...###. $88C ] 5th dup.
#...#... $87B    #.#.#... $881    .#...#.. $887    #...#... $88D ]
#...#... $87C    #.#.#... $882    .#...#.. $888    #...#... $88E ]
#...#... $87D    #.#.###. $883    .#..###. $889    ###.###. $88F ]

The bad monitor ROM requires mirroring of $1DBF at $19BF, as explained in the "TV Games Computer" book, p. 161.

Game startup code is:

$540:
ZPC              = SADR;           // $8BE..$8BF = $8A2..$8A3
SADR             = BK1;            // $8A2..$8A3 = $8B5..$8B6
BEGA             = BK2;            // $8A4..$8A5 = $8B7..$8B8
BK1              = ZBRR1;          // $8B5..$8B6 = $537..$538
BK2              = ZBRR2;          // $8B7..$8B8 = $539..$53A
INTADR..INTADR+4 = UMODE..UMODE+4; // $8B9..$8BD = $53B..$53F
*($8BC)          = *($8B3);        // PSL status
r1..r3           = *($8AD..$8AF);
r4..r6           = *($8B0..$8B2);
PSU              = *($8B4);
PSL              = %00000000;
goto $8BB;
$8BB:
goto $900;

Signetics EOF (Elektor Object Format)

This is the native tape format for this machine. It is is similar to the Signetics Absolute Object Format (see here) but has some differences, primarily:

block header is 'L' rather than ':';
BCC header calculation includes block header (unlike AOF);
all data is stored in binary format (AOF encodes all data except the block header into ASCII format); and
typical payload length is 16 bytes per block rather than 30.

Each block consists of 7 bytes of header and footer, plus the actual data, as follows:

Offset Size Contents Read by
0 1 byte 'L' ($4C) $797
1 1 byte file number ($01..$0F) $7A5
2..3 2 bytes load address (big-endian) $7B5
4 1 byte block payload length, in bytes (usually 16) $7BF
5 1 byte BCC checksum for header bytes 0..4 $7D1
6..6+length-1 length bytes data payload $7D9
6+length 1 byte BCC checksum for data (bytes 6..6+length-1) $7D9

Checksums start as $00. For each emitted byte, the following algorithm is applied:

    SUMC ^= data;
    SUMC <<= 1;

Eg. for a header of $4C $0A $09 $00 $10, the checksum would be:

    SUMC = 0;    // SUMC is %00000000 [$00];
    SUMC ^= $4C; // SUMC is %01001100 [$4C];
    SUMC <<= 1;  // SUMC is %10011000 [$98];
    SUMC ^= $0A; // SUMC is %10010010 [$92];
    SUMC <<= 1;  // SUMC is %00100101 [$25];
    SUMC ^= $09; // SUMC is %00101100 [$2C];
    SUMC <<= 1;  // SUMC is %01011000 [$58];
    SUMC ^= $00; // SUMC is %01011000 [$58];
    SUMC <<= 1;  // SUMC is %10110000 [$B0];
    SUMC ^= $10; // SUMC is %10100000 [$A0];
    SUMC <<= 1;  // SUMC is %01000001 [$41];

Normally, each block contains 16 actual data bytes (for a total block size of 23 bytes). Each game finishes with a block which has 0 data bytes (and thus no data checksum either). The address field of that block is the starting address of the game.
Note that the Elektor BIOS seems not to bother checking the BCCs of the last block (ie. the "start address" block). Which is just as well since that data BCC isn't correct.

PULSE is called with the desired number of pulses in R3 (1..256). Each pulse is as follows:

CASW = $FF;
wait 8 moments (=80 µS)
CASW = $00;
wait 7 moments (=70 µS)

Each of these pulses consists of first a positive and then a negative excursion of the waveform. So it must be the case that while CASW is $FF it is writing the ascending part of the waveform and while CASW is $00 is is writing the descending part. But then CASW remains at $00 afterwards and the waveform has only silence then.

To write the PULSE TRAIN, we call PULSE(7680), then wait 500 microseconds.
To write a ONE, we call PULSE(6), then wait 500 microseconds.
To write a ZERO, we call PULSE(3), then wait 500 microseconds.

When reading, it looks for transitions where CASR is different from its previous value. There are 2 zero crossings (and 2 edges) for each pulse.

To read a bit:

r1 = CASR;
for (SILENC = 256; SILENC > 0; SILENC--)
{   r2 = 119; // transition counter
    RBIT2:
    for (r3 = 3; r3 > 0; r3--) // pause counter
    {   NOP (ie. delay)
        r0 = r1;
        r1 = CASR;
        r0 ^= r1;
        if high bit is set (ie. there was a transition)
        {   r2++;
            if (r2 > 255)
            {   r2 = 255;
            }
            // r2 will be 120..254 for the 1st..135th iterations, and 255 for the 136th and later iterations
            goto RBIT2;
    }   }
    if (r2 >= 122) // 3 or more edges
    {   return r2;
}   }
// timeout after 54 milliseconds
if (*($8A8) == 0) // ie. if verify mode
{   goto RBIT; // BCC error
} // implied else
goto RCAS1; // restart reading

To read a byte:

set alternate register bank, with carry, logical compare
for (MSCR = 8; MSCR > 0; MSCR--)
{   CHI2:
    r5 = RBIT();
    if (r5 <= 133)
    {   // r5 <= 127 (ie. 8 or less edges) is an 0 bit
        // r5 >= 128 && r5 <= 133 (ie. 9..14 edges) is a 1 bit
        r0 = *($89C);
        r5 <<= 1; // this puts the high bit of r2 into the Carry bit
        r0 <<= 1; // this puts the Carry bit into the low bit of r0
        *($89C) = r0;
    } else
    {   if (++r5 != 256)
        {   goto CHI2;
        } // implied else
        {   goto RCAS1; // new leader (pulse train) detected
}   }   }
set main register bank, clear with carry
r1 = r0;
r0 ^= BCC;
r0 <<= 1;
BCC = r0;
return;

To read a file:

do
{   r2 = RBIT();
} while (r2 < 134 || r2 > 140); // wait until we read 15..21 edges

3 pulses is a clear bit (%0).
6 pulses is a set bit (%1).
9 pulses occur in inter-block gaps (sync).

Each pulse lasts 110 microseconds, so there are 9090.90' pulses per second. Unlike with CUTS or similar formats, all pulses are the same width, and therefore all bits are different widths, and therefore there is no fixed data rate; it depends on the data.
Also, there are silent gaps between bits and between bytes (wheras CUTS has no gaps), and sync pulses (not used on CUTS).
Assuming all the data was 0s, and there weren't any gaps, the baud rate would be 3030.30' baud.
Assuming all the data was 1s, and there weren't any gaps, the baud rate would be 1515.15' baud.
The CASIN/CASOUT registers correspond directly to what is on the cassette; ie. the cassette interface does not encode or decode the data but passes it directly between the computer and the cassette recorder (unlike a typical CUTS cassette interface).

The TVC ("TVGC Cassette") file format is an emulator-only format, as follows:

Offset Size Description
0 1 byte magic identifier byte, must be $02
1..2 2 bytes loadaddress (where to start loading the program) (big-endian)
3..4 2 bytes loaded into $8BE.. $8BF (program start vector) (big-endian)
5+ filesize-5 loaded into loadaddress and onwards

Magazine Articles

Elektor magazine articles relevant to the TVGC:

Article ENG HOL FRA GER ITA SPA Notes
Elektor Software Service JUN78 Apr78 SEP78 MAY78 -
VHF/UHF TV modulator OCT78 Oct78 NOV78 OCT78 Dec79 Jan81 EPS-9967
VHF/UHF TV modulator (errata) JUN79 Feb79 - - - - -
Joysticks NOV78 Nov78 - NOV78 Jan80 Jul81 -
Programmable Sound Generator JAN79 Jan79 - JAN79 -
Microprocessor TV Games APR79 Apr79 NOV79 APR79 Dec79 Nov80 -
Building the TVGC APR79 Apr79 NOV79 APR79 Dec79 Nov80 -
Building the TVGC (errata) JUN79 Jun79 - - - May81 -
I played TV games (Part 1) OCT79 Oct79 SEP80 OCT79 Mar80 Jan81 -
I played TV games (Part 2) NOV79 Nov79 OCT80 DEC79 Apr80 Apr81 -
Surround (errata) NOV79 Nov79 - DEC79 Apr80 - ESS-003
Elektor microprocessors MAY80 JUN80 - JUN80 Apr81 May80 -
More on TV games: promises... JUN80 JAN81 NOV80 JUN80 Jan81 Dec81 -
More TV games: over 20K on tape OCT80 - - OCT80 Oct81 ESS-007
We haven't forgotten the TVGC! APR81 - - - -
Random number generator JUL81 JUL81 JUL81 JUL81 Jul82 Jul82 -
TV games extended SEP81 SEP81 SEP81 SEP81 Jan82 Feb82 -
TV games extended (errata) OCT81 - Nov81 OCT81 - Mar82 -
Plug-in EPROM programmer OCT81 OCT81 DEC81 OCT81 Mar82 - aka 2716 Programming Device
15 new programs - - - OCT81 ESS-009
Sound effects generator JUL82 JUL82 JUL82 JUL82 Jul83 Jul83 -
Rapid loading games SEP82 SEP82 SEP82 SEP82 Dec82 Jul83 -
Rapid loading games (errata) - NOV82 NOV82 - - - -
VAM: Video/Audio Modulator FEB83 JAN83 - JAN83 Jun83 Sep83 -
VAM: Video/Audio Modulator (errata) - - - - - Jun84 -
Universal memory card MAR83 MAR83 MAR83 MAR83 Sep83 Jun84 -
2650 single step JUL83 JUL83 JUL83 JUL83 Jul84 Jul84 -
Retronics OCT08 OCT08 NOV08 OCT08 -
Mailbox APR09 FEB09 - - -

Elektor magazine articles relevant only to other Signetics-based machines:

Article ENG HOL FRA GER ITA SPA Notes
Complex Sound Generator SEP78 Sep78 - SEP78 ? ? TI SN76477N
ASCII Keyboard NOV78 Nov78 JAN79 NOV78 Jan80 Jun81 KB05
ASCII Keyboard (errata) DEC78 - - - - - -
Elekterminal Dec78 ? ? ? ? ? -
Capitals from the ASCII Keyboard MAY79 May79 JUN79 SEP79 Feb80 ? -
Shift-Lock for ASCII Keyboard JUL79 Jul79 JUL79 JUL79 ? ? -
Multiple sound effects generator MAR81 FEB81 MAY81 MAR81 Nov81 Oct81 TI SN76477N. Aka Imitator
ASCII keyboard MAY83 MAY83 MAY83 MAY83 Nov83 Nov83 -
Publication started Dec74 Apr61 May78 May70 Jun79 Jan80 -
Publication ended never never never never Apr85 20xx -

"The first Elektor in Italian, subtitled "Electronic - Technical Science and Pleasure", was founded by Jacopo Castelfranchi Editore (JCE) in June 1979. In 1982 it passed to the Jackson Publishing Group. 71 issues were released until April 1985, then Jackson renamed it Elettronica Hobby (later becoming Fare Elettronica). In January 1987 the electronics magazine Progetto of the JCE obtained the rights to Elektor and became, only for a part of the pages, the Italian edition, changing its name to Progetto - the pages of Elektor, then Progetto - Elektor and its pages, finally Progetto Elektor. It continued until 1998, when it was replaced by Progetto PC Upgrade. In July/August 2008 a new Italian Elektor was born, published by Inware Edizioni, which then became digital only and ended with the July/August 2013 issue."

Compatibility Notes

ESS-003-6: Demonstration Program: Apparently it fails to set II (Interrupt Inhibit)? (See Elektor magazine, Oct 1979, p. 31 and 37).

ESS-009-C: Circledrive: The introduction doesn't seem to work? But it seems to just be a joystick calibration routine rather than an introduction.

02-a, 02-b: These are identical except that they have different junk at $912..$917 (which is never used anyway).

03-1, 06-5: These are variants of Example2.

05-1: This is identical to Example3, except that it has different junk at $979..$9FF, $A8A..$AFF, and $BD1..$BFF (which are never used anyway) and different values in the data blocks area ($B1B..$B8B).

06-1: This is identical to 05-1, except that it has different operands in the RESET routine, and different values in the data blocks area ($B3B..$BDB).

08-1a: This is identical to Example2 except with different data ($939..$94B).

10-1a: The picture is invisible as it is drawn in blue on a blue background. To see it, you can eg. POKE BGCOLOUR $78 .

10-1b: This is identical to 08-1a except that it also contains the exploding man (jump to $9DA for unexploded version, $A1B for exploded version).

28-7 (Animated S): You must enable interrupts (POKE CPU 0 in debugger) for this to work.

Dragster: Variables are:

Address German English
$1F0E Loeschenspeicher fuer R0 von Hauptprogramm Erasure store for R0 from main program
$1F0F Joystick Daten Joystick data
$1F1E Gengenzeige (linke und rechte Haelfte) ? (left and right half)
$1F1F Flaggen (bit nr.):
7: Taste gedrueckt Flag links
6: Taste gedrueckt Flag rechts
5: Rundenzaehler Flag links
4: Rundenzaehler Flag rechts
3: Farbinvertierung
2: Stopflagge linker Spieler
1: Stopflagge recht Spieler
0: Startflagge
Flags (bit no.):
7: Key depressed flag left
6: Key depressed flag right
5: Round counter flag left
4: Round counter flag right
3: Colour inversion
2: Stop flag left player
1: Stop flag right player
0: Start flag
$1F4E Hauptuhr (rechter Teil) Main clock (right part)
$1F4F Hauptuhr (linker Teil) Main clock (left part)
$1F50 Leituhr Links (rechter Teil) Route clock left (right part)
$1F51 Leituhr Links (links Teil) Route clock left (left part)
$1F52 Leituhr Rechts (rechter Teil) Route clock right (right part)
$1F53 Leituhr Rechts (links Teil) Route clock right (left part)
$1F54 Univerzalzaehler (loeschbar, ?) Universal counter (erasable, ?)
$1F55 Timingzaehler (vorwaertz) Timing counter (before)
$1F56 Offset Dragster (linke + rechte Haelfte):
0 = Dragster
1 = Stall
2 = Blown
3 = ?
4 = Gear
Offset Dragster (left + right half):
0 = Dragster
1 = Stall
2 = Blown
3 = ?
4 = Gear
$1F57 Dragsterposition links Dragster position left
$1F58 Dragsterposition rechts Dragster position right
$1F59 Drehzahlmonposition links Speed position left
$1F5A Drahzahlmonposition rechts Speed position right
$1F5B Invertierungsflagge:
$00 = normal
$FF = invertiert
Inversion flag:
$00 = normal
$FF = inverted
$1F5C Linke Haelfe: Blinkzaehler in Kombination mit $1F55 -> $D0 = 1 Minute
Rechte Haelfe: SPIELVERSIONSZAEHLER
Left half: Blink counter in combination with $1F55 - > $D0 = 1 Minute
Right half: GAME VERSION COUNTER
$1F5D Offset Hinterrad (rechte + links Haelfte):
? = 0
? = 1
weg = 2
Back wheel offset (right + left half):
? = 0
? = 1
off = 2
$1F5E Duplikathoehe (links + rechte Haelfte):
0 = normal
1 = schrift
Duplicate height (left + right half):
0 = normal
1 = writing
$1F5F Rundenzaehler (links + rechte Halfte) Round counter (left + right half)
$1F60 Startampelfarben Start traffic lights colours
$1F61 Marker delay links Marker delay left
$1F62 Marker delay rechte Marker delay right
$1F63 Dragster ? links Dragster ? left
$1F64 Dragster ? rechts Dragster ? right
$1F65 Dragster delay (rechte und linke Haelfte) Dragster delay (right and left halves)

Example5 (PVI Art): Paddle movement seems to be erratic for some reason.

Explosion, Gunshot: The emulator is not currently fully compatible with these due to incomplete PSG emulation. Specifically:

sound effect should not play until START button is pressed
sound effect probably sounds quite different
sound effect should "fade out" (ie. decay)

Table 48: This will not work as-is in the emulator nor on the real machine: you need to fill in the correct data bytes first. See the book for more details.

PIPBUG/BINBUG-based Machines

PIPBUG-based machines have been offered as kits and as assembled systems, in various configurations by various manufacturers, including Signetics (ie. Philips), Applied Technology, etc.
Their defining characteristic is the use of the PIPBUG ROM BIOS by Signetics (or a compatible OS) as their operating system ("monitor"). (PIP stands for Programmable Integrated Processor; it is another name for the 2650).
Generally, there is software compatibility betweem these machines. However, issues such as the differing locations (and amounts) of expansion RAM in different machines can cause problems.
These machines are not frame-based; they lack a graphics coprocessor (eg. PVI or UVI). The system is effectively CPU + ROM + RAM. There are thus no graphics. However, the output can of course be sent to a Visual Display Unit (VDU) aka monitor (as is done by Ami/WinArcadia), or to a printer-style device, eg. a teletype machine.
Reading input from a keyboard or teletype is achieved by reading the Sense bit of the CPU. Writing output to a VDU or teletype is achieved by writing the Flag bit of the CPU. Or, you can use the Flag bit to output sound. But you cannot do text output and sound output simultaneously. All I/O is done in ASCII format. Loading and saving from/to casette and (on the real machine) to papertape is also supported.
They are designed to be used in conjunction with a standard 110-baud ASCII-based teletype device, such as the DEC VT50, VT52 or VT100, or the Electronics Australia Low Cost VDU.
Some machines possess a S-100 ("Altair") bus or other such features (which are not currently emulated).
The optional 4-digit LED display lacks decimal points, in contrast to the Signetics Instructor 50.

Writing an output character is done from right to left (bit #0 first, then #1..#7), as follows:

Flag on
r5 = r0;
DLAY();
DLAY();
Flag off
for (r4 = 8; r4 > 0; r4--)
{ DLAY();
  r5 >>= 1;
  if (r5 & %10000000)
  { Flag on
  } else
  { Flag off
} }
DLAY();
Flag on

CHIN returns with an input character in R0, but not until there is input (ie. it is synchronous). The high bit is used for parity and is always masked out by CHIN; therefore, only 7-bit input is supported. (Ie. the extended ASCII set values $80..$FF are unsupported.)
The Sense bit is normally high. It pulses low during key transmission (ie. whilst receiving clear bits of a byte). Waiting for the Sense bit to become clear is therefore equivalent to "press any key to continue".
Randomization is normally done by asking the user for a keystroke, then rapidly incrementing a register while waiting for the Sense bit to become clear. Eg.

printf("PRESS ANY KEY");
HERE:
addi,r1 1
tpsu    $80
bctr,eq HERE ;if Sense bit is set

will generate a random number (0..255) in r1.
There is also an optional 4-digit 7-segment LED display which can be attached to the system as an additional output device. Writing to this is done via the WRTD command. The operand is interpreted as follows:

bit 7: 1st digit
bit 6: 2nd digit
bit 5: 3rd digit
bit 4: 4th digit
bits 3..0: digit ($0..$9 = '0'..'9', $A..$F = ' ')

Eg. to write '7' to the 3rd digit would require an operand of $27. A delay is necessary between digit writes on the real machine, but not on the emulator. See the relevant magazine article for more information.

CHIN is used for cassette/papertape/keyboard. It works like this:

do
{ switch to alternate register bank
  PORTC = $80; // enable tape reader
} while (Sense bit is set); // ie. until start of start bit
PORTC = 0; // disable tape reader
DLY(); // wait for half a bit (ie. until centre of start bit)
r4 = 0;
for (r5 = 8; r5 > 0; r5--)
{ DLAY(); // wait for one bit
  r0 = PSU & %10000000;
  r4 <<= 1;
  r0 |= r4;
  r4 = r0;
}
DLAY();
r4 &= %01111111; // delete parity bit
r0 = r4;
switch to main register bank
clear With Carry flag
return;

So it is expecting the following format:

.01234567#

and it returns in the middle of the stop bit (#).
So, we enable the tape reader, wait for the Sense bit to become clear, and then disable the tape reader. Then, we read the eight bits from right to left (bits 0..7) via direct sampling of the PSU at the appropriate moment. The parity bit (bit 7) is then discarded (without checking it).

COUT is used for cassette/papertape/keyboard. r0 is passed as an argument; it is the ASCII character to be output. It works like this:

set Flag bit
r5 = r0;
DLAY();
DLAY();
clear Flag bit
for (r4 = 8; r4 > 0; r4--)
{ DLAY();
  r5 >>= 1;
  if (r5 & %10000000 == %10000000)
  { set Flag bit
  } else
  { clear Flag bit
} }
DLAY();
set Flag bit
return;

So, we set the Flag bit, wait, and clear the Flag bit. Then, we write the eight bits from left to right (bits 0..7). The high bit is not treated any differently to the others. Then we wait again, set the Flag bit and return.
Effectively, we write this for each byte:

##.01234567

where # means Flag set, . means Flag clear, and digits mean Flag is set/ cleared according to the relevant bit. We set the Flag before returning.

When loading, it waits until the input line goes low, then looks for the start character (':').

Some games have 110 baud and 300 baud versions. These are still all stored on cassette at 110 baud; the baud rate in this case actually refers to the speed of keyboard and screen operations, rather than cassette speed.

Hardware equates/memory map

Various memory configurations are possible. Here are some examples, but this is not exhaustive:

Region Size EA 77up2 ("Baby") ABC/PC1500/KT9500 EA 78up5 or PC1001 EA 78up5 + 78up10 Modified ABC1500 with CP1002
$0000..$03FF 1K PIPBUG 1 monitor ROM PIPBUG 1 monitor ROM PIPBUG 1 monitor ROM PIPBUG 1 monitor ROM PIPBUG 2 monitor ROM
$0400..$0436 55 bytes RAM for PIPBUG 1 RAM for PIPBUG 1 RAM for PIPBUG 1 RAM for PIPBUG 1 PIPLA
$0437..$04FF 201 bytes user RAM user RAM user RAM user RAM PIPLA
$0500..$05FF 256 bytes mirror of $0400..$04FF user RAM user RAM user RAM PIPLA
$0600..$07FF 512 bytes mirrors of $0400..$04FF mirror of $0400..$05FF user RAM user RAM PIPLA
$0800..$0861 98 bytes mirror of $0000..$0061 mirror of $0000..$0061 user RAM on 4K version user RAM SMI RAM used by PIPBUG 2 + PIPLA
$0862..$087F 30 bytes mirror of $0062..$007F mirror of $0062..$007F user RAM on 4K version user RAM SMI RAM unused by PIPBUG 2 + PIPLA
$0880..$0BFF 896 bytes mirror of $0080..$03FF mirror of $0080..$03FF user RAM on 4K version user RAM unused
$0C00..$0DFF 512 bytes mirror of $0400..$05FF mirror of $0400..$05FF user RAM on 4K version user RAM motherboard RAM
$0E00..$0FFF 512 bytes mirror of $0600..$07FF mirror of $0600..$07FF user RAM on 4K version user RAM optional RAM
$1000..$13FF 1K mirror of $0000..$03FF mirror of $0000..$03FF user RAM on 4K version user RAM unmapped?
$1400..$1EFF 2.75K mirror of $0400..$0EFF mirror of $0400..$0EFF unused? user RAM unmapped?
$1F00..$1FFF 256 bytes mirror of $0F00..$0FFF mirror of $0F00..$0FFF unused? user RAM mirror of $0F00..$0FFF
$2000..$2FF9 4090 bytes mirror of $0000..$0FF9 mirror of $0000..$0FF9 unused? user RAM unmapped?
$2FFA..$2FFF 6 bytes mirror of $0FFA..$0FFF mirror of $0FFA..$0FFF unused? RAM (for use by EPROM) unmapped?
$3000..$3FFF 4K mirror of $0000..$0FFF mirror of $0000..$0FFF unused? EPROM unmapped?
$4000..$41FF 512 bytes mirror of $0000..$01FF mirror of $0000..$01FF unused? ROM? (for eg. ETI-686) unmapped?
$4200..$57FF 5.5K mirrors of $0000..$0FFF mirrors of $0000..$0FFF unused? RAM (for eg. ETI-686?) unmapped?
$5800..$7CFF 5.25K mirrors of $0000..$0FFF mirrors of $0000..$0FFF unused? RAM (for eg. ETI-686?) unmapped?
$6D00..$7FFF 4.75K mirrors of $0000..$0FFF mirrors of $0000..$0FFF unused? RAM? (eg. for Linearisatie) unmapped?

EA 77up2 ("Baby"): 1K ROM + 256 bytes RAM
Signetics Adaptable Board Computer aka Signetics PC1500 aka Signetics KT9500: 1K ROM + 512 bytes RAM
EA 78up5 ("1K Mini Computer" aka "2650 Mini Computer") or Signetics PC1001: 1K ROM + 1K RAM
EA 78up5+78up10 ("Expanded Mini Computer with EPROM"): 1K ROM + 15.75K RAM + 4K EPROM
Modified ABC1500 with CP1002 (see TN132): 2K ROM + 1152 bytes RAM

The ABC also supports parallel and serial I/O, has an on-board clock, and can be expanded to up to 24K of RAM. These features are not supported by Ami/WinPIPBUG, as the mappings of the serial and parallel I/O ports and clock are unknown.
The Signetics PC1001 Microprocessor Prototyping Card (1K RAM) (assembled) is a different, though closely related, machine.
The Signetics PC2000 is a 4K expansion RAM board suitable for (at least) the PC1001/PC1500/KT9500.
The Signetics PC3000 is another "evaluation kit" (as are the other Signetics-manufactured machines), about which almost nothing is known.
A progression of mostly Applied Technology products can be traced from Baby 2650 to Mini 2650 to ETI-636 to BINBUG-based machines to DG680 to Microbee.

While using PIPBUG 1 "A" and "S" commands, valid inputs are:

<CR> (ie. ENTER) to exit
<LF> (ie. Ctrl+J) to display the next address/register
<nn><CR> to change contents address/register to <nn> and exit
<nn><LF> (ie. type the value then press Ctrl+J) to change contents of address/register to <nn> and display the next address/register.

PIPBUG 1 ROM areas are as follows:

$000..$01C: initialization
$01D..$05A: command handler
$05B..$0A3: input a cmd line into buffer
$0A4..$0AA: subr that stores double precision into temp
$0AB..$0F3: display and alter memory
$0F4..$139: selectively display and alter registers
$13A..$15F: goto address
$160..$1AA: breakpoint runtime code
$1AB..$1C9: subr to clear a bkpt
$1CA..$223: break point
$224..$23C: input two hex chars and form as byte in R1
$23D..$245: calculate the BCC char, EOR and then rotate left
$246..$24F: lookup ASCII char in hex value table
$250..$268: abort exit from any level of subr
$269..$285: byte in R1 output in hex
$286..$2A7: 110 baud input for papertape and char 1 MHz clock
$2A8..$2B3: delay for one bit time
$2B4..$2D4: COUT (Character OUT) routine
$2D5..$30F: get a number from the buffer into R1-R2
$310..$35A: dump to paper tape in object format
$35B..$3B4: subrs for outputting blanks
$3B5..$3FD: load from papertape in object format
$3FE..$3FF: unused?

Note that that PIPBUG, and programs for it, generally run with signed (arithmetic) comparisons, as opposed to the Arcadia, etc. which generally run with unsigned (logical) comparisons.

COUT has the following side effects when called:
PSL: CC = lt;
PSL: primary register bank (r1..r3) is always selected
PSU: Flag pin is always set
r0 = r4 = 0;
r5 = the old r0 (ie. what you passed)
You should not call it when SP > 5 (you need one level of stack for COUT's return address and another level for DLAY's return address).

CHIN has the following side effects when called:
PSL: CC = gt;
PSL: primary register bank (r1..r3) is always selected
PSL: With Carry bit is always set
r0 = r4 = return code (1..127)
r5 = *(DATABUS) = 0;
You should not call it when SP > 5 (you need one level of stack for CHIN's return address and another level for DLAY's/DLY's return address).

Utility EPROM areas are as follows:

Region Label Area Type
$2FFA..$2FFB START RAM data (1st CLI parameter)
$2FFC..$2FFD END RAM data (2nd CLI parameter)
$2FFE..$2FFE NEW RAM data (3rd CLI parameter)
$3C07 GPAR EPROM subroutine
$3C2A INCRT EPROM subroutine
$3C3C PADR EPROM subroutine
$3C50 HEXLIST EPROM subroutine
$3C6A SEARCH EPROM subroutine
$3C8A HEXIN EPROM subroutine
$3CDD VERIFY EPROM subroutine
$3CF8 OK EPROM code section
$3CCB ? EPROM subroutine
$3CCE ? EPROM subroutine
$3D0E FAULTY EPROM code section
$3D3B MOVE EPROM subroutine

Some useful Ctrl-codes are:

Ctrl+G = BEL (7)
Ctrl+H = BS (8)
Ctrl+I = TAB (9)
Ctrl+J = LF (10)
Ctrl+M = CR (13)

Teletype I/O

At 1MHz, there are 1,000,000 short/fast cycles per second, which is 333,333.3' long/slow cycles per second. So each long/slow cycle lasts for 1,000,000÷333,333.3' = 3 µsecs.

At 110 baud, each bit ideally lasts for 9090.90' µsecs.
At 300 baud, each bit ideally lasts for 3333.3' µsecs.
At 1200 baud, each bit ideally lasts for 833.3' µsecs.

For a 110 baud teletype, a full bit delay is:
    bsta,un TDLA  ;3
TDLA:
    eorz    r0    ;2
    bdrr,r0 $ ;256*3
    bdrr,r0 $ ;256*3
TDLY:
    bdrr,r0 $ ;256*3
    lodi,r0 229   ;2
    bdrr,r0 $ ;229*3
    retc,un       ;3

= 3001 long/slow cycles = 9003 µsecs

and a half bit delay is:
    bsta,un TDLY  ;3
TDLY:
    bdrr,r0 $ ;256*3
    lodi,r0 229   ;2
    bdrr,r0 $ ;229*3
    retc,un       ;3

= 1463 long/slow cycles = 4389 µsecs

For a 1200 baud RS-232 terminal, a full bit delay is:
    bsta,un DLAY  ;3
DLAY:
    lodi,r0 89    ;2
DL1:
    bdrr,r0 DL1   ;3
    retc,un       ;3

3+2+(3*89)+3 = 275 long/slow cycles = 825 µsecs

and a half bit delay is:
    bsta,un DLY   ;3
DLY:
    lodi,r0 58    ;2
    bctr,un DL1   ;2
DL1:
    bdrr,r0 DL1   ;3
    retc,un       ;3

3+2+2+(3*58)+3 = 184 long/slow cycle s = 552 µsecs

Note that these delays are shorter than the ideals. However, there is also code that must be run by the caller to process (emit/receive) each bit, which takes additional time to run.

Each character begins with a start bit (%0). Then data bits 0..6 are sent (least significant bits first). Then a parity bit is sent. Then stop bits are sent.
The letter "U" has the 7-bit ASCII code of $55 (%1010101). This would be transmitted as %0,1010101,1,00.

Cassette I/O

A clear (0) bit (Sense bit off) is represented by a slowly pulsing signal. About 10 slowly pulsing cycles represents a clear bit.
A set (1) bit (Sense bit on) is represented by a quickly pulsing signal. About 20 quickly pulsing cycles represents a set bit.

The length of each bit, in time, is identical regardless of its value. (This is in contrast to the system used on the Elektor, which has identical pulses for all values and differentiates values by the positioning of the pulses.)

PIPBUG 1 encodes/decodes the files as Signetics Absolute Object Format (AOF) at 110 baud. There is a low start bit preceding each byte, and two high stop bits following each byte. The parity bit (bit 7 of the data) is always thrown away when reading. The data rate is approximately 10 raw data bytes per second. As values are encoded into ASCII pairs, the actual number of bytes loaded/saved per second from the user's point of view is about 5.

PIPBUG, BINBUG (except ACOS), CD2650 and (presumably) Selbstbaucomputer use a standard Kansas City Computer Users Tape Standard (CUTS) cassette interface to transform standard teletype I/O into cassette tape I/O (ie. high and low bits are turned into the appropriate pulse trains when recording, and pulse trains are analyzed and decoded into high and low bits during playback), usually at 110 baud:

Every "0" bit becomes 21.81' cycles (pulses) of a 2400 Hz tone, and
Every "1" bit becomes 10.90' cycles (pulses) of a 1200 Hz tone.

In practice, exactly 22 or 11 pulses should be done (as it is best to wait until the next zero crossing before doing the next bit).
The BIOS and games only see the teletype Sense and Flag lines, they cannot see the pulse trains. The cassette interface is invisible to the software; as far as it knows there is only an ordinary teletype attached. This means that you can record/play any sort of teletype I/O directly to/ from the tape, not just formal dumps.
300 baud is identical to 110 baud except that only 8 (instead of 22) or 4 (instead of 11) pulses are done; the pulses themselves are identical.

To load a tape, translate it to teletype format:

22 2400 Hz pulses in 9.09' msec = having teletype Sense low for 9.09' msec ("0").
11 1200 Hz pulses in 9.09' msec = having teletype Sense high for 9.09' msec ("1").
If we see a zero crossing every 413.2231 µsec it is a "0", and we should see 22 of those (or more if there are several 0 bits).
If we see a zero crossing every 826.4463 µsec it is a "1", and we should see 11 of those (or more if there are several 1 bits).

and vice versa when saving:

While teletype Sense is 0, flip the tape Sense every 413.2231 ÷ 2 µsec.
While teletype Sense is 1, flip the tape Sense every 826.4463 ÷ 2 µsec.

This is sufficient for all baud rates and encodings.

Here are diagrammatic views of the system, in record mode:

At computer Tape Terminal (VDU/keyboard)
Flag -> tape can save this -> VDU
Sense <- input comes from kybd <- Keyboard

and in playback mode:

At computer Tape Terminal (VDU/keyboard)
Flag -> tape ignores this -> VDU
Sense <- input comes from tape Neither

Papertape I/O

The "teletype tape reader" mentioned in the Prometheus manual is a slow one built into the teletype machine (but not the same as the printer + keyboard). It runs at 10 characters per second, which is 110 baud equivalent. 10 bytes = 10 characters = 1 inch = 1 second.
The "fast paper-tape reader" is a High Speed Paper Tape (HSPT) reader unit. It run at 300 characters per second, which is 3300 baud equivalent.

For input:
If you're using a slow paper tape reader, Prometheus (and PIPBUG 1) can control it directly via the I/O control port.
If you're using a fast paper tape reader, you need your own code (in EPROM) at $2000..$21FF for Prometheus, and it is not supported in PIPBUG 1.
For output:
Prometheus will print a listing to the teletype as normal, and also will punch a tape for the AOF (Signetics Absolute Object Format) file.
Prometheus writes $C0 to the control port to read & advance the papertape.

PIPBUG 1 writes $80 in a rather tight loop (at $28A) to the I/O control port when idle (to read from any papertape that may be present). Only when there is no papertape in the unit can the keyboard and audio cassette be used for input.
Writing $80 to I/O control port "enable[s paper]tape reader". (The papertape punch must not require it, only the reader.) So presumably when that happens the papertape reader unit reads the next byte and then sends it one bit at a time in a teletype-like manner via the Sense pin, and advances the papertape. The papertape would continue to advance automatically until the motor was turned off. As soon as the start bit (a %0) is sent by the papertape unit and heard by PIPBUG 1, it stops the tape reader by writing $0 to the I/O control port. But then it reads the rest of the byte so obviously the tape reader finishes the entire byte regardless once it has started. When it has finished sending, it will then check again whether to send another (at least that is how the emulator works).
When loading, PIPBUG 1 just emits $80s to the I/O control port.
When dumping, all I/O ports are idle (everything is done via the Flag bit). The punch listens to that and when it has heard an entire byte it punches the byte and advances the papertape (ie. it is event-driven rather than continuous).

Printer I/O

EA printer interface:
Uses the data port for (parallel) input and output.
Does not use buffering.
Can accept a new character every 64th of a second (in condensed mode) or every 32nd of a second (in expanded mode).
As soon as the game writes to the data port, it prints the character.
While printing is in progress, the high bit of the input data port is low. It is high while idle.

ETI-641 printer interface:
Uses extended port $19 (25) for (parallel) input and output.
Uses an internal 128-byte buffer.
Can accept a new character every 200,000th of a second (5 µsecs).
Once the internal buffer fills, or a CR is received by the printer, it prints (and empties) the entire buffer.
While printing is in progress, the high bit of the input extended port $19 (25) is low. It is high while idle.

To convert from ASCII to EUY format:

output =  (input & 0x1F)
       | ((input & 0x60) << 1);
output = ^output;

ASCII EUY
$00..$1F $00..$1F
$20..$3F $40..$5F
$40..$5F $80..$9F
$60..$7F $C0..$DF
$80..$9F $00..$1F
$A0..$BF $40..$5F
$C0..$DF $80..$9F
$E0..$FF $C0..$DF

Eg. 'A' would be $41 in ASCII format or $81 in EUY format.
The above table is before the one's complement (ie. flip all bits) operation.

Matsushita EUY-10E023LE printer model number can be decomposed as follows:

E = Electrosensitive
2 = 250mm flat cable, 372mm connector cable
3 = 32/21/16 cpl with 2 spacing dots (horizontally between each character)
L = left-to-right scanning, MSD character generator
E = manufacturer code

Unarchived Software

The following PIPBUG programs are confirmed but unavailable: C-BUG, MultiBug, MATBUG, SBCBUG, 2650 DOS, etc.

If you know of any other software, or have dumps/tapes/listings of any of the above software, please email us.

Various official Signetics 2650 cross-development software was available for the NCSS (National Computer Software Systems) timesharing system (running the VP/CSS OS on IBM System/370 hardware) and the GE (General Electric) Timesharing System Mark III (running the GECOS-III OS on Honeywell 645 hardware):

PIPHASM: Programmable Integrated Processor Hex Assembler
- takes ASCII source code (on disk) as input
- produces AOF file (on disk) as output
- written in FORTRAN IV
- two versions: AS1100 (16-bit) and AS1000 (32-bit).

PIPHTAP: Programmable Integrated Processor Hex Tape
- takes AOF file (on disk) as input
- punches AOF file (on paper tape) as output (for 2650 PC 1001)
- written in FORTRAN IV

PIPSTAP: Programmable Integrated Processor SMS Tape
- takes AOF file (on disk) as input
- punches SMS file (on paper tape) as output (for burning a PROM)
- written in FORTRAN IV

PIPSIM: Programmable Integrated Processor (cross-)Simulator
- takes AOF file (on disk) and ASCII command file (on disk) as input
- written in FORTRAN IV
- two versions: SM1100 (16-bit) and SM1000 (32-bit).

PLµS: Programming Language for Micro Systems
- compiler (produces AOF format as output?)
- extended version of PL/M language
- written in ? language by Gary Kildall for Signetics
- two versions: 2650PC1100 (16-bit) and 2650PL000 (32-bit).

None of this software has been dumped. The PLµS manual is sought so that this language can be reimplemented from the specification.

BINBUG Hardware

The FPGA640 + TCT PCG are mapped as follows:

Region Description
$7000..$700F 1st..16th rows of UDG #0 imagery
$7010..$701F 1st..16th rows of UDG #1 imagery
... ...
$77F0..$77FF 1st..16th rows of UDG #127 imagery
$7800..$783F Contents and inverse video of 1st character row (1st..64th columns):
Bit 7: inverse video (0=off, 1=on)
Bits 6..0: character ($00..$7F)
$7840..$787F Contents and inverse video of 2nd character row (1st..64th columns)
... ...
$7BC0..$7BFF Contents and inverse video of 16th character row (1st..64th columns)
$7C00..$7C3F Colours and attributes of 1st character row (1st..64th columns):
Bit 7: red (0=off, 1=on)
Bit 6: green (0=off, 1=on)
Bit 5: blue (0=off, 1=on)
Bits 4..3: unused
Bit 2: 0=PDG (Pre-Defined Graphic), 1=UDG (User-Defined Graphic)
Bit 1: graphics (0=off, 1=on)
Bit 0: flash (0=off, 1=on)
$7C40..$7C7F Colours and attributes of 2nd character row (1st..64th columns)
... ...
$7FC0..$7FFF Colours and attributes of 16th character row (1st..64th columns)

To read the joystick buttons, you REDE from port $09. Bits are:

Bits 7..6: unused
Bits 5..3: switch bits for joystick A:
 Switch '1' = %000 (fire/serve)
 Switch '2' = %001
 Switch '3' = %010
 Switch '4' = %011
 Switch '5' = %100
 Switch '6' = %101
 Switch '7' = %110
 Nothing    = %111
Bits 2..0: switch bits for joystick B (same format as for joystick A)

To read the joystick paddles, first WRTE a value of $00..$07 to port $EF, according to what you want to read:

Channel '1' (%000): 2nd joystick horizontal
Channel '2' (%001): 2nd joystick vertical
Channel '3' (%010): 1st joystick horizontal
Channel '4' (%011): 1st joystick vertical
Channel '5' (%100): 3rd joystick horizontal
Channel '6' (%101): 3rd joystick vertical
Channel '7' (%110): 4th joystick horizontal
Channel '8' (%111): 4th joystick vertical

Now REDE from port $EF in a loop until the MSB is low (ie. until something in the $00..$7F range is returned).
The X-axis is inverted, ie. $00=right..$7F=left.
The Y-axis is normal, ie. $00=up..$7F=down.

BINBUG BIOS

The following routines are cross-compatible between PIPBUG 1 and BINBUG:

Address Label
$1D EBUG
$5B LINE
$8A CRLF
$A4 STRT
$269 BOUT
$27D AGAP
$286 CHIN
$2B4 COUT
$2DB GNUM

The following routines have the same names, and roughly equivalent functionality, under both PIPBUG 1 and BINBUG; however, they have different addresses and therefore are not directly cross-compatible. They may also have different register usage, stack usage, side effects, etc.:

PIPBUG 1 BINBUG Label
$1F $22 MBUG
$AB $B9 ALTE
$F4 $F1 SREG
$131 $121 GOTO
$160 $14A BK01
$1AB $17B CLBK
$1CA $197 CLR
$1E5 $1A1 BKPT
$246 $28C LKUP
$2A8 $39B DLAY
$2AD $39F DLY
$310 $2E5 DUMP
$35B $27B FORM
$35F $2FB GAP
$3B5 $3C4 LOAD

Here is a useful table comparing various BIOSes for these machines. As there is insufficient information regarding C-BUG, SBCBUG, etc. they are not listed:

OS Input baud Output baud Tape baud MHz Range Year Notes
PIPBUG 1 110 110 110 1 $0..$3FF ? EA 300 baud mod is possible
PIPBUG 2 110/300 110/300 110/300? 1 $0..$3FF ? Supports both rates
HYBUG 300 300 High-speed 1 ? ? 600 and 1200 baud mods are possible
BINBUG 3.5 300/parallel? DG640 300 1? $0..$7FF ? -
BINBUG 3.6 300/parallel? DG640 300 1 $0..$7FF 1979 BINBUG3.6.pdf
BINBUG 4.4 300 DG640 ACOS 1? $0..$7FF ? Supports ACOS and DOS
BINBUG 4.5 ? DG640 ACOS 1? $0..$7FF ? Supports ACOS and DOS
BINBUG 5.2 1200 1200 ACOS 1? $0..$7FF ? Supports ACOS and DOS
BINBUG 5.3 ? serial ACOS ? $0..$7FF ? -
BINBUG 6.0 Eurocard Eurocard ACOS ? $0..$7FF ? -
BINBUG 6.1 150?/300/1200/2400/parallel DG640 ACOS ? $0..$7FF 1982 sbcos_manual.pdf . Supports ACOS and VHSDOS
BINBUG 7.1 300/1200/2400/parallel 300/1200/2400 ACOS ? $0..$7FF 1982 sbcos_manual.pdf . Supports ACOS and VHSDOS
GBUG 300 DG640 ? 1/2 $0..$7FF ? Optional parallel keyboard support
MATBUG 4.1 Eurocard DG640 ? ? $0..$7FF ? matbug_monitor_for_eurocard_system_notes.pdf
MIKEBUG 3 300 DG640 ? 1? $0..$7FF ? -
Multibug (serial version) 300 300 300 ? $0..$7FF 1981 ETI-685
Multibug (memory-mapped version) parallel DG640 300 ? $0..$7FF 1981 ETI-685
MYBUG 300 DG640 ? 1? $0..$7FF ? -
ACOS 2.C - - Control & data I/O ports 1? $6000..$63FF ? -
ACOS 3.C - - Extended I/O ports? 1? $6000..$63FF ? -
ACOS 3.E - - Extended I/O ports 1 $6000..$63FF 1982 sbcos_manual.pdf
VHSDOS 2.6a - - - 1? $6800..$6FFF 1981 vhs_dos_v26a_source_listing.pdf
MicroDOS 4.5a - - - 1? $6800..$6FFF ? MICRODOS.SRC

Baud rates given assume 1 MHz operation (and are therefore doubled at 2 MHz).

BINBUG outputs both to the serial port (at 300 baud) and to the VDU (1K RAM at $7800..$7FFF).
According to ETI Oct 1982, BINBUG can work at 300, 1200 & 2400 baud (!).
SBCOS = SBCBUG = BINBUG 6.1 + BINBUG 7.1 + ACOS 3.E
BINBUG 6.1 & 7.1 support/expect ETI-685 processor board.

Floppy Disk I/O

Each block is 256 bytes, as follows:

     0: next track (0..39).
     1: next sector (1..10).
2..255: data bytes

CMD files are used by VHSDOS and MicroDOS for storage of games. They normally consist of two or more chunks concatenated together. Each chunk has a 3-byte header:

  0..1: load address of chunk (big-endian)
     2: length of payload in bytes (normally <= $FB)

then the payload itself (if any) follows.
The CMD file is terminated by a chunk like this:

  0..1: start address of game (big-endian)
     2: $00

with no payload.
CMD chunks can seamlessly cross block boundaries.
Note that the above assumes that the block header (ie. "next track" and "next sector" bytes) have already been skipped.

The 10 sectors per track are numbered 1..10 and have an interleave of 7, ie. 1, 8, 5, 2, 9, 6, 3, 10, 7, 4. (The available disk images are already deinterleaved.)
At the flux level, there are 250,000 flux transitions per second.
Each bit is 1 clock flux + 1 data flux, so there are 125,000 bits per sec.
So theoretically 15,625 bytes per sec, if there were no sector headers, inter-sector gaps, etc.
However, post-read processing must occur, so we can only really achieve 1/8th of that speed (hence the interleaving). Thus, an effective speed of 12,800 bytes ÷ 8 = 1,600 bytes per second.
After each 20 msec sector read, there is about 140 msec of post-processing as the disk continues to spin. But the CPU has to keep up with the drive as it reads each byte, because the drive has no buffer. Therefore most of the time the CPU is not bothering to read the data passing under the head, but is instead post-processing previously read data.
With an infinitely fast disk, it takes about 30,642 clocks. ie. about 30.642 msec, between reading an arbitrary byte in a given sector and reading the equivalent byte in the next sector.
It also takes additional time to change tracks, and to start or stop the motor.

Game Help

These do nothing very useful, but are not expected to (eg. they are for controlling unemulated hardware, or are code fragments for incorporation into your own games):

2708 EPROM Programmer
Linearization (Linearisatie)
Vector Magnetometer
Wind Furnace Controller
most routines

These games are hardcoded for 110 baud:

On-screen Clock
PPI-based EPROM Programmer
110 baud version of Lunar Lander (machine code)
110 baud version of Biorhythms
110 baud version of Funny Farm Races

These games are hardcoded for 300 baud:

Astro Trek (but an official 110 baud patch is provided with the listing)
Reaction Timer
300 baud version of Lunar Lander (machine code)
300 baud version of Biorhythms
300 baud version of Funny Farm Races

2650 Line Assembler:

"It is not identical but is very similar to the Line Assembler described in the article "2650 mini assembler simplifies programming" by Jamieson Rowe published in the April 1979 issue of Electronics Australia (p. 76-80) and the follow-up article "Improving the 2650 mini line assembler" by A. M. Kollosche in February 1980 (p. 76)." - Chris Burrows.

The start address begin at 2, and increments by 2 every time F5 (reset) is pressed, for some reason.

2650 Micro BASIC programs (eg. Acey-Deucy, Blackjack, Guessing Game (2650 Micro BASIC version), Life (2650 Micro BASIC version), Lunar Lander (2650 Micro BASIC version), Number Game, Radio Log, Temperature Conversion):

Type G1 and then press ENTER to begin execution.
Type L1 and then press ENTER to list the program.
Type E1 and then press ENTER to replace lines starting from 1. Ctrl-C when done.

Some program statements are:

Letter Description Example Standard BASIC
A ASCII input AD INPUT D$:LET D=ASC(LEFT$(D$,1))
E End E END
G GoTo G5 GOTO 5
I Numeric input ID INPUT D
L Let L0=D LET D=0
P Print P"HELLO" PRINT "HELLO"
T Test (if) TD>0 IF D>0 THEN
$ Remark $HELLO$ REM HELLO

Reverse Polish Notation is used. Eg. LVD+#=D,FT-=F means:

L Let
V push V onto the stack
D push D onto the stack
+ add them together
# unary negation of the result (ie. result = -result)
= store the result in
D variable D
, Let again
F push F onto the stack
T push T onto the stack
- subtract T from F
= store the result in
F variable F

Alien Hunt:

Has ! and " at end of table rows, for some reason.

Assembler, AssemblerPlusDemonstration, AssemblerPlusAssemblerList:

AssemblerPlusDemonstration.pgm will assemble without errors, but the generated machine code is not being written to memory anywhere (we are asking in this case for ORG $2000, but it doesn't seem to matter where we ask for, it is never generated anywhere). Hence, the current dump of Assembler.pgm should be considered suspect (although it has been verified). As the other two are based on that dump, they are likewise suspect.

Astro Trek:

Here is a map of all 2401 (7*7*7*7) sectors of the galaxy:

Quadrant 1 Quadrant 2 Quadrant 3 Quadrant 4 Quadrant 5 Quadrant 6 Quadrant 7
S1 S2 S3 S4 S5 S6 S7 S1 S2 S3 S4 S5 S6 S7 S1 S2 S3 S4 S5 S6 S7 S1 S2 S3 S4 S5 S6 S7 S1 S2 S3 S4 S5 S6 S7 S1 S2 S3 S4 S5 S6 S7 S1 S2 S3 S4 S5 S6 S7
Q1 S1 1,1
1,1
1,1
2,1
1,1
3,1
1,1
4,1
1,1
5,1
1,1
6,1
1,1
7,1
2,1
1,1
2,1
2,1
2,1
3,1
2,1
4,1
2,1
5,1
2,1
6,1
2,1
7,1
3,1
1,1
3,1
2,1
3,1
3,1
3,1
4,1
3,1
5,1
3,1
6,1
3,1
7,1
4,1
1,1
4,1
2,1
4,1
3,1
4,1
4,1
4,1
5,1
4,1
6,1
4,1
7,1
5,1
1,1
5,1
2,1
5,1
3,1
5,1
4,1
5,1
5,1
5,1
6,1
5,1
7,1
6,1
1,1
6,1
2,1
6,1
3,1
6,1
4,1
6,1
5,1
6,1
6,1
6,1
7,1
7,1
1,1
7,1
2,1
7,1
3,1
7,1
4,1
7,1
5,1
7,1
6,1
7,1
7,1
S2 1,1
1,2
1,1
2,2
1,1
3,2
1,1
4,2
1,1
5,2
1,1
6,2
1,1
7,2
2,1
1,2
2,1
2,2
2,1
3,2
2,1
4,2
2,1
5,2
2,1
6,2
2,1
7,2
3,1
1,2
3,1
2,2
3,1
3,2
3,1
4,2
3,1
5,2
3,1
6,2
3,1
7,2
4,1
1,2
4,1
2,2
4,1
3,2
4,1
4,2
4,1
5,2
4,1
6,2
4,1
7,2
5,1
1,2
5,1
2,2
5,1
3,2
5,1
4,2
5,1
5,2
5,1
6,2
5,1
7,2
6,1
1,2
6,1
2,2
6,1
3,2
6,1
4,2
6,1
5,2
6,1
6,2
6,1
7,2
7,1
1,2
7,1
2,2
7,1
3,2
7,1
4,2
7,1
5,2
7,1
6,2
7,1
7,2
S3 1,1
1,3
1,1
2,3
1,1
3,3
1,1
4,3
1,1
5,3
1,1
6,3
1,1
7,3
2,1
1,3
2,1
2,3
2,1
3,3
2,1
4,3
2,1
5,3
2,1
6,3
2,1
7,3
3,1
1,3
3,1
2,3
3,1
3,3
3,1
4,3
3,1
5,3
3,1
6,3
3,1
7,3
4,1
1,3
4,1
2,3
4,1
3,3
4,1
4,3
4,1
5,3
4,1
6,3
4,1
7,3
5,1
1,3
5,1
2,3
5,1
3,3
5,1
4,3
5,1
5,3
5,1
6,3
5,1
7,3
6,1
1,3
6,1
2,3
6,1
3,3
6,1
4,3
6,1
5,3
6,1
6,3
6,1
7,3
7,1
1,3
7,1
2,3
7,1
3,3
7,1
4,3
7,1
5,3
7,1
6,3
7,1
7,3
S4 1,1
1,4
1,1
2,4
1,1
3,4
1,1
4,4
1,1
5,4
1,1
6,4
1,1
7,4
2,1
1,4
2,1
2,4
2,1
3,4
2,1
4,4
2,1
5,4
2,1
6,4
2,1
7,4
3,1
1,4
3,1
2,4
3,1
3,4
3,1
4,4
3,1
5,4
3,1
6,4
3,1
7,4
4,1
1,4
4,1
2,4
4,1
3,4
4,1
4,4
4,1
5,4
4,1
6,4
4,1
7,4
5,1
1,4
5,1
2,4
5,1
3,4
5,1
4,4
5,1
5,4
5,1
6,4
5,1
7,4
6,1
1,4
6,1
2,4
6,1
3,4
6,1
4,4
6,1
5,4
6,1
6,4
6,1
7,4
7,1
1,4
7,1
2,4
7,1
3,4
7,1
4,4
7,1
5,4
7,1
6,4
7,1
7,4
S5 1,1
1,5
1,1
2,5
1,1
3,5
1,1
4,5
1,1
5,5
1,1
6,5
1,1
7,5
2,1
1,5
2,1
2,5
2,1
3,5
2,1
4,5
2,1
5,5
2,1
6,5
2,1
7,5
3,1
1,5
3,1
2,5
3,1
3,5
3,1
4,5
3,1
5,5
3,1
6,5
3,1
7,5
4,1
1,5
4,1
2,5
4,1
3,5
4,1
4,5
4,1
5,5
4,1
6,5
4,1
7,5
5,1
1,5
5,1
2,5
5,1
3,5
5,1
4,5
5,1
5,5
5,1
6,5
5,1
7,5
6,1
1,5
6,1
2,5
6,1
3,5
6,1
4,5
6,1
5,5
6,1
6,5
6,1
7,5
7,1
1,5
7,1
2,5
7,1
3,5
7,1
4,5
7,1
5,5
7,1
6,5
7,1
7,5
S6 1,1
1,6
1,1
2,6
1,1
3,6
1,1
4,6
1,1
5,6
1,1
6,6
1,1
7,6
2,1
1,6
2,1
2,6
2,1
3,6
2,1
4,6
2,1
5,6
2,1
6,6
2,1
7,6
3,1
1,6
3,1
2,6
3,1
3,6
3,1
4,6
3,1
5,6
3,1
6,6
3,1
7,6
4,1
1,6
4,1
2,6
4,1
3,6
4,1
4,6
4,1
5,6
4,1
6,6
4,1
7,6
5,1
1,6
5,1
2,6
5,1
3,6
5,1
4,6
5,1
5,6
5,1
6,6
5,1
7,6
6,1
1,6
6,1
2,6
6,1
3,6
6,1
4,6
6,1
5,6
6,1
6,6
6,1
7,6
7,1
1,6
7,1
2,6
7,1
3,6
7,1
4,6
7,1
5,6
7,1
6,6
7,1
7,6
S7 1,1
1,7
1,1
2,7
1,1
3,7
1,1
4,7
1,1
5,7
1,1
6,7
1,1
7,7
2,1
1,7
2,1
2,7
2,1
3,7
2,1
4,7
2,1
5,7
2,1
6,7
2,1
7,7
3,1
1,7
3,1
2,7
3,1
3,7
3,1
4,7
3,1
5,7
3,1
6,7
3,1
7,7
4,1
1,7
4,1
2,7
4,1
3,7
4,1
4,7
4,1
5,7
4,1
6,7
4,1
7,7
5,1
1,7
5,1
2,7
5,1
3,7
5,1
4,7
5,1
5,7
5,1
6,7
5,1
7,7
6,1
1,7
6,1
2,7
6,1
3,7
6,1
4,7
6,1
5,7
6,1
6,7
6,1
7,7
7,1
1,7
7,1
2,7
7,1
3,7
7,1
4,7
7,1
5,7
7,1
6,7
7,1
7,7
Q2 S1 1,2
1,1
1,2
2,1
1,2
3,1
1,2
4,1
1,2
5,1
1,2
6,1
1,2
7,1
2,2
1,1
2,2
2,1
2,2
3,1
2,2
4,1
2,2
5,1
2,2
6,1
2,2
7,1
3,2
1,1
3,2
2,1
3,2
3,1
3,2
4,1
3,2
5,1
3,2
6,1
3,2
7,1
4,2
1,1
4,2
2,1
4,2
3,1
4,2
4,1
4,2
5,1
4,2
6,1
4,2
7,1
5,2
1,1
5,2
2,1
5,2
3,1
5,2
4,1
5,2
5,1
5,2
6,1
5,2
7,1
6,2
1,1
6,2
2,1
6,2
3,1
6,2
4,1
6,2
5,1
6,2
6,1
6,2
7,1
7,2
1,1
7,2
2,1
7,2
3,1
7,2
4,1
7,2
5,1
7,2
6,1
7,2
7,1
S2 1,2
1,2
1,2
2,2
1,2
3,2
1,2
4,2
1,2
5,2
1,2
6,2
1,2
7,2
2,2
1,2
2,2
2,2
2,2
3,2
2,2
4,2
2,2
5,2
2,2
6,2
2,2
7,2
3,2
1,2
3,2
2,2
3,2
3,2
3,2
4,2
3,2
5,2
3,2
6,2
3,2
7,2
4,2
1,2
4,2
2,2
4,2
3,2
4,2
4,2
4,2
5,2
4,2
6,2
4,2
7,2
5,2
1,2
5,2
2,2
5,2
3,2
5,2
4,2
5,2
5,2
5,2
6,2
5,2
7,2
6,2
1,2
6,2
2,2
6,2
3,2
6,2
4,2
6,2
5,2
6,2
6,2
6,2
7,2
7,2
1,2
7,2
2,2
7,2
3,2
7,2
4,2
7,2
5,2
7,2
6,2
7,2
7,2
S3 1,2
1,3
1,2
2,3
1,2
3,3
1,2
4,3
1,2
5,3
1,2
6,3
1,2
7,3
2,2
1,3
2,2
2,3
2,2
3,3
2,2
4,3
2,2
5,3
2,2
6,3
2,2
7,3
3,2
1,3
3,2
2,3
3,2
3,3
3,2
4,3
3,2
5,3
3,2
6,3
3,2
7,3
4,2
1,3
4,2
2,3
4,2
3,3
4,2
4,3
4,2
5,3
4,2
6,3
4,2
7,3
5,2
1,3
5,2
2,3
5,2
3,3
5,2
4,3
5,2
5,3
5,2
6,3
5,2
7,3
6,2
1,3
6,2
2,3
6,2
3,3
6,2
4,3
6,2
5,3
6,2
6,3
6,2
7,3
7,2
1,3
7,2
2,3
7,2
3,3
7,2
4,3
7,2
5,3
7,2
6,3
7,2
7,3
S4 1,2
1,4
1,2
2,4
1,2
3,4
1,2
4,4
1,2
5,4
1,2
6,4
1,2
7,4
2,2
1,4
2,2
2,4
2,2
3,4
2,2
4,4
2,2
5,4
2,2
6,4
2,2
7,4
3,2
1,4
3,2
2,4
3,2
3,4
3,2
4,4
3,2
5,4
3,2
6,4
3,2
7,4
4,2
1,4
4,2
2,4
4,2
3,4
4,2
4,4
4,2
5,4
4,2
6,4
4,2
7,4
5,2
1,4
5,2
2,4
5,2
3,4
5,2
4,4
5,2
5,4
5,2
6,4
5,2
7,4
6,2
1,4
6,2
2,4
6,2
3,4
6,2
4,4
6,2
5,4
6,2
6,4
6,2
7,4
7,2
1,4
7,2
2,4
7,2
3,4
7,2
4,4
7,2
5,4
7,2
6,4
7,2
7,4
S5 1,2
1,5
1,2
2,5
1,2
3,5
1,2
4,5
1,2
5,5
1,2
6,5
1,2
7,5
2,2
1,5
2,2
2,5
2,2
3,5
2,2
4,5
2,2
5,5
2,2
6,5
2,2
7,5
3,2
1,5
3,2
2,5
3,2
3,5
3,2
4,5
3,2
5,5
3,2
6,5
3,2
7,5
4,2
1,5
4,2
2,5
4,2
3,5
4,2
4,5
4,2
5,5
4,2
6,5
4,2
7,5
5,2
1,5
5,2
2,5
5,2
3,5
5,2
4,5
5,2
5,5
5,2
6,5
5,2
7,5
6,2
1,5
6,2
2,5
6,2
3,5
6,2
4,5
6,2
5,5
6,2
6,5
6,2
7,5
7,2
1,5
7,2
2,5
7,2
3,5
7,2
4,5
7,2
5,5
7,2
6,5
7,2
7,5
S6 1,2
1,6
1,2
2,6
1,2
3,6
1,2
4,6
1,2
5,6
1,2
6,6
1,2
7,6
2,2
1,6
2,2
2,6
2,2
3,6
2,2
4,6
2,2
5,6
2,2
6,6
2,2
7,6
3,2
1,6
3,2
2,6
3,2
3,6
3,2
4,6
3,2
5,6
3,2
6,6
3,2
7,6
4,2
1,6
4,2
2,6
4,2
3,6
4,2
4,6
4,2
5,6
4,2
6,6
4,2
7,6
5,2
1,6
5,2
2,6
5,2
3,6
5,2
4,6
5,2
5,6
5,2
6,6
5,2
7,6
6,2
1,6
6,2
2,6
6,2
3,6
6,2
4,6
6,2
5,6
6,2
6,6
6,2
7,6
7,2
1,6
7,2
2,6
7,2
3,6
7,2
4,6
7,2
5,6
7,2
6,6
7,2
7,6
S7 1,2
1,7
1,2
2,7
1,2
3,7
1,2
4,7
1,2
5,7
1,2
6,7
1,2
7,7
2,2
1,7
2,2
2,7
2,2
3,7
2,2
4,7
2,2
5,7
2,2
6,7
2,2
7,7
3,2
1,7
3,2
2,7
3,2
3,7
3,2
4,7
3,2
5,7
3,2
6,7
3,2
7,7
4,2
1,7
4,2
2,7
4,2
3,7
4,2
4,7
4,2
5,7
4,2
6,7
4,2
7,7
5,2
1,7
5,2
2,7
5,2
3,7
5,2
4,7
5,2
5,7
5,2
6,7
5,2
7,7
6,2
1,7
6,2
2,7
6,2
3,7
6,2
4,7
6,2
5,7
6,2
6,7
6,2
7,7
7,2
1,7
7,2
2,7
7,2
3,7
7,2
4,7
7,2
5,7
7,2
6,7
7,2
7,7
Q3 S1 1,3
1,1
1,3
2,1
1,3
3,1
1,3
4,1
1,3
5,1
1,3
6,1
1,3
7,1
2,3
1,1
2,3
2,1
2,3
3,1
2,3
4,1
2,3
5,1
2,3
6,1
2,3
7,1
3,3
1,1
3,3
2,1
3,3
3,1
3,3
4,1
3,3
5,1
3,3
6,1
3,3
7,1
4,3
1,1
4,3
2,1
4,3
3,1
4,3
4,1
4,3
5,1
4,3
6,1
4,3
7,1
5,3
1,1
5,3
2,1
5,3
3,1
5,3
4,1
5,3
5,1
5,3
6,1
5,3
7,1
6,3
1,1
6,3
2,1
6,3
3,1
6,3
4,1
6,3
5,1
6,3
6,1
6,3
7,1
7,3
1,1
7,3
2,1
7,3
3,1
7,3
4,1
7,3
5,1
7,3
6,1
7,3
7,1
S2 1,3
1,2
1,3
2,2
1,3
3,2
1,3
4,2
1,3
5,2
1,3
6,2
1,3
7,2
2,3
1,2
2,3
2,2
2,3
3,2
2,3
4,2
2,3
5,2
2,3
6,2
2,3
7,2
3,3
1,2
3,3
2,2
3,3
3,2
3,3
4,2
3,3
5,2
3,3
6,2
3,3
7,2
4,3
1,2
4,3
2,2
4,3
3,2
4,3
4,2
4,3
5,2
4,3
6,2
4,3
7,2
5,3
1,2
5,3
2,2
5,3
3,2
5,3
4,2
5,3
5,2
5,3
6,2
5,3
7,2
6,3
1,2
6,3
2,2
6,3
3,2
6,3
4,2
6,3
5,2
6,3
6,2
6,3
7,2
7,3
1,2
7,3
2,2
7,3
3,2
7,3
4,2
7,3
5,2
7,3
6,2
7,3
7,2
S3 1,3
1,3
1,3
2,3
1,3
3,3
1,3
4,3
1,3
5,3
1,3
6,3
1,3
7,3
2,3
1,3
2,3
2,3
2,3
3,3
2,3
4,3
2,3
5,3
2,3
6,3
2,3
7,3
3,3
1,3
3,3
2,3
3,3
3,3
3,3
4,3
3,3
5,3
3,3
6,3
3,3
7,3
4,3
1,3
4,3
2,3
4,3
3,3
4,3
4,3
4,3
5,3
4,3
6,3
4,3
7,3
5,3
1,3
5,3
2,3
5,3
3,3
5,3
4,3
5,3
5,3
5,3
6,3
5,3
7,3
6,3
1,3
6,3
2,3
6,3
3,3
6,3
4,3
6,3
5,3
6,3
6,3
6,3
7,3
7,3
1,3
7,3
2,3
7,3
3,3
7,3
4,3
7,3
5,3
7,3
6,3
7,3
7,3
S4 1,3
1,4
1,3
2,4
1,3
3,4
1,3
4,4
1,3
5,4
1,3
6,4
1,3
7,4
2,3
1,4
2,3
2,4
2,3
3,4
2,3
4,4
2,3
5,4
2,3
6,4
2,3
7,4
3,3
1,4
3,3
2,4
3,3
3,4
3,3
4,4
3,3
5,4
3,3
6,4
3,3
7,4
4,3
1,4
4,3
2,4
4,3
3,4
4,3
4,4
4,3
5,4
4,3
6,4
4,3
7,4
5,3
1,4
5,3
2,4
5,3
3,4
5,3
4,4
5,3
5,4
5,3
6,4
5,3
7,4
6,3
1,4
6,3
2,4
6,3
3,4
6,3
4,4
6,3
5,4
6,3
6,4
6,3
7,4
7,3
1,4
7,3
2,4
7,3
3,4
7,3
4,4
7,3
5,4
7,3
6,4
7,3
7,4
S5 1,3
1,5
1,3
2,5
1,3
3,5
1,3
4,5
1,3
5,5
1,3
6,5
1,3
7,5
2,3
1,5
2,3
2,5
2,3
3,5
2,3
4,5
2,3
5,5
2,3
6,5
2,3
7,5
3,3
1,5
3,3
2,5
3,3
3,5
3,3
4,5
3,3
5,5
3,3
6,5
3,3
7,5
4,3
1,5
4,3
2,5
4,3
3,5
4,3
4,5
4,3
5,5
4,3
6,5
4,3
7,5
5,3
1,5
5,3
2,5
5,3
3,5
5,3
4,5
5,3
5,5
5,3
6,5
5,3
7,5
6,3
1,5
6,3
2,5
6,3
3,5
6,3
4,5
6,3
5,5
6,3
6,5
6,3
7,5
7,3
1,5
7,3
2,5
7,3
3,5
7,3
4,5
7,3
5,5
7,3
6,5
7,3
7,5
S6 1,3
1,6
1,3
2,6
1,3
3,6
1,3
4,6
1,3
5,6
1,3
6,6
1,3
7,6
2,3
1,6
2,3
2,6
2,3
3,6
2,3
4,6
2,3
5,6
2,3
6,6
2,3
7,6
3,3
1,6
3,3
2,6
3,3
3,6
3,3
4,6
3,3
5,6
3,3
6,6
3,3
7,6
4,3
1,6
4,3
2,6
4,3
3,6
4,3
4,6
4,3
5,6
4,3
6,6
4,3
7,6
5,3
1,6
5,3
2,6
5,3
3,6
5,3
4,6
5,3
5,6
5,3
6,6
5,3
7,6
6,3
1,6
6,3
2,6
6,3
3,6
6,3
4,6
6,3
5,6
6,3
6,6
6,3
7,6
7,3
1,6
7,3
2,6
7,3
3,6
7,3
4,6
7,3
5,6
7,3
6,6
7,3
7,6
S7 1,3
1,7
1,3
2,7
1,3
3,7
1,3
4,7
1,3
5,7
1,3
6,7
1,3
7,7
2,3
1,7
2,3
2,7
2,3
3,7
2,3
4,7
2,3
5,7
2,3
6,7
2,3
7,7
3,3
1,7
3,3
2,7
3,3
3,7
3,3
4,7
3,3
5,7
3,3
6,7
3,3
7,7
4,3
1,7
4,3
2,7
4,3
3,7
4,3
4,7
4,3
5,7
4,3
6,7
4,3
7,7
5,3
1,7
5,3
2,7
5,3
3,7
5,3
4,7
5,3
5,7
5,3
6,7
5,3
7,7
6,3
1,7
6,3
2,7
6,3
3,7
6,3
4,7
6,3
5,7
6,3
6,7
6,3
7,7
7,3
1,7
7,3
2,7
7,3
3,7
7,3
4,7
7,3
5,7
7,3
6,7
7,3
7,7
Q4 S1 1,4
1,1
1,4
2,1
1,4
3,1
1,4
4,1
1,4
5,1
1,4
6,1
1,4
7,1
2,4
1,1
2,4
2,1
2,4
3,1
2,4
4,1
2,4
5,1
2,4
6,1
2,4
7,1
3,4
1,1
3,4
2,1
3,4
3,1
3,4
4,1
3,4
5,1
3,4
6,1
3,4
7,1
4,4
1,1
4,4
2,1
4,4
3,1
4,4
4,1
4,4
5,1
4,4
6,1
4,4
7,1
5,4
1,1
5,4
2,1
5,4
3,1
5,4
4,1
5,4
5,1
5,4
6,1
5,4
7,1
6,4
1,1
6,4
2,1
6,4
3,1
6,4
4,1
6,4
5,1
6,4
6,1
6,4
7,1
7,4
1,1
7,4
2,1
7,4
3,1
7,4
4,1
7,4
5,1
7,4
6,1
7,4
7,1
S2 1,4
1,2
1,4
2,2
1,4
3,2
1,4
4,2
1,4
5,2
1,4
6,2
1,4
7,2
2,4
1,2
2,4
2,2
2,4
3,2
2,4
4,2
2,4
5,2
2,4
6,2
2,4
7,2
3,4
1,2
3,4
2,2
3,4
3,2
3,4
4,2
3,4
5,2
3,4
6,2
3,4
7,2
4,4
1,2
4,4
2,2
4,4
3,2
4,4
4,2
4,4
5,2
4,4
6,2
4,4
7,2
5,4
1,2
5,4
2,2
5,4
3,2
5,4
4,2
5,4
5,2
5,4
6,2
5,4
7,2
6,4
1,2
6,4
2,2
6,4
3,2
6,4
4,2
6,4
5,2
6,4
6,2
6,4
7,2
7,4
1,2
7,4
2,2
7,4
3,2
7,4
4,2
7,4
5,2
7,4
6,2
7,4
7,2
S3 1,4
1,3
1,4
2,3
1,4
3,3
1,4
4,3
1,4
5,3
1,4
6,3
1,4
7,3
2,4
1,3
2,4
2,3
2,4
3,3
2,4
4,3
2,4
5,3
2,4
6,3
2,4
7,3
3,4
1,3
3,4
2,3
3,4
3,3
3,4
4,3
3,4
5,3
3,4
6,3
3,4
7,3
4,4
1,3
4,4
2,3
4,4
3,3
4,4
4,3
4,4
5,3
4,4
6,3
4,4
7,3
5,4
1,3
5,4
2,3
5,4
3,3
5,4
4,3
5,4
5,3
5,4
6,3
5,4
7,3
6,4
1,3
6,4
2,3
6,4
3,3
6,4
4,3
6,4
5,3
6,4
6,3
6,4
7,3
7,4
1,3
7,4
2,3
7,4
3,3
7,4
4,3
7,4
5,3
7,4
6,3
7,4
7,3
S4 1,4
1,4
1,4
2,4
1,4
3,4
1,4
4,4
1,4
5,4
1,4
6,4
1,4
7,4
2,4
1,4
2,4
2,4
2,4
3,4
2,4
4,4
2,4
5,4
2,4
6,4
2,4
7,4
3,4
1,4
3,4
2,4
3,4
3,4
3,4
4,4
3,4
5,4
3,4
6,4
3,4
7,4
4,4
1,4
4,4
2,4
4,4
3,4
4,4
4,4
4,4
5,4
4,4
6,4
4,4
7,4
5,4
1,4
5,4
2,4
5,4
3,4
5,4
4,4
5,4
5,4
5,4
6,4
5,4
7,4
6,4
1,4
6,4
2,4
6,4
3,4
6,4
4,4
6,4
5,4
6,4
6,4
6,4
7,4
7,4
1,4
7,4
2,4
7,4
3,4
7,4
4,4
7,4
5,4
7,4
6,4
7,4
7,4
S5 1,4
1,5
1,4
2,5
1,4
3,5
1,4
4,5
1,4
5,5
1,4
6,5
1,4
7,5
2,4
1,5
2,4
2,5
2,4
3,5
2,4
4,5
2,4
5,5
2,4
6,5
2,4
7,5
3,4
1,5
3,4
2,5
3,4
3,5
3,4
4,5
3,4
5,5
3,4
6,5
3,4
7,5
4,4
1,5
4,4
2,5
4,4
3,5
4,4
4,5
4,4
5,5
4,4
6,5
4,4
7,5
5,4
1,5
5,4
2,5
5,4
3,5
5,4
4,5
5,4
5,5
5,4
6,5
5,4
7,5
6,4
1,5
6,4
2,5
6,4
3,5
6,4
4,5
6,4
5,5
6,4
6,5
6,4
7,5
7,4
1,5
7,4
2,5
7,4
3,5
7,4
4,5
7,4
5,5
7,4
6,5
7,4
7,5
S6 1,4
1,6
1,4
2,6
1,4
3,6
1,4
4,6
1,4
5,6
1,4
6,6
1,4
7,6
2,4
1,6
2,4
2,6
2,4
3,6
2,4
4,6
2,4
5,6
2,4
6,6
2,4
7,6
3,4
1,6
3,4
2,6
3,4
3,6
3,4
4,6
3,4
5,6
3,4
6,6
3,4
7,6
4,4
1,6
4,4
2,6
4,4
3,6
4,4
4,6
4,4
5,6
4,4
6,6
4,4
7,6
5,4
1,6
5,4
2,6
5,4
3,6
5,4
4,6
5,4
5,6
5,4
6,6
5,4
7,6
6,4
1,6
6,4
2,6
6,4
3,6
6,4
4,6
6,4
5,6
6,4
6,6
6,4
7,6
7,4
1,6
7,4
2,6
7,4
3,6
7,4
4,6
7,4
5,6
7,4
6,6
7,4
7,6
S7 1,4
1,7
1,4
2,7
1,4
3,7
1,4
4,7
1,4
5,7
1,4
6,7
1,4
7,7
2,4
1,7
2,4
2,7
2,4
3,7
2,4
4,7
2,4
5,7
2,4
6,7
2,4
7,7
3,4
1,7
3,4
2,7
3,4
3,7
3,4
4,7
3,4
5,7
3,4
6,7
3,4
7,7
4,4
1,7
4,4
2,7
4,4
3,7
4,4
4,7
4,4
5,7
4,4
6,7
4,4
7,7
5,4
1,7
5,4
2,7
5,4
3,7
5,4
4,7
5,4
5,7
5,4
6,7
5,4
7,7
6,4
1,7
6,4
2,7
6,4
3,7
6,4
4,7
6,4
5,7
6,4
6,7
6,4
7,7
7,4
1,7
7,4
2,7
7,4
3,7
7,4
4,7
7,4
5,7
7,4
6,7
7,4
7,7
Q5 S1 1,5
1,1
1,5
2,1
1,5
3,1
1,5
4,1
1,5
5,1
1,5
6,1
1,5
7,1
2,5
1,1
2,5
2,1
2,5
3,1
2,5
4,1
2,5
5,1
2,5
6,1
2,5
7,1
3,5
1,1
3,5
2,1
3,5
3,1
3,5
4,1
3,5
5,1
3,5
6,1
3,5
7,1
4,5
1,1
4,5
2,1
4,5
3,1
4,5
4,1
4,5
5,1
4,5
6,1
4,5
7,1
5,5
1,1
5,5
2,1
5,5
3,1
5,5
4,1
5,5
5,1
5,5
6,1
5,5
7,1
6,5
1,1
6,5
2,1
6,5
3,1
6,5
4,1
6,5
5,1
6,5
6,1
6,5
7,1
7,5
1,1
7,5
2,1
7,5
3,1
7,5
4,1
7,5
5,1
7,5
6,1
7,5
7,1
S2 1,5
1,2
1,5
2,2
1,5
3,2
1,5
4,2
1,5
5,2
1,5
6,2
1,5
7,2
2,5
1,2
2,5
2,2
2,5
3,2
2,5
4,2
2,5
5,2
2,5
6,2
2,5
7,2
3,5
1,2
3,5
2,2
3,5
3,2
3,5
4,2
3,5
5,2
3,5
6,2
3,5
7,2
4,5
1,2
4,5
2,2
4,5
3,2
4,5
4,2
4,5
5,2
4,5
6,2
4,5
7,2
5,5
1,2
5,5
2,2
5,5
3,2
5,5
4,2
5,5
5,2
5,5
6,2
5,5
7,2
6,5
1,2
6,5
2,2
6,5
3,2
6,5
4,2
6,5
5,2
6,5
6,2
6,5
7,2
7,5
1,2
7,5
2,2
7,5
3,2
7,5
4,2
7,5
5,2
7,5
6,2
7,5
7,2
S3 1,5
1,3
1,5
2,3
1,5
3,3
1,5
4,3
1,5
5,3
1,5
6,3
1,5
7,3
2,5
1,3
2,5
2,3
2,5
3,3
2,5
4,3
2,5
5,3
2,5
6,3
2,5
7,3
3,5
1,3
3,5
2,3
3,5
3,3
3,5
4,3
3,5
5,3
3,5
6,3
3,5
7,3
4,5
1,3
4,5
2,3
4,5
3,3
4,5
4,3
4,5
5,3
4,5
6,3
4,5
7,3
5,5
1,3
5,5
2,3
5,5
3,3
5,5
4,3
5,5
5,3
5,5
6,3
5,5
7,3
6,5
1,3
6,5
2,3
6,5
3,3
6,5
4,3
6,5
5,3
6,5
6,3
6,5
7,3
7,5
1,3
7,5
2,3
7,5
3,3
7,5
4,3
7,5
5,3
7,5
6,3
7,5
7,3
S4 1,5
1,4
1,5
2,4
1,5
3,4
1,5
4,4
1,5
5,4
1,5
6,4
1,5
7,4
2,5
1,4
2,5
2,4
2,5
3,4
2,5
4,4
2,5
5,4
2,5
6,4
2,5
7,4
3,5
1,4
3,5
2,4
3,5
3,4
3,5
4,4
3,5
5,4
3,5
6,4
3,5
7,4
4,5
1,4
4,5
2,4
4,5
3,4
4,5
4,4
4,5
5,4
4,5
6,4
4,5
7,4
5,5
1,4
5,5
2,4
5,5
3,4
5,5
4,4
5,5
5,4
5,5
6,4
5,5
7,4
6,5
1,4
6,5
2,4
6,5
3,4
6,5
4,4
6,5
5,4
6,5
6,4
6,5
7,4
7,5
1,4
7,5
2,4
7,5
3,4
7,5
4,4
7,5
5,4
7,5
6,4
7,5
7,4
S5 1,5
1,5
1,5
2,5
1,5
3,5
1,5
4,5
1,5
5,5
1,5
6,5
1,5
7,5
2,5
1,5
2,5
2,5
2,5
3,5
2,5
4,5
2,5
5,5
2,5
6,5
2,5
7,5
3,5
1,5
3,5
2,5
3,5
3,5
3,5
4,5
3,5
5,5
3,5
6,5
3,5
7,5
4,5
1,5
4,5
2,5
4,5
3,5
4,5
4,5
4,5
5,5
4,5
6,5
4,5
7,5
5,5
1,5
5,5
2,5
5,5
3,5
5,5
4,5
5,5
5,5
5,5
6,5
5,5
7,5
6,5
1,5
6,5
2,5
6,5
3,5
6,5
4,5
6,5
5,5
6,5
6,5
6,5
7,5
7,5
1,5
7,5
2,5
7,5
3,5
7,5
4,5
7,5
5,5
7,5
6,5
7,5
7,5
S6 1,5
1,6
1,5
2,6
1,5
3,6
1,5
4,6
1,5
5,6
1,5
6,6
1,5
7,6
2,5
1,6
2,5
2,6
2,5
3,6
2,5
4,6
2,5
5,6
2,5
6,6
2,5
7,6
3,5
1,6
3,5
2,6
3,5
3,6
3,5
4,6
3,5
5,6
3,5
6,6
3,5
7,6
4,5
1,6
4,5
2,6
4,5
3,6
4,5
4,6
4,5
5,6
4,5
6,6
4,5
7,6
5,5
1,6
5,5
2,6
5,5
3,6
5,5
4,6
5,5
5,6
5,5
6,6
5,5
7,6
6,5
1,6
6,5
2,6
6,5
3,6
6,5
4,6
6,5
5,6
6,5
6,6
6,5
7,6
7,5
1,6
7,5
2,6
7,5
3,6
7,5
4,6
7,5
5,6
7,5
6,6
7,5
7,6
S7 1,5
1,7
1,5
2,7
1,5
3,7
1,5
4,7
1,5
5,7
1,5
6,7
1,5
7,7
2,5
1,7
2,5
2,7
2,5
3,7
2,5
4,7
2,5
5,7
2,5
6,7
2,5
7,7
3,5
1,7
3,5
2,7
3,5
3,7
3,5
4,7
3,5
5,7
3,5
6,7
3,5
7,7
4,5
1,7
4,5
2,7
4,5
3,7
4,5
4,7
4,5
5,7
4,5
6,7
4,5
7,7
5,5
1,7
5,5
2,7
5,5
3,7
5,5
4,7
5,5
5,7
5,5
6,7
5,5
7,7
6,5
1,7
6,5
2,7
6,5
3,7
6,5
4,7
6,5
5,7
6,5
6,7
6,5
7,7
7,5
1,7
7,5
2,7
7,5
3,7
7,5
4,7
7,5
5,7
7,5
6,7
7,5
7,7
Q6 S1 1,6
1,1
1,6
2,1
1,6
3,1
1,6
4,1
1,6
5,1
1,6
6,1
1,6
7,1
2,6
1,1
2,6
2,1
2,6
3,1
2,6
4,1
2,6
5,1
2,6
6,1
2,6
7,1
3,6
1,1
3,6
2,1
3,6
3,1
3,6
4,1
3,6
5,1
3,6
6,1
3,6
7,1
4,6
1,1
4,6
2,1
4,6
3,1
4,6
4,1
4,6
5,1
4,6
6,1
4,6
7,1
5,6
1,1
5,6
2,1
5,6
3,1
5,6
4,1
5,6
5,1
5,6
6,1
5,6
7,1
6,6
1,1
6,6
2,1
6,6
3,1
6,6
4,1
6,6
5,1
6,6
6,1
6,6
7,1
7,6
1,1
7,6
2,1
7,6
3,1
7,6
4,1
7,6
5,1
7,6
6,1
7,6
7,1
S2 1,6
1,2
1,6
2,2
1,6
3,2
1,6
4,2
1,6
5,2
1,6
6,2
1,6
7,2
2,6
1,2
2,6
2,2
2,6
3,2
2,6
4,2
2,6
5,2
2,6
6,2
2,6
7,2
3,6
1,2
3,6
2,2
3,6
3,2
3,6
4,2
3,6
5,2
3,6
6,2
3,6
7,2
4,6
1,2
4,6
2,2
4,6
3,2
4,6
4,2
4,6
5,2
4,6
6,2
4,6
7,2
5,6
1,2
5,6
2,2
5,6
3,2
5,6
4,2
5,6
5,2
5,6
6,2
5,6
7,2
6,6
1,2
6,6
2,2
6,6
3,2
6,6
4,2
6,6
5,2
6,6
6,2
6,6
7,2
7,6
1,2
7,6
2,2
7,6
3,2
7,6
4,2
7,6
5,2
7,6
6,2
7,6
7,2
S3 1,6
1,3
1,6
2,3
1,6
3,3
1,6
4,3
1,6
5,3
1,6
6,3
1,6
7,3
2,6
1,3
2,6
2,3
2,6
3,3
2,6
4,3
2,6
5,3
2,6
6,3
2,6
7,3
3,6
1,3
3,6
2,3
3,6
3,3
3,6
4,3
3,6
5,3
3,6
6,3
3,6
7,3
4,6
1,3
4,6
2,3
4,6
3,3
4,6
4,3
4,6
5,3
4,6
6,3
4,6
7,3
5,6
1,3
5,6
2,3
5,6
3,3
5,6
4,3
5,6
5,3
5,6
6,3
5,6
7,3
6,6
1,3
6,6
2,3
6,6
3,3
6,6
4,3
6,6
5,3
6,6
6,3
6,6
7,3
7,6
1,3
7,6
2,3
7,6
3,3
7,6
4,3
7,6
5,3
7,6
6,3
7,6
7,3
S4 1,6
1,4
1,6
2,4
1,6
3,4
1,6
4,4
1,6
5,4
1,6
6,4
1,6
7,4
2,6
1,4
2,6
2,4
2,6
3,4
2,6
4,4
2,6
5,4
2,6
6,4
2,6
7,4
3,6
1,4
3,6
2,4
3,6
3,4
3,6
4,4
3,6
5,4
3,6
6,4
3,6
7,4
4,6
1,4
4,6
2,4
4,6
3,4
4,6
4,4
4,6
5,4
4,6
6,4
4,6
7,4
5,6
1,4
5,6
2,4
5,6
3,4
5,6
4,4
5,6
5,4
5,6
6,4
5,6
7,4
6,6
1,4
6,6
2,4
6,6
3,4
6,6
4,4
6,6
5,4
6,6
6,4
6,6
7,4
7,6
1,4
7,6
2,4
7,6
3,4
7,6
4,4
7,6
5,4
7,6
6,4
7,6
7,4
S5 1,6
1,5
1,6
2,5
1,6
3,5
1,6
4,5
1,6
5,5
1,6
6,5
1,6
7,5
2,6
1,5
2,6
2,5
2,6
3,5
2,6
4,5
2,6
5,5
2,6
6,5
2,6
7,5
3,6
1,5
3,6
2,5
3,6
3,5
3,6
4,5
3,6
5,5
3,6
6,5
3,6
7,5
4,6
1,5
4,6
2,5
4,6
3,5
4,6
4,5
4,6
5,5
4,6
6,5
4,6
7,5
5,6
1,5
5,6
2,5
5,6
3,5
5,6
4,5
5,6
5,5
5,6
6,5
5,6
7,5
6,6
1,5
6,6
2,5
6,6
3,5
6,6
4,5
6,6
5,5
6,6
6,5
6,6
7,5
7,6
1,5
7,6
2,5
7,6
3,5
7,6
4,5
7,6
5,5
7,6
6,5
7,6
7,5
S6 1,6
1,6
1,6
2,6
1,6
3,6
1,6
4,6
1,6
5,6
1,6
6,6
1,6
7,6
2,6
1,6
2,6
2,6
2,6
3,6
2,6
4,6
2,6
5,6
2,6
6,6
2,6
7,6
3,6
1,6
3,6
2,6
3,6
3,6
3,6
4,6
3,6
5,6
3,6
6,6
3,6
7,6
4,6
1,6
4,6
2,6
4,6
3,6
4,6
4,6
4,6
5,6
4,6
6,6
4,6
7,6
5,6
1,6
5,6
2,6
5,6
3,6
5,6
4,6
5,6
5,6
5,6
6,6
5,6
7,6
6,6
1,6
6,6
2,6
6,6
3,6
6,6
4,6
6,6
5,6
6,6
6,6
6,6
7,6
7,6
1,6
7,6
2,6
7,6
3,6
7,6
4,6
7,6
5,6
7,6
6,6
7,6
7,6
S7 1,6
1,7
1,6
2,7
1,6
3,7
1,6
4,7
1,6
5,7
1,6
6,7
1,6
7,7
2,6
1,7
2,6
2,7
2,6
3,7
2,6
4,7
2,6
5,7
2,6
6,7
2,6
7,7
3,6
1,7
3,6
2,7
3,6
3,7
3,6
4,7
3,6
5,7
3,6
6,7
3,6
7,7
4,6
1,7
4,6
2,7
4,6
3,7
4,6
4,7
4,6
5,7
4,6
6,7
4,6
7,7
5,6
1,7
5,6
2,7
5,6
3,7
5,6
4,7
5,6
5,7
5,6
6,7
5,6
7,7
6,6
1,7
6,6
2,7
6,6
3,7
6,6
4,7
6,6
5,7
6,6
6,7
6,6
7,7
7,6
1,7
7,6
2,7
7,6
3,7
7,6
4,7
7,6
5,7
7,6
6,7
7,6
7,7
Q7 S1 1,7
1,1
1,7
2,1
1,7
3,1
1,7
4,1
1,7
5,1
1,7
6,1
1,7
7,1
2,7
1,1
2,7
2,1
2,7
3,1
2,7
4,1
2,7
5,1
2,7
6,1
2,7
7,1
3,7
1,1
3,7
2,1
3,7
3,1
3,7
4,1
3,7
5,1
3,7
6,1
3,7
7,1
4,7
1,1
4,7
2,1
4,7
3,1
4,7
4,1
4,7
5,1
4,7
6,1
4,7
7,1
5,7
1,1
5,7
2,1
5,7
3,1
5,7
4,1
5,7
5,1
5,7
6,1
5,7
7,1
6,7
1,1
6,7
2,1
6,7
3,1
6,7
4,1
6,7
5,1
6,7
6,1
6,7
7,1
7,7
1,1
7,7
2,1
7,7
3,1
7,7
4,1
7,7
5,1
7,7
6,1
7,7
7,1
S2 1,7
1,2
1,7
2,2
1,7
3,2
1,7
4,2
1,7
5,2
1,7
6,2
1,7
7,2
2,7
1,2
2,7
2,2
2,7
3,2
2,7
4,2
2,7
5,2
2,7
6,2
2,7
7,2
3,7
1,2
3,7
2,2
3,7
3,2
3,7
4,2
3,7
5,2
3,7
6,2
3,7
7,2
4,7
1,2
4,7
2,2
4,7
3,2
4,7
4,2
4,7
5,2
4,7
6,2
4,7
7,2
5,7
1,2
5,7
2,2
5,7
3,2
5,7
4,2
5,7
5,2
5,7
6,2
5,7
7,2
6,7
1,2
6,7
2,2
6,7
3,2
6,7
4,2
6,7
5,2
6,7
6,2
6,7
7,2
7,7
1,2
7,7
2,2
7,7
3,2
7,7
4,2
7,7
5,2
7,7
6,2
7,7
7,2
S3 1,7
1,3
1,7
2,3
1,7
3,3
1,7
4,3
1,7
5,3
1,7
6,3
1,7
7,3
2,7
1,3
2,7
2,3
2,7
3,3
2,7
4,3
2,7
5,3
2,7
6,3
2,7
7,3
3,7
1,3
3,7
2,3
3,7
3,3
3,7
4,3
3,7
5,3
3,7
6,3
3,7
7,3
4,7
1,3
4,7
2,3
4,7
3,3
4,7
4,3
4,7
5,3
4,7
6,3
4,7
7,3
5,7
1,3
5,7
2,3
5,7
3,3
5,7
4,3
5,7
5,3
5,7
6,3
5,7
7,3
6,7
1,3
6,7
2,3
6,7
3,3
6,7
4,3
6,7
5,3
6,7
6,3
6,7
7,3
7,7
1,3
7,7
2,3
7,7
3,3
7,7
4,3
7,7
5,3
7,7
6,3
7,7
7,3
S4 1,7
1,4
1,7
2,4
1,7
3,4
1,7
4,4
1,7
5,4
1,7
6,4
1,7
7,4
2,7
1,4
2,7
2,4
2,7
3,4
2,7
4,4
2,7
5,4
2,7
6,4
2,7
7,4
3,7
1,4
3,7
2,4
3,7
3,4
3,7
4,4
3,7
5,4
3,7
6,4
3,7
7,4
4,7
1,4
4,7
2,4
4,7
3,4
4,7
4,4
4,7
5,4
4,7
6,4
4,7
7,4
5,7
1,4
5,7
2,4
5,7
3,4
5,7
4,4
5,7
5,4
5,7
6,4
5,7
7,4
6,7
1,4
6,7
2,4
6,7
3,4
6,7
4,4
6,7
5,4
6,7
6,4
6,7
7,4
7,7
1,4
7,7
2,4
7,7
3,4
7,7
4,4
7,7
5,4
7,7
6,4
7,7
7,4
S5 1,7
1,5
1,7
2,5
1,7
3,5
1,7
4,5
1,7
5,5
1,7
6,5
1,7
7,5
2,7
1,5
2,7
2,5
2,7
3,5
2,7
4,5
2,7
5,5
2,7
6,5
2,7
7,5
3,7
1,5
3,7
2,5
3,7
3,5
3,7
4,5
3,7
5,5
3,7
6,5
3,7
7,5
4,7
1,5
4,7
2,5
4,7
3,5
4,7
4,5
4,7
5,5
4,7
6,5
4,7
7,5
5,7
1,5
5,7
2,5
5,7
3,5
5,7
4,5
5,7
5,5
5,7
6,5
5,7
7,5
6,7
1,5
6,7
2,5
6,7
3,5
6,7
4,5
6,7
5,5
6,7
6,5
6,7
7,5
7,7
1,5
7,7
2,5
7,7
3,5
7,7
4,5
7,7
5,5
7,7
6,5
7,7
7,5
S6 1,7
1,6
1,7
2,6
1,7
3,6
1,7
4,6
1,7
5,6
1,7
6,6
1,7
7,6
2,7
1,6
2,7
2,6
2,7
3,6
2,7
4,6
2,7
5,6
2,7
6,6
2,7
7,6
3,7
1,6
3,7
2,6
3,7
3,6
3,7
4,6
3,7
5,6
3,7
6,6
3,7
7,6
4,7
1,6
4,7
2,6
4,7
3,6
4,7
4,6
4,7
5,6
4,7
6,6
4,7
7,6
5,7
1,6
5,7
2,6
5,7
3,6
5,7
4,6
5,7
5,6
5,7
6,6
5,7
7,6
6,7
1,6
6,7
2,6
6,7
3,6
6,7
4,6
6,7
5,6
6,7
6,6
6,7
7,6
7,7
1,6
7,7
2,6
7,7
3,6
7,7
4,6
7,7
5,6
7,7
6,6
7,7
7,6
S7 1,7
1,7
1,7
2,7
1,7
3,7
1,7
4,7
1,7
5,7
1,7
6,7
1,7
7,7
2,7
1,7
2,7
2,7
2,7
3,7
2,7
4,7
2,7
5,7
2,7
6,7
2,7
7,7
3,7
1,7
3,7
2,7
3,7
3,7
3,7
4,7
3,7
5,7
3,7
6,7
3,7
7,7
4,7
1,7
4,7
2,7
4,7
3,7
4,7
4,7
4,7
5,7
4,7
6,7
4,7
7,7
5,7
1,7
5,7
2,7
5,7
3,7
5,7
4,7
5,7
5,7
5,7
6,7
5,7
7,7
6,7
1,7
6,7
2,7
6,7
3,7
6,7
4,7
6,7
5,7
6,7
6,7
6,7
7,7
7,7
1,7
7,7
2,7
7,7
3,7
7,7
4,7
7,7
5,7
7,7
6,7
7,7
7,7

The upper pair of numbers are the quadrant X,Y coordinates.
The lower pair of numbers are the sector X,Y coordinates.

In the game, objects are represented thusly on the long-range scanner ("galaxy display"):

1st number = number of aliens         in quadrant
2nd number = number of space stations in quadrant
3rd number = number of stars          in quadrant

In the game, objects are represented thusly on the short-range scanner:

<O> = position of your ship
+++ = position of enemy ship (alien)
 H  = position of space station
 *  = position of star

These issues are known, under Ami/WinArcadia 34.01, at least. The reasons for these issues have not yet been investigated.

For the PIPBUG version only:

The energy display can be incorrect (eg. "08VU", "15\\", etc.).
When firing phasors, the user input prompts are not shown.

For the BINBUG versions only:

The galaxy display is prepended with junk.

Commands are:

0: Move (specify a direction ("course") and distance ("warp factor") in sectors)
1: Short range scan & status
2: Long range scan ("galaxy display")
3: Transfer energy to shield ("shield energy transfer")
4: Fire phasor (specify energy)
5: Fire torpedo (specify direction)

Directions are:

06 05 04 03 02
07 01
08 00
09 15
10 11 12 13 14

Game variables are as follows. All are numbers in ASCII format ('0'..'9') (eg. the value 1234 is represented as $31 $32 $33 $34):

Address(es) Description Range
$60C..$60D stardate (ie. time remaining) 00..99
$62B quadrant X 1..7
$62D quadrant Y 1..7
$63A sector X 1..7
$63C sector Y 1..7
$649..$64C energy 0000..9999
$659 torpedos 0..9
$666..$669 shields 0000..9999
$917..$947 aliens in each of the 49 quadrants 0..9
$948..$978 space stations in each of the 49 quadrants 0..9
$979..$9A9 stars in each of the 49 quadrants 0..9

Binary Floating Point Routines (Application Note AS57):

The program's prompt is corrupt (maybe the emulated teletype is not ready for it).
Each pair of hex digits is not shown until it has been completely input.
The spaces around operators are added automatically by the program rather than by the user.
The start address determines the rounding mode, as follows:

G6A6 will run with rounding.
G6AA will run without rounding.

Give 8 hex digits, then an operator, then another 8 hex digits, then =
Supported operators are +, -, * and : (which is division).

Biorhythm:

Dates are expected to be in dd/mm/yy format.
Invalid dates will cause the program to hang.

Bit Echo:

Prints flashing garbage after each letter, for some reason.

Cricket:

Doesn't randomize very well, for some reason.

DG640 Driver:

To get the flashing cursor, you need PIPBUG (not BINBUG).

ETI-685 Memory Tester:

This expects BINBUG 6.1. It is used as follows:

G440

where and are the start and end addresses, eg.:

G440 1000 1FFF

Funny Farm Races:

1. At the "PLAYER 1-" prompt:
Type in the name of the first player and press ENTER.

2. For each additional player you want to add:
Press P. The machine will say "PLAYER 2-" (or whatever).
Type in the name of the player and then press ENTER.

3. Press ENTER to begin.

4. For each player:
The machine will ask "BET?".
For each bet you want to place:
a. Press Y and then press ENTER.
b. The machine will ask "DOG NO?".
c. Press the number (0..9) of your preferred dog and then press ENTER.
d. The machine will ask "HOW MUCH?".
Press N when this player has placed all their bets.

5. Watch the race and then press ENTER.

6. Go to 4.

Furnace:

This program requires extra hardware (eg. various motors), which is not emulated by Ami/WinPIPBUG. Although it will load and run, it will not do anything useful on the emulators, and, intentionally, does not produce output on the screen. Also, it expects a data table (starting at !6000), which is not present.

Guessing Game (machine code version):

"When called, the program will wait until you enter any character. It will then generate a random number between 1 and 99, which you must guess. Starting address is $0440."

STRT = $440 code
INPT = $493 code
PRNT = $4A6 code
MSAG = $4B1 data

HexCal aka HexCalc:

Enter source address (2 hex digits).
/ appears.
Enter destination address (2 hex digits).
= and result appears.
The first digit of each pair entered is not echoed to the display until the second digit has been input.
Result is the relative offset (ie. the distance between the addresses). Eg.:

01/02=01
03/04=7F
05/05=00
20/30=10

PAIR equ $45E
gosub CRLF;
for (r1 = 3; r1 >= 1; r1--)
{
PAIR = BINOUT();
COUT('/');
PAIR = (BINOUT() - PAIR) & $7F;
COUT('=');
BOUT(PAIR); // Byte output in hex
COUT(' ');
}
goto $3F00;
BINOUT: ;$46D
// Input two hex chars and output in hex
*($476) = BIN(); // Input two hex chars and form as byte
BOUT(*($476)); // Byte output in hex
return *($476);

Hunt the Wumpus:

Here is the map:

             ----0----
            /   / \   \
         --2---5---8---B--
        /  |   |   |   |  \
(E)<---1---3---6---9---C---E--->(1)
        \  |   |   |   |  /
         --4---7---A---D--
            \   \ /   /
             ----F----

Rooms 1 and E are connected.

Room 0 1 2 3 4 5 6 7 8 9 A B C D E F
0 2 5 8 B
1 2 3 4 E
2 0 1 3 5
3 1 2 4 6
4 1 3 7 F
5 0 2 6 8
6 3 5 7 9
7 4 6 A F
8 0 5 9 B
9 6 8 A C
A 7 9 D F
B 0 8 C E
C 9 B D E
D A C E F
E 1 B C D
F 4 7 A D

Life-MachineCode:

"Life is a matrix game concerned with the life, death and birth of cells. Imagine each cell to be in a two-dimensional linear matrix, such that each cell location has eight possible neighbours, as shown:

1 2 3
4 X 5
6 7 8

The rules of cell life, death and birth are as follows:

1. A live cell will survive if it has two or three live neighbours.
2. A live cell will die if it has less than two or more than three live neighbours.
3. A birth in an empty cell will occur if it has exactly three live neighbours.
4. Births and deaths take place simultaneously.

To work with practical terminals the program operates with a limited size matrix, but makes it effectively "infinite" by having "wrap around" from side to side and from top to bottom.
In our version of Life, live cells are represented by Os, and dead or empty cells as blanks. The program starts with an initial pattern (fed in by the player), and calculates the new patterns "generation by generation".
The 32*16 versions are intended for use with the Low Cost VDU of EA February and April 1978. The 32*24 versions are intended for terminals such as the EME-1 VDU, described in the EA January and February 1977 issues.
To use the program, type:

GC00<CR>

and then switch to the appropriate baud rate (110 or 300 baud). Then type a U for 110 baud operation, or a Y for 300 baud operation.
The program will respond with the word "LIFE", followed by the prompt character ":".
If you respond with "N", the program will expect a new matrix to be supplied. The program will echo the N, followed by a carriage return and line feed. A pattern may then be written in (or "seeded") by using the space bar for blanks (these are printed as dots), Os for live cells, and line feeds (LF) [Ctrl+J in Ami/WinArcadia] for new lines.
Blanks are not required on the right hand side of the pattern. Carriage return (CR) will permit overwriting of a line, allowing error correction. Once your pattern is complete, use LFs if necessary to advance to the bottom of the matrix.
Once the pattern is completed, the program will reprint it, and give the prompt sign again. If you now respond with a Gxx, $xx generations will be evolved, with a printout after the last generation. G00 will produce printout after 256 generations, while G01 will produce a printout after only one generation. And so on...
Immediately after you have typed in this command, the program will respond with a message such as <15S, to indicate that in less than 15 seconds it will print out the result of the Gxx instruction. After printing the result the new generation count and prompt will appear at the bottom left hand corner of the screen. This may overwrite live cells, so try and keep your patterns in the centre of the screen (patterns to the right will wrap around to the left).
The remaining instruction is P, which causes the program to print out the existing matrix. The instruction is not used a great deal.
This is the result of a simple pattern. This stabilises after four generations, and then continues forever unchanged:

..O. GENERATION 1
OOO.
....

..O. GENERATION 2
.OO.
.O..

.OO. GENERATION 3
.OO.
.OO.

.OO. GENERATION 4
O..O
.OO.

.OO. GENERATION 5
O..O
.OO.

One of the most interesting and simple patterns has been named the "Glider". The seed for this is shown below:

.O.
..O
OOO

If you are running Life at 1200 baud, it is better to use the autoprint version, which prints out after every generation, and stops automatically when the pattern stabilises.
Simply feed in a starting pattern (using the N command), and sit back and watch. The program will continue until a stable pattern is achieved, at which time it will stop. Note, however, that it cannot detect recurring cyclical patterns, so watch out for these. To stop them, you will have to use the reset facility of the 2650."

For 110 baud, you just need to press U, as documented.
For 300 baud, you need to press U (not Y), then ENTER, contrary to the documentation.
Then press N for a new field and set it up with Os and spaces, using Ctrl-J repeatedly to move down.

$C00..$C59: baud rate initialization routine?
$C26: LIFECRLF
$C39: LIFECOUT
$C5A: LIFECHIN
$C76..$EEC: Life game code
$EED..$F54: Life game variables

LIFECOUT has the following side effects when called:
PSL: CC = eq;
PSL: primary register bank (r1..r3) is always selected
PSU: Flag pin is always set
r1 = *(DATABUS);
r0 = r6 = 0;
You should not call it when SP > 4 (you need one level of stack for LIFECOUT's return address, another level for LIFEDELAY's return address, and another level for LIFEDELAY_ALT's return address.

LIFECHIN has the following side effects when called:
PSL: CC = gt;
PSL: primary register bank (r1..r3) is always selected
PSL: With Carry bit is always clear
r0 = r4 = return code (1..127)
r5 = r6 = 0;
You should not call it when SP > 4 (you need one level of stack for LIFECHIN's return address, another level for LIFEDELAY's return address, and another level for LIFEDELAY_ALT's return address.

Linearization (Linearisatie):

This program requires extra hardware, eg. light pen, which is not supported by Ami/WinPIPBUG. Although it will load and run, it will not do anything useful on the emulators, and, apparently intentionally, does not produce output on the screen.

Lunar Lander (machine code version):

F = Fuel (out of 40)
V = Velocity (- is down (towards surface), + is up (away from surface))
D = Distance from surface (- is underground, + is above ground)
B = Burn

The * is a graphical indicator of your distance from the surface.
You must give a 2-digit burn each turn. Neither digit is displayed until both have been entered.

Lunar Lander (2650 Micro BASIC version):

The pseudocode is:

input fuel (F), velocity (V), height (D)
V = -V; // convert velocity from "down" (towards) to "up" (away from)
for (;;)
{   do
    {   print fuel (F), velocity (V), height (D)
        W = D; // ceiling = height
        input burn (T)
        D += V; // move lander
        F -= T; // deduct burn from fuel
        if   (D > 150) G=-2; // G is the
        elif (D > 100) G=-3; // gravity factor
        elif (D >  50) G=-4; // (stronger closer
        elif (D <  50) G=-5; // to surface)
        else
        {   assert(D == 50);
            G (gravity factor) is uninitialized and will retain its
            value from the previous turn or game (or zero for first run).
        }
        V += T + G; // velocity += burn + gravity factor (applied next turn)
        K = -D * 100; // depth of crater = height below ground * 100
    } while (D > 0 && D <= W); // still above ground but at or below ceiling
    if   (D >  W) escaped gravity, game over
    elif (D <  0) new crater, game over
    else
    {   assert(D == 0);
        if   (V >   0) moving away, continue game
        elif (V ==  0) perfect, game over
        elif (V >  -5) not bad, game over
        elif (V > -10) damage sustained, game over
        elif (V < -10) lander destroyed, game over
        else
        {   assert(V == -10);
            no message given, game over
            (result should really be damage sustained or lander destroyed)
}   }   }

Your burn will not take effect until the turn after you make it.
Any movement away from the moon will be considered to have escaped gravity, regardless of how near you are to it and how much fuel you have.
The weight of your fuel is not taken into consideration by the game. Gravity is taken into consideration but not in an accurate way.
A good landing must have a height of exactly zero and a velocity (for next turn) towards the moon as small as possible.
An example of an easy perfect (if unrealistic) landing would be to start with 6 (or more) units of fuel, velocity down of 1, height of 1, burn of 6. The game changes your height to 1 to 0, and your velocity up from -1 to 0 (it adds the burn of 6 and the gravity factor of -5 to it).

Mastermind, Revised Mastermind:

You need to use Ctrl-L instead of ENTER after each line of input.

Maths Demonstration:

"This program provides the functions of a simple, 3-function calculator. It will multiply, add or subtract two single digit decimal numbers. Normal plus, minus and equals signs are used, with an asterisk symbol for multiplication. Starts at $0440."

Note that the listing is self-contradictory (the machine code bytes do not match the assembly source code).

STRT:
*(MOD) = ADDZ r3;
r3 = SUB1();
for (;;)
{ r0 = CHIN();
  if   (r0 == '+') goto PLUS;
  elif (r0 == '-') goto SUBT;
  elif (r0 == '*') goto MULT;
}

SUBT:
*(MOD) = SUBZ r3;
PLUS: // $45C
gosub COUT(r0); // print operation symbol ('+' or '-')
r2 = r3; // 1st argument
r3 = SUB1(); // 2nd argument
r0 = r2; // 1st argument
MOD:
r0 += r3, or r0 -= r3, depending on the desired operation
if (r0 < 0)
{ r0 = r3 - r2;
  *(A1) = '-'; // store '-' as 1st character
  r0 |= $30; // format for display
  *(A2) = r0; // store r0 as 2nd character
} elif (r0 >= 10)
{ *(A1) = '1'; // store '1' as 1st character
  r0 -= 10;
  r0 |= $30; // format for display
  *(A2) = r0; // store r0 as 2nd character
} else
{ r0 |= $30; // format for display
  *(A1) = r0; // store as 1st character
  r0 = NUL;
  *(A2) = r0 [NUL]; // store as 2nd character
}
goto ZEND;

MULT: // $48E
gosub COUT(r0); // print operation symbol ('*')
r2 = r3; // 1st argument
r3 = SUB1(); // 2nd argument
r0 = 0;
while (r2 != 0)
{ r0 += r3;
  r2--;
}
while (r0 >= 10)
{ r0 -= 10;
  r2++;
}
r2 |= $30; // format for display
*(A1) = r2;
r0 |= $30; // format for display
*(A2) = r0;
goto ZEND;

SUB1:
do
{ r0 = CHIN();
  clear With Carry and COMpare bits
} while (r0 < '0' || r0 > '9');
r3 = r0;
gosub COUT(r0);
r3 &= $0F; // remove display formatting
return r3;

ZEND:
r1 = 0;
while (*(MSAG + ++r1) != 0)
{ COUT(r0);
}
gosub CRLF;
goto STRT;

Memory Test:

You use the program as follows:

G48F <start-address> <end-address> <loops>

where <loops> is "01".."7F". ("80".."$FF" give infinite tests.) Eg.:

G48F 0500 3FFF 7F

If there is no resulting output other than linefeeds (just goes back to the "*" prompt), this indicates success.
Errors are as follows:

Z or S mean that cleared (zeroed) memory did not read back as $00.
W means that a single bit of memory (eg. $10) did not read back correctly.
L means that set memory did not read back as $FF.

The address of the error then follows the error code.

Message Editor:

"Upon being called, this program will give a prompt character, and await a command character. Commands:

T allows a message to be entered
C allows a stored message to be checked
R allows it to be repeated until the CPU is reset

In text input mode, the DEL character acts as a destructive backspace for correcting errors. To return to command mode, type an Esc.
If the message being stored is too long for the buffer, an F will be displayed. Starts at $0440."

MicroByte Adventure:

Due to its length, this has now been split off into a separate document.

MicroWorld BASIC:

Note that this is *not* byte-for-byte identical to the official PIPBUG release of MicroWorld BASIC, as evidenced by the fact that eg. the official BINBUG patch (aka "personality module") for it will not work. The available dump was originally for PIPBUG, then was ported to PHUNSY, then was ported back to PIPBUG.
The first command you should issue is OLD. Then you can RUN or LIST the program.

Mini-Disassembler:

You must type 6 consecutive hex digits. These are not echoed to the screen (except that Ami/WinArcadia do this for you). The first 4 digits are the starting address (including any leading zeroes) and the last 2 digits are the least significant byte of the ending address (the most significant byte is always the same as that of the starting address). Eg.:

0440FF

will disassemble $440..$4FF.
Note that the mnemonics used are not always standard Signetics. Eg.:

HLT = HALT
LPU = LPSU
LPL = LPSL
PPU = PPSU
PPL = PPSL

To disassemble another region, type:

G440

at the command prompt ("*"). If you get another "*", retry; otherwise, now enter a new 6-digit address range.
There are bugs in the published program listing, causing incorrect disassembly of some instructions. There is a fixed version in the Enhancements Pack.
There is also the following unfixed bug: Some situations (eg. 3-byte instruction at $1FE..$200 when range argument was "0100FF") result in the mini-disassembler not detecting the end of the range and instead wrapping back around.

Music:

"The "Music" program occupies locations $4A0 to $5D3, and uses PIPBUG routines. It contains absolute addresses, and is not easily relocated. The music is generated at the flag output of the 2650, and some form of audio transducer is required. This can simply be an audio amplifier and speaker, connected via a suitable attenuator, to the buffered flag output of the CPU.
Monotonic musical notes are generated by pulsing the flag output at suitable rates, with the program "reading" the music from a section of memory. The timing of the music is determined by a time value called "UNIT", which is an even number of up to 15 bits, such that $5160 is about 1/32 of a second.
Each note is specified by two bytes. The first byte represents the number of UNITs that the note will last: $01 gives a duration of 1 UNIT, while $00 gives 256 UNITs, or 8 seconds with a UNIT value of $5160.
The second byte is split into three fields. The most significant bit, bit 7, indicates either a note (%0) or a rest (%1). The next three bits, bits 4, 5 and 6, specify the octave. %111 represents the top octave, while %000 represents the lowest. In practice, the three lowest octaves are not usable, giving a range of only five octaves.
The remaining four bits in the second byte represent the note within the octave. The first note in any octave is E, represented by $0, while the last note is D# (D sharp), represented by $B.
For rests, bits 6 to 0 are not used, so all rests become $80.
It is best to start and end all programs (tunes!) with $80 $80, a long rest, to separate the music from the noises PIPBUG makes while communicating with the terminal. To signify the end of a tune, insert $02 $FF after the long rest.
"Yankee Doodle" occupies locations $5D4 to $6B7, and requires a unit value of $2800, while "Bach" occupies locations $6B8 to $7A3, and requires a unit value of $7000.
To run the program, type:

G58C [<address of first note>] [<value of UNIT>] <CR>

The last two parameters are optional. If they are not given, the program will use the previous values. Thus, to play "Yankee Doodle", type:

G58C 5D4 2800<CR>

and for "Bach", type:

G58C 6B8 7000<CR> "

These print garbage while playing, for some reason.

Note Very low Low Middle High Very high
E $30 $40 $50 $60 $70
F $31 $41 $51 $61 $71
F#/Gb $32 $42 $52 $62 $72
G $33 $43 $53 $63 $73
G#/Ab $34 $44 $54 $64 $74
A $35 $45 $55 $65 $75
A#/Bb $36 $46 $56 $66 $76
B $37 $47 $57 $67 $77
C $38 $48 $58 $68 $78
C#/Db $39 $49 $59 $69 $79
D $3A $4A $5A $6A $7A
D#/Eb $3B $4B $5B $6B $7B
Rest $80 $80 $80 $80 $80

For the purposes of the above table, each "octave" is assumed to begin at E.
Note that there is a short delay for Yankee Doodle, and a long delay for Bach, before they actually begin to play the song.

Nim:

"The game of Nim: starting with 23 you and the program take turns at subtracting a number from 1 to 3. The one that leaves 1 after their move wins. Starting address is $0440."
The winning strategy is as follows:
You will have a turn where there are 6..8 widgets. Taking 1..3 widgets accordingly on this turn will leave 5 widgets.
The computer must then take 1..3 widgets, leaving 2..4 widgets.
You should then take 1..3 widgets accordingly, to leave 1 widget and therefore win.
Ie.:
If 23 remaining on your turn, take 2 leaving 21.
If 22 remaining on your turn, take 1 leaving 21.
If 21 remaining on your turn, take 3 leaving 18 but you are in danger.
If 20 remaining on your turn, take 3 leaving 17.
If 19 remaining on your turn, take 2 leaving 17.
If 18 remaining on your turn, take 1 leaving 17.
If 17 remaining on your turn, take 3 leaving 14 but you are in danger.
If 16 remaining on your turn, take 3 leaving 13.
If 15 remaining on your turn, take 2 leaving 13.
If 14 remaining on your turn, take 1 leaving 13.
If 13 remaining on your turn, take 3 leaving 10 but you are in danger.
If 12 remaining on your turn, take 3 leaving 9.
If 11 remaining on your turn, take 2 leaving 9.
If 10 remaining on your turn, take 1 leaving 9.
If 9 remaining on your turn, you will eventually lose.
If 8 remaining on your turn, take 3 leaving 5.
If 7 remaining on your turn, take 2 leaving 5.
If 6 remaining on your turn, take 1 leaving 5.
If 5 remaining on your turn, you will soon lose.
If 4 remaining on your turn, take 3 leaving 1 and winning.
If 3 remaining on your turn, take 2 leaving 1 and winning.
If 2 remaining on your turn, take 1 leaving 1 and winning.
If 1 remaining on your turn, you have already lost.

Number Game:

The ! prompt means to hit ENTER (it presumably uses this user-dependant delay for randomization).
Numbers up to 65535 are possible.
The target number is stored at $486..$487 in little-endian format.
The number of turns taken is stored at $4A8.

On Screen Clock:

The original published version has a bug at $505 ($00 should be $0C). There is a fixed version in the Games Pack.

This program needs the starting time to be poked into memory and registers before execution. Pause the machine and then set the time like this before starting at $500:
*($573) = tens of hours
r3 = ones of hours
r2 = tens of minutes
r1 = ones of minutes
All values are stored in ASCII format. Eg. for '5', use $35 (ASCII '5'), not $05.
Eg. use this sequence of debugger commands for 11:58:

P
E $573 '1'
E R3 '1'
E R2 '5'
E R1 '8'
J $500
P

When the time reaches 13:00, it will reset back to 01:00 (ie. it is a 12-hour rather than a 24-hour clock).

Othello (Reversi) 2.0:

Input must be in Y,X (row,col) format.

Printer Routines, Trace Routine:

Of course, the provided binaries do nothing (ie. do not "work") by themselves, as they are only subroutines. See the relevant magazine articles for more information about how to use them in your own programs.

Reaction Timer:

You have to react when the cursor is in the leftmost column.

Relative Branch Calculator:

Enter source address (4 hex digits).
Enter destination address (4 hex digits), then "=" appears, and tells you the relative offset (or "?" if out of range).
The first digit of each pair entered is not echoed to the display until the second digit has been input.

Rotate:

"The computer generates a 4*4 array of the first 16 letters of the alphabet, arranged in a random order. The object of the game is to rearrange the array into the following form:

A B C D
E F G H
I J K L
M N O P

The array can only be rearranged by rotating [2*2] blocks of four letters clockwise. The block to be rotated is specified by the letter in its top left hand corner. It is invalid to try to rotate by calling letters on either the bottom row or the right hand column of the array.
If a mistake is made, it can be corrected once between valid rotations. Any two adjacent letters can be exchanged, with the proviso that only one exchange is permitted. When the required pattern has been achieved, or when the game is aborted, the program will print out the number of moves used.
The program occupies locations $440 to $5C7, and uses routines from PIPBUG. To run the program, type:

G440<CR>

and the computer will respond with "PRESS ANY KEY". Once this has been done, a random pattern will be generated and printed, and the prompt message "ROTATE:" given.
Here is a sample printout. The "Z" command was used to terminate the game.

*G440

PRESS ANY KEY

OJMD
EPLI
BFHK
CNAG

ROTATE: F

OJMD
EPLI
BNFK
CAHG

ROTATE: N

OJMD
EFLI
BANK
CHFG

ROTATE: N

OJMD
EPLI
BAFN
CHGK

ROTATE: F

OJMD
EPLI
BAGF
CHKN

ROTATE: EXCHANGE: L,M

OJLD
EPMI
BAGF
CHKN

ROTATE: P

OJLD
EAPI
BGMF
CHKN

ROTATE: M

OJLD
EAPI
BGKM
CHNF

ROTATE: CANCEL

OJLD
EAPI
GMNF
CHKN

ROTATE: G

OJLD
EAPI
BHGF
CKMN

ROTATE: YOU TOOK 07 MOVES

If you wish to rotate a particular block, type the letter in the top left hand corner of that block. If you wish to cancel a move, type carriage return, and the program will respond with "CANCEL", and then reprint the last but one block.
If you wish to exchange two adjacent letters, type X. The program will respond with "EXCHANGE:", and expect you to type in the two desired letters. If you cannot solve a particular pattern, type Z, and this will abort the game.
An average pattern, with only one exchange permitted, should take between 25 and 30 moves. Early attempts may take more."
Note that the game does not enforce the rule about only permitting one exchange per game.
The unpatched version (ie. as found in the Games Pack) will not work on Ami/WinArcadia. You should use the patched version (ie. as found in the Enhancements Pack).

RYTMON:

This program does not echo your input to the screen.

Solitaire:

This game expects a display with more than 16 rows.

Star Shoot:

The objective is to reach the end configuration shown below in as few moves as possible, by shooting stars. Each move consists of a digit 1-9 corresponding to the position of the star to shoot:

No. Start End
123 ... ***
456 .*. *.*
789 ... ***

The only valid first move is 5. Shots have these results:

1 2 3 4 5 6 7 8 9
.!-
!!-
---
!.!
---
---
-!.
-!!
---
!--
.--
!--
-!-
!.!
-!-
--!
--.
--!
---
!!-
.!-
---
---
!.!
---
-!!
-!.

. means the star becomes a dot
! means the star or dot becomes a dot or star (respectively).
- are unchanged. It is possible to reach a configuration with zero stars and thus no possible moves, losing the game.

Time:

This program uses cycle counting techniques. Under Ami/WinArcadia 8.41, it appears to run too fast (ie. the "game" time goes faster than the emulator time).
The two most likely possibilities would be:
(a) the program was not originally tested and tuned to a sufficient precision by its programmer; and/or
(b) the real machine is spending a certain number of cycles servicing interrupts (which don't occur in the emulator).
Of course, since it starts counting from minute 1 rather than minute 0, the time as shown in this program will be minute later than that shown by the emulator.
When this program says "0100" (ie. "one hour"), emulator time should be approximately "00:59:00.00" (though it would be fair to allow a few milliseconds for initialization). However, emulator time when this event occurs is actually only "00:58:47.20". So this program is 12.80 seconds fast over that 59 minutes. (Or, conversely, you could suggest that the emulator is slow by that amount, or a combination of both.)
Such accuracy is approximately 1:276.5625 (slightly worse than 1 second fast per 5 minutes), which makes this program rather useless over lengthy periods.

Vector Magnetometer:

This program expects extra input (eg. various sensors) and output (eg. pitch and roll indicators) hardware, which is not supported by Ami/WinPIPBUG. (The LED display, used for output of heading data, is supported.) Although it will load and run, it will not do anything useful on the emulators, and, intentionally, does not produce output on the main screen (only via the LED display).

Signetics Instructor 50

This machine is a "microprocessor development board" aka "trainer".
The start address for user programs can be specified at runtime by the user as with eg. the Elektor TV Games Computer.
BIOS calls are made via eg. ZBSR *DISPLY; there is a zero page jump table at $1FE6..$1FFF.

Hardware equates/memory map

Region Size Basic version Expanded version
$0000..$01FF 512 bytes user RAM user RAM
$0200..$0FFE 3582 bytes unused expansion RAM
$0FFF 1 byte I/O port I/O port
$1000..$177F 1920 bytes unused unused
$1780..$17BF 64 bytes user RAM user RAM
$17C0..$17FF 64 bytes monitor RAM monitor RAM
$1800..$1FFF 2K monitor ROM monitor ROM
$2000..$7FFF 24K unused expansion RAM

I/O Devices

The 28-key keyboard is as follows:

------Left Keypad------ ---------Right Keypad----------
.SENS.. .WCAS.. .BKPT.. ...C... ...D... ...E... ...F...
..INT.. .RCAS.. ..REG.. ...8... ...9... ...A... ...B...
..MON.. .STEP.. ..MEM.. ...4... ...5... ...6... ...7...
..RST.. ..RUN.. ENT NXT ...0... ...1... ...2... ...3...

MON, RST and ENT NXT are white on orange. All other keys are white on blue. There are no paddles.

8-digit 8-segment LED display (red on black):

Each of the 8 digits is divided into 8 segments, as shown: +0+ The + don't really exist, therefore it is really like this: 5 1 +6+ 0 4 2 5 1 +3+ 7 6 4 2 3 7 Eg. the bottom segment is controlled by bit 3 (so, $08 would set it, $00 would clear it). The display is controllable at the segment level (ie. you can get 256 combinations) via direct hardware access (ie. bypassing USE BIOS functions and using the WRTE instruction), using the bit numbers listed above.

"PARALLEL I/O" section, consisting of:

8 glow LEDs ("7".."0");
8 corresponding toggle switches (unlabelled);
Toggle switch with 3 possible positions (up, middle and down, corresponding to "MEMORY $0FFF", "EXTENDED I/O PORT $07" and "NON-EXT DATA PORT", respectively). "The default is probably EXTENDED I/O PORT $07."

In NON-EXTENDED I/O mode:

REDD,rn to read from the toggle switches
WRTD,rn to write to the glow LEDs

In EXTENDED I/O mode:

REDE,rn $07 to read from the toggle switches
WRTE,rn $07 to write to the glow LEDs

In MEMORY MAPPED I/O mode:

LODA,rn $0FFF to read from the toggle switches
STRA,rn $0FFF to write to the glow LEDs

"RUN" glow LED:

"It appears to be on all the time. It is on in monitor mode, during stepping, and remains on at breakpoints. It will turn off after the processor executes a HALT ($40) instruction. It won't turn back on again until you hit MON, RST, in that order. You can't just break back into monitor mode after hitting a HALT instruction. Hitting MON, RST somehow brings the machine back to life and into monitor mode; otherwise the machine is dark." - Tyler Whitney.

"FLAG" glow LED, showing the state of the Flag pin of the CPU.

"INTERRUPT" toggle switch: "DIRECT" or "INDIRECT":

When an interrupt is generated/received, the Instructor 50 writes $07 or $87 to the data bus, depending on the position of the DIRECT/INDIRECT INTERRUPT switch. Then it does a ZBSR $07 or ZBSR *$07, as appropriate.

"INTERRUPT SELECTOR" jumper (on underside of machine):

"A.C. LINE" (ie. 50Hz) or
"KEYBOARD" (ie. INT key).
"The default is probably keyboard."

S-100 bus (at rear) (not emulated).

"CASSETTE" jacks: "PHONE" and "MIC":

The cassette subsystem is somewhat like that of the Elektor TV Games Computer, but uses 6 pulses for a "0" and 3 pulses for a "1", except that 3 extra pulses are appended to the last bit of each byte (giving 6+3=9 pulses for a "0" or 3+3=6 pulses for a "1").
As with the Elektor, the rate at which bits (and thus bytes) can be loaded/saved depends the actual data payload (ie. depends on whether they are "0"s or "1"s).
Port $F8 bit 4 is FREQ. The BIOS is flipping that at a constant regular rate (at least while recording).
Port $F8 bit 3 is ENV. That is high whilever we are actually recording a bit, and goes low between bits. It stays high for longer for a "0" bit than for a "1" bit.
So whilever ENV is high, we just write the current status of the FREQ bit to the tape, and whilever ENV is low, we just write silence.
It gets NANDed, so if ENV and FREQ are both high, we are low, and otherwise, we are high.
It sets port $F8 to $10 and $18 while writing, and $00 at rest.
During playback, the Sense bit is set directly from the tape based on whether above or below the zero-crossing point.

USE BIOS

USE is an acronym for "User System Executive".

"When in Monitor mode, pressing anything on the hex keypad generates Error 2 on the real machine. On the control keypad, you can hit most keys with impunity. Hitting STEP while in monitor mode generates Error 9 on the real machine." - Tyler Whitney.
Error 2 means: "Restricted command."
Error 9 means: "Next instruction is in the MONITOR area." Ie. if the STEP button is pressed and the next instruction would be in the monitor area, it will be reported by the appearance of Error 9.

The USRDSP (USeR DiSPlay) command is used as follows:

R0: Return code.
R1..R2: Pointer to byte preceding string.
R3: $00/$01/$80. $01 returns immediately. The USE BIOS only allows character-level (ie. glyph-level) access. The character set is as follows:

$00 $01 $02 $03 $04 $05 $06 $07 $08 $09 $0A $0B $0C $0D $0E $0F $10 $11 $12 $13 $14 $15 $16 $17 $18 $19 $1A $1B $1C
0 or O 1 or I 2 3 4 5 6 7 8 9 A b. C d. E F P L U r H o = space J - . Y n
###..########.####################.. ###..# ##########..#.#...#.#...........#...... #.#...
# #. #. #. ## ## .# .. ## ## ## ## . # .. # # .# .# ## .# #. .# #. .. .. .. #. .. . # #. .
#.#..################..############# #..### ##########..#.#############.....####... ######
# #. ## .. #. #. ## #. ## #. ## ## # # .# # # .# .# .# .# ## .# ## #. .. .. #. .. . . ## #
###..#######..#######..####..##.#### ####### #####..#..#######..#.#######...###...... #####.#

Note the trailing dots for "b." and "d.".
Available letters: ABCDEFGHIJLNOPRSUY
Unavailable letters: KMQTVWXZ

Game Help

Beat the Odds:

You can make a bet on any of the following results:

Event Odds
0 lamps lit 250:1
1 lamp lit 15:1
2 lamps lit 7:1
3 lamps lit 7:2 (3.5:1)
4 lamps lit 5:2 (2.5:1)
5 lamps lit 7:2 (3.5:1)
6 lamps lit 7:1
7 lamps lit 15:1
8 lamps lit 250:1
0..1 lamps lit 25:1
2..3 lamps lit 2:1
4..5 lamps lit 1:1
6..8 lamps lit 6:1
0..2 lamps lit 11:2 (5.5:1)
3..5 lamps lit 2:5 (1:10)
6..8 lamps lit 11:2 (5.5:1)
Specific 2-digit number 250:1
Specific MS digit 15:1
Specific LS digit 15:1
Any one of 5 specified 2-digit numbers 50:1
Any one of 10 specified 2-digit numbers 25:1

Note that in the table above, the bet "6..8 lamps lit" is listed twice, with different odds. This is authentic to the original Signetics documentation.

This game is intended to be played by multiple humans using real money. One player would act as the "house" (ie. banker/dealer) and call for bets, take and record wagers, operate the computer, and pay winners according to the above odds. The computer is used merely as a randomizer. There is no lo