Exemplo n.º 1
0
//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);
}
Exemplo n.º 2
0
//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);
    }
}
Exemplo n.º 3
0
 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;
             }
         }