commit - cc1b538ae080ea83a96421aa59d0fa35078f44a2
commit + 26477129cfe7ccef1bfb485f8ee107b557c9f9fa
blob - c115f66915a6581fd4af49849b22d0dcb8fdc0ea
blob + 382df3706cb70a0adeab9a245c2fadc3bfe38831
--- tools/6c
+++ tools/6c
-----------------------------------------------------------------------
-- TOKEN MATCHING
-----------------------------------------------------------------------
-local mnemonics = { "mov", "cli", "hlt", "ret", "sti", "int" }
+local mnemonics = { "mov", "cli", "hlt", "ret", "sti", "int", "call" }
-- This is kinda a double definition but fix later :^)
local arithmetics = { "+", "-", "*", "/", "^", "~", "|", "&" }
end
-----------------------------------------------------------------------
+-- CONSTANTS
+-----------------------------------------------------------------------
+local MAX_S16 = 2^16-1
+local MIN_S16 = -2^16
+
+-----------------------------------------------------------------------
-- DEBUGING
-----------------------------------------------------------------------
local function perror(msg)
local b2 = band(brshift(value, 8), 0xff)
local b1 = band(value, 0xff)
- dst:write(string.char(b2, b1)) -- Little Endian x86
+ dst:write(string.char(b1, b2)) -- Little Endian x86
end
local function writeu32(dst, value)
local b2 = band(brshift(value, 8), 0xff)
local b1 = band(value, 0xff)
- dst:write(string.char(b4, b3, b2, b1)) -- Little Endian x86
+ dst:write(string.char(b1, b2, b3, b4)) -- Little Endian x86
end
i = i + 1
end
end
+
return expr[1]
end
local con = 0
for _, term in ipairs(leftval) do
- table.insert(result, term)
+ if type(term) == "table" then
+ table.insert(result, term)
+ else
+ con = con + term
+ end
end
for _, term in ipairs(rightval) do
blob - 3ea7054e411f2f3630fcdc2c110483cf51399ce4
blob + 04a04989c870c5a0d8575f4f57bcc28f19e0bf48
--- tools/6l
+++ tools/6l
-----------------------------------------------------------------------
-- TOKEN MATCHING
-----------------------------------------------------------------------
-local mnemonics = { "mov", "cli", "hlt", "ret", "sti", "int" }
+local mnemonics = { "mov", "cli", "hlt", "ret", "sti", "int", "call" }
-- This is kinda a double definition but fix later :^)
local arithmetics = { "+", "-", "*", "/", "^", "~", "|", "&" }
end
-----------------------------------------------------------------------
+-- CONSTANTS
+-----------------------------------------------------------------------
+local MAX_S16 = 2^16-1
+local MIN_S16 = -2^16
+
+-----------------------------------------------------------------------
-- DEBUGING
-----------------------------------------------------------------------
local function perror(msg)
local b2 = band(brshift(value, 8), 0xff)
local b1 = band(value, 0xff)
- dst:write(string.char(b2, b1)) -- Little Endian x86
+ dst:write(string.char(b1, b2)) -- Little Endian x86
end
local function writeu32(dst, value)
local b2 = band(brshift(value, 8), 0xff)
local b1 = band(value, 0xff)
- dst:write(string.char(b4, b3, b2, b1)) -- Little Endian x86
+ dst:write(string.char(b1, b2, b3, b4)) -- Little Endian x86
end
i = i + 1
end
end
+
return expr[1]
end
local con = 0
for _, term in ipairs(leftval) do
- table.insert(result, term)
+ if type(term) == "table" then
+ table.insert(result, term)
+ else
+ con = con + term
+ end
end
for _, term in ipairs(rightval) do
local b = { string.byte((hdr), 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 len = b[12] + blshift(b[11], 8)
+ local line = b[1] + blshift(b[2], 8) + blshift(b[3], 16) + blshift(b[4], 24)
+ local col = b[5] + blshift(b[6], 8) + blshift(b[7], 16) + blshift(b[8], 24)
+ local type = b[9] + blshift(b[10], 8)
+ local len = b[11] + blshift(b[12], 8)
local raw = nil
if len > 0 then raw = src:read(len) end
local gen = ast.genast(expr)
local exp = ast.eval(gen)
- for _, v in ipairs(exp) do
- if type(v) == "table" then
- io.write("{")
- io.write(v[1])
- io.write(", ")
- io.write(v[2])
- io.write("} ")
- else
- io.write(tonumber(v))
- end
- end
-
- io.write("\n")
- io.write("\n")
-
- ret.memblock.expression = e
+ ret.memblock.expression = exp
table.insert(ret.details, ASM_MEM8)
ret.opcount = 1
elseif op.type == tk_type["\n"] then
ret.opcount = 0
+ elseif op.type == tk_type["id"] then
+ table.insert(ret.details, ASM_LABEL)
+ table.insert(ret.operands, op)
+ ret.opcount = 0
else
perror("unknown operand `" .. gettokenkey(op) .. "` at line " .. op.line)
end
regs = { },
dispsize = 0,
blevel = 0,
- expression = nil
- }
+ expression = { }
+ },
}
local op1 = readhdr()
local reg2 = nil
local dstmap = "000"
local srcmap = "000"
+ local displacement = 0
for i = 1, #inst.memblock.regs do
if reg1 == nil then
reg1 = inst.memblock.regs[i]
- elseif reg2 == nil then
- reg2 = inst.memblock.regs[i]
end
end
+ if reg1 ~= nil then dstmap = regmap[reg1] end
+ srcmap = regmap[gettokenkey(inst.operands[1])]
+
+ if reg2 ~= nil then
+ for i = 1,#inst.memblock.expression do
+ local entry = inst.memblock.expression[i]
+
+ if type(entry) == "table" and entry[1] == reg2 then
+ local scale = tonumber(entry[2])
+ if scale ~= 1 and scale ~= 2 and scale ~= 4 and scale ~= 8 then
+ perror("Scale for index register can be 1, 2, 4 or 8")
+ end
+
+ ret.sib = scale
+ break
+ end
+ end
+ end
+
+ for i = 1, #inst.memblock.expression do
+ local offset = tonumber(inst.memblock.expression[i])
+
+ if offset ~= nil then
+ displacement = offset
+
+ if reg1 == nil and reg2 == nil then
+ dstmap = "110"
+ end
+ break
+ end
+ end
+
+ if reg1 ~= nil or reg2 ~= nil then
+ if displacement > 127 or displacement < -128 then
+ perror("displacement is only allowed to between -128 and 127")
+ end
+ end
+
+ ret.modrm = bitval("0b" .. mod .. srcmap .. dstmap)
+
return ret
end
end
writeu8(dst, hexval("0hC6"))
writeu8(dst, eval.modrm)
writeu8(dst, ib)
+
+ elseif inst.details[1] == ASM_MEM8 and inst.details[2] == ASM_R8 then
+ if #inst.memblock.regs > 0 then
+ perror("illegal, registers are not allowed in memory access for now. Line " .. inst.operands[2].line)
+ else
+ local addr = inst.memblock.expression[1]
+ writeu8(dst, hexval("0h88"))
+ writeu8(dst, eval.modrm)
+
+ if addr <= 32767 then
+ writeu16(dst, addr)
+ else
+ writeu32(dst, addr)
+ end
+ end
end
end
+local function writecall(inst, curr)
+ local opcount = #inst.details
+ if opcount ~= 1 then
+ perror("call takes 1 operand " .. inst.operands[1].line)
+ end
+
+ -- ONCE AGAIN WE ASSUME THIS IS REAL MODE
+ if inst.details[1] == ASM_LABEL then
+ local addr = symbol_table[inst.operands[1].raw]
+ writeu8(dst, hexval("0hE8"))
+ writeu16(dst, addr - curr)
+ end
+end
+
+local function get_instruction_size(hdr, inst)
+ if hdr.type == tk_type["mov"] then
+ local size = 2
+ local eval = instvaluate(inst)
+ if eval.modrm ~= nil then size = size + 1 end
+
+ -- Check expression for memory constants
+ if inst.memblock and inst.memblock.expression then
+ for _, v in ipairs(inst.memblock.expression) do
+ local num = tonumber(v)
+ if num ~= nil then
+ if num <= MAX_S16 and num >= MIN_S16 then
+ size = size + 2
+ else
+ size = size + 4
+ end
+ end
+ end
+ end
+ return size + 1 -- Plus your trailing byte modifier
+
+ elseif hdr.type == tk_type["hlt"] or hdr.type == tk_type["ret"] or hdr.type == tk_type["cli"] then
+ return 1
+ elseif hdr.type == tk_type["int"] then
+ return 2
+ elseif hdr.type == tk_type["call"] or hdr.type == tk_type["jmp"] then
+ return 3 -- WE ASSUME ITS REAL MODE!!!
+ end
+ return 0
+end
+
-----------------------------------------------------------------------
-- 1st pass (syntax check and symbol table)
-----------------------------------------------------------------------
local inst = asmlyze(hdr)
if inst.type == ASM_INSTRUCTION then
- if hdr.type == tk_type["mov"] then
- -- mov r8, r8
- if inst.details[1] == ASM_R8 and inst.details[2] == ASM_R8 then
- offset = offset + 2
-
- -- mov r8, imm8
- 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)
- end
- end
+ offset = offset + get_instruction_size(hdr, inst)
-- Add symbol table
elseif inst.type == ASM_LABEL then
symbol_table[hdr.raw] = offset
parser.inasm = false
parser.insec = false
+local coffset = 0
+
while true do
local hdr = readhdr()
if hdr == nil then
local inst = asmlyze(hdr)
if inst.type == ASM_INSTRUCTION then
local eval = instvaluate(inst)
+ coffset = coffset + get_instruction_size(hdr, inst)
if eval == nil then
perror("unknown instruction at line " .. hdr.line)
elseif inst.operands[1].type == tk_type["integer"] then
writeu8(dst, intval(inst.operands[1].raw))
end
+ elseif hdr.type == tk_type["call"] then
+ writecall(inst, coffset)
end
end
end
blob - fb5ebec9b76df12de540c6dba0bef4bca2d5dc53
blob + b5e6dcbb21ab9e6ad6c2c3d81931e9250b2dd73d
--- tools/boot.sc
+++ tools/boot.sc
mov ah, 0h0e
mov al, 0h61
int 0h10
- mov [ ((al)) + (bl * 100) * 4 + 0h100 ], bl
+ call me
+ mov [ 0h100 + 300], bl
hlt
+
+me:
+ mov ah, 0h0e
+ mov al, 0h61
+ int 0h10
+ ret
}
blob - 8d86957439a3fd2605f9b14d39de96c8bc135663
blob + 0fdab57d6e3d4e1ff757a04a8e37754252a4ff66
--- tools/linker.lua
+++ tools/linker.lua
local b = { string.byte((hdr), 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 len = b[12] + blshift(b[11], 8)
+ local line = b[1] + blshift(b[2], 8) + blshift(b[3], 16) + blshift(b[4], 24)
+ local col = b[5] + blshift(b[6], 8) + blshift(b[7], 16) + blshift(b[8], 24)
+ local type = b[9] + blshift(b[10], 8)
+ local len = b[11] + blshift(b[12], 8)
local raw = nil
if len > 0 then raw = src:read(len) end
local gen = ast.genast(expr)
local exp = ast.eval(gen)
- for _, v in ipairs(exp) do
- if type(v) == "table" then
- io.write("{")
- io.write(v[1])
- io.write(", ")
- io.write(v[2])
- io.write("} ")
- else
- io.write(tonumber(v))
- end
- end
-
- io.write("\n")
- io.write("\n")
-
- ret.memblock.expression = e
+ ret.memblock.expression = exp
table.insert(ret.details, ASM_MEM8)
ret.opcount = 1
elseif op.type == tk_type["\n"] then
ret.opcount = 0
+ elseif op.type == tk_type["id"] then
+ table.insert(ret.details, ASM_LABEL)
+ table.insert(ret.operands, op)
+ ret.opcount = 0
else
perror("unknown operand `" .. gettokenkey(op) .. "` at line " .. op.line)
end
regs = { },
dispsize = 0,
blevel = 0,
- expression = nil
- }
+ expression = { }
+ },
}
local op1 = readhdr()
local reg2 = nil
local dstmap = "000"
local srcmap = "000"
+ local displacement = 0
for i = 1, #inst.memblock.regs do
if reg1 == nil then
reg1 = inst.memblock.regs[i]
- elseif reg2 == nil then
- reg2 = inst.memblock.regs[i]
end
end
+ if reg1 ~= nil then dstmap = regmap[reg1] end
+ srcmap = regmap[gettokenkey(inst.operands[1])]
+
+ if reg2 ~= nil then
+ for i = 1,#inst.memblock.expression do
+ local entry = inst.memblock.expression[i]
+
+ if type(entry) == "table" and entry[1] == reg2 then
+ local scale = tonumber(entry[2])
+ if scale ~= 1 and scale ~= 2 and scale ~= 4 and scale ~= 8 then
+ perror("Scale for index register can be 1, 2, 4 or 8")
+ end
+
+ ret.sib = scale
+ break
+ end
+ end
+ end
+
+ for i = 1, #inst.memblock.expression do
+ local offset = tonumber(inst.memblock.expression[i])
+
+ if offset ~= nil then
+ displacement = offset
+
+ if reg1 == nil and reg2 == nil then
+ dstmap = "110"
+ end
+ break
+ end
+ end
+
+ if reg1 ~= nil or reg2 ~= nil then
+ if displacement > 127 or displacement < -128 then
+ perror("displacement is only allowed to between -128 and 127")
+ end
+ end
+
+ ret.modrm = bitval("0b" .. mod .. srcmap .. dstmap)
+
return ret
end
end
writeu8(dst, hexval("0hC6"))
writeu8(dst, eval.modrm)
writeu8(dst, ib)
+
+ elseif inst.details[1] == ASM_MEM8 and inst.details[2] == ASM_R8 then
+ if #inst.memblock.regs > 0 then
+ perror("illegal, registers are not allowed in memory access for now. Line " .. inst.operands[2].line)
+ else
+ local addr = inst.memblock.expression[1]
+ writeu8(dst, hexval("0h88"))
+ writeu8(dst, eval.modrm)
+
+ if addr <= 32767 then
+ writeu16(dst, addr)
+ else
+ writeu32(dst, addr)
+ end
+ end
end
end
+local function writecall(inst, curr)
+ local opcount = #inst.details
+ if opcount ~= 1 then
+ perror("call takes 1 operand " .. inst.operands[1].line)
+ end
+
+ -- ONCE AGAIN WE ASSUME THIS IS REAL MODE
+ if inst.details[1] == ASM_LABEL then
+ local addr = symbol_table[inst.operands[1].raw]
+ writeu8(dst, hexval("0hE8"))
+ writeu16(dst, addr - curr)
+ end
+end
+
+local function get_instruction_size(hdr, inst)
+ if hdr.type == tk_type["mov"] then
+ local size = 2
+ local eval = instvaluate(inst)
+ if eval.modrm ~= nil then size = size + 1 end
+
+ -- Check expression for memory constants
+ if inst.memblock and inst.memblock.expression then
+ for _, v in ipairs(inst.memblock.expression) do
+ local num = tonumber(v)
+ if num ~= nil then
+ if num <= MAX_S16 and num >= MIN_S16 then
+ size = size + 2
+ else
+ size = size + 4
+ end
+ end
+ end
+ end
+ return size + 1 -- Plus your trailing byte modifier
+
+ elseif hdr.type == tk_type["hlt"] or hdr.type == tk_type["ret"] or hdr.type == tk_type["cli"] then
+ return 1
+ elseif hdr.type == tk_type["int"] then
+ return 2
+ elseif hdr.type == tk_type["call"] or hdr.type == tk_type["jmp"] then
+ return 3 -- WE ASSUME ITS REAL MODE!!!
+ end
+ return 0
+end
+
-----------------------------------------------------------------------
-- 1st pass (syntax check and symbol table)
-----------------------------------------------------------------------
local inst = asmlyze(hdr)
if inst.type == ASM_INSTRUCTION then
- if hdr.type == tk_type["mov"] then
- -- mov r8, r8
- if inst.details[1] == ASM_R8 and inst.details[2] == ASM_R8 then
- offset = offset + 2
-
- -- mov r8, imm8
- 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)
- end
- end
+ offset = offset + get_instruction_size(hdr, inst)
-- Add symbol table
elseif inst.type == ASM_LABEL then
symbol_table[hdr.raw] = offset
parser.inasm = false
parser.insec = false
+local coffset = 0
+
while true do
local hdr = readhdr()
if hdr == nil then
local inst = asmlyze(hdr)
if inst.type == ASM_INSTRUCTION then
local eval = instvaluate(inst)
+ coffset = coffset + get_instruction_size(hdr, inst)
if eval == nil then
perror("unknown instruction at line " .. hdr.line)
elseif inst.operands[1].type == tk_type["integer"] then
writeu8(dst, intval(inst.operands[1].raw))
end
+ elseif hdr.type == tk_type["call"] then
+ writecall(inst, coffset)
end
end
end
blob - 118b7570602f441e01aed443d89312149213e293
blob + 8c0a97bff15a71cc55d2ef7d551a6fd5d1aa633a
--- tools/util.lua
+++ tools/util.lua
-----------------------------------------------------------------------
-- TOKEN MATCHING
-----------------------------------------------------------------------
-local mnemonics = { "mov", "cli", "hlt", "ret", "sti", "int" }
+local mnemonics = { "mov", "cli", "hlt", "ret", "sti", "int", "call" }
-- This is kinda a double definition but fix later :^)
local arithmetics = { "+", "-", "*", "/", "^", "~", "|", "&" }
end
-----------------------------------------------------------------------
+-- CONSTANTS
+-----------------------------------------------------------------------
+local MAX_S16 = 2^16-1
+local MIN_S16 = -2^16
+
+-----------------------------------------------------------------------
-- DEBUGING
-----------------------------------------------------------------------
local function perror(msg)
local b2 = band(brshift(value, 8), 0xff)
local b1 = band(value, 0xff)
- dst:write(string.char(b2, b1)) -- Little Endian x86
+ dst:write(string.char(b1, b2)) -- Little Endian x86
end
local function writeu32(dst, value)
local b2 = band(brshift(value, 8), 0xff)
local b1 = band(value, 0xff)
- dst:write(string.char(b4, b3, b2, b1)) -- Little Endian x86
+ dst:write(string.char(b1, b2, b3, b4)) -- Little Endian x86
end
i = i + 1
end
end
+
return expr[1]
end
local con = 0
for _, term in ipairs(leftval) do
- table.insert(result, term)
+ if type(term) == "table" then
+ table.insert(result, term)
+ else
+ con = con + term
+ end
end
for _, term in ipairs(rightval) do
blob - /dev/null
blob + 77dcb7dfc5944eca9f8a0559f1f72c0e8a9c0f4f (mode 755)
--- /dev/null
+++ tools/mkmbr
+#!/bin/ksh
+
+set -e
+
+./6c boot.sc && ./6l boot.6 && ./mbrsign 6.boot