summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Robbbert <Robbbert@users.noreply.github.com>2019-05-20 00:00:25 +1000
committer Robbbert <Robbbert@users.noreply.github.com>2019-05-20 00:00:25 +1000
commitba1538903661ce87aa765c51146d041fc94adf3c (patch)
tree6c28ac56849148f77581d9e65909d5a71388fc9f
parent6ba74415beab20351d080ff5c1138423954cc511 (diff)
parent354656e55b84a71c333b2b9a81ff388f7f4a783f (diff)
Merge branch 'master' of https://github.com/mamedev/mame
-rw-r--r--src/devices/cpu/i86/i186.cpp137
-rw-r--r--src/devices/cpu/i86/i186.h13
-rw-r--r--src/mame/drivers/bgt.cpp7
3 files changed, 92 insertions, 65 deletions
diff --git a/src/devices/cpu/i86/i186.cpp b/src/devices/cpu/i86/i186.cpp
index 48329288bf5..3d1dcca5a2d 100644
--- a/src/devices/cpu/i86/i186.cpp
+++ b/src/devices/cpu/i86/i186.cpp
@@ -524,6 +524,16 @@ void i80186_cpu_device::execute_run()
m_regs.w[AX] = 0xffff; // FPU not present
break;
+ case 0xe6: // i_outal
+ write_port_byte_al(fetch());
+ CLK(OUT_IMM8);
+ break;
+
+ case 0xee: // i_outdxal
+ write_port_byte_al(m_regs.w[DX]);
+ CLK(OUT_DX8);
+ break;
+
case 0xf2: // i_repne
case 0xf3:
{
@@ -577,44 +587,46 @@ void i80186_cpu_device::device_start()
state_add( STATE_GENPCBASE, "CURPC", m_pc ).callimport().formatstr("%05X").noshow();
state_add( I8086_HALT, "HALT", m_halt ).mask(1);
- // Most of these mnemonics are not official and only chosen as convenient shorthand.
- state_add( I80186_RELOC, "RELOC", m_reloc ).formatstr("%04X");
+ // Most of these mnemonics are borrowed from the Intel 80C186EB/80C188EB Microprocessor User's Manual.
+ // (The 80C186EB/80C188EB's peripheral block is mapped incompatibly but mostly functionally analogous.)
+ // The DMA register mnemonics are not official and only chosen as convenient shorthand.
+ state_add( I80186_RELREG, "RELREG", m_reloc ).formatstr("%04X");
state_add( I80186_UMCS, "UMCS", m_mem.upper ).formatstr("%04X");
state_add( I80186_LMCS, "LMCS", m_mem.lower ).formatstr("%04X");
state_add( I80186_PACS, "PACS", m_mem.peripheral ).formatstr("%04X");
state_add( I80186_MMCS, "MMCS", m_mem.middle ).formatstr("%04X");
state_add( I80186_MPCS, "MPCS", m_mem.middle_size ).formatstr("%04X");
- state_add( I80186_DMA_SP + 0, "DMA0_SP", m_dma[0].source ).formatstr("%05X").mask(0xfffff);
- state_add( I80186_DMA_DP + 0, "DMA0_DP", m_dma[0].dest ).formatstr("%05X").mask(0xfffff);
- state_add( I80186_DMA_TC + 0, "DMA0_TC", m_dma[0].count ).formatstr("%04X");
- state_add( I80186_DMA_CR + 0, "DMA0_CR", m_dma[0].control ).formatstr("%04X");
- state_add( I80186_DMA_SP + 1, "DMA1_SP", m_dma[1].source ).formatstr("%05X").mask(0xfffff);
- state_add( I80186_DMA_DP + 1, "DMA1_DP", m_dma[1].dest ).formatstr("%05X").mask(0xfffff);
- state_add( I80186_DMA_TC + 1, "DMA1_TC", m_dma[1].count ).formatstr("%04X");
- state_add( I80186_DMA_CR + 1, "DMA1_CR", m_dma[1].control ).formatstr("%04X");
- state_add( I80186_T_COUNT + 0, "T0_COUNT", m_timer[0].count ).formatstr("%04X");
- state_add( I80186_T_MAX_A + 0, "T0_MAX_A", m_timer[0].maxA ).formatstr("%04X");
- state_add( I80186_T_MAX_B + 0, "T0_MAX_B", m_timer[0].maxB ).formatstr("%04X");
- state_add( I80186_T_CONTROL + 0, "T0_CONTROL", m_timer[0].control ).formatstr("%04X");
- state_add( I80186_T_COUNT + 1, "T1_COUNT", m_timer[1].count ).formatstr("%04X");
- state_add( I80186_T_MAX_A + 1, "T1_MAX_A", m_timer[1].maxA ).formatstr("%04X");
- state_add( I80186_T_MAX_B + 1, "T1_MAX_B", m_timer[1].maxB ).formatstr("%04X");
- state_add( I80186_T_CONTROL + 1, "T1_CONTROL", m_timer[1].control ).formatstr("%04X");
- state_add( I80186_T_COUNT + 2, "T2_COUNT", m_timer[2].count ).formatstr("%04X");
- state_add( I80186_T_MAX_A + 2, "T2_MAX", m_timer[2].maxA ).formatstr("%04X");
- state_add( I80186_T_CONTROL + 2, "T2_CONTROL", m_timer[2].control ).formatstr("%04X");
- state_add( I80186_ISR, "ISR", m_intr.in_service ).formatstr("%04X");
- state_add( I80186_IRR, "IRR", m_intr.request ).formatstr("%04X");
- state_add( I80186_PMR, "PMR", m_intr.priority_mask ).formatstr("%04X");
- state_add( I80186_ICSR, "ICSR", m_intr.status ).formatstr("%04X");
- state_add( I80186_TMRCR, "TMRCR", m_intr.timer ).formatstr("%04X");
- state_add( I80186_D0CR, "D0CR", m_intr.dma[0] ).formatstr("%04X");
- state_add( I80186_D1CR, "D1CR", m_intr.dma[1] ).formatstr("%04X");
- state_add( I80186_I0CR, "I0CR", m_intr.ext[0] ).formatstr("%04X");
- state_add( I80186_I1CR, "I1CR", m_intr.ext[1] ).formatstr("%04X");
- state_add( I80186_I2CR, "I2CR", m_intr.ext[2] ).formatstr("%04X");
- state_add( I80186_I3CR, "I3CR", m_intr.ext[3] ).formatstr("%04X");
- state_add( I80186_POLL, "POLL", m_intr.poll_status ).formatstr("%04X");
+ state_add( I80186_DMA_SP + 0, "DMA0SP", m_dma[0].source ).formatstr("%05X").mask(0xfffff);
+ state_add( I80186_DMA_DP + 0, "DMA0DP", m_dma[0].dest ).formatstr("%05X").mask(0xfffff);
+ state_add( I80186_DMA_TC + 0, "DMA0TC", m_dma[0].count ).formatstr("%04X");
+ state_add( I80186_DMA_CR + 0, "DMA0CR", m_dma[0].control ).formatstr("%04X");
+ state_add( I80186_DMA_SP + 1, "DMA1SP", m_dma[1].source ).formatstr("%05X").mask(0xfffff);
+ state_add( I80186_DMA_DP + 1, "DMA1DP", m_dma[1].dest ).formatstr("%05X").mask(0xfffff);
+ state_add( I80186_DMA_TC + 1, "DMA1TC", m_dma[1].count ).formatstr("%04X");
+ state_add( I80186_DMA_CR + 1, "DMA1CR", m_dma[1].control ).formatstr("%04X");
+ state_add( I80186_T_COUNT + 0, "T0CNT", m_timer[0].count ).formatstr("%04X");
+ state_add( I80186_T_MAX_A + 0, "T0CMPA", m_timer[0].maxA ).formatstr("%04X");
+ state_add( I80186_T_MAX_B + 0, "T0CMPB", m_timer[0].maxB ).formatstr("%04X");
+ state_add( I80186_T_CONTROL + 0, "T0CON", m_timer[0].control ).formatstr("%04X");
+ state_add( I80186_T_COUNT + 1, "T1CNT", m_timer[1].count ).formatstr("%04X");
+ state_add( I80186_T_MAX_A + 1, "T1CMPA", m_timer[1].maxA ).formatstr("%04X");
+ state_add( I80186_T_MAX_B + 1, "T1CMPB", m_timer[1].maxB ).formatstr("%04X");
+ state_add( I80186_T_CONTROL + 1, "T1CON", m_timer[1].control ).formatstr("%04X");
+ state_add( I80186_T_COUNT + 2, "T2CNT", m_timer[2].count ).formatstr("%04X");
+ state_add( I80186_T_MAX_A + 2, "T2CMPA", m_timer[2].maxA ).formatstr("%04X");
+ state_add( I80186_T_CONTROL + 2, "T2CON", m_timer[2].control ).formatstr("%04X");
+ state_add( I80186_INSERV, "INSERV", m_intr.in_service ).formatstr("%04X");
+ state_add( I80186_REQST, "REQST", m_intr.request ).formatstr("%04X");
+ state_add( I80186_PRIMSK, "PRIMSK", m_intr.priority_mask ).formatstr("%04X");
+ state_add( I80186_INTSTS, "INTSTS", m_intr.status ).formatstr("%04X");
+ state_add( I80186_TCUCON, "TCUCON", m_intr.timer ).formatstr("%04X");
+ state_add( I80186_D0CON, "D0CON", m_intr.dma[0] ).formatstr("%04X");
+ state_add( I80186_D1CON, "D1CON", m_intr.dma[1] ).formatstr("%04X");
+ state_add( I80186_I0CON, "I0CON", m_intr.ext[0] ).formatstr("%04X");
+ state_add( I80186_I1CON, "I1CON", m_intr.ext[1] ).formatstr("%04X");
+ state_add( I80186_I2CON, "I2CON", m_intr.ext[2] ).formatstr("%04X");
+ state_add( I80186_I3CON, "I3CON", m_intr.ext[3] ).formatstr("%04X");
+ state_add( I80186_POLLSTS, "POLLSTS", m_intr.poll_status ).formatstr("%04X");
// register for savestates
save_item(NAME(m_timer[0].control));
@@ -718,8 +730,10 @@ uint8_t i80186_cpu_device::read_port_byte(uint16_t port)
{
if(!(m_reloc & 0x1000) && (port >> 8) == (m_reloc & 0xff))
{
- uint16_t ret = internal_port_r(*m_io, (port >> 1) & 0x7f, (port & 1) ? 0xff00 : 0x00ff);
- return (port & 1) ? (ret >> 8) : (ret & 0xff);
+ if(port & 1)
+ return internal_port_r(*m_io, (port >> 1) & 0x7f, 0xff00) >> 8;
+ else
+ return internal_port_r(*m_io, (port >> 1) & 0x7f, 0x00ff) & 0xff;
}
return m_io->read_byte(port);
}
@@ -728,12 +742,11 @@ uint16_t i80186_cpu_device::read_port_word(uint16_t port)
{
if(!(m_reloc & 0x1000) && (port >> 8) == (m_reloc & 0xff))
{
+ // Unaligned reads from the internal bus are swapped rather than split
if(port & 1)
- {
- uint8_t low = read_port_byte(port);
- return read_port_byte(port + 1) << 8 | low;
- }
- return internal_port_r(*m_io, (port >> 1) & 0x7f);
+ return swapendian_int16(internal_port_r(*m_io, (port >> 1) & 0x7f));
+ else
+ return internal_port_r(*m_io, (port >> 1) & 0x7f);
}
return m_io->read_word_unaligned(port);
}
@@ -741,20 +754,37 @@ uint16_t i80186_cpu_device::read_port_word(uint16_t port)
void i80186_cpu_device::write_port_byte(uint16_t port, uint8_t data)
{
if(!(m_reloc & 0x1000) && (port >> 8) == (m_reloc & 0xff))
- internal_port_w(*m_io, (port >> 1) & 0x7f, (port & 1) ? (data << 8) : data, (port & 1) ? 0xff00 : 0x00ff);
+ {
+ if(port & 1)
+ internal_port_w(*m_io, (port >> 1) & 0x7f, data << 8, 0xff00);
+ else
+ internal_port_w(*m_io, (port >> 1) & 0x7f, data, 0x00ff);
+ }
else
m_io->write_byte(port, data);
}
+void i80186_cpu_device::write_port_byte_al(uint16_t port)
+{
+ if(!(m_reloc & 0x1000) && (port >> 8) == (m_reloc & 0xff))
+ {
+ // Both AH and AL are written onto the internal bus
+ if(port & 1)
+ internal_port_w(*m_io, (port >> 1) & 0x7f, swapendian_int16(m_regs.w[AX]), 0xff00);
+ else
+ internal_port_w(*m_io, (port >> 1) & 0x7f, m_regs.w[AX], 0x00ff);
+ }
+ else
+ m_io->write_byte(port, m_regs.w[AL]);
+}
+
void i80186_cpu_device::write_port_word(uint16_t port, uint16_t data)
{
if(!(m_reloc & 0x1000) && (port >> 8) == (m_reloc & 0xff))
{
+ // Unaligned writes to the internal bus are swapped rather than split
if(port & 1)
- {
- write_port_byte(port, data & 0xff);
- write_port_byte(port + 1, data >> 8);
- }
+ internal_port_w(*m_io, (port >> 1) & 0x7f, swapendian_int16(data));
else
internal_port_w(*m_io, (port >> 1) & 0x7f, data);
}
@@ -776,12 +806,11 @@ uint16_t i80186_cpu_device::read_word(uint32_t addr)
{
if((m_reloc & 0x1000) && (addr >> 8) == (m_reloc & 0xfff))
{
+ // Unaligned reads from the internal bus are swapped rather than split
if(addr & 1)
- {
- uint8_t low = read_byte(addr);
- return read_byte(addr + 1) << 8 | low;
- }
- return internal_port_r(*m_program, (addr >> 1) & 0x7f);
+ return swapendian_int16(internal_port_r(*m_program, (addr >> 1) & 0x7f));
+ else
+ return internal_port_r(*m_program, (addr >> 1) & 0x7f);
}
return m_program->read_word_unaligned(addr);
}
@@ -798,11 +827,9 @@ void i80186_cpu_device::write_word(uint32_t addr, uint16_t data)
{
if((m_reloc & 0x1000) && (addr >> 8) == (m_reloc & 0xfff))
{
+ // Unaligned writes from the internal bus are swapped rather than split
if(addr & 1)
- {
- write_byte(addr, data & 0xff);
- write_byte(addr + 1, data >> 8);
- }
+ internal_port_w(*m_program, (addr >> 1) & 0x7f, swapendian_int16(data));
else
internal_port_w(*m_program, (addr >> 1) & 0x7f, data);
}
@@ -1809,9 +1836,9 @@ WRITE16_MEMBER(i80186_cpu_device::internal_port_w)
break;
case 0x7f:
+ // 80188 byte output to this port is *not* masked!
if (LOG_PORTS) logerror("%05X:80186 relocation register = %04X\n", m_pc, data);
m_reloc = data;
-
break;
default:
diff --git a/src/devices/cpu/i86/i186.h b/src/devices/cpu/i86/i186.h
index a968f5ef3dd..b2ebe651bc1 100644
--- a/src/devices/cpu/i86/i186.h
+++ b/src/devices/cpu/i86/i186.h
@@ -37,7 +37,7 @@ public:
protected:
enum
{
- I80186_RELOC = I8086_HALT + 1,
+ I80186_RELREG = I8086_HALT + 1,
I80186_UMCS, I80186_LMCS, I80186_PACS, I80186_MMCS, I80186_MPCS,
I80186_DMA_SP,
I80186_DMA_DP = I80186_DMA_SP + 2,
@@ -47,11 +47,11 @@ protected:
I80186_T_MAX_A = I80186_T_COUNT + 3,
I80186_T_MAX_B = I80186_T_MAX_A + 3,
I80186_T_CONTROL = I80186_T_MAX_B + 2,
- I80186_ISR = I80186_T_CONTROL + 3,
- I80186_IRR, I80186_PMR, I80186_ICSR,
- I80186_TMRCR, I80186_D0CR, I80186_D1CR,
- I80186_I0CR, I80186_I1CR, I80186_I2CR, I80186_I3CR,
- I80186_POLL
+ I80186_INSERV = I80186_T_CONTROL + 3,
+ I80186_REQST, I80186_PRIMSK, I80186_INTSTS,
+ I80186_TCUCON, I80186_D0CON, I80186_D1CON,
+ I80186_I0CON, I80186_I1CON, I80186_I2CON, I80186_I3CON,
+ I80186_POLLSTS
};
i80186_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int data_bus_size);
@@ -70,6 +70,7 @@ protected:
virtual uint8_t read_port_byte(uint16_t port) override;
virtual uint16_t read_port_word(uint16_t port) override;
virtual void write_port_byte(uint16_t port, uint8_t data) override;
+ void write_port_byte_al(uint16_t port);
virtual void write_port_word(uint16_t port, uint16_t data) override;
virtual uint8_t read_byte(uint32_t addr) override;
virtual uint16_t read_word(uint32_t addr) override;
diff --git a/src/mame/drivers/bgt.cpp b/src/mame/drivers/bgt.cpp
index f9e6c432114..dc81209526c 100644
--- a/src/mame/drivers/bgt.cpp
+++ b/src/mame/drivers/bgt.cpp
@@ -3,14 +3,13 @@
/* BGT Fruit Machines
BGT (British Gaming Technology) were a small Spanish company
- x86 based, not sure exactly what CPU tho
+ x86 based (186/188 or equivalent)
*/
#include "emu.h"
-#include "cpu/nec/nec.h"
-#include "cpu/i86/i86.h"
+#include "cpu/i86/i186.h"
class bgt_state : public driver_device
@@ -51,7 +50,7 @@ INPUT_PORTS_END
void bgt_state::bgt(machine_config &config)
{
- V30(config, m_maincpu, 12000000); // ? unknown CPU.. definitely x86 based tho
+ I80186(config, m_maincpu, 12000000); // ?
m_maincpu->set_addrmap(AS_PROGRAM, &bgt_state::bgt_map);
m_maincpu->set_addrmap(AS_IO, &bgt_state::bgt_io);
}