summaryrefslogtreecommitdiff
path: root/sdcc-sdldz80-sms-virtual-address.patch
diff options
context:
space:
mode:
Diffstat (limited to 'sdcc-sdldz80-sms-virtual-address.patch')
-rw-r--r--sdcc-sdldz80-sms-virtual-address.patch438
1 files changed, 438 insertions, 0 deletions
diff --git a/sdcc-sdldz80-sms-virtual-address.patch b/sdcc-sdldz80-sms-virtual-address.patch
new file mode 100644
index 0000000..5bef155
--- /dev/null
+++ b/sdcc-sdldz80-sms-virtual-address.patch
@@ -0,0 +1,438 @@
+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;