mirror of
https://github.com/holub/mame
synced 2025-04-23 08:49:55 +03:00
scn2674: Add BREQ output; get a bit smarter about screen reconfiguration (nw)
This commit is contained in:
parent
3ee2d47303
commit
742b89c16b
@ -14,7 +14,7 @@
|
||||
#define LOG_COMMAND (1 << 1)
|
||||
#define LOG_INTR (1 << 2)
|
||||
#define LOG_READ (1 << 3)
|
||||
#define VERBOSE (0)
|
||||
#define VERBOSE (1)
|
||||
#include "logmacro.h"
|
||||
|
||||
|
||||
@ -43,6 +43,7 @@ scn2674_device::scn2674_device(const machine_config &mconfig, device_type type,
|
||||
, device_video_interface(mconfig, *this)
|
||||
, device_memory_interface(mconfig, *this)
|
||||
, m_intr_cb(*this)
|
||||
, m_breq_cb(*this)
|
||||
, m_IR_pointer(0)
|
||||
, m_screen1_address(0), m_screen2_address(0)
|
||||
, m_cursor_address(0)
|
||||
@ -103,6 +104,7 @@ void scn2674_device::device_start()
|
||||
// resolve callbacks
|
||||
m_display_cb.bind_relative_to(*owner());
|
||||
m_intr_cb.resolve_safe();
|
||||
m_breq_cb.resolve_safe();
|
||||
m_scanline_timer = timer_alloc(TIMER_SCANLINE);
|
||||
screen().register_screen_bitmap(m_bitmap);
|
||||
|
||||
@ -221,9 +223,12 @@ void scn2672_device::write_init_regs(uint8_t data)
|
||||
{
|
||||
//LOGMASKED(LOG_COMMAND, "scn2674_write_init_regs %02x %02x\n",m_IR_pointer,data);
|
||||
|
||||
bool parameters_changed = false;
|
||||
switch (m_IR_pointer)
|
||||
{
|
||||
case 0:
|
||||
parameters_changed = m_scanline_per_char_row != ((data & 0x78) >> 3) + 1;
|
||||
|
||||
m_double_ht_wd = BIT(data, 7);
|
||||
m_scanline_per_char_row = ((data & 0x78) >> 3) + 1;
|
||||
m_csync_select = BIT(data, 2);
|
||||
@ -252,6 +257,8 @@ void scn2672_device::write_init_regs(uint8_t data)
|
||||
break;
|
||||
|
||||
case 1:
|
||||
parameters_changed = m_equalizing_constant != (data & 0x7f) + 1;
|
||||
|
||||
m_interlace_enable = BIT(data, 7);
|
||||
m_equalizing_constant = (data & 0x7f) + 1;
|
||||
|
||||
@ -260,6 +267,8 @@ void scn2672_device::write_init_regs(uint8_t data)
|
||||
break;
|
||||
|
||||
case 2:
|
||||
parameters_changed = m_horz_sync_width != (((data & 0x78) >> 3) * 2) + 2;
|
||||
|
||||
m_horz_sync_width = (((data & 0x78) >> 3) * 2) + 2;
|
||||
m_horz_back_porch = ((data & 0x07) * 4) + 1;
|
||||
|
||||
@ -268,6 +277,9 @@ void scn2672_device::write_init_regs(uint8_t data)
|
||||
break;
|
||||
|
||||
case 3:
|
||||
parameters_changed = m_vert_front_porch != (((data & 0xe0) >> 5) * 4) + 4
|
||||
|| m_vert_back_porch != ((data & 0x1f) * 2) + 4;
|
||||
|
||||
m_vert_front_porch = (((data & 0xe0) >> 5) * 4) + 4;
|
||||
m_vert_back_porch = ((data & 0x1f) * 2) + 4;
|
||||
|
||||
@ -276,6 +288,8 @@ void scn2672_device::write_init_regs(uint8_t data)
|
||||
break;
|
||||
|
||||
case 4:
|
||||
parameters_changed = m_rows_per_screen != (data & 0x7f) + 1;
|
||||
|
||||
m_rows_per_screen = (data & 0x7f) + 1;
|
||||
m_character_blink_rate_divisor = BIT(data, 7) ? 32 : 16;
|
||||
|
||||
@ -284,6 +298,8 @@ void scn2672_device::write_init_regs(uint8_t data)
|
||||
break;
|
||||
|
||||
case 5:
|
||||
parameters_changed = m_character_per_row != data + 1;
|
||||
|
||||
m_character_per_row = data + 1;
|
||||
LOGMASKED(LOG_IR, "IR5 - Active Characters Per Row %02i\n", m_character_per_row);
|
||||
break;
|
||||
@ -333,8 +349,7 @@ void scn2672_device::write_init_regs(uint8_t data)
|
||||
break;
|
||||
}
|
||||
|
||||
// Don't reconfigure if the display isn't turned on (incomplete configurations may generate invalid screen parameters)
|
||||
if (m_display_enabled)
|
||||
if (parameters_changed)
|
||||
recompute_parameters();
|
||||
|
||||
m_IR_pointer = std::min(m_IR_pointer + 1, 10);
|
||||
@ -345,9 +360,12 @@ void scn2674_device::write_init_regs(uint8_t data)
|
||||
{
|
||||
//LOGMASKED(LOG_COMMAND, "scn2674_write_init_regs %02x %02x\n",m_IR_pointer,data);
|
||||
|
||||
bool parameters_changed = false;
|
||||
switch (m_IR_pointer)
|
||||
{
|
||||
case 0:
|
||||
parameters_changed = m_scanline_per_char_row != ((data & 0x78) >> 3) + 1;
|
||||
|
||||
m_double_ht_wd = BIT(data, 7);
|
||||
m_scanline_per_char_row = ((data & 0x78) >> 3) + 1;
|
||||
m_csync_select = BIT(data, 2);
|
||||
@ -377,6 +395,8 @@ void scn2674_device::write_init_regs(uint8_t data)
|
||||
break;
|
||||
|
||||
case 1:
|
||||
parameters_changed = m_equalizing_constant != (data & 0x7f) + 1;
|
||||
|
||||
m_interlace_enable = BIT(data, 7);
|
||||
m_equalizing_constant = (data & 0x7f) + 1;
|
||||
|
||||
@ -385,6 +405,8 @@ void scn2674_device::write_init_regs(uint8_t data)
|
||||
break;
|
||||
|
||||
case 2:
|
||||
parameters_changed = m_horz_sync_width != (((data & 0x78) >> 3) * 2) + 2;
|
||||
|
||||
m_use_row_table = BIT(data, 7);
|
||||
m_horz_sync_width = (((data & 0x78) >> 3) * 2) + 2;
|
||||
m_horz_back_porch = ((data & 0x07) * 4) - 1;
|
||||
@ -395,6 +417,9 @@ void scn2674_device::write_init_regs(uint8_t data)
|
||||
break;
|
||||
|
||||
case 3:
|
||||
parameters_changed = m_vert_front_porch != (((data & 0xe0) >> 5) * 4) + 4
|
||||
|| m_vert_back_porch != ((data & 0x1f) * 2) + 4;
|
||||
|
||||
m_vert_front_porch = (((data & 0xe0) >> 5) * 4) + 4;
|
||||
m_vert_back_porch = ((data & 0x1f) * 2) + 4;
|
||||
|
||||
@ -403,6 +428,8 @@ void scn2674_device::write_init_regs(uint8_t data)
|
||||
break;
|
||||
|
||||
case 4:
|
||||
parameters_changed = m_rows_per_screen != (data & 0x7f) + 1;
|
||||
|
||||
m_rows_per_screen = (data & 0x7f) + 1;
|
||||
m_character_blink_rate_divisor = BIT(data, 7) ? 128 : 64;
|
||||
|
||||
@ -411,6 +438,8 @@ void scn2674_device::write_init_regs(uint8_t data)
|
||||
break;
|
||||
|
||||
case 5:
|
||||
parameters_changed = m_character_per_row != data + 1;
|
||||
|
||||
m_character_per_row = data + 1;
|
||||
LOGMASKED(LOG_IR, "IR5 - Active Characters Per Row %02i\n", m_character_per_row);
|
||||
break;
|
||||
@ -429,6 +458,7 @@ void scn2674_device::write_init_regs(uint8_t data)
|
||||
m_cursor_rate_divisor = BIT(data, 4) ? 64 : 32;
|
||||
m_cursor_blink = BIT(data, 5);
|
||||
|
||||
parameters_changed = m_vsync_width != vsync_table[(data & 0xc0) >> 6];
|
||||
m_vsync_width = vsync_table[(data & 0xc0) >> 6];
|
||||
|
||||
LOGMASKED(LOG_IR, "IR7 - Underline Position %02i\n", m_cursor_underline_position);
|
||||
@ -499,8 +529,7 @@ void scn2674_device::write_init_regs(uint8_t data)
|
||||
break;
|
||||
}
|
||||
|
||||
// Don't reconfigure if the display isn't turned on (incomplete configurations may generate invalid screen parameters)
|
||||
if (m_display_enabled)
|
||||
if (parameters_changed)
|
||||
recompute_parameters();
|
||||
|
||||
m_IR_pointer = std::min(m_IR_pointer + 1, 14);
|
||||
@ -601,13 +630,7 @@ void scn2674_device::write_interrupt_mask(bool enabled, uint8_t bits)
|
||||
if (BIT(changed_bits, 3))
|
||||
LOGMASKED(LOG_INTR, "Line Zero IRQ %s\n", enabled ? "enabled" : "disabled");
|
||||
if (BIT(changed_bits, 4))
|
||||
{
|
||||
LOGMASKED(LOG_INTR, "V-Blank IRQ %s\n", enabled ? "enabled" : "disabled");
|
||||
|
||||
// hack to allow PC-X to get its first interrupt
|
||||
if (BIT(bits, 4) && !m_display_enabled)
|
||||
recompute_parameters();
|
||||
}
|
||||
}
|
||||
|
||||
void scn2674_device::write_delayed_command(uint8_t data)
|
||||
@ -925,6 +948,12 @@ WRITE8_MEMBER( scn2674_device::write )
|
||||
|
||||
void scn2674_device::recompute_parameters()
|
||||
{
|
||||
if (!m_equalizing_constant || !m_character_per_row || !m_rows_per_screen)
|
||||
{
|
||||
m_scanline_timer->adjust(attotime::never);
|
||||
return;
|
||||
}
|
||||
|
||||
int horiz_chars_total = (m_equalizing_constant + (m_horz_sync_width << 1)) << 1;
|
||||
int horiz_pix_total = horiz_chars_total * m_hpixels_per_column;
|
||||
int vert_pix_total = m_rows_per_screen * m_scanline_per_char_row + m_vert_front_porch + m_vert_back_porch + m_vsync_width;
|
||||
@ -932,12 +961,6 @@ void scn2674_device::recompute_parameters()
|
||||
int max_visible_x = (m_character_per_row * m_hpixels_per_column) - 1;
|
||||
int max_visible_y = (m_rows_per_screen * m_scanline_per_char_row) - 1;
|
||||
|
||||
if (!horiz_pix_total || !vert_pix_total)
|
||||
{
|
||||
m_scanline_timer->adjust(attotime::never);
|
||||
return;
|
||||
}
|
||||
|
||||
//attoseconds_t refresh = clocks_to_attotime(horiz_chars_total * vert_pix_total).as_attoseconds();
|
||||
LOGMASKED(LOG_IR, "width %u height %u max_x %u max_y %u refresh %f\n", horiz_pix_total, vert_pix_total, max_visible_x, max_visible_y, ATTOSECONDS_TO_HZ(refresh));
|
||||
|
||||
@ -996,7 +1019,11 @@ void scn2674_device::device_timer(emu_timer &timer, device_timer_id id, int para
|
||||
m_irq_register |= 0x08;
|
||||
m_intr_cb(ASSERT_LINE);
|
||||
}
|
||||
if (m_buffer_mode_select == 3)
|
||||
m_breq_cb(ASSERT_LINE);
|
||||
}
|
||||
else if (m_buffer_mode_select == 3)
|
||||
m_breq_cb(CLEAR_LINE);
|
||||
|
||||
// Handle screen splits
|
||||
for (int s = 0; s < 2; s++)
|
||||
|
@ -22,7 +22,9 @@ public:
|
||||
|
||||
// static configuration
|
||||
auto intr_callback() { return m_intr_cb.bind(); }
|
||||
auto breq_callback() { return m_breq_cb.bind(); }
|
||||
void set_character_width(int value) { m_hpixels_per_column = value; }
|
||||
|
||||
template <class FunctionClass>
|
||||
void set_display_callback(void (FunctionClass::*callback)(bitmap_rgb32 &, int, int, uint8_t, uint8_t, uint8_t, uint16_t, bool, bool, bool, bool, bool), const char *name)
|
||||
{
|
||||
@ -59,6 +61,7 @@ protected:
|
||||
//protected:
|
||||
bitmap_rgb32 m_bitmap;
|
||||
devcb_write_line m_intr_cb;
|
||||
devcb_write_line m_breq_cb;
|
||||
|
||||
uint8_t m_IR_pointer;
|
||||
uint16_t m_screen1_address;
|
||||
|
@ -21,6 +21,7 @@ public:
|
||||
qvt201_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_maincpu(*this, "maincpu")
|
||||
, m_mainnmi(*this, "mainnmi")
|
||||
, m_eia(*this, "eia")
|
||||
, m_screen(*this, "screen")
|
||||
, m_p_chargen(*this, "chargen")
|
||||
@ -40,6 +41,7 @@ private:
|
||||
void mem_map(address_map &map);
|
||||
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<input_merger_device> m_mainnmi;
|
||||
required_device<rs232_port_device> m_eia;
|
||||
required_device<screen_device> m_screen;
|
||||
required_region_ptr<u8> m_p_chargen;
|
||||
@ -73,11 +75,12 @@ WRITE8_MEMBER(qvt201_state::duart_out_w)
|
||||
// OP3 = 132/_80
|
||||
// OP4 = SRV
|
||||
// OP5 = BLOCK/_UL
|
||||
// OP6 = preset NMI flipflop
|
||||
// OP6 = preset MBC NMI flipflop
|
||||
// OP7 = _DATA/TALK (EIA pin 14)
|
||||
|
||||
m_eia->write_rts(BIT(data, 0));
|
||||
m_eia->write_dtr(BIT(data, 1));
|
||||
m_mainnmi->in_w<1>(!BIT(data, 6));
|
||||
}
|
||||
|
||||
void qvt201_state::mem_map(address_map &map)
|
||||
@ -100,8 +103,11 @@ MACHINE_CONFIG_START(qvt201_state::qvt201)
|
||||
MCFG_DEVICE_ADD("maincpu", Z80, 3.6864_MHz_XTAL)
|
||||
MCFG_DEVICE_PROGRAM_MAP(mem_map) // IORQ is not used at all
|
||||
|
||||
MCFG_INPUT_MERGER_ANY_HIGH("mainint") // open collector
|
||||
MCFG_INPUT_MERGER_OUTPUT_HANDLER(INPUTLINE("maincpu", 0))
|
||||
input_merger_device &mainint(INPUT_MERGER_ANY_HIGH(config, "mainint")); // open collector
|
||||
mainint.output_handler().set_inputline("maincpu", INPUT_LINE_IRQ0);
|
||||
|
||||
input_merger_device &mainnmi(INPUT_MERGER_ALL_HIGH(config, "mainnmi"));
|
||||
mainnmi.output_handler().set_inputline("maincpu", INPUT_LINE_NMI);
|
||||
|
||||
MCFG_DEVICE_ADD("duart", SCN2681, 3.6864_MHz_XTAL) // XTAL not directly connected
|
||||
MCFG_MC68681_IRQ_CALLBACK(WRITELINE("mainint", input_merger_device, in_w<1>))
|
||||
@ -126,6 +132,7 @@ MACHINE_CONFIG_START(qvt201_state::qvt201)
|
||||
scn2672_device &crtc(SCN2672(config, "crtc", 48.654_MHz_XTAL / 30));
|
||||
crtc.set_character_width(10); // 9 in 132-column mode
|
||||
crtc.intr_callback().set("mainint", FUNC(input_merger_device::in_w<0>));
|
||||
crtc.breq_callback().set("mainnmi", FUNC(input_merger_device::in_w<0>));
|
||||
crtc.set_screen("screen");
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user