Commit Diff


commit - 221a1b719280333b07e0739eeef1308433a758fe
commit + 923305236bcc5057428793a83fad7fc77f2ca4f3
blob - 98a6df92252d1ffb9d3d547479793d5adc94c6ca
blob + a422333b0d09daf877bbbd0e4082f9954ede2c9f
--- tools/6c
+++ tools/6c
@@ -4,7 +4,7 @@
 -- TOKEN MATCHING
 -----------------------------------------------------------------------
 local mnemonics = { "mov", "cli", "hlt", "ret", "sti", "int", "call", 
-	"jmp", "dec", "jz", "jnz" }
+	"jmp", "dec", "jz", "jnz", "cmp", "inc" }
 
 -- This is kinda a double definition but fix later :^)
 local arithmetics = { "+", "-", "*", "/", "^", "~", "|", "&" }
@@ -56,6 +56,7 @@ end
 local MAX_S16 = 2^15-1
 local MIN_S16 = -2^15
 local MAX_U16 = 2^16
+local MAX_U32 = 2^32
 
 -----------------------------------------------------------------------
 -- DEBUGING
@@ -217,7 +218,15 @@ local function writeu32(dst, value)
 	dst:write(string.char(b1, b2, b3, b4)) -- Little Endian x86
 end
 
+local function writes32(dst, value)
+	if value < 0 then
+		value = MAX_U32 + value
+	end
 
+	writeu32(dst, value)
+end
+
+
 local function intval(intstr)
 	local len = #intstr
 	local res = 0
@@ -400,6 +409,10 @@ ast.genast = function(expr)
 end
 
 ast.eval = function(node)
+	if tonumber(node) ~= nil then
+		return { tonumber(node) }
+	end
+
 	if node.data[1] == "number" then
 		return { tonumber(node.data[2]) or 0 }
 	end
blob - 38f73f4bb1f280db4f59b2f47943154e35488a3d
blob + ab515874c65a09776f2571749e6e6ee0f8379fe0
--- tools/6l
+++ tools/6l
@@ -4,7 +4,7 @@
 -- TOKEN MATCHING
 -----------------------------------------------------------------------
 local mnemonics = { "mov", "cli", "hlt", "ret", "sti", "int", "call", 
-	"jmp", "dec", "jz", "jnz" }
+	"jmp", "dec", "jz", "jnz", "cmp", "inc" }
 
 -- This is kinda a double definition but fix later :^)
 local arithmetics = { "+", "-", "*", "/", "^", "~", "|", "&" }
@@ -56,6 +56,7 @@ end
 local MAX_S16 = 2^15-1
 local MIN_S16 = -2^15
 local MAX_U16 = 2^16
+local MAX_U32 = 2^32
 
 -----------------------------------------------------------------------
 -- DEBUGING
@@ -217,7 +218,15 @@ local function writeu32(dst, value)
 	dst:write(string.char(b1, b2, b3, b4)) -- Little Endian x86
 end
 
+local function writes32(dst, value)
+	if value < 0 then
+		value = MAX_U32 + value
+	end
 
+	writeu32(dst, value)
+end
+
+
 local function intval(intstr)
 	local len = #intstr
 	local res = 0
@@ -400,6 +409,10 @@ ast.genast = function(expr)
 end
 
 ast.eval = function(node)
+	if tonumber(node) ~= nil then
+		return { tonumber(node) }
+	end
+
 	if node.data[1] == "number" then
 		return { tonumber(node.data[2]) or 0 }
 	end
@@ -925,6 +938,21 @@ local function writejmp(inst, curr)
 	end
 end
 
+local function writecmp(inst, eval)
+	if inst.details[1] == ASM_R8 and inst.details[2] == ASM_IMM8 then
+		local op = inst.operands[2]
+		local modrm = eval.modrm
+		local imm8 = (op.type == tk_type["hexadecimal"]) and hexval(op.raw) or intval(op.raw)
+
+		modrm = band(eval.modrm, bitval("0b11000111"))
+		modrm = bor(modrm, bitval("0b00111000"))
+		
+		writeu8(dst, hexval("0h80"))
+		writeu8(dst, modrm)
+		writeu8(dst, imm8)
+	end
+end
+
 local function get_instruction_size(hdr, inst)
     if hdr.type == tk_type["mov"] then
 		local opcount = #inst.details
@@ -961,16 +989,27 @@ local function get_instruction_size(hdr, inst)
 		if inst.details[1] == ASM_R8 then
 			return 2
 		end
+
+	elseif hdr.type == tk_type["inc"] then
+		if inst.details[1] == ASM_R8 then
+			return 2
+		end
+
 	elseif hdr.type == tk_type["jz"] then
 		if inst.details[1] == ASM_LABEL then
 			return 4 -- WE ASSUME IT IS REAL MODE HENCE A 2 BYTES ADDRESS
 		end
+	
 	elseif hdr.type == tk_type["jnz"] then
 		if inst.details[1] == ASM_LABEL then
 			return 4 -- WE ASSUME ITS REAL MODE
 		else
 			perror("jnz only support labels for now")
 		end
+	elseif hdr.type == tk_type["cmp"] then
+		if inst.details[1] == ASM_R8 and inst.details[2] == ASM_IMM8 then
+			return 3
+		end
     end
     return 0
 end
@@ -1093,6 +1132,13 @@ while true do
 							writeu8(dst, eval.modrm)
 						end
 
+					elseif hdr.type == tk_type["inc"] then
+						if inst.details[1] == ASM_R8 then
+							local modrm = band(eval.modrm, bitval("0b11000111"))
+							
+							writeu8(dst, hexval("0hFE"))
+							writeu8(dst, modrm)
+						end
 					elseif hdr.type == tk_type["jz"] then
 						if inst.details[1] == ASM_LABEL then
 							local addr = symbol_table[inst.operands[1].raw]
