Atari 2600 VCS Programming

Carlos Duarte do Nascimento
Carlos Duarte do NascimentoSoftware Developer at GitHub
game program™
ATARI 2600
PROGRAMMING
Use with Keyboard Controllers
PROGRAM CONTENTS 2011-2013 CHESTER, INC.
©
What
An overview of the Atari 2600
architecture, covering everything
needed to create a “Hello,World!”
program that can run on emulators
or even on a real Atari
http://slideshare.net/chesterbr
Why
● Pure nostalgia
● Homebrew games
● Demoscene
● Appreciate masterworks such as
Enduro, Pitfall! or River Raid
● Feel better about today's tools
and hardware limitations :-)
http://slideshare.net/chesterbr
@chesterbr
http://chester.me
Who
Atari 2600
(Video Computer System)
Over 600 titles...imagem: mitchelaneous.com
but why were they so...“Atari-ish”?
Let's look inside and find out!
(Atari 2600 Jr. printed circuit board)
CPU: 6507
CPU: 65076502
Video:TIA
Everything else: RIOT (6532)
Look ma, no O.S.!
Atari programs talk directly to the
hardware – there is no middle man!
Its 6502 CPU only “understands”
memory reads and writes, so all the
other chips are hard-wired to act as
memory (even those who aren't)
Memory Map
(very, very, very simplified*)
0000-002C – TIA (write)
0030-003D – TIA (read)
0080-00FF – RIOT (RAM)
0280-0297 – RIOT (I/O,Timer)
F000-FFFF – Cartridge (ROM)
*http://nocash.emubase.de/2k6specs.htm
Memory Map
F000-FFFF – Cartridge (ROM)
(this is not your biggest problem...)
4 KBytes!
Memory Map
0080-00FF – RIOT (RAM)
(and still not your biggest problem)
128 BYTES!!!!!
(1/8 of a KB)
VRAM
(frame buffer)
Typical video chips translate
bit patterns stored onVideo RAM
(VRAM) into pixels and colors
VRAMVRAM
VRAM
38
44
44
7C
44
44
EE
00
VRAM
Screen resolution and color depth
are subject toVRAM size limits
Memory was expensive on the
70s/80s, leading to trade-offs
How muchVRAM does an Atari have?
Memory Map
0000-002C – TIA (write)
0030-003D – TIA (read)
0080-00FF – RIOT (RAM)
0280-0297 – RIOT (I/O,Timer)
F000-FFFF – Cartridge (ROM)
Memory Map
????-???? – VRAM
Memory Map
0 bytes !!!!
????-???? – VRAM
right, now you
got a problem...
Racing the Beam
Since we can't just write pixels to
someVRAM frame buffer, our code
will need to work a bit closer to
the TV hardware, with a little help
from a very unique chip...
TIA
(Television Interface Adaptor)
How a TV set works
Image: cc-by wikipedia user Grm_wnr
Scanlines
public domain illustration by Ian Harvey
60 frames
per second
(NTSC
standard)
TIA is scanline-oriented
As the beam draws each scanline, the
game program must set TIA registers
to configure the objects drawn on it
Most of this objects have only one
color, making multiple colors on the
same scanline theoretically impossible...
...which explains:
vs.
constraints ⇒ creativity
vs.
Screen Objects
● Playfield (PF)
● Players (P0, P1)
● Missiles/Ball (M0, M1, BL)
Scanlines will be rendered based on
how we configure TIA's screen objects:
Playfield (PF)
20-bit pattern with a foreground and
a background color, rendered
over the left side of the scanline
The right side will either repeat or
refect the same pattern (the later
generating a symmetrical image)
PLAYFIELD
PLAYFIELD
PLAYFIELD
PLAYFIELD
Playfield configuration
PF0 = 0000 ←← order
PF1 = 00000000 order →→
PF2 = 00000000 ←← order
REFLECT = 0
resulting scanline
Playfield configuration
PF0 = 0001 ←← order
PF1 = 00000000 order →→
PF2 = 00000000 ←← order
REFLECT = 0
resulting scanline
_ _
Playfield configuration
PF0 = 0011 ←← order
PF1 = 00000000 order →→
PF2 = 00000000 ←← order
REFLECT = 0
resulting scanline
__ __
Playfield configuration
PF0 = 0111 ←← order
PF1 = 00000000 order →→
PF2 = 00000000 ←← order
REFLECT = 0
resulting scanline
___ ___
Playfield configuration
PF0 = 1111 ←← order
PF1 = 11110000 order →→
PF2 = 00000000 ←← order
REFLECT = 0
resulting scanline
________ _______
Playfield configuration
PF0 = 1111 ←← order
PF1 = 11111110 order →→
PF2 = 00010101 ←← order
REFLECT = 0
resulting scanline
___________ _ _ _ ___________ _ _ _
Playfield configuration
PF0 = 1111 ←← order
PF1 = 11111110 order →→
PF2 = 00010101 ←← order
REFLECT = 1
resulting scanline
___________ _ _ _ _ _ _ ___________
___________ _ _ _ _ _ _ ___________
Players (P0, P1)
Each one is an independent 8 bit pattern
(GRP0/GRP1) with a foreground color
(COLUP0 / COLUP1) that can be
positioned at any column of the scanline
e.g.: 10100001 → ████████
PLAYERS
PLAYERS
Players
Each player can be horizontally
stretched, multiplied or inverted by
setting NUSIZn / REFPn (n=0/1)
(number/size and reflect player)
NUSIZ0 (or NUSIZ1)
000
001
010
011
100
101
110
111
NUSIZn
With REFP0 (or REFP1) on
000
001
010
011
100
101
110
111
NUSIZn
NUSIZn
Atari 2600 VCS Programming
NUSIZn
NUSIZn
NUSIZn
NUSIZn
Missiles/Ball (M0/M1/BL)
Can be positioned just like players, but
no bit pattern, just a pixel (although it
can be horizontally stretched 2/4/8x)
M0/M1 use P0/P1colors, while
BL uses the PF foreground color
MISSILES
BALL
BALL
BALL
MISSILE
BALL
MISSILE
Master Plan
For each scanline, configure the
options for each object before the
beam reaches its intended position
The time slot is very short, forcing
programmers to pick and choose what
to change, reusing as much as they can
How short?
6502 ≈ 1,19Mhz (1.194.720 cycles/sec)
NTSC: 60 frames per second
1.194.720/60 ≅ 19.912 cycles per frame
How short?
CPU: 19.912 cyles per frame
NTSC: 262 scanlines per frame
19.912 / 262 = 76 cycles per scanline
How short?
CPU: 19.912 cyles per frame
NTSC: 262 scanlines per frame
19.912 / 262 = 76 cycles per scanline
and what can we do with 76 cycles?
(by the way:WTF is a “cycle”?)
Assembly 6502
Atari 2600 VCS Programming
6502
6502 (Atari-wise)
Reads a program from the cartridge
(ROM) composed of operations that
manipulate and transfer bytes between
cartridge, RIOT (RAM, I/O, timers) and
TIA, keeping state on internal registers
Operations
Each operation that composes a 6502
program in memory is identified by a
1-byte opcode and can be followed
by up to 2 bytes of parameters
An instruction can take up to 6
cycles to be executed
Registers
A = Accumulator (8 bits)
X,Y= Indexes (8 bits)
S = Stack Pointer (8 bits)
P = Status (fags, 8 bits)
PC = Program Counter (16 bits)
Example program
“add 2 to a value stored at a
memory position; store the result
into another memory position”
Implementation
● Read the byte stored on memory
position 0200 into register A
● Add 2 to register A's value
● Write register A's value into
memory position 0201
6502 Machine Code
AD Opcode (Memory → A)
00 Last part of “0200”
02 First part of “0200”
69 Opcode (value + A → A)
02 Value to add
8D Opcode (A → Memory)
01 Last part of “0201”
02 First part of “0201”
Atari 2600 VCS Programming
6502 Assembly Language
Associates the 151 opcodes
with 56 mnnemonic instructions
and a notation for their
parameters (access mode)
6502 Machine Code
AD Opcode (Memory → A)
00 Last part of “0200”
02 First part of “0200”
69 Opcode (value + A → A)
02 Value to add
8D Opcode (A → Memory)
01 Last part of “0201”
02 First part of “0201”
Assembly 6502
AD LDA $0200
00
02
69 ADC #02
02
8D STA $0201
01
02
Assembler
Program that reads a text file
written in Assembly language and
assembles a binary file with the
corresponding machine code
foo.asm
LDA $0200
ADC #02
STA $0201
...
foo.bin
AD000269
028D0102
...
ASSEMBLER
Macro Assembler
ORG $0100 ; Start @ memory 0100
...
SomeLabel:
LDX #$10 ; No idea where this
DEX ; will be in memory,
BNE SomeLabel ; and don't need to!
...
DASM
● 6502 Macro Assembler
● Includes Atari headers
● Multiplataform
● Free and open-source (GPLv2)
http://dasm-dillon.sourceforge.net/
Notation (for today)
#... = decimal value
#$... = hex value
$... = hex address
$... , X = hex address + X
http://www.obelisk.demon.co.uk/6502/addressing.html
6502 Instruction Set
= most relevant for Atari 2600 programming
Data Transfer
LDA, LDX, LDY = Load
STA, STX, STY = Store
TAX,TAY,TXA,
TYA,TSX,TXS = Transfer
LDA #$10 0x10→A
STY $0200 Y→m(0x0200)
TXA X→A
Arithmetic
ADC, SBC = +,- (w/ carry)
INC, INX, INY = ++
DEC, DEX, DEY = --
ADC $0100 m(0x100)+A→A
INC $0200 m(0x200)+1→
m(0x200)
DEX X-1→X
Bit Operations
AND, ORA, EOR = &, |, ^ (A)
ASL, LSR = Arithmetic shift
ROL, ROR = “Rotating” shift
AND #$11 A&0x11→A
LSR A>>1→A (A/2→A)
ROR A>>1 (bit 7=carry)
Comparing / Branching
CMP, CPX, CPY = compare A/X/Y (-)
BCS, BCC = ⇗ if carry set / clear
BEQ, BNE = ⇗ if equal / not equal
BVS, BVC = ⇗ if overfow set / clear
BMI, BPL = ⇗ if minus / plus
CPY $1234 if y=m(0x1234),
BEQ $0200 0x0200→PC
Stack and Subroutines
JSR, RTS = call/return subroutine
PHA, PLA = push / pull A
PHP, PLP = push / pull status (P)
JSR $1234 PC(+3)→stack,
0x1234→PC
RTS stack→PC
Everything else...
NOP = No Operation
JMP = Direct Jump (GOTO)
SEC, CLC = Set/Clear Carry
SEV, CLV = Set/Clear oVerfow
SEI, CLI = Set/Clear Interrupt-off
SED, CLD = Set/Clear Decimal
RTI = Return from Interrupt
BRK = Break
Neo:“I know kung fu.”
Morpheus:“Show me.”
© 1999 Warner Bros
Hello,World!
Hello,World!
Horizontal writing is hard
(too many pixels per scanline)
Hello,World!
Vertical writing
is the way →
(less pixels/scanline)
We can use a player
or the playfield
Hello,World!
Our display kernel will configure each
pair of visible scanlines with a byte
from a “hello world” bitmap (stored
on the card, just after the code)
Let's find which are visible, and how
we need to deal with TV timings
Source: Stella Programmers Guide, SteveWright, 1979
GAMELOGIC
(3+37+30).76=5320cycles
KERNEL
Atari 2600 VCS Programming
Atari 2600 VCS Programming
Program structure
Vertical Sync
Vertical Blank
Overscan
Playfield
main
loop
(infinite)
Kernel
X: count 0 to 191
(192 scanlines)
Program structure
Vertical Sync
Vertical Blank
Overscan
11 chars *
8 bytes *
2 scanlines
per byte =
176
scanlines
Program structure
Vertical Sync
Vertical Blank
Kernel
Overscan
Let's begin!
PROCESSOR 6502
INCLUDE "vcs.h"
ORG $F000 ; Cart begins here
Vertical Sync
Vertical Blank
Kernel
Overscan
Frame (main loop) start
StartFrame:
lda #%00000010 ; Signal VSYNC start by
sta VSYNC ; setting bit 1
REPEAT 3 ; lasts 3 scanlines
sta WSYNC ; (WSYNC = wait until
REPEND ; scanline is finished)
lda #0 ; Signal VSYNC end (and
sta VSYNC ; VBLANK start)
Vertical Sync
Vertical Blank
Kernel
Overscan
Vertical Blank
PreparePlayfield:
lda #$00
sta ENABL ; Disable ball
sta ENAM0 ; Disable missiles
sta ENAM1
sta GRP0 ; Disable players
sta GRP1 ; (with a 0s-only shape)
Vertical Sync
Vertical Blank
Kernel
Overscan
Vertical Blank
sta COLUBK ; Background (0=preto)
sta PF0 ; PF0 and PF2 stay off
sta PF2
lda #$FF ; Playfield color
sta COLUPF ; (yellow-ish)
lda #$00 ; Clear CTRLPF bit 0 to
sta CTRLPF ; repeat playfield
ldx #0 ; X: scanline counter
Vertical Sync
Vertical Blank
Kernel
Overscan
FinishVertical Blank
REPEAT 37 ; VBLANK lasts 37 scanlines
sta WSYNC ; (useful for game logic)
REPEND ;
lda #0 ; Signals VBLANK end (will
sta VBLANK ; “turn on the beam”)
Vertical Sync
Vertical Blank
Kernel
Overscan
Scanline (inner loop)
Scanline:
cpx #174 ; Phrase over?
bcs ScanlineEnd; if so, skip
txa ; Y=X÷2 (logic shift →
lsr ; divides A by 2)
tay ;
lda Phrase,y ; label,Y = mem[label+Y]
sta PF1 ; PF1 = playfield (bits
; 4 to 11) Vertical Sync
Vertical Blank
Kernel
Overscan
Scanline (close inner loop)
ScanlineEnd:
sta WSYNC ; Finish current scanline
inx ; X=line counter
cpx #191 ; last visible scanline?
bne Scanline ; unless so, repeat!
Vertical Sync
Vertical Blank
Kernel
Overscan
Overscan (close main loop)
Overscan:
lda #%00000010 ; “turn off” beam again
sta VBLANK ; 30 scanlines of
REPEAT 30 ; overscan...
sta WSYNC
REPEND
jmp StartFrame ; ...and start it over,
; forever and ever!
Vertical Sync
Vertical Blank
Kernel
Overscan
Hello...
Phrase:
.BYTE %00000000 ; H
.BYTE %01000010
.BYTE %01111110
.BYTE %01000010
.BYTE %01000010
.BYTE %01000010
.BYTE %00000000
.BYTE %00000000 ; E
.BYTE %01111110
...
...world
...
.BYTE %00000000 ; D
.BYTE %01111000
.BYTE %01000100
.BYTE %01000010
.BYTE %01000010
.BYTE %01000100
.BYTE %01111000
.BYTE %00000000 ; PF1 last value (!)
6502 configuration
ORG $FFFA ; Located at the end
; of ROM (cart)
.WORD FrameStart ; NMI address
.WORD FrameStart ; BOOT address
.WORD FrameStart ; BRK address
END
Assemble!
dasm source.asm -ocart.bin -f3
http://stella.sourceforge.net/
Advanced Tricks
Playfield-based score
Playfield-based score
The PF color can be replaced with
player colors (P0 = left side; P1 =
right side) by turning CTRLPF's
score mode bit on
PLAYERS' COLORS
(how could this improve our Hello World?)
(how could this improve our Hello World?)
Playfield-based score
Q: How can different patterns be
shown at each side of the playfield?
A: Change the pattern when the
beam is halfway through the scanline
(“race the beam”)
Atari 2600 VCS Programming
Atari 2600 VCS Programming
beam
...and you have a different shape
at the other half!
Large worlds
Pitfall!
http://pitfallharry.tripod.com/MapRoom/PitfallMap.html
Pitfall!
Screen configuration (logs, vines,
trees, stairs, crocs) was squeezed
into a single byte, but 255 screens
(bytes) are still a huge ROM table
(for Atari standards)
http://pitfallharry.tripod.com/MapRoom/PitfallMap.html
Pitfall!
David Crane implemented a sequence
generator (LFSR), which, for a given
value, would give the previous/next
ones, replacing the 255-byte table
with a 50-byte piece of code
http://en.wikipedia.org/wiki/Linear_feedback_shift_register
River Raid
River Raid
Carol Shaw had used a 16-bit generator,
resulting in thousands of non-repeating
river sectors (tweaking the interpreter
to make the first few ones easier)
When a player loses a life, rendering
restarts from the last generated number,
that is, back on the last bridge
Horizontal positioning
Horizontal positioning
The horizontal position of a player /
missile / ball is not a writable register
Games must sync to with the beam and
write to the appropriate strobe register
when it is on the desired location
STROBE TARGETS
(in theory)
You can calculate...
1 CPU cycle = 3 “color clocks” (pixels)
Horizontal Blank = 22.6 cycles
horiz. position ≈ (cycles – 22.6) * 3
...but it is an estimate, because TIA only
reads its registers every 5 CPU cycles
Smooth ↔ movement is also hard
Alternatives
A 4-bit register allows moving a player,
missile or ball relative to its previous
position (adding -7 to +8 pixels)
The missile can also be reset to the
middle of its player, making it easy to
“fire” it over and over
STROBE TARGETS
VERTICAL MOVEMENT
Just start on a different scanline at each frame
HORIZONTAL MOVEMENT
strobe registers HMP0/1 e HMM0/1
Multi-digit Score
Multi-digit score
The trick is the same of the playfield-
based score (change the registers while
the beam is drawing the scanline), but
timing is much more of an issue here
Let's say the score is 456789...
Multi-digit score
Begin the scanline with the bits for 4
on GRP0 and those for 5 on GRP1
Configure NUSIZ0 and NUSIZ1 for
a triple repetition:
4 4 4 5 5 5
Player 0 Player 1
Multi-digit score
Set player 1 position just to the right
of player 0, overlapping the triplets
454545
Player 0
Player 1
Multi-digit score
Change the patterns (GRP0/GRP1)
syncing with the beam, like this:
BEAM
454545
Multi-digit score
When the beam is about to finish
player 1's 1st
copy, change player 0 to
6 and player 1 to 7:
BEAM
454545
Multi-digit score
Repeat the trick after the 2nd
player 2
copy, this time changing player 0 to 8
and player 1 to 9
BEAM
456767
Multi-digit score
Repeat it for each scanline.
Easy! #not
BEAM
456789
Multi-digit score
There are other hurdles: we can't load
replaced digits from memory, and we
only have 3 memory-writable registers
to store 6 bit patterns...
...and that is why it is fun!
Final Words
A new look to the old school
Knowing what the Atari 2600 was
designed to do, we can appreciate
games that push it beyond its limits
by identifying “impossible” things
It is just the beginning!
The Atari homebrew scene is alive and
kicking, and these are the basics you
need to create your own games/demos
There are several uncovered topics
(sound, timers, collision, I/O...), but with
time and dedication, you can do it!
To learn more
Hello, World: https://gist.github.com/chesterbr/5864935
Sorteio 2600 http://github.com/chesterbr/sorteio2600
Racing The Beam (book): http://bit.ly/dSqhjS
David Crane's talk: http://youtu.be/MBT1OK6VAIU
David Crane's iOS tutorials: http://bit.ly/9pwYHs and http://bit.ly/qWBciZ
Stella Programmer's Guide: http://emu-docs.org/?page=Atari%202600
Classic games disassembled: http://classicdev.org/wiki/2600/Source_Code
Atari 2600 specs: http://nocash.emubase.de/2k6specs.htm
6502 reference: http://bit.ly/hxG5c6
In-browser emulator: http://jogosdeatari.com.br/
Andrew Dave's tutorial: http://bit.ly/ptQDdA (the whole site is great)
Harmony (SD-reader cart): http://harmony.atariage.com/
BAtari (BASIC compiler): http://bataribasic.com
TIA sound examples: http://bit.ly/tnbPrp
Bankswitching (more ROM/RAM): http://bit.ly/tqhLZk
Questions?
Thank you!
@chesterbr
http://slideshare.net/chesterbr
http://chester.me
Credits and License
This presentation is available under the
licença Creative Commons “by-nc” 3.0 l,
noticing the exceptions below
Images from third parties were included (with due credits) under
fair use assumption and/or under their respective licenses.
These are excluded from the license above.
Atari™,Adventure™, Donkey Kong™, Pitfall™, Super Mario™ and
likewise characters/games/systems are mentioned uniquely for
illustrative purposes, also under fair use assumption.They are property
of their rights holders, and are also excluded from the license above.
1 of 151

