Useful
Inventions
Favorite
Quotes
Game
Design
Atari
Memories
Personal
Pages

Home > Atari Memories > #7800basic > 7800basic Guide

7800basic Guide

By Mike “RevEng” Saarna (adapted by Duane Alan Hahn, a.k.a. Random Terrain)

Tip Jar

As an Amazon Associate I earn from qualifying purchases. (I get commissions for purchases made through certain links on this page.)

 

Table of Contents

About This HTML Page

Introduction

7800 Hardware Overview

Controls

Graphics

Sprites and Characters

Palettes

Graphics Modes

Zones

Sound

Formatting and Layout Features

Indenting and White Space

Numeric Representation

Line Numbers and Labels

Combining Multiple Commands

Variables

Regular Variables

Dimensioning Variable Names

Assignment

Other Variable Types

Variable Arrays

Bitwise Variables

Constant Variables

Indirect Variable Arrays

8.8 Fixed Point Variables

Special Variables

Score Variables and BCD Variables

Random Numbers

Temporary Variables

CARRY Variable

pokeydetected Variable

paldetected Variable

Conditional Logic

Code Organization and Flow Control

bank

dmahole

noflow

goto

gosub and return

on…goto and on…gosub

loadrombank

loadrambank

reboot

for…next

User Functions

Data

Regular Data

Sequential Data

Using Character Data

Tiled Character-Map Data Import

speechdata

Program Configuration

set romsize [value]

set doublewide on

set zoneheight [value]

set tallsprite [on|off|spritesheet]

set screenheight

set extradlmemory on

set dlmemory

set plotvalueonscreen

