 
* Graphic Brushes read from DPaint2 take the following form... *
* 
*   DC.B   'FORM',0,0
*   DC.W   GREND-GRST      Length in bytes of remaining data
*GRST   DC.B   'ILBMBMHD',0,0
*   DC.W   BMHDEND-BMHDST
*BMHDST   DC.W   WIDTH,DEPTH      Pixels wide, pixels deep
*   DC.W   0,0,$502 ???
*   DC.W   COMPFLAG      =$100 if compressed
*   DC.W   0,$A0B  ????
*   DC.W   SCRWID,SCRDEP      Screen width/depth in pixels
*BMHDEND
*   DC.B   'CMAP',0,0
*   DC.W   CMAPEND-CMAPST   
*CMPAST   DC.B   $00,$00,$00   Colour register byte map
*   DC.B   $E0,$C0,$A0   Red, Green, Blue
*   DC.B   $00,$00,$00
*   DC.B   $00,$00,$00
*   DC.B   $00,$00,$00
*   DC.B   $00,$00,$00
*   DC.B   $00,$00,$00
*   DC.B   $00,$00,$00
*   DC.B   $00,$00,$00
*   DC.B   $00,$00,$00
*   DC.B   $00,$00,$00
*   DC.B   $00,$00,$00
*   DC.B   $00,$00,$00
*   DC.B   $00,$00,$00
*   DC.B   $00,$00,$00
*   DC.B   $00,$00,$00
*   DC.B   $00,$00,$00
*   DC.B   $00,$00,$00
*   DC.B   $00,$00,$00
*   DC.B   $00,$00,$00
*   DC.B   $00,$00,$00
*   DC.B   $00,$00,$00
*   DC.B   $00,$00,$00
*   DC.B   $00,$00,$00
*   DC.B   $00,$00,$00
*   DC.B   $00,$00,$00
*   DC.B   $00,$00,$00
*   DC.B   $00,$00,$00
*   DC.B   $00,$00,$00
*   DC.B   $00,$00,$00
*   DC.B   $00,$00,$00
*   DC.B   $00,$00,$00
*CMAPEND
*   DC.B   'GRAB',0,0
*   DC.W   GRABEND-GRABST
*GRABST   
*   DC.W   WIDTH/2,DEPTH/2
*GRABEND
*   DC.B   'CRNG',0,0
*   DC.W   CRE1-CRS1
*CRS1   DC.W   0,$AAA,$1,$141F   ???
*CRE1
*   DC.B   'CRNG',0,0
*   DC.W   CRE2-CRS2
*CRS2   DC.W   0,$AAA,$1,$307   ???
*CRE2
*   DC.B   'CRNG',0,0
*   DC.W   CRE3-CRS3
*CRS3   DC.W   0,$AAA,$1,0   ???
*CRE3
*   DC.B   'CRNG',0,0
*   DC.W   CRE4-CRS4
*CRS4   DC.W   0,$AAA,$1,0   ???
*CRE4
*   DC.B   'BODY',0,0
*   DC.W   BODEND-BODST
*BODST            The bit image follows here
*         Taking the form....
*      Line1
*         Bplane 1
*   DC.W         Column1,Column2...Columnx
*         Bplane 2
*   DC.W         Col.....................x
*         Bplane 5
*      LineX
*BODEND

MAT_NAME   DC.B   'MATRIX',0,0

      CNOP   0,4

FILE_INFO_BLOCK
      DC.L   0,0
BRUSH_NAME   DS.B   108
      DC.L   0,0,0,0
      DS.B   256
      
BRNAME      DC.B   'BRUSH',0

DISKNAME   DC.B   'DF1:',0,0

      CNOP   0,4

* Load in all the brushes whose file names are above, covert them,
* and store them in order in the data area 'GRAPHIC'

GET_GRAPHICS

   CALL   Output,DISCBASE
   move.l   d0,d4         d4=input handle

* and print a message

   
   MOVE.L   DISKNAME,D1
   MOVE.L   #ACCESS_READ,D2
   CALL   Lock,DISCBASE
   LEA   V,A5
   MOVE.L   D0,LOCK-V(A5)
   BEQ   LD_LEND

   MOVE.L   D0,D1
   MOVE.L   #FILE_INFO_BLOCK,D2
   CALL   Examine,DISCBASE   
   LEA   GRAPHIC,A6   

