CBM font usable on LCD display

Put "i2cLcdUseCBMChar = 1" to the option.txt file.
You have to use the Chargen rom too
This commit is contained in:
gbouille 2018-12-18 08:23:53 +01:00
parent cb04179fc9
commit 8b3dc69bac
11 changed files with 78 additions and 28 deletions

View File

@ -94,6 +94,7 @@ GraphIEC = 1
//i2cLcdFlip = 1 // Rotate i2c LCD screen 180 degrees
//i2cLcdOnContrast = 127 // Allows you to adjust the contrast on your i2c LCD screen
//i2cScan = 1 // scan i2c bus and display addresses on screen
//i2cLcdUseCBMChar = 0 // set it to 1 to use CBM font on LCD. Small but fun !
//QuickBoot = 0 // faster startup
//ShowOptions = 0 // display some options on startup screen

View File

@ -82,7 +82,7 @@ void FileBrowser::BrowsableListView::RefreshLine(u32 entryIndex, u32 x, u32 y, b
if (entryIndex < list->entries.size())
{
FileBrowser::BrowsableList::Entry* entry = &list->entries[entryIndex];
if (screen->IsMonocrome())
if (screen->IsLCD())
{
// pre-clear line on OLED
memset(buffer1, ' ', columnsMax);
@ -114,9 +114,9 @@ void FileBrowser::BrowsableListView::RefreshLine(u32 entryIndex, u32 x, u32 y, b
int len = strlen(buffer2 + highlightScrollOffset);
strncpy(buffer1, buffer2 + highlightScrollOffset, sizeof(buffer1));
if (!screen->IsMonocrome())
if (!screen->IsLCD())
{
// space pad the remainder of the line (but not on OLED==monochrome)
// space pad the remainder of the line (but not on OLED)
while (len < (int)columnsMax)
buffer1[len++] = ' ';
buffer1[columnsMax] = 0;
@ -524,7 +524,7 @@ FileBrowser::FileBrowser(InputMappings* inputMappings, DiskCaddy* diskCaddy, ROM
if (screenLCD)
{
columns = screenLCD->Width() / 8;
rows = screenLCD->Height() / 16;
rows = screenLCD->Height() / screenLCD->GetFontHeight();
positionX = 0;
positionY = 0;

View File

@ -24,6 +24,7 @@ static inline u8 ascii2petscii(u8 ch)
if (ch > 64 && ch < 91) ch += 128;
else if (ch > 96 && ch < 123) ch -= 32;
else if (ch > 192 && ch < 219) ch -= 128;
else if (ch == 95) ch = 164; // to handle underscore
return ch;
}
static inline u8 petscii2ascii(u8 ch)

View File

@ -19,12 +19,15 @@
#include "SSD1306.h"
#include "debug.h"
#include <string.h>
#include "Petscii.h"
extern "C"
{
#include "xga_font_data.h"
}
extern unsigned char* CBMFont;
SSD1306::SSD1306(int BSCMaster, u8 address, unsigned width, unsigned height, int flip, LCD_MODEL type)
: BSCMaster(BSCMaster)
, address(address)
@ -142,13 +145,13 @@ void SSD1306::RefreshScreen()
}
}
// assumes a text row is 16 bit high
// assumes a text row is 8 bit high
void SSD1306::RefreshTextRows(u32 start, u32 amountOfRows)
{
unsigned int i;
start <<= 1;
amountOfRows <<= 1;
//start <<= 1;
//amountOfRows <<= 1;
for (i = start; i < start+amountOfRows; i++)
{
RefreshPage(i);
@ -230,14 +233,14 @@ void SSD1306::SetVCOMDeselect(u8 value)
SendCommand( (value & 7) << 4 );
}
void SSD1306::PlotText(int x, int y, char* str, bool inverse)
void SSD1306::PlotText(bool useCBMFont, bool petscii, int x, int y, char* str, bool inverse)
{
// assumes 16 character width
int i;
i = 0;
while (str[i] && x < 16)
{
PlotCharacter(x++, y, str[i++], inverse);
PlotCharacter(useCBMFont, petscii, x++, y, str[i++], inverse);
}
}
@ -268,13 +271,25 @@ void transpose8(unsigned char* B, const unsigned char* A, bool inverse)
B[4] = y >> 24; B[5] = y >> 16; B[6] = y >> 8; B[7] = y;
}
void SSD1306::PlotCharacter(int x, int y, char c, bool inverse)
void SSD1306::PlotCharacter(bool useCBMFont, bool petscii, int x, int y, char c, bool inverse)
{
unsigned char a[8], b[8];
transpose8(a, avpriv_vga16_font + (c * 16), inverse);
transpose8(b, avpriv_vga16_font + (c * 16) + 8, inverse);
memcpy(frame + (y * 256) + (x * 8), a, 8);
memcpy(frame + (y * 256) + (x * 8) + 128, b, 8);
if (useCBMFont && CBMFont)
{
if (! petscii)
c = ascii2petscii(c);
c = petscii2screen(c);
transpose8(a, CBMFont + ((c+256) * 8), inverse); // 256 byte shift to use the maj/min bank
memcpy(frame + (y * 128) + (x * 8), a, 8);
}
else
{
transpose8(a, avpriv_vga16_font + (c * 16), inverse);
transpose8(b, avpriv_vga16_font + (c * 16) + 8, inverse);
memcpy(frame + (y * 256) + (x * 8), a, 8);
memcpy(frame + (y * 256) + (x * 8) + 128, b, 8);
}
}
void SSD1306::PlotPixel(int x, int y, int c)

View File

@ -77,8 +77,8 @@ public:
// 128x64 0x3D or 0x3C (if SA0 is grounded)
SSD1306(int BSCMaster = 1, u8 address = 0x3C, unsigned width = 128, unsigned height = 64, int flip = 0, LCD_MODEL type=LCD_UNKNOWN);
void PlotCharacter(int x, int y, char ascii, bool inverse);
void PlotText(int x, int y, char* str, bool inverse);
void PlotCharacter(bool useCBMFont, bool petscii, int x, int y, char ascii, bool inverse);
void PlotText(bool useCBMFont, bool petscii, int x, int y, char* str, bool inverse);
void InitHardware();
void DisplayOn();

View File

@ -74,6 +74,9 @@ public:
virtual void SwapBuffers() = 0;
virtual void RefreshRows(u32 start, u32 amountOfRows) {}
virtual bool IsLCD() { return false; };
virtual bool UseCBMFont() { return false; };
bool IsMonocrome() const { return bpp == 1; }
protected:

View File

@ -23,7 +23,9 @@
#include "debug.h"
#include "ssd_logo.h"
void ScreenLCD::Open(u32 widthDesired, u32 heightDesired, u32 colourDepth, int BSCMaster, int LCDAddress, int LCDFlip, LCD_MODEL LCDType)
extern unsigned char* CBMFont;
void ScreenLCD::Open(u32 widthDesired, u32 heightDesired, u32 colourDepth, int BSCMaster, int LCDAddress, int LCDFlip, LCD_MODEL LCDType, bool luseCBMFont)
{
bpp = 1;
@ -38,7 +40,8 @@ void ScreenLCD::Open(u32 widthDesired, u32 heightDesired, u32 colourDepth, int B
width = widthDesired;
height = heightDesired;
useCBMFont = luseCBMFont;
ssd1306 = new SSD1306(BSCMaster, LCDAddress, width, height, LCDFlip, LCDType);
ssd1306->ClearScreen();
ssd1306->RefreshScreen();
@ -100,7 +103,7 @@ void ScreenLCD::PlotRawImage(const u8* image, int x, int y, int w, int h)
u32 ScreenLCD::PrintText(bool petscii, u32 x, u32 y, char *ptr, RGBA TxtColour, RGBA BkColour, bool measureOnly, u32* width, u32* height)
{
int len = 0;
ssd1306->PlotText(x >> 3, y >> 4, ptr, (BkColour & 0xffffff) != 0);
ssd1306->PlotText(UseCBMFont(), petscii, x >> 3, y >> 4, ptr, (BkColour & 0xffffff) != 0);
return len;
}
@ -111,7 +114,10 @@ u32 ScreenLCD::MeasureText(bool petscii, char *ptr, u32* width, u32* height)
u32 ScreenLCD::GetFontHeight()
{
return 16;
if (CBMFont && useCBMFont)
return 8;
else
return 16;
}
void ScreenLCD::RefreshScreen()
@ -127,5 +133,20 @@ void ScreenLCD::SwapBuffers()
void ScreenLCD::RefreshRows(u32 start, u32 amountOfRows)
{
if (ssd1306)
{
if (UseCBMFont())
ssd1306->RefreshTextRows(start, amountOfRows);
else
ssd1306->RefreshTextRows(start*2, amountOfRows*2);
}
}
bool ScreenLCD::IsLCD()
{
return true;
}
bool ScreenLCD::UseCBMFont()
{
return (CBMFont && useCBMFont);
}

View File

@ -33,7 +33,7 @@ public:
{
}
void Open(u32 width, u32 height, u32 colourDepth, int BSCMaster, int LCDAddress, int LCDFlip, LCD_MODEL LCDType);
void Open(u32 width, u32 height, u32 colourDepth, int BSCMaster, int LCDAddress, int LCDFlip, LCD_MODEL LCDType, bool luseCBMFont);
void DrawRectangle(u32 x1, u32 y1, u32 x2, u32 y2, RGBA colour);
void Clear(RGBA colour);
@ -59,9 +59,11 @@ public:
void RefreshScreen();
void RefreshRows(u32 start, u32 amountOfRows);
bool IsLCD();
bool UseCBMFont();
private:
SSD1306* ssd1306 = 0;
bool useCBMFont;
};
#endif

View File

@ -117,6 +117,7 @@ u16 pc;
unsigned int screenWidth = 1024;
unsigned int screenHeight = 768;
int i2cLcdUseCBMChar = 0;
const char* termainalTextRed = "\E[31m";
const char* termainalTextNormal = "\E[0m";
@ -250,6 +251,7 @@ void InitialiseLCD()
int i2cLcdOnContrast = options.I2CLcdOnContrast();
int i2cLcdDimContrast = options.I2CLcdDimContrast();
int i2cLcdDimTime = options.I2CLcdDimTime();
i2cLcdUseCBMChar = options.I2cLcdUseCBMChar();
LCD_MODEL i2cLcdModel = options.I2CLcdModel();
if (i2cLcdModel)
@ -259,7 +261,7 @@ void InitialiseLCD()
if (i2cLcdModel == LCD_1306_128x32)
height = 32;
screenLCD = new ScreenLCD();
screenLCD->Open(width, height, 1, i2cBusMaster, i2cLcdAddress, i2cLcdFlip, i2cLcdModel);
screenLCD->Open(width, height, 1, i2cBusMaster, i2cLcdAddress, i2cLcdFlip, i2cLcdModel, i2cLcdUseCBMChar);
screenLCD->SetContrast(i2cLcdOnContrast);
screenLCD->ClearInit(0); // sh1106 needs this
@ -268,7 +270,7 @@ void InitialiseLCD()
{
screenLCD->PlotRawImage(logo_ssd_1541ii, 0, 0, width, height);
snprintf(tempBuffer, tempBufferSize, "Pi1541 V%d.%02d", versionMajor, versionMinor);
screenLCD->PrintText(0, 16, 0, tempBuffer, 0xffffffff);
screenLCD->PrintText(false, 16, 0, tempBuffer, 0xffffffff);
logo_done = true;
}
else if (( height == 64) && (strcasecmp(options.GetLcdLogoName(), "1541classic") == 0) )
@ -297,7 +299,7 @@ void InitialiseLCD()
snprintf(tempBuffer, tempBufferSize, "Pi1541 V%d.%02d", versionMajor, versionMinor);
int x = (width - 8*strlen(tempBuffer) ) /2;
int y = (height-16)/2;
screenLCD->PrintText(0, x, y, tempBuffer, 0x0);
screenLCD->PrintText(false, x, y, tempBuffer, 0x0);
}
screenLCD->RefreshScreen();
}
@ -345,7 +347,7 @@ void UpdateScreen()
int top, top2, top3;
int bottom;
int graphX = 0;
//bool refreshUartStatusDisplay;
//bool refreshUartStatusDisplay;
top = screenHeight - height / 2;
bottom = screenHeight - 1;
@ -1051,7 +1053,7 @@ void emulator()
m_IEC_Commands.SetAutoBootFB128(options.AutoBootFB128());
m_IEC_Commands.Set128BootSectorName(options.Get128BootSectorName());
m_IEC_Commands.SetLowercaseBrowseModeFilenames(options.LowercaseBrowseModeFilenames());
m_IEC_Commands.SetLowercaseBrowseModeFilenames(options.LowercaseBrowseModeFilenames());
emulating = IEC_COMMANDS;
@ -1343,6 +1345,8 @@ void DisplayOptions(int y_pos)
screen.PrintText(false, 0, y_pos += 16, tempBuffer, COLOUR_WHITE, COLOUR_BLACK);
snprintf(tempBuffer, tempBufferSize, "AutoBaseName = %s\r\n", options.GetAutoBaseName());
screen.PrintText(false, 0, y_pos += 16, tempBuffer, COLOUR_WHITE, COLOUR_BLACK);
snprintf(tempBuffer, tempBufferSize, "I2cLcdUseCBMChar = %d\r\n", i2cLcdUseCBMChar);
screen.PrintText(false, 0, y_pos += 16, tempBuffer, COLOUR_WHITE, COLOUR_BLACK);
}
void DisplayI2CScan(int y_pos)

View File

@ -148,6 +148,7 @@ Options::Options(void)
, i2cLcdFlip(0)
, i2cLcdOnContrast(127)
, i2cLcdModel(LCD_UNKNOWN)
, i2cLcdUseCBMChar(0)
, scrollHighlightRate(0.125f)
, keyboardBrowseLCDScreen(0)
, buttonEnter(1)
@ -235,6 +236,7 @@ void Options::Process(char* buffer)
ELSE_CHECK_DECIMAL_OPTION(i2cLcdOnContrast)
ELSE_CHECK_DECIMAL_OPTION(i2cLcdDimContrast)
ELSE_CHECK_DECIMAL_OPTION(i2cLcdDimTime)
ELSE_CHECK_DECIMAL_OPTION(i2cLcdUseCBMChar)
ELSE_CHECK_FLOAT_OPTION(scrollHighlightRate)
ELSE_CHECK_DECIMAL_OPTION(keyboardBrowseLCDScreen)
ELSE_CHECK_DECIMAL_OPTION(buttonEnter)

View File

@ -75,7 +75,6 @@ public:
inline unsigned int LowercaseBrowseModeFilenames() const { return lowercaseBrowseModeFilenames; }
inline unsigned int ScreenWidth() const { return screenWidth; }
inline unsigned int ScreenHeight() const { return screenHeight; }
@ -86,6 +85,7 @@ public:
inline unsigned int I2CLcdOnContrast() const { return i2cLcdOnContrast; }
inline unsigned int I2CLcdDimContrast() const { return i2cLcdDimContrast; }
inline unsigned int I2CLcdDimTime() const { return i2cLcdDimTime; }
inline unsigned int I2cLcdUseCBMChar() const { return i2cLcdUseCBMChar; }
inline LCD_MODEL I2CLcdModel() const { return i2cLcdModel; }
inline const char* GetLcdLogoName() const { return LcdLogoName; }
@ -141,6 +141,7 @@ private:
unsigned int i2cLcdOnContrast;
unsigned int i2cLcdDimContrast;
unsigned int i2cLcdDimTime;
unsigned int i2cLcdUseCBMChar;
LCD_MODEL i2cLcdModel = LCD_UNKNOWN;
float scrollHighlightRate;