X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=blobdiff_plain;f=6502.c;h=4397b0748bf446531317d3413908c4c6afb9bae5;hp=ef95a0ce128c0111b6f5fc613b36f200b281e2cf;hb=HEAD;hpb=7d0d2b9ecddea35722fd1d09c99735b98f6f0362 diff --git a/6502.c b/6502.c index ef95a0c..66f2080 100644 --- a/6502.c +++ b/6502.c @@ -1,7 +1,7 @@ // -// RMAC - Reboot's Macro Assembler for all Atari computers +// RMAC - Renamed Macro Assembler for all Atari computers // 6502.C - 6502 Assembler -// Copyright (C) 199x Landon Dyer, 2011-2019 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2021 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // @@ -21,8 +21,9 @@ #include "sect.h" #include "token.h" -#define DEF_KW -#include "kwtab.h" +#define DEF_REG65 +#define DECL_REG65 +#include "6502regs.h" #define UPSEG_SIZE 0x10010L // size of 6502 code buffer, 64K+16bytes @@ -238,6 +239,11 @@ int d_6502() { SaveSection(); // Save curent section SwitchSection(M6502); // Switch to 6502 section + regbase = reg65base; // Update register DFA tables + regtab = reg65tab; + regcheck = reg65check; + regaccept = reg65accept; + used_architectures |= M6502; return 0; } @@ -249,30 +255,26 @@ int d_6502() void m6502cg(int op) { register int amode; // (Parsed) addressing mode - register int i; - uint64_t eval; // Expression value - WORD eattr; // Expression attributes - int zpreq; // 1, optimize instr to zero-page form - register char * p; // (Temp) string usage + uint64_t eval = -1; // Expression value + WORD eattr = 0; // Expression attributes + int zpreq = 0; // 1 = optimize instr to zero-page form ch_size = 0; // Reset chunk size on every instruction // // Parse 6502 addressing mode // - zpreq = 0; - switch (tok[0]) { case EOL: amode = A65_IMPL; break; - case KW_A: + case REG65_A: if (tok[1] != EOL) goto badmode; - amode = A65_IMPL; tok++; + amode = A65_IMPL; break; case '#': @@ -281,28 +283,19 @@ void m6502cg(int op) if (*tok == '>') { tok++; - - if (expr(exprbuf, &eval, &eattr, NULL) < 0) - return; - amode = A65_IMMEDH; - break; } else if (*tok == '<') { tok++; - - if (expr(exprbuf, &eval, &eattr, NULL) < 0) - return; - amode = A65_IMMEDL; - break; } + else + amode = A65_IMMED; if (expr(exprbuf, &eval, &eattr, NULL) < 0) return; - amode = A65_IMMED; break; case '(': @@ -318,53 +311,21 @@ void m6502cg(int op) { // (foo),y tok++; -#if 0 - p = string[tok[1]]; - - // Sleazo tolower() -----------------vvvvvvvvvvv - if (*tok != SYMBOL || p[1] != EOS || (*p | 0x20) != 'y') - goto badmode; - - tok += 2; amode = A65_INDY; -#else - if (tok[0] == KW_Y) - amode = A65_INDY; - if (tok[1] != EOL) + if (tok[0] != REG65_Y) goto badmode; tok++; -#endif } else amode = A65_IND; } - else if (*tok == ',') + else if ((tok[0] == ',') && (tok[1] == REG65_X) && (tok[2] == ')')) { // (foo,x) - tok++; -#if 0 - p = string[tok[1]]; - - // Sleazo tolower() -----------------vvvvvvvvvvv - if (*tok != SYMBOL || p[1] != EOS || (*p | 0x20) != 'x') - goto badmode; - - tok += 2; - if (*tok++ != ')') - goto badmode; - + tok += 3; amode = A65_INDX; -#else - if (tok[0] == KW_X) - amode = A65_INDX; - - if ((tok[1] != ')') || (tok[2] != EOL)) - goto badmode; - - tok += 2; -#endif } else goto badmode; @@ -382,35 +343,18 @@ void m6502cg(int op) if (*tok == '(') { tok++; -#if 0 - p = string[tok[1]]; - if (*tok != SYMBOL || p[1] != EOS || tok[2] != ')' || tok[3] != EOL) - goto badmode; - - i = (*p | 0x20); // Sleazo tolower() - - if (i == 'x') - amode = A65_INDX; - else if (i == 'y') - amode = A65_INDY; - else - goto badmode; - - tok += 3; // Past SYMBOL ')' EOL -#else if ((tok[1] != ')') || (tok[2] != EOL)) goto badmode; - if (tok[0] == KW_X) + if (tok[0] == REG65_X) amode = A65_INDX; - else if (tok[0] == KW_Y) + else if (tok[0] == REG65_Y) amode = A65_INDY; else goto badmode; tok += 2; -#endif zpreq = 1; // Request zeropage optimization } else if (*tok == EOL) @@ -421,88 +365,30 @@ void m6502cg(int op) break; default: - // - // Short-circuit - // x,foo - // y,foo - // - p = string[tok[1]]; - // ggn: the following code is effectively disabled as it would make - // single letter labels not work correctly (would not identify the - // label properly). And from what I understand it's something to - // keep compatibility with the coinop assembler which is probably - // something we don't care about much :D -#if 0 - if (*tok == SYMBOL && p[1] == EOS && tok[2] == ',') - { - tok += 3; // Past: SYMBOL ',' - i = (*p | 0x20); - - if (i == 'x') - amode = A65_ABSX; - else if (i == 'y') - amode = A65_ABSY; - else - goto not_coinop; - - if (expr(exprbuf, &eval, &eattr, NULL) < 0) - return; - - if (*tok != EOL) - goto badmode; - - zpreq = 1; - break; - } - -not_coinop: -#endif + // + // ,x + // ,y if (expr(exprbuf, &eval, &eattr, NULL) < 0) return; - zpreq = 1; + zpreq = 1; // Request zeropage optimization - if (*tok == EOL) + if (tok[0] == EOL) amode = A65_ABS; - else if (*tok == ',') + else if (tok[0] == ',') { tok++; -#if 0 - p = string[tok[1]]; - - if (*tok != SYMBOL || p[1] != EOS) - goto badmode; - tok += 2; - - // - // Check for X or Y index register; - // the OR with 0x20 is a sleazo conversion - // to lower-case that actually works. - // - i = *p | 0x20; // Oooh, this is slimey (but fast!) - - if (i == 'x') - amode = A65_ABSX; - else if (i == 'y') - amode = A65_ABSY; - else - goto badmode; -#else - if (tok[0] == KW_X) + if (tok[0] == REG65_X) { - amode = A65_ABSX; tok++; + amode = A65_ABSX; } - else if (tok[0] == KW_Y) + else if (tok[0] == REG65_Y) { - amode = A65_ABSY; tok++; + amode = A65_ABSY; } - - if (tok[0] != EOL) - goto badmode; -#endif } else goto badmode; @@ -519,17 +405,17 @@ badmode: // o ZPX or ZPY is illegal, or // o expr is zeropage && zeropageRequest && expression is defined // - if (inf[op][amode] == ILLEGAL // If current op is illegal, - || (eval < 0x100 // or expr must be zero-page - && zpreq != 0 // amode must request zero-page opt. - && (eattr & DEFINED))) // and the expression must be defined + if ((inf[op][amode] == ILLEGAL) // If current op is illegal OR + || (zpreq // amode requested a zero-page optimize + && (eval < 0x100) // and expr is zero-page + && (eattr & DEFINED))) // and the expression is defined { - i = abs2zp[amode]; // i = zero-page translation of amode + int i = abs2zp[amode]; // Get zero-page translation of amode #ifdef DO_DEBUG DEBUG printf(" OPT: op=%d amode=%d i=%d inf[op][i]=%d\n", op, amode, i, inf[op][i]); #endif - if (i >= 0 && (inf[op][i] & 0xFF) != ILLEGAL) // Use it if it's legal + if (i >= 0 && (inf[op][i] & 0xFF) != ILLEGAL) // & use it if it's legal amode = i; } @@ -538,6 +424,8 @@ badmode: DEBUG printf("inf[op][amode]=%d\n", (int)inf[op][amode]); #endif + GENLINENOSYM(); + switch (inf[op][amode]) { case A65_IMPL: // Just leave the instruction @@ -635,8 +523,9 @@ badmode: // default: case ILLEGAL: - for(i=0; i<3; i++) - D_byte(NOP); + D_byte(NOP); + D_byte(NOP); + D_byte(NOP); error("illegal 6502 addressing mode"); } @@ -681,3 +570,52 @@ void m6502obj(int ofd) } } + +// Write raw 6502 org'd code. +// Super copypasta'd from above function +void m6502raw(int ofd) +{ + CHUNK * ch = sect[M6502].scode; + + // If no 6502 code was generated, bail out + if ((ch == NULL) || (ch->challoc == 0)) + return; + + register uint8_t *p = ch->chptr; + + for(uint16_t * l=&orgmap[0][0]; lchalloc == 0)) + return; + + if (currentorg != &orgmap[1][0]) + { + // More than one 6502 section created, this is not allowed + error("when generating C64 .PRG files only one org section is allowed - aborting"); + return; + } + + SETLE16(header, 0, orgmap[0][0]); + register uint8_t * p = ch->chptr; + + // Write header + uint32_t unused = write(ofd, header, 2); + // Write the data + unused = write(ofd, p + orgmap[0][0], orgmap[0][1] - orgmap[0][0]); +}