// license:BSD-3-Clause // copyright-holders:Robbbert /*************************************************************************************** Argo 2011-03-16 Skeleton driver. There are no manuals, diagrams, or anything else available afaik. The entire driver is guesswork, however it appears to be related to UNIOR. The monitor will only allow certain characters to be typed, thus the modifier keys appear to do nothing. There is no need to use the enter key; using spacebar and the correct parameters is enough. Commands: same as UNIOR ToDo: - Add remaining devices, most likely 8255. - There is no obvious evidence of sound. - our dma doesn't emulate the update_flag, so had to use a hack for the L command - cursor is one character further to the right than it should be, used another hack ****************************************************************************************/ #include "emu.h" #include "cpu/z80/z80.h" #include "machine/i8251.h" #include "machine/pit8253.h" #include "machine/i8257.h" #include "video/i8275.h" #include "imagedev/cassette.h" //#include "sound/spkrdev.h" #include "speaker.h" #include "machine/timer.h" #include "emupal.h" #include "screen.h" class argo_state : public driver_device { public: argo_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) , m_maincpu(*this, "maincpu") , m_p_videoram(*this, "videoram") , m_p_chargen(*this, "chargen") , m_uart(*this, "uart") , m_pit(*this, "pit") , m_dma(*this, "dma") , m_crtc(*this, "crtc") , m_cass(*this, "cassette") , m_palette(*this, "palette") , m_io_keyboard(*this, "X%d", 0) { } void argo(machine_config &config); void init_argo(); private: enum { TIMER_BOOT }; DECLARE_WRITE8_MEMBER(argo_videoram_w); DECLARE_READ8_MEMBER(argo_io_r); DECLARE_WRITE8_MEMBER(argo_io_w); DECLARE_WRITE_LINE_MEMBER(z0_w); DECLARE_WRITE_LINE_MEMBER(hrq_w); void argo_palette(palette_device &palette) const; DECLARE_READ8_MEMBER(dma_r); I8275_DRAW_CHARACTER_MEMBER(display_pixels); TIMER_DEVICE_CALLBACK_MEMBER(kansas_r); void io_map(address_map &map); void mem_map(address_map &map); required_device m_maincpu; required_region_ptr m_p_videoram; required_region_ptr m_p_chargen; required_device m_uart; required_device m_pit; required_device m_dma; required_device m_crtc; required_device m_cass; required_device m_palette; required_ioport_array<11> m_io_keyboard; uint8_t m_framecnt; bool m_ram_ctrl; uint8_t m_scroll_ctrl; bool m_txe, m_txd, m_rts, m_casspol; u8 m_cass_data[4]; virtual void machine_reset() override; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; }; // write to videoram if following 'out b9,61' otherwise write to the unknown 'extra' ram WRITE8_MEMBER(argo_state::argo_videoram_w) { uint8_t *RAM; if (m_ram_ctrl) m_p_videoram[offset] = data; else { RAM = memregion("extraram")->base(); RAM[offset] = data; } } READ8_MEMBER(argo_state::argo_io_r) { uint8_t low_io = offset; switch (low_io) { case 0xA1: // keyboard offset >>= 8; if (offset < 11) return m_io_keyboard[offset]->read(); else return 0xff; case 0xA0: case 0xA2: case 0xA4: case 0xA6: offset >>= 1; return m_pit->read(offset&3); case 0xC0: case 0xC4: offset >>= 2; return m_crtc->read(offset&1); case 0xE8: // wants bit 4 low then high { u8 data = m_dma->read(space, 8); data |= (m_framecnt << 4); // hack because dma update_flag is not emulated return data; } default: logerror("%s: In %X\n",machine().describe_context(),low_io); return 0xff; } } WRITE8_MEMBER(argo_state::argo_io_w) { switch (offset) { case 0xA0: case 0xA2: case 0xA4: case 0xA6: offset >>= 1; m_pit->write(offset&3, data); break; case 0xA1: // prep scroll step 1 m_scroll_ctrl = (data == 0x61); break; case 0xA9: // prep scroll step 2 if ((m_scroll_ctrl == 1) && (data == 0x61)) m_scroll_ctrl++; break; case 0xB9: // switch between videoram and extraram m_ram_ctrl = (data == 0x61); break; case 0xC0: case 0xC4: offset >>= 2; m_crtc->write(offset&1, data); break; case 0xE8: // hardware scroll if ((m_scroll_ctrl == 2) & (data == 0xe3)) { memmove(m_p_videoram, m_p_videoram+80, 24*80); m_scroll_ctrl = 0; } m_dma->write(space, 8, data); break; default: logerror("%s: Out %X,%X\n",machine().describe_context(),offset,data); } } TIMER_DEVICE_CALLBACK_MEMBER( argo_state::kansas_r ) { if (m_rts) { m_cass_data[1] = m_cass_data[2] = m_cass_data[3] = 0; m_casspol = 1; return; } m_cass_data[1]++; m_cass_data[2]++; uint8_t cass_ws = (m_cass->input() > +0.04) ? 1 : 0; if (cass_ws != m_cass_data[0]) { m_cass_data[0] = cass_ws; if (m_cass_data[1] > 13) m_casspol ^= 1; m_cass_data[1] = 0; m_cass_data[2] = 0; m_uart->write_rxd(m_casspol); } if ((m_cass_data[2] & 7)==2) { m_cass_data[3]++; m_uart->write_rxc(BIT(m_cass_data[3], 0)); } } WRITE_LINE_MEMBER(argo_state::z0_w) { // write - incoming 2400Hz m_uart->write_txc(state); if (!m_txe) { m_cass->output((m_txd ^ state) ? -1.0 : 1.0); } // read - incoming 2514Hz } READ8_MEMBER(argo_state::dma_r) { if (offset < 0xf800) return m_maincpu->space(AS_PROGRAM).read_byte(offset); else return m_p_videoram[offset & 0x7ff]; } WRITE_LINE_MEMBER( argo_state::hrq_w ) { m_maincpu->set_input_line(INPUT_LINE_HALT, state); m_dma->hlda_w(state); } I8275_DRAW_CHARACTER_MEMBER(argo_state::display_pixels) { if ((x == 0) && (y == 0)) m_framecnt++; const rgb_t *palette = m_palette->palette()->entry_list_raw(); uint8_t gfx = m_p_chargen[(linecount & 15) | (charcode << 4)]; if (vsp) gfx = 0; if (lten) { gfx = 0xff; if (x > 6) x-=6; // hack to fix cursor position } if (rvv) gfx ^= 0xff; for(uint8_t i=0;i<7;i++) bitmap.pix32(y, x + i) = palette[BIT(gfx, 6-i) ? (hlgt ? 2 : 1) : 0]; } static constexpr rgb_t argo_pens[3] = { { 0x00, 0x00, 0x00 }, // black { 0xa0, 0xa0, 0xa0 }, // white { 0xff, 0xff, 0xff } // highlight }; void argo_state::argo_palette(palette_device &palette) const { palette.set_pen_colors(0, argo_pens); } /* F4 Character Displayer */ static const gfx_layout argo_charlayout = { 8, 9, /* 8 x 9 characters */ 512, /* 512 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 }, 8*16 /* every char takes 16 bytes */ }; static GFXDECODE_START( gfx_argo ) GFXDECODE_ENTRY( "chargen", 0x0000, argo_charlayout, 0, 1 ) GFXDECODE_END void argo_state::mem_map(address_map &map) { map.unmap_value_high(); map(0x0000, 0x07ff).bankrw("boot"); map(0x0800, 0xf7ff).ram(); map(0xf800, 0xffff).rom().w(FUNC(argo_state::argo_videoram_w)); } void argo_state::io_map(address_map &map) { map(0x0000, 0xFFFF).r(FUNC(argo_state::argo_io_r)); map(0x0000, 0x00ff).mirror(0xff00).w(FUNC(argo_state::argo_io_w)); map(0x00c1, 0x00c1).mirror(0xff00).rw(m_uart, FUNC(i8251_device::data_r), FUNC(i8251_device::data_w)); map(0x00c3, 0x00c3).mirror(0xff00).rw(m_uart, FUNC(i8251_device::status_r), FUNC(i8251_device::control_w)); map(0x00e0, 0x00e7).mirror(0xff00).rw(m_dma, FUNC(i8257_device::read), FUNC(i8257_device::write)); } /* Input ports */ static INPUT_PORTS_START( argo ) // Keyboard was worked out by trial & error;'F' keys produce symbols PORT_START("X0") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("-") PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHAR('-') PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F10) // J PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_UNUSED) // nothing PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_UNUSED) // nothing PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LShift") PORT_CODE(KEYCODE_LSHIFT) PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("7") PORT_CODE(KEYCODE_7_PAD) PORT_CHAR('7') PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8") PORT_CODE(KEYCODE_8_PAD) PORT_CHAR('8') PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("9") PORT_CODE(KEYCODE_9_PAD) PORT_CHAR('9') PORT_START("X1") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Esc") PORT_CODE(KEYCODE_ESC) PORT_CHAR(27) PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Tab") PORT_CODE(KEYCODE_TAB) PORT_CHAR(9) PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Ctrl") PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RShift") PORT_CODE(KEYCODE_RSHIFT) PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("??") PORT_CODE(KEYCODE_F2) PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0_PAD) PORT_CHAR('0') PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(".") PORT_CODE(KEYCODE_DEL_PAD) PORT_CHAR('.') PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("+") PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHAR('+') PORT_START("X2") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("1") PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHAR('A') PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("??") PORT_CODE(KEYCODE_F12) PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("1") PORT_CODE(KEYCODE_1_PAD) PORT_CHAR('1') PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2") PORT_CODE(KEYCODE_2_PAD) PORT_CHAR('2') PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3") PORT_CODE(KEYCODE_3_PAD) PORT_CHAR('3') PORT_START("X3") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F1) // A PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2") PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W) PORT_CHAR('W') PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S) PORT_CHAR('S') PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X) PORT_CHAR('X') PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("4") PORT_CODE(KEYCODE_4_PAD) PORT_CHAR('4') PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("5") PORT_CODE(KEYCODE_5_PAD) PORT_CHAR('5') PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("6") PORT_CODE(KEYCODE_6_PAD) PORT_CHAR('6') PORT_START("X4") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F2) // B PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3") PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_CHAR('E') PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) PORT_CHAR('M') PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CHAR('C') PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F11) // K PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F8) // H PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F9) // I PORT_START("X5") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F3) // C PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("4") PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R) PORT_CHAR('R') PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) PORT_CHAR('F') PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_V) PORT_CHAR('V') PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("BS") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F7) // G PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F6) // F PORT_START("X6") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("5") PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T) PORT_CHAR('T') PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G) PORT_CHAR('G') PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHAR('B') PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT) PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Enter") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("*") PORT_CODE(KEYCODE_ASTERISK) PORT_CHAR('*') PORT_START("X7") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F4) // D PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("6") PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H) PORT_CHAR('H') PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N) PORT_CHAR('N') PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP) PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("\\") PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_START("X8") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F5) // E PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("7") PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U) PORT_CHAR('U') PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("J") PORT_CODE(KEYCODE_J) PORT_CHAR('J') PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M) PORT_CHAR('M') PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("`") PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("]") PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("=") PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_START("X9") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8") PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I) PORT_CHAR('I') PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K) PORT_CHAR('K') PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(",") PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT) PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("\'") PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("[") PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("-") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_START("X10") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("9") PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O) PORT_CHAR('O') PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L) PORT_CHAR('L') // if L is the first character, computer hangs PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(".") PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("/") PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(";") PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P) PORT_CHAR('P') PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0) PORT_CHAR('0') INPUT_PORTS_END void argo_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) { switch (id) { case TIMER_BOOT: /* after the first 4 bytes have been read from ROM, switch the ram back in */ membank("boot")->set_entry(0); break; default: throw emu_fatalerror("Unknown id in argo_state::device_timer"); } } void argo_state::machine_reset() { membank("boot")->set_entry(1); timer_set(attotime::from_usec(5), TIMER_BOOT); } void argo_state::init_argo() { uint8_t *RAM = memregion("maincpu")->base(); membank("boot")->configure_entries(0, 2, &RAM[0x0000], 0xf800); } void argo_state::argo(machine_config &config) { /* basic machine hardware */ Z80(config, m_maincpu, 3500000); // unknown frequency m_maincpu->set_addrmap(AS_PROGRAM, &argo_state::mem_map); m_maincpu->set_addrmap(AS_IO, &argo_state::io_map); /* video hardware */ screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); screen.set_refresh_hz(50); screen.set_size(640, 200); screen.set_visarea_full(); screen.set_screen_update("crtc", FUNC(i8275_device::screen_update)); GFXDECODE(config, "gfxdecode", m_palette, gfx_argo); PALETTE(config, m_palette, FUNC(argo_state::argo_palette), 3); /* sound hardware */ SPEAKER(config, "mono").front_center(); //SPEAKER_SOUND(config, "speaker").add_route(ALL_OUTPUTS, "mono", 0.50); CASSETTE(config, m_cass); m_cass->set_default_state(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED); m_cass->add_route(ALL_OUTPUTS, "mono", 0.15); TIMER(config, "kansas_r").configure_periodic(FUNC(argo_state::kansas_r), attotime::from_hz(38400)); /* Devices */ I8251(config, m_uart, 0); m_uart->txd_handler().set([this] (bool state) { m_txd = state; }); m_uart->txempty_handler().set([this] (bool state) { m_txe = state; }); m_uart->rts_handler().set([this] (bool state) { m_rts = state; }); PIT8253(config, m_pit, 0); m_pit->set_clk<0>(1689600); // this gives the 2400Hz required by the cassette m_pit->out_handler<0>().set(FUNC(argo_state::z0_w)); m_pit->set_clk<1>(0); m_pit->set_clk<2>(0); I8257(config, m_dma, XTAL(20'000'000) / 9); // unknown frequency m_dma->out_hrq_cb().set(FUNC(argo_state::hrq_w)); m_dma->in_memr_cb().set(FUNC(argo_state::dma_r)); m_dma->out_iow_cb<2>().set("crtc", FUNC(i8275_device::dack_w)); i8275_device &crtc(I8275(config, "crtc", XTAL(20'000'000) / 12)); // unknown frequency crtc.set_character_width(6); crtc.set_display_callback(FUNC(argo_state::display_pixels)); crtc.drq_wr_callback().set(m_dma, FUNC(i8257_device::dreq2_w)); crtc.set_screen("screen"); } /* ROM definition */ ROM_START( argo ) ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF ) ROM_LOAD( "argo.rom", 0xf800, 0x0800, CRC(4c4c045b) SHA1(be2b97728cc190d4a8bd27262ba9423f252d31a3) ) ROM_REGION( 0x0800, "videoram", ROMREGION_ERASEFF ) ROM_REGION( 0x0800, "extraram", ROMREGION_ERASEFF ) // no idea what this is for /* character generator not dumped, using the one from 'c10' for now */ ROM_REGION( 0x2000, "chargen", 0 ) ROM_LOAD( "c10_char.bin", 0x0000, 0x2000, BAD_DUMP CRC(cb530b6f) SHA1(95590bbb433db9c4317f535723b29516b9b9fcbf)) ROM_END /* Driver */ /* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ COMP( 1986, argo, unior, 0, argo, argo, argo_state, init_argo, "", "Argo", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)