home *** CD-ROM | disk | FTP | other *** search
/ The CDPD Public Domain Collection for CDTV 3 / CDPDIII.bin / pd / programming / assembler / thesource / volume2 / textfiles / howtocode3.txt < prev   
Encoding:
Text File  |  1993-01-05  |  34.5 KB  |  1,076 lines

  1.            How to write demos that work (Version 3) - 31/12/92
  2.            ===================================================
  3.  
  4.               (or How to bash the metal and get away with it)        
  5.  
  6.                   by Comrade J, Share and Enjoy (retired)
  7.  
  8. Thanks to everyone on the internet for sending their suggestions,
  9. bug reports and comments to me on this article. I'll try and keep
  10. this up to date and posted here frequently. Coming soon, source
  11. code for a small intro using all these techniques that you can
  12. use as the base for whatever you want to do....
  13.  
  14. --------------------------------------------------------------------
  15.  
  16. Most demos I've seen use similar startup code to that I was using back
  17. in 1988. Hey guys, wake up! The Amiga has changed quite a bit since
  18. then.
  19.  
  20. So. Here are some tips on what to do and what not to do:
  21.  
  22.  
  23. 1. RTFM.
  24. ========
  25.  
  26. Read the F**king manuals. All of them. Borrow them off friends or from
  27. your local public library if you have to.
  28.  
  29. Read the "General Amiga Development Guidelines" in the new (grey)
  30. Hardware Reference Manual and follow them TO THE LETTER.
  31. If it says "Leave this bit cleared" then don't set it!
  32.  
  33. Don't use self-modifying code. A common bit of code I see is:
  34.  
  35. ... in the setup code
  36.  
  37.     move.l  $6c.w,old
  38.  
  39. ... at the end of the interrupt
  40.  
  41.         movem.l    (sp)+,a0-a6/d0-d7
  42.     dc.w    $4ef9               ; jmp instruction
  43. old    dc.l    0                   ; self modifying!!!!
  44.  
  45. DONT DO THIS!
  46.  
  47. This is much better (although it still hits $6c which is not a
  48. good thing - It's much better to use AddIntServer() to call your
  49. interrupts, 
  50.  
  51. ... in the setup code
  52.  
  53.     move.l    VBRBase(a0)
  54.     move.l  $6c(a0),old        ; see under VBR below....
  55.  
  56. ... at the end of the interrupt
  57.  
  58.         movem.l    (sp)+,a0-a6/d0-d7
  59.     move.l    old,-(sp)        ; push old address to stack
  60.         rts
  61.  
  62. ... in your data section
  63.  
  64. old    dc.l    0
  65.  
  66.  
  67. 68020 and above processors with cache enabled often barf at the first
  68. piece of code (the cache still contains the JMP 0 instruction
  69. which isn't then altered), but the second piece works fine on the '040.
  70.  
  71.  
  72.  
  73.  
  74.  
  75. 2. Proper Copper startup.
  76. =========================
  77.  
  78. IF you are going to use the copper then this is how you should set it
  79. up. The current workbench view and copper address are stored, the
  80. system frozen, and then the copper enabled. On exit the workbench
  81. view is restored.
  82.  
  83. This guarantees your demo will run on an AGA (Amiga 1200) machine,
  84. even if set into some weird screenmode before running your code.
  85.  
  86. Otherwise under AGA, the hardware registers can be in some strange states
  87. before your code runs, beware!
  88.  
  89. The LoadView(NULL) forces the display to a standard, empty position,
  90. flushing the crap out of the hardware registers: Note. There is
  91. a bug in the V39 OS on Amiga 1200/4000 and the sprite resolution is
  92. *not* reset, you will have to do this manually if you use sprites...
  93.  
  94. Two WaitTOF() calls are needed after the LoadView to wait for both the
  95. long and short frame copperlists of interlaced displays to finish.
  96.  
  97.  
  98. I'm writing this code off the top of my head, if you spot any obvious bugs
  99. email me at the address below, or leave mail to me on Bad Dreams BBS.
  100.  
  101.                 include "exec/macros.i"
  102.                 include "exec/funcdef.i"       ; keep code simple and
  103.                 include "exec/exec_lib.i"      ; easy to read - use
  104.                 include "graphics/gfxbase.i"   ; the includes!
  105.                 include "graphics/gfx_lib.i"
  106.                 include "misc/easystart.i"     ; Allows startup from
  107.                                                ; icon
  108.  
  109.                 section mycode,code            ; need not be in chipram
  110.  
  111. StartCopper:
  112.                 move.l  4.w,a6          ; get ExecBase
  113.         lea    gfxname,a1    ; graphics name
  114.                 moveq    #0,d0        ; any version
  115.         jsr    _LVOOpenLibrary(a6)
  116.         tst.l    d0
  117.         beq     End         ; failed to open? Then quit
  118.         move.l  d0,gfxbase
  119.         move.l    d0,a6
  120.         move.l  gb_ActiView(a6),wbview
  121.                     ; store current view address
  122.                                         ; gb_ActiView = 32
  123.  
  124.                 move.w    #0,a1        ; clears full long-word
  125.         jsr     _LVOLoadView(a6) ; Flush View to nothing
  126.  
  127.                 jsr    _LVOWaitTOF(a6) ; Wait once
  128.         jsr    _LVOWaitTOF(a6) ; Wait again.
  129.  
  130.                             ; Now you can hit the copper!
  131.  
  132.         move.l    4.w,a6
  133.                 jsr    _LVOForbid(a6)  ; Suspend multitasking!
  134.  
  135.         move.l    mycopper,$dff080 ; bang it straight in.
  136.                                          ; (DO NOT F**K WITH GFXBASE!)
  137.  
  138.                 *** DO YOUR FUNKY STUFF HERE ***
  139.  
  140.  
  141. CloseDown:    move.l    4.w,a6
  142.             jsr    _LVOPermit(a6)     ; Enable multitasking
  143.  
  144.         move.l    wbview,a1
  145.         move.l    gfxbase,a6
  146.         jsr    _LVOLoadView(a6) ; Fix view
  147.  
  148.         move.l    gb_copinit(a6),$dff080     ; Kick it into life
  149.                                                ; copinit = 36
  150.         move.l    a6,a1
  151.             move.l    4.w,a6
  152.         jsr    _LVOCloseLibrary(a6) ; EVERYONE FORGETS THIS!!!!
  153.  
  154. End:        rts
  155.  
  156.         section mydata,data_C    ; keep data & code seperate!
  157.  
  158. copperlist      dc.w    $180,0          ; background black
  159.                 dc.w    $5c07,$fffe     ; wait for $5c07,$fffe
  160.                 dc.w    $180,$ff0       ; background yellow
  161.                 dc.w    $ffff,$fffe
  162.                 dc.w    $ffff,$fffe     ; Copper end (always do two
  163.                                         ; copper end cmds!)
  164.  
  165. wbview      dc.l    0
  166. wbcop       dc.l    0
  167. gfxbase     dc.l    0
  168. gfxname     dc.b    "graphics.library",0
  169.  
  170.  
  171. It has been suggested to me that instead of using the GfxBase gb_ActiView
  172. I should instead use the Intuition ib_ViewLord view. This will work
  173. just as well, but there has been debate as to whether in the future
  174. with retargetable graphics (RTG) this will work in the same way. As the
  175. GfxBase is at a lower level than Intuition, I prefer to access it this
  176. way (but thank's for the suggestion Boerge anyway!).  
  177.  
  178.  
  179. 3. Your code won't run from an icon.
  180. ====================================
  181.  
  182. You stick an icon for your new demo (not everyone uses the CLI!) and
  183. it either crashes or doesn't give back all the RAM it uses. Why?
  184.  
  185. Icon startup needs specific code to reply to the workbench message.
  186. With the excellent Hisoft Devpac assember, all you need to do is add
  187. the line
  188.  
  189.     include "misc/easystart.i"
  190.  
  191. and it magically works!
  192.  
  193. For those without Devpac, here is the relevent code:
  194.  
  195. ---------------------------------------------------------
  196.  
  197. * some startup code to make a Workbench execute look like the CLI
  198. * based loosely on RKM Vol 1 page 4-36
  199.  
  200. * Include this at the front of your program
  201. * after any other includes
  202. * note that this needs exec/exec_lib.i
  203.  
  204.     IFND    EXEC_EXEC_I
  205.     include    "exec/exec.i"
  206.     ENDC
  207.     IFND    LIBRARIES_DOSEXTENS_I
  208.     include    "libraries/dosextens.i
  209.     ENDC
  210.  
  211.  
  212.     movem.l    d0/a0,-(sp)        save initial values
  213.     clr.l    returnMsg
  214.  
  215.     sub.l    a1,a1
  216.     move.l    4.w,a6
  217.     jsr    _LVOFindTask(a6)        find us
  218.     move.l    d0,a4
  219.  
  220.     tst.l    pr_CLI(a4)
  221.     beq.s    fromWorkbench
  222.  
  223. * we were called from the CLI
  224.     movem.l    (sp)+,d0/a0        restore regs
  225.     bra    end_startup        and run the user prog
  226.  
  227. * we were called from the Workbench
  228. fromWorkbench
  229.     lea    pr_MsgPort(a4),a0
  230.     move.l    4.w,a6
  231.     jsr    _LVOWaitPort(A6)        wait for a message
  232.     lea    pr_MsgPort(a4),a0
  233.     jsr    _LVOGetMsg(A6)            then get it
  234.     move.l    d0,returnMsg        save it for later reply
  235.  
  236. * do some other stuff here RSN like the command line etc
  237.     nop
  238.  
  239.     movem.l    (sp)+,d0/a0        restore
  240. end_startup
  241.     bsr.s    _main            call our program
  242.  
  243. * returns to here with exit code in d0
  244.     move.l    d0,-(sp)        save it
  245.  
  246.     tst.l    returnMsg
  247.     beq.s    exitToDOS        if I was a CLI
  248.  
  249.     move.l    4.w,a6
  250.         jsr    _LVOForbid(a6)
  251.     move.l    returnMsg(pc),a1
  252.     jsr    _LVOPermit(a6)
  253.  
  254. exitToDOS
  255.     move.l    (sp)+,d0        exit code
  256.     rts
  257.  
  258. * startup code variable
  259. returnMsg    dc.l    0
  260.  
  261. * the program starts here
  262.     even
  263. _main
  264.  
  265. ---------------------------------------------------------
  266.  
  267.  
  268.  
  269.  
  270. 4. How do I tell if I'm running on an Amiga 1200/4000?
  271. ======================================================
  272.  
  273. Do *NOT* check library revision numbers, V39 OS can and does
  274. run on standard & ECS chipset machines (This Amiga 3000
  275. is currently running V39).
  276.  
  277. This code will check for AGA
  278.  
  279.         move.w    $dff07c,d0
  280.     cmp.b    #$f8,d0
  281.     bne.s    .notaga
  282.  
  283.     ; Do your funky AGA Stuff in here!
  284.  
  285. .notaga
  286.  
  287.  
  288.  
  289.  
  290.  
  291. 5. Use Relocatable Code
  292. =======================
  293.  
  294. If you write demos that run from a fixed address you should be shot.
  295. NEVER EVER DO THIS. It's stupid and completely unnecessary.
  296.  
  297. If you require bitplanes to be on a 64Kb boundary then try the
  298. following (in pseudo-code because I'm too lazy to write it in asm
  299. for you):
  300.  
  301.         for c=0 to (top of chip ram) step 65536
  302.  
  303.         if AllocAbs(c,NUMBER_OF_BYTES_YOU_WANT) == TRUE then goto ok:
  304.  
  305.     next c:
  306.  
  307.         print "sorry. No free ram. Close down something and retry demo!"
  308.         stop
  309.  
  310. ok:    Run_Outrageous_demo with mem at c
  311.  
  312. Keep your code in multiple sections. Several small sections are
  313. better than one large section, they will more easilly fit in and run
  314. on a system with fragmented memory.
  315.  
  316.  
  317.  
  318.  
  319. 6. Don't Crunch demos!
  320. ======================
  321.  
  322. Don't ever use Tetrapack or Bytekiller based packers. They are crap.
  323. Many more demos fall over due to being packed with crap packers than
  324. anything else. If you are spreading your demo by electronic means
  325. (which most people do now, the days of the SAE Demodisks are long
  326. gone!) then assemble your code, and use LHARC to archive it, you
  327. will get better compression with LHARC than with most runtime
  328. packers.
  329.  
  330. If you *have* to pack your demos, then use Powerpacker 4+, Turbo
  331. Imploder or Titanics Cruncher, which I've had no problems with myself.
  332.  
  333.  
  334.  
  335.  
  336. 7. Don't use the K-Seka assembler!
  337. ==================================
  338.  
  339. It's dead and buried. Get a life, get a real assembler. Hisoft Devpac
  340. is probably the best all-round assembler, although I use ArgAsm
  341. which is astonishingly fast.
  342.  
  343.  
  344.  
  345. 8. Don't use the hardware unless you have to!
  346. =============================================
  347.  
  348. This one is aimed particularly at utility authors. I've seen some
  349. *awfully* written utilities, for example (although I don't want
  350. to single them out as there are plenty of others) the Kefrens
  351. IFF converter.
  352.  
  353. There is NO REASON why this has to have it's own copperlist. A standard
  354. OS-friendly version opening it's own screen works perfectly (I
  355. still use the original SCA IFF-Converter), and multitasks properly.
  356.  
  357.  
  358. 9. Beware bogus input falling through to Workbench
  359. ==================================================
  360.  
  361. If you keep multitasking enabled and run your own copperlist remember
  362. that any input (mouse clicks, key presses, etc) fall through to the
  363. workbench. The correct way to get around this is to add an input
  364. server to the IDCMP food chain (see - you *do* have to read the
  365. other manuals!) at a high priority to grab all input events before
  366. workbench/cli can get to them.
  367.  
  368. Look at the sourcecode for Protracker for an excellent example of
  369. how to do the job properly. Well done Lars!
  370.  
  371.  
  372.  
  373. 10. Have fun!
  374. =============
  375.  
  376. Too many people out there (particularly the American OS-Lamic
  377. Fundamentalists) try to tell us that you should never program at a hardware
  378. level. If you're programming for fun, ignore them! But try and put
  379. a little thought into how your code will work on other machines,
  380. nothing annoys people more than downloading 400Kb of demo and then
  381. finding it blows up on their machines. I'm not naming any names, but
  382. there are quite a few groups who I have no intention of downloading
  383. their demos again because I know it's a waste of download. With
  384. the launch of the Amiga 1200 you cannot just write for 1.3 Amiga
  385. 500's any more. Let's go out there and write some shit hot demos!
  386.  
  387.  
  388. 11. Don't Publish Code you haven't checked!
  389. ===========================================
  390.  
  391. Thanks to Timo Rossi for spotting the stupid bug in my copper
  392. setup routine (using LOFList instead of copinit). Funnily enough
  393. my own setup routine uses the correct copinit code:
  394.  
  395. Please ignore the original file and use this instead.
  396.  
  397.  
  398.  
  399.  
  400. 12. Copper End
  401. ==============
  402. Always use two copper end commands ie $FFFF,$FFFE,$FFFF,$FFFE.
  403. Why? I'm not sure, but it definately said in the Harwdare
  404. Ref book that you should, ISTR that some Amiga 1000's had a dodgy
  405. copper that could overrun the first Copper End. If you look
  406. at OS copperlists they all have (or at least did when I last looked!)
  407. two END commands.
  408.  
  409. Having just read through the new grey Hardware Reference Manual, I
  410. can find no mention of this at all. Odd. Perhaps I dreamt it?
  411. Who knows? :-) Certainly if you're using copperlists that get
  412. heavily modified two end commands will prevent a bogus SKIP 
  413. command dropping the copper program counter off the end of your
  414. copperlist...
  415.  
  416.  
  417. 13. Vector Base Register (68010 and up)
  418. =======================================
  419.  
  420. The 68010 and above processors have a Vector Base Register (VBR)
  421. that allows the exception vector table to be placed anywhere in
  422. RAM, including fast ram. This gives some speed benefits to systems
  423. with this running, but at a cost.
  424.  
  425. Anything that accesses the interrupt locations directly, for example:
  426.  
  427.     move.l    $6c.w,old
  428.     move.l    MyWickedInterruptCode,$6c.w
  429.  
  430. won't work...     Unfortunately this includes 99.9% of demos.
  431.  
  432. Boerg Noest (borgen@stud.cs.uit.no) writes....
  433.  
  434. > Next your text should mention VBR. It's easy - like this:
  435. >     move.l 4.w a6
  436. >    moveq   #0,d0
  437. >    btst.b  #AFB_68010,AttnFlags+1(a6)
  438. >    beq     .done
  439. >    movec   vbr,d0
  440. >.done
  441. >    move.l  d0,VBRBase
  442. >    rts
  443. >
  444. then you just
  445. >    move.l     VBRBase,a0
  446.     move.l    $6c(a0),oldinterrupt
  447. >    move.l     #myinterrupt,$6c(a0)
  448. >
  449.  
  450. Ok. I don't know how many people use the VBR to offset their interrupts,
  451. I certainly don't as it breaks too much software on my 3000, and it
  452. only gives a minimal speed increase. The main benefit of the 68010
  453. over the 68000 is the loop cache mode. Common 3 word loops like:
  454.  
  455.     moveq    #50,d0
  456. .lp    move.b    (a0)+,(a1)+    ; one word
  457.     dbra    d0,.lp        ; two words
  458.  
  459. are recognised as loops and speed up dramatically on 68010.
  460.  
  461.  
  462.  
  463. 14 Using the blitter.
  464. =====================
  465.  
  466. If you are using the blitter in your code and you are leaving the
  467. system intact (as you should) always use the graphics.library
  468. functions OwnBlitter() and DisownBlitter() to take control
  469. of the blitter. Remember to free it for system use, many system
  470. functions (including floppy disk data decoding) use the blitter.
  471.  
  472. Another big mistake I've seen is with blitter/processor timing.
  473.  
  474. Assuming that a particular routine will be slow enough that a blitter
  475. wait is not needed is silly. Always check for blitter finished, and
  476. wait if you need to.
  477.  
  478. Don't assume the blitter will always run at the same speed too. Think
  479. about how your code would run if the processor or blitter were running
  480. at 100 times the current speed. As long as you keep this in mind,
  481. you'll be in a better frame of mind for writing compatable code.
  482.  
  483. Another big source of blitter problems is using the blitter in interrupts.
  484.  
  485. Most demos do all processing in the interrupt, with only a
  486.  
  487. .wt    btst    #6,$bfe001        ; is left mouse button clicked?
  488.     bne.s    .wt    
  489.     
  490. loop outside of the interrupt. However, some demos do stuff outside the
  491. interrupt too. Warning. If you use blitter in both your interrupt
  492. and your main code, (or for that matter if you use the blitter via the
  493. copper and also in your main code), you may have big problems....
  494.  
  495. Take this for example:
  496.     
  497.     lea    $dff000,a5
  498.     bsr    WaitBlitterFinish    ; check bits for blitter ready
  499.     move.l    #-1,BLTAFWM(a5)        ; set FWM and LWM in one go
  500.     move.l    #source,BLTAPT(a5)    
  501.     move.l    #dest,BLTDPT(a5)
  502.     move.w    #100111110000,BLTCON0(a5)                
  503.     move.w    #0,BLTCON1(a5)        
  504.     move.w    #64*height+width/2,BLTSIZE(a5)    ; trigger blitter
  505.  
  506. There is *nothing* stopping an interrupt, or copper, triggering a
  507. blitter operation between the WaitBlitterFinish call and
  508. your final BLTSIZE blitter trigger. This can lead to total system blowup.
  509.  
  510. Code that may, by luck, work on standard speed machines may die horribly
  511. on faster processors due to timing differences causing this type of
  512. problem to occurr.
  513.  
  514. The safest way to avoid this is to keep all your blitter calls together,
  515. use the copper exclusively, or write a blitter-interrupt routine to
  516. do your blits for you.
  517.  
  518. Always remember to do two blitter-wait-checks... eg:
  519.  
  520.     btst.b    #DMAB_BLTDONE-8,DMACONR(a1)
  521.     btst.b    #DMAB_BLTDONE-8,DMACONR(a1)
  522.  
  523. The first may not give the correct result on machines with early
  524. (non Fat) Agnus chips (eg Amiga 1000, German A2000).
  525.  
  526. 15 NTSC
  527. =======
  528.  
  529. As an European myself, I'm naturally biased agains the inferior video
  530. system, but even though the US & Canada have a relatively minor Amiga
  531. community compared with Europe (Sorry, it's true :-) we should still
  532. help them out, even though they've never done a PAL Video Toaster for
  533. us (sob!).
  534.  
  535. You have two options.
  536.  
  537. Firstly, you could write your code only to use the first 200 display
  538. lines, and leave a black border at the bottom. This annoys PAL owners,
  539. who rightly expect things to have a full display. It took long enough
  540. for European games writers to work out that PAL displays were better.
  541.  
  542. You could write code that automatically checked which system it is
  543. running on and ran the correct code accordingly:
  544.  
  545. (How to check: Note, this is probably not the officialy supported method,
  546. but so many weird things happen with new monitors on AGA machines that
  547. I prefer this method, it's simpler, and works under any Kickstart)
  548.  
  549.     move.l    4.w,a6          ; execbase
  550.     cmp.b    #50,PowerSupplyFrequency(a6)    ; 531(a6)
  551.     beq.s    .pal
  552.  
  553.         jmp    I'm NTSC (or more accurately, I'm running from 60Hz power)
  554. .pal    jmp    I'm PAL  (or I'm running from 50hz power).
  555.  
  556.  
  557. If people have already switched modes to PAL, or if they are running
  558. some weird software like the ICD Flicker Free Video Prefs thingy, then
  559. this completely ignores them, but that serves them right for trying
  560. to be clever :-)
  561.  
  562. Probably better would be to check VBlankFrequency(a6) [530(a6)]
  563. as well, if both are 60Hz then it's definately a NTSC machine. If
  564. one or more are 50Hz, then it's probably a better idea to run in PAL.
  565.  
  566. Under Kickstart 2.04 or greater, the Display Database can be accessed. 
  567. Any program can enquire of the database what type of displays
  568. are available, so for example "I want a 50hz 15Khz PAL screen. Can
  569. I display it on this Amiga?" (Unfortunately it doesn't take
  570. an ASCII string like that, but it's not that more dificult). Of
  571. course many users will have the default monitor installed (PAL or
  572. NTSC) and not realise that they can have extra modes by dragging
  573. the monitor icon into their Monitors drawer, and of course
  574. this doesn't work on Kickstart 1.3 machines.
  575.  
  576. Now, if you want to force a machine into the other display system
  577. you need some magic pokes: Here you go (beware other bits in
  578. $dff1dc can do nasty things. One bit can reverese the polarity
  579. on the video sync, not to healthy for some monitors I've heard...)
  580.  
  581. To turn a NTSC system into PAL (50Hz)
  582.  
  583.     move.w    #32,$dff1dc        ; Magically PAL
  584.  
  585. To turn a PAL system into NTSC (60Hz)
  586.  
  587.     move.w    #0,$dff1dc        ; Magically NTSC
  588.  
  589. Remember: Not all displays can handle both display systems!
  590. Commdore 1084/1084S, Philips 8833/8852 and multisync monitors
  591. will, and very few TV's will handle PAL signals (especially
  592. if being used with a NTSC Amiga modulator). I gather that
  593. most NTSC machines are Amiga 2000's, so perhaps this isn't
  594. a problem.
  595.  
  596. So come on you NTSC users, tell us how you would prefer
  597. the demos written!
  598.  
  599.  
  600.  
  601. 16 Programming AGA hardware
  602. ===========================
  603. I've just got this interesting text file which I thought should be
  604. included with this document:
  605.  
  606. The followings informations were gathered by Junkie/PMC Fr and Yragael.
  607.  
  608. Junkie  bought  a  1200  some  days  ago  and  started  quickly to dasm the
  609. copperlist of the workbench.  Thanx to his work of prime importance and his
  610. impressive  speed  which  leads  me to dasm the copperlist too, I (Yragael)
  611. brings you the followings informations.
  612.  
  613. More  should  follow  as  long  as  we  will not get the hardware reference
  614. manual.
  615.  
  616. We are waiting for your works on 1200 and your cooperation to the trip into
  617. the hardware of the A1200.
  618.  
  619. (next  issue:   Sprite  corrections,  HAM8+,  other  graphic modes, 3 words
  620. copperlists ...)
  621.  
  622. ***************************************************************************
  623.  
  624. USING THE SUPERHIRES MODE
  625.  
  626. To  use  the  SuperHires  mode  (1280  pixels  wide), just use the bit 6 of
  627. register $0100
  628.  
  629. bit 6 | Mode SuperHires
  630. -----------------------
  631.   0   | Non selectionne
  632. -----------------------
  633.   1   | Selectionne
  634. -----------------------
  635.  
  636. ***************************************************************************
  637.  
  638. USING 8 BITPLANES
  639.  
  640. The  number  of bitplanes available used to be no more than 7 and was coded
  641. using  the  bits  14 to 12 of register $0100.  To use 8 bitplanes, just use
  642. bit  4  of  register  $0100.   The  value of bits 14 to 12 will then not be
  643. considered anymore.
  644.  
  645. bit 4 | 8 bitplanes mode 
  646. ------------------------
  647.   0   | Not selected
  648. ------------------------
  649.   1   | Selected
  650. ------------------------
  651.  
  652. ***************************************************************************
  653.  
  654. ACCEDING 24 BITS COLORS
  655.  
  656. The 24 bits color is coded using 2 words:
  657.  
  658. - the first receives the 4 low bits of each R, G and B componants
  659. - the second receives the 4 high bits of each R, G and B componants
  660.  
  661. To modify a color using 24 bits coding, you must use 2 coppers-moves on the
  662. same  color  register.   The  first move must ABSOLUTELY be the move of the
  663. word  of  the 3*4 high bits, the second move is the move of the word of the
  664. 3*4 low bits.
  665.  
  666. The  copper  knowns  when the move regards the 3*4 low bits or the 3*4 high
  667. bits by checking the bit 9 of register $0106
  668.  
  669. bit 9 | Componants access
  670. -----------------------------------------------------------------
  671.   0   | Access to the 4 low bits of componants R, G and B
  672. -----------------------------------------------------------------
  673.   1   | Access to the 4 high bits of componants R, G and B
  674. -----------------------------------------------------------------
  675.  
  676. ex: change $0180 to $00123456 in the copperlist
  677.  
  678. $01060000
  679. $01800135
  680. $01060200
  681. $01800246
  682.  
  683. When  you  want  to  work using the 12 bits color coding mode, the 3*4 bits
  684. value you move to the color register is considered by the copper as the 3*4
  685. high bits.  You don't have to care about $0106.  It seems bit 9 of register
  686. $0106 is initialized to 0 at each copjmp.
  687.  
  688. ***************************************************************************
  689.  
  690. ACCEDING THE 256 COLORS PALETTE
  691.  
  692. The  amiga  don't  work  with  256  separate color registers.  A same color
  693. register is used several times to code several colors.
  694.  
  695. The  amiga  just  works with 8 differents palettes of 32 colors each, using
  696. color registers from $0180 to $01BE.
  697.  
  698. You  can  choose  the  palette  you want to access via the bits 11 to 14 of
  699. register $0106
  700.  
  701.  
  702. bit 14 | bit 13 | bit 12 | Selected palette
  703. --------------------------------------------------------
  704.    0   |    0   |    0   | Palette 0 (color 0 to 31)
  705. --------------------------------------------------------
  706.    0   |    0   |    1   | Palette 1 (color 32 to 63)
  707. --------------------------------------------------------
  708.    0   |    1   |    0   | Palette 2 (color 64 to 95)
  709. --------------------------------------------------------
  710.    0   |    1   |    1   | Palette 3 (color 96 to 125)
  711. --------------------------------------------------------
  712.    1   |    0   |    0   | Palette 4 (color 128 to 159)
  713. --------------------------------------------------------
  714.    1   |    0   |    1   | Palette 5 (color 160 to 191)
  715. --------------------------------------------------------
  716.    1   |    1   |    0   | Palette 6 (color 192 to 223)
  717. --------------------------------------------------------
  718.    1   |    1   |    1   | Palette 7 (color 224 to 255)
  719. --------------------------------------------------------
  720.  
  721. ex: You want to change color 177 to $00123456
  722.  
  723. Color 177 is color $01A2 of palette 5
  724.  
  725. $01065000
  726. $01800246
  727. $01065200
  728. $01800135
  729.  
  730. ***************************************************************************
  731.  
  732. SWITCHING THE PALETTE
  733.  
  734. You can switch colors. The definition of switching color A and color B is:
  735.  
  736. - Color registers of colors A and B are NOT modified by the switching
  737. - Color  A  is  displayed  using  the  content  of register of  color B and
  738.   vice-versa
  739.  
  740. The  switching  of  palette  can't be used on just n colors of the palette.
  741. Once  you  choose  a  switching  value,  ALL  the  palette's colors will be
  742. switched.   The  switching  value  is  the  value separing the colors to be
  743. switched and is coded with bits 15 to 8 of register $010C.
  744.  
  745. ex: You want all the colors separated by  one  color in the colorlist to be
  746.     switched
  747.  
  748. $0180 <--
  749. $0182 <--|--
  750. $0184 <--   |
  751. $0186 <-----
  752. $0188 <--------
  753.  .             |
  754.  .
  755.  .
  756.  
  757. Value 2 will be stocked in bits 15 to 8.
  758.  
  759. The  switching  works  with the palette as if it was a circular palette.  I
  760. mean  if  if the copper consider color 255 and must switch by 1 the colors,
  761. color $0180 will be assiocated to color 255.
  762.  
  763. ***************************************************************************
  764.  
  765. USING SPRITES IN LOWRES, HIRES AND SUPERHIRES
  766.  
  767. To  change  the  reolution  of the sprite, just use bit 7 and 6 of register
  768. $0106
  769.  
  770. bit 7 | bit 6 | Resolution
  771. --------------------------
  772.   0   |   0   | Lowres
  773. --------------------------
  774.   1   |   0   | Hires
  775. --------------------------
  776.   0   |   1   | Lowres
  777. --------------------------
  778.   1   |   1   | SuperHires
  779. --------------------------
  780.  
  781. ***************************************************************************
  782.  
  783. USING 16, 32 AND 64 PIXELS WIDE SPRITES
  784.  
  785. Well,  I  still  have bug there with sprites in 32 or 64 pixels.  Sorry but
  786. the followings informations may have to be corrected.
  787.  
  788. Use bit 3 and 2 of register $01FC
  789.  
  790. bit 3 | bit 2 | Wide
  791. -------------------------
  792.   0   |   0   | 16 pixels
  793. -------------------------
  794.   1   |   0   | 32 pixels
  795. -------------------------
  796.   0   |   1   | 32 pixels
  797. -------------------------
  798.   1   |   1   | 64 pixels
  799. -------------------------
  800.  
  801. The  copper  doesn't read the spritelist in the same way regarding the wide
  802. you choose for your sprite
  803.  
  804. 16 pixels wide reading:
  805.  
  806. word C1, word C2
  807. word A1, word B1
  808.  .
  809.  .
  810.  .
  811. word An, word Bn
  812. $0000 0000
  813.  
  814. C1=first control word
  815. C2=second control word
  816.  
  817. Ai and Bi are combined via OR to form the sprite
  818.  
  819. 32 pixels wide reading:
  820.  
  821. long C1, long C2
  822. long A1, long B1
  823.  .
  824.  .
  825.  .
  826. long An, long Bn
  827. $0000 0000 0000 00000
  828.  
  829. C1=first control long
  830.    the  first control word is the high word of C1.  The low word of C1 must
  831.    contain the second control word.
  832. C2=second control long
  833.    the second control word is the high word of C2. Low word of C2 is $0000
  834.  
  835. Ai and Bi are combined via OR to form the sprite
  836.  
  837. 64 pixels wide reading:
  838.  
  839. double C1, double C2
  840. double A1, double B1
  841.  .
  842.  .
  843.  .
  844. double An, double Bn
  845. $0000 0000 0000 00000 0000 0000 0000 00000
  846.  
  847. C1=first control double
  848.    C1=W3:W2:W1:W0 (Wi=words)
  849.    W3 is first control word
  850.    W2 and W1 are second control word
  851. C2=second control double
  852.    C2=W3:W2:W1:W0 (Wi=words)
  853.    W3 is second control word
  854.  
  855. Ai and Bi are combined via OR to form the sprite
  856.  
  857. ***************************************************************************
  858.  
  859. CHANGING THE SPRITE PALETTE
  860.  
  861. It  is possible to choose the color palette of the sprite.  This is done by
  862. the bits 7 and 4 of register $010C.
  863.  
  864. bit 7 | bit 6 | bit 5 | bit 4 | Starting color of the sprite's palette
  865. -------------------------------------------------------------------------
  866.   0   |   0   |   0   |   0   | $0180/palette 0 (coulor 0)
  867. -------------------------------------------------------------------------
  868.   0   |   0   |   0   |   1   | $01A0/palette 0 (color 15)
  869. -------------------------------------------------------------------------
  870.   0   |   0   |   1   |   0   | $0180/palette 1 (color 31)
  871. -------------------------------------------------------------------------
  872.   0   |   0   |   1   |   1   | $01A0/palette 1 (color 47)
  873. -------------------------------------------------------------------------
  874.   0   |   1   |   0   |   0   | $0180/palette 2 (color 63)
  875. -------------------------------------------------------------------------
  876.   0   |   1   |   0   |   1   | $01A0/palette 2 (color 79)
  877. -------------------------------------------------------------------------
  878.   0   |   1   |   1   |   0   | $0180/palette 3 (color 95)
  879. -------------------------------------------------------------------------
  880.   0   |   1   |   1   |   1   | $01A0/palette 3 (color 111)
  881. -------------------------------------------------------------------------
  882.   1   |   0   |   0   |   0   | $0180/palette 4 (color 127)
  883. -------------------------------------------------------------------------
  884.   1   |   0   |   0   |   1   | $01A0/palette 4 (color 143)
  885. -------------------------------------------------------------------------
  886.   1   |   0   |   1   |   0   | $0180/palette 5 (color 159)
  887. -------------------------------------------------------------------------
  888.   1   |   0   |   1   |   1   | $01A0/palette 5 (color 175)
  889. -------------------------------------------------------------------------
  890.   1   |   1   |   0   |   0   | $0180/palette 6 (color 191)
  891. -------------------------------------------------------------------------
  892.   1   |   1   |   0   |   1   | $01A0/palette 6 (color 207)
  893. -------------------------------------------------------------------------
  894.   1   |   1   |   1   |   0   | $0180/palette 7 (color 223)
  895. -------------------------------------------------------------------------
  896.   1   |   1   |   1   |   1   | $01A0/palette 7 (color 239)
  897. -------------------------------------------------------------------------
  898.  
  899. ***************************************************************************
  900.  
  901.  
  902. That's all. Thanx you VERY MUCH to Junkie/PMC Fr for his work.
  903.  
  904.                                            Written by Yragael
  905.                     Chaos.  Live it.  Learn it.  Be it.
  906.  
  907.                      _\!/_ The Illuminated Ones _\!/_
  908.                       /!\  ««««««««««»»»»»»»»»»  /!\
  909.  
  910. Interesting, eh?
  911.  
  912.  
  913. 17 Keyboard Timings
  914. ===================
  915.  
  916. If you have to read the keyboard by hardware, be very careful
  917. with your timings. Not only do different processor speeds affect
  918. the keyboard timings (for example, in the game F-15 II Strike Eagle
  919. on an Amiga 3000 the key repeat delay is ridiculously slow, you
  920. ttyyppee lliikkee tthhiiss aallll tthhee ttiimmee. You use
  921. up an awful lot of Sidewinders very quickly!)
  922.  
  923. Again, here's something from Boerge:
  924.  
  925. >Third, you should warn about f**king up the keyboard read timing. My keyboard
  926. >absolutely does not work with just reading the $bfxxxx turning it to output,
  927. >and writing the reply, and turning it to input again. I do not have any code
  928. >that is especially good, but for now I use this:
  929. >        move.b  $bfec01,d0      ;get keycode
  930. >        not.b   d0                                
  931. >        lsr.b   #1,d0           ;test up/down flag
  932. >        bcs.s   .NoStore        ;if up, ignore    
  933. >                                                  
  934. >        move.b  d0,Key                            
  935. >.NoStore                                          
  936. >                                                  
  937. >;handshake                                        
  938. >        bset    #6,$bfee01      ;output           
  939. >        clr.b   $bfec01                           
  940. >        moveq   #4-1,d0                           
  941. >.L1     move.b  VHPOSR,d1                         
  942. >.L2     cmp.b   VHPOSR,d1                         
  943. >        beq.b   .L2                               
  944. >        dbra    d0,.L1                            
  945. >                                                  
  946. >        bclr    #6,$bfee01      ;input again
  947.  
  948. Remember though, if you have system interrupts and workbench enabled,
  949. keys can fall-through to workbench. For example, press Amiga-Q in
  950. your demo and you may find Workbench closed on return!
  951.  
  952.  
  953. 18 How to break out of never-ending loops
  954. =========================================
  955.  
  956. Another great tip for Boerge here:
  957.  
  958. >This is a simple tip I have. I needed to be able to break out of my
  959. >code if I had neverending loops. I also needed to call my exit code when I did
  960. >this. Therefore I could not just exit from the keyboard interrupt which I have
  961. >taken over(along with the rest of the machine). My solution wa to enter
  962. >supervisor mode before I start my program, and if I set the stack back then
  963. >I can do an RTE in the interrupt and just return from the Supervisor() call.
  964. >This is snap'ed from my code:
  965. >
  966. >    lea     .SupervisorCode,a5
  967. >    move.l  sp,a4           ; 
  968. >    move.l  (sp),a3         ; 
  969. >    EXEC    Supervisor
  970. >    bra     ReturnWithOS
  971. >
  972. >.SupervisorCode
  973. >    move.l  sp,crashstack   ; remember SSP                
  974. >    move.l  USP,a7          ; swap USP and SSP            
  975. >    move.l  a3,-(sp)        ; push return address on stack
  976. >
  977. >that last was needed because it was a subroutine that RTSes (boy did I have
  978. >porblems working out my crashes before I fixed that)
  979. >Then I have my exit code:
  980. >
  981. >ReturnWithOS
  982. >    tst.l   crashstack                                   
  983. >    beq     .nocrash                                     
  984. >    move.l  crashstack,sp                                
  985. >    clr.l   crashstack                                   
  986. >    RTE                     ; return from supervisor mode
  987. >.nocrash
  988. >
  989. >my exit code goes on after this.
  990. >
  991. >This made it possible to escape from an interrupt without having to care
  992. >for what the exception frames look like.
  993.  
  994.  
  995.  
  996.  
  997. 19. Version numbers!
  998. ====================
  999.  
  1000. Put version numbers in your code. This allows the CLI version command
  1001. to determine easily the version of both your source and executable
  1002. files. Some directory utilities allow version number checking too (so
  1003. you can't accidentally copy a newer version of your source over
  1004. an older one, for example). Of course, if you pack your files the
  1005. version numbers get hidden. Leaving version numbers unpacked
  1006. was going to be added to PowerPacker, but I don't know if this is
  1007. done yet.
  1008.  
  1009. A version number string is in the format
  1010.  
  1011. $VER: howtocode3.txt 3.0 31/12/92.
  1012. ^          ^          ^Version number (date is optional)
  1013. |          |
  1014. |          | File Name
  1015. |
  1016. | Identifier
  1017.  
  1018. The Version command searches for $VER and prints the string it finds 
  1019. following it.    
  1020.  
  1021. For example, adding the line to the begining of your source file
  1022.  
  1023. ; $VER: MyFunDemo.s 3.0 31/12/92    
  1024.     
  1025. and somewhere in your code
  1026.  
  1027.     dc.b    "$VER: MyFunDemo 3.0 31/12/92",0
  1028.  
  1029. means if you do VERSION MySource you will get:
  1030.  
  1031. MyFunDemo.s 3.0 31/12/92
  1032.  
  1033. and if you assemble and do Version MyFunDemo, you'll get
  1034.  
  1035. MyFunDemo 3.0 31/12/92
  1036.  
  1037. Try doing version howtocode3.txt and see what you get :-)
  1038.  
  1039. This can be very useful for those stupid demo compilations
  1040. where everything gets renamed to 1, 2, 3, etc...
  1041.  
  1042. Just do version 1 to get the full filename (and real date)
  1043.  
  1044.  
  1045.  
  1046.  
  1047. Thanks to everyone who has replied. Any more questions, queries,
  1048. or "CJ, you got it wrong again!" type mail to the email
  1049. address below....
  1050.  
  1051. Happy new year!!!!
  1052.  
  1053.  
  1054.  
  1055.  
  1056. --------------------------------------------------------------------
  1057.  
  1058. This text is Copyright (C) 1992 Share and Enjoy, but may be freely
  1059. distributed in any electronic form.
  1060.  
  1061. All opinions expressed in this article are my own, and in no way
  1062. reflect those of Share and Enjoy or any BBS this file may be found
  1063. on.
  1064.  
  1065. I didn't write this for fun, I wrote it for you to use! Hopefully
  1066. this will grow into a big file that demo coders can use. 
  1067.  
  1068. If you strongly disagree with anything I write, or you want to send me
  1069. some source or demos to test on Amiga 1200/4000 etc, or you have
  1070. questions about Amiga programming, or suggestions for future articles,
  1071. or just want to chat about the best way to optimise automatic copperlist
  1072. generation code, then contact me via email at:
  1073.  
  1074. comradej@althera.demon.co.uk or by email at Bad Dreams BBS.
  1075.  
  1076.