Added a few instructions

This commit is contained in:
Izaya 2017-01-25 12:13:39 +11:00
parent 6c99d1b3c6
commit a06d1c5f76
3 changed files with 72 additions and 20 deletions

View File

@ -13,16 +13,21 @@ The T400 is a 12-bit stack machine operating at 1Hz (due to ABMs only running on
### Instructions ### Instructions
There are 8 instructions for the T400. Any values encountered by the processor that are not instructions are treated as data and pushed to the stack. While this does make both the code for the emulator and the code for the emulated computer simple, it has the downside that if you really do want the value 4095 you have to add two things together. There are 8 instructions for the T400. Any values encountered by the processor that are not instructions are treated as data and pushed to the stack. While this does make both the code for the emulator and the code for the emulated computer simple, it has the downside that if you really do want the value 4095 you have to add two things together.
| ins | function | mnemonic | | ins | function | mnemonic |
|--------|------------------------------|---------------| |--------|----------------------------------------------|---------------|
|4095 | push program counter | ppc | |4095 | push program counter | ppc |
|4094 | swap TOS | swp | |4094 | swap TOS | swp |
|4093 | read memory from TOS | read | |4093 | read memory from TOS | read |
|4092 | write to memory from TOS | write | |4092 | write to memory from TOS | write |
|4091 | add TOS | add | |4091 | add TOS | add |
|4090 | suptract TOS | sub | |4090 | suptract TOS | sub |
|4089 | jump to TOS | jmp | |4089 | jump to TOS | jmp |
|4088 | skip if TOS = zero | sez | |4088 | skip if TOS = zero | sez |
|4087 | jump if TOS = zero | jez |
|4086 | jump to subroutine, push pc to retstack | jsr |
|4085 | return from subroutine, PC = top of retstack | ret |
|4084 | duplicate TOS | dup |
|4083 | drop TOS | drop |
## T410 ## T410
The T410, is, in essence, the write instruction in a block. You put in an address and a value and it tries to write the value to that address. The T410, is, in essence, the write instruction in a block. You put in an address and a value and it tries to write the value to that address.

View File

@ -23,7 +23,7 @@ local function push(pos,val)
local sstring = "" local sstring = ""
local sstab = string.split(meta:get_string("stack"),"\n") local sstab = string.split(meta:get_string("stack"),"\n")
sstab[#sstab+1] = tostring(tonumber(val) % 4096) sstab[#sstab+1] = tostring(tonumber(val) % 4096)
if #sstab > 16 then if #sstab > MEMSIZE then
table.remove(sstab,1) table.remove(sstab,1)
end end
for k,v in ipairs(sstab) do for k,v in ipairs(sstab) do
@ -47,10 +47,13 @@ end
local function t400_digiline_receive(pos, node, channel, msg) local function t400_digiline_receive(pos, node, channel, msg)
print("Digiline: "..tostring(pos.x)..","..tostring(pos.y)..","..tostring(pos.z).."; Channel: "..tostring(channel).."; Message: "..tostring(msg)) print("Digiline: "..tostring(pos.x)..","..tostring(pos.y)..","..tostring(pos.z).."; Channel: "..tostring(channel).."; Message: "..tostring(msg))
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
print(meta:get_string("state").." "..meta:get_string("waitingfor"))
if meta:get_string("state") == "waitingdat" and meta:get_string("waitingfor") == channel then if meta:get_string("state") == "waitingdat" and meta:get_string("waitingfor") == channel then
print("got data")
push(pos,tonumber(msg)) push(pos,tonumber(msg))
meta:set_int("pc",meta:get_int("pc")+1) meta:set_int("pc",meta:get_int("pc")+1)
meta:set_string("state","running") meta:set_string("state","running")
print("finished getting data")
elseif meta:get_string("state") == "waitingins" and meta:get_string("waitingfor") == channel then elseif meta:get_string("state") == "waitingins" and meta:get_string("waitingfor") == channel then
meta:set_int("ci",tonumber(msg)) meta:set_int("ci",tonumber(msg))
meta:set_string("state","running") meta:set_string("state","running")
@ -65,6 +68,7 @@ local function t400_set_meta(pos)
ms = ms .. "0\n" ms = ms .. "0\n"
end end
meta:set_string("stack",ms) meta:set_string("stack",ms)
meta:set_string("retstack",ms)
meta:set_string("channel","Default") meta:set_string("channel","Default")
meta:set_string("state","running") meta:set_string("state","running")
meta:set_string("waitingfor","") meta:set_string("waitingfor","")
@ -116,40 +120,83 @@ minetest.register_abm({
local skipnext = false local skipnext = false
print("Attempting to run T400 node at "..pos2string(pos)) print("Attempting to run T400 node at "..pos2string(pos))
local ci = meta:get_int("ci") local ci = meta:get_int("ci")
if ci == 4095 then if ci == 4095 then -- ppc
push(pos,meta:get_int("pc")) push(pos,meta:get_int("pc"))
elseif ci == 4094 then elseif ci == 4094 then -- swp - why do I have this?
local a = pop(pos) local a = pop(pos)
local b = pop(pos) local b = pop(pos)
print("Swapping "..tostring(a).." for "..tostring(b))
push(pos,b) push(pos,b)
push(pos,a) push(pos,a)
elseif ci == 4093 then elseif ci == 4093 then -- read
skipnext = true skipnext = true
local addr = pop(pos) local addr = pop(pos)
meta:set_string("state","waitingdat") meta:set_string("state","waitingdat")
meta:set_string("waitingfor",meta:get_string("channel")..string.format("%X",addr)) meta:set_string("waitingfor",meta:get_string("channel")..string.format("%X",addr))
meta:set_int("pc",meta:get_int("pc")+nins)
digiline:receptor_send(pos,digiline.rules.default,meta:get_string("channel")..string.format("%X",addr),"get") digiline:receptor_send(pos,digiline.rules.default,meta:get_string("channel")..string.format("%X",addr),"get")
elseif ci == 4092 then return
elseif ci == 4092 then -- write
local addr = pop(pos) local addr = pop(pos)
local dat = pop(pos) local dat = pop(pos)
print("Writing "..tostring(dat).." to address "..addr) print("Writing "..tostring(dat).." to address "..addr)
digiline:receptor_send(pos,digiline.rules.default,meta:get_string("channel")..string.format("%X",addr),dat) digiline:receptor_send(pos,digiline.rules.default,meta:get_string("channel")..string.format("%X",addr),dat)
elseif ci == 4091 then elseif ci == 4091 then -- add
print("Adding stuff") print("Adding stuff")
push(pos,pop(pos)+pop(pos)) push(pos,pop(pos)+pop(pos))
elseif ci == 4090 then elseif ci == 4090 then -- sub
push(pos,pop(pos)-pop(pos)) push(pos,pop(pos)-pop(pos))
elseif ci == 4089 then elseif ci == 4089 then -- jmp
local npc = pop(pos) local npc = pop(pos)
print("Jumping to "..tostring(npc)) print("Jumping to "..tostring(npc))
meta:set_int("pc",npc) meta:set_int("pc",npc)
elseif ci == 4088 then nins=0
elseif ci == 4088 then -- sez
local val = pop(pos) local val = pop(pos)
print(val,type(val)) print(val,type(val))
if val == 0 then if val == 0 then
print("Skipping because "..tostring(val).." = 0") print("Skipping because "..tostring(val).." = 0")
nins=nins+1 nins=nins+1
end end
elseif ci == 4087 then -- jez
local addr = pop(pos)
local val = pop(pos)
if val == 0 then
print("Jumping to "..addr.." because "..val.." = 0")
meta:set_int("pc",addr)
nins=0
end
elseif ci == 4086 then -- jsr
local sstring = ""
local sstab = string.split(meta:get_string("retstack"),"\n")
sstab[#sstab+1] = tostring(tonumber(meta:get_int("pc")) % 4096)
if #sstab > MEMSIZE then
table.remove(sstab,1)
end
for k,v in ipairs(sstab) do
sstring = sstring .. v .. "\n"
end
meta:set_string("retstack",sstring)
meta:set_int("pc",pop(pos))
nins=0
elseif ci == 4085 then -- ret
local sstring = ""
local sstab = string.split(meta:get_string("retstack"),"\n")
local sval = tonumber(table.remove(sstab,#sstab))
for k,v in ipairs(sstab) do
sstring = sstring .. v .. "\n"
end
meta:set_string("retstack",sstring)
if not sval then sval = 0 end
meta:set_int("pc",sval)
elseif ci == 4084 then -- dup
local v = pop(pos)
push(pos,v)
push(pos,v)
print("Duplicating "..v)
elseif ci == 4083 then -- drop
print("Dropping stuff")
pop(pos)
else else
print("Pushing "..ci.." to "..pos2string(pos)) print("Pushing "..ci.." to "..pos2string(pos))
push(pos,ci) push(pos,ci)

View File

@ -12,7 +12,7 @@ end
print("Loading.") print("Loading.")
local function t416_digiline_receive(pos, node, channel, msg) local function t416_digiline_receive(pos, node, channel, msg)
print("Digiline: "..tostring(pos.x)..","..tostring(pos.y)..","..tostring(pos.z).."; Channel: "..tostring(channel).."; Message: "..tostring(msg)) --print("Digiline: "..tostring(pos.x)..","..tostring(pos.y)..","..tostring(pos.z).."; Channel: "..tostring(channel).."; Message: "..tostring(msg))
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local mem = string.split(meta:get_string("mem"),"\n") local mem = string.split(meta:get_string("mem"),"\n")
local ms = "" local ms = ""