Programming the 2600 (with some 7800 info)

From: Michael Current (aa700@cleveland.Freenet.Edu)
Date: 12/08/92-11:03:17 AM Z

From: aa700@cleveland.Freenet.Edu (Michael Current)
Subject: Programming the 2600 (with some 7800 info)
Date: Tue Dec  8 11:03:17 1992

Specifications for the Atari 2600/7800
                2600                            7800
CPU:            6507                            6502C (custom, NOT 65C02)
RAM:            128 Bytes, in VLSI              4K, high speed
ROM:            6K max                          52K max
Cpu Clock:      1.19 MHz                        1.79 MHz
Graphics Clock: 3.58 MHz                        7.16 MHz
Slot Config:    Rom access only                 Most CPU lines + video/audio
CPU Avail:      less than 50%                   over 90%
1. ROM specs are based on a non-bank select scheme.
2. Graphics Clock is the master clock used to drive the video chips.
Programming the 2600 in a nutshell.
        The Atari 2600 consists of 3 important ICs: the CPU (6507),
the Television Interface Adapter (TIA or Stella), and the RIOT (6532).
The 7800 has a CPU (6502C or Sally) instead of the 6507 and a GCC1702 
(Maria) chip in addition to the Stella chip.
The CPU:
        The 6507 CPU is a 6502 with 2 important exceptions: it only has
external address lines for 8K of memory and there are NO interrupt lines
connected.  This is not as limiting as it seems if you examine some of
the games for the machine.
The Stella chip:
        This chip makes all the video displays and sounds for the 2600 VCS.
It also has 6 registers which are used as A/D converters and for the trigger
buttons on the joysticks.  The chip also controls the RDY line of the CPU
to initiate horizontal syncronization control.  The chip is NOT a DMA chip.
The CPU must write each line of data into the chip registers AS it draws
the screen.  This accounts for the low CPU availability. The Chip is addresed
through 44 write only registers, and 13 read only registers mapped to
the low end of page 0.  For those familiar with the Atari 800, this chip
is about 1/2 of a TIA/Pokey in all respects.  But, there is no ANTIC chip to
drive it; the CPU must do all the work that the ANTIC does in the 800.
        This chip reads all the console switches (excluding power), the
joysticks, and other controllers.  It also contains the only RAM in the
system and a general purpose timer.  The RAM is mapped to the high end of both 
page 0 and page 1.  This means that it acts as both page 0 fast access memory
and the 6502 stack.  The timer and I/O ports are mapped to Page 2 and 3.
        In order to produce a video display, a program must do the following:
1. Start the vertical blanking interval
2. Start the vertical sync interval immediately
        there is time for about 80 instructions after this
3. End vertical sync
        the game computations must be done now as there won't be time later
4. End vertical blanking
5. Set up each line of the video display as it is drawn
        there is time for about 6 instructions to the video chip before
        the current line starts being displayed.  Atari recommends changing
        the display every other line to gain processing time.
6. Loop back to step 1
The Cartridge:
        A standard cartridge contains the equivalent of a 2716 or 2732/2532
with one notable exception: the chip select line is active high, not low.
The high order address line of the 6507 (A12) is used as the chip enable.
There was at least one company that used EPROMs with a 74LS04 inverter to
compensate for this.
The Pinouts:
Note:   numbers indicate left to right numbering
        Top Row                 Bottom Row
Slot    2716    CPU             2716    CPU
1       13      D3              1       A7
2       14      D4              2       A6
3       15      D5              3       A5
4       16      D6              4       A4
5       17      D7              5       A3
6       *       A12             6       A2
7       19      A10             7       A1
8       NC      A11             8       A0
9       22      A9              9       D0
10      23      A8              10      D1
11      24      +5V             11      D2
12      12      Shield Ground   NC      Ground
    * to inverter and back to 18 for chip select
Major differences between 2600 and 7800 mode:
        2600 mode is default in the 7800.  If it finds 128 bytes at the high
