diff --git a/l7801.lua b/l7801.lua index 6a96c81..7172b8e 100644 --- a/l7801.lua +++ b/l7801.lua @@ -44,7 +44,7 @@ local Keywords_7801 = { 'dcrw','dcx','ex','exx','gti','halt','inr','inrw', 'inx','jb','jmp','jr','jre','ldaw','ldax','ldaxd', 'ldaxi','lti','lxi','mov','mvi','mviw','mvix','nei', - 'nop','offi','oni','ori','pen','per','pex','ret', + 'nop','offi','oni','ori','pen','per','pex','pop','push','ret', 'reti','rets','rld','rrd','sio','softi','staw','stax', 'staxd','staxi','stc','stm','sbi','sui','suinb','table', 'xri', @@ -90,7 +90,7 @@ local opcode_relative = lookupify{ 'jr','jre' } local opcode_reg = lookupify{ - 'dcr','dcx','inr','inx' + 'dcr','dcx','inr','inx','pop','push', } local opcode_reg_reg = lookupify{ 'mov' @@ -116,10 +116,12 @@ local opcode_reg_list = { e = lookupify{'mvi'}, h = lookupify{'mvi'}, l = lookupify{'mvi'}, - v = lookupify{'mvi'}, - bc = lookupify{'ldax','lxi','mvix','stax'}, - de = lookupify{'ldax','ldaxd','ldaxi','lxi','mvix','stax','staxd','staxi'}, - hl = lookupify{'dcx','inx','ldax','ldaxd','ldaxi','lxi','mvix','stax','staxd','staxi'}, + v = lookupify{'inrw','ldaw','dcrw','eqiw','mvi','mviw','pop','push','staw', + 'bit0','bit1','bit2','bit3','bit4','bit5','bit6','bit7', + }, + bc = lookupify{'ldax','lxi','mvix','pop','push','stax'}, + de = lookupify{'ldax','ldaxd','ldaxi','lxi','mvix','pop','push','stax','staxd','staxi'}, + hl = lookupify{'dcx','inx','ldax','ldaxd','ldaxi','lxi','mvix','pop','push','stax','staxd','staxi'}, sp = lookupify{'dcx','inx','lxi'}, } @@ -1480,14 +1482,11 @@ local function ParseLua(src, src_name) end stat = emit_call{name=op, args={expr, mod_expr}, inverse_encapsulate=inverse_encapsulate, paren_open_white=paren_open_whites} break end - if opcode_reg_ind[op] or opcode_reg_ind_ex[op] then - if not tok:ConsumeSymbol('(', tokenList) then - return false, GenerateError("Unexpected character") - end - + + if (opcode_wa[op] or opcode_wab[op] or opcode_reg_ind[op] or opcode_reg_ind_ex[op]) and tok:ConsumeSymbol('(', tokenList) then local paren_open_whites,paren_close_whites = {},{} for _,v in ipairs(tokenList[#tokenList].LeadingWhite) do table.insert(paren_open_whites, v) end - + local register_name = tok:Get(tokenList).Data if not Registers_7801[register_name] then return false, GenerateError(register_name .. " is not a valid register") @@ -1495,58 +1494,51 @@ local function ParseLua(src, src_name) if not (opcode_reg_list[register_name] and opcode_reg_list[register_name][op]) then return false, GenerateError("Opcode " .. op .. " doesn't support this addressing mode") end - if not tok:ConsumeSymbol(')', tokenList) then - return false, GenerateError("Unexpected character") - end - if opcode_reg_ind[op] then - for _,v in ipairs(tokenList[#tokenList-1].LeadingWhite) do table.insert(paren_close_whites, v) end + + if (opcode_wa[op] or opcode_wab[op]) and tok:ConsumeSymbol(',', tokenList) then + if not (register_name == 'v') + or not (opcode_wa[op] or opcode_wab[op]) then + return false, GenerateError("Opcode " .. op .. " doesn't support this addressing mode") + end + inverse_encapsulate = tok:ConsumeSymbol('!', tokenList) + local st, expr = ParseExpr(scope) if not st then return false, expr end + if not tok:ConsumeSymbol(')', tokenList) then + return false, GenerateError("Unexpected character") + end + if opcode_wa[op] then + for _,v in ipairs(tokenList[#tokenList-1].LeadingWhite) do table.insert(paren_close_whites, v) end + for _,v in ipairs(tokenList[#tokenList].LeadingWhite) do table.insert(paren_close_whites, v) end + stat = emit_call{name=op .. "wa", args={expr, mod_expr}, inverse_encapsulate=inverse_encapsulate, paren_open_white=paren_open_whites} break + end + if not tok:ConsumeSymbol(',', tokenList) then + return false, GenerateError("Unexpected character") + end + commaTokenList[1] = tokenList[#tokenList] + local inverse_encapsulates = { inverse_encapsulate } + local exprs = { expr } + inverse_encapsulate = tok:ConsumeSymbol('!', tokenList) + inverse_encapsulates[#inverse_encapsulates+1] = inverse_encapsulate + if inverse_encapsulate then for _,v in ipairs(tokenList[#tokenList-1].LeadingWhite) do table.insert(paren_close_whites, v) end end for _,v in ipairs(tokenList[#tokenList].LeadingWhite) do table.insert(paren_close_whites, v) end - stat = emit_call{name=op .. register_name, paren_open_white=paren_open_whites, paren_close_white=paren_close_whites} break + st, expr = ParseExpr(scope) if not st then return false, expr end + exprs[#exprs+1] = expr + stat = emit_call{name=op .. "waxx", args=exprs, inverse_encapsulate=inverse_encapsulates, paren_open_white=paren_open_whites, paren_close_white=paren_close_whites} break end - if not tok:ConsumeSymbol(',', tokenList) then - return false, GenerateError("Unexpected character") + if (opcode_reg_ind[op] or opcode_reg_ind_ex[op]) and tok:ConsumeSymbol(')', tokenList) then + if opcode_reg_ind[op] then + for _,v in ipairs(tokenList[#tokenList-1].LeadingWhite) do table.insert(paren_close_whites, v) end + for _,v in ipairs(tokenList[#tokenList].LeadingWhite) do table.insert(paren_close_whites, v) end + stat = emit_call{name=op .. register_name, paren_open_white=paren_open_whites, paren_close_white=paren_close_whites} break + end + if opcode_reg_ind_ex[op] and tok:ConsumeSymbol(',', tokenList) then + inverse_encapsulate = tok:ConsumeSymbol('!', tokenList) + local st, expr = ParseExpr(scope) if not st then return false, expr end + if inverse_encapsulate then for _,v in ipairs(tokenList[#tokenList-1].LeadingWhite) do table.insert(paren_close_whites, v) end end + for _,v in ipairs(tokenList[#tokenList].LeadingWhite) do table.insert(paren_close_whites, v) end + stat = emit_call{name=op .. register_name, args={expr}, inverse_encapsulate=inverse_encapsulate, paren_open_white=paren_open_whites, paren_close_white=paren_close_whites} break + end + return false, GenerateError("Opcode " .. op .. " doesn't support this addressing mode") end - inverse_encapsulate = tok:ConsumeSymbol('!', tokenList) - local st, expr = ParseExpr(scope) if not st then return false, expr end - if inverse_encapsulate then for _,v in ipairs(tokenList[#tokenList-1].LeadingWhite) do table.insert(paren_close_whites, v) end end - for _,v in ipairs(tokenList[#tokenList].LeadingWhite) do table.insert(paren_close_whites, v) end - stat = emit_call{name=op .. register_name, args={expr}, inverse_encapsulate=inverse_encapsulate, paren_open_white=paren_open_whites, paren_close_white=paren_close_whites} break - end - if opcode_wa[op] or opcode_wab[op] then - if not tok:ConsumeSymbol('(', tokenList) then - return false, GenerateError("Unexpected character") - end - - local paren_open_whites,paren_close_whites = {},{} - for _,v in ipairs(tokenList[#tokenList].LeadingWhite) do table.insert(paren_open_whites, v) end - - if not (tok:Get(tokenList).Data == 'v') then - return false, GenerateError("Opcode " .. op .. " doesn't support this addressing mode") - end - if not tok:ConsumeSymbol(',', tokenList) then - return false, GenerateError("Unexpected character") - end - inverse_encapsulate = tok:ConsumeSymbol('!', tokenList) - local st, expr = ParseExpr(scope) if not st then return false, expr end - if not tok:ConsumeSymbol(')', tokenList) then return false, expr end - if opcode_wa[op] then - for _,v in ipairs(tokenList[#tokenList-1].LeadingWhite) do table.insert(paren_close_whites, v) end - for _,v in ipairs(tokenList[#tokenList].LeadingWhite) do table.insert(paren_close_whites, v) end - stat = emit_call{name=op .. "wa", args={expr, mod_expr}, inverse_encapsulate=inverse_encapsulate, paren_open_white=paren_open_whites} break - end - if not tok:ConsumeSymbol(',', tokenList) then - return false, GenerateError("Unexpected character") - end - commaTokenList[1] = tokenList[#tokenList] - local inverse_encapsulates = { inverse_encapsulate } - local exprs = { expr } - inverse_encapsulate = tok:ConsumeSymbol('!', tokenList) - inverse_encapsulates[#inverse_encapsulates+1] = inverse_encapsulate - if inverse_encapsulate then for _,v in ipairs(tokenList[#tokenList-1].LeadingWhite) do table.insert(paren_close_whites, v) end end - for _,v in ipairs(tokenList[#tokenList].LeadingWhite) do table.insert(paren_close_whites, v) end - st, expr = ParseExpr(scope) if not st then return false, expr end - exprs[#exprs+1] = expr - stat = emit_call{name=op .. "waxx", args=exprs, inverse_encapsulate=inverse_encapsulates, paren_open_white=paren_open_whites, paren_close_white=paren_close_whites} break end if opcode_reg_reg[op] then local r0_name = tok:Get(tokenList).Data diff --git a/samples/scv_test.l65 b/samples/scv_test.l65 index 4ce2009..adadbfc 100644 --- a/samples/scv_test.l65 +++ b/samples/scv_test.l65 @@ -95,6 +95,12 @@ section{"rom", org=0x8000} @l8 jre l9 nop nop nop nop @l9 + ldax (bc) + ldax (de) + ldax (hl) + stax (bc) + stax (de) + stax (hl) inrw (v,0x01) ldaw (v,0x23) dcrw (v,0x45) @@ -116,12 +122,6 @@ section{"rom", org=0x8000} mvix (bc),0xf9 mvix (de),0xe8 mvix (hl),0xd7 - ldax (bc) - ldax (de) - ldax (hl) - stax (bc) - stax (de) - stax (hl) mviw (v,0x9a),0x3f eqiw (v,0xc5),0x1b ldaxd (de) @@ -132,5 +132,12 @@ section{"rom", org=0x8000} staxi (de) staxd (hl) staxi (hl) - + push bc + push de + push hl + pop hl + pop de + pop bc + push v + pop v writebin(filename .. '.bin') \ No newline at end of file diff --git a/uPD7801.lua b/uPD7801.lua index 88a027e..048f1c7 100644 --- a/uPD7801.lua +++ b/uPD7801.lua @@ -325,12 +325,86 @@ for k,v in pairs(op48imp) do end end +local op48r16={ + pushbc=M.op(0x1e,17), + pushde=M.op(0x2e,17), + pushhl=M.op(0x3e,17), + pushv=M.op(0x0e,17), + popbc=M.op(0x1f,15), + popde=M.op(0x2f,15), + pophl=M.op(0x3f,15), + popv=M.op(0x0f,15), +} M.op48r16 = op48r16 +for k,v in pairs(op48r16) do + M[k] = function() + table.insert(M.section_current.instructions, { size=2, cycles=v.cycles, bin={ 0x48, v.opc } }) + end +end + return M --[[ [todo] 16 bits instructions: 0x48xx + case 0x00: my_stprintf_s(buffer, buffer_len, _T("skit intf0")); break; + case 0x01: my_stprintf_s(buffer, buffer_len, _T("skit intft")); break; + case 0x02: my_stprintf_s(buffer, buffer_len, _T("skit intf1")); break; + case 0x03: my_stprintf_s(buffer, buffer_len, _T("skit intf2")); break; + case 0x04: my_stprintf_s(buffer, buffer_len, _T("skit intfs")); break; + case 0x0a: my_stprintf_s(buffer, buffer_len, _T("sk cy")); break; + case 0x0c: my_stprintf_s(buffer, buffer_len, _T("sk z")); break; + case 0x10: my_stprintf_s(buffer, buffer_len, _T("sknit f0")); break; + case 0x11: my_stprintf_s(buffer, buffer_len, _T("sknit ft")); break; + case 0x12: my_stprintf_s(buffer, buffer_len, _T("sknit f1")); break; + case 0x13: my_stprintf_s(buffer, buffer_len, _T("sknit f2")); break; + case 0x14: my_stprintf_s(buffer, buffer_len, _T("sknit fs")); break; + case 0x1a: my_stprintf_s(buffer, buffer_len, _T("skn cy")); break; + case 0x1c: my_stprintf_s(buffer, buffer_len, _T("skn z")); break; + case 0x30: my_stprintf_s(buffer, buffer_len, _T("rll a")); break; + case 0x31: my_stprintf_s(buffer, buffer_len, _T("rlr a")); break; + case 0x32: my_stprintf_s(buffer, buffer_len, _T("rll c")); break; + case 0x33: my_stprintf_s(buffer, buffer_len, _T("rlr c")); break; + case 0x34: my_stprintf_s(buffer, buffer_len, _T("sll a")); break; + case 0x35: my_stprintf_s(buffer, buffer_len, _T("slr a")); break; + case 0x36: my_stprintf_s(buffer, buffer_len, _T("sll c")); break; + case 0x37: my_stprintf_s(buffer, buffer_len, _T("sll c")); break; + + {&upd7810_device::SKIT_F0, 2, 8, 8,L0|L1}, {&upd7810_device::SKIT_FT0, 2, 8, 8,L0|L1}, + {&upd7810_device::SKIT_F1, 2, 8, 8,L0|L1}, {&upd7810_device::SKIT_F2, 2, 8, 8,L0|L1}, + {&upd7810_device::SKIT_FST, 2, 8, 8,L0|L1}, {&upd7810_device::illegal2, 2, 8, 8,L0|L1}, + {&upd7810_device::illegal2, 2, 8, 8,L0|L1}, {&upd7810_device::illegal2, 2, 8, 8,L0|L1}, + {&upd7810_device::illegal2, 2, 8, 8,L0|L1}, {&upd7810_device::illegal2, 2, 8, 8,L0|L1}, + {&upd7810_device::SK_CY, 2, 8, 8,L0|L1}, {&upd7810_device::illegal2, 2, 8, 8,L0|L1}, + {&upd7810_device::SK_Z, 2, 8, 8,L0|L1}, {&upd7810_device::illegal2, 2, 8, 8,L0|L1}, + + {&upd7810_device::SKNIT_F0, 2, 8, 8,L0|L1}, {&upd7810_device::SKNIT_FT0, 2, 8, 8,L0|L1}, + {&upd7810_device::SKNIT_F1, 2, 8, 8,L0|L1}, {&upd7810_device::SKNIT_F2, 2, 8, 8,L0|L1}, + {&upd7810_device::SKNIT_FST, 2, 8, 8,L0|L1}, {&upd7810_device::illegal2, 2, 8, 8,L0|L1}, + {&upd7810_device::illegal2, 2, 8, 8,L0|L1}, {&upd7810_device::illegal2, 2, 8, 8,L0|L1}, + {&upd7810_device::illegal2, 2, 8, 8,L0|L1}, {&upd7810_device::illegal, 2, 8, 8,L0|L1}, + {&upd7810_device::SKN_CY, 2, 8, 8,L0|L1}, {&upd7810_device::illegal2, 2, 8, 8,L0|L1}, + {&upd7810_device::SKN_Z, 2, 8, 8,L0|L1}, {&upd7810_device::illegal2, 2, 8, 8,L0|L1}, + + /* 0x20 - 0x3F */ + {&upd7810_device::EI, 2, 8, 8,L0|L1}, {&upd7810_device::illegal2, 2, 8, 8,L0|L1}, + {&upd7810_device::illegal2, 2, 8, 8,L0|L1}, {&upd7810_device::illegal2, 2, 8, 8,L0|L1}, + {&upd7810_device::DI, 2, 8, 8,L0|L1}, {&upd7810_device::illegal2, 2, 8, 8,L0|L1}, + {&upd7810_device::illegal2, 2, 8, 8,L0|L1}, {&upd7810_device::illegal2, 2, 8, 8,L0|L1}, + {&upd7810_device::illegal2, 2, 8, 8,L0|L1}, {&upd7810_device::illegal2, 2, 8, 8,L0|L1}, + {&upd7810_device::CLC, 2, 8, 8,L0|L1}, {&upd7810_device::STC, 2, 8, 8,L0|L1}, + {&upd7810_device::PEN, 2,11,11,L0|L1}, {&upd7810_device::PEX, 2,11,11,L0|L1}, + + {&upd7810_device::RLL_A, 2, 8, 8,L0|L1}, {&upd7810_device::RLR_A, 2, 8, 8,L0|L1}, + {&upd7810_device::RLL_C, 2, 8, 8,L0|L1}, {&upd7810_device::RLR_C, 2, 8, 8,L0|L1}, + {&upd7810_device::SLL_A, 2, 8, 8,L0|L1}, {&upd7810_device::SLR_A, 2, 8, 8,L0|L1}, + {&upd7810_device::SLL_C, 2, 8, 8,L0|L1}, {&upd7810_device::SLR_C, 2, 8, 8,L0|L1}, + {&upd7810_device::RLD, 2,17,17,L0|L1}, {&upd7810_device::RRD, 2,17,17,L0|L1}, + {&upd7810_device::illegal2, 2, 8, 8,L0|L1}, {&upd7810_device::illegal2, 2, 8, 8,L0|L1}, + {&upd7810_device::PER, 2,11,11,L0|L1}, {&upd7810_device::illegal2, 2, 8, 8,L0|L1}, + + + 0x4cxx 0x4dxx 0x60xx