Explorar el Código

Last irixxxx's commits

root hace 2 años
padre
commit
c6e2760761
Se han modificado 7 ficheros con 112 adiciones y 98 borrados
  1. 40 52
      cpu/cz80/cz80.c
  2. 5 1
      cpu/cz80/cz80.h
  3. 8 5
      cpu/cz80/cz80_op.c
  4. 49 34
      cpu/cz80/cz80_opED.c
  5. 1 1
      cpu/cz80/cz80macro.h
  6. 7 3
      pico/mode4.c
  7. 2 2
      pico/sms.c

+ 40 - 52
cpu/cz80/cz80.c

@@ -199,7 +199,6 @@ void Cz80_Init(cz80_struc *CPU)
 	CPU->pzR16[3] = pzAF;
 
 	zIX = zIY = 0xffff;
-	zF = ZF;
 
 	CPU->Interrupt_Callback = Cz80_Interrupt_Callback;
 }
@@ -245,7 +244,6 @@ INT32 Cz80_Exec(cz80_struc *CPU, INT32 cycles)
 	UINT32 adr = 0;
 	UINT32 res;
 	UINT32 val;
-	int afterEI = 0;
 	union16 *data;
 
 	PC = CPU->PC;
@@ -255,33 +253,36 @@ INT32 Cz80_Exec(cz80_struc *CPU, INT32 cycles)
 	CPU->ICount = cycles - CPU->ExtraCycles;
 	CPU->ExtraCycles = 0;
 
-	if (!CPU->HaltState)
-	{
 Cz80_Exec:
-		if (CPU->ICount > 0)
+	if (CPU->Status)
+	{
+		if (CPU->Status & CZ80_HAS_NMI)
 		{
+			zIFF1 = 0;
+			CPU->Status &= ~(CZ80_HALTED | CZ80_HAS_NMI);
+			CPU->ExtraCycles += 11;
+			PUSH_16(zRealPC);
+			SET_PC(0x66);
+		} else if (CPU->Status & CZ80_HAS_INT)
+		{
+			CHECK_INT
+		} else if (CPU->Status & CZ80_HALTED)
+		{
+			goto Cz80_Exec_End;
+		}
+		CPU->ICount -= CPU->ExtraCycles;
+		CPU->ExtraCycles = 0;
+	}
+
+	if (CPU->ICount > 0)
+	{
 Cz80_Exec_nocheck:
-			data = pzHL;
-			Opcode = READ_OP();
+		data = pzHL;
+		Opcode = READ_OP();
 #if CZ80_EMULATE_R_EXACTLY
-			zR++;
+		zR++;
 #endif
-			#include "cz80_op.c"
-		}
-
-		if (afterEI)
-		{
-			afterEI = 0;
-Cz80_Check_Interrupt:
-			if (CPU->IRQState != CLEAR_LINE)
-			{
-				CHECK_INT
-			}
-			CPU->ICount -= CPU->ExtraCycles;
-			CPU->ExtraCycles = 0;
-			if (!CPU->HaltState)
-				goto Cz80_Exec;
-		}
+		#include "cz80_op.c"
 	}
 
 Cz80_Exec_End:
@@ -289,7 +290,7 @@ Cz80_Exec_End:
 #if CZ80_ENCRYPTED_ROM
 	CPU->OPBase = OPBase;
 #endif
-	if (!(CPU->HaltState && CPU->ICount > 0))
+	if (!((CPU->Status & CZ80_HALTED) && CPU->ICount > 0))
 		cycles -= CPU->ICount;
 	CPU->ICount = 0;
 #if !CZ80_EMULATE_R_EXACTLY
@@ -308,36 +309,23 @@ void Cz80_Set_IRQ(cz80_struc *CPU, INT32 line, INT32 state)
 {
 	if (line == IRQ_LINE_NMI)
 	{
-		zIFF1 = 0;
-		CPU->ExtraCycles += 11;
-		CPU->HaltState = 0;
-		PUSH_16(CPU->PC - CPU->BasePC)
-		Cz80_Set_Reg(CPU, CZ80_PC, 0x66);
-	}
-	else
+		if (state)
+			CPU->Status |= CZ80_HAS_NMI;
+		else
+			CPU->Status &= ~CZ80_HAS_NMI;
+	} else
 	{
+		CPU->IRQLine = line;
 		CPU->IRQState = state;
-
-		if (state != CLEAR_LINE)
+		if (state)
 		{
-			FPTR PC = CPU->PC;
-#if CZ80_ENCRYPTED_ROM
-			FPTR OPBase = CPU->OPBase;
-#endif
-
-			CPU->IRQLine = line;
-			CHECK_INT
-			CPU->PC = PC;
-#if CZ80_ENCRYPTED_ROM
-			CPU->OPBase = OPBase;
-#endif
+			if (zIFF1)
+				CPU->Status |= CZ80_HAS_INT;
+		} else
+		{
+			CPU->Status &= ~CZ80_HAS_INT;
 		}
 	}
