Example #1
0
        public void SauveSpriteCmp(string fileName, string version)
        {
            byte[]       ret    = MakeSprite();
            byte[]       sprCmp = new byte[ret.Length];
            int          l      = PackDepack.Pack(ret, ret.Length, sprCmp, 0);
            StreamWriter sw     = SaveAsm.OpenAsm(fileName, version);

            SaveAsm.GenereDatas(sw, sprCmp, l, 16);
            SaveAsm.CloseAsm(sw);
            main.SetInfo("Sauvegarde sprite assembleur compacté ok.");
        }
Example #2
0
        private int PackWinDC(byte[] bufOut, ref int sizeDepack, int topBottom, bool razDiff, int modeLigne, bool optimSpeed)
        {
            int xFin = 0;
            int xDeb = BitmapCpc.NbCol;
            int yDeb = BitmapCpc.NbLig;
            int yFin = 0;
            int lStart = 0, lEnd = BitmapCpc.NbLig, xStart = 0, xEnd = BitmapCpc.NbCol;

            if (razDiff)
            {
                Array.Clear(BufPrec, 0, BufPrec.Length);
            }

            // Copier l'image cpc dans le buffer de travail
            img.bitmapCpc.CreeBmpCpc(img.BmpLock, null);

            if (chkZoneVert.Checked)
            {
                xStart = topBottom < 1 ? 0 : BitmapCpc.NbCol >> 1;
                xEnd   = topBottom == 0 ? BitmapCpc.NbCol >> 1 : BitmapCpc.NbCol;
            }
            else
            {
                lStart = topBottom < 1 ? 0 : BitmapCpc.NbLig >> 1;
                lEnd   = topBottom == 0 ? BitmapCpc.NbLig >> 1 : BitmapCpc.NbLig;
            }
            // Recherche les "coordonnées" de l'image différente par rapport à la précédente
            for (int l = lStart; l < lEnd; l += modeLigne)
            {
                int adr = BitmapCpc.GetAdrCpc(l << 1);
                for (int oct = xStart; oct < xEnd; oct++)
                {
                    if (img.bitmapCpc.bmpCpc[adr + oct] != BufPrec[adr + oct])
                    {
                        xDeb = Math.Min(xDeb, oct);
                        xFin = Math.Max(xFin, oct);
                        yDeb = Math.Min(yDeb, l);
                        yFin = Math.Max(yFin, l);
                        BufPrec[adr + oct] = img.bitmapCpc.bmpCpc[adr + oct];
                    }
                }
            }

            int tailleX = xFin > xDeb ? xFin - xDeb + 1 : 0;
            int tailleY = (yFin + 1 - yDeb) / modeLigne;
            int length  = tailleX * tailleY;

            if (length > 0)
            {
                Array.Clear(bLigne, 0, bLigne.Length);
                int pos = 0, AdrEcr;
                bLigne[pos++] = (byte)tailleX;
                bLigne[pos++] = (byte)tailleY;
                if (!optimSpeed)
                {
                    AdrEcr        = 0xC000 + xDeb + (yDeb >> 3) * BitmapCpc.NbCol + (yDeb & 7) * 0x800;
                    bLigne[pos++] = (byte)(AdrEcr & 0xFF);
                    bLigne[pos++] = (byte)(AdrEcr >> 8);
                }
                if (chkCol.Checked)
                {
                    // passage en mode "colonne par colonne"
                    for (int x = xDeb; x <= xFin; x++)
                    {
                        for (int l = 0; l < tailleY * modeLigne; l += modeLigne)
                        {
                            int offsetEcr = ((l + yDeb) >> 3) * BitmapCpc.NbCol + ((l + yDeb) & 7) * 0x800 + x;
                            if (optimSpeed)
                            {
                                AdrEcr        = 0xC000 + offsetEcr;
                                bLigne[pos++] = (byte)(AdrEcr & 0xFF);
                                bLigne[pos++] = (byte)(AdrEcr >> 8);
                            }
                            bLigne[pos++] = BufPrec[offsetEcr];
                        }
                    }
                }
                else
                {
                    // Passage en mode "ligne à ligne"
                    for (int l = yDeb; l <= yFin; l += modeLigne)
                    {
                        int offsetEcr = (l >> 3) * BitmapCpc.NbCol + (l & 7) * 0x800 + xDeb;
                        if (optimSpeed)
                        {
                            AdrEcr        = 0xC000 + offsetEcr;
                            bLigne[pos++] = (byte)(AdrEcr & 0xFF);
                            bLigne[pos++] = (byte)(AdrEcr >> 8);
                        }
                        Array.Copy(BufPrec, offsetEcr, bLigne, pos, tailleX);
                        pos += tailleX;
                    }
                }
                int lpack = PackDepack.Pack(bLigne, pos, bufOut, 0);
                sizeDepack = length + 4;
                return(lpack);
            }
            else
            {
                return(0);
            }
        }
