Jump to content
Coolcrab

Book: Making Games for the Atari 2600

Recommended Posts

Hey all, I came across this book on amazon. Is it any good? I couldn't find a topic on it on the forum (But the title is very generic, so maybe I missed it.)

https://www.amazon.co.uk/Making-Games-Atari-2600-Steven/dp/1541021304/ref=sr_1_4?s=books&ie=UTF8&qid=1506863939&sr=1-4&keywords=atari+2600

Yes it is !

Lot's of info about 2600 in one place explained in clear way. Nothing out of ordinary or that you can't find somewhere else.

 

Price point is not on the low side, but if you like to read and you're serious about making (and finishing) a game for a2600, go for it :)

Share this post


Link to post
Share on other sites

I bought it, really nice book.

 

It's a handy reference when I don't feel like pulling up the web, or just wanna read about some Atari code.

Share this post


Link to post
Share on other sites
Posted (edited)

Hey all, newbie here.  I need some help with this book for chapter 8, in particular the part beginning with "YPos .byte" and ending where I'm supposed to set the address bus to #5 and then sta YPos.  

 

Mainly, this doesn't work.  Nothing ever gets passed to the variable YPos unless I initialize it.  If I don't leave the initialization value blank, as that part of the book seems to imply, then the Y position will be whatever I initialize the variable to.  Otherwise, it's 0, and there's a big old blue line beneath the cat head sprite I'm putting on the screen.  (speaking of that, where is the cowboy sprite written out in this chapter?  I'm a little frustrated with the way this book is organized since the example snippets don't seem to match up to any actual code samples I can find if I really need to reference them). 

 

I started out in Basic when I was a kid, programmed a game in GRASP when I was 15-16, did a smattering of Assembly in college, then mentally became lazy and out of shape as I became dependent on ECMAScript style languages, so I'm a bit out of it. :)

 

Also note:  if I hard code the Y position, it also works and the blue line vanishes.  But I want to do this the right way.

 

Edited by SavedByZero

Share this post


Link to post
Share on other sites
On 7/11/2019 at 5:09 PM, SavedByZero said:

Hey all, newbie here.  I need some help with this book for chapter 8, in particular the part beginning with "YPos .byte" and ending where I'm supposed to set the address bus to #5 and then sta YPos.  

 

Mainly, this doesn't work.  Nothing ever gets passed to the variable YPos unless I initialize it.  If I don't leave the initialization value blank, as that part of the book seems to imply, then the Y position will be whatever I initialize the variable to.  Otherwise, it's 0, and there's a big old blue line beneath the cat head sprite I'm putting on the screen.  (speaking of that, where is the cowboy sprite written out in this chapter?  I'm a little frustrated with the way this book is organized since the example snippets don't seem to match up to any actual code samples I can find if I really need to reference them). 

 

I started out in Basic when I was a kid, programmed a game in GRASP when I was 15-16, did a smattering of Assembly in college, then mentally became lazy and out of shape as I became dependent on ECMAScript style languages, so I'm a bit out of it. :)

 

Also note:  if I hard code the Y position, it also works and the blue line vanishes.  But I want to do this the right way.

 

I have this book and it has been quite helpful .  Can you post your code ? 

I can send you some code snippets that use this routine . I have the cat head program somewhere 

Share this post


Link to post
Share on other sites
On 7/13/2019 at 10:32 PM, easmith said:

I have this book and it has been quite helpful .  Can you post your code ? 

I can send you some code snippets that use this routine . I have the cat head program somewhere 

Yup. The relevant code is simply:

YPos .byte 

 

LDA #5 

Sta YPos

 

Simply put, the address bus value isn’t being stored in YPos. YPos stays to whatever I initialize it to. 

This is early chapter 8 code, which has no accompanying source on the website.

thanks!

Share this post


Link to post
Share on other sites
On 7/17/2019 at 10:22 PM, SavedByZero said:

Yup. The relevant code is simply:

YPos .byte 

 

LDA #5 

Sta YPos

 

Simply put, the address bus value isn’t being stored in YPos. YPos stays to whatever I initialize it to. 

This is early chapter 8 code, which has no accompanying source on the website.

thanks!

posy  the entire  program please. Or send it to me through messenger if you do not want to post it  

