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::