-	if (CPU->ICount > 0)
-	{
-		CPU->ICount -= CPU->ExtraCycles;
-		CPU->ExtraCycles  = 0;
-	}
 }
 
 
@@ -366,7 +354,7 @@ UINT32 Cz80_Get_Reg(cz80_struc *CPU, INT32 regnum)
 	case CZ80_IM:   return zIM;
 	case CZ80_IFF1: return zIFF1;
 	case CZ80_IFF2: return zIFF2;
-	case CZ80_HALT: return CPU->HaltState;
+	case CZ80_HALT: return CPU->Status & CZ80_HALTED;
 	case CZ80_IRQ:  return CPU->IRQState;
 	default: return 0;
 	}
@@ -405,7 +393,7 @@ void Cz80_Set_Reg(cz80_struc *CPU, INT32 regnum, UINT32 val)
 	case CZ80_IM:   zIM = val; break;
 	case CZ80_IFF1: zIFF1 = val ? (1 << 2) : 0; break;
 	case CZ80_IFF2: zIFF2 = val ? (1 << 2) : 0; break;
-	case CZ80_HALT: CPU->HaltState = val; break;
+	case CZ80_HALT: CPU->Status = !!val * CZ80_HALTED; break;
 	case CZ80_IRQ:  CPU->IRQState = val; break;
 	default: break;
 	}

+ 5 - 1
cpu/cz80/cz80.h

@@ -170,6 +170,10 @@ extern "C" {
 #define CZ80_IFF_SFT	CZ80_PF_SFT
 #define CZ80_IFF		CZ80_PF
 
+#define	CZ80_HAS_INT	0x1
+#define	CZ80_HAS_NMI	0x2
+#define	CZ80_HALTED	0x4
+
 #ifndef IRQ_LINE_STATE
 #define IRQ_LINE_STATE
 #define CLEAR_LINE		0		/* clear (a fired, held or pulsed) line */
@@ -247,7 +251,7 @@ typedef struct cz80_t
 
 	UINT8 I;
 	UINT8 IM;
-	UINT8 HaltState;
+	UINT8 Status;
 	UINT8 dummy;
 
 	INT32 IRQLine;

+ 8 - 5
cpu/cz80/cz80_op.c

@@ -686,8 +686,8 @@ OP_CCF:
 
 	OP(0x76):   // HALT
 OP_HALT:
-		CPU->HaltState = 1;
-		goto Cz80_Check_Interrupt;
+		CPU->Status |= CZ80_HALTED;
+		RET(4)
 
 	OP(0xf3):   // DI
 OP_DI:
@@ -709,9 +709,12 @@ OP_EI:
 				zR++;
 #endif
 			}
-			afterEI = 1;
-			CPU->ExtraCycles += 1 - CPU->ICount;
-			CPU->ICount = 1;
+			if (CPU->IRQState)
+			{
+				CPU->Status |= CZ80_HAS_INT;
+				CPU->ExtraCycles -= CPU->ICount;
+				CPU->ICount = 0;
+			}
 		}
 		else zIFF2 = (1 << 2);
 		goto Cz80_Exec_nocheck;

+ 49 - 34
cpu/cz80/cz80_opED.c

@@ -421,8 +421,7 @@ OP_SBC16:
 			zIFF1 = (1 << 2);
 			if (CPU->IRQState)
 			{
-				USE_CYCLES(10)
-				goto Cz80_Check_Interrupt;
+				CPU->Status |= CZ80_HAS_INT;
 			}
 		}
 		else zIFF1 = zIFF2;
@@ -492,23 +491,27 @@ OP_LDX:
 -----------------------------------------*/
 
 	OPED(0xb0): // LDIR
+		if (zBC != 1)
+			PC -= 2;
 		do
 		{
 			val = READ_MEM8(zHL++);
 			WRITE_MEM8(zDE++, val);
 			zBC--;
-			USE_CYCLES(17)
-		} while (zBC && (CPU->ICount > 0));
+			USE_CYCLES(21)
+		} while (zBC > 1 && (CPU->ICount > 0) && !CPU->Status);
 		goto OP_LDXR;
 
 	OPED(0xb8): // LDDR
