diff --git a/opcodes.cpp b/opcodes.cpp index 26c5c03..f796b77 100644 --- a/opcodes.cpp +++ b/opcodes.cpp @@ -884,7 +884,7 @@ void CLASS::insertOpcodes(void) pushopcode("--^", P_LUP, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); pushopcode("PAU", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); pushopcode("SW", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); - pushopcode("USR", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); + pushopcode("USR", P_USR, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); pushopcode("MAC", P_MAC, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); pushopcode("EOM", P_MAC, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); pushopcode("<<<", P_MAC, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); diff --git a/psuedo.cpp b/psuedo.cpp index 36b512e..5145891 100644 --- a/psuedo.cpp +++ b/psuedo.cpp @@ -695,6 +695,74 @@ out: return bytect; } +static int usr_hash(std::string os) { + int hash = 0; + + os.resize(4, ' '); + os = Poco::toUpper(os); + + hash = (os[0] & 0x1f) << 11; + hash |= (os[1] & 0x1f) << 6; + hash |= (os[2] & 0x1f) << 1; + if (os[3] == 'L') hash |= 0x01; + + return hash; +} + +/* + handler for USR. generates a 2-byte opcode hash + USR $00 - equivalent to DW $0 (qasm) + USR 'ADC ' - hashes the 4-byte string (qasm) + USR ADC - hashes the 1-4 byte symbol (merlin) + */ +int CLASS::doUSR(T65816Asm &a, MerlinLine &line, TSymbol &opinfo) +{ + UNUSED(opinfo); + + line.eval_result = 0; // since this is an data p-op, clear the global 'bad operand' flag + + std::string os = Poco::trim(line.operand); + uint32_t bytect = 2; + uint32_t hash = 0; + + char c = os.empty() ? 0 : os.front(); + + if (c == '$' && os.length() > 1) { + + for (uint32_t i = 1; i < os.length(); ++i) + { + char hv = hexVal(os[i]); + if (hv < 0) { + line.setError(errIllegalCharOperand); + bytect = 0; + goto out; + } + hash <<= 4; + hash |= hv; + } + + } else if ((c == '\'' || c == '\"') && os.front() == os.back() && os.length() == 6) { + hash = usr_hash(os.substr(1, 4)); + } else if (os.length() > 0 && os.length() <= 4) { + hash = usr_hash(os); + } else { + printf("line.setError(errBadOperand);\n"); + line.setError(errBadOperand); + bytect = 0; + goto out; + } + + if (a.pass > 0) { + line.outbytes.push_back(hash & 0xff); + line.outbytes.push_back(hash >> 8); + } + +out: + line.outbytect = bytect; + return bytect; + +} + // the handler for STR,STRL,REV,FLS,INV,DCI,ASC int CLASS::doASC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo) { @@ -1008,6 +1076,11 @@ int CLASS::ProcessOpcode(T65816Asm &a, MerlinLine &line, TSymbol &opinfo) case P_ASC: res = doASC(a, line, opinfo); break; + + case P_USR: + res = doUSR(a, line, opinfo); + break; + } return (res); } diff --git a/psuedo.h b/psuedo.h index 809cb54..87e7a27 100644 --- a/psuedo.h +++ b/psuedo.h @@ -22,6 +22,7 @@ enum P_ERR, P_MAC, P_CAS, + P_USR, P_MAX }; @@ -44,6 +45,7 @@ public: int doTR(T65816Asm &a, MerlinLine &line, TSymbol &opinfo); int doASC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo); int doMAC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo); + int doUSR(T65816Asm &a, MerlinLine &line, TSymbol &opinfo); }; diff --git a/testdata/3004-usr-qasm.S b/testdata/3004-usr-qasm.S new file mode 100644 index 0000000..bd449b6 --- /dev/null +++ b/testdata/3004-usr-qasm.S @@ -0,0 +1,198 @@ + + usr $00 + usr '>>> ' + usr '= ' + usr '<<< ' + usr $00 + usr $00 + usr $00 + usr 'XC- ' + usr 'XCE ' + usr 'XC ' + usr 'XBA ' + usr 'WDM ' + usr 'WAI ' + usr 'VAR ' + usr 'USR ' ;*** change this + usr 'USE ' + usr 'TYX ' + usr 'TYP ' + usr 'TYA ' + usr 'TXY ' + usr 'TXS ' + usr 'TXA ' + usr 'TTL ' + usr 'TSX ' + usr 'TSC ' + usr 'TSB ' + usr 'TSA ' + usr 'TRB ' + usr 'TR ' + usr 'TDC ' + usr 'TDA ' + usr 'TCS ' + usr 'TCD ' + usr 'TBX ' + usr 'TAY ' + usr 'TAX ' + usr 'TAS ' + usr 'TAD ' + usr 'SYM ' + usr 'SWA ' + usr 'STZ ' + usr 'STY ' + usr 'STX ' + usr 'STRL' + usr 'STR ' + usr 'STP ' + usr 'STAL' + usr 'STA ' + usr 'SKP ' + usr 'SEP ' + usr 'SEI ' + usr 'SED ' + usr 'SEC ' + usr 'SBCL' + usr 'SBC ' + usr 'SAV ' + usr 'RTS ' + usr 'RTL ' + usr 'RTI ' + usr 'ROR ' + usr 'ROL ' + usr 'RND ' + usr 'REV ' + usr 'REP ' + usr 'REL ' + usr $00 + usr 'PUT ' + usr 'PMC ' + usr 'PLY ' + usr 'PLX ' + usr 'PLP ' + usr 'PLD ' + usr 'PLB ' + usr 'PLA ' + usr 'PHY ' + usr 'PHX ' + usr 'PHP ' + usr 'PHK ' + usr 'PHD ' + usr 'PHB ' + usr 'PHA ' + usr 'PER ' + usr 'PEK ' + usr 'PEI ' + usr 'PEA ' + usr 'PAU ' + usr 'PAG ' + usr 'ORG ' + usr 'ORAL' + usr 'ORA ' + usr 'OBJ ' + usr 'NOP ' + usr 'MX ' + usr 'MVP ' + usr 'MVN ' + usr 'MTX ' + usr '--^ ' + usr 'MAC ' + usr 'LUP ' + usr 'LSTL' + usr 'LST ' + usr 'LSR ' + usr 'LIB ' + usr 'LDY ' + usr 'LDX ' + usr 'LDAL' + usr 'LDA ' + usr 'KBD ' + usr 'JSR ' + usr 'JSL ' + usr 'JMP ' + usr 'JML ' + usr 'INY ' + usr 'INX ' + usr 'INV ' + usr 'INC ' + usr 'INA ' + usr 'IF ' + usr 'HEX ' + usr $00 + usr 'FLS ' + usr 'FLO ' + usr 'FIN ' + usr 'EXT ' + usr 'EXP ' + usr 'EXD ' + usr 'EVL ' + usr 'ERR ' + usr 'EQU ' + usr 'EORL' + usr 'EOR ' + usr 'EOM ' + usr 'ENT ' + usr 'END ' + usr 'ENC ' + usr 'ELS ' + usr 'DW ' + usr 'DUP ' + usr 'DUM ' + usr 'DSK ' + usr 'DS ' + usr 'DO ' + usr 'DL ' + usr 'DFS ' + usr 'DFB ' + usr 'DEY ' + usr 'DEX ' + usr 'DEN ' + usr 'DEC ' + usr 'DEA ' + usr 'DDB ' + usr 'DCI ' + usr 'DBY ' + usr 'DB ' + usr 'DAT ' + usr 'DA ' + usr 'CYC ' + usr 'CRC ' + usr 'CPY ' + usr 'CPX ' + usr 'COP ' + usr 'CMPL' + usr 'CMP ' + usr 'CLV ' + usr 'CLI ' + usr 'CLD ' + usr 'CLC ' + usr 'CHK ' + usr 'CAS ' + usr 'BYT ' + usr 'BVS ' + usr 'BVC ' + usr 'BTR ' + usr 'BRL ' + usr 'BRK ' + usr 'BRA ' + usr 'BPL ' + usr 'BNE ' + usr 'BMI ' + usr 'BLT ' + usr 'BIT ' + usr 'BGE ' + usr 'BFL ' + usr 'BEQ ' + usr 'BEL ' + usr 'BCS ' + usr 'BCC ' + usr 'AST ' + usr 'ASL ' + usr 'ASC ' + usr 'ANDL' + usr 'AND ' + usr 'ADRL' + usr 'ADR ' + usr 'ADCL' + usr 'ADC ' + usr $00 \ No newline at end of file diff --git a/testdata/3005-usr-merlin.S b/testdata/3005-usr-merlin.S new file mode 100644 index 0000000..4a8d38a --- /dev/null +++ b/testdata/3005-usr-merlin.S @@ -0,0 +1,193 @@ +*====================================== +* Opcode table; must be in alpha order. +*-------------------------------------- + + HEX 0000 +CODES USR ADC + ERR *-CODES-2 + USR ADCL + USR ADR + USR ADRL + USR ALI ;Linker + USR AND + USR ANDL + USR ASC + USR ASL + USR ASM ;Linker + USR AST + USR BCC + USR BCS + USR BEQ + USR BGE + USR BIT + USR BLT + USR BMI + USR BNE + USR BPL + USR BRA + USR BRK + USR BRL + USR BVC + USR BVS + USR CAS + USR CHK + USR CLC + USR CLD + USR CLI + USR CLV + USR CMD ;Linker + USR CMP + USR CMPL + USR COP + USR CPX + USR CPY + USR CYC + USR DA + USR DAT + USR DB + USR DCI + USR DDB + USR DEC + USR DEND + USR DEX + USR DEY + USR DFB + USR DO + USR DS + USR DSK + USR DUM + USR DW + USR ELS + USR END + USR ENT + USR EOM + USR EOR + USR EORL + USR EQU + USR ERR + USR EXD + USR EXP + USR EXT + USR FAS ;Linker + USR FIN + USR FLO + USR FLS + USR GEQ ;Linker + USR HEX + USR IF + USR INC + USR INV + USR INX + USR INY + USR JML + USR JMP + USR JMPL + USR JSL + USR JSR + USR KBD + USR KIN ;Linker + USR KND ;Linker + USR LDA + USR LDAL + USR LDX + USR LDY + USR LEN ;Linker + USR LIB ;Linker + USR LIN ;Linker + USR LKV ;Linker + USR LNK ;Linker + USR LSR + USR LST + USR LSTL ;Packs as LSTDO is interpd + USR LUP + USR MAC + USR --^ + USR MVN + USR MVP + USR MX + USR NOL ;Linker + USR NOP + USR OBJ + USR ORA + USR ORAL + USR ORG + USR OVR ;Linker +MIDOP USR PAG + USR PAU + USR PEA + USR PEI + USR PER + USR PHA + USR PHB + USR PHD + USR PHK + USR PHP + USR PHX + USR PHY + USR PLA + USR PLB + USR PLD + USR PLP + USR PLX + USR PLY + USR PMC + USR POS ;Linker + USR REL + USR REP + USR REV + USR ROL + USR ROR + USR RTI + USR RTL + USR RTS + USR SAV + USR SBC + USR SBCL + USR SEC + USR SED + USR SEI + USR SEP + USR SKP + USR STA + USR STAL + USR STP + USR STR + USR STRL + USR STX + USR STY + USR STZ + USR SWA + USR TAD + USR TAS + USR TAX + USR TAY + USR TCD + USR TCS + USR TDA + USR TDC + USR TR + USR TRB + USR TSA + USR TSB + USR TSC + USR TSX + USR TTL + USR TXA + USR TXS + USR TXY + USR TYA + USR TYP + USR TYX + USR USR + USR VAR + USR VER ;Linker + USR WAI + USR WDM + USR XBA + USR XC + USR XCE + USR XREF + USR <<< + USR = + USR >>> +OPCODES