Run the game using VS Code with the Atari Dev Studio extension. Once compiled to a ROM, run using the Stella emulator.
Last active
December 6, 2025 23:23
-
-
Save primaryobjects/6dfa9e98c0f59eec3773e11f545e1538 to your computer and use it in GitHub Desktop.
A Batari Basic (Atari 2600) game similar to Berzerk.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| set tv ntsc | |
| set romsize 8k | |
| rem set kernel_options pfcolors | |
| rem https://alienbill.com/2600/atari-background-builder/ | |
| rem ************************************************************************** | |
| rem BERZERK-STYLE GAME | |
| rem ************************************************************************** | |
| rem ************************************************************************** | |
| rem Variable declarations - use letters m-z to avoid conflicts | |
| rem ************************************************************************** | |
| score = 00000 | |
| scorecolor = $0E | |
| dim m0_active = m | |
| dim m1_active = n | |
| dim e_dir = o | |
| dim e_timer = p | |
| dim cur_level = q | |
| dim plr_lives = r | |
| dim gstate = s | |
| dim shoot_wait = t | |
| dim death_wait = u | |
| dim e_shoot_wait = v | |
| dim temp = w | |
| dim sound0_timer = x | |
| dim sound1_timer = y | |
| dim flash_counter = z | |
| dim sc1 = l | |
| rem ************************************************************************** | |
| rem Initialization | |
| rem ************************************************************************** | |
| gstate = 0 | |
| cur_level = 1 | |
| plr_lives = 3 | |
| player0x = 40 | |
| player0y = 50 | |
| player1x = 100 | |
| player1y = 40 | |
| missile0x = 0 | |
| missile0y = 0 | |
| missile1x = 0 | |
| missile1y = 0 | |
| missile0height = 2 | |
| missile1height = 2 | |
| COLUP0 = $42 | |
| COLUP1 = $36 | |
| COLUPF = $8E | |
| COLUBK = $00 | |
| m0_active = 0 | |
| m1_active = 0 | |
| e_dir = 1 | |
| e_timer = 0 | |
| shoot_wait = 0 | |
| death_wait = 0 | |
| e_shoot_wait = 30 | |
| sound0_timer = 0 | |
| sound1_timer = 0 | |
| flash_counter = 0 | |
| sc1 = 0 | |
| NUSIZ0 = $00 | |
| NUSIZ1 = $00 | |
| rem ************************************************************************** | |
| rem Main Loop | |
| rem ************************************************************************** | |
| main | |
| temp = gstate | |
| if temp = 0 then goto do_title | |
| if temp = 1 then goto do_play | |
| if temp = 2 then goto do_levelup | |
| if temp = 3 then goto do_dead | |
| if temp = 4 then goto do_gameover | |
| goto main | |
| rem ************************************************************************** | |
| rem Title Screen | |
| rem ************************************************************************** | |
| do_title | |
| COLUBK = $00 | |
| scorecolor = $1E | |
| playfield: | |
| ................................ | |
| ..XXXX..XXXXX.XXXX..X...X.X...X. | |
| ..X...X.X.....X...X.X...X.X...X. | |
| ..XXXX..XXX...XXXX..X...X.X.X.X. | |
| ..X...X.X.....X.X...X...X.X.X.X. | |
| ..XXXX..XXXXX.X..X..XXXXX.X...X. | |
| ................................ | |
| ................................ | |
| ........PRESS.FIRE.............. | |
| ................................ | |
| ................................ | |
| end | |
| player0: | |
| %00000000 | |
| end | |
| player1: | |
| %00000000 | |
| end | |
| if joy0fire then gstate = 1 : cur_level = 1 : plr_lives = 3 : score = 0 : player0x = 40 : player0y = 50 : player1x = 100 : player1y = 40 : m0_active = 0 : m1_active = 0 : AUDV0 = 0 : AUDV1 = 0 | |
| drawscreen | |
| goto main | |
| rem ************************************************************************** | |
| rem Level Up | |
| rem ************************************************************************** | |
| do_levelup | |
| death_wait = death_wait + 1 | |
| flash_counter = flash_counter + 1 | |
| rem Rainbow flash effect | |
| temp = flash_counter / 2 | |
| temp = temp & 15 | |
| COLUBK = temp * 16 + temp | |
| rem Level up sound effect | |
| if death_wait < 30 then AUDV0 = 8 : AUDC0 = 4 : AUDF0 = death_wait | |
| if death_wait = 30 then AUDV0 = 0 | |
| playfield: | |
| ................................ | |
| .............X.................. | |
| ............XXXX................ | |
| ..........XXXXXXXX.............. | |
| .........XX..XX..XX............. | |
| .............XX................. | |
| .............XX................. | |
| .............XX................. | |
| .............XX................. | |
| ................................ | |
| ................................ | |
| end | |
| player0: | |
| %00000000 | |
| end | |
| player1: | |
| %00000000 | |
| end | |
| temp = death_wait | |
| if temp > 60 then player0x = 40 | |
| if temp > 60 then player0y = 50 | |
| if temp > 60 then player1x = 100 | |
| if temp > 60 then player1y = 40 | |
| if temp > 60 then m0_active = 0 | |
| if temp > 60 then m1_active = 0 | |
| if temp > 60 then AUDV0 = 0 | |
| if temp > 60 then AUDV1 = 0 | |
| if temp > 60 then flash_counter = 0 | |
| if temp > 60 then death_wait = 0 | |
| if temp > 60 then gstate = 1 | |
| drawscreen | |
| goto main | |
| rem ************************************************************************** | |
| rem Player Died | |
| rem ************************************************************************** | |
| do_dead | |
| COLUBK = $40 | |
| death_wait = death_wait + 1 | |
| playfield: | |
| ................................ | |
| ........X.X....X.X.............. | |
| .........X......X............... | |
| ........X.X....X.X.............. | |
| ................................ | |
| ...........XXXXX................ | |
| .........X......X............... | |
| ........X........X.............. | |
| ................................ | |
| ................................ | |
| ................................ | |
| end | |
| player0: | |
| %00000000 | |
| end | |
| player1: | |
| %00000000 | |
| end | |
| temp = death_wait | |
| if temp > 20 then plr_lives = plr_lives - 1 : death_wait = 0 : temp = plr_lives | |
| if temp = 0 then gstate = 4 : AUDV0 = 0 : AUDV1 = 0 | |
| if temp > 0 then temp = death_wait : if temp = 0 then gstate = 1 : player0x = 40 : player0y = 50 : player1x = 100 : player1y = 40 : m0_active = 0 : m1_active = 0 : AUDV0 = 0 : AUDV1 = 0 | |
| drawscreen | |
| goto main | |
| rem ************************************************************************** | |
| rem Game Over | |
| rem ************************************************************************** | |
| do_gameover | |
| COLUBK = $00 | |
| scorecolor = $36 | |
| playfield: | |
| ................................ | |
| ................................ | |
| ..XXX...XXX..X...X.XXX.........X | |
| .X.....X...X.XX.XX.X..........X. | |
| .X..XX.XXXXX.X.X.X.XX.........X. | |
| .X...X.X...X.X...X.X..........X. | |
| ..XXX..X...X.X...X.XXX.XXXXX.X.. | |
| ................................ | |
| ........PRESS.FIRE.............. | |
| ................................ | |
| ................................ | |
| end | |
| player0: | |
| %00000000 | |
| end | |
| player1: | |
| %00000000 | |
| end | |
| if joy0fire then gstate = 0 | |
| drawscreen | |
| goto main | |
| rem ************************************************************************** | |
| rem Gameplay | |
| rem ************************************************************************** | |
| do_play | |
| rem Set level | |
| temp = cur_level | |
| if temp = 1 then gosub lvl1 | |
| if temp = 2 then gosub lvl2 | |
| if temp = 3 then gosub lvl3 | |
| if temp > 3 then gosub lvl4 | |
| rem Sprites | |
| rem Handle sound timers | |
| if sound0_timer > 0 then sound0_timer = sound0_timer - 1 | |
| if sound0_timer = 0 then AUDV0 = 0 | |
| if sound1_timer > 0 then sound1_timer = sound1_timer - 1 | |
| if sound1_timer = 0 then AUDV1 = 0 | |
| player0: | |
| %01111110 | |
| %01111110 | |
| %00111100 | |
| %11111111 | |
| %00111100 | |
| %00111100 | |
| %01100110 | |
| %11000011 | |
| end | |
| player1: | |
| %00111100 | |
| %01111110 | |
| %11111111 | |
| %01111110 | |
| %00111100 | |
| %01011010 | |
| %10011001 | |
| %10000001 | |
| end | |
| rem Movement | |
| temp = player0x | |
| if joy0right then temp = temp + 1 | |
| if temp < 150 then player0x = temp | |
| temp = player0x | |
| if joy0left then temp = temp - 1 | |
| if temp > 10 then player0x = temp | |
| temp = player0y | |
| if joy0up then temp = temp - 1 | |
| if temp > 10 then player0y = temp | |
| temp = player0y | |
| if joy0down then temp = temp + 1 | |
| if temp < 80 then player0y = temp | |
| rem Wall collision | |
| if collision(player0, playfield) then player0x = player0x - 1 : player0y = player0y + 1 : AUDV0 = 0 : AUDV1 = 0 | |
| rem Shoot delay | |
| temp = shoot_wait | |
| if temp > 0 then shoot_wait = temp - 1 | |
| rem Player shoot | |
| temp = m0_active | |
| if temp = 0 then temp = shoot_wait | |
| if temp = 0 && joy0fire then m0_active = 1 : missile0x = player0x + 3 : missile0y = player0y : shoot_wait = 10 : AUDV0 = 4 : AUDC0 = 8 : AUDF0 = 10 : sound0_timer = 3 | |
| rem Move missile | |
| if m0_active = 1 then missile0y = missile0y - 2 | |
| temp = missile0y | |
| if temp < 5 then m0_active = 0 | |
| if collision(missile0, playfield) then m0_active = 0 | |
| rem Hit enemy | |
| if collision(missile0, player1) then m0_active = 0 : score = score + 10 : sc1 = sc1 + 1 : player1x = 100 : player1y = 40 : AUDV0 = 8 : AUDC0 = 6 : AUDF0 = 5 : sound0_timer = 5 | |
| rem Enemy AI | |
| e_timer = e_timer + 1 | |
| temp = e_timer | |
| if temp > 30 then e_timer = 0 : e_dir = e_dir + 1 | |
| temp = e_dir | |
| if temp > 4 then e_dir = 1 | |
| temp = e_dir | |
| if temp = 1 then temp = player1x : temp = temp + 1 : if temp < 145 then player1x = temp | |
| temp = e_dir | |
| if temp = 2 then temp = player1x : temp = temp - 1 : if temp > 10 then player1x = temp | |
| temp = e_dir | |
| if temp = 3 then temp = player1y : temp = temp - 1 : if temp > 10 then player1y = temp | |
| temp = e_dir | |
| if temp = 4 then temp = player1y : temp = temp + 1 : if temp < 80 then player1y = temp | |
| rem Enemy wall | |
| if collision(player1, playfield) then e_timer = 0 | |
| rem Enemy shoot delay | |
| temp = e_shoot_wait | |
| if temp > 0 then e_shoot_wait = temp - 1 | |
| rem Enemy shoot | |
| temp = m1_active | |
| if temp = 0 then temp = e_shoot_wait | |
| if temp = 0 then m1_active = 1 : missile1x = player1x + 3 : missile1y = player1y : e_shoot_wait = 60 : AUDV1 = 3 : AUDC1 = 7 : AUDF1 = 15 : sound1_timer = 3 | |
| rem Move enemy missile | |
| if m1_active = 1 then missile1y = missile1y + 1 | |
| temp = missile1y | |
| if temp > 85 then m1_active = 0 | |
| if collision(missile1, playfield) then m1_active = 0 | |
| rem Hit player | |
| if collision(missile1, player0) then m1_active = 0 : gstate = 3 : death_wait = 0 : AUDV0 = 8 : AUDC0 = 8 : AUDF0 = 10 : sound0_timer = 5 | |
| rem Player-enemy collision | |
| if collision(player0, player1) then gstate = 3 : death_wait = 0 : AUDV0 = 8 : AUDC0 = 8 : AUDF0 = 10 : sound0_timer = 5 | |
| rem Level up | |
| temp = cur_level | |
| if temp = 1 && sc1 = 10 then cur_level = 2 : gstate = 2 : death_wait = 0 | |
| temp = cur_level | |
| if temp = 2 && sc1 = 20 then cur_level = 3 : gstate = 2 : death_wait = 0 | |
| temp = cur_level | |
| if temp = 3 && sc1 = 30 then cur_level = 4 : gstate = 2 : death_wait = 0 | |
| temp = cur_level | |
| if temp = 4 && sc1 = 40 then cur_level = 5 : gstate = 2 : death_wait = 0 | |
| temp = cur_level | |
| if temp = 5 && sc1 = 50 then cur_level = 6 : gstate = 2 : death_wait = 0 | |
| rem Hide missiles | |
| if m0_active = 0 then missile0x = 0 : missile0y = 0 | |
| if m1_active = 0 then missile1x = 0 : missile1y = 0 | |
| drawscreen | |
| goto main | |
| rem ************************************************************************** | |
| rem Levels | |
| rem ************************************************************************** | |
| lvl1 | |
| COLUBK = $00 | |
| COLUPF = $8E | |
| playfield: | |
| XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | |
| X..............................X | |
| X..............................X | |
| X..............................X | |
| X..........XXXXXX..............X | |
| X..............................X | |
| X..............................X | |
| X..............................X | |
| X..............................X | |
| X..............................X | |
| XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | |
| end | |
| return | |
| lvl2 | |
| COLUBK = $02 | |
| COLUPF = $4E | |
| playfield: | |
| XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | |
| X......X...................X...X | |
| X..............................X | |
| X......X...................X...X | |
| X..............................X | |
| X......X....XXXXXX.........X...X | |
| X..............................X | |
| X......X...................X...X | |
| X..............................X | |
| X......X...................X...X | |
| XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | |
| end | |
| return | |
| lvl3 | |
| COLUBK = $04 | |
| COLUPF = $2E | |
| playfield: | |
| XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | |
| X..X...........................X | |
| X..X...........................X | |
| X..XXXXXXX.....................X | |
| X..............................X | |
| X...........XXXXXXX............X | |
| X..............................X | |
| X..................XXXXXXX..X..X | |
| X...........................X..X | |
| X...........................X..X | |
| XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | |
| end | |
| return | |
| lvl4 | |
| COLUBK = $06 | |
| COLUPF = $CE | |
| playfield: | |
| XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | |
| X..X.....X.....X.....X.....X...X | |
| X..............................X | |
| X..X.....X.....X.....X.....X...X | |
| X..............................X | |
| X..X.....X..XXXXXX...X.....X...X | |
| X..............................X | |
| X..X.....X.....X.....X.....X...X | |
| X..............................X | |
| X..X.....X.....X.....X.....X...X | |
| XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | |
| end | |
| return |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
