novagbase: separate classes (nw)

This commit is contained in:
hap 2019-02-20 21:45:03 +01:00
parent 064050323e
commit dc7fdc367c
6 changed files with 215 additions and 162 deletions

View File

@ -10,7 +10,8 @@ As workaround for the chess games, use an external chess GUI on the side,
such as Arena(in editmode). such as Arena(in editmode).
TODO: (see each driver for more specific) TODO: (see each driver for more specific)
- verify cpu speed and rom labels where unknown - verify cpu speed and rom labels where uncertain
- support for printer
- improve EAS/SC12/etc CPU divider? it seems a little bit slower than the real machine. - improve EAS/SC12/etc CPU divider? it seems a little bit slower than the real machine.
Currently, a dummy timer workaround is needed, or it's much worse. Currently, a dummy timer workaround is needed, or it's much worse.
Is the problem here is due to timing of CPU addressbus changes? We can only 'sense' Is the problem here is due to timing of CPU addressbus changes? We can only 'sense'

View File

@ -84,7 +84,7 @@ WRITE8_MEMBER(delta1_state::io0_w)
// update display here // update display here
set_display_segmask(0xf, 0x7f); set_display_segmask(0xf, 0x7f);
display_matrix(7, 4, m_led_data, sel >> 4); display_matrix(7, 4, m_7seg_data, sel >> 4);
} }
READ8_MEMBER(delta1_state::io0_r) READ8_MEMBER(delta1_state::io0_r)
@ -100,7 +100,7 @@ WRITE8_MEMBER(delta1_state::io1_w)
// IO17: segment commons, active low (always 0?) // IO17: segment commons, active low (always 0?)
// IO10-16: digit segments A-G // IO10-16: digit segments A-G
data = (data & 0x80) ? 0 : (data & 0x7f); data = (data & 0x80) ? 0 : (data & 0x7f);
m_led_data = bitswap<7>(data, 0,1,2,3,4,5,6); m_7seg_data = bitswap<7>(data, 0,1,2,3,4,5,6);
} }
READ8_MEMBER(delta1_state::io1_r) READ8_MEMBER(delta1_state::io1_r)

View File

@ -205,8 +205,8 @@ INPUT_PORTS_END
Machine Drivers Machine Drivers
******************************************************************************/ ******************************************************************************/
MACHINE_CONFIG_START(diablo_state::diablo68k) void diablo_state::diablo68k(machine_config &config)
{
/* basic machine hardware */ /* basic machine hardware */
M68000(config, m_maincpu, 16_MHz_XTAL); M68000(config, m_maincpu, 16_MHz_XTAL);
m_maincpu->set_addrmap(AS_PROGRAM, &diablo_state::diablo68k_map); m_maincpu->set_addrmap(AS_PROGRAM, &diablo_state::diablo68k_map);
@ -222,13 +222,14 @@ MACHINE_CONFIG_START(diablo_state::diablo68k)
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
/* video hardware */ /* video hardware */
MCFG_SCREEN_ADD("screen", LCD) screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_LCD));
MCFG_SCREEN_REFRESH_RATE(60) // arbitrary screen.set_refresh_hz(60); // arbitrary
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500));
MCFG_SCREEN_SIZE(6*16+1, 10) screen.set_size(6*16+1, 10);
MCFG_SCREEN_VISIBLE_AREA(0, 6*16, 0, 10-1) screen.set_visarea(0, 6*16, 0, 10-1);
MCFG_SCREEN_UPDATE_DEVICE("hd44780", hd44780_device, screen_update) screen.set_screen_update("hd44780", FUNC(hd44780_device::screen_update));
MCFG_SCREEN_PALETTE("palette") screen.set_palette("palette");
PALETTE(config, "palette", FUNC(diablo_state::novag_lcd_palette), 3); PALETTE(config, "palette", FUNC(diablo_state::novag_lcd_palette), 3);
HD44780(config, m_lcd, 0); HD44780(config, m_lcd, 0);
@ -242,7 +243,7 @@ MACHINE_CONFIG_START(diablo_state::diablo68k)
SPEAKER(config, "mono").front_center(); SPEAKER(config, "mono").front_center();
BEEP(config, m_beeper, 32.768_kHz_XTAL/32); // 1024Hz BEEP(config, m_beeper, 32.768_kHz_XTAL/32); // 1024Hz
m_beeper->add_route(ALL_OUTPUTS, "mono", 0.25); m_beeper->add_route(ALL_OUTPUTS, "mono", 0.25);
MACHINE_CONFIG_END }
void diablo_state::scorpio68k(machine_config &config) void diablo_state::scorpio68k(machine_config &config)
{ {

View File

@ -3,19 +3,19 @@
// thanks-to:Berger // thanks-to:Berger
/****************************************************************************** /******************************************************************************
Novag generic 6502 based chess computer driver Novag chess computer driver base class
NOTE: MAME doesn't include a generalized implementation for boardpieces yet, NOTE: MAME doesn't include a generalized implementation for boardpieces yet,
greatly affecting user playability of emulated electronic board games. greatly affecting user playability of emulated electronic board games.
As workaround for the chess games, use an external chess GUI on the side, As workaround for the chess games, use an external chess GUI on the side,
such as Arena(in editmode). such as Arena(in editmode).
TODO: TODO:
- cforte ACIA? - printer port
- verify supercon IRQ and beeper frequency
- sforte irq active time (21.5us is too long) - verify supercon IRQ and beeper frequency
- sforte/sexpert led handling is correct? - sforte irq active time (21.5us is too long)
- printer port - sforte/sexpert led handling is correct?
******************************************************************************* *******************************************************************************
@ -34,8 +34,7 @@ Constellation Forte:
- HLCD0538P, 10-digit 7seg LCD display - HLCD0538P, 10-digit 7seg LCD display
- TTL, 18 LEDs, 8*8 chessboard buttons - TTL, 18 LEDs, 8*8 chessboard buttons
When it was first added to MAME as skeleton driver in mmodular.c, cforteb romset I/O is similar to supercon
was assumed to be Super Forte B, but it definitely isn't. I/O is similar to supercon.
******************************************************************************* *******************************************************************************
@ -49,6 +48,7 @@ Super Expert (model 878/887/902):
- printer port, magnetic sensors, 8*8 chessboard leds - printer port, magnetic sensors, 8*8 chessboard leds
I/O via TTL, hardware design was very awkward. I/O via TTL, hardware design was very awkward.
Super Forte is very similar, just a cheaper plastic case and chessboard buttons Super Forte is very similar, just a cheaper plastic case and chessboard buttons
instead of magnet sensors. instead of magnet sensors.
@ -74,43 +74,21 @@ instead of magnet sensors.
#include "novag_supercon.lh" // clickable #include "novag_supercon.lh" // clickable
class novag6502_state : public novagbase_state class sexpert_state : public novagbase_state
{ {
public: public:
novag6502_state(const machine_config &mconfig, device_type type, const char *tag) : sexpert_state(const machine_config &mconfig, device_type type, const char *tag) :
novagbase_state(mconfig, type, tag), novagbase_state(mconfig, type, tag)
m_hlcd0538(*this, "hlcd0538"),
m_rombank(*this, "rombank")
{ } { }
void supercon(machine_config &config);
void cforte(machine_config &config);
void sforte_map(address_map &map);
void sexpert(machine_config &config); void sexpert(machine_config &config);
void sforte(machine_config &config); void sforte(machine_config &config);
void init_sexpert(); void init_sexpert();
DECLARE_INPUT_CHANGED_MEMBER(sexpert_cpu_freq); DECLARE_INPUT_CHANGED_MEMBER(sexpert_cpu_freq) { sexpert_set_cpu_freq(); }
private: private:
optional_device<hlcd0538_device> m_hlcd0538;
optional_memory_bank m_rombank;
// Super Constellation
DECLARE_WRITE8_MEMBER(supercon_mux_w);
DECLARE_WRITE8_MEMBER(supercon_control_w);
DECLARE_READ8_MEMBER(supercon_input1_r);
DECLARE_READ8_MEMBER(supercon_input2_r);
void supercon_map(address_map &map);
// Constellation Forte
void cforte_prepare_display();
DECLARE_WRITE64_MEMBER(cforte_lcd_output_w);
DECLARE_WRITE8_MEMBER(cforte_mux_w);
DECLARE_WRITE8_MEMBER(cforte_control_w);
void cforte_map(address_map &map);
// Super Expert // Super Expert
DECLARE_WRITE8_MEMBER(sexpert_leds_w); DECLARE_WRITE8_MEMBER(sexpert_leds_w);
DECLARE_WRITE8_MEMBER(sexpert_mux_w); DECLARE_WRITE8_MEMBER(sexpert_mux_w);
@ -125,6 +103,73 @@ private:
// Super Forte // Super Forte
DECLARE_WRITE8_MEMBER(sforte_lcd_control_w); DECLARE_WRITE8_MEMBER(sforte_lcd_control_w);
DECLARE_WRITE8_MEMBER(sforte_lcd_data_w); DECLARE_WRITE8_MEMBER(sforte_lcd_data_w);
void sforte_map(address_map &map);
protected:
virtual void machine_reset() override;
};
void sexpert_state::sexpert_set_cpu_freq()
{
// machines were released with either 5MHz or 6MHz CPU
m_maincpu->set_unscaled_clock((ioport("FAKE")->read() & 1) ? (12_MHz_XTAL/2) : (10_MHz_XTAL/2));
}
void sexpert_state::machine_reset()
{
novagbase_state::machine_reset();
sexpert_set_cpu_freq();
m_rombank->set_entry(0);
}
void sexpert_state::init_sexpert()
{
m_rombank->configure_entries(0, 2, memregion("maincpu")->base() + 0x8000, 0x8000);
}
class cforte_state : public novagbase_state
{
public:
cforte_state(const machine_config &mconfig, device_type type, const char *tag) :
novagbase_state(mconfig, type, tag),
m_hlcd0538(*this, "hlcd0538")
{ }
void cforte(machine_config &config);
private:
optional_device<hlcd0538_device> m_hlcd0538;
// Constellation Forte
void cforte_prepare_display();
DECLARE_WRITE64_MEMBER(cforte_lcd_output_w);
DECLARE_WRITE8_MEMBER(cforte_mux_w);
DECLARE_WRITE8_MEMBER(cforte_control_w);
DECLARE_READ8_MEMBER(cforte_input1_r);
DECLARE_READ8_MEMBER(cforte_input2_r);
void cforte_map(address_map &map);
};
class scon_state : public novagbase_state
{
public:
scon_state(const machine_config &mconfig, device_type type, const char *tag) :
novagbase_state(mconfig, type, tag)
{ }
void supercon(machine_config &config);
private:
// Super Constellation
DECLARE_WRITE8_MEMBER(supercon_mux_w);
DECLARE_WRITE8_MEMBER(supercon_control_w);
DECLARE_READ8_MEMBER(supercon_input1_r);
DECLARE_READ8_MEMBER(supercon_input2_r);
void supercon_map(address_map &map);
}; };
@ -145,6 +190,7 @@ void novagbase_state::machine_start()
m_inp_mux = 0; m_inp_mux = 0;
m_led_select = 0; m_led_select = 0;
m_led_data = 0; m_led_data = 0;
m_7seg_data = 0;
m_lcd_control = 0; m_lcd_control = 0;
m_lcd_data = 0; m_lcd_data = 0;
@ -160,6 +206,7 @@ void novagbase_state::machine_start()
save_item(NAME(m_inp_mux)); save_item(NAME(m_inp_mux));
save_item(NAME(m_led_select)); save_item(NAME(m_led_select));
save_item(NAME(m_led_data)); save_item(NAME(m_led_data));
save_item(NAME(m_7seg_data));
save_item(NAME(m_lcd_control)); save_item(NAME(m_lcd_control));
save_item(NAME(m_lcd_data)); save_item(NAME(m_lcd_data));
} }
@ -297,14 +344,14 @@ u16 novagbase_state::read_inputs(int columns)
// TTL // TTL
WRITE8_MEMBER(novag6502_state::supercon_mux_w) WRITE8_MEMBER(scon_state::supercon_mux_w)
{ {
// d0-d7: input mux, led data // d0-d7: input mux, led data
m_inp_mux = m_led_data = data; m_inp_mux = m_led_data = data;
display_matrix(8, 3, m_led_data, m_led_select); display_matrix(8, 3, m_led_data, m_led_select);
} }
WRITE8_MEMBER(novag6502_state::supercon_control_w) WRITE8_MEMBER(scon_state::supercon_control_w)
{ {
// d0-d3: ? // d0-d3: ?
// d4-d6: select led row // d4-d6: select led row
@ -315,13 +362,13 @@ WRITE8_MEMBER(novag6502_state::supercon_control_w)
m_beeper->set_state(data >> 7 & 1); m_beeper->set_state(data >> 7 & 1);
} }
READ8_MEMBER(novag6502_state::supercon_input1_r) READ8_MEMBER(scon_state::supercon_input1_r)
{ {
// d0-d7: multiplexed inputs (chessboard squares) // d0-d7: multiplexed inputs (chessboard squares)
return ~read_inputs(8) & 0xff; return ~read_inputs(8) & 0xff;
} }
READ8_MEMBER(novag6502_state::supercon_input2_r) READ8_MEMBER(scon_state::supercon_input2_r)
{ {
// d0-d5: ? // d0-d5: ?
// d6,d7: multiplexed inputs (side panel) // d6,d7: multiplexed inputs (side panel)
@ -336,7 +383,7 @@ READ8_MEMBER(novag6502_state::supercon_input2_r)
// TTL/generic // TTL/generic
void novag6502_state::cforte_prepare_display() void cforte_state::cforte_prepare_display()
{ {
// 3 led rows // 3 led rows
display_matrix(8, 3, m_led_data, m_led_select, false); display_matrix(8, 3, m_led_data, m_led_select, false);
@ -347,7 +394,7 @@ void novag6502_state::cforte_prepare_display()
display_update(); display_update();
} }
WRITE64_MEMBER(novag6502_state::cforte_lcd_output_w) WRITE64_MEMBER(cforte_state::cforte_lcd_output_w)
{ {
// 4 rows used // 4 rows used
u32 rowdata[4]; u32 rowdata[4];
@ -367,14 +414,14 @@ WRITE64_MEMBER(novag6502_state::cforte_lcd_output_w)
cforte_prepare_display(); cforte_prepare_display();
} }
WRITE8_MEMBER(novag6502_state::cforte_mux_w) WRITE8_MEMBER(cforte_state::cforte_mux_w)
{ {
// d0-d7: input mux, led data // d0-d7: input mux, led data
m_inp_mux = m_led_data = data; m_inp_mux = m_led_data = data;
cforte_prepare_display(); cforte_prepare_display();
} }
WRITE8_MEMBER(novag6502_state::cforte_control_w) WRITE8_MEMBER(cforte_state::cforte_control_w)
{ {
// d0: HLCD0538 data in // d0: HLCD0538 data in
// d1: HLCD0538 clk // d1: HLCD0538 clk
@ -393,6 +440,18 @@ WRITE8_MEMBER(novag6502_state::cforte_control_w)
m_beeper->set_state(data >> 7 & 1); m_beeper->set_state(data >> 7 & 1);
} }
READ8_MEMBER(cforte_state::cforte_input1_r)
{
// d0-d7: multiplexed inputs (chessboard squares)
return ~read_inputs(8) & 0xff;
}
READ8_MEMBER(cforte_state::cforte_input2_r)
{
// d0-d5: ?
// d6,d7: multiplexed inputs (side panel)
return (read_inputs(8) >> 2 & 0xc0) ^ 0xff;
}
/****************************************************************************** /******************************************************************************
@ -401,7 +460,7 @@ WRITE8_MEMBER(novag6502_state::cforte_control_w)
// TTL/generic // TTL/generic
WRITE8_MEMBER(novag6502_state::sexpert_lcd_control_w) WRITE8_MEMBER(sexpert_state::sexpert_lcd_control_w)
{ {
// d0: HD44780 RS // d0: HD44780 RS
// d1: HD44780 R/W // d1: HD44780 R/W
@ -411,19 +470,19 @@ WRITE8_MEMBER(novag6502_state::sexpert_lcd_control_w)
m_lcd_control = data & 7; m_lcd_control = data & 7;
} }
WRITE8_MEMBER(novag6502_state::sexpert_lcd_data_w) WRITE8_MEMBER(sexpert_state::sexpert_lcd_data_w)
{ {
// d0-d7: HD44780 data // d0-d7: HD44780 data
m_lcd_data = data; m_lcd_data = data;
} }
WRITE8_MEMBER(novag6502_state::sexpert_leds_w) WRITE8_MEMBER(sexpert_state::sexpert_leds_w)
{ {
// d0-d7: chessboard leds // d0-d7: chessboard leds
m_led_data = data; m_led_data = data;
} }
WRITE8_MEMBER(novag6502_state::sexpert_mux_w) WRITE8_MEMBER(sexpert_state::sexpert_mux_w)
{ {
// d0: rom bankswitch // d0: rom bankswitch
m_rombank->set_entry(data & 1); m_rombank->set_entry(data & 1);
@ -437,37 +496,19 @@ WRITE8_MEMBER(novag6502_state::sexpert_mux_w)
m_led_data = 0; // ? m_led_data = 0; // ?
} }
READ8_MEMBER(novag6502_state::sexpert_input1_r) READ8_MEMBER(sexpert_state::sexpert_input1_r)
{ {
// d0-d7: multiplexed inputs (chessboard squares) // d0-d7: multiplexed inputs (chessboard squares)
return ~read_inputs(8) & 0xff; return ~read_inputs(8) & 0xff;
} }
READ8_MEMBER(novag6502_state::sexpert_input2_r) READ8_MEMBER(sexpert_state::sexpert_input2_r)
{ {
// d0-d2: printer port // d0-d2: printer port
// d5-d7: multiplexed inputs (side panel) // d5-d7: multiplexed inputs (side panel)
return ~read_inputs(8) >> 3 & 0xe0; return ~read_inputs(8) >> 3 & 0xe0;
} }
void novag6502_state::sexpert_set_cpu_freq()
{
// machines were released with either 5MHz or 6MHz CPU
m_maincpu->set_unscaled_clock((ioport("FAKE")->read() & 1) ? (12_MHz_XTAL/2) : (10_MHz_XTAL/2));
}
MACHINE_RESET_MEMBER(novag6502_state, sexpert)
{
novagbase_state::machine_reset();
sexpert_set_cpu_freq();
m_rombank->set_entry(0);
}
void novag6502_state::init_sexpert()
{
m_rombank->configure_entries(0, 2, memregion("maincpu")->base() + 0x8000, 0x8000);
}
@ -475,16 +516,16 @@ void novag6502_state::init_sexpert()
Super Forte Super Forte
******************************************************************************/ ******************************************************************************/
WRITE8_MEMBER(novag6502_state::sforte_lcd_control_w) WRITE8_MEMBER(sexpert_state::sforte_lcd_control_w)
{ {
// d3: rom bankswitch // d3: rom bankswitch
m_rombank->set_entry(data >> 3 & 1); m_rombank->set_entry(data >> 3 & 1);
// assume same as sexpert // assume same as sexpert
sexpert_lcd_control_w(space, 0, data); sexpert_lcd_control_w(space, offset, data);
} }
WRITE8_MEMBER(novag6502_state::sforte_lcd_data_w) WRITE8_MEMBER(sexpert_state::sforte_lcd_data_w)
{ {
// d0-d2: input mux/led select // d0-d2: input mux/led select
m_inp_mux = 1 << (data & 7); m_inp_mux = 1 << (data & 7);
@ -501,7 +542,7 @@ WRITE8_MEMBER(novag6502_state::sforte_lcd_data_w)
} }
// assume same as sexpert // assume same as sexpert
sexpert_lcd_data_w(space, 0, data); sexpert_lcd_data_w(space, offset, data);
} }
@ -512,47 +553,59 @@ WRITE8_MEMBER(novag6502_state::sforte_lcd_data_w)
// Super Constellation / Constellation Forte // Super Constellation / Constellation Forte
void novag6502_state::supercon_map(address_map &map) void scon_state::supercon_map(address_map &map)
{ {
map(0x0000, 0x0fff).ram().share("nvram"); map(0x0000, 0x0fff).ram().share("nvram");
map(0x1c00, 0x1c00).nopw(); // printer/clock? map(0x1c00, 0x1c00).nopw(); // printer/clock?
map(0x1d00, 0x1d00).nopw(); // printer/clock? map(0x1d00, 0x1d00).nopw(); // printer/clock?
map(0x1e00, 0x1e00).rw(FUNC(novag6502_state::supercon_input2_r), FUNC(novag6502_state::supercon_mux_w)); map(0x1e00, 0x1e00).rw(FUNC(scon_state::supercon_input2_r), FUNC(scon_state::supercon_mux_w));
map(0x1f00, 0x1f00).rw(FUNC(novag6502_state::supercon_input1_r), FUNC(novag6502_state::supercon_control_w)); map(0x1f00, 0x1f00).rw(FUNC(scon_state::supercon_input1_r), FUNC(scon_state::supercon_control_w));
map(0x2000, 0xffff).rom(); map(0x2000, 0xffff).rom();
} }
void novag6502_state::cforte_map(address_map &map) void cforte_state::cforte_map(address_map &map)
{ {
supercon_map(map); map(0x0000, 0x0fff).ram().share("nvram");
map(0x1e00, 0x1e00).rw(FUNC(novag6502_state::supercon_input2_r), FUNC(novag6502_state::cforte_mux_w)); map(0x1c00, 0x1c00).nopw(); // printer?
map(0x1f00, 0x1f00).rw(FUNC(novag6502_state::supercon_input1_r), FUNC(novag6502_state::cforte_control_w)); map(0x1d00, 0x1d00).nopw(); // printer?
map(0x1e00, 0x1e00).rw(FUNC(cforte_state::cforte_input2_r), FUNC(cforte_state::cforte_mux_w));
map(0x1f00, 0x1f00).rw(FUNC(cforte_state::cforte_input1_r), FUNC(cforte_state::cforte_control_w));
map(0x2000, 0xffff).rom();
} }
// Super Expert / Super Forte // Super Expert / Super Forte
void novag6502_state::sforte_map(address_map &map) void sexpert_state::sforte_map(address_map &map)
{ {
map(0x0000, 0x1fef).ram().share("nvram"); // 8KB RAM, but RAM CE pin is deactivated on $1ff0-$1fff map(0x0000, 0x1fef).ram().share("nvram"); // 8KB RAM, but RAM CE pin is deactivated on $1ff0-$1fff
map(0x1ff0, 0x1ff0).r(FUNC(novag6502_state::sexpert_input1_r)); map(0x1ff0, 0x1ff0).r(FUNC(sexpert_state::sexpert_input1_r));
map(0x1ff1, 0x1ff1).r(FUNC(novag6502_state::sexpert_input2_r)); map(0x1ff1, 0x1ff1).r(FUNC(sexpert_state::sexpert_input2_r));
map(0x1ff2, 0x1ff2).nopw(); // printer map(0x1ff2, 0x1ff2).nopw(); // printer
map(0x1ff3, 0x1ff3).nopw(); // printer map(0x1ff3, 0x1ff3).nopw(); // printer
map(0x1ff6, 0x1ff6).w(FUNC(novag6502_state::sforte_lcd_control_w)); map(0x1ff4, 0x1ff4).nopw();
map(0x1ff7, 0x1ff7).w(FUNC(novag6502_state::sforte_lcd_data_w)); map(0x1ff5, 0x1ff5).nopw();
map(0x1ff6, 0x1ff6).w(FUNC(sexpert_state::sforte_lcd_control_w));
map(0x1ff7, 0x1ff7).w(FUNC(sexpert_state::sforte_lcd_data_w));
map(0x1ffc, 0x1fff).rw("acia", FUNC(mos6551_device::read), FUNC(mos6551_device::write)); map(0x1ffc, 0x1fff).rw("acia", FUNC(mos6551_device::read), FUNC(mos6551_device::write));
map(0x2000, 0x7fff).rom(); map(0x2000, 0x7fff).rom();
map(0x8000, 0xffff).bankr("rombank"); map(0x8000, 0xffff).bankr("rombank");
} }
void novag6502_state::sexpert_map(address_map &map) void sexpert_state::sexpert_map(address_map &map)
{ {
sforte_map(map); map(0x0000, 0x1fef).ram().share("nvram"); // 8KB RAM, but RAM CE pin is deactivated on $1ff0-$1fff
map(0x1ff4, 0x1ff4).w(FUNC(novag6502_state::sexpert_leds_w)); map(0x1ff0, 0x1ff0).r(FUNC(sexpert_state::sexpert_input1_r));
map(0x1ff5, 0x1ff5).w(FUNC(novag6502_state::sexpert_mux_w)); map(0x1ff1, 0x1ff1).r(FUNC(sexpert_state::sexpert_input2_r));
map(0x1ff6, 0x1ff6).w(FUNC(novag6502_state::sexpert_lcd_control_w)); map(0x1ff2, 0x1ff2).nopw(); // printer
map(0x1ff7, 0x1ff7).w(FUNC(novag6502_state::sexpert_lcd_data_w)); map(0x1ff3, 0x1ff3).nopw(); // printer
map(0x1ff4, 0x1ff4).w(FUNC(sexpert_state::sexpert_leds_w));
map(0x1ff5, 0x1ff5).w(FUNC(sexpert_state::sexpert_mux_w));
map(0x1ff6, 0x1ff6).w(FUNC(sexpert_state::sexpert_lcd_control_w));
map(0x1ff7, 0x1ff7).w(FUNC(sexpert_state::sexpert_lcd_data_w));
map(0x1ffc, 0x1fff).rw("acia", FUNC(mos6551_device::read), FUNC(mos6551_device::write));
map(0x2000, 0x7fff).rom();
map(0x8000, 0xffff).bankr("rombank");
} }
@ -842,15 +895,11 @@ static INPUT_PORTS_START( sexy_shared )
PORT_BIT(0x400, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_8) PORT_NAME("Print Board / Interface") PORT_BIT(0x400, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_8) PORT_NAME("Print Board / Interface")
PORT_START("FAKE") PORT_START("FAKE")
PORT_CONFNAME( 0x01, 0x00, "CPU Frequency" ) PORT_CHANGED_MEMBER(DEVICE_SELF, novag6502_state, sexpert_cpu_freq, nullptr) // factory set PORT_CONFNAME( 0x01, 0x00, "CPU Frequency" ) PORT_CHANGED_MEMBER(DEVICE_SELF, sexpert_state, sexpert_cpu_freq, nullptr) // factory set
PORT_CONFSETTING( 0x00, "5MHz" ) PORT_CONFSETTING( 0x00, "5MHz" )
PORT_CONFSETTING( 0x01, "6MHz" ) PORT_CONFSETTING( 0x01, "6MHz" )
INPUT_PORTS_END INPUT_PORTS_END
INPUT_CHANGED_MEMBER(novag6502_state::sexpert_cpu_freq)
{
sexpert_set_cpu_freq();
}
static INPUT_PORTS_START( sexpert ) static INPUT_PORTS_START( sexpert )
PORT_INCLUDE( novag_cb_magnets ) PORT_INCLUDE( novag_cb_magnets )
@ -868,60 +917,60 @@ INPUT_PORTS_END
Machine Drivers Machine Drivers
******************************************************************************/ ******************************************************************************/
MACHINE_CONFIG_START(novag6502_state::supercon) void scon_state::supercon(machine_config &config)
{
/* basic machine hardware */ /* basic machine hardware */
MCFG_DEVICE_ADD("maincpu", M6502, 8_MHz_XTAL/2) M6502(config, m_maincpu, 8_MHz_XTAL/2);
MCFG_DEVICE_PERIODIC_INT_DRIVER(novag6502_state, irq0_line_hold, 600) // guessed m_maincpu->set_addrmap(AS_PROGRAM, &scon_state::supercon_map);
MCFG_DEVICE_PROGRAM_MAP(supercon_map) m_maincpu->set_periodic_int(FUNC(scon_state::irq0_line_hold), attotime::from_hz(600)); // guessed
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_1); NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_1);
TIMER(config, "display_decay").configure_periodic(FUNC(novag6502_state::display_decay_tick), attotime::from_msec(1)); TIMER(config, "display_decay").configure_periodic(FUNC(scon_state::display_decay_tick), attotime::from_msec(1));
config.set_default_layout(layout_novag_supercon); config.set_default_layout(layout_novag_supercon);
/* sound hardware */ /* sound hardware */
SPEAKER(config, "mono").front_center(); SPEAKER(config, "mono").front_center();
BEEP(config, m_beeper, 1024); // guessed BEEP(config, m_beeper, 1024); // guessed
m_beeper->add_route(ALL_OUTPUTS, "mono", 0.25); m_beeper->add_route(ALL_OUTPUTS, "mono", 0.25);
MACHINE_CONFIG_END }
MACHINE_CONFIG_START(novag6502_state::cforte)
void cforte_state::cforte(machine_config &config)
{
/* basic machine hardware */ /* basic machine hardware */
MCFG_DEVICE_ADD("maincpu", R65C02, 10_MHz_XTAL/2) R65C02(config, m_maincpu, 10_MHz_XTAL/2);
MCFG_DEVICE_PROGRAM_MAP(cforte_map) m_maincpu->set_addrmap(AS_PROGRAM, &cforte_state::cforte_map);
const attotime irq_period = attotime::from_hz(32.768_kHz_XTAL/128); // 256Hz const attotime irq_period = attotime::from_hz(32.768_kHz_XTAL/128); // 256Hz
TIMER(config, m_irq_on).configure_periodic(FUNC(novag6502_state::irq_on<M6502_IRQ_LINE>), irq_period); TIMER(config, m_irq_on).configure_periodic(FUNC(cforte_state::irq_on<M6502_IRQ_LINE>), irq_period);
m_irq_on->set_start_delay(irq_period - attotime::from_usec(11)); // active for 11us m_irq_on->set_start_delay(irq_period - attotime::from_usec(11)); // active for 11us
TIMER(config, "irq_off").configure_periodic(FUNC(novag6502_state::irq_off<M6502_IRQ_LINE>), irq_period); TIMER(config, "irq_off").configure_periodic(FUNC(cforte_state::irq_off<M6502_IRQ_LINE>), irq_period);
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_1); NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_1);
/* video hardware */ /* video hardware */
HLCD0538(config, m_hlcd0538, 0); HLCD0538(config, m_hlcd0538, 0);
m_hlcd0538->write_cols_callback().set(FUNC(novag6502_state::cforte_lcd_output_w)); m_hlcd0538->write_cols_callback().set(FUNC(cforte_state::cforte_lcd_output_w));
TIMER(config, "display_decay").configure_periodic(FUNC(novag6502_state::display_decay_tick), attotime::from_msec(1)); TIMER(config, "display_decay").configure_periodic(FUNC(cforte_state::display_decay_tick), attotime::from_msec(1));
config.set_default_layout(layout_novag_cforte); config.set_default_layout(layout_novag_cforte);
/* sound hardware */ /* sound hardware */
SPEAKER(config, "mono").front_center(); SPEAKER(config, "mono").front_center();
BEEP(config, m_beeper, 32.768_kHz_XTAL/32); // 1024Hz BEEP(config, m_beeper, 32.768_kHz_XTAL/32); // 1024Hz
m_beeper->add_route(ALL_OUTPUTS, "mono", 0.25); m_beeper->add_route(ALL_OUTPUTS, "mono", 0.25);
MACHINE_CONFIG_END }
MACHINE_CONFIG_START(novag6502_state::sexpert)
void sexpert_state::sexpert(machine_config &config)
{
/* basic machine hardware */ /* basic machine hardware */
MCFG_DEVICE_ADD("maincpu", M65C02, 10_MHz_XTAL/2) // or 12_MHz_XTAL/2 M65C02(config, m_maincpu, 10_MHz_XTAL/2); // or 12_MHz_XTAL/2
MCFG_DEVICE_PROGRAM_MAP(sexpert_map) m_maincpu->set_addrmap(AS_PROGRAM, &sexpert_state::sexpert_map);
const attotime irq_period = attotime::from_hz(32.768_kHz_XTAL/128); // 256Hz const attotime irq_period = attotime::from_hz(32.768_kHz_XTAL/128); // 256Hz
TIMER(config, m_irq_on).configure_periodic(FUNC(novag6502_state::irq_on<M6502_IRQ_LINE>), irq_period); TIMER(config, m_irq_on).configure_periodic(FUNC(sexpert_state::irq_on<M6502_IRQ_LINE>), irq_period);
m_irq_on->set_start_delay(irq_period - attotime::from_nsec(21500)); // active for 21.5us m_irq_on->set_start_delay(irq_period - attotime::from_nsec(21500)); // active for 21.5us
TIMER(config, "irq_off").configure_periodic(FUNC(novag6502_state::irq_off<M6502_IRQ_LINE>), irq_period); TIMER(config, "irq_off").configure_periodic(FUNC(sexpert_state::irq_off<M6502_IRQ_LINE>), irq_period);
mos6551_device &acia(MOS6551(config, "acia", 0)); // R65C51P2 - RTS to CTS, DCD to GND mos6551_device &acia(MOS6551(config, "acia", 0)); // R65C51P2 - RTS to CTS, DCD to GND
acia.set_xtal(1.8432_MHz_XTAL); acia.set_xtal(1.8432_MHz_XTAL);
@ -936,42 +985,41 @@ MACHINE_CONFIG_START(novag6502_state::sexpert)
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_1); NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_1);
MCFG_MACHINE_RESET_OVERRIDE(novag6502_state, sexpert)
/* video hardware */ /* video hardware */
MCFG_SCREEN_ADD("screen", LCD) screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_LCD));
MCFG_SCREEN_REFRESH_RATE(60) // arbitrary screen.set_refresh_hz(60); // arbitrary
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500));
MCFG_SCREEN_SIZE(6*16+1, 10) screen.set_size(6*16+1, 10);
MCFG_SCREEN_VISIBLE_AREA(0, 6*16, 0, 10-1) screen.set_visarea(0, 6*16, 0, 10-1);
MCFG_SCREEN_UPDATE_DEVICE("hd44780", hd44780_device, screen_update) screen.set_screen_update("hd44780", FUNC(hd44780_device::screen_update));
MCFG_SCREEN_PALETTE("palette") screen.set_palette("palette");
PALETTE(config, "palette", FUNC(novag6502_state::novag_lcd_palette), 3);
PALETTE(config, "palette", FUNC(sexpert_state::novag_lcd_palette), 3);
HD44780(config, m_lcd, 0); HD44780(config, m_lcd, 0);
m_lcd->set_lcd_size(2, 8); m_lcd->set_lcd_size(2, 8);
m_lcd->set_pixel_update_cb(FUNC(novag6502_state::novag_lcd_pixel_update), this); m_lcd->set_pixel_update_cb(FUNC(sexpert_state::novag_lcd_pixel_update), this);
TIMER(config, "display_decay").configure_periodic(FUNC(novag6502_state::display_decay_tick), attotime::from_msec(1)); TIMER(config, "display_decay").configure_periodic(FUNC(sexpert_state::display_decay_tick), attotime::from_msec(1));
config.set_default_layout(layout_novag_sexpert); config.set_default_layout(layout_novag_sexpert);
/* sound hardware */ /* sound hardware */
SPEAKER(config, "mono").front_center(); SPEAKER(config, "mono").front_center();
BEEP(config, m_beeper, 32.768_kHz_XTAL/32); // 1024Hz BEEP(config, m_beeper, 32.768_kHz_XTAL/32); // 1024Hz
m_beeper->add_route(ALL_OUTPUTS, "mono", 0.25); m_beeper->add_route(ALL_OUTPUTS, "mono", 0.25);
MACHINE_CONFIG_END }
MACHINE_CONFIG_START(novag6502_state::sforte) void sexpert_state::sforte(machine_config &config)
{
sexpert(config); sexpert(config);
/* basic machine hardware */ /* basic machine hardware */
MCFG_DEVICE_MODIFY("maincpu") m_maincpu->set_addrmap(AS_PROGRAM, &sexpert_state::sforte_map);
MCFG_DEVICE_PROGRAM_MAP(sforte_map)
m_irq_on->set_start_delay(m_irq_on->period() - attotime::from_usec(11)); // active for ?us (assume same as cforte) m_irq_on->set_start_delay(m_irq_on->period() - attotime::from_usec(11)); // active for ?us (assume same as cforte)
config.set_default_layout(layout_novag_sforte); config.set_default_layout(layout_novag_sforte);
MACHINE_CONFIG_END }
@ -1063,17 +1111,17 @@ ROM_END
******************************************************************************/ ******************************************************************************/
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS // YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
CONS( 1984, supercon, 0, 0, supercon, supercon, novag6502_state, empty_init, "Novag", "Super Constellation", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS ) CONS( 1984, supercon, 0, 0, supercon, supercon, scon_state, empty_init, "Novag", "Super Constellation", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS )
CONS( 1986, cfortea, 0, 0, cforte, cforte, novag6502_state, empty_init, "Novag", "Constellation Forte (version A)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS ) CONS( 1986, cfortea, 0, 0, cforte, cforte, cforte_state, empty_init, "Novag", "Constellation Forte (version A)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS )
CONS( 1986, cforteb, cfortea, 0, cforte, cforte, novag6502_state, empty_init, "Novag", "Constellation Forte (version B)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS ) CONS( 1986, cforteb, cfortea, 0, cforte, cforte, cforte_state, empty_init, "Novag", "Constellation Forte (version B)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS )
CONS( 1987, sfortea, 0, 0, sforte, sforte, novag6502_state, init_sexpert, "Novag", "Super Forte (version A, set 1)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS ) CONS( 1987, sfortea, 0, 0, sforte, sforte, sexpert_state, init_sexpert, "Novag", "Super Forte (version A, set 1)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS )
CONS( 1987, sfortea1, sfortea, 0, sforte, sforte, novag6502_state, init_sexpert, "Novag", "Super Forte (version A, set 2)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS ) CONS( 1987, sfortea1, sfortea, 0, sforte, sforte, sexpert_state, init_sexpert, "Novag", "Super Forte (version A, set 2)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS )
CONS( 1988, sforteb, sfortea, 0, sforte, sforte, novag6502_state, init_sexpert, "Novag", "Super Forte (version B)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS ) CONS( 1988, sforteb, sfortea, 0, sforte, sforte, sexpert_state, init_sexpert, "Novag", "Super Forte (version B)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS )
CONS( 1990, sfortec, sfortea, 0, sforte, sforte, novag6502_state, init_sexpert, "Novag", "Super Forte (version C)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS ) CONS( 1990, sfortec, sfortea, 0, sforte, sforte, sexpert_state, init_sexpert, "Novag", "Super Forte (version C)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS )
CONS( 1987, sexperta, 0, 0, sexpert, sexpert, novag6502_state, init_sexpert, "Novag", "Super Expert (version A)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS ) CONS( 1987, sexperta, 0, 0, sexpert, sexpert, sexpert_state, init_sexpert, "Novag", "Super Expert (version A)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS )
CONS( 1988, sexpertb, sexperta, 0, sexpert, sexpert, novag6502_state, init_sexpert, "Novag", "Super Expert (version B)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS ) CONS( 1988, sexpertb, sexperta, 0, sexpert, sexpert, sexpert_state, init_sexpert, "Novag", "Super Expert (version B)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS )
CONS( 1990, sexpertc, sexperta, 0, sexpert, sexpert, novag6502_state, init_sexpert, "Novag", "Super Expert (version C, V3.6)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS ) CONS( 1990, sexpertc, sexperta, 0, sexpert, sexpert, sexpert_state, init_sexpert, "Novag", "Super Expert (version C, V3.6)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS )
CONS( 1990, sexpertc1, sexperta, 0, sexpert, sexpert, novag6502_state, init_sexpert, "Novag", "Super Expert (version C, V1.2)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS ) CONS( 1990, sexpertc1, sexperta, 0, sexpert, sexpert, sexpert_state, init_sexpert, "Novag", "Super Expert (version C, V1.2)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS )

