Commit Diff


commit - 8cd27d016af5c15375e30fd490a71a5cd6a803e9
commit + e0074095e24797bb794ffd465b0b2a6442caa8d9
blob - 2e181e40bb6bac090d4115b2baae058e2d7445dc
blob + 7de524159eeb3940ea7270e030f030511e494f59
--- tools/6c
+++ tools/6c
@@ -110,6 +110,21 @@ local TOKEN_ID = 17
 local TOKEN_STRING = 18
 local TOKEN_SEMICOLON = 19
 local TOKEN_HASH = 20
+local TOKEN_COMMA = 21
+local TOKEN_HLT = 22
+local TOKEN_RET = 23
+local TOKEN_CLI = 24
+local TOKEN_STI = 25
+local TOKEN_AH = 26
+local TOKEN_AL = 27
+local TOKEN_BH = 28
+local TOKEN_BL = 29
+local TOKEN_CL = 30
+local TOKEN_CH = 31
+local TOKEN_DL = 32
+local TOKEN_DH = 33
+local TOKEN_MOV = 34
+local TOKEN_HEXADECIMAL = 35
 
 local function issymbol(char)
 	if char == "{" or
@@ -128,6 +143,7 @@ local function issymbol(char)
 	   char == "." or
 	   char == ":" or
 	   char == ";" or
+	   char == "," or
 	   char == "#" then
 		return true
 	end
@@ -164,6 +180,10 @@ local function readid(line, s)
 			break
 		end
 
+		if i == s and isnumber(char) == true then
+			break
+		end
+
 		table.insert(buf, char)
 	end
 
@@ -173,11 +193,37 @@ end
 local function readint(line, s)
 	local len = #line
 	local buf = { }
+	local hex = false
 
 	for i = s, len do
 		local char = line:sub(i, i)
+
 		if isnumber(char) == false then
-			break
+			if hex == false then
+				if char == "h" and (i - s) == 1 then
+					local prefix = line:sub(i - 1, i - 1)
+
+					if prefix ~= "0" then
+						perror("illegal token `" .. prefix .. "` next to number : " .. line)
+					end
+
+					hex = true
+				else
+					if char ~= "" and char ~= " " then
+						print("illegal sufix for number line : " .. line)
+					end
+				end
+			else
+				if char == "" or char == " " then 
+					break 
+				end
+
+				if char ~= "a" and char ~= "A" and char ~= "b" and char ~= "B" and
+				   char ~= "c" and char ~= "C" and char ~= "d" and char ~= "D" and
+				   char ~= "e" and char ~= "E" and char ~= "f" and char ~= "F" then
+					perror("illegal sufix `" .. char .. "` for hexadecimal " .. line)
+				end
+			end
 		end
 
 		table.insert(buf, char)
@@ -229,6 +275,8 @@ while true do
 				write_u16(TOKEN_SEMICOLON)
 			elseif char == "#" then
 				write_u16(TOKEN_HASH)
+			elseif char == "," then
+				write_u16(TOKEN_COMMA)
 			else
 				print("Unknown symbol : " .. char)
 			end
@@ -244,9 +292,20 @@ while true do
 
 		elseif isnumber(char) then
 			local sint = readint(line, i)
+			local ishex = false
+
+			if sint:sub(2, 2) == "h" then
+				ishex = true
+			end
+
 			local j = 1
 			write_u32(nline)
 			write_u32(column)
