Commit Diff


commit - 0d8d680e5d37cebe6ad59eb5ddb386ed9198507e
commit + 2be87f778a56964007d4c5ccf7171fa000149f79
blob - c13e3c987375f4d827f999dae8a63de533fce3b5
blob + 771e0898b66bd3ce7b85cd60ab72614d746765e4
--- tools/6c
+++ tools/6c
@@ -5,6 +5,9 @@
 -----------------------------------------------------------------------
 local mnemonics = { "mov", "cli", "hlt", "ret", "sti" }
 
+-- This is kinda a double definition but fix later :^)
+local arithmetics = { "+", "-", "*", "/", "^", "~", "|", "&" }
+
 local symbols = { ",", "[", "]", "(", ")", "{", "}", "*", "/", "-",
 	"+", "!", "~", "#", "?", ";", ":" }
 
@@ -12,6 +15,8 @@ local regs8 = { "al", "ah", "bl", "bh", "cl", "ch", "d
 
 local asmkwd = { "asm" }
 
+local tk_misc = { "hexadecimal", "integer", "id", "\n" }
+
 local tk_type = { }
 local count = 0
 
@@ -35,14 +40,14 @@ for i = 1, #asmkwd do
 	tk_type[asmkwd[i]] = count
 end
 
+for i = 1, #tk_misc do
+	count = count + 1
+	tk_type[tk_misc[i]] = count
+end
 local function cincadd()
 	count = count + 1
 	return count
 end
-tk_type.hexadecimal = cincadd()
-tk_type.integer = cincadd()
-tk_type.id = cincadd()
-tk_type["\n"] = cincadd()
 
 -----------------------------------------------------------------------
 -- DEBUGING
@@ -110,6 +115,21 @@ local function isregs8(m)
 	return false
 end
 
+local function isarithmetic(a)
+	local key = gettokenkey(a)
+
+	if key == nil then
+		return false
+	end
+
+	for i,v in ipairs(arithmetics) do
+		if v == key then
+			return true
+		end
+	end
+	return false
+end
+
 -----------------------------------------------------------------------
 -- BITWISE OPERATIONS
 -----------------------------------------------------------------------
@@ -365,9 +385,9 @@ while true do
 			end
 
 			if ishex == true then
-				emittoken(nline, ncol, tk_type.hexadecimal, #data, data)
+				emittoken(nline, ncol, tk_type["hexadecimal"], #data, data)
 			else
-				emittoken(nline, ncol, tk_type.integer, #data, data)
+				emittoken(nline, ncol, tk_type["integer"], #data, data)
 			end
 			i = i + #data
 		elseif char == " " or char == "\t" then
blob - 7ec0dac0f81122dc109dd6e9660fda89a89e952c
blob + c40eacaa915eea26d8db27517a070e966ab2c204
--- tools/6l
+++ tools/6l
@@ -5,6 +5,9 @@
 -----------------------------------------------------------------------
 local mnemonics = { "mov", "cli", "hlt", "ret", "sti" }
 
+-- This is kinda a double definition but fix later :^)
+local arithmetics = { "+", "-", "*", "/", "^", "~", "|", "&" }
+
 local symbols = { ",", "[", "]", "(", ")", "{", "}", "*", "/", "-",
 	"+", "!", "~", "#", "?", ";", ":" }
 
@@ -12,6 +15,8 @@ local regs8 = { "al", "ah", "bl", "bh", "cl", "ch", "d
 
 local asmkwd = { "asm" }
 
+local tk_misc = { "hexadecimal", "integer", "id", "\n" }
+
 local tk_type = { }
 local count = 0
 
@@ -35,14 +40,14 @@ for i = 1, #asmkwd do
 	tk_type[asmkwd[i]] = count
 end
 
+for i = 1, #tk_misc do
+	count = count + 1
+	tk_type[tk_misc[i]] = count
+end
 local function cincadd()
 	count = count + 1
 	return count
 end
-tk_type.hexadecimal = cincadd()
-tk_type.integer = cincadd()
-tk_type.id = cincadd()
-tk_type["\n"] = cincadd()
 
 -----------------------------------------------------------------------
 -- DEBUGING
@@ -110,6 +115,21 @@ local function isregs8(m)
 	return false
 end
 
+local function isarithmetic(a)
+	local key = gettokenkey(a)
+
+	if key == nil then
+		return false
+	end
+
+	for i,v in ipairs(arithmetics) do
+		if v == key then
+			return true
+		end
+	end
+	return false
+end
+
 -----------------------------------------------------------------------
 -- BITWISE OPERATIONS
 -----------------------------------------------------------------------
@@ -289,6 +309,26 @@ local function readhdr()
 	return { line = line, col = col, type = type, len = len, raw = raw }
 end
 
+local function typematch(token, array)
+	local len = #array
+
+	for i = 1, len do
+		if type(array[i]) == "table" then
+			local match = typematch(token, array[i])
+			if match == true then
+				return match
+			end
+		elseif type(array[i]) == "string" then
+			if token.type == tk_type[array[i]] then
+				return true
+			end
+		else
+			perror("illegal typematch must be array or string")
+		end
+	end
+	return false
+end
+
 -- This functions reads an asm line and tells if its a label or instructions
 -- If the return type is instructions, it will tell if its imm8, r8, etc
 --
@@ -306,7 +346,7 @@ local function operlyze(op, ret)
 		ret.opcount = 1
 		table.insert(ret.details, ASM_R8)
 		table.insert(ret.operands, op)
-	elseif op.type == tk_type.integer then
+	elseif op.type == tk_type["integer"] then
 		ret.opcount = 1
 		local val = intval(op.raw)
 		table.insert(ret.operands, op)
@@ -316,7 +356,7 @@ local function operlyze(op, ret)
 		else
 			perror("operand 1 of instruction on line " .. op.line .. " is too big!")
 		end
-	elseif op.type == tk_type.hexadecimal then
+	elseif op.type == tk_type["hexadecimal"] then
 		ret.opcount = 1
 		local val = hexval(op.raw)
 		table.insert(ret.operands, op)
@@ -327,6 +367,68 @@ local function operlyze(op, ret)
 		else
 			perror("operand 1 of instruction on line " .. op.line .. " is too big!")
 		end
+
+	-- You can have max 1 segment registers and 2 GPR. For clarity
+	-- fs:rbx + rcx counts as 1 segment and 2 GPR
+	-- the displacement is capped to 32-bit signed
+	-- No paranthesis allowed for now
+	-- You cannot multiply the base reg (not allowed according to manual)
+	-- You can only multiply index reg by a factor of 2 up to max value 8 (1, 2, 4, 8)
+	elseif op.type == tk_type["["] then
+		local brackets = { opened = 0, closed = 0 }
+
+		while true do
+			local pre = op
+			op = readhdr()
+
+			if op.type == tk_type["\n"] or op.type == tk_type["]"] then
+				break
+			end
+
+			if op.type == tk_type["["] then
+				perror("illegal nested operand at line " .. op.line)
+			end
+
+			if isregs8(op) == true then
+				if typematch(pre, { "[", arithmetics }) == false then
+					perror("missing arithmetic prefix for register " .. gettokenkey(op) ..
+						" line " .. op.line)
+				end
+
+				if #ret.memblock.regs == 0 and typematch(pre, { "+", "-" }) == false then
+					perror("Base register `" .. gettokenkey(op) .. 
+						"` can only be applied + or - on it line " .. op.line)
+				elseif #ret.memblock.regs == 1 and typematch(pre, { "+", "-", "*" }) == false then
+					perror("Index register `" .. gettokenkey(op) .. 
+						"` can only be applied +, - or * on it line " .. op.line)
+				end
+				table.insert(ret.memblock.regs, gettokenkey(op))
+
+			elseif typematch(op, { "hexadecimal", "integer" }) then
+				if typematch(pre, { "[", arithmetics }) == false then
+					perror("missing arithmetic/paranthesis prefix for whole number " .. op.raw ..
+						" line " .. op.line)
+				end
+			-- Other arithmetic symbols
+			elseif isarithmetic(op) == true then
+				if typematch(pre, { regs8, "hexadecimal", "integer" }) == false then
+					perror("illegal token before " .. gettokenkey(op) .. " at line " .. op.line)
+				end
+			else
+				perror("illegal token " .. gettokenkey(op) .. " at line " .. op.line)
+			end
+
+			if #ret.memblock.regs > 2 then
+				perror("a maximum of 2 GPRs are allowed in memory block. Line " .. op.line)
+			end
+		end
+
+		if op.type ~= tk_type["]"] then
+			perror("Missing closing `]` at line " .. op.line)
+		end
+
+		table.insert(ret.details, ASM_MEM8)
+		ret.opcount = 1
 	elseif op.type == tk_type["\n"] then
 		ret.opcount = 0
 	else
@@ -340,7 +442,12 @@ local function asmlyze(first)
 			type = ASM_INSTRUCTION,
 			opcount = 0,
 			details = { },
-			operands = { }
+			operands = { },
+			memblock = { 
+				regs = { },
+				dispsize = 0,
+				blevel = 0,
+			}
 		}
 
 		local op1 = readhdr()
@@ -391,6 +498,7 @@ local function asmlyze(first)
 	end
 end
 
+-- formats instruction to be ready for opcode generation
 local function instvaluate(inst)
 	local regmap = {
 		["al"] = "000", ["ah"] = "100", ["bl"] = "011", ["bh"] = "111",
@@ -420,6 +528,13 @@ local function instvaluate(inst)
 			ret.modrm = bitval("0b11" .. "000" .. dstmap)
 
 			return ret
+		-- mod byte is ...
+		-- 00 memory no displacement
+		-- 01 memory 8 bit displacement
+		-- 10 memory 32 bit displacement
+		-- 11 register to register
+		elseif inst.details[1] == ASM_MEM8 and inst.details[2] == ASM_R8 then
+			return ret
 		end
 	end
 
@@ -438,9 +553,9 @@ local function writemov(inst, eval)
 		writeu8(dst, eval.modrm)
 	elseif inst.details[1] == ASM_R8 and inst.details[2] == ASM_IMM8 then
 		local ib = 0
-		if inst.operands[2].type == tk_type.hexadecimal then
+		if inst.operands[2].type == tk_type["hexadecimal"] then
 			ib = hexval(inst.operands[2].raw)
-		elseif inst.operands[2].type == tk_type.integer then
+		elseif inst.operands[2].type == tk_type["integer"] then
 			ib = intval(inst.operands[2].raw)
 		else
 			perror("attempt to mov a non integer at line " .. inst.operands[2].line)
@@ -481,6 +596,8 @@ while true do
 						elseif inst.details[1] == ASM_R8 and inst.details[2] == ASM_IMM8 then
 							offset = offset + 2
 
+						elseif inst.details[1] == ASM_MEM8 and inst.details[2] == ASM_R8 then
+							offset = offset -- To change later
 						-- huh?
 						else
 							perror("invalid instruction at line " .. hdr.line)
blob - 520f91818c130587e79bd18473207a8f1a9b13b7
blob + 6d39970a0aa2f1314e3971c97ecf869d5bff94ec
--- tools/boot.sc
+++ tools/boot.sc
@@ -1,9 +1,4 @@
 asm {
 _start:
-	mov al, ah
-	mov ah, 0hff
-	ret
-main:
 	hlt
-	cli
 }
blob - 71f6edaaccf35a7ecad23def99747b4524d30cd9
blob + 73c6a396f089b292270ae57e9209b940ccaa8b91
--- tools/compiler.lua
+++ tools/compiler.lua
@@ -128,9 +128,9 @@ while true do
 			end
 
 			if ishex == true then
-				emittoken(nline, ncol, tk_type.hexadecimal, #data, data)
+				emittoken(nline, ncol, tk_type["hexadecimal"], #data, data)
 			else
-				emittoken(nline, ncol, tk_type.integer, #data, data)
+				emittoken(nline, ncol, tk_type["integer"], #data, data)
 			end
 			i = i + #data
 		elseif char == " " or char == "\t" then
blob - fad84b294e1de4a24ef667ced168e53218a52de1
blob + 88127113ea6e94d8819871d58c5f49c92ed74cda
--- tools/linker.lua
+++ tools/linker.lua
@@ -52,6 +52,26 @@ local function readhdr()
 	return { line = line, col = col, type = type, len = len, raw = raw }
 end
 
+local function typematch(token, array)
+	local len = #array
+
+	for i = 1, len do
+		if type(array[i]) == "table" then
+			local match = typematch(token, array[i])
+			if match == true then
+				return match
+			end
+		elseif type(array[i]) == "string" then
+			if token.type == tk_type[array[i]] then
+				return true
+			end
+		else
+			perror("illegal typematch must be array or string")
+		end
+	end
+	return false
+end
+
 -- This functions reads an asm line and tells if its a label or instructions
 -- If the return type is instructions, it will tell if its imm8, r8, etc
 --
@@ -69,7 +89,7 @@ local function operlyze(op, ret)
 		ret.opcount = 1
 		table.insert(ret.details, ASM_R8)
 		table.insert(ret.operands, op)
-	elseif op.type == tk_type.integer then
+	elseif op.type == tk_type["integer"] then
 		ret.opcount = 1
 		local val = intval(op.raw)
 		table.insert(ret.operands, op)
@@ -79,7 +99,7 @@ local function operlyze(op, ret)
 		else
 			perror("operand 1 of instruction on line " .. op.line .. " is too big!")
 		end
-	elseif op.type == tk_type.hexadecimal then
+	elseif op.type == tk_type["hexadecimal"] then
 		ret.opcount = 1
 		local val = hexval(op.raw)
 		table.insert(ret.operands, op)
@@ -90,6 +110,68 @@ local function operlyze(op, ret)
 		else
 			perror("operand 1 of instruction on line " .. op.line .. " is too big!")
 		end
+
+	-- You can have max 1 segment registers and 2 GPR. For clarity
+	-- fs:rbx + rcx counts as 1 segment and 2 GPR
+	-- the displacement is capped to 32-bit signed
+	-- No paranthesis allowed for now
+	-- You cannot multiply the base reg (not allowed according to manual)
+	-- You can only multiply index reg by a factor of 2 up to max value 8 (1, 2, 4, 8)
+	elseif op.type == tk_type["["] then
+		local brackets = { opened = 0, closed = 0 }
+
+		while true do
+			local pre = op
+			op = readhdr()
+
+			if op.type == tk_type["\n"] or op.type == tk_type["]"] then
+				break
+			end
+
+			if op.type == tk_type["["] then
+				perror("illegal nested operand at line " .. op.line)
+			end
+
+			if isregs8(op) == true then
+				if typematch(pre, { "[", arithmetics }) == false then
+					perror("missing arithmetic prefix for register " .. gettokenkey(op) ..
+						" line " .. op.line)
+				end
+
+				if #ret.memblock.regs == 0 and typematch(pre, { "+", "-" }) == false then
+					perror("Base register `" .. gettokenkey(op) .. 
+						"` can only be applied + or - on it line " .. op.line)
+				elseif #ret.memblock.regs == 1 and typematch(pre, { "+", "-", "*" }) == false then
+					perror("Index register `" .. gettokenkey(op) .. 
+						"` can only be applied +, - or * on it line " .. op.line)
+				end
+				table.insert(ret.memblock.regs, gettokenkey(op))
+
+			elseif typematch(op, { "hexadecimal", "integer" }) then
+				if typematch(pre, { "[", arithmetics }) == false then
+					perror("missing arithmetic/paranthesis prefix for whole number " .. op.raw ..
+						" line " .. op.line)
+				end
+			-- Other arithmetic symbols
+			elseif isarithmetic(op) == true then
+				if typematch(pre, { regs8, "hexadecimal", "integer" }) == false then
+					perror("illegal token before " .. gettokenkey(op) .. " at line " .. op.line)
+				end
+			else
+				perror("illegal token " .. gettokenkey(op) .. " at line " .. op.line)
+			end
+
+			if #ret.memblock.regs > 2 then
+				perror("a maximum of 2 GPRs are allowed in memory block. Line " .. op.line)
+			end
+		end
+
+		if op.type ~= tk_type["]"] then
+			perror("Missing closing `]` at line " .. op.line)
+		end
+
+		table.insert(ret.details, ASM_MEM8)
+		ret.opcount = 1
 	elseif op.type == tk_type["\n"] then
 		ret.opcount = 0
 	else
@@ -103,7 +185,12 @@ local function asmlyze(first)
 			type = ASM_INSTRUCTION,
 			opcount = 0,
 			details = { },
-			operands = { }
+			operands = { },
+			memblock = { 
+				regs = { },
+				dispsize = 0,
+				blevel = 0,
+			}
 		}
 
 		local op1 = readhdr()
@@ -184,6 +271,13 @@ local function instvaluate(inst)
 			ret.modrm = bitval("0b11" .. "000" .. dstmap)
 
 			return ret
+		-- mod byte is ...
+		-- 00 memory no displacement
+		-- 01 memory 8 bit displacement
+		-- 10 memory 32 bit displacement
+		-- 11 register to register
+		elseif inst.details[1] == ASM_MEM8 and inst.details[2] == ASM_R8 then
+			return ret
 		end
 	end
 
@@ -202,9 +296,9 @@ local function writemov(inst, eval)
 		writeu8(dst, eval.modrm)
 	elseif inst.details[1] == ASM_R8 and inst.details[2] == ASM_IMM8 then
 		local ib = 0
-		if inst.operands[2].type == tk_type.hexadecimal then
+		if inst.operands[2].type == tk_type["hexadecimal"] then
 			ib = hexval(inst.operands[2].raw)
-		elseif inst.operands[2].type == tk_type.integer then
+		elseif inst.operands[2].type == tk_type["integer"] then
 			ib = intval(inst.operands[2].raw)
 		else
 			perror("attempt to mov a non integer at line " .. inst.operands[2].line)
@@ -245,6 +339,8 @@ while true do
 						elseif inst.details[1] == ASM_R8 and inst.details[2] == ASM_IMM8 then
 							offset = offset + 2
 
+						elseif inst.details[1] == ASM_MEM8 and inst.details[2] == ASM_R8 then
+							offset = offset -- To change later
 						-- huh?
 						else
 							perror("invalid instruction at line " .. hdr.line)
blob - bc25e9dd9309e97d87e1e27f7aad8fb16c655a3b
blob + ae98f98922a5a8d6611cabb8da4d82c4cefa68c7
--- tools/util.lua
+++ tools/util.lua
@@ -3,6 +3,9 @@
 -----------------------------------------------------------------------
 local mnemonics = { "mov", "cli", "hlt", "ret", "sti" }
 
+-- This is kinda a double definition but fix later :^)
+local arithmetics = { "+", "-", "*", "/", "^", "~", "|", "&" }
+
 local symbols = { ",", "[", "]", "(", ")", "{", "}", "*", "/", "-",
 	"+", "!", "~", "#", "?", ";", ":" }
 
@@ -10,6 +13,8 @@ local regs8 = { "al", "ah", "bl", "bh", "cl", "ch", "d
 
 local asmkwd = { "asm" }
 
+local tk_misc = { "hexadecimal", "integer", "id", "\n" }
+
 local tk_type = { }
 local count = 0
 
@@ -33,14 +38,14 @@ for i = 1, #asmkwd do
 	tk_type[asmkwd[i]] = count
 end
 
+for i = 1, #tk_misc do
+	count = count + 1
+	tk_type[tk_misc[i]] = count
+end
 local function cincadd()
 	count = count + 1
 	return count
 end
-tk_type.hexadecimal = cincadd()
-tk_type.integer = cincadd()
-tk_type.id = cincadd()
-tk_type["\n"] = cincadd()
 
 -----------------------------------------------------------------------
 -- DEBUGING
@@ -108,6 +113,21 @@ local function isregs8(m)
 	return false
 end
 
+local function isarithmetic(a)
+	local key = gettokenkey(a)
+
+	if key == nil then
+		return false
+	end
+
+	for i,v in ipairs(arithmetics) do
+		if v == key then
+			return true
+		end
+	end
+	return false
+end
+
 -----------------------------------------------------------------------
 -- BITWISE OPERATIONS
 -----------------------------------------------------------------------
blob - /dev/null
blob + 11a8f0777e691090b3163b0fc7ca37721f2d413b (mode 755)
--- /dev/null
+++ tools/mbrsign
@@ -0,0 +1,57 @@
+#!/usr/local/bin/lua51
+
+-----------------------------------------------------------------------
+-- Checking arguments
+-----------------------------------------------------------------------
+
+progname = "mbrsign"
+
+if arg[1] == nil then
+	print("usage: " .. progname .. " file")
+	os.exit(1)
+end
+
+local function perror(msg)
+	print(progname .. ": " .. msg)
+	os.exit(1)
+end
+
+local file = io.open(arg[1], "rb")
+
+if file == nil then
+	perror("failed to open file " .. arg[1])
+end
+
+
+-----------------------------------------------------------------------
+-- Check file size
+-----------------------------------------------------------------------
+local size = file:seek("end")
+
+if size > 512 then
+	perror("boot file " .. arg[1] .. " size is more than 512 bytes : " .. size .. " bytes")
+end
+
+file:close()
+
+-----------------------------------------------------------------------
+-- Filling 0s
+-----------------------------------------------------------------------
+file = io.open(arg[1], "r+")
+
+if file == nil then
+	perror("faile to open file " .. arg[1] .. " for writting")
+end
+
+if size < 512 then
+	file:seek("set", size)
+	for i = size, 509 do
+		file:write(string.char(0))
+	end
+end
+
+file:seek("set", 510)
+file:write(string.char("0x55"))
+file:write(string.char("0xaa"))
+
+file:close()