/* Copyright 2016 Castle Technology Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/* Tables.c */

/*
 * ScreenModes lookup tables.
 */

#include <stdint.h>
#include <stdbool.h>

#include "kernel.h"
#include "Global/VIDCList.h"

#include "modex.h"
#include "tables.h"

/* These timings are taken from the Display Monitor Timings v1.0 r11 Spec */
const ModeDefinition display_monitor_timings[] = {
    /* 640 x 350 @ 85Hz STD n/a, CVT n/a */
    "640 x 350",    640, 350,   64,  96, 0,  640, 0, 32,
                                 3,  60, 0,  350, 0, 32,
                    31500, -1,  PN,   0, 85,   0,
    /* 640 x 400 @ 85Hz STD n/a, CVT n/a */
    "640 x 400",    540, 400,   64,  96, 0,  640, 0, 32,
                                 3,  41, 0,  400, 0,  1,
                    31500, -1,  NP,   0, 85,   0,
    /* 720 x 400 @ 85Hz STD n/a, CVT n/a */
    "720 x 400",    720, 400,   72, 108, 0,  720, 0, 36,
                                 3,  42, 0,  400, 0,  1,
                    35500, -1,  NP,   0, 85,   0,
    /* 640 x 480 @ 60Hz, STD (31, 40)h, CVT n/a */
    "640 x 480",    640, 480,   96,  40, 8,  640, 8,  8,
                                 2,  25, 8,  480, 8,  2,
                    25175, -1,  NN,   0, 60,   0,
    /* 640 x 480 @ 72Hz, STD (31, 4C), CVT n/a */
    "640 x 480",    640, 480,   40, 120, 8,  640, 8, 16,
                                 3,  20, 8,  480, 8,  1,
                    31500, -1,  NN,   0, 72,   0,
    /* 640 x 480 @ 75Hz, STD (31, 4F), non-CVT com */
    "640 x 480",    640, 480,   64, 120, 0,  640, 0, 16,
                                 3,  16, 0,  480, 0,  1,
                    31500, -1,  NN,   0, 75,   0,
    /* 640 x 480 @ 85Hz, STD (31, 59), non-CVT compliant */
    "640 x 480",    640, 480,   56,  80, 0,  640, 0, 56,
                                 3,  25, 0,  480, 0,  1,
                    36000, -1,  NN,   0, 85,   0,
    /* 800 x 600 @ 56Hz, STD n/a, CVT n/a */
    "800 x 600",    800, 600,   72, 128, 0,  800, 0, 24,
                                 2,  22, 0,  600, 0,  1,
                    36000, -1,  PP,   0, 56,   0,
    /* 800 x 600 @ 60Hz, STD (45, 50), CVT n/a */
    "800 x 600",    800, 600,  128,  88, 0,  800, 0, 40,
                                 4,  23, 0,  600, 0,  1,
                    40000, -1,  PP,   0, 60,   0,
    /* 800 x 600 @ 72Hz, STD (45, 4C), CVT n/a */
    "800 x 600",    800, 600,  120,  64, 0,  800, 0, 56,
                                 6,  23, 0,  600, 0, 37,
                    50000, -1,  PP,   0, 72,   0,
    /* 800 x 600 @ 75Hz, STD (45, 4F), CVT n/a */
    "800 x 600",    800, 600,   80, 160, 0,  800, 0, 16,
                                 3,  21, 0,  600, 0,  1,
                    49500, -1,  PP,   0, 75,   0,
    /* 800 x 600 @ 85Hz, STD (45, 59), CVT n/a */
    "800 x 600",    800, 600,   64, 152, 0,  800, 0, 32,
                                 3,  27, 0,  600, 0,  1,
                    56250, -1,  PP,   0, 85,   0,
    /* 800 x 600 @ 120Hz CVT (RB), STD n/a, CVT n/a */
    "800 x 600",    800, 600,   32,  80, 0,  800, 0, 48,
                                 4,  29, 0,  600, 0,  3,
                    73250, -1,  PN,   0, 120,  0,
    /* 848 x 480 @ 60Hz, STD n/a, CVT n/a */
    "848 x 480",    848, 480,  112, 112, 0,  848, 0, 16,
                                 8,  23, 0,  480, 0,  6,
                    33750, -1,  PP,   0, 60,   0,
    /* 1024 x 768 @ 43Hz (I), STD n/a, CVT n/a */
    "1024 x 768",  1024, 768,  176,  56, 0, 1024, 0,  8,
                                 4,  20, 0,  384, 0,  0,
                    44900, -1,  PP,   1, 43,   0,
    /* 1024 x 768 @ 60Hz, STD (61, 40), CVT n/a */
    "1024 x 768",  1024, 768,  136, 160, 0, 1024, 0, 24,
                                 6,  29, 0,  768, 0,  3,
                    65000, -1,  NN,   0, 60,   0,
    /* 1024 x 768 @ 70Hz, STD (61, 4A), CVT n/a */
    "1024 x 768",  1024, 768,  136, 144, 0, 1024, 0, 24,
                                 6,  29, 0,  768, 0,  3,
                    75000, -1,  NN,   0, 70,   0,
    /* 1024 x 768 @ 75Hz, STD (61, 4F), CVT n/a */
    "1024 x 768",  1024, 768,   96, 176, 0, 1024, 0, 16,
                                 3,  28, 0,  768, 0,  1,
                    78750, -1,  PP,   0, 75,   0,
    /* 1024 x 768 @ 85Hz, STD (61, 59), CVT n/a */
    "1024 x 768",  1024, 768,   96, 208, 0, 1024, 0, 48,
                                 3,  36, 0,  768, 0,  1,
                    94500, -1,  PP,   0, 85,   0,
    /* 1024 x 768 @ 120Hz CVT (RB), STD n/a, CVT n/a */
    "1024 x 768",  1024, 768,   32,  80, 0, 1024, 0, 48,
                                 4,  38, 0,  768, 0,  3,
                   115500, -1,  PN,   0, 120,  0,
    /* 1152 x 864 @ 75Hz, STD (71, 4F), CVT n/a */
    "1152 x 864",  1152, 864,  128, 256, 0, 1152, 0, 64,
                                 3,  32, 0,  864, 0,  1,
                   108000, -1,  PP,   0, 75,   0,
    /* 1280 x 768 @ 60Hz, STD n/a, CVT-RB (7f, 1c, 21) */
    "1280 x 768",  1280, 768,   32,  80, 0, 1280, 0, 48,
                                 7,  12, 0,  768, 0,  3,
                    68250, -1,  PN,   0, 60,   0,
    /* 1280 x 768 @ 60Hz, STD n/a, CVT (7f, 1c, 28) */
    "1280 x 768",  1280, 768,  128, 192, 0, 1280, 0, 64,
                                 7,  20, 0,  768, 0,  3,
                    79500, -1,  NP,   0, 60,   0,
    /* 1280 x 768 @ 75Hz, STD n/a, CVT (7f, 1c, 44) */
    "1280 x 768",  1280, 768,  128, 208, 0, 1280, 0, 80,
                                 7,  27, 0,  768, 0,  3,
                   102250, -1,  NP,   0, 75,   0,
    /* 1280 x 768 @ 85Hz, STD n/a, CVT (7F, 1c, 62) */
    "1280 x 768",  1280, 768,  136, 216, 0, 1280, 0, 80,
                                 7,  31, 0,  768, 0,  3,
                   117500, -1,  NP,   0, 85,   0,
    /* 1280 x 768 @ 120Hz RB, STD n/a, CVT n/a (non-interlaced) */
    "1280 x 768",  1280, 768,   32,  80, 0, 1280, 0, 48,
                                 7,  35, 0,  768, 0,  3,
                   140250, -1,  PN,   0, 120,  0,
    /* 1280 x 800 @ 60Hz, STD n/a, CVT-RB (8f, 18, 21) */
    "1280 x 800",  1280, 800,   32,  80, 0, 1280, 0, 48,
                                 6,  14, 0,  800, 0,  3,
                    71000, -1,  PN,   0, 60,   0,
    /* 1280 x 800 @ 60Hz, STD (81, 00), CVT (8f, 18, 28) */
    "1280 x 800",  1280, 800,  128, 200, 0, 1280, 0, 72,
                                 6,  22, 0,  800, 0,  3,
                    83500, -1,  NP,   0, 60,   0,
    /* 1280 x 800 @ 75Hz, STD (81, 0f), CVT (8f, 18, 44) */
    "1280 x 800",  1280, 800,  128, 208, 0, 1280, 0, 80,
                                 6,  29, 0,  800, 0,  3,
                   106500, -1,  NP,   0, 75,   0,
    /* 1280 x 800 @ 85Hz, STD (81, 19), CVT (8f, 18, 62) */
    "1280 x 800",  1280, 800,  136, 216, 0, 1280, 0, 80,
                                 6,  34, 0,  800, 0,  3,
                   122500, -1,  NP,   0, 85,   0,
    /* 1280 x 800 @ 120Hz RB, STD n/a, CVT n/a (non-interlaced) */
    "1280 x 800",  1280, 800,   32,  80, 0, 1280, 0, 48,
                                 6,  38, 0,  800, 0,  3,
                   146250, -1,  PN,   0, 120,  0,
    /* 1280 x 960 @ 60Hz, STD (81, 40), CVT n/a */
    "1280 x 960",  1280, 960,  112, 312, 0, 1280, 0, 96,
                                 3,  36, 0,  960, 0,  1,
                   108000, -1,  PP,   0, 60,   0,
    /* 1280 x 960 @ 85Hz, STD (81, 59), CVT n/a */
    "1280 x 960",  1280, 960,  160, 224, 0, 1280, 0, 64,
                                 3,  47, 0,  960, 0,  1,
                   148500, -1,  PP,   0, 85,   0,
    /* 1280 x 960 @ 120Hz RB, STD n/a, CVT n/a */
    "1280 x 960",  1280, 960,   32,  80, 0, 1280, 0, 48,
                                 4,  50, 0,  960, 0,  3,
                   175500, -1,  PN,   0, 120,  0,
    /* 1280 x 1024 @ 60Hz, STD n/a, CVT n/a */
    "1280 x 1024", 1280, 1024, 112, 248, 0, 1280, 0, 48,
                                 3,  38, 0, 1024, 0,  1,
                   108000, -1,  PP,   0, 60,   0,
    /* 1280 x 1024 @ 75Hz, STD (81, 8f), CFT n/a */
    "1280 x 1024", 1280, 1024, 144, 248, 0, 1280, 0, 16,
                                 3,  38, 0, 1024, 0,  1,
                   135000, -1,  PP,   0, 75,   0,
    /* 1280 x 1024 @ 85Hz, STD (81, 99), CVT n/a */
    "1280 x 1024", 1280, 1024, 160, 224, 0, 1280, 0, 64,
                                 3,  44, 0, 1024, 0,  1,
                   157500, -1,  PP,   0, 85,   0,
    /* 1280 x 1024 @ 120Hz (RB), STD n/a, CVT n/a */
    "1280 x 1024", 1280, 1024,  32,  80, 0, 1280, 0, 48,
                                 7,  50, 0, 1024, 0,  3,
                   187250, -1,  PN,   0, 120, 0,
    /* 1360 x 768 @ 60Hz, STD n/a, CVT n/a */
    "1360 x 768",  1360,  768, 112, 256, 0, 1360, 0, 64,
                                 6,  18, 0,  768, 0,  3,
                    85500, -1,  PP,   0, 60, 0,
    /* 1360 x 768 @ 120Hz (RB), STD n/a, CVT n/a */
    "1360 x 768",  1360,  768,  32,  80, 0, 1360, 0, 48,
                                 5,  37, 0,  768, 0,  3,
                   148250, -1,  PN,   0, 120, 0,
    /* 1400 x 1050 @ 60Hz CVT (RB), STD n/a, CVT (0c, 20, 21) */
    "1400 x 1050", 1400, 1050,  32,  80, 0, 1400, 0, 48,
                                 4,  23, 0, 1050, 0,  3,
                   101000, -1,  PN,   0, 60, 0,
    /* 1400 x 1050 @ 60Hz, STD (90, 40), CVT (0c, 20, 28) */
    "1400 x 1050", 1400, 1050, 144, 232, 0, 1400, 0, 88,
                                 4,  32, 0, 1050, 0, 3,
                   121750, -1,  NP,   0, 60, 0,
    /* 1400 x 1050 @ 75Hz, STD (90, 4f), CVT (0c, 20, 44) */
    "1400 x 1050", 1400, 1050, 144, 248, 0, 1400, 0, 104,
                                 4,  42, 0, 1050, 0, 3,
                   156000, -1,  NP,   0, 75, 0,
    /* 1400 x 1050 @ 85Hz, STD (90, 59), CVT (0c, 20, 62) */
    "1400 x 1050", 1400, 1050, 152, 256, 0, 1400, 0, 104,
                                 4,  48, 0, 1050, 0, 3,
                   179500, -1,  NP,   0, 85, 0,
    /* 1400 x 1050 @ 120Hz CVT (RB), STD n/a, CVT n/a */
    "1400 x 1050", 1400, 1050,  32,  80, 0, 1400, 0, 48,
                                 4,  55, 0, 1050, 0, 3,
                   208000, -1,  PN,   0, 120, 0,
    /* 1440 x 900 @ 60Hz CVT (RB), STD n/a, CVT (c1, 18, 21) */
    "1440 x 900",  1440,  900,  32,  80, 0, 1440, 0, 48,
                                 6,  17, 0,  900, 0, 3,
                   88750, -1,   PN,   0, 60, 0,
    /* 1440 x 900 @ 60Hz, STD (95,00), CVT (C1, 18, 28) */
    "1440 x 900",  1440,  900, 152, 232, 0, 1440, 0, 80,
                                 6,  25, 0,  900, 0, 3,
                  106500, -1,   NP,   0, 60, 0,
    /* 1440 x 900 @ 75Hz, STD (95,0f), CVT (C1, 18, 44) */
    "1440 x 900",  1440,  900, 152, 248, 0, 1440, 0, 96,
                                 6,  33, 0,  900, 0, 3,
                  136750, -1,   NP,   0, 75, 0,
    /* 1440 x 900 @ 85Hz, STD (95,19), CVT (C1, 18, 68) */
    "1440 x 900",  1440,  900, 152, 256, 0, 1440, 0, 104,
                                 6,  39, 0,  900, 0, 3,
                  157000, -1,   NP,   0, 85, 0,
    /* 1440 x 900 @ 120Hz RB, STD n/a, CVT n/a, */
    "1440 x 900",  1440,  900,  32,  80, 0, 1440, 0, 48,
                                 6,  44, 0,  900, 0, 3,
                  182750, -1,   PN,   0, 120, 0,
    /* 1600 x 1200 @ 60Hz, STD (a9, 40), CVT n/a */
    "1600 x 1200", 1600, 1200, 192, 304, 0, 1600, 0, 64,
                                 3,  46, 0, 1200, 0, 1,
                  162000, -1,   PP,   0, 60, 0,
    /* 1600 x 1200 @ 65Hz, STD (a9,45), CVT n/a */
    "1600 x 1200", 1600, 1200, 192, 304, 0, 1600, 0, 64,
                                 3,  46, 0, 1200, 0, 1,
                  175500, -1,   PP,   0, 65, 0,
    /* 1600 x 1200 @ 70Hz, STD (a9,4a), CVT n/a */
    "1600 x 1200", 1600, 1200, 192, 304, 0, 1600, 0, 64,
                                 3,  46, 0, 1200, 0, 1,
                  189000, -1,   PP,   0, 70, 0,
    /* 1600 x 1200 @ 75Hz, STD (a9,4f), CVT n/a */
    "1600 x 1200", 1600, 1200, 192, 304, 0, 1600, 0, 64,
                                 3,  46, 0, 1200, 0, 1,
                  202500, -1,   PP,   0, 75, 0,
    /* 1600 x 1200 @ 85Hz, STD (a9,59), CVT n/a */
    "1600 x 1200", 1600, 1200, 192, 304, 0, 1600, 0, 64,
                                 3,  46, 0, 1200, 0, 1,
                  229500, -1,   PP,   0, 85, 0,
    /* 1600 x 1200 @ 120Hz, STD n/a, CVT n/a */
    "1600 x 1200", 1600, 1200,  32,  80, 0, 1600, 0, 48,
                                 4,  64, 0, 1200, 0, 3,
                  268250, -1,   PN,   0, 120, 0,
    /* 1680 x 1050 @ 60Hz CVT (RB), STD n/a, CVT (0c, 28, 21) */
    "1680 x 1050", 1680, 1050,  32,  80, 0, 1680, 0, 48,
                                 6,  21, 0, 1050, 0, 3,
                  119000, -1,   PN,   0, 60, 0,
    /* 1680 x 1050 @ 60Hz, STD (b3, 00), CVT (0c, 28, 28) */
    "1680 x 1050", 1680, 1050, 176, 280, 0, 1680, 0, 104,
                                 6,  30, 0, 1050, 0, 3,
                  146250, -1,   NP,   0, 60, 0,
    /* 1680 x 1050 @ 75Hz, STD (b3, 0f), CVT (0c, 28, 44) */
    "1680 x 1050", 1680, 1050, 176, 296, 0, 1680, 0, 120,
                                 6,  40, 0, 1050, 0, 3,
                  187000, -1,   NP,   0, 75, 0,
    /* 1680 x 1050 @ 85Hz, STD (b3, 19), CVT (0c, 2c, 68) */
    "1680 x 1050", 1680, 1050, 176, 304, 0, 1680, 0, 128,
                                 6,  46, 0, 1050, 0, 3,
                  214750, -1,   NP,   0, 85, 0,
    /* 1680 x 1050 @ 120Hz CVT-RN. STD n/a, CVT n/a */
    "1680 x 1050", 1680, 1050,  32,  80, 0, 1680, 0, 48,
                                 6,  53, 0, 1050, 0, 3,
                  245500, -1,   PN,   0, 120, 0,
    /* 1792 x 1344 @ 60Hz, STD (c1, 40), CVT n/a */
    "1792 x 1344", 1792, 1344, 200, 328, 0, 1792, 0, 128,
                                 3,  46, 0, 1344, 0, 1,
                  204750, -1,   NP,   0, 60, 0,
    /* 1792 x 1344 @ 75Hz, STD (c1, 4f), CVT n/a */
    "1792 x 1344", 1792, 1344, 216, 352, 0, 1792, 0, 96,
                                 3,  69, 0, 1344, 0, 1,
                  261000, -1,   NP,   0, 75, 0,
    /* 1792 x 1344 @ 120Hz CVT-RB, STD n/a, CVT n/a */
    "1792 x 1344", 1792, 1344,  32,  80, 0, 1792, 0, 48,
                                 4,  72, 0, 1344, 0, 3,
                  333250, -1,   PN,   0, 120, 0,
    /* 1856 x 1392 @ 60Hz, STD (c9, 40), CVT n/a */
    "1856 x 1392", 1856, 1392, 224, 352, 0, 1856, 0, 96,
                                 3,  43, 0, 1392, 0, 1,
                  218250, -1,   NP,   0, 60, 0,
    /* 1856 x 1392 @ 75Hz, STD (c9, 4f), CVT n/a */
    "1856 x 1392", 1856, 1392, 224, 352, 0, 1856, 0, 128,
                                 3, 104, 0, 1392, 0, 1,
                  288000, -1,   NP,   0, 75, 0,
    /* 1856 x 1392 @ 120Hz CVT-RB, STD n/a, CVT n/a */
    "1856 x 1392", 1856, 1392,  32,  80, 0, 1856, 0, 48,
                                 4,  75, 0, 1392, 0, 3,
                  356500, -1,   PN,   0, 120, 0,
    /* 1920 x 1200 @ 60Hz RB, STD n/a, CVT (57,28,21) */
    "1920 x 1200", 1920, 1200,  32,  80, 0, 1920, 0, 48,
                                 6,  26, 0, 1200, 0, 3,
                  154000, -1,   PN,   0, 60, 0,
    /* 1920 x 1200 @ 60Hz, STD (d1, 00), CVT (57, 28, 28) */
    "1920 x 1200", 1920, 1200, 200, 336, 0, 1920, 0, 136,
                                 6,  36, 0, 1200, 0, 3,
                  193250, -1,   NP,   0, 60, 0,
    /* 1920 x 1200 @ 75Hz, STD (d1, 0f), CVT (57, 28, 44) */
    "1920 x 1200", 1920, 1200, 208, 344, 0, 1920, 0, 136,
                                 6,  46, 0, 1200, 0, 3,
                  245250, -1,   NP,   0, 75, 0,
    /* 1920 x 1200 @ 85Hz, STD (d1, 19), CVT (57, 28, 62) */
    "1920 x 1200", 1920, 1200, 208, 352, 0, 1920, 0, 144,
                                 6,  53, 0, 1200, 0, 3,
                  281250, -1,   NP,   0, 85, 0,
    /* 1920 x 1200 @ 120Hz CVT-RB, STD n/a, CVT n/a */
    "1920 x 1200", 1920, 1200,  32,  80, 0, 1920, 0, 48,
                                 6,  62, 0, 1200, 0, 3,
                  317000, -1,   PN,   0, 120, 0,
    /* 1920 x 1440 @ 60Hz, STD (d1, 40), CVT n/a */
    "1920 x 1440", 1920, 1440, 208, 344, 0, 1920, 0, 128,
                                 3,  56, 0, 1440, 0, 1,
                  234000, -1,   NP,   0, 60, 0,
    /* 1920 x 1440 @ 75Hz, STD (d1, 4f), CVT n/a */
    "1920 x 1440", 1920, 1440, 224, 352, 0, 1920, 0, 144,
                                 3,  56, 0, 1440, 0, 1,
                  297000, -1,   NP,   0, 75, 0,
    /* 1920 x 1440 @ 120Hz RB, STD n/a, CVT n/a */
    "1920 x 1440", 1920, 1440,  32,  80, 0, 1920, 0, 48,
                                 4,  78, 0, 1440, 0, 3,
                  380500, -1,   PN,   0, 120, 0,
    /* 2560 x 1600 CVT-RB, STD n/a, CVT (1f, 38, 21) */
    "2560 x 1600", 2560, 1600,  32,  80, 0, 2560, 0, 48,
                                 6,  37, 0, 1600, 0, 3,
                  268500, -1,   PN,   0, 60, 0,
    /* 2560 x 1600 @ 60Hz, STD n/a, CVT (1f, 38, 28) */
    "2560 x 1600", 2560, 1600, 280, 472, 0, 2560, 0, 192,
                                 6,  49, 0, 1600, 0, 3,
                  348500, -1,   NP,   0, 60, 0,
    /* 2560 x 1600 @ 75Hz, STD n/a, CVT (1f, 38, 44) */
    "2560 x 1600", 2560, 1600, 280, 488, 0, 2560, 0, 208,
                                 6,  63, 0, 1600, 0, 3,
                  443250, -1,   NP,   0, 75, 0,
    /* 2560 x 1600 @ 85Hz, STD n/a, CVT (1f, 38, 62) */
    "2560 x 1600", 2560, 1600, 280, 488, 0, 2560, 0, 208,
                                 6,  73, 0, 1600, 0, 3,
                  505250, -1,   NP,   0, 85, 0,
    /* 2560 x 1600 @ 120Hz RB, STD n/a, CVT n/a */
    "2560 x 1600", 2560, 1600,  32,  80, 0, 2560, 0, 48,
                                 6,  85, 0, 1600, 0, 3,
                  552750, -1,   PN,   0, 120, 0
};

