Jump to content
sunofman

New language to program Atari 2600

Recommended Posts

Hi!

 

This is my first post here.

​I have created a new computer language, that makes 6502 code. ​Before I release it, it would like to test to make a Atari 2600 program.

​But as I don't have time to learn all about 2600 now, I wounder if there is a assembly program I can translate as a example. After that maybe someone would like to test it for writing their own programs. And I can provide the code for that program that i translate, as a programming example.

 

Does anyone know of some suitable assembly code for this? I worst case I could take some machine code, and translate that.

​Any ideas? And where can I find info about the used fileformat for Atari 2600 emulators?

 

 

  • Like 1

Share this post


Link to post
Share on other sites

But as I don't have time to learn all about 2600 now

The Atari is unlike any other system in that the 6507 (6502 compatible) updates the hardware in real time to draw the screen scanline by scanline. Unless you take the time to learn how that works then your new computer language will be worthless for 2600 projects.

 

I wrote a blog series, Collect that goes over what's involved. The blog lists the entries newest first, so go to the bottom of the 2nd page to start with Let's Make a Game!

Share this post


Link to post
Share on other sites

The Atari is unlike any other system in that the 6507 (6502 compatible) updates the hardware in real time to draw the screen scanline by scanline. Unless you take the time to learn how that works then your new computer language will be worthless for 2600 projects.

 

I wrote a blog series, Collect that goes over what's involved. The blog lists the entries newest first, so go to the bottom of the 2nd page to start with Let's Make a Game!

 

 

Well you don't know if what you say is true. I have written my language, and I know what I have done.

 

I asked if there is any assembly code that is suitable. If a normal assembler can't be used, then thats ok, I will fix that. My language isn't based on anyone else assembler or C compiler or anything like that. It is a language made from scratch. It translates to 6502 directly.

 

And 6507 has the same OP codes as 6502, hasn't it? Even if it doesn't than that could be fixed quite easily. And the limited adress space for 6507 isn't a problem. My language does not use a runtime library.

 

And if some code need to be 100% exact, than that can be fixed also, if I have machinecode to go after.

 

To as I alread said. I can translte machine code, in worst case.

 

So if there is a short binary file that is suitable, that would be okey also.

Share this post


Link to post
Share on other sites

The Atari is unlike any other system in that the 6507 (6502 compatible) updates the hardware in real time to draw the screen scanline by scanline. Unless you take the time to learn how that works then your new computer language will be worthless for 2600 projects.

 

I wrote a blog series, Collect that goes over what's involved. The blog lists the entries newest first, so go to the bottom of the 2nd page to start with Let's Make a Game!

 

 

Well, another tought. If I have your permission SpiceWare to use your code, I could translate that to my language.

 

Are you okay with that?

Share this post


Link to post
Share on other sites

You can find this where Darrell said to look.

 

; colorful

; Darrell Spice, Jr

; November 5, 2013

;

; Simple 2600 program that shows off moving bands of colors

;

; compile using DASM

; dasm colorful.asm -f3 -v0 -scolorful.sym -lcolorful.lst -ocolorful.bin

 

;========================================

; Initialize DASM

;========================================

 

; DASM supports a number of processors, this line tells DASM the code

; is for the 6502 CPU. The Atari has a 6507, which is 6502 with an 8K

; address space and no interrupt lines.

PROCESSOR 6502

 

; vcs.h contains the standard definitions for TIA and RIOT registers

include vcs.h

 

; macro.h contains commonly used routines which aid in coding

include macro.h

 

 

;========================================

; Define RAM Usage

;========================================

 

; define a segment for variables

; .U means uninitialized, does not end up in ROM

SEG.U VARS

 

; RAM starts at $80

ORG $80

 

; holds background color for first scanline of frame

BackgroundColor: ds 1 ; stored in $80

 

; holds playfield color for first scanline of frame

PlayfieldColor: ds 1 ; stored in $81

 

; holds # of scanlines left for the kernel to draw

LineCount: ds 1 ; stored in $82

 

 

;========================================

; Define Start of Cartridge

;========================================

 

; define a segment for code

SEG CODE

 

; ROM starts at $F000

ORG $F000

 

 

;========================================

; Initialize Atari

;========================================

 

InitSystem:

; CLEAN_START is a macro found in macro.h

; it sets all RAM, TIA registers

; and CPU registers to 0

CLEAN_START

 

; set playfield to show vertical stripes

lda #$AA

sta PF0

sta PF2

lda #$55

