[BITS 64] [ORG 0000000000200000h] %INCLUDE "bmdev.asm" start: ; Start of program label mov rsi, 5060h ; Read the LOCAL_APIC address from the Pure64 infomap lodsq mov [LOCAL_APIC], rax cli ; Disable interrupts sidt [IDTR] ; Store value of IDTR to memory (2 + 8 bytes) lea rbx, [IDTR + 2] ; Select offset from IDTR mov rbx, [rbx] ; Read offset of IDT into RBX lea rbx, [rbx + 16 * 28h] ; Address of RTC IDT entry xor rax, rax ; Address of new interrupt handler mov eax, [rbx + 8] ; Load upper 32 bits of old interrupt handler from offset 8 shl rax, 32 mov ax, [rbx + 6] ; Load next 16 bits of old interrupt handler from offset 6 shl rax, 16 mov ax, [rbx] ; Load remaining 16 bits of old interrupt handler from offset 0 mov [ORIGINAL_HANDLER], rax ; Store address of old interrupt handler lea rax, [custom_interrupt_handler] ; Address of custom interrupt to insert mov [rbx], ax ; Store lower 16 bits of new interrupt handler at offset 0 shr rax, 16 ; Store next 16 bits of new interrupt handler at offset 6 mov [rbx + 6], ax shr rax, 16 ; Store remaining 32 bits of new interrupt handler at offset 8 mov [rbx + 8], eax sti ; Enable interrupts loop: xor rax, rax ; Check value of FLAG mov al, [FLAG] test al, al jz loop ; Loop while value is 0 mov byte [FLAG], 0 mov rsi, hello_message ; Load RSI with memory address of string call b_print_string ; Print the string that RSI points to ret ; Return to OS LOCAL_APIC: times 8 db 0 IDTR: times 10 db 0 ORIGINAL_HANDLER: times 8 db 0 FLAG: db 0 hello_message: db 'Hello, world!', 13, 0 COUNT: db 0 custom_interrupt_handler: inc byte [COUNT] cmp byte [COUNT], 8 jne end_custom_interrupt_handler mov byte [FLAG], 1 end_custom_interrupt_handler: push rax ; Save rax push rsi ; Save rsi mov al, 0Ch ; Select RTC register C out 70h, al ; Port 0x70 is the RTC index, and 0x71 is the RTC data in al, 71h ; Read the value in register C mov rsi, [LOCAL_APIC]; Acknowledge the IRQ on LOCAL_APIC xor eax, eax mov dword [rsi + 0B0h], eax pop rsi ; Restore rsi pop rax ; Restore rax iretq