diff --git a/sdas/linksrc/aslink.h b/sdas/linksrc/aslink.h index 94c2b7b..c2426c0 100644 --- a/sdas/linksrc/aslink.h +++ b/sdas/linksrc/aslink.h @@ -367,20 +367,30 @@ extern int ASxxxx_VERSION; #define R_BIT 0x400 /* Linker will convert from byte-addressable * space to bit-addressable space. */ #define R_ESCAPE_MASK 0xf0 /* Used to escape relocation modes * greater than 0xff in the .rel * file. */ /* end sdld specific */ +/* Options for platform specific virtual address translation +* +* +*/ +#define PLATFORM_NONE 0 /* Default address handling */ +#define PLATFORM_SMS 1 /* SMS/GG specific virtual address handling */ + +#define PLATFORM_SMS_STR "sms" +/* end sdld specific */ + /* * ASLINK - Version 4 Definitions */ /* * The "A4_" area constants define values used in * generating the assembler area output data. * * Area flags @@ -1030,20 +1040,22 @@ extern int xflag; /* Map file radix type flag #if SDCDB extern int yflag; /* -y, enable SDCC Debug output */ #endif extern int pflag; /* print linker command file flag */ extern int uflag; /* Listing relocation flag */ +extern int platform; /* Select platform specific virtual address translation + */ extern int wflag; /* Enable wide format listing */ extern int zflag; /* Disable symbol case sensitivity */ extern int radix; /* current number conversion radix: * 2 (binary), 8 (octal), 10 (decimal), * 16 (hexadecimal) */ extern int line; /* current line number */ @@ -1151,20 +1163,21 @@ extern char * strrchr(); /* Program function definitions */ #ifdef OTHERSYSTEM /* lkmain.c */ extern FILE * afile(char *fn, char *ft, int wf); extern VOID bassav(void); extern int fndidx(char *str); extern int fndext(char *str); +extern VOID platset(void); extern VOID gblsav(void); extern int intsiz(void); extern VOID iramsav(void); extern VOID xramsav(void); extern VOID codesav(void); extern VOID iramcheck(void); extern VOID link_main(void); extern VOID lkexit(int i); extern int main(int argc, char *argv[]); extern VOID map(void); diff --git a/sdas/linksrc/lkarea.c b/sdas/linksrc/lkarea.c index 77e6f84..612b7e7 100644 --- a/sdas/linksrc/lkarea.c +++ b/sdas/linksrc/lkarea.c @@ -314,20 +314,22 @@ lkparea(char *id) * local variables: * a_uint rloc ;current relocation address * char temp[] ;temporary string * struct symbol *sp ;symbol structure * * global variables: * area *ap Pointer to the current * area structure * area *areap The pointer to the first * area structure of a linked list + * int platform selects platform specific + * virtual address translation * * functions called: * int fprintf() c_library * VOID lnksect() lkarea.c * symbol *lkpsym() lksysm.c * char * strncpy() c_library * int symeq() lksysm.c * * side effects: * All area and areax addresses and sizes are @@ -417,20 +419,34 @@ lnkarea(void) if(!strncmp(ap->a_id, "_CODE_", 6) && atoi(ap->a_id+6)!=0) { // set sane default values for rom banking // 0x4000 is correct for MBC1,2,3,5,7 ap->a_addr = (atoi(ap->a_id+6) << 16) + 0x4000; } if(!strncmp(ap->a_id, "_DATA_", 6)) { // set sane default values for ram banking ap->a_addr = (atoi(ap->a_id+6) << 16) + 0xA000; } } + // Z80 sms/gg virtual address / mapper handling + if (TARGET_IS_Z80 && (platform == PLATFORM_SMS) && ap->a_addr == 0) { + // Standard sega sms/gg mapper used by most + if (!strncmp(ap->a_id, "_CODE_", 6) && atoi(ap->a_id+6)!=0) { + ap->a_addr = (atoi(ap->a_id+6) << 16) + 0x4000; + } + if (!strncmp(ap->a_id, "_LIT_", 5) && atoi(ap->a_id+5)!=0) { + ap->a_addr = (atoi(ap->a_id+5) << 16) + 0x8000; + } + if (!strncmp(ap->a_id, "_DATA_", 6)) { + // set sane default values for ram banking + ap->a_addr = (atoi(ap->a_id+6) << 16) + 0x8000; + } + } if (ap->a_flag & A3_ABS) { /* * Absolute sections */ lnksect(ap); } else { /* sdld specific */ /* Determine memory space */ locIndex = 0; if ((TARGET_IS_8051)) { diff --git a/sdas/linksrc/lkdata.c b/sdas/linksrc/lkdata.c index 169e8c1..8edc81c 100644 --- a/sdas/linksrc/lkdata.c +++ b/sdas/linksrc/lkdata.c @@ -77,20 +77,22 @@ int yflag; /* SDCDB output flag #endif int mflag; /* Map output flag */ int xflag; /* Map file radix type flag */ int pflag; /* print linker command file flag */ int uflag; /* Listing relocation flag */ +int platform; /* Select platform specific virtual address translation + */ int wflag; /* Enable wide format listing */ int zflag; /* Disable symbol case sensitivity */ int radix; /* current number conversion radix: * 2 (binary), 8 (octal), 10 (decimal), * 16 (hexadecimal) */ int line; /* current line number */ @@ -141,20 +143,22 @@ a_uint v_mask; /* Value Mask */ int gline; /* LST file relocation active * for current line */ int gcntr; /* LST file relocation active * counter */ /* sdld specific */ char *optsdcc; char *optsdcc_module; +int platform = PLATFORM_NONE; /* Select platform specific virtual address translation + */ int sflag; /* JCF: Memory usage output flag */ int stacksize=0; /* JCF: Stack size */ int aflag; /* Overlapping area warning flag */ int rflag; /* Extended linear address record flag. */ a_uint iram_size; /* internal ram size */ diff --git a/sdas/linksrc/lkmain.c b/sdas/linksrc/lkmain.c index daf5515..7998409 100644 --- a/sdas/linksrc/lkmain.c +++ b/sdas/linksrc/lkmain.c @@ -219,20 +219,24 @@ main(int argc, char *argv[]) j = i; k = 1; while((c = argv[j][k]) != '\0') { ip = ib; sprintf(ip, "-%c", c); switch(c) { /* * Options with arguments */ + case 'a': + case 'A': + pflag = 0; + case 'b': case 'B': case 'g': case 'G': case 'k': case 'K': case 'l': @@ -241,21 +245,21 @@ main(int argc, char *argv[]) case 'f': case 'F': case 'I': case 'X': case 'C': case 'S': strcat(ip, " "); if (i < argc - 1) strcat(ip, argv[++i]); - else + else strcpy(ip, ""); break; /* * Preprocess these commands */ case 'n': case 'N': pflag = 0; break; @@ -897,29 +901,31 @@ map(void) * ASCII character * lfile *lfp pointer to current lfile structure * being processed by parse() * lfile *linkp pointer to first lfile structure * containing an input REL file * specification * int mflag Map output flag * int oflag Output file type flag * int objflg Linked file/library output object flag * int pflag print linker command file flag + * int platform Selects platform specific virtual address translation * FILE * stderr c_library * int uflag Relocated listing flag * int xflag Map file radix type flag * int wflag Wide listing format * int zflag Disable symbol case sensitivity * * Functions called: * VOID addlib() lklibr.c * VOID addpath() lklibr.c + * VOID platset() lkmain.c * VOID bassav() lkmain.c * VOID doparse() lkmain.c * int fprintf() c_library * VOID gblsav() lkmain.c * VOID getfid() lklex.c * int get() lklex.c * int getnb() lklex.c * VOID lkexit() lkmain.c * char * strsto() lksym.c * int strlen() c_library @@ -939,20 +945,27 @@ parse() while ((c = getnb()) != 0) { /* sdld specific */ if ( c == ';') return(0); /* end sdld specific */ if ( c == '-') { while (ctype[c=get()] & LETTER) { switch(c) { + case 'a': + case 'A': + if (is_sdld() && (TARGET_IS_Z80)) { + platset(); + } + return(0); + case 'C': if (is_sdld() && !(TARGET_IS_Z80 || TARGET_IS_GB)) { codesav(); return(0); } // else fall through case 'c': if (startp->f_type != 0) break; startp->f_type = F_STD; @@ -1220,20 +1233,57 @@ doparse() } if((sfp != NULL) && (sfp != stdin)) { fclose(sfp); } sfp = NULL; startp->f_idp = ""; startp->f_idx = 0; startp->f_type = 0; } +/*)Function VOID platset() + * + * The function platset() sets variable which stores platform + * specific virtual address translation. + * + * local variables: + * none + * + * global variables: + * int platform selects platform specific + * virtual address translation + * char *ip pointer into the REL file + * text line in ib[] + * + * functions called: + * int fprintf() c_library + * int getnb() lklex.c + * int strcmp() c_library + * VOID unget() lklex.c + * + * side effects: + * The basep structure is created. + */ + +VOID +platset() +{ + unget(getnb()); + if (strcmp(ip, PLATFORM_SMS_STR) == 0) { + platform = PLATFORM_SMS; + return; + } + fprintf(stderr, + "No matching platform found for: %s\n", ip); +} + + /*)Function VOID bassav() * * The function bassav() creates a linked structure containing * the base address strings input to the linker. * * local variables: * none * * global variables: * base *basep The pointer to the first @@ -1824,20 +1874,21 @@ char *usetxt_z80_gb[] = { " -n No echo of commands to stdout", "Alternates to Command Line Input:", " -c ASlink >> prompt input", " -f file[.lk] Command File input", "Libraries:", " -k Library path specification, one per -k", " -l Library file specification, one per -l", "Relocation:", " -b area base address = expression", " -g global symbol = expression", + " -a (platform) Select platform specific virtual address translation", "Map format:", " -m Map output generated as (out)file[.map]", " -w Wide listing format for map file", " -x Hexadecimal (default)", " -d Decimal", " -q Octal", "Output:", " -i Intel Hex as (out)file[.ihx]", " -s Motorola S Record as (out)file[.s19]", #if NOICE diff --git a/sdas/linksrc/lkout.c b/sdas/linksrc/lkout.c index 766cc48..22cb18a 100644 --- a/sdas/linksrc/lkout.c +++ b/sdas/linksrc/lkout.c @@ -356,20 +356,22 @@ ixx(int i) * a_uint chksum byte checksum * a_uint lo_addr address within segment * a_uint hi_addr segment number * int i loop counter * int max number of data bytes * int reclen record length * * global variables: * int a_bytes T Line Address Bytes * FILE * ofp output file handle + * int platform selects platform specific + * virtual address translation * int rtaflg first output flag * char rtbuf[] output buffer * a_uint rtadr0 address temporary * a_uint rtadr1 address temporary * * functions called: * int fprintf() c_library * * side effects: * The data is output to the file defined by ofp. @@ -393,20 +395,26 @@ iflush() int i, max, reclen; a_uint chksum, lo_addr, hi_addr; // rom addresses, calculated based on the virtual ones a_uint rrtadr0 = rtadr0; // translate virtual addresses for gameboy if(TARGET_IS_GB){ if(rrtadr0 > 0x10000) rrtadr0 = (rrtadr0>>16) * 0x4000 + (rrtadr0&0xffff) - 0x4000; } + // translate virtual addresses for sms/gg + if(TARGET_IS_Z80 && (platform == PLATFORM_SMS)){ + if(rrtadr0 >= 0x10000) + rrtadr0 = ((rrtadr0 >> 16) * 0x4000) + (rrtadr0 & 0x3FFF); + } + max = (int) (rtadr1 - rtadr0); if (max) { if (a_bytes > 2) { static a_uint prev_hi_addr = 0; hi_addr = (rrtadr0 >> 16) & 0xffff; if ((hi_addr != prev_hi_addr) || rtaflg) { chksum = 0x02; chksum += 0x04; chksum += hi_addr;