[_)\ mmm r~i [_] la C_J rn LJ m MS hi BY LINDA H. SGHREIBEB nnr ADVANCED PROGRAMMING TECHNIQUES for BTSIIT 1 your ninni INCLUDING GRAPHICS & VOICE PROGRAMS Also by Linda Schreiber from TAB BOOKS: No. 1485 ATARI Programming . . . with 55 programs ADVANCED PROGRAMMING TECHNIQUES for nTflm your fit nil i INCLUDING GRAPHICS & VOICE PROGRAMS BY LINDA M. SCHREIBER TAB TAB BOOKS Inc. BLUE RIDGE SUMMIT. PA 17214 FIRST EDITION FIRST PRINTING Copyright © 1983 by TAB BOOKS Inc. Printed in the United States of America Reproduction or publication of the content in any manner, without express permission of the publisher, is prohibited. No liability is assumed with respect to the use of the information herein. Library of Congress Cataloging in Publication Data Schreiber, Linda M. Advanced programming techniques for your ATARI including graphics and voice programs. Includes index. 1. Atari computer— Programming. 2. Computer graphics. 3. Speech synthesis. I. Title. QA76.8.A82S367 1983 001.64'2 82-19340 ISBN 0-8306-0145-7 ISBN 0-8306-1545-8 (pbk.) To my family for their continuing support. Contents Program Listings vii Introduction ix 1 Working with Numbers 1 Binary System— Understanding Hex 2 Working with the Display List 9 The Purpose of ANTIC— Finding the Display List— ANTIC'S Instruction Set— Combining Graphics Modes— The Fourteen Modes— Text Modes— Color Text Modes. 3 Graphics 25 Character Set Make-Up— Restructuring the Set— The Invisible Modes 4 Principles of Animation 45 Characters with a Purpose— Scenes and Movement— Setting the Priorities 5 Looking at BASIC 79 The Token Commands— File Structures— BASIC Tables— Speeding Up a Program 6 Tricks with Strings 91 Machine Language Subroutines— Relocating the Strings— Strings and Player/Missile Graphics 7 Display List Interrupts 107 Handling an Interrupt— Writing Service Routines— Precise Timing— Player/Missile Enhancements 8 Scrolling 121 Course Scrolling— Fine Vertical Scroll— Playfield Widths— Fine Horizontal Scroll— Player/Missile Graphics 9 Page Flipping 133 Displaying Two Screens— Creating Slides 10 Sound Generators 153 The Audio Channel Control— Direct Access 11 Interpreting the Keyboard 161 Keyboard Code— Reading the Keyboard 12 Understanding the Screen Editor 171 Get/Put Characters— Control Characters— Other Memory Locations 13 Disk Use 177 Disk File Manager— Special Functions— Disk Handler— File Management System— File Directory Format— Booting Your Own Disk 14 Cassette Use 195 The Cassette Handler— Booting Your Own Cassettes— Using the Cassette with Sound Index 205 Program Listings 1-1. Conversions 2-1. Mixed Modes Program 2-2. ANTIC 3 2-3. ANTIC 4 and 5 2-4. Color Artifacting 3-1. Data for Exclamation Point 3-2. Character Set Editor 3-3. Multicolor Characters 4-1. Simple Animation 4-2. Simple Animation — Second Method 4-3. Animation in the Text Mode 4-4. Carousel 4-5. Carousel— Animated 4-6. The Bird 5-1. BASIC Tables— Variable Name Table 5-1A. BASIC Tables-Variable Value Table 5-1B. BASIC Tables-String-Array Area 84 5-1C. BASIC Tables— Buffer 5-1D. BASIC Tables-Statement Table 6-1. The Farmer and the Duck, Fox and Grain Puzzle 6-2. Move Character Set 6-3. Move Player/Missile Up/Down 6-4. Player/Missile Strings 7-1. Color Service Routine 7-2. Double Character Sets 7-3. Mirror Images Routine 7-4. Precise Timing 3 7-4A. Precise Timing— Second 13 Method 115 17 7-5. Moving Players 117 21 8-1. Course Vertical Scroll 121 23 8-2. Course Horizontal Scroll 123 26 8-3. Fine Vertical Scroll 126 28 8-4. Fine Vertical Scroll: Down 127 37 8-5. Fine Horizontal Scroll 129 48 8-5A. Fine Horizontal Scroll- Second Method 131 53 9-1. Screen Flipping 133 55 9-2. Simple Page Flipping: Two 60 Different Modes 135 64 9-3. Simultaneous Page Flipping— in 70 BASIC 137 9-4. Simultaneous Page Flipping- 82 Two Modes 137 9-5. Simultaneous Page Flipping: 83 Machine Language Subroutine 138 i 84 9-5A. Simultaneous Page Flipping: 85 Machine Language 86 Subroutine — Horizontal Blank 138 9-5B Simultaneous Page Flipping: 91 Machine Language 100 Subroutine — Vertical Blank 141 100 9-6. Slide Editor 145 102 9-7. Slide Show 148 109 10-1. Sounds 154 112 10-2. Sounds with Attack and Decay 155 113 10-3. Sounds with Attack and 114 Decay— Vibrations 155 10-4. Variations on Tones 157 12-2. Printing Control Characters 174 10-5. Music: Machine Language 13-1. Directory Listing 178 Subroutine 157 13-2. Print from Disk 180 11-1. Read the Keyboard 161 13-3. Calendar 181 11-2. Tiles 163 13-4. Displaying Sectors 185 11-3. Keyboard Conversion 167 13-5. AUTORUN.SYS 190 11-4. Letter Attack 169 14-1. BASIC Boot Load 197 12-1. Locate, Poke, and Peek 171 14-2. Listen and Spell 201 Introduction This book was written for the person who wants to get the most out of his or her ATARI computer. If you have a good understanding of BASIC but want to know how to get more special effects, more sounds, and more graphics from your computer, this book is for you. Every program is explained in detail so that after you enter the program and understand how it works, you can use this knowledge in writing your own programs. All the programs will run on any ATARI personal computer. The ATARI BASIC cartridge CXL4002 and ATARI DOS (for disk programs) were used in creating them. Memory locations that are used by the Operating System are presented. Explanations are given on how to change their values for different programming effects. The chapters on the disk explain the file structure to give you control over the drive. Everything is included here to make you an Advanced Programmer! There is a chapter on creating your own character sets, mixing graphic modes, using the player/missile graphics, and flipping screens. You will even learn how to enter a machine- language subroutine to play music while a BASIC program is running! xi Note: Because many of the listings in this book use graphics characters and/or reverse video, the following codes have been used in the listings: • > clear > Press the escape key and the shift/clear key. This clears the screen. • > characters or letters > Press the control key and the letter indicated between the brackets. ,4// characters or letters between the brackets >> are graphic characters. • Underlined characters or letters are in reverse video. Chapter 1 Working with Numbers Ever since man had the need to know how many items he had in his possession, how much grain he needed, or how many days since the last rain, he has had to devise counting systems. It is believed that some ancient tribes used the base two, or three for counting. There is some evidence that base twenty was used by a few early tribes, since their handiest counting device was their fingers and toes. With numbers came the need to do simple calculations. Soon the problems were no longer simple, and man quickly learned that if he marked the numbers in the dirt or on a tablet he could compute much faster. Stones were probably used much the way we use poker chips today with each type of stone representing a different group of numbers— ones, fives, tens, etc. The figures themselves evolved from crude lines and shapes to the forms we are familiar with today. The abacus is the oldest, and yet the simplest, adding machine invented. The principle of moving the beads on rods has survived the test of time. Many people consider the abacus to be the first type of computer. BINARY SYSTEM As with the abacus, the computer uses its own number system— binary. If you think of a light bulb, a candle, a lock, or a trap, each item has only two states. It can be either on or off, open or closed, set or sprung. The computer operates in the same manner. Each memory location in the computer can be either on or off. The memory in your computer can hold a charge. This is represented by the number one. When a location has no charge, it is represented by a zero. The computer, then, uses binary or base 2 as its number system. In our decimal system, each number position is a multiple of ten. The position to the left of the decimal is the unit position. In the binary system, each position is a multiple of 2 with the position to the left of the decimal the unit position. In the decimal system, there are ten numerals, through 9. In the binary system, only the numerals and 1 are used. The binary number 10110 is 22 in decimal. To convert a binary number to decimal, we add the places that contain a 1 and ignore the place values where there is a zero. 1 2 6 3 1 8 4 2 6 8 4 2 1 10 110 In our example, 10110, there is a 1 in the 16's column, a 1 in the 4's column and a 1 in the 2's column. If we add 16+4+2, we arrive at 22, the decimal equivalent of 10110. Most computers have 8 positions in each memory location. This means that each location can contain a number from to 255. The number that is stored in each memory location is called a byte. Each one or zero in the byte is referred to as a bit. The ATARI computer is an 8-bit computer. There are some 4-bit and 16-bit computers also. Each byte can also be divided into two 4-bit nybbles. Although it seems confusing at first, using the binary system in computers conserves on space and increases speed. If a switch with ten different settings were used, the computer would first have to determine whether or not the switch was set, and then determine which setting it was pointing to. In binary, there are only two possibilities, a 1 or a 0. It takes only 8 bits or switches to count to 255. By adding 8 more, any number up to 65535 can be displayed. Work the following examples to practice converting binary numbers to decimal. 1. 01100001 2. 10110111 3. 11001000 4. 00111001 5. 01110010 6. 00111100 7. 00011110 8. 11011000 9. 01111010 10. 11110001 The decimal equivalents are: 1-97; 2-183; 3-200; 4-57; 5-114; 6-58; 7-30; 8-216; 9-122; 10-241 UNDERSTANDING HEX Although the binary system increases the computer's speed, most of us cannot readily convert a string of Is and 0s into a number that we can understand. To help us, most programmers and manuals reference the memory locations and the numbers stored in them in hex. The hexadecimal system uses the base 16. The numbers after 9 are represented as the letters A-F. To convert a binary number to hex, we first divide the byte into two nybbles. If, for example, we needed to convert 11001101 into hex, we would divide it into two nybbles: 1100 and 1101. Each nybble consists of four bits. Now we treat each nybble as a separate number. By adding the place values of the first nybble, 8+4, we get 12. Twelve is not a one digit number, so we use the letter C. The next nybble is 8+4+1, or 13. One number higher than C is D. Our hex number for 11001101 is CD. Let's try that again with another binary number: 10010111. Divide this 8-bit number into 2 nybbles: 1001 and 0111. The first nybble is 8+1 or 9, the second is 4+2+1 or 7. The hex number for 10010111 is '97'. There are times when you will want the decimal equivalent to a hex number. When you are working in BASIC and want to poke a location with a number, both the location and the number that you are poking must be in decimal. Often the manual you are using will provide only the hex addresses to be poked or the hex values that should be entered. To convert a hex number to decimal is fairly easy. Since each number/letter represents a value from one to 15, each place value in hex is a multiple of 16. If the hex number has only two place, for example, B3, you should multiply the number in the second position from the end by 16 and add the value in the rightmost position. B is equal to 11 decimal, 11x16 is 176. Add 3 and the decimal value of hex B3 is 179. Since the computer can access over 64000 memory locations, the hex number will often contain four places. To convert C253 hex to decimal we would multiply the C (decimal 12) by 4096, the 2 by 256, the 5 by 16 and add 3. (12x4096) +(2x256) +(5x16) +3=49747 To convert a decimal number to hex, you should divide the number by the largest place value feasible; the quotient is the value for that place. Then divide the remainder by the next place value, and continue until there is a remainder less than 16. That number is the last number of the hex number. If, for example, the decimal number is 21013, we would divide the number by 4096. The first or leftmost value of the hex number then is a 5. The remainder is 533. When this number is divided by 256, the next quotient is a 2 with a remainder of 21. 21 divided by 16 is 1 with a remainder of 5. Therefore, the hex equivalent of 21013 is 5215. 5 —2 -1 5 4096) 21013 256)533 16J21 -20480 -512 -16 533 21 5 The following program will convert a decimal number to hex or binary, and a binary or hex number to decimal. Listing 1-1. Conversions 10 REM LISTING 1,1 20 REM BY L,M,SCHREIBER FOR TAB BOOKS 30 REM CONVERSIONS 4 D I M A $ ( 8 ) ! R E M M S T P S I T 1 N S IH A B I NARY NUMBER 5 G E A P H 1 S I P K E 7 5 2 » 1 l ? " > C I... E A R > " t P K E 7 1 t 1 J P K E 712* 1 J C 1... R 1 8 i P I... T 7v2n:iRAU)T0 33»2iPL0T 7»4tBRAWT0 34*4 60 REM PRINT cntrl-R to make the top a n d b o 1 1 o in o f b o ;•; . 70 POSITION 6-2!? "IMPOSITION 3 4 t 2 X? " ! " i R E M c i "i t r 1 - R r e s c - c n t r 1 •••• d o w n a r r a w v e s c • c n t r I ■- b a e k a r r o w s> s h :i. f t :::: 8 R E M e n t r I •••• R 9 s h :i. f t ~ > c n t r 1 ~ 2 & c n t r k ~ E v s h :i. f t = 1 c 1 1 1 r 1 - c w :i. t h d o w n ••■• a r r o w % b a c Listing 1-1. Conversions (continued from page 3). ksrrow to make left & risfht sides 9 P S I T 1 N 8 9 3 I ? " P I e a s e e n t e r a s e 1 e e tie i "i t " 100 ? J? J? " 1, Decimal to Hex "J RE M esc TAB 110 ? J? " 2, Decimal to Binary "J RE M esc TAB 120 ? {? " 3, He;-; to Decimal "{REM e seTAB 1 3 ? i ? " 4 * B i n a r a t o D e c i in a 1 " J P KE 752*0 *REM eseTAB :l. 4 T R A P 1 4 l P S I T 1 N 1 9 » 1 4 t ? " " v } INPUT NJREM TWO SPACES •■■■ 2 esc-cntrl b Ack arrows ••■■ erase a Previous answer 150 IF N<1 OR N>4 THEN 140 J REM CHECK F OR CORRECT INPUT 160 ON N GOSUB 200 » 500 v 700). 900 170 GOTO 50 190 REM ROUTINE TO CONVERT DEC I HAL NUH BERS TO HEX 200 ? "TCLEARTPLEASE ENTER THE DEC I'M AL NUMBER TO BE CONVERTED TO HEX,":? " NUMBER CANNOT EXCEED 65534," 205 REM CLEAR SCREEN v 2 esc-cntrl down s 210 ? ?? "TO EXIT THIS ROUTINE* SIMPLY PRESS THE RETURN KEY, " J? I? 220 TRAP 50 230 INPUT N 250 IF N>65535 OR N<0 THEN 200 260 Nl-NJREM STORE THE NUMBER ENTERED FOR THE CONVERSION ROUTINE 270 P-liD=4096*REM P IS THE HEX POSIT I ON ■■■■ D IS EQUAL TO THE VALUE OF THE HE X POSITION 280 GOSUB 390 {REM USE THE SUBROUTINE T HAT GETS THE FIRST POSITION 290 P^2iD=256{REM P IS THE NEXT POSIT I ON •••■ D IS THE VALUE OF THAT POSITION 300 GOSUB 390 310 P=3JD~16JREM P IS THE THIRD POSIT I ON •■■• D IS THE VALUE OF THAT POSITION 320 GOSUB 390 330 P-4JD-1 340 GOSUB 400 350 ? :? "THE HEX EQUIVALENT OF " i N 5 " IS "SA$ 360 GOTO 2.1.0 380 REM THIS ROUTINE DOES THE ACTUAL C ONVERSION 390 I F N :l. < D T H E N A * ( P t P ) = S T R $ ( ) { R E T U R N 400 H - 1 N T ( N 1 / D ) J R E M D I V I D E T H IE.' N U M B E R BY THE VALUE OF THE POSITION 410 Nl=Nl~-H*DiREM STORE THE REMAINDER FOR THE NEXT CONVERSION 420 I F H > 9 THEN A $ ( P 9 P ) ™ H R $ ( H + 55 ) J R E T URN 430 A $ ( P t P ) :■■■■ S T R * ( H > i R E T U R N 490 REM CONVERT A DECIMAL NUMBER INTO A BINARY NUMBER •■■■ DIVIDE THE NUMBER BY EACH PLACE VALUE 500 ? "TCLEARTPLEASE ENTER THE DEC IN AL NUMBER TO BE CONVERTED TO BINARY, "I ? " NUMBER CANNOT EXCEED 255," 505 REM CLEAR SCREEN » 2 esc-crrtrl down 510 ? J? "TO EXIT THIS ROUTINE t SIMPLY PRESS THE RETURN KEY, " J? i? 520 TRAP 50 530 INPUT N 550 IF N>255 OR N<0 THEN 500 560 N1=NJREM STORE THE NUMBER ENTERED FOR THE CONVERSION ROUTINE 570 P=J.:»=128JREM P IS THE BINARY PUS I TION - D IS EQUAL TO THE VALUE OF THE BINARY POSITION 580 GOSUB 390 J REM USE THE SUBROUTINE T HAT GETS THE FIRST POSITION 590 P=2JD~64JREM P IS THE NEXT POSIT 10 N - D IS THE VALUE OF THAT POSITION 600 GOSUB 390 610 P=3tD=32: GOSUB 390 6 2 P = 4 i D ■ 1 6 J G S U B 3 9 630 P=5JD=8JB0SUB 390 640 P ■ 6 J D - 4 : G S U B 3 9 650 P=7tB=2JGQSUB 390 660 P=8tB«iJG0SUB 400 Listing 1-1. Conversions (continued from page 5). 670 ? J? "THE BINARY EQIVALENT OF " ?NJ ? "IS " »A$(1 rA) i " "JA$<5»8) 680 GOTO 510 700 ? "> CLEAR> PL EASE ENTER THE HEX N U M BE R T B E CON V E R T E D T D E C I M A I... » " ! ? " NUMB E R C A N N G T E X C E E D F' i ;: ' F i :: ' * ■ 710 ? J? "TO EXIT THIS ROUTINE t SIMPLY PRESS THE RETURN KEY. " i? i? 720 N*=0?INPUT At 730 IF A*=" " THEN 50 740 P ■ I... E N ( A $ ) I R E M F I N D U T H Ul MANY P TIQN! Si i .i. uin;:> 750 IF P>4 THEN 700 760 F R I) "» :l. T P I C -• A S C ( A $ ( D v D ) ) 1 1 F C > 7 THEN 700 J REM INVALID LETTER/CHAR A GTE R 770 C :::: C - 5 5 1 I F G < 1 T H E N C ~ A I... ( A $ ( D * D ) ) {REM IF IT'S NOT A LETTER THEN GET THE VALUE 780 ON P-D+l GOTO 820 » 810 * 800 » 790 790 N«C*4096JNEXT D 800 N=N+C*256JNEXT D 810 N=N+C*16JNEXT D 820 N=N+C 8 3 ? X ? " T H E D E C I M A I... E Q U I V A L E N T F " 5 A$yJ? " IS "5N 840 GOTO 710 900 ? "XILEAETP LEASE ENTER THE BINAR Y NUMBER TO BE CONVERTED TO DECIMAL , ■ I ? " NUMB E R C A N N T E X C E E D 1 1 1 1 1 1 1 :l. . " 910 ? }? "TO EXIT THIS ROUTINE* SIMPLY P R E S S T H E R E T U R N K E Y , " t' P t ? 920 N-OJINPUT A$ 930 IF A$«" " THEN 50 940 P ■ I... E N ( A * ) t R E M F I N D G U T H U MANY p D SITIONS 950 IF P>8 THEN 700 960 TRAP 900 J FOR D«l TO P{C~VAL( A* (D? D > ) 970 IF C>1 THEN 900 I REM INCORRECT ENTR Y 980 IF C=l THEN ON P-D+l GOTO 1060 v 105 0» 1 040 9 1030 i 1020s 1010 t 1000*990 985 NEXT D 6 990 N=C#128JNEXT D 1000 N«N+C*64JNEXT D 1010 N-~N+C#32JNEXT D 1020 N~N+C#16SNEXT D 1030 N-N+C*8JNEXT D 1040 N-N+C*4JNEXT D 1050 N~N+C*2JNEXT D 1060 N=N+C 1070 ? {? "THE DECIMAL EQUIVALENT OF " »A*J? "IS "»N 1080 BO TO 910 1090 END Line 40 sets the string space used for the binary or hex numbers. Line 50 removes the cursor, clears the screen, changes the color of the background and border to violet, and draws the top and bottom of the box. To use the plot and DRAWTO commands, you must specify the graphics mode. The color 18 is a control R. Line 70 draws the right and left side of the box for the on-screen display. Use a control Q, shift =, and a control Z for the left side of the box; and a control E, shift =, and a control C for the right side. Use a down arrow and a backspace between each character. Lines 90-130 place the menu on the screen. Keep it neat by using an extra print and a tab in each line. Line 140 uses the trap command. If a letter or character is entered instead of a number, the program will not crash. The two spaces and backspaces will clear any input that was incorrect. Line 150 checks the input. If the number entered is incorrect, the program goes back to the previous line and waits for the correct entry. Line 160 directs the program to the correct routine. The program will return to the menu in line 170. Lines 200-210 clear the screen and place the directions on the screen. Line 220 is another trap. If you enter a letter or simply press the return key, you will return to the main menu. When writing a menu driven program, it is a good idea to give the user a way out in case the wrong selection was made. Lines 230-250 get the number to be converted and check to make sure that the number is within the specified range. If it is not, the program will go back to the beginning of this routine. Line 260 stores the number entered in another variable, Nl. The number in this variable will be converted to a hex number. Lines 270-340 convert the number into a hex number. The variable P is the position that is being converted. When converting numbers from decimal to hex or binary, we start with the leftmost position and work to the right. The value of the first hex position in a four digit hex number is 4096. This number is stored in the variable D. The program then uses the subroutine that begins with line 390 to convert the number. Each time we return from this subroutine, the value in P is increased by one to reflect the next place in the number and the value of D changes to the value of the place. In line 340 we GOSUB to line 400 since this is the last or one's position and the value here will most likely be larger than the value of D. Lines 350-360 display the number entered and its hex equivalent. The program goes back to line 210 and waits for another number or a return. Lines 390-430 do the actual conversion of a decimal number to hex or binary. First the number is compared to the place value. If the number is less than that value, a zero is stored there. Next the number is divided by the place value. The integer or whole number is stored in the variable H. To get the remainder, we multiply the place value by the whole number and subtract it from the number. The new number or remainder is now stored in Nl and will be used when we continue to convert the number. Line 420 is used for decimal to hex conversions. The number is checked to see if it is greater than a 9. If it is, it must be converted into a letter (A-F). This is done by adding 55 to the number. If the number is less than 10, that number is placed into the string. In either case, the routine returns to continue the conversion. Lines 500-680 convert a decimal number to binary. Again, we trap the input so that pressing the return key will return you to the main menu. The number is tested and stored in Nl. Lines 570-660 keep track of which position is being converted and the value of that position. The same subroutine that was used to convert the decimal number to hex is used to convert the decimal number to binary. Lines 670-680 display the results of the conversion and go back to the beginning of this subroutine. Lines 700-840 convert a hex number to decimal. This time we are using a string for the input. If the string is empty, the program will go back to the main menu. The program checks the length of A$. If more than 4 letters or numbers have been entered, the program will go back to the beginning of this subroutine. The ASCII value for each number/letter is stored in C. If the value of C is greater than 70, the letter entered is invalid and the program goes back to the beginning of this subroutine. If it is a valid letter/number, 55 is subtracted from it. If C is less than 10, that position contains a number and its value is placed in C. If the position contains a letter, the value of that letter is obtained by subtracting 55 from its ASCII value. The value in C is multiplied by the place value of its position and added to any previous conversion value. The new conversion value is stored in N. Once the hex number has been converted into its decimal equivalent, both numbers are displayed on the screen. This subroutine continues until the return key is pressed. Lines 900-1080 use the same principle to convert a binary number to decimal. Since the program is expecting only Is and 0s, a trap is placed in line 960 for any letter/character. The value of each position is stored in C, one at a time. If this value is greater than 1, the program returns to the beginning of this module. If C is 1, the value of that position is added to the value in N. This number will be the decimal equivalent of the binary number. Chapter 2 Working with the Display List All microcomputers have one thing in common — a CPU or central processing unit. It is the brains or workhorse of the system depending on how you look at it. Whether it is a 6502, 8080, Z-80, or some other processor, it is what keeps the machine going. The ATARI, however, has three special-purpose LSI (large-scale integrated) chips to take some of the burden off the 6502. They are called ANTIC, CTIA, and POKEY. This chapter will discuss the purpose of ANTIC and how to make use of its capabilities. THE PURPOSE OF ANTIC ANTIC is a microprocessor that is dedicated to updating the screen display. It is a true microprocessor because it has its own instruction set, a program, and data. It operates simultane- ously and in conjunction with the 6502. ANTIC uses the same bus and memory locations that the 6502 does. In order to operate, ANTIC must stop or halt the 6502, get its information, and then let the 6502 continue its work. Both must operate without missing a step. ANTIC's job is to keep the screen updated with the current information. A television screen is normally updated 60 times a second. Since ANTIC must stop the 6502 each time it does its job, the higher the resolution that is displayed on the screen, the more often the 6502 will be interrupted. If you turn off the ANTIC chip completely, the 6502 will operate at maximum efficiency. The ATARI computer and many other personal computers like the Apple and the TRS-80 have memory mapped screen displays. This means that the information that you see on the screen is also stored in a specific portion of the computer's memory. The higher the graphics resolution, the more memory is needed to store this information. The upper left corner of the screen is the lowest memory address, and the lower right corner is the highest memory address. The address of each location in between follows the first address sequentially. In most other computers, you have a choice of one or two graphic modes, or text. It is not always possible to mix the types of graphics modes. The ATARI offers 14 different modes with its CTIA graphics chip. Each mode can be displayed individually or mixed with the others. This is the reason for the ANTIC chip. It has its own program just above the memory set aside for the screen. This program is really a list of the graphics modes that we are using in our program. ANTIC checks this list for the mode of the line, and sends this information along with the data that will be displayed on this line to the CTIA 9 (or GTIA) chip. This chip is the television interface chip. It in turn converts the information that it receives into the signal that we see as a picture or text on the screen. If each line is a different mode, ANTIC tells this to the CTIA (GTIA) chip, and it translates the signal accordingly. FINDING THE DISPLAY LIST Just before the memory set aside for the screen display is the display list that ANTIC uses. The address of the display list is stored at memory locations 560 and 561. To obtain the address of the display list enter this command. PRINT PEEK(560)+PEEK(561)*256 The number that appears on the screen is the starting address of the display list. In graphics mode 0, the display list is 32 bytes long. To see the list type: 10 DLIST=PEEK(560)+PEEK(561)*256 20 FOR X=DLIST TO DLIST+31:? PEEK(X):NEXT X Your list should look like: 112 112 112 66 64 may 156 differ 2 - 2 - 2 - (23 twos) 2 - 2 - 65 32 may 156 differ Before interpretting the display list, you must understand your screen. If you look very closely at the screen, you will see that each character is made up of tiny dots. The picture that you see on the screen is actually many rows of dots stacked from the top of the screen to the bottom of the screen. You do not actually see the complete picture on the screen. The parts of the picture that are above, below, or to the sides of the screen are called overscan. The picture that is transmitted from the networks contains information on the lines above the actual picture. You never see this information because it is in the overscan area. Now look at the display list again. The first three numbers tell ANTIC to display three blank lines that are 8 rows high. This makes sure that the text or picture will be on the screen and not in the overscan area. The next number, 66, is a two part instruction. A 64 tells ANTIC that the following two bytes contain the address of the beginning of the screen display area. The 2 added to the 64 is the ANTIC mode of the first line of the screen. Any number from 2 to 15 can be added to the 64. The number added is always ANTIC's value for the graphics mode. We will discuss the fourteen 10 graphics modes and their ANTIC values later in this chapter. For now, your screen is in graphics mode 0, which is ANTIC mode 2. If you multiply the sixth number in the display list by 256 and add the fifth number of the display list, you would know the exact memory location of the first location in the first line on the screen, or position 0, 0. If you poked this location or any location after this one with a value, you would see characters on your screen. This is a memory mapped screen display. The contents of the memory locations set aside for the screen are visible on the screen. When you use the locate command in BASIC and you tell the computer LOCATE 5,6, B, the computer calculates the memory location of the fifth column and the sixth row based on the mode that we are using and sets the variable B to the value in that memory location. If your screen display begins at memory location 40000 (40K system), and you are in graphics 0, you can use the locate command to find out what is stored on the screen at any location. The command in this example is LOCATE 5,6,B. The computer multiplies the row number by the number of characters in the row, in this case 40, and adds the column number: 6 times 40 plus 5 equals 245. This number is added to the first memory location for the screen. The computer examines that memory location and changes the value found there to AT ASCII. This value is stored in B, and the computer can tell you the value of location. Now that you know how it's done, you can use either the locate command, or the peek function for yourself. Going back to the list of numbers that make up the display list, you see that there is a string of 23 twos before you come to any other numbers. In graphics mode 0, there are 24 rows on the screen. ANTIC knows from the display list that the first row is in graphics mode 0. It also knows where the beginning of the screen display is. The next 23 numbers tell ANTIC that the next 23 rows will all be in graphics mode or ANTIC mode 2. The next number after all the twos is a 65. This again is a two part instruction. The 64 tells ANTIC that there is an address in the next two bytes that it should jump to, and the 1 tells ANTIC to wait for a vertical blank before jumping. When the last number in this list is multiplied by 256 and then the number just before it is added to this product, the total is equal to the beginning address for this display list. Thus ANTIC will repeat these same instructions over and over again until they are changed. It will start at the beginning of the display list, look at the mode the first line is in, take the information from the screen display area, and transfer this information to the CTIA chip for the actual screen display. It goes to the next line, looks at the mode, gets the next lines information, and transfers it. The process is repeated until it reaches the 66, where it waits for a signal called a vertical blank and goes back to the beginning of the display list. What's a vertical blank? The picture that you see on your television screen, whether it's generated by a computer or comes from the main television station, is "painted" on your screen line by line. A beam called a raster scan starts at the left side of the screen (as you look at it), and paints a picture by turning on the correct color beams in that row. When it reaches the end of the row, the beam shuts off, retraces the line, steps down a row, and turns itself back on to paint another line on the screen. The line that has been painted is called a horizontal scan line. The time that the beam is shut off to retrace the line is called a horizontal blank. When the beam reaches the last row on the screen, it not only has to come back to the left side of the screen, but also has to go back to the top of the screen. This period of time, while the beam is shut off and going back to the top side of the screen, is called the vertical blank. If the computer was not synchronized with the television, the display would appear jittery and distorted. By waiting for the vertical blank before beginning the display list again, ANTIC is sure that the display will appear correctly on the screen. 11 ANTIC'S INSTRUCTION SET Looking at the display list again, you see that ANTIC does have a set of instructions that it follows. A blank line can be inserted anywhere in the display list. This blank line can be from one to eight pixels tall. In the display list, the first three numbers were 112, 112, 112. In hex this translates to 70, 70, 70. When you want to tell ANTIC to send a blank line, you use an instruction that only uses the left nybble of the byte. Table 2-1 shows the values used to issue a blank line from one to eight pixels high. ANTIC is also capable of jumping. At the end of the display list, it has the instruction 65. In a jump instruction, the second nybble of the byte is always set to 1. The first nybble can be either or 4 hex. If the instruction is 1, ANTIC will jump to the address indicated in the next two bytes, and continue there. If the instruction is 65 or 41 hex, ANTIC will wait for the vertical blank before jumping. The jump instruction, 1, is used when the display list must cross a IK boundary in memory. ANTIC cannot calculate past 255, so it must be told to jump to the next location. This jump should be placed just before the boundary. The two bytes after the jump instruction should contain the low order and then the high order address of the location that ANTIC should jump to. ANTIC also has display instructions. This time the instruction byte is divided into its individual bits. The last four bits of this byte tell ANTIC which display mode to use. ANTIC's display modes are 2 - 15. If bit 4 is set to 1, then ANTIC can do a horizontal scroll. If it is 0, it cannot. Bit 5 is set to enable the vertical scroll and when bit 6 is set, ANTIC will use the next two bytes as the beginning of the screen memory. See Fig. 2-1. COMBINING GRAPHICS MODES Looking at the ATARI manual, you see that there are eight graphics modes, one for normal text, two for color text, and five for graphics. Yet, looking at ANTIC's instruction set, you can see that there are fourteen different modes. Six of these modes cannot be accessed by BASIC with the graphics command. They can, however, be used with BASIC when you create your own display lists. Combining the different graphics modes and creating your own display list takes a little imagination and the ability to add to 192. Why 192? Think back to the television screen and the horizontal scan. The beam that paints a picture on the screen does so row by row. Every row is the same height. Therefore, every picture has the same number of scan lines. When you count the number of pixels used in a character in graphics mode 0, you see that the character stands 8 pixels or rows high. There are 24 rows in mode 0. 24 x 8 = 192. Multiply the number of rows for any other mode time the number of pixels used in one row. The answer will always be 192. Therefore, Table 2-1. Values to Issue Blank Lines. blank hex decimal lines value value 1 00 2 10 16 3 20 32 4 30 48 5 40 64 6 50 80 7 60 96 8 70 112 12 bit # 7 6 5 4 3 2 1 set bit instruction 7 display list instruction interrupt Fig. 2-1 . Set bits for display list. 6 load memory scan with next two bytes 5 vertical scroll 4 horizontal scroll 3-0 display mode when you create a new display list, you want the number of rows used in each of the modes to total 192. To create a multi-mode screen, you must first decide what you want your screen or display to look like; which graphics modes are best suited for the display; and how you want to organize the general layout of the screen. Once you decide how the screen should look, you are ready to create a new display list. As an example you are writing a program that involves some text, some prompting from the program, and a score that is kept on the screen. The main part of the program will be done in graphics mode 7. The first thing that you have to decide is how many lines you need for the text. This program will only need two lines for text: one line at the top and one line near the bottom. This leaves the rest of the screen for the graphics. In a full screen (no text window), graphics mode 7 has 96 rows, each 2 pixels high (96x2=192). For this program you will use graphics mode 2 at the top and graphics mode 1 near the bottom. To calculate the number of rows that will be in graphics mode 7, you must first determine the number of rows of pixels the other two modes will use. The characters in graphics mode 2 are 16 rows high. The characters in graphics mode 1 are only 8 rows high. This means that 24 rows of the screen will be used by these two modes (8+16=24). By subtracting this number from 192, you can calculate that there are 168 rows left for graphics mode 7 ( 192- 24= 168) . Since each row of graphics mode 7 uses two rows of pixels, there will be 84 rows of graphics mode 7 on the screen (168/2=84). The following program, which draws a baseball diamond, creates a new display list for your program. Listing 2-1. Mixed Modes Program :L0 REM LISTING 2.1 20 REM MIXED MODES 30 REM BY L.M.SCHREIBER FOR TAB BOOKS .1.982 4 D I M M * ( 2 ) : G R A P I -I I C S 2 3 1 R E M H A E C M PUTER SET DI SPI...AY LI SI FOR SRAF hi I C ;s 7 WITH NO TEX1 WINDOW 50 DLIST=PEE K<560)+P EE <(S61 )*2^ 6 60 ANTIC=PEEK<559> !R EM GET THE VAI. .UE I N ' J' HE SHADOW FOR ANT 10 3'S £ TATE 70 POKE 559 y 01 REM SHUT OFF ANT] U r OR D LSI : 'I...AY LIST- CHANGES 80 POKE DLIS T+3»71JR EM MAKE THE f: RS r 13 Listing 2-1. Mixed Modes Program (continued from page 13). LINE GRAPHICS 2 90 POKE DLIST+89*6?REM MAKE THE BOTTOM ROW GRAPHICS 1 100 POKE DLIST+90r65!REM MOVE THE JUMP I. :l. P K E D I... I S T •!• 9 :l. > P E E K ( 5 6 ) 1. 2 P K E Ei I... I S T + 9 2 v P E E K ( S 6 1 ) 1.30 POKE 559 » ANTIC J REM TURN ANTIC BACK ON TO IT'S PREVIOUS STATE L 40 M E M R Y * P E E K ( D I... I S T + 4 ) + P E E K ( D I... I S T + 5 ) *25<5 50 M$^"02%330< OS/20 ( )4" {REM INVERSE IN PARENTHESIS •••• FIRST ONLY 160 B0TT0M=MEM0RY+2 1.70 FOR X-BOTTOM TO BOTTOM+ I... EN ( M$ ) -1 } P ] K E X t A S C < M * ( ( X •••• B T T Mf 1 ) t < X - B T T M + 1 ) ) ) { NEXT X i a o m * * " 2 5 ♦ 3 e e e o @ e 2 5 . 3 ■ : r e m i... a s t f u r CHARACTERS ARE INVERSE 190 B T T M » 83*4 •)• M E M R Y + 22 200 FOR X~ BOTTOM TO BOTTOM + I...EN CM* ) -1 i P OKE X t A S C ( M $ ( ( X •■■• B T T M + 1 ) v < X - B T T M -f 1 ) ) ) {NEXT X 2 1 C L R 1 { P L T r 1 I D R A U T 6 r 4 { D R A U TO 0r80$PL0T 159 ?0 t DRAWTO 99 » 39 {DRAUTO 159 v 79 250 GOTO 250 Line 40 sets M$ to 20. This string will be used to store the characters for the message that will appear, on the screen. The graphics mode is set to 23, which is graphics mode 7 without the text window. Of the three modes that will be used, graphics 7 mode uses the most memory, so it is advantageous to set the mode to 7. The computer will calculate the amount of screen memory needed and move the display list above it. This leaves you with less to figure out. Line 50 finds the address for the beginning of the display list. Line 60 stores ANTIC's state in the variable ANTIC. The value in this memory location varies depending on what control the program will have. It determines the width of the play field and the resolution of players and missiles, and enables the use of player/missile graphics. Line 70 turns off ANTIC while the display list is changed. If ANTIC was left on, it would be using the values in the display list while it was being changed. This could cause the program to crash. Line 80 changes the first row on the screen from graphics mode 7 to graphics mode 2. Remember, you must add the display instruction to the graphics mode in this location. Line 90 changes the last row on the screen to graphics mode 1. You must add 89 to the display 14 list to arrive at the position of the last row of the screen in the display list 89 is obtained in the following manner: 1. The total number of rows on the screen, calculated in terms of graphics mode 7, are tabulated. This number is 96. (Each row is two pixels high.) 2. The total number of rows, calculated in terms of graphics mode 7, done in modes 1 and 2 are calculated. Row 1, which is in mode 2, is 16 pixels or 8 mode-7 rows high. The last row, which is in mode 1, is 8 pixels or 4 mode-7 rows high. The total (8+4) is 12. 3. The 12 from item number two is subtracted from the 96 obtained in item one: 96- 12=84. These are rows 0-83 in terms of graphics mode 7. We know that the first three bytes of the display list (0-2) are for the overscan. The fourth byte (3) sets the first row on the screen, and the next two bytes (4 and 5) indicate the memory location of the screen. 83+5=88— therefore the 89th row in the display list is set for graphics mode 1. Lines 100-120 move the jump and the address of the beginning of the display list into the correct position. Line 130 turns ANTIC back on to its previous state. Now it can execute the new display list. Line 140 finds the location of the screen memory in the display list and stores it in the variable MEMORY. We will use this value when we display the message on the screen. Line 150 places the message in M$. The first open parenthesis is in inverse video. If you have been replacing the character set in your ATARI with a new character set in RAM, you have probably discovered that the character set does not follow its AT ASCII or decimal values. Because we have set the graphics mode to 7, the computer will not print a message as such on the screen. Graphics mode 7 means: "use only two bits from every byte; add four 2-bit combinations together and store them in a memory location on the screen." If we told the computer to PRINT'PRESS" on the screen, it would use only the last two bits of each letter between the quotation marks. The PRES would be combined for one character, the S would be the second. The character on the screen would be the character that was in that location of the ATARI character set. In the next chapter we will redesign a character set. Line 160 stores the value of MEMORY + 2 in the temporary variable BOTTOM. Line 170 is a for . . . next loop that pokes each character of M$ into the memory that is reserved for the screen. Now the AT ASCII value of each character of M$ is stored directly on the screen. Line 180 stores a new message in M$. This is the message that will appear on the bottom of the screen. Once again, the message that appears on the screen is not the same as the characters between the quotes. Line 190 calculates the memory location of the last row on the screen. Line 200 pokes this message directly into the screen memory. Line 210 draws the diamond on the screen. This can be done with the simple plot and DRAWTO commands. Notice that the position PLOT 0,1 is actually the center of the screen rather than the left side. All the positions are shifted over by 80. This often happens when different modes are mixed. Our first row on the screen is in graphics mode 2. ANTIC took the first 80 bytes for this row because it was set for graphics mode 7 which uses 4 bytes for every location on the screen. It knew, though, that graphics mode 2 only needed 20 locations on the screen (20x4=80). Graphics mode 7 uses 160 bytes for every line. The next 160 bytes are displayed on the next row on the screen. The computer thinks that the first 80 bytes belong to the previous row. When the computer calculates the memory position for PLOT 0,1 , though, it does not look at the display list to see if any of the rows have more or less bytes in them than the present mode 15 calls for. It simply multiplies the row number by the number of bytes in a row. Because this is a graphics mode, before it adds the column, it divides by the number of bytes used to display one byte (in this mode, 4) and then adds the column divided by 4. Every row on the screen will be off center because of this method of calculation. Line 250 loops back on itself. You can stop this program by pressing the system reset key. THE FOURTEEN MODES One of the features of the ATARI that has not been widely publicized is that the number of graphics modes is not 9 but 14 with the CTIA chip. When we are working with BASIC, we have 9 choices, Graphics modes 0-8. Graphics mode 9-11 are reserved for the GTIA chip. Any other number will give us an error message. However, when we work directly with the display list, we learn that ANTIC will set the screen for any graphics mode from ANTIC 2 to ANTIC 15. Table 2-2 shows us the different modes and the unique features of each mode. ANTIC modes 2-7 are all text modes. ANTIC modes 8-F are graphics modes. ANTIC gives you three additional text modes and two additional graphic modes. TEXT MODES There are two 2-color text modes available: the standard text mode referred to as Graphics mode 0, and ANTIC mode 3. ANTIC mode 3 has ten scan lines or rows for each character. This feature allows for true descenders on the letters q, y, p, j and for subscripts and superscripts. Because each line in this mode uses ten scan lines or rows on the screen, the display will be two rows shorter than a normal display (10x19=190) or eight rows longer (10x20=200). When you redefine a character set for use in this mode, you do not need to add two blank bytes either before the character or after it. When the computer reads the bytes for the characters from the character set, it will add the two blank bytes automatically to the character. For all the characters, numbers, and uppercase letters, the two blank bytes will be added to the bottom of the letter. Lowercase letters are treated differently. The computer takes the first and second byte of the character and places it in the ninth and tenth row of the character on the screen. It places 2 blank lines in the first and second row and then places the rest of the bytes in the correct position. This can cause some problems if you are using this mode with the character set in ROM. In the following program, the display list will be changed to use ANTIC 3. A message will be printed on the screen using the character set from ROM. Notice the distortion in the letters 1, j, and k. There is no distortion in any of the capital letters, numbers, or graphics because they are not the last 32 characters/letters of the character set. value in two bits of color graphic byte register 00 01 (background) 1 Fig. 2-2. Color register codes. 10 2 11 3 All four color registers Color registers and 1 are used in GRAPHICS 3, 5, 7. are used in GRAPHICS 4 and 6. 16 Listing 2-2. ANTIC 3 10 20 f 30 40 v'EM I... v'EM ANTIC 3 *EM BY L.M.8CHREIBER FOR TAB BOOKS 5 ">Aa Bb Cc Bo Ee Ff 6 si Hh I :i. J,i Kk I... I Mm Nn Oo Pp Oca Er Ss Tt Uu Vv U w Xx Y' : !#$%878@< )?0 5 D L :i: S T o P E E K ( 5 6 ) + P E E K ( 5 6 i ) #2 5 6 1 AN T I C ~ P E E K < 559 ) I R E M G E T T H E U A I... U E I N T H E S H ADOW EOE ANTICS 'S STATE 6 POKE 559* OJ REM SHUT OFF ANTIC FOR D I SPLAY LIST CHANGES 70 POKE DLIST+3f67tREM MAKE THE FIRST LINE ANTIC 3 80 EGP TO 24: POKE DLIST+Xi3iNEXT X J REM CHANGE LIST FOE ANTIC 3 90 POKE BLIST125y65:REM MOVE THE JUMP 100 POKE DLIST+26* PEEK (560) J. 1 P K E D I... I S T f 27 » P E E K ( 5 6 1 ) 120 POKE 559 y ANTIC? REM TURN ANTIC BACK ON TO IT'S PREVIOUS STATE 130 A=PEEK<106)-"8JNB=A*256tREM PLACE C HAEACTEE SET 2K BEFORE ENB OF MEMORY •- STORE VALUE IN NB 1 4 C B = P E E K ( 7 5 6 ) * 2 5 6 J T H :::: CB S X :::: T H J R E M C H ARACTER SET IN ROM 1 5 F R I... C ~ T 1 1 ! P K E N B r P E E K < X+ 7 ) i N B ss N B •}■ 1 ! F E X - T H T T H f 6 i P K E N B » P E E K ( X ) J N B s= N B + 1 ! N E XT X i T H :::: T H + 8 I X •-• T H t N E X T I... C 1 6 F R X ~ T H T T H + 7 ! P K E N B » P E E K ( X ) J N B - N B f 1 i N E XT X J T H »= X ? R E M SAM E 1 7 F R I... C ■■■■■■■ 1 3 T 26 t P K E N B v P E E K ( X +7 ) : N B ss N B f 1 i F R X s= T H T T H + 6 J P K E N B v P E E K < X ) t N B ~ NB + 1 ! N E XT X J T H :;:: T H + 8 i X ■■■■■■■ T H J N E X T I... C :l. 8 F R X ss T H T T H + 7 J P K E N B t P E E K ( X ) t N B =s N B f 1 t H E. XT X { T H : ^ X I R E M SAM E 1 9 F R I... C -^ 2 8 T 64 t P K E N B y P E E K ( X + 7 ) I NB-NB+1SF0R X--TH TO TH+6JP0KE NBsPEEKC X ) J N B s= N B i 1 : N E X T X 5 T H » T H + 8 { X ss T H J N E X T L C 200 FOE I...065 TO 79 1 FOR X=TH TO TH + 7:P OKE NByPEEK(X) JNB==-NB+1 J NEXT XtTH-XJNEX T LCiREM SAME 2 1 P K E N B r P E EK < X+ 7 ) t NB = NB+ 1 J F R X = T H T T H f 6 I P K E N B , P E E K ( X ) I N B = N B + :l. J N E X T XJTH~TH+8JX=THJREM E 17 Listing 2-2. ANTIC 3 (continued from page 17) » 220 FOR LC-81 TO 90 J FOR X=TH TO TH+7JP OKE NB»PEEK J R E M R E P E A T I... A S T BYTE 3 :l. C B ■ AK256+ 1 1 2*8 J P K E C B + 1 r P E E K ( C B ) J REM MO ME BYTE DOWN ONE 320 P K E B y P E E K ( C B 1 7 ) I R E M R E P E AT LAST BYTE 330 C B ■ A * 2 5 6 + :l. 1 3 * 8 i P K E C B + 1 1 P E EK ( CB > I REM MOVE BYTE DOWN ONE 340 P K E C B y P E E K < C B + 7 ) J R E M R E P E A T I... AST BYTE 350 C B - A * 2 5 6 + 1 2 1 * 8 { P K E C B f :l. r P E E K ( C B ) J REM MOVE BYTE DOWN ONE 360 P K E C B y P E E K < C B + 7 ) f R E M R E P E A T L AST BYTE 370 POKE 756 n A Line 40 is the line that will be printed on the screen. It clears the screen and prints each letter of the alphabet in both upper and lowercase. It also prints some numbers, symbols, and graphics on the screen. Line 50 stores the beginning location of the display list in DLIST and the display status in ANTIC. Line 60 shuts off ANTIC so that we can change the display list. Lines 70-110 change the display list from ANTIC mode 2 to ANTIC mode 3. The jump command is moved up since there will be fewer display lines in this mode. The beginning address of this display list is also moved up. Line 120 turns ANTIC back on with the same value or status that it had before we changed the display list. 18 Line 130 subtracts 8 from the amount of memory available in our computer. This value is 2K less than the amount of memory in our computer. We will leave the top IK for the screen display and the display list. The second IK will be used for the character set. We will store the actual decimal address in NB. Line 140 stores the address of the character base in ROM in the variable CB. We also want to store this value in two more variables. Now we can manipulate the address without losing it. Lines 150-260 move the character set from ROM into RAM. If you look at your screen while the character set is being moved, you will see the distortion in several of the lower case letters. You will also see that the letters with descenders are no different in this mode than they are in mode 0. Line 150 transfers the characters from the space to the plus sign from ROM into RAM. When we transfer these characters, we want to take the last byte of the character and place it into the first byte for the character in RAM. The rest of the character will remain the same. Now the character will appear one scan line lower on the screen. The next character is the comma. We do not want to move its last byte first because the comma uses its last byte for data. The other characters that we just transferred do not. If we moved the comma the same way that we moved the other characters, the character would be distorted on the screen when it was printed because the data that it needs for the last row would be in the first row. The 13th through 26th characters will move down one scan line when they are moved. What we are doing in these lines is lowering all the characters one scan line so that the lower case characters that use the second byte for data will not be distorted on the screen (l,j,k,d,b,f,i,t). The characters that use the 8th byte for data, the graphic characters, the comma, and the semicolon are moved into RAM exactly the way they appear in ROM. Lines 270-330 move the data that is in the first byte for these letters into the second byte and repeat the data from the eighth byte into the first byte. These are the letters that have descenders. By adding one more byte of data to these letters, they will appear on the screen with true descenders. When the program is finished, move the cursor over some of the letters on the screen. You will see that the uppercase letters are centered and the letters with descenders are aligned with the last two rows of the cursor. The only letters or characters that place the first two bytes in the last two rows on the screen are the characters from the heart to the end of the character set. By replacing some of the lowercase letters/characters with numbers, you could create superscripts and subscripts. If you are not using any of the lowercase letters, you do not have to transfer the character set the way we did in this program. As long as you are using uppercase letters, numbers, and graphics, you can do a direct transfer of the characters, then create your own characters that would occupy the area normally used for the lower case letters. COLOR TEXT MODES As you can see in Table 2-2, ANTIC modes 6 and 7 correspond to graphics modes 1 and 2. These modes are capable of producing text in four different colors, plus a background color. The difference between these two modes is the size of the characters. Graphics mode 1 characters are just as high as graphics mode characters, but they are twice as wide. Graphics mode 2 characters are both twice as high and twice as wide as graphics mode characters. If you are writing a program where you need colorful letters, numbers, or characters of your own creation, it is much wiser, in terms of memory use to use one of these modes with a redefined character set than to use a higher resolution mode that uses more memory. 19 Table 2-2. All Display Modes Available with CTIA. ANTIC MODE BASIC COLORS i MODE CHARACTER POINT SIZE "V 5 6 8 9 A B C I.'i E F 1 4 E* ..I .■:7. 4 ■.'J /'. /i "Y .■;"). 8x8 8x10 o ■. .- o '...' .-■. KJ 8 k 16 i 6 k a 16x16 8 '■•' 8 .■:"). V;' /'. ••y .•■■. -y 2x2 ■■::■•...• v 2x1 1x1 There are two more text modes between graphics mode and graphics mode 1. These are ANTIC 4 and ANTIC 5. Both of these modes are unique in that they support multicolored text. They can also be used when you want to produce redefined characters that give the illusion of high resolution graphics using only a fraction of the memory. Normal text cannot be used in either of these modes because unlike graphics modes 1 and 2, these modes produce both the color and the shape of the character from the data in the character set. Normal text is illegible in these modes. The following program changes the display list to illustrate these ANTIC modes. 20 Listing 2-3. ANTIC 4 and 5 10 REM LISTING 2,3 20 REM ANTIC 4 Si 5 30 REM BY L.M»SCHREIBER FOR TAB BOOKS 4 ? " > C I... E A R :>■ " S R E M C I... E A R T H E S C R E E N 5 D I... I S T ~ P E E K ( 560 ) + P E E K ( 5 6 1 ) * 2 5 6 i R E M F IND THE BEGINNING OF THE B I SPLAY LIST 6 X ~ P E E K ( B I... I S T + 3 ) t P K E B I... I S T + 3 1 X + 2 1 R E M CHANGE THE FIST ROW TO ANTIC 4 70 FOR X-BLIST+6 TO BLISTT20 t POKE Xv4J NEXT X?REN CHANGE ALL THE ROWS EXCEPT THE FIRST ONE TO ANTIC 4 80 LIST {REM LIST THIS FRO GRAM ON THE SCREEN TO SHOW THE MULTICOLOR MO BE 90 FOR X~l TO 500 i NEXT XJREM WASTE TIM E 1 X = P E E K ( B I... I S T + 3 ) J P K E B I.. I S T +3 » X i :l. t R EM CHANGE THE FIST ROW TO ANTIC 4 110 FOR X-DLIST+6 TO DLIST+28 J POKE X»5 i NEXT XI REM CHANGE ALL THE ROWS EXCEPT THE FIRST ONE TO ANTIC 5 120 LIST J REM LIST THIS PROGRAM ON THE SCREEN TO SHOW THE MULTICOLOR MOBE When this program is run, the listing is shown in vivid yellow and blue. It is nearly impossible to read because the letters blur into each other. ANTIC 5 is nearly the same as ANTIC 4. The only difference is the letters/characters are larger. If you look again at Table 2-2 you will see that there are four different modes that support four colors, three character colors plus the background color. The fourth mode is sandwiched between graphics modes 7 and 8. With this mode, ANTIC E, each point on the screen is only one scan line high, but two pixels wide. It's height is half that of a point in graphics mode 7, but it is just as wide. To use this mode, you would set the screen for graphics mode 8, then change every row in the display list from 15 to 14. This is the highest graphics resolution that is available with color. In this table, you will also see an additional mode for two color graphics. It is located between graphics modes 6 and 7. This ANTIC mode is identical to ANTIC E except for the number of colors that it supports. With this mode, you can only set one color plus the background color. Graphics mode 8 is listed as a two color mode. In actuality, it is like graphics mode 0. The second color depends on luminance or brightness rather than being a true second color. Each of the modes from ANTIC 8-F uses more memory than the text modes. With the text modes, each memory location is one character. If our screen display is 40 characters wide by 24 rows, we are using 960 bytes for the screen display. The size of each character is 8x8 pixels. Which pixels are on and which are off is determined by the information in the character set. Each character uses 8 bytes of information stored in the character set. If the ATASCII value of the character is less that 128, the character will appear in normal video. If the ATASCII value is greater than 127, that is, if the high order bit is set, the character will appear in inverse video on the screen. The same holds true for ANTIC mode 3. 21 In graphics modes 1 and 2, which are both text modes, the character on the screen will be either 8x16, or 16x16. Each row on the screen is20 bytes long. Graphics mode 2 with no text window uses 480 bytes of memory (24x20). Graphics mode uses 240 bytes of memory (12x20) for the screen display. Both of these modes use only the last 6 bits of the internal value of the character on the screen. The first two bits determine which color is used. This is why only half of the character set can be displayed at one time. (If you have redefined characters, you will know that the order that the characters appear in the ROM character set is not according to their AT ASCII value.) By using the first two bits of each byte, the computer can choose one of four colors for the character that will be displayed on the screen. 00 (character) = color 01 (character) = color 1 10 (character) = color 2 11 (character) = color 3 The background color is set with color 4. The nontext modes do not follow this pattern. Graphics modes 3, 5, 7, and ANTIC mode E are four color modes. The character blocks on the screen can be one of three colors, the background is the fourth color. Each point that appears on the screen is not a byte. It is, rather, part of a byte. All the modes that are not text modes use only one or two bits per byte to determine the color that will appear on the screen. Graphics mode 3 displays 10 bytes in each row. With no text window there are 24 rows. 240 (10x24) bytes of memory are used for screen display in this mode. Let's say that we tell the computer to plot a point on the screen in position 0,0. We want the point to appear orange, so we will use COLOR1 . The computer will determine where in memory the first byte of the screen is located. This address is found in the display list. When the computer looks at the value of this byte, it should see 0000 0000 because there is nothing on the screen in this location or the next three locations. After the orange point is on the screen, the value of this byte of memory will be 64. The binary value of this memory byte is 0100 0000. The first two bits now tell the computer to use the color in color register 1. The next three positions are left empty. If we wanted to use green, the color in the second color register, the value of this memory byte would be 128 decimal, or 1000 0000 binary. When a color is plotted in the next position, the computer changes the values in the next two bits of the memory byte. Refer to Fig. 2-2 for the color values and to Fig. 2-3 for a sample point. Graphics modes 5 and 7 are nearly the same. Graphics mode 5 uses 20 bytes in each row, and graphics mode 7 uses 40. Because of the way that the ATARI stores the color information, only three colors plus a background color can be displayed in these modes. If the computer used 4 bits per byte to display color, we could have 16 colors on the screen. Of course, the computer would need twice as much memory for the screen display. The number of pixel rows per graphic row will depend on which mode we have chosen. Graphics mode 3 is 8 pixels high, Graphics mode 5 is 4, and graphics mode 7 is 2. ANTIC E also displays three colors plus the background color. It uses one row of pixels per row. Graphics modes 4 and 6 can display only one color in addition to the background color. Each bit in the byte of memory on the screen determines whether or not that point will be on. If there is a 1, the color in color register will appear on the screen. If there is a 0, that point will appear blank. Mode 4 is the same resolution as mode 5, but because each memory byte in mode 4 22 Fig. 2-3. Screen byte. * The four points on the screen are one byte. The color of each point is determined by two bits. In graphics mode 3, if the byte is 00 01 00 11, then the four points would be: off (or background), orange, off (or background), blue. represents one point on the screen, it uses half as much memory for screen display as mode 5. Graphics mode 4 displays 10 bytes in every row on the screen. Each point is 4 pixels high. Graphics mode 6 uses 20 bytes in each row. Each point is 2 pixels high. The ANTIC mode C also displays one color plus the background color. It displays 20 bytes in each row. Each row is one pixel high. Each of the graphics modes described above is as many pixels wide as it is high. Each point appears as a square on the screen. The two ANTIC modes are both two pixels wide, but only one pixel or scan line high. Graphics mode 8 is the only mode where each pixel can be individually controlled. Each row on the screen is 40 bytes. Each bit of each byte controls one pixel on the screen. If the bit is a 1 , the pixel will be on. If it is a 0, it will be off. Unfortunately, the color of the on pixel is set by the luminance or brightness of the color in color register 1, but the actual color is the same as the background color. Graphics 8 uses the same amount of memory as ANTIC E. Remember the first program in this chapter where we poked values onto the screen? The computer thought that we were in a graphics mode. Each character that it was given to print on the screen was treated as a graphics character. That is, it took the last two bits of the character and stored them in a byte for the screen display. It took the last two bits of the next character and stored them in the next two bits of the memory byte. By poking the data directly into the screen memory, we were able to trick the computer into printing the characters that we wanted on the screen. The characters also had to be the hardware value for the characters that we wanted displayed rather than the AT ASCII value. We will go into the differences between the hardware value of a character and its ATASCII values in Chapter 12. Listing 2-4. Color Artifacting :LO REM LISTING 2,4 20 REM COLOR ARTIFACTING 30 R EM BY 1... , M . S C l-l E E .'!.' B E R F O R TAB B K S 40 GRAPHICS 8 50 D 1... I S T = P E E K ( 56 ) + P E EK < 56 1 > *2 56 60 C ~ P E E K ( D 1... I S T -f 3 ) X P K E D 1... I S T + 3 1 C ■- 1 23 Listing 2-4. Color Artifacting (continued from page 23). 70 X=*6 80 IF PEEK200 THEN 120 110 GOTO 80 120 COLOR It FOR R«0 TO 9 J FOR C=0 TO 15 9 1 PLOT CrRtNEXT C I NEXT R :l. 3 C 1... R 1 i F R R ■ 1 T 1 9 J F R C = 1 T 159 STEP 2 J PLOT CyRSNEXT J NEXT R 140 FOR R~20 TO 29 J FOR 0=0 TO 158 STEP 2: PLOT CrRtNEXT J NEXT R 150 STOP This program changes the display list to ANTIC E. Using only one color register, it paints different colors on the screen. 24 Chapter 3 Graphics Once we have decided on which mode or modes we will be using for our program, we can decide whether or not the standard character set will be suitable for our program. If it is, we can start working on the program. More than likely, if we have a particular design to our program, we will want to construct our own character set. We may want to redesign all the letters for special effects, or we may just want to recreate a few of the graphics characters for our particular application. Before we can redesign the characters, we must understand the size and structure of the character set. CHARACTER SET MAKE-UP As we determined in the previous chapter, each character in graphics is 8 pixels or one byte wide and 8 rows or bytes high. The information to create one character on the screen occupies 8 bytes in the character set. The entire character set uses IK or 1024 bytes of memory. This information is stored in ROM beginning with location 57344. The characters in the character set are not in ATASCII order. In order to implement the color text modes (graphics modes 2 and 3), ATARI chose to change the order of the characters. On any computer, the ASCII value of A is 65. This is true on the ATARI computer. The change occurs internally. When the character set is stored in ROM, the first character is the space. It is followed by the exclamation point, quotation marks, etc. These hold the ATASCII values 32, 33, 34. What has happened is that the characters from 32 - 95 have been shifted up. These are the numbers, symbols, and uppercase letters. The graphic characters which appear to occupy the first 32 positions in the character set are moved to the area just past the uppercase letters and just before the lowercase letters as shown in Table 3-1. Now when you work in graphics modes 1 or 2, you can select either uppercase letters with numbers and symbols, or lowercase letters with graphics. Each character in the character set uses 8 bytes. To find the set of bytes for a particular character, we multiply its place in the character set by 8 and add the product to 57344. Let's look at the construction of the exclamation point. It is the second character in the character set, but since the first character is in the zero position, the exclamation point's place is 1. 1 x 8+57344=57352. The data to place an exclamation point on the screen begins in this memory location. Use the following program to PEEK at this information. 25 Listing 3-1. Data for Exclamation Point 10 REM LISTING 3 ♦ 1 20 REM DATA FOR EXCLAMATION POINT 30 REM BY LINDA M. SCHREIBER FOR TAB B 00 KS 40 CB-57344JREM BEGINNING ADDRESS FOR CHARACTER SET IN ROM 50 EP=1*8+CBJREM MULTIPLY THE LOCATION OF THE CHARACTER BY 8 AND ADD THE BEG INNING ADDRESS OF CHARACTER SET 6 ? " > C I... E A R :>■ " I R E M C I... E A R T H E S C R E E N 70 FOR X=EP TO EP+7JREM GET THE INFORM AT I ON 8 ? P E E K < X ) t R E M P R I N T T H E I N F R M A T 1 N 90 NEXT X The following number should appear on your screen: 24 24 24 24 24 This information determines which pixels will be turned on to form the exclamation point as shown in Fig. 3-1. Because the character set is located in ROM, it is fixed. This character set cannot be changed. But . . . there is a pointer in RAM that tells the computer where the character set begins (location 756 decimal). By changing the value of this location, we can point to a new character set— one that we have created and stored in RAM. The only limitation we have is that the character set must begin on an even IK boundary if we are using 1024 bytes or the entire character set. It must begin on an even V2K boundary if we are using the color text modes. The color text modes display only half of the character set at a time, so we do not need the entire character set in RAM. The character set developed and stored in RAM can be placed in any convenient location. Of course, it should not be in the way of the screen display, display list, or BASIC program. The best place for it is just before the display list. This way it is high enough in memory to be out of the way of our program, but it will not interfere with the screen in any way. RESTRUCTURING THE SET There are several programs on the market today to help you restructure or edit your character set. What these programs essentially do is move the character set from ROM into RAM, then display the character that you want to edit in a large form on the screen. You turn on or 26 decimal code 32 33 34 35 65 66 67 97 98 99 character space A B C (cntl ,) (contl A) (cntl B) Table 3-1. Position of Characters in Character Set. off the pixels that make up the character. When you are satisfied with the character, you can store it in the character set. When you are finished creating new characters, you can store the new character set on disk or cassette. Another way to create a new character set is to move the character set into RAM, design your new characters on graph paper, set the decimal value of each of the eight rows that make up the character, and then poke these values over that character that you intend to replace. Obviously, it is much easier to create new characters with the aid of a program than it is with paper and pencil. If you are redesigning most of the characters in the set, you would want to use the first method. To redesign a few characters, you could use the pencil method. The following program will allow you to redesign the character set and save the new character set to disk or cassette. This set can then be used by any BASIC program. d & c i )Yi /■> I. ■ 1 & x til! 1111 [ill A Fig. 3-1. The exclamation point. ! ! ! ! X I I ! 1 ■•-..-' fill "■..-■ 1 1 1 J /■. lilt till V I | | () j ! '■ 94 1 j | O A '■ j j 0£ 1 j ! OA i 1 i 1 f ! OA 1.8 18 1.8 i O 1. "...' () o o 27 Listing 3-2. Character Set Editor :L0 REM LISTING 3.2 20 REM CHARACTER SET EDITOR 30 REM BY L*M. SCHREIBEE FOR TAB BOOKS 40 DIM B*<10> rCV<7r7) f NAME* (8) v NAM* (14 ) »P:l.*(20> 50 DATA ! » r ! I t v EDIT * LETTER 55 REM DATA !» CTRL-ORE* I \t CTRL-ZRC > EDIT t LETTER ■■•■ CONTROL CHARACTERS FOR M BOX 60 GRAPHICS J POKE 752*1 J? "CTRL E ~ TO EDIT A CHARACTER" J? "CTRL S -• TO S TOP EDIT" 70 ? "CTRL D •- SAVE SET TO DISK";? " CTRL I... •••• LOAD SET FROM DISK"?? "CTRL Q - QUIT" 80 FOR X~16 TO 23 J FOR C~6 TO 13 ! POSIT I ON XyCJ? ""JNEXT C JNEXT XJREM MAKE AN 8x8 DISPLAY WITH CTRL-T 90 READ B*JFOR X=9 TO 13 I READ B*J POSIT ION 9»XJ? B* J NEXT X 1 A ■ P E E K < 1 6 ) ••■• 8JNCB=A#256J R E M P I... A C E NEW CHARACTER SET 2K BEFORE END OF MEM (DRY 1:1.0 POKE 204 k At POKE 206 » 224 J REM STORE THE NEW CHARACTER SET ADDRESS AND THE ROM ADDRESS 120 FOR X=l TO 20 J READ B J PI* < X , X ) -CHR* (B) JNEXT XJREM MACHINE LANGUAGE SUBROU TINE TO MOVE CHARACTER SET 125 DATA 104 » 162 t 4 > 160 f t 1 77 > 205 t 145 f 2 03 r 200 ? 208 1 249 t 230 r 206 r 230 t 204 » 202 » 208 »242y96? :l. 30 Q ■ U SR* CHR* " 5 E N D ? R E M D N E W I T H C H ARACTER SET 250 IF B-12 AND E~Q THEN 1690? REM GET NEW CHARACTER SET 260 REM USE THE NEXT 5 FOR TO EDIT A C l-l ARACTER 270 IF E»l AND B™42 THEN 650? REM GO RI GHT 280 IF E~l AND B=«43 THEN 670? REM GOT I... EFT 290 IF E~l AND B~45 THEN 690? REM GO UP 300 IF E~l AND B~61 THEN 710? REM GO DO WN 310 IF B-32 AND E~l THEN 750? REM CHANG E BIT 320 GOTO 210 400 P S I T I ON 3 v 1 6 ? ? " P R E S S I... E T T E R T E BIT" tGET #4j-B 410 IF (B>26 AND B<32) OR (B>124 AND B < 1 2 8 ) T H E N P S I T 1 N 1 1 r 1 ? ? C H R $ C 2 7 ) i C HR$127 THEN 450 440 P S I T 1 N 1 1 t 1 ? ? C H R $ ( B ) t G T 460 4 50 POSITION 5.17?? "CANNOT EDIT THAT C H A R A C T E R " ? E ~ ? F R T L - 1 T 1 1 N E X T T I... 460 POSITION 3.16?? " " ? POSITION 5.17?? " " j if i::>o THEN 210 470 AS=BJIF B>31 AND B<96 THEN AS=B-32 29 Listing 3-2. Character Set Editor (continued from page 29) J GOTO 490 480 IF B<32 THEN AS«B+64 490 CP=NCB+AS*8JREM POSITION OF CHAR AC TER IN CHARACTER SET 500 F R ■■■■: T 7 J C V ■ P E E K ( Q + C P ) i R E M E T THE VALUES FOR THE CHARACTER 510 CV(Oi-a)™OJIF CV>127 THEN CV<0»Q>-1 JCV=CV~128 520 C V ( :l. t Q > ~0 J I F C V > 6 3 T H E N C V ( 1 s> Q ) ■ 1 ! CV=CV~64 530 C V ( 2 v Q ) - J I F C U > 3 :l. T H E N C V ( 2 v Q ) ■ 1 J CV=CV~32 540 CV<3»Q)=0tIF CV>15 THEN CU(3»Q)»1 J CV=CV~16 550 CV(4»Q>=0JIF CV>7 THEN CV<4»Q)»ltC v=cv-8 560 C V ( 5 r Q ) - ! I F C V > 3 T H E N C U ( 5 i ) * I I C M-CM-4 570 C V < 6 » ) = i I F C M > 1 T H E N C ( 6 » ) * 1 J C V=CV-2 580 CMC7j«)~CV 590 NEXT 600 X~i6JC~6JF0R Q~Q TO 7 IFOR 0:1.-0 TO 7 J P S I T 1 N X + Q 1 t C + Q I ? " " ! I F C V ( Q :l. t Q > * i T h E n p o s I T :i: N X + Q :l. i C + Q I ? " " 6:1.0 NEXT 0:1. J NEXT Q J LOCATE XyCfCHIPOSIT ION X. C 1 I F C H < :l. 2 8 T H E N ? ■ * ■ i G T 630 620 ? "*" 630 IF E«l THEN POSITION 3? 16 J? "USE A RROW KEYS TO EDIT" 640 GOTO 210 650 P S I T I ON X > C J ? C H R $ ( C H ) J X * X + 1 J I F X >23 THEN X~16 660 GOTO 720 670 P S I T I ON X » C J ? C H R $ ( C H ) J X - X - :l. J I F X <:l.6 THEN X=23 680 GOTO 720 690 P S I T I ON Xy C i ? C H R * ( C I -I ) i C « C ••■■ 1 J I F C <6 THEN C=.13 700 GOTO 720 710 P S I T I ON X t C { ? C H R * ( C H ) I C ~ C + 1 J I F C >13 THEN 06 720 I... C A T E X y C » C H ! P S I T I ON X t C t I F C 1-1 > 1 27 THEN ? "*■ J GOTO 740 30 730 ? "*" 740 GOTO 210 750 LOCATE X»C»C2JIF C2>:l.28 THEN CH--20 J C 2 ■■■■■■■■ C 2 ■- 1 2 8 iC < X ••■• 1 6 y ■••■ 6 ) ~» X G T D 770 760 C H = 1 6 t C 2 = C 2 + 1 2 8 t C ( X ■•■• 1 6 y C - 6 ) - 1 770 POSITION X >CJ? CUR* ( C2 ) J GOTO 2:1.0 800 POSITION 3>16t? "EDIT PIN I SHED " {REM CHANGE MESSAGE 810 CV=0:B~.t28JF0R Q»0 TO 7? FOR Q1«0 T 7J REM CONVERT THE 1 Si O'S TO DECIMAL 820 IE CV--l THEN CV-CV+B 830 b=b/2:next gurem REDUCE b for eac H POSITION 840 POKE CP+GrCVJREM CHANGE THE BYTE I N THE CHARACTER SET 8 5 C V ~ X B ■■■■■■ 1 2 8 l R E. M R E S E T T H E A R I A B L E S FOR NEXT BYTE 860 NEXT B J REM FINISH THE CHARATER 870 C P = N C B i P S I T 1 N 1 1 ■• 1 J ? " " I R E T U R N J REM RESET TO CLEAR THE CHARACTER FRO M SCREEN 1640 N A M $ ~ " " X P S I T 1 N 3 ; 16J? "ENTER NAME F R F 1 1... E " 5 J I N P U T NAM E $:iF NAME*^" " THEN 200 1650 NAM$ ( 1 9 2 ) ~ " D J " t N AM* ( 3 v 1 ) «NAME* : N A M * ( 1 1 , 1 4 ) m » t C I -I B " : R E M C D E F 1 1.. E F R C H ARACTER BASE 1660 TRAP 1740 J OPEN #2 v 8 * «NAM* : FOR Q« NCB TO NCB + i023:CV-PEEK J REM GET THE VALUES FOR THE CHARACTER SET 1670 PUT #2 y CO J NEXT OS REM PUT THE OALU ES ONTO DISK 1680 CLOSE #2: GOTO 200 1690 NAM*= " " ■> POS I T I ON 3 y 16:? " E N T E R NAM E F R F I L E " i X I N P U T NAM E *:IF NAME*=" " THEN 200 1700 NAM* ( 1 y2) = "Bt B X NAM* ( 3 ) -NAME* J NAM* < L E N ( N A M E * ) + 3 ) = " . C H B " X R E M C D E F I L E F R CHARACTER BASE 1710 TRAP 1740 J OPEN #2 t 4 » » NAM* : FOR Qa NCB TO NCB+1023JGET #2 y CO {REM GET THE VALUES FOR THE CHARACTER SET 1720 POKE Q, CVt NEXT QJREM PUT THE VALU 31 Listing 3-2. Character Set Editor (continued from page 31) ES ONTO DISK 1730 CLOSE #2 5 0010 200 1740 ER=PEEK(195)JCL0S E # 2 J R E M G E T T H E ERROR NUMBER & CLOSE FILE 1750 IF ER=170 THEN POSITION 3»16J? " F ILE NOT FOUND " J GOTO IS 00 J REM GIVE ERROR MESSAGE 1760 IF ER-162 THEN POSITION 3»16J? " D ISK FULL " J GO TO IS 00 1770 IF ER=169 THEN POSITION 3* 16 J? "D I R E C T R Y F U L I... •••• GET N E Ul D I S K " J GO TO :l. 8 00 1780 POSITION 3 i 16 J? "WE'VE GOT A PR OB LEM 1800 FOR X~l TO 100 1 NEXT X J GOTO 200 Line 50 is the data needed to draw the box on the screen to show what letter/character is being edited. Be sure that this data line is entered exactly as follows: an exclamation point, a space cntrl-Q cntrl-R cntrl-C, space shift-equals space shift-equals, space cntrl-Z cntrl-R cntrl-Z, space EDIT, LETTER. Lines 60-70 set the graphics mode to 0, erase the cursor, and print the control codes on the screen. Lines 80-90 print the grid and box on the screen. Use the cntrl-T to make the 8x8 grid. Line 100 finds the end of memory and calculates the address that would be 2K before the end of memory. This leaves IK for the character set and IK for the screen display and display list. Line 110 pokes the new character set address and the old cha> acter set address into RAM. These two values will be used in the machine language subroutine that moves the character set from ROM into RAM. Line 120 contains the machine language subroutine to move the character set from ROM into RAM. Pl$ must be exact if the routine is to work correctly. The data for the subroutine is in line 125. Be sure that these numbers are entered correctly. If they are not, the program will crash. Line 130 uses the USR function to call the machine language subroutine. The Q is a dummy variable. Line 140 changes the address of location 756 from the character set in ROM to the character set in RAM. Lines 150-180 print the entire character set on the screen. In order to print some codes, the escape key must be entered first. When we are printing characters using the CHR$ command, we can issue an escape code by printing CHR$(27) just before the character. In this way we can display all the characters in the character set. Line 190 opens the keyboard for reading. When editing the character set, we will use only one key stroke commands. 32 Line 200 prints the prompt under the square and grid. There are 15 spaces after the T to clear out any previous message. We will be returning to this line after several of the subroutines in this program. The variable E will be our flag to let the computer know whether or not we are editing a character. When it is set to 0, we can use the control codes to begin an edit, load a character set, save a character set, or quit. When the E is set to 1, we can stop an edit or edit a character using the arrow keys. The variable X is the row that the cursor is in on the screen, and C is the column. Line 210 gets the keystroke from the keyboard and checks it for a control-E. If it is a control-E and we are not in the edit mode, the variable E will change to 1 and the program will go to line 400. Line 220 checks the variable B for a control-S. If the program is in the edit mode, and the control-S is pressed, the program will leave the edit mode and go to the routines that will restore the grid and erase the character in the box. The variable E is also reset to 0. Line 230 checks for a control-D. When a control-D is pressed and the program is not in the edit mode, the program will save the character set displayed on the screen. This program stores the character set to disk. It can be changed to store the characters to cassette by opening the cassette instead of the disk. You do not need a name for the file if you are using a cassette. Line 240 will end the program when a control-Q is pressed. Before ending, the program will restore the ROM character set, restore the cursor, and clear the screen. Whenever an alternate character set is used in a program, it is good programming practice to reset the pointer to the ROM character set. Loading a new program with an alternate character set could confuse the next user. Line 250 will direct the program to the routine that loads a new character set from disk or cassette when a control-L is pressed. Lines 270-310 will direct the program to the lines that alter the character set when the variable E is set to 1 and an arrow key or space bar is pressed. Line 320 will loop back to line 210 if the key pressed is not one of the control keys used in this program. Line 400 begins the edit mode. The prompt under the grid is changed and the program waits for a key to be pressed. Lines 410-460 check the key that has been pressed. If it is one of the screen function keys, clear screen, line up or down, etc., the program will not allow it to be edited, and will print a message to that effect on the screen. If it is a character that can be edited, it will be printed in the box on the screen. Lines 470-480 check the value of B and store the actual location in the character set in variable AS. B is stored in AS before it is checked. There is no else command in ATARI BASIC, so we will store the actual value of B in AS. If it is not a character whose location needs to be changed, AS will be set correctly. If the AT ASCII value of the key pressed is greater than 31 and less than 96, that is any key other than a graphics character or lowercase letter, the program will subtract 32 from B and store it in AS. These are the characters that have been moved up in the actual character set. If the value of B is less than 32, a graphics character has been entered and the program adds 64 to the value of B and stores it in AS. Remember that the graphics characters are located between the uppercase letters and the lowercase letters in the actual character set. Line 490 calculates the position of the first byte of the character in the character set. The position of the character that is stored in AS is multiplied by 8 (each character uses 8 bytes) and this value is added to the location of the character set. The variable CP contains the location of the first byte of the character that will be edited. 33 Lines 500-590 convert the decimal value of each byte into a binary value. Each bit is stored in the array CV. This routine is similar to the routine used in Chapter 1. It takes the decimal value of the byte and compares it to 127. If the number is greater than 127, then the first bit is a one. The program subtracts 128 from the value in CV. The next line checks the remaining value to see if the next bit should be set. Each line continues to check the value of CV against the value of that bit less one. We use one less than the actual bit value because if that bit were set, and we subtracted the bit value, the remainder would be zero. There would be no indication that we should get that bit unless the decimal number was larger than the bit value. By using the bit value less one, we will get a remainder of one if the decimal value is equal to or larger than that place value. Every time the program sets a bit to one, it subtracts the value of that place or bit from the decimal value of the byte. This routine is repeated 8 times; once for each byte that makes up the character set. Lines 600-620 reset the row and column values for the 8x8 grid and using the values in the array CV, draws the character onto the grid. A control-T is printed. Then the value of CV is checked for a 1. If that element of the array does contain a 1, an inverse-video cursor will be printed. Once the entire character has been drawn, the program will use the locate command to find out what has been printed in the upper left corner of the grid. The AT ASCII value of this character will be stored in the variable CH. The asterisk will be our cursor while editing. If the character in the upper left corner is in inverse-video, an inverse-video asterisk will be printed there. Line 630 checks E to see if we are, in fact, in the editing mode. If we are, it prints the prompt on the screen. This routine then goes back to line 210. Lines 650-740 move the asterisk cursor in the grid. The character that is stored in CH is printed in the grid where the asterisk is. If we are moving the asterisk to the right (line 650), the variable X is incremented. If we are moving it to the left (line 670), X is decremented. Moving the asterisk up (line 690) decrements C and moving it down (line 710) increments C. After the variable X or C is changed, the program checks it to make sure that it is not beyond the grid area. If it is, the variable is reset to the other side of the grid, giving it a wrap-around feature. Once X or C are correctly set, the program gets the ATASCII value of the character that the asterisk will be replacing and stores it in CH. Once again, if the character was in normal text, an asterisk will be printed. If the character was an inverse-video cursor, an inverse-video asterisk will be printed. Lines 750-770 change the character in the grid from a ball (cntrl-T) to an inverse-video cursor and back again. When the space bar is pressed, and the program is in the edit mode, it will be directed to this routine. The locate command gets the ATASCII value of the cursor. If it is in inverse-video, then the value of the character that was there will be changed to 20 (cntrl-T), and the asterisk will be reprinted in normal video. Otherwise, the character that was there will be changed to the inverse-video cursor value, and the asterisk will be printed in inverse-video. When the value of CH is changed to 160, indicating that we are setting that bit, the value in the array CV is changed to 1 for the corresponding bit. When we erase a bit from the screen, the value of the corresponding bit is changed back to 0. Lines 800-870 are used when we are satisfied with the new character that we have just created. The new prompt is printed on the screen, and the values stored in the array CV are converted into decimal. This procedure is simpler than the convert from decimal to binary routine. The variable CV is cleared. This variable contains the decimal value of the character. The variable B is set to 128 - the bit value of the most significant bit in the byte. If the leftmost bit is set to one, this value will be added to CV. Since each bit is half the value of the preceding bit in a byte, we divide B by 2 each time we check the next element of the array. Each time an element 34 contains a 1, we add the value of B to CV. After we have checked each of the 8 elements of the array that represent the byte, we will have the decimal value of that byte. That value will be poked into the position of that byte in the character set in RAM. The variables CV and B are reset after each byte . Once the entire character has been moved into the character set, it is removed from the box on the screen and the routine returns to the main part of the program. Since the entire character set is displayed on the screen and it is being used for the prompts as well, it would not be wise to change the uppercase letters or the characters that are being used in the editing modes, especially the control-T, unless absolutely necessary. Lines 1640-1680 save the character set that we edited to disk. The string variable NAM$ is cleared of the last entry, or garbage that the string contains from the previous program. The name that you want to call this set is placed in NAME$. If you press the return key without entering a name, the program will return to the menu. All good programs have an abort code that returns you to the menu should you enter a routine by mistake. When you enter the name of the character set, you do not have to enter the D: before the name. Line 1650 takes the name that you enter and adds the D: before the name. It also appends the name with .CUB. This will separate the character sets from any other programs or files on the disk. The program then opens the file and, using the peek command gets every byte of the character set, and puts in on the disk. When the entire set has been stored on disk, the file is closed. There is a trap set before the file is opened. If the disk or the directory is full, it will be reported on the screen. Lines 1690-1730 get the character sets that we previously stored on the disk. The string variable NAM$ is cleared, and the program asks for the name of the character set that you would like to bring in. If you press the return key without entering a name, the program will return to the main menu. Once again, the program will add the D: to the beginning of the character set name, and .CHB to the end of the name. The trap is set, and the program will bring in the character set. This routine can be used in any program to bring in a character set that is stored on disk. Instead of having the program ask for the name of the character set, you could specify it in the program lines. This way, any character set that is designed with this program can be used with any other program. Once the character set has been read in, the program will close the file and return to the menu. Lines 1740-1800 trap the disk errors. The error number is stored in decimal location 195. By peeking at this location, we can get the number of the error. If the file was not found, the disk is full, or the directory is full, this message will appear on the screen. If any other error caused the program to go to this routine, We've got a problem will be printed on the screen. Normally, every possible error is tested for, but in this case, the error could be 144, which could be the result of anything from a bad disk to the disk door being left open. In this program, we'll let the user know that something has gone wrong, and then return to the menu. The character sets created with this program can be used in any program that requires a different character set. It can be used in text mode or the colored text modes. If you have a cassette recorder, change the following lines. 70 change the word disk to cassette 1640 delete the INPUTs 1650 delete 1660 change the OPEN command to OPEN #7,8,0,"C:" 35 1680 CLOSE #7 1690 delete the INPUT 1700 delete 1710 change the OPEN command to OPEN #7,4,0,"C:" 1730 CLOSE #7 Lines 1740-1800 can be deleted or changed for cassette errors: error 143 and error 138. When using the new character set in another program, calculate the location of the new character set. This will be the first location that the first byte of the character set will be poked in. Always begin the new character set at least IK before the display list and the screen display. THE INVISIBLE MODES In the last chapter, we looked at all the modes that are available on the ATARI. Some of these modes are available in BASIC, others can only be accessed by changing the display list. Using the character editor in this chapter, we could reconstruct the lowercase letters for ANTIC 3, save them to disk, then read them in for the program. We would not have to move the character set from ROM. We would have our new set on disk. Two other modes between graphics mode and graphics mode 1 are ANTIC 4 and ANTIC 5. Both of these modes are text modes, but they support multicolored characters. Each character in these modes is eight pixels wide, but the pixels are turned on or off in pairs. The net effect is that the character is four bits wide. The color of the character is determined by the bit combination of every pair of bits in the byte. Look at Fig. 3-2. The first bit pair is 11. The pixels that would be turned on for this part of the character would be in the color set by color register 3 (peek 711). The second pair of bits, 01, will be the color of color register 1 (peek 709) . The third bit combination, 10, will be the color of color register 2 (peek 710). The last bit combination is 00. This is the background color, the color of register (peek 708). The characters designed using these modes can be one color, or several colors. In the following program, we will design a screen that uses ANTIC mode 4. It gives the illusion of being graphics mode 7 without the memory consumption. This type of program is called a simulation. It simulates a simple circuit. When the circuit is complete, the light will light; when it is broken, the light will go out. The bottom of the light and the wire is the same character. The top of the battery and the wire is also the same character. By using two different bit patterns in each of these characters, we can create a two-color character. By using three different bit patterns, we could create a three-color character. O ' i Fig. 3-2. Bit pairs for color. i i Each pair of bits represents a different color redi ste r ♦ 36 Listing 3-3. Multicolor Characters 20 REM ANTIC 4 - MULTICOLOR CHARACTERS 30 REM BY L*M. SCHREIBER EOR TAB BOOKS 40 DIM PI* (20) 50 A-PEEK(106)-8JNCB-A*256JREM PLACE N EW CHARACTER SET 2K BEFORE END OF MEMO RY 60 POKE 204 t A {POKE 206»224{REM STORE T HE NEW CHARACTER SET ADDRESS AND THE R OM ADDRESS 7 FOR X-l TO 20 J READ BJPl$(X»X)=CHRf( B ) : N E X ■ I ■ X J R E M MAC H I N E L A N G U A Q E S U B R U T INE TO MOVE CHARACTER SET 75 DATA 104s»i<52»4»l<50»0i>177f205»i45>20 3 t 200 » 200 t 24? y 230 t 206 i 230 r 204 r 202 y 208 > 242y96 8 - U S R ( A D R ( P 1 $ ) ) { ? " > C I... E A R > " J R E M USE MACHINE LANGUAGE PROGRAM WITH THE USR FUNCTION 9 D I... I S T = P E E K ( 5 6 ) + P E E K ( 5 6 1 ) * 256 { REM G ET THE LOCATION OF THE DISPLAY LIST 100 POKE DLIST+3»A8{REM CHANGE THE FIR ST LINE TO ANTIC 4 110 FOR X^DLIST+6 TO DLISTf 28 { REM IN G RAPHICS THE DLIST IS 32 BYTES LONG 120 POKE X i-4 {REM CHANGE ALL THEN LINES TO ANTIC 4 130 NEXT X 140 REM CONTROL A •- UPPER LEFT CORNER 150 DATA 85f6A»6A y 64 y 64 » 64 y 64 y 64 160 REM CONTROL.. B - TOP LINE 170 DATA 85 y 0*0* On QrO t ()« 180 REM CONTROL C - TOP OF BATTERY 1 90 DATA 81 y 1 7 y 1 7 1 17 9 170 v 170 t 1 70 r 1 70 200 REM CONTROL D - UPPER RIGHT CORNER 2 1 D A T A 8 5 y 1 » 1 y 1 t 1 i 1 t 1 t 1 220 REM CONTROL E - LOWER RIGHT CORNER 230 DATA 1 y 1 i 1 y 1 y 1 i 1 t 1 t 85 240 REM CONTROL. F ™ BOTTOM LINE 2 5 D A "I" A y t » t t y y 8 5 260 REM CONTROL G •••■ BOTTOM OF BULB 270 DATA 51 y5:l. y51 y51 y 12y 12y 12v85 280 REM CONTROL H - BOTTOM LEFT CORNER 37 Listing 3-3. Multicolor Characters (continued from page 37) 290 DATA 64f64r649 64*64r64i64r85 300 REM CONTROL I - I.. EVER UP 3 :l. .0 A T A y 2 y 8 y 3 2 » 1 2 8 v 320 REM GGNTRO! ) - LEVER PARTWAY DOWN 3 3 U A T A y y y y 1 y 3 2 y .'I. 2 8 y 340 REM CONTROL K - LEVER NEARLY DOWN 3 6 D A T A y v y y y 1 y 1 6 y 370 REM CONTROL L - RIGHT SIDE 380 DATA 64r64r64r64964r64964t64 390 REM CONTROL M •■•• LEFT SIDE 400 DATA I y I y I y I y I y 1 y I y 1 4:1.0 REM CONTROL N ■- LEVER DOWN 4 2 D A T A y y y y y y y .1. 7 430 REM CONTROL - BATTERY BOTTOM 440 DATA 170 y 170 y 170 y 170 y 170 y 1 70 y 170 y 1 70 450 REM CONTROL P ■••• BULB TOP 460 DATA OyOyOyOy 1 2 y 5 1 pSl *51 470 FOR X^NCB165*8 TO NCB + 81*8-1 t REM F IRST BYTE OP CONTROL A 480 READ B J POKE XyBSNEXT XJREM REDES I G N CONTROL CHARACTERS 4 90 POKE 756 » A J REM USE THE NEW CHAR ACT ER SET 500 P S I T 1 N 1 5 y 1 i ? " > A B B B C B B D > " i P S I T 1 N 1 5 y 1 1 I ? " > I... > > }• > M :>• " ; P S I T 1 N 15 v 12 if ">L> >P> >M>" 5 1 P S I T 1 N 1 5 y 1 3 i ? " > H P I F F G F E > " 520 T I... = 30 J G S U B 600} T I... - 5 5 3 P S I T 1 N 1 7 y 1 3 1 ? " > J > " S G S U B 6 1 X R EM BRING THE SWITCH DOWN 540 P S I T 1 N 1 7 1 1 3 t ? " > K > " J G SUB 610 550 P S I T 1 N :l. 7 y 1 3 i ? " > N > " J C = P E E K ( 7 1 ) {POKE 710 » 15 560 T I... « 3 t G S U B 6 J T I... - 5 570 P S I T 1 N 1 7 y 1 3 ! ? " > K > " J P K E 7 1 r C I GO SUB 610 580 POSITION 17»13t? " >J> " I GOSUB 610 590 POSITION 17»13t? ">I>"JGOTO 520 600 IF PEEK (53279)06 THEN 600 610 POKE 77 »0t FOR T«l TO TLJNEXT TtRET URN Line 40 sets Pl$ for 20 characters. The machine language subroutine to move the character set from ROM into RAM will be placed in this string. 38 Table 3-2. Machine Language Listing to Move Character Set From ROM to RAM. Dec i iii s 1 C a d 104 PL A As •-» ■.!■ 1... a i"i b Li a b e L i s ' v H u 1. .1. b i i v.o a tins ?cutjiulatar off 162 LDX :||: 4 the stack, i L o a d t h e :i. i i d b >; X w i 1 •i 4, 4 160 LEY #0 ? 1... o 3 d t i "i to i i i d b ;■; Y w i t t » 177 LB A (20 13 ) > Y 5 1... o a d t i "I 1 c •:;> • b r r i v e d a t i c o i") t b n t ■;:; o f t h B ITl e III Q T H c o n 1 e n t s :i. n 1 1 b n t s o f v :i. i"i t h 8 1 i •■.:■: s d d :i. n a index Y t .ocstion locstion : :, h e i. s the 205™ 145 S T A ( '"• : I ) '! Y t § t o v e t h b r i i..i m b b r :i. n " the 203 accumul a tor address srr: a d d :i. n s t h e i t h e :i. i"i d B ;■; Y c o n t e |-| t s o f 2 3 •- 2 O 4 <• in the . v e d s t b a :• o n t e n t s o with the locations '•" 39 Table 3-2. Machine Language Listing to Move Character Set From ROM to RAM (continued from page 39). v 1 1 1'..: rem i I'lftJ 1 1 1 fit? K T BNE INC.: 20 is INC 204 DEX BNE ? Br»:JI"lt?h if th&? 'I. I : ■' i (■:> A Y I : : riox d 3 c I '. w 3 r d s * D y t e s 5 A d d o i"i e t o t h g? n u in b s r i r ilocstrion 204 » i.i (■? c r e in e , n e i n a e w ? B r a i"i c ii :i. f t h e :i. n d © X X :i. s i"i o t b a c k w a r d s 1 3 b ■:> t e s « jfc -.■turn to BAS.I. C« Line 50 subtracts 8 from the number of pages of RAM in your system. This is 2K of memory. IK is set aside for the screen and display list. The other IK is for the character set. We will move it just before the display list. The variable NCB will contain the decimal location of the new character base. Line 60 stores the location of the new character base and the ROM character base in two temporary locations. These locations will be used by the machine language subroutine. Line 70 contains the machine language subroutine. The data for the machine language subroutine is in line 75. Be sure that all the numbers are entered correctly. Line 80 uses the USR command to execute the machine language subroutine. See Table 3-2 for the assembly language listing of this routine. Line 90 calculates the beginning address of the display list by multiplying the value of decimal location 561 by 256 and adding it to 560. The address of the display list is always a 2-byte figure. Lines 100-130 change the display list from graphics mode (ANTIC 2) to ANTIC 4. The first line of the screen is combined with a command that tells the CTIA where the first memory location of screen data is. To change this line to ANTIC 4, you must add 3 to the first address of the display list and poke this memory location with 68. Since ANTIC 4 uses the same number of lines on the screen as graphics mode 0, we know that there are 23 more locations to change from 2 to 4. By adding 6 to 28 to the address of the display list, we can change the entire screen from graphics mode to ANTIC 4. Lines 140-460 contain the data to change the standard graphics characters to the ones that 40 c o i "i t r o 1 A c o i"i t r q . B c o n t r o 1 f i IV *. i i A i i A i i A c o i"i t v o ! D cant rol cont.ro! c o n t r o ' G control c o i"i t r o . c a n t r o 1 J Fig. 3-3. Character set in circuit. 41 'ontrol c o n t r o :• o I'i t r o I i-J c o i'i t, r o . Fig. 3-3. continued from page 41. will be used in this program. Each character can be one, two, or three colors depending on which bits are set in each byte. See Fig. 3-3 for a detailed description of each character. Lines 470-480 read the bytes for each character and poke them into the correct locations. Line 490 changes the character set used from the one in ROM to the modified one in RAM. Lines 500-510 print the diagram on the screen. Each letter in the quotation marks should be entered as a graphics character. Use the control key to enter these characters into the program. Lines 520-610 make up the body of the program. The variable TL is set to 30. This value will be used in the timing loop. The program goes to the subroutine in line 600. Here it waits for the start key to be pressed. The program will continue to loop until the start key is pressed. Once it is pressed, the program will reset the attract mode, and enter the timing loop in line 610. This timing loop is needed to smooth the program. Without it, the computer would read that the start key was pressed before you had a chance to take your finger off the key. After the timing loop, the program returns to the line that it came from. The variable TL is reset to 5, and the program will lower or raise the lever. Again, be sure that each letter in the quotation marks is entered as a graphics character. We will use the timing loop after each time the lever is drawn. If the lever is being lowered, the light will glow once the connection has been made. If the lever is being raised, the light will go out as soon as the connection is broken. 42 ANTIC 5 could use the character set that we created in this program. The characters, however, would be 16 scan lines tall instead of the 8 in ANTIC 4. The display list would be shortened by 12 bytes. The characters drawn with ANTIC 5 would appear to be in graphics mode 5. Again, we can obtain higher resolution graphics without using large amounts of computer memory. 43 Chapter 4 Principles of Animation Good use of graphics will enhance any program. But graphics alone are like cake without icing. We all prefer movies to snapshots. Movies, cartoons, television, and most other forms of entertain- ment rely heavily on movement along with color, sound, and pictures. In real life, people, animals, and objects move with a particular rhythm. Any movement that differs from the norm appears unnatural and artificial. Artists try to imitate the natural move- ments of their characters when they create cartoons. Hundreds of drawings make up one feature length film. Each drawing is slightly different than the last, so that when they are run together, the characters move smoothly across the screen. Using animation in programs is not difficult, but it does take extra planning to create believable characters that move gracefully on the screen. CHARACTERS WITH A PURPOSE If we had a computer with block graphics, and no way to redefine the character set, we could make a few stick figures and leave the rest to the user's imagination. But, we don't. We can change the characters to create believable figures and characters. We can alter parts of the character so that when it is printed on the screen, we have true animation. Good graphics and good animation does not come easily. Each character that is drawn on the screen must be carefully thought out. We have several different graphic modes available to us. Before designing the character set, we must decide what type of program we are designing, how much animation or movement will be involved, and how the screen will be laid out for good color and movement. Once we have decided on the type of program, we can begin to design the characters. By using graph paper, we can set a good idea of what the character will look like on the screen. The first program that follows uses a very simple form of animation. As the keys 1-8 are pressed, a note floats up from the corresponding pipe and a tone sounds. The note does not appear all at once. Figure 4-1 shows the parts of the note that appear on the screen. Once the entire note is on the screen, it floats to the top of the screen. Four more characters are used to give the illusion of movement on the screen. When the note reaches the top, it does not disappear from the screen all at once. One row of the note is removed at a time until the entire note is gone. As you can see from the drawings, several characters had to be redefined to give the notes the different 45 1 ' ' v XiXiXIX!) I I F I A I I i A i A i i i i i i i i i A. i t I i i y i i i v y i v i v i v i i i i ■•./ i \.- lilt 1 X v * V I i ■■•-. i A I f ! X I i i i v j v ! v ! v ! V ! Y ! I ! i !X!> i i i j y i ! ! ! ! X I i A i A i i A i i V I V " I I i A i A i i i 7 i i i i v ' i liii A I i i i t I A I i ! X ! X ! IX! I xix:x!X!x: : i i i i A I v i v i i v ! A i A t I A "\ i A i A i A i A l v l V i l Fig. 4-1. Character set for notes. 46 I A I A I i A v j y i y i Y i v iXIX! ! :X!x: !X K!X!X!X:X !X!X! ! /\ X 1 I 1 V o 47 XiXiXIXiXiX!)* ! v A I A I A i A I A i A i A i A V ! V ! Y ! V ! V ! Y ! V ! V Fig. 4-1. continued from page 47. ' V X v x ¥ X y A x: i y y x x x x X y i 1 X x X. Y y y y Y ! ! X x x V A X X X ! ! ^ x X x X X x X ! i X V X v A x X i i /■•. A A x v A X ! 1 X x x x x V A y A ) forms that they need. Each note is just slightly different than the others. This keeps the movement of the notes smooth as they appear and disappear. If the notes were drastically different, their movement would be choppy and artificial looking. Listing 4-1. Simple Animation 10 REM LISTING 4*1 20 REM SIMPLE ANIMATION 30 REM BY L*M. SCI-IREIBER FOR TAB BOOKS 48 40 DIM NTE$<8) *P1*<20) 5 A ~ P E E K < :l. 6 ) -■ 8 I C B = A * 2 5 6 J R E M P L A C E C H AEACTEE SET 2K BEE ORE END OF MEM OR 60 POKE 204 s- AJ POKE 206*224 t REM STO HE NEW CHARACTER SET ADDRESS AND "f OM ADDRESS 70 EOR X=l TO 20 { READ BJP1*=C B ) : N E X T X I R E M MAC H I N E I... A N U A E SOB INE TO MOVE CHARACTER SET 75 DATA 1 04 * 162* 4 * 160 *0 * 177 * 205 * 145 » 20 Y RE T HE R HR$( ROUT 3 s- 200; 30*204*202*: 242*96 8 ■ U S R ( A D R ( P 1 $ ) > i R E M U S E MAC H I N E OUAOE PROORAM WITH THE USR FUNCTIO 90 EOR X~8 TO 175 i READ C X POKE CB + X EXT X 8* 12 * 1 r 8 r 8 * 1 04 * 248 » 96 4*6*5*9*8* 104*248 r 96 0*2* 3*5*9* 106* 124*48 8*12*10*8*4*52* 124*48 LAN N v C ! N 100 DATA 110 DATA 120 DATA 130 DATA 140 DATA 150 DATA 160 DATA 170 DATA '.) 192*32* 16*8*48* 112*96 12* 10*8*8*104*248*96*0 10 *8»8» 104 * 248 * 96* » 8 * 8 » 1 04*2 4 8 v 9 6 » » * 180 DATA 8*104*248*96*0*0*0*0 190 DATA 104*248* 96* 0*0*0*0*0 200 DATA 248*96*0*0*0*0*0*0 2 1 DATA 96*0*0*0*0*0*0* 220 DATA 0*0*0*0*0*0*0*8 230 DATA 0*0*0*0*0*0* 8 * 1 2 240 DATA 0*0*0*0*0*8*12*10 250 DATA 260 DATA 270 DATA 280 DATA 290 DATA 255 «> 255 * 255 > 255 » 255* 255 v 55 300 DATA 0*0*0*0* 8 y 1 2 1 1 * 8 0*0*0* 8 * 1 2 » :l. 0*8* 8 0*0* 8 * 1 2 * 1 * 8 t 8 * 1 4 0*8* 12* 10*8* 8* 104 *248 340 GRAPHIC XT MODE 350 POKE 75 SET IN RAM 360 R2-9JF0R I 17 J REM USE LARGE COLOR Tl A J REM NOW WE CAN USE THE TO 20 J FOR X=2 TO 16 49 Listing 4-1. Simple Animation (continued from page 49) STEP' 2 J POSITION XrRJREM HAKE THE PIPES 370 I F R - X < > R 2 T H E N ? # 6 i * 4 " J 6 T 390; REM MAKE THE PIPE SOLID 380 ? # 6 5 " 5 " ! R 2 - R 2 ■■■• 1 i R E M M A K E T H E A I R HOLE 390 NEXT X J NEXT R 400 N T E $ = " y 1 v i: Q H < " : R E M C H A R A C T E R F T HE NOTES-wl diamond left -brae Ret QH@< 410 OPEN #4v4y0y "KJ " J REM OPEN THE KEYB OARD FOR A READ 420 POKE 7 6 A » 255 1 GET #4»CtIF Oil. 2 7 THE N OC -128: POKE 694vOJREM GET THE KEY P RESSED 430 IF C<49 OR C>56 THEN 420 J REM NOT A NUMBER 440 CLOSE #4 J REM SOT THE NOTE 450 c<;-4s;rem PLACE OF NOTE 460 X=C#2iR~9JREM COLUMN FOR THE NOTE ON THE SCREEN 470 SOUND r ASC ( NTE$ ( C v C) ) » :l. <> 1 t REM S OUND OF THE NOTE 480 FOR Rl«l TO 7 I POSIT ION X y R J? *6iCH R $ ( 4 4 ■{• R 1 ) : R E M P R I N T P A R T F T H E N T E 490 GOSUB 800 : REM TIMER ROUTINE 500 NEXT Rl J REM GET THE WHOLE NOTE OUT 5 1 P S I T I ON X » R ! ? 4t 6 5 " ! " i G S I J B 8 J X 2 =X i R2-R J R 1 ;::: R ; R E M I... A S T P S I T 1 N F N T E 520 FOR R=R1 TO STEP -It REM MO YE UP THE SCREEN 530 XI ~ I NT(RND<0)*2)JX 1 = X •{• X :l. t R E M U S E NE OF TWO POSITIONS 540 N=INT(RND(0)*5> JN-33+NJREM GET A N GTE DISPLAY 550 POSITION X1»RI? #6»CHR$ (N) J REM PR I NT THE NOTE 560 P S I T I ON X 2 * R 2 t ? # 6 ? " " t X 2 ™ X 1 ! R 2 = R J GOSUB 800 t REM ERASE THE LAST NOTE & R EMEMBER THIS ONE 570 NEXT RtREM ALL THE WAY UP THE SCRE EN 5 8 P S I T 1 N X 1 1 J ? # 6 ? " ! " ; R E M R I G H ' I ' I ' HE NOTE 590 l : - R R ■■: T 6 i P S I T I ON X 1 t i ? # 6 % C I i 50 R $ ( 3 8 + R > J G G S U B & ! R E M M A K E T H E N G T E D ISA P PEAR 600 NEXT R 610 POSITION XiUOS? #6?" "J rem ERASE I T 620 SOUND GsOyOrOJREN TURN GEE THE SOU NL'i 630 GOTO 410 640 END 300 EGR T=l TO 10? NEXT T I RETURN Line 40 dimensions two strings. NTE$ will contain the characters whose ATASCII values represent the tones C-C. Pl$ will contain the machine language subroutine to move the character set from ROM to RAM. Line 50 subtracts 2K from the amount of RAM in the computer. The decimal address of the first location of the character set in RAM is stored in CB. Line 60 pokes the high order address of the memory location of the RAM character set into 204 and the location of the ROM character set in 206. These addresses will be used in the machine language subroutine that moves the character set from ROM into RAM. Line 70 places the machine language subroutine into Pl$. The data is read from line 75 and placed in Pl$. Be sure that the numbers in the data line are correct. Line 80 calls the machine language subroutine. Line 90 reads the data from lines 100-300 and replaces the characters in the character set from the exclamation point to number five. The variable X is first set to 8. The first 8 locations in the character set (0-7) contain the data for the space. If the information is changed, the screen will not be clear. By adding the value of Xto CB, we will change the next 21 characters after the space. Line 340 begins the program. The graphics mode is set to 17— large color print with no text window. Line 350 pokes 756 with the value of A. The variable A contains the high order address of the RAM based character set. By poking this location, you can change the character set. Lines 360-390 draw the pipes on the screen. To place the air hole in the correct position in each pipe, R2 is set to 9. When the difference between the pipe's row and its column is equal to R2, the air hole will be drawn instead of the solid pipe. After the air hole is drawn, R2 is decreased by 1. Each air hole will therefore be slightly lower than the previous one. Line 400 places one character for each note into NTE$. Be sure that this line is entered correctly, or you will hear some strange tones. It is— yl control period left bracket QH@< Line 410 opens the keyboard with the read command. Line 420 clears location 764. By setting it to 255, you guarantee that the next key pressed will be the tone that you want. If you didn't clear it, the last key pressed would be stored in that location. It could be a key that you pressed by accident. Now the program will wait until a key is pressed. The ATASCII value of the key will be stored in the variable C. If the value of C is greater than 127, it means that the inverse key was accidentally pressed. The program subtracts 128 from the value of C to get the correct value of the key pressed. By poking location 694 with a 0, the inverse flag is reset. The next key pressed will have a value less than 128. 51 Line 430 checks the value of C to make sure that it is a number between 1 and 8. If it is not, the program goes back to line 420 to wait for another key value. Line 440 closes the keyboard. Line 450 calculates the key that was pressed. Since the ATASCII value of 1 is 49, we can set the correct value of the number keys by subtracting 48 from C. Line 460 calculates the column of the pipe that the note will appear above. The pipes are all 2 columns apart. The value of C is multiplied by 2. R is the row that the note will be printed in. Line 470 turns on the sound. We use the ASCII of the character located in position C of NTE$. Remember, C is the key pressed. If a 2 was pressed, the tone would be the ASCII value of a lowercase 1. This value corresponds to the tone of D. Lines 480-500 print the note above the correct pipe. Each time the note is printed, it is the next note in the sequence of characters that make up the notes. First the tip of the note shows, then a little of the stem, etc., until the entire note appears on the screen. The characters used for the notes come one after another in the character set. By adding the value of Rl to 44 (the character just before the first note), we can print the entire sequence of notes easily. Line 510 prints the entire note above the correct pipe. The position of this note is stored in the variables X2, R2, and Rl. These locations will be used in the next routine. Lines 520-570 give the illusion that the note is floating to the top of the screen. Each note is printed either in the same column as the pipe, or one column to the right of the pipe. Line 530 chooses either a or a 1. Add this value to the value of the pipe column (X) in order to calculate the column for the next image of the note. Line 540 chooses one of the five variations that the note can have. The value of N is added to 33 to arrive at the note that will be printed. Line 550 prints the chosen note in the correct column and row. The last note is erased, and the values of the new note are stored in X2 and R2. Line 580 prints the note one last time before it begins to disappear off the top of the screen. Lines 590-600 erase the note slowly from the screen. This time the characters that make the note disappear one row at a time will be used. These characters are also placed sequentially in the character set. By adding the value of R to 38, each character for the note will be printed. Line 610 erases the last row of the note. Line 620 turns off the sound. Line 630 sends the program back to 410 to open the keyboard and wait for another key to be pressed. Line 800 is the timing routine. The program uses it everytime a note is printed on the screen. Without it, the characters would be printed too fast on the screen. In the next two programs, the character set for an airplane is redesigned. The plane will travel from right to left across the screen. Listing 4-2 uses graphics mode 2 without the text window. Listing 4-3 uses the text mode. In both programs, the plane shows some hesitation. The movement is not as smooth as in the previous program. This is because more than one character is moving on the screen at the same time. In the previous program, only one character was moving at any particular time. BASIC was fast enough to erase one character and replace it with a new one. In these programs, the five characters that create the plane are moving at the same time. There are three characters that must be erased while the plane is being drawn in the new position. BASIC is too slow to erase and draw this many characters at one time. 52 Listing 4-2. Simple Animation— Second Method 10 REM LISTING 4.2 20 REM SIMPLE ANIMATION 30 REM BY L.M. SCHREIBER FOR TAB BOOKS 40 DIM PLN$<4) »PN1$(3) yPN2$<3) yPl$<20> 5 A == P E E K ( 1 6 ) - 8 t C B ~ A * 2 5 6 I R E M P I... A C E C H A RACIER SET 2K BEEORE END OF MEMORY 60 POKE 204 y A: POKE 206*224 J REM STORE T HE NEW CHARACTER SET ADDRESS AND THE R OM ADDRESS 70 EOR X»l TO 20 i READ BtPl$ *P:I.*<20 ) 5 A ~ P E E K CI. 6 ) ■••• 8 i C B = A * 2 5 6 i R E M P I... A C E C H 55 Listing 4-3. Animation in the Text Mode (continued from page 55) SET ADDRESS AND THE R A RASTER SET 2K BEFORE END OF MEMORY 60 POKE 204»AIP0KE 206 t 224 X REM STORE T HE NEW OH A RASTER OM ADDRESS 70 FOR X=l TO 20 J I B) JNEXT XJREM MACI INE TO MOVE CHARA( 7 DATA :l.04v:l. i 4 3 j- 200 y 208 t 249 r 230 242y96 80 Q~USR 177 y 205 y 145 * 20 y 206 r 230 r 204 y 202 y 208 y 90 FOR X X T X 1.00 DATA 10 DATA ) 5 REM USE MASH INE LAN •I THE USR FUNCTION rO 63? READ C SPOKE CB+XrCJNE 1.20 1.30 40 DATA DATA DATA 50 DATA 60 DATA 70 80 90 00 IT y 8 y 8 f 1 I r y & t 1 1 y » t 1 1 y y y y 30 y 30 y 30 30 y 30 y 30 y 6 y 7 y 25 ">" {POKE 75 56* A y 7 y :l. 1 y 8 y 8 y 7 y 1 1 f 8 y y 7 y 1 1 y » 1 2 y 3 y 3 y 3 » 255 r 255 » 255* 30 » 30 y30y J. 2y()y OyO 4y 255»254v7y6 2yl {REM ERASE SURSOR POKE PLN$-" !%$ 8 FOR X™35 TO :l. 10 LEFT ACROSS 10 IF X/4=INT" {GOTO 20 STEP -1 {REM FROM RIG THE SCREEN 4) THEN PLNiMl y 1 ) = " ! " LONGEST PROP ONCE OU $(34) {IF X/4-INT(X/4) !)*•*■ {REM USE SHORT E OF 4 J? PLN$5 {REM USING A FLICKERING {NEXT T ALL THE WAY ACROSS This program is essentially the same as the previous one. It is, however, done in the text mode. The two lines that are different are 40 and 190. Line 40 dimensions two strings. This time PLN$ is dimensioned to 20 to accommodate the entire plane. Line 190 stores the entire plane in PLN$. This string should read— exclamation point, percent sign, escape up-arrow, escape back-arrow, dollar sign, space, escape down-arrow, escape down-arrow, escape back-arrow, escape back-arrow, and sign, space, escape up-arrow, escape 56 B i B BIB B B B ! B B BIB B B B B B ! b B ! B B b i b B 1 B B B T-l B }■■' B I B B B B 1 B V. - . 1 1 B 1 1 ' 1 I ■ 1 I ■ I I ' 1 ! ■ 1 1 ' 1 I • 1 1 : 1 1 l 1 1 1 1 1 l 1 1 1 1 1 l 1 1 l 1 1 l . I 1 1 1 1 ! 1 i 1 1 1 ! i : i i i : 1 ! 1 1 1 1 I ! 1 : 1 i 1 ! 1 ! 1 1 1 i 1 ! 1 1 1 : :i. I 1 l 1 ! 1 ! 1 1 i : 1 ! 1 ! :i. i 1 ! 1 , 1 I ■i ' ■—. i:r r." ,..-;. ...,i ....: ■— r V.V V" 204 BIBIB B BIB B B BIBIB h 1 h 1 B BIBIB B B ft A. 1 BIB BIB BIB B B b B B b BIBIB BIBIB BIBIB B B B BIB B 1 B B 1 B B B B B B B B IB 1 B 1 B B 1 B 1 BIBIB BIB! B BIBIB 'BIBIB 1 B 1 B 1 B B 1 B 1 B B 1 B BIB B 1 B B B B B B B B B i B B 1 B i B 1 1 B V.".' A. 1 •<, Fig. 4-3. Character set for carousel. 57 1 o .1 1 :l. 1 :l. :l. .1. o Q .i. 1 1 1 o :l. 1 o n :l. 1 ! .1. ! ! :l. :i. -J 111 ! i ! ! 1 10 1 1 ! ! ! Oil! ! ! : I /\ 1 -| l i l l I i .i. () Oil! ! 1 1 ! I o ! 1 :l. 1 1 ! ! ! ! ! 1 :i. ! .1. ! 1 : :i. ! 1. ! :!. ! ! 1 .1. 1 I 1 I :!. ! 1 ! :l. ! :l. ! o i i i < :l. ! ! < 111: Fig. 4-3. continued from page 57. 144 96 80 80 144 80 80 144 .■• o 80 80 Y R R Y R p R Y R R Y R R R R R Y P Y R R R R R R R R R R R Y! Y R ! R R Y R! Y ! R ! R R ! R Y! Y R R R r: Ri R! B! h B ! B R B BiB BIB BIB P 1 P B B Y R R R Y R Y R R R T R R T R V R Y R R R Y 1 P B R B PIP BIB P P P B B P B B back-arrow, apostrophe, space. The new spaces must follow the upper and lower wings and the tail to erase the characters that were previously drawn in those locations. Both programs display some animation. If the for . . . next loops are left in the program, but the position of the plane in line 230 is made constant, you can see the propeller spin on the plane. It is very difficult to see it spin when the plane is moving across the screen. SCENES AND MOVEMENT Up to now, the programs that we created made very limited use of the character sets. The characters were simply created and the animation or movement was there, but there was very little in the way of a scene. 58 i ! B B T T Y 1 B r T Y Y B B B ! B ! B B ! P B B B B B B B B IB B 1 B B B B ' R ! R R R R R R R R R R 1 R Rl R 1 R R R BIB BIB B B BIB B B P. B 1 BIB B B B B ! Scenes need two parts, the background or picture, and the characters that will move. The ATARI uses the term background to indicate the color of the screen. This color will show through any character, letter, or number that has any bits that are not turned on. If you print the letter on the screen in graphics 2, the would appear orange. The center of the would have the background color showing through. Try this in the direct mode: GR. 2:POSITION 2,2:? #6;"0" The background color in all modes except the text mode is stored in decimal location 712. Playfield characters are either the characters that can be printed on the screen in graphics modes 0-2, or the lines that are drawn on the screen with the plot and drawto commands in the other graphics modes. In the last three programs, the playfield characters were notes, pipes, and pieces of an airplane. The playfield characters can be numbers, letters or graphic characters. The next program will draw a carousel on the screen using redefined characters. ANTIC mode 5, which will produce large multicolored characters, will be used in this program. In ANTIC modes 4 and 5, characters are colored by setting one or two bits in every two bit set to indicate the desired color. Both pixels are turned on to that color. The characters appear to be 4x8. In contrast, in the text mode or in graphics modes 1 and 2, each bit that was set in the character turned on the corresponding pixel. An 8x8 grid contained one character. In Fig. 4-3, the characters that replace the ROM characters are drawn. Instead of an X in the location of a pixel that is turned on, a 1 or a is in that bit position. Next to it is the decimal code that will be used in the program. Next to that is a drawing of how the character will look on the screen. The B pixels will appear blue on the screen, the R will be red and the Y yellow. 59 Listing 4-4. Carousel 10 REM LISTING 4,4 20 REM CAROUSEL 30 REM BY L.M. SCHREIBER FOR TAB BOOKS 40 DIM PI $(20) 50 A~PEEKU06)~8JCB«A*256iREM PLACE CH ARACTER SET 2K BEE ORE END OF MEMORY 60 POKE 204 * A: POKE 206*224 i REM STORE T HE NEW CHARACTER SET ADDRESS AND THE R OM ADDRESS 7 FOR X~.t TO 20 J READ B t PI* ( X * X ) =CHR* ( B ) : N E XT X J R E M MAC l-l I N E I... A N G U A G E S U B R U T INE TO MOVE CHARACTER SET 75 DATA I 04* 1 62. 4 rl 60 * * 1 77*205*145*20 3 * 200 * 208 * 249 * 230 * 206 * 230 * 204 * 202 * 208 * 242*96 8 Q ~ U S R < A D R ( P 1 $ ) ) t R E M U 3 E M A H I N E L A N GO AGE PROGRAM WITH THE USR FUNCTION 90 FOR X=24 TO 95 J READ C J POKE CB+X*CJN EXT X 100 DATA 0*3*15*63*255*255*255*204 110 DATA 255*255*255*255*255*255*255*2 04 1.20 DATA 0*192*240*252*255*255*255*204 130 DATA 9*6*5*5*9*6*5*5 140 D A T A 1 4 4 * 9 6 * 8 * 8 * 1 4 4 * 9 6 * 8 * 8 150 DATA 144*96*80*80*144*96*255*255 160 DATA 9*6*5*5*9*6*255*255 180 DATA 2*2*2*2*15*63*255*255 190 DATA 21*84*21*0*192*240*252*252 200 GRAPHICS 17 2 1 D I... I S T ■ P E E K < 5 6 ) -t- P E E K ( 5 6 1 ) * 2 5 6 i R E M FIND THE BEGINNING OE THE DISPLAY LIST 220 POKE DLIST-f3?69 230 EOR X^6 TO 28 J POKE DL ISTiX * 5 i NEXT XJREM CHANGE ENTIRE DISPLAY LIST TO AN TIC 5 240 POKE 756* A 250 P S I T 1 N 1 7 * 2 i ? # 6 * " * * " i R E M F I... A G N TOP 260 P S I T I ON 7*4? ? # 6 1 " # % $ $ % $ $ $ $ $ $ $ $ $ $ $$$$$$%" 270 EOR X^6 TO 18 STEP 2 % POSITION 7*X: ? #6 5 " % % ' '■ % NEXT XJRE M PRINT THE POLES 60 2 8 P S I T I ON 7 » X J ? # 6 J " > N > ) >NNNNN > ) > N N NNNN>(>NNNNN>ON>" 290 G T 290 Lines 40-190 are the same as in the last program. In this program only one string is dimensioned. Otherwise, the machine language subroutine to move the character set from ROM to RAM is the same. The data lines replace the characters from the pound sign to the plus sign. These characters will draw the carousel on the screen. Line 210 calculates the beginning of the display list. As mentioned before, this program will use ANTIC 5, which will produce multicolored characters. Line 220 changes the first row on the screen from graphics mode to ANTIC 5. Line 230 changes the rest of the display list from graphics mode to ANTIC 5. Line 240 tells the computer to use the RAM character set. Lines 250-280 print the new characters on the screen. The *+ is the flag on the top. The roof has 20 dollar signs ($) between the pound sign (#) and the percent sign (%). Line 270 draws the poles. There is one space, the and sign (&), five spaces, the and sign (&), six spaces, the apostrophe ('), five spaces, and another apostrophe ('). The last line prints the bottom. It uses the same spacing as the poles, CTRLN, close parentheses {)}, five CTRLNs, close parenthesis {)}, six CTRL Ns, open parenthesis { (}, five more CTRL Ns, one last open parenthesis {(}, and a final CTRL N. Line 290 loops back to itself. To add animation to this scene, we will use the player/ 'missile graphics. Players and missiles are terms used by ATARI for special characters that can be created and stored in memory. They are unlike the character sets because each player is only 8 bits or 1 byte wide. The player is, however, as tall as the display screen— using 255 bytes in the single line resolution or 128 bytes in double line resolution. Each player can be thought of as a band that extends from the top of the screen to the bottom. The character is drawn on this band. It can be moved from side to side, and up or down. Because the players are stored in an area of memory other than the memory used for the screen display, their image seems to be superimposed onto the background and playfield characters. In this program, we will create a horse for the carousel. To make it look realistic, we will use two players side-by-side. The horse can move up and down while it is going around on the carousel. Figure 4-4 shows how the horse is created. Figure 4-5 shows the amount of memory needed for player/missile graphics. There are two different modes for player/missile graphics: single resolution and double resolution. In the single resolution mode, each byte is one row or pixel high on the screen. Each player and missile has 256 bytes of memory set aside for it. The area of memory set aside for the players and missiles must begin on an even 2K boundary. This means that the first byte of the memory must be evenly divisible by 2048. An easy way to find the boundary is to subtract 4 from the end of memory for every IK. Memory location 106 contains the amount of memory available in the computer. In a 40K system, the amount stored in this memory location is 160. Multiply 160 by 256 and you get 40960— the amount of actual RAM available. Each time you subtract 1 from the number, you are 61 lsuei b y er ,-.■: Fig. 4-4. Player graphics for carousel. '.f.3Wer actually subtracting 256 bytes. By subtracting 4, you will subtract IK from the amount of available RAM. Since the operating system uses IK of RAM for the screen display and display list in mode 0, you cannot use the last IK of RAM for the player/missile graphics. If you subtracted 8 from the amount in memory location 106, you would have an even 2K boundary, but you would be using the same memory that the screen and display list were using. When you are using single line resolution for our player/missile graphics, we subtract 16 from the amount of RAM available. 62 i..i n U s e d in :i. s s i 1 e < p .1. 3 •■.:■: e r IK boundary ••■• d o i..i b I e 1 i i"i e res o 1 u t :i. o ri obb i n i"i i i "i si o f p / m <3 r a p h i c s player 2 +640 player 3 !•■ .1. o ::i er* e i "i d a t \-?6B f896 f:lG2< 9 !•■•" 1 b o i..i n c a r ( . , for s :i. n ! Jl OS re so] ut: . o n .!. :i. ri e unused in :i. s s :i. I e a player player 2 a y e r layer 4 b e si :i. ri ri :i. n si o f si r a p h :i. c X I ■"> o i"i i .1. .-.-.. D W Fig. 4-5. Memory map for player/missile graphics. 63 This leaves 2K for the screen and display list and gives us an even 2K boundary to begin our graphics. The second mode for player/missile graphics is the double resolution mode. This mode draws each byte on the screen twice as high, or uses two rows for each byte. Since it draws each byte twice, it uses only 128 bytes for each player or missile. The entire mode uses IK of memory. To set aside memory for player/missile graphics that are double resolution, we need to start on an even IK boundary. We can subtract 8 from the amount of RAM available. This will give us IK for the player/missile graphics and IK for the screen and display list in the text mode. In addition to the two -nodes, the players and missiles can be in any of three sizes. When we set the mode to single or double resolution, we do it for all the players and missiles. Each player and/or missile can be in one of three sizes independent of each other. If the size is not set, the players and missiles will default to normal size. Each bit in the byte will be one pixel wide. Double size makes each bit two pixels wide and quadruple size makes the figure four times as wide as a normal one. Note: These figures refer to the width of the player. The resolution determines the height of the character. By adding a few lines to the previous program, we can add a horse to the carousel. The following program uses double width and double line resolution. Listing 4-5. Carousel— Animated 20 REM CAROUSEL 30 REM BY L»M. SGHEEIBEE FOR TAB BOOKS 40 DIM PI* ( 20 ) v UP* (20). DOWN* < 20 ) 5 A ■-■■■ P E E K ( 1 6 ) •■■• 8 i C B = A % 2 5 6 J R E M P I... A E C H ARACTEE SET 2K BEFORE END OF MEMORY 60 POKE 204 c A J POKE 206-224: REM STORE T HE NEW CHARACTER SET ADDRESS AND THE R OM ADDRESS 70 FOR X=l TO 20 i READ BJP1*(X»X)=CHR$( BKNEXT XtREM MACHINE LANGUAGE SSUBROU' INE TO MOVE CHARACTER SET 75 DATA 104 > ! 62 y 4 y 160*0* 1 77 1 205 y 1 45*20 3 y 200 y 208 y 24? y 230 y 206 y 230 y 204 y 202 » 208 y 242y96 8 Q ~ U S R ( A D R ( P 1 $ ) ) { R E M U S E M A C l-l I N E I... A N GUAGE PROGRAM WITH THE USR FUNCTION 90 FOR X^24 TO 95 1 READ C J POKE CB+X»CJN EXT X 100 DATA * 3 » 15? 63 y 255*255* 255*204 1:1.0 DATA 255*25.5*255*255*255*255*255*2 04 120 DATA 0*192*240*252*255*255*255*204 130 DATA 9*6*5*5*9*6*5*5 140 DATA 144*96** 150 DATA I 44 ? 96 »E 64 30*80* 144 y 96 y 80 y 80 30*80* 144 * 96*255* 255 160 DATA 9 *6*5*5*9 * 6*255*255 180 DATA 2? 2*2*2 j IS* 63*255*255 190 DATA 21*84*21*0*192*240*252*252 200 REM DRAW CAROUSEL 2 1 'i 1 " > C I... E A R :>■ " I D I... I S T : - :: P E E K < 560 ) •■!• P E E K ( 5 6 1 ) * 2 5 6 J R E M F I N D T H E D E G I N N I N G F T l-l E DISPLAY LIST 220 POKE DLIST+3*69 230 EOR X~6 TO 2 8 SPOKE DLIST+X * 5 J NEXT XJREM CHANGE ENTIRE DISPLAY LIST TO AN TIC 5 240 POKE 756. A 250 P S I T 1 N 17* 1 I ? " * + " J R E M F I... A G N T DP 260 P S I T I ON 7 * 2 l ? " # $ $ $ $ $ $ * $ $ $ $ $ $ $ * $ $ 270 EOR X™3 TO 9: POSITION 7 t X J? " X & ' ' " J NEXT X J REM PRINT THE POLES 280 POSITION 7yXS? " >N> ) TNNNNNT ) TNNNNN N>ONNNNN>ON>" 290 REM DRAW THE HORSE USING PLAYER/MI SS.ILE GRAPHICS 300 A 1 = A - 4 J R E M P I... A Y E R / M I S S 1 1... E R A P l-l I C S ARE IK ABOVE THE CHARACTER SET 3 1 P 1 ■ A 1 #256 +5 1 2 J P 2 - P 1 + 1 2 8 I P 3 ~ P 2 + .1. 2 8 S P 4 ~ P 3 + 1 2 8 t R E M F I R S T M E M R Y I... C A T 1 N F . PLAYERS 320 FOR X=f XJREM CLE A 330 FOR X=l 1 TO A * 2 5 6 ■■■• 1 I P K E X * i N E X ' * OUT THE MEMORY 'EAD C SPOKE X '! THE HORSE 1+70 TO PI +79 J yCSNEXT XSREM GET DATA EG 340 F R X = P 2+39 T P 2+651 P K E X * 1 2 8 t H E XT XSFOR X-P2T66 TO P2+78IREAD C X POKE X*CJNEXT XJREM OTHER HALF OF HORSE 350 EOR X=P2+79 TO P2+1 02 SPOKE X* 128 IN EXT XJREM REST OF THE POLE 360 EOR X-P3+58 TO P3+70JREAD C SPOKE X *CJNEXT X 370 FOR X-P4+31 TO P4 +61 J POKE X*128JNE XT X S F R X = P 4+62 T P 4 + 7 1 S R E A D C S P K E X*CJNEXT X 3 8 F R X ~ P 4 + 7 1 T P 4 1 9 4 i P K E X ? 1 2 8 S N E XT XSREM REST OP THE POLE 3 90 POKE 559 v 46 S REM DOUBLE LINE RES 01... U TION EOR P/M GRAPHICS 65 Listing 4-5. Carousel— Animated (continued from page 65) 400 POKE 53277* 3 J POKE 5427? » Al {REM ENA BLE P/M GRAPHICS 4:1.0 POKE 623* 4 {REM SET PLAYEIEED CHAR A CTERS PRIORITY OVER P/M GRAPHICS - EN ABLE FIFTH PLAYER 420 P K E 704.11 8 t P (3 K E 705. 1 1 8 ! P K E 706 » 1 16 t POKE 707*1 16: REM HORSE OF A DIFFE RENT COLOR 430 P OK E 532 5 6 ? 1 J P K E 5 32 5 7 * 1 { P K E 532 5 8 p 1 : P OKE 5 3 2 5 9 y 1 { R E M M A K E H R S E L A R G E R 440 H 1 :::: 1 5 J H 2 ■ 1 2 1 J P K E 5 3 2 4 8 y H 1 J P K E 5 324? yH2 SEEM PUT HORSE ON THE SCREEN 450 DATA 15y31 y 63 y 47 y 42 y 42 y 10 y 18 y 36 y 8 460 DATA :l.32yl42y 15?y l?:l.y251 »24()y224y2 40 y 168 y 168 y 200 y 144 y 160 470 DATA 32* 1 12 y 248 y 252* 223* 15* 7* 31* 20 ? 20yl8y?y4 480 DATA 252y254y255y253yl4?y 14?yl48y 1 4 6 y 1 3 7 y 4 500 FOR X=l TO 13 J READ B { UP* ( X » X ) =CHR* ( B ) I N E XT Xi R E M MAC H 1 N E I... A NGU AG E S U B R U TINE FOR UP 510 DATA 104y 160y 0y200y 177y 205y 136y 145 y 205*200* 208*247* 96 520 FOR X=l TO 13 t READ BtBOWN$(X*X)~CH R*(B)tNEXT XJREM MACHINE LANGUAGE SUBR OUTINE FOR DOWN 530 DATA 104*160*255*136*177*205*200*1 45 y 205 y 136 y 208 y 247 y 96 540 P 1 = I N T ( P 1/256): P 2 ~ ( P 1 ■■■■ I NT < P 1 / 256 ) * 2 5 6 ) J P 3 ■ I N T < P 3/256)? P 4 ■ ( P 3 ■••• I N T ( P 3 / 256 ) #256 ) J REM HI/ 1... A D D E E S S F H R S E S 550 TRAP 660 J RESTORE 640JDIR-2JHP1=532 48JHP2*-53249SP0KE 20A-P01 SPOKE 205?P02 {REM MOVE TO THE RIGHT •■•• PLAYERS USED 560 F R X = 1 T ? i M = U S R ( A D R ( U P $ ) ) ! G S U B 670 { NEXT XtGOSUB 600 570 P K E 206 y P 1 ! P K E 205* P 2 ! I F D I R :::: - 2 THEN POKE 206 *P 03 {POKE 205*P04 5 8 F R X = 1 T ? t M ~ U S R ( A D R ( D W N $ ) ) { G S UB 670 {NEXT XtGOSUB 600; GOTO 560 590 REM HORSE MOVING ROUTINE ••■• DIE IS POSITIVE -• HORSE MOOES TO RIGHT •••• DIR 66 IS NEGATIVE HORSE MOVES LEFT 600 H1=H1+DIRJH2=H2+DIR 61.0 IE (DIR-2 A NH H2>146) OR 1 2 1 » 1 08 » 1 08 ■> 96 k 8 1 ? 96 v 1 2 .1. n 162 s> 1 2 1 ? 1 2 1 9 1 08 p 1 OS 9 96 y 121 ? 162 > 1 2 1 650 DATA 121 » 108» 108 ? 96 y 81 *96 p 121 «72?0 ?108»91 > 96* 121 ?()?() 660 TRAP 660 I RESTORE 640 i REM RESTORE M USIC ON OUT-- OF-- DAT A ERROR 670 IF (X+2)/3-INT<(X+2>/3) THEN READ 5 i S U N D n S > 1 9 1 6 8 I F X / 3 :::: I N T ( X / 3 ) f H E N S U N D ? y ? 690 RETURN Line 300 subtracts IK from the beginning of the character set. The character set begins on an even boundary, so subtracting 4 (or IK) from its beginning yields an even boundary for our players. Line 310 calculates the beginning address for each player. The first player (PI) begins 512 bytes after the beginning address for the player/missile graphics. The next player and each subsequent player begin 128 bytes after the previous player. We have already decided that these players will use double line resolution, so we know how much memory should be set aside for each player. Line 320 clears the memory that will be used for the players. When the computer is turned on, or after a program has been run, there can be garbage in the memory area that we will be using. This line removes any data that may have been left there. Lines 330-380 draw the horse in the player/missile area of memory. Player PI is the back portion of the horse going to the right. Player P2 is the front of the horse and the pole. Player P3 is the front portion of the horse going to the left and player P4 is the back and the pole. The data to draw the horse is read from lines 450-480. Line 390 pokes memory location 559 with 46. This sets the player/missile graphics to double line resolution. Line 400 enables the player/missiles by poking 53277 with a 3 and tells the computer where the player/missiles begin by poking 54279 with the value stored in Al. Now the computer knows where the graphics are stored, and what the resolution of the graphics should be. If location 53277 is not poked with a 3, the player/missile graphics will not be enabled. Using player/missile graphics in a program requires both location 559 to be set and 53277 enabled. Line 410 sets the priority levels of the players and characters on the screen. In this program, the characters that are printed on the screen will have higher priority than the players. This will make the horse appear to go behind the poles of the carousel. Line 420 sets the colors used in the four players. The first two locations are for the first two 67 players. This is the horse as it is going from left to right. The next two locations are for the third and fourth players. This color is a little darker than the first color. The horse will be going from right to left. The darker color will give it the illusion of being further away. Line 430 sets the size of the horses. By poking each of these locations with a 1, we will make each of the four players double the normal size. Line 440 places the horse that is facing the right on the screen. Locations 53248 and 53249 set the first two players on the screen. To remove them from the screen, poke these locations with a 0. Line 500 is the machine language subroutine that moves the horse up. Be sure that the data in line 510 is entered correctly. If it isn't, the horse will not move up correctly. Line 520 is the machine language subroutine that moves the horse down. The instructions for this machine language subroutine are in line 530. Line 540 calculates the beginning address of the first and third player. The machine language subroutines move 256 bytes up or down. The first horse uses the first two players, which add up to 256 bytes. The second horse uses the third and fourth players or the next 256 bytes. This line stores the high and low order address of the players in the variables P01, P02, P03, and P04. Line 550 uses the trap command to test for the end of data. Lines 640-650 contain the melody that the computer will be playing while the horse is going around. This melody will be played over and over. When the computer runs out of data it will come up with an error. The trap will direct the computer to Line 660. This line will reset the trap and restore the data. The DIR variable is the amount that will be added or subtracted from the position of the horse on the screen. When DIR is positive, the horse will move from left to right. When DIR is negative, the horse will move from right to left. HP1 and HP2 are the registers that are poked with the position of the horse on the screen. Memory locations 205 and 206 are poked with the memory location of the first player. Two bytes are needed for this location because the memory address is greater than 255. Line 560 moves the horse up nine rows. The music subroutine is accessed every time the horse moves up one row. After the horse is moved up, the subroutine that moves it to the right or left is accessed. Line 570 reinitializes the memory locations that are used in the machine language sub- routines to the player that is being moved. If DIR is positive, the location of the first player will be stored in locations 205 and 206. If DIR is negative, the positions of the third player will be stored in these locations. Line 580 uses the machine language subroutines to move the horse down. Again, the music subroutine will be accessed each time the horse is moved down one row. The subroutine to move the horse to the right or left will be used after the horse is moved down nine rows. These three lines will be repeated over and over again until the system reset key is pressed. Line 600-620 contain the subroutine that moves the horse to the left or right. The value of DIR is added to the position stored in HI and H2. If DIR is positive, two will be added to this value. If DIR is negative, two will be subtracted from this value. (Adding a negative number is the same as subtracting a positive number.) This line also checks the position of the horse on the screen. If the horse is at the end of the carousel, the value of DIR is reversed, the horse that is on the screen is removed, and the registers that control the position of the other horse are placed in variable HP1 and HP2. The other horse is then placed on the screen and the program returns. Line 660 reinitializes the music routine. The program goes to this line when it runs out of 68 PRIORITY SEQUEN p 1 a y e r CE POKE P <■■ .1. •::> :::: lv.' i .P. player 2 player 3 Lay field Lay fie 'Id :l. Lay field 2 Lay field 3 and pi 1 ayer- 5 D . 1" :; ! i) li I' 1 p 1 a y e r player :!. 1. a y f i e 1 d •.v.- Lay-field 1 Lay field 2 i. a y f i e 1 d 3 a n d p 1 "> b P Layfield Lay fi?» Id 1. !. a y f i e I d 2 Layfield 3 and pi player player :l. .■:"). b a c k a r o u i"i d plaufield play field :l. player player :l. p 1 a y er 2 Player 3 P 1 B ':::■ f 1 S 1 O 2 8 p 1 b y f i e 1 d 3 a n d P 1 i.'i ■},<. i- ■ i '.'ii.in d Fig. 4-6. Player/missile priority order. 69 data. The trap is reset, the pointer for the data is restored to line 640. The program continues with the next line. Line 670 reads a note every third time that this routine is accessed. We can calculate every third time beginning with the first time by adding 2 to the value of X and dividing it by 3. If it is a whole number (a number without a remainder) a new note will be read and played. Line 680 turns the note off every third time that this routine is accessed. This time we simply divide X by 3. If it is a whole number, then the note will be turned off. The program will return to the main program. SETTING THE PRIORITIES In the last program, the horse seems to move behind the poles. The pole that the horse is on moves up behind the roof of the carousel and appears above it. When the player/missile graphics are initialized, we can set priorities for the players, missiles, and the characters. The players can appear to move in front of the characters, behind the characters, or in front of some and behind others. Figure 4-6 illustrates the order of priority and the value that must be poked into decimal location 623. The playfield refers to the playfield characters, the characters that are printed on the screen or drawn on the screen with the plot and drawto commands. Theplayers are the characters formed by the player/missile graphics. Player 5 is the fifth player or the missiles as a group. Note: The missiles can be used as four characters, each two bits wide, or as a fifth character eight bits wide. To enable the fifth player, poke 623 with 16 + the priority code. As shown in Fig. 4-6, the top player or playfield has the highest priority. This character will appear on the screen in front of any other. Player always has the highest priority followed by players 1, 2, and 3. In the next program, which is a simple bird and fish game, we will set the priority code to 8. The players will move behind the playfield characters and 1, but in front of playfield characters 2 and 3. Some of the clouds are drawn using the color in playfield character 0, others use the color in playfield character 2. The water is made up of three different waves. Depending on the playfield color used, the fish will or will not be seen. Listing 4-6. The Birds 10 REM LISTING 4*6 20 REM THE BIRD 30 REM BY L.M. SCHREIBER EGR TAB BOOKS 40 DIM P1*<2Q> *UP$<20) kD0WN*(20) 50 A ~ P E E K < 1 6 ) •- 8 i C B ~ A * 2 5 6 i R E M P I... A G E C H A RASTER SET 2K BEFORE END OF MEMORY 60 POKE 204 y A IP OK E 206 r 224 i REM STORE T HE NEW CHARACTER SET ADDRESS AND THE R DM ADDRESS 70 EGR X=l TO 20 i READ BIPl*(XyX)=CHR$< B ) i N E XT X I R E M MAG H I N E L A N G U A G E S U B R U T INE TO MOVE CHARACTER SET 75 DATA 104 y :l62i>4» 160 vOv 177 y 205 y 145 y 20 70 3 y 200 y 208 » 249 y 230 y 206 y 230 p 204 y 202 y 208 y 242y 96 8 Q ~ U S R ( A D R ( P 1 $ ) > ! R E M U S E M A C H I N E L A N BUA8E PROGRAM WITH THE USR FUNCTION 90 FOR X~24 TO 103 t READ SPOKE CB+XyCJ NEXT X 100 DATA 63yl27y255y255y 127y63y7y0 110 DATA Oy 192 s-240 y 248 y 240 y 240 y 192*0 120 DATA * 60 v 126 » 255 1 255 y 127 y 63*12 130 DATA 48 y 56s 124 y 254 y 255 y 127 y 255 y 78 140 DATA 5y 79 y 127 y 63y 127y 255y 99y 150 DATA 224 y 246 v 255 y 255 y 252 y 222 y 140 y 4 160 DATA 34y68y85y 1 1 9 y 255 y 255 y 255 y 255 170 DATA y 68 y 85» 255 y 255 y255y 255*255 180 DATA 68 y 34 y 170 y 238 y 255 y 255 y 255 y 255 190 DATA 233 y 255 y 253 y 255 y 255 y 255 y 255 y 2 55 200 GRAPHICS 17 SPOKE 756 y A SEEM COLOR T EXT MODE 8 USE NEW CHARACTERS 210 POKE 70S y 14 SPOKE 709 y ISO S POKE 710 y J. 4 J P D K E 7 1 1 t 1 8 { P K E 7 1 2 y 1 5 220 F R X -•• 1 T 1 ! C = I N T ( R N D CD* 1 9 ) S R = I N T ( R N D ( 1 ) * 1 > i P S I T 1 N C y R S C ~ I N T ( E N D ( 1 ) * 6 ) t I F X / 2 ■■■■■■ I N T ( X / 2 ) T H E N C ■■■■■■■■ C + 1 2 8 230 ? # 6 5 C H R $ ( •!■ 3 5 ) y S I F C :::: R C ™ 4 T H E N ? #6yCHP$(Cf36) 240 NEXT X 250 F P X ■■■■■■ T 1 9 } C ■ I N T < R N D ( 1 ) * 3 > t P 8 1 T I ON X y 1 5 S I F X / 3 - 1 N T < X / 3 ) T H E N C ■ C + 1 2 8 260 ? #6yCHR*(9fC) 5 {NEXT X 270 F R X = 1 T 8 S ? # 6 5 " > I... I... i... I... I... I... L I... I... I... L I... I... L LI...LLLL>" 5 SNEXT X 2 8 A 1 « A - 8 t P 1 ■ A 1 * 2 5 6 + 1 2 4 S P 2 ■■■■■ P 1 + 25 6 J P 3 -P2T256SREM FIRST MEMORY LOCATION OF P LAYEPS--2K ABOVE CHARACTER SET 290 EOP X=P1 TO Pl-f 10231 POKE XyOSNEXT XSREM CLEAR OUT THE MEMORY 300 REM SET UP PLAYERS - BIRD & FISH 310 POKE 559 y 62 S REM SINGLE LINE RESOLU TION FOR P/M GRAPHICS 320 POKE 53277 y 3 SPOKE 54279 y A 1 S REM ENA BEE P/M GRAPHICS 330 POKE 623ySSEEM SET PL A YP I ELD CHAR A CTERS PRIORITY OVER P/M GRAPHICS - EN ABLE FIFTH PLAYER 71 Listing 4-6. The Birds (continued from page 71) 340 POKE 704 t 2 I POKE 705 , 200 I POKE 706? 2 00 % REM 00 1... OP BIRD % FISH 360 RESTORE 380 J FOR X=F2-fl52 TO P2+159 !READ SPOKE X? OS NEXT XI REM DRAW FISH SWIMMING 370 FOR X«P 3+152 TO P3 + 159 J READ C X POKE XvOSNEXT XSREM DRAW FISH SWIMMING 380 DATA 0? 48? 12:1. * 255*255* 121 ?4S?0 390 DATA 60? 24? 24? 60? 126? J. 26? 60? 24 4 C ■■■■■■ I N T ( R N D ( 1 ) * 3 ) t R E S T R E 4 1 i S F R X-Pl+60 TO P1+65JREAD SPOKE X? OS NEXT XSREM GET DATA FOR THE BIRD 401 DATA 0?0?66? 1 63?24?0 402 DATA ? 1 29 ? 66 ? 36 ? 24 ? 403 DATA 0?0?0?36?90? 129 460 FOR X~l TO 132 READ B S UP$ ( X ? X ) ~CHR* ( B ) J N E X T X : E E M M A C H I N E I... A N G U A G E S U B R U TINE FOR UP 470 DATA 104? 160?0?200? 177?205? 136? 145 ? 205? 200? 208? 247? 96 480 FOR X~l TO 13 J READ B S DOWN* ( X ? X )-~CH R$(B)SNEXT XSREM MACHINE LANGUAGE SUBR OUTINE FOR UP 490 DATA 104? 160? 255? 136? 177? 205? 200? 1 45? 205? 136? 208? 247? 96 5 P 1 = I N T ( P 1 / 2 5 6 ) J P 2 ~ ( P 1 - 1 N T ( P 1/256 ) *256 ) J P03-INT ( P3/256 ) t P04~ ( P3--INT ( P3/ 256)*256) J REM HI/LO ADDRESS OF PLAYERS 5 1 ~ I N T ( R N D ( 1 ) * 1 ) + 50 1 V 1 ~ 200 5 U - 6 S P K E 206? P 1 J P K E 205? P 2 I G S U B 720 J R E M SET VARIABLES FOR PLAYERS 520 POKE 53278 » { POKE 53249 ? 01 J V1-V1--1 II F 01^20 THEN UK? 00 530 GOSUB 630 540 POKE 53248* VJC=INT*3) JRESTO RE 400+CJFOR X=P1+U TO P1+U+5JREAD CSP OKE X?CSNEXT X 560 IF PEEK (53260)02 AND (01^200 OR U -149) THEN IF U.t/4=I NT ( 01/4 ) THEN FISH - F I S H + 1 ! G S U B 7 2 J G T 520 570 IF PEEK (53260)02 THEN 520 5 8 P K E 5 3 2 4 9 ? S P K E 5 3 2 5 ? J B I R D ■ B I R D+l 72 600 P K E 2 6 » P 3 J P K E 2 5 •> P D 4 1 F R X ■■■■ 1 T :l. ? Q -• U S R ( A D R ( U P $ ) ) i Q ~ U S R < A D R < D W N $ ) ) I N E XT X J R E M B I R D E A T S F I S H 6.1.0 POKE 53250»0JF0R X«Pi+U TO Pl+U+S: POKE XyOJNEXT XJREM ERASE BIRD 620 GO SUB 720 i GOTO 500 630 IF STICK <0) -14 AND U>40 THEN Q-USR ( A D R < U P $ > ) J U :::: U ■- 1 } R E l ' U R N I R E M M E B I R D UP 640 IF STICK CO) =13 AND IK 149 THEN Q=US R ( A D R ( B W N* > ) J U * U + 1 J R E T U R N i R E M MOV E B IRD DOWN 650 IF STICK <0) -7 AND V<190 THEN V=Utl 660 IF STICK C0>~11 AND V>53 THEN V=V~1 670 RETURN 710 REM ROUTINE PUTS SCORE ON SCREEN 720 POS I T I ON 2 r 22 J ? #6 5 " B I RD " { POS I T I ON 1 4 r 22 : ? *6 i " F I SH " J POS I T I ON 3 * 23 t ? #6 5 BIRDS {POSITION 15»23J? #6? FISH* 730 IF FISI-K100 AND BIRIKIOO THEN RETU RN 740 POSITION 2»10J? #6? "GAME OVER* i POS ITION 1»12I? *6i "PRESS START TO PLAY" 750 IF PEEK (53279)06 THEN 740 760 FISH=0!BIRD : = :: t P P t P K E 5324 8 1 J P KE 53249r0JP0KE 53250.0 1 POP SGOTO 200; REM CLEAR VARIABLES Lines 40-190 are the same as the past few programs. In this program they will dimension the strings used for the three machine language subroutines. The machine language subroutine to move the character set from ROM to RAM is the same. The data lines replace the characters from the pound sign to the plus sign. These characters will draw the clouds and the water on the screen. See Fig. 4-7 for these characters. Line 200 sets the mode that will be used: large color characters with no text window. Poking 756 with the value of A changes the character set. Line 210 changes the colors of the characters. There will be two colors used for all the characters: white and green. The background will be changed to light blue. Lines 220-240 place the clouds on the screen. The position for the clouds is chosen randomly. No two screens will look the same. If the first or fifth cloud is chosen, the program will add the second half of the cloud. Half of the clouds on the screen will be drawn with the characters in the normal character set. The other half of the characters will be drawn as if they were printed in inverse video. The color will be the same, white, but the priority will be different. Lines 250-260 print the top of the water on the screen. This time every third will be printed as a inverse video character. 73 v V x X X ! A | v "y" y v y V 1 V 1 i y A v y y y A V A v V A i / .-■ i v i ■...- i \ i ! x" ! x ! ) t i y i y i i s. i A i A ' .■■ A | x y V X ! 1 Y i \ V' X X J ! X x •-./ X i ; - I V V y i i y A y A r .■ :' ! X y X ! j A y x y i < ■* ! v V A X 1 X x 1 i 1 V x X ! ! • ! )' : ' x Y ; V ; ■ V ( i y v A i A i 1 & V A X V ! "' ■' ' V \ i A y X ! X i Fig. 4-7. Character set for birds. 74 * -• y y A y ,., I X x V x x X ! X v x y y A A V j ! X A v v y y V V I 1 Y \- y X y A y A i I V x V y y y x A i j y V I v I ■■ ■■ f V v y * y X i X i I v J '" ■' ! v i i A 1 V y V r ■; e r s t o r t :i. % r v' I I V i ' I V i i V i i ! -j s r v s i" o r b :i r - - d Line 270 colors the bottom of the screen with water. Line 280 calculates the beginning of the player/missile graphics area. In this program we are using the single resolution character set so the player/missile graphics must begin on an even 2K boundary. By subtracting 8 (2K) from the beginning of the character set, we know where to begin the player/missile graphics. The first player begins 1024 bytes from the beginning of the memory set aside. The second and third players are 256 bytes apart. Line 290 clears the area of memory that will be used for player/missile graphics. This memory could contain data from a previous program or garbage. This would show up on the screen in the player/missile area. Line 310 pokes 559 with 62. This tells the computer that we are using single resolution for these players. Line 320 enables the player/missile graphics. If a 3 were not poked into 53277, the player/missile graphics would not be enabled. Poking 54279 with the value of Al tells the computer where the player/missiles begin. Line 330 sets the priorities of the players and characters. The characters that would be 75 printed as normal characters have a higher priority than the player/missile graphics. The player/missiles have a higher priority than the characters that are printed in inverse video. Line 340 sets the color for the players. The bird will be black and the fish are green. Remember, there are two fish images as players, one that is swimming and one that is caught. Lines 360-390 first restore the pointer to line 380. This is the first line of data for the fish. The first time that the program is run, there is no problem having the computer read the correct data for the fish. If the program is played again, without rerunning it, the pointer will be pointing to one of the lines of bird data. After the pointer is set to line 380, the program reads the data into the player/missile graphics area that is set aside for the second and third players. Line 400 chooses a number from to 2. There are three different ways that the bird can be drawn on the screen. The program chooses one, restores the pointer to that line, then reads the data into the area set aside for the first player. Line 460 places the machine language subroutine that will move the player up into UP$. Be sure that the data is entered correctly. Line 480 places the machine language subroutine that moves the players down into DOWN$. Line 500 finds the first memory location of the first player. This location is greater than 255, so it occupies two bytes. The high order address, that is, the whole number of the address, is stored in the variable P01. The low order address, the remainder, is stored in P02. This address is used by the machine language subroutine. Line 510 chooses a random number for the vertical position of the bird. The bird will always be the same distance from the top of the screen, but it can appear in any column on the screen. This number is stored in V. VI is the vertical position of the fish on the screen. The beginning address of the first player is placed in memory locations 205 and 206. The program is then directed to the subroutine in lines 720-730. This places the words BIRD and FISH on the screen along with a score (0) for each. Line 520 clears the hit register. In the ATARI computer, there is one memory location that registers when a player hits a missile, characters, or another player. This register must be cleared before it can be read. By poking location 53249 with the value stored in VI, we place the fish on the screen. One is subtracted from VI. The next time the program executes this line, it will move the fish over one to the left. If the value in VI becomes equal to 20, the fish is nearly off the screen. The value of VI is reset to 200. Line 530 sends the computer to line 630. The computer will check the joystick to see if it has been moved. When the computer returns to this part of the program, the bird may have moved up or down, or the value in variable V may have changed indicating that the bird has moved either to the right or the left. Line 540 moves the bird to the right or left by poking the value of V into register 53248. The computer then chooses a random number to change the wings on the bird. The number is added to 400 and the pointer for the data is restored to this line. The computer reads the new data for the bird and pokes it into the area of memory in the player/missile graphics area that the bird occupies. The variable Pi is the beginning of the first player's area of memory. The variable U is the offset for the first byte of the bird. It increases and decreases as we move the bird up and down on the screen. Line 560 checks the register that will record whether or not the bird (player 1) has hit the fish (player 2). If the bird has not hit the fish (PEEK(53260)< >2) and the fish has been placed back on the right side of the screen, (VI =200) or if the bird is resting on the water (U=149) and the fish has moved four places, the fish will be given a point. This keeps the player from landing the bird on 76 the water and waiting for the fish to come by. The subroutine in line 720 updates the score and the computer continues the program with line 520. Line 570 sends the computer back to line 520 if the bird has not hit the fish. Line 580 removes the swimming fish from the screen. The computer will execute this line if the value in register 53260 is 2. The swimming fish is replaced by the hanging fish. The score for the bird is increased by one. Line 600 pokes the beginning address for the third player, the hanging fish, into memory locations 206 and 205. The machine language subroutines to move the fish up and down are executed ten times. The fish never really moves up and down. This gives the effect of the fish wiggling while the bird tries to eat it. Table 4-1. Machine Language Listing to Move Players Up/Down. Decimal Code 104 PL A 160 I...DY #0 200 :i:ny 177 L.DA (205) t Y 205 136 DEY 145 ST A C 2 5 ) •■> Y 205 200 :i:ny 208 BNE 247 96 RTS 104 PL A 160 LDY #255 255 136 DEY 177 LDA (205) j Y 205 200 I NY 145 B'T A < 205 > i Y 205 136 DEY 208 BNE 2 4 7 96 RTS Assembly Language Listing ? p u 11 the a e e Li in u 1 a t o r a f f t h & s t a c: k ? i... o 3 d t h e i n d e ;•; Y w i t h zer o (Increment the index Y 8 1... □ a d 1 h e a c c u m u 1 a t o r w :i. t h t h e v a 1 u e of the address in location 205-206 offset by Y (Decrement the index Y (Store the value in the accumulator in the memory locations pointed to by 205-206 offset by Y ( I n c r e in e n t Y (If the index Y is not zero? go back 8 bytes (Return to BASIC K o u t :i. n e t o m o v e c h a r a c t e r u p (Pull the accumulator off the stack (Load the index Y with 255 "Decrement index Y s I... o 3 d t h e s c e u iri u 1 ;:; t or w i t h t h e v a 1 i.j e o f t- h e add r e s s i n I o c a t i o n 205-206 offset by Y 5 Inc re merit Y P Store the value in the accumulator in the memory location pointed to by 205-206 offset by Y (Decrement Y (If the index Y is not sera* go back 8 bytes (Return to BASIC ^' o u t i n e t o m o v e c h a r a c t e r d o w n 77 Line 610 erases the bird. The bird will be redrawn in the player area of memory. If we don't erase the bird, we will have two birds in that area when we only want one. Line 620 updates the score and sends the computer to line 500 where the bird is repositioned on the screen and you are given another chance to try to catch a fish. Lines 630-670 check the joystick to see if it has moved. If it has been moved up or down, the computer will use the correct machine language subroutine to move the bird. The variable Ul will be changed to reflect the new position of the bird on the screen. If the joystick has been moved to the left or right, the variable V will change. Line 720 updates the score on the bottom of the screen. Line 730 checks the score to see if either the bird or the fish has over 100 points. If neither does, the computer will return to the same. Line 740-760 ends the game when either the fish or the bird passes 100. The computer checks location 53279 to see if the start key has been pressed . When the value of this location is 6, the start key has been pressed, and the program can continue. The scores are cleared, the players are removed from the stage and the program goes to line 200 to begin the game again. Since this was entered as a subroutine, the return address is popped off the stack. If the return address for a subroutine is not popped off the stack, it will stay there. If more and more addresses are placed on the stack and never removed, the stack could run out of space, causing the program to crash. Table 4-1 contains explanations of the machine language subroutines that are used to move the players up and down. Each machine language subroutine that is to return to BASIC must pull the last byte off the stack. If it doesn't, the subroutine will not return. 78 Chapter 5 Looking at BASIC By now, writing programs in BASIC is almost as natural as writing letters in English. But, did you ever wonder how the computer interprets the commands that you type in? Or how it knows that the line that was just entered contains an error? Just what does the computer do with a program? THE TOKEN COMMANDS Each time that you see a variable in a line or command, BASIC looks it up in its Variable Name Table. Each variable is assigned a number in the order that it was entered. This number is a token that represents the variable name in the line or command. If the variable appears in the table, BASIC assigns its token for the variable. If it doesn't appear in this table, it is added to the table. Up to 128 variables can be used in one BASIC program. The BASIC commands are converted into token commands. A number or token represents every command that BASIC knows. A one number token uses less memory than a four or five character word. As you enter a program line, BASIC converts the line into a string of numbers or tokens. This makes it easy for BASIC to execute the program. The line numbers that you enter are converted into two byte numbers and stored in the area that BASIC sets aside for the program. Why two bytes? BASIC will accept line numbers up to 32767. When this number is converted to hex, it becomes 7FFF, the largest positive sign number possible. Any number in hex 8000 or larger is considered a negative number, BASIC does not allow negative line numbers. By changing the line number that we entered into a two byte number, every line in BASIC will have two bytes set aside for line numbers. This makes it easy for BASIC to manipulate the lines. Once the line number has been converted into a two byte number, a dummy number will be placed into the line. This number will contain the offset, or the number of bytes in this line. Right now, BASIC does not know how many bytes are needed for this line. The next number is how many bytes are in this statement. Since there can be more than one statement on each line, BASIC must keep track of both the line length and the statement length. This number will also be a dummy number until the entire line is checked. Now that BASIC knows that this is a program line, it looks for a command. The entire list of 79 Table 5-1 BASIC'S for Tokens Commands. TOKEN COMMAND REM :i. DATA "5 INPUT 3 COLOR 4 LIST 5 ENTER 6 LET ..., I F 8 FOR Q NI::.X i 10 GOTO :l. i GO TO 12 GOSUB 13 TRAP 14 BYE IS 00 NT 16 COM .1.7 CLOSE 1 8 OLE 19 DEO '•.? (-' D I M 21 END .■•j .-•; NEW ,.j ..» OF' EN •;:> .a LOAD A".'! O SAVE A*.. <.> STATUS possible commands is in ROM. If the first command following the line number is not in this list, an error message will appear on the screen. If the command is found in the table, it will be converted into a code or token value. Depending on the command, BASIC will check the next part of the statement to make sure that it is accurate. For example, the print command must be followed by double quotes, a variable, or a string variable, FOR must be followed by a variable that is equal to a number, the next part of the command, TO, and another number, TRAP must be followed by a line number or a variable, etc. If any element of the statement is missing or otherwise incorrect, BASIC will stop checking the line, reprint it on the screen, with the word ERROR, and highlight the possible problem area. Once BASIC has determined that the statement is correct, it will replace the dummy numbers with the correct figures and wait for the next statement or line to be entered. A complete list of commands and their BASIC tokens are listed in Table 5-1. Each command has its own numerical token. When you enter a BASIC statement into the computer and you do not type the entire word out; for example, GR. 1 instead of GRAPHICS 1 , and you list the program, BASIC will expand the command and print it correctly. When entering a BASIC program, you only 80 27 NOTE POINT '".'■ Q X 1 3 ON POKE 3 4 ■*y in* o ■...' PRINT RAD READ RESTORE *5 o RETURN RUN STOP 39 POP 40 41 ? (PRINT) GET •V -■.:. ■•v •...' A A "V "Y POT GRAPHICS PLOT 43 POSITION 4 A DOS 47 DRAW TO 48 SET COLOR 49 50 5:1. 52 53 LOCATE SOUND LP P.I. NT OS AVE GEO AD 54 LET (impl: ERROR :ed) save keystrokes, not bytes, when you use the abbreviated forms of the commands. The command will use the same amount of memory no matter which way it was entered. The same is true about spaces. On certain other computers, you can save memory by eliminating the spaces in the statements. ATARI BASIC will automatically place spaces between the commands when it lists the program on the screen. FILE STRUCTURES When we store a value in a variable, string, or array, BASIC must be able to reference the variable and to store or retrieve the information. First, it must be able to identify the type of variable. Then, it must have memory set aside for it. Each time we use a new variable in our program, we use eight bytes of memory. A string and an array uses the eight bytes plus the size of the string or the array. The names of the variables are stored in a table. A second table stores the value of the variable or the location in memory that stores the string or array information. Because of the amount of memory that is used by variables, strings, and arrays, we try to reuse variable names whenever possible. 81 However, it is better to use variables than numbers in a program if you will be using the number often. For example, if you will be going to a line for a timing routine from different parts of the program, it saves memory to make the line number for timing routine equal to a variable, and then GOSUB the variable. BASIC TABLES The first table that BASIC uses is called the Variable Name Table. Every variable used in a program is assigned a number from to 127. If you try to use more than 128 variables in a program you will set an error message. Listing 5-1. BASIC Tables— Variable Name Table 10 20 30 2) 9 STRING* ( 10) 5 T A B i... E ■■■■■■■■ P E E K ( 1 3 ) f P E E K < 1 3 1 > # 2566 60 FOR X^ TABLE TO TABLE +20$? CHR$JNEXT Xt? I REM SHOW THE VARIABLES IN THE TABLE 70 VLUE=PEEK v# v# v# 3 6 b< of 4 ] 3 ! 6 1 __ I 1 1 ■a Codec i i i i DiM+i : math i ■■:■• i q i / i Q i I I Decimal ! 2ndMMi:l. 1 1 1 1 1 D I M : 1 1 i%& B :i. n sr a v r 3 w 1 1 ! 65 ! 1 , „ 1 1 __. , ! :l. St string ! 129! 1 1 1 i 1 "f [■ © e ' The second group of numbers is the information for our string, STRINGS. The first byte is 129. This means that this variable is a dimensioned string. The next byte is the variable number. STRINGS is the second variable in the table. The next two bytes contain the offset that is added to the beginning of the string/afray area to find out where the data for the string is stored. The contents of the first byte is added to the contents of the second byte after it is multiplied by 256. In this case, the second byte is zero. So we know that the information stored in STRINGS begins 198 bytes after the beginning of the string/array area. The next two bytes contain the length of STRINGS. We have not stored anything in this string, so its length at this time is zero. The last two bytes in this group tell the computer how many bytes to set aside for this string. We dimensioned STRINGS to 10, so the first of the two bytes is 10, the other is zero. The next group of bytes contain the information for the variable TABLE. This variable was not dimensioned. It was the next variable that was entered into the computer. The first byte for this variable is a zero. This means that it is a numeric variable. Only one number can be stored in this variable. The next byte is the variable number. This is the third variable in this program, so its number is 2. The next six bytes contain the value of TABLE. Since only one number can be stored in a numeric variable at a time, the computer stores this information right in this table. It uses six bytes because it stores the number as a Binary Coded Decimal. This format differs from the format used when the computer stores a number using two bytes. At this point it is not necessary to understand how or why the computer uses this format, just that it does. The last group of bytes contain the information for the variable X. Again, this is a numeric variable as indicated by the zero. It is the fourth variable used in this program so its number is 4. The value stored in X is represented in the next 6 bytes. Table 5-2 is a chart showing the different ways the variables can be represented in the Variable Value Table. The area set aside for the strings and arrays is called the String/ Array area. The address for the beginning of this area is stored in memory locations 140 and 141. Let's add the following lines to our program. Listing 5-1 B. BASIC Tables— String-Array Area 10 REM LISTING 5. IB 20 REM BASIC TABLES 30 REM BY L.M. SCHREIBER FOR TAB BOOKS 40 DIM A<10r2) » STRING* < 10) 5 T A B I... E :; = P E E K ( 1 3 ) i P E E K ( 1 3 1 ) #256 60 FOR X^ TABLE TO TABLE+20J? CHR*(PEEK 84 (X)HJNEXT XJ? J? 5 REM SHOW THE VARIAB I...ES IN THE TABLE 7 V |... I j E ■■■■■ P E E K ( :l. 3 4 ) + ! :: ' E E K'(135)#256JR E MAD DRESS OF THE VARIABLE VALUE TABLE S l :: ' » t F R X ■■■■■■■ V L t J E T V I... U E + 3 1 i R E M S H W INFORMATION FOR FIRST 4 VARIABLES 9 P R I N T P E E K < X ) » I P » P i 1 J I F P :::: 4 R P ~ 8 THEN ? " " tIF P=8 THEN PRINT IP=OJREM PRINT ESO-CTRL •UP ARROW IF 4 OR 8 100 NEXT X 110 STRING*- "HI THERE" 1 2 F R X = V I... U E + 8 T V I... U E 1 1 5 J ? P E E K ( X ) » iNEXT XS? JREM SHOW THE OHANGE IN THE VARIABLE VALUE TABLE 130 STAR E A ~ P E E K c:l. 4 > + P E E K ( 1 4 1 ) #25 6 i R E M FIND THE BEGINNING OF THE STRING/ ARRA Y A R E A 140 ME8SAGE-STAREA+198JREM FIND THE ST RING ISO FOR X= MESS AGE TO MESSAGETLEN ( STRIN (3 $ ) •- 1 5 R E M S T A R T T E N D F S T R I N (3 * 160 ? CHR$(FFEKCX) ) 5 JREM PRINT THE CHA RAOTER OF THE VALUE IN THIS AREA 170 NEXT X ISO ? J? "STRING-" 5 STRING* The fifth group of bytes is nearly identical to the second group. This is the information for STRING$. The only byte that is different is the fifth byte. It contains an eight because the message in STRINGS is eight characters long. The next line prints the contents of STRING$ by peeking at the area in memory where STRINGS is stored. Finally, STRINGS is printed to show that the message is the same. By knowing this information, it is possible to trick the computer into looking at memory that was not originally set aside as a string by the computer. In the next.chapter you will learn how to manipulate this information. Another area of memory that BASIC uses is the Output Buffer. When a BASIC line is entered into the computer, the entry must be stored somewhere while it is being tokenized and checked for the proper structure. The area set aside for this is stored in memory locations 128 and 129. This area or buffer is 256 bytes long. Listing 5-1 C. BASIC Tables— Buffer 10 REM LISTING S.1C 20 REM BASIC TABLES 30 REM BY L.M. SCHREIBER FOR TAB BOOKS 4 D I M A ( 1 y 2 ) y S T R I N G $ ( 1 ) 5 T A B I... E ~ P E E K ( 1 3 ) + P E E K CI. 3 1 ) * 2 5 6 60 FOR X- TABLE TO TABLE +20 J? CHR*(PEEK 85 Listing 5-1 C. BASIC Tables— Buffer (continued from page 85) ( x ) ) i t next x : ? : ? : rem show the var :i: ab LES IN THE TABLE 70 VLUE-PEEK ( 134 ) +PEEK C 135>*256? REM AD DRESS OF THE MAR I ABLE VALUE TABLE 8 P = t F R X ■ V L. U E T V I... U E + 3 1 i R EM SHOW INFORMATION FOR FIRST 4 VARIABLES 90 PRINT PEEK»iP=P+ltIF PM OR P=8 T hi E N ? " ■ J I F P = 8 T H E N P R I NT J P - J R E M PRINT ESC -CTRL-UP ARROW IF 4 OR 8 .1.00 NEXT X 11.0 STRING*** "HI THERE" 120 FOR X=VLUE+8 TO VLUE+15J? PEEK(X)> J NEXT Xt? J REM SHOW THE CHANGE IN THE VARIABLE VALUE TABLE 130 STAREA=PEEK<140)+PEEK<141>*256IREM FIND THE BEGINNING OF THE STRING/A RR A Y AREA 140 MESSAGE=STAREA + 198 5 REM FIND THE ST RING 150 FOR X=MESSAGE TO MESSAGE+LEN ( STRIN G*)-l JREM START TO END OF STRING* 1 60 ? CHR* ( PEEK ( X ) ) J * REM PR INT THE CHA RACTER OF THE VALUE IN THIS AREA 170 NEXT X 180 ? :? "STRING-" 5 STRING* 190 B U F F E R ■ P E E K ( 1 2 8 ) + P E E K CI. 2 9 ) * 2 5 6 t R E M BEGINNING OF THE BUFFER 200 FOR X= BUFFER TO BUFFER +1 50 i? CHR$< P E E K < X ) ) ? J REM P R I N T T H E C N T E N T S F T H E BUFFER 210 NEXT X The contents of this buffer will vary from program to program depending on what has been entered into the computer. Once the lines of the program have been tokenized and placed in the program, BASIC has to know where in memory the program begins. The address of the beginning of the BASIC program is stored in the Statement Table in memory locations 136 and 137. By adding a few more lines to the program you can see the tokenized BASIC program. Listing 5-1 D. BASIC Tables— Statement Table 10 REM LISTING 5, ID 20 REM BASIC TABLES 30 REM BY L.M. SCHREIBER FOR TAB BOOKS 86 40 DIM A< :l.0»2) kS'ir:i:ng$( 10) 5 T A B I... E = P E E K ( :l. 3 ) + P E E K ( :l. 3 1 ) #256 6 FOR X™ TABLE TO TABLE* 20 J? CHR$ ( PEEK ( X ) ) 9 I H E XT X I ? 5 ? ? R E M S H W T H E V A R I A B LE8 IN THE TABLE 70 1... U E = P E E K ( 1 3 4 ) + P E E K ( 1 3 3 ) * 2 5 6 % R E M A D DRESS OF' THE OAR I ABLE VALUE TABLE S P - J F R X :■■■■■ !... L J E I ' 1... U E + 3 1 I R E M S H W INFORMATION FOR FIRST 4 VARIABLES 9 P R I N T P E E K ( X ) ,i P - P + 1 1 1 F P ~ 4 R P = S T H E N ? " " 1 I F P ~ B T H E N P R I N T ! P :::: { R E M 'RINT ESC -CTRL- -UP ARROW IF 4 OR 8 .00 NEXT X .10 STRING*- "HI THERE" . 2 F R X ■■■■■■■ 1... U E + S T 1... U E + 1 5 1 1 P E E K ( X ) * J NEXT X{? J REM SHOW THE CHANGE IN THE VARIABLE VALUE TABLE 1 3 S T A R E A = P E E K ( 1 4 ) + P E E K < 1 4 1 ) #25 6 1 R E M FIND THE BEGINNING OF THE STRING/ARRA Y AREA 1 40 fi E S S A G E = S T A R E A + 1 9 8 { R E M F I N D T H E S T RING i 5 F R X = M E S S A 13 E T M E 88 A G E + 1... E N ( S T R I N G $ ) ■■■• 1 ! R E M S T A R T T E N D F S T R I N G $ 1 6 ? H R * ( P E E K ( X ) ) I I R E M P R I N T T H E C H A RASTER OF THE VALUE IN THIS AREA 170 NEXT X 180 ? {? :ng STRING* 1 9 B U F F E R ~ P E E K < 1 2 8 ) + P E E K ( 1 29 ) #2 5 6 1 R E M BEGINNING OF THE BUFFER 200 FOR X== BUFFER TO BUFFER + 150 J ? CHR*( P E E K ( X ) ) 5 i R E M P R I N T T H E C N T E N T S F T H E BUFFER 210 NEXT X 220 P R G R A M = P E E K < 1 3 6 ) + P E E K" ( 1 3 7 ) #256 J R E i-i THE PROGRAM 230 LuK X--I ■ l-UOKi-iM I'm | ROUI AMf :l 1. 00 % > : CH R $ ( P E E K ( X ) ) i i N E X T X i R E M P R I N T T H E T K E NIZFD PROGRAM The remarks are perfectly readable. The rest of the listing should look like code. It is. Every command is converted to one of the token values (Table 5-1). The variables have their own tokens. It would be very hard for you to try to read this listing. In order for BASIC to keep track of where it is when executing the program, it sets aside two bytes of memory to use as a pointer. Memory locations 138 and 139 contain the address of the current statement. When BASIC is not executing a program, this buffer points to the beginning of 87 the immediate line mode, which is the area that the next command will be placed if it is not a BASIC line, but an immediate command. When BASIC is executing a program, it also needs an area set aside for return statements and for . . . next loops. This is called the Run Time Stack. When BASIC executes a GOSUB, it must know where to return to. Four bytes are used for every GOSUB. One byte indicates that the next address is a return address for a GOSUB. The next two bytes contain the line number to return to. The fourth byte is the offset in the line, so that BASIC will continue with the next statement on that line. A for . . . next loop uses 16 bytes of memory in the stack: the last number that the variable can count to (6 bytes), the step of the for . . . next loop (6 bytes), the variable name of the variable that is counting, the line number (2 bytes), and the offset of the for statement. The first two numbers use the Binary Coded Decimal format. Incorrect use of the for . . . next loop or GOSUBs without RETURNs and/or POPs can cause a program to crash. Table 5-3 is a chart that shows the addresses that BASIC uses to store this information. SPEEDING UP A PROGRAM Now that we have an understanding of how BASIC stores a program and the pointers that it uses to keep track of the program as it runs it, we can use different techniques to speed up a program and to use memory effectively. A well written program should ran smoothly and use only as much memory as necessary. Having a computer with 48K in it does not mean that you should not try to conserve memory. If your short programs are written loosely, and you do not get into the habit of trying to write the program as tightly as possible, you will run out of memory very quickly when you try to write a large program. Sometimes the only way to shorten a program is to recode it. If the program was not flow charted or modifications were added to the program after it was written, you may find that the Table 5-3. Table of Addresses for BASIC Tables. decimal table a d d r & s> -CHR#*256 140 POKE DLIST+3»69tREM ANTIC MODE 5 150 FOR Q=7 TO 28 i POKE DLIST+G*5JNEXT Q i POKE DLISTi6y6n : " l P S I T 1 N 20 * 8 } ? " # # # # $ X 8 8888888888888888 8 8 8 %.%%% 8 8 8 8 » - # # ** " 180 FOR Q-9 TO 12 t POSITION 20*0 J? "222 ':> 2 '•> '"> '•* '•' '- 1 *? "* ' :> n 2 " :> ' :> ' :> ' :> :> 2 2 2 7 7 2 2 ' :> 2 7 7 ' :> 7 7 7 7 2 7 7 7 " :next o 190 U)*~" 8888888&8&&8888&888&88' ( )*+8* 5 REM FARMER UPRIGHT 200 U 1 $~ " &88&&&8&88888888 8 8 8 8 8 ' * 1 #+ 8 8 " ! R E M I... E A N I N G F R W A R D 2 1 P S I T 1 N v 1 J ? " T A K E d U C K f X w H E A 92 T" :rem show options 220 C * :::: " 534"; F - :!. I F 1 ~ J W ■■■■ 1 i W 1 ~ J D = 1 I D :l. » : P S I T ION 2 6 « 3 i ? W * I R E. M P R I N T l : " A R hi ER-SET VARIABLES 230 P S I T 1 N 2 1 » 7 I ? C * < 1 f 3 > ! i :: ' S I T 1 N :l. 6.8: ? C $ ( 4 •> 6 ) t P E N # 1 » 4 » i> " K J " J R E M P R I NT POSITIONS OF DUCK-W HEAT-FOX 240 E T # 1 f B 5 I F B > 1 2 7 T H E N B - B ■••• 1 2 8 ! P K E 694fOJREM RESTORE FROM INVERSE 250 IF D ANB (B--68 OR B~100) THEN C$<6 v6)^" " {U$<26»2A)~ B 0" JC*(3f3>~"4" JB1-1 }D=OJGOTO 290 1 REM DUCK 260 IF F ANB (B«70 OR B-102) THEN C$(4 , 4 ) ■■■■■■■■ " " J Ul $ ( 2 6 y 2 6 ) ■■■■■■■■ ',»: F :::: J F :!. :::: I J C * ( :l. t 1 > a" 5 "J GOTO 290; REM FOX 270 IF W ANB (B~87 OR B~ 11?) THEN G$<5 , 5 ) = " ' J W* (.26 f 26 ) ;::: " / " 5 W~G 5 W 1 :;:: 1 t C* < 2 f 2 ) -"3" J GOTO 290 275 IF B«32 THEN 290 280 GOTO 240 290 p o s I T :i: N 1 6 » 8 J ? $ ( 4 v 6 ) I C I... S E # 1 i W 1 $ < 25 f 25 ) ~ W * ( 2 6 » 2 6 ) I R E M P U T I N T H E R S TEING 3 F R Q * 1 T :l. 1 ! P S I T I ON 2 6 , 8 I ? W :l. $ ! REM MOVE THE BOAT 3:1.0 TEMP$=W$ ( 1 v 2 ) J W$=W$ ( 3 » 23 ) J W* < 27 » 28 >=TEMP$JREM MOVE THE BOAT TO THE LEFT 320 POSITION 26*8 1? W* 330 T E M P $ ■■:■■■■ W I $ ( 1 f 2 ) J W I * » W I * ( 3 ? 28 ) t W I $ ( 2 7f28)=TEMP* 340 NEXT BtIF Fl ANB Dl ANB U)I THEN PO SIT I ON Of! J? " YOU GOT IT !! "J GO TO 540 350 IF F ANB D THEN POSITION OfIJ? " FOX EATS BUCK! ! " ! GOTO 540 360 IE B AND W THEN POSITION Of II? " DUCK EATS WHEAT "J 60 TO 540 370 W* ( 4 » 4 ) ~ " * " J Wl$ < 3 f 3 ) :::: "*" I POS I T I ON 26*8;? U${ POSITION 2:1. v 7 ; ? C$ CI. v 3 ) J OPEN #1f4f0» "KJ " 380 GET #1fBJIF B>127 THEN B=B-128JPQK E 694fOJREM RESTORE FROM INVERSE 390 IF Dl AND (B«68 OR B«100) THEN C$< 3-3)==" " J U$ ( 4 f 4 ) ■■■■■■■■ "0 ■ t C* (6 f 6) ■ "4 " J B 1 ~0 t 93 Listing 6-1. The Farmer and the Duck, Fox, and Grain Puzzle (continued from page 93) D= It GOTO 430 i REM DUCK 400 IF Fl AND (B~70 OR B~i02) THEN C$( 1 » 1 ) " » » i C$ ( A y 4 ) ~ " 5 " i m ( 4 v 4 ) ™ '."l F 1 ~0 S F=l JGOTO 430 t REM IT'S THE FOX 4:1.0 IF Wl AND = " / " ? W 1 ~0 * W=l JGOTO 430 4:1.5 IF B^32 THEN 430 420 GOTO 380 430 P S I T 1 N 2lv?l ? $ < 1 > 3 ) ! 1... S E # 1 t W 1 * ( 3 •/ 3 ) = W * < 4 :' 4 ) tR E. M P U T I N T H E R S T ' R I N G 440 F [) R Q :::: 1 T 1 1 I P S I T I ON 2 6 , 3 ! ? \4 $ I R EM MOVE THE BOAT 450 TEMP* < 1 12) ~W1 $ ( 27 y 28 ) J TEMP* ( 3 t 28 ) = W :l. $ ( 1 1 26 ) J W :l. $ ■■■■■■■ T E M P $ I R E M MOV E B Q A T T R IGHT 460 POSITION 26*8?? Ul$ 4 70 T E M P $ ( :l. ? 2 ) ■■■■■■■■ Ul $ ( 2 7 y 2 8 ) ; T E M P $ < 3 > 2 8 ) ~ W *<1»26) ?W$»TEMP$ 480 NEXT Q 490 IF Fl AND Dl THEN POSITION Or It? " FOX EATS DUCK! ! " JGOTO 540 500 IE Dl AND Wl THEN POSITION 0*1 t? " DUCK EATS WHEAT " {GOTO 540 510 POSITION 16981? C$(4*6 ) t W* (26 t 26)- "*" JW1$<25»25)~"*" {POSITION 26p8?? W$ 530 GOTO 230 540 F R :::: 1 T 1 00 % N E X T Q I G T 1 7 Line 40 dimensions four strings. The W$s will be the boat in the water. C$ is the machine language subroutine to move the character set from ROM to RAM. TEMP$ contains temporary information for the strings. Line 50 finds the top of memory available on your system and subtracts 2K from it. This is where the RAM character set will begin. This location is poked into memory location 204. The beginning of the ROM character set is poked into location 206. These two memory locations will be in the machine language subroutine. Line 60 is the machine language subroutine that moves the character set from ROM to RAM. Be sure that the data in line 70 is entered correctly. It must be typed in exactly or it won't work. Line 90 uses the machine language subroutine to move the character set from ROM to RAM. Line 100 reads new characters into the character set. We will be replacing the characters from the pound sign (#) to number 5. See Fig. 6-1 for the new characters. To get the decimal location of the first byte in the RAM character set, we multiply the value of A by 256. Since we want to begin the new characters with the fourth character, we multiply 8 (bytes per character) by 94 3 (characters to skip). We will begin replacing the characters with byte 24. Lines 110-128 contain the data used to change the characters. Each line is a different character. Line 130 finds the beginning of the display list. We will be changing the display list to work in ANTIC 5. Line 140 changes the fourth byte of the display list to 69. This is the instruction that tells the computer that the next two bytes indicate where the screen memory begins, and the mode of the first line on the screen. Line 150 changes the rest of the lines in the display list to ANTIC mode 5. The seventh line of the display list is changed to ANTIC 6 (graphics mode 1). This line will contain text. Line 160 changes the colors that will be used in the program. Location 82 is poked with a zero to change the left margin on the screen. All the lines on the screen are 40 characters wide except the second line. This line is 20 characters wide. This places the margin in the center of the screen. If we don't change the left margin to zero, the computer will skip the screen area that would normally be the left margin. Because it is now in the middle of the screen, there would be a strange empty line down the middle of the screen. Line 170 pokes location 756 with the new character set location. The screen is cleared and the shore lines and water are printed on the screen. Notice that the shore begins on the left side of the screen and extends to the right margin, but the program tells the computer to begin the print with position 20. All the lines after the second one are 20 characters off. Line 180 fills the bottom of the screen with blue. Lines 190-200 place the waves and the farmer in the boat into the two strings. In W$, the farmer will be upright; in Wl$, the farmer will appear to be leaning forward. Line 210 prints the options on the screen. The D in duck, the F in fox and the W in wheat are different colors; these are the keys that will be pressed to place that object into the boat and row it across. Line 220 places three spaces and the numbers 534 into C$. C$ will not be used any more in the program, so rather than use a different variable, we are reusing C$. The 5, 3, and 4 are the new characters for the fox, the wheat, and the duck. The next six variables will indicate where the fox, the duck, and the wheat are. F, W, and D will be set to 1 when the fox, the wheat, and the duck are on the right side of the screen. The Fl, Wl, and Dl will be set to one when the fox, the wheat, and the duck are on the left side of the screen. The farmer in the boat is printed on the screen. Line 230 prints the items on both sides of the screen. When the program begins, the first three elements of C$ will be empty. The fourth through sixth will contain the fox, the wheat, and the duck. The keyboard is opened for input. Line 240 gets a value from the keyboard. This value will be an AT ASCII value for the key pressed. If the value of B is greater than 127, the inverse key has been accidentally pressed. By subtracting 128 from this value, it will be restored to the correct value. By poking location 694 with a zero, the flag is reset for normal characters. Lines 250-270 check the key that has been entered for one of the three characters. If the variable for that character is a one, the first part of the if . . . then statement is true. We do not have to enter IF D = 1, IF D serves the same purpose. If the D is one, the computer will go on the second part of the statement and check to see if the D or d key has been pressed. If it has, the duck is placed into the boat. The redefined character for is the duck. When the boat is on the right side of the screen, that part of the boat is the 26th position in the string. The third character in C$ will be the duck. This element is replaced with the 4, the duck on the ground. The variable for the left side 95 ■/ j v ! v [ v j v ! v ' v ! v I v I '• : i x A A 1 i ■' ! Y | V i / I V j V I ' >' ' J 3C y i | y ; | i X i 3 " ! y y y X V '•■/ i X 1 I V I * r i A v X i A y A X i X y x y X ! X ! X A X X X i X I ! X X x A A X /\ i A i 1 Y x A A i i ' V A v v .•■\ V ' •..,/ v y y X y ' i A A A A .-'S 1 w y V y y y V 1 i y\ A A •■ % ' A A i ' y v V y Fig. 6-1 . Character set for farmer, duck, fox and grain. * 96 x X ! • x /\ A i ■■ .-■ i v 1 /■-. A A i .• '•- 1 A i v v y y y A x i ; i 1 X A X V i A A -■ ■• A i ! x V X V " A i w V 1 ! /\ A A l I V V X ! X A A V ( ! X V X A .■■'\ X ! i A i / • i v x V V y X ! i v i ■• i A i .- < ! X A x Y x A i i A t ! X X x ! X X V j ' V I A X X ! i V x X ! i V V I l A A V y A X V A y V A v A X X X y A Y A X A X y y A V y /■-. y y x A A y V 1 ' X X A X V x X ! [ V V A '•■/ x y j i A V A A X ! IX I V i A i i y ! i A i 97 of the screen is changed to a 1 and the variable for the right side of the screen is set to zero. The program goes on to line 290. The other two lines are the same. They use the redefined characters for the fox and wheat. Line 275 checks for the space bar. If the space bar is pressed, the program will go on to the next part of the routine and row the boat across the screen. Only press the space bar when you want the farmer to row the boat with nothing in it. Line 280 sends the computer back to line 240. The key that has been pressed is not one of the four correct keys, or the character that you are trying to take across the river is already on the other side. Line 290 reprints the fourth through sixth characters of C$ on the screen. The character that is in the boat will be removed from the shore. The keyboard is closed and the character that is in the boat in W$ is placed in Wl$. The boat is one character to the left in Wl$. Lines 300-340 form a for. . .next loop to move the boat from the right to the left. Wl$ is printed on the screen. This is the string with the farmer leaning forward in his boat. The oar is in a slightly different position also. The first two characters of W$ is stored in TEMP$. These two characters will end up at the end of W$. The rest of W$, from the third position to the end is placed in W$. This, in effect, moves the characters up two places. The characters stored in TEMP$ is placed in the last two places of W$. W$ is printed on the screen. The same procedure is repeated with Wl, except it is not printed on the screen. Wl$ is printed when the routine is repeated. When the loop 98 ends, W$ will be on the screen. The computer will check the values of Fl, Dl, and Wl. If they are all 1, all three characters are on the left and the game is over. The winning message is printed on the screen. Line 350 checks the variables F and D. If both of these are a 1, then the fox and duck are together. Since they cannot be together, the message FOX EATS DUCK appears on the screen. Line 360 checks the values of D and W. If both of these are a 1, the duck and the wheat are together. The message DUCK EATS WHEAT appears on the screen. Line 370 restores the boat to normal in both strings, prints the empty boat on the screen, and prints the first three characters of C$ on the shore. The character that has been brought over on the boat will now appear on the land. Line 380 gets a new key from the keyboard. Again, the value is checked to see if the inverse key has been set. If it has, 128 will be subtracted and the flag reset. Lines 390-410 check the key that has been pressed against the values in the variables. If the correct key has been pressed, but the corresponding variable is a zero, then that character is on the other side of the river and the boat must be rowed back before the character can be placed in it. Line 415 checks for the space bar. If it has been pressed, the program will go on the routine that moves the boat back across the water. Line 420 sends the computer back to line 380 for a new input. The key pressed was not an F, D, or W or the space bar. Line 430 prints C$ on the shore. The character placed in the boat will be removed. The character is placed into Wl$. Again, because Wl$ is offset by one character, the character that was placed in the boat is placed one position to the left in Wl. Lines 440-480 move the boat back across the screen. The lines are similar to the ones that moved the boat across the screen the first time. This time the last two characters are placed in the first two positions of TEMP$. The first through 26th characters of Wl$ are placed in the 3rd through 28th elements of TEMP$. Then the contents of TEMP$ are placed in Wl$. The same procedure is used to move the boat in VV$. Lines 490-500 check to see if the fox is left with the duck, or the duck is left with the wheat. Line 510 prints the fourth through sixth characters of C$ onto the shore. The new character will appear here now. The boat will be restored, and the empty boat will be printed on the screen. The program continues until the characters are all on the left side of the screen. Line 540 is a timing subroutine. It is used to give you a chance to read the message on the screen. To restore the screen, press the system reset key. MACHINE LANGUAGE SUBROUTINES Until now, you have placed machine language subroutines into a string by setting a position of the string equal to the character string of a number. Every program that moves the character set to RAM, or moves a player/missile up or down used the same machine language subroutine. The following two programs place a machine language subroutine in a string. The program then prints the string on the screen with a line number in front of it. By moving the cursor over the line and pressing return, we place the new line with the subroutine into the program. This line can then be stored on disk for future use. When you want this subroutine in a program, you do not have to use a for . . . next loop with the data lines. The line with the characters already in the string can be used. 99 Listing 6-2. Move Character Set 10 REM LISTING 6,2 20 Ft EM MOVE CHARACTER SET 30 REM BY L*M*SCHREIBER FOR TAB BOOKS 4 DIM C$<20) 50 EOR X~l TO 20 t READ BJC*(X»X)~CHR*■ " y 5 y " C $ - " ', C H R$ ( 3 4 ) » C 5 C H R % ( 34 ) * ? 60?? 7 Line 40 sets aside 20 bytes for the machine language subroutine. Line 50 reads the data into the string. When it finishes, each byte of the string will be an instruction of the subroutine. Line 70 clears the screen. The number 50 and the string will be printed on the screen. The numbers 60 and 70 will also be printed on the screen. Now move the cursor to the top of the screen and press the return key three times. Line 50 will be replaced with the string that contains the subroutine. Lines 60 and 70 will be erased. To use this subroutine, subtract 2K from the amount of memory available in your system (A=PEEK(106)-8). Store the value of A in location 204 (POKE 204.A). Store the beginning address of the ROM character set in location 206 (POKE 206,224). To execute the subroutine use the USR command— Q = USR(ADR(C$)). This subroutine will move the ROM character set into RAM. Listing 6-3. Move Player/Missile Up/Down 10 REM LISTING 6,3 20 REM MOVE PLAYER/MISSILE UP/ DOWN 30 REM BY L.M.SCHREIBER FOR TAB BOOKS 40 DIM UP*< 13) yD0WN$( 13) 50 FOR X---1 TO 13? READ B J UP* ( Xt X ) ~CHR*< B) JNEXT X 60 DATA 104y 160y0y200v 177.205 y 136 y 145y 205 y 200 y 208 y 247 y 96 70 EOR X™1 TO 13; READ B i DOWN* ( X r X ) ~CHR *(B) JNEXT X 80 DATA 104y 160y255y 136y 177y205y200y 14 5.205y 136 v 208 , 247 » 96 9 ? " :>■ C I... E A R > " y 5 ? " U P * :::: " y C H R * ( 3 4 ) ? t F R X = 1 T 1 3 i ? C l-l R * ( A S C ( U P * ( X » X ) ) ) ? i N E X T XJ? CHR*(34) 1 ? 60 5" D W N $ ■■■■■■ " y' C 1-1 R * ( 3 4 ) i I F R X « 1 T 1 3 X I F A S C ( D U) N * ( X P X ) ) > 252 T H E N ? C H R *(27) i 100 :l. 1 ? CHR$ ( ASC ( DOUN$ ( X s> X ) ) > y % NEXT X J ? C H R $(34) t ? 7 I ? 8 I ? 9 t ? 1 J ? :l. :i. Line 40 sets aside 13 bytes each for the two machine language subroutines. Line 50 reads the data from line 60 into UP$. UP$ will contain the machine language subroutine to move the players up. Line 70 reads the data from line 80 into DOWN$. This is the machine language subroutine to move the players down. Line 90 clears the screen and prints the two strings on the screen with line numbers before them. The numbers 70, 80, 90, 100, and 110 also appear on the screen. Move the cursor to the top of the screen and press the return key 7 times. Lines 50 and 60 will be replaced with the new lines that contain the machine language subroutines. Lines 70, 80, 90, 100, and 110 will be erased from the program. To use these subroutines, store the high order address of the player to be moved in location 206 and the low order in location 205. Executing either subroutine with the USR command will move the player up or down. When storing a machine language subroutine in a string, make sure that the subroutine contains relative branches. That is jumps that depend on a byte count instead of a firm address. The string can be placed anywhere in memory. The location of the string will vary from program to program. If the machine language subroutine contained a set jump, for example, jump to address 2048, the program would always jump to that address. If the correct instruction was there, the routine would work properly. If it wasn't, the program would crash. By using a relative jump, for example, Branch Not Equal, the program will be directed to a location by bytes (forward 8 bytes, backwards 3 bytes, etc.). This routine could be located anywhere since the same instruction will always appear 8 bytes after or 3 bytes before the current instruction. RELOCATING THE STRINGS In the last chapter, tables for the variables, their names, and the string/array area were listed. Knowing where the computer looks to find out where a string is located enables us to be able to relocate strings to areas that are more suitable for our program needs. The two tables that we will be using in the next program are the variable value table and the string/array area. By changing the offset values in the variable value table, we can make the computer "think" that the string is located elsewhere in memory. By changing the values in the fifth and sixth locations in the variable value table, we can change the length of the string. In effect, we can make the screen one string, and manipulate it as such. We could even store a program in a string if we had reason to. One example of relocating the strings is in the next program. STRINGS AND PLAYER/MISSILE GRAPHICS The player/missile graphics have provisions for moving the player/missiles to the right or left with a simple poke command. But, in order to move the players up or down, we have to rely on machine language subroutines. If the player was extremely long (tall), the movement could look a little jumpy. In the next program, which simulates a slot machine, we will move the players up by manipulating a string. 101 Listing 6-4. Player/Missile Strings 10 REM LISTING 6,4 20 REM PLAYER/MISSILE STRINGS 30 REM BY L.M.SCHREIBER EOR TAB BOOKS 4 D I M P L :l. * ( 1 ) v P I... 2 $ ( :l. ) t P I... 3$ ( 1 ) t T E M P $ ( :l. ) yJOKPT$(S> 5 G R A P H I C S 4 i D I... I S T ™ P E E K ( 5 6 ) 1 P E E K ( 5 6 1 )*256}REM GET THE B I SPLAY LIST 60 POKE DLIST+45»70tP0KE DLIST+48»6JP0 K E B I... I S T + 4 9 v 6 X P K E B L I S T + 5 ? 6 J R E M C H A N GE TEXT WINDOW TO GR. :1. 7 G 1... R :l. t P I... T 5 v 3 7 t B R A W T 50 * 5 J DRAW T 2 4 f 5 ! P S I T ION 2 4 t 3 7 J P K E 7 6 5 » 1 J X 1 1 8 r # 6 » * » * S J " J R E M B R A W S L T M A C H I N E 80 COLOR OJFOR X~10 TO 13 J PLOT 26»XJDR A WTO 32 fX: PLOT 34 rX i BR A WTO 40»XJPL0T 4 2yXJBRAWT0 4S*XJNEXT xjrem make window 90 A R T ■ P E E K < 1 34 ) + P E E K(135)*256:STTAB=' P E E K ( 1 4 ) + P E E K ( 1 4 1 ) *256 J R E M G E T T H E V A R I ABLE S STRING TABLES 100 POKE 559x46JREM SET EOR DOUBLE LIN E P/M RESOLUTION 1 1 P M B A S E ■:■■■■ P E E K < 1 6 ) - 8 5 P K E 5 4 2 7 9 t P MBA SEJREM SET P/M GRAPHICS 2K ABOVE ENB F MEMORY :l. 2 P M B A S E :::: P M B A S E * 2 LVJ 6 ! R E M F U I... I... A D D R E S S OF P/M GRAPHICS 130 X=OJFOR Z=512 TO 768 STEP 1281 REM BEGINNING OF EACH PLAYER 1 4 S T R F F S E T - P M B A S E + Z •■■• S T T A B t R E M C I -I A N G E THE OFFSET VALUE FOR THE STRINGS 1 5 S T R A I... 3 ~ I N T ( S T R F F S E T / 25 6 ) J R E M H I G H ORBER ABBRESS OF OFFSET 1 6 S T R A I... 4 ■ S 'I' R F F S E T ■••• 25 6* S T R A I... 3 i R E M LOW ORBER ABBRESS OF OFFSET 170 POKE VART+2+X»STRVAL4tREM THIRD BY TE FOR STRING VARIABLE IN VARIABLE TAB LE 1 8 P K E V A R T + 3 +X » S T R V A I... 3 J R E M F U R T H B YTE FOR STRING VARIABLE IN VARIABLE TA BLE 190 POKE VART+4-fX»128IR£M MAKE STRING 128 BYTES LONG 200 POKE VART+5+X»0 210 POKE VART + 6 + Xy 1281 REM SET LENGTH T 102 128 220 POKE VART+7+X*0SX=X+8JNEXT ZJREM I NCREMENT X FOR NEXT STRING 230 P L 1 * ( 1 ) :::: " > t > " I P L :l. $ ( :l. 2 8 ) :::: " > t > " ! P I... :i. $ < 2 ) = P I... 1 $ 5 R E M C I... E A R T H E S T R I N G 240 X=36JF0R Z~l TO 54 I READ B JPLi* ( X «X ) ~ C H R * < B ) t X ~ X + :l. J N EX T Z } J C K P T $ = P I... :l. $ ( 7 3 , 80) :rem get symbols 250 DATA 255y()y32yl6y 16 y 40 y 108 y 108 y 260 DATA 255v0y0y24y60y 126 y 60 y 24 v 270 DATA 255y0y0y0y60y 126*60*0*0 280 DATA 255 y y 48 y 3 y 24 y 60 y 126*60*0 290 DATA 255*0*0*0*126*126*0*0*0 300 DATA 255 y 0» 16* 16 y 56 y 124* 124 y 1 24 y 310 PL2*~PL1$!PL3*"PL1* 320 POKE 53277 * 3 % POKE 623*4JREM ENABLE P / M G R A P l-l 1 C S •- E S T A B I... I S H P R 1 R I T I E 8 330 P K E 7 04 * 9 1 P K E 705*1201 P K E 7 6 » 3 : P K E 7 8 y 1 5 i R E M S E T C 1... R S 340 MONEY-100JPOKE 53248 * 104 5 POKE 5324 9 y 119 SPOKE 53250 y 135? REM FILL THE WIND ows 350 88 ai 360 MOVE THE PLAYERS ON THE SCREEN " :>• G I... E A R > Y U H A U E * ■ * MON E Y J ? " P R E a K E Y " 9 i R E M P R I N T T l-l E M E S S A G E F PEEK (764) -=255 THEN 360 J REM WAIT FOR A KEY TO BE PRESSED 370 MON E Y = M N E Y - 1 5 P K E 7 6 4 * 255 JT ~ I N T ( R N D ( 1 ) # 1 5 ) •!• 5 J R E M P I C K NUMB E R F S P I N S F ROM 5 ■■■• 14 3 8 F R X « 1 T T * 9 I T E M P * "-■ P I... 3 * ( 3 6 ) X P I... 3 $ ( 36 * 38 ) ~PL3# ( 37 y 89 ) i PI... 3$ < 89 ) «TEMP* i REM ROTATE THE STRINGS 390 F R Z ■ 1 T 2 I T E M P $ ™ P I... 2$ < 3 6 ) J P L 2 $ ( 3 6 y 8 8 ) ~ P I... 2 * < 3 7 * 89 ) ! P I... 2 $ ( 3 9 ) ~ T E M P $ J N E X T 400 FOR Z-l TO 3JTEMP$=PL1$<36)JPL1$<3 6 y 8 8 ) ~ P I... 1 * < 3 7 * 8 9 ) I P L 1 * (89) = T E M P $ i N E X T Z i NEXT X 4 1 T ;;:: I N T < R N D ( 1 ) * 6 ) i 6 { R E M P I C K NUMB E R OF TURNS FROM 1 ••■• 6 420 F R X ■■■■■■■■ 1 T T *9 J T E M P $ ~ P I... 2 $ < 36 > I P I... 2 $ ( 36 r 8 8 ) = P I... 2$ ( 3 7 ? 8 9 ) J P I... 2 $ ( 89 ) = T E M P $ I R E M ROTATE THE FIRST TWO STRINGS 430 F R Z ■ ;|. T 2 } T E M P * ■ p |... ;|. $(36)? P I... 1 $ ( 3 103 Listing 6-4. Player/Missile Strings (continued from page 103) 550 ? "PRESS ANY KEY TO PLAY AGAIN" i ;R EM NEXT PLAYER 560 IF PEEK (764) "255 THEN 560 I REM WAIT FOR A KEY 570 GOTO 340 J REM PRESS SYSTEM RESET TO END GAME 6 y 88 ) -PL 1* < 37 9 89 ) J PL :l. $ ( 89 ) --TEMP* { NEXT Z t NEXT X 440 T = I N T ( R N D ( 1 ) * 6 ) + 6 5 R E M P I C K NUMB E R OF TURNS FROM 1 •■■• 6 450 F R X * :l. T T #9 J T E M P $ = P I... 1 $ ( 3 6 ) i P I... :l. $ ( 3 6 y 8 8 ) = P I... I * ( 3 7 y 8 9 > i P I... 1 $ (89) ■ T E M P * t N E X T x:rem last string 455 REM CHECK FOR PAYOFF 460 IF Pl...3$ ( 3? i 44 )-PL2*( 37 t 44) AND PL 3 *<37»44)~PL1$(37»44) AND PL3#~JCKPT* T HEN M0NEY=M0NEY+500t 8-75} GOTO 5:1.0 470 IF PL1$ (37*44 )=PL2$(37» 44) AND PI...3 * ( 37 y 44 ) =PL1* ( 3? t A A ) THEN MONEY-MONEY* :loo:s=-~j.oo{goto 510 480 IF PL 1 $ ( 37 y 44 )™PL2*( 37 » 44) THEN MO N E Y == M N E Y f • 5 t S ■■■■■■ 1251 8 T 5 1 490 IF PL 1 $( 37 y 44 ) =PL3$( 37 » 44) THEN MO NEY=MONEY+5JS*15(MGOT0 5:1.0 500 S=200 : REM NO WIN 510 SOUND Of St 10 r 10 {FOR X-l TO MONEY IN EXT X: SOUND OyOyOyOJREM MAKE SOUND TO INDICATE WINNING 520 IF MONEY>0 AND M0NEY<1000 THEN 350 J REM CHECK FOR END OF GAME 530 ? " > C I... E A R :>• " : I F M N E Y = T H E N ? " a o u I a s e ■ J T 5501 R E M I... 8 T Y U R S H I R T 540 I F M N E Y ~ 1 T H E N ? " Y U W I N " i R E M BROKE THE BANK 550 ? "PRESS ANY KEY TO PLAY AGAIN" i IR EM NEXT PLAYER- 560 IF PEEK (764) -=255 THEN 560 : REM WAIT FOR A KEY 570 GOTO 340 J REM PRESS SYSTEM RESET TO END GAME Line 40 sets aside one byte for the strings that will be used for the players. TEMP$ will hold one byte during the string manipulation. JCKPT$ is the jackpot character. In order for this procedure to work correctly, PL1$, PL2$, and PL3$ must be the first three variables in the 104 variable name table. Before typing this program in, turn off the computer; then turn it back on. Begin typing in this program. If the computer is given a variable before the PL strings, it will store that variable in the table. This will set the PL strings off and the program will not work correctly. Line 50 sets the graphics to 4. We will only need two colors for the slot machine, the background color and the machine's color. The beginning of the display list is stored in DLIST. Line 60 changes the text window from graphics mode to graphics mode 1. When we are using a graphics mode with a text window, the display list will have another load command after the proper number of mode commands. This command tells the computer to start a new screen display in graphics mode 0. We will change that to graphics mode 1 by poking it with a 70. The three lines that would display graphics mode are changed to graphics mode 1 by poking three more locations in the display list with a 6. (Graphics mode 1 is ANTIC 6.) Now the text window in the program will have large print. Line 70 uses the XIO command to draw a slot machine on the screen. Line 80 uses color (black) to erase part of the slot machine for the windows. Line 90 stores the location of the variable table in VART and the address of the string/array are in STTAB. These two values will be used to relocate the strings. Line 100 sets the player/missile for double line resolution. Line 110 sets the player/missile graphics 2K before the end of memory. The top of memory is stored in location 106. By subtracting 8 from it, we are subtracting 2K of memory. The beginning of the player/missile area is stored in 54279. Line 120 multiplies the beginning address by 256 to arrive at the decimal location of the player/missiles. The number that is stored in PMBASE before it is multiplied is the high order address. Lines 130-220 relocate the three strings that will be used for the player/missile graphics. The variable X is set to (zero). This is the variable number or location in the variable table. The first player is 512 bytes past the address of the beginning of the player/missile area. Each player is 128 bytes apart, so the for . . . next loop uses a step 128. The string offset is stored in the variable STROFFSET. This is the value that the computer will add to the address of the string/array area to arrive at the location of the string. When the strings are not being relocated , the first string will have zeros as the offset since the first string will begin at the first byte of the string/array area. The second string's offset will be one more than the length of the first string. The string should begin with the first byte of the player. The value of Z will be added to PMBASE. This is where the player begins in the player/missile graphics area. The value of STTAB must be subtracted because the computer will "add" this value back when it is looking at the string. The value that you arrive at is the new offset for the string. This value is greater than 255, so it will have to be divided into two bytes. The high order address is the integer (whole number) of the offset divided by 256. The low order address is arrived at by subtracting the high order integer times 256 from the address. These two bytes are stored in the third and fourth bytes of the variable table for that string. The next two bytes in the variable table indicate the amount of memory set aside for the string. We want 128 bytes for each string, so the low order is poked with 128 and the high order with a (zero). The last two bytes set the length of the string. We want the string to be 128 bytes long, so these two locations will be poked with a 18 and (zero). The variable X is incremented by 8 because the information for the next string will begin 8 bytes down from the beginning of the information for this string. This routine is repeated two more times. When it is finished, the first three strings in the variable table will be 128 bytes long and their location will be the player/missile graphics area. 105 Line 230 clears the first string. Line 240 reads the data in the next 6 lines and stores it in the string. This data will draw the cherry, orange, lemon, apple, gold bar, and bell into the player/missile graphics are. The string JCKPT is set to the 5th character in the string. Line 310 sets the other two strings. Line 320 pokes location 53277 with a 3 to enable the players, and location 623 is poked with a 4. This establishes the priorities of the players and the graphics on the screen. If the priorities were not set, some of the players would appear over the machine instead of inside it. Line 330 sets the colors of the slot machine and the three wheels. Line 340 sets the variable MONEY to 100. This is the amount of money you have to start the game. The three players are moved on the screen by poking their locations into the correct registers. Line 350 prints a message in the text window. Line 360 checks location 764 for a value other than 255. When the value of this location changes, then a key has been pressed. Line 370 subtracts one dollar from the amount of money left. The key location is cleared, and a random number from 5 to 19 is chosen. This number determines the number of times the rightmost wheel will spin. Lines 380-400 make the wheels spin. This works on the same principle as the boat in the first program of this chapter. The top character of the string (in this case it's in the 36th location) is removed from the string and stored in a temporary location. The rest of the string is moved up one byte. The character that is being stored in the temporary location is moved to the end of the string. Each of these strings is a different player. The rightmost wheel is rotated once, the middle one twice and the leftmost three times each time the program executes the loop. This gives the illusion of the wheels spinning at different speeds. Lines 410-450 spin the middle and leftmost wheel after the right wheel stops. Each wheel is spun a few more times after one wheel stops. Lines 460-500 check for a payoff. If all three characters shown on the machine are the same and they are the bars, the jackpot is won. 500 is added to the amount stored in MONEY. If the three are the same, but not the jackpot, 100 is added to the amount stored in MONEY. If the first two characters are a match, 5 is added. If there are no matches, nothing is added to the amount in MONEY. Line 510 makes a sound to indicate the win. The variable S is set to a different value depending on the amount of MONEY won. This line generates the sound. Line 520 checks the variable MONEY to see if you can still play. If there is no MONEY, or the value of MONEY is greater than 1000, the game ends. Line 530 clears the screen and prints you lose if you have no money left. Line 540 prints you win if the amount in MONEY is greater than 1000. Line 550 prints the message on the screen. Line 560 waits for a key to be pressed. The program will loop here until a key is pressed, if the system reset key is pressed, the program will end. Line 570 sends the program back to line 340 to play again. 106 Chapter 7 Display List Interrupts An interrupt is a subtle way to get the computer to do a task while it appears to be doing something else. When you are working on a program with your ATARI, the computer looks like it is just sitting there waiting for you to enter your new line or command. What is actually happening is the computer is very busy maintaining several areas. The ANTIC chip keeps the information on the screen; the clock keeps time; and the computer keeps checking to see if it's time to start the active mode. When you press a key, you are interrupting the 6502. It now checks which key was pressed, and sends that information over to the ANTIC chip so that it can be displayed on the screen. Because of the speed at which the computer works, this appears to be done instantaneously. The computer is capable of handling more functions if it is interrupted at the proper times. HANDLING AN INTERRUPT One of the best times to interrupt the computer is when it is drawing on the screen. To draw an image on the screen, the computer must be synchronized with the raster scan of the television set. This happens within the computer and we do not have to be concerned with it. When the raster scan begins to draw a picture on the screen, it begins with the upper left corner and goes across the screen to the upper right corner. When it is finished with the line, it shuts itself off, retraces its line, then drops down one line and turns itself back on. It continues to draw lines, turn itself off, retrace, drop down, and turn itself back on until it reaches the bottom of the screen. There it will shut itself off and return to the top of the screen, where it will begin to draw all over again. The period of time during which the raster is turned off and is retracing the line is called a horizontal blank. The period of time needed for the raster to go back to the top of the screen is called the vertical blank. During this time we can interrupt the computer and have it do something that we want it to do: something that may not be possible in BASIC or machine language alone. There are certain registers or memory locations in your ATARI that seem to have a double in ROM. The color registers are one set of these registers. There are 9 different locations to store the color values in RAM. There are also 9 color locations in the ROM or Operating System. If you poked a value into the RAM locations, you would change the color of the character on the screen. If you poked a value into the corresponding ROM location, nothing would happen. ANTIC draws characters on the screen based on the colors in the ROM locations (these 107 Table 7-1 Hardware Registers and Shadows. Re«$i< rter h 3 row a r e a h a d o w d e s c ' •■ :i. p t i o i"i a d d r e s is i::j A •") '"' "X a d d r e a s Character Character Color bad Color resi: Color res: C o 1 o r r e s : Color res': ni o d e base :. 3 r O U l"i d . s t e r .ster 1 .ster 2 . a ter 3 54281 562/4 53270 53271 ,... .. } . ,.j ..., ...j 53273 ,/ v ',',i ^'.' 756 712 708 709 710 7 1 1 Color reM> ' p 1 a •■.:■; e r ( 53266 704 Color' res, >layer :l I:: i 3 2 6 7 705 Color reS/ ' p 1 a y er ^ 53268 706 C 1 o r rea, 'Player • 53269 707 Display 1 : . a t h i s h 54275 561 Display 1: . s t 1 o w 54274 560 locations are also called the hardware registers). Each time the vertical blank occurs, 60 times every second, the computer looks at the colors in the RAM locations and stores them in the hardware registers. If you poked a color value into a hardware register, it will be replaced within a 60th of a second! Table 7-1 shows a list of hardware registers. The second location is called the shadow register. This is the register that contains the value that will be placed in the hardware register by the computer during the vertical blank. There is a way to change a value in the hardware register without interference from the shadow register: interrupt the display list and change the value during a horizontal blank. WRITING SERVICE ROUTINES During the period of time that the raster scan is retracing itself, the computer is free to do other things, like change colors, character sets, or other images on the screen. To do this, however, the computer must be told to watch for an interrupt. In the following program, the 108 computer is told that there will be a display list interrupt. The correct bit is set for an interrupt at the end of a line, and the colors in color registers are changed. The only problem with using a display list interrupt to change the color value is that the character will always be one color above the line and the other color below the line. If the character travels above the line it will be changed to the original color. Listing 7-1. Color Service Routine 10 REM LISTING 7*1 n st:.i(v.Li,c. ROUTINE 30 REM BY L.M.SCHREl'BER FOR TAB BOOKS 50 GRAPHICS IS 6 D I... « P E E K ( 560 ) f P E E K < 56 1 > * 256 J D I... - D L + 1 J REM THE 5TH LINE ON THE SCEEN 70 POKE DL y PEEK (DL) +128t REM set the St h bit to 1 ba addinsi 128 to the peek o f t h a t 1 o e 3 1 i o i'i 80 FOR Ml... -1536 TO 1564 { RE A D Q X POKE MLj J NEXT ML J REM POKE THE MACHINE LANGOAG E SUBROUTINE INTO FREE RAM 9 P K E 5 1 2 9 J P K E 5 1 3 , 6 ! P K E 54 2 86 1 1 9 2 {REM AB DRESS OF MACHINE LANGUAGE SUBR OUTINE - ACTIO ATE INTERRUPT 100 DATA 72 v 138*72* 152 » 72 » 162* 100 y 160 y 8y 169y8Sy 141 y 10 y 212 y 141 r 24 y 208 y 1 42 y 23 y 208 y 140y22y208y 104 y 168y 104* 170y 104 y 64 :l. 2 P S I T I ON 2 t 1 : ? # 6 i " B I... U E "."dree n " 1 3 P S I T I ON 2 y 3 i ? # 6 i " r e d " y " Y E I... I... W " 1 6 P S I T ION 2 y 7 X ? # 6 y " P I N K " y " p u r p 1 e " 5 POSITION 7y?;? #6? "GREY" 170 GOTO 170 Line 50 changes the graphics mode to 18— mode 2 without the text window. Line 60 stores the beginning of the display list in variable DL. The address of the beginning of the display list is stored in locations 560 and 561. To arrive at this address, the contents of memory location 561 must be multiplied by 256 and the contents of memory location 560 must be added to this product. Add 10 to this address to point to the middle of the display list. Line 70 changes the display list. By setting the high order bit of a display list value to 1, we tell ANTIC that after it draws or writes this line onto the screen, there will be an interrupt. Since we may not be sure what the value might be at this particular location, the simplest way to set the bit is to add 128 to the value of this location. Line 80 reads the data from line 100 and pokes it into the free RAM beginning at location 1536. See Table 7-2 for the assembly language listing of the subroutine. Line 90 stores the address of the beginning of the interrupt routine at memory locations 512-513. The address, in this case 1536 is divided by 256. The high order address is the integer part of the quotient. 1536/256=6. There is no remainder. The 6 is stored in memory location 513. 109 Table 7-2. Service Routine to Change Colors. d e c i iii s 1 c o d e 138 a s s e iti b 1 y 1 s n a u s g b I :i. s t :i. n a !• H ;'-■ i I" ... :.. A 3 C C U In i..l 1 ■:-.< t r l"i TX A rl r 3 ns f e r :i n d e ;■; X t o accuuul a tor. 7 2 ! :: ' H A ? P u s h a c c u m u 1 a t o r o n I !"• n i "i !' ;-"■■ rrl' i" 1' r- ;:; i "i -I- r iv.^ i ■■ t 1 ca f stack i P t* o n i i 1 1 jiV.'l ';.;' X ) 152 -. L. '...' I 1 '..- v.. 1 1 l.- ..> 1.- 1 '..> 1 1 .:.■ 1 ... 1 1 "... i it A ? Transfer indeM Y to sccumula tor. 72 162 F'HA spMsri accumulator on C c o it t e n t s t ransferrei LDX #100 SLosd index X with 1' i from in )0 j i e >; i .1. '■..■' '-.,' 160 LDY #8 J Load i nde;; Y with 8 8 169 L.DA -II- 8 8 SLosd accumulator w:i. ■ ,h 88. 88 141 ETA H42.B2. liVtore t h e c o n t e r 1 1 « ■> of the 10 ;i> c c u in u I s t o r a t t h :i. s B d d r B S S S n d If there was a remainder, it would be stored in location 512. Since there is none, a zero is stored there. Memory location 54286 is poked with 192. This is a hardware address that can enable the interrupt for the display list interrupt and the vertical blank interrupt. If it is not enabled, ANTIC would ignore the code in the display list that tells it that this is the place where it should execute the interrupt routine. Lines 120-160 print on the screen. The first four words— blue, green, red, and yellow use the colors that are preset by the operating system. Be sure that BLUE is in uppercase and inverse, and red is lowercase inverse. Each word will appear in its color. The three words on the bottom will appear in new colors. PINK is uppercase inverse, and appears pink on the screen. Purple and GREY were previously green and YELLOW. The interrupt routine changed the color code in the 110 w 3 i t f D r t h e h D r :i. z o n t s 1 s a n c <• HT'A !:;^2/2 ? Store in color register* X S3? ? i ? B t o r e? :i. n oh-; X i n c o .1. o r r e ;-> . . . , 3 »Store index Y in color rssister PL A i Remove value from black « 1.68 TAY i {'\_a PI... A 1.70 TAX 1.04 PL A ,--■'-, .-:*!'. RTI ? I r 3 n s f e r 1 1 t a :i. ri d e ;■; Y . £ Remove another value from sitae !> Transfer it to index X* ? Remove value from stack « JReti.irn Prom interrupt? hardware register during a vertical blank. The operating system replaced the color with the color code from the RAM shadow address during the horizontal blank. Everytime something is printed on the top half of the screen, it will appear in the color set by the operating system, or the color that was placed in the shadow registers under program control. The colors on the bottom half of the screen will be the colors forced into the hardware registers during the interrupt. End this program by pressing the system reset key. Changing the colors in a program is only one possible use of interrupts. Any feature that has both a shadow or RAM address and a hardware address can have multiple uses with the interrupt. In the next program we will use two character sets in the same program. The standard character set will be displayed at the top of the screen, and the new characters will be used at the bottom. 111 Listing 7-2. Double Character Sets :i. o 20 I 30 40 ( 50 ( JEM LISTING 7,2 :EM DOUBLE CHAR ACT IEM BY L.M.SCHREIBER FOR TAB BOOKS GRAPHICS ;b=peek-8:pok * 224 j rem place new ch end of memory 60 EOR ML- 1536 TO 155 Q 5 NEXT ML J REM MOVE TH TO RAM E 204*CBJP0KE 206 ARACTERS 2K ABOVE 5t READ Q t POKE ML* E MACHINE CODE IN 70 Q~USR< is; "X a 80 DATA 104*162*2*160 3 * 200 » 208 * 249 » 230 * 206 242*96 90 C1~CB*256+263JF0R AD R t POKE X*GJNEXT X 00 DATA Or 126? 102*10 01 DATA * 124 * 102*10 02 DATA Or 124 * 100*96 03 DATA 0* :1.24 s- 1 02*10 04 DATA 0* 124 v 100x96 ) J REM NOW RUN IT *0* 177*205* 145*20 * 230* 204* 202* 208* 05 DATA r 124 r 100*96 06 DATA 0*124*100*96 07 DATA 0*102* 102* 10^ X-Cl TO CI +20 7 J RE 2*126*102*102*102 2*124*102*102*124 *96* 100* 100* 124 2* 102*102*102* 124 *120»96*100*124 * 120*96*96* 112 * 108* 100* 100* 124 9 09 DATA 0*30*12*12*1 10 DATA 0*102*100*10 11 DATA 0*120*48*48* 12 DATA 0*55*90*90*9 DATA 0*94*102*102 D A T A 15 DATA 16 DATA 1.17 DATA L18 DATA 1.19 DATA ""■ ■!•>■ i •"> 13 14 0*60* 102m 102 0* 124» 102* 10 »6()< 1 02 v 1 02 0*124* 1 2 t 1 * 1 2 4 y 1 v 9 6 U !■' ■I y V v 9 !-' DATA 0*102*102*10 21 DATA 0*102*102*10 22 DATA 0*90*90*90*9 23 DATA 0*122*90*92* 24 DATA 0*102*102*10 25 DATA 0*124*70*76* 60 DL=PEEK<560>+PEEK 4y24y 24 y 60 2*76*76*124 4*124*102*102*102 48*50 y5()y 126 0*90*90*90 *102» 102*102*102 y 102* 102 y 102 y 60 2« 124 y 96* 96*96 v 102? 118*110* 102 2y 124 y 102 y 102* 102 * 1 24 > 1 2 * 76 * 1 24 24*24*24*60 2 • 10, ; v 107 » ;| 02 y I . ; 6 2*102*100* 104 y 112 0*90*90* 1 8 24*58*90*94 2*102*124*6*124 24*50*98* 124 <561)#256{DL™BL+1 112 5 {REM ADD SERVICE ROUTINE IN MIDDLE OF DISPLAY LIST .1.70 POKE Dl... i PEEK (Dl... )•!• 128 J REM SET BIT F OR INTERRUPT 1.80 POP ML- 1.536 TO 1 546 t READ J POKE ML yQJNEXT ML J POKE 1.538 » OB J REM POKE THE M ACHINE LANGUAGE SUBROUTINE INTO RAM 1.90 POKE 512*0 J POKE 51.3 , 6 i POKE 54286 vl 92 5 REM ADDRESS OF MAC MINE LANGUAGE SUB ROUTINE ■•■■ ACTIVATE INTERRUPT 200 DATA 72 y 1.69 » 1.52 » 1.41 t 1.0 y 21.2 1-1.41 •> 9y2 1.2 9 1.04 t 64 21.0 POSITION 9*21? "STANDARD CHARACTER a ii o 220 P S I T 1 N 1. 3 1 1 5 J ? " B 1... D F A C E " 300 BO TO 300 One of the first tricks that everyone learns is how to turn the screen upside-down by poking 755 with a 4. (If you've never tried it, do it now with the direct command: POKE 755,4 (If you have a program listed on the screen, it will look most impressive!) This is fine if you want everything to be upside down. But, maybe, you want just one or two lines in the middle of the screen turned for a mirror effect. Again, the interrupt routines can be used to do it right on cue! Listing 7-3. Mirror Images Routine 10 REM LISTING 7,3 20 REM MIRROR IMAGES ROUTINE 30 REM BY L*M*SCHEEIBEE FOR TAB BOOKS 4 GRAPHICS 5 D I... ~ P E E K ( 5 6 ) + P E E K ( 5 6 1 ) * 2 5 6 t D I... = D I... + 1 5 5 REM THE STH LINE ON THE SCEEN 7 P K E D I... f X ■> P E E K ( D I... ) ■!■ 1 2 8 X R E M s e t t h e 8 1 A b :i. t t o 1 b ■:-.! s ci a :i. n s 1 2 8 80 FOR ML™ 1.536 TO 1546? READ QX POKE Ml... y Q t N E X T M L t R E M P K E T H E M A C H I N E I... A N U A E SUBROUTINE INTO PREE RAM 9 POKE 512yOJPuKE 51 3*6 J POKE 54286 » 1.9 2 J REM ADDRESS OF MACHINE LANGUAGE SUBR OUTINE - ACTIVATE INTERRUPT 1 00 DATA 72 1 1 69 » 4 > 1 A 1 t 1 y 2 1 2 v 1 4 1 y 1 y 2 1 2 113 Line 40 sets the graphics mode to 0. This command will make the computer reset the entire display list. By having the display list reset, we can run this program several times. If the display list was not reset, line 70 would produce an error message. Line 50 finds the beginning of the display list and stores this address in the variable DL. We add 15 to this address so that we will be working with the middle of the display list. Line 70 sets the eighth bit of the byte in the display list. By adding 128 to the value found at this location, we set only one bit without disturbing the original value. Line 80 reads the machine language subroutine that inverts the letters. Line 90 pokes the address of the machine language subroutine into memory locations 512 and 513. 192 is poked into location 54286 to tell the computer that an interrupt will be generated. Run the program. Now list the program. The listing on the top half of the screen will be correct. The listing on the bottom half of the screen will be inverted. Press the system reset key to turn the screen back to normal. PRECISE TIMING Another use for a service routine is for precise timing. The routing will be executed every time the computer comes to that line in the display list. Since the display list is synchronized with the raster scan on the television, the routine will be executed every l/60th of a second. By placing a counter in the routine, a character can be moved, a sound can be made, or a color changed precisely on schedule. In the following program, the neon sign is kept flashing with an interrupt service routine. Listing 7-4. Precise Timing 20 REM PRECISE TIMING 30 REM BY L.M.5CH REISER FOR TAB BOOKS 40 GRAPHICS X POKE 752 * 1 5 D i... :::: P E E K ( 5 6 ) 1 P E E K ( 5 6 .1. ) * 2 5 6 ! D I... « D I... f 6 i REM THE 2MB LINE ON THE SCEEN 70 POKE BL?PEEK(BL ) +128 J REM set the St f'i bit to .1. by adding 128 80 EOR ML =1536 TO 1 558 J READ QfPOKE ML» Q J NEXT ML? REM POKE THE MACHINE LANGUAG E SUBROUTINE INTO PREE RAM 9 O ! ::i K E 2 O 6 t I R E M S E T C U N T E R A N D D A T A TO 1 P S I T 1 N 9 i ? " " 5 1... R 4 2 t P I... T 3 3?5SDRAWT0 33 » 18 I BR A WTO 5»18JDRAWT0 5? 5JDRAWT0 33 v 5 1 1 1... R 1 7 I P I... T 3 4 1 4 J D R A U T 3 4 » 1 ? J B RAWT0 4. IvUiRAWTO 4 > 4 JDRAWTQ 34? 4 120 COLOR 42 J PLOT 35 t 3 JBRAWTO 35»20JDR AWTO 3y20niRAWT0 3v3;BRAWT0 36^3 1 3 P 3 1 T 1 N 1 3 1 1 ! ? " B E D B Y - BY MO T E I... " 114 140 POSITION 10 v 12 1? "COLOR TV •- WATER BED" 1 5 P S I T I N 1 5 » 1 4 J ? " I... U P R I C E " 190 POKE 51 2* 01 POKE 513 y 6 JPG K'E 54286*1 92? REM ADDRESS OF MACHINE LANGUAGE SUB ROUTINE ■■■■ ACTIVATE INTERRUPT 200 DATA 72i'165i'19»240»16»169»255j»133» 1 9 v 1 65 :' 206 y 9 y .1. 9 1 33 v 206 t 141 v 10 f 212 > 141 y 1 r212» 104 y 64 210 GOTO 2:1.0 Line 40 sets the grapics mode to 0. This must be done at the beginning of the program because you will be adding a value to an existing value in the display list. By setting the graphics mode at the beginning of the program, the computer reinstates the original value into the display list. If this wasn't done, and the program was rerun, the computer would be adding a value to the value that was changed in the previous run. Poking 752 with a 1 removes the cursor from the screen. Line 50 finds the beginning of the display list and sets the variable DL to the 2nd line or the 7th value in the display list. Line 70 gets the value from the display list and adds 128 to it. The new value is poked back into the display list. This is the line that the graphics were set back to zero for. Line 80 reads the machine language subroutine into memory. This is the routine that the computer will execute during the interrupt. Line 90 pokes the memory location 206 with a zero. We will be using this location as a counter for this program. Line 100 and 120 use the position command to erase the cursor that was left there by the graphic command. The plot and DRAWTO commands draw a rectangle on the screen. The 42 after COLOR is the character that will be drawn. In this case, it will be an asterisk (*). Line 110 draws another rectangle between the first and second rectangle. Lines 130-150 print the message inside the sign. The words COLOR, WATER, and LOW PRICE are in inverse video. Line 190 tells the computer where in memory the service routine is located and tells the computer that there will be an interrupt. Line 200 contains the data for the machine language subroutine. This subroutine uses the clock to find out when the words should be turned on and off. See Table 7-3 for the assembly language listing for this program. To end this program, press the system reset key. Listing 7-4A. Precise Timing— Second Method 10 REM LISTING 7, 4 A 20 REM PRECISE TIMING 30 REM BY I... *M,SCHREIBEE EOR TAB BOOKS 4 G E A P H I C S J P K E 7 5 2 > 1 5 D I... ::: P E E K ( 5 6 ) f P E E K ( 5 6 1 ) * 2 5 6 S D I... ~ D i... + 6 S REM THE 2ND LINE ON THE SCEEN 70 POKE DL v PEEK (DD4-128J REM set the St 115 Table 7-3. Service Interrupt to Flash Inverse Characters. ci e e :i. m a 3. c o d e a s 0'R the contents of the accumulator 1 with 1. 133 ST A 206 t Store the accumulator at location 206 206, 141 ST A 542S2 5 Store the accumulator at this 10 location and wait for horizontal 212 sync, 141 ST A 54273 I Store is at this location - 1 hardware address for 1 character 2 1 2 m o d e , 104 PI... A vPull trie value for the accumulator off trie stack, 64 RTI ? Return from interrupt. 116 Listing 7-4A. Precise Timing— Second Method (continued from page 115) h bit to 1 by adding 128 SO FOR ML =-1536 TO 1 558 S READ OS POKE ML* Q J NEXT ML J REM POKE THE MACHINE LANGUAG E SUBROUTINE INTO FREE RAM 90 POKE 206 s- OS REM SET COUNTER AND DATA T 100 POSITION 0*0 S? " " S COLOR 421 PLOT 3 3 9 5 S DRAW TO 33 * IS S DRAW TO 5yl8SDRAWT0 5» 5SDRAWT0 33*5 1 1 C 1... R 1 7 J P I... T 3 4 * 4 t D R A W T 34* i 9 i D RAWTO 4»19SBRAWT0 4»4SDRAWT0 34 r 4 120 COLOR 42 i PLOT 35 r 3 SDR AUTO 33* 20 SDR AWTO 3»20SBRAWT0 3 t 3 J DRAWTO 36*3 1 3 P S I T I N 1 3 * :|. I ? " B E D D Y •■■■ D Y HO T E I... " 1 4 P S I T 1 N 1 till ? " C 1... R T U ■- W A T E R DED" 150 POSITION 15*145? "LOW PRICE" 190 POKE 512 *Q SPOKE 513 » 6 SPOKE 54286*1 92 1 REM ADDRESS OP MACHINE LANGUAGE SOD R U T I N E ••■■ A C T 1 A T E I N T E R R U P T 200 DATA 72* 165* 19*240* 16 v 169*255* 133* 1 9 * 1 6 5 * 2 6 * 9 * * 1 3 3 * 2 6 * 1 4 1 * ;|. () , 2 1 2 * 1 4 1 * 1 *212* 104 p64 210 GOTO 210 This listing is nearly identical to the previous one. The difference is in the data line. In the first program, the value in location 206 was "or'd" with 1. The value was stored in 54273. By alternating this value between a 1 and a 0, we turn on the characters that were printed in inverse video. In the second program a zero is stored in this location. Now the computer will print the same characters in inverse video, then normal video. PLAYER/MISSILE ENHANCEMENTS In a previous chapter, the player/missile graphics were described as a band that fit over the screen. This band could be moved to the right or left by poking a location with a value. In the next program we will use the service routine to continually move a player on the screen. Listing 7-5. Moving Players 10 REM LISTING 7,5 20 REM MO VI NO PLAYERS 30 REM DY I... ,M,SCHREIBER FOR TAB BOOKS 50 GRAPHICS 6 D I... ■■■■■■■■ P E E K ( 5 6 ) + P E E K ( 5 6 1 ) * 2 5 6 SB i... = D I... + 6 J REM THE 2ND LINE ON THE SCEEN 70 POKE Dl... * PEEK ( DDL 12SJ REM set the 8t 117 Listing Listing 7-5. Moving Players (continued from page 117) h bit to 1 by adding 128 to the peek o f t h a t 1 o c b t i o i"i 90 A-~PEEK<:t.06>~16JREM 2K ABOVE DISPLAY LIST :i. P K E 5 4 2 7 9 t A I P MB A S E = A*256JREM T E I... I... ANTIC WHERE PLAYERS WILL BEGIN 1:1.0 POKE 559*62$P0KE 53277 ? 3 I REM SINGL E LINE RESOLUTION 120 FOR X-PMBASE-M024 TO PMBASE+1280 IP OKE XjOJNEXT XJREM CLEAR OUT THE GARB A GE 130 RESTORE 14OSF0R X~0 TO 10 1 READ (KP K E P NBAS E f 1 1 4 + X t Q I N E X T X 140 DATA 64* .1.20 *94 t 95 v 94 * 120 t 64 » 64? 255 * 1 26*60 150 POKE 704*60JPOKE 53248* 01 POKE 205 y J POKE 710*0 170 EOR ML- 1536 TO 1548 i READ Q I POKE ML »q:next ml t rem poke the machine langua GE SUBROUTINE INTO EREE RAM 190 POKE 512*0 SPOKE 5 13*6 { POKE 54286*1 92 t REM ABDRESS OF MACHINE LANGUAGE SUB ROUTINE ■- ACTIVATE INTERRUPT 200 DATA 72*230*205*165*205* 141 * 10* 2 12 * 141 * * 208 * 104 * 64 210 GOTO 210 Line 50 sets the graphics mode to 0. This is done at the beginning of the program because a value will be added to an existing value in the display list. By setting the graphics mode at the beginning of the program, the computer reinstates the original value into the display list. If this wasn't done and the program was rerun, the computer would be adding a value to the value that was changed in the previous run. Line 60 finds the beginning of the display list and sets the variable DL to the 2nd line or the 7th value in the display list. Line 70 gets the value from the display list and adds 128 to it. The new value is poked back into the display list. This is the line that the graphics were set back to zero for. Line 90 finds out how much memory is in the system and subtracts 2K from it. This places the player/missile graphics before the display list. Line 100 pokes the beginning location of the player/missile area into 54279. That amount is multiplied by 256 to get the actual location of the beginning of the player/missile area. Line 110 sets the resolution to single line resolution and tells the computer to enable the players/missiles. Line 130 clears out the memory area that will be used by the player. If this memory is not 118 cleared, the player could contain random bits or the data from a previous program. This clutter would appear on the screen when the player is moved onto the screen. Line 130 reads the data that makes up the boat into the player/missile graphics area. Line 140 is the data for the boat. Line 150 sets the color of the boat, the background color of the screen, and sets the location of the boat on the screen to zero. Memory location 205 will be used as a shadow location for 53248. The value in 205 will be changed by one each time the computer executes this subroutine. This value will then be stored in location 53248 by the service routine. Every time this value changes, the boat will move on the screen. Line 170 reads the values for the machine language routine and stores them in RAM. Line 190 tells the computer where in memory the service routine is located and tells the computer that it will have an interrupt. Line 200 is the data for the machine language subroutine. To end this program press SYSTEM RESET. When you use any service routine in program, keep in mind that the computer will execute the routine continually until the system reset key is pressed. If it is used with a BASIC program, the program can be processing information, waiting for an input, or drawing on the screen while the service routine performs its functions. In effect, you are running two programs at the same time. 119 Chapter 8 Scrolling Scrolling is a technique that moves the contents of a screen up, down, left, or right. When the screen appears to move up or down, the movement is referred to as vertical scrolling. When it moves left or right, the movement is referred to as horizontal scrolling. Either the entire screen or selected lines can move. Text adventure games usually scroll the bottom part of the screen, while the top part remains the same. The text appears to disappear just under the dotted line. Space games often use both horizontal and vertical scrolling. The entire galaxy moves to the left or right, up or down, depending on the direction of the joystick. This gives the illusion of a larger playfield and adds realism to the game. There are two methods of scrolling on the ATARI computer. The course vertical scroll moves information up or down one line at a time. The entire screen moves up or down. If there is a lot of information on the screen, the movement could appear jumpy. The course horizontal scroll moves every line to the left or right one byte. Again, moving the entire screen could make it appear to roll. It does not look smooth. Fine vertical scrolling moves the line up or down by one pixel. As each line moves up, the line beneath it also moves up. The movement is much smoother than the course scroll. The fine horizontal scroll moves the line to the left or right by one pixel. COURSE SCROLLING In a previous chapter we looked at the display list. The fifth and sixth bytes of the display list tell the computer where the screen memory begins. If this value were changed, the screen display would be different. In the next program, you will print a message on the screen. The message is too long to be displayed on the screen all at one time. You could print part of it, have a timing loop in the program, and then print the rest of it, but in this program the entire message is printed on the screen slowly. The message scrolls from the bottom of the screen to the top. It is not difficult to read, although it is a bit jumpy. Listing 8-1. Course Vertical Scroll 10 REM LISTING 8*1 2 REM COURSE VERTICAL SCROLL 121 Listing 8-1. Course Vertical Scroll (continued from page 121) 30 REM BY L.fUSCHREIBER FOR TAB BOOKS 40 GRAPHICS 5 D I... I S T = P E E K < 5 6 ) + P E E K ( 5 6 :l. ) * 2 5 6 IR E M G ET THE BEGINNING OF THE DISPLAY LIST 6 P K E D I... I S T 1 3 9 P E. E K ( D I... I S T + 3 ) + 3 70 FOR X^6 TO 28 J POKE DLIST+ X t 7 ! NEXT X SO ? "THIS MESSAGE WILL" 90 ? "SCROLL ON THE" 100 ? "SCREEN, IT IS" 110 ? "MUCH TOO LONG TO" 120 ? "BE SHOWN ALL AT" 130 ? "ONCE •■ SO YOU" 1.40 ? "ONLY SEE PART OF" 150 ? "THE MESSAGE AT A" 160 ? "TIME, " 170 ? "WHAT YOU DON'T" 180 ? "SEE IS IN THE PART" 190 ? "OF MEMORY THAT IS" 200 ? "NOT DISPLAYED ON" 210 ? "THE SCREEN, " 220 ? "THE COURSE SCROLL" 230 ? "MAKES THE ENTIRE" 240 ? "MESSAGE SHOW! " 3 S C R I... W ~ P E E K ( D I... I S T ■!■ 4 ) l S C R l-l I ~ P E E K ( D I... IST+5) 3 1. P R X ■ I T 1 1 t S C R I... W - S C R I... W + 4 i R E M ADD TO THE VALUE TO MOUE TWO LINES UP ON THE SCREEN 320 FOR Y~l TO 500 J NEXT YJREM TIMING I... OOP FOR READABILITY 330 IF SCRL0W>256 THEN SCR LOW^SC PLOW -2 56JSCRHX=SCRHI+1JREM GO TO THE NEXT PA GE OF MESSAGE 340 P K E D I... I S T I- 4 y S C R I... W I P \< E D I... I S T i 3 y S C R H I J P. E M D I S P I... A Y N E W S C R E E N 350 NEXT XJREM SHOW ENTIRE MESSAGE Line 40 sets the graphics mode to 0. This is done because you will be poking a value based on the peek of a location in the display list. If the value has already been changed and the program is run again, the results on the second run may not be the same as on the first run. Line 50 finds the beginning of the display list. Line 60 changes the value of the fourth byte of the display list (the first byte is DLIST+O). It will now be graphics mode 2. Line 70 changes the rest of the display list to graphics mode 2. This mode uses 16-pixel rows 122 instead of 8-pixel rows like modes and 1. Since only 12 rows will be displayed on the screen at one time, half of the display list will not be seen. Lines 80 - 240 print the message on the screen. There are 17 rows of text. Since we changed the mode by changing the display list, the computer will try to place 40 characters on a line. Each line that we are printing is less than 20 characters. The text will appear double spaced on the screen. All 17 rows of text will be placed in the area of memory set aside for the screen display. Line 300 finds the beginning of the memory set aside for the screen. The two bytes are stored in variables SCRLOW and SCRHI Lines 310 - 350 scroll the message on the screen. Line 310 begins the for . . . next loop that will move the beginning byte of the screen display area 11 times. 40 is added to the value in SCRLOW. This is the low order byte of the beginning of the screen display area. We add 40 so that we can move 2 screen rows at the same time. Line 320 contains a timing loop. If we did not slow down this routine, the lines would be printed so fast that we could not read them! Line 330 checks the value of SCRLOW. If it is greater than 255, it will be reduced by that amount, and SCRHI will be increased by 1. If we didn't increase SCRHI by 1 every time SCRLOW reached 255, the computer would stay on the same page of memory. Line 340 changes the beginning of the screen memory by changing the contents of the memory locations that ANTIC looks at to start displaying information on the screen. Line 350 continues the for . . . next loop. To return to the text mode, press the system reset key. The next program prints every character that the computer is capable of printing in the color text mode. Every line contains all 256 characters, but only 20 characters can be displayed on the screen at one time. How can every line contain 256 characters? Remember that the fourth instruction in the display list tells ANTIC the mode of the top line and that the next two bytes contain the beginning of the screen memory. If we change the display list so that every line starts its own screen memory, we can make the lines as long or as short as we need. Each line can be in a different mode, or they can all be in the same mode. The next listing prints all the characters in the same mode. The one following it uses mixed modes. Listing 8-2. Course Horizontal Scroll 10 REM LISTING 8*2 20 rem course:: HORIZONTAL SCROLL 30 REM BY L.M.SCHREIBER FOR TAB BOOKS 40 POKE 5 5 9.0? REM TURN OFF ANTIC 5 S C R E E N = P E E K < 1 6 > •-• :l. 2 i R E M T H E S C R E E N WILL BEGIN 12 PAGES FROM THE ENB OF ME MORY 6 O B I... I S T - S C R E E N * 2 5 6 ■•■• 5 O i R E M S T A R T T H E B I SRI... AY LIST 50 BYTES BEFORE THE SCREEN 7 F R X ~ T 2 ; P O K E B I... I S T + X « 1 1 2 I N E X T XJREM FIRST THREE BYTES OF B I SPLAY LIS T 80 FOR X~l TO 12: REM TWELVE LINES BISP LAYEB ON THE SCREEN 9 O P K E B I... I S T \-3*X*? 1 i R E M M O B E 2 123 Listing 8-2. Course Horizontal Scroll (continued from page 123) 100 P K E D I... I S T i 3 * X -f :l. « i R E M I... (J W (J R I) E R A D DRESS OF SCREEN LINE :l. 1 P K E D I... I S T + 3 * X f 2 v S C R E E N + ( X - 1 ) J R E M HIGH ORDER ADDRESS OF SCREEN LINE 120 NEXT X 130 POKE dl: tion to beg: I S T + X * 3 » 6 5 J R E M J U M P I N S T R U C INNING OF DISPLAY LIST . 4 D I... H I :: = I N T < D I... I ST/256)? D L I... ;::: D L I S T •••■ ( D I... (1*256) 1.50 POKE DLXST+X*3+lrDLL0 1. 6 P K E D I... I S T + X * 3 + 2 9 D L H I 1. 7 P K E 5 6 ■' D I... I... l P K E 561? D I... H I I R E M i :: ' U r THE NEW DISPLAY LIST ADDRESS INTO IT S REGISTERS 1 S P K i;;: 8 S 9 t P K li- S 9 s S C R E E N ! R E M T E I... I... THE OPERATING SYSTEM WHERE THE SCREEN BEGINS 190 POKE 55?:' 34; REM TURN ANTIC BACK ON 200 POKE 82 f 01 REM START AT THE EDGE OF THE SCREEN 2 1 ? " .)■ " 220 DIM A* (256) 230 F R X == :l. T 256 1 A $ ( X » X ) :::: H R $ ( X - 1 ) J N EXT X 240 F R Z = T 1 1 ! D I S P L A Y = ( S C R E E N+Z ) *2 56J FOR X=0 TO 255 I POKE DISPLAY IX 9 A SO ( A $(X+1»X+1 )) JNEXT XJNEXT Z 250 FOR Z-0 TO 235 J FOR X=l TO 12 J REM I... EAVE 20 CHARACTERS ON THE SCREEN - 12 LINES ON SCREEN 260 P K E D I... I S T + X >K 3 •!• 1 » Z i R E M P K E T H E I... E FT MARGIN INTO THE LOW ORDER SCREEN AD DRESS FOR EACH ROW 270 NEXT X JNEXT ZJRFM DO ENTIRE SCREEN 2 SO FOR Z-235 TO STEP -IJF'OR X~l TO 12J REM DO IT BACKWARDS 290 P K E D I... I S T + X* 3 i 1 9 1 i R E M P K E T H E I... E FT MARGIN INTO THE LOW ORDER SCREEN AD DRESS FOR EACH ROW 300 NEXT X J NEXT ZJREM DO ENTIRE SCREEN 310 GOTO 250 I REM KEEP DOING IT Line 40 turns off ANTIC. Since we are making major changes to the display list, it is a good idea to turn off ANTIC. Otherwise we could confuse or lock up the computer. 124 Line 50 finds the amount of memory available in the system and subtracts 12 from it. This will give us 12 pages or 3K of memory for the screen display. Line 60 subtracts 50 bytes from the beginning of the screen area. That should be enough for the display list. Lines 70 - 160 set up the new display list. Line 70 pokes in the values for the first three bytes of the display list. Lines 80 - 120 set up the main body of the display list. There will be 12 lines on the screen. Instead of poking in the value for that line of the display list, we need to do more. First, we will offset the value of X by multiplying it by 3. Three is used because there are 3 values that must be poked in for every line. The first value is 71; this is the same value that would normally be placed in a display list for mode 2. It means that the line is in mode 2. The next 2 bytes indicate the beginning of the screen display area. The next value to be poked in is a zero. Every line will begin on an even page of memory. The next value is the high order byte for the screen display area. The line number minus one is added to the value of screen. The jump instruction for ANTIC is poked into the end of the display list along with the two byte address for the beginning of the display list. Now ANTIC will know where to jump when it gets to the end of the display list. The new values for the location of the display list are placed in memory locations 560 and 561. ANTIC is turned back on and the left margin of the screen is changed to 0. Line 210 clears the screen. Line 220 sets aside 256 bytes for A$. This string will be displayed in every line on the screen. Line 230 places the character for every value from to 255 into A$. Line 240 calculates the beginning of the screen display area for the line by multiplying the value of SCREEN plus Z by 256. The ASC (AT ASCII) value of every character in A$ is poked into this memory area. Lines 250 - 270 change the value in the low order byte of the screen display area for every line. This makes the rows on the screen appear to move to the left. Lines 280 - 300 reverse the process. By subtracting one from the low order byte of every row displayed, the screen will shift to the right. FINE VERTICAL SCROLL The fine vertical scroll is achieved by moving the characters on a line up or down one pixel at a time. After the first line has been scrolled as far as possible, the scrolling to the next line is done the same way it was done in the course scroll program. Once again, the display list plays an important part in the fine scroll. The sixth bit of the byte that tells ANTIC what mode the line is must be set in order to scroll that line. An easier way is to XX XX XX XX XX XX XX XX XXXXXXX XX XX X X X X XXXXXXX XXXXXXX XX XX XX XXXXXXX XXXXXXX y y v y XX XX XX yy XXXXXXX XXXXXXX XX XX v y* y y XX XX XX XX XXXXXXX XXXXXXX XX XX XX XX XX XX XX XX XXX ;xxx y -/ v v ;xx XX XX XX XX XX XX XXXXXXX X X X ;xxx X X XX X X X X XX XX XXX XXXXXXX yy XX XX XX XXXXXXX XX XX v y XX XX XX XX XX XX XX i 2 3 A 5 6 7 Fig. 8-1. Scroll values. 125 add 32 to the mode. If the screen is mode 0, the display list has 2 for the mode. Change the 2 to 34 and that line can scroll vertically. Of course, the line will not scroll all by itself. The computer must be told when to scroll that line and how far to scroll it. 54277 is poked with a value from to 7. A zero holds the character in the position that it would be in if there was no scroll. A seven moves the character up seven pixels. It is almost in line with the correct position for the line just above it. Figure 8-1 shows the character position from to 7. The following program uses the fine scroll with the course scroll to move a message up on the screen. Listing 8-3. Fine Vertical Scroll 10 REM LISTING 8,3 20 REM FINE VERTICAL SCROLL. 30 REM BY L«H.8CHREIBER FOR TAB BOOKS 40 GRAPHICS 5 D I... I S T :::; P E E K ( 5 6 ) + P E E K<561)#256JREM G ET THE BEGINNING OF THE DISPLAY LIST 60 POKE DLIBT+3rl02 70 FOR X~<5 TO 28 1 POKE BLISTTX r 38 J NEXT A 80 POSITION 2s>8 170 ? "THIS SCROLLING" 180 ? "IS EASIER TO READ" 190 ? "THAN THE COARSE" 200 ? "METHOD. " 210 ? "YOU CAN MAKE" 220 ? "IT SCROLL FAST" 230 ? "OR SLOW WITH" 240 ? "A TIMING LOOP, " 290 S C R L U) - P E E K ( D I... I S T + 4 ) i S C R H I ■ P E E K < D I... IST+5) 3 F R X ■■■■■■ 1 T 8 ! S C R I... W = S C R I... W f 2 ? R E M ADD TO THE VALUE TO MOVE TWO LINES UP ON THE SCREEN 310 IF SCRL0W>256 THEN SCRL0W=SCRL0W~2 5 6 i S R H I ~ S C R H I i 1 t R E M G T T H E N E X T P A BE OF MESSAGE 320 LN-LN+10 3 30 FOP Z«0 TO 7 1 POKE 54277 rZ J FOR Y=l TO 251 NEXT Y I NEXT ZIPOKE 54277*0 340 POKE 559*0; POKE 54277 ? JP OKE BLIST ■f 4 » S C R I... W I P K E D I... I S T + 5 » S C R H 1 I P K E 5 5 9 ■, 34; REM DISPLAY NEW S GREEN 350 F R Y = 1 T 1 I N E XT Y J N E XT X J R E M S H OW ENTIRE MESSAGE 126 Line 40 resets the display list every time the program is run. Line 50 finds the beginning of the display list. Every byte that tells ANTIC the mode of the line must be changed. The 6th bit of the byte must be set to 1. Line 60 sets the top line of the screen for the scroll. This byte also tells ANTIC that the next two bytes are where the screen memory begins. Line 70 sets the rest of the bytes in the display list for the vertical scroll. Line 80 sets the position on the screen where the message will begin to be printed. Lines 170 - 240 print the message on the screen. The entire message will not be printed on the screen since this is graphics mode 2. The display list is as long as it would be in mode 0, so part of the message will be printed out of the screen area. Line 290 sets the variable SCRLOW to the low order address of the screen and SCRHI to the high order address of the screen. Lines 300 - 350 scroll the message on the screen. Line 300 begins the for . . . next loop. 20 is added to the value in SCRLOW because there are only 20 characters displayed in a line on the screen. If the value of SCRLOW exceeds 255, the value is reset by subtracting 255 from it, and 1 is added to the value of SCRHI. This will give ANTIC a new page to display on the screen. If SCRHI was not incremented, ANTIC would only display 1 page of screen memory over and over again. Line 330 begins the fine vertical scroll. A value from to 7 is poked in memory location 54277. After each poke, there is a timing loop. This will slow down the process of scrolling and make the text more readable. Once the lines are scrolled up as high as they can go, we shut off ANTIC, poke 54277 with to reset the scroll or put the line back to normal, and poke the display list with the new screen values. This is the course scroll. Because ANTIC is shut off, it will be a smooth scroll. ANTIC is turned back on and after another timing loop, the program continues with the original for.. ..next loop. When the entire message has scrolled up the screen, the program will end. Press the system reset key to return to the text mode. When you want a message or characters to move down on the screen, the process must be reversed. The characters must be brought down one line by the course scroll, scrolled all the way up to the top of that line, then slowly scrolled down on the screen. A downward scroll is not always as smooth as an upward scroll. Listing 8-4. Fine Vertical Scroll: Down 10 REM LISTING 8.4 20 REM FINE VERTICAL SCROLL - DOWN 30 REM BY L.M.SCHREIBER FOR TAB BOOKS 40 GRAPHICS S D L I S T = P E E K < 5 60 ) + P E E K < 5 6 1 ) #256 J R E M G ET THE BEGINNING OF THE DISPLAY LIST 6 POKE DLIST+3»102 70 FOR X=6 TO 28 J POKE DLISTLX r 38 J NEXT 80 POSITION 2»8 9 O S C R I... W "-• 24 4 I S C R H I = P E E K ( D I... I S T +5 ) J P O K E DL I STL4v SCRLOW 127 ?LOW»SCRLOW~20tREM 1 LINES DOWN ON THE Listing 8-4. Fine Vertical Scroll: Down (continued from page 127) 170 ? "THIS SCROLLING" 180 ? "IS EASIER TO READ" 190 ? "THAN THE COARSE" 200 ? "METHOD, " 210 ? "YOU CAN MAKE" 220 ? "IT SCROLL EAST" 230 ? "OR SLOW WITH" 240 ? "A TIM I NO LOOP, " 300 FOR X»l TO 8JSCR SUBTRACT TO MOOE TWO SCREEN 330 POKE 559 *G J POKE DLIST'i4 v SCRLOW : POK E D L I S T + 5 y S C R hi I I P K E 559 » 3 4 1 R E M H I S P I... A Y NEW SCREEN 340 FOR Z~7 TO STEP -1 1 POKE 5427/vZS FOR Y~l TO 20 J NEXT Y I NEXT Z 350 F E Y -- 1 T 2 i N E X T Y I N E XT X ; R E M S H OW ENTIRE MESSAGE Line 40 resets the graphics to mode 0. This restores the display list to its original contents. Line 50 finds the beginning of the display list. Line 60 sets the fourth byte of the display list for the vertical scroll and graphics mode 1. Line 70 sets the rest of the lines in the display list for graphics mode 1 with the bit set for the vertical scroll. Line 80 begins printing the message on this line. Line 90 sets the variable SCRLOW to 244. This figure was calculated by printing the value of SCRLOW at the end of the last program. The variable SCRHI should remain the same value as the high byte address in the display list. Change the display list low order byte for the screen address. Lines 170 - 240 print the message on the screen. This time the entire message will be visible on the screen. Lines 300 - 350 scroll the message down on the screen. This time 20 is subtracted from the beginning of the screen memory. By subtracting 20, ANTIC starts to display the screen area 20 bytes before the point where the message begins. This pushes the message down one line on the screen. Line 330 shuts off ANTIC while the new screen memory values are poked into the display list. ANTIC is turned on and the screen displays the message one line lower. By poking memory location 54277 with 7 to 0, we start the scroll with the lines scrolled up as high as possible. They are then slowly lowered on the screen. The timing loops keep the scrolling smooth. Every time the line is in the correct position, ANTIC is shut off, and the line is moved down one with a course scroll, but it is immediately scrolled up after ANTIC is turned on. A scroll down is not always as smooth as a scroll up. PLAYFIELD WIDTHS The width of the playfield is the number of columns that you can place information in. Up until 128 now, no matter which mode we worked in, the width of the screen was always the same - 40 columns or 320 pixels. The width of the playfield does not have to remain constant. There are three different playfield widths that you can choose from. Try this in the direct mode: POKE 559,33 Look at the screen! It is much smaller now. It is only 32 columns, or 256 pixels wide. Everything that is on the screen looks like it is in the wrong place. ANTIC doesn't look to see how wide the screen is. It will still try to put 40 characters in a line. If the line is too short, it will put the rest in the next line. Now try this - POKE 559,35 There is no margin on the left and right sides of the screen. Again, the information on the screen is not in the right place. This is the wide playfield. It is 48 characters or 384 pixels wide. The screen information will not be in the right place, because the information appears on the screen sequentially. If the line is longer than 40 characters, the information from the next line is placed on this line. To get back to the normal width, poke 559,34 or press the system reset key. These playfields can be used to create special effects. The wide playfield is used with the fine horizontal scroll. FINE HORIZONTAL SCROLL The fine horizontal scroll is very similar to the fine vertical scroll. Every character in the line that is to be scrolled is moved to the right approximately 2 pixels. Clear the screen and try this in the direct mode: X = PEEK(560) + PEEK(561) * 256 + 7:POKE X,18 This sets one line of the display list for the horizontal scroll. When you press the return key, the 'X— will move to the left and seem to disappear off the screen. READY will appear under the 8 and the left margin will seem to be on the right side of the screen. Now enter this: FOR Y=0 TO 15:POKE 54276,Y:NEXT Y The third line moves to the right and the entire line can be read. If you reverse the command: FOR Y=1 5 TO STEP - 1 POKE 54276,Y:NEXT Y the line will move back to the left. The rest of the screen is offset because this line is 8 characters or bytes longer than the other lines on the screen. READY is on the next line because the first 8 bytes of the fifth line are now on the fourth line. Every line after that is offset by 8 bytes. If enough lines are set for the horizontal scroll, the offset will work itself back to the left margin. The next two programs are variations on a ticker tape routine. The first program performs the horizontal scroll using the same technique as was used with the vertical scroll. Notice that in addition to scrolling to the left, the message is also scrolling up the screen! Press the system reset key before the message goes too far. The second program shows a solution to this program. Listing 8-5. Fine Horizontal Scroll 10 REM LISTING 8.5 20 REM FINE HORIZONTAL SCROLL 30 REM BY L*M»SCHREIBER FOR TAB BOOKS 40 DIM A$(48) 5 P. A P H I C S t P K E S 2 > O 5 P K E 7 52 1 1 % REM SET LEFT MARGIN 129 Listing 8-5. Fine Horizontal Scroll (continued from page 129) 6 D L I S ' I ■ ■ P E E K < 5 6 ) + P E E K ( 5 6 1 ) * 25 6 1 8 C R i... U ■ P E E K ( D L I S T + 4 ) J S C R H I = P E E K ( D L I S T + 5 ) J R E M DISPLAY LIST AND SCREEN MEMORY 7 P K E D I... I S T + 1 * P E E K ( D I... I S ' I ' + 1 ) + 1 6 i R E M SET IT UP FOR HORIZONTAL SCROLL. 80 A*™ STAY TUNE EOR AN IMPORTANT MESS AGE ON COMPUTERS " 9 P K E 5 4 2 7 6 •> 1 5 J R E M S E T S C R i... I... T T H E RIGHT 100 POSITION 0»5I? A$ 110 EOR X™15 TO STEP -II POKE 54276 s-X J FOR Y=l TO 40 : NEXT Y I NEXT XI REM SCROL L TO THE LEFT 1 2 S C R I... W ~ S C R I... U +4 J I F S C R I... W > 255 T H E N S C R H I :::: S C R ii I f 1 I S C R I... W = S C R I... W - 255 1 3 P K E D L I S T + 4 » S C R I... W I P K E D I... I S T i 5 » S CRN I 140 EOR Y~l TO 10 1 NEXT Y I GOTO 1:1.0 Line 40 sets aside 48 bytes for the message. This is the number of characters that will fit on one line when the screen is set for the wide playfield. Line 50 clears the screen, sets the left margin to 0, and removes the cursor from the screen. If we did not set the left margin to 0, the computer would leave two bytes blank on the screen in the line that the message is printed in. These two bytes are where the left margin is for a normal playfield width. Line 60 finds the beginning of the display list and places the screen memory address in variables SCRLOW and SCRHI. Line 70 sets the sixth row of the screen for the fine horizontal scroll. The fine horizontal scroll is set by adding 16 to the value in the display list. Line 80 places the message into A$. Be sure to add the space after the last word, computers. Line 90 pokes 15 into memory location 54276. This will scroll the line all the way to the right. Line 100 prints the message on the sixth line of the screen. (The first line is 0.) Line 110 begins the horizontal scroll. The for... next loop decreases from 15 to 0, moving the message from the right to the left. Line 120 adds 4 to the low byte of the screen memory area. Scrolling from 15 to moves 4 characters off the screen. Line 130 pokes the new values into the display list and completes the scroll. Notice that the message spirals on the screen. Four characters at a time appear on the line above the scrolling line. This line is not set to scroll, so the characters stay there until the next course scroll. We are moving the screen display area, so even though we are moving the characters across on the line, we are also moving them up in the screen memory. The next program tries to correct this situation. When the words are scrolled to the left, the letters are removed and placed at the end of the line. The screen is still spiralling up the display, 130 but because the letters are constantly being removed from the beginning of the line and added to the end, it gives the illusion of remaining on the same line. Listing 8-5A. Fine Horizontal Scroll— Second Method 10 REM LISTING 8, 5 A 20 REM FINE HORIZONTAL SCROLL 30 REM BY L,M,SCHREIBER FOR TAB BOOKS 4 D I i'-i A $ (48) 5 R A i :: ' H I C S I P K E 8 2 v 1 P K E 7 5 2 i 1 I R E M SET LEFT MARGIN 6 D i... I S T ~ P E E K ( 560 ) + P E E K ( 5 6 :l. ) * 2 5 6 J S C R I... W ■■■■■■■ P E E K ( D I... I S T + 4 ) I S C R H I "-• P E E K ( D I... I S T + 5 ) 7 P K E D I... I S T •{• :l. t P F E K ( D I... I S T + 1 ) + 1 6 X R E M SET' IT UP FOR HORIZONTAL SCROLL 80 A$~"STAY TUNE FOR AN IMPORTANT MESS AGE GN COMPUTERS " 9 P K E 54276? :l. 5 J ! ;: ' S 1 T 1 N v 5 1 ? A $ :l. L I N F 5 <* S C R IT 1*25 6 f S C R !... U ■!• 199 1 R E M F 1 R ST BYTE OF THE FIFTH LINE 1 :l. P K E I... I N E S + 4 7 > P E E K ( I... I NE5 > I F' K E I... I N E5»0tLINE5™LINE5+l 1 2 S C R I... W ■■■■■■■■ S C E L U f 1 \ I F 'S C R i... W > 255 T 1-1 E N S C R !... U ::; S C ! : ;: I... U ■- 2 5 5 J S C R IT I * S C R H I ■{■ 1 130 FOR X=15 TO 12 STEP -II POKE 54276^ X I F R Y ~ 1 T 3 i N E X T Y I N E X T X 1 4 i ;; ' K E 5 59^0; P K E D L I S T + 4 » S C R I... W ? i :: ' K il D i... I S T + 5 > S C R IT I ; P K E 559»34»G0T 1 :l. PLAYER/MISSILE GRAPHICS Many applications for using horizontal and vertical scrolling come to mind when you consider adding player/missile graphics. A map of the United States or the world could be drawn on the screen. To keep it at a reasonable size, you would not have to fit the entire map on the screen. A player could be used as a cursor. Moving the joystick would move the cursor up, down, left, or right on the map. When the red button on the joystick is pressed, the screen would scroll in the direction indicated by the joystick, exposing other parts of the map. 131 Chapter 9 Page Flipping In the display list there are two bytes set aside to tell ANTIC where the beginning of the screen memory is. If we were to change these bytes, we would get some strange displays on the screen. It could be garbage, or it could be a clear screen. It all depends on what is in the memory area that ANTIC is trying to display. Try this in the direct mode: DLIST=PEEK(560)+PEEK(561)*256:POKE DLIST+5,6 What do you see on your screen? This is the area of memory that we usually store machine language subroutines in because the operating system doesn't use it. DISPLAYING TWO SCREENS By adjusting the memory that will be used by the screen, we can set aside memory for more than one screen display. We can then flip back and forth between the two screens. The new picture or message will immediately appear on the screen. If speed is critical, or you do not want the user to see the image being drawn, screen flipping is the answer. It does, however, use up a lot of memory. In the text mode, figure another IK of memory for each additional screen that you want displayed. If you are using a high resolution graphics mode, the memory cost is even more! The following program shows two messages that are displayed on two different screens. Listing 9-1. Screen Flipping 10 REM LISTING 9 . .1. 20 REM SIMPLE PAGE FLIPPING 30 REM BY L,M,SCHREIBER FOR TAB BOOKS 4 G R A P l-l I C S t P K E 7 5 2 * 1 X ? " > C I... E A R > " 5 B L L 1 ■■■■■■■■ P E P. K ( 56 ) J B I... H :l. = P E E K < 5 6 1 ) J D I... 1 = B I... I... .1. + D I... 1-1 1*256? S C R 1 ^ P P. P. K ( D I... 1 f 4 ) i S C R 2 = P E E K ( D I... 1 + 5 ) I S C R ~ S C R 1 + S C R 2 * 2 5 6 6 i :: ' K E 1 6 f P P. P. K ( 1 6 ) - 4 % R E M MOO E S C R E E N UP IK 70 GRAPHICS OS REM RESET THE B I SPLAY LI 133 Listing 9-1. Screen Flipping (continued from page 133) ST 8 D I - 1. . 2 = P E E K < 560 > t D I... H 2 ~ P E E K ( 5 6 1 ) { D L 2 - D I... L 2 + D L l-l 2 * 2 5 6 5 S C 1 » P E E K ( D I... 2 + 4 > J S C 2 ■ P E E K < DL2+5) $SC~8C1+SC2#256 9 P D K E 752 9 1 J ? " T H 1 S M E 3 S A (■) E I S N P A 6 E 2 " I ? " W l-l 1 1... E Y U A R E R E A D I N (3 I T " I ? "I'M WRITING ON SCREEN 2" I P K E 8 8 r S C R 1 1 P K E 8 9 * S C R 2 5 R E M L E T THE COMPUTER WRITE ON THE OTHER SCREEN 110 ? " GOOD WORD!"* REM 2 ESC- DO WN ARROWS ■- FIVE SPACES 120 POKE 88 » SCI i POKE 89s-SC2JC=0J? " I'm ready rrvss any ke«!"tREM 2 DOWN ARROWS ■- 3 SPACE 130 IF PEEK=255 THEN 130 140 POKE 764* 2 55 l REM CLEAR THE REGISTE R 1 5 P K E D I... 2 + 4 » S C R 1 5 P K E D I... 2 + 5 » S C R 2 t R E M SHOW SCREEN 1 .1.60 FOR Y"-"l TO 200 J NEXT YJREM TIMING I... OCR 165 ? " :>■ C I... E A R y " 1 1 F C T H E N 1 8 1 7 ? " T h i s w a s p r :i. n ted w h i 1 e a o u w e r e wa t c h i n a t h e o t h s r 1 s c r e e n » " ?C™1JREM 4 DOWN ARROWS 1 '! ! "pre s s a n u k e y " ! R E M D W N A R R W I TAB 1 9 P K E D I... 2 •!• 4 » S C 1 I P K E D I... 2+5 » S C 2 J R E M RESET THE SCREEN 200 00 TO 130 Line 40 sets the graphics mode to 0. This line also removes the cursor and clears the screen. This will be considered page 1. It is ready for something to be written on it. Line 50 finds the beginning of the display list. The location of the screen memory is stored in the fifth and sixth bytes of the display list. These values are stored in the variables SCI and SC2. The first byte of the screen is stored in the variable SCR. Line 60 subtracts 4 from the value in memory location 106. This memory location tells the computer how much memory (RAM) is available for it to use. It will count backwards from this location when setting aside screen space and the display list. By poking 4 less than the total number of pages of memory available, we are saving IK of memory of the screen and display list that we just initialized. Line 70 resets the display list and screen. Because we changed the amount of memory that the computer thinks it has, the first display list and screen display memory is intact. The screen memory and display list that the computer set in this line are lower in memory than those 134 established for the preceding screen. We now have two display lists and screen memories in the computer's RAM. Line 80 calculates the new display list and the location of the new screen memory. This is the second display list and screen in RAM. Line 90 removes the cursor and prints a message on the screen. This message appears on the screen that you are looking at. Line 100 pokes the memory location of the first screen into memory locations 88 and 89. This is where the computer looks to see where the screen display area is. If we change these bytes to the location on the first screen, the computer will print or draw in that memory area. This will not affect the display that we are looking at. Line 110 is the message that the computer will print on the screen. This message will not appear on the screen that we are looking at because locations 88 and 89 have been changed. Line 120 sets the variable C to 0. C is used as a flag in this program. When it is 0, a second message will be printed on the second screen. When it is 1, the message will not be printed. The message between the quotes will be printed after C is set to 0. Before printing any message, memory locations 88 and 89 must be changed. If they were not changed back to the screen memory of the screen that we are looking at, 'we would not see this message. Line 130 checks memory location 764. When its value is not 255, a key has been pressed. The program will loop here until a key is pressed. Line 140 clears memory location 764 by resetting it to 255. If this location was not reset when the program looped back to line 130, it would think that a key had been pressed whether one was or not. Line 150 pokes the values for the first screen memory into the display list. Now the message that was poked into that memory area will be displayed on the screen. Line 160 is a timing loop to give you a chance to read the message. Line 165 clears this screen. This will not clear the screen that you are looking at! This will clear screen 2. If C is set, the program will go on to line 180. Line 170 prints a message on the screen and sets C to 1. This message is not printed on the screen that you are looking at, but at the other screen. Line 180 prints the rest of the message. Line 190 resets the screen by poking the screen memory area for the second screen into the display list. Line 200 sends the computer back to line 130 to repeat the program. To end the program press the system reset key. This will reset the display list and all the registers. If you press the break key, you will only stop the program but not reset any of the registers. This method of screen flipping can be used with other modes as well. In the next program, the screen will flip between mode and mode 1. Listing 9-2. Simple Page Flipping: Two Different Modes 10 REM LISTING 9,2 20 REM SIMPLE PAGE E LIPPING - TWO DIFE ERE NT MODES 3 O R EM BY I... .M.S C H R E I B E R F O R TAB B O O |< S 40 GRAPHICS 1? 135 Listing 9-2. Simple Page Flipping: Two Different Modes (continued from page 135) 5 D I... I... :l. = P E E K ( 5 60 ) ♦ D L H 1 ■■■■■■ P E E K < 5 6 1 ) « D I... :l. ~ D I... I... :l. + D I... H 1*256} S C R 1 ~ P E E K ( D I... :l. +4 ) J S C R 2 ~ P E E K ( D I... :l. +5 ) J S C R * S C R :l. + S C R2*25 6 6 P K E :l. 6 t P E E K < 1 6 ) •••• 4 I R E M M E S C R E E N UP IK 70 GRAPHICS 01 REM RESET THE DISPLAY LI ST 8 D I... 1... 2 ■ P E E K ( 560 ) J D I... H 2 ■ P E E K ( 5 6 1 ) I D I... 2 ■ D L L 2 + D I... H 2*25 6 J SC :l. ~ P E E K ( D I... 2 + 4 > i S C 2 ■ P E E K ( DL2+5) JSC«8C1+8C2*256 9 P K E 752 r 1 J ? " T H I S M E S S A G E I S N PAGE 2"i? "WHILE YOU ARE READING IT" J? "I'M WRITING ON SCREEN 1" 1. P K E 8 8 ? S C R I } P K E 8 9 » S C R 2 J P K E 8 7 ? .10 ? #61 "GOOD WORK" 1 2 P K E S 8 v S C 1 I P K E 8 9 * SB C 2 t P K E 8 7 r 1 C~OJ? " I'm ready press any key!" 130 IF PEEK (764) -255 THEN 130 140 POKE 76 4-1 255; REM CLEAR THE REGISTE R :l. 5 P K E 560. D I... I... 1 J P K E 561? D I... H 1 J R E M S H OW SCREEN 2 160 EOR Y=l TO 200? NEXT YrREM TIMING I..7 OOP 1 6 5 ? " > C I... E A R }• " i I F C T I i E N 1 8 :l. 7 'i 1 " T h J. s w s i:; p r i n ted w h i I e y o u were watching the other screen*" JC=1 180 ? "press ana key" :l. 9 P K E 560. D I... I... 2 I P K E 5 6 1 t D L H 2 J R E M R E SET THE SCREEN 200 GOTO 130 Line 40 sets the display list for mode 1 without the text window. The rest of the listing is identical to the previous one with one exception. Line 150 changes the display list that the computer is using for the second screen to the display list for the first screen. Line 190 resets the display list for the second screen. By changing memory locations 560 and 561 for the different display lists, you can flip between screens that are in different modes. What if you want to display two screens simultaneously? It can be done. But with all the capabilities of the ATARI with one screen display, is there really a need to display two screens at 136 once? The next four programs illustrate different approaches that can be taken to display two screens at the same time. In all cases, there will be some flickering. Listing 9-3. Simultaneous Page Flipping— in BASIC 10 REM LISTING 9*3 20 REM SIMULTANEOUS PAGE FLIPPING 30 REM BY L»M.SCHREIBER FOR TAB BOOKS 4 G R A i :: ' H I C S i P K E 7 52 » 1 i ? " > C I... E A R > " 5 L I... :l. ■■■■■■■■ P E E K < 56 O > J D I... 1-1 :!. ~ P E E K < 5 6 1 ) i D L. 1 = D I... I... 1 + D I... H 1*2561 S C R 1 = P E E K < D I... 1 + 4 ) I S C R 2 » P E E K ( D I... 1 f 5 ) ? S C R ~ S C R 1 + S R 2* 256 6 POKE: 1 06 v PEEK H. 06) ■■■•4 J REM MOVE SCREE N UP IK 70 GRAPHICS 01 REM SET THE DISPLAY LIST TO ANOTHER MODE 8 D I... I... 2 = P E E K ( 56 ) I » I... H 2 » p E E K < 56 1) J D I... 2 = D I... L 2 + D I... H 2 * 2 5 6 J S C 1 ™ P E E K ( D L 2+ 4 ) J S C 2 = F : ' E E K ( DL2+5) JSC~SC1+SC2#256 90 POKE 752 f II POSIT I ON 2 » 9 ;? "THIS CAN CREATE" 1 P K E 8 B 9 S C R 1 I P K E 8 9 » S C R 2 1 1 ? " i: N T E R E S 7 I N G E F F E C T S " ! R E M 2 - E S ■- D W N A R R U S t 2 ■■■■ E S C ■•- T A B S 1 2 P K E D I... 2 + 4 * S C R 1 I P K E D I... 2 + 3 s> S C R 2 J P K E D I... 2 i 4 t S C 1 J P K E D L 2+5 t S C 2 \ G T 1 2 Listing 9-4. Simultaneous Page Flipping— Two Modes 10 REM LISTING 9,4 20 REM SIMULTANEOUS PAGE PL I PP I NO 30 REM BY L.M.SCHREIBER POP TAB BOOKS 4 GRAPHICS 17 3 D I... I... :l. :;:: P E E K ( 56 ) X D I... H 1 ^ P E E K ( 56 1 ) J D I... 1 ::;: B I... I... 1 + D I... I -1 1 #25 6 % S C R 1 ■■■■■■■ P E E K ( D I... 1 + 4 ) I S C R 2 ~ P E E K ( D I... 1 +5)3 S C R = S C R 1 1 S C R 2 # 2 3 6 6 P K E 1 6 v P E E K ( 1 6 ) - 4 { R E M MOO E S C R E E N UP IK 70 GRAPHICS 18 J REM SET THE DISPLAY LIS T TO ANOTHER MODE 8 D I... I... 2 - P E E K ( 5 6 > 5 D L H 2 ~ P E E K < 3 6 1 ) 5 B L 2 ~ D I... I... 2 f D I... H 2*256 J SC 1 = P E E K ( D I... 2+4 ) J S C 2 = P E E K ( DI...2 + 3) SSC=SC1+SC2#256 90 POSITION 2v3t? #6? "THIS CAN CREATE" 1 P K E S 8 y S C R 1 \ P K E 8 9 > S C R 2 J P OKE 87? :l. 1 1 ? # 6 5 " I N T E R E S T I N G E F F E C T S " 137 Listing 9-4. Simultaneous Page Flipping— Two Modes (continued from page 137) 130 IF PEEK (764) --255 THEN 130 1 4 P K E 560. D L I... 1 i P K E 5 6 1 . D L H 1 160 POKE 560. DLL 2: POKE 561 »DLH2t GOTO 1 3 Listing 9-5. Simultaneous Page Flipping: Machine Language Subroutine 10 REM LISTING 9,5 20 REM SIMULTANEOUS PAGE FLIPPING -•■ MA CHINE LANGUAGE SUBROUTINE 30 REM BY L.M»SCHRE1BER FOR TAB BOOKS 4 G R A P l-l I G S J P K E 752 r 1 1 ? " >'C I... I!!: A R > " 5 D I... I... 1 = P E E K < 56 ) I D L l-l 1 ^ P E E K < 5 6 1 ) t D I... 1 :::: D I... I... 1 1 D I... H 1*256: S G R 1 ■■■■■ P E E K ( D I... 1 + 4 5 5 S C R 2 ™ P E Ii: K ( D I... 1 i 5 ) 1 S C R - S C R 1 + S G R 2 * 2 5 6 6 P K E 1 6 y P E E K < 1 6 ) •••• 4 I R E M MOO E S G R E E N UP IK 70 GRAPH I OS OS REM SET THE DISPLAY LIST TO ANOTHER MODE 3 D I... I... 2 = P E E K ( 5 6 ) J D I... l-l 2 ~ P E E K < 5 6 1 ) 5 D I... 2 ~ D I... L 2 -f D I... l-l 2 * 2 5 6 I S G 1 * P E E K ( D I... 2+4)1 S C 2 = P E E K ( DL2+5) :SC~SCl-fSC2*256 9 P K E 752.12 P S I T I ON 2.92? " ' I ' H I S G A N ORE ATE" 1 I-' K E S 8 . S G R 1 I P K E 8 9 . S C R 2 1 1 ? " I N T E R E S T I N G E F F E G T S " 1 2 P K E 203. S G R 1 ? P K E 204. S G R 2 ! P K E 2 5 . S G 1 t P K E 2 6 . S C 2 l R E M A D D R E S S F B T H SCREENS 1 3 P K E 2 8 . D I... H 2 1 P K E 207. D I... I... 2+41 R E M WHERE SCREEN ADDRESS IS STORED 140 EOR X~0 TO 30 1 READ C SPOKE 1536-fX.C J NEXT X 150 DATA 104.160.0.165.203.145.207.200 . 165.204. 145.207. 136. 165. 205. 145.207.2 00. 165.206. 145.207. 136.173.252.2 160 DATA 201.255.240.229.96 170 Q^USRCI.536) Listing 9-5A. Simultaneous Page Flipping: Machine Language Subroutine— Horizontal Blank 10 REM LISTING 9, 5 A 20 REM SIMULTANEOUS PAGE FLIPPING - MA 138 C H I N E I... A N G U A G E S U B R fJ U T I N E 30 REM BY LtM»8CHREIBER FOR TAB BOOKS 4 (3 R A P H :i: C S : P K E 752 9 1 1 ? " > " 5 D L. !... 1 : ~ P E E K ( 5 6 ) I'D I... H 1 -= P E E K ( S 6 1 ) J D L 1 » D I... I... :l. 1 D I... H 1*2561 S C R :!. ■■■■■■■■ P E E K ( D I... :!. i 4 ) I S R 2 = P E E K ( D I... :l. + 5 ) i S C R :::: S C R :l. -f S R 2*256 6 P K E 1 6 ? P E E K ( 1 6 ) ■•■• 4 ! R E M M V E S C R E E N UP IK 70 GRAPHICS OJREM SET THE DISPLAY LIST TO ANOTHER MODE 8 D i... I... 2 ~ P E E K ( 5 6 ) i D I... H 2 ™ P E E K < 5 6 1 ) i D L 2 ~ D I... I... 2 + D I... H 2 # 2 56 S SC :l. ™ P E E K ( D I... 2 + 4 ) I S C 2 ■■■■■ P I!: E K ( D I... 2 + 5 ) J S = S C 1 -f S 02*256 9 P K E 7 52 j 1 I P S I T I ON 2 :> 5 S ? " T H I S C A N ORE ATE" :l. i ;: ' K E 8 8 ■> S R 1 I P K E 8 9 v S C R 2 110 ? "INTERESTING EFFECTS" 120 POKE 206i»SC2!REM ADDRESS OF ONE SO REEN :l. 3 F E X :::: T 1 9 J R E A D C I P K E 1536 + X ■> C 5 NEXT X 140 POKE 1 553 ?DLH2? POKE 1552»DLL2+5JP0 KE 209 j At REM WHERE SCREEN ADDRESS IS S TOR EH I ')'■> DO t A 72 « I 6 J » 4 « 69 ; 209 » i- i?3 \' 209 =• 1,65 :- : 2 06 9 24 9 1 1 v 2 9 a 1 4 1 ? 1 » 2 J. 2 v 1 4 1 » > > 1 4 v 6 A 170 POKE DL2+28i 130 1 8 ! :: ' K li: 5 1 2 1 J P K E 5 1 3 1 6 1 P K E 54 28 6 » :l. 190 GOTO 190 These four listings are nearly identical. Line 40 sets the mode to (except in listing 9-4 where it is set to 17, which is mode 1 without a text window), removes the cursor, and clears the screen. The display list is now set for the first screen. Line 50 finds the beginning of the display list, and the location of the screen memory for this mode. These values will be used later in the program. Line 60 moves the end of RAM IK. This protects the display list when we reset the graphics mode. Line 70 sets a new display list by setting the graphics mode. This new display list will be located before the old one. The screen display area for this mode will also be located before the other screen. The other display list is protected because 106 was poked with a number that was IK less than the actual amount of memory in the system. Line 80 finds the new display list and the screen memory locations for the second screen. 139 Table 9-1. Machine Language Subroutine to Flip Screen. ■J e c i iti a .1. c o d e a s s e in b 1 w 1 a n a u a a e 1 i s t :i. n s 104 PL A SPu'N a number from t ■ie st< fck. .1.60 1... Ll )' # i 1. . D :-.> d :i. I"i d e ;•; t w :i. t h > 165 1... Li h ,.■ 3 9 1... o a d 1. 1 1 h a c c u m u 1 a tor with the 2u3 value in location 203 145 8 f A C 20 7 ) » Y > c 3 1 o r e :i. t :i. ri m s m o r y .ocat: . O 1 1 207 207 plus the value of i nde: ^ i '.- 200 I NY i Increment index Y« 165 LDA 204 ? Load the accumulator with the 204 145 v a .1. u e i i"i 1 o c a t :i. o n 2 4 S I A i 20 7 ) » V ? ( ': t o r e :i. t i ri m e m o r u .ocat: n n 207 "207 plus the value of i nde; : Y . 136 I.i 1::. V '• I.i e c r l e m e i"i t :i. n d e ;■; r * 165 LDA 205 SLoad the accumulator w :i. t h the 205 value in location 205 Line 90 prints a message on the screen that we are looking at. Line 100 sets locations 88 and 89 for the first screen memory. In listing 9-4, location 87 is set for mode 1. This will place the message in the correct position on the screen. Line 110 prints the message on the screen. This message will appear on the first screen, not the screen that we are looking at. Line 120 is a loop in listing 9-3. The screen memory location in the display list is constantly changed between the first and second screen. Although both messages appear on the screen, there is noticeable flickering. In listing 9-4, line 130 waits for a key to be pressed. Each time one is pressed, the address of the display list is changed back and forth between the first display list and the second. This program flips the screens by changing the entire display lists because they are in two different modes. Listing 9-5 uses a machine language subroutine to flip the screens. See Table 9-1 for the assembly language listing of this subroutine. Once the machine language subroutine is poked into memory, the computer uses a USR command to access it. The screen will continue to flip until a key is pressed. There is less flickering with this method than the previous one, but it is still 140 145 ST A ( 207 ) v Y » S t o r e i t :i. n in e in o r y I a c a t i o n 207 207 p 1 u s 1 h v a 1 u c o f i n d ok Y . 200 I NY v I ii c r e hi e n t :i. n d e ;■; Y * 165 LDA 206 5 1... o a d t h e a r r > i m u 1 a t or w :i. t h t h e 206 value in location 206 • 145 ST A (207) y Y > S t o p e :i. t :i. n iri e iri o p y 1 o c; a t :i. a n 207 207 p 1 u ;;; t h e v a 1 u a f :i. n d e x Y . 136 DEY 5 D & c P E in e n t :i. n d h ;■; Y < 173 LDA 764 y|...oad the accumulator with the 253 value from location 764 2 201 CMP #255 jSbb if a key was pressed. 240 BEQ ■■} ■;:> <;> » B r ;;; n c h :i. f n o k e w w a ;:; pre s s e d 229 b a c k w a r d s 27 b ■:< t e ;;; • 96 H 1 S S Return to BASIC if key was pre s sed. noticeable. Lines 120 and 130 poke the addresses of both screens and the address of the display list where the screen memory should be placed— in memory locations that are not used by BASIC or the operating system. Listing 9-5A uses a display list interrupt to change the screens. Table 9-2 shows the assembly language listing for this routine. By using a display list interrupt, the screen is flipped every time ANTIC comes to that line in the display list. This method causes the least amount of flickering. Listing 9-5B. Simultaneous Page Flipping: Machine Language Subroutine— Vertical Blank 10 REM LISTING 9. SB 20 REM SI MUL TAN EC) US PAGE FLIPPING - HA CHINE LANGUAGE SUBROUTINE 30 REM BY L.M*SCHREIBER EUR TAB BOOKS 4 R A P H I C S I P K E 752 1 1 i ? " > " 5 D L I... :l. ~ P E E K ( 5 6 ) SB I... 1-1 :l. - P E E K < 56 1 ) J B I... 1 :::: D I... I... 1 + D L H I * 2 5 6 % S C R 1 ! = P E E K < B I... ;|. f 4 ) I S C R 2 ~ P E E 141 Listing 9-5B. Simultaneous Page Flipping: Machine Language Subroutine— Vertical Blank (con- tinued from page 141) K ( D I... 1 + 5 ) t 8 C R ■■■■■ S C R :l. + S C R 2 #25 6 6 P K E 1 6 ? P E E K ( :l. 6 ) - 4 I R E M MOV E S C R E E N UP :I.K 70 GRAPHICS Of REM BET THE DISPLAY LIST TO ANOTHER MODE 8 D I... L 2 ■■■■■■ P E E K ( 5 6 ) J D I... H 2 « P E E K ( 5 6 1 ) X D I... 2 « D I... I... 2 i D L H 2* 256 % S C :l. = P E E K ( D I... 2 +4 > J S C 2 - P E E K ( D I... 2+ 5 ) i S C ■■■■■■■■ S C 1 f S 02*256 9 P K E 7 52 1 1 1 P S I T I ON 2 1 5 J ? " T H I S C A N CREATE" 1 P K E 8 8 v S C R 1 I P K E 8 9 1 S C R 2 110 ? "INTERESTING EFFECTS" 120 POKE 206»8C2JREM ADDRESS OF ONE SO REEN 130 EOF;: X™0 TO 21 J READ C t POKE 1536+X*C I NEXT X 140 POKE 1553»DLH2JP0KE 1552yDLL2+5JP0 KE 209 9 4 J REM WHERE SCREEN ADDRESS IS S TOR ED 150 DATA 72 » 169? 4 i 6? v 209 a 133 » 209 t 165 i> 2 06» 24 1 1 1 v 209 ? 1 4 1 t 1 p 2 1 2» 141 » »0» 1 04 y 7 6 1 95 » 22S 160 F R X - 1 560 T 1 5711 R E A D C ! P K E X ? C J NEXT X 170 DATA 1 04 v 104? 104 k 168j 104? 104? 170? 1 04? 104? 76? 92? 228 1 8 Q : - : U S R ( 1 5 6 ? ? 6 ? 6 ) 190 GOTO 190 Listing 9-5B uses a slightly different method of screen flipping. The machine language subroutine is accessed on the vertical blank. Every 60th of a second, the raster scan reaches the bottom right corner of the screen. When it shuts itself off to go back to the top-left corner, there is a vertical blank. By flipping the screen at this time, each screen is displayed for l/60th of a second 30 times in one second. Theoretically, you should not see any flickering here because the eye detects movement at l/20th of a second. This is the most reliable way to display two screens at the same time. The machine language subroutine used here is executed during the vertical blank. The computer has certain routines that it must perform during this period. There is time, though, to insert your own code for the computer to execute in addition to its own. The trick is to steal the vector or address location for your own use. In this program we are using the immediate vertical blank vector for our routine. Any time that a machine language subroutine is executed during an immediate vertical blank, it should end with a jump to 58463. A machine language subroutine can also be used during the deferred vertical blank. This routine should end with a jump to 58466. These addresses contain the routines that the computer needs to perform during the vertical 142 Table 9-2. Machine Language Subroutine— Horizontal Blank. decimal code a s s e iti b 1 y lansfussie 1 i s t :L n s! 72 F'l-IA 5 P 'J S h t h e v 3 1 i..i e :i. n t h e a c r 1 1 m u .1. 3 1 o r a n t h e s I a c k . 3.69 LDA #4 PL 03d the accumulator with 4* 4 6? EOR 209 •Exclusive OR it with the 209 o o n t e ri t s o f 1 a c a t i o n 2 9 * 133 ST A 209 • Store? the result i n locati on 209 209* 165 LDA 206 P L o a d t h e a C c u m u 1 a t o r w i t h t h e 206 v a 1 u e i i"i 2 6 <■ 24 CI...C i Clear the carry. i o i ADC 209 5 A d d w i t h o a r r u t h e v a 1 u e i n 209 location 209, :l. 4 :l. STA 54281 i P Store it - wait for 1 /"! .1 ."J h o r :i. z o n t a 1 s w n c • .,'• 1, ». :l. 4 :l. ST A ? S t o r e :i. t i i"i 1 o c a t i o n « 104 PL A P G e t t h e v a 1 1 1 e b a c k f r o m t h e s t a c k . 64 H I .1. J Return from the interrupt. 143 blank. As the name implies, an immediate vertical blank routine is performed as soon as the blanking period begins. A deferred vertical blank is executed after other routines are completed. The routines that you want executed should be fast and to the point. There is a time limit for these routines. If they are too long they could cause problems with the display by changing registers while the scan is turned on. Routines performed during the immediate vertical blank should not exceed 300 machine cycles. Routines using the deferred vertical blank can be about 25,000 machine cycles. Remember, a machine language instruction is not a machine cycle long. Some instruction can use up to 7 machine cycles. The USR routine passes the address of the machine language subroutine that the vertical blank will use to another machine language subroutine. ATARI has a routine in its operating system to set up immediate and deferred vertical blank routines. To set the address for the routine, you must call a routine at location 58460. When this routine is called, the address of your machine language subroutine must be stored in the Y (low order address) and X (high order address). A 6 must be in the accumulator if it's an immediate vertical blank routine; a 7 if it's a deferred. The machine language subroutine at location 1560 accomplishes this. See Fig. 9-3 for the assembly language listings for these routines. CREATING SLIDES With some screen flipping and a disk drive, an entire presentation can be displayed. Slides, pictures, or graphs can be prepared ahead of time and stored on disk. Then, under program control, the slide could be loaded into the computer's memory. While one picture is on the screen, another could be loaded into another part of memory. By pressing a key, the computer would 'flip' to the other picture and load a new picture into the screen memory that is not being shown any longer. The following program will allow you to create slides that will be stored on disk. The program after it will retrieve those slides in any order than you want. Table 9-3. Machine Language Subroutine for Vertical Blank. 76 JMP 58463 ;Jump to this address to 95 computer's routines. 228 replace the return from interrupt with this jump to complete the vertical interrupt routines. decimal code assembly anguage instructions 104 PLA Get value from stack (?) 104 PLA Get value from stack (0) 104 PLA Get value from stack (0) 168 TAY Transfer it to index Y. 104 PLA Get value from stack. (0) 104 PLA Get value from stack. (6) 170 TAX Transfer it to index X. 104 PLA Get value from stack (0) 104 PLA Get value from stack (6) 76 JMP 58460 Jump to address to set up subroutine to run during 92 /ertical blank. 228 — change for machine language subroutine Boot routine to set up subroutine during vertical blank. 144 Listing 9-6. Slide Editor 2 REM SLIDE EDITOR 30 REM BY LfM.SCHREIBER FOR TAB BOOKS 32 FOR X-1536 TO 1 548 S READ B i POKE X?BJ NEXT XSUP-1536SEEM ROUTINE TO MO ME UP 34 DATA 1 04 ? 160 «() ? 200 ? 1 77 ? 205? 136 ? 145 ? 205 ? 200 » 208 y 247 ? 96 36 FOR X-1552 TO 1564 S READ BtPOKE X?BJ NEXT XSD0WN^1552SEEM ROUTINE TO MOVE D OWN 38 DATA 104* 160? 255? 136v 177 ? 205 ? 200 ? 14 5? 205? 136? 208? 247? 96 40 DIM NAME$( 14) ?N$(8) 50 NAME* (. 1 ) " " " J NAME* (12) ~ " " I NAME* < 2 ) ■■■■■■■ NAM E * t H A ME $ » " D J " ! R E M C L E A R T H E 8 T R I N 60 'I 1 ">CL£AR> PLEASE ENTER THE NAME F T H E P I C T U R E " 5 I N P U T N $ 5 N A M E * ( 3 > =N$ i N A M E * ( 1 :l. ? 1 4 ) ■■:■■■■ " . D R W " S I F N * * " " T H E N 5 7 (3 R A P I -I I C S 2 1 S R E M S E T D I S P I... AY F R G R A PHICS MODE 5 ■■■■ NO TEXT WINDOW 8 P M ~ P E E K ( 1 6 ) - 8 S P K E 54279? P M S P K E 2 05 ? S POKE. 206 ? PM-f 2 I PM-~PM*256 S REM BEGIN NINO OF PLAYER 8 5 D I... I S T " P E E K ( 5 6 ) •)• P E E K ( 5 6 1 ) * 2 5 6 90 POKE 559? 46 SEEM 2-LINE RESOLUTION F OR PLAYER 100 POKE 53277? 3 SEEM ENABLE PLAYER/MIS SILE GRAPHICS 110 FOR X-PMT512 TO PM-f 640 SPOKE X?0SNE XT XJREM CLEAR MEMORY FOR PLAYER 120 RESTORE 130? FOR X^PM-f525 TO P Mi 532 {READ B SPOKE X?BSNEXT XSREM MAKE CURSO R 130 DATA 24 ? 24 ? 24 ? 231 ? 231 ? 24? 24? 24 140 POKE 704? 12 S REM COLOR PLAYER WHITE 1 5 H Z "- 4 7 S T » S X » 1 I Y « S C ~ 2 160 POKE 53248? HZ 170 IF PEEK (764) -255 THEN 220 180 B~PEEK(764)~30JIF B«"l THEN C-BJOOT 220 190 IE B=0 THEN O2IG0T0 220 200 IF B=-4 THEN C=3JGOT0 220 210 IF B=~6 THEN C=4 220 POKE 764 ? 255 t IF PEEK (53279) =6 THEN 145 Listing 9-6. Slide Editor (continued from page 145) 350 230 IF STRK3<0)=G THEN COLOR C J PLOT X» Y 240 IF STICK <0>=15 THEN 170 250 I F S T I C K < ) :::: 7 AND X < 79 T H E N X = X 1 :l. ! H Z = H Z + 2 { P K E 5 3 2 4 8 p H Z i G T 1 7 260 I F S T I C K ( ) » 1 1 AND X > 1 T H E N X ~ X - 1 I H Z ■ H 1 -2 I P K E 53248 » H Z. ! 6 T 1 7 270 IF STICK<0>~13 AND Y<47 THEN Y-Y+l t Q = U S R ( D W N ) I 9. ■■■■■■ U S R ( D OWN)? G ')" :l. 7 280 IF ST ICK (0)^14 AND Y>0 THEN Y=Y-1J Q = U S R ( U P ) ! Q - U S R ( U P ) I GO T :l. 7 290 IF STICK (0)^6 AND X<79 AND Y>0 THE N X ■ X + 1 J H Z - H Z + 2 I P K E 53248 » H Z t Y - Y •••■ 1 J Q - U S R ( U P ) i Q ■■"-■■ U S R ( U P ) i 6 T 1 7 300 IF STICK<0)=5 AND X<79 AND Y<47 TH E N X ■ X + 1 i H Z ■ H Z +2 % P K E 53248* H Z i Y = Y + 1 1 Q ~ U S R ( D W N ) t Q -- 1. J S R < D UN ) t G T :l. 7 310 IF STICK (0)^9 AND X>1 AND Y<47 THE N X ■■■■■■ X -■ 1 1 H Z ■ H Z •- 2 t P K E 53248 » H Z J Y ■ Y + 1 1 Q ~ U S R ( D U N ) J Q - U S R ( D WN > t G T 1 7 320 IF STICK<0)=10 AND X>1 AND Y>0 THE N X ~ X •■•• 1 ! H Z ■■■■■■■ H Z •■ • 2 I P K E 5324 8 » H 1 1 Y ■ Y - 1 i Q ~ USR(UP) {Q»USR ■■■■■■■■ " " I NAME* ( 140 ) ~ " " 5 NAME* ( 2 ) - NAM E * X 8 C R * -- NAM E * J N * » S C R * 80 ? "HOW MANY SCREENS "» J INPUT S J REM THREE SPACE AND BACKSPACES 90 IF S>10 THEN SO X REM NO MORE THAN 10 SCREENS 1 F R X - 1 T S ! ? " E N T E R " y X 5 " S C R E E N "? SIN RUT N*JEEM GET THE NAMES OF THE S GREENS 1 1 S P ~ X * 1 4 ■■•■ 1 3 i N A M E * ( S P ) ■■■■■■■■ " D i " X N A M E * ( 8 P i 2 y S P f 9 ) = N * X N A M E * ( 8 P + 1 ) = ' . D R W " i R E M E N TIRE NAME 120 NEXT X 130 GRAPHICS 21 J REM SET 2ND SCREEN 140 D I... I S ' l ' - P E E K < 5 6 ) + P E E K<561)#256JSC R 2 = P E E K ( 8 8 ) i P E E K ( 8 9 ) * 2 5 6 I R E M S E C N D S C R E EN AREA ISO F=OIFOR X~l TO Si REM NOW GET THE S GREENS 1 6 8 P ~ X * 1 4 •■•• 1 3 ; S C R * ~ NAM E * ( S P ? 8 P ••}■ 1 3 ) S R E M NAME OF SCREEN TO BE DISPLAYED 170 SCREE N=SCR2J IF X/2~INT< X/2 ) THEN 8 C R E E N = 8 C R 1 t R E M G E T T H E R I G H T 8 C R E E N 180 OR EN #2»4 y OvSCR* 190 FOR Z=SCREEN TO 8CREENT9S9 X GET #2? 8 X P K E Z y 8 X N E XT IX C I... S E 1 2 J E E M G E T S C R EEN FROM DISK AND ROT IN MEMORY 200 IF X~2 THEN F™1 210 IF F THEN GOSUB 300 J REM WAIT FOR S TART 220 NEXT X 230 GOTO 230 300 IF PEEK (33279) ^7 THEN 300 3 1 I F F E E K ( & 8 ) < > P E E K ( D I... I S T f 4 ) T H E N P K E D I... I S T + 4 y P E E K ( 8 8 ) I P K E D I... I S T + 5 t P P. E K ( 89) {RETURN 320 P K E D L I S I ' i 4 * 8 1 X P K E D I... I S T ■{■ 5 y 8 2 330 RETURN Line 40 subtracts 4 from the amount of RAM shown in location 106. This IK of memory will be set aside for one screen. The variable S2 is the high order byte of the screen memory, SI is the low order byte. 149 Line 50 changes the value in 106 by poking it with the value that was there less 4 (IK). Now the computer thinks that it has IK less of memory and will not touch the memory past this address. Line 60 resets the display list and screen. Since there is less memory for the computer to use, the display list and screen are relocated. Line 70 sets aside string space for the names of the screens that will be shown. N AME$ will contain the names of all the screens that will be shown. Each screen name needs 14 bytes or character spaces. There is room for 10 titles as the program stands. Increase the amount of string space by adding multiples of 14 to 140. Line 75 clears all the strings. There can be data in the strings that can interfere with the program. The easiest solution is to clear out strings that have been fielded. Line 80 asks for the number of screens that you are planning to display. After the word SCREENS come three spaces and three backarrows. This will clear out a previous entry if it was more than 10. The number of screens that you plan to show are stored in variable S. Line 90 checks S to see if it is greater than 10. If it is, line 80 will repeat. If you changed NAME$ for more than 10 titles, change the 10 in this line to reflect the number of screens that can be entered. Lines 100-120 allow you to enter the titles of the screens that you want displayed. Be sure to enter the names correctly. There is no trap in this program for wrong titles. The titles should be entered exactly as you entered them when you saved them in the previous program. The computer will add the D: to the beginning of the name and the .DRW to the end. Line 130 sets the screen for mode 5 with no text window. This is the mode that the pictures were drawn in, so this is the mode that they must be shown in. Line 140 finds the beginning of the display list and the beginning of the screen memory for this display list. In addition to the fifth and sixth locations in the display list, the beginning location of the screen memory area is also stored in decimal locations 88 and 89. Line 150 starts the loop that loads the screens into memory. The loop will be repeated the number of times that S is set for. Line 160 extracts the name of the first screen from N AME$. The variable SP will be the first byte for the name of the screen. The value of X will be multiplied by 14 (there are 14 bytes for each name) and 13 will be subtracted from that answer. That points SP to the first letter of the name of the screen. Since D: was added to every name, SP should be pointing to a D. The string SCR$ will hold the name of the screen. The next 13 bytes after and including the byte that SB is pointing to will be stored in SCR$. Line 170 stores the value of SCR2 in SCREEN. SCR2 is the first byte of the second screen. Then the variable X is checked to see if it is even or odd. If X is even, X/2 will be equal to the INT(X/2). The even screens are displayed on the first screen. The variable SCREEN will be changed to the first byte of the first screen. Now the screens will load, alternating between the first and second screen. Line 180 opens the buffer to read the file from the disk. If SCR$ contains the wrong information, the program will crash. Line 190 gets the bytes from the disk and stores them in memory from the first byte of the screen to the last. After the entire file is read to the screen, the buffer is closed. You will be able to watch the first picture being drawn on the screen. Line 200 checks the value of X. If it is greater than 1, then the computer will go to the subroutine that waits for the start button to be pressed. 150 Line 210 finishes the loop. If there are more screens to be loaded, the computer will loop back and load the next screen. This time, the picture will be loaded on the screen that is not being displayed. Line 220 loops until the system reset key is pressed. Lines 300-330 changes the screen that is being viewed. While one screen is displayed, the computer loads in another screen. When the start button is pressed, the computer compares the value of location 88 with the value of the screen in the display list. If these are not the same, the first screen is being displayed and the computer loads the values of locations 88 and 89 into the screen display in the display list. Now the second screen is displayed, and the routine returns to the main program. If the second screen is being displayed, the computer places the first screen address into the display list. This method of page flipping can be used for any number of screens. The only thing to remember is- DO NOT PRESS START UNTIL THE DRIVE HAS SHUT OFF. The program can also be designed to show a series of slides without any human intervention. Every slide ends with a .DRW. The program can load in the files by checking every entry on the disk for the .DRW. Use the * for the name of the program and .DRW for the extender. The computer will only choose those files that end in .DRW. A timing loop will leave the pictures on the screen long enough to be viewed without getting monotonous. With a little ingenuity, the program can load entire display lists as well as the pictures so that the slides can use multimode resolutions and alternate character sets. 151 Chapter 10 Sound Generators All sounds are generated by the same mechanism— the movement of air. How fast, how long, and with how much force this vibration occurs will govern the sound that we hear. A kitten's purr is quite distinguishable from a lion's roar! By careful manipulation of the sound registers, a variety of sounds and effects can be created. The four sound or voice channels that the ATARI has can be used alone or in combination with each other. Each channel can be set for a different distortion. This can be used to create strange sound effects for programs. THE AUDIO CHANNEL CONTROL Every sound has the same characteristics — attack, decay, sustain, and release. The actual tone depends on the frequency or number of pulses generated in a given time period. The higher the frequency, the higher the note or tone. In the sound command four different options must be set: SOUND v,p,d,1 . v=voice. There are four different voices or sound channels that can be used. Each is set by using the numbers 0-3. Each voice must be set with a separate sound statement. p=pitch. This is the frequency of the tone. Any number from 0-255 can be used. The higher the number, the lower the tone. A zero will produce no tone— just a clock from the speaker. The actual sound of the tone will depend on which distortion setting is used. d=distortion. The distortion here means the noise content of the sound that will be generated. The distortion value will tell the computer how to generate the pulses that will become sound. Only values of 10 or 14 will produce pure tones. l=loudness or volume. The tones can be loud or soft. Each voice channel can be set independently. The only restriction is that the sum of the volume of the voices used cannot exceed 32. The following program demonstrates how the tone (p) can vary depending on the level of distortion (d). The number of the pitch as well as the distortion will be printed on the screen while you listen to the tone. 153 Listing 10-1. Sounds 10 REM LISTING 10, 1 20 REM SOUNDS 30 REM BY L.M»SCHREIB£R FOR TAB BOOKS 40 FOR P-5 TO 255 STEP 5 }? PxJREM STEP THE NOTES BY 5 50 FOR D»0 TO 14 STEP 21? D»JREM CHANG E THE DISTORTION - USE ONI...Y EVEN NUMBE ES 6 S U N D y l :: ' j D ? 1 J F R Y ~ 1 T 2 : N E X T YJREM LISTEN TO THE SOUND 7 NEXT Dl? {REM GO THROUGH ALL THE SO UNDS •••• THE FEINT LETS THE NEXT FITCH S TART ON A NEW LINE 80 NEXT F Line 40 begins the for . . . next loop to change the pitch that the sound register will use. The number of the pitch will be printed on the screen. Line 50 begins the for . . . next loop to change the distortion of the sound register. Only the even numbers from 0-14 can be used for the distortion. Each pitch or tone will be heard in all 8 distortions. Line 60 plays the sound. The value of the pitch and/or distortion will be different each time this line is executed. The for . . . next loop here gives you time to listen to the sound created. Lines 70-80 complete the loops. As you can hear, some of the distortions of a pitch are very similar to others in the same pitch. Others have no sound at all. The only pure tones are generated by distortions 10 and 14. The volume of the sound can be used to enhance the sound created. Too often the sound is a "set it and forget it" function. Listen again to the sounds generated by the last program. Each sound came on and went off. True sounds do not occur this way. Listen to a piano key being struck, then a drum, and finally a horn (wind instrument) being blown. Each instrument produces its own unique sounds. Although both an organ and a piano are keyboard instruments, they have their own sound qualities. The time that a tone takes to reach its amplitude (height of sound) is called attack time. The decay time is the time it takes for the sound to start to fade, the sustain time is the length of time that the tone is heard (still vibrating). At the release time, the tone has faded away completely. The piano is the best example of these four factors. When you strike the key, you immediately hear the tone. It is loud and clear. This is the attack time. That loudness does not continue for an extended period of time. Very quickly the tone starts to fade. This is the decay time. The tone does not die away completely. The length of time that you can still hear the tone is the sustain level. When the tone finally fades completely, it is the release time. The following program creates an interesting effect when attack, delay, sustain, and release time are inserted into the program. 154 Listing 10-2. Sounds with Attack and Decay 10 REM LISTING 10.2 20 REM SOUND S- WITH ATTACK & DECAY 30 REM BY L.M.SCHREIBER FOR TAB BOOKS 40 FOR X=l TO 14? READ PJREM GET THE TO NE VALUE 50 FOR 0-0 TO 14 STEP 2 t SOUND 0»P»10»V SFGR Y=l TO 10 1 NEXT Y I NEXT VJREM ATT AC K 60 FOR Y=14 TO 8 STEP -2 i SOUND 0»P»10» Mi FOR Y = l TO 20 I NEXT Y I NEXT 02 REM DEC A Y 70 FOR Y~l TO 100 t NEXT YSREM SUSTAIN SO FOR 0-6 TO STEP -2 t SOUND 0»P>10»V J NEXT OiFOR Y~l TO 10 J NEXT YJREM RE LEA SE 90 NEXT XI REM DO ENTIRE SONG 100 DATA 121 t 121 p 31 t&l » 72*72*81 *91»91 r 96? 96 s> 108? 108 1 .1.2:1. Line 40 reads the pitch values from the data line. These are the tones that the computer will play. Line 50 simulates an attack. The volume begins at and gradually works its way up to 14. At each level, a timing loop holds the tone and volume level. Line 60 is the decay. The volume gradually decreases. The timing loop is longer here so that it will take a longer time for the sound to fade. Line 70 is the sustain. This is the length of time that you will hear the sound. The volume will remain the same. Line 80 reduces the volume of the sound to 0. This is the release time. The timing loop here gives each tone generated its own time. If there was not a clean break between the tones, the tone would appear to run into each other. Line 90 completes the loop. The sound created by this program gives the effect of an accordian. You can almost hear the bellow opening and closing with each attack and decay. The next program uses a slightly different technique to create attack and decay. There is a very definite vibrato to the melody. Listing 10-3. Sounds with Attack and Decay— Vibrations 10 REM LISTING 10,3 20 REM 01 BRAT IONS 30 REM BY L.M.SCHREIBER FOR TAB BOOKS 4 o d :i: M A $ ( 1 2 ) 155 Listing 10-3. Sounds with Attack and Decay— Vibrations (continued from page 155) 50 A$«" 673987654345" 60 FOR X«l TO 14 J READ PJREM GET THE TO NE VALUE 70 FOR T~l TO 3? FOR Z = l TO 12JV«VAL {SOUND 0»PrlOnUJNEXT Z I NEXT T 80 FOR Y~l TO 10 ! NEXT Y t SOUND , v » 90 NEXT X :l. 00 DATA 1 2 :l. f 1 2 1 >> 8 :L , 8 1 i ??. >• 72 s> 8 1 n 9 1 <, 9 1 » 96^96^ :1.08 s- 108 v 121 Line 40 dimensions A$ for the volume settings. Line 50 sets the volume sequence in A$. Line 60 reads the pitch from the data line at the end of the program. Line 70 contains the timing loop and the sound statement. This time the entire range of volumes will be changed rapidly a number of times rather than changing the volume and holding it for a period of time. The volume sequence will be used three times. The variable V will contain the volume. As Z is increased from 1 to 12, the correct volume will be removed from A$. Line 80 holds the last volume of the sound for a few seconds, then turns it off. Line 90 completes the loop. DIRECT ACCESS Like most commands in ATARI BASIC, there are hardware registers for the sound generators that can be set by poke commands. For each voice that you want to set, there are two addresses that must be poked. Voice Frequency Audio # Register Control o 53760 53761 1 53762 53763 2 53764 53765 3 53766 53767 The frequency register can be poked with any value from 0-255. This has the same effect as the P variable in the sound command. The audio control register is a combination of the volume variable (V) and the distortion variable (D). To find the number that should be poked here, multiply the distortion value by 16 and add the volume. By knowing where these register are, it is possible to use only the register that you need in a program. This will make it execute the sound changes faster because the one register will be set directly, and BASIC will not have to reset registers that are already set; for example, if the volume and distortion are set, and you have no reason to change them, you can poke the frequency register with the pitch or tones. If you use the sound statement, BASIC will recompute the distortion and volume each time it executes the sound command. There is one more control register for the audio. This register can change the way that the tones are generated. In the previous examples, we used one sound generator. We could easily 156 change the program to use two, three, or all four generators. For an actual tune, this would generate some harmony. For sound effects, a second or third sound register will add to the realism of the sound. It is also possible to use two registers together to form a 2-byte tone generator. This will increase the range of sounds that the computer can generate. In the next program, address 53768 is poked with 16. This will couple sound register with 1. Register is the low order byte and register 1 is the high order byte. As the tones begin, you will notice that as long as register 1 is set to 0, the tones sound the same as those generated with a single sound register. Once the value of register 1 changes, the tones become deeper, until they become so very deep that they do not seem to change their pitch. Listing 10-4. Variations on Tones 10 REM LISTING 10.4 20 REM VARIATIONS ON TONES 30 REM BY L.M.SCHREIBER FOR TAB BOOKS 4 P K E 537 68 » 1 6 I R E M I... I N K V 1 C E S I 1 50 POKE 53/61 y 170 60 FOR P~0 TO 255 SPOKE 53762 »P;? "SOUN D REGISTER 1~" rP» 70 EOE Pl-0 TO 255 STEP 5; POKE 53760 yp 1 ! ? P 1 r 80 POP Y*l TO 100 J NEXT YJREM TIMER 90 NEXT Pi J? J NEXT P Line 40 pokes location 53768 with 16. This joins sound registers and 1 into one register. Line 50 pokes location 53761 with 170. This is equivalent to a distortion of 10 and a volume of 10. Line 60 begins the for . . . next loop that changes the pitch content of register 1. This register will increase in value once every time the register reaches 255. Line 70 begins the for . . . next loop to change the pitch value in register 0. Every time this register cycles from to 255, register 1 will be increased by 1. Line 80 is a timing loop to give you a chance to hear the tones being generated. Line 90 continues the loop until all the tones have been generated. Knowing where the tone generator registers are located is very helpful if you want to write a machine language subroutine for the sounds and/or music that you need for your program. Some of the arcade games play music while the program is running. It is possible to write a machine language subroutine that uses the vertical blank to produce music. The procedure is very similar to the one used in the last chapter to display two screens at the same time. Listing 10-5. Music: Machine Language Subroutine 10 REM LISTING 10,5 20 REM MUSIC ™ MACHINE LANGUAGE SUBROU TINE 30 REM BY L.MtSCHREIBER POP TAB BOOKS 157 Listing 10-5. Music: Machine Language Subroutine (continued from page 157) 4 A » P E E K ( 1 6 ) -■ :l. I R E M S A V E 256 BYT E S 50 POKE 106*AJREM MOVE EVERYTHING UP 2 56 BYTES 60 GRAPHICS OJREM RESET THE SCREEN AND DISPLAY LIST 7 P (J K E 206 * 1 I P K E * 20 J R E M S E T T H E L E N6TH OF THE NOTE PLAY 80 POKE 207 i-OJ REM OFFSET FOR THE NOTE BUFFER 90 POKE 203 .0 SPOKE 204 * A {REM ADDRESS F BUFFER FOR NOTES :l. B U F = A #2 5 6 i Q F F * 1 9 1 i R E M B E G INNING F BUFFER AND LENGTH 110 FOR X-BUF TO BUF-f OFF } READ C J POKE X vCJNEXT X J POKE 205 * OFF J REM READ IN THE NOTES 111 DATA 0*60*64*60*81 * 60* 64* 60* 96 y :l. 21 * 128* 121 k 162*121 *128* 121 112 DATA 162*60*64*60*81 » 60*64 * 60*72 1 9 1*96*91 ,121 * 91 * 96*91 113 DATA 108* 53* 60* 53* 72* 53*60* S3* 64* 8 1*85*81*108*81*85*81 114 DATA 96*47*53*47*64*47*53* 47*60* 72 * 76 * 72 * 96 * 72*76? 72 115 DATA 60*85*96*85*60*85*96*85*64*81 * 85* 81* 64* 81* 85* 81 116 DATA 64*96* 108*96*64*96* 108*96*72* 85 * 96* 85* 72? 85* 96*85 1 1 7 DATA 72*1 08 * 121 * 1 08 * 72 * 1 08 * 1 2 1 * 1 08 * 8 1 * 96 * 1 OS * 96 * 8 1 * 96 * 1 08 * 96 1 1 8 D A T A 8 1 * 1 1 4*12 8 * 1 1 4 * 8 1 * 1 1 4*12 8 * 1 1 4 * 8 5 * 1 8 * 1 1 4 * 1 8 * 8 5 * 1 8 * 1 1 4 * 1 8 1 1 9 DATA 8 1 * 85 * 8 1 * 1 08 * 72 * 8 1 * 72 * 108 * 64 * 7 2 * 6 4 * 1 8 * 6 * 6 4 * 6 * 1 8 120 DATA 53*85*81*72*64*64*53*53*47*40 * 5 3 * 4 * 6 * 4 * 6 4 * 4 121 DATA 72*72*85*96*85*85*64*64*60*53 * 64* 60* 72* 68* 72* 81 1 22 DA T A 8 1 * 8 1 * 8 1 * 8 1 * 8 1 * 8 1 * 8 1 * 8 1 * 8 1 * 8 1 * * * * * * 130 FOR X-0 TO 33? READ C SPOKE 1536iX*C J NEXT X 140 DATA 72*169*170*141*1 * 210* 198*206* 208 * 20 * 1 65 * * 133 * 206 * 1 64 * 207 * 177 * 203 * 1 158 96*205*208*2* 1 6 y 2 5 5 * 2 v 1 3 2 * 2 07 150 DATA 14J. *0* 2 10 p :1.04 c 76 y 95 y 228 :l. 6 F R X - :l. 5 7 T D :l. 5 8 1 1 R E A D C ! P K E X > C J NEXT X 170 DATA 104 > 104* 104 y 168* 1 04 y 104j 170* 1 04 y 104*76 t 92? 228 180 Q«USR ( 1570*0*6* 6) 1 9 ? P E E K ( 20 7 ) * " F F S E T " r i :: ' E E K ( 20 6 ) * " C (INTER " 2 G T 1 9 Line 40 moves the end of memory down by 256 bytes. This is the area that will be our buffer for the music. The music buffer can be as large or small as needed. This program will restrict the length of the melody to 256 bytes. Line 50 pokes this new end of memory value into location 106. Now the computer will not use the last page of memory. Line 60 resets the screen and the display list using the value in 106 as the end of memory. Line 70 pokes a 1 into location 206. This location will be used as the timer or duration of the note being played. We set it to a 1 to begin with as a dummy value. Location will hold the duration value. Location 206 will change while the program is being executed. Every time it counts down to 0, the computer will have to restore the duration value for the next note. Location will not change when the program is executed. Line 80 uses location 207 as the offset for the buffer. This location will increment every time a note is played. By adding the number in this location to the beginning address of the buffer, the computer will always know where the next note is. Line 90 sets locations 203 and 204 to the buffer address. Location 203 is set to because we know that the music buffer begins on an even page. Location 204 is set to the high order byte of the beginning of the music buffer. Since we set the last page of memory aside for the music buffer, this value is poked into location 204. Line 100 computes the decimal address of the first byte of the music buffer by multiplying the value of A by 256. The variable OFF is set to one less than the number of notes that will be played. Line 110 is the for . . . next loop that moves the data on the next 12 lines into the music buffer. Each number in the data lines represents one note. Line 130 reads the machine language subroutine into page 6 of the computer's memory. This is the routine that will be executed everytime the vertical blank is executed. Be sure that the data in lines 150 and 160 are entered correctly. If there is an incorrect number in the routine the system will crash or lock up. Line 160 places into memory the machine language subroutine that will initialize the routine that runs during the vertical blank. Again, it is important that the line of data is entered correctly. Line 180 executes the second machine language subroutine. The beginning address of the vertical blank routine and the type of routine is passed to the machine language subroutine with the USR command. Line 190 simply prints the offset value from location 207 and the counter or duration value from location 206. Every time the number in 207 changes, the note will also change. Once it 159 reaches the 191st note of the melody, it will reset to 0. The counter shows how long the note is being held. Every time it reaches 0, a new note is pointed to by location 207. To stop this program, you must press the system reset key. If you press only the break key, you will only stop the BASIC program. The machine language subroutine running in the vertical blank will not be affected. By experimenting with different distortions, durations, and frequencies, you can change the entire effect of the melody. 160 Chapter 1 1 Interpreting the Keyboard There are times when a simple input statement is not the best way to get information from the keyboard: the program may not lend itself to question marks on the screen; you may want single key input; or you may want the program to continue with its task and the keyboard to be read only when a key is actually pressed. (This is sometimes called reading it on the fly.) When you use the input command to retrieve information from the keyboard the program stops and a question mark appears on the screen. The entry is placed in either a string or a variable. If letters or other characters are entered into a numeric variable instead of numbers, an error will result. This can be resolved by using strings for all inputs. The input can be checked only after the return key has been pressed. Using this command is the simplest way to get information. It is used most often. The second method of getting an entry is with the get command. Although the program must still stop to get the input, this method is much faster than the previous way. The characters entered can be screened immediately. If the character is not correct, the program can disregard it and wait for another entry to be made. The buffer length can be set for any length, and when full, the program can continue without waiting for the return key. The keys pressed do not have to appear on the screen. The following program is a useful routine that can be used in any program that needs a read-keyboard routine. Listing 11-1. Read the Keyboard 10 REM LISTING 11»1 20 REM READ THE KEYBOARD 30 REM BY L*M*SCHREIBER FOR TAB BOOKS 40 DIM BUF*<10) 5 P K E 752?!} ? " > " J P E N #2 ? 4 y * " K I " J R EM CLEAR SCREEN - OPEN KEYBOARD FOR A READ 60 FOR X=l TO 10 t REM BUFFER IS 10 CHAR AC TEES LONG 161 Listing 11-1. Read the Keyboard (continued from page 161) 70 GET #2*BJREM WAIT FOR A KEY TO BE P R ESS ED ™ STORE AT ASCI I VALUE IN B 80 IE B>:l.27 THEN B-B-128 1 POKE 694y(>;RE M IE ATARI KEY HAS BEEN PRESSED RESET 90 IE B>?0 THEN B-B-32JP0KE 702k 64? REM MAKE IT UPPER CASE 100 IE B<65 THEN 70 J REM IT'S NOT A LET TER 1 1 B U E $ ( X ) » C H R * ( B > J R E M P L) T I T I N T H E STRING 120 POSITION X»5J? CHRfCBKNEXT X 130 ? BUF$ 140 CLOSE #2 Line 40 sets the buffer length — (BUF$) to 10 characters. Line 50 removes the cursor, clears the screen, and opens the keyboard for a read. Line 60 begins the for . . . next loop that will accept keyboard input without using a return key. Line 70 waits for a key to be pressed. The keyboard must be opened before the get command will work. The ATASCII value of the key pressed will be placed in the variable B. Line 80 checks the value of B. If it is greater than 127, the ATARI or inverse key was accidentally pressed. Correct this by poking into location 694. Subtract 128 from the value of B to get the normal code for the key pressed. Line 90 checks the value to see if it is upper or lowercase. If the caps/lower key was pressed, all the inputs would be in lowercase. Rather than check each key against 2 values, it is easier to subtract 32 from the value in B and reset the keyboard for uppercase by poking location 702 with 64. Line 100 now checks the value of B to make sure that it is a letter. If the ATASCII value is less than 32, it is not a letter, and the program goes back to line 70 to wait for another input. The key that was pressed is disregarded completely. It is not displayed on the screen and it is not stored in the buffer. Line 110 places the letter for the key pressed into BUF$. As each correct key is pressed and entered, the value of X will increase. This will point to the next vacant position in BUF$. Line 120 places the letter on the screen. The row is set, the column position will increase with X. Line 130 prints BUF$ on the screen under the letters that were printed as they were pressed. BUF$ contains exactly what was printed on the screen. If any numbers or control characters were pressed, they were ignored by the program. Line 140 closes the keyboard. In the next program, we will use this input routine for a tile game. This game is based on the 5 x5 letter tile game. Each tile can only slide to a vacant spot. Try to arrange the letters correctly. 162 Listing 1 1-2. Tiles :I.O REM LISTING 11,2 20 REM TILES 30 REM BY L.fUSCHREIBER FOR TAB BOOKS 4 DIM BUT* < 25) ?TEMP$< 1 ) 5 B I J F * ■■■■ " A B C D E F' G H I J K I... M N P Q R S T U V W X " I R E M PI... ACE ALL THE TILES IN A STRING 60 FOR T=l TO 5: FOR X~l TO 25JR-~INT(RN D ( 1 ) * 2 5 ) + I I R E M P I C K A L E T T E R 70 T E M P $ ■■■■■■■ B U F * ( R r R ) J B U F $ ( R r R ) :: = B U F t ( 2 6 - X t 2 6 •••• X ) t B U F $(26 - X » 2 6 - X ) => T E M P $ S R E M MOV E THE LETTERS AROUND SO NEXT X J NEXT TIREM DO IT SEVERAL TIM ES 90 GRAF HICS 18? REM MODE 2 WITHOUT TEXT WINDOW :l. X => I : F R R ■■■■■■■■ 4 T 8 i F R = 7 T 1 :!. t P S I T 1 N C v R J 'i 1 # 6 9BU F $ < X * X ) t R E M P R I N T T H E LETTER :l. :l. X « X f I I N E X T C i ME X T R J R E M P R I N T T H E WHOLE STRING 120 REM READ THE KEYBOARD 1 3 P S I T 1 N I » 1 1 ? # &J"pres s a 1 ©tie t> " 1 P E N # 2 r 4 , c " K J " : R E M i :: ' E N T H E K E Y B A R D FOR A READ 140 GET #2 vBJ CLOSE #2 t REM GET A KEYSTR ONE 150 IF BVI.27 THEN B = B- 127 1 POKE 6?4»0JR EM RESET THE INVERSE FLAG 160 IF B>?0 THEN B-B-32IP0KE 702? 64? RE M SET FOR UPPER CASE ONLY 170 IE B<65 OR B>88 THEN 1301 REM TRY A GAIN - NOT A GOOD LETTER 1 8 F G R X as 1 T 25; I F A S C ( B U F $ < X 9 X ) ) ~ B THEN 200 190 NEXT X J GOTO 130 J REM NOT THERE?? 2 R ~ I N i ' ( ( X - 1 > / 5 > + 4 I R E M M P (J T E T H E R OW 210 C==CX--(R~4)*S>+6JREM THIS IS THE CO LUMN 220 P E N # 2 r A » j " K t " i F R T ™ 1 T 2 I S U N D 9 5 s> 1 t 1 i F R Y = 1 I" 1 t N E XT Y I S U N D v > v i N E X T T X R E M G E T K E Y 2 30 I 5 1 1 n ON 1 p i. l '' : ll :■> 5 "pre s s a n a r r 1 o w " 163 Listing 11-2. Tiles (continued from page 163) I GET #2 fB I CLOSE #2 J REM GET THE KEYSTEO KE 240 IF B~42 THEN 300 1 REM RIGHT ARROW 250 IE B~43 THEN 320 J REM LEFT ARROW 260 IE B==45 THEN 340 J REM UP ARROW 270 IE B=61 THEN 360 1 REM DOWN ARROW 280 GOTO 220 J REM NOT A 'MOVE" KEY 290 REM NOW SEE IE THE LETTER GAN MO ME 300 IE X~25 THEN 130 305 I F B U F $ ( X + 1 >■ X + 1 ) < > " " R X / 5 « I N T « X /5) THEN 130 310 POSITION C?R{? #6 5" "I POSITION Gil t R I ? # 6 9 B U F $ ( X •> X ) ? B U F % ( X f :l. t X + 1 ) ~ B U F $ ( X i>X) t BUF$ < X ? X ) ■■■■■■■ " " J GOTO 130 320 IE X=l THEN 130 325 I F ( X •■•• 1 ) / 5 a I N T ( ( X ■■■ 1 ) / 5 ) E B [J f $ < X •••• lyX-l)<>" l! THEN 130 330 POSITION CyRl? #6?" "J POSIT I ON C-1 9 R i ? # 6 ? B U F $ < X r X ) I B U F $ ( X •- 1 » X ■■■• :l. ) ~ B U F $ ( X ?X> JBUF$-" " J GOTO 130 340 IF R=4 THEN 130 345 IE BUE$CX"5vX-5)<>" " THEN 130 350 P S I T 1 N C r R X ? # 69* " I P S I T 1 N G » R -1 i ? #6 i BUF$ ( X ? X ) i BUF$ ( X--5 r X -5 ) -BUE$ ( X yX) JBUF$(XyX)™" " iGOTO 130 360 IE R=S THEN 130 365 IF BUF$(X-f5yXf5)<>" " THEN 130 370 P S I T 1 N G t R 5 ? # 6 5 " "J P S I T 1 N C t R •{• 1 i ? #6 i BUE$ ( X 9 X ) t BUE$ < Xi5 » XI 5 ) >=BUF$ ( X t X) I BUE$ ( X y X ) ™ " " J GOTO 130 Line 40 sets aside 25 bytes for the letters (BUF$) and one byte for a temporary storage (TEMP$). Line 50 places the first twenty-four letters of the alphabet into BUF$. The twenty-fifth letter is the space. Lines 60-80 shuffle the letters. A random letter (R) is picked. That letter is placed in TMP$. The last letter minus the value of X is placed in the random position. The letter in TEMP$ is moved to the position that was just vacated. The loop continues until all the letters have moved five times. This method ensures that all the letters in the string will be thoroughly mixed. Line 90 sets the screen for graphics mode 2 with no text window. Line 100 places all the letters in BUF$ in a 5 x 5 grid on the screen. The variable X will point to the letter in the string. R is the row and C is the column. To center it on the screen we begin with the 4th row and 7th column. Line 110 increments X each time a letter is printed. This moves the pointer up one letter. 164 The loop continues until all the letters have been printed. Line 130 prints the direction on the screen. First a letter must be pressed. The keyboard is opened for a read. Line 140 sets the value of the key pressed and closes the keyboard. Line 150 checks the value of B. If it is greater than 127, then the inverse or ATARI key has been pressed. 127 must be subtracted from this value and location 694 must be poked with a zero to set it back to normal. Line 160 checks to see if the value is for a lowercase letter. If it is, 32 is subtracted from the value and location 702 is poked with a 64. The keys pressed now will be returned as upper case. Line 170 checks the value of B. If it is not a letter between A and X the program will return to line 130 for another input. Line 180 finds the position of the letter pressed in BUF$. The value of X will be its position. Line 190 sends the program back to line 130 for another input if the letter is not found. Line 200 calculates the row of the letter. The value of X minus 1 is divided by 5. The integer of the result is added to 4. Since there are 5 letters in each row, dividing X by 5 will give the row number. However, the fifth letter in each row would be put in the wrong row. By subtracting one from X, the resulting integer is the correct row (the first row is counted as row 0). Since we began printing the letters in position 4, this number is added to the result. Now we know which row on the screen the letter is in. Line 210 calculates the column. 4 is subtracted from the value of X to give the true row. This answer is multiplied by 5 (there are 5 letters in each row) and the result is subtracted from the position that X is pointing to. This answer is added to 6 because it will be in the range of 1-5. The columns on the screen begin with position 7. Now that we know where the letter is located on the screen, we can get a keystroke for the direction that the letter should be moved. Line 220 opens the keyboard for a read. A short tone will indicate that the program is ready for another input. Line 230 prints the new message on the screen. This time the program wants an arrow key to be pressed. When a key has been pressed, the computer will close the keyboard. Lines 240-270 will send the computer to the correct routine depending on whether the up arrow, down arrow, right arrow, or left arrow was pressed. Actually, the code that the program is comparing the inputs to are for the asterisk, the minus sign, the equals sign, and the plus sign. By using these codes instead of the control-arrow codes, the program is truly a one keystroke program. Line 280 sends the program back to line 220 if an arrow key was not pressed. Line 300 checks to see if X is pointing to 25. If it is, then it is at the end of the buffer and the letter cannot be moved to the right. The program will send the computer back to line 130 for another letter input. Line 305 checks to see if the next place in the buffer is empty. It also checks to see if this letter is in the fifth column on the screen. If either of these conditions are true, then the letter cannot move to the right, and the computer will go back to line 130 for a new letter. Line 310 erases the letter from its position on the grid and moves it over one to the right. Then it moves the letter up one space in the buffer. The position that the letter was occupying becomes a space. The program continues with line 130. Line 320 checks to see if X is the first position. This routine moves the letters to the left. If the letter to be moved to the left occupies the first position in the string, it cannot be moved to the left. The program returns for another letter input. 165 Line 325 checks to see if the letter occupies the first column of the grid. It also checks the position just before it in the buffer. If this position is full the letter cannot be moved to the left. If the letter cannot be moved because of either of these conditions, the program waits for another input at line 130. Line 330 uses the same procedure, but in reverse, to move the letter to the left. The letter is first erased from the screen, and then reprinted in the new position. The letter is moved down one position in the buffer and the old position becomes a space. Line 340 checks to see if the row (R) is 4. If it is, then the letter is in the top row. This routine moves the letter up one row. A letter in the first row cannot be moved up. Line 345 checks the buffer five positions before the position of the letter that will be moved. The letter will move up one row. The square that it is moving to is five positions before its position. If that position is not empty, the program will go back and wait for a new command. Line 350 erases the letter from the grid and reprints it one row up. It then moves the letter up five positions in the buffer and replaces it with a space. Line 360 checks the value of the row (R) to see if it is the last row of the grid. This routine moves the letter down one row. The letters cannot be moved past the last row. Line 365 checks the buffer five positions past the letters position to make sure that it is a space. If it is not, the program will go back to line 130 for another entry. Line 370 erases the letter and prints it one row down. It then moves the letter over five positions in the buffer. The letter's original position becomes a space. This entire game is played with single keystroke entries. There are actually two entries for each move, but each is treated separately. If the first entry is correct, the program will ask for the second. Inputs that are not considered legal are ignored. KEYBOARD CODE The third method of entry from the keyboard is to read the keyboard on the fly. This means that the computer is busy running the program, but it keeps checking to see if a key was pressed. If it was, then it will process that information. If no key was pressed, it will continue with the main program. This method could be used in a game where the computer is working out some possible moves. If the player had to wait for the computer to make its move after the player made his/her move, the game could be excessively long. If, however, the computer could do its thinking while the player did, the time that the computer needed for its moves would appear to be shortened. A chess game is a good example of a situation where you would want the computer to think while the player did. The keyboard code is not ATASCII. It does not seem to follow any pattern. The only exception is that there is one bit set in the code if it's an uppercase letter, or if the control key has been pressed. Table 11-1 shows the hardware key code and the corresponding key. Try the following one line program: 10 ? PEEK(764),:GOTO 10 There will be a stream of 255s on the screen until a key is pressed. Once a key has been pressed, that value will be printed on the screen until another key has been pressed. This is the hardware code for the keys. To convert the keycode into ATASCII so that you would know which key was actually pressed could be done with all the possible characters in a string buffer. There is 166 no need to do duplicate work. Beginning with memory location 65278, all the ATASCII codes are listed according to keycode. The following program will show you the internal or hardward code of the key and the character. Listing 11-3. Keyboard Conversion 10 REM LISTING 11.3 20 REM KEYBOARD CONVERSION 30 REM BY L.M.SCH REISER FOR TAB BOOKS 40 CON VERS I ON = 6 52 7 & 5 ? " > C I... E A R > " J P K E 752 r It R E M C I... E A R S C REEN - REMOVE CURSOR AG POSITION 3v5ri ; "PRESS ANY KEY ON TH e keyboard l" except the break k ey::i" 70 if peek (764) --255 then 70 i rem no key has been presseb 8 k - p e e k ( 76 4 > i p k e 76 4 > 255 i r e m sao e the code - clear the location 9 p s i t 1 n 3 » :!. i ? " i n t e e n a l c d e f k e y p r e s s e d " ? k c i r e m s h w h a r dware value ■- 6 spaces--5 esc-bk arrow 100 position 3*151? "key pressed •••• " i chr* ( peek ( con vers i on+kc ) ) s rem 6 spaces -5 esc-bk arrow 110 GOTO 60 Line 40 sets the variable CONVERSION to the first byte of the ATASCII values. This location is the ROM or the operating system. Line 50 clears the screen and removes the cursor. Line 60 asks you to press any key with the exception of the break key. Line 70 loops until a key has been pressed. When a key has been pressed, the value of location 764 will not be 255. Line 80 stores the value of location 764 in variable KC. Location 764 is poked with 255. This clears it for another input. Line 90 prints the internal or hardware code for the key that was pressed. Be sure to enter six spaces and five escape control-backarrows in the print line. This will erase the previous code from the screen. Line 100 adds the keycode to the first byte of the table in ROM. The program then prints the character of the peek of that location. This character will be in lowercase unless the shift key or control key was pressed for the input. Line 110 loops back to line 60 for another entry. Because of this table in ROM, it is very easy to convert keycode into the actual ATASCII values for a program. 167 letter D r character e o d e hardwa re c o d e 32 33 ! 33 95 ii 3 4 '■'.■' ,-:'A 35 36 '•? % 37 93 X 38 9:1. / 3? 1 :l. 5 ( 40 :l. :l. 2 ) 4 :l. :l. :l. 4 * 42 7 .}. 43 6 ? 44 "1 -") .... 45 1 4 4 46 :?.' "V .■■' 47 ■...' ■...■ :l. 48 4? 50 v 50 30 3 5:1. 26 4 52 24 5 53 29 6 54 27 ..., 55 5 :l Table 11-1. ATASCII and Hardware Values. 168 READING THE KEYBOARD The following program is an example of how the keyboard can be read while the computer is executing a main program. This simple keyboard program will keep letters flying across the screen. If you press the correct letter, the letter will stop and you will be awarded points. The entire time that the letters are moving across the screen, the computer is checking location 764 to see if a key has been pressed. Listing 11-4. Letter Attack 10 REM LISTING 1:1,4 20 REM LETTER ATTACK 30 REM BY L,M,SCHREIBER FOR TAB BOOKS 40 CON VERS I ON- 652 78 50 GRAPHICS J.7ITL=30tREM MO BE 2 NO TEX T WINDOW. 6 K ■■■■■■■■ I N T ( R N B ( 1 ) * 2 6 ) + 6 5 t R E M G E T A T A S C I 1 VALUE FOR CHARACTER - DON'T USE A SPA CE 7 P S I T 1 N 2 f J ? • 6 5 " s c o re " t S C 8 R a I N T ( R N B ( 1 ) * 2 2 ) + 1 J R E M P I C K A R A N B M ROW FOR THE LETTER 9 F R X = 1 T 1 9 l P S I T 1 N X -• 1 t R i ? # 6 J " " ?CHE*CK> 100 FOR T=l TO Tl... 110 IF PEEK (764) ~2S S THEN 140? REM NO K EY HAS BEEN PRESSED 1 20- K C ■■■■■■ P E E K ( 76 4 ) J P K E 7 6 4 ? 2 5 5 J R E M SAO E THE CO BE -• CLEAR THE LOCATION 1 3 I F P E E K ( C N '■■> E R S 1 N + K C ) - 3 2 ~ K T H E N S C=SC+20"-XJT=TI..JX™-i9 140 NEXT T 1 5 N E XT X l P S I T 1 N :i. 9 y R ; ? # 6 5" " 160 IE SC<1000 THEN 60 170 IF SC>=1000 THEN GRAPHICS 17 J POSIT ION 4 y 4 t ? # 6 y " Y U MA B E I T " t P S I T I ON 4 •> 6X1 #6P "score •••• " ?SC 1 S ? # 6 5 " P I... AY A G A I N " i P E N 1 2 y 4 1 y ■ K % " 1 90 GET #2 >- B i C I... S E # 2 i I F B = 8 9 R B - 1 2 1 T H E N I ■ I... * T I... •- 5 i G R A P l-l I C S 1 7 I G T 6 Line 40 sets the variable CONVERSION to 65278. This is the first byte of the ROM table to convert the internal or hardware code into AT ASCII. Line 50 sets the screen to mode 2 with no text window. The variable TL will be used in the timing loop. It can be changed to any number to make the letters move faster or slower. Line 60 chooses a number for the letter that will fly across the screen. It chooses a number 169 from 0-25 because there are 26 letters in the alphabet. This number is added to 65. The letter A is AT ASCII 65. Line 70 prints the current score on the screen. This line will update the score after every letter. Line 80 picks a random row for the letter to travel on. The letter cannot be on the 0th line because that's where the score is printed. Line 90 begins the for . . . next loop that moves the letter across the screen. The letter begins on the left side of the screen and continues across to the right. Line 100 begins the timing loop. If there was no timing loop, the letter would travel across the screen too fast to be read. Line 110 checks location 764 for a value other than 255. If no key has been pressed, the computer is directed to line 140 to continue the timing loop. Line 120 stores the value of location 764 in the variable KC. The location is cleared by poking it with 255. Line 130 checks the key pressed with the letter that is being displayed. The program looks at the peek of the keycode added to the first byte of the ROM table. Since this is the lowercase AT ASCII code for the letter, 32 must be subtracted from the code. If this result is equal to the value of KC, the correct key has been pressed. A new score is calculated by adding 20 (20- X) to the old score. X is the horizontal position of the letter at the time the correct response key was pressed. The variables T and X are set to their highest values and the for . . . next loop continues. Since T and X are at their limit, the program will continue with line 160. If the letter reaches the edge of the screen, it will be erased from the screen. If the correct key has been pressed, the letter will stop on the screen and remain there until another letter erases it. Line 160 sends the computer back to line 60 for another letter if the score is less than 1000. Line 170 will end the game if the score reaches or surpasses 1000. The screen will clear and a message will appear. The ending score will also be printed. Line 180 asks if you want to play again. The keyboard is opened for a read. Line 190 gets an input from the keyboard and closes it. If the letter Y has been pressed, the program will subtract 5 from the counter and go to line 60 for another game. Each time a new game is played, the letters will fly faster on the screen. If any other key is pressed, the program will end. 170 Chapter 12 Understanding the Screen Editor Everything that you see on your screen is processed by the screen editor. It keeps track of where the cursor is, where the screen memory begins, whether or not there is a text window, the tab locations, the mode the screen is in, the right and left margins, etc. This chapter will list most of the memory locations that the screen editor uses and the function of each location. These locations can be changed by the program. If they are changed correctly, they can add features to your program. If they are not, the program could crash or produce results that are less than desirable. GET/PUT CHARACTERS When the program contains the locate command, it is getting a character from the screen. This command contains the row and column that you want looked at. It returns the AT ASCII value of the character at that location. Listing 12-1. Locate, Poke, and Peek 10 REM LISTING 12.1 20 REM LOCATE? POKE AND PEEK 30 PEN BY L.M.SCHREIBER POP TAB BOOKS 40 OP A P HICS 0? PEN CLEAR THE SGPEEN 50 ? "ABCBEFGHUKLMNO P Q R S T U V U) X YZ " 60 LOCATE 2 .(KB: POSITION 2»0:? CI-IR$ '"' " % R E n P U T N T R 1... C H ARACTERS IN THIS STRING 60 POKE 766? 1 70 ? "A$ CONTROL CHARACTERS ' ! ?A$ SO POKE 766 vO Line 40 sets aside 20 places for characters in A$. Line 50 places an assortment of control characters into A$. These are - bell, clear, insert character, delete character, cursor down, cursor up, cursor right, cursor left, tab, insert line, and delete line. To print these characters within the quotes, use the escape control keys for all but the last two; use the escape shift keys for those. Line 60 pokes location 766 with a 1. Anytime this location is not zero, the control characters will be printed on the screen as characters. Line 70 prints the contents of A$ on the screen. If you do not clear the screen before running this program, you will see that A$ is printed exactly as it is set in line 50. Line 80 resets location 766 with a 0. Now if you try to print A$, you will get the bell, the screen cleared and all the other control characters executed. OTHER MEMORY LOCATIONS The following list of memory locations are used by the screen editor, display handler, etc, to display information on the screen. They are all located in RAM, so they can be changed under program control. Some values may be immediately reset by the operating system; others will be ignored; and changing some can cause strange results, or make the system crash. Memory Function Location 88,89 This is the beginning of the screen memory. When the contents of these locations are changed, the computer will print in memory other than that being displayed on 174 Memory Location Function the screen. This location was changed in the program Slide Shows (Chapter 9). 675 This byte and the next 14 bytes make up the bit map for the tab. Every bit that is set is a tab. For example, input POKE 675,1 7. Now press the tab key. The cursor will stop under the E in READY— the fourth screen position, and under the space after the Y— the eighth screen position. All tabs can be cleared by this statement. FOR X=675 TO 689:POKE X,0:NEXT X 694 This location sets or clears the inverse flag. If this location is 128, all the characters will be treated as inverse characters. It must be set to for normal characters. This location was used in Chapter 11. 702 This location is set for lower or uppercase letters. If this location is 64, the shift-lock has been set and the characters are uppercase. If it is 0, the characters are lowercase. This location was also used in Chapter 11. 703 This location can only be 4 or 24. If it is 24, it sets the normal screen size. A 4 sets the text window at the bottom of the screen. Poke this location with a 4; then list a program. The entire program will scroll in the bottom four lines of the screen. By experimenting with these locations, you will learn how to create the effects that you need or want for your programs. 175 Chapter 13 Disk Use Convenient program and data storage is provided by the floppy disk system available with the ATARI. By understanding how the computer handles the disks and how the disks themselves are organized, you can better control and utilize the system. DISK FILE MANAGER The file manager provides the commands that allow BASIC to access the disk drive. Up to four drives can be accessed with the manager that conies with the ATARI Disk Operating System (DOS). Throughout this chapter and the next, the ATARI DOS will be used for the examples. If you are using a different DOS on your system, some of the commands or formats may differ. lOCBs The ATARI computer has a portion of memory set aside for input and output control. This area of memory is called the input/output control buffer (IOCB). The memory locations in this area are set for the device(s) that will be handled. This area is not exclusively for the disk drives. It can also be used by the screen editor, cassette, or any other device that can access it. It can also be used under program control. The IOCB stores information concerning the device that is being used, the process that will be performed (writing to the device or reading from it) the length of the buffer that will be written from or read into, and location of the buffer. CIO Functions The central input/output (CIO) functions control most of the disk operations. Each disk operation has its own specific function. Some operations have options that can be accessed by using the correct auxiliary code. Open. The open command can be used to create a new file, append an existing file, or update an existing file. The file can also be opened for a read. To use the open command, you must specify which drive, the name of the file and the option, for example, OPEN #2,8,0,"D:NAMES". The file NAMES would be opened using buffer #2. It is opened for a write only. If a file already exists with that name, it will be written over. If it does not exist, it will be created. Its name will be added to the directory. Using the format OPEN #2,9,0,"D:NAMES" opens the file for an append. The file will not 177 be destroyed. The information sent to it will be placed immediately following the data that is already there. If you use the format OPEN #2,12,0,"D:NAMES", the file will be opened for update. Any part of it can be changed without affecting the rest of the file if the file was created properly. You can also use the open command to read the directory from BASIC by using OPEN #2,6,0,"D:*.*". In the next program, you can read the directory from BASIC and run any program by entering that program's number. Listing 13-1. Directory Listing 10 REM LISTING 13.1 20 REM DIRECTORY LISTING 30 REM BY L.M.SCHREIBER FOR TAB BOOKS 40 DIM DIR$(76S) »BUF$(14) 4 5 D I R $ ( 1 ) ■■■■■■■ " " i D I R $(768) - " " t D I R $ ( 2 ) - D IR$ 5 ? " }■ 1... E A R > " i R E M C I... E A R T H E S C R E E N 6 P E N # 2»6»0v"DJ*.*"}N ~ 1 ! X ■ 1 JREM P E N THE FILE FOR THE DIRECTORY 70 INPUT #2»BUFt!REM GET AN ENTRY 8 D I R * ( X » X '<■ 1 1 ) ™ B U F $ ( 3 » 1 3 ) ! R E M i :: ' I... A C E I T IN THE DIRECTORY BUFFER 9 I F A S C ( B U I- $ ( 1 »D) < 58 AN D A S C ( B U F $ ( 1 9 1 ) ) > 4 7 T H E N N * N - 1 t C I... S E 1 2 ! G T 1 1 1 X =a X •}■ 1 2 ! N ~ N f :l. J G Q T 7 1 1 R » I J C ■ 2 J F R X s ;|. J Q N J P S I T 1 N C + ( NOT INT ( X/10 ) ) *RI? X 5 " , " t DIR$ ( X * 1 2 ■••■ 1 1 ■ X*12) J REM PRINT THE FILE 120 024-CJIF C=2 THEN R-R+1IREM NEXT COLUMN y NEXT ROW 130 NEXT XI REM FINISH DIRECTORY 140 TRAP 140 5 POSITION 2v22;? "ENTER NU MBER OF PROGRAM " ? I INPUT P 150 IF P>N OR P<1 THEN 140 :l. 6 B U F * C 1 ) == " "IB U F * (14) = " "IB U F * ( 2 ) = B U F $ I B U F $ ■■■■■■■■ ""SB U F * :::: " D { " J i :: ' R X ~ P * 1 2 ■■■■ 1 1 T p >k 1 2 ■■■• i s :i: F d :i: R $ c X * X ) ■■■■■■■■ " " T H E N 1 8 170 NEXT XJX=P*12™3 1 8 X - X •••• :!. i B U F $ ( 3 ) = D I R $ ( P * 1 2 •■■• 1 1 » X ) J X :::: I... E N(BUF*) 1 ? X ■■■■■■■■ X -f 1 ! B U F $ i X v X ) = " . * t X ■■■■■■■■ X •}■ 1 i B U F $ C X f X i2)-DIR$0L EAR TENTER THE LENGTH OF A LIN E" i J INPUT PL 50 ? "ENTER THE NUMBER OF LINES TO A P AGE" i {INPUT I...N 60 OPEN #2*Si>0j "R4I " 70 OPEN #1 >4K)» "DSL I STING" 80 L=l 90 TRAP 300 1 FOR Ol TO PL 100 GET #1 cB 110 ? #2 5GHR*CB) ? 120 IF B=1S5 THEN 130 NEXT CJ? #2JCHr 40 "<$< 155) ? 140 L-L+l JIF LBUF#<20 ) »MT*C8 ) »TEMP$< 25) 5 ? " }■ 1... E A R :>• " i P S I T ION 5 > 2 : ? " P L EASE C I -1 S E I " I P S I T I ON 5 s> 4 : ? " 1. ♦ F R MAT N E W DISK" 60 POSITION 5 ? 61? "2, CHECK CALENDER" 7 T R A P 7 ! P S I T 1 N 1. :> Q X ? " "it 1 N P UT CtREM 2 SPACES X 2 LEFT ARROWS TO C LEAR ENTRY SO IE (XI OR C>2 THEN 70 t REM ONLY ACCE PT 1 OR 2 90 ON C SOTO 1<)0»250 1 P K E 752vii ? " > C I... E A R > " I P S I T I ON 2« 10 J? "THIS SELECTION WILL FORMAT A DIS K FOR THE CALENDER PROGRAM. PLACE A" 110 ? "NEW DISK INTO THE DRIVE AND PRE 181 Listing 13-3. Calendar (continued from page 181) SS RETURN ANY OTHER KEY WILL RETUR N YOU TO THE MENU" 120 IF PEEK (764) =255 THEN 120 1 3 I... N - 5 i 1 F P E E K C 7 6 4 ) ~- 1 2 T H E N I... N = 1 5 140 POKE 764 » 255 1 GOTO I...N 1 5 X 1 254» # 1 v » r ' D :l. J " J R E M F R M A T T H E DISK 1 6 l : - R X := 1 T 1 2 i R E A D B U F $ J D A Y $ ( :l. ) - " " J D A Y $ ( 3 ) ■■■■■■■■ " " Hi A Y $ ( 2 ) ~ D A Y * J P E N # 2 9 8 y OoBUFf 1 7 F R D = :l. T 31 s D A Y $ ( 1 ) ~ S T R $ ( D ) ! D A Y $ (30) :::: " " ; p R I N T # 2 ? D A Y $ J N E X T D 180 CLOSE #2? NEXT XJEEM CREATE THE HON TH FILES 1 9 Ii ATA D J J A N U A R Y •> D J F E B E U A R Y v D t M A R C H 9 D i APR I L. » D { MAY i D I JUNE > D I JULY v D S AUGUST 2 D A T A D ! S E P T E M B E E 9 D J C T B E R 9 D t N V E M BER?D J DECEMBER 2 1 P K E 7 52 » * G T 5 250 ? " > C I... i::: A R }■ " l P S I T I ON 5» 1 I ? " E N T E R THE MONTH" 5 J INPUT MT$ 260 TRAP 270 J RESTORE 190! FOR X»l TO 12 : R E A B B U F $ i I F I... E N ( M T $ ) i 2 < = L E N ( B U F $ ) T H EN IF BUF$(3yLEN(MT$)+2)~MT$ THEN 2S0 270 NEXT X J GOTO 50 280 TRAP 280 J? J? " ENTER THE DAY"? 5 INPUT D 290 TRAP 40000: OPEN #2j>4yQ*BUF$tF0R X™ 1 T 3 1 : N T Ii: # 2 v S 9 B 1 1 N P U T ^11^ 2 9 D A Y $ 3 I F A I... ( D A Y $ ( 1 y 2 ) ) < > D T H E N N E XT Xi C LOSE #2 IGOTQ 50 310 CLOSE #2 320 ? " :>■ C L E A R > " i ? " D A T E R E Q U E S T E D - " ? MT$5" " n:i 330 ? J? DAY* 340 ? :? "PRESS K-TO KEEP INFORMATION & RETURN TO MENU" 350 ? I? "PRESS U-TO UPDATE INFORM AT 10 N " 360 ? t? "PRESS D-TO REVIEW ANOTHER DA TE" 370 P III: N #2 1 A f r " K f ■ J G E T # 2 9 C i C I... S E ll^ 2 380 IF C>1 27 THEN C-0 128: POKE 694 y(> 390 IE C-75 OR O107 THEN 50 182 400 IF C-85 OR Oil? THEN 450 410 IF 068 OR C=»100 THEN 250 420 GOTO 370 450 ? {? "PLEASE ENTER NEW INFORMATION 460 T E M P $ ( :l. > ~ " " I T E M P * ( 2 5 ) ~ " " { T E M P $ ( 2 ) = T E M P $ 1 I N P U T T E M P $ J I F I... E N ( T E M P $ ) < > 2 5 THEN TEMP* (25)=" " 4 70 ? "VERIFY - THIS IS CORRECT " 4 8 P E N # 2 r 4 r r " K I " i G E T # 2 y C I C L S E # 2 490 IF OJ.27 THEN 00.128 J POKE 6 94^0 500 IF C--89 OR C-121 THEN 530 510 IF 078 OR C--110 THEN 450 520 GOTO 470 530 D A Y $ ( 4 ) ~~ T E M P * i D A Y $ ( 3 ) « » " ? R E M S T RE THE NEW INFORMATION 540 P E N # 2 1 1 2 v v BIJ F $ J P 1 N T # 2 » S t B J R E M RE -OPEN THE BUFFER AND POINT TO THE S ECTOR 550 ? #2$ BAY* J CLOSE #25GOTO 50 J REM STO RE THE INFORMATION ON DISK Line 40 sets aside space for the strings. DAYS will hold the day's activity. BUF$ is used as a buffer for the disk file name. MT$ is the month and TEMP$ holds information temporarily. Line 50 clears the screen and places the first menu option on the screen. Line 60 places the second menu option on the screen. Line 70 places a question mark on the screen and waits for an entry. The trap will keep the program from crashing as a letter or other character is entered. Two spaces and two left arrows are printed before the input. This will erase the entry if the program does not accept it. Line 80 checks the value of C. If it is not a 1 or 2, the program will return to line 70. Line 90 branches to the correct routine. Line 100 removes the cursor and clears the screen. It prints part of the message on the screen. Line 110 prints the rest of the message on the screen. Line 120 waits until a key has been pressed. Line 130 sets the variable LN to 50. This is one of the two lines that the program can be directed to. If the return key was pressed, the value of LN changes to 150, the other line number. Line 140 clears the key input and sends the computer to the correct line. Line 150 formats the disk. It is very important that the disk in the drive does not have programs that you want to keep on it. When the disk is formatted, all the information on the disk will be erased. Lines 160-180 place the files for the months on disk. The X loop goes from 1 to 12. The month is read into BUF$. The contents of DAY$ are cleared, and the file is opened with the name that is in BUF$. Line 170 begins the second loop. This loop places a buffer for each day of the month on 183 the disk. The first byte(s) of the DAY$ contains the number of that day. The last byte is set to a blank space. The entire buffer is printed to the disk. After all the days have been printed to the disk, the file is closed and the X loop continues. Lines 190-200 contain the months in the format needed to open files on the disk. Line 210 puts the cursor back on the screen and returns to the main menu. The disk is now set up as a calendar. Line 250 begins the calendar routine. The screen is cleared, and the message to enter a month is placed on the screen. Line 260 restores the data line and begins the for.... next loop to look for a match between the month entered, and the months on file. The contents of BUF$ beginning with the third byte is compared to the contents of MT$ (the month entered). If a match is found, the computer goes on to line 280. Line 270 continues the loop if no match is found. If the month cannot be found because of a spelling error, the program goes back to the main menu. Line 280 waits for a day to be entered. All the files are set up for 31 days. The entry here is not checked for a correct day. If you need more days in your year, here's your chance to lengthen February! Line 290 clears the trap. The file for the month specified by BUF$ is opened for a read. The loop gets every day from 1 to 31. The program has no way of knowing where in the file the day is located. The note command places the sector number of the day being read into the variable S. The first byte of the day is placed in B. Line 300 checks the day in the buffer against the day entered. The loop continues until the days match. If no match is made, the file is closed and the program returns to the main menu. Line 310 closes the file if the days match. Line 320 clears the screen and prints the month and day entered on the screen. Line 330 places a blank line on the screen, then prints the contents of DAY$. Lines 340-360 print a mini-menu. If you want to keep the information that is on the screen and return to the main menu, press K. If you want to change the information, press the U. Press D if you want to check another date. Line 370 opens the keyboard for a read. When a key is pressed, the keyboard will be closed. Line 380 checks the value of C. If it is greater than 127, the inverse or ATARI key has been pressed. 128 must be subtracted from the value of C. A zero is poked into memory location 694 to reset the flag for normal text. Lines 390-410 check the value of C. If it is a K, the program will return to the main menu. If it is a U, the program will continue with line 450. Entering a D will send the computer back to line 250 for another entry. Line 420 will send the computer back for another entry because the key that was pressed was invalid. Line 450 issues a blank line, and then asks for the new information to be entered. Line 460 clears any previous information or garbage from TEMP$. It then waits for a new input. If the length of the input is less than 25, the last character of the string will be set to a space. Line 470 asks you to verify what you typed. Line 480 opens the keyboard for a read. Once a key has been pressed, the keyboard will be closed. Lines 490-520 check the value of C. If a Y or an N was not entered, the program will loop back for another entry. If an N was pressed, the program will go back to line 450 for a new input. If the 184 entry is correct, the program will continue with line 530. Line 530 places the information from TEMP$ into DAY$. The last byte of DAY$ is set to a space. The disk is fielded for 30 bytes per record. If fewer bytes are sent back to the disk, the pointers would be changed, and we could not retrieve information from the disk. Line 540 opens the file in BUF$ for read/write or append. The point command is used to set the pointer to the correct sector and byte. The information in DAY$ must be placed back on the disk in the exact spot that it was taken from. Line 550 prints DAY$ to the disk and closes the buffer. After each update, the routine will return to the main menu. DISK HANDLER Another way to access the information on the disk is by using the disk handler. The disk handler is twelve bytes long and can transfer one sector (128 bytes) of data to or from the disk. In order to transfer the information, the disk handler must be set up by the program. The disk handler begins at memory location 768. It must contain the number of the disk drive that will be accessed, the command byte (get sector, put sector, format, or status request), the buffer address, and the number of the sector to be accessed. The next program will load in.a specified track from a disk and display it as characters on the screen. The characters can be changed, and resaved onto the disk. This program will not allow you to change the data on the disk, just to look at it. It will tell you the status of the track. If the status is not OK, it is a bad track. Either the information on it got scrambled, or it was made into a bad track for copy protection purposes. Listing 13-4. Displaying Sectors 10 REM LISTING 13.4 20 REM DISPLAYING SECTORS 30 REM BY L*M,SCHREIBER FOR TAB BOOKS 4 D I M B U F F E R $ ( 1 28 > s D R O U T * < 5 ) 5 B I J F F E R $ ( 1 ) = " " I B U F F E R $ ( 1 2 8 ) :::: " "IB I J F F E R $ ( 2 ) = B l J F F E R $ S R E M C I... E A R T l-l E B U F F E R 60 FOR X=l TO 5 {READ B JDR0UT* »CHR $(B) J NEXT X 65 DATA 1 04 » 32 p83 t 228*96 7 A D D R ~ A D R < B U F F E R $ ) i R E M D E C I M A L A D D R E SS OF BUFFER* 8 B U F l-l I :■■■■■■ I N T < A D D R / 2 5 6 ) i R E M l-l I G l-l R D E R BYTE 9 B U F I... -•= A D D R - ( B U F l-l I *256 ) t REM L W R D E R BYTE 1 D C B ~ 76 8 J R E M D I S P LAY C N T R 1... C H AR AC TERS - SET DEVICE CONTROL BLOCK 1 1 P K E D B f 1 i 1 I R E M B R I U E # 1 120 POKE DCB+2»82JREM GET SECTOR 130 POKE DCB + 4vBUFI...0JREM BEGINNING OF BUFFER - LOW ORDER ADDRESS 185 Listing 13-4. Displaying Sectors (continued from page 185) 140 POKE BCB+5»BUFHI J REM BEGINNING OF BUFFER ■- HIGH ORDER ADDRESS 150 POKE 766 *0 STRAP ISO J? "INPUT BE CIO R NUMB E R " 9 i I N P U T S E C T R t P K E 766,11 R E M GET A SECTOR NUMBER 160 SECTORH 1> I NT ( SECTOR/256 ) ; REM GET H IGH ORDER BYTE OF SECTOR 1 7 S E C T R I... ■■■■; S E C T R - ( S E C T R H T. * 256 ) i R E M GET LOW ORDER BYTE OE SECTOR 1 8 P K E D C B ■■}■ 1 t S £ C T R I... 1 R E M S T R E I T 190 POKE DCB+U» SECTORH I 200 X ■■■■■■-■ U S R < A D R ( D R U T * ) ) J R E M C A I... I... T H E ♦ S« ROUTINE TO READ DISK 210 DSTAT^PEEK(DCBi3) {REM GET THE STAT U S 220 ? " D I S K S T A T U S ~ " ? D S T A T i J I F D S T A T ~ 1 THEN ? " •••■ OK "{GOTO 240 230 PRINT {REM PRINT SECTOR INFORM AT 10 N ON NEW LINE 240 ? " S E C T R D AT A t " t ? B U F F E R $ 2 5 G T 1 5 260 END Line 40 sets aside space for two strings. BUFFER$ will contain the data in the sector. DROUT will contain the address of the machine language subroutine in the operating system that will use the disk handler. Line 50 clears the buffer. Line 60 reads the machine language subroutine into 0R0UT$. This subroutine is a jump to a subroutine in the operating system. We need this subroutine to access the operating system subroutine because we are accessing this subroutine through BASIC. The first thing that the subroutine must do is pull a byte off the stack. If we accessed the routine directly, it would not return properly since the byte would not be pulled off the stack. Line 70 places the decimal address of the first byte of the buffer into the variable ADDR. Line 80 divides this number by 256. This integer is the high order address of the string location. Line 90 subtracts this number from the address. This gives the low order address. Line 100 sets the variable DCB to 768, the beginning of the device control block, and pokes location 766 with a 1. Now if there are any control codes in the sector, they will be printed on the screen. Line 110 pokes the second byte of the device control block with the number of the drive that will be read. Line 120 pokes the next byte with the command byte. 82 is the command to get a sector from the disk. Lines 130-140 place the low order and high order byte of the address into the device control 186 block. This address is the beginning of BUFFER$. Line 150 asks for a sector number. The trap is set for inputs that are not numbers. The sector number will be stored in the variable SECTOR. Lines 160-170 divide this number for the low order and high order bytes. Lines 180-190 place these bytes into the correct addresses of the device control block. Line 200 calls the machine language subroutine that calls the operating system's disk interface routine. Line 210 checks the status of the sector read. Line 220 prints the status of that sector. If it is a 1, the sector was read incorrectly. Line 230 forces a line feed to the screen. There is a semicolon after the status value in line 220. If the status was not OK, the line feed would not occur. Line 240 prints the sector on the screen. Some sectors look like they are displaying garbage on the screen. Others are a string of hearts, and still others are perfectly readable. Line 250 sends the program back to line 150 to get another sector to be displayed. Press the break key when you are finished displaying sectors. The following list shows which bytes are used for the DCB and which commands could be used. Address Function 769 This byte is set to the number of the drive that will be accessed (1-4). 770 This is the command byte. The commands are: 82-get sector; 87-put sector with verify; 83-status request; 33-format disk. 771 This is the status byte. After a successful read, this byte will be a 1. 772-773 This is the buffer address that indicates where the data will be placed or taken from. 778-779 This is the number of the sector that the routine will access. The sector could be written to or read from. FILE MANAGEMENT SYSTEM In addition to the disk file manager, there is also a file management system. This governs the format of the disk, the location of the boot record, the file directory, the volume table of contents, and any other information needed to keep files on a disk. If any or all of the files that the file management system (FMS) uses are destroyed, the disk may not boot, copy correctly, or read in the files. By understanding how the files are structured on the disk, bad sectors can be fixed; the table of contents can be altered; and files can be deleted or restored without using the disk file manager. Track Format When a disk is formatted, all the data on the disk is erased. There are 720 sectors on the disk. Every byte in every sector is set to 0. The first sector of the disk is reserved for the boot record. If there is no boot record, the disk will not load from a cold start. When DOS is written to the formatted disk, the boot record is written to the disk along with the DOS and DUP files. When the disk boots, it brings DOS into the computer. When a file or record is sent to the disk, it may require one or more tracks. The FMS begins with the first available sector and stores the program on subsequent available sector. The key word here is available. If, for example, a program used two sectors for storage; the next program 187 used four; and the third used five. Now, you delete the second program from the disk. Those four sectors are available for another program. The next program that you write needs 10 sectors. The FMS uses the first four sectors from the deleted program and the six sectors after the third program. How does it know where the rest of the program is??? Every sector of every program has its own linking bytes. There are 128 bytes in every sector. Bytes 1-125 contain the data for that sector. It could be a program listing, a file, or whatever else was saved to the disk. The 126th byte contains the file number. Every sector that pertains to this program will have the same file number. If there is a mismatch between file numbers, an error 164, file number mismatch, will occur. Byte 127 is the forward pointer. It contains the sector number for the next sector that has more data for this file. It usually is, but does not have to be, the following sector. This is how the computer knows where the rest of the program is. If sectors 4-8 are used for a program and the next available sector is 14, the number 14 will be stored in byte 127 on sector 8. When the computer finishes reading in the data from sector 8 it will continue on to sector 14 and skip sectors 9-13. If this is the last sector for the file, this byte will be 0. Byte 128 is the byte count. It contains the number of bytes that should be read in from this sector. A full sector contains 125 bytes. Anything less than 125 is considered a short sector. If you use the Displaying Sectors program from this chapter, you can examine the sectors of the disk and see how the sectors are linked. Volume Table of Contents When you want to save a program onto the disk, the computer has to know where there is room to save it. It can't sit there and examine every sector on the disk to decide whether or not the program should be placed there. Sector 360 is the volume table of contents (VTOC). Use the Displaying Sectors program to examine this sector. Now examine a newly formatted disk. The VTOC for the disk that has been used should have a string of hearts, with some inverse insert characters. The disk that was just formatted is almost filled with the inverse insert characters. This is a bit map that tells the computer which sectors have been used and which ones are empty. The fourth and fifth bytes of this sector indicate how many sectors are available. On a new disk these two characters should be an inverse C and a control B. This is a two byte number: 2*256+195=707 free sectors. On a used disk, this number will vary. If the 4th and 5th bytes are set to 0, the computer would think that the disk is full. The bit map begins with the 11th byte or character. On the new disk, this byte will be 15, the character will be a control 0. The next 44 bytes are inverse insert characters (ATASCII 255). The 45th and 46th bytes are a heart and insert character. The next 43 bytes are inverse insert characters (ATASCII 255). Every time something is stored on the disk, this sector is checked. If the bit is a 1, then the sector is free and the information can be placed in that sector. The bit in the bit map is then set to 0. The 45th and 46th bytes are sectors 360-368. These sectors are reserved for this VTOC and the directory. If the directory sectors are changed to ones, they could be written on. The computer would not be able to list a directory or load or store programs. FILE DIRECTORY FORMAT Beginning with sector 361, the computer keeps the names of the programs on the disk. There are sixteen bytes used for each entry. Up to eight names can be stored on each sector. There are eight sectors set aside for the directory. Up to 64 files or names can be stored on a disk. This 188 means that even if there are free sectors on the disk, the disk will not hold more than 64 programs or files. Look at sector 361 using the Displaying Sectors program. You should see up to eight file names. Before each name, there are some characters. The first byte of the file name is the flag byte. If this character is a B, the file is available. If it is a b, the file is locked. If it is an inverse heart, the file has been deleted. The next two bytes contain the sector count. The second byte is the low byte, the third, the high byte. Multiply the AT ASCII value of the third byte by 256, and add the ATASCII value of the second byte to find out how many sectors are used for the file. The fourth and fifth bytes contain the sector number at which this file starts. Again, this is a two byte number with the low byte first and the high byte second. Use the ATASCII values of these characters to find out which sector the file begins in. The next eight bytes are the name of the file. The last three are the extender. There is no period separating the name from the extender. When the directory is read into the computer, the period is added by the program. If the file name or extender contains more characters than there is space for in the directory, the extra characters will be ignored. Table 13-1 shows the format of the file directory. BOOTING YOUR OWN DISK When you place a disk into the drive, and turn on the computer, the drive turns on and a program boots. This program could be the DOS or another program. Most commercially available machine language programs will boot themselves when you turn the computer on. BASIC programs are usually loaded into the computer. AUTORUN.SYS You may have noticed a program on your ATARI disk called AUTORUN.SYS. If you examine the disk directory from various software firms, you may find the AUTORUN.SYS is anywhere from one to three or more sectors long. You may have also found that when you write DOS to a new disk, the AUTORUN.SYS does not get written to the new disk. It has to be copied. Table 13-1. File Directory Format. 12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 b ' :: ; t e 1 f 1 a b b u t e b wte 2 83 s e c t o r c a u n t b y t & 4 S 3 s 1 8 r t :i. n s s e c t a r b y t e? 6 ■■■■ 1 3 f ' :i. 1 e n s in e byte 14-16 extender 189 The purpose of the AUTORUN.SYS is to give the programmer a way to boot a program or load a machine language program into the computer during the boot process. Let's say that you have a machine language program that will disable the break key. You want this program executed immediately when the system is turned on. If the program had to be loaded by the user and executed, chances are it wouldn't be done. A short routine could be inserted into your BASIC program to load and execute this routine, but this would take up memory space and time. When you turn your computer on and DOS is loaded in, it checks to see if there is a program on the disk called AUTORUN.SYS. If there is, it loads this program and executes it before it turns control over to the user. The AUTORUN.SYS program must be written in machine language. It cannot be a BASIC program. In the following program, you will create your own AUTORUN.SYS. It will change the right and left margins on the screen, and the background color before BASIC takes over. Listing 13-5. AUTORUN.SYS 10 REM LISTING 13.5 20 REM AUTORUN.SYS 30 REM BY L.M.SCH REISER FOR TAB BOOKS 4 P E N # 2 y 8 » j " D J A U T R U N , S Y S " % R E M P E n the;: buffer to write the new autorun 50 rut #2* 255 x put #2 r 255 1 rem leah i no b YTES 60 RUT #2*0 {PUT #2 t 6 I REM STARTING ADDR ESS 7 i :: ' U T # 2 » 1 3 J P U T # 2 ? 6 i R E M E N D I N G A D D R E SS 80 FOR B»l TO 14; READ DJREM GET THE DA TA FOR THE ROUTINE 90 PUT #2 I'D J REM RUT IT IN THE BUFFER 100 NEXT BJREM CONTINUE THE LOOP 110 PUT #2? 226 t PUT #2? 2 {REM AUTO ADDRE 1 2 P U T # 2 v 2 2 7 I P U T # 2«2iR E M S T A R T F R M THIS ADDRESS 1 3 P U T # 2 1 J P U T # 2*6* R E M S T A E T I N G A D D RESS 140 CLOSE #2 {REM CLOSE THE BUFFER ••■ PR GGRAM GOES TO DISK 150 END 200 DATA I A9?Sf i 3 3 y 02 v 1 6 ! > : ? 30 » 1.3 3 ? 33 •> 16 9»208» 141 ■/ 198y2s- 96 Line 40 opens the disk buffer to write to the disk. The name of the program is AUTO- RUN.SYS. If there is a program by that name on the disk, it will be replaced by this one. Line 50 puts the first two bytes of this program into the disk buffer. The first two bytes of any machine language program is 255. 190 Line 60 places the beginning address of the program into the buffer. The machine language program will begin at memory location 1536 (600 hex). Line 70 places the ending address of the program into the buffer. The machine language program is 14 bytes long, so the ending address will be 1549 (60D hex). Line 80 begins the for.... next loop that reads the machine language program into the disk buffer. There are 14 bytes in this program. Line 90 puts each byte into the buffer. Line 100 continues the loop until all the bytes have been read and placed into the buffer. Line 110 puts the low order address of the autorun routine into the disk buffer. Line 120 puts the high order address of the autorun routine into the buffer. Line 130 puts the beginning address of the machine language program into the buffer. This is the address that will be put into the preceding addresses. For a program to load and run, the running address must be stored in memory locations 738 and 739. Line 140 closes the disk buffer. When the buffer is closed, its contents will be sent to the disk. Line 200 contains the machine language program that will be run when the disk is booted in. After you enter this program, run it. Be sure that the disk that is in your drive does not have an AUTORUN. SYS on it or it will be destroyed. It is best to have a new initialized disk in the drive. The DOS must be on the disk. When you run the program, the disk will turn on and you can hear the program being saved to the disk. After it is saved, turn the computer off and then turn it back on. You will hear the disk boot in. The cursor will move to the right and the screen will turn black. The word READY will appear in green. If you load in a program and list it, you will see that your margins have moved. See Table 13-2 for the machine language listing of the program. Boot Record The AUTORUN. SYS is one way to load and execute programs. But, what if you are writing programs in machine language, and you do not want a directory on the disk, but do want the program to load and run when the disk is turned on? In the last chapter, we discussed how the disk was structured. The first sector is called the boot sector. This is the sector that the computer will look at to bring in a program from the disk. If you copied the DOS on the disk, you have the ATARI boot on this sector. It will bring in the DOS. If you placed your own boot on this sector, it will bring in whatever program you want it to. This is not something that can be easily accomplished from BASIC, but that's not to say that it can't be done. If you are ready to place your own boot records on the disks, you must have a good understanding of assembly language and how the boot process works. In this chapter, we will only describe the boot process. The boot sector has its own specific format. The first byte is stored in memory location 576. It is not used by the boot and should be set to a zero. The second byte tells the computer how many sectors are in the boot. It should include this sector. This number can be any number from 1 to 255. If it is 256, it will be set to zero. The third and fourth bytes tell the computer where to start loading the program. This does not have to be where the program begins, just where to start loading the file. The fifth and sixth bytes tell the computer where the program begins. After all the sectors for the boot have been loaded, the computer has to know where it should transfer control to. This address will be the beginning of the program. The third and fourth bytes and the fifth and sixth bytes are two byte addresses. Be sure that the third and fifth bytes contain the low order address and the fourth and sixth bytes contain the high order address. 191 Table 13-2. Machine Language Routine for AUTORUN.SYS. d e c i in a .'1. c ode as b < * m b 1 a 1 a n 3 u a si e 1 i s I i n <■! 169 i::; LDA #5 yLoad the accumulator with r.:- 133 ST A 8 2 9 S t o r e :i. t i n 1 o c 3 1 i o n 8 2 . 82 , 169 LDA # 3 5 1... o a d t h e a e c u m u 1 a t o r w :i. t h 30. 30 133 ST A S3 y Store it :i. i"i location S3. 83 169 • LDA #208 J Load the accumu'l a tor with 208, 208 1 4 1 ST A 7 1 5 S t o r e i t i ri 1 o c a t i o n 7 1 » 198 2 96 RTS J R e t i.j r n f v o iri t h e r' o u t i n e » The following is an example of the structure of a boot record. It is not the complete record. ignore 3 number of sectors in boot low order address 7 high order address— place boot here 64 low order address 21 high order address for initialization 76 jump to following address 20 low order byte 7 high order byte 3 ?? 3 ?? ?? 124 ?? 26 ?? 1 data— loads into the Y register 24 192 125 203 data 7 172 load the Y index use-next address 14 low order byte for address 7 high order byte for address 240 branch if it's 54 ahead 54 bytes This portion of a disk boot shows how the information in the first sector is used. The first byte (0) is ignored. The second byte indicates how many sectors are in this boot. This number is stored at location 577. The next two bytes are stored at locations 578 and 579. They tell the computer where this boot should begin. The first six bytes and all the byte following will be moved to the location in memory beginning with the address specified here. The next two bytes are the initialization bytes. After the boot is executed, the address in this memory location will be jumped through. The next instruction in the boot is a jump. Once the three sectors have been moved into memory the computer will perform a jump subroutine. The address that it will jump to is the sixth address after the beginning address. In this case it is location 1798 (706 hex). The instruction at this address is to jump to memory location 1824 (720 hex). At this location, the computer will load the Y index with the value stored at 1812 (714 hex). If the value is zero, the computer will move ahead 54 bytes. If we count 15 bytes down in the table, we will see that the value at that location is a one. The computer will proceed to the next instruction. The boot process then consists of: 1. Reading the first sector and storing the first six bytes, which indicate the number of sectors, the load address, and the initialization address. 2. Placing the boot sectors into memory beginning with the location specified in the third and fourth bytes of the boot sector. 3. Jumping to the subroutine that begins in the seventh location after the beginning of the boot. 4. Jumping through the subroutine whose address is stored in locations 12 and 13 (fifth and sixth bytes of the boot record). 5. Transferring control to the program by jumping to the address in locations 14 and 15. The machine language program loaded into the computer will now be fully operational. If the addresses are set correctly when system reset key is pressed, the program will restart itself. If they are not, the drive may turn on and the computer may try to boot the program again, or the computer will go to BASIC or the memo pad. 193 Chapter 14 Cassette Use Like the disk, the cassette is a convenient form of storage that can be utilized more effectively when the way the computer handles it, and its physical structure are understood. THE CASSETTE HANDLER The cassette handler is similar to the disk manager. Files can be written to or read from the cassette. The buffer can be opened for get and put commands. Programs can be loaded using BASIC or using an autoload command. However, there are some important differences between the disk and cassette. The cassette can only read and/or write data to the portion of tape under the recorder head. Files cannot be stored or retrieved from just any position. When a program is saved to the cassette, it is saved in one continuous stream. There is no positioning of the head. You cannot specify tracks like you can point to sectors and bytes on the disk. Likewise, you can only read what is passing under the cassette head. You cannot point to only one section of tape like you can read in one sector from the disk. The cassette is, however, a fairly reliable way to store and retrieve information. Format of Data If you have a recorder, save a program to it. It doesn't have to be very long— four or five lines will do. After the program is saved, rewind the tape and enter these commands in the direct mode: OPEN #7,4,0,"C:":FOR X=l TO 128:GET #7,B:? B;" ";:NEXT X:CLOSE #7 This opens the cassette for a read. Now press the play button on the recorder and the return key on the keyboard. You will hear one tone. Press the return key again. After you hear a record of data being read in, you will see numbers being printed on the screen. This is the code for the program that was saved. The computer is printing it from the cassette buffer, in the same manner as it was printed from the disk buffer. Now enter this without clearing the screen: FOR X=0 TO 130:?PEEK(1021+X);" ";:NEXT X 195 The first three bytes that are printed on the screen are different from the first three bytes that were printed from the buffer. But, if you compare the first byte of the buffer with the fourth byte, you will see that both number patterns are identical. Memory location 1021 begins the cassette buffer. The buffer is 131 bytes long. The first two bytes in the buffer are 85. These two bytes are fixed and are used by the computer to measure the speed of the cassette. The third byte is the control byte. If this byte is 252, the record is full— 128 bytes. A 250 in this position indicates a partially full record and a 254 is an end of file record. The first bytes after the speed and control bytes for the first record consist of the table entries. This includes the variable table, the value table, etc. The values are adjusted by the amount of memory in your machine. This is why a program that requires more storage memory than your machine has will produce an error message immediately when you try loading it rather than half way through the load. The last byte that the computer reads from the cassette is a checksum. When the program was saved to the cassette, every byte that was sent to the cassette in the 128 byte record was added to the previous bytes. The two markers are also included in the addition. After the two markers, the control byte, and the record were sent to the cassette, the sum of the bytes were also sent. When the records are read in, the bytes are added together again. If the sum of the bytes match the checksum byte that is read in, then the record is assumed to be correct and the computer will continue with the loading process. If the two bytes do not match, the load will stop and an error message will appear on the screen. Cassette Frames Each record of 128 bytes is considered a frame. The speed at which the data is sent or received is called the baud rate. The ATARI uses the baud rate of 600. This means that 600 bits are sent per second. (Each byte is 8 bits). The two marker bytes are read in by the computer. The computer determines how long it took to read them in and calculates the correct baud rate for the tape. It does this with every frame of data that is read in. The input baud rates can be adjusted to read faster or slower. This adjustment process allows for variations in motor speeds, stretched tape, etc. It does not, however, allow for alignment problems between the recorder that the program was originally saved on and the one that it is being read on. You may have noticed that when you CSAVE a program to cassette, the records seem to be sent faster than when you use the list command. There are two different modes that the computer can use when sending records to the cassette. One is called the normal IRG (Inter-Record Gap), and the other is the short IRG. The computer uses the short IRG for the CSAVE and CLOAD commands. The computer reads in the record, checks the checksum, places it in RAM, and goes back for another record. The recorder is running the entire time. The computer must do its work quickly so that it won't miss the next record. When the computer uses the normal IRG for saving records to the tape, the recorder stops after every record is read into the computer. The information can be processed; then next record can be read in. The baud rate for saving and reading the data is the same for both modes. It is the time between records that varies. In the normal mode there is about 3 seconds of tone between records. In the short mode there is about Vi of a second of tone time between records. The IRG is set up by the computer when the save or load command is entered. If the wrong command is entered for the tape, the program will not load and an error message will be displayed on the screen. 196 BOOTING YOUR OWN CASSETTES There are two different ways to make your cassettes load and run automatically. The first way is with a BASIC program. A short boot program is saved to the tape. Then, without moving the tape, the second program is saved to the cassette. By using the RUN "C:" command, the boot program will load, run, and load in the second program. The following program is a short boot program that will load and run a second program. Listing 14-1. BASIC Boot Load 10 REM LISTING 14,1 20 REM BASIC BOOT LOAD 30 rem by l*m.schreiber EOR TAB BOOKS 4 Q R A P H I C S t P K E 7 1 ? 1 1 4 I P K E 712? 1 1 4 50 POKE 65 *0 t POKE 752*1 6 POSITION 23*2 J? "copyright 1983" 7 P S 1 1" 1 N 1 3 v 1 J ? " N a w 1 o a d :i. n <■!. " 5 P S I TION 1 K.l 80 POSITION 15* 16 J? "your name" 90 COLOR 35? PLOT 10*7tDRAWT0 27* 7 t DRAW T 2 7 v 1 8 t D R A W T 1 s> 1 3 ♦ D R A W T 1 y 7 I C 1... 32? PLOT 2*20 1 P K E 7 5 2 » ? P K E 7 6 4 ■> 1 2 1.10 RUN "C? " Line 40 sets the graphics mode to 0. The graphics mode must be set before plots and drawtos. The background color and border colors are changed. Line 50 pokes 65 with a 0. This will turn off the noise channel and you won't be able to hear the program loading. This line also removes the cursor from the screen. Line 60 prints the copyright notice on the screen. Lines 70-80 prints your message on the screen. Line 90 sets the color to 35. This is the AT ASCII value of the pound sign. Using the plot and drawto commands, a border is drawn around your message. Line 100 turns the cursor back on and places a carriage return in the location that holds the last key entered. Line 110 executes the RUN "C:" command. You won't have to press the return key because the code is already poked into location 764. The program that is saved on the tape after this boot program had to be saved using the SAVE "C:" command. If it was CSAVEd, this procedure won't work. If you want the next program to load in only, and not run, change line 110 to CLOAD, and be sure that the program that you want to load was CSAVEd to the cassette. The noise location was set to zero in this program so that music or instructions could be heard over the television speaker. This command is not needed if you will not be using the second track on the cassette. 197 Boot Record If you wrote a machine language program that you want to load in from cassette without using the editor/assembler, you need to write a boot record as the first record of the cassette program. The boot record for the cassette is almost identical to that for the disk. There are six bytes for the first record of the boot. The first byte is ignored. The second byte contains the number of records that should be initially read. The third and fourth bytes contain the address where the boot records should be stored. The fifth and sixth bytes contain the address that should take control of the program after the boot is completed. The following is the partial coding of a machine language program's boot record. ignore 32 number of records 191 low order memory load address 11 ' high order memory load address 184 low order initialize address 27 high order initialize address 169 load the accumulator with next byte 60 141 store it in the next address 2 low order address 211 high order address 169 load the accumulator with next byte 3 141 store it in the next address 15 low order address 210 high order address The computer will ignore the leading zero. The next number, 32, is the number of records that will be read in. This value will be saved. The computer will begin storing these records at location 3007. The fifth and sixth bytes will be stored at memory locations 2 and 3. After all the records are read in, the computer will issue a jump to the subroutine at the seventh byte loaded in. This byte will load the accumulator with 60 and store this value at location 54018. This shuts off the cassette recorder. The program continues. When it has returned, the computer will jump through the initialization routine. The address for this routine was stored in locations 2 and 3. Once the initialization is complete, the computer will jump through the address at location 14-15 and begin the program. Although it is possible to write a BASIC program that will load and automatically run a machine language program, it really should be done using the editor/assembler. The procedure to load a cassette with a machine language boot on it is: Turn off the computer. Hold down the start key and turn the computer on. When you hear the single tone, press the play button on the recorder and press the return key on the computer. The records on the tape must be created using the short mode for it to load properly. 198 USING THE CASSETTE WITH SOUND In the last program, we used a BASIC boot program to bring in the program. Using the RUN "C:" command, the computer loaded in the first program and ran it. This program contained the instruction to either CLOAD or RUN "C:" the next program on the tape. It also poked the memory location that directed the sound of the data so that the program loaded silently. The ATARI recorder is a stereo recorder. Most other computers use a monaurial recorder. With a monaurial recorder, the computer places two tracks of data on the tape, one track on one half and one on the other. With a stereo recorder, the computer only uses half of the track for data. A stereo recorder places four tracks on each tape, two on one half of the tape and two on the other. See Fig. 14-1 for the data tracks. The other two tracks on the tape are left blank. They can have sound or spoken instructions on them if you have the facilities to record and duplicate stereo tapes. The procedure is fairly simple, but it does require some planning and timing. First, load the BASIC boot program into the computer. Save it to a new cassette using the SAVE "C:" command. After the BASIC boot program has been saved to the cassette, load in the program that you want to save. If you have a disk drive, you can load the program in from the disk. If you have only a cassette recorder, carefully remove the new cassette from the recorder and place the cassette with the program on it in the recorder and load it into the computer. You want to handle the cassette with the new program on it carefully because the tape is in position for the second program. If you rewind the tape, you will be saving the program over the BASIC boot program. If the tape advances too far, there could be a loading problem. Once the second program is loaded into the computer, it can be saved to the new tape with either the SAVE "C:" command or the CSAVE command. If your boot program is using the RUN "C:" command, then use the SAVE "C:" command and the second program will run immediately after it is loaded in. If your BASIC boot program uses the CLOAD command, CSAVE your program to the cassette. After the second program has been saved, rewind the cassette, type RUN "C:", press the play button on the recorder and the return key on the computer twice. If you have not poked left track - audio r :i. s! h 1 t r a c k - d a t a risiht track ■■■■ data left track ■•■• audio Fig. 14-1. Track formats on cassette. 199 location 65 with a 0, you will hear the BASIC boot program load in. The screen will change colors and display your message on the screen. The tone will sound and the computer will begin to load in the second program. You don't even have to press the return key. The BASIC boot program did it all. Now listen to the program load. If you can hear it, you either didn't have a POKE 65,0 in the boot program, have a problem with separation in the cassette recorder, or have very good ears. The only sounds that should come through the television speaker are the sounds recorded on the left track. Since we did not place any sounds there, you shouldn't hear any. Adding Sounds or Instructions In order to record sounds, music, or instructions on the left track, you need a stereo cassette recorder/duplicator. Place the cassette into the recorder and listen to it. First you will hear a pure tone. Then you will hear the date. Each record is separated by the pure tone. The BASIC boot program will be about four or five records long. The last record of this program will have a slightly different sound. After listening to the records several times, you will be able to tell the difference between the program records and the ending record. After the last record for the first program, you will hear the pure tone again for a longer period of time before you hear the first record. This is the tone that the computer sends out before it starts to send the program. It seems longer here because there is no leader tape between the first and second program. This is where you should start the music, sound, or instructions on the left track. Place a new tape into deck B of the recorder/duplicator. Place the tape that you have just saved the two programs on into deck A. Press the play and record buttons for cassette B and the play button for cassette A. If you are using a microphone, be sure that it is connected to the left track. If you will be recording music directly, be sure that your patch cord is plugged in for the left channel. Listen to the cassette as it is being duplicated from deck A to deck B. When you hear the tone for the beginning of the second program, you can begin speaking, playing the music, etc. Be sure to stop recording on the left track just before the last record. Otherwise, the recorder will stop loading in the program and you will not hear the remaining words or music. Rewind both cassettes, remove the newly created cassette from deck B and place it in your program recorder. Type RUN "C:" and press the return key. This time when the second program loads into the machine, you should hear your music, instructions, or whatever you recorded on the left track coming through the television speaker. Because of the speed variances between recording machines, head alignments, and the nature of cassettes, you may have to repeat the duplication process before you create a tape that will load. This process cannot be used with a high speed tape duplicator. Voice Synchronization Another use for the cassette recorder is for voice synchronization. Poking memory location 54018 with 52, turns on the motor on the recorder. Poking that location with a 60 turns the motor off. The following program turns the recorder on and off at the correct time. It is a spelling program. To use this program, you will need a recorder with a microphone. First enter this program into the computer and save it on tape. Either turn the tape over and rewind it so that you are at the beginning of the back side, or just remove the tape from the program recorder and place it in the other recorder. Now record the words in the data line onto the tape. Space the words at five second intervals. Now rewind the cassette to the beginning of the words and run the program. 200 Listing 14-2. Listen and Spell 10 REM LISTING 14*2 20 REM LISTEN AND SPELL 30 REM BY L*M»SCHREIBER FOR TAB BOOKS 4 D I M W R D $ ( 1 5 ) » AN S $ ( 1 5 ) 50 N ~ N i :l. I ? " :>• C I... E A R > " ! I F N > 1 T H E N 1 70 J REM CLEAR THE SCREEN 6 POSITION 3y5S? "LISTEN TO THE WORD" 70 POKE 54018* 52 {REM TURN ON THE RE COR DER SO FOR T~l TO 2000 t NEXT TJREM LET IT R UN 90 POKE 54018?60JREM TURN IT OFF 100 W-OJREAD WORD* 110 ? 5? "WHAT WAS THE WORD " t REM ASK F OR WORD 120 INPUT AN 8$ 130 IF WORD*=ANS$ THEN POSITION 3*20*? " V E R Y G D " J F R T :::: 1 T 5 J N E X T T % G T 30 140 W^ Will IF WO 3 THEN 110 150 POSITION 3v2()ri ! "THE WORD WAS — " J WORD* 1.60 FOR 7=1 TO 500 J NEXT TJGOTO 50 1. 7 P S I T 1 N 3 v 1 I ? " Y U H A E F I N I S H E D YOUR SPELLING FOR TODAY!!!" 180 END 2 DATA B K 8 » F A V R I T E » F T B A I... I... y H B B I E S s> C A R N 1 A I... v M U N T A I N <■ B 1 N I C v F A 1 1... U R E » A T T I TUBE y SECURE Line 40 sets aside the string space for the word (WORD$) and the answer (ANS$). Line 50 adds one to the value in N. This counts the words as they are being given. If the value is greater than 10, then all the words have been given and the program will go to the end at line 170 after the screen is cleared. Line 60 instructs the user to listen to the word. Line 70 turns on the cassette recorder by poking location 54018 with a 52. The play button on the recorder must be pressed down for this program to work. If that button is not down, you will hear a click from the television speaker, but no word. Line 80 is a timing loop. This is set for about five seconds. You may have to adjust this number for your own program recorder. Line 90 turns the recorder back off. Line 100 sets the variable W to zero. This variable will count the number of times the user tries to spell the word. It also reads the word from the data line. This is the word that was just spoken on the tape. 201 Line 110 asks the user for the word. Line 120 waits for an entry to be made. Line 130 checks the answer entered against the word. If it is correct, a message will be printed on the screen; the program will pause and then go on to line 50 for another word. Line 140 adds one to the variable W and checks to see is this was the third try. If it wasn't, the program goes to line 110 and asks for the word to be entered again. Line 150 prints the correct word if the user tried to spell it three times and couldn't. Line 160 is a timing loop to give the user time to study the word. Then the program continues at line 50. Line 170 tells the user that all the words have been spelled. Line 200 contains the words used in this program. This program can be a very effective way to learn, but it does have its drawbacks. In this case, the words must be asked in the same order every time. After a while, the user will know the order of the words. Since the tape cannot be rewound or fastforwarded from the computer, the information will always be presented in the same order. If the word was entered wrong, or if you want to hear it again, the tape cannot be rewound to that word. On the other hand, if you are presenting a very structured lesson or a story with animation, there would be no need to rewind or repeat parts of the tape. 202 Index Index Abacus, 1 Animation, 45 Animation in the Text Mode program, 55 Animation programs, 48, 53 Animation with strings, 91 ANTIC chip, 9 ANTIC instruction set, 12 ANTIC 3 mode, 17 ANTIC 3 program, 17 Assembly language listing to move character set from ROM to RAM, 39 AUTORUN/SYS, 189 AUTORUN/SYS, machine language routine for, 192 AUTORUN/SYS program, 190 B BASIC, 79 BASIC Boot Load program, 197 BASIC Table programs, 82-86 BASIC token commands, 79, 80 Binary number system, 1 Blank, horizontal, 11, 107 Blank, vertical, 11-107 Boot, cassette, 197 Boot, disk, 189 Boot record, cassette, 198 Boot sector, 191 Buffer, disk, 179 Calendar program, 181 Carousel program, 60, 64 Cassette boot, 197 Cassette handler, 195 Characters, hardware values of, 23 Central processing unit, 9 Character set, 16 Character set, editing, 26 Character set construction, 25 Character Set Editor program, 28 Character set moved from ROM to RAM, 39 Chip, ANTIC, 9 Chip, CTIA, 9, 16 Chip, GTIA, 10, 16 Chip, POKEY, 9 Chips, large-scale integrated, 9 Code, hardware, 168 Code, keyboard, 166 Color Artifacting program, 23 Color Service Routine, 109 Color text modes, 19 Command, DRAWTO, 15 Command, input, 161 Command, locate, 11, 171 Command, open, 177 Commands, BASIC token, 79, 80 Commands, XIO, 181 Control codes, ATASCII, 172 Conversions program, numbers, 3 Counting systems, 1 Course Horizontal Scroll program, 1 23 Course Vertical Scroll program, 121 CTIA chip, 10, 16 Data for Exclamation Point program, 26 Data format, cassette, 195 Decay, 153 Directory, file, 187 Directory Listing program, 178 Disk boot, 189 Disk buffer, 179 Disk file manager, 177 Disk handler, 185 Displaying Sectors program, 185 Display list, 10 Display list interrupts, 107 Display modes, 20 Distortion, 153 Double Character Sets program, 112 DRAWTO command, 15 Editing the character set, 26 Exclamation point, 26 Farmer, and the Duck, Fox and Grain Puzzle program, 91 File directory, 187 File management system, 187 File manager, disk, 177 File structures, 81 Fine Horizontal Scroll programs, 129, 131 Fine Vertical Scroll: Down program, 127 Fine Vertical Scroll program, 126 Frames, cassette, 196 u Gap, inter-record, 196 Graphic modes, 16 Graphics modes program, mixed, 13 GTIA chip, 10, 16 H Handler, disk, 185 Hardware code, 168 Hardware registers, 108 Hexadecimal number system, 2 Horizontal blank, 11, 107 Horizontal Blank, Machine Language Subroutine, 143 Input command, 161 205 Input/output, central, 1 77 Input/output control buffer, 177 Instruction set, ANTIC, 12 Interrupt routine to flash inverse characters, 116 Interrupts, display list, 107 Invisible graphic modes, 36 Keyboard code, 166 Keyboard Conversion program, 167 Keyboard interpretation, 161 Large-scale integrated chips, 9 Letter Attack program, 169 List, display, 10 Listen and Spell program, 201 Locate, Poke, and Peek program, 171 Locate command, 11, 171 Loudness, 153 M Machine language listing, moving players up and down, 77 Machine language subroutine, Hori- zontal Blank, 143 Machine language subroutine for ver- tical blank, 144 Machine language subroutines, 99 Memory addresses, screen, 9, 1 1 Memory locations, screen, 174 Mirror Images Routine, 113 Missiles, 14, 61 Mixed Modes program, 13 Modes, display, 20 Modes, graphic, 16 Modes, invisible graphic, 36 Modes, nontext, 22 Modes, text, 16 Move Player/Missile Up/Down pro- gram, 100 Moving Players program, 117 Moving players up and down, machine language listing, 77 Multicolor Characters program, 37 Music: Machine Language Subrou- tine, 157 N Nontext modes, 22 Number system, binary, 1 Number system, hexadecimal, 2 Open command, 177 Output buffer, 85 Overscan, 10 Page flipping, 133 Pitch, 153 Pixels, 12 Player/missile graphics, 14, 61 Player/missile priority order, 69 Player/Missile Strings program, 102 Players, 14, 61 Playfield, 14, 128 Pointer, 87 POKEY chip, 9 Precise Timing Programs, 114, 115 Print form Disk program, 180 Printing Control Characters program, 174 Priority order, player/missile, 69 Program, Animation in the Text Mode, 55 Program, ANTIC 3, 17 Program, AUTORUN/SYS, 190 Program, BASIC Boot Load, 197 Program, BASIC Tables, 82-86 Program, Calendar, 181 Program, Carousel, 60, 64 Program, Character Set Editor, 28 Program, Color Artifacting, 23 Program, Color Service Routine, 109 Program, Conversions, 3 Program, Course Horizontal Scroll, 123 Program, Course Vertical Scroll, 121 Program, Data for Exclamation point, 26 Program, Directory Listing, 178 Program, displaying Sectors, 185 Program, Double Character Sets, 1 1 2 Program, Fine Horizontal Scroll, 129, 131 Program, Fine Vertical Scroll, 126 Program, Fine Vertical ScrolhDown, 127 Program, Keyboard Conversion, 167 Program, Letter Attack, 1 69 Program, Listen and Spell, 201 Program, Locate, Poke, and Peek, 171 Program, Mirror Images Routine, 113 Program, Mixed Modes, 13 Program, Move Character Set, 100 Program, Move Player/Missile Up/ Down, 100 Program, Moving Players, 117 Program, Multicolor Characters, 37 Program, Music: Machine Language Subroutine, 157 Program, Precise Timing, 114, 115 Program, Print from Disk, 180 Program, Printing Control Characters, 174 Program, Read the Keyboard, 161 Program, Simple Page Flipping: Two Different Modes, 135 Program, Simultaneous Page Flip- ping: Machine Language Sub- routine, 141 Program, Slide Editor, 145 Program, Slide Show, 148 Program, Sounds, 154 Program, Sounds with Attack and Decay, 155 Program, The Birds, 70 Program, The Farmer and the Duck, Fox, and Grain Puzzle, 91 Program, Tiles, 163 Program, Variations on Tones, 1 57 Programs, Simultaneous Page Flip- ping, 137-139 Raster scan, 11, 107 Read the Keyboard Program, 161 Register, shadow, 108 Registers, hardware, 108 Registers, sound, 156 Relocating strings, 101 ROM, 16 ROM to RAM, character set moved from, 39 Routine, deferred vertical blank, 144 Routine, immediate vertical blank, 144 Runtime stack, 88 Screen displays, memory mapped, 9 Screen flipping, 133 Screen flipping, machine language subroutine for, 140 Screen Flipping program, 133 Screen memory locations, 174 Scrolling, course, 121, 123 Scrolling, fine, 125, 129 Scrolling, horizontal, 121, 123, 129 Scrolling, vertical, 121, 125 Service interrupt to flash inverse characters, 116 Shadow register, 108 Simple Animation program, 48, 53 Simple Page Flipping: Two Different Modes program, 135 Simultaneous Page Flipping: Machine Language Subroutine program, 141 Simultaneous Page Flipping pro- grams, 137-139 Slide Editor program, 145 Slides, creating, 144 Slide Show program, 148 Sound, 153 Sound, direct access too, 156 Sound characteristics, attack, 153 Sound characteristics, decay, 153 Sound characteristics, release, 153 Sound characteristics, sustain, 153 Sounds on tape, 200 Sounds program, 154 Sounds with Attack and Decay pro- gram, 155 206 Speeding up a program, 88 The Birds program, 70 Vertical blank, 11, 107 Statement table, 86 Tiles program, 163 Vertical blank, machine language sub- String/array area, 84 Token commands, 79, 80 routine for, 144 Strings, animation using, 91 Tone generator registers, 157 Voice, 153 Strings, relocating, 101 Track format, disk, 187 Voice synchronization, 200 Subroutines, 89 Volume, 153 Subroutines, machine language, 99 V Volume table of contents, disk, 187 Variable name table, 79 T Variables, 81 X Text modes, 16 Variations on Tones program, 157 XIO commands, 181 207 Advanced Programming Techniques for Your ATARI ®, including Graphics and Voice Programs If you are intrigued with the possibilities of the programs included in Advanced Programming Techniques for Your ATARI * including Graphics and Voice Pro- grams (TAB Book No. 1 545), you should definitely consider having the ready-to-run disk containing the software applications. This software is guaranteed free of man- ufacturer's defects. (If you have any problems, return the disk within 30 days and we'll send you a new one.) Not only will you save the time and effort of typing the programs, the disk eliminates the possibility of errors that can prevent the pro- grams from functioning. Interested? Available on disk for the ATARI 400 or 800, 32K at $29.95 for each disk plus $1 .00 each shipping and handling. I'm interested. Send me: Acct. No. Name disk for Advanced Programming Techniques for Your ATARI ®, includ- ing Graphics and Voice Programs (631 3S). Check/Money Order enclosed for $ ($29.95 plus $1 .00 each for shipping and handling) - VISA MasterCard Expires Address City . State Zip Signature Mail To: TAB BOOKS Inc. Blue Ridge Summit, PA 17214 (Pa. add 6% sales tax. Orders outside U.S. must be prepaid with international money orders in U.S. dollars.) TAB 1 545 Advanced Programming Techniques for Your ATARI® including Graphics and Voice Programs by Linda M. Schreiber • Get the most from your ATARI'S sound and graphics capabilities for both practical and entertainment purposes! • Master the special techniques that let you write your own advanced programs for almost any application you can think of! • Go beyond the limitations imposed by BASIC ... to become the master of your machine rather than merely its user! Here's a book that shows you how to understand the special characteristics of your ATARI and how to use them for all sorts of new and exciting sound and graphics effects. You can create your own character sets . . . mix graphics modes . . . use player/missile graphics and screen flipping . . . create animated games . . . under- stand and use interrupts . . . create your own self-booting disk and cassette programs . . . even enter a machine language subroutine to play music while a BASIC program is running! If you have a good understanding of BASIC but want to go beyond the limita- tions it imposes, this book is the place to begin. You'll learn to manipulate your machine using professional tips and tricks perfected by an author thoroughly knowl- edgeable in both program design and the ATARI'S capabilities. Every program is described in detail so that you'll be able to use the illustrated techniques to begin writing your own original programs. You'll even find a listing of all ATARI memory locations used by the operating system, discover how to change their values for different programming effects, and learn how to use the disk file structure to give you control over the drive. EVERYTHING you need to become an advanced program- mer, able to use all of your ATARI'S unique capabilities, is included in this outstand- ing sourcebook! Linda M. Schreiber is a professional programmer and expert on microcomput- ers. She is the author of TAB'S ATARI Programming . . . with 55 Programs. OTHER POPULAR TAB BOOKS OF INTEREST 25 Graphics Programs in MICROSOFT® BASIC (No. 1533— $10.95 paper; $17.95 hard) ATARI Programming . . . with 55 programs (No. 1485 — $13.95 paper; $21.95 hard) Programming Your ATARI® Computer (No. 1453— $10.95 paper; $16.95 hard) Machine and Assembly Language Programming (No. 1389— $9.95 paper; $15.95 hard) TAB TAB BOOKS Inc. Blue Ridge Summit, Pa. 17214 Send for FREE TAB Catalog describing over 750 current titles in print. FPT > $1H.5D PRICES HIGHER IN CANADA ISBN D-fl3Db-15MS-fl