sta PF1

 

 

;========================================

; Sync Signal

;========================================

 

VerticalSync:

lda #2 ; LoaD Accumulator with 2

sta WSYNC ; STore Accumulator to WSYNC, any value halts CPU until start of next scanline

sta VSYNC ; Accumulator D1=1, turns on Vertical Sync signal

sta VBLANK ; Accumulator D1=1, turns on Vertical Blank signal (image output off)

lda #47

sta TIM64T ; set timer for end of Vertical Blank

sta WSYNC ; 1st scanline of VSYNC

sta WSYNC ; 2nd scanline of VSYNC

lda #0 ; LoaD Accumulator with 0

sta WSYNC ; 3rd scanline of VSYNC

sta VSYNC ; Accumulator D1=0, turns off Vertical Sync signal

 

 

;========================================

; Vertical Blank

;========================================

 

VerticalBlank:

;==========================

; game logic starts here

;==========================

 

; update background color for first scanline of this frame

inc BackgroundColor

 

; update playfield color for first scanline this frame

dec PlayfieldColor

lda #199

sta LineCount

 

;==========================

; game logic ends here

;==========================

 

VBwait:

sta WSYNC

bit TIMINT

bpl VBwait ; loop until the timer ends

 

 

;========================================

; Kernel

;========================================

 

; turn on video output

sta WSYNC

lda #0

sta VBLANK

sta COLUBK ; color first scanline black

sta COLUPF ; color first scanline black

ldx BackgroundColor

ldy PlayfieldColor

 

; draw the screen

KernelLoop:

sta WSYNC ; wait for start of next scanline

stx COLUBK ; change background color for current scanline

sty COLUPF ; change playfield color for current scanline

inx ; increase X so next scanline has a different background color

iny ; increase Y so next scanline has a different playfield color

dec LineCount ; decrease the line count

bne KernelLoop ; if we didn't hit 0, then draw another scanline

 

 

;========================================

; Overscan

;========================================

 

; done drawing the screen

OverScan:

sta WSYNC ; Wait for SYNC (start of next scanline)

lda #2 ; LoaD Accumulator with 2

sta VBLANK ; STore Accumulator to VBLANK, D1=1 turns image output off

lda #23

sta TIM64T

 

;===================================

; additional game logic goes here

;===================================

 

OSwait:

sta WSYNC

bit TIMINT

bpl OSwait ; loop until the timer ends

 

jmp VerticalSync ; start the next frame

 

 

;========================================

; Define End of Cartridge

;========================================

 

ORG $FFFA ; set address to 6507 Interrupt Vectors

.WORD InitSystem ; NMI

.WORD InitSystem ; RESET

.WORD InitSystem ; IRQ

Edited by SIO2

Share this post


Link to post
Share on other sites

Welcome to the forum.

 

All the Atari games are small. You could probably use any game, but collect is probably the best choice because it is one of the most commented source files you're going to find.

 

I'm curious to see what new features your language will bring. Could you give an overview of what it supports and what it gains over assembler?

Share this post


Link to post
Share on other sites

Welcome to the forum.

 

All the Atari games are small. You could probably use any game, but collect is probably the best choice because it is one of the most commented source files you're going to find.

 

I'm curious to see what new features your language will bring. Could you give an overview of what it supports and what it gains over assembler?

 

 

Thanks!

Yes, I could give a overview, and answer questions.

 

Well it support structured code. And it's a lot easier than assembly. And it's a good language for someone that is familiar with assembly.

 

And programs would be a lot smaller than assembly programs, without loosing functionality.

 

My brother translated a C64 assembly program with raster graphics. And that program started on the first try, without rewrite. And that was his first program in that language. So it's extremely easy language if you know assembly. And it's easy to convert assembly programs to this language.

 

So in some ways it's easier than C coding, and easier than assembly. It's more low level than C. And programs are more compact than c code, and assembly code.

 

And I could also integrates specific functionality in this language, so It's also more hi level than C. A bit like basic, with performance almost almost on pair with assembly. So if there is corner cases, or special syntax for easier programming, than I could make that if people would use it.

 

It is also easy to write timing specific code. I could write a table, how much data and cycles everything takes later if someone is interested.

Share this post


Link to post
Share on other sites

Well you don't know if what you say is true. I have written my language, and I know what I have done.

I've been coding for the 6502 since the early 80s. I learned machine language by hand assembling code (as I didn't have an assembler), putting the results into data statements, poking it into memory, then running it on my Vic 20.

 

