summaryrefslogtreecommitdiff
path: root/sdcc-sdldz80-sms-virtual-address.patch
blob: 5bef15580583ed88a7587c04b332a62815849919 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
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;