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: