Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 65 additions & 52 deletions src/devices/video/ef9345.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,6 @@
#include <algorithm>


#define MODE24x40 0
#define MODEVAR40 1
#define MODE8x80 2
#define MODE12x80 3
#define MODE16x40 4

//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
Expand Down Expand Up @@ -239,16 +233,7 @@ void ef9345_device::draw_char_80(uint8_t *c, uint16_t x, uint16_t y)
// set then ef9345 mode
void ef9345_device::set_video_mode(void)
{
if (m_variant == EF9345_MODE::TYPE_TS9347)
{
// Only TGS 7 & 6 used for the char mode with the TS9347
m_char_mode = ((m_tgs & 0xc0) >> 6);
}
else
{
// PAT 7, TGS 7 & 6
m_char_mode = ((m_pat & 0x80) >> 5) | ((m_tgs & 0xc0) >> 6);
}
m_char_mode = parse_video_mode();

uint16_t new_width = (m_char_mode == MODE12x80 || m_char_mode == MODE8x80) ? 492 : 336;

Expand All @@ -273,6 +258,27 @@ void ef9345_device::set_video_mode(void)
m_block = 0x0800 * ((((m_ror & 0xf0) >> 4) | ((m_ror & 0x40) >> 5) | ((m_ror & 0x20) >> 3)) & 0x0c);
}

ef9345_device::char_mode_t ef9345_device::parse_video_mode() const
{
uint8_t selector = (BIT(m_pat, 7) << 2) | bitswap<2>(m_tgs, 7, 6);
switch (selector)
{
default:
logerror("Unknown EF9345 mode: 0x%x\n", selector);
[[fallthrough]];
case 0b000:
return MODE24x40;
case 0b001:
return MODEVAR40;
case 0b100:
return MODE16x40;
case 0b011:
return MODE12x80;
case 0b010:
return MODE8x80;
}
}

// initialize the ef9345 accented chars
void ef9345_device::init_accented_chars(void)
{
Expand Down Expand Up @@ -382,25 +388,7 @@ void ef9345_device::zoom(uint8_t *pix, uint16_t n)
// calculate the address of the char x,y
uint16_t ef9345_device::indexblock(uint16_t x, uint16_t y)
{
uint16_t i = x, j;

if (m_variant == EF9345_MODE::TYPE_EF9345)
{
// On the EF9345 the service row is always displayed at the top, and
// it can be fetched from either Y=0 or Y=1.
j = (y == 0) ? ((m_tgs & 0x20) >> 5) : ((m_ror & 0x1f) + y - 1);
}
else
{
// On the TS9347 the service row is displayed either at the top or at
// the bottom, and it is always fetched from Y=0.
if (m_tgs & 1)
j = (y == 24) ? 0 : ((m_ror & 0x1f) + y);
else
j = (y == 0) ? 0 : ((m_ror & 0x1f) + y - 1);
}

j = (j > 31) ? (j - 24) : j;
uint16_t i = x, j = indexrow(y);

//right side of a double width character
if ((m_tgs & 0x80) == 0 && x > 0)
Expand All @@ -413,6 +401,16 @@ uint16_t ef9345_device::indexblock(uint16_t x, uint16_t y)
return 0x40 * j + i;
}

uint16_t ef9345_device::indexrow(uint16_t y)
{
uint16_t j;

// On the EF9345 the service row can be fetched from either Y=0 or Y=1.
j = (y == 0) ? BIT(m_tgs, 5) : ((m_ror & 0x1f) + y - 1);

return (j > 31) ? (j - 24) : j;
}

// applies the insert, flash, conceal and negative attributes,
// considering whether the cursor is on this character or not.
std::tuple<uint8_t, uint8_t, bool> ef9345_device::makecolors(uint8_t c0, uint8_t c1, bool insert, bool flash, bool conceal, bool negative, bool cursor)
Expand Down Expand Up @@ -775,30 +773,14 @@ void ef9345_device::makechar(uint16_t x, uint16_t y)
makechar_24x40(x, y);
break;
case MODEVAR40:
if (m_variant == EF9345_MODE::TYPE_TS9347)
{ // TS9347 char mode definition is different.
makechar_16x40(x, y);
break;
}
[[fallthrough]];
case MODE8x80:
logerror("Unemulated EF9345 mode: %02x\n", m_char_mode);
break;
case MODE12x80:
makechar_12x80(x, y);
break;
case MODE16x40:
if (m_variant == EF9345_MODE::TYPE_TS9347)
{
logerror("Unemulated EF9345 mode: %02x\n", m_char_mode);
}
else
{
makechar_16x40(x, y);
}
break;
default:
logerror("Unknown EF9345 mode: %02x\n", m_char_mode);
makechar_16x40(x, y);
break;
}
}
Expand Down Expand Up @@ -1178,3 +1160,34 @@ void ef9345_device::data_w(offs_t offset, uint8_t data)
if (offset & 8)
ef9345_exec(m_registers[0] & 0xff);
}