I became involved with Stella in the mid 90s when I ported it to run on OS/2.

 

Two of my 2600 homebrews are in the best sellers list.

 

etc. So yes, I'm fairly familiar with the inner workings of the 2600 :)

 

I asked if there is any assembly code that is suitable.

Feel free to use Collect for your tests. As ZackAttack points out, you're unlikely to find anything as commented as that, I wrote it specifically to be a tutorial so put in way more comments that I usually would. The code SIO2 pointed out is in colorful.zip

 

And 6507 has the same OP codes as 6502, hasn't it?

Yes.

  • Like 2

Share this post


Link to post
Share on other sites

Sounds promising. My biggest complaint with assembly is how difficult it is to fail at compile time. Well that and the massive amounts of macros needed to make decent code.

 

The Atari is very resource constrained. You may need to include either the ability to link with assembled binaries or inline assembly for the most timing critical parts. Typically this would be the display kernel(s).

Share this post


Link to post
Share on other sites

I could translate some code segments, starting with this...

 

;========================================

; Define RAM Usage
;========================================

; define a segment for variables
; .U means uninitialized, does not end up in ROM
SEG.U VARS

; RAM starts at $80
ORG $80

; holds background color for first scanline of frame
BackgroundColor: ds 1 ; stored in $80

; holds playfield color for first scanline of frame
PlayfieldColor: ds 1 ; stored in $81

; holds # of scanlines left for the kernel to draw
LineCount: ds 1 ; stored in $82

 

 

--------------------------------------------------

 

That code would look like this...

 

< ========================================

Define RAM Usage
======================================== >

 

80: < RAM starts at $80 >

BackgroundColor:80 < holds background color for first scanline of frame >

PlayfieldColor:81 < holds playfield color for first scanline of frame >

LineCount:82 < holds # of scanlines left for the kernel to draw >

Share this post


Link to post
Share on other sites

I could translate some code segments, starting with this...

 

;========================================

; Define RAM Usage

;========================================

 

; define a segment for variables

; .U means uninitialized, does not end up in ROM

SEG.U VARS

 

; RAM starts at $80

ORG $80

 

; holds background color for first scanline of frame

BackgroundColor: ds 1 ; stored in $80

 

; holds playfield color for first scanline of frame

PlayfieldColor: ds 1 ; stored in $81

 

; holds # of scanlines left for the kernel to draw

LineCount: ds 1 ; stored in $82

 

 

--------------------------------------------------

 

That code would look like this...

 

< ========================================

Define RAM Usage

======================================== >

 

80: < RAM starts at $80 >

BackgroundColor:80 < holds background color for first scanline of frame >

PlayfieldColor:81 < holds playfield color for first scanline of frame >

LineCount:82 < holds # of scanlines left for the kernel to draw >

 

Well it would be written even shorter ...

 

< ========================================

Define RAM Usage

======================================== >

BackgroundColor:80 < holds background color for first scanline of frame >

PlayfieldColor:81 < holds playfield color for first scanline of frame >

LineCount:82 < holds # of scanlines left for the kernel to draw >

 

 

 

...that would be more correct code using my language. You don't need to set origin in this case.

Share this post


Link to post
Share on other sites

Here is another translation of this assembly...

 

;========================================
; Define Start of Cartridge
;========================================

; define a segment for code
SEG CODE

; ROM starts at $F000
ORG $F000

 

 

-----------------

 

to this code...

 

;========================================

; Define Start of Cartridge
;========================================

F000: < ROM starts at $F000 >

Share this post


Link to post
Share on other sites

;========================================
; Sync Signal
;========================================

VerticalSync:
lda #2 ; LoaD Accumulator with 2
sta WSYNC ; STore Accumulator to WSYNC, any value halts CPU until start of next scanline
sta VSYNC ; Accumulator D1=1, turns on Vertical Sync signal
sta VBLANK ; Accumulator D1=1, turns on Vertical Blank signal (image output off)
lda #47
sta TIM64T ; set timer for end of Vertical Blank
sta WSYNC ; 1st scanline of VSYNC
sta WSYNC ; 2nd scanline of VSYNC
lda #0 ; LoaD Accumulator with 0
sta WSYNC ; 3rd scanline of VSYNC
sta VSYNC ; Accumulator D1=0, turns off Vertical Sync signal

 

 

-------

 

That would be translated to...

 

< =======================================

Sync Signal
======================================= >

 

VerticalSync:

