summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/machine/esqlcd.cpp
blob: a9348a5bde289340decaeacdc87592fe2391571d (plain) (tree)
1
2
3
4
5
6
7
8
9
10





                                                          
                


                      

                     
 
                                                                                                     

                                                                                                                                              



                                                                               







                                                    



                                                                               
                                           































































































































                                                                                      

                                                                                                                                              
 

                                                                   
                                                   
 
 
                                                                                                                                              
                                             





                                                                       




                               


                                                                          
                                





                                              
                                                                                                                                        
                                               
                                          
                               


                                                                                        
                                                                                                                                        
                                                 
                                          
                               


                                                                                           
                                                                                                                                        
                                                 
                                          
                               




                                             
                                                        
                            





                                                                     
                         
                                                                                                                                                 


                            
                                                               

                                                 
                                          
                               

                        
                                                                                                                                         
                                          
                               
         
 

                                             
                                                                                                                        
                                                             
                                                  



                                 
 



                                                


                                                              
                                                                     
                                                            
                                       





                                                                                     
                                                            
                                       




                                                                          
                                                            
                                       





                                                               
                                                                                                                               
                                                  
                                       

                                  
                                                                                                                               

                                            
                                  
                                                                                                                               

                                             

                                
                                                                                                                               
                                                  
                                       

                 

            
                                                                                                      
         

                                                                                                                                              
                                                                                                                         
                                                                                              

                                             
 

                                                                                                                                              
                                         
 



                                                  
                                                                 



                                                                                         




                                                                                                                                              






                                                                                                                                              
                                       

                      
                                                                 
                                         
                                                                                                                         

                                                                                                                                              
                                    
 
                                                                 
                                         


                                                                                                                                              
                                     

                                           
                                     

                                                                                                                                              
                                                                      






                                                                                   
// license:BSD-3-Clause
// copyright-holders:Parduz
/*
    Ensoniq LCD dotmatrix Displays
    derived by Parduz from the VFD Emulation by R. Belmont
*/
#include "emu.h"
#include "esqlcd.h"
#include "esq2by16.lh"

//#define VERBOSE 1
#include "logmacro.h"

DEFINE_DEVICE_TYPE(ESQ2X16_SQ1, esq2x16_sq1_device, "esq2x16_sq1", "Ensoniq 2x16 VFD (SQ-1 variant)")

// --- SQ1 - Parduz --------------------------------------------------------------------------------------------------------------------------