/* Established timings maps the established timings bitfield onto
 * standard timings defined by the Display Monitor Timings Spec
 * Where there is no timing (0 - yes this /is/ a value on the table
 * but it's not used by the bitfield fortunately) then we use the
 * calculation method preferred by the display.
 */

/*    b7    b6    b5    b4    b3    b2    b1    b0 */
const char established_timings[] = {
    0x00, 0x00, 0x04, 0x00, 0x05, 0x06, 0x08, 0x09,
    0x0a, 0x0b, 0x00, 0x0f, 0x10, 0x11, 0x12, 0x24
    /* N.B. third byte not checked */
};

const char established_timings3[] = {
    0x01, 0x02, 0x03, 0x07, 0x0e, 0x0c, 0x13, 0x15,
    0x16, 0x17, 0x18, 0x19, 0x20, 0x21, 0x23, 0x25,
    0x27, 0x2e, 0x2f, 0x30, 0x31, 0x29, 0x2a, 0x2b,
    0x2c, 0x39, 0x3a, 0x3b, 0x3c, 0x33, 0x34, 0x35,
    0x36, 0x37, 0x3e, 0x3f, 0x41, 0x42, 0x44, 0x45,
    0x46, 0x47, 0x49, 0x4a, 0x00, 0x00, 0x00, 0x00
    /* N.B. 7th byte not checked */
};