#2 =WSYNC =VSYNC =VBLANC < turn on Vertical Sync and Vertical Blanc signal >

#47.0 =TIM64T =WSYNC =WSYNC < first and second scanline of VSYNC >

#0 =WSYNC =VSYNC < third scanline, and turn of Vertical Sync signal >

Share this post


Link to post
Share on other sites

Sounds promising. My biggest complaint with assembly is how difficult it is to fail at compile time. Well that and the massive amounts of macros needed to make decent code.

 

The Atari is very resource constrained. You may need to include either the ability to link with assembled binaries or inline assembly for the most timing critical parts. Typically this would be the display kernel(s).

 

 

What type of macros is needed to make decent code for 2600 and why?

 

Well you can inline assembly and binary data and mashine code in this language.

Share this post


Link to post
Share on other sites

OK!

 

Now I have managed to compile a binary identical program to Collect in my language.

 

But there is some minor things that I have to fix, before it's usable as a Language for Atari 2600. I had to patch the program with some in-line machine code.

 

I don't now how the code works, but I guess I will learn something along the way.

 

Even if I don't don't know how Atari 2600 works, it will still be useful for 2600 projects.

If I can use it without knowing anything, maybe it will be useful for someone who actually know how to program the Atari 2600.

  • Like 1

Share this post


Link to post
Share on other sites

OK!

 

Now I have managed to compile a binary identical program to Collect in my language.

 

But there is some minor things that I have to fix, before it's usable as a Language for Atari 2600. I had to patch the program with some in-line machine code.

 

I don't now how the code works, but I guess I will learn something along the way.

 

Even if I don't don't know how Atari 2600 works, it will still be useful for 2600 projects.

If I can use it without knowing anything, maybe it will be useful for someone who actually know how to program the Atari 2600.

 

The meat of any 2600 project is the graphics kernel. Most of the time is taken up by manually drawing the screen. So, without that sorted out there's little benefit over straight assembly.

 

That doesn't mean I think your effort are in vain! I just think that maybe another 650x system would be a better fit. Perhaps you could target the NES and use an available graphics/io library.

 

The Atari 2600 already has 2 high level languages (bB and vwBASIC). Besides C you'd be the only game in town for the NES.

  • Like 1

Share this post


Link to post
Share on other sites

 

Does any one know, why the empty part of the ROM file is filled with $FF ?

 

In my ROM generated in my language, the empty part of the ROM is filled with $00 and is fully working in stella.

 

But I can change the empty filling to $FF if it's a problem when writing Atari 2600 programs.

 

Otherwise, that rom is identical to Collect ROM file.

 

At the moment, the program converted to my language is mostly translated to my language. But some instructions is in-line assembly.

And there is one instruction type that is still machine code (relative BEQ and BNE), that should be fixed so it can use my language syntax with 100% efficiency, like it was hand-coded assembly. But I will fix that sooner or later.

 

What is the reason why DASM is used to write Atari 2600 programs? Is there some special functionality in it that is needed?

 

I'm thinking of making a feature to disassemble Atari 2600 roms, and be able to recompile them immediately and start converting and modifying. I already have a disassembler half made. And it can probably be fixed to it uses real names for hardware registers automatically if i spend a little time on it.

Share this post


Link to post
Share on other sites

 

The meat of any 2600 project is the graphics kernel. Most of the time is taken up by manually drawing the screen. So, without that sorted out there's little benefit over straight assembly.

 

That doesn't mean I think your effort are in vain! I just think that maybe another 650x system would be a better fit. Perhaps you could target the NES and use an available graphics/io library.

 

The Atari 2600 already has 2 high level languages (bB and vwBASIC). Besides C you'd be the only game in town for the NES.

 

Ok! what parts is the graphics kernel? I have already converted the Collect program, doesn't that have a graphics kernel. I use the exact the same variable names and label names as the Collect program. What more programs has to be converted to get a full graphics kernel?

Ok thanks for the advise on NES, I will tackle that later. But I will fix Atari 2600 first I guess. I used to play on it back in the early 80s, and later on i played games on c64, vic20 and NES and Lynx. So I will probably fix them also. But I think I will do things chronologically, so maybe Atari 800 is the next stop.

  • Like 1

Share this post


Link to post
Share on other sites

< ========================================

Define RAM Usage

======================================== >

 

BackgroundColor:80 < holds background color for first scanline of frame >

PlayfieldColor:81 < holds playfield color for first scanline of frame >

LineCount:82 < holds # of scanlines left for the kernel to draw >


