;FastPlot and FastCircle - another way to set
;dots and circles quickly
;Written by Frank Neumann, 18.03.1988
;(c) KICKSTART 1988
;Labels von exec.library

execbase = 4
OpenLib = -408
CloseLib = -414

;Labels von intuition.library
OpenScreen = -198
CloseScreen = -66


;---------- Code Section
run:

jsr     OpenStuff
cmp.w   #0,d0
bne     exit     ;if screen couldn't be opened, exit immediately

;your own routines should be inserted here...
;here is an example: draw 100 circles with radius from 1 to 100,
;centered in the middle of the screen

move.l  #1,d2   ;radius...

h0:
move.l  #160,d0
move.l  #128,d1
jsr     FastCircle
addq.l  #1,d2
cmp.l   #100,d2
bne     h0

waitleftmouse:    ;wait until left mousebutton is pressed
move.b  $bfe001,d0
and.b   #64,d0
bne     waitleftmouse

jsr     CloseStuff

exit:
rts


;----- Subroutines
OpenStuff:
move.l  execbase,a6
lea     intname,a1
move.l  #0,d0
jsr     OpenLib(a6)
move.l  d0,intbase ; OpenLibrary("intuition.library")

move.l  intbase,a6
lea     newscreen,a0
jsr     OpenScreen(a6)
cmp.l   #0,d0
bne     set2

err0:                 ;screen couldn't be opened; do error-handling
jsr     CloseStuff2   ;close only the libraries that were opened
move.l  #255,d0
rts

set2:
move.l  d0,screen
move.l  screen,a0
move.l  192(a0),a0
move.l  a0,bpnt       ;save bitplane pointer
move.l  #10240,d0     ;amount of bytes that have to be cleared
 
cl1:
move.b  #0,(a0)+
dbra    d0,cl1    ;clear bitplane (320 * 256)

;move.l  screen,a0
;add.l   #192,a0
;move.l  192(a0),d0
;move.l  d0,bpnt   ;here we get the pointer to the (yet only one) bitplane
                   ;from the screen structure and copy it to our pointer


;now we set up some tables for speed-up
lea     adrs,a0
move.l  #255,d0
move.l  bpnt,d1

l1:
move.l  d1,(a0)+
add.l   #40,d1
dbra    d0,l1     ;this is the table for starting addresses of each line

move.w  #0,d0
lea     bytes,a0

l2:
move.w  d0,d1
ror.w   #3,d1
move.b  d1,(a0)+
add.w   #1,d0
cmp.w   #320,d0
bne     l2       ;this was the table for whole byte counts at each position 

move.w  #0,d0    ;this is a flag: d0=0 -> OpenStuff was successful
rts


CloseStuff:
move.l  intbase,a6
move.l  screen,a0
jsr     CloseScreen(a6)

CloseStuff2:
move.l  execbase,a6
move.l  intbase,a1
jsr     CloseLib(a6)

rts

;----- Now, here comes the real fast plot!
;----- it expects:x-coord. in d0, y-coord. in d1...and that's all!

FastPlot:
movem.l d0/d1/a0/a1,-(sp)

cmp.w   #0,d0
bge     t2
jmp     end1    ;boundary check: x low

t2:
cmp.w   #0,d1
bge     t3
jmp     end1    ;y low

t3:
cmp.w   #320,d0
blt     t4
jmp     end1    ;x high

t4:
cmp.w   #256,d1
blt     t5
jmp     end1    ;y high

t5:
lea     adrs,a0
rol.w   #2,d1
move.l  0(a0,d1),a1
lea     bytes,a0
clr.w   d1
move.b  0(a0,d0),d1	
add.l   d1,a1
and.w   #7,d0
eor.b   #7,d0
bset    d0,(a1)

end1:
movem.l (sp)+,d0/d1/a0/a1
rts

;the FastReset subroutine is almost identical to FastPlot with
;the only exception of the BCLR command.

FastReset:
movem.l d0/d1/a0/a1,-(sp)

cmp.w   #0,d0
bge     rt2
jmp     endr1    ;(cf. FastPlot)

rt2:
cmp.w   #0,d1
bge     rt3
jmp     endr1    ;y low

