sms: add pause support
authornotaz <notasas@gmail.com>
Fri, 30 Aug 2013 23:23:57 +0000 (02:23 +0300)
committernotaz <notasas@gmail.com>
Sat, 31 Aug 2013 17:35:52 +0000 (20:35 +0300)
cpu/DrZ80/drz80.h
cpu/DrZ80/drz80.s
pico/pico_int.h
pico/sms.c

index 708f0a9..05773f9 100644 (file)
@@ -52,7 +52,7 @@ struct DrZ80
   int cycles;                      /*0x44 - Cycles pending to be executed yet */
   int previouspc;                  /*0x48 - Previous PC */
   unsigned char Z80_IRQ;        /*0x4C - Set IRQ Number (must be halfword aligned) */   
-  unsigned char Z80IF;          /*0x4D - Interrupt Flags:  bit1=_IFF1, bit2=_IFF2, bit3=_HALT */
+  unsigned char Z80IF;          /*0x4D - Interrupt Flags:  bit0=_IFF1, bit1=_IFF2, bit2=_HALT, b3=NMI */
   unsigned char Z80IM;          /*0x4E - Set IRQ Mode */
   unsigned char spare;          /*0x4F - N/A */
   unsigned int z80irqvector;    /*0x50 - Set IRQ Vector i.e. 0xFF=RST */
index edb29df..ff2a6b8 100644 (file)
@@ -97,6 +97,7 @@ DrZ80Ver: .long 0x0001
        .equ Z80_IF1, 1<<0\r
        .equ Z80_IF2, 1<<1\r
        .equ Z80_HALT, 1<<2\r
+       .equ Z80_NMI, 1<<3\r
 \r
 ;@---------------------------------------\r
 \r
@@ -1359,9 +1360,11 @@ DrZ80Run:
 \r
 .if INTERRUPT_MODE == 0\r
        ;@ check ints\r
+       tst r0,#(Z80_NMI<<8)\r
+       blne DoNMI\r
        tst r0,#0xff\r
        movne r0,r0,lsr #8\r
-       tstne r0,#1\r
+       tstne r0,#Z80_IF1\r
        blne DoInterrupt\r
 .endif\r
 \r
@@ -1515,6 +1518,36 @@ DoInterrupt_end:
        ldmfd sp!,{pc} ;@ return\r
 .endif\r
 \r
+DoNMI:\r
+       stmfd sp!,{lr}\r
+\r
+       bic r0,r0,#((Z80_NMI|Z80_HALT|Z80_IF1)<<8)\r
+       strh r0,[cpucontext,#z80irq] @ 0x4C, irq and IFF bits\r
+\r
+       ;@ push pc on stack\r
+       ldr r0,[cpucontext,#z80pc_base]\r
+       sub r2,z80pc,r0\r
+       opPUSHareg r2\r
+\r
+       ;@ read new pc from vector address\r
+.if UPDATE_CONTEXT\r
+       str z80pc,[cpucontext,#z80pc_pointer]\r
+.endif\r
+       mov r0,#0x66\r
+.if DRZ80_XMAP\r
+       rebasepc\r
+.else\r
+       stmfd sp!,{r3,r12}\r
+       mov lr,pc\r
+       ldr pc,[cpucontext,#z80_rebasePC] ;@ r0=new pc - external function sets z80pc_base and returns new z80pc in r0\r
+       ldmfd sp!,{r3,r12}\r
+       mov z80pc,r0    \r
+.endif\r
+       ldrh r0,[cpucontext,#z80irq] @ 0x4C, irq and IFF bits\r
+       eatcycles 11\r
+       ldmfd sp!,{pc}\r
+\r
+\r
 .data\r
 .align 4\r
 \r
@@ -5615,7 +5648,7 @@ ei_return:
        ;@ check ints\r
        tst r0,#0xff\r
        movne r0,r0,lsr #8\r
-       tstne r0,#1\r
+       tstne r0,#Z80_IF1\r
        blne DoInterrupt\r
 \r
        ;@ continue\r
index 690c233..1acc1b0 100644 (file)
@@ -174,6 +174,8 @@ extern struct DrZ80 drZ80;
 #define z80_run(cycles)    ((cycles) - DrZ80Run(&drZ80, cycles))\r
 #define z80_run_nr(cycles) DrZ80Run(&drZ80, cycles)\r
 #define z80_int()          drZ80.Z80_IRQ = 1\r
+#define z80_int()          drZ80.Z80_IRQ = 1\r
+#define z80_nmi()          drZ80.Z80IF |= 8\r
 \r
 #define z80_cyclesLeft     drZ80.cycles\r
 #define z80_pc()           (drZ80.Z80PC - drZ80.Z80PC_BASE)\r
@@ -184,6 +186,7 @@ extern struct DrZ80 drZ80;
 #define z80_run(cycles)    Cz80_Exec(&CZ80, cycles)\r
 #define z80_run_nr(cycles) Cz80_Exec(&CZ80, cycles)\r
 #define z80_int()          Cz80_Set_IRQ(&CZ80, 0, HOLD_LINE)\r
+#define z80_nmi()          Cz80_Set_IRQ(&CZ80, IRQ_LINE_NMI, 0)\r
 \r
 #define z80_cyclesLeft     (CZ80.ICount - CZ80.ExtraCycles)\r
 #define z80_pc()           Cz80_Get_Reg(&CZ80, CZ80_PC)\r
@@ -193,6 +196,7 @@ extern struct DrZ80 drZ80;
 #define z80_run(cycles)    (cycles)\r
 #define z80_run_nr(cycles)\r
 #define z80_int()\r
+#define z80_nmi()\r
 \r
 #endif\r
 \r
@@ -313,7 +317,8 @@ struct PicoMS
 {\r
   unsigned char carthw[0x10];\r
   unsigned char io_ctl;\r
-  unsigned char pad[0x4f];\r
+  unsigned char nmi_state;\r
+  unsigned char pad[0x4e];\r
 };\r
 \r
 // some assembly stuff depend on these, do not touch!\r
index 58905bd..8c44d51 100644 (file)
@@ -11,7 +11,6 @@
  * - remaining status flags (OVR/COL)
  * - RAM support in mapper
  * - region support
- * - Pause button (NMI)
  * - SN76496 DAC-like usage
  * - H counter
  */
@@ -256,8 +255,14 @@ void PicoFrameMS(void)
   int skip = PicoSkipFrame;
   int lines_vis = 192;
   int hint; // Hint counter
+  int nmi;
   int y;
 
+  nmi = (PicoPad[0] >> 7) & 1;
+  if (!Pico.ms.nmi_state && nmi)
+    z80_nmi();
+  Pico.ms.nmi_state = nmi;
+
   PicoFrameStartMode4();
   hint = pv->reg[0x0a];