function ENT:InitASMOpcodes() self.OpcodeCount = {} for i=1,199 do if ((i >= 1) && (i <= 9)) || (i == 69) then self.OpcodeCount[i] = 1 elseif (i >= 10) && (i <= 19) then self.OpcodeCount[i] = 2 elseif (i >= 20) && (i <= 29) then self.OpcodeCount[i] = 1 elseif (i >= 30) && (i <= 39) then self.OpcodeCount[i] = 1 elseif (i >= 40) && (i <= 49) then self.OpcodeCount[i] = 0 elseif (i >= 50) && (i <= 59) then self.OpcodeCount[i] = 2 elseif (i >= 60) && (i <= 68) then self.OpcodeCount[i] = 2 elseif (i >= 70) && (i <= 79) then self.OpcodeCount[i] = 1 elseif (i >= 80) && (i <= 89) then self.OpcodeCount[i] = 2 elseif (i >= 90) && (i <= 99) then self.OpcodeCount[i] = 1 elseif (i >= 100) && (i <= 109) then self.OpcodeCount[i] = 1 elseif (i >= 110) && (i <= 119) then self.OpcodeCount[i] = 0 end end end function ENT:Core_Version() local SVNString = "$Revision: 532 $" return tonumber(string.sub(SVNString,12,14)) end function ENT:DecodeOpcode( opcode ) //------------------------------------------------------------ if (opcode == "jne") || (opcode == "jnz") then //JNE X : IP = X, IF CMPR ~= 0 return 1 elseif (opcode == "jmp") then //JMP X : IP = X return 2 elseif (opcode == "jg") || (opcode == "jnle") then //JG X : IP = X, IF CMPR > 0 return 3 elseif (opcode == "jge") || (opcode == "jnl") then //JGE X : IP = X, IF CMPR >= 0 return 4 elseif (opcode == "jl") || (opcode == "jnge") then //JL X : IP = X, IF CMPR < 0 return 5 elseif (opcode == "jle") || (opcode == "jng") then //JLE X : IP = X, IF CMPR <= 0 return 6 elseif (opcode == "je") || (opcode == "jz") then //JE X : IP = X, IF CMPR = 0 return 7 elseif (opcode == "cpuid") then //CPUID X : EAX -> CPUID[X] return 8 elseif (opcode == "push") then //PUSH X : X -> STACK return 9 //------------------------------------------------------------ elseif (opcode == "add") then //ADD X,Y : X = X + Y return 10 elseif (opcode == "sub") then //SUB X,Y : X = X - Y return 11 elseif (opcode == "mul") then //MUL X,Y : X = X * Y return 12 elseif (opcode == "div") then //DIV X,Y : X = X / Y return 13 elseif (opcode == "mov") then //MOV X,Y : X = Y return 14 elseif (opcode == "cmp") then //CMP X,Y : CMPR = X - Y return 15 elseif (opcode == "rd") then //RD X,Y : X = MEMORY[Y] return 16 elseif (opcode == "wd") then //WD X,Y : MEMORY[X] = Y return 17 elseif (opcode == "min") then //MIN X,Y : MIN(X,Y) return 18 elseif (opcode == "max") then //MAX X,Y : MAX(X,Y) return 19 //------------------------------------------------------------ elseif (opcode == "inc") then //INC X : X = X + 1 return 20 elseif (opcode == "dec") then //DEC X : X = X - 1 return 21 elseif (opcode == "neg") then //NEG X : X = -X return 22 elseif (opcode == "rand") then //RAND X : X = Random(0..1) return 23 elseif (opcode == "loop") then //LOOP X : IF ECX ~= 0 THEN JUMP X //2.00 return 24 elseif (opcode == "loopa") then //LOOP X : IF EAX ~= 0 THEN JUMP X //2.00 return 25 elseif (opcode == "loopb") then //LOOP X : IF EBX ~= 0 THEN JUMP X //2.00 return 26 elseif (opcode == "loopd") then //LOOP X : IF EDX ~= 0 THEN JUMP X //2.00 return 27 elseif (opcode == "spg") then //SRD X : PAGE(X) = READ ONLY //2.00 return 28 elseif (opcode == "cpg") then //CRD X : PAGE(X) = READ AND WRITE //2.00 return 29 //------------------------------------------------------------ elseif (opcode == "pop") then //POP X : X <- STACK return 30 elseif (opcode == "call") then //CALL X : IP -> STACK; IP = X return 31 elseif (opcode == "not") then //NOT X : X = not X return 32 elseif (opcode == "fint") then //FINT X : X = FLOOR(X) return 33 elseif (opcode == "frnd") then //FRND X : X = ROUND(X) return 34 elseif (opcode == "ffrac") then //FFRAC X : X = X - FLOOR(X) return 35 elseif (opcode == "finv") then //FINV X : X = 1 / X return 36 elseif (opcode == "halt") then //HALT X : HALT UNTIL PORT[X] return 37 elseif (opcode == "fshl") then //FSHL X : X = X * 2 //2.00 return 38 elseif (opcode == "fshr") then //FSHR X : X = X / 2 //2.00 return 39 //------------------------------------------------------------ elseif (opcode == "ret") then //RET : IP <- STACK return 40 elseif (opcode == "iret") then //IRET : IP <- STACK //2.00 return 41 elseif (opcode == "sti") then //STI : IF = TRUE //2.00 return 42 elseif (opcode == "cli") then //CLI : IF = FALSE //2.00 return 43 elseif (opcode == "stp") then //STP : PF = TRUE //2.00 return 44 elseif (opcode == "clp") then //CLP : PF = FALSE //2.00 return 45 // elseif (opcode == "") then //RESERVED //2.00 // return 46 elseif (opcode == "RETF") then //RETF : IP,CS <- STACK //2.00 return 47 // elseif (opcode == "") then //RESERVED //2.00 // return 48 // elseif (opcode == "") then //RESERVED //2.00 // return 49 //------------------------------------------------------------ elseif (opcode == "and") then //FAND X,Y : X = X AND Y return 50 elseif (opcode == "or") then //FOR X,Y : X = X OR Y return 51 elseif (opcode == "xor") then //FXOR X,Y : X = X XOR Y return 52 elseif (opcode == "fsin") then //FSIN X,Y : X = SIN Y return 53 elseif (opcode == "fcos") then //FCOS X,Y : X = COS Y return 54 elseif (opcode == "ftan") then //FTAN X,Y : X = TAN Y return 55 elseif (opcode == "fasin") then //FASIN X,Y : X = ASIN Y return 56 elseif (opcode == "facos") then //FACOS X,Y : X = ACOS Y return 57 elseif (opcode == "fatan") then //FATAN X,Y : X = ATAN Y return 58 elseif (opcode == "mod") then //MOD X,Y : X = X MOD Y //2.00 return 59 //------------------------------------------------------------ elseif (opcode == "bit") then //BIT X,Y : CMPR = BIT(X,Y) //2.00 return 60 elseif (opcode == "sbit") then //SBIT X,Y : BIT(X,Y) = 1 //2.00 return 61 elseif (opcode == "cbit") then //CBIT X,Y : BIT(X,Y) = 0 //2.00 return 62 elseif (opcode == "tbit") then //TBIT X,Y : BIT(X,Y) = ~BIT(X,Y)//2.00 return 63 elseif (opcode == "band") then //AND X,Y : X = X AND Y //2.00 return 64 elseif (opcode == "bor") then //OR X,Y : X = X OR Y //2.00 return 65 elseif (opcode == "bxor") then //XOR X,Y : X = X XOR Y //2.00 return 66 elseif (opcode == "bshl") then //SHL X,Y : X = X SHL Y //2.00 return 67 elseif (opcode == "bshr") then //SHR X,Y : X = X SHR Y //2.00 return 68 elseif (opcode == "jmpf") then //JMPF X,Y : CS = Y; IP = X //2.00 return 69 //------------------------------------------------------------ elseif (opcode == "cne") || (opcode == "cnz") then //CNE X : CALL(X), IF CMPR ~= 0 //2.00 return 71 elseif (opcode == "cg") || (opcode == "cnle") then //CG X : CALL(X), IF CMPR > 0 //2.00 return 73 elseif (opcode == "cge") || (opcode == "cnl") then //CGE X : CALL(X), IF CMPR >= 0 //2.00 return 74 elseif (opcode == "cl") || (opcode == "cnge") then //CL X : CALL(X), IF CMPR < 0 //2.00 return 75 elseif (opcode == "cle") || (opcode == "cng") then //CLE X : CALL(X), IF CMPR <= 0 //2.00 return 76 elseif (opcode == "ce") || (opcode == "cz") then //CE X : CALL(X), IF CMPR = 0 //2.00 return 77 elseif (opcode == "mcopy") then //MCOPY X : X BYTES(ESI) -> EDI //2.00 return 78 elseif (opcode == "mxchg") then //MXCHG X : X BYTES(ESI) <> EDI //2.00 return 79 //------------------------------------------------------------ elseif (opcode == "fpwr") then //FPWR X,Y : X = X ^ Y //2.00 return 80 elseif (opcode == "xchg") then //XCHG X,Y : X,Y = Y,X //2.00 return 81 elseif (opcode == "flog") then //FLOG X,Y : X = LOG(Y) //2.00 return 82 elseif (opcode == "flog10") then//FLOG10 X,Y : X = LOG10(Y) //2.00 return 83 elseif (opcode == "in") then //IN X,Y : X = PORT[Y] //2.00 return 84 elseif (opcode == "out") then //OUT X,Y : PORT[X] = Y //2.00 return 85 elseif (opcode == "fabs") then //FABS X,Y : X = ABS(Y) //2.00 return 86 elseif (opcode == "fsgn") then //FSGN X,Y : X = SIGN(Y) //2.00 return 87 elseif (opcode == "fexp") then //FEXP X,Y : X = EXP(Y) //2.00 return 88 elseif (opcode == "callf") then //CALLF X,Y : CS = Y; CALL(X) //2.00 return 89 //------------------------------------------------------------ elseif (opcode == "fpi") then //FPI X : X = PI //2.00 return 90 elseif (opcode == "fe") then //FE X : X = E //2.00 return 91 elseif (opcode == "int") then //INT X : INTERRUPT(X) //2.00 return 92 elseif (opcode == "tpg") then //TPG X : CMPR = TEST(PAGE(X))* //2.00 return 93 elseif (opcode == "fceil") then //FCEIL X : X = CEIL(X) //2.00 return 94 elseif (opcode == "erpg") then //ERPG X : ERASE ROM PAGE(X) //2.00 return 95 elseif (opcode == "wrpg") then //WRPG X : WRITE ROM PAGE(X) //2.00 return 96 elseif (opcode == "rdpg") then //RDPG X : READ ROM PAGE(X) //2.00 return 97 elseif (opcode == "timer") then //TIMER X : X = TIMER //2.00 return 98 elseif (opcode == "lidtr") then //LIDTR X : IDTR = X //2.00 return 99 //------------------------------------------------------------ elseif (opcode == "jner") || (opcode == "jnzr") then //JNE X : IP = IP+X, IF CMPR ~= 0 //2.00 return 101 elseif (opcode == "jmpr") then //JMP X : IP = IP+X //2.00 return 102 elseif (opcode == "jgr") || (opcode == "jnler") then //JG X : IP = IP+X, IF CMPR > 0 //2.00 return 103 elseif (opcode == "jger") || (opcode == "jnlr") then //JGE X : IP = IP+X, IF CMPR >= 0 //2.00 return 104 elseif (opcode == "jlr") || (opcode == "jnger") then //JL X : IP = IP+X, IF CMPR < 0 //2.00 return 105 elseif (opcode == "jler") || (opcode == "jngr") then //JLE X : IP = IP+X, IF CMPR <= 0 //2.00 return 106 elseif (opcode == "jer") || (opcode == "jzr") then //JE X : IP = IP+X, IF CMPR = 0 //2.00 return 107 elseif (opcode == "lneg") then //LNEG X : X = LOGNEGATE(X) //3.00 return 108 //------------------------------------------------------------ elseif (opcode == "nmiret") then //NMIRET X : NMIRESTORE; //2.00 return 110 end return -1 end function ENT:OpcodeParamCount( opcode ) if (self.OpcodeCount[opcode]) then return self.OpcodeCount[opcode] else return 0 end end function ENT:Digit( prefix ) return (prefix == "0") || (prefix == "1") || (prefix == "2") || (prefix == "3") || (prefix == "4") || (prefix == "5") || (prefix == "6") || (prefix == "7") || (prefix == "8") || (prefix == "9") || (prefix == ".") || (prefix == "-") || (prefix == "+") end function ENT:ValidNumber( line ) if (line) then return self:Digit(string.sub(line,1,1)) else return false end end function ENT:Explode(seperator ,str) local tble={} ll=0 local prevll = 1 str = string.Trim(str) while true do l = string.find(str,seperator,ll+1,true) if l~=nil then local leftstr = string.Left(str,l) local rightstr = string.Right(str,string.len(str)-l) local cleft = 0 local cright = 0 for i = 1, string.len(leftstr) do if (string.sub(leftstr,i,i) == "'") then cleft = cleft + 1 end end for i = 1, string.len(rightstr) do if (string.sub(rightstr,i,i) == "'") then cright = cright + 1 end end if (cleft % 2 == 0) && (cright % 2 == 0) then table.insert(tble, string.sub(str,ll,l-1)) prevll = ll+l+1 end ll=l+1 else table.insert(tble, string.sub(str,math.min(prevll,ll))) break end end return tble end function ENT:Lowercase(str) local j = 1 local rstr = "" while (j <= string.len(str)) do local leftstr = string.Left(str,j) local rightstr = string.Right(str,string.len(str)-j) local cleft = 0 local cright = 0 for i = 1, string.len(leftstr) do if (string.sub(leftstr,i,i) == "'") then cleft = cleft + 1 end end for i = 1, string.len(rightstr) do if (string.sub(rightstr,i,i) == "'") then cright = cright + 1 end end if (cleft % 2 == 0) && (cright % 2 == 0) then rstr = rstr..string.lower(string.sub(leftstr,j,j)) else rstr = rstr..string.sub(leftstr,j,j) end j = j + 1 end return rstr end function ENT:RemoveFuckingSpaces(str) end function ENT:Error( pl, error ) pl:PrintMessage(HUD_PRINTCONSOLE,"-> "..error) pl:ConCommand("wire_cpu_editor_addlog \""..error.."\"") end function ENT:Compile_ASM( pl, line, linenumber, firstpass ) local opcodetable = self:Explode(" ", line or { } ) local dopcode = 0 local nextparams = false local nextvariable = false local nextorg = false local nextdefine = false local nextalloc = false local nextdb = false local programsize = 0 if (self.MakeDump) && (string.Trim(line) ~= "") && (not firstpass) then self.Dump = self.Dump.."["..linenumber.."]"..self.WIP.." = "..line.."\n" end for _,opcode in pairs(opcodetable) do opcode = string.Trim(opcode) if (nextdefine) then local deftable = self:Explode(",", opcode ) if (table.Count(deftable) == 2) then if (not self.Labels[deftable[1]]) then if (self:ValidNumber(deftable[2])) then self.Labels[deftable[1]] = deftable[2] //-self:Error(pl,"ZyeliosASM: Added define "..deftable[1].."["..deftable[2].."]\n") else self:Error(pl,"ZyeliosASM: Error (E270) at line "..linenumber..": Attempt to define a non-number\n") return false end else if (firstpass) then self:Error(pl,"ZyeliosASM: Error (E236) at line "..linenumber..": Define "..deftable[1].." already exists\n") return false end end else self:Error(pl,"ZyeliosASM: Error (E335) at line "..linenumber..": Invalid number of parameters in DEFINE macro\n") return false end elseif (nextdb) then // Msg("db explode:"..opcode..";\n") local dbtable = self:Explode(",", opcode ) // PrintTable(dbtable) // Msg("db start\n") // for _,dbvalue in pairs(dbtable) do for i=0,table.Count(dbtable) do local dbvalue = dbtable[i] if (dbvalue) && (dbvalue ~= "") then dbvalue = string.Trim(dbvalue) // Msg("dbvalue:"..dbvalue..";\n") if self:ValidNumber(dbvalue) then self:Write(dbvalue) else if (string.sub(dbvalue,1,1) == "'") && (string.sub(dbvalue,-1,-1) == "'") then local string = string.sub(dbvalue,2,-2) for i = 1, string.len(string) do self:Write(string.byte(string,i)) end else if (self.Labels[dbvalue]) then self:Write(self.Labels[dbvalue]) elseif (self.Labels[dbvalue..":"]) then self:Write(self.Labels[dbvalue..":"]) else if (not firstpass) then self:Error(pl,"ZyeliosASM: Error (E450) at line "..linenumber..": Invalid parameter in DB macro\n") return false end //self:Write(0) end end end end end elseif (nextorg) then if self:ValidNumber(opcode) then self.WIP = tonumber(opcode) else self:Error(pl,"ZyeliosASM: Error (E333) at line "..linenumber..": Invalid parameter in ORG macro\n") return false end elseif (nextalloc) then local alloctable = string.Explode(",", opcode ) if (table.Count(alloctable) == 0) then //-self:Error(pl,"ZyeliosASM: Allocated new variable ".."0".." ["..self.WIP.."]\n") self:Write( 0 ) end if (table.Count(alloctable) == 1) then alloctable[1] = string.Trim(alloctable[1]) local prefix = string.sub(alloctable[1],1,1) if self:ValidNumber(alloctable[1]) then //-self:Error(pl,"ZyeliosASM: Allocated variable ".."["..alloctable[1].."] ["..self.WIP.."]\n") for i = 0,alloctable[1]-1 do self:Write( 0 ) end else if (not self.Labels[alloctable[1]]) then self.Labels[alloctable[1]] = self.WIP //-self:Error(pl,"ZyeliosASM: Allocated new variable "..alloctable[1].." ["..self.WIP.."]\n") self:Write( 0 ) else if (firstpass) then self:Error(pl,"ZyeliosASM: Error (E231) at line "..linenumber..": Variable "..opcode.." already exists\n") return false else self:Write( 0 ) end end end end if (table.Count(alloctable) == 2) then alloctable[1] = string.Trim(alloctable[1]) alloctable[2] = string.Trim(alloctable[2]) if (not self.Labels[alloctable[1]]) then self.Labels[alloctable[1]] = self.WIP //-self:Error(pl,"ZyeliosASM: Allocated new variable "..alloctable[1].."["..alloctable[2].."] ["..self.WIP.."]\n") self:Write( alloctable[2] ) else if (firstpass) then self:Error(pl,"ZyeliosASM: Error (E231) at line "..linenumber..": Variable "..opcode.." already exists\n") return false else self:Write( alloctable[2] ) end end end if (table.Count(alloctable) == 3) then alloctable[1] = string.Trim(alloctable[1]) alloctable[2] = string.Trim(alloctable[2]) alloctable[3] = string.Trim(alloctable[3]) if (not self.Labels[alloctable[1]]) then self.Labels[alloctable[1]] = self.WIP //-self:Error(pl,"ZyeliosASM: Allocated new array "..alloctable[1].."["..alloctable[2].."] ["..self.WIP.."]\n") for i = 1, alloctable[2] do self:Write( alloctable[3] ) end else if (firstpass) then self:Error(pl,"ZyeliosASM: Error (E231) at line "..linenumber..": Variable "..opcode.." already exists\n") return false else for i = 1, alloctable[2] do self:Write( alloctable[3] ) end end end end nextalloc = false elseif (nextparams) then local paramtable = string.Explode(",", opcode or {"none","none"} ) local drm1 = 0 local drm2 = 0 local disp1,disp2 = 0 local segment1 = -1 local segment2 = -1 if (table.Count(paramtable) ~= self:OpcodeParamCount( dopcode )) then self:Error(pl,"ZyeliosASM: Error (E245) at line "..linenumber..": wrong number of parameters for opcode\n") self:Error(pl,"Code: ["..linenumber.."]"..self.WIP.." = "..line.."\n") return false end paramtable[1] = string.Trim(paramtable[1]) if (self:ValidNumber(paramtable[1])) then drm1 = 0 elseif (paramtable[1] == "eax") then drm1 = 1 elseif (paramtable[1] == "ebx") then drm1 = 2 elseif (paramtable[1] == "ecx") then drm1 = 3 elseif (paramtable[1] == "edx") then drm1 = 4 elseif (paramtable[1] == "esi") then drm1 = 5 elseif (paramtable[1] == "edi") then drm1 = 6 elseif (paramtable[1] == "esp") then drm1 = 7 elseif (paramtable[1] == "ebp") then drm1 = 8 elseif (paramtable[1] == "cs") then drm1 = 9 elseif (paramtable[1] == "ss") then drm1 = 10 elseif (paramtable[1] == "ds") then drm1 = 11 elseif (paramtable[1] == "es") then drm1 = 12 elseif (paramtable[1] == "gs") then drm1 = 13 elseif (paramtable[1] == "fs") then drm1 = 14 elseif (string.sub(paramtable[1],1,4) == "port") then drm1 = 1000+string.sub(paramtable[1],5) else local prefix = string.find(paramtable[1],"#") local postprefix = paramtable[1] if (prefix) then postprefix = string.sub(paramtable[1],2) end local segmentprefix2 = string.find(paramtable[1],":") if (segmentprefix2) then local segmentprefix = string.sub(paramtable[1],1,segmentprefix2-1) if (not self:ValidNumber(segmentprefix)) then if (segmentprefix == "cs") then segment1 = -2 elseif (segmentprefix == "ss") then segment1 = -3 elseif (segmentprefix == "ds") then segment1 = -4 elseif (segmentprefix == "es") then segment1 = -5 elseif (segmentprefix == "gs") then segment1 = -6 elseif (segmentprefix == "fs") then segment1 = -7 end else segment1 = segmentprefix end prefix = string.find(paramtable[1],"#",segmentprefix2) if (prefix) then postprefix = string.sub(paramtable[1],prefix+1) else postprefix = string.sub(paramtable[1],segmentprefix2+1) end end if (prefix == nil) && (not self:ValidNumber(paramtable[1])) then if (self.Labels[postprefix..":"]) then paramtable[1] = self.Labels[postprefix..":"] elseif (self.Labels[postprefix]) then paramtable[1] = self.Labels[postprefix] else if (not firstpass) then self:Error(pl,"ZyeliosASM: Error (E235) at line "..linenumber..": No such label: "..postprefix.."!\n") return false end end end if (prefix ~= nil) then if (postprefix == "eax") then drm1 = 17 elseif (postprefix == "ebx") then drm1 = 18 elseif (postprefix == "ecx") then drm1 = 19 elseif (postprefix == "edx") then drm1 = 20 elseif (postprefix == "esi") then drm1 = 21 elseif (postprefix == "edi") then drm1 = 22 elseif (postprefix == "esp") then drm1 = 23 elseif (postprefix == "ebp") then drm1 = 24 elseif (self.Labels[postprefix..":"]) then drm1 = 25 disp1 = self.Labels[postprefix..":"] elseif (self.Labels[postprefix]) then drm1 = 25 disp1 = self.Labels[postprefix] else if (postprefix) then if (not self.ValidNumber(postprefix)) then if (not firstpass) then self:Error(pl,"ZyeliosASM: Error (E236) at line "..linenumber..": No such variable: "..postprefix.."!\n") //I'm teh pirate yarr! return false end end drm1 = 25 disp1 = postprefix else self:Error(pl,"ZyeliosASM: Error (E490) at line "..linenumber..": Wrong memory reference syntax!\n") end end end end if (self:OpcodeParamCount( dopcode ) > 1) && (paramtable[2] ~= "none") then paramtable[2] = string.Trim(paramtable[2]) if (self:ValidNumber(paramtable[2])) then drm2 = 0 elseif (paramtable[2] == "eax") then drm2 = 1 elseif (paramtable[2] == "ebx") then drm2 = 2 elseif (paramtable[2] == "ecx") then drm2 = 3 elseif (paramtable[2] == "edx") then drm2 = 4 elseif (paramtable[2] == "esi") then drm2 = 5 elseif (paramtable[2] == "edi") then drm2 = 6 elseif (paramtable[2] == "esp") then drm2 = 7 elseif (paramtable[2] == "ebp") then drm2 = 8 elseif (paramtable[2] == "cs") then drm2 = 9 elseif (paramtable[2] == "ss") then drm2 = 10 elseif (paramtable[2] == "ds") then drm2 = 11 elseif (paramtable[2] == "es") then drm2 = 12 elseif (paramtable[2] == "gs") then drm2 = 13 elseif (paramtable[2] == "fs") then drm2 = 14 elseif (string.sub(paramtable[2],1,4) == "port") then drm2 = 1000+string.sub(paramtable[2],5) else local prefix = string.find(paramtable[2],"#") local postprefix = paramtable[2] if (prefix) then postprefix = string.sub(paramtable[2],2) end local segmentprefix2 = string.find(paramtable[2],":") if (segmentprefix2) then local segmentprefix = string.sub(paramtable[2],1,segmentprefix2-1) if (not self:ValidNumber(segmentprefix)) then if (segmentprefix == "cs") then segment2 = -2 elseif (segmentprefix == "ss") then segment2 = -3 elseif (segmentprefix == "ds") then segment2 = -4 elseif (segmentprefix == "es") then segment2 = -5 elseif (segmentprefix == "gs") then segment2 = -6 elseif (segmentprefix == "fs") then segment2 = -7 end else segment2 = segmentprefix end prefix = string.find(paramtable[2],"#",segmentprefix2) if (prefix) then postprefix = string.sub(paramtable[2],prefix+1) else postprefix = string.sub(paramtable[2],segmentprefix2+1) end end if (prefix == nil) && (not self:ValidNumber(paramtable[2])) then if (self.Labels[postprefix..":"]) then paramtable[2] = self.Labels[postprefix..":"] elseif (self.Labels[postprefix]) then paramtable[2] = self.Labels[postprefix] else if (not firstpass) then self:Error(pl,"ZyeliosASM: Error (E232) at line "..linenumber..": No such label: "..postprefix.."!\n") return false end end end if (prefix ~= nil) then if (postprefix == "eax") then drm2 = 17 elseif (postprefix == "ebx") then drm2 = 18 elseif (postprefix == "ecx") then drm2 = 19 elseif (postprefix == "edx") then drm2 = 20 elseif (postprefix == "esi") then drm2 = 21 elseif (postprefix == "edi") then drm2 = 22 elseif (postprefix == "esp") then drm2 = 23 elseif (postprefix == "ebp") then drm2 = 24 elseif (self.Labels[postprefix..":"]) then drm2 = 25 disp2 = self.Labels[postprefix..":"] elseif (self.Labels[postprefix]) then drm2 = 25 disp2 = self.Labels[postprefix] else if (postprefix) then if (not self.ValidNumber(postprefix)) then if (not firstpass) then self:Error(pl,"ZyeliosASM: Error (E231) at line "..linenumber..": No such variable: "..postprefix.."!\n") return false end end drm2 = 25 disp2 = postprefix else self:Error(pl,"ZyeliosASM: Error (E490) at line "..linenumber..": Wrong memory reference syntax!\n") end end end end end local rm = drm1 + drm2*10000 local sopcode = dopcode if (segment1 ~= -1) then dopcode = dopcode + 1000 end if (segment2 ~= -1) then dopcode = dopcode + 10000 end self:Write( dopcode ) self:Write( rm ) programsize = programsize + 2 if (segment1 ~= -1) then self:Write( segment1 ) end if (segment2 ~= -1) then self:Write( segment2 ) end if (drm1 == 0) then self:Write( paramtable[1] ) programsize = programsize + 1 end if (drm1 == 25) then self:Write( disp1 ) end if (self:OpcodeParamCount( sopcode ) > 1) && (drm2 == 0) then self:Write( paramtable[2] ) programsize = programsize + 1 end if (drm2 == 25) then self:Write( disp2 ) end nextparams = false else if ( opcode == "alloc" ) then nextalloc = true elseif (opcode == "db") then nextdb = true elseif ( opcode == "org" ) then nextorg = true elseif ( opcode == "define" ) then nextdefine = true elseif ( opcode == "code" ) then if (self.Labels["codestart"]) then if (firstpass) then self:Error(pl,"ZyeliosASM: Error (E600) at line "..linenumber..": CODESTART label exists - cant use CODE macro\n") return false end end self.Labels["codestart"] = self.WIP elseif ( opcode == "data" ) then if (self.Labels["datastart"]) then if (firstpass) then self:Error(pl,"ZyeliosASM: Error (E601) at line "..linenumber..": DATASTART label exists - cant use DATA macro\n") return false end end self.Labels["datastart"] = self.WIP self:Write(2) self:Write(0) if (self.Labels["codestart"]) then self:Write(self.Labels["codestart"]) else self:Write(0) if (not firstpass) then self:Error(pl,"ZyeliosASM: Error (E602) at line "..linenumber..": No CODE macro, cant use DATA macro\n") return false end end else dopcode = self:DecodeOpcode( opcode ) if (dopcode ~= -1) then if (self:OpcodeParamCount( dopcode ) > 0) then nextparams = true else self:Write( dopcode ) self:Write( 0 ) programsize = programsize + 2 end else local lastsymbol = string.sub(opcode,-1,-1) local labelname = string.sub(opcode,1,string.len(opcode)-1) if (lastsymbol == ":") then if (not self.Labels[labelname]) then self.Labels[labelname] = self.WIP //self:Error(pl,"ZyeliosASM: Added label "..opcode.."["..self.WIP.."]\n") else if (firstpass) then self:Error(pl,"ZyeliosASM: Error (E200) at line "..linenumber..": Label "..opcode.." already exists\n") return false end end else if (opcode ~= "") && (opcode ~= " ") then self:Error(pl,"ZyeliosASM: Error (E500) at line "..linenumber..": unknown opcode: "..opcode.."\n") return false end end end end end end return true end function ENT:ParseProgram_ASM( pl, programtext, parsedline, firstpass ) if (self.FatalError) then return false end if (programtext == nil) then return end //local programtext2 = string.gsub(programtext,"/*(.-)*/") //Msg("!!: "..programtext2.."\n") //local programtext2 = string.Implode(" ",tablenolines) local comment = string.find(programtext,"//") local programtext2 = programtext if (comment) then programtext2 = string.sub(programtext,1,comment-1) end local linestable = string.Explode(";", programtext2 or { } ) local linenumber = 0 for _,line in pairs(linestable) do linenumber = linenumber + 1 if (not self:Compile_ASM( pl, self:Lowercase(line), parsedline, firstpass )) then self.FatalError = true self.Memory[0] = 0 //FIXME end end end