[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[tyndur-devel] [PATCH 4/6] + cdi.video: vesa



Achtung, qemu-spezifisch! Funktioniert so in anderen Umgebungen nicht.

Signed-off-by: Alexander Siol <alex@xxxxxxxxxx>
---
 src/modules/cdi/vesa/Makefile.all |    6 +
 src/modules/cdi/vesa/bitmap.c     |   79 +++++++++
 src/modules/cdi/vesa/bitmap.h     |   14 ++
 src/modules/cdi/vesa/device.c     |  180 +++++++++++++++++++
 src/modules/cdi/vesa/device.h     |   15 ++
 src/modules/cdi/vesa/drawing.c    |  341 +++++++++++++++++++++++++++++++++++++
 src/modules/cdi/vesa/drawing.h    |   59 +++++++
 src/modules/cdi/vesa/main.c       |  124 ++++++++++++++
 src/modules/cdi/vesa/vesa.h       |   47 +++++
 9 files changed, 865 insertions(+), 0 deletions(-)
 create mode 100644 src/modules/cdi/vesa/Makefile.all
 create mode 100644 src/modules/cdi/vesa/bitmap.c
 create mode 100644 src/modules/cdi/vesa/bitmap.h
 create mode 100644 src/modules/cdi/vesa/device.c
 create mode 100644 src/modules/cdi/vesa/device.h
 create mode 100644 src/modules/cdi/vesa/drawing.c
 create mode 100644 src/modules/cdi/vesa/drawing.h
 create mode 100644 src/modules/cdi/vesa/main.c
 create mode 100644 src/modules/cdi/vesa/vesa.h

diff --git a/src/modules/cdi/vesa/Makefile.all b/src/modules/cdi/vesa/Makefile.all
new file mode 100644
index 0000000..ec6f85a
--- /dev/null
+++ b/src/modules/cdi/vesa/Makefile.all
@@ -0,0 +1,6 @@
+shopt -s extglob
+source $LOST_BUILDMK_ROOT/config.sh
+
+echo "LD   $1/modules/vesa"
+$LOST_TOOLS_LD -ovesa.mod -Ttext=0x40000000 *.o --start-group $2 --end-group
+$LOST_TOOLS_STRIP -s vesa.mod -o $1/modules/vesa
diff --git a/src/modules/cdi/vesa/bitmap.c b/src/modules/cdi/vesa/bitmap.c
new file mode 100644
index 0000000..d1cbdfc
--- /dev/null
+++ b/src/modules/cdi/vesa/bitmap.c
@@ -0,0 +1,79 @@
+/*  
+ * Copyright (c) 2009 The tyndur Project. All rights reserved.
+ *
+ * This code is derived from software contributed to the tyndur Project
+ * by Alexander Siol.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR 
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/
+
+#include <cdi/video.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+struct cdi_video_bitmap *vesa_bitmap_create(struct cdi_video_device *device,
+    unsigned int width, unsigned int height, void *data)
+{
+    struct cdi_video_bitmap *bitmap = calloc(1,sizeof(struct cdi_video_bitmap));
+
+    printf("device, bitmap_create start: %x\n", device);
+
+    bitmap->device = device;
+    bitmap->width = width;
+    bitmap->height = height;
+    bitmap->format.bpp = 32;
+//    bitmap->format.format = CDI_VIDEO_FMT_USER;
+    bitmap->format.red_bits = 8;
+    bitmap->format.red_offset = 16;
+    bitmap->format.green_bits = 8;
+    bitmap->format.green_offset = 8;
+    bitmap->format.blue_bits = 8;
+    bitmap->format.blue_offset = 0;
+
+    bitmap->pitch = bitmap->format.bpp / 8 * width;
+
+    bitmap->in_vram = 0;
+
+    bitmap->pixeldata = calloc(1, width * height * 4);
+    if (data) {
+        memcpy(bitmap->pixeldata, data, width * height * 4);
+    }
+
+    printf("device, bitmap_create end: %x\n", bitmap->device);
+
+
+    return bitmap;
+}
+
+void vesa_bitmap_destroy(struct cdi_video_device *device,
+    struct cdi_video_bitmap *bitmap)
+{
+    if (bitmap->device != device) return;
+    if (bitmap->in_vram == 0) free(bitmap->pixeldata);
+    free(bitmap);
+}
+
+void vesa_bitmap_set_usage_hint(struct cdi_video_device *device,
+    struct cdi_video_bitmap *bitmap, enum cdi_video_bitmap_usage_hint hint)
+{
+    //TODO("");
+}
\ No newline at end of file
diff --git a/src/modules/cdi/vesa/bitmap.h b/src/modules/cdi/vesa/bitmap.h
new file mode 100644
index 0000000..dda60e4
--- /dev/null
+++ b/src/modules/cdi/vesa/bitmap.h
@@ -0,0 +1,14 @@
+
+#ifndef __VESA_BITMAP_H__
+#define __VESA_BITMAP_H__
+
+#include <cdi/video.h>
+
+void vesa_bitmap_set_usage_hint(struct cdi_video_device *device,
+    struct cdi_video_bitmap *bitmap, enum cdi_video_bitmap_usage_hint hint);
+void vesa_bitmap_destroy(struct cdi_video_device *device,
+    struct cdi_video_bitmap *bitmap);
+struct cdi_video_bitmap *vesa_bitmap_create(struct cdi_video_device *device,
+    unsigned int width, unsigned int height, void *data);
+
+#endif /* __VESA_BITMAP_H__ */
diff --git a/src/modules/cdi/vesa/device.c b/src/modules/cdi/vesa/device.c
new file mode 100644
index 0000000..a775eca
--- /dev/null
+++ b/src/modules/cdi/vesa/device.c
@@ -0,0 +1,180 @@
+/*  
+ * Copyright (c) 2009 The tyndur Project. All rights reserved.
+ *
+ * This code is derived from software contributed to the tyndur Project
+ * by Alexander Siol.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR 
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/
+
+#include "device.h"
+#include <cdi/video.h>
+#include <cdi/vesa.h>
+#include <cdi/lists.h>
+#include <cdi/pci.h>
+#include <cdi/misc.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "vesa.h"
+#include "drawing.h"
+#include "bitmap.h"
+
+struct vesa_device *vesa_device_create(char *name, struct cdi_pci_device* pci)
+{
+    // Device anlegen
+    struct vesa_device *dev;
+    dev = malloc(sizeof(struct vesa_device));
+    dev->dev.dev.name = name;
+    dev->dev.displays = cdi_list_create();
+
+    dev->dev.raster_op = CDI_VIDEO_ROP_COPY;
+    dev->dev.restore_data = NULL;
+
+    dev->dev.vram = NULL;
+    dev->dev.vram_size = 0;
+
+
+    int i;
+
+    // Ressourcen holen (Speicher als Framebuffer)
+    // FIXME: Hack, Keine Ahnung ob das auÃ?erhalb von qemu tut.
+    cdi_pci_alloc_memory(pci);
+    for (i = 0; i < cdi_list_size(pci->resources); i++) {
+        struct cdi_pci_resource *res;
+        res = cdi_list_get(pci->resources, i);
+        if (res->type == CDI_PCI_MEMORY && res->length > 0x1000) {
+            dev->dev.vram = res->address;
+            dev->dev.vram_size = res->length;
+            break;
+        }
+    }
+
+    // Display anlegen
+    struct cdi_video_display* vesadisplay;
+    vesadisplay = calloc(1,sizeof(struct cdi_video_display));
+
+    vesadisplay->device = (struct cdi_video_device*)dev;
+    vesadisplay->mode = NULL;
+    vesadisplay->modes = cdi_list_create();
+
+    // Muss von change_mode gesetzt werden
+    vesadisplay->frontbuffer = NULL;
+
+    cdi_list_push(dev->dev.displays, vesadisplay);
+
+    printf("vesa_device_create, vram: %x, len %d MB\n", dev->dev.vram, dev->dev.vram_size / 1024 / 1024);
+    return dev;
+}
+
+/**
+ * Callback fuer CDI-Vesa-Modi
+ */
+void vesa_mode_callback(int modenum, struct cdi_video_vesa_mode_info *modeinfo)
+{
+    switch (modeinfo->depth) {
+        case 32:
+        case 24:
+        case 16:
+            printf("Modus OK: %dx%d\n", modeinfo->width, modeinfo->height);
+            struct cdi_video_display *vesadisplay;
+            struct vesa_device *vesadev;
+            // Gerät & Display suchen.
+            // VESA kann nur ein Gerät und ein Display
+            vesadev = cdi_list_get(vesa_driver.drv.drv.devices, 0);
+            vesadisplay = cdi_list_get(vesadev->dev.displays, 0);
+
+            // Modus hinzufügen
+            struct cdi_video_vesa_mode *vesamode;
+            vesamode = calloc(1,sizeof(struct cdi_video_vesa_mode));
+            vesamode->vesamode = modenum;
+            vesamode->mode.width = modeinfo->width;
+            vesamode->mode.height = modeinfo->height;
+            vesamode->mode.depth = modeinfo->depth;
+            cdi_list_push(vesadisplay->modes, vesamode);
+
+            break;
+        default:
+            /*printf("Modus NICHT OK: %dx%dx%d\n", modeinfo->width, 
+                modeinfo->height, modeinfo->depth);*/
+            break;
+    }
+    return;
+}
+
+/**
+ * Modus setzen
+ */
+int vesa_display_set_mode(struct cdi_video_device *device,
+    struct cdi_video_display *display, struct cdi_video_displaymode *mode)
+{
+    struct cdi_video_vesa_mode *vesamode;
+    vesamode = (struct cdi_video_vesa_mode*)mode;
+    cdi_video_vesa_change_mode(vesamode->vesamode);
+
+    struct cdi_video_bitmap *bitmap;
+    if (display->frontbuffer != NULL) {
+        bitmap = display->frontbuffer;
+    } else {
+        bitmap = calloc(1, sizeof(struct cdi_video_bitmap));
+    }
+
+    struct cdi_video_vesa_mode_info *vesamodeinfo;
+    vesamodeinfo = cdi_video_vesa_get_mode(vesamode->vesamode);
+
+    bitmap->width = mode->width;
+    bitmap->height = mode->height;
+    bitmap->format.bpp = vesamodeinfo->depth;
+    bitmap->format.red_bits = vesamodeinfo->redmasksize;
+    bitmap->format.red_offset = vesamodeinfo->redfieldpos;
+    bitmap->format.green_bits = vesamodeinfo->greenmasksize;
+    bitmap->format.green_offset = vesamodeinfo->greenfieldpos;
+    bitmap->format.blue_bits = vesamodeinfo->bluemasksize;
+    bitmap->format.blue_offset = vesamodeinfo->bluefieldpos;
+    bitmap->format.alpha_bits = 0;
+    bitmap->format.alpha_offset = 0;
+
+    // Offsets müssen auf 32-bit passen.
+    if (bitmap->format.bpp == 16) {
+        bitmap->format.red_offset += 16;
+        bitmap->format.green_offset += 16;
+        bitmap->format.blue_offset += 16;
+    }
+
+    bitmap->in_vram = 1;
+    bitmap->device = device;
+    bitmap->pixeldata = NULL; // Im VRAM, passt so
+    bitmap->pitch = bitmap->width * bitmap->format.bpp / 8;
+
+    display->frontbuffer = bitmap;
+
+    struct cdi_video_color color;
+    color.alpha = 0;
+    color.red = 0;
+    color.green = 0;
+    color.blue = 0;
+
+    memset(bitmap->device->vram, 0, bitmap->width * bitmap->height *
+        bitmap->format.bpp);
+    //vesa_draw_rectangle(bitmap, 0, 0, bitmap->width, bitmap->height, color);
+
+    return 0;
+}
diff --git a/src/modules/cdi/vesa/device.h b/src/modules/cdi/vesa/device.h
new file mode 100644
index 0000000..7f5ea22
--- /dev/null
+++ b/src/modules/cdi/vesa/device.h
@@ -0,0 +1,15 @@
+
+#ifndef __VESA_DEVICE_H__
+#define __VESA_DEVICE_H__
+
+#include <cdi/pci.h>
+#include <cdi/vesa.h>
+#include <cdi/video.h>
+
+void vesa_mode_callback(int modenum, 
+    struct cdi_video_vesa_mode_info *modeinfo);
+struct vesa_device *vesa_device_create(char *name, struct cdi_pci_device* pci);
+int vesa_display_set_mode(struct cdi_video_device *device,
+    struct cdi_video_display *display, struct cdi_video_displaymode *mode);
+
+#endif /* __VESA_DEVICE_H__ */
diff --git a/src/modules/cdi/vesa/drawing.c b/src/modules/cdi/vesa/drawing.c
new file mode 100644
index 0000000..bde9675
--- /dev/null
+++ b/src/modules/cdi/vesa/drawing.c
@@ -0,0 +1,341 @@
+/*  
+ * Copyright (c) 2009 The tyndur Project. All rights reserved.
+ *
+ * This code is derived from software contributed to the tyndur Project
+ * by Alexander Siol.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/
+
+#include <cdi/video.h>
+#include <stdio.h>
+#include "drawing.h"
+#include <stdlib.h>
+
+
+#define min(x,y) (((x) < (y)) ? (x) : (y))
+
+uint32_t colormasks[3] = { 0xffff0000, 0x00ffffff, 0xffffffff }; // 16, 24, 32 bpp
+
+void vesa_set_raster_op(struct cdi_video_device *device,
+    enum cdi_video_raster_op rop)
+{
+    device->raster_op = rop;
+}
+
+void vesa_draw_line(struct cdi_video_bitmap *target, unsigned int x1, 
+    unsigned int y1, unsigned int x2, unsigned int y2,
+    struct cdi_video_color color)
+{
+    // Speicher suchen
+    char *dstchar = NULL;
+    if (target->in_vram == 1) {
+        dstchar = target->device->vram;
+    }
+    int x_shift = target->format.bpp / 8;
+
+    dstchar += (uint32_t)target->pixeldata;
+    dstchar += y1 * target->pitch;
+    dstchar += x1 * x_shift;
+
+    // Farben und Farbmasken
+    uint32_t new = 0, old = 0;
+    uint32_t colormask, keepmask;
+
+    colormask = colormasks[(target->format.bpp - 16) / 8];
+    keepmask = ~colormask;
+
+    new = convert_color(target->format, color);
+
+    // Bresenham Initialisierung
+    int dx = x2 - x1;
+    int dy = y2 - y1;
+
+    int xstep = 0, ystep = 0;
+    int normal_step_x, normal_step_y, error_fast, error_slow;
+    int error, i;
+
+    if (dx > 0) {
+        xstep = x_shift;
+    } else if (dx < 0) {
+        xstep = -x_shift;
+        dx = -dx;
+    }
+
+    if (dy > 0) {
+        ystep = target->pitch;
+    } else if (dy < 0) {
+        ystep = -target->pitch;
+        dy = -dy;
+    }
+
+    if (dx > dy) {
+        normal_step_x = xstep;
+        normal_step_y = 0;
+        error_fast = dy;
+        error_slow = dx;
+    } else {
+        normal_step_x = 0;
+        normal_step_y = ystep;
+        error_fast = dx;
+        error_slow = dy;
+    }
+    error = error_slow >> 1;
+
+
+    for (i = 0; i <= error_slow; i++) {
+        old = *(uint32_t*)dstchar & colormask;
+        *(uint32_t*)dstchar &= keepmask;
+        *(uint32_t*)dstchar |= new & colormask;
+
+        error -= error_fast;
+        if (error < 0) {
+            error += error_slow;
+            dstchar += xstep;
+            dstchar += ystep;
+        } else {
+            dstchar += normal_step_x;
+            dstchar += normal_step_y;
+        }
+    }
+}
+
+void vesa_draw_rectangle(struct cdi_video_bitmap *target, unsigned int x,
+    unsigned int y, unsigned int width, unsigned int height,
+    struct cdi_video_color color)
+{
+    int widthctr;
+    // Pixel vorbereiten
+    char *linestart = NULL, *in_line;
+    if (target->in_vram == 1) {
+        linestart = target->device->vram;
+    }
+    int x_shift = target->format.bpp / 8;
+
+    linestart += (uint32_t)target->pixeldata;
+    linestart += y * target->pitch;
+    linestart += x * x_shift;
+
+    // Farben und Farbmasken
+    uint32_t new = 0, old = 0;
+    uint32_t colormask, keepmask;
+
+    colormask = colormasks[(target->format.bpp - 16) / 8];
+    keepmask = ~colormask;
+
+    new = convert_color(target->format, color);
+
+    while (height > 0) {
+        // Render Line
+        widthctr = width;
+        in_line = linestart;
+        while (widthctr > 0) {
+            // Render Pixel
+            old = *(uint32_t*)in_line & colormask;
+            new = do_rop(target->device->raster_op, new, old);
+
+            *(uint32_t*)in_line &= keepmask;
+            *(uint32_t*)in_line |= new & colormask;
+
+            in_line += x_shift;
+            widthctr--;
+        }
+        // Eine Reihe weiter
+        height--;
+        linestart += target->pitch;
+    }
+}
+
+// TODO TODO TODO TODO TODO
+void vesa_draw_ellipse(struct cdi_video_bitmap *target, unsigned int x,
+    unsigned int y, unsigned int width, unsigned int height,
+    struct cdi_video_color color);
+
+void vesa_draw_bitmap(struct cdi_video_bitmap *target,
+    struct cdi_video_bitmap *source, unsigned int x, unsigned int y)
+{
+    vesa_draw_bitmap_part(target, source, x, y, 0, 0, source->width,
+        source->height);
+}
+
+void vesa_draw_bitmap_part(struct cdi_video_bitmap *target, 
+    struct cdi_video_bitmap *source, unsigned int x, unsigned int y, 
+    unsigned int srcx, unsigned int srcy, unsigned int width, 
+    unsigned int height)
+{
+    int copywidth, copyheight, origcopywidth;
+
+    // Zu kopierenden Bereich festlegen
+    copywidth = min( min( target->width - x, width ),
+                     source->width - srcx);
+    copyheight = min (min (target->height - y, height),
+                    source->height - srcy);
+
+    // Speicherstellen berechnen
+    char *srcchar = NULL;
+    if (source->in_vram == 1) { srcchar = source->device->vram; }
+    srcchar += (int)source->pixeldata;
+    srcchar += (int)(srcx * source->format.bpp / 8);
+    srcchar += (int)(srcy * source->pitch);
+
+    char *dstchar = NULL;
+    if (target->in_vram == 1) { dstchar = target->device->vram; }
+    dstchar += (int)target->pixeldata;
+    dstchar += (int)(x * target->format.bpp / 8);
+    dstchar += (int)(y * target->pitch);
+
+    char *dstline, *srcline;
+
+    // Farben und Farbmasken
+    uint32_t new = 0, old = 0;
+    struct cdi_video_color newcolor;
+    uint32_t colormask, keepmask;
+
+    colormask = colormasks[(target->format.bpp - 16) / 8];
+    keepmask = ~colormask;
+
+    // Schleifenvorbereitung
+    dstline = dstchar;
+    srcline = srcchar;
+    origcopywidth = copywidth;
+    while (copyheight > 0) {
+        copywidth = origcopywidth;
+        while (copywidth > 0) {
+            // Farben vorbereiten
+            old = *(uint32_t*)dstchar & colormask;
+            newcolor = convert_color_from_pixel(source->format,
+                *(uint32_t*)srcchar);
+            new = convert_color(target->format, newcolor);
+            new = do_rop(target->device->raster_op, new, old);
+
+            // Malen
+            *(uint32_t*)dstchar &= keepmask;
+            *(uint32_t*)dstchar |= new & colormask;
+
+            // Zeiger einen Pixel weitersetzen
+            srcchar += source->format.bpp / 8;
+            dstchar += target->format.bpp / 8;
+            copywidth--;
+        }
+        // Linie fertig, naechste benutzen.
+        dstline += target->pitch;
+        srcline += source->pitch;
+        srcchar = srcline;
+        dstchar = dstline;
+        copyheight--;
+    }
+}
+
+inline void vesa_draw_dot(struct cdi_video_bitmap *target, unsigned int x,
+    unsigned int y, struct cdi_video_color color)
+{
+    // Speicherposition berechnen
+    char *tmp;
+    if (target->in_vram == 1) {
+        tmp = target->device->vram;
+    } else {
+        tmp = NULL;
+    }
+    tmp += (int)(target->pixeldata);
+    tmp += (int)(y * (target->pitch));
+    tmp += (int)(x * (target->format.bpp) / 8);
+
+    uint32_t *start = (uint32_t*)tmp;
+
+    // Farben und Farbmasken definieren.
+    uint32_t newcolor = 0, oldcolor = 0;
+    uint32_t colormask, keepmask;
+    colormask = colormasks[(target->format.bpp - 16) / 8];
+    keepmask = ~colormask;
+
+    // Farbe berechnen
+    oldcolor = *start & colormask;
+    newcolor = convert_color(target->format, color);
+    newcolor = do_rop(target->device->raster_op, newcolor, oldcolor);
+
+    // und setzen.
+    *start &= keepmask;
+    *start |= newcolor & colormask;
+}
+
+inline uint32_t do_rop(enum cdi_video_raster_op rop, uint32_t new, uint32_t old)
+{
+    switch (rop) {
+        case CDI_VIDEO_ROP_OR:
+            return new | old;
+        case CDI_VIDEO_ROP_XOR:
+            return new ^ old;
+        default:
+            fprintf(0, "VESA unterstützt ROP %d nicht\n",
+                rop);
+        // Hier _kein_ break, damit im Fehlerfall wenigstens was rauskommt.
+        case CDI_VIDEO_ROP_COPY:
+            return new;
+    }
+}
+
+inline uint32_t convert_color(struct cdi_video_pixel_format fmt,
+    struct cdi_video_color cdicolor)
+{
+    uint32_t red, blue, green, alpha, color;
+    red = cdicolor.red << fmt.red_bits >> 8;
+    green = cdicolor.green << fmt.green_bits >> 8;
+    blue = cdicolor.blue << fmt.blue_bits >> 8;
+
+    // Hier pruefen reicht, RGB sollte eigentlich immer da sein.
+    if (fmt.alpha_bits > 0) {
+        alpha = cdicolor.alpha << fmt.alpha_bits >> 8;
+    } else {
+        alpha = 0;
+    }
+    color = red << fmt.red_offset |
+        green << fmt.green_offset |
+        blue << fmt.blue_offset |
+        alpha << fmt.alpha_offset;
+    return color;
+}
+
+struct cdi_video_color convert_color_from_pixel(struct cdi_video_pixel_format
+    fmt, uint32_t value)
+{
+    struct cdi_video_color color;
+    int redmask, bluemask, greenmask, alphamask;
+
+    // Masken setzen
+    redmask = ((1 << fmt.red_bits) - 1) << fmt.red_offset;
+    greenmask = ((1 << fmt.green_bits) - 1) << fmt.green_offset;
+    bluemask = ((1 << fmt.blue_bits) - 1) << fmt.blue_offset;
+    alphamask = ((1 << fmt.alpha_bits) - 1) << fmt.alpha_offset;
+
+    // Farben extrahieren
+    color.red = (value & redmask) >> fmt.red_offset;
+    color.green = (value & greenmask) >> fmt.green_offset;
+    color.blue = (value & bluemask) >> fmt.blue_offset;
+    color.alpha = (value & alphamask) >> fmt.alpha_offset;
+
+    // Auf die richtige Aufloesung bringen.
+    color.red = color.red << 8 >> fmt.red_bits;
+    color.green = color.green << 8 >> fmt.green_bits;
+    color.blue = color.blue << 8 >> fmt.blue_bits;
+    color.alpha = color.alpha << 8 >> fmt.alpha_bits;
+
+    return color;
+}
diff --git a/src/modules/cdi/vesa/drawing.h b/src/modules/cdi/vesa/drawing.h
new file mode 100644
index 0000000..c2a24d6
--- /dev/null
+++ b/src/modules/cdi/vesa/drawing.h
@@ -0,0 +1,59 @@
+/*  
+ * Copyright (c) 2009 The tyndur Project. All rights reserved.
+ *
+ * This code is derived from software contributed to the tyndur Project
+ * by Alexander Siol.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR 
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/
+
+#ifndef __VESA_DRAWING_H__
+#define __VESA_DRAWING_H__
+
+#include <cdi/video.h>
+
+void vesa_set_raster_op(struct cdi_video_device *device,
+    enum cdi_video_raster_op rop);
+void vesa_draw_line(struct cdi_video_bitmap *target, unsigned int x1,
+    unsigned int y1, unsigned int x2, unsigned int y2,
+    struct cdi_video_color color);
+void vesa_draw_rectangle(struct cdi_video_bitmap *target, unsigned int x, 
+    unsigned int y, unsigned int width, unsigned int height, 
+    struct cdi_video_color color);
+void vesa_draw_ellipse(struct cdi_video_bitmap *target, unsigned int x, 
+    unsigned int y, unsigned int width, unsigned int height, 
+    struct cdi_video_color color);
+void vesa_draw_bitmap(struct cdi_video_bitmap *target, 
+    struct cdi_video_bitmap *bitmap, unsigned int x, unsigned int y);
+void vesa_draw_bitmap_part(struct cdi_video_bitmap *target, 
+    struct cdi_video_bitmap *bitmap, unsigned int x, unsigned int y, 
+    unsigned int srcx, unsigned int srcy, unsigned int width, 
+    unsigned int height);
+inline void vesa_draw_dot(struct cdi_video_bitmap *target, unsigned int x,
+    unsigned int y, struct cdi_video_color color);
+
+inline uint32_t do_rop(enum cdi_video_raster_op rop, uint32_t new, uint32_t old);
+inline uint32_t convert_color(struct cdi_video_pixel_format fmt,
+    struct cdi_video_color cdicolor);
+struct cdi_video_color convert_color_from_pixel(struct cdi_video_pixel_format
+    fmt, uint32_t value);
+
+#endif /* __VESA_DRAWING_H__ */
diff --git a/src/modules/cdi/vesa/main.c b/src/modules/cdi/vesa/main.c
new file mode 100644
index 0000000..ed6ba22
--- /dev/null
+++ b/src/modules/cdi/vesa/main.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2008 Alexander Siol
+ *
+ * This program is free software. It comes without any warranty, to
+ * the extent permitted by applicable law. You can redistribute it 
+ * and/or modify it under the terms of the Do What The Fuck You Want 
+ * To Public License, Version 2, as published by Sam Hocevar. See
+ * http://sam.zoy.org/projects/COPYING.WTFPL for more details.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <cdi.h>
+#include <cdi/misc.h>
+#include <cdi/video.h>
+#include <cdi/pci.h>
+#include <cdi/lists.h>
+#include <cdi/vesa.h>
+
+#include "vesa.h"
+#include "bitmap.h"
+#include "device.h"
+#include "drawing.h"
+
+char *driver_name = "vesa";
+struct cdi_video_vesa_driver vesa_driver;
+
+static void vesa_driver_init(void);
+static void vesa_driver_destroy(struct cdi_driver* driver);
+void vesa_init_device(struct cdi_device* device);
+
+#define DEBUG printf
+#define TODO //
+
+#ifdef CDI_STANDALONE
+int main(void)
+#else
+int init_vesa(void)
+#endif
+{
+    DEBUG("vesa driver running\n");
+    cdi_init();
+    vesa_driver_init();
+
+    cdi_run_drivers();
+
+    return 0;
+}
+
+/**
+ * Initialisiert den Treiber und registriert ihn
+ */
+static void vesa_driver_init(void)
+{
+    cdi_list_t pci_devices;
+    struct cdi_pci_device *pci;
+
+    memset(&vesa_driver, 0, sizeof(vesa_driver));
+    cdi_video_driver_init((struct cdi_video_driver*)&vesa_driver);
+
+    // Fill driver struct
+    vesa_driver.drv.drv.name = driver_name;
+    vesa_driver.drv.drv.type = CDI_VIDEO;
+    vesa_driver.drv.drv.init_device = NULL;//vesa_init_device;
+    vesa_driver.drv.drv.remove_device = NULL;
+    vesa_driver.drv.drv.destroy = vesa_driver_destroy;
+
+    vesa_driver.drv.display_set_mode = vesa_display_set_mode;
+
+    vesa_driver.drv.bitmap_create = vesa_bitmap_create;
+    vesa_driver.drv.bitmap_destroy = vesa_bitmap_destroy;
+    vesa_driver.drv.bitmap_set_usage_hint = vesa_bitmap_set_usage_hint;
+
+    vesa_driver.drv.set_raster_op = vesa_set_raster_op;
+    vesa_driver.drv.draw_line = vesa_draw_line;
+    vesa_driver.drv.draw_rectangle = vesa_draw_rectangle;
+    vesa_driver.drv.draw_ellipse = NULL;//vesa_draw_ellipse;
+    vesa_driver.drv.draw_bitmap = vesa_draw_bitmap;
+    vesa_driver.drv.draw_bitmap_part = vesa_draw_bitmap_part;
+    vesa_driver.drv.draw_dot = vesa_draw_dot;
+
+    // Find VGA cards
+    pci_devices = cdi_list_create();
+    cdi_pci_get_all_devices(pci_devices);
+    while ((pci = cdi_list_pop(pci_devices))) {
+        if (pci->class_id == 0x03 && pci->subclass_id == 0x00 &&
+            pci->interface_id == 0x00) {
+            char *name = malloc(8);
+            snprintf(name, 8, "vesa%01d", cdi_list_size(vesa_driver.drv.drv.devices));
+            struct vesa_device *dev = vesa_device_create(name, pci);
+            dev->dev.dev.driver = (struct cdi_driver*)&vesa_driver;
+            cdi_list_push(vesa_driver.drv.drv.devices, dev);
+        } else {
+            cdi_pci_device_destroy(pci);
+        }
+    }
+    cdi_list_destroy(pci_devices);
+
+    // TODO FIXME Nach init_device verschieben!
+    struct cdi_video_vesa_info_block **vesainfo_ptr;
+    vesainfo_ptr = malloc(sizeof(void*));
+    // Abort at once if we don't have VESA
+    if (cdi_video_vesa_initialize(vesainfo_ptr, vesa_mode_callback) == -1) {
+        return;
+    }
+
+    // Registers the driver
+    cdi_video_driver_register((struct cdi_video_driver*)&vesa_driver);
+}
+
+void vesa_init_device(struct cdi_device* device) {
+    return;
+}
+
+/**
+ * Zerstoert den Treiber
+ * @param driver Pointer to the driver
+ */
+static void vesa_driver_destroy(struct cdi_driver* driver)
+{
+    cdi_video_driver_destroy((struct cdi_video_driver*)driver);
+}
diff --git a/src/modules/cdi/vesa/vesa.h b/src/modules/cdi/vesa/vesa.h
new file mode 100644
index 0000000..d6c6271
--- /dev/null
+++ b/src/modules/cdi/vesa/vesa.h
@@ -0,0 +1,47 @@
+/*  
+ * Copyright (c) 2009 The tyndur Project. All rights reserved.
+ *
+ * This code is derived from software contributed to the tyndur Project
+ * by Alexander SIol.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR 
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef VESA_H
+#define VESA_H
+
+#include <cdi/pci.h>
+
+
+extern struct cdi_video_vesa_driver vesa_driver;
+
+struct cdi_video_vesa_driver {
+    struct cdi_video_driver drv;
+};
+
+struct vesa_device {
+    struct cdi_video_device dev;
+};
+
+struct vesa_device *vesa_device_create(char *name, struct cdi_pci_device* pci);
+
+#endif /* VESA_H */
\ No newline at end of file
-- 
1.6.0.4