mirror of
https://github.com/holub/mame
synced 2025-05-13 17:38:21 +03:00
hp64k: DMA added to HP hybrid CPU (working?)
This commit is contained in:
parent
da5de0d3d9
commit
bf377a6b8f
@ -42,6 +42,7 @@ enum {
|
|||||||
#define HPHYBRID_IRL_BIT 9 // IRL requested
|
#define HPHYBRID_IRL_BIT 9 // IRL requested
|
||||||
#define HPHYBRID_IRH_SVC_BIT 10 // IRH in service
|
#define HPHYBRID_IRH_SVC_BIT 10 // IRH in service
|
||||||
#define HPHYBRID_IRL_SVC_BIT 11 // IRL in service
|
#define HPHYBRID_IRL_SVC_BIT 11 // IRL in service
|
||||||
|
#define HPHYBRID_DMAR_BIT 12 // DMA request
|
||||||
|
|
||||||
#define HPHYBRID_IV_MASK 0xfff0 // IV mask
|
#define HPHYBRID_IV_MASK 0xfff0 // IV mask
|
||||||
|
|
||||||
@ -51,6 +52,15 @@ enum {
|
|||||||
|
|
||||||
const device_type HP_5061_3011 = &device_creator<hp_5061_3011_cpu_device>;
|
const device_type HP_5061_3011 = &device_creator<hp_5061_3011_cpu_device>;
|
||||||
|
|
||||||
|
WRITE_LINE_MEMBER(hp_hybrid_cpu_device::dmar_w)
|
||||||
|
{
|
||||||
|
if (state) {
|
||||||
|
BIT_SET(m_flags , HPHYBRID_DMAR_BIT);
|
||||||
|
} else {
|
||||||
|
BIT_CLR(m_flags , HPHYBRID_DMAR_BIT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
hp_hybrid_cpu_device::hp_hybrid_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname)
|
hp_hybrid_cpu_device::hp_hybrid_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname)
|
||||||
: cpu_device(mconfig, type, name, tag, owner, clock, shortname, __FILE__),
|
: cpu_device(mconfig, type, name, tag, owner, clock, shortname, __FILE__),
|
||||||
m_program_config("program", ENDIANNESS_BIG, 16, 16, -1),
|
m_program_config("program", ENDIANNESS_BIG, 16, 16, -1),
|
||||||
@ -127,13 +137,16 @@ void hp_hybrid_cpu_device::device_reset()
|
|||||||
void hp_hybrid_cpu_device::execute_run()
|
void hp_hybrid_cpu_device::execute_run()
|
||||||
{
|
{
|
||||||
do {
|
do {
|
||||||
|
if (BIT(m_flags , HPHYBRID_DMAEN_BIT) && BIT(m_flags , HPHYBRID_DMAR_BIT)) {
|
||||||
|
handle_dma();
|
||||||
|
} else {
|
||||||
debugger_instruction_hook(this, m_reg_P);
|
debugger_instruction_hook(this, m_reg_P);
|
||||||
|
|
||||||
// Check for interrupts
|
// Check for interrupts
|
||||||
check_for_interrupts();
|
check_for_interrupts();
|
||||||
|
|
||||||
// TODO: check dma
|
|
||||||
m_reg_I = execute_one(m_reg_I);
|
m_reg_I = execute_one(m_reg_I);
|
||||||
|
}
|
||||||
} while (m_icount > 0);
|
} while (m_icount > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -768,6 +781,32 @@ void hp_hybrid_cpu_device::check_for_interrupts(void)
|
|||||||
m_reg_I = RM(m_reg_P);
|
m_reg_I = RM(m_reg_P);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void hp_hybrid_cpu_device::handle_dma(void)
|
||||||
|
{
|
||||||
|
// Patent hints at the fact that terminal count is detected by bit 15 of dmac being 1 after decrementing
|
||||||
|
bool tc = BIT(--m_dmac , 15) != 0;
|
||||||
|
UINT16 tmp;
|
||||||
|
|
||||||
|
if (BIT(m_flags , HPHYBRID_DMADIR_BIT)) {
|
||||||
|
// "Outward" DMA: memory -> peripheral
|
||||||
|
tmp = RM(m_dmama++);
|
||||||
|
WIO(m_dmapa , tc ? 2 : 0 , tmp);
|
||||||
|
m_icount -= 10;
|
||||||
|
} else {
|
||||||
|
// "Inward" DMA: peripheral -> memory
|
||||||
|
tmp = RIO(m_dmapa , tc ? 2 : 0);
|
||||||
|
WM(m_dmama++ , tmp);
|
||||||
|
m_icount -= 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is the one of the biggest question marks: is the DMA automatically disabled on TC?
|
||||||
|
// Here we assume it is. After all it would make no difference because there is no way
|
||||||
|
// to read the DMA enable flag back, so each time the DMA is needed it has to be enabled again.
|
||||||
|
if (tc) {
|
||||||
|
BIT_CLR(m_flags , HPHYBRID_DMAEN_BIT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
UINT16 hp_hybrid_cpu_device::RM(UINT16 addr)
|
UINT16 hp_hybrid_cpu_device::RM(UINT16 addr)
|
||||||
{
|
{
|
||||||
UINT16 tmp;
|
UINT16 tmp;
|
||||||
|
@ -65,6 +65,8 @@
|
|||||||
class hp_hybrid_cpu_device : public cpu_device
|
class hp_hybrid_cpu_device : public cpu_device
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
DECLARE_WRITE_LINE_MEMBER(dmar_w);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
hp_hybrid_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname);
|
hp_hybrid_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname);
|
||||||
|
|
||||||
@ -124,6 +126,7 @@ private:
|
|||||||
UINT16 get_skip_addr_sc(UINT16 opcode , UINT16& v , unsigned n);
|
UINT16 get_skip_addr_sc(UINT16 opcode , UINT16& v , unsigned n);
|
||||||
void do_pw(UINT16 opcode);
|
void do_pw(UINT16 opcode);
|
||||||
void check_for_interrupts(void);
|
void check_for_interrupts(void);
|
||||||
|
void handle_dma(void);
|
||||||
|
|
||||||
UINT16 RM(UINT16 addr);
|
UINT16 RM(UINT16 addr);
|
||||||
void WM(UINT16 addr , UINT16 v);
|
void WM(UINT16 addr , UINT16 v);
|
||||||
|
Loading…
Reference in New Issue
Block a user