;*********************************************************************
;* Here contains 68K assembler source code to convert color byte     *
;* information into data that is suitable for a system that          *
;* displays color in a multiple plane configuration. This code       *
;* assumes each plane is offset by 16 bits (2 bytes).                *
;* Available Functions:                                              *
;*                                                                   *
;* int byte2raw8(char *color_data, char *buffer); 256 color          *
;* int byte2raw4(char *color_data, char *buffer);  16 color          *
;* int byte2raw2(char *color_data, char *buffer);   4 color          *
;* int byte2raw1(char *color_data, char *buffer);   2 color          *
;* Return value is the number of bytes written to the buffer.        *


     export byte2raw8
     export byte2raw4
     export byte2raw2
     export byte2raw1
     text

;*********************************************************************
;* This will convert byte color into 8 plane pixel color.            *
;* Input 16 bytes of color information.                              *
;* Output 8 integers suitable for displaying on the ATARI.           *
;*********************************************************************
;* Function:
;* int byte2raw8(char *color_data, char *buffer);
;* color_data will be converted and placed into location buffer.
;* color_data = A0. (Must be word aligned)
;* buffer     = A1. (Must be word aligned)

     
byte2raw8:
     movem.l  D1-D7/A0-A2,-(A7)       ; Save used registers.

     moveq.l  #0,D0                   ; Now zero them out.
     moveq.l  #0,D1                   ; Pixel color store here
     moveq.l  #0,D2                   ; in registers D0-D3.
     moveq.l  #0,D3
     
     move.l   #$1, D5                 ; Set up 'OR' mask.
     move.l   D5,D6
     swap     D6
     
     adda.l   #12,A0                  ; Start at end of data.
     
     ; In order to plot the data in the correct order. We need
     ; to reverse the order of the 16 bytes of data.
     
     move.l   (A0),D4                 ; Get the last 4 bytes

     ror.w    #8,D4                   ; Convert to Intel format.
     swap     D4
     ror.w    #8,D4
     
     move     #3,D7                   ; Loop 4 times (4 bytes).

.loop1:     
     lsl.l    #1,D4                   ; Bit was set?
     bcc      .b12                    ; Branch if not.
     or.l     D5,D3                   ; Set pixel on plane 7
.b12:
     lsl.l    #1,D4
     bcc      .b13
     or.l     D6,D3                   ; Plane 6
.b13:          
     lsl.l    #1,D4
     bcc      .b14
     or.l     D5,D2                   ; Plane 5
.b14:     
     lsl.l    #1,D4
     bcc      .b15
     or.l     D6,D2                   ; Plane 4
.b15:
     lsl.l    #1,D4
     bcc      .b16
     or.l     D5,D1                   ; Plane 3
.b16:     
     lsl.l    #1,D4
     bcc      .b17
     or.l     D6,D1                   ; Plane 2
.b17:
     lsl.l    #1,D4
     bcc      .b18
     or.l     D5,D0                   ; Plane 1
.b18:
     lsl.l    #1,D4
     bcc      .b19
     or.l     D6,D0                   ; Plane 0
.b19:     
     lsl.l    D5                      ; Shift odd and even plane
     lsl.l    D6                      ; 'OR' mask.
          
     dbf     D7,.loop1                ; Branch if data still available.

     suba.l   #4,A0                   ; Adjust data pointer to left
     move.l   (A0),D4                 ; and get the 3rd 4 byte group.

     ror.w    #8,D4                   ; Convert long word into Intel
     swap     D4                      ; format.
     ror.w    #8,D4

     move     #3,D7                   ; Set up loop counter.

.loop2:     
     lsl.l    #1,D4
     bcc      .b22
     or.l     D5,D3                   ; Plane 7
.b22:
     lsl.l    #1,D4
     bcc      .b23
     or.l     D6,D3                   ; Plane 6
.b23:          
     lsl.l    #1,D4
     bcc      .b24
     or.l     D5,D2                   ; Plane 5
