commit - 0d8d680e5d37cebe6ad59eb5ddb386ed9198507e
commit + 2be87f778a56964007d4c5ccf7171fa000149f79
blob - c13e3c987375f4d827f999dae8a63de533fce3b5
blob + 771e0898b66bd3ce7b85cd60ab72614d746765e4
--- tools/6c
+++ tools/6c
-----------------------------------------------------------------------
local mnemonics = { "mov", "cli", "hlt", "ret", "sti" }
+-- This is kinda a double definition but fix later :^)
+local arithmetics = { "+", "-", "*", "/", "^", "~", "|", "&" }
+
local symbols = { ",", "[", "]", "(", ")", "{", "}", "*", "/", "-",
"+", "!", "~", "#", "?", ";", ":" }
local asmkwd = { "asm" }
+local tk_misc = { "hexadecimal", "integer", "id", "\n" }
+
local tk_type = { }
local count = 0
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
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
-----------------------------------------------------------------------
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
-----------------------------------------------------------------------
local mnemonics = { "mov", "cli", "hlt", "ret", "sti" }
+-- This is kinda a double definition but fix later :^)
+local arithmetics = { "+", "-", "*", "/", "^", "~", "|", "&" }
+
local symbols = { ",", "[", "]", "(", ")", "{", "}", "*", "/", "-",
"+", "!", "~", "#", "?", ";", ":" }
local asmkwd = { "asm" }
+local tk_misc = { "hexadecimal", "integer", "id", "\n" }
+
local tk_type = { }
local count = 0
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
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
-----------------------------------------------------------------------
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
--
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)
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)
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
type = ASM_INSTRUCTION,
opcount = 0,
details = { },
- operands = { }
+ operands = { },
+ memblock = {
+ regs = { },
+ dispsize = 0,
+ blevel = 0,
+ }
}
local op1 = readhdr()
end
end
+-- formats instruction to be ready for opcode generation
local function instvaluate(inst)
local regmap = {
["al"] = "000", ["ah"] = "100", ["bl"] = "011", ["bh"] = "111",
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
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)
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
asm {
_start:
- mov al, ah
- mov ah, 0hff
- ret
-main:
hlt
- cli
}
blob - 71f6edaaccf35a7ecad23def99747b4524d30cd9
blob + 73c6a396f089b292270ae57e9209b940ccaa8b91
--- tools/compiler.lua
+++ tools/compiler.lua
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
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
--
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)
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)
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
type = ASM_INSTRUCTION,
opcount = 0,
details = { },
- operands = { }
+ operands = { },
+ memblock = {
+ regs = { },
+ dispsize = 0,
+ blevel = 0,
+ }
}
local op1 = readhdr()
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
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)
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
-----------------------------------------------------------------------
local mnemonics = { "mov", "cli", "hlt", "ret", "sti" }
+-- This is kinda a double definition but fix later :^)
+local arithmetics = { "+", "-", "*", "/", "^", "~", "|", "&" }
+
local symbols = { ",", "[", "]", "(", ")", "{", "}", "*", "/", "-",
"+", "!", "~", "#", "?", ";", ":" }
local asmkwd = { "asm" }
+local tk_misc = { "hexadecimal", "integer", "id", "\n" }
+
local tk_type = { }
local count = 0
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
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
+#!/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()