From e687507a3b343810537e16996918767985842f42 Mon Sep 17 00:00:00 2001 From: Shawn Quick Date: Thu, 9 Feb 2023 13:26:09 -0800 Subject: [PATCH] now able to push all test scripts to a directory that can be shared with gsplus, and files directly loaded into Merlin. Also support 'CHK' p-op to compare assemblies between the two --- Makefile | 4 +- asm.cpp | 114 +++++++++++++++++++++++++----------------------- asm.h | 3 +- opcodes.cpp | 65 ++++++++++++++++++++------- parms.json | 21 +++++++-- psuedo.cpp | 32 ++++++++++++++ psuedo.h | 5 +++ qoptions.h | 2 +- runtests.sh | 3 ++ single.sh | 3 +- test.s | 68 ++++++++++++++++------------- testdata/test.S | 1 + tomerlin.sh | 12 +++++ 13 files changed, 223 insertions(+), 110 deletions(-) create mode 120000 testdata/test.S create mode 100755 tomerlin.sh diff --git a/Makefile b/Makefile index af25d0d..ff2d79d 100644 --- a/Makefile +++ b/Makefile @@ -35,14 +35,14 @@ cider: -mkdir -p ./build -cd ./build && cmake -DCIDER=1 -DCMAKE_BUILD_TYPE=DEBUG .. && $(MAKE) $S - distclean: clean -rm -rf ./qasmout -rm -rf ./m32out -rm -rf ./libhfs/build ./nufxlib/build ./diskimg/build ./libpal/build clean: - -rm -rf ./build *.2mg test.bin + -rm -rf ./build *.2mg test.bin *_Output.txt _FileInforma*.txt testdata/*.bin testdata/Finder.Data + -rm -rf ./log_qasm ./testdata1 test depend: -cd ./build && $(MAKE) depend diff --git a/asm.cpp b/asm.cpp index 07a625c..c1d601a 100644 --- a/asm.cpp +++ b/asm.cpp @@ -150,15 +150,21 @@ void CLASS::print(uint32_t lineno) pcol += printf(" "); } - + string addrmode=options->addrModeEnglish(addressmode).c_str(); pcol+=printf("%s ",addrmode.c_str()); + pcol+=printf("/%04X ",flags); while(pcol<50) { pcol+=printf(" "); } - pcol+=printf("|"); + char sc=shiftchar; + if (sc==0) + { + sc=' '; + } + pcol+=printf("%c |",sc); } @@ -1624,57 +1630,75 @@ int CLASS::callOpCode(std::string op, MerlinLine &line) } } - if (line.addressmode == syn_imm) + if (line.addressmode == syn_imm) //page 83 merlin16 manual { //printf("immediate mode\n"); - switch (line.expr_shift) + switch (line.shiftchar) { case '<': //line.expr_value &= 0xFF; break; case '>': - line.expr_value >>= 8; + //line.expr_value >>= 8; //line.expr_value &= 0xFFFF; break; case '^': - line.expr_value = (line.expr_value >> 16); + //line.expr_value = (line.expr_value >> 16); //line.expr_value = (line.expr_value >> 16) & 0xFFFF; break; - case '|': + case '|': // should never get here, handled in getAddrMode //if (syntax == SYNTAX_MERLIN) if (options.isMerlin()) { - line.setError(errBadLabel); + line.setError(errBadOperand); line.expr_value = 0; } + //line.shiftchar=0; break; } } else { - switch (line.expr_shift) + switch (line.shiftchar) // page 84 Merlin16 manual { case '<': - line.flags |= FLAG_DP; + if (options.isMerlin32()) + { + line.flags |= FLAG_DP; + line.expr_value &= 0xFF; + } break; case '>': -#if 0 if (options.isMerlin32()) { // bug in M32 or not, do what it does - line.flags |= FLAG_FORCEABS; + //line.flags |= FLAG_FORCEABS; + line.flags |= FLAG_FORCELONG; } else -#endif { - line.flags |= FLAG_FORCELONG; + // Merlin16+ uses this to force long addressing + // need to check Merlin16 + if (!options.isMerlin()) // not merlin8 + { + line.flags |= FLAG_FORCELONG; + } + } break; case '|': - line.flags |= FLAG_FORCEABS; + if ((!options.isMerlin32()) && (options.isMerlinCompat())) + { + line.flags |= FLAG_FORCEABS; + //line.shiftchar=0; + } break; case '^': - //line.flags |= FLAG_FORCELONG; + if (options.isMerlin32()) + { + line.flags |= FLAG_DP; + line.expr_value >>= 16; + } break; } } @@ -1737,7 +1761,7 @@ const std::string valExpression = "^([^\\[,();]+)$"; // this one looks for ]variables const std::string varExpression = "([]]{1}[:0-9A-Z_a-z]{1}[0-9A-Z_a-z]*)"; -const std::string varMACExpression = "([]]{1}[:0-9]{1}[0-9]*)"; +const std::string macExpression = "([]]{1}[:0-9]{1}[0-9]*)"; // opcode check. emitted opcodes are compared against this // table, and if the XC status doesn't meet the requirements @@ -1798,7 +1822,7 @@ void CLASS::initpass(void) { trackrep = false; // can't turn this ON in M16 } - else if (options.isQASM()) + else if (options.isNative()) { // we will allow this to be settable default off trackrep = false; @@ -1920,30 +1944,6 @@ void CLASS::complete(void) if (f.is_open()) { -#if 0 - uint32_t lineno = 0; - uint32_t l = (uint32_t)lines.size(); - while (lineno < l) - { - MerlinLine &line = lines.at(lineno++); - if ((line.outbytect > 0) && ((line.flags & FLAG_INDUM) == 0)) - { - for (uint32_t i = 0; i < line.outbytect; i++) - { - f.put(line.outbytes[i]); - } - } - if ((line.datafillct > 0) && ((line.flags & FLAG_INDUM) == 0)) - { - for (uint32_t i = 0; i < line.datafillct; i++) - { - f.put(line.datafillbyte & 0xFF); - } - - } - } -#else - for (unsigned int i=0; i= 0) //{ - line.addressmode = x; + line.addressmode = x; //} int64_t value = -1; diff --git a/asm.h b/asm.h index 1814ca1..a6c7e6a 100644 --- a/asm.h +++ b/asm.h @@ -388,9 +388,10 @@ class TPsuedoOp; class T65816Asm : public TFileProcessor { protected: - std::vector outputbytes; public: + std::vector outputbytes; + // options bool casesen; bool showmx; diff --git a/opcodes.cpp b/opcodes.cpp index 27c592f..d4d13de 100644 --- a/opcodes.cpp +++ b/opcodes.cpp @@ -654,7 +654,7 @@ int CLASS::doBase6502(MerlinLine & line, TSymbol & sym) } if ((m == syn_absx) || (m == syn_abs) || (m == syn_absy)) { - if ((line.flags & FLAG_FORCEABS) || (line.expr_value >= 0x100)) + if ((line.flags & FLAG_FORCEABS) || (line.expr_value >= 0x100) ) { bytelen++; amode += 2; @@ -725,6 +725,7 @@ int CLASS::doBase6502(MerlinLine & line, TSymbol & sym) { if ((((line.flags & FLAG_DP) == 0) && ((line.flags & FLAG_FORCEDP) == 0)) || (line.flags & FLAG_FORCEABS) + || (m==syn_absy) ) { bytelen++; @@ -806,26 +807,58 @@ out: } res += bytelen; - //if (options.isMerlin32()) - { - if ((op==0xB9) || (op==0x79) || (op==0xF9) || (op==0x99)) - { - // there are 4 instructions that don't have (dp),y addressing so convert to (abs), - if (bytelen<2) - { - res++; - bytelen++; - } - } - } if ((pass > 0) && (res > 0)) { + int pidx=0; + uint8_t *ptr=(uint8_t *)&line.expr_value; setOpcode(line, op); + if (line.shiftchar!=0) + { + if (m==syn_imm) + { + switch(line.shiftchar) + { + case '>': + pidx+=1; + break; + case '^': + pidx+=2; + break; + } + } + else + { + switch(line.shiftchar) + { + case '>': + { + if ((line.flags&FLAG_FORCELONG)!=FLAG_FORCELONG) + { + pidx+=1; + } + } + break; + case '^': + { + + } + break; + } + } + } for (i = 0; i < (res - 1); i++) { - line.outbytes.push_back(line.expr_value >> (8 * i)); + if (pidx>3) // don't over index into 32 bit int + { + line.outbytes.push_back(0x00); + } + else + { + line.outbytes.push_back(ptr[pidx]); + pidx++; + } } line.outbytect = res; } @@ -941,6 +974,7 @@ void CLASS::insertOpcodes(void) pushopcode("PAG", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); pushopcode("TTL", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); pushopcode("SKP", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); + pushopcode("PAU", P_PAU, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); pushopcode("TR", P_TR, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); pushopcode("ASC", P_ASC, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); pushopcode("DCI", P_ASC, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); @@ -961,12 +995,11 @@ void CLASS::insertOpcodes(void) pushopcode("ELSE", P_DO, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); pushopcode("IF", P_DO, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); pushopcode("FIN", P_DO, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); - pushopcode("CHK", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); + pushopcode("CHK", P_CHK, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); pushopcode("ERR", P_ERR, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); pushopcode("KBD", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); pushopcode("LUP", P_LUP, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); 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", P_USR, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); pushopcode("MAC", P_MAC, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); diff --git a/parms.json b/parms.json index 035dd16..74c8c07 100644 --- a/parms.json +++ b/parms.json @@ -10,16 +10,29 @@ "1": "${QASM_BASE}" }, { - "2": "0/object" + "2": "0/source" }, { - "3": "1/macros" + "3": "0/object" }, { - "4": "1/toolmacs" + "4": "1/macros" }, { - "5": "../backup" + "5": "1/lib" + }, + { + "6": "1/commands" + }, + { + "7": "1/help" + }, + { + "8": "object", + "volume": "0/merlin.2mg", + "size": "800K", + "format": "prodos", + "fileformat": "2mg" } ] }, diff --git a/psuedo.cpp b/psuedo.cpp index 049a631..fe1df23 100644 --- a/psuedo.cpp +++ b/psuedo.cpp @@ -777,6 +777,32 @@ out: } +int CLASS::doPAU(T65816Asm &a, MerlinLine &line, TSymbol &opinfo) +{ + UNUSED(opinfo); + + return 0; +} + +int CLASS::doCHK(T65816Asm &a, MerlinLine &line, TSymbol &opinfo) +{ + int res=1; + + UNUSED(opinfo); + if (a.pass>0) + { + uint8_t val=0; + for (uint64_t i=0;i/dev/null cat ${FNAME}_Output.txt >OUTNAME +cat ${FNAME}_Output.txt qasm ${FNAME}.S -t merlin32 -i M65816 -o 0/${FNAME}.S.bin qasm ${FNAME}.S -t qasm -i M65816 -o 0/${FNAME}.S_q.bin diff --git a/test.s b/test.s index 1a5598d..f2686b4 100644 --- a/test.s +++ b/test.s @@ -10,14 +10,9 @@ xc off xc xc - lst - ;lst OFF + ZP equ $00 org $2000 - lda $04,y - adc $04,y - sbc $04,y - sta $04,y lda <$fff0 ;zp lda >$fff0 ;ABS (lo word) @@ -29,31 +24,35 @@ ZP equ $00 lda >$fff0+24 ;ABS (lo word) lda ^$fff0+24 ;ABS (hi word) lda |$fff0+24 ;ABS (long in 65816 mode) + ldal $fff0+24 ;ABS (long in 65816 mode) + lda: $fff0+24 ;ABS (long in 65816 mode) + lda: $00 + mx %11 lda #<$fff0 ;zp lda #>$fff0 ;ABS (lo word) lda #^$fff0 ;ABS (hi word) lda #<$FFF0+$FFFF lda #>$FFF0+$FFFF + lda #^$FFF0+$FFFF + mx %00 + lda #<$fff0 ;zp + lda #>$fff0 ;ABS (lo word) + lda #^$fff0 ;ABS (hi word) + lda #<$FFF0+$FFFF + lda #>$FFF0+$FFFF + lda #^$FFF0+$FFFF - - lst off - ;end - - - ora ($00) lda ($00) bit: $FFFE,X ror: $FFFE,X ora #ZP begin - ;]m equ * - ; lda begin - ; lda ]m - ;lst on - ;end + ;]m equ * + lda begin + ;lda ]m _mymac mac ]mac1 lda ]mac1 @@ -64,7 +63,6 @@ _mymac mac _ascmac mac asc ]1,]2,8D eom - ;lst off ;var 'one';'two';'three' justlable ;line with just a lable start @@ -73,23 +71,31 @@ another lda #$00 ;line with everything nop ;line with just opcode _mymac *;1 _mymac *;2 - _ascmac 'hello';'there' - - lup 2 -]m equ * - nop - lda ]m - bra ]m - --^ - sav 2/test.bin - end + ;_ascmac 'hello';'there' + ;lup 2 + ;]m equ * + ;nop + ;lda ]m + ;bra ]m + ;--^ ]1 nop nop - ;lst - bra ]1 + ;bra ]1 ;typ $06 db 255 - ;lst off +]DPNOP equ $80 + lda ]DPNOP + jsr DPCODE + rts + org $0080 +DPCODE nop + lda DPCODE + lda |DPCODE + lda >DPCODE + + lst + chk + lst off diff --git a/testdata/test.S b/testdata/test.S new file mode 120000 index 0000000..84ccdec --- /dev/null +++ b/testdata/test.S @@ -0,0 +1 @@ +../test.s \ No newline at end of file diff --git a/tomerlin.sh b/tomerlin.sh new file mode 100755 index 0000000..99aba74 --- /dev/null +++ b/tomerlin.sh @@ -0,0 +1,12 @@ +#!/bin/bash +rm -rf ./testdata1/* +cp -r ./testdata/*.S testdata1/ +cd ./testdata1 +X=`ls *.S` + +for F in $X ; do + UFNAME=`echo $F | tr '[:lower:]' '[:upper:]'` + qasm -x format-merlin $F >${UFNAME} + rm -rf $F +done +ls