Example #3
0
        /*
         *              private int PackWinDC4(byte[] bufOut, bool razDiff = false) {
         *                      int[] xFin = { 0, 0, 0, 0 };
         *                      int[] xDeb = { img.NbCol, img.NbCol, img.NbCol, img.NbCol };
         *                      int[] yDeb = { img.NbLig, img.NbLig, img.NbLig, img.NbLig };
         *                      int[] yFin = { 0, 0, 0, 0 };
         *                      int[] ld = { 0, 0, img.NbLig >> 1, img.NbLig >> 1 };
         *                      int[] lf = { img.NbLig >> 1, img.NbLig >> 1, img.NbLig, img.NbLig };
         *                      int[] od = { 0, img.NbCol >> 1, 0, img.NbCol >> 1 };
         *                      int[] of = { img.NbCol >> 1, img.NbCol, img.NbCol >> 1, img.NbCol };
         *                      if (razDiff)
         *                              Array.Clear(BufPrec, 0, BufPrec.Length);
         *
         *                      // Copier l'image cpc dans le buffer de travail
         *                      img.bitmapCpc.CreeBmpCpc(img.BmpLock);
         *
         *                      int posBufOut = 1;
         *                      byte nbZone = 0;
         *                      // Recherche les "coordonnées" de l'image différente par rapport à la précédente
         *                      for (int i = 0; i < 4; i++) {
         *                              for (int l = ld[i]; l < lf[i]; l++) {
         *                                      int adr = img.GetAdrCpc(l << 1);
         *                                      for (int oct = od[i]; oct < of[i]; oct++) {
         *                                              if (img.bitmapCpc.bmpCpc[adr + oct] != BufPrec[adr + oct]) {
         *                                                      xDeb[i] = Math.Min(xDeb[i], oct);
         *                                                      xFin[i] = Math.Max(xFin[i], oct);
         *                                                      yDeb[i] = Math.Min(yDeb[i], l);
         *                                                      yFin[i] = Math.Max(yFin[i], l);
         *                                                      BufPrec[adr + oct] = img.bitmapCpc.bmpCpc[adr + oct];
         *                                              }
         *                                      }
         *                              }
         *                              if (xFin[i] >= xDeb[i] && yFin[i] >= yDeb[i]) {
         *                                      int nbOctets = xFin[i] - xDeb[i] + 1;
         *                                      int length = nbOctets * (yFin[i] + 1 - yDeb[i]);
         *                                      Array.Clear(bLigne, 0, bLigne.Length);
         *                                      int AdrEcr = xDeb[i] + (yDeb[i] >> 3) * img.NbCol + (yDeb[i] & 7) * 0x800;
         *                                      bLigne[0] = (byte)AdrEcr;
         *                                      bLigne[1] = (byte)(AdrEcr >> 8);
         *                                      bLigne[2] = (byte)(xFin[i] - xDeb[i] + 1);
         *                                      bLigne[3] = (byte)(yFin[i] - yDeb[i] + 1);
         *                                      // Passage en mode "ligne à ligne
         *                                      int pos = 4;
         *                                      for (int l = yDeb[i]; l <= yFin[i]; l++) {
         *                                              Array.Copy(BufPrec, (l >> 3) * img.NbCol + (l & 7) * 0x800 + xDeb[i], bLigne, pos, nbOctets);
         *                                              pos += nbOctets;
         *                                      }
         *                                      posBufOut = PackDepack.Pack(bLigne, length, bufOut, posBufOut);
         *                                      nbZone++;
         *                              }
         *                      }
         *                      bufOut[0] = nbZone;
         *                      return posBufOut;
         *              }
         */
        private int PackAscii(byte[] bufOut, ref int sizeDepack, bool razDiff, bool firstFrame, bool imageMode, bool perte = false)
        {
            int  posDiff = 0, lastPosDiff = 0, nDiff = 0;
            byte nbModif   = 0;
            int  tailleMax = (BitmapCpc.NbLig * BitmapCpc.NbCol) >> 3;

            if (razDiff)
            {
                Array.Clear(OldImgAscii, 0, OldImgAscii.Length);
            }

            if (perte)
            {
                for (int i = BitmapCpc.NbCol; i < tailleMax - BitmapCpc.NbCol; i++)
                {
                    if (OldImgAscii[i - 1] == img.bitmapCpc.imgAscii[i - 1] && OldImgAscii[i + 1] == img.bitmapCpc.imgAscii[i + 1] &&
                        OldImgAscii[i - BitmapCpc.NbCol] == img.bitmapCpc.imgAscii[i - BitmapCpc.NbCol] && OldImgAscii[i + BitmapCpc.NbCol] == img.bitmapCpc.imgAscii[i + BitmapCpc.NbCol])
                    {
                        img.bitmapCpc.imgAscii[i] = OldImgAscii[i];
                    }
                }
            }
            for (int i = 0; i < tailleMax; i++)
            {
                byte oldAsc = OldImgAscii[i];
                byte newAsc = img.bitmapCpc.imgAscii[i];
                if (nbModif == 255 || (oldAsc != newAsc) || firstFrame)
                {
                    if (oldAsc != newAsc)
                    {
                        nDiff++;
                        lastPosDiff = (posDiff + 2);
                    }
                    DiffImage[posDiff++] = (byte)nbModif;
                    DiffImage[posDiff++] = newAsc;
                    nbModif = 0;
                    if (posDiff >= DiffImage.Length)
                    {
                        break;
                    }
                }
                else
                {
                    nbModif++;
                }
            }
            Array.Copy(img.bitmapCpc.imgAscii, OldImgAscii, OldImgAscii.Length);
            sizeDepack = img.bitmapCpc.imgAscii.Length + 4;
            if (nDiff == 0 && rbFrameFull.Checked)
            {
                if (rbFrameFull.Checked)
                {
                    BufTmp[0] = (byte)'I';
                    lastAscii = 'I';
                    return(PackDepack.Pack(BufTmp, 1, bufOut, 0));
                }
                else
                {
                    img.main.SetInfo("Impossible d'ajouter image identique...");
                    return(0);
                }
            }
            else
            {
                BufTmp[0] = (byte)'O';
                Array.Copy(img.bitmapCpc.imgAscii, 0, BufTmp, 1, tailleMax);
                int lo = rbFrameO.Checked || imageMode?PackDepack.Pack(img.bitmapCpc.imgAscii, tailleMax, BufPrec, 0) : PackDepack.Pack(BufTmp, tailleMax + 1, BufPrec, 0);

                posDiff = Math.Min(lastPosDiff, posDiff);
                if (rbFrameD.Checked || imageMode)
                {
                    BufTmp[0] = (byte)(posDiff >> 1);
                    BufTmp[1] = (byte)(posDiff >> 9);
                    Array.Copy(DiffImage, 0, BufTmp, 2, posDiff);
                }
                else
                {
                    BufTmp[0] = (byte)'D';
                    BufTmp[1] = (byte)(posDiff >> 1);
                    BufTmp[2] = (byte)(posDiff >> 9);
                    Array.Copy(DiffImage, 0, BufTmp, 3, posDiff);
                }
                int ldRaw = posDiff + (rbFrameD.Checked ? 2 : 3);
                int ld    = PackDepack.Pack(BufTmp, ldRaw, bufOut, 0);
                if (ld > ldRaw)
                {
                    img.main.SetInfo("Perte de " + (ld - ldRaw).ToString() + " octets...");
                }

                if (lo > ld && !rbFrameO.Checked || rbFrameD.Checked)
                {
                    if (imageMode)
                    {
                        rbFrameFull.Checked = false;
                        rbFrameD.Checked    = true;
                    }
                    lastAscii = 'D';
                    return(ld);
                }
                else
                {
                    Array.Copy(BufPrec, bufOut, lo);
                    if (imageMode)
                    {
                        rbFrameFull.Checked = false;
                        rbFrameO.Checked    = true;
                    }
                    lastAscii = 'O';
                    return(lo);
                }
            }
        }
