Commit Diff


commit - d606d8179b1a8bf8fef0cadea6422d32dcba6e74
commit + 221a1b719280333b07e0739eeef1308433a758fe
blob - b6a9421f8eeb2eb8f2dfe3c277f80eb68fd460fa
blob + 98a6df92252d1ffb9d3d547479793d5adc94c6ca
--- tools/6c
+++ tools/6c
@@ -4,7 +4,7 @@
 -- TOKEN MATCHING
 -----------------------------------------------------------------------
 local mnemonics = { "mov", "cli", "hlt", "ret", "sti", "int", "call", 
-	"jmp" }
+	"jmp", "dec", "jz", "jnz" }
 
 -- This is kinda a double definition but fix later :^)
 local arithmetics = { "+", "-", "*", "/", "^", "~", "|", "&" }
blob - c9d1a7e6c036459bc69a9f9e4f5e04ff0279acdc
blob + 38f73f4bb1f280db4f59b2f47943154e35488a3d
--- tools/6l
+++ tools/6l
@@ -4,7 +4,7 @@
 -- TOKEN MATCHING
 -----------------------------------------------------------------------
 local mnemonics = { "mov", "cli", "hlt", "ret", "sti", "int", "call", 
-	"jmp" }
+	"jmp", "dec", "jz", "jnz" }
 
 -- This is kinda a double definition but fix later :^)
 local arithmetics = { "+", "-", "*", "/", "^", "~", "|", "&" }
@@ -766,6 +766,13 @@ local function instvaluate(inst)
 		return ret
 	elseif opcount == 1 then
 	-- amslyze caps it at 2
+		if inst.details[1] == ASM_R8 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
 		if inst.details[1] == ASM_R8 and inst.details[2] == ASM_R8 then
@@ -902,6 +909,22 @@ local function writecall(inst, curr)
 	end
 end
 
+local function writejmp(inst, curr)
+	local opcount = #inst.details
+
+	if opcount ~= 1 then
+		perror("jmp takes 1 operand " .. inst.operands[1].line)
+	end
+
+	-- AGAIN THIS IS ASSUMED TO BE REAL MODE
+	if inst.details[1] == ASM_LABEL then
+		local addr = symbol_table[inst.operands[1].raw]
+
+		writeu8(dst, hexval("0hE9"))
+		writes16(dst, addr - curr)
+	end
+end
+
 local function get_instruction_size(hdr, inst)
     if hdr.type == tk_type["mov"] then
 		local opcount = #inst.details
@@ -934,6 +957,20 @@ local function get_instruction_size(hdr, inst)
         return 2
     elseif hdr.type == tk_type["call"] or hdr.type == tk_type["jmp"] then
         return 3 -- WE ASSUME ITS REAL MODE!!!
+	elseif hdr.type == tk_type["dec"] 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
     end
     return 0
 end
@@ -1043,6 +1080,47 @@ while true do
 						end
 					elseif hdr.type == tk_type["call"] then
 						writecall(inst, coffset)
+
+					elseif hdr.type == tk_type["jmp"] then
+						writejmp(inst, coffset)
+
+					elseif hdr.type == tk_type["dec"] then
+						if inst.details[1] == ASM_R8 then
+							eval.modrm = band(eval.modrm, bitval("0b11000111"))
+							eval.modrm = bor(eval.modrm, bitval("0b00001000"))
+
+							writeu8(dst, hexval("0hFE"))
+							writeu8(dst, eval.modrm)
+						end
+
+					elseif hdr.type == tk_type["jz"] then
+						if inst.details[1] == ASM_LABEL then
+							local addr = symbol_table[inst.operands[1].raw]
+							if addr == nil then
+								perror("attempt to jz to unknown label " .. inst.operands[1].raw .. " line " .. hdr.line)
+							end
+
+							-- WE ASSUME THIS IS REAL MODE
+							writeu8(dst, hexval("0h0F"))
+							writeu8(dst, hexval("0h84"))
+							writes16(dst, addr - coffset)
+						else
+							perror("Unssuported jz target at line " .. hdr.line)
+						end
+
+					elseif hdr.type == tk_type["jnz"] then
+						if inst.details[1] == ASM_LABEL then
+							local addr = symbol_table[inst.operands[1].raw]
+							if addr == nil then
+								perror("attempt to jnz to unknown label " .. inst.operands[1].raw .. " line " .. hdr.line)
+							end
+
+							-- WE ASSUME ITS REAL MODE
+							writeu8(dst, hexval("0h0F"))
+							writeu8(dst, hexval("0h85"))
+							writes16(dst, addr - coffset)
+						end
+
 					end
 				end
 			end
