Permalink
Browse files

Merge remote-tracking branch 'upstream/master'

  • Loading branch information...
2 parents a895b99 + 142e2e6 commit 44585d21ca812b6d27088d43ea2eb87baf789bb0 @Robbbert committed Jan 7, 2017
@@ -1895,6 +1895,7 @@ files {
createMESSProjects(_target, _subtarget, "force")
files {
+ MAME_DIR .. "src/mame/drivers/miniforce.cpp",
MAME_DIR .. "src/mame/drivers/fccpu20.cpp",
MAME_DIR .. "src/mame/drivers/fccpu30.cpp",
MAME_DIR .. "src/mame/drivers/force68k.cpp",
@@ -5,14 +5,32 @@
*
* pps4.c
*
- * Rockwell PPS-4 CPU
- * Introduced in 1972, it ran at 256kHz. An improved version was released
- * in 1975, but could only manage 200kHz. The chipset continued to be
- * produced through the 1980s, but never found much acceptance. Chip
- * numbers are 10660 (original), 11660, 12660.
+ * Rockwell Parallel Processing System (PPS-4) Microcomputer
+ *
+ * Introduced in 1972, the PPS-4 was a 4-bit PMOS CPU that ran at 256kHz.
+ * The improved PPS-4/2, released in 1975, doubled the width of discrete
+ * output and added an internal clock generator (intended for use with a
+ * 3.579545MHz NTSC XTAL), but the latter could only manage 200kHz. The
+ * chipset later evolved into the PPS-4/1 (MM76, MM78, etc.) series of
+ * MCUs which Rockwell continued to produce through the early 1980s.
+ *
+ * Part numbers are 10660 (original), 11660 (PPS-4/2), 12660.
+ *
+ * List of memory chips:
+ * 10432 RAM (256 x 4)
+ * 10932 RAM (512 x 4)
+ * A05XX ROM (1K x 8)
+ * A52XX ROM (2K x 8)
+ * A66XX ROM (4K x 8)
+ * A88XX ROM (8K x 8)
+ * A08XX ROM/RAM (704 x 8/72 x 4)
+ * A07XX ROM/RAM (1K x 8/116 x 4)
+ * A20XX ROM/RAM (1.5K x 8/128 x 4)
+ * A17XX ROM/RAM + I/O (2K x 8/128 x 4/16 x 1)
+ * A23XX ROM/RAM + I/O (1K x 8/128 x 4/16 x 1)
*
* List of support / peripheral chips:
- * 10706 Clock generator
+ * 10706 4-phase clock generator
* 10738 Bus interface
* 11049 Interval timer
* 10686 General purpose I/O
@@ -24,8 +42,10 @@
* 10815 keyboard/printer controller
* 10930 Serial data controller
* 15380 dot matrix printer controller
+ * 11696 Parallel input/output
*
- * Note: External clock should be divided by 18 (not implemented).
+ * All of the above devices, except those providing 4-bit RAM, were also
+ * compatible with the failed PPS-8 series of 8-bit PMOS CPUs.
*
* Pinouts:
* 10660 11660
@@ -55,6 +75,7 @@
* +--------------------+ +--------------------+
*
*****************************************************************************/
+
#include "emu.h"
#include "debugger.h"
#include "pps4.h"
@@ -69,22 +90,36 @@
#endif
const device_type PPS4 = &device_creator<pps4_device>;
+const device_type PPS4_2 = &device_creator<pps4_2_device>;
-pps4_device::pps4_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : cpu_device(mconfig, PPS4, "PPS4", tag, owner, clock, "pps4", __FILE__ )
+pps4_device::pps4_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, u32 clock, const char *shortname, const char *file)
+ : cpu_device(mconfig, type, name, tag, owner, clock, shortname, file)
, m_program_config("program", ENDIANNESS_LITTLE, 8, 12)
, m_data_config("data", ENDIANNESS_LITTLE, 8, 12) // 4bit RAM
- , m_io_config("io", ENDIANNESS_LITTLE, 8, 8+1) // 4bit IO
+ , m_io_config("io", ENDIANNESS_LITTLE, 8, 8) // 4bit IO
+ , m_dia_cb(*this)
+ , m_dib_cb(*this)
+ , m_do_cb(*this)
+{
+}
+
+pps4_device::pps4_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : pps4_device(mconfig, PPS4, "PPS-4", tag, owner, clock, "pps4", __FILE__)
+{
+}
+
+pps4_2_device::pps4_2_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : pps4_device(mconfig, PPS4_2, "PPS-4/2", tag, owner, clock, "pps4_2", __FILE__)
{
}
/**
* @brief pps4_device::M Return the memory at address B
* @return ROM/RAM(B)
*/
-uint8_t pps4_device::M()
+u8 pps4_device::M()
{
- uint8_t ret = m_data->read_byte(m_B & ~m_SAG);
+ u8 ret = m_data->read_byte(m_B & ~m_SAG);
m_SAG = 0;
return ret;
}
@@ -94,13 +129,13 @@ uint8_t pps4_device::M()
* @brief pps4_device::W Write to the memory address at B
* @return ROM/RAM(B)
*/
-void pps4_device::W(uint8_t data)
+void pps4_device::W(u8 data)
{
m_data->write_byte(m_B & ~m_SAG, data);
m_SAG = 0;
}
-offs_t pps4_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options)
+offs_t pps4_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options)
{
extern CPU_DISASSEMBLE( pps4 );
return CPU_DISASSEMBLE_NAME(pps4)(this, stream, pc, oprom, opram, options);
@@ -113,9 +148,9 @@ offs_t pps4_device::disasm_disassemble(std::ostream &stream, offs_t pc, const ui
* program counter is incremented. The icount is decremented.
* @return m_I the next opcode
*/
-inline uint8_t pps4_device::ROP()
+inline u8 pps4_device::ROP()
{
- const uint8_t op = m_direct->read_byte(m_P & 0xFFF);
+ const u8 op = m_direct->read_byte(m_P & 0xFFF);
m_Ip = m_I1; // save previous opcode
m_P = (m_P + 1) & 0xFFF;
m_icount -= 1;
@@ -129,9 +164,9 @@ inline uint8_t pps4_device::ROP()
* icount is decremented.
* @return m_I2 the next argument
*/
-inline uint8_t pps4_device::ARG()
+inline u8 pps4_device::ARG()
{
- const uint8_t arg = m_direct->read_byte(m_P & 0xFFF);
+ const u8 arg = m_direct->read_byte(m_P & 0xFFF);
m_P = (m_P + 1) & 0xFFF;
m_icount -= 1;
return arg;
@@ -265,7 +300,7 @@ void pps4_device::iADCSK()
*/
void pps4_device::iADI()
{
- const uint8_t imm = ~m_I1 & 15;
+ const u8 imm = ~m_I1 & 15;
m_A = m_A + imm;
m_Skip = (m_A >> 4) & 1;
m_A = m_A & 15;
@@ -490,7 +525,7 @@ void pps4_device::iRF2()
*/
void pps4_device::iLD()
{
- const uint16_t i3c = ~m_I1 & 7;
+ const u16 i3c = ~m_I1 & 7;
m_A = M();
m_B = m_B ^ (i3c << 4);
}
@@ -513,8 +548,8 @@ void pps4_device::iLD()
*/
void pps4_device::iEX()
{
- const uint16_t i3c = ~m_I1 & 7;
- const uint8_t mem = M();
+ const u16 i3c = ~m_I1 & 7;
+ const u8 mem = M();
W(m_A);
m_A = mem;
m_B = m_B ^ (i3c << 4);
@@ -542,9 +577,9 @@ void pps4_device::iEX()
*/
void pps4_device::iEXD()
{
- const uint8_t i3c = ~m_I1 & 7;
- const uint8_t mem = M();
- uint8_t bl = m_B & 15;
+ const u8 i3c = ~m_I1 & 7;
+ const u8 mem = M();
+ u8 bl = m_B & 15;
W(m_A);
m_A = mem;
m_B = m_B ^ (i3c << 4);
@@ -696,7 +731,7 @@ void pps4_device::iLBUA()
void pps4_device::iXABL()
{
// swap A and BL
- uint8_t bl = m_B & 15;
+ u8 bl = m_B & 15;
m_B = (m_B & ~15) | m_A;
m_A = bl;
}
@@ -717,7 +752,7 @@ void pps4_device::iXABL()
void pps4_device::iXBMX()
{
// swap X and BM
- const uint8_t bm = (m_B >> 4) & 15;
+ const u8 bm = (m_B >> 4) & 15;
m_B = (m_B & ~(15 << 4)) | (m_X << 4);
m_X = bm;
}
@@ -786,7 +821,7 @@ void pps4_device::iXS()
*/
void pps4_device::iCYS()
{
- const uint16_t sa = (m_SA >> 4) | (m_A << 8);
+ const u16 sa = (m_SA >> 4) | (m_A << 8);
m_A = m_SA & 15;
m_SA = sa;
}
@@ -893,7 +928,7 @@ void pps4_device::iLBL()
*/
void pps4_device::iINCB()
{
- uint8_t bl = m_B & 15;
+ u8 bl = m_B & 15;
bl = (bl + 1) & 15;
if (0 == bl) {
LOG(("%s: skip BL=%x\n", __FUNCTION__, bl));
@@ -919,7 +954,7 @@ void pps4_device::iINCB()
*/
void pps4_device::iDECB()
{
- uint8_t bl = m_B & 15;
+ u8 bl = m_B & 15;
bl = (bl - 1) & 15;
if (15 == bl) {
LOG(("%s: skip BL=%x\n", __FUNCTION__, bl));
@@ -945,7 +980,7 @@ void pps4_device::iDECB()
*/
void pps4_device::iT()
{
- const uint16_t p = (m_P & ~63) | (m_I1 & 63);
+ const u16 p = (m_P & ~63) | (m_I1 & 63);
LOG(("%s: P=%03x I=%02x -> P=%03x\n", __FUNCTION__, m_P, m_I1, p));
m_P = p;
}
@@ -1084,8 +1119,8 @@ void pps4_device::iSKZ()
*/
void pps4_device::iSKBI()
{
- const uint8_t i4 = m_I1 & 15;
- const uint8_t bl = m_B & 15;
+ const u8 i4 = m_I1 & 15;
+ const u8 bl = m_B & 15;
m_Skip = bl == i4 ? 1 : 0;
}
@@ -1184,18 +1219,20 @@ void pps4_device::iRTNSK()
* the CPU and sets up the I/O enable signal. The second
* ROM word is then received by the I/O devices and decoded
* for address and command. The contents of the accumulator
- * inverted are placed on the data lines for acceptance by
- * the I/O. At the same time, input data received by the I/O
- * device is transferred to the accumulator inverted.
- *
- * FIXME: Is BL on the I/D:8-5 lines during the I/O cycle?
- * The ROM, RAM, I/O chips A17xx suggest this, because they
- * expect the value of BL to address one of the sixteen
+ * inverted are placed on the data lines [I/D:4-1] for
+ * acceptance by the I/O. At the same time, input data
+ * received by the I/O device [on I/D:8-5] is transferred
+ * to the accumulator inverted.
+ *
+ * The RAM address register (B) is placed on the address bus
+ * during the I/O request cycle. The original RAM chip ignores
+ * this and leaves the data bus alone at this time, but the
+ * A17xx uses the value of BL to address one of the sixteen
* input/output lines.
*/
void pps4_device::iIOL()
{
- uint8_t ac = ((m_B & 15) << 4) | (~m_A & 15);
+ u8 ac = (~m_A & 15);
m_I2 = ARG();
m_io->write_byte(m_I2, ac);
LOG(("%s: port:%02x <- %x\n", __FUNCTION__, m_I2, ac));
@@ -1219,7 +1256,7 @@ void pps4_device::iIOL()
*/
void pps4_device::iDIA()
{
- m_A = m_io->read_byte(PPS4_PORT_A) & 15;
+ m_A = m_dia_cb() & 15;
}
/**
@@ -1237,7 +1274,13 @@ void pps4_device::iDIA()
*/
void pps4_device::iDIB()
{
- m_A = m_io->read_byte(PPS4_PORT_B) & 15;
+ m_A = m_dib_cb() & 15;
+}
+
+void pps4_2_device::iDIB()
+{
+ // PPS-4/2 can write zeros onto bidirectional DIO pins to mask open-drain inputs
+ m_A = m_dib_cb() & m_DIO;
}
/**
@@ -1255,7 +1298,14 @@ void pps4_device::iDIB()
*/
void pps4_device::iDOA()
{
- m_io->write_byte(PPS4_PORT_A, m_A);
+ m_do_cb(m_A);
+}
+
+void pps4_2_device::iDOA()
+{
+ // DOA also transfers contents of X to DIO on PPS-4/2
+ m_DIO = m_X;
+ m_do_cb(m_A | (m_X << 4));
}
/**
@@ -1551,6 +1601,16 @@ void pps4_device::device_start()
state_add( STATE_GENFLAGS, "GENFLAGS", m_C).formatstr("%3s").noshow();
m_icountptr = &m_icount;
+
+ m_dia_cb.resolve_safe(0);
+ m_dib_cb.resolve_safe(0);
+ m_do_cb.resolve_safe();
+}
+
+void pps4_2_device::device_start()
+{
+ pps4_device::device_start();
+ save_item(NAME(m_DIO));
}
void pps4_device::state_string_export(const device_state_entry &entry, std::string &str) const
@@ -1586,3 +1646,19 @@ void pps4_device::device_reset()
m_I2 = 0; // Most recent parameter I2(8:1)
m_Ip = 0; // Previous instruction I(8:1)
}
+
+void pps4_2_device::device_reset()
+{
+ pps4_device::device_reset();
+ m_DIO = 15; // DIO clamp
+}
+
+READ16_MEMBER(pps4_device::address_bus_r)
+{
+ if (&space == m_io || &space == m_data)
+ return m_B;
+ else if (&space == m_program)
+ return m_P;
+ else
+ return 0;
+}
Oops, something went wrong.

0 comments on commit 44585d2

Please sign in to comment.