Hackfix and re-enable strtoull and wcstoull, see bug #3798.
[sdcc.git] / sdcc / sdas / as6500 / r65mch.c
blob3e34b9b0c6711183f5ccc534418a0f9250b9afde
1 /* r65mch.c */
3 /*
4 * Copyright (C) 1995-2023 Alan R. Baldwin
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * Alan R. Baldwin
21 * 721 Berkeley St.
22 * Kent, Ohio 44240
26 * With Contributions from
28 * Marko Makela
29 * Sillitie 10 A
30 * 01480 Vantaa
31 * Finland
32 * Internet: Marko dot Makela at Helsinki dot Fi
33 * EARN/BitNet: msmakela at finuh
36 #include "asxxxx.h"
37 #include "r6500.h"
39 char *cpu = "Rockwell 6502/6510/65C02";
40 char *dsft = "asm";
42 int r6500;
43 int r65f11;
44 int r65c00;
45 int r65c02;
48 * Opcode Cycle Definitions
50 #define OPCY_SDP ((char) (0xFF))
51 #define OPCY_ERR ((char) (0xFE))
53 #define OPCY_6500 ((char) (0xFD))
54 #define OPCY_65F11 ((char) (0xFC))
55 #define OPCY_65C00 ((char) (0xFB))
56 #define OPCY_65C02 ((char) (0xFA))
58 /* OPCY_NONE ((char) (0x80)) */
59 /* OPCY_MASK ((char) (0x7F)) */
61 #define UN ((char) (OPCY_NONE | 0x00))
64 * R65 Cycle Count
66 * opcycles = r65pg1[opcode]
68 static char r65pg1[256] = {
69 /*--*--* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
70 /*--*--* - - - - - - - - - - - - - - - - */
71 /*00*/ 7, 6,UN,UN,UN, 3, 5,UN, 3, 2, 2,UN,UN, 4, 6,UN,
72 /*10*/ 4, 6,UN,UN,UN, 4, 6,UN, 2, 5,UN,UN,UN, 5, 7,UN,
73 /*20*/ 6, 6,UN,UN, 3, 3, 5,UN, 4, 2, 2,UN, 4, 4, 6,UN,
74 /*30*/ 4, 6,UN,UN,UN, 4, 6,UN, 2, 5,UN,UN,UN, 5, 7,UN,
75 /*40*/ 6, 6,UN,UN,UN, 3, 5,UN, 3, 2, 2,UN, 3, 4, 6,UN,
76 /*50*/ 4, 6,UN,UN,UN, 4, 6,UN, 2, 5,UN,UN,UN, 5, 7,UN,
77 /*60*/ 6, 6,UN,UN,UN, 3, 5,UN, 4, 2, 2,UN, 5, 4, 6,UN,
78 /*70*/ 4, 6,UN,UN,UN, 4, 6,UN, 2, 5,UN,UN,UN, 5, 7,UN,
79 /*80*/ UN, 6,UN,UN, 3, 3, 3,UN, 2,UN, 2,UN, 4, 4, 4,UN,
80 /*90*/ 4, 6,UN,UN, 4, 4, 4,UN, 2, 5, 2,UN,UN, 5,UN,UN,
81 /*A0*/ 2, 6, 2,UN, 3, 3, 3,UN, 2, 2, 2,UN, 4, 4, 4,UN,
82 /*B0*/ 4, 6,UN,UN, 4, 4, 4,UN, 2, 5, 2,UN, 5, 5, 5,UN,
83 /*C0*/ 2, 6,UN,UN, 3, 3, 5,UN, 2, 2, 2,UN, 4, 4, 6,UN,
84 /*D0*/ 4, 6,UN,UN,UN, 4, 6,UN, 2, 5,UN,UN,UN, 5, 7,UN,
85 /*E0*/ 2, 6,UN,UN, 3, 3, 5,UN, 2, 2, 2,UN, 4, 4, 6,UN,
86 /*F0*/ 4, 6,UN,UN,UN, 4, 6,UN, 2, 5,UN,UN,UN, 5, 7,UN
89 static char f11pg1[256] = {
90 /*--*--* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
91 /*--*--* - - - - - - - - - - - - - - - - */
92 /*00*/ 7, 6,UN,UN,UN, 3, 5, 5, 3, 2, 2,UN,UN, 4, 6, 7,
93 /*10*/ 4, 6,UN,UN,UN, 4, 6, 5, 2, 5,UN,UN,UN, 5, 7, 7,
94 /*20*/ 6, 6,UN,UN, 3, 3, 5, 5, 4, 2, 2,UN, 4, 4, 6, 7,
95 /*30*/ 4, 6,UN,UN,UN, 4, 6, 5, 2, 5,UN,UN,UN, 5, 7, 7,
96 /*40*/ 6, 6,UN,UN,UN, 3, 5, 5, 3, 2, 2,UN, 3, 4, 6, 7,
97 /*50*/ 4, 7,UN,UN,UN, 4, 6, 5, 2, 5,UN,UN,UN, 5, 7, 7,
98 /*60*/ 6, 6,UN,UN,UN, 3, 5, 5, 4, 2, 2,UN, 5, 4, 6, 7,
99 /*70*/ 4, 6,UN,UN,UN, 4, 6, 5, 2, 5,UN,UN,UN, 5, 7, 7,
100 /*80*/ UN, 6,UN,UN, 3, 3, 3, 5, 2,UN, 2,UN, 4, 4, 4, 7,
101 /*90*/ 4, 6,UN,UN, 4, 4, 4, 5, 2, 5, 2,UN,UN, 5,UN, 7,
102 /*A0*/ 2, 6, 2,UN, 3, 3, 3, 5, 2, 2, 2,UN, 4, 4, 4, 7,
103 /*B0*/ 4, 6,UN,UN, 4, 4, 4, 5, 2, 5, 2,UN, 5, 5, 5, 7,
104 /*C0*/ 2, 6,UN,UN, 3, 3, 5, 5, 2, 2, 2,UN, 4, 4, 6, 7,
105 /*D0*/ 4, 6,UN,UN,UN, 4, 6, 5, 2, 5,UN,UN,UN, 5, 7, 7,
106 /*E0*/ 2, 6,UN,UN, 3, 3, 5, 5, 2, 2, 2,UN, 4, 4, 6, 7,
107 /*F0*/ 2, 6,UN,UN,UN, 4, 6, 5, 2, 5,UN,UN,UN, 5, 7, 7
110 static char c00pg1[256] = {
111 /*--*--* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
112 /*--*--* - - - - - - - - - - - - - - - - */
113 /*00*/ 7, 6,10,UN,UN, 3, 5, 5, 3, 2, 2,UN,UN, 4, 6, 7,
114 /*10*/ 4, 6,UN,UN,UN, 4, 6, 5, 2, 5,UN,UN,UN, 5, 7, 7,
115 /*20*/ 6, 6,UN,UN, 3, 3, 5, 5, 4, 2, 2,UN, 4, 4, 6, 7,
116 /*30*/ 4, 6,UN,UN,UN, 4, 6, 5, 2, 5,UN,UN,UN, 5, 7, 7,
117 /*40*/ 6, 6,UN,UN,UN, 3, 5, 5, 3, 2, 2,UN, 3, 4, 6, 7,
118 /*50*/ 4, 6,UN,UN,UN, 4, 6, 5, 2, 5, 3,UN,UN, 5, 7, 7,
119 /*60*/ 6, 6,UN,UN,UN, 3, 5, 5, 4, 2, 2,UN, 5, 4, 6, 7,
120 /*70*/ 4, 6,UN,UN,UN, 4, 6, 5, 2, 5, 4,UN,UN, 5, 7, 7,
121 /*80*/ 4, 6,UN,UN, 3, 3, 3, 5, 2,UN, 5,UN, 4, 4, 4, 7,
122 /*90*/ 4, 6,UN,UN, 4, 4, 4, 5, 2, 5, 2,UN,UN, 5,UN, 7,
123 /*A0*/ 2, 6, 2,UN, 3, 3, 3, 5, 2, 2, 2,UN, 4, 4, 4, 7,
124 /*B0*/ 4, 6,UN,UN, 4, 4, 4, 5, 2, 5, 2,UN, 5, 5, 5, 7,
125 /*C0*/ 2, 6,UN,UN, 3, 3, 5, 5, 2, 2, 2,UN, 4, 4, 6, 7,
126 /*D0*/ 4, 6,UN,UN,UN, 4, 6, 5, 2, 5, 3,UN,UN, 5, 7, 7,
127 /*E0*/ 2, 6,UN,UN, 3, 3, 5, 5, 2, 2, 2,UN, 4, 4, 6, 7,
128 /*F0*/ 4, 6,UN,UN,UN, 4, 6, 5, 2, 5, 4,UN,UN, 5, 7, 7
131 static char c02pg1[256] = {
132 /*--*--* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
133 /*--*--* - - - - - - - - - - - - - - - - */
134 /*00*/ 7, 6,UN,UN, 5, 3, 5, 5, 3, 2, 2,UN, 6, 4, 6, 7,
135 /*10*/ 4, 6, 5,UN, 5, 4, 6, 5, 2, 5, 2,UN, 6, 5, 7, 7,
136 /*20*/ 6, 6,UN,UN, 3, 3, 5, 5, 4, 2, 2,UN, 4, 4, 6, 7,
137 /*30*/ 4, 6, 5,UN, 4, 4, 6, 5, 2, 5, 2,UN, 5, 5, 7, 7,
138 /*40*/ 6, 6,UN,UN,UN, 3, 5, 5, 3, 2, 2,UN, 3, 4, 6, 7,
139 /*50*/ 4, 6, 5,UN,UN, 4, 6, 5, 2, 5, 3,UN,UN, 5, 7, 7,
140 /*60*/ 6, 7,UN,UN, 3, 4, 5, 5, 4, 3, 2,UN, 6, 5, 6, 7,
141 /*70*/ 4, 7, 6,UN, 4, 5, 6, 5, 2, 6, 4,UN, 6, 6, 7, 7,
142 /*80*/ 4, 6,UN,UN, 3, 3, 3, 5, 2, 2, 2,UN, 4, 4, 4, 7,
143 /*90*/ 4, 6, 5,UN, 4, 4, 4, 5, 2, 5, 2,UN, 4, 5, 5, 7,
144 /*A0*/ 2, 6, 2,UN, 3, 3, 3, 5, 2, 2, 2,UN, 4, 4, 4, 7,
145 /*B0*/ 4, 6, 5,UN, 4, 4, 4, 5, 2, 5, 2,UN, 5, 5, 5, 7,
146 /*C0*/ 2, 6,UN,UN, 3, 3, 5, 5, 2, 2, 2,UN, 4, 4, 6, 7,
147 /*D0*/ 4, 6, 5,UN,UN, 4, 6, 5, 2, 5, 3,UN,UN, 5, 7, 7,
148 /*E0*/ 2, 7,UN,UN, 3, 4, 5, 5, 2, 3, 2,UN, 4, 5, 6, 7,
149 /*F0*/ 4, 7, 6,UN,UN, 5, 6, 5, 2, 6, 4,UN,UN, 6, 7, 7
152 int mchtyp;
153 struct area *zpg;
156 * Process a machine op.
158 VOID
159 machine(mp)
160 struct mne *mp;
162 int op, t1;
163 struct expr e1,e2;
164 char id[NCPS];
165 int c, v1, v2;
167 clrexpr(&e1);
168 clrexpr(&e2);
169 op = (int) mp->m_valu;
170 switch (mp->m_type) {
172 case S_SDP:
173 opcycles = OPCY_SDP;
174 zpg = dot.s_area;
175 if (more()) {
176 expr(&e1, 0);
177 if (e1.e_flag == 0 && e1.e_base.e_ap == NULL) {
178 if (e1.e_addr) {
179 xerr('b', "Only Page 0 Allowed.");
182 if ((c = getnb()) == ',') {
183 getid(id, -1);
184 zpg = alookup(id);
185 if (zpg == NULL) {
186 xerr('u', "Undefined Area.");
188 } else {
189 unget(c);
192 outdp(zpg, &e1, 0);
193 lmode = SLIST;
194 break;
195 case S_CPU:
196 mchtyp = op;
197 switch(mchtyp) {
198 case X_R6500:
199 opcycles = OPCY_6500;
200 r65f11 = 0;
201 r65c00 = 0;
202 r65c02 = 0;
203 break;
205 case X_R65F11:
206 opcycles = OPCY_65F11;
207 r65f11 = 1;
208 r65c00 = 0;
209 r65c02 = 0;
210 break;
212 case X_R65C00:
213 opcycles = OPCY_65C00;
214 r65f11 = 1;
215 r65c00 = 1;
216 r65c02 = 0;
217 break;
219 case X_R65C02:
220 opcycles = OPCY_65C02;
221 r65f11 = 1;
222 r65c00 = 1;
223 r65c02 = 1;
224 break;
226 break;
228 case S_INH3:
229 if (r65c02) {
230 while(more()) getnb();
231 xerr('o', "Invalid 65C02 Instruction");
232 break;
235 case S_INH2:
236 if (!r65c00) {
237 while(more()) getnb();
238 xerr('o', "Invalid 6500/65F11 Instruction");
239 break;
242 case S_INH1:
243 outab(op);
244 break;
246 case S_BRA2:
247 if (!r65c00) {
248 while(more()) getnb();
249 xerr('o', "Invalid 6500/65F11 Instruction");
250 break;
253 case S_BRA1:
254 expr(&e1, 0);
255 outab(op);
256 if (mchpcr(&e1)) {
257 v1 = (int) (e1.e_addr - dot.s_addr - 1);
258 if ((v1 < -128) || (v1 > 127))
259 aerr();
260 outab(v1);
261 } else {
262 outrb(&e1, R_PCR);
264 if (e1.e_mode != S_USER)
265 rerr();
266 break;
268 case S_JSR:
269 t1 = addr(&e1);
270 outab(op);
271 outrw(&e1, 0);
272 if (t1 != S_DIR && t1 != S_EXT)
273 aerr();
274 break;
276 case S_JMP:
277 t1 = addr(&e1);
278 switch (t1) {
279 case S_DIR:
280 case S_EXT:
281 outab(op);
282 outrw(&e1, 0);
283 break;
284 case S_IND:
285 outab(op + 0x20);
286 outrw(&e1, 0);
287 break;
288 default:
289 if (r65c02) { /* Check 65C02 Extensions */
290 switch(t1) {
291 case S_IPREX:
292 outab(op + 0x30);
293 outrw(&e1, 0);
294 break;
295 default:
296 outab(op);
297 outaw(0);
298 aerr();
299 break;
301 } else {
302 outab(op);
303 outaw(0);
304 aerr();
306 break;
308 break;
310 case S_DOP:
311 t1 = addr(&e1);
312 switch (t1) {
313 case S_IPREX:
314 outab(op + 0x01);
315 outrb(&e1, R_PAG0);
316 break;
317 case S_DIR:
318 outab(op + 0x05);
319 outrb(&e1, R_PAG0);
320 break;
321 case S_IMMED:
322 outab(op + 0x09);
323 outrb(&e1, 0);
324 if (op == 0x80)
325 aerr();
326 break;
327 case S_EXT:
328 outab(op + 0x0D);
329 outrw(&e1, 0);
330 break;
331 case S_IPSTY:
332 outab(op + 0x11);
333 outrb(&e1, R_PAG0);
334 break;
335 case S_DINDX:
336 outab(op + 0x15);
337 outrb(&e1, R_PAG0);
338 break;
339 case S_DINDY:
340 case S_INDY:
341 outab(op + 0x19);
342 outrw(&e1, 0);
343 break;
344 case S_INDX:
345 outab(op + 0x1D);
346 outrw(&e1, 0);
347 break;
348 default:
349 if (r65c02) { /* Check 65C02 Extensions */
350 switch(t1) {
351 case S_IND:
352 outab(op + 0x12);
353 outrb(&e1, R_PAG0);
354 break;
355 default:
356 outab(op + 0x05);
357 outab(0);
358 aerr();
359 break;
361 } else {
362 outab(op + 0x05);
363 outab(0);
364 aerr();
366 break;
368 break;
370 case S_SOP:
371 t1 = addr(&e1);
372 switch (t1) {
373 case S_DIR:
374 outab(op + 0x06);
375 outrb(&e1, R_PAG0);
376 break;
377 case S_EXT:
378 outab(op + 0x0E);
379 outrw(&e1, 0);
380 break;
381 case S_ACC:
382 if (op == 0xC0) { /* 65C02 Extension */
383 outab(0x3A);
384 if (!r65c02)
385 xerr('o', "Valid Only For The 65C02");
386 } else
387 if (op == 0xE0) { /* 65C02 Extension */
388 outab(0x1A);
389 if (!r65c02)
390 xerr('o', "Valid Only For The 65C02");
391 } else {
392 outab(op + 0x0A);
394 break;
395 case S_DINDX:
396 outab(op + 0x16);
397 outrb(&e1, R_PAG0);
398 break;
399 case S_INDX:
400 outab(op + 0x1E);
401 outrw(&e1, 0);
402 break;
403 default:
404 outab(op + 0x06);
405 outab(0);
406 aerr();
407 break;
409 break;
411 case S_BIT:
412 t1 = addr(&e1);
413 switch (t1) {
414 case S_DIR:
415 outab(op + 0x04);
416 outrb(&e1, R_PAG0);
417 break;
418 case S_EXT:
419 outab(op + 0x0C);
420 outrw(&e1, 0);
421 break;
422 default:
423 if (r65c02) { /* Check 65C02 Extensions */
424 switch(t1) {
425 case S_DINDX:
426 outab(op + 0x14);
427 outrb(&e1, R_PAG0);
428 break;
429 case S_INDX:
430 outab(op + 0x1C);
431 outrw(&e1, 0);
432 break;
433 case S_IMMED:
434 outab(0x89);
435 outrb(&e1, R_USGN);
436 break;
437 default:
438 outab(op + 0x04);
439 outab(0);
440 aerr();
441 break;
443 } else {
444 outab(op + 0x04);
445 outab(0);
446 aerr();
448 break;
450 break;
452 case S_CP:
453 t1 = addr(&e1);
454 switch (t1) {
455 case S_DIR:
456 outab(op + 0x04);
457 outrb(&e1, R_PAG0);
458 break;
459 case S_EXT:
460 outab(op+0x0C);
461 outrw(&e1, 0);
462 break;
463 case S_IMMED:
464 outab(op);
465 outrb(&e1, 0);
466 break;
467 default:
468 outab(op);
469 outab(0);
470 aerr();
471 break;
473 break;
475 case S_LDSTX:
476 t1 = addr(&e1);
477 switch (t1) {
478 case S_IMMED:
479 outab(op + 0x02);
480 outrb(&e1, 0);
481 if (op == 0x80)
482 aerr();
483 break;
484 case S_DIR:
485 outab(op + 0x06);
486 outrb(&e1, R_PAG0);
487 break;
488 case S_EXT:
489 outab(op + 0x0E);
490 outrw(&e1, 0);
491 break;
492 case S_DINDY:
493 outab(op + 0x16);
494 outrb(&e1, R_PAG0);
495 break;
496 case S_INDY:
497 outab(op + 0x1E);
498 outrw(&e1, 0);
499 break;
500 default:
501 outab(op + 0x06);
502 outab(0);
503 aerr();
504 break;
506 break;
508 case S_LDSTY:
509 t1 = addr(&e1);
510 switch (t1) {
511 case S_IMMED:
512 outab(op);
513 outrb(&e1, 0);
514 if (op == 0x80)
515 aerr();
516 break;
517 case S_DIR:
518 outab(op + 0x04);
519 outrb(&e1, R_PAG0);
520 break;
521 case S_EXT:
522 outab(op + 0x0C);
523 outrw(&e1, 0);
524 break;
525 case S_DINDX:
526 outab(op + 0x14);
527 outrb(&e1, R_PAG0);
528 break;
529 case S_INDX:
530 outab(op + 0x1C);
531 outrw(&e1, 0);
532 break;
533 default:
534 outab(op + 0x04);
535 outab(0);
536 aerr();
537 break;
539 break;
541 case S_BB:
542 if (!r65f11) {
543 while(more()) getnb();
544 xerr('o', "Invalid For The 6500");
545 break;
547 if ((c = getnb()) != '*')
548 unget(c);
549 expr(&e1, 0);
550 comma(1);
551 expr(&e2, 0);
552 outab(op);
553 outrb(&e1, R_PAG0);
554 if (mchpcr(&e2)) {
555 v2 = (int) (e2.e_addr - dot.s_addr - 1);
556 if ((v2 < -128) || (v2 > 127))
557 aerr();
558 outab(v2);
559 } else {
560 outrb(&e2, R_PCR);
562 if (e2.e_mode != S_USER)
563 rerr();
564 break;
566 case S_MB:
567 if (!r65f11) {
568 while(more()) getnb();
569 xerr('o', "Invalid For The 6500");
570 break;
572 t1 = addr(&e1);
573 outab(op);
574 outrb(&e1, R_PAG0);
575 if (t1 != S_DIR && t1 != S_EXT)
576 aerr();
577 break;
579 case S_STZ:
580 if (!r65c02) {
581 while(more()) getnb();
582 xerr('o', "Valid Only For The 65C02");
583 break;
585 switch (addr(&e1)) {
586 case S_DIR:
587 outab(op + 0x04);
588 outrb(&e1, R_PAG0);
589 break;
590 case S_EXT:
591 outab(op + 0x3C);
592 outrw(&e1, 0);
593 break;
594 case S_DINDX:
595 outab(op + 0x14);
596 outrb(&e1, R_PAG0);
597 break;
598 case S_INDX:
599 outab(op + 0x3E);
600 outrw(&e1, 0);
601 break;
602 default:
603 outab(op + 0x04);
604 outab(0);
605 aerr();
606 break;
608 break;
610 case S_TB:
611 if (!r65c02) {
612 while(more()) getnb();
613 xerr('o', "Valid Only For The 65C02");
614 break;
616 switch (addr(&e1)) {
617 case S_DIR:
618 outab(op + 0x04);
619 outrb(&e1, R_PAG0);
620 break;
621 case S_EXT:
622 outab(op+0x0C);
623 outrw(&e1, 0);
624 break;
625 default:
626 outab(op);
627 outab(0);
628 aerr();
629 break;
631 break;
633 default:
634 opcycles = OPCY_ERR;
635 err('o');
636 break;
638 if (opcycles == OPCY_NONE) {
640 * Donot Change Selection Order
642 if (r65c02) {
643 opcycles = c02pg1[cb[0] & 0xFF];
644 } else
645 if (r65c00) {
646 opcycles = c00pg1[cb[0] & 0xFF];
647 } else
648 if (r65f11) {
649 opcycles = f11pg1[cb[0] & 0xFF];
650 } else
651 if (r6500) {
652 opcycles = r65pg1[cb[0] & 0xFF];
658 * Branch/Jump PCR Mode Check
661 mchpcr(esp)
662 struct expr *esp;
664 if (esp->e_base.e_ap == dot.s_area) {
665 return(1);
667 if (esp->e_flag==0 && esp->e_base.e_ap==NULL) {
669 * Absolute Destination
671 * Use the global symbol '.__.ABS.'
672 * of value zero and force the assembler
673 * to use this absolute constant as the
674 * base value for the relocation.
676 esp->e_flag = 1;
677 esp->e_base.e_sp = &sym[1];
679 return(0);
683 * Machine dependent initialization
685 VOID
686 minit()
689 * Byte Order
691 hilo = 0;
694 * Address Space
696 exprmasks(3);
699 * Zero Page Area Pointer
701 zpg = NULL;
704 * Default Machine
706 mchtyp = X_R6500;
707 r6500 = 1;
708 r65f11 = 0;
709 r65c00 = 0;
710 r65c02 = 0;