Share this post


Link to post
Share on other sites
Posted (edited)

Yes. Good book!

I bought this book a couple of months ago and it was worth it. Really easy to read and good examples, but you need to dig deeper in the code to understand some of the techniques.

What helped me a lot was the fact that I read the book after taking that online course from Gustavo Pezzi (from pikuma.com). He even recommends the book in the last session, as one of the suggestions for next steps after the course.

I learned a lot from his videos and also from Hugg's book.

Edited by pinkydutta
typos

Share this post


Link to post
Share on other sites
On 7/21/2019 at 10:18 AM, easmith said:

posy  the entire  program please. Or send it to me through messenger if you do not want to post it  


	processor 6502
        include "vcs.h"
        include "macro.h"
        include "xmacro.h"

        org $f000

BGColor equ $81
counter equ #0
SpriteHeight equ 9
TooLow equ 5
YPos .byte 
	
Start
	CLEAN_START

NextFrame
       
        lda #2
        sta VBLANK

        sta VSYNC
	sta WSYNC
        sta WSYNC
        sta WSYNC
        lda #0
        sta VSYNC
        
        ldx #37 
LVBlank
	sta WSYNC
        dex 
        bne LVBlank
        lda #0
        sta VBLANK

        ldx #192
        ;ldy counter
        lda $5
  	sta YPos
    
LVScan 
	txa 
        sec 
        sbc YPos 
        cmp #SpriteHeight
        bcc InSprite 
        lda #0;
InSprite
	tay
        lda Frame0,y
        sta WSYNC
        sta GRP0
        lda ColorFrame0,y
CUT
	sta COLUP0        
        dex 
        bne LVScan
        
        ;sta WSYNC   ;Playfield section 
	;lda #255
       ; sta PF0
       ; lda #135
       ; sta PF1
       ; lda #135
       ;	sta PF2
       ; lda #2
       ; sta COLUBK
       ; ldy #255
       ; sty COLUPF
      ;  clc 


LVOver
	sta WSYNC 
       ; dex 
       ; bne LVOver
       ; dec BGColor 
        ;jmp NextFrame

; Cat-head graphics data 
Frame0 
      .byte #0; zero padding, also clears register 
      .byte #%00111100;$AE 
      .byte #%01000010;$AE 
      .byte #%11100111;$AE 
      .byte #%11111111;$AC 
      .byte #%10011001;$8E 
      .byte #%01111110;$8E 
      .byte #%11000011;$98 
      .byte #%10000001;$98 
; Cat-head color data 
ColorFrame0 
      .byte #0; unused (for now) 
      .byte #$AA; 
      .byte #$AC; 
      .byte #$AB; 
      .byte #$AC; 
      .byte #$8E; 
      .byte #$8E; 
      .byte #$98; 
      .byte #$94;
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Epilogue

	org $fffc
        .word Start	; reset vector
        .word Start	; BRK vector

(this was kind of a hybrid of me messing around with some early examples of how to do things)

Share this post


Link to post
Share on other sites
Posted (edited)

Try using

 

#5 instead of $5, which is a memory address , a register I think and is probably 0 

 

Edited by easmith

Share this post


Link to post
Share on other sites

 Just started so it may be a simple answer, but something in that book has me confused.

 

In the book the example puts the vertical blank first , then the vertical sync.  This seems backwards to me.

 

From the example on 8bitworkshop.com , the example called 5. Painting on the CRT:

 

NextFrame
; Enable VBLANK (disable output)
    lda #2
        sta VBLANK
; At the beginning of the frame we set the VSYNC bit...
    lda #2
    sta VSYNC
; And hold it on for 3 scanlines...
    sta WSYNC
    sta WSYNC
    sta WSYNC
; Now we turn VSYNC off.
    lda #0
    sta VSYNC

; Now we need 37 lines of VBLANK...
    ldx #37
LVBlank    sta WSYNC    ; accessing WSYNC stops the CPU until next scanline
    dex        ; decrement X
    bne LVBlank    ; loop until X == 0

; Re-enable output (disable VBLANK)
    lda #0
        sta VBLANK
; 192 scanlines are visible
; We'll draw some rainbows
    ldx #192
    lda BGColor    ; load the background color out of RAM
