diff --git a/lua/wire/client/hlzasm/hc_compiler.lua b/lua/wire/client/hlzasm/hc_compiler.lua index b90c0e9..8499140 100644 --- a/lua/wire/client/hlzasm/hc_compiler.lua +++ b/lua/wire/client/hlzasm/hc_compiler.lua @@ -670,7 +670,7 @@ function HCOMP:SetSpecialLabels() self:SetLabel("__DATE_MINUTE__",tonumber(os.date("%M"))) self:SetLabel("__DATE_SECOND__",tonumber(os.date("%S"))) - if self.Settings.CurrentPlatform == "GPU" then + if string.match(self.Settings.CurrentPlatform, "GPU$") then self:SetLabel("regClk", 65535) self:SetLabel("regReset", 65534) self:SetLabel("regHWClear", 65533) diff --git a/lua/wire/client/hlzasm/hc_preprocess.lua b/lua/wire/client/hlzasm/hc_preprocess.lua index 77b226e..fb89615 100644 --- a/lua/wire/client/hlzasm/hc_preprocess.lua +++ b/lua/wire/client/hlzasm/hc_preprocess.lua @@ -9,12 +9,12 @@ -------------------------------------------------------------------------------- -- Load file function HCOMP:LoadFile(filename) - return file.Read("data/"..self.Settings.CurrentPlatform.."Chip/"..filename, "GAME") -- So we also get /addons/wire/data/ + return file.Read("data/"..self.Location.."/"..filename, "GAME") -- So we also get /addons/wire/data/ end -- Save file function HCOMP:SaveFile(filename,text) - file.Write(self.Settings.CurrentPlatform.."Chip/"..filename,text) + file.Write(self.Location.."/"..filename,text) end -- Trim spaces at string sides diff --git a/lua/wire/client/text_editor/modes/zcpu.lua b/lua/wire/client/text_editor/modes/zcpu.lua index a9a8972..168e54f 100644 --- a/lua/wire/client/text_editor/modes/zcpu.lua +++ b/lua/wire/client/text_editor/modes/zcpu.lua @@ -3,7 +3,11 @@ local string_gmatch = string.gmatch local string_gsub = string.gsub local draw_WordBox = draw.WordBox -local EDITOR = {} +local EDITOR = { + UseValidator = true, + Validator = CPULib.Validate, + E2HelperCategory = "ZASM", -- As an override, makes GPU and SPU use the ZCPU helper too +} -- CPU hint box local oldpos, haschecked = {0,0}, false @@ -151,7 +155,11 @@ end function EDITOR:ShowContextHelp(word) E2Helper.Show() - E2Helper.UseCPU(self:GetParent().EditorType) + if E2Helper.Modes then + E2Helper:SetMode("ZASM") + else + E2Helper.UseCPU(self:GetParent().EditorType) + end E2Helper.Show(word) end @@ -362,3 +370,16 @@ function EDITOR:Paint() end WireTextEditor.Modes.ZCPU = EDITOR +WireTextEditor.Modes.ZGPU = EDITOR +local ZSPU = { + UseSoundBrowser = true +} + +-- Proxy everything else from the ZCPU editor. +local ZSPU_Meta = { + __index = function(self,key) return EDITOR[key] end +} + +setmetatable(ZSPU,ZSPU_Meta) + +WireTextEditor.Modes.ZSPU = ZSPU diff --git a/lua/wire/cpulib.lua b/lua/wire/cpulib.lua index 322fe50..91a8046 100644 --- a/lua/wire/cpulib.lua +++ b/lua/wire/cpulib.lua @@ -45,7 +45,7 @@ if CLIENT or TESTING then ------------------------------------------------------------------------------ -- Request compiling specific sourcecode - function CPULib.Compile(source,fileName,successCallback,errorCallback,targetPlatform) + function CPULib.Compile(source,fileName,successCallback,errorCallback,targetPlatform,sourceDirectory) -- Stop any compile/upload process that is running right now timer.Remove("cpulib_compile") timer.Remove("cpulib_upload") @@ -72,6 +72,7 @@ if CLIENT or TESTING then -- Start compiling the sourcecode HCOMP.Settings.CurrentPlatform = targetPlatform or "CPU" + HCOMP.Location = sourceDirectory or HCOMP.Settings.CurrentPlatform .. "chip" print("=== HL-ZASM High Level Assembly Compiler Output ==") -- Initialize callbacks @@ -88,10 +89,11 @@ if CLIENT or TESTING then function CPULib.SelectTab(editor,fileName,dontForceChange) if not editor then return end local editorType = string.lower(editor.EditorType) - local fullFileName = editorType.."chip\\"..fileName - - if string.sub(fileName,1,7) == editorType.."chip" then + local fullFileName + if string.match(fileName,"^"..editor.Location) then fullFileName = fileName + else + fullFileName = editor.Location.."/"..fileName end local currentTab = editor:GetActiveTabIndex() @@ -143,7 +145,7 @@ if CLIENT or TESTING then end editor.C.Val:Update({{message = issue, line = line, char = char}}, nil, issue, Color(128, 20, 50)) - end,editor.EditorType) + end,editor.EditorType,editor.Location) end ------------------------------------------------------------------------------ @@ -372,8 +374,12 @@ if CLIENT or TESTING then if ZCPU_Editor then -- Highlight current position local currentPosition = CPULib.Debugger.PositionByPointer[CPULib.Debugger.Variables[CPULib.Debugger.PreferredTracker or "IP"]] - if currentPosition then + -- Check if currentposition is even in the correct editor first, when switching editors CPULib's debugging info switches + -- to the file in the new editor. + if not currentPosition.File:sub(1,9):match("cpuchip/") then + return + end -- Clear all highlighted lines for tab=1,ZCPU_Editor:GetNumTabs() do ZCPU_Editor:GetEditor(tab):ClearHighlightedLines() @@ -823,6 +829,128 @@ end -- -- INT: 48-bit signed integer +if CLIENT then + timer.Simple(1,function() + if E2Helper.Modes then + -- If the version of wiremod is too old for E2Helper modules we should be fine since it's probably + -- the one with the hardcoded ZCPU support, we just miss out on seeing extension stuff. + E2Helper.Modes.ZASM = nil -- Erase existing mode + CPULib.E2HelperMode = E2Helper:RegisterMode("ZASM") + local helperModule = CPULib.E2HelperMode + + local helperDesc = helperModule.Descriptions + local helperInst = helperModule.Items + helperModule.ModeSetup = function(panel) + panel.FunctionColumn:SetName("Instruction") + panel.FunctionColumn:SetWidth(126) + panel.FromColumn:SetName("From") -- This can be the extension name now + panel.FromColumn:SetWidth(80) + panel.TakesColumn:SetName("Takes") + panel.TakesColumn:SetWidth(60) + panel.ReturnsColumn:SetName("Platform") + panel.ReturnsColumn:SetWidth(60) + panel.CostColumn:SetName("Opcode") + panel.CostColumn:SetWidth(40) + end + -- Divran's instruction generator from the original e2helper implementation. + local function AddCPUDesc(FuncName, Args, Desc, Platform, Type) + table.insert(helperInst, { [1] = FuncName, [2] = "ZASM", [3] = Args, [4] = Platform, [5] = Type }) + helperDesc[FuncName] = Desc + end + + -- Add help on all opcodes + for _, instruction in ipairs(CPULib.InstructionTable) do + if (instruction.Mnemonic ~= "RESERVED") and + (not instruction.Obsolete) then + local instructionArgs = instruction.Operand1 + if instruction.Operand2 ~= "" then + instructionArgs = instructionArgs .. ", " .. instruction.Operand2 + end + + AddCPUDesc(instruction.Mnemonic, + instructionArgs, + instruction.Reference, + instruction.Set, + instruction.Opcode) + end + end + -- Create and destroy hooks for extended instruction support. + local function helperCreateInstructionHook(indexes) + for _,k in ipairs(indexes) do + local instr = CPULib.InstructionTable[k] + local instructionArgs = instr.Operand1 + if instr.Operand2 ~= "" then + instructionArgs = instructionArgs .. ", " .. instr.Operand2 + end + table.insert(helperInst,{ + [1] = instr.Mnemonic, + [2] = instr.Extension, + [3] = instructionArgs, + [4] = instr.Set, + [5] = instr.Opcode + }) + helperDesc[instr.Mnemonic] = instr.Reference + end + end + local function helperDestroyInstructionHook(indexes) + for _,k in ipairs(indexes) do + helperDesc[helperInst[k][1]] = nil + helperInst[k] = nil + end + end + table.insert(CPULib.CreateInstructionHooks,helperCreateInstructionHook) + table.insert(CPULib.RemoveInstructionHooks,helperDestroyInstructionHook) + end + end) +end + +function CPULib.SetupEditor(editor,title,location,name) + -- Modes support removes the original handling for the debug buttons, which are added back here. + -- These were also moved a bit to make them not overlap the sound browser on the spu + if E2Helper.Modes then + -- Add "step forward" button + local DebugForward = editor:addComponent(vgui.Create("Button", editor), -366, 31, -286, 20) + DebugForward:SetText("Step Forward") + DebugForward.Font = "E2SmallFont" + DebugForward.DoClick = function() + local currentPosition = CPULib.Debugger.PositionByPointer[CPULib.Debugger.Variables.IP] + if currentPosition then + local linePointers = CPULib.Debugger.PointersByLine[currentPosition.Line .. ":" .. currentPosition.File] + if linePointers then -- Run till end of line + RunConsoleCommand("wire_cpulib_debugstep", linePointers[2]) + else -- Run just once + RunConsoleCommand("wire_cpulib_debugstep") + end + else -- Run just once + RunConsoleCommand("wire_cpulib_debugstep") + end + -- Reset interrupt text + CPULib.InterruptText = nil + end + editor.C.DebugForward = DebugForward + + -- Add "reset" button + local DebugReset = editor:addComponent(vgui.Create("Button", editor), -406, 31, -366, 20) + DebugReset:SetText("Reset") + DebugReset.DoClick = function() + RunConsoleCommand("wire_cpulib_debugreset") + -- Reset interrupt text + CPULib.InterruptText = nil + end + editor.C.DebugReset = DebugReset + + -- Add "run" button + local DebugRun = editor:addComponent(vgui.Create("Button", editor), -441, 31, -406, 20) + DebugRun:SetText("Run") + DebugRun.DoClick = function() RunConsoleCommand("wire_cpulib_debugrun") end + editor.C.DebugRun = DebugRun + editor:Setup(title,location,"Z"..name) + else + editor:Setup(title,location,name) + -- ZCPU will be fine without the new version, because the old version is hardcoded to support us. + end +end + CPULib.InstructionTable = {} local W1,R0,OB,UB,CB,TR,OL,BL = 1,2,4,8,16,32,64,128 @@ -847,6 +975,7 @@ local function Entry(Set,Opc,Mnemonic,Ops,Version,Flags,Op1,Op2,Reference) Old = Bit(Flags,OL), BlockPrefix = Bit(Flags,BL), }) + end local function CPU(...) Entry("CPU",...) end local function GPU(...) Entry("GPU",...) end @@ -918,7 +1047,8 @@ function CPULib:RegisterExtension(name, extension) OpFunc = opfunc, Flags = flags, Op1Name = "", - Op2Name = "" + Op2Name = "", + Description = docs.Description } if not docs then instruction.Description = "Instruction "..name.." created by extension "..self.Name @@ -999,7 +1129,10 @@ function CPULib:RebuildExtendedInstructions() for _,extension in ipairs(platform) do for _,i in ipairs(self.Extensions[platname][extension].Instructions) do Entry(platname,curOpcode,i.Name,i.Operands,i.Version,self:ParseFlagArray(i.Flags),i.Op1Name,i.Op2Name,i.Description) - table.insert(self.ExtendedInstructions,#CPULib.InstructionTable) + -- Store extension name on the instruction + local lastIndex = #CPULib.InstructionTable + CPULib.InstructionTable[lastIndex].Extension = extension + table.insert(self.ExtendedInstructions,lastIndex) curOpcode = curOpcode - 1 end end diff --git a/lua/wire/stools/cpu.lua b/lua/wire/stools/cpu.lua index ce79c96..204620d 100644 --- a/lua/wire/stools/cpu.lua +++ b/lua/wire/stools/cpu.lua @@ -112,7 +112,7 @@ if CLIENT then ------------------------------------------------------------------------------ function ZCPU_RequestCode() if ZCPU_Editor then - CPULib.Compile(ZCPU_Editor:GetCode(),ZCPU_Editor:GetChosenFile(),compile_success,compile_error) + CPULib.Compile(ZCPU_Editor:GetCode(),ZCPU_Editor:GetChosenFile(),compile_success,compile_error,"CPU",ZCPU_Editor.Location) end end net.Receive("ZCPU_RequestCode", ZCPU_RequestCode) @@ -123,7 +123,7 @@ if CLIENT then function ZCPU_OpenEditor() if not ZCPU_Editor then ZCPU_Editor = vgui.Create("Expression2EditorFrame") - ZCPU_Editor:Setup("ZCPU Editor", "cpuchip", "CPU") + CPULib.SetupEditor(ZCPU_Editor,"ZCPU Editor", "cpuchip", "CPU") end ZCPU_Editor:Open() end @@ -148,7 +148,7 @@ if CLIENT then function FileBrowser:OnFileOpen(filepath, newtab) if not ZCPU_Editor then ZCPU_Editor = vgui.Create("Expression2EditorFrame") - ZCPU_Editor:Setup("ZCPU Editor", "cpuchip", "CPU") + CPULib.SetupEditor(ZCPU_Editor,"ZCPU Editor", "cpuchip", "CPU") end ZCPU_Editor:Open(filepath, nil, newtab) end diff --git a/lua/wire/stools/gpu.lua b/lua/wire/stools/gpu.lua index c6942a3..f444992 100644 --- a/lua/wire/stools/gpu.lua +++ b/lua/wire/stools/gpu.lua @@ -91,7 +91,7 @@ if CLIENT then function ZGPU_RequestCode() if ZGPU_Editor then CPULib.Debugger.SourceTab = ZGPU_Editor:GetActiveTab() - CPULib.Compile(ZGPU_Editor:GetCode(),ZGPU_Editor:GetChosenFile(),compile_success,compile_error,"GPU") + CPULib.Compile(ZGPU_Editor:GetCode(),ZGPU_Editor:GetChosenFile(),compile_success,compile_error,"GPU",ZGPU_Editor.Location) end end net.Receive("ZGPU_RequestCode", ZGPU_RequestCode) @@ -102,7 +102,7 @@ if CLIENT then function ZGPU_OpenEditor() if not ZGPU_Editor then ZGPU_Editor = vgui.Create("Expression2EditorFrame") - ZGPU_Editor:Setup("ZGPU Editor", "gpuchip", "GPU") + CPULib.SetupEditor(ZGPU_Editor,"ZGPU Editor", "gpuchip", "GPU") end ZGPU_Editor:Open() end @@ -127,7 +127,7 @@ if CLIENT then function FileBrowser:OnFileOpen(filepath, newtab) if not ZGPU_Editor then ZGPU_Editor = vgui.Create("Expression2EditorFrame") - ZGPU_Editor:Setup("ZGPU Editor", "gpuchip", "GPU") + CPULib.SetupEditor(ZGPU_Editor,"ZGPU Editor", "gpuchip", "GPU") end ZGPU_Editor:Open(filepath, nil, newtab) end diff --git a/lua/wire/stools/spu.lua b/lua/wire/stools/spu.lua index 5c58c55..962e7b5 100644 --- a/lua/wire/stools/spu.lua +++ b/lua/wire/stools/spu.lua @@ -89,7 +89,7 @@ if CLIENT then function ZSPU_RequestCode() if ZSPU_Editor then CPULib.Debugger.SourceTab = ZSPU_Editor:GetActiveTab() - CPULib.Compile(ZSPU_Editor:GetCode(),ZSPU_Editor:GetChosenFile(),compile_success,compile_error) + CPULib.Compile(ZSPU_Editor:GetCode(),ZSPU_Editor:GetChosenFile(),compile_success,compile_error,"SPU",ZSPU_Editor.Location) end end net.Receive("ZSPU_RequestCode", ZSPU_RequestCode) @@ -100,7 +100,7 @@ if CLIENT then function ZSPU_OpenEditor() if not ZSPU_Editor then ZSPU_Editor = vgui.Create("Expression2EditorFrame") - ZSPU_Editor:Setup("ZSPU Editor", "spuchip", "SPU") + CPULib.SetupEditor(ZSPU_Editor,"ZSPU Editor", "spuchip", "SPU") end ZSPU_Editor:Open() end @@ -132,7 +132,7 @@ if CLIENT then function FileBrowser:OnFileOpen(filepath, newtab) if not ZSPU_Editor then ZSPU_Editor = vgui.Create("Expression2EditorFrame") - ZSPU_Editor:Setup("ZSPU Editor", "spuchip", "SPU") + CPULib.SetupEditor(ZSPU_Editor,"ZSPU Editor", "spuchip", "SPU") end ZSPU_Editor:Open(filepath, nil, newtab) end