diff --git a/src/emu/cpu/tms7000/tms7000.c b/src/emu/cpu/tms7000/tms7000.c index 5535a4d2741..30266fa6f9d 100644 --- a/src/emu/cpu/tms7000/tms7000.c +++ b/src/emu/cpu/tms7000/tms7000.c @@ -23,6 +23,7 @@ * - memory modes with IOCNT0, currently ignored * - timer event counter mode (timer control register, bit 6) * - TMS70x1/2 serial port and timer 3 + * - TMS70C46 is same as TMS70C40, except with support for memory mapped I/O? * - when they're needed, add TMS70Cx2, TMS7742, TMS77C82, SE70xxx * *****************************************************************************/ @@ -50,6 +51,7 @@ const device_type TMS7040 = &device_creator; const device_type TMS70C00 = &device_creator; const device_type TMS70C20 = &device_creator; const device_type TMS70C40 = &device_creator; +const device_type TMS70C46 = &device_creator; const device_type TMS7001 = &device_creator; const device_type TMS7041 = &device_creator; const device_type TMS7002 = &device_creator; @@ -149,6 +151,11 @@ tms70c40_device::tms70c40_device(const machine_config &mconfig, const char *tag, { } +tms70c46_device::tms70c46_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : tms7000_device(mconfig, TMS70C46, "TMS70C46", tag, owner, clock, ADDRESS_MAP_NAME(tms7040_mem), TMS7000_CHIP_IS_CMOS, "tms70c46", __FILE__) +{ +} + tms7001_device::tms7001_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : tms7000_device(mconfig, TMS7001, "TMS7001", tag, owner, clock, ADDRESS_MAP_NAME(tms7001_mem), TMS7000_CHIP_FAMILY_70X2, "tms7001", __FILE__) { diff --git a/src/emu/cpu/tms7000/tms7000.h b/src/emu/cpu/tms7000/tms7000.h index 6ae9a345209..1f0cb89da5a 100644 --- a/src/emu/cpu/tms7000/tms7000.h +++ b/src/emu/cpu/tms7000/tms7000.h @@ -303,6 +303,13 @@ public: }; +class tms70c46_device : public tms7000_device +{ +public: + tms70c46_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); +}; + + class tms7001_device : public tms7000_device { public: @@ -338,6 +345,7 @@ extern const device_type TMS7040; extern const device_type TMS70C00; extern const device_type TMS70C20; extern const device_type TMS70C40; +extern const device_type TMS70C46; extern const device_type TMS7001; extern const device_type TMS7041; extern const device_type TMS7002; diff --git a/src/mess/drivers/cc40.c b/src/mess/drivers/cc40.c index 6255d1728ec..dbf357529c5 100644 --- a/src/mess/drivers/cc40.c +++ b/src/mess/drivers/cc40.c @@ -2,6 +2,8 @@ // copyright-holders:hap /*************************************************************************** + Texas Instruments Compact Computer 40 (aka CC-40) + --------------------------------------------- | --------------------------------------- | | | | | @@ -43,8 +45,20 @@ * - indicates that it's on the other side of the PCB + + CC-40 is powered by 4 AA batteries. These will also save internal RAM, + provided that the machine is turned off properly. If a program is running, + you may have to press BREAK before turning the CC-40 off. + + To run a cartridge that doesn't automatically boot, use the command + run"dir" to see which program(s) can be loaded. Load a program with + run"" + TODO: + - some strange bugs with cartridge software, maybe TMS7000 bug? + - other RAM configurations (6KB(default), 12KB, 18KB, external) + - Hexbus interface and peripherals - HD44100 is not accessed by the CPU, is it connected to the HD44780? Probably responsible for the LCD indicators, how? @@ -54,6 +68,8 @@ #include "cpu/tms7000/tms7000.h" #include "video/hd44780.h" #include "sound/dac.h" +#include "machine/nvram.h" +#include "imagedev/cartslot.h" #include "cc40.lh" @@ -73,7 +89,6 @@ public: ioport_port *m_key_matrix[8]; UINT8 m_power; - UINT8 m_bus_control; UINT8 m_banks; UINT8 m_clock_control; UINT8 m_key_select; @@ -81,7 +96,6 @@ public: void update_lcd_indicator(UINT8 y, UINT8 x, int state); DECLARE_READ8_MEMBER(bus_control_r); - DECLARE_WRITE8_MEMBER(bus_control_w); DECLARE_WRITE8_MEMBER(power_w); DECLARE_WRITE8_MEMBER(sound_w); DECLARE_READ8_MEMBER(battery_r); @@ -95,9 +109,49 @@ public: virtual void machine_reset(); virtual void machine_start(); DECLARE_PALETTE_INIT(cc40); + DECLARE_DEVICE_IMAGE_LOAD_MEMBER(cc40_cartridge); }; +/*************************************************************************** + + File Handling + +***************************************************************************/ + +DEVICE_IMAGE_LOAD_MEMBER(cc40_state, cc40_cartridge) +{ + UINT8* pos = memregion("user1")->base(); + offs_t size; + + if (image.software_entry() == NULL) + size = image.length(); + else + size = image.get_software_region_length("rom"); + + // max size is 4*32KB + if (size >= 0x20000) + { + image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid file size"); + return IMAGE_INIT_FAIL; + } + + if (image.software_entry() == NULL) + { + if (image.fread(pos, size) != size) + { + image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unable to fully read file"); + return IMAGE_INIT_FAIL; + } + } + else + memcpy(pos, image.get_software_region("rom"), size); + + return IMAGE_INIT_PASS; +} + + + /*************************************************************************** Video @@ -112,7 +166,13 @@ PALETTE_INIT_MEMBER(cc40_state, cc40) void cc40_state::update_lcd_indicator(UINT8 y, UINT8 x, int state) { - ; + // reference _________________... + // output# |10 11 12 13 14 0 1 2 3 4 + // above | < SHIFT CTL FN DEG RAD GRAD I/O UCL > + // ---- raw lcd screen here ---- + // under | ERROR v v v v v v _LOW + // output# | 60 61 62 63 50 51 52 53 + output_set_lamp_value(y * 10 + x, state); } static HD44780_PIXEL_UPDATE(cc40_pixel_update) @@ -126,7 +186,7 @@ static HD44780_PIXEL_UPDATE(cc40_pixel_update) else if (line < 2 && pos < 16) { // internal: 2*16, external: 1*31 + indicators - bitmap.pix16(y, line*16*6 + pos*6 + x) = state; + bitmap.pix16(1 + y, 1 + line*16*6 + pos*6 + x) = state; } } @@ -140,12 +200,10 @@ static HD44780_PIXEL_UPDATE(cc40_pixel_update) READ8_MEMBER(cc40_state::bus_control_r) { - return m_bus_control; -} - -WRITE8_MEMBER(cc40_state::bus_control_w) -{ - m_bus_control = data; + // According to TI's official documentation, this register is set with predefined values + // describing system hardware configuration, but there doesn't seem to be any indication + // that it's used at all. + return 0x4c; } WRITE8_MEMBER(cc40_state::power_w) @@ -178,10 +236,11 @@ READ8_MEMBER(cc40_state::bankswitch_r) WRITE8_MEMBER(cc40_state::bankswitch_w) { // d0-d1: system rom bankswitch - membank("bank1")->set_entry(data & 3); - - // d1-d2: cartridge rom bankswitch + membank("sysbank")->set_entry(data & 3); + // d2-d3: cartridge rom bankswitch + membank("cartbank")->set_entry(data >> 2 & 3); + m_banks = data & 0x0f; } @@ -235,7 +294,7 @@ WRITE8_MEMBER(cc40_state::keyboard_w) static ADDRESS_MAP_START( main_map, AS_PROGRAM, 8, cc40_state ) ADDRESS_MAP_UNMAP_HIGH - AM_RANGE(0x0110, 0x0110) AM_READWRITE(bus_control_r, bus_control_w) + AM_RANGE(0x0110, 0x0110) AM_READ(bus_control_r) AM_RANGE(0x0111, 0x0111) AM_WRITE(power_w) AM_RANGE(0x0112, 0x0112) AM_NOP // hexbus data AM_RANGE(0x0113, 0x0113) AM_NOP // hexbus available @@ -246,10 +305,14 @@ static ADDRESS_MAP_START( main_map, AS_PROGRAM, 8, cc40_state ) AM_RANGE(0x011a, 0x011a) AM_READWRITE(clock_r, clock_w) AM_RANGE(0x011e, 0x011f) AM_DEVREADWRITE("hd44780", hd44780_device, read, write) - AM_RANGE(0x0800, 0x0fff) AM_RAM - AM_RANGE(0x1000, 0x17ff) AM_RAM - AM_RANGE(0x3000, 0x37ff) AM_RAM - AM_RANGE(0xd000, 0xefff) AM_ROMBANK("bank1") + AM_RANGE(0x0800, 0x0fff) AM_RAM AM_SHARE("nvram1") + AM_RANGE(0x1000, 0x17ff) AM_RAM AM_SHARE("nvram2") + AM_RANGE(0x3000, 0x37ff) AM_RAM AM_SHARE("nvram3") + + AM_RANGE(0x0000, 0x4fff) AM_UNMAP // cartridge rom is at $5000-$cfff - direct address, not relative + AM_RANGE(0x0000, 0xcfff) AM_MASK(0x7fff) AM_ROMBANK("cartbank") + + AM_RANGE(0xd000, 0xefff) AM_ROMBANK("sysbank") ADDRESS_MAP_END static ADDRESS_MAP_START( main_io_map, AS_IO, 8, cc40_state ) @@ -322,11 +385,11 @@ static INPUT_PORTS_START( cc40 ) PORT_START("IN5") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_CHAR('0') PORT_CHAR('\'') PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_DEL) PORT_CHAR(UCHAR_MAMEKEY(DEL)) PORT_NAME("CLR UCL") - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) PORT_NAME("Cursor Left DEL") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) PORT_NAME("Cursor Right INS") + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) PORT_NAME("Cursor Up PB") PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH_PAD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR(UCHAR_MAMEKEY(SLASH_PAD)) PORT_NAME("/") - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) PORT_NAME("Cursor Down") PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_9_PAD) PORT_CHAR('9') PORT_CHAR(')') PORT_START("IN6") @@ -351,6 +414,7 @@ static INPUT_PORTS_START( cc40 ) INPUT_PORTS_END + /*************************************************************************** Machine Config @@ -360,6 +424,9 @@ INPUT_PORTS_END void cc40_state::machine_reset() { m_power = 1; + + address_space &space = m_maincpu->space(AS_PROGRAM); + bankswitch_w(space, 0, 0); } void cc40_state::machine_start() @@ -368,20 +435,17 @@ void cc40_state::machine_start() for (int i = 0; i < 8; i++) m_key_matrix[i] = ioport(tags[i]); - UINT8 *ROM = memregion("maincpu")->base(); - membank("bank1")->configure_entries(0, 4, &ROM[0x10000], 0x2000); - membank("bank1")->set_entry(0); - + membank("sysbank")->configure_entries(0, 4, memregion("system")->base(), 0x2000); + membank("cartbank")->configure_entries(0, 4, memregion("user1")->base(), 0x8000); + // zerofill m_power = 0; - m_bus_control = 0; m_banks = 0; m_clock_control = 0; m_key_select = 0; // register for savestates save_item(NAME(m_power)); - save_item(NAME(m_bus_control)); save_item(NAME(m_banks)); save_item(NAME(m_clock_control)); save_item(NAME(m_key_select)); @@ -394,12 +458,16 @@ static MACHINE_CONFIG_START( cc40, cc40_state ) MCFG_CPU_PROGRAM_MAP(main_map) MCFG_CPU_IO_MAP(main_io_map) + MCFG_NVRAM_ADD_0FILL("nvram1") + MCFG_NVRAM_ADD_0FILL("nvram2") + MCFG_NVRAM_ADD_0FILL("nvram3") + /* video hardware */ MCFG_SCREEN_ADD("screen", LCD) - MCFG_SCREEN_REFRESH_RATE(60) + MCFG_SCREEN_REFRESH_RATE(60) // arbitrary MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) - MCFG_SCREEN_SIZE(6*31, 9*1) - MCFG_SCREEN_VISIBLE_AREA(0, 6*31-1, 0, 9*1-1) + MCFG_SCREEN_SIZE(6*31+1, 9*1+1) + MCFG_SCREEN_VISIBLE_AREA(0, 6*31, 0, 9*1) MCFG_DEFAULT_LAYOUT(layout_cc40) MCFG_SCREEN_UPDATE_DEVICE("hd44780", hd44780_device, screen_update) MCFG_SCREEN_PALETTE("palette") @@ -416,9 +484,18 @@ static MACHINE_CONFIG_START( cc40, cc40_state ) MCFG_DAC_ADD("dac") MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) + + /* cartridge */ + MCFG_CARTSLOT_ADD("cart") + MCFG_CARTSLOT_EXTENSION_LIST("256,bin,rom") + MCFG_CARTSLOT_NOT_MANDATORY + MCFG_CARTSLOT_LOAD(cc40_state, cc40_cartridge) + MCFG_CARTSLOT_INTERFACE("cc40_cart") + MCFG_SOFTWARE_LIST_ADD("cart_list", "cc40_cart") MACHINE_CONFIG_END + /*************************************************************************** Game drivers @@ -426,10 +503,14 @@ MACHINE_CONFIG_END ***************************************************************************/ ROM_START( cc40 ) - ROM_REGION( 0x18000, "maincpu", 0 ) - ROM_LOAD( "tms70c20.bin", 0xf800, 0x0800, CRC(a21bf6ab) SHA1(3da8435ecbee143e7fa149ee8e1c92949bade1d8) ) - ROM_LOAD( "cc40.bin", 0x10000, 0x8000, CRC(f5322fab) SHA1(1b5c4052a53654363c458f75eac7a27f0752def6) ) + ROM_REGION( 0x10000, "maincpu", 0 ) + ROM_LOAD( "tms70c20.bin", 0xf800, 0x0800, CRC(a21bf6ab) SHA1(3da8435ecbee143e7fa149ee8e1c92949bade1d8) ) // internal cpu rom + + ROM_REGION( 0x8000, "system", 0 ) + ROM_LOAD( "cc40.bin", 0x0000, 0x8000, CRC(f5322fab) SHA1(1b5c4052a53654363c458f75eac7a27f0752def6) ) // system rom, banked + + ROM_REGION( 0x20000, "user1", ROMREGION_ERASEFF ) // cartridge area, max 4*32KB ROM_END -COMP( 1983, cc40, 0, 0, cc40, cc40, driver_device, 0, "Texas Instruments", "Compact Computer 40", GAME_NOT_WORKING ) +COMP( 1983, cc40, 0, 0, cc40, cc40, driver_device, 0, "Texas Instruments", "Compact Computer 40", GAME_SUPPORTS_SAVE ) diff --git a/src/mess/layout/cc40.lay b/src/mess/layout/cc40.lay index 6dbec26d316..65aeac0462b 100644 --- a/src/mess/layout/cc40.lay +++ b/src/mess/layout/cc40.lay @@ -1,9 +1,228 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +