//Add with carry void adc(CPU *c, OP_CODE_INFO *o){ int8_t carry = getFlag(c,C); int8_t accum = getRegByte(c,ACCUM); int8_t operand = o->operand; int16_t sum = (0x00FF&carry) + (0x00FF&accum) + (0x00FF&operand); int8_t sumByte = sum & 0x00FF; setZero(c,sumByte); if(getFlag(c,D)){ //in decimal mode //if lower 4 bits of operands plus //the carry in are larger than 9, //then we need to apply conversions //to remain in binary coded decimal format. if((accum & 0xF) + (operand & 0xF) + carry > 9){ sum += 6; } setSign(c,sum&0xFF); setOverflow(c,accum,operand,sum&0xFF); //if the higher bits aren't in //BCD format we need to add 96 to convert. //Black magic from http://nesdev.com/6502.txt sum += sum > 0x99 ? 96 : 0; setCarryBCD(c, sum); } else { setSign(c,sumByte); setOverflow(c,accum,operand,sumByte); setCarry(c,sum); } setRegByte(c,ACCUM,sum&0xFF); }
//Arithmetic shift left void asl(CPU *c, OP_CODE_INFO *o){ int8_t operand = o->operand; int16_t res = (0x00FF&operand) << 1; int8_t resByte = res & 0x00FF; setCarry(c,res); setSign(c,resByte); setZero(c,resByte); if(o->mode == modeAccumulator){ setRegByte(c,ACCUM,res); } else { write(c,o->address,res); } }
void simulateToRead() { if (_debug) printf("%*s% 7.2lf ", _indent*8, "", _tNextStop/(400.0*256.0)); int pc = _pch | _memory[2]; int op = _program->op(pc); incrementPC(); UInt16 r; if ((op & 0x800) == 0) { _f = op & 0x1f; if ((op & 0x400) == 0) { bool d = ((op & 0x20) != 0); // true if destination is f, false if destination is W char dc = d ? 'f' : 'W'; switch (op >> 6) { case 0x0: if (!d) switch (_f) { case 0: if (_debug) { printf("NOP "); printf("\n"); } _f = -1; break; case 2: if (_debug) { printf("OPTION "); printf("\n"); } _f = -1; _option = _w; break; case 3: if (_debug) { printf("SLEEP "); printf("\n"); } _f = -1; throw Exception(String("SLEEP not supported")); break; case 4: if (_debug) { printf("CLRWDT "); printf("\n"); } _f = -1; throw Exception(String("CLRWDT not supported")); break; case 6: if (_debug) { printf("TRIS GPIO "); printf("\n"); } _f = 0x20; _data = _w; break; default: unrecognizedOpcode(op); break; } else { if (_debug) { printf("MOVWF 0x%02x ", _f); printf("\n"); } _data = _w; } break; case 0x1: if (_debug) { if (!d) printf("CLRW "); else printf("CLRF 0x%02x ", _f); printf("\n"); } storeZ(0, d); break; case 0x2: if (_debug) { printf("SUBWF 0x%02x, %c ", _f, dc); printf("\n"); } { UInt8 m = readMemory(_f); r = m - _w; if (r & 0x100) _memory[3] |= 1; else _memory[3] &= 0xfe; if ((m & 0xf) - (_w & 0xf) != (r & 0xf)) _memory[3] |= 2; else _memory[3] &= 0xfd; storeZ(r, d); } break; case 0x3: if (_debug) { printf("DECF 0x%02x, %c ", _f, dc); printf("\n"); } storeZ(readMemory(_f) - 1, d); break; case 0x4: if (_debug) { printf("IORWF 0x%02x, %c ", _f, dc); printf("\n"); } storeZ(readMemory(_f) | _w, d); break; case 0x5: if (_debug) { printf("ANDWF 0x%02x, %c ", _f, dc); printf("\n"); } storeZ(readMemory(_f) & _w, d); break; case 0x6: if (_debug) { printf("XORWF 0x%02x, %c ", _f, dc); printf("\n"); } storeZ(readMemory(_f) ^ _w, d); break; case 0x7: if (_debug) { printf("ADDWF 0x%02x, %c ", _f, dc); printf("\n"); } { UInt8 m = readMemory(_f); r = m + _w; if (r & 0x100) _memory[3] |= 1; else _memory[3] &= 0xfe; if ((_w & 0xf) + (m & 0xf) != (r & 0xf)) _memory[3] |= 2; else _memory[3] &= 0xfd; storeZ(r, d); } break; case 0x8: if (_debug) { printf("MOVF 0x%02x, %c ", _f, dc); printf("\n"); } storeZ(readMemory(_f), d); break; case 0x9: if (_debug) { printf("COMF 0x%02x, %c ", _f, dc); printf("\n"); } storeZ(~readMemory(_f), d); break; case 0xa: if (_debug) { printf("INCF 0x%02x, %c ", _f, dc); printf("\n"); } storeZ(readMemory(_f) + 1, d); break; case 0xb: if (_debug) { printf("DECFSZ 0x%02x, %c ", _f, dc); printf("\n"); } r = readMemory(_f) - 1; store(r, d); if (r == 0) { incrementPC(); _skipping = true; } break; case 0xc: if (_debug) { printf("RRF 0x%02x, %c ", _f, dc); printf("\n"); } r = readMemory(_f) | ((_memory[3] & 1) << 8); setCarry((r & 1) != 0); store(r >> 1, d); break; case 0xd: if (_debug) { printf("RLF 0x%02x, %c ", _f, dc); printf("\n"); } r = (readMemory(_f) << 1) | (_memory[3] & 1); setCarry((r & 0x100) != 0); store(r, d); break; case 0xe: if (_debug) { printf("SWAPF 0x%02x, %c ", _f, dc); printf("\n"); } r = readMemory(_f); store((r >> 4) | (r << 4), d); break; case 0xf: if (_debug) { printf("INCFSF 0x%02x, %c ", _f, dc); printf("\n"); } r = readMemory(_f) + 1; store(r, d); if (r == 0) { incrementPC(); _skipping = true; } break; } }