Modifying Display Memory
It is possible to modify display memory directly by POKEing a new value in. If we do so, ANTIC will interpret the new value as data and start displaying it on the screen. Choose a display location to display blocks down (two rows) and in the middle of the screen. Since each display block is 40 bytes long, that will be the start of the display memory + 100. Type:
POKE 40100,46 (RETURN)
*Note: If you do not have 48K of memory in your Atari, do not use this. Instead find the beginning of the display memory by dumping the display list and looking for the 16 bit address in that listing. It will be the 5th and 6th bytes of the display list, and will be an address immediately following the end of the display list. For example: if the 16 bit conversion says 17,250, then add 100 to that to get 17,350, and type POKE 17350,46 (RETURN).
An "N" will have magically appeared two rows down in the center of the screen. (A 46 is the code for an N). We have just directly modified display memory.
Move around in memory a bit from the start of display memory to the end, and try POKEing in the 46 in other locations. You will get N's appearing all over. Try POKEing in other numbers than 46, and you will get other characters appearing on the screen. Do be careful to stay inside of the display memory area. If you go past display memory into the display list, unpredictable things will happen.
Try a FOR-NEXT loop from 0 to 255 and POKE the value into a display memory location. You will see all the possible letters alternating in one location. You could also use a series of memory locations with a FOR-NEXT loop to fill them with data. Here are two examples.
MEMLOC=XXXXX (fill in where you want data modified.)
FOR CHAR=0 TO 255
Fill a whole selection of display memory full of N's.
FOR LOC=MEMSTART TO MEMEND
You can do similar things by POKEing into display memory in other graphics modes.
We will pick one of the 24 graphics 0 blocks, and change it to a graphics 8 block by POKEing into the display list. ANTIC will display the contents of those 40 memory locations as graphics 8 dots on one scan line (the size of graphics 8 blocks). The whole displayed area will shorten by 7 lines because the graphics 8 block is 7 lines shorter than a graphics 0 block. The letters on that line will be replaced by a graphics 8 line with dots on it, with the character data represented as dots. Above and below the graphics 8 line, there will be the usual character data. Since both graphics 0 and 8 use 40 bytes per display memory block, we do not have to worry about the start of other lines being in the wrong place.
Pick a byte in the middle of the graphics 0 instructions in the display list. We picked 39984 (see Figure II). It can be any of the "2" graphics instructions, but if you pick one in the middle, it will show up better. Now the code for a graphics 8 display block is 15, so to modify that byte to a 15, we:
POKE 39984,15 (RETURN)
A middle line of characters is gone and there is a very small line of dots where they used to be; that's our graphics 8 display block. (If you had a blank screen in graphics 0 when you POKEd in the 15, you will not see any dots. That is because graphics 0 with a blank screen is display memory filled with 0's, and graphics 0 displays 0's as blanks.)
When you LIST a program on the screen, you will see the "black hole" effect. A line of characters will scroll up normally, hit the character line that is now a graphics 8 line, and disappear. It will be a group of dots. As the display scrolls up one more line, it will reappear out of that group of dots and something else will take its place. The dot pattern will shift also as the data on that line shifts. (Screen scrolling is accomplished through rewriting display memory). This is completely consistent and normal. Display memory has not changed, only the way ANTIC interprets that memory. If we wanted to restore the display block to graphics 0, we would type:
POKE 39984,2 (RETURN)
to put the graphics 0 code back in.
RESET will completely rewrite the display list and clear out display memory. It is a good way to restore your display if you make a lot of mistakes.
If you change all the graphics 0 opcodes to graphics 8, your complete screen size will be 24 scan lines, or just the top one eighth of the screen, and if you LIST a program, you will get a wildly shifting dot pattern where the characters used to be. You can use a FOR NEXT loop to modify all of the display list opcodes from 2s to 8s, and then back, for a yo-yo effect.
If graphics 0 is opcode 2, and graphics 8 is opcode 15, what are 3,4,5... 14? The Atari has 14 graphics modes, not the 9 that the Basic manual describes. A complete listing of graphics opcodes follows. It gives the display list opcodes, the Basic graphics number, whether it is a character or graphic mode, how high a display block it is in, the number of colors allowed, and the X and Y dimensions of the screen.
Some of these modes are just variations on other graphics modes. POKE them into the display list to try them out. One mode has 10 scan lines for letters, instead of 8. This one is for use with letters you would like to appear above or below the regular 8 scan lines, for things like exponents or subscripts.
Instead of having ANTIC show the display memory, let's have it show another part of memory. If we alter the address where ANTIC is told display memory's location, it will put whatever (probably garbage) it finds on the new location on the screen. We will choose an area of memory that is constantly changing all the time. This will make for an interesting and rapidly changing display. Type NEW for a new program, then:
1 POKE 39972,1:POKE 39973,0
The reason I do these P0KEs with a program is the instant either POKE is executed, the screen display will become illegible. What you will have is a rapidly flickering display reflecting low memory, where a lot of work is done. If you add:
2 FOR N=1 to 65000
3 NEXT N
and run it, you will watch the computer's memory as Basic executes from a neat ringside seat. For those of you with a display list in a different place,just change the appropriate locations. You should have no trouble figuring out which they should be, if you have followed the examples to this point.
If you would like to see ANTIC become misaligned with where the lines ought to start and end, try inserting a mode 2 line in the middle of the display list. Since mode 2 uses only 20 bytes per line, the remaining 20 will be picked up by the next graphics 0 line, and cause problems. Try it and watch the result.
Here are a few hints on making your own display lists and custom displays.
Start with a Basic display list longer than or equal to the length of the one you intend to have. It is very easy to shorten a display list. Just move the last instruction up a few bytes. Your display memory will be allocated by Basic this way, and you will avoid problems.
Do not try to POKE too much data. POKE is pretty slow. Until you learn machine language it is best to use PRINT or other Basic commands as much as possible.
If we were actually going to generate the graph in the example, we would start with a graphics 8 display list, move the jump instruction at the end up so we have the right number of display blocks, modify the block appropriately, then use POKEs for the titles and labels. The regular graphics 8 PLOT and DRAWTO commands would work fine for actually drawing the graph, if we modify the display slightly.
With our graphics 2 instruction at the start of the display list, we have misaligned memory with ANTIC. So move the display memory pointer back 20 bytes, and all will be well once again.
Your best bet at this point is to experiment with your own custom display lists and memory setups. The experience will be most helpful in later sections.
We will continue with further adventures in the display list. Next we will describe all the ANTIC opcodes (we have listed only the graphics related ones so far), have some discussions on how to use them, and find out some more of the tricks the display list can accomplish for us. This will help you design and implement displays faster and more effectively.
We will also discuss display list interrupts. Some spectacular display generation programs are included in this section.