Beispiel #1
0
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;
}
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;
}