qemu/hw/display/sm501_template.h
<<
>>
Prefs
   1/*
   2 * Pixel drawing function templates for QEMU SM501 Device
   3 *
   4 * Copyright (c) 2008 Shin-ichiro KAWASAKI
   5 *
   6 * Permission is hereby granted, free of charge, to any person obtaining a copy
   7 * of this software and associated documentation files (the "Software"), to deal
   8 * in the Software without restriction, including without limitation the rights
   9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 * copies of the Software, and to permit persons to whom the Software is
  11 * furnished to do so, subject to the following conditions:
  12 *
  13 * The above copyright notice and this permission notice shall be included in
  14 * all copies or substantial portions of the Software.
  15 *
  16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 * THE SOFTWARE.
  23 */
  24
  25#if DEPTH == 8
  26#define BPP 1
  27#define PIXEL_TYPE uint8_t
  28#elif DEPTH == 15 || DEPTH == 16
  29#define BPP 2
  30#define PIXEL_TYPE uint16_t
  31#elif DEPTH == 32
  32#define BPP 4
  33#define PIXEL_TYPE uint32_t
  34#else
  35#error unsupport depth
  36#endif
  37
  38#ifdef BGR_FORMAT
  39#define PIXEL_NAME glue(DEPTH, bgr)
  40#else
  41#define PIXEL_NAME DEPTH
  42#endif /* BGR_FORMAT */
  43
  44
  45static void glue(draw_line8_, PIXEL_NAME)(
  46                 uint8_t *d, const uint8_t *s, int width, const uint32_t *pal)
  47{
  48    uint8_t v, r, g, b;
  49    do {
  50        v = ldub_p(s);
  51        r = (pal[v] >> 16) & 0xff;
  52        g = (pal[v] >>  8) & 0xff;
  53        b = (pal[v] >>  0) & 0xff;
  54        ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
  55        s ++;
  56        d += BPP;
  57    } while (-- width != 0);
  58}
  59
  60static void glue(draw_line16_, PIXEL_NAME)(
  61                 uint8_t *d, const uint8_t *s, int width, const uint32_t *pal)
  62{
  63    uint16_t rgb565;
  64    uint8_t r, g, b;
  65
  66    do {
  67        rgb565 = lduw_p(s);
  68        r = ((rgb565 >> 11) & 0x1f) << 3;
  69        g = ((rgb565 >>  5) & 0x3f) << 2;
  70        b = ((rgb565 >>  0) & 0x1f) << 3;
  71        ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
  72        s += 2;
  73        d += BPP;
  74    } while (-- width != 0);
  75}
  76
  77static void glue(draw_line32_, PIXEL_NAME)(
  78                 uint8_t *d, const uint8_t *s, int width, const uint32_t *pal)
  79{
  80    uint8_t r, g, b;
  81
  82    do {
  83        ldub_p(s);
  84#if defined(TARGET_WORDS_BIGENDIAN)
  85        r = s[1];
  86        g = s[2];
  87        b = s[3];
  88#else
  89        b = s[0];
  90        g = s[1];
  91        r = s[2];
  92#endif
  93        ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
  94        s += 4;
  95        d += BPP;
  96    } while (-- width != 0);
  97}
  98
  99/**
 100 * Draw hardware cursor image on the given line.
 101 */
 102static void glue(draw_hwc_line_, PIXEL_NAME)(SM501State * s, int crt,
 103                         uint8_t * palette, int c_y, uint8_t *d, int width)
 104{
 105    int x, i;
 106    uint8_t bitset = 0;
 107
 108    /* get hardware cursor pattern */
 109    uint32_t cursor_addr = get_hwc_address(s, crt);
 110    assert(0 <= c_y && c_y < SM501_HWC_HEIGHT);
 111    cursor_addr += 64 * c_y / 4;  /* 4 pixels per byte */
 112    cursor_addr += s->base;
 113
 114    /* get cursor position */
 115    x = get_hwc_x(s, crt);
 116    d += x * BPP;
 117
 118    for (i = 0; i < SM501_HWC_WIDTH && x + i < width; i++) {
 119        uint8_t v;
 120
 121        /* get pixel value */
 122        if (i % 4 == 0) {
 123            bitset = ldub_phys(&address_space_memory, cursor_addr);
 124            cursor_addr++;
 125        }
 126        v = bitset & 3;
 127        bitset >>= 2;
 128
 129        /* write pixel */
 130        if (v) {
 131            v--;
 132            uint8_t r = palette[v * 3 + 0];
 133            uint8_t g = palette[v * 3 + 1];
 134            uint8_t b = palette[v * 3 + 2];
 135            ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
 136        }
 137        d += BPP;
 138    }
 139}
 140
 141#undef DEPTH
 142#undef BPP
 143#undef PIXEL_TYPE
 144#undef PIXEL_NAME
 145#undef BGR_FORMAT
 146