Quantcast
Channel: VBForums - Game Demos
Viewing all articles
Browse latest Browse all 56

Atari 2600 Programming Tutorial 3 - The Playfield (Demo Included)

$
0
0
Welcome back to another exciting episode of my ultimate Atari 2600 programming tutorial. :bigyello:

Now things are gonna get interesting because now you are gonna get to plot pixels on the screen! Just one problem though. This one is a pain in the neck because the Atari was designed as a Pong-like system with cutting costs in mind. Even though there are 160 color clocks per visible scanline, there are only 40 pixels across the screen, with every pixel being 4x1 pixels wide. So the dimensions of the draw field pixels are 40x192. Thats why everything in Atari 2600 games looks so wide.

As for the playfield itself, there are 3 registers. PF0, PF1, and PF2. They only cover half the screen and is mirrored on the other side. PF0 is only 4 pixels wide, PF1 is 8 pixels wide, and PF2 is 8 pixels wide. So if you do the math, 4+8+8 + 4+8+8 = 40 pixels. Even though PF0 is 8 bits, the lower 4 bits are completely ignored by the processor. Any bits that are set will plot the pixels on the screen and mirror it on the other side. But it gets even worse. PF0 and PF2's bits are reveresed! For example if PF0 is 00010000, with the lower 4 bits ignored, and the upper 4 bits reversed, it will draw a pixel on the left side of the screen using 1000. So you can imagine games with scrolling being extremely difficult to program on this beast with not only PF0 and PF2's bits being reversed, but also mirrored on the other side!

The mirroring can be turned on and off as well with the first bit of CTRLPF.

Mirroring On:
Code:

        lda #%00000001
        sta CTRLPF


Mirroring Off:
Code:

        lda #%00000000
        sta CTRLPF

What that does if the mirroring is on is that the left half of the screen becomes PF0, PF1, PF2 and the right half becomes PF2, PF1, PF0. If the mirroring is off, it becomes PF0, PF1, PF2, and PF0, PF1, PF2.

But the bits are more than for just mirroring. Take a look at what the other bits do!

Code:

CTRLPF

    This address is used to write into the playfield control

    register (a logic 1 causes action as described below)



    D0 = REF (reflect playfield)



    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 can

    move behind the playfield)



    D4 & D5 = BALL SIZE

              D5  D4  Width

              0    0    1 clock

              0    1    2 clocks

              1    0    4 clocks

              1    1    8 clocks

You can also set the color of the playfield through the COLUPF. For example:

Code:

        lda #$45
        sta COLUPF

This will set the color for the entire playfield to maroon red.

Now that you got the basics of what a playfield is, it's time to do some code to draw a playfield! In this example we will be drawing a border all around the screen with a blue background:

Code:

        processor 6502

        include "vcs.h"
        include "macro.h"
       

BLUE        = $9A
       
;------------------------------------------------------------------------------
        SEG
        ORG $F000
       
Reset
; Clear RAM and all TIA registers
        ldx #0
        lda #0
Clear         
        sta 0,x
        inx
        bne Clear
;------------------------------------------------
; Once-only initialization. . .
        lda #BLUE
        sta COLUBK            ; set the background color
       
        lda #$45
        sta COLUPF
       
        lda #%00000001
        sta CTRLPF
       
;------------------------------------------------

StartOfFrame
; Start of new frame
; Start of vertical blank processing
        lda #0
        sta VBLANK
        lda #2
        sta VSYNC
        sta WSYNC
        sta WSYNC
        sta WSYNC              ; 3 scanlines of VSYNC signal
        lda #0
        sta VSYNC
;------------------------------------------------
; 37 scanlines of vertical blank. . .
        ldx #0
VerticalBlank 
        sta WSYNC
        inx
        cpx #37
        bne VerticalBlank