+			if ishex == true then
+				write_u16(TOKEN_HEXADECIMAL)
+			else
+				write_u16(TOKEN_INTEGER)
+			end
 			write_u16(#sint)
 			i = i + #sint
 
@@ -264,6 +323,45 @@ while true do
 			if id == "asm" then
 				write_u16(TOKEN_ASM)
 				write_u16(0)
+			elseif id == "hlt" then
+				write_u16(TOKEN_HLT)
+				write_u16(0)
+			elseif id == "ret" then
+				write_u16(TOKEN_RET)
+				write_u16(0)
+			elseif id == "cli" then
+				write_u16(TOKEN_CLI)
+				write_u16(0)
+			elseif id == "sti" then
+				write_u16(TOKEN_STI)
+				write_u16(0)
+			elseif id == "ah" then
+				write_u16(TOKEN_AH)
+				write_u16(0)
+			elseif id == "al" then
+				write_u16(TOKEN_AL)
+				write_u16(0)
+			elseif id == "bh" then
+				write_u16(TOKEN_BH)
+				write_u16(0)
+			elseif id == "bl" then
+				write_u16(TOKEN_BL)
+				write_u16(0)
+			elseif id == "ch" then
+				write_u16(TOKEN_CH)
+				write_u16(0)
+			elseif id == "cl" then
+				write_u16(TOKEN_CL)
+				write_u16(0)
+			elseif id == "dh" then
+				write_u16(TOKEN_DH)
+				write_u16(0)
+			elseif id == "dl" then
+				write_u16(TOKEN_DL)
+				write_u16(0)
+			elseif id == "mov" then
+				write_u16(TOKEN_MOV)
+				write_u16(0)
 			else
 				local j = 1
 				write_u16(TOKEN_ID)
@@ -289,3 +387,5 @@ end
 
 src:close()
 dst:close()
+
+print(progname .. ": " .. arg[1] .. " -> " .. arg[2])
blob - 11e1d810af892577140dd17861cc1755c5503e5a
blob + ce8ce69a13ac2aa9f4ce553f4fe23518d06d60e8
--- tools/6l
+++ tools/6l
@@ -3,6 +3,360 @@
 progname = "6l"
 
 if (arg[1] == nil) then
-	print("usage: " .. progname .. " file")
+	print("usage: " .. progname .. " [file ...]")
 	os.exit(1)
 end
+
+if arg[2] == nil then
+	arg[2] = "6." ..string.gsub(arg[1], "%.%w+$", "")
+end
+
+local function perror(msg)
+	print(progname .. ": error: " .. msg)
+	os.exit(1)
+end
+
+src = io.open(arg[1], "rb")
+
+if src == nil then
+	perror("failed to open " .. arg[1])
+end
+
+dst = io.open(arg[2], "wb")
+
+if dst == nil then
+	perror("failed to open " .. arg[2])
+end
+
+local function brshift(value, bit)
+	return math.floor(value / (2 ^ bit))
+end
+
+local function blshift(value, bit)
+	return value * (2 ^ bit)
+end
+
+local function bor(a, b)
+	local result = 0
+	local shift = 1
+
+	while a > 0 or b > 0 do
+		local r1 = a % 2
+		local r2 = b % 2
+
+		if r1 == 1 or r2 == 1 then
+			result = result + shift
+		end
+
+		a = math.floor(a / 2)
+		b = math.floor(b / 2)
+		shift = shift * 2
+	end
+
+	return result
+end
+
+--[[
+
+Token {
+	u32 Line;
+	u32 Column;
+	u16 Type;
+	u16 Length;
+}
+
+]]--
+
+local TOKEN_ASM = 0
+local TOKEN_LEFT_CURLY_BRACKET = 1
+local TOKEN_RIGHT_CURLY_BRACKET = 2
+local TOKEN_MULTIPLY = 3
+local TOKEN_DIVIDE = 4
+local TOKEN_SUBTRACT = 5
+local TOKEN_ADD = 6
+local TOKEN_LEFT_SQUARE_BRACKET = 7
+local TOKEN_RIGHT_SQUARE_BRACKET = 8
+local TOKEN_LEFT_PARANTHESIS = 9
+local TOKEN_RIGHT_PARANTHESIS = 10
+local TOKEN_QUESTION = 11
+local TOKEN_EXCLAMATION = 12
+local TOKEN_TILDA = 13
+local TOKEN_PERIOD = 14
+local TOKEN_COLUMN = 15
+local TOKEN_INTEGER = 16
+local TOKEN_ID = 17
+local TOKEN_STRING = 18
+local TOKEN_SEMICOLON = 19
+local TOKEN_HASH = 20
+local TOKEN_COMMA = 21
+local TOKEN_HLT = 22
+local TOKEN_RET = 23
+local TOKEN_CLI = 24
+local TOKEN_STI = 25
+local TOKEN_AH = 26
+local TOKEN_AL = 27
+local TOKEN_BH = 28
+local TOKEN_BL = 29
+local TOKEN_CL = 30
+local TOKEN_CH = 31
+local TOKEN_DL = 32
+local TOKEN_DH = 33
+local TOKEN_MOV = 34
+local TOKEN_HEXADECIMAL = 35
+
+local asm = {
+	hlt = 0xF4,
+	ret = 0xC3, -- Near return
+	cli = 0xFA,
+	sti = 0xFB,
+}
+
+local MODE_NONE = 0
+local MODE_ASM = 1
+
+function readtoken()
+	local header = src:read(12)
+
+	if header == nil then
+		return nil
+	end
+
+	local b = { string.byte(header, 1, 12) }
+
+	local line = b[4] + blshift(b[3], 8) + blshift(b[2], 16) + blshift(b[1], 24)
+	local col = b[8] + blshift(b[7], 8) + blshift(b[6], 16) + blshift(b[5], 24)
+	local type = b[10] + blshift(b[9], 8)
+	local length = b[12] + blshift(b[11], 8)
+	local raw = src:read(length)
+
+	return { column = col, line = line, type = type, length = length, raw = raw }
+end
+
+function hexval(hex)
+	local dig = hex:sub(3)
+	local len = #dig
+	local result = 0
+
+	for i = 1,len do
+		local d = dig:sub(i, i)
+
+		if d:lower() == "a" then
+			d = 10
+		elseif d:lower() == "b" then
+			d = 11
+		elseif d:lower() == "c" then
+			d = 12
+		elseif d:lower() == "d" then
+			d = 13
+		elseif d:lower() == "e" then
+			d = 14
+		elseif d:lower() == "f" then
+			d = 15
+		end
+
+		result = result + d * (16 ^ (len - i))
+	end
+
+	return result
+end
+
+local mode = MODE_NONE
+local brace_depth = 0
+local begin = src:seek("cur")
+
+while true do
+	local token = readtoken()
+	if token == nil then
+		break
+	end
+
+	-- Syntax check
+	if token.type == TOKEN_ASM then
+		if mode == MODE_ASM then
+			perror("error: nested asm attempt at line " .. token.line .. " column " .. token.column)
+			break
+		end
+
+		local next = readtoken()
+		if next == nil or next.type ~= TOKEN_LEFT_CURLY_BRACKET then
+			perror("error: missing '{' after asm at line " .. token.line .. " column " .. token.column)
+			break
+		end
+
+		mode = MODE_ASM
+	elseif token.type == TOKEN_HLT then
+		if mode ~= MODE_ASM then
+			perror("error: hlt instruction outside asm block at line " .. token.line .. " column " ..
+				token.column)
+		end
+
+		local next = readtoken()
+
+		if next ~= nil and next.line == token.line then
+			perror("error: illegal token next to hlt on line " .. token.line .. " column " .. 
+				token.column)
+		end
+	elseif token.type == TOKEN_RET then
+		if mode ~= MODE_ASM then
+			perror("error: ret instruction out of asm block at line " .. token.line .. " column " ..
+				token.column)
+		end
+
+		local next = readtoken()
+		if next ~= nil and next.line == token.line then
+			perror("error: illegal token after ret on line " .. token.line " .. column " ..
+				token.column)
+		end
+	elseif token.type == TOKEN_CLI then
+		if mode ~= MODE_ASM then
+			perror("error: cli instruction out of asm block at line " .. token.line .. " column " ..
+				token.column)
+		end
+
+		local next = readtoken()
+		if next ~= nil and next.line == token.line then
+			perror("error: illegal token after cli on line " .. token.line " .. column " ..
+				token.column)
+		end
+	elseif token.type == TOKEN_STI then
+		if mode ~= MODE_ASM then
+			perror("error: sti instruction out of asm block at line " .. token.line .. " column " ..
+				token.column)
+		end
+
+		local next = readtoken()
+		if next ~= nil and next.line == token.line then
+			perror("error: illegal token after sti on line " .. token.line " .. column " ..
+				token.column)
+		end
+
+	elseif token.type == TOKEN_MOV then
+		if mode ~= MODE_ASM then
+			perror("error: sti instruction out of asm block at line " .. token.line .. " column " ..
+				token.column)
+		end
+
+		local op1 = readtoken()
+
+		if op1.type ~= TOKEN_AL and op1.type ~= TOKEN_AH and op1.type ~= TOKEN_BL and
+		   op1.type ~= TOKEN_BH and op1.type ~= TOKEN_CH and
+		   op1.type ~= TOKEN_CL and op1.type ~= TOKEN_DH and
+		   op1.type ~= TOKEN_DL then
+			perror("illegal first operand for mov at line " .. token.line .. " column " ..
+				token.column)
+		end
+
+		local comma = readtoken()
+
+		if comma.type ~= TOKEN_COMMA then
+			perror("missing comma next to first operand line " .. token.line .. " column " ..
+				token.column)
+		end
+
+		local op2 = readtoken()
+
+		if op2.type ~= TOKEN_AL and op2.type ~= TOKEN_AH and op2.type ~= TOKEN_BL and
+		   op2.type ~= TOKEN_BH and op2.type ~= TOKEN_CH and
+		   op2.type ~= TOKEN_CL and op2.type ~= TOKEN_DH and
+		   op2.type ~= TOKEN_DL and op2.type ~= TOKEN_HEXADECIMAL then
+			perror("illegal second operand for mov at line " .. token.line .. " column " ..
+				token.column)
+		end
+
+		-- Checking if hex value is to high: mov r8, imm8
+		if op2.type == TOKEN_HEXADECIMAL and 
+		  (op1.type == TOKEN_AH or op1.type == TOKEN_AL or
+		   op1.type == TOKEN_BH or op1.type == TOKEN_BL or
+		   op1.type == TOKEN_CH or op1.type == TOKEN_CL or
+		   op1.type == TOKEN_DH or op1.type == TOKEN_DL) then
+			if hexval(op2.raw) > 255 then
+				perror("hexvalue too high at line " .. token.line .. " column " .. token.column)
+			end
+		end
+	end
+end
+
+src:seek("set", begin)
+
+while true do
+	local token = readtoken()
+	if token == nil then
+		break
+	end
+
+	if token.type == TOKEN_HLT then
+		dst:write(string.char(asm.hlt))
+	elseif token.type == TOKEN_RET then
+		dst:write(string.char(asm.ret))
+	elseif token.type == TOKEN_CLI then
+		dst:write(string.char(asm.cli))
+	elseif token.type == TOKEN_STI then
+		dst:write(string.char(asm.sti))
+	elseif token.type == TOKEN_MOV then
+		local op1 = readtoken()
+		readtoken() -- Comma
+		local op2 = readtoken()
+
+		if op1.type == TOKEN_AL then
+			if op2.type == TOKEN_HEXADECIMAL then
+				local opcode = { hexval("0hB0") + tonumber("000", 2), hexval(op2.raw) }
+
+				dst:write(string.char(opcode[1]))
+				dst:write(string.char(opcode[2]))
+			end
+		elseif op1.type == TOKEN_AH then
+			if op2.type == TOKEN_HEXADECIMAL then
+				local opcode = { hexval("0hB0") + tonumber("100", 2), hexval(op2.raw) }
+
+				dst:write(string.char(opcode[1]))
+				dst:write(string.char(opcode[2]))
+			end
+		elseif op1.type == TOKEN_BL then
+			if op2.type == TOKEN_HEXADECIMAL then
+				local opcode = { hexval("0hB0") + tonumber("011", 2), hexval(op2.raw) }
+
+				dst:write(string.char(opcode[1]))
+				dst:write(string.char(opcode[2]))
+			end
+		elseif op1.type == TOKEN_BH then
+			if op2.type == TOKEN_HEXADECIMAL then
+				local opcode = { hexval("0hB0") + tonumber("111", 2), hexval(op2.raw) }
+
+				dst:write(string.char(opcode[1]))
+				dst:write(string.char(opcode[2]))
+			end
+		elseif op1.type == TOKEN_CL then
+			if op2.type == TOKEN_HEXADECIMAL then
+				local opcode = { hexval("0hB0") + tonumber("001", 2), hexval(op2.raw) }
+
+				dst:write(string.char(opcode[1]))
+				dst:write(string.char(opcode[2]))
+			end
+		elseif op1.type == TOKEN_CH then
+			if op2.type == TOKEN_HEXADECIMAL then
+				local opcode = { hexval("0hB0") + tonumber("101", 2), hexval(op2.raw) }
+
+				dst:write(string.char(opcode[1]))
+				dst:write(string.char(opcode[2]))
+			end
+		elseif op1.type == TOKEN_DL then
+			if op2.type == TOKEN_HEXADECIMAL then
+				local opcode = { hexval("0hB0") + tonumber("010", 2), hexval(op2.raw) }
+
+				dst:write(string.char(opcode[1]))
+				dst:write(string.char(opcode[2]))
+			end
+		elseif op1.type == TOKEN_DH then
+			if op2.type == TOKEN_HEXADECIMAL then
+				local opcode = { hexval("0hB0") + tonumber("110", 2), hexval(op2.raw) }
+
+				dst:write(string.char(opcode[1]))
+				dst:write(string.char(opcode[2]))
+			end
+		end
+	end
+end
+
+src:close()
+dst:close()
+print(arg[1] .. " -> " .. arg[2])
blob - 41132f6b89059a67428a66b152a26ab7cf840a38
blob + 17dc1369b1522cc6139fcb7b47f9086f35c4d8bb
--- tools/boot.c
+++ tools/boot.c
@@ -1,11 +1,4 @@
-import libc;
-
 asm {
 _start:
-	hlt
+	ret
 }
-
-void main()
-{
-	u64 var = 22;
-}