//**********************************************
// Arithmetic Gates
//**********************************************

GateActions("Arithmetic")

GateActions["PHI"] = {
	name = "Phi",
	inputs = { },
	outputs = { "Algebra", "Trig", "666" },
	output = function(gate)
		return
			(1 + math.sqrt(5)) / 2,
			2*math.cos(math.rad(36)),
			-(math.sin(math.rad(666)) + math.cos(math.rad(6*6*6)))
	end	
}
//Q: What is Phi?
//A: Phi is a irrational decimal value of approx. 1.6180339887...
//   Phi resembles the ratio of the sides of an ordinay A4 paper sheet. -- that is bullshit, A4 is 1.414:1, very far from phi
//   Phi resembles the screen ratio of widescreens (16:9 or 16:10 is roughly the same as Phi:1).
//   Phi is the approximate ratio between two sucsessing fibbonachi numbers (1,1,2,3,5,8,13,21,35...).
//   Phi resembles the expansion coefficient of snail shells.
//   Phi resembles the expansion acceleration of the universe. -- wtf?
--   Phi is a/b = (a+b)/a

//**********************************************
// Memory Chips
//**********************************************

GateActions("Memory")

GateActions["ram1024k"] = {
	name = "RAM(1M = 1024k)",
	inputs = { "Clk", "AddrRead", "AddrWrite", "Data" },
	output = function(gate, Clk, AddrRead, AddrWrite, Data )
		AddrRead = math.floor(tonumber(AddrRead))
		AddrWrite = math.floor(tonumber(AddrWrite))
		if (Clk > 0) then
			if (AddrWrite < 1048575) and (AddrWrite >= 0) then
				gate.LatchStore[AddrWrite] = Data
			end
		end
		return gate.LatchStore[AddrRead] or 0
	end,
	reset = function(gate)
		gate.LatchStore = {}
		for i = 0,1048575 do
			gate.LatchStore[i] = 0
		end
	end,
	label = function(Out, Clk, AddrRead, AddrWrite, Data)
		return "WriteAddr:"..AddrWrite.."  Data:"..Data.."  Clock:"..Clk..
		"\nReadAddr:"..AddrRead.." = "..Out
	end,
	ReadCell = function(dummy,gate,Address)
		if Address < 0 then return 0 end
		if Address >= 1048576 then return 0 end
		
		return gate.LatchStore[Address] or 0
	end,
	WriteCell = function(dummy,gate,Address,value)
		if Address < 0 then return false end
		if Address >= 1048576 then return false end
		
		gate.LatchStore[Address] = value
		return true
	end
}

GateActions["ram64x64x64"] = {
	name = "RAM(64x64x64 store)",
	inputs = { "Clk", "AddrRX", "AddrRY", "AddrRZ", "AddrWX", "AddrWY", "AddrWZ", "Data" },
	output = function(gate, Clk, AddrRX, AddrRY, AddrRZ, AddrWX, AddrWY, AddrWZ, Data)
		ReadX = math.floor(tonumber(AddrRX))
		ReadY = math.floor(tonumber(AddrRY))
		ReadZ = math.floor(tonumber(AddrRZ))
		WriteX = math.floor(tonumber(AddrWX))
		WriteY = math.floor(tonumber(AddrWY))
		WriteZ = math.floor(tonumber(AddrWZ))
		if (Clk > 0) then
			if (WriteX < 64) and (WriteX >= 0) and (WriteY < 64) and (WriteY >= 0) and (WriteZ < 64) and (WriteZ >= 0) then
				gate.LatchStore[WriteX + WriteY*64 + WriteZ*4096] = Data
			end
		end
		
		if (ReadX < 0) or (ReadX >= 64) or (ReadY < 0) or (ReadY >= 64) or (ReadZ < 0) or (ReadZ >= 64) then
			return 0
		end
		
		return gate.LatchStore[ReadX + ReadY*64 + ReadZ*4096] or 0
	end,
	reset = function(gate)
		gate.LatchStore = {}
		for i = 0,262143 do
			gate.LatchStore[i] = 0
		end
	end,
	label = function(Out, Clk, AddrRX, AddrRY, AddrRZ, AddrWX, AddrWY, AddrWZ, Data)
		return "WriteAddr:"..AddrWX..", "..AddrWY..", "..AddrWZ..
			"\nReadAddr:"..AddrRX..", "..AddrRY..", "..AddrRZ..
			"\nData:"..Data.."  Clock:"..Clk
	end,
	ReadCell = function(dummy,gate,Address)
		if Address < 0 then return 0 end
		if Address >= 262144 then return 0 end
		
		return gate.LatchStore[Address] or 0
	end,
	WriteCell = function(dummy,gate,Address,value)
		if Address < 0 then return false end
		if Address >= 262144 then return false end
		
		gate.LatchStore[Address] = value
		return true
	end
}

GateActions()