.b24:     
     lsl.l    #1,D4
     bcc      .b25
     or.l     D6,D2                   ; Plane 4
.b25:
     lsl.l    #1,D4
     bcc      .b26
     or.l     D5,D1                   ; Plane 3
.b26:     
     lsl.l    #1,D4
     bcc      .b27
     or.l     D6,D1                   ; Plane 2
.b27:
     lsl.l    #1,D4
     bcc      .b28
     or.l     D5,D0                   ; Plane 1
.b28:
     lsl.l    #1,D4
     bcc      .b29
     or.l     D6,D0                   ; Plane 0
.b29:     
     lsl.l    D5
     lsl.l    D6
          
     dbf     D7,.loop2

     suba.l   #4,A0                   ; Adjust data pointer left and
     move.l   (A0),D4                 ; get the 2nd 4 byte group.

     ror.w    #8,D4                   ; Convert to Intel format.
     swap     D4
     ror.w    #8,D4

     move     #3,D7                   ; Set up loop counter.

.loop3:     
     lsl.l    #1,D4
     bcc      .b32
     or.l     D5,D3                   ; Plane 7
.b32:
     lsl.l    #1,D4
     bcc      .b33
     or.l     D6,D3                   ; Plane 6
.b33:          
     lsl.l    #1,D4
     bcc      .b34
     or.l     D5,D2                   ; Plane 5
.b34:     
     lsl.l    #1,D4
     bcc      .b35
     or.l     D6,D2                   ; Plane 4
.b35:
     lsl.l    #1,D4
     bcc      .b36
     or.l     D5,D1                   ; Plane 3
.b36:     
     lsl.l    #1,D4
     bcc      .b37
     or.l     D6,D1                   ; Plane 2
.b37:
     lsl.l    #1,D4
     bcc      .b38
     or.l     D5,D0                   ; Plane 1
.b38:
     lsl.l    #1,D4
     bcc      .b39
     or.l     D6,D0                   ; Plane 0
.b39:     
     lsl.l    D5
     lsl.l    D6
          
     dbf     D7,.loop3

     suba.l   #4,A0                   ; Adjust data pointer left and
     move.l   (A0),D4                 ; get the first 4 bytes.

     ror.w    #8,D4                   ; Shift data to intel format.
     swap     D4
     ror.w    #8,D4

     move     #3,D7                   ; Loop 4 times.

.loop4:     
     lsl.l    #1,D4
     bcc      .b42
     or.l     D5,D3                   ; Plane 7
.b42:
     lsl.l    #1,D4
     bcc      .b43
     or.l     D6,D3                   ; Plane 6
.b43:          
     lsl.l    #1,D4
     bcc      .b44
     or.l     D5,D2                   ; Plane 5
.b44:     
     lsl.l    #1,D4
     bcc      .b45
     or.l     D6,D2                   ; Plane 4
.b45:
     lsl.l    #1,D4
     bcc      .b46
     or.l     D5,D1                   ; Plane 3
.b46:     
     lsl.l    #1,D4
     bcc      .b47
     or.l     D6,D1                   ; Plane 2
.b47:
     lsl.l    #1,D4
     bcc      .b48
     or.l     D5,D0                   ; Plane 1
.b48:
     lsl.l    #1,D4
     bcc      .b49
     or.l     D6,D0                   ; Plane 0
.b49:     
     lsl.l    D5
     lsl.l    D6
          
     dbf     D7,.loop4

     move.l  D0,(A1)+                 ; Now move the data into
     move.l  D1,(A1)+                 ; buffer.
     move.l  D2,(A1)+
     move.l  D3,(A1)

     movem.l (A7)+,D1-D7/A0-A2        ; Restore used registers.
 
     move.l  #16,D0                   ; Return number of bytes written.
     rts                              ; Return to calling function.

;*********************************************************************
;* This will convert byte color into 4 plane pixel color.            *
;* Input 16 bytes of color information.                              *
;* Output 4 integers suitable for displaying on the ATARI.           *
;*********************************************************************
;* Function:
;* int byte2raw4(char *color_data, char *buffer);
;* color_data will be converted and placed into location buffer.
;* color_data = A0. (Must be word aligned)
;* buffer     = A1. (Must be word aligned)