I would not want to use that method. When RAM usage is defined like this:

        ORG $80
Player1X:   ds 1
Player1Y:   ds 1
Player2X:   ds 1
Player2Y:   ds 1
Shot1X:     ds 1
Shot1Y:     ds 1
Shot2X:     ds 1
Shot2Y:     ds 1
Score:      ds 3


 

If you later decide to start using 16 bit values for subpixel positioning you'd just do this:

        ORG $80
Player1X:   ds 2
Player1Y:   ds 2
Player2X:   ds 2
Player2Y:   ds 2
Shot1X:     ds 2
Shot1Y:     ds 2
Shot2X:     ds 2
Shot2Y:     ds 2
Score:      ds 3


With your method you'd have to go to each and every variable you've defined and manually update where in RAM they are located. That's a tedious, and very error prone, thing to do.

 

Yes, in Collect I list out where the variables end up in RAM; however, that's only in the comments, and only because it's a tutorial where I don't expect people to already know that's how RAM usage gets assigned.

Share this post


Link to post
Share on other sites

Does any one know, why the empty part of the ROM file is filled with $FF ?

Fill value doesn't matter

 

 

What is the reason why DASM is used to write Atari 2600 programs? Is there some special functionality in it that is needed?

 

That's like asking why most people use Windows based computers - people use dasm because most of the existing 2600 source code is in the format used by dasm. There have been investigations into replacing dasm, such as this one in 2011, but they've gone nowhere.

Share this post


Link to post
Share on other sites

Ok! what parts is the graphics kernel?

 

The Atari is unlike any other system in that the 6507 (6502 compatible) updates the hardware in real time to draw the screen scanline by scanline. Unless you take the time to learn how that works then your new computer language will be worthless for 2600 projects.

Covered in Step 1 - Generate a Stable Display

  • Like 1

Share this post


Link to post
Share on other sites


I would not want to use that method. When RAM usage is defined like this:

        ORG $80
Player1X:   ds 1
Player1Y:   ds 1
Player2X:   ds 1
Player2Y:   ds 1
Shot1X:     ds 1
Shot1Y:     ds 1
Shot2X:     ds 1
Shot2Y:     ds 1
Score:      ds 3


 

If you later decide to start using 16 bit values for subpixel positioning you'd just do this:

        ORG $80
Player1X:   ds 2
Player1Y:   ds 2
Player2X:   ds 2
Player2Y:   ds 2
Shot1X:     ds 2
Shot1Y:     ds 2
Shot2X:     ds 2
Shot2Y:     ds 2
Score:      ds 3


With your method you'd have to go to each and every variable you've defined and manually update where in RAM they are located. That's a tedious, and very error prone, thing to do.

 

Yes, in Collect I list out where the variables end up in RAM; however, that's only in the comments, and only because it's a tutorial where I don't expect people to already know that's how RAM usage gets assigned.

 

 

I agree on that. It was just some hasty translation, without much thought. I have support for what you talk about, it's quite essential.

Share this post


Link to post
Share on other sites

 

 

Well then I already has support for the graphics kernel, I have tested to write that code, and it worked.

 

So there isn't anything specific that is needed for Atari 2600 support, more than a efficient compiler on pair with assembly.

 

Is there anything I have missed?

 

A bit curious, is there a C compiler that is efficient enough to write programs to Atari 2600?

Share this post


Link to post
Share on other sites

 

 

So there isn't anything specific that is needed for Atari 2600 support, more than a efficient compiler on pair with assembly.

 

 

 

The biggest thing is going to be, for the display kernel, the ability for the programmer to have EXACT control over the timings of everything. For a game of any complexity, you need to carefully work out exactly when each machine instruction runs, which involves carefully counting the cycles of each instruction. Any language that abstracts that away is not going to work for the kernel. So to make your language viable, one of the following will probably have to be true:

 

1. Your language is meant to be used just in the game logic, and the programmers will still plan to use assembly for the kernel

2. Your language is just a different syntax but logically is just a different mapping of source to machine code. (ie like how different assemblers may have slightly different syntax)

3. You include pre-written display kernels (like batari basic) and your users will just use one of yours.

  • Like 3

Share this post


Link to post
Share on other sites

A bit curious, is there a C compiler that is efficient enough to write programs to Atari 2600?

 

cc65 is sometimes used in nes programming, and would probably work for game logic on the Atari in some cases. Definitely not in the kernel though.

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.
Note: Your post will require moderator approval before it will be visible.

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...