#define lobyte(x) (x&0xFF) #define hibyte(x) ((x>>8)&0xFF) #define wordfrombytes(h,l) (((h<<8)&0xFF00)|(l&0xFF)) #define popbyte readmemory(--cpu->s) #define loadimmed readmemory(cpu->i++) #define loadstackrel readmemory((cpu->s+signed8(cpu->t))%65536) #define loadstackrelp1 readmemory((cpu->s+signed8(cpu->t)+1)%65536) #define wordut (wordfrombytes(cpu->u, cpu->t)) #define wordcb (wordfrombytes(cpu->c, cpu->b)) #define loadut readmemory(wordut) #define loadutp1 readmemory((wordut+1)%65536) #define loadp readmemory(cpu->p) #define loadpinc readmemory(cpu->p++) #define loadpp1 readmemory((cpu->p+1)%65536) #define loadq readmemory(cpu->q) #define loadqinc readmemory(cpu->q++) #define loadqp1 readmemory((cpu->q+1)%65536) #define signed8(x) (x>=128 ? x|0xFF00 : x) #define setzf(x) cpu->nz=(x!=0); #define loadimmedt cpu->t = loadimmed; #define loadimm161 cpu->u = loadimmed; #define loadimm162 cpu->t = loadimmed; #define loadstackrelu cpu->u = loadstackrel; #define storestackrel(x) writememory(cpu->s+signed8(cpu->t), x); #define storestackrel161(x) writememory((cpu->s+signed8(cpu->t) )%65536, hibyte(x)); #define storestackrel162(x) writememory((cpu->s+signed8(cpu->t)+1)%65536, lobyte(x)); #define loadstackrel161 cpu->u=loadstackrel; #define loadstackrel162 cpu->t=loadstackrelp1; #define storeut(x) writememory(wordut, x); #define storeutp1(x) writememory((wordut+1)%65536, x); #define storep(x) writememory(cpu->p, x); #define storepinc(x) writememory(cpu->p++, x); #define storepp1(x) writememory((cpu->p+1)%65536, x); #define storeq(x) writememory(cpu->q, x); #define storeqinc(x) writememory(cpu->q++, x); #define storeqp1(x) writememory((cpu->q+1)%65536, x); #define pushretaddr1 writememory(cpu->s++, hibyte(cpu->i)); #define pushretaddr2 writememory(cpu->s++, lobyte(cpu->i)); #define lni cpu->instr = readmemory(cpu->i++); cpu->cycle = 0; #define ldi cpu->instr = readmemory(cpu->i); cpu->cycle = 0; #define addf(x,y) { x=(x+y); cpu->cf=x>=256; x&=0xFF; setzf(x); } #define subf(x,y) addf(x,-y); #define cmpf(x,y) { int t=x-y; cpu->cf=(t>=256); setzf(t); } #define rol(x,y) x=(x<>(8-y)); #define ror(x,y) x=(x>>y)|(x<<(8-y)); #define sra(x,y) x=(x>>y); #define jmpabsp cpu->i=cpu->p; lni; #define jmpabsq cpu->i=cpu->q; lni; #define jmpabsut cpu->i=wordut; lni; #define jmpabsutplus1 cpu->i=(wordut+1)%65536; lni; #define pushbyte(b) writememory(cpu->s++, b); #define push161(x) pushbyte(hibyte(x)); #define push162(x) pushbyte(lobyte(x)); #define pop161 cpu->t=popbyte; #define pop162 cpu->u=popbyte; #define tst(x) cpu->cf = x>=128; cpu->nz = x!=0; #define instrpreload cpu->instrpre = loadimmed; #define instrloadpre cpu->instr = cpu->instrpre; #define jmprelt cpu->i = (cpu->i + signed8(cpu->t))%65536; lni; #define saveretaddr cpu->q = (cpu->i+1)%65536; #define readmemory(x) _readmemory(cpu, mem, x) #define writememory(x, y) _writememory(cpu, mem, x, y) struct CPU { int a; int b; int c; int u; int t; int p; int q; int s; int v; int i; int cf; int nz; int irq; int ifg; int rfg; int instr; int cycle; int instrpre; int tick; }; struct Event { int id; int addr; }; struct Memory { int data[65536]; int canwrite[65536]; int writes[65536]; int reads[65536]; int onread[65536]; int onwrite[65536]; struct Event events[4096]; int numevents; }; void postEvent(struct Memory* const mem, int id, int addr) { if(mem->numevents<4096) { mem->events[mem->numevents].id = id; mem->events[mem->numevents].addr = addr; mem->numevents++; } } int _readmemory(const struct CPU* const cpu, struct Memory* const mem, const int addr) { int addr2 = addr%65536; mem->reads[addr2] = cpu->tick; if(mem->onread[addr2]) { postEvent(mem, mem->onread[addr2], addr2); } return mem->data[addr2]; } int _writememory(const struct CPU* const cpu, struct Memory* const mem, const int addr, const int data) { int addr2 = addr%65536; if(mem->canwrite[addr2]) { mem->writes[addr2] = cpu->tick; mem->data[addr2] = data%256; } if(mem->onwrite[addr2]) { postEvent(mem, mem->onwrite[addr2], addr2); } } typedef void(*CPUInstruction)(struct CPU* const cpu, struct Memory* const mem); #include "instructions_gen.c" int TickCPU(struct CPU* const cpu, struct Memory* const mem, const int count, const int countinstrs) { int i = 0; while(iirq && !cpu->ifg && cpu->cycle==0) { cpu->instr = 0xF2; } if(cpu->rfg || cpu->ifg || cpu->irq) { CPUInstruction instr = CPUInstructions[cpu->instr][cpu->cycle]; if(instr) instr(cpu, mem); if(!countinstrs || cpu->cycle==0) { i++; } } else { i = count; break; } if(mem->numevents!=0) { break; } } return count-i; }