end of memory to match its encryption scheme, it will enable 7800 mode. There 
is a small ROM inside the unit which displays the Atari pattern on screen as
it does this.
        The 7800 mode is DMA driven, so the processor is free most of the time
to do other things, as the graphics chip runs 4 times faster than the CPU.
        The 7800 cartridge slot includes 8 more lines: A13, A14, A15, R/W,
phase 2 clock, audio, video, and HALT (unique to Atari 6502).
        The 2600 video has foreground/background, 2 player/missles, and one
ball. The 7800 can display as many objects as the DMA can read in one line.
        The sound is exactly the same as it still uses the Stella chip
 (except Ballblazer which has its own sound chip in the cartridge).

--- graphics.txt ---
Wsync   Wait for sync
This address halts microprocessor by clearing RDY latch to zero.  RDY is
set true again by the leading edge of horizontal blank.
        Data bits not used.
Rsync   Reset Sync
This address resets the horizontal sync counter to define the begining of
horizontal blank time, and is used in chip testing.
        Data bits not used.
This address controls vertical sync time by writing D1 into the Vsync latch.
        D1 -    1: start vertical sync
                0: stop vertical sync
This address controls vertical blank and the latches and dumping transistors
on the input ports by writing into bits D7,D6, and D1 of the Vblank register.
        D1 -    1: start vertical blank
                0: stop vertical blank
        D6 -    1: enable I4 and I5 latches
                0: disable latches - also resets latches to logic true
        D7 -    1: Dump I0,I1,I2,I3 ports to ground
                0: Remove dump path to ground
Pf0, Pf1, Pf2
These addresses are used to write into the playfield registers.
                        horizontal scan line map
                      (160 clocks, each bit =4 clocks)
                                                                Ctrlpf bit 0
bits            4-7     7-0     0-7  |  4-7     7-0     0-7
register        Pf0     Pf1     Pf2     Pf0     Pf1     Pf2     0
bits            4-7     7-0     0-7  |  7-0     0-7     7-4
register        Pf0     Pf1     Pf2     Pf2     Pf1     Pf0     1
This address is used to write into the playfield control register.
if bit is 1 then:
        D0 -    (REF)   reflect playfield, see above
        D1 -    (SCORE) left half of playfield gets color of player 0
                        right half gets color of player 1
        D2 -    (PFP)   playfield gets priority over players so they move
                        behind playfield
        D5,D4 - Ball Size       if 00,  1 clock wide
                                if 01,  2 clocks wide
                                if 10,  4 clocks wide
                                if 11,  8 clocks wide
Nusiz0, Nusiz1
These addresses control the number and size of players and missles.
        D5,D4 -         Missle Size     see Ball Size above
        D2,D1,D0 -      Player number/size
                        if 000,         X               one copy
                        if 001,         X X             two copies, close
                        if 010,         X   X           two copies, medium
                        if 011,         X X X           three copies, close
                        if 100,         X       X       Two copies, far
                        if 101,         XX              one copy, double width
                        if 110,         X   X   X       3 copies, medium
                        if 111,         XXXX            one copy, quad width
Resp0, Resp1, Resm0, Resm1, Resbl
These addresses are used to reset players, missles and the ball.  The object
will begin its serial graphics at that time of a horizontal line at which the
reset address occurs.
        Data bits not used.
Resmp0, Resmp1
These addresses are used to reset the horizontal location of a missle to
the center of its corresponding player.  As long as this control bit is
true (1), the misslw will remain locked to the center of its player and the mis
sle graphics will be disabled.  When a zero is written into this location,
the missle is enabled, and can be moved independently from the player.
        D1 -    0: allow missle to move
                1: lock missle to player
This address causes the horizontal motion register values to be acted upon
during the horizontal blank time in which it occurs.  It must occur at the
beginning of horizontal blanking in order to allow time for generation of
extra clock pulses into the horizontal position counters.  If motion is
desired, this command must immediately follow a Wsync command in the program.
        Data bits not used.
This address clears all horizontal motion registers to zero (no motion).
        Data bits not used.
