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/>.
26 * With Contributions from
32 * Internet: Marko dot Makela at Helsinki dot Fi
33 * EARN/BitNet: msmakela at finuh
39 char *cpu
= "Rockwell 6502/6510/65C02";
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))
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
156 * Process a machine op.
169 op
= (int) mp
->m_valu
;
170 switch (mp
->m_type
) {
177 if (e1
.e_flag
== 0 && e1
.e_base
.e_ap
== NULL
) {
179 xerr('b', "Only Page 0 Allowed.");
182 if ((c
= getnb()) == ',') {
186 xerr('u', "Undefined Area.");
199 opcycles
= OPCY_6500
;
206 opcycles
= OPCY_65F11
;
213 opcycles
= OPCY_65C00
;
220 opcycles
= OPCY_65C02
;
230 while(more()) getnb();
231 xerr('o', "Invalid 65C02 Instruction");
237 while(more()) getnb();
238 xerr('o', "Invalid 6500/65F11 Instruction");
248 while(more()) getnb();
249 xerr('o', "Invalid 6500/65F11 Instruction");
257 v1
= (int) (e1
.e_addr
- dot
.s_addr
- 1);
258 if ((v1
< -128) || (v1
> 127))
264 if (e1
.e_mode
!= S_USER
)
272 if (t1
!= S_DIR
&& t1
!= S_EXT
)
289 if (r65c02
) { /* Check 65C02 Extensions */
349 if (r65c02
) { /* Check 65C02 Extensions */
382 if (op
== 0xC0) { /* 65C02 Extension */
385 xerr('o', "Valid Only For The 65C02");
387 if (op
== 0xE0) { /* 65C02 Extension */
390 xerr('o', "Valid Only For The 65C02");
423 if (r65c02
) { /* Check 65C02 Extensions */
543 while(more()) getnb();
544 xerr('o', "Invalid For The 6500");
547 if ((c
= getnb()) != '*')
555 v2
= (int) (e2
.e_addr
- dot
.s_addr
- 1);
556 if ((v2
< -128) || (v2
> 127))
562 if (e2
.e_mode
!= S_USER
)
568 while(more()) getnb();
569 xerr('o', "Invalid For The 6500");
575 if (t1
!= S_DIR
&& t1
!= S_EXT
)
581 while(more()) getnb();
582 xerr('o', "Valid Only For The 65C02");
612 while(more()) getnb();
613 xerr('o', "Valid Only For The 65C02");
638 if (opcycles
== OPCY_NONE
) {
640 * Donot Change Selection Order
643 opcycles
= c02pg1
[cb
[0] & 0xFF];
646 opcycles
= c00pg1
[cb
[0] & 0xFF];
649 opcycles
= f11pg1
[cb
[0] & 0xFF];
652 opcycles
= r65pg1
[cb
[0] & 0xFF];
658 * Branch/Jump PCR Mode Check
664 if (esp
->e_base
.e_ap
== dot
.s_area
) {
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.
677 esp
->e_base
.e_sp
= &sym
[1];
683 * Machine dependent initialization
699 * Zero Page Area Pointer