use32
org 0x10000

include "toyos.inc"

idt = 00000500h
keyStateMap = idt + 2048

codeSel = 8       ; Selector for 32 bit code
dataSel = 16      ; Selector for 32 bit data

start:

   mov  eax, dataSel
   mov  ds, eax
   mov  es, eax
   mov  ss, eax
   mov  esp, 90000h

   virtual at edi
      idtEntry interruptDesc ?,?,?
   end virtual

   ; Initialize the IDT:
   mov  edi, idt
   mov  ecx, 256

   GenIdtLoop:

      mov  [idtEntry.offset0_15], dummyIntHandler and 0xFFFF
      mov  [idtEntry.selector], codeSel
      mov  [idtEntry.flags], intHandlerFlags
      mov  [idtEntry.offset16_31], dummyIntHandler shr 16

      add  edi, 8
      dec  ecx
   jnz  byte GenIdtLoop

   ; Point INT 09h to the keyboard handler:
   mov  edi, idt + 9*8
   mov  [idtEntry.offset0_15], keyboardIntHandler and 0xFFFF
   mov  [idtEntry.offset16_31], keyboardIntHandler shr 16

   push dword idt
   push word (256*8)
   lidt [esp]
   add  esp, 6

   ; Initialize key state map:
   xor  eax, eax
   mov  edi, keyStateMap
   mov  ecx, 128 / 4
   rep  stosd

   sti

   endlessLoop:
      inc  word [0xB8000]
   jmp  byte endlessLoop

dummyIntHandler:
   iretd

keyboardIntHandler:
   push eax
   push ebx
   push ds

   mov  eax, dataSel
   mov  ds, eax

   ; A grey-on-blue 'A' should appear at (1,0) on the
   ;   screen as soon as a key is pressed:
   mov  al, 'A'
   mov  ah, 0x17
   mov  [0xB8002], ax

   ; Update the key state map:
   xor  eax, eax
   mov  bl, 1
   in   al, 60h
   test al, 80h
   jz   byte @F
     and  al, 7Fh
     dec  bl
   @@:
   mov  [keyStateMap+eax], bl

   pop  ds
   pop  ebx
   pop  eax

   iretd
