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: