Permalink
Browse files

added LOAD and STOR opcodes

LOAD and STOR are implemented as free-register opcodes, accepting
either two registers, or one register and a number. the load a value
from memory into a register, and store a value from a register into
memory respectively.

they should be used in preference to the assignment forms of MOV
(which will be deprecated)
  • Loading branch information...
1 parent e03dde2 commit 3689fb6eec76c44748051d52edae26f96d68091f @Textmode committed May 15, 2011
Showing with 87 additions and 6 deletions.
  1. +43 −3 asm.lua
  2. +36 −1 machine.lua
  3. +8 −2 opcodes.lua
View
@@ -88,9 +88,9 @@ end
-- regardless, the encoder ends by returning either the encoded chunk, or
-- false, followed by a message explaining the error.
local encoders = {
- NOP = function(a, b, c)
+ NOP = function(a, b, c, d)
-- NOP is the do-nothing instruction. it has only one form.
- if not (a or b or c) then
+ if (a or b or c or d) then
return false, "NOP must be properly qualified: 'NOP'" end
return string.char(op.NOP)
end;
@@ -498,7 +498,7 @@ local encoders = {
elseif af == 'register' then
-- theres no actual free-register JMP, but LJMP with SEG as 1dR is equivilent.
-- (its also the same size)
- return string.char(op.LJMP_1dR_1dR, reg_encode('SEG', av))
+ return string.char(op.LJMP_1dR_2dR, reg_encode('SEG', av))
end
return false, "unhandled JMP form!"
end;
@@ -790,7 +790,47 @@ local encoders = {
return string.char(op.OUT_1dR_2dR, reg_encode(av, bv))
end;
+ LOAD = function(a, b)
+ -- the load instrution, used to load data from an address into a register
+ if not (a and b) then
+ return false, "LOAD must be properly qualified: 'LOAD iN,dR' or 'LOAD iR,dR'" end
+ local af, aa, av = parm(a)
+ local bf, ba, bv = parm(b)
+ if not (bf == 'register') then
+ return false, "LOAD only loads an indirect number or register into a direct register"
+ end
+ if aa or (not ba) then
+ return false, "LOAD only loads an indirect number or register into a direct register"
+ end
+ if af == 'register' then
+ return string.char(op.LOAD_1iR_2dR, reg_encode(av, bv))
+ elseif af == 'number' then
+ return string.char(op.LOAD_1iN_2dR, reg_encode('A', bv), av)
+ else -- af == 'symbol'
+ return string.char(op.LOAD_1iN_2dR, reg_encode('A', bv), 0x0)
+ end
+ end;
+
+ STOR = function(a, b)
+ -- the store instrution, used to store data from a register into an address.
+ if not (a and b) then
+ return false, "STOR must be properly qualified: 'STOR dR,iN,' or 'LOAD dR,iR'" end
+ local af, aa, av = parm(a)
+ local bf, ba, bv = parm(b)
+ if not (af == 'register' and (bf == 'register' or bf == 'symbol' or bf == 'number')) then
+ return false, "STOR only stores a direct register into an indirect register or number" end
+ if (not aa) or ba then
+ return false, "STOR only stores a direct register into an indirect register or number" end
+
+ if bf == 'register' then
+ return string.char(op.STOR_1dR_2iR, reg_encode(av, bv))
+ elseif bf == 'number' then
+ return string.char(op.STOR_1dR_2iN, reg_encode(av, 'A'), bv)
+ else -- bf == 'symbol'
+ return string.char(op.STOR_1dR_2iN, reg_encode(av, 'A'), 0x0)
+ end
+ end;
}
-----
View
@@ -736,6 +736,41 @@ function ins.LES_1dA_2dB_3dRET(self)
return 1;
end;
+-- LOAD &R: R
+-- Put address contents into register
+function ins.LOAD_1iR_2dR(self)
+ local _, b = convreg(self, adrget(self, self.IP+1))
+ self[b] = adrget(self, self.a)
+ return 2;
+end;
+
+-- LOAD &nn: R
+-- Put address contents into register
+function ins.LOAD_1iN_2dR(self)
+ local _, b = convreg(self, adrget(self, self.IP+1))
+ local point = adrget(self, self.IP+2)
+ self[b] = adrget(self, point)
+ return 3;
+end;
+
+-- STOR R: &R
+-- Put register contents into address
+function ins.STOR_1dR_2iR(self)
+ local a, b = convreg(self, adrget(self, self.IP+1))
+ adrset(self, self.b, self.a)
+ return 2;
+end;
+
+-- STOR R: &nn
+-- Put register contents into address
+function ins.STOR_1dR_2iN(self)
+ local a, b = convreg(self, adrget(self, self.IP+1))
+ local point = adrget(self, self.IP+2)
+ adrset(self, point, self[a])
+ return 3;
+end;
+
+
-- HLT
-- halts the machine
function ins.HLT(self)
@@ -868,7 +903,7 @@ function _M:load(start, data)
-- starting offset is optional, but we have to shuffle things around
-- a bit if its not given.
if data == nil then data, start = start, 0 end
- assert(type(data)=='table' or type(data)=='string', "Invalid loadable data parm")
+ assert(type(data)=='table' or type(data)=='string', "Invalid loadable data parm: '" ..type(data).."'")
if type(data)=='string' then data=stringtodata(data) end
View
@@ -5,8 +5,8 @@ local remap = {
[0x01] = {'INC_1dACC'};
[0x02] = {'MOV_1iR_2iR'};
[0x03] = {'MOV_1dA_2dN'};
- [0x04] = {'MOV_1iN_2dA'};
- [0x05] = {'MOV_1dN_2dA'};
+ [0x04] = {'MOV_1iN_2dA', 'LOAD_1iN_2dA'};
+ [0x05] = {'MOV_1dN_2dA', 'LOAD_1dN_2dA'};
[0x06] = {'ADD_1dR_2dR_3dACC'};
[0x07] = {'SWP_1dR_2dR'};
@@ -46,6 +46,12 @@ local remap = {
[0x26] = {'ROL_1dR_2dR_3dRET'};
[0x27] = {'ROR_1dR_2dR_3dRET'};
+ [0x28] = {'LOAD_1iR_2dR'};
+ [0x29] = {'LOAD_1iN_2dR'};
+ [0x2a] = {'STOR_1dR_2iR'};
+ [0x2b] = {'STOR_1dR_2iN'};
+
+
[0xa0] = {'EQL_1dA_2dB_3dRET'};
[0xa1] = {'SHW_1dR'};
[0xa2] = {'DIV_1dR_2dR_3dRET'};

0 comments on commit 3689fb6

Please sign in to comment.