Hmp0, Hmp1, Hmm0, Hmm1, Hmbl
These addresses write data (horizontal motion values) into the horizontal
motion registers.  These registers cause horizontal motion only when commanded
to do so by the horizontal movement command Hmove.  The motion values use the
upper 4 bits of the byte. They are signed numbers with a +7 to -8 range. The
positive numbers indicate left movement, the negative indicate right.
Warning: These registers should not be modified during the 24 computer cycles
following an Hmove command.  Unpredictable motion values may result.
Enam0, Enam1, Enabl
These addresses write into the single bit missle or ball graphics registers.
        D1 -    0: disables object
                1: enables object
Grp0, Grp1
These addresses write data into the player graphics registers
                        horizontal scan line map
                          (each bit =1 clock)
bits 7-0        if Refp0 (Refp1) is 0
bits 0-7        if Refp0 (Refp1) is 1 (reflected)
Refp0, Refp1
These addresses write data into the the single bit player reflect registers.
see above.
        D3 -    0: normal
                1: reflected
Vdelp0, Vdelp1, Vdelbl
These addresses write data into the single bit vertical delay registers, to
delay players or the ball by one vertical line.
        D0 -    0: no delay
                1: delayed
This address clears all collision latches to zero (no collision)
        Data bits not used.
Colupb, Colup1, Colupf, Colubk
These addresses write data into the player, playfield, and background
color-luminance registers.
        D3, D2, D1 -    Luminance values 000 is dark, 111 is bright.
        D7,D6,D5,D4 -   Colors  0000    Grey
                                0001    Gold
                                0010    Orange
                                0011    Red orange
                                0100    Pink
                                0101    Purple
                                0110    Blue purple
                                0111    Blue
                                1000    Blue
                                1001    Light blue
                                1010    Turquoise
                                1011    Green blue
                                1100    Green
                                1101    Yellow green
                                1110    Orange green
                                1111    Light orange
Audf0, Audf1
These addresses write data into the audio frequency divider registers.
        D4,D3,D2,D1,D0 -        00000   30KHz divided by 1
                                00001   "              " 2
                                11111   "              " 32
Audc0, Audc1
These addresses write data into the audio control registers which control
the noise content and additional division of the audio output.
                bits            value           noise type      division
        D3, D2, D1, D0 -        0000                            set to 1
                                0001            4 bit poly
                                0010                /15 into 4 bit poly
                                0011                5 bit poly into 4 bit poly
                                0100                            divide by 2
                                0101                            divide by 2
                                0110                            divide by 31
                                0111                5 bit poly into /2
                                1000            9 bit poly
                                1001            5 bit poly
                                1010                            divide by 31
                                1011                set last 4 bits to 1
                                1100                            divide by 6
                                1101                            divide by 6
                                1110                            divide by 93
                                1111                5 bit poly divided by 6
Audv0, Audv1
These addresses write data into the audio volume registers which set the pull
down impedance driving the audio output pads.
        D3, D2, D1, D0 -        0000    no output
                                1111    loudest output

