From fafa5a515c59b360e3765c67a50966001098d04d Mon Sep 17 00:00:00 2001 From: Scott Stone Date: Sun, 10 Jun 2012 17:23:15 +0000 Subject: [PATCH] Enable proper save stating for bfm_bd1 machine which should fix MT bug#03990 as well. [James Wallace] --- src/mame/drivers/bfm_sc1.c | 40 +- src/mame/drivers/bfm_sc2.c | 69 ++-- src/mame/drivers/bfm_sc4h.c | 16 +- src/mame/machine/bfm_bd1.c | 797 ++++++++++++++++++------------------ src/mame/machine/bfm_bd1.h | 72 +++- src/mame/video/bfm_adr2.c | 9 - 6 files changed, 498 insertions(+), 505 deletions(-) diff --git a/src/mame/drivers/bfm_sc1.c b/src/mame/drivers/bfm_sc1.c index ff75b3758be..5d21b4d1715 100644 --- a/src/mame/drivers/bfm_sc1.c +++ b/src/mame/drivers/bfm_sc1.c @@ -104,7 +104,11 @@ class bfm_sc1_state : public driver_device { public: bfm_sc1_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) { } + : driver_device(mconfig, type, tag), + m_vfd0(*this, "vfd0") + { } + + optional_device m_vfd0; int m_mmtr_latch; int m_triac_latch; @@ -162,6 +166,7 @@ public: DECLARE_READ8_MEMBER(nec_r); DECLARE_WRITE8_MEMBER(nec_reset_w); DECLARE_WRITE8_MEMBER(nec_latch_w); + }; #define VFD_RESET 0x20 @@ -347,21 +352,16 @@ WRITE8_MEMBER(bfm_sc1_state::vfd_w) { // vfd reset line changed if ( !(data & VFD_RESET) ) { // reset the vfd - BFM_BD1_reset(0); - BFM_BD1_reset(1); - BFM_BD1_reset(2); + m_vfd0->reset(); } } if ( changed & VFD_CLOCK1 ) { // clock line changed if ( !(data & VFD_CLOCK1) && (data & VFD_RESET) ) { // new data clocked into vfd - BFM_BD1_shift_data(0, data & VFD_DATA ); + m_vfd0->shift_data(data & VFD_DATA ); } } - BFM_BD1_draw(0); - BFM_BD1_draw(1); - BFM_BD1_draw(2); } } @@ -633,7 +633,6 @@ READ8_MEMBER(bfm_sc1_state::vid_uart_ctrl_r) static MACHINE_RESET( bfm_sc1 ) { bfm_sc1_state *state = machine.driver_data(); - BFM_BD1_init(0); state->m_vfd_latch = 0; state->m_mmtr_latch = 0; state->m_triac_latch = 0; @@ -649,9 +648,7 @@ static MACHINE_RESET( bfm_sc1 ) state->m_mux2_datahi = 0; state->m_mux2_input = 0; - BFM_BD1_reset(0); // reset display1 - BFM_BD1_reset(1); // reset display2 - BFM_BD1_reset(2); // reset display3 + state->m_vfd0->reset(); // reset stepper motors ///////////////////////////////////////////////////////////// { @@ -1095,6 +1092,7 @@ static MACHINE_CONFIG_START( scorpion1, bfm_sc1_state ) MCFG_CPU_PERIODIC_INT(timer_irq, 1000 ) // generate 1000 IRQ's per second MCFG_WATCHDOG_TIME_INIT(PERIOD_OF_555_MONOSTABLE(120000,100e-9)) + MCFG_BFMBD1_ADD("vfd0",0) MCFG_SPEAKER_STANDARD_MONO("mono") MCFG_SOUND_ADD("aysnd",AY8912, MASTER_CLOCK/4) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) @@ -1168,26 +1166,18 @@ static DRIVER_INIT(toppoker) sc1_common_init(machine,3,1, 3); adder2_decode_char_roms(machine); // decode GFX roms MechMtr_config(machine,8); - - BFM_BD1_init(0); } static DRIVER_INIT(lotse) { sc1_common_init(machine,6,1, 3); MechMtr_config(machine,8); - - BFM_BD1_init(0); - BFM_BD1_init(1); } static DRIVER_INIT(lotse_bank0) { sc1_common_init(machine,6,1, 0); MechMtr_config(machine,8); - - BFM_BD1_init(0); - BFM_BD1_init(1); } @@ -1195,18 +1185,12 @@ static DRIVER_INIT(nocrypt) { sc1_common_init(machine,6,0, 3); MechMtr_config(machine,8); - - BFM_BD1_init(0); - BFM_BD1_init(1); } static DRIVER_INIT(nocrypt_bank0) { sc1_common_init(machine,6,0, 0); MechMtr_config(machine,8); - - BFM_BD1_init(0); - BFM_BD1_init(1); } @@ -1216,8 +1200,6 @@ static DRIVER_INIT(rou029) { sc1_common_init(machine,6,0, 3); MechMtr_config(machine,8); - - BFM_BD1_init(0); } ///////////////////////////////////////////////////////////////////////////////////// @@ -1228,8 +1210,6 @@ static DRIVER_INIT(clatt) sc1_common_init(machine,6,1, 3); MechMtr_config(machine,8); - BFM_BD1_init(0); - Scorpion1_SetSwitchState(state,3,2,1); Scorpion1_SetSwitchState(state,3,3,1); Scorpion1_SetSwitchState(state,3,6,1); diff --git a/src/mame/drivers/bfm_sc2.c b/src/mame/drivers/bfm_sc2.c index f46f4c614ca..9fd35b5c1fd 100644 --- a/src/mame/drivers/bfm_sc2.c +++ b/src/mame/drivers/bfm_sc2.c @@ -178,7 +178,13 @@ class bfm_sc2_state : public driver_device { public: bfm_sc2_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) { } + : driver_device(mconfig, type, tag), + m_vfd0(*this, "vfd0"), + m_vfd1(*this, "vfd1") + { } + + optional_device m_vfd0; + optional_device m_vfd1; int m_sc2gui_update_mmtr; UINT8 *m_nvram; @@ -186,8 +192,6 @@ public: UINT8 m_e2ram[1024]; int m_mmtr_latch; int m_triac_latch; - int m_vfd1_latch; - int m_vfd2_latch; int m_irq_status; int m_optic_pattern; int m_uart1_data; @@ -323,8 +327,6 @@ static void e2ram_reset(running_machine &machine); static void on_scorpion2_reset(running_machine &machine) { bfm_sc2_state *state = machine.driver_data(); - state->m_vfd1_latch = 0; - state->m_vfd2_latch = 0; state->m_mmtr_latch = 0; state->m_triac_latch = 0; state->m_irq_status = 0; @@ -351,9 +353,6 @@ static void on_scorpion2_reset(running_machine &machine) state->m_slide_states[4] = 0; state->m_slide_states[5] = 0; - BFM_BD1_reset(0); // reset display1 - BFM_BD1_reset(1); // reset display2 - e2ram_reset(machine); devtag_reset(machine, "ymsnd"); @@ -944,19 +943,15 @@ WRITE8_MEMBER(bfm_sc2_state::payout_select_w) WRITE8_MEMBER(bfm_sc2_state::vfd2_data_w) { - m_vfd2_latch = data; - BFM_BD1_newdata(1, data); - BFM_BD1_draw(1); + m_vfd1->write_char(data); } /////////////////////////////////////////////////////////////////////////// WRITE8_MEMBER(bfm_sc2_state::vfd_reset_w) { - BFM_BD1_reset(0); // reset both VFD's - BFM_BD1_reset(1); - BFM_BD1_draw(0); - BFM_BD1_draw(1); + m_vfd0->reset(); + m_vfd1->reset(); } /////////////////////////////////////////////////////////////////////////// @@ -1177,7 +1172,6 @@ READ8_MEMBER(bfm_sc2_state::vfd_status_r) WRITE8_MEMBER(bfm_sc2_state::vfd1_data_w) { - m_vfd1_latch = data; if (machine().device("matrix")) { @@ -1185,8 +1179,7 @@ WRITE8_MEMBER(bfm_sc2_state::vfd1_data_w) } else { - BFM_BD1_newdata(0, data); - BFM_BD1_draw(0); + m_vfd0->write_char(data); } } @@ -1414,25 +1407,14 @@ static int read_e2ram(running_machine &machine) static MACHINE_RESET( init ) { - // reset adder2 - MACHINE_RESET_CALL(adder2); + bfm_sc2_state *state = machine.driver_data(); // reset the board ////////////////////////////////////////////////////// on_scorpion2_reset(machine); - BFM_BD1_init(0); - BFM_BD1_init(1); -} + state->m_vfd0->reset(); + state->m_vfd1->reset(); -static SCREEN_UPDATE_IND16( addersc2 ) -{ - bfm_sc2_state *state = screen.machine().driver_data(); - if ( state->m_sc2_show_door ) - { - output_set_value("door",( Scorpion2_GetSwitchState(screen.machine(),state->m_sc2_door_state>>4, state->m_sc2_door_state & 0x0F) ) ); - } - - return SCREEN_UPDATE16_CALL(adder2); } @@ -2164,6 +2146,8 @@ static MACHINE_CONFIG_START( scorpion2_vid, bfm_sc2_state ) MCFG_CPU_PERIODIC_INT(timer_irq, 1000) // generate 1000 IRQ's per second MCFG_WATCHDOG_TIME_INIT(PERIOD_OF_555_MONOSTABLE(120000,100e-9)) + MCFG_BFMBD1_ADD("vfd0",0) + MCFG_NVRAM_ADD_0FILL("nvram") MCFG_NVRAM_HANDLER(bfm_sc2) MCFG_DEFAULT_LAYOUT(layout_bfm_sc2) @@ -2172,9 +2156,9 @@ static MACHINE_CONFIG_START( scorpion2_vid, bfm_sc2_state ) MCFG_SCREEN_SIZE( 400, 280) MCFG_SCREEN_VISIBLE_AREA( 0, 400-1, 0, 280-1) MCFG_SCREEN_REFRESH_RATE(50) - MCFG_SCREEN_UPDATE_STATIC(addersc2) MCFG_VIDEO_START( adder2) + MCFG_SCREEN_UPDATE_STATIC(adder2) MCFG_VIDEO_RESET( adder2) MCFG_PALETTE_LENGTH(16) @@ -2609,9 +2593,11 @@ static const bfmdm01_interface dm01_interface = /* machine init (called only once) */ static MACHINE_RESET( awp_init ) { + bfm_sc2_state *state = machine.driver_data(); + on_scorpion2_reset(machine); - BFM_BD1_init(0); - BFM_BD1_init(1); + state->m_vfd0->reset(); + state->m_vfd1->reset(); } @@ -3700,6 +3686,9 @@ static MACHINE_CONFIG_START( scorpion2, bfm_sc2_state ) MCFG_CPU_PERIODIC_INT(timer_irq, 1000 ) MCFG_WATCHDOG_TIME_INIT(PERIOD_OF_555_MONOSTABLE(120000,100e-9)) + MCFG_BFMBD1_ADD("vfd0",0) + MCFG_BFMBD1_ADD("vfd1",1) + MCFG_SPEAKER_STANDARD_MONO("mono") MCFG_SOUND_ADD("upd",UPD7759, UPD7759_STANDARD_CLOCK) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50) @@ -3731,7 +3720,6 @@ static MACHINE_CONFIG_START( scorpion2_dm01, bfm_sc2_state ) MCFG_CPU_PERIODIC_INT(timer_irq, 1000 ) MCFG_WATCHDOG_TIME_INIT(PERIOD_OF_555_MONOSTABLE(120000,100e-9)) - MCFG_SPEAKER_STANDARD_MONO("mono") MCFG_SOUND_ADD("ymsnd",YM2413, XTAL_3_579545MHz) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0) @@ -3789,9 +3777,6 @@ static DRIVER_INIT (bbrkfst) sc2awp_common_init(machine,5, 1); MechMtr_config(machine,8); - BFM_BD1_init(0); - BFM_BD1_init(1); - state->m_has_hopper = 0; Scorpion2_SetSwitchState(machine,4,0, 1); /* GBP1 Low Level Switch */ @@ -3812,9 +3797,6 @@ static DRIVER_INIT (drwho_common) MechMtr_config(machine,8); - BFM_BD1_init(0); - BFM_BD1_init(1); - state->m_has_hopper = 0; Scorpion2_SetSwitchState(machine,4,0, 0); /* GBP1 Low Level Switch */ @@ -3844,8 +3826,6 @@ static DRIVER_INIT (focus) { sc2awp_common_init(machine,6, 1); MechMtr_config(machine,5); - - BFM_BD1_init(0); } static DRIVER_INIT (cpeno1) @@ -3934,7 +3914,6 @@ static DRIVER_INIT (bfmcgslm) bfm_sc2_state *state = machine.driver_data(); sc2awp_common_init(machine,6, 1); MechMtr_config(machine,8); - BFM_BD1_init(0); state->m_has_hopper = 0; } diff --git a/src/mame/drivers/bfm_sc4h.c b/src/mame/drivers/bfm_sc4h.c index f2a7d657dd3..63f9654e6dd 100644 --- a/src/mame/drivers/bfm_sc4h.c +++ b/src/mame/drivers/bfm_sc4h.c @@ -37,7 +37,6 @@ #include "sound/ymz280b.h" #include "machine/68681.h" #include "bfm_sc4.lh" -#include "machine/bfm_bd1.h" #include "video/awpvid.h" //DMD01 #include "video/bfm_dm01.h" @@ -456,8 +455,7 @@ void bfm_sc4_reset_serial_vfd(running_machine &machine) { sc4_state *state = machine.driver_data(); - BFM_BD1_reset(0); - BFM_BD1_draw(0); + state->m_vfd0->reset(); state->vfd_old_clock = false; } @@ -481,6 +479,8 @@ void bfm_sc4_write_serial_vfd(running_machine &machine, bool cs, bool clock, boo { if ( !clock ) { + //Should move to the internal serial process when DM01 is device-ified +// m_vfd0->shift_data(!data); state->vfd_ser_value <<= 1; if (data) state->vfd_ser_value |= 1; @@ -494,8 +494,7 @@ void bfm_sc4_write_serial_vfd(running_machine &machine, bool cs, bool clock, boo } else { - BFM_BD1_newdata(0, state->vfd_ser_value); - BFM_BD1_draw(0); + state->m_vfd0->write_char(state->vfd_ser_value); } } } @@ -642,8 +641,6 @@ static MACHINE_START( sc4 ) bfm_sc4_68307_portb_w ); m68307_set_duart68681(machine.device("maincpu"),machine.device("m68307_68681")); - BFM_BD1_init(0); - int reels = 6; state->m_reels=reels; @@ -782,6 +779,7 @@ MACHINE_CONFIG_START( sc4, sc4_state ) MCFG_DUART68681_ADD("duart68681", 16000000/4, bfm_sc4_duart68681_config) // ?? Mhz + MCFG_BFMBD1_ADD("vfd0",0) MCFG_DEFAULT_LAYOUT(layout_bfm_sc4) @@ -803,12 +801,15 @@ static MACHINE_START( adder4 ) MACHINE_CONFIG_DERIVED_CLASS( sc4_adder4, sc4, sc4_adder4_state ) MCFG_CPU_ADD("adder4", M68340, 25175000) // 68340 (CPU32 core) MCFG_CPU_PROGRAM_MAP(sc4_adder4_map) + MCFG_BFMBD1_ADD("vfd0",0) MCFG_MACHINE_START( adder4 ) MACHINE_CONFIG_END MACHINE_CONFIG_DERIVED_CLASS( sc4dmd, sc4, sc4_state ) /* video hardware */ + MCFG_BFMBD1_REMOVE("vfd0") + MCFG_DEFAULT_LAYOUT(layout_sc4_dmd) MCFG_CPU_ADD("matrix", M6809, 2000000 ) /* matrix board 6809 CPU at 2 Mhz ?? I don't know the exact freq.*/ MCFG_CPU_PROGRAM_MAP(bfm_dm01_memmap) @@ -816,6 +817,7 @@ MACHINE_CONFIG_DERIVED_CLASS( sc4dmd, sc4, sc4_state ) MCFG_MACHINE_START( sc4 ) MACHINE_CONFIG_END + INPUT_PORTS_START( sc4_base ) PORT_START("IN-0") PORT_DIPNAME( 0x01, 0x00, "IN-0:0" ) diff --git a/src/mame/machine/bfm_bd1.c b/src/mame/machine/bfm_bd1.c index 9cd56869aae..a403469712c 100644 --- a/src/mame/machine/bfm_bd1.c +++ b/src/mame/machine/bfm_bd1.c @@ -2,63 +2,19 @@ Bellfruit BD1 VFD module interface and emulation by J.Wallace + TODO: Implement flashing (our only datasheet has that section + completely illegible) **********************************************************************/ #include "emu.h" #include "bfm_bd1.h" -static struct -{ - UINT8 type, // type of alpha display +const device_type BFM_BD1 = &device_creator; - changed, // flag <>0, if contents are changed - window_start, // display window start pos 0-15 - window_end, // display window end pos 0-15 - window_size, // window size - pad; // unused align byte - - INT8 pcursor_pos, // previous cursor pos - cursor_pos; // current cursor pos - - UINT16 user_def, // user defined character state - user_data; // user defined character data (16 bit) - - UINT8 scroll_active, // flag <>0, scrolling active - display_mode, // display scroll mode, 0/1/2/3 - display_blanking, // display blanking mode, 0/1/2/3 - blank_flag, - flash_rate, // flash rate 0-F - flash_control, // flash control 0/1/2/3 - flash_flag; - - UINT8 string[18]; // text buffer - UINT32 segments[16], // segments - outputs[16]; // standardised outputs - - UINT8 count, // bit counter - data; // receive register - -} bd1[MAX_BD1]; - - -// local prototypes /////////////////////////////////////////////////////// - -static void ScrollLeft( int id); -static int BD1_setdata(int id, int segdata, int data); - -// local vars ///////////////////////////////////////////////////////////// - -// -// Bellfruit BD1 charset to ASCII conversion table -// -static const char BD1ASCII[] = -//0123456789ABCDEF0123456789ABC DEF01 23456789ABCDEF0123456789ABCDEF - "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_ ?\"#$%%'()*+.-./0123456789&%<=>?" - "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_ ?\"#$%%'()*+.-./0123456789&%<=>?" - "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_ ?\"#$%%'()*+.-./0123456789&%<=>?"; /* - BD1 14 segment charset lookup table + BD1 14 segment charset lookup table, according to datasheet (we rewire this later) + 2 --------- |\ |3 /| @@ -71,6 +27,8 @@ static const char BD1ASCII[] = --------- C 9 + 8 is flashing + */ static const UINT16 BD1charset[]= @@ -112,7 +70,7 @@ static const UINT16 BD1charset[]= 0x0009, // 0000 0000 0000 1001 ". 0xC62A, // 1100 0110 0010 1010 #. 0xC62D, // 1100 0110 0010 1101 $. - 0x0100, // 0000 0000 0000 0000 flash ? + 0x0100, // 0000 0001 0000 0000 flash character 0x0000, // 0000 0000 0000 0000 not defined 0x0040, // 0000 0000 1000 0000 '. 0x0880, // 0000 1000 1000 0000 (. @@ -141,322 +99,347 @@ static const UINT16 BD1charset[]= 0x4406, // 0100 0100 0000 0110 ? }; -/////////////////////////////////////////////////////////////////////////// - -void BFM_BD1_init(int id) +bfm_bd1_t::bfm_bd1_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, BFM_BD1, "BFM BD1 VFD controller", tag, owner, clock), + m_port_val(0) { - assert_always((id >= 0) && (id < MAX_BD1), "BFM_BD1_init called on an invalid display ID!"); - - memset( &bd1[id], 0, sizeof(bd1[0])); - - BFM_BD1_reset(id); } -/////////////////////////////////////////////////////////////////////////// - -void BFM_BD1_reset(int id) +void bfm_bd1_t::static_set_value(device_t &device, int val) { - bd1[id].window_end = 15; - bd1[id].window_size = (bd1[id].window_end - bd1[id].window_start)+1; - memset(bd1[id].string, ' ', 16); - - bd1[id].count = 0; - - bd1[id].changed |= 1; + bfm_bd1_t &bd1 = downcast(device); + bd1.m_port_val = val; } -/////////////////////////////////////////////////////////////////////////// - -UINT32 *BFM_BD1_get_segments(int id) +void bfm_bd1_t::device_start() { - return bd1[id].segments; + m_timer=timer_alloc(0); + + save_item(NAME(m_cursor)); + save_item(NAME(m_cursor_pos)); + save_item(NAME(m_window_start)); // display window start pos 0-15 + save_item(NAME(m_window_end)); // display window end pos 0-15 + save_item(NAME(m_window_size)); // window size + save_item(NAME(m_shift_count)); + save_item(NAME(m_shift_data)); + save_item(NAME(m_pcursor_pos)); + save_item(NAME(m_blank_flag)); + save_item(NAME(m_flash_flag)); + save_item(NAME(m_scroll_active)); + save_item(NAME(m_display_mode)); + save_item(NAME(m_flash_rate)); + save_item(NAME(m_flash_control)); + save_item(NAME(m_chars)); + save_item(NAME(m_attrs)); + save_item(NAME(m_user_data)); // user defined character data (16 bit) + save_item(NAME(m_user_def)); // user defined character state + + device_reset(); } -/////////////////////////////////////////////////////////////////////////// - -UINT32 *BFM_BD1_get_outputs(int id) +void bfm_bd1_t::device_reset() { - return bd1[id].outputs; + m_cursor = 0; + m_cursor_pos = 0; + m_window_start = 0; + m_window_end = 0; + m_window_size = 0; + m_shift_count = 0; + m_shift_data = 0; + m_pcursor_pos = 0; + m_blank_flag = 0; + m_flash_flag = 0; + m_scroll_active = 0; + m_display_mode = 0; + m_flash_rate = 0; + m_flash_control = 0; + m_user_data = 0; + m_user_def = 0; + + memset(m_chars, 0, sizeof(m_chars)); + memset(m_attrs, 0, sizeof(m_attrs)); + m_timer->adjust(attotime::from_hz(clock()), 0); } -/////////////////////////////////////////////////////////////////////////// - -UINT32 *BFM_BD1_set_outputs(int id) +void bfm_bd1_t::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) { - int cursor; - for (cursor = 0; cursor < 16; cursor++) + update_display(); + m_timer->adjust(attotime::from_hz(clock()), 0); +} + +UINT32 bfm_bd1_t::set_display(UINT16 segin) +{ + UINT32 segout=0; + if ( segin & 0x0004 ) segout |= 0x0001; + else segout &= ~0x0001; + if ( segin & 0x0002 ) segout |= 0x0002; + else segout &= ~0x0002; + if ( segin & 0x0020 ) segout |= 0x0004; + else segout &= ~0x0004; + if ( segin & 0x0200 ) segout |= 0x0008; + else segout &= ~0x0008; + if ( segin & 0x2000 ) segout |= 0x0010; + else segout &= ~0x0010; + if ( segin & 0x0001 ) segout |= 0x0020; + else segout &= ~0x0020; + if ( segin & 0x8000 ) segout |= 0x0040; + else segout &= ~0x0040; + if ( segin & 0x4000 ) segout |= 0x0080; + else segout &= ~0x0080; + if ( segin & 0x0008 ) segout |= 0x0100; + else segout &= ~0x0100; + if ( segin & 0x0400 ) segout |= 0x0200; + else segout &= ~0x0200; + if ( segin & 0x0010 ) segout |= 0x0400; + else segout &= ~0x0400; + if ( segin & 0x0040 ) segout |= 0x0800; + else segout &= ~0x0800; + if ( segin & 0x0080 ) segout |= 0x1000; + else segout &= ~0x1000; + if ( segin & 0x0800 ) segout |= 0x2000; + else segout &= ~0x2000; + if ( segin & 0x1000 ) segout |= 0x4000; + else segout &= ~0x4000; + + return segout; +} + +void bfm_bd1_t::device_post_load() +{ + for (int i =0; i<16; i++) { - if ( BFM_BD1_get_segments(id)[cursor] & 0x0004 ) bd1[id].outputs[cursor] |= 0x0001; - else bd1[id].outputs[cursor] &= ~0x0001; - if ( BFM_BD1_get_segments(id)[cursor] & 0x0002 ) bd1[id].outputs[cursor] |= 0x0002; - else bd1[id].outputs[cursor] &= ~0x0002; - if ( BFM_BD1_get_segments(id)[cursor] & 0x0020 ) bd1[id].outputs[cursor] |= 0x0004; - else bd1[id].outputs[cursor] &= ~0x0004; - if ( BFM_BD1_get_segments(id)[cursor] & 0x0200 ) bd1[id].outputs[cursor] |= 0x0008; - else bd1[id].outputs[cursor] &= ~0x0008; - if ( BFM_BD1_get_segments(id)[cursor] & 0x2000 ) bd1[id].outputs[cursor] |= 0x0010; - else bd1[id].outputs[cursor] &= ~0x0010; - if ( BFM_BD1_get_segments(id)[cursor] & 0x0001 ) bd1[id].outputs[cursor] |= 0x0020; - else bd1[id].outputs[cursor] &= ~0x0020; - if ( BFM_BD1_get_segments(id)[cursor] & 0x8000 ) bd1[id].outputs[cursor] |= 0x0040; - else bd1[id].outputs[cursor] &= ~0x0040; - if ( BFM_BD1_get_segments(id)[cursor] & 0x4000 ) bd1[id].outputs[cursor] |= 0x0080; - else bd1[id].outputs[cursor] &= ~0x0080; - if ( BFM_BD1_get_segments(id)[cursor] & 0x0008 ) bd1[id].outputs[cursor] |= 0x0100; - else bd1[id].outputs[cursor] &= ~0x0100; - if ( BFM_BD1_get_segments(id)[cursor] & 0x0400 ) bd1[id].outputs[cursor] |= 0x0200; - else bd1[id].outputs[cursor] &= ~0x0200; - if ( BFM_BD1_get_segments(id)[cursor] & 0x0010 ) bd1[id].outputs[cursor] |= 0x0400; - else bd1[id].outputs[cursor] &= ~0x0400; - if ( BFM_BD1_get_segments(id)[cursor] & 0x0040 ) bd1[id].outputs[cursor] |= 0x0800; - else bd1[id].outputs[cursor] &= ~0x0800; - if ( BFM_BD1_get_segments(id)[cursor] & 0x0080 ) bd1[id].outputs[cursor] |= 0x1000; - else bd1[id].outputs[cursor] &= ~0x1000; - if ( BFM_BD1_get_segments(id)[cursor] & 0x0800 ) bd1[id].outputs[cursor] |= 0x2000; - else bd1[id].outputs[cursor] &= ~0x2000; - if ( BFM_BD1_get_segments(id)[cursor] & 0x1000 ) bd1[id].outputs[cursor] |= 0x4000; - else bd1[id].outputs[cursor] &= ~0x4000; - //Flashing ? Set an unused pin as a control - if ( BFM_BD1_get_segments(id)[cursor] & 0x100 ) bd1[id].outputs[cursor] |= 0x40000; - else bd1[id].outputs[cursor] &= ~0x40000; + output_set_indexed_value("vfd", (m_port_val*16) + i, m_outputs[i]); + } +} + +void bfm_bd1_t::update_display() +{ + m_outputs[m_cursor] = set_display(m_chars[m_cursor]);; + output_set_indexed_value("vfd", (m_port_val*16) + m_cursor, m_outputs[m_cursor]); + + m_cursor++; + if (m_cursor >15) + { + m_cursor=0; + } +} +/////////////////////////////////////////////////////////////////////////// +void bfm_bd1_t::blank(int data) +{ + switch ( data & 0x04 ) + { + case 0x00: // blank all + { + memset(m_chars, 0, sizeof(m_chars)); + memset(m_attrs, 0, sizeof(m_attrs)); + } + break; + case 0x01: // blank inside window + if ( m_window_size > 0 ) + { + memset(m_chars+m_window_start,0,m_window_size); + memset(m_attrs+m_window_start,0,m_window_size); + } + break; + case 0x02: // blank outside window + if ( m_window_size > 0 ) + { + if ( m_window_start > 0 ) + { + for (int i = 0; i < m_window_start; i++) + { + memset(m_chars+i,0,i); + memset(m_attrs+i,0,i); + } + } + + if (m_window_end < 15 ) + { + for (int i = m_window_end; i < 15- m_window_end ; i++) + { + memset(m_chars+i,0,i); + memset(m_attrs+i,0,i); + } + } + } + break; + + case 0x03: // blank entire display + { + memset(m_chars, 0, sizeof(m_chars)); + memset(m_attrs, 0, sizeof(m_attrs)); + } + break; + } +} +int bfm_bd1_t::write_char(int data) +{ + int change = 0; + if ( m_user_def ) + { + m_user_def--; + + m_user_data <<= 8; + m_user_data |= data; + + if ( m_user_def ) + { + return 0; + } + + setdata( m_user_data, data); + change ++; + } + else + { + + if(data < 0x80)//characters + { + + if (m_blank_flag || m_flash_flag) + { + if (m_blank_flag) + { + //m_display_blanking = data & 0x0F; + blank( data & 0x04 ); + m_blank_flag = 0; + } + if (m_flash_flag) + { + //not setting yet + m_flash_flag = 0; + } + } + else + { + if (data > 0x3F) + { + // logerror("Undefined character %x \n", data); + } + + setdata(BD1charset[(data & 0x3F)], data); + } + } + else + { + switch ( data & 0xF0 ) + { + case 0x80: // 0x80 - 0x8F Set display blanking + if (data ==0x84)// futaba setup + { + m_blank_flag = 1; + } + else + { + blank(data&0x04);//use the blanking data + } + break; + + case 0x90: // 0x90 - 0x9F Set cursor pos + m_cursor_pos = data & 0x0F; + m_scroll_active = 0; + if ( m_display_mode == 2 ) + { + if ( m_cursor_pos >= m_window_end) m_scroll_active = 1; + } + break; + + case 0xA0: // 0xA0 - 0xAF Set display mode + m_display_mode = data &0x03; + break; + + case 0xB0: // 0xB0 - 0xBF Clear display area + switch ( data & 0x03 ) + { + case 0x00: // clr nothing + break; + + case 0x01: // clr inside window + if ( m_window_size > 0 ) + { + memset(m_chars+m_window_start,0,m_window_size); + memset(m_attrs+m_window_start,0,m_window_size); + } + + break; + + case 0x02: // clr outside window + if ( m_window_size > 0 ) + { + if ( m_window_start > 0 ) + { + for (int i = 0; i < m_window_start; i++) + { + memset(m_chars+i,0,i); + memset(m_attrs+i,0,i); + } + } + + if (m_window_end < 15 ) + { + for (int i = m_window_end; i < 15- m_window_end ; i++) + { + memset(m_chars+i,0,i); + memset(m_attrs+i,0,i); + } + } + } + case 0x03: // clr entire display + { + memset(m_chars, 0, sizeof(m_chars)); + memset(m_attrs, 0, sizeof(m_attrs)); + } + } + break; + + case 0xC0: // 0xC0 - 0xCF Set flash rate + m_flash_rate = data & 0x0F; + break; + + case 0xD0: // 0xD0 - 0xDF Set Flash control + m_flash_control = data & 0x03; + break; + + case 0xE0: // 0xE0 - 0xEF Set window start pos + m_window_start = data &0x0F; + m_window_size = (m_window_end - m_window_start)+1; + break; + + case 0xF0: // 0xF0 - 0xFF Set window end pos + m_window_end = data &0x0F; + m_window_size = (m_window_end - m_window_start)+1; + m_scroll_active = 0; + if ( m_display_mode == 2 ) + { + if ( m_cursor_pos >= m_window_end) + { + m_scroll_active = 1; + m_cursor_pos = m_window_end; + } + } + break; + } + } } return 0; } /////////////////////////////////////////////////////////////////////////// -char *BFM_BD1_get_string( int id) +void bfm_bd1_t::setdata(int segdata, int data) { - return (char *)bd1[id].string; -} - -/////////////////////////////////////////////////////////////////////////// - -void BFM_BD1_shift_data(int id, int data) -{ - bd1[id].data <<= 1; - - if ( !data ) bd1[id].data |= 1; - - if ( ++bd1[id].count >= 8 ) - { - if ( BFM_BD1_newdata(id, bd1[id].data) ) - { - bd1[id].changed |= 1; - } - //logerror("vfd %3d -> %02X \"%s\"\n", id, bd1[id].data, bd1[id].string); - - bd1[id].count = 0; - bd1[id].data = 0; - } -} - -/////////////////////////////////////////////////////////////////////////// - -int BFM_BD1_newdata(int id, int data) -{ - int change = 0; - int cursor; - - if ( bd1[id].user_def ) - { - bd1[id].user_def--; - - bd1[id].user_data <<= 8; - bd1[id].user_data |= data; - - if ( bd1[id].user_def ) - { - return 0; - } - - data = '@'; - change = BD1_setdata(id, bd1[id].user_def, data); - } - else - { - } - - switch ( data & 0xF0 ) - { - case 0x80: // 0x80 - 0x8F Set display blanking - - //TODO: Implement this, MAME artwork not mature enough - switch ( data & 0x04 ) - { - case 0x00: // blank all - break; - case 0x01: // blank inside window - break; - - case 0x02: // blank outside window - break; - - case 0x03: // blank entire display - break; - - case 0x04: // futaba setup - - bd1[id].blank_flag = 1; - break; - } - break; - - case 0x90: // 0x90 - 0x9F Set cursor pos - - bd1[id].cursor_pos = data & 0x0F; - - bd1[id].scroll_active = 0; - if ( bd1[id].display_mode == 2 ) - { - if ( bd1[id].cursor_pos >= bd1[id].window_end) bd1[id].scroll_active = 1; - } - break; - - case 0xA0: // 0xA0 - 0xAF Set display mode - - bd1[id].display_mode = data &0x03; - break; - - case 0xB0: // 0xB0 - 0xBF Clear display area - - switch ( data & 0x03 ) - { - case 0x00: // clr nothing - break; - - case 0x01: // clr inside window - - if ( bd1[id].window_size > 0 ) - { - memset( bd1[id].string+bd1[id].window_start, ' ',bd1[id].window_size ); - } - break; - - case 0x02: // clr outside window - - if ( bd1[id].window_size > 0 ) - { - if ( bd1[id].window_start > 0 ) - { - memset( bd1[id].string, ' ', bd1[id].window_start); - for (cursor = 0; cursor < bd1[id].window_start; cursor++) - { - bd1[id].segments[cursor] = 0x0000; - } - } - - if (bd1[id].window_end < 15 ) - { - memset( bd1[id].string+bd1[id].window_end, ' ', 15-bd1[id].window_end); - for (cursor = bd1[id].window_end; cursor < 15-bd1[id].window_end; cursor++) - { - bd1[id].segments[cursor] = 0x0000; - } - - } - } - case 0x03: // clr entire display - - memset(bd1[id].string, ' ' , 16); - for (cursor = 0; cursor < 16; cursor++) - { - bd1[id].segments[cursor] = 0x0000; - } - break; - } - change = 1; - break; - - case 0xC0: // 0xC0 - 0xCF Set flash rate - - bd1[id].flash_rate = data & 0x0F; - break; - - case 0xD0: // 0xD0 - 0xDF Set Flash control - - bd1[id].flash_control = data & 0x03; - break; - - case 0xE0: // 0xE0 - 0xEF Set window start pos - - bd1[id].window_start = data &0x0F; - bd1[id].window_size = (bd1[id].window_end - bd1[id].window_start)+1; - break; - - case 0xF0: // 0xF0 - 0xFF Set window end pos - - bd1[id].window_end = data &0x0F; - bd1[id].window_size = (bd1[id].window_end - bd1[id].window_start)+1; - - bd1[id].scroll_active = 0; - if ( bd1[id].display_mode == 2 ) - { - if ( bd1[id].cursor_pos >= bd1[id].window_end) - { - bd1[id].scroll_active = 1; - bd1[id].cursor_pos = bd1[id].window_end; - } - } - break; - - default: - - if (bd1[id].blank_flag || bd1[id].flash_flag) - { - if (bd1[id].blank_flag) - { - bd1[id].display_blanking = data & 0x0F; - change = 1; - bd1[id].blank_flag = 0; - } - if (bd1[id].flash_flag) - { - //not setting yet - bd1[id].blank_flag = 0; - } - } - else - { - - if (data > 0x3F) - { - // logerror("Undefined character %x \n", data); - } - change = BD1_setdata(id, BD1charset[data & 0x3F], data); - } - break; - } - return change; -} - - - - -/////////////////////////////////////////////////////////////////////////// - -static void ScrollLeft(int id) -{ - int i = bd1[id].window_start; - - while ( i < bd1[id].window_end ) - { - bd1[id].string[ i ] = bd1[id].string[ i+1 ]; - bd1[id].segments[i] = bd1[id].segments[i+1]; - i++; - } -} - -/////////////////////////////////////////////////////////////////////////// - -static int BD1_setdata(int id, int segdata, int data) -{ - - int change = 0, move = 0; - + int move = 0; + int change =0; switch ( data ) { case 0x25: // flash - move++; + if(m_chars[m_pcursor_pos] & (1<<8)) + { + move++; + } + else + { + m_chars[m_pcursor_pos] |= (1<<8); + } break; case 0x26: // undefined @@ -465,8 +448,14 @@ static int BD1_setdata(int id, int segdata, int data) case 0x2C: // semicolon case 0x2E: // decimal point - bd1[id].segments[bd1[id].pcursor_pos] |= (1<<12); - change++; + if( m_chars[m_pcursor_pos] & (1<<12)) + { + move++; + } + else + { + m_chars[m_pcursor_pos] |= (1<<12); + } break; case 0x3B: // dummy char @@ -474,139 +463,143 @@ static int BD1_setdata(int id, int segdata, int data) break; case 0x3A: - bd1[id].user_def = 2; + m_user_def = 2; break; default: - move = 1; - change = 1; + move++; + change++; } if ( move ) { - int mode = bd1[id].display_mode; - bd1[id].pcursor_pos = bd1[id].cursor_pos; + int mode = m_display_mode; - if ( bd1[id].window_size <= 0 || (bd1[id].window_size > 16)) - { // no window selected default to rotate mode + m_pcursor_pos = m_cursor_pos; + + if ( m_window_size <= 0 || (m_window_size > 16)) + { // if no window selected default to equivalent rotate mode if ( mode == 2 ) mode = 0; else if ( mode == 3 ) mode = 1; - //mode &= -2; } switch ( mode ) { case 0: // rotate left - bd1[id].cursor_pos &= 0x0F; + m_cursor_pos &= 0x0F; if ( change ) { - bd1[id].string[bd1[id].cursor_pos] = BD1ASCII[data]; - bd1[id].segments[bd1[id].cursor_pos] = segdata; + m_chars[m_cursor_pos] = segdata; } - bd1[id].cursor_pos++; - if ( bd1[id].cursor_pos >= 16 ) bd1[id].cursor_pos = 0; + m_cursor_pos++; + if ( m_cursor_pos >= 16 ) m_cursor_pos = 0; break; case 1: // Rotate right - bd1[id].cursor_pos &= 0x0F; + m_cursor_pos &= 0x0F; if ( change ) { - bd1[id].string[bd1[id].cursor_pos] = BD1ASCII[data]; - bd1[id].segments[bd1[id].cursor_pos] = segdata; + m_chars[m_cursor_pos] = segdata; } - bd1[id].cursor_pos--; - if ( bd1[id].cursor_pos < 0 ) bd1[id].cursor_pos = 15; + m_cursor_pos--; + if ( m_cursor_pos < 0 ) m_cursor_pos = 15; break; case 2: // Scroll left - if ( bd1[id].cursor_pos < bd1[id].window_end ) + if ( m_cursor_pos < m_window_end ) { - bd1[id].scroll_active = 0; + m_scroll_active = 0; if ( change ) { - bd1[id].string[bd1[id].cursor_pos] = BD1ASCII[data]; - bd1[id].segments[bd1[id].cursor_pos] = segdata; + m_chars[m_cursor_pos] = segdata; } - if ( move ) bd1[id].cursor_pos++; + m_cursor_pos++; } else { if ( move ) { - if ( bd1[id].scroll_active ) ScrollLeft(id); - else bd1[id].scroll_active = 1; + if ( m_scroll_active ) + { + int i = m_window_start; + while ( i < m_window_end ) + { + m_chars[i] = m_chars[i+1]; + i++; + } + } + else m_scroll_active = 1; } if ( change ) { - bd1[id].string[bd1[id].window_end] = BD1ASCII[data]; - bd1[id].segments[bd1[id].cursor_pos] = segdata; + m_chars[m_window_end] = segdata; } else { - bd1[id].string[bd1[id].window_end] = ' '; - bd1[id].segments[bd1[id].cursor_pos] = 0; + m_chars[m_window_end] = 0; } } break; case 3: // Scroll right - if ( bd1[id].cursor_pos > bd1[id].window_start ) + if ( m_cursor_pos > m_window_start ) { if ( change ) { - bd1[id].string[bd1[id].cursor_pos] = BD1ASCII[data]; - bd1[id].segments[bd1[id].cursor_pos] = segdata; + m_chars[m_cursor_pos] = segdata; } - bd1[id].cursor_pos--; + m_cursor_pos--; + if ( m_cursor_pos > 15 ) m_cursor_pos = 0; } else { - int i = bd1[id].window_end; - - while ( i > bd1[id].window_start ) + if ( move ) { - bd1[id].string[ i ] = bd1[id].string[ i-1 ]; - bd1[id].segments[i] = bd1[id].segments[i-1]; - i--; - } + if ( m_scroll_active ) + { + int i = m_window_end; + while ( i > m_window_start ) + { + m_chars[i] = m_chars[i-1]; + i--; + } + } + else m_scroll_active = 1; + } if ( change ) { - bd1[id].string[bd1[id].window_start] = BD1ASCII[data]; - bd1[id].segments[bd1[id].window_start] = segdata; + m_chars[m_window_start] = segdata; + } + else + { + m_chars[m_window_start] = 0; } } break; } } - return change; } -void BFM_BD1_draw(int id) +void bfm_bd1_t::shift_data(int data) { - int cursor; - BFM_BD1_set_outputs(id); + m_shift_data <<= 1; + + if ( !data ) m_shift_data |= 1; - for (cursor = 0; cursor < 16; cursor++) + if ( ++m_shift_count >= 8 ) { - output_set_indexed_value("vfd", (id*16)+cursor, BFM_BD1_get_outputs(id)[cursor]); - - if (BFM_BD1_get_outputs(id)[cursor] & 0x40000) - { - //activate flashing (unimplemented, just toggle on and off) - } - else - { - //deactivate flashing (unimplemented) - } + write_char(m_shift_data); + m_shift_count = 0; + m_shift_data = 0; } } diff --git a/src/mame/machine/bfm_bd1.h b/src/mame/machine/bfm_bd1.h index a6edb0372e2..85703568e68 100644 --- a/src/mame/machine/bfm_bd1.h +++ b/src/mame/machine/bfm_bd1.h @@ -1,22 +1,70 @@ -#ifndef BFM_BD1 -#define BFM_BD1 +#pragma once +#ifndef BFM_BD1_H +#define BFM_BD1_H -#define MAX_BD1 3 // max number of displays emulated +//Based on the datasheet, the makimum oscillation rate for one character is 31.25 KHz, so we set our character clock to that. +#define MCFG_BFMBD1_ADD(_tag,_val) \ + MCFG_DEVICE_ADD(_tag, BFM_BD1,312500)\ + MCFG_BD1_PORT(_val) \ -void BFM_BD1_init( int id ); // setup a display +#define MCFG_BD1_PORT(_val) \ + bfm_bd1_t::static_set_value(*device, _val); \ -void BFM_BD1_reset( int id); // reset the alpha +#define MCFG_BFMBD1_REMOVE(_tag) \ + MCFG_DEVICE_REMOVE(_tag) + +class bfm_bd1_t : public device_t +{ +public: + typedef delegate line_cb; + bfm_bd1_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); -void BFM_BD1_shift_data(int id, int data); // clock in a bit of data -int BFM_BD1_newdata( int id, int data); // clock in 8 bits of data + // inline configuration helpers + static void static_set_value(device_t &device, int val); -UINT32 *BFM_BD1_get_segments(int id); // get current segments displayed -UINT32 *BFM_BD1_set_outputs(int id); // convert segments to standard for display -UINT32 *BFM_BD1_get_outputs(int id); // get converted segments + int write_char(int data); + virtual void update_display(); + UINT8 m_port_val; + void blank(int data); + void shift_data(int data); + void setdata(int segdata, int data); + UINT32 set_display(UINT16 segin); -char *BFM_BD1_get_string( int id); // get current string displayed (not as accurate) +protected: + static const UINT8 AT_NORMAL = 0x00; + static const UINT8 AT_FLASH = 0x01; + static const UINT8 AT_FLASHED = 0x80; // set when character should be blinked off -void BFM_BD1_draw(int id); + emu_timer *m_timer; + + int m_cursor_pos; + int m_window_start; // display window start pos 0-15 + int m_window_end; // display window end pos 0-15 + int m_window_size; // window size + int m_shift_count; + int m_shift_data; + int m_pcursor_pos; + int m_blank_flag; + int m_flash_flag; + int m_scroll_active; + int m_display_mode; + int m_flash_rate; + int m_flash_control; + UINT8 m_cursor; + UINT16 m_chars[16]; + UINT16 m_outputs[16]; + UINT8 m_attrs[16]; + UINT16 m_user_data; // user defined character data (16 bit) + UINT16 m_user_def; // user defined character state + + virtual void device_start(); + virtual void device_reset(); + virtual void device_post_load(); + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); + +}; + +extern const device_type BFM_BD1; #endif diff --git a/src/mame/video/bfm_adr2.c b/src/mame/video/bfm_adr2.c index 3fc7b7d7e6f..6217ddfd176 100644 --- a/src/mame/video/bfm_adr2.c +++ b/src/mame/video/bfm_adr2.c @@ -248,15 +248,6 @@ PALETTE_INIT( adder2 ) /////////////////////////////////////////////////////////////////////////// -MACHINE_RESET( adder2 ) -{ - // setup the standard bellfruit BD1 display ///////////////////////////// - - BFM_BD1_init(0); -} - -/////////////////////////////////////////////////////////////////////////// - INTERRUPT_GEN( adder2_vbl ) { if ( adder2_c101 & 0x01 )