Jump to content
batari

Atari 2600 BASIC compiler is here!

Recommended Posts

I'm probably going to get a mix of praise and criticism for this. Anyway, I've written a BASIC compiler for the Atari 2600. Yes, you read that right. This is not a joke!

 

Of course there is no "print" statement, string operations or arrays... But I've managed to abstract some of the harder things to simple BASIC keywords and functions.

 

Also, it doesn't generate binaries directly, instead it converts them to an assembly file in DASM syntax, then invokes DASM to make a binary. It comes with a canned kernel with two players, two missiles, and asymmetric playfield and a 6-digit score, but it is possible for a somewhat-experienced programmer to make it work with almost any kernel.

 

It is my hope that folks will use this BASIC as a stepping stone to serious 2600/6502 programming, much like some of us did in the past on our C-64's, Apples or Atari 8-bits. Since it generates meaningful assemblies instead of binaries, I think this is likely, or at least I remain hopeful.

 

The included kernel uses a bitmapped 32x12 playfield and has easy to use scrolling routines too, which could be used to make a car racing game or something of that sort. Calling the display kernel is not automatic - you must use the drawscreen function.

 

[technical stuff]

Also, the compiler generates pretty efficient code, or at least I think so. As long as you're not using too many of the playfield scrolling routines, I think (I hope) it's unlikely that you will exceed the time alloted for overscan/vblank. The compiler also inserts conditional compilation flags to prevent player graphics from wrapping page boundaries and can also be configured to automatically use branches instead of jumps where the target is near.

 

Also, I haven't abstracted out all 2600 intricacies - you still have direct access to any TIA register and can include inline assembly. In fact you must use TIA regs for some things, like colors and sound, but you access them just like any other variable.

[/technical stuff]

 

To learn more, read the README file or ask me questions, or tell me I'm crazy or something since I have been critical about this very thing in the past...

 

Please try it out and tell me what you all think!

 

EDIT: This project now has a homepage! To get the latest builds as well as other tools and documentation in one place, go to http://alienbill.com/2600/basic/

 

EDIT: Alpha 0.2 has been released. Download "batari_basic_alpha2.zip" below. EDIT AGAIN: updated with slight bugfixes... download Alpha2 again if you already did.

batari_basic_alpha2.zip

Edited by batari

Share this post


Link to post
Share on other sites

Hi there!

 

Wow, sounds very cool, can't wait to try that!

 

Actually I think it's pretty good that it's 2-step, doing assembly code first. So one can probably use it to create a rough framework and then continue development in assembler.

 

Greetings,

Manuel

Share this post


Link to post
Share on other sites

This looks like a great idea. I think it will also make a good prototyping tool for experienced developers. It should allow a game idea to be tested before investing a lot of effort on a custom kernel. Unfortunately I can't actually run it as I am a Linux user, but I hope that you are going to release the C source at some point? Are you using LEX/YACC (Flex/Bison) to parse the source files as this should solve the spacing issues? You are probably not looking for suggestions yet, but I think that presenting the registers as 2D arrays would make some things easier to express, e.g. if CXM0P(7)=1 then ... I will be interested to watch how this develops.

 

Chris

Share this post


Link to post
Share on other sites

Looks cool, and fun. Good job! :D

 

A few comments on the 2600basic.asm kernel you have there...

 

Since it is a 2-line kernel, you should really use SwitchDraw instead of SkipDraw.

 

Also, rather than:

 lda missile1height;3
dcp missile1y;5
;c=1 active
ldy temp4;3
; lda #0;14
; adc #1;16
rol;2
rol;2
sta ENAM1;3

Use this to save a few cycles (at the expense of another byte of RAM):

 lda missile1height;3
dcp missile1y;5
;c=1 active
ldy temp4;3
; lda #0;14
; adc #1;16
sbc missile1adjuster;3 -- where missile1adjuster = missile1height - 2
sta ENAM1;3

