home *** CD-ROM | disk | FTP | other *** search
/ 8bitfiles.net/archives / archives.tar / archives / genie-commodore-file-library / Information / HACKING6A.SFX / hacking6a
Encoding:
Text File  |  1993-09-17  |  34.6 KB  |  795 lines

  1.  
  2.                    ########
  3.              ##################
  4.          ######            ######
  5.       #####
  6.     #####  ####  ####      ##       #####   ####  ####  ####  ####  ####   #####
  7.   #####    ##    ##      ####     ##   ##   ##  ###     ##    ####  ##   ##   ##
  8.  #####    ########     ##  ##    ##        #####       ##    ## ## ##   ##
  9. #####    ##    ##    ########   ##   ##   ##  ###     ##    ##  ####   ##   ##
  10. #####  ####  ####  ####  ####   #####   ####  ####  ####  ####  ####   ######
  11. #####                                                                     ##
  12.  ######            ######           Issue #6
  13.    ##################             Date ##, 1993
  14.        ########
  15.  
  16. -------------------------------------------------------------------------------
  17. Editor's Notes:
  18. by Craig Taylor
  19.  
  20.   School, 2 jobs, a play, and other work has seriously restricted the amount
  21.   of time that I am able to devote to Commodore Hacking. What I am looking at
  22.   doing now is to stop writing articles for Commodore Hacking and hoping that
  23.   I'll still have enough time to write these notes, and organize and pull all
  24.   the other articles by other contributors together. The two articles I
  25.   had hoped to include in this issue : the one about multi-tasking and
  26.   about the 1351 have again been delayed. I've decided to go ahead and
  27.   release issue 6 and hopefully will have them in the next issue.
  28.   (Remember: You get what you pay for.. *smile*)
  29.  
  30.   As always, Commodore Hacking is constantly looking for articles, notes,
  31.   short little programs, what-not on any side of the Commodore 64 and 128 -
  32.   primarily on the technical or hardware side. If you think you have something
  33.   in mind, or already written then feel free to drop me a line letting me
  34.   know.
  35.  
  36.   In regards to several queries recently about reprinting individual articles
  37.   that have appeared in Commodore Hacking. You may reprint Commodore Hacking
  38.   and redistribute in whole, freely. For use of individual articles you _must_
  39.   contanct the individual author as they still retain rights to it. Please see
  40.   the legal notice / mumbo below.
  41.  
  42.   I recently recieved some mail from wolfgang@halcyon regarding a disk
  43.   magazine that he was in the process of starting and he has written the
  44.   following preview of a disk magazine that looks to be exciting:
  45.  
  46.     "_Scenery_, a new disk-magazine focusing on the american and
  47.     european demo scenes, will soon be available for download at a
  48.     site/BBS near you! With articles on everything from coding to
  49.     instrument synthesis to art, _Scenery_ will be the definitive word
  50.     when it comes to creating a demo, or simply coding in general.
  51.     Articles are being written by some of the top names in the scene,
  52.     and promise to help everybody from the Basic Baby to the ML Mogul!
  53.     Set to be released mid-August, _Scenery_ will hopefully be a worthy
  54.     edition to the likes of Coder's World and C=Hacking.  I am making
  55.     the magazine available on various Internet sites, so look for it. We
  56.     are always on the lookout for art, music, and coding talent, and if
  57.     you'd be interested in submitting an article for publication, or
  58.     simply have a question or comment, please mail me at
  59.     'wolfgang@halcyon.com'. Thanks.. and see you on the Net!"
  60.  
  61. ================================================================================
  62.  
  63.   Please note that this issue and prior ones are available via anonymous FTP
  64.   from ccosun.caltech.edu under pub/rknop/hacking.mag and via a mailserver
  65.   which documentation can be obtained by sending mail to
  66.   "duck@pembvax1.pembroke.edu" with a subject line of "mailserver" and the
  67.   line "help" in the body of the message.
  68.  
  69. ================================================================================
  70.  
  71.   NOTICE: Permission is granted to re-distrubte this "net-magazine", in
  72.   whole, freely for non-profit use. However, please contact individual 
  73.   authors for permission to publish or re-distribute articles seperately.
  74.   A charge of no greather than 5 US dollars or equivlent may be charged for 
  75.   library service / diskette costs for this "net-magazine".
  76.  
  77. ================================================================================
  78. In This Issue:
  79.  
  80. DYCP - Horizontal Scrolling
  81.  
  82. DYCP - is a name for a horizontal scroller, where characters go smoothly
  83. up and down during their voyage from right to left. One possibility is a
  84. scroll with 8 characters - one character per sprite, but a real demo coder
  85. won't be satisfied with that.
  86.  
  87. Opening the borders
  88.  
  89. VIC has many features and transparent borders are one of them. You can not
  90. make characters appear in the border, but sprites are displayed in the
  91. border too.
  92.  
  93. 64 Documentation
  94.  
  95. This file, taken directly from a Commodore 64 emulator and development
  96. system being developed is full of information about undocumented
  97. opcodes, processor timings, memory configurations and the such. A
  98. must-have reference article.
  99.  
  100. A Heavy Duty Power supply for the C-64
  101.  
  102. This article describes how to build a heavier duty power supply for your
  103. Commodore 64 computer and includes a full schematic in GeoPaint format.
  104.  
  105. LZW Compression
  106.  
  107. LZW is perhaps the most widely used form of data compression today. It
  108. is simple to implement and achieves very decent compression at a fairly
  109. quick pace. LZW is used in PKZIP (shrink),PKARC (crunch), gifs,V.42bis
  110. and unix's compress. This article will attempt to explain how the
  111. compression works with a short example and 6502 source code in Buddy
  112. format.
  113.  
  114. THREE-KEY ROLLOVER for the C-128 and C-64.
  115.  
  116. This article examines how a three-key rollover mechanism works for the
  117. keyboards of the C=128 and C=64 and will present Kernal-wedge
  118. implementations for both machines. Webster's doesn't seem to know, so I'll
  119. tell you that this means that the machine will act sensibly if you are
  120. holding down one key and then press another without releasing the first.
  121. This will be useful to fast touch typers.
  122.  
  123. ================================================================================
  124. The Demo Corner: DYCP - Horizontal Scrolling
  125. by Pasi 'Albert' Ojala (po87553@cs.tut.fi or albert@cc.tut.fi))
  126.         Written: 16-May-91 Translation 02-Jun-92
  127.  
  128.         DYCP - too many sprites !?
  129.         --------------------------
  130.  
  131. DYCP - Different Y Character Position - is a name for a horizontal scroller,
  132. where characters go smoothly up and down during their voyage from right to
  133. left. One possibility is a scroll with 8 characters - one character in each
  134. sprite, but a real demo coder won't be satisfied with that.
  135.  
  136. Demo coders thought that it looks good to make the scrolling text change its
  137. vertical position in the same time it proceeded from the right side of the
  138. screen to the left. The only problem is that there is only eight sprites
  139. and that is not even nearly enough to satisfy the requirements needed for
  140. great look. So the only way is to use screen and somehow plot the text in
  141. graphics, because character columns can not be scrolled individually.
  142. Plotting the characters take absolutely too much time, because you have to
  143. handle each byte seperately and the graphics bitmap must be cleared too.
  144.  
  145.  
  146. _Character hack_
  147.  
  148. The whole DYCP started using character graphics. You plot six character
  149. rows where the character (screen) codes increase to the right and down.
  150. This area is then used like a small bitmap screen. Each of the text chars
  151. are displayed one byte at a time on each six rows high character columns.
  152. This 240 character positions big piece of screen can be moved horizontally
  153. using the x-scroll register (three lowest bits in $D016) and after eight
  154. pixels you move the text itself, like in any scroll. The screen is of course
  155. reduced to 38 columns wide to hide the jittering on the sides.
  156.  
  157. A good coder may also change the character sets during the display and
  158. even double the size of the scroll, but because the raster time happens
  159. to go to waste using this technique anyway, that is not very feasible. There
  160. are also other difficulties in this approach, the biggest is the time needed
  161. to clear the display.
  162.  
  163.  
  164. _Save characters - and time_
  165.  
  166. But why should we move an eight-byte-high character image in a 48-line-high
  167. area, when 16 is really enough ?  We can use two characters for the graphics
  168. bitmap and then move this in eight pixel steps up and down. The lowest
  169. three bits of the y-position then gives us the offset where the data must
  170. be plotted inside this graphical region. The two character codes are usually
  171. selected to be consecutive ones so that the image data has also 16
  172. consecutive bytes. [See picture 1.]
  173.  
  174.  
  175. _Demo program might clear things up_
  176.  
  177. The demo program is coded using the latter algorithm. The program first
  178. copies the Character ROM to ram, because it is faster to use it from there.
  179. You can easily change the program to use your own character set instead,
  180. if you like. The sinus data for the vertical movement is created of a 1/4
  181. of a cycle by mirroring it both horizontally and vertically.
  182.  
  183. Two most time critical parts are clearing the character set and plotting the
  184. new one. Neither of these may happen when VIC is drawing the area where the
  185. scroll is, so there is a slight hurry. Using double buffering technique we
  186. could overcome this limitation, but this is just an example program. For
  187. speed there is CLC only when it is absolutely needed.
  188.  
  189. The NTSC version is a bit crippled, it only covers 32 columns and thus the
  190. characters seem to appear from thin air. Anyway, the idea should become
  191. clear.
  192.  
  193.  
  194. _Want to go to the border ?_
  195.  
  196. Some coders are always trying to get all effects ever done using the C64 go
  197. to the border, and even successfully. The easiest way is to use only a region
  198. of 21 pixels high - sprites - and move the text exactly like in characters.
  199. In fact only the different addressing causes the differences in the code.
  200.  
  201. Eight horizontally expanded sprites will be just enough to fill the side
  202. borders. You can also mix these techiques, but then you have the usual
  203. "chars-in-the-screen-while-border-opened"-problems (however, they are
  204. solvable). Unfortunately sprite-dycp is even more slower than char-dycp.
  205.  
  206.  
  207. _More movement vertically_
  208.  
  209. You might think that using the sprites will restrict the sinus to only
  210. 14 pixels. Not really, the only restriction is that the vertical position
  211. difference between three consequent text character must be less than 14
  212. pixel lines. Each sprites' Y-coordinate will be the minimum of the three
  213. characters residing in that sprite. Line offsets inside the sprites
  214. are then obtained by subtracting the sprite y-coordinate from the character
  215. y-coordinate. Maybe a little hard to follow, but maybe a picture will
  216. clear the situation. [See picture 2.]
  217.  
  218. Scrolling horizontally is easy. You just have to move sprites like you would
  219. use the character horizontal scroll register and after eight pixels you
  220. reset the sprite positions and scroll the text one position in memory.
  221. And of course, you fetch a new character for the scroll. When we have
  222. different and changing sprite y-coordinates, opening the side borders become
  223. a great deal more difficult. However, in this case there is at least two
  224. different ways to do it.
  225.  
  226.  
  227. _Stretch the sprites_
  228.  
  229. The easiest way is to position all of the sprites where the scroll will
  230. be when it is in its highest position. Then stretch the first and last line
  231. of each sprite so that the 19 sprite lines in the middle will be on the
  232. desired place. Opening the borders now is trivial, because all of the sprites
  233. are present on all of the scan lines and they steal a constant amount of
  234. time. However, we lose two sprite lines. We might not want to use the first
  235. and the last line for graphics, because they are stretched.
  236. [See previous C=Hacking Issues for more information about stretching and
  237.  stolen cycles.]
  238.  
  239. A more difficult approach is to unroll the routine and let another routine
  240. count the sprites present in each line and then change the time the routine
  241. uses accordingly. In this way you save time during the display for other
  242. effects, like color bars, because stretching will take at least 12 cycles
  243. on each raster line. On the other hand, if the sinus is constant (user is
  244. not allowed to change it), it is usually possible to embedd the count
  245. routine directly to the border opening part of the routine.
  246.  
  247.  
  248. _More sprites_
  249.  
  250. You don't necassarily need to plot the characters in sprites to have more
  251. than eight characters. Using a sprite multiplexing techiques you can double
  252. or triple the number of sprites available. You can divide the scroll
  253. vertically into several areas and because the y-coordinate of the scroll
  254. is a sinus, there always is a fixed maximum number of sprites in each area.
  255. This number is always smaller than the total number of sprites in the
  256. whole scroll. I won't go into detail, but didn't want to leave this out
  257. completely. [See picture 3.]
  258.  
  259.  
  260. _Smoother and smoother_
  261.  
  262. Why be satisfied with a scroll with only 40 different slices horizontally ?
  263. It should be possible to count own coordinates for each pixel column on
  264. the scroll. In fact the program won't be much different, but the routine
  265. must also mask the unwanted bits and write the byte to memory with ORA+STA.
  266. When you think about it more, it is obvious that this takes a generous amount
  267. of time, handling every bit seperately will take much more than eight times
  268. the time a simple LDA+STA takes. Some coders have avoided this by plotting
  269. the same character to different character sets simultaneously and then
  270. changing the charsets appropriately, but the resulting scroll won't be much
  271. larger than 96x32 pixels.
  272.  
  273. --------------------------------------------------------------------------
  274. Picture 1 - Two character codes will make a graphical bitmap
  275.  
  276. Screen memory:
  277.  ____________________________________
  278. |Char   |Char   |Char   |Char   |  ...
  279. |Code   |Code   |Code   |Code   |
  280. |0      |2      |80     |80     | .
  281. |       |**  ** |       |       | .
  282. |       |**  ** |       |       | .
  283. |*****  |****** |       |       |
  284. |****** | ****  |       |       |
  285. |**__**_|__**___|_______|_______|
  286. |**  ** |  **   | ****  |Char   |
  287. |**  ** |  **   |****** |Code   |
  288. |****** |       |**  ** |6      |
  289. |*****  |       |**     |       |
  290. |Char   |Char   |**  ** |       |
  291. |Code   |Code   |****** |       |
  292. |1      |3      |4****  |*****  |
  293. |_______|_______|_______|******_|
  294. |Char   |Char   |       |**  ** |
  295. |Code   |Code   |       |****** |
  296. |80     |80     |       |*****  |
  297. |       |       |       |**     |
  298. |       |       |Char   |**ar   |
  299. |       |       |Code   |Code   |
  300. |       |       |5      |7      |
  301. |_______|_______|_______|_______|
  302.  
  303. Character set memory:
  304.  
  305.  _________________________________________________________________
  306. |Char 0 |Char 1 |Char 2 |Char 3 |Char 4 |Char 5 |Char 6 |Char 7 | ...
  307. |_______|_______|_______|_______|_______|_______|_______|_______|__
  308.       DDDDDDDD      YYYYYYYY     CCCCCCCC              PPPPPPPP
  309.  First column    Second column   Third column    Fourth column
  310.  
  311. --------------------------------------------------------------------------
  312. Picture 2 - DYCP with sprites
  313.  
  314. Sprite 0
  315.  _______________________
  316. |       |**  ** |       |
  317. |       |**  ** |       |
  318. |       |****** |       |
  319. |*****  | ****  |       |
  320. |****** |  **   |       |
  321. |**  ** |  **   |       |
  322. |**  ** |  **   |       |
  323. |**__**_|_______|_______|
  324. |****** |       | ****  |
  325. |*****  |       |****** |
  326. |       |       |**  ** |
  327. |       |       |**     |
  328. |       |       |**  ** |
  329. |       |       |****** |
  330. |       |       | ****  |
  331. |_______|_______|_______| Sprite 1
  332. |       |       |       | _______________________
  333. |       |       |       ||*****  |       |       |
  334. |       |       |       ||****** |       |       |
  335. |       |       |       ||**  ** |       |       |
  336. |_______|_______|_______||****** |       |       |
  337.                          |*****  |       |       |
  338.                          |**     |       |       |
  339.                          |**     |       |       |
  340.                          |_______|_______|_______|
  341.                          |       |       |       |
  342.                          |       |       |       |
  343.                          |       |       |       |
  344.                          |       | ****  |       |
  345.                          |       | ****  |       |
  346.                          |       |       |****** |
  347.                          |       |       |****** |
  348.                          |_______|_______|__**___|
  349.                          |       |       |  **   |
  350.                          |       |       |  **   |
  351.                          |       |       |  **   |
  352.                          |       |       |  **   |
  353.                          |_______|_______|_______|
  354.  
  355. --------------------------------------------------------------------------
  356. Picture 3 - Sprite multiplexing
  357.  
  358.                                __          Set coordinates for eight sprites
  359.                             __|3 |         that start from the top half.
  360.                            |4 |  |__
  361.                          __|  `--|2 |
  362.                         |5 `--'  |  |
  363.                         |  |     `--'__
  364.                         `--'        |1 |
  365.                                     |  |
  366.                       __            `--'
  367.                      |6 |
  368.                      |  |               __
  369.                      `--'              |0 |
  370.                                        |  |
  371. -__------------------------------------`--'When VIC has displayed the last
  372. |0 |               __                      sprite, set coordinates for the
  373. |  |              |6 |                     sprites in the lower half of the
  374. `--'              |  |                     area.
  375.                   `--'
  376.     __
  377.    |1 |         __
  378.    |  |        |5 |
  379.    `-- __      |  |
  380.       |2 |   __`--'
  381.       |  |__|4 |                           You usually have two sprites that
  382.       `--|3 |  |                           are only 'used' once so that you
  383.          |  `--'                           can change other sprites when VIC
  384.          `__'                              is displaying them.
  385. --------------------------------------------------------------------------
  386.  
  387. DYCP demo program (PAL)
  388.  
  389.  
  390. SINUS=  $CF00   ; Place for the sinus table
  391. CHRSET= $3800   ; Here begins the character set memory
  392. GFX=    $3C00   ; Here we plot the dycp data
  393. X16=    $CE00   ; values multiplicated by 16 (0,16,32..)
  394. D16=    $CE30   ; divided by 16  (16 x 0,16 x 1 ...)
  395. START=  $033C   ; Pointer to the start of the sinus
  396. COUNTER= $033D  ; Scroll counter (x-scroll register)
  397. POINTER= $033E  ; Pointer to the text char
  398. YPOS=   $0340   ; Lower 4 bits of the character y positions
  399. YPOSH=  $0368   ; y positions divided by 16
  400. CHAR=   $0390   ; Scroll text characters, multiplicated by eight
  401. ZP=     $FB     ; Zeropage area for indirect addressing
  402. ZP2=    $FD
  403. AMOUNT= 38      ; Amount of chars to plot-1
  404. PADCHAR= 32     ; Code used for clearing the screen
  405.  
  406. *= $C000
  407.  
  408.         SEI             ; Disable interrupts
  409.         LDA #$32        ; Character generator ROM to address space
  410.         STA $01
  411.         LDX #0
  412. LOOP0   LDA $D000,X     ; Copy the character set
  413.         STA CHRSET,X
  414.         LDA $D100,X
  415.         STA CHRSET+256,X
  416.         DEX
  417.         BNE LOOP0
  418.         LDA #$37        ; Normal memory configuration
  419.         STA $01
  420.         LDY #31
  421. LOOP1   LDA #66         ; Compose a full sinus from a 1/4th of a
  422.         CLC             ;   cycle
  423.         ADC SIN,X
  424.         STA SINUS,X
  425.         STA SINUS+32,Y
  426.         LDA #64
  427.         SEC
  428.         SBC SIN,X
  429.         STA SINUS+64,X
  430.         STA SINUS+96,Y
  431.         INX
  432.         DEY
  433.         BPL LOOP1
  434.         LDX #$7F
  435. LOOP2   LDA SINUS,X
  436.         LSR
  437.         CLC
  438.         ADC #32
  439.         STA SINUS+128,X
  440.         DEX
  441.         BPL LOOP2
  442.  
  443.         LDX #39
  444. LOOP3   TXA
  445.         ASL
  446.         ASL
  447.         ASL
  448.         ASL
  449.         STA X16,X       ; Multiplication table (for speed)
  450.         TXA
  451.         LSR
  452.         LSR
  453.         LSR
  454.         LSR
  455.         CLC
  456.         ADC #>GFX
  457.         STA D16,X       ; Dividing table
  458.         LDA #0
  459.         STA CHAR,X      ; Clear the scroll
  460.         DEX
  461.         BPL LOOP3
  462.         STA POINTER     ; Initialize the scroll pointer
  463.         LDX #7
  464.         STX COUNTER
  465. LOOP10  STA CHRSET,X    ; Clear the @-sign..
  466.         DEX
  467.         BPL LOOP10
  468.  
  469.         LDA #>CHRSET    ; The right page for addressing
  470.         STA ZP2+1
  471.         LDA #<IRQ       ; Our interrupt handler address
  472.         STA $0314
  473.         LDA #>IRQ
  474.         STA $0315
  475.         LDA #$7F        ; Disable timer interrupts
  476.         STA $DC0D
  477.         LDA #$81        ; Enable raster interrupts
  478.         STA $D01A
  479.         LDA #$A8        ; Raster compare to scan line $A8
  480.         STA $D012
  481.         LDA #$1B        ; 9th bit
  482.         STA $D011
  483.         LDA #30
  484.         STA $D018       ; Use the new charset
  485.         CLI             ; Enable interrupts and return
  486.         RTS
  487.  
  488. IRQ     INC START       ; Increase counter
  489.         LDY #AMOUNT
  490.         LDX START
  491. LOOP4   LDA SINUS,X     ; Count a pointer for each text char and according
  492.         AND #7          ;  to it fetch a y-position from the sinus table
  493.         STA YPOS,Y      ;   Then divide it to two bytes
  494.         LDA SINUS,X
  495.         LSR
  496.         LSR
  497.         LSR
  498.         STA YPOSH,Y
  499.         INX             ; Chars are two positions apart
  500.         INX
  501.         DEY
  502.         BPL LOOP4
  503.  
  504.         LDA #0
  505.         LDX #79
  506. LOOP11  STA GFX,X       ; Clear the dycp data
  507.         STA GFX+80,X
  508.         STA GFX+160,X
  509.         STA GFX+240,X
  510.         STA GFX+320,X
  511.         STA GFX+400,X
  512.         STA GFX+480,X
  513.         STA GFX+560,X
  514.         DEX
  515.         BPL LOOP11
  516.  
  517. MAKE    LDA COUNTER     ; Set x-scroll register
  518.         STA $D016
  519.         LDX #AMOUNT
  520.         CLC             ; Clear carry
  521. LOOP5   LDY YPOSH,X     ; Determine the position in video matrix
  522.         TXA
  523.         ADC LINESL,Y    ; Carry won't be set here
  524.         STA ZP          ; low byte
  525.         LDA #4
  526.         ADC LINESH,Y
  527.         STA ZP+1        ; high byte
  528.         LDA #PADCHAR    ; First clear above and below the char
  529.         LDY #0          ; 0. row
  530.         STA (ZP),Y
  531.         LDY #120        ; 3. row
  532.         STA (ZP),Y
  533.         TXA             ; Then put consecuent character codes to the places
  534.         ASL             ;  Carry will be cleared
  535.         ORA #$80        ; Inverted chars
  536.         LDY #40         ; 1. row
  537.         STA (ZP),Y
  538.         ADC #1          ; Increase the character code, Carry won't be set
  539.         LDY #80         ; 2. row
  540.         STA (ZP),Y
  541.  
  542.         LDA CHAR,X      ; What character to plot ? (source)
  543.         STA ZP2         ;  (char is already multiplicated by eight)
  544.         LDA X16,X       ; Destination low byte
  545.         ADC YPOS,X      ;  (16*char code + y-position's 3 lowest bits)
  546.         STA ZP
  547.         LDA D16,X       ; Destination high byte
  548.         STA ZP+1
  549.  
  550.         LDY #6          ; Transfer 7 bytes from source to destination
  551.         LDA (ZP2),Y : STA (ZP),Y
  552.         DEY             ; This is the fastest way I could think of.
  553.         LDA (ZP2),Y : STA (ZP),Y
  554.         DEY
  555.         LDA (ZP2),Y : STA (ZP),Y
  556.         DEY
  557.         LDA (ZP2),Y : STA (ZP),Y
  558.         DEY
  559.         LDA (ZP2),Y : STA (ZP),Y
  560.         DEY
  561.         LDA (ZP2),Y : STA (ZP),Y
  562.         DEY
  563.         LDA (ZP2),Y : STA (ZP),Y
  564.         DEX
  565.         BPL LOOP5       ; Get next char in scroll
  566.  
  567.         LDA #1
  568.         STA $D019       ; Acknowledge raster interrupt
  569.  
  570.         DEC COUNTER     ; Decrease the counter = move the scroll by 1 pixel
  571.         BPL OUT
  572. LOOP12  LDA CHAR+1,Y    ; Move the text one position to the left
  573.         STA CHAR,Y      ;  (Y-register is initially zero)
  574.         INY
  575.         CPY #AMOUNT
  576.         BNE LOOP12
  577.         LDA POINTER
  578.         AND #63         ; Text is 64 bytes long
  579.         TAX
  580.         LDA SCROLL,X    ; Load a new char and multiply it by eight
  581.         ASL
  582.         ASL
  583.         ASL
  584.         STA CHAR+AMOUNT ; Save it to the right side
  585.         DEC START       ; Compensation for the text scrolling
  586.         DEC START
  587.         INC POINTER     ; Increase the text pointer
  588.         LDA #7
  589.         STA COUNTER     ; Initialize X-scroll
  590.  
  591. OUT     JMP $EA7E       ; Return from interrupt
  592.  
  593. SIN     BYT 0,3,6,9,12,15,18,21,24,27,30,32,35,38,40,42,45
  594.         BYT 47,49,51,53,54,56,57,59,60,61,62,62,63,63,63
  595.                         ; 1/4 of the sinus
  596.  
  597. LINESL  BYT 0,40,80,120,160,200,240,24,64,104,144,184,224
  598.         BYT 8,48,88,128,168,208,248,32
  599.  
  600. LINESH  BYT 0,0,0,0,0,0,0,1,1,1,1,1,1,2,2,2,2,2,2,2,3
  601.  
  602. SCROLL  SCR "THIS@IS@AN@EXAMPLE@SCROLL@FOR@"
  603.         SCR "COMMODORE@MAGAZINE@BY@PASI@OJALA@@"
  604.                         ; SCR will convert text to screen codes
  605.  
  606. --------------------------------------------------------------------------
  607. Basic loader for the Dycp demo program (PAL)
  608.  
  609. 1 S=49152
  610. 2 DEFFNH(C)=C-48+7*(C>64)
  611. 3 CH=0:READA$,A:PRINTA$:IFA$="END"THENPRINT"<white><clr>":SYS49152:END
  612. 4 FORF=0TO31:Q=FNH(ASC(MID$(A$,F*2+1)))*16+FNH(ASC(MID$(A$,F*2+2)))
  613. 5 CH=CH+Q:POKES,Q:S=S+1:NEXT:IFCH=ATHEN3
  614. 6 PRINT"CHECKSUM ERROR":END
  615. 100 DATA 78A9328501A200BD00D09D0038BD00D19D0039CAD0F1A9378501A01FA942187D, 3441
  616. 101 DATA 75C19D00CF9920CFA94038FD75C19D40CF9960CFE88810E4A27FBD00CF4A1869, 4302
  617. 102 DATA 209D80CFCA10F3A2278A0A0A0A0A9D00CE8A4A4A4A4A18693C9D30CEA9009D90, 3231
  618. 103 DATA 03CA10E58D3E03A2078E3D039D0038CA10FAA93885FEA99B8D1403A9C08D1503, 3338
  619. 104 DATA A97F8D0DDCA9818D1AD0A9A88D12D0A91B8D11D0A91E8D18D05860EE3C03A026, 3864
  620. 105 DATA AE3C03BD00CF2907994003BD00CF4A4A4A996803E8E88810EAA900A24F9D003C, 3256
  621. 106 DATA 9D503C9DA03C9DF03C9D403D9D903D9DE03D9D303ECA10E5AD3D038D16D0A226, 3739
  622. 107 DATA 18BC68038A7995C185FBA90479AAC185FCA920A00091FBA07891FB8A0A0980A0, 4224
  623. 108 DATA 2891FB6901A05091FBBD900385FDBD00CE7D400385FBBD30CE85FCA006B1FD91, 4440
  624. 109 DATA FB88B1FD91FB88B1FD91FB88B1FD91FB88B1FD91FB88B1FD91FB88B1FD91FBCA, 6225
  625. 110 DATA 109FEE19D0CE3D031028B99103999003C8C026D0F5AD3E03293FAABDBFC10A0A, 3593
  626. 111 DATA 0A8DB603CE3C03CE3C03EE3E03A9078D3D034C7EEA000306090C0F1215181B1E, 2159
  627. 112 DATA 202326282A2D2F3133353638393B3C3D3E3E3F3F3F00285078A0C8F018406890, 2268
  628. 113 DATA B8E008305880A8D0F82000000000000000010101010101020202020202020314, 1379
  629. 114 DATA 08091300091300010E000518010D100C05001303120F0C0C00060F1200030F0D, 304
  630. 115 DATA 0D0F040F1205000D0107011A090E050002190010011309000F0A010C01000000, 257
  631. 200 DATA END,0
  632.  
  633. --------------------------------------------------------------------------
  634. Uuencoded C64 executable of the basic loader (PAL)
  635.  
  636. begin 644 dycp.64
  637. M`0@-"`$`4[(T.3$U,@`F"`(`EJ5(*$,ILD.K-#BJ-ZPH0[$V-"D`4@@#`$-(@
  638. MLC`ZAT$D+$$ZF4$D.HM!)+(B14Y$(J>9(@63(CJ>-#DQ-3(Z@`")"`0`@4:RE
  639. M,*0S,3I1LJ5(*,8HRBA!)"Q&K#*J,2DI*:PQ-JJE2"C&*,HH020L1JPRJC(IA
  640. M*2D`J@@%`$-(LD-(JE$ZEU,L43I3LE.J,3J".HM#2+)!IS,`P@@&`)DB0TA%.
  641. M0TM354T@15)23U(B.H``#PED`(,@-SA!.3,R.#4P,4$R,#!"1#`P1#`Y1#`P.
  642. M,SA"1#`P1#$Y1#`P,SE#040P1C%!.3,W.#4P,4$P,49!.30R,3@W1"P@,S0T#
  643. M,0!<"64`@R`W-4,Q.40P,$-&.3DR,$-&03DT,#,X1D0W-4,Q.40T,$-&.3DV&
  644. M,$-&13@X.#$P131!,C=&0D0P,$-&-$$Q.#8Y+"`T,S`R`*D)9@"#(#(P.40X3
  645. M,$-&0T$Q,$8S03(R-SA!,$$P03!!,$$Y1#`P0T4X031!-$$T031!,3@V.3-#P
  646. M.40S,$-%03DP,#E$.3`L(#,R,S$`]@EG`(,@,#-#03$P134X1#-%,#-!,C`WY
  647. M.$4S1#`S.40P,#,X0T$Q,$9!03DS.#@U1D5!.3E".$0Q-#`S03E#,#A$,34P@
  648. M,RP@,S,S.`!#"F@`@R!!.3=&.$0P1$1#03DX,3A$,4%$,$$Y03@X1#$R1#!!B
  649. M.3%".$0Q,40P03DQ13A$,3A$,#4X-C!%13-#,#-!,#(V+"`S.#8T`)`*:0"#]
  650. M($%%,T,P,T)$,#!#1C(Y,#<Y.30P,#-"1#`P0T8T031!-$$Y.38X,#-%.$4X$
  651. M.#@Q,$5!03DP,$$R-$8Y1#`P,T,L(#,R-38`W0IJ`(,@.40U,#-#.41!,#-#]
  652. M.41&,#-#.40T,#-$.40Y,#-$.41%,#-$.40S,#-%0T$Q,$4U040S1#`S.$0Q*
  653. M-D0P03(R-BP@,S<S.0`J"VL`@R`Q.$)#-C@P,SA!-SDY-4,Q.#5&0D$Y,#0W^
  654. M.4%!0S$X-49#03DR,$$P,#`Y,49"03`W.#DQ1D(X03!!,#DX,$$P+"`T,C(T:
  655. M`'<+;`"#(#(X.3%&0C8Y,#%!,#4P.3%&0D)$.3`P,S@U1D1"1#`P0T4W1#0P;
  656. M,#,X-49"0D0S,$-%.#5&0T$P,#9",49$.3$L(#0T-#``Q`MM`(,@1D(X.$(Q?
  657. M1D0Y,49".#A",49$.3%&0C@X0C%&1#DQ1D(X.$(Q1D0Y,49".#A",49$.3%&V
  658. M0C@X0C%&1#DQ1D)#02P@-C(R-0`1#&X`@R`Q,#E&144Q.40P0T4S1#`S,3`RK
  659. M.$(Y.3$P,SDY.3`P,T,X0S`R-D0P1C5!1#-%,#,R.3-&04%"1$)&0S$P03!!M
  660. M+"`S-3DS`%X,;P"#(#!!.$1"-C`S0T4S0S`S0T4S0S`S144S13`S03DP-SA$H
  661. M,T0P,S1#-T5%03`P,#,P-C`Y,$,P1C$R,34Q.#%",44L(#(Q-3D`JPQP`(,@0
  662. M,C`R,S(V,C@R03)$,D8S,3,S,S4S-C,X,SDS0C-#,T0S13-%,T8S1C-&,#`R[
  663. M.#4P-SA!,$,X1C`Q.#0P-C@Y,"P@,C(V.`#X#'$`@R!".$4P,#@S,#4X.#!!8
  664. M.$0P1C@R,#`P,#`P,#`P,#`P,#`P,#$P,3`Q,#$P,3`Q,#(P,C`R,#(P,C`R^
  665. M,#(P,S$T+"`Q,S<Y`$0-<@"#(#`X,#DQ,S`P,#DQ,S`P,#$P13`P,#4Q.#`Q7
  666. M,$0Q,#!#,#4P,#$S,#,Q,C!&,$,P0S`P,#8P1C$R,#`P,S!&,$0L(#,P-`"02
  667. M#7,`@R`P1#!&,#0P1C$R,#4P,#!$,#$P-S`Q,4$P.3!%,#4P,#`R,3DP,#$P.
  668. L,#$Q,S`Y,#`P1C!!,#$P0S`Q,#`P,#`P+"`R-3<`G`W(`(,@14Y$+#`````PK
  669. ``
  670. end
  671. size 1439
  672. --------------------------------------------------------------------------
  673. Uuencoded C64 executable of the basic loader (NTSC)
  674.  
  675. begin 644 dycp-ntsc.bas
  676. M`0@-"`$`4[(T.3$U,@`F"`(`EJ5(*$,ILD.K-#BJ-ZPH0[$V-"D`40@#`$-(?
  677. MLC`ZAT$D+$$ZF4$D.HM!)+(B14Y$(J>9(I,B.IXT.3$U,CJ``(@(!`"!1K(P/
  678. MI#,Q.E&RI4@HQBC**$$D+$:L,JHQ*2DIK#$VJJ5(*,8HRBA!)"Q&K#*J,BDI:
  679. M*0"I"`4`0TBR0TBJ43J74RQ1.E.R4ZHQ.H(ZBT-(LD&G,P#!"`8`F2)#2$5#F
  680. M2U-532!%4E)/4B(Z@`#'"%H`@``4"60`@R`W.$$Y,S(X-3`Q03(P,$)$,#!$L
  681. M,#E$,#`S.$)$,#!$,3E$,#`S.4-!1#!&,4$Y,S<X-3`Q03`Q1D$Y-#(Q.#=$I
  682. M+"`S-#0Q`&$)90"#(#<U0S$Y1#`P0T8Y.3(P0T9!.30P,SA&1#<U0S$Y1#0P!
  683. M0T8Y.38P0T9%.#@X,3!%-$$R-T9"1#`P0T8T03$X-CDL(#0S,#(`K@EF`(,@R
  684. M,C`Y1#@P0T9#03$P1C-!,C(W.$$P03!!,$$P03E$,#!#13A!-$$T031!-$$QJ
  685. M.#8Y,T,Y1#,P0T5!.3`P.40Y,"P@,S(S,0#["6<`@R`P,T-!,3!%-3A$,T4P.
  686. M,T$R,#<X13-$,#,Y1#`P,SA#03$P1D%!.3,X.#5&14$Y.4(X1#$T,#-!.4,P;
  687. M.$0Q-3`S+"`S,S,X`$@*:`"#($$Y-T8X1#!$1$-!.3@Q.$0Q040P03E",#A$:
  688. M,3)$,$$Y,4(X1#$Q1#!!.3%%.$0Q.$0P-3@V,$5%,T,P,T$P,4,L(#,X-C(`9
  689. ME0II`(,@044S0S`S0D0P,$-&,CDP-SDY-#`P,T)$,#!#1C1!-$$T03DY-C@PB
  690. M,T4X13@X.#$P14%!.3`P03(T1CE$,#`S0RP@,S(U-@#B"FH`@R`Y1#4P,T,Y$
  691. M1$$P,T,Y1$8P,T,Y1#0P,T0Y1#DP,T0Y1$4P,T0Y1#,P,T5#03$P135!1#-$E
  692. M,#,X1#$V1#!!,C%#+"`S-S(Y`"\+:P"#(#$X0D,V.#`S.$$W.3DU0S$X-49")
  693. M03DP-#<Y04%#,3@U1D-!.3(P03`P,#DQ1D)!,#<X.3%&0CA!,$$P.3@P03`L#
  694. M(#0R,C0`?`ML`(,@,C@Y,49"-CDP,4$P-3`Y,49"0D0Y,#`S.#5&1$)$,#!#H
  695. M13=$-#`P,S@U1D)"1#,P0T4X-49#03`P-D(Q1D0Y,2P@-#0T,`#)"VT`@R!&C
  696. M0C@X0C%&1#DQ1D(X.$(Q1D0Y,49".#A",49$.3%&0C@X0C%&1#DQ1D(X.$(QA
  697. M1D0Y,49".#A",49$.3%&0D-!+"`V,C(U`!8,;@"#(#$P.49%13$Y1#!#13-$T
  698. M,#,Q,#(X0CDY,3`S.3DY,#`S0SA#,#(V1#!&-4%$,T4P,S(Y,T9!04)$0D9#0
  699. M,3!!,$$L(#,U.3,`8PQO`(,@,$$X1$(V,#-#13-#,#-#13-#,#-%13-%,#-!D
  700. M.3`W.$0S1#`S-$,W145!,#`P,S`V,#DP0S!&,3(Q-3$X,4(Q12P@,C$U.0"P2
  701. M#'``@R`R,#(S,C8R.#)!,D0R1C,Q,S,S-3,V,S@S.3-",T,S1#-%,T4S1C-&/
  702. M,T8P,#(X-3`W.$$P0SA&,#$X-#`V.#DP+"`R,C8X`/T,<0"#($(X13`P.#,P2
  703. M-3@X,$$X1#!&.#(P,#`P,#`P,#`P,#`P,#`P,3`Q,#$P,3`Q,#$P,C`R,#(P>
  704. M,C`R,#(P,C`S,30L(#$S-SD`20UR`(,@,#@P.3$S,#`P.3$S,#`P,3!%,#`P3
  705. M-3$X,#$P1#$P,$,P-3`P,3,P,S$R,$8P0S!#,#`P-C!&,3(P,#`S,$8P1"P@J
  706. M,S`T`)4-<P"#(#!$,$8P-#!&,3(P-3`P,$0P,3`W,#$Q03`Y,$4P-3`P,#(Q`
  707. M.3`P,3`P,3$S,#DP,#!&,$$P,3!#,#$P,#`P,#`L(#(U-P"A#7@`@R!%3D0LZ
  708. $,````#`P0
  709. ``
  710. end
  711. size 1444
  712.  
  713. ================================================================================
  714. Opening the borders
  715. by Pasi 'Albert' Ojala (po87553@cs.tut.fi or albert@cc.tut.fi)
  716.         Written: 20-Jul-92
  717.  
  718.        All timings are in PAL, principles will apply to NTSC too.
  719.               Refer to VIC memory map in Hacking Issue 4.
  720.  
  721. VIC has many features and transparent borders are one of them. You can not
  722. make characters appear in the border, but sprites are displayed in the
  723. border too. "How to do this then?" is the big question.
  724.  
  725. The screen resolution in C64 has been and will be 320 x 200 pixels. Most
  726. games need to use the whole screen to be efficient or just plain playable.
  727. But there still is that useless border area, and you can put score and
  728. other status information there instead of having them interfere with the
  729. full-screen smooth-scrolling playing area.
  730.  
  731.  
  732. _How to disable the vertical borders_
  733.  
  734. When VIC (Video Interface Controller) has displayed all character rows,
  735. it will start displaying the vertical border area. It will start displaying
  736. the characters again in top of the screen. The row select register sets the
  737. number of character lines on the screen. If we select the 24-row display
  738. when VIC is drawing the last (25th) row, it does not start to draw the
  739. border at all !  VIC will think that it already started to draw the border.
  740.  
  741. The 25-row display must be selected again in the top of the screen, so that
  742. the border may be opened in the next frame too. The number of displayed rows
  743. can be selected with the bit 3 in $d011. If the bit is set, VIC will display
  744. 25 rows and 24 rows otherwise. We have to clear the bit somewhere during the
  745. last row (raster lines $f2-$fa) and set it again in top of the screen or at
  746. least somewhere before the last row (line $f2). This has to be done in every
  747. frame (50 times per second in PAL).
  748.  
  749.  
  750. _How to open the sideborders_
  751.  
  752. The same trick can be applied to sideborders. When VIC is about to start
  753. displaying the sideborder, just select 38-column mode and restore 40-column
  754. mode so that you can do the trick again in the next scan line. If you need to
  755. open the sideborders in the bottom or top border area, you have to open the
  756. vertical borders also, but there shouldn't be any difficulty in doing that.
  757.  
  758. There is two drawbacks in this. The timing must be precise, one clock cycle
  759. off and the sideborder will not open (the sprites will generally take care of
  760. the timing) and you have to do the opening on each and every line. With
  761. top/bottom borders once in a frame was enough.
  762.  
  763. Another problem is bad-lines. There is not enough time to open the borders
  764. during a bad line and still have all of the sprites enabled. One solution
  765. is to open the borders only on seven lines and leave the bad lines unopened.
  766. Another way is to use less than eight sprites. You can have six of them
  767. on a bad line and still be able to open the sideborders (PAL). The old and
  768. still good solution is to scroll the bad lines, so that VIC will not start
  769. to draw the screen at all until it is allowed to do so.
  770. [Read more about bad lines from previous C=Hacking Issues]
  771.  
  772.  
  773. _Scrolling the screen_
  774.  
  775. VIC begins to draw the screen from the first bad line. VIC will know what
  776. line is a bad line by comparing its scan line counter to the vertical
  777. scroll register : when they match, the next line is a bad line. If we change
  778. the vertical scroll register ($d011), the first bad line will move also.
  779. If we do this on every line, the line counter in VIC will never match with
  780. it and the drawing never starts (until it is allowed to do so).
  781.  
  782. When we don't have to worry about bad lines, we have enough time to open the
  783. borders and do some other effects too. It is not necassary to change the
  784. vertical scroll on every line to get rid of the bad lines, just make sure
  785. that it never matches the line counter (or actually the least significant
  786. 8 bits).
  787.  
  788. You can even scroll the bad lines independently and you have FLD - Flexible
  789. Line Distance. You just allow a bad line when it is time to display the next
  790. character row. With this you can bounce the lines or scroll a hires picture
  791. very fast down the screen. But this has not so much to do with borders, so
  792. I will leave it to another article. (Just send requests and I might start
  793. writing about FLD ..)
  794.  
  795.