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" @@ -22,44 +28,22 @@ DEFINE_DEVICE_TYPE(SAA5243E, saa5243e_device, "saa5243e", "SAA5243E EURO CCT") //DEFINE_DEVICE_TYPE(SAA5243H, saa5243h_device, "saa5243h", "SAA5243H 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(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) - { - 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) - { - case 1: case 2: case 3: case 4: case 5: case 6: - // auto-increment register - m_i2c_address++; - 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++; - 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(); - break; - } - break; - } - m_i2c_bits++; } else { if (m_i2c_bits == 8) { - m_i2c_sdar = 0; + switch (m_i2c_state) + { + 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 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) + { + 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; + } + + if (m_i2c_state != STATE_IDLE) + { + m_i2c_sdar = 0; + } } else { @@ -278,10 +260,19 @@ 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) { @@ -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))); } } } diff --git a/src/devices/video/saa5240.h b/src/devices/video/saa5240.h index 575d3a38238..12b3421fb3b 100644 --- a/src/devices/video/saa5240.h +++ b/src/devices/video/saa5240.h @@ -38,28 +38,20 @@ #pragma once - -//************************************************************************** -// CONSTANTS -//************************************************************************** - -#define SAA5240_SLAVE_ADDRESS ( 0x22 ) - - //************************************************************************** // TYPE DEFINITIONS //************************************************************************** // ======================> saa5240_device -class saa5240_device : - public device_t, - public device_memory_interface +class saa5240_device : public device_t { public: // construction/destruction saa5240_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + void set_ram_size(uint16_t ram_size) { m_ram_size = ram_size; } + void write_scl(int state); void write_sda(int state); int read_sda(); @@ -73,18 +65,16 @@ public: protected: saa5240_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); - // device-level overrides + // device_t overrides virtual void device_start() override ATTR_COLD; - virtual void device_reset() override ATTR_COLD; - - // optional information overrides - virtual space_config_vector memory_space_config() const override; private: + static constexpr uint8_t SAA5240_SLAVE_ADDRESS = 0x22; + required_region_ptr m_char_rom; - const address_space_config m_space_config; - address_space *m_videoram; + std::unique_ptr m_ram; + uint16_t m_ram_size; // internal state uint8_t m_register[12]; @@ -98,12 +88,11 @@ private: int m_i2c_devsel; int m_i2c_address; + uint16_t ram_addr(int chapter, int row, int column); void increment_active_data(); void update_active_data(); - enum { STATE_IDLE, STATE_DEVSEL, STATE_ADDRESS, STATE_DATAIN, STATE_DATAOUT }; - - void saa5240_vram(address_map &map) ATTR_COLD; + enum { STATE_IDLE, STATE_DEVSEL, STATE_ADDRESS, STATE_DATAIN, STATE_DATAOUT, STATE_READSELACK }; enum { @@ -147,6 +136,10 @@ private: uint16_t get_rom_data(uint8_t data, offs_t row); void get_character_data(uint8_t data); + static constexpr uint8_t ALPHANUMERIC = 0x01; + static constexpr uint8_t CONTIGUOUS = 0x02; + static constexpr uint8_t SEPARATED = 0x03; + uint8_t m_held_char; uint8_t m_next_chartype; uint8_t m_curr_chartype; diff --git a/src/mame/acorn/accomm.cpp b/src/mame/acorn/accomm.cpp index 57d7f23a90e..4e27236e43b 100644 --- a/src/mame/acorn/accomm.cpp +++ b/src/mame/acorn/accomm.cpp @@ -25,22 +25,22 @@ #include "emu.h" +#include "bus/centronics/ctronics.h" +#include "bus/econet/econet.h" +#include "bus/rs232/rs232.h" #include "cpu/g65816/g65816.h" #include "machine/6522via.h" #include "machine/6850acia.h" #include "machine/clock.h" #include "machine/input_merger.h" #include "machine/mc6854.h" -#include "machine/ram.h" #include "machine/nvram.h" #include "machine/pcf8573.h" +#include "machine/ram.h" #include "machine/scn_pci.h" #include "sound/beep.h" #include "sound/pcd3311.h" #include "video/saa5240.h" -#include "bus/econet/econet.h" -#include "bus/centronics/ctronics.h" -#include "bus/rs232/rs232.h" #include "emupal.h" #include "screen.h" @@ -110,6 +110,8 @@ private: void ram_w(offs_t offset, uint8_t data); uint8_t sheila_r(offs_t offset); void sheila_w(offs_t offset, uint8_t data); + uint8_t via_pb_r(); + void via_pb_w(uint8_t data); void accomm_palette(palette_device &palette) const; @@ -509,32 +511,31 @@ uint8_t accomm_state::ram_r(offs_t offset) } else { - switch (m_ram->size()) - { - case 512 * 1024: - data = m_ram->pointer()[offset & 0x7ffff]; - break; - - case 1024 * 1024: - data = m_ram->pointer()[offset & 0xfffff]; - break; - } + data = m_ram->pointer()[offset & m_ram->mask()]; } return data; } void accomm_state::ram_w(offs_t offset, uint8_t data) { - switch (m_ram->size()) - { - case 512 * 1024: - m_ram->pointer()[offset & 0x7ffff] = data; - break; + m_ram->pointer()[offset & m_ram->mask()] = data; +} - case 1024 * 1024: - m_ram->pointer()[offset & 0xfffff] = data; - break; - } + +uint8_t accomm_state::via_pb_r() +{ + return 0xfe | (m_rtc->sda_r() & m_cct->read_sda()); +} + +void accomm_state::via_pb_w(uint8_t data) +{ + data ^= 0xff; + + m_rtc->sda_w(BIT(data, 1)); + m_rtc->scl_w(BIT(data, 2)); + + m_cct->write_sda(BIT(data, 1)); + m_cct->write_scl(BIT(data, 2)); } @@ -710,11 +711,6 @@ void accomm_state::main_map(address_map &map) map(0xff0000, 0xffffff).rom().region("maincpu", 0x010000); /* ROM bank 1 (ROM Slot 0) */ } -void accomm_state::saa5240_map(address_map &map) -{ - map.global_mask(0x07ff); - map(0x0000, 0x07ff).ram(); -} INPUT_CHANGED_MEMBER(accomm_state::trigger_reset) { @@ -926,17 +922,14 @@ void accomm_state::accomm(machine_config &config) /* teletext */ SAA5240A(config, m_cct, 6_MHz_XTAL); - m_cct->set_addrmap(0, &accomm_state::saa5240_map); + m_cct->set_ram_size(0x800); /* via */ MOS6522(config, m_via, 16_MHz_XTAL / 16); m_via->writepa_handler().set("cent_data_out", FUNC(output_latch_device::write)); m_via->ca2_handler().set("centronics", FUNC(centronics_device::write_strobe)); - m_via->readpb_handler().set([this] () { return uint8_t(m_rtc->sda_r() & m_cct->read_sda()); }); - m_via->writepb_handler().set(m_rtc, FUNC(pcf8573_device::sda_w)).bit(1).invert(); - m_via->writepb_handler().append(m_rtc, FUNC(pcf8573_device::scl_w)).bit(2).invert(); - m_via->writepb_handler().append(m_cct, FUNC(saa5240a_device::write_sda)).bit(1).invert(); - m_via->writepb_handler().append(m_cct, FUNC(saa5240a_device::write_scl)).bit(2).invert(); + m_via->readpb_handler().set(FUNC(accomm_state::via_pb_r)); + m_via->writepb_handler().set(FUNC(accomm_state::via_pb_w)); m_via->irq_handler().set(m_irqs, FUNC(input_merger_device::in_w<0>)); /* rs423 */ @@ -977,7 +970,7 @@ void accomm_state::accomm(machine_config &config) econet.clk_wr_callback().append(m_adlc, FUNC(mc6854_device::rxc_w)); econet.data_wr_callback().set(m_adlc, FUNC(mc6854_device::set_rx)); - ECONET_SLOT(config, "econet254", "econet", econet_devices).set_slot(254); + ECONET_SLOT(config, "econet254", "econet", econet_devices); /* printer */ centronics_device ¢ronics(CENTRONICS(config, "centronics", centronics_devices, "printer")); @@ -993,7 +986,7 @@ void accomm_state::accommi(machine_config &config) /* teletext */ SAA5240B(config.replace(), m_cct, 6_MHz_XTAL); - m_cct->set_addrmap(0, &accomm_state::saa5240_map); + m_cct->set_ram_size(0x800); } diff --git a/src/mame/skeleton/datacast.cpp b/src/mame/skeleton/datacast.cpp index 4ed73a09884..4906c9c8876 100644 --- a/src/mame/skeleton/datacast.cpp +++ b/src/mame/skeleton/datacast.cpp @@ -32,7 +32,7 @@ ------------------ 22 SAA5240 A2 PCF8582 - C0 ? + C0 SAB3036 TODO: - implement keypad @@ -84,7 +84,6 @@ private: void i2c_w(uint8_t data); void mem_map(address_map &map) ATTR_COLD; - void saa5240_map(address_map &map) ATTR_COLD; required_device m_maincpu; required_device m_screen; @@ -109,7 +108,7 @@ void datacast_state::mem_map(address_map &map) map(0x00000, 0x7ffff).ram(); map(0xc0000, 0xc0000).rw(FUNC(datacast_state::keypad_r), FUNC(datacast_state::keypad_w)).umask16(0x00ff); map(0xc0080, 0xc0080).lr8([]() { return 0xff; }, "dips"); // unknown purpose - map(0xc0100, 0xc010f).noprw(); //.rw(m_saa5250, FUNC(saa5250_device::read), FUNC(saa5250_device::write)).umask16(0x00ff); + map(0xc0100, 0xc010f).noprw(); //.rw(m_cidac, FUNC(saa5250_device::read), FUNC(saa5250_device::write)).umask16(0x00ff); map(0xc0180, 0xc0180).rw(FUNC(datacast_state::i2c_r), FUNC(datacast_state::i2c_w)).umask16(0x00ff); map(0xc0200, 0xc0203).rw(m_usart[0], FUNC(i8251_device::read), FUNC(i8251_device::write)).umask16(0x00ff); map(0xc0280, 0xc0280).w(m_dbrg, FUNC(com8116_device::stt_str_w)); @@ -117,12 +116,6 @@ void datacast_state::mem_map(address_map &map) map(0xf0000, 0xfffff).rom().region("rom", 0); } -void datacast_state::saa5240_map(address_map &map) -{ - map.global_mask(0x07ff); - map(0x0000, 0x07ff).ram(); -} - static INPUT_PORTS_START(datacast) PORT_START("X1") @@ -158,7 +151,7 @@ INPUT_PORTS_END uint8_t datacast_state::keypad_r() { uint8_t data = (m_kb->read() << 0) | (m_kb->da_r() << 5); - logerror("keypad_r: %02x\n", data); + logerror("%s keypad_r: %02x\n", machine().describe_context(), data); return data; } @@ -166,13 +159,13 @@ void datacast_state::keypad_w(uint8_t data) { m_key_col = data; - logerror("keypad_w: %02x\n", data); + logerror("%s keypad_w: %02x\n", machine().describe_context(), data); } uint8_t datacast_state::i2c_r() { - return m_i2cmem->read_sda() & m_cct->read_sda(); + return m_i2cmem->read_sda() & m_cct->read_sda(); } void datacast_state::i2c_w(uint8_t data) @@ -203,10 +196,10 @@ void datacast_state::datacast(machine_config &config) //SAA5231(config, m_saa5231, 13.875_MHz_XTAL); SAA5240A(config, m_cct, 6_MHz_XTAL); - m_cct->set_addrmap(0, &datacast_state::saa5240_map); + m_cct->set_ram_size(0x800); - //SAA5250(config, m_saa5250, 0); - //m_saa5250->set_addrmap(0, &datacast_state::saa5250_map); // 2K RAM + //SAA5250(config, m_cidac, 0); + //m_cidac->set_buffer_size(0x800); I2C_PCF8582(config, m_i2cmem).set_e0(1);