Example #4
0
        private int PackDirectMem(byte[] bufOut, ref int sizeDepack, bool newMethode, bool razDiff)
        {
            if (razDiff)
            {
                Array.Clear(BufPrec, 0, BufPrec.Length);
            }

            // Copier l'image cpc dans le buffer de travail
            img.bitmapCpc.CreeBmpCpc(img.BmpLock, null);
            byte[] src = img.bitmapCpc.bmpCpc;

            int maxSize = (BitmapCpc.NbCol) + ((BitmapCpc.NbLig - 1) >> 3) * (BitmapCpc.NbCol) + ((BitmapCpc.NbLig - 1) & 7) * 0x800;

            if (maxSize >= 0x4000)
            {
                maxSize += 0x3800;
            }

            int maxDelta = newMethode ? 127 : 255;
            // Recherche les "coordonnées" de l'image différente par rapport à la précédente
            int  bc = 0, posDiff = 0;
            byte deltaAdr = 0;

            for (int adr = 0; adr < maxSize; adr++)
            {
                byte o = BufPrec[adr];
                byte n = src[adr];
                if (deltaAdr == 127 || (o != n))
                {
                    if (newMethode && adr < maxSize - 256 && BufPrec[adr + 1] != src[adr + 1] && BufPrec[adr + 2] != src[adr + 2] && src[adr + 1] == n && src[adr + 2] == n)
                    {
                        DiffImage[posDiff++] = (byte)(deltaAdr | 0x80);
                        bc++;
                        int d = 0;
                        while (d < 255 && src[adr + d] == n)
                        {
                            d++;
                        }

                        DiffImage[posDiff++] = (byte)d;
                        DiffImage[posDiff++] = n;
                        deltaAdr             = 0;
                        adr += d - 1;
                    }
                    else
                    {
                        DiffImage[posDiff++] = (byte)deltaAdr;
                        DiffImage[posDiff++] = n;
                        bc++;
                        deltaAdr = 0;
                        if (posDiff >= DiffImage.Length)
                        {
                            break;
                        }
                    }
                }
                else
                {
                    deltaAdr++;
                }
            }
            BufTmp[0] = (byte)(bc);
            BufTmp[1] = (byte)(bc >> 8);
            Buffer.BlockCopy(DiffImage, 0, BufTmp, 2, posDiff);
            int lPack = PackDepack.Pack(BufTmp, posDiff + 2, bufOut, 0);

            Array.Copy(src, BufPrec, BufPrec.Length);
            sizeDepack = posDiff + 2;
            return(lPack);
        }