More Related Content

Viewers also liked(20)

AtariAtari
Atari
Tony Freeman496 views
Atari foda montalvo cruzAtari foda montalvo cruz
Atari foda montalvo cruz
Brayan Alejandro Montalvo Cruz1.6K views
git fail --force (make it up with your pull requests)git fail --force (make it up with your pull requests)
git fail --force (make it up with your pull requests)
Carlos Duarte do Nascimento1.3K views
AtariAtari
Atari
sharusharief941.7K views
Adventure lectureAdventure lecture
Adventure lecture
Pptblog Pptblogcom835 views
gamesgames
games
marionnoriam510 views
The Video Game R-EvolutionThe Video Game R-Evolution
The Video Game R-Evolution
Julio Seaman1.5K views
IntroVideojuegosIntroVideojuegos
IntroVideojuegos
vacacionesvideojuegos1.1K views
DeepHack.Game Skynet teamDeepHack.Game Skynet team
DeepHack.Game Skynet team
DeepHackLab1K views
DeepHack.Game 5vision teamDeepHack.Game 5vision team
DeepHack.Game 5vision team
DeepHackLab1.1K views
Aula 02   operadores aritiméticosAula 02   operadores aritiméticos
Aula 02 operadores aritiméticos
Tácito Graça583 views
Caderno didatico pascalCaderno didatico pascal
Caderno didatico pascal
Alvaro Melo1.5K views
Módulo 2  pascalMódulo 2  pascal
Módulo 2 pascal
Hilário Santos Russo1.5K views
Passar de algoritmo para pascalPassar de algoritmo para pascal
Passar de algoritmo para pascal
moraesdenise1.4K views
Aula 03   estrutura de seleçãoAula 03   estrutura de seleção
Aula 03 estrutura de seleção
Tácito Graça1K views
Apostila pascal Apostila pascal
Apostila pascal
Michael Soto2K views
Guia Rápido Da Linguagem PascalGuia Rápido Da Linguagem Pascal
Guia Rápido Da Linguagem Pascal
MikeNandes1.2K views

