cc40 added lcd indicators, cartridge load, battery ram

This commit is contained in:
Michaël Banaan Ananas 2014-07-19 22:24:15 +00:00
parent 17a5ce8acc
commit a09e869c8b
4 changed files with 351 additions and 36 deletions

View File

@ -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<tms7040_device>;
const device_type TMS70C00 = &device_creator<tms70c00_device>;
const device_type TMS70C20 = &device_creator<tms70c20_device>;
const device_type TMS70C40 = &device_creator<tms70c40_device>;
const device_type TMS70C46 = &device_creator<tms70c46_device>;
const device_type TMS7001 = &device_creator<tms7001_device>;
const device_type TMS7041 = &device_creator<tms7041_device>;
const device_type TMS7002 = &device_creator<tms7002_device>;
@ -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__)
{

View File

@ -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;

View File

@ -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"<shortname of program in list>"
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 )

View File

@ -1,9 +1,228 @@
<?xml version="1.0"?>
<mamelayout version="2">
<element name="static_bg">
<rect><color red="0.5412" green="0.57255" blue="0.5804" /></rect>
</element>
<!-- define lcd indicators -->
<element name="ind_left" defstate="0">
<rect><color red="0.5412" green="0.57255" blue="0.5804" /></rect>
<text string="&lt;" align="1" state="0">
<color red="0.494" green="0.501" blue="0.522" />
</text>
<text string="&lt;" align="1" state="1">
<color red="0.361" green="0.325" blue="0.345" />
</text>
</element>
<element name="ind_right" defstate="0">
<rect><color red="0.5412" green="0.57255" blue="0.5804" /></rect>
<text string="&gt;" align="2" state="0">
<color red="0.494" green="0.501" blue="0.522" />
</text>
<text string="&gt;" align="2" state="1">
<color red="0.361" green="0.325" blue="0.345" />
</text>
</element>
<element name="ind_shift" defstate="0">
<rect><color red="0.5412" green="0.57255" blue="0.5804" /></rect>
<text string="SHIFT" state="0">
<color red="0.494" green="0.501" blue="0.522" />
</text>
<text string="SHIFT" state="1">
<color red="0.361" green="0.325" blue="0.345" />
</text>
</element>
<element name="ind_ctl" defstate="0">
<rect><color red="0.5412" green="0.57255" blue="0.5804" /></rect>
<text string="CTL" state="0">
<color red="0.494" green="0.501" blue="0.522" />
</text>
<text string="CTL" state="1">
<color red="0.361" green="0.325" blue="0.345" />
</text>
</element>
<element name="ind_fn" defstate="0">
<rect><color red="0.5412" green="0.57255" blue="0.5804" /></rect>
<text string="FN" state="0">
<color red="0.494" green="0.501" blue="0.522" />
</text>
<text string="FN" state="1">
<color red="0.361" green="0.325" blue="0.345" />
</text>
</element>
<element name="ind_deg" defstate="0">
<rect><color red="0.5412" green="0.57255" blue="0.5804" /></rect>
<text string="DEG" state="0">
<color red="0.494" green="0.501" blue="0.522" />
</text>
<text string="DEG" state="1">
<color red="0.361" green="0.325" blue="0.345" />
</text>
</element>
<element name="ind_rad" defstate="0">
<rect><color red="0.5412" green="0.57255" blue="0.5804" /></rect>
<text string="RAD" state="0">
<color red="0.494" green="0.501" blue="0.522" />
</text>
<text string="RAD" state="1">
<color red="0.361" green="0.325" blue="0.345" />
</text>
</element>
<element name="ind_grad" defstate="0">
<rect><color red="0.5412" green="0.57255" blue="0.5804" /></rect>
<text string="GRAD" state="0">
<color red="0.494" green="0.501" blue="0.522" />
</text>
<text string="GRAD" state="1">
<color red="0.361" green="0.325" blue="0.345" />
</text>
</element>
<element name="ind_io" defstate="0">
<rect><color red="0.5412" green="0.57255" blue="0.5804" /></rect>
<text string="I/O" state="0">
<color red="0.494" green="0.501" blue="0.522" />
</text>
<text string="I/O" state="1">
<color red="0.361" green="0.325" blue="0.345" />
</text>
</element>
<element name="ind_ucl" defstate="0">
<rect><color red="0.5412" green="0.57255" blue="0.5804" /></rect>
<text string="UCL" state="0">
<color red="0.494" green="0.501" blue="0.522" />
</text>
<text string="UCL" state="1">
<color red="0.361" green="0.325" blue="0.345" />
</text>
</element>
<element name="ind_error" defstate="0">
<rect><color red="0.5412" green="0.57255" blue="0.5804" /></rect>
<text string="ERROR" state="0">
<color red="0.494" green="0.501" blue="0.522" />
</text>
<text string="ERROR" state="1">
<color red="0.361" green="0.325" blue="0.345" />
</text>
</element>
<element name="ind_user" defstate="0">
<rect><color red="0.5412" green="0.57255" blue="0.5804" /></rect>
<text string="v" state="0">
<color red="0.494" green="0.501" blue="0.522" />
</text>
<text string="v" state="1">
<color red="0.361" green="0.325" blue="0.345" />
</text>
</element>
<element name="ind_low" defstate="0">
<rect state="0"><color red="0.494" green="0.501" blue="0.522" /></rect>
<rect state="1"><color red="0.361" green="0.325" blue="0.345" /></rect>
<text string="LOW">
<color red="0.5412" green="0.57255" blue="0.5804" />
</text>
</element>
<view name="Internal Layout">
<bounds left="0" top="0" right="189" bottom="32" />
<screen index="0">
<bounds left="0" top="0" right="1488" bottom="72" />
<bounds x="1" y="11" width="187" height="10" />
</screen>
<!-- draw background around lcd screen matrix part -->
<bezel element="static_bg">
<bounds left="0" top="0" right="188" bottom="11.25" />
</bezel>
<bezel element="static_bg">
<bounds left="0" top="0" right="1.25" bottom="32" />
</bezel>
<bezel element="static_bg">
<bounds left="187.75" top="0" right="189" bottom="32" />
</bezel>
<bezel element="static_bg">
<bounds left="0" top="20.75" right="188" bottom="32" />
</bezel>
<!-- draw top row of lcd indicators -->
<bezel name="lamp10" element="ind_left">
<bounds x="1.5" y="1" width="20" height="5" />
</bezel>
<bezel name="lamp4" element="ind_right">
<bounds x="167.5" y="1" width="20" height="5" />
</bezel>
<bezel name="lamp11" element="ind_shift">
<bounds x="7" y="3" width="20" height="5" />
</bezel>
<bezel name="lamp12" element="ind_ctl">
<bounds x="29" y="3" width="20" height="5" />
</bezel>
<bezel name="lamp13" element="ind_fn">
<bounds x="51" y="3" width="20" height="5" />
</bezel>
<bezel name="lamp14" element="ind_deg">
<bounds x="73" y="3" width="20" height="5" />
</bezel>
<bezel name="lamp0" element="ind_rad">
<bounds x="95" y="3" width="20" height="5" />
</bezel>
<bezel name="lamp1" element="ind_grad">
<bounds x="117" y="3" width="20" height="5" />
</bezel>
<bezel name="lamp2" element="ind_io">
<bounds x="139" y="3" width="20" height="5" />
</bezel>
<bezel name="lamp3" element="ind_ucl">
<bounds x="161" y="3" width="20" height="5" />
</bezel>
<!-- draw bottom row of lcd indicators -->
<bezel name="lamp60" element="ind_error">
<bounds x="7" y="24" width="20" height="5" />
</bezel>
<bezel name="lamp61" element="ind_user">
<bounds x="29" y="26" width="20" height="5" />
</bezel>
<bezel name="lamp62" element="ind_user">
<bounds x="51" y="26" width="20" height="5" />
</bezel>
<bezel name="lamp63" element="ind_user">
<bounds x="73" y="26" width="20" height="5" />
</bezel>
<bezel name="lamp50" element="ind_user">
<bounds x="95" y="26" width="20" height="5" />
</bezel>
<bezel name="lamp51" element="ind_user">
<bounds x="117" y="26" width="20" height="5" />
</bezel>
<bezel name="lamp52" element="ind_user">
<bounds x="139" y="26" width="20" height="5" />
</bezel>
<bezel name="lamp53" element="ind_low">
<bounds x="165" y="25.5" width="12" height="5" />
</bezel>
</view>
</mamelayout>