1 //
2 // CODE.C
3 // Code Generation Routines for 68000 Assembler
4 //
5 // Function: output()
6 // Places the data whose size and value are specified onto
7 // the output stream at the current location contained in
8 // global varible loc. That is, if a listing is being
9 // produced, it calls listObj() to print the data in the
10 // object code field of the current listing line; if an
11 // object file is being produced, it calls outputObj() to
12 // output the data in the form of S-records.
13 //
14 // effAddr()
15 // Computes the 6-bit effective address code used by the
16 // 68000 in most cases to specify address modes. This code
17 // is returned as the value of effAddr(). The desired
18 // addressing mode is determined by the field of the
19 // opDescriptor which is pointed to by the operand
20 // argument. The lower 3 bits of the output contain the
21 // register code and the upper 3 bits the mode code.
22 //
23 // extWords()
24 // Computes and outputs (using output()) the extension
25 // words for the specified operand. The generated
26 // extension words are determined from the data contained
27 // in the opDescriptor pointed to by the op argument and
28 // from the size code of the instruction, passed in
29 // the size argument. The errorPtr argument is used to
30 // return an error code by the standard mechanism.
31 //
32 // Usage: output(data, size)
33 // int data, size;
34 //
35 // effAddr(operand)
36 // opDescriptor *operand;
37 //
38 // extWords(op, size, errorPtr)
39 // opDescriptor *op;
40 // int size, *errorPtr;
41 //
42 // Author: Paul McKee
43 // ECE492 North Carolina State University
44 //
45 // Date: 12/13/86
46 //
47 // Copyright 1990-1991 North Carolina State University. All Rights Reserved.
48 //
49
50 #include <stdio.h>
51 #include <stdlib.h>
52
53 #include "asm.h"
54
55 extern int loc;
56 extern char pass2;
57 extern FILE *listFile;
58
59 extern char listFlag; // True if a listing is desired
60 extern char objFlag; // True if an object code file is desired
61
62 void
output(int data,int size)63 output(int data, int size)
64 {
65 if (listFlag)
66 listObj(data, size);
67 if (objFlag)
68 outputObj(loc, data, size);
69 }
70
71 int
effAddr(opDescriptor * operand)72 effAddr(opDescriptor *operand)
73 {
74 switch (operand->mode) {
75 case DnDirect:
76 return 0x00 | operand->reg;
77 case AnDirect:
78 return 0x08 | operand->reg;
79 case AnInd:
80 return 0x10 | operand->reg;
81 case AnIndPost:
82 return 0x18 | operand->reg;
83 case AnIndPre:
84 return 0x20 | operand->reg;
85 case AnIndDisp:
86 return 0x28 | operand->reg;
87 case AnIndIndex:
88 return 0x30 | operand->reg;
89 case AbsShort:
90 return 0x38;
91 case AbsLong:
92 return 0x39;
93 case PCDisp:
94 return 0x3A;
95 case PCIndex:
96 return 0x3B;
97 case Immediate:
98 return 0x3C;
99 default:
100 printf("INVALID EFFECTIVE ADDRESSING MODE!\n");
101 exit(0);
102 }
103 return -1;
104 }
105
106 void
extWords(opDescriptor * op,int size,int * errorPtr)107 extWords(opDescriptor *op, int size, int *errorPtr)
108 {
109 int disp;
110
111 switch (op->mode) {
112 case DnDirect:
113 case AnDirect: /* These modes take */
114 case AnInd: /* no extension words. */
115 case AnIndPost:
116 case AnIndPre:
117 break;
118 case AnIndDisp:
119 case PCDisp:
120 if (pass2) {
121 disp = op->data;
122 if (op->mode == PCDisp)
123 disp -= loc;
124 output(disp & 0xFFFF, WORD);
125 if (disp < -32768 || disp > 32767)
126 NEWERROR(*errorPtr, INV_DISP);
127 }
128 loc += 2;
129 break;
130 case AnIndIndex:
131 case PCIndex:
132 if (pass2) {
133 disp = op->data;
134 if (op->mode == PCIndex)
135 disp -= loc;
136 output(((op->size == LONG) ? 0x800 : 0)
137 | (op->index << 12) | (disp & 0xFF), WORD);
138 if (disp < -128 || disp > 127)
139 NEWERROR(*errorPtr, INV_DISP);
140 }
141 loc += 2;
142 break;
143 case AbsShort:
144 if (pass2) {
145 output(op->data & 0xFFFF, WORD);
146 if (op->data < -32768 || op->data > 32767)
147 NEWERROR(*errorPtr, INV_ABS_ADDRESS);
148 }
149 loc += 2;
150 break;
151 case AbsLong:
152 if (pass2)
153 output(op->data, LONG);
154 loc += 4;
155 break;
156 case Immediate:
157 if (!size || size == WORD) {
158 if (pass2) {
159 output(op->data & 0xFFFF, WORD);
160 if (op->data < -32768 || op->data > 65535)
161 NEWERROR(*errorPtr,
162 INV_16_BIT_DATA);
163 }
164 loc += 2;
165 } else if (size == BYTE) {
166 if (pass2) {
167 output(op->data & 0xFF, WORD);
168 if (op->data < -32768 || op->data > 32767)
169 NEWERROR(*errorPtr,
170 INV_8_BIT_DATA);
171 }
172 loc += 2;
173 } else if (size == LONG) {
174 if (pass2)
175 output(op->data, LONG);
176 loc += 4;
177 }
178 break;
179 default:
180 printf("INVALID EFFECTIVE ADDRESSING MODE!\n");
181 exit(1);
182 }
183 }
184