Similar to Atari 2600 VCS Programming(20)

 8086-instruction-set-ppt 8086-instruction-set-ppt
8086-instruction-set-ppt
jemimajerome27.9K views
Brief description of all the interuptsBrief description of all the interupts
Brief description of all the interupts
SHREEHARI WADAWADAGI280 views
Reading php terminal-gameboy-emulatorReading php terminal-gameboy-emulator
Reading php terminal-gameboy-emulator
Tomoki Hasegawa4.8K views
PALPAL
PAL
Prakash Rao94 views
int 21 h for screen displayint 21 h for screen display
int 21 h for screen display
Anju Kanjirathingal1K views
8-bit Emulator Programming with Go8-bit Emulator Programming with Go
8-bit Emulator Programming with Go
Ignacio Sánchez Ginés925 views
Instruction set of 8086Instruction set of 8086
Instruction set of 8086
Tirumalesh Nizampatnam3K views
Home works summary.pptxHome works summary.pptx
Home works summary.pptx
HebaEng7 views
Multipliers in VLSIMultipliers in VLSI
Multipliers in VLSI
Kiranmai Sony18.6K views
Keyboard interruptKeyboard interrupt
Keyboard interrupt
Tech_MX11.6K views
Arduino based applications part 2Arduino based applications part 2
Arduino based applications part 2
Jawaher Abdulwahab Fadhil92 views
Chapter 2   The 8088 MicroprocessorChapter 2   The 8088 Microprocessor
Chapter 2 The 8088 Microprocessor
Dwight Sabio1.6K views
Lecture6Lecture6
Lecture6
misgina Mengesha573 views
RapportRapport
Rapport
yahya ayari807 views
CAAL_CCSU_U1.pdfCAAL_CCSU_U1.pdf
CAAL_CCSU_U1.pdf
salabhmehrotra4 views
amba.pptamba.ppt
amba.ppt
Rahul5340357 views
system software 16 markssystem software 16 marks
system software 16 marks
vvcetit43.2K views
amba.pptamba.ppt
amba.ppt
DivyaDewkathe10 views
amba.pptamba.ppt
amba.ppt
VediAshutosh4 views

