Fix for "*" getting bad section attributes, reported by A. Seed.
[rmac] / eagen0.c
1 //
2 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
3 // EAGEN0.C - Effective Address Code Generation
4 //            Generated Code for eaN (Included twice by "eagen.c")
5 // Copyright (C) 199x Landon Dyer, 2011 Reboot and Friends
6 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
7 // Source utilised with the kind permission of Landon Dyer
8 //
9
10 int eaNgen(WORD siz)
11 {
12         WORD w;
13         VALUE v;
14         WORD tdb;
15
16         v = aNexval;
17         w = (WORD)(aNexattr & DEFINED);
18         tdb = (WORD)(aNexattr & TDB);
19
20         switch (amN)
21         {
22         // "Do nothing" - they're in the opword
23         case DREG:
24         case AREG:
25         case AIND:
26         case APOSTINC:
27         case APREDEC:
28         case AM_USP:
29         case AM_CCR:
30         case AM_SR:
31         case AM_NONE:
32                 // This is a performance hit, though
33                 break;
34         case ADISP:
35                 // expr(An)
36                 if (w)
37                 {
38                         // Just deposit it 
39                         if (tdb)
40                                 rmark(cursect, sloc, tdb, MWORD, NULL);
41
42                         if (v + 0x8000 >= 0x18000)
43                                 return error(range_error);
44
45                         D_word(v);
46                 }
47                 else
48                 {
49                         // Arrange for fixup later on 
50                         AddFixup(FU_WORD|FU_SEXT, sloc, aNexpr);
51                         D_word(0);
52                 }
53
54                 break;
55         case PCDISP:
56                 if (w)
57                 {
58                         // Just deposit it 
59                         if ((aNexattr & TDB) == cursect)
60                                 v -= (VALUE)sloc;
61                         else if ((aNexattr & TDB) != ABS)
62                                 error(rel_error);
63
64                         if (v + 0x8000 >= 0x10000)
65                                 return error(range_error);
66
67                         D_word(v);
68                 }
69                 else
70                 {
71                         // Arrange for fixup later on 
72                         AddFixup(FU_WORD|FU_SEXT|FU_PCREL, sloc, aNexpr);
73                         D_word(0);
74                 }
75
76                 break;
77         case AINDEXED:
78                 // Compute ixreg and size+scale
79                 w = (WORD)((aNixreg << 12) | aNixsiz);
80
81                 if (aNexattr & DEFINED)
82                 {
83                         // Deposit a byte... 
84                         if (tdb)
85                                 // Can't mark bytes 
86                                 return error(abs_error);
87
88                         if (v + 0x80 >= 0x180)
89                                 return error(range_error);
90
91                         w |= v & 0xff;
92                         D_word(w);
93                 }
94                 else
95                 {
96                         // Fixup the byte later
97                         AddFixup(FU_BYTE|FU_SEXT, sloc+1, aNexpr);
98                         D_word(w);
99                 }
100
101                 break;
102         case PCINDEXED:
103                 // Compute ixreg and size+scale
104                 w = (WORD)((aNixreg << 12) | aNixsiz);
105
106                 if (aNexattr & DEFINED)
107                 {
108                         // Deposit a byte... 
109                         if ((aNexattr & TDB) == cursect) 
110                                 v -= (VALUE)sloc;
111                         else if ((aNexattr & TDB) != ABS)
112                                 error(rel_error);
113
114                         if (v + 0x80 >= 0x100)
115                                 return error(range_error);
116
117                         w |= v & 0xff;
118                         D_word(w);
119                 }
120                 else
121                 {
122                         // Fixup the byte later 
123                         AddFixup(FU_WBYTE|FU_SEXT|FU_PCREL, sloc, aNexpr);
124                         D_word(w);
125                 }
126
127                 break;
128         case IMMED:
129                 switch (siz)
130                 {
131                 case SIZB:
132                         if (w)
133                         {
134                                 if (tdb)
135                                         return error("illegal byte-sized relative reference");
136
137                                 if (v + 0x100 >= 0x200)
138                                         return error(range_error);
139
140                                 D_word(v);
141                         }
142                         else
143                         {
144                                 AddFixup(FU_BYTE|FU_SEXT, sloc+1, aNexpr);
145                                 D_word(0);
146                         }
147
148                         break;
149                 case SIZW:
150                 case SIZN:
151                         if (w)
152                         {
153                                 if (tdb)
154                                         rmark(cursect, sloc, tdb, MWORD, NULL);
155
156                                 if (v + 0x10000 >= 0x20000)
157                                         return error(range_error);
158
159                                 D_word(v);
160                         }
161                         else
162                         {
163                                 AddFixup(FU_WORD|FU_SEXT, sloc, aNexpr);
164                                 D_word(0);
165                         }
166
167                         break;
168                 case SIZL:
169                         if (w)
170                         {
171                                 if (tdb)
172                                         rmark(cursect, sloc, tdb, MLONG, NULL);
173
174                                 D_long(v);
175                         }
176                         else
177                         {
178                                 AddFixup(FU_LONG, sloc, aNexpr);
179                                 D_long(0);
180                         }
181
182                         break;
183                 default:
184                         // IMMED size problem
185                         interror(1);
186                 }
187
188                 break;
189         case ABSW:
190                 if (w)
191                 {
192                         if (tdb)
193                                 rmark(cursect, sloc, tdb, MWORD, NULL);
194
195                         if (v + 0x8000 >= 0x10000)
196                                 return error(range_error);
197
198                         D_word(v);
199                 }
200                 else
201                 {
202                         AddFixup(FU_WORD|FU_SEXT, sloc, aNexpr);
203                         D_word(0);
204                 }
205
206                 break;
207         case ABSL:
208                 if (w)
209                 {
210                         if (tdb)
211                                 rmark(cursect, sloc, tdb, MLONG, NULL);
212
213                         D_long(v);
214                 }
215                 else
216                 {
217                         AddFixup(FU_LONG, sloc, aNexpr);
218                         D_long(0);
219                 }
220
221                 break;
222         case ABASE:
223         case MEMPOST:
224         case MEMPRE:
225         case PCBASE:
226         case PCMPOST:
227         case PCMPRE:
228                 return error("unsupported 68020 addressing mode");
229         default:
230                 // Bad addressing mode in ea gen 
231                 interror(3);
232         }
233
234         return OK;
235 }
236
237 // Undefine dirty macros
238 #undef eaNgen
239 #undef amN
240 #undef aNexattr
241 #undef aNexval
242 #undef aNexpr
243 #undef aNixreg
244 #undef aNixsiz
245