Amigan Software
Signetics-based Machines Coding/Gaming Guide
This document was written on 29/8/08, and last updated on 18/6/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
├ 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:
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$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 |
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.
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.
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 |
$FF | 30.75781 | 30.5176 | b0 | ? |
$FE | 30.87843 | 30.6373 | B0 (30.868 Hz) | ? |
$FD | 31.00000 | 30.7579 | b0 | ? |
$FC | 31.12253 | 30.8794 | b0 | B0 (30.868 Hz) |
$FB | 31.24603 | 31.0020 | b0 | ? |
$FA | 31.37052 | 31.1255 | b0 | ? |
$F9 | 31.49600 | 31.2500 | b0 | ? |
$F8 | 31.62249 | 31.3755 | b0 | ? |
$F7 | 31.75000 | 31.5020 | c1 | ? |
$F6 | 31.87854 | 31.6296 | c1 | ? |
$F5 | 32.00813 | 31.7581 | c1 | ? |
$F4 | 32.13877 | 31.8878 | c1 | ? |
$F3 | 32.27049 | 32.0184 | c1 | ? |
$F2 | 32.40329 | 32.1502 | c1 | ? |
$F1 | 32.53719 | 32.2831 | c1 | ? |
$F0 | 32.67220 | 32.4170 | C1 (32.703 Hz) | ? |
$EF | 32.80833 | 32.5521 | c1 | ? |
$EE | 32.94561 | 32.6883 | c1 | C1 (32.703 Hz) |
$ED | 33.08403 | 32.8256 | c1 | ? |
$EC | 33.22363 | 32.9641 | c1 | ? |
$EB | 33.36441 | 33.1038 | c1 | ? |
$EA | 33.50638 | 33.2447 | c1 | ? |
$E9 | 33.64957 | 33.3868 | c#1/d♭1 | ? |
$E8 | 33.79399 | 33.5300 | c#1/d♭1 | ? |
$E7 | 33.93966 | 33.6746 | c#1/d♭1 | ? |
$E6 | 34.08658 | 33.8203 | c#1/d♭1 | ? |
$E5 | 34.23478 | 33.9674 | c#1/d♭1 | ? |
$E4 | 34.38428 | 34.1157 | c#1/d♭1 | ? |
$E3 | 34.53509 | 34.2654 | c#1/d♭1 | ? |
$E2 | 34.68723 | 34.4163 | C#1/D♭1 (34.648 Hz) | ? |
$E1 | 34.84071 | 34.5686 | c#1/d♭1 | ? |
$E0 | 34.99556 | 34.7222 | c#1/d♭1 | C#1 (34.648 Hz) |
$DF | 35.15179 | 34.8772 | c#1/d♭1 | ? |
$DE | 35.30942 | 35.0336 | c#1/d♭1 | ? |
$DD | 35.46847 | 35.1914 | c#1/d♭1 | ? |
$DC | 35.62896 | 35.3507 | d1 | ? |
$DB | 35.79091 | 35.5114 | d1 | ? |
$DA | 35.95434 | 35.6735 | d1 | ? |
$D9 | 36.11927 | 35.8372 | d1 | ? |
$D8 | 36.28571 | 36.0023 | d1 | ? |
$D7 | 36.45370 | 36.1690 | d1 | ? |
$D6 | 36.62326 | 36.3372 | D1 (36.708 Hz) | ? |
$D5 | 36.79439 | 36.5070 | d1 | ? |
$D4 | 36.96714 | 36.6784 | d1 | D1 (36.708 Hz) |
$D3 | 37.14151 | 36.8514 | d1 | ? |
$D2 | 37.31754 | 37.0261 | d1 | ? |
$D1 | 37.49524 | 37.2024 | d1 | ? |
$D0 | 37.67464 | 37.3804 | d1 | ? |
$CF | 37.85577 | 37.5601 | d#1/e♭1 | ? |
$CE | 38.03865 | 37.7415 | d#1/e♭1 | ? |
$CD | 38.22330 | 37.9248 | d#1/e♭1 | ? |
$CC | 38.40976 | 38.1098 | d#1/e♭1 | ? |
$CB | 38.59804 | 38.2966 | d#1/e♭1 | ? |
$CA | 38.78818 | 38.4852 | d#1/e♭1 | ? |
$C9 | 38.98020 | 38.6757 | D#1/e♭1 (38.891 Hz) | ? |
$C8 | 39.17413 | 38.8682 | d#1/e♭1 | D#1/E♭1 (38.891 Hz) |
$C7 | 39.37000 | 39.0625 | d#1/e♭1 | ? |
$C6 | 39.56784 | 39.2588 | d#1/e♭1 | ? |
$C5 | 39.76768 | 39.4571 | d#1/e♭1 | ? |
$C4 | 39.96954 | 39.6574 | d#1/e♭1 | ? |
$C3 | 40.17347 | 39.8597 | e1 | ? |
$C2 | 40.37949 | 40.0641 | e1 | ? |
$C1 | 40.58763 | 40.2706 | e1 | ? |
$C0 | 40.79793 | 40.4793 | e1 | ? |
$BF | 41.01042 | 40.6901 | e1 | ? |
$BE | 41.22513 | 40.9031 | E1 (41.203 Hz) | ? |
$BD | 41.44210 | 41.1184 | e1 | E1 (41.203 Hz) |
$BC | 41.66138 | 41.3360 | e1 | ? |
$BB | 41.88298 | 41.5559 | e1 | ? |
$BA | 42.10695 | 41.7781 | e1 | ? |
$B9 | 42.33333 | 42.0027 | e1 | ? |
$B8 | 42.56216 | 42.2297 | f1 | ? |
$B7 | 42.79348 | 42.4592 | f1 | ? |
$B6 | 43.02732 | 42.6913 | f1 | ? |
$B5 | 43.26374 | 42.9258 | f1 | ? |
$B4 | 43.50276 | 43.1630 | f1 | ? |
$B3 | 43.74445 | 43.4028 | F1 (43.654 Hz) | ? |
$B2 | 43.98883 | 43.6453 | f1 | F1 (43.654 Hz) |
$B1 | 44.23595 | 43.8904 | f1 | ? |
$B0 | 44.48587 | 44.1384 | f1 | ? |
$AF | 44.73864 | 44.3892 | f1 | ? |
$AE | 44.99429 | 44.6429 | f1 | ? |
$AD | 45.25287 | 44.8994 | f#1/g♭1 | ? |
$AC | 45.51445 | 45.1590 | f#1/g♭1 | ? |
$AB | 45.77907 | 45.4215 | f#1/g♭1 | ? |
$AA | 46.04678 | 45.6871 | f#1/g♭1 | ? |
$A9 | 46.31765 | 45.9559 | F#1/G♭1 (46.249 Hz) | ? |
$A8 | 46.59172 | 46.2278 | f#1/g♭1 | F#1/G♭1 (46.249 Hz) |
$A7 | 46.86905 | 46.5030 | f#1/g♭1 | ? |
$A6 | 47.14970 | 46.7814 | f#1/g♭1 | ? |
$A5 | 47.43373 | 47.0633 | f#1/g♭1 | ? |
$A4 | 47.72121 | 47.3485 | f#1/g♭1 | ? |
$A3 | 48.01220 | 47.6372 | g1 | ? |
$A2 | 48.30675 | 47.9294 | g1 | ? |
$A1 | 48.60494 | 48.2253 | g1 | ? |
$A0 | 48.90683 | 48.5248 | G1 (48.999 Hz) | ? |
$9F | 49.21250 | 48.8281 | g1 | ? |
$9E | 49.52201 | 49.1352 | g1 | G1 (48.999 Hz) |
$9D | 49.83544 | 49.4462 | g1 | ? |
$9C | 50.15287 | 49.7611 | g1 | ? |
$9B | 50.47436 | 50.0801 | g1 | ? |
$9A | 50.80000 | 50.4032 | g#1/a♭1 | ? |
$99 | 51.12987 | 50.7305 | g#1/a♭1 | ? |
$98 | 51.46405 | 51.0621 | g#1/a♭1 | ? |
$97 | 51.80263 | 51.3980 | G#1/A♭1 (51.913 Hz) | ? |
$96 | 52.14569 | 51.7384 | g#1/a♭1 | ? |
$95 | 52.49333 | 52.0833 | g#1/a♭1 | G#1/A♭1 (51.913 Hz) |
$94 | 52.84564 | 52.4329 | g#1/a♭1 | ? |
$93 | 53.20270 | 52.7872 | g#1/a♭1 | ? |
$92 | 53.56462 | 53.1463 | a1 | ? |
$91 | 53.93151 | 53.5103 | a1 | ? |
$90 | 54.30345 | 53.8793 | a1 | ? |
$8F | 54.68056 | 54.2535 | a1 | ? |
$8E | 55.06294 | 54.6329 | A1 (55.000 Hz) | ? |
$8D | 55.45070 | 55.0176 | a1 | A1 (55.000 Hz) |
$8C | 55.84397 | 55.4078 | a1 | ? |
$8B | 56.24286 | 55.8036 | a1 | ? |
$8A | 56.64748 | 56.2050 | a1 | ? |
$89 | 57.05797 | 56.6123 | a#1/b♭1 | ? |
$88 | 57.47445 | 57.0255 | a#1/b♭1 | ? |
$87 | 57.89706 | 57.4449 | a#1/b♭1 | ? |
$86 | 58.32593 | 57.8704 | A#1/B♭1 (58.270 Hz) | ? |
$85 | 58.76119 | 58.3022 | a#1/b♭1 | A#1/B♭1 (58.270 Hz) |
$84 | 59.20301 | 58.7406 | a#1/b♭1 | ? |
$83 | 59.65152 | 59.1856 | a#1/b♭1 | ? |
$82 | 60.10687 | 59.6374 | a#1/b♭1 | ? |
$81 | 60.56923 | 60.0962 | a#1/b♭1 | ? |
$80 | 61.03876 | 60.5620 | b1 | ? |
$7F | 61.52 | 61.0352 | B1 (61.735 Hz) | b1 |
$7E | 62.00 | 61.5157 | b1 | B1 (61.735 Hz) |
$7D | 62.49 | 62.0040 | b1 | b1 |
$7C | 62.99 | 62.5000 | b1 | b1 |
$7B | 63.50 | 63.0040 | b1 | b1 |
$7A | 64.02 | 63.5163 | c2 | c2 |
$79 | 64.54 | 64.0369 | c2 | c2 |
$78 | 65.07 | 64.5661 | c2 | c2 |
$77 | 65.62 | 65.1042 | C2 (65.406 Hz) | c2 |
$76 | 66.17 | 65.6513 | c2 | C2 (65.406 Hz) |
$75 | 66.73 | 66.2076 | c2 | ? |
$74 | 67.30 | 66.7735 | c2 | ? |
$73 | 67.88 | 67.3491 | c#2/d♭2 | ? |
$72 | 68.47 | 67.9348 | c#2/d♭2 | ? |
$71 | 69.07 | 68.5307 | c#2/d♭2 | ? |
$70 | 69.68 | 69.1372 | C#2/D♭2 (69.296 Hz) | C#2/D♭2 (69.296 Hz) |
$6F | 70.30 | 69.7545 | c#2/d♭2 | ? |
$6E | 70.94 | 70.3829 | c#2/d♭2 | ? |
$6D | 71.58 | 71.0227 | d2 | ? |
$6C | 72.24 | 71.6743 | d2 | ? |
$6B | 72.91 | 72.3380 | D2 (73.416 Hz) | ? |
$6A | 73.59 | 73.0140 | d2 | ? |
$69 | 74.28 | 73.7028 | d2 | D2 (73.416 Hz) |
$68 | 74.99 | 74.4048 | d2 | ? |
$67 | 75.71 | 75.1202 | d2 | ? |
$66 | 76.45 | 75.8495 | d#2/e♭2 | ? |
$65 | 77.20 | 76.5931 | d#2/e♭2 | ? |
$64 | 77.96 | 77.3515 | D#2/E♭2 (77.782 Hz) | D#2/E♭2 (77.782 Hz) |
$63 | 78.74 | 78.1250 | d#2/e♭2 | ? |
$62 | 79.54 | 78.9141 | d#2/e♭2 | ? |
$61 | 80.35 | 79.7194 | e2 | ? |
$60 | 81.18 | 80.5412 | e2 | ? |
$5F | 82.02 | 81.3802 | E2 (82.407 Hz) | ? |
$5E | 82.88 | 82.2368 | e2 | E2 (82.407 Hz) |
$5D | 83.77 | 83.1117 | e2 | ? |
$5C | 84.67 | 84.0054 | e2 | ? |
$5B | 85.59 | 84.9185 | f2 | ? |
$5A | 86.53 | 85.8516 | f2 | ? |
$59 | 87.49 | 86.8056 | F2 (87.307 Hz) | ? |
$58 | 88.47 | 87.7809 | f2 | F2 (87.307 Hz) |
$57 | 89.48 | 88.7784 | f2 | ? |
$56 | 90.51 | 89.7989 | f#2 | ? |
$55 | 91.56 | 90.8430 | f#2 | ? |
$54 | 92.64 | 91.9118 | F#2/G♭2 (92.499 Hz) | ? |
$53 | 93.74 | 93.0060 | f#2 | F#2/G♭2 (92.499 Hz) |
$52 | 94.87 | 94.1265 | g2 | ? |
$51 | 96.02 | 95.2744 | g2 | ? |
$50 | 97.21 | 96.4506 | g2 | ? |
$4F | 98.42 | 97.6563 | G2 (97.999 Hz) | G2 (97.999 Hz) |
$4E | 99.67 | 98.8924 | g2 | ? |
$4D | 100.95 | 100.160 | g#2/a♭2 | ? |
$4C | 102.26 | 101.461 | g#2/a♭2 | ? |
$4B | 103.61 | 102.796 | G#2/A♭2 (103.826 Hz) | ? |
$4A | 104.99 | 104.167 | g#2/a♭2 | G#2/A♭2 (103.826 Hz) |
$49 | 106.41 | 105.574 | g#2/a♭2 | ? |
$48 | 107.86 | 107.021 | a2 | ? |
$47 | 109.36 | 108.507 | a2 | ? |
$46 | 110.90 | 110.035 | A2 (110.000 Hz) | A2 (110.000 Hz) |
$45 | 112.49 | 111.607 | a2 | ? |
$44 | 114.12 | 113.225 | a#2/b♭2 | ? |
$43 | 115.79 | 114.890 | a#2/b♭2 | ? |
$42 | 117.52 | 116.604 | A#2/B♭2 (116.541 Hz) | A#2/B♭2 (116.541 Hz) |
$41 | 119.30 | 118.371 | a#2/b♭2 | ? |
$40 | 121.14 | 120.192 | a#2/b♭2 | ? |
$3F | 123.03 | 122.070 | B2 (123.471 Hz) | B2 (123.471 Hz) |
$3E | 124.98 | 124.008 | b2 | ? |
$3D | 127.00 | 126.008 | c3 | ? |
$3C | 129.08 | 128.074 | c3 | ? |
$3B | 131.23 | 130.208 | C3 (130.813 Hz) | C3 (130.813 Hz) |
$3A | 133.46 | 132.415 | c#3 | - |
$39 | 135.76 | 134.698 | c#3 | - |
$38 | 138.14 | 137.061 | C#3/D♭3 (138.591 Hz) | ? |
$37 | 140.61 | 139.509 | c#3 | C#3/D♭3 (138.591 Hz) |
$36 | 143.16 | 142.045 | d3 | ? |
$35 | 145.81 | 144.676 | D3 (146.832 Hz) | ? |
$34 | 148.57 | 147.406 | d3 | D3 (146.832 Hz) |
$33 | 151.42 | 150.240 | d3 | ? |
$32 | 154.39 | 153.186 | d#3/e♭3 | ? |
$31 | 157.48 | 156.250 | D#3/E♭3 (155.563 Hz) | |
$30 | 160.69 | 159.439 | d#3/e♭3 | ? |
$2F | 164.04 | 162.760 | E3 (164.814 Hz) | ? |
$2E | 167.53 | 166.223 | e3 | E3 (164.814 Hz) |
$2D | 171.17 | 169.837 | f3 | ? |
$2C | 174.98 | 173.611 | F3 (174.614 Hz) | |
$2B | 178.95 | 177.557 | f3 | ? |
$2A | 183.12 | 181.686 | F#3/G♭3 (184.997 Hz) | ? |
$29 | 187.48 | 186.012 | f#3/g♭3 | F#3/G♭3 (184.997 Hz) |
$28 | 192.05 | 190.549 | g3 | ? |
$27 | 196.85 | 195.313 | G3 (195.998 Hz) | |
$26 | 201.90 | 200.321 | g3 | ? |
$25 | 207.21 | 205.592 | G#3/A♭3 (207.652 Hz) | |
$24 | 212.81 | 211.149 | g#3/a♭3 | ? |
$23 | 218.72 | 217.014 | A3 (220.000 Hz) | |
$22 | 224.97 | 223.214 | a3 | ? |
$21 | 231.59 | 229.779 | A#3/B♭3 (233.082 Hz) | |
$20 | 238.61 | 236.742 | a#3/b♭3 | ? |
$1F | 246.06 | 244.141 | B3 (246.942 Hz) | |
$1E | 254.00 | 252.016 | b3 | ? |
$1D | 262.47 | 260.417 | C4 (261.626 Hz) | |
$1C | 271.52 | 269.397 | c#4/d♭4 | ? |
$1B | 281.21 | 279.018 | C#4/D♭4 (277.183 Hz) | |
$1A | 291.63 | 289.352 | D4 (293.665 Hz) | |
$19 | 302.84 | 300.481 | d4 | ? |
$18 | 314.96 | 312.500 | D#4/E♭4 (311.127 Hz) | |
$17 | 328.08 | 325.521 | E4 (329.628 Hz) | |
$16 | 342.35 | 339.674 | f4 | ? |
$15 | 357.91 | 355.114 | F4 (349.228 Hz) | |
$14 | 374.95 | 372.024 | F#4/G♭4 (369.994 Hz) | |
$13 | 393.70 | 390.625 | G4 (391.995 Hz) | |
$12 | 414.42 | 411.184 | G#4/A♭4 (415.305 Hz) | |
$11 | 437.44 | 434.028 | A4 (440.000 Hz) | |
$10 | 463.18 | 459.559 | A#4/B♭4 (466.164 Hz) | |
$0F | 492.12 | 488.281 | B4 (493.883 Hz) | |
$0E | 524.93 | 520.833 | C5 (523.251 Hz) | |
$0D | 562.43 | 558.036 | C#5/D♭5 (554.365 Hz) | |
D5 (587.33 Hz) | ||||
$0C | 605.69 | 600.962 | D#5 (622.254 Hz) | D5 (587.33 Hz) |
$0B | 656.17 | 651.042 | E5 (659.255 Hz) | |
$0A | 715.82 | 710.227 | F5 (698.456 Hz) | |
F#5/G♭5 (739.99 Hz) | ||||
$09 | 787.40 | 781.250 | G5 (783.991) | |
G#5/A♭5 (830.61 Hz) | ||||
$08 | 874.89 | 868.056 | A5 (880.000 Hz) | |
A#5/B♭5 (932.30 Hz) | ||||
$07 | 984.25 | 976.562 | B5 (987.767 Hz) | |
C6 (1046.50 Hz) | ||||
$06 | 1124.86 | 1116.071 | C#6/D♭6 (1108.731 Hz) | |
D6 (1174.70 Hz) | ||||
D#6/E♭6 (1244.50 Hz) | ||||
$05 | 1312.33 | 1302.083 | E6 (1318.510 Hz) | |
F6 (1396.90 Hz) | ||||
F#6/G♭6 (1480.00 Hz) | ||||
$04 | 1574.80 | 1562.500 | G6 (1567.982 Hz) | |
G#6/A♭6 (1661.20 Hz) | ||||
A6 (1760.00 Hz) | ||||
A#6/B♭6 (1864.66 Hz) | ||||
$03 | 1968.50 | 1953.125 | B6 (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) | ||||
$02 | 2624.67 | 2604.167 | E7 (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) | ||||
$01 | 3937.00 | 3906.250 | B7 (3951.07 Hz) | |
$00 | Rest |
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 ![]() | |||
$2000..$7FFF | 24K | 3 mirrors of $0000..$1FFF |
1Backgammon, Chess 1 and Draughts only.
2Chess 2 only.
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 ![]() ·suggested in ![]() ·suggested in ![]() ·suggested in ![]() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$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:
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$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):
| ||||||||||||||||||||||||||||
$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:
| ||||||||||||||||||||||||||||
$8AC..$8B4 | 9 bytes | REGM | 2650 register status:
| ||||||||||||||||||||||||||||
$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 | 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 | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | 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 | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | Notes |
![]() ![]() | SEP78 | Sep78 | - | SEP78 | ? | ? | TI SN76477N |
![]() | NOV78 | Nov78 | JAN79 | NOV78 | Jan80 | Jun81 | KB05 |
![]() | DEC78 | - | - | - | - | - | - |
![]() | Dec78 | ? | ? | ? | ? | ? | - |
![]() | MAY79 | May79 | JUN79 | SEP79 | Feb80 | ? | - |
![]() | JUL79 | Jul79 | JUL79 | JUL79 | ? | ? | - |
![]() ![]() | MAR81 | FEB81 | MAY81 | MAR81 | Nov81 | Oct81 | TI SN76477N. Aka Imitator |
![]() | 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 | ![]() | ![]() |
$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
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.
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 |
![]() | 110 | 110 | 110 | 1 | $0..$3FF | ? | EA 300 baud mod is possible |
![]() | 110/300 | 110/300 | 110/300? | 1 | $0..$3FF | ? | Supports both rates |
![]() | 300 | 300 | High-speed | 1 | ? | ? | 600 and 1200 baud mods are possible |
![]() | 300/parallel? | DG640 | 300 | 1? | $0..$7FF | ? | - |
![]() | 300/parallel? | DG640 | 300 | 1 | $0..$7FF | 1979 | BINBUG3.6.pdf |
![]() | 300 | DG640 | ACOS | 1? | $0..$7FF | ? | Supports ACOS and DOS |
![]() | ? | DG640 | ACOS | 1? | $0..$7FF | ? | Supports ACOS and DOS |
![]() | 1200 | 1200 | ACOS | 1? | $0..$7FF | ? | Supports ACOS and DOS |
![]() | ? | serial | ACOS | ? | $0..$7FF | ? | - |
![]() | Eurocard | Eurocard | ACOS | ? | $0..$7FF | ? | - |
![]() | 150?/300/1200/2400/parallel | DG640 | ACOS | ? | $0..$7FF | 1982 | sbcos_manual.pdf . Supports ACOS and VHSDOS |
![]() | 300/1200/2400/parallel | 300/1200/2400 | ACOS | ? | $0..$7FF | 1982 | sbcos_manual.pdf . Supports ACOS and VHSDOS |
![]() | 300 | DG640 | ? | 1/2 | $0..$7FF | ? | Optional parallel keyboard support |
![]() | Eurocard | DG640 | ? | ? | $0..$7FF | ? | matbug_monitor_for_eurocard_system_notes.pdf |
![]() | 300 | DG640 | ? | 1? | $0..$7FF | ? | - |
![]() | 300 | 300 | 300 | ? | $0..$7FF | 1981 | ETI-685 |
![]() | parallel | DG640 | 300 | ? | $0..$7FF | 1981 | ETI-685 |
![]() | 300 | DG640 | ? | 1? | $0..$7FF | ? | - |
![]() | - | - | Control & data I/O ports | 1? | $6000..$63FF | ? | - |
![]() | - | - | Extended I/O ports? | 1? | $6000..$63FF | ? | - |
![]() | - | - | Extended I/O ports | 1 | $6000..$63FF | 1982 | sbcos_manual.pdf |
![]() | - | - | - | 1? | $6800..$6FFF | 1981 | vhs_dos_v26a_source_listing.pdf |
![]() | - | - | - | 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 | 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
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.
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 logic in the game for showing odds, taking bets, ascertaining winners, paying winners, etc.
Dice with Display:
The rightmost parallel I/O switch (bit 0) needs to be on, otherwise
the 7-segment LED digit area of the display will never change.
The program relies on random data in uninitialized RAM for its random
number generation, hence you should ensure that "Settings|Emulator|
Randomize memory?" is on before loading the game.
Game of Memories:
This is a Game of Life according to the rules from John Horton Conway. It was written for the Ami/WinInstructor emulator.
The particularity of Game of Memories is that the field for the Game of Life is laid out in a 16*16 byte grid storage area that the emulator can graphically represent and so the view can be resembled - whereby the name of the program: Game of Memories.
When the progam is loaded into WinArcadia, the field is still not seen. "Tools|Memory editor..." must be invoked. The field is in the memory bank $0E00..$0EFF. You should set "Region" to that memory region, and "View as" to "Characters".
The original listing has an error in byte $125:
0124 F9 7C BDRR,r1 $122
which causes an infinite loop. It should instead be:
0124 F9 7E BDRR,r1 $124
The version in the Games Pack incorporates this fix.
Train:
Bits 6..4
Bits 3..0
%000: 0 mph (stopped)
%0000: oP...... HSE
%001: 80 mph
%0001: oPOOO... HSE + 3 FC
%010: 40 mph
%0010: oPOUU... HSE + 1 FC + 2 EC
%011: 27 mph
%0011: oPOUAo.. HSE + 1 FC + 1 EC + 1 HC + 1 C
%100: 19 mph
%0100: oPOOo... HSE + 2 FC + 1 C
%101: 15 mph
%0101: oPooo... HSE + 3 C
%110: 12 mph
%0110: oPUUUo.. HSE + 3 EC + 1 C
%111: 10 mph
%0111: o=ooo... LSE + 3 C
-
%1000: o=UUo... LSE + 2 EC + 1 C
-
%1001: o=AAo... LSE + 2 HC + 1 C
-
%1010: o=UUo... LSE + 2 EC + 1 C
-
%1011: o=OOOo.. LSE + 3 FC + 1 C
-
%1100: o=...... LSE
-
%1101: M....... MT
-
%1110: doooo... EM + 4 C
-
%1111: Mooo.... MT + 3 C
Train components are:
Abbreviation | Display | Description |
EM | d | electric-powered mine engine |
MT | M | battery-powered mine tractor |
HSE | oP | high speed engine |
LSE | o= | low speed engine |
FC | O | full car |
HC | A | half-full car |
EC | U | empty car |
C | o | caboose |
Signetics TWIN
Region | Size | Master CPU | Slave CPU |
$0000..$00FF | 256 bytes | bootstrap ROM (to boot SDOS from disk) | slave RAM |
$0100..$14FF | 5K | master RAM (for SDOS) | slave RAM |
$1500..$187F | 896 bytes | master RAM (overlay area 1) | slave RAM |
$1880..$1BFF | 896 bytes | master RAM (overlay area 2) | slave RAM |
$1C00..$3FFD | 9214 bytes | master RAM | slave RAM |
$3FFE..$3FFF | 2 bytes | DOS version number (except for very early versions) | slave RAM |
$4000..$7FFF | 16K | window into (ie. mirror of) slave RAM | unexpanded system: unmapped
expanded system: slave RAM |
The resident (non-overlay) part of SDOS contains:
job dispatcher
SVC processor
device handlers
GO, LOAD, SYSTEM, XEQ commands
TWIN stands for Test Ware Instrument.
The master CPU runs DOS and handles all I/O (keyboard, CRT, floppies, etc.). The slave CPU merely runs programs in its own memory, and asks the master to perform I/O for it via service requests (and, of course, can access prototype hardware, depending on which mode is in use). To switch from master to slave, the master just executes a HALT instruction. To switch from slave to master, any master interrupt (but not slave interrupt) can be used. Eg. timer/keyboard/etc. interrupts and Service Requests. The master CPU has 16 interrupt priority levels. Master CPU interrupt handlers start at $0000 of master RAM and go up by 2 per entry. The slave CPU has 8 interrupt priority levels. Slave CPU interrupt handlers start at $0000 of slave RAM and go up by 2 per entry. Interrupt priorities 1 and 3 are used for master and slave RAM parity errors, respectively. Lower priority numbers represent "higher" (more important) priorities.
Note that, in MOD headers, the destination base address specified by the Set Base command start is always as viewed from the master CPU, even when loading into slave RAM (as the loading as always done by the master CPU).
Errata: On page 1-17 of the Tektronix 8002A Service Manual, ITD should be OTD. Thus, to read a sector the steps are:
1. Go RST mode. Check disk status.
2. Go SIO mode. Check disk status.
3. Go OTD mode. Send Normal Read command.
4. Go OTD mode. Send drive number.
5. Go OTD mode. Send sector number.
6. Go OTD mode. Send track number.
7. Go IND mode. Read 1st byte.
: : :
134. Go IND mode. Read 128th byte.
135. Go RST mode. Check disk status.
SDOS supports these formats:
"Hex" - Appendix C (AOF)
"SMS" - Appendix D (for PROM programmer)
"MOD" - "Binary load module"
"Com" - "Command file" (ie. batch/script file)
Here are the contents of the various "DOS areas" aka "bootblocks" (tracks 1..4) of the disks:
DOS (tracks 1..4) | Disk(s) |
DIP4 | diag_4.4_5-23-79 |
EXOS | HM19..22 |
PMON (expects 8080 slave) | pascal_I.4b |
CP/M | 0517-0135-01_8002_cpm_adm3_pe_ws_palasm |
CP/M | 0517-0136..0142-01 |
CP/M | 8002_cpm_ws_hk |
CP/M | 88000141_8088_thor_of_ops |
CP/M | arb_mgr_work_disk |
CP/M | asm09src_cpm |
CP/M | cpm_on_tek_ws_utilities |
CP/M | cpm_trace_theory_of_ops |
CP/M | cpm_whitesmiths_c |
CP/M | debug_card_programmable_parts_2-3-81 |
CP/M | tek_cpm_prom_document_format |
CP/M | wordstar_perkin-elmer_terminal |
SDOS 2.0 | van_erp |
SDOS 2.0 | HM02..04 |
SDOS 2.0 | HM06..07 |
SDOS 2.0 | HM13..14 |
SDOS 2.0 | HM16..18 |
SDOS 2.0 | HM23..25 |
SDOS 4.0 | HM01 |
SDOS 4.0 | HM10 |
SDOS 4.2 | config42 |
SDOS 4.2 | HM05 |
SDOS 4.2 | HM15 |
SDOS 4.2 | system42 |
SDOS 4.2 | tss40 |
TEKDOS 2650 VER 1.6 REV A (aka UDOS) | tekdos_v1.6_2650 |
TEKDOS 6500 3.1 | tekdos_3.1_6500_copy |
TEKDOS 6800 1.9 | tekdos_1.9_bkup_8-79 |
TEKDOS 6800 1.9 | 99900761-01-A_tekdos_1.9 |
TEKDOS 6800 3.1 | 99900809-01_9508 |
TEKDOS 6800 3.1 | 99900817-01_9508_9508_link_cpy2 |
TEKDOS 6800 3.1 | 99900818-01_9508_executive_copy2 |
TEKDOS 6800 3.1 | 99900819-01_9508_io_module_copy2 |
TEKDOS 6800 3.1 | 99900820-01_9508_system_subroutines_cpy2 |
TEKDOS 6800 3.1 | 99900821-01_9508_emulator_ctl_cpy2 |
TEKDOS 6800 3.1 | 99900822-01_9508_cmd_line_proc_cpy2 |
TEKDOS 6800 3.1 | 99900823-01_9508_9508_real_time_analyzer_cpy2 |
TEKDOS 6800 3.1 | 99900824-01_9508_memory_cpy2 |
TEKDOS 6800 3.1 | 99900825-01_9508_comm_cpy2 |
TEKDOS 6800 3.1 | 99900924-01_9508_executable_modules_cpy2 |
TEKDOS 6800 3.1 | Tek8002_1a |
TEKDOS 6800 3.1 | Tek8002_2 |
TEKDOS 6800 3.3 | TekDOS_3.3_6800_cpy1..2 |
TEKDOS 6801 3.1 | 6801_tekdos_v3.1_f001 |
TEKDOS 680X 3.2 | Tek8002_12..14 |
TEKDOS 8048 3.1 | chuck_tekdos_ice |
TEKDOS 8080 3.0 | Tek8002_3 |
TEKDOS 8080 3.1 | Tek8002_4 |
TEKDOS 8080 3.1 | Tek8002_6a |
TEKDOS 8080 3.1 | Tek8002_11 |
TEKDOS 8085 3.1 | Tek8002_5 |
TEKDOS 8085 3.1 | Tek8002_7a |
TEKDOS Z80 2.2 | 99900862-01 |
TEKDOS Z80 2.2 | 99901253-01_9516_boot_listing |
TEKDOS Z80 2.2 | 99901254-01_9516_boot_src_obj |
TEKDOS Z80 2.2 | 99902585-01 |
TEKDOS Z80 3.1 | 0517-0143..0147-01 |
TEKDOS Z80 3.1 | 8048_v3.1_9-6-79 |
TEKDOS Z80 3.1 | 8086_fpgas |
TEKDOS Z80 3.1 | 9516_debug_diagnostic_with_diagnostic_emulator |
TEKDOS Z80 3.1 | ed_lenox_z80_3.3 |
TEKDOS Z80 3.1 | editor_for_slave_adapter_d0 |
TEKDOS Z80 3.1 | hal_gillette_z80_v3.1_system |
TEKDOS Z80 3.1 | master_cmd_files_for_slave_adapter |
TEKDOS Z80 3.1 | master_cmd_files_for_slave_adapter_run_disk_0 |
TEKDOS Z80 3.1 | progfpga_slave_adapter_ed_lennox_0 |
TEKDOS Z80 3.1 | slave_adapter_drive_1_programmable_parts_hist |
TEKDOS Z80 3.1 | supervsrctl |
TEKDOS Z80 3.1 | Tek8002_8 |
TEKDOS Z80 3.1 | Tek8002_10 |
TEKDOS Z80 3.1 | Tek8002_17b |
TEKDOS Z80 3.1 | Tek8002_21 |
TEKDOS Z80 3.1 | tekdosz80v3.1slaveadaptersupervisorrun |
TEKDOS Z80 3.1 | test_files_for_8086 |
TEKDOS Z80 3.1 | z80_3.1_debug_checkout_8086_vehicle |
TEKDOS Z80 3.2 | Tek8002_16 |
TEKTIP 1.5 | tektip_1.5 |
TOS 1.0 | TWINBoot |
"EMPTY" (all zeroes) | Tek8002_15 |
"EMPTY" (all zeroes) | Tek8002_23b |
"SDOS" (all zeroes) | cmd_src_5b |
"SDOS" (all zeroes) | HM08..09 |
"SDOS" (all zeroes) | HM11..HM12 |
"SDOS" (all zeroes) | margriet1 |
"SDOS" (all zeroes) | sdos42_link |
"SDOS" (all zeroes) | TWINData |
"TEKDOS" (all zeroes) | 99900827-01_hazel_6809_cpy2 |
"TEKDOS" (all zeroes) | 99900828-01_hazel_8080-85_cpy2 |
"TEKDOS" (all zeroes) | 99900829-01_hazel_6800_cpy2 |
"TEKDOS" (all zeroes) | 99900831-01_hazel_8048_cpy2 |
"TEKDOS" (all zeroes) | cpm-wordstar_ed_lennox |
"TEKDOS" (all zeroes) | files |
"TEKDOS" (all zeroes) | supv_edit_disk_slave_adapter_drive_1 |
"TEKDOS" (all zeroes) | supvhis2 |
"TEKDOS" (all zeroes) | supvhis3 |
"TEKDOS" (all zeroes) | Tek8002_1b |
"TEKDOS" (all zeroes) | Tek8002_17a |
"TEKDOS" (all zeroes) | Tek8002_22 |
"TEKDOS" (all zeroes) | Tek8002_25 |
Other file(s) | 99900826-01_h2lasm_cpy2 |
Other file(s) | 99900830-01_hazel_z80_cpy2 |
Other file(s) | 99900878-01_com-ram-05_part1_v1.0_cpy2 |
Other file(s) | 99900884-01_com-ram-05_part2_v1.0_cpy2 |
Other file(s) | 99900889-01_com-ram-05_part3_v1.0_cpy2 |
Other file(s) | 99901441-01 |
Other file(s) | sdos42_cmd_src_1..5 |
Other file(s) | Tek8002_9 |
Other file(s) | Tek8002_18..20 |
Other file(s) | Tek8002_23a |
Other file(s) | Tek8002_24a |
Other file(s) | Tek8002_24b |
Other file(s) | Tek8002_26 |
Other file(s) | pas_src |
Other file(s) | prom_mod9 |
Other file(s) | rasm |
Other file(s) | sdos42_hwa |
Other file(s) | sdos42_macro_src |
Other file(s) | sdos42_opt_drv |
Other file(s) | sdos42_res_link |
Other file(s) | sdos42_res_master |
Other file(s) | sdos42_util |
Corrupt/missing | word_star_work_disk.img |
word_star_work_disk.img is only 311,296 bytes (missing the first track?).
TOS 1.0 asks for the current date and time on boot. If those are
entered, the timer is enabled.
TEKDOS (apart from UDOS) switches to the slave CPU. Slave memory is all zeroes (why!?) so we just run endlessly through the first 8K page of slave memory. Changing the HALT at $1DC1 of master memory to NOP is sufficient to get TEKDOS working.
TEKTIP 1.5 doesn't like to get interrupts 4 and 5 (teletype I/O).
DOS command filename and return code cross-reference (with no arguments supplied):
Command | EXOS | TOS | SDOS 2.0 | UDOS | SDOS 4.0 | SDOS 4.2 | ||||||
Filename(s) | Return code | Filename(s) | Return code | Filename(s) | Return code | Filename(s) | Return code | Filename(s) | Return code | Filename(s) | Return code | |
Abort | P, (O) | Yes | E | ABT 31 | P, (N) | ABT 31 | M, (O) | ABT 31 | L, (K) | ABT 31 | M, (L1) | ABT 31 |
ASM | - | ASM 3 | Z, 8, 7 | No | U, T, S, Z, 5, 4, 3 | No | Z, Y, SZ, Z | No | Y, Z, 2, 1, 0, Z | No | Z, 6, 5, Z | No |
ASsign | D, (C) | ASsign 31 | 3, (R) | ASN 31 | E | ASN 31 | E | ASN 31 | E | ASN 31 | 8 | ASN 31 |
CLose | D, (C) | CLose 31 | 3, (R) | CLS 31 | E | CLS 31 | E | CLS 31 | E | CLS 31 | 8 | CLS 31 |
Cont | P, (O) | Yes | E | CON 31 | P, (N) | CON 31 | M, (O) | CON 31 | L, (K) | CON 31 | M, (L1) | CON 31 |
CMpf | - | CMpf 3 | - | TOS 3 | - | DOS 3 | P1, Z | CMP 31 | M1, M, (L1) | CMP 31 | D, E | CMP 31 |
COPy | B, (A) | COPy 16 | G | COP 13 | E | COP 30 | E | COP 30 | E | COP 30 | 2, (1) | COP 16 |
CProm | - | CProm 3 | S, (W) | PRM EOJ | K, (J) | Yes | I, X, (W) | PRM 62 | P1, P, (O) | Yes | Q1, Q, (P1) | Yes |
CSms | - | CSms 3 | - | TOS 3 | E, (R) | SMS 6 | E, (P) | SMS 6 | E, (M1) | SMS 6 | N, (M1) | SMS 6 |
DEBug | A, 7, @ | Yes | N, M, (O) | Yes | E, 1, (Z) | Yes | E, (D) | No | E, Z, (8) | Yes | I, C, (4) | Yes |
DELete | C, (B) | DELete EOJ | 4, (3) | DEL 31 | E | DEL 31 | E | DEL 31 | E | DEL 31 | 8 | DEL 31 |
DEv
DEVice | Q, (P) | DEv 31
(as DEv) | W, (E) | DEV 31
(as DEVice) | R, (P) | DEV 31
(as DEVice) | N, (M) | DEV 31
(as DEVice) | L1, (L) | DEV 31
(as DEVice) | M1, (M) | DEV 31
(as DEVice) |
DFil | - | DFil 3 | - | TOS 3 | - | DOS 3 | - | DOS 3 | O, N1, (N) | DFL 31 | P1, P, (O) | DFL 31 |
Dump | 4, (3) | Dump 31 | H, (G) | DMP 31 | Z | DMP 31 | 4, (3) | DMP 31 | Z | DMP 31 | 1, (D) | DMP 31 |
DUP | R, (Q) | DUP 9 | T, (S) | DUP 9 | Z, (W) | DUP 9 | T, (S) | DUP 9 | V, (U) | DUP 9 | T1, (T) | DUP 9 |
EDIT | 9, G, F, E | No | E, K, 8 | No | D, C, B, A, H, G, F, E | No | D, C, B, A, H, G, F, E | Yes | D, C, B, A, H, G, F, E | No | E, I1, Y | No |
Ex
Exam | 7 | Ex 31
(as Ex) | H, (G) | EXM 31
(as Exam) | 2, (1) | EXM 31
(as Exam) | COPYSYS, (BOOT) | EXM 31
(as Exam) | Z | EXM 31
(as Exam) | 0, (C) | EXM 31
(as Exam) |
Fill | - | Fill 3 | - | TOS 3 | - | DOS 3 | P, (N) | FIL 31 | 71, (7) | FIL 31 | Z | FIL 31 |
FORMAT | E | FORMAT 9 | V, (F) | FMT 9 | E | FMT 9 | E | FMT 8 | E | FMT 8 | 8 | FMT 9 |
Go | - | Go 31 | - | TOS 31 | - | No | - | DOS 37 | - | DOS 37 | - | DOS 37 |
Ice | - | Ice 3 | - | TOS 3 | - | DOS 3 | - | DOS 3 | Q, (P1) | ICE EOJ | R, (Q1) | ICE EOJ |
Kill | Q, (P) | Kill 31 | W, (E) | KIL 31 | R, (P) | KIL 31 | N, (M) | KIL 31 | L1, (L) | KIL 31 | M1, (M) | KIL 31 |
LDir
Ldir | O, L | Yes
(as LDir) | R, 6 | Yes
(as LDir) | N, M | Yes
(as Ldir) | O, L | Yes
(as Ldir) | K, J | Yes
(as Ldir) | L1, L | Yes
(as LDir) |
LOad | - | LOad 49 | - | ONA 49 | - | DOS 49 | - | DOS 49 | - | DOS 49 | DOS 49 | |
Module | N, M, (L) | Module 34 | 2, D, (N) | MOD 12 | O, L, (K) | MOD 12 | K, J, (I) | MOD 12 | I1, I, (R) | MOD 12 | K, J, (H) | MOD 12 |
MOVe | - | MOVe 3 | - | TOS 3 | - | DOS 3 | P, (N) | MOV 31 | 8 | MOV 31 | #B, (#) | MOV 31 |
Patch | - | Patch 3 | - | TOS 3 | Z | PAT 31 | 4, (3) | PAT 31 | 71, (7) | PAT 31 | Z | PAT 31 |
E, (Q) | PRint 30 | C, (1) | PRN 30 | E | PRN 30 | E | PRN 30 | E | PRN 30 | 8, (N) | PRN 30 | |
PRINTL | E, (Q) | PRINTL 30 | C, (1) | PRN 30 | E | PRN 30 | E | PRN 30 | E | PRN 30 | 8, (N) | PRN 30 |
PROm | - | PROm 3 | - | TOS 3 | - | DOS 3 | - | DOS 3 | 8 | PRM 52 | !, (9) | PRM 52 |
REad | - | REad 3 | - | TOS 3 | - | DOS 3 | - | DOS 3 | X, (W) | RDW 31 | N1, W, (V) | RDW 31 |
REName | C, (B) | REName 8 | 4, (3) | REN 31 | E | REN 31 | E | REN 31 | E | REN 31 | 8 | REN 31 |
Rhex | - | Rhex 3 | L, (J) | No | J, (Z) | No | W, (V) | No | N, (X) | No | O, (N1) | No |
RProm | K, (J) | RProm EOJ | S, (W) | PRM EOJ | K, (J) | PRM EOJ | I, X, (W) | PRM 62 | P1, P, (O) | PRM EOJ | Q1, Q, (P1) | PRM EOJ |
SEArch | Q, (P) | SEArch 31 | W, (E) | SCH 31 | R, (P) | SCH 31 | - | DOS 3 | - | DOS 3 | - | DOS 3 |
SLave | T, (S) | SLave 31 | P, (U) | SLV 31 | Z | SLV 31 | V, (U) | SLV EOJ | - | DOS 3 | - | DOS 3 |
STatus | S, (R) | Yes | U, (V) | Yes | Z | Yes | U, (T) | Yes | W, (V) | Yes | V, U, T1 | Yes |
Sus
Suspend | P, (O) | Yes
(as Sus) | E | SUS 31
(as Suspend) | P, (N) | SUS 31
(as Suspend) | M, (O) | SUS 31
(as Suspend) | L, (K) | SUS 31
(as Suspend) | M, (L1) | SUS 31
(as Suspend) |
SYstem | - | Yes | - | Yes | - | Yes | - | DOS 9 | - | Yes | - | Yes |
TYpe | Q, (P) | TYpe 31 | W, (E) | TYP 31 | R, (P) | TYP 31 | N, (M) | TYP 31 | L1, (L) | TYP 31 | M1, (M) | TYP 31 |
Upr | - | Upr 3 | - | TOS 3 | - | DOS 3 | - | DOS 3 | E | UPR EOJ | 8 | UPR EOJ |
Verify | Q | Verify 31 | F, (T) | TOS 48 | W, (V) | VER 31 | S, (R) | VER 31 | U, (T) | VER 31 | T, (S1) | VER 31 |
WHex | - | WHex 3 | J, (P) | WHX 30 | V, (U) | WHX 30 | R, (P1) | WHX 30 | T, (S1) | WHX 30 | S1, (X) | WHX 30 |
WProm | K, (J) | WProm EOJ | S, (W) | PRM EOJ | K, (J) | PRM EOJ | I, X, (W) | Yes | P1, P, (O) | Yes | Q1, Q, (P1) | Yes |
WRite | - | WRite 3 | - | TOS 3 | - | DOS 3 | - | DOS 3 | X, (W) | RDW 31 | N1, W, (V) | RDW 31 |
WSms | - | WSms 3 | - | TOS 3 | E, (R) | Yes | E, (P) | Yes | E, (M1) | Yes | N, (M1) | Yes |
Xeq
XEQ | - | Xeq 49
(as Xeq) | - | ONA 49
(as Xeq) | - | DOS 49
(as XEQ) | - | DOS 49
(as XEQ) | - | DOS 49
(as XEQ) | - | DOS 49
(as XEQ) |
Most of these filenames are stored on disk with a prepended "@" (and are displayed by "LDIR ." with a prepended ".").
Parenthesized filenames mean the head is over that file at the end of the operation but it is not read from.
Return codes are:
3 | Command file not found. |
6 | Device read error. |
8 | Device not specified when required. |
9 | Invalid drive number. |
12 | Invalid file name. |
13 | Input file not found. |
16 | Input device assign failure. |
30 | Invalid parameter. |
31 | Parameter required. |
34 | Invalid address. |
37 | Invalid go address. |
48 | Load file not found. |
49 | Load file assign failure. |
62 | Device not operational. |
EOJ | End of Job. |
I/O Ports
For reads:
Port | Description |
$E8 | Data Byte |
$E9 | Status Byte:
bits 7..5: unused bit 4: parity error bit 3: framing error bit 2: data overrun bit 1: transmit buffer empty bit 0: data available |
$EA | "Controller Flag Byte" |
$EB | "Disk Status Byte" |
For writes:
Port | Name | Description |
$D0 | PCPT | High Speed Paper Tape (HSPT) control port |
$D1 | PDPT | PDPT High Speed Paper Tape (HSPT) data port |
$E8 | ? | CRT/TTY output |
$E9 | ? | Bits 7..3: unused
Bit 2: enable TTY interrupts Bit 1: parity select Bit 0: TTY paper tape reader |
$EA | ? | Control Device (floppy drive and printer) |
$EB | ? | Data Device (floppy drive and printer) |
$EC | ? | Bits 7..1: ?
Bit 0: interval timer (0=disabled, 1=enabled) |
$ED | ? | "Master Memory Protect" |
$EE | BSPT | Common memory bank select:
$00 = map slave RAM $0000..$3FFF to master RAM $4000..$7FFF $01 = map slave RAM $4000..$7FFF to master RAM $4000..$7FFF $02 = map slave RAM $8000..$BFFF to master RAM $4000..$7FFF $03 = map slave RAM $C000..$FFFF to master RAM $4000..$7FFF |
Central Data 2650
"Product: 2650 Single Board Computer
Company: Central Data Company
Features: Employs Signetics 2650 microprocessor.
There is an in-built 80 character by 16 line video display character
generator (64 upper case ASCII character set) with a user programmable
set of 64 characters (8x8 matrix) for non-standard characters.
There is a Kansas City Standard cassette interface, a 1024 byte PROM
monitor program, 2048 bytes of programmable memory of which 768 are
available for programming with the balance dedicated to the display,
one 8 bit input port and one 8 bit output port.
In addition there are sockets for 3K of PROM (which may include the
Central Data Company's editor and assembler).
A BASIC software package is available on cassette tape.
The user needs to supply 3A at 5V power supply, an ASCII keyboard, a
video monitor and possibly some additional memory."
- "Small Systems Computer Sourcebook" [sic], by J. C. Boonham.
A typical configuration is:
Central Data 2650 computer (including CUTS cassette interface)
ASCII-encoded keyboard
video monitor
tape deck
power supply
Region | Size | Description |
$0000..$03FF | 1K | monitor ("supervisor") ROM BIOS |
$0400..$0FFF | 3K | expansion ROM (optional) |
$1000..$103F | 64 bytes | display RAM (unusable) |
$1040..$14FF | 1216 bytes | display RAM |
$1500..$150F | 16 bytes | monitor RAM (unusable) |
$1510..$17E9 | 730 bytes | user RAM |
$17EA..$17FF | 26 bytes | monitor RAM |
$1800..$1FFF | 2K | unused |
$2000..$7FFF | 24K | expansion RAM/ROM (optional) |
$1000..$103F: "In the first CD2650 Newsletter, April 1978, Jeff Roloff
says: '...if you get hold of some slow RAM for use in the display section,
the first four characters will be illegible because of timing problems.'
If the RAM was fast enough for the rest of the display it would be fast
enough at the beginning. I suspect that he had problems with resetting his
counters which made the first character spaces too narrow. I remember
designing a frequency synthesiser with 74 series ICs where the downcounter
had to start resetting at count 3 to be ready at count 0!" - Richard
Rogers.
$1500..$150F: "You can't use $1500..$150F because when you reach the end
of the line, WCHR at $0396 sends you to LFCR at $0024 which immediately
writes a space at the current (too big) cursor position." - Richard
Rogers.
The layout of display RAM is unusual:
$1000: 0,0
$1001: 0,1
$1002: 0,2
: : :
$100F: 0,15
$1010: 1,0
$1011: 1,1...
To access a given cell, the formula is:
address = $1000 + (x * 16) + y;
where x is 0..79 and y is 0..15.
Characters $00..$3F use the 1st character generator PROM. They are the uppercase alphabetic characters, numeric characters and punctuation characters.
Characters $40..$7F use the optional 2nd character generator PROM, if available (otherwise
just another copy of $00..$3F). These are generally used for eg. lower case characters, Star Trek characters, card symbols and chessmen.
Characters $80..$FF are not normally used.
The character sets are:
Code | Non-chessmen ("lowercase") | Chessmen | ASCII | |||||||||||||||||||||||||||||||||||||||||||||
$0 | $1 | $2 | $3 | $4 | $5 | $6 | $7 | $8 | $9 | $A | $B | $C | $D | $E | $F | $0 | $1 | $2 | $3 | $4 | $5 | $6 | $7 | $8 | $9 | $A | $B | $C | $D | $E | $F | $0 | $1 | $2 | $3 | $4 | $5 | $6 | $7 | $8 | $9 | $A | $B | $C | $D | $E | $F | |
$0x | @ | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | @ | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | @ | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O |
$1x | P | Q | R | S | T | U | V | W | X | Y | Z | [ | · | ] | ↑ | ← | P | Q | R | S | T | U | V | W | X | Y | Z | [ | · | ] | ↑ | ← | P | Q | R | S | T | U | V | W | X | Y | Z | [ | · | ] | ↑ | ← |
$2x | ! | " | # | $ | % | & | ' | ( | ) | * | + | , | - | . | / | ! | " | # | $ | % | & | ' | ( | ) | * | + | , | - | . | / | ! | " | # | $ | % | & | ' | ( | ) | * | + | , | - | . | / | |||
$3x | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | : | ; | < | = | > | ? | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | : | ; | < | = | > | ? | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | : | ; | < | = | > | ? |
$4x | ` | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | ♔ | ♕ | ♗ | ♖ | ♘ | ♙ | ♚ | ♛ | ♝ | ♜ | ♞ | ♟ | ■ | ◫ | ▣ | □ | @ | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O |
$5x | p | q | r | s | t | u | v | w | x | y | z | { | | | } | ~ | ■ | p | q | r | s | t | u | v | w | x | y | z | { | | | } | ~ | ■ | P | Q | R | S | T | U | V | W | X | Y | Z | [ | · | ] | ↑ | ← |
$6x | ! | " | # | $ | % | & | ' | ( | ) | * | + | , | - | . | / | - | ! | " | # | $ | % | & | ' | ( | ) | * | + | , | - | . | / | - | ` | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o |
$7x | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | : | ; | < | = | > | ? | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | : | ; | < | = | > | ? | p | q | r | s | t | u | v | w | x | y | z | { | | | } | ~ | ■ |
Red is non-chessmen ("lowercase") character set.
Green is chessmen character set.
Character $4D (shown here as ◫) is actually a square with a horizontal (not vertical) bisecting line. Unicode sux :-(
Blue (ASCII) is used for Central Data DOS and P1 DOS.
Characters shown here in dark blue are control codes which will be displayed as inverse video.
In the real character PROMs, the character glyphs are stored in this order:
1st PROM:
glyphs $00, $20, $10, $30, $08, $28, $18, $38, (bytes $000..$03F of PROM)
glyphs $01, $21, $11, $31, $09, $29, $19, $39, (bytes $040..$07F of PROM)
glyphs $02, $22, $12, $32, $0A, $2A, $1A, $3A, (bytes $080..$0BF of PROM)
glyphs $03, $23, $13, $33, $0B, $2B, $1B, $3B, (bytes $0C0..$0FF of PROM)
glyphs $04, $24, $14, $34, $0C, $2C, $1C, $3C, (bytes $100..$17F of PROM)
glyphs $05, $25, $15, $35, $0D, $2D, $1D, $3D, (bytes $140..$17F of PROM)
glyphs $06, $26, $16, $36, $0E, $2E, $1E, $3E, (bytes $180..$1BF of PROM)
glyphs $07, $27, $17, $37, $0F, $2F, $1F, $3F. (bytes $1C0..$1FF of PROM)
2nd PROM:
glyphs $40, $60, $50, $70, $48, $68, $58, $78, (bytes $000..$03F of PROM)
glyphs $41, $61, $51, $71, $49, $69, $59, $79, (bytes $040..$07F of PROM)
glyphs $42, $62, $52, $72, $4A, $6A, $5A, $7A, (bytes $080..$0BF of PROM)
glyphs $43, $63, $53, $73, $4B, $6B, $5B, $7B, (bytes $0C0..$0FF of PROM)
glyphs $44, $64, $54, $74, $4C, $6C, $5C, $7C, (bytes $100..$13F of PROM)
glyphs $45, $65, $55, $75, $4D, $6D, $5D, $7D, (bytes $140..$17F of PROM)
glyphs $46, $66, $56, $76, $4E, $6E, $5E, $7E, (bytes $180..$1BF of PROM)
glyphs $47, $67, $57, $77, $4F, $6F, $5F, $7F. (bytes $1C0..$1FF of PROM)
Supervisor BIOS
A period (.) indicates that the supervisor program is ready for a command.
An A indicates that it is waiting for you to type in an address.
At any time the supervisor is looking for a keyboard input, you can press Esc
which will terminate the present command and wait for a new one.
A: Alter or display memory
Press A.
It will then ask for a hexadecimal address.
The address and the data then appear on the next line.
You can now:
press Esc to quit the alter/display routine;
enter C to change the data at that location;
type in two hex characters to fill the memory location; or
press space to display the next memory location.
B: Set a breakpoint address
Press B.
It will then ask you for the address of the breakpoint.
When this address is reached in the program, the supervisor will save
all of the registers and wait for a new command. It signifies that the
breakpoint address has been reached by writing the message:
BP 1703
The registers and memory can now be examined as you see fit. After the breakpoint has been executed, it is cleared and the program will be allowed to run past the point next time through.
C: Clear a breakpoint address
Press C.
The supervisor responds by typing the address that the breakpoint was
set at. Note that you must set breakpoints at an address position where
an instruction would begin. In other words, you cannot set a breakpoint
to be executed at an address which is the second or third byte of an
instruction.
E: Execute a program
Press E.
It will then ask for the address that is should start executing at.
It will then jump to the address and start executing instructions.
I: Inspect CPU registers
Press I.
It will then ask you to type a register number corresponding to the
register that you want, as follows:
0 register 0 (r0)
1 register 1, bank 0 (r1)
2 register 2, bank 0 (r2)
3 register 3, bank 0 (r3)
4 register 1, bank 1 (r4)
5 register 2, bank 1 (r5)
6 register 3, bank 1 (r6)
7 Program Status Word, Lower (PSL)
8 Program Status Word, Upper (PSU)
The microcomputer will then display the data that was in this register
just before the program returned to the supervisor. You now have three
options:
to stop by pressing Esc;
to change the register value by entering C; or
to inspect another register by pressing Space.
There are also the D, L, R and V commands, which are used for tape
operations.
It seems to be possible to "hang" the supervisor; eg. by pressing E
repeatedly. This is because RETN ($288) branches to *ADD1, and sometimes
ADD1 has garbage such as $6EEE.
The available scan of the supervisor is poor; the following bytes could conceivably be wrong:
$13A, $16C, $181: probably $EB but maybe $E8
$316: probably $F8 but maybe $FB
$3C4: probably $2E but maybe $28 or $2B
The following unnamed variables are used by the supervisor:
$17EB..$17F3
$17F8
$17FC
$17FD?
The WCHR routine masks its character to the $00..$3F range (ie. it
prints everything as uppercase).
The KBIN routine can return characters in the $00..$7F range. However,
it can only print them as uppercase (because it uses WCHR).
The supervisor internally works with letters in the $41..$5A (65..90)
(ASCII uppercase "A".."Z") range. It relies on the masking performed by
WCHR to output them as $01..$2A (1..26) (CD2650 uppercase "A".."Z").
Ideally, full autodocs for the supervisor (and for the BIOSes of the TVGC, PIPBUG and the SI50) would be available, eg.:
WRAD:
Stack required: 2.
Functions called: LFCR, HXOT, WRBL.
Pages: 3.
Addresses: $DB..$EF.
Can branch to: None.
RAM data accessed: ADD1/2.
ROM data accessed: None.
ROM constants used: INCD ($10), CUCD ($1C), SPCD ($20).
Subsections: L2.
Called by: ?.
Registers: r0 will be SPCD ($20), r3 will be CUCD ($1C).
PSW: WC is cleared.
Unarchived Software
The following are confirmed but unavailable:
Spacewar (clone of "Scelbi's Galaxy Game for the 8008/8080"), by Roger Miskowicz
Star Trek
Target
If you know of any other software, or have dumps/tapes/listings of any of
the above software, please
email
us.
Game Help
8KBASIC.pgm:
To start a game: press R then ENTER.
Now, from the "OPTION" prompt, press R.
In editor (at COMMAND prompt):
- = go to beginning of file
+ = go to end of file
/ = go backwards 15 lines
Bx = go backwards x lines
space = go forwards 15 lines
Fx = go forwards x lines
Cx = change line x
Ix = insert after line x
Ctrl+C = done changing/inserting
Dx = delete x lines from top of screen
R = go to BASIC
In BASIC (at OPTION prompt):
I = Inspect variable
L = RUN to line
R = RUN
Esc = stop running
S = Single step
Esc = go to editor
Standard BASIC | 8K BASIC |
CLS | ERASE |
var=PEEK(addr) | PEEK addr,var |
PRINT"string" | PRINT'string' |
PRINT var | PRINT #var |
PRINT AT y,x | PRINT@y,x |
'comment | *comment |
IF a=b THEN | IF a=b |
The interpreter doesn't like blank lines (gives ARG ERROR),
but an empty comment (* only) is acceptable.
String concatenation (eg. A$='FOO'+'BAR') is not allowed.
String assignments (eg. A$='FOO') must exactly fill the
allocated (DIMensioned) storage.
When running programs: for multi-variable INPUT statements, each entry
should be terminated with the RETURN key (not a comma).
A normal floating point variable is 8..22 bytes:
1 byte for type ($0x)
2 bytes for pointer to next variable
1..15 bytes for name
4 bytes for contents
A floating point array is 4+ bytes:
1 byte for type ($4x)
2 bytes for pointer to next variable
1..15 bytes for name
(0..255)*4 bytes for contents
A string is 5..274 bytes:
1 byte for type ($8x)
2 bytes for pointer to next variable
1..15 bytes for name
1 byte for length
0..255 bytes for contents
Here is a summary of the differences between V1.0 and V1.3 of 8K BASIC (all values in hex):
Range
V1.0
V1.3
1780..17AA
00s
<various>
25B9..25BB
70 F4 80
1F 3E 98
2C25..2C27
3F 34 0D
3F 3F EE
2E6F..2E74
EE 14 A5 9C 30 5A
CE 14 A5 C0 C0 C0 (unofficial)
33B9..33BC
1A 64 19 6F
9C 4F D1 C0
3995
04
03
3E88..3EAA
<various>
<various>
3F2F..3F31
3F 3C F5
1F 17 96
3F78..3F7A
1F 38 91
1F 17 82
3FD1..3FED
<none>
<various>
3FEE..3FF3
<none>
<various>
The handwritten annotations on the listing are generally transcriptions of the V1.3 changes.
Accurate PSL emulation (as provided by Ami/WinArcadia 33.91+) is needed
for the floating point subsystem to work correctly.
There is still one remaining problem to be investigated: using the ^
(power of) operator (eg. LET A=3^2) will cause a hang.
Bytes $3D90..$3D91 (in the COSine() function handler) are ambiguous (due
to a poor quality printout/photocopy). But logically they would be $06 $04 (LODI,r2 4).
Numbers are stored using 1 exponent byte and 3 mantissa bytes, as follows:
Bit 31 is the sign of the exponent (0=positive, 1=negative).
Positive exponents represent large positive or negative numbers.
Negative exponents represent small positive or negative numbers (-0.5..0.5).
Bits 30..24 are the exponent itself, ie. the position of the "decimal" (really binary) point,
ie. how many bits are needed to store the integer part of the number.
Very small numbers will have negative exponents (and will have leading zeroes in the fractional part).
Bit 23 is the sign of the mantissa (0=positive, 1=negative).
Bits 22..0 are the mantissa itself.
Positive numbers that have been properly normalized will have mantissa bytes of $400000..$7FFFFF.
Negative numbers that have been properly normalized will have mantissa bytes of $C00000..$FFFFFF.
Values of $0..$3FFFFF and $800000..$BFFFFF should never occur.
The integer part is obtained by right-shifting (halving) the mantissa, 23 - exponent times.
The fractional part is obtained by left-shifting (doubling) the mantissa, exponent times.
This represents the fractional part in units of 1/8,388,608.
So by dividing this value by 8,388,608 you would obtain the fractional part.
Exponent
Range
Int. digits
Int. zeroes
.
Frac. zeroes
Frac. digits
Example
-128
About 10^-38
0
0
.
128
23
0.000001 = $80 00 00 08
...
...
...
...
.
...
...
...
-3
1/16..1/8
0
0
.
3
23
0.0625 = $FD 40 00 00
-2
1/8..¼
0
0
.
2
23
0.125 = $FE 40 00 00
-1
¼..½
0
0
.
1
23
0.25 = $FF 40 00 00
0
½..1
0
0
.
0
23
0.5 = $00 40 00 00
+1
1..2
1
0
.
0
22
1.0 = $01 40 00 00
+2
2..4
2
0
.
0
21
2.0 = $02 40 00 00
+3
4..8
3
0
.
0
20
5.0 = $03 50 00 00
+4
8..16
4
0
.
0
19
10.0 = $04 50 00 00
+5
16..32
5
0
.
0
18
20.0 = $05 50 00 00
+6
32..64
6
0
.
0
17
50.0 = $06 64 00 00
+7
64..128
7
0
.
0
16
100.0 = $07 64 00 00
+8
128..256
8
0
.
0
15
200.0 = $08 64 00 00
+9
256..512
9
0
.
0
14
500.0 = $09 7D 00 00
+10
512..1K
10
0
.
0
13
1000.0 = $0A 7D 00 00
+11
1K..2K
11
0
.
0
12
+12
2K..4K
12
0
.
0
11
+13
4K..8K
13
0
.
0
10
+14
8K..16K
14
0
.
0
9
+15
16K..32K
15
0
.
0
8
+16
32K..64K
16
0
.
0
7
+17
64K..128K
17
0
.
0
6
+18
128K..256K
18
0
.
0
5
+19
256K..512K
19
0
.
0
4
+20
512K..1M
20
0
.
0
3
+21
1M..2M
21
0
.
0
2
+22
2M..4M
22
0
.
0
1
+23
4M..8M
23
0
.
0
0
+24
8M..16M
23
1
.
0
0
+25
16M..32M
23
2
.
0
0
...
...
...
...
.
...
...
...
+127
about 10^37
23
104
.
0
0
~10^37 = $7F 7F FF FF
Int. digits: number of meaningful digits at left of integer part.
Int. zeroes: number of trailing zeroes at right of integer part.
Frac. zeroes: number of leading zeroes at left of fractional part.
Frac. digits: number of meaningful digits at right of fractional part.
Ie. <integer digits><integer zeroes>.<fractional zeroes><fractional digits>
Eg. for an exponent of -2, the number is %0.00xxxxxxxxxxxxxxxxxxxxxxx (where x are mantissa digits).
At +24 and greater exponents, there are not enough mantissa digits to even hold the complete integer number
(let alone any fractions).
12KBASIC-A.aof, 12KBASIC-B.aof:
It obeys one-letter commands of the form Xn, where X tells it what to do and n is the line number (or number of lines?).
S - save to tape (pauses during save)
L - load from tape
R - runs the BASIC program
Cn - change from line n onwards
D - deletes line 1
Dn - deletes lines from 1 to n
E - exits to supervisor
An - append after line n. If you have just inserted some lines, it will add them again after the designated line
F - scrolls forwards 1 line
Fn - scrolls forwards n lines
I - insert after line 1 - type in program, Ctrl-C (=ETX) ends input
In - insert after line n - type in program, Ctrl-C (=ETX) ends input
Bn - scrolls backwards n lines
X - scrolls forwards 1 line
Xn - ?
P - modify string?
G - go and run program with following options:
D - direct execution of a typed-in line
R - run the program
S - single step
Esc - exits
It only needs line numbers as GOTO (and GOSUB, etc.) destinations.
At $5800 there is a small test program. It looks as if whoever saved the
program first ran it with the extended functions deleted and wrote a small
program before saving. So some of the extended functions may be corrupted
or they may all be missing.
When an error is encountered: these OPTIONs are available:
D - direct mode
R - rerun the program
S - single step
Esc - exits
12KBASIC-A.aof was probably typed in by me from the listing. Need to compare with 12KBASIC-B, which may have been modified for PHUNSY or PoP, as there are 982 differences (4%) between them.
ALP.bin:
Neither of these has been typed in by me from the listing. Need to verify these dumps against the listing and compare with each other. One or both may have been modified for PHUNSY or PoP, as there are 831 differences (4%) between them.
AlphaChess.aof, CDChess.aof, Chess3.aof:
The chessboard is laid out in accordance with standard chess notation, ie.:
A | B | C | D | E | F | G | H | |
8 | A8 □♜ BR | B8 ■♞ BN | C8 □♝ BB | D8 ■♛ BQ | E8 □♚ BK | F8 ■♝ BB | G8 □♞ BN | H8 ■♜ BR |
7 | A7 ■♟ BP | B7 □♟ BP | C7 ■♟ BP | D7 □♟ BP | E7 ■♟ BP | F7 □♟ BP | G7 ■♟ BP | H7 □♟ BP |
6 | A6 □ | B6 ■ | C6 □ | D6 ■ | E6 □ | F6 ■ | G6 □ | H6 ■ |
5 | A5 ■ | B5 □ | C5 ■ | D5 □ | E5 ■ | F5 □ | G5 ■ | H5 □ |
4 | A4 □ | B4 ■ | C4 □ | D4 ■ | E4 □ | F4 ■ | G4 □ | H4 ■ |
3 | A3 ■ | B3 □ | C3 ■ | D3 □ | E3 ■ | F3 □ | G3 ■ | H3 □ |
2 | A2 □♙ WP | B2 ■♙ WP | C2 □♙ WP | D2 ■♙ WP | E2 □♙ WP | F2 ■♙ WP | G2 □♙ WP | H2 ■♙ WP |
1 | A1 ■♖ WR | B1 □♘ WN | C1 ■♗ WB | D1 □♕ WQ | E1 ■♔ WK | F1 □♗ WB | G1 ■♘ WN | H1 □♖ WR |
Moves are entered as source-destination. Eg. B1-A3.
AntennaComputer.bin:
This is a good dump, as regards the actual antenna computer program. The accompanying BASIC interpreter is why it is marked as a suspect dump. Overflows are very easy to generate, eg. attempting a LOOP of 1000 MHz.
Backup.aof: This program appears to be incomplete. Eg. execution flows beyond the listing into $15C3, it expects a TAPe OUT subroutine at $15C7 and a CLear SCReen subroutine at $1602. There is probably another unscanned page to this listing.
Bootstrap.aof: Might be the same as the IPL; needs reinvestigation.
Chess3.aof:
This does not appear to have been correctly ported to the CD2650. Eg.
the KBIN function of the BIOS will echo the keystroke, but the game itself
also echoes the keystroke, resulting in double echoing.
Also note that it swallows (ignores) the first keypress after booting
(although it might use the timing of that keypress for randomization or
similar purposes).
Additionally, the byte at $29C7 is erroneous. Presumably BSTA,un $2400
was meant rather than BSTA,un *$2400 [$7710]; therefore $A4 should be
changed to $24.
DOS.aof:
Got a "NOT READY" error, presumably due to incomplete disk emulation. Needs reinvestigation.
Editor/Assembler:
Commands are similar to the 12K BASIC editor, except:
G: goes to the supervisor
R: runs the assembler
Z: frees (zeroes) memory (changes BLOCKS LEFT from 00 to 50)
Hamurabi.aof:
You start with 100 men, 2800 bushels and 1000 acres. Turn phases are:
#1: Buy land: how many acres? (at 17..22 bushels per acre) (average of 19.5 bushels per acre)
Generally, at a price of 17..19 bushels per acre, you should buy.
#2: Sell land: how many acres? (at 17..22 bushels per acre) (average of 19.5 bushels per acre)
Generally, at a price of 20..22 bushels per acre, you should sell.
#3: Distribute food: how many bushels?
Requirement is 20 bushels per man.
Overfeeding will bring immigrants at 40 bushels per man.
There is never any reason to overfeed by more than 1960 bushels
(which would bring 49 overfeeding immigrants, plus 1 hungry immigrant in a good harvest (and more in average or bad harvests), thus hitting the maximum of 50 immigrants per turn).
Deaths from starvation, and overfeeding immigrants, are calculated here but not applied yet.
#4: Plant land: how many acres?
There is never any reason not to plant the maximum possible amount of land.
Limiting factors are (ie. use whichever of these is the lowest):
a. acres
b. bushels * 2
c. men * 10
Bushels are used up (although you will always get more back as harvest than what you plant as seed).
1 bushel can plant 2 acres and a bad (minimum) harvest is 1 bushel per planted acre.
Acres and men are not used up (you just need enough of them available).
Harvest/rats:
Harvest per planted acre is 1..5 (average of 3) bushels. Since 1 bushel plants 2 acres, harvest per planted bushel is double this, ie. 2..10 (average of 6) bushels.
Rats eat 0..7% of total (stored+harvest) bushels per turn (average of 3.5%).
Population changes:
Immigrants are those from overfeeding as previously calculated in phase #3, plus these hungry immigrants:
((total bushels * (5 - harvest per acre)) ÷ 600) + 1
So, to bring immigrants, you should overfeed, have many total bushels, and a bad harvest.
There is a limit of 50 total immigrants per turn.
Deaths from starvation are as previously calculated in phase #3.
Additionally, there is a 10% chance of a plague which will kill 50% of your men
(ie. average 5% plague deaths per turn).
This is applied after immigrants and deaths from starvation have already been applied
(in fact, strictly speaking it is applied at the start of the next turn).
The random factors each turn are:
a. the value of land (17..22 bushels per acre, average 19.5);
b. the harvest per planted acre (1..5 bushels per planted acre, average 3);
c. rat appetite (0..7% of total bushels, average 3.5%); and
d. whether a plague occurs (10% chance of killing 50% of your men) (average 5% plague deaths per turn).
In this version, there is no real scoring system nor game end (except with zero acres).
Scoring could be measured in land and/or food (and/or men, but the only reason to want men is for planting the land).
One possible algorithm is: score = bushels + (acres * 19.5) + men.
Input.aof:
This program is similar in purpose to TVTypewriter.aof except
that it supports both uppercase and lowercase I/O.
Since the code for backspace is the same as that for lowercase "h" (8),
and the code for a carriage return is the same as that for lowercase "m"
(13), these two lowercase letters are unusable in this program.
Note that this program has not been tested on the genuine machine and
the key bindings are mostly guesswork.
Life.aof:
Move around the screen with U/D/L/R for up/down/left/right. Use O (not 0) to set cells (they will appear as small o characters or as squares, depending on VDU setting) and the spacebar to clear them. To begin the simulation, move (with D key) the cursor to the bottom row of the screen. Never move the cursor above the top of the screen.
LunarLander.aof:
Here is the disassembly of the machine code routine:
$5BF6: 73 REDD,r3
$5BF7: 3F 01 9A BSTA,un DECR
$5BFA: CB 02 STRR,r3 $5BFE
$5BFC: 17 RETC,un
$5BFD: ?? <unused>
$5BFE: <vv> <value>
MemoryTest.aof:
The provided dump tests the RAM at $2000..$7FFF. The normal result of running this program is no output (ie. success). The byte at $1512 is the high byte of the starting address. The low byte of the starting address is always $00. The byte at $1513 is the high byte of the (ending address + 1). The low byte of the ending address is always $FF. Therefore, you must test $xx00..yyFF (a multiple of 256 bytes, aligned at a 256-byte boundary). Eg. storing $80 at $1513 gives an ending address of $7FFF, and storing $48 there would give an ending address of $47FF. Ie.
start address = *($1512) * $100;
end address = (*($1513) * $100) - 1;
If you want to see error messages, you could change $1512 to $00 and $1513 to $80, to test $0000..$07FF (which is ROM and therefore fails the test). Output will loop until a key is pressed. Memory is tested destructively. Therefore, you must not test the $1510..$15A8 area, otherwise you will overwrite the program. Contrary to what is stated in the instructions, the are where the program is located ($1510..$15A8) is normal (ie. non- display) user RAM, not display RAM.
MorseCode.aof:
This program lacks documentation. It might be originally designed to be interactive rather than to use stored text.
NumbersGame.aof:
INT seems to round to the nearest integer, rather than just dropping the fractional part. Therefore, "digits" range in value from 1..12.
Pattern.aof:
"The program has been typed into SCREENs 5 and 6. LOAD does not work unless LIST has been used first." - Richard Rogers. To run this program, type the following:
5 LIST 6 LIST 5 LOAD
123 PATTERN
You can change the 123 to a different number; it controls the number of blobs to write.
ScreenPrinter.aof:
This program refers to (external) printer routines at $4000 and $4147.
TVTypewriter.aof:
This program seems to expect the address of KBIN to be $309. However, the correct address is $30F. This change has been made to the available dump. Also, the screen is filled with $00 ("@" symbol). This may be authentic.
PHUNSY
PHUNSY means [Frank] PHilipse UNiversal SYstem.
Region | Size | Mini-PHUNSY | Full version |
$0000..$07FF | 2K | RAM | EPROM (PHUNSY BIOS) |
$0800..$0BFF | 1K | RAM (optional) | user RAM |
$0C00..$0E40 | 577 bytes | RAM (optional) | MDCR RAM |
$0E41..$0EDF | 159 bytes | RAM (optional) | user RAM |
$0EE0..$0EFF | 32 bytes | RAM (optional) | monitor RAM (scratchpad) |
$0F00..$0FFF | 256 bytes | RAM (optional) | monitor RAM (command input buffer) |
$1000..$17FF | 2K | RAM (optional) | RAM (screen memory) |
$1800..$1DFF | 1536 bytes | RAM (for use by BIOS) | banked RAM ("U" bank) |
$1E00..$1FFF | 512 bytes | ROM (Mini-Monitor BIOS) | banked RAM ("U" bank) |
$2000..$3FFF | 8K | unmapped? | general purpose RAM |
$4000..$7FFF | 16K | unmapped? | banked RAM ("Q" bank) |
Banks are:
U0: RAM
U1: EPROM (PDCR (Portable Digital Cassette Recorder))
U2: EPROM (DASS (DisASSembler))
U3: EPROM (LABHND (LABel HaNDler))
U4..UF: RAM
Q0: EPROM (MWB (MicroWorld BASIC)) ($4000..$5983)
Q1..QF: RAM
To run a BASIC game (after loading it):
Q (if necessary)
OLD
RUN
To make BASIC usable (after loading it):
NEW
To use the label program:
3UU
There are various versions of the PHUNSY monitor:
PMON0400.BIN is 04-0 from 1982 (as used in Ami/WinArcadia)
PMON0401.BIN is 04-1 from 1982
PMON0402.BIN is 04-2 from 1983
PMON0403.BIN is 04-3 from 1982 (sic)
03A-PMON0404.BIN and 04A-PMON0404.bin are 04-4 from 1983
Control port (ie. WRTC operand):
Bits 7..4 select which U-bank to use at $1800..$1FFF
Bits 3..0 select which Q-bank to use at $4000..$7FFF
Control port reads (REDC) are for serial input.
Data port reads (REDD) are for parallel input.
If high bit of data port is clear, a key is down.
If high bit of data port is set, no key is down.
Sound is generated by rapidly toggling bit 1 of the data port (via WRTD).
Writing to extended port $7E (WRTE) sets the timer countdown. It is
specified in units of 10 milliseconds (ie. 1/100ths of a second), and
thus can range from 0.01 to 2.55 seconds ($01..$FF). After expiration,
an interrupt is generated, causing execution to jump to $001D. The timer
is automatically reloaded whenever it expires. Writing $00 disables the
timer.
IOAD is the WRTZV pointer: normally $7AB (SROUT)
IIAD is the REDZV pointer $7D8 (SERIN)
ICAD is the CHIZV pointer $7C4 (DCHIN)
SERIN waits for a key to be pressed, then returns it. Its pseudocode is:
r5 = 0;
r4 = 8;
do
{
r0 = PORTC & 1;
} while (r0 != 0);
gosub DELAYC;
for (r4 = 8; r4 >= 1; r4--)
{
gosub DELAY;
r0 = (PORTC & 1) | r5;
r5 = r0 >> 1;
}
gosub DELAY;
r0 = r5 & %01111111;
return;
CHINP returns a key if one is currently being pressed, otherwise it returns $7F (DEL). Its pseudocode is:
r0 = PORTD;
if (r0 & %10000000 == %10000000)
{
r0 = $7F [DEL];
}
else
{
PORTD = 4;
r0 = PORTD;
PORTD = 0;
do
{
r5 = PORTD;
} while (r5 & %10000000 == %10000000);
r0 &= $7F;
}
return;
KEYIN waits for a key to be pressed, then returns it. Its pseudocode is:
do
{
r0 = PORTD;
} while (r0 & %10000000 == %10000000);
PORTD = 4;
r0 = PORTD;
PORTD = 0;
do
{
r5 = PORTD;
} while (r5 & %10000000 == %10000000);
r0 &= $7F;
return;
Mini-PHUNSY
The 24-key keyboard is as follows:
...0... ...4... ...8... ...C... ..D->M. .Reset.
...1... ...5... ...9... ...D... ..M->D. ..Halt.
...2... ...6... ...A... ...E... ...G... DumpCas
...3... ...7... ...B... ...F... ...Cl.. LoadCas
which in the emulator is (by default):
...a1.. ...a2.. ...a3.. NumLock ...n/.. ...n*..
...Q... ...W... ...E... ...n7.. ...n8.. ...n9..
...A... ...S... ...D... ...n4.. ...n5.. ...n6..
...Z... ...X... ...C... ...n1.. ...n2.. ...n3..
Cas = Cassette
Cl = Clear
D = Display
G = Go to
M = Memory
Output is 6 7-segment digits and 7 decimal points, as follows:
.1.2.3.4.5.6.
The first decimal point is always lit. The second to seventh are lit when IOPORT($13) is 1..6, respectively.
Game Help
These PHUNSY BINs are compatible with Ami/WinPHUNSY:
50-THEME
64>374
BELMACH
BELMACH0
BIG-CHAR:
This is a subroutine designed to be called by other programs, by putting
the desired ASCII value in r0 and calling $3700. The imagery for the
character set is at $3000..$32FF. See the commented disassembly of this
program for more details.
BMK
CHRPRNTR
CLEARMEM:
This works but takes a few moments.
COPY
This installs these routines:
800G show this help
803G read cassette to RAM
806G save RAM to cassette
809G continue read after error
DASS6800
FORTH-01
FUN-CLOCK
GEINTJE
GETS-002:
Unsure what it is showing.
Eventually gets into an infinite output loop.
GRAPJE-1..5
KLOK:
The emulator is too fast, or the "game" is too slow, by a 1:120 ratio (0.8%).
KRANT
L-KRANT
MODESTA,B,C,N (all except MODEST itself)
MWBAS-04,05,06 (all except 00 and M6):
Type NEW at startup, otherwise it will always just say "FILE ERROR".
MWBAS, 14A-MWBAS-06, 20A-MWBAS-06, MWBAS-M6 are the 24/12/1983 version.
13A-MWBAS-06 is the 23/4/1984 version.
MWBAS-07 is the 6/11/2010 version.
MWBAS-00, MWBAS-05 are undated.
OTHELLO
PASS (both dumps)
PAUZE
PEDT-004
PEDT-0A3
PIANO
PMONmini
QASS-003
RAMTEST
RUNLIGHT
SEE-C374:
Usage: U
Type eg. U0 to start viewing memory from address $0000.
SEE-CHAR:
Usage: 800G
Type eg. 800G0 to start viewing memory from address $0000.
SEE-EXT (all dumps)
all games in the MicroWorldBASIC/ directory
These dumps are incompatible, problematic or otherwise unusable:
300-BAUD
BASIO-20 (It reads from extended I/O port(s) for some reason; possibly non-PHUNSY.
Maybe it's eg. the CD2650 extended basic functions. Needs investigation.)
CASSDISK
CDC-I/O (It's expecting there to be code at $6003 and there isn't any.)
CLOCK (10-A and 16-A. FUN.MDCR version is OK.)
CONV2>0 (This gosubs to $19EC (which doesn't contain anything) for some reason.)
CONV6>2
COPYOV
DAME (This is an ASCII picture.)
DISK
FLXWR-02
FORTH-00
FPRINTER
GRAPHICS
GRAPHS
HEXDUMP
I/OPACK (This seems to expect a different BIOS.)
LKRANT
MEMTA (Flashes INPUT ERR very briefly. Probably needs arguments to be provided.)
MODEST (both dumps)
MWBAS-00
MWBAS-M6
PALASM
PCITALK (Reads/writes from/to extended I/O port(s) for some reason.)
PH-CHR
PHCSRD (This tries to read from the cassette (via the Sense pin).)
PHEDTR2 (both dumps) (This reads from extended I/O ports for some reason.)
PORT9600
PRPRG ((E)PR(OM) Pr(o)g(rammer)?
Has PHUNSY monitor 04-P4 (special edition?) in it, and Malotaux
programmer, and data for various non-Signetics chips.
READHEX
ROW->COL (both dumps)
SCR
SEND-JET (This jumps to $1914 (which doesn't contain anything) for some reason.)
SER-I/O
SOUTCASS
TERML
TPRINT-S
TPRINTER (both dumps)
TRNR-001
ZOOI
The reasons are various, eg.:
the program is accessing unemulated hardware (eg. SER-I/O);
the "program" is really just a subroutine library for use by other programs (eg. BIG-CHAR);
the "program" is really just data;
the program might just have bugs (eg. FORTH-00?);
the program might be a bad dump;
the program is expecting command line arguments (eg. SEE-CHAR);
the program is not intended to produce any output (eg. CLEARMEM);
etc.
Translations of game names:
![]() | ![]() |
Dame | Lady |
Krant | Newspaper |
Liedjes | Songs |
Zooi | Mess |
Ravensburger Selbstbaucomputer
Region | Size | No BIOS | With BIOS |
$0000..$07FF | 2K | user RAM | 2716 BIOS ROM or 28C16 BIOS EEPROM (bottom left of memory card) |
$0800..$08FF | 0.25K | user RAM? | 6116 BIOS RAM (top left of memory card) |
$0900..$0FFF | 1.75K | user RAM? | 6116 user RAM (top left of memory card) |
$1000..$17FF | 2K | user RAM? | 6116 RAM, 2716 ROM, or 28C16 EEPROM (bottom right of memory card) |
$1800..$1FFF | 2K | user RAM? | 6116 RAM, 2716 ROM, or 28C16 EEPROM (top right of memory card) |
$2000..$7FFF | 24K | unmapped? | unmapped? |
"Selbstbaucomputer" translates to "Self-built computer". The subsystems of this system are:
No. | ![]() | ![]() | Pages |
1 | Netzteil | Power supply | 69-80 |
2 | Busplatte | Bus board or backplane | 81-92 |
3 | Daten eingabe anzeige | Data input display | 93-110 |
4 | CPU | CPU | 111-140 |
5 | Addressen eingabe anzeige | Address input display | 141-147 |
6 | Speicher | Memory | 148-172 |
7 | Porteinheit | Port unit | 173-189 |
8 | A/D-Wandler | A/D converter (analog-to-digital converter) | 190-212 |
9 | Tastatur & anzeige | Keyboard & display | 213-239 |
10 | Casetten-interface | Cassette interface | 240-249 |
The system could also be operated without any monitor! With this mode, you enter your code with a binary address switch and data switch in single step mode ;-) You start at address $0. After entering your program, you could run it at 1 Hz or 1 MHz, or stay in single step mode.
From the games book (autotranslated from German):
"At the beginning of all programs is the hardware used. "Basic version" means: CPU, data and address input and output, RAM memory and port module, without EPROM and without keyboard and display unit. In these cases is the switch on the memory card in Position "1" to bring so that the RAM area begins at address $0000. If you have the keyboard and display unit use the switch on the memory card in position "2" standing, so that the EPROM is at the beginning of the addressing area. Then you can use the data and address input and output units from detach from the bus plate. You can but also leave them connected. In the case need the data switch There in position DAFLOT and the Address switch Adr in position ADFLOT standing, otherwise nothing works. These two construction stages are of use to you then if you have a program in Single-STEP or single-CLOCK clock through then the switch must STEP-RUN on the keyboard in stand in the STEP position so that the seven-segment displays in case of her activation not be overloaded. You can then observe the program progress on the data and observe address input and output."
The 24-key keyboard is as follows:
...C... ...D... ...E... ...F... ..CMD.. .FLAG..
...8... ...9... ...A... ...B... ..RUN.. ..MON..
...4... ...5... ...6... ...7... ..GOTO. ..PC...
...0... ...1... ...2... ...3... ..RST.. ..NXT..
By default, these are mapped to the following host keys (on Ami/WinSelbstbaucomputer):
...a1.. ...a2.. ...a3.. .NumLk. ...n/.. ...n*..
...Q... ...W... ...E... ...n7.. ...n8.. ...n9..
...A... ...S... ...D... ...n4.. ...n5.. ...n6..
...Z... ...X... ...C... ...n1.. ...n2.. ...n3..
Diode colours are:
Diode | Colour |
CLOCK | red |
OPACK | green |
OPREQ | yellow |
M/IO | red |
RUN/WAIT | green |
WRP | red |
FLAG | red |
Monitor BIOS
V0.9 BIOS functions:
HEXDEZ (ZBSR,un *$3) @ $5E9 HEXBCD
CONV (ZBSR,un *$5) @ $230 CONVT
SEP (ZBSR,un *$7) @ $207 SEPNIB
COMB (ZBSR,un *$9) @ $21E COMNIB
DIS (ZBSR,un *$B) @ $E5 DISP
KIN (ZBSR,un *$D) @ $C4 KIN1
INIT (ZBSR,un *$F) @ $235 INIT1
SAVE (ZBSR,un *$11) @ $24E INIT2
RECAL (ZBSR,un *$13) @ $272 INIT3
CDIS (ZBSR,un *$15) @ $296 CDISP
BPGOT (ZBSR,un *$17) @ $574 BPFND
LODAT (ZBSR,un *$19) @ $149 LOAD
ADDSUB (ZBSR,un *$1B) @ $6A0 ADSB
MULT (ZBSR,un *$1D) @ $6CD MPYS
DIV (ZBSR,un *$1F) @ $700 DIVS
DEZHEX (ZBSR,un *$21) @ $649 BCDHEX
SEPD (ZBSR,un *$23) @ $197 SEPDIS
HEXD (ZBSR,un *$25) @ $774 HEXD1
DHEX (ZBSR,un *$27) @ $79D DHEX1
HEX (ZBSR,un *$29) @ $79F DHEX2
DEZ (ZBSR,un *$2B) @ $776 HEXD2
ERROR (ZBSR,un *$2D) @ $432 ERR
Note that byte $673 of the V0.9 BIOS is not listed in the PDF. Its correct value has been ascertained to be $82.
V2.0 BIOS functions:
KIN (ZBSR,un *$14) @ $384 KBIN
WBL (ZBSR,un *$16) @ $16A WRBL
WCH (ZBSR,un *$18) @ $425 WCHR
INPHX (ZBSR,un *$1A) @ $1B6 INHX
OUTHX (ZBSR,un *$1C) @ $4F HXO
LINEF (ZBSR,un *$1E) @ $45 LFC
PUT (ZBSR,un *$20) @ $2C1 SERO
GET (ZBSR,un *$22) @ $35E SERI
HXTAB (ZBSR,un *$24) @ $19A TABL
ADRES (ZBSR,un *$26) @ $185 ADDR
CONTR (ZBSR,un *$28) @ $48C CR
HO (ZBSR,un *$2A) @ $4E5 HOME1
CURSL (ZBSR,un *$2C) @ $4EE CURL3
CURSR (ZBSR,un *$2E) @ $52B CURR1
CURSU (ZBSR,un *$30) @ $5E6 CUUP1
CURSD (ZBSR,un *$32) @ $4C2 LF1
SCCLR (ZBSR,un *$34) @ $4CA CLR2
BACK (ZBSR,un *$36) @ $51A BACK1
Monitor commands are:
Alter
B
C
Dump
E
I
Load
R
Verify
Game Help
These programs are contained in the "2650 Programme.pdf" book:
![]() | ![]() |
440-Hz-Programm zum Abgleich des CLOCK-Oszillators | 440 Hz program for the adjustment of clock oscillator |
Portadressierung | Port addressing |
Einfache Addition | Simple addition |
Einfache Subtraktion | Simple subtraction |
Einfache Multiplikation | Simple multiplication |
Einfache Division | Simple division |
Verkehrsampel 1 | Traffic lights 1 |
Blinklicht | Beacon |
Würfel | Dice |
Metronom | Metronome |
Lauflicht | Running light |
Voltmeter mit dualer Anzeige | Dual display voltmeter |
Denkzeitbegrenzer | Think time limiter |
Verkehrsampel 2 | Traffic lights 2 |
VU-Meter | Vumeter |
Laufschrift | Scrolling text |
Würfelspiel | Dice game |
Reaktionstest | Reaction test |
Stoppuhr | Stopwatch |
Digitaluhr | Digital clock |
HEX-DEZ-HEX-Wandlung | Hexadecimal-decimal-hexadecimal conversion |
HEX-Rechnen | Hexadecimal calculation |
DEZ-Rechnen | Decimal calculation |
Lottozahlen | Lotto numbers |
Morse-Übungsprogramm | Morse code practice |
Voltmeter 2 (3stellig dezimal) | Voltmeter 2 (3-digit decimal) |
DecCalculation.aof:
The entire program is as follows:
for (;;)
{ gosub GDEZ;
*($827) = r3;
*($828) = r2;
do
{ gosub KIN;
r3 = *($800);
REGS = r3;
} while (r3 <= $0F || r3 >= $50);
gosub GDEZ;
*($829) = r3;
*($82A) = r2;
r3 = REGS;
switch (r3)
{
case '-': PSL |= COM ; gosub ADDSUB;
acase '+': PSL &= ~(COM); gosub ADDSUB;
acase '*': gosub MULT;
acase '/': gosub DIV;
adefault: r3 = *($812) = '3'; // 6th digit
goto ERROR;
}
gosub HEXD;
gosub KIN;
}
GDEZ:
do
{ gosub CDIS;
gosub KIN;
PSL &= ~(WC);
r3 = *($800);
if (r3 == '+')
{ *($8FF) = '+';
r3 = *($80D) = 'P'; // 1st digit
} elif (r3 == '-')
{ *($8FF) = '-';
r3 = *($80D) = '-'; // 1st digit
} }
while (*($800) != '+' && *($800) != '-');
r2 = *($82D) = 5;
gosub LODAT;
r3 = $20;
if (*($8FF) != '-')
{ *($81A) |= $90;
}
*($82E..$830) = *($81A..$81C);
gosub DEZHEX;
r3 = *($82B);
r2 = *($82C);
return;
Dice.bin:
This shows the number in binary on the glow LEDs; ie:
.......* means 1 was rolled
......*. means 2 was rolled
......** means 3 was rolled
.....*.. means 4 was rolled
.....*.* means 5 was rolled
.....**. means 6 was rolled
DiceGame.bin:
The entire program is as follows:
for (;;)
{ *($80D..$812) = 0;
*($81B) = 0;
for (i = 0; i < 3; i++)
{ gosub RANDOM;
gosub SUMME;
gosub CONV;
*($80D + i) = r3; // 1st..3rd segments
gosub KIN;
} }
SUMME:
*($81C) = r3;
*($81B) += r3;
*($82B) = 0;
*($82C) = r3;
gosub HEXDEZ;
r3 = *($830);
*($801) = r3;
gosub SEP;
r3 = *($801);
gosub CONV;
*($811) = r3; // 5th segment
r3 = *($802);
gosub CONV;
*($812) = R3; // 6th segment
r3 = *($81C);
return;
RANDOM:
r0 = PSU & Sense;
NEW:
r3 = 0;
LOOP:
r3++;
if (r3 == 7) goto NEW;
r0 = PSU & Sense;
compare r0 against *($815);
if (==) goto LOOP;
return;
LottoNumbers.aof:
The entire program is as follows:
gosub CDIS; // clear display
*(LOTTO..LOTTO+14) = 0; // or, *($8F0..$8FE) = 0;
RSLT = 0;
for (*($8F7) = 1; *($8F7) <= 7; *($8F7)++)
{ *(LOTTO + *($8F7)) = RANDOM();
*($82C) = *($8F7);
gosub HEXDEZ;
r3 = *($830);
DATA2 = r3;
gosub SEP;
*($812) = CONV(DATA3); // 6th digit
*($811) = CONV(DATA2); // 5th digit
*($80D) = CONV(*($8F7)); // 1st digit
gosub KIN;
}
goto START;
RANDOM:
WBUF = PSU & Sense;
for (r3 = 1; r3 <= 49; r3++)
{ if ((PSU & Sense) != WBUF)
{ r0 = r3;
for (r2 = 1; r2 <= 7; r2++)
{ if (r0 == *(LOTTO + r2))
{ goto RANDOM;
} } } }
return; // result is in r0 and also in r3
$830 is the number that has just been drawn (1..49).
$8F1..$8F6 are the drawn numbers.
$8F7 is the sequence number (1..3).
The randomizer constantly cycles through 1..49 and stops as soon as the Sense bit changes.
Morse Code Practice:
The data table is as follows:
Character
Data
Morse
Notes
A
$0240
%.-000000
-
B
$0480
%-...0000
-
C
$04A0
%-.-.0000
-
D
$0380
%-..00000
-
E
$0100
%.0000000
-
...
...
...
...
Z
$04C0
%--..0000
-
0
$05F8
%-----000
-
1
$0578
%.----000
-
...
...
...
...
9
$05F0
%----.000
-
=
$0588
%-...-000
-
;
$06A8
%-.-.-.00
-
,
$06CC
%--..--00
-
-
$0684
%-....-00
-
/
$0590
%-..-.000
-
:
$06E0
%---...00
-
?
$0630
%..--..00
-
.
$0654
%.-.-.-00
-
$05A8
%-.-.-000
Starting signal (/KA aka /CT)
+
$0550
%.-.-.000
New message follows (/RN aka /AR)
MIKIT 2650
Region | Size | MIKIT 2650-K1, 2650-P1 | MIKIT 2650-K21, 2650-P21, 2650-K1+2650-K2 |
$0000..$01FF | 512 bytes | BIOS ROM | BIOS ROM |
$0200..$03FF | 512 bytes | unmapped? | BIOS ROM |
$0400..$041F | 32 bytes | BIOS RAM | BIOS RAM |
$0420..$04FF | 234 bytes | user RAM | user RAM |
$0500..$07FF | 768 bytes | unmapped? | user RAM |
$0800..$7FFF | 30K | unmapped? | unmapped? |
Both versions support keypad input and LED output.
MIKIT 2650-K1, 2650-P1 have 4 I/O ports, 512 bytes of ROM, 256 bytes of RAM.
MIKIT 2650-K21, 2650-P21, 2650-K1+2650-K2 have 8 I/O ports, 1K of ROM, 1K of RAM,
and support cassette and teletype I/O.
The 8 glow LEDs controlled by writing to the Control port (WRTC).
The 6 LED digits are at $402..$407 (in BIOS RAM).
$FD is the entry point to the BIOS display routine.
The cassette recorder uses port 227 ($E3) for input and port 228 ($E4) for output.
The teletype uses port 229 ($E5) for input and port 226 ($E2) for output.
The 24-key keyboard is as follows:
.BLANK. ...R... ...C... ...D... ...E... ...F...
...+... ...G... ...8... ...9... ...A... ...B...
...H... ...P... ...4... ...P... ...6... ...7...
...L... ...S... ...0... ...1... ...2... ...3...
BLANK = ?
R = Read
+ = Add?
G = Go
H = Halt
P = Punch
L = Load
S = Store
By default, these are mapped to the following host keys (on Ami/WinMIKIT):
...a1.. ...a2.. ...a3.. .NumLk. ...n/.. ...n*..
...Q... ...W... ...E... ...n7.. ...n8.. ...n9..
...A... ...S... ...D... ...n4.. ...n5.. ...n6..
...Z... ...X... ...C... ...n1.. ...n2.. ...n3..
Game Help
Stufenzaehler (Program 5):
The entire program is as follows:
enable interrupts
use main register bank
clear With Carry
set signed compare
for (;;)
{ for (r1 = 1, r3 = N; r3 > 0; r1++, r3--)
{ r0 = *(&A + r3);
if (r1 == r0)
{ PORTC = r1;
}
while (PORTC != *(&B + r3));
} }
Ein- und Aus-Schaltbare Blinklampe (Program 7):
The entire program is as follows:
enable interrupts
use main register bank
clear With Carry
set signed compare
AUS:
use main register bank
PORTC = ........; // clear glow LEDs
while (PORTC & %10000000);
for (;;)
{ PORTC = .......#; // light one glow LED
for (r4 = 256; r4 > 0; r4--)
{ for (r5 = 48; r5 > 0; r5--)
{ if (PORTC & %00000001 == %00000000)
{ goto AUS;
} } }
PORTC = ........; // clear glow LEDs
for (r4 = 256; r4 > 0; r4--)
{ for (r5 = 48; r5 > 0; r5--)
{ if (PORTC & %00000001 == %00000000)
{ goto AUS;
} } } }
Elektronischer Würfel (Program 8):
The entire program is as follows:
enable interrupts
use main register bank
clear With Carry
set unsigned compare
*($402..$407) = $66;
for (;;)
{ for (r1 = 6; r1 > 0; r1--)
{ gosub $FD;
if (PORTC & %10000000 == %00000000)
{ *($407) = r1;
do
{ gosub $FD;
r0 = PORTC;
} while (r0 >= 1 && r0 <= 127);
} } }
Reaktionzeittest (Program 12):
Press any key to begin.
As soon as the numbers begin incrementing, press eg. the '1' key.
Codiertes Schloss (Program 13):
You have to press three keys in succession within limited times.
The keys you have to press are stored in *($52A..$52C) (in reverse order).
COD is $529.
Press 1, then 2, then 3.
The entire game is as follows:
enable interrupts
use main register bank
clear With Carry
set unsigned compare
PORTC = 0; // clear glow LEDs
while (PORTC != *($52D)); // wait for first key
for (r1 = 2; r1 >= 0; r1--)
{ for (r2 = 256; r2 > 0; r2--)
{ wait
if (PORTC == *(&COD + r1)) // if pressed correct key
{ goto S1;
} }
PORTC = ########; // lose
for (;;);
S1:
;
}
PORTC = #.#.#.#.; // win
for (;;);
Coin-ops
MAME 0.277 compatibility table (non-pinball non-bootleg coin-ops only):
Name | Company | Year | Colours | Graphics | Sound | Flipping | Conversion kit | ||||||
OR | CE | DK | GA | PM | SC | ||||||||
3-D Bowling | Meadows | 1978 | 100% | 100% | 0% | Yes | OR | ||||||
8 Ball Action | Meadows | 1978 | 100% | 100% | 100% | Yes | DK | PM | |||||
![]() | Zaccaria | 1980 | 100% | 99% | 99% | No | OR | ||||||
Bigfoot Bonkers | Meadows | 1976 | 100% | 100% | 100% | Yes | OR | ||||||
Bulls Eye Darts | Senko/Shinkai | 1985 | 0% | 99/100% | 100% | Yes | CE | GA | |||||
Cat and Mouse | Zaccaria | 1982 | 100% | 100% | 99% | Yes | OR | ||||||
Continental (bingo) | Bally | 1980 | - | - | 0% | - | OR | ||||||
Cosmos | Century | 1981 | 100% | 100% | 99% | No | OR | ||||||
Dark Warrior | Century | 1981 | 100% | 100% | 99% | No | OR | ||||||
Dazzler | Century | 1982 | 100% | 100% | 99% | No | OR | ||||||
Dead Eye | Meadows | 1978 | 100% | 100% | 100% | Yes | OR | ||||||
Digger | Century | 1982 | 100% | 100% | 99% | No | OR | ||||||
Dodgem | Zaccaria | 1979 | 100% | 100% | 99% | Yes | OR | ||||||
Driving Force | Shinkai | 1984 | 100% | 100% | 100% | Yes | GA | PM | |||||
Embargo | Cinematronics | 1977 | 100% | 100% | 0% | Yes | OR | ||||||
![]() | Zaccaria | 1979 | 100% | 99% | 99% | No | OR | ||||||
Gold Bug | Century | 1982 | 100% | 100% | 99% | No | OR | ||||||
Gypsy Juggler | Meadows | 1978 | 100% | 99% | 100% | Yes | OR | ||||||
Heart Attack | Century | 1983 | 100% | 100% | 99% | No | OR | ||||||
Herbie at the Olympics | Seatongrove | 1984 | 100% | 100% | 100% | Yes | DK | ||||||
Hero 1 | Seatongrove | 1984 | 100% | 100% | 100% | Yes | OR | ||||||
Hero 2 | Seatongrove | 1984 | 100% | 100% | 100% | Yes | DK | ||||||
Hex Pool | Senko | 1985 | 100% | 100% | 100% | Yes | GA | ||||||
Hunchback | Century | 1983 | 100% | 100% | 99/100% | No/Yes | OR | DK | GA | SC | |||
Hunchback Olympic | Seatongrove | 1984 | 100% | 100% | 99/100% | No/Yes | OR | SC | |||||
Inferno | Meadows | 1978 | 100% | 100% | 0% | Yes | OR | ||||||
![]() | Zaccaria | 1981 | 100% | 100% | 99% | Yes | OR | ||||||
Lazer Command | Meadows | 1976 | 100% | 100% | 100% | Yes | OR | ||||||
Logger | Century | 1982 | 100% | 100% | 99% | No | OR | ||||||
![]() | Kitronix | 198x | 1% | 1% | 1% | - | OR | ||||||
Outline & Radar Zone | Century | 1982 | 100% | 100% | 99% | No | OR | ||||||
Porky | Shinkai | 1985 | 100% | 100% | 100% | Yes | PM | ||||||
Quasar | Zaccaria | 1980 | 100% | 100% | 99% | No | OR | ||||||
Quiz Show | Kee | 1976 | - | - | - | - | OR | ||||||
Raiders | Century | 1983 | 100% | 100% | 99% | No | OR | ||||||
Rack + Roll | Senko | 1986 | 100% | 100% | 100% | Yes | GA | ||||||
Sea Battle & Armada | Zaccaria | 1980 | 99% | 99% | 0% | Yes | OR | ||||||
Shooting Gallery | Seatongrove | 1984 | 100% | 100% | 99% | Yes | DK | ||||||
Space Fortress | Century | 1981 | 100% | 100% | 99% | No | OR | ||||||
Space Warp? | Cosmos | 1983 | 0% | - | - | - | GA | ||||||
Special Forces 1 & 2 | Senko | 1985 | 100% | 100% | 100% | Yes | DK | ||||||
Sub Hunter | Model Racing | 1979 | - | - | 0% | - | OR | ||||||
Superbike | Century | 1983 | 100% | 100% | 99% | No | OR | DK | GA | ||||
The Invaders | Zaccaria | 1979? | 100% | 100% | 99% | Yes | OR | ||||||
Trivia Challenge | Senko | 1985 | - | - | - | - | GA | ||||||
Video 8 Ball | Century | 1982 | 100% | 100% | 99% | No | OR | ||||||
Wall Street | Century | 1982 | 100% | 100% | 99% | No | OR |
Conversion kits are:
OR = Original
CE = Centipede
DK = Donkey Kong/Donkey Kong Jr.
GA = Galaxian [sic]
PM = Pac-Man
SC = Scramble
These Zaccaria non-pinball coin-ops do not use a 2650 (all others do):
Jack Rabbit
Money Money
Motor Show
Scorpion
Coin-op originals of (presumably or explicitly) licenced ports to Arcadia-family consoles:
Name | Licensor | Year | Graphics | Sound | Flipping | CPU(s) |
![]() | Konami | 1981 | 100% | 99% | Yes | Z80 |
![]() | Exidy? | 1977 | 100% | 99% | Yes | 6502 |
![]() | Nichibutsu? | 1980 | 100% | 100% | Yes | Z80 |
![]() | Tekhan | 1981 | 100% | 100% | Yes | 2*Z80 |
![]() | Coreland | 1981 | 100% | 99% | Yes | Z80 |
![]() | Konami | 1981 | 100% | 100% | Yes | 2*Z80 |
![]() | Tekhan | 1981 | 99% | 100% | Yes | 8085A |
![]() | Sigma | 1980 | 100% | 100% | Yes | 6802+6809 |
![]() | Tehkan | 1981 | 99% | 99% | Yes | Z80 |
![]() | Tekhan | 1981 | 100% | 100% | Yes | 2*Z80 |
![]() | Sigma | 1981 | 100% | 99% | Yes | 6802+6809 |
![]() | Konami | 1980 | 100% | 100% | Yes | 2*Z80 |
![]() | Konami | 1981 | 100% | 100% | Yes | 2*Z80 |
Malzak
Region | Size | Malzak 1 | Malzak 2 |
$0000..$07FF | 2K | from $0000..$07FF of malzak.5 (ROM code) | from $0000..$07FF of malzak.1a (ROM code) |
$0800..$0BFF | 1K | from $0000..$03FF of malzak.4 (ROM code) | from $0000..$03FF of malzak.2b (ROM code) |
$0C00..$0FFF | 1K | from $0000..$03FF of malzak.3 (ROM data) (screen data?) | banked area (controlled by bit 6 of I/O port $40)
Malzak 1: from $0000..$03FF of malzak.4d (ROM data) (screen data) Malzak 2: from $0400..$07FF of malzak.4d (ROM data) (screen data) |
$1000..$13FF | 1K | RAM | RAM |
$1400..$14FF | 256 bytes | 1st PVI | 1st PVI |
$1500..$15FF | 256 bytes | 2nd PVI | 2nd PVI |
$1600..$16FF | 256 bytes | playfield tilemap | playfield tilemap |
$1700..$17FF | 256 bytes | RAM | NVRAM |
$1800..$1E3F | 1600 bytes | teletext screen contents | teletext screen contents |
$1E40..$1FFF | 448 bytes | RAM? | RAM? |
$2000..$27FF | 2K | from $0800..$0FFF of malzak.5 (ROM code) | from $0800..$0FFF of malzak.1a (ROM code) |
$2800..$2BFF | 1K | empty | from $0800..$0BFF of malzak.2b |
$2C00..$2FFF | 1K | empty | empty |
$3000..$3FFF | 4K | mirror of $1000..$1FFF | mirror of $1000..$1FFF |
$4000..$43FF | 1K | from $0400..$07FF of malzak.4 (ROM code) (terrain code) | from $0400..$07FF of malzak.2b (ROM code) (terrain code) |
$4400..$4BFF | 2K | from $0000..$07FF of malzak.3 (ROM data) (terrain data) | banked area? If so...
Malzak 1: from $0000..$07FF of malzak.3 (ROM data) (terrain data) Malzak 2: from $0000..$07FF of malzak.3c (ROM data) (terrain data) |
$4C00..$4FFF | 1K | empty | empty |
$5000..$5FFF | 4K | mirror of $1000..$1FFF | mirror of $1000..$1FFF |
$6000..$63FF | 1K | empty | from $0C00..$0FFF of malzak.2b |
$6400..$6FFF | 3K | empty | empty |
$7000..$7FFF | 4K | mirror of $1000..$1FFF | mirror of $1000..$1FFF |
malzak.1 (containing tile imagery) is not accessible to the CPU,
nor is the teletext character imagery. Both are identical
between Malzak 1 and Malzak 2.
$1xxx is deliberately mirrored at $3xxx, $5xxx, $7xxx, because on
the 2650, you can only access data on the same 8K page, so mirroring is
very useful for the game programmer (otherwise code in the $2000..$7FFF
region could not directly access any of the RAM).
For Malzak 2, if *($14CC) is $00 (ie. test switch is at position 4), the game will enter test mode when booting. When it enters test mode, it clears the settings first.
Input devices are:
8-way digital joystick
P1, P2 buttons
Firebutton
Coin slot
Test switch (Malzak 2 only)
Input bits are:
Bit 7: up (active high)
Bit 6: left (active high)
Bit 5: right (active high)
Bit 4: fire (active high)
Bit 3: 2P (active high)
Bit 2: 1P (active high)
Bit 1: down (active high)
Bit 0: coin slot (active low)
Maps of Malzak 1 and 2 are available in the Maps Pack at http://amigan.yatho.com/maps.rar.
When you run out of fuel, your ship falls out of the sky, but your exhaust continues to burn and does not fall. This is probably authentic.
Astro Wars & Galaxia
Region | Size | Astro Wars | Galaxia |
$0000..$03FF | 1K | from $0000..$03FF of 08h.bin (ROM) | from $0000..$03FF of 08h.bin (ROM) |
$0400..$07FF | 1K | from $0000..$03FF of 10h.bin (ROM) | from $0000..$03FF of 10h.bin (ROM) |
$0800..$0BFF | 1K | from $0000..$03FF of 11h.bin (ROM) | from $0000..$03FF of 11h.bin (ROM) |
$0C00..$0FFF | 1K | from $0000..$03FF of 13h.bin (ROM) | from $0000..$03FF of 13h.bin (ROM) |
$1000..$13FF | 1K | from $0000..$03FF of 08i.bin (ROM) | from $0000..$03FF of 08i.bin (ROM) |
$1400..$14FF | 256 bytes | RAM | banked:
when Flag bit of PSU is clear: bullet RAM when Flag bit of PSU is set: palette RAM (16 bytes) |
$1500..$15FF | 256 bytes | PVI | 1st PVI |
$1600..$16FF | 256 bytes | unmapped? | 2nd PVI |
$1700..$17FF | 256 bytes | unmapped? | 3rd PVI |
$1800..$1BFF | 1K | banked:
when Flag bit of PSU is clear: screen colours when Flag bit of PSU is set: screen contents | banked:
when Flag bit of PSU is clear: screen colours when Flag bit of PSU is set: screen contents |
$1C00..$1CFF | 256 bytes | banked:
when Flag bit of PSU is clear: bullet RAM when Flag bit of PSU is set: palette RAM (16 bytes) | RAM |
$1D00..$1FFF | 768 bytes | unmapped? | RAM |
$2000..$23FF | 1K | from $0000..$03FF of 10i.bin (ROM) | from $0000..$03FF of 10i.bin (ROM) |
$2400..$27FF | 1K | from $0000..$03FF of 11i.bin (ROM) | from $0000..$03FF of 11i.bin (ROM) |
$2800..$2BFF | 1K | from $0000..$03FF of 13i.bin (ROM) | from $0000..$03FF of 13i.bin (ROM) |
$2C00..$2FFF | 1K | from $0000..$03FF of 11l.bin (ROM) | from $0000..$03FF of 11l.bin (ROM) |
$3000..$33FF | 1K | from $0000..$03FF of 13l.bin (ROM) | from $0000..$03FF of 13l.bin (ROM) |
$3400..$3FFF | 3K | mirror of $1400..$1FFF | mirror of $1400..$1FFF |
$4000..$53FF | 5K | unknown | unknown |
$5400..$5FFF | 3K | mirror of $1400..$1FFF | mirror of $1400..$1FFF |
$6000..$73FF | 5K | unknown | unknown |
$7400..$7FFF | 3K | mirror of $1400..$1FFF | mirror of $1400..$1FFF |
In Astro Wars, the yellow sprites are meteors, not bullets; this explains why they do not emanate from the enemy ships.
Laser Battle & Lazarian
Region | Size | Laser Battle | Lazarian |
$0000..$03FF | 1K | from $0000..$03FF of lb02.7c/laz.7c/02-1.7c | from $0000..$03FF of lb02.7c/laz.7c/02-1.7c |
$0400..$07FF | 1K | from $0000..$03FF of lb02.6c/laz.6c/02-2.6c | from $0000..$03FF of lb02.6c/laz.6c/02-2.6c |
$0800..$0BFF | 1K | from $0000..$03FF of lb02.5c/laz.5c/02-3.5c | from $0000..$03FF of lb02.5c/laz.5c/02-3.5c |
$0C00..$0FFF | 1K | from $0000..$03FF of lb02.3c/laz.3c/02-4.3c | from $0000..$03FF of lb02.3c/laz.3c/02-4.3c |
$1000..$13FF | 1K | from $0000..$03FF of lb02.2c/laz.2c/02-5.2c | from $0000..$03FF of lb02.2c/laz.2c/02-5.2c |
$1400..$14FF | 256 bytes | unused | unused |
$1500..$15FF | 256 bytes | 1st PVI | 1st PVI |
$1600..$16FF | 256 bytes | 2nd PVI | 2nd PVI |
$1700..$17FF | 256 bytes | 3rd PVI | 3rd PVI |
$1800..$1BFF | 1K | display RAM (write-only) | display RAM (write-only) |
$1C00..$1FFF | 1K | user RAM | user RAM |
$2000..$23FF | 1K | from $0000..$03FF of lb02.7b/laz.7b/02-6.7b | from $0000..$03FF of lb02.7b/laz.7b/02-6.7b |
$2400..$27FF | 1K | from $0000..$03FF of lb02.6b/laz.6b/02-7.6b | from $0000..$03FF of lb02.6b/laz.6b/02-7.6b |
$2800..$2BFF | 1K | from $0000..$03FF of lb02.5b/laz.5b/02-8.5b | from $0000..$03FF of lb02.5b/laz.5b/02-8.5b |
$2C00..$2FFF | 1K | from $0000..$03FF of lb02.3b/laz.3b/02-9.3b | from $0000..$03FF of lb02.3b/laz.3b/02-9.3b |
$3000..$33FF | 1K | from $0000..$03FF of lb02.2b | from $0800..$0BFF of laz10-62.2b |
$3400..$37FF | 1K | mirror of $1400..$17FF | mirror of $1400..$17FF |
$3800..$3BFF | 1K | mirror of $1800..$1BFF? | from $0000..$03FF of laz10-62.2b |
$3C00..$3FFF | 1K | mirror of $1C00..$1FFF | mirror of $1C00..$1FFF |
$4000..$43FF | 1K | from $0400..$07FF of lb02.7c/laz.7c/02-1.7c | from $0400..$07FF of lb02.7c/laz.7c/02-1.7c |
$4400..$47FF | 1K | from $0400..$07FF of lb02.6c/laz.6c/02-2.6c | from $0400..$07FF of lb02.6c/laz.6c/02-2.6c |
$4800..$4BFF | 1K | from $0400..$07FF of lb02.5c/laz.5c/02-3.5c | from $0400..$07FF of lb02.5c/laz.5c/02-3.5c |
$4C00..$4FFF | 1K | from $0400..$07FF of lb02.3c/laz.3c/02-4.3c | from $0400..$07FF of lb02.3c/laz.3c/02-4.3c |
$5000..$53FF | 1K | from $0400..$07FF of lb02.2c/laz.2c/02-5.2c | from $0400..$07FF of lb02.2c/laz.2c/02-5.2c |
$5400..$5FFF | 3K | mirror of $1400..$1FFF? | mirror of $1400..$1FFF? |
$6000..$63FF | 1K | from $0400..$07FF of lb02.7b/laz.7b/02-6.7b | from $0400..$07FF of lb02.7b/laz.7b/02-6.7b |
$6400..$67FF | 1K | from $0400..$07FF of lb02.6b/laz.6b/02-7.6b | from $0400..$07FF of lb02.6b/laz.6b/02-7.6b |
$6800..$6BFF | 1K | from $0400..$07FF of lb02.5b/laz.5b/02-8.5b | from $0400..$07FF of lb02.5b/laz.5b/02-8.5b |
$6C00..$6FFF | 1K | from $0400..$07FF of lb02.3b/laz.3b/02-9.3b | from $0400..$07FF of lb02.3b/laz.3b/02-9.3b |
$7000..$73FF | 1K | from $0C00..$0FFF of lb02.2b/laz10-62.2b/02-10-11.2b | from $0C00..$0FFF of lb02.2b/laz10-62.2b/02-10-11.2b |
$7400..$77FF | 1K | mirror of $1400..$17FF? | mirror of $1400..$17FF? |
$7800..$7BFF | 1K | mirror of $1800..$1BFF? | from $0400..$07FF of laz10-62.2b |
$7C00..$7FFF | 1K | mirror of $1C00..$1FFF? | mirror of $1C00..$1FFF? |
Extended I/O port $02 is multiplexed among four inputs. The games write to extended I/O port $06 to control which input is selected. The input ports are (all active low):
Input | Bit(s) | Laser Battle | Lazarian |
$00 | 7 | Button 4 (0=pressed, 1=unpressed) | Button 4 (0=pressed, 1=unpressed) |
$00 | 6 | Button 3 (0=pressed, 1=unpressed) | Button 3 (0=pressed, 1=unpressed) |
$00 | 5 | Button 2 (0=pressed, 1=unpressed) | Button 2 (0=pressed, 1=unpressed) |
$00 | 4 | Button 1 (0=pressed, 1=unpressed) | Button 1 (0=pressed, 1=unpressed) |
$00 | 3 | Service A (0=pressed, 1=unpressed) | Service A (0=pressed, 1=unpressed) |
$00 | 2 | Coin B (0="pressed", 1="unpressed") | Coin B (0="pressed", 1="unpressed") |
$00 | 1 | P2 start (0=pressed, 1=unpressed) | P2 start (0=pressed, 1=unpressed) |
$00 | 0 | P1 start (0=pressed, 1=unpressed) | P1 start (0=pressed, 1=unpressed) |
$10 | 7 | Reset (0="pressed", 1="unpressed") | Reset (0="pressed", 1="unpressed") |
$10 | 6 | Coin A (0="pressed", 1="unpressed") | Coin A (0="pressed", 1="unpressed") |
$10 | 5 | ? | ? |
$10 | 4 | ? | ? |
$10 | 3 | ? | ? |
$10 | 2 | ? | ? |
$10 | 1 | ? | ? |
$10 | 0 | ? | ? |
$20 | 7 | Collision detection (0=off, 1=on) | Collision detection (0=off, 1=on) |
$20 | 6 | Infinite lives (0=off, 1=on) | Calibration display (0=off, 1=on) |
$20 | 5..4 | Lives:
%00 = 2 lives %01 = 3 lives %10 = 5 lives %11 = 6 lives | Lives:
%00 = 2 lives %01 = 3 lives %10 = 4 lives %11 = 5 lives |
$20 | 3..2 | Coin B generosity:
%00 = 2 credits %01 = 3 credits %10 = 5 credits %11 = 7 credits | Coin B generosity:
%00 = 2 credits %01 = 3 credits %10 = 5 credits %11 = 7 credits |
$20 | 1..0 | Coin A generosity:
%00 = 1 credit %01 = 2 credits %10 = 3 credits %11 = 5 credits | Coin A generosity:
%00 = ½ credit %01 = 1 credit %10 = 2 credits %11 = 3 credits |
$30 | 7 | Joystick down (0=yes, 1=no) | Joystick down (0=yes, 1=no) |
$30 | 6 | Joystick up (0=yes, 1=no) | Joystick up (0=yes, 1=no) |
$30 | 5 | Joystick right (0=yes, 1=no) | Joystick right (0=yes, 1=no) |
$30 | 4 | Joystick left (0=yes, 1=no) | Joystick left (0=yes, 1=no) |
$30 | 3 | ? | ? |
$30 | 2 | ? | Freeze (0=off, 1=on) |
$30 | 1 | ? | Firing (0=rapid, 1=normal) |
$30 | 0 | ? | ? |
Zaccaria Pinball for Android
Here is how to run the latest version of Zaccaria Pinball (on Android 4.4+), with all tables. Unfortunately an internet connection is required during play and there is only one ball (man/life) per game.
1. Go to https://d.apkpure.com/b/XAPK/hu.magicpixel.Zaccaria?versionCode=25 which will download Zaccaria Pinball_4.0.3_APKPure.apkx (1,049,698,248 bytes).
2. Rename Zaccaria Pinball_4.0.3_APKPure.apkx as Zaccaria Pinball_4.0.3_APKPure.zip
3. Extract this ZIP.
4. Make a new directory (folder): Internal storage/Android/obb/hu.magicpixel.Zaccaria
5. Move main.25.hu.magicpixel.Zaccaria.obb from wherever it was unZIPped to (typically Downloads), to Internal storage/Android/obb/hu.magicpixel.Zaccaria
6. Install hu.magicpixel.Zaccaria.apk as normal (by clicking on it).
Zaccaria Pinball for Switch
Here is how to emulate the Switch version of Zaccaria Pinball on 64-bit Windows 11 (at least), with all tables. Unfortunately the emulator crashes a lot, so perhaps an alternative emulator should be used instead (but Yuzu EA 4176 has similar issues).
1. Download the emulator + keys + firmware package: Nintendo Switch Emulator ryujinx 1.1.1403 win x64.torrent .
2. Extract ryujinx-1.1.1403-win_x64.rar to eg. C:\EMULATORS .
If WinRAR complains that the file is corrupt, your WinRAR version is
probably too old (eg. WinRAR 3.62 and earlier are definitely too old);
you will need to download and install a more recent version of WinRAR
from https://www.rarlab.com .
3. Extract prod.keys and title.keys from Prodkeys.net_v19.0.0.zip to C:\Users\username\AppData\Roaming\Ryujinx\system , replacing username with your username.
4. Make a directory C:\EMULATORS\ryujinx-1.1.1403-win_x64\BIOS and extract all files from Firmware 19.0.0.zip to there.
5. Download Zaccaria Pinball [010092400A678000]+[v1.0.4+72DLC][US]_Patched.xci.rar (1,370,161,805 bytes) from https://send.cm/u79fqcimms2j.
6. Make a directory C:\EMULATORS\ryujinx-1.1.1403-win_x64\GAMES and extract Zaccaria Pinball [010092400A678000]+[v1.0.4+72DLC][US](nsw2u)_Patched.xci into it.
7. Click "Options|Settings...|User Interface|Game Directories|Add...", choose C:\EMULATORS\ryujinx-1.1.1403-win_x64\GAMES and click OK.
8. Right-click the Zaccaria Pinball icon, click "Manage Title Updates", click "Bundled: Version 1.0.4", click "Save".
9. Right-click the Zaccaria Pinball icon, click "Manage DLC", click "Enable All", click "Save".
10. Double-click the Zaccaria Pinball icon to run the game.
Pull the plunger back and release to launch the ball. Click the left or right side of the screen to operate the appropriate flipper.
Zaccaria Pinball for Windows
Here is how to run the latest version of Zaccaria Pinball (on Windows 7/8/8.1/10/11), which otherwise would require Steam, without Digital Restrictions Management (DRM) and with all tables:
1. Download Zaccaria_Pinball_v20220905_Steam_RiP from
https://filecrypt.cc/Container/066D918234.html .
Extract it all to somewhere (eg. C:\GAMES\ZACCARIA). The password is cs.rin.ru .
If WinRAR complains that the file is corrupt, your WinRAR version is
probably too old (eg. WinRAR 3.62 and earlier are definitely too old);
you will need to download and install a more recent version of WinRAR
from https://www.rarlab.com .
2. Download Zaccaria_Pinball_v20220905_Cracks_Only from
https://filecrypt.cc/Container/C2CFA101D4.html .
Extract everything from SSE_v1.4.3 directory into the same directory as
previously (thus overwriting ZaccariaPinball.exe and steam_api.dll).
The password is cs.rin.ru .
3. Optionally, you can create a desktop shortcut as follows:
3a. Click on an empty part of the desktop, right-click and choose
"New|Shortcut".
3b. Click "Browse...".
3c. Navigate to where SmartSteamLoader.exe is located (eg.
C:\GAMES\ZACCARIA), click the SmartSteamLoader.exe file, and click
"OK".
3d. Click "Next...".
3e. Change the shortcut name to eg. "Zaccaria Pinball" or whatever and
press ENTER.
4. If you want a better icon for the shortcut:
4a. Download the icon from
https://cdn.cloudflare.steamstatic.com/steamcommunity/public/images/apps/444930/08bf6c6da88227cce20ef9e1993f128235a8a46f.ico
(or "Save as.." the icon here on the right)
into the same directory as SmartSteamLoader.exe (C:\GAMES\ZACCARIA or wherever).
4b. Click on the shortcut, right-click and choose "Properties".
4c. Click "Change Icon...".
4d. Click "Browse...".
4e. Double-click the 08bf6c6da88227cce20ef9e1993f128235a8a46f.ico file.
4f. Click "OK" twice.
5. At this point, you may be able to run SmartSteamLoader.exe to launch the game. If this does not work, undertake the below steps as necessary.
6. If you get errors about missing MSVCP100.dll and/or MSVCR100.dll files,
or error 0xc000007b, you need either of these (your choice):
6a. Microsoft Visual C++ 2008 Redistributable Package (4,483,040 bytes)
from
https://download.microsoft.com/download/5/D/8/5D8C65CB-C849-4025-8E95-C3966CAFD8AE/vcredist_x86.exe. Run the installer.
Or:
6b. Microsoft Visual C++ 2010 SP1 Redistributable Package MFC Security
Update (8,993,774 bytes) from
https://download.microsoft.com/download/1/6/5/165255E7-1014-4D0A-B094-B6A430A6BFFC/vcredist_x86.exe. Run the installer and choose the "Repair" option.
(You need the x86 (32-bit) version even if you have an x64 (64-bit) CPU.)
7. If you get errors about missing OpenAL32.dll, you need OpenAL.
You can get this from https://openal.org/downloads/oalinst.zip.
Extract oalinst.exe anywhere and run it.
Links were valid as at January 2023. The support thread is at https://cs.rin.ru/forum/viewtopic.php?f=10&t=72437&e=0. If any links are no longer working, please advise; we have copies of all files archived.
Pinball games using a 2650 and/or made by Zaccaria:
Name | Company | Year | MAME | ZP | Bonus | CPU(s) |
Aerobatics | Zaccaria | 1977 | No | Yes | ? | None |
Black Belt | Zaccaria | 1986 | 0% | Yes | Yes | 2650 |
Cinestar | Zaccaria | 1974 | No | Yes | ? | None |
Circus (pinball) | Zaccaria | 1977 | No | Yes | ? | None |
Clown (pinball) | Zaccaria | 1985 | 0% | Yes | Yes | 2650 |
Combat (pinball) | Zaccaria | 1977 | No | Yes | ? | None |
Devil Riders | Zaccaria | 1984 | 0% | Yes | Yes | 2650 |
Earth, Wind, Fire | Zaccaria | 1981 | 0% | Yes | Yes | 2650+8035 |
Farfalla | Zaccaria | 1983 | 0% | Yes | Yes | 2650 |
Fire Mountain | Zaccaria | 1980 | 0% | Yes | No | 2650 |
Future World | Zaccaria | 1978 | 0% | Yes | No | 2650 |
Granada | Zaccaria | 1974 | No | Yes | ? | None |
Hot Wheels | Zaccaria | 1979 | 0% | Yes | No | 2650 |
House of Diamonds | Zaccaria | 1978 | 0% | Yes | No | 2650 |
Locomotion | Zaccaria | 1981 | 0% | Yes | Yes | 2650+8035 |
Lucky Fruit | Zaccaria | 1975 | No | Yes | ? | None |
Magic Castle | Zaccaria | 1984 | 0% | Yes | Yes | 2650 |
Mexico '86 | Zaccaria | 1986 | 0% | Yes | Yes | 2650 |
Moon Flight | Zaccaria | 1976 | No | Yes | ? | None |
Mystic Star | Zaccaria | 1986 | 0% | Yes | No | 6800 |
Nautilus | Zaccaria | 1977 | No | Yes | ? | None |
New Star's Phoenix | Zaccaria | 1987 | 0% | No | ? | 2650 |
Pinball Champ '82 | Zaccaria | 1982 | No | Yes | Yes | ? |
Pinball Champ '83 | Zaccaria | 1983 | 0% | Yes | Yes | 2650 |
Pool Champion | Zaccaria | 1985 | 0% | Yes | Yes | 2650 |
Red Show | Zaccaria | 1975 | No | Yes | ? | None |
Robot | Zaccaria | 1985 | 0% | Yes | Yes | 2650 |
Scramble (pinball) | Tecnoplay | 1987 | 0% | No | ? | 2650 |
Shooting the Rapids | Zaccaria | 1979 | 0% | Yes | No | 2650 |
Ski Jump (prototype) | Zaccaria | 1978 | 0% | No | ? | SC/MP |
Soccer Kings | Zaccaria | 1982 | 0% | Yes | Yes | 2650 |
Space City (prototype) | Zaccaria | 1979 | 0% | No | ? | SC/MP |
Space Shuttle | Zaccaria | 1980 | 0% | Yes | No | 2650+8035 |
Spooky | Zaccaria | 1987 | 0% | Yes | Yes | 2650 |
Star God | Zaccaria | 1980 | 0% | Yes | No | 2650 |
Star's Phoenix | Zaccaria | 1987 | 0% | Yes | Yes | 2650 |
Strike | Zaccaria | 1978 | 0% | Yes | No | SC/MP |
Supersonic | Zaccaria | 1977 | No | Yes | ? | None |
Thunder Man | Apple Time | 1987 | 0% | No | ? | 2650 |
Time Machine | Zaccaria | 1983 | 0% | Yes | Yes | 2650 |
Top Hand | Zaccaria | 1974 | No | Yes | ? | None |
Tropical | Zaccaria | 1974 | No | Yes | ? | None |
Universe | Zaccaria | 1977 | No | Yes | ? | None |
Winter Sports (pinball) | Zaccaria | 1978 | 0% | Yes | No | 2650 |
Wood's Queen | Zaccaria | 1976 | No | Yes | ? | None |
Zankor | Zaccaria | 1986 | 0% | Yes | Yes | 2650 |
MAME: MAME 0.277.
ZP: Zaccaria Pinball v20220905.
Bonus: whether the table has an annoying time-limited bonus ball.
1974-1977 games are electro-mechanical ("EM").
1978-1981 games are 1st generation solid state ("SS").
1982-1987 games are 2nd generation solid state ("SS").
Multiplatform
Comparative Tables
Platform | Keyboard input | VDU output | Tape input | Tape output | Tape format | Motor control |
![]() | Memory mapped | Memory mapped | n/a | n/a | n/a | n/a |
![]() | Memory mapped | Memory mapped | n/a | n/a | n/a | n/a |
![]() | Memory mapped | Memory mapped | 1515+ baud raw via CASIN | 1515+ baud raw via CASOUT | EOF | No |
![]() | 110 baud teletype via Sense | 110 baud teletype via Flag | 110 baud CUTS via Sense | 110 baud CUTS via Flag | AOF | No |
![]() | 110/300 baud teletype via Sense | 110/300 baud teletype via Flag | 110/300 baud CUTS via Sense | 110/300 baud CUTS via Flag | AOF? | No? |
![]() | 300/600/1200 baud teletype? | 300/600/1200 baud teletype? | 300/600/1200 baud? | 300/600/1200 baud? | ? | ? |
![]() | 300 baud teletype via Sense | Memory mapped | ? | ? | ? | Yes, with ACOS |
![]() | Memory mapped | ? | ? baud via Sense | ? baud via extended I/O port $F8 | AOF | No? |
![]() | Parallel keyboard via Data port | Memory mapped, 80*16 characters
Monochrome | 300* baud CUTS via Sense
clear bit = 4 cycles of 1200Hz set bit = 8 cycles of 2400Hz | 300* baud CUTS via Flag
clear bit = 4 cycles of 1200Hz set bit = 8 cycles of 2400Hz | AOF | Yes |
![]() | ? | Memory mapped, 64*32 characters
8-level greyscale | ? | ? | ? | ? |
![]() | Parallel keyboard via port $07 | Ports $1B & $1C | 110 baud CUTS? via Sense | 110 baud CUTS? via Flag | ? | Yes |
* The 4.73 MHz (approx.) version of the Central Data 2650 operates at 1200 instead of 300 baud.
Platform | Drives | Size | Tracks | Track size | Sectors/track | Sector size | Sectors | Capacity | Format(s) | Dir sectors | DOS sectors | Max files | Controller | RPM | Speed |
![]() | 0+ | 5.25" | 40 (0..39) | 2.5K | 10 (1..10) | 256 bytes | 400 | 100K | RAW | 10 | 3 | 100 | 1 MHz FD1771 | 300 | 12.5K/sec |
![]() | 0-4 | 5.25" | 35 (0..34) | 2.25K | 9 (1..9) | 256 bytes | 315 | 78.75K | RAW | 18 | 128 | 64 | 1 MHz FD1771 | 300 | 11.25K/sec |
![]() | 2 | 8" | 77 (0..76) | 4K | 32 (0..31) | 128 bytes | 308 | 308K | IMG, TWIN | 4 | 27 | 78 | ? | 360 | 24K/sec |
Speed = bytes per sector * sectors per track * revolutions per second.
(Speed of reading/writing processed bytes, assuming an infinitely fast CPU.)
Data is stored on the bottom (ie. non-label) side of a single-sided disk
(the read-write head of a single-sided drive is on the bottom).
Viewing the disk from below (ie. viewing the data side),
the disk spins clockwise (thus sectors are numbered anticlockwise).
The drive motor on 8" floppy drives runs on 230V AC and is always on.
The drive is kept spinning at all times. The head is unloaded when idle,
but the disk is always spinning within its sleeve.
The drive motor on 5.25" floppy drives is turned on and off as required.
.RAW files are raw disk files of 100K (102,400 bytes) (BINBUG) or 78.75K
(80,640 bytes) CD2650), lacking sector and block numbers.
.IMG files are raw disk files of 308K (315,392 bytes), lacking sector and
block numbers.
.TWIN files are disk files of 320,320 bytes, the same as .IMG except that
each 128-byte sector is prepended with the track and sector numbers (thus
becoming 130 bytes per sector).
Printer | ![]() ![]() | ![]() |
Condensed width | 32 columns * 8 dots = 256 dots | 132 columns |
Normal width | 32 columns * 8 dots = 256 dots | 80 columns |
Expanded width | 16 columns * 16 dots = 256 dots | ? |
Speed | 2 lines/sec (512 dots/sec) | ? |
Paper size (printable area) | ? cm * 60 m | 2.5..8" * 11" |
Paper size (total) | 6 cm * 60 m | 4..9.5" * 11" |
Horizontal characters per inch (condensed mode) | ? | 16.5 |
Horizontal characters per inch (normal mode) | ? | 10 |
Vertical characters per inch | ? | 6 |
BIOS/DOS command cross-reference:
CPU: | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | Ami/WinArcadia | ||
See & alter IAR | PC | REG C | PC | J|JUMP | ||||||
See & alter PSU | REG | S 7 | S7 | REG 7 | SEt PSU | I8 | CMD A | E|POKE PSU | ||
See & alter PSL | REG | S 8 | S8 | REG 8 | SEt PSL | I7 | CMD A | E|POKE PSL | ||
See & alter registers | REG | S 0..6 | S0..S6 | REG 0..6 | SEt R0..R6 | I0..I6 | CMD A | E|POKE R0..R6 | ||
Set slave CPU mode | Ice | |||||||||
Memory: | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | Ami/WinArcadia |
Compare (verify) memory | V | COMP | ||||||||
Copy (move) memory | MOVe | M | NXT | COPY|MOVE | ||||||
Dump memory to screen | D address1 address2 | Dump | I | D|PEEK | ||||||
Fill memory | Fill | P | FILL | |||||||
Patch memory | REG F | Patch | : | |||||||
See & alter memory | MEM | A address | A | MEM | Exam
WRite | A | : | NXT | Read | E|POKE
D|PEEK |
Program control: | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | Ami/WinArcadia |
Abort program | Abort | |||||||||
Cold start DOS | K | |||||||||
Continue program | Cont | G|P | ||||||||
Execute program | START | G address | G | RUN | Go | E (supervisor)
EXEC (CD DOS) | G | RUN
GOTO PC | Go | G|P |
Generate an interrupt | INT | GI | ||||||||
Reset machine | RST | RST
MON | F5 key | |||||||
Step instruction | STEP | S | ||||||||
Suspend program | Suspend | G|P | ||||||||
Warm start DOS | W | |||||||||
Debugging: | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | Ami/WinArcadia |
Clear breakpoint | BP | C 1|2 | C | BKPT | CLBp | C | BP1/2 | CMD C | BC | |
Load debugger | DEBug | |||||||||
Relocate debug utility programs | Upr | |||||||||
Set breakpoint | BP | B 1|2 address | B | BKPT | BKpt | B | BP1/2 | CMD B | Halt | BP |
Set trace mode | TRace | T | ||||||||
Show status of debugger | DStat | V|VIEW CPU
BL, IL, WL | ||||||||
Show status of slave program | STatus | |||||||||
Tapes: | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ||
Adjust tape | REG A | |||||||||
Issue MDCR command | T | |||||||||
Load memory as AOF/EOF from tape | RCAS | L | L | RCAS | L | R | CMD F | Load | ||
Run tape recorder | R | |||||||||
Save (dump) memory as AOF/EOF to tape | WCAS | D address1 address2 | D | WCAS | D | W | CMD D | Store | ||
Verify (check) tape | V | CMD E | ||||||||
Disks: | ![]() | ![]() | Ami/WinArcadia | |||||||
Copy disk | DUP | DISKCOPY | ||||||||
Format (initialize) disk | FORMAT | |||||||||
List files on disk | Ldir | LIST | DIR | |||||||
List open files | LOPEN | |||||||||
Raw read | DISKRD | |||||||||
Raw write | DISKWR | |||||||||
Relabel disk | REName | |||||||||
Reset disk drives | RESTORE | |||||||||
Set default drive | DUNIT | |||||||||
Set system drive | SYstem | |||||||||
Show free disk space | Ldir | FREE | DIR | |||||||
Show (inspect) raw sector(s) | INSPECT | |||||||||
Verify (check) disk | Verify | |||||||||
Files on disk: | ![]() | ![]() | Ami/WinArcadia | |||||||
Assemble source code | ASM | ASM | ||||||||
Compare files | CMPf | |||||||||
Copy file(s) | COPy | |||||||||
Delete file | DELete | DELETE | DEL | |||||||
Dump file (to screen) as hex and ASCII | DFil | |||||||||
Edit file on disk | EDIT | |||||||||
Load (read) AOF file from device | Rhex | |||||||||
Load (read) IMAG file from disk | LOAD | |||||||||
Load (read) & run IMAG file from disk | RUN | |||||||||
Load (read) binary? file from disk | READ | |||||||||
Load (read) MOD file from device | LOad | |||||||||
Load (read) & run MOD file from device | XEQ | |||||||||
Rename file | REName | RENAME | ||||||||
Print file without line numbers | ||||||||||
Print file with line numbers | PRINTL | |||||||||
Reserve disk space for a new file | ALLOC | |||||||||
Save (write) AOF file to device | WHex | |||||||||
Save (write) binary? file to disk | WRITE | |||||||||
Save (write) MOD file to device | Module | |||||||||
Save (write) IMAG file to disk | IMAGE | |||||||||
Set change code on file | CCODE | |||||||||
Set inspection code on file | ICODE | |||||||||
Truncate file | DEALLOC | |||||||||
Channels: | ![]() | ![]() | ||||||||
Assign device to channel | ASSign | |||||||||
Close channel/file | CLose | CLOSE | ||||||||
Inform OS of peripheral availability | DEVice | |||||||||
Open file | OPEN | |||||||||
PROMs: | ![]() | ![]() | ||||||||
Compare PROM against slave memory | CProm | |||||||||
Compare SMS file against slave memory | CSms | |||||||||
Punch memory as BPNF file to papertape | Punch | |||||||||
Read/write/verify PROM | PROm | |||||||||
Read PROM into slave memory | RProm | |||||||||
Write slave memory to PROM | WProm | |||||||||
Save (write) SMS file to device | WSms | |||||||||
Command (script) files: | ![]() | |||||||||
Comment | * | |||||||||
Toggle termination condition | Kill | |||||||||
Toggle echoing | TYpe | |||||||||
Memory banks: | ![]() | |||||||||
"Q" bank select/execute | Q | |||||||||
"U" bank select/execute | U | |||||||||
Show selected banks | = | |||||||||
I/O ports: | ![]() | Ami/WinArcadia | ||||||||
Read from I/O port | REad | READPORT | ||||||||
Write to I/O port | WRite | WRITEPORT | ||||||||
Miscellaneous: | ![]() | ![]() | ![]() | Ami/WinArcadia | ||||||
Log in/on | SIGNON | |||||||||
Set date | DATE | |||||||||
Set default file type | DTYPE | |||||||||
Set default codeword | ENTER | |||||||||
Show date | WHEN | |||||||||
Show error message | S | ERROR | ||||||||
Show OS ID | X |
Letters in lowercase are optional.
Timing table:
Area | ![]() | ![]() ![]() ![]() | ![]() | ![]() | ![]() | ![]() | ![]() |
Horizontal back porch (pre-colourburst) | -17..-16/32..33 (2) | -21..-19/28..30 (3) | ? | - | 58..65 (8) | ? | ? |
Horizontal back porch (colourburst) | -15..-7/34..42 (9) | -18..-10/31..39 (9) | ? | - | 66..81 (16) | ? | ? |
Horizontal back porch (post-colourburst) | -6..-1/43..48 (6) | -9..-1/40..48 (9) | ? | - | 82..127 (46) | ? | ? |
Horizontal back porch (total) | -17..-1/32..48 (17) | -21..-1/28..48 (21) | 702?..767 (66?) | 776..903 (128) | 58..127 (70) | 0..26 (27) | 0..26 (27) |
Main display area (horizontal) | 0..177,-49..-40/49..226,0..9 (188) | 0..177,-49..-44/49..226,0..5 (184) | 0..575 (576) | 0..639 (640) | 128..511 (384) | 27..99 (73) | 27..99 (73) |
Horizontal front porch | -39..-35/10..14 (5) | -43..-39/6..10 (5) | 576..641? (66?) | 640..711 (72) | 0..25 (26) | 100..115 (16) | 100..115 (16) |
Horizontal retrace | -34..-18/15..31 (17) | -38..-22/11..27 (17) | 642?..701? (60?) | 712..775 (64) | 26..57 (32) | 116..127 (12) | 116..127 (12) |
Total (horizontal) | -49..177/0..226 (227) | -49..177/0..226 (227) | 0..767 (768) | 0..903 (904) | 0..511 (512) | 0..127 (128) | 0..127 (128) |
Vertical back porch | -14..-1 (14) | -28..-1 (28) | ~286.5?..312.5 (~26?) | 228..263 (36) | 273..312 (40) | 0..41 (42) | 0..43 (44) |
Main display area (vertical) | 0..241 (242) | 0..268 (269) | 0..255 (256) | 0..191 (192) | 0..255 (256) | 42..233 (192) | 44..275 (232) |
Vertical front porch | -20..-18 (3) | -43..~-30.5 (~13.5) | 256..281? (26?) | 192..215 (24) | 256..268 (13) | 234..257 (24) | 276..305 (30) |
Vertical retrace | -17..-15 (3) | ~-30.5..-29 (~2.5) | 282?..~286.5? (~4.5?) | 216..227 (12) | 269..272 (4) | 258..261 (4) | 306..311 (6) |
Total (vertical) | 0..261 (262) | 0..311 (312) | 0..311.5 (312.5) | 0..263 (264) | 0..312 (313) | 0..261 (262) | 0..311 (312) |
Main display | 188*242=45,496 | 188*269=50,572 | 576*256=147,456 | 640*192=122,880 | 384*256=98,304 | 73*192=14,016 | 73*232=16,936 |
Entire display | 227*262=59,474 | 227*312=70,824 | 768*312.5=240,000 | 904*264=238,656 | 512*313=160,256 | 128*262=33,536 | 128*312=39,936 |
Lines per second (method A) | 60*262=15,720 | 50*312=15,600 | 50*312.5=15,625 | 60*264=15,840 | 50*313=15,650 | 60*262=15,720 | 50*312=15,600 |
Lines per second (method C) | ~60.18672*262= ~15,768.92064 | ~50.08041*312= ~15,625.08792 | ?*312.5=? | ?*264=? | ?*313=? | ?*262=? | ?*312=? |
Line duration (µS) (method A) | 1,000,000÷15,720= ~63.61323 | 1,000,000÷15,600= ~64.10256 | ? | ? | ? | ? | ? |
Line duration (µS) (method C) | 1,000,000÷~15,768.92064= ~63.41588 | 1,000,000÷~15,625.08792= ~63.99964 | ? | ? | ? | ? | ? |
Pixel duration (nS) (method A) | 16.666'÷59,474=~280.23450 | 20,000÷70,824=~282.39015 | ? | ? | ? | ? | ? |
Pixel duration (nS) (method C) | 1÷3,579,545=~279.36511 | 1÷3,546,895=~281.93674 | ? | ? | ? | ? | ? |
Pixels per CPU cycle | 4 | 4 | 12 | 12 | 8 | ∞ | ∞ |
CPU cycles per frame | 59,474÷4=14,865.5 | 70,824÷4=17,706 | 240,000÷12=20,000 | 238,656÷12=19,888 | 160,256÷8=20,032 | - | - |
Pixels per second (method A) | 59,474*60=3,568,440 | 70,824*50=3,541,200 | 240,000*50=12,000,000 | 238,656*60=14,319,360 | 160,256*50=8,012,800 | 33,536*60=2,012,160 | 39,936*50=1,996,800 |
Pixels per second (method B) | 227÷64=3,546,875 | 227÷64=3,546,875 | 768÷64=12,000,000 | 904÷64=14,125,000 | 512÷64=8,000,000 | 128÷64=2,000,000 | 128÷64=2,000,000 |
Pixels per second (method C) | 3,579,545 (+/- 10) | 3,546,895 (+/- 35) | ? | 14,192,640 | ? | ? | ? |
CPU speed (Hz) (method A) | 3,568,440÷4=892,110 | 3,541,200÷4=885,300 | 12,000,000÷12=1,000,000 | 14,319,360÷12=1,193,280 | 8,012,800÷8=1,001,600 | - | - |
CPU speed (Hz) (method B) | 227÷4÷64=886,718.75 | 227÷4÷64=886,718.75 | 768÷12÷64=1,000,000 | 904÷12÷64=1,177,083' | 512÷8÷64=1,000,000 | - | - |
CPU speed (Hz) (method C) | 3,579,545÷4=894,886.25 | 3,546,895÷4=886,723.75 | ? | 14,192,640÷12=1.18272 | ? | - | - |
Frames per second (method A) | 60÷1.001=~59.94 (NTSC) | 50 (PAL) | 50 (PAL) | 60÷1.001=~59.94 (NTSC) | 50 (PAL) | 60÷1.001=~59.94 (NTSC) | 50 (PAL) |
Frames per second (method B) | 3,546,875 ÷59,474=~59.63740 | 3,546,875 ÷70,824=~50.08013 | 12,000,000 ÷240,000=50 | 14,125,000 ÷238,656=~59.18561 | 8,000,000 ÷160,256=~49.92013 | 2,000,000 ÷33,536=~59.63740 | 2,000,000 ÷39,936=~50.08013 |
Frames per second (method C) | 3,579,545 ÷59,474=~60.18672 | 3,546,895 ÷70,824=~50.08040 | ? | 14,192,640 ÷238,656=~59.46903 | ? | ? | ? |
Frame duration (µS) (method A) | 1,000,000÷60= 16,666.6' | 1,000,000÷50= 20,000 | ? | 1,000,000÷60= 16,666.6' | ? | ? | ? |
Frame duration (µS) (method C) | 1,000,000÷~60.18672= ~16,614.96084 | 1,000,000÷~50.08040= ~19,967.88741 | ? | 1,000,000÷~59.46903= ~16,815.47619 | ? | ? | ? |
Astro Wars and Lazarian, although they use PAL USGs (2621), have NTSC master clocks
(14,318,180 Hz ÷ 4 = 3,579,545 Hz and 14,318,000 Hz ÷ 4 = 3,579,500 Hz, respectively).
To calculate pixels per µsec:
Divide width of screen (eg. 227) by duration of line (64 µsecs) = 3.546875 pixels per µsec.
To calculate µsecs per pixel:
Divide duration of line (64 µsecs) by width of screen (eg. 227) = 0.281938 µsecs per pixel (datasheet says 282 nsecs).
Method A assumes exactly 50/60 frames per second, and calculates all timings relative to that. (60÷1.001 would be more accurate than 60 for
colour NTSC.)
Method B assumes exactly 64 µsecs per rastline, and calculates all timings relative to that.
Method C uses the master clock frequency as documented in eg. service manual, and calculates all timings relative to that.
This is the most accurate method.
Measured 2622 USG output from a real NTSC console indicates that a frame lasts for about 16,615.2 µS, giving a derived FPS of about 60.18585.
The USG generates a single sync pulse (lasting for 227*3=681 X-pixels for NTSC or 114+227+227+11=579 X-pixels for PAL), known as block sync, rather than a train of long and short pulses, known as commercial sync, which is/was typically used for TV broadcasts).
USG signals are:
Abbrev. | Name | Description |
CSYNC | Composite Sync | high whenever VS equals HS (ie. whenever both are low, or both are high).
high during visible area and blanking low during HS low during VS high during HS+VS |
VRST | Vertical Reset | high from X,Y-pixel 10,1..9,20 (NTSC) or 6,1..5,43 (PAL) (ie. during vertical blank). |
CBLNK | Composite Blanking | high whenever HRST or VRST (or both) is high. |
? | ? | high whenever HRST or VRST (or both) is high, except during CBF. |
CBF | Colour Burst Flag | high from X-pixel 34..42 (NTSC) or 31..39 (PAL) (ie. during colour burst). |
HRST | Horizontal ReSeT | high from X-pixel 10..48 (NTSC) or 6..48 (PAL) (ie. during horizontal blank). |
PCK | horizontal Position ClocK | high during the left half of each pixel, low during the right half. |
OE | Odd/Even line | high during even-numbered rastlines (assuming X >= 23 (NTSC) or X >= 19 (PAL)).
toggles at X-pixel 23 (NTSC) or 19 (PAL) of each line (ie. midway through horizontal retrace). |
HS | Horizontal Sync | high from X-pixel 15..31 (NTSC) or 11..27 (PAL) (ie. during horizontal retrace). |
VS | Vertical Sync | high from X,Y-pixel 32,3..31,5 (NTSC) or 113,12..10,15 (PAL) (ie. during vertical retrace). |
Standard TV broadcasts vs. USG output:
Standard | 480i (NTSC) | 240p (NTSC) | 2622 USG | 576i (PAL) | 288p (PAL) | 2621 USG |
1st field visible lines | 240 | 240 | 242 | 288 | 288 | 269 |
1st field blanking lines | 22½ | 22 | 20 | 24½ | 24 | 43 |
2nd field visible lines | 240 | 240 | 242 | 288 | 288 | 269 |
2nd field blanking lines | 22½ | 22 | 20 | 24½ | 24 | 43 |
Lines per frame | 525 | 524 | 524 | 625 | 624 | 624 |
2650 CPU
Addressing mode notation (for eg. LODx instruction):
Addressing Mode | Signetics Format | Signetics Example | CALM Format | CALM Example | IEEE-694 Format | IEEE-694 Example | ||||||
Register | LODZ | reg | LODZ | r1 | LOAD | A,reg | LOAD | A,B | LD | .0,.reg | LD | .0.,1 |
Immediate | LODI,reg | imm | LODI,r0 | 12 | LOAD | reg,#imm | LOAD | A,#12 | LD | .reg,#imm | LD | .0,#12 |
Relative direct | LODR,reg | rel | LODR,r0 | 1234 | LOAD | reg,^rel | LOAD | A,^1234 | LD | .reg,$rel | LD | .0,$1234 |
Relative indirect | LODR,reg | *rel | LODR,r0 | *1234 | LOAD | reg,^@rel | LOAD | A,^@1234 | LD | .reg,$@rel | LD | .0,$@1234 |
Absolute direct | LODA,reg | abs | LODA,r0 | 1234 | LOAD | reg,abs | LOAD | A,1234 | LD | .reg,/abs | LD | .0,/1234 |
Absolute indirect | LODA,reg | *abs | LODA,r0 | *1234 | LOAD | reg,@abs | LOAD | A,@1234 | LD | .reg,/@abs | LD | .0,/@1234 |
Indexed direct | LODA,r0 | abs,reg | LODA,r0 | 1234,r1 | LOAD | A,(reg)+abs | LOAD | A,(B)+1234 | LD | .0,/abs(.reg) | LD | .0,/1234(.1) |
Indexed indirect | LODA,r0 | *abs,reg | LODA,r0 | *1234,r1 | LOAD | A,(reg)+@abs | LOAD | A,(B)+@1234 | LD | .0,/@abs(.reg) | LD | .0,/@1234(.1) |
Indexed direct with pre-increment | LODA,r0 | abs,reg+ | LODA,r0 | 1234,r1+ | LOAD | A,(+reg)+abs | LOAD | A,(+B)+1234 | LD | .0,/abs(+.reg) | LD | .0,/1234(+.1) |
Indexed indirect with pre-increment | LODA,r0 | *abs,reg+ | LODA,r0 | *1234,r1+ | LOAD | A,(+reg)+@abs | LOAD | A,(+B)+@1234 | LD | .0,/@abs(+.reg) | LD | .0,/@1234(+.1) |
Indexed direct with pre-decrement | LODA,r0 | abs,reg- | LODA,r0 | 1234,r1- | LOAD | A,(-reg)+abs | LOAD | A,(-B)+1234 | LD | .0,/abs(-.reg) | LD | .0,/1234(-.1) |
Indexed indirect with pre-decrement | LODA,r0 | *abs,reg- | LODA,r0 | *1234,r1- | LOAD | A,(-reg)+@abs | LOAD | A,(-B)+@1234 | LD | .0,/@abs(-.reg) | LD | .0,/@1234(-.1) |
Program Status Word (PSW) bits:
Register | Bit(s) | Readable/Writable | Signetics | CALM | IEEE-694 Letter | |||||
2650/2650A | 2650B | Name | Abbrev. | Letter | Name | Abbrev. | Letter | |||
PSU | 7 | R/- | Sense | S | S | Input | I | I | ? | |
PSU | 6 | R/W | Flag | F | F | Output | O | O | ? | |
PSU | 5 | R/W | Interrupt Inhibit | II | I | Interrupt mask bit | IOF | F | I | |
PSU | 4 | -/- | R/W | User Flag #1 | UF1 | 1 | User Flag #1 | UF1 | 1 | ? |
PSU | 3 | -/- | R/W | User Flag #2 | UF2 | 2 | User Flag #2 | UF2 | 2 | ? |
PSU | 2..0 | R/W | Stack Pointer | SP | - | Stack Pointer | SP | - | ? | |
PSL | 7..6 | R/W | Condition Code | CC | - | ? | ? | - | ? | |
PSL | 5 | R/W | Inter-Digit Carry | IDC | D | Half carry | H | H | ? | |
PSL | 4 | R/W | Register Select | RS | R | BANK1 | B | B | ? | |
PSL | 3 | R/W | With Carry | WC | W | WITHCARRY | W | W | ? | |
PSL | 2 | R/W | Overflow | OVF | O | OVERFLOW | V | V | V | |
PSL | 1 | R/W | Compare | COM | M | LOGICOMP | L | L | ? | |
PSL | 0 | R/W | Carry | C | C | CARRY | C | C | C |
Directive cross-reference (not all supported by the emulator):
Signetics | PB2 | TS1 | PRO | TW1 | TS2 | TW2 | CALM | IEEE-694 | Description |
ACON address
ACON address(es)... | No | Yes1 | Yes1 | Yes | Yes | Yes | - | - | Insert the given address(es) into the object |
- | No | No | No | No | No | No | .ALIGN value | - | Align assembler program counter to the next multiple of value |
- | No | No | No | No | No | No | .APC value | - | Select one of the assembler program counters |
ASCI string | Yes | No | No | No | No | No | .ASCII string | - | Insert the ASCII text in the object |
- | No | No | No | No | No | No | .ASCIZ string | - | Insert the ASCII text in the object, with ASCII NUL code at the end |
- | No | No | No | No | No | No | .ASCIZE string | - | Insert the ASCII text in the object, with ASCII NUL code at the end, and add pad byte if needed for even alignment |
CEJE rows | No | No | No | No | No | Yes | - | - | Conditionally commence a new page in the listing |
- | No | No | No | No | No | No | .CHAP string | - | Add the specified text in the subtitle header |
CSECT | No | No | No | No | No | Yes | - | - | Identify object module |
DATA byte(s)...
(DB byte(s)...) | No | Yes | Yes | Yes | Yes | Yes | .DATA.8 byte(s)...
.8 byte(s)... | DATA byte(s)...
DATAB byte(s)... | Insert the given byte(s) into the object |
(DFLT 0|1|10|16) | No | No | No | No | No | No | .BASE value | BASE B|Q|D|H | Set the default base |
- | No | No | No | No | No | No | .BLK.16 length | - | Add length words to the value of the assembler program counter |
- | No | No | No | No | No | No | .BLK.32 length | - | Add length longwords to the value of the assembler program counter |
(DW word(s)...) | No | No | No | No | No | No | .DATA.16 word(s)...
.16 word(s)... | DATAL word(s)... | Insert the given word(s) into the object |
- | No | No | No | No | No | No | .DATA.32 longword(s)...
.32 longword(s)... | - | Insert the given longword(s) into the object |
EJE
(PAGE) | No | Yes | Yes | Yes | Yes | Yes | .PAGE | PAGE | Commence a new page in the listing |
ELSE | No | No | No | Yes | Yes | Yes | .ELSE | - | Assemble up to corresponding .ENDIF, if condition was false |
END
END [address] | Yes2 | Yes | Yes | Yes | Yes | Yes | .END | END | End assembly (and optionally set program start address, for some assemblers) |
ENDIF | No | No | No | Yes | Yes | Yes | .ENDIF | - | End conditional assembly |
- | No | No | No | No | No | No | .ENDLIST | - | End conditional listing |
- | No | No | No | No | No | No | .ENDMACRO
.EXITMACRO | - | End macro definition |
ENDS | No | No | No | No | Yes | No | - | - | End segment |
- | No | No | No | No | No | No | .ENDTEXT | - | End comment block |
ENTRY symbol(s)... | No | No | No | No | Yes | Yes | .EXPORT symbol(s)... | - | Define the exported symbols |
symbol EQU value | No | Yes | Yes | Yes | Yes | Yes | (symbol .EQU value)
symbol = value | symbol EQU value | Define a symbol permanently |
- | No | No | No | No | No | No | .ERROR string | - | Generate an error message |
- | No | No | No | No | No | No | .EVEN | - | Align assembler program counter to the next even value |
EXTRN symbol(s)... | No | No | No | No | Yes | Yes | .IMPORT symbol(s)... | - | Define the imported symbols |
- | No | No | No | No | No | No | .FILL.8|16|32 length,value | - | Fill length bytes/words/longswords with value |
IF condition | No | No | No | Yes | Yes | Yes | .IF condition | - | Begin conditional assembly |
(INCLUDE filename) | No | No | No | No | No | No | .INS filename | - | Insert the mentioned source file |
- | No | No | No | No | No | No | .LAYOUT HEX|DEC|LENGTH rows|WIDTH columns|TAB columns|LEADING0 TRUE|FALSE|DEFFIRST|LSBFIRST|MSBFIRST | - | Define the general layout parameters for the listing |
- | No | No | No | No | No | No | .LAYOUTMACRO COMMENT|COMPRESS|ERROR|LIST|REPLACE [TRUE|FALSE] | - | Define the macro layout parameters for the listing |
LIBR string | No | No | Yes | No | No | No | - | - | Library directive (print message and wait for user keypress) |
- | No | No | No | No | No | No | .LIST condition | - | Begin conditional listing |
- | No | No | No | No | No | No | .LISTIF condition | - | Controls whether conditional assembly directives (.IF/.ELSE/.ENDIF) themselves appear in the listing |
- | No | No | No | No | No | No | .LOCALMACRO symbol(s)... | - | List of local symbols in a macro |
- | No | No | No | No | No | No | .MACRO name[,parameter(s)...] | - | Begin macro definition |
- | No | No | No | No | No | No | .ODD | - | Align assembler program counter to the next odd value |
ORG address | Yes | Yes | Yes | Yes | Yes | Yes | .LOC address | ORG address | Set current assembler program counter |
PCH ON|OFF | No | Yes | Yes | Yes | Yes | Yes | - | - | Resume or discontinue punching papertape |
- | No | No | No | No | No | No | .PROC filename | - | Insert the mentioned processor description (eg. .PROC S2650 ) |
- | No | No | No | No | No | No | .PROCSET parameter | - | Enable a processor feature |
- | No | No | No | No | No | No | .PROCVAL parameter value | - | Set a named parameter with a specific value |
PRT ON|OFF
PRT ON|OFF|GEN|NOGEN | No | Yes3 | Yes3 | Yes3 | Yes3 | Yes | - | - | Resume or discontinue printing |
- | No | No | No | No | No | No | .RANGE.8|16|32 min,max | - | Define the range of values permitted for .DATA, .FILL, etc. |
- | No | No | No | No | No | No | .REF filename | - | Insert the mentioned symbol table |
REPRO | No | No | No | No | No | Yes | - | - | Copy next line into object module and do not assemble that line |
RES length
(DS length) | No | Yes | Yes | Yes | Yes | Yes | .BLK.8 length | RES length | Add length bytes to the value of the assembler program counter |
SEG segment,relocation,mode | No | No | No | No | Yes | No | - | - | Begin segment |
symbol SET value | No | No | No | Yes | Yes | Yes | - | - | Define a symbol temporarily |
SPC rows | No | Yes | Yes | Yes | Yes | Yes | - | - | Add blank lines (spacing) |
(START address) | No | No | No | No | No | No | .START address | - | Set program start address |
- | No | No | No | No | No | No | .STRING string | - | Insert the ASCII text in the object, with length (8 bits) at the beginning |
- | No | No | No | No | No | No | .SYSCALL symbol | - | Define a special instruction (system call) |
- | No | No | No | No | No | No | .TEXT | - | Begin comment block |
TITL string | No | Yes | Yes | Yes | Yes | Yes | .TITLE string | TITLE string | Start a new page with the specified title |
1 Only one argument is allowed.
2 No arguments are allowed.
3 Only ON and OFF arguments are allowed.
Notes for CALM:
Extended .BLK notation is supported by the standard
(though not by the emulator), eg.
.BLK.8.16.32.16.8 10 will reserve 100 ((1+2+4+2+1)*10) bytes.
And similarly for [.DATA].8|16|32 , eg.
8.8.16 "A","Z",$1234 .
.LAYOUT and .LAYOUTMACRO can take multiple arguments, eg.
LAYOUT HEX,LENGTH 66 .
Assemblers are: PB2=PIPLA, TS1=Timeshare unrelocatable, PRO=Prometheus, TW1=TWIN unrelocatable, TS2=Timeshare relocatable, TW2=TWIN relocatable.
Directives in parentheses are unofficial (supported by the emulator but not part of the standard).
The emulator uses a slightly modified version of the CALM and IEEE-694 notations, to avoid clashes with other uses of these symbols, as follows. Differences are highlighted.
Signetics real | Signetics in emu | CALM real | CALM in emu | IEEE-964 real | IEEE-964 in emu | |
I/O port | $ | & | ||||
Indirection | * | * | @ | * | @ | * |
Immediate value | # | # | # | # | ||
Relative address | .+ | ^ | $ | ^ | ||
Absolute address | / | / | ||||
Zero page address | 0+ | / | ! | & | ||
Current address | $ | $ | APC | $ | * | $ |
Binary | 'B' | % | 2' | % | B' | % |
Octal | 'O' | @ | 8' | @ | Q' | @ |
Decimal | 'D' | ! or 'D' | 10' | ! | D' | ! |
Hexadecimal | 'H' | $ or 'H' | 16' | $ | H' | $ |
Instruction cross-reference:
Hex | Signetics | CALM | IEEE-694 | Signetics pseudocode | PSU | PSL | Note | ||||||||||||||
Opcode | Operands | Opcode | Real oprnds | Emu oprnds | Opcode | Real oprnds | Emu oprnds | S | F | II | SP | CC | IDC | RS | WC | OVF | COM | C | |||
00 | LODZ | r0 | LOAD | A,A | MOV | .0,.0 | if (r0 & $80) CC = LT; elif (r0 == 0) CC = EQ; else CC = GT; | - | - | - | - | W | - | - | - | - | - | - | 1 | ||
01 | LODZ | r1 | LOAD | A,B | MOV | .0,.1 | r0 = r1; | - | - | - | - | W | - | R | - | - | - | - | - | ||
02 | LODZ | r2 | LOAD | A,C | MOV | .0,.2 | r0 = r2; | - | - | - | - | W | - | R | - | - | - | - | - | ||
03 | LODZ | r3 | LOAD | A,D | MOV | .0,.3 | r0 = r3; | - | - | - | - | W | - | R | - | - | - | - | - | ||
04 | LODI,r0 | imm | LOAD | A,#imm | LD | .0,#imm | r0 = imm; | - | - | - | - | W | - | - | - | - | - | - | - | ||
05 | LODI,r1 | imm | LOAD | B,#imm | LD | .1,#imm | r1 = imm; | - | - | - | - | W | - | R | - | - | - | - | - | ||
06 | LODI,r2 | imm | LOAD | C,#imm | LD | .2,#imm | r2 = imm; | - | - | - | - | W | - | R | - | - | - | - | - | ||
07 | LODI,r3 | imm | LOAD | D,#imm | LD | .3,#imm | r3 = imm; | - | - | - | - | W | - | R | - | - | - | - | - | ||
08 | LODR,r0 | rel | LOAD | A,.+rel | A,^rel | LD | .0,$rel | .0,^rel | r0 = *rel; | - | - | - | - | W | - | - | - | - | - | - | - |
09 | LODR,r1 | rel | LOAD | B,.+rel | B,^rel | LD | .1,$rel | .1,^rel | r1 = *rel; | - | - | - | - | W | - | R | - | - | - | - | - |
0A | LODR,r2 | rel | LOAD | C,.+rel | C,^rel | LD | .2,$rel | .2,^rel | r2 = *rel; | - | - | - | - | W | - | R | - | - | - | - | - |
0B | LODR,r3 | rel | LOAD | D,.+rel | D,^rel | LD | .3,$rel | .3,^rel | r3 = *rel; | - | - | - | - | W | - | R | - | - | - | - | - |
0C | LODA,r0 | abs | LOAD | A,abs | LD | .0,/abs | r0 = *abs; | - | - | - | - | W | - | - | - | - | - | - | - | ||
0D | LODA,r1 | abs | LOAD | B,abs | LD | .1,/abs | r1 = *abs; | - | - | - | - | W | - | R | - | - | - | - | - | ||
0E | LODA,r2 | abs | LOAD | C,abs | LD | .2,/abs | r2 = *abs; | - | - | - | - | W | - | R | - | - | - | - | - | ||
0F | LODA,r3 | abs | LOAD | D,abs | LD | .3,/abs | r3 = *abs; | - | - | - | - | W | - | R | - | - | - | - | - | ||
10 | LDPL | abs | LOAD | L,abs | LD | .L,/abs | PSL = *abs; | - | - | - | - | W | W | W | W | W | W | W | 2 | ||
11 | STPL | abs | LOAD | abs,L | ST | .L,/abs | *abs = PSL; | - | - | - | - | R | R | R | R | R | R | R | 2 | ||
12 | SPSU | LOAD | A,U | MOV | .0,.U | r0 = PSU; | R | R | R | R | W | - | - | - | - | - | - | - | |||
13 | SPSL | LOAD | A,L | MOV | .0,.L | r0 = PSL; | - | - | - | - | B | R | R | R | R | R | R | - | |||
14 | RETC,eq | RET,EQ | RETEQ | if (CC == EQ) return; | - | - | - | B | R | - | - | - | - | - | - | - | |||||
15 | RETC,gt | RET,GT | RETGT | if (CC == GT) return; | - | - | - | B | R | - | - | - | - | - | - | - | |||||
16 | RETC,lt | RET,LT | RETLT | if (CC == LT) return; | - | - | - | B | R | - | - | - | - | - | - | - | |||||
17 | RETC,un
RET | RET | RET | return; | - | - | - | B | - | - | - | - | - | - | - | 3 | |||||
18 | BCTR,eq
BER BOR BZR | rel | JUMP,eq | .+rel | ^rel | BEQ | $rel | ^rel | if (CC == EQ) goto rel; | - | - | - | - | R | - | - | - | - | - | - | 3 |
19 | BCTR,gt
BHR BPR | rel | JUMP,gt | .+rel | ^rel | BGT | $rel | ^rel | if (CC == GT) goto rel; | - | - | - | - | R | - | - | - | - | - | - | 3 |
1A | BCTR,lt
BLR BMR | rel | JUMP,lt | .+rel | ^rel | BLT | $rel | ^rel | if (CC == LT) goto rel; | - | - | - | - | R | - | - | - | - | - | - | 3 |
1B | BCTR,un
BR | rel | JUMP | .+rel | ^rel | BR | $rel | ^rel | goto rel; | - | - | - | - | - | - | - | - | - | - | - | 3 |
1C | BCTA,eq
BEA BOA BZA | abs | JUMP,eq | abs | BEQ | /abs | if (CC == EQ) goto abs; | - | - | - | - | R | - | - | - | - | - | - | 3 | ||
1D | BCTA,gt
BHA BPA | abs | JUMP,gt | abs | BGT | /abs | if (CC == GT) goto abs; | - | - | - | - | R | - | - | - | - | - | - | 3 | ||
1E | BCTA,lt
BLA BMA | abs | JUMP,lt | abs | BLT | /abs | if (CC == LT) goto abs; | - | - | - | - | R | - | - | - | - | - | - | 3 | ||
1F | BCTA,un
BA | abs | JUMP | abs | BR | /abs | goto abs; | - | - | - | - | - | - | - | - | - | - | - | 3 | ||
20 | EORZ
EORZ | r0
r0 | XOR
CLR | A,A
A | XOR
CLR | .0,.0
.0 | r0 = 0;
r0 = 0; | - | - | - | - | W | - | - | - | - | - | - | - | ||
21 | EORZ | r1 | XOR | A,B | XOR | .0,.1 | r0 ^= r1; | - | - | - | - | W | - | R | - | - | - | - | - | ||
22 | EORZ | r2 | XOR | A,C | XOR | .0,.2 | r0 ^= r2; | - | - | - | - | W | - | R | - | - | - | - | - | ||
23 | EORZ | r3 | XOR | A,D | XOR | .0,.3 | r0 ^= r3; | - | - | - | - | W | - | R | - | - | - | - | - | ||
24 | EORI,r0
EORI,r0 | imm
$FF | XOR
NOT | A,#imm
A | XOR
NOT | .0,#imm
.0 | r0 ^= imm;
r0 ^= $FF; | - | - | - | - | W | - | - | - | - | - | - | - | ||
25 | EORI,r1
EORI,r1 | imm
$FF | XOR
NOT | B,#imm
B | XOR
NOT | .1,#imm
.1 | r1 ^= imm;
r1 ^= $FF; | - | - | - | - | W | - | R | - | - | - | - | - | ||
26 | EORI,r2
EORI,r2 | imm
$FF | XOR
NOT | C,#imm
C | XOR
NOT | .2,#imm
.2 | r2 ^= imm;
r2 ^= $FF; | - | - | - | - | W | - | R | - | - | - | - | - | ||
27 | EORI,r3
EORI,r3 | imm
$FF | XOR
NOT | D,#imm
D | XOR
NOT | .3,#imm
.3 | r3 ^= imm;
r3 ^= $FF; | - | - | - | - | W | - | R | - | - | - | - | - | ||
28 | EORR,r0 | rel | XOR | A,.+rel | A,^rel | XOR | .0,$rel | .0,^rel | r0 ^= *rel; | - | - | - | - | W | - | - | - | - | - | - | - |
29 | EORR,r1 | rel | XOR | B,.+rel | B,^rel | XOR | .1,$rel | .1,^rel | r1 ^= *rel; | - | - | - | - | W | - | R | - | - | - | - | - |
2A | EORR,r2 | rel | XOR | C,.+rel | C,^rel | XOR | .2,$rel | .2,^rel | r2 ^= *rel; | - | - | - | - | W | - | R | - | - | - | - | - |
2B | EORR,r3 | rel | XOR | D,.+rel | D,^rel | XOR | .3,$rel | .3,^rel | r3 ^= *rel; | - | - | - | - | W | - | R | - | - | - | - | - |
2C | EORA,r0 | abs | XOR | A,abs | XOR | .0,/abs | r0 ^= *abs; | - | - | - | - | W | - | - | - | - | - | - | - | ||
2D | EORA,r1 | abs | XOR | B,abs | XOR | .1,/abs | r1 ^= *abs; | - | - | - | - | W | - | R | - | - | - | - | - | ||
2E | EORA,r2 | abs | XOR | C,abs | XOR | .2,/abs | r2 ^= *abs; | - | - | - | - | W | - | R | - | - | - | - | - | ||
2F | EORA,r3 | abs | XOR | D,abs | XOR | .3,/abs | r3 ^= *abs; | - | - | - | - | W | - | R | - | - | - | - | - | ||
30 | REDC,r0 | LOAD | A,$CTRL | A,&CTRL | IN | .0,CTRL | r0 = IOPORT(CTRL); | - | - | - | - | W | - | - | - | - | - | - | - | ||
31 | REDC,r1 | LOAD | B,$CTRL | B,&CTRL | IN | .1,CTRL | r1 = IOPORT(CTRL); | - | - | - | - | W | - | R | - | - | - | - | - | ||
32 | REDC,r2 | LOAD | C,$CTRL | C,&CTRL | IN | .2,CTRL | r2 = IOPORT(CTRL); | - | - | - | - | W | - | R | - | - | - | - | - | ||
33 | REDC,r3 | LOAD | D,$CTRL | D,&CTRL | IN | .3,CTRL | r3 = IOPORT(CTRL); | - | - | - | - | W | - | R | - | - | - | - | - | ||
34 | RETE,eq | RETION,EQ | RETIEQ | if (CC == EQ) { PSU &= ~PSU_II; return; } | - | - | W | B | R | - | - | - | - | - | - | - | |||||
35 | RETE,gt | RETION,GT | RETIGT | if (CC == GT) { PSU &= ~PSU_II; return; } | - | - | W | B | R | - | - | - | - | - | - | - | |||||
36 | RETE,lt | RETION,LT | RETILT | if (CC == LT) { PSU &= ~PSU_II; return; } | - | - | W | B | R | - | - | - | - | - | - | - | |||||
37 | RETE,un | RETION | RETI | PSU &= ~PSU_II; return; | - | - | W | B | - | - | - | - | - | - | - | - | |||||
38 | BSTR,eq | rel | CALL,EQ | .+rel | ^rel | CALLEQ | $rel | ^rel | if (CC == EQ) gosub rel; | - | - | - | B | R | - | - | - | - | - | - | - |
39 | BSTR,gt | rel | CALL,GT | .+rel | ^rel | CALLGT | $rel | ^rel | if (CC == GT) gosub rel; | - | - | - | B | R | - | - | - | - | - | - | - |
3A | BSTR,lt | rel | CALL,LT | .+rel | ^rel | CALLLT | $rel | ^rel | if (CC == LT) gosub rel; | - | - | - | B | R | - | - | - | - | - | - | - |
3B | BSTR,un
BSR | rel | CALL | .+rel | ^rel | CALL | $rel | ^rel | gosub rel; | - | - | - | B | - | - | - | - | - | - | - | 3 |
3C | BSTA,eq | abs | CALL,EQ | abs | CALLEQ | /abs | if (CC == EQ) gosub abs; | - | - | - | B | R | - | - | - | - | - | - | - | ||
3D | BSTA,gt | abs | CALL,GT | abs | CALLGT | /abs | if (CC == GT) gosub abs; | - | - | - | B | R | - | - | - | - | - | - | - | ||
3E | BSTA,lt | abs | CALL,LT | abs | CALLLT | /abs | if (CC == LT) gosub abs; | - | - | - | B | R | - | - | - | - | - | - | - | ||
3F | BSTA,un
BSA | abs | CALL | abs | CALL | /abs | gosub abs; | - | - | - | B | - | - | - | - | - | - | - | 3 | ||
40 | HALT | WAIT | HALT|WAIT | for (;;); | - | - | - | - | - | - | - | - | - | - | - | 4 | |||||
41 | ANDZ | r1 | AND | A,B | AND | .0,.1 | r0 &= r1; | - | - | - | - | W | - | R | - | - | - | - | - | ||
42 | ANDZ | r2 | AND | A,C | AND | .0,.2 | r0 &= r2; | - | - | - | - | W | - | R | - | - | - | - | - | ||
43 | ANDZ | r3 | AND | A,D | AND | .0,.3 | r0 &= r3; | - | - | - | - | W | - | R | - | - | - | - | - | ||
44 | ANDI,r0 | imm | AND | A,#imm | AND | .0,#imm | r0 &= imm; | - | - | - | - | W | - | - | - | - | - | - | - | ||
45 | ANDI,r1 | imm | AND | B,#imm | AND | .1,#imm | r1 &= imm; | - | - | - | - | W | - | R | - | - | - | - | - | ||
46 | ANDI,r2 | imm | AND | C,#imm | AND | .2,#imm | r2 &= imm; | - | - | - | - | W | - | R | - | - | - | - | - | ||
47 | ANDI,r3 | imm | AND | D,#imm | AND | .3,#imm | r3 &= imm; | - | - | - | - | W | - | R | - | - | - | - | - | ||
48 | ANDR,r0 | rel | AND | A,.+rel | A,^rel | AND | .0,$rel | .0,^rel | r0 &= *rel; | - | - | - | - | W | - | - | - | - | - | - | - |
49 | ANDR,r1 | rel | AND | B,.+rel | B,^rel | AND | .1,$rel | .1,^rel | r1 &= *rel; | - | - | - | - | W | - | R | - | - | - | - | - |
4A | ANDR,r2 | rel | AND | C,.+rel | C,^rel | AND | .2,$rel | .2,^rel | r2 &= *rel; | - | - | - | - | W | - | R | - | - | - | - | - |
4B | ANDR,r3 | rel | AND | D,.+rel | D,^rel | AND | .3,$rel | .3,^rel | r3 &= *rel; | - | - | - | - | W | - | R | - | - | - | - | - |
4C | ANDA,r0 | abs | AND | A,abs | AND | .0,/abs | r0 &= *abs; | - | - | - | - | W | - | - | - | - | - | - | - | ||
4D | ANDA,r1 | abs | AND | B,abs | AND | .1,/abs | r1 &= *abs; | - | - | - | - | W | - | R | - | - | - | - | - | ||
4E | ANDA,r2 | abs | AND | C,abs | AND | .2,/abs | r2 &= *abs; | - | - | - | - | W | - | R | - | - | - | - | - | ||
4F | ANDA,r3 | abs | AND | D,abs | AND | .3,/abs | r3 &= *abs; | - | - | - | - | W | - | R | - | - | - | - | - | ||
50 | RRR,r0 | RR|RRC|SR | A | ROR|RORC|SHR | .0 | r0 >>= 1; | - | - | - | - | W | W | - | R | W | - | B | 4 | |||
51 | RRR,r1 | RR|RRC|SR | B | ROR|RORC|SHR | .1 | r1 >>= 1; | - | - | - | - | W | W | R | R | W | - | B | 4 | |||
52 | RRR,r2 | RR|RRC|SR | C | ROR|RORC|SHR | .2 | r2 >>= 1; | - | - | - | - | W | W | R | R | W | - | B | 4 | |||
53 | RRR,r3 | RR|RRC|SR | D | ROR|RORC|SHR | .3 | r3 >>= 1; | - | - | - | - | W | W | R | R | W | - | B | 4 | |||
54 | REDE,r0 | port | LOAD | A,$port | A,&port | IN | .0,port | r0 = IOPORT(port); | - | - | - | - | W | - | - | - | - | - | - | - | |
55 | REDE,r1 | port | LOAD | B,$port | B,&port | IN | .1,port | r1 = IOPORT(port); | - | - | - | - | W | - | R | - | - | - | - | - | |
56 | REDE,r2 | port | LOAD | C,$port | C,&port | IN | .2,port | r2 = IOPORT(port); | - | - | - | - | W | - | R | - | - | - | - | - | |
57 | REDE,r3 | port | LOAD | D,$port | D,&port | IN | .3,port | r3 = IOPORT(port); | - | - | - | - | W | - | R | - | - | - | - | - | |
58 | BRNR,r0 | rel | JUMP,ANE | .+rel | ^rel | BNZ | .0,$rel | .0,^rel | if (r0 != 0) goto rel; | - | - | - | - | - | - | - | - | - | - | - | - |
59 | BRNR,r1 | rel | JUMP,BNE | .+rel | ^rel | BNZ | .1,$rel | .1,^rel | if (r1 != 0) goto rel; | - | - | - | - | - | - | R | - | - | - | - | - |
5A | BRNR,r2 | rel | JUMP,CNE | .+rel | ^rel | BNZ | .2,$rel | .2,^rel | if (r2 != 0) goto rel; | - | - | - | - | - | - | R | - | - | - | - | - |
5B | BRNR,r3 | rel | JUMP,DNE | .+rel | ^rel | BNZ | .3,$rel | .3,^rel | if (r3 != 0) goto rel; | - | - | - | - | - | - | R | - | - | - | - | - |
5C | BRNA,r0 | abs | JUMP,ANE | abs | BNZ | .0,/abs | if (r0 != 0) goto abs; | - | - | - | - | - | - | - | - | - | - | - | - | ||
5D | BRNA,r1 | abs | JUMP,BNE | abs | BNZ | .1,/abs | if (r1 != 0) goto abs; | - | - | - | - | - | - | R | - | - | - | - | - | ||
5E | BRNA,r2 | abs | JUMP,CNE | abs | BNZ | .2,/abs | if (r2 != 0) goto abs; | - | - | - | - | - | - | R | - | - | - | - | - | ||
5F | BRNA,r3 | abs | JUMP,DNE | abs | BNZ | .3,/abs | if (r3 != 0) goto abs; | - | - | - | - | - | - | R | - | - | - | - | - | ||
60 | IORZ | r0 | OR | A,A | OR | .0,.0 | if (r0 & 80) CC = LT; elif (r0 == 0) CC = EQ; else CC = GT; | - | - | - | - | W | - | - | - | - | - | - | - | ||
61 | IORZ | r1 | OR | A,B | OR | .0,.1 | r0 |= r1; | - | - | - | - | W | - | R | - | - | - | - | - | ||
62 | IORZ | r2 | OR | A,C | OR | .0,.2 | r0 |= r2; | - | - | - | - | W | - | R | - | - | - | - | - | ||
63 | IORZ | r3 | OR | A,D | OR | .0,.3 | r0 |= r3; | - | - | - | - | W | - | R | - | - | - | - | - | ||
64 | IORI,r0 | imm | OR | A,#imm | OR | .0,#imm | r0 |= imm; | - | - | - | - | W | - | - | - | - | - | - | - | ||
65 | IORI,r1 | imm | OR | B,#imm | OR | .1,#imm | r1 |= imm; | - | - | - | - | W | - | R | - | - | - | - | - | ||
66 | IORI,r2 | imm | OR | C,#imm | OR | .2,#imm | r2 |= imm; | - | - | - | - | W | - | R | - | - | - | - | - | ||
67 | IORI,r3 | imm | OR | D,#imm | OR | .3,#imm | r3 |= imm; | - | - | - | - | W | - | R | - | - | - | - | - | ||
68 | IORR,r0 | rel | OR | A,.+rel | A,^rel | OR | .0,$rel | .0,^rel | r0 |= *rel; | - | - | - | - | W | - | - | - | - | - | - | - |
69 | IORR,r1 | rel | OR | B,.+rel | B,^rel | OR | .1,$rel | .1,^rel | r1 |= *rel; | - | - | - | - | W | - | R | - | - | - | - | - |
6A | IORR,r2 | rel | OR | C,.+rel | C,^rel | OR | .2,$rel | .2,^rel | r2 |= *rel; | - | - | - | - | W | - | R | - | - | - | - | - |
6B | IORR,r3 | rel | OR | D,.+rel | D,^rel | OR | .3,$rel | .3,^rel | r3 |= *rel; | - | - | - | - | W | - | R | - | - | - | - | - |
6C | IORA,r0 | abs | OR | A,abs | OR | .0,/abs | r0 |= *abs; | - | - | - | - | W | - | - | - | - | - | - | - | ||
6D | IORA,r1 | abs | OR | B,abs | OR | .1,/abs | r1 |= *abs; | - | - | - | - | W | - | R | - | - | - | - | - | ||
6E | IORA,r2 | abs | OR | C,abs | OR | .2,/abs | r2 |= *abs; | - | - | - | - | W | - | R | - | - | - | - | - | ||
6F | IORA,r3 | abs | OR | D,abs | OR | .3,/abs | r3 |= *abs; | - | - | - | - | W | - | R | - | - | - | - | - | ||
70 | REDD,r0 | LOAD | A,$DATA | A,&DATA | IN | .0,DATA | r0 = IOPORT(DATA); | - | - | - | - | W | - | - | - | - | - | - | - | ||
71 | REDD,r1 | LOAD | B,$DATA | B,&DATA | IN | .1,DATA | r1 = IOPORT(DATA); | - | - | - | - | W | - | R | - | - | - | - | - | ||
72 | REDD,r2 | LOAD | C,$DATA | C,&DATA | IN | .2,DATA | r2 = IOPORT(DATA); | - | - | - | - | W | - | R | - | - | - | - | - | ||
73 | REDD,r3 | LOAD | D,$DATA | D,&DATA | IN | .3,DATA | r3 = IOPORT(DATA); | - | - | - | - | W | - | R | - | - | - | - | - | ||
74 | CPSU
CPSU CPSU CPSU CPSU CPSU | imm
$80 $40 $20 $20 $07 | BIC
CLR CLR ION CLR CLR | U,#imm
INPUT OUTPUT IOF STACK | AND
AND AND EI EI AND | .U,#~imm
.U,#~$80 .U,#~$40 .U,#~$07 | PSU &= ~(imm & %01111111);
; PSU &= ~PSU_F; PSU &= ~PSU_II; PSU &= ~PSU_II; PSU &= ~PSU_SP; | - | W | W | W | - | - | - | - | - | - | - | 5 | ||
75 | CPSL
CPSL CPSL CPSL CPSL CPSL CPSL CPSL CPSL | imm
$20 $10 $08 $04 $04 $02 $01 $01 | BIC
CLR CLR CLR CLRV CLR CLR CLRC CLR | L,#imm
HALFCARRY BANK|BANK1 WITHCARRY OVERFLOW LOGICOMP CARRY | AND
AND AND AND CLRV CLRV AND CLRC CLRC | .L,#~imm
.L,#~$20 .L,#~$10 .L,#~$08 .L,#~$02 | PSL &= ~imm;
PSL &= ~PSL_IDC; PSL &= ~PSL_RS; PSL &= ~PSL_WC; PSL &= ~PSL_V; PSL &= ~PSL_V; PSL &= ~PSL_COM; PSL &= ~PSL_C; PSL &= ~PSL_C; | - | - | - | - | W | W | W | W | W | W | W | - | ||
76 | PPSU
PPSU PPSU PPSU PPSU | imm
$80 $40 $20 $20 | OR
SET SET IOF SET | U,#imm
INPUT OUTPUT IOF | OR
OR OR DI DI | .U,#imm
.U,#$80 .U,#$40 | PSU |= imm & %01111111;
; PSU |= PSU_F; PSU |= PSU_II; PSU |= PSU_II; | - | W | W | W | - | - | - | - | - | - | - | 5 | ||
77 | PPSL
PPSL PPSL PPSL PPSL PPSL PPSL PPSL PPSL | imm
$20 $10 $08 $04 $04 $02 $01 $01 | OR
SET SET SET SETV SET SET SETC SET | L,#imm
HALFCARRY BANK|BANK1 WITHCARRY OVERFLOW LOGICOMP CARRY | OR
OR OR OR SETV SETV OR SETC SETC | .L,#imm
.L,#$20 .L,#$10 .L,#$08 .L,#$02 | PSL |= imm;
PSL |= PSL_IDC; PSL |= PSL_RS; PSL |= PSL_WC; PSL |= PSL_V; PSL |= PSL_V; PSL |= PSL_COM; PSL |= PSL_C; PSL |= PSL_C; | - | - | - | - | W | W | W | W | W | W | W | - | ||
78 | BSNR,r0 | rel | CALL,ANE | .+rel | ^rel | CALLNZ | .0,$rel | .0,^rel | if (r0 != 0) gosub rel; | - | - | - | B | - | - | - | - | - | - | - | - |
79 | BSNR,r1 | rel | CALL,BNE | .+rel | ^rel | CALLNZ | .1,$rel | .1,^rel | if (r1 != 0) gosub rel; | - | - | - | B | - | - | R | - | - | - | - | - |
7A | BSNR,r2 | rel | CALL,CNE | .+rel | ^rel | CALLNZ | .2,$rel | .2,^rel | if (r2 != 0) gosub rel; | - | - | - | B | - | - | R | - | - | - | - | - |
7B | BSNR,r3 | rel | CALL,DNE | .+rel | ^rel | CALLNZ | .3,$rel | .3,^rel | if (r3 != 0) gosub rel; | - | - | - | B | - | - | R | - | - | - | - | - |
7C | BSNA,r0 | abs | CALL,ANE | abs | CALLNZ | .0,/abs | if (r0 != 0) gosub abs; | - | - | - | B | - | - | - | - | - | - | - | - | ||
7D | BSNA,r1 | abs | CALL,BNE | abs | CALLNZ | .1,/abs | if (r1 != 0) gosub abs; | - | - | - | B | - | - | R | - | - | - | - | - | ||
7E | BSNA,r2 | abs | CALL,CNE | abs | CALLNZ | .2,/abs | if (r2 != 0) gosub abs; | - | - | - | B | - | - | R | - | - | - | - | - | ||
7F | BSNA,r3 | abs | CALL,DNE | abs | CALLNZ | .3,/abs | if (r3 != 0) gosub abs; | - | - | - | B | - | - | R | - | - | - | - | - | ||
80 | ADDZ | r0 | ADD|ADDC | A,A | ADD|ADDC | .0,.0 | r0 += r0; | - | - | - | - | W | W | - | R | W | - | B | 4 | ||
81 | ADDZ | r1 | ADD|ADDC | A,B | ADD|ADDC | .0,.1 | r0 += r1; | - | - | - | - | W | W | R | R | W | - | B | 4 | ||
82 | ADDZ | r2 | ADD|ADDC | A,C | ADD|ADDC | .0,.2 | r0 += r2; | - | - | - | - | W | W | R | R | W | - | B | 4 | ||
83 | ADDZ | r3 | ADD|ADDC | A,D | ADD|ADDC | .0,.3 | r0 += r3; | - | - | - | - | W | W | R | R | W | - | B | 4 | ||
84 | ADDI,r0 | imm | ADD|ADDC | A,#imm | ADD|ADDC | .0,#imm | r0 += imm; | - | - | - | - | W | W | - | R | W | - | B | 4 | ||
85 | ADDI,r1 | imm | ADD|ADDC | B,#imm | ADD|ADDC | .1,#imm | r1 += imm; | - | - | - | - | W | W | R | R | W | - | B | 4 | ||
86 | ADDI,r2 | imm | ADD|ADDC | C,#imm | ADD|ADDC | .2,#imm | r2 += imm; | - | - | - | - | W | W | R | R | W | - | B | 4 | ||
87 | ADDI,r3 | imm | ADD|ADDC | D,#imm | ADD|ADDC | .3,#imm | r3 += imm; | - | - | - | - | W | W | R | R | W | - | B | 4 | ||
88 | ADDR,r0 | rel | ADD|ADDC | A,.+rel | A,^rel | ADD|ADDC | .0,$rel | .0,^rel | r0 += *rel; | - | - | - | - | W | W | - | R | W | - | B | 4 |
89 | ADDR,r1 | rel | ADD|ADDC | B,.+rel | B,^rel | ADD|ADDC | .1,$rel | .1,^rel | r1 += *rel; | - | - | - | - | W | W | R | R | W | - | B | 4 |
8A | ADDR,r2 | rel | ADD|ADDC | C,.+rel | C,^rel | ADD|ADDC | .2,$rel | .2,^rel | r2 += *rel; | - | - | - | - | W | W | R | R | W | - | B | 4 |
8B | ADDR,r3 | rel | ADD|ADDC | D,.+rel | D,^rel | ADD|ADDC | .3,$rel | .3,^rel | r3 += *rel; | - | - | - | - | W | W | R | R | W | - | B | 4 |
8C | ADDA,r0 | abs | ADD|ADDC | A,abs | ADD|ADDC | .0,/abs | r0 += *abs; | - | - | - | - | W | W | - | R | W | - | B | 4 | ||
8D | ADDA,r1 | abs | ADD|ADDC | B,abs | ADD|ADDC | .1,/abs | r1 += *abs; | - | - | - | - | W | W | R | R | W | - | B | 4 | ||
8E | ADDA,r2 | abs | ADD|ADDC | C,abs | ADD|ADDC | .2,/abs | r2 += *abs; | - | - | - | - | W | W | R | R | W | - | B | 4 | ||
8F | ADDA,r3 | abs | ADD|ADDC | D,abs | ADD|ADDC | .3,/abs | r3 += *abs; | - | - | - | - | W | W | R | R | W | - | B | 4 | ||
90 | - | ||||||||||||||||||||
91 | - | ||||||||||||||||||||
92 | LPSU | LOAD | U,A | MOV | .U,.0 | PSU = (PSU & %10000000) | (r0 & %01111111); | - | W | W | W | - | - | - | - | - | - | - | 5 | |||
93 | LPSL | LOAD | L,A | MOV | .L,.0 | PSL = r0; | - | - | - | - | W | W | W | W | W | W | W | - | |||
94 | DAR,r0 | DA | A | ADJ | .0 | r0 = DAR(r0); | - | - | - | - | W | R | - | - | - | - | R | - | |||
95 | DAR,r1 | DA | B | ADJ | .1 | r1 = DAR(r1); | - | - | - | - | W | R | R | - | - | - | R | - | |||
96 | DAR,r2 | DA | C | ADJ | .2 | r2 = DAR(r2); | - | - | - | - | W | R | R | - | - | - | R | - | |||
97 | DAR,r3 | DA | D | ADJ | .3 | r3 = DAR(r3); | - | - | - | - | W | R | R | - | - | - | R | - | |||
98 | BCFR,eq
BNER BNZR | rel | JUMP,NE | .+rel | ^rel | BNE | $rel | ^rel | if (CC != EQ) goto rel; | - | - | - | - | R | - | - | - | - | - | - | 3 |
99 | BCFR,gt
BNHR BNPR | rel | JUMP,LE | .+rel | ^rel | BLE | $rel | ^rel | if (CC != GT) goto rel; | - | - | - | - | R | - | - | - | - | - | - | 3 |
9A | BCFR,lt
BNLR BNMR | rel | JUMP,GE | .+rel | ^rel | BGE | $rel | ^rel | if (CC != LT) goto rel; | - | - | - | - | R | - | - | - | - | - | - | 3 |
9B | ZBRR | zero | JUMP | 0+zero | /zero | BR | !zero | &zero | goto zero; | - | - | - | - | - | - | - | - | - | - | - | - |
9C | BCFA,eq
BNEA BNZA | abs | JUMP,NE | abs | BNE | /abs | if (CC != EQ) goto abs; | - | - | - | - | R | - | - | - | - | - | - | 3 | ||
9D | BCFA,gt
BNHA BNPA | abs | JUMP,LE | abs | BLE | /abs | if (CC != GT) goto abs; | - | - | - | - | R | - | - | - | - | - | - | 3 | ||
9E | BCFA,lt
BNLA BNMA | abs | JUMP,GE | abs | BGE | /abs | if (CC != LT) goto abs; | - | - | - | - | R | - | - | - | - | - | - | 3 | ||
9F | BXA,r3 | abs | JUMP | (D)+abs | BR | /abs(.3) | goto abs + r3; | - | - | - | - | - | - | R | - | - | - | - | - | ||
A0 | SUBZ | r0 | SUB|SUBB | A,A | SUB|SUBC | .0,.0 | r0 -= r0; | - | - | - | - | W | W | - | R | W | - | B | 4 | ||
A1 | SUBZ | r1 | SUB|SUBB | A,B | SUB|SUBC | .0,.1 | r0 -= r1; | - | - | - | - | W | W | R | R | W | - | B | 4 | ||
A2 | SUBZ | r2 | SUB|SUBB | A,C | SUB|SUBC | .0,.2 | r0 -= r2; | - | - | - | - | W | W | R | R | W | - | B | 4 | ||
A3 | SUBZ | r3 | SUB|SUBB | A,D | SUB|SUBC | .0,.3 | r0 -= r3; | - | - | - | - | W | W | R | R | W | - | B | 4 | ||
A4 | SUBI,r0 | imm | SUB|SUBB | A,#imm | SUB|SUBC | .0,#imm | r0 -= imm; | - | - | - | - | W | W | - | R | W | - | B | 4 | ||
A5 | SUBI,r1 | imm | SUB|SUBB | B,#imm | SUB|SUBC | .1,#imm | r1 -= imm; | - | - | - | - | W | W | R | R | W | - | B | 4 | ||
A6 | SUBI,r2 | imm | SUB|SUBB | C,#imm | SUB|SUBC | .2,#imm | r2 -= imm; | - | - | - | - | W | W | R | R | W | - | B | 4 | ||
A7 | SUBI,r3 | imm | SUB|SUBB | D,#imm | SUB|SUBC | .3,#imm | r3 -= imm; | - | - | - | - | W | W | R | R | W | - | B | 4 | ||
A8 | SUBR,r0 | rel | SUB|SUBB | A,.+rel | A,^rel | SUB|SUBC | .0,$rel | .0,^rel | r0 -= *rel; | - | - | - | - | W | W | - | R | W | - | B | 4 |
A9 | SUBR,r1 | rel | SUB|SUBB | B,.+rel | B,^rel | SUB|SUBC | .1,$rel | .1,^rel | r1 -= *rel; | - | - | - | - | W | W | R | R | W | - | B | 4 |
AA | SUBR,r2 | rel | SUB|SUBB | C,.+rel | C,^rel | SUB|SUBC | .2,$rel | .2,^rel | r2 -= *rel; | - | - | - | - | W | W | R | R | W | - | B | 4 |
AB | SUBR,r3 | rel | SUB|SUBB | D,.+rel | D,^rel | SUB|SUBC | .3,$rel | .3,^rel | r3 -= *rel; | - | - | - | - | W | W | R | R | W | - | B | 4 |
AC | SUBA,r0 | abs | SUB|SUBB | A,abs | SUB|SUBC | .0,/abs | r0 -= *abs; | - | - | - | - | W | W | - | R | W | - | B | 4 | ||
AD | SUBA,r1 | abs | SUB|SUBB | B,abs | SUB|SUBC | .1,/abs | r1 -= *abs; | - | - | - | - | W | W | R | R | W | - | B | 4 | ||
AE | SUBA,r2 | abs | SUB|SUBB | C,abs | SUB|SUBC | .2,/abs | r2 -= *abs; | - | - | - | - | W | W | R | R | W | - | B | 4 | ||
AF | SUBA,r3 | abs | SUB|SUBB | D,abs | SUB|SUBC | .3,/abs | r3 -= *abs; | - | - | - | - | W | W | R | R | W | - | B | 4 | ||
B0 | WRTC,r0 | LOAD | $CTRL,A | &CTRL,A | OUT | .0,CTRL | IOPORT(CTRL) = r0; | - | - | - | - | - | - | - | - | - | - | - | - | ||
B1 | WRTC,r1 | LOAD | $CTRL,B | &CTRL,B | OUT | .1,CTRL | IOPORT(CTRL) = r1; | - | - | - | - | - | - | R | - | - | - | - | - | ||
B2 | WRTC,r2 | LOAD | $CTRL,C | &CTRL,C | OUT | .2,CTRL | IOPORT(CTRL) = r2; | - | - | - | - | - | - | R | - | - | - | - | - | ||
B3 | WRTC,r3 | LOAD | $CTRL,D | &CTRL,D | OUT | .3,CTRL | IOPORT(CTRL) = r3; | - | - | - | - | - | - | R | - | - | - | - | - | ||
B4 | TPSU
TPSU TPSU TPSU | imm
$80 $40 $20 | TEST
TEST TEST TEST | U,#imm
INPUT OUTPUT IOF | TEST
TEST TEST TEST | .U,#imm
.U,#$80 .U,#$40 .U,#$20 | CC = (PSU & imm == imm) ? EQ : LT;
CC = (PSU & PSU_S) ? EQ : LT; CC = (PSU & PSU_F) ? EQ : LT; CC = (PSU & PSU_II) ? EQ : LT; | R | R | R | R | W | - | - | - | - | - | - | - | ||
B5 | TPSL
TPSL TPSL TPSL TPSL TPSL TPSL | imm
$20 $10 $08 $04 $02 $01 | TEST
TEST TEST TEST TEST TEST TEST | L,#imm
HALFCARRY BANK|BANK1 WITHCARRY OVERFLOW LOGICOMP CARRY | TEST
TEST TEST TEST TEST TEST TEST | .L,#imm
.L,#$20 .L,#$10 .L,#$08 .L,#$04 .L,#$02 .L,#$01 | CC = (PSL & imm == imm) ? EQ : LT;
CC = (PSL & PSL_IDC) ? EQ : LT; CC = (PSL & PSL_RS) ? EQ : LT; CC = (PSL & PSL_WC) ? EQ : LT; CC = (PSL & PSL_OVF) ? EQ : LT; CC = (PSL & PSL_COM) ? EQ : LT; CC = (PSL & PSL_C) ? EQ : LT; | - | - | - | - | B | R | R | R | R | R | R | - | ||
B6 | - | ||||||||||||||||||||
B7 | - | ||||||||||||||||||||
B8 | BSFR,eq | rel | CALL,NE | .+rel | ^rel | CALLNE | $rel | ^rel | if (CC != EQ) gosub rel; | - | - | - | B | R | - | - | - | - | - | - | - |
B9 | BSFR,gt | rel | CALL,LE | .+rel | ^rel | CALLLE | $rel | ^rel | if (CC != GT) gosub rel; | - | - | - | B | R | - | - | - | - | - | - | - |
BA | BSFR,lt | rel | CALL,GE | .+rel | ^rel | CALLGE | $rel | ^rel | if (CC != LT) gosub rel; | - | - | - | B | R | - | - | - | - | - | - | - |
BB | ZBSR | zero | CALL | .0+zero | /zero | CALL | !zero | &zero | gosub zero; | - | - | - | B | - | - | - | - | - | - | - | - |
BC | BSFA,eq | abs | CALL,NE | abs | CALLNE | /abs | if (CC != EQ) gosub abs; | - | - | - | B | R | - | - | - | - | - | - | - | ||
BD | BSFA,gt | abs | CALL,LE | abs | CALLLE | /abs | if (CC != GT) gosub abs; | - | - | - | B | R | - | - | - | - | - | - | - | ||
BE | BSFA,lt | abs | CALL,GE | abs | CALLGE | /abs | if (CC != LT) gosub abs; | - | - | - | B | R | - | - | - | - | - | - | - | ||
BF | BSXA,r3 | abs | CALL | (D)+abs | CALL | /abs(.3) | gosub abs + r3; | - | - | - | B | - | - | R | - | - | - | - | - | ||
C0 | NOP | NOP | NOP | ; | - | - | - | - | - | - | - | - | - | - | - | - | |||||
C1 | STRZ r1 | LOAD | B,A | MOV | .1,.0 | r1 = r0; | - | - | - | - | W | - | R | - | - | - | - | - | |||
C2 | STRZ r2 | LOAD | C,A | MOV | .2,.0 | r2 = r0; | - | - | - | - | W | - | R | - | - | - | - | - | |||
C3 | STRZ r3 | LOAD | D,A | MOV | .3,.0 | r3 = r0; | - | - | - | - | W | - | R | - | - | - | - | - | |||
C4 | - | ||||||||||||||||||||
C5 | - | ||||||||||||||||||||
C6 | - | ||||||||||||||||||||
C7 | - | ||||||||||||||||||||
C8 | STRR,r0 | rel | LOAD | .+rel,A | ^rel,A | ST | .0,$rel | .0,^rel | *rel = r0; | - | - | - | - | W | - | - | - | - | - | - | - |
C9 | STRR,r1 | rel | LOAD | .+rel,B | ^rel,B | ST | .1,$rel | .1,^rel | *rel = r1; | - | - | - | - | W | - | R | - | - | - | - | - |
CA | STRR,r2 | rel | LOAD | .+rel,C | ^rel,C | ST | .2,$rel | .2,^rel | *rel = r2; | - | - | - | - | W | - | R | - | - | - | - | - |
CB | STRR,r3 | rel | LOAD | .+rel,D | ^rel,D | ST | .3,$rel | .3,^rel | *rel = r3; | - | - | - | - | W | - | R | - | - | - | - | - |
CC | STRA,r0 | abs | LOAD | abs,A | ST | .0,/abs | *abs = r0; | - | - | - | - | W | - | - | - | - | - | - | - | ||
CD | STRA,r1 | abs | LOAD | abs,B | ST | .1,/abs | *abs = r1; | - | - | - | - | W | - | R | - | - | - | - | - | ||
CE | STRA,r2 | abs | LOAD | abs,C | ST | .2,/abs | *abs = r2; | - | - | - | - | W | - | R | - | - | - | - | - | ||
CF | STRA,r3 | abs | LOAD | abs,D | ST | .3,/abs | *abs = r3; | - | - | - | - | W | - | R | - | - | - | - | - | ||
D0 | RRL,r0 | RL|RLC|SL|ASL | A | ROL|ROLC|SHL|SHLA | .0 | r0 <<= 1; | - | - | - | - | W | W | - | R | W | - | B | 4 | |||
D1 | RRL,r1 | RL|RLC|SL|ASL | B | ROL|ROLC|SHL|SHLA | .1 | r1 <<= 1; | - | - | - | - | W | W | R | R | W | - | B | 4 | |||
D2 | RRL,r2 | RL|RLC|SL|ASL | C | ROL|ROLC|SHL|SHLA | .2 | r2 <<= 1; | - | - | - | - | W | W | R | R | W | - | B | 4 | |||
D3 | RRL,r3 | RL|RLC|SL|ASL | D | ROL|ROLC|SHL|SHLA | .3 | r3 <<= 1; | - | - | - | - | W | W | R | R | W | - | B | 4 | |||
D4 | WRTE,r0 | port | LOAD | $port,A | &port,A | OUT | .0,port | IOPORT(port) = r0; | - | - | - | - | - | - | - | - | - | - | - | - | |
D5 | WRTE,r1 | port | LOAD | $port,B | &port,B | OUT | .1,port | IOPORT(port) = r1; | - | - | - | - | - | - | R | - | - | - | - | - | |
D6 | WRTE,r2 | port | LOAD | $port,C | &port,C | OUT | .2,port | IOPORT(port) = r2; | - | - | - | - | - | - | R | - | - | - | - | - | |
D7 | WRTE,r3 | port | LOAD | $port,D | &port,D | OUT | .3,port | IOPORT(port) = r3; | - | - | - | - | - | - | R | - | - | - | - | - | |
D8 | BIRR,r0
BIRR,r0 | rel
$+2 | INCJ,NE
INC | A,.+rel
A | A,^rel
A | IBNZ
INC | .0,$rel
.0 | .0,^rel
.0 | if (++r0 != 0) goto rel;
r0++; | - | - | - | - | - | - | - | - | - | - | - | 6 |
D9 | BIRR,r1
BIRR,r1 | rel
$+2 | INCJ,NE
INC | B,.+rel
B | B,^rel
B | IBNZ
INC | .1,$rel
.1 | .1,^rel
.1 | if (++r1 != 0) goto rel;
r1++; | - | - | - | - | - | - | R | - | - | - | - | 6 |
DA | BIRR,r2
BIRR,r2 | rel
$+2 | INCJ,NE
INC | C,.+rel
C | C,^rel
C | IBNZ
INC | .2,$rel
.2 | .2,^rel
.2 | if (++r2 != 0) goto rel;
r2++; | - | - | - | - | - | - | R | - | - | - | - | 6 |
DB | BIRR,r3
BIRR,r3 | rel
$+2 | INCJ,NE
INC | D,.+rel
D | D,^rel
D | IBNZ
INC | .3,$rel
.3 | .3,^rel
.3 | if (++r3 != 0) goto rel;
r3++; | - | - | - | - | - | - | R | - | - | - | - | 6 |
DC | BIRA,r0
BIRA,r0 | abs
$+2 | INCJ,NE
INC | A,abs
A | IBNZ
INC | .0,/abs
.0 | if (++r0 != 0) goto abs;
r0++; | - | - | - | - | - | - | - | - | - | - | - | 6 | ||
DD | BIRA,r1
BIRA,r1 | abs
$+2 | INCJ,NE
INC | B,abs
B | IBNZ
INC | .1,/abs
.1 | if (++r1 != 0) goto abs;
r1++; | - | - | - | - | - | - | R | - | - | - | - | 6 | ||
DE | BIRA,r2
BIRA,r2 | abs
$+2 | INCJ,NE
INC | C,abs
C | IBNZ
INC | .2,/abs
.2 | if (++r2 != 0) goto abs;
r2++; | - | - | - | - | - | - | R | - | - | - | - | 6 | ||
DF | BIRA,r3
BIRA,r3 | abs
$+2 | INCJ,NE
INC | D,abs
D | IBNZ
INC | .3,/abs
.3 | if (++r3 != 0) goto abs;
r3++; | - | - | - | - | - | - | R | - | - | - | - | 6 | ||
E0 | COMZ | r0 | COMP | A,A | CMP | .0,.0 | CC = EQ; | - | - | - | - | W | - | - | - | - | R | - | - | ||
E1 | COMZ | r1 | COMP | A,B | CMP | .0,.1 | if (r0 > r1) CC = GT; elif (r0 < r1) CC = LT; else CC = EQ; | - | - | - | - | W | - | R | - | - | R | - | - | ||
E2 | COMZ | r2 | COMP | A,C | CMP | .0,.2 | if (r0 > r2) CC = GT; elif (r0 < r2) CC = LT; else CC = EQ; | - | - | - | - | W | - | R | - | - | R | - | - | ||
E3 | COMZ | r3 | COMP | A,D | CMP | .0,.3 | if (r0 > r3) CC = GT; elif (r0 < r3) CC = LT; else CC = EQ; | - | - | - | - | W | - | R | - | - | R | - | - | ||
E4 | COMI,r0 | imm | COMP | A,#imm | CMP | .0,#imm | if (r0 > imm) CC = GT; elif (r0 < imm) CC = LT; else CC = EQ; | - | - | - | - | W | - | - | - | - | R | - | - | ||
E5 | COMI,r1 | imm | COMP | B,#imm | CMP | .1,#imm | if (r1 > imm) CC = GT; elif (r1 < imm) CC = LT; else CC = EQ; | - | - | - | - | W | - | R | - | - | R | - | - | ||
E6 | COMI,r2 | imm | COMP | C,#imm | CMP | .2,#imm | if (r2 > imm) CC = GT; elif (r2 < imm) CC = LT; else CC = EQ; | - | - | - | - | W | - | R | - | - | R | - | - | ||
E7 | COMI,r3 | imm | COMP | D,#imm | CMP | .3,#imm | if (r3 > imm) CC = GT; elif (r3 < imm) CC = LT; else CC = EQ; | - | - | - | - | W | - | R | - | - | R | - | - | ||
E8 | COMR,r0 | rel | COMP | A,.+rel | A,^rel | CMP | .0,$rel | .0,^rel | if (r0 > *rel) CC = GT; elif (r0 < *rel) CC = LT; else CC = EQ; | - | - | - | - | W | - | - | - | - | R | - | - |
E9 | COMR,r1 | rel | COMP | B,.+rel | B,^rel | CMP | .1,$rel | .1,^rel | if (r1 > *rel) CC = GT; elif (r1 < *rel) CC = LT; else CC = EQ; | - | - | - | - | W | - | R | - | - | R | - | - |
EA | COMR,r2 | rel | COMP | C,.+rel | C,^rel | CMP | .2,$rel | .2,^rel | if (r2 > *rel) CC = GT; elif (r2 < *rel) CC = LT; else CC = EQ; | - | - | - | - | W | - | R | - | - | R | - | - |
EB | COMR,r3 | rel | COMP | D,.+rel | D,^rel | CMP | .3,$rel | .3,^rel | if (r3 > *rel) CC = GT; elif (r3 < *rel) CC = LT; else CC = EQ; | - | - | - | - | W | - | R | - | - | R | - | - |
EC | COMA,r0 | abs | COMP | A,abs | CMP | .0,/abs | if (r0 > *abs) CC = GT; elif (r0 < *abs) CC = LT; else CC = EQ; | - | - | - | - | W | - | - | - | - | R | - | - | ||
ED | COMA,r1 | abs | COMP | B,abs | CMP | .1,/abs | if (r1 > *abs) CC = GT; elif (r1 < *abs) CC = LT; else CC = EQ; | - | - | - | - | W | - | R | - | - | R | - | - | ||
EE | COMA,r2 | abs | COMP | C,abs | CMP | .2,/abs | if (r2 > *abs) CC = GT; elif (r2 < *abs) CC = LT; else CC = EQ; | - | - | - | - | W | - | R | - | - | R | - | - | ||
EF | COMA,r3 | abs | COMP | D,abs | CMP | .3,/abs | if (r3 > *abs) CC = GT; elif (r3 < *abs) CC = LT; else CC = EQ; | - | - | - | - | W | - | R | - | - | R | - | - | ||
F0 | WRTD,r0 | LOAD | $DATA,A | &DATA,A | OUT | .0,DATA | IOPORT(DATA) = r0; | - | - | - | - | - | - | - | - | - | - | - | - | ||
F1 | WRTD,r1 | LOAD | $DATA,B | &DATA,B | OUT | .1,DATA | IOPORT(DATA) = r1; | - | - | - | - | - | - | R | - | - | - | - | - | ||
F2 | WRTD,r2 | LOAD | $DATA,C | &DATA,C | OUT | .2,DATA | IOPORT(DATA) = r2; | - | - | - | - | - | - | R | - | - | - | - | - | ||
F3 | WRTD,r3 | LOAD | $DATA,D | &DATA,D | OUT | .3,DATA | IOPORT(DATA) = r3; | - | - | - | - | - | - | R | - | - | - | - | - | ||
F4 | TMI,r0 | imm | TEST | A,#imm | TEST | .0,#imm | CC = (r0 & imm == imm) ? EQ : LT; | - | - | - | - | W | - | - | - | - | - | - | - | ||
F5 | TMI,r1 | imm | TEST | B,#imm | TEST | .1,#imm | CC = (r1 & imm == imm) ? EQ : LT; | - | - | - | - | W | - | R | - | - | - | - | - | ||
F6 | TMI,r2 | imm | TEST | C,#imm | TEST | .2,#imm | CC = (r2 & imm == imm) ? EQ : LT; | - | - | - | - | W | - | R | - | - | - | - | - | ||
F7 | TMI,r3 | imm | TEST | D,#imm | TEST | .3,#imm | CC = (r3 & imm == imm) ? EQ : LT; | - | - | - | - | W | - | R | - | - | - | - | - | ||
F8 | BDRR,r0
BDRR,r0 | rel
$+2 | DECJ,NE
DEC | A,.+rel
A | A,^rel
A | DBNZ
DEC | .0,$rel
.0 | .0,^rel
.0 | if (--r0 != 0) goto rel;
r0--; | - | - | - | - | - | - | - | - | - | - | - | 6 |
F9 | BDRR,r1
BDRR,r1 | rel
$+2 | DECJ,NE
DEC | B,.+rel
B | B,^rel
B | DBNZ
DEC | .1,$rel
.1 | .1,^rel
.1 | if (--r1 != 0) goto rel;
r1--; | - | - | - | - | - | - | R | - | - | - | - | 6 |
FA | BDRR,r2
BDRR,r2 | rel
$+2 | DECJ,NE
DEC | C,.+rel
C | C,^rel
C | DBNZ
DEC | .2,$rel
.2 | .2,^rel
.2 | if (--r2 != 0) goto rel;
r2--; | - | - | - | - | - | - | R | - | - | - | - | 6 |
FB | BDRR,r3
BDRR,r3 | rel
$+2 | DECJ,NE
DEC | D,.+rel
D | D,^rel
D | DBNZ
DEC | .3,$rel
.3 | .3,^rel
.3 | if (--r3 != 0) goto rel;
r3--; | - | - | - | - | - | - | R | - | - | - | - | 6 |
FC | BDRA,r0
BDRA,r0 | abs
$+2 | DECJ,NE
DEC | A,abs
A | DBNZ
DEC | .0,/abs
.0 | if (--r0 != 0) goto abs;
r0--; | - | - | - | - | - | - | - | - | - | - | - | 6 | ||
FD | BDRA,r1
BDRA,r1 | abs
$+2 | DECJ,NE
DEC | B,abs
B | DBNZ
DEC | .1,/abs
.1 | if (--r1 != 0) goto abs;
r1--; | - | - | - | - | - | - | R | - | - | - | - | 6 | ||
FE | BDRA,r2
BDRA,r2 | abs
$+2 | DECJ,NE
DEC | C,abs
C | DBNZ
DEC | .2,/abs
.2 | if (--r2 != 0) goto abs;
r2--; | - | - | - | - | - | - | R | - | - | - | - | 6 | ||
FF | BDRA,r3
BDRA,r3 | abs
$+2 | DECJ,NE
DEC | D,abs
D | DBNZ
DEC | .3,/abs
.3 | if (--r3 != 0) goto abs;
r3--; | - | - | - | - | - | - | R | - | - | - | - | 6 |
Notes:
1: Indeterminate.
2: 2650B only.
3: For Signetics, additional mnemonics listed are only supported for extended notation.
4: For CALM, ADDC/SUBB/RLC/SL/ASL/RRC/SR are equivalent to ADD/SUB/RL/RL/RL/RR/RR respectively, depending on PSW.
For IEEE-694, ADDC/SUBC/ROLC/SHL/SHLA/RORC/SHR/WAIT are equivalent to ADD/SUB/RL/RL/RL/RR/RR/HALT respectively, depending on PSW.
See table below.
5: Pseudocode shown assumes 2650B. For 2650/2650A, mask is %01100111 instead of %01111111.
6: INC/DEC are ambiguous, as they can be interpreted as BIRR/BDRR or (less efficiently) as BIRA/BDRA.
F (Flag) column is also used for UF1 (User Flag #1) and UF2 (User Flag #2) bits on 2650B.
R=Read, W=Written, B=Both, -=Neither.
reg = register.
imm = 1-byte immediate value.
port = 1-byte immediate value (representing an extended I/O port address).
rel = 1-byte relative address (direct or indirect).
zero = 1-byte zero page address (direct or indirect).
abs = 2-byte absolute address (direct or indirect,
also with optional pre-increment/pre-decrement/indexing for non-branch
instructions).
Colours used in the above table are:
Arithmetic, transfer |
I/O, PSW, mixed |
Branch |
Special |
Illegal |
Table of equivalent instructions:
Signetics | CALM | IEEE |
HALT when II is clear | WAIT | WAIT |
HALT when II is set | WAIT | HALT |
RRR when WC is clear | RR | ROR |
RRR when WC is set | RRC | RORC |
RRR when WC is set and C is clear | SR | SHR |
ADD when WC is clear | ADD | ADD |
ADD when WC is set | ADDC | ADDC |
SUB when WC is clear | SUB | SUB |
SUB when WC is set | SUBB | SUBC |
RRL when WC is clear | RL | ROL |
RRL when WC is set | RLC | ROLC |
RRL when WC is set and C is clear | SL|ASL | SHL|SHLA |
Arithmetic shift right (ASR (CALM)/SHRA (IEEE-694)) is not available on these CPUs.
Relative branches are calculated these from the next instruction, ie. the IAR is incremented by 2 so it points to the start of the next instruction, then the branch is calculated. Indirect branches are the same as direct ones except that you must add $80 to the operand value.
Relative to next instruction | Relative to this instruction | Operand value |
-64 = $-40 | -62 = $-3E | $40 |
-63 = $-3F | -61 = $-3D | $41 |
-62 = $-3E | -60 = $-3C | $42 |
-61 = $-3D | -59 = $-3B | $43 |
-60 = $-3C | -58 = $-3A | $44 |
-59 = $-3B | -57 = $-39 | $45 |
-58 = $-3A | -56 = $-38 | $46 |
-57 = $-39 | -55 = $-37 | $47 |
-56 = $-38 | -54 = $-36 | $48 |
-55 = $-37 | -53 = $-35 | $49 |
-54 = $-36 | -52 = $-34 | $4A |
-53 = $-35 | -51 = $-33 | $4B |
-52 = $-34 | -50 = $-32 | $4C |
-51 = $-33 | -49 = $-31 | $4D |
-50 = $-32 | -48 = $-30 | $4E |
-49 = $-31 | -47 = $-2F | $4F |
-48 = $-30 | -46 = $-2E | $50 |
-47 = $-2F | -45 = $-2D | $51 |
-46 = $-2E | -44 = $-2C | $52 |
-45 = $-2D | -43 = $-2B | $53 |
-44 = $-2C | -42 = $-2A | $54 |
-43 = $-2B | -41 = $-29 | $55 |
-42 = $-2A | -40 = $-28 | $56 |
-41 = $-29 | -39 = $-27 | $57 |
-40 = $-28 | -38 = $-26 | $58 |
-39 = $-27 | -37 = $-25 | $59 |
-38 = $-26 | -36 = $-24 | $5A |
-37 = $-25 | -35 = $-23 | $5B |
-36 = $-24 | -34 = $-22 | $5C |
-35 = $-23 | -33 = $-21 | $5D |
-34 = $-22 | -32 = $-20 | $5E |
-33 = $-21 | -31 = $-1F | $5F |
-32 = $-20 | -30 = $-1E | $60 |
-31 = $-1F | -29 = $-1D | $61 |
-30 = $-1E | -28 = $-1C | $62 |
-29 = $-1D | -27 = $-1B | $63 |
-28 = $-1C | -26 = $-1A | $64 |
-27 = $-1B | -25 = $-19 | $65 |
-26 = $-1A | -24 = $-18 | $66 |
-25 = $-19 | -23 = $-17 | $67 |
-24 = $-18 | -22 = $-16 | $68 |
-23 = $-17 | -21 = $-15 | $69 |
-22 = $-16 | -20 = $-14 | $6A |
-21 = $-15 | -19 = $-13 | $6B |
-20 = $-14 | -18 = $-12 | $6C |
-19 = $-13 | -17 = $-11 | $6D |
-18 = $-12 | -16 = $-10 | $6E |
-17 = $-11 | -15 = $-F | $6F |
-16 = $-10 | -14 = $-E | $70 |
-15 = $-F | -13 = $-D | $71 |
-14 = $-E | -12 = $-C | $72 |
-13 = $-D | -11 = $-B | $73 |
-12 = $-C | -10 = $-A | $74 |
-11 = $-B | -9 = $-9 | $75 |
-10 = $-A | -8 = $-8 | $76 |
-9 = $-9 | -7 = $-7 | $77 |
-8 = $-8 | -6 = $-6 | $78 |
-7 = $-7 | -5 = $-5 | $79 |
-6 = $-6 | -4 = $-4 | $7A |
-5 = $-5 | -3 = $-3 | $7B |
-4 = $-4 | -2 = $-2 | $7C |
-3 = $-3 | -1 = $-1 | $7D |
-2 = $-2 | 0 = $0 | $7E |
-1 = $-1 | +1 = $+1 | $7F |
0 = $0 | +2 = $+2 | $00 |
+1 = $+1 | +3 = $+3 | $01 |
+2 = $+2 | +4 = $+4 | $02 |
+3 = $+3 | +5 = $+5 | $03 |
+4 = $+4 | +6 = $+6 | $04 |
+5 = $+5 | +7 = $+7 | $05 |
+6 = $+6 | +8 = $+8 | $06 |
+7 = $+7 | +9 = $+9 | $07 |
+8 = $+8 | +10 = $+A | $08 |
+9 = $+9 | +11 = $+B | $09 |
+10 = $+A | +12 = $+C | $0A |
+11 = $+B | +13 = $+D | $0B |
+12 = $+C | +14 = $+E | $0C |
+13 = $+D | +15 = $+F | $0D |
+14 = $+E | +16 = $+10 | $0E |
+15 = $+F | +17 = $+11 | $0F |
+16 = $+10 | +18 = $+12 | $10 |
+17 = $+11 | +19 = $+13 | $11 |
+18 = $+12 | +20 = $+14 | $12 |
+19 = $+13 | +21 = $+15 | $13 |
+20 = $+14 | +22 = $+16 | $14 |
+21 = $+15 | +23 = $+17 | $15 |
+22 = $+16 | +24 = $+18 | $16 |
+23 = $+17 | +25 = $+19 | $17 |
+24 = $+18 | +26 = $+1A | $18 |
+25 = $+19 | +27 = $+1B | $19 |
+26 = $+1A | +28 = $+1C | $1A |
+27 = $+1B | +29 = $+1D | $1B |
+28 = $+1C | +30 = $+1E | $1C |
+29 = $+1D | +31 = $+1F | $1D |
+30 = $+1E | +32 = $+20 | $1E |
+31 = $+1F | +33 = $+21 | $1F |
+32 = $+20 | +34 = $+22 | $20 |
+33 = $+21 | +35 = $+23 | $21 |
+34 = $+22 | +36 = $+24 | $22 |
+35 = $+23 | +37 = $+25 | $23 |
+36 = $+24 | +38 = $+26 | $24 |
+37 = $+25 | +39 = $+27 | $25 |
+38 = $+26 | +40 = $+28 | $26 |
+39 = $+27 | +41 = $+29 | $27 |
+40 = $+28 | +42 = $+2A | $28 |
+41 = $+29 | +43 = $+2B | $29 |
+42 = $+2A | +44 = $+2C | $2A |
+43 = $+2B | +45 = $+2D | $2B |
+44 = $+2C | +46 = $+2E | $2C |
+45 = $+2D | +47 = $+2F | $2D |
+46 = $+2E | +48 = $+30 | $2E |
+47 = $+2F | +49 = $+31 | $2F |
+48 = $+30 | +50 = $+32 | $30 |
+49 = $+31 | +51 = $+33 | $31 |
+50 = $+32 | +52 = $+34 | $32 |
+51 = $+33 | +53 = $+35 | $33 |
+52 = $+34 | +54 = $+36 | $34 |
+53 = $+35 | +55 = $+37 | $35 |
+54 = $+36 | +56 = $+38 | $36 |
+55 = $+37 | +57 = $+39 | $37 |
+56 = $+38 | +58 = $+3A | $38 |
+57 = $+39 | +59 = $+3B | $39 |
+58 = $+3A | +60 = $+3C | $3A |
+59 = $+3B | +61 = $+3D | $3B |
+60 = $+3C | +62 = $+3E | $3C |
+61 = $+3D | +63 = $+3F | $3D |
+62 = $+3E | +64 = $+40 | $3E |
+63 = $+3F | +65 = $+41 | $3F |
Eg. if you found the bytes $C8 and $50 at addresses $0100 and $0101:
$C8 is the opcode STRR,R0 (you can find this out from eg. WinArcadia's
"Help|Opcodes..." subwindow).
We look up the operand value $50 on the above table (right-hand column).
Now, looking at the central column, we see that it means -46 (which is
$-2E in hex), relative from this instruction.
So, the instruction is STRR,R0 $0100+$-2E, or, in other words,
STRR,R0 $00D2.
If we had instead found the bytes $C8 and $D0 at addresses $0100 and
$0101, the instruction would instead be STRR,R0 *$00D2 (since
$D0-$80=$50).
Four-digit decimal numbers can be implemented as follows.
Two decimal digits can be packed into each byte, one digit per nybble.
The numbers are relative to $66, eg:
addi,r0 $65
means -1
addi,r0 $66
means ±0
addi,r0 $67
means +1
To add 1 to a four-digit decimal number, use the following code:
ppsl $08 ;PSL |= %00001000; // set WC (With Carry) bit
cpsl $01 ;PSL &= %11111110; // clear C (Carry/Borrow) bit
loda,r0 LOWBYTE
addi,r0 $67
dar,r0
stra,r0 LOWBYTE
loda,r0 HIGHBYTE
addi,r0 $66 ;add 0, but any carry is applied
dar,r0
stra,r0 HIGHBYTE
cpsl $08 ;PSL &= %11110111; // clear WC (With Carry) bit
High byte, bits 7..4: thousands digit (%0000..%1001)
High byte, bits 3..0: hundreds digit (%0000..%1001)
Low byte, bits 7..4: tens digit (%0000..%1001)
Low byte, bits 3..0: ones digit (%0000..%1001)
If your game is larger than 4K, you will need to be aware of the
following rules.
The CPU divides the 32K address space into 4 pages, each of 8K, as
follows:
PAGE0 equ $0000 ;$0000..$1FFF: 1st page
PAGE1 equ $2000 ;$2000..$3FFF: 2nd page
PAGE2 equ $4000 ;$4000..$5FFF: 3rd page
PAGE3 equ $6000 ;$6000..$7FFF: 4th page
Execution of code cannot flow across page boundaries (wraparound will
occur instead).
For absolute non-branch instructions (LODA, STRA, etc.), direct loads
and stores can be done only on the current page. Eg. this will not work
as expected:
$2000: lodi,r0 $51
$2002: stra,r0 $1800
$2005: retc,un
because address $3800 will be written to instead of address $1800. But you can do an indirect load/store to any address. Eg.
$2000: lodi,r0 $51
$2002: stra,r0 *$2007
$2005: retc,un
$2007: dw $1800
will work correctly (although unfortunately it is slower than a direct access). Also, sometimes you can take advantage of mirroring to perform your work on the current page and let the machine mirror it to the other pages. For example, the $3800 in the example above is a mirror of $1800 on Emerson and Tele-Fever and therefore would in fact work on those machines (but not on a Palladium).
The operand field (two bytes) for absolute non-branch instructions is as follows (for eg. LODA,reg opcode):
bit 15: indirect addressing flag
bits 14..13: index control:
%00 = no indexing
reg is destination register
%01 = pre-increment indexing (++)
reg is index register
r0 is destination register
%01 = pre-decrement indexing (--)
reg is index register
r0 is destination register
%11 = normal indexing
reg is index register
r0 is destination register
bits 12.. 0: offset ($0000..$1FFF) (8K range) from start of page ($0/$2000/$4000/$6000)
Absolute branch instructions (BCTA, BSTA, etc.) are not subject to this restriction
(since they use 15 rather than 13 bits for the address)
and therefore can perform direct (or indirect) branches to anywhere in the 32K memory map.
The operand field (two bytes) for absolute branch instructions is:
bit 15: indirect addressing flag
bits 14.. 0: absolute address ($0000..$7FFF) (32K range)
The effective address is decoded by a real 2650 after the decision is made about whether a branch will be taken, not before. This is important because "entering the indirect addressing sequence adds two cycles (6 clock periods) to the execution time of an instruction." The 2650 manual seems to imply elsewhere that the effective address is calculated before the instruction itself is executed. However, this has now been proven to be wrong. The time penalty for indirection is applied only if the branch is actually taken.
EORZ r0 is always better than LODI,r0 $00.
BCTA,un $003F (or less), or BCTA,un $7FC0 (or more), are never
better than ZBRR. And likewise for BSTA vs. ZBSR.
COMZ r0 is always better than CPSL $C0. Both yield CC=EQ.
These are all the same in effect, size and speed:
ANDI,Rn $FF
EORI,Rn $00
IORI,Rn $00
All set CC according to r0.
These are both the same in effect, size and speed:
LODZ r0 (indeterminate!)
IORZ r0
Both set CC according to r0.
Note that LODZ r0 can (and in fact does, on the particular real Australian PAL Emerson Arcadia 2001 tested) have indeterminate side effects (and therefore is not really equivalent to IORZ r0).
These are both the same in effect, size and speed:
LODI,rn $FF
IORI,rn $FF
Both set rn to $FF and set CC to LT.
These are both the same in effect, size and speed:
LODI,rn $0
ANDI,rn $0
Both set rn to $00 and set CC to EQ.
Project Numbers
Electronics Australia:
Project | Reference | Description | EA Issue | Pages | Main chip(s) | Retailer |
![]() | 2/CC/16
2/CC/17 | Video Data Terminal | Jan 1977
Feb 1977 | 32-37
42-47 | Signetics 2513 character generator
Nat. Semi. MM5740AAF keyboard encoder | ? |
![]() | 2/CC/18 | 2650 Baby Computer | Mar 1977 | 68-69,71-73 | Signetics 2650 CPU | AT ($75 in Feb '78) |
![]() | 2/CC/19 | CUTS cassette interface | Apr 1977 | 40-45 | Signetics 555 timer | ? |
77up5 | 8/M/13 | "Mini-SCAMP" computer | Apr 1977 | ? | SC/MP CPU | ? |
![]() | 2/CC/23 | Low Cost VDU | Feb 1978 | 64-65,67-68 | Signetics 2513 character generator | AT ($99.50 in Feb-Apr '78) |
![]() | 2/CC/25? | ├ Video modulator (& power supply) for Low Cost VDU | Apr 1978 | 48-49,51,53,55-56 | - | AT ($22.50 in Feb '78) |
![]() | 2/CC/25 | ├ Keyboard for Low Cost VDU | Apr 1978 | 48-49,51,53,55-56 | - | ? |
![]() | 2/CC/30 | └ Alternative keyboard for Low Cost VDU | Sep 1978 | 92-93 | MM5303M | ? |
![]() | 2/CC/26 | 2650 Mini Computer | May 1978 | 54-58 | Signetics 2650 CPU | ? |
![]() | 2/CC/32 | ├ Expansion Board for 2650 Mini Computer | Nov 1978 | 70-73,75-76 | - | ? |
![]() | 2/CC/33 | ├ Extra RAM for 2650 Mini Computer | Dec 1978 | 83,85,87-88 | 2114 SRAMs | ? |
![]() | 2/CC/35 | └ EPROM Programmer for 2650 Mini Computer et al. | Feb 1979 | 84-86,88-89 | 2704/2708 EPROMs | ? |
78ut9 | 2/CC/28
2/CC/29 | Ultra Low Cost VDU | Aug 1978
Sep 1978 | 82-86
82-83,85-87 | Signetics 2513 character generator
Motorola 6800 CPU | ? |
? | 2/CC/46 | └ Serial Interface for Ultra Low Cost VDU | Nov 1979 | 83,85,87-88 | Signetics 2536 UART | ? |
Electronics Today International:
Project | Description | Magazine | Pages | Main chip(s) | Retailer |
ETI-560 | Mains Cable Seeker | ETI AU May 80 | ? | - | ? |
![]() | Low Cost VDU | ETI UK Aug 76
ETI UK Sep 76 ETI UK Oct 76 | 56-57
10-16 30-31 | Signetics 2513 character generator | RF Equipment Spares (£445 in Oct '76) |
![]() | VDU | ETI AU Jan 77
ETI AU Feb 77 ETI AU Mar 77 | 95-99
69-77 81-84,87-89 | Signetics 2513 character generator | AT ($158.50 in Mar '77), Orbit |
ETI-630 | ├ Hex display for ETI-631 or SCMPIO | ETI AU Dec 76 | 56-? | ? | AEC, AT ($13.75 in Dec '76) |
![]() | ├ ASCII keyboard & encoder | ETI AU Dec 76 | 47-52 | Harris HD0165 keyboard encoder | AEC, AT, Orbit |
ETI-631F | ├ ASCII keyboard & encoder for System 68 | ETI UK Apr 77 | 25-30 | Harris HD0165 keyboard encoder | ? |
![]() | ├ ASCII keyboard & encoder | ETI AU Apr 77 | 55-59 | 4078 glue logic | AEC, AT, Orbit |
![]() | └ TV Sync Generator for ETI-632 (and others) | ETI AU Jan 77 | 65-68 | 4072 counter | AEC, AT ($17.75 in Mar '77) |
ETI-634 | EDU interface | ETI AU Aug 78 | ? | Intel 8080 CPU | - |
![]() | S-100 Microcomputer Power Supply | ETI AU Sep 77 | 66-69 | - | - |
![]() | ├ Low Cost S-100 Motherboard | ETI AU May 80 | 52-54 | - | ? |
![]() | ├ 16K S-100 RAM card | ETI AU Feb 79 | 53-57 | 2114 SRAMs | ? |
![]() | └ S-100 PROM board | ETI AU Mar 81 | ? | ? | ? |
![]() | CUTS cassette interface | ETI AU Jan 78 | 25-28 | Signetics 555 timer | AEC, AT, DSE, SV |
ETI-638 | EPROM programmer | ETI AU Jul 78 | ? | Motorola 6800 CPU | AEC, AT |
ETI-639 | Computerized musical doorbell | ETI AU Mar 78 | ? | ? | AT |
![]() aka DG640, MW640 | S-100 VDU for 2650-based machines (and others) | ETI AU Apr 78
ETI AU May 78 ETI AU Jun 78 | 32-35
89-95 57-60 | MCM6574/MCM6674 character generator | AT, Orbit, SV |
![]() | └ S-100 Programmable Character Generator for ETI-640 (and others) | ETI AU Jun 80 | 67-74 | 2114 SRAMs | AT ($150-$175 (est.) in Jun '80; $140 in Jul '80) |
ETI-641 | S-100 thermal printer based on Philips EUR-10E023LE | ETI AU Sep 78 | ? | Intel 8080 CPU | - |
ETI-643 | Universal EPROM programmer card | ETI AU Dec 79
ETI AU Jan 80 | ?
? | Intel 8080 CPU | ? |
ETI-644 | Modem | ETI AU Oct 82
ETI Computer Projects #1 | ?
? | ? | Altronics, Jaycar, Microtrix, RIE |
ETI-644A | └ A revision for the ETI-644 modem | ETI Computer Projects #1 | ? | ? | ? |
![]() | A turtle robot (aka "Tasman Turtle") | ETI AU Feb 82
ETI AU Apr 82 ETI AU May 82 ETI AU Jun 82 | 82
29-35 24-29,32,36 42-46,48,51 | SAA1027 motor controllers | Flexible Systems (assembled) ($799 in Feb '82)
ETI AU (minimum kit) ($349 in Apr-Jul '82) |
ETI-646 | ├ A hand controller for the turtle robot | ETI AU Jul 82 | 84-86 | 4011 quad NAND gates | Flexible Systems ($55 (kit) and $79 (assembled) in Jul '82) |
ETI-647 | └ Speech synthesizer for the turtle robot (and others) (aka "Turtle Talk") | ETI AU Sep 82
ETI AU Oct 82 | 81-86
81-84,86-89 | MM54104 SPC
| Flexible Systems ($240 in Jun '82), ETI AU ($250 in Oct '82), RIE |
ETI-648 | Micro-Grasp robot arm | ETI Computers & Computing #4 | 6-13,15-19 | - | ? |
ETI-649 | Light pen for ![]() | ETI Computers & Computing #4 | ? | ? | ? |
ETI-650 | STAC (Standard Timer And Controller) timer | ETI AU Nov 78 | ? | ? | AT |
ETI-651 | Binary-to-hex number converter | ETI AU Jun 79 | ? | Signetics 2650 CPU | ? |
ETI-652 | Atari joystick interface for System 80 | ETI AU Aug 82 | ? | ? | ? |
ETI-653 | 16-channel computer output driver | ETI Computers & Computing #4 | ? | ? | ? |
ETI-654 | General purpose Apple I/O card | ETI Computers & Computing #4 | ? | ? | ? |
ETI-656 | EPROM debugger | ETI Computer Projects #1 | 35-37 | 2716 EPROM | ? |
ETI-658 | RS-232 breakout box | ETI Computer Projects #1 | ? | ? | ? |
ETI-659 | VIC-20 audio cassette interface | ETI AU May 84 | ? | ? | ? |
ETI-660 | Learner's microcomputer | ETI AU May-Jun 81, Oct-Nov 81 | ? | 1802 CPU | AEC ($99 in Apr '82) |
ETI-661 | └ Chord tutor adaptor for ETI-660 | ETI AU Nov 84 | ? | ? | ? |
ETI-662 | 6802 processor board | ETI AU Apr 84 | ? | Motorola 6802 CPU | ? |
ETI-664 | Hobbybot robot | ETI AU Nov-Dec 85 | ? | ? | ? |
ETI-665 | Computing routing switch | ETI AU Oct 85 | ? | ? | ? |
ETI-666 | Printer switch | ETI AU Feb 85 | ? | ? | ? |
ETI-667 | Printer sharer | ETI AU Apr 85 | ? | ? | ? |
ETI-668 | ![]() | ETI AU Feb 83 | ? | ? | ? |
ETI-669 | └ Upgrade for ETI-668 | ETI AU Sep 88 | ? | ? | ? |
ETI-671 | ![]() | ETI Computer Projects #1 | ? | ? | ? |
ETI-672 | ![]() | ETI Computer Projects #1 | ? | ? | ? |
ETI-673 | ![]() | ETI Computer Projects #1 | ? | ? | ? |
ETI-674 | ![]() | ETI AU Dec 83 | ? | ? | ? |
ETI-675 | ![]() | ETI Computer Projects #1 | ? | ? | ? |
ETI-676 | ![]() | ETI Computer Projects #1 | ? | ? | ? |
ETI-677 | Chatterbox voice synthesiser for Centronics parallel port | ETI AU Jan 85 | ? | Votrax SC-01 synthesizer | ? |
ETI-678 | ![]() | ETI Computer Projects #1 | ? | ? | ? |
ETI-679 | ![]() | ETI AU Jun 85 | ? | ? | ? |
ETI-680 aka DG680 | Microcomputer | ETI AU Nov 79 | ? | Zilog Z80 CPU | ? |
ETI-683 | Computer controller | ETI AU Dec 84 | ? | ? | ? |
ETI-684 | Intelligent modem | ETI AU Dec 85, Feb-Mar 86, Jun-Aug 86 | ? | ? | ? |
![]() | 2650-based Single Board Computer for S-100 bus | ETI AU Dec 81 | ? | Signetics 2650A/2650A-1 CPU | ? |
![]() | ├ Low Cost ASCII Keyboard for ETI-685 (and others) | ETI AU May 82 | 99-103 | GI AY-5-2376 keyboard encoder | AEC, Amtex, Electronic Agencies, RIE |
![]() | └ PPI-based EPROM Programmer for ETI-685 (and others) | ETI AU Oct 82
ETI Computer Projects #1 | 72-73,75-78
40-44,75 | 2708/2716 EPROMs | Ron Koenig |
ETI-687 | VZ-200 update | ETI AU Jul 86 | ? | ? | ? |
ETI-688 | Bipolar PROM Programmer | ETI AU Jun 83
ETI Computers & Computing #4 | 46-49
20-23 | - | ? |
ETI-689 | Bus sharing switch | ETI Jan 86 | ? | ? | ? |
ETI-690 | "Little Big Board" computer | ETI Computer Projects #1 | ? | Zilog Z80A CPU | ? |
![]() ![]() | Current Loop Interface (TTY to RS-232 adapter) | ETI AU Jan 85 | 68-69,72 | ? | ? |
![]() | Pong game (B&W) | ETI AU Nov 76
ETI UK May 77 | 44-51
12-16 | General Instrument AY-3-8500 | Appollo ($52.50 in Jan '77), AT, DSE |
![]() | ├ Pong game (colour) | - | - | GI AY-3-8500 + AY-3-8515 | Appollo ($82.50 in Jan '77) |
![]() | ├ Colour converter | - | - | General Instrument AY-3-8515 | Appollo ($34.50 in Jan '77) |
![]() | └ Rifle kit | ETI AU Mar 77 | 54-55 | - | Appollo ($25 in Jan '77), DSE |
![]() | Stunt cycle game | ETI AU Jun 78 | 31-37 | General Instrument AY-3-8760 | DSE, Orbit |
![]() | Tank game | ETI AU Oct 78 | ? | General Instrument AY-3-8710 | AEC, DSE, Orbit |
ETI-630 scan is missing because the available scan of ETI AU Dec '76 is missing pages 55-62.
ETI-638,641,643,647 can be connected to any CPU (but the provided software is not written for the 2650).
ETI-645 (and therefore also its accessory projects) is compatible with ETI-685 as mentioned in ETI Aug 1982, p. 91.
ETI-685 can use PIPBUG, BINBUG or SBCBUG (which is basically BINBUG + ACOS).
It is compatible with
ETI-635,636,640,642,645,670,681,682,686.
The cassette interface (promised in ETI AU Dec 1981, p.
104) and real-time clock/calendar (promised in ETI AU
Mar 1982, p. 95) were never published.
All dollar prices in the preceding two tables are in $AUD. Prices are generally for kits,
except where otherwise specified, and are generally inclusive of taxes but exclusive of postage.
Appollo (with two Ps) is really how the company name was spelt.
AEC = All Electric Components (formerly ED&E Sales), AT = Applied Technology, DSE = Dick Smith Electronics, RIE = Rod Irving Electronics, SV = Silicon Valley.
Other magazines and non-projects:
Project | Description | Retailer | Magazine | Price |
![]() | Kansas City cassette interface (assembled) | Applied Technology | EA Nov '77, p. 98 | $AUD37.50 |
![]() | Kansas City cassette interface (kit) | Applied Technology | EA Nov '77, p. 98 | $AUD22.50 |
MW850 | S-100 motherboard | Applied Technology (Owen J. Hill) | ? | ? |
MW864 | 64K SRAM | Applied Technology | ? | ? |
MW6545 | CRT controller (S-100 card) (based around MOS/Rockwell 6545 CRT controller chip?) | Applied Technology (John Wilmshurst) | ? | ? |
![]() | Universal Keyboard in Teletype Model 33 ASR layout | Applied Technology | ETI AU Feb '78, p. 70 | $AUD59.50 |
![]() | ├ Number pad | Applied Technology | ETI AU Feb '78, p. 70 | $AUD16.50 |
![]() | ├ Cursor control | Applied Technology | ETI AU Feb '78, p. 70 | $AUD7.50 |
![]() | └ Spare key switches | Applied Technology | ETI AU Feb '78, p. 70 | $AUD2 |
![]() | Signetics KT9500 (fully buffered kit) | Signetics/Philips
Applied Technology | EA Sep '76, p. 64-67
EA Dec '77, p. 72 | $AUD165
$AUD199 |
![]() | Signetics KT9500 (motherboard with component kit) | Applied Technology | EA Dec '77, p. 72 | $AUD35 |
![]() | Prototyping card | Signetics/Philips | EA Sep '76, p. 64-67 | $AUD345 |
![]() | Evaluation kit (Adaptable Board Computer) | Signetics/Philips | EA Sep '76, p. 64-67 | $AUD245 |
![]() | Prometheus assembler | Signetics/Philips | ? | ? |
![]() | 4K RAM expansion board | Signetics/Philips | EA Sep '76, p. 64-67 | $AUD400 |
![]() | Front panel kit (TTY replacement) (for Baby 2650) | Applied Technology | EA Mar '77, p. 64 | $AUD49.50 |
![]() | EA Baby 2650 -> KT9500 conversion kit | Applied Technology | EA Dec '77, p. 72 | $AUD142 |
![]() | Fully encoded ASCII keyboard | Elektor | Elektor Nov '78, p. 6-11 | £6.50/$USD14.35 |
![]() | Elekterminal | Elektor | Elektor Dec '78, p. 16-24 | £10.85/$USD23.95 |
![]() | AY-3-8500-based Pong game | Elektor | Elektor Jul/Aug '77, p. 40-41 | £2.05/$USD4.50 |
CT750 was "adapted from a design described in Radio Electronics" (presumably sometime in Nov '75-May '77)
but this design has not been located.
Dark grey items are irrelevant. Light grey items are semi-relevant (eg. could be feasibly adapted).
Elektor magazine articles pertaining to the Elektor TV Games Computer are covered in
its Coding Guide
.
Component Numbers
Component | Manufacturer | Description | Used in |
? | ? | Main transformer, 10V/2A secondary | ![]() |
? | ? | Zener diode | ![]() |
? | ? | 5.6V/400mW zener diode | ![]() |
1N4001 | ? | Silicon diode | ![]() |
1N4003 | ? | Silicon diode | ![]() |
1N4004 | ? | Silicon diode | ![]() |
1N4148
1N484A 1N914 1N914A | ? | Silicon diode | ![]() ![]() ![]() ![]() ![]() ![]() |
1702A | Intel | MOS erasable PROM | ![]() |
OA91 | ? | Germanium diode | ![]() |
2N2219 | ? | Silicon NPN transistor | ![]() |
2N2894
2N4258 | ? | Silicon NPN transistor | ![]() |
2N3055 | ? | Silicon NPN transistor | ![]() ![]() |
2SB561C | ? | Transistor | ![]() |
2101-1N | ? | 256*4-bit (128-byte) SRAM | ![]() |
2102
2102-1 2102A4 2102AL4 21L02-1 | Signetics | 1024*1-bit (128-byte) SRAM | ![]() ![]() ![]() ![]() |
2112B
2112-2 2112-A4 MM2112-4 | ? | 256*4-bit (128-byte) SRAM | ![]() ![]() ![]() ![]() |
2114
2114-A4 2114L-4 TMS2114L-45NL | Fairchild?
Fairchild? Fairchild? TI | 1024*4-bit (512-byte) SRAM | ![]() ![]() ![]() ![]() ![]() ![]() |
2332 | Commodore | 4K PROM | ![]() |
? | ? | Inductor? 1µH | ![]() |
2410077 | ? | Ferrite choke coil (resistor type) 10µH | ![]() |
2410144 | ? | Ferrite bead 4T | ![]() |
2504 | Signetics | 1024-bit DSR (Dynamic Shift Register) | ? |
2513
RO-3-2513 | Signetics
General Instrument | Character Generator | ![]() |
2519 | Signetics | 40-bit SSR (Static Shift Register) | ? |
2602 | Signetics | 1024*1-bit (128-byte) SRAM | ? |
2606 | Signetics | 256*4-bit (128-byte) SRAM | ![]() |
2608 (CN0035) | Signetics | 1K PROM (PIPBUG 1 monitor) | ![]() |
? | ? | Trimmer capacitor, 0..22pF | ![]() |
2610007 | ? | Trimmer capacitor, 7..25pF | ![]() |
2616 | Signetics | 2K PROM | ![]() ![]() |
2621
2621-I 2621 N | Signetics | PAL USG (Universal Sync Generator) | ![]() ![]() ![]() ![]() |
2622 | Signetics | NTSC USG (Universal Sync Generator) | ![]() |
2632 | Signetics | 4K PROM | ![]() |
2636
2636-I 2636 N | Signetics | PVI (Programmable Video Interface) | ![]() ![]() ![]() |
2637 | Signetics | UVI (Universal Video Interface) | ![]() |
2650 | Signetics | CPU (<= 1.25 MHz, 1975) | ![]() ![]() ![]() ![]() ![]() ![]() |
2650-1 | Signetics | CPU (<= 2 MHz, <= 1976) | ? |
2650A
2650-AI 2650A N | Signetics | CPU (<= 1.25 MHz, 1977) | ![]() ![]() ![]() ![]() ![]() |
MAB 2650A | Philips | CPU (<= 1.25 MHz, 197x) | ![]() |
2650A-1 | Signetics | CPU (<= 2 MHz, 1977) | ![]() |
2650B | Signetics | CPU (<= 1.25 MHz, 1977) | None? |
2650B-1 | Signetics | CPU (<= 2 MHz, 1977?) | None? |
2650-P-02 | Synertek | *NOT* Signetics 2650-compatible! | - |
2651 | Signetics | PCI (Programmable Communications Interface) | ![]() |
2652 | Signetics | Multi-Protocol Comms Circuit (incl. Sync. Data Link Control (SDLC)) | ? |
2653 | Signetics | Polynomial Generator/Checker | ? |
2655
8255A | Signetics
Intel | PPI (Programmable Peripheral Interface) | ![]() |
2656 | Signetics | SMI (System Memory Interface) | ![]() |
2657 | Signetics | DMA (Direct Memory Access) controller | ? |
2661 | Signetics | EPCI (Enhanced Programmable Communication Interface) | ? |
2670 | Signetics | Display Character and Graphics Generator | ? |
2671 | Signetics | Programmable Keyboard and Communications Controller | ? |
2672 | Signetics | Programmable Video Timing Controller | ? |
2673 | Signetics | Video Attributes Controller | ? |
2681 | Signetics | DUART (Dual Asynchronous Receiver/Transmitter) | ? |
? | ? | Capacitor, 8.2pF | ![]() |
? | ? | Capacitor, 15pF | ![]() |
? | ? | Capacitor, 22pF | ![]() |
? | ? | Capacitor, 27?pF | ![]() |
? | ? | Capacitor, 33pF | ![]() |
? | ? | Capacitor, 120pF | ![]() |
? | ? | Capacitor, 220pF | ![]() |
? | ? | Capacitor, 470pF | ![]() |
? | ? | Capacitor, 1nF | ![]() ![]() |
? | ? | Capacitor, 3.3nF | ![]() |
? | ? | Capacitor, 3.9nF | ![]() |
? | ? | Capacitor, 4.7nF | ![]() |
? | ? | Capacitor, 10nF | ![]() |
? | ? | Capacitor, 47nF | ![]() ![]() |
? | ? | Capacitor, 100nF | ![]() ![]() |
? | ? | Capacitor, 150nF MKH | ![]() |
? | ? | Capacitor, 220nF | ![]() |
? | ? | Capacitor, 2.2µF | ![]() |
? | ? | Capacitor, 10µF/16V | ![]() ![]() |
? | ? | Capacitor, 47µF | ![]() |
? | ? | Capacitor, 100µF/6V | ![]() ![]() |
? | ? | Capacitor, 220µF/6V | ![]() |
? | ? | Capacitor, 1mF | ![]() |
? | ? | Capacitor, 4.7mF/16V | ![]() ![]() |
? | ? | Tantalum capacitor, 220nF/16V | ![]() |
? | ? | Tantalum capacitor, 1µF/16V | ![]() |
? | ? | Tantalum capacitor, 2.2µF/16V | ![]() |
? | ? | Electrolytic or tantalum capacitor, 1.5µF/35V | ![]() |
2703 10 2 | ? | Electrolytic capacitor, 10µF/10V | ![]() |
2703 20 3 | ? | Electrolytic capacitor, 200µF/10V | ![]() |
2703 22 4 | ? | Electrolytic capacitor, 2.2mF/16V | ![]() |
2708 | ? | 1024*8-bit (1K) EPROM | ![]() ![]() |
2716 | Texas Instruments | 2K*8-bit (2K) EPROM | ![]() ![]() ![]() ![]() ![]() |
? | ? | NPO ceramic capacitor, 47pF | ![]() |
? | ? | Ceramic capacitor, 56pF | ![]() |
? | ? | Ceramic capacitor, 68pF | ![]() |
2722 27 3-3 | ? | Ceramic capacitor, 270pF/25V | ![]() |
? | ? | NPO ceramic capacitor, 330pF | ![]() |
2722 50 3-3 | ? | Ceramic capacitor, 500pF/25V | ![]() |
2722 10 4-1 | ? | Ceramic capacitor, 1nF/25V | ![]() |
? | ? | LV polyester capacitor, 47nF | ![]() |
? | ? | LV polyester capacitor, 220nF | ![]() |
2722 40 5-1 | ? | Ceramic capacitor, 40nF/25V | ![]() |
2732
D2732D | ?
NEC | 4K*8-bit (4K) EPROM | ![]() ![]() ![]() |
2732 47 5-3 | ? | Mylar capacitor, 47nF/50V | ![]() |
2732 10 6-1 | ? | Mylar capacitor, 100nF/25V | ![]() |
2732 10 6-3 | ? | Mylar capacitor, 100nF/50V | ![]() |
2732 47 6-3 | ? | Mylar capacitor, 470nF/50V | ![]() |
28C16 | Intel | 2K EEPROM | ![]() |
2981 | ? | ? | ![]() |
? | ? | Potentiometer 220Ω | ![]() |
? | ? | Potentiometer 1,000Ω | ![]() |
? | ? | Potentiometer 47,000Ω | ![]() |
? | ? | Joystick potentiometer 680,000Ω | ![]() |
? | ? | Preset potentiometer 1,000Ω | ![]() |
? | ? | Preset potentiometer 2,200Ω | ![]() |
? | ? | Preset potentiometer 2,500Ω (2,200Ω) | ![]() |
? | ? | Resistor ⅛W 1,800Ω | ![]() |
? | ? | Resistor ⅛W 22,000Ω | ![]() |
? | ? | Resistor ⅛W 150,000Ω | ![]() |
? | ? | Resistor ⅛W 180,000Ω | ![]() ![]() |
3200 39 1 | ? | Resistor ¼W 3.9Ω | ![]() |
3200 56 2 | ? | Resistor ¼W 56Ω | ![]() |
3200 68 2 | ? | Resistor ¼W 68Ω | ![]() |
3200 10 3 | ? | Resistor ¼W 100Ω | ![]() ![]() |
3200 15 3 | ? | Resistor ¼W 150Ω | ![]() ![]() |
3200 18 3 | ? | Resistor ¼W 180Ω | ![]() |
3200 22 3 | ? | Resistor ¼W 220Ω | ![]() ![]() ![]() |
3200 27 3 | ? | Resistor ¼W 270Ω | ![]() |
3200 33 3 | ? | Resistor ¼W 330Ω | ![]() ![]() |
3200 39 3 | ? | Resistor ¼W 390Ω | ![]() |
3200 47 3 | ? | Resistor ¼W 470Ω | ![]() ![]() ![]() |
3200 68 3 | ? | Resistor ¼W 680Ω | ![]() ![]() |
3200 82 3 | ? | Resistor ¼W 820Ω | ![]() |
3200 10 4 | ? | Resistor ¼W 1,000Ω | ![]() ![]() ![]() ![]() |
3200 12 4 | ? | Resistor ¼W 1,200Ω | ![]() ![]() |
3200 15 4 | ? | Resistor ¼W 1,500Ω | ![]() ![]() ![]() |
3200 20 4 | ? | Resistor ¼W 2,000Ω | ![]() |
3200 22 4 | ? | Resistor ¼W 2,200Ω | ![]() ![]() ![]() ![]() |
3200 27 4 | ? | Resistor ¼W 2,700Ω | ![]() |
3200 33 4 | ? | Resistor ¼W 3,300Ω | ![]() ![]() |
3200 47 4 | ? | Resistor ¼W 4,700Ω | ![]() ![]() ![]() ![]() |
3200 56 4 | ? | Resistor ¼W 5,600Ω | ![]() ![]() |
3200 68 4 | ? | Resistor ¼W 6,800Ω | ![]() |
3200 10 5 | ? | Resistor ¼W 10,000Ω | ![]() ![]() ![]() ![]() |
3200 12 5 | ? | Resistor ¼W 12,000Ω | ![]() ![]() |
3200 15 5 | ? | Resistor ¼W 15,000Ω | ![]() ![]() |
3200 18 5 | ? | Resistor ¼W 18,000Ω | ![]() ![]() |
3200 22 5 | ? | Resistor ¼W 22,000Ω | ![]() ![]() |
? | ? | Resistor 27,000Ω | ![]() |
3200 33 5 | ? | Resistor ¼W 33,000Ω | ![]() |
3200 39 5 | ? | Resistor ¼W 39,000Ω | ![]() ![]() |
3200 47 5 | ? | Resistor ¼W 47,000Ω | ![]() ![]() |
? | ? | Resistor 56,000Ω | ![]() |
3200 82 5 | ? | Resistor ¼W 82,000Ω | ![]() |
3200 10 6 | ? | Resistor ¼W 100,000Ω | ![]() ![]() ![]() |
3200 18 6 | ? | Resistor ¼W 180,000Ω | ![]() |
3200 22 6 | ? | Resistor ¼W 220,000Ω | ![]() |
3200 47 6 | ? | Resistor ¼W 470,000Ω | ![]() ![]() |
? | ? | Resistor 3W 0.22Ω | ![]() |
? | ? | Resistor 3,900Ω | ![]() |
? | ? | Resistor 1,000,000Ω | ![]() |
? | ? | Resistor 1,500,000Ω | ![]() |
? | ? | Resistor 2,000,000Ω | ![]() |
? | ? | Resistor 2,200,000Ω | ![]() |
3410025 | ? | 3.579545 MHz oscillator | ![]() |
SKY8867 | ? | 8.867 MHz oscillator | ![]() ![]() |
? | ? | ~27 MHz oscillator | ![]() |
? | ? | 100Ω/500mW loudspeaker | ![]() |
3450012 | ? | NTSC modulator | ![]() |
3624 | Intel? | 512*8-bit (512-byte) PROM | ![]() |
4N28 | ? | Opto-coupler | ![]() |
4011
HEF 4011 | ? | Quad 2-input NAND gate | ![]() ![]() |
4015 | ? | Dual 4-stage shift register | ![]() |
4016
HEF4016 4066 HEF4066BP | ? | Quad analog switch | ![]() ![]() ![]() ![]() ![]() |
4024 | ? | 7-stage binary ripple counter | ![]() |
CD 4040 | ? | 12-stage binary ripple counter | ![]() |
4049 | ? | Hex inverter (CMOS) | ![]() |
4051 | ? | Single 8-channel analog multiplexer/demultiplexer | ![]() |
4053
CD4053 CD4053B HEF4053B TC4053BP | ?
? ? ? Toshiba | Triple 2-channel multiplexer/demultiplexer | ![]() ![]() |
4069
CD4069CN | ? | Hex inverter gate | ![]() ![]() |
4070
CD4070BE | ?
RCA | Quad 2-input XOR gate | ![]() ![]() |
4072 | ? | Dual 4-input OR gate | ![]() |
4081
CD4081BE | ?
RCA | Quad 2-input AND gate | ![]() ![]() |
4097 | ? | Single differential 8-channel analog multiplexer/demultiplexer | ![]() |
CD 4099 | ? | 8-bit addressable latch | ![]() |
40097 | ? | 3-state hex driver | ![]() |
4116 | ? | 2K DRAM | ![]() |
HEF 4528 | ? | Dual monostable multivibrator | ![]() |
5082-4870450 | Hewlett-Packard | LED indicator | ![]() |
555
NE555 | Signetics
? | Timer | ![]() ![]() ![]() ![]() ![]() ![]() |
555-3007 | Dialco | LED indicator | ![]() |
6116 | IDT | 2048*8-bit (2K) SRAM | ![]() |
7400
74LS00 | ? | Quad 2-input NAND gate | ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
741 | ? | Operational amplifier | ![]() |
7402
74LS02 HD74LS02P | ? | Quad 2-input NOR gate | ![]() ![]() ![]() ![]() ![]() ![]() |
7403
74LS03 | ? | Quad 2-input NAND gate | ![]() ![]() |
7404
74LS04 74LS04N 74S04 DM74LS04N MM74C04N | ?
? ? ? Nat. Semi. Nat. Semi. | Hex 1-input inverter gate | ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
74LS05
741S05PC | ?
Fairchild | Hex 1-input inverter gate | ![]() ![]() ![]() |
7406 | ? | Hex 1-input open collector inverter gate | ![]() ![]() ![]() |
7407 | ? | Hex buffer gate | ![]() |
7408
74LS08 | ? | Quad 2-input AND gate | ![]() ![]() ![]() ![]() ![]() |
7410
74LS10 SN74LS10N-10 | ?
? TI | Triple 3-input NAND gate | ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
7411
74LS11 | ? | Triple 3-input AND gate | ![]() ![]() |
74LS13 | ? | Dual 4-input NAND gate | ![]() |
7414
74LS14 | ? | Hex 1-input inverter gate | ![]() ![]() ![]() ![]() ![]() |
7420
74LS20 | ? | Dual 4-input NAND gate | ![]() ![]() ![]() ![]() |
7421
74LS21 | ? | Dual 4-input AND gate | ![]() ![]() ![]() ![]() |
7425 | ? | Dual 4-input NOR gate with strobe | ![]() |
74LS26 | ? | Quad 2-input NAND gate | ![]() |
74LS27 | ? | Triple 3-input NOR gate | ![]() ![]() |
7430
74LS30 | ? | Single 8-input NAND gate | ![]() ![]() ![]() ![]() |
7432
74LS32 | ? | Quad 2-input OR gate | ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
7438
74LS38 | ? | Quad 2-input NAND open collector gate | ![]() |
7442 | ? | BCD to decimal decoder | ![]() ![]() |
74LS51 | ? | ? | ![]() |
7470 | ? | AND-gated positive edge triggered J-K flip-flop, asynchronous preset and clear | ![]() |
7473
74LS73 | ? | Dual J-K flip-flop, asynchronous clear | ![]() |
7474
74LS74 | ? | Dual D positive edge triggered flip-flop, asynchronous preset and clear | ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
7475
74LS75 | ? | 4-bit bistable latch, complementary outputs | ![]() ![]() |
74LS76 | ? | Dual J-K flip-flop, asynchronous preset and clear | ![]() |
7485
74LS85 | ? | 4-bit magnitude comparator | ![]() ![]() ![]() |
7486
74LS86 74LS86N | ? | Quad 2-input XOR gate | ![]() ![]() ![]() ![]() ![]() ![]() |
7490
74LS90 | ? | Decade counter | ![]() ![]() ![]() ![]() |
7492
74LS92 | ? | Divide-by-12 counter | ![]() ![]() |
7493
74LS93 | ? | 4-bit binary counter | ![]() ![]() ![]() |
7495 | ? | 4-bit shift register, parallel in, parallel out, serial input | ![]() |
74LS107 | ? | Dual J-K flip-flop, clear | ![]() |
74109
74LS109 | ? | Dual J-NotK positive-edge-triggered flip-flop, clear and preset | ![]() ![]() ![]() |
74S112
72LS112 | ? | Dual J-K negative-edge-triggered flip-flop, clear and preset | ![]() |
74LS113 | ? | Dual J-K negative-edge-triggered flip-flop, preset | ![]() |
74123
74LS123 | ? | Dual monostable Schmitt trigger | ![]() ![]() ![]() |
74125
74LS125 | ? | Quad bus buffer, negative enable | ![]() ![]() ![]() |
74126 | ? | Quad bus buffer, positive enable | ![]() |
74LS132 | ? | Quad 2-input NAND gate | ![]() ![]() |
74LS135 | ? | Quad XOR/XNOR gate, two inputs to select logic type | ![]() |
74LS136 | ? | Quad 2-input XOR gate | ![]() |
74LS138 | ? | 3:8 line decoder/demultiplexer, inverting outputs | ![]() ![]() ![]() |
74LS139 | ? | Dual 2:4 line decoder/demultiplexer, inverting outputs | ![]() ![]() ![]() ![]() |
74145
74LS145 | ? | 4-bit D flp-flp w/ complementary outputs & reset (keypad inputs) | ![]() |
74148 | ? | 8:3 line priority encoder | ![]() |
74153
74LS153 | ? | Dual 4:1 line selector/multiplexer, non-inverting outputs | ![]() |
74154
74LS154 | Valvo | 4:16 line decoder/demultiplexer, inverting outputs | ![]() ![]() |
74LS155 | ? | Dual 2:4 line decoder/demultiplexer, totem pole | ![]() |
74LS156
74LS156PC | ?
Fairchild | Dual 2:4 line decoder/demultiplexer, open collector | ![]() ![]() ![]() ![]() |
74157
74LS157 | ? | Quad 2:1 line selector/multiplexer, non-inverting outputs | ![]() ![]() ![]() ![]() |
74LS161 | ? | Synchronous presettable 4-bit binary counter, asynchronous clear | ![]() ![]() ![]() |
74163
74LS163 74LS163A | ? | Synchronous presettable 4-bit binary counter, synchronous clear | ![]() ![]() ![]() |
74LS164 | ? | 8-bit SIPO shift register, asynchronous clear, not output latch | ![]() |
74165
74LS165 | ? | 8-bit PISO shift register, parallel load, complementary outputs | ![]() ![]() |
74166
74LS166 | ? | Parallel-load 8-bit shift register | ![]() ![]() ![]() |
74174
74LS174 | ? | Hex D flip-flop, common asynchronous clear | ![]() ![]() |
74LS175 | ? | Quad D edge-triggered flip-flop, comp. outputs and async. clear | ![]() ![]() |
74191 | ? | Synchronous presettable up/down 4-bit binary counter | ![]() |
74LS193 | ? | Synchronous presettable up/down 4-bit binary counter, clear | ![]() |
74LS221 | ? | Dual monostable multivibrator | ![]() |
74LS240 | ? | ? | ![]() |
74LS241 | ? | Octal buffer, non-inverting outputs | ![]() |
74LS243 | ? | ? | ![]() |
74244
74LS244 L4LS244 | ? | Octal buffer, non-inverting outputs | ![]() ![]() ![]() ![]() |
74LS245
8T245 | ? | Octal bus transceiver, non-inverting outputs | ![]() ![]() ![]() ![]() |
74LS251 | ? | 8:1 selector/multiplexer, complementary outputs | ![]() ![]() |
74LS253 | ? | ? | ![]() |
74258 | ? | Quad 2:1 multiplexer (3-state) (keypad inputs) | ![]() |
74LS258
74LS258APC | ?
Signetics | Quad 2:1 selector/multipler, inverting outputs | ![]() ![]() ![]() |
74LS260
74S260 | ? | Dual 5-input NOR gate | ![]() ![]() |
74273
74LS273 | ? | 8-bit register, asynchronous clear | ![]() ![]() ![]() ![]() |
74LS283 | ? | 4-bit binary full adder | ![]() |
74LS365 | ? | Hex buffer, non-inverting outputs | ![]() |
74367
74LS367 8097 8T97 | ? | Hex buffer, non-inverting outputs | ![]() ![]() ![]() |
74368
74LS368 8098 8T98 | ? | Hex buffer, inverting outputs | ![]() ![]() ![]() |
74LS373 | ? | Octal transparent latch | ![]() ![]() ![]() |
74C374
74LS374 74LS378PC | ?
? Fairchild | Octal tri-state latch | ![]() ![]() ![]() ![]() ![]() |
74LS378 | ? | 6-bit clock enable | ![]() ![]() |
74LS379 | ? | 4-bit clock enable and complementary outputs | ![]() |
74S387
SFC 71301E 1-0 | ? | 256*4-bit (128-byte) PROM | ![]() |
74LS393 | ? | Dual 4-bit binary counter, asynchronous clear | ![]() |
74S471 | ? | 256*8-bit (256-byte) PROM | ![]() |
74LS514?** | ? | ? | ![]() |
74LS640
74LS640-1 | ? | Octal bus transceiver, inverting outputs | ![]() |
7805
µA7805 LM340T-5.0 | ?
Signetics TI | +5V power regulator | ![]() ![]() ![]() ![]() ![]() ![]() |
7812
µA7812 | ?
Signetics | +12V power regulator | ![]() ![]() |
7905
79L05 | ? | -5V power regulator | ![]() ![]() ![]() |
7912
79L12 | ? | -12V power regulator | ![]() |
79G | ? | Communications controller | ![]() |
8131 | ? | 128*8-bit (128-byte) SRAM? | ![]() ![]() |
81LS95 | ? | Octal tri-state buffer | ![]() |
81LS97 | ? | Octal buffer | ![]() |
81LS98 | ? | Octal buffer | ![]() |
8250 | ? | 1 of 8 decoder | ![]() |
N82S100 | Signetics | FPLA (PROM) | ![]() |
82S103 | Signetics | Bipolar FPGA | ![]() |
82S115 | Signetics | 512*8-bit (512-byte) PROM | ![]() ![]() ![]() ![]() |
82S123 | Signetics | 32*8-bit (32-byte) PROM | ![]() ![]() ![]() |
82S129 | Signetics | 512*8-bit (512-byte) PROM? | ![]() |
82S130 | Signetics | 256*4-bit (256-byte) PROM? | ![]() |
8T15 | ? | E1A driver (RS232) | ![]() |
8T16 | ? | E1A receiver (RS232) | ![]() |
8T26 | ? | Quad bus driver/receiver | ![]() |
8T28 | ? | ? | ![]() |
899-5 R220/330 | Beckman | Resistor network | ![]() |
9344 | Fairchild | 4-bit by 2-bit multiplier | ![]() |
AM25LS2520 | ? | Octal D-type flip-flop | ![]() |
AM9519PC | AMD | DMA (Direct Memory Access) controller | ![]() |
AY-3-8900 | General Instrument | Standard Television Interface Chip | ? |
AY-3-8910 | General Instrument | PSG (Programmable Sound Generator) | ![]() |
AY-5-1013
MM5303 | General Instrument
Motorola | UART (Universal Asynchronous Receiver/Transmitter) | ![]() |
AY-5-2376 | General Instrument | Keyboard encoder | ![]() |
B40C5000 | ? | Power transistor | ![]() |
BC107B
BC547 BC547B | ? | NPN bipolar transistor | ![]() |
BC108
BC548 | ? | NPN bipolar transistor | ![]() ![]() ![]() |
BC177B
BC557 BC557B | ? | Audio amplifier | ![]() |
BC327 | ? | PNP bipolar transistor? | ![]() |
BC337 | ? | NPN bipolar transistor | ![]() ![]() |
BC517 | ? | NPN bipolar transistor | ![]() |
BC558 | ? | NPN bipolar transistor | ![]() |
BD135
BD137 BD139 | ? | Transistor | ![]() |
BD140 | ? | NPN bipolar transistor | ![]() |
BFY90 | ? | Transistor | ![]() |
BF194
BF195 BF254 BF255 BF494 BF495 | ? | Transistor | ![]() |
BF451 | ? | NPN bipolar transistor | ![]() |
BS170 | ? | Field effect transistor | ![]() |
CA324E | RCA | NPN transistor array | ![]() ![]() |
CA3081 | ? | NPN transistor array | ![]() |
CA3130 | ? | Operational amplifier | ![]() |
EM401 | ? | Silicon diode | ![]() |
HDSP 3531
HP 5082-7611 | Hewlett-Packard | 7-segment LED display | ![]() |
SF.F 96364 | Thomson-CSF (Sescosem) | CRT (Cathode Ray Tube) Controller (more advanced than EF9364) | ![]() |
DUS | - | Diode, Universal, Silicon* | ![]() |
EF9364 | Thomson | CRT (Cathode Ray Tube) Controller (less advanced than SF.F 96364) | ![]() |
LF356
LF357 | ? | Operational amplifier? | ![]() |
LM309
LM309K | Texas Instruments | +5V power regulator | ![]() ![]() ![]() |
LM323K | ? | ? | ![]() |
LM339 | Nat. Semi. | Quad differential comparator | ![]() ![]() |
3403 | ? | Quad operational amplifier? | ![]() |
LM393 | ? | Differential comparator? | ![]() |
LM3900 | ? | Quad operational amplifier | ![]() |
LVM-2A-34 | ? | ? | ![]() |
MCM6574
MCM6674 | Motorola | Character Generator | ![]() |
PEIX | ? | ? | ![]() |
SAA5050 | Signetics | Teletext Character Generator | ![]() |
SN76477 | Texas Instruments | Sound effect generator | ![]() ![]() |
S9014 | Signetics? | NPN transistor? | ![]() |
TCA 520B | ? | Cassette interface | ![]() |
TDA 1010
TDA 1010A | ? | Audio amplifier | ![]() |
TEA 1002 | Mullard | PAL Colour Encoder & Video Summer | ![]() |
TIL220 | ? | Red LED | ![]() |
TIL222 | ? | Green LED | ![]() |
TL084 | ? | Operational amplifier | ![]() |
TMS2516 | Texas Instruments | 16,384*8-bit (2K) EEPROM | ![]() |
TMS2532 | Texas Instruments | 32,768*8-bit (4K) EEPROM | ![]() |
TMS3615 | Texas Instruments | OMTS (Octave Multiple Tone Synthesizer) | ![]() |
TMS4045
TMS4045-20 | Texas Instruments | 1024*4-bit (512-byte) SRAM
1024*4-bit (512-byte) SRAM (200 ns) | ![]() |
ULN2003 | ? | Darlington transistor array? | ![]() |
UM1233 | Astec | PAL modulator | ![]() |
UM1285-8 | Astec | NTSC VHF modulator | ![]() |
ZN425E | ? | Monolithic 8-bit D-A converter | ![]() |
* Eg. BA 127, BA 217, BA 218, BA 221, BA 222, BA 317, BA 318, BAX 13, BAY 61, 1N914, 1N4148.
** Misprint of 74LS541?
Components listed together are not necessarily interchangable drop-in equivalents (eg. speeds, power requirements, etc. may differ).
For most machines, only semiconductors are listed, not capacitors, resistors, etc. Mechanical components and connectors are not listed.
Colours used in table are:
Capacitor |
Connector/mechanical (not currently listed) |
Diode |
Resistor |
Transistor |
Basic IC |
Advanced IC |
Miscellaneous |
Programming Languages Overview
![]() | ![]() | ![]() | ![]() | ![]() | ![]() | Name | Language | Coder/porter | Year | Size | Notes |
![]() | Assembler | Assembler | Peter Marschat | 198x | 2K ($1000..$17FF) | - | |||||
![]() | 2650 Line Assembler | Assembler | ? | 19xx | 1,332 bytes ($15CC..$1AFF) | - | |||||
![]() | Assembler | Assembler | Applied Technology (David Curtis) | 197x | 2½K ($1200..$1BFF) | - | |||||
![]() | PIP Line Assembler (PIPLA) | Assembler | Signetics | 1979 | 1K ($400..$7FF) | PIPBUG 2 is $0..$3FF | |||||
![]() | Prometheus | Assembler | Signetics | 1977 | 5½K ($2200..$37FF) | - | |||||
![]() | 2650 Micro BASIC | BASIC | Alan Peek | 1978-1979 | ? | - | |||||
![]() | MicroWorld BASIC | BASIC | Applied Technology (Ian Binnie & Martin Hood) | 1979 | ? | - | |||||
![]() | TCT BASIC | BASIC | TCT Micro Design | 19xx | ? | - | |||||
![]() | BASIC | BASIC | MicroByte (Ian Binnie & Martin Hood) | 19xx | 6K | Undumped | |||||
![]() | FORTH | FORTH | MicroByte (Ian Binnie & Martin Hood) | 1982 | ~8K | Undumped | |||||
![]() | TWIN [unrelocatable] assembler | Assembler | Signetics | 1976 | ? | - | |||||
![]() | TWIN relocatable assembler | Assembler | Signetics | 1979 | ? | - | |||||
![]() | BASIC | BASIC | Signetics | 1982 | 8K | GN007 | |||||
![]() | Pascal | Pascal | Signetics | 1982 | ? | GN007 | |||||
![]() | Editor/Assembler | Assembler | Central Data? | 19xx | 5¼K ($2000..$34FF) | - | |||||
![]() | "8K" BASIC | BASIC | Central Data | 1978 | 6,271 bytes ($2781..$3FFF) | Editor is $2000..$2780 | |||||
![]() | "12K" BASIC | BASIC | Central Data | 1978 | 15,010 bytes ($2000..$5AA1) | Including editor | |||||
![]() | FORTH | FORTH | D. P. Hildyard | 1981 | ? | - | |||||
![]() | 2650 Assembler (PASS) | Assembler | ? | 19xx | ? | - | |||||
![]() | QASS | Assembler? | ? | 19xx | ? | - | |||||
![]() | FORTH | FORTH | Frank Philipse? | 19xx | ? | Converted from CD2650 to PHUNSY? | |||||
![]() | MicroWorld BASIC | BASIC | Frank Philipse | 19xx-2010 | ? | Converted from PIPBUG to PHUNSY | |||||
[Unrelocatable] Cross-Assembler | Assembler | Signetics | 197x | ? | Written in FORTRAN. Ran on PDP-11/40 (NCSS & GE Mark III timeshares). Undumped. | ||||||
Relocatable [Cross-]Assembler | Assembler | Signetics | April 1977 | ? | Written in FORTRAN. Ran on PDP-11/40 (NCSS & GE Mark III timeshares). Undumped. | ||||||
PLµS | PL/M superset | Signetics (Gary Kildall) | 1978 | ? | Cross-compiler. Written in FORTRAN. Ran on NCSS timeshare and (other) "16- and 32-bit machines". Undumped. |
Disassemblers are not listed.
MicroWorld (and later Microbee and Honeysoft) are variant names of Applied Technology.
Ian Binne & Martin Hood wrote MicroWorld BASIC for Applied Technology but would later form MicroByte.
File Formats Overview
A | u | t | o | s | e | n | s | e | Extn. | Meaning | Description | Loaded from | Run from | Efficiency | ||
![]() | ![]() | ![]() | ![]() | BIN | Binary | Headerless raw binary.
![]() ![]() ![]() ![]() | Always $0 | Always $0 | Very good | |||||||
![]() | TVC | TV (Television) Games Computer | Ami/Droid/WinElektor-only format. Represents a partial RAM image (loaded from tape). | Yes | Yes | Very good | ||||||||||
![]() | EOF | Elektor TVGC Object Format | Native on-tape file format for Elektor TVGC (and Hobby Module). Similar to AOF. | Yes | Yes | OK | ||||||||||
![]() | ![]() | ![]() | ![]() | ![]() | ![]() | 8SVX | IFF 8-bit Sampled Vox (Voice) | Entire (side of) analog (audio) tape. | Yes | Yes | Extremely poor | |||||
![]() | ![]() | ![]() | ![]() | ![]() | ![]() | AIFF | Audio Interchange File Format | Entire (side of) analog (audio) tape. | Yes | Yes | Extremely poor | |||||
![]() | ![]() | ![]() | ![]() | ![]() | ![]() | WAV | RIFF (Rip-off of IFF) Waveform | Entire (side of) analog (audio) tape. | Yes | Yes | Extremely poor | |||||
![]() | ![]() | ![]() | PAP | Papertape | Headerless raw binary. Represents an entire roll of papertape.
(Note: ![]() | No/Yes* | No/Yes* | Very good/OK* | ||||||||
![]() | ![]() | ![]() | ![]() | ![]() | ![]() | AOF | Signetics Absolute Object Format | Native on-tape (audio cassette tape and papertape) file format for SI50/PIPBUG/BINBUG/CD2650, also used on TWIN. Similar to EOF. | Yes | Yes | OK | |||||
![]() | CMD | Command | Native on-disk file format for BINBUG-based machines. | Yes | Yes | Good | ||||||||||
![]() | ![]() | RAW | Raw disk image | Entire (side of) BINBUG or CD2650 floppy disk (5¼"), raw. | n/a | n/a | Very good | |||||||||
![]() | MOD | Module | Native on-disk file format for TWIN. | Yes | Yes | Good | ||||||||||
![]() | TWIN | Test Ware Instrument disk image | Entire (side of) TWIN floppy disk (8"), with sector headers. | n/a | n/a | Good | ||||||||||
![]() | IMG | Raw disk image | Entire (side of) TWIN floppy disk (8"), raw. | n/a | n/a | Very good | ||||||||||
![]() | SMS | "ASCII-Hex SMS" | For PROM burners. Probably invented by
SMS Microcomputer Systems
.
TWIN can load/save this format, but its own built-in PROM burner does not require it (instead it just reads from a user-specified region of slave RAM). | Always $0 | Always $0 | Poor | ||||||||||
![]() | IMAG | Image | Native on-disk file format for CD2650. | Yes | Yes | Good | ||||||||||
![]() | MDCR | Mini Digital Cassette Recorder | Entire digital tape. | Yes | Yes | Good | ||||||||||
![]() | BPNF | Begin Plus Negative Finish | For PROM burners. | No | No | Very poor | ||||||||||
![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | COS | Common saved state | Ami/Droid/WinArcadia-only format. Represents a complete machine state. | Always $0 | Yes | Good |
![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | COR | Common recording | Ami/WinArcadia-only format. Represents a complete machine state and subsequent user input. | Always $0 | Yes | Good |
![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | HEX | Intel hexadecimal object format | Roughly similar to AOF, though without game start address feature. | Yes | No | OK |
![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ASM | Assembly language | 2650 CPU assembly language source code (in ASCII). | Yes | No | Poor |
![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | SYM | Symbol table | Symbol table, ie. label definitions (in ASCII). No effect on guest. | No | No | n/a |
A yellow background behind the machine glyph means autosense is supported by the emulator for that machine and file format combination. These are the recommended file formats for everyday use:
BIN for Arcadia/Interton/SI50/PHUNSY;
TVC for Elektor; and
AOF for PIPBUG/BINBUG/CD2650/Selbstbaucomputer/MIKIT.
Plus the floppy disk formats (IMG/TWIN/RAW) when using disk-based software (ie. any of the DOSes).
COS and COR files can be used for any purpose as desired; they are the most powerful and flexible of all formats.
Use of the tape formats (8SVX/AIFF/WAV/MDCR) should normally only be needed when dumping tapes.
Use of the PROM burner formats (BPNF/SMS) should never be needed unless you actually have, and want to use,
an old PROM burner that expects its data in one of these formats.
PAP papertape format can be useful for easily giving input to or saving output from the guest via a file.
There is not much necessity to use EOF format but you can do so if you want.
If it mostly equivalent to TVC except it is less efficient, has checksums, and has a file ID ($0..$F range) (and is
not supported for autosensing).
Use of the on-disk formats (CMD/MOD/IMAG) should not normally be needed; usually it is more convenient to just use
the disk (IMG/TWIN/RAW) containing the program.
Any of the file formats can be used inside a ZIP archive if desired.
Note that AOF/ASM/BIN/HEX/SYM/etc. files can be force-loaded/saved to/from practically any guest using the debugger
(even where blank in the table above).
"Loaded from" of "yes" means the file format contains start and end addresses for where it should be loaded.
"Run from" of "yes" means the file format can contain a game start address for where it should begin execution from.
Efficiency is in terms of storage space, as a means of storing games for emulator users. In case your host machine is down to its last terabyte ;-) .
*: The 1st value is inherent. The 2nd value assumes an AOF is stored on it.
Signetics AOF (Absolute Object Format)
Each block is as follows:
Offset(s) | Description |
0 | colon (:) ($3A) |
1..2 | load address (big-endian) |
3 | block length:
0 = last block 1..255 = 2..256 bytes (respectively) |
4 | checksum for header bytes 0..3 |
5..n-1 | data (ASCII-encoded hex, each character representing 1 nybble) |
n | checksum for data |
Files are normally terminated by a zero-length block. The load address of
this block is used as the start address of the game.
Checksums start as $00. For each emitted byte, the following algorithm is
applied:
SUMC ^= data;
SUMC <<= 1;
Eg. the following program:
$1600: C0 C0 C0 C0
would be encoded as follows:
3A 16 00 03 15 (1st block header)
C0 C0 C0 C0 88 (1st block data)
3A 00 00 00 A3 (2nd block header)
For the 1st header:
SUMC = 0; // SUMC is %00000000 [$00];
SUMC ^= $3A; // SUMC is %00111010 [$3A];
SUMC <<= 1; // SUMC is %01110100 [$74];
SUMC ^= $16; // SUMC is %01100010 [$62];
SUMC <<= 1; // SUMC is %11000100 [$C4];
SUMC ^= $00; // SUMC is %11000100 [$C4];
SUMC <<= 1; // SUMC is %10001001 [$89];
SUMC ^= $03; // SUMC is %10001010 [$8A];
SUMC <<= 1; // SUMC is %00010101 [$15];
For the 1st data:
SUMC = 0; // SUMC is %00000000 [$00];
SUMC ^= $C0; // SUMC is %11000000 [$C0];
SUMC <<= 1; // SUMC is %10000001 [$81];
SUMC ^= $C0; // SUMC is %01000001 [$41];
SUMC <<= 1; // SUMC is %10000010 [$82];
SUMC ^= $C0; // SUMC is %01000010 [$42];
SUMC <<= 1; // SUMC is %10000100 [$84];
SUMC ^= $C0; // SUMC is %01000100 [$44];
SUMC <<= 1; // SUMC is %10001000 [$88];
For the 2nd header:
SUMC = 0; // SUMC is %00000000 [$00];
SUMC ^= $3A; // SUMC is %00111010 [$3A];
SUMC <<= 1; // SUMC is %01110100 [$74];
SUMC ^= $00; // SUMC is %01110100 [$74];
SUMC <<= 1; // SUMC is %11101000 [$E8];
SUMC ^= $00; // SUMC is %11101000 [$E8];
SUMC <<= 1; // SUMC is %11010001 [$D1];
SUMC ^= $00; // SUMC is %11010001 [$D1];
SUMC <<= 1; // SUMC is %10100011 [$A3];