mirror of
https://github.com/holub/mame
synced 2025-04-22 16:31:49 +03:00
smc1102: add opcode placeholders and microinstructions
This commit is contained in:
parent
96789c582b
commit
962f44a5fa
@ -7,7 +7,7 @@
|
||||
SMC1102 is a CMOS MCU based on TMS1100, keeping the same ALU and opcode mnemonics.
|
||||
They added a timer, interrupts, and a built-in LCD controller.
|
||||
|
||||
In the USA, it was marketed by S-MOS Systems, an affiliate of the Seiko Group.
|
||||
In the USA, it was marketed by S-MOS Systems, an affiliate of Seiko Group.
|
||||
|
||||
SMC1112 die notes (SMC1102 is assumed to be the same):
|
||||
- 128x4 RAM array at top-left
|
||||
@ -18,7 +18,10 @@ SMC1112 die notes (SMC1102 is assumed to be the same):
|
||||
- no output PLA
|
||||
|
||||
TODO:
|
||||
- x
|
||||
- row(pc) order is unknown
|
||||
- each opcode is 4 cycles instead of 6
|
||||
- does it have CL (call latch)
|
||||
- everything else
|
||||
|
||||
*/
|
||||
|
||||
@ -60,10 +63,111 @@ void smc1102_cpu_device::device_start()
|
||||
|
||||
u32 smc1102_cpu_device::decode_micro(offs_t offset)
|
||||
{
|
||||
return 0;
|
||||
// TCY, YNEC, TCMIY
|
||||
static const u16 micro1[3] = { 0x0402, 0x1204, 0x1032 };
|
||||
|
||||
// 0x20, 0x30, 0x00, 0x70
|
||||
static const u16 micro2[0x40] =
|
||||
{
|
||||
0x0102, 0x0801, 0x0802, 0x1001, 0x306a, 0x303a, 0x2021, 0x2020,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0e04, 0x0e04, 0x0e04, 0x0e04, 0x0899, 0x0099, 0x0819, 0x0804,
|
||||
|
||||
0x0904, 0x0898, 0x1104, 0x2821, 0x104a, 0x101a, 0x0909, 0x0849,
|
||||
0x0401, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0404, 0x0000,
|
||||
|
||||
0x0519, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0519,
|
||||
0x0000, 0x0519, 0x0519, 0x0000, 0x0000, 0x0000, 0x0519, 0x0419,
|
||||
};
|
||||
|
||||
u16 mask = 0;
|
||||
|
||||
if (offset >= 0x40 && offset < 0x70)
|
||||
mask = micro1[offset >> 4 & 3];
|
||||
else if (offset < 0x80 && (offset & 0xf0) != 0x10)
|
||||
mask = micro2[((offset ^ 0x20) | (offset >> 1 & 0x20)) & 0x3f];
|
||||
|
||||
// does not have M_MTN or M_STSL
|
||||
const u32 md[14] = { M_AUTA, M_AUTY, M_NE, M_C8, M_CIN, M_CKM, M_15TN, M_NATN, M_ATN, M_CKN, M_CKP, M_MTP, M_YTP, M_STO };
|
||||
u32 decode = 0;
|
||||
|
||||
for (int bit = 0; bit < 14; bit++)
|
||||
if (mask & (1 << bit))
|
||||
decode |= md[bit];
|
||||
|
||||
return decode;
|
||||
}
|
||||
|
||||
void smc1102_cpu_device::device_reset()
|
||||
{
|
||||
tms1100_cpu_device::device_reset();
|
||||
|
||||
// changed/added fixed instructions (mostly handled in op_extra)
|
||||
m_fixed_decode[0x0a] = F_EXTRA;
|
||||
m_fixed_decode[0x71] = F_EXTRA;
|
||||
m_fixed_decode[0x74] = F_EXTRA;
|
||||
m_fixed_decode[0x75] = F_EXTRA;
|
||||
m_fixed_decode[0x76] = F_RETN;
|
||||
m_fixed_decode[0x78] = F_EXTRA;
|
||||
m_fixed_decode[0x7b] = F_EXTRA;
|
||||
|
||||
m_fixed_decode[0x72] = m_fixed_decode[0x73] = F_EXTRA;
|
||||
m_fixed_decode[0x7c] = m_fixed_decode[0x7d] = F_EXTRA;
|
||||
}
|
||||
|
||||
|
||||
// opcode deviations
|
||||
void smc1102_cpu_device::op_tasr()
|
||||
{
|
||||
// TASR: transfer A to LCD S/R
|
||||
}
|
||||
|
||||
void smc1102_cpu_device::op_tsg()
|
||||
{
|
||||
// TSG: transfer LCD S/R to RAM
|
||||
}
|
||||
|
||||
void smc1102_cpu_device::op_intdis()
|
||||
{
|
||||
// INTDIS: disable interrupt
|
||||
}
|
||||
|
||||
void smc1102_cpu_device::op_inten()
|
||||
{
|
||||
// INTEN: enable interrupt after next instruction
|
||||
}
|
||||
|
||||
void smc1102_cpu_device::op_selin()
|
||||
{
|
||||
// SELIN: select interrupt
|
||||
}
|
||||
|
||||
void smc1102_cpu_device::op_tmset()
|
||||
{
|
||||
// TMSET: transfer A to timer latch
|
||||
}
|
||||
|
||||
void smc1102_cpu_device::op_halt()
|
||||
{
|
||||
// HALT: stop CPU
|
||||
}
|
||||
|
||||
void smc1102_cpu_device::op_extra()
|
||||
{
|
||||
switch (m_opcode)
|
||||
{
|
||||
case 0x0a: op_tasr(); break;
|
||||
case 0x71: op_halt(); break;
|
||||
case 0x74: op_inten(); break;
|
||||
case 0x75: op_intdis(); break;
|
||||
case 0x78: op_selin(); break;
|
||||
case 0x7b: op_tmset(); break;
|
||||
|
||||
case 0x72: case 0x73: case 0x7c: case 0x7d:
|
||||
op_tsg(); break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
@ -53,6 +53,20 @@ protected:
|
||||
virtual u32 decode_micro(offs_t offset) override;
|
||||
|
||||
virtual void write_o_reg(u8 index) override { } // no O pins
|
||||
|
||||
virtual void op_setr() override { tms1k_base_device::op_setr(); } // no anomaly with MSB of X register
|
||||
virtual void op_rstr() override { tms1k_base_device::op_rstr(); } // "
|
||||
|
||||
virtual void op_extra() override;
|
||||
|
||||
private:
|
||||
void op_halt();
|
||||
void op_intdis();
|
||||
void op_inten();
|
||||
void op_selin();
|
||||
void op_tasr();
|
||||
void op_tmset();
|
||||
void op_tsg();
|
||||
};
|
||||
|
||||
class smc1112_cpu_device : public smc1102_cpu_device
|
||||
|
@ -696,10 +696,12 @@ void tms1k_base_device::execute_one()
|
||||
if (m_fixed & F_LDP) op_ldp();
|
||||
if (m_fixed & F_COMC) op_comc();
|
||||
if (m_fixed & F_TPC) op_tpc();
|
||||
|
||||
if (m_fixed & F_TAX) op_tax();
|
||||
if (m_fixed & F_TAC) op_tac();
|
||||
if (m_fixed & F_TADM) op_tadm();
|
||||
if (m_fixed & F_TMA) op_tma();
|
||||
|
||||
if (m_fixed & F_OFF) op_off();
|
||||
if (m_fixed & F_SEAC) op_seac();
|
||||
if (m_fixed & F_REAC) op_reac();
|
||||
@ -707,6 +709,8 @@ void tms1k_base_device::execute_one()
|
||||
if (m_fixed & F_SBL) op_sbl();
|
||||
if (m_fixed & F_XDA) op_xda();
|
||||
|
||||
if (m_fixed & F_EXTRA) op_extra();
|
||||
|
||||
// after fixed opcode handling: store status, write ram
|
||||
m_status = status;
|
||||
if (m_ram_out != -1)
|
||||
|
@ -73,67 +73,69 @@ protected:
|
||||
// microinstructions
|
||||
enum
|
||||
{
|
||||
M_15TN = (1U << 0), // 15 to -ALU
|
||||
M_ATN = (1U << 1), // ACC to -ALU
|
||||
M_AUTA = (1U << 2), // ALU to ACC
|
||||
M_AUTY = (1U << 3), // ALU to Y
|
||||
M_C8 = (1U << 4), // CARRY8 to STATUS
|
||||
M_CIN = (1U << 5), // Carry In to ALU
|
||||
M_CKM = (1U << 6), // CKB to MEM
|
||||
M_CKN = (1U << 7), // CKB to -ALU
|
||||
M_CKP = (1U << 8), // CKB to +ALU
|
||||
M_MTN = (1U << 9), // MEM to -ALU
|
||||
M_MTP = (1U << 10), // MEM to +ALU
|
||||
M_NATN = (1U << 11), // ~ACC to -ALU
|
||||
M_NE = (1U << 12), // COMP to STATUS
|
||||
M_STO = (1U << 13), // ACC to MEM
|
||||
M_STSL = (1U << 14), // STATUS to Status Latch
|
||||
M_YTP = (1U << 15), // Y to +ALU
|
||||
M_15TN = (1U << 0), // 15 to -ALU
|
||||
M_ATN = (1U << 1), // ACC to -ALU
|
||||
M_AUTA = (1U << 2), // ALU to ACC
|
||||
M_AUTY = (1U << 3), // ALU to Y
|
||||
M_C8 = (1U << 4), // CARRY8 to STATUS
|
||||
M_CIN = (1U << 5), // Carry In to ALU
|
||||
M_CKM = (1U << 6), // CKB to MEM
|
||||
M_CKN = (1U << 7), // CKB to -ALU
|
||||
M_CKP = (1U << 8), // CKB to +ALU
|
||||
M_MTN = (1U << 9), // MEM to -ALU
|
||||
M_MTP = (1U << 10), // MEM to +ALU
|
||||
M_NATN = (1U << 11), // ~ACC to -ALU
|
||||
M_NE = (1U << 12), // COMP to STATUS
|
||||
M_STO = (1U << 13), // ACC to MEM
|
||||
M_STSL = (1U << 14), // STATUS to Status Latch
|
||||
M_YTP = (1U << 15), // Y to +ALU
|
||||
|
||||
M_CME = (1U << 16), // Conditional Memory Enable
|
||||
M_DMTP = (1U << 17), // DAM to +ALU
|
||||
M_NDMTP = (1U << 18), // ~DAM to +ALU
|
||||
M_SSE = (1U << 19), // Special Status Enable
|
||||
M_SSS = (1U << 20), // Special Status Sample
|
||||
M_CME = (1U << 16), // Conditional Memory Enable
|
||||
M_DMTP = (1U << 17), // DAM to +ALU
|
||||
M_NDMTP = (1U << 18), // ~DAM to +ALU
|
||||
M_SSE = (1U << 19), // Special Status Enable
|
||||
M_SSS = (1U << 20), // Special Status Sample
|
||||
|
||||
M_SETR = (1U << 21), // -> line #0d, F_SETR (TP0320 custom)
|
||||
M_RSTR = (1U << 22), // -> line #36, F_RSTR (TMS02x0 custom)
|
||||
M_UNK1 = (1U << 23) // -> line #37, F_???? (TMS0270 custom)
|
||||
M_SETR = (1U << 21), // -> line #0d, F_SETR (TP0320 custom)
|
||||
M_RSTR = (1U << 22), // -> line #36, F_RSTR (TMS02x0 custom)
|
||||
M_UNK1 = (1U << 23) // -> line #37, F_???? (TMS0270 custom)
|
||||
};
|
||||
|
||||
// standard/fixed instructions - these are documented more in their specific handlers
|
||||
enum
|
||||
{
|
||||
F_BR = (1ULL << 0),
|
||||
F_CALL = (1ULL << 1),
|
||||
F_CLO = (1ULL << 2),
|
||||
F_COMC = (1ULL << 3),
|
||||
F_COMX = (1ULL << 4),
|
||||
F_COMX8 = (1ULL << 5),
|
||||
F_LDP = (1ULL << 6),
|
||||
F_LDX = (1ULL << 7),
|
||||
F_RBIT = (1ULL << 8),
|
||||
F_RETN = (1ULL << 9),
|
||||
F_RSTR = (1ULL << 10),
|
||||
F_SBIT = (1ULL << 11),
|
||||
F_SETR = (1ULL << 12),
|
||||
F_TDO = (1ULL << 13),
|
||||
F_TPC = (1ULL << 14),
|
||||
F_BR = (1ULL << 0),
|
||||
F_CALL = (1ULL << 1),
|
||||
F_CLO = (1ULL << 2),
|
||||
F_COMC = (1ULL << 3),
|
||||
F_COMX = (1ULL << 4),
|
||||
F_COMX8 = (1ULL << 5),
|
||||
F_LDP = (1ULL << 6),
|
||||
F_LDX = (1ULL << 7),
|
||||
F_RBIT = (1ULL << 8),
|
||||
F_RETN = (1ULL << 9),
|
||||
F_RSTR = (1ULL << 10),
|
||||
F_SBIT = (1ULL << 11),
|
||||
F_SETR = (1ULL << 12),
|
||||
F_TDO = (1ULL << 13),
|
||||
F_TPC = (1ULL << 14),
|
||||
|
||||
F_TAX = (1ULL << 15),
|
||||
F_TXA = (1ULL << 16),
|
||||
F_TRA = (1ULL << 17),
|
||||
F_TAC = (1ULL << 18),
|
||||
F_TCA = (1ULL << 19),
|
||||
F_TADM = (1ULL << 20),
|
||||
F_TMA = (1ULL << 21),
|
||||
F_TAX = (1ULL << 15),
|
||||
F_TXA = (1ULL << 16),
|
||||
F_TRA = (1ULL << 17),
|
||||
F_TAC = (1ULL << 18),
|
||||
F_TCA = (1ULL << 19),
|
||||
F_TADM = (1ULL << 20),
|
||||
F_TMA = (1ULL << 21),
|
||||
|
||||
F_OFF = (1ULL << 22),
|
||||
F_REAC = (1ULL << 23),
|
||||
F_SAL = (1ULL << 24),
|
||||
F_SBL = (1ULL << 25),
|
||||
F_SEAC = (1ULL << 26),
|
||||
F_XDA = (1ULL << 27)
|
||||
F_OFF = (1ULL << 22),
|
||||
F_REAC = (1ULL << 23),
|
||||
F_SAL = (1ULL << 24),
|
||||
F_SBL = (1ULL << 25),
|
||||
F_SEAC = (1ULL << 26),
|
||||
F_XDA = (1ULL << 27),
|
||||
|
||||
F_EXTRA = (1ULL << 28), // custom opcodes
|
||||
};
|
||||
|
||||
void rom_10bit(address_map &map);
|
||||
@ -152,6 +154,7 @@ protected:
|
||||
virtual void set_cki_bus();
|
||||
virtual void dynamic_output() { } // not used by default
|
||||
virtual void read_opcode();
|
||||
virtual void op_extra() { }
|
||||
|
||||
virtual void op_br();
|
||||
virtual void op_call();
|
||||
|
@ -40,13 +40,13 @@ tms1000_base_disassembler::tms1000_base_disassembler(const u8 *lut_mnemonic, boo
|
||||
}
|
||||
}
|
||||
|
||||
tms1000_disassembler::tms1000_disassembler() : tms1000_base_disassembler(tms1000_mnemonic, false, 6)
|
||||
{ }
|
||||
|
||||
tms1100_disassembler::tms1100_disassembler(const u8 *lut_mnemonic, bool opcode_9bits, int pc_bits) :
|
||||
tms1000_base_disassembler(lut_mnemonic, opcode_9bits, pc_bits)
|
||||
{ }
|
||||
|
||||
tms1000_disassembler::tms1000_disassembler() : tms1000_base_disassembler(tms1000_mnemonic, false, 6)
|
||||
{ }
|
||||
|
||||
tms1100_disassembler::tms1100_disassembler() : tms1100_disassembler(tms1100_mnemonic, false, 6)
|
||||
{ }
|
||||
|
||||
|
@ -1,16 +1,28 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:hap
|
||||
/******************************************************************************
|
||||
/*******************************************************************************
|
||||
|
||||
Coleco Talking Wrinkles, a plushie dog handpuppet toy
|
||||
Talking Wrinkles, a plushie dog handpuppet toy
|
||||
|
||||
Hardware is a P80C31BH @ 11MHz and a 32KB ROM, RAM is in the MCU.
|
||||
It also has a cartridge slot, but no known cartridges were released.
|
||||
The speech technology is by Electronic Speech Systems.
|
||||
Published by Lakeside (a Coleco subsidiary at that time, after Coleco purchased
|
||||
Leisure Dynamics in 1985). Programming by Steve Beck. The speech technology is
|
||||
by Electronic Speech Systems. The plushie itself is licensed from Ganz Bros.
|
||||
|
||||
Hardware notes:
|
||||
|
||||
PCB 1:
|
||||
- PCB label: REV 4.1 DIGITAL, 201239C, (C) COLECO 1986
|
||||
- P80C31BH, 11MHz XTAL
|
||||
- 32KB EPROM
|
||||
- cartridge slot (no known cartridges were released)
|
||||
|
||||
PCB 2:
|
||||
- PCB label: ANALOG REV 6.2, 201238D, (C) COLECO 1986
|
||||
- button, motion sensor, microphone
|
||||
|
||||
Known sensors:
|
||||
- 0x02: bellybutton, literally a button
|
||||
- 0x04: detect violent motion (Wrinkles will cry)
|
||||
- 0x04: detect violent motion (drop Wrinkles and he will cry)
|
||||
- 0x10: detect light motion
|
||||
- 0x40: detect open mouth (use as handpuppet to make it 'talk')
|
||||
- 0x80: detect magnet in mouth (the toy came with a 'bone' that has a magnet in it)
|
||||
@ -19,7 +31,7 @@ TODO:
|
||||
- where is the microphone? or are they the same inputs as the motion sensors?
|
||||
- power-on by pressing button
|
||||
|
||||
******************************************************************************/
|
||||
*******************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
@ -49,9 +61,9 @@ private:
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
/*******************************************************************************
|
||||
Address Maps
|
||||
******************************************************************************/
|
||||
*******************************************************************************/
|
||||
|
||||
void wrinkles_state::main_map(address_map &map)
|
||||
{
|
||||
@ -61,15 +73,15 @@ void wrinkles_state::main_map(address_map &map)
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
/*******************************************************************************
|
||||
Input Ports
|
||||
******************************************************************************/
|
||||
*******************************************************************************/
|
||||
|
||||
static INPUT_PORTS_START( wrinkles )
|
||||
PORT_START("INPUTS")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_1) PORT_NAME("Tickle Button")
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CODE(KEYCODE_5) PORT_NAME("Shake Sensor")
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CODE(KEYCODE_5) PORT_NAME("Impact Sensor")
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CODE(KEYCODE_4) PORT_NAME("Motion Sensor")
|
||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNKNOWN )
|
||||
@ -79,28 +91,28 @@ INPUT_PORTS_END
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
/*******************************************************************************
|
||||
Machine Configs
|
||||
******************************************************************************/
|
||||
*******************************************************************************/
|
||||
|
||||
void wrinkles_state::wrinkles(machine_config &config)
|
||||
{
|
||||
/* basic machine hardware */
|
||||
// basic machine hardware
|
||||
I80C31(config, m_maincpu, 11_MHz_XTAL);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &wrinkles_state::main_map);
|
||||
m_maincpu->port_in_cb<1>().set_ioport("INPUTS");
|
||||
m_maincpu->port_out_cb<3>().set("dac", FUNC(dac_8bit_r2r_device::write));
|
||||
|
||||
/* sound hardware */
|
||||
// sound hardware
|
||||
SPEAKER(config, "speaker").front_center();
|
||||
DAC_8BIT_R2R(config, "dac").add_route(ALL_OUTPUTS, "speaker", 0.5);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
/*******************************************************************************
|
||||
ROM Definitions
|
||||
******************************************************************************/
|
||||
*******************************************************************************/
|
||||
|
||||
ROM_START( wrinkles )
|
||||
ROM_REGION( 0x8000, "maincpu", 0 )
|
||||
@ -111,9 +123,9 @@ ROM_END
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
/*******************************************************************************
|
||||
Drivers
|
||||
******************************************************************************/
|
||||
*******************************************************************************/
|
||||
|
||||
// YEAR NAME PARENT CMP MACHINE INPUT CLASS INIT COMPANY, FULLNAME, FLAGS
|
||||
CONS( 1986, wrinkles, 0, 0, wrinkles, wrinkles, wrinkles_state, empty_init, "Coleco / Ganz", "Talking Wrinkles", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_CONTROLS | MACHINE_NOT_WORKING )
|
||||
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY, FULLNAME, FLAGS
|
||||
CONS( 1986, wrinkles, 0, 0, wrinkles, wrinkles, wrinkles_state, empty_init, "Lakeside / Coleco / Ganz Bros", "Talking Wrinkles", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_CONTROLS | MACHINE_NOT_WORKING )
|
||||
|
@ -173,6 +173,7 @@ on Joerg Woerner's datamath.org: http://www.datamath.org/IC_List.htm
|
||||
*M34014 TMS1100 1981, Coleco Bowlatronic
|
||||
M34017 TMS1100 1981, Microvision cartridge: Cosmic Hunter
|
||||
@M34018 TMS1100 1981, Coleco Head to Head: Electronic Boxing
|
||||
*M34033 TMS1100 1982, Spartus Electronic Talking Clock (1411-61)
|
||||
@M34038 TMS1100 1982, Parker Brothers Lost Treasure
|
||||
M34047 TMS1100 1982, Microvision cartridge: Super Blockbuster
|
||||
@M34078A TMS1100 1983, Milton Bradley Electronic Arcade Mania
|
||||
|
@ -160,7 +160,7 @@ u32 microvision_state::tms1100_micro_pla(offs_t offset)
|
||||
// default TMS1100 microinstructions PLA - this should work for all games
|
||||
// verified for: blckbstr, bowling, pinball, vegasslt
|
||||
|
||||
// TCY, YNEC, TMCIY, AxAAC
|
||||
// TCY, YNEC, TCMIY, AxAAC
|
||||
static const u16 micro1[4] = { 0x0108, 0x9080, 0x8068, 0x0136 };
|
||||
|
||||
// 0x20, 0x30, 0x00
|
||||
|
Loading…
Reference in New Issue
Block a user