4 * Copyright (C) 1989-2009 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/>.
24 * ported to the Rabbit2000 by
25 * Ulrich Raich and Razaq Ijoduola
29 * email: Ulrich dot Raich at cern dot ch
33 * xerr messages and order fix Copyright (C) 1989-2021 Alan R. Baldwin
38 * Extensions: P. Felber
40 * Altered by Leland Morrison to support rabbit 2000
41 * and rabbit 4000 instruction sets (2011)
48 * Read an address specifier. Pack the
49 * address information into the supplied
50 * `expr' structure. Return the mode of
53 * This addr(esp) routine performs the following addressing decoding:
55 * address mode flag addr base
57 * label s_type ---- s_addr s_area
58 * [REG] S_IND+icode 0 0 NULL
59 * [label] S_INDM ---- s_addr s_area
60 * offset[REG] S_IND+icode ---- offset ----
69 /* fix order of '<', '>', and '#' */
71 if (((c
= getnb()) == '<') || (c
== '>')) {
80 if ((c
= getnb()) == '#') {
82 esp
->e_mode
= S_IMMED
;
84 /* ljm - leading digit is used for offset for dd(ix|iy|sp) */
85 } else if ((c
== '-') || ((c
>= '0') && (c
<= '9'))) {
88 esp
->e_mode
= S_IMMED
;
94 * or '(' register=[hl,ix,iy,sp,bc,de] ')'
95 * ref to memory, scan the next 'symbol' to see if
96 * it is a register or an absolute address
98 if ((indx
= admode(R8
)) != 0) {
101 if ((indx
= admode(R8X
)) != 0) {
105 if ((indx
= admode(R16AF_ALT
)) != 0) {
109 if ((indx
= admode(R16AF
)) != 0) {
113 if ((indx
= admode(R16
)) != 0) {
121 esp
->e_mode
= (mode
+ indx
)&0xFF;
122 esp
->e_base
.e_ap
= NULL
;
125 * flag an error if the closing paren is absent
127 if ((c
= getnb()) != RTIND
) {
128 xerr('q', "Missing ')'.");
140 * scan the list(s) of registers to see if the
141 * name matches the name of one of the processor
144 if ((indx
= admode(R8
)) != 0) {
147 if ((indx
= admode(R8X
)) != 0) {
150 if ((indx
= admode(R16AF_ALT
)) != 0) {
153 if ((indx
= admode(R16AF
)) != 0) {
156 if ((indx
= admode(R16_ALT
)) != 0) {
159 if ((indx
= admode(R16
)) != 0) {
162 if ((indx
= admode(R32_JKHL
)) != 0) {
165 if ((indx
= admode(R32_BCDE
)) != 0) {
168 if ((indx
= admode(RXPC
)) != 0) {
176 esp
->e_addr
= indx
&0xFF;
178 esp
->e_base
.e_ap
= NULL
;
180 if ((c
= getnb()) == LFIND
) {
182 if ((indx
&0xFF)==IX
|| (indx
&0xFF)==IY
||
185 esp
->e_mode
= S_INDR
+ (indx
&0xFF);
186 } else if ( (indx
&0xFF)==HL
) {
187 esp
->e_mode
= S_IDHL_OFFSET
;
189 xerr('a', "BC, DE, HL, SP, IX, or IY required.");
191 if ((c
= getnb()) != RTIND
)
192 xerr('q', "Missing ')'.");
197 return (esp
->e_mode
);
201 * Enter admode() to search a specific addressing mode table
202 * for a match. Return the addressing value on a match or
217 while ( *(ptr
= &sp
[i
].a_str
[0]) ) {
228 * srch --- does string match ?
237 while (*ptr
&& *str
) {
238 if (ccase
[*ptr
& 0x007F] != ccase
[*str
& 0x007F])
243 if (ccase
[*ptr
& 0x007F] == ccase
[*str
& 0x007F]) {
249 if (!(ctype
[*ptr
& 0x007F] & LTR16
)) {
261 struct adsym R8
[] = {
272 struct adsym R8X
[] = {
278 struct adsym R8IP
[] = {
283 struct adsym R16
[] = {
293 struct adsym R16_ALT
[] = {
300 struct adsym R16AF
[] = {
305 struct adsym R16AF_ALT
[] = {
310 struct adsym R32_BCDE
[] = {
311 { "bcde", BCDE
|0400 },
315 struct adsym R32_JKHL
[] = {
316 { "jkhl", JKHL
|0400 },
320 struct adsym RXPC
[] = {
326 * Conditional definitions
329 struct adsym CND
[] = {
341 struct adsym ALT_CND
[] = {
342 { "GT", CC_GT
|0400 },
343 { "GTU", CC_GTU
|0400 },
344 { "LT", CC_LT
|0400 },
346 { "NZ", CC_NZ
|0400 },
348 { "NC", CC_NC
|0400 },