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;
|