More from Carlos Duarte do Nascimento(8)

git fail --force (faça as pazes com seus pull requests)git fail --force (faça as pazes com seus pull requests)
git fail --force (faça as pazes com seus pull requests)
Carlos Duarte do Nascimento644 views
Mashups: Criando Valor na Web 2.0 (BandTec)Mashups: Criando Valor na Web 2.0 (BandTec)
Mashups: Criando Valor na Web 2.0 (BandTec)
Carlos Duarte do Nascimento1K views
Aplicativos Mobile: Da Idéia ao Produto (ou não)Aplicativos Mobile: Da Idéia ao Produto (ou não)
Aplicativos Mobile: Da Idéia ao Produto (ou não)
Carlos Duarte do Nascimento673 views
Apontador API (para programadores Python)Apontador API (para programadores Python)
Apontador API (para programadores Python)
Carlos Duarte do Nascimento1.5K views
Mashups: Criando Valor na Web 2.0Mashups: Criando Valor na Web 2.0
Mashups: Criando Valor na Web 2.0
Carlos Duarte do Nascimento791 views
Cruzalinhas - Palestra Relâmpago no Fisl 11Cruzalinhas - Palestra Relâmpago no Fisl 11
Cruzalinhas - Palestra Relâmpago no Fisl 11
Carlos Duarte do Nascimento720 views

