diff options
author | Pavel Pisa <pisa@cmp.felk.cvut.cz> | 2019-03-04 15:30:11 +0100 |
---|---|---|
committer | Pavel Pisa <pisa@cmp.felk.cvut.cz> | 2019-03-04 15:30:11 +0100 |
commit | 1dc09ab41ae703a1f15be87cacab5e842cf1a09d (patch) | |
tree | 392908ad6642e1ad5f9afa8c21998665a83534af /qtmips_machine/cop0state.cpp | |
parent | cd3a4b268a9b3d4d5436fee5de7967adb6f6e170 (diff) | |
download | qtmips-1dc09ab41ae703a1f15be87cacab5e842cf1a09d.tar.gz qtmips-1dc09ab41ae703a1f15be87cacab5e842cf1a09d.tar.bz2 qtmips-1dc09ab41ae703a1f15be87cacab5e842cf1a09d.zip |
Implemented interrupt delivery and processing for serial port.
Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
Diffstat (limited to 'qtmips_machine/cop0state.cpp')
-rw-r--r-- | qtmips_machine/cop0state.cpp | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/qtmips_machine/cop0state.cpp b/qtmips_machine/cop0state.cpp index ea937ce..9c5fa1c 100644 --- a/qtmips_machine/cop0state.cpp +++ b/qtmips_machine/cop0state.cpp @@ -91,7 +91,7 @@ const Cop0State::cop0reg_desc_t Cop0State::cop0reg_desc[Cop0State::COP0REGS_CNT] &Cop0State::read_cop0reg_default, &Cop0State::write_cop0reg_default}, [Cop0State::Compare] = {"Compare", 0x00000000, &Cop0State::read_cop0reg_default, &Cop0State::write_cop0reg_default}, - [Cop0State::Status] = {"Status", 0x00000000, + [Cop0State::Status] = {"Status", Status_IE | Status_IntMask, &Cop0State::read_cop0reg_default, &Cop0State::write_cop0reg_default}, [Cop0State::Cause] = {"Cause", 0x00000000, &Cop0State::read_cop0reg_default, &Cop0State::write_cop0reg_default}, @@ -178,3 +178,31 @@ void Cop0State::update_execption_cause(enum ExceptionCause excause, bool in_dela if (excause != EXCAUSE_INT) cop0reg[(int)Cause] |= (int)excause << 2; } + +void Cop0State::set_interrupt_signal(uint irq_num, bool active) { + std::uint32_t mask; + if (irq_num >= 8) + return; + mask = Status_Int0 << irq_num; + if (active) + cop0reg[(int)Cause] |= mask; + else + cop0reg[(int)Cause] &= ~mask; +} + +bool Cop0State::core_interrupt_request() { + std::uint32_t irqs; + irqs = cop0reg[(int)Status]; + irqs &= cop0reg[(int)Cause]; + irqs &= Status_IntMask; + + return !!(irqs && cop0reg[(int)Status] & Status_IntMask && + !(cop0reg[(int)Status] & Status_EXL)); +} + +void Cop0State::set_status_exl(bool value) { + if (value) + cop0reg[(int)Status] |= Status_EXL; + else + cop0reg[(int)Status] &= ~Status_EXL; +} |