byte2raw4:
     movem.l  D2-D7/A0-A2,-(A7)       ; Save used registers.

     moveq.l  #0,D2                   ; in registers D0-D3.
     moveq.l  #0,D3
     
     move.l   #$1, D5                 ; Set up 'OR' mask.
     move.l   D5,D6
     swap     D6
     
     adda.l   #12,A0                  ; Start at end of data.
     
     ; In order to plot the data in the correct order. We need
     ; to reverse the order of the 16 bytes of data.
     
     move.l   (A0),D4                 ; Get the last 4 bytes

     ror.w    #8,D4                   ; Convert to Intel format.
     swap     D4
     ror.w    #8,D4
     
     move     #3,D7                   ; Loop 4 times (4 bytes).

.loop1:     
     lsl.l    #4,D4                   ; First four bits unused.
     
     lsl.l    #1,D4                   ; Bit was set?
     bcc      .b12                    ; Branch if not.
     or.l     D5,D3                   ; Set pixel on plane 3
.b12:
     lsl.l    #1,D4
     bcc      .b13
     or.l     D6,D3                   ; Plane 2
.b13:          
     lsl.l    #1,D4
     bcc      .b14
     or.l     D5,D2                   ; Plane 1
.b14:     
     lsl.l    #1,D4
     bcc      .b15
     or.l     D6,D2                   ; Plane 0
.b15:
     
     lsl.l    D5                      ; Shift odd and even plane
     lsl.l    D6                      ; 'OR' mask.
          
     dbf     D7,.loop1                ; Branch if data still available.

     suba.l   #4,A0                   ; Adjust data pointer to left
     move.l   (A0),D4                 ; and get the 3rd 4 byte group.

     ror.w    #8,D4                   ; Convert long word into Intel
     swap     D4                      ; format.
     ror.w    #8,D4

     move     #3,D7                   ; Set up loop counter.

.loop2:     
     lsl.l    #4,D4                   ; First 4 bits unused.
     
     lsl.l    #1,D4
     bcc      .b22
     or.l     D5,D3                   ; Plane 3
.b22:
     lsl.l    #1,D4
     bcc      .b23
     or.l     D6,D3                   ; Plane 2
.b23:          
     lsl.l    #1,D4
     bcc      .b24
     or.l     D5,D2                   ; Plane 1
.b24:     
     lsl.l    #1,D4
     bcc      .b25
     or.l     D6,D2                   ; Plane 0
.b25:
     lsl.l    D5
     lsl.l    D6
          
     dbf     D7,.loop2

     suba.l   #4,A0                   ; Adjust data pointer left and
     move.l   (A0),D4                 ; get the 2nd 4 byte group.

     ror.w    #8,D4                   ; Convert to Intel format.
     swap     D4
     ror.w    #8,D4

     move     #3,D7                   ; Set up loop counter.

.loop3:     
     lsl.l    #4,D4                   ; First 4 bits unused.
     
     lsl.l    #1,D4
     bcc      .b32
     or.l     D5,D3                   ; Plane 3
.b32:
     lsl.l    #1,D4
     bcc      .b33
     or.l     D6,D3                   ; Plane 2
.b33:          
     lsl.l    #1,D4
     bcc      .b34
     or.l     D5,D2                   ; Plane 1
.b34:     
     lsl.l    #1,D4
     bcc      .b35
     or.l     D6,D2                   ; Plane 0
.b35:
     lsl.l    D5
     lsl.l    D6
          
     dbf     D7,.loop3

     suba.l   #4,A0                   ; Adjust data pointer left and
     move.l   (A0),D4                 ; get the first 4 bytes.

     ror.w    #8,D4                   ; Shift data to intel format.
     swap     D4
     ror.w    #8,D4

     move     #3,D7                   ; Loop 4 times.

