diff options
author | 2012-08-21 10:41:19 +0000 | |
---|---|---|
committer | 2012-08-21 10:41:19 +0000 | |
commit | 7285b359d259b2ae0fdf85096571c386ec8c991a (patch) | |
tree | a027aff57f1a255f9ec6cfd3b68cabe4b6683998 /src/mess/drivers/bml3.c | |
parent | 67c425e90757876a6716b7867df30c0149912e74 (diff) |
Merge of MESS sources (no whatsnew)
Diffstat (limited to 'src/mess/drivers/bml3.c')
-rw-r--r-- | src/mess/drivers/bml3.c | 952 |
1 files changed, 952 insertions, 0 deletions
diff --git a/src/mess/drivers/bml3.c b/src/mess/drivers/bml3.c new file mode 100644 index 00000000000..c4b9689ebad --- /dev/null +++ b/src/mess/drivers/bml3.c @@ -0,0 +1,952 @@ +/************************************************************************************** + + Basic Master Level 3 (MB-6890) (c) 1980 Hitachi + + preliminary driver by Angelo Salese + + TODO: + - keyboard shift key is ugly mapped. + - keyboard is actually tied to crtc hsync timer + - understand how to load a tape + - some NEWON commands now makes the keyboard to not work anymore (it does if you + soft reset) + - video bugs for the interlaced video modes. + - LINE command doesn't work? It says "type mismatch" + + NOTES: + - NEWON changes the video mode, they are: + 0: 320 x 200, bit 5 active + 1: 320 x 200, bit 5 unactive + 2: 320 x 375, bit 5 active + 3: 320 x 375, bit 5 unactive + 4: 640 x 200, bit 5 active + 5: 640 x 200, bit 5 unactive + 6: 640 x 375, bit 5 active + 7: 640 x 375, bit 5 unactive + 8-15: same as above plus sets bit 4 + 16-31: same as above plus shows the bar at the bottom + +**************************************************************************************/ + +#include "emu.h" +#include "cpu/m6809/m6809.h" +#include "video/mc6845.h" +#include "machine/mc6843.h" +#include "sound/beep.h" +#include "machine/6821pia.h" +#include "machine/6850acia.h" +#include "sound/2203intf.h" + +//#include "imagedev/cassette.h" +#include "imagedev/flopdrv.h" +#include "formats/basicdsk.h" + +class bml3_state : public driver_device +{ +public: + bml3_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_crtc(*this, "crtc"), + //m_cass(*this, CASSETTE_TAG), + m_beep(*this, BEEPER_TAG) + { } + + required_device<cpu_device> m_maincpu; + required_device<mc6845_device> m_crtc; + //required_device<cassette_image_device> m_cass; + required_device<device_t> m_beep; + DECLARE_WRITE8_MEMBER(bml3_6845_w); + DECLARE_READ8_MEMBER(bml3_keyboard_r); + DECLARE_WRITE8_MEMBER(bml3_hres_reg_w); + DECLARE_WRITE8_MEMBER(bml3_vres_reg_w); + DECLARE_READ8_MEMBER(bml3_vram_r); + DECLARE_WRITE8_MEMBER(bml3_vram_w); + DECLARE_READ8_MEMBER(bml3_fdd_r); + DECLARE_WRITE8_MEMBER(bml3_fdd_w); + DECLARE_READ8_MEMBER(bml3_kanji_r); + DECLARE_WRITE8_MEMBER(bml3_kanji_w); + DECLARE_READ8_MEMBER(bml3_psg_latch_r); + DECLARE_WRITE8_MEMBER(bml3_psg_latch_w); + DECLARE_READ8_MEMBER(bml3_vram_attr_r); + DECLARE_WRITE8_MEMBER(bml3_vram_attr_w); + DECLARE_READ8_MEMBER(bml3_beep_r); + DECLARE_WRITE8_MEMBER(bml3_beep_w); + DECLARE_WRITE8_MEMBER(bml3_piaA_w); + DECLARE_READ8_MEMBER(bml3_keyb_nmi_r); + DECLARE_WRITE8_MEMBER(bml3_firq_mask_w); + DECLARE_READ8_MEMBER(bml3_firq_status_r); + + + DECLARE_READ_LINE_MEMBER( bml3_acia_rx_r ); + DECLARE_WRITE_LINE_MEMBER( bml3_acia_tx_w ); + DECLARE_READ_LINE_MEMBER( bml3_acia_dts_r ); + DECLARE_WRITE_LINE_MEMBER( bml3_acia_rts_w ); + DECLARE_READ_LINE_MEMBER(bml3_acia_dcd_r); + DECLARE_WRITE_LINE_MEMBER(bml3_acia_irq_w); + + DECLARE_READ8_MEMBER(bml3_a000_r); DECLARE_WRITE8_MEMBER(bml3_a000_w); + DECLARE_READ8_MEMBER(bml3_c000_r); DECLARE_WRITE8_MEMBER(bml3_c000_w); + DECLARE_READ8_MEMBER(bml3_e000_r); DECLARE_WRITE8_MEMBER(bml3_e000_w); + DECLARE_READ8_MEMBER(bml3_f000_r); DECLARE_WRITE8_MEMBER(bml3_f000_w); + DECLARE_READ8_MEMBER(bml3_fff0_r); DECLARE_WRITE8_MEMBER(bml3_fff0_w); + + UINT8 m_attr_latch; + UINT8 m_io_latch; + UINT8 m_hres_reg; + UINT8 m_vres_reg; + UINT8 m_keyb_press; + UINT8 m_keyb_press_flag; + UINT8 *m_p_chargen; + UINT8 m_psg_latch; + void m6845_change_clock(UINT8 setting); + UINT8 m_crtc_vreg[0x100],m_crtc_index; + UINT16 m_kanji_addr; + UINT8 *m_extram; + UINT8 m_firq_mask,m_firq_status; + +protected: + virtual void machine_reset(); + +}; + +#define mc6845_h_char_total (state->m_crtc_vreg[0]) +#define mc6845_h_display (state->m_crtc_vreg[1]) +#define mc6845_h_sync_pos (state->m_crtc_vreg[2]) +#define mc6845_sync_width (state->m_crtc_vreg[3]) +#define mc6845_v_char_total (state->m_crtc_vreg[4]) +#define mc6845_v_total_adj (state->m_crtc_vreg[5]) +#define mc6845_v_display (state->m_crtc_vreg[6]) +#define mc6845_v_sync_pos (state->m_crtc_vreg[7]) +#define mc6845_mode_ctrl (state->m_crtc_vreg[8]) +#define mc6845_tile_height (state->m_crtc_vreg[9]+1) +#define mc6845_cursor_y_start (state->m_crtc_vreg[0x0a]) +#define mc6845_cursor_y_end (state->m_crtc_vreg[0x0b]) +#define mc6845_start_addr (((state->m_crtc_vreg[0x0c]<<8) & 0x3f00) | (state->m_crtc_vreg[0x0d] & 0xff)) +#define mc6845_cursor_addr (((state->m_crtc_vreg[0x0e]<<8) & 0x3f00) | (state->m_crtc_vreg[0x0f] & 0xff)) +#define mc6845_light_pen_addr (((state->m_crtc_vreg[0x10]<<8) & 0x3f00) | (state->m_crtc_vreg[0x11] & 0xff)) +#define mc6845_update_addr (((state->m_crtc_vreg[0x12]<<8) & 0x3f00) | (state->m_crtc_vreg[0x13] & 0xff)) + + +static VIDEO_START( bml3 ) +{ + bml3_state *state = machine.driver_data<bml3_state>(); + state->m_p_chargen = state->memregion("chargen")->base(); +} + +static SCREEN_UPDATE_IND16( bml3 ) +{ + bml3_state *state = screen.machine().driver_data<bml3_state>(); + int x,y,count; + int xi,yi; + int width; //,height; + UINT8 *vram = state->memregion("vram")->base(); + + count = 0x0000; + + width = (state->m_hres_reg & 0x80) ? 80 : 40; +// height = (state->m_vres_reg & 0x08) ? 1 : 0; + +// popmessage("%02x %02x",state->m_hres_reg,state->m_vres_reg); + + for(y=0;y<25;y++) + { + for(x=0;x<width;x++) + { + int tile = vram[count+0x0000] & 0x7f; + int tile_bank = (vram[count+0x0000] & 0x80) >> 7; + int color = vram[count+0x4000] & 7; + int reverse = vram[count+0x4000] & 8; + //attr & 0x10 is used ... bitmap mode? (apparently bits 4 and 7 are used for that) + + for(yi=0;yi<mc6845_tile_height;yi++) + { + for(xi=0;xi<8;xi++) + { + int pen; + + if(reverse) + pen = (state->m_p_chargen[tile*16+yi*2+tile_bank] >> (7-xi) & 1) ? 0 : color; + else + pen = (state->m_p_chargen[tile*16+yi*2+tile_bank] >> (7-xi) & 1) ? color : 0; + + bitmap.pix16(y*mc6845_tile_height+yi, x*8+xi) = pen; + } + } + + if(mc6845_cursor_addr-0x400 == count) + { + int xc,yc,cursor_on; + + cursor_on = 0; + switch(mc6845_cursor_y_start & 0x60) + { + case 0x00: cursor_on = 1; break; //always on + case 0x20: cursor_on = 0; break; //always off + case 0x40: if(screen.machine().primary_screen->frame_number() & 0x10) { cursor_on = 1; } break; //fast blink + case 0x60: if(screen.machine().primary_screen->frame_number() & 0x20) { cursor_on = 1; } break; //slow blink + } + + if(cursor_on) + { + for(yc=0;yc<(8-(mc6845_cursor_y_start & 7));yc++) + { + for(xc=0;xc<8;xc++) + { + bitmap.pix16(y*mc6845_tile_height+yc+7, x*8+xc) = 7; + } + } + } + } + + count++; + } + } + + return 0; +} + +WRITE8_MEMBER( bml3_state::bml3_6845_w ) +{ + if(offset == 0) + { + m_crtc_index = data; + m_crtc->address_w(space, 0, data); + } + else + { + m_crtc_vreg[m_crtc_index] = data; + m_crtc->register_w(space, 0, data); + } +} + +READ8_MEMBER( bml3_state::bml3_keyboard_r ) +{ + if(m_keyb_press_flag) + { + int res; + res = m_keyb_press; + m_keyb_press = m_keyb_press_flag = 0; + return res | 0x80; + } + + return 0x00; +} + +void bml3_state::m6845_change_clock(UINT8 setting) +{ + int m6845_clock = XTAL_1MHz; + + switch(setting & 0x88) + { + case 0x00: m6845_clock = XTAL_1MHz; break; //320 x 200 + case 0x08: m6845_clock = XTAL_1MHz*2; break; //320 x 375 + case 0x80: m6845_clock = XTAL_1MHz*2; break; //640 x 200 + case 0x88: m6845_clock = XTAL_1MHz*4; break; //640 x 375 + } + + m_crtc->set_clock(m6845_clock); +} + +WRITE8_MEMBER( bml3_state::bml3_hres_reg_w ) +{ + /* + x--- ---- width (1) 80 / (0) 40 + -x-- ---- used in some modes, unknown purpose + --x- ---- used in some modes, unknown purpose (also wants $ffc4 to be 0xff), color / monochrome switch? + */ + + m_hres_reg = data; + + m6845_change_clock((m_hres_reg & 0x80) | (m_vres_reg & 0x08)); +} + +WRITE8_MEMBER( bml3_state::bml3_vres_reg_w ) +{ + /* + ---- x--- char height + */ + m_vres_reg = data; + + m6845_change_clock((m_hres_reg & 0x80) | (m_vres_reg & 0x08)); +} + + +READ8_MEMBER( bml3_state::bml3_vram_r ) +{ + UINT8 *vram = memregion("vram")->base(); + + /* TODO: this presumably also triggers an attr latch read, unsure yet */ + m_attr_latch = vram[offset+0x4000]; + + return vram[offset]; +} + +WRITE8_MEMBER( bml3_state::bml3_vram_w ) +{ + UINT8 *vram = memregion("vram")->base(); + + vram[offset] = data; + vram[offset+0x4000] = m_attr_latch; +} + +READ8_MEMBER( bml3_state::bml3_fdd_r ) +{ + //printf("FDD 0xff20 R\n"); + return -1; +} + +WRITE8_MEMBER( bml3_state::bml3_fdd_w ) +{ + //printf("FDD 0xff20 W %02x\n",data); +} + +READ8_MEMBER( bml3_state::bml3_kanji_r ) +{ +// return m_kanji_rom[m_kanji_addr << 1 + offset]; + return machine().rand(); +} + +WRITE8_MEMBER( bml3_state::bml3_kanji_w ) +{ + m_kanji_addr &= (0xff << (offset*8)); + m_kanji_addr |= (data << ((offset^1)*8)); +} + +READ8_MEMBER( bml3_state::bml3_psg_latch_r) +{ + return 0x7f; +} + +WRITE8_MEMBER( bml3_state::bml3_psg_latch_w) +{ + m_psg_latch = data; +} + +static READ8_DEVICE_HANDLER( bml3_ym2203_r ) +{ + bml3_state *state = device->machine().driver_data<bml3_state>(); + UINT8 dev_offs = ((state->m_psg_latch & 3) != 3); + + return ym2203_r(device,dev_offs); +} + +static WRITE8_DEVICE_HANDLER( bml3_ym2203_w ) +{ + bml3_state *state = device->machine().driver_data<bml3_state>(); + UINT8 dev_offs = ((state->m_psg_latch & 3) != 3); + + ym2203_w(device,dev_offs,data); +} + +READ8_MEMBER( bml3_state::bml3_vram_attr_r) +{ + return m_attr_latch; +} + +WRITE8_MEMBER( bml3_state::bml3_vram_attr_w) +{ + m_attr_latch = data; +} + +READ8_MEMBER( bml3_state::bml3_beep_r) +{ + return -1; // BEEP status read? +} + +WRITE8_MEMBER( bml3_state::bml3_beep_w) +{ + beep_set_state(m_beep,!BIT(data, 7)); +} + +READ8_MEMBER( bml3_state::bml3_a000_r) { return m_extram[offset + 0xa000]; } +WRITE8_MEMBER( bml3_state::bml3_a000_w) { m_extram[offset + 0xa000] = data; } +READ8_MEMBER( bml3_state::bml3_c000_r) { return m_extram[offset + 0xc000]; } +WRITE8_MEMBER( bml3_state::bml3_c000_w) { m_extram[offset + 0xc000] = data; } +READ8_MEMBER( bml3_state::bml3_e000_r) { return m_extram[offset + 0xe000]; } +WRITE8_MEMBER( bml3_state::bml3_e000_w) { m_extram[offset + 0xe000] = data; } +READ8_MEMBER( bml3_state::bml3_f000_r) { return m_extram[offset + 0xf000]; } +WRITE8_MEMBER( bml3_state::bml3_f000_w) { m_extram[offset + 0xf000] = data; } +READ8_MEMBER( bml3_state::bml3_fff0_r) { return m_extram[offset + 0xfff0]; } +WRITE8_MEMBER( bml3_state::bml3_fff0_w) { m_extram[offset + 0xfff0] = data; } + +READ8_MEMBER( bml3_state::bml3_keyb_nmi_r) +{ + return 0; // bit 7 used to signal a BREAK key pressure +} + +WRITE8_MEMBER( bml3_state::bml3_firq_mask_w) +{ + m_firq_mask = data & 0x80; + if(m_firq_mask) + { + m_firq_status = 0; // clear pending firq + device_set_input_line(m_maincpu, M6809_FIRQ_LINE, CLEAR_LINE); + } +} + +READ8_MEMBER( bml3_state::bml3_firq_status_r ) +{ + UINT8 res = m_firq_status << 7; + m_firq_status = 0; + device_set_input_line(m_maincpu, M6809_FIRQ_LINE, CLEAR_LINE); + return res; +} + +static ADDRESS_MAP_START(bml3_mem, AS_PROGRAM, 8, bml3_state) + ADDRESS_MAP_UNMAP_HIGH + AM_RANGE(0x0000, 0x03ff) AM_RAM + AM_RANGE(0x0400, 0x43ff) AM_READWRITE(bml3_vram_r,bml3_vram_w) + AM_RANGE(0x4400, 0x9fff) AM_RAM + AM_RANGE(0xff00, 0xff00) AM_DEVREADWRITE_LEGACY("ym2203",bml3_ym2203_r,bml3_ym2203_w) + AM_RANGE(0xff02, 0xff02) AM_READWRITE(bml3_psg_latch_r,bml3_psg_latch_w) // PSG address/data select + AM_RANGE(0xff18, 0xff1f) AM_DEVREADWRITE_LEGACY("mc6843",mc6843_r,mc6843_w) + AM_RANGE(0xff20, 0xff20) AM_READWRITE(bml3_fdd_r,bml3_fdd_w) // FDD drive select + AM_RANGE(0xff75, 0xff76) AM_READWRITE(bml3_kanji_r,bml3_kanji_w)// kanji i/f + AM_RANGE(0xffc0, 0xffc3) AM_DEVREADWRITE("pia6821", pia6821_device, read, write) + AM_RANGE(0xffc4, 0xffc4) AM_DEVREADWRITE("acia6850", acia6850_device, status_read, control_write) + AM_RANGE(0xffc5, 0xffc5) AM_DEVREADWRITE("acia6850", acia6850_device, data_read, data_write) + AM_RANGE(0xffc6, 0xffc7) AM_WRITE(bml3_6845_w) + AM_RANGE(0xffc8, 0xffc8) AM_READ(bml3_keyb_nmi_r) // keyboard nmi + AM_RANGE(0xffc9, 0xffc9) AM_READ_PORT("DSW") + AM_RANGE(0xffca, 0xffca) AM_READ(bml3_firq_status_r) // timer irq +// AM_RANGE(0xffcb, 0xffcb) light pen flag + AM_RANGE(0xffd0, 0xffd0) AM_WRITE(bml3_hres_reg_w) // mode select +// AM_RANGE(0xffd1, 0xffd1) trace counter +// AM_RANGE(0xffd2, 0xffd2) remote switch + AM_RANGE(0xffd3, 0xffd3) AM_READWRITE(bml3_beep_r,bml3_beep_w) // music select + AM_RANGE(0xffd4, 0xffd4) AM_WRITE(bml3_firq_mask_w) +// AM_RANGE(0xffd5, 0xffd5) light pen + AM_RANGE(0xffd6, 0xffd6) AM_WRITE(bml3_vres_reg_w) // interlace select +// AM_RANGE(0xffd7, 0xffd7) baud select + AM_RANGE(0xffd8, 0xffd8) AM_READWRITE(bml3_vram_attr_r,bml3_vram_attr_w) // attribute register + AM_RANGE(0xffe0, 0xffe0) AM_READ(bml3_keyboard_r) // keyboard mode register +// AM_RANGE(0xffe8, 0xffe8) bank register +// AM_RANGE(0xffe9, 0xffe9) IG mode register +// AM_RANGE(0xffea, 0xffea) IG enable register + AM_RANGE(0xa000, 0xfeff) AM_ROM AM_REGION("maincpu", 0xa000) + AM_RANGE(0xfff0, 0xffff) AM_ROM AM_REGION("maincpu", 0xfff0) + AM_RANGE(0xa000, 0xbfff) AM_WRITE(bml3_a000_w) + AM_RANGE(0xc000, 0xdfff) AM_WRITE(bml3_c000_w) + AM_RANGE(0xe000, 0xefff) AM_WRITE(bml3_e000_w) + AM_RANGE(0xf000, 0xfeff) AM_WRITE(bml3_f000_w) + AM_RANGE(0xfff0, 0xffff) AM_WRITE(bml3_fff0_w) +ADDRESS_MAP_END + + +/* Input ports */ + +static INPUT_PORTS_START( bml3 ) + PORT_START("DSW") + PORT_DIPNAME( 0x07, 0x01, "NewOn" ) // TODO + PORT_DIPSETTING( 0x00, "0" ) + PORT_DIPSETTING( 0x01, "1" ) + PORT_DIPSETTING( 0x02, "2" ) + PORT_DIPSETTING( 0x03, "3" ) + PORT_DIPSETTING( 0x04, "4" ) + PORT_DIPSETTING( 0x05, "5" ) + PORT_DIPSETTING( 0x06, "6" ) + PORT_DIPSETTING( 0x07, "7" ) + PORT_DIPNAME( 0x08, 0x00, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x08, DEF_STR( On ) ) + PORT_DIPNAME( 0x10, 0x10, "Show F help" ) + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x10, DEF_STR( On ) ) + PORT_DIPNAME( 0x20, 0x00, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x20, DEF_STR( On ) ) + PORT_DIPNAME( 0x40, 0x00, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x40, DEF_STR( On ) ) + PORT_DIPNAME( 0x80, 0x00, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x80, DEF_STR( On ) ) + + PORT_START("key1") //0x00-0x1f + PORT_BIT(0x00000001,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') + PORT_BIT(0x00000002,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Up") PORT_CODE(KEYCODE_UP) + PORT_BIT(0x00000004,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("?") + PORT_BIT(0x00000008,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Left") PORT_CODE(KEYCODE_LEFT) + PORT_BIT(0x00000010,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Down") PORT_CODE(KEYCODE_DOWN) + PORT_BIT(0x00000020,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Right") PORT_CODE(KEYCODE_RIGHT) + PORT_BIT(0x00000040,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("X1") + PORT_BIT(0x00000080,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Shift")PORT_CODE(KEYCODE_LSHIFT) + PORT_BIT(0x00000100,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("X2") + PORT_BIT(0x00000200,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Caps Lock") PORT_CODE(KEYCODE_CAPSLOCK) PORT_TOGGLE + PORT_BIT(0x00000400,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Kana Lock") PORT_CODE(KEYCODE_NUMLOCK) PORT_TOGGLE + PORT_BIT(0x00000800,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Kana Shift") PORT_CODE(KEYCODE_LCONTROL) + PORT_BIT(0x00001000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("X6") + PORT_BIT(0x00002000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("8 PAD") PORT_CODE(KEYCODE_8_PAD) PORT_CHAR('8') + PORT_BIT(0x00004000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("9 PAD") PORT_CODE(KEYCODE_9_PAD) PORT_CHAR('9') + PORT_BIT(0x00008000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("*") PORT_CODE(KEYCODE_ASTERISK) PORT_CHAR('*') + PORT_BIT(0x00010000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("7") PORT_CODE(KEYCODE_7) PORT_CHAR('7') + PORT_BIT(0x00020000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("4") PORT_CODE(KEYCODE_4) PORT_CHAR('4') + PORT_BIT(0x00040000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("6") PORT_CODE(KEYCODE_6) PORT_CHAR('6') + PORT_BIT(0x00080000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("8") PORT_CODE(KEYCODE_8) PORT_CHAR('8') + PORT_BIT(0x00100000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0) PORT_CHAR('0') + PORT_BIT(0x00200000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("^") + PORT_BIT(0x00400000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("-") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') + PORT_BIT(0x00800000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("3") PORT_CODE(KEYCODE_3) PORT_CHAR('3') + PORT_BIT(0x01000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Backspace") PORT_CODE(KEYCODE_BACKSPACE) + PORT_BIT(0x02000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("5") PORT_CODE(KEYCODE_5) PORT_CHAR('5') + PORT_BIT(0x04000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("1") PORT_CODE(KEYCODE_1) PORT_CHAR('1') + PORT_BIT(0x08000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("2") PORT_CODE(KEYCODE_2) PORT_CHAR('2') + PORT_BIT(0x10000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("9") PORT_CODE(KEYCODE_9) PORT_CHAR('9') + PORT_BIT(0x20000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("7 PAD") PORT_CODE(KEYCODE_7_PAD) PORT_CHAR('7') + PORT_BIT(0x40000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("X7") //backspace + PORT_BIT(0x80000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("\xC2\xA5") //PORT_NAME("?") + + PORT_START("key2") //0x20-0x3f + PORT_BIT(0x00000001,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U) + PORT_BIT(0x00000002,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R) + PORT_BIT(0x00000004,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) + PORT_BIT(0x00000008,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I) + PORT_BIT(0x00000010,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P) + PORT_BIT(0x00000020,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("[") + PORT_BIT(0x00000040,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("@") + PORT_BIT(0x00000080,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("0 PAD") PORT_CODE(KEYCODE_0_PAD) PORT_CHAR('0') + PORT_BIT(0x00000100,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) + PORT_BIT(0x00000200,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T) + PORT_BIT(0x00000400,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W) + PORT_BIT(0x00000800,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) + PORT_BIT(0x00001000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O) + PORT_BIT(0x00002000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(".") + PORT_BIT(0x00004000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("HOME") PORT_CODE(KEYCODE_HOME) //or cls? + PORT_BIT(0x00008000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("ENTER") PORT_CODE(KEYCODE_ENTER) + PORT_BIT(0x00010000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("J") PORT_CODE(KEYCODE_J) + PORT_BIT(0x00020000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) + PORT_BIT(0x00040000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H) + PORT_BIT(0x00080000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K) + PORT_BIT(0x00100000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(";") + PORT_BIT(0x00200000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("]") + PORT_BIT(0x00400000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(":") + PORT_BIT(0x00800000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("4 PAD") PORT_CODE(KEYCODE_4_PAD) PORT_CHAR('4') + PORT_BIT(0x01000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) + PORT_BIT(0x02000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G) + PORT_BIT(0x04000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S) + PORT_BIT(0x08000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) + PORT_BIT(0x10000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L) + PORT_BIT(0x20000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("5 PAD") PORT_CODE(KEYCODE_5_PAD) PORT_CHAR('5') + PORT_BIT(0x40000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("6 PAD") PORT_CODE(KEYCODE_6_PAD) PORT_CHAR('6') + PORT_BIT(0x80000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("-") PORT_CODE(KEYCODE_MINUS) + + PORT_START("key3") //0x40-0x5f + PORT_BIT(0x00000001,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M) + PORT_BIT(0x00000002,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_V) + PORT_BIT(0x00000004,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N) + PORT_BIT(0x00000008,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(",") PORT_CODE(KEYCODE_COMMA) + PORT_BIT(0x00000010,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("/") PORT_CODE(KEYCODE_BACKSLASH) + PORT_BIT(0x00000020,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("/ PAD") PORT_CODE(KEYCODE_SLASH_PAD) + PORT_BIT(0x00000040,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("_") + PORT_BIT(0x00000080,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("1") PORT_CODE(KEYCODE_1_PAD) PORT_CHAR('1') + PORT_BIT(0x00000100,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) + PORT_BIT(0x00000200,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) + PORT_BIT(0x00000400,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X) + PORT_BIT(0x00000800,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) + PORT_BIT(0x00001000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(".") PORT_CODE(KEYCODE_STOP) + PORT_BIT(0x00002000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("X8") + PORT_BIT(0x00004000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("3 PAD") PORT_CODE(KEYCODE_3_PAD) PORT_CHAR('3') + PORT_BIT(0x00008000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("+") PORT_CODE(KEYCODE_PLUS_PAD) + PORT_BIT(0x00010000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("PF1") PORT_CODE(KEYCODE_F1) + PORT_BIT(0x00020000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("PF2") PORT_CODE(KEYCODE_F2) + PORT_BIT(0x00040000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("PF3") PORT_CODE(KEYCODE_F3) + PORT_BIT(0x00080000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("PF4") PORT_CODE(KEYCODE_F4) + PORT_BIT(0x00100000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("PF5") PORT_CODE(KEYCODE_F5) + PORT_BIT(0xffe00000,IP_ACTIVE_HIGH,IPT_UNKNOWN) +INPUT_PORTS_END + +static const mc6845_interface mc6845_intf = +{ + "screen", /* screen we are acting on */ + 8, /* number of pixels per video memory address */ + NULL, /* before pixel update callback */ + NULL, /* row update callback */ + NULL, /* after pixel update callback */ + DEVCB_NULL, /* callback for display state changes */ + DEVCB_NULL, /* callback for cursor state changes */ + DEVCB_NULL, /* HSYNC callback */ + DEVCB_NULL, /* VSYNC callback */ + NULL /* update address callback */ +}; + +static TIMER_DEVICE_CALLBACK( keyboard_callback ) +{ + bml3_state *state = timer.machine().driver_data<bml3_state>(); + static const char *const portnames[3] = { "key1","key2","key3" }; + int i,port_i,scancode; + scancode = 0; + + for(port_i=0;port_i<3;port_i++) + { + for(i=0;i<32;i++) + { + if((timer.machine().root_device().ioport(portnames[port_i])->read()>>i) & 1) + { + { + state->m_keyb_press = scancode; + state->m_keyb_press_flag = 1; + cputag_set_input_line(timer.machine(), "maincpu", M6809_IRQ_LINE, HOLD_LINE); + return; + } + } + + scancode++; + } + } +} + +#if 0 +static INTERRUPT_GEN( bml3_irq ) +{ + cputag_set_input_line(device->machine(), "maincpu", M6809_IRQ_LINE, HOLD_LINE); +} +#endif + + +static INTERRUPT_GEN( bml3_timer_firq ) +{ + bml3_state *state = device->machine().driver_data<bml3_state>(); + + if(!state->m_firq_mask) + { + device_set_input_line(state->m_maincpu, M6809_FIRQ_LINE, ASSERT_LINE); + state->m_firq_status = 1; + } +} + +static PALETTE_INIT( bml3 ) +{ + int i; + + for(i=0;i<8;i++) + palette_set_color_rgb(machine, i, pal1bit(i >> 1),pal1bit(i >> 2),pal1bit(i >> 0)); +} + +static MACHINE_START(bml3) +{ + bml3_state *state = machine.driver_data<bml3_state>(); + + beep_set_frequency(machine.device(BEEPER_TAG),1200); //guesswork + beep_set_state(machine.device(BEEPER_TAG),0); + state->m_extram = auto_alloc_array(machine,UINT8,0x10000); +} + +void bml3_state::machine_reset() +{ + address_space *mem = m_maincpu->memory().space(AS_PROGRAM); + + /* defaults */ + mem->install_rom(0xa000, 0xfeff,mem->machine().root_device().memregion("maincpu")->base() + 0xa000); + mem->install_rom(0xfff0, 0xffff,mem->machine().root_device().memregion("maincpu")->base() + 0xfff0); + mem->install_write_handler(0xa000, 0xbfff, 0, 0,write8_delegate(FUNC(bml3_state::bml3_a000_w), this),0); + mem->install_write_handler(0xc000, 0xdfff, 0, 0,write8_delegate(FUNC(bml3_state::bml3_c000_w), this),0); + mem->install_write_handler(0xe000, 0xefff, 0, 0,write8_delegate(FUNC(bml3_state::bml3_e000_w), this),0); + mem->install_write_handler(0xf000, 0xfeff, 0, 0,write8_delegate(FUNC(bml3_state::bml3_f000_w), this),0); + mem->install_write_handler(0xfff0, 0xffff, 0, 0,write8_delegate(FUNC(bml3_state::bml3_fff0_w), this),0); + + m_firq_mask = -1; // disable firq +} + +/* F4 Character Displayer */ +static const gfx_layout bml3_charlayout8x8even = +{ + 8, 8, /* 8 x 8 characters */ + RGN_FRAC(1,1), /* 256 characters */ + 1, /* 1 bits per pixel */ + { 0 }, /* no bitplanes */ + /* x offsets */ + { 0, 1, 2, 3, 4, 5, 6, 7 }, + /* y offsets */ + { 0*8, 2*8,4*8, 6*8, 8*8, 10*8, 12*8, 14*8 }, + 8*16 /* every char takes 8 bytes */ +}; + +static const gfx_layout bml3_charlayout8x8odd = +{ + 8, 8, /* 8 x 8 characters */ + RGN_FRAC(1,1), /* 256 characters */ + 1, /* 1 bits per pixel */ + { 0 }, /* no bitplanes */ + /* x offsets */ + { 0, 1, 2, 3, 4, 5, 6, 7 }, + /* y offsets */ + { 1*8, 3*8, 5*8, 7*8, 9*8, 11*8, 13*8, 15*8 }, + 8*16 /* every char takes 8 bytes */ +}; + +static const gfx_layout bml3_charlayout8x16 = +{ + 8, 16, /* 8 x 8 characters */ + RGN_FRAC(1,1), /* 256 characters */ + 1, /* 1 bits per pixel */ + { 0 }, /* no bitplanes */ + /* x offsets */ + { 0, 1, 2, 3, 4, 5, 6, 7 }, + /* y offsets */ + { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8, 8*8, 9*8, 10*8, 11*8, 12*8, 13*8, 14*8, 15*8 }, + 8*16 /* every char takes 8 bytes */ +}; + +static GFXDECODE_START( bml3 ) + GFXDECODE_ENTRY( "chargen", 0, bml3_charlayout8x8even, 0, 4 ) + GFXDECODE_ENTRY( "chargen", 0, bml3_charlayout8x8odd, 0, 4 ) + GFXDECODE_ENTRY( "chargen", 0, bml3_charlayout8x16, 0, 4 ) +GFXDECODE_END + +const mc6843_interface bml3_6843_if = { NULL }; + +WRITE8_MEMBER(bml3_state::bml3_piaA_w) +{ + address_space *mem = m_maincpu->memory().space(AS_PROGRAM); + /* ROM banking: + -0-- --0- 0xa000 - 0xbfff ROM R RAM W + -1-- --0- 0xa000 - 0xbfff RAM R/W + -x-- --1- 0xa000 - 0xbfff no change + 0--- -0-- 0xc000 - 0xdfff ROM R RAM W + 1--- -0-- 0xc000 - 0xdfff RAM R/W + x--- -1-- 0xc000 - 0xdfff no change + 0--- 0--- 0xe000 - 0xefff ROM R RAM W + 1--- 0--- 0xe000 - 0xefff RAM R/W + x--- 1--- 0xe000 - 0xefff no change + ---- ---x 0xf000 - 0xfeff (0) ROM R RAM W (1) RAM R/W + ---- --x- 0xfff0 - 0xffff (0) ROM R RAM W (1) RAM R/W + */ + printf("Check banking PIA A -> %02x\n",data); + + if(!(data & 0x2)) + { + if(data & 0x40) + { + mem->install_readwrite_handler(0xa000, 0xbfff, 0, 0, + read8_delegate(FUNC(bml3_state::bml3_a000_r), this), + write8_delegate(FUNC(bml3_state::bml3_a000_w), this), 0); + } + else + { + mem->install_rom(0xa000, 0xbfff, + mem->machine().root_device().memregion("maincpu")->base() + 0xa000); + mem->install_write_handler(0xa000, 0xbfff, 0, 0, + write8_delegate(FUNC(bml3_state::bml3_a000_w), this), + 0); + } + } + + if(!(data & 0x4)) + { + if(data & 0x40) + { + mem->install_readwrite_handler(0xc000, 0xdfff, 0, 0, + read8_delegate(FUNC(bml3_state::bml3_c000_r), this), + write8_delegate(FUNC(bml3_state::bml3_c000_w), this), 0); + } + else + { + mem->install_rom(0xc000, 0xdfff, + mem->machine().root_device().memregion("maincpu")->base() + 0xc000); + mem->install_write_handler(0xc000, 0xdfff, 0, 0, + write8_delegate(FUNC(bml3_state::bml3_c000_w), this), + 0); + } + } + + if(!(data & 0x8)) + { + if(data & 0x80) + { + mem->install_readwrite_handler(0xe000, 0xefff, 0, 0, + read8_delegate(FUNC(bml3_state::bml3_e000_r), this), + write8_delegate(FUNC(bml3_state::bml3_e000_w), this), 0); + } + else + { + mem->install_rom(0xe000, 0xefff, + mem->machine().root_device().memregion("maincpu")->base() + 0xe000); + mem->install_write_handler(0xe000, 0xefff, 0, 0, + write8_delegate(FUNC(bml3_state::bml3_e000_w), this), + 0); + } + } + + if(data & 1) + { + mem->install_readwrite_handler(0xf000, 0xfeff, 0, 0, + read8_delegate(FUNC(bml3_state::bml3_f000_r), this), + write8_delegate(FUNC(bml3_state::bml3_f000_w), this), 0); + } + else + { + mem->install_rom(0xf000, 0xfeff, + mem->machine().root_device().memregion("maincpu")->base() + 0xf000); + mem->install_write_handler(0xf000, 0xfeff, 0, 0, + write8_delegate(FUNC(bml3_state::bml3_f000_w), this), + 0); + } + + if(data & 2) + { + mem->install_readwrite_handler(0xfff0, 0xffff, 0, 0, + read8_delegate(FUNC(bml3_state::bml3_fff0_r), this), + write8_delegate(FUNC(bml3_state::bml3_fff0_w), this), 0); + } + else + { + mem->install_rom(0xfff0, 0xffff, + mem->machine().root_device().memregion("maincpu")->base() + 0xfff0); + mem->install_write_handler(0xfff0, 0xffff, 0, 0, + write8_delegate(FUNC(bml3_state::bml3_fff0_w), this), + 0); + } +} + +static const pia6821_interface bml3_pia_config = +{ + DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, + + DEVCB_DRIVER_MEMBER(bml3_state, bml3_piaA_w), /* port A output */ + DEVCB_NULL, + DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL +}; + + +READ_LINE_MEMBER( bml3_state::bml3_acia_rx_r ) +{ + printf("TAPE R\n"); + return 1; +} + +WRITE_LINE_MEMBER( bml3_state::bml3_acia_tx_w ) +{ + printf("%02x TAPE\n",state); +} + + +READ_LINE_MEMBER( bml3_state::bml3_acia_dts_r ) +{ + printf("TAPE R DTS\n"); + return 1; +} + +WRITE_LINE_MEMBER( bml3_state::bml3_acia_rts_w ) +{ + printf("%02x TAPE RTS\n",state); +} + +READ_LINE_MEMBER( bml3_state::bml3_acia_dcd_r ) +{ + printf("TAPE R DCD\n"); + return 1; +} + +WRITE_LINE_MEMBER( bml3_state::bml3_acia_irq_w ) +{ + printf("%02x TAPE IRQ\n",state); +} + + +static ACIA6850_INTERFACE( bml3_acia_if ) +{ + 600, + 600, + DEVCB_DRIVER_LINE_MEMBER(bml3_state, bml3_acia_rx_r), + DEVCB_DRIVER_LINE_MEMBER(bml3_state, bml3_acia_tx_w), + DEVCB_DRIVER_LINE_MEMBER(bml3_state, bml3_acia_dts_r), + DEVCB_DRIVER_LINE_MEMBER(bml3_state, bml3_acia_rts_w), + DEVCB_DRIVER_LINE_MEMBER(bml3_state, bml3_acia_dcd_r), + DEVCB_DRIVER_LINE_MEMBER(bml3_state, bml3_acia_irq_w) +}; + +static const ym2203_interface ym2203_interface_1 = +{ + { + AY8910_LEGACY_OUTPUT, + AY8910_DEFAULT_LOADS, + DEVCB_NULL, // read A + DEVCB_NULL, // read B + DEVCB_NULL, // write A + DEVCB_NULL // write B + }, + DEVCB_NULL +}; + +/* TODO */ +static const floppy_interface bml3_floppy_interface = +{ + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + FLOPPY_STANDARD_5_25_DSHD, + LEGACY_FLOPPY_OPTIONS_NAME(default), + "floppy_3_5", + NULL +}; + +static MACHINE_CONFIG_START( bml3, bml3_state ) + /* basic machine hardware */ + MCFG_CPU_ADD("maincpu",M6809, XTAL_1MHz) + MCFG_CPU_PROGRAM_MAP(bml3_mem) + MCFG_CPU_VBLANK_INT("screen", bml3_timer_firq ) +// MCFG_CPU_PERIODIC_INT(bml3_firq,45) + + MCFG_MACHINE_START(bml3) +// MCFG_MACHINE_RESET(bml3) + + /* video hardware */ + MCFG_SCREEN_ADD("screen", RASTER) + MCFG_SCREEN_REFRESH_RATE(60) + MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ + MCFG_SCREEN_SIZE(640, 480) + MCFG_SCREEN_VISIBLE_AREA(0, 320-1, 0, 200-1) + MCFG_SCREEN_UPDATE_STATIC(bml3) + MCFG_VIDEO_START(bml3) + MCFG_PALETTE_LENGTH(8) + MCFG_PALETTE_INIT(bml3) + MCFG_GFXDECODE(bml3) + + /* Devices */ + MCFG_MC6845_ADD("crtc", H46505, XTAL_1MHz, mc6845_intf) + MCFG_TIMER_ADD_PERIODIC("keyboard_timer", keyboard_callback, attotime::from_hz(240/8)) + MCFG_MC6843_ADD( "mc6843", bml3_6843_if ) + MCFG_PIA6821_ADD("pia6821", bml3_pia_config) + MCFG_ACIA6850_ADD("acia6850", bml3_acia_if) + + MCFG_LEGACY_FLOPPY_4_DRIVES_ADD(bml3_floppy_interface) + + /* Audio */ + MCFG_SPEAKER_STANDARD_MONO("mono") + MCFG_SOUND_ADD(BEEPER_TAG, BEEP, 0) + MCFG_SOUND_ROUTE(ALL_OUTPUTS,"mono",0.50) + + MCFG_SOUND_ADD("ym2203", YM2203, 2000000) //unknown clock / divider + MCFG_SOUND_CONFIG(ym2203_interface_1) + MCFG_SOUND_ROUTE(0, "mono", 0.25) + MCFG_SOUND_ROUTE(1, "mono", 0.25) + MCFG_SOUND_ROUTE(2, "mono", 0.50) + MCFG_SOUND_ROUTE(3, "mono", 0.50) +MACHINE_CONFIG_END + +/* ROM definition */ +ROM_START( bml3 ) + ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF ) +// ROM_LOAD( "l3bas.rom", 0xa000, 0x6000, BAD_DUMP CRC(d81baa07) SHA1(a8fd6b29d8c505b756dbf5354341c48f9ac1d24d)) //original, 24k isn't a proper rom size! + /* Handcrafted ROMs, rom labels and contents might not match */ + ROM_LOAD( "598 p16611.ic3", 0xa000, 0x2000, BAD_DUMP CRC(954b9bad) SHA1(047948fac6808717c60a1d0ac9205a5725362430)) + ROM_LOAD( "599 p16561.ic4", 0xc000, 0x2000, BAD_DUMP CRC(b27a48f5) SHA1(94cb616df4caa6415c5076f9acdf675acb7453e2)) + ROM_LOAD( "600 p16681.ic5", 0xe000, 0x2000, BAD_DUMP CRC(fe3988a5) SHA1(edc732f1cd421e0cf45ffcfc71c5589958ceaae7)) + + ROM_REGION( 0x1000, "chargen", 0 ) + ROM_LOAD("font.rom", 0x00000, 0x1000, BAD_DUMP CRC(0b6f2f10) SHA1(dc411b447ca414e94843636d8b5f910c954581fb) ) // handcrafted + + ROM_REGION( 0x8000, "vram", ROMREGION_ERASEFF ) + + ROM_REGION( 0x20000, "kanji", ROMREGION_ERASEFF ) + ROM_LOAD("kanji.rom", 0x00000, 0x20000, NO_DUMP ) +ROM_END + +/* Driver */ + +/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ +COMP( 1980, bml3, 0, 0, bml3, bml3, driver_device, 0, "Hitachi", "Basic Master Level 3", GAME_NOT_WORKING | GAME_NO_SOUND) + |