IS_IT_BRUSH

   LEA   V,A5
   TST.L   D0
   BEQ   LD_LEND
   LEA   BRUSH_NAME,A0
   CLR.L   D3
BR_DOT
   MOVE.B   (A0)+,D0
   ADDQ   #1,D3
   TST.B   D0
   BEQ   LD_BRUSH_NEXT
   CMP.B   #'.',D0
   BNE   BR_DOT

   LEA   BRNAME,A1
BR_T_LOOP
   MOVE.B   (A0)+,D0
   ADDQ   #1,D3
   AND.B   #%11011111,D0   Convert to upper case
   CMP.B   (A1)+,D0
   BNE   LD_BRUSH_NEXT
   TST.B   D0
   BNE   BR_T_LOOP

   move.l   d4,d1         file handle
   move.l   #BRUSH_NAME,d2      address of message
   CALL   Write,DISCBASE      and send it

   LEA   BRUSH_NAME,A0
   
GETGR_L
   BSR   LOAD_BRUSH

LD_BRUSH_NEXT

   LEA   V,A5
   MOVE.L   LOCK-V(A5),D1
   MOVE.L   #FILE_INFO_BLOCK,D2
   CALL   ExNext,DISCBASE
   BRA   IS_IT_BRUSH

LD_LEND
   RTS
      
* Open the file 'MATRIX' for reading, return 0 in d0 if error *

OPEN_MATRIX

   MOVE.L   #MAT_NAME,D1
   MOVE.L   #1005,D2
   CALL   Open,DISCBASE
   LEA   V,A5
   MOVE.L   D0,FILE-V(A5)
   BEQ   MATNOTX
   MOVE.L   D0,D1
   MOVE.L   #MATRIX,D2
   MOVE.L   #WIDTH*HEIGHT*2,D3
   CALL   Read,DISCBASE   
   LEA   V,A5
   MOVE.L   FILE-V(A5),D1
   CALL   Close,DISCBASE
   LEA   V,A5
   MOVE   #1,D0
MATNOTX
   RTS

* Open the file 'MATRIX' for writing *
   
WRITE_MATRIX
   
   MOVE.L   #MAT_NAME,D1
   CALL   DeleteFile,DISCBASE

   MOVE.L   #MAT_NAME,D1
   MOVE.L   #1006,D2
   CALL   Open,DISCBASE
   LEA   V,A5
   MOVE.L   D0,FILE-V(A5)
   BEQ   W_ERROR
   MOVE.L   D0,D1
   MOVE.L   #MATRIX,D2
   MOVE.L   #WIDTH*HEIGHT*2,D3
   CALL   Write,DISCBASE
   MOVE.L   D0,-(SP)
   LEA   V,A5
   MOVE.L   FILE-V(A5),D1
   CALL   Close,DISCBASE
   MOVE.L   (SP)+,D0
   CMP.L   #$FFFFFFFF,D0
   BEQ   W_ERROR
   RTS
   
W_ERROR
   LEA   CUSTOM,A6
   MOVE.L   #$291,COLOUR0(A6)
   RTS
      
* Load a brush file at DISC_BUFFER

LOAD_BRUSH

   MOVE.L   A0,D1
   MOVE.L   #1005,D2
   CALL   Open,DISCBASE
   LEA   V,A5
   MOVE.L   D0,FILE-V(A5)
   BEQ   LERROR
   MOVE.L   D0,D1
   MOVE.L   #DISC_BUFFER,D2
   MOVE.L   #$8000,D3
   CALL   Read,DISCBASE

   LEA   V,A5
   MOVE.L   FILE-V(A5),D1
   CALL   Close,DISCBASE
   
* Now follows a routine to take the brush data at DISC_BUFFER
* and get the 'compressed' flag, x size, y size and point at data block
 
BRUSH_TEST

   LEA   DISC_BUFFER,A1
   BSR   WORD_TO_BUF
   CMP.L   #'FORM',WORD_BUF
   BNE   GTERR
   ADD.L   #2,A1
   BSR   WORD_TO_BUF
   MOVE   (A1)+,D0
   MOVE   (A1)+,D1      Pixels wide in D1
   MOVE   (A1)+,D2      Pixels deep in D2 
   ADD   #6,A1
   MOVE   (A1)+,D7      Compression flag in D7   
   SUBQ   #$8,D0
   ADD   D0,A1