Recently uploaded(20)

Atari 2600 VCS Programming

  • 1. game program™ ATARI 2600 PROGRAMMING Use with Keyboard Controllers PROGRAM CONTENTS 2011-2013 CHESTER, INC. ©
  • 2. What An overview of the Atari 2600 architecture, covering everything needed to create a “Hello,World!” program that can run on emulators or even on a real Atari http://slideshare.net/chesterbr
  • 3. Why ● Pure nostalgia ● Homebrew games ● Demoscene ● Appreciate masterworks such as Enduro, Pitfall! or River Raid ● Feel better about today's tools and hardware limitations :-) http://slideshare.net/chesterbr
  • 6. Over 600 titles...imagem: mitchelaneous.com
  • 7. but why were they so...“Atari-ish”?
  • 8. Let's look inside and find out! (Atari 2600 Jr. printed circuit board)
  • 13. Look ma, no O.S.! Atari programs talk directly to the hardware – there is no middle man! Its 6502 CPU only “understands” memory reads and writes, so all the other chips are hard-wired to act as memory (even those who aren't)
  • 14. Memory Map (very, very, very simplified*) 0000-002C – TIA (write) 0030-003D – TIA (read) 0080-00FF – RIOT (RAM) 0280-0297 – RIOT (I/O,Timer) F000-FFFF – Cartridge (ROM) *http://nocash.emubase.de/2k6specs.htm
  • 15. Memory Map F000-FFFF – Cartridge (ROM) (this is not your biggest problem...) 4 KBytes!
  • 16. Memory Map 0080-00FF – RIOT (RAM) (and still not your biggest problem) 128 BYTES!!!!! (1/8 of a KB)
  • 17. VRAM (frame buffer) Typical video chips translate bit patterns stored onVideo RAM (VRAM) into pixels and colors
  • 19. VRAM Screen resolution and color depth are subject toVRAM size limits Memory was expensive on the 70s/80s, leading to trade-offs How muchVRAM does an Atari have?
  • 20. Memory Map 0000-002C – TIA (write) 0030-003D – TIA (read) 0080-00FF – RIOT (RAM) 0280-0297 – RIOT (I/O,Timer) F000-FFFF – Cartridge (ROM)
  • 22. Memory Map 0 bytes !!!! ????-???? – VRAM right, now you got a problem...
  • 23. Racing the Beam Since we can't just write pixels to someVRAM frame buffer, our code will need to work a bit closer to the TV hardware, with a little help from a very unique chip...
  • 25. How a TV set works Image: cc-by wikipedia user Grm_wnr
  • 26. Scanlines public domain illustration by Ian Harvey 60 frames per second (NTSC standard)
  • 27. TIA is scanline-oriented As the beam draws each scanline, the game program must set TIA registers to configure the objects drawn on it Most of this objects have only one color, making multiple colors on the same scanline theoretically impossible...
  • 30. Screen Objects ● Playfield (PF) ● Players (P0, P1) ● Missiles/Ball (M0, M1, BL) Scanlines will be rendered based on how we configure TIA's screen objects:
  • 31. Playfield (PF) 20-bit pattern with a foreground and a background color, rendered over the left side of the scanline The right side will either repeat or refect the same pattern (the later generating a symmetrical image)
  • 36. Playfield configuration PF0 = 0000 ←← order PF1 = 00000000 order →→ PF2 = 00000000 ←← order REFLECT = 0 resulting scanline
  • 37. Playfield configuration PF0 = 0001 ←← order PF1 = 00000000 order →→ PF2 = 00000000 ←← order REFLECT = 0 resulting scanline _ _
  • 38. Playfield configuration PF0 = 0011 ←← order PF1 = 00000000 order →→ PF2 = 00000000 ←← order REFLECT = 0 resulting scanline __ __
  • 39. Playfield configuration PF0 = 0111 ←← order PF1 = 00000000 order →→ PF2 = 00000000 ←← order REFLECT = 0 resulting scanline ___ ___
  • 40. Playfield configuration PF0 = 1111 ←← order PF1 = 11110000 order →→ PF2 = 00000000 ←← order REFLECT = 0 resulting scanline ________ _______
  • 41. Playfield configuration PF0 = 1111 ←← order PF1 = 11111110 order →→ PF2 = 00010101 ←← order REFLECT = 0 resulting scanline ___________ _ _ _ ___________ _ _ _
  • 42. Playfield configuration PF0 = 1111 ←← order PF1 = 11111110 order →→ PF2 = 00010101 ←← order REFLECT = 1 resulting scanline ___________ _ _ _ _ _ _ ___________
  • 43. ___________ _ _ _ _ _ _ ___________
  • 44. Players (P0, P1) Each one is an independent 8 bit pattern (GRP0/GRP1) with a foreground color (COLUP0 / COLUP1) that can be positioned at any column of the scanline e.g.: 10100001 → ████████
  • 47. Players Each player can be horizontally stretched, multiplied or inverted by setting NUSIZn / REFPn (n=0/1) (number/size and reflect player)
  • 49. With REFP0 (or REFP1) on 000 001 010 011 100 101 110 111 NUSIZn
  • 56. Missiles/Ball (M0/M1/BL) Can be positioned just like players, but no bit pattern, just a pixel (although it can be horizontally stretched 2/4/8x) M0/M1 use P0/P1colors, while BL uses the PF foreground color
  • 58. BALL
  • 59. BALL
  • 62. Master Plan For each scanline, configure the options for each object before the beam reaches its intended position The time slot is very short, forcing programmers to pick and choose what to change, reusing as much as they can
  • 63. How short? 6502 ≈ 1,19Mhz (1.194.720 cycles/sec) NTSC: 60 frames per second 1.194.720/60 ≅ 19.912 cycles per frame
  • 64. How short? CPU: 19.912 cyles per frame NTSC: 262 scanlines per frame 19.912 / 262 = 76 cycles per scanline
  • 65. How short? CPU: 19.912 cyles per frame NTSC: 262 scanlines per frame 19.912 / 262 = 76 cycles per scanline and what can we do with 76 cycles? (by the way:WTF is a “cycle”?)
  • 68. 6502
  • 69. 6502 (Atari-wise) Reads a program from the cartridge (ROM) composed of operations that manipulate and transfer bytes between cartridge, RIOT (RAM, I/O, timers) and TIA, keeping state on internal registers
  • 70. Operations Each operation that composes a 6502 program in memory is identified by a 1-byte opcode and can be followed by up to 2 bytes of parameters An instruction can take up to 6 cycles to be executed
  • 71. Registers A = Accumulator (8 bits) X,Y= Indexes (8 bits) S = Stack Pointer (8 bits) P = Status (fags, 8 bits) PC = Program Counter (16 bits)
  • 72. Example program “add 2 to a value stored at a memory position; store the result into another memory position”
  • 73. Implementation ● Read the byte stored on memory position 0200 into register A ● Add 2 to register A's value ● Write register A's value into memory position 0201
  • 74. 6502 Machine Code AD Opcode (Memory → A) 00 Last part of “0200” 02 First part of “0200” 69 Opcode (value + A → A) 02 Value to add 8D Opcode (A → Memory) 01 Last part of “0201” 02 First part of “0201”
  • 76. 6502 Assembly Language Associates the 151 opcodes with 56 mnnemonic instructions and a notation for their parameters (access mode)
  • 77. 6502 Machine Code AD Opcode (Memory → A) 00 Last part of “0200” 02 First part of “0200” 69 Opcode (value + A → A) 02 Value to add 8D Opcode (A → Memory) 01 Last part of “0201” 02 First part of “0201”
  • 78. Assembly 6502 AD LDA $0200 00 02 69 ADC #02 02 8D STA $0201 01 02
  • 79. Assembler Program that reads a text file written in Assembly language and assembles a binary file with the corresponding machine code foo.asm LDA $0200 ADC #02 STA $0201 ... foo.bin AD000269 028D0102 ... ASSEMBLER
  • 80. Macro Assembler ORG $0100 ; Start @ memory 0100 ... SomeLabel: LDX #$10 ; No idea where this DEX ; will be in memory, BNE SomeLabel ; and don't need to! ...
  • 81. DASM ● 6502 Macro Assembler ● Includes Atari headers ● Multiplataform ● Free and open-source (GPLv2) http://dasm-dillon.sourceforge.net/
  • 82. Notation (for today) #... = decimal value #$... = hex value $... = hex address $... , X = hex address + X http://www.obelisk.demon.co.uk/6502/addressing.html
  • 83. 6502 Instruction Set = most relevant for Atari 2600 programming
  • 84. Data Transfer LDA, LDX, LDY = Load STA, STX, STY = Store TAX,TAY,TXA, TYA,TSX,TXS = Transfer LDA #$10 0x10→A STY $0200 Y→m(0x0200) TXA X→A
  • 85. Arithmetic ADC, SBC = +,- (w/ carry) INC, INX, INY = ++ DEC, DEX, DEY = -- ADC $0100 m(0x100)+A→A INC $0200 m(0x200)+1→ m(0x200) DEX X-1→X
  • 86. Bit Operations AND, ORA, EOR = &, |, ^ (A) ASL, LSR = Arithmetic shift ROL, ROR = “Rotating” shift AND #$11 A&0x11→A LSR A>>1→A (A/2→A) ROR A>>1 (bit 7=carry)
  • 87. Comparing / Branching CMP, CPX, CPY = compare A/X/Y (-) BCS, BCC = ⇗ if carry set / clear BEQ, BNE = ⇗ if equal / not equal BVS, BVC = ⇗ if overfow set / clear BMI, BPL = ⇗ if minus / plus CPY $1234 if y=m(0x1234), BEQ $0200 0x0200→PC
  • 88. Stack and Subroutines JSR, RTS = call/return subroutine PHA, PLA = push / pull A PHP, PLP = push / pull status (P) JSR $1234 PC(+3)→stack, 0x1234→PC RTS stack→PC
  • 89. Everything else... NOP = No Operation JMP = Direct Jump (GOTO) SEC, CLC = Set/Clear Carry SEV, CLV = Set/Clear oVerfow SEI, CLI = Set/Clear Interrupt-off SED, CLD = Set/Clear Decimal RTI = Return from Interrupt BRK = Break
  • 90. Neo:“I know kung fu.” Morpheus:“Show me.” © 1999 Warner Bros
  • 92. Hello,World! Horizontal writing is hard (too many pixels per scanline)
  • 93. Hello,World! Vertical writing is the way → (less pixels/scanline) We can use a player or the playfield
  • 94. Hello,World! Our display kernel will configure each pair of visible scanlines with a byte from a “hello world” bitmap (stored on the card, just after the code) Let's find which are visible, and how we need to deal with TV timings
  • 95. Source: Stella Programmers Guide, SteveWright, 1979 GAMELOGIC (3+37+30).76=5320cycles KERNEL
  • 98. Program structure Vertical Sync Vertical Blank Overscan Playfield
  • 99. main loop (infinite) Kernel X: count 0 to 191 (192 scanlines) Program structure Vertical Sync Vertical Blank Overscan 11 chars * 8 bytes * 2 scanlines per byte = 176 scanlines
  • 101. Let's begin! PROCESSOR 6502 INCLUDE "vcs.h" ORG $F000 ; Cart begins here Vertical Sync Vertical Blank Kernel Overscan
  • 102. Frame (main loop) start StartFrame: lda #%00000010 ; Signal VSYNC start by sta VSYNC ; setting bit 1 REPEAT 3 ; lasts 3 scanlines sta WSYNC ; (WSYNC = wait until REPEND ; scanline is finished) lda #0 ; Signal VSYNC end (and sta VSYNC ; VBLANK start) Vertical Sync Vertical Blank Kernel Overscan
  • 103. Vertical Blank PreparePlayfield: lda #$00 sta ENABL ; Disable ball sta ENAM0 ; Disable missiles sta ENAM1 sta GRP0 ; Disable players sta GRP1 ; (with a 0s-only shape) Vertical Sync Vertical Blank Kernel Overscan
  • 104. Vertical Blank sta COLUBK ; Background (0=preto) sta PF0 ; PF0 and PF2 stay off sta PF2 lda #$FF ; Playfield color sta COLUPF ; (yellow-ish) lda #$00 ; Clear CTRLPF bit 0 to sta CTRLPF ; repeat playfield ldx #0 ; X: scanline counter Vertical Sync Vertical Blank Kernel Overscan
  • 105. FinishVertical Blank REPEAT 37 ; VBLANK lasts 37 scanlines sta WSYNC ; (useful for game logic) REPEND ; lda #0 ; Signals VBLANK end (will sta VBLANK ; “turn on the beam”) Vertical Sync Vertical Blank Kernel Overscan
  • 106. Scanline (inner loop) Scanline: cpx #174 ; Phrase over? bcs ScanlineEnd; if so, skip txa ; Y=X÷2 (logic shift → lsr ; divides A by 2) tay ; lda Phrase,y ; label,Y = mem[label+Y] sta PF1 ; PF1 = playfield (bits ; 4 to 11) Vertical Sync Vertical Blank Kernel Overscan
  • 107. Scanline (close inner loop) ScanlineEnd: sta WSYNC ; Finish current scanline inx ; X=line counter cpx #191 ; last visible scanline? bne Scanline ; unless so, repeat! Vertical Sync Vertical Blank Kernel Overscan
  • 108. Overscan (close main loop) Overscan: lda #%00000010 ; “turn off” beam again sta VBLANK ; 30 scanlines of REPEAT 30 ; overscan... sta WSYNC REPEND jmp StartFrame ; ...and start it over, ; forever and ever! Vertical Sync Vertical Blank Kernel Overscan
  • 109. Hello... Phrase: .BYTE %00000000 ; H .BYTE %01000010 .BYTE %01111110 .BYTE %01000010 .BYTE %01000010 .BYTE %01000010 .BYTE %00000000 .BYTE %00000000 ; E .BYTE %01111110 ...
  • 110. ...world ... .BYTE %00000000 ; D .BYTE %01111000 .BYTE %01000100 .BYTE %01000010 .BYTE %01000010 .BYTE %01000100 .BYTE %01111000 .BYTE %00000000 ; PF1 last value (!)
  • 111. 6502 configuration ORG $FFFA ; Located at the end ; of ROM (cart) .WORD FrameStart ; NMI address .WORD FrameStart ; BOOT address .WORD FrameStart ; BRK address END
  • 112. Assemble! dasm source.asm -ocart.bin -f3 http://stella.sourceforge.net/
  • 115. Playfield-based score The PF color can be replaced with player colors (P0 = left side; P1 = right side) by turning CTRLPF's score mode bit on
  • 117. (how could this improve our Hello World?)
  • 118. (how could this improve our Hello World?)
  • 119. Playfield-based score Q: How can different patterns be shown at each side of the playfield? A: Change the pattern when the beam is halfway through the scanline (“race the beam”)
  • 122. beam ...and you have a different shape at the other half!
  • 126. Pitfall! Screen configuration (logs, vines, trees, stairs, crocs) was squeezed into a single byte, but 255 screens (bytes) are still a huge ROM table (for Atari standards) http://pitfallharry.tripod.com/MapRoom/PitfallMap.html
  • 127. Pitfall! David Crane implemented a sequence generator (LFSR), which, for a given value, would give the previous/next ones, replacing the 255-byte table with a 50-byte piece of code http://en.wikipedia.org/wiki/Linear_feedback_shift_register
  • 129. River Raid Carol Shaw had used a 16-bit generator, resulting in thousands of non-repeating river sectors (tweaking the interpreter to make the first few ones easier) When a player loses a life, rendering restarts from the last generated number, that is, back on the last bridge
  • 131. Horizontal positioning The horizontal position of a player / missile / ball is not a writable register Games must sync to with the beam and write to the appropriate strobe register when it is on the desired location
  • 133. You can calculate... 1 CPU cycle = 3 “color clocks” (pixels) Horizontal Blank = 22.6 cycles horiz. position ≈ (cycles – 22.6) * 3 ...but it is an estimate, because TIA only reads its registers every 5 CPU cycles Smooth ↔ movement is also hard
  • 134. Alternatives A 4-bit register allows moving a player, missile or ball relative to its previous position (adding -7 to +8 pixels) The missile can also be reset to the middle of its player, making it easy to “fire” it over and over
  • 136. VERTICAL MOVEMENT Just start on a different scanline at each frame HORIZONTAL MOVEMENT strobe registers HMP0/1 e HMM0/1
  • 138. Multi-digit score The trick is the same of the playfield- based score (change the registers while the beam is drawing the scanline), but timing is much more of an issue here Let's say the score is 456789...
  • 139. Multi-digit score Begin the scanline with the bits for 4 on GRP0 and those for 5 on GRP1 Configure NUSIZ0 and NUSIZ1 for a triple repetition: 4 4 4 5 5 5 Player 0 Player 1
  • 140. Multi-digit score Set player 1 position just to the right of player 0, overlapping the triplets 454545 Player 0 Player 1
  • 141. Multi-digit score Change the patterns (GRP0/GRP1) syncing with the beam, like this: BEAM 454545
  • 142. Multi-digit score When the beam is about to finish player 1's 1st copy, change player 0 to 6 and player 1 to 7: BEAM 454545
  • 143. Multi-digit score Repeat the trick after the 2nd player 2 copy, this time changing player 0 to 8 and player 1 to 9 BEAM 456767
  • 144. Multi-digit score Repeat it for each scanline. Easy! #not BEAM 456789
  • 145. Multi-digit score There are other hurdles: we can't load replaced digits from memory, and we only have 3 memory-writable registers to store 6 bit patterns... ...and that is why it is fun!
  • 147. A new look to the old school Knowing what the Atari 2600 was designed to do, we can appreciate games that push it beyond its limits by identifying “impossible” things
  • 148. It is just the beginning! The Atari homebrew scene is alive and kicking, and these are the basics you need to create your own games/demos There are several uncovered topics (sound, timers, collision, I/O...), but with time and dedication, you can do it!
  • 149. To learn more Hello, World: https://gist.github.com/chesterbr/5864935 Sorteio 2600 http://github.com/chesterbr/sorteio2600 Racing The Beam (book): http://bit.ly/dSqhjS David Crane's talk: http://youtu.be/MBT1OK6VAIU David Crane's iOS tutorials: http://bit.ly/9pwYHs and http://bit.ly/qWBciZ Stella Programmer's Guide: http://emu-docs.org/?page=Atari%202600 Classic games disassembled: http://classicdev.org/wiki/2600/Source_Code Atari 2600 specs: http://nocash.emubase.de/2k6specs.htm 6502 reference: http://bit.ly/hxG5c6 In-browser emulator: http://jogosdeatari.com.br/ Andrew Dave's tutorial: http://bit.ly/ptQDdA (the whole site is great) Harmony (SD-reader cart): http://harmony.atariage.com/ BAtari (BASIC compiler): http://bataribasic.com TIA sound examples: http://bit.ly/tnbPrp Bankswitching (more ROM/RAM): http://bit.ly/tqhLZk
  • 151. Credits and License This presentation is available under the licença Creative Commons “by-nc” 3.0 l, noticing the exceptions below Images from third parties were included (with due credits) under fair use assumption and/or under their respective licenses. These are excluded from the license above. Atari™,Adventure™, Donkey Kong™, Pitfall™, Super Mario™ and likewise characters/games/systems are mentioned uniquely for illustrative purposes, also under fair use assumption.They are property of their rights holders, and are also excluded from the license above.