diff --git a/devices/video/pdmonboard.cpp b/devices/video/pdmonboard.cpp
index 2d85828..74c3118 100644
--- a/devices/video/pdmonboard.cpp
+++ b/devices/video/pdmonboard.cpp
@@ -26,6 +26,7 @@ along with this program. If not, see .
#include
#include
#include
+#include
#include
#include
@@ -116,20 +117,38 @@ void PdmOnboardVideo::set_clut_color(uint8_t color)
}
}
-void PdmOnboardVideo::set_depth_internal(int pitch)
+void PdmOnboardVideo::set_depth_internal(int width)
{
switch (this->pixel_depth) {
case 1:
this->convert_fb_cb = [this](uint8_t* dst_buf, int dst_pitch) {
this->convert_frame_1bpp_indexed(dst_buf, dst_pitch);
};
- this->fb_pitch = pitch >> 3; // one byte contains 8 pixels
+ this->fb_pitch = width >> 3; // one byte contains 8 pixels
+ break;
+ case 2:
+ this->convert_fb_cb = [this](uint8_t* dst_buf, int dst_pitch) {
+ this->convert_frame_2bpp_indexed(dst_buf, dst_pitch);
+ };
+ this->fb_pitch = width >> 2; // one byte contains 4 pixels
+ break;
+ case 4:
+ this->convert_fb_cb = [this](uint8_t* dst_buf, int dst_pitch) {
+ this->convert_frame_4bpp_indexed(dst_buf, dst_pitch);
+ };
+ this->fb_pitch = width >> 1; // one byte contains 2 pixels
break;
case 8:
this->convert_fb_cb = [this](uint8_t* dst_buf, int dst_pitch) {
this->convert_frame_8bpp_indexed(dst_buf, dst_pitch);
};
- this->fb_pitch = pitch; // one byte contains 1 pixel
+ this->fb_pitch = width; // one byte contains 1 pixel
+ break;
+ case 16:
+ this->convert_fb_cb = [this](uint8_t* dst_buf, int dst_pitch) {
+ this->convert_frame_15bpp_BE(dst_buf, dst_pitch);
+ };
+ this->fb_pitch = width << 1; // 1 pixel is 2 bytes
break;
default:
ABORT_F("PDM-Video: pixel depth %d not implemented yet!", this->pixel_depth);
@@ -241,29 +260,86 @@ void PdmOnboardVideo::disable_video_internal()
*/
void PdmOnboardVideo::convert_frame_1bpp_indexed(uint8_t *dst_buf, int dst_pitch)
{
- uint8_t *src_buf, *src_row, pix;
- uint32_t *dst_row;
- int src_pitch, width;
- uint32_t pixels[2];
+ uint8_t *src_row, *dst_row;
+ int src_pitch;
+ uint64_t pixels;
// prepare cached ARGB values for white & black pixels
- pixels[0] = this->palette[127];
- pixels[1] = this->palette[255];
+ pixels = ((uint64_t)this->palette[127] << 32) | this->palette[255];
- src_buf = this->fb_ptr;
- src_pitch = this->fb_pitch;
- width = this->active_width >> 3;
+ src_pitch = this->fb_pitch - ((this->active_width + 7) >> 3);
+ dst_pitch = dst_pitch - 4 * this->active_width;
- for (int h = 0; h < this->active_height; h++) {
- src_row = &src_buf[h * src_pitch];
- dst_row = (uint32_t *)(&dst_buf[h * dst_pitch]);
-
- for (int x = 0; x < width; x++) {
- pix = src_row[x];
-
- for (int i = 0; i < 8; i++, pix <<= 1, dst_row++) {
- *dst_row = pixels[(pix >> 7) & 1];
+ src_row = this->fb_ptr - 1;
+ dst_row = dst_buf;
+ for (int h = this->active_height; h > 0; h--) {
+ uint8_t bit = 0x00;
+ uint8_t c;
+ for (int x = this->active_width; x > 0; x--) {
+ if (!bit) {
+ src_row += 1;
+ bit = 0x80;
+ c = *src_row;
}
+ WRITE_DWORD_LE_A(dst_row, (uint32_t)(pixels >> (!(c & bit) << 5)));
+ bit >>= 1;
+ dst_row += 4;
}
+ src_row += src_pitch;
+ dst_row += dst_pitch;
+ }
+}
+
+void PdmOnboardVideo::convert_frame_2bpp_indexed(uint8_t *dst_buf, int dst_pitch)
+{
+ uint8_t *src_row, *dst_row;
+ int src_pitch;
+
+ src_pitch = this->fb_pitch - (this->active_width >> 2);
+ dst_pitch = dst_pitch - 4 * this->active_width;
+
+ src_row = this->fb_ptr;
+ dst_row = dst_buf;
+ for (int h = this->active_height; h > 0; h--) {
+ uint8_t c;
+ for (int x = this->active_width >> 2; x > 0; x--) {
+ c = *src_row;
+ WRITE_DWORD_LE_A(dst_row, this->palette[c & 0xc0 | 0x3f]);
+ dst_row += 4;
+ WRITE_DWORD_LE_A(dst_row, this->palette[(c << 2) & 0xc0 | 0x3f]);
+ dst_row += 4;
+ WRITE_DWORD_LE_A(dst_row, this->palette[(c << 4) & 0xc0 | 0x3f]);
+ dst_row += 4;
+ WRITE_DWORD_LE_A(dst_row, this->palette[(uint8_t)(c << 6) | 0x3f]);
+ dst_row += 4;
+ src_row += 1;
+ }
+ src_row += src_pitch;
+ dst_row += dst_pitch;
+ }
+}
+
+void PdmOnboardVideo::convert_frame_4bpp_indexed(uint8_t *dst_buf, int dst_pitch)
+{
+ uint8_t *src_row, *dst_row;
+ int src_pitch;
+
+ src_pitch = this->fb_pitch - (this->active_width >> 1);
+ dst_pitch = dst_pitch - 4 * this->active_width;
+
+ src_row = this->fb_ptr;
+ dst_row = dst_buf;
+ for (int h = this->active_height; h > 0; h--) {
+ uint8_t c;
+ for (int x = this->active_width >> 1; x > 0; x--) {
+ c = *src_row;
+ WRITE_DWORD_LE_A(dst_row, this->palette[c & 0xf0 | 0x0f]);
+ dst_row += 4;
+ WRITE_DWORD_LE_A(dst_row, this->palette[(uint8_t)(c << 4) | 0x0f]);
+ dst_row += 4;
+ src_row += 1;
+ }
+ src_row += src_pitch;
+ dst_row += dst_pitch;
}
}
diff --git a/devices/video/pdmonboard.h b/devices/video/pdmonboard.h
index b8aac9f..6a403c2 100644
--- a/devices/video/pdmonboard.h
+++ b/devices/video/pdmonboard.h
@@ -69,10 +69,12 @@ public:
};
protected:
- void set_depth_internal(int pitch);
+ void set_depth_internal(int width);
void enable_video_internal();
void disable_video_internal();
void convert_frame_1bpp_indexed(uint8_t *dst_buf, int dst_pitch);
+ void convert_frame_2bpp_indexed(uint8_t *dst_buf, int dst_pitch);
+ void convert_frame_4bpp_indexed(uint8_t *dst_buf, int dst_pitch);
private:
uint8_t video_mode;