Yazwh0_BitMagic_Legacy/BitMagic.Machines/Palette.cs
using BitMagic.Common;
using System.Drawing;

namespace BitMagic.Machines
{
    public class Palette : NormalMemory
    {
        public PixelRgba[] Colours = new PixelRgba[0x100];

        public Palette() : base("Palette", 0x200)
        {           
        }

        public override void Init(IMemory memory, int startAddress)
        {
            base.Init(memory, startAddress);

            InitColours(new[] {
                0x000, 0xfff, 0x800, 0xafe, 0xc4c, 0x0c5, 0x00a, 0xee7, 0xd85, 0x640, 0xf77, 0x333, 0x777, 0xaf6, 0x08f, 0xbbb,
                0x000, 0x111, 0x222, 0x333, 0x444, 0x555, 0x666, 0x777, 0x888, 0x999, 0xaaa, 0xbbb, 0xccc, 0xddd, 0xeee, 0xfff,
                0x211, 0x433, 0x644, 0x866, 0xa88, 0xc99, 0xfbb, 0x211, 0x422, 0x633, 0x844, 0xa55, 0xc66, 0xf77, 0x200, 0x411,
                0x611, 0x822, 0xa22, 0xc33, 0xf33, 0x200, 0x400, 0x600, 0x800, 0xa00, 0xc00, 0xf00, 0x221, 0x443, 0x664, 0x886,
                0xaa8, 0xcc9, 0xfeb, 0x211, 0x432, 0x653, 0x874, 0xa95, 0xcb6, 0xfd7, 0x210, 0x431, 0x651, 0x862, 0xa82, 0xca3,
                0xfc3, 0x210, 0x430, 0x640, 0x860, 0xa80, 0xc90, 0xfb0, 0x121, 0x343, 0x564, 0x786, 0x9a8, 0xbc9, 0xdfb, 0x121,
                0x342, 0x463, 0x684, 0x8a5, 0x9c6, 0xbf7, 0x120, 0x241, 0x461, 0x582, 0x6a2, 0x8c3, 0x9f3, 0x120, 0x240, 0x360,
                0x480, 0x5a0, 0x6c0, 0x7f0, 0x121, 0x343, 0x465, 0x686, 0x8a8, 0x9ca, 0xbfc, 0x121, 0x242, 0x364, 0x485, 0x5a6,
                0x6c8, 0x7f9, 0x020, 0x141, 0x162, 0x283, 0x2a4, 0x3c5, 0x3f6, 0x020, 0x041, 0x061, 0x082, 0x0a2, 0x0c3, 0x0f3,
                0x122, 0x344, 0x466, 0x688, 0x8aa, 0x9cc, 0xbff, 0x122, 0x244, 0x366, 0x488, 0x5aa, 0x6cc, 0x7ff, 0x022, 0x144,
                0x166, 0x288, 0x2aa, 0x3cc, 0x3ff, 0x022, 0x044, 0x066, 0x088, 0x0aa, 0x0cc, 0x0ff, 0x112, 0x334, 0x456, 0x668,
                0x88a, 0x9ac, 0xbcf, 0x112, 0x224, 0x346, 0x458, 0x56a, 0x68c, 0x79f, 0x002, 0x114, 0x126, 0x238, 0x24a, 0x35c,
                0x36f, 0x002, 0x014, 0x016, 0x028, 0x02a, 0x03c, 0x03f, 0x112, 0x334, 0x546, 0x768, 0x98a, 0xb9c, 0xdbf, 0x112,
                0x324, 0x436, 0x648, 0x85a, 0x96c, 0xb7f, 0x102, 0x214, 0x416, 0x528, 0x62a, 0x83c, 0x93f, 0x102, 0x204, 0x306,
                0x408, 0x50a, 0x60c, 0x70f, 0x212, 0x434, 0x646, 0x868, 0xa8a, 0xc9c, 0xfbe, 0x211, 0x423, 0x635, 0x847, 0xa59,
                0xc6b, 0xf7d, 0x201, 0x413, 0x615, 0x826, 0xa28, 0xc3a, 0xf3c, 0x201, 0x403, 0x604, 0x806, 0xa08, 0xc09, 0xf0b});
        }

        private void InitColours(int[] colours)
        {
            var address = 0;
            foreach(var colour in colours)
            {
                var value = colour & 0xff;
                Memory!.WriteNotification[StartAddress + address] = WriteNotification;
                WriteNotification(StartAddress + address++, (byte)value);

                value = (colour & 0xff00) >> 8;
                Memory!.WriteNotification[StartAddress + address] = WriteNotification;
                WriteNotification(StartAddress + address++, (byte)value);
            }
        }

        // if address is even, then its Green\Blue, otherwise its blank, Red
        public void WriteNotification(int address, byte value)
        {
            var idx = (address - StartAddress) >> 1;

            if ((address & 1) == 0)
            {
                var g = value & 0xf0;
                g += g >> 4;
                var b = value & 0x0f;
                b += b << 4;

                Colours[idx] = new PixelRgba(Colours[idx].R, (byte)g, (byte)b);
            } 
            else
            {
                var r = value & 0x0f; ;
                r += r << 4;

                value = (byte)r;

                Colours[idx] = new PixelRgba(value, Colours[idx].G, Colours[idx].B);
            }

            Memory!.Memory[address] = value;
        }
    }

}