Example #5
0
        public Bitmap CreateImageFromCpc(int length, Param par, bool isSprite = false)
        {
            if (!isSprite)
            {
                if (bmpCpc[0] == 'M' && bmpCpc[1] == 'J' && bmpCpc[2] == 'H')
                {
                    DepactOCP();
                }
                else
                if (bmpCpc[0] == 'P' && bmpCpc[1] == 'K' && (bmpCpc[2] == 'O' || bmpCpc[2] == 'V' || bmpCpc[2] == 'S'))
                {
                    DepactPK();
                }
                else
                {
                    if (!InitDatas())
                    {
                        if (length == 16384)
                        {
                            nbCol = 80;
                            nbLig = 200;
                        }
                        else
                        if (length < 32000)
                        {
                            int l = PackDepack.Depack(bmpCpc, 0, bufTmp);
                            Array.Copy(bufTmp, bmpCpc, l);
                            if (!InitDatas())
                            {
                                cpcPlus = false;
                                nbCol   = maxColsCpc;
                                nbLig   = maxLignesCpc;
                                SetPalette(bmpCpc, 0x600, cpcPlus);
                            }
                        }
                        else
                        {
                            if (length > 0x4000)
                            {
                                nbCol = maxColsCpc;
                                nbLig = maxLignesCpc;
                            }
                        }
                    }
                }
            }
            par.cpcPlus = cpcPlus;
            // Rendu dans un bitmap PC
            DirectBitmap loc = new DirectBitmap(nbCol << 3, nbLig * 2);

            for (int y = 0; y < nbLig << 1; y += 2)
            {
                int mode    = (modeVirtuel >= 5 ? 1 : modeVirtuel >= 3 ? (y & 2) == 0 ? modeVirtuel - 2 : modeVirtuel - 3 : modeVirtuel);
                int adrCPC  = isSprite ? nbCol * (y >> 1) : GetAdrCpc(y);
                int xBitmap = 0;
                for (int x = 0; x < nbCol; x++)
                {
                    byte octet = bmpCpc[adrCPC + x];
                    switch (mode)
                    {
                    case 0:
                        loc.SetHorLineDouble(xBitmap, y, 4, GetPalCPC(Palette[(octet >> 7) + ((octet & 0x20) >> 3) + ((octet & 0x08) >> 2) + ((octet & 0x02) << 2)]));
                        loc.SetHorLineDouble(xBitmap + 4, y, 4, GetPalCPC(Palette[((octet & 0x40) >> 6) + ((octet & 0x10) >> 2) + ((octet & 0x04) >> 1) + ((octet & 0x01) << 3)]));
                        xBitmap += 8;
                        break;

                    case 1:
                        loc.SetHorLineDouble(xBitmap, y, 2, GetPalCPC(Palette[((octet >> 7) & 1) + ((octet >> 2) & 2)]));
                        loc.SetHorLineDouble(xBitmap + 2, y, 2, GetPalCPC(Palette[((octet >> 6) & 1) + ((octet >> 1) & 2)]));
                        loc.SetHorLineDouble(xBitmap + 4, y, 2, GetPalCPC(Palette[((octet >> 5) & 1) + ((octet >> 0) & 2)]));
                        loc.SetHorLineDouble(xBitmap + 6, y, 2, GetPalCPC(Palette[((octet >> 4) & 1) + ((octet << 1) & 2)]));
                        xBitmap += 8;
                        break;

                    case 2:
                        for (int i = 8; i-- > 0;)
                        {
                            loc.SetPixel(xBitmap, y, GetPalCPC(Palette[(octet >> i) & 1]));
                            loc.SetPixel(xBitmap++, y + 1, GetPalCPC(Palette[(octet >> i) & 1]));
                        }

                        break;
                    }
                }
            }
            return(loc.Bitmap);
        }
