;*** Lines with the Blitter

;Custom chip register

INTENA  = $9A   ;Interrupt enable register (write)
DMACON  = $96   ;DMA-Control register (write)
DMACONR = $2    ;DMA-Control register (read)
COLOR00 = $180  ;Color palette register
VHPOSR  = $6    ;Position (read)

;Copper Register

COP1LC  = $80   ;Addresse of 1st. Copper-List
COP2LC  = $84   ;Addersse of 2nd. Copper-List
COPJMP1 = $88   ;Jump to  Copper-List 1
COPJMP2 = $8a   ;Jump to Copper-List 2

;Bitplane Register

BPLCON0 = $100  ;Bitplane control register 0
BPLCON1 = $102  ;1 (Scroll value)
BPLCON2 = $104  ;2 (Sprite<>Playfield Priority)
BPL1PTH = $0E0  ;Pointer to 1st. bitplane
BPL1PTL = $0E2  ;
BPL1MOD = $108  ;Modulo value for odd Bit-Planes
BPL2MOD = $10A  ;Modulo value for even Bit-Planes
DIWSTRT = $08E  ;Start of screen window
DIWSTOP = $090  ;End of screen window
DDFSTRT = $092  ;Bit-Plane DMA Start
DDFSTOP = $094  ;Bit-Plane DMA Stop

;Blitter Register

BLTCON0 = $40   ;Blitter control register 0 (ShiftA,Usex,LFx)
BLTCON1 = $42   ;Blitter control register 1 (ShiftB,misc. Bits)
BLTCPTH = $48   ;Pointer to source C
BLTCPTL = $4a
BLTBPTH = $4c   ;Pointer to source B
BLTBPTL = $4e 
BLTAPTH = $50   ;Pointer to source A
BLTAPTL = $52
BLTDPTH = $54   ;Pointer to targer data D
BLTDPTL = $56
BLTCMOD = $60   ;Modulo value for source C
BLTBMOD = $62   ;Modulo value for source B
BLTAMOD = $64   ;Modulo value for source A
BLTDMOD = $66   ;Modulo value for target D
BLTSIZE = $58   ;HBlitter window width/height
BLTCDAT = $70   ;Source C data register
BLTBDAT = $72   ;Source B data register
BLTADAT = $74   ;Source A data register
BLTAFWM = $44   ;Mask for first data word from source A
BLTALWM = $46   ;Mask for first data word from source B

;CIA-A Port register A (Mouse key)

CIAAPRA = $bfe001 

;Exec Library Base Offsets

OpenLibrary = -30-522 ;LibName,Version/a1,d0
Forbid      = -30-102
Permit      = -30-108
AllocMem    = -30-168 ;ByteSize,Requirements/d0,d1
FreeMem     = -30-180 ;MemoryBlock,ByteSize/a1,d0

;Graphics Library Base Offsets

OwnBlitter    = -30-426
DisownBlitter = -30-432

;graphics base

StartList = 38

;other Labels

Execbase   = 4
Planesize  = 80*256      ;Bitplane size: 80 Bytes by 256 lines
Planewidth = 80
CLsize     = 3*4         ;The Copper-List contains 3 commands
Chip       = 2           ;allocate Chip-RAM
Clear      = Chip+$10000 ;Clear Chip-RAM first

;*** Initialization ***

Start:

;A;llocate memory for bit plane

 move.l Execbase,a6
 move.l #Planesize,d0    ;Memory requirment for bit plane
 move.l #clear,d1
 jsr    AllocMem(a6)     ;Allocate memory
 move.l d0,Planeadr
 beq    Ende             ;Error! -> End

;Allocate memory for Copper-List

 moveq  #Clsize,d0
 moveq  #chip,d1
 jsr    AllocMem(a6)
 move.l d0,CLadr
 beq    FreePlane        ;Error! -> FreePlane

;Create Copper-List

 move.l d0,a0            ;Address of Copper-List from a0
 move.l Planeadr,d0      ;Address of Bitplane
 move.w #bpl1pth,(a0)+   ;First Copper coommand in RAM
 swap   d0
 move.w d0,(a0)+         ;Hi-Word of Bit plane address in RAM
 move.w #bpl1ptl,(a0)+   ;second command in RAM
 swap   d0
 move.w d0,(a0)+         ;Lo-Word of  Bitplane address in RAM
 move.l #$fffffffe,(a0)  ;End of Copper-List

