// applesystem.h // Core elements of the 6502 CPU, and flag manipulation. typedef unsigned char byte; typedef unsigned short address; byte acc, X, Y, P, S = 0x00; address PC = 0x0000; byte Memory[4096]; // TO DO. Add expansion capability to memory. // FLAGS const byte flag_N = 0x80; // Negative const byte flag_V = 0x40; // Overflow const byte flag_B = 0x10; // BRK command const byte flag_D = 0x08; // Decimal mode const byte flag_I = 0x04; // IRQ disable const byte flag_Z = 0x02; // Zero const byte flag_C = 0x01; // Carry byte getFlag(byte flag) { return ((P & flag) == flag) ? 1 : 0; } void setFlag(byte flag, int x) { //OVERLOAD TO ACCEPT INT AS WELL if (x == 1){ if ((P & flag) == 0x0) P += flag; }else if (x == 0){ if ((P & flag) == flag) P -= flag; } else{ fprintf(stderr, "setFlag() passed arg neither 0 or 1"); } } void flagSet(byte flag){ P |= flag; } void flagClear(byte flag){ P &= ~flag; } // BCD // need to actually look into BCD on the 6502 byte toBCD(byte x){ if (x < 100){ byte a = ((x / 10) << 4); byte b = (x % 10); return (a + b); } else{ fprintf(stderr, "Number greater than 99 passed to toBCD()"); } } byte fromBCD(byte x){ byte a = ((x >> 4) * 10); byte b = (x & 0xF); return (a + b); } // Functions which perform reusable routines for finding if a specific flag should be set. void setFlagN(byte x){ if (x & flag_N == flag_N) setFlag(flag_N, 1); else setFlag(flag_N, 0); } //Perform prior to any changes void setFlagV(byte x, byte y){ if ((x & flag_N) == (y & flag_N)){ if (((x + y) & (flag_N ^ 0xFF)) > 0x7F) setFlag(flag_V, 1); else setFlag(flag_V, 0); }else{ if (((x - y) & (flag_N ^ 0xFF)) > 0x7F) setFlag(flag_V, 1); else setFlag(flag_V, 0); } } /*void setFlagB(){ //WORK ON setFlag(flag_B, 1); }*/ //Dont really need since its dependent on the BRK insturction /*void setFlagD(){ setFlag(flag_D, 1); }*/ /*void setFlagI(){ //WORK ON setFlag(flag_Z, 1); }*/ void setFlagZ(int x){ if (x == 0) setFlag(flag_Z, 1); else setFlag(flag_Z, 0); } //Only 6 instructions, 2 not including stack instructions, use the carry flag. // Need to look further into implementation details for this. /*void setFlagC(){ setFlag(flag_Z, 1); }*/