.loop4:     
     lsl.l    #4,D4                   ; First 4 bits unused.
     
     lsl.l    #1,D4
     bcc      .b42
     or.l     D5,D3                   ; Plane 3
.b42:
     lsl.l    #1,D4
     bcc      .b43
     or.l     D6,D3                   ; Plane 2
.b43:          
     lsl.l    #1,D4
     bcc      .b44
     or.l     D5,D2                   ; Plane 1
.b44:     
     lsl.l    #1,D4
     bcc      .b45
     or.l     D6,D2                   ; Plane 0
.b45:
     lsl.l    D5
     lsl.l    D6
          
     dbf     D7,.loop4

     move.l  D2,(A1)+                 ; Now move the data into
     move.l  D3,(A1)+                 ; buffer.

     movem.l (A7)+,D2-D7/A0-A2        ; Restore used registers.

     move.l  #8,D0                    ; Number of bytes written. 
     rts                              ; Return to calling function.

;*********************************************************************
;* This will convert byte color into 2 plane pixel color.            *
;* Input 16 bytes of color information.                              *
;* Output 2 integers suitable for displaying on the ATARI.           *
;*********************************************************************
;* Function:
;* int byte2raw2(char *color_data, char *buffer);
;* color_data will be converted and placed into location buffer.
;* color_data = A0. (Must be word aligned)
;* buffer     = A1. (Must be word aligned)

byte2raw2:
     movem.l  D3-D7/A0-A2,-(A7)       ; Save used registers.

     moveq.l  #0,D3                   ; in registers D0-D3.
     
     move.l   #$1, D5                 ; Set up 'OR' mask.
     move.l   D5,D6
     swap     D6
     
     adda.l   #12,A0                  ; Start at end of data.
     
     ; In order to plot the data in the correct order. We need
     ; to reverse the order of the 16 bytes of data.
     
     move.l   (A0),D4                 ; Get the last 4 bytes

     ror.w    #8,D4                   ; Convert to Intel format.
     swap     D4
     ror.w    #8,D4
     
     move     #3,D7                   ; Loop 4 times (4 bytes).

.loop1:     
     lsl.l    #6,D4                   ; First four bits unused.
     
     lsl.l    #1,D4                   ; Bit was set?
     bcc      .b12                    ; Branch if not.
     or.l     D5,D3                   ; Set pixel on plane 1
.b12:
     lsl.l    #1,D4
     bcc      .b13
     or.l     D6,D3                   ; Plane 0
.b13:          
     
     lsl.l    D5                      ; Shift odd and even plane
     lsl.l    D6                      ; 'OR' mask.
          
     dbf     D7,.loop1                ; Branch if data still available.

     suba.l   #4,A0                   ; Adjust data pointer to left
     move.l   (A0),D4                 ; and get the 3rd 4 byte group.

     ror.w    #8,D4                   ; Convert long word into Intel
     swap     D4                      ; format.
     ror.w    #8,D4

     move     #3,D7                   ; Set up loop counter.

.loop2:     
     lsl.l    #6,D4                   ; First 6 bits unused.
     
     lsl.l    #1,D4
     bcc      .b22
     or.l     D5,D3                   ; Plane 1
.b22:
     lsl.l    #1,D4
     bcc      .b23
     or.l     D6,D3                   ; Plane 0
.b23:          
     lsl.l    D5
     lsl.l    D6
          
     dbf     D7,.loop2

     suba.l   #4,A0                   ; Adjust data pointer left and
     move.l   (A0),D4                 ; get the 2nd 4 byte group.

     ror.w    #8,D4                   ; Convert to Intel format.
     swap     D4
     ror.w    #8,D4

     move     #3,D7                   ; Set up loop counter.

.loop3:     
     lsl.l    #6,D4                   ; First 6 bits unused.
     
     lsl.l    #1,D4
     bcc      .b32
     or.l     D5,D3                   ; Plane 1
.b32:
     lsl.l    #1,D4
     bcc      .b33
     or.l     D6,D3                   ; Plane 0
