mirror of
https://github.com/mamedev/mame.git
synced 2024-09-28 03:20:58 +02:00
bt47x: add bt479 device
This commit is contained in:
parent
b458bf71c9
commit
2bfe504eef
2 changed files with 203 additions and 24 deletions
|
@ -10,18 +10,19 @@
|
|||
* Bt476 80Mhz 8 bit 3 6 bit
|
||||
* Bt477 80MHz 8 bit 4 bit 3 8 bit sleep mode, compatibility mode
|
||||
* Bt478 80MHz 8 bit 4 bit 3 8 bit
|
||||
* Bt479 80MHz 8 bit 4 bit 3 8 bit 1024 palette entries, 16 windows, compatibility mode
|
||||
*
|
||||
* Not emulated:
|
||||
*
|
||||
* Bt473 80MHz 24 bit 4 bit 3 8 bit true color/passthrough/bypass modes
|
||||
* Bt474 85MHz 4x8 bit 4x4 bit 3 8 bit sleep mode, vga mode
|
||||
* Bt479 80MHz 8 bit 4 bit 3 8 bit 16 windows, compatibility mode
|
||||
*
|
||||
* Sources:
|
||||
* - http://www.bitsavers.org/components/brooktree/_dataBooks/1991_Brooktree_Product_Databook.pdf
|
||||
* - Brooktree Product Databook 1991
|
||||
*
|
||||
* TODO:
|
||||
* - remaining devices
|
||||
* - bt479 window mode, overlay mask, 10-bit modes
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
|
@ -40,7 +41,7 @@ DEFINE_DEVICE_TYPE(BT475, bt475_device, "bt475", "Brooktree Bt475 256 Color RAMD
|
|||
DEFINE_DEVICE_TYPE(BT476, bt476_device, "bt476", "Brooktree Bt476 256 Color RAMDAC")
|
||||
DEFINE_DEVICE_TYPE(BT477, bt477_device, "bt477", "Brooktree Bt477 256 Color RAMDAC")
|
||||
DEFINE_DEVICE_TYPE(BT478, bt478_device, "bt478", "Brooktree Bt478 256 Color RAMDAC")
|
||||
//DEFINE_DEVICE_TYPE(BT479, bt479_device, "bt479", "Brooktree Bt479 1024 Color RAMDAC")
|
||||
DEFINE_DEVICE_TYPE(BT479, bt479_device, "bt479", "Brooktree Bt479 1024 Color RAMDAC")
|
||||
|
||||
void bt47x_device_base::map(address_map &map)
|
||||
{
|
||||
|
@ -57,6 +58,37 @@ void bt47x_device_base::map(address_map &map)
|
|||
}
|
||||
}
|
||||
|
||||
u8 bt47x_device_base::read(offs_t offset)
|
||||
{
|
||||
u8 data = 0;
|
||||
switch (offset)
|
||||
{
|
||||
case 0: data = address_r(); break;
|
||||
case 1: data = palette_r(); break;
|
||||
case 2: data = mask_r(); break;
|
||||
case 3: data = address_r(); break;
|
||||
case 4: if (m_overlay_colors) data = address_r(); break;
|
||||
case 5: if (m_overlay_colors) data = overlay_r(); break;
|
||||
case 7: if (m_overlay_colors) data = address_r(); break;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void bt47x_device_base::write(offs_t offset, u8 data)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 0: address_w(data); break;
|
||||
case 1: palette_w(data); break;
|
||||
case 2: mask_w(data); break;
|
||||
case 3: address_w(data); break;
|
||||
case 4: if (m_overlay_colors) address_w(data); break;
|
||||
case 5: if (m_overlay_colors) overlay_w(data); break;
|
||||
case 7: if (m_overlay_colors) address_w(data); break;
|
||||
}
|
||||
}
|
||||
|
||||
void bt475_device_base::map(address_map &map)
|
||||
{
|
||||
bt47x_device_base::map(map);
|
||||
|
@ -64,6 +96,45 @@ void bt475_device_base::map(address_map &map)
|
|||
map(0x06, 0x06).rw(FUNC(bt475_device_base::command_r), FUNC(bt475_device_base::command_w));
|
||||
}
|
||||
|
||||
u8 bt475_device_base::read(offs_t offset)
|
||||
{
|
||||
if (offset == 6)
|
||||
return command_r();
|
||||
else
|
||||
return bt47x_device_base::read(offset);
|
||||
}
|
||||
|
||||
void bt475_device_base::write(offs_t offset, u8 data)
|
||||
{
|
||||
if (offset == 6)
|
||||
command_w(data);
|
||||
else
|
||||
bt47x_device_base::write(offset, data);
|
||||
}
|
||||
|
||||
void bt479_device::map(address_map &map)
|
||||
{
|
||||
bt47x_device_base::map(map);
|
||||
|
||||
map(0x06, 0x06).rw(FUNC(bt479_device::control_r), FUNC(bt479_device::control_w));
|
||||
}
|
||||
|
||||
u8 bt479_device::read(offs_t offset)
|
||||
{
|
||||
if (offset == 6)
|
||||
return control_r();
|
||||
else
|
||||
return bt47x_device_base::read(offset);
|
||||
}
|
||||
|
||||
void bt479_device::write(offs_t offset, u8 data)
|
||||
{
|
||||
if (offset == 6)
|
||||
control_w(data);
|
||||
else
|
||||
bt47x_device_base::write(offset, data);
|
||||
}
|
||||
|
||||
bt47x_device_base::bt47x_device_base(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock, unsigned const palette_colors, unsigned const overlay_colors, unsigned const color_bits)
|
||||
: device_t(mconfig, type, tag, owner, clock)
|
||||
, device_palette_interface(mconfig, *this)
|
||||
|
@ -103,6 +174,11 @@ bt478_device::bt478_device(machine_config const &mconfig, char const *tag, devic
|
|||
{
|
||||
}
|
||||
|
||||
bt479_device::bt479_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
|
||||
: bt47x_device_base(mconfig, BT479, tag, owner, clock, 1024, 16, 8)
|
||||
{
|
||||
}
|
||||
|
||||
void bt47x_device_base::device_start()
|
||||
{
|
||||
save_item(NAME(m_address));
|
||||
|
@ -121,6 +197,18 @@ void bt475_device_base::device_start()
|
|||
save_item(NAME(m_command));
|
||||
}
|
||||
|
||||
void bt479_device::device_start()
|
||||
{
|
||||
bt47x_device_base::device_start();
|
||||
|
||||
save_item(NAME(m_window));
|
||||
save_item(NAME(m_command));
|
||||
save_item(NAME(m_flood));
|
||||
|
||||
m_command[0] = 0;
|
||||
m_command[1] = 0;
|
||||
}
|
||||
|
||||
u8 bt47x_device_base::address_r()
|
||||
{
|
||||
LOGMASKED(LOG_READS, "address_r 0x%02x\n", m_address);
|
||||
|
@ -139,22 +227,27 @@ void bt47x_device_base::address_w(u8 data)
|
|||
m_address = data;
|
||||
}
|
||||
|
||||
void bt47x_device_base::increment_address(bool const side_effects)
|
||||
void bt47x_device_base::increment_address(bool const rgb, bool const side_effects)
|
||||
{
|
||||
if (!machine().side_effects_disabled() || side_effects)
|
||||
{
|
||||
// increment component index and address register
|
||||
m_address_rgb = (m_address_rgb + 1) % 3;
|
||||
if (m_address_rgb == 0)
|
||||
if (rgb)
|
||||
{
|
||||
// increment component index and address register
|
||||
m_address_rgb = (m_address_rgb + 1) % 3;
|
||||
if (m_address_rgb == 0)
|
||||
m_address++;
|
||||
}
|
||||
else
|
||||
m_address++;
|
||||
}
|
||||
}
|
||||
|
||||
u8 bt47x_device_base::palette_r()
|
||||
{
|
||||
u8 const data = m_color_ram[m_address][m_address_rgb];
|
||||
u8 const data = m_color_ram[address()][m_address_rgb];
|
||||
|
||||
increment_address();
|
||||
increment_address(true);
|
||||
|
||||
LOGMASKED(LOG_READS, "palette_r 0x%02x\n", data);
|
||||
|
||||
|
@ -165,16 +258,16 @@ void bt47x_device_base::palette_w(u8 data)
|
|||
{
|
||||
LOG("palette_w 0x%02x\n", data);
|
||||
|
||||
m_color_ram[m_address][m_address_rgb] = data;
|
||||
m_color_ram[address()][m_address_rgb] = data;
|
||||
|
||||
// update the mame palette to match the device
|
||||
if (m_address_rgb == 2)
|
||||
set_pen_color(m_address, rgb_t(
|
||||
m_color_ram[m_address][0] << (8 - color_bits()),
|
||||
m_color_ram[m_address][1] << (8 - color_bits()),
|
||||
m_color_ram[m_address][2] << (8 - color_bits())));
|
||||
set_pen_color(address(), rgb_t(
|
||||
m_color_ram[address()][0] << (8 - color_bits()),
|
||||
m_color_ram[address()][1] << (8 - color_bits()),
|
||||
m_color_ram[address()][2] << (8 - color_bits())));
|
||||
|
||||
increment_address(true);
|
||||
increment_address(true, true);
|
||||
}
|
||||
|
||||
u8 bt47x_device_base::mask_r()
|
||||
|
@ -196,7 +289,7 @@ u8 bt47x_device_base::overlay_r()
|
|||
unsigned const index = m_palette_colors + (m_address & (m_overlay_colors - 1));
|
||||
u8 const data = m_color_ram[index][m_address_rgb];
|
||||
|
||||
increment_address();
|
||||
increment_address(true);
|
||||
|
||||
LOGMASKED(LOG_READS, "overlay_r 0x%02x\n", data);
|
||||
|
||||
|
@ -217,7 +310,7 @@ void bt47x_device_base::overlay_w(u8 data)
|
|||
m_color_ram[index][1] << (8 - color_bits()),
|
||||
m_color_ram[index][2] << (8 - color_bits())));
|
||||
|
||||
increment_address(true);
|
||||
increment_address(true, true);
|
||||
}
|
||||
|
||||
u8 bt475_device_base::command_r()
|
||||
|
@ -233,3 +326,61 @@ void bt475_device_base::command_w(u8 data)
|
|||
|
||||
m_command = data;
|
||||
}
|
||||
|
||||
enum bt479_command_0_mask : u8
|
||||
{
|
||||
BT479_CR0_OL = 0x0f, // overlay read mask
|
||||
BT479_CR0_CP = 0xf0, // color palette select
|
||||
};
|
||||
|
||||
u8 bt479_device::control_r()
|
||||
{
|
||||
unsigned const address = bt47x_device_base::address();
|
||||
u8 data = 0;
|
||||
|
||||
switch (address)
|
||||
{
|
||||
case 0x82:
|
||||
case 0x83:
|
||||
data = m_command[address & 1];
|
||||
break;
|
||||
case 0x84:
|
||||
case 0x85:
|
||||
data = m_flood[address & 1];
|
||||
break;
|
||||
default:
|
||||
if (address < 0x80)
|
||||
data = m_window[address];
|
||||
break;
|
||||
}
|
||||
|
||||
LOGMASKED(LOG_READS, "control_r 0x%02x\n", data);
|
||||
increment_address(false);
|
||||
return data;
|
||||
}
|
||||
|
||||
void bt479_device::control_w(u8 data)
|
||||
{
|
||||
unsigned const address = bt47x_device_base::address();
|
||||
LOG("control_w address 0x%02x data 0x%02x\n", address, data);
|
||||
|
||||
switch (address)
|
||||
{
|
||||
case 0x82:
|
||||
case 0x83:
|
||||
LOG("control_w command%d 0x%02x\n", address & 1, data);
|
||||
m_command[address & 1] = data;
|
||||
break;
|
||||
case 0x84:
|
||||
case 0x85:
|
||||
LOG("control_w flood%d 0x%02x\n", address & 1, data);
|
||||
m_flood[address & 1] = data;
|
||||
break;
|
||||
default:
|
||||
if (address < 0x80)
|
||||
m_window[address] = data;
|
||||
break;
|
||||
}
|
||||
|
||||
increment_address(false, true);
|
||||
}
|
||||
|
|
|
@ -15,14 +15,16 @@ public:
|
|||
rgb_t overlay_lookup(u8 index) const { return pen_color(m_palette_colors + index); }
|
||||
|
||||
virtual void map(address_map &map);
|
||||
virtual u8 read(offs_t offset);
|
||||
virtual void write(offs_t offset, u8 data);
|
||||
|
||||
protected:
|
||||
bt47x_device_base(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock, unsigned const palette_colors, unsigned const overlay_colors, unsigned const color_bits);
|
||||
|
||||
// device_t overrides
|
||||
// device_t implementation
|
||||
virtual void device_start() override;
|
||||
|
||||
// device_palette_interface overrides
|
||||
// device_palette_interface implementation
|
||||
virtual u32 palette_entries() const noexcept override { return m_palette_colors + m_overlay_colors; }
|
||||
|
||||
// read/write handlers
|
||||
|
@ -35,12 +37,12 @@ protected:
|
|||
u8 overlay_r();
|
||||
void overlay_w(u8 data);
|
||||
|
||||
// helpers
|
||||
virtual unsigned address() const { return m_address; };
|
||||
void increment_address(bool const rgb, bool const side_effects = false);
|
||||
virtual unsigned color_bits() const { return m_color_bits; }
|
||||
|
||||
private:
|
||||
// helpers
|
||||
void increment_address(bool const side_effects = false);
|
||||
|
||||
// device state
|
||||
u8 m_address;
|
||||
u8 m_address_rgb;
|
||||
|
@ -58,11 +60,13 @@ class bt475_device_base : public bt47x_device_base
|
|||
{
|
||||
public:
|
||||
virtual void map(address_map &map) override;
|
||||
virtual u8 read(offs_t offset) override;
|
||||
virtual void write(offs_t offset, u8 data) override;
|
||||
|
||||
protected:
|
||||
bt475_device_base(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock, unsigned const palette_colors, unsigned const overlay_colors, unsigned const color_bits);
|
||||
|
||||
// device_t overrides
|
||||
// device_t implementation
|
||||
virtual void device_start() override;
|
||||
|
||||
u8 command_r();
|
||||
|
@ -115,6 +119,30 @@ public:
|
|||
bt478_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
|
||||
};
|
||||
|
||||
class bt479_device : public bt47x_device_base
|
||||
{
|
||||
public:
|
||||
bt479_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
|
||||
|
||||
virtual void map(address_map &map) override;
|
||||
virtual u8 read(offs_t offset) override;
|
||||
virtual void write(offs_t offset, u8 data) override;
|
||||
|
||||
protected:
|
||||
virtual void device_start() override;
|
||||
|
||||
virtual unsigned address() const override { return BIT(m_command[0], 4, 2) * 0x100 + bt47x_device_base::address(); };
|
||||
virtual unsigned color_bits() const override { return BIT(m_command[1], 1) ? 8 : 6; }
|
||||
|
||||
u8 control_r();
|
||||
void control_w(u8 data);
|
||||
|
||||
private:
|
||||
u8 m_window[0x80];
|
||||
u8 m_command[2];
|
||||
u8 m_flood[2];
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(BT471, bt471_device)
|
||||
//DECLARE_DEVICE_TYPE(BT473, bt473_device)
|
||||
//DECLARE_DEVICE_TYPE(BT474, bt474_device)
|
||||
|
@ -122,6 +150,6 @@ DECLARE_DEVICE_TYPE(BT475, bt475_device)
|
|||
DECLARE_DEVICE_TYPE(BT476, bt476_device)
|
||||
DECLARE_DEVICE_TYPE(BT477, bt477_device)
|
||||
DECLARE_DEVICE_TYPE(BT478, bt478_device)
|
||||
//DECLARE_DEVICE_TYPE(BT479, bt479_device)
|
||||
DECLARE_DEVICE_TYPE(BT479, bt479_device)
|
||||
|
||||
#endif // MAME_VIDEO_BT47X_H
|
||||
|
|
Loading…
Reference in a new issue