|
1 | 1 | /* |
2 | | - * Copyright (C) 2022 Craig Thomas |
| 2 | + * Copyright (C) 2022-2025 Craig Thomas |
3 | 3 | * This project uses an MIT style license - see LICENSE for details. |
4 | 4 | */ |
5 | 5 | package ca.craigthomas.yacoco3e.components; |
|
8 | 8 |
|
9 | 9 | import java.util.function.Function; |
10 | 10 |
|
11 | | -import static ca.craigthomas.yacoco3e.datatypes.AddressingMode.IMMEDIATE; |
12 | 11 | import static ca.craigthomas.yacoco3e.datatypes.RegisterSet.*; |
13 | 12 |
|
14 | 13 | /** |
|
19 | 18 | */ |
20 | 19 | public class BranchInstruction extends Instruction |
21 | 20 | { |
22 | | - protected Function<InstructionBundle, Boolean> operation; |
| 21 | + protected Function<IOController, Boolean> operation; |
23 | 22 |
|
24 | 23 | public BranchInstruction(int opcode, |
25 | 24 | int ticks, |
26 | 25 | String mnemonic, |
27 | | - Function<InstructionBundle, Boolean> operation |
| 26 | + Function<IOController, Boolean> operation |
28 | 27 | ) { |
29 | 28 | this.opcodeValue = opcode; |
30 | 29 | this.mnemonic = mnemonic; |
31 | 30 | this.ticks = ticks; |
32 | 31 | this.operation = operation; |
33 | | - this.addressingMode = IMMEDIATE; |
34 | | - this.immediateByte = true; |
| 32 | + this.addressingMode = AddressingMode.IMMEDIATE; |
| 33 | + this.isByteSized = true; |
| 34 | + this.isValidInstruction = true; |
| 35 | + this.addressRead = new UnsignedWord(); |
35 | 36 | } |
36 | 37 |
|
37 | | - public int call(MemoryResult memoryResult, IOController io) { |
38 | | - if (operation.apply(new InstructionBundle(memoryResult, io)).equals(true)) { |
39 | | - UnsignedByte offset = memoryResult.value.getHigh(); |
40 | | - io.regs.pc.add(offset.isNegative() ? offset.getSignedShort() : offset.getShort()); |
| 38 | + public int call(IOController io) { |
| 39 | + if (operation.apply(io).equals(true)) { |
| 40 | + io.regs.pc.add(byteRead.isNegative() ? byteRead.getSignedShort() : byteRead.getShort()); |
41 | 41 | } |
42 | 42 | return ticks; |
43 | 43 | } |
44 | 44 |
|
45 | 45 | /** |
46 | 46 | * Branches to the specified address, pushing the value of the PC onto the S |
47 | 47 | * stack before branching. |
48 | | - * |
49 | | - * @param bundle the InstructionBundle that contains information to process |
50 | 48 | */ |
51 | | - public static Boolean branchToSubroutine(InstructionBundle bundle) { |
52 | | - bundle.io.pushStack(Register.S, bundle.io.regs.pc); |
| 49 | + public static Boolean branchToSubroutine(IOController io) { |
| 50 | + io.pushStack(Register.S, io.regs.pc); |
53 | 51 | return true; |
54 | 52 | } |
55 | 53 |
|
56 | 54 | /** |
57 | 55 | * Branch always will always return true when called. |
58 | | - * |
59 | | - * @param bundle the InstructionBundle with the information to process. |
60 | 56 | */ |
61 | | - public static Boolean branchAlways(InstructionBundle bundle) { |
| 57 | + public static Boolean branchAlways(IOController io) { |
62 | 58 | return true; |
63 | 59 | } |
64 | 60 |
|
65 | 61 | /** |
66 | 62 | * Branch never will always return false when called. |
67 | | - * |
68 | | - * @param bundle the InstructionBundle with the information to process. |
69 | 63 | */ |
70 | | - public static Boolean branchNever(InstructionBundle bundle) { |
| 64 | + public static Boolean branchNever(IOController io) { |
71 | 65 | return false; |
72 | 66 | } |
73 | 67 |
|
74 | 68 | /** |
75 | 69 | * Branch on high will return true if carry is not set, and zero is not set. |
76 | | - * |
77 | | - * @param bundle the InstructionBundle with the information to process. |
78 | 70 | */ |
79 | | - public static Boolean branchOnHigh(InstructionBundle bundle) { |
80 | | - return !bundle.io.regs.cc.isMasked(CC_C) && !bundle.io.regs.cc.isMasked(CC_Z); |
| 71 | + public static Boolean branchOnHigh(IOController io) { |
| 72 | + return !io.regs.cc.isMasked(CC_C) && !io.regs.cc.isMasked(CC_Z); |
81 | 73 | } |
82 | 74 |
|
83 | 75 | /** |
84 | 76 | * Branch on lower will return true if carry is set or zero is set. |
85 | | - * |
86 | | - * @param bundle the InstructionBundle with the information to process. |
87 | 77 | */ |
88 | | - public static Boolean branchOnLower(InstructionBundle bundle) { |
89 | | - return bundle.io.regs.cc.isMasked(CC_C) || bundle.io.regs.cc.isMasked(CC_Z); |
| 78 | + public static Boolean branchOnLower(IOController io) { |
| 79 | + return io.regs.cc.isMasked(CC_C) || io.regs.cc.isMasked(CC_Z); |
90 | 80 | } |
91 | 81 |
|
92 | 82 | /** |
93 | 83 | * Branch on carry clear will return true if carry is not set. |
94 | | - * |
95 | | - * @param bundle the InstructionBundle with the information to process. |
96 | 84 | */ |
97 | | - public static Boolean branchOnCarryClear(InstructionBundle bundle) { |
98 | | - return !bundle.io.regs.cc.isMasked(CC_C); |
| 85 | + public static Boolean branchOnCarryClear(IOController io) { |
| 86 | + return !io.regs.cc.isMasked(CC_C); |
99 | 87 | } |
100 | 88 |
|
101 | 89 | /** |
102 | 90 | * Branch on carry set will return true if carry is set. |
103 | | - * |
104 | | - * @param bundle the InstructionBundle with the information to process. |
105 | 91 | */ |
106 | | - public static Boolean branchOnCarrySet(InstructionBundle bundle) { |
107 | | - return bundle.io.regs.cc.isMasked(CC_C); |
| 92 | + public static Boolean branchOnCarrySet(IOController io) { |
| 93 | + return io.regs.cc.isMasked(CC_C); |
108 | 94 | } |
109 | 95 |
|
110 | 96 | /** |
111 | 97 | * Branch on not equal will return true if the zero flag is set. |
112 | | - * |
113 | | - * @param bundle the InstructionBundle with the information to process. |
114 | 98 | */ |
115 | | - public static Boolean branchOnNotEqual(InstructionBundle bundle) { |
116 | | - return !bundle.io.regs.cc.isMasked(CC_Z); |
| 99 | + public static Boolean branchOnNotEqual(IOController io) { |
| 100 | + return !io.regs.cc.isMasked(CC_Z); |
117 | 101 | } |
118 | 102 |
|
119 | 103 | /** |
120 | 104 | * Branch on equal will return true if the zero flag is set. |
121 | | - * |
122 | | - * @param bundle the InstructionBundle with the information to process. |
123 | 105 | */ |
124 | | - public static Boolean branchOnEqual(InstructionBundle bundle) { |
125 | | - return bundle.io.regs.cc.isMasked(CC_Z); |
| 106 | + public static Boolean branchOnEqual(IOController io) { |
| 107 | + return io.regs.cc.isMasked(CC_Z); |
126 | 108 | } |
127 | 109 |
|
128 | 110 | /** |
129 | 111 | * Branch on overflow clear will return true if the overflow flag is clear. |
130 | | - * |
131 | | - * @param bundle the InstructionBundle with the information to process. |
132 | 112 | */ |
133 | | - public static Boolean branchOnOverflowClear(InstructionBundle bundle) { |
134 | | - return !bundle.io.regs.cc.isMasked(CC_V); |
| 113 | + public static Boolean branchOnOverflowClear(IOController io) { |
| 114 | + return !io.regs.cc.isMasked(CC_V); |
135 | 115 | } |
136 | 116 |
|
137 | 117 | /** |
138 | 118 | * Branch on overflow set will return true if the overflow flag is set. |
139 | | - * |
140 | | - * @param bundle the InstructionBundle with the information to process. |
141 | 119 | */ |
142 | | - public static Boolean branchOnOverflowSet(InstructionBundle bundle) { |
143 | | - return bundle.io.regs.cc.isMasked(CC_V); |
| 120 | + public static Boolean branchOnOverflowSet(IOController io) { |
| 121 | + return io.regs.cc.isMasked(CC_V); |
144 | 122 | } |
145 | 123 |
|
146 | 124 | /** |
147 | 125 | * Branch on plus will return true if the negative flag is clear. |
148 | | - * |
149 | | - * @param bundle the InstructionBundle with the information to process. |
150 | 126 | */ |
151 | | - public static Boolean branchOnPlus(InstructionBundle bundle) { |
152 | | - return !bundle.io.regs.cc.isMasked(CC_N); |
| 127 | + public static Boolean branchOnPlus(IOController io) { |
| 128 | + return !io.regs.cc.isMasked(CC_N); |
153 | 129 | } |
154 | 130 |
|
155 | 131 | /** |
156 | 132 | * Branch on minus will return true if the negative flag is set. |
157 | | - * |
158 | | - * @param bundle the InstructionBundle with the information to process. |
159 | 133 | */ |
160 | | - public static Boolean branchOnMinus(InstructionBundle bundle) { |
161 | | - return bundle.io.regs.cc.isMasked(CC_N); |
| 134 | + public static Boolean branchOnMinus(IOController io) { |
| 135 | + return io.regs.cc.isMasked(CC_N); |
162 | 136 | } |
163 | 137 |
|
164 | 138 | /** |
165 | 139 | * Branch on greater than equal to zero will return true if the negative and overflow |
166 | 140 | * flags are both set or both clear. |
167 | | - * |
168 | | - * @param bundle the InstructionBundle with the information to process. |
169 | 141 | */ |
170 | | - public static Boolean branchOnGreaterThanEqualZero(InstructionBundle bundle) { |
171 | | - return bundle.io.regs.cc.isMasked(CC_N) == bundle.io.regs.cc.isMasked(CC_V); |
| 142 | + public static Boolean branchOnGreaterThanEqualZero(IOController io) { |
| 143 | + return io.regs.cc.isMasked(CC_N) == io.regs.cc.isMasked(CC_V); |
172 | 144 | } |
173 | 145 |
|
174 | 146 | /** |
175 | 147 | * Branch on less than zero will return true if the negative and overflow are not equal. |
176 | | - * |
177 | | - * @param bundle the InstructionBundle with the information to process. |
178 | 148 | */ |
179 | | - public static Boolean branchOnLessThanZero(InstructionBundle bundle) { |
180 | | - return bundle.io.regs.cc.isMasked(CC_N) != bundle.io.regs.cc.isMasked(CC_V); |
| 149 | + public static Boolean branchOnLessThanZero(IOController io) { |
| 150 | + return io.regs.cc.isMasked(CC_N) != io.regs.cc.isMasked(CC_V); |
181 | 151 | } |
182 | 152 |
|
183 | 153 | /** |
184 | 154 | * Branch on greater than zero will return true if the zero flag is clear, |
185 | 155 | * and if negative and overflow are both set or both clear. |
186 | | - * |
187 | | - * @param bundle the InstructionBundle with the information to process. |
188 | 156 | */ |
189 | | - public static Boolean branchOnGreaterThanZero(InstructionBundle bundle) { |
190 | | - return !bundle.io.regs.cc.isMasked(CC_Z) && (bundle.io.regs.cc.isMasked(CC_N) == bundle.io.regs.cc.isMasked(CC_V)); |
| 157 | + public static Boolean branchOnGreaterThanZero(IOController io) { |
| 158 | + return !io.regs.cc.isMasked(CC_Z) && (io.regs.cc.isMasked(CC_N) == io.regs.cc.isMasked(CC_V)); |
191 | 159 | } |
192 | 160 |
|
193 | 161 | /** |
194 | 162 | * Branch on less than equal to zero will return true if the zero flag is set, |
195 | 163 | * or if overflow and negative are not equal. |
196 | | - * |
197 | | - * @param bundle the InstructionBundle with the information to process. |
198 | 164 | */ |
199 | | - public static Boolean branchOnLessThanEqualZero(InstructionBundle bundle) { |
200 | | - return bundle.io.regs.cc.isMasked(CC_Z) || (bundle.io.regs.cc.isMasked(CC_N) != bundle.io.regs.cc.isMasked(CC_V)); |
| 165 | + public static Boolean branchOnLessThanEqualZero(IOController io) { |
| 166 | + return io.regs.cc.isMasked(CC_Z) || (io.regs.cc.isMasked(CC_N) != io.regs.cc.isMasked(CC_V)); |
201 | 167 | } |
202 | 168 |
|
203 | 169 | } |
0 commit comments