summaryrefslogblamecommitdiffstatshomepage
path: root/src/devices/video/sed1200.cpp
blob: 371832f579a8ad6bcad306b682127e2f6e02f1f2 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13

                                     










                                                                            




                                                                            



                                                                                   










                                                                                                              

                                                                                                                                                                                                                 
 

 
                                                                                                                       
                                                              


 
                                                                                                                       
                                                              


 
                                                                                                                       
                                                              


 
                                                                                                                       
                                                              


 
                                                                  



                                    
                                                                  



                                    
                                                                  



                                    
                                                                  










                                                   
                                














                                 
                                            







































                                                                                
                                   



                    
                                         



















                                                               
                                       





                                    
                                     















                                                                                   
// license:BSD-3-Clause
// copyright-holders:Olivier Galibert
/***************************************************************************

    SED1200

    A LCD controller.

    The D/F variants have a packaging difference (QFP80 vs. bare chip).

    The A/B variants have an internal CGROM difference (jis
    vs. european characters)

***************************************************************************/

#include "emu.h"
#include "sed1200.h"

DEFINE_DEVICE_TYPE(SED1200D0A, sed1200d0a_device, "sed1200da", "Epson SED1200D-0A")
DEFINE_DEVICE_TYPE(SED1200F0A, sed1200f0a_device, "sed1200fa", "Epson SED1200F-0A")
DEFINE_DEVICE_TYPE(SED1200D0B, sed1200d0b_device, "sed1200db", "Epson SED1200D-0B")
DEFINE_DEVICE_TYPE(SED1200F0B, sed1200f0b_device, "sed1200fb", "Epson SED1200F-0B")

ROM_START( sed1200x0a )
	ROM_REGION( 0x800, "cgrom", 0 )
	ROM_LOAD( "sed1200-a.bin", 0x000, 0x800, CRC(e8c28054) SHA1(086406eb74e9ed97b309d2a4bdedc567626e9a98))
ROM_END

ROM_START( sed1200x0b )
	ROM_REGION( 0x800, "cgrom", 0 )
	ROM_LOAD( "sed1200-b.bin", 0x000, 0x800, CRC(d0741f51) SHA1(c8c856f1357286a2c8c806af81724a828345357e))
ROM_END

sed1200_device::sed1200_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
	device_t(mconfig, type, tag, owner, clock), cursor_direction(false), cursor_blinking(false), cursor_full(false), cursor_on(false), display_on(false), cursor_address(0), cgram_address(0), cgrom(nullptr)
{
}

sed1200d0a_device::sed1200d0a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
	sed1200_device(mconfig, SED1200D0A, tag, owner, clock)
{
}

sed1200f0a_device::sed1200f0a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
	sed1200_device(mconfig, SED1200F0A, tag, owner, clock)
{
}

sed1200d0b_device::sed1200d0b_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
	sed1200_device(mconfig, SED1200D0B, tag, owner, clock)
{
}

sed1200f0b_device::sed1200f0b_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
	sed1200_device(mconfig, SED1200F0B, tag, owner, clock)
{
}

const tiny_rom_entry *sed1200d0a_device::device_rom_region() const
{
	return ROM_NAME(sed1200x0a);
}

const tiny_rom_entry *sed1200f0a_device::device_rom_region() const
{
	return ROM_NAME(sed1200x0a);
}

const tiny_rom_entry *sed1200d0b_device::device_rom_region() const
{
	return ROM_NAME(sed1200x0b);
}

const tiny_rom_entry *sed1200f0b_device::device_rom_region() const
{
	return ROM_NAME(sed1200x0b);
}

void sed1200_device::device_start()
{
	memset(cgram, 0, sizeof(cgram));
	memset(ddram, 0, sizeof(ddram));
	if(memregion("cgrom"))
		cgrom = memregion("cgrom")->base();
	else
		cgrom = nullptr;

	soft_reset();
}

void sed1200_device::soft_reset()
{
	cursor_direction = false;
	cursor_blinking = false;
	cursor_full = false;
	cursor_on = false;
	display_on = false;
	cursor_address = 0x00;
	cgram_address = 0x00;
}

void sed1200_device::control_w(uint8_t data)
{
	switch(data) {
	case 0x04: case 0x05:
		cursor_direction = data & 0x01;
		break;
	case 0x06: case 0x07:
		cursor_step();
		break;
	case 0x08: case 0x09:
		cursor_full = data & 0x01;
		break;
	case 0x0a: case 0x0b:
		cursor_blinking = data & 0x01;
		break;
	case 0x0c: case 0x0d:
		display_on = data & 0x01;
		break;
	case 0x0e: case 0x0f:
		cursor_on = data & 0x01;
		break;
	case 0x10:
		soft_reset();
		break;
	case 0x12: case 0x13:
		break; // Number of lines selection
	default:
		if((data & 0xf0) == 0x20)
			cgram_address = (data & 3)*8;
		else if((data & 0xe0) == 0x40) {
			cgram[cgram_address++] = data;
			if(cgram_address == 4*8)
				cgram_address = 0;
		} else if(data & 0x80) {
			cursor_address = data & 0x40 ? 10 : 0;
			cursor_address += (data & 0x3f) >= 10 ? 9 : data & 0x3f;
		}
		break;
	}
}

uint8_t sed1200_device::control_r()
{
	return 0x00;
}

void sed1200_device::data_w(uint8_t data)
{
	ddram[cursor_address] = data;
	cursor_step();
}

void sed1200_device::cursor_step()
{
	if(cursor_direction) {
		if(cursor_address == 0 || cursor_address == 10)
			cursor_address += 9;
		else
			cursor_address --;
	} else {
		if(cursor_address == 9 || cursor_address == 19)
			cursor_address -= 9;
		else
			cursor_address ++;
	}
}

const uint8_t *sed1200_device::render()
{
	memset(render_buf, 0, 20*8);
	if(!display_on)
		return render_buf;

	for(int i=0; i<20; i++) {
		uint8_t c = ddram[i];
		if(c < 4)
			memcpy(render_buf + 8*i, cgram + 8*c, 8);
		else if(cgrom)
			memcpy(render_buf + 8*i, cgrom + 8*c, 8);
	}

	if(cursor_on && (!cursor_blinking || (machine().time().as_ticks(2) & 1))) {
		if(cursor_full)
			for(int i=0; i<8; i++)
				render_buf[cursor_address*8+i] ^= 0x1f;
		else
			render_buf[cursor_address*8+7] ^= 0x1f;
	}

	return render_buf;
}