home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
618a.lha
/
GoLD
/
GoLDSub.a
< prev
Wrap
Text File
|
1992-02-02
|
14KB
|
433 lines
;****************************************************************************
;
; GoLDSub - Routinen für 'Game of Life - Duo'
;
;****************************************************************************
;
; void SetCell(bmap,x,y,col)
;
; Sets the cell at coordinates (x,y) to the color 'col'.
; Here x and y are not pixel-coordinates but 'cell-coordinates', i.e.
; the position of the cell is at window position (4x,3y).
; The BitMap is assumed to have 2 Planes and there is no check for
; legal coordinate values.
;
;****************************************************************************
;
; void ScanAgar(Agar,AuxAgar,CellTrans,xsize,ysize,cs)
;
; From 'Agar' the new types of the cells which change in the current
; cycle are computed and stored in 'AuxAgar'.
; 'Agar' and 'AuxAgar' are character arrays of 'xsize' columns and
; 'ysize' lines. 'CellTrans' is an array with 'cs' columns and as many
; lines as there are different types of cells. 'CellTrans[i][j]' contains
; the type of the cell into which a cell of type i has to be changed when
; the sum of the eight neighbouring cells yields j.
;
;****************************************************************************
;
; void ChangeAgar(bm,Agar,AuxAgar,xsize,ysize,xoffset,yoffset)
;
; The new types of the cells which change in the current cycle are read
; from 'AuxAgar' and used to update 'Agar' and the display.
; (xoffset,yoffset) are the cell-coordinates of the upper left corner
; of the output area in the BitMat 'bm'.
;
;****************************************************************************
;
; void DisplayAgar(bm,Agar,xsize,ysize,xoffset,yoffset)
;
; The 'Agar' of size 'xsize' x 'ysize' is displayed in the BitMap 'bm' at
; cell-coordinates (xoffset,yoffset).
;
;****************************************************************************
;
; void CountCells(Agar,BluSum,RedSum,Len)
;
; The number of blue and red cells in 'Agar' (which is interpreted as a
; character string of length 'Len + 1') is returned in '*BluSum' and
; '*RedSum', resp.
;
;****************************************************************************
;
; Created by
; Andreas Neubacher
;
; Hausleitnerweg 26
; 4020 Linz
; Austria
;
; E-mail: aneubach@risc.uni-linz.ac.at (Internet)
; k318577@alijku11 (Bitnet)
;
;****************************************************************************
;
; Copyright notice:
; I don't claim any copyright and put this code into the public domain.
;
;****************************************************************************
;
; 92-01-19 AN : Finished release version
;
;****************************************************************************
section GoLDSub,code
;****************************************************************************
xdef _SetCell ; C entry : void SetCell(bmap, x, y, col);
; struct BitMap *bmap;
; short x,y,col;
xdef SetCell ; Assembler entry : A0 D0 D0 D1
; hi lo
_SetCell
movea.l 4(SP),A0
move.l 8(SP),D0
swap D0
move.w 14(SP),D0
move.l 16(SP),D1
; Register usage
;
; D0 ... x/y (hi-/lo-word), mask for nibble set/clear
; D1 ... col; offset for the byte, which contains the second line of the cell
; D2 ... offset for the byte, which contains the first line of the cell
; A0 ... pointer to the BitMap
; A1 ... pointer to the Bitplane
SetCell
move.l D2,-(SP)
swap D1
move.w (A0),D1 ; D1 := bmap->BytesPerRow
move.w D1,D2
add.w D2,D2
add.w D1,D2 ; D2 := 3 * bmap->BytesPerRow
mulu.w D0,D2 ; * y
swap D0
lsr.w #1,D0
bcs ELSE1 ; IF x even THEN
add.w D0,D2 ; D2 := D2 + x/2
move.l #$008F0070,D0 ; D0 := maske for high nibble
bra ENDIF1
ELSE1 ; ELSE
add.w D0,D2 ; D2 := D2 + x/2
move.l #$00F80007,D0 ; D0 := maske for low nibble
ENDIF1 ; ENDIF
add.w D2,D1 ; D1 := D2 + bmap->BytesPerRow
movea.l 8(A0),A1 ; A1 points to first Bitplane
btst #16,D1
beq ELSE2 ; IF col odd THEN
or.b D0,(A1,D2.w) ; set cell
or.b D0,(A1,D1.w) ; set cell
bra ENDIF2
ELSE2 ; ELSE
swap D0
and.b D0,(A1,D2.w) ; clear cell
and.b D0,(A1,D1.w) ; clear cell
swap D0
ENDIF2 ; ENDIF
movea.l 12(A0),A1 ; A1 points to second Bitplane
btst #17,D1
beq ELSE3 ; IF col > 1 THEN
or.b D0,(A1,D2.w) ; set cell
or.b D0,(A1,D1.w) ; set cell
bra ENDIF3
ELSE3 ; ELSE
swap D0
and.b D0,(A1,D2.w) ; clear cell
and.b D0,(A1,D1.w) ; clear cell
ENDIF3 ; ENDIF
move.l (SP)+,D2
rts
;****************************************************************************
xdef _ScanAgar ; C entry : void ScanAgar(a, aa, ct, xs, ys, cs);
; char *a,*aa,*ct;
; short xs,ys,cs;
xdef ScanAgar ; Assembler entry : A0 A1 A2 D0 D1 D2
_ScanAgar
movea.l 4(SP),A0
movea.l 8(SP),A1
movea.l 12(SP),A2
move.l 16(SP),D0
move.l 20(SP),D1
move.l 24(SP),D2
; Register usage
;
; D0 ... 'xs'
; D1 ... 'ys', row counter
; D2 ... 'cs', sum of cell values
; D3 ... column counter
; A0 ... 'a'
; A1 ... 'aa'
; A2 ... 'ct'
; A3/A4 ... auxiliary pointers into 'a'
; A5/A6 ... pointers to second/third line of matrix 'ct'
ScanAgar
movem.l D3/A3-A6,-(SP)
movea.l A0,A3
adda.w D0,A3
movea.l A3,A4
adda.w D0,A4
adda.w D0,A1
addq.l #1,A1
movea.l A2,A5
adda.w D2,A5
movea.l A5,A6
adda.w D2,A6
moveq #0,D2
subq.w #3,D0 ; xs := xs - 3
subq.w #3,D1 ; ys := ys - 3
REPEAT1 ; REPEAT
move.w D0,D3 ; D3 := xs
REPEAT2 ; REPEAT
move.b (A0)+,D2 ; D2 := sum over
add.b (A0),D2 ; the eight
add.b 1(A0),D2 ; neighbours
add.b (A3)+,D2 ; of the
add.b 1(A3),D2 ; current
add.b (A4)+,D2 ; cell
add.b (A4),D2 ;
add.b 1(A4),D2 ;
btst #0,(A3)
beq ELSE4 ; IF current cell = 1 THEN
move.b (A5,D2.w),(A1)+ ; curr. aux. cell := ct[1][D2]
bra ENDIF4
ELSE4 btst #1,(A3)
bne ELSE5 ; ELSE IF current cell = 0 THEN
move.b (A2,D2.w),(A1)+ ; curr. aux. cell := ct[0][D2]
bra ENDIF4
ELSE5 ; ELSE
move.b (A6,D2.w),(A1)+ ; curr. aux. cell := ct[2][D2]
ENDIF4 ; ENDIF
dbf D3,REPEAT2 ; UNTIL row finished
addq.l #2,A0
addq.l #2,A1 ; next
addq.l #2,A3 ; row
addq.l #2,A4
dbf D1,REPEAT1 ; UNTIL all rows finished
movem.l (SP)+,D3/A3-A6
rts
;****************************************************************************
xdef _ChangeAgar ; C entry : void ChangeAgar(bm, a, aa, xs, ys, xo, yo);
; struct BitMap *bm;
; char *a,*aa;
; short xs,ys,xo,yo;
xdef ChangeAgar ; Assembler entry : A0 A1 A2 D0 D1 D2 D2
; hi lo
_ChangeAgar
movea.l 4(SP),A0
movea.l 8(SP),A1
movea.l 12(SP),A2
move.l 16(SP),D0
move.l 20(SP),D1
move.l 24(SP),D2
swap D2
move.w 30(SP),D2
; Register usage
;
; D0 ... x/y (hi-/lo-word)
; D1 ... value of current cell; color
; D2 ... x-offset
; D3 ... column counter
; D4 ... row counter
; D5 ... 'xs'
; D6 ... y-offset
; A0 ... 'bm'
; A2 ... pointer to current cell in 'aa'
; A3 ... pointer to current cell in 'a'
ChangeAgar
movem.l D2-D6/A3,-(SP)
movea.l A1,A3
add.w D0,A2
addq.l #1,A2
add.w D0,A3
addq.l #1,A3
subq.w #3,D0
subq.w #3,D1
move.w D1,D4
move.w D2,D6
add.w D1,D6
swap D2
add.w D0,D2
move.w D0,D5
REPEAT3 ; REPEAT
move.w D5,D3
REPEAT4 ; REPEAT
move.b (A2),D1 ; D1 := current cell in 'aa'
bne ELSE6 ; IF D1 = 0 THEN
move.b D1,(A3) ; current cell in 'a' := D1
moveq #2,D1 ; color := 2
bra ENDIF7 ; GOTO ENDIF7
ELSE6 cmp.b #2,D1
bgt ENDIF6 ; ELSE IF D1 < 3 THEN
beq ELSE7 ; IF D1 = 1 THEN
move.b D1,(A3) ; current cell in 'a' := D1
moveq #0,D1 ; color := 0
bra ENDIF7 ; ELSE
ELSE7 move.b D1,(A3) ; current cell in 'a' := D1
moveq #1,D1 ; color := 1
ENDIF7 ; ENDIF
move.w D2,D0
sub.w D3,D0
swap D0
move.w D6,D0
sub.w D4,D0
jsr SetCell ; SetCell(bm,D2-D3,D6-D4,color)
ENDIF6 ; ENDIF
addq.l #1,A2 ; next
addq.l #1,A3 ; cell
dbf D3,REPEAT4 ; UNTIL row finished
addq.l #2,A2 ; next
addq.l #2,A3 ; row
dbf D4,REPEAT3 ; UNTIL all rows finished
movem.l (SP)+,D2-D6/A3
rts
;****************************************************************************
xdef _DisplayAgar ; C entry : void DisplayAgar(bm, a, xs, ys, xo, yo);
; struct BitMap *bm;
; char *a;
; short xs,ys,xo,yo;
xdef DisplayAgar ; Assembler entry : A0 A2 D0 D1 D2 D2
; hi lo
_DisplayAgar
movea.l 4(SP),A0
movea.l 8(SP),A2
move.l 12(SP),D0
move.l 16(SP),D1
move.l 20(SP),D2
swap D2
move.w 26(SP),D2
; Register usage
;
; D0 ... x/y (hi-/lo-word)
; D1 ... value of current cell; color
; D2 ... x-offset
; D3 ... y-offset
; D4 ... 'xs'
; D5 ... column counter
; D6 ... line counter
; A0 ... 'bm'
; A2 ... pointer to current cell in 'a'
DisplayAgar
movem.l D3-D6,-(SP)
add.w D0,A2
addq.l #1,A2
subq.w #3,D0
subq.w #3,D1
move.w D1,D3
add.w D2,D3
move.w D1,D6
swap D2
add.w D0,D2
move.w D0,D4
REPEAT5 ; REPEAT
move.w D4,D5
REPEAT6 ; REPEAT
move.b (A2)+,D1 ; D1 := current cell in 'a'
bne ELSE8 ; IF D1 = 0 THEN
moveq #2,D1 ; color := 2
bra ENDIF8 ;
ELSE8 btst #0,D1
beq ELSE9 ; ELSE IF D1 = 1 THEN
moveq #0,D1 ; color := 0
bra ENDIF8 ; ELSE
ELSE9 moveq #1,D1 ; color := 1
ENDIF8 ; ENDIF
move.w D2,D0
sub.w D5,D0
swap D0
move.w D3,D0
sub.w D6,D0
jsr SetCell ; SetCell(bm,D2-D5,D3-D6,color)
dbf D5,REPEAT6 ; UNTIL row finished
addq.l #2,A2 ; next row
dbf D6,REPEAT5 ; UNTIL all rows finished
movem.l (SP)+,D3-D6
rts
;****************************************************************************
xdef _CountCells ; C entry : void CountCells(a, bluc, redc, len);
; char *a;
; short *redc,*bluc;
; unsigned short len;
xdef CountCells ; Assembler entry : A0 A1 A2 D0
_CountCells
movea.l 4(SP),A0
movea.l 8(SP),A1
movea.l 12(SP),A2
move.l 16(SP),D0
; Register usage
;
; D0 ... cell counter
; D1 ... counter for blue cells
; D2 ... counter for red cells
; D3 ... current cell
; A0 ... pointer to current cell
; A1 ... 'bluc'
; A2 ... 'redc'
CountCells
movem.l D2/D3,-(SP)
moveq.l #0,D1
move.l D1,D2
REPEAT7 ; REPEAT
move.b (A0)+,D3 ; get current cell
bne ELSE10 ; IF cell = 0 THEN
addq.w #1,D1 ; blue cell
bra ENDIF10
ELSE10
btst #0,D3
bne ENDIF10 ; ELSE IF cell = 2 THEN
addq.w #1,D2 ; red cell
ENDIF10 ; ENDIF
dbf D0,REPEAT7 ; UNTIL all cells finished
move.w D1,(A1)
move.w D2,(A2)
movem.l (SP)+,D2/D3
rts
END