title: Real mode Interrupt handling routine not working as expected
body: <p>I managed to load a small kernel into memory via a bootloader that performs a far jump to <code>0x0090:0x0000</code>. The kernel is loaded successfully as I print a character from there to test it and it works properly.</p>
  
  <p>I wanted to remap interrupts <code>0x08-&gt;0x0F</code> and <code>0x70-&gt;0x77</code> to interrupts <code>0x20-&gt;0x2F</code>, so the exception/reserved interrupts are not overlapped. So far, I am only handling a keyboard press and attempting to print it to the screen.<br>I went over it a bunch of times and for some reason, I just don't know why but nothing happens when I press a key.<br>
  The keymap is just an array of the scancodes to their respected ASCII value.</p>
  
  <p>If this is of any help: I tested running a loop and printing a character then <code>HLT</code>ing, and once 2 characters were printed, it hanged. I made sure to enable interrupts.<br>
  (I'm loading 4 sectors (from sector 2 to sector 5) for the bootloader which is why I'm padding this to make it 2048 bytes in size).</p>
  
  <p>By the way,  I don't have to <code>CLI</code> in my interrupt procedures since it's done for me, right? I remember reading this but I am not too sure.</p>
  
  <pre><code>BITS 16
  ORG 0x0000
  
  ; Setup Segments ;
  cli
  cld
  mov ax, cs
  mov ds, ax              ; this program was far-jumped to (0x0090:0x0000) so ds = cs = 0x0090
  mov ax, VIDEO_ORIGIN
  mov es, ax
  
  ; Remap PIC Interrupt Vector Offsets to 0x20 -&gt; 0x35 ;
  remapInterrupts:
      ; Send Initialization Command (expecting ICW4)
      mov al, 0x11
      out 0x20, al
      out 0xA0, al
  
      ; Remap Vector Offsets (ICW2)
      mov al, 0x20        ; Master IRQ lines mapped to 0x20 -&gt; 0x27
      out 0x21, al
      mov al, 0x28        ; Slave IRQ lines mapped to 0x28 -&gt; 0x2F
      out 0xA1, al
  
      ; Set Cascade Lines between Master and Slave PICs (ICW3)
      mov al, 0x04        ; 00000100 (line 2)
      out 0x21, al
      mov al, 0x02        ; 00000010 (line 2 in binary, cascade identity)
      out 0xA1, al
  
      ; Set 80x86 Mode (ICW4)
      mov al, 0x01
      out 0x21, al
      out 0xA1, al
  
      ; Set Masks
      mov al, 0xFD        ; 11111101 (keyboard)
      out 0x21, al
      mov al, 0xFF        ; 11111111
      out 0xA1, al
  
  setInterrupts:
      push ds
      mov ax, 0x0000
      mov ds, ax
      mov [ds:0x84], word interrupt21     ; 0x84 = 0x21 * 4
      mov [ds:0x86], cs
      pop ds
      jmp start
  
      interrupt20:                ; Programmable Interval Timer
          ; NOT SUPPORTED, place holder
          push ax
          mov al, 0x20
          out 0x20, al
          pop ax
          iret
      interrupt21:                ; Keyboard
          push ax
          push bx
          in al, 0x60
          test al, 0x80           ; high-bit set = keyup = don't print
          jnz .finish
          movzx bx, al
          mov al, [keymap + bx]
          mov ah, 0x07
          stosw
  
          .finish:
          mov al, 0x20
          out 0x20, al
  
          pop bx
          pop ax
          iret
      interrupt22:                ; Slave Cascade
      interrupt23:                ; COM2 / COM4
      interrupt24:                ; COM1 / COM3
      interrupt25:                ; LPT2
      interrupt26:                ; Floppy controller
      interrupt27:                ; LPT1
          ; NOT SUPPORTED, place holder
          push ax
          mov al, 0x20
          out 0x20, al
          pop ax
          iret
      interrupt28:                ; RTC
      interrupt29:                ; Unassigned
      interrupt2A:                ; Unassigned
      interrupt2B:                ; Unassigned
      interrupt2C:                ; Mouse Controller
      interrupt2D:                ; Math Coprocessor
      interrupt2E:                ; Hard Disk Controller 1
      interrupt2F:                ; Hard Disk Controller 2
          ; NOT SUPPORTED, place holder
          push ax
          mov al, 0x20
          out 0xA0, al
          out 0x20, al
          pop ax
          iret
  
  start:
      sti
      xor di, di
      jmp $
  
  ; --- CONSTANTS --- ;
  VIDEO_ORIGIN EQU 0xB800
  
  ; --- DATA --- ;
  drive db 0
  keymap:
      db 00h, 1Bh, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 08h, 09h
      db 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '[', ']', 00h, 00h
      db 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', "'", '`', 00h, '\'
      db 'Z', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/', 00h, 00h, 00h, ' ', 00h,
      db 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h,
      db '-', 00h, 00h, 00h, '+', 00h, 00h, 00h, 00h, 00h
  
  times 2048 - ($ - $$) db 0
  </code></pre>