Jump to content

Photo

Begginer questions to get me started


9 replies to this topic

#1 awsm OFFLINE  

awsm

    Combat Commando

  • 4 posts
  • Location:Berlin

Posted Tue May 31, 2016 3:30 AM

Hello everybody,
I'm new here so first of all thanks for accepting me to AtariAge. I hope that over time I can give back more than I initially might take. I'm also new to VCS development, while having some experience doing 6502 assembly on the Commodore C64 ( http://www.awsm.de).
 
I followed the excellent tutorial from Kirk Israel ( http://alienbill.com.../101/index.html) and now I'm looking forward to the next steps. I must admit that it was an off and on again job, so I clearly don't remember every single information given, but will give it a second read again.
 
Anyway, I took the code and tried to make it my own by converting it to my coding habits (mostly syntax). I came across some issues I'd like to get your advice on. 
 
 
1. Is there an easy way to show changes visually?
With the luxury of memory mapped IO on the Commodore 64, if I want to track e.g. if a specific section of my code got executed, I could simply to either
 
INC $0400 (increment the first char on the top left of the screen) or
INC $d020 (increment the border color)
 
but I can't seem to do that with a simple
 
INC COLUBK, right?
 
 
2. Is there something like a best practice template for the code?
On the 64, live was easy. Whenever you want to change something of the screen, just update the screen memory. No beam racing. Now with my first changes to Kirk's tutorial script, I seem to be running into timing issues already, having "just" added a few lines of code. I know I need to understand and learn better how to manage cycles and when I got enough time to do some calculations. I'm just wondering if there's something like a template that some people find helpful to get started with a good code structure.
 
 
3. Are JSR and JMP bad coding practice on the VCS?
This might sound silly, but better ask before falling into a pit I can't climb out of. Kirk's tutorial avoids subroutines and code jumps, it's basically one big chunk of code with some conditional branching. On the 64, I'm used to setting up my code in different files, build small libs even, so there's some JSR and RTS to keep the main asm file structured. Since memory is so limited I guess every byte counts twice, so what's your take on this?
 
 
4. Which resources (links, tutorial, books) would you consider "must read"?
Surprisingly, I seem to find far less on the topic of VCS development than I anticipated, and quite a bit of what I find is quite old (which is fine since it's safe to assume VCS hardware didn't change too much since 1977...). Any advice will be helpful here.
 
 
Finally, I would be thankful of anybody more experienced than me (that would be all of you probably ;) ) to check out my code and comment on it. ANY advice is appreciated really, there's no pride to hurt if you're starting at square one... :D
 
Specifically, you'll see that after adding a second player (the rectangle), a big portion of the left screen seems to be unaccessible to the sprites. My idea is that I simply lack the time to draw everything, but then again it could be something really different. In the end, that listing is just a quick copy and paste version of the tutorial.
 
The source and bin are included in the attached ZIP.
 
Thank you for reading through this on hopefully not rolling your eyes already ;)
Enjoy the day,
awsm
 
 
screen.png

Attached Files



#2 Gip-Gip OFFLINE  

Gip-Gip

    Chopper Commander

  • 161 posts
  • Location:Georgia, US

Posted Tue May 31, 2016 7:34 AM

1.

 

Yes, you can. You just have to be mindful of when the frame is drawn

 

Nope, it's write only(thanks for reminding me, RevEng!)

 

2.

 

Most people store all the graphics to RAM, and either make or incorporate a display kernel to draw the stored graphics

 

3.

 

Not always. If you know the amount of time a JMP or JSR will take, it's perfectly safe (and saves space).

 

4..

 

Atari 2600 Programming for Newbies, the Stella Programmer's Guide, and the 6502 Opcode List.

 

5.

It looks like you're using only 1 player sprite(and performing too many calculations).

 

You cannot distribute vcs.h due to crappy licensing, and if you want to distribute the header you'll have to make your own. I recommend licensing your works under one of the many open source licenses, as that clears up a lot of things legally.

 

P.S.

headers belong in include/ not lib/


Edited by Gip-Gip, Tue May 31, 2016 8:37 AM.


#3 RevEng OFFLINE  

RevEng

    River Patroller

  • 4,497 posts
  • Bitnik
  • Location:Canada

Posted Tue May 31, 2016 8:06 AM

1. INC COLUBK doesn't work because COLUBK is a write-only register. If you INC a byte of RAM and stuff it in COLUBK, you'll see what you expect.

2. There's no standard template that everybody uses as such, but certainly there's a common code sections based on which section of frame the beam is in. i.e. visible screen, overscan, vblank (and vsync). Check out my answer to #4 for that. Beyond dealing with different bits of the frame, most VCS games differ greatly from each other in detailed approach. Different resources get read from different sources (ROM/RAM), layout of the resources will be optimized differently for the display kernel, and they don't bother with resources that the particular game doesn't use.

3. Not bad practice, but we use them where appropriate to saving resources. In the middle of the visible-display kernel, forget about it. Otherwise, when it results in overall ROM savings without excessive cycle penalty, sure.

