FDS fixed for asm core
authornotaz <notasas@gmail.com>
Sun, 6 May 2007 19:14:50 +0000 (19:14 +0000)
committernotaz <notasas@gmail.com>
Sun, 6 May 2007 19:14:50 +0000 (19:14 +0000)
git-svn-id: file:///home/notaz/opt/svn/fceu@126 be3aeb3a-fb24-0410-a615-afba39da0efa

Makefile.base
Makefile.gp2x
fds.c
ncpu.S
x6502.h

index 756e55c..bd411f2 100644 (file)
@@ -9,7 +9,7 @@ include input/Makefile
 
 fceu2:         ${OBJECTS} ${MOBJS} ${MUOBJS} ${MUSOBJS} ${INPOBJS} ${OBJDRIVER}
                ${CC} -o fceu ${OBJECTS} ${MOBJS} ${MUOBJS} ${MUSOBJS} ${INPOBJS} ${OBJDRIVER} ${LDRIVER}
-ifndef DEBUG
+ifndef NOSTRIP
                $(STRIP) fceu
 endif
 
index af7d4ae..137b353 100644 (file)
@@ -9,12 +9,15 @@ B     = drivers/gp2x/
 ifdef DEBUG
 TFLAGS += -ggdb
 LDRIVER        += -ggdb
+NOSTRIP = 1
 else
 TFLAGS += -ftracer -fstrength-reduce -funroll-loops -fomit-frame-pointer -fstrict-aliasing -ffast-math
-TFLAGS += -O3 # -pg
-LDRIVER        += -O3 # -pg
+TFLAGS += -O3 #-pg -fno-omit-frame-pointer
+LDRIVER        += -O3 #-pg -fno-omit-frame-pointer
 endif
 
+#NOSTRIP = 1
+
 asm_6502=1
 #debug_asm_6502=1
 
diff --git a/fds.c b/fds.c
index f0640a0..41b3a5d 100644 (file)
--- a/fds.c
+++ b/fds.c
@@ -144,6 +144,17 @@ static void FDSInit(void)
  FDSSoundReset();\r
  InDisk=0;\r
  SelectDisk=0;\r
+\r
+#ifdef ASM_6502\r
+ {\r
+  int page;\r
+  // asm code needs pages to be set again..\r
+  for (page=12; page<28; page++) // 0x6000-0xdfff 32K RAM\r
+   Page[page]=FDSRAM  - (page<<11) + ((page-12)<<11);\r
+  for (; page<32; page++)        // 0xe000-0xffff 8K BIOS\r
+   Page[page]=FDSBIOS - (page<<11) + ((page-28)<<11);\r
+ }\r
+#endif\r
 }\r
 \r
 void FCEU_FDSInsert(void)\r
