;*DDK*************************************************************************/
;
; COPYRIGHT (C) Microsoft Corporation, 1989
; COPYRIGHT    Copyright (C) 1995 IBM Corporation
;
;    The following IBM OS/2 WARP source code is provided to you solely for
;    the purpose of assisting you in your development of OS/2 WARP device
;    drivers. You may use this code in accordance with the IBM License
;    Agreement provided in the IBM Device Driver Source Kit for OS/2. This
;    Copyright statement may not be removed.;
;*****************************************************************************/
;/*****************************************************************************
;*
;* SOURCE FILE NAME = EDDBPHNK.ASM
;*
;* DESCRIPTIVE NAME = Phunk area routines
;*
;*
;* VERSION      V2.0
;*
;* DATE
;*
;* DESCRIPTION Display Device Driver functions supporting BitBlt for SDBM20
;*             blting between system memory bitmaps and VRAM
;*
;*
;* FUNCTIONS    eddb_CreatePalMapping
;*              MapPalette
;*
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES
;*
;*              NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVITY =
;*   DATE      FLAG        APAR   CHANGE DESCRIPTION
;*   --------  ----------  -----  --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
;*   02/15/93              61938  Performance Problems with DrawBits and BitBlt
;*   03/02/93              62435  Make same changes as XGA defect 61776.
;*   05/01/93              68721  Performance Problems with DrawBits and BitBlt
;*                                Fixed a regression caused by the fix for defect 62735.  We copied
;*                                in the fix for the XGA defect 62735 but the fix was not completely
;*                                right.
;*
;*****************************************************************************/

        .386
        .MODEL FLAT,SYSCALL
        ASSUME  SS:FLAT, DS:FLAT, CS:FLAT, ES:FLAT

        .xlist

INCL_GPILOGCOLORTABLE   equ                      1
INCL_DDIMISC            equ                      1
INCL_GRE_BITMAPS        equ                      1
INCL_GPIBITMAPS         equ                      1
INCL_GPILOGCOLORTABLE   equ                      1
INCL_GRE_PALETTE        equ                      1
INCL_GRE_COLORTABLE     equ                      1
INCL_DEV                equ                      1
INCL_DDICOMFLAGS        equ                      1
INCL_WINPALETTE         equ                      1
INCL_WINSYS             equ                      1
INCL_GPIERRORS          equ                      1
        include pmgre.inc
DINCL_ENABLE            equ                      1
DINCL_BITMAP            equ                      1
DINCL_CLR_TBL           equ                      1
        include driver.inc
        include extern.inc
        include protos.inc
        include assert.mac
        include palette.inc
        .list
.DATA

ifdef PALMGR2

;/*
;** Flag to indicate whether or not Palette conversion needs to be done
;** This is set by eddb_CreatePalMapping()
;*/

PUBLIC UsePaletteMapping
UsePaletteMapping       BYTE    0

;/*
;** Table used to store the mapping between the two palettes used by
;** eddb_CreatePaletteMapping and eddb_ConvertPhunk.
;*/

PUBLIC PaletteMapping
PaletteMapping          BYTE    256 DUP (?)

;/*
;** These variables keep track of the current palette mapping so we
;** can use a simple last mapping still valid cache type scheme.
;** The palette pointers are PVOIDs because they may point to either
;** a DEVPAL (real palette manager palettes) or an array of RGBs (a
;** device default palette).
;*/

endif ;/* PALMGR2 */


FNULL EQU 0
.CODE


ifdef PALMGR2

Update_Bank PROTO SYSCALL                ;JMW

eddb_CreatePalMapping PROC SYSCALL USES ESI EDI EBX,
        pdcSrc:PDDC

LOCAL   SourceType                      :ULONG,
        DestType                        :ULONG,
        SourceDevice                    :ULONG,
        DestDevice                      :ULONG,
        index                           :ULONG,
        pSourceDeviceDefaultPalette     :PTR RGB2,
        myrgb                           :RGB2
;/* {
;**    /******************************************************************/
;**    /* This function is called by eddb_BitBlt and sets up the palette */
;**    /* conversion table (PalettMapping) to be used by                 */
;**    /* eddb_ConvertPhunk. UsePaletteMapping is set to FALSE if the    */
;**    /* mapping is the identity mapping (otherwise it is set to TRUE). */
;**    /* The palettes to be used are obtained from pdc (for the         */
;**    /* destination) and pdcSrc (for the source). If pdcSrc is         */
;**    /* NULL then we must assume that we are using the same palette as */
;**    /* the destination DC.                                            */
;**    /*                                                                */
;**    /* The code must deal with Logical Color Tables (LCTs) as well as */
;**    /* palettes, and must be able to convert between memory/memory,   */
;**    /* memory/screen, and screen/memory. The case of screen/screen    */
;**    /* is considered as the identity mapping (even if the DCs are not */
;**    /* the same).                                                     */
;**    /*                                                                */
;**    /* As a quick reminder of what the pels in each case represent:   */
;**    /*                                                                */
;**    /* Screen pels are physical indexes into the Hardware Palette     */
;**    /* whether we are dealing with a DC which is using a palette or   */
;**    /* a LCT.                                                         */
;**    /*                                                                */
;**    /* Memory bitmap pels are logical indexes into a Palette if we are*/
;**    /* dealing with a DC which is using a Palette, or physical indexes*/
;**    /* into the device default palette if we are dealing with a DC    */
;**    /* which is using a LCT, or physical indexes into the HW palette  */
;**    /* if we are dealing with a DC which is using a RLCT (realizable  */
;**    /* LCT).                                                          */
;**    /******************************************************************/
;**
;**    /******************************************************************/
;**    /* Local constants - note that we can add the devices (SCREEN and */
;**    /* MEMORY) to the types (PALETTE, LCT and RLCT) without loosing   */
;**    /* information.                                                   */
;**    /******************************************************************/
;*/

        SCREEN  EQU 10h
        MEMORY  EQU 20h
        PALETTE EQU 1
        LCT     EQU 2
        RLCT    EQU 3