/*! \file font5x7.h \brief Graphic LCD Font (Ascii Characters). */
//*****************************************************************************
//
// File Name    : 'font5x7.h'
// Title        : Graphic LCD Font (Ascii Charaters)
// Author       : Pascal Stang
// Date         : 10/19/2001
// Revised      : 10/19/2001
// Version      : 0.1
// Target MCU   : Atmel AVR
// Editor Tabs  : 4
//
//*****************************************************************************
// standard ascii 5x7 font
// defines ascii characters 0x20-0x7F (32-127)
static unsigned char const Font5x7[][5] = {
	{0x00, 0x00, 0x08, 0x00, 0x00}, // _Undef_      0x00 - dots for debug purposes
	{0x01, 0x00, 0x00, 0x00, 0x40}, // _Undef_      0x01 - dots for debug purposes
	{0x02, 0x00, 0x00, 0x00, 0x00}, // _Undef_      0x02
	{0x03, 0x00, 0x00, 0x00, 0x00}, // _Undef_      0x03
	{0x04, 0x00, 0x00, 0x00, 0x00}, // _Undef_      0x04
	{0x05, 0x00, 0x00, 0x00, 0x00}, // _Undef_      0x05
	{0x06, 0x00, 0x00, 0x00, 0x00}, // _Undef_      0x06
	{0x07, 0x00, 0x00, 0x00, 0x00}, // _Undef_      0x07
	{0x20, 0x70, 0x3F, 0x00, 0x00}, // Croma        0x08
	{0x20, 0x70, 0x3F, 0x02, 0x0C}, // Croma        0x09
	{0x20, 0x70, 0x3F, 0x05, 0x0A}, // Croma        0x0A
	{0x20, 0x70, 0x3F, 0x15, 0x2A}, // Croma        0x0B
	{0x20, 0x50, 0x50, 0x3F, 0x00}, // Croma        0x0C
	{0x0D, 0x00, 0x00, 0x00, 0x00}, // _Undef_      0x0D
	{0x0E, 0x00, 0x00, 0x00, 0x00}, // _Undef_      0x0E
	{0x0F, 0x00, 0x00, 0x00, 0x00}, // _Undef_      0x0F
	{0x10, 0x00, 0x00, 0x00, 0x00}, // _Undef_      0x10
	{0x11, 0x00, 0x00, 0x00, 0x00}, // _Undef_      0x11
	{0x12, 0x00, 0x00, 0x00, 0x00}, // _Undef_      0x12
	{0x13, 0x00, 0x00, 0x00, 0x00}, // _Undef_      0x13
	{0x14, 0x00, 0x00, 0x00, 0x00}, // _Undef_      0x14
	{0x15, 0x00, 0x00, 0x00, 0x00}, // _Undef_      0x15
	{0x16, 0x00, 0x00, 0x00, 0x00}, // _Undef_      0x16
	{0x17, 0x00, 0x00, 0x00, 0x00}, // _Undef_      0x17
	{0x18, 0x00, 0x00, 0x00, 0x00}, // _Undef_      0x18
	{0x19, 0x00, 0x00, 0x00, 0x00}, // _Undef_      0x19
	{0x1A, 0x00, 0x00, 0x00, 0x00}, // _Undef_      0x1A
	{0x1B, 0x00, 0x00, 0x00, 0x00}, // _Undef_      0x1B
	{0x1C, 0x00, 0x00, 0x00, 0x00}, // _Undef_      0x1C
	{0x1D, 0x00, 0x00, 0x00, 0x00}, // _Undef_      0x1D
	{0x1E, 0x00, 0x00, 0x00, 0x00}, // _Undef_      0x1E
	{0x1F, 0x00, 0x00, 0x00, 0x00}, // _Undef_      0x1F
	{0x00, 0x00, 0x00, 0x00, 0x00}, // (space)      0x20
	{0x00, 0x00, 0x5F, 0x00, 0x00}, // !            0x21
	{0x00, 0x07, 0x00, 0x07, 0x00}, // "            0x22
	{0x14, 0x7F, 0x14, 0x7F, 0x14}, // #            0x23
	{0x24, 0x2A, 0x7F, 0x2A, 0x12}, // $            0x24
	{0x23, 0x13, 0x08, 0x64, 0x62}, // %            0x25
	{0x36, 0x49, 0x55, 0x22, 0x50}, // &            0x26
	{0x00, 0x05, 0x03, 0x00, 0x00}, // '            0x27
	{0x00, 0x1C, 0x22, 0x41, 0x00}, // (            0x28
	{0x00, 0x41, 0x22, 0x1C, 0x00}, // )            0x29
	{0x08, 0x2A, 0x1C, 0x2A, 0x08}, // *            0x2A
	{0x08, 0x08, 0x3E, 0x08, 0x08}, // +            0x2B
	{0x00, 0x50, 0x30, 0x00, 0x00}, // ,            0x2C
	{0x08, 0x08, 0x08, 0x08, 0x08}, // -            0x2D
	{0x00, 0x60, 0x60, 0x00, 0x00}, // .            0x2E
	{0x20, 0x10, 0x08, 0x04, 0x02}, // /            0x2F
	{0x3E, 0x51, 0x49, 0x45, 0x3E}, // 0            0x30
	{0x00, 0x42, 0x7F, 0x40, 0x00}, // 1            0x31
	{0x42, 0x61, 0x51, 0x49, 0x46}, // 2            0x32
	{0x21, 0x41, 0x45, 0x4B, 0x31}, // 3            0x33
	{0x18, 0x14, 0x12, 0x7F, 0x10}, // 4            0x34
	{0x27, 0x45, 0x45, 0x45, 0x39}, // 5            0x35
	{0x3C, 0x4A, 0x49, 0x49, 0x30}, // 6            0x36
	{0x01, 0x71, 0x09, 0x05, 0x03}, // 7            0x37
	{0x36, 0x49, 0x49, 0x49, 0x36}, // 8            0x38
	{0x06, 0x49, 0x49, 0x29, 0x1E}, // 9            0x39
	{0x00, 0x36, 0x36, 0x00, 0x00}, // :            0x3A
	{0x00, 0x56, 0x36, 0x00, 0x00}, // ;            0x3B
	{0x00, 0x08, 0x14, 0x22, 0x41}, // <            0x3C
	{0x14, 0x14, 0x14, 0x14, 0x14}, // =            0x3D
	{0x41, 0x22, 0x14, 0x08, 0x00}, // >            0x3E
	{0x02, 0x01, 0x51, 0x09, 0x06}, // ?            0x3F
	{0x32, 0x49, 0x79, 0x41, 0x3E}, // @            0x40
	{0x7E, 0x11, 0x11, 0x11, 0x7E}, // A            0x41
	{0x7F, 0x49, 0x49, 0x49, 0x36}, // B            0x42
	{0x3E, 0x41, 0x41, 0x41, 0x22}, // C            0x43
	{0x7F, 0x41, 0x41, 0x22, 0x1C}, // D            0x44
	{0x7F, 0x49, 0x49, 0x49, 0x41}, // E            0x45
	{0x7F, 0x09, 0x09, 0x01, 0x01}, // F            0x46
	{0x3E, 0x41, 0x41, 0x51, 0x32}, // G            0x47
	{0x7F, 0x08, 0x08, 0x08, 0x7F}, // H            0x48
	{0x00, 0x41, 0x7F, 0x41, 0x00}, // I            0x49
	{0x20, 0x40, 0x41, 0x3F, 0x01}, // J            0x4A
	{0x7F, 0x08, 0x14, 0x22, 0x41}, // K            0x4B
	{0x7F, 0x40, 0x40, 0x40, 0x40}, // L            0x4C
	{0x7F, 0x02, 0x04, 0x02, 0x7F}, // M            0x4D
	{0x7F, 0x04, 0x08, 0x10, 0x7F}, // N            0x4E
	{0x3E, 0x41, 0x41, 0x41, 0x3E}, // O            0x4F
	{0x7F, 0x09, 0x09, 0x09, 0x06}, // P            0x50
	{0x3E, 0x41, 0x51, 0x21, 0x5E}, // Q            0x51
	{0x7F, 0x09, 0x19, 0x29, 0x46}, // R            0x52
	{0x46, 0x49, 0x49, 0x49, 0x31}, // S            0x53
	{0x01, 0x01, 0x7F, 0x01, 0x01}, // T            0x54
	{0x3F, 0x40, 0x40, 0x40, 0x3F}, // U            0x55
	{0x1F, 0x20, 0x40, 0x20, 0x1F}, // V            0x56
	{0x7F, 0x20, 0x18, 0x20, 0x7F}, // W            0x57
	{0x63, 0x14, 0x08, 0x14, 0x63}, // X            0x58
	{0x03, 0x04, 0x78, 0x04, 0x03}, // Y            0x59
	{0x61, 0x51, 0x49, 0x45, 0x43}, // Z            0x5A
	{0x00, 0x00, 0x7F, 0x41, 0x41}, // [            0x5B
	{0x02, 0x04, 0x08, 0x10, 0x20}, // \            0x5C
	{0x41, 0x41, 0x7F, 0x00, 0x00}, // ]            0x5D
	{0x04, 0x02, 0x01, 0x02, 0x04}, // ^            0x5E
	{0x40, 0x40, 0x40, 0x40, 0x40}, // _            0x5F
	{0x00, 0x01, 0x02, 0x04, 0x00}, // `            0x60
	{0x20, 0x54, 0x54, 0x54, 0x78}, // a            0x61
	{0x7F, 0x48, 0x44, 0x44, 0x38}, // b            0x62
	{0x38, 0x44, 0x44, 0x44, 0x20}, // c            0x63
	{0x38, 0x44, 0x44, 0x48, 0x7F}, // d            0x64
	{0x38, 0x54, 0x54, 0x54, 0x18}, // e            0x65
	{0x08, 0x7E, 0x09, 0x01, 0x02}, // f            0x66
	{0x08, 0x14, 0x54, 0x54, 0x3C}, // g            0x67
	{0x7F, 0x08, 0x04, 0x04, 0x78}, // h            0x68
	{0x00, 0x44, 0x7D, 0x40, 0x00}, // i            0x69
	{0x20, 0x40, 0x44, 0x3D, 0x00}, // j            0x6A
	{0x00, 0x7F, 0x10, 0x28, 0x44}, // k            0x6B
	{0x00, 0x41, 0x7F, 0x40, 0x00}, // l            0x6C
	{0x7C, 0x04, 0x18, 0x04, 0x78}, // m            0x6D
	{0x7C, 0x08, 0x04, 0x04, 0x78}, // n            0x6E
	{0x38, 0x44, 0x44, 0x44, 0x38}, // o            0x6F
	{0x7C, 0x14, 0x14, 0x14, 0x08}, // p            0x70
	{0x08, 0x14, 0x14, 0x18, 0x7C}, // q            0x71
	{0x7C, 0x08, 0x04, 0x04, 0x08}, // r            0x72
	{0x48, 0x54, 0x54, 0x54, 0x20}, // s            0x73
	{0x04, 0x3F, 0x44, 0x40, 0x20}, // t            0x74
	{0x3C, 0x40, 0x40, 0x20, 0x7C}, // u            0x75
	{0x1C, 0x20, 0x40, 0x20, 0x1C}, // v            0x76
	{0x3C, 0x40, 0x30, 0x40, 0x3C}, // w            0x77
	{0x44, 0x28, 0x10, 0x28, 0x44}, // x            0x78
	{0x0C, 0x50, 0x50, 0x50, 0x3C}, // y            0x79
	{0x44, 0x64, 0x54, 0x4C, 0x44}, // z            0x7A
	{0x00, 0x08, 0x36, 0x41, 0x00}, // {            0x7B
	{0x00, 0x00, 0x7F, 0x00, 0x00}, // |            0x7C
	{0x00, 0x41, 0x36, 0x08, 0x00}, // }            0x7D
	{0x08, 0x08, 0x2A, 0x1C, 0x08}, // ->           0x7E
	{0x08, 0x1C, 0x2A, 0x08, 0x08}  // <-           0x7F
};
//--------------------------------------------------------------------------------------------------------------------------------------------

