diff --git a/assembler-8608.lua b/assembler-8608.lua index dd7f80a..72563a1 100644 --- a/assembler-8608.lua +++ b/assembler-8608.lua @@ -1,13 +1,25 @@ local arch8608 = require("rom-8608-defs") -local aliases = { - ["jpz imm8"] = {"jeq imm8"}, - ["jnz imm8"] = {"jne imm8"}, - ["jmp q" ] = {"ret" }, -} +local function loadutf8table(fn) + local tt = {} + for l in io.lines(fn) do if l~="" then + local c, d = l:match("^([^ ]+) (.+)$") + local t = {}; for v in d:gmatch("[^ ]+") do table.insert(t, tonumber(v, 16)) end; + tt[c] = t + end end + return tt +end +local utf8table = loadutf8table("./utf8table.txt") local function trim(s) return s:gsub("^ +", ""):gsub(" +$", "").."" end +local function getutf8len(c) + local d = c:byte() + if bit.band(d, 0xE0)==0xC0 then return 2 + elseif bit.band(d, 0xF0)==0xE0 then return 3 + elseif bit.band(d, 0xF8)==0xF0 then return 4 + else error("invalid utf8 first byte: "..string.format("%02X", d)) end +end local function validWordsFromInstrs(instrs) local words = {} for mnem, _ in pairs(instrs) do @@ -303,6 +315,9 @@ local function prefixCode(code, fn) -- fix strings, add line numbers local bracehasmid = {} local lastnl = false + local utf8str = "" + local utf8len = 0 + out(".ln 1"); out("\n"); for i = 1, #code do local c = code:sub(i, i) @@ -347,11 +362,24 @@ local function prefixCode(code, fn) -- fix strings, add line numbers elseif state=="commentml" then if c=="/" and cp=="*" then state = "code" end elseif state=="string" then - if c=="\\" then state = "stringesc" - elseif c=="\"" then state = "code" + if c=="\\" then state = "stringesc" + elseif c=="\"" then state = "code" + elseif c:byte()>=128 then + utf8str = c + utf8len = getutf8len(c) + state = "stringutf8" else outn(c:byte()) end elseif state=="stringesc" then outn(string.byte(stringEscapes[c] or error("invalid escape "..c))); state = "string"; + elseif state=="stringutf8" then + utf8str = utf8str..c + if #utf8str == utf8len then + local valt = utf8table[utf8str] + if not valt then local datastr = ""; for i = 1, #utf8str do datastr = datastr .. string.format("%02X ", utf8str:sub(i, i):byte()) end; + error("Unrecognized UTF-8 character: "..datastr); end + for i, v in ipairs(valt) do outn(v) end + state = "string" + end end end assert(#bracestack==0, "unclosed brace") @@ -397,7 +425,7 @@ local function instrsFromArch(arch) mnem = mnem:gsub("([%*%+%-])", " %1 ") mnem = trim(mnem):gsub(" +", " ") addMnem(mnem, instr.opcode) - local alias = aliases[trim(mnem)] + local alias = arch.aliases[trim(mnem)] if alias then for _, v in ipairs(alias) do addMnem(v, instr.opcode) end end end end @@ -566,13 +594,14 @@ local function strtovec(str) local v = {}; for word in str:gmatch("[^ \t\r\n]+") function AssembleFile(fn, romsizes, offsets, lens) local offset = tonumber(offsets); local len = tonumber(lens); local romsize = strtovec(romsizes); local arch = arch8608 local mem = assembleFile(fn, arch) + print(""..fn:match("[^/\\]+$").."\n") printMemory(mem) assert(#romsize==3, "incorrect rom size") buildMemory(mem, romsize, offset, len) disassembleMemory(mem, arch) end ts.eval [[ - function AssembleFile(%fn, %romsize, %offset, %len) { luacall("AssembleFile", %fn, %romsize, %offset, %len); } + function AssembleFile(%fn, %romsize, %offset, %len) { luacall("AssembleFile", "Add-ons/_misc/rom/8608programs/" @ %fn, %romsize, %offset, %len); } ]] if arg then AssembleFile(arg[1] or "../8608programs/test.asm", "16 16 8", "0", "256") end diff --git a/instructionList.txt b/instructionList.txt index 89c6470..1c335a7 100644 --- a/instructionList.txt +++ b/instructionList.txt @@ -5,12 +5,13 @@ hlt F0 1 Halt non-interrupt execution run F1 1 Resume non-interrupt execution brk F3 1 Trigger interrupt irt F4 1 Return from interrupt +nop FF 1 Do nothing 16-bit Inc/Dec (I): -icp 12 1 P++ -dcp 15 1 P-- -icq 13 1 Q++ -dcq 16 1 Q-- +inc p 12 1 P++ +dec p 15 1 P-- +inc q 13 1 Q++ +dec q 16 1 Q-- 8-bit Unary (U): inc a 10 1 A++, set flags @@ -125,16 +126,18 @@ jgt imm8 35 2 I+=imm8 if !Zero & Carry jle imm8 36 2 I+=imm8 if Zero | !Carry Stack (S): -pha 40 2 *(S++)=A -phb 44 2 *(S++)=B -phc 45 2 *(S++)=C -php 41 3 *(S++++)=P -phq 46 3 *(S++++)=Q -ppa 42 2 A=*(--S) -ppb 47 2 B=*(--S) -ppc 48 2 C=*(--S) -ppp 43 3 P=*(----S) -ppq 49 3 Q=*(----S) +psh a 40 2 *(S++)=A +psh b 44 2 *(S++)=B +psh c 45 2 *(S++)=C +psh p 41 3 *(S++++)=P +psh q 46 3 *(S++++)=Q +pop a 42 2 A=*(--S) +pop b 47 2 B=*(--S) +pop c 48 2 C=*(--S) +pop p 43 3 P=*(----S) +pop q 49 3 Q=*(----S) +psh imm8 3B 3 *(S++)=imm8 +psh imm16 3C 5 *(S++++)=imm16 8-bit Load/Store (B): lda imm8 20 2 A=imm8, update zero flag @@ -212,21 +215,26 @@ lda pl 86 1 A=P&FF lda ph 87 1 A=P>>8 lda ql 88 1 A=Q&FF lda qh 89 1 A=Q>>8 +ldb pl 37 1 B=P&FF +ldc ph 38 1 C=P>>8 +ldb ql 39 1 B=Q&FF +ldc qh 3A 1 C=Q>>8 ldp q 8A 1 P=Q ldp s 8B 1 P=S ldp v 8C 1 P=V ldp i 8D 1 P=I -ldp cb 91 1 P=C<<8+B +ldp cb 91 1 P=(C<<8)+B +ldq cb E0 1 Q=(C<<8)+B ldq p 8E 1 Q=P lds p 8F 1 S=P ldv p 90 1 V=P -Opcodes used: 207/255 +Opcodes used: 216/255 0123456789ABCDEF 00 | C--------------- 10 | UUIIUIIUUUUUUUUU 20 | BWWWAWBBBBBUUUUA -30 | JJJJJJJ-------AA +30 | JJJJJJJMMMMSSSAA 40 | SSSSSSSSSSXXXAAA 50 | BBBBBBBBBBBBBBBB 60 | JBBJJJJJWWWWWWWW @@ -237,5 +245,5 @@ A0 | AAAAAAAAAAAAAAAA B0 | AAAAAAAAAAAAAAAA C0 | BBBBBBBBBBBBWWWW D0 | AAAAAAAAAAAAAAAA -E0 | ---------------- -F0 | CCCCC----------- +E0 | M--------------- +F0 | CCCCC----------C diff --git a/rom-8608-defs.lua b/rom-8608-defs.lua index 047451a..cfcf6ef 100644 --- a/rom-8608-defs.lua +++ b/rom-8608-defs.lua @@ -127,12 +127,13 @@ instructions = { { mnem="int" , opcode=0xF2, {"instrSwapIV","intFlgVal","intFlgClk","irqFlgClk"}, }, { mnem="brk" , opcode=0xF3, {"instrSwapIV","adwInc","intFlgVal","intFlgClk"}, desc="Trigger interrupt" }, { mnem="irt" , opcode=0xF4, {"instrSwapIV","adwInc","intFlgClk"}, desc="Return from interrupt" }, + { mnem="nop" , opcode=0xFF, {"instrNext"}, desc="Do nothing" }, { category = "16-bit Inc/Dec", catlet="I" }, - { mnem="icp" , opcode=0x12, {"adwlP","adwInc","adwSaveP","instrNext"}, desc="P++" }, - { mnem="dcp" , opcode=0x15, {"adwlP","adwrm1","adwSaveP","instrNext"}, desc="P--" }, - { mnem="icq" , opcode=0x13, {"adwlQ","adwInc","adwSaveQ","instrNext"}, desc="Q++" }, - { mnem="dcq" , opcode=0x16, {"adwlQ","adwrm1","adwSaveQ","instrNext"}, desc="Q--" }, + { mnem="inc p" , opcode=0x12, {"adwlP","adwInc","adwSaveP","instrNext"}, desc="P++" }, + { mnem="dec p" , opcode=0x15, {"adwlP","adwrm1","adwSaveP","instrNext"}, desc="P--" }, + { mnem="inc q" , opcode=0x13, {"adwlQ","adwInc","adwSaveQ","instrNext"}, desc="Q++" }, + { mnem="dec q" , opcode=0x16, {"adwlQ","adwrm1","adwSaveQ","instrNext"}, desc="Q--" }, { category = "8-bit Unary", catlet="U" }, { mnem="inc a" , opcode=0x10, {"aluA","alur1" ,"aluOpAdd" ,"instrNext"}, desc="A++, set flags" }, @@ -247,16 +248,18 @@ instructions = { { mnem="jle imm8" , opcode=0x36, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NC","instrNext0Z"}, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if Zero | !Carry" }, { category = "Stack", catlet="S" }, - { mnem="pha" , opcode=0x40, {"pushReg","alurA","instrSub1"}, {"instrNext"}, desc="*(S++)=A" }, - { mnem="phb" , opcode=0x44, {"pushReg","alurB","instrSub1"}, {"instrNext"}, desc="*(S++)=B" }, - { mnem="phc" , opcode=0x45, {"pushReg","alurC","instrSub1"}, {"instrNext"}, desc="*(S++)=C" }, - { mnem="php" , opcode=0x41, {"pushReg","alurPH","instrSub1"}, {"pushReg","alurPL","instrSub2"}, {"instrNext"}, desc="*(S++++)=P" }, - { mnem="phq" , opcode=0x46, {"pushReg","alurQH","instrSub1"}, {"pushReg","alurQL","instrSub2"}, {"instrNext"}, desc="*(S++++)=Q" }, - { mnem="ppa" , opcode=0x42, {"popReg","memSaveA","instrSub1"}, {"instrNext"}, desc="A=*(--S)" }, - { mnem="ppb" , opcode=0x47, {"popReg","memSaveB","instrSub1"}, {"instrNext"}, desc="B=*(--S)" }, - { mnem="ppc" , opcode=0x48, {"popReg","memSaveC","instrSub1"}, {"instrNext"}, desc="C=*(--S)" }, - { mnem="ppp" , opcode=0x43, {"pop161","instrSub1"}, {"pop162","instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*(----S)" }, - { mnem="ppq" , opcode=0x49, {"pop161","instrSub1"}, {"pop162","instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*(----S)" }, + { mnem="psh a" , opcode=0x40, {"pushReg","alurA","instrSub1"}, {"instrNext"}, desc="*(S++)=A" }, + { mnem="psh b" , opcode=0x44, {"pushReg","alurB","instrSub1"}, {"instrNext"}, desc="*(S++)=B" }, + { mnem="psh c" , opcode=0x45, {"pushReg","alurC","instrSub1"}, {"instrNext"}, desc="*(S++)=C" }, + { mnem="psh p" , opcode=0x41, {"pushReg","alurPH","instrSub1"}, {"pushReg","alurPL","instrSub2"}, {"instrNext"}, desc="*(S++++)=P" }, + { mnem="psh q" , opcode=0x46, {"pushReg","alurQH","instrSub1"}, {"pushReg","alurQL","instrSub2"}, {"instrNext"}, desc="*(S++++)=Q" }, + { mnem="pop a" , opcode=0x42, {"popReg","memSaveA","instrSub1"}, {"instrNext"}, desc="A=*(--S)" }, + { mnem="pop b" , opcode=0x47, {"popReg","memSaveB","instrSub1"}, {"instrNext"}, desc="B=*(--S)" }, + { mnem="pop c" , opcode=0x48, {"popReg","memSaveC","instrSub1"}, {"instrNext"}, desc="C=*(--S)" }, + { mnem="pop p" , opcode=0x43, {"pop161","instrSub1"}, {"pop162","instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*(----S)" }, + { mnem="pop q" , opcode=0x49, {"pop161","instrSub1"}, {"pop162","instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*(----S)" }, + { mnem="psh imm8" , opcode=0x3B, {"loadImmedT","instrSub1"}, {"pushReg","alurT","instrSub2"}, {"instrNext"}, desc="*(S++)=imm8" }, + { mnem="psh imm16" , opcode=0x3C, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"pushReg","alurU","instrSub3"}, {"pushReg","alurT","instrSub4"}, {"instrNext"}, desc="*(S++++)=imm16" }, -- 0x3D { category = "8-bit Load/Store", catlet="B" }, { mnem="lda imm8" , opcode=0x20, {"loadImmed", "memSaveA","memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=imm8, update zero flag" }, @@ -334,14 +337,25 @@ instructions = { { mnem="lda ph" , opcode=0x87, {"alurPH","aluOpMov","aluSaveA","instrNext"}, desc="A=P>>8" }, { mnem="lda ql" , opcode=0x88, {"alurQL","aluOpMov","aluSaveA","instrNext"}, desc="A=Q&FF" }, { mnem="lda qh" , opcode=0x89, {"alurQH","aluOpMov","aluSaveA","instrNext"}, desc="A=Q>>8" }, + { mnem="ldb pl" , opcode=0x37, {"alurPL","aluOpMov","aluSaveB","instrNext"}, desc="B=P&FF" }, + { mnem="ldc ph" , opcode=0x38, {"alurPH","aluOpMov","aluSaveC","instrNext"}, desc="C=P>>8" }, + { mnem="ldb ql" , opcode=0x39, {"alurQL","aluOpMov","aluSaveB","instrNext"}, desc="B=Q&FF" }, + { mnem="ldc qh" , opcode=0x3A, {"alurQH","aluOpMov","aluSaveC","instrNext"}, desc="C=Q>>8" }, { mnem="ldp q" , opcode=0x8A, {"adwlQ" , "adwSaveP","instrNext"}, desc="P=Q" }, { mnem="ldp s" , opcode=0x8B, {"adwlS" , "adwSaveP","instrNext"}, desc="P=S" }, { mnem="ldp v" , opcode=0x8C, {"adwlV" , "adwSaveP","instrNext"}, desc="P=V" }, { mnem="ldp i" , opcode=0x8D, {"adwlI" , "adwSaveP","instrNext"}, desc="P=I" }, - { mnem="ldp cb" , opcode=0x91, {"adwrCB", "adwSaveP","instrNext"}, desc="P=C<<8+B" }, + { mnem="ldp cb" , opcode=0x91, {"adwrCB", "adwSaveP","instrNext"}, desc="P=(C<<8)+B" }, + { mnem="ldq cb" , opcode=0xE0, {"adwrCB", "adwSaveQ","instrNext"}, desc="Q=(C<<8)+B" }, { mnem="ldq p" , opcode=0x8E, {"adwlP" , "adwSaveQ","instrNext"}, desc="Q=P" }, { mnem="lds p" , opcode=0x8F, {"adwlP" , "adwSaveS","instrNext"}, desc="S=P" }, { mnem="ldv p" , opcode=0x90, {"adwlP" , "adwSaveV","instrNext"}, desc="V=P" }, }, +aliases = { + ["jpz imm8"] = {"jeq imm8"}, + ["jnz imm8"] = {"jne imm8"}, + ["jmp q" ] = {"ret" }, +}, + } diff --git a/utf8table.txt b/utf8table.txt new file mode 100644 index 0000000..05a2346 --- /dev/null +++ b/utf8table.txt @@ -0,0 +1,88 @@ +。 A1 +「 A2 +」 A3 +、 A4 +・ A5 +ヲ A6 +ァ A7 +ィ A8 +ゥ A9 +ェ AA +ォ AB +ャ AC +ュ AD +ョ AE +ッ AF +ー B0 +ア B1 +イ B2 +ウ B3 +エ B4 +オ B5 +カ B6 +キ B7 +ク B8 +ケ B9 +コ BA +サ BB +シ BC +ス BD +セ BE +ソ BF +タ C0 +チ C1 +ツ C2 +テ C3 +ト C4 +ナ C5 +ニ C6 +ヌ C7 +ネ C8 +ノ C9 +ハ CA +ヒ CB +フ CC +ヘ CD +ホ CE +マ CF +ミ D0 +ム D1 +メ D2 +モ D3 +ヤ D4 +ユ D5 +ヨ D6 +ラ D7 +リ D8 +ル D9 +レ DA +ロ DB +ワ DC +ン DD +゛ DE +゜ DF +ガ B6 DE +ギ B7 DE +グ B8 DE +ゲ B9 DE +ゴ BA DE +ザ BB DE +ジ BC DE +ズ BD DE +ゼ BE DE +ゾ BF DE +ダ C0 DE +ヂ C1 DE +ヅ C2 DE +デ C3 DE +ド C4 DE +バ CA DE +ビ CB DE +ブ CC DE +ベ CD DE +ボ CE DE +パ CA DF +ピ CB DF +プ CC DF +ペ CD DF +ポ CE DF