.b33:          
     lsl.l    D5
     lsl.l    D6
          
     dbf     D7,.loop3

     suba.l   #4,A0                   ; Adjust data pointer left and
     move.l   (A0),D4                 ; get the first 4 bytes.

     ror.w    #8,D4                   ; Shift data to intel format.
     swap     D4
     ror.w    #8,D4

     move     #3,D7                   ; Loop 4 times.

.loop4:     
     lsl.l    #6,D4                   ; First 4 bits unused.
     
     lsl.l    #1,D4
     bcc      .b42
     or.l     D5,D3                   ; Plane 3
.b42:
     lsl.l    #1,D4
     bcc      .b43
     or.l     D6,D3                   ; Plane 2
.b43:          
     lsl.l    D5
     lsl.l    D6
          
     dbf     D7,.loop4

     move.l  D3,(A1)                  ; Now move the data into
                                      ; buffer.
     movem.l (A7)+,D3-D7/A0-A2        ; Restore used registers.

     move.l  #4,D0                    ; Number of bytes written. 
     rts                              ; Return to calling function.

;*********************************************************************
;* This will convert byte color into 2 plane pixel color.            *
;* Input 16 bytes of color information.                              *
;* Output 1 integers suitable for displaying on the ATARI.           *
;*********************************************************************
;* Function:
;* int byte2raw1(char *color_data, char *buffer);
;* color_data will be converted and placed into location buffer.
;* color_data = A0. (Must be word aligned)
;* buffer     = A1. (Must be word aligned)

byte2raw1:
     movem.l  D3-D7/A0-A2,-(A7)       ; Save used registers.

     moveq.l  #0,D3                   ; Zero register D3.

     ; In order to plot the data in the correct order. We need
     ; to reverse the order of the 16 bytes of data.

     adda.l   #12,A0                  ; Start at end of data.     
     move.l   (A0),D4                 ; Get the last 4 bytes

     ror.w    #8,D4                   ; Convert to Intel format.
     swap     D4
     ror.w    #8,D4
          
     move.l   #$1, D5                 ; Set up 'OR' mask.
     lsl.l    #7,D4                   ; First 7 bits unused.
     
     lsl.l    #1,D4                   ; Bit was set?
     bcc      .b12                    ; Branch if not.
     or.l     D5,D3                   ; Set pixel on plane 1
.b12:    
     lsl.l    D5                      ; Shift 'OR' mask.
     lsl.l    #7,D4                   ; First 7 bits unused.
     
     lsl.l    #1,D4                   ; Bit was set?
     bcc      .b13                    ; Branch if not.
     or.l     D5,D3                   ; Set pixel on plane 1
.b13:    
     lsl.l    D5                      ; Shift 'OR' mask.
     lsl.l    #7,D4                   ; First 7 bits unused.
     
     lsl.l    #1,D4                   ; Bit was set?
     bcc      .b14                    ; Branch if not.
     or.l     D5,D3                   ; Set pixel on plane 1
.b14:    
     lsl.l    D5                      ; Shift 'OR' mask.
     lsl.l    #7,D4                   ; First 7 bits unused.
     
     lsl.l    #1,D4                   ; Bit was set?
     bcc      .b15                    ; Branch if not.
     or.l     D5,D3                   ; Set pixel on plane 1
.b15:    

     subq.l   #4,A0
     move.l   (A0),D4                 ; Get 4 bytes

     ror.w    #8,D4                   ; Convert to Intel format.
     swap     D4
     ror.w    #8,D4
          
     lsl.l    D5                      ; Shift 'OR' mask.
     lsl.l    #7,D4                   ; First 7 bits unused.
     
     lsl.l    #1,D4                   ; Bit was set?
     bcc      .b22                    ; Branch if not.
     or.l     D5,D3                   ; Set pixel on plane 1
.b22:    
     lsl.l    D5                      ; Shift 'OR' mask.
     lsl.l    #7,D4                   ; First 7 bits unused.
     
     lsl.l    #1,D4                   ; Bit was set?
     bcc      .b23                    ; Branch if not.
     or.l     D5,D3                   ; Set pixel on plane 1