--- stella.txt ---
Atari 2600      Stella Memory Map
Write Address Registers
Addr    Assy Name       Bits Used       Function
00      Vsync           0000 00x0       Vertical Sync Set-Clear
01      Vblank          xx00 00x0       Vertical Blank Set-Clear
02      Wsync           ---- ----       Wait for Horizontal Blank
03      Rsync           ---- ----       Reset Horizontal Sync Counter
04      Nusiz0          00xx 0xxx       Number-Size player/missle 0
05      Nusiz1          00xx 0xxx       Number-Size player/missle 1
06      Colup0          xxxx xxx0       Color-Luminance Player 0
07      Colup1          xxxx xxx0       Color-Luminance Player 1
08      Colupf          xxxx xxx0       Color-Luminance Playfield
09      Colubk          xxxx xxx0       Color-Luminance Background
0A      Ctrlpf          00xx 0xxx       Control Playfield, Ball, Collisions
0B      Refp0           0000 x000       Reflection Player 0
0C      Refp1           0000 x000       Reflection Player 1
0D      Pf0             xxxx 0000       Playfield Register Byte 0
0E      Pf1             xxxx xxxx       Playfield Register Byte 1
0F      Pf2             xxxx xxxx       Playfield Register Byte 2
10      Resp0           ---- ----       Reset Player 0
11      Resp1           ---- ----       Reset Player 1
12      Resm0           ---- ----       Reset Missle 0
13      Resm1           ---- ----       Reset Missle 1
14      Resbl           ---- ----       Reset Ball
15      Audc0           0000 xxxx       Audio Control 0
16      Audc1           0000 xxxx       Audio Control 1
17      Audf0           000x xxxx       Audio Frequency 0
18      Audf1           000x xxxx       Audio Frequency 1
19      Audv0           0000 xxxx       Audio Volume 0
1A      Audv1           0000 xxxx       Audio Volume 1
1B      Grp0            xxxx xxxx       Graphics Register Player 0
1C      Grp1            xxxx xxxx       Graphics Register Player 1
1D      Enam0           0000 00x0       Graphics Enable Missle 0
1E      Enam1           0000 00x0       Graphics Enable Missle 1
1F      Enabl           0000 00x0       Graphics Enable Ball
20      Hmp0            xxxx 0000       Horizontal Motion Player 0
21      Hmp1            xxxx 0000       Horizontal Motion Player 1
22      Hmm0            xxxx 0000       Horizontal Motion Missle 0
23      Hmm1            xxxx 0000       Horizontal Motion Missle 1
24      Hmbl            xxxx 0000       Horizontal Motion Ball
25      Vdelp0          0000 000x       Vertical Delay Player 0
26      Vdelp1          0000 000x       Vertical Delay Player 1
27      Vdelbl          0000 000x       Vertical Delay Ball
28      Resmp0          0000 00x0       Reset Missle 0 to Player 0
29      Resmp1          0000 00x0       Reset Missle 1 to Player 1
2A      Hmove           ---- ----       Apply Horizontal Motion
2B      Hmclr           ---- ----       Clear Horizontal Move Registers
2C      Cxclr           ---- ----       Clear Collision Latches
Read Address Registers
                                                        bit 6   bit 7
0       Cxm0p           xx00 0000       Read Collision  M0-P1   M0-P0
1       Cxm1p           xx00 0000                       M1-P0   M1-P1
2       Cxp0fb          xx00 0000                       P0-PF   P0-BL
3       Cxp1fb          xx00 0000                       P1-PF   P1-BL
4       Cxm0fb          xx00 0000                       M0-PF   M0-BL
5       Cxm1fb          xx00 0000                       M1-PF   M1-BL
6       Cxblpf          x000 0000                       BL-PF   -----
7       Cxppmm          xx00 0000                       P0-P1   M0-M1
8       Inpt0           x000 0000       Read Pot Port 0
9       Inpt1           x000 0000       Read Pot Port 1
A       Inpt2           x000 0000       Read Pot Port 2
B       Inpt3           x000 0000       Read Pot Port 3
C       Inpt4           x000 0000       Read Input (Trigger) 0
D       Inpt5           x000 0000       Read Input (Trigger) 1
Atari 2600      RIOT Memory Map
80-FF                                   Ram     also at 180-1FF
280     Swcha                           Port A data register (joysticks...)
281     Swacnt                          Port A data direction register (DDR)
282     Swchb                           Port B data (console switches)
283     Swbcnt                          Port B DDR
284     Intim                           Timer output
294     Tim1t                           set 1 clock interval
295     Tim8t                           set 8 clock interval
296     Tim64t                          set 64 clock interval
297     T1024t                          set 1024 clock interval
                                                these are also at 380-397
Atari 2600      ROM Memory Map
E000-FFFF                               Rom     also 1000-1FFF
                                                     3000-3FFF ....
