ћЬЬЬЬ ЬЬ ЬЬ ЬЬЬЬ РР ЬРР Ь Р РЬЬЬЬРЬР Р Р Р РЬЬЬЬРЬРРРРР РРРРЬР РЬЬЬЬЬ ЬЬЬЬЬР Р Р Р 5ў ўџџ №њњњћћћћћћњ >J.ЬЬЬЬЬЬЬЬЬнЬнЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬнЬнЬнЬннЬнЬнЬЬнЬнЬннЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬнЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬнЬнЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬннннннннннннннннннн№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ""""""ђџ/""""""џџџџџџџџџџ/"ђџ/"ђџ/""""""џџџџџџџџ""""""ђџ/""""""џџџџџџџџџџ/"ђџ/"ђџ/""""""џџџџџџџџ""""""ђџ/""""""џџџџџџџџџџ/"ђџ/"ђџ/""""""џџџџџџџџ""""""ђџ!"џџџџџџџџџџ/"ђџ/"ђџ/""""""џџџџџџџџ""""""ђџџџ/"ђџџџџџџџџџџџџ/"ђџ/"ђџ/""""""џџџџџџџџ""""""ђџџџ/"ђџџџџџџџџџџџџ/"ђџ/"ђџ/""""""џџџџџџџџ""""""ђџџџ/"ђџџџџџџџџџџџџ/"ђџ/"ђџ/""""""џџџџџџџџ""!"ђџџџ/"ђџџџџџџџџџџџџ/"ђџ/"ђџ/"""џџџџџџџџ""џџ/"ђџџџ/"ђџџџџ""""""ђџ/"ђџ/"ђџ/"ђџџ""џџџџџџџџ""џџ/"ђџџџ/"ђџџџџ""""""ђџ/"ђџ/"ђџ/"ђџџ""џџџџџџџџ""џџ/"ђџџџ/"ђџџџџ""""""ђџ/"ђџ/"ђџ/"ђџџ""џџџџџџџџ""џџ/"ђџџџ/"ђџџџџёџ/"ђџ/"ђџ/"ђџџ""џџџџџџџџ""џџ/"ђџџџ/"ђџџџџџџџџџџџџ/"ђџ/"ђџ/"ђџџ""џџџџџџџџ""џџ/"ђџџџ/"ђџџџџџџџџџџџџ/"""""ђџ/"ђџџ""џџџџџџџџ""џџ/"ђџџџ/"ђџџџџџџџџџџџџ/"""""ђџ/"ђџџ""џџџџџџџџ""џџ/"ђџџџ/"ђџџџџџџџџџџџџ/"""""ђџ/"ђџџ""џџџџџџџџ""џџ/"ђџџџ/"ђџџџџџџџџџџџџ!"ёџ/"ђџџ""џџџџџџџџ""џџ/"ђџџџ/"ђџџџџџџџџџџџџџџ/"ђџџџ/"ђџџ""џџџџџџџџ""џџ/"ђџџџ/"ђџџџџџџџџџџџџџџ/"ђџџџ/"ђџџ""џџџџџџџџ""џџ/"ђџџџ/"ђџџџџџџџџџџџџџџ/"ђџџџ/"ђџџ""џџџџџџџџџџёџџџёџџџџџџџџџџџџџџёџџџёџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџярююююююююююююююююююююююююююююююююююююююююююююююЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬнЬнЬнЬнЬнЬЬЬнЬЬЬнЬЬнЬЬннЬЬнЬнЬнЬЬнЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬнЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬнЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬнЬнЬЬнЬнЬЬнЬЬЬЬЬнЬЬЬнЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬЬнннннннннннннннннннннннннннннннŸJ-- title: MT-VM -- author: Salvatore Barone -- desc: Micro-Tic Virtual Machine V_0.7.0 -- script: lua --[[ TO PROGRAM THE ROM, EDIT THE SPRITES ON THE SPRITES TAB. TO DECOMPILE THE ROM, SET THE VARIABLE VM.DECOMPILE TO true. TO DECOMPILE ON-THE-FLY, PRESS [A]+[B]+[UP], TO DISABLE THIS FEATURE, CHANGE THE VARIABLE VM.DECOMPILED TO true. INSTRUCTION SET: ENX NN NN NN = 00 = 00_00 - Ends the execution. NOP NN NN NN = 01 = 01_00 - No instruction. MOV SR DS NN = 02 = 02_00 - Sets the DS register to the value of SR. NEG RG NN NN = 03 = 03_00 - Negates the value of RG register. ADD VA VB DS = 04 = 04_00 - Adds the VA value with VB value and puts it on DS register. SUB VA VB DS = 05 = 05_00 - Substracts the VA value with VB value and puts it on DS register. MUL VA VB DS = 06 = 06_00 - Multiply the VA value with VB value and puts it on DS register. DIV VA VB DS = 07 = 07_00 - Divides the VA value with VB value and puts it on DS register. WRT RG VA NN = 08 = 08_00 - Writes the value VA on the address stored on register RG of persistent memory. RDM RG RG NN = 09 = 09_00 - Reads the value located on the address that is stored on the first RG register and stores it on the second RG register. FRM NN NN NN = 0A = 10_00 - Formats the entire Read-Write persistent memory. DCM NN NN NN = 0B = 11_00 - Decompiles the program. RDT UK UK UK = 0C = 12_00 - This instruction equals to NOP, but in the UK arguments you can put anything, if you have an instruction that needs more than 3 arguments, the next instruction will be this instruction with the arguments that the instruction needs in addition to the 3 arguments. PEX SC-SC-SC = 0D = 13_00 - Pause the execution for SC seconds. JMP LN-LN-LN = 11 = 01_01 - Jumps to the line number specified in LN argument. TST VA VB CN = 12 = 02_01 - Tests the VA and VB values with the CN condition and sets the check register to 1 if the condition its true. Condition values: 00 = 00_00 - = - Equal to. 01 = 01_00 - < - Minor than. 02 = 02_00 - > - Greater than. 03 = 03_00 - ! - Not equal to. JIZ LN-LN-LN = 13 = 03_01 - If check register its equal to zero, jumps to the LN line. JNZ LN-LN-LN = 14 = 04_01 - If check register its not equal to zero, jumps to the LN line. JGZ LN-LN-LN = 15 = 05_01 - If check register its greater than zero, jumps to the LN line. JLZ LN-LN-LN = 16 = 06_01 - If check register its lower than zero, jumps to the LN line. CLS CL NN NN = 20 = 00_02 - Clears the screen with the color provided. SPR ID XC YC = 21 = 01_02 - Prints the tile ID in the XC coordinate and YC coordinate. --------------------------- TO DO: RCT XC YC CL = 22 = 02_02 - Draws a rectangle in XC and YC coordinates and it extends to WD and HT and have the CL color. RDT WD HT NN RCF XC YC CL = 23 = 03_02 - Draws a rectangle without filling it in XC and YC coordinates and it extends to WD and HT and have the CL color. RDT WD HT NN ]]-- -- CORE VARIABLES: VM = { VERSION = {0,7,0}, START = true, DECOMPILE = false, DECOMPILED = false, P_COUNTER = 0, C_COUNTER = 0, ERROR_REG = false, CHECK_REG = 0, REGISTERS = { A = 0, B = 0, C = 0, D = 0, E = 0, F = 0 }, ROM_START = 0x06000, ROM_LENGT = 7680, RWM_LENGT = 512, SCREEN = { RESOLUTION = {128,128}, POSITION = {0,0}, BACKGROUND_C = 0, BORDER_COLOR = 12, TITLE_COLOR = 0, SPR_INDEX = 256, }, I_LENGTH = 4, I_TINSTR = 0, I_BLOCKL = 8, I_BLOCKS = 240, INSTRUCTIONS = { I0 = {"ENX", 0, false, false}, I1 = {"NOP", 0, false, false}, I2 = {"MOV", 2, false, true }, I3 = {"NEG", 1, false, true }, I4 = {"ADD", 3, false, true }, I5 = {"SUB", 3, false, true }, I6 = {"MUL", 3, false, true }, I7 = {"DIV", 3, false, true }, I8 = {"WRT", 2, false, true }, I9 = {"RDM", 2, false, true }, I10 = {"FRM", 0, false, false}, I11 = {"DCM", 0, false, false}, I12 = {"RDT", 3, false, false}, I13 = {"PEX", 3, true, false}, I17 = {"JMP", 3, true, false}, I18 = {"TST", 3, false, true }, I19 = {"JIZ", 3, true, false}, I20 = {"JNZ", 3, true, false}, I21 = {"JGZ", 3, true, false}, I22 = {"JLZ", 3, true, false}, I32 = {"CLS", 1, false, true }, I33 = {"SPR", 3, false, true } } } VM.I_TINSTR = VM.ROM_LENGT / VM.I_LENGTH -- HELPER FUNCTIONS: function printf(text, x, y, color) if color == nil then color = 15 end return print(text, x, y, color, true) end function sleep(secs) local tm = time() while true do if time() == (tm + (secs * 1000)) then break end end end function getTextLength(text) return printf(text, 0, -6, 0) end function borderColor(color) poke(0x3FF8, color) end function checkValue(value) if type(value) == "string" then if string.byte(value) < 65 or string.byte(value) > 71 then RSOD("Register \"" .. value .. "\" doesn't exists!", "Syntax") else return value end else return value end end function checkRegister(regnum) RES = 0 if regnum > 249 and regnum < (250 + 6) then RES = regnum - 250 RES = string.char(65 + RES) else RES = regnum end return RES end function mergeValues(V1, V2, V3) RES = tostring(V3) .. tostring(V2) .. tostring(V1) RES = tonumber(RES) return RES end function parseInstruction(instr) RES, ARGS, MERGED, ACCESSREG = "",0,false,false if VM.INSTRUCTIONS["I" .. tostring(instr)] == nil then RES = "UNK" ARGS = 0 MERGED = false ACCESSREG = false else RES, ARGS, MERGED, ACCESSREG = VM.INSTRUCTIONS["I" .. tostring(instr)][1], VM.INSTRUCTIONS["I" .. tostring(instr)][2], VM.INSTRUCTIONS["I" .. tostring(instr)][3], VM.INSTRUCTIONS["I" .. tostring(instr)][4] end return RES, ARGS, MERGED, ACCESSREG end function getBlock(line) RES = line / VM.I_BLOCKL RES = math.modf(RES) return RES end -- CORE FUNCTIONS: function RSOD(ERROR, LEVEL) cls(2) borderColor(2) printf("Micro-Tic Virtual Machine has crashed :(", 0, 0, 12) printf("----------------------------------------", 0, 8, 12) printf("CRASH REPORT:", 0, 16, 12) printf(" LEVEL: " .. LEVEL, 0, 24, 12) printf(" ERROR: " .. ERROR, 0, 32, 12) printf(" REGISTER DUMP: ", 0, 40, 12) for i=0, 5 do printf(" REGISTER " .. string.char(65 + i) .. " = " .. tostring(VM.REGISTERS[string.char(65 + i)]), 0, (48 + (8 * i)), 12) end printf(" PROGRAM COUNTER = " .. tostring(VM.P_COUNTER), 0, (48 + (8 * 6)), 12) printf(" CHECK REGISTER = " .. tostring(VM.CHECK_REG), 0, (48 + (8 * 7)), 12) VM.ERROR_REG = true end function decompile() trace("]===< DECOMPILATION >===[", 13) trace("") CIN = 0 CV = {CIN, CIN, CIN} for i = 1, VM.ROM_LENGT do CIN, CV[1], CV[2], CV[3] = readLine(i - 1) CIN, ARG, MERG, ACCREG = parseInstruction(CIN) LINE = "LINE[" .. tostring(i - 1) .. "][" .. tostring(getBlock(i - 1)) .. "]: " .. CIN .. " " if ACCREG then for i = 1, ARG do CV[i] = checkRegister(CV[i]) end end if CIN == "TST" then if CV[3] == 0 then CV[3] = "=" elseif CV[3] == 1 then CV[3] = "<" elseif CV[3] == 2 then CV[3] = ">" elseif CV[3] == 3 then CV[3] = "!" end end if ARG > 0 then if MERG == false then for i = 1, ARG do LINE = LINE .. " " .. CV[i] end else LINE = LINE .. " " .. tostring(mergeValues(CV[1], CV[2], CV[3])) end end trace(LINE, 6) if CIN == VM.INSTRUCTIONS.I0[1] then break end end trace("") trace("]===< DECOMPILED >===[", 13) end -- INSTRUCTION FUNCTIONS: function ENX() sync(2, 0, true) trace("TO SAVE THE GAME, TYPE SAVE", 13) exit() end function NOP() end function JMP(LINE) VM.P_COUNTER = LINE - 1 end function MOV(SRC, DST) SOURCE = checkValue(SRC) DESTIN = checkValue(DST) if type(DESTIN) ~= "string" then RSOD("The MOV instruction needs a register.", "Syntax") else if type(SOURCE) == "string" then VM.REGISTERS[DESTIN] = VM.REGISTERS[SOURCE] else VM.REGISTERS[DESTIN] = SOURCE end end end function WRT(ADD, VAL) ADDRESS = checkValue(ADD) VALUE = checkValue(VAL) if type(ADDRESS) ~= "string" then RSOD("This instruction doesn't support numbers for the RG field.", "Syntax") else ADDRESS = VM.REGISTERS[ADDRESS] if ADDRESS < 0 or ADDRESS > VM.RWM_LENGT then RSOD("Read-Write Persistent memory access boundary error!", "Fatal") else if type(VALUE) == "string" then VALUE = VM.REGISTERS[VALUE] elseif VALUE < 0 > 255 then RSOD("Value boundary error!", "Fatal") end poke((VM.ROM_START + VM.ROM_LENGT) + ADDRESS, VALUE) end end end function RDM(ADD, REG) ADDRESS = checkValue(ADD) REGISTER = checkValue(REG) if type(ADDRESS) ~= "string" or type(REGISTER) ~= "string" then RSOD("This instruction doesn't support numbers for the RG fields.", "Syntax") else ADDRESS = VM.REGISTERS[ADDRESS] if ADDRESS < 0 or ADDRESS > VM.RWM_LENGT then RSOD("Read-Write Persistent memory access boundary error!", "Fatal") end VM.REGISTERS[REGISTER] = peek((VM.ROM_START + VM.ROM_LENGT) + ADDRESS) end end function FRM() for i = 0, VM.RWM_LENGT do poke((VM.ROM_START + VM.ROM_LENGT) + i, 0) end end function ADD(N1, N2, DST) NUM1 = 0 NUM2 = 0 CNM1 = checkValue(N1) CNM2 = checkValue(N2) CDST = checkValue(DST) if type(CDST) ~= "string" then RSOD("The ADD instruction needs a register.", "Syntax") else if type(CNM1) == "string" then NUM1 = VM.REGISTERS[CNM1] else NUM1 = CNM1 end if type(CNM2) == "string" then NUM2 = VM.REGISTERS[CNM2] else NUM2 = CNM2 end VM.REGISTERS[CDST] = NUM1 + NUM2 end end function SUB(N1, N2, DST) NUM1 = 0 NUM2 = 0 CNM1 = checkValue(N1) CNM2 = checkValue(N2) CDST = checkValue(DST) if type(CDST) ~= "string" then RSOD("The ADD instruction needs a register.", "Syntax") else if type(CNM1) == "string" then NUM1 = VM.REGISTERS[CNM1] else NUM1 = CNM1 end if type(CNM2) == "string" then NUM2 = VM.REGISTERS[CNM2] else NUM2 = CNM2 end VM.REGISTERS[CDST] = NUM1 - NUM2 end end function MUL(N1, N2, DST) NUM1 = 0 NUM2 = 0 CNM1 = checkValue(N1) CNM2 = checkValue(N2) CDST = checkValue(DST) if type(CDST) ~= "string" then RSOD("The ADD instruction needs a register.", "Syntax") else if type(CNM1) == "string" then NUM1 = VM.REGISTERS[CNM1] else NUM1 = CNM1 end if type(CNM2) == "string" then NUM2 = VM.REGISTERS[CNM2] else NUM2 = CNM2 end VM.REGISTERS[CDST] = NUM1 * NUM2 end end function DIV(N1, N2, DST) NUM1 = 0 NUM2 = 0 CNM1 = checkValue(N1) CNM2 = checkValue(N2) CDST = checkValue(DST) if type(CDST) ~= "string" then RSOD("The ADD instruction needs a register.", "Syntax") else if type(CNM1) == "string" then NUM1 = VM.REGISTERS[CNM1] else NUM1 = CNM1 end if type(CNM2) == "string" then NUM2 = VM.REGISTERS[CNM2] else NUM2 = CNM2 end VM.REGISTERS[CDST] = NUM1 / NUM2 end end function NEG(REG) REGISTER = checkValue(REG) VM.REGISTERS[REGISTER] = VM.REGISTERS[REGISTER] - (VM.REGISTERS[REGISTER] * 2) end function TST(V1, V2, COND) VAL1 = 0 VAL2 = 0 CVA1 = checkValue(V1) CVA2 = checkValue(V2) if type(CVA1) == "string" then VAL1 = VM.REGISTERS[CVA1] else VAL1 = CVA1 end if type(CVA2) == "string" then VAL2 = VM.REGISTERS[CVA2] else VAL2 = CVA2 end if COND == "=" then if VAL1 == VAL2 then VM.CHECK_REG = 1 else VM.CHECK_REG = 0 end elseif COND == "<" then if VAL1 < VAL2 then VM.CHECK_REG = 1 else VM.CHECK_REG = 0 end elseif COND == ">" then if VAL1 > VAL2 then VM.CHECK_REG = 1 else VM.CHECK_REG = 0 end elseif COND == "!" then if VAL1 ~= VAL2 then VM.CHECK_REG = 1 else VM.CHECK_REG = 0 end else RSOD("The conditional \"" .. COND .. "\" doesn't exists!", "Syntax") end end function JIZ(LINE) if VM.CHECK_REG == 0 then JMP(LINE) end end function JNZ(LINE) if VM.CHECK_REG ~= 0 then JMP(LINE) end end function JGZ(LINE) if VM.CHECK_REG > 0 then JMP(LINE) end end function JLZ(LINE) if VM.CHECK_REG < 0 then JMP(LINE) end end function CLS(COLOR) COLOR = checkValue(COLOR) if COLOR < 0 or COLOR > 15 then RSOD("The color \"" .. tostring(COLOR) .. "\" doesn't exists!", "Syntax") else rect(VM.SCREEN.POSITION[1] + 1, VM.SCREEN.POSITION[2] + 1, VM.SCREEN.RESOLUTION[1], VM.SCREEN.RESOLUTION[2], COLOR) end end function SPR(ID, XC, YC) XCOORD, YCOORD = checkValue(XC) + 1, checkValue(YC) + 1 if ID < 0 or ID > 249 then RSOD("Tile id out of range!", "Syntax") else spr(ID, XCOORD, YCOORD, 0, 1) end end -- INSTRUCTION PARSER FUNCTIONS: function readLine(LINE) POS = LINE * 4 if POS > VM.ROM_LENGT then RSOD("Memory access boundary error!", "Fatal") else POS = VM.ROM_START + POS end RES = {peek(POS), peek(POS + 1), peek(POS + 2), peek(POS + 3)} return RES[1], RES[2], RES[3], RES[4] end function execute(ins, v1, v2, v3) if parseInstruction(ins) == "ENX" then ENX() return parseInstruction(ins) elseif parseInstruction(ins) == "NOP" then NOP() return parseInstruction(ins) elseif parseInstruction(ins) == "MOV" then v1 = checkRegister(v1) v2 = checkRegister(v2) MOV(v1, v2) return parseInstruction(ins) elseif parseInstruction(ins) == "NEG" then v1 = checkRegister(v1) NEG(v1) return parseInstruction(ins) elseif parseInstruction(ins) == "ADD" or parseInstruction(ins) == "SUB" or parseInstruction(ins) == "MUL" or parseInstruction(ins) == "DIV" then v1 = checkRegister(v1) v2 = checkRegister(v2) v3 = checkRegister(v3) if parseInstruction(ins) == "ADD" then ADD(v1, v2, v3) elseif parseInstruction(ins) == "SUB" then SUB(v1, v2, v3) elseif parseInstruction(ins) == "MUL" then MUL(v1, v2, v3) elseif parseInstruction(ins) == "DIV" then DIV(v1, v2, v3) end return parseInstruction(ins) elseif parseInstruction(ins) == "WRT" then v1 = checkRegister(v1) v2 = checkRegister(v2) WRT(v1, v2) return parseInstruction(ins) elseif parseInstruction(ins) == "RDM" then v1 = checkRegister(v1) v2 = checkRegister(v2) RDM(v1, v2) return parseInstruction(ins) elseif parseInstruction(ins) == "FRM" then FRM() return parseInstruction(ins) elseif parseInstruction(ins) == "DCM" then decompile() return parseInstruction(ins) elseif parseInstruction(ins) == "RDT" then NOP() return parseInstruction(ins) elseif parseInstruction(ins) == "PEX" then sleep(mergeValues(v1, v2, v3)) return parseInstruction(ins) elseif parseInstruction(ins) == "JMP" then JMP(mergeValues(v1, v2, v3)) return parseInstruction(ins) elseif parseInstruction(ins) == "TST" then v1 = checkRegister(v1) v2 = checkRegister(v2) if v3 == 0 then v3 = "=" elseif v3 == 1 then v3 = "<" elseif v3 == 2 then v3 = ">" else v3 = "!" end TST(v1, v2, v3) return parseInstruction(ins) elseif parseInstruction(ins) == "JIZ" then JIZ(mergeValues(v1, v2, v3)) return parseInstruction(ins) elseif parseInstruction(ins) == "JNZ" then JNZ(mergeValues(v1, v2, v3)) return parseInstruction(ins) elseif parseInstruction(ins) == "JGZ" then JGZ(mergeValues(v1, v2, v3)) return parseInstruction(ins) elseif parseInstruction(ins) == "JLZ" then JLZ(mergeValues(v1, v2, v3)) return parseInstruction(ins) elseif parseInstruction(ins) == "CLS" then v1 = checkRegister(v1) CLS(v1) return parseInstruction(ins) elseif parseInstruction(ins) == "SPR" then v2 = checkRegister(v2) v3 = checkRegister(v3) SPR(v1, v2, v3) return parseInstruction(ins) else RSOD("The instruction \"" .. tostring(ins) .. "\" doesn't exists!", "Syntax") return parseInstruction(ins) end end function drawUI() local POSITIONS = {VM.SCREEN.RESOLUTION[1] + 2, VM.SCREEN.POSITION[2], (240 - (VM.SCREEN.RESOLUTION[1] + 2)), 136} -- FRAME: rectb(VM.SCREEN.POSITION[1], VM.SCREEN.POSITION[2], VM.SCREEN.RESOLUTION[1] + 2, VM.SCREEN.RESOLUTION[2] + 2, VM.SCREEN.BORDER_COLOR) rect(VM.SCREEN.POSITION[1], VM.SCREEN.RESOLUTION[2] + 2, VM.SCREEN.RESOLUTION[1] + 2, (VM.SCREEN.RESOLUTION[2] + 2) + (136 - (VM.SCREEN.RESOLUTION[2] + 2)), VM.SCREEN.BORDER_COLOR) printf("MT Virtual Machine", ((VM.SCREEN.RESOLUTION[1] - getTextLength("MT Virtual Machine"))//2), VM.SCREEN.RESOLUTION[2] + 2, VM.SCREEN.BACKGROUND_C) -- DEBUG: rect(POSITIONS[1], POSITIONS[2], POSITIONS[3], POSITIONS[4], VM.SCREEN.BACKGROUND_C) rect(POSITIONS[1], POSITIONS[2], POSITIONS[3], 7, VM.SCREEN.BORDER_COLOR) printf("DEBUG PANEL", POSITIONS[1] + ((POSITIONS[3] - getTextLength("DEBUG PANEL"))//2), POSITIONS[2] + 1, VM.SCREEN.BACKGROUND_C) visor(POSITIONS[1], POSITIONS[2] + 7, POSITIONS[3], POSITIONS[4]) end function visor(SW, SH, EW, EH) -- BLOCK SECTION: spr(VM.SCREEN.SPR_INDEX + getBlock(VM.P_COUNTER), SW + (EW - (8*2)), SH, -1, 2) rect((SW + (EW - (8*2))) - 2, SH, 2, (8*2) + 1, VM.SCREEN.BORDER_COLOR) rect((SW + (EW - (8*2))) - 2, SH + (8*2), (8*2) + 2, 2, VM.SCREEN.BORDER_COLOR) printf("CURRENT BLOCK:", SW + 2, SH + 2, VM.SCREEN.BORDER_COLOR) -- REGISTER SECTION: local RTEXT_INDEX = ((8*2) + 2) + 4 printf("REGISTERS:", SW + 2, SH + RTEXT_INDEX, VM.SCREEN.BORDER_COLOR) printf(" PC = " .. tostring(VM.P_COUNTER), SW + 2, SH + (RTEXT_INDEX + 8), VM.SCREEN.BORDER_COLOR) printf(" CC = " .. tostring(VM.C_COUNTER), SW + 2, (SH + (RTEXT_INDEX + 8)) + 8, VM.SCREEN.BORDER_COLOR) printf(" CR = " .. tostring(VM.CHECK_REG), SW + 2, (((SH + (RTEXT_INDEX + 8)) + 8) + 8), VM.SCREEN.BORDER_COLOR) for i=0, 5 do printf(" R" .. string.char(65 + i) .. " = " .. tostring(VM.REGISTERS[string.char(65 + i)]), SW + 2, ((((SH + (RTEXT_INDEX + 8)) + 8) + 8) + 8) + (i*8), VM.SCREEN.BORDER_COLOR) end -- READ-WRITE PERSISTENT MEMORY SECTION: local RTEXT_INDEX = EH - 23 local RWMEM_INDEX = 496 rect(SW, RTEXT_INDEX, EW, 7, VM.SCREEN.BORDER_COLOR) printf("RW MEMORY:", SW + 2, RTEXT_INDEX + 1, VM.SCREEN.BACKGROUND_C) for i = 0, 8 do spr(RWMEM_INDEX + i, SW + (i * 8), RTEXT_INDEX + 7, -1) end local RWMEM_INDEX = RWMEM_INDEX + 8 for i = 0, 8 do spr(RWMEM_INDEX + i, SW + (i * 8), RTEXT_INDEX + 15, -1) end rect(SW + (8*8), RTEXT_INDEX + 7, 2, 8*8, VM.SCREEN.BORDER_COLOR) end -- MAIN VM LOOP: function TIC() if VM.START then trace("MT-VM v" .. tostring(VM.VERSION[1]) .. "." .. tostring(VM.VERSION[2]) .. "." .. tostring(VM.VERSION[3]), 13) trace("") if VM.DECOMPILE then decompile() VM.DECOMPILE = false end drawUI() rect(VM.SCREEN.POSITION[1] + 1, VM.SCREEN.POSITION[2] + 1, VM.SCREEN.RESOLUTION[1], VM.SCREEN.RESOLUTION[2], VM.SCREEN.BACKGROUND_C) VM.START = false elseif not VM.ERROR_REG then drawUI() if btn(0) and btn(4) and btn(5) and VM.DECOMPILED == false then decompile() VM.DECOMPILED = true end INSTR, VA1, VA2, VA3 = readLine(VM.P_COUNTER) INSTR = execute(INSTR, VA1, VA2, VA3) if INSTR == "ENX" then trace("VM ENDED", 13) end if not VM.ERROR_REG then VM.P_COUNTER = VM.P_COUNTER + 1 VM.C_COUNTER = VM.C_COUNTER + 1 end end end