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.
		
		
		
		
		
			
		
			
				
	
	
		
			64 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			C++
		
	
			
		
		
	
	
			64 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			C++
		
	
| #include "pic.h"
 | |
| 
 | |
| #include "ioport.h"
 | |
| 
 | |
| namespace PIC {
 | |
| 
 | |
| void initialize() {
 | |
|   // Access primary & secondary PIC via two ports each
 | |
|   IOPort primary_port_a(0x20);
 | |
|   IOPort primary_port_b(0x21);
 | |
|   IOPort secondary_port_a(0xa0);
 | |
|   IOPort secondary_port_b(0xa1);
 | |
| 
 | |
|   // Initialization Command Word 1 (ICW1)
 | |
|   // Basic PIC configuration, starting initialization
 | |
|   enum InitializationCommandWord1 {
 | |
|     ICW4_NEEDED = 1 << 0,  // use Initialization Command Word 4
 | |
|     SINGLE_MODE = 1 << 1,  // Single or multiple (cascade mode)  8259A
 | |
|     ADDRESS_INTERVAL_HALF =
 | |
|         1 << 2,  // 4 or 8 bit interval between the interrupt vector locations
 | |
|     LEVEL_TRIGGERED = 1 << 3,  // Level or edge triggered
 | |
|     ALWAYS_1 = 1 << 4,
 | |
|   };
 | |
|   const uint8_t icw1 = InitializationCommandWord1::ICW4_NEEDED |
 | |
|                        InitializationCommandWord1::ALWAYS_1;
 | |
|   // ICW1 in port A (each)
 | |
|   primary_port_a.outb(icw1);
 | |
|   secondary_port_a.outb(icw1);
 | |
| 
 | |
|   // Initialization Command Word 2 (ICW2):
 | |
|   // Configure interrupt vector base offset in port B
 | |
|   primary_port_b.outb(0x20);    // Primary: IRQ Offset 32
 | |
|   secondary_port_b.outb(0x28);  // Secondary: IRQ Offset 40
 | |
| 
 | |
|   // Initialization Command Word 3 (ICW3):
 | |
|   // Configure pin on primary PIC connected to secondary PIC
 | |
|   const uint8_t pin = 2;          // Secondary connected on primary pin 2
 | |
|   primary_port_b.outb(1 << pin);  // Pin as bit mask for primary
 | |
|   secondary_port_b.outb(pin);     // Pin as value (ID) for secondary
 | |
| 
 | |
|   // Initialization Command Word 4 (ICW4)
 | |
|   // Basic PIC configuration, starting initialization
 | |
|   enum InitializationCommandWord4 {
 | |
|     MODE_8086 = 1 << 0,       // 8086/8088 or 8085 mode
 | |
|     AUTO_EOI = 1 << 1,        // Single or multiple (cascade mode)  8259A
 | |
|     BUFFER_PRIMARY = 1 << 2,  // Primary or secondary buffering
 | |
|     BUFFERED_MODE =
 | |
|         1 << 3,  // Enable or disable buffering (for primary or secondary above)
 | |
|     SPECIAL_FULLY_NESTED = 1 << 4  // Special or non special fully nested
 | |
|   };
 | |
|   const uint8_t icw4 = InitializationCommandWord4::MODE_8086 |
 | |
|                        InitializationCommandWord4::AUTO_EOI;
 | |
|   // ICW3 in port B (each)
 | |
|   primary_port_b.outb(icw4);
 | |
|   secondary_port_b.outb(icw4);
 | |
| 
 | |
|   // Operation Control Word 1 (OCW1):
 | |
|   // Disable (mask) all hardware interrupts on both legacy PICs (we'll use APIC)
 | |
|   secondary_port_b.outb(0xff);
 | |
|   primary_port_b.outb(0xff);
 | |
| }
 | |
| 
 | |
| }  // namespace PIC
 |