1 /* ----------------------------------------------------------------------
3 * PACKAGE: as31 - 8031/8051 Assembler.
6 * This file contains the symbol table search/insertion routines
7 * associated with user defined symbols.
9 * The reserved keyword (instructions/directives) look up routine
12 * The opcode table for all of the instructions is located in this
16 * Jan. 19, 1990 - Created. (Ken Stauffer)
19 * All code in this file written by Ken Stauffer (University of Calgary)
27 /* normally in stdlib.h, but that include file also defines */
28 /* "div" which conflicts with the div in this file */
29 extern void *malloc(size_t size);
30 extern void free(void *ptr);
36 #define B(a) (0xF0+(a))
37 #define ACC(a) (0xE0+(a))
38 #define PSW(a) (0xD0+(a))
39 #define T2CON(a) (0xC8+(a))
40 #define IP(a) (0xB8+(a))
41 #define P3(a) (0xB0+(a))
42 #define IE(a) (0xA8+(a))
43 #define P2(a) (0xA0+(a))
44 #define SCON(a) (0x98+(a))
45 #define P1(a) (0x90+(a))
46 #define TCON(a) (0x88+(a))
47 #define P0(a) (0x80+(a))
49 /* ----------------------------------------------------------------------
51 * These symbols are not reserved keywords.
52 * This array contains the initial symbol table entries
53 * for the user symbol table. The symbols are
54 * basically convienient names that make writing
55 * in 8031/8051 bearable.
57 * The function syminit() inserts these entries into the
62 static struct symbol sinit[] = {
63 { "AC", 1, LABEL, PSW(6), NULL },
64 { "ACC", 1, LABEL, ACC(0), NULL },
65 { "B", 1, LABEL, B(0), NULL },
66 { "CY", 1, LABEL, PSW(7), NULL },
67 { "DPH", 1, LABEL, 0x83, NULL },
68 { "DPL", 1, LABEL, 0x82, NULL },
69 { "EA", 1, LABEL, IE(7), NULL },
70 { "ES", 1, LABEL, IE(4), NULL },
71 { "ET0", 1, LABEL, IE(1), NULL },
72 { "ET1", 1, LABEL, IE(3), NULL },
73 { "ET2", 1, LABEL, IE(5), NULL },
74 { "EX0", 1, LABEL, IE(0), NULL },
75 { "EX1", 1, LABEL, IE(2), NULL },
76 { "EXEN2", 1, LABEL, T2CON(3),NULL },
77 { "EXF2", 1, LABEL, T2CON(6),NULL },
78 { "F0", 1, LABEL, PSW(5), NULL },
79 { "IE", 1, LABEL, IE(0), NULL },
80 { "IE0", 1, LABEL, TCON(1),NULL },
81 { "IE1", 1, LABEL, TCON(3),NULL },
82 { "INT0", 1, LABEL, P3(2), NULL },
83 { "INT1", 1, LABEL, P3(3), NULL },
84 { "IP", 1, LABEL, IP(0), NULL },
85 { "IT0", 1, LABEL, TCON(0),NULL },
86 { "IT1", 1, LABEL, TCON(2),NULL },
87 { "OV", 1, LABEL, PSW(2), NULL },
88 { "P", 1, LABEL, PSW(0), NULL },
89 { "P0", 1, LABEL, P0(0), NULL },
90 { "P1", 1, LABEL, P1(0), NULL },
91 { "P2", 1, LABEL, P2(0), NULL },
92 { "P3", 1, LABEL, P3(0), NULL },
93 { "PCON", 1, LABEL, 0x87, NULL },
94 { "PS", 1, LABEL, IP(4), NULL },
95 { "PSW", 1, LABEL, PSW(0), NULL },
96 { "PT0", 1, LABEL, IP(1), NULL },
97 { "PT1", 1, LABEL, IP(3), NULL },
98 { "PT2", 1, LABEL, IP(5), NULL },
99 { "PX0", 1, LABEL, IP(0), NULL },
100 { "PX1", 1, LABEL, IP(2), NULL },
101 { "RB8", 1, LABEL, SCON(2),NULL },
102 { "RCAP2H", 1, LABEL, 0xCB, NULL },
103 { "RCAP2L", 1, LABEL, 0xCA, NULL },
104 { "RCLK", 1, LABEL, T2CON(5),NULL },
105 { "REN", 1, LABEL, SCON(4),NULL },
106 { "RD", 1, LABEL, P3(7), NULL },
107 { "RI", 1, LABEL, SCON(0),NULL },
108 { "RL2", 1, LABEL, T2CON(0),NULL },
109 { "RS0", 1, LABEL, PSW(3), NULL },
110 { "RS1", 1, LABEL, PSW(4), NULL },
111 { "RXD", 1, LABEL, P3(0), NULL },
112 { "SBUF", 1, LABEL, 0x99, NULL },
113 { "SCON", 1, LABEL, SCON(0),NULL },
114 { "SM0", 1, LABEL, SCON(7),NULL },
115 { "SM1", 1, LABEL, SCON(6),NULL },
116 { "SM2", 1, LABEL, SCON(5),NULL },
117 { "SP", 1, LABEL, 0x81, NULL },
118 { "T0", 1, LABEL, P3(4), NULL },
119 { "T1", 1, LABEL, P3(5), NULL },
120 { "T2", 1, LABEL, P0(0), NULL },
121 { "T2CON", 1, LABEL, T2CON(0),NULL },
122 { "T2EX", 1, LABEL, P0(1), NULL },
123 { "TB8", 1, LABEL, SCON(3),NULL },
124 { "TCLK", 1, LABEL, T2CON(4),NULL },
125 { "TCON", 1, LABEL, TCON(0),NULL },
126 { "TF0", 1, LABEL, TCON(5),NULL },
127 { "TF1", 1, LABEL, TCON(7),NULL },
128 { "TF2", 1, LABEL, T2CON(7),NULL },
129 { "TH0", 1, LABEL, 0x8C, NULL },
130 { "TH1", 1, LABEL, 0x8D, NULL },
131 { "TH2", 1, LABEL, 0xCD, NULL },
132 { "TI", 1, LABEL, SCON(1),NULL },
133 { "TL0", 1, LABEL, 0x8A, NULL },
134 { "TL1", 1, LABEL, 0x8B, NULL },
135 { "TL2", 1, LABEL, 0xCC, NULL },
136 { "TMOD", 1, LABEL, 0x89, NULL },
137 { "TR0", 1, LABEL, TCON(4),NULL },
138 { "TR1", 1, LABEL, TCON(6),NULL },
139 { "TR2", 1, LABEL, T2CON(2),NULL },
140 { "TXD", 1, LABEL, P3(1), NULL },
141 { "WR", 1, LABEL, P3(6), NULL }
144 #define SINITSIZE (sizeof(sinit)/sizeof(sinit[0]))
146 /* ----------------------------------------------------------------------
148 * These arrays contain the various opcodes for the
149 * various forms an instruction may take.
151 * The ordering of these opcodes is very critical to the
152 * proper fuctioning of the assembler.
154 * When a given form of an instruction is parsed, the parser
155 * indexes one of these arrays by the correct amount and thus
156 * obtains the correct opcode for the particular form.
160 static unsigned char acall[]= { 0x11 };
161 static unsigned char add[]= { 0x28, 0x25, 0x26, 0x24 };
162 static unsigned char addc[]= { 0x38, 0x35, 0x36, 0x34 };
163 static unsigned char ajmp[]= { 0x01 };
164 static unsigned char anl[]= { 0x58, 0x55, 0x56, 0x54, 0x52, 0x53, 0x82,
166 static unsigned char cjne[]= { 0xb5, 0xb4, 0xb8, 0xb6 };
167 static unsigned char clr[]= { 0xe4, 0xc3, 0xc2 };
168 static unsigned char cpl[]= { 0xf4, 0xb3, 0xb2 };
169 static unsigned char da[]= { 0xd4 };
170 static unsigned char dec[]= { 0x14, 0x18, 0x15, 0x16 };
171 static unsigned char div[]= { 0x84 };
172 static unsigned char djnz[]= { 0xd8, 0xd5 };
173 static unsigned char inc[]= { 0x04, 0x08, 0x05, 0x06, 0xa3 };
174 static unsigned char jb[]= { 0x20 };
175 static unsigned char jbc[]= { 0x10 };
176 static unsigned char jc[]= { 0x40 };
177 static unsigned char jmp[]= { 0x73 };
178 static unsigned char jnb[]= { 0x30 };
179 static unsigned char jnc[]= { 0x50 };
180 static unsigned char jnz[]= { 0x70 };
181 static unsigned char jz[]= { 0x60 };
182 static unsigned char lcall[]= { 0x12 };
183 static unsigned char ljmp[]= { 0x02 };
184 static unsigned char mov[]= { 0xe8, 0xe5, 0xe6, 0x74, 0xf5, 0x75, 0xf8,
185 0xa8, 0x78, 0x88, 0x85, 0x86, 0xf6, 0xa6,
186 0x76, 0x90, 0xa2, 0x92 };
187 static unsigned char movc[]= { 0x93, 0x83 };
188 static unsigned char movx[]= { 0xe2, 0xe3, 0xe0, 0xf2, 0xf3, 0xf0 };
189 static unsigned char mul[]= { 0xa4 };
190 static unsigned char nop[]= { 0x00 };
191 static unsigned char orl[]= { 0x48, 0x45, 0x46, 0x44, 0x42, 0x43, 0x72,
193 static unsigned char pop[]= { 0xd0 };
194 static unsigned char push[]= { 0xc0 };
195 static unsigned char ret[]= { 0x22 };
196 static unsigned char reti[]= { 0x32 };
197 static unsigned char rl[]= { 0x23 };
198 static unsigned char rlc[]= { 0x33 };
199 static unsigned char rr[]= { 0x03 };
200 static unsigned char rrc[]= { 0x13 };
201 static unsigned char setb[]= { 0xd3, 0xd2 };
202 static unsigned char sjmp[]= { 0x80 };
203 static unsigned char subb[]= { 0x98, 0x95, 0x96, 0x94 };
204 static unsigned char swap[]= { 0xc4 };
205 static unsigned char xch[]= { 0xc8, 0xc5, 0xc6 };
206 static unsigned char xchd[]= { 0xd6 };
207 static unsigned char xrl[]= { 0x68, 0x65, 0x66, 0x64, 0x62, 0x63 };
209 /* ----------------------------------------------------------------------
211 * This table contains opcodes, directives and a few reserved
214 * The second field is the keywords token value.
216 * Unless the symbol is an opcode, the third field will
219 * The third field is a pointer to an array of opcode bytes.
221 * --> This list must be in order by the first field
224 static struct opcode optable[] = {
227 {"acall", ACALL, acall },
229 {"addc", ADDC, addc },
230 {"ajmp", AJMP, ajmp },
232 {"byte", D_BYTE, NULL },
234 {"cjne", CJNE, cjne },
238 {"db", D_BYTE, NULL },
241 {"djnz", DJNZ, djnz },
242 {"dptr", DPTR, NULL },
243 {"dw", D_WORD, NULL },
244 {"end", D_END, NULL },
245 {"equ", D_EQU, NULL },
246 {"flag", D_FLAG, NULL },
256 {"lcall", LCALL, lcall },
257 {"ljmp", LJMP, ljmp },
259 {"movc", MOVC, movc },
260 {"movx", MOVX, movx },
263 {"org", D_ORG, NULL },
267 {"push", PUSH, push },
277 {"reti", RETI, reti },
282 {"setb", SETB, setb },
283 {"sjmp", SJMP, sjmp },
284 {"skip", D_SKIP, NULL },
285 {"subb", SUBB, subb },
286 {"swap", SWAP, swap },
287 {"word", D_WORD, NULL },
289 {"xchd", XCHD, xchd },
293 #define OPTABSIZE (sizeof(optable)/sizeof(struct opcode))
296 /* ----------------------------------------------------------------------
298 * Do a binary search through optable[], for a matching
299 * symbol. Return the symbol found or NULL.
303 struct opcode *lookop(const char *s)
305 register int low,high,mid,cond;
311 if( (cond = strcasecmp(s,optable[mid].name)) < 0 )
316 return(&optable[mid]);
321 /* ----------------------------------------------------------------------
322 * symtab, hash, looksym:
323 * User symbol table routines.
324 * symtab is the hash table for the user symbols.
325 * (chaining is used for collision resolution).
329 static struct symbol *symtab[HASHTABSIZE];
331 int hash(const char *s)
333 register const char *p;
334 register unsigned h=0, g;
337 h = (h<<4) + toupper(*p);
338 if ( (g = h&0xf0000000) ) {
343 return( h % HASHTABSIZE );
346 struct symbol *looksym(const char *s)
348 register struct symbol *ptr, *prev;
355 for(ptr=symtab[hv]; ptr; ptr = ptr->next) {
356 if( !strcasecmp(ptr->name,s) ) {
358 prev->next = ptr->next;
359 ptr->next = symtab[hv];
367 if ( (p = malloc(strlen(s) + 1)) ) {
370 error("Cannot allocate %d bytes",strlen(s)+1);
373 ptr = (struct symbol *) malloc( sizeof(struct symbol) );
375 error("Cannot allocate %d bytes",sizeof(struct symbol));
379 ptr->next = symtab[hv];
384 /* ----------------------------------------------------------------------
386 * Initializes the hash table, with the initial symbols from
391 // static struct symbol *symtab[HASHTABSIZE];
397 /* clear all entries in the symbol table */
398 memset(symtab, 0, sizeof(struct symbol *) * HASHTABSIZE);
400 /* load all the pre-defined symbols */
401 for(i=0; i<SINITSIZE; i++ ) {
402 hv = hash(sinit[i].name);
404 sinit[i].next = symtab[hv];
405 symtab[hv] = &sinit[i];
406 sinit[i].next = NULL;
410 /* free all the memory allocated for the symbols */
414 struct symbol *sym, *next;
417 for (i=0; i<HASHTABSIZE; i++) {
419 while (sym != NULL) {
420 if (sym->predefined) {
423 if (sym->name) free(sym->name);