home *** CD-ROM | disk | FTP | other *** search
- ;BlitterSand
- ;by Mike Creutz
- ; P.O. Box 204
- ; E. Moriches, NY 11940
- ; USA
- ;creutz@bnlux0.bnl.gov
- ;23 June 1990
-
- ;This program simulates the cellular automaton model presented
- ;by P. Bak, C. Tang, and K. Wiesenfeld (Phys. Rev. Lett. 59, 381 (1987);
- ;Phys. Rev. A38, 364 (1988)) to illustrate self organized criticality.
- ;Each site carries a positive integer representing the local slope of
- ;a sandpile. If the slope exceeds 3, the site is unstable and on
- ;updating it drops by 4, adding one to each of his neighbors.
- ;Sand is lost only at the edges. Any state will relax to stability
- ;through such sand loss.
-
- ;The colors representing slopes of 0 through 7 are white, black,
- ;red, green, yellow, blue, magenta, and cyan, respectively.
-
- ;Various keypresses do as follows:
- ; <esc>, q, or any control character exits
- ; p pauses; repeated presses single step; any other key restarts
- ; d doubles the lattice modulo 8
- ; a sets a flag to pause after each relaxation
-
- ;The program can be run from either CLI or Workbench. This code
- ;is completely self contained and will run directly through A68K
- ;followed by BLink without need for any include files.
-
- ;The program directly accesses the blitter for speed, but does
- ;so in a mode friendly to multitasking. To understand the program
- ;details you should have the Amiga Hardware Reference Manual.
-
- ;Technically, the show proceeds as follows:
-
- ;We start with ones on the borders and twos on the corners
- ;of a 288 by 188 lattice. For the first loop, whenever a stable state
- ;occurs, the heights are all doubled, and the system is allowed to
- ;relax back to stability. This eventually leads to a unique state
- ;that when doubled relaxes to itself. The system can be described
- ;as a large Abelian group and this state represents the identity.
-
- ;After the identity is found, the program proceeds to construct
- ;the inverse of the state with all cells unity. After this is found it
- ;is tripled to give the inverse of the minimally stable state with all
- ;cells being 3.
-
- ;After all this, to keep the show going, the identity is
- ;added to the system which then relaxes back to itself. This loops
- ;until intervention.
-
- ;If you hit 'd' on an active state early in the program, the search for
- ;the identity will be derailed and the program will go into a mode where
- ;the pattern is unlikely to repeat for the lifetime of the universe.
- ;After a few hours, however, it will probably look uninterestingly random.
- ; ******************************************************
-
- ; library offsets:
- _LVOOpenLibrary EQU -552
- _LVOCloseLibrary EQU -414
- _LVOSetAPen EQU -342
- _LVOSetBPen EQU -348
- _LVOSetDrMd EQU -354
- _LVOWritePixel EQU -324
- _LVOMove EQU -240
- _LVODraw EQU -246
- _LVOText EQU -60
- _LVOClipBlit EQU -552
- _LVOOpenScreen EQU -198
- _LVOOpenWindow EQU -204
- _LVOCloseScreen EQU -66
- _LVOCloseWindow EQU -72
- _LVOGetMsg EQU -372
- _LVOReplyMsg EQU -378
- _LVOWaitPort EQU -384
- _LVOLoadRGB4 EQU -192
- _LVOOwnBlitter EQU -456
- _LVODisownBlitter EQU -462
- _LVOWaitBlit EQU -228
- _LVOAllocMem EQU -198
- _LVOFreeMem EQU -210
- _LVOSetRast EQU -234
- _LVOFindTask EQU -294
- _LVOForbid EQU -132
-
- ;IDCMP Flags
- CLOSEWINDOW EQU $200
- VANILLAKEY EQU $200000
- ; window flags
- WINDOWDRAG EQU $2
- WINDOWDEPTH EQU $4
- WINDOWCLOSE EQU $8
- BACKDROP EQU $100
- BORDERLESS EQU $800
- ACTIVATE EQU $1000
- ; various useful numbers
- MEMF_PUBLIC EQU 1
- MEMF_CHIP EQU 2
- MEMF_FAST EQU 4
- MEMB_CLEAR EQU $10000
- pr_CLI EQU 172
- pr_MsgPort EQU 92
- AbsExecBase EQU $4
- JAM1 EQU 0
- JAM2 EQU 1
- COMPLEMENT EQU 2
- INVERSID EQU 3
-
- ; custom chip register offsets
- _custom EQU $DFF000
- DMACONR EQU $002
- BLTCON0 EQU $040
- BLTCON1 EQU $042
- BLTAFWM EQU $044
- BLTALWM EQU $046
- BLTCPT EQU $048
- BLTBPT EQU $04C
- BLTAPT EQU $050
- BLTDPT EQU $054
- BLTSIZE EQU $058
- BLTCMOD EQU $060
- BLTBMOD EQU $062
- BLTAMOD EQU $064
- BLTDMOD EQU $066
- BLTCDAT EQU $070
- BLTBDAT EQU $072
- BLTADAT EQU $074
-
- ; various size parameters
- xmin EQU 16 ; should be a multiple of 16
- ymin EQU 11 ; 11 or more to avoid border effects
- xmax EQU 303 ; -1+multiple of 16
- ymax EQU 198
-
- ; a small system for testing:
- ;xmin equ 48
- ;xmax equ 127
- ;ymin equ 50
- ;ymax equ 150
-
- startdisp EQU 2*(xmin/16)+ymin*40 ; shift from start of bitplane to lattice
- modulo EQU 40-2*((xmax-xmin+1)/16) ; blitter modulo
- enddisp EQU -modulo-2+((ymax-ymin+1)*40) ; shift to end of lattice
- bsize EQU 20-(modulo/2)+$40*(ymax-ymin+1) ; for BLTSIZE
- workspacesize EQU 40*(ymax-ymin+1)
-
- ; startup code for CLI or Workbench
- ; opens graphics and intuition libraries, calls 'Main' and exits
- startup:
- movem.l d2-d7/a2-a6,-(a7) ; save registers
- move.l AbsExecBase,a6 ; exec base pointer
- clr.l workbenchmessage
- suba.l a1,a1 ; clear a1
- jsr _LVOFindTask(a6) ; where is our task
- move.l d0,a4
- tst.l pr_CLI(a4) ; are we running from CLI?
- bne fromcli ; if not then get workbench message
- lea pr_MsgPort(a4),a0
- jsr _LVOWaitPort(a6)
- Jsr _LVOGetMsg(a6)
- move.l d0,workbenchmessage ; save for exit
- ;open graphics and intuition libraries
- fromcli lea GraphicsName(pc),a1 ; pointer to name of library
- moveq #0,d0 ; accept any version
- jsr _LVOOpenLibrary(a6)
- move.l d0,GraphicsBase ; save graphics base
- tst.l d0
- beq.s Exit1 ; quit if trouble opening library
- lea IntuitionName(pc),a1 ; pointer to name of library
- moveq #0,d0 ; accept any version
- jsr _LVOOpenLibrary(a6)
- move.l d0,IntuitionBase ; save intuition base
- tst.l d0
- beq.s Exit2 ; quit if trouble opening library
-
- ; execute main program
- bsr Main
-
- ;final cleanup
- Exit3: movea.l IntuitionBase,a1 ; intuition base
- movea.l AbsExecBase,a6 ; exec base pointer
- jsr _LVOCloseLibrary(a6)
- Exit2: movea.l GraphicsBase,a1 ; graphics base
- jsr _LVOCloseLibrary(a6)
- moveq.l #0,d0 ; return zero
- Exit1: tst.l workbenchmessage ; are we a workbench program?
- beq.s Exit0 ; if not goto exit0
- jsr _LVOForbid(a6) ; because the RKM tells me so
- movea.l workbenchmessage(pc),a1
- jsr _LVOReplyMsg(a6) ; reply to workbench message
- Exit0: movem.l (a7)+,d2-d7/a2-a6 ; restore registers
- rts ; end of startup code
-
- Main: move.l a7,oldstack ; save stack for exit
- ; allocate various working areas
- moveq.l #7,d2 ; memory allocation loop counter
- lea.l workingplane1(pc),a2
- bra.s startalloc
- allocloop move.l #workspacesize,d0 ; size for working area
- move.l #MEMF_CHIP+MEMB_CLEAR,d1 ;get chip memory
- jsr _LVOAllocMem(a6)
- tst.l d0
- beq quit1
- move.l d0,(a2)+
- startalloc dbf.s d2,allocloop
-
- ; open screen and window
- move.l IntuitionBase(pc),a6
- lea myscreen(pc),a0
- jsr _LVOOpenScreen(a6) ; open custom screen
- move.l d0,screen ; save screen structure pointer
- beq quit1 ; quit if trouble
- lea mywindow(pc),a0 ; open display window
- jsr _LVOOpenWindow(a6)
- move.l d0,window ; save address of window structure
- beq quit2 ;quit if trouble
- movea.l d0,a0
- move.l 86(a0),userport
- movea.l 50(a0),a0 ; rastport
- move.l a0,rastport
- move.l 4(a0),a0 ; bitmap structure
- move.l 8(a0),bitplane1
- move.l 12(a0),bitplane2
- move.l 16(a0),bitplane3
- addi.l #startdisp,bitplane1
- addi.l #startdisp,bitplane2
- addi.l #startdisp,bitplane3
- ;set colors
- movea.l GraphicsBase(pc),a6 ; graphics library address in a6
- movea.l screen(pc),a0
- adda.l #44,a0 ; viewport
- lea.l colors(pc),a1
- moveq.l #8,d0
- jsr _LVOLoadRGB4(a6)
- ; show credits
- bsr credits
- ;draw initial box of ones
- movea.l rastport(pc),a1
- moveq.w #1,d0
- jsr _LVOSetAPen(a6) ; set pen color
- movea.l rastport(pc),a1
- moveq.w #JAM1,d0
- jsr _LVOSetDrMd(a6) ; set drawing mode
- movea.l rastport(pc),a1
- move.w #xmin,d0
- move.w #ymin,d1
- jsr _LVOMove(a6) ; go to top left corner
- movea.l rastport(pc),a0
- move.w #xmax,d0
- move.w #ymin,d1
- jsr _LVODraw(a6) ; draw top line
- movea.l rastport(pc),a0
- move.w #xmax,d0
- move.w #ymax,d1
- jsr _LVODraw(a6) ; right side
- movea.l rastport(pc),a0
- move.w #xmin,d0
- move.w #ymax,d1
- jsr _LVODraw(a6) ; bottom
- movea.l rastport(pc),a0
- move.w #xmin,d0
- move.w #ymin,d1
- jsr _LVODraw(a6) ; left
- ;set corners to two
- movea.l rastport(pc),a1
- moveq.w #2,d0
- jsr _LVOSetAPen(a6) ; new color for corners
- movea.l rastport(pc),a1
- move.w #xmin,d0
- move.w #ymin,d1
- jsr _LVOWritePixel(a6) ; nw corner
- movea.l rastport(pc),a1
- move.w #xmax,d0
- move.w #ymin,d1
- jsr _LVOWritePixel(a6) ; ne corner
- movea.l rastport(pc),a1
- move.w #xmax,d0
- move.w #ymax,d1
- jsr _LVOWritePixel(a6) ; se corner
- movea.l rastport(pc),a1
- move.w #xmin,d0
- move.w #ymax,d1
- jsr _LVOWritePixel(a6) ; sw corner
-
- ; showtime -- first double until identity found
- firstloop: bsr relax
- lea.l storage1(pc),a0 ; prepare to compare with storage
- lea.l bitplane1(pc),a1
- bsr compare2 ; see if lattices equal
- btst.b #5,control(pc)
- bne.s foundidentity
- lea.l bitplane1(pc),a0
- lea.l storage1(pc),a1
- bsr copy2 ; copy bitplanes to storage
- bsr double ; double things
- bra.s firstloop
- ; save identity and set first storage plane to unity
- foundidentity:
- lea.l bitplane1(pc),a0
- lea.l identity1(pc),a1
- bsr copy2
- lea.l storage1(pc),a0
- bsr set1
- ; subtract first storage plane while adding identity
- bra.s stillactive
- secondloop: bsr sand
- btst.b #5,control(pc) ; check if still active
- beq.s stillactive
- lea.l identity1(pc),a0
- lea.l bitplane1(pc),a1
- bsr addit
- stillactive: bsr subtract1
- btst.b #5,control(pc) ; check if more to subtract
- bne.s tripleit
- bsr checkmessage
- bra.s secondloop
- ; triple to find inverse of minimally stable state
- tripleit bsr relax
- lea.l bitplane1(pc),a0
- lea.l storage1(pc),a1
- bsr copy2
- bsr double
- bsr relax
- lea.l storage1(pc),a0
- lea.l bitplane1(pc),a1
- bsr addit
- bsr relax
- ; to keep display moving, repeatedly add identity and relax
- finalloop lea.l identity1(pc),a0
- lea.l bitplane1(pc),a1
- bsr addit
- bsr relax
- bra.s finalloop
-
- ; time to quit
- getout:
- ; close windows and screen
- movea.l window(pc),a0
- move.l IntuitionBase(pc),a6
- jsr _LVOCloseWindow(a6)
- quit2 movea.l screen(pc),a0
- jsr _LVOCloseScreen(a6)
- ; deallocate memory
- quit1: movea.l AbsExecBase,a6
- moveq.l #7,d2 ; memory deallocation loop counter
- lea.l workingplane1(pc),a2
- bra.s startdealloc
- deallocloop move.l #workspacesize,d0 ; size for working area
- movea.l (a2)+,a1
- move.l a1,d1 ; to test if not zero
- beq.s done
- jsr _LVOFreeMem(a6) ; return memory
- startdealloc dbf.s d2,deallocloop
- done movea.l oldstack(pc),a7 ; reset stack pointer
- rts ; all done
-
- ; subroutine to update lattice until relaxed
- relax: bsr sand
- btst.b #5,control(pc) ; check if still active
- bne.s relaxed
- bsr checkmessage
- bra.s relax
- relaxed: tst.w autopause ; should we pause
- beq.s autooff
- bsr waitformessage
- autooff rts
-
- ; message handling subroutine
- ; message location returned in d0, class in d2, code in d3
- ; with VANILLAKEY code is ascii of pressed key
- waitformessage: ; pause for a signal
- movea.l AbsExecBase,a6
- movea.l userport(pc),a0
- jsr _LVOWaitPort(a6) ; wait for a message
- checkmessage: ; enter here to not wait if no message
- movea.l AbsExecBase,a6
- movea.l userport(pc),a0
- jsr _LVOGetMsg(a6)
- tst.l d0
- bne.s messagefound
- rts
- messagefound:
- movea.l d0,a1
- move.l 20(a1),d2 ; save class in d2
- move.w 24(a1),d3 ; and code in d3
- jsr _LVOReplyMsg(a6) ; reply to message
- ; check for various keypresses
- cmpi.w #27,d3 ; esc
- ble getout ; leave for escape or control characters
- cmpi.w #'q',d3
- beq getout ; quit for q
- cmpi.w #'p',d3 ; p ; pause for p
- bne.s not_p
- movea.l userport(pc),a0
- jsr _LVOWaitPort(a6) ; wait for a message
- not_p cmpi.w #'d',d3 ; d
- bne.s not_d ; double for d
- bsr double
- not_d cmpi.w #'a',d3 ; a
- bne.s not_a
- not.w autopause ; flip autopausing flag
- not_a rts ; continue
-
- ; storage area
- ; window and screen parameters
- mywindow dc.w 0,0,320,200 ; xmin,ymin,xsize,ysize
- dc.b 0,0 ; detail pen, block pen
- ; (Intuition Direct Communication Message Port)
- dc.l VANILLAKEY ; IDCMP Flags, ask for keypresses
- dc.l ACTIVATE+BORDERLESS ;+BACKDROP ; flags (type in amigabasic)
- dc.l 0 ; gadgets
- dc.l 0 ; checkmark
- dc.l title ; my title
- screen dc.l 0 ;location of screen, fill later
- dc.l 0 ;bitmap
- dc.w 0,0,320,200 ;min-max window size
- dc.w $f ; type: 1=wbenchscreen $F=customscreen
- myscreen dc.w 0,0,320,200 ;size
- dc.w 3 ;depth
- dc.b 5,6 ;pens
- dc.w $0 ;viewmodes- interlace=4, hires=$8000
- ; sprites=$4000, ham=$800, extra_halfbrite=$80
- dc.w $f ;type: customscreen
- dc.l textattr ;font
- dc.l title ;title
- dc.l 0 ;gadgets
- dc.l 0 ;custombitmap
- textattr dc.l fontname
- dc.w 8 ;fontsize
- dc.b 0,0 ;style and flags
- colors dc.w $fff ; color table
- dc.w $000
- dc.w $f00
- dc.w $0f0
- dc.w $ff0
- dc.w $00f
- dc.w $f0f
- dc.w $0ff
-
- workbenchmessage dc.l 0
- GraphicsBase dc.l 0
- IntuitionBase dc.l 0
- GraphicsName dc.b 'graphics.library',0
- IntuitionName dc.b 'intuition.library',0
- title dc.b 'BlitterSand -- <esc> to exit',0
- fontname dc.b 'topaz.font',0
- window dc.l 0
- rastport dc.l 0
- userport dc.l 0
- bitplane1 dc.l 0
- bitplane2 dc.l 0
- bitplane3 dc.l 0
- workingplane1 dc.l 0
- workingplane2 dc.l 0
- workingplane3 dc.l 0
- storage1 dc.l 0
- storage2 dc.l 0
- identity1 dc.l 0
- identity2 dc.l 0
- control dc.w 0
- autopause dc.w 0
- oldstack dc.l 0
-
- ; primary updating routine
- sand: movea.l GraphicsBase(pc),a6 ; graphics library address in a6
- jsr _LVOOwnBlitter(a6) ; grab blitter for my use
- lea _custom,a5
- move.l bitplane1(pc),d2 ;start of bitplane1
- move.l bitplane2(pc),d3 ;start of bitplane2
- move.l bitplane3(pc),d4 ;start of bitplane3
- move.l workingplane1(pc),d5 ; start of working plane 1
- move.l workingplane2(pc),d6 ; start of working plane 2
- move.l workingplane3(pc),d7 ; start of working plane 3
- ; add left, top, and bottom neighbors to workspace
- ; work on first bit:
- jsr _LVOWaitBlit(a6)
- move.l d5,BLTDPT(a5) ; first workspace plane
- move.l d4,d0
- move.l d0,BLTAPT(a5) ; for left neighbor
- addi.l #40,d0
- move.l d0,BLTBPT(a5) ; for bottom neighbor
- subi.l #80,d0
- move.l d0,BLTCPT(a5) ; for top
- move.w #0,BLTCON1(a5)
- move.w #$1f96,BLTCON0(a5) ; odd number of source bits set
- move.w #modulo,BLTAMOD(a5) ; set up modulos
- move.w #modulo,BLTBMOD(a5)
- move.w #modulo,BLTCMOD(a5)
- move.w #modulo,BLTDMOD(a5)
- move.w #$ffff,BLTAFWM(a5)
- move.w #$fffe,BLTALWM(a5) ; mask out last bit of row
- move.w #bsize,BLTSIZE(a5) ; do it
- ; second bit
- jsr _LVOWaitBlit(a6)
- move.l d6,BLTDPT(a5) ; second plane of workspace
- move.l d4,d0
- move.l d0,BLTAPT(a5) ; reset bitplane pointers
- addi.l #40,d0
- move.l d0,BLTBPT(a5)
- subi.l #80,d0
- move.l d0,BLTCPT(a5)
- move.w #$1fe8,BLTCON0(a5) ; 2 or more source bits set
- move.w #bsize,BLTSIZE(a5) ; go to it
- ; add in fourth neighbor, third bit of result
- jsr _LVOWaitBlit(a6)
- move.l d4,d0
- addi.l #enddisp,d0
- move.l d0,BLTAPT(a5) ; end of lattice
- move.l d7,d0
- addi.l #enddisp,d0
- move.l d0,BLTDPT(a5) ; end of third plane of workspace
- move.l d5,d0
- addi.l #enddisp,d0
- move.l d0,BLTBPT(a5) ; first workspace plane
- move.l d6,d0
- addi.l #enddisp,d0 ; second workspace plane
- move.l d0,BLTCPT(a5)
- move.w #2,BLTCON1(a5) ; descending mode
- move.w #$1f80,BLTCON0(a5) ; third bit only if all already set
- move.w #$7fff,BLTALWM(a5)
- move.w #bsize,BLTSIZE(a5) ; OK
- ; add in fourth neighbor, second bit of result
- jsr _LVOWaitBlit(a6)
- move.l d4,d0
- addi.l #enddisp,d0
- move.l d0,BLTAPT(a5)
- move.l d6,d0
- addi.l #enddisp,d0
- move.l d0,BLTDPT(a5)
- move.l d0,BLTCPT(a5)
- move.l d5,d0
- addi.l #enddisp,d0
- move.l d0,BLTBPT(a5)
- move.w #$1f6a,BLTCON0(a5) ; second bit only if appropriate
- move.w #bsize,BLTSIZE(a5) ; here we go again
- ; add in fourth neighbor, first bit of result
- jsr _LVOWaitBlit(a6)
- move.l d4,d0
- addi.l #enddisp,d0
- move.l d0,BLTAPT(a5)
- move.l d5,d0
- addi.l #enddisp,d0
- move.l d0,BLTDPT(a5)
- move.l d0,BLTBPT(a5)
- move.w #$1d3c,BLTCON0(a5) ; second bit from a xor b
- move.w #bsize,BLTSIZE(a5) ; finish setting up workspace
- ; add it all up
- jsr _LVOWaitBlit(a6) ; 2w,3w,2b to 3b
- move.l d4,BLTDPT(a5)
- move.l d3,BLTAPT(a5)
- move.l d6,BLTBPT(a5)
- move.l d7,BLTCPT(a5)
- move.w #0,BLTCON1(a5) ; reset for ascending mode
- move.w #$0fea,BLTCON0(a5)
- move.w #$ffff,BLTALWM(a5) ; fix last word mask
- move.w #bsize,BLTSIZE(a5)
- jsr _LVOWaitBlit(a6) ; 2w,2b to 2b
- move.l d3,BLTDPT(a5)
- move.l d3,BLTAPT(a5)
- move.l d6,BLTBPT(a5)
- move.w #$0d3c,BLTCON0(a5)
- move.w #bsize,BLTSIZE(a5)
- jsr _LVOWaitBlit(a6) ; 1w,1b,2b to 3w for carry
- move.l d7,BLTDPT(a5)
- move.l d2,BLTAPT(a5)
- move.l d3,BLTBPT(a5)
- move.l d5,BLTCPT(a5)
- move.w #$0f80,BLTCON0(a5)
- move.w #bsize,BLTSIZE(a5)
- jsr _LVOWaitBlit(a6) ; 1w, 1b to 2b
- move.l d3,BLTDPT(a5)
- move.l d2,BLTAPT(a5)
- move.l d5,BLTBPT(a5)
- move.l d3,BLTCPT(a5)
- move.w #$0f6a,BLTCON0(a5)
- move.w #bsize,BLTSIZE(a5)
- jsr _LVOWaitBlit(a6) ; final carry
- move.l d4,BLTDPT(a5)
- move.l d4,BLTAPT(a5)
- move.l d7,BLTBPT(a5)
- move.w #$0dfc,BLTCON0(a5)
- move.w #bsize,BLTSIZE(a5)
- jsr _LVOWaitBlit(a6) ; 1w, 1b to 1b
- move.w DMACONR(a5),control ; save control register for later
- move.l d2,BLTDPT(a5)
- move.l d2,BLTAPT(a5)
- move.l d5,BLTBPT(a5)
- move.w #$0d3c,BLTCON0(a5)
- move.w #bsize,BLTSIZE(a5)
- jsr _LVODisownBlitter(a6) ; I'm done for now
- rts
-
- ; double main lattice
- double: movea.l GraphicsBase(pc),a6 ; graphics library address in a6
- jsr _LVOOwnBlitter(a6)
- lea _custom,a5
- move.l bitplane1(pc),d2 ;start of bitplane1
- move.l bitplane2(pc),d3 ;start of bitplane2
- move.l bitplane3(pc),d4 ;start of bitplane3
- ; shift up all bitplanes
- jsr _LVOWaitBlit(a6)
- move.l d4,BLTDPT(a5) ; copy to plane 3
- move.l d3,BLTAPT(a5) ; from plane 2
- move.w #0,BLTCON1(a5)
- move.w #$09f0,BLTCON0(a5)
- move.w #modulo,BLTAMOD(a5)
- move.w #modulo,BLTBMOD(a5)
- move.w #modulo,BLTCMOD(a5)
- move.w #modulo,BLTDMOD(a5)
- move.w #$ffff,BLTAFWM(a5)
- move.w #$ffff,BLTALWM(a5)
- move.w #bsize,BLTSIZE(a5)
- jsr _LVOWaitBlit(a6)
- move.l d3,BLTDPT(a5) ; copy to plane 2
- move.l d2,BLTAPT(a5) ; from plane 1
- move.w #$09f0,BLTCON0(a5)
- move.w #bsize,BLTSIZE(a5)
- jsr _LVOWaitBlit(a6)
- move.l d2,BLTDPT(a5) ; clear plane 1
- move.w #$0100,BLTCON0(a5)
- move.w #bsize,BLTSIZE(a5)
- jsr _LVODisownBlitter(a6) ; give it back
- rts
-
- compare2 ; compare two planes, pointed to by (a0) and (a1)
- movea.l GraphicsBase(pc),a6 ; graphics library address in a6
- lea _custom,a5
- move.l (a0)+,d2 ;start of bitplane1
- move.l (a0),d3 ;start of bitplane2
- move.l (a1)+,d4 ;start of comparison bitplane1
- move.l (a1),d5 ;start of comparison bitplane2
- jsr _LVOOwnBlitter(a6) ; get blitter
- jsr _LVOWaitBlit(a6)
- move.l d2,BLTAPT(a5) ; plane 1
- move.l d4,BLTBPT(a5) ; compare 1
- move.w #0,BLTCON1(a5)
- move.w #$0c3c,BLTCON0(a5)
- move.w #modulo,BLTAMOD(a5)
- move.w #modulo,BLTBMOD(a5)
- move.w #$ffff,BLTAFWM(a5)
- move.w #$ffff,BLTALWM(a5)
- move.w #bsize,BLTSIZE(a5)
- jsr _LVOWaitBlit(a6)
- move.w DMACONR(a5),control ; save control register for later
- move.l d3,BLTAPT(a5) ; plane 2
- move.l d5,BLTBPT(a5) ; compare 2
- move.w #0,BLTCON1(a5)
- move.w #$0c3c,BLTCON0(a5)
- move.w #bsize,BLTSIZE(a5)
- jsr _LVOWaitBlit(a6)
- move.w DMACONR(a5),d0
- and.w d0,control ; save control register for later
- jsr _LVODisownBlitter(a6) ; give it back
- rts
-
- copy2 ; copy two planes, pointed to by (a0) and (a1)
- movea.l GraphicsBase(pc),a6 ; graphics library address in a6
- lea _custom,a5
- move.l (a0)+,d2 ;start of bitplane1
- move.l (a0),d3 ;start of bitplane2
- move.l (a1)+,d4 ;start of copy bitplane1
- move.l (a1),d5 ;start of copy bitplane2
- jsr _LVOOwnBlitter(a6) ; prepare blitter
- jsr _LVOWaitBlit(a6)
- move.l d2,BLTAPT(a5) ; plane 1
- move.l d4,BLTDPT(a5) ; copy 1
- move.w #0,BLTCON1(a5)
- move.w #$09f0,BLTCON0(a5) ; straight copy
- move.w #modulo,BLTAMOD(a5)
- move.w #modulo,BLTDMOD(a5)
- move.w #$ffff,BLTAFWM(a5)
- move.w #$ffff,BLTALWM(a5)
- move.w #bsize,BLTSIZE(a5)
- jsr _LVOWaitBlit(a6)
- move.l d3,BLTAPT(a5) ; plane 2
- move.l d5,BLTDPT(a5) ; copy 2
- move.w #0,BLTCON1(a5)
- move.w #$09f0,BLTCON0(a5)
- move.w #bsize,BLTSIZE(a5)
- jsr _LVODisownBlitter(a6) ; give it back
- rts
-
- set1: ; set one plane to unity, pointed to by (a0)
- movea.l GraphicsBase(pc),a6 ; graphics library address in a6
- lea _custom,a5
- move.l (a0),d2 ;start of plane
- jsr _LVOOwnBlitter(a6) ; get blitter
- jsr _LVOWaitBlit(a6)
- move.l d2,BLTDPT(a5) ; plane 1
- move.w #0,BLTCON1(a5)
- move.w #$01ff,BLTCON0(a5) ; straight set
- move.w #modulo,BLTDMOD(a5)
- move.w #bsize,BLTSIZE(a5)
- jsr _LVODisownBlitter(a6) ; give it back
- rts
-
- ; subtract storage1 from nonzero lattice sites
- subtract1: movea.l GraphicsBase(pc),a6 ; graphics library address in a6
- jsr _LVOOwnBlitter(a6)
- lea _custom,a5
- move.l bitplane1(pc),d2 ;start of bitplane1
- move.l bitplane2(pc),d3 ;start of bitplane2
- move.l workingplane1(pc),d5 ; start of working plane 1
- move.l workingplane2(pc),d6 ; start of working plane 2
- move.l storage1(pc),d7
- jsr _LVOWaitBlit(a6)
- move.l d5,BLTDPT(a5) ; new first plane to working plane
- move.l d2,BLTAPT(a5) ; old first plane
- move.l d3,BLTBPT(a5) ; old second plane
- move.l d7,BLTCPT(a5) ; subtracting plane
- move.w #0,BLTCON1(a5)
- move.w #$0f58,BLTCON0(a5)
- move.w #modulo,BLTAMOD(a5)
- move.w #modulo,BLTBMOD(a5)
- move.w #modulo,BLTCMOD(a5)
- move.w #modulo,BLTDMOD(a5)
- move.w #$ffff,BLTAFWM(a5)
- move.w #$ffff,BLTALWM(a5)
- move.w #bsize,BLTSIZE(a5)
- jsr _LVOWaitBlit(a6)
- move.l d6,BLTDPT(a5) ; new second plane to working plane
- move.l d2,BLTAPT(a5) ; old first plane
- move.l d3,BLTBPT(a5) ; old second plane
- move.l d7,BLTCPT(a5) ; subtracting plane
- move.w #0,BLTCON1(a5)
- move.w #$0fc4,BLTCON0(a5)
- move.w #bsize,BLTSIZE(a5)
- jsr _LVOWaitBlit(a6)
- move.l d7,BLTDPT(a5) ; new subtracting plane to storage
- move.l d2,BLTAPT(a5) ; old first plane
- move.l d3,BLTBPT(a5) ; old second plane
- move.l d7,BLTCPT(a5) ; subtracting plane
- move.w #0,BLTCON1(a5)
- move.w #$0f02,BLTCON0(a5)
- move.w #bsize,BLTSIZE(a5)
- jsr _LVOWaitBlit(a6)
- move.w DMACONR(a5),control ; save control register for later
- move.l d5,BLTAPT(a5) ; new plane 1
- move.l d2,BLTDPT(a5) ; copy back
- move.w #0,BLTCON1(a5)
- move.w #$09f0,BLTCON0(a5) ; straight copy
- move.w #bsize,BLTSIZE(a5)
- jsr _LVOWaitBlit(a6)
- move.l d6,BLTAPT(a5) ; new plane 2
- move.l d3,BLTDPT(a5) ; copy back
- move.w #0,BLTCON1(a5)
- move.w #$09f0,BLTCON0(a5)
- move.w #bsize,BLTSIZE(a5)
- jsr _LVODisownBlitter(a6) ; give it back
- rts
-
- ; add two lattices, source pointed at by (a0) and dest by (a1)
- addit: movea.l GraphicsBase(pc),a6 ; graphics library address in a6
- lea _custom,a5
- move.l (a1)+,d2 ;start of bitplane1
- move.l (a1)+,d3 ;start of bitplane2
- move.l (a1),d4 ;start of bitplane3
- move.l (a0)+,d5 ;start of adding plane1
- move.l (a0),d6 ;start of adding plane2
- jsr _LVOOwnBlitter(a6) ; prepare to add identity to lattice
- move.l workingplane3(pc),d7 ; for carry
- jsr _LVOWaitBlit(a6)
- move.l d7,BLTDPT(a5) ; carry
- move.l d2,BLTAPT(a5) ; old first plane
- move.l d5,BLTBPT(a5) ; identity1
- move.w #0,BLTCON1(a5)
- move.w #$0dc0,BLTCON0(a5)
- move.w #modulo,BLTAMOD(a5)
- move.w #modulo,BLTBMOD(a5)
- move.w #modulo,BLTCMOD(a5)
- move.w #modulo,BLTDMOD(a5)
- move.w #$ffff,BLTAFWM(a5)
- move.w #$ffff,BLTALWM(a5)
- move.w #bsize,BLTSIZE(a5)
- jsr _LVOWaitBlit(a6)
- move.l d2,BLTDPT(a5) ; new first plane (assume old=0)
- move.l d2,BLTAPT(a5) ; old first plane
- move.l d5,BLTBPT(a5) ; identity1
- move.w #0,BLTCON1(a5)
- move.w #$0d3c,BLTCON0(a5)
- move.w #bsize,BLTSIZE(a5)
- jsr _LVOWaitBlit(a6)
- move.l d4,BLTDPT(a5) ; new third bit
- move.l d3,BLTAPT(a5) ; old second plane
- move.l d6,BLTBPT(a5) ; identity2
- move.l d7,BLTCPT(a5) ; old carry
- move.w #0,BLTCON1(a5)
- move.w #$0fe8,BLTCON0(a5)
- move.w #bsize,BLTSIZE(a5)
- jsr _LVOWaitBlit(a6)
- move.l d3,BLTDPT(a5) ; new second bit
- move.l d3,BLTAPT(a5) ; old second plane
- move.l d6,BLTBPT(a5) ; identity2
- move.l d7,BLTCPT(a5) ; old carry
- move.w #0,BLTCON1(a5)
- move.w #$0f96,BLTCON0(a5)
- move.w #bsize,BLTSIZE(a5)
- jsr _LVODisownBlitter(a6) ; give it back
- rts
-
- credits: ; display introductory comments
- moveq.l #30,d2 ; length of lines
- moveq.l #15,d3 ; number of lines
- moveq.l #25,d4 ; starting row
- movea.l GraphicsBase(pc),a6 ; graphics library address in a6
- lea.l mytext(pc),a3 ; start of text information
- movea.l rastport(pc),a1
- moveq.w #7,d0
- jsr _LVOSetBPen(a6) ; set background pen color
- movea.l rastport(pc),a1
- moveq.w #JAM2,d0
- jsr _LVOSetDrMd(a6) ; set drawing mode
- bra startprint
- myprint: movea.l rastport(pc),a1 ; rastport
- move.l d4,d1 ; starting row
- moveq.l #40,d0 ; starting column
- jsr _LVOMove(a6) ; locate pen
- movea.l rastport(pc),a1 ; rastport
- move.b (a3)+,d0 ; get color
- andi.l #7,d0 ; make sure color valid
- jsr _LVOSetAPen(a6) ; set color
- movea.l rastport(pc),a1 ; rastport
- movea.l a3,a0 ; text location
- move.l d2,d0 ; length of line
- jsr _LVOText(a6) ; print line
- adda.l d2,a3 ; next line
- addi.l #8,d4 ; next row
- startprint: dbf d3,myprint
- bsr waitformessage ; wait for key press
- movea.l GraphicsBase(pc),a6 ; graphics library address in a6
- movea.l rastport(pc),a1
- moveq.l #0,d0
- jsr _LVOSetRast(a6) ; clear screen
- rts
- mytext: ; initial number represents color
- dc.b 2,' '
- dc.b 2,' BlitterSand '
- dc.b 2,' '
- dc.b 6,' by '
- dc.b 2,' '
- dc.b 5,' Michael Creutz '
- dc.b 6,' creutz@bnlux0.bnl.gov '
- dc.b 5,' '
- dc.b 5,'<esc>, q exit '
- dc.b 5,' p pause '
- dc.b 5,' d double modulo 8 '
- dc.b 5,' a pause after relax '
- dc.b 1,' '
- dc.b 1,' Press any key to start '
- dc.b 2,' '
- end
-