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 16:23:49 Functions: 100.0 % 3 3
Branches: 60.5 % 124 75

             Branch data     Line data    Source code
       1                 :             : #include "asar.h"
       2                 :             : #include "warnings.h"
       3                 :             : #include "errors.h"
       4                 :             : #include "assembleblock.h"
       5                 :             : #include "asar_math.h"
       6                 :             : 
       7                 :             : #include "arch-shared.h"
       8                 :             : 
       9                 :             : #define write1 write1_pick
      10                 :             : 
      11                 :         281 : void asinit_65816()
      12                 :             : {
      13                 :         281 : }
      14                 :             : 
      15                 :         255 : void asend_65816()
      16                 :             : {
      17                 :         255 : }
      18                 :             : 
      19                 :             : extern bool fastrom;
      20                 :             : extern int recent_opcode_num;
      21                 :             : 
      22                 :      110776 : bool asblock_65816(char** word, int numwords)
      23                 :             : {
      24                 :             : #define is(test) (!stricmpwithupper(word[0], test))
      25                 :             : //#define par word[1]
      26                 :      110776 :         string par;
      27         [ +  + ]:      110776 :         if (word[1]) par = word[1];
      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 init(left, right) strip_suffix(par, right); strip_prefix(par, left); getvars(false)
      36                 :             : #define init_index(left, right) itrim(par, left, right); getvars(false)
      37                 :             : #define bankoptinit(left) strip_prefix(par, left); getvars(true)
      38                 :             : #define blankinit() len=1; explicitlen=false; num=0
      39                 :             : #define end() return false
      40                 :             : #define as0(    op, byte) if (is(op)          ) { write1((unsigned int)byte);              return true; }
      41                 :             : #define as1(    op, byte) if (is(op) && len==1) { write1((unsigned int)byte); write1(num); return true; }
      42                 :             : #define as2(    op, byte) if (is(op) && len==2) { write1((unsigned int)byte); write2(num); return true; } \
      43                 :             :                                                                                                         /*if (is(op) && len==3 && emulate) { write1(byte); write2(num); return true; }*/
      44                 :             : #define as3(    op, byte) if (is(op) && len==3) { write1((unsigned int)byte); write3(num); return true; }
      45                 :             : //#define as23(   op, byte) if (is(op) && (len==2 || len==3)) { write1(byte); write2(num); return true; }
      46                 :             : #define as32(   op, byte) if (is(op) && ((len==2 && !explicitlen) || len==3)) { write1((unsigned int)byte); write3(num); return true; }
      47                 :             : #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); } \
      48                 :             :                                                                                                                                                                          else { write1((unsigned int)byte); write2(num); } return true; }
      49                 :             : #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); } \
      50                 :             :                                                                                                                                                                          else {  write1((unsigned int)byte); write2(num); } return true; }
      51                 :             : #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; }
      52                 :             : #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); \
      53                 :             :                                                                                                         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()); \
      54                 :             :                                                                                                         return true; }
      55                 :             : #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);\
      56                 :             :                                                                                         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()); \
      57                 :             :                                                                                         return true; }
      58                 :             : #define the8(offset, len) as##len("ORA", offset+0x00); as##len("AND", offset+0x20); as##len("EOR", offset+0x40); as##len("ADC", offset+0x60); \
      59                 :             :                                                                                                         as##len("STA", offset+0x80); as##len("LDA", offset+0xA0); as##len("CMP", offset+0xC0); as##len("SBC", offset+0xE0)
      60                 :             : #define thenext8(offset, len) as##len("ASL", offset+0x00); as##len("BIT", offset+0x1E); as##len("ROL", offset+0x20); as##len("LSR", offset+0x40); \
      61                 :             :                                                                                                                         as##len("ROR", offset+0x60); as##len("LDY", offset+0x9E); as##len("DEC", offset+0xC0); as##len("INC", offset+0xE0)
      62                 :             : #define thefinal7(offset, len) as##len("TSB", offset+0x00); as##len("TRB", offset+0x10); as##len("STY", offset+0x80); as##len("STX", offset+0x82); \
      63                 :             :                                                                                                                          as##len("LDX", offset+0xA2); as##len("CPY", offset+0xC0); as##len("CPX", offset+0xE0)
      64                 :             : #define onlythe8(left, right, offset) else if (match(left, right)) do { init_index(left, right); the8(offset, 1); end(); } while(0)
      65   [ +  +  +  +  :      110776 :         else if ((strlen(word[0])!=3 && (strlen(word[0])!=5 || word[0][3]!='.')) || (word[1] && word[2])) return false;
          +  +  +  +  +  
                      + ]
      66         [ +  + ]:        2167 :         else if (!word[1])
      67                 :             :         {
      68                 :             :                 blankinit();
      69                 :         570 :                 as0("PHP", 0x08); as0("ASL", 0x0A); as0("PHD", 0x0B); as0("CLC", 0x18);
      70                 :         561 :                 as0("INC", 0x1A); as0("TCS", 0x1B); as0("PLP", 0x28); as0("ROL", 0x2A);
      71                 :         555 :                 as0("PLD", 0x2B); as0("SEC", 0x38); as0("DEC", 0x3A); as0("TSC", 0x3B);
      72                 :         546 :                 as0("RTI", 0x40); as0("PHA", 0x48); as0("LSR", 0x4A); as0("PHK", 0x4B);
      73                 :         537 :                 as0("CLI", 0x58); as0("PHY", 0x5A); as0("TCD", 0x5B); as0("RTS", 0x60);
      74                 :         525 :                 as0("PLA", 0x68); as0("ROR", 0x6A); as0("RTL", 0x6B); as0("SEI", 0x78);
      75                 :         516 :                 as0("PLY", 0x7A); as0("TDC", 0x7B); as0("DEY", 0x88); as0("TXA", 0x8A);//these tables are blatantly stolen from xkas
      76                 :         504 :                 as0("PHB", 0x8B); as0("TYA", 0x98); as0("TXS", 0x9A); as0("TXY", 0x9B);
      77                 :         492 :                 as0("TAY", 0xA8); as0("TAX", 0xAA); as0("PLB", 0xAB); as0("CLV", 0xB8);
      78                 :         480 :                 as0("TSX", 0xBA); as0("TYX", 0xBB); as0("INY", 0xC8); as0("DEX", 0xCA);
      79                 :         468 :                 as0("WAI", 0xCB); as0("CLD", 0xD8); as0("PHX", 0xDA); as0("STP", 0xDB);
      80                 :         456 :                 as0("INX", 0xE8); as0("NOP", 0xEA); as0("XBA", 0xEB); as0("SED", 0xF8);
      81                 :          15 :                 as0("PLX", 0xFA); as0("XCE", 0xFB);
      82                 :           9 :                 as1("BRK", 0x00); as1("COP", 0x02); as1("WDM", 0x42);
      83                 :             :                 //as0("DEA", 0x3A); as0("INA", 0x1A); as0("TAD", 0x5B); as0("TDA", 0x7B);//nobody cares about these, but keeping them does no harm
      84                 :             :                 //as0("TAS", 0x1B); as0("TSA", 0x3B); as0("SWA", 0xEB);                  //actually, it does: it may make some users think it's correct.
      85                 :             :                 end();
      86                 :             :         }
      87         [ +  + ]:        1597 :         else if (!stricmp(word[1], "A"))
      88                 :             :         {
      89                 :             :                 blankinit();
      90                 :          21 :                 as0("ASL", 0x0A); as0("LSR", 0x4A); as0("ROL", 0x2A); as0("ROR", 0x6A);
      91                 :           9 :                 as0("INC", 0x1A); as0("DEC", 0x3A);
      92                 :           3 :                 goto opAFallback;//yay goto
      93                 :             :         }
      94   [ +  +  -  + ]:        1576 :         else if (match("#", ""))
      95                 :             :         {
      96                 :         231 :                 bankoptinit('#');
      97                 :         230 :                 as_a("ORA", 0x09); as_a("AND", 0x29); as_a("EOR", 0x49); as_a("ADC", 0x69);
      98                 :         177 :                 as_a("BIT", 0x89); as_a("LDA", 0xA9); as_a("CMP", 0xC9); as_a("SBC", 0xE9);
      99                 :         102 :                 as_xy("CPX", 0xE0); as_xy("CPY", 0xC0); as_xy("LDX", 0xA2); as_xy("LDY", 0xA0);
     100                 :          75 :                 as_rep("ASL", 0x0A); as_rep("LSR", 0x4A); as_rep("ROL", 0x2A); as_rep("ROR", 0x6A);
     101                 :          51 :                 as_rep("INC", 0x1A); as_rep("DEC", 0x3A); as_rep("INX", 0xE8); as_rep("DEX", 0xCA);
     102                 :         141 :                 as_rep("INY", 0xC8); as_rep("DEY", 0x88); as_rep("NOP", 0xEA);
     103                 :          18 :                 as1("REP", 0xC2); as1("SEP", 0xE2);
     104                 :          12 :                 as1("BRK", 0x00); as1("COP", 0x02); as1("WDM", 0x42);
     105                 :             :                 end();
     106                 :             :         }
     107                 :        1345 :         onlythe8("(", ",s),y", 0x13);
     108                 :        1321 :         onlythe8("[", "],y", 0x17);
     109                 :        1297 :         onlythe8("(", "),y", 0x11);
     110                 :        1273 :         onlythe8("", ",s", 0x03);
     111   [ +  +  -  + ]:        1249 :         else if (match("[", "]"))
     112                 :             :         {
     113                 :          33 :                 init('[', ']');
     114                 :          33 :                 the8(0x07, 1);
     115                 :           9 :                 as2("JMP", 0xDC); as2("JML", 0xDC);
     116                 :             :                 end();
     117                 :             :         }
     118   [ +  +  +  + ]:        1216 :         else if (match("(", ",x)"))
     119                 :             :         {
     120                 :          30 :                 init_index("(", ",x)");
     121                 :          30 :                 the8(0x01, 1);
     122                 :           6 :                 as2("JMP", 0x7C); as2("JSR", 0xFC);
     123                 :             :                 end();
     124                 :             :         }
     125   [ +  +  +  -  :        1186 :         else if (match("(", ")") && confirmqpar(substr(word[1]+1, (int)(strlen(word[1]+1)-1))))
             +  -  +  + ]
     126                 :             :         {
     127                 :          30 :                 init('(', ')');
     128                 :          30 :                 the8(0x12, 1);
     129                 :           6 :                 as1("PEI", 0xD4);
     130                 :           3 :                 as2("JMP", 0x6C);
     131                 :             :                 end();
     132                 :             :         }
     133   [ +  -  +  -  :        1156 :         else if (match("", ",x"))
                   +  + ]
     134                 :             :         {
     135                 :         258 :                 init_index("", ",x");
     136   [ +  -  -  +  :         258 :                 if (match("(", ")") && confirmqpar(substr(word[1] + 1, (int)(strlen(word[1] + 1) - 2 - 1)))) asar_throw_warning(0, warning_id_65816_yy_x_does_not_exist);
          -  -  -  -  -  
                +  -  - ]
     137                 :         258 :                 the8(0x1F, 3);
     138                 :         208 :                 the8(0x1D, 2);
     139                 :         159 :                 the8(0x15, 1);
     140                 :         111 :                 thenext8(0x16, 1);
     141                 :          63 :                 thenext8(0x1E, 2);
     142                 :          15 :                 as1("STZ", 0x74);
     143                 :           9 :                 as1("STY", 0x94);
     144                 :           6 :                 as2("STZ", 0x9E);
     145                 :             :                 end();
     146                 :             :         }
     147   [ +  -  +  -  :         898 :         else if (match("", ",y"))
                   +  + ]
     148                 :             :         {
     149                 :          39 :                 init_index("", ",y");
     150   [ -  +  -  - ]:          39 :                 if (len==3 && emulatexkas) len=2;
     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   [ +  +  +  +  :         859 :                 if ((is("MVN") || is("MVP")) && confirmqpar(par))
             +  -  +  - ]
     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                 :             :                         snes_label tmp;
     180   [ +  +  +  -  :           3 :                         if (pass && !labelval(par, &tmp)) return false;
             -  +  -  + ]
     181                 :           3 :                         len=getlen(par);
     182                 :             :                         num=tmp.pos;
     183                 :             :                 }
     184   [ +  +  +  + ]:         856 :                 if (is("JSR") || is("JMP"))
     185                 :             :                 {
     186                 :          27 :                         int tmp=optimizeforbank;
     187                 :          27 :                         optimizeforbank=-1;
     188                 :          27 :                         getvars(false)
     189                 :          27 :                         optimizeforbank=tmp;
     190                 :             :                 }
     191                 :             :                 else
     192                 :             :                 {
     193                 :         829 :                         getvars(false)
     194                 :             :                 }
     195                 :         856 :                 the8(0x0F, 3);
     196                 :         796 :                 the8(0x0D, 2);
     197                 :         715 :                 the8(0x05, 1);
     198                 :         658 :                 thenext8(0x06, 1);
     199                 :         610 :                 thenext8(0x0E, 2);
     200                 :         562 :                 thefinal7(0x04, 1);
     201                 :         520 :                 thefinal7(0x0C, 2);
     202                 :         478 :                 as1("STZ", 0x64);
     203                 :         472 :                 as2("STZ", 0x9C);
     204                 :         466 :                 as2("JMP", 0x4C);
     205                 :         460 :                 as2("JSR", 0x20);
     206                 :         439 :                 as32("JML", 0x5C);
     207                 :         430 :                 as32("JSL", 0x22);
     208                 :         400 :                 as2("MVN", 0x54);
     209                 :         400 :                 as2("MVP", 0x44);
     210                 :         400 :                 as2("PEA", 0xF4);
     211         [ +  + ]:         397 :                 if (emulatexkas)
     212                 :             :                 {
     213                 :          15 :                         asar_throw_warning(0, warning_id_feature_deprecated, "usage of jmp instead of jml ", "use jml instead");
     214                 :          15 :                         as3("JMP", 0x5C);//all my hate
     215                 :             :                         //as3("JSR", 0x22);
     216                 :             :                 }
     217                 :         397 :                 as_rel1("BRA", 0x80);
     218                 :         391 :                 as_rel1("BCC", 0x90);
     219                 :         388 :                 as_rel1("BCS", 0xB0);
     220                 :         385 :                 as_rel1("BEQ", 0xF0);
     221                 :         379 :                 as_rel1("BNE", 0xD0);
     222                 :         376 :                 as_rel1("BMI", 0x30);
     223                 :         373 :                 as_rel1("BPL", 0x10);
     224                 :         370 :                 as_rel1("BVC", 0x50);
     225                 :         367 :                 as_rel1("BVS", 0x70);
     226                 :         364 :                 as_rel2("BRL", 0x82);
     227                 :         361 :                 as_rel2("PER", 0x62);
     228                 :             :                 end();
     229                 :             :         }
     230                 :             :         return true;
     231                 :      110776 : }
        

Generated by: LCOV version 2.0-1