ef9345_device::char_mode_t ts9347_device::parse_video_mode() const
{
switch (bitswap<2>(m_tgs, 7, 6))
{
case 0b00:
return MODE24x40;
case 0b01:
return MODE16x40;
case 0b11:
return MODE12x80;
case 0b10:
return MODE8x80;
default: // unreachable
abort();
}
}

uint16_t ts9347_device::indexrow(uint16_t y)
{
uint16_t j;

// On the TS9347 the service row is displayed either at the top or at
// the bottom, and it is always fetched from Y=0.
if (m_tgs & 1)
j = (y == 24) ? 0 : ((m_ror & 0x1f) + y);
else
j = (y == 0) ? 0 : ((m_ror & 0x1f) + y - 1);

return (j > 31) ? (j - 24) : j;
}
27 changes: 24 additions & 3 deletions src/devices/video/ef9345.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,18 @@ class ef9345_device : public device_t,
void update_scanline(uint16_t scanline);
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);

protected:
enum char_mode_t : uint8_t {
// 40 column modes:
MODE24x40, // long codes
MODEVAR40, // variable codes
MODE16x40, // short codes

// 80 column modes:
MODE8x80, // long codes
MODE12x80, // variable codes
};

protected:
enum class EF9345_MODE {
TYPE_EF9345 = 0x001,
TYPE_TS9347 = 0x002
Expand All @@ -67,7 +77,6 @@ class ef9345_device : public device_t,
TIMER_CALLBACK_MEMBER(clear_busy_flag);
TIMER_CALLBACK_MEMBER(blink_tick);

private:
void set_busy_flag(int period);
void set_video_mode(void);
void init_accented_chars(void);
Expand All @@ -77,6 +86,12 @@ class ef9345_device : public device_t,
uint16_t indexblock(uint16_t x, uint16_t y);
std::tuple<uint8_t, uint8_t, bool> makecolors(uint8_t c0, uint8_t c1, bool insert, bool flash, bool conceal, bool negative, bool cursor);

virtual char_mode_t parse_video_mode() const;

// Computes the index of the memory row containing data for the y-th
// screen row.
virtual uint16_t indexrow(uint16_t y);

// Dispatch rendering of character (x, y) to one of the specialized
// drawing functions (bichrome40/quadrichrome40/bichrome80).
void makechar(uint16_t x, uint16_t y);
Expand Down Expand Up @@ -105,7 +120,7 @@ class ef9345_device : public device_t,
address_space *m_videoram;

uint8_t m_bf; //busy flag
uint8_t m_char_mode; //40 or 80 chars for line
char_mode_t m_char_mode; //40 or 80 chars for line
uint8_t m_acc_char[0x2000]; //accented chars
uint8_t m_registers[8]; //registers R0-R7
uint8_t m_state; //status register
Expand Down Expand Up @@ -135,8 +150,14 @@ class ts9347_device : public ef9345_device
{
public:
ts9347_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

protected:
virtual char_mode_t parse_video_mode() const override;
virtual uint16_t indexrow(uint16_t y) override;
};

ALLOW_SAVE_TYPE(ef9345_device::char_mode_t)

// device type definition
DECLARE_DEVICE_TYPE(EF9345, ef9345_device)
DECLARE_DEVICE_TYPE(TS9347, ts9347_device)
Expand Down
Loading