Mercurial > hg-old > index.cgi
comparison src/insn_bitbit.c @ 32:9bd0fbfe7405
Added basic indexed mode handling
author | lost |
---|---|
date | Fri, 02 Jan 2009 04:22:39 +0000 |
parents | |
children | 74a3fef7c8d0 |
comparison
equal
deleted
inserted
replaced
31:674ee393426c | 32:9bd0fbfe7405 |
---|---|
1 /* | |
2 insn_bitbit.c | |
3 Copyright © 2008 William Astle | |
4 | |
5 This file is part of LWASM. | |
6 | |
7 LWASM is free software: you can redistribute it and/or modify it under the | |
8 terms of the GNU General Public License as published by the Free Software | |
9 Foundation, either version 3 of the License, or (at your option) any later | |
10 version. | |
11 | |
12 This program is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
15 more details. | |
16 | |
17 You should have received a copy of the GNU General Public License along with | |
18 this program. If not, see <http://www.gnu.org/licenses/>. | |
19 */ | |
20 | |
21 /* | |
22 for handling inherent mode instructions | |
23 */ | |
24 | |
25 #define __insn_bitbit_c_seen__ | |
26 | |
27 #include <stdlib.h> | |
28 | |
29 #include "lwasm.h" | |
30 #include "instab.h" | |
31 #include "expr.h" | |
32 | |
33 OPFUNC(insn_bitbit) | |
34 { | |
35 int r; | |
36 lwasm_expr_stack_t *s; | |
37 int v1; | |
38 int tv; | |
39 | |
40 lwasm_emitop(as, l, instab[opnum].ops[0]); | |
41 | |
42 r = toupper(*(*p)++); | |
43 if (r == 'A') | |
44 r = 1; | |
45 else if (r == 'B') | |
46 r = 2; | |
47 else if (r == 'C' && toupper(**p) == 'C') | |
48 { | |
49 r = 0; | |
50 (*p)++; | |
51 } | |
52 else | |
53 { | |
54 register_error(as, l, 1, "Bad register"); | |
55 return; | |
56 } | |
57 if (*(*p)++ != ',') | |
58 { | |
59 register_error(as, l, 1, "Bad operand"); | |
60 return; | |
61 } | |
62 s = lwasm_expr_eval(*p, NULL); | |
63 if (!s) | |
64 { | |
65 register_error(as, l, 1, "Bad operand"); | |
66 return; | |
67 } | |
68 if (!lwasm_expr_is_constant(s)) | |
69 { | |
70 register_error(as, l, 2, "Incomplete reference"); | |
71 } | |
72 v1 = lwasm_expr_get_value(s); | |
73 lwasm_expr_stack_free(s); | |
74 if (v1 < 0 || v1 > 7) | |
75 { | |
76 register_error(as, l, 2, "Invalid bit number"); | |
77 v1 = 0; | |
78 } | |
79 if (*(*p)++ != ',') | |
80 { | |
81 register_error(as, l, 1, "Bad operand"); | |
82 return; | |
83 } | |
84 r = (r << 6) | (v1 << 3); | |
85 | |
86 s = lwasm_expr_eval(*p, NULL); | |
87 if (!s) | |
88 { | |
89 register_error(as, l, 1, "Bad operand"); | |
90 return; | |
91 } | |
92 if (!lwasm_expr_is_constant(s)) | |
93 { | |
94 register_error(as, l, 1, "Incomplete reference"); | |
95 } | |
96 v1 = lwasm_expr_get_value(s); | |
97 lwasm_expr_stack_free(s); | |
98 if (v1 < 0 || v1 > 7) | |
99 { | |
100 register_error(as, l, 2, "Invalid bit number"); | |
101 v1 = 0; | |
102 } | |
103 if (*(*p)++ != ',') | |
104 { | |
105 register_error(as, l, 1, "Bad operand"); | |
106 return; | |
107 } | |
108 r |= v1; | |
109 | |
110 lwasm_emit(as, l, r); | |
111 | |
112 // ignore base page address modifier | |
113 if (**p == '<') | |
114 (*p)++; | |
115 | |
116 s = lwasm_expr_eval(*p, NULL); | |
117 if (!s) | |
118 { | |
119 register_error(as, l, 1, "Bad operand"); | |
120 return; | |
121 } | |
122 if (!lwasm_expr_is_constant(s)) | |
123 { | |
124 register_error(as, l, 1, "Incomplete reference"); | |
125 } | |
126 v1 = lwasm_expr_get_value(s); | |
127 lwasm_expr_stack_free(s); | |
128 v1 &= 0xFFFF; | |
129 | |
130 tv = v1 - ((as -> dpval) << 8); | |
131 if (tv > 0xFF || tv < 0) | |
132 { | |
133 register_error(as, l, 2, "Byte overflow"); | |
134 } | |
135 lwasm_emit(as, l, tv & 0xff); | |
136 } |