Dominant Amber - A 1KB Atari 2600 game

Identify the dominant color in random arrangements as quickly as possible

Similar projects worth following
A 1KB game for the Atari 2600. Run on a real Atari 2600 with a flash cart (search Harmony cartridge) or on your computer with the Stella emulator.

Dominant Amber is a a mini game for the Atari 2600 console. Race against the clock to quickly identify the 'dominant' color for a high score.


The posted ROM image, Dominant_Amber.bin, is 2KB in size. The first 1KB is filled with 0xFF and is not accessed by the program in any way. The second 1KB is the game code, of which all 1024 bytes are utilized. It is padded to 2KB because some emulators and flash cartridges for the Atari 2600 do not support ROM images smaller than 2KB.

The Atari 2600 has no internal ROM or code of any kind, so the 1KB on the cartridge is the sole program.

See the project logs for details about the byte saving techniques used.


Code is formatted to assemble with the multi platform DASM.

Command line:

dasm Dominant_Amber.asm -f3 -v5 -oDominant_Amber.bin


6502 Assembly source for Dominant Amber. Assembles with DASM 6502 cross-assembler. Requires vcs.h for hardware defines.

asm - 13.24 kB - 01/04/2017 at 01:57



ROM image for use with emulators and flash cartridges

macbinary - 2.00 kB - 01/03/2017 at 02:26


  • 1 × Atari 2600 with programable cartridge, or Atari 2600 Emulator to run the ROM image

  • Some Byte-saving tricks

    Rick Skrbina01/04/2017 at 03:29 0 comments

    The most enjoyable part of coding for the Atari 2600 is getting it to do what you wanted with the very limited resources available. Released in 1977, it is one of the earliest microprocessor based game consoles. The console features 128 bytes of RAM, 2x 8 bit I/O ports (usually used for input), and a very limited graphics chip that must be updated every scan line 'on the fly' as the screen is drawn in real time.

    When trying to cram your program into a limited ROM, you will find that there are always bytes to be saved if you look hard enough. Here are some of the tricks I used to cram Dominant Amber into 1024 Bytes.

    BIT opcode to skip an instruction

    An old trick with the 6502 is that the BIT (absolute) instruction can be used to skip the next instruction, eliminating a branch. This is a savings of a byte each time it is used, since branch instructions take 2 bytes.

    The BIT (absolute) instruction is 3 bytes. It's function is to load D7 and D6 of the byte at the address specified into two of the CPU's flags. It does not corrupt any registers other than the status register, so using it as a pseudo branch instruction has no ill effect. Here is an example in the code:

    	lda ScreenSaverPosition
    	cmp #65
    	beq DontIncScreenSaverPosition
    	inc ScreenSaverPosition
    	.byte $2C                          ;opcode for BIT instruction
                                               ;used to skip dec instruction
                                               ;dec .. used as absolute address
                                               ;for BIT 
    	dec ScreenSaverOffset

    Branch instead of Jump

    Another useful trick is to branch instead of jump when possible. Jump instructions take 3 bytes and branches are only 2. So when possible, you should always use a branch. The catch is that the 6502 does not have a 'branch always', and branches can only go to +/- 128 bytes from the instruction itself. When you have a situation where you don't need to jump far, and you know for sure what the status register will contain, use the appropriate branch.

    Reuse your data tables when possible

    An example of data reuse in Dominant Amber is the frequency/volume envelop data for the sounds.

    'Correct' sound envelop table = 'Incorrect' sound frequency table

    'Correct' sound frequency table = 'Incorrect sound envelop table

    This was enough along with a different distortion setting on the TIA to make a positive and negative sounding effect using the same data. The savings here was 24 bytes.

    It is also common to reuse graphics data that repeats. For example the 0, 8, 9, and 6 characters share byte patterns, so these characters share bytes with each other.

    BRK instead of JSR

    The BRK instruction pushes the processor status to the stack and effectively jumps to a subroutine pointed to by the break vector. The advantage of using BRK to call a subroutine is that it only costs 1 byte, as opposed to the 3 bytes that a standard JSR takes. These 2 byte savings add up if a subroutine is called many times.

    Use illegal opcodes

    The 6502 has 8 bit instructions, but not all possible 255 of them are defined and explained in the datasheet. Over the years, hackers have documented what the other instructions missing from the documentation do. Of course it is normally bad practice to use such an instruction, but for the Atari 2600, there are some useful ones that work on all the official hardware out there. For example, I use a couple different forms of LAX, or Load Accumulator and X to save some space when I need the same value in two registers. Normally this would require an LDA and TAX, or LDX and TXA, so just using LAX eliminates a byte for the transfer.

    Add more than you want..

    There was a couple places in the code that sometimes a value would be added, and some times subtracted from a variable. I found that I could avoid a branch instruction if I added the value I wanted + the value that would be subtracted in the other case, and ran both cases. For example:

    	adc #14	 ;save branch instruction by +14 -7 for +7
    	sbc #7

    Branching to RandomAdd7 will result in adding 7 to the accumulator when the block of code is executed...

    Read more »

  • Source code released

    Rick Skrbina01/04/2017 at 02:13 0 comments

    Source code has been added to the page. This game was written in 6502 assembly language, and is formatted to assemble with DASM.

  • ROM now available

    Rick Skrbina01/03/2017 at 02:32 0 comments

    The ROM image is now included on this page. Note that ROM is padded to 2K in order to retain compatibility with most Atari 2600 emulators. The game code is in the second 1K of the binary. There is no BIOS or internal ROM in the Atari 2600, only the ROM on the cartridges.

    Source code and documentation to follow

View all 3 project logs

Enjoy this project?



Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates