X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=cpu%2FCyclone%2FMain.cpp;h=a85aebcef924414327e2219d338b3c877c6304e7;hb=d5d119243c9e1086e1e6cb34ea05bfd6ab18c200;hp=2f92c5cfd67672e084b9980fc6960730881cceb8;hpb=cc68a136aa179a5f32fe40208371eb9c2b0aadae;p=picodrive.git diff --git a/cpu/Cyclone/Main.cpp b/cpu/Cyclone/Main.cpp index 2f92c5c..a85aebc 100644 --- a/cpu/Cyclone/Main.cpp +++ b/cpu/Cyclone/Main.cpp @@ -32,6 +32,51 @@ void ltorg() else ot(" .ltorg\n"); } +#if CYCLONE_FOR_GENESIS +// r12=ptr to tas in table, trashes r0,r1 +static void ChangeTAS(int norm) +{ + ot(" ldr r0,=Op4ad0%s\n",norm?"_":""); + ot(" mov r1,#8\n"); + ot("setrtas_loop%i0%s ;@ 4ad0-4ad7\n",norm,ms?"":":"); + ot(" subs r1,r1,#1\n"); + ot(" str r0,[r12],#4\n"); + ot(" bne setrtas_loop%i0\n",norm); + ot(" ldr r0,=Op4ad8%s\n",norm?"_":""); + ot(" mov r1,#7\n"); + ot("setrtas_loop%i1%s ;@ 4ad8-4ade\n",norm,ms?"":":"); + ot(" subs r1,r1,#1\n"); + ot(" str r0,[r12],#4\n"); + ot(" bne setrtas_loop%i1\n",norm); + ot(" ldr r0,=Op4adf%s\n",norm?"_":""); + ot(" str r0,[r12],#4\n"); + ot(" ldr r0,=Op4ae0%s\n",norm?"_":""); + ot(" mov r1,#7\n"); + ot("setrtas_loop%i2%s ;@ 4ae0-4ae6\n",norm,ms?"":":"); + ot(" subs r1,r1,#1\n"); + ot(" str r0,[r12],#4\n"); + ot(" bne setrtas_loop%i2\n",norm); + ot(" ldr r0,=Op4ae7%s\n",norm?"_":""); + ot(" str r0,[r12],#4\n"); + ot(" ldr r0,=Op4ae8%s\n",norm?"_":""); + ot(" mov r1,#8\n"); + ot("setrtas_loop%i3%s ;@ 4ae8-4aef\n",norm,ms?"":":"); + ot(" subs r1,r1,#1\n"); + ot(" str r0,[r12],#4\n"); + ot(" bne setrtas_loop%i3\n",norm); + ot(" ldr r0,=Op4af0%s\n",norm?"_":""); + ot(" mov r1,#8\n"); + ot("setrtas_loop%i4%s ;@ 4af0-4af7\n",norm,ms?"":":"); + ot(" subs r1,r1,#1\n"); + ot(" str r0,[r12],#4\n"); + ot(" bne setrtas_loop%i4\n",norm); + ot(" ldr r0,=Op4af8%s\n",norm?"_":""); + ot(" str r0,[r12],#4\n"); + ot(" ldr r0,=Op4af9%s\n",norm?"_":""); + ot(" str r0,[r12],#4\n"); +} +#endif + // trashes all temp regs static void PrintException(int ints) { @@ -86,14 +131,13 @@ static void PrintException(int ints) void CheckInterrupt(int op) { ot(";@ CheckInterrupt:\n"); - ot(" ldr r0,[r7,#0x44]\n"); // same as ldrb r0,[r7,#0x47] - ot(" movs r0,r0,lsr #24 ;@ Get IRQ level (loading word is faster)\n"); + ot(" ldr r1,[r7,#0x44] ;@ Get SR high T_S__III and irq level\n"); + ot(" movs r0,r1,lsr #24 ;@ Get IRQ level\n"); // same as ldrb r0,[r7,#0x47] ot(" beq NoInts%x\n",op); ot(" cmp r0,#6 ;@ irq>6 ?\n"); - ot(" ldrleb r1,[r7,#0x44] ;@ Get SR high: T_S__III\n"); ot(" andle r1,r1,#7 ;@ Get interrupt mask\n"); ot(" cmple r0,r1 ;@ irq<=6: Is irq<=mask ?\n"); - ot(" blgt DoInterrupt\n"); + ot(" blgt CycloneDoInterrupt\n"); ot("NoInts%x%s\n", op,ms?"":":"); ot("\n"); } @@ -109,22 +153,21 @@ static void PrintFramework() ot(" mov r7,r0 ;@ r7 = Pointer to Cpu Context\n"); ot(" ;@ r0-3 = Temporary registers\n"); ot(" ldrb r9,[r7,#0x46] ;@ r9 = Flags (NZCV)\n"); - ot(" ldr r6,=JumpTab ;@ r6 = Opcode Jump table\n"); + ot(" ldr r6,=CycloneJumpTab ;@ r6 = Opcode Jump table\n"); ot(" ldr r5,[r7,#0x5c] ;@ r5 = Cycles\n"); ot(" ldr r4,[r7,#0x40] ;@ r4 = Current PC + Memory Base\n"); ot(" ;@ r8 = Current Opcode\n"); - ot(" ldr r0,[r7,#0x44]\n"); + ot(" ldr r1,[r7,#0x44] ;@ Get SR high T_S__III and irq level\n"); ot(" mov r9,r9,lsl #28 ;@ r9 = Flags 0xf0000000, cpsr format\n"); ot(" ;@ r10 = Source value / Memory Base\n"); ot("\n"); ot(";@ CheckInterrupt:\n"); - ot(" movs r0,r0,lsr #24 ;@ Get IRQ level\n"); // same as ldrb r0,[r7,#0x47] + ot(" movs r0,r1,lsr #24 ;@ Get IRQ level\n"); // same as ldrb r0,[r7,#0x47] ot(" beq NoInts0\n"); ot(" cmp r0,#6 ;@ irq>6 ?\n"); - ot(" ldrleb r1,[r7,#0x44] ;@ Get SR high: T_S__III\n"); ot(" andle r1,r1,#7 ;@ Get interrupt mask\n"); ot(" cmple r0,r1 ;@ irq<=6: Is irq<=mask ?\n"); - ot(" blgt DoInterrupt\n"); + ot(" blgt CycloneDoInterrupt\n"); ot(";@ Check if interrupt used up all the cycles:\n"); ot(" subs r5,r5,#0\n"); ot(" blt CycloneEndNoBack\n"); @@ -143,7 +186,14 @@ static void PrintFramework() ot("CycloneEnd%s\n", ms?"":":"); ot(" sub r4,r4,#2\n"); ot("CycloneEndNoBack%s\n", ms?"":":"); +#ifdef CYCLONE_FOR_PICODRIVE + ot(" ldr r1,[r7,#0x54]\n"); + ot(" mov r9,r9,lsr #28\n"); + ot(" tst r1,r1\n"); + ot(" bxne r1 ;@ jump to alternative CycloneEnd\n"); +#else ot(" mov r9,r9,lsr #28\n"); +#endif ot(" str r4,[r7,#0x40] ;@ Save Current PC + Memory Base\n"); ot(" str r5,[r7,#0x5c] ;@ Save Cycles\n"); ot(" strb r9,[r7,#0x46] ;@ Save Flags (NZCV)\n"); @@ -161,7 +211,7 @@ static void PrintFramework() ot(";@ uncompress jump table\n"); if (ms) ot("CycloneInit\n"); else ot("CycloneInit:\n"); - ot(" ldr r12,=JumpTab\n"); + ot(" ldr r12,=CycloneJumpTab\n"); ot(" add r0,r12,#0xe000*4 ;@ ctrl code pointer\n"); ot(" ldr r1,[r0,#-4]\n"); ot(" tst r1,r1\n"); @@ -187,7 +237,7 @@ static void PrintFramework() ot(" bgt unc_loop_in\n"); ot(" b unc_loop\n"); ot("unc_finish%s\n", ms?"":":"); - ot(" ldr r12,=JumpTab\n"); + ot(" ldr r12,=CycloneJumpTab\n"); ot(" ;@ set a-line and f-line handlers\n"); ot(" add r0,r12,#0xa000*4\n"); ot(" ldr r1,[r0,#4] ;@ a-line handler\n"); @@ -254,8 +304,28 @@ static void PrintFramework() ot(" bx lr\n"); ot("\n"); + if (ms) ot("CycloneSetRealTAS\n"); + else ot("CycloneSetRealTAS:\n"); +#if CYCLONE_FOR_GENESIS + ot(" ldr r12,=CycloneJumpTab\n"); + ot(" tst r0,r0\n"); + ot(" add r12,r12,#0x4a00*4\n"); + ot(" add r12,r12,#0x00d0*4\n"); + ot(" beq setrtas_off\n"); + ChangeTAS(1); + ot(" bx lr\n"); + ot("setrtas_off%s\n",ms?"":":"); + ChangeTAS(0); + ot(" bx lr\n"); + ltorg(); + ot("\n"); +#else + ot(" bx lr\n"); + ot("\n"); +#endif + ot(";@ DoInterrupt - r0=IRQ number\n"); - ot("DoInterrupt%s\n", ms?"":":"); + ot("CycloneDoInterrupt%s\n", ms?"":":"); ot(" stmdb sp!,{lr} ;@ Push ARM return address\n"); ot(";@ Get IRQ Vector address:\n"); @@ -465,6 +535,9 @@ static void PrintJumpTable() ot(";@ -------------------------- Jump Table --------------------------\n"); + // space for decompressed table + ot(ms?" area |.data|, data\n":" .data\n .align 4\n\n"); + #if COMPRESS_JUMPTABLE int handlers=0,reps=0,*indexes,ip,u,out; // use some weird compression on the jump table @@ -472,10 +545,7 @@ static void PrintJumpTable() 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?"":":"); + ot("CycloneJumpTab%s\n", ms?"":":"); if(ms) { for(i = 0; i < 0xa000/8; i++) ot(" dcd 0,0,0,0,0,0,0,0\n"); @@ -548,7 +618,7 @@ static void PrintJumpTable() ot("\n"); free(indexes); #else - ot("JumpTab%s\n", ms?"":":"); + ot("CycloneJumpTab%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 @@ -602,6 +672,7 @@ static int CycloneMake() ot(" export CycloneRun\n"); ot(" export CycloneSetSr\n"); ot(" export CycloneGetSr\n"); + ot(" export CycloneSetRealTAS\n"); ot(" export CycloneVer\n"); ot("\n"); ot("CycloneVer dcd 0x%.4x\n",CycloneVer); @@ -612,7 +683,12 @@ static int CycloneMake() ot(" .global CycloneRun\n"); ot(" .global CycloneSetSr\n"); ot(" .global CycloneGetSr\n"); + ot(" .global CycloneSetRealTAS\n"); ot(" .global CycloneVer\n"); +#ifdef CYCLONE_FOR_PICODRIVE + ot(" .global CycloneDoInterrupt\n"); + ot(" .global CycloneJumpTab\n"); +#endif ot("CycloneVer: .long 0x%.4x\n",CycloneVer); } ot("\n"); @@ -623,6 +699,8 @@ static int CycloneMake() if (ms) ot(" END\n"); + ot("\n\n;@ vim:filetype=armasm\n"); + fclose(AsmFile); AsmFile=NULL; #if 0