;/*
;** Decide where the source is coming from...
;*/
        mov     esi,pdcSrc
        mov     edi,pdcGlobal

        ASSUME  ESI:PDDC
        ASSUME  EDI:PDDC

;/*
;**    if (pdcSrc == NULL)
;*/

        cmp     esi,0
        jnz     not_null

;/*
;**    {
;**        /**************************************************************/
;**        /* We have no source DC so we must assume that we are using   */
;**        /* a bitmap (in memory) that is of the same type as the       */
;**        /* destination. (Note that we set up a pointer to the device  */
;**        /* default palette and the code later always uses this rether */
;**        /* than the value in the pdcSrc. We have to do this because   */
;**        /* in the destination may be an LCT on the screen and so      */
;**        /* could be using a different device default palette.  Since  */
;**        /* we set up pdcSrc to be pdc here then we would loose that   */
;**        /* information and would not convert when we had to.)         */
;**        /**************************************************************/
;**        SourceDevice = MEMORY;
;*/

        mov     SourceDevice,MEMORY

;/*
;**        pSourceDeviceDefaultPalette = MemoryDeviceDefaultPalette;
;*/

        mov     eax,MemoryDeviceDefaultPalette
        mov     pSourceDeviceDefaultPalette,eax

;/*
;**        pdcSrc = pdc;
;*/

        mov     esi,edi
;/*
;**        if (pdc->DCIColFormat == LCOLF_PALETTE)
;*/

                test    [edi].ddc_fbClrTbl,DDC_PALETTE
                jz      not_pal
;/*
;**        {
;**            SourceType = PALETTE;
;*/

                mov     SourceType,PALETTE
                jmp     endif_1

;/*
;**        }
;**        else if (fRealizeSupported && (pdc->DCIColStatus & LCOL_REALIZABLE))
;*/

not_pal:
                test    [edi].ddc_fbClrTbl,DDC_REALIZABLE
                jz      do_lct

;/*
;**        {
;**            SourceType = RLCT;
;*/

                mov     SourceType,RLCT
                jmp     endif_1

;/*
;**        }
;**        else
;*/

do_lct:
;/*
;**        {
;**            SourceType = LCT;
;*/

                mov     SourceType,LCT
                jmp     endif_1

;/*
;**        }
;**    }
;**    else
;*/

not_null:
;/*
;**    {
;**        /**************************************************************/
;**        /* We do have a source DC so we must use it to work out all   */
;**        /* we need to know about the source to decide how to go about */
;**        /* the operation.                                             */
;**        /**************************************************************/
;**        pSourceDeviceDefaultPalette = pdcSrc->DCIDeviceDefaultPalette;
;*/

        mov     eax,[esi].ddc_pDefPal
        mov     pSourceDeviceDefaultPalette,eax
;/*
;**        if (pdcSrc->DCIDCType == OD_DIRECT)
;*/

                test    [esi].ddc_fb,DDC_DEVICE
                jz      not_device

;/*
;**        {
;**            SourceDevice = SCREEN;
;*/

                mov     SourceDevice,SCREEN
                jmp     check_pal

;/*
;**        }
;**        else
;*/

not_device:
;/*
;**        {
;**            SourceDevice = MEMORY;
;*/

                mov     SourceDevice,MEMORY

;/*
;**        }
;**
;*/

check_pal:
;/*
;**        if (pdcSrc->DCIColFormat == LCOLF_PALETTE)
;*/

        test    [esi].ddc_fbClrTbl,DDC_PALETTE
        jz      not_pal2

;/*
;**        {
;**            SourceType = PALETTE;
;*/

                mov     SourceType,PALETTE
                jmp     endif_1

;/*
;**        }
;**        else if (fRealizeSupported && (pdcSrc->DCIColStatus & LCOL_REALIZABLE))
;*/

not_pal2:
                test    [esi].ddc_fbClrTbl,DDC_REALIZABLE
                jz      do_lct2

;/*
;**        {
;**            SourceType = RLCT;
;*/

                mov     SourceType,RLCT
                jmp     endif_1

;/*
;**        }
;**        else
;*/

do_lct2:
;/*
;**        {
;**            SourceType = LCT;
;*/

                mov     SourceType,LCT

;/*
;**        }
;**   }
;*/

endif_1:

;/*
;**
;**    /******************************************************************/
;**    /* ...and where the destination is going to.                      */
;**    /******************************************************************/
;**    if (pdc->DCIDCType == OD_DIRECT)
;*/

        test    [edi].ddc_fb,DDC_DEVICE
        jz      not_device2

;/*
;**    {
;**        DestDevice = SCREEN;
;*/

        mov     DestDevice,SCREEN
        jmp     check_pal3

;/*
;**    }
;**    else
;*/

not_device2:
;/*
;**    {
;**        DestDevice = MEMORY;
;*/

        mov     DestDevice,MEMORY