Example #6
0
        private void DepactPK()
        {
            byte[] Palette = new byte[0x100];

            // Valeurs par défaut
            cpcPlus = false;
            nbCol   = 80;
            nbLig   = 200;

            //
            //PKSL -> 320x200 STD
            //PKS3 -> 320x200 Mode 3
            //PKSP -> 320x200 PLUS
            //PKVL -> Overscan STD
            //PKVP -> Overscan PLUS
            //

            cpcPlus = (bmpCpc[3] == 'P') || (bmpCpc[2] == 'O');
            bool Overscan = (bmpCpc[2] == 'V') || (bmpCpc[3] == 'V');
            bool Std      = (bmpCpc[2] == 'S' && bmpCpc[3] == 'L');

            if (Std)
            {
                for (int i = 0; i < 17; i++)
                {
                    Palette[i] = bmpCpc[i + 4];
                }
            }

            int l = PackDepack.Depack(bmpCpc, Std ? 21 : 4, bufTmp);

            if (Std)
            {
                int i = 0;
                for (int x = 0; x < 80; x++)
                {
                    for (int y = 0; y < 200; y++)
                    {
                        bmpCpc[x + GetAdrCpc(y << 1)] = bufTmp[i++];
                    }
                }
            }
            else
            {
                Array.Copy(bufTmp, bmpCpc, l);
            }
            if (Overscan)
            {
                nbCol = maxColsCpc;
                nbLig = maxLignesCpc;
                SetPalette(bmpCpc, 0x600, cpcPlus);
            }
            else
            {
                if (Std)
                {
                    SetPalette(Palette, 0, cpcPlus);
                }
                else
                {
                    SetPalette(bmpCpc, 0x17D0, cpcPlus);
                }
            }
        }
