From 1db8f70e30f9c36854f23e2e787ef8a2946af911 Mon Sep 17 00:00:00 2001 From: angelosa Date: Fri, 28 Jun 2024 18:58:17 +0200 Subject: casio/fp200.cpp: cleanups, convert I/O to memory_view, hookup RTC --- src/mame/casio/fp200.cpp | 208 ++++++++++++++++++----------------------------- 1 file changed, 78 insertions(+), 130 deletions(-) diff --git a/src/mame/casio/fp200.cpp b/src/mame/casio/fp200.cpp index 56f8e0a179a..756fbb790de 100644 --- a/src/mame/casio/fp200.cpp +++ b/src/mame/casio/fp200.cpp @@ -1,27 +1,25 @@ // license:BSD-3-Clause // copyright-holders:Angelo Salese -/*************************************************************************** - - FP-200 (c) 1982 Casio - - preliminary driver by Angelo Salese +/************************************************************************************************** - TODO: - - What's the LCDC type? Custom? - - Unless I've missed something in the schems, this one shouldn't have any - sound capability. - - backup RAM. - - Rewrite video emulation from scratch. +FP-200 (c) 1982 Casio - Notes: - - on start-up there's a "memory illegal" warning. Enter "RESET" command - to initialize it (thanks to Takeda Toshiya for pointing this out). +TODO: +- Identify LCDC type, move to device (custom inside the gate array); +- Confirm not having any sound capaibilities; +- backup RAM; +- cassette i/f; +- FDC (requires test program that Service manual mentions); -***************************************************************************/ +Notes: +- on start-up there's a "memory illegal" warning. Enter "RESET" command + to initialize it (thanks to Takeda Toshiya for pointing this out). +**************************************************************************************************/ #include "emu.h" #include "cpu/i8085/i8085.h" +#include "machine/rp5c01.h" #include "emupal.h" #include "screen.h" #include "speaker.h" @@ -37,6 +35,8 @@ public: fp200_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) , m_maincpu(*this, "maincpu") + , m_rtc(*this, "rtc") + , m_ioview(*this, "ioview") { } void fp200(machine_config &config); @@ -46,9 +46,10 @@ public: private: // devices required_device m_maincpu; - uint8_t m_io_type = 0; + required_device m_rtc; + memory_view m_ioview; uint8_t *m_chargen = nullptr; - uint8_t m_keyb_mux = 0; + uint8_t m_keyb_matrix = 0; struct{ uint8_t x = 0; @@ -65,19 +66,17 @@ private: // screen updates uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - uint8_t fp200_io_r(offs_t offset); - void fp200_io_w(offs_t offset, uint8_t data); - uint8_t fp200_lcd_r(offs_t offset); - void fp200_lcd_w(offs_t offset, uint8_t data); - uint8_t fp200_keyb_r(offs_t offset); - void fp200_keyb_w(offs_t offset, uint8_t data); + uint8_t lcd_r(offs_t offset); + void lcd_w(offs_t offset, uint8_t data); + uint8_t keyb_r(offs_t offset); + void keyb_w(offs_t offset, uint8_t data); void sod_w(int state); int sid_r(); - void fp200_palette(palette_device &palette) const; - void fp200_io(address_map &map); - void fp200_map(address_map &map); + void palette_init(palette_device &palette) const; + void main_io(address_map &map); + void main_map(address_map &map); // driver_device overrides virtual void machine_start() override; @@ -92,7 +91,7 @@ void fp200_state::video_start() m_lcd.attr = make_unique_clear(20*64); } -/* TODO: Very preliminary, I actually believe that the LCDC writes in a blitter fashion ... */ +// TODO: rewrite, don't loop 4 times uint32_t fp200_state::screen_update( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect ) { uint16_t l_offs, r_offs; @@ -101,11 +100,11 @@ uint32_t fp200_state::screen_update( screen_device &screen, bitmap_ind16 &bitmap l_offs = 0; r_offs = 0; - for(int y=cliprect.top(); y (L) %02x\n",m_lcd.x,m_lcd.y,m_lcd.status); + //logerror("%d %d -> (L) %02x\n",m_lcd.x,m_lcd.y,m_lcd.status); if(m_lcd.status == 0xb) res = read_lcd_attr(m_lcd.x,m_lcd.y); else if(m_lcd.status == 1) res = read_lcd_vram(m_lcd.x,m_lcd.y); break; case 2: - //printf("%d %d -> (R) %02x\n",m_lcd.x,m_lcd.y,m_lcd.status); + //logerror("%d %d -> (R) %02x\n",m_lcd.x,m_lcd.y,m_lcd.status); if(m_lcd.status == 0xb) res = read_lcd_attr(m_lcd.x + 10,m_lcd.y); else if(m_lcd.status == 1) @@ -272,7 +271,7 @@ void fp200_state::write_lcd_attr(uint16_t X, uint16_t Y,uint8_t data) return; //if(data != 0x60) - // printf("%d %d %02x\n",X,Y,data); + // logerror("%d %d %02x\n",X,Y,data); m_lcd.attr[base_offs] = data; } @@ -293,19 +292,19 @@ void fp200_state::write_lcd_vram(uint16_t X, uint16_t Y,uint8_t data) } } -void fp200_state::fp200_lcd_w(offs_t offset, uint8_t data) +void fp200_state::lcd_w(offs_t offset, uint8_t data) { switch(offset) { case 1: - //printf("%d %d -> %02x (%c) (L %02x)\n",m_lcd.x,m_lcd.y,data,data,m_lcd.status); + //logerror("%d %d -> %02x (%c) (L %02x)\n",m_lcd.x,m_lcd.y,data,data,m_lcd.status); if(m_lcd.status == 0xb) write_lcd_attr(m_lcd.x,m_lcd.y,data); else if(m_lcd.status == 1) write_lcd_vram(m_lcd.x,m_lcd.y,data); break; case 2: - //printf("%d %d -> %02x (%c) (R %02x)\n",m_lcd.x + 10,m_lcd.y,data,data,m_lcd.status); + //logerror("%d %d -> %02x (%c) (R %02x)\n",m_lcd.x + 10,m_lcd.y,data,data,m_lcd.status); if(m_lcd.status == 0xb) write_lcd_attr(m_lcd.x + 10,m_lcd.y,data); else if(m_lcd.status == 1) @@ -323,7 +322,7 @@ void fp200_state::fp200_lcd_w(offs_t offset, uint8_t data) } } -uint8_t fp200_state::fp200_keyb_r(offs_t offset) +uint8_t fp200_state::keyb_r(offs_t offset) { const char *const keynames[16] = { "KEY0", "KEY1", "KEY2", "KEY3", "KEY4", "KEY5", "KEY6", "KEY7", @@ -332,108 +331,57 @@ uint8_t fp200_state::fp200_keyb_r(offs_t offset) uint8_t res; if(offset == 0) - res = ioport(keynames[m_keyb_mux])->read(); + res = ioport(keynames[m_keyb_matrix])->read(); else { - printf("Unknown keyboard offset read access %02x\n",offset + 0x20); + logerror("Unknown keyboard offset read access %02x\n",offset + 0x20); res = 0; } return res; } -void fp200_state::fp200_keyb_w(offs_t offset, uint8_t data) +void fp200_state::keyb_w(offs_t offset, uint8_t data) { if(offset == 1) - m_keyb_mux = data & 0xf; - else if(offset == 0) - { - // ... ? - } + m_keyb_matrix = data & 0xf; else - printf("Unknown keyboard offset write access %02x %02x\n",offset + 0x20,data); + logerror("Unknown keyboard offset write access %02x %02x\n",offset + 0x20,data); } -/* -Annoyingly the i/o map uses the SOD to access different devices, so we need trampolines. -SOD = 0 -0x10 - 0x1f Timer control (RPC05 RTC) -0x20 - 0x2f AUTO-POWER OFF -0x40 - 0x4f FDC Device ID Code (5 for "FP-1021FD") -0x80 - 0xff FDD (unknown type) -SOD = 1 -0x00 - 0x0f LCD control. -0x10 - 0x1f I/O control -0x20 - 0x2f Keyboard -0x40 - 0x4f MT.RS-232C control -0x80 - 0x8f Printer (Centronics) -*/ -uint8_t fp200_state::fp200_io_r(offs_t offset) +void fp200_state::main_map(address_map &map) { - uint8_t res; - - if(m_io_type == 0) - { - res = 0; - logerror("Unemulated I/O read %02x (%02x)\n",offset,m_io_type); - } - else - { - switch(offset & 0xf0) - { - //case 0x00: return; - case 0x00: res = fp200_lcd_r(offset & 0xf); break; - case 0x20: res = fp200_keyb_r(offset & 0xf); break; - default: res = 0; logerror("Unemulated I/O read %02x (%02x)\n",offset,m_io_type); break; - } - } - - return res; -} - -void fp200_state::fp200_io_w(offs_t offset, uint8_t data) -{ - if(m_io_type == 0) - { - switch(offset & 0xf0) - { - default:logerror("Unemulated I/O write %02x (%02x) <- %02x\n",offset,m_io_type,data); break; - } - } - else - { - switch(offset & 0xf0) - { - case 0x00: fp200_lcd_w(offset & 0xf,data); break; - case 0x20: fp200_keyb_w(offset & 0xf,data); break; - default:logerror("Unemulated I/O write %02x (%02x) <- %02x\n",offset,m_io_type,data); break; - } - } -} - -void fp200_state::fp200_map(address_map &map) -{ - map(0x0000, 0x7fff).rom(); - map(0x8000, 0x9fff).ram(); -// 0xa000, 0xffff exp RAM + map(0x0000, 0x7fff).rom(); // basic & cetl + // TODO: 1 waitstate penalty for accessing any RAM + map(0x8000, 0x9fff).ram(); // internal RAM +// 0xa000, 0xffff exp RAM (FP-201RAM) map(0xa000, 0xbfff).ram(); map(0xc000, 0xdfff).ram(); - map(0xe000, 0xffff).ram(); + map(0xe000, 0xffff).ram(); // or exp ROM (FP-206ROM) } -void fp200_state::fp200_io(address_map &map) +void fp200_state::main_io(address_map &map) { - map(0x00, 0xff).rw(FUNC(fp200_state::fp200_io_r), FUNC(fp200_state::fp200_io_w)); + map(0x00, 0xff).view(m_ioview); + m_ioview[0](0x10, 0x1f).rw("rtc", FUNC(rp5c01_device::read), FUNC(rp5c01_device::write)); +// m_ioview[0](0x20, 0x2f) AUTO-POWER OFF +// m_ioview[0](0x40, 0x4f) FDC Device ID Code (5 for "FP-1021FD") +// m_ioview[0](0x80, 0xff) FDD (unknown type) + m_ioview[1](0x00, 0x0f).rw(FUNC(fp200_state::lcd_r), FUNC(fp200_state::lcd_w)); +// m_ioview[1](0x10, 0x10) I/O control (w/o), D1 selects CMT or RS-232C +// m_ioview[1](0x11, 0x11) I/O control (w/o), uPD65010G gate array control + m_ioview[1](0x20, 0x2f).rw(FUNC(fp200_state::keyb_r), FUNC(fp200_state::keyb_w)); +// m_ioview[1](0x40, 0x4f) CMT & RS-232C control +// m_ioview[1](0x80, 0x8f) [Centronics] printer } INPUT_CHANGED_MEMBER(fp200_state::keyb_irq) { /* a keyboard stroke causes a rst7.5 */ m_maincpu->set_input_line(I8085_RST75_LINE, (newval) ? ASSERT_LINE : CLEAR_LINE); - } -/* TODO: remote SW? */ +// TODO: implement remote SW static INPUT_PORTS_START( fp200 ) PORT_START("KEY0") PORT_BIT( 0x0f, IP_ACTIVE_HIGH, IPT_UNUSED ) @@ -541,8 +489,8 @@ static const gfx_layout charlayout = RGN_FRAC(1,1), 1, { RGN_FRAC(0,1) }, - { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 }, - { 0, 1, 2, 3, 4, 5, 6, 7 }, + { STEP8(0, 8) }, + { STEP8(0, 1) }, 8*8 }; @@ -556,10 +504,9 @@ void fp200_state::machine_start() uint8_t *raw_gfx = memregion("raw_gfx")->base(); m_chargen = memregion("chargen")->base(); - for(int i=0;i<0x800;i++) - { - m_chargen[i] = raw_gfx[bitswap<16>(i,15,14,13,12,11,6,5,4,3,10,9,8,7,2,1,0)]; - } + // HACK: convert GFX to a more usable format + for(int i = 0; i < 0x800; i++) + m_chargen[i] = raw_gfx[bitswap<16>(i, 15, 14, 13, 12, 11, 6, 5, 4, 3, 10, 9, 8, 7, 2, 1, 0)]; } void fp200_state::machine_reset() @@ -567,7 +514,7 @@ void fp200_state::machine_reset() } -void fp200_state::fp200_palette(palette_device &palette) const +void fp200_state::palette_init(palette_device &palette) const { palette.set_pen_color(0, 0xa0, 0xa8, 0xa0); palette.set_pen_color(1, 0x30, 0x38, 0x10); @@ -575,23 +522,25 @@ void fp200_state::fp200_palette(palette_device &palette) const void fp200_state::sod_w(int state) { - m_io_type = state; + m_ioview.select(state); } int fp200_state::sid_r() { - return (ioport("KEYMOD")->read() >> m_keyb_mux) & 1; + return (ioport("KEYMOD")->read() >> m_keyb_matrix) & 1; } void fp200_state::fp200(machine_config &config) { /* basic machine hardware */ I8085A(config, m_maincpu, MAIN_CLOCK); - m_maincpu->set_addrmap(AS_PROGRAM, &fp200_state::fp200_map); - m_maincpu->set_addrmap(AS_IO, &fp200_state::fp200_io); + m_maincpu->set_addrmap(AS_PROGRAM, &fp200_state::main_map); + m_maincpu->set_addrmap(AS_IO, &fp200_state::main_io); m_maincpu->in_sid_func().set(FUNC(fp200_state::sid_r)); m_maincpu->out_sod_func().set(FUNC(fp200_state::sod_w)); + RP5C01(config, "rtc", XTAL(32'768)); + /* video hardware */ screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_LCD)); screen.set_refresh_hz(60); @@ -603,10 +552,9 @@ void fp200_state::fp200(machine_config &config) GFXDECODE(config, "gfxdecode", "palette", gfx_fp200); - PALETTE(config, "palette", FUNC(fp200_state::fp200_palette), 2); + PALETTE(config, "palette", FUNC(fp200_state::palette_init), 2); - /* sound hardware */ - SPEAKER(config, "mono").front_center(); + // No sound HW } -- cgit v1.2.3