2007-03-21 21:09:01 +00:00
|
|
|
AddCSLuaFile( "cl_init.lua" )
|
2007-04-12 19:16:47 +00:00
|
|
|
//AddCSLuaFile( "shared.lua" )
|
2007-03-21 21:09:01 +00:00
|
|
|
include('shared.lua')
|
2007-04-12 19:16:47 +00:00
|
|
|
include('compiler_asm.lua')
|
2007-03-21 21:09:01 +00:00
|
|
|
|
|
|
|
ENT.WireDebugName = "CPU"
|
|
|
|
|
|
|
|
function ENT:Initialize()
|
|
|
|
self.Entity:PhysicsInit( SOLID_VPHYSICS )
|
|
|
|
self.Entity:SetMoveType( MOVETYPE_VPHYSICS )
|
|
|
|
self.Entity:SetSolid( SOLID_VPHYSICS )
|
2007-11-10 23:10:57 +00:00
|
|
|
|
2007-05-16 19:53:47 +00:00
|
|
|
self.Inputs = Wire_CreateInputs(self.Entity, { "MemBus", "IOBus", "Frequency", "Clk", "Reset", "NMI"})
|
2007-04-12 19:16:47 +00:00
|
|
|
self.Outputs = Wire_CreateOutputs(self.Entity, { "Error" })
|
2007-03-21 21:09:01 +00:00
|
|
|
|
|
|
|
self.Memory = {}
|
|
|
|
for i = 0, 65535 do
|
|
|
|
self.Memory[i] = 0
|
|
|
|
end
|
|
|
|
|
2007-04-12 19:16:47 +00:00
|
|
|
self.ROMMemory = {}
|
|
|
|
for i = 0, 65535 do
|
|
|
|
self.ROMMemory[i] = 0
|
|
|
|
end
|
|
|
|
|
|
|
|
self.Page = {}
|
|
|
|
for i = 0, 511 do
|
|
|
|
self.Page[i] = true
|
|
|
|
end
|
2007-03-21 21:09:01 +00:00
|
|
|
|
2007-04-12 19:16:47 +00:00
|
|
|
self.IOBus = nil
|
|
|
|
self.MemBus = nil
|
|
|
|
self.UseROM = false
|
2007-03-21 21:09:01 +00:00
|
|
|
|
|
|
|
self.Clk = 0
|
2007-04-12 19:16:47 +00:00
|
|
|
self.InputClk = 0
|
|
|
|
|
|
|
|
self:Reset()
|
|
|
|
|
|
|
|
//= Different compiler vars========
|
|
|
|
self.WIP = 0
|
|
|
|
self.FatalError = false
|
|
|
|
self.Labels = {}
|
|
|
|
self.Compiling = false
|
2007-05-17 21:30:52 +00:00
|
|
|
self.Dump = ""
|
|
|
|
self.MakeDump = false
|
2007-04-12 19:16:47 +00:00
|
|
|
//=================================
|
2007-11-10 23:10:57 +00:00
|
|
|
|
2007-11-08 21:45:54 +00:00
|
|
|
//Execution "local" vars
|
|
|
|
self.DeltaTime = 0
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Opcode = 0
|
|
|
|
self.RM = 0
|
|
|
|
self.Params = {0, 0}
|
|
|
|
self.Result = 0
|
|
|
|
self.dRM2 = 0
|
|
|
|
self.dRM1 = 0
|
|
|
|
self.Segment1 = 0
|
|
|
|
self.Segment2 = 0
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Disp1 = 0
|
|
|
|
self.Disp2 = 0
|
|
|
|
|
2007-11-08 21:45:54 +00:00
|
|
|
self.ThinkTime = (1000)/100
|
2007-04-12 19:16:47 +00:00
|
|
|
self.PrevTime = CurTime()
|
2007-11-10 23:10:57 +00:00
|
|
|
self.CPUCyclesLeft = 0
|
2007-06-11 21:45:39 +00:00
|
|
|
|
2007-11-08 21:45:54 +00:00
|
|
|
self:SetOverlayText("CPU")
|
|
|
|
self:InitializeOpcodeTable()
|
2007-11-10 23:10:57 +00:00
|
|
|
self:InitASMOpcodes()
|
2007-04-12 19:16:47 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function ENT:Reset()
|
|
|
|
self.IP = 0
|
|
|
|
|
|
|
|
for i = 0, 511 do
|
|
|
|
self.Page[i] = true
|
|
|
|
end
|
2007-03-21 21:09:01 +00:00
|
|
|
|
|
|
|
self.EAX = 0
|
|
|
|
self.EBX = 0
|
|
|
|
self.ECX = 0
|
|
|
|
self.EDX = 0
|
|
|
|
|
|
|
|
self.ESI = 0
|
|
|
|
self.EDI = 0
|
|
|
|
self.ESP = 65535
|
|
|
|
self.EBP = 0
|
2007-04-12 19:16:47 +00:00
|
|
|
|
|
|
|
self.CS = 0
|
|
|
|
self.SS = 0
|
|
|
|
self.DS = 0
|
|
|
|
self.ES = 0
|
|
|
|
self.GS = 0
|
|
|
|
self.FS = 0
|
|
|
|
|
|
|
|
self.IDTR = 0
|
|
|
|
self.IF = true
|
|
|
|
self.PF = false
|
|
|
|
|
|
|
|
self.Debug = false
|
2007-03-21 21:09:01 +00:00
|
|
|
|
|
|
|
self.CMPR = 0
|
2007-04-12 19:16:47 +00:00
|
|
|
self.ILTC = 0
|
|
|
|
self.XEIP = 0
|
|
|
|
self.LADD = 0
|
|
|
|
self.INTR = false
|
|
|
|
self.TMR = 0
|
|
|
|
self.TIMER = 0
|
2007-03-21 21:09:01 +00:00
|
|
|
|
2007-04-12 19:16:47 +00:00
|
|
|
self.Clk = self.InputClk
|
2007-03-21 21:09:01 +00:00
|
|
|
|
|
|
|
self.HaltPort = -1
|
|
|
|
|
2007-04-12 19:16:47 +00:00
|
|
|
if (self.UseROM) then
|
|
|
|
for i = 0, 65535 do
|
|
|
|
self.Memory[i] = self.ROMMemory[i]
|
|
|
|
end
|
|
|
|
end
|
2007-03-21 21:09:01 +00:00
|
|
|
|
|
|
|
Wire_TriggerOutput(self.Entity, "Error", 0.0)
|
|
|
|
end
|
|
|
|
|
2007-04-12 19:16:47 +00:00
|
|
|
//INTERRUPTS TABLE
|
|
|
|
//Value | Meaning | Passed parameters
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
//0.0 | Software restart |
|
|
|
|
//2.0 | End of program execution |
|
|
|
|
//3.0 | Division by zero |
|
2007-11-10 23:10:57 +00:00
|
|
|
//4.0 | Unknown opcode | OPCODE,ADDRESS
|
2007-04-12 19:16:47 +00:00
|
|
|
//5.0 | Internal error |
|
|
|
|
//6.0 | Stack error |
|
|
|
|
//7.0 | Memory fault (Read/write violation) | ADDRESS
|
|
|
|
//8.0 | External bus error |
|
|
|
|
//9.0 | Page fault (Write access violation) | ADDRESS
|
|
|
|
//10.0 | Port Bus fault | ADDRESS
|
|
|
|
//11.0 | ROM Error |
|
|
|
|
//12.0 | Page error (wrong page id) |
|
|
|
|
//13.0 | General Protection Error |
|
2007-11-10 23:10:57 +00:00
|
|
|
//14.0 | Idiot error |
|
2007-04-12 19:16:47 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
function ENT:Interrupt( intnumber )
|
|
|
|
if ( self.Compiling ) then
|
|
|
|
self.FatalError = true
|
|
|
|
return
|
|
|
|
end
|
|
|
|
if (self.Debug) then
|
|
|
|
Msg("INTERRUPT: "..intnumber.." AT "..self.XEIP.." LADD="..self.LADD.." ILTC="..self.ILTC.."\n")
|
|
|
|
end
|
|
|
|
if ( self.INTR ) then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
self.INTR = true
|
|
|
|
if ( intnumber <= 1 ) or ( intnumber > 255) then
|
|
|
|
self:Reset()
|
|
|
|
self.EAX = 10
|
|
|
|
if (intnumber == 1) then
|
|
|
|
self.Clk = 0
|
|
|
|
end
|
|
|
|
return
|
|
|
|
end
|
2007-11-10 23:10:57 +00:00
|
|
|
Wire_TriggerOutput(self.Entity, "Error", intnumber)
|
2007-04-12 19:16:47 +00:00
|
|
|
if (self.IF) then
|
|
|
|
if (self.PF == false) then
|
|
|
|
self.Clk = 0
|
|
|
|
return
|
|
|
|
else
|
|
|
|
local intaddress = self.IDTR + intnumber*2
|
|
|
|
if (intaddress > 65535) then intaddress = 65535 end
|
|
|
|
if (intaddress < 0) then intaddress = 0 end
|
|
|
|
local intoffset = self.Memory[intaddress]
|
|
|
|
local intprops = self.Memory[intaddress+1]
|
|
|
|
if (intprops ~= 0) then //Interrupt active, temp fix
|
|
|
|
self.INTR = false
|
2007-11-10 23:10:57 +00:00
|
|
|
if ( intnumber == 4 ) ||
|
|
|
|
( intnumber == 7 ) ||
|
|
|
|
( intnumber == 9 ) ||
|
|
|
|
( intnumber == 10) then
|
|
|
|
self:Push(self.LADD)
|
|
|
|
end
|
|
|
|
if ( intnumber == 4 ) then //If wrong opcode then store data
|
|
|
|
self:Push(self.ILTC)
|
|
|
|
end
|
2007-04-12 19:16:47 +00:00
|
|
|
if self:Push(self.IP) then //Store IRET
|
|
|
|
self:Push(self.XEIP)
|
|
|
|
self.IP = intoffset
|
|
|
|
end
|
|
|
|
self.INTR = true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2007-03-21 21:09:01 +00:00
|
|
|
function ENT:Write( value )
|
2007-04-12 19:16:47 +00:00
|
|
|
if (value) then
|
|
|
|
if (self.UseROM) then
|
|
|
|
if (self.WIP < 65536) then
|
|
|
|
self.ROMMemory[self.WIP] = value
|
|
|
|
end
|
|
|
|
else
|
|
|
|
self:WriteCell(self.WIP,value)
|
|
|
|
end
|
|
|
|
if (self.Debug) then
|
|
|
|
//Msg("-> ZyeliosASM: Wrote "..value.." at ["..self.WIP.."]\n")
|
|
|
|
end
|
|
|
|
|
|
|
|
self.WIP = self.WIP + 1
|
|
|
|
end
|
2007-03-21 21:09:01 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function ENT:Read( )
|
2007-04-12 19:16:47 +00:00
|
|
|
if (self.INTR) then //Lock the bus & eip
|
|
|
|
if (self.Debug) then
|
|
|
|
Msg("BUS READ WHILE LOCKED\n")
|
|
|
|
end
|
|
|
|
return nil
|
|
|
|
end
|
2007-11-03 16:44:17 +00:00
|
|
|
if (!self.IP) then
|
|
|
|
Self:Reset()
|
|
|
|
Wire_TriggerOutput(self.Entity, "Error", 5.0)
|
|
|
|
return nil
|
|
|
|
end
|
2007-03-21 21:09:01 +00:00
|
|
|
self.IP = self.IP + 1
|
2007-04-12 19:16:47 +00:00
|
|
|
return self:ReadCell(self.IP-1+self.CS)
|
2007-03-21 21:09:01 +00:00
|
|
|
end
|
|
|
|
|
2007-04-12 19:16:47 +00:00
|
|
|
function ENT:ReadCell( Address )
|
|
|
|
if (self.INTR) then //Lock the bus
|
|
|
|
return nil
|
|
|
|
end
|
2007-03-21 21:09:01 +00:00
|
|
|
|
2007-04-12 19:16:47 +00:00
|
|
|
if (Address < 0) then
|
2007-05-17 21:30:52 +00:00
|
|
|
return self.ReadPort(-Address-1)
|
2007-04-12 19:16:47 +00:00
|
|
|
end
|
|
|
|
if (Address < 65536) then
|
|
|
|
return self.Memory[math.floor(Address)]
|
|
|
|
else
|
|
|
|
if (self.Inputs.MemBus.Src) then
|
|
|
|
if (self.Inputs.MemBus.Src.LatchStore) then
|
|
|
|
if (self.Inputs.MemBus.Src.LatchStore[math.floor(Address)-65536]) then
|
|
|
|
return self.Inputs.MemBus.Src.LatchStore[math.floor(Address)-65536]
|
|
|
|
else
|
|
|
|
self.LADD = math.floor(Address)
|
|
|
|
self:Interrupt(7)
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
elseif (self.Inputs.MemBus.Src.ReadCell) then
|
|
|
|
local var = self.Inputs.MemBus.Src:ReadCell(math.floor(Address)-65536)
|
|
|
|
if (var) then
|
|
|
|
return var
|
|
|
|
else
|
|
|
|
self.LADD = math.floor(Address)
|
|
|
|
self:Interrupt(7)
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
else
|
|
|
|
self.LADD = math.floor(Address)
|
|
|
|
self:Interrupt(8)
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
else
|
|
|
|
self.LADD = math.floor(Address)
|
|
|
|
self:Interrupt(7)
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2007-03-21 21:09:01 +00:00
|
|
|
|
2007-04-12 19:16:47 +00:00
|
|
|
function ENT:WriteCell( Address, value )
|
|
|
|
if (self.INTR) then //Lock the bus
|
|
|
|
return nil
|
|
|
|
end
|
2007-03-21 21:09:01 +00:00
|
|
|
|
2007-04-12 19:16:47 +00:00
|
|
|
if (Address < 0) then
|
2007-04-18 19:43:32 +00:00
|
|
|
//self.LADD = math.floor(Address)
|
|
|
|
//self:Interrupt(8)
|
|
|
|
//return false
|
|
|
|
return WritePort(-Address-1,value)
|
2007-04-12 19:16:47 +00:00
|
|
|
end
|
|
|
|
if (Address < 65536) then
|
|
|
|
if (self.Page[math.floor(Address / 128)]) then
|
|
|
|
self.Memory[math.floor(Address)] = value
|
|
|
|
else
|
|
|
|
self.LADD = math.floor(Address)
|
|
|
|
self:Interrupt(9)
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
return true
|
|
|
|
else
|
|
|
|
if (self.Inputs.MemBus.Src) then
|
|
|
|
if (self.Inputs.MemBus.Src.LatchStore) then
|
|
|
|
if (self.Inputs.MemBus.Src.LatchStore[math.floor(Address)-65536]) then
|
|
|
|
self.Inputs.MemBus.Src.LatchStore[math.floor(Address)-65536] = value
|
|
|
|
return true
|
|
|
|
else
|
|
|
|
self.LADD = math.floor(Address)
|
|
|
|
self:Interrupt(7)
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
elseif (self.Inputs.MemBus.Src.WriteCell) then
|
|
|
|
if (self.Inputs.MemBus.Src:WriteCell(math.floor(Address)-65536,value)) then
|
|
|
|
return true
|
|
|
|
else
|
|
|
|
self.LADD = math.floor(Address)
|
|
|
|
self:Interrupt(7)
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
else
|
|
|
|
self.LADD = math.floor(Address)
|
|
|
|
self:Interrupt(8)
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
else
|
|
|
|
self.LADD = math.floor(Address)
|
|
|
|
self:Interrupt(7)
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
end
|
2007-05-18 20:08:04 +00:00
|
|
|
return true
|
2007-04-12 19:16:47 +00:00
|
|
|
end
|
2007-03-21 21:09:01 +00:00
|
|
|
|
2007-04-12 19:16:47 +00:00
|
|
|
function ENT:ReadPort( Address )
|
|
|
|
if (self.INTR) then //Lock the bus
|
|
|
|
return nil
|
|
|
|
end
|
2007-03-21 21:09:01 +00:00
|
|
|
|
2007-04-12 19:16:47 +00:00
|
|
|
|
|
|
|
if (Address < 0) then
|
|
|
|
self.LADD = -math.floor(Address)
|
2007-05-18 20:08:04 +00:00
|
|
|
self:Interrupt(10)
|
2007-04-12 19:16:47 +00:00
|
|
|
return nil
|
|
|
|
end
|
|
|
|
if (self.Inputs.IOBus.Src) then
|
|
|
|
if (self.Inputs.IOBus.Src.LatchStore) then
|
|
|
|
if (self.Inputs.IOBus.Src.LatchStore[math.floor(Address)]) then
|
|
|
|
return self.Inputs.IOBus.Src.LatchStore[math.floor(Address)]
|
|
|
|
else
|
|
|
|
self.LADD = -math.floor(Address)
|
|
|
|
self:Interrupt(10)
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
elseif (self.Inputs.IOBus.Src.ReadCell) then
|
|
|
|
local var = self.Inputs.IOBus.Src:ReadCell(math.floor(Address))
|
|
|
|
if (var) then
|
|
|
|
return var
|
|
|
|
else
|
|
|
|
self.LADD = -math.floor(Address)
|
|
|
|
self:Interrupt(10)
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
else
|
|
|
|
self.LADD = -math.floor(Address)
|
|
|
|
self:Interrupt(8)
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
else
|
2007-05-18 20:08:04 +00:00
|
|
|
return 0
|
2007-04-12 19:16:47 +00:00
|
|
|
end
|
|
|
|
end
|
2007-03-21 21:09:01 +00:00
|
|
|
|
2007-04-12 19:16:47 +00:00
|
|
|
function ENT:WritePort( Address, value )
|
|
|
|
if (self.INTR) then //Lock the bus
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
|
|
|
|
if (Address < 0) then
|
|
|
|
self.LADD = -math.floor(Address)
|
|
|
|
self:Interrupt(8)
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
if (self.Inputs.IOBus.Src) then
|
|
|
|
if (self.Inputs.IOBus.Src.LatchStore) then
|
|
|
|
if (self.Inputs.IOBus.Src.LatchStore[math.floor(Address)]) then
|
|
|
|
self.Inputs.IOBus.Src.LatchStore[math.floor(Address)] = value
|
|
|
|
return true
|
|
|
|
else
|
|
|
|
self.LADD = -math.floor(Address)
|
|
|
|
self:Interrupt(10)
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
elseif (self.Inputs.IOBus.Src.WriteCell) then
|
|
|
|
if (self.Inputs.IOBus.Src:WriteCell(math.floor(Address),value)) then
|
|
|
|
return true
|
|
|
|
else
|
|
|
|
self.LADD = -math.floor(Address)
|
|
|
|
self:Interrupt(10)
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
else
|
|
|
|
self.LADD = -math.floor(Address)
|
|
|
|
self:Interrupt(8)
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
else
|
2007-05-18 20:08:04 +00:00
|
|
|
return true
|
2007-03-21 21:09:01 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2007-04-12 19:16:47 +00:00
|
|
|
function ENT:Push(value)
|
|
|
|
if (self.INTR) then //Lock the bus
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
|
|
|
|
self:WriteCell(self.ESP+self.SS,value)
|
|
|
|
self.ESP = self.ESP - 1
|
|
|
|
if (self.ESP < 0) then
|
|
|
|
self.ESP = 0
|
|
|
|
self:Interrupt(6)
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
function ENT:Pop()
|
|
|
|
if (self.INTR) then //Lock the bus
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
|
|
|
|
self.ESP = self.ESP + 1
|
|
|
|
if (self.ESP > 65535) then
|
|
|
|
self.ESP = 65535
|
|
|
|
self:Interrupt(6)
|
|
|
|
return nil
|
|
|
|
else
|
|
|
|
return self:ReadCell(self.ESP+self.SS)
|
2007-03-21 21:09:01 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
//CPUID
|
|
|
|
//Value | EAX
|
|
|
|
//--------------------------------------------
|
|
|
|
//0 | CPU Version
|
|
|
|
//1 | RAM Size
|
|
|
|
//--------------------------------------------
|
|
|
|
|
2007-11-08 21:45:54 +00:00
|
|
|
function ENT:InitializeOpcodeTable()
|
|
|
|
self.OpcodeTable = {}
|
2007-04-12 19:16:47 +00:00
|
|
|
|
2007-11-08 21:45:54 +00:00
|
|
|
self.OpcodeTable[0] = function () //END
|
|
|
|
self:Interrupt(2)
|
2007-04-12 19:16:47 +00:00
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.OpcodeTable[1] = function () //JNE
|
|
|
|
if (self.CMPR ~= 0) then
|
2007-11-10 23:10:57 +00:00
|
|
|
self.IP = self.Params[1]
|
2007-04-12 19:16:47 +00:00
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
2007-04-12 19:16:47 +00:00
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.OpcodeTable[2] = function () //JMP
|
2007-11-10 23:10:57 +00:00
|
|
|
self.IP = self.Params[1]
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
2007-03-21 21:09:01 +00:00
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.OpcodeTable[3] = function () //JG
|
2007-03-21 21:09:01 +00:00
|
|
|
if (self.CMPR > 0) then
|
2007-11-10 23:10:57 +00:00
|
|
|
self.IP = self.Params[1]
|
2007-03-21 21:09:01 +00:00
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[4] = function () //JGE
|
2007-03-21 21:09:01 +00:00
|
|
|
if (self.CMPR >= 0) then
|
2007-11-10 23:10:57 +00:00
|
|
|
self.IP = self.Params[1]
|
2007-03-21 21:09:01 +00:00
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[5] = function () //JL
|
2007-03-21 21:09:01 +00:00
|
|
|
if (self.CMPR < 0) then
|
2007-11-10 23:10:57 +00:00
|
|
|
self.IP = self.Params[1]
|
2007-03-21 21:09:01 +00:00
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[6] = function () //JLE
|
2007-03-21 21:09:01 +00:00
|
|
|
if (self.CMPR <= 0) then
|
2007-11-10 23:10:57 +00:00
|
|
|
self.IP = self.Params[1]
|
2007-03-21 21:09:01 +00:00
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[7] = function () //JE
|
2007-03-21 21:09:01 +00:00
|
|
|
if (self.CMPR == 0) then
|
2007-11-10 23:10:57 +00:00
|
|
|
self.IP = self.Params[1]
|
2007-03-21 21:09:01 +00:00
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
2007-03-21 21:09:01 +00:00
|
|
|
//============================================================
|
2007-11-08 21:45:54 +00:00
|
|
|
self.OpcodeTable[8] = function () //CPUID
|
2007-11-10 23:10:57 +00:00
|
|
|
if (self.Params[1] == 0) then //CPU VERSION
|
|
|
|
self.EAX = 291 //= 3.00 BETA 2
|
|
|
|
elseif (self.Params[1] == 1) then //AMOUNT OF RAM
|
|
|
|
self.EAX = 65536 //= 64KB
|
|
|
|
elseif (self.Params[1] == 2) then //TYPE (0 - ZCPU; 1 - ZGPU)
|
|
|
|
self.EAX = 0 //= ZCPU
|
2007-03-21 21:09:01 +00:00
|
|
|
else
|
|
|
|
self.EAX = 0
|
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
2007-03-21 21:09:01 +00:00
|
|
|
//============================================================
|
2007-11-08 21:45:54 +00:00
|
|
|
self.OpcodeTable[9] = function () //PUSH
|
2007-11-10 23:10:57 +00:00
|
|
|
//self.Memory[ESP] = self.Params[1]
|
|
|
|
self:Push(self.Params[1])
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
2007-03-21 21:09:01 +00:00
|
|
|
//------------------------------------------------------------
|
2007-11-08 21:45:54 +00:00
|
|
|
self.OpcodeTable[10] = function () //ADD
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = self.Params[1] + self.Params[2]
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[11] = function () //SUB
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = self.Params[1] - self.Params[2]
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[12] = function () //MUL
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = self.Params[1] * self.Params[2]
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[13] = function () //DIV
|
2007-11-10 23:10:57 +00:00
|
|
|
if (math.abs(self.Params[2]) < 0.0000000001) then
|
2007-04-12 19:16:47 +00:00
|
|
|
self:Interrupt(3)
|
2007-03-21 21:09:01 +00:00
|
|
|
else
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = self.Params[1] / self.Params[2]
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
self.OpcodeTable[14] = function () //MOV
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = self.Params[2]
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[15] = function () //CMP
|
2007-11-10 23:10:57 +00:00
|
|
|
self.CMPR = self.Params[1] - self.Params[2]
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[16] = function () //RD
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = self.Memory[self.Params[2]]
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[17] = function () //WD
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Memory[self.Params[1]] = self.Params[2]
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[18] = function () //MIN
|
2007-11-10 23:10:57 +00:00
|
|
|
if (tonumber(self.Params[2]) < tonumber(self.Params[1])) then
|
|
|
|
self.Result = self.Params[2]
|
2007-03-21 21:09:01 +00:00
|
|
|
else
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = self.Params[1]
|
2007-03-21 21:09:01 +00:00
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[19] = function () //MAX
|
2007-11-10 23:10:57 +00:00
|
|
|
if (tonumber(self.Params[2]) > tonumber(self.Params[1])) then
|
|
|
|
self.Result = self.Params[2]
|
2007-03-21 21:09:01 +00:00
|
|
|
else
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = self.Params[1]
|
2007-03-21 21:09:01 +00:00
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
2007-03-21 21:09:01 +00:00
|
|
|
//------------------------------------------------------------
|
2007-11-08 21:45:54 +00:00
|
|
|
self.OpcodeTable[20] = function () //INC
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = self.Params[1] + 1
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[21] = function () //DEC
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = self.Params[1] - 1
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[22] = function () //NEG
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = -self.Params[1]
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[23] = function () //RAND
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = math.random()
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[24] = function () //LOOP
|
2007-04-12 19:16:47 +00:00
|
|
|
if (self.ECX ~= 0) then
|
2007-11-10 23:10:57 +00:00
|
|
|
self.IP = self.Params[1]
|
2007-04-24 16:04:39 +00:00
|
|
|
self.ECX = self.ECX-1
|
2007-04-12 19:16:47 +00:00
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[25] = function () //LOOPA
|
2007-04-12 19:16:47 +00:00
|
|
|
if (self.EAX ~= 0) then
|
2007-11-10 23:10:57 +00:00
|
|
|
self.IP = self.Params[1]
|
2007-04-12 19:16:47 +00:00
|
|
|
self.EAX = self.EAX-1
|
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[26] = function () //LOOPB
|
2007-04-12 19:16:47 +00:00
|
|
|
if (self.EBX ~= 0) then
|
2007-11-10 23:10:57 +00:00
|
|
|
self.IP = self.Params[1]
|
2007-04-24 16:04:39 +00:00
|
|
|
self.EBX = self.EBX-1
|
2007-04-12 19:16:47 +00:00
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[27] = function () //LOOPD
|
2007-04-12 19:16:47 +00:00
|
|
|
if (self.EDX ~= 0) then
|
2007-11-10 23:10:57 +00:00
|
|
|
self.IP = self.Params[1]
|
2007-04-24 16:04:39 +00:00
|
|
|
self.EDX = self.EDX-1
|
2007-04-12 19:16:47 +00:00
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[28] = function () //SPG
|
2007-11-10 23:10:57 +00:00
|
|
|
if (math.floor(self.Params[1] / 128) >= 0) && (math.floor(self.Params[1] / 128) < 512) then
|
|
|
|
Page[math.floor(self.Params[1] / 128)] = false
|
2007-03-21 21:09:01 +00:00
|
|
|
else
|
2007-04-12 19:16:47 +00:00
|
|
|
self:Interrupt(12)
|
2007-03-21 21:09:01 +00:00
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[29] = function () //CPG
|
2007-11-10 23:10:57 +00:00
|
|
|
if (math.floor(self.Params[1] / 128) >= 0) && (math.floor(self.Params[1] / 128) < 512) then
|
|
|
|
Page[math.floor(self.Params[1] / 128)] = true
|
2007-03-21 21:09:01 +00:00
|
|
|
else
|
2007-04-12 19:16:47 +00:00
|
|
|
self:Interrupt(12)
|
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
2007-04-12 19:16:47 +00:00
|
|
|
//------------------------------------------------------------
|
2007-11-08 21:45:54 +00:00
|
|
|
self.OpcodeTable[30] = function () //POP
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = self:Pop()
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[31] = function () //CALL
|
2007-04-12 19:16:47 +00:00
|
|
|
if self:Push(self.IP) then
|
2007-11-10 23:10:57 +00:00
|
|
|
self.IP = self.Params[1]
|
2007-03-21 21:09:01 +00:00
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[32] = function () //NOT
|
2007-11-10 23:10:57 +00:00
|
|
|
if self.Params[1] <= 0 then
|
|
|
|
self.Result = 1
|
2007-03-21 21:09:01 +00:00
|
|
|
else
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = 0
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
self.OpcodeTable[33] = function () //FINT
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = math.floor(self.Params[1])
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[34] = function () //RND
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = math.round(self.Params[1])
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[35] = function () //FLOOR
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = self.Params[1] - math.floor(self.Params[1])
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[36] = function () //INV
|
2007-11-10 23:10:57 +00:00
|
|
|
if (math.abs(self.Params[1]) < 0.0000000001) then
|
2007-04-12 19:16:47 +00:00
|
|
|
self:Interrupt(3)
|
2007-03-21 21:09:01 +00:00
|
|
|
else
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = 1 / self.Params[1]
|
2007-03-21 21:09:01 +00:00
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[37] = function () //HALT
|
2007-11-10 23:10:57 +00:00
|
|
|
self.HaltPort = math.Clamp(math.floor(self.Params[1]),0,7)
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[38] = function () //FSHL
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = math.floor(self.Params[1] * 2)
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[39] = function () //FSHR
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = math.floor(self.Params[1] / 2)
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
2007-03-21 21:09:01 +00:00
|
|
|
//------------------------------------------------------------
|
2007-11-08 21:45:54 +00:00
|
|
|
self.OpcodeTable[40] = function () //RET
|
2007-04-12 19:16:47 +00:00
|
|
|
local newIP = self:Pop()
|
|
|
|
if (newIP) then
|
|
|
|
self.IP = newIP
|
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[41] = function () //IRET
|
2007-04-12 19:16:47 +00:00
|
|
|
local newIP = self:Pop()
|
|
|
|
if (newIP) then
|
|
|
|
self.IP = newIP
|
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[42] = function () //STI
|
2007-04-12 19:16:47 +00:00
|
|
|
self.IF = true
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[43] = function () //CLI
|
2007-04-12 19:16:47 +00:00
|
|
|
self.IF = false
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[44] = function () //STP
|
2007-04-12 19:16:47 +00:00
|
|
|
self.PF = true
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[45] = function () //CLP
|
2007-04-12 19:16:47 +00:00
|
|
|
self.PF = false
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[46] = function () //STD
|
2007-04-12 19:16:47 +00:00
|
|
|
//self.Debug = true
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[47] = function () //RETF
|
2007-04-12 19:16:47 +00:00
|
|
|
local newIP = self:Pop()
|
|
|
|
local newCS = self:Pop()
|
|
|
|
if (newIP) && (newCS) then
|
|
|
|
self.IP = newIP
|
|
|
|
self.CS = newCS
|
2007-03-21 21:09:01 +00:00
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[48] = function () //RCMPR
|
2007-05-17 21:30:52 +00:00
|
|
|
self.EAX = self.CMPR
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[49] = function () //TMR
|
2007-04-12 19:16:47 +00:00
|
|
|
self.EAX = self.TMR
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
2007-03-21 21:09:01 +00:00
|
|
|
//------------------------------------------------------------
|
2007-11-08 21:45:54 +00:00
|
|
|
self.OpcodeTable[50] = function () //AND
|
2007-11-10 23:10:57 +00:00
|
|
|
if (self.Params[1] > 0) && (self.Params[2] > 0) then
|
|
|
|
self.Result = 1
|
2007-03-21 21:09:01 +00:00
|
|
|
else
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = 0
|
2007-03-21 21:09:01 +00:00
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[51] = function () //OR
|
2007-11-10 23:10:57 +00:00
|
|
|
if (self.Params[1] > 0) || (self.Params[2] > 0) then
|
|
|
|
self.Result = 1
|
2007-03-21 21:09:01 +00:00
|
|
|
else
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = 0
|
2007-03-21 21:09:01 +00:00
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[52] = function () //XOR
|
2007-11-10 23:10:57 +00:00
|
|
|
if ((self.Params[1] > 0) && (self.Params[2] <= 0)) ||
|
|
|
|
((self.Params[1] <= 0) && (self.Params[2] > 0)) then
|
|
|
|
self.Result = 1
|
2007-03-21 21:09:01 +00:00
|
|
|
else
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = 0
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
self.OpcodeTable[53] = function () //FSIN
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = math.sin(self.Params[2])
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[54] = function () //FCOS
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = math.cos(self.Params[2])
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[55] = function () //FTAN
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = math.tan(self.Params[2])
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[56] = function () //FASIN
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = math.asin(self.Params[2])
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[57] = function () //FACOS
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = math.acos(self.Params[2])
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[58] = function () //FATAN
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = math.atan(self.Params[2])
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[59] = function () //MOD
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = math.fmod(self.Params[1],self.Params[2])
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
2007-03-21 21:09:01 +00:00
|
|
|
//------------------------------------------------------------
|
2007-11-08 21:45:54 +00:00
|
|
|
self.OpcodeTable[60] = function () //BIT
|
2007-11-10 23:10:57 +00:00
|
|
|
local temp = self.Params[1]
|
|
|
|
for i = 0,math.Clamp(self.Params[2],0,7)-1 do
|
2007-05-16 19:53:47 +00:00
|
|
|
temp = math.floor(temp / 10)
|
|
|
|
end
|
2007-05-18 20:08:04 +00:00
|
|
|
self.CMPR = math.fmod(temp,10)
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[61] = function () //SBIT
|
2007-11-10 23:10:57 +00:00
|
|
|
local temp = self.Params[1]
|
2007-05-16 19:53:47 +00:00
|
|
|
local temp2 = 0
|
|
|
|
local temp3 = 1
|
|
|
|
for i = 0,7 do
|
2007-11-10 23:10:57 +00:00
|
|
|
if (i == self.Params[2]) then
|
2007-05-16 19:53:47 +00:00
|
|
|
temp2 = temp2 + temp3*1
|
|
|
|
else
|
|
|
|
temp2 = temp2 + temp3*math.fmod(temp,10)
|
|
|
|
end
|
|
|
|
temp = math.floor(temp / 10)
|
|
|
|
temp3 = temp3*10
|
|
|
|
end
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = temp2
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[62] = function () //CBIT
|
2007-11-10 23:10:57 +00:00
|
|
|
local temp = self.Params[1]
|
2007-05-16 19:53:47 +00:00
|
|
|
local temp2 = 0
|
|
|
|
local temp3 = 1
|
|
|
|
for i = 0,7 do
|
2007-11-10 23:10:57 +00:00
|
|
|
if (i == self.Params[2]) then
|
2007-05-16 19:53:47 +00:00
|
|
|
temp2 = temp2 + temp3*0
|
|
|
|
else
|
|
|
|
temp2 = temp2 + temp3*math.fmod(temp,10)
|
|
|
|
end
|
|
|
|
temp = math.floor(temp / 10)
|
|
|
|
temp3 = temp3*10
|
|
|
|
end
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = temp2
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[69] = function () //JMPF
|
2007-11-10 23:10:57 +00:00
|
|
|
self.CS = self.Params[2]
|
|
|
|
self.IP = self.Params[1]
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
2007-04-12 19:16:47 +00:00
|
|
|
//------------------------------------------------------------
|
2007-11-08 21:45:54 +00:00
|
|
|
self.OpcodeTable[71] = function () //CNE
|
2007-04-12 19:16:47 +00:00
|
|
|
if (self.CMPR ~= 0) then
|
|
|
|
if self:Push(self.IP) then
|
2007-11-10 23:10:57 +00:00
|
|
|
self.IP = self.Params[1]
|
2007-03-21 21:09:01 +00:00
|
|
|
end
|
2007-04-12 19:16:47 +00:00
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[72] = function () //CJMP
|
2007-04-12 19:16:47 +00:00
|
|
|
if self:Push(self.IP) then
|
2007-11-10 23:10:57 +00:00
|
|
|
self.IP = self.Params[1]
|
2007-04-12 19:16:47 +00:00
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[73] = function () //CG
|
2007-04-12 19:16:47 +00:00
|
|
|
if (self.CMPR > 0) then
|
|
|
|
if self:Push(self.IP) then
|
2007-11-10 23:10:57 +00:00
|
|
|
self.IP = self.Params[1]
|
2007-03-21 21:09:01 +00:00
|
|
|
end
|
2007-04-12 19:16:47 +00:00
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[74] = function () //CGE
|
2007-04-12 19:16:47 +00:00
|
|
|
if (self.CMPR >= 0) then
|
|
|
|
if self:Push(self.IP) then
|
2007-11-10 23:10:57 +00:00
|
|
|
self.IP = self.Params[1]
|
2007-03-21 21:09:01 +00:00
|
|
|
end
|
2007-04-12 19:16:47 +00:00
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[75] = function () //CL
|
2007-04-12 19:16:47 +00:00
|
|
|
if (self.CMPR < 0) then
|
|
|
|
if self:Push(self.IP) then
|
2007-11-10 23:10:57 +00:00
|
|
|
self.IP = self.Params[1]
|
2007-03-21 21:09:01 +00:00
|
|
|
end
|
2007-04-12 19:16:47 +00:00
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[76] = function () //CLE
|
2007-04-12 19:16:47 +00:00
|
|
|
if (self.CMPR <= 0) then
|
|
|
|
if self:Push(self.IP) then
|
2007-11-10 23:10:57 +00:00
|
|
|
self.IP = self.Params[1]
|
2007-03-21 21:09:01 +00:00
|
|
|
end
|
2007-04-12 19:16:47 +00:00
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[77] = function () //CE
|
2007-04-12 19:16:47 +00:00
|
|
|
if (self.CMPR == 0) then
|
|
|
|
if self:Push(self.IP) then
|
2007-11-10 23:10:57 +00:00
|
|
|
self.IP = self.Params[1]
|
2007-03-21 21:09:01 +00:00
|
|
|
end
|
2007-04-12 19:16:47 +00:00
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[78] = function () //MCOPY
|
2007-11-10 23:10:57 +00:00
|
|
|
if (self.Params[1] == 0) then return end
|
|
|
|
for i = 1,math.Clamp(self.Params[1],1,8192) do
|
2007-04-12 19:16:47 +00:00
|
|
|
local val
|
|
|
|
val = self:ReadCell(self.ESI+segment1)
|
|
|
|
if (val == nil) then return end
|
|
|
|
if (self:WriteCell(self.EDI+segment2,val) == false) then return end
|
|
|
|
self.EDI = self.EDI + 1
|
|
|
|
self.ESI = self.ESI + 1
|
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[79] = function () //MXCHG
|
2007-11-10 23:10:57 +00:00
|
|
|
if (self.Params[1] == 0) then return end
|
|
|
|
for i = 1,math.Clamp(self.Params[1],1,8192) do
|
2007-04-12 19:16:47 +00:00
|
|
|
local val
|
|
|
|
val1 = self:ReadCell(self.ESI+segment1)
|
|
|
|
val2 = self:ReadCell(self.EDI+segment2)
|
|
|
|
if (val1 == nil) || (val2 == nil) then return end
|
|
|
|
if (self:WriteCell(self.EDI+segment2,val1) == false) || (self:WriteCell(self.ESI+segment1,val2) == false) then return end
|
|
|
|
self.EDI = self.EDI + 1
|
|
|
|
self.ESI = self.ESI + 1
|
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
2007-04-12 19:16:47 +00:00
|
|
|
//------------------------------------------------------------
|
2007-11-08 21:45:54 +00:00
|
|
|
self.OpcodeTable[80] = function () //FPWR
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = self.Params[1]^self.Params[2]
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[81] = function () //XCHG
|
2007-11-10 23:10:57 +00:00
|
|
|
local val1 = self.Params[2]
|
|
|
|
local val2 = self.Params[1]
|
|
|
|
|
|
|
|
self.Result = val1
|
|
|
|
if (self.dRM2 == 1) then self.EAX = val2
|
|
|
|
elseif (self.dRM2 == 2) then self.EBX = val2
|
|
|
|
elseif (self.dRM2 == 3) then self.ECX = val2
|
|
|
|
elseif (self.dRM2 == 4) then self.EDX = val2
|
|
|
|
elseif (self.dRM2 == 5) then self.ESI = val2
|
|
|
|
elseif (self.dRM2 == 6) then self.EDI = val2
|
|
|
|
elseif (self.dRM2 == 7) then self.ESP = val2
|
|
|
|
elseif (self.dRM2 == 8) then self.EBP = val2
|
|
|
|
elseif (self.dRM2 == 9) then self:Interrupt(13)
|
|
|
|
elseif (self.dRM2 == 10) then self.SS = val2
|
|
|
|
elseif (self.dRM2 == 11) then self.DS = val2
|
|
|
|
elseif (self.dRM2 == 12) then self.ES = val2
|
|
|
|
elseif (self.dRM2 == 13) then self.GS = val2
|
|
|
|
elseif (self.dRM2 == 14) then self.FS = val2
|
|
|
|
elseif (self.dRM2 >= 17) && (self.dRM2 <= 25) then
|
|
|
|
self:WriteCell(self.Disp2+self.Segment2,val2)
|
|
|
|
elseif (self.dRM2 >= 1000) && (self.dRM2 <= 2024) then
|
|
|
|
self:WritePort(self.dRM2-1000,val2)
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
self.OpcodeTable[82] = function () //FLOG
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = math.log(self.Params[2])
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[83] = function () //FLOG10
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = math.log10(self.Params[2])
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[84] = function () //IN
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = self:ReadPort(self.Params[2])
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[85] = function () //OUT
|
2007-11-10 23:10:57 +00:00
|
|
|
self:WritePort(self.Params[1],self.Params[2])
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[86] = function () //FABS
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = math.abs(self.Params[2])
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[87] = function () //FSGN
|
2007-11-10 23:10:57 +00:00
|
|
|
if (self.Params[2] > 0) then
|
|
|
|
self.Result = 1
|
|
|
|
elseif (self.Params[2] < 0) then
|
|
|
|
self.Result = -1
|
2007-04-12 19:16:47 +00:00
|
|
|
else
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = 0
|
2007-04-12 19:16:47 +00:00
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[88] = function () //FEXP
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = math.exp(self.Params[2])
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[89] = function () //CALLF
|
2007-04-12 19:16:47 +00:00
|
|
|
if self:Push(self.CS) && self:Push(self.IP) then
|
2007-11-10 23:10:57 +00:00
|
|
|
self.IP = self.Params[1]
|
|
|
|
self.CS = self.Params[2]
|
2007-04-12 19:16:47 +00:00
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
2007-04-12 19:16:47 +00:00
|
|
|
//------------------------------------------------------------
|
2007-11-08 21:45:54 +00:00
|
|
|
self.OpcodeTable[90] = function () //FPI
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = 3.141592653589793
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[91] = function () //FE
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = 2.718281828459045
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[92] = function () //INT
|
2007-11-10 23:10:57 +00:00
|
|
|
self:Interrupt(tonumber(self.Params[1]))
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[93] = function () //TPG
|
2007-11-10 23:10:57 +00:00
|
|
|
local tadd = self.Params[1]*128
|
2007-04-12 19:16:47 +00:00
|
|
|
self.CMPR = 0
|
2007-11-10 23:10:57 +00:00
|
|
|
while (tadd < self.Params[1]*128+128) do
|
2007-04-12 19:16:47 +00:00
|
|
|
local val = self:ReadCell(tadd)
|
|
|
|
if (val == nil) then
|
|
|
|
self.CMPR = tadd
|
2007-11-10 23:10:57 +00:00
|
|
|
tadd = self.Params[1]*128+128
|
2007-03-21 21:09:01 +00:00
|
|
|
end
|
2007-04-12 19:16:47 +00:00
|
|
|
tadd = tadd + 1
|
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[94] = function () //FCEIL
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = math.ceil(self.Params[1])
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[95] = function () //ERPG
|
2007-11-10 23:10:57 +00:00
|
|
|
if (self.Params[1] >= 0) && (self.Params[1] < 512) then
|
|
|
|
local tadd = self.Params[1]*128
|
|
|
|
while (tadd < self.Params[1]*128+128) do
|
2007-04-12 19:16:47 +00:00
|
|
|
self.ROMMemory[tadd] = 0
|
|
|
|
tadd = tadd + 1
|
2007-03-21 21:09:01 +00:00
|
|
|
end
|
2007-04-12 19:16:47 +00:00
|
|
|
else
|
|
|
|
self:Interrupt(12)
|
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[96] = function () //WRPG
|
2007-11-10 23:10:57 +00:00
|
|
|
if (self.Params[1] >= 0) && (self.Params[1] < 512) then
|
|
|
|
local tadd = self.Params[1]*128
|
|
|
|
while (tadd < self.Params[1]*128+128) do
|
2007-04-12 19:16:47 +00:00
|
|
|
self.ROMMemory[tadd] = self.Memory[tadd]
|
|
|
|
tadd = tadd + 1
|
2007-03-21 21:09:01 +00:00
|
|
|
end
|
|
|
|
else
|
2007-04-12 19:16:47 +00:00
|
|
|
self:Interrupt(12)
|
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[97] = function () //RDPG
|
2007-11-10 23:10:57 +00:00
|
|
|
if (self.Params[1] >= 0) && (self.Params[1] < 512) then
|
|
|
|
local tadd = self.Params[1]*128
|
|
|
|
while (tadd < self.Params[1]*128+128) do
|
2007-04-12 19:16:47 +00:00
|
|
|
self.Memory[tadd] = self.ROMMemory[tadd]
|
|
|
|
tadd = tadd + 1
|
2007-03-21 21:09:01 +00:00
|
|
|
end
|
2007-04-12 19:16:47 +00:00
|
|
|
else
|
|
|
|
self:Interrupt(12)
|
2007-03-21 21:09:01 +00:00
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[98] = function () //TIMER
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Result = self.TIMER
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
self.OpcodeTable[99] = function () //LIDTR
|
2007-11-10 23:10:57 +00:00
|
|
|
self.IDTR = self.Params[1]
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
2007-04-12 19:16:47 +00:00
|
|
|
//------------------------------------------------------------
|
2007-11-08 21:45:54 +00:00
|
|
|
self.OpcodeTable[101] = function () //JNER
|
2007-05-16 19:53:47 +00:00
|
|
|
if (self.CMPR ~= 0) then
|
2007-11-10 23:10:57 +00:00
|
|
|
self.IP = self.IP + self.Params[1]
|
2007-05-16 19:53:47 +00:00
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[102] = function () //JMPR
|
2007-11-10 23:10:57 +00:00
|
|
|
self.IP = self.IP + self.Params[1]
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[103] = function () //JGR
|
2007-05-16 19:53:47 +00:00
|
|
|
if (self.CMPR > 0) then
|
2007-11-10 23:10:57 +00:00
|
|
|
self.IP = self.IP + self.Params[1]
|
2007-05-16 19:53:47 +00:00
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[104] = function () //JGER
|
2007-05-16 19:53:47 +00:00
|
|
|
if (self.CMPR >= 0) then
|
2007-11-10 23:10:57 +00:00
|
|
|
self.IP = self.IP + self.Params[1]
|
2007-05-16 19:53:47 +00:00
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[105] = function () //JLR
|
2007-05-16 19:53:47 +00:00
|
|
|
if (self.CMPR < 0) then
|
2007-11-10 23:10:57 +00:00
|
|
|
self.IP = self.IP + self.Params[1]
|
2007-05-16 19:53:47 +00:00
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[106] = function () //JLER
|
2007-05-16 19:53:47 +00:00
|
|
|
if (self.CMPR <= 0) then
|
2007-11-10 23:10:57 +00:00
|
|
|
self.IP = self.IP + self.Params[1]
|
2007-05-16 19:53:47 +00:00
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
|
|
|
self.OpcodeTable[107] = function () //JER
|
2007-05-16 19:53:47 +00:00
|
|
|
if (self.CMPR == 0) then
|
2007-11-10 23:10:57 +00:00
|
|
|
self.IP = self.IP + self.Params[1]
|
2007-05-16 19:53:47 +00:00
|
|
|
end
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
2007-05-16 19:53:47 +00:00
|
|
|
//------------------------------------------------------------
|
2007-11-08 21:45:54 +00:00
|
|
|
self.OpcodeTable[110] = function () //NMIRET
|
2007-05-16 19:53:47 +00:00
|
|
|
local newval
|
|
|
|
newval = self:Pop() if (newval) then self.IP = newval else return end
|
|
|
|
newval = self:Pop() if (newval) then self.CMPR = newval else return end
|
|
|
|
|
|
|
|
newval = self:Pop() if (newval) then self.EAX = newval else return end
|
|
|
|
newval = self:Pop() if (newval) then self.EBX = newval else return end
|
|
|
|
newval = self:Pop() if (newval) then self.ECX = newval else return end
|
|
|
|
newval = self:Pop() if (newval) then self.EDX = newval else return end
|
|
|
|
newval = self:Pop() if (newval) then self.EBP = newval else return end
|
|
|
|
newval = self:Pop() if (newval) then else return end //ESP - not now
|
|
|
|
newval = self:Pop() if (newval) then self.ESI = newval else return end
|
|
|
|
newval = self:Pop() if (newval) then self.EDI = newval else return end
|
|
|
|
|
|
|
|
newval = self:Pop() if (newval) then self.CS = newval else return end
|
|
|
|
newval = self:Pop() if (newval) then else return end //SS - not now
|
|
|
|
newval = self:Pop() if (newval) then self.DS = newval else return end
|
|
|
|
newval = self:Pop() if (newval) then self.FS = newval else return end
|
|
|
|
newval = self:Pop() if (newval) then self.GS = newval else return end
|
|
|
|
newval = self:Pop() if (newval) then self.ES = newval else return end
|
|
|
|
|
2007-11-08 21:45:54 +00:00
|
|
|
self.WriteBack = false
|
|
|
|
end
|
2007-05-16 19:53:47 +00:00
|
|
|
//------------------------------------------------------------
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function ENT:Execute( )
|
|
|
|
self.DeltaTime = CurTime()-(self.PrevTime or CurTime())
|
|
|
|
self.PrevTime = (self.PrevTime or CurTime())+self.DeltaTime
|
|
|
|
|
|
|
|
self.TIMER = self.TIMER + self.DeltaTime
|
|
|
|
self.TMR = self.TMR + 1
|
|
|
|
if (self.Debug) then
|
|
|
|
Msg(">TMR="..self.TMR.." IP="..self.IP.." ");
|
|
|
|
end
|
|
|
|
|
|
|
|
if (!self.IP) then
|
|
|
|
Self:Reset()
|
|
|
|
Wire_TriggerOutput(self.Entity, "Error", 5.0)
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
self.XEIP = self.IP
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Opcode = self:Read( )
|
|
|
|
self.RM = self:Read( )
|
|
|
|
self.Params = {0, 0}
|
|
|
|
self.Result = 0
|
2007-11-08 21:45:54 +00:00
|
|
|
|
|
|
|
if (self.Debug) then
|
|
|
|
Msg("OPCODE="..opcode.." RM="..rm.." ");
|
|
|
|
end
|
|
|
|
|
2007-11-10 23:10:57 +00:00
|
|
|
if (self.Opcode) then
|
|
|
|
self.ILTC = self.Opcode
|
2007-11-08 21:45:54 +00:00
|
|
|
else
|
|
|
|
self.ILTC = -1
|
|
|
|
end
|
|
|
|
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Disp1 = 0
|
|
|
|
self.Disp2 = 0
|
2007-11-08 21:45:54 +00:00
|
|
|
|
2007-11-10 23:10:57 +00:00
|
|
|
if (self.Opcode == nil) || (self.RM == nil) then
|
2007-11-08 21:45:54 +00:00
|
|
|
self.INTR = false
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Opcode = self.Opcode + 1 - 1 //Dont laugh, it helps
|
2007-11-08 21:45:54 +00:00
|
|
|
|
2007-11-10 23:10:57 +00:00
|
|
|
self.dRM2 = math.floor(self.RM / 10000)
|
|
|
|
self.dRM1 = self.RM - self.dRM2*10000
|
2007-11-08 21:45:54 +00:00
|
|
|
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Segment1 = self.DS
|
|
|
|
self.Segment2 = self.DS
|
2007-11-08 21:45:54 +00:00
|
|
|
|
|
|
|
//Fix problem here (the lua buttfux one):
|
2007-11-10 23:10:57 +00:00
|
|
|
if (self.Opcode > 1000) then
|
|
|
|
if (self.Opcode > 10000) then
|
|
|
|
self.Segment2 = self:Read() //FIXME wrong order
|
|
|
|
self.Opcode = self.Opcode-10000
|
|
|
|
if (self.Opcode > 1000) then
|
|
|
|
self.Segment1 = self.self:Read()
|
|
|
|
self.Opcode = self.Opcode-1000
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
else
|
2007-11-10 23:10:57 +00:00
|
|
|
self.Segment1 = self.self:Read()
|
|
|
|
self.Opcode = self.Opcode-1000
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
//if (self.Debug) then
|
|
|
|
// Msg("OPCODE2="..opcode.." S1="..segment1.." S2="..segment2.." ");
|
|
|
|
//end
|
|
|
|
|
2007-11-10 23:10:57 +00:00
|
|
|
if (self.Segment1 == -2) then self.Segment1 = self.CS end
|
|
|
|
if (self.Segment1 == -3) then self.Segment1 = self.SS end
|
|
|
|
if (self.Segment1 == -4) then self.Segment1 = self.DS end
|
|
|
|
if (self.Segment1 == -5) then self.Segment1 = self.ES end
|
|
|
|
if (self.Segment1 == -6) then self.Segment1 = self.GS end
|
|
|
|
if (self.Segment1 == -7) then self.Segment1 = self.FS end
|
|
|
|
if (self.Segment2 == -2) then self.Segment2 = self.CS end
|
|
|
|
if (self.Segment2 == -3) then self.Segment2 = self.SS end
|
|
|
|
if (self.Segment2 == -4) then self.Segment2 = self.DS end
|
|
|
|
if (self.Segment2 == -5) then self.Segment2 = self.ES end
|
|
|
|
if (self.Segment2 == -6) then self.Segment2 = self.GS end
|
|
|
|
if (self.Segment2 == -7) then self.Segment2 = self.FS end
|
|
|
|
|
|
|
|
if (self.OpcodeCount[self.Opcode] && (self.OpcodeCount[self.Opcode] > 0)) then
|
|
|
|
if (self.dRM1 == 0) then self.Params[1] = self:Read( )
|
|
|
|
elseif (self.dRM1 == 1) then self.Params[1] = self.EAX
|
|
|
|
elseif (self.dRM1 == 2) then self.Params[1] = self.EBX
|
|
|
|
elseif (self.dRM1 == 3) then self.Params[1] = self.ECX
|
|
|
|
elseif (self.dRM1 == 4) then self.Params[1] = self.EDX
|
|
|
|
elseif (self.dRM1 == 5) then self.Params[1] = self.ESI
|
|
|
|
elseif (self.dRM1 == 6) then self.Params[1] = self.EDI
|
|
|
|
elseif (self.dRM1 == 7) then self.Params[1] = self.ESP
|
|
|
|
elseif (self.dRM1 == 8) then self.Params[1] = self.EBP
|
|
|
|
elseif (self.dRM1 == 9) then self.Params[1] = self.CS
|
|
|
|
elseif (self.dRM1 == 10) then self.Params[1] = self.SS
|
|
|
|
elseif (self.dRM1 == 11) then self.Params[1] = self.DS
|
|
|
|
elseif (self.dRM1 == 12) then self.Params[1] = self.ES
|
|
|
|
elseif (self.dRM1 == 13) then self.Params[1] = self.GS
|
|
|
|
elseif (self.dRM1 == 14) then self.Params[1] = self.FS
|
|
|
|
elseif (self.dRM1 == 17) then self.Disp1 = math.floor(self.EAX)
|
|
|
|
elseif (self.dRM1 == 18) then self.Disp1 = math.floor(self.EBX)
|
|
|
|
elseif (self.dRM1 == 19) then self.Disp1 = math.floor(self.ECX)
|
|
|
|
elseif (self.dRM1 == 20) then self.Disp1 = math.floor(self.EDX)
|
|
|
|
elseif (self.dRM1 == 21) then self.Disp1 = math.floor(self.ESI)
|
|
|
|
elseif (self.dRM1 == 22) then self.Disp1 = math.floor(self.EDI)
|
|
|
|
elseif (self.dRM1 == 23) then self.Disp1 = math.floor(self.ESP)
|
|
|
|
elseif (self.dRM1 == 24) then self.Disp1 = math.floor(self.EBP)
|
|
|
|
elseif (self.dRM1 == 25) then
|
2007-11-08 21:45:54 +00:00
|
|
|
local addr = self:Read( )
|
2007-11-10 23:10:57 +00:00
|
|
|
if (addr ~= nil) then self.Disp1 = math.floor(addr) end
|
|
|
|
end
|
|
|
|
if (self.dRM1 >= 17) && (self.dRM1 <= 25) then
|
|
|
|
self.Params[1] = self:ReadCell(self.Disp1+self.Segment1)
|
|
|
|
end
|
|
|
|
if (self.dRM1 >= 1000) && (self.dRM1 <= 2024) then
|
|
|
|
self.Params[1] = self:ReadPort(self.dRM1-1000)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if (self.OpcodeCount[self.Opcode] && (self.OpcodeCount[self.Opcode] > 1)) then
|
|
|
|
if (self.dRM2 == 0) then self.Params[2] = self:Read( )
|
|
|
|
elseif (self.dRM2 == 1) then self.Params[2] = self.EAX
|
|
|
|
elseif (self.dRM2 == 2) then self.Params[2] = self.EBX
|
|
|
|
elseif (self.dRM2 == 3) then self.Params[2] = self.ECX
|
|
|
|
elseif (self.dRM2 == 4) then self.Params[2] = self.EDX
|
|
|
|
elseif (self.dRM2 == 5) then self.Params[2] = self.ESI
|
|
|
|
elseif (self.dRM2 == 6) then self.Params[2] = self.EDI
|
|
|
|
elseif (self.dRM2 == 7) then self.Params[2] = self.ESP
|
|
|
|
elseif (self.dRM2 == 8) then self.Params[2] = self.EBP
|
|
|
|
elseif (self.dRM2 == 9) then self.Params[2] = self.CS
|
|
|
|
elseif (self.dRM2 == 10) then self.Params[2] = self.SS
|
|
|
|
elseif (self.dRM2 == 11) then self.Params[2] = self.DS
|
|
|
|
elseif (self.dRM2 == 12) then self.Params[2] = self.ES
|
|
|
|
elseif (self.dRM2 == 13) then self.Params[2] = self.GS
|
|
|
|
elseif (self.dRM2 == 14) then self.Params[2] = self.FS
|
|
|
|
elseif (self.dRM2 == 17) then self.Disp2 = math.floor(self.EAX)
|
|
|
|
elseif (self.dRM2 == 18) then self.Disp2 = math.floor(self.EBX)
|
|
|
|
elseif (self.dRM2 == 19) then self.Disp2 = math.floor(self.ECX)
|
|
|
|
elseif (self.dRM2 == 20) then self.Disp2 = math.floor(self.EDX)
|
|
|
|
elseif (self.dRM2 == 21) then self.Disp2 = math.floor(self.ESI)
|
|
|
|
elseif (self.dRM2 == 22) then self.Disp2 = math.floor(self.EDI)
|
|
|
|
elseif (self.dRM2 == 23) then self.Disp2 = math.floor(self.ESP)
|
|
|
|
elseif (self.dRM2 == 24) then self.Disp2 = math.floor(self.EBP)
|
|
|
|
elseif (self.dRM2 == 25) then
|
2007-11-08 21:45:54 +00:00
|
|
|
local addr = self:Read( )
|
2007-11-10 23:10:57 +00:00
|
|
|
if (addr ~= nil) then self.Disp2 = math.floor(addr) end
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
2007-11-10 23:10:57 +00:00
|
|
|
if (self.dRM2 >= 17) && (self.dRM2 <= 25) then
|
|
|
|
self.Params[2] = self:ReadCell(self.Disp2+self.Segment2)
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
2007-11-10 23:10:57 +00:00
|
|
|
if (self.dRM2 >= 1000) && (self.dRM2 <= 2024) then
|
|
|
|
self.Params[2] = self:ReadPort(self.dRM2-1000)
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if (self.Debug) then
|
2007-11-10 23:10:57 +00:00
|
|
|
if (self.Params[1] && self.Params[2]) then
|
|
|
|
Msg("PARAMS1="..self.Params[1].." PARAMS2="..self.Params[2].."\n");
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2007-11-10 23:10:57 +00:00
|
|
|
if (self.Params[1]) then
|
|
|
|
self.Params[1] = tonumber(self.Params[1])
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
2007-11-10 23:10:57 +00:00
|
|
|
if (self.Params[2]) then
|
|
|
|
self.Params[2] = tonumber(self.Params[2])
|
2007-11-08 21:45:54 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
if (self.INTR) then
|
|
|
|
self.INTR = false
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
self.WriteBack = true
|
2007-11-10 23:10:57 +00:00
|
|
|
|
|
|
|
if (self.OpcodeTable[self.Opcode]) then self.OpcodeTable[self.Opcode]()
|
|
|
|
else self:Interrupt(4) end
|
2007-03-21 21:09:01 +00:00
|
|
|
|
2007-04-12 19:16:47 +00:00
|
|
|
if (self.INTR) then
|
|
|
|
self.INTR = false
|
|
|
|
return
|
2007-03-21 21:09:01 +00:00
|
|
|
end
|
|
|
|
|
2007-11-10 23:10:57 +00:00
|
|
|
if (self.OpcodeCount[self.Opcode] && (self.OpcodeCount[self.Opcode] > 0)) &&
|
|
|
|
(self.dRM1 ~= 0) &&
|
|
|
|
(self.WriteBack) &&
|
|
|
|
(self.Clk == 1) then
|
|
|
|
if (self.dRM1 == 1) then self.EAX = self.Result
|
|
|
|
elseif (self.dRM1 == 2) then self.EBX = self.Result
|
|
|
|
elseif (self.dRM1 == 3) then self.ECX = self.Result
|
|
|
|
elseif (self.dRM1 == 4) then self.EDX = self.Result
|
|
|
|
elseif (self.dRM1 == 5) then self.ESI = self.Result
|
|
|
|
elseif (self.dRM1 == 6) then self.EDI = self.Result
|
|
|
|
elseif (self.dRM1 == 7) then self.ESP = self.Result
|
|
|
|
elseif (self.dRM1 == 8) then self.EBP = self.Result
|
|
|
|
elseif (self.dRM1 == 9) then self:Interrupt(13)
|
|
|
|
elseif (self.dRM1 == 10) then self.SS = self.Result
|
|
|
|
elseif (self.dRM1 == 11) then self.DS = self.Result
|
|
|
|
elseif (self.dRM1 == 12) then self.ES = self.Result
|
|
|
|
elseif (self.dRM1 == 13) then self.GS = self.Result
|
|
|
|
elseif (self.dRM1 == 14) then self.FS = self.Result
|
|
|
|
elseif (self.dRM1 >= 17) && (self.dRM1 <= 25) then
|
|
|
|
self:WriteCell(self.Disp1+self.Segment1,self.Result)
|
|
|
|
elseif (self.dRM1 >= 1000) && (self.dRM1 <= 2024) then
|
|
|
|
self:WritePort(self.dRM1-1000,self.Result)
|
2007-04-12 19:16:47 +00:00
|
|
|
end
|
2007-03-21 21:09:01 +00:00
|
|
|
end
|
|
|
|
|
2007-04-12 19:16:47 +00:00
|
|
|
if (self.INTR) then
|
|
|
|
self.INTR = false
|
|
|
|
end
|
2007-03-21 21:09:01 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function ENT:Use()
|
|
|
|
end
|
|
|
|
|
|
|
|
function ENT:Think()
|
|
|
|
self.BaseClass.Think(self)
|
2007-11-10 23:10:57 +00:00
|
|
|
|
|
|
|
self.CPUCyclesLeft = self.CPUCyclesLeft + self.ThinkTime*2.5
|
|
|
|
while (self.CPUCyclesLeft > 0) && (self.Clk >= 1.0) do
|
2007-10-24 14:11:05 +00:00
|
|
|
self:Execute()
|
2007-11-10 23:10:57 +00:00
|
|
|
self.CPUCyclesLeft = self.CPUCyclesLeft - 1
|
|
|
|
end
|
|
|
|
if (self.Clk >= 1.0) then
|
|
|
|
self.Entity:NextThink(CurTime()+0.025)
|
2007-03-21 21:09:01 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function ENT:TriggerInput(iname, value)
|
|
|
|
if (iname == "Clk") then
|
|
|
|
self.Clk = value
|
2007-04-12 19:16:47 +00:00
|
|
|
self.InputClk = value
|
|
|
|
self.PrevTime = CurTime()
|
2007-11-10 23:10:57 +00:00
|
|
|
|
|
|
|
if (self.Clk >= 1.0) then
|
|
|
|
self.Entity:NextThink(CurTime()+0.025)
|
|
|
|
end
|
2007-03-21 21:09:01 +00:00
|
|
|
elseif (iname == "Frequency") then
|
2007-05-18 20:08:04 +00:00
|
|
|
if (!SinglePlayer() && (value > 20000)) then
|
|
|
|
self.ThinkTime = 200
|
|
|
|
return
|
|
|
|
end
|
2007-03-21 21:09:01 +00:00
|
|
|
if (value ~= 0) then
|
|
|
|
self.ThinkTime = value/100
|
|
|
|
end
|
|
|
|
elseif (iname == "Reset") then
|
|
|
|
if (value >= 1.0) then
|
2007-04-12 19:16:47 +00:00
|
|
|
self:Reset()
|
2007-03-21 21:09:01 +00:00
|
|
|
Wire_TriggerOutput(self.Entity, "Error", 0.0)
|
|
|
|
end
|
2007-04-12 19:16:47 +00:00
|
|
|
elseif (iname == "MemBus") then
|
|
|
|
self.MemBus = self.Inputs.MemBus.Src /////////////
|
|
|
|
elseif (iname == "IOBus") then
|
|
|
|
self.IOBus = self.Inputs.IOBus.Src /////////////
|
2007-05-16 19:53:47 +00:00
|
|
|
elseif (iname == "NMI") then
|
|
|
|
if (value >= 32) then
|
|
|
|
if ((self.Clk >= 1.0) && (self.IF) &&
|
|
|
|
self:Push(self.ES) &&
|
|
|
|
self:Push(self.GS) &&
|
|
|
|
self:Push(self.FS) &&
|
|
|
|
self:Push(self.DS) &&
|
|
|
|
self:Push(self.SS) &&
|
|
|
|
self:Push(self.CS) &&
|
|
|
|
|
|
|
|
self:Push(self.EDI) &&
|
|
|
|
self:Push(self.ESI) &&
|
|
|
|
self:Push(self.ESP) &&
|
|
|
|
self:Push(self.EBP) &&
|
|
|
|
self:Push(self.EDX) &&
|
|
|
|
self:Push(self.ECX) &&
|
|
|
|
self:Push(self.EBX) &&
|
|
|
|
self:Push(self.EAX) &&
|
|
|
|
|
|
|
|
self:Push(self.CMPR) &&
|
|
|
|
self:Push(self.IP)) then
|
|
|
|
Interrupt(math.floor(value));
|
|
|
|
end
|
|
|
|
end
|
2007-03-21 21:09:01 +00:00
|
|
|
end
|
|
|
|
end
|