mirror of
https://github.com/holub/mame
synced 2025-07-04 01:18:59 +03:00
hphybrid: fixed interrupt bug in 5061-3001
This commit is contained in:
parent
d35eed3cd4
commit
fbb38f96b7
@ -1016,12 +1016,12 @@ void hp_hybrid_cpu_device::check_for_interrupts(void)
|
|||||||
m_pa_changed_func((UINT8)CURRENT_PA);
|
m_pa_changed_func((UINT8)CURRENT_PA);
|
||||||
|
|
||||||
// Is this correct? Patent @ pg 210 suggests that the whole interrupt recognition sequence
|
// Is this correct? Patent @ pg 210 suggests that the whole interrupt recognition sequence
|
||||||
// lasts for 32 cycles (6 are already accounted for in get_ea for one indirection)
|
// lasts for 32 cycles
|
||||||
m_icount -= 26;
|
m_icount -= 32;
|
||||||
|
|
||||||
// Do a double-indirect JSM IV,I instruction
|
// Do a double-indirect JSM IV,I instruction
|
||||||
WM(AEC_CASE_C , ++m_reg_R , m_reg_P);
|
WM(AEC_CASE_C , ++m_reg_R , m_reg_P);
|
||||||
m_reg_P = RM(get_ea(0xc008));
|
m_reg_P = RM(AEC_CASE_I , RM(HP_REG_IV_ADDR));
|
||||||
m_reg_I = fetch();
|
m_reg_I = fetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1485,12 +1485,20 @@ UINT32 hp_5061_3001_cpu_device::add_mae(aec_cases_t aec_case , UINT16 addr)
|
|||||||
bsc_reg = HP_REG_R37_ADDR;
|
bsc_reg = HP_REG_R37_ADDR;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
case AEC_CASE_I:
|
||||||
logerror("hphybrid: aec_case=%d\n" , aec_case);
|
// Behaviour of AEC during interrupt vector fetch is undocumented but it can be guessed from 9845B firmware.
|
||||||
return 0;
|
// Basically in this case the integrated AEC seems to do what the discrete implementation in 9845A does:
|
||||||
}
|
// top half of memory is mapped to block 0 (fixed) and bottom half is mapped according to content of R35
|
||||||
|
// (see pg 334 of patent).
|
||||||
|
bsc_reg = top_half ? 0 : HP_REG_R35_ADDR;
|
||||||
|
break;
|
||||||
|
|
||||||
UINT16 aec_reg = m_reg_aec[ bsc_reg - HP_REG_R32_ADDR ] & BSC_REG_MASK;
|
default:
|
||||||
|
logerror("hphybrid: aec_case=%d\n" , aec_case);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT16 aec_reg = (bsc_reg != 0) ? (m_reg_aec[ bsc_reg - HP_REG_R32_ADDR ] & BSC_REG_MASK) : 0;
|
||||||
|
|
||||||
if (m_forced_bsc_25) {
|
if (m_forced_bsc_25) {
|
||||||
aec_reg = (aec_reg & 0xf) | 0x20;
|
aec_reg = (aec_reg & 0xf) | 0x20;
|
||||||
|
@ -90,82 +90,83 @@ public:
|
|||||||
template<class _Object> static devcb_base &set_pa_changed_func(device_t &device, _Object object) { return downcast<hp_hybrid_cpu_device &>(device).m_pa_changed_func.set_callback(object); }
|
template<class _Object> static devcb_base &set_pa_changed_func(device_t &device, _Object object) { return downcast<hp_hybrid_cpu_device &>(device).m_pa_changed_func.set_callback(object); }
|
||||||
|
|
||||||
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 , UINT8 addrwidth);
|
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 , UINT8 addrwidth);
|
||||||
|
|
||||||
// device-level overrides
|
// device-level overrides
|
||||||
virtual void device_start() override;
|
virtual void device_start() override;
|
||||||
virtual void device_reset() override;
|
virtual void device_reset() override;
|
||||||
|
|
||||||
// device_execute_interface overrides
|
// device_execute_interface overrides
|
||||||
virtual UINT32 execute_min_cycles() const override { return 6; }
|
virtual UINT32 execute_min_cycles() const override { return 6; }
|
||||||
virtual UINT32 execute_input_lines() const override { return 2; }
|
virtual UINT32 execute_input_lines() const override { return 2; }
|
||||||
virtual UINT32 execute_default_irq_vector() const override { return 0xffff; }
|
virtual UINT32 execute_default_irq_vector() const override { return 0xffff; }
|
||||||
virtual void execute_run() override;
|
virtual void execute_run() override;
|
||||||
virtual void execute_set_input(int inputnum, int state) override;
|
virtual void execute_set_input(int inputnum, int state) override;
|
||||||
|
|
||||||
UINT16 execute_one(UINT16 opcode);
|
UINT16 execute_one(UINT16 opcode);
|
||||||
UINT16 execute_one_sub(UINT16 opcode);
|
UINT16 execute_one_sub(UINT16 opcode);
|
||||||
// Execute an instruction that doesn't belong to either BPC or IOC
|
// Execute an instruction that doesn't belong to either BPC or IOC
|
||||||
virtual UINT16 execute_no_bpc_ioc(UINT16 opcode) = 0;
|
virtual UINT16 execute_no_bpc_ioc(UINT16 opcode) = 0;
|
||||||
|
|
||||||
// device_memory_interface overrides
|
// device_memory_interface overrides
|
||||||
virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const override { return (spacenum == AS_PROGRAM) ? &m_program_config : ( (spacenum == AS_IO) ? &m_io_config : NULL ); }
|
virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const override { return (spacenum == AS_PROGRAM) ? &m_program_config : ( (spacenum == AS_IO) ? &m_io_config : NULL ); }
|
||||||
|
|
||||||
// device_state_interface overrides
|
// device_state_interface overrides
|
||||||
void state_string_export(const device_state_entry &entry, std::string &str) override;
|
void state_string_export(const device_state_entry &entry, std::string &str) override;
|
||||||
|
|
||||||
// device_disasm_interface overrides
|
// device_disasm_interface overrides
|
||||||
virtual UINT32 disasm_min_opcode_bytes() const override { return 2; }
|
virtual UINT32 disasm_min_opcode_bytes() const override { return 2; }
|
||||||
virtual UINT32 disasm_max_opcode_bytes() const override { return 2; }
|
virtual UINT32 disasm_max_opcode_bytes() const override { return 2; }
|
||||||
virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) override;
|
virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) override;
|
||||||
|
|
||||||
// Different cases of memory access
|
// Different cases of memory access
|
||||||
// See patent @ pg 361
|
// See patent @ pg 361
|
||||||
typedef enum {
|
typedef enum {
|
||||||
AEC_CASE_A, // Instr. fetches, non-base page fetches of link pointers, BPC direct non-base page accesses
|
AEC_CASE_A, // Instr. fetches, non-base page fetches of link pointers, BPC direct non-base page accesses
|
||||||
AEC_CASE_B, // Base page fetches of link pointers, BPC direct base page accesses
|
AEC_CASE_B, // Base page fetches of link pointers, BPC direct base page accesses
|
||||||
AEC_CASE_C, // IOC, EMC & BPC indirect final destination accesses
|
AEC_CASE_C, // IOC, EMC & BPC indirect final destination accesses
|
||||||
AEC_CASE_D // DMA accesses
|
AEC_CASE_D, // DMA accesses
|
||||||
} aec_cases_t;
|
AEC_CASE_I // Interrupt vector fetches
|
||||||
|
} aec_cases_t;
|
||||||
|
|
||||||
// do memory address extension
|
// do memory address extension
|
||||||
virtual UINT32 add_mae(aec_cases_t aec_case , UINT16 addr) = 0;
|
virtual UINT32 add_mae(aec_cases_t aec_case , UINT16 addr) = 0;
|
||||||
|
|
||||||
UINT16 remove_mae(UINT32 addr);
|
UINT16 remove_mae(UINT32 addr);
|
||||||
|
|
||||||
UINT16 RM(aec_cases_t aec_case , UINT16 addr);
|
UINT16 RM(aec_cases_t aec_case , UINT16 addr);
|
||||||
UINT16 RM(UINT32 addr);
|
UINT16 RM(UINT32 addr);
|
||||||
virtual UINT16 read_non_common_reg(UINT16 addr) = 0;
|
virtual UINT16 read_non_common_reg(UINT16 addr) = 0;
|
||||||
|
|
||||||
void WM(aec_cases_t aec_case , UINT16 addr , UINT16 v);
|
void WM(aec_cases_t aec_case , UINT16 addr , UINT16 v);
|
||||||
void WM(UINT32 addr , UINT16 v);
|
void WM(UINT32 addr , UINT16 v);
|
||||||
virtual void write_non_common_reg(UINT16 addr , UINT16 v) = 0;
|
virtual void write_non_common_reg(UINT16 addr , UINT16 v) = 0;
|
||||||
|
|
||||||
UINT16 fetch(void);
|
UINT16 fetch(void);
|
||||||
|
|
||||||
UINT16 get_skip_addr(UINT16 opcode , bool condition) const;
|
UINT16 get_skip_addr(UINT16 opcode , bool condition) const;
|
||||||
|
|
||||||
devcb_write8 m_pa_changed_func;
|
devcb_write8 m_pa_changed_func;
|
||||||
|
|
||||||
int m_icount;
|
int m_icount;
|
||||||
bool m_forced_bsc_25;
|
bool m_forced_bsc_25;
|
||||||
|
|
||||||
// State of processor
|
// State of processor
|
||||||
UINT16 m_reg_A; // Register A
|
UINT16 m_reg_A; // Register A
|
||||||
UINT16 m_reg_B; // Register B
|
UINT16 m_reg_B; // Register B
|
||||||
UINT16 m_reg_P; // Register P
|
UINT16 m_reg_P; // Register P
|
||||||
UINT16 m_reg_R; // Register R
|
UINT16 m_reg_R; // Register R
|
||||||
UINT16 m_reg_C; // Register C
|
UINT16 m_reg_C; // Register C
|
||||||
UINT16 m_reg_D; // Register D
|
UINT16 m_reg_D; // Register D
|
||||||
UINT16 m_reg_IV; // Register IV
|
UINT16 m_reg_IV; // Register IV
|
||||||
UINT16 m_reg_W; // Register W
|
UINT16 m_reg_W; // Register W
|
||||||
UINT8 m_reg_PA[ HPHYBRID_INT_LVLS + 1 ]; // Stack of register PA (4 bit-long)
|
UINT8 m_reg_PA[ HPHYBRID_INT_LVLS + 1 ]; // Stack of register PA (4 bit-long)
|
||||||
UINT16 m_flags; // Flags
|
UINT16 m_flags; // Flags
|
||||||
UINT8 m_dmapa; // DMA peripheral address (4 bits)
|
UINT8 m_dmapa; // DMA peripheral address (4 bits)
|
||||||
UINT16 m_dmama; // DMA address
|
UINT16 m_dmama; // DMA address
|
||||||
UINT16 m_dmac; // DMA counter
|
UINT16 m_dmac; // DMA counter
|
||||||
UINT16 m_reg_I; // Instruction register
|
UINT16 m_reg_I; // Instruction register
|
||||||
UINT32 m_genpc; // Full PC
|
UINT32 m_genpc; // Full PC
|
||||||
|
|
||||||
private:
|
private:
|
||||||
address_space_config m_program_config;
|
address_space_config m_program_config;
|
||||||
|
Loading…
Reference in New Issue
Block a user