summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/video/saa5240.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/video/saa5240.cpp')
-rw-r--r--src/devices/video/saa5240.cpp385
1 files changed, 217 insertions, 168 deletions
diff --git a/src/devices/video/saa5240.cpp b/src/devices/video/saa5240.cpp
index 318ccc48d27..52b653b0709 100644
--- a/src/devices/video/saa5240.cpp
+++ b/src/devices/video/saa5240.cpp
@@ -2,17 +2,23 @@
// copyright-holders:Nigel Barnes
/*********************************************************************
- Philips SAA5240 European Controlled Teletext Circuit
+ Philips SAA5240 European Controlled Teletext Circuit (CCT)
+
+ TODO:
+ - implement data acquisition.
+ - output interlaced video.
*********************************************************************/
#include "emu.h"
#include "saa5240.h"
+#include "screen.h"
+
#define LOG_DATA (1U << 1)
#define LOG_LINE (1U << 2)
-#define VERBOSE (LOG_DATA)
+#define VERBOSE (0)
#include "logmacro.h"
@@ -23,43 +29,21 @@ DEFINE_DEVICE_TYPE(SAA5243E, saa5243e_device, "saa5243e", "SAA5243E EURO CCT")
//-------------------------------------------------
-// default address map
-//-------------------------------------------------
-
-void saa5240_device::saa5240_vram(address_map &map)
-{
- if (!has_configured_map(0))
- map(0x0000, 0x1fff).ram();
-}
-
-//-------------------------------------------------
-// memory_space_config - return a description of
-// any address spaces owned by this device
-//-------------------------------------------------
-
-device_memory_interface::space_config_vector saa5240_device::memory_space_config() const
-{
- return space_config_vector {
- std::make_pair(0, &m_space_config)
- };
-}
-
-//-------------------------------------------------
// ROM( saa5240 )
//-------------------------------------------------
-ROM_START( saa5240a )
- ROM_REGION16_BE( 0xc80, "chargen", ROMREGION_ERASE00 )
+ROM_START(saa5240a)
+ ROM_REGION16_BE(0xc80, "chargen", ROMREGION_ERASE00)
ROM_LOAD("saa5240a", 0x0280, 0x0a00, BAD_DUMP CRC(e205d1fc) SHA1(cb6872260c91f0665f8c7d691c9becc327e0ecc3)) // hand made from datasheet
ROM_END
-ROM_START( saa5240b )
- ROM_REGION16_BE( 0xc80, "chargen", ROMREGION_ERASE00 )
+ROM_START(saa5240b)
+ ROM_REGION16_BE(0xc80, "chargen", ROMREGION_ERASE00)
ROM_LOAD("saa5240b", 0x0280, 0x0a00, BAD_DUMP CRC(7b196f2c) SHA1(61d4460ed0956ff470cc1362ea6bb1f9abe4bc03)) // hand made from datasheet
ROM_END
-ROM_START( saa5243e )
- ROM_REGION16_BE( 0x1180, "chargen", ROMREGION_ERASE00 )
+ROM_START(saa5243e)
+ ROM_REGION16_BE(0x1180, "chargen", ROMREGION_ERASE00)
ROM_LOAD("saa5243e", 0x0280, 0x0f00, BAD_DUMP CRC(a74402e7) SHA1(48123c9bb0377e417a147f5a68088c1ed7bee12d)) // hand made from datasheet
ROM_END
@@ -70,26 +54,20 @@ ROM_END
const tiny_rom_entry *saa5240a_device::device_rom_region() const
{
- return ROM_NAME( saa5240a );
+ return ROM_NAME(saa5240a);
}
const tiny_rom_entry *saa5240b_device::device_rom_region() const
{
- return ROM_NAME( saa5240b );
+ return ROM_NAME(saa5240b);
}
const tiny_rom_entry *saa5243e_device::device_rom_region() const
{
- return ROM_NAME( saa5243e );
+ return ROM_NAME(saa5243e);
}
-
-#define ALPHANUMERIC 0x01
-#define CONTIGUOUS 0x02
-#define SEPARATED 0x03
-
-
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
@@ -100,9 +78,8 @@ const tiny_rom_entry *saa5243e_device::device_rom_region() const
saa5240_device::saa5240_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, type, tag, owner, clock)
- , device_memory_interface(mconfig, *this)
, m_char_rom(*this, "chargen")
- , m_space_config("videoram", ENDIANNESS_LITTLE, 8, 13, 0, address_map_constructor(FUNC(saa5240a_device::saa5240_vram), this))
+ , m_ram_size(0x2000)
, m_slave_address(SAA5240_SLAVE_ADDRESS)
, m_i2c_scl(0)
, m_i2c_sdaw(0)
@@ -115,18 +92,18 @@ saa5240_device::saa5240_device(const machine_config &mconfig, device_type type,
{
}
-saa5240a_device::saa5240a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
- saa5240_device(mconfig, SAA5240A, tag, owner, clock)
+saa5240a_device::saa5240a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : saa5240_device(mconfig, SAA5240A, tag, owner, clock)
{
}
-saa5240b_device::saa5240b_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
- saa5240_device(mconfig, SAA5240B, tag, owner, clock)
+saa5240b_device::saa5240b_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : saa5240_device(mconfig, SAA5240B, tag, owner, clock)
{
}
-saa5243e_device::saa5243e_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
- saa5240_device(mconfig, SAA5243E, tag, owner, clock)
+saa5243e_device::saa5243e_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : saa5240_device(mconfig, SAA5243E, tag, owner, clock)
{
}
@@ -137,9 +114,21 @@ saa5243e_device::saa5243e_device(const machine_config &mconfig, const char *tag,
void saa5240_device::device_start()
{
- m_videoram = &space(0);
+ m_ram = make_unique_clear<uint8_t[]>(m_ram_size);
+
+ // memory is cleared to 'space' on power-up
+ std::memset(m_ram.get(), 0x20, m_ram_size);
+
+ // row 0 column 7 chapter 0 is alpha white
+ m_ram[0x07] = 0x07;
+
+ // registers cleared on power-up, except R5 and R6
+ std::fill(std::begin(m_register), std::end(m_register), 0x00);
+ m_register[5] = 0x03;
+ m_register[6] = 0x03;
// state saving
+ save_pointer(NAME(m_ram), m_ram_size);
save_item(NAME(m_i2c_scl));
save_item(NAME(m_i2c_sdaw));
save_item(NAME(m_i2c_sdar));
@@ -152,21 +141,6 @@ void saa5240_device::device_start()
save_item(NAME(m_slave_address));
}
-void saa5240_device::device_reset()
-{
- // memmory is cleared to 'space' on power-up
- for (int i = 0; i < 0x1fff; i++)
- m_videoram->write_byte(i, 0x20);
-
- // row 0 column 7 chapter 0 is alpha white
- m_videoram->write_byte(7, 0x07);
-
- // reset registers
- std::fill(std::begin(m_register), std::end(m_register), 0x00);
- m_register[5] = 0x03;
- m_register[6] = 0x03;
-}
-
//**************************************************************************
// READ/WRITE HANDLERS
@@ -196,78 +170,86 @@ void saa5240_device::write_scl(int state)
{
if (m_i2c_scl)
{
- switch (m_i2c_state)
+ m_i2c_bits++;
+ }
+ else
+ {
+ if (m_i2c_bits == 8)
{
- case STATE_DEVSEL:
- m_i2c_devsel = m_i2c_shift;
-
- if ((m_i2c_devsel & 0xfe) != m_slave_address)
- {
- LOGMASKED(LOG_DATA, "devsel %02x: not this device\n", m_i2c_devsel);
- m_i2c_state = STATE_IDLE;
- }
- else if ((m_i2c_devsel & 1) == 0)
- {
- LOGMASKED(LOG_DATA, "devsel %02x: write\n", m_i2c_devsel);
- m_i2c_state = STATE_ADDRESS;
- }
- else
- {
- LOGMASKED(LOG_DATA, "devsel %02x: read\n", m_i2c_devsel);
- m_i2c_state = STATE_DATAOUT;
- }
- break;
-
- case STATE_ADDRESS:
- m_i2c_address = m_i2c_shift;
- LOGMASKED(LOG_DATA, "address %02x\n", m_i2c_shift);
-
- m_i2c_state = STATE_DATAIN;
- break;
-
- case STATE_DATAIN:
- m_register[m_i2c_address] = m_i2c_shift;
- LOGMASKED(LOG_DATA, "data[ %02x ] <- %02x\n", m_i2c_address, m_i2c_shift);
-
- switch (m_i2c_address)
+ switch (m_i2c_state)
{
- case 1: case 2: case 3: case 4: case 5: case 6:
- // auto-increment register
- m_i2c_address++;
+ case STATE_DEVSEL:
+ m_i2c_devsel = m_i2c_shift;
+
+ if ((m_i2c_devsel & 0xfe) != m_slave_address)
+ {
+ LOGMASKED(LOG_DATA, "devsel %02x: not this device\n", m_i2c_devsel);
+ m_i2c_state = STATE_IDLE;
+ }
+ else if ((m_i2c_devsel & 1) == 0)
+ {
+ LOGMASKED(LOG_DATA, "devsel %02x: write\n", m_i2c_devsel);
+ m_i2c_state = STATE_ADDRESS;
+ }
+ else
+ {
+ LOGMASKED(LOG_DATA, "devsel %02x: read\n", m_i2c_devsel);
+ m_i2c_state = STATE_READSELACK;
+ }
break;
- case 8:
- // active chapter - clear memory
- //if (BIT(m_register[8], 3))
- //{
- // for (int i = 0; i < 0x3ff; i++)
- // m_videoram->write_byte((m_register[8] & 0x07) * 0x400 + i, 0x20);
- //}
- [[fallthrough]];
- case 9: case 10:
- update_active_data();
-
- // auto-increment register
- m_i2c_address++;
+ case STATE_ADDRESS:
+ m_i2c_address = m_i2c_shift;
+ LOGMASKED(LOG_DATA, "address %02x\n", m_i2c_shift);
+
+ m_i2c_state = STATE_DATAIN;
break;
- case 11:
- // active data
- offs_t offset = (m_register[8] & 0x07) * 0x400 + (m_register[9] & 0x1f) * 40 + (m_register[10] & 0x3f);
- m_videoram->write_byte(offset, m_i2c_shift);
- increment_active_data();
+ case STATE_DATAIN:
+ m_register[m_i2c_address] = m_i2c_shift;
+ LOGMASKED(LOG_DATA, "data[ %02x ] <- %02x\n", m_i2c_address, m_i2c_shift);
+
+ switch (m_i2c_address)
+ {
+ case 1: // Mode
+ case 2: // Page request address
+ case 3: // Page request data
+ case 4: // Display chapter
+ case 5: // Display control (normal)
+ case 6: // Display control (newsflash/subtitle)
+ m_i2c_address++; // auto-increment register
+ break;
+
+ case 7: // Display mode
+ break;
+
+ case 8: // Active chapter
+ if (BIT(m_register[8], 3))
+ {
+ // clear memory
+ for (int i = 0; i < 0x400; i++)
+ m_ram[ram_addr(m_register[8], 0, 0) + i] = 0x20;
+ }
+ [[fallthrough]];
+
+ case 9: // Active row
+ case 10: // Active column
+ update_active_data();
+ m_i2c_address++; // auto-increment register
+ break;
+
+ case 11: // Active data
+ m_ram[ram_addr(m_register[8], m_register[9], m_register[10])] = m_i2c_shift;
+ increment_active_data();
+ break;
+ }
break;
}
- break;
- }
- m_i2c_bits++;
- }
- else
- {
- if (m_i2c_bits == 8)
- {
- m_i2c_sdar = 0;
+ if (m_i2c_state != STATE_IDLE)
+ {
+ m_i2c_sdar = 0;
+ }
}
else
{
@@ -278,11 +260,20 @@ void saa5240_device::write_scl(int state)
}
break;
+ case STATE_READSELACK:
+ m_i2c_bits = 0;
+ m_i2c_state = STATE_DATAOUT;
+ break;
+
case STATE_DATAOUT:
if (m_i2c_bits < 8)
{
if (m_i2c_scl)
{
+ m_i2c_bits++;
+ }
+ else
+ {
if (m_i2c_bits == 0)
{
m_i2c_shift = m_register[m_i2c_address];
@@ -291,8 +282,7 @@ void saa5240_device::write_scl(int state)
if (m_i2c_address == 11)
increment_active_data();
- // FIXME: is this conditional?
- if (BIT(m_register[1], 6))
+ if (!BIT(m_register[1], 6))
{
// 7 bits with parity checking
m_i2c_shift &= 0x7f;
@@ -303,7 +293,6 @@ void saa5240_device::write_scl(int state)
m_i2c_sdar = (m_i2c_shift >> 7) & 1;
m_i2c_shift = (m_i2c_shift << 1) & 0xff;
- m_i2c_bits++;
}
}
else
@@ -316,18 +305,12 @@ void saa5240_device::write_scl(int state)
m_i2c_state = STATE_IDLE;
}
- m_i2c_bits++;
+ m_i2c_bits = 0;
}
else
{
- if (m_i2c_bits == 8)
- {
- m_i2c_sdar = 1;
- }
- else
- {
- m_i2c_bits = 0;
- }
+
+ m_i2c_sdar = 1;
}
}
break;
@@ -372,6 +355,12 @@ int saa5240_device::read_sda()
}
+uint16_t saa5240_device::ram_addr(int chapter, int row, int column)
+{
+ uint16_t addr = (chapter & 0x07) * 0x400 + (row & 0x1f) * 40 + (column & 0x3f);
+ return addr & (m_ram_size - 1);
+}
+
void saa5240_device::increment_active_data()
{
// auto-increment column
@@ -388,8 +377,7 @@ void saa5240_device::increment_active_data()
void saa5240_device::update_active_data()
{
- offs_t offset = (m_register[8] & 0x07) * 0x400 + (m_register[9] & 0x1f) * 40 + (m_register[10] & 0x3f);
- m_register[11] = m_videoram->read_byte(offset);
+ m_register[11] = m_ram[ram_addr(m_register[8], m_register[9], m_register[10])];
}
//-------------------------------------------------
@@ -400,17 +388,16 @@ int saa5240_device::calc_parity(uint8_t data)
{
uint8_t count = 0;
- while(data != 0)
+ while (data != 0)
{
count++;
- data &= (data-1);
+ data &= (data - 1);
}
return (count ^ 1) & 1;
}
-
//-------------------------------------------------
// process_control_character
//-------------------------------------------------
@@ -565,16 +552,83 @@ uint16_t saa5240_device::get_gfx_data(uint8_t data, offs_t row, bool separated)
uint16_t saa5240_device::get_rom_data(uint8_t data, offs_t row)
{
- uint16_t c;
- if (row < 0 || row >= 10)
+ static const uint8_t nc_char_matrix[6][128] =
{
- c = 0;
- }
+ // SAA5240A - German / SAA5240B - Italian / SAA5243E - German
+ {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f
+ },
+ // SAA5240A - English / SAA5240B - German / SAA5243E - English
+ {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0x83, 0x84, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0x80, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+ 0x81, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x88, 0x89, 0x8a, 0x7f
+ },
+ // SAA5240A - Swedish / SAA5240B - French / SAA5243E - Swedish
+ {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0x93, 0x94, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0x90, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+ 0x91, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x92, 0x98, 0x99, 0x9a, 0x7f
+ },
+ // SAA5243E - Italian
+ {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0xa3, 0xa4, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0xa0, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ 0xa1, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0xa2, 0xa8, 0xa9, 0xaa, 0x7f
+ },
+ // SAA5243E - Spanish
+ {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0xb3, 0xb4, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0xb0, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xb1, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0xb2, 0xb8, 0xb9, 0xba, 0x7f
+ },
+ // SAA5243E - Swedish
+ {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0xc3, 0xc4, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0xc0, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xc1, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0xc2, 0xc8, 0xc9, 0xca, 0x7f
+ }
+ };
+
+ // decode national option characters
+ if (!BIT(data, 7))
+ data = nc_char_matrix[1][data]; // TODO: select character set from page header control bits
else
- {
- c = m_char_rom[(data * 10) + row];
- }
- return c;
+ data &= 0x7f;
+
+ return m_char_rom[(data * 10) + row];
}
@@ -628,7 +682,7 @@ void saa5240_device::get_character_data(uint8_t data)
m_held_char = 32;
}
- if (m_curr_chartype == ALPHANUMERIC || !BIT(data,5))
+ if (m_curr_chartype == ALPHANUMERIC || !BIT(data, 5))
m_char_data = get_rom_data(data, ra);
else
m_char_data = get_gfx_data(data, ra, (m_curr_chartype == SEPARATED));
@@ -643,9 +697,6 @@ void saa5240_device::vcs_w(int state)
{
if (state)
{
- m_ra++;
- m_ra %= 10;
-
if (!m_ra)
{
if (m_double_height_bottom_row)
@@ -706,33 +757,31 @@ int saa5240_device::get_rgb()
uint32_t saa5240_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
- for (int y = 0; y < 25 * 10; y++)
+ for (int y = cliprect.min_y; y <= cliprect.max_y; y++)
{
int sy = y / 10;
- int x = 0;
+ int x = screen.visible_area().left();
+
+ m_ra = y % 10;
vcs_w(1);
vcs_w(0);
for (int sx = 0; sx < 40; sx++)
{
- uint8_t code = m_videoram->read_byte((sy * 40) + sx) & 0x7f;
- get_character_data(code);
+ // get display data
+ get_character_data(m_ram[ram_addr(m_register[4], sy, sx)]);
for (int bit = 0; bit < 12; bit++)
{
f6_w(1);
f6_w(0);
- int color = get_rgb();
-
- if (BIT(code, 7)) color ^= 0x07;
-
- int r = BIT(color, 0) * 0xff;
- int g = BIT(color, 1) * 0xff;
- int b = BIT(color, 2) * 0xff;
-
- bitmap.pix(y, x++) = rgb_t(r, g, b);
+ // cursor on at active row/column
+ if (BIT(m_register[7], 6) && (sy == m_register[9]) && (sx == m_register[10]))
+ bitmap.pix(y, x++) = rgb_t::white();
+ else
+ bitmap.pix(y, x++) = rgb_t(pal1bit(BIT(get_rgb(), 0)), pal1bit(BIT(get_rgb(), 1)), pal1bit(BIT(get_rgb(), 2)));
}
}
}