GSaha567/seq_level_training_data
052
1text,length,is_long_context,metric_val,label_metric2"// license:GPL-2.0+3// copyright-holders:Angelo Salese, Jonathan Edwards, Christopher Edwards,Robbbert4/**************************************************************************************5 6 Basic Master Level 3 (MB-689x) (c) 1980 Hitachi7 8 Driver by Angelo Salese, Jonathan Edwards and Christopher Edwards9 10 TODO:11 - implement sound as a bml3bus slot device12 - account for hardware differences between MB-6890, MB-6891 and MB-689213 (e.g. custom font support on the MB-6892)14 15**************************************************************************************/16 17#include ""emu.h""18 19#include ""cpu/m6809/m6809.h""20#include ""imagedev/cassette.h""21#include ""machine/6821pia.h""22#include ""machine/6850acia.h""23#include ""machine/clock.h""24#include ""machine/timer.h""25#include ""sound/2203intf.h""26#include ""sound/spkrdev.h""27#include ""sound/wave.h""28#include ""video/mc6845.h""29 30#include ""bus/bml3/bml3bus.h""31#include ""bus/bml3/bml3mp1802.h""32#include ""bus/bml3/bml3mp1805.h""33#include ""bus/bml3/bml3kanji.h""34 35#include ""screen.h""36#include ""speaker.h""37 38// System clock definitions, from the MB-6890 servce manual, p.48:39 40#define MASTER_CLOCK ( 32256000 ) // Master clock crystal (X1) frequency, 32.256 MHz. ""fx"" in the manual.41 42#define D80_CLOCK ( MASTER_CLOCK / 2 ) // Graphics dot clock in 80-column mode. ~16 MHz.43#define D40_CLOCK ( D80_CLOCK / 2 ) // Graphics dot clock in 40-column mode. ~8 MHz.44 45#define CPU_EXT_CLOCK ( D40_CLOCK / 2 ) // IC37, 4.032 MHz signal to EXTAL on the 6809 MPU.46#define CPU_CLOCK ( CPU_EXT_CLOCK / 4 ) // Actual MPU clock frequency (""fE"" in the manual). The division yielding CPU_CLOCK is done in the 6809 itself. Also used as the 40-column character clock.47 48#define C80_CLOCK ( CPU_EXT_CLOCK / 2 ) // 80-column character mode. IC37, ""80CHRCK""; ~2 MHz.49#define C40_CLOCK ( CPU_CLOCK ) // 40-column character mode; same as MPU clock. ""40CHRCK""; ~1 MHz.50 51// Video signal clocks from the HD4650SSP CRTC (IC36)52// In the real hardware, the 80-/40-column Mode switch changes the CRTC character clock input source. However, it just uses a different divider, so the end result is the same horizontal vsync frequency.53#define H_CLOCK ( C80_CLOCK / 128 ) // in 80-column mode54//#define H_CLOCK ( C40_CLOCK / 64 ) // in 40-column mode (either way the frequency is the same: 15.75 kHz)55#define V_CLOCK ( 2 * H_CLOCK / 525 ) // Vertical refresh rate comes out at exactly 60 Hz.56 57// TODO: ACIA RS-232C and cassette interface clocks (service manual p.67); perhaps reverse the order and simply divide by 2 from each previous frequency.58// IC111 (74LS157P) takes 16.128 MHz and 1.008 MHz TTL clock inputs. The RS/C SW input line determines the mode (high -> RS-232C).59 60// Frequencies for RS-232C mode:61// D80_CLOCK / 840.0 // 19200 Hz62// D80_CLOCK / 420 // 38400 Hz63// D80_CLOCK / 210 // 76800 Hz64// D80_CLOCK / 105.0 // 153600 Hz65 66// Frequencies for cassette mode:67// / 13440 //120068// / 6720 // 240069// / 3360 // 480070// / 1680 // 960071 72 73class bml3_state : public driver_device74{75public:76 bml3_state(const machine_config &mconfig, device_type type, const char *tag)77 : driver_device(mconfig, type, tag)78 , m_maincpu(*this, ""maincpu"")79 , m_p_videoram(*this, ""vram"")80 , m_p_chargen(*this, ""chargen"")81 , m_bml3bus(*this, ""bml3bus"")82 , m_crtc(*this, ""crtc"")83 , m_cass(*this, ""cassette"")84 , m_speaker(*this, ""speaker"")85 , m_ym2203(*this, ""ym2203"")86 , m_acia(*this, ""acia"")87 , m_palette(*this, ""palette"")88 {89 }90 91 DECLARE_READ8_MEMBER(bml3_6845_r);92 DECLARE_WRITE8_MEMBER(bml3_6845_w);93 DECLARE_READ8_MEMBER(bml3_keyboard_r);94 DECLARE_WRITE8_MEMBER(bml3_keyboard_w);95 DECLARE_WRITE8_MEMBER(bml3_hres_reg_w);96 DECLARE_WRITE8_MEMBER(bml3_vres_reg_w);97 DECLARE_READ8_MEMBER(bml3_vram_r);98 DECLARE_WRITE8_MEMBER(bml3_vram_w);99 DECLARE_READ8_MEMBER(bml3_psg_latch_r);100 DECLARE_WRITE8_MEMBER(bml3_psg_latch_w);101 DECLARE_READ8_MEMBER(bml3_vram_attr_r);102 DECLARE_WRITE8_MEMBER(bml3_vram_attr_w);103 DECLARE_READ8_MEMBER(bml3_beep_r);104 DECLARE_WRITE8_MEMBER(bml3_beep_w);105 DECLARE_WRITE8_MEMBER(bml3_piaA_w);106 DECLARE_READ8_MEMBER(bml3_keyb_nmi_r);107 DECLARE_WRITE8_MEMBER(bml3_firq_mask_w);108 DECLARE_READ8_MEMBER(bml3_firq_status_r);109 DECLARE_WRITE8_MEMBER(relay_w);110 DECLARE_WRITE_LINE_MEMBER(bml3bus_nmi_w);111 DECLARE_WRITE_LINE_MEMBER(bml3bus_irq_w);112 DECLARE_WRITE_LINE_MEMBER(bml3bus_firq_w);113 DECLARE_WRITE_LINE_MEMBER(bml3_acia_tx_w);114 DECLARE_WRITE_LINE_MEMBER(bml3_acia_rts_w);115 DECLARE_WRITE_LINE_MEMBER(bml3_acia_irq_w);116 117 DECLARE_READ8_MEMBER(bml3_a000_r); DECLARE_WRITE8_MEMBER(bml3_a000_w);118 DECLARE_READ8_MEMBER(bml3_c000_r); DECLARE_WRITE8_MEMBER(bml3_c000_w);119 DECLARE_READ8_MEMBER(bml3_e000_r); DECLARE_WRITE8_MEMBER(bml3_e000_w);120 DECLARE_READ8_MEMBER(bml3_f000_r); DECLARE_WRITE8_MEMBER(bml3_f000_w);121 DECLARE_READ8_MEMBER(bml3_fff0_r); DECLARE_WRITE8_MEMBER(bml3_fff0_w);122 123 MC6845_UPDATE_ROW(crtc_update_row);124 125 // INTERRUPT_GEN_MEMBER(bml3_irq);126 INTERRUPT_GEN_MEMBER(bml3_timer_firq);127 TIMER_DEVICE_CALLBACK_MEMBER(bml3_c);128 TIMER_DEVICE_CALLBACK_MEMBER(bml3_p);129 TIMER_DEVICE_CALLBACK_MEMBER(keyboard_callback);130 DECLARE_READ8_MEMBER(bml3_ym2203_r);131 DECLARE_WRITE8_MEMBER(bml3_ym2203_w);132 133 void bml3mk2(machine_config &config);134 void bml3mk5(machine_config &config);135 void bml3(machine_config &config);136 void bml3_common(machine_config &config);137 void bml3_mem(address_map &map);138 void bml3mk2_mem(address_map &map);139 void bml3mk5_mem(address_map &map);140private:141 u8 m_hres_reg;142 u8 m_crtc_vreg[0x100];143 u8 m_psg_latch;144 u8 m_attr_latch;145 u8 m_vres_reg;146 bool m_keyb_interrupt_disabled;147 bool m_keyb_nmi_disabled; // not used yet148 bool m_keyb_counter_operation_disabled;149 u8 m_keyb_empty_scan;150 u8 m_keyb_scancode;151 bool m_keyb_capslock_led_on;152 bool m_keyb_hiragana_led_on;153 bool m_keyb_katakana_led_on;154 bool m_cassbit;155 bool m_cassold;156 u8 m_cass_data[4];157 virtual void machine_reset() override;158 virtual void machine_start() override;159 void m6845_change_clock(u8 setting);160 u8 m_crtc_index;161 std::unique_ptr<u8[]> m_extram;162 u8 m_firq_mask;163 u8 m_firq_status;164 required_device<cpu_device> m_maincpu;165 required_region_ptr<u8> m_p_videoram;166 required_region_ptr<u8> m_p_chargen;167 required_device<bml3bus_device> m_bml3bus;168 required_device<mc6845_device> m_crtc;169 required_device<cassette_image_device> m_cass;170 required_device<speaker_sound_device> m_speaker;171 optional_device<ym2203_device> m_ym2203;172 required_device<acia6850_device> m_acia;173 required_device<palette_device> m_palette;174};175 176#define mc6845_h_char_total (m_crtc_vreg[0])177#define mc6845_h_display (m_crtc_vreg[1])178#define mc6845_h_sync_pos (m_crtc_vreg[2])179#define mc6845_sync_width (m_crtc_vreg[3])180#define mc6845_v_char_total (m_crtc_vreg[4])181#define mc6845_v_total_adj (m_crtc_vreg[5])182#define mc6845_v_display (m_crtc_vreg[6])183#define mc6845_v_sync_pos (m_crtc_vreg[7])184#define mc6845_mode_ctrl (m_crtc_vreg[8])185#define mc6845_tile_height (m_crtc_vreg[9]+1)186#define mc6845_cursor_y_start (m_crtc_vreg[0x0a])187#define mc6845_cursor_y_end (m_crtc_vreg[0x0b])188#define mc6845_start_addr (((m_crtc_vreg[0x0c]<<8) & 0x3f00) | (m_crtc_vreg[0x0d] & 0xff))189#define mc6845_cursor_addr (((m_crtc_vreg[0x0e]<<8) & 0x3f00) | (m_crtc_vreg[0x0f] & 0xff))190#define mc6845_light_pen_addr (((m_crtc_vreg[0x10]<<8) & 0x3f00) | (m_crtc_vreg[0x11] & 0xff))191#define mc6845_update_addr (((m_crtc_vreg[0x12]<<8) & 0x3f00) | (m_crtc_vreg[0x13] & 0xff))192 193 194 195READ8_MEMBER( bml3_state::bml3_6845_r )196{197 if (offset)198 return m_crtc->register_r(space, 0);199 else200 return m_crtc->status_r(space, 0);201}202 203WRITE8_MEMBER( bml3_state::bml3_6845_w )204{205 if(offset == 0)206 {207 m_crtc_index = data;208 m_crtc->address_w(space, 0, data);209 }210 else211 {212 m_crtc_vreg[m_crtc_index] = data;213 m_crtc->register_w(space, 0, data);214 }215}216 217READ8_MEMBER( bml3_state::bml3_keyboard_r )218{219 u8 ret = m_keyb_scancode;220 m_keyb_scancode &= 0x7f;221 return ret;222}223 224WRITE8_MEMBER( bml3_state::bml3_keyboard_w )225{226 m_keyb_katakana_led_on = BIT(data, 0);227 m_keyb_hiragana_led_on = BIT(data, 1);228 m_keyb_capslock_led_on = BIT(data, 2);229 m_keyb_counter_operation_disabled = BIT(data, 3);230 m_keyb_interrupt_disabled = !BIT(data, 6);231 m_keyb_nmi_disabled = !BIT(data, 7);232}233 234void bml3_state::m6845_change_clock(u8 setting)235{236 int m6845_clock = CPU_CLOCK; // CRTC and MPU are synchronous by default237 238 switch(setting & 0x88)239 {240 case 0x00: m6845_clock = C40_CLOCK; break; //320 x 200241 case 0x08: m6845_clock = C40_CLOCK; break; //320 x 200, interlace242 case 0x80: m6845_clock = C80_CLOCK; break; //640 x 200243 case 0x88: m6845_clock = C80_CLOCK; break; //640 x 200, interlace244 }245 246 m_crtc->set_clock(m6845_clock);247}248 249WRITE8_MEMBER( bml3_state::bml3_hres_reg_w )250{251 // MODE SEL register (see service manual p.43).252 /*253 x--- ---- ""W"" bit: 0 = 40 columns, 1 = 80 columns254 -x-- ---- ""HR"" bit: 0 = high resolution, 1 = normal255 --x- ---- ""C"" bit - ACIA mode: 0 = cassette, 1 = RS-232C256 ---- -RGB Background colour257 */258 259 m_hres_reg = data;260 261 m6845_change_clock((m_hres_reg & 0x80) | (m_vres_reg & 0x08));262}263 264WRITE8_MEMBER( bml3_state::bml3_vres_reg_w )265{266 // The MB-6890 had an interlaced video mode which was used for displaying Japanese (Hiragana and Katakana) text (8x16 character glyph bitmaps).267 /*268 ---- x--- Interlace select: 0 = non-interlace, 1 = interlace269 */270 m_vres_reg = data;271 272 m6845_change_clock((m_hres_reg & 0x80) | (m_vres_reg & 0x08));273}274 275 276READ8_MEMBER( bml3_state::bml3_vram_r )277{278 // Bit 7 masks reading back to the latch279 if (!BIT(m_attr_latch, 7))280 {281 m_attr_latch = m_p_videoram[offset+0x4000];282 }283 284 return m_p_videoram[offset];285}286 287WRITE8_MEMBER( bml3_state::bml3_vram_w )288{289 m_p_videoram[offset] = data;290 // color ram is 5-bit291 m_p_videoram[offset+0x4000] = m_attr_latch & 0x1F;292}293 294READ8_MEMBER( bml3_state::bml3_psg_latch_r)295{296 return 0x7f;297}298 299WRITE8_MEMBER( bml3_state::bml3_psg_latch_w)300{301 m_psg_latch = data;302}303 304READ8_MEMBER(bml3_state::bml3_ym2203_r)305{306 u8 dev_offs = ((m_psg_latch & 3) != 3);307 308 return m_ym2203->read(space, dev_offs);309}310 311WRITE8_MEMBER(bml3_state::bml3_ym2203_w)312{313 u8 dev_offs = ((m_psg_latch & 3) != 3);314 315 m_ym2203->write(space, dev_offs, data);316}317 318READ8_MEMBER( bml3_state::bml3_vram_attr_r)319{320 // C-REG-SELECT register321 // Reads from a VRAM address copy the corresponding 'colour RAM' address to the low-order 5 bits of this register as a side-effect322 // (unless MK bit indicates 'prohibit write')323 return m_attr_latch;324}325 326WRITE8_MEMBER( bml3_state::bml3_vram_attr_w)327{328 // C-REG-SELECT register329 // Writes to a VRAM address copy the low-order 5 bits of this register to the corresponding 'colour RAM' address as a side-effect330 /*331 x--- ---- ""MK"" bit: 0 = enable write, 1 = prohibit write332 ---x ---- ""GC"" bit: 0 = character, 1 = graphic333 ---- x--- ""RV"" bit: 0 = normal, 1 - reverse334 ---- -RGB Foreground colour335 */336 m_attr_latch = data;337}338 339READ8_MEMBER( bml3_state::bml3_beep_r)340{341 return -1; // BEEP status read?342}343 344WRITE8_MEMBER( bml3_state::bml3_beep_w)345{346 m_speaker->level_w(BIT(data, 7));347}348 349WRITE8_MEMBER( bml3_state::relay_w )350{351 m_cass->change_state(352 BIT(data,7) ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED, CASSETTE_MASK_MOTOR);353}354 355READ8_MEMBER( bml3_state::bml3_a000_r) { return m_extram[offset + 0xa000]; }356WRITE8_MEMBER( bml3_state::bml3_a000_w) { m_extram[offset + 0xa000] = data; }357READ8_MEMBER( bml3_state::bml3_c000_r) { return m_extram[offset + 0xc000]; }358WRITE8_MEMBER( bml3_state::bml3_c000_w) { m_extram[offset + 0xc000] = data; }359READ8_MEMBER( bml3_state::bml3_e000_r) { return m_extram[offset + 0xe000]; }360WRITE8_MEMBER( bml3_state::bml3_e000_w) { m_extram[offset + 0xe000] = data; }361READ8_MEMBER( bml3_state::bml3_f000_r) { return m_extram[offset + 0xf000]; }362WRITE8_MEMBER( bml3_state::bml3_f000_w) { m_extram[offset + 0xf000] = data; }363READ8_MEMBER( bml3_state::bml3_fff0_r) { return m_extram[offset + 0xfff0]; }364WRITE8_MEMBER( bml3_state::bml3_fff0_w) { m_extram[offset + 0xfff0] = data; }365 366READ8_MEMBER( bml3_state::bml3_keyb_nmi_r)367{368 return 0; // bit 7 used to signal a BREAK key pressure369}370 371WRITE8_MEMBER( bml3_state::bml3_firq_mask_w)372{373 m_firq_mask = data & 0x80;374 if(m_firq_mask)375 {376 m_firq_status = 0; // clear pending firq377 m_maincpu->set_input_line(M6809_FIRQ_LINE, CLEAR_LINE);378 }379}380 381READ8_MEMBER( bml3_state::bml3_firq_status_r )382{383 u8 res = m_firq_status << 7;384 m_firq_status = 0;385 m_maincpu->set_input_line(M6809_FIRQ_LINE, CLEAR_LINE);386 return res;387}388 389WRITE_LINE_MEMBER(bml3_state::bml3bus_nmi_w)390{391 m_maincpu->set_input_line(INPUT_LINE_NMI, state);392}393 394WRITE_LINE_MEMBER(bml3_state::bml3bus_irq_w)395{396 m_maincpu->set_input_line(M6809_IRQ_LINE, state);397}398 399WRITE_LINE_MEMBER(bml3_state::bml3bus_firq_w)400{401 m_maincpu->set_input_line(M6809_FIRQ_LINE, state);402}403 404 405void bml3_state::bml3_mem(address_map &map)406{407 map.unmap_value_high();408 map(0x0000, 0x03ff).ram();409 map(0x0400, 0x43ff).rw(this, FUNC(bml3_state::bml3_vram_r), FUNC(bml3_state::bml3_vram_w));410 map(0x4400, 0x9fff).ram();411 map(0xff40, 0xff46).noprw(); // lots of unknown reads and writes412 map(0xffc0, 0xffc3).rw(""pia"", FUNC(pia6821_device::read), FUNC(pia6821_device::write));413 map(0xffc4, 0xffc5).rw(m_acia, FUNC(acia6850_device::read), FUNC(acia6850_device::write));414 map(0xffc6, 0xffc7).rw(this, FUNC(bml3_state::bml3_6845_r), FUNC(bml3_state::bml3_6845_w));415 // KBNMI - Keyboard ""Break"" key non-maskable interrupt416 map(0xffc8, 0xffc8).r(this, FUNC(bml3_state::bml3_keyb_nmi_r)); // keyboard nmi417 // DIPSW - DIP switches on system mainboard418 map(0xffc9, 0xffc9).portr(""DSW"");419 // TIMER - System timer enable420 map(0xffca, 0xffca).r(this, FUNC(bml3_state::bml3_firq_status_r)); // timer irq421 // LPFLG - Light pen interrupt422// AM_RANGE(0xffcb, 0xffcb)423 // MODE_SEL - Graphics mode select424 map(0xffd0, 0xffd0).w(this, FUNC(bml3_state::bml3_hres_reg_w));425 // TRACE - Trace counter426// AM_RANGE(0xffd1, 0xffd1)427 // REMOTE - Remote relay control for cassette - bit 7428 map(0xffd2, 0xffd2).w(this, FUNC(bml3_state::relay_w));429 // MUSIC_SEL - Music select: toggle audio output level when rising430 map(0xffd3, 0xffd3).rw(this, FUNC(bml3_state::bml3_beep_r), FUNC(bml3_state::bml3_beep_w));431 // TIME_MASK - Prohibit timer IRQ432 map(0xffd4, 0xffd4).w(this, FUNC(bml3_state::bml3_firq_mask_w));433 // LPENBL - Light pen operation enable434 map(0xffd5, 0xffd5).noprw();435 // INTERLACE_SEL - Interlaced video mode (manual has ""INTERACE SEL""!)436 map(0xffd6, 0xffd6).w(this, FUNC(bml3_state::bml3_vres_reg_w));437// AM_RANGE(0xffd7, 0xffd7) baud select438 // C_REG_SEL - Attribute register (character/video mode and colours)439 map(0xffd8, 0xffd8).rw(this, FUNC(bml3_state::bml3_vram_attr_r), FUNC(bml3_state::bml3_vram_attr_w));440 // KB - Keyboard mode register, interrupt control, keyboard LEDs441 map(0xffe0, 0xffe0).rw(this, FUNC(bml3_state::bml3_keyboard_r), FUNC(bml3_state::bml3_keyboard_w));442// AM_RANGE(0xffe8, 0xffe8) bank register443// AM_RANGE(0xffe9, 0xffe9) IG mode register444// AM_RANGE(0xffea, 0xffea) IG enable register445 map(0xa000, 0xfeff).rom().region(""maincpu"", 0xa000);446 map(0xfff0, 0xffff).rom().region(""maincpu"", 0xfff0);447 map(0xa000, 0xbfff).w(this, FUNC(bml3_state::bml3_a000_w));448 map(0xc000, 0xdfff).w(this, FUNC(bml3_state::bml3_c000_w));449 map(0xe000, 0xefff).w(this, FUNC(bml3_state::bml3_e000_w));450 map(0xf000, 0xfeff).w(this, FUNC(bml3_state::bml3_f000_w));451 map(0xfff0, 0xffff).w(this, FUNC(bml3_state::bml3_fff0_w));452 453#if 0454 map(0xff00, 0xff00).rw(this, FUNC(bml3_state::bml3_ym2203_r), FUNC(bml3_state::bml3_ym2203_w));455 map(0xff02, 0xff02).rw(this, FUNC(bml3_state::bml3_psg_latch_r), FUNC(bml3_state::bml3_psg_latch_w)); // PSG address/data select456#endif457}458 459void bml3_state::bml3mk2_mem(address_map &map)460{461 bml3_mem(map);462 // TODO: anything to add here?463 464}465 466void bml3_state::bml3mk5_mem(address_map &map)467{468 bml3_mem(map);469 // TODO: anything to add here?470 471}472 473/* Input ports */474 475static INPUT_PORTS_START( bml3 )476 477 // DIP switches (service manual p.88)478 // Note the NEWON command reboots with a soft override for the DIP switch479 PORT_START(""DSW"")480 PORT_DIPNAME( 0x01, 0x01, ""BASIC/terminal mode"")481 PORT_DIPSETTING(0x00, ""Terminal mode"")482 PORT_DIPSETTING(0x01, ""BASIC mode"")483 PORT_DIPNAME( 0x02, 0x02, ""Interlaced video"")484 PORT_DIPSETTING(0x00, DEF_STR( Off ) )485 PORT_DIPSETTING(0x02, DEF_STR( On ))486 // This is overridden by the 'Mode' toggle button487 PORT_DIPNAME( 0x04, 0x04, ""40-/80-column"")488 PORT_DIPSETTING(0x00, ""40 chars/line"")489 PORT_DIPSETTING(0x04, ""80 chars/line"")490 PORT_DIPNAME( 0x08, 0x00, ""Video resolution"")491 PORT_DIPSETTING(0x00, ""High"")492 PORT_DIPSETTING(0x08, ""Low"")493 PORT_DIPNAME( 0x10, 0x00, ""Show PF key content"")494 PORT_DIPSETTING(0x00, DEF_STR ( Off ) )495 PORT_DIPSETTING(0x10, DEF_STR ( On ))496 PORT_DIPNAME( 0x20, 0x00, ""Terminal duplex"")497 PORT_DIPSETTING(0x00, ""Full duplex"")498 PORT_DIPSETTING(0x20, ""Half duplex"")499 PORT_DIPNAME( 0x40, 0x00, ""Terminal bits"")500 PORT_DIPSETTING(0x00, ""8 bits/char"")501 PORT_DIPSETTING(0x40, ""7 bits/char"")502 PORT_DIPNAME( 0x80, 0x00, ""Hiragana->Katakana"")503 PORT_DIPSETTING( 0x00, DEF_STR( Off ) )504 PORT_DIPSETTING( 0x80, DEF_STR( On ) )505 506// TODO: also model the CS jumper block?507 508 // RAM expansion configurations (see service manual p.76)509/*510 PORT_START(""RAM"")511 PORT_DIPNAME( 0x0003, 0x0002, ""RAM size"" )512 PORT_DIPSETTING( 0x0000, ""32 kiB (standard)"" )513 PORT_DIPSETTING( 0x0001, ""40 kiB (32 kiB + 8 kiB)"" )514 PORT_DIPSETTING( 0x0002, ""60 kiB (32 kiB + 28 kiB)"" )515*/516 517 PORT_START(""key1"") //0x00-0x1f518 PORT_BIT(0x00000001,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""Space"") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ')519 PORT_BIT(0x00000002,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""Up"") PORT_CODE(KEYCODE_UP)520 PORT_BIT(0x00000004,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""? PAD"") PORT_CHAR('?')521 PORT_BIT(0x00000008,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""Left"") PORT_CODE(KEYCODE_LEFT)522 PORT_BIT(0x00000010,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""Down"") PORT_CODE(KEYCODE_DOWN)523 PORT_BIT(0x00000020,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""Right"") PORT_CODE(KEYCODE_RIGHT)524 PORT_BIT(0x00000040,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""Control"") PORT_CODE(KEYCODE_LCONTROL)525 PORT_BIT(0x00000080,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""Shift"")PORT_CODE(KEYCODE_LSHIFT)526 PORT_BIT(0x00000100,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""X2"") // ???527 PORT_BIT(0x00000200,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""Caps Lock"") PORT_CODE(KEYCODE_CAPSLOCK)528 PORT_BIT(0x00000400,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""Kana Lock"") PORT_CODE(KEYCODE_NUMLOCK)529 PORT_BIT(0x00000800,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""Kana Shift"") PORT_CODE(KEYCODE_LALT)530 PORT_BIT(0x00001000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""ESC"") PORT_CODE(KEYCODE_ESC)531 PORT_BIT(0x00002000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""8 PAD"") PORT_CODE(KEYCODE_8_PAD) PORT_CHAR('8')532 PORT_BIT(0x00004000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""9 PAD"") PORT_CODE(KEYCODE_9_PAD) PORT_CHAR('9')533 PORT_BIT(0x00008000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""*"") PORT_CODE(KEYCODE_ASTERISK) PORT_CHAR('*')534 PORT_BIT(0x00010000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""7"") PORT_CODE(KEYCODE_7) PORT_CHAR('7')535 PORT_BIT(0x00020000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""4"") PORT_CODE(KEYCODE_4) PORT_CHAR('4')536 PORT_BIT(0x00040000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""6"") PORT_CODE(KEYCODE_6) PORT_CHAR('6')537 PORT_BIT(0x00080000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""8"") PORT_CODE(KEYCODE_8) PORT_CHAR('8')538 PORT_BIT(0x00100000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""0"") PORT_CODE(KEYCODE_0) PORT_CHAR('0')539 PORT_BIT(0x00200000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""^"") PORT_CODE(KEYCODE_BACKSLASH)540 PORT_BIT(0x00400000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""-"") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-')541 PORT_BIT(0x00800000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""3"") PORT_CODE(KEYCODE_3) PORT_CHAR('3')542 PORT_BIT(0x01000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""Delete"") PORT_CODE(KEYCODE_BACKSPACE)543 PORT_BIT(0x02000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""5"") PORT_CODE(KEYCODE_5) PORT_CHAR('5')544 PORT_BIT(0x04000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""1"") PORT_CODE(KEYCODE_1) PORT_CHAR('1')545 PORT_BIT(0x08000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""2"") PORT_CODE(KEYCODE_2) PORT_CHAR('2')546 PORT_BIT(0x10000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""9"") PORT_CODE(KEYCODE_9) PORT_CHAR('9')547 PORT_BIT(0x20000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""7 PAD"") PORT_CODE(KEYCODE_7_PAD) PORT_CHAR('7')548 PORT_BIT(0x40000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""Delete PAD"") //backspace549 PORT_BIT(0x80000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""\\xC2\\xA5"") PORT_CODE(KEYCODE_TAB) // yen sign550 551 PORT_START(""key2"") //0x20-0x3f552 PORT_BIT(0x00000001,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""U"") PORT_CODE(KEYCODE_U)553 PORT_BIT(0x00000002,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""R"") PORT_CODE(KEYCODE_R)554 PORT_BIT(0x00000004,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""Y"") PORT_CODE(KEYCODE_Y)555 PORT_BIT(0x00000008,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""I"") PORT_CODE(KEYCODE_I)556 PORT_BIT(0x00000010,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""P"") PORT_CODE(KEYCODE_P)557 PORT_BIT(0x00000020,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""["") PORT_CODE(KEYCODE_OPENBRACE)558 PORT_BIT(0x00000040,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""@"") PORT_CODE(KEYCODE_EQUALS)559 PORT_BIT(0x00000080,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""0 PAD"") PORT_CODE(KEYCODE_0_PAD) PORT_CHAR('0')560 PORT_BIT(0x00000100,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""Q"") PORT_CODE(KEYCODE_Q)561 PORT_BIT(0x00000200,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""T"") PORT_CODE(KEYCODE_T)562 PORT_BIT(0x00000400,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""W"") PORT_CODE(KEYCODE_W)563 PORT_BIT(0x00000800,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""E"") PORT_CODE(KEYCODE_E)564 PORT_BIT(0x00001000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""O"") PORT_CODE(KEYCODE_O)565 PORT_BIT(0x00002000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("". PAD"") PORT_CODE(KEYCODE_DEL_PAD) PORT_CHAR('.')566 PORT_BIT(0x00004000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""HOME"") PORT_CODE(KEYCODE_HOME) //or cls?567 PORT_BIT(0x00008000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""ENTER"") PORT_CODE(KEYCODE_ENTER)568 PORT_BIT(0x00010000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""J"") PORT_CODE(KEYCODE_J)569 PORT_BIT(0x00020000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""F"") PORT_CODE(KEYCODE_F)570 PORT_BIT(0x00040000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""H"") PORT_CODE(KEYCODE_H)571 PORT_BIT(0x00080000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""K"") PORT_CODE(KEYCODE_K)572 PORT_BIT(0x00100000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("";"") PORT_CODE(KEYCODE_COLON)573 PORT_BIT(0x00200000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""]"") PORT_CODE(KEYCODE_CLOSEBRACE)574 PORT_BIT(0x00400000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("":"") PORT_CODE(KEYCODE_QUOTE)575 PORT_BIT(0x00800000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""4 PAD"") PORT_CODE(KEYCODE_4_PAD) PORT_CHAR('4')576 PORT_BIT(0x01000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""A"") PORT_CODE(KEYCODE_A)577 PORT_BIT(0x02000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""G"") PORT_CODE(KEYCODE_G)578 PORT_BIT(0x04000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""S"") PORT_CODE(KEYCODE_S)579 PORT_BIT(0x08000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""D"") PORT_CODE(KEYCODE_D)580 PORT_BIT(0x10000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""L"") PORT_CODE(KEYCODE_L)581 PORT_BIT(0x20000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""5 PAD"") PORT_CODE(KEYCODE_5_PAD) PORT_CHAR('5')582 PORT_BIT(0x40000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""6 PAD"") PORT_CODE(KEYCODE_6_PAD) PORT_CHAR('6')583 PORT_BIT(0x80000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""- PAD"") PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHAR('-')584 585 PORT_START(""key3"") //0x40-0x5f586 PORT_BIT(0x00000001,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""M"") PORT_CODE(KEYCODE_M)587 PORT_BIT(0x00000002,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""V"") PORT_CODE(KEYCODE_V)588 PORT_BIT(0x00000004,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""N"") PORT_CODE(KEYCODE_N)589 PORT_BIT(0x00000008,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("","") PORT_CODE(KEYCODE_COMMA)590 PORT_BIT(0x00000010,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""/"") PORT_CODE(KEYCODE_SLASH)591 PORT_BIT(0x00000020,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""/ PAD"") PORT_CODE(KEYCODE_SLASH_PAD) PORT_CHAR('/')592 PORT_BIT(0x00000040,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""_"") PORT_CODE(KEYCODE_TILDE)593 PORT_BIT(0x00000080,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""1 PAD"") PORT_CODE(KEYCODE_1_PAD) PORT_CHAR('1')594 PORT_BIT(0x00000100,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""Z"") PORT_CODE(KEYCODE_Z)595 PORT_BIT(0x00000200,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""B"") PORT_CODE(KEYCODE_B)596 PORT_BIT(0x00000400,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""X"") PORT_CODE(KEYCODE_X)597 PORT_BIT(0x00000800,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""C"") PORT_CODE(KEYCODE_C)598 PORT_BIT(0x00001000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""."") PORT_CODE(KEYCODE_STOP)599 PORT_BIT(0x00002000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""2 PAD"") PORT_CODE(KEYCODE_2_PAD) PORT_CHAR('2')600 PORT_BIT(0x00004000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""3 PAD"") PORT_CODE(KEYCODE_3_PAD) PORT_CHAR('3')601 PORT_BIT(0x00008000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""+"") PORT_CODE(KEYCODE_PLUS_PAD)602 PORT_BIT(0x00010000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""PF1"") PORT_CODE(KEYCODE_F1)603 PORT_BIT(0x00020000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""PF2"") PORT_CODE(KEYCODE_F2)604 PORT_BIT(0x00040000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""PF3"") PORT_CODE(KEYCODE_F3)605 PORT_BIT(0x00080000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""PF4"") PORT_CODE(KEYCODE_F4)606 PORT_BIT(0x00100000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(""PF5"") PORT_CODE(KEYCODE_F5)607 PORT_BIT(0xffe00000,IP_ACTIVE_HIGH,IPT_UNKNOWN)608INPUT_PORTS_END609 610MC6845_UPDATE_ROW( bml3_state::crtc_update_row )611{612 const rgb_t *palette = m_palette->palette()->entry_list_raw();613 // The MB-6890 has a 5-bit colour RAM region. The meaning of the bits are:614 // 0: blue615 // 1: red616 // 2: green617 // 3: reverse/inverse video618 // 4: graphic (not character)619 620 u8 x=0,hf=0,xi=0,interlace=0,bgcolor=0,rawbits=0,dots[2],color=0,pen=0;621 bool reverse=0,graphic=0,lowres=0;622 u16 mem=0;623 624 interlace = (m_crtc_vreg[8] & 3) ? 1 : 0;625 lowres = BIT(m_hres_reg, 6);626 bgcolor = m_hres_reg & 7;627 628 if (interlace)629 {630 ra >>= 1;631 if (y > 0x176) return;632 }633 634 // redundant initializers to keep compiler happy635 dots[0] = dots[1] = 0;636 637 for(x=0; x<x_count; x++)638 {639 if (lowres)640 mem = (ma + x - 0x400) & 0x3fff;641 else642 mem = (ma + x + ra * x_count/40 * 0x400 -0x400) & 0x3fff;643 644 color = m_p_videoram[mem|0x4000] & 7;645 reverse = BIT(m_p_videoram[mem|0x4000], 3) ^ (x == cursor_x);646 graphic = BIT(m_p_videoram[mem|0x4000], 4);647 648 rawbits = m_p_videoram[mem];649 650 if (graphic)651 {652 if (lowres)653 {654 // low-res graphics, each tile has 8 bits arranged as follows:655 // 4 0656 // 5 1657 // 6 2658 // 7 3659 dots[0] = dots[1] = (rawbits >> ra/2 & 0x11) * 0xf;660 }661 else662 {663 dots[0] = dots[1] = rawbits;664 }665 }666 else667 {668 // character mode669 int tile = rawbits & 0x7f;670 int tile_bank = BIT(rawbits, 7);671 if (interlace)672 {673 dots[0] = m_p_chargen[(tile_bank<<11)|(tile<<4)|(ra<<1)];674 dots[1] = m_p_chargen[(tile_bank<<11)|(tile<<4)|(ra<<1)|tile_bank];675 }676 else677 {678 dots[0] = dots[1] = m_p_chargen[(tile<<4)|(ra<<1)|tile_bank];679 }680 }681 682 for(hf=0;hf<=interlace;hf++)683 {684 for(xi=0;xi<8;xi++)685 {686 if(reverse)687 pen = (dots[hf] >> (7-xi) & 1) ? bgcolor : color;688 else689 pen = (dots[hf] >> (7-xi) & 1) ? color : bgcolor;690 691 bitmap.pix32(y, x*8+xi) = palette[pen];692 // when the mc6845 device gains full interlace&video support, replace the line above with the line below693 // bitmap.pix32(y*(interlace+1)+hf, x*8+xi) = palette[pen];694 }695 }696 }697}698 699 700TIMER_DEVICE_CALLBACK_MEMBER(bml3_state::keyboard_callback)701{702 static const char *const portnames[3] = { ""key1"",""key2"",""key3"" };703 int i,port_i;704 bool trigger = false;705 706 if(!(m_keyb_scancode & 0x80))707 {708 m_keyb_scancode = (m_keyb_scancode + 1) & 0x7F;709 if (m_keyb_counter_operation_disabled)710 {711 m_keyb_scancode &= 0x7;712 }713 714 if (m_keyb_scancode == 0x7F)715 {716 if (m_keyb_empty_scan == 1)717 {718 // full scan completed with no keypress719 trigger = true;720 }721 if (m_keyb_empty_scan > 0)722 m_keyb_empty_scan--;723 }724 else if (m_keyb_scancode < 32*3)725 {726 port_i = m_keyb_scancode / 32;727 i = m_keyb_scancode % 32;728 if((ioport(portnames[port_i])->read()>>i) & 1)729 {730 m_keyb_empty_scan = 2;731 trigger = true;732 }733 }734 if (trigger)735 {736 m_keyb_scancode |= 0x80;737 if (!m_keyb_interrupt_disabled)738 m_maincpu->set_input_line(M6809_IRQ_LINE, HOLD_LINE);739 }740 /* Don't need this apparently...741 else742 {743 m_maincpu->set_input_line(M6809_IRQ_LINE, CLEAR_LINE);744 }745 */746 }747}748 749TIMER_DEVICE_CALLBACK_MEMBER( bml3_state::bml3_p )750{751 /* cassette - turn 1200/2400Hz to a bit */752 m_cass_data[1]++;753 u8 cass_ws = (m_cass->input() > +0.03) ? 1 : 0;754 755 if (cass_ws != m_cass_data[0])756 {757 m_cass_data[0] = cass_ws;758 m_acia->write_rxd((m_cass_data[1] < 12) ? 1 : 0);759 m_cass_data[1] = 0;760 }761}762 763#if 0764INTERRUPT_GEN_MEMBER(bml3_state::bml3_irq)765{766 m_maincpu->set_input_line(M6809_IRQ_LINE, HOLD_LINE);767}768#endif769 770 771INTERRUPT_GEN_MEMBER(bml3_state::bml3_timer_firq)772{773 if(!m_firq_mask)774 {775 m_maincpu->set_input_line(M6809_FIRQ_LINE, ASSERT_LINE);776 m_firq_status = 1;777 }778}779 780void bml3_state::machine_start()781{782 m_extram = std::make_unique<u8[]>(0x10000);783 m_psg_latch = 0;784 m_attr_latch = 0;785 m_vres_reg = 0;786 m_keyb_interrupt_disabled = 0;787 m_keyb_nmi_disabled = 0;788 m_keyb_counter_operation_disabled = 0;789 m_keyb_empty_scan = 0;790 m_keyb_scancode = 0;791 m_keyb_capslock_led_on = 0;792 m_keyb_hiragana_led_on = 0;793 m_keyb_katakana_led_on = 0;794 m_crtc_index = 0;795 m_firq_status = 0;796 m_cassbit = 0;797 m_cassold = 0;798}799 800void bml3_state::machine_reset()801{802 address_space &mem = m_maincpu->space(AS_PROGRAM);803 804 /* defaults */805 mem.install_rom(0xa000, 0xfeff,memregion(""maincpu"")->base() + 0xa000);806 mem.install_rom(0xfff0, 0xffff,memregion(""maincpu"")->base() + 0xfff0);807 mem.install_write_handler(0xa000, 0xbfff, write8_delegate(FUNC(bml3_state::bml3_a000_w), this),0);808 mem.install_write_handler(0xc000, 0xdfff, write8_delegate(FUNC(bml3_state::bml3_c000_w), this),0);809 mem.install_write_handler(0xe000, 0xefff, write8_delegate(FUNC(bml3_state::bml3_e000_w), this),0);810 mem.install_write_handler(0xf000, 0xfeff, write8_delegate(FUNC(bml3_state::bml3_f000_w), this),0);811 mem.install_write_handler(0xfff0, 0xffff, write8_delegate(FUNC(bml3_state::bml3_fff0_w), this),0);812 813 m_firq_mask = -1; // disable firq814}815 816WRITE8_MEMBER(bml3_state::bml3_piaA_w)817{818 address_space &mem = m_maincpu->space(AS_PROGRAM);819 /* ROM banking:820 -0-- --0- 0xa000 - 0xbfff ROM R RAM W821 -1-- --0- 0xa000 - 0xbfff RAM R/W822 -x-- --1- 0xa000 - 0xbfff no change823 0--- -0-- 0xc000 - 0xdfff ROM R RAM W824 1--- -0-- 0xc000 - 0xdfff RAM R/W825 x--- -1-- 0xc000 - 0xdfff no change826 0--- 0--- 0xe000 - 0xefff ROM R RAM W827 1--- 0--- 0xe000 - 0xefff RAM R/W828 x--- 1--- 0xe000 - 0xefff no change829 ---- ---x 0xf000 - 0xfeff (0) ROM R RAM W (1) RAM R/W830 ---- --x- 0xfff0 - 0xffff (0) ROM R RAM W (1) RAM R/W831 */832 logerror(""Check banking PIA A -> %02x\\n"",data);833 834 if(!(data & 0x2))835 {836 if(data & 0x40)837 {838 mem.install_readwrite_handler(0xa000, 0xbfff,839 read8_delegate(FUNC(bml3_state::bml3_a000_r), this),840 write8_delegate(FUNC(bml3_state::bml3_a000_w), this), 0);841 }842 else843 {844 mem.install_rom(0xa000, 0xbfff,845 memregion(""maincpu"")->base() + 0xa000);846 mem.install_write_handler(0xa000, 0xbfff,847 write8_delegate(FUNC(bml3_state::bml3_a000_w), this),848 0);849 }850 }851 852 if(!(data & 0x4))853 {854 if(data & 0x40)855 {856 mem.install_readwrite_handler(0xc000, 0xdfff,857 read8_delegate(FUNC(bml3_state::bml3_c000_r), this),858 write8_delegate(FUNC(bml3_state::bml3_c000_w), this), 0);859 }860 else861 {862 mem.install_rom(0xc000, 0xdfff,863 memregion(""maincpu"")->base() + 0xc000);864 mem.install_write_handler(0xc000, 0xdfff,865 write8_delegate(FUNC(bml3_state::bml3_c000_w), this),866 0);867 }868 }869 870 if(!(data & 0x8))871 {872 if(data & 0x80)873 {874 mem.install_readwrite_handler(0xe000, 0xefff,875 read8_delegate(FUNC(bml3_state::bml3_e000_r), this),876 write8_delegate(FUNC(bml3_state::bml3_e000_w), this), 0);877 }878 else879 {880 mem.install_rom(0xe000, 0xefff,881 memregion(""maincpu"")->base() + 0xe000);882 mem.install_write_handler(0xe000, 0xefff,883 write8_delegate(FUNC(bml3_state::bml3_e000_w), this),884 0);885 }886 }887 888 if(data & 1)889 {890 mem.install_readwrite_handler(0xf000, 0xfeff,891 read8_delegate(FUNC(bml3_state::bml3_f000_r), this),892 write8_delegate(FUNC(bml3_state::bml3_f000_w), this), 0);893 }894 else895 {896 mem.install_rom(0xf000, 0xfeff,897 memregion(""maincpu"")->base() + 0xf000);898 mem.install_write_handler(0xf000, 0xfeff,899 write8_delegate(FUNC(bml3_state::bml3_f000_w), this),900 0);901 }902 903 if(data & 2)904 {905 mem.install_readwrite_handler(0xfff0, 0xffff,906 read8_delegate(FUNC(bml3_state::bml3_fff0_r), this),907 write8_delegate(FUNC(bml3_state::bml3_fff0_w), this), 0);908 }909 else910 {911 mem.install_rom(0xfff0, 0xffff,912 memregion(""maincpu"")->base() + 0xfff0);913 mem.install_write_handler(0xfff0, 0xffff,914 write8_delegate(FUNC(bml3_state::bml3_fff0_w), this),915 0);916 }917}918 919WRITE_LINE_MEMBER( bml3_state::bml3_acia_tx_w )920{921 //logerror(""%02x TAPE\\n"",state);922 m_cassbit = state;923}924 925 926WRITE_LINE_MEMBER( bml3_state::bml3_acia_rts_w )927{928 logerror(""%02x TAPE RTS\\n"",state);929}930 931WRITE_LINE_MEMBER( bml3_state::bml3_acia_irq_w )932{933 logerror(""%02x TAPE IRQ\\n"",state);934}935 936TIMER_DEVICE_CALLBACK_MEMBER( bml3_state::bml3_c )937{938 m_cass_data[3]++;939 940 if (m_cassbit != m_cassold)941 {942 m_cass_data[3] = 0;943 m_cassold = m_cassbit;944 }945 946 if (m_cassbit)947 m_cass->output(BIT(m_cass_data[3], 0) ? -1.0 : +1.0); // 2400Hz948 else949 m_cass->output(BIT(m_cass_data[3], 1) ? -1.0 : +1.0); // 1200Hz950}951 952#if 0953static const ay8910_interface ay8910_config =954{955 AY8910_LEGACY_OUTPUT,956 AY8910_DEFAULT_LOADS,957 DEVCB_NOOP, // read A958 DEVCB_NOOP, // read B959 DEVCB_NOOP, // write A960 DEVCB_NOOP // write B961};962#endif963 964static SLOT_INTERFACE_START(bml3_cards)965 SLOT_INTERFACE(""bml3mp1802"", BML3BUS_MP1802) /* MP-1802 Floppy Controller Card */966 SLOT_INTERFACE(""bml3mp1805"", BML3BUS_MP1805) /* MP-1805 Floppy Controller Card */967 SLOT_INTERFACE(""bml3kanji"", BML3BUS_KANJI)968SLOT_INTERFACE_END969 970 971MACHINE_CONFIG_START(bml3_state::bml3_common)972 /* basic machine hardware */973 MCFG_CPU_ADD(""maincpu"",M6809, CPU_CLOCK)974 MCFG_CPU_VBLANK_INT_DRIVER(""screen"", bml3_state, bml3_timer_firq)975// MCFG_CPU_PERIODIC_INT_DRIVER(bml3_state, bml3_firq, 45)976 977// MCFG_MACHINE_RESET_OVERRIDE(bml3_state,bml3)978 979 /* video hardware */980 MCFG_SCREEN_ADD(""screen"", RASTER)981 MCFG_SCREEN_REFRESH_RATE(60)982 MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2400)) /* Service manual specifies ""Raster return period"" as 2.4 ms (p.64), although the total vertical non-displaying time seems to be 4 ms. */983 MCFG_SCREEN_SIZE(640, 400)984 MCFG_SCREEN_VISIBLE_AREA(0, 320-1, 0, 200-1)985 MCFG_SCREEN_UPDATE_DEVICE(""crtc"", mc6845_device, screen_update)986 MCFG_PALETTE_ADD_3BIT_BRG(""palette"")987 988 /* Devices */989 // CRTC clock should be synchronous with the CPU clock.990 MCFG_MC6845_ADD(""crtc"", H46505, ""screen"", CPU_CLOCK)991 MCFG_MC6845_SHOW_BORDER_AREA(false)992 MCFG_MC6845_CHAR_WIDTH(8)993 MCFG_MC6845_UPDATE_ROW_CB(bml3_state, crtc_update_row)994 995 // fire once per scan of an individual key996 // According to the service manual (p.65), the keyboard timer is driven by the horizontal video sync clock.997 MCFG_TIMER_DRIVER_ADD_PERIODIC(""keyboard_timer"", bml3_state, keyboard_callback, attotime::from_hz(H_CLOCK/2))998 MCFG_TIMER_DRIVER_ADD_PERIODIC(""bml3_c"", bml3_state, bml3_c, attotime::from_hz(4800))999 MCFG_TIMER_DRIVER_ADD_PERIODIC(""bml3_p"", bml3_state, bml3_p, attotime::from_hz(40000))1000 1001 MCFG_DEVICE_ADD(""pia"", PIA6821, 0)1002 MCFG_PIA_WRITEPA_HANDLER(WRITE8(bml3_state, bml3_piaA_w))1003 1004 MCFG_DEVICE_ADD(""acia"", ACIA6850, 0)1005 MCFG_ACIA6850_TXD_HANDLER(WRITELINE(bml3_state, bml3_acia_tx_w))1006 MCFG_ACIA6850_RTS_HANDLER(WRITELINE(bml3_state, bml3_acia_rts_w))1007 MCFG_ACIA6850_IRQ_HANDLER(WRITELINE(bml3_state, bml3_acia_irq_w))1008 1009 MCFG_DEVICE_ADD(""acia_clock"", CLOCK, 9600) // 600 baud x 16(divider) = 96001010 MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE(""acia"", acia6850_device, write_txc))1011 MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE(""acia"", acia6850_device, write_rxc))1012 1013 MCFG_CASSETTE_ADD( ""cassette"" )1014 1015 /* Audio */1016 MCFG_SPEAKER_STANDARD_MONO(""mono"")1017 MCFG_SOUND_WAVE_ADD(WAVE_TAG, ""cassette"")1018 MCFG_SOUND_ROUTE(ALL_OUTPUTS, ""mono"", 0.25)1019 MCFG_SOUND_ADD(""speaker"", SPEAKER_SOUND, 0)1020 MCFG_SOUND_ROUTE(ALL_OUTPUTS, ""mono"", 0.50)1021 1022 /* slot devices */1023 MCFG_DEVICE_ADD(""bml3bus"", BML3BUS, 0)1024 MCFG_BML3BUS_CPU(""maincpu"")1025 MCFG_BML3BUS_OUT_NMI_CB(WRITELINE(bml3_state, bml3bus_nmi_w))1026 MCFG_BML3BUS_OUT_IRQ_CB(WRITELINE(bml3_state, bml3bus_irq_w))1027 MCFG_BML3BUS_OUT_FIRQ_CB(WRITELINE(bml3_state, bml3bus_firq_w))1028 /* Default to MP-1805 disk (3"" or 5.25"" SS/SD), as our MB-6892 ROM dump includes1029 the MP-1805 ROM.1030 User may want to switch this to MP-1802 (5.25"" DS/DD).1031 Note it isn't feasible to use both, as they each place boot ROM at F800.1032 */1033 MCFG_BML3BUS_SLOT_ADD(""bml3bus"", ""sl1"", bml3_cards, ""bml3mp1805"")1034 MCFG_BML3BUS_SLOT_ADD(""bml3bus"", ""sl2"", bml3_cards, nullptr)1035 MCFG_BML3BUS_SLOT_ADD(""bml3bus"", ""sl3"", bml3_cards, nullptr)1036 MCFG_BML3BUS_SLOT_ADD(""bml3bus"", ""sl4"", bml3_cards, nullptr)1037 MCFG_BML3BUS_SLOT_ADD(""bml3bus"", ""sl5"", bml3_cards, nullptr)1038 MCFG_BML3BUS_SLOT_ADD(""bml3bus"", ""sl6"", bml3_cards, ""bml3kanji"")1039 1040MACHINE_CONFIG_END1041 1042MACHINE_CONFIG_START(bml3_state::bml3)1043 bml3_common(config);1044 MCFG_CPU_MODIFY( ""maincpu"" )1045 MCFG_CPU_PROGRAM_MAP(bml3_mem)1046 1047#if 01048 // TODO: slot device for sound card1049 // audio1050 MCFG_SOUND_ADD(""ym2203"", YM2203, 2000000) //unknown clock / divider1051 MCFG_YM2203_AY8910_INTF(&ay8910_config)1052 MCFG_SOUND_ROUTE(0, ""mono"", 0.25)1053 MCFG_SOUND_ROUTE(1, ""mono"", 0.25)1054 MCFG_SOUND_ROUTE(2, ""mono"", 0.50)1055 MCFG_SOUND_ROUTE(3, ""mono"", 0.50)1056#endif1057MACHINE_CONFIG_END1058 1059MACHINE_CONFIG_START(bml3_state::bml3mk2)1060 bml3_common(config);1061 MCFG_CPU_MODIFY( ""maincpu"" )1062 MCFG_CPU_PROGRAM_MAP(bml3mk2_mem)1063 1064 // TODO: anything to add here?1065MACHINE_CONFIG_END1066 1067MACHINE_CONFIG_START(bml3_state::bml3mk5)1068 bml3_common(config);1069 MCFG_CPU_MODIFY( ""maincpu"" )1070 MCFG_CPU_PROGRAM_MAP(bml3mk5_mem)1071 1072 // TODO: anything to add here?1073MACHINE_CONFIG_END1074 1075 1076 1077/* ROM definition */1078ROM_START( bml3 )1079 ROM_REGION( 0x10000, ""maincpu"", ROMREGION_ERASEFF )1080// ROM_LOAD( ""l3bas.rom"", 0xa000, 0x6000, BAD_DUMP CRC(d81baa07) SHA1(a8fd6b29d8c505b756dbf5354341c48f9ac1d24d)) //original, 24k isn't a proper rom size!1081 // TODO: replace with MB-6890 ROMs (these are from an MB-6892)1082 ROM_LOAD( ""598 p16611.ic3"", 0xa000, 0x2000, BAD_DUMP CRC(954b9bad) SHA1(047948fac6808717c60a1d0ac9205a5725362430))1083 ROM_LOAD( ""599 p16561.ic4"", 0xc000, 0x2000, BAD_DUMP CRC(b27a48f5) SHA1(94cb616df4caa6415c5076f9acdf675acb7453e2))1084 // TODO: Replace checksums with a ROM dump without a disk controller patch (checksums here are inclusive of the MP1805 patch)1085 ROM_LOAD( ""600 p16681.ic5"", 0xe000, 0x2000, BAD_DUMP CRC(fe3988a5) SHA1(edc732f1cd421e0cf45ffcfc71c5589958ceaae7))1086 1087 ROM_REGION( 0x1000, ""chargen"", 0 )1088 ROM_LOAD(""font.rom"", 0x00000, 0x1000, BAD_DUMP CRC(0b6f2f10) SHA1(dc411b447ca414e94843636d8b5f910c954581fb) ) // handcrafted1089 1090 ROM_REGION( 0x8000, ""vram"", ROMREGION_ERASEFF )1091ROM_END1092 1093ROM_START( bml3mk2 )1094 ROM_REGION( 0x10000, ""maincpu"", ROMREGION_ERASEFF )1095// ROM_LOAD( ""l3bas.rom"", 0xa000, 0x6000, BAD_DUMP CRC(d81baa07) SHA1(a8fd6b29d8c505b756dbf5354341c48f9ac1d24d)) //original, 24k isn't a proper rom size!1096 // TODO: replace with MB-6891 ROMs (these are from an MB-6892)1097 ROM_LOAD( ""598 p16611.ic3"", 0xa000, 0x2000, BAD_DUMP CRC(954b9bad) SHA1(047948fac6808717c60a1d0ac9205a5725362430))1098 ROM_LOAD( ""599 p16561.ic4"", 0xc000, 0x2000, BAD_DUMP CRC(b27a48f5) SHA1(94cb616df4caa6415c5076f9acdf675acb7453e2))1099 ROM_LOAD( ""600 p16681.ic5"", 0xe000, 0x2000, BAD_DUMP CRC(fe3988a5) SHA1(edc732f1cd421e0cf45ffcfc71c5589958ceaae7))1100 1101 ROM_REGION( 0x1000, ""chargen"", 0 )1102 ROM_LOAD(""font.rom"", 0x00000, 0x1000, BAD_DUMP CRC(0b6f2f10) SHA1(dc411b447ca414e94843636d8b5f910c954581fb) ) // handcrafted1103 1104 ROM_REGION( 0x8000, ""vram"", ROMREGION_ERASEFF )1105ROM_END1106 1107ROM_START( bml3mk5 )1108 ROM_REGION( 0x10000, ""maincpu"", ROMREGION_ERASEFF )1109// ROM_LOAD( ""l3bas.rom"", 0xa000, 0x6000, BAD_DUMP CRC(d81baa07) SHA1(a8fd6b29d8c505b756dbf5354341c48f9ac1d24d)) //original, 24k isn't a proper rom size!1110 /* Handcrafted ROMs, rom labels and contents might not match */1111 ROM_LOAD( ""598 p16611.ic3"", 0xa000, 0x2000, BAD_DUMP CRC(954b9bad) SHA1(047948fac6808717c60a1d0ac9205a5725362430))1112 ROM_LOAD( ""599 p16561.ic4"", 0xc000, 0x2000, BAD_DUMP CRC(b27a48f5) SHA1(94cb616df4caa6415c5076f9acdf675acb7453e2))1113 // TODO: Replace checksums with a ROM dump without a disk controller patch (checksums here are inclusive of the MP1805 patch)1114 ROM_LOAD( ""600 p16681.ic5"", 0xe000, 0x2000, BAD_DUMP CRC(fe3988a5) SHA1(edc732f1cd421e0cf45ffcfc71c5589958ceaae7))1115 1116 ROM_REGION( 0x1000, ""chargen"", 0 )1117 ROM_LOAD(""font.rom"", 0x00000, 0x1000, BAD_DUMP CRC(0b6f2f10) SHA1(dc411b447ca414e94843636d8b5f910c954581fb) ) // handcrafted1118 1119 ROM_REGION( 0x8000, ""vram"", ROMREGION_ERASEFF )1120ROM_END1121 1122/* Driver */1123 1124/* YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS */1125COMP( 1980, bml3, 0, 0, bml3, bml3, bml3_state, 0, ""Hitachi"", ""MB-6890 Basic Master Level 3"", MACHINE_NOT_WORKING)1126COMP( 1982, bml3mk2,bml3, 0, bml3mk2, bml3, bml3_state, 0, ""Hitachi"", ""MB-6891 Basic Master Level 3 Mark 2"", MACHINE_NOT_WORKING)1127COMP( 1983, bml3mk5,bml3, 0, bml3mk5, bml3, bml3_state, 0, ""Hitachi"", ""MB-6892 Basic Master Level 3 Mark 5"", MACHINE_NOT_WORKING)1128",16241,True,2732.492557592215,median1129"1130#include ""tsMuxer.h""1131 1132#include ""pesPacket.h""1133#include ""tsPacket.h""1134//#include ""tsEncoder.h""1135#include <fs/textfile.h>1136 1137#include ""ac3StreamReader.h""1138#include ""avCodecs.h""1139#include ""dtsStreamReader.h""1140#include ""dvbSubStreamReader.h""1141#include ""h264StreamReader.h""1142#include ""iso_writer.h""1143#include ""lpcmStreamReader.h""1144#include ""mpegAudioStreamReader.h""1145#include ""mpegStreamReader.h""1146#include ""muxerManager.h""1147#include ""vodCoreException.h""1148 1149#ifdef _WIN321150#define WIN32_LEAN_AND_MEAN1151#include <windows.h>1152#endif1153 1154using namespace std;1155 1156int V3_flags = 0;1157int HDR10_metadata[6] = {0, 0, 0, 0, 0, 0};1158bool isV3() { return V3_flags & HDMV_V3; }1159bool is4K() { return V3_flags & FOUR_K; }1160 1161const static uint64_t M_PCR_DELTA = 7000;1162const static uint64_t SIT_INTERVAL = 76900;1163// const static uint64_t M_CBR_PCR_DELTA = 2250;1164const static uint64_t M_CBR_PCR_DELTA = 7000;1165 1166static const uint8_t PES_INT_AC3_ID = 0x80;1167static const uint8_t PES_INT_DTS_ID = 0x8a;1168// static const uint8_t PES_INT_LPCM_ID = 0xa0;1169static const uint8_t PES_INT_SUB_ID = 0x20;1170 1171// static const int64_t FIXED_PTS_OFFSET = 27593l;1172 1173// static const int64_t FIXED_PCR_OFFSET = 45000;1174static const int64_t DEFAULT_VBV_BUFFER_LEN = 500; // default 500 ms vbv buffer1175// static const int64_t FIXED_PCR_OFFSET = 8589934592ll - 90000ll*10ll;1176 1177// static const uint64_t FIXED_PCR_OFFSET = 0;1178 1179static const int PAT_PID = 0;1180static const int SIT_PID = 0x1f;1181static const int NULL_PID = 8191;1182 1183uint8_t DefaultSitTableOne[] = {1184 0x47, 0x40, 0x1f, 0x10, 0x00, 0x7f, 0xf0, 0x19, 0xff, 0xff, 0xc1, 0x00, 0x00, 0xf0, 0x0a, 0x63, 0x08, 0xc1, 0x5a,1185 0xae, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x80, 0x00, 0x34, 0x1e, 0xe7, 0x4e, 0xff, 0xff, 0xff, 0xff, 0xff,1186 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,1187 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,1188 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,1189 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,1190 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,1191 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,1192 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,1193 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};1194 1195TSMuxer::TSMuxer(MuxerManager* owner) : AbstractMuxer(owner)1196{1197 m_m2tsMode = false;1198 m_vbvLen = DEFAULT_VBV_BUFFER_LEN * 90;1199 m_lastPESDTS = -1;1200 m_cbrBitrate = -1; // mux CBR if bitrate specifed