Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- term.setTextColor(colors.green)
- local pc = 0
- local rstack = {}
- for i = 0, 31 do
- rstack[i] = i
- end
- local rstack_pointer = 0
- local dstack = {}
- for i = 0, 31 do
- dstack[i] = i
- end
- local dstack_T = 0
- local dstack_N = 0
- local dstack_depth = 0
- local video_ram = {}
- for i = 0, 10239 do
- video_ram[i] = 0x20
- end
- video_ram[0x2600] = 0
- video_ram[0x2602] = 0
- video_ram[0x2604] = 0
- local kbd_buf = {}
- local kbd_buf_head = 0
- local kbd_buf_tail = 0
- for i = 0, 15 do
- kbd_buf[i] = 0
- end
- if not fs.exists("forth_img") then
- shell.run("pastebin", "get", "0QuVj5Zy", "forth_img")
- end
- local ram = {}
- local forth_file = assert(io.open("forth_img", "r"))
- for i = 0, 0x1FFF do
- ram[i] = tonumber(forth_file:read())
- end
- forth_file:close()
- -- Default: 51x19
- function display_all()
- local i = video_ram[0x2600]
- local cursor_x = video_ram[0x2602]
- local cursor_y = video_ram[0x2604]
- for y = 0, 18 do
- local str = ""
- for x = 0, 50 do
- str = str..string.char(video_ram[i * 128 + x])
- end
- term.setCursorPos(1, y + 1)
- term.write(str)
- i = (i + 1) % 19
- end
- term.setCursorPos(cursor_x + 1, cursor_y + 1)
- end
- function save_ram(filename)
- local forth_file = assert(io.open(filename, "w"))
- for i = 0, 0x1FFF do
- forth_file:write(tostring(ram[i]))
- forth_file:write("\n")
- end
- forth_file:close()
- end
- function read_mem(addr)
- local a = bit.band(addr, 0xFFFE)
- if addr < 0x4000 then
- return ram[bit.blogic_rshift(addr, 1)]
- elseif a == 0x7000 then
- return kbd_buf_head
- elseif a == 0x7002 then
- return kbd_buf_tail
- elseif a == 0x7004 then
- return kbd_buf[kbd_buf_head]
- else
- return 0
- end
- end
- function write_mem(addr, data)
- local a = bit.band(addr, 0xFFFE)
- if addr < 0x4000 then
- ram[bit.blogic_rshift(addr, 1)] = data
- elseif (addr >= 0x4000) and (addr < (0x4000 + 10240)) then
- video_ram[addr - 0x4000] = data
- --print("addr = "..(addr - 0x4000).." data = "..data)
- elseif addr == 0x7000 then
- kbd_buf_head = bit.band(data, 0x0F)
- end
- end
- function ALU(op, read_mem)
- if op == 0 then return dstack_T
- elseif op == 1 then return dstack_N
- elseif op == 2 then return bit.band(dstack_T + dstack_N, 0xFFFF)
- elseif op == 3 then return bit.band(dstack_T, dstack_N)
- elseif op == 4 then return bit.bor(dstack_T, dstack_N)
- elseif op == 5 then return bit.bor(bit.band(bit.blshift(dstack_T, 8), 0xFF00), bit.band(bit.blogic_rshift(dstack_T, 8), 0xFF))
- elseif op == 6 then return bit.band(bit.bnot(dstack_T), 0xFFFF)
- elseif op == 7 then
- if dstack_N == dstack_T then
- return 0xFFFF
- else
- return 0
- end
- elseif op == 8 then
- -- N < T
- --print("T = "..dstack_T.." N = "..dstack_N)
- if (bit.band(dstack_N, 0x8000) ~= 0) or (bit.band(dstack_T, 0x8000) ~= 0) then
- if dstack_N >= dstack_T then
- return 0
- else
- return 0xFFFF
- end
- elseif bit.band(dstack_N, 0x8000) ~= 0 then
- return 0xFFFF
- elseif bit.band(dstack_T, 0x8000) ~= 0 then
- return 0
- else
- if dstack_N < dstack_T then
- return 0xFFFF
- else
- return 0
- end
- end
- elseif op == 9 then return bit.blogic_rshift(dstack_T, 1)
- elseif op == 10 then return bit.band(dstack_T - 1, 0xFFFF)
- elseif op == 11 then return rstack[rstack_pointer]
- elseif op == 12 then return read_mem(dstack_T)
- elseif op == 13 then return bit.band(bit.blshift(dstack_T, 1), 0xFFFF)
- elseif op == 14 then return dstack_depth
- elseif op == 15 then
- if dstack_N < dstack_T then
- return 0xFFFF
- else
- return 0
- end
- else
- print("Invalid ALU operation. op = "..op)
- end
- end
- function execute_insn(read_mem, write_mem)
- local dstack_T_buf = dstack_T
- local istr = read_mem(bit.blshift(pc, 1))
- if bit.band(istr, 0x8000) == 0x8000 then
- -- literal.
- --print("literal pc = "..pc.." T = "..bit.band(istr, 0x7FFF))
- dstack_depth = bit.band(dstack_depth + 1, 0x1F)
- dstack[dstack_depth] = dstack_N
- dstack_N = dstack_T
- dstack_T = bit.band(istr, 0x7FFF)
- pc = bit.band(pc + 1, 0x1FFF)
- elseif bit.band(istr, 0xE000) == 0 then
- -- jump.
- --print("jump pc = "..pc)
- pc = bit.band(istr, 0x1FFF)
- elseif bit.band(istr, 0xE000) == 0x2000 then
- -- conditional jump.
- --print("cond_jump pc = "..pc)
- if dstack_T ~= 0 then
- pc = bit.band(pc + 1, 0x1FFF)
- else
- pc = bit.band(istr, 0x1FFF)
- end
- dstack_T = dstack_N
- dstack_N = dstack[dstack_depth]
- dstack_depth = bit.band(dstack_depth - 1, 0x1F)
- elseif bit.band(istr, 0xE000) == 0x4000 then
- -- call.
- --print("call pc = "..pc)
- rstack_pointer = bit.band(rstack_pointer + 1, 0x1F)
- rstack[rstack_pointer] = bit.blshift(bit.band(pc + 1, 0x1FFF), 1)
- pc = bit.band(istr, 0x1FFF)
- elseif bit.band(istr, 0xE000) == 0x6000 then
- -- ALU.
- --print("ALU pc = "..pc)
- -- N -> [T]
- if bit.band(istr, 0x20) ~= 0 then
- write_mem(dstack_T, dstack_N)
- end
- -- dstack+-
- if bit.band(istr, 3) == 0 then
- dstack_T = ALU(bit.band(bit.blogic_rshift(istr, 8), 0x0F), read_mem)
- if bit.band(istr, 0x80) ~= 0 then dstack_N = dstack_T_buf end -- T -> N
- elseif bit.band(istr, 3) == 1 then
- dstack_T = ALU(bit.band(bit.blogic_rshift(istr, 8), 0x0F), read_mem)
- dstack_depth = bit.band(dstack_depth + 1, 0x1F)
- dstack[dstack_depth] = dstack_N
- if bit.band(istr, 0x80) ~= 0 then dstack_N = dstack_T_buf end -- T -> N
- elseif bit.band(istr, 3) == 3 then
- dstack_T = ALU(bit.band(bit.blogic_rshift(istr, 8), 0x0F), read_mem)
- dstack_N = dstack[dstack_depth]
- dstack_depth = bit.band(dstack_depth - 1, 0x1F)
- else
- -- Error.
- end
- -- R -> PC
- if bit.band(istr, 0x1000) ~= 0 then
- pc = bit.blogic_rshift(rstack[rstack_pointer], 1)
- else
- pc = bit.band(pc + 1, 0x1FFF)
- end
- -- rstack+-
- if bit.band(istr, 0xC) == 4 then
- rstack_pointer = bit.band(rstack_pointer + 1, 0x1F)
- rstack[rstack_pointer] = dstack_T_buf
- elseif bit.band(istr, 0xC) == 0xC then
- rstack_pointer = bit.band(rstack_pointer - 1, 0x1F)
- end
- end
- end
- while true do
- for i = 0, 1000 do
- execute_insn(read_mem, write_mem)
- end
- display_all()
- os.startTimer(0.05)
- local key = 0xFF
- local event, p = os.pullEvent()
- if event == "key" then
- if p == 28 then
- key = 0x0D
- elseif p == 14 then
- key = 0x08
- end
- elseif event == "char" then
- key = string.byte(p)
- end
- if (key ~= 0xFF) and (((kbd_buf_tail + 1) % 16) ~= kbd_buf_head) then
- kbd_buf_tail = (kbd_buf_tail + 1) % 16
- kbd_buf[kbd_buf_tail] = key
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment