Lua 5.3 didn't need an x86 emulator. But now, it has one regardless.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

keyboard.lua 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. -- TODO: The keyboard code is a massive hack which in no way reflects real hardware.
  2. -- joysticks (for now)
  3. cpu_port_set(0x201, function(cond,val)
  4. if not val then
  5. return 0
  6. end
  7. end)
  8. local charqueue = {}
  9. local kbd_data_queue = {}
  10. local function populate_bitmask(kz)
  11. local keys = 0
  12. for i,k in ipairs(kz) do
  13. if k >= 0 and platform_key_down(k) then
  14. keys = keys | (1 << (i - 1))
  15. end
  16. end
  17. return keys
  18. end
  19. function keyboard_update()
  20. RAM[0x417] = populate_bitmask({0x36, 0x2A, 0x1D, 0x38, 0x46, -1, 0x3A, 0x52})
  21. RAM[0x418] = populate_bitmask({-1, -1, -1, -1, -1, -1, -1, -1})
  22. end
  23. function kbd_send_ibm(code, chr)
  24. while #kbd_data_queue > 0 do table.remove(kbd_data_queue, 1) end
  25. if code <= 0x7F then
  26. table.insert(charqueue, {code, chr or 0})
  27. end
  28. table.insert(kbd_data_queue, code)
  29. emu_debug(2, string.format("kbd_send_ibm: %02X", code))
  30. if pic_interrupt_enabled(PIC_INTERRUPT_KEYBOARD) then
  31. cpu_emit_interrupt(9, false)
  32. end
  33. end
  34. RAM[0x471] = 0 -- break key check
  35. RAM[0x496] = 0 -- keyboard mode/type
  36. RAM[0x497] = 0 -- keyboard LED flags
  37. RAM[0x417] = 0 -- keyboard flags 1
  38. RAM[0x418] = 0 -- keyboard flags 2
  39. local kbd_port_b = 0x03
  40. local kbd_spkr_latch = 0
  41. function kbd_get_spkr_latch()
  42. local v = kbd_spkr_latch
  43. kbd_spkr_latch = 0
  44. return v
  45. end
  46. function kbd_get_port_b()
  47. return kbd_port_b
  48. end
  49. local kbd_status = 0x10
  50. local kbd_a2 = 0
  51. -- keyboard I/O
  52. cpu_port_set(0x60, function(cond,val)
  53. if not val then
  54. emu_debug(1, string.format("kbd 0060: read"))
  55. if #kbd_data_queue > 0 then
  56. local v = kbd_data_queue[1]
  57. table.remove(kbd_data_queue, 1)
  58. if type(v) == "table" then return v[1] end
  59. return v
  60. end
  61. return 0x00
  62. else
  63. kbd_a2 = 0
  64. emu_debug(1, string.format("kbd 0060: received %02X", val))
  65. if val == 5 then -- TODO: What is this?
  66. kbd_data_queue = {}
  67. table.insert(kbd_data_queue, 0x00)
  68. table.insert(kbd_data_queue, 0x00)
  69. table.insert(kbd_data_queue, 0x00)
  70. end
  71. end
  72. end)
  73. cpu_port_set(0x61, function(cond,val)
  74. if not val then
  75. emu_debug(1, "kbd port b read")
  76. return kbd_port_b
  77. else
  78. emu_debug(1, "kbd port b write " .. val)
  79. kbd_port_b = val
  80. kbd_spkr_latch = kbd_spkr_latch | val
  81. end
  82. end)
  83. cpu_port_set(0x64, function(cond,val)
  84. if not val then
  85. emu_debug(1, string.format("kbd 0064: read"))
  86. local v = kbd_status | (kbd_a2 << 3)
  87. if #kbd_data_queue > 0 then
  88. kbd_status = kbd_status ~ 3
  89. else
  90. kbd_status = kbd_status & (0xFC)
  91. end
  92. return v
  93. else
  94. kbd_a2 = 1
  95. emu_debug(1, string.format("kbd 0064: received %02X", val))
  96. end
  97. end)
  98. cpu_register_interrupt_handler(0x16, function(ax,ah,al)
  99. if (ah == 0x00) then
  100. local bios, ascii = nil, nil
  101. local dd = nil
  102. if type(charqueue[1]) == "table" then
  103. dd = charqueue[1]
  104. table.remove(charqueue, 1)
  105. end
  106. if dd ~= nil then
  107. bios = dd[1]
  108. ascii = dd[2]
  109. end
  110. if bios == nil then
  111. cpu_set_flag(6)
  112. return "block"
  113. else
  114. cpu_clear_flag(6)
  115. CPU["regs"][1] = ((bios & 0xFF) << 8) | (ascii & 0xFF)
  116. return true
  117. end
  118. elseif (ah == 0x01) then
  119. -- check for keystroke
  120. local ascii, bios = nil, nil
  121. if (#charqueue > 0) and type(charqueue[1]) == "table" then
  122. ascii = charqueue[1][2]
  123. bios = charqueue[1][1]
  124. end
  125. if bios == nil then
  126. cpu_set_flag(6)
  127. return true
  128. else
  129. cpu_clear_flag(6)
  130. CPU["regs"][1] = ((bios & 0xFF) << 8) | (ascii & 0xFF)
  131. return true
  132. end
  133. elseif (ah == 0x02) then
  134. -- query shift flags
  135. if ah == 0x12 then
  136. ah = RAM[0x418]
  137. end
  138. al = RAM[0x417]
  139. CPU["regs"][1] = (ah << 8) | al
  140. return true
  141. else
  142. cpu_set_flag(0)
  143. end
  144. end)