View File

@ -60,8 +60,8 @@ public:
// misc common // misc common
u16 m_inp_mux; // multiplexed keypad/leds mask u16 m_inp_mux; // multiplexed keypad/leds mask
u16 m_led_select; u16 m_led_select;
u32 m_7seg_data; // data for seg leds
u16 m_led_data; u16 m_led_data;
u32 m_7seg_data; // data for seg leds
u8 m_speech_data; u8 m_speech_data;
u8 m_speech_bank; // speech rom higher address bits u8 m_speech_bank; // speech rom higher address bits

View File

@ -24,6 +24,7 @@ public:
driver_device(mconfig, type, tag), driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"), m_maincpu(*this, "maincpu"),
m_irq_on(*this, "irq_on"), m_irq_on(*this, "irq_on"),
m_rombank(*this, "rombank"),
m_beeper(*this, "beeper"), m_beeper(*this, "beeper"),
m_dac(*this, "dac"), m_dac(*this, "dac"),
m_lcd(*this, "hd44780"), m_lcd(*this, "hd44780"),
@ -39,6 +40,7 @@ public:
// devices/pointers // devices/pointers
required_device<cpu_device> m_maincpu; required_device<cpu_device> m_maincpu;
optional_device<timer_device> m_irq_on; optional_device<timer_device> m_irq_on;
optional_memory_bank m_rombank;
optional_device<beep_device> m_beeper; optional_device<beep_device> m_beeper;
optional_device<dac_bit_interface> m_dac; optional_device<dac_bit_interface> m_dac;
optional_device<hd44780_device> m_lcd; optional_device<hd44780_device> m_lcd;
@ -51,6 +53,7 @@ public:
u16 m_inp_mux; // multiplexed keypad mask u16 m_inp_mux; // multiplexed keypad mask
u16 m_led_select; u16 m_led_select;
u16 m_led_data; u16 m_led_data;
u8 m_7seg_data;
u8 m_lcd_control; u8 m_lcd_control;
u8 m_lcd_data; u8 m_lcd_data;