Example #7
0
        static public int SauveScr(string fileName, BitmapCpc bitmapCpc, ImageCpc img, Param param, bool compact, string version = null, int[,] colMode5 = null)
        {
            byte[] bufPack  = new byte[0x8000];
            bool   overscan = (BitmapCpc.NbLig * BitmapCpc.NbCol > 0x3F00);

            if (param.withPalette && version == null)
            {
                if (param.cpcPlus)
                {
                    ModePal[0] = (byte)(BitmapCpc.modeVirtuel | 0x8C);
                    int k = 1;
                    for (int i = 0; i < 16; i++)
                    {
                        ModePal[k++] = (byte)(((BitmapCpc.Palette[i] >> 4) & 0x0F) | (BitmapCpc.Palette[i] << 4));
                        ModePal[k++] = (byte)(BitmapCpc.Palette[i] >> 8);
                    }
                }
                else
                {
                    ModePal[0] = (byte)BitmapCpc.modeVirtuel;
                    for (int i = 0; i < 16; i++)
                    {
                        ModePal[1 + i] = (byte)BitmapCpc.Palette[i];
                    }
                }
            }

            byte[] imgCpc = bitmapCpc.bmpCpc;
            if (!overscan)
            {
                Buffer.BlockCopy(ModePal, 0, imgCpc, 0x17D0, ModePal.Length);
                if (param.withCode && version == null)
                {
                    if (param.cpcPlus)
                    {
                        Buffer.BlockCopy(CodeP0, 0, imgCpc, 0x07D0, CodeP0.Length);
                        Buffer.BlockCopy(CodeP1, 0, imgCpc, 0x0FD0, CodeP1.Length);
                        Buffer.BlockCopy(CodeP3, 0, imgCpc, 0x1FD0, CodeP3.Length);
                    }
                    else
                    {
                        Buffer.BlockCopy(CodeStd, 0, imgCpc, 0x07D0, CodeStd.Length);
                    }

                    if (BitmapCpc.modeVirtuel == 3 || BitmapCpc.modeVirtuel == 4)
                    {
                        Buffer.BlockCopy(codeEgx0, 0, imgCpc, 0x37D0, codeEgx0.Length);
                        Buffer.BlockCopy(codeEgx1, 0, imgCpc, 0x2FD0, codeEgx1.Length);
                        imgCpc[0x07F2] = 0xD0;
                        imgCpc[0x07F3] = 0xF7;                          //	CALL 0xF7D0
                        imgCpc[0x37FA] = 0xEF;                          //	Call 0xEFD0
                    }
                }
            }
            else
            {
                if (BitmapCpc.NbLig * BitmapCpc.NbCol > 0x4000)
                {
                    Buffer.BlockCopy(ModePal, 0, imgCpc, 0x600, ModePal.Length);
                    if (param.withCode && version == null)
                    {
                        if (param.cpcPlus)
                        {
                            Buffer.BlockCopy(CodeOvP, 0, imgCpc, 0x621, CodeOvP.Length);
                        }
                        else
                        {
                            Buffer.BlockCopy(CodeOv, 0, imgCpc, 0x611, CodeOv.Length);
                        }

                        if (BitmapCpc.modeVirtuel == 3 || BitmapCpc.modeVirtuel == 4)
                        {
                            Buffer.BlockCopy(codeEgx0, 0, imgCpc, 0x1600, codeEgx0.Length);
                            Buffer.BlockCopy(codeEgx1, 0, imgCpc, 0x1640, codeEgx1.Length);
                            if (param.cpcPlus)
                            {
                                imgCpc[0x669] = 0xCD;
                                imgCpc[0x66A] = 0x00;
                                imgCpc[0x66B] = 0x18;                                           // CALL	#1800
                            }
                            else
                            {
                                imgCpc[0x631] = 0x00;
                                imgCpc[0x632] = 0x18;                                           // CALL	#1800
                            }
                            imgCpc[0x1629] = 0x40;
                            imgCpc[0x162A] = 0x18;                              //	CALL	#1840
                        }
                    }
                }
            }

            short     startAdr = (short)(overscan ? 0x200 : 0xC000);
            short     exec     = (short)(overscan ? param.cpcPlus ? 0x821 : 0x811 : 0xC7D0);
            CpcAmsdos entete;
            int       lg = BitmapCpc.BitmapSize;

            if (compact)
            {
                lg = PackDepack.Pack(bitmapCpc.bmpCpc, lg, bufPack, 0) + 1;                 // Prendre 1 octet de marge ?
                if (param.withCode && version == null)
                {
                    Buffer.BlockCopy(codeDepack, 0, bufPack, lg, codeDepack.Length);
                    bufPack[lg + 4]  = (byte)(startAdr & 0xFF);
                    bufPack[lg + 5]  = (byte)(startAdr >> 8);
                    startAdr         = (short)(0xA657 - (lg + codeDepack.Length));
                    bufPack[lg + 1]  = (byte)(startAdr & 0xFF);
                    bufPack[lg + 2]  = (byte)(startAdr >> 8);
                    bufPack[lg + 32] = (byte)(exec & 0xFF);
                    bufPack[lg + 33] = (byte)(exec >> 8);
                    lg  += codeDepack.Length;
                    exec = (short)(0xA657 - codeDepack.Length);
                }
                else
                {
                    startAdr = (short)(0xA657 - lg);
                    exec     = 0;
                }
            }
            if (version != null)
            {
                // Sauvegarde source assembleur
                StreamWriter sw  = SaveAsm.OpenAsm(fileName, version);
                int          org = 0xA500 - lg - (BitmapCpc.modeVirtuel == 5 ? 600 : 0);
                sw.WriteLine("	ORG	#"+ org.ToString("X4"));
                sw.WriteLine("	Nolist");
                sw.WriteLine("ImageCmp:");
                SaveAsm.GenereDatas(sw, bufPack, lg, 16);
                sw.WriteLine("	List");
                if (param.withCode)
                {
                    sw.WriteLine("	RUN	$");
                    sw.WriteLine("_StartDepack:");
                    if (BitmapCpc.modeVirtuel == 3 || BitmapCpc.modeVirtuel == 4)
                    {
                        SaveAsm.GenereAfficheModeEgx(sw, BitmapCpc.Palette, overscan);
                    }
                    else
                    {
                        SaveAsm.GenereFormatEcran(sw);
                        if (BitmapCpc.modeVirtuel == 5)
                        {
                            SaveAsm.GenereAfficheModeX(sw, colMode5, overscan);
                        }
                        else
                        {
                            SaveAsm.GenereAfficheStd(sw, img, BitmapCpc.modeVirtuel, BitmapCpc.Palette, overscan);
                        }
                    }
                }
                SaveAsm.CloseAsm(sw);
            }
            else
            {
                entete = CpcSystem.CreeEntete(fileName, startAdr, (short)lg, exec);
                BinaryWriter fp = new BinaryWriter(new FileStream(fileName, FileMode.Create));
                fp.Write(CpcSystem.AmsdosToByte(entete));
                fp.Write(compact ? bufPack : bitmapCpc.bmpCpc, 0, lg);
                fp.Close();
            }
            return(lg);
        }