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 }