4. Check out Spiceware's Collect series of blogs. They're tutorials that step you through a first program, and answer exactly the sorts of questions you're starting to ask.

#4 awsm OFFLINE  

awsm

    Combat Commando

  • Topic Starter
  • 4 posts
  • Location:Berlin

Posted Tue May 31, 2016 12:34 PM

1. Yes, you can. You just have to be mindful of when the frame is drawn
Nope, it's write only(thanks for reminding me, RevEng!)
1. INC COLUBK doesn't work because COLUBK is a write-only register. If you INC a byte of RAM and stuff it in COLUBK, you'll see what you expect.

 

 

 
Snap! Didn't catch that one, thanks for letting me know.
 
2. Most people store all the graphics to RAM, and either make or incorporate a display kernel to draw the stored graphics

 

 

 
I need to learn more about that then.
 
4. Atari 2600 Programming for Newbies, the Stella Programmer's Guide, and the 6502 Opcode List.

 

 

 
Thanks!

5. It looks like you're using only 1 player sprite(and performing too many calculations).
 

 

 

Really? Hm. Can't spot my error there...
 
You cannot distribute vcs.h due to crappy licensing, and if you want to distribute the header you'll have to make your own. I recommend licensing your works under one of the many open source licenses, as that clears up a lot of things legally.

 

 

 
Wow. Okay. Guess I have to respect that then. Thank you for the heads up

P.S.
headers belong in include/ not lib/

 

 

 
Understood!

2. There's no standard template that everybody uses as such, but certainly there's a common code sections based on which section of frame the beam is in. i.e. visible screen, overscan, vblank (and vsync). Check out my answer to #4 for that. Beyond dealing with different bits of the frame, most VCS games differ greatly from each other in detailed approach. Different resources get read from different sources (ROM/RAM), layout of the resources will be optimized differently for the display kernel, and they don't bother with resources that the particular game doesn't use.
4. Check out Spiceware's Collect series of blogs. They're tutorials that step you through a first program, and answer exactly the sorts of questions you're starting to ask. 

 

 

 
I will make sure to take more time getting familiar with the details and the tutorial provided. Thank you for pointing me to it.


#5 gauauu OFFLINE  

gauauu

    Moonsweeper

  • 250 posts
  • Location:Illinois

Posted Tue May 31, 2016 12:47 PM

 

You cannot distribute vcs.h due to crappy licensing, and if you want to distribute the header you'll have to make your own. I recommend licensing your works under one of the many open source licenses, as that clears up a lot of things legally.

 

 

The copy of vcs.h that I found didn't have a license attached. Do you have further information about this?

 

 

Most people store all the graphics to RAM, and either make or incorporate a display kernel to draw the stored graphics

 

 

Huh. I didn't realize there was a "most".  In my current game, I only store a pointer to the graphics in RAM. Then use an indirect indexed load to pull the right graphics data out of ROM. 


Edited by gauauu, Tue May 31, 2016 12:47 PM.


#6 Gip-Gip OFFLINE  

Gip-Gip

    Chopper Commander

  • 161 posts
  • Location:Georgia, US

Posted Tue May 31, 2016 1:12 PM

 

The copy of vcs.h that I found didn't have a license attached. Do you have further information about this?

 

This is the comment at the top of vcs.h:

 

    ; THIS IS A PRELIMINARY RELEASE OF *THE* "STANDARD" VCS.H
    ; THIS FILE IS EXPLICITLY SUPPORTED AS A DASM-PREFERRED COMPANION FILE
    ; PLEASE DO *NOT* REDISTRIBUTE THIS FILE!

 

 

Huh. I didn't realize there was a "most".  In my current game, I only store a pointer to the graphics in RAM. Then use an indirect indexed load to pull the right graphics data out of ROM. 

 

I had the idea of RAM graphics in mind. Plus, accessing RAM and ROM is the same, it's only slightly different ;)

 

Anyways, going by my definition of most, I would assume most Atari kernels go by this structure:

 

VBLANK(calculations)

IMAGE(display kernel)

OVERSCAN(more calculations)

 

and just for further reference, a display kernel is supposed to fetch data from either RAM or ROM and draw it to the screen. How it does so(and how the data is interpreted) is entirely subjective.


Edited by Gip-Gip, Tue May 31, 2016 1:13 PM.


#7 SpiceWare ONLINE  

SpiceWare

    Quadrunner

  • 11,061 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Tue May 31, 2016 3:22 PM

I will make sure to take more time getting familiar with the details and the tutorial provided. Thank you for pointing me to it.

 
 
Do note that the blog lists the entries newest first, so you'll have to go to the bottom of (currently) page 2 of the Collect blog entries to start the tutorial.  As to your questions:
 
1 - yeah, the read-only and write-only TIA registers can throw you for a loop.  Step 3 - Score & Timer display contains my answer, implement the score display early on and use it to display diagnostic info.
 
