home *** CD-ROM | disk | FTP | other *** search
/ Vectronix 2 / VECTRONIX2.iso / FILES_03 / JAG_DOX.ZIP / tutorial.txt < prev   
Text File  |  1996-01-27  |  13KB  |  406 lines

  1. # -------------------------------------------------------------------
  2. # BLITTER TUTORIAL                      (c) Copyright 1996 Nat! & KKP
  3. # -------------------------------------------------------------------
  4. # These are some of the results/guesses that Klaus and Nat! found
  5. # out about the Jaguar with a few helpful hints by other people, 
  6. # who'd prefer to remain anonymous. 
  7. #
  8. # Since we are not under NDA or anything from Atari we feel free to 
  9. # give this to you for educational purposes only.
  10. #
  11. # Please note, that this is not official documentation from Atari
  12. # or derived work thereof (both of us have never seen the Atari docs)
  13. # and Atari isn't connected with this in any way.
  14. #
  15. # Please use this informationphile as a starting point for your own
  16. # exploration and not as a reference. If you find anything innacurate,
  17. # missing, needing more explanation etc. by all means please write
  18. # to us:
  19. #      nat@zumdick.rhein-main.de
  20. # or
  21. #      kkp@gamma.dou.dk
  22. #
  23. # If you could do us a small favor, don't use this information for
  24. # those lame flamewars on r.g.v.a or the mailing list.
  25. #
  26. # HTML soon ?
  27. # -------------------------------------------------------------------
  28. # $Id: tutorial.txt,v 1.4 1996/01/27 15:22:58 nat Exp $
  29. # -------------------------------------------------------------------
  30.  
  31. Blitter tutorial:
  32. =-=-=-=-=-=-=-=-=
  33.  
  34. Here are a few examples, that should work. They haven't been tested (yet).
  35. (note: not the best code, but hopefully understandable)
  36.  
  37. a) Clearing 256 bytes starting from $2000
  38.    --------------------------------------
  39.  
  40. .wait:
  41.    move.l   B_CMD,d0             ;; wait for blitter to finish
  42.    ror.w    #1,d0                ;; Check if blitter is idle
  43.    bcc.b    .wait                ;; bit was clear -> busy
  44.  
  45.    move.l   #$2000,A1_BASE       ;; point to destination
  46.    move.l   #$0,A1_PIXEL         ;; start in front
  47.    move.l   #PIXEL16|XADDPHR|PITCH1,A1_FLAGS ;; use 16bit pixels/phrasemode
  48.    move.l   #0,B_PATD            ;; our value to draw
  49.  
  50.    move.w   #1,d0                ;; we wanna draw 1 'line'
  51.    swap     d0                   ;; in upper word
  52.    move.w   #256/2/4,d0          ;; and 256 bytes == 128 16-bit-pixels
  53.    move.l   d0,B_COUNT           ;; == 32 phrases
  54.  
  55.    move.l   #PATDSEL,B_CMD       ;; use B_PATD to draw and GO
  56.  
  57.  
  58.  
  59. b)  Setting 256 bytes starting at $2001 to 0xFF:
  60.     -------------------------------------------
  61.  
  62.    move.l   #$2000,A1_BASE       ;; point to destination
  63.    move.l   #$1,A1_PIXEL         ;; start at offset 1
  64.    move.l   #PIXEL8|XADDPIX|PITCH1,A1_FLAGS ;; use 8bit pixels pixelmode
  65.    move.l   #$FF,B_PATD          ;; our value to draw
  66.  
  67.    move.w   #1,d0                ;; we wanna draw 1 'line'
  68.    swap     d0                   ;; in upper word
  69.    move.w   #256,d0              ;; and 256 bytes == 256 8-bit-pixels
  70.    move.l   d0,B_COUNT           
  71.  
  72.    move.l   #PATDSEL,B_CMD       ;; use B_PATD to draw and GO
  73.  
  74.  
  75. c)  Copying 256 bytes from $2000 to $3000
  76.     ------------------------------------
  77.    
  78.    move.l   #$3000,A1_BASE       ;; point to destination
  79.    move.l   #$0,A1_PIXEL         ;; start in front
  80.    move.l   #PIXEL16|XADDPHR|PITCH1,A1_FLAGS ;; use 16bit pixels/phrasemode
  81.  
  82.    move.l   #$2000,A2_BASE       ;; point to source
  83.    move.l   #$0,A2_PIXEL         ;; start in front
  84.    move.l   #PIXEL16|XADDPHR|PITCH1,A2_FLAGS ;; use 16bit pixels/phrasemode
  85.  
  86.    move.w   #1,d0                ;; we wanna draw 1 'line'
  87.    swap     d0                   ;; in upper word
  88.    move.w   #256/2/4,d0          ;; and 256 bytes == 128 pixels
  89.    move.l   d0,B_COUNT           ;; == 32 phrases
  90.  
  91.    move.l   #LFU_REPLACE|SRCEN,B_CMD ;; straight copy 
  92.  
  93.  
  94. d)  XORing 256 bytes from $2000 with $3000
  95.     ------------------------------------
  96.  
  97.    as c) but    
  98.  
  99.    move.l   #LFU_XOR|DSTEN|SRCEN,B_CMD 
  100.  
  101.       instead of
  102.  
  103.    move.l   #LFU_REPLACE|SRCEN,B_CMD
  104.  
  105.  
  106.  
  107. e)  Gouraudshading a horizontal 64 pixel line 
  108.     on a 320x200 bitmap at $20000 starting at relative point 100,120
  109.     --------------------------------------------------------------
  110.    
  111.    move.l   #$20000,A1_BASE      ;; point to destination
  112.    move.w   #120,d0              ;; Y pos
  113.    swap     d0                   ;; in upper word
  114.    move.w   #100,d0              ;; X pos in lower
  115.    move.l   d0,A1_PIXEL          ;; start in the middle
  116.    move.l   #PIXEL16|XADDPIX|WID320|PITCH1,A1_FLAGS ;; note the WID320!!
  117.  
  118.    move.w   #$8000,B_PATD        ;; starting color
  119.    move.l   #$00038000,B_IINC    ;; intensity increment (3.5)
  120.  
  121.    move.w   #1,d0                ;; we wanna draw 1 'line'
  122.    swap     d0                   ;; in upper word
  123.    move.w   #64,d0               ;; and 64 pixels
  124.    move.l   d0,B_COUNT           
  125.  
  126.    move.l   #PATDSEL|GOURD,B_CMD 
  127.  
  128.  
  129. f)  Blitting a 64x64 piece from a 128x128 pixmap  (Pos: 10, 20)
  130.     unto a 320x200 pixmap with source shading (Pos: 100,120). 
  131.     The source is at $30000 the destination at $20000. 
  132.     --------------------------------------------------------------
  133.    
  134.    move.l   #$20000,A1_BASE      ;; point to destination
  135.    move.l   #PIXEL16|XADDPIX|WID320|PITCH1,A1_FLAGS ;; note the WID320!!
  136.  
  137.    move.w   #120,d0              ;; Y pos
  138.    swap     d0                   ;; in upper word
  139.    move.w   #100,d0              ;; X pos in lower
  140.    move.l   d0,A1_PIXEL          ;; start in the middle
  141.  
  142.    move.w   #1,d0
  143.    swap     d0
  144.    move.w   #-64,d0
  145.    move.l   d0,A1_STEP   
  146.  
  147.  
  148.    move.l   #$30000,A2_BASE
  149.    move.l   #PIXEL16|XADDPIX|WID128|PITCH1,A2_FLAGS
  150.  
  151.    move.w   #12,d0               ;; Y pos
  152.    swap     d0                   ;; in upper word
  153.    move.w   #10,d0               ;; X pos in lower
  154.    move.l   d0,A2_PIXEL
  155.  
  156.    move.w   #1,d0
  157.    swap     d0
  158.    move.w   #-64,d0
  159.    move.l   d0,A2_STEP
  160.  
  161.    move.w   #64,d0               ;; we wanna draw 64 lines
  162.    swap     d0                   ;; in upper word
  163.    move.w   #64,d0               ;; and 64 pixels each
  164.    move.l   d0,B_COUNT           
  165.    
  166.    move.l   #$00040000,B_IINC    ;; shade value for source
  167.  
  168.    move.l   #SRCEN|DSTEN|UPDA1|UPDA2|SRCSHADE,B_CMD 
  169.  
  170.  
  171. g)  Blitting a 64x64 piece from a 128x128 pixmap  (Pos: 10, 20)
  172.     unto a 320x200 pixmap with source shading (Pos: 100,120). 
  173.     The pixmap will appear rotated about 45 degrees 
  174.     The source is at $30000 the destination at $20000.   (TESTED)
  175.     --------------------------------------------------------------
  176.    
  177.    move.l   #$20000,A1_BASE      ;; point to destination
  178.    move.l   #PIXEL16|XADDINC|WID320|PITCH1,A1_FLAGS ;; note the WID320!!
  179.  
  180.    move.w   #120,d0              ;; Y pos
  181.    swap     d0                   ;; in upper word
  182.    move.w   #100,d0              ;; X pos in lower
  183.    move.l   d0,A1_PIXEL          ;; start in the middle
  184.  
  185.    move.l   #0,A1_INC            ;; scaling in the X direction
  186.    move.w   #$8000,d0            ;; and stepping diagonally
  187.    swap     d0
  188.    move.w   #$8000,d0
  189.    move.l   d0,A1_FINC
  190.  
  191.    move.w   #-33,d0     
  192.    swap     d0
  193.    move.w   #-32,d0
  194.    move.l   d0,A1_STEP
  195.  
  196.    move.w   #$8000,d0   
  197.    swap     d0
  198.    move.w   #$8000,d0
  199.    move.l   d0,A1_FSTEP
  200.  
  201.  
  202.    move.l   #$30000,A2_BASE
  203.    move.l   #PIXEL16|XADDPIX|WID128|PITCH1,A2_FLAGS
  204.  
  205.    move.w   #12,d0               ;; Y pos
  206.    swap     d0                   ;; in upper word
  207.    move.w   #10,d0               ;; X pos in lower
  208.    move.l   d0,A2_PIXEL
  209.  
  210.    move.w   #1,d0
  211.    swap     d0
  212.    move.w   #-64,d0
  213.    move.l   d0,A2_STEP
  214.  
  215.    move.w   #64,d0               ;; we wanna draw 64 lines
  216.    swap     d0                   ;; in upper word
  217.    move.w   #64,d0               ;; and 64 pixels each
  218.    move.l   d0,B_COUNT           
  219.    
  220.    move.l   #$00040000,B_IINC    ;; shade value for source
  221.  
  222.    move.l   #LFU_REPLACE|DSTEN|SRCEN|UPDA1|UPDA1F|UPDA2|SRCSHADE,B_CMD 
  223.  
  224.  
  225. Rotating with the blitter:
  226. =-=-=-=-=-=-=-=-=-=-=-=-=
  227.  
  228. Scaling and rotation are really nice effects you can do with the 
  229. blitter. But you got to be careful that you don't leave holes 
  230. accidentally on the screen. 
  231.  
  232. There are two ways to produce holes, one because of using a step
  233. size (in either direction) that is larger than 1. This should be
  234. obvious I guess.
  235.  
  236. The other not so obvious source of holes are quantization errors.
  237.  
  238. For example to rotate a bitmap around 30 degrees, you might do these
  239. calculations:
  240.  
  241.           a   
  242.     A +--------+ B    our source pixmap of size 64x64
  243.       |        |
  244.       |        | a            a == 64
  245.       |        |
  246.    D  +--------+ C
  247.                
  248.              A   x      
  249.       ........+.........      That's how it should look like
  250.              / \  .           rotated                                 
  251.             /   \ . y   
  252.            /     \.
  253.         D +       + B
  254.            \     /
  255.           a \   / a     
  256.              \ /
  257.               + C
  258.  
  259.      A     x
  260.       +...........         a magnified look at the upper corner
  261.        \m)    90 .         we notice that:
  262.         \        .
  263.          \       .
  264.           \      .         x = cos( m) * a
  265.            \     .  y      y = sin( m) * a
  266.           a \    .
  267.              \   .
  268.               \  .         m = 30 deg
  269.                \ .         x = 55.43 = $0037.6CF5
  270.                 \.         y = 32.00 = $0020.0000
  271.                  +         
  272.                   B
  273. hor increment = x / a = cos( m) = 0.87 = $0.DDB4  ($1.0000 * 0.87)
  274. ver increment = y / a = sin( m) = 0.50 = $0.8000
  275.  
  276.            Y     X
  277. --------+-----+-----+      
  278. A1_INC     0     0
  279. A1_FINC  $8000 $DDB4
  280.  
  281. We wanna draw in runs from A to B. Now after a line has been drawn. We
  282. need to step back to the point we came from (A) (-55.43,-32) and then
  283. move in a 60 degree (180 - 90 - 30) angle backwards (-) 
  284. and downwards (+), down the left slope (A -> D).
  285.  
  286. To get it perfect we calculate everything in integer fractional 
  287. representation (like the Blitter does):   
  288.                                  Y         X
  289.         64 * A1_INC.A1_FINC = $20.0000  $37.6D00
  290.  
  291. hor step      = -x - cos( 60) = -$37.6D00 - $8000 = $FFC81300
  292. ver step      = -y + sin( 60) = -$20.0000 + $DDB4 = $FFE0DDB4
  293.  
  294.            Y     X
  295. --------+-----+-----+      
  296. A1_STEP  $FFE0 $FFC8
  297. A1_FSTEP $DDB4 $1300
  298.  
  299.  
  300. Now if you blit something on the screen you'll see holes (not
  301. drawn pixels) in your pixmap, although the step size in both
  302. directions is 1 (sin(x)^2 + cos(x)^2 = 1). The error is introduced
  303. while the blitter is stepping in the 'integer.fractional' domain
  304. and then plots a pixel in the 'integer' domain. What I mean with
  305. 'integer.fractional' domain are the contents of the A1_PIXEL, A1_FPIXEL
  306. and the A1_FPIXEL and the A1_INC, A1_FINC registers. 
  307.  
  308. The problem will be visible on adjacent lines only, because the
  309. quantization of the pixels, which starts at a different fractional 
  310. offset, will be slightly but decisively different for the subsequent 
  311. runs. 
  312. Try the following program. Run it once with BLOCK set to 1 and look 
  313. at the resulting moiree pattern. Now set BLOCK to 0 and examine the 
  314. colored lines closely (drawn in sequence from top to bottom) and notice 
  315. how each line differs from the next.
  316.  
  317.  
  318. BLOCK   equ     1
  319.  
  320.    .if BLOCK
  321. HEIGHT  equ     64
  322. WIDTH   equ     64
  323.    .else
  324. HEIGHT  equ     16
  325. WIDTH   equ     16
  326.    .endif
  327.  
  328. HINC      equ         $DDB4
  329. VINC      equ         $8000
  330.  
  331. HSTEP      equ         -(HEIGHT*HINC)-VINC
  332. VSTEP      equ        -(WIDTH*VINC)+HINC
  333.  
  334. blit:
  335. .wait:    
  336.     move.l    B_CMD,d0
  337.     lsr.w        #1,d0
  338.     bcc.b        .wait
  339.     
  340.    move.l   #$20000,A1_BASE      ;; point to destination
  341.    move.l   #PIXEL16|XADDINC|WID256|PITCH1,A1_FLAGS ;; note the WID320
  342.  
  343.    move.w   #64,d0               ;; Y pos
  344.    swap     d0                   ;; in upper word
  345.    move.w   #128,d0              ;; X pos in lower
  346.    move.l   d0,A1_PIXEL          ;; start in the middle
  347.  
  348.    move.l   #$0,A1_FPIXEL        
  349.    move.l   #$0,A1_INC           
  350.  
  351.    move.w   #VINC,d0             
  352.    swap     d0
  353.    move.w   #HINC,d0             
  354.    move.l   d0,A1_FINC
  355.  
  356.  .if BLOCK
  357.    move.w   #VSTEP>>16,d0        
  358.  .else
  359.    move.w   #(VSTEP>>16)+2,d0   ;; uncomment this, comment out next
  360.  .endif
  361.    swap     d0
  362.    move.w   #HSTEP>>16,d0            
  363.    move.l   d0,A1_STEP
  364.  
  365.    move.w   #VSTEP&$FFFF,d0
  366.    swap     d0
  367.    move.w   #HSTEP&$FFFF,d0
  368.    move.l   d0,A1_FSTEP
  369.  
  370.    move.w   #HEIGHT,d0              ;; we wanna draw # lines
  371.    swap     d0                          ;; in upper word
  372.    move.w   #WIDTH,d0               ;; and # pixels each
  373.    move.l   d0,B_COUNT           
  374.  
  375.  .if BLOCK
  376.    move.l   #PATDSEL|UPDA1|UPDA1F|LFU_REPLACE,B_CMD 
  377.  .else
  378.    move.l   #$01000000,B_IINC       
  379.    move.l   #$00C0,B_PATD           
  380.    move.l   #GOURD|TOPBEN|PATDSEL|UPDA1|UPDA1F|LFU_REPLACE,B_CMD 
  381.  .endif
  382.  
  383.    rts
  384.  
  385. How do you get rid of the holes ? 
  386.  
  387. If you want to use the blitter for rotation, you probably should scale
  388. down the bitmaps you want to rotate. Maybe using a 96x96 source 
  389. pixmap for a 'apparent' 64x64 target pixmap size will be sufficient.
  390. You gotta experiment. It depends on the rotation angle!
  391.  
  392. ( Well there's a software method I did once, which can do rotation without 
  393.   holes. It goes basically like this:
  394.  
  395.    Use the steepest slope for "STEP" use the other slope for your
  396.    line drawings (like Bresenham f.e.)
  397.    Use the most outside pixel as your starting pixel
  398.    Draw a line with the required slope.
  399.    Do an integer step horizontally (or vertically but not both) away
  400.    from your first starting pixel.
  401.    Skip as many pixels as needed until you want to start drawing.
  402.    Draw the line.
  403.  
  404.    I can't quite see this being done with the blitter though :).
  405. )
  406.