+		if (zBC != 1)
+			PC -= 2;
 		do
 		{
 			val = READ_MEM8(zHL--);
 			WRITE_MEM8(zDE--, val);
 			zBC--;
-			USE_CYCLES(17)
-		} while (zBC && (CPU->ICount > 0));
+			USE_CYCLES(21)
+		} while (zBC > 1 && (CPU->ICount > 0) && !CPU->Status);
 
 OP_LDXR:
 		F = zF & (SF | ZF | CF);
@@ -517,14 +520,14 @@ OP_LDXR:
 		if (zBC)
 		{
 			zF = F | VF;
-			PC -= 2;
 #if CZ80_EMULATE_R_EXACTLY
 			zR--;
 #endif
-			goto Cz80_Exec_End;
+			ADD_CYCLES(4)
+			goto Cz80_Exec;
 		}
 		zF = F;
-		ADD_CYCLES(5)
+		ADD_CYCLES(4+5)
 		goto Cz80_Exec;
 
 /*-----------------------------------------
@@ -553,6 +556,8 @@ OP_CPX:
 -----------------------------------------*/
 
 	OPED(0xb1): // CPIR
+		if (zBC != 1)
+			PC -= 2;
 		do
 		{
 			val = READ_MEM8(zHL++);
@@ -564,11 +569,13 @@ OP_CPX:
 			if (res & 0x08) F |= XF;
 			if (zBC) F |= VF;
 			zF = F;
-			USE_CYCLES(17)
-		} while (zBC && !(F & ZF) && (CPU->ICount > 0));
+			USE_CYCLES(21)
+		} while (zBC > 1 && !(F & ZF) && (CPU->ICount > 0) && !CPU->Status);
 		goto OP_CPXR;
 
 	OPED(0xb9): // CPDR
+		if (zBC != 1)
+			PC -= 2;
 		do
 		{
 			val = READ_MEM8(zHL--);
@@ -580,19 +587,19 @@ OP_CPX:
 			if (res & 0x08) F |= XF;
 			if (zBC) F |= VF;
 			zF = F;
-			USE_CYCLES(17)
-		} while (zBC && !(F & ZF) && (CPU->ICount > 0));
+			USE_CYCLES(21)
+		} while (zBC > 1 && !(F & ZF) && (CPU->ICount > 0) && !CPU->Status);
 
 OP_CPXR:
 		if (zBC && !(F & ZF))
 		{
-			PC -= 2;
 #if CZ80_EMULATE_R_EXACTLY
 			zR--;
 #endif
-			goto Cz80_Exec_End;
+			ADD_CYCLES(4)
+			goto Cz80_Exec;
 		}
-		ADD_CYCLES(5)
+		ADD_CYCLES(4+5)
 		goto Cz80_Exec;
 
 /*-----------------------------------------
@@ -614,7 +621,7 @@ OP_INX:
 		F = SZ[zB];
 		res = ((UINT32)(zC - 1) & 0xff) + (UINT32)val;
 		if (val & SF) F |= NF;
-		if (res & 0x100) F |= HF | CF;
+		if (res < val) F |= HF | CF;
 		F |= SZP[(UINT8)(res & 0x07) ^ zB] & PF;
 		zF = F;
 		RET(12)
@@ -624,40 +631,44 @@ OP_INX:
 -----------------------------------------*/
 
 	OPED(0xb2): // INIR
+		if (zB != 1)
+			PC -= 2;
 		do
 		{
 			val = IN(zBC);
 			zB--;
 			WRITE_MEM8(zHL++, val);
-			USE_CYCLES(17)
-		} while (zB && (CPU->ICount > 0));
+			USE_CYCLES(21)
+		} while (zB > 1 && (CPU->ICount > 0) && !CPU->Status);
 		goto OP_INXR;
 
 	OPED(0xba): // INDR
+		if (zB != 1)
+			PC -= 2;
 		do
 		{
 			val = IN(zBC);
 			zB--;
 			WRITE_MEM8(zHL--, val);
-			USE_CYCLES(17)
-		} while (zB && (CPU->ICount > 0));
+			USE_CYCLES(21)
+		} while (zB > 1 && (CPU->ICount > 0) && !CPU->Status);
 
 OP_INXR:
 		F = SZ[zB];
 		res = ((UINT32)(zC - 1) & 0xff) + (UINT32)val;
 		if (val & SF) F |= NF;
-		if (res & 0x100) F |= HF | CF;
+		if (res < val) F |= HF | CF;
 		F |= SZP[(UINT8)(res & 0x07) ^ zB] & PF;
 		zF = F;
 		if (zB)
 		{
-			PC -= 2;
 #if CZ80_EMULATE_R_EXACTLY
 			zR--;
 #endif
-			goto Cz80_Exec_End;
+			ADD_CYCLES(4)
+			goto Cz80_Exec;
 		}
