;
; X86 fakemode routines for DOS PTC
; Copyright (c) 1998 Glenn Fiedler (ptc@gaffer.org)
; Adapted for use in PTC 2.0 C++ API by Jonathan Matthew (jmatthew@uq.net.au)
; This source code is licensed under the GNU LGPL
;

BITS 32

GLOBAL _PlaneBlt1_RGB
GLOBAL _PlaneBlt1_RBG
GLOBAL _PlaneBlt1_GRB
GLOBAL _PlaneBlt2_RBG
GLOBAL _PlaneBlt2_GBR
GLOBAL _PlaneBlt3_RGBRGB
GLOBAL _PlaneBlt3_GRBGRB
GLOBAL _PlaneBlt3_RBGRBG
GLOBAL _PlaneBlt3_GRBRBG
GLOBAL _PlaneBlt3_RBGGRB
GLOBAL _PlaneBlt3_RGBR
GLOBAL _PlaneBlt3_GRBG
GLOBAL _PlaneBlt3_RBGR
GLOBAL _PlaneBlt3_GRBR
GLOBAL _PlaneBlt3_RBGG

SECTION .text

;; Parameters:
;; eax - source (moved to esi)
;; edx - dest (moved to edi)
;; ecx - # rows (moved to edx)
;; returns updated dest in eax
;; (that's all because of DJGPP)

_PlaneBlt1_RGB:

    push    ebp
    push    esi
    push    edi
    push    ebx
    mov     esi, eax
    mov     edi, edx
    mov     edx, ecx

.L1     mov     ebp, 20
        push    edx

.L2         mov     cl, [esi]                   ; ECX = greens (low 3 bits)
            mov     ch, [esi+8]
            shl     ecx, 16
            mov     cl, [esi+8+8]
            mov     ch, [esi+8+8+8]
            mov     ebx, ecx                    ; EBX = blues
            and     ecx, 11100000111000001110000011100000b
            ror     ecx, 16+5

            mov     dl, [esi+1]                 ; EDX = greens (high 3 bits)
            mov     dh, [esi+8+1]
            shl     edx, 16
            mov     dl, [esi+8+8+1]
            mov     dh, [esi+8+8+8+1]
            mov     eax, edx                    ; EAX = reds
            and     edx, 00000111000001110000011100000111b
            ror     edx, 16-3

            and     ebx, 00011111000111110001111100011111b
            ror     ebx, 15
            add     ebx, 80808080h

            and     eax, 11111000111110001111100011111000b
            ror     eax, 16+2

            add     ecx, edx
            add     ecx, 40404040h

            mov     [edi], eax
            mov     [edi+80], ecx
            mov     [edi+160], ebx

            add     edi, 4
            add     esi, 4*4*2

            dec     ebp
            jnz     .L2

        pop     edx
        add     edi, 160

        dec     edx
        jnz     .L1

.L3
    mov     eax, edi
    pop     ebx
    pop     edi
    pop     esi
    pop     ebp
    ret

_PlaneBlt1_RBG:

    push    ebp
    push    esi
    push    edi
    push    ebx
    mov     esi, eax
    mov     edi, edx
    mov     edx, ecx

.L1     mov     ebp,20
        push    edx

.L2         mov     cl,[esi]                                    ; ECX = greens (low 3 bits)
            mov     ch,[esi+8]
            shl     ecx,16
            mov     cl,[esi+8+8]
            mov     ch,[esi+8+8+8]
            mov     ebx,ecx                                     ; setup blues in ebx
            and     ecx,11100000111000001110000011100000b
            ror     ecx,16+5

            mov     dl,[esi+1]                                  ; EDX = greens (high 3 bits)
            mov     dh,[esi+8+1]
            shl     edx,16
            mov     dl,[esi+8+8+1]
            mov     dh,[esi+8+8+8+1]
            mov     eax,edx                                     ; setup reds in eax
            and     edx,00000111000001110000011100000111b
            ror     edx,16-3
   
            and     ebx,00011111000111110001111100011111b       ; EBX = blues
            ror     ebx,15
            add     ebx,80808080h

            and     eax,11111000111110001111100011111000b       ; EAX = reds
            ror     eax,16+2

            add     ecx,edx                                     ; ECX = green(lo)+green(hi)
            add     ecx,40404040h

            mov     [edi],eax
            mov     [edi+160],ecx
            mov     [edi+80],ebx

            add     edi,4
            add     esi,4*4*2

            dec     ebp
            jnz     .L2

        pop     edx
        add     edi,160

        dec     edx
        jnz     .L1

.L3
    mov     eax, edi
    pop     ebx
    pop     edi
    pop     esi
    pop     ebp
    ret

_PlaneBlt1_GRB:

    push    ebp
    push    esi
    push    edi
    push    ebx
    mov     esi, eax
    mov     edi, edx
    mov     edx, ecx

.L1     mov     ebp,20
        push    edx

.L2         mov     cl,[esi]                                    ; ECX = greens (low 3 bits)
            mov     ch,[esi+8]
            shl     ecx,16
            mov     cl,[esi+8+8]
            mov     ch,[esi+8+8+8]
            mov     ebx,ecx                                     ; setup blues in ebx
            and     ecx,11100000111000001110000011100000b
            ror     ecx,16+5

            mov     dl,[esi+1]                                  ; EDX = greens (high 3 bits)
            mov     dh,[esi+8+1]
            shl     edx,16
            mov     dl,[esi+8+8+1]
            mov     dh,[esi+8+8+8+1]
            mov     eax,edx                                     ; setup reds in eax
            and     edx,00000111000001110000011100000111b
            ror     edx,16-3
   
            and     ebx,00011111000111110001111100011111b       ; EBX = blues
            ror     ebx,15
            add     ebx,80808080h

            and     eax,11111000111110001111100011111000b       ; EAX = reds
            ror     eax,16+2

            add     ecx,edx                                     ; ECX = green(lo)+green(hi)
            add     ecx,40404040h

            mov     [edi+80],eax
            mov     [edi],ecx
            mov     [edi+160],ebx

            add     edi,4
            add     esi,4*4*2

            dec     ebp
            jnz     .L2

        pop     edx
        add     edi,160

        dec     edx
        jnz     .L1

.L3
    mov     eax, edi
    pop     ebx
    pop     edi
    pop     esi
    pop     ebp
    ret


_PlaneBlt2_RBG:

    push    ebp
    push    esi
    push    edi
    push    ebx
    mov     esi, eax
    mov     edi, edx
    mov     edx, ecx

.L1     mov     ebp, 20
        push    edx

.L2         mov     cl, [esi]
            mov     ch, [esi+8]
            shl     ecx, 16
            mov     cl, [esi+16]
            mov     ch, [esi+24]            ; low greens in ecx
            mov     ebx, ecx                ; blues in ebx
            and     ecx, 0c0c0c0c0h
            ror     ecx, 16+6

            mov     dl, [esi+1]
            mov     dh, [esi+9]
            shl     edx, 16
            mov     dl, [esi+17]
            mov     dh, [esi+25]            ; high greens in edx
            mov     eax, edx                ; reds in eax
            and     edx, 07070707h
            ror     edx, 16-2

            and     ebx, 1c1c1c1ch
            ror     ebx, 16+2

            and     eax, 0f0f0f0f0h
            ror     eax, 16+1

            add     eax, ebx                ; eax = red+blue
            add     ecx, edx                ; ecx = green

            or      ecx, 80808080h

            mov     [edi], eax
            mov     [edi+80], ecx

            add     esi, 4*4*2
            add     edi, 4

            dec     ebp
            jnz     .L2

        pop     edx
        add     edi, 80

        dec     edx
        jnz     .L1

.L3
    mov     eax, edi
    pop     ebx
    pop     edi
    pop     esi
    pop     ebp
    ret


_PlaneBlt2_GBR:

    push    ebp
    push    esi
    push    edi
    push    ebx
    mov     esi, eax
    mov     edi, edx
    mov     edx, ecx

.L1     mov     ebp, 20
        push    edx

.L2         mov     cl, [esi]
            mov     ch, [esi+8]
            shl     ecx, 16
            mov     cl, [esi+16]
            mov     ch, [esi+24]            ; low greens in ecx
            mov     ebx, ecx                ; blues in ebx
            and     ecx, 0c0c0c0c0h
            ror     ecx, 16+6

            mov     dl, [esi+1]
            mov     dh, [esi+9]
            shl     edx, 16
            mov     dl, [esi+17]
            mov     dh, [esi+25]            ; high greens in edx
            mov     eax, edx                ; reds in eax
            and     edx, 07070707h
            ror     edx, 16-2

            and     ebx, 1c1c1c1ch
            ror     ebx, 16+2

            and     eax, 0f0f0f0f0h
            ror     eax, 16+1

            add     eax, ebx                ; eax = red+blue
            add     ecx, edx                ; ecx = green

            or      ecx, 80808080h

            mov     [edi], ecx
            mov     [edi+80], eax

            add     esi, 4*4*2
            add     edi, 4

            dec     ebp
            jnz     .L2

        pop     edx
        add     edi, 80

        dec     edx
        jnz     .L1

.L3
    mov     eax, edi
    pop     ebx
    pop     edi
    pop     esi
    pop     ebp
    ret


_PlaneBlt3_RGBRGB:

    push ebp
    push    esi
    push    edi
    push    ebx
    mov     esi, eax
    mov     edi, edx
    mov     edx, ecx

.L1     mov ebp,20
        push edx

.L2         ; 1st pixel [0r,0g,1b]

            mov cl,[esi]                                    ; ECX = greens (low 3 bits)
            mov ch,[esi+8]
            shl ecx,16
            mov cl,[esi+8+8]
            mov ch,[esi+8+8+8]
            and ecx,11100000111000001110000011100000b
            ror ecx,16+5

            mov dl,[esi+1]                                  ; EDX = greens (high 3 bits)
            mov dh,[esi+8+1]
            shl edx,16
            mov dl,[esi+8+8+1]
            mov dh,[esi+8+8+8+1]
            mov eax,edx                                     ; setup reds in eax
            and edx,00000111000001110000011100000111b
            ror edx,16-3
   
            mov bl,[esi+320*2]                              ; EBX = blues
            mov bh,[esi+8+320*2]
            shl ebx,16
            mov bl,[esi+8+8+320*2]
            mov bh,[esi+8+8+8+320*2]
            and ebx,00011111000111110001111100011111b       
            ror ebx,15
            add ebx,80808080h

            and eax,11111000111110001111100011111000b       ; EAX = reds
            ror eax,16+2

            add ecx,edx                                     ; ECX = green(lo)+green(hi)
            add ecx,40404040h

            mov [edi],eax
            mov [edi+80],ecx
            mov [edi+160],ebx

            ; 2nd pixel [1r,2g,2b]

            mov al,[esi+1+320*2]                            ; EAX = reds
            mov ah,[esi+8+1+320*2]
            shl eax,16
            mov al,[esi+8+8+1+320*2]
            mov ah,[esi+8+8+8+1+320*2]
            and eax,11111000111110001111100011111000b
            ror eax,16+2

            mov cl,[esi+640*2]                              ; ECX = greens (low 3 bits)
            mov ch,[esi+8+640*2]
            shl ecx,16
            mov cl,[esi+8+8+640*2]
            mov ch,[esi+8+8+8+640*2]
            mov ebx,ecx                                     ; setup blues in ebx
            and ecx,11100000111000001110000011100000b
            ror ecx,16+5

            mov dl,[esi+1+640*2]                            ; EDX = greens (high 3 bits)
            mov dh,[esi+8+1+640*2]
            shl edx,16
            mov dl,[esi+8+8+1+640*2]
            mov dh,[esi+8+8+8+1+640*2]
            and edx,00000111000001110000011100000111b
            ror edx,16-3
   
            and ebx,00011111000111110001111100011111b       ; EBX = blues
            ror ebx,15
            add ebx,80808080h

            add ecx,edx                                     ; ECX = green(lo)+green(hi)
            add ecx,40404040h

            mov [edi+240],eax
            mov [edi+240+80],ecx
            mov [edi+240+160],ebx

            add edi,4
            add esi,4*4*2

            dec ebp
            jz .L3
            jmp .L2

.L3     pop edx
        add edi,320+80
        add esi,320*2*2

        dec edx
        jz .L4
        jmp .L1

.L4
    mov     eax, edi
    pop     ebx
    pop     edi
    pop     esi
    pop ebp
    ret


_PlaneBlt3_GRBGRB:

    push ebp
    push    esi
    push    edi
    push    ebx
    mov     esi, eax
    mov     edi, edx
    mov     edx, ecx

.L1     mov ebp,20
        push edx

.L2         ; 1st pixel [0g,0r,1b]

            mov cl,[esi]                                    ; ECX = greens (low 3 bits)
            mov ch,[esi+8]
            shl ecx,16
            mov cl,[esi+8+8]
            mov ch,[esi+8+8+8]
            and ecx,11100000111000001110000011100000b
            ror ecx,16+5

            mov dl,[esi+1]                                  ; EDX = greens (high 3 bits)
            mov dh,[esi+8+1]
            shl edx,16
            mov dl,[esi+8+8+1]
            mov dh,[esi+8+8+8+1]
            mov eax,edx                                     ; setup reds in eax
            and edx,00000111000001110000011100000111b
            ror edx,16-3
   
            mov bl,[esi+320*2]                              ; EBX = blues
            mov bh,[esi+8+320*2]
            shl ebx,16
            mov bl,[esi+8+8+320*2]
            mov bh,[esi+8+8+8+320*2]
            and ebx,00011111000111110001111100011111b       
            ror ebx,15
            add ebx,80808080h

            and eax,11111000111110001111100011111000b       ; EAX = reds
            ror eax,16+2

            add ecx,edx                                     ; ECX = green(lo)+green(hi)
            add ecx,40404040h

            mov [edi],ecx        ; G0
            mov [edi+80],eax     ; R0    
            mov [edi+160],ebx    ; B1

            ; 2nd pixel [1g,2r,2b]

            mov al,[esi+1+640*2]                            ; EAX = reds
            mov ah,[esi+8+1+640*2]
            shl eax,16
            mov al,[esi+8+8+1+640*2]
            mov ah,[esi+8+8+8+1+640*2]
            and eax,11111000111110001111100011111000b
            ror eax,16+2

            mov cl,[esi+320*2]                              ; ECX = greens (low 3 bits)
            mov ch,[esi+8+320*2]
            shl ecx,16
            mov cl,[esi+8+8+320*2]
            mov ch,[esi+8+8+8+320*2]
            and ecx,11100000111000001110000011100000b
            ror ecx,16+5

            mov dl,[esi+1+320*2]                            ; EDX = greens (high 3 bits)
            mov dh,[esi+8+1+320*2]
            shl edx,16
            mov dl,[esi+8+8+1+320*2]
            mov dh,[esi+8+8+8+1+320*2]
            and edx,00000111000001110000011100000111b       
            ror edx,16-3

            mov bl,[esi+640*2]                              ; EBX = blues
            mov bh,[esi+8+640*2]
            shl ebx,16
            mov bl,[esi+8+8+640*2]
            mov bh,[esi+8+8+8+640*2]
            and ebx,00011111000111110001111100011111b       
            ror ebx,15
            add ebx,80808080h

            add ecx,edx                                     ; ECX = green(lo)+green(hi)
            add ecx,40404040h

            mov [edi+240],ecx      ; G1
            mov [edi+240+80],eax   ; R2   
            mov [edi+240+160],ebx  ; B2

            add edi,4
            add esi,4*4*2

            dec ebp
            jz .L3
            jmp .L2

.L3     pop edx
        add edi,320+80
        add esi,320*2*2

        dec edx
        jz .L4
        jmp .L1

.L4
    mov     eax, edi
    pop     ebx
    pop     edi
    pop     esi
    pop ebp
    ret


_PlaneBlt3_RBGRBG:

    push ebp
    push    esi
    push    edi
    push    ebx
    mov     esi, eax
    mov     edi, edx
    mov     edx, ecx

.L1     mov ebp,20
        push edx

.L2         ; 1st pixel [0r,0b,1g]

            mov bl,[esi]                                    ; EBX = blues
            mov bh,[esi+8]
            shl ebx,16
            mov bl,[esi+8+8]
            mov bh,[esi+8+8+8]
            and ebx,00011111000111110001111100011111b       
            ror ebx,15
            add ebx,80808080h

            mov al,[esi+1]                                  ; EAX = reds
            mov ah,[esi+8+1]
            shl eax,16
            mov al,[esi+8+8+1]
            mov ah,[esi+8+8+8+1]
            and eax,11111000111110001111100011111000b       
            ror eax,16+2

            mov cl,[esi+320*2]                              ; ECX = greens (low 3 bits)
            mov ch,[esi+8+320*2]
            shl ecx,16
            mov cl,[esi+8+8+320*2]
            mov ch,[esi+8+8+8+320*2]
            and ecx,11100000111000001110000011100000b
            ror ecx,16+5

            mov [edi],eax       ; R0
            
            mov dl,[esi+1+320*2]                            ; EDX = greens (high 3 bits)
            mov dh,[esi+8+1+320*2]
            shl edx,16
            mov dl,[esi+8+8+1+320*2]
            mov dh,[esi+8+8+8+1+320*2]
            mov eax,edx                                     ; setup eax = r1
            and edx,00000111000001110000011100000111b
            ror edx,16-3
   
            add ecx,edx                                     ; ECX = green(lo)+green(hi)
            add ecx,40404040h

            mov [edi+80],ebx    ; B0
            mov [edi+160],ecx   ; G1

            ; 2nd pixel [1r,2b,2g]

            and eax,11111000111110001111100011111000b
            ror eax,16+2

            mov cl,[esi+640*2]                              ; ECX = greens (low 3 bits)
            mov ch,[esi+8+640*2]
            shl ecx,16
            mov cl,[esi+8+8+640*2]
            mov ch,[esi+8+8+8+640*2]
            mov ebx,ecx                                     ; setup blues in ebx
            and ecx,11100000111000001110000011100000b
            ror ecx,16+5

            mov dl,[esi+1+640*2]                            ; EDX = greens (high 3 bits)
            mov dh,[esi+8+1+640*2]
            shl edx,16
            mov dl,[esi+8+8+1+640*2]
            mov dh,[esi+8+8+8+1+640*2]
            and edx,00000111000001110000011100000111b
            ror edx,16-3
   
            and ebx,00011111000111110001111100011111b       ; EBX = blues
            ror ebx,15
            add ebx,80808080h

            add ecx,edx                                     ; ECX = green(lo)+green(hi)
            add ecx,40404040h

            mov [edi+240],eax      ; R1
            mov [edi+240+80],ebx   ; B2
            mov [edi+240+160],ecx  ; G2

            add edi,4
            add esi,4*4*2

            dec ebp
            jz .L3
            jmp .L2

.L3     pop edx
        add edi,320+80
        add esi,320*2*2

        dec edx
        jz .L4
        jmp .L1

.L4
    mov     eax, edi
    pop     ebx
    pop     edi
    pop     esi
    pop ebp
    ret


_PlaneBlt3_GRBRBG:

    push ebp
    push    esi
    push    edi
    push    ebx
    mov     esi, eax
    mov     edi, edx
    mov     edx, ecx

.L1     mov ebp,20
        push edx

.L2         ; 1st pixel [0g,0r,1b]

            mov cl,[esi]                                    ; ECX = greens (low 3 bits)
            mov ch,[esi+8]
            shl ecx,16
            mov cl,[esi+8+8]
            mov ch,[esi+8+8+8]
            and ecx,11100000111000001110000011100000b
            ror ecx,16+5

            mov dl,[esi+1]                                  ; EDX = greens (high 3 bits)
            mov dh,[esi+8+1]
            shl edx,16
            mov dl,[esi+8+8+1]
            mov dh,[esi+8+8+8+1]
            mov eax,edx                                     ; setup reds in eax
            and edx,00000111000001110000011100000111b
            ror edx,16-3
   
            mov bl,[esi+320*2]                              ; EBX = blues
            mov bh,[esi+8+320*2]
            shl ebx,16
            mov bl,[esi+8+8+320*2]
            mov bh,[esi+8+8+8+320*2]
            and ebx,00011111000111110001111100011111b       
            ror ebx,15
            add ebx,80808080h

            and eax,11111000111110001111100011111000b       ; EAX = reds
            ror eax,16+2

            add ecx,edx                                     ; ECX = green(lo)+green(hi)
            add ecx,40404040h

            mov [edi],ecx        ; G0
            mov [edi+80],eax     ; R0    
            mov [edi+160],ebx    ; B1

            ; 2nd pixel [1r,2b,2g]

            mov al,[esi+1+320*2]                            ; EAX = reds
            mov ah,[esi+8+1+320*2]
            shl eax,16
            mov al,[esi+8+8+1+320*2]
            mov ah,[esi+8+8+8+1+320*2]
            and eax,11111000111110001111100011111000b
            ror eax,16+2

            mov cl,[esi+640*2]                              ; ECX = greens (low 3 bits)
            mov ch,[esi+8+640*2]
            shl ecx,16
            mov cl,[esi+8+8+640*2]
            mov ch,[esi+8+8+8+640*2]
            mov ebx,ecx                                     ; setup ebx = blues
            and ecx,11100000111000001110000011100000b
            ror ecx,16+5

            mov dl,[esi+1+640*2]                            ; EDX = greens (high 3 bits)
            mov dh,[esi+8+1+640*2]
            shl edx,16
            mov dl,[esi+8+8+1+640*2]
            mov dh,[esi+8+8+8+1+640*2]
            and edx,00000111000001110000011100000111b       
            ror edx,16-3
   
            and ebx,00011111000111110001111100011111b       ; EBX = blues
            ror ebx,15
            add ebx,80808080h

            add ecx,edx                                     ; ECX = green(lo)+green(hi)
            add ecx,40404040h

            mov [edi+240],eax       ; R1   
            mov [edi+240+80],ebx    ; B2
            mov [edi+240+160],ecx   ; G2

            add edi,4
            add esi,4*4*2

            dec ebp
            jz .L3
            jmp .L2

.L3     pop edx
        add edi,320+80
        add esi,320*2*2

        dec edx
        jz .L4
        jmp .L1

.L4
    mov     eax, edi
    pop     ebx
    pop     edi
    pop     esi
    pop ebp
    ret


_PlaneBlt3_RBGGRB:

    push ebp
    push    esi
    push    edi
    push    ebx
    mov     esi, eax
    mov     edi, edx
    mov     edx, ecx

.L1     mov ebp,20
        push edx

.L2         ; 1st pixel [0r,0b,1g]

            mov bl,[esi]                                    ; EBX = blues
            mov bh,[esi+8]
            shl ebx,16
            mov bl,[esi+8+8]
            mov bh,[esi+8+8+8]
            and ebx,00011111000111110001111100011111b       
            ror ebx,15
            add ebx,80808080h

            mov al,[esi+1]                                  ; EAX = reds
            mov ah,[esi+8+1]
            shl eax,16
            mov al,[esi+8+8+1]
            mov ah,[esi+8+8+8+1]
            and eax,11111000111110001111100011111000b       
            ror eax,16+2

            mov [edi+80],ebx    ; B0

            mov dl,[esi+1+320*2]                            ; EDX = greens (high 3 bits)
            mov dh,[esi+8+1+320*2]
            shl edx,16
            mov dl,[esi+8+8+1+320*2]
            mov dh,[esi+8+8+8+1+320*2]
            mov ebx,edx                                     ; setup ebx = g1 (hi)
            and edx,00000111000001110000011100000111b
            ror edx,16-3

            mov [edi],eax       ; R0

            mov cl,[esi+320*2]                              ; ECX = greens (low 3 bits)
            mov ch,[esi+8+320*2]
            shl ecx,16
            mov cl,[esi+8+8+320*2]
            mov ch,[esi+8+8+8+320*2]
            mov eax,ecx                                     ; setup eax = g1 (lo)
            and ecx,11100000111000001110000011100000b
            ror ecx,16+5
   
            add ecx,edx                                     ; ECX = green(lo)+green(hi)
            add ecx,40404040h

            mov [edi+160],ecx   ; G1

            ; 2nd pixel [1g,2r,2b]

            mov ecx,eax                                     ; ECX = greens (low 3 bits)
            and ecx,11100000111000001110000011100000b
            ror ecx,16+5

            mov edx,ebx                                     ; EDX = greens (hi 3 bits)
            and edx,00000111000001110000011100000111b
            ror edx,16-3
   
            mov al,[esi+1+640*2]                            ; EAX = reds
            mov ah,[esi+8+1+640*2]
            shl eax,16
            mov al,[esi+8+8+1+640*2]
            mov ah,[esi+8+8+8+1+640*2]
            and eax,11111000111110001111100011111000b       
            ror eax,16+2

            mov bl,[esi+640*2]                              ; EBX = blues
            mov bh,[esi+8+640*2]
            shl ebx,16
            mov bl,[esi+8+8+640*2]
            mov bh,[esi+8+8+8+640*2]
            and ebx,00011111000111110001111100011111b
            ror ebx,15
            add ebx,80808080h

            add ecx,edx                                     ; ECX = green(lo)+green(hi)
            add ecx,40404040h

            mov [edi+240],ecx       ; G1
            mov [edi+240+80],eax    ; R2
            mov [edi+240+160],ebx   ; B2

            add edi,4
            add esi,4*4*2

            dec ebp
            jz .L3
            jmp .L2

.L3     pop edx
        add edi,320+80
        add esi,320*2*2

        dec edx
        jz .L4
        jmp .L1

.L4
    mov     eax, edi
    pop     ebx
    pop     edi
    pop     esi
    pop ebp
    ret


_PlaneBlt3_RGBR:

    push ebp
    push    esi
    push    edi
    push    ebx
    mov     esi, eax
    mov     edi, edx
    mov     edx, ecx

    mov ebp,20

.L1     mov cl,[esi]                                    ; ECX = greens (low 3 bits)
        mov ch,[esi+8]
        shl ecx,16
        mov cl,[esi+8+8]
        mov ch,[esi+8+8+8]
        and ecx,11100000111000001110000011100000b
        ror ecx,16+5

        mov dl,[esi+1]                                  ; EDX = greens (high 3 bits)
        mov dh,[esi+8+1]
        shl edx,16
        mov dl,[esi+8+8+1]
        mov dh,[esi+8+8+8+1]
        mov eax,edx                                     ; setup reds in eax
        and edx,00000111000001110000011100000111b
        ror edx,16-3
   
        mov bl,[esi+320*2]                              ; EBX = blues
        mov bh,[esi+8+320*2]
        shl ebx,16
        mov bl,[esi+8+8+320*2]
        mov bh,[esi+8+8+8+320*2]
        and ebx,00011111000111110001111100011111b       
        ror ebx,15
        add ebx,80808080h

        and eax,11111000111110001111100011111000b       ; EAX = reds
        ror eax,16+2

        add ecx,edx                                     ; ECX = green(lo)+green(hi)
        add ecx,40404040h

        mov [edi],eax
        mov [edi+80],ecx
        mov [edi+160],ebx

        mov al,[esi+1+320*2]                            ; EAX = reds
        mov ah,[esi+8+1+320*2]
        shl eax,16
        mov al,[esi+8+8+1+320*2]
        mov ah,[esi+8+8+8+1+320*2]
        and eax,11111000111110001111100011111000b
        ror eax,16+2

        mov [edi+240],eax

        add edi,4
        add esi,4*4*2

        dec ebp
        jz .L2
        jmp .L1

.L2
    mov     eax, edi
    pop     ebx
    pop     edi
    pop     esi
    pop ebp
    ret


_PlaneBlt3_GRBG:

    push ebp
    push    esi
    push    edi
    push    ebx
    mov     esi, eax
    mov     edi, edx
    mov     edx, ecx
    mov ebp,20

.L1     mov cl,[esi]                                    ; ECX = greens (low 3 bits)
        mov ch,[esi+8]
        shl ecx,16
        mov cl,[esi+8+8]
        mov ch,[esi+8+8+8]
        and ecx,11100000111000001110000011100000b
        ror ecx,16+5

        mov dl,[esi+1]                                  ; EDX = greens (high 3 bits)
        mov dh,[esi+8+1]
        shl edx,16
        mov dl,[esi+8+8+1]
        mov dh,[esi+8+8+8+1]
        mov eax,edx                                     ; setup reds in eax
        and edx,00000111000001110000011100000111b
        ror edx,16-3
   
        mov bl,[esi+320*2]                              ; EBX = blues
        mov bh,[esi+8+320*2]
        shl ebx,16
        mov bl,[esi+8+8+320*2]
        mov bh,[esi+8+8+8+320*2]
        and ebx,00011111000111110001111100011111b       
        ror ebx,15
        add ebx,80808080h

        and eax,11111000111110001111100011111000b       ; EAX = reds
        ror eax,16+2

        add ecx,edx                                     ; ECX = green(lo)+green(hi)
        add ecx,40404040h

        mov [edi],ecx        ; G0
        mov [edi+80],eax     ; R0    
        mov [edi+160],ebx    ; B1

        mov cl,[esi+320*2]                              ; ECX = greens (low 3 bits)
        mov ch,[esi+8+320*2]
        shl ecx,16
        mov cl,[esi+8+8+320*2]
        mov ch,[esi+8+8+8+320*2]
        and ecx,11100000111000001110000011100000b
        ror ecx,16+5
                                                        
        mov dl,[esi+1+320*2]                            ; EDX = greens (high 3 bits)
        mov dh,[esi+8+1+320*2]
        shl edx,16
        mov dl,[esi+8+8+1+320*2]
        mov dh,[esi+8+8+8+1+320*2]
        and edx,00000111000001110000011100000111b       
        ror edx,16-3
   
        add ecx,edx                                     ; ECX = green(lo)+green(hi)
        add ecx,40404040h

        mov [edi+240],ecx      ; G1

        add edi,4
        add esi,4*4*2

        dec ebp
        jz .L2
        jmp .L1

.L2
    mov     eax, edi
    pop     ebx
    pop     edi
    pop     esi
    pop ebp
    ret


_PlaneBlt3_RBGR:

    push ebp
    push    esi
    push    edi
    push    ebx
    mov     esi, eax
    mov     edi, edx
    mov     edx, ecx
    mov ebp,20

.L1     mov bl,[esi]                                    ; EBX = blues
        mov bh,[esi+8]
        shl ebx,16
        mov bl,[esi+8+8]
        mov bh,[esi+8+8+8]
        and ebx,00011111000111110001111100011111b       
        ror ebx,15
        add ebx,80808080h

        mov al,[esi+1]                                  ; EAX = reds
        mov ah,[esi+8+1]
        shl eax,16
        mov al,[esi+8+8+1]
        mov ah,[esi+8+8+8+1]
        and eax,11111000111110001111100011111000b       
        ror eax,16+2
    
        mov cl,[esi+320*2]                              ; ECX = greens (low 3 bits)
        mov ch,[esi+8+320*2]
        shl ecx,16
        mov cl,[esi+8+8+320*2]
        mov ch,[esi+8+8+8+320*2]
        and ecx,11100000111000001110000011100000b
        ror ecx,16+5

        mov [edi],eax       ; R0

        mov dl,[esi+1+320*2]                            ; EDX = greens (high 3 bits)
        mov dh,[esi+8+1+320*2]
        shl edx,16
        mov dl,[esi+8+8+1+320*2]
        mov dh,[esi+8+8+8+1+320*2]
        mov eax,edx                                     ; setup eax = r1
        and edx,00000111000001110000011100000111b
        ror edx,16-3
   
        add ecx,edx                                     ; ECX = green(lo)+green(hi)
        add ecx,40404040h

        mov [edi+80],ebx    ; B0
        mov [edi+160],ecx   ; G1

        and eax,11111000111110001111100011111000b
        ror eax,16+2

        mov [edi+240],eax      ; R1

        add edi,4
        add esi,4*4*2

        dec ebp
        jz .L2
        jmp .L1

.L2
    mov     eax, edi
    pop     ebx
    pop     edi
    pop     esi
    pop ebp
    ret


_PlaneBlt3_GRBR:

    push ebp
    push    esi
    push    edi
    push    ebx
    mov     esi, eax
    mov     edi, edx
    mov     edx, ecx
    mov ebp,20

.L1     mov cl,[esi]                                    ; ECX = greens (low 3 bits)
        mov ch,[esi+8]
        shl ecx,16
        mov cl,[esi+8+8]
        mov ch,[esi+8+8+8]
        and ecx,11100000111000001110000011100000b
        ror ecx,16+5

        mov dl,[esi+1]                                  ; EDX = greens (high 3 bits)
        mov dh,[esi+8+1]
        shl edx,16
        mov dl,[esi+8+8+1]
        mov dh,[esi+8+8+8+1]
        mov eax,edx                                     ; setup reds in eax
        and edx,00000111000001110000011100000111b
        ror edx,16-3
   
        mov bl,[esi+320*2]                              ; EBX = blues
        mov bh,[esi+8+320*2]
        shl ebx,16
        mov bl,[esi+8+8+320*2]
        mov bh,[esi+8+8+8+320*2]
        and ebx,00011111000111110001111100011111b       
        ror ebx,15
        add ebx,80808080h

        and eax,11111000111110001111100011111000b       ; EAX = reds
        ror eax,16+2

        add ecx,edx                                     ; ECX = green(lo)+green(hi)
        add ecx,40404040h

        mov [edi],ecx        ; G0
        mov [edi+80],eax     ; R0    
        mov [edi+160],ebx    ; B1

        mov al,[esi+1+320*2]                            ; EAX = reds
        mov ah,[esi+8+1+320*2]
        shl eax,16
        mov al,[esi+8+8+1+320*2]
        mov ah,[esi+8+8+8+1+320*2]
        and eax,11111000111110001111100011111000b
        ror eax,16+2

        mov [edi+240],eax       ; R1   

        add edi,4
        add esi,4*4*2

        dec ebp
        jz .L2
        jmp .L1

.L2
    mov     eax, edi
    pop     ebx
    pop     edi
    pop     esi
    pop ebp
    ret


_PlaneBlt3_RBGG:

    push ebp
    push    esi
    push    edi
    push    ebx
    mov     esi, eax
    mov     edi, edx
    mov     edx, ecx
    mov ebp,20

.L1     mov bl,[esi]                                    ; EBX = blues
        mov bh,[esi+8]
        shl ebx,16
        mov bl,[esi+8+8]
        mov bh,[esi+8+8+8]
        and ebx,00011111000111110001111100011111b       
        ror ebx,15
        add ebx,80808080h

        mov al,[esi+1]                                  ; EAX = reds
        mov ah,[esi+8+1]
        shl eax,16
        mov al,[esi+8+8+1]
        mov ah,[esi+8+8+8+1]
        and eax,11111000111110001111100011111000b       
        ror eax,16+2

        mov [edi+80],ebx    ; B0
   
        mov dl,[esi+1+320*2]                            ; EDX = greens (high 3 bits)
        mov dh,[esi+8+1+320*2]
        shl edx,16
        mov dl,[esi+8+8+1+320*2]
        mov dh,[esi+8+8+8+1+320*2]
        mov ebx,edx                                     ; setup ebx = g1 (hi)
        and edx,00000111000001110000011100000111b
        ror edx,16-3

        mov [edi],eax       ; R0

        mov cl,[esi+320*2]                              ; ECX = greens (low 3 bits)
        mov ch,[esi+8+320*2]
        shl ecx,16
        mov cl,[esi+8+8+320*2]
        mov ch,[esi+8+8+8+320*2]
        mov eax,ecx                                     ; setup eax = g1 (lo)
        and ecx,11100000111000001110000011100000b
        ror ecx,16+5
   
        add ecx,edx                                     ; ECX = green(lo)+green(hi)
        add ecx,40404040h

        mov [edi+160],ecx   ; G1

        mov ecx,eax                                     ; ECX = greens (low 3 bits)
        and ecx,11100000111000001110000011100000b
        ror ecx,16+5

        mov edx,ebx                                     ; EDX = greens (hi 3 bits)
        and edx,00000111000001110000011100000111b
        ror edx,16-3

        add ecx,edx                                     ; ECX = green(lo)+green(hi)
        add ecx,40404040h

        mov [edi+240],ecx       ; G1

        add edi,4
        add esi,4*4*2

        dec ebp
        jz .L2
        jmp .L1

.L2
    mov     eax, edi
    pop     ebx
    pop     edi
    pop     esi
    pop ebp
    ret