Saves 1 cycle for each missile and the ball.

Share this post


Link to post
Share on other sites
This looks like a great idea.  I think it will also make a good prototyping tool for experienced developers.  It should allow a game idea to be tested before investing a lot of effort on a custom kernel.    Unfortunately I can't actually run it as I am a Linux user, but I hope that you are going to release the C source at some point?  Are you using LEX/YACC (Flex/Bison) to parse the source files as this should solve the spacing issues?  You are probably not looking for suggestions yet, but I think that presenting the registers as 2D arrays would make some things easier to express, e.g. if CXM0P(7)=1 then ...  I will be interested to watch how this develops.

 

Chris

887497[/snapback]

I welcome any/all suggestions! My parser is written by me, and this is why it is so picky. I'll look into LEX and/or YACC to see how they can help, as the spacing issue is a little annoying.

 

Also, allowing TIA regs as arrays should be simple enough to implement.

 

I'll go ahead and post the source so others can compile it. Also, I am open to suggestions on how to improve the source too, if anyone notices anything funny.

 

EDIT: Bug found when compiled under Linux - has been fixed. If you are having problems, download the updated source below.

2600basicsource.zip

Edited by batari

Share this post


Link to post
Share on other sites
Looks cool, and fun.  Good job!  :D

 

A few comments on the 2600basic.asm kernel you have there...

 

Since it is a 2-line kernel, you should really use SwitchDraw instead of SkipDraw.

 

Also, rather than:

 lda missile1height;3
dcp missile1y;5
;c=1 active
ldy temp4;3
; lda #0;14
; adc #1;16
rol;2
rol;2
sta ENAM1;3

Use this to save a few cycles (at the expense of another byte of RAM):

 lda missile1height;3
dcp missile1y;5
;c=1 active
ldy temp4;3
; lda #0;14
; adc #1;16
sbc missile1adjuster;3 -- where missile1adjuster = missile1height - 2
sta ENAM1;3

Saves 1 cycle for each missile and the ball.

887578[/snapback]

Thanks for the suggestions - I want to improve the kernel definitely since I want to free up enough cycles to display the ball. I've only got one byte of RAM to spare - so this equates to 1 cycle here. I tried using switchdraw at some point but I went back to skipdraw, but I can't remember why - I think it might have used up an extra byte of RAM or something. I'll look into this again and see if I can get it working with switchdraw. I also need to VDEL P1 at some point.

Share this post


Link to post
Share on other sites
Thanks for the suggestions - I want to improve the kernel definitely since I want to free up enough cycles to display the ball.  I've only got one byte of RAM to spare - so this equates to 1 cycle here.  I tried using switchdraw at some point but I went back to skipdraw, but I can't remember why - I think it might have used up an extra byte of RAM or something.  I'll look into this again and see if I can get it working with switchdraw.  I also need to VDEL P1 at some point.

Yeah, SwitchDraw uses two bytes of RAM for every object. Might be worth scaring up some RAM for the extra cycles, though. Use SwitchDraw for both players and the code I posted for the three single-bit objects and you save 7 cycles altogether.

 

Maybe if you don't allow calls to DisplayScreen inside a subroutine? Kind of restrictive, but then you can use the 6 stack bytes for the temp variables you'll need.

Share this post


Link to post
Share on other sites
Thanks for the suggestions - I want to improve the kernel definitely since I want to free up enough cycles to display the ball.  I've only got one byte of RAM to spare - so this equates to 1 cycle here.  I tried using switchdraw at some point but I went back to skipdraw, but I can't remember why - I think it might have used up an extra byte of RAM or something.  I'll look into this again and see if I can get it working with switchdraw.  I also need to VDEL P1 at some point.

Yeah, SwitchDraw uses two bytes of RAM for every object. Might be worth scaring up some RAM for the extra cycles, though. Use SwitchDraw for both players and the code I posted for the three single-bit objects and you save 7 cycles altogether.

 

Maybe if you don't allow calls to DisplayScreen inside a subroutine? Kind of restrictive, but then you can use the 6 stack bytes for the temp variables you'll need.

887829[/snapback]

That should work. The compiler isn't smart enough to know if it's in a subroutine when displayscreen is called, so I'd either have to figure out how to do this and issue a warning, or just mention this restriction in the documentation. It should be worth it if I can get the ball on the screen.

Share this post


Link to post
Share on other sites
I welcome any/all suggestions!  My parser is written by me, and this is why it is so picky.  I'll look into LEX and/or YACC to see how they can help, as the spacing issue is a little annoying.

 

I'll go ahead and post the source so others can compile it.  Also, I am open to suggestions on how to improve the source too, if anyone notices anything funny.

887820[/snapback]

 

Thanks - the source code compiles fine under Linux with gcc. Lex and Yacc should definitely help you - I wouldn't dream of writing my own parser anymore! Basically, Lex takes the input and converts it into lexical tokens which solves the spacing issue, e.g "if x then" becomes ["IF","VAR(X)","THEN"], and Yacc takes these tokens and converts them into a parse tree to match the grammar (and rejects any invalid syntax), e.g. ["IF", "IF"] would be rejected. I would offer to do this for you, but it has been several years since I used these tools. I will let you know if I think of any more suggestions.

 

Chris

Edited by cd-w

Share this post


Link to post
Share on other sites
I welcome any/all suggestions!  My parser is written by me, and this is why it is so picky.  I'll look into LEX and/or YACC to see how they can help, as the spacing issue is a little annoying.

 

I'll go ahead and post the source so others can compile it.  Also, I am open to suggestions on how to improve the source too, if anyone notices anything funny.

887820[/snapback]

 

Thanks - the source code compiles fine under Linux with gcc. Lex and Yacc should definitely help you - I wouldn't dream of writing my own parser anymore! Basically, Lex takes the input and converts it into lexical tokens which solves the spacing issue, e.g "if x then" becomes ["IF","VAR(X)","THEN"], and Yacc takes these tokens and converts them into a parse tree to match the grammar (and rejects any invalid syntax), e.g. ["IF", "IF"] would be rejected. I would offer to do this for you, but it has been several years since I used these tools. I will let you know if I think of any more suggestions.

 

Chris

887869[/snapback]

Oh yeah, for anyone else using something other than DOS (I'm not using DOS myself) the following shell script may be helpful, which I used to compile sample.bas:

./2600bas<sample.bas>sample.asm
cat 2600basic.asm sample.asm 2600basicfooter.asm > test.asm
./dasm test.asm -f3 -otest.bin

Share this post


Link to post
Share on other sites
Thanks - the source code compiles fine under Linux with gcc.  Lex and Yacc should definitely help you - I wouldn't dream of writing my own parser anymore!  Basically, Lex takes the input and converts it into lexical tokens which solves the spacing issue, e.g "if x  then" becomes ["IF","VAR(X)","THEN"], and Yacc takes these tokens and converts them into a parse tree to match the grammar (and rejects any invalid syntax), e.g. ["IF", "IF"] would be rejected.  I would offer to do this for you, but it has been several years since I used these tools.    I will let you know if I think of any more suggestions.

 

Chris

887869[/snapback]

I can second that info about Lex and Yacc. We're currently using this to implement a mini debugger language in Stella, so one can type 'breakcond *A = 0xff, or something like that.

 

Steve

Share this post


Link to post
Share on other sites

I was wondering whe somebody would come up with something like this

this will defently move my game developing ahead.

ironicly, I remember mentioning that if compare 2600 asm language to Ti-extened basic language it's not very different.(It's posted in the 2600 for beginers subforum I think)

Share this post


Link to post
Share on other sites

Hello everyone,

 

Have been lurking for a very long time. Had a bit of free time today, thought I might give this project a quick try.

 

I compiled under Linux too. No worries there.

 

This worked for me, but for the last bit:

 

./2600bas<sample.bas>sample.asm
cat 2600basic.asm sample.asm 2600basicfooter.asm > test.asm
./dasm test.asm -f3 -otest.bin

 

I just worked through this and ran into a snag.

 

dasm says:

 

DASM V2.20.09, Macro Assembler ©1988-2003

Warning: Unable to open 'vcs.h'

Warning: Unable to open 'macro.h'

Warning: Unable to open '2600basic.h'

test.asm (766): error: Syntax Error ''.

test.asm (766): error: Syntax Error ''.

Unrecoverable error(s) in pass, aborting assembly!

Complete.

 

Specified the include directories on the command line, edited the test.asm file, what gives?

 

I'm assuming there is some prep for DASM that I don't know about? I just grabbed the latest package, copied the Linux binary into the working directory and ???

 

EDIT: Everything referenced in the test.asm file is in the same working directory.

Edited by potatohead

Share this post


Link to post
Share on other sites

One bug has been found so far - at the beginning of the 2600basic.h file, it attempts to include itself, which could be the cause.

 

If not, please post your test.asm file so I can take a look. I have not tested in Linux at all, just OSX and DOS so far, so it could very well be a bug. Yep, this is definitely an alpha version...

 

Hello everyone,

 

Have been lurking for a very long time.  Had a bit of free time today, thought I might give this project a quick try. 

 

I compiled under Linux too.  No worries there.

 

This worked for me, but for the last bit:

 

./2600bas<sample.bas>sample.asm
cat 2600basic.asm sample.asm 2600basicfooter.asm > test.asm
./dasm test.asm -f3 -otest.bin


 

I just worked through this and ran into a snag. 

 

dasm says:

 

DASM V2.20.09, Macro Assembler ©1988-2003

Warning: Unable to open 'vcs.h'

Warning: Unable to open 'macro.h'

Warning: Unable to open '2600basic.h'

test.asm (766): error: Syntax Error ''.

test.asm (766): error: Syntax Error ''.

Unrecoverable error(s) in pass, aborting assembly!

Complete.

 

Specified the include directories on the command line, edited the test.asm file, what gives?

 

I'm assuming there is some prep for DASM that I don't know about?  I just grabbed the latest package, copied the Linux binary into the working directory and ???

888071[/snapback]

Share this post


Link to post
Share on other sites

EDIT: for some reason my edit didn't take and got posted below... Anyway, please get the updated source above.

Edited by batari

Share this post


Link to post
Share on other sites
test.asm (766): error: Syntax Error ''.

test.asm (766): error: Syntax Error ''.

Unrecoverable error(s) in pass, aborting assembly!

Complete.

888071[/snapback]

EDIT: This was a bug, and it has been fixed (easy fix). Source code above updated. Thanks for finding it!

Edited by batari

Share this post


Link to post
Share on other sites

I lied :)

 

Success!

 

The output is still goofy from dasm:

 

DASM V2.20.09, Macro Assembler ©1988-2003

Warning: Unable to open 'vcs.h'

Warning: Unable to open 'macro.h'

Warning: Unable to open '2600basic.h'

Warning: Unable to open 'vcs.h'

Warning: Unable to open 'macro.h'

Warning: Unable to open '2600basic.h'

Warning: Unable to open 'vcs.h'

Warning: Unable to open 'macro.h'

Warning: Unable to open '2600basic.h'

Complete.

 

But it does indeed produce a working binary file.

 

Very cool stuff.

 

I've been watching this stuff with great interest. It's nice to finally have a simple dev path on my Linux box for some futzing around. This project should speed some of the learning curve.

 

After years of banging around on my 400, as a kid, seeing this 6502 stuff go is just great.

 

Mandrake 10, BTW, using Stella for emulation.

Share this post


