--- M6502/M6502.xs 2007/08/03 09:18:08 108 +++ M6502/M6502.xs 2008/04/13 00:32:39 195 @@ -10,8 +10,20 @@ M6502 *R = NULL; int debug = 0; +// same as memory size +#define CACHE_SIZE 0xffff byte opCache[CACHE_SIZE]; +#define CALLBACK_READ_SKIP 0x00 +#define CALLBACK_READ_ONCE 0x01 +#define CALLBACK_READ_ALWAYS 0x02 +#define CALLBACK_READ_MASK 0x0f +#define CALLBACK_WRITE_SKIP 0x00 +#define CALLBACK_WRITE_ONCE 0x10 +#define CALLBACK_WRITE_ALWAYS 0x20 +#define CALLBACK_WRITE_MASK 0xf0 +byte perlCallBack[CACHE_SIZE]; + void update_C_R(void) { R->A = SvIV( get_sv("M6502::A", FALSE) ); R->P = SvIV( get_sv("M6502::P", FALSE) ); @@ -71,7 +83,13 @@ /** required if there is a #define FAST_RDOP. **/ /************************************ TO BE WRITTEN BY USER **/ -byte mem(word Addr) { +byte mem(register word Addr) { + + if ( perlCallBack[Addr] & CALLBACK_READ_MASK == CALLBACK_READ_SKIP ) + return opCache[Addr]; + if ( perlCallBack[Addr] & CALLBACK_READ_MASK == CALLBACK_READ_ONCE ) + perlCallBack[Addr] = perlCallBack[Addr] & CALLBACK_WRITE_MASK | CALLBACK_READ_SKIP; + byte byte; int count; debugf(("mem(%04x)", Addr)); @@ -112,6 +130,9 @@ void Wr6502(register word Addr,register byte Value) { debugf(("Wr6502(%04x,%02x)", Addr, Value)); opCache[Addr] = Value; + if ( perlCallBack[Addr] & CALLBACK_WRITE_MASK == CALLBACK_WRITE_SKIP ) return; + if ( perlCallBack[Addr] & CALLBACK_WRITE_MASK == CALLBACK_WRITE_ONCE ) + perlCallBack[Addr] = perlCallBack[Addr] & CALLBACK_READ_MASK | CALLBACK_WRITE_SKIP; dSP; ENTER; SAVETMPS; @@ -126,7 +147,6 @@ byte Op6502(register word Addr) { byte Op; - if ( opCache[Addr] ) return opCache[Addr]; Op = mem(Addr); debugf(("Op6502(%04x,%02x) PC:%04x", Addr, Op, R->PC.W)); return Op; @@ -174,7 +194,8 @@ PerlIO_stdoutf("can't alloc %d bytes for M6502", sizeof(M6502)); exit(1); } - memset( opCache, 0, sizeof(opCache) ); + memset( opCache, 0, CACHE_SIZE ); + memset( perlCallBack, CALLBACK_READ_ALWAYS | CALLBACK_WRITE_ALWAYS, CACHE_SIZE ); } Reset6502(R); debugf(("Reset6502 over")); @@ -205,6 +226,22 @@ return debug; } +/* FIXME somehow check if Addr will fit in int on current platform */ +void set_read_callback(int Addr) { + perlCallBack[Addr] == perlCallBack[Addr] & CALLBACK_WRITE_MASK | CALLBACK_READ_ALWAYS; +} + +void set_write_callback(int Addr) { + perlCallBack[Addr] == perlCallBack[Addr] & CALLBACK_READ_MASK | CALLBACK_WRITE_ALWAYS; +} + +/* we fake here, since we will need to call perl at least once to get initial value... */ +int disable_all_callbacks(void) { + memset( perlCallBack, CALLBACK_READ_ONCE | CALLBACK_WRITE_ONCE, CACHE_SIZE ); + return perlCallBack[0]; +} + + MODULE = M6502 PACKAGE = M6502 PROTOTYPES: DISABLE @@ -226,3 +263,13 @@ int exec(int cycles) + +void +set_read_callback(int Addr) + +void +set_write_callback(int Addr) + +int +disable_all_callbacks() +