changeset 122:ffa6533584ca

Use the MPWriteCtx class. However, due to this refactoring, there are probably various things in _exporting_ (platform format/prg) that may now be broken.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 09 Jul 2018 18:08:06 +0300
parents 25a29d29ee6a
children f49f83b9bbc7
files events.pde exporters.pde
diffstat 2 files changed, 275 insertions(+), 320 deletions(-) [+]
line wrap: on
line diff
--- a/events.pde	Mon Jul 09 18:07:04 2018 +0300
+++ b/events.pde	Mon Jul 09 18:08:06 2018 +0300
@@ -846,8 +846,9 @@
 /*
         message("Source|export");
         String fname = (g_spare ? sfilename : filename) +"_"+ (g_spare ? "spare" : "main") +".asm";
-        byte[] fdata = mpExportMachinePRG(true);
-        if (fdata != null && mpSaveBinaryFile(fname, fdata))
+        MPWriteCtx ctx = new MPWriteCtx();
+
+        if (mpExportMachinePRG(ctx) && mpSaveBinaryFile(fname, ctx.getSource()))
             message("EXPORTED");
         else
             message("COULD NOT|EXPORT");
@@ -860,8 +861,9 @@
         message("Executable|export");
 
         String fname = (g_spare ? sfilename : filename) +"_"+ (g_spare ? "spare" : "main") +"."+ g_exportext;
-        byte[] fdata = mpExportMachinePRG(false);
-        if (fdata != null && mpSaveBinaryFile(fname, fdata))
+        MPWriteCtx ctx = new MPWriteCtx();
+
+        if (mpExportMachinePRG(ctx) && mpSaveBinaryFile(fname, ctx.getData()))
             message("EXPORTED");
         else
             message("COULD NOT|EXPORT");
@@ -892,10 +894,11 @@
         if (g_formatext != "") {
             message("Format|export");
 
-            byte[] fdata = mpExportFormat(0); // XXX TODO
             String fname = filename +"_"+ (g_spare ? "spare" : "main") +"."+ g_formatext;
+            MPWriteCtx ctx = new MPWriteCtx();
 
-            if (fdata != null && mpSaveBinaryFile(fname, fdata))
+            if (mpExportFormat(ctx, 0) && // XXX TODO
+                mpSaveBinaryFile(fname, ctx.getData()))
                 message("EXPORTED");
             else
                 message("COULD NOT|EXPORT");
--- a/exporters.pde	Mon Jul 09 18:07:04 2018 +0300
+++ b/exporters.pde	Mon Jul 09 18:08:06 2018 +0300
@@ -4,7 +4,6 @@
 // remember hexdump -C !
 //
 String g_formatname, g_formatext;
-int g_dataoffs;
 int[] g_grids = new int[16];
 int OLD = 0;
 int NEW = 1;
@@ -15,6 +14,7 @@
 {
     public int m_offs, m_bpl, m_bytes, m_indent;
     public String m_byteDef, m_eol, m_src;
+    public byte[] data;
 
     MPWriteCtx()
     {
@@ -25,6 +25,7 @@
         m_byteDef = ".byte";
         m_src = "";
         m_eol = "\n";
+        m_data = new byte[1*1024];
     }
 
     void setOffs(int offs)
@@ -37,6 +38,16 @@
         m_bpl = bpl;
     }
 
+    byte[] getData()
+    {
+        return m_data;
+    }
+
+    byte[] getSource()
+    {
+        return m_src;
+    }
+
     String getIndent()
     {
         String str = "";
@@ -76,6 +87,11 @@
         m_src += m_byteDef +" ";
     }
 
+    void byteSep()
+    {
+        m_src += ",";
+    }
+
     void indent()
     {
         m_src += getIndent();
@@ -112,11 +128,16 @@
         }
     }
 
-    void writeByteAt(int offs, int bval, String blabel)
+    void writeByteAt(int boffs, int bval, String blabel)
     {
-        m_offs = offs;
+        m_offs = boffs;
         writeByte(bval, blabel);
     }
+
+    void loadTemplate(String fname)
+    {
+        m_data = mpLoadBinaryFile("templates/" + fname);
+    }
 }
 
 
@@ -133,24 +154,6 @@
 }
 
 
-void mpSetDataOffs(int offs)
-{
-    g_dataoffs = offs;
-}
-
-
-void mpWriteByte(int bb)
-{
-    g_template[g_dataoffs++] = byte(bb);
-}
-
-
-void mpLoadTemplate(String fname)
-{
-    g_template = mpLoadBinaryFile("templates/" + fname);
-}
-
-
 boolean mpImportFormat(byte[] fdata)
 {
     int x, y, x2, y2, y3, head, xx, yy, yp, ad, valu;
@@ -361,93 +364,109 @@
 }
 
 
-byte[] mpExportFormat(int subformat)
+bool mpExportFormat(MPWriteCtx ctx, int subformat)
 {
     int val1, val2, val3;
     int y, y2, yy, x, yp, xp, ad, valu, valu2, bri;
 
     if (machine == PLUS4) { // botticelli hires
-        mpLoadTemplate("g.hires.prg");
-        mpSetDataOffs(0x02);
-        mpExportColorData(40, 25, 65536, 5); //lumis
-        mpSetDataOffs(1026);
-        mpExportColorData(40, 25, 65536, 4); //colors
-        mpSetDataOffs(2050);
-        mpExportBitmapData(40, 25);
+        ctx.loadTemplate("g.hires.prg");
+
+        ctx.setOffs(0x02);
+        mpExportColorData(ctx, 40, 25, 65536, 5); //lumis
+
+        ctx.setOffs(1026);
+        mpExportColorData(ctx, 40, 25, 65536, 4); //colors
+
+        ctx.setOffs(2050);
+        mpExportBitmapData(ctx, 40, 25);
     }
     else
     if (machine == PLUS4M) { // multi botticelli multicolor
-        mpLoadTemplate("m.multi.prg");
+        ctx.loadTemplate("m.multi.prg");
+
         val2 = getpluscolor(int(g_map[1]));
         val1 = getplusluminance(int(g_map[1]));
         val3 = val2 * 16 + val1;
-        mpSetDataOffs(1025);
-        mpWriteByte(val3);
+        ctx.writeByteAt(1025, val3);
+
         val2 = getpluscolor(int(g_map[2]));
         val1 = getplusluminance(int(g_map[2]));
         val3 = val2 * 16 + val1;
-        mpSetDataOffs(1024);
-        mpWriteByte(val3);
-        mpSetDataOffs(1026);
-        mpExportColorData(40, 25, 65536, 6); //colors
-        mpSetDataOffs(2);
-        mpExportColorData(40, 25, 65536, 7); //lumis
-        mpSetDataOffs(2050);
-        mpExportBitmapData(40, 25);
+        ctx.writeByteAt(1024, val3);
+
+        ctx.setOffs(1026);
+        mpExportColorData(ctx, 40, 25, 65536, 6); //colors
+
+        ctx.setOffs(2);
+        mpExportColorData(ctx, 40, 25, 65536, 7); //lumis
+
+        ctx.setOffs(2050);
+        mpExportBitmapData(ctx, 40, 25);
     }
     else
     if (machine == C64) {
-        mpLoadTemplate("hires.art");
-        mpSetDataOffs(2);
-        mpExportBitmapData(40, 25);
-        mpSetDataOffs(0x1f42);
-        mpExportColorData(40, 25, 65536, 0);
-        mpSetDataOffs(0x232a);
-        mpWriteByte(g_map[0]);
+        ctx.loadTemplate("hires.art");
+
+        ctx.setOffs(2);
+        mpExportBitmapData(ctx, 40, 25);
+
+        ctx.setOffs(0x1f42);
+        mpExportColorData(ctx, 40, 25, 65536, 0);
+
+        ctx.writeByteAt(0x232a, g_map[0]);
     }
     else
     if (machine == C64M) {
         if (subformat == 0)
         {
             // Advanced Art Studio
-            mpLoadTemplate("multic.ocp");
-            mpSetDataOffs(2);
-            mpExportBitmapData(40, 25);
-            mpSetDataOffs(0x1f42);
-            mpExportColorData(40, 25, 65536, 1);
-            mpSetDataOffs(0x233a);
-            mpExportColorData(40, 25, 65536 + 2000, 2);
-            mpSetDataOffs(0x232a);
-            mpWriteByte(g_map[0]);
-            mpSetDataOffs(0x232b);
-            mpWriteByte(g_map[1]);
+            ctx.loadTemplate("multic.ocp");
+
+            ctx.setOffs(2);
+            mpExportBitmapData(ctx, 40, 25);
+
+            ctx.setOffs(0x1f42);
+            mpExportColorData(ctx, 40, 25, 65536, 1);
+
+            ctx.setOffs(0x233a);
+            mpExportColorData(ctx, 40, 25, 65536 + 2000, 2);
+
+            ctx.writeByteAt(0x232a, g_map[0]);
+            ctx.writeByteAt(0x232b, g_map[1]);
         }
         else
         {
             // Koala Painter
-            mpLoadTemplate("multic.kla");
-            mpSetDataOffs(2);
-            mpExportBitmapData(40, 25);
-            mpSetDataOffs(0x1f42);
-            mpExportColorData(40, 25, 65536, 1);
-            mpSetDataOffs(0x232a);
-            mpExportColorData(40, 25, 65536 + 2000, 2);
-            mpSetDataOffs(0x2712);
-            mpWriteByte(g_map[1] & 0x0f);
+            ctx.loadTemplate("multic.kla");
+
+            ctx.setOffs(2);
+            mpExportBitmapData(ctx, 40, 25);
+
+            ctx.setOffs(0x1f42);
+            mpExportColorData(ctx, 40, 25, 65536, 1);
+
+            ctx.setOffs(0x232a);
+            mpExportColorData(ctx, 40, 25, 65536 + 2000, 2);
+
+            ctx.writeByteAt(0x2712, g_map[1] & 0x0f);
         }
     }
     else
     if (machine == MSX) {
-        mpLoadTemplate("msx-screen2.sc2");
-        mpSetDataOffs(7);
-        mpExportBitmapData(32, 24);
-        mpSetDataOffs(7 + (32 * 24 * 8) + 768 + 1280);
-        mpExportColorData(32, 24, 65536, 3); //there's an exception for msx-style
+        ctx.loadTemplate("msx-screen2.sc2");
+
+        ctx.setOffs(7);
+        mpExportBitmapData(ctx, 32, 24);
+
+        ctx.setOffs(7 + (32 * 24 * 8) + 768 + 1280);
+        mpExportColorData(ctx, 32, 24, 65536, 3); //there's an exception for msx-style
     }
     else
     if (machine == SPECTRUM) {
-        mpLoadTemplate("zx-screen.scr");
-        mpSetDataOffs(0);
+        ctx.loadTemplate("zx-screen.scr");
+
+        ctx.setOffs(0);
         for (y = 0; y < 3; y++)
         for (y2 = 0; y2 < 8; y2++)
         for (yy = 0; yy < 8; yy++)
@@ -465,7 +484,7 @@
                    g_map[ad + 6] * 2 +
                    g_map[ad + 7] * 1;
 
-            mpWriteByte(valu);
+            ctx.writeByte(valu);
         }
 
         for (y = 0; y < 24; y++)
@@ -486,35 +505,34 @@
             if (bri == 1) {
                 valu += 64;
             }
-            mpWriteByte(valu + valu2 * 8);
+            ctx.writeByte(valu + valu2 * 8);
         }
     }
     else
-        return null;
+        return false;
 
-    return fdata;
+    return true;
 }
 
 
-byte[] mpExportMachinePRG(boolean sorsa)
+bool mpExportMachinePRG(MPWriteCtx ctx)
 {
     // any common text headers
-    String src = ";machine=" + str(machine) + " (" + g_name + ")\n";
-    String bsrc = "";
+    ctx.comment("machine=" + str(machine) + " (" + g_name + ")");
 
     if (machine == C64) { //C64 HIRES
+        ctx.loadTemplate("c64show.prg");
 
-        mpLoadTemplate("c64show.prg");
-        mpSetDataOffs(0x0227);
-        bsrc = mpExportBitmapData(40, 25);
+        ctx.setOffs(0x0227);
+        ctx.label("_bitmap");
+        mpExportBitmapData(ctx, 40, 25);
 
-        mpSetDataOffs(0x2167);
-        mpWriteByte(g_map[0]); //=border
-        mpSetDataOffs(0x2168);
-        mpWriteByte(g_map[1]); //=background mutta ei tarvita
-        mpSetDataOffs(0x2169);
-        src += "; The following two first values are border and background\n";
-        src += mpExportColorData(40, 25, 65536, 0);
+        ctx.comment("The following two first values are border and background");
+        ctx.writeByteAt(0x2167, g_map[0]); //=border
+        ctx.writeByteAt(0x2168, g_map[1]); //=background mutta ei tarvita
+
+        ctx.setOffs(0x2169);
+        mpExportColorData(ctx, 40, 25, 65536, 0);
 
         //c64show.prg
         //offsets
@@ -525,23 +543,22 @@
     else
     if (machine == C64M) { //C64 MULTICOLOR
 
-        mpLoadTemplate("c64mshow.prg");
-        mpSetDataOffs(0x0239);
-        bsrc = mpExportBitmapData(40, 25);
+        ctx.loadTemplate("c64mshow.prg");
+        ctx.setOffs(0x0239);
+        mpExportBitmapData(ctx, 40, 25);
 
         // first color information
-        mpSetDataOffs(0x2179);
-        mpWriteByte(g_map[0]);
-        mpSetDataOffs(0x217A);
-        mpWriteByte(g_map[1]);
-        mpSetDataOffs(0x217B);
-        src += "; The following two first values are border and background\n";
-        src += mpExportColorData(40, 25, 65536, 1);
+        ctx.comment("The following two first values are border and background");
+        ctx.writeByteAt(0x2179, g_map[0]);
+        ctx.writeByteAt(0x217a, g_map[1]);
+
+        ctx.setOffs(0x217B);
+        mpExportColorData(ctx, 40, 25, 65536, 1);
 
         // second color information
-        mpSetDataOffs(0x2563);
-        src += "; The following goes to $D800 onwards\n";
-        src += mpExportColorData(40, 25, 65536 + 2000, 2);
+        ctx.setOffs(0x2563);
+        ctx.comment("The following goes to $D800 onwards");
+        mpExportColorData(ctx, 40, 25, 65536 + 2000, 2);
 
         //c64 multicolor
         //offsets
@@ -553,43 +570,48 @@
     }
     else
     if (machine == PLUS4M) { //PLUS4 MULTICOLOR
-        mpLoadTemplate("showpfourm.prg");
-        src += "  .global _bitmap\n";
-        src += "  .global _color1\n";
-        src += "  .global _color2\n";
-        src += "  .global _border\n";
-        src += "  .global _back1\n";
-        src += "  .global _back2\n";
-        src += "_bitmap:\n";
-        mpSetDataOffs(0x013e);
-        bsrc = mpExportBitmapData(40, 25);
-        src += "_border:\n";
+        ctx.loadTemplate("showpfourm.prg");
+
+        ctx.line(".global _bitmap");
+        ctx.line(".global _color1");
+        ctx.line(".global _color2");
+        ctx.line(".global _border");
+        ctx.line(".global _back1");
+        ctx.line(".global _back2");
+
+        ctx.label("_bitmap");
+        ctx.setOffs(0x013e);
+        mpExportBitmapData(ctx, 40, 25);
+
         val1 = getpluscolor(int(g_map[0]));
         val2 = getplusluminance(int(g_map[0]));
         val3 = val2 * 16 + val1;
-        mpSetDataOffs(0x207e);
-        mpWriteByte(val3);
-        src += "  .byte " + val3 +"\n";
-        src += "_back1:\n";
+        ctx.label("_border");
+        ctx.setOffs(0x207e);
+        ctx.writeByte(val3);
+
         val1 = getpluscolor(int(g_map[1]));
         val2 = getplusluminance(int(g_map[1]));
         val3 = val2 * 16 + val1;
-        mpSetDataOffs(0x207f);
-        mpWriteByte(val3);
-        src += "  .byte " + val3 +"\n";
-        src += "_back2:\n";
+        ctx.label("_back1");
+        ctx.setOffs(0x207f);
+        ctx.writeByte(val3);
+
         val1 = getpluscolor(int(g_map[2]));
         val2 = getplusluminance(int(g_map[2]));
         val3 = val2 * 16 + val1;
-        mpSetDataOffs(0x2080);
-        mpWriteByte(val3);
-        src += "  .byte " + val3 +"\n";
-        src += "_color1:\n";
-        mpSetDataOffs(0x2081);
-        src += mpExportColorData(40, 25, 65536, 6);
-        src += "_color2:\n";
-        mpSetDataOffs(0x2469);
-        src += mpExportColorData(40, 25, 65536, 7);
+        ctx.label("_back2");
+        ctx.setOffs(0x2080);
+        ctx.writeByte(val3);
+
+        ctx.label("_color1");
+        ctx.setOffs(0x2081);
+        mpExportColorData(ctx, 40, 25, 65536, 6);
+
+        ctx.label("_color2");
+        ctx.setOffs(0x2469);
+        mpExportColorData(ctx, 40, 25, 65536, 7);
+
         //plus4 multic
         //0x013e bitmap (40 x 25 x 8)
         //0x207e border
@@ -600,24 +622,28 @@
     }
     else
     if (machine == PLUS4) { // Plus 4 hires
-        mpLoadTemplate("showpfour.prg");
-        src += "  .global _bitmap\n";
-        src += "  .global _color\n";
-        src += "  .global _lumi\n";
-        src += "  .global _border\n";
-        src += "_bitmap:\n";
-        mpSetDataOffs(0x0137);
-        bsrc = mpExportBitmapData(40, 25);
+        ctx.loadTemplate("showpfour.prg");
+
+        ctx.line(".global _bitmap");
+        ctx.line(".global _color");
+        ctx.line(".global _lumi");
+        ctx.line(".global _border");
+
+        ctx.setOffs(0x0137);
+        mpExportBitmapData(ctx, 40, 25);
+
         val1 = getpluscolor(int(g_map[0]));
         val2 = getplusluminance(int(g_map[0]));
         val3 = val2 * 16 + val1;
-        mpSetDataOffs(0x2077);
-        mpWriteByte(val3); //border
+        ctx.setOffs(0x2077);
+        ctx.writeByte(val3); //border
 
-        mpSetDataOffs(0x2078);
-        src += mpExportColorData(40, 25, 65536, 4); //colors
-        mpSetDataOffs(0x2460);
-        src += mpExportColorData(40, 25, 65536, 5); //lumis
+        ctx.setOffs(0x2078);
+        mpExportColorData(ctx, 40, 25, 65536, 4); //colors
+
+        ctx.setOffs(0x2460);
+        mpExportColorData(ctx, 40, 25, 65536, 5); //lumis
+
         //plus4 hires
         //0x0137   bitmap (40 x 25 x 8)
         //0x2077   borderi
@@ -626,17 +652,21 @@
     }
     else
     if (machine == MSX) { // MSX
-        mpLoadTemplate("msxshow.com");
-        mpSetDataOffs(0x00f9);
-        src += "\t.globl _nimi1,_nimi2\n";
-        src += "\t.area _CODE\n";
-        src += "_nimi1:\n";
-        bsrc = mpExportBitmapData(32, 24);
-        mpSetDataOffs(0x18f9);
-        //mpWriteByte(g_map[1]); //backg
-        //src += "; The first following value is background\n";
-        src += "_nimi2:\n";
-        src += mpExportColorData(32, 24, 65536, 3); //there's an exception for msx-style
+        ctx.loadTemplate("msxshow.com");
+        ctx.line(".globl _bitmap,_nimi2");
+        ctx.line(".area _CODE");
+
+        ctx.setOffs(0x00f9);
+        ctx.label("_bitmap");
+        mpExportBitmapData(ctx, 32, 24);
+
+
+        //ctx.writeByte(g_map[1]); //backg
+        //ctx.comment("The first following value is background");
+        ctx.label("_nimi2");
+        ctx.setOffs(0x18f9);
+        mpExportColorData(ctx, 32, 24, 65536, 3); //there's an exception for msx-style
+
         //msx comm
         //0x00f9 bitmap (32x24 x 8 bytes)
         //0x18f9 background color
@@ -647,10 +677,10 @@
 
         //would need some cleaning up
 
-        //  src += "  .area  _DATA\n";
-        //  src += "  .globl _taustakuva\n\n";
-        //  src += "_taustakuva:\n";
-        mpLoadTemplate("specshow.tap");
+        //  ctx.line(".area  _DATA\n";
+        //  ctx.line(".globl _taustakuva\n\n";
+        //  ctx.label("_taustakuva");
+        ctx.loadTemplate("specshow.tap");
 
         int checksum = 0xc9;
         for (y = 0x1d24; y <= 0x1d3d; y++) { //1d3e
@@ -659,36 +689,37 @@
 
         //TAP requires fiddling with the checksum
         //println("Checksum:"+hex(checksum,2));
-        mpSetDataOffs(0x0223);
-        src += ".byte " + (str(g_map[0])) + " ;border\n";
-        mpWriteByte(g_map[0]);
+        ctx.setOffs(0x0223);
+        ctx.byteDef();
+        ctx.writeByte(g_map[0]);
         checksum = checksum ^ int(g_map[0]);
 
         for (int y = 0; y <= 2; y++)
-        for (int y2 = 0; y2 <= 7; y2++)
-        for (int yy = 0; yy <= 7; yy++)
+        for (int y2 = 0; y2 < 8; y2++)
+        for (int yy = 0; yy < 8; yy++)
         {
-            src += ".byte ";
-            for (int x = 0; x <= 31; x++)
+            for (int x = 0; x < 32; x++)
             {
                 int yp = y * 64 + yy * 8 + y2,
                     ad = 1024 + yp * 256 + x * 8,
-                    valu = g_map[ad + 0] * 128 + g_map[ad + 1] * 64 + g_map[ad + 2] * 32 + g_map[ad + 3] * 16 + g_map[ad + 4] * 8 + g_map[ad + 5] * 4 + g_map[ad + 6] * 2 + g_map[ad + 7] * 1;
+                    valu =
+                        g_map[ad + 0] * 128 +
+                        g_map[ad + 1] * 64 +
+                        g_map[ad + 2] * 32 +
+                        g_map[ad + 3] * 16 +
+                        g_map[ad + 4] * 8 +
+                        g_map[ad + 5] * 4 +
+                        g_map[ad + 6] * 2 +
+                        g_map[ad + 7] * 1;
 
-                src += str(valu);
-                mpWriteByte(valu);
+                ctx.writeByte(valu);
                 checksum = checksum ^ int(valu);
-                if (x <= 30) {
-                    src += ",";
-                }
             }
-            src += "\n";
         }
 
-        src += "; attributes\n";
+        ctx.comment("attributes");
         for (int y = 0; y < 24; y++)
         {
-            src += ".byte ";
             for (int x = 0; x < 32; x++)
             {
                 int ad = 65536 + x + y * 256,
@@ -709,42 +740,34 @@
                     valu = valu + 64;
                 }
 
-                src += str(valu + valu2 * 8);
-                mpWriteByte(valu + valu2 * 8);
+                ctx.writeByte(valu + valu2 * 8);
                 checksum = checksum ^ int(valu + valu2 * 8);
-                if (x <= 30) {
-                    src += ",";
-                }
             }
-            src += "\n";
         }
+
         //println("checksum:"+hex(checksum,2));
-        mpSetDataOffs(0x1d3e);
-        mpWriteByte(int(checksum));
+        ctx.writeByteAt(0x1d3e, int(checksum));
     }
     else
     if (machine == CPC) {
         int val1, val2, val3, valu;
-        mpLoadTemplate("cpc-mode0.bin");
+        ctx.loadTemplate("cpc-mode0.bin");
 
-        mpSetDataOffs(69); //bitmap offset
-        bsrc = mpExportBitmapData_CPC(160, 200);
-        mpSetDataOffs(16453);
-        src += ";palette\n";
-        src += ".byte ";
+        ctx.setOffs(69); //bitmap offset
+        ctx.label("_bitmap");
+        mpExportBitmapData_CPC(ctx, 160, 200);
 
         //fixed # of palette entries, just trying to be generic
+        ctx.setOffs(16453);
+        ctx.setBPL(g_maxcolors - 1);
+        ctx.label("_palette");
         for (int i = 0; i < g_maxcolors; i++)
         {
             val1 = int(g_g[i] / (256 / g_palsteps));
             val2 = int(g_r[i] / (256 / g_palsteps));
             val3 = int(g_b[i] / (256 / g_palsteps));
 
-            mpWriteByte(val1 * 9 + val2 * 3 + val3);
-            src += str(val1 * 9 + val2 * 3 + val3);
-            if (i < g_maxcolors - 1) {
-                src += ",";
-            }
+            ctx.writeByte(ctx, val1 * 9 + val2 * 3 + val3);
         }
 
         valu = int(g_map[0]);
@@ -752,108 +775,84 @@
         val2 = int(g_r[valu] / (256 / g_palsteps));
         val3 = int(g_b[valu] / (256 / g_palsteps));
 
-        src += "\n";
-        src += ";border\n";
-        src += ".byte ";
+        ctx.label("_border");
+        ctx.setOffs(16469);
+        ctx.writeByte(val1 * 9 + val2 * 3 + val3);
 
-        mpSetDataOffs(16469);
-
-        mpWriteByte(val1 * 9 + val2 * 3 + val3);
-        src += str(val1 * 9 + val2 * 3 + val3);
         //cpc
         //69    bitmap 16384 bytes
         //16453 palette 16 bytes (0..26)
         //16469 border color (0..26)
     }
     else
-        return null;
+        return false;
 
-    // any common lead-outs
-    if (sorsa)
-        return src +"\n"+ bsrc;
-    else
-        return g_template;
+    return true;
 }
 
 
-String mpExportBitmapData_CPC(int xwid, int yy)
+void mpExportBitmapData_CPC(MPWriteCtx ctx, int xwid, int yy)
 {
     int x, y, ad, val1, val2, y2;
     int pix0b0, pix0b1, pix0b2, pix0b3;
     int pix1b0, pix1b1, pix1b2, pix1b3;
-    String src = ";bitmap\n";
+
+    ctx.setBPL(xwid / 2);
+    ctx.byteDef();
 
     for (y2 = 0; y2 < 8; y2++)
     {
         for (y = 0; y < 25; y++)
+        for (x = 0; x < int(xwid / 2); x++)
         {
-            src += "  .byte ";
-            for (x = 0; x < int(xwid / 2); x++) {
-                ad = 1024 + (y * 8) * X + (y2 * X) + x * 4;
+            ad = 1024 + (y * 8) * X + (y2 * X) + x * 4;
 
-                val1 = int(g_map[ad]);
-                pix0b0 = 0;
-                pix0b1 = 0;
-                pix0b2 = 0;
-                pix0b3 = 0;
-                if ((val1 & 1) != 0) pix0b0 = 1;
-                if ((val1 & 2) != 0) pix0b1 = 1;
-                if ((val1 & 4) != 0) pix0b2 = 1;
-                if ((val1 & 8) != 0) pix0b3 = 1;
+            val1 = int(g_map[ad]);
+            pix0b0 = 0;
+            pix0b1 = 0;
+            pix0b2 = 0;
+            pix0b3 = 0;
+            if ((val1 & 1) != 0) pix0b0 = 1;
+            if ((val1 & 2) != 0) pix0b1 = 1;
+            if ((val1 & 4) != 0) pix0b2 = 1;
+            if ((val1 & 8) != 0) pix0b3 = 1;
 
-                val1 = int(g_map[ad + 2]);
-
-                pix1b0 = 0;
-                pix1b1 = 0;
-                pix1b2 = 0;
-                pix1b3 = 0;
-                if ((val1 & 1) != 0) pix1b0 = 1;
-                if ((val1 & 2) != 0) pix1b1 = 1;
-                if ((val1 & 4) != 0) pix1b2 = 1;
-                if ((val1 & 8) != 0) pix1b3 = 1;
+            val1 = int(g_map[ad + 2]);
 
-                val2 = pix1b3 + pix0b3 * 2 + pix1b1 * 4 + pix0b1 * 8 + pix1b2 * 16 + pix0b2 * 32 + pix1b0 * 64 + pix0b0 * 128;
-
-                src += str(int(val2));
-                mpWriteByte(val2);
-
-                if (x < int(xwid / 2) - 1) {
-                    src += ",";
-                }
-            }
-            src += "\n";
-        }
-        src += "  .byte ";
+            pix1b0 = 0;
+            pix1b1 = 0;
+            pix1b2 = 0;
+            pix1b3 = 0;
+            if ((val1 & 1) != 0) pix1b0 = 1;
+            if ((val1 & 2) != 0) pix1b1 = 1;
+            if ((val1 & 4) != 0) pix1b2 = 1;
+            if ((val1 & 8) != 0) pix1b3 = 1;
 
+            val2 = pix1b3 + pix0b3 * 2 + pix1b1 * 4 + pix0b1 * 8 + pix1b2 * 16 + pix0b2 * 32 + pix1b0 * 64 + pix0b0 * 128;
+
+            ctx.writeByte(val2);
+        }
+
+        ctx.byteDef();
         for (int j = 0; j <= 47; j++)
-        {
-            mpWriteByte(0);
-            src += str(int(0));
-            if (j < 47) {
-                src += ",";
-            }
-        }
-        src += "\n";
+            ctx.writeByte(0);
+        ctx.eol();
     }
-    src += "\n";
-    return src;
+    ctx.eod();
 }
 
 
-String mpExportBitmapData(int xx, int yy)
+void mpExportBitmapData(MPWriteCtx ctx, int xx, int yy)
 {
-    String src = "";
-    //String src = "unsigned char img[]={";
-
     int linep = 0,
         xwid  = xx * 8,
         ywid = yy * 8;
 
+    ctx.setBPL(64);
+    ctx.byteDef();
     for (int y = 0; y < yy; y++)
     for (int x = 0; x < xx; x++)
     {
-        // src += "  .byte ";
-        src += "\t.db ";
         for (int y2 = 0; y2 < 8; y2++)
         {
             int ad = 1024 + y * (xwid * 8) + (y2 * xwid) + x * 8;
@@ -867,23 +866,10 @@
                 g_map[ad + 6] * 2 +
                 g_map[ad + 7] * 1;
 
-            src += str(int(value));
-            mpWriteByte(int(value));
-
-            if (y2 <= 6) {
-                src += ",";
-            }
-        }
-        src += "\n";
-        if (++linep == xx)
-        {
-            linep = 0;
-            src += "\n";
+            ctx.writeByte(int(value));
         }
     }
-    src += "\n";
-
-    return src;
+    ctx.eod();
 }
 
 
@@ -935,10 +921,9 @@
 }
 
 
-String mpExportColorData(int xx, int yy, int source, int param)
+void mpExportColorData(MPWriteCtx ctx, int xx, int yy, int source, int param)
 {
     int valu, valu2, kalu, muista, ad, linep, xwid, ywid, xoor, yline, myrpsi;
-    String src = "";
 
     xwid = xx * 8;
     ywid = yy * 8;
@@ -952,38 +937,13 @@
     if (machine == MSX) {
         myrpsi = 7;
     }
-    if (param < 2) {
-        src += "colora:\n";
-    }
-    if (param == 2) {
-        src += "colorb:\n";
-    }
-    if (param < 2) {
-        src += "  .byte " + int(g_map[0]) + "," + int(g_map[1]) +"\n";
-    }
     if (param == 3) {
-        //   src += "color:\n";
-        //   src += "  .byte ";
-        //  src += g_map[0]+" \n";
         xoor = xx * 8;
     }
-    if (param == 4) {
-        src += "_border:\n";
-        src += "  .byte ";
-        kalu = getpluscolor(int(g_map[0]));
-        valu2 = getplusluminance(int(g_map[0]));
-        valu = valu2 * 16 + kalu;
-        src += valu + " \n";
-        src += "_color:\n";
-    }
-    if (param == 5) {
-        src += "_lumi:\n";
-    }
 
     for (int y = 0; y < yy; y++)
     {
-        //src += "  .byte ";
-        src += "\t.db ";
+        ctx.byteDef();
         for (int x = 0; x < xx; x++)
         for (yline = 0; yline <= myrpsi; yline++)
         {
@@ -1039,17 +999,10 @@
                     return null;
             }
 
-            src += str(valu * 16 + valu2);
-            mpWriteByte(valu * 16 + valu2);
-            if (x < (xx - 1) || yline < myrpsi)
-            {
-                src += ",";
-            }
+            ctx.writeByte(valu * 16 + valu2);
         }
-        src += "\n";
+        ctx.eol();
     }
-
-    return src +"\n";
 }
 
 
@@ -1236,7 +1189,6 @@
             {
                 for (xx = cx * 8; xx <= cx * 8 + 7; xx = xx + molox)
                 {
-
                     x2 = int(image.width / X) * xx;
                     y2 = int(image.height / Y) * yy;