SuperCharger Disk BASIC Manual ------------------------------ SuperCharger Disk BASIC is so close to Flashback BASIC the same manual can be used and most programs can be cross compiled with few changes. Important differences are: 1. Unlimited variable arrays may be declared in addition to constant arrays. 2. Variable arrays for the virtual world and sprite objects remain, however the variable arrays for the player and sprite colors no longer occupy the first 1.5 rows of the virtual world so you can scroll over that area without seeing the color data. 3. Flashback BASIC allows multiple Virtual Worlds, SuperCharger Disk BASIC allows multiple programs (see DOS commands in chapter 16). CONTENTS: ----------------------------------------------------------------------- 0. Introduction to Virtual World BASIC 1. Virtual World BASIC Syntax 2. Virtual World BASIC Commands 3. Fun with variable arrays and strings! 4. Redefining part of a sprite 5. Printing strings with the print command 6. Storing ASCII Text in data statements 7. Scrolling text through sprites or the screen 6. Array transformations 7. Raising an event and Chiptunes (also events) 8. Compiling your program manually 9. Using the Visual IDE 10. Debugging your programs 11. Load Balancing 12. Resources, Examples and Tutorials 13. Old-School BASIC mode 14. Display List Interrupts 15. Multicolor playfields, sprites, DLI zones 16. Multiple virtual worlds (Flashback BASIC only) 17. Padding small programs (Flashback BASIC only) 18. Stella compatibility settings (Flashback BASIC only) 19. DOS commands (SuperCharger Disk BASIC) 20. Sharing variables between BASIC programs (SuperCharger Disk BASIC) ----------------------------------------------------------------------- Introducing Virtual World BASIC ------------------------------- Virtual World BASIC allows you to create games in BASIC for the Atari 2600 that take place in a virtual world much larger than the Television screen. You have a playfield camera to pan about the virtual world, and sprites which you can bind to virtual world pixels (tile mapping). And, off-screen virtual collision detection. You design the large virtual world by "drawing it" with ASCII art in your BASIC program. You draw the sprite graphics that way too. The BASIC also has a chiptune engine - You define chip tunes that repeat in the background and for specific game events in a table just below your ASCII art. Virtual World BASIC is designed for programmatically and visually manipulating arrays, graphics and binary strings. The virtual world contains thousands of pixels that you control programmatically with the vwpixel command. The playfield camera view links relationally to the virtual world and shows a 200 tile pixel view (20x10) on the Television screen whenever you change the cam coordinates. vwBASIC's objects can all be addressed as arrays in BASIC, and you can define hundreds of additional variables as named arrays. Setting up ---------- Extract the files to c:\vwBASIC (You can create a different folder but you will have to edit the paths in the compiler script). Now just edit the program.txt file, it's loaded with a sample program you can modify or use as a guide to write new programs. Note: for Atari Flashback BASIC, you still want to use the vwBASIC directory; if you have vwBASIC already installed just put the Atari Flashback BASIC files in the same directory - they do not conflict with one another and can cross-compile the same BASIC programs with very vew changes. vwBASIC language syntax ----------------------- Almost pure TinyBASIC a-z variables (a,b,c,d are temp variables) and array variables (see chapter 3). simple expressions with no parenthesis. 100 e=5*n is ok, but "e=5*n-3" must be written as two statements: 100 e=5*n:e=e-3 bitwise operators: ^ xor, & and, | or. number prefixes: none - decimal(255), % binary (%11111111), $ hex ($ff) Modulus remainder is stored in temp variable b after division. if then else ------------ if then else is supported in BASIC horizontal format: 10 if e>=5*n or g*2=r-3 then e=10:i=17 else i=33:e=e+2 Note: You cannot mix and and or in the same if statement (use another if). If must always be the first statement in a line. Language commands: ------------------ vwpixel - sets, flips, polls virtual world pixels and binds sprites to the virtual world. Examples: 10 vwpixel(0,0,on):rem turn on upper left pixel in the virtual world. 20 vwpixel(x,y,flip):rem flip the virtual world pixel at x,y. 30 if vwipxel(5,5,poll)>0 then COLUBK=255:rem change background color if virtual world pixel 5,5 is on. 40 vwpixel(5,5,bindplayer0):rem bind sprite to virtual world pixel 5,5. 45 player0x=player0x+3:player0y=player0y+2: fine grain control Line 45 shows the fine grain coordinate system variables for the sprite which get set by vwpixel; you can adjust them for fine grain movement between tiles. 10 Loadplayer0(8): rem load second sprite definition from library ------------------------------------------------------------------ Loads the player 1 sprite with a definition (8 rows of 8 pixels) from the sprite library, starting at the specified index of 8. 20 loadplayer1upsidedown(0): rem load first sprite def from library -------------------------------- Loads the player 2 sprite from the sprite library, flipped upside down. You have control over horizontal flip via TIA system var REFP0: 10 REFP1=255:rem flip player 2 horizontally reading the joysticks --------------------- Joysticks are read using friendly named variables that return 1 or 0: 10 if joy0left=1 then f=3: rem joystick 0 pushed left 20 if joy1fire=1 then f=4: rem joystick 1 botton pressed data statements --------------------- Named variable arrays are declared and initialized in data statements: 90 rem create boats data array, dimension and initialize 100 data boats 1,3,2,3,2,4,7 read --------------------- 110 read i(boats,j):rem read element j from boats array into i. 120 i=boats(j):rem read element j from boats array into i. 130 boats(i)=boats(j): rem assign one array element variable to another. write [alias: print] ------------------------ 120 print %11111111(player0,0):rem print to top row of player 1 sprite. 130 write i(boats,j):rem write value i into boats array at element j. 140 boats(j)=5:rem standard BASIC array syntax is also supported 150 boats(j)=boats(x)*5:rem BASIC array manipulation For Next loops --------------------- 10 rem nested looping, inner/outer example: 20 for x= 3 to 5: for y = 12 to 2 step -2: vwpixel(x,y,on): next y,x goto gosub return --------------------- 10 if e=33 then gosub 100 else goto 200 20 goto 200 100 e=33:return 200 rem fun with vwBASIC variable arrays and strings! ---------------------------------------------- vwBASIC has a small number of predefined variables in low RAM (e-z,var1,var2,px,py,bx,by and score) and virtually unlimited named variable arrays. vwBASIC lets you declare and initialize named variable arrays in data statements: 100 data boats 1,3,2,3,2,4,7 Manipulating array variables: ------------------------------------ 110 i=boats(0): rem store the first element of boats in i. 120 boats(0)=i+1: rem store i+1 in the first element in boats. 130 boats(0)=boats(3)*2: rem assign one element to a multiple of another An alternate array syntax is also supported: 110 read i(boat,0):rem read 1st element of boats into i 120 write i(boats,1):rem write i into 2nd element of boats array. You can add as many named arrays as you wish. If you reach a total of 255 total element variables for all of your arrays combined, you must start a new array. You can then continue building arrays until 256 additional element variables are reached (255+256 total) and then must start a new array again. It is possible to have over 1,000 bytes of array variables in this manner if you desire it. This is unlikely, but when you're used to working with 26 variables just declaring an extra 50 gives you much more flexibility to code. Nearly all of the abstract objects in vwBASIC are arrays or multidimensional arrays. If you look at the ASCII art definition for the virtual world and the sprite library, they are binary tabular arrays you can work with visually or programmatically - the virtual world contains 2,000 binary variables and each sprite definition contains 64. vwBASIC has special commands like vwpixel to address the individual bits in the virtual world, and a load sprite function that reads 8 binary strings out of the sprite library (comprising an 8x8 sprite image) to load one of the system sprite tables, player0 and player1. Visually redefining part of a sprite: ------------------------------------- 10 print %11111111(player0,0) 20 print %11000011(player0,1) 30 print %11111111(player0,2) We just printed three rows of pixels on the player1 sprite, which has 8 rows. Built in functions loadplayer0(n) and loadplayer0upsidedown(n) contain loops that read 8 rows of the sprite library starting at index n and load the player sprites much like this - you can write similar functions in vwBASIC. Printing strings on the world with the PRINT@ command: ------------------------------------------------------- You can poll,flip or set the individual pixels or bind the sprites to them with vwpixel but you can also print a binary string to the virtual world, 8 bits at a time much like the BASIC PRINT@ command. print %10101010(virtualworld,3) --------------------------------------- Prints the binary pattern block at the position of the 3rd byte - the table is 12 bytes accross to hold the 92 pixel wide virtual world, and 20 bytes deep, as per it's ASCII art definition. You can calculate the @ index by multiplying rows x 12 (row length) and adding to find the target byte column. Note: the first byte in each row is partially obscured. Sample program using the print command to visually illustrate bitwise operators: 5 rem Fun with SuperCharger BASIC on the Atari 2600! 7 rem using the BASIC print command with binary strings 8 rem to print output to the screen using the 9 rem bitwise operators & and, ^ xor, | or , + plus, - minus 10 i=%11111111 & %00001111 + %00100000:rem expect 00101111 20 k=%11111111 | %00001111:rem expect 11111111 30 j=%11111111 ^ %00001111 - %01000000:rem expect 10110000 40 l=%11111111 50 print i(virtualworld,1) 60 print k(virtualworld,13) 70 print j(virtualworld,25):print l(virtualworld,37) 90 vwpixel(13,1,flip):rem flip or set a single pixel 100 if g=0 then g=1:scrollvirtualworldtoggle=1 storing ASCII text in data statements ------------------------------------- ASCII text can be easily stored in Data statements with BASIC: 10 data mydata "this is ASCII text" Scrolling ASCII text through the sprites or the screen (or DLI zones) --------------------------------------------------------------------- The WARPDRIVE game includes a lot of text in data statements and shows how BASIC can be used to read the ASCII text and scroll it full size through the screen - as a fun BASIC exercise, try modifying the different messages in the game! Array transformations --------------------- The above works because all arrays, regardless of the number of dimensions or type, may also be accessed as a single dimensional byte array. You can also read past the end of one array into the next array: 100 i=array1(7):rem can read past boundary into the next array 105 data array1 5,6,7,8 110 data array2 1,2,3,4 The utility in the example above is that you can use the two 4 element arrays individually and combine them as one 8 element array when needed. *You can assign one arrays elements to another and reference transformations in expressions just like with scalar variables: 10 array1(n)=array2(3)*7 30 rem BASIC array manipulation syntax *Note: With ATARI FLASHBACK BASIC you can only assign to the built in RAM variable arrays virtualworld, player0, player1, rowcolors and player0colors (the last two overlap the virtualworld, occupying the first 1.5 rows); Every named array you declare is a a constant array (read only). Double Buffering in RAM ----------------------- While virtualworld is the system table array for the virtual world, there is another system table array for the playfield camera, RAMplayfield. This is another buffer that can be modified independently of the virtual world for special effects and a higher resolution playfield. There is no physical object to draw with ASCII art for this table as there is for the virtualworld, because the table is linked relationally and populated from a coordinate view section of the virtual world whenever you raise an event or a DLI. Relational Database core ------------------------ Commands like vwpixel modify both 2D binary system tables when their coordinates overlap using relational calculus behind the scenes as does raising an event, which creates a playfield camera view table from anywhere within the virtual world table as described below - the playfield CAM is like a sheet of glass that you can annotate and then just wipe off by raising an event or a DLI without moving the camera. Raising an event ---------------- Raising an event causes the camera view to refresh at the virtual world coordinates specified by XIndex and BYTErowoffset (system variables for the playfield CAM). XIndex is the CAM's x coordinate, and BYTErowoffset is the CAM's y*12 coordinate. You can raise an event anytime you want by flipping on the system variable to scroll the virtual world: 10 scrollvirtualworldtoggle=1 Raising an event also runs whatever code you've got in the Kitchen sink section using a larger time window to run code - more time than there is in either of the gameloop sections so it's a good place for a long running routine. The event variable is automatically toggled back off (set to 0) until you set it again to raise another event. Note that events should only be raised conditionally; there is usually no need to raise an event to refresh the playfield camera view unless it's virtual world coordinates have changed, doing so constantly will result in flicker. chiptunes --------- below the ASCII art, there is a table for chiptunes: chiptunes 7,30,0,0,8 7,24,0,0,8 7,20,0,0,8 7,24,0,0,7 30,0,0,30,0 10,20,5,11,25 7,7,6,5,20 6,4,4,6,10 0,0,0,0,0 The chiptunes table works like this; each line contains data for both voices of the Atari sound chip and a common duration: frequency, channel, frequency, channel, duration Music is processed through an fx engine that changes the sound envelope. The chiptunes table is designed to hold multiple chiptunes; a repeating main theme and multiple sub themes which return control to the main theme. In this example the first song loops after it reaches a duration of 0 (line 5). Playing the next tune --------------------- Setting the music index (system var MUSICINDEX) to 5 will start the player at the following line (line 6), the second theme in this case. The second theme only plays once - when it reaches a duration of 0 (line 9) it goes back to playing the main theme. There is another system variable SUSTAINFORFRAMES that holds the duration value and can be overridden for sound effects along with the channel and frequency variables AUDC0/AUDC1 and AUDF0/AUDF1. Compiling your program manually ------------------------------- First make sure your program is saved as c:\vwBASIC\Program.txt Next compile your program with the vwBASIC compiler: Run the vwBASIC_compiler.ps1 script from the shell or command line; it will take the basic program in c:\vwBASIC\Program.txt and compile it into c:\vwBASIC\Program.asm. Note: If you are using Atari Flashback BASIC, run the ATARI_FLASHBACK_BASIC_compiler.ps1. Note: If you get a message you cannot run the compiler powershell script, you need to enable scripting: set-executionpolicy -scope CurrentUser -ExecutionPolicy RemoteSigned Next, assemble your Assembly output file into a ROM binary with dasm*. from the command line: dasm c:\vwBASIC\program.asm -oc:\vwBASIC\Program.bin -f3 If there are no BASIC errors (unhandled lines are OK), the compiler will automatically complete this step for you. If you wish to manually override, you can still compile a program with BASIC errors. *dasm is included, if your system requires a different version get it here: http://dasm-dillon.sourceforge.net/ Launching BASIC Programs in the emulator automatically ------------------------------------------------------- The compiler is configured to launch the ROM in the Atari Emulator (Stella) upon successful compile. You can also launch your basic programs in the IDE by pressing the Play button. Create the subdirectory "c:\vwBASIC\Stella and place a copy of Stella.exe and it's DLL's there. If you do not already have the Stella emulator you can download it from http://stella.sourceforge.net/ (You can also place a copy of Z26.exe or another emulator and rename it stella.exe) You can also play the ROM binary on real Atari hardware with a ROM flashcart or a custom built cartridge, or SD cart for the Atari Flashback Portable. Putting games on Tape and CD - Virtual World BASIC only: The makewav.exe utility for creating WAV files for Tape, compact disc or iPod for the SuperCharger or Cuttle Cart is included. The syntax is: makewav -ts Program.bin Using the Visual IDE (NEW! Now integrated) -------------------------------------------- The Windows Powershell ISE is an excellent visual IDE for vwBASIC: It's included or free with your Windows OS and Linux. On Windows you can launch it directly from Administrative tools or by running powershell_ise.exe. 1. Go to Start Menu and search for "Windows PowerShell ISE". Right click and choose "Run as administrator". 2. In the top part, paste "Set-ExecutionPolicy RemoteSigned" run the script. Choose "Yes". Note: This is completely safe and will not open your system up to malicious script execution because the default scope is local-machine and your user account that you browse the web with cannot run powershell scripts unless an alternate method is used - and then it must ask your permission first. 1. Load the PowerShell ISE and select the "show script pane right" icon to configure your environment. 2. Load the c:\vwBASIC\vwBASIC_Compiler.ps1 compiler script (or ATARI_FLASHBACK_BASIC_Compiler.ps1 of you are using Atari Flashback BASIC). 3. Load any BASIC program (.bas or .txt file, the IDE always selects the left most one to compile) 4. Edit the program and save your changes. 5. Select the vwBASIC_Compiler.ps1 tab and press Play to compile and launch in Stella: You'll see the Assembly output flowing through the left pane as the compiler is working. Click the Program.txt tab to review your code alongside it's Assembly output; the scrollbars let you match up the code. When the compiler finishes, it either presents an error report showing what program lines need to be fixed, or launches your ROM binary in the Stella emulator (For more information about Stella, visit http://stella.sourceforge.net/). Debugging: ---------- Finding syntax errors in your code - these are the most common and frequent BASIC coding errors and easy to find! The compiler reports each Syntax Error it finds as well as unhandled lines (What?) of BASIC code it could not understand as illustrated in these examples: ;----UNHANDLED LINES FOUND: ;--------------------------------- ;--xxx-unhandled line 79: _68 COLUP0 $84 ;--xxx-unhandled line 91: _77 glob blop what ;--xxx-unhandled line 243: _189 rem----------------------subroutines: ;--xxx-unhandled line 244: _190 rem---------------------------------- ;----BASIC ERRORS FOUND, REPORT: ;--------------------------------- ;check line 90: _76 if z=2 and y<19 y=y+1 ;check line 95: _81 if z=2 and y=19 z=1 Note: Unhandled lines (What?) can often be ignored but all Errors must be fixed before your code will compile. If the compiler fails to find the error for you, DASM may locate it or it may be a complex error that is syntactically correct and requires you trace for it. Out of Memory error: Dasm provides this third type of Tiny BASIC error meaning that you are out of memory. Dasm will complain of a "reverse index" if an out of memory error occurs. You can reduce your code size or transfer some of it to the other gameloop; both gameloops can hold about 6K of BASIC code. Note that gameloop2 shares space for graphics and sound while gameloop1 shares space with named array variables. Load balancing: --------------- If the screen rolls (scanline count>262) you are doing too much in a single frame and need to load balance by either moving some of the code to gameloop2 (the other vertical blank), or running it in a different frame; a simple framecounter variable can allow you to split your code up on different branches for different frames to balance it. Remember when you are designing programs that both gameloops run every single frame or many times per second. Some system variables are write only ------------------------------------ COLUPF, COLUP0, COLUP1 and COLUBK: These are the system vars that hold the virtualworld color, the player colors and the background colors. 10 COLUP0=255:COLUP1=$FF:rem set the player colors Works, but you cannot read back from these variables. Some system arrays are read only: *Do not write to the sprite library table ------------------------------------------ It is not page aligned so doing this might break the code, the two system sprite tables player0 and player1 are the tables to write to, to update the sprites directly (and they are page aligned). If you want the sprite library to be malleable, you could define your own sprite library in binary table array variables. Ditto for not writing to the music table - it's not page aligned either. vwBASIC resources: ------------------ Random Terrain's batari BASIC pages are an excellent resource as most of the Atari write-only system variables like COLUPF,COLUP1,COLUP0 and COLUBK (pixel color, player colors, background color) are in common. And there are great tools like color lookup tables and a sound development kit where you can hear the fx you create: http://www.randomterrain.com/atari-2600-memories-tia-color-charts.html http://www.randomterrain.com/atari-2600-memories-batari-basic-music-toy.html Sample program (Tron LightCycles) ---------------------------------- The sample program provides examples of working with vwBASIC functions and language intrinsics and it's unique abilities manipulating arrays: The camera follows Player 1 about the virtual world, if the button is pressed Player 1 leaves a trail like in Tron/surround. The screen flashes whenever Player 1 drives over an existing virtual world pixel, and the pixel is erased. Player 2 can do the same things but the camera doesn't follow them - player 2 can drive off screen. Player 2's virtual world offscreen collisions can be verified by Player 1 following them with the camera. When Player 2 is leaving a trail, Player 1 becomes animated - three rows of the Player 1 sprite are mapped to the Player 2 sprite. Game and Demo Tutorials and examples ------------------------------------ Simple Single Statement Program - BASIC Programming is so easy you can start with a single statement! StarBlitz - a smooth scroller Defenderesque game where you defend the colorful Cities of Mars from Meteors, Missiles and Space Ships! KC Munchkin Monster Maze is a limited edition homebrew release that illustrates the effects you can achieve with vwBASIC and a tube Television: https://www.youtube.com/watch?v=aghqgf6qqRw This complex game example uses 50 variables - the 28 scalar variables were not enough, so another 20 array variables were utilized. It also takes advantage of preinitialization to save code space. The Breakout Adventure Tutorial illustrates the use of variable array manipulations to render scrolling objects over and within a scrolling playfield: http://atariage.com/forums/topic/240433-demo-scroller-tutorial/ Sample Program Defender III (Atari Flashback BASIC) ---------------------------------------------------- This sample program is for the Atari Flashback, though it could be compiled with the Virtual World BASIC compiler to run on the SuperCharger with a few changes. Display List Demo 5 ------------------- Shows how to set and call DLI's with very simple BASIC commands. The two gameloops where BASIC runs control the top and bottom vertical blanks respectively, allowing for alot of processing power and interesting effects with DLI's - this demo creates three seperate screen cams and scrolls the virtual world through them in different directions and illustrates binding sprites and floating them over the scrolling backgrounds. About the extra colors in the games: ------------------------------------ The Atari can exploit ideosyncracies in the NTSC signal and RF carrier to display artifact colors (multiplying the depth of the bitmap for free to get additional colors). On an antique tube Television this is a very pleasant effect. The Vader and 6-switch models of the Atari produce the strongest artifact colors and moire effects through their RF connection (they leak chroma). Virtual World BASIC lets you produce artifact colors on virtual world tile pixels and nearby sprites by choosing high luminosity colors for the tile pixels - both of the games above use an array of preselected artifact colors to produce their effects. Old-School BASIC mode: ---------------------- vwBASIC supports Old-School BASIC programming just like we did it back in the early days of home computing! No template directives are necessary, though you can add them, same for the ASCII art. It's just Old-School BASIC. All of the system resources are still there and programatically accessible just like bitd. Remember those fun BASIC type-in's in old-school programming Magazines? 9LineBlitz is a sample Old-School BASIC program you can type-in and run: --------------------------------------------------------------------------------- 0 data city 1,4,2,5,3,2,3,1,4,1,1,1,5,2,2,3,1,4,1,4,3,1,4,4,1,1,2,2,3,1,3,4,5,4,4,3,4,5,1,2,4,1,5,2,2,3,1,3,1,1,4,1 1 if g=0 then for j=0 to 7:player1(j)=189:player0(j)=pl(j):next j:BYTErowoffset=120:COLUPF=$84:COLUP0=$b4 else goto 3 2 for j=20 to 71:k=j-20:k=city(k)+14:for i=k to 19:vwpixel(j,i,on):next i,j:player0y=88:player0x=94:COLUP1=$74:y=20 9 if i<17 then i=i+1:virtualworld(i)=i*9:goto 9 else for i=19 to 239:virtualworld(i)=0:next i:rem Emulator patch 3 COLUBK=0:AUDV0=0:g=1:scrollvirtualworldtoggle=1:BITIndex=BITIndex+1:data pl 0,224,127,231,252,192,128,0:rem bitmap 4 if joy0fire=1 and y>=20 then AUDF0=6:AUDC0=8:AUDV0=15:x=BITIndex+11:y=11:i=88-player0y:i=i/10:y=y+i 5 if y<21 then vwpixel(x,y,bindplayer1):j=y-10:y=y+1:COLUP1=M(j):data M $64,$54,$b4,$a4,$32,$44,$24,$c4,$94,$f4,$54 6 if y<=19 and vwpixel(x,y,poll)>0 then vwpixel(x,y,flip):player1x=0:player1y=0:AUDC0=y:y=20:AUDF0=4:AUDV0=15 7 if BITIndex>71 then BITIndex=0:player0y=player0y-2:rem player flies lower each pass over the smoothly scrolling city 8 if CXP0FB>126 then CXCLR=0:g=0:for i=0 to 255:AUDF0=i:AUDV0=i:COLUBK=$34:next i:rem check collision, restart game There is an annual Old-School BASIC 10 Liner contest (80,120 and 256 character variety) conducted internationally here: http://gkanold.wix.com/homeputerium#!basic-tenliners-2016/c450 Notice how line 9 is out of sequence? It was added to create compatiblity with the Stella emulator and the Atari Flashback Console will also require padding for small Game programs like this one (see chapters 18 and 17). Update: The VCS placed very well in the 2016 contest, beating the C64, Speccy, ZX-81 and MSX machines! Display List Interrupts (NEW!) ------------------------------- Display list interrupts run during the vertical blank and provide the ability to split the screen up into multiple horizontal sections, each of which can contain a vertically, horizontally or diagonally scrolling playfield with free floating or tile-mapped sprites. The DLI demo programs (DLI_Demo.txt) demonstrates setting up display lists to scroll the top half of the screen vertically while scrolling the bottom half of the screen horizontally at different speeds. The demo actually uses 4 DLI calls to do this but arranges them to create two contiguous scroll zones. Syntax for calling the DLI is simple: "gosub DLI" two rows (1/5) of the screen will be updated based on the value you store in scrollvirtualworldtoggle (it's reused for DLI's; just don't use zero). Put in an 8, and the bottom two rows of the screen will be updated: 100 scrollvirtualworldtoggle=8:gosub DLI:scrollvirtualworldtoggle=0: rem call DLI, update tile rows 9 and 10. Put in a 1 and rows 2 and 3 will be updated near the top of the screen: 100 scrollvirtualworldtoggle=1:gosub DLI:scrollvirtualworldtoggle=0: rem call DLI, update tile rows 2 and 3. Trick to span three rows (about 1/3 of the screen) - use "3" as a prefix before the start row. Put in a 37 and the bottom three rows of the screen will be updated: 100 scrollvirtualworldtoggle=37:gosub DLI:scrollvirtualworldtoggle=0: rem call DLI, update tile rows 8,9 and 10. Put in a 30 and the top 3 rows will be updated. 100 scrollvirtualworldtoggle=30:gosub DLI:scrollvirtualworldtoggle=0: rem call DLI, update tile rows 1,2 and 3. It's no more complex than setting the x,y coordinates for the playfield camera to pan the view about the virtual world, you're just able to do that independantly for each section of the screen you define with a DLI! You can call a DLI from each gameloop with different camera settings; each game loop runs on one of the vertical blanks so one of your DLI calls will happen "before" (called from the top blank) the display is drawn and one will happen after the display is drawn, the one called from the bottom blank (gameloop2). DLI Overhead: 3 row DLI's will occuply most of the top vertical blank, and will barely fit in the bottom blank while 2 row DLI's leave plenty of space for your own program code in either vertical blank. Just like raising an event to scroll the entire screen, A DLI need be called only as frequently as you need to update it's target section of the screen (pan the camera for that area only). Exercises for setting up multiple DLI's and setting their animation rates: 1. Increase the scrolling speed of the top half of the screen to match the bottom, so they are both animated at 30 FPS (every other frame). 2. Change the demo to show three visible scroll zones; try to set up two zones scrolling horizontally in opposite directions or at different speeds, while the third "larger" zone (comprised of two zones) scrolls vertically or diagonally. Multicolor playfields and DLI zones: (NEW!) -------------------------------------------- The color of the rows in each DLI zones can be independenlty colored via the rowcolors shadow register array: *rowcolors 100,110,120,130,140,150,160,170,180,90 If rowcolors is not specified in your program a default fade array is used that can be programatically accessed. To change the rowcolors shadow register array programatically, simply update it like any array variable. 10 rowcolors(3)=100:rem change the color of the third row of tiles visible. Multicolor Note: COLUPF is no longer effective; you can only change the playfield color via the shadow register array. Multicolor sprites: (NEW!) -------------------------- You can control the color of each row of the first sprite via it's shadow register array: *player0colors 100,255,100,100,200,200,200,200 If player0colors is not specified in your program a default fade array is used that can be programatically accessed. 10 player0colors(4)=14:color one line of sprite white. Multicolor Note II: COLUP0 is no longer effective; you can only change the color via the shadow register array. The second sprite is mono color and under control of the COLUP1 register. *With Flashback BASIC, the rowcolors and player0colors register arrays reside in the top 1.5 rows of the virtual world due to RAM constraints so you must define them programmatically or set the bits in the top row. Multiple Virtual Worlds (Flashback BASIC only) ----------------------------------------------- Flashback BASIC supports multiple virtual worlds and reloading virtual worlds after they have been changed. Set temp variable a to 0 or 1 to specify the first or second virtual world, and call loadvirtualworld: 10 a=0:gosub loadvirtualworld: rem load the first virtual world image A second ASCII art virtual world may be defined as virtualworld2 right below the virtualworld ASCII art. 10 a=1:gosub loadvirtualworld: rem load the second virtual world image Padding small programs (Flashback BASIC only) ---------------------------------------------- Small programs like examples and demos will work fine in the emulator or on larger Atari consoles, but may not work on the Atari Flashback Portable unless you add padding – the DLI demo shows an example where unused data statements are added to make the program larger. As your program grows you can remove the unused padding - it’s only necessary for the Atari Flashback to recognize your program when it is small. Stella compatibility settings (Old-School mode Flashback BASIC only) --------------------------------------------------------------------- To make the Stella emulator compatible with the Atari Flashback consoles RAM configuration enter the debug menu (the key under escape) and set the option to clear the RAM, exit and restart. This is necessary because old-school BASIC mode runs direct to the hardware which initializes the RAM while Stella only initializes SuperCharger RAM by default. Using the graphics designers will also initialize RAM. SuperCharger Disk BASIC DOS Commands -------------------------------------- SuperCharger Disk BASIC adds two DOS commands "load" and "SUPERCHARGERID" SUPERCHARGERID specifies the current programs ID in the directory, the default is 0 for the main program if not specified. The "program directory" consists of an ISAM file made from concatenated SuperCharger ROM's, or multiple SuperCharger audio files on a cassette tape. Supercharger games on cassette have identifying headers allowing the tape drive to function as a disk drive like the ADAM Family home computer. This feature made the multiload games like Dragon Stomper and Surivial Island possible in the early 80's and is now available in BASIC! example setting a modules SUPERCHARGERID to 2: 10 SUPERCHARGERID=2 Note that any number betwween 0 and 255 can be specified as the programs SuperCharger ID and that all ID's must be unique in the multiload. example using the load command to load a program module with a SUPERCHARGER ID of 2: 10 load 2 SuperCharger DOS security system: ----------------------------------- Note: any program with a supercharger ID other than 0 will be blocked from loading directly and will brick up - this is a security feature, another program must load it by specifying it's non-zero ID via the load command. Sharing variables between SuperCharger Disk BASIC programs: ------------------------------------------------------------ The following variables are preserved when programs are loaded: k,l,m,n,o,p,q,r,s and score player0x, player0y, player1x, player1y missile0x,missile0y,missile1x,missile1y Note that reloading the main program (SUPERCHARGERID 0) from another program will clear all the variables. If data needs to be preserved for programs reloading the main program, an initial loader program can be used to circumvent this feature. Total number of modules allowed: Up to 256 6K programs may be loaded and can cross reference one another within a single ISAM file up to 2 MB in size. Harmony flashcart limitation: currently only 4 SuperCharger programs may participate in an ISAM but there is a project underway to increase this number to 40 or more via a firmware update. PlusCart Encore and UnoCart flashcarts support 256 SuperCharger programs in an ISAM up to 2 MB in size. The SuperCharger and a standard cassette tape can support modular games just like the classic multiload games Survival Island and Dragon Stomper. Development Note for testing individual modules in large games: Once a SUPERCHARGERID other than zero is specified, the participating module can no longer autostart in Stella so use "SUPERCHARGERID=0" for debugging and change the ID back for loading once ready to put the modules together. Example combining multiple game modules to create a single large game ROM binary: ----------------------------------------------------------------------------------- Here is an example of combining 2 program modules into a single file for the Harmony flashcart (after they have been compiled individually and renamed). The first module will autostart (SUPERCHARGERID=0) but the other module with SUPERCHARGERID=3 can only be loaded using the DOS load command. 10 rem testing load command sharing BASIC variables in loaded program 20 SUPERCHARGERID=3:rem program 3 (program will brick-up if not loaded by another) 25 COLUBK=q:rem set the background color to variable q, some variables are preserved! 26 vwpixel(19,10,flip):vwpixel(1,1,flip) 35 if joy0right=1 and BITIndex <92 then BITIndex=BITIndex+1:scrollvirtualworldtoggle=1 36 if joy0left=1 and BITIndex >0 then BITIndex=BITIndex-1:scrollvirtualworldtoggle=1 37 if joy0down=1 then BYTErowoffset=BYTErowoffset+12:scrollvirtualworldtoggle=1 38 if joy0up=1 then BYTErowoffset=BYTErowoffset-12:scrollvirtualworldtoggle=1 45 if k=1 then return 46 for x= 0 to 239 47 virtualworld(x)=MUSICINDEX(x) 48 next x 50 BITIndex=0:BYTErowoffset=0:k=1 After compiling this program you will notice it will brick up upon launching - that's expected until it is combined, rename the compiled program.bin to program3.bin Now compile the program which will load that program when the button is pushed: 5 rem this program loads another program when the button is pushed 6 rem and transfers variable k for the others screen color 7 rem button initializes Tiny BASIC vars in ZeroPage RAM 8 rem and displays the entire zeropage (almost, 240 of 255 bytes) visually - 9 rem Then pushing Right and Down will scroll through the ZeroPage to inspect 20 SUPERCHARGERID=0:not necessary since this is the main program 25 z=100:COLUBK=z:q=116 26 rem change the background color by sharing variable q 27 vwpixel(19,9,flip):vwpixel(0,0,flip) 35 if joy0right=1 and BITIndex< 92 then BITIndex=BITIndex+1:scrollvirtualworldtoggle=1 36 if joy0left=1 and BITIndex >0 then BITIndex=BITIndex-1:scrollvirtualworldtoggle=1 37 if joy0down=1 then BYTErowoffset=BYTErowoffset+12:scrollvirtualworldtoggle=1 38 if joy0up=1 then BYTErowoffset=BYTErowoffset-12:scrollvirtualworldtoggle=1 44 rem Press button to set all BASIC variables for visual scroll test: 45 if joy0fire=0 then return 47 a=255:b=255:c=255:d=255 50 e=255:f=255:g=255:h=255:i=255:j=255:k=255:l=255:m=255:n=255:o=255:p=255:q=116:r=255:s=255:t=255:u=255:v=255:w=255 55 x=255:y=255:z=255:var1=255:var2=255:score=255:missile1y=255:missile0y=255:player1y=255:player0y=255:player1x=255:player0x=255 56 missile1x=255:missile0x=255:score=255:px=255:py=255:bx=255:by=255 58 for x= 0 to 239 59 virtualworld(x)=MUSICINDEX(x):rem load ZeroPage into virtualworld 60 next x 64 BITIndex=0:BYTErowoffset=0:rem move CAM to upper left corner 65 load 3: rem loads program with supercharger ID 3 from ISAM file or Magnetic Tape Command line example of combining those two SuperCharger Disk BASIC programs into a single ISAM multiload file: c:\vwBASIC>copy /b program.bin + program3.bin Program.bin now contains both programs, when run pressing the button will launch the other program and pass in variables. Example to create a multiload cassette Tape for the SuperCharger or Cuttle Cart: Instead of combining the programs into a single ROM, use the MAKEWAV utility as specified earlier on each of the programs to create WAV files. The two WAV files created may then be placed in any order on the Tape and the ISAM mechanism will always find the correct file to load. A looping Tape or auto reversing Cassette deck may be used to avoid the need to rewind to fully emulate a Disk Drive via Tape like the ADAM Home Computer. More Information ---------------- Visit RelationalFramework.com for more information about Atari Flashback BASIC, SuperCharger Disk BASIC and links to fun and interesting BASIC resources and easy BASIC game programming lessons in 10 lines.