p1rx

FORTH CPU

Sep 11th, 2014
182
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.66 KB | None | 0 0
  1. term.setTextColor(colors.green)
  2.  
  3. local pc = 0
  4.  
  5. local rstack = {}
  6. for i = 0, 31 do
  7.   rstack[i] = i
  8. end
  9. local rstack_pointer = 0
  10.  
  11. local dstack = {}
  12. for i = 0, 31 do
  13.   dstack[i] = i
  14. end
  15. local dstack_T = 0
  16. local dstack_N = 0
  17. local dstack_depth = 0
  18.  
  19. local video_ram = {}
  20. for i = 0, 10239 do
  21.   video_ram[i] = 0x20
  22. end
  23. video_ram[0x2600] = 0
  24. video_ram[0x2602] = 0
  25. video_ram[0x2604] = 0
  26.  
  27. local kbd_buf = {}
  28. local kbd_buf_head = 0
  29. local kbd_buf_tail = 0
  30. for i = 0, 15 do
  31.   kbd_buf[i] = 0
  32. end
  33.  
  34. if not fs.exists("forth_img") then
  35.   shell.run("pastebin", "get", "0QuVj5Zy", "forth_img")
  36. end
  37. local ram = {}
  38. local forth_file = assert(io.open("forth_img", "r"))
  39. for i = 0, 0x1FFF do
  40.   ram[i] = tonumber(forth_file:read())
  41. end
  42. forth_file:close()
  43.  
  44. -- Default: 51x19
  45. function display_all()
  46.   local i = video_ram[0x2600]
  47.   local cursor_x = video_ram[0x2602]
  48.   local cursor_y = video_ram[0x2604]
  49.   for y = 0, 18 do
  50.     local str = ""
  51.     for x = 0, 50 do
  52.       str = str..string.char(video_ram[i * 128 + x])
  53.     end
  54.     term.setCursorPos(1, y + 1)
  55.     term.write(str)
  56.     i = (i + 1) % 19
  57.   end
  58.   term.setCursorPos(cursor_x + 1, cursor_y + 1)
  59. end
  60.  
  61. function save_ram(filename)
  62.   local forth_file = assert(io.open(filename, "w"))
  63.   for i = 0, 0x1FFF do
  64.     forth_file:write(tostring(ram[i]))
  65.     forth_file:write("\n")
  66.   end
  67.   forth_file:close()
  68. end
  69.  
  70. function read_mem(addr)
  71.   local a = bit.band(addr, 0xFFFE)
  72.   if addr < 0x4000 then
  73.     return ram[bit.blogic_rshift(addr, 1)]
  74.   elseif a == 0x7000 then
  75.     return kbd_buf_head
  76.   elseif a == 0x7002 then
  77.     return kbd_buf_tail
  78.   elseif a == 0x7004 then
  79.     return kbd_buf[kbd_buf_head]
  80.   else
  81.     return 0
  82.   end
  83. end
  84.  
  85. function write_mem(addr, data)
  86.   local a = bit.band(addr, 0xFFFE)
  87.   if addr < 0x4000 then
  88.     ram[bit.blogic_rshift(addr, 1)] = data
  89.   elseif (addr >= 0x4000) and (addr < (0x4000 + 10240)) then
  90.     video_ram[addr - 0x4000] = data
  91.     --print("addr = "..(addr - 0x4000).." data = "..data)
  92.   elseif addr == 0x7000 then
  93.     kbd_buf_head = bit.band(data, 0x0F)
  94.   end
  95. end
  96.  
  97. function ALU(op, read_mem)
  98.   if op == 0 then return dstack_T
  99.   elseif op == 1 then return dstack_N
  100.   elseif op == 2 then return bit.band(dstack_T + dstack_N, 0xFFFF)
  101.   elseif op == 3 then return bit.band(dstack_T, dstack_N)
  102.   elseif op == 4 then return bit.bor(dstack_T, dstack_N)
  103.   elseif op == 5 then return bit.bor(bit.band(bit.blshift(dstack_T, 8), 0xFF00), bit.band(bit.blogic_rshift(dstack_T, 8), 0xFF))
  104.   elseif op == 6 then return bit.band(bit.bnot(dstack_T), 0xFFFF)
  105.   elseif op == 7 then
  106.     if dstack_N == dstack_T then
  107.       return 0xFFFF
  108.     else
  109.       return 0
  110.     end
  111.   elseif op == 8 then
  112.     -- N < T
  113.     --print("T = "..dstack_T.." N = "..dstack_N)
  114.     if (bit.band(dstack_N, 0x8000) ~= 0) or (bit.band(dstack_T, 0x8000) ~= 0) then
  115.       if dstack_N >= dstack_T then
  116.         return 0
  117.       else
  118.         return 0xFFFF
  119.       end
  120.     elseif bit.band(dstack_N, 0x8000) ~= 0 then
  121.       return 0xFFFF
  122.     elseif bit.band(dstack_T, 0x8000) ~= 0 then
  123.       return 0
  124.     else
  125.       if dstack_N < dstack_T then
  126.         return 0xFFFF
  127.       else
  128.         return 0
  129.       end
  130.     end
  131.   elseif op == 9 then return bit.blogic_rshift(dstack_T, 1)
  132.   elseif op == 10 then return bit.band(dstack_T - 1, 0xFFFF)
  133.   elseif op == 11 then return rstack[rstack_pointer]
  134.   elseif op == 12 then return read_mem(dstack_T)
  135.   elseif op == 13 then return bit.band(bit.blshift(dstack_T, 1), 0xFFFF)
  136.   elseif op == 14 then return dstack_depth
  137.   elseif op == 15 then
  138.     if dstack_N < dstack_T then
  139.       return 0xFFFF
  140.     else
  141.       return 0
  142.     end
  143.   else
  144.     print("Invalid ALU operation. op = "..op)
  145.   end
  146. end
  147.  
  148. function execute_insn(read_mem, write_mem)
  149.   local dstack_T_buf = dstack_T
  150.   local istr = read_mem(bit.blshift(pc, 1))
  151.  
  152.   if bit.band(istr, 0x8000) == 0x8000 then
  153.     -- literal.
  154.     --print("literal pc = "..pc.." T = "..bit.band(istr, 0x7FFF))
  155.     dstack_depth = bit.band(dstack_depth + 1, 0x1F)
  156.     dstack[dstack_depth] = dstack_N
  157.     dstack_N = dstack_T
  158.     dstack_T = bit.band(istr, 0x7FFF)
  159.     pc = bit.band(pc + 1, 0x1FFF)
  160.   elseif bit.band(istr, 0xE000) == 0 then
  161.     -- jump.
  162.     --print("jump pc = "..pc)
  163.     pc = bit.band(istr, 0x1FFF)
  164.   elseif bit.band(istr, 0xE000) == 0x2000 then
  165.     -- conditional jump.
  166.     --print("cond_jump pc = "..pc)
  167.     if dstack_T ~= 0 then
  168.       pc = bit.band(pc + 1, 0x1FFF)
  169.     else
  170.       pc = bit.band(istr, 0x1FFF)
  171.     end
  172.     dstack_T = dstack_N
  173.     dstack_N = dstack[dstack_depth]
  174.     dstack_depth = bit.band(dstack_depth - 1, 0x1F)
  175.   elseif bit.band(istr, 0xE000) == 0x4000 then
  176.     -- call.
  177.     --print("call pc = "..pc)
  178.     rstack_pointer = bit.band(rstack_pointer + 1, 0x1F)
  179.     rstack[rstack_pointer] = bit.blshift(bit.band(pc + 1, 0x1FFF), 1)
  180.     pc = bit.band(istr, 0x1FFF)
  181.   elseif bit.band(istr, 0xE000) == 0x6000 then
  182.     -- ALU.
  183.     --print("ALU pc = "..pc)
  184.     -- N -> [T]
  185.     if bit.band(istr, 0x20) ~= 0 then
  186.       write_mem(dstack_T, dstack_N)
  187.     end
  188.     -- dstack+-
  189.     if bit.band(istr, 3) == 0 then
  190.       dstack_T = ALU(bit.band(bit.blogic_rshift(istr, 8), 0x0F), read_mem)
  191.       if bit.band(istr, 0x80) ~= 0 then dstack_N = dstack_T_buf end -- T -> N
  192.     elseif bit.band(istr, 3) == 1 then
  193.       dstack_T = ALU(bit.band(bit.blogic_rshift(istr, 8), 0x0F), read_mem)
  194.       dstack_depth = bit.band(dstack_depth + 1, 0x1F)
  195.       dstack[dstack_depth] = dstack_N
  196.       if bit.band(istr, 0x80) ~= 0 then dstack_N = dstack_T_buf end -- T -> N
  197.     elseif bit.band(istr, 3) == 3 then
  198.       dstack_T = ALU(bit.band(bit.blogic_rshift(istr, 8), 0x0F), read_mem)
  199.       dstack_N = dstack[dstack_depth]
  200.       dstack_depth = bit.band(dstack_depth - 1, 0x1F)
  201.     else
  202.       -- Error.
  203.     end
  204.     -- R -> PC
  205.     if bit.band(istr, 0x1000) ~= 0 then
  206.       pc = bit.blogic_rshift(rstack[rstack_pointer], 1)
  207.     else
  208.       pc = bit.band(pc + 1, 0x1FFF)
  209.     end
  210.     -- rstack+-
  211.     if bit.band(istr, 0xC) == 4 then
  212.       rstack_pointer = bit.band(rstack_pointer + 1, 0x1F)
  213.       rstack[rstack_pointer] = dstack_T_buf
  214.     elseif bit.band(istr, 0xC) == 0xC then
  215.       rstack_pointer = bit.band(rstack_pointer - 1, 0x1F)
  216.     end
  217.   end
  218. end
  219.  
  220. while true do
  221.   for i = 0, 1000 do
  222.     execute_insn(read_mem, write_mem)
  223.   end
  224.   display_all()
  225.  
  226.   os.startTimer(0.05)
  227.   local key = 0xFF
  228.   local event, p = os.pullEvent()
  229.   if event == "key" then
  230.     if p == 28 then
  231.       key = 0x0D
  232.     elseif p == 14 then
  233.       key = 0x08
  234.     end
  235.   elseif event == "char" then
  236.     key = string.byte(p)
  237.   end
  238.   if (key ~= 0xFF) and (((kbd_buf_tail + 1) % 16) ~= kbd_buf_head) then
  239.     kbd_buf_tail = (kbd_buf_tail + 1) % 16
  240.     kbd_buf[kbd_buf_tail] = key
  241.   end
  242. end
Advertisement
Add Comment
Please, Sign In to add comment