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