rt3:
cmp.w   #320,d0
blt     rt4
jmp     endr1    ;x high

rt4:
cmp.w   #256,d1
blt     rt5
jmp     endr1    ;y high

rt5:
lea     adrs,a0
rol.w   #2,d1
move.l  0(a0,d1),a1
lea     bytes,a0
clr.w   d1
move.b  0(a0,d0),d1	
add.l   d1,a1
and.w   #7,d0
eor.b   #7,d0
bclr    d0,(a1)

endr1:
movem.l (sp)+,d0/d1/a0/a1
rts


;subroutine to calculate and plot a circle; it expects:
;x-coord. in d0, y-coord. in d1, radius in d2
FastCircle:
movem.l d0/d1/d2/d3,-(sp)
move.w  d0,x
move.w  d1,y
move.w  #0,phi
move.w  d2,x1
move.w  #0,y1

circl1:
move.w  phi,d3
add.w   y1,d3
add.w   y1,d3
addq.w  #1,d3
move.w  d3,phiy

sub.w   x1,d3
sub.w   x1,d3
addq.w  #1,d3
move.w  d3,phixy

move.w  x,d0
add.w   x1,d0
move.w  y,d1
add.w   y1,d1
jsr     FastPlot    ;x+x1,y+y1

move.w  x,d0
sub.w   x1,d0
move.w  y,d1
add.w   y1,d1
jsr     FastPlot    ;x-x1,y+y1

move.w  x,d0
add.w   x1,d0
move.w  y,d1
sub.w   y1,d1
jsr     FastPlot    ;x+x1,y-y1

move.w  x,d0
sub.w   x1,d0
move.w  y,d1
sub.w   y1,d1
jsr     FastPlot    ;x-x1,y-y1

move.w  x,d0
add.w   y1,d0
move.w  y,d1
add.w   x1,d1
jsr     FastPlot    ;x+y1,y+x1

move.w  x,d0
sub.w   y1,d0
move.w  y,d1
add.w   x1,d1
jsr     FastPlot    ;x-y1,y+x1

move.w  x,d0
add.w   y1,d0
move.w  y,d1
sub.w   x1,d1
jsr     FastPlot    ;x+y1,y-x1

move.w  x,d0
sub.w   y1,d0
move.w  y,d1
sub.w   x1,d1
jsr     FastPlot    ;x-y1,y-x1

move.w  phiy,d0
move.w  d0,phi
addq.w  #1,y1
move.w  phixy,d0
jsr     ToAbs
move.w  d0,d1
move.w  phiy,d0
jsr     ToAbs
cmp.w   d0,d1
bge     circl3
move.w  phixy,d0
move.w  d0,phi
subq.w  #1,x1

circl3:
move.w  y1,d0
cmp.w   x1,d0
ble     circl1
movem.l (sp)+,d0/d1/d2/d3
rts


;subroutine that returns the absolute value of a word argument
ToAbs:
cmp.w   #0,d0
bmi     ToA1
rts
ToA1:
neg.w   d0
rts


;---------- Data Section
intname: dc.b "intuition.library",0,0
even
intbase: blk.l 1

newscreen:
dc.w 0        ;LeftEdge
dc.w 0        ;TopEdge
dc.w 320      ;Width
dc.w 256      ;Height
dc.w 1        ;Depth
dc.b 0        ;DetailPen
dc.b 1        ;BlockPen 
dc.w 0        ;ViewModes...LORES
dc.w 15       ;Type :here we use CUSTOMSCREEN
dc.l 0        ;Font
dc.l 0        ;Title
dc.l 0        ;Gadgets
dc.l 0        ;BitMap

screen: blk.l 1     ;pointer to screen structure
bpnt:   blk.l 1     ;pointer to the bitplane
adrs:   blk.l 256   ;auxiliary arrays
bytes:  blk.b 320   ; - " -
phi:    blk.w 1     ;register for circle calculations
phiy:   blk.w 1     ; - " -
phixy:  blk.w 1     ; - " -
x1:     blk.w 1     ; - " -
y1:     blk.w 1     ; - " -
x:      blk.w 1     ; - " -
y:      blk.w 1     ; - " -