ScanLoop
    adc #1        ; add 1 to the current background color in A
    sta COLUBK    ; set the background color
    sta WSYNC    ; WSYNC doesn't care what value is stored
    dex
    bne ScanLoop

; Enable VBLANK again
    lda #2
        sta VBLANK
; 30 lines of overscan to complete the frame
    ldx #30
LVOver    sta WSYNC
    dex
    bne LVOver

 

 

 

Would not this have been correct with VSYNC first?

NextFrame

; At the beginning of the frame we set the VSYNC bit...
    lda #2
    sta VSYNC
; And hold it on for 3 scanlines...
    sta WSYNC
    sta WSYNC
    sta WSYNC
; Now we turn VSYNC off.
    lda #0
    sta VSYNC

; Now we need 37 lines of VBLANK...
; Enable VBLANK (disable output)
    lda #2
        sta VBLANK
     ldx #37
LVBlank    sta WSYNC    ; accessing WSYNC stops the CPU until next scanline
    dex        ; decrement X
    bne LVBlank    ; loop until X == 0

; Re-enable output (disable VBLANK)
    lda #0
        sta VBLANK
; 192 scanlines are visible
; We'll draw some rainbows
    ldx #192
    lda BGColor    ; load the background color out of RAM
ScanLoop
    adc #1        ; add 1 to the current background color in A
    sta COLUBK    ; set the background color
    sta WSYNC    ; WSYNC doesn't care what value is stored
    dex
    bne ScanLoop

; Enable VBLANK again
    lda #2
        sta VBLANK
; 30 lines of overscan to complete the frame
    ldx #30
LVOver    sta WSYNC
    dex
    bne LVOver

 

 

Share this post


Link to post
Share on other sites
22 hours ago, easmith said:

Try using

 

#5 instead of $5, which is a memory address , a register I think and is probably 0 

 

Thanks, but no, that didn’t change anything. In fact I believe I originally had it that way but started messing around, sorry for the confusion.

Share this post


Link to post
Share on other sites
16 hours ago, SavedByZero said:

Thanks, but no, that didn’t change anything. In fact I believe I originally had it that way but started messing around, sorry for the confusion.

     

  You were missing some things in what you posted:

the  seg.variables  and seg.code definitions.  Also , you had your Overscan and VBlank  at same time .

 

  I added the use of timers for vblank and overscan .  This should work 

 

**********************************************************************

    processor 6502
        include "vcs.h"
        include "macro.h"
        seg.u variables
        org $80

YPos     .byte  

 

        seg code
        org $f000

BGColor equ $81
counter equ 0
SpriteHeight equ $9
TooLow equ $5
; Cat-head graphics data 
Frame0 
      .byte #0; zero padding, also clears register 
      .byte #%00111100;$AE 
      .byte #%01000010;$AE 
      .byte #%11100111;$AE 
      .byte #%11111111;$AC 
      .byte #%10011001;$8E 
      .byte #%01111110;$8E 
      .byte #%11000011;$98 
      .byte #%10000001;$98 
; Cat-head color data 
ColorFrame0 
      .byte #0; unused (for now) 
      .byte #$AA; 
      .byte #$AC; 
      .byte #$AB; 
      .byte #$AC; 
      .byte #$8E; 
      .byte #$8E; 
      .byte #$98; 
      .byte #$94;

    
Start
       CLEAN_START
NextFrame
       
        lda #2
        
        sta VSYNC
       sta WSYNC
        sta WSYNC
        sta WSYNC
        
        
        ldx #49      
        stx TIM64T 
          lda #0
        sta VSYNC

LVBlank
        
       lda INTIM       
        bne LVBlank 
        lda #0 
        sta VBLANK  
             
        ldx #192
        ;ldy counter
        lda  #5
         sta YPos
    
LVScan 
      txa 
        sec 
        sbc YPos 
        cmp #9
        bcc InSprite 
        lda #0;
InSprite
       tay
        lda Frame0,y
        sta WSYNC
        sta GRP0
        lda ColorFrame0,y
CUT
    sta COLUP0        
        dex 
        bne LVScan
        
        


LVOver
    
OverScan                            ;start Overscan
   lda #2      
   sta VBLANK         
   lda #32     
   sta TIM64T  

OSwait
       lda INTIM         
       bne OSwait              ; check for end of overscan
       sta CXCLR
       jmp NextFrame

     

 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Epilogue

    org $fffc
        .word Start    ; reset vector
        .word Start    ; BRK vector

Share this post


Link to post
Share on other sites
On 7/23/2019 at 1:41 PM, polyex said:

 Just started so it may be a simple answer, but something in that book has me confused.

 

In the book the example puts the vertical blank first , then the vertical sync.  This seems backwards to me.

 

From the example on 8bitworkshop.com , the example called 5. Painting on the CRT:

 

NextFrame
; Enable VBLANK (disable output)
    lda #2
        sta VBLANK
; At the beginning of the frame we set the VSYNC bit...
    lda #2
    sta VSYNC
; And hold it on for 3 scanlines...
    sta WSYNC
    sta WSYNC
    sta WSYNC
; Now we turn VSYNC off.
    lda #0
    sta VSYNC

; Now we need 37 lines of VBLANK...
    ldx #37
LVBlank    sta WSYNC    ; accessing WSYNC stops the CPU until next scanline
    dex        ; decrement X
    bne LVBlank    ; loop until X == 0

; Re-enable output (disable VBLANK)
    lda #0
        sta VBLANK
; 192 scanlines are visible
; We'll draw some rainbows
    ldx #192
    lda BGColor    ; load the background color out of RAM
ScanLoop
    adc #1        ; add 1 to the current background color in A
    sta COLUBK    ; set the background color
    sta WSYNC    ; WSYNC doesn't care what value is stored
    dex
    bne ScanLoop

; Enable VBLANK again
    lda #2
        sta VBLANK
; 30 lines of overscan to complete the frame
    ldx #30
LVOver    sta WSYNC
    dex
    bne LVOver

 

 

 

Would not this have been correct with VSYNC first?

NextFrame

; At the beginning of the frame we set the VSYNC bit...
    lda #2
    sta VSYNC
; And hold it on for 3 scanlines...
    sta WSYNC
    sta WSYNC
    sta WSYNC
; Now we turn VSYNC off.
    lda #0
    sta VSYNC

; Now we need 37 lines of VBLANK...
; Enable VBLANK (disable output)
    lda #2
        sta VBLANK
     ldx #37
LVBlank    sta WSYNC    ; accessing WSYNC stops the CPU until next scanline
    dex        ; decrement X
    bne LVBlank    ; loop until X == 0

; Re-enable output (disable VBLANK)
    lda #0
        sta VBLANK
; 192 scanlines are visible
; We'll draw some rainbows
    ldx #192
    lda BGColor    ; load the background color out of RAM
ScanLoop
    adc #1        ; add 1 to the current background color in A
    sta COLUBK    ; set the background color
    sta WSYNC    ; WSYNC doesn't care what value is stored
    dex
    bne ScanLoop

; Enable VBLANK again
    lda #2
        sta VBLANK
; 30 lines of overscan to complete the frame
    ldx #30
LVOver    sta WSYNC
    dex
    bne LVOver

 

 

 

I don't think you need the

lda #2

 sta VBLANK 

 

at all before you draw your screen if you have it at the bottom of your frame loop for overscan .  It remains #2

until you write the #0 after VBLANK. 

 

 

Share this post


Link to post
Share on other sites
7 minutes ago, easmith said:

     

  You were missing some things in what you posted:

the  seg.variables  and seg.code definitions.  Also , you had your Overscan and VBlank  at same time .

 

  I added the use of timers for vblank and overscan .  This should work 

 

**********************************************************************

    processor 6502
        include "vcs.h"
        include "macro.h"
        seg.u variables
        org $80

YPos     .byte  

 

        seg code
        org $f000

BGColor equ $81
counter equ 0
SpriteHeight equ $9
TooLow equ $5
; Cat-head graphics data 
Frame0 
      .byte #0; zero padding, also clears register 
      .byte #%00111100;$AE 
      .byte #%01000010;$AE 
      .byte #%11100111;$AE 
      .byte #%11111111;$AC 
      .byte #%10011001;$8E 
      .byte #%01111110;$8E 
      .byte #%11000011;$98 
      .byte #%10000001;$98 