/* List of standard timings - ie modes which have a defined 2-byte code
 * in the DMT document.
 *
 * NB The third parameter is DMT NUMBER, not ARRAY NUMBER. This is usually
 * array value -1. This is to make cross-checks against the DMT spec easier.
 * We have used 4x3 columns to prevent the source file getting too long.
 * The list should be 0-terminated.
 */
const STDTiming std_timings[] = {
#ifndef FORCE_CALCULATED_VALUES /* Removes the table for debugging */
    0x31, 0x19, 0x2,   0x31, 0x40, 0x4,   0x31, 0x4c, 0x5,   0x31, 0x4f, 0x6,
    0x31, 0x59, 0x7,   0x45, 0x40, 0x9,   0x45, 0x4c, 0xa,   0x45, 0x4f, 0xb,
    0x45, 0x59, 0xc,   0x61, 0x40, 0x10,  0x61, 0x4a, 0x11,  0x61, 0x4f, 0x12,
    0x61, 0x59, 0x13,  0x71, 0x4f, 0x15,  0x81, 0x00, 0x1c,  0x81, 0x0f, 0x1d,
    0x81, 0x19, 0x1e,  0x81, 0x40, 0x20,  0x81, 0x59, 0x21,  0x81, 0x80, 0x23,
    0x81, 0x8f, 0x24,  0x81, 0x99, 0x25,  0x90, 0x40, 0x2a,  0x90, 0x4f, 0x2b,
    0x90, 0x59, 0x2c,  0x95, 0x00, 0x2f,  0x90, 0x0f, 0x30,  0x95, 0x19, 0x31,
    0xa9, 0x40, 0x33,  0xa9, 0x45, 0x34,  0xa9, 0x4a, 0x35,  0xa9, 0x4f, 0x36,
    0xa9, 0x59, 0x37,  0xb3, 0x00, 0x3a,  0xb3, 0x0f, 0x3b,  0xb3, 0x19, 0x3c,
    0xc1, 0x40, 0x3e,  0xc1, 0x4f, 0x3f,  0xc9, 0x40, 0x41,  0xc9, 0x4f, 0x42,
    0xd1, 0x00, 0x45,  0xd1, 0x0f, 0x46,  0xd1, 0x19, 0x47,  0xd1, 0x40, 0x49,
    0xd1, 0x4f, 0x4a,
#endif
    0x00, 0x00, 0
};