.b23:    
     lsl.l    D5                      ; Shift 'OR' mask.
     lsl.l    #7,D4                   ; First 7 bits unused.
     
     lsl.l    #1,D4                   ; Bit was set?
     bcc      .b24                    ; Branch if not.
     or.l     D5,D3                   ; Set pixel on plane 1
.b24:    
     lsl.l    D5                      ; Shift 'OR' mask.
     lsl.l    #7,D4                   ; First 7 bits unused.
     
     lsl.l    #1,D4                   ; Bit was set?
     bcc      .b25                    ; Branch if not.
     or.l     D5,D3                   ; Set pixel on plane 1
.b25:    

     subq.l   #4,A0
     move.l   (A0),D4                 ; Get 4 bytes

     ror.w    #8,D4                   ; Convert to Intel format.
     swap     D4
     ror.w    #8,D4
          
     lsl.l    D5                      ; Shift 'OR' mask.
     lsl.l    #7,D4                   ; First 7 bits unused.
     
     lsl.l    #1,D4                   ; Bit was set?
     bcc      .b32                    ; Branch if not.
     or.l     D5,D3                   ; Set pixel on plane 1
.b32:    
     lsl.l    D5                      ; Shift 'OR' mask.
     lsl.l    #7,D4                   ; First 7 bits unused.
     
     lsl.l    #1,D4                   ; Bit was set?
     bcc      .b33                    ; Branch if not.
     or.l     D5,D3                   ; Set pixel on plane 1
.b33:    
     lsl.l    D5                      ; Shift 'OR' mask.
     lsl.l    #7,D4                   ; First 7 bits unused.
     
     lsl.l    #1,D4                   ; Bit was set?
     bcc      .b34                    ; Branch if not.
     or.l     D5,D3                   ; Set pixel on plane 1
.b34:    
     lsl.l    D5                      ; Shift 'OR' mask.
     lsl.l    #7,D4                   ; First 7 bits unused.
     
     lsl.l    #1,D4                   ; Bit was set?
     bcc      .b35                    ; Branch if not.
     or.l     D5,D3                   ; Set pixel on plane 1
.b35:    
          
     subq.l   #4,A0
     move.l   (A0),D4                 ; Get 4 bytes

     ror.w    #8,D4                   ; Convert to Intel format.
     swap     D4
     ror.w    #8,D4
          
     lsl.l    D5                      ; Shift 'OR' mask.
     lsl.l    #7,D4                   ; First 7 bits unused.
     
     lsl.l    #1,D4                   ; Bit was set?
     bcc      .b42                    ; Branch if not.
     or.l     D5,D3                   ; Set pixel on plane 1
.b42:    
     lsl.l    D5                      ; Shift 'OR' mask.
     lsl.l    #7,D4                   ; First 7 bits unused.
     
     lsl.l    #1,D4                   ; Bit was set?
     bcc      .b43                    ; Branch if not.
     or.l     D5,D3                   ; Set pixel on plane 1
.b43:    
     lsl.l    D5                      ; Shift 'OR' mask.
     lsl.l    #7,D4                   ; First 7 bits unused.
     
     lsl.l    #1,D4                   ; Bit was set?
     bcc      .b44                    ; Branch if not.
     or.l     D5,D3                   ; Set pixel on plane 1
.b44:    
     lsl.l    D5                      ; Shift 'OR' mask.
     lsl.l    #7,D4                   ; First 7 bits unused.
     
     lsl.l    #1,D4                   ; Bit was set?
     bcc      .b45                    ; Branch if not.
     or.l     D5,D3                   ; Set pixel on plane 1
.b45:    

     move.w  D3,(A1)                  ; Now move the data into
                                      ; buffer.
     movem.l (A7)+,D3-D7/A0-A2        ; Restore used registers.

     move.l  #2,D0                    ; Number of bytes written. 
     rts                              ; Return to calling function.
                
end_loop:
     bra end_loop                     ; just in case.
     end