gearmulator

Emulation of classic VA synths of the late 90s/2000s that are based on Motorola 56300 family DSPs
Log | Files | Refs | Submodules | README | LICENSE

lcd.cpp (4841B)


      1 #include "lcd.h"
      2 
      3 #include <cassert>
      4 
      5 #include "mc68k/logging.h"
      6 
      7 #define LOG MCLOG
      8 
      9 namespace hwLib
     10 {
     11 	LCD::LCD() = default;
     12 
     13 	std::optional<uint8_t> LCD::exec(bool registerSelect, bool read, uint8_t g)
     14 	{
     15 		bool changed = false;
     16 		bool cgRamChanged = false;
     17 
     18 		std::optional<uint8_t> result;
     19 
     20 		if(!read)
     21 		{
     22 			if(!registerSelect)
     23 			{
     24 				if(g == 0x01)
     25 				{
     26 					LOG("LCD Clear Display");
     27 					m_dramData.fill(' ');
     28 					changed = true;
     29 				}
     30 				else if(g == 0x02)
     31 				{
     32 					LOG("LCD Return Home");
     33 					m_dramAddr = 0;
     34 					m_cursorPos = 0;
     35 				}
     36 				else if((g & 0xfc) == 0x04)
     37 				{
     38 					const int increment = (g >> 1) & 1;
     39 					const int shift = g & 1;
     40 					LOG("LCD Entry Mode Set, inc=" << increment << ", shift=" << shift);
     41 
     42 					m_addrIncrement = increment ? 1 : -1;
     43 				}
     44 				else if((g & 0xf8) == 0x08)
     45 				{
     46 					const int displayOnOff = (g >> 2) & 1;
     47 					const int cursorOnOff = (g >> 1) & 1;
     48 					const int cursorBlinking = g & 1;
     49 
     50 					LOG("LCD Display ON/OFF, display=" << displayOnOff << ", cursor=" << cursorOnOff << ", blinking=" << cursorBlinking);
     51 
     52 					m_displayOn = displayOnOff != 0;
     53 					m_cursorOn = cursorOnOff != 0;
     54 					m_cursorBlinking = cursorBlinking != 0;
     55 				}
     56 				else if((g & 0xf3) == 0x10)
     57 				{
     58 					const int scrl = (g >> 2) & 3;
     59 
     60 					LOG("LCD Cursor/Display Shift, scrl=" << scrl);
     61 					m_cursorShift = static_cast<CursorShiftMode>(scrl);
     62 				}
     63 				else if((g & 0xec) == 0x28)
     64 				{
     65 					const int dl = (g >> 4) & 1;
     66 					const int ft = g & 3;
     67 
     68 					LOG("LCD Function Set, dl=" << dl << ", ft=" << ft);
     69 					m_dataLength = static_cast<DataLength>(dl);
     70 					m_fontTable = static_cast<FontTable>(ft);
     71 				}
     72 				else if(g & (1<<7))
     73 				{
     74 					const int addr = g & 0x7f;
     75 //					LOG("LCD Set DDRAM address, addr=" << addr);
     76 					m_dramAddr = addr;
     77 					m_addressMode = AddressMode::DDRam;
     78 				}
     79 				else if(g & (1<<6))
     80 				{
     81 					const int acg = g & 0x3f;
     82 
     83 //					LOG("LCD Set CGRAM address, acg=" << acg);
     84 					m_cgramAddr = acg;
     85 					m_addressMode = AddressMode::CGRam;
     86 				}
     87 				else
     88 				{
     89 					LOG("LCD unknown command");
     90 					assert(false);
     91 				}
     92 			}
     93 			else
     94 			{
     95 				if(m_addressMode == AddressMode::CGRam)
     96 				{
     97 //					changed = true;
     98 //					LOG("LCD write data to CGRAM addr " << m_cgramAddr << ", data=" << static_cast<int>(g));
     99 
    100 					if (m_cgramData[m_cgramAddr] != g)
    101 					{
    102 						m_cgramData[m_cgramAddr] = g;
    103 						cgRamChanged = true;
    104 					}
    105 
    106 					m_cgramAddr += m_addrIncrement;
    107 
    108 					/*
    109 					if((m_cgramAddr & 0x7) == 0)
    110 					{
    111 						std::stringstream ss;
    112 						ss << "CG RAM character " << (m_cgramAddr/8 - 1) << ':' << '\n';
    113 						ss << "##################" << '\n';
    114 						for(auto i = m_cgramAddr - 8; i < m_cgramAddr - 1; ++i)
    115 						{
    116 							ss << '#';
    117 							for(int x=7; x >= 0; --x)
    118 							{
    119 								if(m_cgramData[i] & (1<<x))
    120 									ss << "[]";
    121 								else
    122 									ss << "  ";
    123 							}
    124 							ss << '#' << '\n';
    125 						}
    126 						ss << "##################" << '\n';
    127 						const auto s(ss.str());
    128 						LOG(s);
    129 					}
    130 					*/
    131 				}
    132 				else
    133 				{
    134 //					LOG("LCD write data to DDRAM addr " << m_dramAddr << ", data=" << static_cast<int>(g) << ", char=" << static_cast<char>(g));
    135 
    136 					const auto old = m_dramData;
    137 
    138 					if(m_dramAddr >= 20 && m_dramAddr < 0x40)
    139 					{
    140 						for(size_t i=1; i<=20; ++i)
    141 							m_dramData[i-1] = m_dramData[i];
    142 						m_dramData[19] = static_cast<char>(g);
    143 					}
    144 					else if(m_dramAddr > 0x53)
    145 					{
    146 						for(size_t i=21; i<=40; ++i)
    147 							m_dramData[i-1] = m_dramData[i];
    148 
    149 						m_dramData[39] = static_cast<char>(g);
    150 					}
    151 					else
    152 					{
    153 						if(m_dramAddr < 20)
    154 							m_dramData[m_dramAddr] = static_cast<char>(g);
    155 						else
    156 							m_dramData[m_dramAddr - 0x40 + 20] = static_cast<char>(g);
    157 					}
    158 
    159 					if(m_dramAddr != 20 && m_dramAddr != 0x54)
    160 						m_dramAddr += m_addrIncrement;
    161 
    162 					if(m_dramData != old)
    163 						changed = true;
    164 				}
    165 			}
    166 		}
    167 		else
    168 		{
    169 			if(registerSelect)
    170 			{
    171 				LOG("LCD read data from CGRAM or DDRAM");
    172 				if(m_addressMode == AddressMode::CGRam)
    173 					result = m_cgramData[m_cgramAddr];
    174 				else
    175 					result = m_dramData[m_dramAddr];
    176 			}
    177 			else
    178 			{
    179 				LOG("LCD read busy flag & address");
    180 				if(m_addressMode == AddressMode::CGRam)
    181 				{
    182 					result = static_cast<uint8_t>(m_cgramAddr);
    183 				}
    184 				else
    185 				{
    186 					auto a = m_dramAddr;
    187 					if(a > 0x53)
    188 						a = 0x53;
    189 					if(a == 20)
    190 						a = 19;
    191 					result = static_cast<uint8_t>(m_dramAddr);
    192 				}
    193 			}
    194 		}
    195 
    196 		if(changed && m_changeCallback)
    197 			m_changeCallback();
    198 
    199 		if(cgRamChanged && m_cgRamChangeCallback)
    200 			m_cgRamChangeCallback();
    201 
    202 		return result;
    203 	}
    204 
    205 	bool LCD::getCgData(std::array<uint8_t, 8>& _data, uint32_t _charIndex) const
    206 	{
    207 		const auto idx = _charIndex * 8;
    208 		if(idx + 8 >= getCgRam().size())
    209 			return false;
    210 
    211 		uint32_t j = 0;
    212 
    213 		for(auto i = idx; i<idx+8; ++i)
    214 			_data[j++] = getCgRam()[i];
    215 
    216 		return true;
    217 	}
    218 }