You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			62 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			C++
		
	
			
		
		
	
	
			62 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			C++
		
	
| #include "cmos.h"
 | |
| 
 | |
| #include "core_interrupt.h"
 | |
| #include "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
 |