/* simulator for 6811 $Log: sim.c,v $ * Revision 1.22 1994/03/22 22:17:57 ted * fixed some type errors. some seemingly serious. * * Revision 1.21 1994/02/25 21:51:34 teller * corrected potential problems/errors associated with neg and tst * instructions * * Revision 1.20 1994/02/25 19:48:52 teller * sub8 revised as it did not set condition codes correctly * still needs some work for neg and tst -- also jsr sets cycle count * in wierd (wrong) fashion * * Revision 1.19 1994/02/10 23:34:40 teller * fixed overflow for instructions that use 16-bit subtracts, namely cpx * cpy, cpd, subd * Pat Teller & Richard Oliver * * Revision 1.18 1994/02/02 18:59:43 teller * comments changed * * Revision 1.17 1993/10/12 18:05:46 pfeiffer * Fixed inc8 routine to work properly with negative increments * * Revision 1.16 1993/10/07 19:36:29 pfeiffer * Made comments for all variants of ldab instruction match (some called it ldb) * Fixed ldab condition codes; most addressing modes didn't set them, those * that did based them on A accumulator * Fixed cba instruction; it was doing an sba instead. * * Revision 1.15 1993/09/24 19:42:33 teller * *** empty log message *** * * Revision 1.14 1993/09/23 21:10:55 teller * modifications to make CPD, CPX, and CPY work correctly * C bit not set correctly * some displays incorrect * some comments incorrect * exhaustive testing in progress but installing new version * * Revision 1.13 1993/09/08 19:07:42 pfeiffer * Fixed lda direct to set condition codes * * Revision 1.12 1993/09/02 15:02:40 pfeiffer * Added ``m'' command to set values in memory * Inserted Ted's fixed fdiv instruction * * Revision 1.11 1993/07/28 17:30:32 pfeiffer * Fixed daa * * Revision 1.9 1993/07/26 22:42:16 pfeiffer * Added halfcarry flag * Added daa instruction * Fixed bgt, ble, clra, clrb instructions * * Revision 1.8 1993/07/20 21:20:08 ted * added cmpd indexed instruction * * Revision 1.7 1993/03/02 05:45:59 ted * mostly fixed condition code goobers. also fixed pshy which * pushed x instead. * * Revision 1.5 1993/01/30 00:00:35 ted * added word and byte declarations * * Revision 1.4 1993/01/28 02:05:20 ted * simple speed ups based on better inlining, * and passing a pointer to the state instead of * passing the actual state. * * Revision 1.3 1993/01/27 23:22:13 ted * added rcs log comment at top * */ #include #include "sim.h" /* shift directions. perhaps should be an enum */ #define LEFT 1 #define RIGHT -1 /* used to toss condition codes safely */ m6811 _null_state, *NULL_STATE=&_null_state; /* handy bit bucket */ /* setter functions for status bits */ INLINE void set_half_carry(m6811 *state, int value) {state->half_carry = value;} INLINE void set_x_interrupt(m6811 *state, int value) {state->x_interrupt = value;} INLINE void set_stop_disable(m6811 *state, int value) {state->stop_disable = value;} INLINE void set_overflow(m6811 *state, int value) {state->overflow = value;} INLINE void set_negative(m6811 *state, int value) {state->negative = value;} INLINE void set_carry(m6811 *state, int value) {state->carry = value;} INLINE void set_idisable(m6811 *state, int value) {state->idisable = value;} INLINE void set_zero(m6811 *state, int value) {state->zero = value;} void set_ccw(m6811 *state, byte value) { set_stop_disable(state, (value&0x80) != 0); /* S */ set_x_interrupt(state, (value&0x40) != 0); /* X */ set_half_carry(state, (value&0x20) != 0); /* H */ set_idisable(state, (value&0x10) != 0); /* I */ set_negative(state, (value&0x8) != 0); /* N */ set_zero(state, (value&0x4) != 0); /* Z */ set_overflow(state, (value&0x2) != 0); /* V */ set_carry(state, (value&0x1) != 0); /* C */ } /* getter functions for conditions code bits */ INLINE int get_half_carry(m6811 *state) {return state->half_carry;} INLINE int get_x_interrupt(m6811 *state) {return state->x_interrupt;} INLINE int get_stop_disable(m6811 *state) {return state->stop_disable;} INLINE int get_overflow(m6811 *state) {return state->overflow;} INLINE int get_negative(m6811 *state) {return state->negative;} INLINE int get_carry(m6811 *state) {return state->carry;} INLINE int get_idisable(m6811 *state) {return state->idisable;} INLINE int get_zero(m6811 *state) {return state->zero;} byte get_ccw(m6811 *state) { byte r; r = 0; if (get_stop_disable(state)) r |= 0x80; /* S */ if (get_x_interrupt(state)) r |= 0x40; /* X */ if (get_half_carry(state)) r |= 0x20; /* H */ if (get_idisable(state)) r |= 0x10; /* I */ if (get_negative(state)) r |= 0x8; /* N */ if (get_zero(state)) r |= 0x4; /* Z */ if (get_overflow(state)) r |= 0x2; /* V */ if (get_carry(state)) r |= 0x1; /* C */ return r; } /* getter functions for registers */ INLINE byte get_a(m6811 *state) {return (state->d >> 8) & 0xff;} INLINE byte get_b(m6811 *state) {return state->d & 0xff;} INLINE word get_d(m6811 *state) {return state->d;} INLINE word get_x(m6811 *state) {return state->x;} INLINE word get_y(m6811 *state) {return state->y;} INLINE word get_s(m6811 *state) {return state->sp;} INLINE word get_pc(m6811 *state) {return state->pc;} /* setter functions for registers */ INLINE void set_a(m6811 *state, byte value) { state->d &= 0xff; state->d |= value<<8; } INLINE void set_b(m6811 *state, byte value) { state->d &= 0xff00; state->d |= value; } INLINE void set_d(m6811 *state, word value) {state->d = 0xffff&value;} INLINE void set_x(m6811 *state, word value) {state->x = 0xffff&value;} INLINE void set_y(m6811 *state, word value) {state->y = 0xffff&value;} INLINE void set_s(m6811 *state, word value) {state->sp = 0xffff&value;} INLINE void set_pc(m6811 *state, word value) {state->pc = 0xffff&value;} /* memory modifiers */ INLINE void set_mem8(byte *m, word address, byte value) {m[address] = 0xff&value;} INLINE void set_mem16(byte *m, word address, word value) {m[address]=(value>>8)&0xff; m[address+1] = value&0xff; } /* memory accessors */ INLINE byte get_mem8(byte *m, word add) {return 0xff&m[add];} INLINE word get_mem16(byte *m, word add) {return (m[add]<<8) + m[add+1];} /* read memory, bump pc. as in reading op-codes */ INLINE byte fetch8(byte *m, m6811 *state) {return get_mem8(m, state->pc++);} INLINE word fetch16(byte *m, m6811 *state) {long r;r = get_mem16(m, state->pc);state->pc += 2; return r;} /* 8 bit add, sets condition codes */ INLINE byte add8(byte a, byte b, m6811 *state) { int r; r = a+b; set_carry(state, (0x100&r) != 0); set_zero(state, (r&0xff) == 0); set_negative(state, (r&0x80) != 0); set_overflow(state, (((a^b)&0x80) == 0) && ((((a&0x80)!=0)^get_negative(state))!=0)); /* jjp -- added set halfcarry */ set_half_carry(state, ((a^b) & 0x10) != (r & 0x10)); return r&0xff; } /* 8 bit subtract, sets condition codes */ INLINE byte sub8(byte a, byte b, m6811 *state) { int r; r = a-b; set_carry(state, ((((a^0x80))&(b&0x80))|| ((b&0x80)&(r&0x80))|| ((r&0x80)&(a^0x80))) != 0); set_zero(state, (r&0xff) == 0); set_negative(state, (r&0x80) != 0); set_overflow(state, (((a&0x80)&(b^0x80)&(r^0x80))|| ((a^0x80)&(b&0x80)&(r&0x80)))!=0); return r&0xff; } /* 8 bit subtract for negation, sets condition codes */ INLINE byte sub8neg(byte a, m6811 *state) { int r; r = 0-a; set_carry(state, (r&0xff != 0)); set_zero(state, (r&0xff) == 0); set_negative(state, (r&0x80) != 0); set_overflow(state, ((r&0x80)&(~r&0x40)&(~r&0x20)& (~r&0x10)&(~r&0x08)&(~r&0x04)& (~r&0x02) & (~r&0x01))!=0); return r&0xff; } /* 8 bit subtract for tst, sets condition codes */ INLINE byte sub8tst(byte a, m6811 *state) { int r; r = a-0; set_carry(state, 0); set_zero(state, (r&0xff) == 0); set_negative(state, a&0x80); set_overflow(state, 0); return r&0xff; } /* 8 bit OR, just like add, but hits fewer condition codes */ INLINE byte or8(byte a, byte b, m6811 *state) { int r; r = a|b; set_zero(state, (r&0xff) == 0); set_negative(state, (r&0x80) != 0); set_overflow(state, 0); return r&0xff; } /* AND works just like OR */ INLINE byte and8(byte a, byte b, m6811 *state) { int r; r = a&b; set_zero(state, (r&0xff) == 0); set_negative(state, (r&0x80) != 0); set_overflow(state, 0); return r&0xff; } /* and so does XOR */ INLINE byte xor8(byte a, byte b, m6811 *state) { int r; r = a^b; set_zero(state, (r&0xff) == 0); set_negative(state, (r&0x80) != 0); set_overflow(state, 0); return r&0xff; } /* used in loads and stores */ INLINE void tst8(byte a, m6811 *state) { set_zero(state, (a&0xff) == 0); set_negative(state, (a&0x80) != 0); set_overflow(state, 0); } /* used when loading and storing D */ INLINE void tst16(word a, m6811 *state) { set_zero(state, (a&0xffff) == 0); set_negative(state, (a&0x8000) != 0); set_overflow(state, 0); } /* increment a 16 bit quantity, set flags */ word inc16(word old, int inc, m6811 *state) { old += inc; set_zero(state, (old&0xffff) == 0); return old&0xffff; } /* same for 8 bits. more conditions are checked */ byte inc8(byte old, int inc, m6811 *state) { int t; t = old; t += inc; set_zero(state, (t&0xff) == 0); set_negative(state, (t & 0x80) != 0); set_overflow(state, t > 256); return t&0xff; } /* shift from a specified bit, into carry. general enough to handle all 6811 shifts */ byte shift8(byte old, int direction, int new_bit, m6811 *state) { int carry, t; t = old; if (direction == LEFT) { carry = ((t & 0x80) != 0); t = (t<<1) + new_bit; } else if (direction == RIGHT) { carry = t & 1; t = (t>>1) + (new_bit<<7); } else { fprintf(stderr, "internal error in shift8\n"); exit(1); } set_carry(state, carry); tst8(t&0xff, state); return t&0xff; } word shift16(word old, int direction, int new_bit, m6811 *state) { int carry; if (direction == LEFT) { carry = ((old & 0x8000) != 0); old = (old<<1) + new_bit; } else if (direction == RIGHT) { carry = old & 1; old = (old>>1) + (new_bit<<7); } else { fprintf(stderr, "internal error in shift16\n"); exit(1); } set_carry(state, carry); tst16(old&0xffff, state); return old&0xffff; } /* 16 bit add with condition codes */ word add16a(word a, word b, m6811 *state) { long r; r = a+b; set_carry(state, (abs(b)>abs(a))); set_zero(state, (r&0xffff) == 0); set_negative(state, (r&0x8000) != 0); set_overflow(state, get_carry(state) ^ get_negative(state)); /* return r&0xff; replaced by jjp */ return r&0xffff; } /* 16 bit add with condition codes */ word add16(word a, word b, m6811 *state) { long r; r = a+b; set_carry(state, r>65536); set_zero(state, (r&0xffff) == 0); set_negative(state, (r&0x8000) != 0); set_overflow(state, get_carry(state) ^ get_negative(state)); /* return r&0xff; replaced by jjp */ return r&0xffff; } /* and subtract */ INLINE word sub16(word a, word b, m6811 *state) { /* 16 bit subtract with condition codes */ long r; r = a-b; set_carry(state, (abs(b)>abs(a))); set_zero(state, (r&0xffff) == 0); set_negative(state, (r&0x8000) != 0); set_overflow(state, ((((a&0x8000)&(b^0x8000)&(r^0x8000))&0x8000)||(((a^0x8000)&(b&0x8000)&(r&0x8000))&0x8000))); /* return r&0xff; replaced by jjp */ return r&0xffff; } /* implements the 6811 branch instructions. may modify pc if condition is true */ void branch(m6811 *state, byte *m, int condition) { int offset; offset = fetch8(m, state); if (condition) { if (offset & 0x80) { offset = offset-256; } set_pc(state, get_pc(state)+offset); } } /* what happens with unimplemented instructions */ void not_done(m6811 state, byte *memory) { fprintf(stderr, "encountered unimplemented instruction at %04lx (%02x)\n", state.pc-1, memory[state.pc-1]); getchar(); } /* count some cycles */ INLINE void cycle(m6811 *state, int count) {state->t += count;} /* step one instruction. return new state, possibly modify memory */ void single_step(m6811 *state, byte *memory) { int opcode; word temp; word add; opcode = fetch8(memory, state); /* get opcode */ switch (opcode) { /* and dispatch to handler */ case 0x01: /* nop */ cycle(state, 2); break; case 0x02: /* idiv */ cycle(state, 41); if (get_x(state) == 0) { set_carry(state, 1); set_zero(state, 0); /* correct value here not clear */ } else { temp = get_d(state)/get_x(state); set_d(state, get_d(state)%get_x(state)); set_x(state, temp); set_zero(state, temp == 0); set_carry(state, 0); } set_overflow(state, 0); break; case 0x03: { /* fdiv */ unsigned long u; set_carry(state, 0); set_zero(state, 0); set_overflow(state, 0); cycle(state, 41); u = get_d(state); if (u > get_x(state)) { set_overflow(state, 1); } else { u <<= 16; set_zero(state, u == 0); set_d(state, (u%get_x(state))); set_x(state, (u/get_x(state))); } } break; case 0x04: /* lsrd */ cycle(state, 3); set_d(state, shift16(get_d(state), RIGHT, 0, state)); break; case 0x05: /* asld or lsld */ cycle(state, 3); set_d(state, shift16(get_d(state), LEFT, 0, state)); break; case 0x06: /* tap */ cycle(state, 2); set_ccw(state, get_a(state)); break; case 0x07: /* tpa */ cycle(state, 2); set_a(state, get_ccw(state)); break; case 0x08: /* inx */ cycle(state, 3); set_x(state, inc16(get_x(state), 1, state)); break; case 0x09: /* dex */ cycle(state, 3); set_x(state, inc16(get_x(state), -1, state)); break; case 0x0a: /* clv */ cycle(state, 2); set_overflow(state, 0); break; case 0x0b: /* sev */ cycle(state, 2); set_overflow(state, 1); break; case 0x0c: /* clc */ cycle(state, 2); set_carry(state, 0); break; case 0x0d: /* sec */ cycle(state, 2); set_carry(state, 1); break; case 0x0e: /* cli */ cycle(state, 2); set_idisable(state, 0); break; case 0x0f: /* sei */ cycle(state, 2); set_idisable(state, 1); break; case 0x10: /* sba */ cycle(state, 2); set_a(state, sub8(get_a(state), get_b(state), state)); break; case 0x11: /* cba */ cycle(state, 2); sub8(get_a(state), get_b(state), state); break; case 0x12: /* brset */ cycle(state, 6); add = fetch8(memory, state); temp = fetch8(memory, state) & get_mem8(memory, add); branch(state, memory, temp!=0); break; case 0x13: /* brclr */ cycle(state, 6); add = fetch8(memory, state); temp = fetch8(memory, state) & get_mem8(memory, add); branch(state, memory, temp==0); break; case 0x14: /* bset */ cycle(state, 6); add = fetch8(memory, state); set_mem8(memory, add, or8(get_mem8(memory, add), fetch8(memory, state), state)); break; case 0x15: /* bclr */ cycle(state, 6); add = fetch8(memory, state); set_mem8(memory, add, and8(get_mem8(memory, add), ~fetch8(memory, state), state)); break; case 0x16: /* tab */ cycle(state, 2); set_b(state, get_a(state)); tst8(get_b(state), state); break; case 0x17: /* tba */ cycle(state, 2); set_a(state, get_b(state)); tst8(get_a(state), state); break; case 0x19: /* daa */ cycle(state, 2); /* jjp */ if (((get_a(state) & 0xf) > 9) || get_half_carry(state)) { temp = get_a(state) + 6; if (temp > 0xff) set_carry(state, 1); set_a(state, temp); } if ((((get_a(state) & 0xf0) >> 4) > 9) || (get_carry(state) == 1)) { set_carry(state, 1); set_a(state, get_a(state) + 0x60); } set_zero(state, get_a(state) == 0); set_negative(state, (get_a(state) & 0x80) != 0); break; case 0x1b: /* aba */ cycle(state, 2); set_a(state, add8(get_a(state), get_b(state), state)); break; case 0x1c: /* bset indirect,x */ cycle(state, 7); add = fetch8(memory, state)+get_x(state); set_mem8(memory, add, or8(get_mem8(memory, add), fetch8(memory, state), state)); break; case 0x1d: /* bclr indirect,x */ cycle(state, 7); add = fetch8(memory, state)+get_x(state); set_mem8(memory, add, and8(get_mem8(memory, add), ~fetch8(memory, state), state)); break; case 0x1e: /* brset indirect,x mask dest */ cycle(state, 7); add = fetch8(memory, state)+get_x(state); temp = fetch8(memory, state) & get_mem8(memory, add); branch(state, memory, temp!=0); break; case 0x1f: /* brclr indirect,x mask dest */ cycle(state, 7); add = fetch8(memory, state)+get_x(state); temp = fetch8(memory, state) & get_mem8(memory, add); branch(state, memory, temp==0); break; case 0x20: /* bra */ cycle(state, 3); branch(state, memory, 1); break; case 0x21: /* brn */ cycle(state, 3); branch(state, memory, 0); break; case 0x22: /* bhi */ cycle(state, 3); branch(state, memory, (get_carry(state)|get_zero(state)) == 0); break; case 0x23: /* bls */ cycle(state, 3); branch(state, memory, (get_carry(state)|get_zero(state)) == 1); break; case 0x24: /* bhs or bcc */ cycle(state, 3); branch(state, memory, !get_carry(state)); break; case 0x25: /* blo or bcs */ cycle(state, 3); branch(state, memory, get_carry(state)); break; case 0x26: /* bne */ cycle(state, 3); branch(state, memory, !get_zero(state)); break; case 0x27: /* beq */ cycle(state, 3); branch(state, memory, get_zero(state)); break; case 0x28: /* bvc */ cycle(state, 3); branch(state, memory, !get_overflow(state)); break; case 0x29: /* bvs */ cycle(state, 3); branch(state, memory, get_overflow(state)); break; case 0x2a: /* bpl */ cycle(state, 3); branch(state, memory, !get_negative(state)); break; case 0x2b: /* bmi */ cycle(state, 3); branch(state, memory, get_negative(state)); break; case 0x2c: /* bge */ cycle(state, 3); branch(state, memory, (get_negative(state)^get_overflow(state))==0); printf("%d %d\n\n",get_negative(state),get_overflow(state)); break; case 0x2d: /* blt */ cycle(state, 3); branch(state, memory, (get_negative(state)^get_overflow(state))==1); break; case 0x2e: /* bgt */ cycle(state, 3); /* branch(state, memory, (get_zero(state)& (get_negative(state)& get_overflow(state)))==0); Replaced by jjp */ branch(state, memory, (get_zero(state)| (get_negative(state)^ get_overflow(state)))==0); break; case 0x2f: /* ble */ cycle(state, 3); /* branch(state, memory, (get_zero(state)& (get_negative(state)& get_overflow(state)))==1); Replaced by jjp */ branch(state, memory, (get_zero(state)| (get_negative(state)^ get_overflow(state)))==1); break; case 0x30: /* tsx */ cycle(state, 3); set_x(state, get_s(state)+1); break; case 0x31: /* ins */ cycle(state, 3); set_s(state, inc16(get_s(state), 1, NULL_STATE)); break; case 0x32: /* pula */ cycle(state, 4); set_s(state, inc16(get_s(state), 1, NULL_STATE)); set_a(state, get_mem8(memory, get_s(state))); break; case 0x33: /* pulb */ cycle(state, 4); set_s(state, inc16(get_s(state), 1, NULL_STATE)); set_b(state, get_mem8(memory, get_s(state))); break; case 0x34: /* des */ cycle(state, 3); set_s(state, inc16(get_s(state), -1, NULL_STATE)); break; case 0x35: /* txs */ cycle(state, 3); set_s(state, get_x(state)-1); break; case 0x36: /* psha */ cycle(state, 3); set_mem8(memory, get_s(state), get_a(state)); set_s(state, inc16(get_s(state), -1, NULL_STATE)); break; case 0x37: /* pshb */ cycle(state, 3); set_mem8(memory, get_s(state), get_b(state)); set_s(state, inc16(get_s(state), -1, NULL_STATE)); break; case 0x38: /* pulx */ cycle(state, 5); set_s(state, inc16(get_s(state), 1, NULL_STATE)); set_x(state, get_mem16(memory, get_s(state))); set_s(state, inc16(get_s(state), 1, NULL_STATE)); break; case 0x39: /* rts */ cycle(state, 5); set_s(state, inc16(get_s(state), 1, NULL_STATE)); temp = get_mem16(memory, get_s(state)); set_s(state, inc16(get_s(state), 1, NULL_STATE)); set_pc(state, temp); break; case 0x3a: /* abx */ cycle(state, 3); set_x(state, add16(get_b(state), get_x(state), NULL_STATE)); break; case 0x3b: /* rti */ cycle(state, 12); not_done(*state, memory); break; case 0x3c: /* pshx */ cycle(state, 4); temp = get_x(state); set_s(state, inc16(get_s(state), -1, NULL_STATE)); set_mem16(memory, get_s(state), temp); set_s(state, inc16(get_s(state), -1, NULL_STATE)); break; case 0x3d: /* mul */ cycle(state, 10); set_d(state, get_a(state)*get_b(state)); set_carry(state, (get_b(state)&0x80) != 0); break; case 0x3e: /* wai */ case 0x3f: /* swi */ cycle(state, 14); not_done(*state, memory); break; case 0x40: /* nega */ cycle(state, 2); set_a(state, sub8neg(get_a(state), state)); break; case 0x43: /* coma */ cycle(state, 2); set_a(state, xor8(0xff, get_a(state), state)); set_carry(state, 1); break; case 0x44: /* lsra */ cycle(state, 2); set_a(state, shift8(get_a(state), RIGHT, 0, state)); break; case 0x46: /* rora */ cycle(state, 2); set_a(state, shift8(get_a(state), RIGHT, get_carry(state), state)); break; case 0x47: /* asra */ cycle(state, 2); set_a(state, shift8(get_a(state), RIGHT, (get_a(state)&0x80)!=0, state)); break; case 0x48: /* asla or lsla */ cycle(state, 2); set_a(state, shift8(get_a(state), LEFT, 0, state)); break; case 0x49: /* rola */ cycle(state, 2); set_a(state, shift8(get_a(state), LEFT, get_carry(state), state)); break; case 0x4a: /* deca */ cycle(state, 2); set_a(state, inc8(get_a(state), -1, state)); break; case 0x4c: /* inca */ cycle(state, 2); set_a(state, inc8(get_a(state), 1, state)); break; case 0x4d: /* tsta */ cycle(state, 2); (void) sub8tst(get_a(state), state); break; case 0x4f: /* clra */ cycle(state, 2); /*set_a(state, sub8(get_a(state), get_a(state), state)); The above didn't set CC correctly. Replaced by jjp*/ set_a(state, add8(0, 0, state)); break; case 0x50: /* negb */ cycle(state, 2); set_b(state, sub8neg(get_b(state), state)); break; case 0x53: /* comb */ cycle(state, 2); set_b(state, xor8(0xff, get_b(state), state)); break; case 0x54: /* lsrb */ cycle(state, 2); set_b(state, shift8(get_b(state), RIGHT, 0, state)); break; case 0x56: /* rorb */ cycle(state, 2); set_b(state, shift8(get_b(state), RIGHT, get_carry(state), state)); break; case 0x57: /* asrb */ cycle(state, 2); set_b(state, shift8(get_b(state), RIGHT, (get_a(state)&0x80)!=0, state)); break; case 0x58: /* aslb or lslb */ cycle(state, 2); set_b(state, shift8(get_b(state), LEFT, 0, state)); break; case 0x59: /* rolb */ cycle(state, 2); set_a(state, shift8(get_a(state), LEFT, get_carry(state), state)); break; case 0x5a: /* decb */ cycle(state, 2); set_b(state, inc8(get_b(state), -1, state)); break; case 0x5c: /* incb */ cycle(state, 2); set_b(state, inc8(get_b(state), 1, state)); break; case 0x5d: /* tstb */ cycle(state, 2); (void) sub8tst(get_b(state), state); break; case 0x5f: /* clrb */ cycle(state, 2); /*set_b(state, sub8(get_b(state), get_b(state), state)); The above didn't set CC correctly. Replaced by jjp*/ set_b(state, add8(0, 0, state)); break; case 0x60: /* neg indirect,x */ cycle(state, 6); add = fetch8(memory, state)+get_x(state); set_mem8(memory, add, sub8neg(get_mem8(memory, add), state)); break; case 0x63: /* com indirect,x */ cycle(state, 6); add = fetch8(memory, state)+get_x(state); set_mem8(memory, add, xor8(0xff, get_mem8(memory, add), state)); break; case 0x64: /* lsr indirect,x */ cycle(state, 6); add = fetch8(memory, state)+get_x(state); set_mem8(memory, add, shift8(get_mem8(memory, add), RIGHT, 0, state)); break; case 0x66: /* ror indirect,x */ cycle(state, 6); add = fetch8(memory, state)+get_x(state); set_mem8(memory, add, shift8(get_mem8(memory, add), RIGHT, get_carry(state), state)); break; case 0x67: /* asr indirect,x */ cycle(state, 6); add = fetch8(memory, state)+get_x(state); set_mem8(memory, add, shift8(get_mem8(memory, add), RIGHT, (get_a(state)>>7)&1, state)); break; case 0x68: /* asl indirect,x */ cycle(state, 6); add = fetch8(memory, state)+get_x(state); set_mem8(memory, add, shift8(get_mem8(memory, add), LEFT, 0, state)); break; case 0x69: /* rol */ cycle(state, 6); add = fetch8(memory, state)+get_x(state); set_mem8(memory, add, shift8(get_mem8(memory, add), LEFT, get_carry(state), state)); break; case 0x6a: /* dec indirect,x */ cycle(state, 6); add = fetch8(memory, state)+get_x(state); set_mem8(memory, add, inc8(get_mem8(memory, add), -1, state)); break; case 0x6c: /* inc indirect,x */ cycle(state, 6); add = fetch8(memory, state)+get_x(state); set_mem8(memory, add, inc8(get_mem8(memory, add), 1, state)); break; case 0x6d: /* tst indirect,x */ cycle(state, 6); add = fetch8(memory, state)+get_x(state); sub8tst(get_mem8(memory, add), state); break; case 0x6e: /* jmp indirect,x */ cycle(state, 3); set_pc(state, fetch8(memory, state)+get_x(state)); break; case 0x6f: /* clr indirect,x */ cycle(state, 6); add = fetch8(memory, state)+get_x(state); set_mem8(memory, add, add8(0, 0, state)); break; case 0x70: /* neg extended */ cycle(state, 6); add = fetch16(memory, state); set_mem8(memory, add, sub8neg(get_mem8(memory, add), state)); break; case 0x73: /* com extended */ cycle(state, 6); add = fetch16(memory, state); set_mem8(memory, add, xor8(0xff, get_mem8(memory, add), state)); break; case 0x74: /* lsr extended */ cycle(state, 6); add = fetch16(memory, state); set_mem8(memory, add, shift8(get_mem8(memory, add), RIGHT, 0, state)); break; case 0x76: /* ror extended */ cycle(state, 6); add = fetch16(memory, state); set_mem8(memory, add, shift8(get_mem8(memory, add), RIGHT, get_carry(state), state)); break; case 0x77: /* asr extended */ cycle(state, 6); add = fetch16(memory, state); set_mem8(memory, add, shift8(get_mem8(memory, add), RIGHT, (get_a(state)>>7)&1, state)); break; case 0x78: /* asl extended */ cycle(state, 6); add = fetch16(memory, state); set_mem8(memory, add, shift8(get_mem8(memory, add), LEFT, 0, state)); break; case 0x79: /* rol extended */ cycle(state, 6); add = fetch16(memory, state); set_mem8(memory, add, shift8(get_mem8(memory, add), LEFT, get_carry(state), state)); break; case 0x7a: /* dec extended */ cycle(state, 6); add = fetch16(memory, state); set_mem8(memory, add, inc8(get_mem8(memory, add), -1, state)); break; case 0x7c: /* inc extended */ cycle(state, 6); add = fetch16(memory, state); set_mem8(memory, add, inc8(get_mem8(memory, add), 1, state)); break; case 0x7d: /* tst extended */ cycle(state, 6); add = fetch16(memory, state); sub8tst(get_mem8(memory, add), state); break; case 0x7e: /* jmp extended */ cycle(state, 3); set_pc(state, fetch16(memory, state)); break; case 0x7f: /* clr extended */ cycle(state, 6); add = fetch16(memory, state); set_mem8(memory, add, add8(0, 0, state)); break; case 0x80: /* suba immediate */ cycle(state, 2); set_a(state, sub8(get_a(state), fetch8(memory, state), state)); break; case 0x81: /* cmpa immediate */ cycle(state, 2); (void) sub8(get_a(state), fetch8(memory, state), state); break; case 0x82: /* sbca immediate */ cycle(state, 2); set_a(state, sub8(get_a(state), fetch8(memory+get_carry(state), state), state)); break; case 0x83: /* subd immediate */ cycle(state, 4); set_d(state, sub16(get_d(state), fetch16(memory, state), state)); break; case 0x84: /* anda immediate */ cycle(state, 2); set_a(state, and8(get_a(state), fetch8(memory, state), state)); break; case 0x85: /* bita immediate */ cycle(state, 2); (void) and8(get_a(state), fetch8(memory, state), state); break; case 0x86: /* ldaa immediate */ cycle(state, 2); set_a(state, fetch8(memory, state)); tst8(get_a(state), state); break; case 0x88: /* eora immediate */ cycle(state, 2); set_a(state, xor8(get_a(state), fetch8(memory, state), state)); break; case 0x89: /* adca immediate */ cycle(state, 2); set_a(state, add8(get_a(state)+get_carry(state), fetch8(memory, state), state)); break; case 0x8a: /* ora immediate */ cycle(state, 2); set_a(state, or8(get_a(state), fetch8(memory, state), state)); break; case 0x8b: /* adda immediate */ cycle(state, 2); set_a(state, add8(get_a(state), fetch8(memory, state), state)); break; case 0x8c: /* cpx immediate */ cycle(state, 4); (void) sub16(get_x(state), fetch16(memory, state), state); break; case 0x8d: /* bsr dest */ cycle(state, 6); temp = fetch8(memory, state); set_pc(state, get_pc(state)+temp); break; case 0x8e: /* lds immediate */ cycle(state, 3); set_s(state, fetch16(memory, state)); tst16(get_s(state), state); break; case 0x8f: /* xgdx */ cycle(state, 3); temp = get_x(state); set_x(state, get_d(state)); set_d(state, temp); break; case 0x90: /* suba direct */ cycle(state, 3); add = fetch8(memory, state); set_a(state, sub8(get_a(state), get_mem8(memory, add), state)); break; case 0x91: /* cmpa direct */ cycle(state, 3); add = fetch8(memory, state); (void) sub8(get_a(state), get_mem8(memory, add), state); break; case 0x92: /* sbca direct */ cycle(state, 3); add = fetch8(memory, state); set_a(state, sub8(get_a(state), get_mem8(memory, add), state)); break; case 0x93: /* subd direct */ cycle(state, 5); add = fetch8(memory, state); set_d(state, sub16(get_d(state), get_mem16(memory, add), state)); break; case 0x94: /* anda direct */ cycle(state, 3); add = fetch8(memory, state); set_a(state, and8(get_a(state), get_mem8(memory, add), state)); break; case 0x95: /* bita direct */ cycle(state, 3); add = fetch8(memory, state); (void) and8(get_a(state), get_mem8(memory, add), state); break; case 0x96: /* ldaa direct */ cycle(state, 3); add = fetch8(memory, state); set_a(state, get_mem8(memory, add)); tst8(get_a(state), state); break; case 0x97: /* sta direct */ cycle(state, 3); add = fetch8(memory, state); set_mem8(memory, add, get_a(state)); tst8(get_a(state), state); break; case 0x98: /* eora direct */ cycle(state, 3); add = fetch8(memory, state); set_a(state, xor8(get_a(state), get_mem8(memory, add), state)); break; case 0x99: /* adca direct */ cycle(state, 3); add = fetch8(memory, state); set_a(state, add8(get_a(state)+get_carry(state), get_mem8(memory, add), state)); break; case 0x9a: /* ora direct */ cycle(state, 3); add = fetch8(memory, state); set_a(state, or8(get_a(state), get_mem8(memory, add), state)); break; case 0x9b: /* adda direct */ cycle(state, 3); add = fetch8(memory, state); set_a(state, add8(get_a(state), get_mem8(memory, add), state)); break; case 0x9c: /* cpx direct */ cycle(state, 5); add = fetch8(memory, state); (void) sub16(get_x(state), get_mem16(memory, add), state); break; case 0x9d: /* jsr direct */ cycle(state, 5); set_pc(state, fetch8(memory, state)); break; case 0x9e: cycle(state, 4); add = fetch8(memory, state); set_s(state, get_mem16(memory, add)); break; case 0x9f: /* sts direct */ cycle(state, 4); add = fetch8(memory, state); tst16(get_s(state), state); set_mem16(memory, add, get_s(state)); break; case 0xa0: /* suba indirect,x */ cycle(state, 4); add = fetch8(memory, state)+get_x(state); set_a(state, sub8(get_a(state), get_mem8(memory, add), state)); break; case 0xa1: /* cmpa indirect,x */ cycle(state, 4); add = fetch8(memory, state)+get_x(state); (void) sub8(get_a(state), get_mem8(memory, add), state); break; case 0xa2: /* sbca indirect,x */ cycle(state, 4); add = fetch8(memory, state)+get_x(state); set_a(state, sub8(get_a(state), get_mem8(memory, add), state)); break; case 0xa3: /* subd indirect,x */ cycle(state, 6); add = fetch8(memory, state)+get_x(state); set_d(state, sub16(get_d(state), get_mem16(memory, add), state)); break; case 0xa4: /* anda indirect,x */ cycle(state, 4); add = fetch8(memory, state)+get_x(state); set_a(state, and8(get_a(state), get_mem8(memory, add), state)); break; case 0xa5: /* bita indirect,x */ cycle(state, 4); add = fetch8(memory, state)+get_x(state); (void) and8(get_a(state), get_mem8(memory, add), state); break; case 0xa6: /* ldaa indirect,x */ cycle(state, 4); add = fetch8(memory, state)+get_x(state); set_a(state, get_mem8(memory, add)); tst8(get_a(state), state); break; case 0xa7: /* sta indirect,x */ cycle(state, 4); add = fetch8(memory, state)+get_x(state); set_mem8(memory, add, get_a(state)); tst8(get_a(state), state); break; case 0xa8: /* eora indirect,x */ cycle(state, 4); add = fetch8(memory, state)+get_x(state); set_a(state, xor8(get_a(state), get_mem8(memory, add), state)); break; case 0xa9: /* adca indirect,x */ cycle(state, 4); add = fetch8(memory, state)+get_x(state); set_a(state, add8(get_a(state)+get_carry(state), get_mem8(memory, add), state)); break; case 0xaa: /* ora indirect,x */ cycle(state, 4); add = fetch8(memory, state)+get_x(state); set_a(state, or8(get_a(state), get_mem8(memory, add), state)); break; case 0xab: /* adda indirect,x */ cycle(state, 4); add = fetch8(memory, state)+get_x(state); set_a(state, add8(get_a(state), get_mem8(memory, add), state)); break; case 0xac: /* cpx indirect,x */ cycle(state, 6); add = fetch8(memory, state)+get_x(state); (void) sub16(get_x(state), get_mem16(memory, add), state); break; case 0xad: /* jsr indirect,x */ cycle(state, 6); set_pc(state, fetch8(memory, state)+get_x(state)); break; case 0xae: /* lds indirect,x */ cycle(state, 5); add = fetch8(memory, state)+get_x(state); set_s(state, get_mem16(memory, add)); tst16(get_s(state), state); break; case 0xaf: /* sts indirect,x */ cycle(state, 5); add = fetch8(memory, state)+get_x(state); tst16(get_s(state), state); set_mem16(memory, add, get_s(state)); break; case 0xb0: /* suba extended */ cycle(state, 4); add = fetch16(memory, state); set_a(state, sub8(get_a(state), get_mem8(memory,add), state)); break; case 0xb1: /* cmpa extended */ cycle(state, 4); add = fetch16(memory, state); (void) sub8(get_a(state), get_mem8(memory,add), state); break; case 0xb2: /* sbca extended */ cycle(state, 4); add = fetch16(memory, state); set_a(state, sub8(get_a(state), get_mem8(memory, add), state)); break; case 0xb3: /* subd extended */ cycle(state, 6); add = fetch16(memory, state); set_d(state, sub16(get_d(state), get_mem16(memory, add), state)); break; case 0xb4: /* anda extended */ cycle(state, 4); add = fetch16(memory, state); set_a(state, and8(get_a(state), get_mem8(memory, add), state)); break; case 0xb5: /* bita extended */ cycle(state, 4); add = fetch16(memory, state); (void) and8(get_a(state), get_mem8(memory, add), state); break; case 0xb6: /* ldaa extended */ cycle(state, 4); add = fetch16(memory, state); set_a(state, get_mem8(memory, add)); tst8(get_a(state), state); break; case 0xb7: /* sta extended */ cycle(state, 4); add = fetch16(memory, state); set_mem8(memory, add, get_a(state)); tst8(get_a(state), state); break; case 0xb8: /* eora extended */ cycle(state, 4); add = fetch16(memory, state); set_a(state, xor8(get_a(state), get_mem8(memory, add), state)); break; case 0xb9: /* adca extended */ cycle(state, 4); add = fetch16(memory, state); set_a(state, add8(get_a(state)+get_carry(state), get_mem8(memory, add), state)); break; case 0xba: /* ora extended */ cycle(state, 4); add = fetch16(memory, state); set_a(state, or8(get_a(state), get_mem8(memory, add), state)); break; case 0xbb: /* adda extended */ cycle(state, 4); add = fetch16(memory, state); set_a(state, add8(get_a(state), get_mem8(memory, add), state)); break; case 0xbc: /* cpx extended */ cycle(state, 6); add = fetch16(memory, state); (void) sub16(get_x(state), get_mem16(memory, add), state); break; case 0xbd: /* jsr extended */ cycle(state, 6); add = fetch16(memory, state); set_s(state, inc16(get_s(state), -2, NULL_STATE)); set_mem16(memory, get_s(state)+1, get_pc(state)); set_pc(state, add); break; case 0xbe: /* lds extended */ cycle(state, 5); add = fetch16(memory, state); set_s(state, get_mem16(memory, add)); tst16(get_s(state), state); break; case 0xbf: /* sts extended */ cycle(state, 5); add = fetch16(memory, state); tst16(get_s(state), state); set_mem16(memory, add, get_s(state)); break; case 0xc0: /* subb immediate */ cycle(state, 2); set_b(state, sub8(get_b(state), fetch8(memory, state), state)); break; case 0xc1: /* cmpb immediate */ cycle(state, 2); (void) sub8(get_b(state), fetch8(memory, state), state); break; case 0xc2: /* sbcb immediate */ cycle(state, 2); set_b(state, sub8(get_b(state), fetch8(memory+get_carry(state), state), state)); break; case 0xc3: /* addd immediate */ cycle(state, 4); set_d(state, add16(get_d(state), fetch16(memory, state), state)); break; case 0xc4: /* andb immediate */ cycle(state, 2); set_b(state, and8(get_b(state), fetch8(memory, state), state)); break; case 0xc5: /* bitb immediate */ (void) and8(get_b(state), fetch8(memory, state), state); break; case 0xc6: /* ldab immediate */ cycle(state, 2); set_b(state, fetch8(memory, state)); tst8(get_b(state), state); break; case 0xc8: /* eorb immediate */ cycle(state, 2); set_b(state, xor8(get_b(state), fetch8(memory, state), state)); break; case 0xc9: /* adcb immediate */ cycle(state, 2); set_b(state, add8(get_b(state)+get_carry(state), fetch8(memory, state), state)); break; case 0xca: /* orab immediate */ cycle(state, 2); set_b(state, or8(get_b(state), fetch8(memory, state), state)); break; case 0xcb: /* addb immediate */ cycle(state, 2); set_b(state, add8(get_b(state), fetch8(memory, state), state)); break; case 0xcc: /* ldd immediate */ cycle(state, 3); set_d(state, fetch16(memory, state)); tst16(get_d(state), state); break; case 0xce: /* ldx immediate */ cycle(state, 3); set_x(state, fetch16(memory, state)); tst16(get_x(state), state); break; case 0xcf: /* stop */ cycle(state, 2); set_pc(state, get_pc(state)-1); break; case 0xd0: /* subb direct */ cycle(state, 3); add = fetch8(memory, state); set_b(state, sub8(get_b(state), get_mem8(memory, add), state)); break; case 0xd1: /* cmpb direct */ cycle(state, 3); add = fetch8(memory, state); (void) sub8(get_b(state), get_mem8(memory, add), state); break; case 0xd2: /* sbcb direct */ cycle(state, 3); add = fetch8(memory, state); set_b(state, sub8(get_b(state), get_mem8(memory, add), state)); break; case 0xd3: /* add direct */ cycle(state, 5); add = fetch8(memory, state); set_d(state, add16(get_d(state), get_mem16(memory, add), state)); break; case 0xd4: /* andb direct */ cycle(state, 3); add = fetch8(memory, state); set_b(state, and8(get_b(state), get_mem8(memory, add), state)); break; case 0xd5: /* bitb direct */ cycle(state, 3); add = fetch8(memory, state); (void) and8(get_b(state), get_mem8(memory, add), state); break; case 0xd6: /* ldab direct */ cycle(state, 3); add = fetch8(memory, state); set_b(state, get_mem8(memory, add)); tst8(get_b(state), state); break; case 0xd7: /* stab direct */ cycle(state, 3); add = fetch8(memory, state); set_mem8(memory, add, get_b(state)); tst8(get_a(state), state); break; case 0xd8: /* eorb direct */ cycle(state, 3); add = fetch8(memory, state); set_b(state, xor8(get_b(state), get_mem8(memory, add), state)); break; case 0xd9: /* adcb direct */ cycle(state, 3); add = fetch8(memory, state); set_b(state, add8(get_b(state)+get_carry(state), get_mem8(memory, add), state)); break; case 0xda: /* orab direct */ cycle(state, 3); add = fetch8(memory, state); set_b(state, or8(get_b(state), get_mem8(memory, add), state)); break; case 0xdb: /* addb direct */ cycle(state, 3); add = fetch8(memory, state); set_b(state, add8(get_b(state), get_mem8(memory, add), state)); break; case 0xdc: /* ldd direct */ cycle(state, 4); add = fetch8(memory, state); set_d(state, get_mem16(memory, add)); tst16(get_d(state), state); break; case 0xdd: /* stad direct */ cycle(state, 4); add = fetch8(memory, state); set_mem16(memory, add, get_d(state)); tst8(get_a(state), state); break; case 0xde: /* ldx direct */ cycle(state, 4); add = fetch8(memory, state); set_x(state, get_mem16(memory, add)); tst16(get_x(state), state); break; case 0xdf: /* stx direct */ cycle(state, 4); add = fetch8(memory, state); set_mem16(memory, add, get_x(state)); break; case 0xe0: /* subb indirect,x */ cycle(state, 4); add = fetch8(memory, state)+get_x(state); set_b(state, sub8(get_b(state), get_mem8(memory, add), state)); break; case 0xe1: /* cmpb indirect,x */ cycle(state, 4); add = fetch8(memory, state)+get_x(state); (void) sub8(get_b(state), get_mem8(memory, add), state); break; case 0xe2: /* sbcb indirect,x */ cycle(state, 4); add = fetch8(memory, state)+get_x(state); set_b(state, sub8(get_b(state), get_mem8(memory, add), state)); break; case 0xe3: /* addd indirect,x */ cycle(state, 6); add = fetch8(memory, state)+get_x(state); set_d(state, add16(get_d(state), get_mem16(memory, add), state)); break; case 0xe4: /* andb indirect,x */ cycle(state, 4); add = fetch8(memory, state)+get_x(state); set_b(state, and8(get_b(state), get_mem8(memory, add), state)); break; case 0xe5: /* bitb indirect,x */ cycle(state, 4); add = fetch8(memory, state)+get_x(state); (void) and8(get_b(state), get_mem8(memory, add), state); break; case 0xe6: /* ldab indirect,x */ cycle(state, 4); add = fetch8(memory, state)+get_x(state); set_b(state, get_mem8(memory, add)); tst8(get_b(state), state); break; case 0xe7: /* stb indirect,x */ cycle(state, 4); add = fetch8(memory, state)+get_x(state); set_mem8(memory, add, get_b(state)); break; case 0xe8: /* eorb indirect,x */ cycle(state, 4); add = fetch8(memory, state)+get_x(state); set_b(state, xor8(get_b(state), get_mem8(memory, add), state)); break; case 0xe9: /* adcb indirect,x */ cycle(state, 4); add = fetch8(memory, state)+get_x(state); set_b(state, add8(get_b(state)+get_carry(state), get_mem8(memory, add), state)); break; case 0xea: /* orb indirect,x */ cycle(state, 4); add = fetch8(memory, state)+get_x(state); set_b(state, or8(get_b(state), get_mem8(memory, add), state)); break; case 0xeb: /* addb indirect,x */ cycle(state, 4); add = fetch8(memory, state)+get_x(state); set_b(state, add8(get_b(state), get_mem8(memory, add), state)); break; case 0xec: /* ldd indirect,x */ cycle(state, 5); add = fetch8(memory, state)+get_x(state); set_d(state, get_mem16(memory, add)); tst16(get_d(state), state); break; case 0xed: /* stad indirect,x */ cycle(state, 5); add = fetch8(memory, state)+get_x(state); set_mem16(memory, add, get_d(state)); tst8(get_a(state), state); break; case 0xee: /* ldx indirect,x */ cycle(state, 5); add = fetch8(memory, state)+get_x(state); set_x(state, get_mem16(memory, add)); tst16(get_x(state), state); break; case 0xef: /* stx direct */ cycle(state, 5); add = fetch8(memory, state)+get_x(state); set_mem16(memory, add, get_x(state)); break; case 0xf0: /* subb extended */ cycle(state, 4); add = fetch16(memory, state); set_b(state, sub8(get_b(state), get_mem8(memory,add), state)); break; case 0xf1: /* cmpb extended */ cycle(state, 4); add = fetch16(memory, state); (void) sub8(get_b(state), get_mem8(memory,add), state); break; case 0xf2: /* sbcb extended */ cycle(state, 4); add = fetch16(memory, state); set_b(state, sub8(get_b(state), get_mem8(memory, add), state)); break; case 0xf3: /* addd extended */ cycle(state, 6); add = fetch16(memory, state); set_d(state, add16(get_d(state), get_mem16(memory, add), state)); break; case 0xf4: /* andb extended */ cycle(state, 4); add = fetch16(memory, state); set_b(state, and8(get_b(state), get_mem8(memory, add), state)); break; case 0xf5: /* bitb extended */ cycle(state, 4); add = fetch16(memory, state); (void) and8(get_b(state), get_mem8(memory, add), state); break; case 0xf6: /* ldab extended */ cycle(state, 4); add = fetch16(memory, state); set_b(state, get_mem8(memory, add)); tst8(get_b(state), state); break; case 0xf7: /* stb extended */ cycle(state, 4); add = fetch16(memory, state); set_mem8(memory, add, get_b(state)); break; case 0xf8: /* eorb extended */ cycle(state, 4); add = fetch16(memory, state); set_b(state, xor8(get_b(state), get_mem8(memory, add), state)); break; case 0xf9: /* adcb extended */ cycle(state, 4); add = fetch16(memory, state); set_b(state, add8(get_b(state)+get_carry(state), get_mem8(memory, add), state)); break; case 0xfa: /* orb extended */ cycle(state, 4); add = fetch16(memory, state); set_b(state, or8(get_b(state), get_mem8(memory, add), state)); break; case 0xfb: /* addb extended */ cycle(state, 4); add = fetch16(memory, state); set_b(state, add8(get_b(state), get_mem8(memory, add), state)); break; case 0xfc: /* ldd extended */ cycle(state, 5); add = fetch16(memory, state); set_d(state, get_mem16(memory, add)); tst16(get_d(state), state); break; case 0xfd: /* stad extended */ cycle(state, 5); /* add = fetch16(memory, state)+get_x(state); replaced by jjp*/ add = fetch16(memory, state); set_mem16(memory, add, get_d(state)); tst8(get_a(state), state); break; case 0xfe: /* ldx extended */ cycle(state, 5); /* add = fetch16(memory, state)+get_x(state); jjp */ add = fetch16(memory, state); set_x(state, get_mem16(memory, add)); tst16(get_x(state), state); break; case 0xff: /* stx extended */ cycle(state, 5); /* add = fetch16(memory, state)+get_x(state); jjp */ add = fetch16(memory, state); set_mem16(memory, add, get_x(state)); break; case 0x18: /* magic page prefix */ switch (fetch8(memory, state)) { case 0x08: /* iny */ cycle(state, 4); set_y(state, inc16(get_y(state), 1, state)); break; case 0x09: /* dey */ cycle(state, 4); set_y(state, inc16(get_y(state), -1, state)); break; case 0x1c: /* bset indirect,y */ cycle(state, 8); add = fetch8(memory, state)+get_y(state); set_mem8(memory, add, or8(get_mem8(memory, add), fetch8(memory, state), state)); break; case 0x1d: /* bclr indirect,y */ cycle(state, 8); add = fetch8(memory, state)+get_y(state); set_mem8(memory, add, and8(get_mem8(memory, add), ~fetch8(memory, state), state)); break; case 0x1e: /* brset indirect,y mask dest */ cycle(state, 8); add = fetch8(memory, state)+get_y(state); temp = fetch8(memory, state) & get_mem8(memory, add); branch(state, memory, temp!=0); break; case 0x1f: /* brclr indirect,y mask dest */ cycle(state, 8); add = fetch8(memory, state)+get_y(state); temp = fetch8(memory, state) & get_mem8(memory, add); branch(state, memory, temp==0); break; case 0x30: /* tsy */ cycle(state, 4); set_y(state, get_s(state)+1); break; case 0x35: /* tys */ cycle(state, 4); set_s(state, get_y(state)-1); break; case 0x38: /* puly */ cycle(state, 6); set_s(state, inc16(get_s(state), 1, NULL_STATE)); set_y(state, get_mem16(memory, get_s(state))); set_s(state, inc16(get_s(state), 1, NULL_STATE)); break; case 0x3a: /* aby */ cycle(state, 4); set_y(state, add16(get_b(state), get_y(state), NULL_STATE)); break; case 0x3c: /* pshy */ cycle(state, 5); temp = get_y(state); set_s(state, inc16(get_s(state), -1, NULL_STATE)); set_mem16(memory, get_s(state), temp); set_s(state, inc16(get_s(state), -1, NULL_STATE)); break; case 0x60: /* neg indirect,y */ cycle(state, 7); add = fetch8(memory, state)+get_y(state); set_mem8(memory, add, sub8neg(get_mem8(memory, add), state)); break; case 0x63: /* com indirect,y */ cycle(state, 7); add = fetch8(memory, state)+get_y(state); set_mem8(memory, add, xor8(0xff, get_mem8(memory, add), state)); break; case 0x64: /* lsr indirect,y */ cycle(state, 7); add = fetch8(memory, state)+get_y(state); set_mem8(memory, add, shift8(get_mem8(memory, add), RIGHT, 0, state)); break; case 0x66: /* ror indirect,y */ cycle(state, 7); add = fetch8(memory, state)+get_y(state); set_mem8(memory, add, shift8(get_mem8(memory, add), RIGHT, get_carry(state), state)); break; case 0x67: /* asr indirect,y */ cycle(state, 7); add = fetch8(memory, state)+get_y(state); set_mem8(memory, add, shift8(get_mem8(memory, add), RIGHT, (get_a(state)>>7)&1, state)); break; case 0x68: /* asl indirect,y */ cycle(state, 7); add = fetch8(memory, state)+get_y(state); set_mem8(memory, add, shift8(get_mem8(memory, add), LEFT, 0, state)); break; case 0x69: /* rol */ cycle(state, 7); add = fetch8(memory, state)+get_y(state); set_mem8(memory, add, shift8(get_mem8(memory, add), LEFT, get_carry(state), state)); break; case 0x6a: /* dec indirect,y */ cycle(state, 7); add = fetch8(memory, state)+get_y(state); set_mem8(memory, add, inc8(get_mem8(memory, add), -1, state)); break; case 0x6c: /* inc indirect,y */ cycle(state, 7); add = fetch8(memory, state)+get_y(state); set_mem8(memory, add, inc8(get_mem8(memory, add), 1, state)); break; case 0x6d: /* tst indirect,y */ cycle(state, 7); add = fetch8(memory, state)+get_y(state); sub8tst(get_mem8(memory, add), state); break; case 0x6e: /* jmp indirect,y */ cycle(state, 4); set_pc(state, fetch8(memory, state)+get_y(state)); break; case 0x6f: /* clr indirect,y */ cycle(state, 7); add = fetch8(memory, state)+get_y(state); set_mem8(memory, add, add8(0, 0, state)); break; case 0x8c: /* cpy immediate */ cycle(state, 5); (void) sub16(get_y(state), fetch16(memory, state), state); break; case 0x8f: /* xgdy */ cycle(state, 4); temp = get_y(state); set_y(state, get_d(state)); set_d(state, temp); break; case 0x9c: /* cpy direct */ cycle(state, 6); add = fetch8(memory, state); (void) sub16(get_y(state), get_mem16(memory, add), state); break; case 0xa0: /* suba indirect,y */ cycle(state, 5); add = fetch8(memory, state)+get_y(state); set_a(state, sub8(get_a(state), get_mem8(memory, add), state)); break; case 0xa1: /* cmpa indirect,y */ cycle(state, 5); add = fetch8(memory, state)+get_y(state); (void) sub8(get_a(state), get_mem8(memory, add), state); break; case 0xa2: /* sbca indirect,y */ cycle(state, 5); add = fetch8(memory, state)+get_y(state); set_a(state, sub8(get_a(state), get_mem8(memory, add), state)); break; case 0xa3: /* subd indirect,y */ cycle(state, 7); add = fetch8(memory, state)+get_y(state); set_d(state, sub16(get_d(state), get_mem16(memory, add), state)); break; case 0xa4: /* anda indirect,y */ cycle(state, 5); add = fetch8(memory, state)+get_y(state); set_a(state, and8(get_a(state), get_mem8(memory, add), state)); break; case 0xa5: /* bita indirect,y */ cycle(state, 5); add = fetch8(memory, state)+get_y(state); (void) and8(get_a(state), get_mem8(memory, add), state); break; case 0xa6: /* ldaa indirect,y */ cycle(state, 5); add = fetch8(memory, state)+get_y(state); set_a(state, get_mem8(memory, add)); tst8(get_a(state), state); break; case 0xa7: /* sta indirect,y */ cycle(state, 5); add = fetch8(memory, state)+get_y(state); set_mem8(memory, add, get_a(state)); tst8(get_a(state), state); break; case 0xa8: /* eora indirect,y */ cycle(state, 5); add = fetch8(memory, state)+get_y(state); set_a(state, xor8(get_a(state), get_mem8(memory, add), state)); break; case 0xa9: /* adca indirect,y */ cycle(state, 5); add = fetch8(memory, state)+get_y(state); set_a(state, add8(get_a(state)+get_carry(state), get_mem8(memory, add), state)); break; case 0xaa: /* ora indirect,y */ cycle(state, 5); add = fetch8(memory, state)+get_y(state); set_a(state, or8(get_a(state), get_mem8(memory, add), state)); break; case 0xab: /* adda indirect,y */ cycle(state, 5); add = fetch8(memory, state)+get_y(state); set_a(state, add8(get_a(state), get_mem8(memory, add), state)); break; case 0xac: /* cpy indirect,y */ cycle(state, 7); add = fetch8(memory, state)+get_y(state); (void) sub16(get_y(state), get_mem16(memory, add), state); break; case 0xad: /* jsr indirect,y */ cycle(state, 7); set_pc(state, fetch8(memory, state)+get_y(state)); break; case 0xae: /* lds indirect,y */ cycle(state, 6); add = fetch8(memory, state)+get_y(state); set_s(state, get_mem16(memory, add)); tst16(get_s(state), state); break; case 0xaf: /* sts indirect,y */ cycle(state, 6); add = fetch8(memory, state)+get_y(state); tst16(get_s(state), state); set_mem16(memory, add, get_s(state)); break; case 0xbc: /* cpy extended */ cycle(state, 7); add = fetch16(memory, state); (void) sub16(get_y(state), get_mem16(memory, add), state); break; case 0xce: /* ldy immediate */ cycle(state, 4); set_y(state, fetch16(memory, state)); tst16(get_y(state), state); break; case 0xde: /* ldy direct */ cycle(state, 5); add = fetch8(memory, state); set_y(state, get_mem16(memory, add)); tst16(get_y(state), state); break; case 0xdf: /* sty direct */ cycle(state, 5); add = fetch8(memory, state); set_mem16(memory, add, get_y(state)); tst16(get_y(state), state); break; case 0xe0: /* subb indirect,y */ cycle(state, 5); add = fetch8(memory, state)+get_y(state); set_b(state, sub8(get_b(state), get_mem8(memory, add), state)); break; case 0xe1: /* cmpb indirect,y */ cycle(state, 5); add = fetch8(memory, state)+get_y(state); (void) sub8(get_b(state), get_mem8(memory, add), state); break; case 0xe2: /* sbcb indirect,y */ cycle(state, 5); add = fetch8(memory, state)+get_y(state); set_b(state, sub8(get_b(state), get_mem8(memory, add), state)); break; case 0xe3: /* addd indirect,y */ cycle(state, 7); add = fetch8(memory, state)+get_y(state); set_d(state, add16(get_d(state), get_mem16(memory, add), state)); break; case 0xe4: /* andb indirect,y */ cycle(state, 5); add = fetch8(memory, state)+get_y(state); set_b(state, and8(get_b(state), get_mem8(memory, add), state)); break; case 0xe5: /* bitb indirect,y */ cycle(state, 5); add = fetch8(memory, state)+get_y(state); (void) and8(get_b(state), get_mem8(memory, add), state); break; case 0xe6: /* ldab indirect,y */ cycle(state, 5); add = fetch8(memory, state)+get_y(state); set_b(state, get_mem8(memory, add)); tst8(get_b(state), state); break; case 0xe7: /* stb indirect,y */ cycle(state, 5); add = fetch8(memory, state)+get_y(state); set_mem8(memory, add, get_b(state)); break; case 0xe8: /* eorb indirect,y */ cycle(state, 5); add = fetch8(memory, state)+get_y(state); set_b(state, xor8(get_b(state), get_mem8(memory, add), state)); break; case 0xe9: /* adcb indirect,y */ cycle(state, 5); add = fetch8(memory, state)+get_y(state); set_b(state, add8(get_b(state)+get_carry(state), get_mem8(memory, add), state)); break; case 0xea: /* orb indirect,y */ cycle(state, 5); add = fetch8(memory, state)+get_y(state); set_b(state, or8(get_b(state), get_mem8(memory, add), state)); break; case 0xeb: /* addb indirect,y */ cycle(state, 5); add = fetch8(memory, state)+get_y(state); set_b(state, add8(get_b(state), get_mem8(memory, add), state)); break; case 0xec: /* ldd indirect,y */ cycle(state, 6); add = fetch8(memory, state)+get_y(state); set_d(state, get_mem16(memory, add)); tst16(get_d(state), state); break; case 0xed: /* stad indirect,y */ cycle(state, 6); add = fetch8(memory, state)+get_y(state); set_mem16(memory, add, get_d(state)); tst8(get_a(state), state); break; case 0xee: /* ldy direct */ cycle(state, 6); add = fetch8(memory, state)+get_y(state); set_y(state, get_mem16(memory, add)); tst16(get_y(state), state); break; case 0xef: /* sty direct */ cycle(state, 6); add = fetch8(memory, state)+get_y(state); set_mem16(memory, add, get_y(state)); tst16(get_y(state), state); break; case 0xfe: /* ldy extended */ cycle(state, 6); add = fetch16(memory, state)+get_y(state); set_y(state, get_mem16(memory, add)); tst16(get_y(state), state); break; case 0xff: /* sty extended */ cycle(state, 6); add = fetch16(memory, state)+get_y(state); set_mem16(memory, add, get_y(state)); tst16(get_y(state), state); break; default: bad_op(*state); break; } break; case 0x1a: /* magic page prefix */ switch(fetch8(memory, state)) { case 0x83: /* cpd # */ cycle(state, 5); temp = fetch16(memory, state); (void) sub16(get_d(state), temp, state); break; case 0x93: /* cpd direct */ cycle(state, 6); temp = fetch8(memory, state); (void) sub16(get_d(state), get_mem16(memory, temp), state); break; case 0xa3: /* cpd indirect,x */ cycle(state, 7); temp = fetch8(memory, state)+get_x(state); (void) sub16(get_d(state), get_mem16(memory, temp), state); break; case 0xac: /* cpy indirect,x */ cycle(state, 7); temp = fetch8(memory, state)+get_y(state); (void) sub16(get_d(state), get_mem16(memory, temp), state); break; case 0xb3: /* cpd extended */ cycle(state, 7); temp = fetch16(memory, state); (void) sub16(get_d(state), get_mem16(memory, temp), state); break; case 0xee: /* ldy indirect,x */ cycle(state, 6); temp = fetch8(memory, state)+get_x(state); set_y(state, get_mem16(memory, temp)); tst16(get_y(state), state); break; case 0xef: /* sty indirect,x */ cycle(state, 6); temp = fetch8(memory, state)+get_x(state); set_mem16(memory, temp, get_y(state)); tst16(get_y(state), state); break; default: /* most ops in page are illegal */ bad_op(*state); break; } break; case 0xcd: /* page 4 prefix */ switch(fetch8(memory, state)) { case 0xa3: /* cpd indirect,y */ cycle(state, 7); add = fetch8(memory, state) + get_y(state); (void) sub16(get_d(state), get_mem16(memory, add), state); break; case 0xac: /* cpx indirect,y */ cycle(state, 7); add = fetch8(memory, state) + get_y(state); (void) sub16(get_x(state), get_mem16(memory, add), state); break; case 0xee: /* ldx indirect,y */ cycle(state, 6); add = fetch8(memory, state) + get_y(state); set_x(state, get_mem16(memory, add)); tst16(get_x(state), state); break; case 0xef: /* stx indirect,y */ cycle(state, 6); add = fetch8(memory, state) + get_y(state); set_mem16(memory, add, get_x(state)); tst16(get_x(state), state); break; default: /* only a few legal ops */ bad_op(*state); break; } break; default: bad_op(*state); break; } }