;/*
;**    }
;*/

check_pal3:

;/*
;**    if (pdc->DCIColFormat == LCOLF_PALETTE)
;*/

        test    [edi].ddc_fbClrTbl,DDC_PALETTE
        jz      not_pal3

;/*
;**    {
;**        DestType = PALETTE;

        mov     DestType,PALETTE
        jmp     end_pal3

;/*
;**    }
;**    else if (fRealizeSupported && (pdc->DCIColStatus & LCOL_REALIZABLE))
;*/

not_pal3:
                test    [edi].ddc_fbClrTbl,DDC_REALIZABLE
                jz      do_lct3

;/*
;**    {
;**        DestType = RLCT;
;*/

        mov     DestType,RLCT
        jmp     end_pal3

;/*
;**    }
;**    else
;*/

do_lct3:

;/*
;**    {
;**        DestType = LCT;
;*/

        mov     DestType,LCT

;/*
;**    }
;*/

end_pal3:

;/*
;**    /******************************************************************/
;**    /* Do some tests now to see if we are going to need to bother     */
;**    /* using a PaletteMapping. If both the source and the destination */
;**    /* are the screen or either are RLCTs then we use a one to one    */
;**    /* mapping.  If both the source and the destination are using the */
;**    /* same palette then there is no need to do any conversion if     */
;**    /* they are using the same device type (screen contains indexes   */
;**    /* into the HW palette, memory contains indexes into the palette  */
;**    /* manager palette).  If both the source and the destination are  */
;**    /* using an LCT which is mapped onto the same device default      */
;**    /* palette then we do not need to do any conversion.              */
;**    /******************************************************************/
;**    if (   (SourceType == RLCT)
;*/

        cmp     SourceType,RLCT
        je      dont_bother

;/*
;**        || (DestType == RLCT)
;*/

        cmp     DestType,RLCT
        je      dont_bother

;/*
;**        || ( (SourceDevice == SCREEN) && (DestDevice == SCREEN) )
;*/

        cmp     SourceDevice,SCREEN
        jne     @F
        cmp     DestDevice,SCREEN
        je      dont_bother
@@:
;/*
;**
;**        || ( (SourceType == PALETTE) && (DestType == PALETTE)
;**             && (pdcSrc->Palette == pdc->Palette)
;**             && (SourceDevice == DestDevice) )
;*/

        cmp     SourceType,PALETTE
        jne     @F
        cmp     DestType,PALETTE
        jne     @F
        mov     eax,[esi].ddc_npdevpal
        cmp     eax,[edi].ddc_npdevpal
        jne     @F
        mov     eax,SourceDevice
        cmp     eax,DestDevice
        je      dont_bother
@@:

;/*
;**        || ( (SourceType == LCT) && (DestType == LCT)
;**             && ( pSourceDeviceDefaultPalette ==
;**                  pdc->DCIDeviceDefaultPalette) )
;*/

        cmp     SourceType,LCT
        jne     keep_going
        cmp     DestType,LCT
        jne     keep_going
        mov     eax,pSourceDeviceDefaultPalette
        cmp     eax,[edi].ddc_pDefPal
        jne     keep_going

;/*
;**       )
;**    {
;*/

dont_bother:
;/*
;**        UsePaletteMapping = FALSE;
;*/

        mov     UsePaletteMapping,0
        jmp     cpm_exit

;/*
;**        return;
;**    }
;*/

keep_going:

;/*
;**    /******************************************************************/
;**    /* We have to use a palette mapping but with a bit (or a lot) of  */
;**    /* luck the current palette mapping will be the same as the       */
;**    /* mapping we want to use so there will be no need to recreate    */
;**    /* the palette mapping.  CurrentMappingValid is always set to     */
;**    /* FALSE whenever either of the "palettes" (HW palette / LCTs /   */
;**    /* palman palettes) envolved in the mapping get altered in anyway.*/
;**    /******************************************************************/
;**    if (   CurrentMappingValid
;*/

        cmp     CurrentMappingValid,0
        jz      keep_going2

;/*
;**        && (  ( (SourceDevice == SCREEN) && (CurrentSourcePalette == FNULL) )
;*/

        cmp     SourceDevice,SCREEN
        jne     @F
        cmp     CurrentSourcePalette,FNULL
        je      and_1
@@:
;/*
;**           || ( (SourceType == PALETTE) && (SourceDevice != SCREEN)
;**                && (CurrentSourcePalette == pdcSrc->Palette) )
;*/

        cmp     SourceType,PALETTE
        jne     @F
        cmp     SourceDevice,SCREEN
        je      @F
        mov     eax,CurrentSourcePalette
        cmp     eax,[esi].ddc_npdevpal
        je      and_1
@@:
;/*
;**           || ( (SourceType == LCT)
;**                && (CurrentSourcePalette == pSourceDeviceDefaultPalette) ))
;*/

        cmp     SourceType,LCT
        jne     keep_going2
        mov     eax,CurrentSourcePalette
        cmp     eax,pSourceDeviceDefaultPalette
        jne     keep_going2

and_1:
;/*
;**        && (  (  (DestType == PALETTE)
;**              && (  (  (DestDevice != SCREEN)
;**                    && (CurrentDestPalette == pdc->Palette) )
;**                 || (  (DestDevice == SCREEN)
;**                    && (CurrentDestPalette == FNULL) ) ) )
;**           || (  (DestType == LCT)
;**              && (CurrentDestPalette == pdc->DCIDeviceDefaultPalette) ) )
;**
;** the above broken down ...
;**        &&
;**         (
;**          (
;**           (DestType == PALETTE)
;**           &&
;**           (
;**            ((DestDevice != SCREEN) && (CurrentDestPalette == pdc->Palette))
;**            ||
;**            ((DestDevice == SCREEN) && (CurrentDestPalette == FNULL))
;**           )
;**          )
;**          ||
;**          (
;**           (DestType == LCT) && (CurrentDestPalette == pdc->DCIDeviceDefaultPalette)
;**          )
;**         )
;*/
;V2.1EKF00 Start
;the above section was replaced by the section below in XGA by defect #61776
;/*
;**         &&
;**          (  ((DestType == PALETTE) && (CurrentDestPalette == pdc->Palette))
;**           ||
;**             ((DestType == LCT) &&
;**                (CurrentDestPalette == pdc->DCIDeviceDefaultPalette))
;**          )
;*/
;V2.1EKF00 End

        cmp     DestType,PALETTE
        jne     last_chance
;V2.1EKF00        cmp     DestDevice,SCREEN
;V2.1EKF00        je      @F
        mov     eax,CurrentDestPalette
        cmp     eax,[edi].ddc_npdevpal
        je      set_true
;V2.1EKF00@@:
;V2.1EKF00        cmp     DestDevice,SCREEN
;V2.1EKF00        jne     last_chance
;V2.1EKF00        cmp     CurrentDestPalette,FNULL
;V2.1EKF00        je      set_true
last_chance:
        cmp     DestType,LCT
        jne     keep_going2
        mov     eax,CurrentDestPalette
        cmp     eax,[edi].ddc_pDefPal
        jne     keep_going2

;/*
;**        )
;**    {
;*/

set_true:

;/*
;**        /**************************************************************/
;**        /* We can use the current palette-palette mapping.            */
;**        /**************************************************************/
;**        UsePaletteMapping = TRUE;
;*/

        mov     UsePaletteMapping,1
        jmp     cpm_exit

;/*
;**        return;
;**    }
;*/

keep_going2:
;/*
;**
;**    /******************************************************************/
;**    /* Now for each case lets loop through the palettes and set up    */
;**    /* each entry in the PaletteMapping table.                        */
;**    /******************************************************************/
;**    switch (SourceType+SourceDevice)
;*/

        mov     eax,SourceType
        add     eax,SourceDevice

;/*
;**    {
;**        case PALETTE+SCREEN:
;**        case LCT+SCREEN:
;*/

        cmp     eax,PALETTE+SCREEN
        je      @F
        cmp     eax,LCT+SCREEN
        jne     case_1
@@:
;/*
;**            switch (DestType+DestDevice)
;*/

                mov     eax,DestType
                add     eax,DestDevice

;/*
;**            {
;**                case PALETTE+SCREEN:
;**                case RLCT+SCREEN:
;**                case RLCT+MEMORY:
;**                case LCT+SCREEN:
;*/

                        cmp     eax,PALETTE+SCREEN
                        je      @F
                        cmp     eax,RLCT+SCREEN
                        je      @F
                        cmp     eax,RLCT+MEMORY
                        je      @F
                        cmp     eax,LCT+SCREEN
                        jne     case_01
@@:
ifdef FIREWALLS
                int 3
;/*
;**                    haltproc();
;*/
endif ;/* FIREWALLS */
;/*
;**                    break;
;*/

                        jmp     end_0
case_01:
;/*
;**                case PALETTE+MEMORY:
;*/

                        cmp     eax,PALETTE+MEMORY
                        jne     case_02

;/*
;**                    for (index = 0; index < 256; index++)
;*/

                        mov     ebx,255
looptop_00:
;/*
;**                    {
;**                        PaletteMapping[index] = (BYTE)
;**                           NearestPaletteIndex(HWPalette[index]);
;*/

                        INVOKE  NearestPaletteIndex,
                                edi,
                                HWPalette[ebx*sizeof RGB2]
;JMW                        mov     PaletteMapping[ecx],al
                        mov     PaletteMapping[ebx],al ;JMW
                        dec     ebx
                        jns     looptop_00

;/*
;**                    }
;**                    CurrentDestPalette = pdc->Palette;
;*/

                        mov     eax,[edi].ddc_npdevpal
                        mov     CurrentDestPalette,eax

;/*
;**                    break;
;*/

                        jmp     end_0

case_02:
;/*
;**                case LCT+MEMORY:
;*/

                cmp     eax,LCT+MEMORY
                jne     end_0

;/*
;**                    for (index = 0; index < 256 ; index++)
;*/

                mov     ebx,255
looptop_01:
;/*
;**                    {
;**                        PaletteMapping[index] = (BYTE)
;**                           NearestMemoryDefaultPhysicalIndex(HWPalette[index]);
;*/
                        INVOKE  NearestMemoryDefaultPhysicalIndex,
                                HWPalette[ebx*sizeof RGB2]
;JMW                        mov     PaletteMapping[ecx],al
                        mov     PaletteMapping[ebx],al ;JMW
                        dec     ebx
                        jns     looptop_01

;/*
;**                    }
;**                    CurrentDestPalette = pdc->DCIDeviceDefaultPalette;
;*/

                        mov     eax,[edi].ddc_pDefPal   ;@DMS was missing
                        mov     CurrentDestPalette,eax  ;@DMS was missing

;/*
;**                    break;
;**            }
;*/

end_0:
;/*
;**            CurrentSourcePalette = NULL;
;*/

                mov     CurrentSourcePalette,0

;/*
;**            break;
;*/

                jmp     end_OSwitch

;/*
;**        case PALETTE+MEMORY:
;*/

case_1:
        cmp     eax,PALETTE+MEMORY
        jne     case_2

;/*
;**            switch (DestType+DestDevice)
;*/

                mov     eax,DestType
                add     eax,DestDevice

;/*
;**            {
;**                case RLCT+SCREEN:
;**                case RLCT+MEMORY:
;*/

                cmp     eax,RLCT+SCREEN
                je      @F
                cmp     eax,RLCT+MEMORY
                jne     case_11
@@:
ifdef FIREWALLS
;/*
;**                    haltproc();
;*/

                int 3
endif ;/* FIREWALLS */
;/*
;**                    break;
;*/

                jmp     end_1

case_11:
;/*
;**                case PALETTE+SCREEN:
;*/

                cmp     eax,PALETTE+SCREEN
                jne     case_12

;/*
;**                    for (index = 0;
;**                         index < pdcSrc->Palette->usCountStored;
;**                         index++)
;**                    {
;*/

                        mov     ebx,0
                        jmp     loopentry_11
looptop_11:
;/*
;**                        PaletteMapping[index] = (BYTE)
;**                            pdc->Palette->entries[
;**                                    NearestPaletteIndex(
;**                                    pdcSrc->Palette->entries[index].rgb)
;**                                ].bCurrent;
;*/


mov     eax,[esi].ddc_npdevpal ;JMW

                        INVOKE  NearestPaletteIndex,
                                edi,
                                [eax].DEVPAL.entries[ebx*sizeof PALENTRY].rgb

                        mov     edx,[edi].ddc_npdevpal
                        mov     al,[edx].DEVPAL.entries[eax*sizeof PALENTRY].bCurrent
                        mov     PaletteMapping[ebx],al
                        inc     ebx
loopentry_11:
                        mov     eax,[esi].ddc_npdevpal
                        cmp     ebx,[eax].DEVPAL.usCountStored
                        jb      looptop_11

;/*
;**                    }
;**                    while (index < 256)
;**                    {
;*/

                        jmp     whileentry_11
whiletop_11:
;/*
;**                        PaletteMapping[index++] = (BYTE)0;
;*/

                        mov     PaletteMapping[ebx],0
                        inc     ebx
whileentry_11:
                        cmp     ebx,256
                        jb      whiletop_11

;/*
;**                    }
;**     ;              CurrentDestPalette = NULL;
;**                    CurrentDestPalette = pdc->Palette;       ;          
;*/

        ;               mov     CurrentDestPalette,0
                        mov     eax,[edi].ddc_npdevpal          ;          
                        mov     CurrentDestPalette,eax          ;          
                        jmp     end_1

;/*
;**                    break;
;*/

                jmp     end_1

case_12:
;/*
;**                case PALETTE+MEMORY:
;*/

                cmp     eax,PALETTE+MEMORY
                jne     case_13

;/*
;**                    for (index = 0;
;**                         index < pdcSrc->Palette->usCountStored;
;**                         index++)
;**                    {
;*/

                        mov     ebx,0
                        jmp     loopentry_12
looptop_12:
;/*
;**                        PaletteMapping[index] = (BYTE)
;**                                NearestPaletteIndex(
;**                                pdcSrc->Palette->entries[index].rgb);
;*/

mov     eax,[esi].ddc_npdevpal ;JMW
                        INVOKE  NearestPaletteIndex,
                                edi,
                                [eax].DEVPAL.entries[ebx*sizeof PALENTRY].rgb

                        mov     PaletteMapping[ebx],al
                        inc     ebx
loopentry_12:
                        mov     eax,[esi].ddc_npdevpal
                        cmp     ebx,[eax].DEVPAL.usCountStored
                        jb      looptop_12

;/*
;**                    }
;**                    while (index < 256)
;*/

                        jmp     whileentry_12
whiletop_12:

;/*
;**                    {
;**                        PaletteMapping[index++] = (BYTE)0;
;*/

                        mov     PaletteMapping[ebx],0
                        inc     ebx
whileentry_12:
                        cmp     ebx,256
                        jb      whiletop_12

;/*
;**                    }
;**                    CurrentDestPalette = pdc->Palette;
;*/

                        mov     eax,[edi].ddc_npdevpal
                        mov     CurrentDestPalette,eax

;/*
;**                    break;
;*/

                jmp     end_1

case_13:
;/*
;**                case LCT+SCREEN:
;*/

                cmp     eax,LCT+SCREEN
                jne     case_14

;/*
;**                    for (index = 0;
;**                         index < pdcSrc->Palette->usCountStored;
;**                         index++)
;**                    {
;*/

                        mov     ebx,0
                        jmp     loopentry_13
looptop_13:
;/*
;**                        PaletteMapping[index] = (BYTE)
;**                                NearestDirectDefaultPhysicalIndex(
;**                                pdcSrc->Palette->entries[index].rgb);
;*/

mov     eax,[esi].ddc_npdevpal ;JMW
                        INVOKE  NearestDirectDefaultPhysicalIndex,
                                [eax].DEVPAL.entries[ebx*sizeof PALENTRY].rgb

                        mov     PaletteMapping[ebx],al
                        inc     ebx
loopentry_13:
                        mov     eax,[esi].ddc_npdevpal
                        cmp     ebx,[eax].DEVPAL.usCountStored
                        jb      looptop_13

;/*
;**                    }
;**                    while (index < 256)
;*/

                        jmp     whileentry_13
whiletop_13:
;/*
;**                    {
;**                        PaletteMapping[index++] = (BYTE)0;
;*/

                        mov     PaletteMapping[ebx],0
                        inc     ebx
whileentry_13:
                        cmp     ebx,256
                        jb      whiletop_13

;/*
;**                    }
;**                    CurrentDestPalette = pdc->DCIDeviceDefaultPalette;
;*/

                        mov     eax,[edi].ddc_pDefPal
                        mov     CurrentDestPalette,eax

;/*
;**                    break;
;*/

                jmp     end_1

case_14:
;/*
;**                case LCT+MEMORY:
;*/

                cmp     eax,LCT+MEMORY
                jne     end_1

;/*
;**                    for (index = 0;
;**                         index < pdcSrc->Palette->usCountStored;
;**                         index++)
;**                    {
;*/

                        mov     ebx,0
                        jmp     loopentry_14
looptop_14:
;/*
;**                        PaletteMapping[index] = (BYTE)
;**                                NearestMemoryDefaultPhysicalIndex(
;**                                pdcSrc->Palette->entries[index].rgb);
;*/

mov     eax,[esi].ddc_npdevpal ;JMW
                        INVOKE  NearestMemoryDefaultPhysicalIndex,
                                [eax].DEVPAL.entries[ebx*sizeof PALENTRY].rgb

                        mov     PaletteMapping[ebx],al
                        inc     ebx
loopentry_14:
                        mov     eax,[esi].ddc_npdevpal
                        cmp     ebx,[eax].DEVPAL.usCountStored
                        jb      looptop_14

;/*
;**                    }
;**                    while (index < 256)
;*/

                        jmp     whileentry_14
whiletop_14:
;/*
;**                    {
;**                        PaletteMapping[index++] = (BYTE)0;
;*/

                        mov     PaletteMapping[ebx],0
                        inc     ebx
whileentry_14:
                        cmp     ebx,256
                        jb      whiletop_14

;/*
;**                    }
;**                    CurrentDestPalette = pdc->DCIDeviceDefaultPalette;
;**                    break;
;**            }
;*/

                        mov     eax,[edi].ddc_pDefPal
                        mov     CurrentDestPalette,eax
end_1:
;/*
;**            CurrentSourcePalette = pdcSrc->Palette;
;*/

                        mov     eax,[esi].ddc_npdevpal
                        mov     CurrentSourcePalette,eax

;/*
;**            break;
;**
;*/

        jmp     end_OSwitch

;/*
;**        case LCT+MEMORY:
;*/

case_2:
        cmp     eax,LCT+MEMORY
        jne     case_3

;/*
;**            switch (DestType+DestDevice)
;*/

                mov     eax,DestType
                add     eax,DestDevice

;/*
;**            {
;**                case RLCT+SCREEN:
;**                case RLCT+MEMORY:
;**                case LCT+MEMORY:
;*/

                cmp     eax,RLCT+SCREEN
                je      @F
                cmp     eax,RLCT+MEMORY
                je      @F
                cmp     eax,LCT+MEMORY
                jne     case_21
@@:
ifdef FIREWALLS
;/*
;**                    haltproc();
;*/

                int 3
endif ;/* FIREWALLS */
;/*
;**                    break;
;*/

                jmp     end_2


case_21:
;/*
;**                case PALETTE+SCREEN:
;*/

                cmp     eax,PALETTE+SCREEN
                jne     case_22

;/*
;**                    for (index = 0; index < 256 ; index++)
;**                    {
;*/

                        mov     ebx,255
looptop_21:
;/*
;**                        PaletteMapping[index] = (BYTE)
;**                            pdc->Palette->entries[
;**                                NearestPaletteIndex(
;**                                MemoryDeviceDefaultRGB2(index))
;**                            ].bCurrent;
;*/

                        MemoryDeviceDefaultRGB2 ebx,eax
                        mov     myrgb,eax

                        INVOKE  NearestPaletteIndex,
                                edi,
                                myrgb

                        mov     edx,[edi].ddc_npdevpal
                        mov     al,[edx].DEVPAL.entries[eax*sizeof PALENTRY].bCurrent
                        mov     PaletteMapping[ebx],al
                        dec     ebx
                        jns     looptop_21
;/*
;**                    }
;**     ;              CurrentDestPalette = NULL;
;**                    CurrentDestPalette = pdc->Palette;       ;          
;*/

        ;               mov     CurrentDestPalette,0
                        mov     eax,[edi].ddc_npdevpal          ;          
                        mov     CurrentDestPalette,eax          ;          

;/*
;**                    break;
;*/

                jmp     end_2

case_22:
;/*
;**                case PALETTE+MEMORY:
;*/

                cmp     eax,PALETTE+MEMORY
                jne     case_23

;/*
;**                    for (index = 0; index < 256 ; index++)
;**                    {
;*/

                        mov     ebx,255
looptop_22:
;/*
;**                        PaletteMapping[index] = (BYTE)
;**                                NearestPaletteIndex(
;**                                MemoryDeviceDefaultRGB2(index));
;*/

                        MemoryDeviceDefaultRGB2 ebx,eax
                        mov     myrgb,eax
                        INVOKE  NearestPaletteIndex,
                                edi,
                                myrgb

                        mov     PaletteMapping[ebx],al
                        dec     ebx
                        jns     looptop_22

;/*
;**                    }
;**                    CurrentDestPalette = pdc->Palette;
;*/

                mov     eax,[edi].ddc_npdevpal
                mov     CurrentDestPalette,eax

;/*
;**                    break;
;*/

                jmp     end_2

case_23:
;/*
;**                case LCT+SCREEN:
;*/

                cmp     eax,LCT+SCREEN
                jne     end_2

;/*
;**                    for (index = 0; index < 256 ; index++)
;**                    {
;*/

                        mov     ebx,255
looptop_23:
;/*
;**                        PaletteMapping[index] = (BYTE)
;**                                NearestDirectDefaultPhysicalIndex(
;**                                MemoryDeviceDefaultRGB2(index));
;*/


                        MemoryDeviceDefaultRGB2 ebx,eax
                        mov     myrgb,eax
                        INVOKE  NearestDirectDefaultPhysicalIndex,
                                myrgb

                        mov     PaletteMapping[ebx],al
                        dec     ebx
                        jns     looptop_23

;/*
;**                    }
;**                    CurrentDestPalette = pdc->DCIDeviceDefaultPalette;
;*/

                mov     eax,[edi].ddc_pDefPal
                mov     CurrentDestPalette,eax

;/*
;**                    break;
;**            }
;*/

end_2:
;/*
;**            CurrentSourcePalette = pSourceDeviceDefaultPalette;
;*/

                mov     eax,pSourceDeviceDefaultPalette
                mov     CurrentSourcePalette,eax

;/*
;**            break;
;*/

                jmp     end_OSwitch

;/*
;**        case RLCT+SCREEN:
;**        case RLCT+MEMORY:
;*/

case_3:
        cmp     eax,RLCT+SCREEN
        je      @F
        cmp     eax,RLCT+MEMORY
        jne     end_OSwitch
@@:
ifdef FIREWALLS
;/*
;**            haltproc();
;*/

        int 3
endif ;FIREWALLS
;/*
;**            break;
;**    }
;*/

end_OSwitch:
;/*
;**
;**    /******************************************************************/
;**    /* Set the CurrentMappingValid flag to indicate that the current  */
;**    /* mapping is valid. This will be invalidated by a call to either */
;**    /* HWPaletteChanged or ChangedPalette or ChangedColorTable.       */
;**    /******************************************************************/
;**    CurrentMappingValid = TRUE;
;*/

        mov     CurrentMappingValid,1

;/*
;**    /******************************************************************/
;**    /* And last but not least we must set UsePaletteMapping.          */
;**    /******************************************************************/
;**    UsePaletteMapping = TRUE;
;*/

        mov     UsePaletteMapping,1

;/*
;** }
;*/

cpm_exit:
        ret
eddb_CreatePalMapping ENDP

;/***************************************************************************
;*
;* FUNCTION NAME = MapPalette
;*
;* DESCRIPTION   =
;*
;* INPUT         = psdSrc:PSURFACE
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

MapPalette PROC SYSCALL USES ESI EDI EBX,
        psdSrc:PSURFACE

LOCAL   pBuffer   :DWORD,
        ulSize    :DWORD

        mov     ebx,psdSrc
        ASSUME  ebx:PSURFACE

        mov     esi,[ebx].sd_pBits
        mov     eax,[ebx].sd_cbScan
        mov     edx,[ebx].sd_cy
        mul     edx
        mov     ulSize,eax              ;save size

        lea     ebx,pBuffer

;/*
;** eax = size in bytes
;** ebx = pPointer to allocated memory
;*/


        INVOKE  private_alloc
        or      ecx,ecx
        jz      alloc_ok

        mov     eax,PMERR_INSUFFICIENT_MEMORY
        save_error_code
        xor     eax,eax
ifdef FIREWALLS
        int 3
endif
        jmp     mp_exit

alloc_ok:
        mov     edi,pBuffer

        mov     ecx,ulSize
        shr     ecx,2                   ;translate dwords
        lea     ebx,PaletteMapping
        mov     edx,0

loop_top:
        lodsd
        mov     dl,al
        mov     al,BYTE PTR [ebx+edx]
        mov     dl,ah
        mov     ah,BYTE PTR [ebx+edx]
        ror     eax,16
        mov     dl,al
        mov     al,BYTE PTR [ebx+edx]
        mov     dl,ah
        mov     ah,BYTE PTR [ebx+edx]
        rol     eax,16
        stosd
        dec     ecx
        jnz     loop_top


        mov     ecx,ulSize
        and     ecx,3
        jz      skip_byte
        and     ecx,2
        jz      skip_word


        lodsw
        mov     dl,al
        mov     al,BYTE PTR [ebx+edx]
        mov     dl,ah
        mov     ah,BYTE PTR [ebx+edx]
        stosw
skip_word:


        and     ecx,1
        jz      skip_byte


        lodsb
        mov     dl,al
        mov     al,BYTE PTR [ebx+edx]
        stosb
skip_byte:


        ASSUME  ebx:NOTHING
        mov     eax,1           ;return success
        mov     edx,pBuffer     ;and our new bitmap
mp_exit:
        ret
MapPalette ENDP

MapPaletteDevice PROC SYSCALL USES ESI EDI EBX,
        psdSrc       :PSURFACE,
        psdSrcBuffer :PSURFACE,
        xSrc         :DWORD,
        ySrc         :DWORD

LOCAL   pBuffer        :DWORD,
        sd_cy          :DWORD,
        sd_cx          :DWORD,
        sd_cbScan      :DWORD,
        cbNextScan     :DWORD,
        sd_pBits       :DWORD,
        scan_per_bank  :WORD,
        scanlines_left :BYTE,
        current_bank   :BYTE

        xor     edx,edx
        mov     eax,10000h
        mov     ebx,SCREEN_CBSCAN
        div     ebx
        mov     ebx,eax
        mov     scan_per_bank,ax

        mov     ebx,psdSrc
        ASSUME  ebx:PSURFACE

        mov     edi,psdSrcBuffer
        ASSUME  edi:PSURFACE

        mov     eax,[ebx].sd_cbScan
        mov     sd_cbScan,eax
        sub     eax,[edi].sd_cx
        mov     cbNextScan,eax

        mov     eax,[ebx].sd_pBits
        mov     sd_pBits,eax

        mov     eax,[edi].sd_cx
        mov     sd_cx,eax

        mov     edx,[edi].sd_cy
        mov     sd_cy,edx

        mul     edx

        lea     ebx,pBuffer

        ;eax = size in bytes
        ;ebx = pPointer to allocated memory

        INVOKE  private_alloc
        or      ecx,ecx
        jz      alloc_ok1

        mov     eax,PMERR_INSUFFICIENT_MEMORY
        save_error_code
        xor     eax,eax
        jmp     mp_exit1

alloc_ok1:

        mov     eax,ySrc
        mov     cx,scan_per_bank
        xor     edx,edx
        div     cx
        mov     current_bank,al
        mov     cx,scan_per_bank
        sub     cx,dx
        mov     scanlines_left,cl
        xchg    dx,ax
        call    set_bank_select
        mul     sd_cbScan
        add     eax,xSrc

        mov     ecx,sd_cy
        xor     edx,edx
        mov     edi,pBuffer
        mov     esi,sd_pBits
        add     esi,eax
        lea     ebx,PaletteMapping
        jecxz   loop_end
loop_cy:
        push    ecx
        mov     ecx,sd_cx
loop_cx:
        lodsb
        mov     dl,al
        mov     al,BYTE PTR [ebx+edx]
        stosb
        loop    loop_cx
        pop     ecx
        dec     ecx
        jz      loop_end
        dec     scanlines_left
        jz      @f
        add     esi,cbNextScan
        jmp     loop_cy
@@:
        mov     dx,scan_per_bank
        mov     scanlines_left,dl
        inc     current_bank
        mov     dl,current_bank
        call    set_bank_select
        mov     esi,sd_pBits
        add     esi,xSrc
        jmp     loop_cy

loop_end:
        ASSUME  ebx:NOTHING
        mov     eax,1           ;return success
        mov     edx,pBuffer     ;and our new bitmap
mp_exit1:
        ret
MapPaletteDevice ENDP

;           Start

EXTERNDEF       TransSurf       :DWORD

MapPaletteMemory PROC SYSCALL USES ESI EDI EBX,
        psdSrc       :PSURFACE,
        psdSrcBuffer :PSURFACE,
        xSrc         :DWORD,
        ySrc         :DWORD

LOCAL   pBuffer        :DWORD,
        sd_cy          :DWORD,
        sd_cx          :DWORD,
        sd_cbScan      :DWORD,
        cbNextScan     :DWORD,
        sd_pBits       :DWORD

        mov     ebx,psdSrc
        ASSUME  ebx:PSURFACE

        mov     edi,psdSrcBuffer
        ASSUME  edi:PSURFACE

        mov     eax,[ebx].sd_cbScan
        mov     sd_cbScan,eax
        sub     eax,[edi].sd_cx
        mov     cbNextScan,eax

        mov     eax,[ebx].sd_pBits
        mov     sd_pBits,eax

        mov     eax,[edi].sd_cx
        mov     sd_cx,eax

        mov     edx,[edi].sd_cy
        mov     sd_cy,edx

        mul     edx

        lea     ebx,pBuffer

        ASSUME  EBX:PTR DWORD
        cmp     eax,1000h
        ja      @f
        lea     eax,TransSurf
        mov     [ebx],eax
        jmp     alloc_ok1
@@:
        ASSUME  EBX:NOTHING

        ;eax = size in bytes
        ;ebx = pPointer to allocated memory

        INVOKE  private_alloc
        or      ecx,ecx
        jz      alloc_ok1

        mov     eax,PMERR_INSUFFICIENT_MEMORY
        save_error_code
        xor     eax,eax
        jmp     mp_exit1

alloc_ok1:
        mov     ecx,sd_cy
        xor     edx,edx
        mov     edi,pBuffer
        mov     esi,sd_pBits
        add     esi,xSrc
        mov     eax,ySrc
        mul     sd_cbScan
        add     esi,eax
        lea     ebx,PaletteMapping
        jecxz   loop_end
loop_cy:
        push    ecx
        mov     ecx,sd_cx
loop_cx:
        lodsb
        mov     dl,al
        mov     al,BYTE PTR [ebx+edx]
        stosb
        loop    loop_cx
        pop     ecx
        dec     ecx
        jz      loop_end
        add     esi,cbNextScan
        jmp     loop_cy

loop_end:
        ASSUME  ebx:NOTHING
        mov     eax,1           ;return success
        mov     edx,pBuffer     ;and our new bitmap
mp_exit1:
        ret
MapPaletteMemory ENDP

;           End

endif ;PALMGR2
END