void esq2x16_sq1_device::device_add_mconfig(machine_config &config)
{
	config.set_default_layout(layout_esq2by16);
}

//--------------------------------------------------------------------------------------------------------------------------------------------
void esq2x16_sq1_device::write_char(int data)
{
	int DisplayCode = data;
	int LedState;

	// Non-ASCII codes that needs to be treated as ASCII characters
	if (
		data == 0x08 ||
		data == 0x09 ||
		data == 0x0A ||
		data == 0x0B ||
		data == 0x0C
	) data = '^';  // musical notes

	// Resolve here 2-Bytes commands: the command was saved previously
	switch (m_lcd_command) {
		case 0:
			// No current command.
			break;

		case 0x87:
			// Go To
			LOG("LCD %02X: Go To %02X                  - pos=%02X (%d)\n", m_lcd_command, DisplayCode, m_lcdPos, m_lcdPage);
			m_lcdPos = DisplayCode;
			m_lcd_command = 0;
			return;

		case 0x88:
			// Save Cursor position - What the second byte (00 or 01) means?
			LOG("LCD %02X: Save Pos.      (%02X)       - pos=%02X (%d)\n", m_lcd_command, DisplayCode, m_lcdPos, m_lcdPage);
			m_lcdSavedPos = m_lcdPos;
			m_lcd_command = 0;
			return;

		case 0x89:
			// Restore Cursor position - What the second byte (00 or 01) means?
			LOG("LCD %02X: Restore Pos.   (%02X)       - pos=%02X (%d)\n", m_lcd_command, DisplayCode, m_lcdPos, m_lcdPage);
			m_lcdPos = m_lcdSavedPos;
			m_lcd_command = 0;
			return;

		case 0x8D:
		case 0x8E:
		case 0x8F:
			// LED OFF, ON, BLINK
			LedState = m_lcd_command & 0x03;
			if (
				DisplayCode >= 16 || // Out of bounds
				DisplayCode == 6  || // non-existent
				DisplayCode == 7  || // non-existent
				DisplayCode == 14 || // non-existent
				DisplayCode == 15    // non-existent
				)
			{
				LOG("LCD %02X: Led %02d doesn't exist       - pos=%02X (%d)\n", m_lcd_command, DisplayCode, m_lcdPos, m_lcdPage);
			}
			else
			{
				m_leds[DisplayCode] = LedState;
				update_display();
			}
			m_lcd_command = 0;
			return;

		default:
			LOG("LCD: Unknown 2-Bytes Command:%02X-%02X - pos=%02X (%d)\n", m_lcd_command, DisplayCode, m_lcdPos, m_lcdPage);
			m_lcd_command = 0;
			return;
	}

	if ((data >= 0x20) && (data <= 0x7f))
	{
		LOG("LCD %02X:                     \"%c\"   - pos=%02X (%d)\n", DisplayCode, data, m_lcdPos, m_lcdPage);
		m_lcdpg[m_lcdPage][m_lcdPos++] = DisplayCode;
		if (m_lcdPos > 31)  m_lcdPos = 31;

		update_display();
		return;
	}

	if (DisplayCode >= 0x80)
	{
		switch (DisplayCode) {
			// Known 2-bytes command
			case 0x87:  // Go To
			case 0x88:  // Save Cursor Position
			case 0x89:  // Restore Cursor Position
				// Save the command for the next byte
				m_lcd_command = DisplayCode;
				return;

			// Unknown 2-bytes command
			case 0x85:
			case 0x86:
			case 0x95:
				// ??? - related to blinking chars? - 2 bytes command
				m_lcd_command = DisplayCode;
				return;

			case 0x8D:
			case 0x8E:
			case 0x8F:
				// LEDs OFF,ON and BLINK - 2 bytes command
				m_lcd_command = DisplayCode;
				return;

			// "Page" selectors (?)
			case 0x90: // Blink
			case 0x91: // ??
			case 0x92: // Normal
				m_lcdPage = DisplayCode & 0x03;
				LOG("LCD %02X: Page Change ?             - pos=%02X (%d)\n", DisplayCode, m_lcdPos, m_lcdPage);
				m_lcd_command = 0;
				return;

			case 0x8C:
				LOG("LCD %02X: Lcd Clear                 - pos=%02X (%d)\n", DisplayCode, m_lcdPos, m_lcdPage);
				lcd_reset();
				return;
			case 0x98:
				LOG("LCD %02X: Page Clear ?              - pos=%02X (%d)\n", DisplayCode, m_lcdPos, m_lcdPage);
				page_reset();
				return;

			default:
				LOG("LCD %02X: Unknown Command           - pos=%02X (%d)\n", DisplayCode, m_lcdPos, m_lcdPage);
				m_lcd_command = 0;
				return;
		}
	}
	else
	{
		LOG("LCD: Unknown LCD Code: %04X       - pos=%02X (%d)\n", data, m_lcdPos, m_lcdPage);
	}
}
//--------------------------------------------------------------------------------------------------------------------------------------------
esq2x16_sq1_device::esq2x16_sq1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
	esqvfd_device(mconfig, ESQ2X16_SQ1, tag, owner, clock, make_dimensions<2, 16>(*this)),
	m_lcdPix(*this, "pg_%u%03u", 1U, 0U),
	m_leds(*this, "rLed_%u", 0U)
{
}
//--------------------------------------------------------------------------------------------------------------------------------------------
void esq2x16_sq1_device::update_display()
{
	for (int page = 0; page < 4; page++)
	{
		for (int pos = 0; pos < 32; pos++)
		{
			// stealed from tecnbras.cpp and modified
			for (int rr = 0; rr < 7; rr++)
			{
				char lcdCharRow = rotate_lcd_char(m_lcdpg[page][pos],rr);
				m_lcdPix[page][pos*7 + rr] = 0x1f & lcdCharRow;
			}
		}
	}
}
//--------------------------------------------------------------------------------------------------------------------------------------------
void esq2x16_sq1_device::device_start()
{
	esqvfd_device::device_start();
	m_lcdPix.resolve();
	m_leds.resolve();
}
//--------------------------------------------------------------------------------------------------------------------------------------------
void esq2x16_sq1_device::device_reset()
{
	//lcd_reset();
	m_lcdPage = m_lcdSavedPos = m_lcdPos = m_lcd_command = 0;
	for (auto &led : m_leds) led = 0;
	memset(m_lcdpg,  1, sizeof(m_lcdpg));   // Set to 1 for debug: to see what "pages" are set to 0 from the firmware
}
//--------------------------------------------------------------------------------------------------------------------------------------------
void esq2x16_sq1_device::lcd_reset()
{
	m_lcdPage = m_lcdSavedPos = m_lcdPos = m_lcd_command = 0;
	for (auto &led : m_leds) led = 0;
	memset(m_lcdpg,  0, sizeof(m_lcdpg));
}
//--------------------------------------------------------------------------------------------------------------------------------------------
void esq2x16_sq1_device::page_reset()
{
	memset(m_lcdpg[m_lcdPage],  0, 32);
	m_lcdPos = m_lcd_command = 0;
}
//--------------------------------------------------------------------------------------------------------------------------------------------
char esq2x16_sq1_device::rotate_lcd_char(uint8_t lcdChar, int charRow)
{
	char lcdCharRow = 0;
	for (int cc=0; cc<5; cc++){
		lcdCharRow |= BIT(Font5x7[lcdChar][cc], charRow) ? (1 << (cc)) : 0;
	}
	return lcdCharRow;
}