BTEST1   BSR   GET_AND_TEST
   BEQ   CONVERT_BRUSH
   ADD.W   (A1)+,A1
   BRA   BTEST1
   
* Convert a DPaint2 brush BODY to 5 graphic blocks *
* A1 points at BODY-2 A0 at destination for data   *
* D1 is pixels wide D2 is pixels deep         *

CONVERT_BRUSH

   MOVE.L   A6,A0
   LEA   V,A5
   MOVE   D2,GDEPTH-V(A5)
   ADD.L   #2,A1
   MOVE   D1,D3
   MOVE   D3,D4
   LSR   #3,D3
   AND   #$F,D4
   BNE   CB1
   SUBQ   #1,D3
CB1   MOVE   D3,D4
   AND   #$FFFE,D4
   ADDQ   #2,D4
   MOVE   D4,GWIDTH-V(A5)
   MULU   D2,D4
   MOVE.L   A0,A2
   ADD   D4,A2
   MOVE.L   A2,A3
   ADD   D4,A3
   MOVE.L   A3,A4
   ADD   D4,A4
   MOVE.L   A4,A5
   ADD   D4,A5
   LSR   #1,D3
   MOVE   D3,D5
   TST   D7
   BNE COMPRESSED
NC20   MOVE.W   (A1)+,(A0)+
   DBRA   D3,NC20
   MOVE   D5,D3
NC21   MOVE.W   (A1)+,(A2)+
   DBRA   D3,NC21
   MOVE   D5,D3
NC22   MOVE.W   (A1)+,(A3)+
   DBRA   D3,NC22
   MOVE   D5,D3
NC23   MOVE.W   (A1)+,(A4)+
   DBRA   D3,NC23
   MOVE   D5,D3
NC24   MOVE.W   (A1)+,(A5)+
   DBRA   D3,NC24
   MOVE   D5,D3
   SUBQ   #1,D2
   BNE   NC20
   MOVE.L   A5,A6
   RTS

* Move the Colour Data from DISC_BUFFER into the hardware colour register *

SET_COLOURS
   
   LEA   DISC_BUFFER,A1
   BSR   WORD_TO_BUF
   ADDQ   #2,A1
   LEA   COLOUR0+CUSTOM,A0
   MOVE   #$1F,D0
GET_CMAP
   BSR   WORD_TO_BUF   
   CMP.L   #'CMAP',WORD_BUF
   BEQ   START_LOAD
   ADD.W   (A1)+,A1
   BRA   GET_CMAP
START_LOAD
   ADDQ   #2,A1
COL_LOOP   
   CLR   D1
   MOVE.B   (A1)+,D1
   ASL   #4,D1
   OR.B   (A1)+,D1
   CLR   D2
   MOVE.B   (A1)+,D2
   LSR   #4,D2
   OR   D2,D1
   MOVE   D1,(A0)+
   DBRA   D0,COL_LOOP
   RTS

COMPRESSED

   ASL   #1,D3
   ASL   #1,D5

COMP1   MOVE.L   A0,A6
   BSR   DECOMP_LINE
   MOVE.L   A6,A0
   MOVE.L   A2,A6
   BSR   DECOMP_LINE
   MOVE.L   A6,A2
   MOVE.L   A3,A6
   BSR   DECOMP_LINE
   MOVE.L   A6,A3
   MOVE.L   A4,A6
   BSR   DECOMP_LINE
   MOVE.L   A6,A4
   MOVE.L   A5,A6
   BSR   DECOMP_LINE
   MOVE.L   A6,A5
   SUBQ   #1,D2
   BNE   COMP1
   RTS

DECOMP_LINE

   MOVE.B   (A1)+,D0
   EXT.W   D0
   TST   D0
   BMI   ISCOMP
L_NC   MOVE.B   (A1)+,(A6)+   
   SUBQ   #1,D3
   DBRA   D0,L_NC
   TST   D3
   BPL   DECOMP_LINE
   MOVE   D5,D3
   RTS
