typedef unsigned char byte; byte acc, X, Y, S, P = 0x00; byte Memory[4096]; // TO DO. Add expansion capability to memory. /* To Do. + Find variables better passed as pointers instead */ // FLAGS const byte flag_N = 0x80; // Negative (Note that byte cast is necessary here only) 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 toggleFlag(byte flag) { P = ((P & flag) == flag) ? (P + flag) : (P - flag); } // BCD 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); } // Class of instructions //each one has every type of addressing mode, inherited from a base class. // the different addressing modes will be distinguished when the bytecode is called, it will run the instructions function with a selection for the /* example Immediate ADC #$44 $69 2 2 instruction(0x69); -> ADC({enum for immediate}); Zero Page ADC $44 $65 2 3 instruction(0x65); -> ADC({enum for Zero Page}); */ // Set particular flags // Functions which quickly set specific flags that are straightforward checks, and are repeated often. void setFlagN(byte x){ if (x ^ flag_N == flag_N){ setFlag(flag_N, 1); }else{ //not sure if this should be present, I think it is 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); } } //Only 6 instructions, 2 not including stack instructions, use the carry flag. /*void setFlagC(){ // NOTE. Must make setFlagC functional with independence. Look into carrying on 6502 setFlag(flag_Z, 1); }*/