--- colrdemo.asm ---
;       Color Demo
;       Taken from the Magicard Manual
;       shows almost all the colors on the left side
;       of the screen and cycles slowly on the right
Start   LDA     $81 ;   get contents of memory
        STA     $0F ;   save into a pattern control register
        LDA     #$03
        STA     $0A ;   set background control register
        LDA     #$55
        STA     $07 ;   set right side color
        LDY     #$00
        STA     $02 ;   wait for horizontal sync
        STA     $01 ;   start vertical blanking
        STA     $00 ;   start vertical retrace
        LDA     #$2A
        STA     $0295 ; set timer for appropriate length
Loop1   LDY     $0284
        BNE     Loop1 ; waste time
        STY     $02 ;   wait for horizontal sync
        STY     $00 ;   end vertical retrace period
        LDA     #$24
        STA     $0296 ; set timer for next wait
        LDA     $0282
        AND     #$01 ;  check for reset switch
        BNE     NReset
        BRK ;           only interrupt available - must have vector set
NReset  INC     $80 ;   increment right side color cycle counter
        BNE     Loop2
        LDA     #$E0
        STA     $80 ;   reset counter
        INC     $81
        LDA     $81 ;   increment right side color
        STA     $06 ;   store it in color register
Loop2   LDY     $0284
        BNE     Loop2 ; waste time
        STY     $02 ;   wait for horizontal sync
        STY     $01 ;   end vertical blanking
        LDX     #$E4 ;  number of line to draw on screen
Loop3   STY     $02 ;   wait for horizontal sync
        STX     $0E ;   change a background pattern with each line
        STX     $07 ;   change right side color with each line
        BNE     loop3
        JMP     Start ; do next screen (every 1/60th second)

--- bilboard.asm ---
;       Billboard Demo
;       displays sonething close to, but not quite like
;       the colored billboard used in "Close Encounters..."
;       just a small demo to see what could be done
Start   LDX     #$FF
        JSR     Sub0
        LDA     #$06
        STA     $09
        LDA     #$02
        STA     $0A
        LDA     #$35
        STA     $B1
        STA     $B4
        LDA     $1B
        STA     $B2
        STA     $B3
        LDA     #$00
        STA     $B6
        LDA     #$AA
        STA     $B5
Main    JSR     Sub1
        LDA     #$50
        STA     $06
        LDA     #$80
        STA     $07
        LDA     #$08
        STA     $19
        JSR     Sub2
        LDA     $0282
        AND     #$02
        BEQ     Start
        JSR     Sub3
        LDX     #$10
Loop1   NOP
        STY     $02
        BNE     Loop1
        LDY     #$06
        LDX     #$04
Loop2   STY     #$02
        LDA     $B1
        STA     $0D
        LDA     $B2
        STA     $0E
        LDA     $B3
        STA     $0F
        LDA     $B4
        STA     $0D
        LDA     $B5
        STA     $0E
        LDA     $B6
        STA     $0F
        BNE     Loop2
        LDA     #$06
        STA     $06
        STA     $07
        LDX     #$A6
Loop3   NOP
        STY     $02
        BNE     Loop3
        JMP     Main
Sub0    CLD
        LDX     #$00
        STX     $0281
        STX     $0283
        LDY     #$04
Loc0    STX     $00,Y
        CPY     #$20
        BNE     Loc0
        STX     $2B
Sub1    LDY     #$FF
        STY     $02
        STY     $01
        STY     $00
        LDA     #$2A
        STA     $0295
        LDA     $0282
        AND     #$01
        BNE     Loc1
Loc1    RTS
Sub2    LDY     $0284
        BNE     Sub2
        STY     $02
        STY     $00
        LDA     #$19
        STA     $0296
Sub3    LDY     $0284
        BNE     Sub3
        STY     $02
        STY     $01
        STY     $2A
         Michael Current, Cleveland Free-Net 8-bit Atari SIGOp
Carleton College, Northfield, MN, USA / UUCP: ...!umn-cs!ccnfld!currentm
      Internet: / Cleveland Free-Net: aa700

Return to message index