@@ -1121,6 +1167,8 @@ while true do
 							writes16(dst, addr - coffset)
 						end
 
+					elseif hdr.type == tk_type["cmp"] then
+						writecmp(inst, eval)
 					end
 				end
 			end
blob - 4d889701ee2fbcdd8d607ff6366016bcbe0da108
blob + bebf513b56d50f1ce90cb3994db35cbbfa782e46
--- tools/boot.sc
+++ tools/boot.sc
@@ -10,9 +10,20 @@ print:
 inter:
 	call print
 	dec bl
-	jz end
 	jnz inter
+}
+
+asm {
+	mov cl, 0
+second:
+	mov ah, 0h0e
+	mov al, 0h41
+	int 0h10
+	inc cl
+	cmp cl, 33
+	jz end
+	jmp second
 end:
-	mov [ 0h100 + 300], bl
+	mov [ 0h30 ], bl
 	hlt
 }
blob - 4b79652e60434d0c33b5a3c10731898ff2e848f0
blob + fde3083bfbc7d30f4de8c831e63a279544968e3c
--- tools/linker.lua
+++ tools/linker.lua
@@ -461,6 +461,21 @@ local function writejmp(inst, curr)
 	end
 end
 
+local function writecmp(inst, eval)
+	if inst.details[1] == ASM_R8 and inst.details[2] == ASM_IMM8 then
+		local op = inst.operands[2]
+		local modrm = eval.modrm
+		local imm8 = (op.type == tk_type["hexadecimal"]) and hexval(op.raw) or intval(op.raw)
+
+		modrm = band(eval.modrm, bitval("0b11000111"))
+		modrm = bor(modrm, bitval("0b00111000"))
+		
+		writeu8(dst, hexval("0h80"))
+		writeu8(dst, modrm)
+		writeu8(dst, imm8)
+	end
+end
+
 local function get_instruction_size(hdr, inst)
     if hdr.type == tk_type["mov"] then
 		local opcount = #inst.details
@@ -497,16 +512,27 @@ local function get_instruction_size(hdr, inst)
 		if inst.details[1] == ASM_R8 then
 			return 2
 		end
+
+	elseif hdr.type == tk_type["inc"] then
+		if inst.details[1] == ASM_R8 then
+			return 2
+		end
+
 	elseif hdr.type == tk_type["jz"] then
 		if inst.details[1] == ASM_LABEL then
 			return 4 -- WE ASSUME IT IS REAL MODE HENCE A 2 BYTES ADDRESS
 		end
+	
 	elseif hdr.type == tk_type["jnz"] then
 		if inst.details[1] == ASM_LABEL then
 			return 4 -- WE ASSUME ITS REAL MODE
 		else
 			perror("jnz only support labels for now")
 		end
+	elseif hdr.type == tk_type["cmp"] then
+		if inst.details[1] == ASM_R8 and inst.details[2] == ASM_IMM8 then
+			return 3
+		end
     end
     return 0
 end
@@ -629,6 +655,13 @@ while true do
 							writeu8(dst, eval.modrm)
 						end
 
+					elseif hdr.type == tk_type["inc"] then
+						if inst.details[1] == ASM_R8 then
+							local modrm = band(eval.modrm, bitval("0b11000111"))
+							
+							writeu8(dst, hexval("0hFE"))
+							writeu8(dst, modrm)
+						end
 					elseif hdr.type == tk_type["jz"] then
 						if inst.details[1] == ASM_LABEL then
 							local addr = symbol_table[inst.operands[1].raw]
@@ -657,6 +690,8 @@ while true do
 							writes16(dst, addr - coffset)
 						end
 
+					elseif hdr.type == tk_type["cmp"] then
+						writecmp(inst, eval)
 					end
 				end
 			end
blob - 2ee3f42b8994baab795f1a6eb8b6c764f0f9b890
blob + f99efa741ad5ace5d4e48cf07471a770ffdfe6cf
--- tools/util.lua
+++ tools/util.lua
@@ -2,7 +2,7 @@
 -- TOKEN MATCHING
 -----------------------------------------------------------------------
 local mnemonics = { "mov", "cli", "hlt", "ret", "sti", "int", "call", 
-	"jmp", "dec", "jz", "jnz" }
+	"jmp", "dec", "jz", "jnz", "cmp", "inc" }
 
 -- This is kinda a double definition but fix later :^)
 local arithmetics = { "+", "-", "*", "/", "^", "~", "|", "&" }
@@ -54,6 +54,7 @@ end
 local MAX_S16 = 2^15-1
 local MIN_S16 = -2^15
 local MAX_U16 = 2^16
+local MAX_U32 = 2^32
 
 -----------------------------------------------------------------------
 -- DEBUGING
@@ -215,7 +216,15 @@ local function writeu32(dst, value)
 	dst:write(string.char(b1, b2, b3, b4)) -- Little Endian x86
 end
 
+local function writes32(dst, value)
+	if value < 0 then
+		value = MAX_U32 + value
+	end
 
+	writeu32(dst, value)
+end
+
+
 local function intval(intstr)
 	local len = #intstr
 	local res = 0
@@ -398,6 +407,10 @@ ast.genast = function(expr)
 end
 
 ast.eval = function(node)
+	if tonumber(node) ~= nil then
+		return { tonumber(node) }
+	end
+
 	if node.data[1] == "number" then
 		return { tonumber(node.data[2]) or 0 }
 	end