blob - 61f5a27365fe483db3abdbe669340a81ceff5a26
blob + 4d889701ee2fbcdd8d607ff6366016bcbe0da108
--- tools/boot.sc
+++ tools/boot.sc
@@ -1,16 +1,18 @@
 asm {
 _start:
+	mov bl, 0hff
+	jmp inter
+print:
 	mov ah, 0h0e
 	mov al, 0h61
 	int 0h10
-	call me
+	ret
+inter:
+	call print
+	dec bl
+	jz end
+	jnz inter
+end:
 	mov [ 0h100 + 300], bl
 	hlt
-
-me:
-	mov ah, 0h0e
-	mov al, 0h61
-	int 0h10
-	call me
-	ret
 }
blob - 2d754aaa964d81a62e0d9e71a668132a4d7c59fe
blob + 4b79652e60434d0c33b5a3c10731898ff2e848f0
--- tools/linker.lua
+++ tools/linker.lua
@@ -302,6 +302,13 @@ local function instvaluate(inst)
 		return ret
 	elseif opcount == 1 then
 	-- amslyze caps it at 2
+		if inst.details[1] == ASM_R8 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
 		if inst.details[1] == ASM_R8 and inst.details[2] == ASM_R8 then
@@ -438,6 +445,22 @@ local function writecall(inst, curr)
 	end
 end
 
+local function writejmp(inst, curr)
+	local opcount = #inst.details
+
+	if opcount ~= 1 then
+		perror("jmp takes 1 operand " .. inst.operands[1].line)
+	end
+
+	-- AGAIN THIS IS ASSUMED TO BE REAL MODE
+	if inst.details[1] == ASM_LABEL then
+		local addr = symbol_table[inst.operands[1].raw]
+
+		writeu8(dst, hexval("0hE9"))
+		writes16(dst, addr - curr)
+	end
+end
+
 local function get_instruction_size(hdr, inst)
     if hdr.type == tk_type["mov"] then
 		local opcount = #inst.details
@@ -470,6 +493,20 @@ local function get_instruction_size(hdr, inst)
         return 2
     elseif hdr.type == tk_type["call"] or hdr.type == tk_type["jmp"] then
         return 3 -- WE ASSUME ITS REAL MODE!!!
+	elseif hdr.type == tk_type["dec"] 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
     end
     return 0
 end
@@ -579,6 +616,47 @@ while true do
 						end
 					elseif hdr.type == tk_type["call"] then
 						writecall(inst, coffset)
+
+					elseif hdr.type == tk_type["jmp"] then
+						writejmp(inst, coffset)
+
+					elseif hdr.type == tk_type["dec"] then
+						if inst.details[1] == ASM_R8 then
+							eval.modrm = band(eval.modrm, bitval("0b11000111"))
+							eval.modrm = bor(eval.modrm, bitval("0b00001000"))
+
+							writeu8(dst, hexval("0hFE"))
+							writeu8(dst, eval.modrm)
+						end
+
+					elseif hdr.type == tk_type["jz"] then
+						if inst.details[1] == ASM_LABEL then
+							local addr = symbol_table[inst.operands[1].raw]
+							if addr == nil then
+								perror("attempt to jz to unknown label " .. inst.operands[1].raw .. " line " .. hdr.line)
+							end
+
+							-- WE ASSUME THIS IS REAL MODE
+							writeu8(dst, hexval("0h0F"))
+							writeu8(dst, hexval("0h84"))
+							writes16(dst, addr - coffset)
+						else
+							perror("Unssuported jz target at line " .. hdr.line)
+						end
+
+					elseif hdr.type == tk_type["jnz"] then
+						if inst.details[1] == ASM_LABEL then
+							local addr = symbol_table[inst.operands[1].raw]
+							if addr == nil then
+								perror("attempt to jnz to unknown label " .. inst.operands[1].raw .. " line " .. hdr.line)
+							end
+
+							-- WE ASSUME ITS REAL MODE
+							writeu8(dst, hexval("0h0F"))
+							writeu8(dst, hexval("0h85"))
+							writes16(dst, addr - coffset)
+						end
+
 					end
 				end
 			end
blob - 73f2e4afc8a778a98f22a8aa3b4715360afdcf66
blob + 2ee3f42b8994baab795f1a6eb8b6c764f0f9b890
--- tools/util.lua
+++ tools/util.lua
@@ -2,7 +2,7 @@
 -- TOKEN MATCHING
 -----------------------------------------------------------------------
 local mnemonics = { "mov", "cli", "hlt", "ret", "sti", "int", "call", 
-	"jmp" }
+	"jmp", "dec", "jz", "jnz" }
 
 -- This is kinda a double definition but fix later :^)
 local arithmetics = { "+", "-", "*", "/", "^", "~", "|", "&" }