;------------------------------------------------
; Do 192 scanlines of color-changing (our picture)
      ldx #0                ; this counts our scanline number
      lda #%11111111
      sta PF0
      sta PF1
      sta PF2
      ; We won't bother rewriting PF0-PF2 every scanline of the top 8 lines - they never change!

Top8Lines     
        sta WSYNC
    inx
    cpx #8                ; are we at line 8?
    bne Top8Lines          ; No, so do another

    ; Now we want 176 lines of "wall"
    ; Note: 176 (middle) + 8 (top) + 8 (bottom) = 192 lines

    lda #%00010000        ; PF0 is mirrored <--- direction, low 4 bits ignored
    sta PF0
    lda #0
    sta PF1
    sta PF2
    ; again, we don't bother writing PF0-PF2 every scanline - they never change!

MiddleLines   
        sta WSYNC
    inx
    cpx #184
    bne MiddleLines
    ; Finally, our bottom 8 scanlines - the same as the top 8
    ; AGAIN, we aren't going to bother writing PF0-PF2 mid scanline!
    lda #%11111111
    sta PF0
    sta PF1
    sta PF2

Bottom8Lines   
        sta WSYNC
    inx
    cpx #192
    bne Bottom8Lines
;------------------------------------------------
    lda #%01000010
    sta VBLANK          ; end of screen - enter blanking     
;------------------------------------------------
; 30 scanlines of overscan. . .
        ldx #0
Overscan       
        sta WSYNC
        inx
        cpx #30
        bne Overscan
        jmp StartOfFrame
;------------------------------------------------------------------------------

        ORG $FFFA
       
InterruptVectors
        .word Reset          ; NMI
        .word Reset          ; RESET
        .word Reset          ; IRQ

END

Save the file as playfield.asm, and change the Compile.bat code to this:

Code:

@echo off
dasm playfield.asm -lkernel.txt -f3 -v5 -oplayfield.bin

Be sure its all in the same folder as the DASM.exe so it can compile! Run the batch file to compile the playfield.asm code. You should have a playfield.bin file created. Run it through Stella and it should look like this:



And that's how it's done! You can play around with where the pixels are plotted if you'd like, or even change the colors of everything.

Exercise: Remove the right wall while having the left wall remain!

Answer to Tutorial 2 exercise:
Code:

        processor 6502

        include "vcs.h"
        include "macro.h"

BLACK        = $00
       
;------------------------------------------------------------------------------
        SEG
        ORG $F000
       
Reset
; Clear RAM and all TIA registers
        ldx #0
        lda #0
Clear         
        sta 0,x
        inx
        bne Clear
;------------------------------------------------
; Once-only initialization. . .
        lda #BLACK
        sta COLUBK            ; set the background color
;------------------------------------------------

StartOfFrame
; Start of new frame
; Start of vertical blank processing
        lda #0
        sta VBLANK
        lda #2
        sta VSYNC
        sta WSYNC
        sta WSYNC
        sta WSYNC              ; 3 scanlines of VSYNC signal
        lda #0
        sta VSYNC
;------------------------------------------------
; 37 scanlines of vertical blank. . .
        ldx #0
VerticalBlank 
        sta WSYNC
        inx
        cpx #37
        bne VerticalBlank
;------------------------------------------------
;192 lines of drawfield
        ldx #0
DrawField:

        sta WSYNC
        inx
        stx COLUBK
        cpx #192
        bne DrawField
;------------------------------------------------
; end of screen - enter blanking
        lda #%01000010
        sta VBLANK         
;------------------------------------------------
; 30 scanlines of overscan. . .
        ldx #0
Overscan       
        sta WSYNC
        inx
        cpx #30
        bne Overscan
        jmp StartOfFrame
;------------------------------------------------

        ORG $FFFA
       
InterruptVectors
        .word Reset          ; NMI
        .word Reset          ; RESET
        .word Reset          ; IRQ

END

Next tutorial I'm gonna show you how to do real graphics through asymmetrical playfields :)
Attached Files

Viewing all articles
Browse latest Browse all 56

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>