int main() { M6502 *mpu = M6502_new(0, 0, 0); /* Make a 6502 */ unsigned pc = 0x1000; /* PC for 'assembly' */ /* Install the two callback functions defined above. */ M6502_setCallback(mpu, call, WRCH, wrch); /* Calling FFEE -> wrch() */ M6502_setCallback(mpu, call, 0, done); /* Calling 0 -> done() */ /* A few macros that dump bytes into the 6502's memory. */ # define gen1(X) (mpu->memory[pc++]= (uint8_t)(X)) # define gen2(X,Y) gen1(X); gen1(Y) # define gen3(X,Y,Z) gen1(X); gen2(Y,Z) /* Hand-assemble the program. */ gen2(0xA2, 'A' ); // LDX #'A' gen1(0x8A ); // TXA gen3(0x20,0xEE,0xFF); // JSR FFEE gen1(0xE8 ); // INX gen2(0xE0, 'Z'+1 ); // CPX #'Z'+1 gen2(0xD0, -9 ); // BNE 0x1002 gen2(0xA9, '\n' ); // LDA #'\n' gen3(0x20,0xEE,0xFF); // JSR FFEE gen2(0x00,0x00 ); // BRK /* Just for fun: disssemble the program. */ { char insn[64]; uint16_t ip= 0x1000; while (ip < pc) { ip += M6502_disassemble(mpu, ip, insn); printf("%04X %s\n", ip, insn); } } /* Point the RESET vector at the first instruction in the assembled * program. */ M6502_setVector(mpu, RST, 0x1000); /* Reset the 6502 and run the program. */ M6502_reset(mpu); M6502_run(mpu); M6502_delete(mpu); /* We never reach here, but what the hey. */ return 0; }
static int gen2(int len, long r1) { int i; if(len <= 0) { if(r1 == mulval) return 1; return 0; } len--; if(len == 0) goto calcr0; if(gen3(len, r1, r1+1, UR1)) { i = '+'; goto out; } if(gen3(len, r1-1, r1, UR0)) { i = '-'; goto out; } if(gen3(len, 1, r1+1, UR1)) { i = '+'; goto out; } if(gen3(len, 1, r1-1, UR1)) { i = '-'; goto out; } return 0; calcr0: if(mulval == r1+1) { i = '+'; goto out; } if(mulval == r1-1) { i = '-'; goto out; } return 0; out: *--mulcp = i; return 1; }
BOOST_AUTO_TEST_CASE_TEMPLATE(generator_test, engine_type, engines) { typedef typename engine_type::result_type test_type; engine_type gen; gen.seed(); test_type a = gen.min(); test_type b = gen.max(); BOOST_CHECK(a < b); a = gen(); // // This extracts 32-bit values for use in seeding other sequences, // not really applicable here, and not functional for signed types anyway. //gen.generate(&b, &b + 1); gen.discard(20); typename engine_type::base_type base(gen.base()); std::stringstream ss; ss << gen; engine_type gen2; ss >> gen2; BOOST_CHECK(gen == gen2); gen2(); BOOST_CHECK(gen != gen2); // // construction and seeding: // engine_type gen3(0); gen3.seed(2); }
int main() { srand((unsigned)time(NULL)); for (int i = 1; i <= 4; ++i) gen1(i); for (int i = 5; i <= 8; ++i) gen2(i); for (int i = 9; i <= 12; ++i) gen3(i); for (int i = 13; i <= 16; ++i) gen4(i); for (int i = 17; i <= 20; ++i) gen5(i); return 0; }
int wr(M6502 *mpu, uint16_t address, uint8_t data) { if (address != 0x42) { abort(); } unsigned pc = 0x6000; gen2(0xa9, data); // LDA #data gen3(0x4c, 0x00, 0x20); // JMP &2000 return 0; }
int main(int argc, char *argv[]) { M6502 *mpu = M6502_new(0, 0, 0); parse_args(argc, argv, mpu); unsigned pc = 0x1000; unsigned saved_pc; M6502_setCallback(mpu, call, 0, done ); M6502_setCallback(mpu, call, 0xffee, oswrch); gen2(0xa2, 0xff ); // LDX #&FF gen1(0x9a ); // TXS gen2(0xa9, 'A' ); // LDA #'A' // LDA #'B' is 0xa9, 0x42. So if we execute a JSR at 0x42a7, it will // push 0x42 and then 0xa9 onto the stack. Since the stack grows downwards // those bytes will be in the right order for execution. gen3(0x4c, 0xa7, 0x42); // JMP &42A7 pc = 0x42a7; gen3(0x20, 0x00, 0x30); // JSR &3000 saved_pc = pc; pc = 0x3000; gen3(0x4c, 0xfe, 0x01); // JMP &01FE pc = 0x200; gen3(0x20, 0xee, 0xff); // JSR &FFEE gen1(0x60 ); // RTS pc = saved_pc; // Let's do the same thing again, but this time code has already been // executed from that address on the stack, so we're verifying the change // is picked up. We do LDA #'C' this time, so we execute the JSR from // 0x43a7. gen3(0x4c, 0xa7, 0x43); // JMP &43A7 pc = 0x43a7; gen3(0x20, 0x00, 0x30); // JSR &3000 gen2(0x00, 0x00 ); // BRK M6502_setVector(mpu, RST, 0x1000); M6502_reset(mpu); M6502_run(mpu); M6502_delete(mpu); /* We never reach here, but what the hey. */ return 0; }
int main(int argc, char *argv[]) { M6502 *mpu = M6502_new(0, 0, 0); parse_args(argc, argv, mpu); unsigned pc = 0x1000; M6502_setCallback(mpu, call, 0, done); M6502_setCallback(mpu, call, 0xffee, oswrch); M6502_setCallback(mpu, write, 0x42, wr ); gen2(0xa9, '>' ); // LDA #'>' gen3(0x20, 0xee, 0xff); // JSR &FFEE gen2(0xa2, 'A' ); // LDX #'A' gen3(0x8e, 0x42, 0x00); // STX &0042 gen3(0x20, 0x00, 0x60); // JSR &6000 gen1(0xe8 ); // INX gen2(0xe0, 'Z'+1 ); // CPX #('Z'+1) gen2(0x90, 0xf5 ); // BCC to STX gen2(0xa0, 0x05 ); // LDY #&05 gen2(0xa9, '>' ); // LDA #'>' gen3(0x20, 0xee, 0xff); // JSR &FFEE gen2(0xa2, 'A' ); // LDX #'A' gen2(0x96, 0x42-0x05 ); // STX (&42-&05),Y gen3(0x20, 0x00, 0x60); // JSR &6000 gen1(0xe8 ); // INX gen2(0xe0, 'Z'+1 ); // CPX #('Z'+1) gen2(0x90, 0xf6 ); // BCC to STX gen2(0x00, 0x00 ); // BRK pc = 0x2000; gen3(0x20, 0xee, 0xff); // JSR &FFEE gen1(0x60 ); // RTS M6502_setVector(mpu, RST, 0x1000); M6502_reset(mpu); M6502_run(mpu); M6502_delete(mpu); /* We never reach here, but what the hey. */ return 0; }
int main(int argc, char *argv[]) { M6502 *mpu = M6502_new(0, 0, 0); parse_args(argc, argv, mpu); unsigned pc = 0x1000; unsigned saved_pc; M6502_setCallback(mpu, call, 0xf000, done ); M6502_setCallback(mpu, call, 0xffee, oswrch); gen2(0xa2, 0xff ); // LDX #&FF gen1(0x9a ); // TXS gen2(0xa9, 'A' ); // LDA #'A' // LDA #'B' is 0xa9, 0x42. So if we execute a BRK at 0x42a7, it will // push 0x42, 0xa9 and the flags onto the stack. Since the stack grows // downwards those bytes will be in the right order for execution. We'll // additionally push an LDX immediate opcode so we can "execute" the flags // value. We can nearly force the flags to be whatever we like using PLP, // although the BRK will set the B and X bits in the stacked value. We // demonstrate this by explicitly masking off those bits in the values we // force into the flags. enum { flagX= (1<<5), /* unused */ flagB= (1<<4) /* irq from brk */ }; uint8_t mask = ~(flagX | flagB); gen2(0xa0, '0' & mask); // LDY #('0' with B/X masked off) gen1(0x5a ); // PHY gen1(0x28 ); // PLP gen3(0x4c, 0xa7, 0x42); // JMP &42A7 pc = 0x42a7; gen2(0x00, 0x00 ); // BRK saved_pc = pc; pc = 0x0; // BRK vector gen2(0xa9, 0xa2 ); // LDA #<LDX # opcode> gen1(0x48 ); // PHA gen3(0x4c, 0xfc, 0x01); // JMP &01FC pc = 0x200; gen3(0x20, 0xee, 0xff); // JSR &FFEE gen1(0x8a ); // TXA gen3(0x20, 0xee, 0xff); // JSR &FFEE gen1(0x68 ); // PLA gen1(0x40 ); // RTI pc = saved_pc; // Let's do the same thing again, but this time code has already been // executed from that address on the stack, so we're verifying the change // is picked up. We do LDA #'C' this time, so we execute the BRK from // 0x43a7. gen2(0xa0, '1' & mask); // LDY #('1' with B/X masked off) gen1(0x5a ); // PHY gen1(0x28 ); // PLP gen3(0x4c, 0xa7, 0x43); // JMP &43A7 pc = 0x43a7; gen2(0x00, 0x00 ); // BRK gen3(0x4c, 0x00, 0xf0); // JMP &F000 (quit) M6502_setVector(mpu, RST, 0x1000); M6502_reset(mpu); M6502_run(mpu); M6502_delete(mpu); /* We never reach here, but what the hey. */ return 0; }
static int gen3(int len, long r0, long r1, int flag) { int i, f1, f2; long x; if(r0 <= 0 || r0 >= r1 || r1 > valmax) return 0; len--; if(len == 0) goto calcr0; if(!(flag & UR1)) { f1 = UR1|SR1; for(i=1; i<=shmax; i++) { x = r0<<i; if(x > valmax) break; if(gen3(len, r0, x, f1)) { i += 'a'; goto out; } } } if(!(flag & UR0)) { f1 = UR1|SR1; for(i=1; i<=shmax; i++) { x = r1<<i; if(x > valmax) break; if(gen3(len, r1, x, f1)) { i += 'a'; goto out; } } } if(!(flag & SR1)) { f1 = UR1|SR1|(flag&UR0); for(i=1; i<=shmax; i++) { x = r1<<i; if(x > valmax) break; if(gen3(len, r0, x, f1)) { i += 'a'; goto out; } } } if(!(flag & SR0)) { f1 = UR0|SR0|(flag&(SR1|UR1)); f2 = UR1|SR1; if(flag & UR1) f2 |= UR0; if(flag & SR1) f2 |= SR0; for(i=1; i<=shmax; i++) { x = r0<<i; if(x > valmax) break; if(x > r1) { if(gen3(len, r1, x, f2)) { i += 'a'; goto out; } } else if(gen3(len, x, r1, f1)) { i += 'a'; goto out; } } } x = r1+r0; if(gen3(len, r0, x, UR1)) { i = '+'; goto out; } if(gen3(len, r1, x, UR1)) { i = '+'; goto out; } x = r1-r0; if(gen3(len, x, r1, UR0)) { i = '-'; goto out; } if(x > r0) { if(gen3(len, r0, x, UR1)) { i = '-'; goto out; } } else if(gen3(len, x, r0, UR0)) { i = '-'; goto out; } return 0; calcr0: f1 = flag & (UR0|UR1); if(f1 == UR1) { for(i=1; i<=shmax; i++) { x = r1<<i; if(x >= mulval) { if(x == mulval) { i += 'a'; goto out; } break; } } } if(mulval == r1+r0) { i = '+'; goto out; } if(mulval == r1-r0) { i = '-'; goto out; } return 0; out: *--mulcp = i; return 1; }