LCOV - code coverage report
Current view: top level - asar - arch-65816.cpp (source / functions) Coverage Total Hit
Test: asar.info Lines: 99.2 % 120 119
Test Date: 2024-01-15 17:20:38 Functions: 100.0 % 3 3
Branches: 63.5 % 96 61

             Branch data     Line data    Source code
       1                 :             : #include "asar.h"
       2                 :             : #include "assembleblock.h"
       3                 :             : #include "asar_math.h"
       4                 :             : 
       5                 :             : #define write1 write1_pick
       6                 :             : 
       7                 :         335 : void asinit_65816()
       8                 :             : {
       9                 :         335 : }
      10                 :             : 
      11                 :         309 : void asend_65816()
      12                 :             : {
      13                 :         309 : }
      14                 :             : 
      15                 :             : extern bool fastrom;
      16                 :             : extern int recent_opcode_num;
      17                 :             : 
      18                 :        7588 : bool asblock_65816(char** word, int numwords)
      19                 :             : {
      20                 :             : #define is(test) (!stricmpwithupper(word[0], test))
      21                 :             : //#define par word[1]
      22         [ +  + ]:        7588 :         if(word[0][0] == '\'') return false;
      23                 :        7387 :         string par;
      24         [ +  + ]:       13909 :         for(int i = 1; i < numwords; i++){
      25         [ +  + ]:        6522 :                 if(i > 1) par += " ";
      26                 :        6522 :                 par += word[i];
      27                 :             :         }
      28                 :             :         unsigned int num;
      29                 :             :         int len=0;//declared here for A->generic fallback
      30                 :             :         bool explicitlen = false;
      31                 :             :         bool hexconstant = false;
      32                 :             :         if(0);
      33                 :             : #define getvars(optbank) num=(pass==2)?getnum(par):0; hexconstant=is_hex_constant(par); if (word[0][3]=='.') { len=getlenfromchar(word[0][4]); explicitlen=true; word[0][3]='\0'; } else {len=getlen(par, optbank); explicitlen=false;}
      34                 :             : #define match(left, right) (word[1] && stribegin(par, left) && striend(par, right))
      35                 :             : #define matchr(right) (word[1] && striend(par, right))
      36                 :             : #define matchl(left) (word[1] && stribegin(par, left))
      37                 :             : #define init(left, right) par.strip_suffix(right); par.strip_prefix(left); getvars(false)
      38                 :             : #define init_index(left, right) itrim(par, left, right); getvars(false)
      39                 :             : #define bankoptinit(left) par.strip_prefix(left); getvars(true)
      40                 :             : #define blankinit() len=1; explicitlen=false; num=0
      41                 :             : #define end() return false
      42                 :             : #define as0(    op, byte) if (is(op)          ) { write1((unsigned int)byte);              return true; }
      43                 :             : #define as1(    op, byte) if (len==1 && is(op)) { write1((unsigned int)byte); write1(num); return true; }
      44                 :             : #define as2(    op, byte) if (len==2 && is(op)) { write1((unsigned int)byte); write2(num); return true; }
      45                 :             : #define as3(    op, byte) if (len==3 && is(op)) { write1((unsigned int)byte); write3(num); return true; }
      46                 :             : //#define as23(   op, byte) if (is(op) && (len==2 || len==3)) { write1(byte); write2(num); return true; }
      47                 :             : #define as32(   op, byte) if (is(op) && ((len==2 && !explicitlen) || len==3)) { write1((unsigned int)byte); write3(num); return true; }
      48                 :             : #define as_a(   op, byte) if (is(op)) { if(!explicitlen && !hexconstant) asar_throw_warning(0, warning_id_implicitly_sized_immediate); if (len==1) { write1(byte); write1(num); } \
      49                 :             :                                                                                                                                                                          else { write1((unsigned int)byte); write2(num); } return true; }
      50                 :             : #define as_xy(  op, byte) if (is(op)) { if(!explicitlen && !hexconstant) asar_throw_warning(0, warning_id_implicitly_sized_immediate); if (len==1) { write1(byte); write1(num); } \
      51                 :             :                                                                                                                                                                          else {  write1((unsigned int)byte); write2(num); } return true; }
      52                 :             : #define as_rep( op, byte) if (is(op)) { if (pass<2) { num=getnum(par); } if(foundlabel) asar_throw_error(0, error_type_block, error_id_no_labels_here); for (unsigned int i=0;i<num;i++) { write1((unsigned int)byte); } recent_opcode_num = num; return true; }
      53                 :             : #define as_rel1(op, byte) if (is(op)) { int pos=(!foundlabel)?(int)num:(int)num-((snespos&0xFFFFFF)+2); write1((unsigned int)byte); write1((unsigned int)pos); \
      54                 :             :                                                                                                         if (pass==2 && foundlabel && (pos<-128 || pos>127)) asar_throw_error(2, error_type_block, error_id_relative_branch_out_of_bounds, dec(pos).data()); \
      55                 :             :                                                                                                         return true; }
      56                 :             : #define as_rel2(op, byte) if (is(op)) { int pos=(!foundlabel)?(int)num:(int)num-((snespos&0xFFFFFF)+3); write1((unsigned int)byte); write2((unsigned int)pos);\
      57                 :             :                                                                                         if (pass==2 && foundlabel && (pos<-32768 || pos>32767)) asar_throw_error(2, error_type_block, error_id_relative_branch_out_of_bounds, dec(pos).data()); \
      58                 :             :                                                                                         return true; }
      59                 :             : #define the8(offset, len) as##len("ORA", offset+0x00); as##len("AND", offset+0x20); as##len("EOR", offset+0x40); as##len("ADC", offset+0x60); \
      60                 :             :                                                                                                         as##len("STA", offset+0x80); as##len("LDA", offset+0xA0); as##len("CMP", offset+0xC0); as##len("SBC", offset+0xE0)
      61                 :             : #define thenext8(offset, len) as##len("ASL", offset+0x00); as##len("BIT", offset+0x1E); as##len("ROL", offset+0x20); as##len("LSR", offset+0x40); \
      62                 :             :                                                                                                                         as##len("ROR", offset+0x60); as##len("LDY", offset+0x9E); as##len("DEC", offset+0xC0); as##len("INC", offset+0xE0)
      63                 :             : #define thefinal7(offset, len) as##len("TSB", offset+0x00); as##len("TRB", offset+0x10); as##len("STY", offset+0x80); as##len("STX", offset+0x82); \
      64                 :             :                                                                                                                          as##len("LDX", offset+0xA2); as##len("CPY", offset+0xC0); as##len("CPX", offset+0xE0)
      65                 :             : #define onlythe8(left, right, offset) else if (match(left, right)) do { init_index(left, right); the8(offset, 1); end(); } while(0)
      66   [ +  +  +  +  :        7387 :         else if ((strlen(word[0])!=3 && (strlen(word[0])!=5 || word[0][3]!='.'))) return false;
                   +  + ]
      67         [ +  + ]:        2262 :         else if (numwords == 1)
      68                 :             :         {
      69                 :             :                 blankinit();
      70                 :         606 :                 as0("PHP", 0x08); as0("ASL", 0x0A); as0("PHD", 0x0B); as0("CLC", 0x18);
      71                 :         597 :                 as0("INC", 0x1A); as0("TCS", 0x1B); as0("PLP", 0x28); as0("ROL", 0x2A);
      72                 :         591 :                 as0("PLD", 0x2B); as0("SEC", 0x38); as0("DEC", 0x3A); as0("TSC", 0x3B);
      73                 :         582 :                 as0("RTI", 0x40); as0("PHA", 0x48); as0("LSR", 0x4A); as0("PHK", 0x4B);
      74                 :         573 :                 as0("CLI", 0x58); as0("PHY", 0x5A); as0("TCD", 0x5B); as0("RTS", 0x60);
      75                 :         561 :                 as0("PLA", 0x68); as0("ROR", 0x6A); as0("RTL", 0x6B); as0("SEI", 0x78);
      76                 :         552 :                 as0("PLY", 0x7A); as0("TDC", 0x7B); as0("DEY", 0x88); as0("TXA", 0x8A);//these tables are blatantly stolen from xkas
      77                 :         540 :                 as0("PHB", 0x8B); as0("TYA", 0x98); as0("TXS", 0x9A); as0("TXY", 0x9B);
      78                 :         528 :                 as0("TAY", 0xA8); as0("TAX", 0xAA); as0("PLB", 0xAB); as0("CLV", 0xB8);
      79                 :         516 :                 as0("TSX", 0xBA); as0("TYX", 0xBB); as0("INY", 0xC8); as0("DEX", 0xCA);
      80                 :         504 :                 as0("WAI", 0xCB); as0("CLD", 0xD8); as0("PHX", 0xDA); as0("STP", 0xDB);
      81                 :         492 :                 as0("INX", 0xE8); as0("NOP", 0xEA); as0("XBA", 0xEB); as0("SED", 0xF8);
      82                 :          15 :                 as0("PLX", 0xFA); as0("XCE", 0xFB);
      83                 :           9 :                 as1("BRK", 0x00); as1("COP", 0x02); as1("WDM", 0x42);
      84                 :             :                 //as0("DEA", 0x3A); as0("INA", 0x1A); as0("TAD", 0x5B); as0("TDA", 0x7B);//nobody cares about these, but keeping them does no harm
      85                 :             :                 //as0("TAS", 0x1B); as0("TSA", 0x3B); as0("SWA", 0xEB);                  //actually, it does: it may make some users think it's correct.
      86                 :             :                 end();
      87                 :             :         }
      88         [ +  + ]:        1656 :         else if (!stricmp(word[1], "A"))
      89                 :             :         {
      90                 :             :                 blankinit();
      91                 :          21 :                 as0("ASL", 0x0A); as0("LSR", 0x4A); as0("ROL", 0x2A); as0("ROR", 0x6A);
      92                 :           9 :                 as0("INC", 0x1A); as0("DEC", 0x3A);
      93                 :           3 :                 goto opAFallback;//yay goto
      94                 :             :         }
      95         [ +  + ]:        1635 :         else if (matchl("#"))
      96                 :             :         {
      97                 :         231 :                 bankoptinit('#');
      98                 :         227 :                 as_a("ORA", 0x09); as_a("AND", 0x29); as_a("EOR", 0x49); as_a("ADC", 0x69);
      99                 :         174 :                 as_a("BIT", 0x89); as_a("LDA", 0xA9); as_a("CMP", 0xC9); as_a("SBC", 0xE9);
     100                 :          99 :                 as_xy("CPX", 0xE0); as_xy("CPY", 0xC0); as_xy("LDX", 0xA2); as_xy("LDY", 0xA0);
     101                 :          72 :                 as_rep("ASL", 0x0A); as_rep("LSR", 0x4A); as_rep("ROL", 0x2A); as_rep("ROR", 0x6A);
     102                 :          48 :                 as_rep("INC", 0x1A); as_rep("DEC", 0x3A); as_rep("INX", 0xE8); as_rep("DEX", 0xCA);
     103                 :         138 :                 as_rep("INY", 0xC8); as_rep("DEY", 0x88); as_rep("NOP", 0xEA);
     104                 :          15 :                 as1("REP", 0xC2); as1("SEP", 0xE2);
     105                 :           9 :                 as1("BRK", 0x00); as1("COP", 0x02); as1("WDM", 0x42);
     106                 :             :                 end();
     107                 :             :         }
     108                 :        1404 :         onlythe8("(", ",s),y", 0x13);
     109                 :        1380 :         onlythe8("[", "],y", 0x17);
     110                 :        1356 :         onlythe8("(", "),y", 0x11);
     111                 :        1332 :         onlythe8("", ",s", 0x03);
     112   [ +  +  -  + ]:        1308 :         else if (match("[", "]"))
     113                 :             :         {
     114                 :          33 :                 init('[', ']');
     115                 :          33 :                 the8(0x07, 1);
     116                 :           9 :                 as2("JMP", 0xDC); as2("JML", 0xDC);
     117                 :             :                 end();
     118                 :             :         }
     119   [ +  +  +  + ]:        1275 :         else if (match("(", ",x)"))
     120                 :             :         {
     121                 :          30 :                 init_index("(", ",x)");
     122                 :          30 :                 the8(0x01, 1);
     123                 :           6 :                 as2("JMP", 0x7C); as2("JSR", 0xFC);
     124                 :             :                 end();
     125                 :             :         }
     126   [ +  +  -  + ]:        1245 :         else if (match("(", ")"))
     127                 :             :         {
     128                 :          30 :                 init('(', ')');
     129                 :          30 :                 the8(0x12, 1);
     130                 :           6 :                 as1("PEI", 0xD4);
     131                 :           3 :                 as2("JMP", 0x6C);
     132                 :             :                 end();
     133                 :             :         }
     134         [ +  + ]:        1215 :         else if (matchr(",x"))
     135                 :             :         {
     136                 :         255 :                 init_index("", ",x");
     137   [ +  -  -  +  :         255 :                 if (match("(", ")")) asar_throw_warning(0, warning_id_65816_yy_x_does_not_exist);
             -  -  -  - ]
     138                 :         255 :                 the8(0x1F, 3);
     139                 :         207 :                 the8(0x1D, 2);
     140                 :         159 :                 the8(0x15, 1);
     141                 :         111 :                 thenext8(0x16, 1);
     142                 :          63 :                 thenext8(0x1E, 2);
     143                 :          15 :                 as1("STZ", 0x74);
     144                 :           9 :                 as1("STY", 0x94);
     145                 :           6 :                 as2("STZ", 0x9E);
     146                 :             :                 end();
     147                 :             :         }
     148         [ +  + ]:         960 :         else if (matchr(",y"))
     149                 :             :         {
     150                 :          39 :                 init_index("", ",y");
     151                 :          39 :                 as1("LDX", 0xB6);
     152                 :          33 :                 as1("STX", 0x96);
     153                 :          30 :                 as2("LDX", 0xBE);
     154   [ -  +  -  -  :          24 :                 if (len==1 && (is("ORA") || is("AND") || is("EOR") || is("ADC") || is("STA") || is("LDA") || is("CMP") || is("SBC")))
          -  -  -  -  -  
          -  -  -  -  -  
             -  -  -  - ]
     155                 :             :                 {
     156                 :           0 :                         asar_throw_warning(0, warning_id_65816_xx_y_assume_16_bit, word[0]);
     157                 :             :                         len=2;
     158                 :             :                 }
     159                 :          24 :                 the8(0x19, 2);
     160                 :             :                 end();
     161                 :             :         }
     162                 :             :         else
     163                 :             :         {
     164   [ +  +  +  + ]:         921 :                 if ((is("MVN") || is("MVP")))
     165                 :             :                 {
     166                 :             :                         int numargs;
     167         [ +  - ]:           6 :                         autoptr<char**>param=qpsplit(par.temp_raw(), ',', &numargs);
     168         [ +  - ]:           6 :                         if (numargs ==2)
     169                 :             :                         {
     170   [ +  +  +  - ]:           9 :                                 write1(is("MVN")?(unsigned int)0x54:(unsigned int)0x44);
     171   [ +  +  +  -  :           6 :                                 write1(pass==2?getnum(param[0]):0);
                   +  - ]
     172   [ +  +  +  -  :           6 :                                 write1(pass==2?getnum(param[1]):0);
                   +  - ]
     173                 :             :                                 return true;
     174                 :             :                         }
     175                 :           6 :                 }
     176                 :             :                 if (false)
     177                 :             :                 {
     178                 :             : opAFallback:
     179                 :           3 :                         snes_label tmp;
     180   [ +  +  +  -  :           3 :                         if (pass && !labelval(par, &tmp)) return false;
             -  +  -  + ]
     181                 :           3 :                         len=getlen(par);
     182                 :             :                         num=tmp.pos;
     183                 :             :                 }
     184   [ +  +  +  + ]:         918 :                 if (is("JSR") || is("JMP"))
     185                 :             :                 {
     186                 :          24 :                         int tmp=optimizeforbank;
     187                 :          24 :                         optimizeforbank=-1;
     188                 :          24 :                         getvars(false)
     189                 :          24 :                         optimizeforbank=tmp;
     190                 :             :                 }
     191                 :             :                 else
     192                 :             :                 {
     193                 :         894 :                         getvars(false)
     194                 :             :                 }
     195                 :         917 :                 the8(0x0F, 3);
     196                 :         846 :                 the8(0x0D, 2);
     197                 :         744 :                 the8(0x05, 1);
     198                 :         684 :                 thenext8(0x06, 1);
     199                 :         636 :                 thenext8(0x0E, 2);
     200                 :         588 :                 thefinal7(0x04, 1);
     201                 :         546 :                 thefinal7(0x0C, 2);
     202                 :         504 :                 as1("STZ", 0x64);
     203                 :         498 :                 as2("STZ", 0x9C);
     204                 :         492 :                 as2("JMP", 0x4C);
     205                 :         489 :                 as2("JSR", 0x20);
     206                 :         468 :                 as32("JML", 0x5C);
     207                 :         462 :                 as32("JSL", 0x22);
     208                 :         432 :                 as2("MVN", 0x54);
     209                 :         432 :                 as2("MVP", 0x44);
     210                 :         432 :                 as2("PEA", 0xF4);
     211                 :         429 :                 as_rel1("BRA", 0x80);
     212                 :         426 :                 as_rel1("BCC", 0x90);
     213                 :         423 :                 as_rel1("BCS", 0xB0);
     214                 :         420 :                 as_rel1("BEQ", 0xF0);
     215                 :         414 :                 as_rel1("BNE", 0xD0);
     216                 :         411 :                 as_rel1("BMI", 0x30);
     217                 :         408 :                 as_rel1("BPL", 0x10);
     218                 :         405 :                 as_rel1("BVC", 0x50);
     219                 :         402 :                 as_rel1("BVS", 0x70);
     220                 :         399 :                 as_rel2("BRL", 0x82);
     221                 :         396 :                 as_rel2("PER", 0x62);
     222                 :             :                 end();
     223                 :             :         }
     224                 :             :         return false;
     225                 :        7387 : }
        

Generated by: LCOV version 2.0-1