mirror of
https://github.com/holub/mame
synced 2025-04-20 23:42:22 +03:00
i86: add support for IF status and segreg address spaces [Carl]
altos8600: will make whatsnew entry later (nw)
This commit is contained in:
parent
b924b468b4
commit
a4dfbf86e9
@ -1376,6 +1376,7 @@ createMESSProjects(_target, _subtarget, "altos")
|
||||
files {
|
||||
MAME_DIR .. "src/mame/drivers/altos5.cpp",
|
||||
MAME_DIR .. "src/mame/drivers/altos486.cpp",
|
||||
MAME_DIR .. "src/mame/drivers/altos8600.cpp",
|
||||
}
|
||||
|
||||
createMESSProjects(_target, _subtarget, "ami")
|
||||
|
@ -109,23 +109,29 @@ i8086_cpu_device::i8086_cpu_device(const machine_config &mconfig, device_type ty
|
||||
: i8086_common_cpu_device(mconfig, type, tag, owner, clock)
|
||||
, m_program_config("program", ENDIANNESS_LITTLE, data_bus_size, 20, 0)
|
||||
, m_opcodes_config("opcodes", ENDIANNESS_LITTLE, data_bus_size, 20, 0)
|
||||
, m_stack_config("stack", ENDIANNESS_LITTLE, data_bus_size, 20, 0)
|
||||
, m_code_config("code", ENDIANNESS_LITTLE, data_bus_size, 20, 0)
|
||||
, m_extra_config("extra", ENDIANNESS_LITTLE, data_bus_size, 20, 0)
|
||||
, m_io_config("io", ENDIANNESS_LITTLE, data_bus_size, 16, 0)
|
||||
, m_out_if_func(*this)
|
||||
{
|
||||
}
|
||||
|
||||
device_memory_interface::space_config_vector i8086_cpu_device::memory_space_config() const
|
||||
{
|
||||
space_config_vector spaces = {
|
||||
std::make_pair(AS_PROGRAM, &m_program_config),
|
||||
std::make_pair(AS_IO, &m_io_config)
|
||||
};
|
||||
if(has_configured_map(AS_OPCODES))
|
||||
return space_config_vector {
|
||||
std::make_pair(AS_PROGRAM, &m_program_config),
|
||||
std::make_pair(AS_OPCODES, &m_opcodes_config),
|
||||
std::make_pair(AS_IO, &m_io_config)
|
||||
};
|
||||
else
|
||||
return space_config_vector {
|
||||
std::make_pair(AS_PROGRAM, &m_program_config),
|
||||
std::make_pair(AS_IO, &m_io_config)
|
||||
};
|
||||
spaces.push_back(std::make_pair(AS_OPCODES, &m_opcodes_config));
|
||||
if(has_configured_map(AS_STACK))
|
||||
spaces.push_back(std::make_pair(AS_STACK, &m_stack_config));
|
||||
if(has_configured_map(AS_CODE))
|
||||
spaces.push_back(std::make_pair(AS_CODE, &m_code_config));
|
||||
if(has_configured_map(AS_EXTRA))
|
||||
spaces.push_back(std::make_pair(AS_EXTRA, &m_extra_config));
|
||||
return spaces;
|
||||
}
|
||||
|
||||
uint8_t i8086_cpu_device::fetch_op()
|
||||
@ -146,6 +152,7 @@ uint8_t i8086_cpu_device::fetch()
|
||||
|
||||
void i8086_cpu_device::execute_run()
|
||||
{
|
||||
u8 iflag = m_IF;
|
||||
while(m_icount > 0 )
|
||||
{
|
||||
if ( m_seg_prefix_next )
|
||||
@ -276,12 +283,18 @@ void i8086_cpu_device::execute_run()
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(iflag != m_IF)
|
||||
{
|
||||
m_out_if_func(m_IF ? ASSERT_LINE : CLEAR_LINE);
|
||||
iflag = m_IF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void i8086_cpu_device::device_start()
|
||||
{
|
||||
i8086_common_cpu_device::device_start();
|
||||
m_out_if_func.resolve_safe();
|
||||
state_add( I8086_ES, "ES", m_sregs[ES] ).formatstr("%04X");
|
||||
state_add( I8086_CS, "CS", m_sregs[CS] ).callimport().formatstr("%04X");
|
||||
state_add( I8086_SS, "SS", m_sregs[SS] ).formatstr("%04X");
|
||||
@ -398,6 +411,9 @@ void i8086_common_cpu_device::device_start()
|
||||
{
|
||||
m_program = &space(AS_PROGRAM);
|
||||
m_opcodes = has_space(AS_OPCODES) ? &space(AS_OPCODES) : m_program;
|
||||
m_stack = m_program;
|
||||
m_code = m_program;
|
||||
m_extra = m_program;
|
||||
m_direct = &m_program->direct();
|
||||
m_direct_opcodes = &m_opcodes->direct();
|
||||
m_io = &space(AS_IO);
|
||||
@ -491,6 +507,7 @@ void i8086_common_cpu_device::device_reset()
|
||||
m_src = 0;
|
||||
m_halt = false;
|
||||
m_lock = false;
|
||||
m_easeg = DS;
|
||||
}
|
||||
|
||||
|
||||
@ -508,8 +525,8 @@ void i8086_common_cpu_device::interrupt(int int_num, int trap)
|
||||
m_pending_irq &= ~INT_IRQ;
|
||||
}
|
||||
|
||||
uint16_t dest_off = read_word( int_num * 4 + 0 );
|
||||
uint16_t dest_seg = read_word( int_num * 4 + 2 );
|
||||
uint16_t dest_off = read_word( int_num * 4 + 0, CS );
|
||||
uint16_t dest_seg = read_word( int_num * 4 + 2, CS );
|
||||
|
||||
PUSH(m_sregs[CS]);
|
||||
PUSH(m_ip);
|
||||
@ -579,10 +596,12 @@ uint32_t i8086_common_cpu_device::calc_addr(int seg, uint16_t offset, int size,
|
||||
{
|
||||
if ( m_seg_prefix && (seg==DS || seg==SS) && override )
|
||||
{
|
||||
m_easeg = m_seg_prefix;
|
||||
return (m_sregs[m_prefix_seg] << 4) + offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_easeg = seg;
|
||||
return (m_sregs[seg] << 4) + offset;
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,17 @@ DECLARE_DEVICE_TYPE(I8088, i8088_cpu_device)
|
||||
#define MCFG_I8086_LOCK_HANDLER(_write) \
|
||||
devcb = &i8086_common_cpu_device::set_lock_handler(*device, DEVCB_##_write);
|
||||
|
||||
#define MCFG_I8086_IF_HANDLER(_write) \
|
||||
devcb = &i8086_cpu_device::set_if_handler(*device, DEVCB_##_write);
|
||||
|
||||
#define MCFG_I8086_STACK_MAP(map) \
|
||||
MCFG_DEVICE_ADDRESS_MAP(i8086_cpu_device::AS_STACK, map)
|
||||
|
||||
#define MCFG_I8086_CODE_MAP(map) \
|
||||
MCFG_DEVICE_ADDRESS_MAP(i8086_cpu_device::AS_CODE, map)
|
||||
|
||||
#define MCFG_I8086_EXTRA_MAP(map) \
|
||||
MCFG_DEVICE_ADDRESS_MAP(i8086_cpu_device::AS_EXTRA, map)
|
||||
|
||||
enum
|
||||
{
|
||||
@ -139,6 +150,11 @@ protected:
|
||||
inline uint16_t read_word(uint32_t addr);
|
||||
inline void write_byte(uint32_t addr, uint8_t data);
|
||||
inline void write_word(uint32_t addr, uint16_t data);
|
||||
inline address_space *sreg_to_space(int sreg);
|
||||
inline uint8_t read_byte(uint32_t addr, int sreg);
|
||||
inline uint16_t read_word(uint32_t addr, int sreg);
|
||||
inline void write_byte(uint32_t addr, uint8_t data, int sreg);
|
||||
inline void write_word(uint32_t addr, uint16_t data, int sreg);
|
||||
virtual uint8_t read_port_byte(uint16_t port);
|
||||
virtual uint16_t read_port_word(uint16_t port);
|
||||
virtual void write_port_byte(uint16_t port, uint8_t data);
|
||||
@ -297,7 +313,7 @@ protected:
|
||||
uint8_t m_fire_trap;
|
||||
uint8_t m_test_state;
|
||||
|
||||
address_space *m_program, *m_opcodes;
|
||||
address_space *m_program, *m_opcodes, *m_stack, *m_code, *m_extra;
|
||||
direct_read_data *m_direct, *m_direct_opcodes;
|
||||
address_space *m_io;
|
||||
offs_t m_fetch_xor;
|
||||
@ -310,6 +326,7 @@ protected:
|
||||
uint32_t m_ea;
|
||||
uint16_t m_eo;
|
||||
uint16_t m_e16;
|
||||
int m_easeg;
|
||||
|
||||
// Used during execution of instructions
|
||||
uint8_t m_modrm;
|
||||
@ -340,11 +357,18 @@ protected:
|
||||
class i8086_cpu_device : public i8086_common_cpu_device
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
AS_STACK = AS_OPCODES + 1,
|
||||
AS_CODE, // data reads from CS are still different from opcode fetches
|
||||
AS_EXTRA
|
||||
};
|
||||
// construction/destruction
|
||||
i8086_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
// device_memory_interface overrides
|
||||
virtual space_config_vector memory_space_config() const override;
|
||||
template <class Object> static devcb_base &set_if_handler(device_t &device, Object &&cb)
|
||||
{ return downcast<i8086_cpu_device &>(device).m_out_if_func.set_callback(std::forward<Object>(cb)); }
|
||||
|
||||
protected:
|
||||
i8086_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int data_bus_size);
|
||||
@ -358,8 +382,12 @@ protected:
|
||||
|
||||
address_space_config m_program_config;
|
||||
address_space_config m_opcodes_config;
|
||||
address_space_config m_stack_config;
|
||||
address_space_config m_code_config;
|
||||
address_space_config m_extra_config;
|
||||
address_space_config m_io_config;
|
||||
static const uint8_t m_i8086_timing[200];
|
||||
devcb_write_line m_out_if_func;
|
||||
};
|
||||
|
||||
class i8088_cpu_device : public i8086_cpu_device
|
||||
|
@ -36,6 +36,42 @@ void i8086_common_cpu_device::write_word(uint32_t addr, uint16_t data)
|
||||
m_program->write_word_unaligned(addr, data);
|
||||
}
|
||||
|
||||
address_space *i8086_common_cpu_device::sreg_to_space(int sreg)
|
||||
{
|
||||
switch(sreg)
|
||||
{
|
||||
default:
|
||||
return m_program;
|
||||
case CS:
|
||||
return m_code;
|
||||
case SS:
|
||||
return m_stack;
|
||||
case ES:
|
||||
return m_extra;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t i8086_common_cpu_device::read_byte(uint32_t addr, int sreg)
|
||||
{
|
||||
return sreg_to_space(sreg)->read_byte(addr);
|
||||
}
|
||||
|
||||
uint16_t i8086_common_cpu_device::read_word(uint32_t addr, int sreg)
|
||||
{
|
||||
return sreg_to_space(sreg)->read_word_unaligned(addr);
|
||||
}
|
||||
|
||||
void i8086_common_cpu_device::write_byte(uint32_t addr, uint8_t data, int sreg)
|
||||
{
|
||||
sreg_to_space(sreg)->write_byte(addr, data);
|
||||
}
|
||||
|
||||
|
||||
void i8086_common_cpu_device::write_word(uint32_t addr, uint16_t data, int sreg)
|
||||
{
|
||||
sreg_to_space(sreg)->write_word_unaligned(addr, data);
|
||||
}
|
||||
|
||||
inline uint16_t i8086_common_cpu_device::fetch_word()
|
||||
{
|
||||
uint16_t data = fetch();
|
||||
@ -229,7 +265,6 @@ inline uint32_t i8086_common_cpu_device::get_ea(int size, int op)
|
||||
m_ea = calc_addr(DS, m_eo, size, op);
|
||||
break;
|
||||
}
|
||||
|
||||
return m_ea;
|
||||
}
|
||||
|
||||
@ -242,7 +277,7 @@ inline void i8086_common_cpu_device::PutbackRMByte(uint8_t data)
|
||||
}
|
||||
else
|
||||
{
|
||||
write_byte( m_ea, data );
|
||||
write_byte( m_ea, data, m_easeg );
|
||||
}
|
||||
}
|
||||
|
||||
@ -255,7 +290,7 @@ inline void i8086_common_cpu_device::PutbackRMWord(uint16_t data)
|
||||
}
|
||||
else
|
||||
{
|
||||
write_word( m_ea, data );
|
||||
write_word( m_ea, data, m_easeg );
|
||||
}
|
||||
}
|
||||
|
||||
@ -268,7 +303,7 @@ inline void i8086_common_cpu_device::PutImmRMWord()
|
||||
else
|
||||
{
|
||||
uint32_t addr = get_ea(2, I8086_WRITE);
|
||||
write_word( addr, fetch_word() );
|
||||
write_word( addr, fetch_word(), m_easeg );
|
||||
}
|
||||
}
|
||||
|
||||
@ -307,7 +342,7 @@ inline void i8086_common_cpu_device::PutImmRMByte()
|
||||
else
|
||||
{
|
||||
uint32_t addr = get_ea(1, I8086_WRITE);
|
||||
write_byte( addr, fetch() );
|
||||
write_byte( addr, fetch(), m_easeg );
|
||||
}
|
||||
}
|
||||
|
||||
@ -391,7 +426,7 @@ inline uint16_t i8086_common_cpu_device::GetRMWord()
|
||||
}
|
||||
else
|
||||
{
|
||||
return read_word( get_ea(2, I8086_READ) );
|
||||
return read_word(get_ea(2, I8086_READ), m_easeg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -400,7 +435,7 @@ inline uint16_t i8086_common_cpu_device::GetnextRMWord()
|
||||
{
|
||||
uint32_t addr = ( m_ea & ~0xffff ) | ( ( m_ea + 2 ) & 0xffff );
|
||||
|
||||
return read_word( addr );
|
||||
return read_word(addr, m_easeg);
|
||||
}
|
||||
|
||||
|
||||
@ -412,32 +447,32 @@ inline uint8_t i8086_common_cpu_device::GetRMByte()
|
||||
}
|
||||
else
|
||||
{
|
||||
return read_byte( get_ea(1, I8086_READ) );
|
||||
return read_byte( get_ea(1, I8086_READ), m_easeg );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline void i8086_common_cpu_device::PutMemB(int seg, uint16_t offset, uint8_t data)
|
||||
{
|
||||
write_byte( calc_addr(seg, offset, 1, I8086_WRITE), data);
|
||||
write_byte( calc_addr(seg, offset, 1, I8086_WRITE), data, m_easeg);
|
||||
}
|
||||
|
||||
|
||||
inline void i8086_common_cpu_device::PutMemW(int seg, uint16_t offset, uint16_t data)
|
||||
{
|
||||
write_word( calc_addr( seg, offset, 2, I8086_WRITE), data);
|
||||
write_word( calc_addr( seg, offset, 2, I8086_WRITE), data, m_easeg);
|
||||
}
|
||||
|
||||
|
||||
inline uint8_t i8086_common_cpu_device::GetMemB(int seg, uint16_t offset)
|
||||
{
|
||||
return read_byte( calc_addr(seg, offset, 1, I8086_READ) );
|
||||
return read_byte( calc_addr(seg, offset, 1, I8086_READ), m_easeg);
|
||||
}
|
||||
|
||||
|
||||
inline uint16_t i8086_common_cpu_device::GetMemW(int seg, uint16_t offset)
|
||||
{
|
||||
return read_word( calc_addr(seg, offset, 2, I8086_READ) );
|
||||
return read_word( calc_addr(seg, offset, 2, I8086_READ), m_easeg);
|
||||
}
|
||||
|
||||
|
||||
@ -540,7 +575,7 @@ inline void i8086_common_cpu_device::ExpandFlags(uint16_t f)
|
||||
inline void i8086_common_cpu_device::i_insb()
|
||||
{
|
||||
uint32_t ea = calc_addr(ES, m_regs.w[DI], 1, I8086_WRITE);
|
||||
write_byte(ea, read_port_byte(m_regs.w[DX]));
|
||||
write_byte(ea, read_port_byte(m_regs.w[DX]), ES);
|
||||
m_regs.w[DI] += -2 * m_DF + 1;
|
||||
CLK(IN_IMM8);
|
||||
}
|
||||
@ -548,7 +583,7 @@ inline void i8086_common_cpu_device::i_insb()
|
||||
inline void i8086_common_cpu_device::i_insw()
|
||||
{
|
||||
uint32_t ea = calc_addr(ES, m_regs.w[DI], 2, I8086_WRITE);
|
||||
write_word(ea, read_port_word(m_regs.w[DX]));
|
||||
write_word(ea, read_port_word(m_regs.w[DX]), ES);
|
||||
m_regs.w[DI] += -4 * m_DF + 2;
|
||||
CLK(IN_IMM16);
|
||||
}
|
||||
@ -915,14 +950,14 @@ inline void i8086_common_cpu_device::DecWordReg(uint8_t reg)
|
||||
|
||||
inline void i8086_common_cpu_device::PUSH(uint16_t data)
|
||||
{
|
||||
write_word(calc_addr(SS, m_regs.w[SP] - 2, 2, I8086_WRITE, false), data);
|
||||
write_word(calc_addr(SS, m_regs.w[SP] - 2, 2, I8086_WRITE, false), data, SS);
|
||||
m_regs.w[SP] -= 2;
|
||||
}
|
||||
|
||||
|
||||
inline uint16_t i8086_common_cpu_device::POP()
|
||||
{
|
||||
uint16_t data = read_word(calc_addr(SS, m_regs.w[SP], 2, I8086_READ, false));
|
||||
uint16_t data = read_word(calc_addr(SS, m_regs.w[SP], 2, I8086_READ, false), SS);
|
||||
|
||||
m_regs.w[SP] += 2;
|
||||
return data;
|
||||
|
374
src/mame/drivers/altos8600.cpp
Normal file
374
src/mame/drivers/altos8600.cpp
Normal file
@ -0,0 +1,374 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Carl
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/i86/i86.h"
|
||||
#include "cpu/i8089/i8089.h"
|
||||
#include "machine/ram.h"
|
||||
#include "machine/pic8259.h"
|
||||
|
||||
class altos8600_state : public driver_device
|
||||
{
|
||||
public:
|
||||
altos8600_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||
driver_device(mconfig, type, tag),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_dmac(*this, "dmac"),
|
||||
m_pic1(*this, "pic8259_1"),
|
||||
m_pic2(*this, "pic8259_2"),
|
||||
m_pic3(*this, "pic8259_3"),
|
||||
m_ram(*this, RAM_TAG),
|
||||
m_bios(*this, "bios")
|
||||
{}
|
||||
DECLARE_READ16_MEMBER(cpuram_r);
|
||||
DECLARE_WRITE16_MEMBER(cpuram_w);
|
||||
DECLARE_READ16_MEMBER(stkram_r);
|
||||
DECLARE_WRITE16_MEMBER(stkram_w);
|
||||
DECLARE_READ16_MEMBER(coderam_r);
|
||||
DECLARE_WRITE16_MEMBER(coderam_w);
|
||||
DECLARE_READ16_MEMBER(xtraram_r);
|
||||
DECLARE_WRITE16_MEMBER(xtraram_w);
|
||||
DECLARE_READ16_MEMBER(cpuio_r);
|
||||
DECLARE_WRITE16_MEMBER(cpuio_w);
|
||||
DECLARE_READ16_MEMBER(nmi_r);
|
||||
DECLARE_WRITE16_MEMBER(nmi_w);
|
||||
DECLARE_READ16_MEMBER(dmacram_r);
|
||||
DECLARE_WRITE16_MEMBER(dmacram_w);
|
||||
DECLARE_READ16_MEMBER(mmuaddr_r);
|
||||
DECLARE_WRITE16_MEMBER(mmuaddr_w);
|
||||
DECLARE_READ16_MEMBER(mmuflags_r);
|
||||
DECLARE_WRITE16_MEMBER(mmuflags_w);
|
||||
DECLARE_READ8_MEMBER(get_slave_ack);
|
||||
DECLARE_READ16_MEMBER(fault_r);
|
||||
DECLARE_READ16_MEMBER(errlo_r);
|
||||
DECLARE_READ16_MEMBER(errhi_r);
|
||||
DECLARE_WRITE16_MEMBER(clear_w);
|
||||
DECLARE_WRITE8_MEMBER(cattn_w);
|
||||
DECLARE_WRITE16_MEMBER(mode_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(cpuif_w);
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
|
||||
private:
|
||||
u16 xlate_r(address_space &space, offs_t offset, u16 mem_mask, int permbit);
|
||||
void xlate_w(address_space &space, offs_t offset, u16 data, u16 mem_mask, int permbit);
|
||||
void seterr(offs_t offset, u16 mem_mask, u16 err_mask);
|
||||
required_device<i8086_cpu_device> m_maincpu;
|
||||
required_device<i8089_device> m_dmac;
|
||||
required_device<pic8259_device> m_pic1;
|
||||
required_device<pic8259_device> m_pic2;
|
||||
required_device<pic8259_device> m_pic3;
|
||||
required_device<ram_device> m_ram;
|
||||
required_memory_region m_bios;
|
||||
u8 m_mmuaddr[256];
|
||||
u16 m_mmuflags[256], m_mmuerr, m_mode, m_mmueaddr[2];
|
||||
bool m_cpuif, m_user;
|
||||
};
|
||||
|
||||
void altos8600_state::machine_start()
|
||||
{
|
||||
m_mode = 0;
|
||||
}
|
||||
|
||||
void altos8600_state::machine_reset()
|
||||
{
|
||||
m_mode = (m_mode & 0x10) | 2;
|
||||
m_cpuif = false;
|
||||
m_user = false;
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(altos8600_state::cpuif_w)
|
||||
{
|
||||
if(m_user)
|
||||
{
|
||||
seterr(0, 0, 1);
|
||||
return;
|
||||
}
|
||||
m_cpuif = state ? true : false;
|
||||
if(state && BIT(m_mode, 0))
|
||||
m_user = true;
|
||||
}
|
||||
|
||||
READ16_MEMBER(altos8600_state::fault_r)
|
||||
{
|
||||
return m_mmuerr;
|
||||
}
|
||||
|
||||
READ16_MEMBER(altos8600_state::errlo_r)
|
||||
{
|
||||
return m_mmueaddr[0];
|
||||
}
|
||||
|
||||
READ16_MEMBER(altos8600_state::errhi_r)
|
||||
{
|
||||
return m_mmueaddr[1];
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(altos8600_state::clear_w)
|
||||
{
|
||||
m_mmuerr = 0xff;
|
||||
m_maincpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE);
|
||||
}
|
||||
|
||||
READ16_MEMBER(altos8600_state::mmuaddr_r)
|
||||
{
|
||||
return m_mmuaddr[offset & 0xff];
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(altos8600_state::mmuaddr_w)
|
||||
{
|
||||
if(mem_mask & 0xff)
|
||||
m_mmuaddr[offset & 0xff] = data & 0xff;
|
||||
}
|
||||
|
||||
READ16_MEMBER(altos8600_state::mmuflags_r)
|
||||
{
|
||||
return m_mmuflags[offset & 0xff] | (m_user ? 1 : 0) | (m_mode & 2);
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(altos8600_state::mmuflags_w)
|
||||
{
|
||||
data &= ~0x17;
|
||||
COMBINE_DATA(&m_mmuflags[offset & 0xff]);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(altos8600_state::cattn_w)
|
||||
{
|
||||
m_dmac->sel_w(offset & 1 ? ASSERT_LINE : CLEAR_LINE);
|
||||
m_dmac->ca_w(ASSERT_LINE);
|
||||
m_dmac->ca_w(CLEAR_LINE);
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(altos8600_state::mode_w)
|
||||
{
|
||||
m_mode = data;
|
||||
if(m_cpuif && BIT(m_mode, 0))
|
||||
m_user = true;
|
||||
}
|
||||
|
||||
READ8_MEMBER(altos8600_state::get_slave_ack)
|
||||
{
|
||||
m_user = false;
|
||||
if(offset == 2)
|
||||
return m_pic2->acknowledge();
|
||||
else if(offset == 3)
|
||||
return m_pic3->acknowledge();
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
void altos8600_state::seterr(offs_t offset, u16 mem_mask, u16 err_mask)
|
||||
{
|
||||
if(machine().side_effect_disabled())
|
||||
return;
|
||||
logerror("Fault at %06x type %04x\n", offset << 1, err_mask);
|
||||
m_maincpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE);
|
||||
m_mmuerr &= ~err_mask;
|
||||
m_mmueaddr[0] = (offset << 1) | (!(mem_mask & 0xff) ? 1 : 0);
|
||||
m_mmueaddr[1] = (m_user ? 0x100 : 0) | (m_mode & 2 ? 0x200 : 0) | ((offset >> 3) & 0xf000);
|
||||
}
|
||||
|
||||
u16 altos8600_state::xlate_r(address_space &space, offs_t offset, u16 mem_mask, int permbit)
|
||||
{
|
||||
u8 page = m_mmuaddr[offset >> 11];
|
||||
u16 flags = m_mmuflags[offset >> 11];
|
||||
if((offset >= 0x7f000) && BIT(m_mode, 1))
|
||||
return m_bios->as_u16(offset & 0xfff);
|
||||
if(m_user && !BIT(flags, 11))
|
||||
seterr(offset, mem_mask, 0x800);
|
||||
else if(m_user && !BIT(flags, permbit))
|
||||
seterr(offset, mem_mask, 1 << permbit);
|
||||
return ((u16 *)(m_ram->pointer()))[(page << 11) | (offset & 0x7ff)];
|
||||
|
||||
}
|
||||
|
||||
void altos8600_state::xlate_w(address_space &space, offs_t offset, u16 data, u16 mem_mask, int permbit)
|
||||
{
|
||||
u8 page = m_mmuaddr[offset >> 11];
|
||||
u16 flags = m_mmuflags[offset >> 11];
|
||||
if(m_user && !BIT(flags, 7))
|
||||
{
|
||||
seterr(offset, mem_mask, 0x80);
|
||||
return;
|
||||
}
|
||||
else if(!m_user && !BIT(flags, 8))
|
||||
{
|
||||
seterr(offset, mem_mask, 0x10);
|
||||
return;
|
||||
}
|
||||
else if(m_user && !BIT(flags, permbit))
|
||||
seterr(offset, mem_mask, 1 << permbit);
|
||||
COMBINE_DATA(&((u16 *)(m_ram->pointer()))[(page << 11) | (offset & 0x7ff)]);
|
||||
}
|
||||
|
||||
READ16_MEMBER(altos8600_state::cpuram_r)
|
||||
{
|
||||
return xlate_r(space, offset, mem_mask, 14);
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(altos8600_state::cpuram_w)
|
||||
{
|
||||
xlate_w(space, offset, data, mem_mask, 14);
|
||||
}
|
||||
|
||||
READ16_MEMBER(altos8600_state::stkram_r)
|
||||
{
|
||||
return xlate_r(space, offset, mem_mask, 13);
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(altos8600_state::stkram_w)
|
||||
{
|
||||
xlate_w(space, offset, data, mem_mask, 13);
|
||||
}
|
||||
|
||||
READ16_MEMBER(altos8600_state::coderam_r)
|
||||
{
|
||||
return xlate_r(space, offset, mem_mask, 15);
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(altos8600_state::coderam_w)
|
||||
{
|
||||
xlate_w(space, offset, data, mem_mask, 15);
|
||||
}
|
||||
|
||||
READ16_MEMBER(altos8600_state::xtraram_r)
|
||||
{
|
||||
return xlate_r(space, offset, mem_mask, 12);
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(altos8600_state::xtraram_w)
|
||||
{
|
||||
xlate_w(space, offset, data, mem_mask, 12);
|
||||
}
|
||||
|
||||
READ16_MEMBER(altos8600_state::cpuio_r)
|
||||
{
|
||||
if(m_user)
|
||||
{
|
||||
seterr(offset, mem_mask, 0x800);
|
||||
return 0;
|
||||
}
|
||||
return m_dmac->space(AS_IO).read_word_unaligned(offset << 1, mem_mask);
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(altos8600_state::cpuio_w)
|
||||
{
|
||||
if(m_user)
|
||||
{
|
||||
seterr(offset, mem_mask, 0x800);
|
||||
return;
|
||||
}
|
||||
m_dmac->space(AS_IO).write_word_unaligned(offset << 1, mem_mask);
|
||||
}
|
||||
|
||||
READ16_MEMBER(altos8600_state::dmacram_r)
|
||||
{
|
||||
u8 page = m_mmuaddr[offset >> 11];
|
||||
u16 flags = m_mmuflags[offset >> 11];
|
||||
if((offset >= 0x7f000) && BIT(m_mode, 1))
|
||||
return m_bios->as_u16(offset & 0xfff);
|
||||
if(!BIT(flags, 10))
|
||||
seterr(offset, mem_mask, 0x400);
|
||||
return ((u16 *)(m_ram->pointer()))[(page << 11) | (offset & 0x7ff)];
|
||||
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(altos8600_state::dmacram_w)
|
||||
{
|
||||
u8 page = m_mmuaddr[offset >> 11];
|
||||
u16 flags = m_mmuflags[offset >> 11];
|
||||
if(!BIT(flags, 6))
|
||||
{
|
||||
seterr(offset, mem_mask, 0x40);
|
||||
return;
|
||||
}
|
||||
COMBINE_DATA(&((u16 *)(m_ram->pointer()))[(page << 11) | (offset & 0x7ff)]);
|
||||
}
|
||||
|
||||
READ16_MEMBER(altos8600_state::nmi_r)
|
||||
{
|
||||
seterr(offset, mem_mask, 0x100);
|
||||
return 0;
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(altos8600_state::nmi_w)
|
||||
{
|
||||
seterr(offset, mem_mask, 0x100);
|
||||
}
|
||||
|
||||
static ADDRESS_MAP_START(cpu_mem, AS_PROGRAM, 16, altos8600_state)
|
||||
AM_RANGE(0x00000, 0xfffff) AM_READWRITE(cpuram_r, cpuram_w)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
static ADDRESS_MAP_START(stack_mem, i8086_cpu_device::AS_STACK, 16, altos8600_state)
|
||||
AM_RANGE(0x00000, 0xfffff) AM_READWRITE(stkram_r, stkram_w)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
static ADDRESS_MAP_START(code_mem, i8086_cpu_device::AS_CODE, 16, altos8600_state)
|
||||
AM_RANGE(0x00000, 0xfffff) AM_READWRITE(coderam_r, coderam_w)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
static ADDRESS_MAP_START(extra_mem, i8086_cpu_device::AS_EXTRA, 16, altos8600_state)
|
||||
AM_RANGE(0x00000, 0xfffff) AM_READWRITE(xtraram_r, xtraram_w)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
static ADDRESS_MAP_START(cpu_io, AS_IO, 16, altos8600_state)
|
||||
AM_RANGE(0x0000, 0xffff) AM_READWRITE(cpuio_r, cpuio_w)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
static ADDRESS_MAP_START(dmac_mem, AS_PROGRAM, 16, altos8600_state)
|
||||
AM_RANGE(0x00000, 0xfffff) AM_READWRITE(dmacram_r, dmacram_w)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
static ADDRESS_MAP_START(dmac_io, AS_IO, 16, altos8600_state)
|
||||
AM_RANGE(0x0000, 0x0007) AM_READ(fault_r)
|
||||
AM_RANGE(0x0008, 0x000f) AM_WRITE(clear_w)
|
||||
AM_RANGE(0x0010, 0x0017) AM_READ(errlo_r)
|
||||
AM_RANGE(0x0018, 0x001f) AM_READ(errhi_r)
|
||||
AM_RANGE(0x0030, 0x0037) AM_WRITE(mode_w)
|
||||
AM_RANGE(0x0058, 0x005f) AM_DEVREADWRITE8("pic8259_1", pic8259_device, read, write, 0x00ff)
|
||||
AM_RANGE(0x0060, 0x0067) AM_DEVREADWRITE8("pic8259_2", pic8259_device, read, write, 0x00ff)
|
||||
AM_RANGE(0x0068, 0x006f) AM_DEVREADWRITE8("pic8259_3", pic8259_device, read, write, 0x00ff)
|
||||
AM_RANGE(0x0070, 0x0077) AM_NOP
|
||||
AM_RANGE(0x0078, 0x007f) AM_WRITE8(cattn_w, 0xffff)
|
||||
AM_RANGE(0x0200, 0x03ff) AM_READWRITE(mmuflags_r, mmuflags_w)
|
||||
AM_RANGE(0x0400, 0x05ff) AM_READWRITE(mmuaddr_r, mmuaddr_w)
|
||||
AM_RANGE(0x0000, 0xffff) AM_READWRITE(nmi_r, nmi_w)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
static MACHINE_CONFIG_START(altos8600)
|
||||
MCFG_CPU_ADD("maincpu", I8086, XTAL_5MHz)
|
||||
MCFG_CPU_PROGRAM_MAP(cpu_mem)
|
||||
MCFG_CPU_IO_MAP(cpu_io)
|
||||
MCFG_CPU_DECRYPTED_OPCODES_MAP(code_mem)
|
||||
MCFG_I8086_STACK_MAP(stack_mem)
|
||||
MCFG_I8086_CODE_MAP(code_mem)
|
||||
MCFG_I8086_EXTRA_MAP(extra_mem)
|
||||
MCFG_CPU_IRQ_ACKNOWLEDGE_DEVICE("pic8259_1", pic8259_device, inta_cb)
|
||||
MCFG_I8086_IF_HANDLER(WRITELINE(altos8600_state, cpuif_w))
|
||||
|
||||
MCFG_CPU_ADD("dmac", I8089, XTAL_5MHz)
|
||||
MCFG_CPU_PROGRAM_MAP(dmac_mem)
|
||||
MCFG_CPU_IO_MAP(dmac_io)
|
||||
MCFG_I8089_DATABUS_WIDTH(16)
|
||||
MCFG_I8089_SINTR1(DEVWRITELINE("pic8259_2", pic8259_device, ir3_w))
|
||||
MCFG_I8089_SINTR2(DEVWRITELINE("pic8259_2", pic8259_device, ir4_w))
|
||||
|
||||
MCFG_PIC8259_ADD("pic8259_1", INPUTLINE("maincpu", 0), VCC, READ8(altos8600_state, get_slave_ack))
|
||||
MCFG_PIC8259_ADD("pic8259_2", DEVWRITELINE("pic8259_1", pic8259_device, ir2_w), GND, NOOP)
|
||||
MCFG_PIC8259_ADD("pic8259_3", DEVWRITELINE("pic8259_1", pic8259_device, ir3_w), GND, NOOP)
|
||||
|
||||
MCFG_RAM_ADD(RAM_TAG)
|
||||
MCFG_RAM_DEFAULT_SIZE("1M")
|
||||
MCFG_RAM_EXTRA_OPTIONS("512K")
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
ROM_START(altos8600)
|
||||
ROM_REGION(0x2000, "bios", 0)
|
||||
ROM_SYSTEM_BIOS(0, "bios", "bios")
|
||||
ROMX_LOAD("11753_1.5_lo.bin", 0x0000, 0x1000, CRC(dfa7bf0e) SHA1(6628fd7c579423b51d2642aeaa7fc0405a989252), ROM_SKIP(1) | ROM_BIOS(1))
|
||||
ROMX_LOAD("11753_1.5_hi.bin", 0x0001, 0x1000, CRC(9b5e812c) SHA1(c2ef24859edd48d2096db47e16855c9bc01dae75), ROM_SKIP(1) | ROM_BIOS(1))
|
||||
ROM_END
|
||||
|
||||
COMP(1981, altos8600, 0, 0, altos8600, 0, altos8600_state, 0, "Altos", "8600", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW)
|
@ -1085,6 +1085,9 @@ altos5 //
|
||||
@source:altos486.cpp
|
||||
altos486
|
||||
|
||||
@source:altos8600.cpp
|
||||
altos8600
|
||||
|
||||
@source:alvg.cpp
|
||||
agsoccer //
|
||||
dinoeggs //
|
||||
|
@ -31,6 +31,7 @@ altair.cpp
|
||||
alto2.cpp
|
||||
altos5.cpp
|
||||
altos486.cpp
|
||||
altos8600.cpp
|
||||
amico2k.cpp
|
||||
amiga.cpp
|
||||
ampro.cpp
|
||||
|
Loading…
Reference in New Issue
Block a user