/* List of 3-byte CVT timings - ie modes which have a defined 3-byte code
 * in the DMT document.
 *
 * NB The third parameter is DMT NUMBER, not ARRAY NUMBER. This is usually
 * array value -1. This is to make cross-checks against the DMT spec easier.
 * We have used 4x3 columns to prevent the source file getting too long.
 * The list should be 0-terminated.
 */
#ifdef DERIVE_CVT3_FROM_DMT
const CVTTiming cvt_timings[] = {
#ifndef FORCE_CALCULATED_VALUES /* Removes the table for debugging */
    0x7f, 0x1c, 0x21, 0x16,  0x7f, 0x1c, 0x28, 0x17,  0x7f, 0x1c, 0x44, 0x18,
    0x7f, 0x1c, 0x62, 0x19,  0x8f, 0x18, 0x21, 0x1b,  0x8f, 0x18, 0x28, 0x1c,
    0x8f, 0x18, 0x44, 0x1d,  0x8f, 0x18, 0x62, 0x1e,  0x0c, 0x20, 0x21, 0x29,
    0x0c, 0x20, 0x28, 0x2a,  0x0c, 0x20, 0x44, 0x2b,  0x0c, 0x20, 0x62, 0x2c,
    0xc1, 0x18, 0x21, 0x2e,  0xc1, 0x18, 0x28, 0x2f,  0xc1, 0x18, 0x44, 0x30,
    0xc1, 0x18, 0x68, 0x31,  0x0c, 0x28, 0x21, 0x39,  0x0c, 0x28, 0x28, 0x3a,
    0x0c, 0x28, 0x44, 0x3b,  0x0c, 0x28, 0x68, 0x3c,  0x57, 0x28, 0x21, 0x44,
    0x57, 0x28, 0x28, 0x45,  0x57, 0x28, 0x44, 0x46,  0x57, 0x28, 0x62, 0x47,
    0x1f, 0x38, 0x21, 0x4c,  0x1f, 0x38, 0x28, 0x4d,  0x1f, 0x38, 0x44, 0x4e,
    0x1f, 0x38, 0x62, 0x4f,
#endif
    0x00, 0x00, 0x00, 0
};
#endif