; Cat-head color data 
ColorFrame0 
      .byte #0; unused (for now) 
      .byte #$AA; 
      .byte #$AC; 
      .byte #$AB; 
      .byte #$AC; 
      .byte #$8E; 
      .byte #$8E; 
      .byte #$98; 
      .byte #$94;

    
Start
       CLEAN_START
NextFrame
       
        lda #2
        
        sta VSYNC
       sta WSYNC
        sta WSYNC
        sta WSYNC
        
        
        ldx #49      
        stx TIM64T 
          lda #0
        sta VSYNC

LVBlank
        
       lda INTIM       
        bne LVBlank 
        lda #0 
        sta VBLANK  
             
        ldx #192
        ;ldy counter
        lda  #5
         sta YPos
    
LVScan 
      txa 
        sec 
        sbc YPos 
        cmp #9
        bcc InSprite 
        lda #0;
InSprite
       tay
        lda Frame0,y
        sta WSYNC
        sta GRP0
        lda ColorFrame0,y
CUT
    sta COLUP0        
        dex 
        bne LVScan
        
        


LVOver
    
OverScan                            ;start Overscan
   lda #2      
   sta VBLANK         
   lda #32     
   sta TIM64T  

OSwait
       lda INTIM         
       bne OSwait              ; check for end of overscan
       sta CXCLR
       jmp NextFrame

     

 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Epilogue

    org $fffc
        .word Start    ; reset vector
        .word Start    ; BRK vector

I will try that, although those header files that I'm missing aren't things I have.  They're just....there, in the code sample header that I used as a springboard for my own code.  This book is confusing; it doesn't tell me when I'm supposed to be writing new files from sratch vs. just reading the examples to get a feel for them, it doesn't consistently give chapter samples (the chapter I'm trying to recreate the sample for is missing one on the website, where the surrounding chapters both have code samples), and it doesn't explain the header files included that I see in the samples, at least not yet.

Share this post


Link to post
Share on other sites
Posted (edited)
47 minutes ago, SavedByZero said:

I will try that, although those header files that I'm missing aren't things I have.  They're just....there, in the code sample header that I used as a springboard for my own code.  This book is confusing; it doesn't tell me when I'm supposed to be writing new files from sratch vs. just reading the examples to get a feel for them, it doesn't consistently give chapter samples (the chapter I'm trying to recreate the sample for is missing one on the website, where the surrounding chapters both have code samples), and it doesn't explain the header files included that I see in the samples, at least not yet.

Yes I know.  What is hard to come by, and is frustrating , are complete examples of code in the context of a larger working program .   

 

You just have to ask questions.  Some experienced programmer will answer. I suggest you start  new topic in the 2600  Programming forum for each different technical issue you encounter , so that it gets eyeballs. There are people who are very knowledgeable ( way more than me ).  Soon enough you will have a  basic template that covers all the the basics that can be duplicated for the most part from program to program .

 

 

Edited by easmith

Share this post


Link to post
Share on other sites
Posted (edited)
54 minutes ago, easmith said:

Yes I know.  What is hard to come by, and is frustrating , are complete examples of code in the context of a larger working program .   

 

You just have to ask questions.  Some experienced programmer will answer. I suggest you start  new topic in the 2600  Programming forum for each different technical issue you encounter , so that it gets eyeballs. There are people who are very knowledgeable ( way more than me ).  Soon enough you will have a  basic template that covers all the the basics that can be duplicated for the most part from program to program .

 

 

Will do, thanks! By the way, I got this code straight from the book:

lda #2 ; same as binary #%00000010 
sta VBLANK; turn on VBLANK 
sta VSYNC; turn on VSYNC Now that we’re emitting a VSYNC signal, we need to hold it for three scanlines. We strobe this register (i.e., write to it) to make it halt the CPU until the next scanline begins. If we do this three times, the TIA will have generated our three lines of VSYNC signal and can then turn off the VSYNC bit: 
sta WSYNC; first scanline 
sta WSYNC; second scanline 
sta WSYNC; third scanline 
lda #0 
sta VSYNC; turn off VSYNC

 

Edited by SavedByZero

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...