X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=blobdiff_plain;f=6502.c;h=5978240a5bfe53be35059fb0b6820c78e6653532;hp=0e203f098b5dadc6c0647b065a791fb933d5f244;hb=9153334781cd2e23750f4dc002e847606c07a1f0;hpb=ff2052bcaa1428a33a202822a81a6f9b8e567ef4 diff --git a/6502.c b/6502.c index 0e203f0..5978240 100644 --- a/6502.c +++ b/6502.c @@ -1,5 +1,9 @@ // -// 6502 Assembler +// RMAC - Reboot's Macro Assembler for all Atari computers +// 6502.C - 6502 Assembler +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends +// RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 +// Source utilised with the kind permission of Landon Dyer // // Init6502 initialization // d_6502 handle ".6502" directive @@ -19,12 +23,13 @@ #define UPSEG_SIZE 0x10010L // size of 6502 code buffer, 64K+16bytes -// +// Internal vars +static uint16_t orgmap[1024][2]; // Mark all 6502 org changes + // Exported vars -// const char in_6502mode[] = "directive illegal in .6502 section"; -static uint16_t orgmap[1024][2]; // Mark all 6502 org changes uint16_t * currentorg = &orgmap[0][0]; // Current org range +char strtoa8[128]; // ASCII to Atari 800 internal conversion table // // 6502 addressing modes; @@ -145,6 +150,22 @@ static int abs2zp[] = -1 // ZPY }; +static char a8internal[] = +{ + ' ', 0, '!', 1, '"', 2, '#', 3, '$', 4, '%', 5, '&', 6, '\'', 7, + '(', 8, ')', 9, '*', 10, '+', 11, ',', 12, '-', 13, '.', 14, '/', 15, + '0', 16, '1', 17, '2', 18, '3', 19, '4', 20, '5', 21, '6', 22, '7', 23, + '8', 24, '9', 25, ':', 26, ';', 27, '<', 28, '=', 29, '>', 30, '?', 31, + '@', 32, 'A', 33, 'B', 34, 'C', 35, 'D', 36, 'E', 37, 'F', 38, 'G', 39, + 'H', 40, 'I', 41, 'J', 42, 'K', 43, 'L', 44, 'M', 45, 'N', 46, 'O', 47, + 'P', 48, 'Q', 49, 'R', 50, 'S', 51, 'T', 52, 'U', 53, 'V', 54, 'W', 55, + 'X', 56, 'Y', 57, 'Z', 58, '[', 59, '\\', 60, ']', 61, '^', 62, '_', 63, + 'a', 97, 'b', 98, 'c', 99, 'd', 100, 'e', 101, 'f', 102, 'g', 103, 'h', 104, + 'i', 105, 'j', 106, 'k', 107, 'l', 108, 'm', 109, 'n', 110, 'o', 111, 'p', 112, + 'q', 113, 'r', 114, 's', 115, 't', 116, 'u', 117, 'v', 118, 'w', 119, 'x', 120, + 'y', 121, 'z', 122 +}; + // // Initialize 6502 assembler @@ -186,6 +207,24 @@ void Init6502() // Set up first org section (set to zero) orgmap[0][0] = 0; + + SwitchSection(M6502); // Switch to 6502 section + + // Initialise string conversion table(s) + char * p = a8internal; + memset(strtoa8, 31, 128); // 31=fallback value ("?") + + for(; pchptr, 0, UPSEG_SIZE); + } + + SwitchSection(TEXT); // Go back to TEXT } @@ -197,13 +236,6 @@ int d_6502() SaveSection(); // Save curent section SwitchSection(M6502); // Switch to 6502 section - if (challoc == 0) - { - // Allocate and clear 64K of space for the 6502 section - chcheck(UPSEG_SIZE); - memset(sect[M6502].scode->chptr, 0, UPSEG_SIZE); - } - return 0; } @@ -215,7 +247,7 @@ void m6502cg(int op) { register int amode; // (Parsed) addressing mode register int i; - VALUE eval; // Expression value + uint64_t eval; // Expression value WORD eattr; // Expression attributes int zpreq; // 1, optimize instr to zero-page form register char * p; // (Temp) string usage @@ -226,7 +258,7 @@ void m6502cg(int op) // zpreq = 0; - switch ((int)*tok) + switch (tok[0]) { case EOL: amode = A65_IMPL; @@ -238,6 +270,7 @@ void m6502cg(int op) if (*tok == '>') { tok++; + if (expr(exprbuf, &eval, &eattr, NULL) < 0) return; @@ -247,6 +280,7 @@ void m6502cg(int op) else if (*tok == '<') { tok++; + if (expr(exprbuf, &eval, &eattr, NULL) < 0) return; @@ -275,7 +309,8 @@ void m6502cg(int op) tok++; p = string[tok[1]]; - if (*tok != SYMBOL || p[1] != EOS || (*p | 0x20) != 'y') // Sleazo tolower() + // Sleazo tolower() -----------------vvvvvvvvvvv + if (*tok != SYMBOL || p[1] != EOS || (*p | 0x20) != 'y') goto badmode; tok += 2; @@ -290,7 +325,8 @@ void m6502cg(int op) tok++; p = string[tok[1]]; - if (*tok != SYMBOL || p[1] != EOS || (*p | 0x20) != 'x') // Sleazo tolower() + // Sleazo tolower() -----------------vvvvvvvvvvv + if (*tok != SYMBOL || p[1] != EOS || (*p | 0x20) != 'x') goto badmode; tok += 2; @@ -345,7 +381,12 @@ void m6502cg(int op) // 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 ',' @@ -369,6 +410,7 @@ void m6502cg(int op) } not_coinop: +#endif if (expr(exprbuf, &eval, &eattr, NULL) < 0) return; @@ -550,8 +592,6 @@ badmode: // Generate 6502 object output file. // // ggn: converted into a com/exe/xex output format -// Notes: 1. The $FFFF is only mandatory for the first segment, but let's dump it everywhere for now -// 2. It's still dumping pages instead of more fine grained stuff. Should look into this - a8 people don't like waste so much ;) void m6502obj(int ofd) { uint16_t exeheader[3]; @@ -571,9 +611,13 @@ void m6502obj(int ofd) { exeheader[1] = l[0]; exeheader[2] = l[1] - 1; - size_t unused = write(ofd, headpoint, headsize); // Write header + + // Write header + size_t unused = write(ofd, headpoint, headsize); unused = write(ofd, p + l[0], l[1] - l[0]); - headpoint = &exeheader[1]; // Skip the $FFFF after first segment, it's not mandatory + + // Skip the $FFFF after first segment, it's not mandatory + headpoint = &exeheader[1]; headsize = 4; } }