--- /dev/null
+/**
+ * \file
+ * <!--
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ * This file is part of DevLib - See README.devlib for information.
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief Custom control for graphics LCD emulation (interface)
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.1 2006/01/16 03:51:35 bernie
+ *#* Add LCD Qt emulator.
+ *#*
+ *#*/
+
+#include "lcd_gfx_qt.h"
+#include <emul/emul.h>
+
+#include <qpainter.h>
+#include <qimage.h>
+#include <qsizepolicy.h>
+#include <qsize.h>
+
+// Display colors
+#define LCD_FG_COLOR 0x0, 0x0, 0x0
+#define LCD_BG_COLOR 0xBB, 0xCC, 0xBB
+
+
+EmulLCD::EmulLCD(QWidget *parent, const char *name) :
+ QFrame(parent, name, WRepaintNoErase | WResizeNoErase),
+ fg_color(LCD_FG_COLOR),
+ bg_color(LCD_BG_COLOR)
+{
+ // initialize bitmap
+ memset(raster, 0xAA, sizeof(raster));
+
+ // set widget frame
+ setFrameStyle(QFrame::Panel | QFrame::Sunken);
+ frame_width = frameWidth();
+}
+
+
+EmulLCD::~EmulLCD()
+{
+ // nop
+}
+
+
+QSizePolicy EmulLCD::sizePolicy() const
+{
+ return QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed, false);
+}
+
+
+QSize EmulLCD::sizeHint() const
+{
+ return QSize(
+ WIDTH + frame_width * 2,
+ HEIGHT + frame_width * 2);
+}
+
+
+void EmulLCD::drawContents(QPainter *p)
+{
+ QImage img(raster, WIDTH, HEIGHT, 1, NULL, 0, QImage::IgnoreEndian);
+
+ p->setBackgroundMode(OpaqueMode);
+ p->setPen(fg_color);
+ p->setBackgroundColor(bg_color);
+ p->drawImage(frame_width, frame_width, img);
+}
+
+void EmulLCD::writeRaster(uint8_t *new_raster)
+{
+ memcpy(raster, new_raster, sizeof(raster));
+
+ QPainter p(this);
+ drawContents(&p);
+}
+
+
+
+#include <gfx/gfx.h>
+#include <cfg/debug.h>
+
+/*!
+ * Raster buffer to draw into.
+ * Bits in the bitmap bytes have vertical orientation,
+ * as required by the LCD driver.
+ */
+DECLARE_WALL(wall_before_raster, WALL_SIZE)
+static uint8_t lcd_raster[EmulLCD::WIDTH * ((EmulLCD::HEIGHT + 7) / 8)];
+DECLARE_WALL(wall_after_raster, WALL_SIZE)
+
+/*! Default LCD bitmap */
+struct Bitmap lcd_bitmap;
+
+extern "C" void lcd_init(void)
+{
+ gfx_bitmapInit(&lcd_bitmap, lcd_raster, EmulLCD::WIDTH, EmulLCD::HEIGHT);
+ gfx_bitmapClear(&lcd_bitmap);
+}
+
+extern "C" void lcd_blit_bitmap(Bitmap *bm)
+{
+ emul->emulLCD->writeRaster(bm->raster);
+}
+
+#include "lcd_gfx_qt_moc.cpp"
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2000,2001 Bernardo Innocenti <bernie@codewiz.org>
+ * This file is part of DevLib - See README.devlib for information.
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief Custom Qt widget for emulating a graphics LCD display (implementation)
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.1 2006/01/16 03:51:35 bernie
+ *#* Add LCD Qt emulator.
+ *#*
+ *#*/
+
+#include <qpainter.h>
+#include <qfont.h>
+#include <qsizepolicy.h>
+#include <qsize.h>
+#include "EmulLCD.h"
+#include "Emul.h"
+
+
+// Display colors
+#define LCD_FG_COLOR 0x0, 0x0, 0x0
+#define LCD_BG_COLOR 0xBB, 0xCC, 0xBB
+
+
+EmulLCD::EmulLCD(QWidget *parent, const char *name) :
+ QFrame(parent, name, WRepaintNoErase | WResizeNoErase),
+ lcd_font("courier", 18),
+ fg_color(LCD_FG_COLOR),
+ bg_color(LCD_BG_COLOR),
+ cr_row(0),
+ cr_col(0),
+ cgramaddr(-1),
+ show_cursor(true)
+{
+ // initialize DDRAM
+ memcpy(ddram,
+ "01234567890123456789"
+ "abcdefghijhlmnopqrst"
+ "ABCDEFGHIJKLMNOPQRST"
+ "!@#$%^&*()_+|{}':?><",
+ sizeof(ddram));
+
+ // setup font
+ lcd_font.setFixedPitch(true);
+ setFont(lcd_font);
+
+ // get exact font size
+ QFontMetrics fm(lcd_font);
+ font_width = fm.width(QChar(' '));
+ font_height = fm.height();
+
+ // set widget frame
+ setFrameStyle(QFrame::Panel | QFrame::Sunken);
+// setLineWidth(2);
+ frame_width = frameWidth();
+}
+
+
+EmulLCD::~EmulLCD()
+{
+ // nop
+}
+
+
+QSizePolicy EmulLCD::sizePolicy() const
+{
+ return QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed, false);
+}
+
+
+QSize EmulLCD::sizeHint() const
+{
+ return QSize(
+ font_width * COLS + frame_width * 2,
+ font_height * ROWS + frame_width * 2);
+}
+
+
+void EmulLCD::drawContents(QPainter *p)
+{
+ RedrawText(*p);
+}
+
+
+void EmulLCD::SetPainter(QPainter & p)
+{
+ p.setBackgroundMode(OpaqueMode);
+ p.setPen(fg_color);
+ p.setBackgroundColor(bg_color);
+}
+
+
+void EmulLCD::RedrawText(QPainter & p)
+{
+ int r, c;
+
+ SetPainter(p);
+
+ for (r = 0; r < ROWS; r++)
+ for (c = 0; c < COLS; c++)
+ PrintChar(p, r, c);
+}
+
+
+void EmulLCD::PrintChar(QPainter & p, int row, int col)
+{
+ // Fetch char from DD RAM
+ unsigned char c = ddram[row][col];
+
+ // Map some Hitachi characters to ISO Latin1
+ switch(c)
+ {
+ case 0xDF:
+ c = 0xBA; // "degrees" glyph
+ break;
+
+ case 0xE4:
+ c = 0xB5; // "micro" glyph
+ break;
+
+ default: // all others
+ break;
+ }
+
+ // Draw char on display
+ int x = col * font_width + frame_width;
+ int y = row * font_height + frame_width;
+ bool restore_colors = false;
+
+ if (show_cursor && (row == cr_row) && (col == cr_col))
+ {
+ // Exchange FG/BG colors
+ p.setPen(bg_color);
+ p.setBackgroundColor(fg_color);
+ restore_colors = true;
+ }
+
+ p.drawText(x, y, x + font_width, y + font_height, 0 /*tf*/,
+ QString(QChar(c)), 1);
+
+ if (restore_colors)
+ {
+ // Restore FG/BG colors
+ p.setPen(fg_color);
+ p.setBackgroundColor(bg_color);
+ }
+}
+
+
+void EmulLCD::MoveCursor(int r, int c)
+{
+ // Save old cursor position
+ int old_row = cr_row;
+ int old_col = cr_col;
+
+ // Move the cursor
+ cgramaddr = -1;
+ cr_row = r;
+ cr_col = c;
+
+ if (show_cursor && (old_col != cr_col || old_row != cr_row))
+ {
+ QPainter p(this);
+ SetPainter(p);
+
+ // Draw new cursor
+ PrintChar(p, cr_row, cr_col);
+
+ // Erase old cursor
+ PrintChar(p, old_row, old_col);
+ }
+}
+
+
+void EmulLCD::ShowCursor(bool show)
+{
+ show_cursor = show;
+
+ // Draw (or erase) cursor
+ QPainter p(this);
+ SetPainter(p);
+ PrintChar(p, cr_row, cr_col);
+}
+
+
+void EmulLCD::AdvanceCursor()
+{
+ // Move the cursor
+ if (cr_col == COLS - 1)
+ {
+ if (cr_row == ROWS - 1)
+ MoveCursor(0, 0);
+ else
+ MoveCursor(cr_row + 1, 0);
+ }
+ else
+ MoveCursor(cr_row, cr_col + 1);
+}
+
+
+void EmulLCD::PutChar(unsigned char c)
+{
+ if (cgramaddr != -1)
+ {
+ // Write data in CGRAM
+ cgram[cgramaddr] = c;
+
+ // Auto increment CGRAM address
+ cgramaddr = (cgramaddr + 1) & 0x3F;
+ }
+ else
+ {
+ // Writing in DDRAM
+ ddram[cr_row][cr_col] = c;
+
+ // Update display
+ {
+ QPainter p(this);
+ SetPainter(p);
+ PrintChar(p, cr_row, cr_col);
+ }
+ AdvanceCursor();
+ }
+}
+
+
+char EmulLCD::GetChar()
+{
+ char c = ddram[cr_row][cr_col];
+ AdvanceCursor();
+ return c;
+}
+
+
+void EmulLCD::Clear()
+{
+ memset(ddram, ' ', sizeof(ddram));
+ cr_row = cr_col = 0;
+
+ QPainter p(this);
+ RedrawText(p);
+}
+
+
+void EmulLCD::SetCGRamAddr(unsigned char addr)
+{
+ cgramaddr = addr & (sizeof(cgram) - 1);
+}
+
+
+// Hitachi LM044L register-level emulation
+
+#define INI_DISPLAY 0x30
+#define INI_OP_DISP 0x38 /* 8 bits, 2 lines, 5x7 dots */
+#define ON_DISPLAY 0x0F /* Switch on display */
+#define OFF_DISPLAY 0x08 /* Switch off display */
+#define CLR_DISPLAY 0x01 /* Clear display */
+#define CURSOR_BLOCK 0x0D /* Show cursor (block) */
+#define CURSOR_LINE 0x0F /* Show cursor (line) */
+#define CURSOR_OFF 0x0C /* Hide cursor */
+#define MODE_DISPL 0x06
+#define SHIFT_DISPLAY 0x18
+#define MOVESHIFT_LEFT 0x00
+#define MOVESHIFT_RIGHT 0x04
+#define LCD_CGRAMADDR (1<<6)
+#define LCD_DDRAMADDR (1<<7)
+
+
+extern "C" void Emul_LCDWriteReg(unsigned char d)
+{
+ static const unsigned char lcd_rowaddress[EmulLCD::ROWS] = { 0x80, 0xC0, 0x94, 0xD4 };
+
+ switch(d)
+ {
+ case CLR_DISPLAY:
+ emul->emulLCD->Clear();
+ break;
+
+ case CURSOR_BLOCK:
+ case CURSOR_LINE:
+ emul->emulLCD->ShowCursor(true);
+ break;
+
+ case CURSOR_OFF:
+ emul->emulLCD->ShowCursor(false);
+ break;
+
+ default:
+ // Set DDRAM address?
+ if (d & LCD_DDRAMADDR)
+ {
+ for (int i = 0; i < EmulLCD::ROWS; i++)
+ {
+ if ((d >= lcd_rowaddress[i]) && (d < lcd_rowaddress[i] + EmulLCD::COLS))
+ {
+ emul->emulLCD->MoveCursor(i, d - lcd_rowaddress[i]);
+ break;
+ }
+ }
+ }
+ else if (d & LCD_CGRAMADDR)
+ emul->emulLCD->SetCGRamAddr(d);
+ break;
+ }
+}
+
+
+extern "C" unsigned char Emul_LCDReadReg(void)
+{
+ return 0; /* This LCD model is never busy ;-) */
+}
+
+
+extern "C" void Emul_LCDWriteData(unsigned char d)
+{
+ emul->emulLCD->PutChar(d);
+}
+
+
+extern "C" unsigned char Emul_LCDReadData(void)
+{
+ return emul->emulLCD->GetChar();
+}
+
+#include "EmulLCD.moc"
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2000,2001 Bernardo Innocenti <bernie@codewiz.org>
+ * This file is part of DevLib - See README.devlib for information.
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief Custom Qt widget for emulating a graphics LCD display (implementation)
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.1 2006/01/16 03:51:35 bernie
+ *#* Add LCD Qt emulator.
+ *#*
+ *#*/
+
+#ifndef EMULLCD_H
+#define EMULLCD_H
+
+#include <qframe.h>
+#include <qfont.h>
+#include <qcolor.h>
+
+// fwd decls
+class QSizePolicy;
+class QPaintEvent;
+class QResizeEvent;
+
+/**
+ * Qt widget to emulate a dot-matrix LCD display.
+ */
+class EmulLCD : public QFrame
+{
+ Q_OBJECT
+
+public:
+// Attributes
+ enum { COLS = 20, ROWS = 4 };
+
+// Construction
+ EmulLCD(QWidget *parent = 0, const char *name = 0);
+ virtual ~EmulLCD();
+
+// Base class overrides
+protected:
+ virtual QSizePolicy sizePolicy() const;
+ virtual QSize sizeHint() const;
+ virtual void drawContents(QPainter *p);
+
+// Operations
+public:
+ void MoveCursor (int col, int row);
+ void ShowCursor (bool show = true);
+ void PutChar (unsigned char c);
+ char GetChar ();
+ void Clear ();
+ void SetCGRamAddr (unsigned char addr);
+
+// Implementation
+protected:
+ void SetPainter(QPainter & p);
+ void RedrawText(QPainter & p);
+ void PrintChar(QPainter & p, int row, int col);
+ void AdvanceCursor();
+
+ QFont lcd_font; ///< Display character font
+ QColor fg_color, bg_color; ///< LCD colors
+ int font_width, font_height; ///< Font dimensions
+ int frame_width; ///< Frame width (and height)
+ int cr_row, cr_col; ///< Cursor position
+ int cgramaddr; ///< CGRAM Address (-1 disabled)
+ unsigned char ddram[ROWS][COLS];///< Display data RAM
+ unsigned char cgram[8*8]; ///< CGRAM
+ bool show_cursor; ///< Cursor enabled?
+};
+
+#endif // !defined(EMULLCD_H)
+