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

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; The X numbers are shifted right by 13 before use
; These numbers are in units of 1/8192

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; The upper commented out numbers do this SciAm cover (almost)
; XSTART  equ $fffffa86
; XINC  equ 1

; XSTART  equ ((-1)<<13)
; XINC  equ (1<<9)

; XSTART  equ 0
; XINC  equ (1<<7)

; XSTART  equ ((-2)<<13)
; XINC  equ ((10<<11)/WIDTH)


; The Y numbers are shifted right by 13 before use
; These numbers are in units of 1/8192

; The upper commented out numbers do this SciAm cover
; YSTART  equ $ffffde9a
; YINC  equ 1

; YSTART  equ ((-1)<<13)
; YINC  equ (1<<9)

; YSTART  equ ((-2)<<13)
; YINC  equ (1<<7)

; YSTART  equ ((-19)<<9)
; YINC  equ ((6<<12)/WIDTH)


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; The most important thing in a Mandlebrot program is the inner loop
; The most important thing in a GPU program is to keep as much as possible
; in registers and as much of the rest in internal RAM
; First the inner loop:
; In order to handle both the Mandlebrot and Julia sets we make no assumptions
; about initial conditions.
; The basic loop is: (given xi, yi, cx, cy)
; temp=xi*yi
; sx=xi*xi
; sy=yi*yi
; yi=temp+temp+cy
; xi=sx-sy+cx
; count+=1
; interate until count>maxcount or sx+sy>4

; Note that the nubers used here are 3.13 fixed point
; For a Mandlebrot xi=yi=0 at the start always

; Assume that the following registers are already set up
;       movei   #MAXCNT,maxcnt
;       movei   #FOUR,four

 INBUF  equ $00f03810
; SEMAPHORE equ $0000bff0

 WIDTH  equ 640
 HEIGHT  equ 480
 
 XSTART  equ ((-2)<<13)
 XINC  equ ((10<<11)/WIDTH)
 
 YSTART  equ ((-19)<<9)
 YINC  equ ((6<<12)/WIDTH)

 .gpu

 xi              .equr          R1
 yi              .equr          R2
 cx              .equr          R3
 cy              .equr          R4
 sx              .equr          R5
 sy              .equr          R6
 temp            .equr          R7
 count           .equr          R8
 maxcnt          .equr          R9
 four            .equr          R10
 inloop          .equr          R11
 semaphore       .equr          R12
 inbuf           .equr          R13
 
; A1 = R14
; d2 = R18
; A0 = R19
; d0 = R20
; d1 = R21

 jx              .equr          R15
 jy              .equr          R16
 ypos            .equr          R17
 xpos            .equr          R23
 rinner          .equr          R24
 router          .equr          R25

mandGPU::
 .org     $f03000
; ancien code 68000
; Mandle:
start_mandGPU::
 moveq #0,jx
 moveq #0,jy

 movei #$20000,R14

 movei #YSTART,ypos ; Initialize y position

 movei #HEIGHT-1,R18

 movei #INBUF+8,R19
 
 movei #inner,rinner
 movei #outer,router

 move jx,R20
 store R20,(R19)
 addq #4,R19

 move jy,R20
 store R20,(R19)

outer:
 movei #INBUF+4,R19

 move ypos,R20
 store R20,(R19)

 movei #WIDTH-1,R21
 movei #XSTART,xpos ; Initialize x position

inner:
 movei #INBUF,R19

 move xpos,R20
 store R20,(R19)
; fin 68000

; start_mandGPU::
 movei   #loop,inloop

 movei   #(4<<13),four
 movei   #254,maxcnt

; movei   #$0000bff0,semaphore
 movei   #$00f03810,inbuf

 xor     count,count

 load    (inbuf),cx
 addq    #4,inbuf

 load    (inbuf),cy
 addq    #4,inbuf

 load    (inbuf),xi
 addq    #4,inbuf

 load    (inbuf),yi
 addq    #4,inbuf

loop:
 move    xi,temp
 imult   yi,temp         ; temp=xi*yi

 imult   xi,xi           ; xi=xi*xi

 imult   yi,yi           ; yi=yi*yi

 sharq   #13,xi          ; normalize all mult results
 sharq   #13,temp
 sharq   #13,yi

; The folowing code has been interleaved

 add     temp,temp       ; temp=temp+temp

 move    yi,sy           ; sy=yi*yi

 add     cy,temp         ; temp=temp+temp+cy

 move    xi,sx           ; sx=xi*xi

 move    temp,yi         ; yi=temp+temp+cy

 sub     sy,xi           ; xi=sx-sy

 add     cx,xi           ; xi=sx-sy+cx


 addq    #1,count
 cmp     count,maxcnt

 jr      MI,noloop       ; MI is branch count<maxcnt
; nop      ; optimisation, no need to "nop" here

 add     sx,sy
 cmp     sy,four

 jr      EQ,noloop
 nop
 jump    CC,(inloop)
 nop

noloop:
; store   count,(semaphore)
; re 68000
 storeb count,(R14)
 addq #1,R14


; addq #XINC,xpos
 movei #XINC,R26
 add  R26,xpos
 
 subq #1,R21
 jump PL,(rinner)
 nop

; addq #YINC/2,ypos
; addq #YINC/2,ypos
 movei #YINC,R26
 add  R26,ypos
 
 subq #1,R18
 jump PL,(router)
 nop
 nop
 ; re fin 68000
;BRAK !

;       NOTE: This halts the GPU
 movei   #0,R30
 movei   #$00f02114,R31
 store   R30,(R31)

 nop
 nop
 nop
 nop
 nop
 nop
 nop
 nop
end_mandGPU::