Link to post
Share on other sites

P r e t t y : n i c e ! :P

 

I played around with it a bit, still get the "Warning: Unable to..." every time but it compiles ok. If I got the time i'll try and make a simple pong like game with it, always make a pong game on every new 'language' i learn.

 

I noticed you can't use negative numbers (-4) so made a little work around attached to this post, try it out it worked on StellaX.

 

It would look nicer if you could remove the extension someway so it will not look like dong.txt.bin (or dong.bas.bin) but dong.bin

 

BTW. there is an easter egg in the emulator just create a new file (empty.bin) of 0 bytes and (reload) open it with StellaX and watch the egg.

 

greets

dong.txt

Share this post


Link to post
Share on other sites
I noticed you can't use negative numbers (-4) so made a little work around attached to this post, try it out it worked on StellaX.

There is some support for negative numbers because of the way the variables work. For addition and subraction, another way of expressing 128 to 255 is -128 to -1.

 

Were you trying to do a = -a? If so, this didn't work because it confused the compiler. However, you could use a = 0 - a instead.

 

It would look nicer if you could remove the extension someway so it will not look like dong.txt.bin (or dong.bas.bin) but dong.bin

888235[/snapback]

yeah, I'll fix that.

Share this post


Link to post
Share on other sites

Thanks a = 0 - a worked , saves some lines, but at first i did got an "Cannot pars line |" error when trying to use "if X > 166 | x < 16 then a = 0 - a" so I gues thats not possible (yet).

 

Hope you'll get the ball thing going, now then "all" it needs is sound support and a nice ide something like notepad but then with quick instruction insertion and compile(&run) function. I could make something like that if you wantt.

 

Oh and can you make one of those wonderfull beep commands :) should be simple for you I gues or something like a sound (freq) command.

 

(edited a = - a didn't work but a = 0 -a did)

Edited by attendo

Share this post


Link to post
Share on other sites
Thanks a = - a worked , saves some lines,  but at first i did got an "Cannot pars line |" error when trying to use "if X > 166 | x < 16 then a = 0 - a" so I gues thats not possible (yet).

 

Hope you'll get the ball thing going, now then "all" it needs is sound support and a nice ide something like notepad but then with quick instruction insertion and compile(&run) function. I could make something like that if you wantt.

 

Oh and can you make one of those wonderfull beep commands :) should be simple for you I gues or something like a sound (freq) command.

888254[/snapback]

It only handles simple if-then statements right now. I will add support for more complicated expressions if I can figure out how to do this :?

 

If you want to use sound, the TIA registers are easy enough to use, I just haven't explained how to use them in this BASIC yet. Anyway:

 

AUDV0 : channel 0 volume (value is 0-15)

AUDF0 : channel 0 frequency (value is 0-31)

AUDC0 : channel 0 control (detemines the "voice" - value 0-15)

and AUDV1, AUDF1, AUDC1 for channel 1

 

To make a beep, I'd set AUDC0 and AUDF0 at the beginning of the program. I think these might produce a good "beep" sound:

 

5 AUDC0 = 12 : AUDF0 = 3

 

then when the ball changes direction, you can also set AUDV0 = 15 to turn the sound on, then set AUDV0 = 0 sometime after the call to "drawscreen" which will keep the sound on for about 1/60th of a second, but should be perfect for a pong game. To keep the sound on longer, you would need to set up a counter or something of that sort and turn it off after several iterations through the game loop.

Share this post


Link to post
Share on other sites

I have been talking about something like this for YEARS. People said it could not be done. Of course mine would probably be more in-depth than this one is, but this is a start and I'm gonna check it out.

 

It could be the start of an actually 2600 game design program or a 2600 development system. The way I envision my idea was a graphic editor built in, and different routines that could allow you to make a variety of games with little effort. Almost like a Gamemaker or Click N Play designed to make 2600 games.

Edited by yuppicide

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