commit e0074095e24797bb794ffd465b0b2a6442caa8d9 from: Onana Onana Xavier Manuel date: Thu Sep 24 14:21:26 2026 UTC Added support to mov: r8, imm8 for 6c and 6l commit - 8cd27d016af5c15375e30fd490a71a5cd6a803e9 commit + e0074095e24797bb794ffd465b0b2a6442caa8d9 blob - 2e181e40bb6bac090d4115b2baae058e2d7445dc blob + 7de524159eeb3940ea7270e030f030511e494f59 --- tools/6c +++ tools/6c @@ -110,6 +110,21 @@ local TOKEN_ID = 17 local TOKEN_STRING = 18 local TOKEN_SEMICOLON = 19 local TOKEN_HASH = 20 +local TOKEN_COMMA = 21 +local TOKEN_HLT = 22 +local TOKEN_RET = 23 +local TOKEN_CLI = 24 +local TOKEN_STI = 25 +local TOKEN_AH = 26 +local TOKEN_AL = 27 +local TOKEN_BH = 28 +local TOKEN_BL = 29 +local TOKEN_CL = 30 +local TOKEN_CH = 31 +local TOKEN_DL = 32 +local TOKEN_DH = 33 +local TOKEN_MOV = 34 +local TOKEN_HEXADECIMAL = 35 local function issymbol(char) if char == "{" or @@ -128,6 +143,7 @@ local function issymbol(char) char == "." or char == ":" or char == ";" or + char == "," or char == "#" then return true end @@ -164,6 +180,10 @@ local function readid(line, s) break end + if i == s and isnumber(char) == true then + break + end + table.insert(buf, char) end @@ -173,11 +193,37 @@ end local function readint(line, s) local len = #line local buf = { } + local hex = false for i = s, len do local char = line:sub(i, i) + if isnumber(char) == false then - break + if hex == false then + if char == "h" and (i - s) == 1 then + local prefix = line:sub(i - 1, i - 1) + + if prefix ~= "0" then + perror("illegal token `" .. prefix .. "` next to number : " .. line) + end + + hex = true + else + if char ~= "" and char ~= " " then + print("illegal sufix for number line : " .. line) + end + end + else + if char == "" or char == " " then + break + end + + if char ~= "a" and char ~= "A" and char ~= "b" and char ~= "B" and + char ~= "c" and char ~= "C" and char ~= "d" and char ~= "D" and + char ~= "e" and char ~= "E" and char ~= "f" and char ~= "F" then + perror("illegal sufix `" .. char .. "` for hexadecimal " .. line) + end + end end table.insert(buf, char) @@ -229,6 +275,8 @@ while true do write_u16(TOKEN_SEMICOLON) elseif char == "#" then write_u16(TOKEN_HASH) + elseif char == "," then + write_u16(TOKEN_COMMA) else print("Unknown symbol : " .. char) end @@ -244,9 +292,20 @@ while true do elseif isnumber(char) then local sint = readint(line, i) + local ishex = false + + if sint:sub(2, 2) == "h" then + ishex = true + end + local j = 1 write_u32(nline) write_u32(column) + if ishex == true then + write_u16(TOKEN_HEXADECIMAL) + else + write_u16(TOKEN_INTEGER) + end write_u16(#sint) i = i + #sint @@ -264,6 +323,45 @@ while true do if id == "asm" then write_u16(TOKEN_ASM) write_u16(0) + elseif id == "hlt" then + write_u16(TOKEN_HLT) + write_u16(0) + elseif id == "ret" then + write_u16(TOKEN_RET) + write_u16(0) + elseif id == "cli" then + write_u16(TOKEN_CLI) + write_u16(0) + elseif id == "sti" then + write_u16(TOKEN_STI) + write_u16(0) + elseif id == "ah" then + write_u16(TOKEN_AH) + write_u16(0) + elseif id == "al" then + write_u16(TOKEN_AL) + write_u16(0) + elseif id == "bh" then + write_u16(TOKEN_BH) + write_u16(0) + elseif id == "bl" then + write_u16(TOKEN_BL) + write_u16(0) + elseif id == "ch" then + write_u16(TOKEN_CH) + write_u16(0) + elseif id == "cl" then + write_u16(TOKEN_CL) + write_u16(0) + elseif id == "dh" then + write_u16(TOKEN_DH) + write_u16(0) + elseif id == "dl" then + write_u16(TOKEN_DL) + write_u16(0) + elseif id == "mov" then + write_u16(TOKEN_MOV) + write_u16(0) else local j = 1 write_u16(TOKEN_ID) @@ -289,3 +387,5 @@ end src:close() dst:close() + +print(progname .. ": " .. arg[1] .. " -> " .. arg[2]) blob - 11e1d810af892577140dd17861cc1755c5503e5a blob + ce8ce69a13ac2aa9f4ce553f4fe23518d06d60e8 --- tools/6l +++ tools/6l @@ -3,6 +3,360 @@ progname = "6l" if (arg[1] == nil) then - print("usage: " .. progname .. " file") + print("usage: " .. progname .. " [file ...]") os.exit(1) end + +if arg[2] == nil then + arg[2] = "6." ..string.gsub(arg[1], "%.%w+$", "") +end + +local function perror(msg) + print(progname .. ": error: " .. msg) + os.exit(1) +end + +src = io.open(arg[1], "rb") + +if src == nil then + perror("failed to open " .. arg[1]) +end + +dst = io.open(arg[2], "wb") + +if dst == nil then + perror("failed to open " .. arg[2]) +end + +local function brshift(value, bit) + return math.floor(value / (2 ^ bit)) +end + +local function blshift(value, bit) + return value * (2 ^ bit) +end + +local function bor(a, b) + local result = 0 + local shift = 1 + + while a > 0 or b > 0 do + local r1 = a % 2 + local r2 = b % 2 + + if r1 == 1 or r2 == 1 then + result = result + shift + end + + a = math.floor(a / 2) + b = math.floor(b / 2) + shift = shift * 2 + end + + return result +end + +--[[ + +Token { + u32 Line; + u32 Column; + u16 Type; + u16 Length; +} + +]]-- + +local TOKEN_ASM = 0 +local TOKEN_LEFT_CURLY_BRACKET = 1 +local TOKEN_RIGHT_CURLY_BRACKET = 2 +local TOKEN_MULTIPLY = 3 +local TOKEN_DIVIDE = 4 +local TOKEN_SUBTRACT = 5 +local TOKEN_ADD = 6 +local TOKEN_LEFT_SQUARE_BRACKET = 7 +local TOKEN_RIGHT_SQUARE_BRACKET = 8 +local TOKEN_LEFT_PARANTHESIS = 9 +local TOKEN_RIGHT_PARANTHESIS = 10 +local TOKEN_QUESTION = 11 +local TOKEN_EXCLAMATION = 12 +local TOKEN_TILDA = 13 +local TOKEN_PERIOD = 14 +local TOKEN_COLUMN = 15 +local TOKEN_INTEGER = 16 +local TOKEN_ID = 17 +local TOKEN_STRING = 18 +local TOKEN_SEMICOLON = 19 +local TOKEN_HASH = 20 +local TOKEN_COMMA = 21 +local TOKEN_HLT = 22 +local TOKEN_RET = 23 +local TOKEN_CLI = 24 +local TOKEN_STI = 25 +local TOKEN_AH = 26 +local TOKEN_AL = 27 +local TOKEN_BH = 28 +local TOKEN_BL = 29 +local TOKEN_CL = 30 +local TOKEN_CH = 31 +local TOKEN_DL = 32 +local TOKEN_DH = 33 +local TOKEN_MOV = 34 +local TOKEN_HEXADECIMAL = 35 + +local asm = { + hlt = 0xF4, + ret = 0xC3, -- Near return + cli = 0xFA, + sti = 0xFB, +} + +local MODE_NONE = 0 +local MODE_ASM = 1 + +function readtoken() + local header = src:read(12) + + if header == nil then + return nil + end + + local b = { string.byte(header, 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 length = b[12] + blshift(b[11], 8) + local raw = src:read(length) + + return { column = col, line = line, type = type, length = length, raw = raw } +end + +function hexval(hex) + local dig = hex:sub(3) + local len = #dig + local result = 0 + + for i = 1,len do + local d = dig:sub(i, i) + + if d:lower() == "a" then + d = 10 + elseif d:lower() == "b" then + d = 11 + elseif d:lower() == "c" then + d = 12 + elseif d:lower() == "d" then + d = 13 + elseif d:lower() == "e" then + d = 14 + elseif d:lower() == "f" then + d = 15 + end + + result = result + d * (16 ^ (len - i)) + end + + return result +end + +local mode = MODE_NONE +local brace_depth = 0 +local begin = src:seek("cur") + +while true do + local token = readtoken() + if token == nil then + break + end + + -- Syntax check + if token.type == TOKEN_ASM then + if mode == MODE_ASM then + perror("error: nested asm attempt at line " .. token.line .. " column " .. token.column) + break + end + + local next = readtoken() + if next == nil or next.type ~= TOKEN_LEFT_CURLY_BRACKET then + perror("error: missing '{' after asm at line " .. token.line .. " column " .. token.column) + break + end + + mode = MODE_ASM + elseif token.type == TOKEN_HLT then + if mode ~= MODE_ASM then + perror("error: hlt instruction outside asm block at line " .. token.line .. " column " .. + token.column) + end + + local next = readtoken() + + if next ~= nil and next.line == token.line then + perror("error: illegal token next to hlt on line " .. token.line .. " column " .. + token.column) + end + elseif token.type == TOKEN_RET then + if mode ~= MODE_ASM then + perror("error: ret instruction out of asm block at line " .. token.line .. " column " .. + token.column) + end + + local next = readtoken() + if next ~= nil and next.line == token.line then + perror("error: illegal token after ret on line " .. token.line " .. column " .. + token.column) + end + elseif token.type == TOKEN_CLI then + if mode ~= MODE_ASM then + perror("error: cli instruction out of asm block at line " .. token.line .. " column " .. + token.column) + end + + local next = readtoken() + if next ~= nil and next.line == token.line then + perror("error: illegal token after cli on line " .. token.line " .. column " .. + token.column) + end + elseif token.type == TOKEN_STI then + if mode ~= MODE_ASM then + perror("error: sti instruction out of asm block at line " .. token.line .. " column " .. + token.column) + end + + local next = readtoken() + if next ~= nil and next.line == token.line then + perror("error: illegal token after sti on line " .. token.line " .. column " .. + token.column) + end + + elseif token.type == TOKEN_MOV then + if mode ~= MODE_ASM then + perror("error: sti instruction out of asm block at line " .. token.line .. " column " .. + token.column) + end + + local op1 = readtoken() + + if op1.type ~= TOKEN_AL and op1.type ~= TOKEN_AH and op1.type ~= TOKEN_BL and + op1.type ~= TOKEN_BH and op1.type ~= TOKEN_CH and + op1.type ~= TOKEN_CL and op1.type ~= TOKEN_DH and + op1.type ~= TOKEN_DL then + perror("illegal first operand for mov at line " .. token.line .. " column " .. + token.column) + end + + local comma = readtoken() + + if comma.type ~= TOKEN_COMMA then + perror("missing comma next to first operand line " .. token.line .. " column " .. + token.column) + end + + local op2 = readtoken() + + if op2.type ~= TOKEN_AL and op2.type ~= TOKEN_AH and op2.type ~= TOKEN_BL and + op2.type ~= TOKEN_BH and op2.type ~= TOKEN_CH and + op2.type ~= TOKEN_CL and op2.type ~= TOKEN_DH and + op2.type ~= TOKEN_DL and op2.type ~= TOKEN_HEXADECIMAL then + perror("illegal second operand for mov at line " .. token.line .. " column " .. + token.column) + end + + -- Checking if hex value is to high: mov r8, imm8 + if op2.type == TOKEN_HEXADECIMAL and + (op1.type == TOKEN_AH or op1.type == TOKEN_AL or + op1.type == TOKEN_BH or op1.type == TOKEN_BL or + op1.type == TOKEN_CH or op1.type == TOKEN_CL or + op1.type == TOKEN_DH or op1.type == TOKEN_DL) then + if hexval(op2.raw) > 255 then + perror("hexvalue too high at line " .. token.line .. " column " .. token.column) + end + end + end +end + +src:seek("set", begin) + +while true do + local token = readtoken() + if token == nil then + break + end + + if token.type == TOKEN_HLT then + dst:write(string.char(asm.hlt)) + elseif token.type == TOKEN_RET then + dst:write(string.char(asm.ret)) + elseif token.type == TOKEN_CLI then + dst:write(string.char(asm.cli)) + elseif token.type == TOKEN_STI then + dst:write(string.char(asm.sti)) + elseif token.type == TOKEN_MOV then + local op1 = readtoken() + readtoken() -- Comma + local op2 = readtoken() + + if op1.type == TOKEN_AL then + if op2.type == TOKEN_HEXADECIMAL then + local opcode = { hexval("0hB0") + tonumber("000", 2), hexval(op2.raw) } + + dst:write(string.char(opcode[1])) + dst:write(string.char(opcode[2])) + end + elseif op1.type == TOKEN_AH then + if op2.type == TOKEN_HEXADECIMAL then + local opcode = { hexval("0hB0") + tonumber("100", 2), hexval(op2.raw) } + + dst:write(string.char(opcode[1])) + dst:write(string.char(opcode[2])) + end + elseif op1.type == TOKEN_BL then + if op2.type == TOKEN_HEXADECIMAL then + local opcode = { hexval("0hB0") + tonumber("011", 2), hexval(op2.raw) } + + dst:write(string.char(opcode[1])) + dst:write(string.char(opcode[2])) + end + elseif op1.type == TOKEN_BH then + if op2.type == TOKEN_HEXADECIMAL then + local opcode = { hexval("0hB0") + tonumber("111", 2), hexval(op2.raw) } + + dst:write(string.char(opcode[1])) + dst:write(string.char(opcode[2])) + end + elseif op1.type == TOKEN_CL then + if op2.type == TOKEN_HEXADECIMAL then + local opcode = { hexval("0hB0") + tonumber("001", 2), hexval(op2.raw) } + + dst:write(string.char(opcode[1])) + dst:write(string.char(opcode[2])) + end + elseif op1.type == TOKEN_CH then + if op2.type == TOKEN_HEXADECIMAL then + local opcode = { hexval("0hB0") + tonumber("101", 2), hexval(op2.raw) } + + dst:write(string.char(opcode[1])) + dst:write(string.char(opcode[2])) + end + elseif op1.type == TOKEN_DL then + if op2.type == TOKEN_HEXADECIMAL then + local opcode = { hexval("0hB0") + tonumber("010", 2), hexval(op2.raw) } + + dst:write(string.char(opcode[1])) + dst:write(string.char(opcode[2])) + end + elseif op1.type == TOKEN_DH then + if op2.type == TOKEN_HEXADECIMAL then + local opcode = { hexval("0hB0") + tonumber("110", 2), hexval(op2.raw) } + + dst:write(string.char(opcode[1])) + dst:write(string.char(opcode[2])) + end + end + end +end + +src:close() +dst:close() +print(arg[1] .. " -> " .. arg[2]) blob - 41132f6b89059a67428a66b152a26ab7cf840a38 blob + 17dc1369b1522cc6139fcb7b47f9086f35c4d8bb --- tools/boot.c +++ tools/boot.c @@ -1,11 +1,4 @@ -import libc; - asm { _start: - hlt + ret } - -void main() -{ - u64 var = 22; -}