2 - best practice is to put cycle counts in your Kernel.  I don't recall if I pointed it out in the blog entries or not, but I do so in the source - I expect you to review the source for each entry as I put in way more comments than I normally would, such as:
;===============================================================================
; Kernel
; ------
; here we update the registers in TIA, the video chip, scanline by scanline
; in order to generate what the player sees.
;
; Timing is crucial in the kernel, so we need to count the cycles.  You may
; use your own method of counting cycles, this is how I do it:
;       instruction     ;xx yy - comment
;   xx = cycles instruction will take
;   yy = cumulative cycle count after instruction runs
;   comment = what is going on.  Some instructions have special notation:
;       @aa-bb where aa and bb are numbers.  These are used to denote that the
;           instruction MUST be done within a range of cycles.  This is especially
;           true of updating the playfield where you need to update the register
;           twice on a scanline if you want the left and right side of the screen
;           to show different images.  If aa > bb that means the instruction can
;           be executed on the prior scanline on or after cycle aa.
;       (a b) where a and b are numbers.  These are used for branches to show
;           the cycles and cycle count if the branch is taken.
;
; The following is used to denote when a new scanline starts:
;---------------------------------------
;
;===============================================================================
Kernel:            
        sta WSYNC       ; Wait for SYNC (halts CPU until end of scanline)
;---------------------------------------                
        lda INTIM       ; 4  4 - check the timer
        bne Kernel      ; 2  6 - (3 7) Branch if its Not Equal to 0
    ; turn on the display
        sta VBLANK      ; 3  9 - Accumulator D1=0, turns off Vertical Blank signal (image output on)
        ldx #5          ; 2 11 - use X as the loop counter for ScoreLoop

    ; first thing we draw is the score.  Score is drawn using only PF1 of the
    ; playfield.  The playfield is set for in repeat mode, and SCORE is turned
    ; on so the left and right sides take on the colors of player0 and player1.
    ; To get here we can fall thru from above (cycle 11) OR loop back from below
    ; (cycle 43). We start the cycle count from the worst case scenario
ScoreLoop:              ;   43 - cycle after bpl ScoreLoop
        ldy DigitTens   ; 3 46 - get the tens digit offset for the Score
        lda DigitGfx,y  ; 5 51 -   use it to load the digit graphics
        and #$F0        ; 2 53 -   remove the graphics for the ones digit
        sta ScoreGfx    ; 3 56 -   and save it
        ldy DigitOnes   ; 3 59 - get the ones digit offset for the Score
        lda DigitGfx,y  ; 5 64 -   use it to load the digit graphics
        and #$0F        ; 2 66 -   remove the graphics for the tens digit
        ora ScoreGfx    ; 3 69 -   merge with the tens digit graphics
        sta ScoreGfx    ; 3 72 -   and save it
        sta WSYNC       ; 3 75 - wait for end of scanline
;---------------------------------------        
        sta PF1         ; 3  3 - @66-28, update playfield for Score display
...
 
3 - JSR and JMP are fine, though keep mind that the stack starts at the end of your 128 bytes of RAM so nested JSRs could collide with your RAM usage if you're not careful.

4 - covered in the blog series.

#8 awsm OFFLINE  

awsm

    Combat Commando

  • Topic Starter
  • 4 posts
  • Location:Berlin

Posted Wed Jun 1, 2016 1:13 AM

Thank you SpiceWare, I've started the tutorial. Excellent work, well written and full of valuable information.



#9 BNE Jeff OFFLINE  

BNE Jeff

    Moonsweeper

  • 285 posts
  • Location:Virginia, USA

Posted Sat Jun 4, 2016 6:48 AM

I think you're taking the right path..  The Kirk Isreal tutorial is so simple and has the absolute beginner's perspective.  Easy to grasp and alter.  He leaves a lot of things out though. He had to, I think, just to keep it simple.  You've already run into the biggest thing he left out- the two line kernel. 

 

Darrell Spice's Collect series is an excellent second step.  Still for beginners, but teaches good, efficient form, a required skill for Atari.  There is a lot more content in that series so it takes longer.  You have some programming experience, so you should be able to get through it quicker than me.  Did you get the Stella manual? It will be an easy read for you.

 

Hey look!  I figured out how to add screen shots!  Its what I turned "Thin Red Line" into.  I'd add my butchering of "Collect" but its still too much of an embarrassment.

Attached Thumbnails

  • Screen shot BS.jpg

Edited by BNE Jeff, Sat Jun 4, 2016 6:53 AM.


#10 awsm OFFLINE  

awsm

    Combat Commando

  • Topic Starter
  • 4 posts
  • Location:Berlin

Posted Mon Jun 6, 2016 3:51 PM

Thank you Jeff for taking the time and giving me really good advice on how to progress from here. 

I'm now at step 3 (the score and timers) and it really takes me a long time to understand most of it. Probably, because the code - at least for me - is so cleverly written. It feels like unzipping the code in my brain.






0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users