Permalink
Browse files

improved and consolidated flag handling

  • Loading branch information...
Textmode committed Mar 10, 2011
1 parent b64f3a4 commit d21ed0d612f05c4934e98d3164c06e697c14e581
Showing with 79 additions and 77 deletions.
  1. +3 −3 bitfield.lua
  2. +76 −74 machine.lua
View
@@ -52,7 +52,7 @@ _MT.__index = _M.GET --(self, idx)
--
-- Returns: (nothing)
function _M.SET(b, n, v)
- if not isbf(b) then b = bitfield(b) end
+ if not isbf(b) then b = _M:new(b) end
assert(n > 0, "Cannot set imaginary bits.")
n = bin(n)
@@ -64,11 +64,11 @@ function _M.SET(b, n, v)
if v then
if b.value % (2*n) < n then
- b.value = self.value + n
+ b.value = b.value + n
end
else -- false/clear
if b.value % (2*n) >= n then
- b.value = self.value - n
+ b.value = b.value - n
end
end
View
@@ -41,12 +41,23 @@ local signals = {
local CF = 1 -- carry flag
local SF = 2 -- sign (negative) flag
local OF = 3 -- overflow/underflow flag
---local ZF = 4 -- zero flag
---local PF = 5 -- parity flag
+local ZF = 4 -- zero flag
+local PF = 5 -- parity flag
--local U1 = 6 -- unused
--local U2 = 7 -- unused
--local U3 = 8 -- unused
+local parity = {
+ [0x0] = 1; [0x1] = 0; -- 0000 0001
+ [0x2] = 0; [0x3] = 1; -- 0010 0011
+ [0x4] = 0; [0x5] = 1; -- 0100 0101
+ [0x6] = 1; [0x7] = 0; -- 0110 0111
+ [0x8] = 0; [0x9] = 1; -- 1000 1001
+ [0xa] = 1; [0xb] = 0; -- 1010 1011
+ [0xc] = 1; [0xd] = 0; -- 1100 1101
+ [0xe] = 0; [0xf] = 1; -- 1110 1111
+}
+
-------------------------------------------------------------------------
-- MISC
@@ -136,6 +147,47 @@ local function getflag(self, flag, bool)
return bitfield.GET(self.FLG, flag)
end
+local function doflags(self, value)
+
+ if value == 0 then
+ setflag(self, CF, false)
+ setflag(self, SF, false)
+ setflag(self, OF, false)
+ setflag(self, ZF, true)
+ setflag(self, PF, true)
+ else
+ setflag(self, ZF, false)
+ end
+
+
+ if value ~= (value % 256) then
+ setflag(self, OF, true)
+ setflag(self, CF, true)
+ else
+ setflag(self, OF, false)
+ setflag(self, CF, false)
+ end
+
+ if value < 0x00 then
+ setflag(self, SF, true)
+ setflag(self, CF, true)
+ else
+ setflag(self, SF, false)
+ setflag(self, CF, true)
+ end
+
+ do -- Parity bit assignment
+ local a = math.floor(value % 16)
+ local b = math.floor(value / 16)
+ a = parity[a]
+ b = parity[b]
+
+ setflag(self, PF, (a or b) and not (a and b)) -- XOR, for those of you following along at home
+ end
+
+ return value
+end
+
-- does nothing.
local function nop() end
@@ -153,11 +205,8 @@ _M.iset = {
-- Fixed register Increment
[0x01]=function(self)
local r = (self.ACC+1)
- if r > 0xff then
- setflag(self, OF, true)
- setflag(self, CF, true)
- end
- self.ACC = r % 256
+
+ self.ACC = doflags(self, r) % 256
return 1
end;
-- MOV &R:&R
@@ -193,12 +242,7 @@ _M.iset = {
local a, b = convreg(self, adrget(self, self.IP+1))
local r = (self[a] + self[b])
- if r > 0xff then
- setflag(self, CF, true)
- setflag(self, OF, true)
- end
-
- self.ACC = r % 256
+ self.ACC = doflags(self, r) % 256
return 2;
end;
-- SWP R:R
@@ -221,12 +265,7 @@ _M.iset = {
[0x09]=function(self)
local r = (self.A + self.B)
- if r > 0xff then
- setflag(self, CF, true)
- setflag(self, OF, true)
- end
-
- self.ACC = r % 256
+ self.ACC = doflags(self, r) % 256
return 1;
end;
-- SHW .A
@@ -362,11 +401,7 @@ _M.iset = {
local r = round(self[a] * self[b])
- if r > 0xff then
- setflag(self, OF, true)
- end
-
- self.RET = r % 256
+ self.RET = doflags(self, r) % 256
return 2;
end;
-- SUB R1:.R2 -> .ACC
@@ -376,34 +411,33 @@ _M.iset = {
local r = (self[a] - self[b])
- if r < 0x00 then
- setflag(self, CF, true)
- setflag(self, OF, true)
- setflag(self, SF, true)
- end
- self.ACC = r % 256
+ self.ACC = doflags(self, r) % 256
return 2;
end;
-- MOD R, R -> RET
-- Free-register Modulo
[0x1b]=function(self)
local a, b = convreg(self, adrget(self, self.IP+1))
- self.RET = round((self[a] % self[b]) % 256)
+ local r =round(self[a] % self[b])
+ self.RET = doflags(self, r) % 256
return 2;
end;
-- MOD R, R -> ACC
-- Free-register Modulo
[0x1c]=function(self)
local a, b = convreg(self, adrget(self, self.IP+1))
- self.ACC = round((self[a] % self[b]) % 256)
+ local r = round(self[a] % self[b])
+
+ self.ACC = doflags(self, r) % 256
return 2;
end;
-- DIV R, R -> ACC
-- Free-register divide
[0x1d]=function(self)
local a, b = convreg(self, adrget(self, self.IP+1))
if self.b == 0 then self:signal(SIG_DIV0) end
- self.ACC = round((self[a] / self[b]) % 256)
+ local r = round(self[a] / self[b])
+ self.ACC = doflags(self, r) % 256
return 2;
end;
-- MUL R, R -> ACC
@@ -415,24 +449,15 @@ _M.iset = {
local r = round(self[a] * self[b])
- if r > 0xff then
- setflag(self, OF, true)
- end
-
- self.ACC = r % 256
+ self.ACC = doflags(self, r) % 256
return 2;
end;
-- DEC ACC
-- Fixed register Decrement
[0x1f]=function(self)
local r = (self.ACC-1)
- if r < 0x00 then
- setflag(self, CF, true)
- setflag(self, OF, true)
- setflag(self, SF, true)
- end
- self.ACC = r % 256
+ self.ACC = doflags(self, r) % 256
return 1
end;
@@ -443,12 +468,7 @@ _M.iset = {
local a, b = convreg(self, adrget(self, self.IP+1))
local r = (self[a] - self[b])
- if r < 0x00 then
- setflag(self, CF, true)
- setflag(self, OF, true)
- setflag(self, SF, true)
- end
- self.RET = r % 256
+ self.RET = doflags(self, r) % 256
return 2;
end;
-- MOV nn, B
@@ -519,7 +539,8 @@ _M.iset = {
[0xa2]=function(self)
local a, b = convreg(self, adrget(self, self.IP+1))
if self.b == 0 then self:signal(SIG_DIV0) end
- self.RET = round((self[a] / self[b]) % 256)
+ local r = round(self[a] / self[b])
+ self.RET = doflags(self, r) % 256
return 2;
end;
-- GTR .A:.B -> .RET
@@ -534,50 +555,31 @@ _M.iset = {
local a, b = convreg(self, adrget(self, self.IP+1))
local r = (self[a] + self[b])
- if r > 0xff then
- setflag(self, CF, true)
- setflag(self, OF, true)
- end
- self.RET = r % 256
+ self.RET = doflags(self, r) % 256
return 2;
end;
-- SUB .A:.B -> .RET
-- fixed-register AB SUBtraction, results in RET
[0xa5]=function(self)
local r = (self.A - self.B)
- if r < 0x00 then
- setflag(self, CF, true)
- setflag(self, OF, true)
- setflag(self, SF, true)
- end
- self.RET = r % 256
+ self.RET = doflags(self, r) % 256
return 1;
end;
-- ADD .A:.B -> .RET
-- fixed-register AB ADDition, results in RET
[0xa6]=function(self)
local r = (self.A + self.B)
- if r > 0xff then
- setflag(self, CF, true)
- setflag(self, OF, true)
- setflag(self, SF, true)
- end
- self.RET = r % 256
+ self.RET = doflags(self, r) % 256
return 1;
end;
-- SUB .A:.B -> .ACC
-- fixed-register AB SUBtraction, results in ACC
[0xa7]=function(self)
local r = (self.A - self.B)
- if r < 0x00 then
- setflag(self, CF, true)
- setflag(self, OF, true)
- setflag(self, SF, true)
- end
- self.ACC = r % 256
+ self.ACC = doflags(self, r) % 256
return 1;
end;

0 comments on commit d21ed0d

Please sign in to comment.