3 #include "basic_type.hpp"
4 #include "nes_memory_map.hpp"
5 #include "instruction.hpp"
6 #include "nes_memory_mapper.hpp"
7 #include "utils/hex_form.hpp"
15 enum ProcessorStateType {
16 PS_C=0, PS_Z, PS_I, PS_D,
17 PS_B, PS_U, PS_V, PS_N,
21 R_A=0, R_X, R_Y, R_SP, R_PS,
26 IO_PPU=0, IO_VRAM, IO_CONST,
34 NesMemoryMapper m_mapper;
35 Word m_return_addr; // to test whether return is corresponding.
38 const StateMachine* mp_parent;
39 std::vector<Word> m_call_stack;
43 StateMachine(Word pc, const NesMemoryMapper& mapper)
51 for (unsigned i=0; i<REG_NUM; ++i) {
56 StateMachine(const StateMachine& that)
58 m_mapper(that.m_mapper),
59 m_return_addr(that.m_return_addr),
60 m_cond_flag(that.m_cond_flag),
62 m_call_stack(that.m_call_stack)
64 for (unsigned i=0; i<REG_NUM; ++i) {
65 m_reg[i] = that.m_reg[i];
68 void copy(const StateMachine& that)
72 m_mapper.copy(that.m_mapper);
73 m_return_addr = that.m_return_addr;
74 m_cond_flag = that.m_cond_flag;
76 unsigned size = that.m_call_stack.size();
77 m_call_stack.resize(size);
79 for (unsigned i=0; i<size; ++i) {
80 m_call_stack[i]=that.m_call_stack[i];
83 for (unsigned i=0; i<REG_NUM; ++i) {
84 m_reg[i] = that.m_reg[i];
87 const StateMachine& parent()const { return *mp_parent; }
91 if (mp_parent == this) {
94 return mp_parent->depth()+1;
98 void execute(PInstruction instr);
101 if (mp_parent == this) {
104 for (unsigned i=0; i<REG_NUM; ++i) {
105 m_reg[i] = mp_parent->m_reg[i];
107 m_mapper.copy(mp_parent->m_mapper);
111 const NesMemoryMapper& mapper()const {return m_mapper; }
112 Byte a()const { return m_reg[R_A]; }
113 Byte x()const { return m_reg[R_X]; }
114 Byte y()const { return m_reg[R_Y]; }
115 Word stackAddress()const
117 return bit8::addressIndex(nes::STACK_OFFSET, m_reg[R_SP]);
119 Word returnAddress()const { return m_return_addr; }
121 Byte sp()const { return m_reg[R_SP]; }
122 void setSP(Byte val) { m_reg[R_SP] = val; }
123 Word pc()const { return m_pc; }
124 void setPC(Word addr)
128 bool ps(ProcessorStateType bit) {return bit8::byteBit(m_reg[R_PS],bit);}
129 void setPS(ProcessorStateType bit, bool val)
131 return bit8::setByteBit(m_reg[R_PS],bit, val);
133 PInstruction nextInstruction()
136 MemoryID id=m_mapper.id(m_pc);
137 return m_mapper.getInstruction(id);
138 /* index behaviour is not good, when reading instruction.
139 Byte byte=m_mapper.data(id);
140 Byte low=m_mapper.indexedData(id, 1);
141 Byte high=m_mapper.indexedData(id, 2);
142 PInstruction ptr(new Instruction(m_pc, byte, low, high));
145 bool isCorrespondReturn()const { return m_return_addr+1 == m_pc; }
147 void setupMatchCase(PInstruction instr)
150 m_pc = instr->operand();
152 m_pc = instr->next();
155 void setupOtherCase(PInstruction instr)
158 m_pc = instr->next();
160 m_pc = instr->operand();
165 MemoryID id = m_mapper.id(nes::STACK_OFFSET);
166 m_return_addr=m_mapper.indexedData(id, m_reg[R_SP]+1);
167 m_return_addr+=m_mapper.indexedData(id, m_reg[R_SP]+2)<<8;
171 std::cout << "stack trace: ";
172 unsigned size=m_call_stack.size();
173 for (unsigned i=0; i<size-1; i+=2){
174 std::cout << " [" << HexForm(m_call_stack[size-i-1])
175 << " > " << HexForm(m_call_stack[size-i-2])
178 std::cout << std::endl;
180 MemoryID targetID(AddressingMode mode, Word operand);
184 void call(Word dest_addr, Word ret_addr);
188 MemoryID id = m_mapper.id(nes::STACK_OFFSET);
189 m_mapper.indexedData(id, m_reg[R_SP]) = byte;
195 MemoryID id = m_mapper.id(nes::STACK_OFFSET);
196 return m_mapper.indexedData(id, m_reg[R_SP]);
198 void pushWord(Word word);
200 // read the value of operand.
201 Byte& target(AddressingMode mode, Word operand);
205 setPS(PS_N, bit8::signBit(val));
206 setPS(PS_Z, val == 0);
208 bool isOverflowAddtion(Byte a, Byte b, Byte result);
209 bool isOverflowSubtraction(Byte a, Byte b, Byte result);
210 void compare(Byte left, Byte right);