commit b868c2b1a57866d362bdf3ddd17a0149e7c25376 from: Onana Onana Xavier Manuel date: Mon Sep 28 18:54:20 2026 UTC Added mov r16, imm16 for a hello world program :) commit - fc369242fc4d8d26841940659c9e6ef95d995ad1 commit + b868c2b1a57866d362bdf3ddd17a0149e7c25376 blob - d007f719884f24c68f2545876792f134cddededd blob + 122b1b9ebeb3a1c5eb4a9674994f5205cad28359 --- tools/6c +++ tools/6c @@ -14,12 +14,14 @@ local symbols = { ",", "[", "]", "(", ")", "{", "}", " local regs8 = { "al", "ah", "bl", "bh", "cl", "ch", "dl", "dh" } -local regs16 = { "ax", "bx", "cx", "dx" } +local regs16 = { "ax", "bx", "cx", "dx", "si", "di", "bp", "sp" } local ptr16 = { "si", "di", "bp", "sp" } -local asmkwd = { "asm" } +local asmkwd = { "asm", "org" } +local regs = { } + local ckwd = { "u8" } local tk_misc = { "hexadecimal", "integer", "id", "string", "\n" } @@ -32,6 +34,10 @@ for i = 1, #mnemonics do tk_type[mnemonics[i]] = count end +for i = 1, #regs8 do table.insert(regs, regs8[i]) end + +for i = 1, #regs16 do table.insert(regs, regs16[i]) end + for i = 1, #symbols do count = count + 1 tk_type[symbols[i]] = count @@ -146,6 +152,38 @@ local function isregs8(m) return false end +local function isregs16(m) + local key = gettokenkey(m) + + if key == nil then + return false + end + + for i, v in ipairs(regs16) do + if v == key then + return true + end + end + + return false +end + +local function isregs(m) + local key = gettokenkey(m) + + if key == nil then + return false + end + + for i, v in ipairs(regs) do + if v == key then + return true + end + end + + return false +end + local function isarithmetic(a) local key = gettokenkey(a) @@ -435,6 +473,10 @@ ast.eval = function(node) return { tonumber(node) } end + if type(node) == "string" then + return { { node, 1 } } + end + if node.data[1] == "number" then return { tonumber(node.data[2]) or 0 } end @@ -502,6 +544,35 @@ end ----------------------------------------------------------------------- progname = "6c" +local offset = nil +local i = 0 + +while i < #arg do + if arg[i] == "-org" and offset == nil then + local value = arg[i + 1] + if value == nil then + perror("-org flag requires a position") + end + + if tonumber(value) ~= nil then + perror("-org requires a hexadecimal value") + end + + if value:sub(1, 1) ~= "0" and value:sub(2, 2) ~= "h" then + perror("ORG needs hexval") + end + offset = value + + table.remove(arg, i + 1) + table.remove(arg, i) + end + i = i + 1 +end + +if offset == nil then + offset = "0h00" +end + local input = arg[1] local output = arg[2] @@ -618,6 +689,8 @@ end -- Tokenizing ----------------------------------------------------------------------- +emittoken(0, 0, tk_type["org"], #offset, offset) +emittoken(0, 0, tk_type["\n"], 0, 0) local nline = 1 while true do local line = src:read("*l") @@ -665,7 +738,7 @@ while true do end if tk_type[id] == nil then - emittoken(nline, ncol, tk_type.id, #id, id) + emittoken(nline, ncol, tk_type["id"], #id, id) else emittoken(nline, ncol, tk_type[id], 0, nil) end blob - 75d71488a3c955c3dd92adac692d57c728bd373b blob + 76a16a010b7c58eefacaa8c4d2aeef9ff4772101 --- tools/6l +++ tools/6l @@ -14,12 +14,14 @@ local symbols = { ",", "[", "]", "(", ")", "{", "}", " local regs8 = { "al", "ah", "bl", "bh", "cl", "ch", "dl", "dh" } -local regs16 = { "ax", "bx", "cx", "dx" } +local regs16 = { "ax", "bx", "cx", "dx", "si", "di", "bp", "sp" } local ptr16 = { "si", "di", "bp", "sp" } -local asmkwd = { "asm" } +local asmkwd = { "asm", "org" } +local regs = { } + local ckwd = { "u8" } local tk_misc = { "hexadecimal", "integer", "id", "string", "\n" } @@ -32,6 +34,10 @@ for i = 1, #mnemonics do tk_type[mnemonics[i]] = count end +for i = 1, #regs8 do table.insert(regs, regs8[i]) end + +for i = 1, #regs16 do table.insert(regs, regs16[i]) end + for i = 1, #symbols do count = count + 1 tk_type[symbols[i]] = count @@ -146,6 +152,38 @@ local function isregs8(m) return false end +local function isregs16(m) + local key = gettokenkey(m) + + if key == nil then + return false + end + + for i, v in ipairs(regs16) do + if v == key then + return true + end + end + + return false +end + +local function isregs(m) + local key = gettokenkey(m) + + if key == nil then + return false + end + + for i, v in ipairs(regs) do + if v == key then + return true + end + end + + return false +end + local function isarithmetic(a) local key = gettokenkey(a) @@ -435,6 +473,10 @@ ast.eval = function(node) return { tonumber(node) } end + if type(node) == "string" then + return { { node, 1 } } + end + if node.data[1] == "number" then return { tonumber(node.data[2]) or 0 } end @@ -505,6 +547,7 @@ local input = arg[1] local output = arg[2] local symbol_table = { } +local csymbols = { } local offset = 0 local parser = { inasm = false, -- In Assembly @@ -583,12 +626,19 @@ local ASM_INSTRUCTION = 2 local ASM_R8 = 3 local ASM_IMM8 = 4 local ASM_MEM8 = 5 +local ASM_R16 = 6 local function operlyze(op, ret) if isregs8(op) == true then ret.opcount = 1 table.insert(ret.details, ASM_R8) table.insert(ret.operands, op) + + elseif isregs16(op) == true then + ret.opcount = 1 + table.insert(ret.details, ASM_R16) + table.insert(ret.operands, op) + elseif op.type == tk_type["integer"] then ret.opcount = 1 local val = intval(op.raw) @@ -632,7 +682,7 @@ local function operlyze(op, ret) perror("illegal nested operand at line " .. op.line) end - if isregs8(op) == true then + if isregs(op) == true then if typematch(pre, { "[", "(", arithmetics }) == false then perror("missing arithmetic prefix for register " .. gettokenkey(op) .. " line " .. op.line) @@ -662,25 +712,25 @@ local function operlyze(op, ret) -- Other arithmetic symbols elseif isarithmetic(op) == true then - if typematch(pre, { regs8, "hexadecimal", "integer", ")" }) == false then + if typematch(pre, { regs, "hexadecimal", "integer", ")" }) == false then perror("illegal token before " .. gettokenkey(op) .. " at line " .. op.line) end - if #ret.memblock.regs == 1 and typematch(pre, { regs8 }) == true and typematch(op, { "+", "-" } ) == false then + if #ret.memblock.regs == 1 and typematch(pre, { regs }) == true and typematch(op, { "+", "-" } ) == false then perror("Base register `" .. gettokenkey(pre) .. "` can only be applied + or - on it line " .. op.line) end table.insert(expr, gettokenkey(op)) elseif op.type == tk_type["("] then - if typematch(pre, { regs8, arithmetics, "(", "[" , "hexadecimal", "integer" }) == false then + if typematch(pre, { regs, arithmetics, "(", "[" , "hexadecimal", "integer" }) == false then perror("illegal token befor `(` at line " .. op.line) end table.insert(expr, "(") depth = depth + 1 elseif op.type == tk_type[")"] then - if typematch(pre, { regs8, "hexadecimal", ")", "integer" }) == false then + if typematch(pre, { regs, "hexadecimal", ")", "integer" }) == false then perror("illegal token before `)` at line " .. op.line) end @@ -788,7 +838,8 @@ end local function instvaluate(inst) local regmap = { ["al"] = "000", ["ah"] = "100", ["bl"] = "011", ["bh"] = "111", - ["cl"] = "001", ["ch"] = "101", ["dl"] = "010", ["dh"] = "110" + ["cl"] = "001", ["ch"] = "101", ["dl"] = "010", ["dh"] = "110", + ["si"] = "110", } local ret = { @@ -808,6 +859,12 @@ local function instvaluate(inst) local rm = regmap[gettokenkey(inst.operands[1])] ret.modrm = bitval("0b" .. mod .. reg .. rm) + elseif inst.details[1] == ASM_R16 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 @@ -827,7 +884,7 @@ local function instvaluate(inst) -- 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 + elseif (inst.details[1] == ASM_MEM8 and inst.details[2] == ASM_R8) or (inst.details[1] == ASM_R8 and inst.details[2] == ASM_MEM8) then local mod = "00" local reg1 = nil @@ -842,8 +899,14 @@ local function instvaluate(inst) end end - if reg1 ~= nil then dstmap = regmap[reg1] end - srcmap = regmap[gettokenkey(inst.operands[1])] + if inst.details[1] == ASM_MEM8 then + if reg1 ~= nil then dstmap = regmap[reg1] end + srcmap = regmap[gettokenkey(inst.operands[1])] + else + if reg1 ~= nil then srcmap = regmap[reg1] end + local k = gettokenkey(inst.operands[1]) + srcmap = regmap[k] + end if reg2 ~= nil then for i = 1,#inst.memblock.expression do @@ -868,9 +931,19 @@ local function instvaluate(inst) displacement = offset if reg1 == nil and reg2 == nil then - dstmap = "110" + if inst.details[1] == ASM_MEM8 then + dstmap = "110" + else + srcmap = "110" + end end break + else + reg = inst.memblock.expression[i][1] + + if reg == "si" and inst.details[2] == ASM_MEM8 and mod == "00" then + dstmap = "100" + end end end @@ -883,6 +956,14 @@ local function instvaluate(inst) ret.modrm = bitval("0b" .. mod .. srcmap .. dstmap) return ret + + elseif inst.details[1] == ASM_R16 and inst.details[2] == ASM_LABEL then + local srcmap = "000" + local dstmap = regmap[gettokenkey(inst.operands[1])] + local mod = "00" + + ret.modrm = bitval("0b" .. srcmap .. dstmap) + return ret end end @@ -927,6 +1008,35 @@ local function writemov(inst, eval) writeu32(dst, addr) end end + + elseif inst.details[1] == ASM_R8 and inst.details[2] == ASM_MEM8 then + if #inst.memblock.regs > 0 then + local disp = 0 + + for i = 1,#inst.memblock.expression do + if type(inst.memblock.expression[i]) == "string" then + disp = tonumber(inst.memblock.expression[i]) + print(disp) + end + end + + writeu8(dst, hexval("0h8A")) + writeu8(dst, eval.modrm) + + if disp ~= 0 then + writeu8(dst, disp) -- ASSUMING its signed integer + end + else + perror("required register at line " .. inst.operands[1].line) + end + + elseif inst.details[1] == ASM_R16 and inst.details[2] == ASM_LABEL then + if csymbols[inst.operands[2].raw] ~= nil then + local rw = band(eval.modrm, bitval("0b111")) + + writeu8(dst, hexval("0hB8") + rw) + writeu16(dst, csymbols[inst.operands[2].raw]) + end end end @@ -984,7 +1094,8 @@ local function get_instruction_size(hdr, inst) if (inst.details[1] == ASM_R8 or inst.details[1] == ASM_IMM8) and (inst.details[2] == ASM_R8 or inst.details[2] == ASM_IMM8) then return 3 - elseif inst.details[1] == ASM_MEM8 and inst.details[2] == ASM_R8 then + + elseif (inst.details[1] == ASM_MEM8 and inst.details[2] == ASM_R8) or (inst.details[1] == ASM_R8 and inst.details[2] == ASM_MEM8) then local size = 2 if inst.memblock and inst.memblock.expression then for _, v in ipairs(inst.memblock.expression) do @@ -1000,6 +1111,8 @@ local function get_instruction_size(hdr, inst) end return size + elseif inst.details[1] == ASM_R16 and inst.details[2] == ASM_LABEL then + return 3 end elseif hdr.type == tk_type["hlt"] or hdr.type == tk_type["ret"] or hdr.type == tk_type["cli"] then @@ -1016,6 +1129,8 @@ local function get_instruction_size(hdr, inst) elseif hdr.type == tk_type["inc"] then if inst.details[1] == ASM_R8 then return 2 + elseif inst.details[1] == ASM_R16 then + return 2 end elseif hdr.type == tk_type["jz"] then @@ -1050,6 +1165,7 @@ while true do if parser.inasm == true then if hdr.type == tk_type["asm"] then perror("illegal nested asm keyword at line " .. hdr.line .. " column " .. hdr.col) + elseif hdr.type == tk_type["}"] then parser.inasm = false else @@ -1099,6 +1215,9 @@ while true do end end + elseif hdr.type == tk_type["org"] then + offset = hexval(hdr.raw) + elseif hdr.type == tk_type["u8"] then local n = readhdr() @@ -1119,6 +1238,7 @@ while true do if data.type ~= tk_type["string"] then perror("missing string next to " .. name.raw .. " at line " .. hdr.line) + csymbol[name.raw] = offset end local semi = readhdr() @@ -1154,6 +1274,7 @@ while true do perror("illegal nested asm keyword at line " .. hdr.line .. " column " .. hdr.col) elseif hdr.type == tk_type["}"] then parser.inasm = false + else if hdr.type ~= tk_type["\n"] then local inst = asmlyze(hdr) @@ -1216,6 +1337,11 @@ while true do writeu8(dst, hexval("0hFE")) writeu8(dst, modrm) + elseif inst.details[1] == ASM_R16 then + local modrm = band(eval.modrm, bitval("0b11000111")) + + writeu8(dst, hexval("0hFF")) + writeu8(dst, modrm) end elseif hdr.type == tk_type["jz"] then if inst.details[1] == ASM_LABEL then @@ -1256,6 +1382,9 @@ while true do parser.inasm = true readhdr() -- Skip `{` + elseif hdr.type == tk_type["org"] then + coffset = hexval(hdr.raw) + elseif hdr.type == tk_type["u8"] then local n = readhdr() @@ -1273,6 +1402,7 @@ while true do end writeu8(dst, 0) + csymbols[name.raw] = coffset coffset = coffset + #data + 1 readhdr() end blob - 39c2bc0e58de7275b4ad92debad6d562d422a564 blob + 5e3a7fcec05873e85d3ab8c33f58ca2f2e582794 --- tools/boot.sc +++ tools/boot.sc @@ -1,50 +1,37 @@ -/* - * boot.sc - * - * Just a simple test to see if comments work in the source file - * as well as the assembly blocks. The assembly blocks can - * call sections between each other without being in the same - * block. - * - * The next step is to also support things like db, dd, dw and dq. - * This will allow things like moving string into registers. - */ +struct DAP { + u8 size; + u8 rsvd; + u16 sectors; + u16 destination; + u16 segment; + u64 blockNum; +}; /* SKIP BLOCK */ asm { -entry: +skip: jmp start } u8 *msg = "Hello World"; asm { -start: - mov bl, 0hff - jmp inter print: mov ah, 0h0e - mov al, 0h61 +print_loop: + mov al, [si] + cmp al, 0h00 + jz print_done int 0h10 + inc si + jmp print_loop +print_done: ret -inter: - call print - dec bl - jnz inter } asm { - mov cl, 0 +start: + mov si, msg call print -second: - mov ah, 0h0e - mov al, 0h41 - int 0h10 - inc cl - cmp cl, 33 - jz end - jmp second -end: - mov [ 0h30 ], bl hlt } blob - 862da8cc04649469c596765516f807dd1ec01c3b blob + c5b28468b952e9bd0d31772102a2f19a64d1b323 --- tools/compiler.lua +++ tools/compiler.lua @@ -3,6 +3,35 @@ ----------------------------------------------------------------------- progname = "6c" +local offset = nil +local i = 0 + +while i < #arg do + if arg[i] == "-org" and offset == nil then + local value = arg[i + 1] + if value == nil then + perror("-org flag requires a position") + end + + if tonumber(value) ~= nil then + perror("-org requires a hexadecimal value") + end + + if value:sub(1, 1) ~= "0" and value:sub(2, 2) ~= "h" then + perror("ORG needs hexval") + end + offset = value + + table.remove(arg, i + 1) + table.remove(arg, i) + end + i = i + 1 +end + +if offset == nil then + offset = "0h00" +end + local input = arg[1] local output = arg[2] @@ -119,6 +148,8 @@ end -- Tokenizing ----------------------------------------------------------------------- +emittoken(0, 0, tk_type["org"], #offset, offset) +emittoken(0, 0, tk_type["\n"], 0, 0) local nline = 1 while true do local line = src:read("*l") @@ -166,7 +197,7 @@ while true do end if tk_type[id] == nil then - emittoken(nline, ncol, tk_type.id, #id, id) + emittoken(nline, ncol, tk_type["id"], #id, id) else emittoken(nline, ncol, tk_type[id], 0, nil) end blob - 08acb106c046ffe78b27b2a9314e57629653da97 blob + e4e5942926051ed1f8dcc303fbc44d5d16d7639c --- tools/linker.lua +++ tools/linker.lua @@ -6,6 +6,7 @@ local input = arg[1] local output = arg[2] local symbol_table = { } +local csymbols = { } local offset = 0 local parser = { inasm = false, -- In Assembly @@ -84,12 +85,19 @@ local ASM_INSTRUCTION = 2 local ASM_R8 = 3 local ASM_IMM8 = 4 local ASM_MEM8 = 5 +local ASM_R16 = 6 local function operlyze(op, ret) if isregs8(op) == true then ret.opcount = 1 table.insert(ret.details, ASM_R8) table.insert(ret.operands, op) + + elseif isregs16(op) == true then + ret.opcount = 1 + table.insert(ret.details, ASM_R16) + table.insert(ret.operands, op) + elseif op.type == tk_type["integer"] then ret.opcount = 1 local val = intval(op.raw) @@ -133,7 +141,7 @@ local function operlyze(op, ret) perror("illegal nested operand at line " .. op.line) end - if isregs8(op) == true then + if isregs(op) == true then if typematch(pre, { "[", "(", arithmetics }) == false then perror("missing arithmetic prefix for register " .. gettokenkey(op) .. " line " .. op.line) @@ -163,25 +171,25 @@ local function operlyze(op, ret) -- Other arithmetic symbols elseif isarithmetic(op) == true then - if typematch(pre, { regs8, "hexadecimal", "integer", ")" }) == false then + if typematch(pre, { regs, "hexadecimal", "integer", ")" }) == false then perror("illegal token before " .. gettokenkey(op) .. " at line " .. op.line) end - if #ret.memblock.regs == 1 and typematch(pre, { regs8 }) == true and typematch(op, { "+", "-" } ) == false then + if #ret.memblock.regs == 1 and typematch(pre, { regs }) == true and typematch(op, { "+", "-" } ) == false then perror("Base register `" .. gettokenkey(pre) .. "` can only be applied + or - on it line " .. op.line) end table.insert(expr, gettokenkey(op)) elseif op.type == tk_type["("] then - if typematch(pre, { regs8, arithmetics, "(", "[" , "hexadecimal", "integer" }) == false then + if typematch(pre, { regs, arithmetics, "(", "[" , "hexadecimal", "integer" }) == false then perror("illegal token befor `(` at line " .. op.line) end table.insert(expr, "(") depth = depth + 1 elseif op.type == tk_type[")"] then - if typematch(pre, { regs8, "hexadecimal", ")", "integer" }) == false then + if typematch(pre, { regs, "hexadecimal", ")", "integer" }) == false then perror("illegal token before `)` at line " .. op.line) end @@ -289,7 +297,8 @@ end local function instvaluate(inst) local regmap = { ["al"] = "000", ["ah"] = "100", ["bl"] = "011", ["bh"] = "111", - ["cl"] = "001", ["ch"] = "101", ["dl"] = "010", ["dh"] = "110" + ["cl"] = "001", ["ch"] = "101", ["dl"] = "010", ["dh"] = "110", + ["si"] = "110", } local ret = { @@ -309,6 +318,12 @@ local function instvaluate(inst) local rm = regmap[gettokenkey(inst.operands[1])] ret.modrm = bitval("0b" .. mod .. reg .. rm) + elseif inst.details[1] == ASM_R16 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 @@ -328,7 +343,7 @@ local function instvaluate(inst) -- 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 + elseif (inst.details[1] == ASM_MEM8 and inst.details[2] == ASM_R8) or (inst.details[1] == ASM_R8 and inst.details[2] == ASM_MEM8) then local mod = "00" local reg1 = nil @@ -343,8 +358,14 @@ local function instvaluate(inst) end end - if reg1 ~= nil then dstmap = regmap[reg1] end - srcmap = regmap[gettokenkey(inst.operands[1])] + if inst.details[1] == ASM_MEM8 then + if reg1 ~= nil then dstmap = regmap[reg1] end + srcmap = regmap[gettokenkey(inst.operands[1])] + else + if reg1 ~= nil then srcmap = regmap[reg1] end + local k = gettokenkey(inst.operands[1]) + srcmap = regmap[k] + end if reg2 ~= nil then for i = 1,#inst.memblock.expression do @@ -369,9 +390,19 @@ local function instvaluate(inst) displacement = offset if reg1 == nil and reg2 == nil then - dstmap = "110" + if inst.details[1] == ASM_MEM8 then + dstmap = "110" + else + srcmap = "110" + end end break + else + reg = inst.memblock.expression[i][1] + + if reg == "si" and inst.details[2] == ASM_MEM8 and mod == "00" then + dstmap = "100" + end end end @@ -384,6 +415,14 @@ local function instvaluate(inst) ret.modrm = bitval("0b" .. mod .. srcmap .. dstmap) return ret + + elseif inst.details[1] == ASM_R16 and inst.details[2] == ASM_LABEL then + local srcmap = "000" + local dstmap = regmap[gettokenkey(inst.operands[1])] + local mod = "00" + + ret.modrm = bitval("0b" .. srcmap .. dstmap) + return ret end end @@ -428,6 +467,35 @@ local function writemov(inst, eval) writeu32(dst, addr) end end + + elseif inst.details[1] == ASM_R8 and inst.details[2] == ASM_MEM8 then + if #inst.memblock.regs > 0 then + local disp = 0 + + for i = 1,#inst.memblock.expression do + if type(inst.memblock.expression[i]) == "string" then + disp = tonumber(inst.memblock.expression[i]) + print(disp) + end + end + + writeu8(dst, hexval("0h8A")) + writeu8(dst, eval.modrm) + + if disp ~= 0 then + writeu8(dst, disp) -- ASSUMING its signed integer + end + else + perror("required register at line " .. inst.operands[1].line) + end + + elseif inst.details[1] == ASM_R16 and inst.details[2] == ASM_LABEL then + if csymbols[inst.operands[2].raw] ~= nil then + local rw = band(eval.modrm, bitval("0b111")) + + writeu8(dst, hexval("0hB8") + rw) + writeu16(dst, csymbols[inst.operands[2].raw]) + end end end @@ -485,7 +553,8 @@ local function get_instruction_size(hdr, inst) if (inst.details[1] == ASM_R8 or inst.details[1] == ASM_IMM8) and (inst.details[2] == ASM_R8 or inst.details[2] == ASM_IMM8) then return 3 - elseif inst.details[1] == ASM_MEM8 and inst.details[2] == ASM_R8 then + + elseif (inst.details[1] == ASM_MEM8 and inst.details[2] == ASM_R8) or (inst.details[1] == ASM_R8 and inst.details[2] == ASM_MEM8) then local size = 2 if inst.memblock and inst.memblock.expression then for _, v in ipairs(inst.memblock.expression) do @@ -501,6 +570,8 @@ local function get_instruction_size(hdr, inst) end return size + elseif inst.details[1] == ASM_R16 and inst.details[2] == ASM_LABEL then + return 3 end elseif hdr.type == tk_type["hlt"] or hdr.type == tk_type["ret"] or hdr.type == tk_type["cli"] then @@ -517,6 +588,8 @@ local function get_instruction_size(hdr, inst) elseif hdr.type == tk_type["inc"] then if inst.details[1] == ASM_R8 then return 2 + elseif inst.details[1] == ASM_R16 then + return 2 end elseif hdr.type == tk_type["jz"] then @@ -551,6 +624,7 @@ while true do if parser.inasm == true then if hdr.type == tk_type["asm"] then perror("illegal nested asm keyword at line " .. hdr.line .. " column " .. hdr.col) + elseif hdr.type == tk_type["}"] then parser.inasm = false else @@ -600,6 +674,9 @@ while true do end end + elseif hdr.type == tk_type["org"] then + offset = hexval(hdr.raw) + elseif hdr.type == tk_type["u8"] then local n = readhdr() @@ -620,6 +697,7 @@ while true do if data.type ~= tk_type["string"] then perror("missing string next to " .. name.raw .. " at line " .. hdr.line) + csymbol[name.raw] = offset end local semi = readhdr() @@ -655,6 +733,7 @@ while true do perror("illegal nested asm keyword at line " .. hdr.line .. " column " .. hdr.col) elseif hdr.type == tk_type["}"] then parser.inasm = false + else if hdr.type ~= tk_type["\n"] then local inst = asmlyze(hdr) @@ -717,6 +796,11 @@ while true do writeu8(dst, hexval("0hFE")) writeu8(dst, modrm) + elseif inst.details[1] == ASM_R16 then + local modrm = band(eval.modrm, bitval("0b11000111")) + + writeu8(dst, hexval("0hFF")) + writeu8(dst, modrm) end elseif hdr.type == tk_type["jz"] then if inst.details[1] == ASM_LABEL then @@ -757,6 +841,9 @@ while true do parser.inasm = true readhdr() -- Skip `{` + elseif hdr.type == tk_type["org"] then + coffset = hexval(hdr.raw) + elseif hdr.type == tk_type["u8"] then local n = readhdr() @@ -774,6 +861,7 @@ while true do end writeu8(dst, 0) + csymbols[name.raw] = coffset coffset = coffset + #data + 1 readhdr() end blob - 77dcb7dfc5944eca9f8a0559f1f72c0e8a9c0f4f blob + bd0e7f99e83117aeea2baf2059f3d4dd789b319f --- tools/mkmbr +++ tools/mkmbr @@ -2,4 +2,4 @@ set -e -./6c boot.sc && ./6l boot.6 && ./mbrsign 6.boot +./6c -org 0h7c00 boot.sc && ./6l boot.6 && ./mbrsign 6.boot blob - 4f2c6e65529c5e9cde697a510410e1f6ba2ab2f8 blob + 3edcc8b34cdf43de8bf627f3777428bad65ea457 --- tools/util.lua +++ tools/util.lua @@ -12,12 +12,14 @@ local symbols = { ",", "[", "]", "(", ")", "{", "}", " local regs8 = { "al", "ah", "bl", "bh", "cl", "ch", "dl", "dh" } -local regs16 = { "ax", "bx", "cx", "dx" } +local regs16 = { "ax", "bx", "cx", "dx", "si", "di", "bp", "sp" } local ptr16 = { "si", "di", "bp", "sp" } -local asmkwd = { "asm" } +local asmkwd = { "asm", "org" } +local regs = { } + local ckwd = { "u8" } local tk_misc = { "hexadecimal", "integer", "id", "string", "\n" } @@ -30,6 +32,10 @@ for i = 1, #mnemonics do tk_type[mnemonics[i]] = count end +for i = 1, #regs8 do table.insert(regs, regs8[i]) end + +for i = 1, #regs16 do table.insert(regs, regs16[i]) end + for i = 1, #symbols do count = count + 1 tk_type[symbols[i]] = count @@ -144,6 +150,38 @@ local function isregs8(m) return false end +local function isregs16(m) + local key = gettokenkey(m) + + if key == nil then + return false + end + + for i, v in ipairs(regs16) do + if v == key then + return true + end + end + + return false +end + +local function isregs(m) + local key = gettokenkey(m) + + if key == nil then + return false + end + + for i, v in ipairs(regs) do + if v == key then + return true + end + end + + return false +end + local function isarithmetic(a) local key = gettokenkey(a) @@ -433,6 +471,10 @@ ast.eval = function(node) return { tonumber(node) } end + if type(node) == "string" then + return { { node, 1 } } + end + if node.data[1] == "number" then return { tonumber(node.data[2]) or 0 } end