ISCOMP   NEG   D0
L_ISC   MOVE.B   (A1),(A6)+
   SUBQ   #1,D3
   DBRA   D0,L_ISC
   ADD   #1,A1
   TST   D3
   BPL   DECOMP_LINE
   MOVE   D5,D3
   RTS


GET_AND_TEST

   BSR   WORD_TO_BUF
   CMP.L   #'BODY',WORD_BUF
   RTS

WORD_TO_BUF

   LEA   WORD_BUF,A2
WTB1   MOVE.B   (A1),(A2)+
   TST.B   (A1)+
   BNE   WTB1
   ADD.L   #1,A1
   RTS

WORD_BUF   DC.L   0,0,0   

** Print up the data at PLAYFIELDXY as a screen full of 'chite' data ***

NEWSCREEN

   LEA   V,A5
   MOVE   PLAYFIELDY-V(A5),D0
   MOVE   D0,D2
   MULU   #160,D0         D2 is y pos
   MOVE   PLAYFIELDX-V(A5),D3
   ASL   #1,D3         
    ADD   D3,D0         D3 is x pos * 2 for word
   LEA   PLAYFIELD,A2
   ADD   D0,A2         A2 points at first PLAYFIELD pos'n
   CLR.L   D0         D0 is xy pixel pos   
NS_L1
   SWAP   D0
NS_L2
   MOVE.L   #$00040020,D1      D1 size data for blitter
   LEA   SCREEN,A1      A1 is first bitplane
   LEA   GRAPHIC,A0
   MOVE.W   (A2)+,D4
   AND   #$FF,D4
   MULU   #(8*4*4*5),D4
   ADD   D4,A0         A0 points at graphic data
   MOVEM.L   D0-D3/A0-A2,-(SP)
   BSR   BLIT_5_PLANE
   MOVEM.L   (SP)+,D0-D3/A0-A2   
   SWAP   D0
   ADD   #$20,D0
   CMP   #$140,D0
   BNE   NS_L1
   ADD   #140,A2         Point A2 at next line down
   CLR   D0
   SWAP   D0      
   ADD   #$20,D0
   CMP   #$80,D0
   BNE   NS_L2
   BSR   BLIT_BIT_MASK
   LEA   V,A5
   MOVE   PLAYFIELDY-V(A5),D0
   MOVE   D0,D2
   MULU   #160,D0         D2 is y pos
   MOVE   PLAYFIELDX-V(A5),D3
   ASL   #1,D3         
    ADD   D3,D0         D3 is x pos * 2 for word
   LEA   PLAYFIELD,A2
   ADD   D0,A2         A2 points at first PLAYFIELD pos'n
   CLR.L   D0         D0 is xy pixel pos   
NS_L1_BAK
   SWAP   D0
NS_L2_BAK
   MOVE.L   #$00040020,D1      D1 size data for blitter
   LEA   SCREEN,A1      A1 is first bitplane
   LEA   GRAPHIC,A0
   MOVE.W   (A2)+,D4
   LSR   #8,D4
   MULU   #(8*4*4*5),D4
   ADD   D4,A0         A0 points at graphic data
   MOVEM.L   D0-D3/A0-A2,-(SP)
   LEA   BITPLANE6,A2
   BSR   BLIT_5_PLANE_MASKED
   MOVEM.L   (SP)+,D0-D3/A0-A2   
   SWAP   D0
   ADD   #$20,D0
   CMP   #$140,D0
   BNE   NS_L1_BAK
   ADD   #140,A2         Point A2 at next line down
   CLR   D0
   SWAP   D0      
   ADD   #$20,D0
   CMP   #$80,D0
   BNE   NS_L2_BAK
   LEA   V,A5
   RTS

* BLIT the current number (foreground or background) graphic, to show *
* what will be placed on screen with the mouse               *

BLIT_CURRENT
   
   MOVEM.L   D0-D2/A0/A1/A5,-(SP)      
   MOVE   CURNUM,D0
   MULU   #(8*4*4*5),D0
   MOVE.L   #$00040020,D1      D1 size data for blitter
   LEA   SCREEN,A1      A1 is first bitplane
   LEA   GRAPHIC,A0
   ADD   D0,A0
   MOVE.L   #$F00084,D0
   BSR   BLIT_5_PLANE
   MOVEM.L   (SP)+,D0-D2/A0/A1/A5
   RTS