/* CEA 861-D mode timings */
#define CEA_MODE(NUM,WIDTH,HEIGHT,INT,HZ,ASPECT,CLOCK59,CLOCK60,SYNCS,H0,H1,H2,H3,V0,V1,V2,V3,V4) \
{\
  #WIDTH " x " #HEIGHT, \
  WIDTH, \
  HEIGHT, \
  { H1, H2, 0, H3, 0, H0 }, \
  { V2, (V3)-(V2), 0, V4, 0, (V1)-(V0) }, \
  CLOCK60, \
  -1, \
  SYNCS, \
  INT, \
  HZ \
}

/* Horizontal & vertical parameters are listed as shown in the spec (reading
 * the timing diagrams from left to right), so the CEA_MODE macro needs to
 * manipulate them a bit in order to convert them to the form RISC OS uses.
 * For the vertical timings this means taking the value to the left of the
 * transition point.
 *
 * However the macro assumes that the V1 number (at the start of the VSync
 * period) is the total line count; so for modes where this isn't the case
 * (e.g. 2) the macro parameters are manually fudged by subtracting the
 * actual VSync start value from V0 and V2-V4.
 *
 * Currently, there are some parameters included in the macro which aren't used,
 * such as the image aspect ratio, and the alternate clock rate. Also where
 * multiple vsync width values are permissible, only the first set of timings
 * has been used, and the macro doesn't record the permissible pixel repetition
 * values for the modes where pixel repetition is expected.
 */