;Allocate Blitter

 move.l #GRname,a1
 clr.l  d0
 jsr    OpenLibrary(a6)
 move.l a6,-(sp)         ;ExecBase from the Stack
 move.l d0,a6            ;GraphicsBase from a6
 move.l a6,-(sp)         ;and from the Stack
 jsr    OwnBlitter(a6)   ;Take over Blitter

;*** Main program ***

;DMA and Task-Switching off

 move.l 4(sp),a6         ;ExecBase to a6
 jsr    forbid(a6)       ;Task-Switching off
 lea    $dff000,a5
 move.w #$03e0,dmacon(a5)

;Copper initialization

 move.l CLadr,cop1lc(a5)
 clr.w  copjmp1(a5)

;Set color

 move.w #$0000,color00(a5)   ;Black background
 move.w #$0fa0,color00+2(a5) ;Yellow line

;Playfield initialization

 move.w #$2081,diwstrt(a5)   ;20,129
 move.w #$20c1,diwstop(a5)   ;20,449
 move.w #$003c,ddfstrt(a5)   ;Normal  Hires Screen
 move.w #$00d4,ddfstop(a5)
 move.w #%1001001000000000,bplcon0(a5)
 clr.w  bplcon1(a5)
 clr.w  bplcon2(a5)
 clr.w  bpl1mod(a5)
 clr.w  bpl2mod(a5)

;DMA on
 move.w #$83C0,dmacon(a5)

;*** Fill area with Blitter ***

;Part 1:

;Draw filled triangle

;Set starting value

 move.l Planeadr,a0       ;Set constant parameters for
 move.w #Planewidth,a1    ;the LineDraw routine
 move.w #$ffff,a2         ;Mask from $FFFF -> no pattern

;* Draw border lines *

;Line from 320,10 to 600,200
 move.w #320,d0
 move.w #10,d1
 move.w #600,d2
 move.w #200,d3
 bsr    drawline          ;Line draw
;Line from 319,10 to 40,200
 move.w #319,d0
 move.w #10,d1
 move.w #40,d2
 move.w #200,d3
 bsr    drawline          ;draw line
;* Fill area *

;Wait till the blitter draws the last line

Wline: btst #14,dmaconr(a5) ;BBUSY test
 bne   Wline

 add.l  #Planesize-2,a0    ;Address of last word
 move.w #$09f0,bltcon0(a5) ;USEA and D, LFx: D = A
 move.w #$000a,bltcon1(a5) ;Inclusive Fill plus Descending
 move.w #$ffff,bltafwm(a5) ;First- and Last word mask set
 move.w #$ffff,bltalwm(a5)
 move.l a0,bltapth(a5)     ;Address of last word of Bit-
 move.l a0,bltdpth(a5)     ;plane in the Address-Register
 move.w #0,bltamod(a5)     ;no Modulo
 move.w #0,bltdmod(a5)
 move.w #$ff*64+40,bltsize(a5) ;Start Blitter

;Wait for mouse button

end1:   btst #6,ciaapra  ;Mouse key pressed?
 bne.S  end1             ;no  -> continue

;End of Part 1.

;Wait till blitter is ready

Wait:   btst #14,dmaconr(a5)
 bne    Wait

;Activate old Copper-List

 move.l (sp)+,a6       ;Get GraphicsBase from Stack
 move.l StartList(a6),cop1lc(a5)
 clr.w  copjmp1(a5)    ;Activare Startup-Copper-List
 move.w #$8020,dmacon(a5)
 jsr    DisownBlitter(a6)    ;Release blitter
 move.l (sp)+,a6         ;ExecBase from Stack
 jsr    Permit(a6)       ;Task Switching on

;Release memory for Copper-List

 move.l CLadr,a1         ;Set parameter for FreeMem
 moveq  #CLsize,d0
 jsr    FreeMem(a6)      ;Release memory


;Release Bitplane memory

FreePlane:
 move.l Planeadr,a1
 move.l #Planesize,d0
 jsr    FreeMem(a6)

Ende:
 clr.l  d0
 rts                     ;Program end

;Variables

CLadr:    dc.l 0         ;Address of Copper-List
Planeadr: dc.l 0         ;Address of Bitplane

;Constants

GRname: dc.b "graphics.library",0

 align                   ;even

;*** DrawLine Routine ***
;DrawLine draws a line with the Blitter.
;The following parameters are used:
;d0  =  X1   X-coordinate of Start points
;d1  =  Y1   Y-coordinate of Start points
;d2  =  X2   X-coordinate of End points
;d3  =  Y2   Y-coordinate of End points
;a0 must point to the first word of the bitplane
;a1 contains bitplane width in bytes
;a2 word written directly to mask register
;d4 to d6 are used as work registers
 