-		ADD_CYCLES(5);
+		ADD_CYCLES(4+5);
 		goto Cz80_Exec;
 
 /*-----------------------------------------
@@ -679,7 +690,7 @@ OP_OUTX:
 		F = SZ[zB];
 		res = (UINT32)zL + (UINT32)val;
 		if (val & SF) F |= NF;
-		if (res & 0x100) F |= HF | CF;
+		if (res < val) F |= HF | CF;
 		F |= SZP[(UINT8)(res & 0x07) ^ zB] & PF;
 		zF = F;
 		RET(12)
@@ -689,40 +700,44 @@ OP_OUTX:
 -----------------------------------------*/
 
 	OPED(0xb3): // OTIR
+		if (zB != 1)
+			PC -= 2;
 		do
 		{
 			val = READ_MEM8(zHL++);
 			zB--;
 			OUT(zBC, val);
-			USE_CYCLES(17)
-		} while (zB && (CPU->ICount > 0));
+			USE_CYCLES(21)
+		} while (zB > 1 && (CPU->ICount > 0) && !CPU->Status);
 		goto OP_OTXR;
 
 	OPED(0xbb): // OTDR
+		if (zB != 1)
+			PC -= 2;
 		do
 		{
 			val = READ_MEM8(zHL--);
 			zB--;
 			OUT(zBC, val);
-			USE_CYCLES(17)
-		} while (zB && (CPU->ICount > 0));
+			USE_CYCLES(21)
+		} while (zB > 1 && (CPU->ICount > 0) && !CPU->Status);
 
 OP_OTXR:
 		F = SZ[zB];
 		res = (UINT32)zL + (UINT32)val;
 		if (val & SF) F |= NF;
-		if (res & 0x100) F |= HF | CF;
+		if (res < val) F |= HF | CF;
 		F |= SZP[(UINT8)(res & 0x07) ^ zB] & PF;
 		zF = F;
 		if (zB)
 		{
-			PC -= 2;
 #if CZ80_EMULATE_R_EXACTLY
 			zR--;
 #endif
-			goto Cz80_Exec_End;
+			ADD_CYCLES(4)
+			goto Cz80_Exec;
 		}
-		ADD_CYCLES(5)
+		ADD_CYCLES(4+5)
 		goto Cz80_Exec;
 	}
 

+ 1 - 1
cpu/cz80/cz80macro.h

@@ -90,7 +90,7 @@
 		if (CPU->IRQState == HOLD_LINE)				\
 			CPU->IRQState = CLEAR_LINE;			\
 									\
-		CPU->HaltState = 0;					\
+		CPU->Status &= ~(CZ80_HALTED|CZ80_HAS_INT);		\
 		zIFF1 = zIFF2 = 0;					\
 		IntVect = CPU->Interrupt_Callback(CPU->IRQLine);	\
 									\

+ 7 - 3
pico/mode4.c

@@ -232,14 +232,18 @@ static void DrawDisplayM4(int scanline)
 
   // Find the line in the name table
   line = pv->reg[9] + scanline; // vscroll + scanline
-  line &= 0xff;
 
   // Find name table:
   nametab = PicoMem.vram;
-  if ((Pico.video.reg[0] & 6) == 6 && (Pico.video.reg[1] & 0x18))
+  if ((pv->reg[0] & 6) == 6 && (pv->reg[1] & 0x18)) {
+    line &= 0xff;
     nametab += ((pv->reg[2] & 0x0c) << (10-1)) + (0x700 >> 1);
-  else
+  } else {
+    while (line >= 224) line -= 224;
     nametab += (pv->reg[2] & 0x0e) << (10-1);
+    // old SMS only, masks line:7 with reg[2]:0 for address calculation
+    //if ((pv->reg[2] & 0x01) == 0) line &= 0x7f;
+  }
   nametab += (line>>3) << (6-1);
 
   dx = pv->reg[8]; // hscroll

+ 2 - 2
pico/sms.c

@@ -380,8 +380,8 @@ void PicoFrameMS(void)
     z80_nmi();
   Pico.ms.nmi_state = nmi;
 
-  if ((Pico.video.reg[0] & 6) == 6 && (Pico.video.reg[1] & 0x18))
-    lines_vis = (Pico.video.reg[1] & 0x08) ? 240 : 224;
+  if ((pv->reg[0] & 6) == 6 && (pv->reg[1] & 0x18))
+    lines_vis = (pv->reg[1] & 0x08) ? 240 : 224;
   PicoFrameStartMode4();
   hint = pv->reg[0x0a];