]> Shamusworld >> Repos - rmac/blob - eagen0.c
Fix problem in tokenizer that caused legit code to make assembler barf.
[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       case DREG:                                            // "Do nothing" - they're in the opword
22       case AREG:
23       case AIND:
24       case APOSTINC:
25       case APREDEC:
26       case AM_USP:
27       case AM_CCR:
28       case AM_SR:
29       case AM_NONE:
30          break;                                             // This is a performance hit, though
31       case ADISP:                                           // expr(An)
32          if(w) {                                            // Just deposit it 
33             if(tdb)
34                rmark(cursect, sloc, tdb, MWORD, NULL);
35             if(v + 0x8000 >= 0x18000)
36                return(error(range_error));
37             D_word(v);
38          } else {                                           // Arrange for fixup later on 
39             fixup(FU_WORD|FU_SEXT, sloc, aNexpr);
40             D_word(0);
41          }
42          break;
43       case PCDISP:
44          if(w) {                                            // Just deposit it 
45             if((aNexattr & TDB) == cursect)
46                v -= (VALUE)sloc;
47             else if((aNexattr & TDB) != ABS)
48                error(rel_error);
49
50             if(v + 0x8000 >= 0x10000)
51                return(error(range_error));
52             D_word(v);
53          } else {                                           // Arrange for fixup later on 
54             fixup(FU_WORD|FU_SEXT|FU_PCREL, sloc, aNexpr);
55             D_word(0);
56          }
57          break;
58       case AINDEXED:
59          w = (WORD)((aNixreg << 12) | aNixsiz);             // Compute ixreg and size+scale
60          if(aNexattr & DEFINED) {                           // Deposit a byte... 
61             if(tdb)
62                return(error(abs_error));                    // Can't mark bytes 
63             if(v + 0x80 >= 0x180)
64                return(error(range_error));
65             w |= v & 0xff;
66             D_word(w);
67          } else {                                           // Fixup the byte later
68             fixup(FU_BYTE|FU_SEXT, sloc+1, aNexpr);
69             D_word(w);
70          }
71          break;
72       case PCINDEXED:
73          w = (WORD)((aNixreg << 12) | aNixsiz);             // Compute ixreg and size+scale
74          if(aNexattr & DEFINED) {                           // Deposit a byte... 
75             if((aNexattr & TDB) == cursect) 
76                v -= (VALUE)sloc;
77             else if((aNexattr & TDB) != ABS)
78                error(rel_error);
79
80             if(v + 0x80 >= 0x100)
81                return(error(range_error));
82             w |= v & 0xff;
83             D_word(w);
84          } else {                                           // Fixup the byte later 
85             fixup(FU_WBYTE|FU_SEXT|FU_PCREL, sloc, aNexpr);
86             D_word(w);
87          }
88          break;
89       case IMMED:
90          switch(siz) {
91             case SIZB:
92                if(w) {
93                   if(tdb)
94                      return(error("illegal byte-sized relative reference"));
95                   if(v + 0x100 >= 0x200)
96                      return(error(range_error));
97                   D_word(v);
98                } else {
99                   fixup(FU_BYTE|FU_SEXT, sloc+1, aNexpr);
100                   D_word(0);
101                }
102                break;
103             case SIZW:
104             case SIZN:
105                if(w) {
106                   if(tdb)
107                      rmark(cursect, sloc, tdb, MWORD, NULL);
108                   if(v + 0x10000 >= 0x20000)
109                      return(error(range_error));
110                   D_word(v);
111                } else {
112                   fixup(FU_WORD|FU_SEXT, sloc, aNexpr);
113                   D_word(0);
114                }
115                break;
116             case SIZL:
117                if(w) {
118                   if(tdb)
119                      rmark(cursect, sloc, tdb, MLONG, NULL);
120                   D_long(v);
121                } else {
122                   fixup(FU_LONG, sloc, aNexpr);
123                   D_long(0);
124                }
125                break;
126             default:
127                interror(1);                                 // IMMED size problem
128          }
129          break;
130       case ABSW:
131          if(w) {
132             if(tdb)
133                rmark(cursect, sloc, tdb, MWORD, NULL);
134             if(v + 0x8000 >= 0x10000)
135                return(error(range_error));
136             D_word(v);
137          } else {
138             fixup(FU_WORD|FU_SEXT, sloc, aNexpr);
139             D_word(0);
140          }
141          break;
142       case ABSL:
143          if(w) {
144             if(tdb)
145                rmark(cursect, sloc, tdb, MLONG, NULL);
146             D_long(v);
147          } else {
148             fixup(FU_LONG, sloc, aNexpr);
149             D_long(0);
150          }
151          break;
152       case ABASE:
153       case MEMPOST:
154       case MEMPRE:
155       case PCBASE:
156       case PCMPOST:
157       case PCMPRE:
158          return(error("unsupported 68020 addressing mode"));
159       default:
160          interror(3);                                       // Bad addressing mode in ea gen 
161    }
162
163    return(OK);
164 }
165
166 // Undefine dirty macros
167 #undef eaNgen
168 #undef amN
169 #undef aNexattr
170 #undef aNexval
171 #undef aNexpr
172 #undef aNixreg
173 #undef aNixsiz