mirror of
https://github.com/holub/mame
synced 2025-04-21 07:52:35 +03:00
rc759: Major improvements to I82730, hook up SN76489A, preliminary palette
This commit is contained in:
parent
d26be5231a
commit
62fdcc28df
@ -13,14 +13,12 @@
|
||||
|
||||
#include "screen.h"
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// CONSTANTS
|
||||
//**************************************************************************
|
||||
|
||||
#define VERBOSE 1
|
||||
#define VERBOSE_COMMANDS 1
|
||||
#define VERBOSE_DATASTREAM 0
|
||||
#define LOG_GENERAL (1U << 0)
|
||||
#define LOG_COMMANDS (1U << 1)
|
||||
#define LOG_DATASTREAM (1U << 2)
|
||||
//#define VERBOSE (LOG_GENERAL | LOG_COMMANDS | LOG_DATASTREAM)
|
||||
#define VERBOSE (LOG_GENERAL)
|
||||
#include "logmacro.h"
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
@ -29,22 +27,6 @@
|
||||
|
||||
DEFINE_DEVICE_TYPE(I82730, i82730_device, "i82730", "Intel 82730")
|
||||
|
||||
const char *const i82730_device::s_command_names[] =
|
||||
{
|
||||
/* 00 */ "NOP",
|
||||
/* 01 */ "START DISPLAY",
|
||||
/* 02 */ "START VIRTUAL DISPLAY",
|
||||
/* 03 */ "STOP DISPLAY",
|
||||
/* 04 */ "MODE SET",
|
||||
/* 05 */ "LOAD CBP",
|
||||
/* 06 */ "LOAD INTMASK",
|
||||
/* 07 */ "LPEN ENABLE",
|
||||
/* 08 */ "READ STATUS",
|
||||
/* 09 */ "LD CUR POS",
|
||||
/* 0a */ "SELF TEST",
|
||||
/* 0b */ "TEST ROW BUFFER"
|
||||
};
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
@ -65,26 +47,20 @@ i82730_device::i82730_device(const machine_config &mconfig, const char *tag, dev
|
||||
m_initialized(false),
|
||||
m_mode_set(false),
|
||||
m_ca(0),
|
||||
m_ca_latch(false),
|
||||
m_sysbus(0x00),
|
||||
m_ibp(0x0000),
|
||||
m_cbp(0x0000),
|
||||
m_intmask(0xffff),
|
||||
m_status(0x0000),
|
||||
m_list_switch(0),
|
||||
m_auto_line_feed(0),
|
||||
m_list_switch(false),
|
||||
m_auto_line_feed(false),
|
||||
m_max_dma_count(0),
|
||||
m_lptr(0),
|
||||
m_status(0x0000),
|
||||
m_intmask(0xffff),
|
||||
m_sptr(0),
|
||||
m_dma_burst_space(0),
|
||||
m_dma_burst_length(0),
|
||||
m_hfldstrt(0),
|
||||
m_margin(0),
|
||||
m_lpr(0),
|
||||
m_field_attribute_mask(0),
|
||||
m_vsyncstp(0),
|
||||
m_vfldstrt(0),
|
||||
m_vfldstp(0),
|
||||
m_frame_int_count(0),
|
||||
m_row(nullptr),
|
||||
m_dma_count(0),
|
||||
m_row_count(0),
|
||||
m_row_index(0)
|
||||
{
|
||||
}
|
||||
@ -120,6 +96,7 @@ void i82730_device::device_reset()
|
||||
m_mode_set = false;
|
||||
|
||||
m_ca = 0;
|
||||
m_ca_latch = false;
|
||||
m_status = 0x0000;
|
||||
}
|
||||
|
||||
@ -188,66 +165,119 @@ void i82730_device::mode_set()
|
||||
uint16_t tmp;
|
||||
|
||||
tmp = read_word(mptr);
|
||||
m_dma_burst_space = tmp & 0x7f;
|
||||
m_dma_burst_length = (tmp >> 8) & 0x7f;
|
||||
m_mb.burst_length = (tmp >> 8) & 0x7f;
|
||||
m_mb.burst_space = tmp & 0x7f;
|
||||
|
||||
tmp = read_word(mptr + 2);
|
||||
uint8_t hsyncstp = tmp & 0xff;
|
||||
uint8_t line_length = (tmp >> 8) & 0xff;
|
||||
m_mb.line_length = (tmp >> 8) & 0xff;
|
||||
m_mb.hsyncstp = tmp & 0xff;
|
||||
|
||||
tmp = read_word(mptr + 4);
|
||||
uint8_t hfldstp = tmp & 0xff;
|
||||
m_hfldstrt = (tmp >> 8) & 0xff;
|
||||
m_mb.hfldstrt = (tmp >> 8) & 0xff;
|
||||
m_mb.hfldstp = tmp & 0xff;
|
||||
|
||||
tmp = read_word(mptr + 6);
|
||||
uint8_t hbrdstp = tmp & 0xff;
|
||||
uint8_t hbrdstrt = (tmp >> 8) & 0xff;
|
||||
m_mb.hbrdstrt = (tmp >> 8) & 0xff;
|
||||
m_mb.hbrdstp = tmp & 0xff;
|
||||
|
||||
tmp = read_word(mptr + 8);
|
||||
m_margin = tmp & 0x1f;
|
||||
m_mb.scroll_margin = tmp & 0x1f;
|
||||
|
||||
tmp = read_word(mptr + 10);
|
||||
m_lpr = tmp & 0x1f;
|
||||
m_mb.rvv_row = bool(BIT(tmp, 11));
|
||||
m_mb.blk_row = bool(BIT(tmp, 10));
|
||||
m_mb.dbl_hgt = bool(BIT(tmp, 9));
|
||||
m_mb.wdef = bool(BIT(tmp, 8));
|
||||
m_mb.lpr = tmp & 0x1f;
|
||||
|
||||
tmp = read_word(mptr + 12);
|
||||
m_mb.nrmstrt = (tmp >> 8) & 0x1f;
|
||||
m_mb.nrmstp = tmp & 0x1f;
|
||||
|
||||
tmp = read_word(mptr + 14);
|
||||
m_mb.supstrt = (tmp >> 8) & 0x1f;
|
||||
m_mb.supstp = tmp & 0x1f;
|
||||
|
||||
tmp = read_word(mptr + 16);
|
||||
m_mb.substrt = (tmp >> 8) & 0x1f;
|
||||
m_mb.substp = tmp & 0x1f;
|
||||
|
||||
tmp = read_word(mptr + 18);
|
||||
m_mb.cur1strt = (tmp >> 8) & 0x1f;
|
||||
m_mb.cur1stp = tmp & 0x1f;
|
||||
|
||||
tmp = read_word(mptr + 20);
|
||||
m_mb.cur2strt = (tmp >> 8) & 0x1f;
|
||||
m_mb.cur2stp = tmp & 0x1f;
|
||||
|
||||
tmp = read_word(mptr + 22);
|
||||
m_mb.u2_line_sel = (tmp >> 8) & 0x1f;
|
||||
m_mb.u1_line_sel = tmp & 0x1f;
|
||||
|
||||
tmp = read_word(mptr + 24);
|
||||
m_field_attribute_mask = tmp & 0x7fff;
|
||||
m_mb.field_attribute_mask = tmp & 0x7fff;
|
||||
|
||||
tmp = read_word(mptr + 26);
|
||||
uint16_t frame_length = tmp & 0x7ff;
|
||||
m_mb.frame_length = tmp & 0x7ff;
|
||||
|
||||
tmp = read_word(mptr + 28);
|
||||
m_vsyncstp = tmp & 0x7ff;
|
||||
m_mb.vsyncstp = tmp & 0x7ff;
|
||||
|
||||
tmp = read_word(mptr + 30);
|
||||
m_vfldstrt = tmp & 0x7ff;
|
||||
m_mb.vfldstrt = tmp & 0x7ff;
|
||||
|
||||
tmp = read_word(mptr + 32);
|
||||
m_vfldstp = tmp & 0x7ff;
|
||||
m_mb.vfldstp = tmp & 0x7ff;
|
||||
|
||||
tmp = read_word(mptr + 38);
|
||||
m_frame_int_count = tmp & 0x0f;
|
||||
m_mb.duty_cyc_cursor = (tmp >> 12) & 0x0f;
|
||||
m_mb.cursor_blink = (tmp >> 8) & 0x0f;
|
||||
m_mb.frame_int_count = tmp & 0x0f;
|
||||
|
||||
tmp = read_word(mptr + 40);
|
||||
m_mb.duty_cyc_char = (tmp >> 12) & 0x0f;
|
||||
m_mb.char_blink = (tmp >> 8) & 0x0f;
|
||||
m_mb.ile = bool(BIT(tmp, 7));
|
||||
m_mb.rfe = bool(BIT(tmp, 6));
|
||||
m_mb.bpol = bool(BIT(tmp, 5));
|
||||
m_mb.bue = bool(BIT(tmp, 4));
|
||||
m_mb.cr2_cd = bool(BIT(tmp, 3));
|
||||
m_mb.cr1_cd = bool(BIT(tmp, 2));
|
||||
m_mb.cr2_be = bool(BIT(tmp, 1));
|
||||
m_mb.cr1_be = bool(BIT(tmp, 0));
|
||||
|
||||
tmp = read_word(mptr + 40);
|
||||
m_mb.reverse_video = (tmp >> 12) & 0x0f;
|
||||
m_mb.blinking_char = (tmp >> 8) & 0x0f;
|
||||
m_mb.cr2_rvv = bool(BIT(tmp, 3));
|
||||
m_mb.cr1_rvv = bool(BIT(tmp, 2));
|
||||
m_mb.cr2_oe = bool(BIT(tmp, 1));
|
||||
m_mb.cr1_oe = bool(BIT(tmp, 0));
|
||||
|
||||
tmp = read_word(mptr + 42);
|
||||
m_mb.abs_line_count = (tmp >> 12) & 0x0f;
|
||||
m_mb.invisible_char = (tmp >> 8) & 0x0f;
|
||||
m_mb.underline2 = (tmp >> 4) & 0x0f;
|
||||
m_mb.underline1 = tmp & 0x0f;
|
||||
|
||||
// setup screen mode
|
||||
rectangle visarea(hbrdstrt * 16, hbrdstp * 16 - 1, m_vsyncstp, m_vfldstp + m_margin + 1 + m_lpr - 1);
|
||||
attoseconds_t period = HZ_TO_ATTOSECONDS(clock() * 16) * line_length * 16 * frame_length;
|
||||
screen().configure(line_length * 16, frame_length, visarea, period);
|
||||
rectangle visarea(m_mb.hbrdstrt * 16, m_mb.hbrdstp * 16 - 1, m_mb.vsyncstp, m_mb.vfldstp + m_mb.scroll_margin + 1 + m_mb.lpr - 1);
|
||||
attoseconds_t period = HZ_TO_ATTOSECONDS(clock() * 16) * m_mb.line_length * 16 * m_mb.frame_length;
|
||||
screen().configure(m_mb.line_length * 16, m_mb.frame_length, visarea, period);
|
||||
|
||||
// start display is now valid
|
||||
m_mode_set = true;
|
||||
|
||||
// adjust timer for the new mode
|
||||
m_row_timer->adjust(screen().time_until_pos(0));
|
||||
|
||||
// output some debug info
|
||||
if (VERBOSE)
|
||||
{
|
||||
logerror("%s('%s'): ---- setting mode ----\n", shortname(), basetag());
|
||||
logerror("%s('%s'): dma burst length %02x, space %02x\n", shortname(), basetag(), m_dma_burst_length, m_dma_burst_space);
|
||||
logerror("%s('%s'): margin %02x, lpr %02x\n", shortname(), basetag(), m_margin, m_lpr);
|
||||
logerror("%s('%s'): ---- modeset ----\n", shortname(), basetag());
|
||||
logerror("%s('%s'): dma burst length %02x, space %02x\n", shortname(), basetag(), m_mb.burst_length, m_mb.burst_space);
|
||||
logerror("%s('%s'): margin %02x, lpr %02x\n", shortname(), basetag(), m_mb.scroll_margin, m_mb.lpr);
|
||||
logerror("%s('%s'): hsyncstp: %02x, line_length: %02x, hfldstrt: %02x, hbrdstart: %02x, hfldstop: %02x, hbrdstop: %02x\n",
|
||||
shortname(), basetag(), hsyncstp, line_length, m_hfldstrt, hbrdstrt, hfldstp, hbrdstp);
|
||||
shortname(), basetag(), m_mb.hsyncstp, m_mb.line_length, m_mb.hfldstrt, m_mb.hbrdstrt, m_mb.hfldstp, m_mb.hbrdstp);
|
||||
logerror("%s('%s'): frame_length %04x, vsyncstp: %04x, vfldstrt: %04x, vfldstp: %04x\n",
|
||||
shortname(), basetag(), frame_length, m_vsyncstp, m_vfldstrt, m_vfldstp);
|
||||
shortname(), basetag(), m_mb.frame_length, m_mb.vsyncstp, m_mb.vfldstrt, m_mb.vfldstp);
|
||||
}
|
||||
}
|
||||
|
||||
@ -256,16 +286,15 @@ void i82730_device::execute_command()
|
||||
uint8_t command = read_byte(m_cbp + 1);
|
||||
uint16_t tmp;
|
||||
|
||||
if (VERBOSE_COMMANDS && command < std::size(s_command_names))
|
||||
logerror("%s('%s'): executing command: %s [cbp = %08x]\n", shortname(), basetag(), s_command_names[command], m_cbp);
|
||||
|
||||
tmp = read_word(m_cbp + 2);
|
||||
m_list_switch = BIT(tmp, 6);
|
||||
m_auto_line_feed = BIT(tmp, 7);
|
||||
m_list_switch = bool(BIT(tmp, 7));
|
||||
m_auto_line_feed = bool(BIT(tmp, 6));
|
||||
|
||||
tmp = read_word(m_cbp + 4);
|
||||
m_max_dma_count = tmp & 0xff;
|
||||
|
||||
LOGMASKED(LOG_COMMANDS, "list switch %d, autolf %d, dma count %02x\n", m_list_switch, m_auto_line_feed, m_max_dma_count);
|
||||
|
||||
switch (command)
|
||||
{
|
||||
// NOP
|
||||
@ -274,68 +303,83 @@ void i82730_device::execute_command()
|
||||
|
||||
// START DISPLAY
|
||||
case 0x01:
|
||||
LOGMASKED(LOG_COMMANDS, "Executing command START DISPLAY\n");
|
||||
if (m_mode_set)
|
||||
{
|
||||
m_status = (m_status & ~VDIP) | DIP;
|
||||
m_row_timer->adjust(screen().time_until_pos(0));
|
||||
}
|
||||
break;
|
||||
|
||||
// START VIRTUAL DISPLAY
|
||||
case 0x02:
|
||||
if (m_mode_set)
|
||||
m_status = VDIP | (m_status & ~DIP);
|
||||
LOGMASKED(LOG_COMMANDS, "Executing command START VIRTUAL DISPLAY - not implemented\n");
|
||||
break;
|
||||
|
||||
// STOP DISPLAY
|
||||
case 0x03:
|
||||
LOGMASKED(LOG_COMMANDS, "Executing command STOP DISPLAY\n");
|
||||
m_status &= ~(VDIP | DIP);
|
||||
m_row_timer->reset();
|
||||
break;
|
||||
|
||||
// MODE SET
|
||||
case 0x04:
|
||||
LOGMASKED(LOG_COMMANDS, "Executing command MODE SET\n");
|
||||
mode_set();
|
||||
break;
|
||||
|
||||
// LOAD CBP
|
||||
case 0x05:
|
||||
LOGMASKED(LOG_COMMANDS, "Executing command LOAD CBP\n");
|
||||
m_cbp = (read_word(m_cbp + 16) << 16) | read_word(m_cbp + 14);
|
||||
LOGMASKED(LOG_COMMANDS, "--> New value = %08x\n", m_cbp);
|
||||
execute_command();
|
||||
break;
|
||||
|
||||
// LOAD INTMASK
|
||||
case 0x06:
|
||||
LOGMASKED(LOG_COMMANDS, "Executing command LOAD INTMASK\n");
|
||||
m_intmask = read_word(m_cbp + 22);
|
||||
if (VERBOSE_COMMANDS)
|
||||
logerror("%s('%s'): intmask now %04x\n", shortname(), basetag(), m_intmask);
|
||||
LOGMASKED(LOG_COMMANDS, "--> New value = %02x\n", m_intmask);
|
||||
break;
|
||||
|
||||
// LPEN ENABLE
|
||||
case 0x07:
|
||||
fatalerror("%s('%s'): Unimplemented command %s\n", shortname(), basetag(), s_command_names[command]);
|
||||
LOGMASKED(LOG_COMMANDS, "Executing command LPEN ENABLE - not implemented\n");
|
||||
break;
|
||||
|
||||
// READ STATUS
|
||||
case 0x08:
|
||||
LOGMASKED(LOG_COMMANDS, "Executing command READ STATUS\n");
|
||||
write_word(m_cbp + 18, m_status);
|
||||
m_status &= (VDIP | DIP);
|
||||
break;
|
||||
|
||||
// LD CUR POS
|
||||
case 0x09:
|
||||
fatalerror("%s('%s'): Unimplemented command %s\n", shortname(), basetag(), s_command_names[command]);
|
||||
LOGMASKED(LOG_COMMANDS, "Executing command LD CUR POS\n");
|
||||
tmp = read_word(m_cbp + 26);
|
||||
m_cursor[0].y = (tmp >> 8) & 0xff;
|
||||
m_cursor[0].x = tmp & 0xff;
|
||||
tmp = read_word(m_cbp + 28);
|
||||
m_cursor[1].y = (tmp >> 8) & 0xff;
|
||||
m_cursor[1].x = tmp & 0xff;
|
||||
LOGMASKED(LOG_COMMANDS, "--> Cursor %d, %d and %d, %d\n", m_cursor[0].x, m_cursor[0].y, m_cursor[1].x, m_cursor[1].y);
|
||||
break;
|
||||
|
||||
// SELF TEST
|
||||
case 0x0a:
|
||||
fatalerror("%s('%s'): Unimplemented command %s\n", shortname(), basetag(), s_command_names[command]);
|
||||
LOGMASKED(LOG_COMMANDS, "Executing command SELF TEST - not implemented\n");
|
||||
break;
|
||||
|
||||
// TEST ROW BUFFER
|
||||
case 0x0b:
|
||||
fatalerror("%s('%s'): Unimplemented command %s\n", shortname(), basetag(), s_command_names[command]);
|
||||
LOGMASKED(LOG_COMMANDS, "Executing command TEST ROW BUFFER - not implemented\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
if (VERBOSE_COMMANDS)
|
||||
logerror("%s('%s'): executing command: (reserved) [cbp = %08x]\n", shortname(), basetag(), m_cbp);
|
||||
LOGMASKED(LOG_COMMANDS, "Executing command %02x - unknown\n", command);
|
||||
m_status |= RCC;
|
||||
update_interrupts();
|
||||
break;
|
||||
@ -345,11 +389,269 @@ void i82730_device::execute_command()
|
||||
write_word(m_cbp, read_word(m_cbp) & 0xff00);
|
||||
}
|
||||
|
||||
bool i82730_device::dscmd_endrow()
|
||||
{
|
||||
LOGMASKED(LOG_DATASTREAM, "Executing datastream command ENDROW\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool i82730_device::dscmd_eof()
|
||||
{
|
||||
LOGMASKED(LOG_DATASTREAM, "Executing datastream command EOF - not implemented\n");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool i82730_device::dscmd_eol()
|
||||
{
|
||||
LOGMASKED(LOG_DATASTREAM, "Executing datastream command EOL\n");
|
||||
|
||||
m_sptr = (read_word(m_lptr + 2) << 16) | read_word(m_lptr);
|
||||
m_lptr += 4;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool i82730_device::dscmd_fulrowdescrpt(uint8_t param)
|
||||
{
|
||||
LOGMASKED(LOG_DATASTREAM, "Executing datastream command FULROWDESCRPT %d\n", param);
|
||||
|
||||
uint16_t tmp;
|
||||
|
||||
if (param >= 1)
|
||||
{
|
||||
tmp = read_word(m_sptr);
|
||||
m_sptr += 2;
|
||||
m_mb.rvv_row = bool(BIT(tmp, 11));
|
||||
m_mb.blk_row = bool(BIT(tmp, 10));
|
||||
m_mb.dbl_hgt = bool(BIT(tmp, 9));
|
||||
m_mb.wdef = bool(BIT(tmp, 8));
|
||||
m_mb.lpr = tmp & 0x1f;
|
||||
|
||||
LOGMASKED(LOG_DATASTREAM, "--> RVV_ROW %d, BLK_ROW %d, DBL_HGT %d, WDEF %d, LPR %d\n", m_mb.rvv_row, m_mb.blk_row, m_mb.dbl_hgt, m_mb.wdef, m_mb.lpr);
|
||||
}
|
||||
|
||||
if (param >= 2)
|
||||
{
|
||||
tmp = read_word(m_sptr);
|
||||
m_sptr += 2;
|
||||
m_mb.nrmstrt = (tmp >> 8) & 0x1f;
|
||||
m_mb.nrmstp = tmp & 0x1f;
|
||||
|
||||
LOGMASKED(LOG_DATASTREAM, "--> NRMSTRT %d, NRMSTP %d\n", m_mb.nrmstrt, m_mb.nrmstp);
|
||||
}
|
||||
|
||||
if (param >= 3)
|
||||
{
|
||||
tmp = read_word(m_sptr);
|
||||
m_sptr += 2;
|
||||
m_mb.supstrt = (tmp >> 8) & 0x1f;
|
||||
m_mb.supstp = tmp & 0x1f;
|
||||
|
||||
LOGMASKED(LOG_DATASTREAM, "--> SUPSTRT %d, SUPSTP %d\n", m_mb.supstrt, m_mb.supstp);
|
||||
}
|
||||
|
||||
if (param >= 4)
|
||||
{
|
||||
tmp = read_word(m_sptr);
|
||||
m_sptr += 2;
|
||||
m_mb.substrt = (tmp >> 8) & 0x1f;
|
||||
m_mb.substp = tmp & 0x1f;
|
||||
|
||||
LOGMASKED(LOG_DATASTREAM, "--> SUBSTRT %d, SUBSTP %d\n", m_mb.substrt, m_mb.substp);
|
||||
}
|
||||
|
||||
if (param >= 5)
|
||||
{
|
||||
tmp = read_word(m_sptr);
|
||||
m_sptr += 2;
|
||||
m_mb.cur1strt = (tmp >> 8) & 0x1f;
|
||||
m_mb.cur1stp = tmp & 0x1f;
|
||||
|
||||
LOGMASKED(LOG_DATASTREAM, "--> CUR1STRT %d, CUR1STP %d\n", m_mb.cur1strt, m_mb.cur1stp);
|
||||
}
|
||||
|
||||
if (param >= 6)
|
||||
{
|
||||
tmp = read_word(m_sptr);
|
||||
m_sptr += 2;
|
||||
m_mb.cur2strt = (tmp >> 8) & 0x1f;
|
||||
m_mb.cur2stp = tmp & 0x1f;
|
||||
|
||||
LOGMASKED(LOG_DATASTREAM, "--> CUR2STRT %d, CUR2STP %d\n", m_mb.cur2strt, m_mb.cur2stp);
|
||||
}
|
||||
|
||||
if (param >= 7)
|
||||
{
|
||||
tmp = read_word(m_sptr);
|
||||
m_sptr += 2;
|
||||
m_mb.u2_line_sel = (tmp >> 8) & 0x1f;
|
||||
m_mb.u1_line_sel = tmp & 0x1f;
|
||||
|
||||
LOGMASKED(LOG_DATASTREAM, "--> U2 LINE SEL %d, U1 LINE SEL %d\n", m_mb.u2_line_sel, m_mb.u1_line_sel);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool i82730_device::dscmd_sl_scroll_strt(uint8_t param)
|
||||
{
|
||||
LOGMASKED(LOG_DATASTREAM, "Executing datastream command SL SCROLL START %d - not implemented\n", param);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool i82730_device::dscmd_sl_scroll_end(uint8_t param)
|
||||
{
|
||||
LOGMASKED(LOG_DATASTREAM, "Executing datastream command SL SCROLL END %d - not implemented\n", param);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool i82730_device::dscmd_tab_to(uint8_t param)
|
||||
{
|
||||
LOGMASKED(LOG_DATASTREAM, "Executing datastream command TAB TO %d - not implemented\n", param);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool i82730_device::dscmd_max_dma_count(uint8_t param)
|
||||
{
|
||||
LOGMASKED(LOG_DATASTREAM, "Executing datastream command LD MAX DMA COUNT %02x\n", param);
|
||||
|
||||
m_max_dma_count = param;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool i82730_device::dscmd_endstrg()
|
||||
{
|
||||
LOGMASKED(LOG_DATASTREAM, "Executing datastream command ENDSTRG\n");
|
||||
|
||||
m_sptr = (read_word(m_lptr + 2) << 16) | read_word(m_lptr);
|
||||
m_lptr += 4;
|
||||
|
||||
LOGMASKED(LOG_DATASTREAM, "--> SPTR %08x\n", m_sptr);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool i82730_device::dscmd_skip(uint8_t param)
|
||||
{
|
||||
LOGMASKED(LOG_DATASTREAM, "Executing datastream command SKIP %d - not implemented\n", param);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool i82730_device::dscmd_repeat(uint8_t param)
|
||||
{
|
||||
LOGMASKED(LOG_DATASTREAM, "Executing datastream command REPEAT %d\n", param);
|
||||
|
||||
uint16_t data = read_word(m_sptr);
|
||||
m_sptr += 2;
|
||||
|
||||
LOGMASKED(LOG_DATASTREAM, "--> Repeating %02x\n", data);
|
||||
|
||||
while (param--)
|
||||
{
|
||||
if (--m_dma_count && m_row_count < 200)
|
||||
m_row[m_row_count++] = data;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool i82730_device::dscmd_sub_sup(uint8_t param)
|
||||
{
|
||||
LOGMASKED(LOG_DATASTREAM, "Executing datastream command SUP SUB - not implemented\n", param);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool i82730_device::dscmd_rpt_sub_sup(uint8_t param)
|
||||
{
|
||||
LOGMASKED(LOG_DATASTREAM, "Executing datastream command RPT SUP SUB - not implemented\n", param);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool i82730_device::dscmd_set_gen_pur_attrib(uint8_t param)
|
||||
{
|
||||
LOGMASKED(LOG_DATASTREAM, "Executing datastream command SET GEN PUR ATTRIB - not implemented\n", param);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool i82730_device::dscmd_set_field_attrib()
|
||||
{
|
||||
LOGMASKED(LOG_DATASTREAM, "Executing datastream command SET FIELD ATTRIB\n");
|
||||
|
||||
m_mb.field_attribute_mask = read_word(m_sptr) & 0x7fff;
|
||||
m_sptr += 2;
|
||||
|
||||
LOGMASKED(LOG_DATASTREAM, "--> New value = %04x\n", m_mb.field_attribute_mask);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool i82730_device::dscmd_init_next_process()
|
||||
{
|
||||
LOGMASKED(LOG_DATASTREAM, "Executing datastream command INIT NEXT PROCESS - not implemented\n");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool i82730_device::execute_datastream_command(uint8_t command, uint8_t param)
|
||||
{
|
||||
// RESERVED
|
||||
if (command >= 0x90 && command <= 0xbf)
|
||||
{
|
||||
LOGMASKED(LOG_DATASTREAM, "Executing reserved datastream command %02x\n", command);
|
||||
|
||||
m_status |= RDC;
|
||||
update_interrupts();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// NOP
|
||||
if (command >= 0xc0)
|
||||
return false;
|
||||
|
||||
// DATASTREAM COMMANDS
|
||||
switch (command)
|
||||
{
|
||||
case 0x80: return dscmd_endrow();
|
||||
case 0x81: return dscmd_eof();
|
||||
case 0x82: return dscmd_eol();
|
||||
case 0x83: return dscmd_fulrowdescrpt(param);
|
||||
case 0x84: return dscmd_sl_scroll_strt(param);
|
||||
case 0x85: return dscmd_sl_scroll_end(param);
|
||||
case 0x86: return dscmd_tab_to(param);
|
||||
case 0x87: return dscmd_max_dma_count(param);
|
||||
case 0x88: return dscmd_endstrg();
|
||||
case 0x89: return dscmd_skip(param);
|
||||
case 0x8a: return dscmd_repeat(param);
|
||||
case 0x8b: return dscmd_sub_sup(param);
|
||||
case 0x8c: return dscmd_rpt_sub_sup(param);
|
||||
case 0x8d: return dscmd_set_gen_pur_attrib(param);
|
||||
case 0x8e: return dscmd_set_field_attrib();
|
||||
case 0x8f: return dscmd_init_next_process();
|
||||
}
|
||||
|
||||
// should never get here
|
||||
return false;
|
||||
}
|
||||
|
||||
void i82730_device::load_row()
|
||||
{
|
||||
bool finished = false;
|
||||
|
||||
m_row[m_row_index].count = 0;
|
||||
m_dma_count = m_max_dma_count;
|
||||
m_row_count = 0;
|
||||
|
||||
while (!finished)
|
||||
{
|
||||
@ -358,44 +660,37 @@ void i82730_device::load_row()
|
||||
|
||||
if (BIT(data, 15))
|
||||
{
|
||||
switch (data >> 8)
|
||||
{
|
||||
case 0x8e:
|
||||
m_field_attribute_mask = read_word(m_sptr) & 0x7fff;
|
||||
m_sptr += 2;
|
||||
|
||||
if (VERBOSE_DATASTREAM)
|
||||
logerror("%s('%s'): SET FIELD ATTRIB to %04x\n", shortname(), basetag(), m_field_attribute_mask);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
fatalerror("%s('%s'): Unimplemented datastream command %02x\n", shortname(), basetag(), data >> 8);
|
||||
}
|
||||
finished = execute_datastream_command(data >> 8, data & 0xff);
|
||||
}
|
||||
else
|
||||
{
|
||||
// maximum row size is 200
|
||||
if (m_row[m_row_index].count < m_max_dma_count && m_row[m_row_index].count < 200)
|
||||
// fetch data
|
||||
if (--m_dma_count > 0)
|
||||
{
|
||||
m_row[m_row_index].data[m_row[m_row_index].count++] = data;
|
||||
if (m_row_count < 200)
|
||||
{
|
||||
m_row[m_row_count++] = data;
|
||||
}
|
||||
else
|
||||
{
|
||||
// buffer overrun
|
||||
m_status |= DBOR;
|
||||
update_interrupts();
|
||||
finished = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
// move to next string?
|
||||
if (m_auto_line_feed == 0)
|
||||
if (!m_auto_line_feed)
|
||||
{
|
||||
m_sptr = (read_word(m_lptr + 2) << 16) | read_word(m_lptr);
|
||||
m_lptr += 4;
|
||||
}
|
||||
#endif
|
||||
|
||||
finished = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_sptr -= 2;
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER( i82730_device::row_update )
|
||||
@ -408,10 +703,10 @@ TIMER_CALLBACK_MEMBER( i82730_device::row_update )
|
||||
m_status &= (VDIP | DIP);
|
||||
|
||||
// clear field attribute mask
|
||||
m_field_attribute_mask = 0;
|
||||
m_mb.field_attribute_mask = 0;
|
||||
|
||||
// get listbase
|
||||
if (m_list_switch)
|
||||
if (m_list_switch == 0)
|
||||
m_lptr = (read_word(m_cbp + 8) << 16) | read_word(m_cbp + 6);
|
||||
else
|
||||
m_lptr = (read_word(m_cbp + 12) << 16) | read_word(m_cbp + 10);
|
||||
@ -421,46 +716,52 @@ TIMER_CALLBACK_MEMBER( i82730_device::row_update )
|
||||
|
||||
// fetch initial row
|
||||
m_row_index = 0;
|
||||
m_row = &m_row_buffer[m_row_index][0];
|
||||
load_row();
|
||||
}
|
||||
else if (y >= m_vsyncstp && y < m_vfldstrt)
|
||||
else if (y >= m_mb.vsyncstp && y < m_mb.vfldstrt)
|
||||
{
|
||||
// blank (top border)
|
||||
}
|
||||
else if (y >= m_vfldstrt && y < m_vfldstp)
|
||||
else if (y >= m_mb.vfldstrt && y < m_mb.vfldstp)
|
||||
{
|
||||
uint8_t lc = (y - m_vfldstrt) % (m_lpr + 1);
|
||||
uint8_t lc = (y - m_mb.vfldstrt) % (m_mb.lpr + 1);
|
||||
|
||||
// call driver
|
||||
m_update_row_cb(m_bitmap, m_row[m_row_index].data, lc, y - m_vsyncstp, m_row[m_row_index].count);
|
||||
m_update_row_cb(m_bitmap, m_row, lc, y - m_mb.vsyncstp, m_row_count);
|
||||
|
||||
// swap buffers at end of row
|
||||
if (lc == m_lpr)
|
||||
if (lc == m_mb.lpr)
|
||||
{
|
||||
m_row_index ^= 1;
|
||||
m_row = &m_row_buffer[m_row_index][0];
|
||||
|
||||
// load status row data at end of regular display
|
||||
if (y == (m_mb.vfldstp - 1))
|
||||
m_sptr = (read_word(m_cbp + 36) << 16) | read_word(m_cbp + 34);
|
||||
|
||||
load_row();
|
||||
}
|
||||
}
|
||||
else if (y >= m_vfldstp && y < m_vfldstp + m_margin + 1)
|
||||
else if (y >= m_mb.vfldstp && y < m_mb.vfldstp + m_mb.scroll_margin + 1)
|
||||
{
|
||||
// margin
|
||||
}
|
||||
else if (y >= m_vfldstp + m_margin + 1 && y < m_vfldstp + m_margin + 1 + m_lpr + 1)
|
||||
else if (y >= m_mb.vfldstp + m_mb.scroll_margin + 1 && y < m_mb.vfldstp + m_mb.scroll_margin + 1 + m_mb.lpr + 1)
|
||||
{
|
||||
uint8_t lc = (y - (m_vfldstp + m_margin + 1)) % (m_lpr + 1);
|
||||
|
||||
m_sptr = (read_word(m_cbp + 36) << 16) | read_word(m_cbp + 34);
|
||||
load_row();
|
||||
uint8_t lc = (y - (m_mb.vfldstp + m_mb.scroll_margin + 1)) % (m_mb.lpr + 1);
|
||||
|
||||
// call driver
|
||||
m_update_row_cb(m_bitmap, m_row[m_row_index].data, lc, y - m_vsyncstp, m_row[m_row_index].count);
|
||||
m_update_row_cb(m_bitmap, m_row, lc, y - m_mb.vsyncstp, m_row_count);
|
||||
}
|
||||
else if (y == m_vfldstp + m_margin + 1 + m_lpr + 1)
|
||||
else if (y == m_mb.vfldstp + m_mb.scroll_margin + 1 + m_mb.lpr + 1)
|
||||
{
|
||||
// todo: check ca
|
||||
// check ca latch
|
||||
if (m_ca_latch)
|
||||
attention();
|
||||
|
||||
// frame interrupt?
|
||||
if ((screen().frame_number() % m_frame_int_count) == 0)
|
||||
if ((screen().frame_number() % m_mb.frame_int_count) == 0)
|
||||
m_status |= EONF;
|
||||
|
||||
// check interrupts
|
||||
@ -471,16 +772,27 @@ TIMER_CALLBACK_MEMBER( i82730_device::row_update )
|
||||
// vblank
|
||||
}
|
||||
|
||||
m_row_timer->adjust(screen().time_until_pos((y + 1) % screen().height()));
|
||||
// schedule next line (if enabled)
|
||||
if (m_status & DIP)
|
||||
m_row_timer->adjust(screen().time_until_pos((y + 1) % screen().height()));
|
||||
}
|
||||
|
||||
void i82730_device::attention()
|
||||
{
|
||||
execute_command();
|
||||
m_ca_latch = false;
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( i82730_device::ca_w )
|
||||
{
|
||||
if (VERBOSE)
|
||||
logerror("%s('%s'): ca_w %d\n", shortname(), basetag(), state);
|
||||
|
||||
// falling edge
|
||||
if (m_ca == 1 && state == 0)
|
||||
m_ca_latch = true;
|
||||
|
||||
m_ca = state;
|
||||
|
||||
// check ca every cycle if the display isn't active
|
||||
if (m_ca_latch && ((m_status & DIP) == 0))
|
||||
{
|
||||
if (!m_initialized)
|
||||
{
|
||||
@ -490,6 +802,8 @@ WRITE_LINE_MEMBER( i82730_device::ca_w )
|
||||
// get intermediate block pointer
|
||||
m_ibp = (read_word(0xfffffffe) << 16) | read_word(0xfffffffc);
|
||||
|
||||
m_cbp = (read_word(m_ibp + 4) << 16) | read_word(m_ibp + 2);
|
||||
|
||||
// get system configuration byte
|
||||
uint8_t scb = read_byte(m_ibp + 6);
|
||||
|
||||
@ -511,26 +825,17 @@ WRITE_LINE_MEMBER( i82730_device::ca_w )
|
||||
}
|
||||
}
|
||||
|
||||
// fetch command block pointer
|
||||
m_cbp = (read_word(m_ibp + 4) << 16) | read_word(m_ibp + 2);
|
||||
|
||||
// and execute command
|
||||
execute_command();
|
||||
attention();
|
||||
}
|
||||
|
||||
m_ca = state;
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( i82730_device::irst_w )
|
||||
{
|
||||
if (VERBOSE)
|
||||
logerror("%s('%s'): irst_w %d\n", shortname(), basetag(), state);
|
||||
|
||||
m_sint_handler(0);
|
||||
}
|
||||
|
||||
uint32_t i82730_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
copybitmap(bitmap, m_bitmap, 0, 0, m_hfldstrt * 16, 0, cliprect);
|
||||
copybitmap(bitmap, m_bitmap, 0, 0, m_mb.hfldstrt * 16, 0, cliprect);
|
||||
return 0;
|
||||
}
|
||||
|
@ -66,8 +66,6 @@ private:
|
||||
VDIP = 0x100 // virtual display in progress
|
||||
};
|
||||
|
||||
static const char *const s_command_names[];
|
||||
|
||||
bool sysbus_16bit() { return BIT(m_sysbus, 0); }
|
||||
|
||||
uint8_t read_byte(offs_t address);
|
||||
@ -78,7 +76,28 @@ private:
|
||||
void update_interrupts();
|
||||
void mode_set();
|
||||
void execute_command();
|
||||
|
||||
bool dscmd_endrow();
|
||||
bool dscmd_eof();
|
||||
bool dscmd_eol();
|
||||
bool dscmd_fulrowdescrpt(uint8_t param);
|
||||
bool dscmd_sl_scroll_strt(uint8_t param);
|
||||
bool dscmd_sl_scroll_end(uint8_t param);
|
||||
bool dscmd_tab_to(uint8_t param);
|
||||
bool dscmd_max_dma_count(uint8_t param);
|
||||
bool dscmd_endstrg();
|
||||
bool dscmd_skip(uint8_t param);
|
||||
bool dscmd_repeat(uint8_t param);
|
||||
bool dscmd_sub_sup(uint8_t param);
|
||||
bool dscmd_rpt_sub_sup(uint8_t param);
|
||||
bool dscmd_set_gen_pur_attrib(uint8_t param);
|
||||
bool dscmd_set_field_attrib();
|
||||
bool dscmd_init_next_process();
|
||||
|
||||
bool execute_datastream_command(uint8_t command, uint8_t param);
|
||||
|
||||
void load_row();
|
||||
void attention();
|
||||
|
||||
TIMER_CALLBACK_MEMBER(row_update);
|
||||
|
||||
@ -92,48 +111,99 @@ private:
|
||||
|
||||
bitmap_rgb32 m_bitmap;
|
||||
|
||||
// internal registers
|
||||
bool m_initialized;
|
||||
bool m_mode_set;
|
||||
|
||||
int m_ca;
|
||||
bool m_ca_latch;
|
||||
|
||||
// internal registers
|
||||
uint8_t m_sysbus;
|
||||
uint32_t m_ibp;
|
||||
uint32_t m_cbp;
|
||||
uint16_t m_intmask;
|
||||
uint16_t m_status;
|
||||
uint32_t m_ibp; // intermediate block pointer
|
||||
uint32_t m_cbp; // command block pointer
|
||||
|
||||
int m_list_switch;
|
||||
int m_auto_line_feed;
|
||||
bool m_list_switch;
|
||||
bool m_auto_line_feed;
|
||||
uint8_t m_max_dma_count;
|
||||
|
||||
uint32_t m_lptr;
|
||||
uint16_t m_status;
|
||||
uint16_t m_intmask;
|
||||
|
||||
uint32_t m_sptr;
|
||||
|
||||
int m_dma_burst_space;
|
||||
int m_dma_burst_length;
|
||||
|
||||
// display parameters
|
||||
int m_hfldstrt;
|
||||
int m_margin;
|
||||
int m_lpr;
|
||||
uint16_t m_field_attribute_mask;
|
||||
int m_vsyncstp;
|
||||
int m_vfldstrt;
|
||||
int m_vfldstp;
|
||||
|
||||
int m_frame_int_count;
|
||||
|
||||
// row buffers
|
||||
struct row_buffer
|
||||
struct modeset
|
||||
{
|
||||
uint16_t data[200];
|
||||
int count;
|
||||
};
|
||||
// horizontal modes
|
||||
uint8_t burst_length;
|
||||
uint8_t burst_space;
|
||||
uint8_t line_length;
|
||||
uint8_t hsyncstp;
|
||||
uint8_t hfldstrt;
|
||||
uint8_t hfldstp;
|
||||
uint8_t hbrdstrt;
|
||||
uint8_t hbrdstp;
|
||||
uint8_t scroll_margin;
|
||||
// char row characteristics
|
||||
bool rvv_row;
|
||||
bool blk_row;
|
||||
bool dbl_hgt;
|
||||
bool wdef;
|
||||
uint8_t lpr;
|
||||
uint8_t nrmstrt;
|
||||
uint8_t nrmstp;
|
||||
uint8_t supstrt;
|
||||
uint8_t supstp;
|
||||
uint8_t substrt;
|
||||
uint8_t substp;
|
||||
uint8_t cur1strt;
|
||||
uint8_t cur1stp;
|
||||
uint8_t cur2strt;
|
||||
uint8_t cur2stp;
|
||||
uint8_t u2_line_sel;
|
||||
uint8_t u1_line_sel;
|
||||
uint16_t field_attribute_mask;
|
||||
// vertical modes
|
||||
uint16_t frame_length;
|
||||
uint16_t vsyncstp;
|
||||
uint16_t vfldstrt;
|
||||
uint16_t vfldstp;
|
||||
// blink control
|
||||
uint8_t duty_cyc_cursor;
|
||||
uint8_t cursor_blink;
|
||||
uint8_t frame_int_count;
|
||||
uint8_t duty_cyc_char;
|
||||
uint8_t char_blink;
|
||||
bool ile;
|
||||
bool rfe;
|
||||
bool bpol;
|
||||
bool bue;
|
||||
bool cr2_cd;
|
||||
bool cr1_cd;
|
||||
bool cr2_be;
|
||||
bool cr1_be;
|
||||
// atrribute bit selects
|
||||
uint8_t reverse_video;
|
||||
uint8_t blinking_char;
|
||||
bool cr2_rvv;
|
||||
bool cr1_rvv;
|
||||
bool cr2_oe;
|
||||
bool cr1_oe;
|
||||
uint8_t abs_line_count;
|
||||
uint8_t invisible_char;
|
||||
uint8_t underline2;
|
||||
uint8_t underline1;
|
||||
} m_mb;
|
||||
|
||||
row_buffer m_row[2];
|
||||
int m_row_index;
|
||||
uint16_t m_row_buffer[2][200];
|
||||
uint16_t *m_row; // pointer to currently active row buffer
|
||||
uint8_t m_dma_count;
|
||||
uint8_t m_row_count; // maximum 200
|
||||
int m_row_index; // 0 or 1
|
||||
|
||||
struct cursor
|
||||
{
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
} m_cursor[2];
|
||||
};
|
||||
|
||||
// device type definition
|
||||
|
@ -6,9 +6,12 @@
|
||||
|
||||
TODO:
|
||||
- Needs better I82730 emulation
|
||||
- Sound
|
||||
- Floppy I/O errors
|
||||
- Many more things
|
||||
|
||||
Notes:
|
||||
- Press SPACE during self-test for an extended menu
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
@ -28,6 +31,7 @@
|
||||
#include "imagedev/cassette.h"
|
||||
#include "imagedev/floppy.h"
|
||||
#include "formats/rc759_dsk.h"
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
#include "speaker.h"
|
||||
|
||||
@ -49,6 +53,7 @@ public:
|
||||
m_nvram(*this, "nvram"),
|
||||
m_ppi(*this, "ppi"),
|
||||
m_txt(*this, "txt"),
|
||||
m_palette(*this, "palette"),
|
||||
m_cas(*this, "cas"),
|
||||
m_isbx(*this, "isbx"),
|
||||
m_speaker(*this, "speaker"),
|
||||
@ -81,6 +86,7 @@ private:
|
||||
required_device<nvram_device> m_nvram;
|
||||
required_device<i8255_device> m_ppi;
|
||||
required_device<i82730_device> m_txt;
|
||||
required_device<palette_device> m_palette;
|
||||
required_device<cassette_image_device> m_cas;
|
||||
required_device<isbx_slot_device> m_isbx;
|
||||
required_device<speaker_sound_device> m_speaker;
|
||||
@ -181,7 +187,8 @@ void rc759_state::rc759_io(address_map &map)
|
||||
map.unmap_value_high();
|
||||
map(0x000, 0x003).mirror(0x0c).rw(m_pic, FUNC(pic8259_device::read), FUNC(pic8259_device::write)).umask16(0x00ff);
|
||||
map(0x020, 0x020).r(m_kbd, FUNC(rc759_kbd_hle_device::read));
|
||||
// map(0x056, 0x056)
|
||||
map(0x056, 0x056).w(m_snd, FUNC(sn76494_device::write));
|
||||
map(0x056, 0x057).nopr();
|
||||
map(0x05a, 0x05a).w(FUNC(rc759_state::rtc_data_w));
|
||||
map(0x05c, 0x05c).rw(FUNC(rc759_state::rtc_data_r), FUNC(rc759_state::rtc_addr_w));
|
||||
// map(0x060, 0x06f).w(FUNC(rc759_state::crt_control_w)).umask16(0x00ff);
|
||||
@ -264,6 +271,7 @@ void rc759_state::txt_irst_w(uint16_t data)
|
||||
|
||||
uint8_t rc759_state::palette_r(offs_t offset)
|
||||
{
|
||||
// not sure if it's possible to read back
|
||||
logerror("palette_r(%02x)\n", offset);
|
||||
return 0xff;
|
||||
}
|
||||
@ -271,6 +279,22 @@ uint8_t rc759_state::palette_r(offs_t offset)
|
||||
void rc759_state::palette_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
logerror("palette_w(%02x): %02x\n", offset, data);
|
||||
|
||||
// two colors/byte. format: IRGBIRGB
|
||||
static constexpr uint8_t val[4] = { 0x00, 0x55, 0xaa, 0xff };
|
||||
int r, g, b;
|
||||
|
||||
r = (BIT(data, 2) << 1) | BIT(data, 3);
|
||||
g = (BIT(data, 1) << 1) | BIT(data, 3);
|
||||
b = (BIT(data, 0) << 1) | BIT(data, 3);
|
||||
|
||||
m_palette->set_pen_color(offset * 2 + 0, rgb_t(val[r], val[g], val[b]));
|
||||
|
||||
r = (BIT(data, 6) << 1) | BIT(data, 7);
|
||||
g = (BIT(data, 5) << 1) | BIT(data, 7);
|
||||
b = (BIT(data, 4) << 1) | BIT(data, 7);
|
||||
|
||||
m_palette->set_pen_color(offset * 2 + 1, rgb_t(val[r], val[g], val[b]));
|
||||
}
|
||||
|
||||
|
||||
@ -598,6 +622,8 @@ void rc759_state::rc759(machine_config &config)
|
||||
m_txt->set_update_row_callback(FUNC(rc759_state::txt_update_row));
|
||||
m_txt->sint().set(m_pic, FUNC(pic8259_device::ir4_w));
|
||||
|
||||
PALETTE(config, m_palette).set_entries(64);
|
||||
|
||||
// sound
|
||||
SPEAKER(config, "mono").front_center();
|
||||
SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.50);
|
||||
|
Loading…
Reference in New Issue
Block a user