Commit Diff


commit - fc369242fc4d8d26841940659c9e6ef95d995ad1
commit + b868c2b1a57866d362bdf3ddd17a0149e7c25376
blob - d007f719884f24c68f2545876792f134cddededd
blob + 122b1b9ebeb3a1c5eb4a9674994f5205cad28359
--- tools/6c
+++ tools/6c
@@ -14,12 +14,14 @@ local symbols = { ",", "[", "]", "(", ")", "{", "}", "
 
 local regs8 = { "al", "ah", "bl", "bh", "cl", "ch", "dl", "dh" }
 
-local regs16 = { "ax", "bx", "cx", "dx" }
+local regs16 = { "ax", "bx", "cx", "dx", "si", "di", "bp", "sp" }
 
 local ptr16 = { "si", "di", "bp", "sp" }
 
-local asmkwd = { "asm" }
+local asmkwd = { "asm", "org" }
 
+local regs = { }
+
 local ckwd = { "u8" }
 
 local tk_misc = { "hexadecimal", "integer", "id", "string", "\n" }
@@ -32,6 +34,10 @@ for i = 1, #mnemonics do
 	tk_type[mnemonics[i]] = count
 end
 
+for i = 1, #regs8 do table.insert(regs, regs8[i]) end
+
+for i = 1, #regs16 do table.insert(regs, regs16[i]) end
+
 for i = 1, #symbols do
 	count = count + 1
 	tk_type[symbols[i]] = count
@@ -146,6 +152,38 @@ local function isregs8(m)
 	return false
 end
 
+local function isregs16(m)
+	local key = gettokenkey(m)
+
+	if key == nil then
+		return false
+	end
+
+	for i, v in ipairs(regs16) do
+		if v == key then
+			return true
+		end
+	end
+
+	return false
+end
+
+local function isregs(m)
+	local key = gettokenkey(m)
+
+	if key == nil then
+		return false
+	end
+
+	for i, v in ipairs(regs) do
+		if v == key then
+			return true
+		end
+	end
+
+	return false
+end
+
 local function isarithmetic(a)
 	local key = gettokenkey(a)
 
@@ -435,6 +473,10 @@ ast.eval = function(node)
 		return { tonumber(node) }
 	end
 
+	if type(node) == "string" then
+		return { { node, 1 } }
+	end
+
 	if node.data[1] == "number" then
 		return { tonumber(node.data[2]) or 0 }
 	end
@@ -502,6 +544,35 @@ end
 -----------------------------------------------------------------------
 
 progname = "6c"
+local offset = nil
+local i = 0
+
+while i < #arg do
+	if arg[i] == "-org" and offset == nil then
+		local value = arg[i + 1]
+		if value == nil then
+			perror("-org flag requires a position")
+		end
+
+		if tonumber(value) ~= nil then
+			perror("-org requires a hexadecimal value")
+		end
+
+		if value:sub(1, 1) ~= "0" and value:sub(2, 2) ~= "h" then
+			perror("ORG needs hexval")
+		end
+		offset = value
+
+		table.remove(arg, i + 1)
+		table.remove(arg, i)
+	end
+	i = i + 1
+end
+
+if offset == nil then
+	offset = "0h00"
+end
+
 local input = arg[1]
 local output = arg[2]
 
@@ -618,6 +689,8 @@ end
 -- Tokenizing
 -----------------------------------------------------------------------
 
+emittoken(0, 0, tk_type["org"], #offset, offset)
+emittoken(0, 0, tk_type["\n"], 0, 0)
 local nline = 1
 while true do
 	local line = src:read("*l")
@@ -665,7 +738,7 @@ while true do
 			end
 
 			if tk_type[id] == nil then
-				emittoken(nline, ncol, tk_type.id, #id, id)
+				emittoken(nline, ncol, tk_type["id"], #id, id)
 			else
 				emittoken(nline, ncol, tk_type[id], 0, nil)
 			end
blob - 75d71488a3c955c3dd92adac692d57c728bd373b
blob + 76a16a010b7c58eefacaa8c4d2aeef9ff4772101
--- tools/6l
+++ tools/6l
@@ -14,12 +14,14 @@ local symbols = { ",", "[", "]", "(", ")", "{", "}", "
 
 local regs8 = { "al", "ah", "bl", "bh", "cl", "ch", "dl", "dh" }
 
-local regs16 = { "ax", "bx", "cx", "dx" }
+local regs16 = { "ax", "bx", "cx", "dx", "si", "di", "bp", "sp" }
 
 local ptr16 = { "si", "di", "bp", "sp" }
 
-local asmkwd = { "asm" }
+local asmkwd = { "asm", "org" }
 
+local regs = { }
+
 local ckwd = { "u8" }
 
 local tk_misc = { "hexadecimal", "integer", "id", "string", "\n" }
@@ -32,6 +34,10 @@ for i = 1, #mnemonics do
 	tk_type[mnemonics[i]] = count
 end
 
+for i = 1, #regs8 do table.insert(regs, regs8[i]) end
+
+for i = 1, #regs16 do table.insert(regs, regs16[i]) end
+
 for i = 1, #symbols do
 	count = count + 1
 	tk_type[symbols[i]] = count
@@ -146,6 +152,38 @@ local function isregs8(m)
 	return false
 end
 
+local function isregs16(m)
+	local key = gettokenkey(m)
+
+	if key == nil then
+		return false
+	end
+
+	for i, v in ipairs(regs16) do
+		if v == key then
+			return true
+		end
+	end
+
+	return false
+end
+
+local function isregs(m)
+	local key = gettokenkey(m)
+
+	if key == nil then
+		return false
+	end
+
+	for i, v in ipairs(regs) do
+		if v == key then
+			return true
+		end
+	end
+
+	return false
+end
+
 local function isarithmetic(a)
 	local key = gettokenkey(a)
 
@@ -435,6 +473,10 @@ ast.eval = function(node)
 		return { tonumber(node) }
 	end
 
+	if type(node) == "string" then
+		return { { node, 1 } }
+	end
+
 	if node.data[1] == "number" then
 		return { tonumber(node.data[2]) or 0 }
 	end
@@ -505,6 +547,7 @@ local input = arg[1]
 local output = arg[2]
 
 local symbol_table = { }
+local csymbols = { }
 local offset = 0
 local parser = {
 	inasm = false, -- In Assembly
@@ -583,12 +626,19 @@ local ASM_INSTRUCTION = 2
 local ASM_R8 = 3
 local ASM_IMM8 = 4
 local ASM_MEM8 = 5
+local ASM_R16 = 6
 
 local function operlyze(op, ret)
 	if isregs8(op) == true then
 		ret.opcount = 1
 		table.insert(ret.details, ASM_R8)
 		table.insert(ret.operands, op)
+
+	elseif isregs16(op) == true then
+		ret.opcount = 1
+		table.insert(ret.details, ASM_R16)
+		table.insert(ret.operands, op)
+
 	elseif op.type == tk_type["integer"] then
 		ret.opcount = 1
 		local val = intval(op.raw)
@@ -632,7 +682,7 @@ local function operlyze(op, ret)
 				perror("illegal nested operand at line " .. op.line)
 			end
 
-			if isregs8(op) == true then
+			if isregs(op) == true then
 				if typematch(pre, { "[", "(", arithmetics }) == false then
 					perror("missing arithmetic prefix for register " .. gettokenkey(op) ..
 						" line " .. op.line)
@@ -662,25 +712,25 @@ local function operlyze(op, ret)
 
 			-- Other arithmetic symbols
 			elseif isarithmetic(op) == true then
-				if typematch(pre, { regs8, "hexadecimal", "integer", ")" }) == false then
+				if typematch(pre, { regs, "hexadecimal", "integer", ")" }) == false then
 					perror("illegal token before " .. gettokenkey(op) .. " at line " .. op.line)
 				end
 
-				if #ret.memblock.regs == 1 and typematch(pre, { regs8 }) == true and typematch(op, { "+", "-" } ) == false then
+				if #ret.memblock.regs == 1 and typematch(pre, { regs }) == true and typematch(op, { "+", "-" } ) == false then
 					perror("Base register `" .. gettokenkey(pre) .. 
 						"` can only be applied + or - on it line " .. op.line)
 				end
 				table.insert(expr, gettokenkey(op))
 
 			elseif op.type == tk_type["("] then
-				if typematch(pre, { regs8, arithmetics, "(", "[" , "hexadecimal", "integer" }) == false then
+				if typematch(pre, { regs, arithmetics, "(", "[" , "hexadecimal", "integer" }) == false then
 					perror("illegal token befor `(` at line " .. op.line)
 				end
 
 				table.insert(expr, "(")
 				depth = depth + 1
 			elseif op.type == tk_type[")"] then
-				if typematch(pre, { regs8, "hexadecimal", ")", "integer" }) == false then
+				if typematch(pre, { regs, "hexadecimal", ")", "integer" }) == false then
 					perror("illegal token before `)` at line " .. op.line)
 				end
 
@@ -788,7 +838,8 @@ end
 local function instvaluate(inst)
 	local regmap = {
 		["al"] = "000", ["ah"] = "100", ["bl"] = "011", ["bh"] = "111",
-		["cl"] = "001", ["ch"] = "101", ["dl"] = "010", ["dh"] = "110"
+		["cl"] = "001", ["ch"] = "101", ["dl"] = "010", ["dh"] = "110",
+		["si"] = "110",
 	}
 
 	local ret = {
@@ -808,6 +859,12 @@ local function instvaluate(inst)
 			local rm = regmap[gettokenkey(inst.operands[1])]
 
 			ret.modrm = bitval("0b" .. mod .. reg .. rm)
+		elseif inst.details[1] == ASM_R16 then
+			local mod = "11"
+			local reg = "000"
+			local rm = regmap[gettokenkey(inst.operands[1])]
+
+			ret.modrm = bitval("0b" .. mod .. reg .. rm)
 		end
 		return ret
 	else
@@ -827,7 +884,7 @@ local function instvaluate(inst)
 		-- 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
+		elseif (inst.details[1] == ASM_MEM8 and inst.details[2] == ASM_R8) or (inst.details[1] == ASM_R8 and inst.details[2] == ASM_MEM8) then
 			local mod = "00"
 
 			local reg1 = nil
@@ -842,8 +899,14 @@ local function instvaluate(inst)
 				end
 			end
 
-			if reg1 ~= nil then dstmap = regmap[reg1] end
-			srcmap = regmap[gettokenkey(inst.operands[1])]
+			if inst.details[1] == ASM_MEM8 then
+				if reg1 ~= nil then dstmap = regmap[reg1] end
+				srcmap = regmap[gettokenkey(inst.operands[1])]
+			else
+				if reg1 ~= nil then srcmap = regmap[reg1] end
+				local k = gettokenkey(inst.operands[1])
+				srcmap = regmap[k]
+			end
 
 			if reg2 ~= nil then
 				for i = 1,#inst.memblock.expression do
@@ -868,9 +931,19 @@ local function instvaluate(inst)
 					displacement = offset
 
 					if reg1 == nil and reg2 == nil then
-						dstmap = "110"
+						if inst.details[1] == ASM_MEM8 then
+							dstmap = "110"
+						else
+							srcmap = "110"
+						end
 					end
 					break
+				else
+					reg = inst.memblock.expression[i][1]
+					
+					if reg == "si" and inst.details[2] == ASM_MEM8 and mod == "00" then
+						dstmap = "100"
+					end
 				end
 			end
 
@@ -883,6 +956,14 @@ local function instvaluate(inst)
 			ret.modrm = bitval("0b" .. mod .. srcmap .. dstmap)
 
 			return ret
+
+		elseif inst.details[1] == ASM_R16 and inst.details[2] == ASM_LABEL then
+			local srcmap = "000"
+			local dstmap = regmap[gettokenkey(inst.operands[1])]
+			local mod = "00"
+
+			ret.modrm = bitval("0b" .. srcmap .. dstmap)
+			return ret
 		end
 	end
 
@@ -927,6 +1008,35 @@ local function writemov(inst, eval)
 				writeu32(dst, addr)
 			end
 		end
+
+	elseif inst.details[1] == ASM_R8 and inst.details[2] == ASM_MEM8 then
+		if #inst.memblock.regs > 0 then
+			local disp = 0
+
+			for i = 1,#inst.memblock.expression do
+				if type(inst.memblock.expression[i]) == "string" then
+					disp = tonumber(inst.memblock.expression[i])
+					print(disp)
+				end
+			end
+
+			writeu8(dst, hexval("0h8A"))
+			writeu8(dst, eval.modrm)
+
+			if disp ~= 0 then
+				writeu8(dst, disp) -- ASSUMING its signed integer
+			end
+		else
+			perror("required register at line " .. inst.operands[1].line)
+		end
+
+	elseif inst.details[1] == ASM_R16 and inst.details[2] == ASM_LABEL then
+		if csymbols[inst.operands[2].raw] ~= nil then
+			local rw = band(eval.modrm, bitval("0b111"))
+			
+			writeu8(dst, hexval("0hB8") + rw)
+			writeu16(dst, csymbols[inst.operands[2].raw])
+		end
 	end
 end
 
@@ -984,7 +1094,8 @@ local function get_instruction_size(hdr, inst)
 
 		if (inst.details[1] == ASM_R8 or inst.details[1] == ASM_IMM8) and (inst.details[2] == ASM_R8 or inst.details[2] == ASM_IMM8) then
 			return 3
-		elseif inst.details[1] == ASM_MEM8 and inst.details[2] == ASM_R8 then
+
+		elseif (inst.details[1] == ASM_MEM8 and inst.details[2] == ASM_R8) or (inst.details[1] == ASM_R8 and inst.details[2] == ASM_MEM8) then
 			local size = 2
 			if inst.memblock and inst.memblock.expression then
 				for _, v in ipairs(inst.memblock.expression) do
@@ -1000,6 +1111,8 @@ local function get_instruction_size(hdr, inst)
 			end
 
 			return size
+		elseif inst.details[1] == ASM_R16 and inst.details[2] == ASM_LABEL then
+			return 3
 		end
 
     elseif hdr.type == tk_type["hlt"] or hdr.type == tk_type["ret"] or hdr.type == tk_type["cli"] then
@@ -1016,6 +1129,8 @@ local function get_instruction_size(hdr, inst)
 	elseif hdr.type == tk_type["inc"] then
 		if inst.details[1] == ASM_R8 then
 			return 2
+		elseif inst.details[1] == ASM_R16 then
+			return 2
 		end
 
 	elseif hdr.type == tk_type["jz"] then
@@ -1050,6 +1165,7 @@ while true do
 	if parser.inasm == true then
 		if hdr.type == tk_type["asm"] then
 			perror("illegal nested asm keyword at line " .. hdr.line .. " column " .. hdr.col)
+
 		elseif hdr.type == tk_type["}"] then
 			parser.inasm = false
 		else
@@ -1099,6 +1215,9 @@ while true do
 				end
 			end
 
+		elseif hdr.type == tk_type["org"] then
+			offset = hexval(hdr.raw)
+
 		elseif hdr.type == tk_type["u8"] then
 			local n = readhdr()
 			
@@ -1119,6 +1238,7 @@ while true do
 
 				if data.type ~= tk_type["string"] then
 					perror("missing string next to " .. name.raw .. " at line " .. hdr.line)
+					csymbol[name.raw] = offset
 				end
 
 				local semi = readhdr()
@@ -1154,6 +1274,7 @@ while true do
 			perror("illegal nested asm keyword at line " .. hdr.line .. " column " .. hdr.col)
 		elseif hdr.type == tk_type["}"] then
 			parser.inasm = false
+
 		else
 			if hdr.type ~= tk_type["\n"] then
 				local inst = asmlyze(hdr)
@@ -1216,6 +1337,11 @@ while true do
 							
 							writeu8(dst, hexval("0hFE"))
 							writeu8(dst, modrm)
+						elseif inst.details[1] == ASM_R16 then
+							local modrm = band(eval.modrm, bitval("0b11000111"))
+
+							writeu8(dst, hexval("0hFF"))
+							writeu8(dst, modrm)
 						end
 					elseif hdr.type == tk_type["jz"] then
 						if inst.details[1] == ASM_LABEL then
@@ -1256,6 +1382,9 @@ while true do
 			parser.inasm = true
 			readhdr() -- Skip `{`
 
+		elseif hdr.type == tk_type["org"] then
+			coffset = hexval(hdr.raw)
+
 		elseif hdr.type == tk_type["u8"] then
 			local n = readhdr()
 
@@ -1273,6 +1402,7 @@ while true do
 						end
 
 						writeu8(dst, 0)
+						csymbols[name.raw] = coffset
 						coffset = coffset + #data + 1
 						readhdr()
 					end
blob - 39c2bc0e58de7275b4ad92debad6d562d422a564
blob + 5e3a7fcec05873e85d3ab8c33f58ca2f2e582794
--- tools/boot.sc
+++ tools/boot.sc
@@ -1,50 +1,37 @@
-/* 
- * boot.sc
- *
- * Just a simple test to see if comments work in the source file
- * as well as the assembly blocks. The assembly blocks can
- * call sections between each other without being in the same
- * block.
- *
- * The next step is to also support things like db, dd, dw and dq.
- * This will allow things like moving string into registers.
- */
+struct DAP {
+	u8 size;
+	u8 rsvd;
+	u16 sectors;
+	u16 destination;
+	u16 segment;
+	u64 blockNum;
+};
 
 /* SKIP BLOCK */
 asm {
-entry:
+skip:
 	jmp start
 }
 
 u8 *msg = "Hello World";
 
 asm {
-start:
-	mov bl, 0hff
-	jmp inter
 print:
 	mov ah, 0h0e
-	mov al, 0h61
+print_loop:
+	mov al, [si]
+	cmp al, 0h00
+	jz print_done
 	int 0h10
+	inc si
+	jmp print_loop
+print_done:
 	ret
-inter:
-	call print
-	dec bl
-	jnz inter
 }
 
 asm {
-	mov cl, 0
+start:
+	mov si, msg
 	call print
-second:
-	mov ah, 0h0e
-	mov al, 0h41
-	int 0h10
-	inc cl
-	cmp cl, 33
-	jz end
-	jmp second
-end:
-	mov [ 0h30 ], bl
 	hlt
 }
blob - 862da8cc04649469c596765516f807dd1ec01c3b
blob + c5b28468b952e9bd0d31772102a2f19a64d1b323
--- tools/compiler.lua
+++ tools/compiler.lua
@@ -3,6 +3,35 @@
 -----------------------------------------------------------------------
 
 progname = "6c"
+local offset = nil
+local i = 0
+
+while i < #arg do
+	if arg[i] == "-org" and offset == nil then
+		local value = arg[i + 1]
+		if value == nil then
+			perror("-org flag requires a position")
+		end
+
+		if tonumber(value) ~= nil then
+			perror("-org requires a hexadecimal value")
+		end
+
+		if value:sub(1, 1) ~= "0" and value:sub(2, 2) ~= "h" then
+			perror("ORG needs hexval")
+		end
+		offset = value
+
+		table.remove(arg, i + 1)
+		table.remove(arg, i)
+	end
+	i = i + 1
+end
+
+if offset == nil then
+	offset = "0h00"
+end
+
 local input = arg[1]
 local output = arg[2]
 
@@ -119,6 +148,8 @@ end
 -- Tokenizing
 -----------------------------------------------------------------------
 
+emittoken(0, 0, tk_type["org"], #offset, offset)
+emittoken(0, 0, tk_type["\n"], 0, 0)
 local nline = 1
 while true do
 	local line = src:read("*l")
@@ -166,7 +197,7 @@ while true do
 			end
 
 			if tk_type[id] == nil then
-				emittoken(nline, ncol, tk_type.id, #id, id)
+				emittoken(nline, ncol, tk_type["id"], #id, id)
 			else
 				emittoken(nline, ncol, tk_type[id], 0, nil)
 			end
blob - 08acb106c046ffe78b27b2a9314e57629653da97
blob + e4e5942926051ed1f8dcc303fbc44d5d16d7639c
--- tools/linker.lua
+++ tools/linker.lua
@@ -6,6 +6,7 @@ local input = arg[1]
 local output = arg[2]
 
 local symbol_table = { }
+local csymbols = { }
 local offset = 0
 local parser = {
 	inasm = false, -- In Assembly
@@ -84,12 +85,19 @@ local ASM_INSTRUCTION = 2
 local ASM_R8 = 3
 local ASM_IMM8 = 4
 local ASM_MEM8 = 5
+local ASM_R16 = 6
 
 local function operlyze(op, ret)
 	if isregs8(op) == true then
 		ret.opcount = 1
 		table.insert(ret.details, ASM_R8)
 		table.insert(ret.operands, op)
+
+	elseif isregs16(op) == true then
+		ret.opcount = 1
+		table.insert(ret.details, ASM_R16)
+		table.insert(ret.operands, op)
+
 	elseif op.type == tk_type["integer"] then
 		ret.opcount = 1
 		local val = intval(op.raw)
@@ -133,7 +141,7 @@ local function operlyze(op, ret)
 				perror("illegal nested operand at line " .. op.line)
 			end
 
-			if isregs8(op) == true then
+			if isregs(op) == true then
 				if typematch(pre, { "[", "(", arithmetics }) == false then
 					perror("missing arithmetic prefix for register " .. gettokenkey(op) ..
 						" line " .. op.line)
@@ -163,25 +171,25 @@ local function operlyze(op, ret)
 
 			-- Other arithmetic symbols
 			elseif isarithmetic(op) == true then
-				if typematch(pre, { regs8, "hexadecimal", "integer", ")" }) == false then
+				if typematch(pre, { regs, "hexadecimal", "integer", ")" }) == false then
 					perror("illegal token before " .. gettokenkey(op) .. " at line " .. op.line)
 				end
 
-				if #ret.memblock.regs == 1 and typematch(pre, { regs8 }) == true and typematch(op, { "+", "-" } ) == false then
+				if #ret.memblock.regs == 1 and typematch(pre, { regs }) == true and typematch(op, { "+", "-" } ) == false then
 					perror("Base register `" .. gettokenkey(pre) .. 
 						"` can only be applied + or - on it line " .. op.line)
 				end
 				table.insert(expr, gettokenkey(op))
 
 			elseif op.type == tk_type["("] then
-				if typematch(pre, { regs8, arithmetics, "(", "[" , "hexadecimal", "integer" }) == false then
+				if typematch(pre, { regs, arithmetics, "(", "[" , "hexadecimal", "integer" }) == false then
 					perror("illegal token befor `(` at line " .. op.line)
 				end
 
 				table.insert(expr, "(")
 				depth = depth + 1
 			elseif op.type == tk_type[")"] then
-				if typematch(pre, { regs8, "hexadecimal", ")", "integer" }) == false then
+				if typematch(pre, { regs, "hexadecimal", ")", "integer" }) == false then
 					perror("illegal token before `)` at line " .. op.line)
 				end
 
@@ -289,7 +297,8 @@ end
 local function instvaluate(inst)
 	local regmap = {
 		["al"] = "000", ["ah"] = "100", ["bl"] = "011", ["bh"] = "111",
-		["cl"] = "001", ["ch"] = "101", ["dl"] = "010", ["dh"] = "110"
+		["cl"] = "001", ["ch"] = "101", ["dl"] = "010", ["dh"] = "110",
+		["si"] = "110",
 	}
 
 	local ret = {
@@ -309,6 +318,12 @@ local function instvaluate(inst)
 			local rm = regmap[gettokenkey(inst.operands[1])]
 
 			ret.modrm = bitval("0b" .. mod .. reg .. rm)
+		elseif inst.details[1] == ASM_R16 then
+			local mod = "11"
+			local reg = "000"
+			local rm = regmap[gettokenkey(inst.operands[1])]
+
+			ret.modrm = bitval("0b" .. mod .. reg .. rm)
 		end
 		return ret
 	else
@@ -328,7 +343,7 @@ local function instvaluate(inst)
 		-- 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
+		elseif (inst.details[1] == ASM_MEM8 and inst.details[2] == ASM_R8) or (inst.details[1] == ASM_R8 and inst.details[2] == ASM_MEM8) then
 			local mod = "00"
 
 			local reg1 = nil
@@ -343,8 +358,14 @@ local function instvaluate(inst)
 				end
 			end
 
-			if reg1 ~= nil then dstmap = regmap[reg1] end
-			srcmap = regmap[gettokenkey(inst.operands[1])]
+			if inst.details[1] == ASM_MEM8 then
+				if reg1 ~= nil then dstmap = regmap[reg1] end
+				srcmap = regmap[gettokenkey(inst.operands[1])]
+			else
+				if reg1 ~= nil then srcmap = regmap[reg1] end
+				local k = gettokenkey(inst.operands[1])
+				srcmap = regmap[k]
+			end
 
 			if reg2 ~= nil then
 				for i = 1,#inst.memblock.expression do
@@ -369,9 +390,19 @@ local function instvaluate(inst)
 					displacement = offset
 
 					if reg1 == nil and reg2 == nil then
-						dstmap = "110"
+						if inst.details[1] == ASM_MEM8 then
+							dstmap = "110"
+						else
+							srcmap = "110"
+						end
 					end
 					break
+				else
+					reg = inst.memblock.expression[i][1]
+					
+					if reg == "si" and inst.details[2] == ASM_MEM8 and mod == "00" then
+						dstmap = "100"
+					end
 				end
 			end
 
@@ -384,6 +415,14 @@ local function instvaluate(inst)
 			ret.modrm = bitval("0b" .. mod .. srcmap .. dstmap)
 
 			return ret
+
+		elseif inst.details[1] == ASM_R16 and inst.details[2] == ASM_LABEL then
+			local srcmap = "000"
+			local dstmap = regmap[gettokenkey(inst.operands[1])]
+			local mod = "00"
+
+			ret.modrm = bitval("0b" .. srcmap .. dstmap)
+			return ret
 		end
 	end
 
@@ -428,6 +467,35 @@ local function writemov(inst, eval)
 				writeu32(dst, addr)
 			end
 		end
+
+	elseif inst.details[1] == ASM_R8 and inst.details[2] == ASM_MEM8 then
+		if #inst.memblock.regs > 0 then
+			local disp = 0
+
+			for i = 1,#inst.memblock.expression do
+				if type(inst.memblock.expression[i]) == "string" then
+					disp = tonumber(inst.memblock.expression[i])
+					print(disp)
+				end
+			end
+
+			writeu8(dst, hexval("0h8A"))
+			writeu8(dst, eval.modrm)
+
+			if disp ~= 0 then
+				writeu8(dst, disp) -- ASSUMING its signed integer
+			end
+		else
+			perror("required register at line " .. inst.operands[1].line)
+		end
+
+	elseif inst.details[1] == ASM_R16 and inst.details[2] == ASM_LABEL then
+		if csymbols[inst.operands[2].raw] ~= nil then
+			local rw = band(eval.modrm, bitval("0b111"))
+			
+			writeu8(dst, hexval("0hB8") + rw)
+			writeu16(dst, csymbols[inst.operands[2].raw])
+		end
 	end
 end
 
@@ -485,7 +553,8 @@ local function get_instruction_size(hdr, inst)
 
 		if (inst.details[1] == ASM_R8 or inst.details[1] == ASM_IMM8) and (inst.details[2] == ASM_R8 or inst.details[2] == ASM_IMM8) then
 			return 3
-		elseif inst.details[1] == ASM_MEM8 and inst.details[2] == ASM_R8 then
+
+		elseif (inst.details[1] == ASM_MEM8 and inst.details[2] == ASM_R8) or (inst.details[1] == ASM_R8 and inst.details[2] == ASM_MEM8) then
 			local size = 2
 			if inst.memblock and inst.memblock.expression then
 				for _, v in ipairs(inst.memblock.expression) do
@@ -501,6 +570,8 @@ local function get_instruction_size(hdr, inst)
 			end
 
 			return size
+		elseif inst.details[1] == ASM_R16 and inst.details[2] == ASM_LABEL then
+			return 3
 		end
 
     elseif hdr.type == tk_type["hlt"] or hdr.type == tk_type["ret"] or hdr.type == tk_type["cli"] then
@@ -517,6 +588,8 @@ local function get_instruction_size(hdr, inst)
 	elseif hdr.type == tk_type["inc"] then
 		if inst.details[1] == ASM_R8 then
 			return 2
+		elseif inst.details[1] == ASM_R16 then
+			return 2
 		end
 
 	elseif hdr.type == tk_type["jz"] then
@@ -551,6 +624,7 @@ while true do
 	if parser.inasm == true then
 		if hdr.type == tk_type["asm"] then
 			perror("illegal nested asm keyword at line " .. hdr.line .. " column " .. hdr.col)
+
 		elseif hdr.type == tk_type["}"] then
 			parser.inasm = false
 		else
@@ -600,6 +674,9 @@ while true do
 				end
 			end
 
+		elseif hdr.type == tk_type["org"] then
+			offset = hexval(hdr.raw)
+
 		elseif hdr.type == tk_type["u8"] then
 			local n = readhdr()
 			
@@ -620,6 +697,7 @@ while true do
 
 				if data.type ~= tk_type["string"] then
 					perror("missing string next to " .. name.raw .. " at line " .. hdr.line)
+					csymbol[name.raw] = offset
 				end
 
 				local semi = readhdr()
@@ -655,6 +733,7 @@ while true do
 			perror("illegal nested asm keyword at line " .. hdr.line .. " column " .. hdr.col)
 		elseif hdr.type == tk_type["}"] then
 			parser.inasm = false
+
 		else
 			if hdr.type ~= tk_type["\n"] then
 				local inst = asmlyze(hdr)
@@ -717,6 +796,11 @@ while true do
 							
 							writeu8(dst, hexval("0hFE"))
 							writeu8(dst, modrm)
+						elseif inst.details[1] == ASM_R16 then
+							local modrm = band(eval.modrm, bitval("0b11000111"))
+
+							writeu8(dst, hexval("0hFF"))
+							writeu8(dst, modrm)
 						end
 					elseif hdr.type == tk_type["jz"] then
 						if inst.details[1] == ASM_LABEL then
@@ -757,6 +841,9 @@ while true do
 			parser.inasm = true
 			readhdr() -- Skip `{`
 
+		elseif hdr.type == tk_type["org"] then
+			coffset = hexval(hdr.raw)
+
 		elseif hdr.type == tk_type["u8"] then
 			local n = readhdr()
 
@@ -774,6 +861,7 @@ while true do
 						end
 
 						writeu8(dst, 0)
+						csymbols[name.raw] = coffset
 						coffset = coffset + #data + 1
 						readhdr()
 					end
blob - 77dcb7dfc5944eca9f8a0559f1f72c0e8a9c0f4f
blob + bd0e7f99e83117aeea2baf2059f3d4dd789b319f
--- tools/mkmbr
+++ tools/mkmbr
@@ -2,4 +2,4 @@
 
 set -e
 
-./6c boot.sc && ./6l boot.6 && ./mbrsign 6.boot
+./6c -org 0h7c00 boot.sc && ./6l boot.6 && ./mbrsign 6.boot
blob - 4f2c6e65529c5e9cde697a510410e1f6ba2ab2f8
blob + 3edcc8b34cdf43de8bf627f3777428bad65ea457
--- tools/util.lua
+++ tools/util.lua
@@ -12,12 +12,14 @@ local symbols = { ",", "[", "]", "(", ")", "{", "}", "
 
 local regs8 = { "al", "ah", "bl", "bh", "cl", "ch", "dl", "dh" }
 
-local regs16 = { "ax", "bx", "cx", "dx" }
+local regs16 = { "ax", "bx", "cx", "dx", "si", "di", "bp", "sp" }
 
 local ptr16 = { "si", "di", "bp", "sp" }
 
-local asmkwd = { "asm" }
+local asmkwd = { "asm", "org" }
 
+local regs = { }
+
 local ckwd = { "u8" }
 
 local tk_misc = { "hexadecimal", "integer", "id", "string", "\n" }
@@ -30,6 +32,10 @@ for i = 1, #mnemonics do
 	tk_type[mnemonics[i]] = count
 end
 
+for i = 1, #regs8 do table.insert(regs, regs8[i]) end
+
+for i = 1, #regs16 do table.insert(regs, regs16[i]) end
+
 for i = 1, #symbols do
 	count = count + 1
 	tk_type[symbols[i]] = count
@@ -144,6 +150,38 @@ local function isregs8(m)
 	return false
 end
 
+local function isregs16(m)
+	local key = gettokenkey(m)
+
+	if key == nil then
+		return false
+	end
+
+	for i, v in ipairs(regs16) do
+		if v == key then
+			return true
+		end
+	end
+
+	return false
+end
+
+local function isregs(m)
+	local key = gettokenkey(m)
+
+	if key == nil then
+		return false
+	end
+
+	for i, v in ipairs(regs) do
+		if v == key then
+			return true
+		end
+	end
+
+	return false
+end
+
 local function isarithmetic(a)
 	local key = gettokenkey(a)
 
@@ -433,6 +471,10 @@ ast.eval = function(node)
 		return { tonumber(node) }
 	end
 
+	if type(node) == "string" then
+		return { { node, 1 } }
+	end
+
 	if node.data[1] == "number" then
 		return { tonumber(node.data[2]) or 0 }
 	end