set plotvaluepage [$##]

set zoneprotection

set pauseroutine

set pokeysound

set trackersupport basic

set tiasfx mono

set avoxvoice on

set debug color

set mcpdevcart

set basepath

set hssupport

set hsseconds

set hsscoresize

set hscolorbase

set hsdifficultytext off

set hsdifficultytext

set hsgameranks

Graphics Commands

displaymode

clearscreen

savescreen and restorescreen

drawscreen

drawwait

Working With the Screen Commands

doublebuffer

the topscreenroutine subroutine

Setting Palettes

zoneheight

screenheight

adjustvisible

incgraphic

incbanner

newblock

plotsprite

plotbanner

Notes on Use of Characters

characterset

plotchars

plotmap

plotmapfile

plotvalue

peekchar

pokechar

lockzone

unlockzone

shakescreen

memcpy

memset

Sprite Collisions with boxcollision

Joystick Controls

joyxany

Driving Controls

Keypad Controls

Mouse Controls

Console Switches

Reset, Select, & Difficulty Switches

pausing

Direct TIA Sound

tsound

TIA Sound Registers

Direct POKEY Sound

psound

POKEY Sound Registers

TIA and POKEY Sound Effect Driver

Music Tracker

Enabling the Tracker

Instrument Data

songdata

Labels

Track and Song Modifiers

TIA Key Mapping

Note Data

Drum Note Data

playsong

stopsong

AtariVox Voice Support

High Score Support

Saving Game Memory

Feature Modules

Conditional Compilation and Compiling Message Output

Assembly Language

inline assembly

Including External Assembly

Inlining External Assembly

Installing 7800basic

Compiling Your 7800basic Code

On Windows

On OS X or Linux

Files Produced by Compilation

Page last updated on: 2020y_05m_09d_2142t

This document is meant as an introduction to the 7800basic language command structure and syntax. It’s not meant as a general programming primer.

 

 

 

About This HTML Page

This page is based on the 7800basic PDF file created by RevEng. You can download the latest version of 7800basic and the 7800basic Developers Guide (PDF) through a link at AtariAge.

 

 

Table of Contents and Index

There is a table of contents and an index on this page to help you find what you are looking for as quickly as possible.

 

 

Link Colors

Links that jump to other places on this page are blue. Links that lead to other pages online are red.

 

 

 

 

 

Introduction

7800basic is a programming language that can be used to create games for the Atari 7800 game console. It differs from the majority of BASIC languages in that it compiles your source code into fast 6502 machine language code.

 

7800basic is based on the Atari 2600 programming language batari BASIC, so if you’re familiar with bB, you’ll be right at home with 7800basic.

 

7800basic is designed to put as much control as you want in your hands, so if you’re familiar with 6502 assembly code you can easily customize the modular framework, or mix your high level BASIC source code with your own low level assembly code.

 

If you don’t want to learn assembly language, don’t worry, you don’t need to know assembly language to produce games. Everything you need is accessible using pure BASIC.

Back to Top

 

 

 

 

 

7800 Hardware Overview

Although 7800basic handles many of the hardware details for you, it will help to have a general understanding of the hardware you’ll be developing for.

 

 

 

Formatting and Layout Features

 

Variables

Back to Top

 

 

 

 

 

Other Variable Types

Back to Top

 

 

 

 

 

Special Variables

Back to Top

 

 

 

 

 

Conditional Logic

Perhaps the most important statement is the if…then statement. These can divert the flow of your program based on a condition. The basic syntax is:

 

if condition then action

action can be a statement, label or line number if you prefer. If the condition is true, then the statement will be executed. Specifying a line number or label will jump there if the condition is true. Put into numerical terms, the result of any comparison that equals a zero is false, with all other numbers being true.

 

There are three types of if…then statements.

 

1. Simple True/False Evaluation

The first type is a simple check where the condition is a single statement.

 

The following example diverts program flow to line 20 if a is anything except zero:

   if a then 20

This type of if…then statement is more often used for checking the state of various read registers. For example, the joysticks, console switches, single bits and hardware collisions are all checked this way.

   if joy0up then x = x + 1

That will add 1 to x if the left joystick is pushed up.

   if switchreset then 200

Jumps to line 200 if the reset switch on the console is set.

   if collision(player1,playfield) then t = 1

Sets t to 1 if player1 collides with the playfield.

   if !a{3} then a{4} = 1

Sets bit 4 of a if bit 3 of a is zero. See Bitwise Variables for more information about using single bits.

 

 

2. Simple Comparison

A second type of statement includes a simple comparison. Valid comparisons are = , < , >, <=, >=, and <>.

   if a < 2 then 50
   if f = g then f = f + 1
   if r <> e then r = e

 

3. Compound Statement

The third type of if…then is a complex or compound statement, that is, one containing a boolean AND (&&) operator or a boolean OR (||) operator. You are allowed only one OR (||) for each if…then statement. You can use more than one AND (&&) in a line, but you cannot mix AND (&&) and OR (||).

   if x < 10 && x > 2 then b = b - 1
   if !joy0up && gameover = 0 then 200
   if x = 5 || x = 6 then x = x - 4

Warning: Using multiple if…thens in a single line might not work correctly if you are using boolean operators.

Back to Top

 

 

 

 

 

Code Organization and Flow Control

Back to Top

 

 

 

 

 

Program Configuration

7800basic has a series of “set” commands you may use to customize the 7800basic environment configuration. These should be at the top of your program, prior to other commands.

 

 

Back to Top

 

 

 

 

 

Graphics Commands

Back to Top

 

 

 

 

 

Joystick Controls

Two-button joystick controls are the default in 7800basic. If you’ve switched from joysticks to another controller, you may switch back with the changecontrol statement, specifying controller port 0 or controller port 1.

   changecontrol 0 2buttonjoy

The 2buttonjoy mode will work with one button sticks, but if you prefer to force a single-button mode, you can do so with changecontrol.

   changecontrol 0 1buttonjoy

Joysticks are read by using an if…then statement. There are four directional functions and two fire button functions for each joystick.

   if joy0up then y = y - 1
   if joy0down then y = y + 1
   if joy0left then x = x - 1
   if joy0right then x = x + 1
   if joy0fire0 then goto __Purple_Monkey
   if joy0fire1 then goto __Aqua_Monkey

These can also be inverted using the ! token. For example:

   if !joy0up then goto __Tasty_Pilgrim

If a 2600 style single-button joystick is plugged in, the joystick button is read through joy0fire1.

 

 

If you wish to see if a joystick was used at all, you can check joy0any or joy1any:

   if joy0any then goto __Player_Moved

Back to Top

 

 

 

 

 

Driving Controls

Atari 2600 style driving controls can be used with 7800basic. To enable them for your game, use the changecontrol command in your program code, specifying controller port 0 or port 1.

   changecontrol 0 driving

7800basic will then read the driving controller for you, every frame. To adjust your sprite’s position, just add the drivingposition0 (controller port 0) or drivingposition1 (controller port 1) to your sprite’s position variable. Once you’ve done this, be sure to clear the drivingposition variable, or else your sprite will continue to move without any additional rotation of the controller.

   player0x=player0x+drivingposition0 : drivingposition0=0

Back to Top

 

 

 

 

 

Mouse Controls

Either Atari ST or Amiga mice can be used with 7800basic. To enable them for your game, use the changecontrol command in your program code, specifying controller port 0 or port 1.

   changecontrol 0 stmouse

   changecontrol 0 amigamouse

7800basic will then read the selected mouse every frame, and adjust the mousex0 and mousey0 variables (controller port 0) or mousex1 and mousey1 variables (controller port 1). You can use these variables as-is, though you may also wish to limit their range by testing them with if…then and change the variable as needed.

Back to Top

 

 

 

 

 

Keypad Controls

Atari 2600 keypad controls can be used with 7800basic. To enable them for your game, use the changecontrol command in your program code, specifying controller port 0 or port 1.

   changecontrol 0 keypad

Keypad controllers are read by using an if…then statement to test for key presses. Here’s an example of testing if button “3” is being pressed.

   if keypad0key3 then goto __Handle_Key_Press_3

The keypad 0 buttons can be read with keypad0key0 through keypad0key9, keypad0keys (star), and keypad0keyh (hash).

 

The keypad 1 buttons can be read with keypad1key0 through keypad1key9, keypad1keys (star), and keypad1keyh (hash).

 

The keypad data is also encoded as bits in the variables keypadmatrix0a-keypadmatrix0d and keypadmatrix1a – keypadmatrix1d.

 

Back to Top

 

 

 

 

 

Console Switches

Back to Top

 

 

 

 

 

Direct TIA Sound

TIA is the sound chip in the 7800. If you’re creating a game that has no extra soundchip on the circuit board, you’ll be making all of your sounds by manipulating TIA. You can do so by playing TIA data with the playsfx command, or by manipulating the TIA registers directly.

 

 

Back to Top

 

 

 

 

 

Direct POKEY Sound

7800basic is able to access the POKEY sound chip, if the chip is provided either on the cartridge or through add-on hardware. To enable this access, use the following line near the top of your BASIC program.

   set pokeysupport on

You can check to see if a POKEY chip was detected in the following manner.

   if pokeydetected then gosub playmypokeysong else gosub playmytiasong

 

 

Back to Top

 

 

 

 

 

TIA and POKEY Sound Effect Driver

7800basic has an advanced sound driver that greatly simplifies adding both TIA and POKEY sound effects in your game.

   playsfx soundata [offset]

The optional offset parameter allows you to raise or lower the pitch of the played sound. If you have a sound which is often repeated, it’s recommended that you vary its pitch a bit randomly.

   temp7=rand&3 : rem set temp7 to a random number from 0-3
   playsfx sfx_lasershot temp7

When you play a sound, the sound driver will automatically choose between the two available sound channels based on which channels are already being used by the driver, and if both channels are being used it will interrupt one of the playing sounds based on a priority system.

 

Before playing a sound with playsfx, you’ll need to define the sound effect data in the expected format. The data format 7800basic works with is composed of three parts, a header, the sound data itself, and an end-of-sound marker.

 

The header consists of 3 bytes:

 

The sound data then consists of 3 byte chunks, each of which represents the Sound Frequency, Control/Waveform, and Volume to play. The sound driver will continue to play the sound data until it reaches an end of sound marker, which consists of 3 zero bytes.

 

Here’s an example TIA sound, which simulates the sound effect when jumpman jumps a barrel in Donkey Kong. There are 5 chunks of sound data, and each chunk plays for 5 frames.

   data sfx_jumpman
   16, 5, 4 ; version, priority, frames per chunk
   $1E,$04,$08 ; 1st chunk of freq,channel,volume data
   $1B,$04,$08 ; 2nd chunk
   $18,$04,$08 ; 3rd chunk
   $11,$04,$08 ; 4th chunk
   $16,$04,$08 ; 5th chunk
   $00,$00,$00 ; End Of Sound marker
end

If you wish to constrain the sound driver to only using the first sound channel when playing TIA sounds, you can use the “set tiasfx mono” statement.

Back to Top

 

 

 

 

 

Music Tracker

7800basic has a music tracker you can use to automatically play song data, with options to select tempo and number of repetitions.

 

The music tracker requires that you provide instrument data and song data.

 

 

Back to Top

 

 

 

 

 

AtariVox Voice Support

You can send speech data to the AtariVox via the speak command.

   speak speechdataname

See the speechdata command and set avoxvoice on for more information.

Back to Top

 

 

 

 

 

High Score Support

7800basic supports high score tables for up to 4 different difficulty levels in your game. The actual device used to store the tables can be an Atari 7800 High Score Cart, AtariVox, or SaveKey device.

 

To incorporate high score support in your game, you first need to enable high score support. Pick a unique 4 digit hex value to identify your game...

   set hssupport $1234

When your game is nearing completion, you can reserve your chosen number by announcing it in this AtariAge thread: https://atariage.com/forums/topic/128432-high-score-cart-values/

 

You also need to include the high score font graphic in your game. It can go in any graphics block, but must be the first graphic imported in its block. Note that you need to use 320A mode for the high score graphic, even if your game uses a different mode.

   incgraphic hiscorefont.png 320A

Before trying to display a high score table, you need to set the game difficulty level variable from 0 to 3, which represents easy, intermediate, advanced, and expert levels.

   gamedifficulty=2

If your game has no difficulty levels, you can leave gamedifficulty at the default of 0. You can then display the current high score table, without allowing high score entry with the command...

   drawhiscore attract

When a single player game is over, and you them to have the chance to enter their initials, you can use the command...

   drawhiscore single

Or with a two player game, you can use the following command to allow the first player to enter initials...

   drawhiscore player1

And as you might expect, the second player has a similar command...

   drawhiscore player2

The drawhiscore command will erase the currently drawn screen, savescreen buffer, and the color palettes, so you’ll need to draw a new screen after issuing this command.

 

It’s also noteworthy that drawhiscore command allows the high score display to be interrpted by pressing the joystick fire button. The command may exit with the user holding the fire button down, so you may need to account for that in your basic code.

 

If you want the players’ scores to be provided a descriptive ranking, you can use the “set hsgameranks” command. Scores should be ordered from biggest to 0...

   set hsgameranks 30000 commander 10000 lieutenant 0 ensign

If the player’s score variable didn’t beat any recorded scores, the high score routines will just diplay the table, and the ranking description if you’ve enabled that functionality in your game.

 

If you have AtariVox speechdata named “vox_highscore”, the AtariVox will say the speech once while the player enters a high score.

 

If you have sound effect data named “sfx_highscore”, the sound effect will play once while the player enters a high score.

 

If you have a tracker song named “song_highscore”, the song will play once while the player enters a high score.

 

There are various “set” commands that change the behavior of the high score tables. See the Program Configuration section for more details.

 

Lastly, if you wish to detect which device is being used, you may check the hsdevice variable:

   0=no device, 1=High Score Cart, and 2=AtariVox/SaveKey

Back to Top

 

 

 

 

 

Saving Game Memory

7800basic supports saving and loading up to 25 variables to any detected High Score device. You will need to include high score support in your game, as demonstrated in the previous High Score Support section. If you only wish to save game memory and not display high score tables, you may omit importing the high score font.

 

The data will be saved in an unused difficulty level’s area. To inform 7800basic of this, we set the gamedifficulty variable.

   gamedifficulty=3

From there we call the savememory command to save your variables.

   savememory playerx playery playerroom playerworld

If the variables are dim’ed consecutively in memory, you may list them as a range.

   savememory playerx-playerworld

Loading previously save variables is done with the loadmemory command, which also accepts both forms of variable listing that the savememory command uses.

   loadmemory playerx playery playerroom playerworld

   loadmemory playerx-playerworld

If your game is also displaying high score tables, be sure to restore the gamedifficulty variable to its original value after loading/saving data.

Back to Top

 

 

 

 

 

Feature Modules

7800basic has a lot of options to interface with external hardware, and there isn’t enough space in the 7800basic’s reserved 4k area to hold all of the feature modules required. If you get a message about this area having negative space during compiling, it means you need to store the modules elsewhere in your game.

 

You can do so with the “inline” keyword at the location where the module can go. At present time you can do this for the atarivox, pokey support, and sound tracker modules.

   inline 7800vox.asm
   inline pokeysound.asm
   inline tracker.asm

Avoid putting these statements directly in the path of your own code flow, since they’re not meant to be executed directly.

Back to Top

 

 

 

 

Conditional Compilation and Compiling Message Output

7800basic has a few commands that let you easily enable or disable code blocks. This allows you to build a few different custom ROM images from just a minor change to a constant value in your source code.

 

These commands are #ifconst, #else, and #endif, and can be used in the following fashion.

   const officialrelease = 1
   
   [a bunch of common game code would go here]
   
   #ifconst officialrelease
     plotbanner officialbanner 0 0 0
   #else
     plotbanner demobanner 0 0 0
   #endif

There’s also an echo command which you can use to display messages, or the values of constants, when the ROM is compiled.

   echo " "
   const airblockstart = <chars_air
   const airblockend = airblockstart+chars_air_width-1
   echo "TILES: airblockstart:",airblockstart," airblockend:",airblockend
   echo " "

The #ifconst, #else, #endif, and echo commands are all passed directly from your 7800basic source code to the dasm assembler, which is responsible for their function. If you wish to learn more about them, you can reference the documentation for dasm.

Back to Top

 

 

 

 

 

Assembly Language

7800basic allows you to incorporate your own assembly language routines into your BASIC code in a few different ways.

 

 

Back to Top

 

 

 

 

 

Installing 7800basic

7800basic is distributed as a single zip file. Download the latest zip file and unzip to whichever location you desire to use. Make sure your unzip utility creates the expected subdirectories (/docs, /includes, …) rather than sticking all of the files into one directory.

 

Windows users should double-click and the provided install_win.bat file. OS X and Linux users should run the install_ux.sh script.

 

In both cases, just follow any instructions presented by the installer.

Back to Top

 

 

 

 

 

Compiling Your 7800basic Code

7800basic is a command-line program, so these instructions will cover how to compile your BASIC programs using the command-line. If you’re uncomfortable with BASIC command-line usage for your OS, you may wish to read up on it a bit first.

 

 

 

Index

Back to Top

 

 

In Case You Didn’t Know

 

B Vitamins = Good

Some people appear to have a mental illness because they have a vitamin B deficiency. For example, the wife of a guy I used to chat with online had severe mood swings which seemed to be caused by food allergies or intolerances. She would became irrational, obnoxious, throw tantrums, and generally act like she had a mental illness. The horrid behavior stopped after she started taking a vitamin B complex. I’ve been taking #ad Jarrow B-Right for many years. It makes me much easier to live with.

 

 

Soy = Bad

Unfermented soy is bad! “When she stopped eating soy, the mental problems went away.” Fermented soy doesn’t bother me, but the various versions of unfermented soy (soy flour, soybean oil, and so on) that are used in all kinds of products these days causes a negative mental health reaction in me that a vitamin B complex can’t tame. The sinister encroachment of soy has made the careful reading of ingredients a necessity.

 

 

Wheat = Bad

If you are overweight, have type II diabetes, or are worried about the condition of your heart, check out the videos by William Davis and Ivor Cummins. It seems that most people should avoid wheat, not just those who have a wheat allergy or celiac disease. Check out these books: #ad Undoctored, #ad Wheat Belly, and #ad Eat Rich, Live Long.

 

 

Negative Ions = Good

Negative ions are good for us. You might want to avoid positive ion generators and ozone generators. Whenever I need a new air cleaner (with negative ion generator), I buy it from surroundair.com. A plain old air cleaner is better than nothing, but one that produces negative ions makes the air in a room fresher and easier for me to breathe. It also helps to brighten my mood.

 

 

Litterbugs = Bad

Never litter. Toss it in the trash or take it home. Do not throw it on the ground. Also remember that good people clean up after themselves at home, out in public, at a campsite and so on. Leave it better than you found it.

 

 

Climate Change Cash Grab = Bad

Seems like more people than ever finally care about water, land, and air pollution, but the climate change cash grab scam is designed to put more of your money into the bank accounts of greedy politicians. Those power-hungry schemers try to trick us with bad data and lies about overpopulation while pretending to be caring do-gooders. Trying to eliminate pollution is a good thing, but the carbon footprint of the average law-abiding human right now is actually making the planet greener instead of killing it.

 

Watch these two YouTube videos for more information:

CO2 is Greening The Earth

The Climate Agenda

 

 

Hydrofracking = Bad

Hydrofracking is bad for you, your family, your friends, and the environment.

 

 

Hydroxychloroquine = Good

Although some people with certain conditions may not be able to take it, hydroxychloroquine is a cheap drug that has been prescribed by doctors since the 1950s and it seems to be helping many people who have COVID-19 when administered early enough. (Hydroxychloroquine is also supposedly safe and tolerable as an anti-cancer therapy.) Seems like most news sources are going out of their way to make it sound like hydroxychloroquine is the most dangerous drug in the world, but they also make it sound like it’s the greatest drug in the world for lupus and rheumatoid arthritis patients. They basically say that using hydroxychloroquine for COVID-19 patients would be taking that great and wonderful drug away from the other patients who need it. So which is it? Is hydroxychloroquine deadly or divine?

 

If you believe that a couple of Trump supporters took the medicine hydroxychloroquine and it’s President Trumps fault that the husband died, you’ve been duped. Watch this video. The wife was a prolific Democratic donor, it seems she hated her husband, she used fish tank cleaner (not the medicine hydroxychloroquine), and now she is the subject of a homicide investigation.

 

Some people claim that the reason so many news sources want to keep doctors from using hydroxychloroquine for COVID-19 is that they are desperate to keep everyone afraid to leave their homes since mail-in voting will make voter fraud much easier (the only way they could beat Trump). Others claim that the rabid anti-hydroxychloroquine campaign was to make way for the expensive new drug called remdesivir. Drug companies can’t make much money with old generic drugs, so new drugs must be pushed. Both claims could be true since remdesivir supposedly isn’t as good as hydroxychloroquine.

 

According to Dr. Shiva Ayyadurai, hydroxychloroquine does four things: (1) stops viral entry, (2) stops viral RNA replication, (3) stops viral particle assembly, and (4) stops cytokine storm. Remdesivir only stops viral RNA replication. Did you get that? Hydroxychloroquine does four things and remdesivir only does one. The doctor also said that nearly 70 percent of the people who took remdesivir had some type of adverse effect. If all of that is true and the more anemic medicine ends up being used by most doctors thanks to the smear campaign against hydroxychloroquine, the average American will beg to vote from home.

 

In case you didn’t know, Patrick Howley reported that one of the authors of the ‘study’ saying that hydroxychloroquine doesn’t work at VA hospitals got a research grant from Gilead (the company that makes remdesivir). Does that seem a little fishy to you?

 

Bryan Fischer said in an article that Dr. Fauci has known since 2005 that chloroquine is an effective inhibitor of coronaviruses. You might also want to check out the following three links:

The REAL Truth about Dr. Fauci, Remdesivir and Hydroxychloroquine!

Chloroquine Is a Potent Inhibitor of SARS Coronavirus Infection and Spread (2005)

Sequential CQ / HCQ Research Papers and Reports

 

“The Disruptive Physician” had this to say at Twitter: “Meanwhile, regular doctors like me are using HCQ + Azithromycin and Zinc to good effect. One nursing home in NE Ohio had 30 cases - started everyone on HCQ, no deaths. Quick recovery. Why would the MSM hide this? Why would twitter block people who question the WHO?” You might also want to check out Dr. Stephen Smith, Dr. Ramin Oskoui and Dr. Yvette Lozano.

 

In case you’re interested, here are a few COVID-19 patients who appear to claim that hydroxychloroquine saved their lives: elderly couple Louis Amen and Dolores Amen, Daniel Dae Kim, Rio Giardinieri, John McConnell, Margaret Novins, Jim Santilli, Billy Saracino, and Karen Whitsett (Democratic member of the Michigan House of Representatives).

Disclaimer

View this page and any external web sites at your own risk. I am not responsible for any possible spiritual, emotional, physical, financial or any other damage to you, your friends, family, ancestors, or descendants in the past, present, or future, living or dead, in this dimension or any other.

 

Use any example programs at your own risk. I am not responsible if they blow up your computer or melt your Atari 7800.

 

Home Inventions Quotations Game Design Atari Memories Personal Pages About Site Map Contact Privacy Policy Tip Jar