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