DrawLine:
 
;Compute the lines starting address

 move.l a1,d4            ;Width in work register
 mulu   d1,d4            ;Y1 * Bytes per line
 moveq  #-$10,d5         ;No leading characters: $f0
 and.w  d0,d5            ;Bottom four bits masked from X1
 lsr.w  #3,d5            ;Remainder divided by  8
 add.w  d5,d4            ;Y1 * Bytes per line + X1/8
 add.l  a0,d4            ;plus starting address of the Bitplane
                         ;d4 now contains the starting address
                         ;of the line
                         ;Compute octants and deltas

 clr.l  d5               ;Clear work register
 sub.w  d1,d3            ;Y2-Y1  DeltaY from D3
 roxl.b #1,d5            ;shift leading char from DeltaY in d5
 tst.w  d3               ;Restore N-Flag
 bge.s  y2gy1            ;When DeltaY positive, goto y2gy1
 neg.w  d3               ;DeltaY invert (if not positive)
y2gy1:
 sub.w  d0,d2            ;X2-X1  DeltaX to D2
 roxl.b #1,d5            ;Move leading char in DeltaX to d5
 tst.w  d2               ;Restore N-Flag
 bge.s  x2gx1            ;When DeltaX positive, goto x2gx1
 neg.w  d2               ;DeltaX invert (if not  positive)
x2gx1:
 move.w d3,d1            ;DeltaY to d1
 sub.w  d2,d1            ;DeltaY-DeltaX
 bge.s  dygdx            ;When DeltaY > DeltaX, goto dygdx
 exg    d2,d3            ;Smaller Delta goto d2
dygdx: roxl.b #1,d5      ;d5 contains results of 3 comparisons
 move.b Octant_table(pc,d5),d5 ;get matching octants
 add.w  d2,d2            ;Smaller Delta * 2
  
;Test, for end of last blitter operation

WBlit:   btst #14,dmaconr(a5);BBUSY-Bit test
 bne.s   WBlit           ;Wait until equal to 0

 move.w d2,bltbmod(a5)   ;2* smaller Delta to BLTBMOD
 sub.w  d3,d2            ;2* smaller Delta - larger Delta
 bge.s  signnl           ;When 2* small delta > large delta to signnl
 or.b   #$40,d5          ;Sign flag set
signnl: move.w d2,bltaptl(a5) ;2*small delta-large delta in BLTAPTL
 sub.w  d3,d2            ;2* smaller Delta - 2* larger Delta
 move.w d2,bltamod(a5)   ;to BLTAMOD

;Initialization other info

 move.w #$8000,bltadat(a5)
 move.w a2,bltbdat(a5)   ;Mask from a2 in BLTBDAT
 move.w #$ffff,bltafwm(a5)
 and.w  #$000f,d0        ;bottom  4 Bits from  X1
 ror.w  #4,d0            ;to START0-3
 or.w   #$0bca,d0        ;USEx and LFx set
 move.w d0,bltcon0(a5)
 move.w d5,bltcon1(a5)   ;Octant in Blitter
 move.l d4,bltcpth(a5)   ;Start address of line to
 move.l d4,bltdpth(a5)   ;BLTCPT and BLTDPT
 move.w a1,bltcmod(a5)   ;Width of Bitplane in both
 move.w a1,bltdmod(a5)   ;Modulo Registers

;BLTSIZE initialization and Blitter start

 lsl.w  #6,d3            ;LENGTH * 64
 addq.w #2,d3            ;plus (Width = 2)
 move.w d3,bltsize(a5)

 rts

;Octant table with LINE =1:
;The octant table contains code values
;for each octant, shifted to the correct position


;Part 2:

;Octant table with SING =1 and LINE =1:

Octant_table:

 dc.b 0 *4+3 ;y1<y2, x1<x2, dx<dy = Okt6 
 dc.b 4 *4+3 ;y1<y2, x1<x2, dx>dy = Okt7
 dc.b 2 *4+3 ;y1<y2, x1>x2, dx<dy = Okt5
 dc.b 5 *4+3 ;y1<y2, x1>x2, dx>dy = Okt4
 dc.b 1 *4+3 ;y1>y2, x1<x2, dx<dy = Okt1
 dc.b 6 *4+3 ;y1>y2, x1<x2, dx>dy = Okt0
 dc.b 3 *4+3 ;y1>y2, x1>x2, dx<dy = Okt2
 dc.b 7 *4+3 ;y1>y2, x1>x2, dx>dy = Okt3

 end


