forked from BSB-WS23/mpstubs
62 lines
1.2 KiB
C++
62 lines
1.2 KiB
C++
#include "machine/cmos.h"
|
|
|
|
#include "machine/core.h"
|
|
#include "machine/ioport.h"
|
|
|
|
namespace CMOS {
|
|
static IOPort address(0x70);
|
|
static IOPort data(0x71);
|
|
|
|
namespace NMI {
|
|
static const uint8_t mask = 0x80;
|
|
// Cache NMI to speed things up
|
|
static bool disabled = false;
|
|
|
|
void enable() {
|
|
bool status = Core::Interrupt::disable();
|
|
uint8_t value = address.inb();
|
|
value &= ~mask;
|
|
address.outb(value);
|
|
Core::Interrupt::restore(status);
|
|
disabled = false;
|
|
}
|
|
|
|
void disable() {
|
|
bool status = Core::Interrupt::disable();
|
|
uint8_t value = address.inb();
|
|
value |= mask;
|
|
address.outb(value);
|
|
Core::Interrupt::restore(status);
|
|
disabled = true;
|
|
}
|
|
|
|
bool isEnabled() {
|
|
disabled = (address.inb() & mask) != 0;
|
|
return !disabled;
|
|
}
|
|
} // namespace NMI
|
|
|
|
static void setAddress(enum Register reg) {
|
|
uint8_t value = reg;
|
|
// The highest bit controls the Non Maskable Interrupt
|
|
// so we don't want to accidentally change it.
|
|
if (NMI::disabled) {
|
|
value |= NMI::mask;
|
|
} else {
|
|
value &= ~NMI::mask;
|
|
}
|
|
address.outb(value);
|
|
}
|
|
|
|
uint8_t read(enum Register reg) {
|
|
setAddress(reg);
|
|
return data.inb();
|
|
}
|
|
|
|
void write(enum Register reg, uint8_t value) {
|
|
setAddress(reg);
|
|
data.outb(value);
|
|
}
|
|
|
|
} // namespace CMOS
|