main.cpp
来自「motorola ezx 平台下的fba模拟器」· C++ 代码 · 共 633 行 · 第 1/2 页
CPP
633 行
if (type==1) ot("write");
if (type==2) ot("fetch");
if (type==1) ot("%d(r0,r1)",8<<size);
else ot("%d(r0)", 8<<size);
ot(" handler\n");
#if MEMHANDLERS_CHANGE_CYCLES
ot(" ldr r5,[r7,#0x5c] ;@ Load Cycles\n");
#endif
#if MEMHANDLERS_CHANGE_FLAGS
ot(" ldrb r9,[r7,#0x46] ;@ r9 = Load Flags (NZCV)\n");
ot(" mov r9,r9,lsl #28\n");
#endif
#if MEMHANDLERS_CHANGE_PC
ot(" ldr r4,[r7,#0x40] ;@ Load PC\n");
#endif
return 0;
}
static void PrintOpcodes()
{
int op=0;
printf("Creating Opcodes: [");
ot(";@ ---------------------------- Opcodes ---------------------------\n");
// Emit null opcode:
ot("Op____%s ;@ Called if an opcode is not recognised\n", ms?"":":");
ot(" sub r4,r4,#2\n");
#if USE_UNRECOGNIZED_CALLBACK
ot(" str r4,[r7,#0x40] ;@ Save PC\n");
ot(" mov r1,r9,lsr #28\n");
ot(" strb r1,[r7,#0x46] ;@ Save Flags (NZCV)\n");
ot(" str r5,[r7,#0x5c] ;@ Save Cycles\n");
ot(" ldr r11,[r7,#0x94] ;@ UnrecognizedCallback\n");
ot(" tst r11,r11\n");
ot(" movne lr,pc\n");
ot(" movne pc,r11 ;@ call UnrecognizedCallback if it is defined\n");
ot(" ldr r5,[r7,#0x5c] ;@ Load Cycles\n");
ot(" ldrb r9,[r7,#0x46] ;@ r9 = Load Flags (NZCV)\n");
ot(" mov r9,r9,lsl #28\n");
ot(" ldr r4,[r7,#0x40] ;@ Load PC\n");
ot(" tst r0,r0\n");
ot(" moveq r0,#0x10\n");
ot(" bleq Exception\n");
#else
ot(" mov r0,#0x10\n");
ot(" bl Exception\n");
#endif
Cycles=34;
OpEnd();
// Unrecognised a-line and f-line opcodes throw an exception:
ot("Op__al%s ;@ Unrecognised a-line opcode\n", ms?"":":");
ot(" sub r4,r4,#2\n");
#if USE_AFLINE_CALLBACK
ot(" str r4,[r7,#0x40] ;@ Save PC\n");
ot(" mov r1,r9,lsr #28\n");
ot(" strb r1,[r7,#0x46] ;@ Save Flags (NZCV)\n");
ot(" str r5,[r7,#0x5c] ;@ Save Cycles\n");
ot(" ldr r11,[r7,#0x94] ;@ UnrecognizedCallback\n");
ot(" tst r11,r11\n");
ot(" movne lr,pc\n");
ot(" movne pc,r11 ;@ call UnrecognizedCallback if it is defined\n");
ot(" ldr r5,[r7,#0x5c] ;@ Load Cycles\n");
ot(" ldrb r9,[r7,#0x46] ;@ r9 = Load Flags (NZCV)\n");
ot(" mov r9,r9,lsl #28\n");
ot(" ldr r4,[r7,#0x40] ;@ Load PC\n");
ot(" tst r0,r0\n");
ot(" moveq r0,#0x28\n");
ot(" bleq Exception\n");
#else
ot(" mov r0,#0x28\n");
ot(" bl Exception\n");
#endif
Cycles=4;
OpEnd();
ot("Op__fl%s ;@ Unrecognised f-line opcode\n", ms?"":":");
ot(" sub r4,r4,#2\n");
#if USE_AFLINE_CALLBACK
ot(" str r4,[r7,#0x40] ;@ Save PC\n");
ot(" mov r1,r9,lsr #28\n");
ot(" strb r1,[r7,#0x46] ;@ Save Flags (NZCV)\n");
ot(" str r5,[r7,#0x5c] ;@ Save Cycles\n");
ot(" ldr r11,[r7,#0x94] ;@ UnrecognizedCallback\n");
ot(" tst r11,r11\n");
ot(" movne lr,pc\n");
ot(" movne pc,r11 ;@ call UnrecognizedCallback if it is defined\n");
ot(" ldr r5,[r7,#0x5c] ;@ Load Cycles\n");
ot(" ldrb r9,[r7,#0x46] ;@ r9 = Load Flags (NZCV)\n");
ot(" mov r9,r9,lsl #28\n");
ot(" ldr r4,[r7,#0x40] ;@ Load PC\n");
ot(" tst r0,r0\n");
ot(" moveq r0,#0x2c\n");
ot(" bleq Exception\n");
#else
ot(" mov r0,#0x2c\n");
ot(" bl Exception\n");
#endif
Cycles=4;
OpEnd();
for (op=0;op<0x10000;op++)
{
if ((op&0xfff)==0) { printf("%x",op>>12); fflush(stdout); } // Update progress
OpAny(op);
}
ot("\n");
printf("]\n");
}
// helper
static void ott(char *str, int par, char *nl, int nlp, int counter, int size)
{
switch(size) {
case 0: if((counter&7)==0) ot(ms?" dcb ":" .byte "); break;
case 1: if((counter&7)==0) ot(ms?" dcw ":" .hword "); break;
case 2: if((counter&7)==0) ot(ms?" dcd ":" .long "); break;
}
ot(str, par);
if((counter&7)==7) ot(nl,nlp); else ot(",");
}
static void PrintJumpTable()
{
int i=0,op=0,len=0;
ot(";@ -------------------------- Jump Table --------------------------\n");
#if COMPRESS_JUMPTABLE
int handlers=0,reps=0,*indexes,ip,u,out;
// use some weird compression on the jump table
indexes=(int *)malloc(0x10000*4);
if(!indexes) { printf("ERROR: out of memory\n"); exit(1); }
len=0x10000;
// space for decompressed table
ot(ms?" area |.data|, data\n":" .data\n .align 4\n\n");
ot("JumpTab%s\n", ms?"":":");
if(ms) {
for(i = 0; i < 0xa000/8; i++)
ot(" dcd 0,0,0,0,0,0,0,0\n");
} else
ot(" .rept 0x%x\n .long 0,0,0,0,0,0,0,0\n .endr\n", 0xa000/8);
// hanlers live in "a-line" part of the table
// first output nop,a-line,f-line handlers
ot(ms?" dcd Op____,Op__al,Op__fl,":" .long Op____,Op__al,Op__fl,");
handlers=3;
for(i=0;i<len;i++)
{
op=CyJump[i];
for(u=i-1; u>=0; u--) if(op == CyJump[u]) break; // already done with this op?
if(u==-1 && op >= 0) {
ott("Op%.4x",op," ;@ %.4x\n",i,handlers,2);
indexes[op] = handlers;
handlers++;
}
}
if(handlers&7) {
fseek(AsmFile, -1, SEEK_CUR); // remove last comma
for(i = 8-(handlers&7); i > 0; i--)
ot(",000000");
ot("\n");
}
if(ms) {
for(i = (0x4000-handlers)/8; i > 0; i--)
ot(" dcd 0,0,0,0,0,0,0,0\n");
} else {
ot(ms?"":" .rept 0x%x\n .long 0,0,0,0,0,0,0,0\n .endr\n", (0x4000-handlers)/8);
}
printf("total distinct hanlers: %i\n",handlers);
// output data
for(i=0,ip=0; i < 0xf000; i++, ip++) {
op=CyJump[i];
if(op == -2) {
// it must skip a-line area, because we keep our data there
ott("0x%.4x", handlers<<4, "\n",0,ip++,1);
ott("0x%.4x", 0x1000, "\n",0,ip,1);
i+=0xfff;
continue;
}
for(reps=1; i < 0xf000; i++, reps++) if(op != CyJump[i+1]) break;
if(op>=0) out=indexes[op]<<4; else out=0; // unrecognised
if(reps <= 0xe || reps==0x10) {
if(reps!=0x10) out|=reps; else out|=0xf; // 0xf means 0x10 (0xf appeared to be unused anyway)
ott("0x%.4x", out, "\n",0,ip,1);
} else {
ott("0x%.4x", out, "\n",0,ip++,1);
ott("0x%.4x", reps,"\n",0,ip,1);
}
}
if(ip&1) ott("0x%.4x", 0, "\n",0,ip++,1);
if(ip&7) fseek(AsmFile, -1, SEEK_CUR); // remove last comma
ot("\n");
if(ip&7) {
for(i = 8-(ip&7); i > 0; i--)
ot(",0x0000");
ot("\n");
}
if(ms) {
for(i = (0x2000-ip/2)/8; i > 0; i--)
ot(" dcd 0,0,0,0,0,0,0,0\n");
} else {
ot(" .rept 0x%x\n .long 0,0,0,0,0,0,0,0\n .endr\n", (0x2000-ip/2)/8);
}
ot("\n");
free(indexes);
#else
ot("JumpTab%s\n", ms?"":":");
len=0xfffe; // Hmmm, armasm 2.50.8684 messes up with a 0x10000 long jump table
// notaz: same thing with GNU as 2.9-psion-98r2 (reloc overflow)
// this is due to COFF objects using only 2 bytes for reloc count
for (i=0;i<len;i++)
{
op=CyJump[i];
if(op>=0) ott("Op%.4x",op," ;@ %.4x\n",i-7,i,2);
else if(op==-2) ott("Op__al",0, " ;@ %.4x\n",i-7,i,2);
else if(op==-3) ott("Op__fl",0, " ;@ %.4x\n",i-7,i,2);
else ott("Op____",0, " ;@ %.4x\n",i-7,i,2);
}
if(i&7) fseek(AsmFile, -1, SEEK_CUR); // remove last comma
ot("\n");
ot(";@ notaz: we don't want to crash if we run into those 2 missing opcodes\n");
ot(";@ so we leave this pattern to patch it later\n");
ot("%s 0x78563412\n", ms?" dcd":" .long");
ot("%s 0x56341290\n", ms?" dcd":" .long");
#endif
}
static int CycloneMake()
{
int i;
char *name="cyclone.s";
// Open the assembly file
if (ms) name="Cyclone.asm";
AsmFile=fopen(name,"wt"); if (AsmFile==NULL) return 1;
printf("Making %s...\n",name);
ot("\n;@ Dave's Cyclone 68000 Emulator v%x.%.3x - Assembler Output\n\n",CycloneVer>>12,CycloneVer&0xfff);
ot(";@ (c) Copyright 2003 Dave, All rights reserved.\n");
ot(";@ some code (c) Copyright 2005-2006 notaz, All rights reserved.\n");
ot(";@ Cyclone 68000 is free for non-commercial use.\n\n");
ot(";@ For commercial use, separate licencing terms must be obtained.\n\n");
CyJump=(int *)malloc(0x40000); if (CyJump==NULL) return 1;
memset(CyJump,0xff,0x40000); // Init to -1
for(i=0xa000; i<0xb000; i++) CyJump[i] = -2; // a-line emulation
for(i=0xf000; i<0x10000; i++) CyJump[i] = -3; // f-line emulation
if (ms)
{
ot(" area |.text|, code\n");
ot(" export CycloneInit\n");
ot(" export CycloneRun\n");
ot(" export CycloneSetSr\n");
ot(" export CycloneGetSr\n");
ot(" export CycloneVer\n");
ot("\n");
ot("CycloneVer dcd 0x%.4x\n",CycloneVer);
}
else
{
ot(" .global CycloneInit\n");
ot(" .global CycloneRun\n");
ot(" .global CycloneSetSr\n");
ot(" .global CycloneGetSr\n");
ot(" .global CycloneVer\n");
ot("CycloneVer: .long 0x%.4x\n",CycloneVer);
}
ot("\n");
PrintFramework();
PrintOpcodes();
PrintJumpTable();
if (ms) ot(" END\n");
fclose(AsmFile); AsmFile=NULL;
printf("Assembling...\n");
// Assemble the file
if (ms) system("armasm Cyclone.asm");
else system("as -o Cyclone.o Cyclone.s");
printf("Done!\n\n");
free(CyJump);
return 0;
}
int main()
{
printf("\n Dave's Cyclone 68000 Emulator v%x.%.3x - Core Creator\n\n",CycloneVer>>12,CycloneVer&0xfff);
// Make GAS or ARMASM version
CycloneMake();
return 0;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?