const ModeDefinition cea_modes[] = {
/*       NUM    WIDTH   HEIGHT  INT     HZ      ASPECT  CLOCK59 CLOCK60 SYNCS   H0      H1      H2      H3      V0      V1      V2      V3      V4 */
CEA_MODE(1,     640,    480,    0,      60,     A43,    25175,  25200,  NN,     16,     96,     48,     640,    515,    525,    2,      35,     480),
CEA_MODE(2,     720,    480,    0,      60,     A43,    27000,  27027,  NN,     16,     62,     60,     720,    522-6,  525,    12-6,   42-6,   480),
CEA_MODE(3,     720,    480,    0,      60,     A169,   27000,  27027,  NN,     16,     62,     60,     720,    522-6,  525,    12-6,   42-6,   480),
CEA_MODE(4,     1280,   720,    0,      60,     A169,   74176,  74250,  PP,     110,    40,     220,    1280,   745,    750,    5,      25,     720),
CEA_MODE(5,     1920,   1080,   1,      60,     A169,   74176,  74250,  PP,     88,     44,     148,    1920,   1123,   1125,   5,      20,     540),
CEA_MODE(6,     720,    480,    1,      60,     A43,    27000,  27027,  NN,     38,     124,    114,    1440,   524-3,  525,    6-3,    21-3,   240),
CEA_MODE(7,     720,    480,    1,      60,     A169,   27000,  27027,  NN,     38,     124,    114,    1440,   524-3,  525,    6-3,    21-3,   240),
CEA_MODE(8,     720,    240,    0,      60,     A43,    27000,  27027,  NN,     38,     124,    114,    1440,   261-3,  262,    6-3,    21-3,   240),
CEA_MODE(9,     720,    240,    0,      60,     A169,   27000,  27027,  NN,     38,     124,    114,    1440,   261-3,  262,    6-3,    21-3,   240),
CEA_MODE(10,    2880,   480,    1,      60,     A43,    54000,  54054,  NN,     76,     248,    228,    2880,   524-3,  525,    6-3,    21-3,   240),
CEA_MODE(11,    2880,   480,    1,      60,     A169,   54000,  54054,  NN,     76,     248,    228,    2880,   524-3,  525,    6-3,    21-3,   240),
CEA_MODE(12,    2880,   240,    0,      60,     A43,    54000,  54054,  NN,     76,     248,    228,    2880,   261-3,  262,    6-3,    21-3,   240),
CEA_MODE(13,    2880,   240,    0,      60,     A169,   54000,  54054,  NN,     76,     248,    228,    2880,   261-3,  262,    6-3,    21-3,   240),
CEA_MODE(14,    1440,   480,    0,      60,     A43,    54000,  54054,  NN,     32,     124,    120,    1440,   522-6,  525,    12-6,   42-6,   480),
CEA_MODE(15,    1440,   480,    0,      60,     A169,   54000,  54054,  NN,     32,     124,    120,    1440,   522-6,  525,    12-6,   42-6,   480),
CEA_MODE(16,    1920,   1080,   0,      60,     A169,   148352, 148500, PP,     88,     44,     148,    1920,   1121,   1125,   5,      41,     1080),
CEA_MODE(17,    720,    576,    0,      50,     A43,    27000,  27000,  NN,     12,     64,     68,     720,    620,    625,    5,      44,     576),
CEA_MODE(18,    720,    576,    0,      50,     A169,   27000,  27000,  NN,     12,     64,     68,     720,    620,    625,    5,      44,     576),
CEA_MODE(19,    1280,   720,    0,      50,     A169,   74250,  74250,  PP,     440,    40,     220,    1280,   745,    750,    5,      25,     720),
CEA_MODE(20,    1920,   1080,   1,      50,     A169,   74250,  74250,  PP,     528,    44,     148,    1920,   1123,   1125,   5,      20,     540),
CEA_MODE(21,    720,    576,    1,      50,     A43,    27000,  27000,  NN,     24,     126,    138,    1440,   623,    625,    3,      22,     288),
CEA_MODE(22,    720,    576,    1,      50,     A169,   27000,  27000,  NN,     24,     126,    138,    1440,   623,    625,    3,      22,     288),
CEA_MODE(23,    720,    288,    0,      50,     A43,    27000,  27000,  NN,     24,     126,    138,    1440,   310,    312,    3,      21,     288),
CEA_MODE(24,    720,    288,    0,      50,     A169,   27000,  27000,  NN,     24,     126,    138,    1440,   310,    312,    3,      21,     288),
CEA_MODE(25,    2880,   576,    1,      50,     A43,    54000,  54000,  NN,     48,     252,    276,    2880,   623,    625,    3,      22,     288),
CEA_MODE(26,    2880,   576,    1,      50,     A169,   54000,  54000,  NN,     48,     252,    276,    2880,   623,    625,    3,      22,     288),
CEA_MODE(27,    2880,   288,    0,      50,     A43,    54000,  54000,  NN,     48,     252,    276,    2880,   310,    312,    3,      22,     288),
CEA_MODE(28,    2880,   288,    0,      50,     A169,   54000,  54000,  NN,     48,     252,    276,    2880,   310,    312,    3,      22,     288),
CEA_MODE(29,    1440,   576,    0,      50,     A43,    54000,  54000,  NN,     24,     128,    136,    1440,   620,    625,    5,      44,     576),
CEA_MODE(30,    1440,   576,    0,      50,     A169,   54000,  54000,  NN,     24,     128,    136,    1440,   620,    625,    5,      44,     576),
CEA_MODE(31,    1920,   1080,   0,      50,     A169,   148500, 148500, PP,     528,    44,     148,    1920,   1121,   1125,   5,      41,     1080),
CEA_MODE(32,    1920,   1080,   0,      24,     A169,   74176,  74250,  PP,     638,    44,     148,    1920,   1121,   1125,   5,      41,     1080),
CEA_MODE(33,    1920,   1080,   0,      25,     A169,   74250,  74250,  PP,     528,    44,     148,    1920,   1121,   1125,   5,      41,     1080),
CEA_MODE(34,    1920,   1080,   0,      30,     A169,   74176,  74250,  PP,     88,     44,     148,    1920,   1121,   1125,   5,      41,     1080),
CEA_MODE(35,    2880,   480,    0,      60,     A43,    108000, 108108, NN,     64,     248,    240,    2880,   522-6,  525,    12-6,   42-6,   480),
CEA_MODE(36,    2880,   480,    0,      60,     A169,   108000, 108108, NN,     64,     248,    240,    2880,   522-6,  525,    12-6,   42-6,   480),
CEA_MODE(37,    2880,   576,    0,      50,     A43,    108000, 108000, NN,     48,     256,    272,    2880,   620,    625,    5,      44,     576),
CEA_MODE(38,    2880,   576,    0,      50,     A169,   108000, 108000, NN,     48,     256,    272,    2880,   620,    625,    5,      44,     576),
CEA_MODE(39,    1920,   1080,   1,      50,     A169,   72000,  72000,  PN,     32,     168,    184,    1920,   1227,   1250,   5,      62,     540),
CEA_MODE(40,    1920,   1080,   1,      100,    A169,   148500, 148500, PP,     528,    44,     148,    1920,   1123,   1125,   5,      20,     540),
CEA_MODE(41,    1280,   720,    0,      100,    A169,   148500, 148500, PP,     440,    40,     220,    1280,   745,    750,    5,      25,     720),
CEA_MODE(42,    720,    576,    0,      100,    A43,    54000,  54000,  NN,     12,     64,     68,     720,    620,    625,    5,      44,     576),
CEA_MODE(43,    720,    576,    0,      100,    A169,   54000,  54000,  NN,     12,     64,     68,     720,    620,    625,    5,      44,     576),
CEA_MODE(44,    720,    576,    1,      100,    A43,    54000,  54000,  NN,     24,     126,    138,    1440,   623,    625,    3,      22,     288),
CEA_MODE(45,    720,    576,    1,      100,    A169,   54000,  54000,  NN,     24,     126,    138,    1440,   623,    625,    3,      22,     288),
CEA_MODE(46,    1920,   1080,   1,      120,    A169,   148352, 148500, PP,     88,     44,     148,    1920,   1123,   1125,   5,      20,     540),
CEA_MODE(47,    1280,   720,    0,      120,    A169,   148352, 148500, PP,     110,    40,     220,    1280,   745,    750,    5,      25,     720),
CEA_MODE(48,    720,    480,    0,      120,    A43,    54000,  54054,  NN,     16,     62,     60,     720,    522-6,  525,    12-6,   42-6,   480),
CEA_MODE(49,    720,    480,    0,      120,    A169,   54000,  54054,  NN,     16,     62,     60,     720,    522-6,  525,    12-6,   42-6,   480),
CEA_MODE(50,    720,    480,    1,      120,    A43,    54000,  54054,  NN,     38,     124,    114,    1440,   524-3,  525,    6-3,    21-3,   240),
CEA_MODE(51,    720,    480,    1,      120,    A169,   54000,  54054,  NN,     38,     124,    114,    1440,   524-3,  525,    6-3,    21-3,   240),
CEA_MODE(52,    720,    576,    0,      200,    A43,    108000, 108000, NN,     12,     64,     68,     720,    620,    625,    5,      44,     576),
CEA_MODE(53,    720,    576,    0,      200,    A169,   108000, 108000, NN,     12,     64,     68,     720,    620,    625,    5,      44,     576),
CEA_MODE(54,    720,    576,    1,      200,    A43,    108000, 108000, NN,     24,     126,    138,    1440,   623,    625,    3,      22,     288),
CEA_MODE(55,    720,    576,    1,      200,    A169,   108000, 108000, NN,     24,     126,    138,    1440,   623,    625,    3,      22,     288),
CEA_MODE(56,    720,    480,    0,      240,    A43,    108000, 108000, NN,     16,     62,     60,     720,    522-6,  525,    12-6,   42-6,   480),
CEA_MODE(57,    720,    480,    0,      240,    A169,   108000, 108000, NN,     16,     62,     60,     720,    522-6,  525,    12-6,   42-6,   480),
CEA_MODE(58,    720,    480,    1,      240,    A43,    108000, 108000, NN,     38,     124,    114,    1440,   524-3,  525,    6-3,    21-3,   240),
CEA_MODE(59,    720,    480,    1,      240,    A169,   108000, 108000, NN,     38,     124,    114,    1440,   524-3,  525,    6-3,    21-3,   240)
};
typedef char cea_modes_assert[((sizeof(cea_modes) / sizeof(cea_modes[0])) <= MAXCEAMODENUM) ? 1 : -1];

/* EOF Tables.c */