#@L}5 _$% l0$)$$Hȱ$ UhL" `e$$%`$%`  R@W!( L(1   Y I`  d  Ld M * @  $ % CC$$)%1 Udߥ$9%: !0 S$% DD˙`  }J)Lr d M * @  $ % CC$$)%1 Udߥ$9%: !0 S$%} DD˙`  }J)Lr J  ((  p L ()   J}L= ( L 0q A    IB JC;? D W } LL  ` W )LA!  ߰")-݆ p" } $G@LL 08`Q")<2Q0 -G$Ș݆ UL# ; p8(()(0ʥ)NQ` }$GȘ݆LU )L ݆ L GȘ ݆LL )W>Z   HH)H }p h  hyhy D L> L JJ    ! LA*` BF }7'8  M HN H` 8 Z  \LdJJ!"! GFE@F (!L }EE !E^ ^ E E7EȩEdE/EȩE  D } .L }  ;F d  ;?F7F? ( .   Z D LL d } . D  L    p  E` , d)  D L) 0BM݊L݉} ML  N݆ L NLML [ TEqEHȱEqEh 0Gȹ G} HLL GɛL  LFREE SECTORS G) *Gȩ GȽG GȌ*jj >G} C8jJ3j2CD( C202C ԠBX` N 1? l LlD:RAMDISK}.COMLu L1 L ;LHL  T`  `1  ɐ     `TU  } L ? .  t`GBJ ~DEHI B V0dV!}QDEHI VF9 ,0 ,0 s0hhL  L` H hDHEh"}DEL8HI4 0 HI,0 0  9 .G VLO#},0 L4*IJ`llD1:AUTORUN.SYSNEED MEM.SAV TO LOAD THIS FILE.D1:MEM.SAV J y08 B|DEHI$} V0 0`B;DEL`?<0LV`@ʆ v s? F0Ξ05: [ BDEHI%} VY8 B V  @  /DE `E:D1:DUP.SYSERROR-SAVING USER MEMORY ON DISKTYPE Y TO &}STILL RUN DOS B;DE J  (` 9 V⪍ ઍ  -'}LLu ÝDEHILV 9 .l 9 .l  `` s$B BH(}I|DE V BLV nB,DE JLV B V BLVDEIʩ BꭝLu }M D D D D %BB! % 9* v% w%u % D %LJ& fffffff>`<*}|0`̌8l8pv00````00 0f< x||||-}|||~|l8l8lfff< 0`@`0 000006c!"|™.}|™|~x|™|as22sa>2222r|晒xLLLLNB|晁晉|™||™/}v|~Þ~fdddd||晙d8晙™晙dd|2x`x`~<~~<"#30 ~ <~~<0}|~~||~~||>````~~8<8<||1}~~~|0000~l8|ll8l~ 8`8pp##82}$ %0$1$3$4$ ?̏?1$4$ॄ``ex$w$e{$z$褄 x${3}$`(mDeXYi????)^̜D)DȄ?Čei?̜D@L$4}i( %&L$??`??????8??Ƌ拑` T8` 8` n%D5} %LJ&} T8t?????@:@CD(DDi?18?8?8?@K????` -??6} $ &= Y%&'?L' &= Y%?`'XRUT`H)h)` i@LG&8 `DCIDID $ 87}Х)LS&ЭC?H &hɛL&,C0ɜf) `{\\X^T_PHC^? e,h .&) C8} $8??''i?i? 'LJ&?'?'LJ&ʊ &HIHd'Hc'H`# \^_|}~2k)9}9:+O)29+,0];'3A/1/s)l32'))(m(( ):--,+<,+4,++d,CIC`"I"` (8??8??? ??:} $8?内?凅((?m???i? $L'`8???? ????8?? ??`8??;}`??`ЭD(DDΝD $ '} T8L &L'ЭDΜDΜDD $ '} T8L &ƇƆL'<}Ƌ^^()`8eiL'^` 懥͒?^eiL'??L'=}??8̓??? $LC)s)s)`)))))`Ƌ ^`^Ƌ͂?L)ƌ >}L(L)??L')*^懥͒?LC)懥͒?LC)^L4)??????}`8??hh``8Ie?Ie?????8?m?͉? &۠= Y%?`???m?@}??m?? $????8?傅*+?僅 $8??????` K* ( h*8????` n( K* ( h*L+A}L. 9*2 &= Y% o%H &h)_ @W K* (Lh*S K* )Lh*P K* ;-Lh*`8????ХL'??B}L+͒???L++,L+ee8?傅?僅8傍?働? $8??????`C} @LO, @ O,L4) @ {, @` @ @ {,L'?m @?m @ͅ?hhL,m @m @8?倅?偅D} M$?m @??m @?`?It?`= Y% 8)})Y`,-Э`2 & > Y% ,L & % %LJ&^懥͒?E}LC)L4)Ƌ^Ƌ̓?L)8ee8内包LM-L'@ԩ-0F}1-XYȑȑ`ppp-.A-Hs) ԍЍ)Х  h@ЭG} 9* &> Y%I $I2 o%)_ @W . )L.S . )L.P . -L. 'L &??`8??H}?? *?? $L5.'U?? T8~ T8? o%?,C09 .n/CL.ɛE~L.~ T8L.) }̓?𻥌)I}Ю ? T8CL.?`2 &Ϡ= Y% ,L &D D D D Lto/j0CL|/C??L/CJ}8?勪,C0ɛ^L/ .&L/^L/ 2` &9> Y% [00@ w/p?D?E8??H??I B V0 oK}/ ';0 LX1H o/h!H} T8Q> Y%h v8 P0 -?` &Y> Y%L70C BLVpCCH@k0f1 .h? &hhL- P0CL}D?E?HICJBLV8??ą &s> Y% [0L0 % 0L0LX1CDE8?冝HM}?凝IB V`CHm??Im???e??e? /??` P0L0} T8ig1b2> Y%L70@ԭs)N})`????8* &?.??.??.??.? ??L1? ?8??????L1?`8????O}?? ? &> Y%?`m?m?8?倅?偅eͅ? &> Y%?` M$?m???c2^3m??P}?? $L'ȱȊ`)?! ;I@Ln(H)h)` @@L2i `Э& &? Y% .@L &?@̔?Q}L &@@S@ .&ъ 拥͒?6@ei?Ō?卐8@@@ '` _3Z4& ? Y%R}?` &8???? v8?`KE:P@HH8@@@@1pHI B@ V( 0LJ&hh@`S} &נ>LY%L5ЭL= &> Y% o1 [0L5 o1 3?? @ @C3? @@3t@??[4V5@T}@?@L5^)@@@?挐?@?ȱ?8ei@ 5@ 58.@??䅎@ 7 5@U}? 258??<:? ?? 25?E T8> Y% o% '; -} T8 &LJ&LX48?@0 5??兎B W5V}R65 7 5 5 5@@?8@@@@ &> Y% o% 3??䅎A 5 7?@0 5` ?@ 3`?m@W}@ 5` 3C 3` @) 25656 @L.7ʊ @6HHG6HF6H`8@eiLX4^@`wlrtbsnhf%p?xmqi6666X}66S6N766766x6n6e6'7P7ȩ@L*6 1@L*6 1@?@L*6 1@?@L*6 1?L*6?L*6 1?L*6 1?L*6 1?LY}*6 1?L*6 1?L*6@ȘH 25h@` 7?A?L*6ȱ^` 7?B?L*6 7L*6ȱ @Ls4 1H @)Z}hd@ *6LO7-86^ 2???`CC 0L3 % 0L3hhpCLN4̏?0 2 3 @  3_ 3L[}7`@) @ 2c8@?J8? 3@L7e8??8? L7u @I @#@@@ q8@L7 @d@ 3L7.8)9 B V\}nD8EHIBLV䌡8HI B V䬡8`E:Lx8Dԅ ؠH),D0 T8L8 3h0``]}D 8D)?<D)@`I@`D9,P a{)ɀ`H2ҢҠh`lj;k+*opui-=vc*99bx^}z436521, .nm/reytwq907~8<>fhdgsaLJ:K\^OPUI_|VCBXZ$#&%"![ ]NM?REYTWQ()'@}FHDGSA {  _} ` }9: 2@ : 2@ &: $L9L &Э# &? Y% .:@?<@̔?`}L &8@@e@@ee8?傅?僅 $8?@???:@) @ @ {,<@ .&:@m:@ia}L':; ';pD>EHIJB V0\DDdDeDDD L;0?+K T8 L;03D L;0) T8DD. T8L: b} L;ƌL:p B VpC`H T8h T8 L;0 T8LA;pHIBLV o1 .8 o1R} T8 : =DDDΘDΘD = o%c};a;<)_ݼ;L<ʊ ;H;H`+*-=RLUF12345678 ;<<0<<<<<=========G=%= =DL< =DDd} DDDL; =D8L< =Di͘DުL<>C) 2 C C.ʎDC`pBDHIDe}CELV CL^;pCJ C< w<0% % 00} T8 - &LJ&T T8LT8@ '; Y=Q> Y%@ v8 T8g}> Y% o% =L< I==` Y=? Y%>LT8=>`124 chr=1 sector.PAGE 6 WRITERExit to DOSBuffer FullDelete (S,W,P):h} Are You Sure? (Y/N)ERASE ALL TEXTErase (S,W,P): to exitSave (Device:Filename)>Error #BREAK Key AbortNo ErrorsLi}oad (Device:Filename)> Press D1:*.*Memory Ful>?lNo text in bufferPrint (Device:Filename)>Printing...Insert nexj}t sheet, press Find:Not FoundChange To: -Exit ̭oad ̭elete ormat nlock ock ename Drive #k}Rename to:Format Diskrive #w8<<  B JKIHiDiELV`L8 8 BLV`Lxm}8t8l Lu8hihiHHȱȱL8c !#3`Lu8JJJJ`H 8h`Hn}ȩh Q8L8 Z8L8 8L8 8L8 8L8S:@9E:E9H '9 H9I9 8 '9h)0ICo}9D9L8 L :::: :Lr:::IEL[::i:iIIL[:`:i::iq}::L:`L{:w:w: C`L:L: D8:MEM.SAV: 8| 9 '9`L:L: D:DUP.SYS:̩ 8r} x:ɀL: '9`88 |9Y:X: '9L); D8:DUP.SYS; 8::88 9 '98? :`;WL`; 9s}Ln; ` :Y;Y;L;L;)} Setting Up ATARI 130XE Ram Disk; 9L; ; -9  t} L;D8:; :9 :Y;Lerction, or color register indirection. With display list interrupts the full power of these feature z}s can be deployed.Theory of operation Display list interrupts take advantage of the sequential nature of the raster scan t {}elevision display. The television draws the screen image in a time sequence. It draws images from the top of the screen to th |}e bottom. This drawing process takes about 17,OOO microseconds, which looks instantaneous to the human eye, but is a long tim }}e in the time scale that the computer works in. The computer has plenty of time to change the parameters of the screen displa ~}y while it is being drawn. Of course, it must effect each change each time the screen is drawn, which is 6O times per second. } Also (and this is the tricky part), it must change the parameter in question at exactly the same time each time the screen i }s drawn. That is, the cycle of changing screen parameters must be synchronized to the screen drawing cycle. One way to do thi }s might be to lock the 65O2 up into a tight timing loop whose execution frequency is exactly 6O hertz. This would make it ver }y difficult to carry out any computations other than the screen display computations. It would also be a tedious job. A much }better way would be to interrupt the 65O2 just before the time has come to change the screen parameters. The 65O2 responds to } the interrupt, changes the screen parameters, and returns to its normal business. The interrupt to do this must be precisely } timed to occur at exactly the same time during the screen drawing process. This specially timed interrupt is provided by the } antic chip; it is called a display list interrupt (dli) The timing and execution of any interrupt process can be intricat }e; therefore we will first narrate the sequence of events in a properly working dli. The process begins when the antic chip e }ncounters a display list instruction with its interrupt bit (bit d7) set. Antic waits until the last scan line of the mode li }ne it is currently displaying. Antic then refers to its nmien register to see if display list interrupts have been enabled. I }f the enable bit is clear, antic ignores the interrupt and continues its regular tasks. If the enable bit is set, antic pulls } down the nmi line on the 65O2. Antic then goes back to its normal display activities. The 65O2 vectors through the nmi vecto }r to an interrupt service routine in the os. This routine first determines the cause of the interrupt. If the interrupt is in }deed a dli, the routine vectors through addresses $O2OO, $O2O1 (low then high) to a dli service routine. The dli routine chan }ges one or more of the graphics registers which control the display. Then the 65O2 rtiS to resume its mainline program.Page } 5-1 above more of the graphics registers which control the display. Then the 65O2 rtiS to resume its mainline program.Page 0080There are a number of steps involved in setting up a dli. The very first thing you must do is write the dli routine} itself.The routine must push any 65O2 registers that will be altered onto the stack, as the os interrupt poll routine saves }no registers. (The 65O2 does automatically push the processor status register onto the stack.) The routine should be short an}d fast; it should only change registers related to the display. It should end by restoring any 65O2 registers pushed onto the} stack. Next you must place the dli service routine somewhere in memory. Page 6 is an ideal place. Set the vector at $O2OO, $}O2O1 to point to your routine. Determine the vertical point on the screen where you want the dli to occur, then go to the cor}responding display list instruction and set bit d7 of the nmien register at $d4Oe. The dli will immediately begin functioning}.DLI TIMING As with any interrupt service routine, timing considerations can be critical. Antic does not send the interru}pt to the 65O2 immediately upon encountering an interrupt instruction; it delays this until the last scan line of the interru}pting mode line. There are a number of processing delays before the dli reaches your service routine. Thus, your dli service }routine will begin executing while the electron beam is partway across the screen in the last scan line of the interrupting m}ode line. For example, if such a dli routine changes a color register, the old color will be displayed on the left half of th}e screen and the new color will show up on the right half of the screen. Because of uncertain timing in the response of the 6}5O2 to an interrupt, the border between them will not be sharp but will jiggle back and forth irritatingly. There is a sol}ution to this problem. It is provided in the form of the wsync (wait for horizontal sync) register. Whenever this register is} addressed in any way, the antic chip pulls down the rdy line on the 65O2. This effectively freezes the 65O2 until the regist}er is reset by a horizontal sync. The effect is that the 65O2 freezes until the electron beam reaches the right edge of the s}tandard playfield. If you insert a sta wsync instruction just before the instructionwhich stores a value into a color registe}r, the color will go into the color register while the beam is off the screen. The color transition will occur one scan line }lower, but will be neat and clean. The proper use of a dli then is to set the dli bit on the mode line before the mode lin}e for which you want the action to occur. The dli service routine should first save the 65O2 registers onto the stack, and th}en load the 65O2 registers with the new graphics values to be used. It should execute a sta wsync, and then store the new val}ues into the appropriate antic or ctia registers. Finally, it should restore the 65O2 registers and return from the interrupt}. This procedure will guarantee that the graphics registers are changed at the beginning of the desired line while the electr}on beam is off the screen.page 5-2 aboveraphics registers are changed at the beginning of the desired line while the electr*0080DLI EXAMPLEA simple program demonstrating a dli is given below:1O DLIST=PEEK(56O)+256*PEEK(561):REM FIND D}ISPLAY LIST2O POKE DLIST+15,13O:REM INSERT INTERRUPT INSTRUCTION3O FOR I=O TO 19:REM } LOOP FOR POKING DLI SERVICE ROUTINE4O READ A:POKE 1536+I,A:NEXT I5O DATA 72,138,72,169,8O,162,886O DATA 141,1O,212,141,2}3,2O87O DATA 141,24,2O8,1O4,17O,1O4,648O POKE 512,O:POKE 513,6:REM POKE IN INTERRUPT VECTOR9O POKE 54286,192}:REM ENABLE DLIThis routine uses the following assembly language DLI service routine:PHA save} accumulatorTXAPHA save x-registerLDA #$5O dark color for charactersLDX #$58 pinkSTA wsync waitSTA colp}f1 store colorSTX colpf2 store colorPLATAXPLA restore registersRTI done This is a very simple dli }routine. It changes the background color from blue to pink. It also changes the color of the characters so that they show up }as dark against the pink background. You might wonder why the upper half of the screen remains blue even though the dli routi}ne keeps stuffing pink into the color register. The answer is that the os vertical blank interrupt routine keeps stuffing blu}e into the color register during the vertical blank period. The blue color comes from the os shadow register for that color r}egister. Every hardware color register is shadowed out to a ram location. You may already know about these shadow registers a}t locations 7O8 through 712. For most purposes you can change colors by poking values into the shadow registers. If you poke }directly into the hardware registers, the os shadow process will wipe out your poked color within a 6OTH of a second. For dli}S, however, you must store your new color values directly into the hardware registers. You can not use a dli to set the color} of the first displayed line of the screen; the os takes care of that line for you. Use dliS to change colors of lines below }the first line.page 5-3 above the screen; the os takes care of that line for you. Use dliS to change colors of lines below 0080ATTRACT MODE By stuffing colors directly into the hardware registers, you create a new problem: you defeat the a}utomatic attract mode. Attract mode is a feature provided by the operating system. After nine minutes without a keypress, the} colors on the screen begin to cycle through random hues at lowered luminances. This ensures that a computer left unattended }for several hours does not burn an image into the television screen. It is easy to build attract mode into a display list int}errupt. Only two lines of assembly code need be inserted into the dli routine: OLD NEW LDA NEWCOL LDA NEW}COL STA WSYNC EOR COLRSH STA COLPF2 AND DRKMSK STA WSYNC STA COLPF2DRKMSK and CO}LRSH are zero page locations ($4e and $4f) set up and updated by the OS during vertical blank interrupt. When attract mode is} not in force, colrsh takes a value of OO and drkmsk takes $ff. When attract mode is in force, colrsh is given a new random v}alue every 4 seconds and drkmsk holds a value of $f6. Thus, colrsh scrambles the color and drkmsk lops off the highest lumina}nce bit.DETAILED TIMING CONSIDERATIONS The implementation of attract mode in dliS exacerbates an already difficult proble}m: the shortage of execution time during a dli. A description of dli timing will make the problem more obvious. DLI execution} is broken into three phases: -phase one covers the period from the beginning of the dli to the sta wsync instruction. During} phase one the electron beam is drawing the last scan line of the interrupting mode line. - Phase two covers the period from }the sta wsync instruction to the appearance of the beam on the television screen. Phase two corresponds to horizontal blank; }all graphics changes should be made during phase two. - Phase three covers the period from the appearance of the beam on the }screen to the end of the dli service routine. The timing of phase three is not critical. One horizontal scan line takes 11}4 processor clock cycles of real time. A dli reaches the 65O2 on cycle number 8. The 65O2 takes from 8 to 14 cycles to respon}d to the interrupt. The os routine to service the interrupt and vector it on to the dli service routine takes 11 machine cycl}es. During this time from 1 to 3 cycles will be stolen for memory refresh dma. Thus, the dli service routine is not reached u}ntil from 28 to 36 clock cycles have elapsed. For planning purposes we must assume the worst case and program as if the dli s}ervice is reached on cycle number 36.page 5-4 abovenning purposes we must assume the worst case and program as if the dli s50080Furthermore, the STA WSYNC instruction must be reached by cycle number 1OO; this reduces the time available in phas}e one by 14 cycles. Finally, antic's dma will steal some of the remaining clock cycles from the 65O2. Nine cycles will be los}t to memory refresh dma. This leaves an absolute maximum of 55 cycles available for phase one. This maximum is achieved only }with blank line mode lines.Character and map mode instructions will result in the loss of one cycle for each byte of display }data. The worst case arises with basic modes O, 7, and 8, which require 4O bytes per line. Only 15 machine cycles are availab}le to phase one in such modes. Thus, a phase one routine will have from 15 to 55 machine cycles of execution time available t}o it. Phase two, the critical phase, extends over 27 clock cycles of real time. As with phase one, some of these cycles ar}e lost to cycle stealing dma. Player-missile graphics will cost five cycles if they are used. The display instruction will co}st one cycle; if the lms option is used, two more cycles will be stolen. Finally, one or two cycles may be lost to memory ref}resh or display data retrieval. Thus, from 17 to 26 machine cycles are available to phase two. The problems of dli timing }now become obvious. To load, attract and store a single color will consume 14 cycles. Saving a, x, and y will cost 47 cycles,} most if not all of phase one. Obviously, the programmer who wishes to use dli for extensive graphics changes will expend muc}h effort on the timing of the dli. Fortunately, the beginning programmer need not be concerned with extensive timing calculat}ions. If only single color changes or simple graphics operations are to be performed, cycle counting and speed optimization a}re unnecessary. These considerations are only important for high-performance situations. There are no simple options for t}he programmer who needs to change more than three color registers in a single dli. It might be possible to load, attract, and} store a fourth color early in phase three if that color is not displayed on the left edge of the screen. Similarly, a color }not showing up on the right side of the screen could be changed during phase one. Another approach is to break one overactive} dli into two less ambitious dliS, each doing half the work of the original. The second dli could be provided by inserting a }single scan line blank instruction (with dli bit set) into the display list just below the main interrupting mode line. This }will consume some screen space. Another partial solution is to perform the attract chores during vertical blank periods. T}o do this, two tables of colors must be kept in ram. The first table contains color values intended to be displayed by the dl}i routines. The second table contains the attracted values of these colors. During vertical blank, a user-supplied interrupt }service routine fetches each color from the first table, attracts it, and stores the attracted color to the second table. The} dli routine then retrieves values directly from the second table without paying the time penalty for attract.page 5-5 abov}edli routine then retrieves values directly from the second table without paying the time penalty for attract.page 5-5 abov0080MULTIPLE DLI's It is often desirable to have a number of dliS occurring at several vertical positions on the scr }een. This is an important way to add color to a display. Unfortunately, there is only one dli vector; if multiple dliS are to } be implemented then the vectoring to the appropriate dli must be implemented, in the dli routine itself. There are several w }ays to do this. If the dli routine does the same process with different values then it can be table-driven. On each pass thro }ugh the dli routine, a counter is incremented and used as an index to a table of values. A sample dli routine for doing this }is as follows: PHA TXA PHA INC COUNTR LDX COUNTR LDA COLTAB,X use page two for color table } STA WSYNC wait STA COLBAK CPX #$4F last line? BNE ENDDLI no, exit LDA #$OO } yes, reset counter STA COUNTREnddli pla TAX PLA restore accumulator RTIThe basic pro }gram to call this routine is:1O GRAPHICS 72O DLIST=PEEK(56O)+256*PEEK(561):REM FIND DISPLAY LIST3O FOR J=6 TO 84:REM } GIVE EVERY MODE LINE A DLI4O POKE DLIST+J,141:REM BASIC MODE 7 WITH DLI BIT SET5O } NEXT J6O FOR J=O TO 3O7O READ A:POKE 1536+J,A:NEXT J:REM POKE IN DLI SERVICE ROUTINE8O DATA 72,138,72,238,32,6,17 }5,32,69O DATA 189,O,24O,141,1O,212,141,26,2O81OO DATA 224,79,2O8,5,169,O11O DATA 141,32,6,1O4,17O,1O4,6412O POKE 512,O:PO }KE 513,6:REM VECTOR TO DLI SERVICE ROUTINE13O POKE 54286,192:REM ENABLE DLIThis program } will put 8O different colors onto the screen. There are other ways to implement multiple DLI's. One way is to use a dli c }ounter as a test for branching through the dli service routines to the proper dli service routine.page 5-6 aboveuse a dli c r0080This slows down the response of all the dliS, particularly the ones at the end of the test sequence. A better way i$}s to have each dli service routine write the address of the next routine into the dli vector at $2OO, $2O1. This should be do$}ne during phase three. This is the most general solution to the problem of multiple dliS. It has the additional advantage tha$}t vectoring logic is performed after the time critical portion of the dli, not before. The os keyboard click routine inter$}feres with the function of the dli. Whenever a key is pressed and acknowledged, the onboard speaker is clicked. The timing fo$}r this click is provided by several sta wsync instructions. This can throw off the timing of a dli routine and cause the scre$}en colors to jump downward by one scan line for a fraction of a second. There is no easy solution to this problem. One possib$}le solution involves the vcount register, a read-only register in antic which tells what scan line antic is displaying. A dli%} routine could examine this register to decide when to change a color. Another solution is to disable the os keyboard service%} routine and provide your own keyboard routine. This would be a tedious job. The final solution is to accept no inputs from t%}he keyboard. If key presses are not acknowledged, the screen jiggle does occur.KERNELS The dli was designed to replace a %}more primitive software/hardware technique called a kernel. A kernel is a 65O2 program loop which is precisely timed to displ%}ay cycle of the television set. By monitoring the vcount register and consulting a table of screen changes catalogued as a fu%}nction of vcount values, the 65O2 can arbitrarily control all graphics values for the entire screen. A high price is paid for%} this power: the 65O2 is not available for computations during the screen display time, which is about 75 percent of the time%}. Furthermore, no computation may consume more than the 4OOO or so machine cycles available during vertical blank and oversca%}n periods. This restriction means that kernels can only be used with programs requiring little computation, such as certain s% }kill and action games. For example, the basketball program for the atari 4OO/8OO computers uses a kernel; the program require% }s little computation but much color. The multicolored players in this game could not be done with display list interrupts, be% }cause dliS are keyed to playfield vertical positions, not player positions. It is possible to extend the kernel idea right% } into a single scan line and change graphics registers on the fly. In this way a single color register can present several co% }lors on a single scan line. The horizontal position of the color change is determined by the amount of time that elapses befo%}re the change goes in. Thus, by carefully counting machine cycles, the programmer can get more graphics onto the screen. Unfo%}rtunately, this is extremely difficult to achieve in practice. With antic dmaING the 65O2, it is very difficult to know exact%}ly how many cycles have really elapsed; a simple count of 65O2 cycles is not adequate. If antic'S dma is turned off, the 65O2%} can assume full control of the display but must then perform all the work that antic normally does.page 5-7 above the 65O2$t0080For these reasons horizontal kernels are seldom worth the effort. However, if the two images to be displayed in dif)}ferent colors are widely separated, say by 2O color clocks or more, the separation should cover up the timing uncertainties a)}nd render this technique feasible.APPLICATIONS OF DISPLAY LIST INTERRUPTS The tremendous value of graphics indirection an)}d all those modifiable registers in the hardware now becomes obvious. With display list interrupts, every one of those regist)}ers can be changed on the fly. You can put lots of color, graphics, and special effects onto the screen. The most obvious app)}lication of dliS is to put more color onto the screen. Each color register can be changed as many times as you have dliS. Thi)}s applies to both playfield color registers and player color registers. Thus, you have up to nine color registers, each of wh)}ich can display up to 128 different colors. Is that enough color for you? Of course, a normal program would not lend itself t)}o effectively using all of those colors. Too many dliS start slowing down the whole program. Sometimes the screen layout cann)}ot accomodate lots of dliS. In practice, a dozen colors is easy, two dozen requires careful planning, and more than that requ)}ires a contrived situation. Display list interrupts can give more than color; they can also be used to extend the power of)} player-missile graphics. The horizontal position of a player can be changed by a dli. In this way a player can be reposition)}ed partway down the screen. A single player can have several incarnations on the screen. If you imagine a player as a vertica)}l column with images drawn on it, a dli becomes a pair of scissors with which you can snip the column and reposition sections) } of it on the screen. Of course, no two sections of the player can be on the same horizontal line, so two incarnations of the)!} player cannot be on the same horizontal line. If your display needs allow graphics objects that will never be on the same ho)"}rizontal line, a single player can do the job. Another way to use dliS in conjunction with players is to change their widt)#}h or priority. This would most often be used along with the priority masking trick described in section 4. The last applic)$}ation of dliS is the changing of character graphics in a large window and regular text in a text window. Multiple character s)%}et changes are possible; a program might use one graphics character set at the top of the screen, another graphics character )&}set in the middle of the screen, and a regular text character set at the bottom. A 'rosetta stone' program would also be poss)'}ible, showing different text fonts on the same screen. The vertical reflect bit can be changed with a dli routine, allowing s)(}ome text to be rightside up and other text to be upside down. The proper use of the dli requires careful layout of the scr))}een display. The designer must give close consideration to the vertical architecture of display.page 5-8 aboveut of the scr(p0080The raster scan television system is not two-dimensionally symmetric; it has far more vertical structure than horiz-+}ontal structure. This is because the pace for horizontal screen drawing is 262 times faster than the pace for vertical screen-,} drawing. The atari home computer display system was designed specifically for raster scan television, and it mirrors the ani--}sotropy of the raster scan system. The atari home computer display is not a flat, blank sheet of paper on which you draw; it -.}is a stack of thin strips, each of which can take different parameters. The programmer who insists on designing an isotropic -/}display wastes many opportunities. You will achieve optimal results when you organize the information you wish to display in -0}a strong vertical structure. This allows the full power of the dli to be brought to bear. Figure 5-1 shows some screen dis-1}plays from various programs and gives estimates of the degree of vertical screen architecture used in each.page 5-9 aboveN-2}ote:-the examples of vertical screen architecture that should be in picture form here, are described in writing because of pr-3}oblems with high resolution graphics on a 1O27 printer.The picture simply shows six screens from the following games and one-4} utility. The games are :- space invaders, scram, missile command, star raiders, asteroids and graph it. They are shown as if-5} they were part way into a game and it is assumed that a reasonable idea of the graphics may be gained from this note.page -6}5-1O abovepart way into a game and it is assumed that a reasonable idea of the graphics may be gained from this note.page , 00806SCROLLINGQuite frequently the amount of information that a programmer wants to display exceeds the amount of i18}nformation that can fit onto a screen. One way of solving this problem is to scroll the information across the display. For e19}xample, listings of basic programs scroll vertically from the bottom to the top of the screen. All personal computers impleme1:}nt this type of scrolling. However, the atari home computer has two additional scrolling facilities that offer exciting possi1;}bilites. The first is "load memory scan" (lms) coarse scrolling; the second is fine scrolling.Conventional computers use coa1<}rse scrolling; in this type of scrolling, the pixels that hold the characters are fixed in position on the screen and text is1=} scrolled by moving bytes through the screen ram. The resolution of the scrolling is a single character pixel, which is very 1>}coarse. The scrolling this produces is jerky and quite unpleasant. Furthermore, it is achieved by moving up to a thousand byt1?}es around in memory, a slow and clumsy task. In essence, the program must move data through the playfield to scroll.Some per1@}sonal computers can produce a somewhat finer scroll by drawing images in a higher resolution graphics mode and then scrolling1A} these images. Although higher scrolling resolution is achieved, more data must be moved to attain the scrolling and the prog1B}ram is consequently slowed. The fundamental problem is that the scrolling is implemented by moving data through the screen ar1C}ea.There is a better way to achieve coarse scrolling with atari 4OO/8OO : move the screen area over the data. The display li1D}st opcodes support the load memory scan feature. The lms instruction was first described in section 2 and tells antic where t1E}he screen memory is. A normal display list will have one lms instruction at the beginning of the display list; the ram area i1F}t points to provides the screen data for the entire screen in a linear sequence. By manipulating the operand bytes of the lms1G} instruction, a primitive scroll can be implemented. In effect, this moves the playfield window over the screen data. Thus, b1H}y manipulating just 2 address bytes, you can produce an effect identical to moving the entire screen ram. The following progr1I}am does just that :1O DLIST=PEEK(56O)+256*PEEK(561):REM FIND DISPLAY LIST2O LMSLOW=DLIST+4 :REM GET LOW ADDR1J}ESS OF LMS OPERAND3O LMSHIGH=DLIST+5 :REM GET HIGH ADDRESS OF LMS OPERAND4O FOR I=O TO 255 :REM 1K}OUTER LOOP5O POKE LMSHIGH,I6O FOR J=O TO 255 :REM INNER LOOP7O POKE LMS,OW,J8O FOR Y=1 TO 5O:NEXT Y 1L} :REM DELAY LOOP9O NEXT J1OO NEXT I TO 255 :REM INNER LOOP7O POKE LMS,OW,J8O FOR Y=1 TO 5O:NEXT Y 0'0080This program sweeps the display over the entire address space of the computer. The contents of the memory are all d5N}umped onto the screen. The scroll is a clumsy serial scroll combining horizontal scrolling with vertical scrolling. A pure ve5O}rtical scroll can be achieved by adding or subtracting a fixed amount (the line length in bytes) to the lms operand. The foll5P}owing program does that :1O GRAPHICS O2O DLIST=PEEK(56O)+256*PEEK(561)3O LMSLOW=DLIST+44O LMSHIGH=DLIST+55O SCREENLOW=O5Q}6O SCREENHIGH=O7O SCREENLOW=SCREENLOW+4O :REM NEXT LINE8O IF SCREENLOW<256 THEN GOTO 12O:REM OVERFLOW?9O SCREENLOW5R}=SCREENLOW-256 :REM YES, ADJUST POINTER1OO SCREENHIGH=SCREENHIGH+111O IF SCCREENHIGH=256 THEN END12O POKE LMSLOW,SCR5S}EENLOW13O POKE LMSHIGH,SCREENHIGH14O GOTO 7OHORIZONTAL SCROLLING A pure horizontal scroll is not so simple to do as a pu5T}re vertical scroll. The problem is that the screen ram for a simple display list is organized serially. The screen data bytes5U} for the lines are strung in sequence, with the bytes for one line immediately following the bytes for the previous line. You5V} can horizontally scroll the lines by shifting all the bytes to the left; this is done by decrementing the lms operand. Howev5W}er, the leftmost byte on each line will then be scrolled into the rightmost position in the next higher line. The first sampl5X}e program above illustrated this problem. The solution isto expand the screen data area and break it up into a series of ind5Y}ependent horizontal line data areas. Figure 6-1 schematically illustrates this idea :ea and break it up into a series of ind4V0080-------- --------:......: ....:......:......:......: ...:......:.......:..9[}....: ....:......:.......:......: .....:......:......:......: .....:......:.......:......: 9\} ....:......:......-------- --------normal data arrangement for arrangement 9]}horizontal scrollFigure 6-1 arranging screen ram On the left is the normal arrangement. One-dimensional serial ram is st9^}acked in linear sequence to create the screen data area. On the right is the arrangement we need for proper horizontal scroll9_}ing. The ram is of course still one-dimensional and still serial, but now it is used differently. The ram for each horizontal9`} line extends much further than the screen can show. This is no accident; the whole point of scrolling is to allow a program 9a}to display more information than the screen can hold. You can't show all that extra information if you don't allocate the ram9b} to hold it. With this arrangement you can implement true horizontal scrolling. You can move the screen window over the scree9c}n data without the undesirable vertical roll of the earlier approach. The first step in implementing pure horizontal scroll 9d}is to determine the total horizontal line length and allocate ram accordingly. Next you must write a completely new display l9e}ist with a lms instruction on each mode line. The display list will of course be longer than usual, but there is no reason wh9f}y you cannot write such a display list. What values do you use for the lms operand? It is most convenient to use the address 9g}of the first byte of each horizontal screen data line. There will be one such address for each mode line on the screen. Once 9q}b%DOS SYSbC)AUTORUN SYSb lRAMDISK COMbuDERE39 bDERE40 bDERE41 bDERE42 bDERE43 bDERE44 bDERE45 bDERE46 b *DERE47 b7DERE48 b MDERE49 bZDERE50 b{DERE51 bDERE52 bDERE53 bDERE54 bDERE55 bDERE56 bDERE57 b DERE58 bDERE59 b2DERE60 bIDERE61 b QDERE62 b ^DERE63 bhDERE64 byDERE65 bDERE66 bDERE67 b DERE68 bDERE69 b DERE70 #DERE71 #DERE72 #DERE73 #DERE74 #DERE75 #"DERE76 #2DERE77 # BDERE78 # NDERE79 # WDERE80 #`DERE81 #uDERE82 #DERE83 #DERE84 # DERE85 #DERE86 #DERE87 # DERE88 DERE89 the new display list is in place, antic must be turned onto it and screen data must be written to populate the screen. To exe9r}cute a scroll, each and every lms operand in the display list must be incremented for a rightward scroll or decremented for a9s} leftward scroll. Program logic must ensure that the image does not scroll beyond the limits of the allocated ram areas; othe9t}rwise, garbage displays will result. In setting up such logic, the programmer must remember that the LMS operand points to th9u}e first screen data byte in the displayed line. The maximum value of the LMS operand is equal to the address of the last byte9v} in the long horizontal line minus the number of bytes in one displayed line. Remember also that the LMS value should not com9w}e within one screen display line's length (in bytes) of a 4K address boundary, or the wrong data will be displayed due to LMS9x} counter rollover. As this process is rather intricate, let us work out an example. First, we must select our total horizo9y}ntal line length. We shall use a horizontal line length of 256 bytes, as this will simplify address calculations. Each horizo9z}ntal line will then require one page of RAM.PAGE 6-3 ABOVE56 bytes, as this will simplify address calculations. Each horizo8<0080Since we will use BASIC mode 2, there will be 12 mode lines on screen; thus, 12 pages or 3K of RAM will be required=|}. For simplicity (and to guarantee that our screen RAM will be populated with nonzero data), we will use the bottom 3K of RAM=}}. This area is used by the OS and DOS and should be full of interesting data. To make matters more interesting, we'll put the=~} display list onto page 6 so that we can display the display list on the screen as we are scrolling. The initial values of th=}e LMS operands will thus be particularly easy to calculate; the low order bytes will be zeros and the high order bytes will b=}e (in order) 0, 1, 2, etc. The following program performs all these operations and scrolls the screen horizontally:10 REM fi=}rst set up the display list20 POKE 1536,112:REM 8 blank lines30 POKE 1537,112:REM 8 blank lines40 PO=}KE 1538,112:REM 8 blank lines50 FOR I=1 TO 12:REM Loop to put in display list60 POKE 1536+3*I,71:REM =} BASIC mode 2 with LMS set70 POKE 1536+3*I+1,0:REM Low byte of LMS operand80 POKE 1536+3*I+2,I:REM Hig=}h byte of LMS operand90 NEXT I100 POKE 1575,65:REM ANTIC JVB instruction110 POKE 1576,0:REM Display list starts=} at $0600120 POKE 1577,6130 REM tell ANTIC where display list is140 POKE 560,0150 POKE 561,6160 REM now scroll horizonta=}lly170 FOR I=0 TO 235:REM Loop through LMS low bytes175 REM we use 235---not 255---because screen width is 20 char=}acters180 FOR J=1 TO 12:REM for each mode line190 POKE 1536+3*J+1,I:REM Put in new LMS low byte200 NEXT J=}210 NEXT I220 GOTO 170:REM Endless loop This program scrolls the data from right to left. When the end of =}a page is reached, it simply starts over at the beginning. The display list can be found on the sixth line down (it's on page=} 6). It appears as a sequence of double quotation marks. The next step is to mix vertical and horizontal scrolling to get =}diagonal scrolling. Horizontal scrolling is achieved by adding 1 to or subtracting 1 from the LMS operand. Vertical scrolling=} is achieved by adding the line length to or subtracting the line length from the LMS operand. Diagonal scrolling is achieved=} by executing both operations. There are four possible diagonal scroll directions. If, for example, the line length is 256 by=}tes and we wish to scroll down and to the right, we must add 256+(-1)=255 to each LMS operand in the display list. This is a =}2-byte add; the BASIC program example given above avoids the difficulties of 2-byte address manipulations but most programs w=}ill not be so contrived. For truly fast two-dimensional scrolling, assembly language will be necessary.PAGE 6-4 ABOVErams w<w0080 All sorts of weird arrangements are possible if we differentially manipulate the LMS bytes. Lines could scroll rA}elative to each other or hop over each other. Of course, some of this could be done with a conventional display but more dataA} would have to be moved to it. The real advantage of LMS scrolling is its speed. Instead of manipulating an entire screenful A}of data, many thousands of bytes in size, a program need only manipulate two or perhaps a few dozen bytes.FINE SCROLLING A}The second important scrolling facility of the ATARI Computer is the fine scrolling capability. Fine scrolling is the capabilA}ity of scrolling a pixel in steps smaller than the pixel size. (Throughout this section the term pixel refers to an entire chA}aracter, not to the smaller dots that make up a character.) Coarse scrolls proceed in steps equal to one pixel dimension; finA}e scrolls proceed in steps of one scan line vertically and one color clock horizontally. Fine scrolling can only carry so farA}; to get full fine scrolling over long distances on the screen you must couple fine scrolling with coarse scrolling. ThereA} are only two steps to implement fine scrolling. First, you set the fine scroll enable bits in the display list instruction bA}ytes for the mode lines in which you want fine scrolling. (In most cases you want the entire screen to scroll so you set all A}the scroll enable bits in all the display list instruction bytes.) Bit D5 of the display list instruction is the vertical scrA}oll enable bit; bit D4 of the display list instruction is the horizontal scroll enable bit. You then store the scrolling valuA}e you desire into the appropriate scrolling register. There are two scrolling registers, one for horizontal scrolling and oneA} vertical scrolling. The horizontal scroll register (HSCROL) is at $D404; the vertical scroll register (VSCROL) is at $D405. A}For horizontal scrolling, you store into HSCROL the number of color clocks by which you wat the mode line scrolled. For vertiA}cal scrolling, you store into VSCROL the number of scan lines that you want the mode line scrolled. These scroll values will A}be applied to every line for which the respective fine scroll is enabled. There are two complicating factors that you encoA}unter when you use fine scrolling. Both arise from the fact that a partially scrolled display shows more information than a nA}ormal display. Consider for example what happens when you horizontally scroll a line by half a character to the left. There aA}re 40 characters in the line. Half of the first character disappears off of the left edge of the screen. The 40th character sA}crolls to the left. What takes its place? Half of a new character should scroll in to take the place of the now scrolled 40thA} character. This character would be the 41st character. But there are only 40 characters in a normal line. What happens? IA}f you have implemented coarse scrolling, then the 41st character suddenly appears on the screen after the first character disA}appears off the left edge. This sudden appearance is jerky and unsightly. The solution to this problem has already been builtA} into the hardware.PAGE 6-5 ABOVEden appearance is jerky and unsightly. The solution to this problem has already been built@#0080There are three display options for line widths: the narrow playfield (128 color clocks wide), the normal playfieldE} (160 color clocks wide) and the wide playfield (192 color clocks wide). These options are set by setting appropriate bits inE} the DMACTL register. When using horizontal fine scrolling, ANTIC automatically retrieves more data from RAM than it displaysE}. For example, if DMACTL is set for normal playfield, which in BASIC mode 0 has 40 bytes per line, then ANTIC will actually rE}etrieve data at a rate appropriate to wide playfield---48 bytes per line. This will throw lines off horizontally if it is notE} taken into account. The problem does not manifest itself if you have already organized screen RAM into long horizontal linesE} as in Figure 6-1. The corresponding problem for vertical scrolling can be handled in either of two ways. The sloppy way iE}s to ignore it. Then you will not get half-images of both ends of the display. Instead, the images at the bottom of the displE}ay will not scroll in properly; they will suddenly pop into view. The proper way takes very little work. To get proper fine sE}crolling into and out of the display region you must dedicate one mode line to act as a buffer. You do this by refraining froE}m setting the vertical scroll bit in the display list instruction of the last mode line of the vertically scrolled zone. The E}window will now scroll without the unpleasant jerk. The screen image will be shortened by one mode line. An advantage of scroE}lling displays now becomes apparent. It is quite possible to create screen images that have more than 192 scan lines in the dE}isplay. This could be disastrous with a static display, but with a scrolling display images which are above or below the dispE}layed region can always be scrolled into view. Fine scrolling will only scroll so far. The vertical limit for fine scrolliE}ng is 16 scan lines; the horizontal limit for fine scrolling is 16 color clocks. If you attempt to scroll beyond these limitsE}, ANTIC simply ignores the higher bits of the scroll registers. To get full fine scrolling (in which the entire screen smoothE}ly scrolls as far as you wish) you must couple fine scrolling with coarse scrolling. To do this, first fine scroll the image,E} keeping track of how far it has been scrolled. When the amount of fine scrolling equals the size of the pixel, reset the finE}e scroll register to zero and execute a coarse scroll. Figure 6-2 illustrates the process.PAGE 6-6 ABOVEixel, reset the finDj0080 ONE STEP -----I} : :--- --- --- --- --- --- --- --- --- ---: : : : : : : : : : : : : : : : : : : :: : :I} : : : : : : : : : : : : : : : :E:: : : : : : : : : : : : :E: :E: : : : :--- --- --- --- -E- -E- --- --- --- ---: : : : :EI}: :E: : : : : : : : : : : : :: : :E: : : : : : : : : : : : : : : : ::E: : : : : : : : : : : : : : : :E: : :--- --- --- ---I} --- --- --- --- --- ---Note:- Blocks 4, 6, 7 should be read as being slightly higher than is possible to show here. It is aI} basic gradient.Figure 6-2 Linking Fine Scroll to Coarse ScrollThe following program illustrates simple fine scrolling:1 I}HSCROL=542762 VSCROL=5427710 GRAPHICS 0:LIST20 DLIST=PEEK(560)+256*PEEK(561)30 POKE DLIST+10,50:REM EnablI}e both scrolls40 POKE DLIST+11,50:REM Do it for two mode lines50 FOR Y=0 TO 760 POKE VSCROL,Y:REM I} Vertical scroll70 GOSUB 200:REM Delay80 NEXT Y90 FOR X=0 TO 3100 POKE HSCROL,X:REM I} Horizontal scroll110 GOSUB 200:REM Delay120 NEXT X130 GOTO 40200 FOR J=1 TO 200210 NI}EXT J:RETURN This program shows fine scrolling taking place at very slow speed. It demonstrates several problems that arisI}e when using fine scrolling. First, the display lines below the scrolled window are shifted to the right. This is due to ANTII}C's automatically retrieving 48 bytes per line instead of 40. The problem arises only in unrealistic demonstration programs sI}uch as this one. In real scrolling applications, the arrangement of the screen data (as shown in Figure 6-1) precludes this pI}roblem.PAGE 6-7 ABOVEl scrolling applications, the arrangement of the screen data (as shown in Figure 6-1) precludes this pH0080The second, more serious problem arises when the scroll registers are modified while ANTIC is in the middle of its M}display process. This confuses ANTIC and causes the screen to jerk. The solution is to change the scroll registers only durinM}g vertical blank periods. This can only be done with assembly language routines. Thus, fine scrolling normally requires the uM}se of assembly language.APPLICATIONS OF SCROLLING The applications of full fine scrolling for graphics are numerous. The M}obvious application is for large maps that are created with character graphics. Using BASIC Graphics mode 2, I have created aM} very large map of Russia which contains about 10 screenfuls of image. The screen becomes a window to the map. The user can sM}croll about the entire map with a joystick. The system is very memory efficient; the entire map program plus data plus displaM}y list and character set definitions requires a total of about 4K of RAM. There are many other applications of this techniM}que. Any very large image that can be drawn with character graphics is amenable to this system. (Scrolling does not require cM}haracter graphics. Map graphics are less desirable for scrolling applications because of their large memory requirements.) LaM}rge electronic schematics could be presented in this way. The joystick could be used both to scroll around the schematic and M}to indicate particular components that the user wishes to address. Large blueprints or architectural diagrams could also be dM}isplayed with this technique. Any big image that need not be seen in its entirety can be presented with this system. LargeM} blocks of text are also usable here, although it might not be practical to read continuous blocks of text by scrolling the iM}mage. This system is more suited to presenting blocks of independent text. One particularly exciting idea is to apply this syM}stem to menus. The program starts by presenting a welcome sign on the screen with signs indicating submenus pointing to otherM} regions of the larger image. "This way to addition" could point up while "this way to subtraction" might point down. The useM}r scrolls around the menu with the joystick, perusing his options. When he wishes to make a choice, he places a cursor on theM} option and presses the red button. Although this system could not be applied to all programs, it could be of great value to M}certain types of programs. There are two "blue sky" applications of fine scrolling which have not yet been fully explored.M} The first is selective fine scrolling, in which different mode lines of the display have different scroll bits enabled. NormM}ally you would want the entire screen to scroll, but it is not necessary to do so. You could select one line for horizontal sM}crolling only, another line for vertical scrolling only, and so forth. The second blue sky feature is the prospect of using dM}isplay list interrupts to change the HSCROL or VSCROL registers on the fly. However, changing VSCROL on the fly is a tricky oM}peration; it would probably confuse ANTIC and produce undesirable results. Changing HSCROL is also tricky but might be easierM}.PAGE 6-8 ABOVEd probably confuse ANTIC and produce undesirable results. Changing HSCROL is also tricky but might be easierL00807SOUND The atari 4OO/8OO home computers have extensive hardware sound capabilities. There are four independenQ}tly controllable sound channels, all able to play simultaneously. Each channel has a frequency register determining the note,Q} and a control register regulating the volume and the noise content. Several options allow you to insert high-pass filters, cQ}hoose clock bases, set alternate modes of operation, and modify polynomial counters.DEFINITION OF TERMS AND CONVENTIONS FQ}or the purposes of this discussion, a few terms and conventions need to be clarified: 1 hZ (hertz) is 1 pulse per seQ}cond 1 khZ (kilo-hertz) is 1,OOO pulses per second 1 mhZ (mega-hertz) is 1,OOO,OOO pulses per second A "pulse" is a Q}sudden voltage rise followed somewhat later by a sudden voltage drop. If a pulse is sent to the television speaker, it will bQ}e heard as a single pop. A "wave" as used here is a continuous series of pulses. There are different types of waves, distiQ}nguished by the shape of the individual pulses. Waves created by the atari computer are square waves (as in figure 7-2). BrasQ}s instruments typically produce triangle waves, and a singer produces sine waves (depicted in figure 7-15). A shift registQ}er is like a memory location (in that it holds binary data) that, when so instructed, shifts all its bits to the right one poQ}sition; I.E., bit 5 will get whatever was in bit 4, but bit 4 will get whatever was in bit 3, etc. Thus, the rightmost bit isQ} pushed out, and the leftmost bit assumes the value on its input wire (see figure 7-1). --------------- BEQ}FORE SHIFT :1::2::3::4::5: --------------- ! ! ! ! ! output input ! ! ! Q} ! ---------> -------->-- ! ! ! ! ! ! ! ! ! ---------------AFTER SHIFT :1::2::3::4:Q}:5: ---------------Note:- The vertical lines have arrows pointing from top to bottom. 1 down to 2, etc.FigurQ}e 7-1 Diagram of Bit Flow of a Shift Register.page 7-1 aboveve arrows pointing from top to bottom. 1 down to 2, etc.FigurP>0080 AUDF1-4 is to be read, "any of the audio frequency registers, 1 through 4." their addresses are: $d2OO, $d2O2, $U}d2O4, $d2O6, (5376O, 53762, 53764, 53766). AUDC1-4 is to be read, "any of the audio control registers, 1 through 4." theirU} addresses are: $D2O1, $D2O3, $D2O5, $D2O7 (53761, 53763, 53765, 53767). For the purposes of this discussion, frequency isU} a measure of the number of pulses in a given amount of time; I.E., a note with a frequency of 1OO Hz means that in one seconU}d, exactly 1OO pulses will occur. The more frequent (hence the term "frequency") the pulses of a note, the higher the note. FU}or example, a singer sings at a high frequency (perhaps 5 khZ), and a cow moos at a low frequency (perhaps 1OO hZ). The wordsU} "frequency," "note," "tone," and "pitch" are used interchangeably. "noise" and "distortion" are used interchangeably althV}ough their meanings are not the same. "noise" is a more accurate description of the function performed by the atari computer.V} The 6O-Hz interrupt referred to later in this section is also called the vertical blank interrupt. All examples are inV} basic unless otherwise stated. Type the examples exactly as they appear. If there are no line numbers, don't use any; and ifV} several statements are on the same line, type them as such.SOUND HARDWARE Sound is generated in the atari computer by thV}e pokey chip, which also handles the serial i/o bus and the keyboard. The pokey chip must be initialized before it will work V}properly. Initialization is required after any serial bus operation (cassette, disk drive, printer, or rs-232 read/write). ToV} initialize pokey in basic, execute a null sound statement; I.E., sound O,O,O,O. In machine language, store a O at audctl ($dV}2O8 = 53768), and a 3 at skctl ($d2Of = 53775, shadowed at $232 = 562).AUDF1-4 Each audio channel has a corresponding freV}quency register that controls the note played by the computer. The frequency register contains the number "n" used in a dividV }e-by-n circuit. This divide is not a division in the mathematical sense, but rather something much simpler: for every n pulseV }s coming in, 1 pulse goes out. For example, figure 7-2 shows a divide-by-4 function:page 7-2 aboveimpler: for every n pulseTd0080 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- :: :: :: :: :: :: :: :: ::Z } :: :: :: :: :: :: :: :: input :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: pulses:: :: :Z }: :: :: :: :: :: :: :: :: :: :: :: :: :: :: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -Z}- -- -- ! ! ! ! ! ! ! Z} ! -- -- -- -- :: :: :: Z} ::output:: :: :: ::pulses:: :: Z} :: :: -- -------------- ----------------- ----------------- ---------- As N gets larger, outZ}put pulses will become less frequent, making a lower frequency note.AUDC1-4 Each channel also has a corresponding controlZ} register. These registers allow the volume and distortion content of each channel to be set. The bit assignment for audc1-4 Z}as follows:AUDC1-4 -------------------------bit number !7 !6 !5 !4 !3 !2 !1 !0 ! ! ! ! ! ! ! !Z} ! ! ------------------------- ! !Vo! volume ! !distortn!On! ! Z} ! !Ll! ! ! ! y! !Figure 7-3 AUDC1-4 bit assignmentVolume The volume conZ}trol for each audio channel is straightforward. The lower 4 bits of the audio control register contain a 4-bit number that spZ}ecifies the volume of the sound. A zero in these bits means zero volume, and a 15 means as loud as possible. The sum of the vZ}olumes of the four channels should not exceed 32, since this forces overmodulation of the audio output. The sound produced teZ}nds to actually lose volume and assume a buzzing quality.DISTORTION Figure 7-3 shows that each channel also has three disZ}tortion control bits in its audio control register. Distortion is used to create special sound effects any time a pure tone iZ}s undesirable. The computer's use of distortion offers great versatility and controllability. It is easy to synthesize of Z}an almost endless variety of sounds, from rumbles, rattles, and squawks to clicks, whispers, and mood setting background tempZ}os.page 7-3 aboveariety of sounds, from rumbles, rattles, and squawks to clicks, whispers, and mood setting background tempX0080 Distortion as used here is not equivalent to the standard interpretation. For example, "intermodulation distorti^ }on" and "harmonic distortion" are quality criteria specified for high-fidelity stereo systems. These types of distortion refe^!}r to waveform degeneration, where the shape of the wave is slightly changed due to error in the electronic circuitry. The com^"}puter's distortion does not alter waves (they are always square waves), but rather deletes selected pulses from the waveform.^#} This technique is not adequately characterized by the word "distortion." a more descriptive and appropriate term for these d^$}istortion methods is "noise". Before you can fully grasp what we mean by distortion, you must understand polynomial counte^%}rs (poly-counters). Poly counters are employed in the atari computer as a source of random pulses used in noise generation. T^&}he atari computer's poly-counters utilize a shift register working at 1.79 MHz. The shift register's contents are shuffled an^'}d fed back into the input; this produces a semi-random sequence of bits at the output of the shift register. For example, ^(}in the diagram below, the old value of bit 5 will be pushed out of shift register to become the next output pulse, and bit 1 ^)}will become a function of bits 3 and 5: input wire->. .-<-shift ! ! register ^*} ! ! ! ! <-random ! ! ! pulse ! ^+} v ! v ----------- v ===========!1!2!3!4!5!----------> " ----------- " ^,}*** ! ! " **** (-' ! =======***** ( ! **** (-----' bit processor->***Figure 7^-}-4 5-Bit Poly-Counter The bit processor gets values from certain bits in the shift register (bits 3 and 5 above), and pro^.}cesses them in a way irrelevant to this discussion. It yields a value that becomes bit 1 of the poly-counter's shift register^/}. These poly-counters are not truly random because they repeat their bit sequence after a certain span of time. As you mig^0}ht suspect, their repetition rate depends upon the number of bits in the poly-counter; I.E., the longer ones require many cyc^1}les before they repeat, while the shorter ones repeat more often.page 7-4 aboventer; I.E., the longer ones require many cyc\Q0080 On the atari computer, distortion is achieved by using random pulses from these poly-counters in a selection cirb3}cuit. This circuit is actually a digital comparator, but "selection circuit" is more descriptive. The only pulses making it tb4}hrough the selection circuit to the output are those coinciding with a random pulse. Various pulses from the input are therebb5}y eliminated in a random fashion. Figure 7-5 illustrates this selection method. A dotted line connects pulses that coincide.b6} - - - - - - - - --Poly-counters ! ! ! ! ! ! ! ! !!random pulses ! ! ! ! ! ! ! ! !! b7} ! ! ! ! ! ! ! ! !! -- -- - --- -- - -- - - - -- -- -- -- -- -- -- -- -- -- -- b8} -- -- -- -- tone pulses :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: from freq. :: :: :: :: ::b9} :: :: :: :: :: :: :: :: :: :: divider :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: -- b:} -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- ! ! ! ! ! b;} ! ! ! ! ! ! ! -- -- -- -- --b<} --tones :: :: :: :: :: ::that :: :: :: :: b=} :: ::make :: :: :: :: :: ::it -- ------ ------ ------------------b>} ------ ---------- -----------Figure 7-5 Selection Function Used To Mix In Distortion The net effect is this: some pb?}ulses from the frequency divider circuit are deleted. Obviously, if some of the pulses are deleted, the note will sound diffeb@}rent. This is how distortion is introduced into a sound channel. Because poly-counters repeat their bit sequences, their obA}utput pattern of pulses is cyclic. And since the selection circuit uses this output pattern to delete pulses from the originabB}l note, the distorted note will contain the same repetitious pattern. This allows the hardware to create noises such as dronebC}s, motors, and other sounds having repetitive patterns. The atari computer is equipped with three poly-counters of differebD}nt lengths, which can be combined in amny ways to produce interesting sound effects. The smaller poly-counters (4 and 5 bits bE}long) repeat often enough to create droning sounds that rise and fall quickly; while the larger poly-counter (17 bits long) tbF}akes so long to repeat that no pattern to the distortion can be readily discerned. This 17-bit poly-counter can be used to gebG}nerate explosions, steam, and any sound where random crackling and popping is desired. It is even irregular enough to be usedbH} to generate white noise (an audio term meaning a hissing sound).page 7-5 aboveired. It is even irregular enough to be used`Q0080 Each audio channel offers six distinct combinations of the three poly-counters:AUDC1-4-----------------!7!6!5fJ}!4!3!2!1!O!----------------- ! ! !-------!O O O! div clock by freq, select using 5 bit then 17 bit polys, div by 2!O x fK}1! div clock by freq, select using 5-bit poly, then div by 2!O 1 O! div clock by freq, select using 5-bit then 4 bit polysfL}, div by 2!1 O O! div clock by freq, select using 17-bit poly, div by 2!1 x 1! div clock by freq, then div by 2 (no poly-fM}counters)!1 1 O! div clock by freq, select using 4 bit poly, div by 2-------notes: "clock" means the input frequency. fN}an "x" means, "it doesn't matter if this bit is set or not."Figure 7-6 available poly-counter combinations These upper fO}audc1-4 bits control three switches in the audio circuit as shown below. This diagram will help you understand why the table fP}of figure 7-6 is structured as it is:page 7-6 aboveuit as shown below. This diagram will help you understand why the table d50080 : to tv : speaker /. / . / +2 . jR} ------- : * / 5--------/ / *-----------! * jS} ! ! ! /. ! / . ! /s c . ! jT} !e i ! ! !l r ! ! !e c ! ! !c u ! ! !jU}t i ! ! !i t ! ! !o ! ! !n ! ! ------ jV} ! ! ! ! ! --------------* ! ! ! *jW} ! / 7------!---------------/ ! --*/ *-- ! ! ! jX} * /. ! . / . ! 6-------. / . ! * .*-- !s c ! jY} ! ! ! !e i ! ! ! ! !l r ! ! ! ! !e c ! ! ! ! jZ}!c u ! ! ! ! !t i ! ! ! ---- !i t ! ! ! !17! !o ! ! ! j[}! ! !n ! ! ! !bp! ------ ! ! !io! ! ! ! !-----! !tl! ------! ! !4 j\}bit! ! y! !5bit!!------* !poly ! ---- !poly! ! !-----! ------ input from j]}div. by (divider byte ??)Figure 7-7 AUDC1-4 Block Diagram. page 7-7.m h`0080 Each combination of the poly-counters offers a unique sound. Furthermore, the distorted sounds can sound quite dn_}ifferent at different frequencies. For this reason some trial and error is necessary to find a combination of distortion and n`}frequency that produces the desired sound effect. Below is a table of guides, just to get you started:AUDC1-4-------------na}----!7!6!5!4!3!2!1!O!----------------- ! ! ! ! ! ! low frequencies middle frequencies high frequencies ! nb}! ! !---------------------------------------------------------------------!-------!O O O!!geiger counter raging firnc}e rushing air steam !!O x 1!!machine gun auto at idle electric motor power transformer !!O 1 O!!nd} calm fire laboring auto auto with a "miss" !!1 O O!! building crashing in radio intene}rference waterfall !!1 x 1!!pure tones !!1 1 O!! airplane nf} lawn mower electric razor !-------!-----------------------------------------------------------ng}----------!figure 7-8sounds produced by distortion combinations at several frequenciespage 7-7 above------------------lk0080VOLUME ONLY SOUND Bit 4 of audc1-4 specifies the volume only mode. When this bit is set, the volume value in audri}c1-4 bits O-3 is sent directly to the television speaker; it is not modulated with the frequency specified in the audf1-4 regrj}isters. To fully understand the use of this mode of operation, you must understand how a speaker works and what happens tork} the television speaker when it receives a pulse. Any speaker has a cone that moves in and out. The cone's position at any tirl}me is directly proportional to the voltage it is receiving from the computer at that time. If the voltage sent is zero, then rm}the speaker is in the resting position. Whenever the cone changes position, it moves air that is detected by your ear as sounrn}d. From our definition of a pulse, you know that it consists of a rising voltage followed by a falling voltage. If you werro}e to send the speaker a pulse, it would push out with the rising voltage and pull back with the falling voltage, resulting inrp} a wave of air that can be detected by your ear as a pop. The following statements will produce such a pop on the television rq}speaker by sending a single pulse:POKE 53761,31:POKE 53761,16 A stream of pulses (or wave) would set the speaker into crr}onstant motion, and a continuous buzz or note would be heard. The faster the pulses are sent, the higher the note. This is hors}w the computer generates sound on the television speaker. It is essential to note that in the volume only mode the volume rt}sent does not drop back to zero automatically, but rather remains constant untill the program changes it. The program should ru}modulate the volume often enough to create a noise. Now try the following statements, listening carefully after each:POKE 5rv}3761,31POKE 53761,31 The first time you heard a pop, which is expected. The speaker pushed out and moved air. But the serw}cond time you didn't. This is because the speaker cone was already in the extended position; another extension command did norx}thing to the speaker, moving no air, so you heard nothing. Now try this:POKE 53761,16POKE 53761,16page 7-8 aboved did nopu0080 Just as before, you heard a pop the first time as the speaker moved back to its resting position, and you heard vz}nothing the second time because the speaker was already in the resting position. Thus, the volume only bit gives the progrv{}am complete control over the position of the speaker at any time. Although the examples given above are only binary examples v|}(either on or off), you are by no means limited to this type of speaker modulation. You may set the speaker to any of 16 distv}}inct positions. For example, a simple triangle wave (similar to the waveform produced by brass instruments) could be generv~}ated by sending a volume of 8 followed by 9, 1O, 11, 1O, 9, 8, 7, 6, 5, 6, 7, and back to 8, and repeating this sequence overv} and over very rapidly. By changing the volume quickly enough, virtually any waveform can be created. It is feasible, for exav}mple, to perform voice synthesis using this technique. It requires the use of assembly language. There is more discussion of v}this bit in a later section.AUDCTl In addition to the independent channel control bytes (audc1-4), there is an option bytv}e (audctl) affecting all four channels. Each bit in audctl is assigned a specific function:AUDCTL ($D2O8 = 53768) if sev}t, this bit...-----------------!7!6!5!4!3!2!1!O!----------------- ! ! ! ! ! ! ! !->switches main clock base from 64 khZ tv}o 15 khZ ! ! ! ! ! ! !--->inserts high-pass filter into chan 2, clocked by chan 4 ! ! ! ! ! !----->inserts high-pass filterv} into chan 1, clocked by chan 3 ! ! ! ! !------->joins channel 4 to channel 3 (16 bit resolution) ! ! ! !--------->joins chv}annel 2 to channel 1 (16 bit resolution) ! ! !----------->clocks channel 3 with 1.79 mhZ ! !------------->clocks channel 1 v}with 1.79 mhZ !--------------->makes the 17 bit poly-counter into a 9 bit poly-counterFigure 7-9 AUDCTL Bit AssignmentCLv}OCKING Before proceeding with the explanations of the audctl options, a new concept must be explained: clocking. In generav}l, a clock is a train of pulses used to synchronize the millions of internal operations occurring every second in any computev}r. The central clock pulses continuously, each pulse telling the circuitry to perform another step in its operations. You mayv} remember that a divide-by-n frequency divider outputs one pulse for every nTH input pulse. You may have wondered where the iv}nput pulses come from. There is one main clock running at 1.79 MHz; it can provide the input pulses.page 7-9 aboveere the itt0080 There are also several secondary clocks that can be used as input clocks. The audctl register allows you to selez}ct which clock is used as the input to the divide-by-n circuit. If you select a different input clock, the output from the frz}equency divider will change drastically. For example, imagine that you are using the 15 khZ clock, and the frequency regisz}ter is set to divide by 8. The rate of output pulses from the divide-by-n circuit would be about 2 khZ. But if you changed thz}e selection of clocks to get the 64 khZ clock and did not change the frequency register, then what would happen? The divide-bz}y-n would still be putting out one pulse for every 8TH input RATE WOULD BE 64 KHz. the result is an output frequency (from thz}e divide-by-N) of 8KHz. The formula for the output frequency (from the divide-by-N) is quite simple: z}clockoutput frequency = ------- N Setting bit 1 of the AUDCTL register switches from the 64-KHz clz}ock to the 15 KHz clock. It is important to note that if this bit is set, every sound channel clocked with the 64 KHz clock wz}ill instead use the 15 KHz clock. Similarly, by setting bits 5 or 6, you can clock channels 3 or 1, respectively, with 1.79 Mz}Hz. This will produce a much higher note, as demonstrated with the following example:SOUND O,255,1O,8 z} Turn on channel 1, low tonePOKE 53768,64 Set AUDCTL bit 616-Bit Frequency Options The eighz}t bits of resolution in the frequency control registers seems to provide more than adequate resolution for the task of selectz}ing any desired frequency. There are, however, situations in which eights bits are inadequate. Consider for example what happz}ens when we execute the following statements:FOR I= 255 TO O STEP -1:SOUND O,1,1O,8:NEXT IThe sound initially rises smootz}hly, but as it approaches the end of its range the frequency takes larger and larger steps which are noticeably clumsy. This z}is because we are dividing the clock by smaller and smaller numbers. 15KHz divided by 255 is almost the same as 15 KHz dividez}d by 254; but 15KHz divided by 2 is very far from 15KHz divided by 1. The only way to solve this problem is to use a larger nz}umber that allows us to specify our frequency with greater precision. The means to do this is built into POKEY.PAGE 7-1O ABz}OVEer that allows us to specify our frequency with greater precision. The means to do this is built into POKEY.PAGE 7-1O ABx0080 AUDCTL bit 3 and 4 allow two channels to be joined, creating a single channel with an extended dynamic frequency~} range. Normally, each channel's frequency divider number can range from O to 255 (8 bits of divide-by-N capability). Joining~} two channels allows a frequency range of O to 65535 (16 bits of divide-by-N capability). In this mode, it is possible to red~}uce the output frequency to less than one Hertz. The following program uses two channels in the 16-bit mode, and two paddles ~}as the frequency inputs. Insert a set of paddles into port 1, type in and run the following program:1O SOUND O,O,O,O ~} Initialize sound2O POKE 53768,8O Clock ch1 w 1.79 MHz, clock ch2 w ch13O POKE~} 53761,16O:POKE 53763,168 Turn off ch1, turn off ch2 (pure tones)4O POKE 5376O,PADDLE(O):POKE 53762,PADDLE(1) ~} set paddles to put freqs in freq regs5O GOTO 4O The right paddle tunes the sound coarsely, and the left paddle fine~}ly tunes the sound between the coarse increments. This program first sets bits 4 and 6 of AUDCTL which means, "clock chann~}el 1 with 1.79 MHz, and join channel 2 to channel 1." Once this happens, the 8-bit frequency registers of both channels are a~}ssumed to represent a single 16-bit number N, used to divide the input clock. Next, channel 1's volume is set to zero. Since ~}channel 1 no longer has its own direct output, its volume setting is meaningless to us and we zero it. Channel 1's frequency ~}register is used as the fine or low byte in the sound generation, and channel 2's frequency register is the coarse or high by~}te. For example, pokeing a 1 into channel 1's frequency register makes the pair divide by 1. Pokeing a 1 into channel 2's fre~}quency register makes the pair divide by 256. And pokeing a 1 into both frequency registers makes the pair divide by 257. ~}Bit 3 of AUDCTL can be used to join channel 4 to channel 3 in precisely the same way.PAGE 7-11 ABOVEpair divide by 257. |f0080 The following instructions demonstrate some interesting aspects of 16-bit sound.SOUND O,O,O,OPOKE 53768,24POK}E 53761,168POKE 53763,168POKE 53765,168POKE 53767,168POKE 5376O,24O:REM try pokeing other numbers into these next 4 locat}ionsPOKE 53764,252POKE 53762,28POKE 53766,49HIGH-PASS FILTERS AUDCTL bits 1 and 2 control high-pass filters in chann}els 2 and 1 respectively. A high-pass filter allows only higher frequencies to pass through. In the case of these high-pass f}ilters, high frequencies are defined to be anything higher than the output of another channel selected by the AUDCTL bit comb}ination. For example, if channel 3 is playing a cow's moo, and AUDCTL bit 2 is set, then only sounds with frequencies higher }than the moo will be heard on channel 1 (anything lower than the "moooo" will be filtered out):!///////////////////////////}///!!//////////////////////////////!!//////////////////////////////!!//////////////////////////////!! ///////////////////}//// ////!! //////////////////// ///!<-cow's moo (played by channel 3)! ///////////////// !! /////////}/////// !! ////////////// ! channel 1! ///// <====================== will only play! ////}///////// ! frequencies in! /////////// ! this shaded area! ////////// !!} ////// !! !! !!--------------------------}-----The Effect of a High-Pass FilterInserted in Channel 1 and Clocked by Channel 3PAGE 7-12 ABOVE--------------------i0080 The filter is programmable in real time since the filtering channel can be changed on the fly. This opens a larg}e field of possiblities to the programmer. The filters are used mostly to create special effects. Try the following statement}s:SOUND O,O,O,OPOKE 53768,4POKE 53761,168:POKE 53765,168POKE 5376O,254:POKE 53764,1279-Bit Polynomial Conversion B}it 7 of AUDCTL turns the 17-bit poly-counter into a 9-bit poly-counter. The shorter the poly-counter, the more often its dist}ortion pattern repeats, or the more discernible the pattern in the distortion. Therefore, changing the 17-bit poly counter in}to a 9-bit poly counter will make the noise pattern more repetitious and more discernible. Try the follwing demonstration of }the 9-bit poly counter option, listening carefully when the POKE is executed:SOUND O,8O,8,8 Use th}e 17-bit polyPOKE 53768,128 Change to the 9-bit polyPAGE 7-13 ABOVE Use th`0080SOUND GENERATION SOFTWARE TECHNIQUES There are two basic ways to use the ATARI Computer sound system: static an}d dynamic. Static sound generation is the simpler of the two; the program sets a few sound generators, turns to other activit}ies for a while, and then turns them off. Dynamic sound generation is more difficult; the computer must continuously update t}he sound generators during program execution. For example:Static sound Dynamic SoundSOUND O,12O,8,8 FOR} X=O TO 255 SOUND O,X,8,8 NEXT XStatic Sound Static sound is normally l}imited to beeps, clicks, and buzzes. There are exceptions. Two examples are the programs given as special effects in the sect}ions on high-pass filters and 16 bit sound. Another way to obtain interesting effects is to use interference, as in this exam}ple:SOUND O,255,1O,8SOUND 1,254,1O,8 The strange effect is a result of closely phased peaks and valleys. Examine Figur}e 7-11. It shows two channels independently running sine waves at slightly different frequencies, and their sum. The sum curv}e shows the strange interference pattern created when these two channels are added.PAGE 7-14 ABOVE their sum. The sum curve0080 ! ! ! + ! * * * * ! *!* * * * * * *ch.1-!--*-!-*---*---*}---*---*---*---*-- ! * ! * * * * * * * - !* ! *! *! * * ! ! ! } + ! *! ! **! ** ! * !* ! * !* * *ch.2-!--*-!-*--!---*---!-*----*-----*-- ! * ! * }! * ! * * * - !* ! !* ! ** * ! ! ! + ! *! ! ! **}ch.1-! * !* ! ** ! * * + !-*--!-*--!--*--*-!-------*---*--ch.2-! * ! * ! * *! * * !* ! } *!* !****** ** - ! ! ! ! ! ! ! !--> pos.+neg.=0 ! ! ! ! }-----------> neg.+neg.=double neg. ! ! ! !---------------> pos.+pos.=double pos.Figure 7-11Two Sine Wave}s at Different Frequencies and Their SumPAGE 7-15 ABOVE---------------> pos.+pos.=double pos.Figure 7-11Two Sine Wave:0080 Figure 7-11 shows that at some points in time the waves are assisting each other, and at other points, they inte}rfere with each other. Adding the volumes of the two waves whose peaks coincide will yield a wave with twice the strength or }volume. Similarly adding the volumes of the two waves while one is at maximum and the other is at minimum will result in a ca}ncellation of both of them. On the graph of the sum curve, we can see this effect. Toward the ends of the graph, volume incre}ases since both channels' peaks and valleys are close together, almost doubling the sound. Toward the middle of the graph, th}e waves oppose each other and the resulting wave is flat. An interesting project might be writing a program to plot interacti}on patterns of 2, 3, and 4 channels as in Figure 7-11. You might discover some unique sounds. The slighter the difference }in frequency between the two channels, the longer the pattern of repetition. To understand this, draw some graphs similar to }Figure 7-11 and study the interaction. As an example, try the following statements:SOUND 0,255,10,8SOUND 1,254,10,8SOUND 1},253,10,8SOUND 1,252,10,8 As the difference in frequency grows, the period of repetition decreases.DYNAMIC SOUND More} complex sound effects normally require the use of dynamic sound techniques. Three methods of dynamic sound generation are av}ailable to the ATARI 400/800 programmer: sound in BASIC, 60-Hz interrupt sound, and sound in machine code.BASIC SOUND BAS}IC is somewhat limited in its handling of sound generation. As you may have noticed, the SOUND statement kills any special AU}DCTL setting. This problem can be avoided by poking valies directly into the sound registers rather than using the SOUND stat}ement. In addition, BASIC is limited on account of its speed. If the program is not completely dedicated to sound generati}on, there is seldom enough processor time to do more than static sound or choppy dynamic sound. The only alternative is to te}mporarily halt all other processing while generating sound.PAGE 7-16 ABOVEoppy dynamic sound. The only alternative is to teL0080 Another problem can occur when using the computer to play music on more than one channel. If all four channel}s are used, the time seperation between the first sound statement and the fourth can be substantial enough to make a noticeab}le delay between the different channels. The following program presents a solution to this problem:10 SOUND 0,0,0,0:DIM S}IMUL$(16)20 RESTORE 9999:X=125 READ Q:IF Q<>-1 THEN SIMUL$(X)=CHR$ (Q):X=X+1:GOTO 2527 RESTORE 10030 READ F1,C1,F2,C2,F3,}C3,F4,C440 IF F1=-1 THEN END50 X=USR(ADR(SIMUL$),F1,C1,F2,C2,F3,C3,F4,C4)55 FOR X=0 TO 150:NEXT X60 GOTO 30100 DATA 182,}168,0,0,0,0,0,0110 DATA 162,168,182,166,0,0,0,0120 DATA 144,168,162,166,35,166,0,0130 DATA 128,168,144,166,40,166,35,1661}40 DATA 121,168,128,166,45,166,40,166150 DATA 108,168,121,166,47,166,45,166160 DATA 96,168,108,166,53,166,47,166170 DATA 9}1,168,96,166,60,166,53,166999 DATA -1,0,0,0,0,0,0,09000 REM9010 REM9020 REM this data contains the machine lang. program,}9030 REM and is read into SIMUL$9999 DATA 104,133,203,162,0,104,104,157,0,210,232,228,203,208,246,96,-1 In this program,} SIMUL$ is a tiny machine language program that pokes all four sound channels very quickly. A BASIC program using SIMUL$ can }rapidly manipulate all four channels. Any program can call SIMUL$ by putting the sound register values inside the USR functio}n in line 50 of the demonstration program. The parameters should be ordered as shown, with the control register value followi}ng the frequency register value, and repeating this ordering one to four times, once for each sound channel to be set. As }a speed consideration as well as a convenience, SIMUL$ allows you to specify sound for less than four channels; i.e., 1,2, an}d 3 or 1 and 2, or just channel 1. Simply don't put the unused parameters inside the USR function. SIMUL$ offers another d}istinct advantage to the BASIC programmer. As mentioned earlier, the AUDCTL register is reset upon execution of any SOUND sta}tement in BASIC. However, using SIMUL$, no SOUND statements are executed, and thus the AUDCTL setting is retained.PAGE 7-17} ABOVE in BASIC. However, using SIMUL$, no SOUND statements are executed, and thus the AUDCTL setting is retained.PAGE 7-170080 There is another, but impractical, method of sound generation in BASIC. This method uses the volume-only bit of }any of the four audio control registers. Type in and run the following program:SOUND 0,0,0,010 POKE 53761,16:POKE 53761,31:}GOTO 10 This program sets the volume-only bit in channel 1 and modulates the volume from 0 to 15 as fast as BASIC can. Thi}s program uses all of the processing time available to BASIC, yet it produces only a low buzz.60-Hz Interrupt This techni}que is probably the most versatile and practical of all methods available to the ATARI Computer programmer. Precisely ever}y 60th of a second, the computer hardware automatically generates an interrupt. When this happens, the computer temporarily l}eaves the mainline program, (the program running on the system; i.e., BASIC, STAR RAIDERS). It then executes an interrupt ser}vice routine, which is a small routine designed specifically for servicing these interrupts. When the interrupt service routi}ne finishes, it executes a special machine language instruction that restores the computer to the interrupted program. This a}ll occurs in such a way (if done properly) that the program executing is not affected, and in fact has no idea that it ever s}topped! The interrupt service routine currently resident on the ATARI 400/800 Computer simply maintains timers, translates} controller information, and performs miscellaneous other chores requiring regular attention. Before the interrupt service} routine returns to the mainline program, it can be made to execute any user routine; i.e., your sound generation routine. Th }is is ideal for sound generation since the timing is precisely controlled, and especially since another program can be execut }ing without paying heed to the sound generator. Even more impressive is its versatility. Because it is a machine language pro }gram, the interrupt sound program will lend itself equally well to a mainline program written in any language - BASIC, assemb }ler, FORTH, PASCAL. In fact, the sound generator will require few, if any, modifications to work with another program or even } another language. A table-driven routine offers maximum flexibility and simplicity for such a purpose. "Table-driven" ref}ers to a type of program that accesses data tables in memory for its information. In the case of the sound generator, the dat}a tables would contain the frequency values and possibly the audio control register values. The routine would simply read the} next entries in the data table, and put them into their respective audio registers. Using this method, notes could change as} often as 60 times per second, fast enough for most applications.PAGE 7-18 ABOVEs. Using this method, notes could change asR0080 Once such a program has been written and placed in memory (say, at location $600), you need to install it as par}t of the 60-Hz interrupt service routine. This si accomplished by a method known as vector stealing. Memory locations $224},$225 contain the address of a small routine called XITVBL (eXIT Vertical Blank Interrupt service routine). XITVBL is designe}d to be executed after all 60-Hz interrupt processing is complete, restoring the computer to the mainline program as previous}ly discussed.The procedure to install your sound routine is as follows:1. Place your program in memory.2. Verify that the }last instruction executed is a JMP $E462 ($E462 is XITVBL, so this will make the mainline program continue).3. Load the x re}gister with the high byte of your routine's address (a 6 in this case).4. Load the y register with the low byte of your rout}ine's address ( a 0 in this case).5. Load the accumulator with a 7.6. Do a JSR $E45C (to set locations $224,$225). Steps} 3-6 are all required to change the value of $224,$225 without error. The routine called is SETVBV (SET Vertical Blank Vector}s), which will simply put the address of your routine into locations $224,$225. Once installed, the system will wrk as follow}s when an interrupt occurs:1. The computer's interrupt routine is executed.2. It jumps to the program whose address is in $}224,$225, which is now your routine.3. Your routine executes.4. Your routine then jumps to XITVBL.5. XITVBL restores the c}omputer and makes it resume normal operation. If you do not wish to implement such a program yourself, there is one availa}ble from the ATARI Program Exchange. The package is called INSOMNIA (Interrupt Sound Initializer/Alterer). It allows creation } and modification of sound data while you listen. It is accompanied by an interrupt sound generator that is table driven and !}compatible with any language.PAGE 7-19 ABOVEen. It is accompanied by an interrupt sound generator that is table driven and .0080MACHINE-CODE SOUND GENERATION Direct control of sound registers with mainline machine language opens new doors i#}n sound generation. The technique is as follows: write a program similar to the 60-Hz interrupt routine in that it is table-d$}riven, but now the mainline routine is dedicated to sound generation. By expanding much more processor time on sound generati%}on, you can produce higher quality sunds. Consider, for example, the output of a typical 60 Hz music routine: ---&}--- ! ! ! ! ! ! ! ! f ! ------- r ! '} ! e ! ! q ! ! ------! ! ! ! ! (} ! ! ! note :<- ->: timeFigure 7-12Example of 3 Music Notes Played wit)}h a 60 Hz Interrupt Music Routine Since much more processing time is available with mainline machine language, we can cha*}nge the frequency at very high speed during the note's playing time so that it simulates an instrument. For example, suppose +}we discovered that whenever any piano key is struck it produces characteristic sequence of frequencies, as shown in Figure 7-,}13. * * * * * * * * * * * * * * * * * -} * * *----- * * * * * * * * .}*Figure 7-13Graph of Frequency Sequence for a Piano Note Let's call the above graph the "piano envelope". To simulate /}a piano, the idea would be to very quickly apply the piano envelope to the plain vanilla beep. The note is thus slightly modi0}fied during its playing time. For example, a piano simulation of the 3 notes in Figure 7-12 would look like this:PAGE 7-20 1}ABOVEuring its playing time. For example, a piano simulation of the 3 notes in Figure 7-12 would look like this:PAGE 7-20 0080 * * * * * * * * * f ! * * *-- r ! !3} e ! ! * q ! ! * * * ! * * * * * ! 4} * * *- * ! ! * * * ! !* * * * * ! 5} !! * * *! !! !! 6} !:<--note--->:Figure 7-14Example of the 3 Notes of Figure 7-10Played With a Piano Envelope We have essentia7}lly the same sound produced by the standard music routine of Figure 7-12, only the notes now have a piano tone, and sound muc8}h prettier than just flat beeps. Unfortunately, we had to sacrifice all other processing to get that piano tone. The sound ch9}annel is no longer updated only once every note, but perhaps 100 times within the note's duration.Volume only sound Earli:}er we experimented with the AUDC1-4 volume only bits, but discovered that they weren't of much use in BASIC. This was due ent;}irely to the fact that BASIC is too slow to effectively use them. This is not the case with machine language. As mentioned<} earlier, this bit offers a tremendous capacity for accurate sound reproduction. True waveform generation (to the time and vo=}lume resolution limits of the computer) is made possible with this bit. Instead of just putting a piano flavor into the music>}, you can now make it closely replicate a piano sound. Unfortunately, it can never precisely duplicate an instrument. 4 bits ?}(16 values) is not enough volume resolution for truly high-quality work. Nevertheless, the technique does generate surprising@}ly good sounds. The following program demonstrates the use of one of the volume only bits. If you have an assembler, type it A}in and try it:PAGE 7-21 ABOVErogram demonstrates the use of one of the volume only bits. If you have an assembler, type it 0080 0100 ; 0110 ; VONLY Bob Fraser 7-23-81 0120 ; 0130 ; C} 0140 ; volume-only AUDC1-4 bit test routine 0150 ; 0160 ; 0170 ; 0180 ;D}D208 0190 AUDCTL = $D208D200 0200 AUDF1 = $D200D201 0210 AUDC1 = $D201D20F 0220 SKCTL E} = $D20F 0230 ; 0240 ;0000 0250 *= $B000B0 01 0260 TEMPO .BYTE 100B1 00 F}0270 MSC .BYTE 0 0280 ; 0290 ; 0300 ;00B2 0310 *= $40004000 A900 03G}20 LDA #04002 8D08D2 0330 STA AUDCTL4005 A903 0340 LDA #34007 8D0FD2 0350 STA SKCTL400A A20H}0 0360 LDX #0 0370 ;400C A900 0380 LDA #0400E 8D0ED4 0390 STA $D40E kill vbi's4011 I}8D0ED2 0400 STA $D20E kill irq's4014 8D00D4 0410 STA $D400 kill dma 0420 ; 0430 ;J} 0440 ;4017 BD5240 0450 LOO LDA DTAB,X401A 85B1 0460 STA MSC 0470 ;401C BD3640 0480 K} LDA VTAB,X401F A4B0 0490 L0 LDY TEMPO4021 8D01D2 0500 STA AUDC14024 88 0510 L1 DEY4025 D0FD 05L}20 BNE L1 0530 ; 0540 ; dec most sig ctr4027 C6B1 0550 DEC MSC4029 D0F4 0560 M} BNE L0 0570 ; 0580 ; 0590 ; new note 0600 ;PAGE 7-22 ABOVEF4 0560 o0080402B E8 0610 INX402C EC3540 0620 CPX NC402F D0E6 0630 BNE LOO 0640 ; O} 0650 ; wrap note pointer4031 A200 0660 LDX #04033 F0E2 0670 BEQ LOO 0680 ; P} 0690 ;4035 1C 0700 NC .BYTE 28 note count 0710 ; 0720 ; table of volumes to be played in Q}succession 0730 VTAB4036 18 0740 .BYTE 24,25,26,27,28,29,30,314037 194038 1A4039 1B403A 1C403B 1R}D403C 1E403D 1F403E 1E 0750 .BYTE 30,29,28,27,26,25,24403F 1D4040 1C4041 1B4042 1A4043 194044 184045 17 S} 0760 .BYTE 23,22,21,20,19,18,174046 164047 154048 144049 13404A 12404B 11404C 12 0770 .BYTE 18,1T}9,20,21,22,23404D 13404E 14404F 154050 164051 17 0780 ; 0790 ; this table contains the duration U}of each entry above 0800 DTAB4052 01 0810 .BYTE 1,1,1,2,2,2,3,64053 014054 014055 024056 024057 V}024058 034059 06PAGE 7-23 ABOVE0 DTAB4052 01 0810 .BYTE 1,1,1,2,2,2,3,64053 014054 014055 024056 024057 #0080405A 03 0820 .BYTE 3,2,2,2,1,1,1405B 02405C 02405D 02405E 01405F 014060 014061 01 0830 X} .BYTE 1,1,2,2,2,3,64062 014063 024064 024065 024066 034067 064068 03 0840 .BYTE 3,2,2,2,1,14069 02406A 0Y}2406B 02406C 01406D 01 Suprisingly, speed is not really a problem here. The wave has almost 60 steps, and the program cZ}an still be made to play the wave at up to 10 Khz. Remove lines 400-410, and try the program once more. It will sound quit[}e broken up. The cause is the 60 Hz interrupt discussed in the previous section. You can actually hear the interrupts taking \}place since all sound stops during that time. Line 420 disables screen DMA. This is why the screen goes to solid backgroun]}d color when the program is executed. It serves two purposes: to speed up the processor, and to make the timing consistent, s^}ince DMA steals cycles at odd intervals. In this demonstration program, the sound created is a sine wave. The wave is rema_}rkably pure, and does indeed sound like a sine wave. If graphed, the data looks like this:PAGE 7-24 ABOVE. The wave is remak008015-! ------14-! --- ---13-! -- --12-! -- --11-! -a}- --10-! - - 9-! - - 8=!-----------------------------b}------------------------------------------- 7-! - - 6-! c} - - 5-! -- -- 4-! d} -- -- 3-! -- -- 2-! e} --- --- 1-! ------Figure 7-15Graphf} of Sine Wave data for Volume Only Program This section has discussed the technical aspects of sound generation with the Ag}TARI Computer. The programmer must also understand the broader role of sound in the complete software package. Movie makerh}s have long understood the importance of mood setting background music. The recent space adventure movies by George Lucas arei} excellent examples. When the villain enters the room you know immediately to fear and hate him from the menacing background j}rhythms accompanying his entry. You gleefully clap your hands when the hero saves the princess while gallant music plays in tk}he background. Likewise, horror films can frighten you by merely playing eerie music, even though the action may be completell}y ordinary. SPACE INVADERS (trademark of Taito America Corp) issues a personal threat to its player and victim with its ecm}hoing stomp. As the tempo increases, knuckles whiten and teeth grind. When a Zylon from STAR RAIDERS fires a photon torpedo yn}ou push frantically on the control to avoid impact. As it bores straight for your forehead, times slows and you hear it hissio}ng louder and louder as it approaches. Just before impact, you duck and dislodge yourself from your armchair. Impressionisp}tic sounds affect our subconcious and our state of mind. This is due possibly to the fact that sounds, if present, are continq}uously entering our mind whether or not we are actively listening. Visual inputs, on the other hand, require the user's attenr}tion. If we are distracted from the TV set, we cease to concentrate on the picture and the image leaves our mind. Sound theres}fore offers the programmer a direct path to the user's mind - bypassing his thought processes and zeroing in on his emotions.t}PAGE 7-25 ABOVEogrammer a direct path to the user's mind - bypassing his thought processes and zeroing in on his emotions.00808THE OPERATING SYSTEMINTRODUCTION With every Atari home computer system comes an Atari 10K Operating system v}cartridge. The importance of this cartridge is often overlooked. Without it, you have a lot of potential, but absolutely nothw}ing else! This situation is not unique to the Atari; it is encountered with all computers. A computer is, after all, merely ax} collection of hardware devices. A user must manage these resources to accomplish any task. If all programmers had to start fy}rom scratch on each program, we would have an even larger software shortage than we have today. The solution that has evolvedz} over the years is to build in a program that manages the resources available to the system, and eases the programming burden{} required to control them. This program is known by various names:- operating system, master control program, system executiv|}e, system monitor, etc. In the Atari it is known as the operating system or OS. The first task facing the student of the o}}perating system, is to take an inventory of exactly what resources are available to the OS. These are:-6502 microprocessorR~}AM memory (various amounts)ANTIC LSI integrated circuitCTIA LSI integrated circuitPOKEY LSI integrated circuitPIA peri}pheral interface adaptor integrated circuit By using these resources, the OS can interact with and control a wide variety }of external hardware devices, including a television receiver/monitor, keyboard, console speaker, console switches, joysticks}, paddles, cassette recorder, disk drive, printers, RS-232 interface and modem. The remainder of this subsection briefly l}ists the main elements of the OS. These elements are described in detail in following subsections.MONITOR. The OS monitor }is the system routine that is executed when the computer is turned on or the [SYSTEM RESET] button is pressed. Through this r}outine the OS takes control of the system; it does not relinquish control unless control unless control is taken away from it} by the programmer. The monitor sets up the memory management system, initializes the I/O subsystem, sets up system vectors a}nd selects the execution environment after initialization is complete.INTERRUPT PROCESSING STRUCTURE. The computer utilizes }the standard interrupt processing structure of the 6502 microprocessor, with some external augmentation for enhanced flexibil}ity. Interrupts are generated by numerous events, including keyboard strokes, the [BREAK] keystroke, some serial bus events, }system timer timeouts, and the vertical blank interval on the television.page 8-1 above keystroke, some serial bus events, Y0080OS SYSTEM VECTORS. The system vectors provide a mechanism that allows users to access system routines, or customize} the OS for special needs. The most frequent uses of the vectors are to call I/O system routines, set timers, and transfer co}ntrol to different environments. System routines may be vectored to in one of two ways. ROM vectors are locations that contai}n JMP instructions to system routines and cannot be altered. RAM vectors are RAM locations that contain alterable addresses o}f system routines. The locations of both types of vectors are guaranteed to remain the same in future releases of the OS.INP}UT/OUTPUT SUBSYSTEM. The OS gives an application programmer access to the full capabilities of the computer's peripherals. Th}e Input/Output subsystem is a set of routines that link high level I/O operations with device handlers that control the physi}cal I/O hardware.REAL TIME PROGRAMMING. The Atari computer is well equipped to deal with problems in the "real time domain".} To facilitate this feature, The OS has two types of timers:- hardware timers and system software timers. Hardware timers ar}e countdown timers that can be used to time events with durations that range from half a microsecond to several seconds. Syst}em timers are software timers that tick at 60 Hertz, and can be used for applications as diverse as serial bus timing and sou}nd effect generation.ROM CHARACTER SET. The computer is equipped with what is known as a "soft character set", i.e., it can} be changed. The ROM-based character set is used to provide a standard character set at power-up.FLOATING POINT PACKAGE. T}he floating point package is a set of mathematical routines that extend the arithmetic capability of the system. The routines} use binary coded decimal (BCD) arithmetic to provide standard mathematical functions (+, -, *, /), exponential and logarithm}ic functions as well as conversion from ATASCII to BCD and BCD to ATASCII.page 8-2 above, *, /), exponential and logarithm[0080THE MONITOR The OS monitor is that portion of the OS ROM that handles both the power-up and SYSTEM RESET sequencÛ}es. These sequences allow the OS to gain initial control of the computer and ensure that everthing is properly initialized beÜ}fore releasing partial control to an application program. Both sequences are similar in function and in fact share much of thÝ}e same code. The power-up routine (also known as Coldstart) is invoked either by turning on the computer or by jumping to Þ}COLDSV ($E477), a system routine vector. Important items to remember about the power-up sequence are: 1. ALL of RAM memorß}y is cleared except locations $0000-$000F. 2. Both a cassette and disk boot are attempted. BOOT? ($0009) is a flag that inà}dicates the success or failure of the boots. Bit 0 = 1 for a successful cassette boot; Bit 1 = 1 for a successful disk boot.á} 3. COLDST ($0244) is a flag that tells the Monitor that it is in the middle of power-up. COLDST=0 means [SYSTEM RESET] keyâ} has been pressed, whereas COLDST<>0 indicates initial power-up. The COLDST flag can be used to gain a certain amount of progã}ram security. If COLDST is set to a non-zero value during program execution, then pressing [SYSTEM RESET] will initiate the pä}ower-up sequence. This will prevent the user from gaining control of the computer while the program is running. Pressing tå}he [SYSTEM RESET] key causes a SYSTEM RESET (also known as Warmstart). Some of the key facts to remember about the SYSTEM RESæ}ET sequence are: 1. The OS RAM vectors are downloaded from ROM during both SYSTEM RESET and power-up sequences. If you wisç}h to "steal" a vector, some provision must be made to handle SYSTEM RESET. See the MEMORY MANAGEMENT subsection of this sectiè}on for suggestions on how this is done. 2. MEMLO, MEMTOP, APPMHI, RAMSIZ and RAMTOP are reset during System Reset. If you é}wish to alter these RAM pointers to reserve some space for assembler modules called by BASIC, you must make some provision foê}r handling SYSTEM RESET. Figure 8-3 provides an example of how to do this. The next few pages present a detailed flowchartë} for the power-up and SYSTEM RESET sequences.PAGE 8-3 ABOVE to do this. The next few pages present a detailed flowchart>0080What would normally follow on the next four pages should be four full page drawings of how an operating system workǭ}s, i.e.- boxes and lines and how they all connect together to carry out a specific task. Due to the limitations of graphics aǮ}nd drawing and some printers, it was not practical to attempt to draw them, it is at this point it must be said that there maǯ}y be some of you who would desire these items and so I must reccommend that you should attempt to get hold of a photocopy of ǰ}them, either from the book or from an existing photocopy. There are several drawings throughout the book. It is reccommended DZ}that you also print this page as a reminder to yourself just in case you ever wish to get the said pages. The importance of tDz}he drawings is relative to one's technical ability and the ambition to learn, therefore, if you don't have the ability or thedz} thirst for knowledge you will not find any major use for the drawings. I am truly sorry I couldn't do them because this makeǴ}s all the hard work done already, somewhat incomplete but nevertheless extremely useful. TORPEDO, EDITOR.ŠӠǵ}śPAGE 8-4 ABOVEŠӠśPAGE 8-5 ABOVEŠӠśPAGE 8-6 ABOVEŠԠӠǶ}PAGE 8-7 ABOVEVEŠӠśPAGE 8-5 ABOVEŠӠśPAGE 8-6 ABOVEŠԠӠ0080MEMORY MANAGEMENT The fact that the OS is written for a 6502 microprocessor dictates a number of overall memory˸} management decisions. In the 6502, there are three special regions in the memory address space. Page zero has crucial signif˹}icance in that the use of data values on this page will result in tighter, faster executing code. Indeed, there are instructi˺}ons that absolutely require page zero locations to work. Page one is special because it is used for the 6502 stack. Addresses˻} $FFFA - $FFFF are also special because they are reserved for hardware reset and interrupt vectors. Thus, the first task o˼}f memory management is to assign the OS ROM to the highest part of memory address space. The OS resides in the address space ˽}from $D800 to $FFFF. Just under this area is the space reserved for the hardware registers in ANTIC, CTIA, and POKEY. These r˾}eside in the $D000-$DFFF range. At the other end of memory address space, the OS reserves half of page zero for its own us˿}e. Pages two, three, four and five are also reserved for OS usage. From a programming viewpoint, the usable memory area runs }from $0600 to $BFFF. When the system is powered-up, one of the fist actions taken by the OS is to determine how much RAM m}emory is present. This is accomplished by checking the first byte of each 4K block of memory starting at $1000. The contents }of this byte are read, complemented and an attempt is made to store the complemented value back out. If this attempt is succe}ssful, the temporary memory size counter is incremented by 4K. This process continues until a location is found that cannot b}e changed. Two variables, RAMTOP and RAMSIZ contain the number of RAM pages present. In addition to these locations, pointers} MEMLO, MEMTOP and APPMHI are maintained by the OS memory management routines. The relationships between these pointers are s}hown in Figure 8-2, a simple memory map. MEMLO is a 2-byte location that the OS uses to indicate where an application prog}ram may begin. You can modify MEMLO to create reserved areas for assembly language routines that may be called from BASIC. BA}SIC uses the value in MEMLO to determine the starting location of a program (see Section 10 for a discussion of the structure} of a BASIC program). If the value of MEMLO is changed to a higher address, it must be done before control is transferred to }the BASIC cartridge. This is a tricky operation, because MEMLO is reset by both power-up and SYSTEM RESET. If an applicati}on program is running in a disk drive environment, the AUTORUN.SYS facility can be used to change MEMLO to reserve space. How}ever, DOS is also initialized during SYSTEM RESET via the DOSINI vector ($000C). This vector contains the address of the DOS }initialization code called as part of the monitor system initialization. DOSINI is also the only point at which you can "trap}" the SYSTEM RESET sequence. Since the DOS initialization must occur regardless of what is done to the MEMLO pointer, you mus}t allow the normal initialization to occur before "stealing" the DOSINI vector. This may be done by moving the contents of DO}SINI into the 2-byte address of a JSR information on the AUTORUN.SYS feature).PAGE 8-8 ABOVEe by moving the contents of DO_0080Just after the JSR instruction, place the code which sets MEMLO to a new value. Follow this with a RTS instruction.} DOSINI must then be reset to the address of the JSR instruction. When a SYSTEM RESET occurs, the new code sequence is called} and the first instruction, JSR OLDDOSINI, initializes DOS. The remaining code is then executed which sets MEMLO to its new v}alue and then rejoins the rest of the initialization sequence. Figure 8-3 presents an example showing how to do this. The }above technique can also be used with MEMTOP, the user high memory pointer. This pointer indicates the highest RAM address ac}cessible to an application program. This RAM address differs from the highest physical RAM address because the OS allocates s}ome RAM at the very top of RAM for its display list and display data. Space for assembly language modules and data can be set} aside by lowering MEMTOP from the values set by power-up and SYSTEM RESET. Using MEMTOP instead of MEMLO to reserve space do}es create one problem. The value of MEMTOP depends on both the amount of RAM in the system and the graphics mode of the displ}ay. This makes it difficult to predict its value before actually examining the location unless you make assumptions about the} system configuration. This uncertainty over the final location of the machine code forces the programmer to use only relocat}able code. APPMHI is a location that contains an address specifying the lowest address to which the display RAM may extend}. Correctly setting APPMHI ensures that the display handler will not clobber some of your program code or data. RAMSIZ, li}ke MEMTOP, can also be used to reserve space for user routines or data. Since RAMSIZ is a single byte value that contains the} number of RAM pages present (i.e., groups of 256 bytes), lowering its value by 1 will reserve 256 locations. The advantage o}f using RAMSIZ instead of MEMTOP is that the space saved by moving RAMSIZ down is above the display memory, whereas space sav}ed by moving MEMTOP down remains below the display memory.PAGE 8-9 ABOVEown is above the display memory, whereas space savK0080 MEMORY MAP OS BASIC RAM ------------ } : : : PAGE : : SIX :MEMLO 2E7,2E8 : :------------------------}-- : : : DOS : : : 80,81 LOMEM --------------}----------- : : : BASIC : : TOKEN : : PROGRAM :APPMH}I OE,OF : : 90,91 MEMTOP--------------------------------------- : : OE,OF APHM } : : ! : FREE : ! : RAM : FRE(0) : : }! : : !MEMTOP 2E5,2E6: :2E5,2E6 HIMEM---------------------------------------SDLST 230},231 : : : DISPLAY : : LIST :SAVMSC 58,59 : :--------------------------} : : : SCREEN : : RAM :TXTMSC 294,295: :----------------}---------- : : : TEXT : : WINDOW :RAMTOP 6A : :RAMSIZ} 2E4----------------Figure 8-2 OS and Basic Pointers (DOS present)PAGE 8-10 ABOVE 6A : :RAMSIZc0080 0010 ; RESET THE MEMLO POINTER 0020 ;0600 0030 START = $600000C 0040 }DOSINI = $0C02E7 0050 MEMLO = $2E73000 0060 NEWMEM = $3000 ; THIS IS THE NEW VALUE FOR M}EMLO 0065 ; 0070 ; THIS ROUTINE RESERVES SPACE FOR ASSEMBLY ROUTINES 0090 ; BY RESETTING }THE MEMLO POINTER. IT RUNS AS 0100 ; AN AUTORUN.SYS FILE. IT ALSO RESETS MEMLO ON [RESET]. 0120 ; MEM}LO IS SET TO THE VALUE OF NEWMEM. 0130 ; 0140 ; THIS PART IS PERMANENT, IE. NEEDS TO BE RESIDENT. } 0150 ; THE SYSTEM DOSINI VECTOR HAS BEEN STOLEN 0160 ; AND STORED IN THE ADDRESS PORTION OF THE JSR TROJ}AN 0170 ; INSTRUCTION. SO WHEN [RESET] IS PRESSED, DOSINI VECTORS 0180 ; TO INITDOS, JSR TROJAN THEN }CALLS THE DOS INITIALIZATION 0185 ; ROUTINES, MEMLO IS RESET TO NEW VALUE AND CONTROL 0190 ; RETURNS }TO THE MONITOR.0000 0200 *= START 0210 INITDOS0600 200D06 0220 JSR TROJAN DO DOS INIT}IALIZATION0603 A900 0230 LDA #NEWMEM&2550605 8DE702 0240 STA MEMLO0608 A930 0250 LDA #NEWMEM/2}56060A 8DE802 0260 STA MEMLO+1 0270 TROJAN060D 60 0280 RTS 0290 ; THIS PART IS E}XECUTED AT POWER UP ONLY AND 0300 ; CAN BE DELETED AFTER POWER-UP. 0330 ; THIS ROUTINE STORES THE CON}TENTS OF DOSINI INTO THE JSR 0350 ; TROJAN INSTRUCTION. IT THEN REPLACES DOSINI WITH 0370 ; A NEW VAL}UE, LOCATION INITDOS. 0390 GRABDOSI060E A50C 0400 LDA DOSINI ; SAVE DOSINI0610 8D0106 0410 } STA INITDOS+10613 A50D 0420 LDA DOSINI+10615 8D0206 0430 STA INITDOS+20618 A900 0440 LDA #INI}TDOS+255 ; SET DOSINI061A 850C 0450 STA DOSINI061C A906 0460 LDA #INITDOS/256061E 850D 0470 ST}A DOSINI+10620 A500 0480 LDA NEWMEM&255 ; SET MEMLO0622 8DE702 0490 STA MEMLO0625 A930 050}0 LDA #NEWMEM/2560627 8DE802 0510 STA MEMLO+1062A 60 0520 RTS062B 0530 *= $2E202E}2 0E06 0540 .WORD GRABDOSI ; SET RUN ADDRESS02E4 0550 .ENDFigure 8-3 Reset MEMLOPA}