@@ -188,7 +199,7 @@ void FCEU_FDSSelect(void)
 \r
 static void FP_FASTAPASS(1) FDSFix(int a)\r
 {\r
- if((IRQa&2) && IRQCount)\r
+ if(IRQCount && (IRQa&2))\r
  {\r
   IRQCount-=a;\r
   if(IRQCount<=0)\r
@@ -224,8 +235,13 @@ static DECLFR(FDSRead4030)
        uint8 ret=0;\r
 \r
        /* Cheap hack. */\r
+#ifndef ASM_6502\r
        if(X.IRQlow&FCEU_IQEXT) ret|=1;\r
        if(X.IRQlow&FCEU_IQEXT2) ret|=2;\r
+#else\r
+       if((nes_registers[4]>>8)&FCEU_IQEXT) ret|=1;\r
+       if((nes_registers[4]>>8)&FCEU_IQEXT2) ret|=2;\r
+#endif\r
 \r
        if(!fceuindbg)\r
        {\r
@@ -485,7 +501,7 @@ static INLINE void ClockFall(void)
  clockcount=(clockcount+1)&7;\r
 }\r
 \r
-static INLINE int32 FDSDoSound(void)\r
+static INLINE int32 FDSDoSound(int32 mul)\r
 {\r
  fdso.count+=fdso.cycles;\r
  if(fdso.count>=((int64)1<<40))\r
@@ -504,11 +520,14 @@ static INLINE int32 FDSDoSound(void)
  if(fdso.count>=32768) goto dogk;\r
 \r
  // Might need to emulate applying the amplitude to the waveform a bit better...\r
+/*\r
  {\r
   int k=amplitude[0];\r
   if(k>0x20) k=0x20;\r
   return (fdso.cwave[b24latch68>>19]*k)*4/((SPSG[0x9]&0x3)+2);\r
  }\r
+*/\r
+ return (fdso.cwave[b24latch68>>19]*mul)>>16;\r
 }\r
 \r
 static int32 FBC=0;\r
@@ -517,6 +536,7 @@ static void RenderSound(void)
 {\r
  int32 end, start;\r
  int32 x;\r
+ int32 mul;\r
 \r
  start=FBC;\r
  end=(SOUNDTS<<16)/soundtsinc;\r
@@ -524,10 +544,27 @@ static void RenderSound(void)
   return;\r
  FBC=end;\r
 \r
+ // hack for performance, might produce bad results..\r
+ if (!amplitude[0])\r
+  return;\r
+\r
+ switch (SPSG[0x9]&0x3)\r
+ {\r
+  default:mul = (4<<16)/2;\r
+  case 1: mul = (4<<16)/3;\r
+  case 2: mul = (4<<16)/4;\r
+  case 3: mul = (4<<16)/5;\r
+ }\r
+ {\r
+  int k=amplitude[0];\r
+  if(k>0x20) k=0x20;\r
+  mul *= k;\r
+ }\r
+\r
  if(!(SPSG[0x9]&0x80))\r
   for(x=start;x<end;x++)\r
   {\r
-   uint32 t=FDSDoSound();\r
+   uint32 t=FDSDoSound(mul);\r
    t+=t>>1;\r
    t>>=4;\r
    Wave[x>>4]+=t; //(t>>2)-(t>>3); //>>3;\r
diff --git a/ncpu.S b/ncpu.S
index d26a9ca..96c867b 100644 (file)
--- a/ncpu.S
+++ b/ncpu.S
@@ -91,7 +91,7 @@ ldmfd sp!,{r0-r3,r12,lr}
 @@@
 @@@ ¤Ê¤ó¤«Ì¾Á°¤¬ÊѤÀ¤Ê(¤É¡¼¤Ç¤â¤¤¡¼¤±¤É¡¼
 @@@
-.macro CYCLE_NEXT      n, hook_check=1, do_cyc_add=1
+.macro CYCLE_NEXT      n, unused=0, do_cyc_add=1
        @@DEBUG_INFO
 
 .if \do_cyc_add
@@ -99,17 +99,17 @@ ldmfd sp!,{r0-r3,r12,lr}
 .endif
        subs    REG_CYCLE, REG_CYCLE, #\n*48<<16
        ble     cpu_exec_end
-.if \hook_check
        tst     REG_P_REST, #1<<16
-       blne    do_irq_hook
-.endif
+       bne     do_irq_hook
+
        ldrb    r0, [REG_PC], #1
        tst     REG_P_REST, #0xff<<8
        ldreq   pc, [REG_OP_TABLE, r0, lsl #2]
 
        @ do some messing to find out which IRQ is pending..
-       tst     REG_P_REST, #FCEU_IQNMI<<8
-       bne     do_int
+       @ assumption: NMI can be set only on very first run, because it is only set once before vblank..
+@      tst     REG_P_REST, #FCEU_IQNMI<<8
+@      bne     do_int
        tst     REG_P_REST, #P_REST_I_FLAG
        @@ if I_FLAG=1, continue execution, don't trigger IRQ
        bicne   REG_P_REST, REG_P_REST, #FCEU_IQTEMP<<8
@@ -2826,13 +2826,26 @@ cpu_exec:
 
 @      ldr   REG_OP_TABLE, = cpu_exec_table @ set on init
 
-       CYCLE_NEXT      0, 0
+       ldrb    r0, [REG_PC], #1
+       tst     REG_P_REST, #0xff<<8
+       ldreq   pc, [REG_OP_TABLE, r0, lsl #2]
+
+       @ assumption: NMI can be set only on very first run, because it is only set once before vblank..
+       tst     REG_P_REST, #FCEU_IQNMI<<8
+       bne     do_int
+       tst     REG_P_REST, #P_REST_I_FLAG
+       @@ if I_FLAG=1, continue execution, don't trigger IRQ
+       bicne   REG_P_REST, REG_P_REST, #FCEU_IQTEMP<<8
+       ldrne   pc, [REG_OP_TABLE, r0, lsl #2]
+       @@ I_FLAG=0 and REST is checked, we have a IRQ
+       b       do_int
+
 
 cpu_exec_end:
        FLUSH_TIMESTAMP r0
 
        tst     REG_P_REST, #1<<16
-       blne    do_irq_hook_noflushts
+       bne     do_irq_hook_final
 
        ldr     r0, =nes_registers
        stmia   r0, {r4-r12}
@@ -2911,7 +2924,6 @@ nes_internal_ram:
        .fill   0x100, 1, 0
 nes_stack:
        .fill   0x700, 1, 0
-@ TODO: write code which keeps it up-to-date
 pc_base:
        .long   0
 MapIRQHook:
@@ -3143,29 +3155,60 @@ X6502_Rebase_a:
 do_irq_hook:
        FLUSH_TIMESTAMP r0
 
-do_irq_hook_noflushts:
        @ get irqhook cycles
        and     r0, REG_CYCLE, #0xff00
-       bic     REG_CYCLE, REG_CYCLE, #0xff00
        mov     r0, r0, lsr #8
 #ifndef DEBUG_ASM_6502
        @ I have reviewed all MapIRQHook functions, they only seem to cause IRQs, not messing cycles or something
        str     REG_P_REST, [REG_OP_TABLE, #(OTOFFS_NES_REGS + 0x10)]   @ might set irq
-       mov     REG_P_REST, lr                  @ r8
+       mov     REG_P_REST, REG_OP_TABLE                                @ r8
 
        @ if somebody modifies MapIRQHook without calling reset, we are doomed
        mov     lr, pc
        ldr     pc, [REG_OP_TABLE, #OTOFFS_IRQ_HOOK]
 
-       ldr     REG_OP_TABLE, =cpu_exec_table   @ got trashed because was in r12
-       mov     lr, REG_P_REST
+       mov     REG_OP_TABLE, REG_P_REST                                @ got trashed because was in r12
        ldr     REG_P_REST, [REG_OP_TABLE, #(OTOFFS_NES_REGS + 0x10)]   @ might set irq
 #else
        ldr     r1, =mapirq_cyc_a
        str     r0, [r1]
        mov     r1, r0
 #endif
+
+       ldrb    r0, [REG_PC], #1
+       bic     REG_CYCLE, REG_CYCLE, #0xff00
+       tst     REG_P_REST, #0xff<<8
+       ldreq   pc, [REG_OP_TABLE, r0, lsl #2]
+
+       @ do some messing to find out which IRQ is pending..
+       tst     REG_P_REST, #P_REST_I_FLAG
+       @@ if I_FLAG=1, continue execution, don't trigger IRQ
+       bicne   REG_P_REST, REG_P_REST, #FCEU_IQTEMP<<8
+       ldrne   pc, [REG_OP_TABLE, r0, lsl #2]
+       @@ I_FLAG=0 and REST is checked, we have a IRQ
+       b       do_int
+
+
+do_irq_hook_final:
+       ldr     r1, =nes_registers
+
+       @ get irqhook cycles
+       and     r0, REG_CYCLE, #0xff00
+       bic     REG_CYCLE, REG_CYCLE, #0xff00
+       mov     r0, r0, lsr #8
+
+       stmia   r1, {r4-r12}
+
+       ldmfd   r13!,{r4-r11,lr}
+
+#ifndef DEBUG_ASM_6502
+       ldr     pc, [REG_OP_TABLE, #OTOFFS_IRQ_HOOK]
+#else
+       ldr     r1, =mapirq_cyc_a
+       str     r0, [r1]
+       mov     r1, r0
        bx      lr
+#endif
 
 
 @ vim:filetype=armasm
diff --git a/x6502.h b/x6502.h
index d6e8a05..83adca0 100644 (file)
--- a/x6502.h
+++ b/x6502.h
@@ -78,8 +78,10 @@ extern void FP_FASTAPASS(1) (*MapIRQHook)(int a);
 #define X6502_Reset X6502_Reset_a
 #define X6502_Power X6502_Power_a
 #define X6502_AddCycles X6502_AddCycles_a
-#define X6502_IRQBegin X6502_IRQBegin_a
-#define X6502_IRQEnd X6502_IRQEnd_a
+//#define X6502_IRQBegin X6502_IRQBegin_a
+//#define X6502_IRQEnd X6502_IRQEnd_a
+#define X6502_IRQBegin(w) nes_registers[4]|=w<<8
+#define X6502_IRQEnd(w) nes_registers[4]&=~(w<<8)
 #define X6502_Rebase X6502_Rebase_a
 #define X6502_GetCycleCount() ((int32)nes_registers[7]>>16)
 #define X6502_A