;DA2_blitter
;-----------
;blits a full screen
;
;Entry:
; R0 - DA2 source
; R1 - GPU buffer
; R2 - screen width
; R3 - screen height
;R10 - Vend
;R12 - palette lookup table
;R13 +0 - GPU border
;    +4 - Left+Right border
;    +8 - Vstart corrected for left border

;bpp      = 1 / 2 / 4 / 8 (bits per pixel + 1)
;pix_byte = 3 / 2 / 1 / 0 (pixels per byte as 1<<N)
;ratio    = 0 is square, 1 is double width, 2 is double height

MACRO DA2_blitter bpp:I, pix_byte:I, ratio:I
{
 #if ratio == 2				;double height
   LDR     R7, [R13, #blitter_stack.GPU_border]	;get GPU border
   ADD     R2, R2, R7			;add to width, for 2nd raster
 #endif
 MOV     R2, R2, LSL #2			;*4 as STRD can't be shifted

 MOV     R11, #(1 << bpp) - 1		;bitmask for pixels
 ._blit_y_loop
   PLD     [R0, #0]			;pre-load screen
   BL      IOC_timers 			;increase IOC timers

   #if ratio == 2			;double height
     LDR     R7, [R13, #blitter_stack.GPU_border]	;get GPU border
     RSB     R4, R7, R2, LSR #2		;correct width
   #endif
   #if ratio == 0
     MOV     R4, R2, LSR #2		;R4=width
   #endif
   #if ratio == 1			;double width
     MOV     R4, R2, LSR #3		;R4=width/2 for double width
   #endif

   ._blit_vstart_loop
   AND     R7, R0, #%11			;R7=byte offset within word
   BIC     R0, R0, #%11			;align screen start to words

   ADD     PC, PC, R7, LSL #2		;jump to appropriate blitter
   NOP
   B       _blit_0_offset_x_loop	;word aligned
   B       _blit_8_offset_x_loop	;misaligned +1 byte
   B       _blit_16_offset_x_loop	;misaligned +2 bytes
					;misaligned +3 bytes
   ._blit_24_offset_x_loop
     LDRB    R5, [R0, #3]		;---0 load pixels
     LDR     R6, [R0, #4]!		;X321
     ORR     R5, R5, R6, LSL #8		;3210

     BL      _blit_one_word
   BGT     _blit_24_offset_x_loop
   ADD     R0, R0, #3			;correct address
   B       _blit_x_done

   ._blit_16_offset_x_loop
     LDRH    R5, [R0, #2]		;--10 load pixels
     LDRH    R6, [R0, #4]!		;--32
     ORR     R5, R5, R6, LSL #16	;3210

     BL      _blit_one_word
   BGT     _blit_16_offset_x_loop
   ADD     R0, R0, #2			;correct address
   B       _blit_x_done

   ._blit_8_offset_x_loop
     LDR     R5, [R0], #4		;210X load pixels
     LDRB    R6, [R0]			;---3
     MOV     R5, R5, LSR #8		;-210
     ORR     R5, R5, R6, LSL #24	;3210

     BL      _blit_one_word
   BGT     _blit_8_offset_x_loop
   ADD     R0, R0, #1			;correct address
   B       _blit_x_done

   ._blit_0_offset_x_loop
     LDR     R5, [R0], #4		;load pixels

     BL      _blit_one_word
   BGT     _blit_0_offset_x_loop

   ._blit_x_done
   LDMIA   R13, {R5, R7}		;R5=GPU border, R7=DA2 border
   ADD     R1, R1, R4, ASL #2		;correct for overrun
   #if pix_byte > 0
     ADD     R0, R0, R4, ASR #pix_byte	;correct for overrun
     ADD     R0, R0, R7, LSR #pix_byte	;go to next line in DA2
   #else
     ADD     R0, R0, R4			;correct for overrun
     ADD     R0, R0, R7			;go to next line in DA2
   #endif

   CMP     R0, R10			;have we hit Vend?
   MVNHS   R10, #0			;YES, ignore Vend from now on
   LDRHS   R0, [R13, #blitter_stack.Vstart]	; |+  get corrected Vstart from stack

   #if compile_DEBUG == 1
     MVNHS  R6, #0			;RED bar indicated screen wrap
     STRHS  R6, [R1, #-4]
     STRHS  R6, [R1, #-8]
     STRHS  R6, [R1, #-12]
     STRHS  R6, [R1, #-16]
   #endif

   ADD     R1, R1, R5, LSL #2		;skip border in GPU

   #if ratio == 2			;double height
     ADD     R1, R1, R2			;skip a raster
     SUBS    R3, R3, #2			;last vertical line?
   #else
     SUBS    R3, R3, #1			;last vertical line?
   #endif

 BNE     _blit_y_loop			;NO
B       blit_exit


._blit_one_word
 PLD     [R0, #32]			;pre-load screen

 #if bpp == 8
   #if bpp == 8 AND (ratio == 0 OR ratio == 2)		;square / double height
     AND     R6, R11, R5		;pixels 0-3
     AND     R7, R11, R5, LSR #8
     AND     R8, R11, R5, LSR #16
     AND     R9, R11, R5, LSR #24
     LDR     R6, [R12, R6, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     LDR     R8, [R12, R8, LSL #2]
     LDR     R9, [R12, R9, LSL #2]
     #if bpp == 8 AND ratio == 2	;double height
       STRD    R6, R7, [R1, R2]
     #endif
     STRD    R6, R7, [R1], #8
     #if bpp == 8 AND ratio == 2	;double height
       STRD    R8, R9, [R1, R2]
     #endif
     STRD    R8, R9, [R1], #8
   #endif
   #if bpp == 8 AND ratio == 1		;double width
     AND     R9, R11, R5, LSR #8	;pixels 0,1
     AND     R7, R11, R5
     LDR     R9, [R12, R9, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     MOV     R8, R9			;duplicate pixels
     MOV     R6, R7
     STRD    R8, R9, [R1, #8]
     STRD    R6, R7, [R1], #16

     AND     R9, R11, R5, LSR #24	;pixels 2,3
     AND     R7, R11, R5, LSR #16
     LDR     R9, [R12, R9, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     MOV     R8, R9			;duplicate pixels
     MOV     R6, R7
     STRD    R8, R9, [R1, #8]
     STRD    R6, R7, [R1], #16
   #endif
 #endif
 #if bpp == 4
   #if bpp == 4 AND (ratio == 0 OR ratio == 2)		;square / double height
     AND     R6, R11, R5		;pixels 0-3
     AND     R7, R11, R5, LSR #4
     AND     R8, R11, R5, LSR #8
     AND     R9, R11, R5, LSR #12
     LDR     R6, [R12, R6, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     LDR     R8, [R12, R8, LSL #2]
     LDR     R9, [R12, R9, LSL #2]
     #if bpp == 4 AND ratio == 2	;double height
       STRD    R6, R7, [R1, R2]
     #endif
     STRD    R6, R7, [R1], #8
     #if bpp == 4 AND ratio == 2	;double height
       STRD    R8, R9, [R1, R2]
     #endif
     STRD    R8, R9, [R1], #8

     AND     R6, R11, R5, LSR #16	;pixels 4-7
     AND     R7, R11, R5, LSR #20
     AND     R8, R11, R5, LSR #24
     AND     R9, R11, R5, LSR #28
     LDR     R6, [R12, R6, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     LDR     R8, [R12, R8, LSL #2]
     LDR     R9, [R12, R9, LSL #2]
     #if bpp == 4 AND ratio == 2	;double height
       STRD    R6, R7, [R1, R2]
     #endif
     STRD    R6, R7, [R1], #8
     #if bpp == 4 AND ratio == 2	;double height
       STRD    R8, R9, [R1, R2]
     #endif
     STRD    R8, R9, [R1], #8
   #endif
   #if bpp == 4 AND ratio == 1		;double width
     AND     R9, R11, R5, LSR #4	;pixels 0,1
     AND     R7, R11, R5
     LDR     R9, [R12, R9, LSL #2]
     LDR     R7, [R12, R7, LSL #2]
     MOV     R8, R9			;duplicate pixels
     MOV     R6, R7
     STRD    R8, R9, [R1, #8]
     STRD    R6, R7, [R1], #16

     AND     R9, R11, R5, LSR #12	;pixels 2,3
     AND     R7, R11, R5, LSR #8
     LDR     R9, [R12, R9, LSL #2]
     LDR     R7, [R12, R7, LSL #2]
     MOV     R8, R9			;duplicate pixels
     MOV     R6, R7
     STRD    R8, R9, [R1, #8]
     STRD    R6, R7, [R1], #16

     AND     R9, R11, R5, LSR #20	;pixels 4,5
     AND     R7, R11, R5, LSR #16
     LDR     R9, [R12, R9, LSL #2]
     LDR     R7, [R12, R7, LSL #2]
     MOV     R8, R9			;duplicate pixels
     MOV     R6, R7
     STRD    R8, R9, [R1, #8]
     STRD    R6, R7, [R1], #16

     AND     R9, R11, R5, LSR #28	;pixels 6,7
     AND     R7, R11, R5, LSR #24
     LDR     R9, [R12, R9, LSL #2]
     LDR     R7, [R12, R7, LSL #2]
     MOV     R8, R9			;duplicate pixels
     MOV     R6, R7
     STRD    R8, R9, [R1, #8]
     STRD    R6, R7, [R1], #16
   #endif
 #endif
 #if bpp == 2
   #if bpp == 2 AND (ratio == 0 OR ratio == 2)		;square / double height
     AND     R6, R11, R5		;pixels 0-3
     AND     R7, R11, R5, LSR #2
     AND     R8, R11, R5, LSR #4
     AND     R9, R11, R5, LSR #6
     LDR     R6, [R12, R6, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     LDR     R8, [R12, R8, LSL #2]
     LDR     R9, [R12, R9, LSL #2]
     #if bpp == 2 AND ratio == 2	;double height
       STRD    R6, R7, [R1, R2]
     #endif
     STRD    R6, R7, [R1], #8
     #if bpp == 2 AND ratio == 2	;double height
       STRD    R8, R9, [R1, R2]
     #endif
     STRD    R8, R9, [R1], #8

     AND     R6, R11, R5, LSR #8	;pixels 4-7
     AND     R7, R11, R5, LSR #10
     AND     R8, R11, R5, LSR #12
     AND     R9, R11, R5, LSR #14
     LDR     R6, [R12, R6, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     LDR     R8, [R12, R8, LSL #2]
     LDR     R9, [R12, R9, LSL #2]
     #if bpp == 2 AND ratio == 2	;double height
       STRD    R6, R7, [R1, R2]
     #endif
     STRD    R6, R7, [R1], #8
     #if bpp == 2 AND ratio == 2	;double height
       STRD    R8, R9, [R1, R2]
     #endif
     STRD    R8, R9, [R1], #8

     AND     R6, R11, R5, LSR #16	;pixels 8-11
     AND     R7, R11, R5, LSR #18
     AND     R8, R11, R5, LSR #20
     AND     R9, R11, R5, LSR #22
     LDR     R6, [R12, R6, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     LDR     R8, [R12, R8, LSL #2]
     LDR     R9, [R12, R9, LSL #2]
     #if bpp == 2 AND ratio == 2	;double height
       STRD    R6, R7, [R1, R2]
     #endif
     STRD    R6, R7, [R1], #8
     #if bpp == 2 AND ratio == 2	;double height
       STRD    R8, R9, [R1, R2]
     #endif
     STRD    R8, R9, [R1], #8

     AND     R6, R11, R5, LSR #24	;pixels 12-15
     AND     R7, R11, R5, LSR #26
     AND     R8, R11, R5, LSR #28
     AND     R9, R11, R5, LSR #30
     LDR     R6, [R12, R6, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     LDR     R8, [R12, R8, LSL #2]
     LDR     R9, [R12, R9, LSL #2]
     #if bpp == 2 AND ratio == 2	;double height
       STRD    R6, R7, [R1, R2]
     #endif
     STRD    R6, R7, [R1], #8
     #if bpp == 2 AND ratio == 2	;double height
       STRD    R8, R9, [R1, R2]
     #endif
     STRD    R8, R9, [R1], #8
   #endif
   #if bpp == 2 AND ratio == 1			;double width
     AND     R9, R11, R5, LSR #2	;pixels 0,1
     AND     R7, R11, R5
     LDR     R9, [R12, R9, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     MOV     R8, R9			;duplicate pixels
     MOV     R6, R7
     STRD    R8, R9, [R1, #8]
     STRD    R6, R7, [R1], #16

     AND     R9, R11, R5, LSR #6	;pixels 2,3
     AND     R7, R11, R5, LSR #4
     LDR     R9, [R12, R9, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     MOV     R8, R9			;duplicate pixels
     MOV     R6, R7
     STRD    R8, R9, [R1, #8]
     STRD    R6, R7, [R1], #16

     AND     R9, R11, R5, LSR #10	;pixels 4,5
     AND     R7, R11, R5, LSR #8
     LDR     R9, [R12, R9, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     MOV     R8, R9			;duplicate pixels
     MOV     R6, R7
     STRD    R8, R9, [R1, #8]
     STRD    R6, R7, [R1], #16

     AND     R9, R11, R5, LSR #14	;pixels 6,7
     AND     R7, R11, R5, LSR #12
     LDR     R9, [R12, R9, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     MOV     R8, R9			;duplicate pixels
     MOV     R6, R7
     STRD    R8, R9, [R1, #8]
     STRD    R6, R7, [R1], #16

     AND     R9, R11, R5, LSR #18	;pixels 8,9
     AND     R7, R11, R5, LSR #16
     LDR     R9, [R12, R9, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     MOV     R8, R9			;duplicate pixels
     MOV     R6, R7
     STRD    R8, R9, [R1, #8]
     STRD    R6, R7, [R1], #16

     AND     R9, R11, R5, LSR #22	;pixels 10,11
     AND     R7, R11, R5, LSR #20
     LDR     R9, [R12, R9, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     MOV     R8, R9			;duplicate pixels
     MOV     R6, R7
     STRD    R8, R9, [R1, #8]
     STRD    R6, R7, [R1], #16

     AND     R9, R11, R5, LSR #26	;pixels 12,13
     AND     R7, R11, R5, LSR #24
     LDR     R9, [R12, R9, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     MOV     R8, R9			;duplicate pixels
     MOV     R6, R7
     STRD    R8, R9, [R1, #8]
     STRD    R6, R7, [R1], #16

     AND     R9, R11, R5, LSR #30	;pixels 14,15
     AND     R7, R11, R5, LSR #28
     LDR     R9, [R12, R9, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     MOV     R8, R9			;duplicate pixels
     MOV     R6, R7
     STRD    R8, R9, [R1, #8]
     STRD    R6, R7, [R1], #16
   #endif
 #endif
 #if bpp == 1
   #if bpp == 1 AND (ratio == 0 OR ratio == 2)		;square / double height
     AND     R6, R11, R5		;pixels 0-3
     AND     R7, R11, R5, LSR #1
     AND     R8, R11, R5, LSR #2
     AND     R9, R11, R5, LSR #3
     LDR     R6, [R12, R6, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     LDR     R8, [R12, R8, LSL #2]
     LDR     R9, [R12, R9, LSL #2]
     #if bpp == 1 AND ratio == 2	;double height
       STRD    R6, R7, [R1, R2]
     #endif
     STRD    R6, R7, [R1], #8
     #if bpp == 1 AND ratio == 2	;double height
       STRD    R8, R9, [R1, R2]
     #endif
     STRD    R8, R9, [R1], #8

     AND     R6, R11, R5, LSR #4	;pixels 4-7
     AND     R7, R11, R5, LSR #5
     AND     R8, R11, R5, LSR #6
     AND     R9, R11, R5, LSR #7
     LDR     R6, [R12, R6, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     LDR     R8, [R12, R8, LSL #2]
     LDR     R9, [R12, R9, LSL #2]
     #if bpp == 1 AND ratio == 2	;double height
       STRD    R6, R7, [R1, R2]
     #endif
     STRD    R6, R7, [R1], #8
     #if bpp == 1 AND ratio == 2	;double height
       STRD    R8, R9, [R1, R2]
     #endif
     STRD    R8, R9, [R1], #8

     AND     R6, R11, R5, LSR #8	;pixels 8-11
     AND     R7, R11, R5, LSR #9
     AND     R8, R11, R5, LSR #10
     AND     R9, R11, R5, LSR #11
     LDR     R6, [R12, R6, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     LDR     R8, [R12, R8, LSL #2]
     LDR     R9, [R12, R9, LSL #2]
     #if bpp == 1 AND ratio == 2	;double height
       STRD    R6, R7, [R1, R2]
     #endif
     STRD    R6, R7, [R1], #8
     #if bpp == 1 AND ratio == 2	;double height
       STRD    R8, R9, [R1, R2]
     #endif
     STRD    R8, R9, [R1], #8

     AND     R6, R11, R5, LSR #12	;pixels 12-15
     AND     R7, R11, R5, LSR #13
     AND     R8, R11, R5, LSR #14
     AND     R9, R11, R5, LSR #15
     LDR     R6, [R12, R6, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     LDR     R8, [R12, R8, LSL #2]
     LDR     R9, [R12, R9, LSL #2]
     #if bpp == 1 AND ratio == 2	;double height
       STRD    R6, R7, [R1, R2]
     #endif
     STRD    R6, R7, [R1], #8
     #if bpp == 1 AND ratio == 2	;double height
       STRD    R8, R9, [R1, R2]
     #endif
     STRD    R8, R9, [R1], #8

     AND     R6, R11, R5, LSR #16	;pixels 16-19
     AND     R7, R11, R5, LSR #17
     AND     R8, R11, R5, LSR #18
     AND     R9, R11, R5, LSR #19
     LDR     R6, [R12, R6, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     LDR     R8, [R12, R8, LSL #2]
     LDR     R9, [R12, R9, LSL #2]
     #if bpp == 1 AND ratio == 2	;double height
       STRD    R6, R7, [R1, R2]
     #endif
     STRD    R6, R7, [R1], #8
     #if bpp == 1 AND ratio == 2	;double height
       STRD    R8, R9, [R1, R2]
     #endif
     STRD    R8, R9, [R1], #8

     AND     R6, R11, R5, LSR #20	;pixels 20-23
     AND     R7, R11, R5, LSR #21
     AND     R8, R11, R5, LSR #22
     AND     R9, R11, R5, LSR #23
     LDR     R6, [R12, R6, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     LDR     R8, [R12, R8, LSL #2]
     LDR     R9, [R12, R9, LSL #2]
     #if bpp == 1 AND ratio == 2	;double height
       STRD    R6, R7, [R1, R2]
     #endif
     STRD    R6, R7, [R1], #8
     #if bpp == 1 AND ratio == 2	;double height
       STRD    R8, R9, [R1, R2]
     #endif
     STRD    R8, R9, [R1], #8

     AND     R6, R11, R5, LSR #24	;pixels 24-27
     AND     R7, R11, R5, LSR #25
     AND     R8, R11, R5, LSR #26
     AND     R9, R11, R5, LSR #27
     LDR     R6, [R12, R6, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     LDR     R8, [R12, R8, LSL #2]
     LDR     R9, [R12, R9, LSL #2]
     #if bpp == 1 AND ratio == 2	;double height
       STRD    R6, R7, [R1, R2]
     #endif
     STRD    R6, R7, [R1], #8
     #if bpp == 1 AND ratio == 2	;double height
       STRD    R8, R9, [R1, R2]
     #endif
     STRD    R8, R9, [R1], #8

     AND     R6, R11, R5, LSR #28	;pixels 28-31
     AND     R7, R11, R5, LSR #29
     AND     R8, R11, R5, LSR #30
     AND     R9, R11, R5, LSR #31
     LDR     R6, [R12, R6, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     LDR     R8, [R12, R8, LSL #2]
     LDR     R9, [R12, R9, LSL #2]
     #if bpp == 1 AND ratio == 2	;double height
       STRD    R6, R7, [R1, R2]
     #endif
     STRD    R6, R7, [R1], #8
     #if bpp == 1 AND ratio == 2	;double height
       STRD    R8, R9, [R1, R2]
     #endif
     STRD    R8, R9, [R1], #8
   #endif
   #if bpp == 2 AND ratio == 1				;double width
     AND     R9, R11, R5, LSR #1	;pixels 0,1
     AND     R7, R11, R5
     LDR     R9, [R12, R9, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     MOV     R8, R9			;duplicate pixels
     MOV     R6, R7
     STRD    R8, R9, [R1, #8]
     STRD    R6, R7, [R1], #16

     AND     R9, R11, R5, LSR #3	;pixels 2,3
     AND     R7, R11, R5, LSR #2
     LDR     R9, [R12, R9, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     MOV     R8, R9			;duplicate pixels
     MOV     R6, R7
     STRD    R8, R9, [R1, #8]
     STRD    R6, R7, [R1], #16

     AND     R9, R11, R5, LSR #5	;pixels 4,5
     AND     R7, R11, R5, LSR #4
     LDR     R9, [R12, R9, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     MOV     R8, R9			;duplicate pixels
     MOV     R6, R7
     STRD    R8, R9, [R1, #8]
     STRD    R6, R7, [R1], #16

     AND     R9, R11, R5, LSR #7	;pixels 6,7
     AND     R7, R11, R5, LSR #6
     LDR     R9, [R12, R9, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     MOV     R8, R9			;duplicate pixels
     MOV     R6, R7
     STRD    R8, R9, [R1, #8]
     STRD    R6, R7, [R1], #16

     AND     R9, R11, R5, LSR #9	;pixels 8,9
     AND     R7, R11, R5, LSR #8
     LDR     R9, [R12, R9, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     MOV     R8, R9			;duplicate pixels
     MOV     R6, R7
     STRD    R8, R9, [R1, #8]
     STRD    R6, R7, [R1], #16

     AND     R9, R11, R5, LSR #11	;pixels 10,11
     AND     R7, R11, R5, LSR #10
     LDR     R9, [R12, R9, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     MOV     R8, R9			;duplicate pixels
     MOV     R6, R7
     STRD    R8, R9, [R1, #8]
     STRD    R6, R7, [R1], #16

     AND     R9, R11, R5, LSR #13	;pixels 12,13
     AND     R7, R11, R5, LSR #12
     LDR     R9, [R12, R9, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     MOV     R8, R9			;duplicate pixels
     MOV     R6, R7
     STRD    R8, R9, [R1, #8]
     STRD    R6, R7, [R1], #16

     AND     R9, R11, R5, LSR #15	;pixels 14,15
     AND     R7, R11, R5, LSR #14
     LDR     R9, [R12, R9, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     MOV     R8, R9			;duplicate pixels
     MOV     R6, R7
     STRD    R8, R9, [R1, #8]
     STRD    R6, R7, [R1], #16

     AND     R9, R11, R5, LSR #17	;pixels 16,17
     AND     R7, R11, R5, LSR #16
     LDR     R9, [R12, R9, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     MOV     R8, R9			;duplicate pixels
     MOV     R6, R7
     STRD    R8, R9, [R1, #8]
     STRD    R6, R7, [R1], #16

     AND     R9, R11, R5, LSR #19	;pixels 18,19
     AND     R7, R11, R5, LSR #18
     LDR     R9, [R12, R9, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     MOV     R8, R9			;duplicate pixels
     MOV     R6, R7
     STRD    R8, R9, [R1, #8]
     STRD    R6, R7, [R1], #16

     AND     R9, R11, R5, LSR #21	;pixels 20,21
     AND     R7, R11, R5, LSR #20
     LDR     R9, [R12, R9, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     MOV     R8, R9			;duplicate pixels
     MOV     R6, R7
     STRD    R8, R9, [R1, #8]
     STRD    R6, R7, [R1], #16

     AND     R9, R11, R5, LSR #23	;pixels 22,23
     AND     R7, R11, R5, LSR #22
     LDR     R9, [R12, R9, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     MOV     R8, R9			;duplicate pixels
     MOV     R6, R7
     STRD    R8, R9, [R1, #8]
     STRD    R6, R7, [R1], #16

     AND     R9, R11, R5, LSR #25	;pixels 24,25
     AND     R7, R11, R5, LSR #24
     LDR     R9, [R12, R9, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     MOV     R8, R9			;duplicate pixels
     MOV     R6, R7
     STRD    R8, R9, [R1, #8]
     STRD    R6, R7, [R1], #16

     AND     R9, R11, R5, LSR #27	;pixels 26,27
     AND     R7, R11, R5, LSR #26
     LDR     R9, [R12, R9, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     MOV     R8, R9			;duplicate pixels
     MOV     R6, R7
     STRD    R8, R9, [R1, #8]
     STRD    R6, R7, [R1], #16

     AND     R9, R11, R5, LSR #29	;pixels 28,29
     AND     R7, R11, R5, LSR #28
     LDR     R9, [R12, R9, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     MOV     R8, R9			;duplicate pixels
     MOV     R6, R7
     STRD    R8, R9, [R1, #8]
     STRD    R6, R7, [R1], #16

     AND     R9, R11, R5, LSR #31	;pixels 30,31
     AND     R7, R11, R5, LSR #30
     LDR     R9, [R12, R9, LSL #2]	;load palette entries
     LDR     R7, [R12, R7, LSL #2]
     MOV     R8, R9			;duplicate pixels
     MOV     R6, R7
     STRD    R8, R9, [R1, #8]
     STRD    R6, R7, [R1], #16
   #endif
 #endif

 CMP     R0, R10			;have we hit Vend?
 BHS     _hit_vEnd			;YES

 SUBS    R4, R4, #1 << (pix_byte + 2)
MOV    PC, R14

 ._hit_vEnd
 MVN     R10, #0			;ignore Vend from now on
 LDR     R0, MEMC_Vstart		;and resume from Vstart

 #if compile_DEBUG == 1
   MVN   R6, #0				;RED bar indicated screen wrap
   STR   R6, [R1, #-4]
   STR   R6, [R1, #-8]
   STR   R6, [R1, #-12]
   STR   R6, [R1, #-16]
 #endif

 SUBS    R4, R4, #1 << (pix_byte + 2)
 BGT     _blit_vstart_loop		;loop back to correct byte alignment
MOV   PC, R14				;continue if no more pixels on raster
}
