File: CALCMAND.S - Tab length: 1 2 4 8 - Lines: on off - No wrap: on off

001: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
002: ; The X numbers are shifted right by 13 before use
003: ; These numbers are in units of 1/8192
004: 
005: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
006: ; The upper commented out numbers do this SciAm cover (almost)
007: ;       XSTART          equ     $fffffa86
008: ;       XINC            equ     1
009: 
010: ;       XSTART          equ     ((-1)<<13)
011: ;       XINC            equ     (1<<9)
012: 
013: ;       XSTART          equ     0
014: ;       XINC            equ     (1<<7)
015: 
016: ;       XSTART          equ     ((-2)<<13)
017: ;       XINC            equ     ((10<<11)/WIDTH)
018: 
019: 
020: ; The Y numbers are shifted right by 13 before use
021: ; These numbers are in units of 1/8192
022: 
023: ; The upper commented out numbers do this SciAm cover
024: ;       YSTART          equ     $ffffde9a      
025: ;       YINC            equ     1
026: 
027: ;       YSTART          equ     ((-1)<<13)
028: ;       YINC            equ     (1<<9)
029: 
030: ;       YSTART          equ     ((-2)<<13)
031: ;       YINC            equ     (1<<7)
032: 
033: ;       YSTART          equ     ((-19)<<9)
034: ;       YINC            equ     ((6<<12)/WIDTH)
035: 
036: 
037: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
038: ; The most important thing in a Mandlebrot program is the inner loop
039: ; The most important thing in a GPU program is to keep as much as possible
040: ; in registers and as much of the rest in internal RAM
041: ; First the inner loop:
042: ; In order to handle both the Mandlebrot and Julia sets we make no assumptions
043: ; about initial conditions.
044: ; The basic loop is: (given xi, yi, cx, cy)
045: ; temp=xi*yi
046: ; sx=xi*xi
047: ; sy=yi*yi
048: ; yi=temp+temp+cy
049: ; xi=sx-sy+cx
050: ; count+=1
051: ; interate until count>maxcount or sx+sy>4
052: 
053: ; Note that the nubers used here are 3.13 fixed point
054: ; For a Mandlebrot xi=yi=0 at the start always
055: 
056: ; Assume that the following registers are already set up
057: ;       movei   #MAXCNT,maxcnt
058: ;       movei   #FOUR,four
059: 
060:         INBUF           equ     $00f03810
061: ;       SEMAPHORE       equ     $0000bff0
062: 
063:         WIDTH           equ     640
064:         HEIGHT          equ     480
065:        
066:         XSTART          equ     ((-2)<<13)
067:         XINC            equ     ((10<<11)/WIDTH)
068:        
069:         YSTART          equ     ((-19)<<9)
070:         YINC            equ     ((6<<12)/WIDTH)
071: 
072:         .gpu
073: 
074:         xi              .equr          R1
075:         yi              .equr          R2
076:         cx              .equr          R3
077:         cy              .equr          R4
078:         sx              .equr          R5
079:         sy              .equr          R6
080:         temp            .equr          R7
081:         count           .equr          R8
082:         maxcnt          .equr          R9
083:         four            .equr          R10
084:         inloop          .equr          R11
085:         semaphore       .equr          R12
086:         inbuf           .equr          R13
087:        
088: ; A1 = R14
089: ; d2 = R18
090: ; A0 = R19
091: ; d0 = R20
092: ; d1 = R21
093: 
094:         jx              .equr          R15
095:         jy              .equr          R16
096:         ypos            .equr          R17
097:         xpos            .equr          R23
098:         rinner          .equr          R24
099:         router          .equr          R25
100: 
101: mandGPU::
102:         .org     $f03000
103: ; ancien code 68000    
104: ; Mandle:
105: start_mandGPU::
106:         moveq   #0,jx
107:         moveq   #0,jy
108: 
109:         movei   #$20000,R14
110: 
111:         movei   #YSTART,ypos    ; Initialize y position
112: 
113:         movei   #HEIGHT-1,R18
114: 
115:         movei   #INBUF+8,R19
116:        
117:         movei   #inner,rinner
118:         movei   #outer,router
119: 
120:         move    jx,R20
121:         store   R20,(R19)
122:         addq    #4,R19
123: 
124:         move    jy,R20
125:         store   R20,(R19)
126: 
127: outer:
128:         movei   #INBUF+4,R19
129: 
130:         move    ypos,R20
131:         store   R20,(R19)
132: 
133:         movei   #WIDTH-1,R21
134:         movei   #XSTART,xpos    ; Initialize x position
135: 
136: inner:
137:         movei   #INBUF,R19
138: 
139:         move    xpos,R20
140:         store   R20,(R19)
141: ; fin 68000
142: 
143: ; start_mandGPU::
144:         movei   #loop,inloop
145: 
146:         movei   #(4<<13),four
147:         movei   #254,maxcnt
148: 
149: ;       movei   #$0000bff0,semaphore
150:         movei   #$00f03810,inbuf
151: 
152:         xor     count,count
153: 
154:         load    (inbuf),cx
155:         addq    #4,inbuf
156: 
157:         load    (inbuf),cy
158:         addq    #4,inbuf
159: 
160:         load    (inbuf),xi
161:         addq    #4,inbuf
162: 
163:         load    (inbuf),yi
164:         addq    #4,inbuf
165: 
166: loop:
167:         move    xi,temp
168:         imult   yi,temp         ; temp=xi*yi
169: 
170:         imult   xi,xi           ; xi=xi*xi
171: 
172:         imult   yi,yi           ; yi=yi*yi
173: 
174:         sharq   #13,xi          ; normalize all mult results
175:         sharq   #13,temp
176:         sharq   #13,yi
177: 
178: ; The folowing code has been interleaved
179: 
180:         add     temp,temp       ; temp=temp+temp
181: 
182:         move    yi,sy           ; sy=yi*yi
183: 
184:         add     cy,temp         ; temp=temp+temp+cy
185: 
186:         move    xi,sx           ; sx=xi*xi
187: 
188:         move    temp,yi         ; yi=temp+temp+cy
189: 
190:         sub     sy,xi           ; xi=sx-sy
191: 
192:         add     cx,xi           ; xi=sx-sy+cx
193: 
194: 
195:         addq    #1,count
196:         cmp     count,maxcnt
197: 
198:         jr      MI,noloop       ; MI is branch count<maxcnt
199: ;       nop                                             ; optimisation, no need to "nop" here
200: 
201:         add     sx,sy
202:         cmp     sy,four
203: 
204:         jr      EQ,noloop
205:         nop
206:         jump    CC,(inloop)
207:         nop
208: 
209: noloop:
210: ;       store   count,(semaphore)
211: ; re 68000
212:         storeb  count,(R14)
213:         addq    #1,R14
214: 
215: 
216: ;       addq    #XINC,xpos
217:         movei   #XINC,R26
218:         add             R26,xpos
219:        
220:         subq    #1,R21
221:         jump    PL,(rinner)
222:         nop
223: 
224: ;       addq    #YINC/2,ypos
225: ;       addq    #YINC/2,ypos
226:         movei   #YINC,R26
227:         add             R26,ypos
228:        
229:         subq    #1,R18
230:         jump    PL,(router)
231:         nop
232:         nop
233:         ; re fin 68000  
234: ;BRAK !
235: 
236: ;       NOTE: This halts the GPU
237:         movei   #0,R30
238:         movei   #$00f02114,R31
239:         store   R30,(R31)
240: 
241:         nop
242:         nop
243:         nop
244:         nop
245:         nop
246:         nop
247:         nop
248:         nop
249: end_mandGPU::
250: