fix 25pacmano highscore-hang / update z180 core

This commit is contained in:
dinkc64 2020-09-04 21:05:35 -04:00
parent ba949b7caf
commit 6a6422690e
9 changed files with 302 additions and 2247 deletions

View File

@ -285,12 +285,13 @@ static INT32 DrvInit()
Z180MapMemory(DrvSprLut, 0x4ff00, 0x4ffff, MAP_WRITE);
Z180SetReadHandler(pacgal20_read);
Z180SetWriteHandler(pacgal20_write);
Z180SetReadPortHandler(pacgal20_read_port);
Z180SetWritePortHandler(pacgal20_write_port);
Z180SetReadPortHandler(pacgal20_read_port);
Z180SetWritePortHandler(pacgal20_write_port);
Z180Close();
NamcoSoundInit(73728000 / 4 / 6 / 32, 3, 0);
NamcoSoundSetAllRoutes(1.00, BURN_SND_ROUTE_BOTH);
NamcoSoundSetBuffered(Z180TotalCycles, 18432000);
DACInit(0, 0, 1, Z180TotalCycles, 18432000);
DACSetRoute(0, 0.90, BURN_SND_ROUTE_BOTH);
@ -562,6 +563,7 @@ static INT32 DrvDraw()
draw_chars();
draw_sprites();
BurnTransferFlip(global_flip, global_flip); // unflip coctail for netplay etc.
BurnTransferCopy(DrvPalette + (game_selected * 0x1000));
return 0;
@ -586,7 +588,7 @@ static INT32 DrvFrame()
DrvInputs[2] ^= (DrvJoy3[i] & 1) << i;
}
if (sprite_pal_base) // 25pacmano
if (sprite_pal_base) // 25pacmano board-check
DrvInputs[2] ^= 0x7e;
}

View File

@ -82,6 +82,21 @@ Hitachi HD647180 series:
#include "z180_intf.h"
#include <stddef.h>
/* interrupt priorities */
#define Z180_INT_TRAP 0 /* Undefined opcode */
#define Z180_INT_NMI 1 /* NMI */
#define Z180_INT_IRQ0 2 /* Execute IRQ1 */
#define Z180_INT_IRQ1 3 /* Execute IRQ1 */
#define Z180_INT_IRQ2 4 /* Execute IRQ2 */
#define Z180_INT_PRT0 5 /* Internal PRT channel 0 */
#define Z180_INT_PRT1 6 /* Internal PRT channel 1 */
#define Z180_INT_DMA0 7 /* Internal DMA channel 0 */
#define Z180_INT_DMA1 8 /* Internal DMA channel 1 */
#define Z180_INT_CSIO 9 /* Internal CSI/O */
#define Z180_INT_ASCI0 10 /* Internal ASCI channel 0 */
#define Z180_INT_ASCI1 11 /* Internal ASCI channel 1 */
#define Z180_INT_MAX Z180_INT_ASCI1
// in z180_intf.cpp
extern void __fastcall z180_cpu_write_handler(UINT32 address, UINT8 data);
extern UINT8 __fastcall z180_cpu_fetchop_handler(UINT32 address);
@ -125,12 +140,22 @@ typedef struct {
UINT8 tmdrh[2]; /* latched TMDR0H and TMDR1H values */
UINT16 tmdr_value[2]; /* TMDR values used byt PRT0 and PRT1 as down counter */
UINT8 tif[2]; /* TIF0 and TIF1 values */
INT32 timer_cnt;
INT32 extra_cycles;
UINT8 nmi_state; /* nmi line state */
UINT8 nmi_pending; /* nmi pending */
UINT8 nmi_hold; /* nmi hold logic */
UINT8 irq_state[3]; /* irq line states (INT0,INT1,INT2) */
UINT8 irq_hold[3]; // irq hold logic */
UINT8 after_EI; /* are we in the EI shadow? */
UINT8 int_pending[Z180_INT_MAX + 1];
UINT32 total_cycles;
UINT32 current_cycles;
UINT32 EA;
INT32 icount;
INT32 end_run;
const struct z80_irq_daisy_chain *daisy;
int (*irq_callback)(int irqline);
@ -222,6 +247,8 @@ typedef struct {
#define _IFF2 Z180.IFF2
#define _HALT Z180.HALT
#define EA Z180.EA
#define IO(n) Z180.io[(n)-Z180_CNTLA0]
#define IO_CNTLA0 IO(Z180_CNTLA0)
#define IO_CNTLA1 IO(Z180_CNTLA1)
@ -403,7 +430,7 @@ typedef struct {
#define Z180_CNTR_RESET 0x07
#define Z180_CNTR_RMASK 0xff
#define Z180_CNTR_WMASK 0x7f
#define Z180_CNTR_WMASK 0x4f
/* 0b CSI/O transmit/receive register */
#define Z180_TRDR_RESET 0x00
@ -720,7 +747,7 @@ typedef struct {
/* 36 refresh control register */
#define Z180_RCR_REFE 0x80
#define Z180_RCR_REFW 0x80
#define Z180_RCR_REFW 0x40
#define Z180_RCR_CYC 0x03
#define Z180_RCR_RESET 0xc0
@ -779,9 +806,7 @@ typedef struct {
#define Z180_IOCR_RMASK 0xff
#define Z180_IOCR_WMASK 0xff
static int z180_icount;
static Z180_Regs Z180;
static UINT32 EA;
static UINT8 SZ[256]; /* zero and sign flags */
static UINT8 SZ_BIT[256]; /* zero, sign and parity/overflow (=zero) flags for BIT opcode */
@ -794,9 +819,6 @@ static UINT8 *SZHVC_add;
static UINT8 *SZHVC_sub;
#endif
static UINT32 total_cycles;
static UINT32 current_cycles;
void z180_scan(INT32 nAction)
{
if (nAction & ACB_DRIVER_DATA) {
@ -804,32 +826,20 @@ void z180_scan(INT32 nAction)
memset(&ba, 0, sizeof(ba));
ba.Data = &Z180;
ba.nLen = STRUCT_SIZE_HELPER(Z180_Regs, after_EI);
ba.nLen = STRUCT_SIZE_HELPER(Z180_Regs, end_run);
ba.szName = "Z180 Registers";
BurnAcb(&ba);
}
}
/****************************************************************************
* Burn an odd amount of cycles, that is instructions taking something
* different from 4 T-states per opcode (and R increment)
****************************************************************************/
Z180_INLINE void BURNODD(int cycles, int opcodes, int cyclesum)
{
if( cycles > 0 )
{
_R += (cycles / cyclesum) * opcodes;
z180_icount -= (cycles / cyclesum) * cyclesum;
}
}
static UINT8 z180_readcontrol(UINT32 port);
static void z180_writecontrol(UINT32 port, UINT8 data);
static void z180_dma0(void);
static void z180_dma1(void);
static int z180_dma0(int max_cycles);
static int z180_dma1(void);
static void z180_handle_io_timers(int cycles);
//static void z180_set_info(UINT32 state, cpuinfo *info);
#include "z180daa.h"
#include "z180ops.h"
#include "z180tbl.h"
@ -1283,7 +1293,15 @@ static void z180_writecontrol(UINT32 port, UINT8 data)
break;
case Z180_TCR:
IO_TCR = (IO_TCR & ~Z180_TCR_WMASK) | (data & Z180_TCR_WMASK);
{
UINT16 old = IO_TCR;
/* Force reload on state change */
IO_TCR = (IO_TCR & ~Z180_TCR_WMASK) | (data & Z180_TCR_WMASK);
if (!(old & Z180_TCR_TDE0) && (IO_TCR & Z180_TCR_TDE0))
Z180.tmdr_value[0] = 0; //IO_RLDR0L | (IO_RLDR0H << 8);
if (!(old & Z180_TCR_TDE1) && (IO_TCR & Z180_TCR_TDE1))
Z180.tmdr_value[1] = 0; //IO_RLDR1L | (IO_RLDR1H << 8);
}
break;
case Z180_IO11:
@ -1485,21 +1503,28 @@ static void z180_writecontrol(UINT32 port, UINT8 data)
}
}
static void z180_dma0(void)
static int z180_dma0(int max_cycles)
{
UINT32 sar0 = 65536 * IO_SAR0B + 256 * IO_SAR0H + IO_SAR0L;
UINT32 dar0 = 65536 * IO_DAR0B + 256 * IO_DAR0H + IO_DAR0L;
int bcr0 = 256 * IO_BCR0H + IO_BCR0L;
int count = (IO_DMODE & Z180_DMODE_MMOD) ? bcr0 : 1;
if (bcr0 == 0)
{
IO_DSTAT &= ~Z180_DSTAT_DE0;
return;
bcr0 = 0x10000;
}
while (count-- > 0)
int count = (IO_DMODE & Z180_DMODE_MMOD) ? bcr0 : 1;
int cycles = 0;
if (!(IO_DSTAT & Z180_DSTAT_DE0))
{
return 0;
}
while (count > 0)
{
Z180.extra_cycles = 0;
/* last transfer happening now? */
if (bcr0 == 1)
{
@ -1509,17 +1534,25 @@ static void z180_dma0(void)
{
case 0x00: /* memory SAR0+1 to memory DAR0+1 */
program_write_byte_8le(dar0++, program_read_byte_8le(sar0++));
cycles += (IO_DCNTL >> 6) * 2; // memory wait states
bcr0--;
break;
case 0x04: /* memory SAR0-1 to memory DAR0+1 */
program_write_byte_8le(dar0++, program_read_byte_8le(sar0--));
cycles += (IO_DCNTL >> 6) * 2; // memory wait states
bcr0--;
break;
case 0x08: /* memory SAR0 fixed to memory DAR0+1 */
program_write_byte_8le(dar0++, program_read_byte_8le(sar0));
cycles += (IO_DCNTL >> 6) * 2; // memory wait states
bcr0--;
break;
case 0x0c: /* I/O SAR0 fixed to memory DAR0+1 */
if (Z180.iol & Z180_DREQ0)
{
program_write_byte_8le(dar0++, IN(sar0));
cycles += IO_DCNTL >> 6; // memory wait states
bcr0--;
/* edge sensitive DREQ0 ? */
if (IO_DCNTL & Z180_DCNTL_DIM0)
{
@ -1530,17 +1563,25 @@ static void z180_dma0(void)
break;
case 0x10: /* memory SAR0+1 to memory DAR0-1 */
program_write_byte_8le(dar0--, program_read_byte_8le(sar0++));
cycles += (IO_DCNTL >> 6) * 2; // memory wait states
bcr0--;
break;
case 0x14: /* memory SAR0-1 to memory DAR0-1 */
program_write_byte_8le(dar0--, program_read_byte_8le(sar0--));
cycles += (IO_DCNTL >> 6) * 2; // memory wait states
bcr0--;
break;
case 0x18: /* memory SAR0 fixed to memory DAR0-1 */
program_write_byte_8le(dar0--, program_read_byte_8le(sar0));
cycles += (IO_DCNTL >> 6) * 2; // memory wait states
bcr0--;
break;
case 0x1c: /* I/O SAR0 fixed to memory DAR0-1 */
if (Z180.iol & Z180_DREQ0)
{
program_write_byte_8le(dar0--, IN(sar0));
cycles += IO_DCNTL >> 6; // memory wait states
bcr0--;
/* edge sensitive DREQ0 ? */
if (IO_DCNTL & Z180_DCNTL_DIM0)
{
@ -1551,9 +1592,13 @@ static void z180_dma0(void)
break;
case 0x20: /* memory SAR0+1 to memory DAR0 fixed */
program_write_byte_8le(dar0, program_read_byte_8le(sar0++));
cycles += (IO_DCNTL >> 6) * 2; // memory wait states
bcr0--;
break;
case 0x24: /* memory SAR0-1 to memory DAR0 fixed */
program_write_byte_8le(dar0, program_read_byte_8le(sar0--));
cycles += (IO_DCNTL >> 6) * 2; // memory wait states
bcr0--;
break;
case 0x28: /* reserved */
break;
@ -1563,6 +1608,8 @@ static void z180_dma0(void)
if (Z180.iol & Z180_DREQ0)
{
OUT(dar0, program_read_byte_8le(sar0++));
cycles += IO_DCNTL >> 6; // memory wait states
bcr0--;
/* edge sensitive DREQ0 ? */
if (IO_DCNTL & Z180_DCNTL_DIM0)
{
@ -1575,6 +1622,8 @@ static void z180_dma0(void)
if (Z180.iol & Z180_DREQ0)
{
OUT(dar0, program_read_byte_8le(sar0--));
cycles += IO_DCNTL >> 6; // memory wait states
bcr0--;
/* edge sensitive DREQ0 ? */
if (IO_DCNTL & Z180_DCNTL_DIM0)
{
@ -1588,9 +1637,9 @@ static void z180_dma0(void)
case 0x3c: /* reserved */
break;
}
bcr0--;
count--;
if ((z180_icount -= 6) < 0)
cycles += 6 + Z180.extra_cycles;
if (cycles > max_cycles)
break;
}
@ -1609,25 +1658,32 @@ static void z180_dma0(void)
Z180.iol &= ~Z180_TEND0;
IO_DSTAT &= ~Z180_DSTAT_DE0;
/* terminal count interrupt enabled? */
if (IO_DSTAT & Z180_DSTAT_DIE0 && _IFF1)
take_interrupt(Z180_INT_DMA0);
if (IO_DSTAT & Z180_DSTAT_DIE0 && _IFF1) {
Z180.int_pending[Z180_INT_DMA0] = 1;
}
}
return cycles;
}
static void z180_dma1(void)
static int z180_dma1(void)
{
UINT32 mar1 = 65536 * IO_MAR1B + 256 * IO_MAR1H + IO_MAR1L;
UINT32 iar1 = 256 * IO_IAR1H + IO_IAR1L;
int bcr1 = 256 * IO_BCR1H + IO_BCR1L;
if ((Z180.iol & Z180_DREQ1) == 0)
return;
/* counter is zero? */
if (bcr1 == 0)
{
IO_DSTAT &= ~Z180_DSTAT_DE1;
return;
bcr1 = 0x10000;
}
int cycles = 0;
if ((Z180.iol & Z180_DREQ1) == 0)
return 0;
if (!(IO_DSTAT & Z180_DSTAT_DE1))
{
return 0;
}
/* last transfer happening now? */
@ -1636,6 +1692,8 @@ static void z180_dma1(void)
Z180.iol |= Z180_TEND1;
}
Z180.extra_cycles = 0;
switch (IO_DCNTL & (Z180_DCNTL_DIM1 | Z180_DCNTL_DIM0))
{
case 0x00: /* memory MAR1+1 to I/O IAR1 fixed */
@ -1652,6 +1710,9 @@ static void z180_dma1(void)
break;
}
cycles += IO_DCNTL >> 6; // memory wait states
cycles += Z180.extra_cycles; // use extra_cycles for I/O wait states
/* edge sensitive DREQ1 ? */
if (IO_DCNTL & Z180_DCNTL_DIM1)
Z180.iol &= ~Z180_DREQ1;
@ -1667,12 +1728,13 @@ static void z180_dma1(void)
{
Z180.iol &= ~Z180_TEND1;
IO_DSTAT &= ~Z180_DSTAT_DE1;
if (IO_DSTAT & Z180_DSTAT_DIE1 && _IFF1)
take_interrupt(Z180_INT_DMA1);
if (IO_DSTAT & Z180_DSTAT_DIE1 && _IFF1) {
Z180.int_pending[Z180_INT_DMA1] = 1;
}
}
/* six cycles per transfer (minimum) */
z180_icount -= 6;
return 6 + cycles;
}
void z180_write_iolines(UINT32 data)
@ -1910,6 +1972,11 @@ void z180_reset(void)
Z180.irq_hold[0] = 0;
Z180.irq_hold[1] = 0;
Z180.irq_hold[2] = 0;
for (i=0; i <= Z180_INT_MAX; i++)
{
Z180.int_pending[i] = 0;
}
Z180.timer_cnt = 0;
Z180.after_EI = 0;
Z180.tif[0] = 0;
Z180.tif[1] = 0;
@ -1988,37 +2055,38 @@ void z180_reset(void)
z80daisy_reset(Z180.daisy);
z180_mmu();
total_cycles = 0;
current_cycles = 0;
Z180.total_cycles = 0;
Z180.current_cycles = 0;
}
/* Handle PRT timers, decreasing them after 20 clocks and returning the new icount base that needs to be used for the next check */
static int handle_timers(int current_icount, int previous_icount)
static void clock_timers()
{
int diff = previous_icount - current_icount;
int new_icount_base;
if(diff >= 20)
Z180.timer_cnt++;
if (Z180.timer_cnt >= 20)
{
Z180.timer_cnt = 0;
/* Programmable Reload Timer 0 */
if(IO_TCR & Z180_TCR_TDE0)
{
Z180.tmdr_value[0]--;
if(Z180.tmdr_value[0] == 0)
{
Z180.tmdr_value[0] = IO_RLDR0L | (IO_RLDR0H << 8);
Z180.tif[0] = 1;
} else {
Z180.tmdr_value[0]--;
}
}
/* Programmable Reload Timer 1 */
if(IO_TCR & Z180_TCR_TDE1)
{
Z180.tmdr_value[1]--;
if(Z180.tmdr_value[1] == 0)
{
Z180.tmdr_value[1] = IO_RLDR1L | (IO_RLDR1H << 8);
Z180.tif[1] = 1;
} else {
Z180.tmdr_value[1]--;
}
}
@ -2027,7 +2095,7 @@ static int handle_timers(int current_icount, int previous_icount)
// check if we can take the interrupt
if(_IFF1 && !Z180.after_EI)
{
take_interrupt(Z180_INT_PRT0);
Z180.int_pending[Z180_INT_PRT0] = 1;
}
}
@ -2036,31 +2104,39 @@ static int handle_timers(int current_icount, int previous_icount)
// check if we can take the interrupt
if(_IFF1 && !Z180.after_EI)
{
take_interrupt(Z180_INT_PRT1);
Z180.int_pending[Z180_INT_PRT1] = 1;
}
}
new_icount_base = current_icount + (diff - 20);
}
else
{
new_icount_base = previous_icount;
}
return new_icount_base;
}
static void check_interrupts(void)
static int check_interrupts(void)
{
int i;
for(i = 0; i <= 2; i++)
int cycles = 0;
/* check for IRQs before each instruction */
if (_IFF1 && !Z180.after_EI)
{
/* check for IRQs before each instruction */
if(Z180.irq_state[i] != Z180_CLEAR_LINE && _IFF1 && !Z180.after_EI)
{
take_interrupt(Z180_INT0 + i);
}
if (Z180.irq_state[0] != Z180_CLEAR_LINE && (IO_ITC & Z180_ITC_ITE0) == Z180_ITC_ITE0)
Z180.int_pending[Z180_INT_IRQ0] = 1;
if (Z180.irq_state[1] != Z180_CLEAR_LINE && (IO_ITC & Z180_ITC_ITE1) == Z180_ITC_ITE1)
Z180.int_pending[Z180_INT_IRQ1] = 1;
if (Z180.irq_state[2] != Z180_CLEAR_LINE && (IO_ITC & Z180_ITC_ITE2) == Z180_ITC_ITE2)
Z180.int_pending[Z180_INT_IRQ2] = 1;
}
for (i = 0; i <= Z180_INT_MAX; i++)
if (Z180.int_pending[i])
{
cycles += take_interrupt(i);
Z180.int_pending[i] = 0;
break;
}
return cycles;
}
void z180_write_internal_io(UINT32 port, UINT8 data)
@ -2070,25 +2146,34 @@ void z180_write_internal_io(UINT32 port, UINT8 data)
}
}
static INT32 end_run;
/****************************************************************************
* Handle I/O and timers
****************************************************************************/
static void z180_handle_io_timers(int cycles)
{
while (cycles-- > 0)
{
clock_timers();
}
}
/****************************************************************************
* Execute 'cycles' T-states. Return number of T-states really executed
****************************************************************************/
int z180_execute(int cycles)
{
int old_icount = cycles;
z180_icount = cycles;
current_cycles = cycles;
Z180.icount = cycles;
Z180.current_cycles = cycles;
INT32 curcycles = 0;
end_run = 0;
Z180.end_run = 0;
/* check for NMIs on the way in; they can only be set externally */
/* via timers, and can't be dynamically enabled, so it is safe */
/* to just check here */
if (Z180.nmi_pending)
{
_PPC = -1; /* there isn't a valid previous program counter */
LEAVE_HALT; /* Check if processor was halted */
/* disable DMA transfers!! */
@ -2098,8 +2183,10 @@ int z180_execute(int cycles)
_IFF1 = 0;
PUSH( PC );
_PCD = 0x0066;
z180_icount -= 11;
Z180.icount -= 11;
Z180.nmi_pending = 0;
z180_handle_io_timers(11);
if (Z180.nmi_hold) {
Z180.nmi_hold = 0;
Z180.nmi_state = CPU_IRQSTATUS_NONE;
@ -2114,86 +2201,113 @@ again:
if ((IO_DSTAT & Z180_DSTAT_DE0) == Z180_DSTAT_DE0 &&
(IO_DMODE & Z180_DMODE_MMOD) == Z180_DMODE_MMOD)
{
z180_dma0();
old_icount = handle_timers(z180_icount, old_icount);
/* FIXME z180_dma0 should be handled in handle_io_timers */
curcycles = z180_dma0(Z180.icount);
Z180.icount -= curcycles;
z180_handle_io_timers(curcycles);
}
else
{
do
{
check_interrupts();
curcycles = check_interrupts();
Z180.icount -= curcycles;
z180_handle_io_timers(curcycles);
Z180.after_EI = 0;
_PPC = _PCD;
_R++;
if (!_HALT)
{
_R++;
IO_FRC++; /* Added FRC counting, not implemented yet */
Z180.extra_cycles = 0;
EXEC_Z180_INLINE(op,ROP());
} else {
Z180.extra_cycles = 3;
}
Z180.icount -= Z180.extra_cycles;
z180_handle_io_timers(Z180.extra_cycles);
EXEC_Z180_INLINE(op,ROP());
old_icount = handle_timers(z180_icount, old_icount);
/* if channel 0 was started in burst mode, go recheck the mode */
if ((IO_DSTAT & Z180_DSTAT_DE0) == Z180_DSTAT_DE0 &&
(IO_DMODE & Z180_DMODE_MMOD) == Z180_DMODE_MMOD)
goto again;
z180_dma0();
old_icount = handle_timers(z180_icount, old_icount);
curcycles = z180_dma0(6);
Z180.icount -= curcycles;
z180_handle_io_timers(curcycles);
z180_dma1();
old_icount = handle_timers(z180_icount, old_icount);
curcycles = z180_dma1();
Z180.icount -= curcycles;
z180_handle_io_timers(curcycles);
/* If DMA is done break out to the faster loop */
if ((IO_DSTAT & Z180_DSTAT_DME) != Z180_DSTAT_DME)
break;
} while( z180_icount > 0 && !end_run);
} while( Z180.icount > 0 && !Z180.end_run);
}
}
if (z180_icount > 0 && !end_run)
if (Z180.icount > 0 && !Z180.end_run)
{
do
{
check_interrupts();
Z180.after_EI = 0;
_PPC = _PCD;
_R++;
EXEC_Z180_INLINE(op,ROP());
old_icount = handle_timers(z180_icount, old_icount);
/* If DMA is started go to check the mode */
if ((IO_DSTAT & Z180_DSTAT_DME) == Z180_DSTAT_DME)
goto again;
} while( z180_icount > 0 && !end_run );
curcycles = check_interrupts();
Z180.icount -= curcycles;
z180_handle_io_timers(curcycles);
Z180.after_EI = 0;
_PPC = _PCD;
if (!_HALT) {
_R++;
IO_FRC++; /* Added FRC counting, not implemented yet */
Z180.extra_cycles = 0;
EXEC_Z180_INLINE(op,ROP());
} else {
Z180.extra_cycles = 3;
}
Z180.icount -= Z180.extra_cycles;
z180_handle_io_timers(Z180.extra_cycles);
} while( Z180.icount > 0 && !Z180.end_run );
}
total_cycles += cycles - z180_icount;
Z180.total_cycles += cycles - Z180.icount;
INT32 ret = cycles - z180_icount;
INT32 ret = cycles - Z180.icount;
z180_icount = current_cycles = 0;
Z180.icount = Z180.current_cycles = 0;
return ret;
}
INT32 z180_idle(INT32 cyc)
{
total_cycles += cyc;
Z180.total_cycles += cyc;
return cyc;
}
void z180_run_end()
{
end_run = 1;
Z180.end_run = 1;
}
INT32 z180_total_cycles()
{
return total_cycles + (current_cycles - z180_icount);
return Z180.total_cycles + (Z180.current_cycles - Z180.icount);
}
void z180_new_frame()
{
total_cycles = 0;
Z180.total_cycles = 0;
}
#if 0
/****************************************************************************
* Burn 'cycles' T-states. Adjust R register for the lost time
****************************************************************************/
@ -2204,26 +2318,32 @@ void z180_burn(int cycles)
/* NOP takes 3 cycles per instruction */
int n = (cycles + 2) / 3;
_R += n;
z180_icount -= 3 * n;
Z180.icount -= 3 * n;
}
}
#endif
/****************************************************************************
* Set IRQ line state
****************************************************************************/
void z180_set_irq_line(int irqline, int state)
{
if (!((irqline >= 0 && irqline <= 2) || irqline == 0x20)) {
bprintf(0, _T("z180_set_irq_line(%x, %x): unsupported irqline.\n"), irqline, state);
return;
}
if (state == CPU_IRQSTATUS_HOLD || state == CPU_IRQSTATUS_AUTO) {
// irq hold logic -dink
state = CPU_IRQSTATUS_ACK;
if (irqline == Z180_INPUT_LINE_NMI) {
if (irqline == 0x20) {
Z180.nmi_hold = 1;
} else {
Z180.irq_hold[irqline] = 1;
}
}
if (irqline == Z180_INPUT_LINE_NMI)
if (irqline == 0x20)
{
/* mark an NMI pending on the rising edge */
if (Z180.nmi_state == Z180_CLEAR_LINE && state != Z180_CLEAR_LINE)
@ -2232,7 +2352,6 @@ void z180_set_irq_line(int irqline, int state)
}
else
{
/* update the IRQ state */
Z180.irq_state[irqline] = state;
if (Z180.daisy)
@ -2495,7 +2614,7 @@ void z180_get_info(UINT32 state, cpuinfo *info)
case CPUINFO_PTR_EXECUTE: info->execute = z180_execute; break;
case CPUINFO_PTR_BURN: info->burn = z180_burn; break;
case CPUINFO_PTR_DISASSEMBLE: info->disassemble = z180_dasm; break;
case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &z180_icount; break;
case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &Z180.icount; break;
case CPUINFO_PTR_TRANSLATE: info->translate = z180_translate; break;
case CPUINFO_PTR_Z180_CYCLE_TABLE + Z180_TABLE_op: info->p = (void *)cc[Z180_TABLE_op]; break;
case CPUINFO_PTR_Z180_CYCLE_TABLE + Z180_TABLE_cb: info->p = (void *)cc[Z180_TABLE_cb]; break;

View File

@ -5,7 +5,6 @@
#define Z180_CLEAR_LINE 0
#define Z180_ASSERT_LINE 1
#define Z180_INPUT_LINE_NMI 32
#if 0
@ -140,17 +139,6 @@ enum
};*/
#define Z180_INT0 0 /* Execute INT1 */
#define Z180_INT1 1 /* Execute INT1 */
#define Z180_INT2 2 /* Execute INT2 */
#define Z180_INT_PRT0 3 /* Internal PRT channel 0 */
#define Z180_INT_PRT1 4 /* Internal PRT channel 1 */
#define Z180_INT_DMA0 5 /* Internal DMA channel 0 */
#define Z180_INT_DMA1 6 /* Internal DMA channel 1 */
#define Z180_INT_CSIO 7 /* Internal CSI/O */
#define Z180_INT_ASCI0 8 /* Internal ASCI channel 0 */
#define Z180_INT_ASCI1 9 /* Internal ASCI channel 1 */
/* MMU mapped memory lookup */
extern UINT8 z180_readmem(UINT32 offset);
extern void z180_writemem(UINT32 offset, UINT8 data);

File diff suppressed because it is too large Load Diff

View File

@ -292,12 +292,10 @@ OP(op,fe) { CP(ARG()); } /* CP n */
OP(op,ff) { RST(0x38); } /* RST 7 */
static void take_interrupt(int irq)
static int take_interrupt(int irq)
{
int irq_vector;
/* there isn't a valid previous program counter */
_PPC = -1;
int cycles = 0;
/* Check if processor was halted */
LEAVE_HALT;
@ -305,7 +303,7 @@ static void take_interrupt(int irq)
/* Clear both interrupt flip flops */
_IFF1 = _IFF2 = 0;
if( irq == Z180_INT0 )
if( irq == Z180_INT_IRQ0 )
{
/* Daisy chain mode? If so, call the requesting device */
if (Z180.daisy)
@ -322,7 +320,7 @@ static void take_interrupt(int irq)
PUSH( PC );
RM16( irq_vector, &Z180.PC );
/* CALL opcode timing */
z180_icount -= cc[Z180_TABLE_op][0xcd];
cycles += cc[Z180_TABLE_op][0xcd];
}
else
/* Interrupt mode 1. RST 38h */
@ -331,7 +329,7 @@ static void take_interrupt(int irq)
PUSH( PC );
_PCD = 0x0038;
/* RST $38 + 'interrupt latency' cycles */
z180_icount -= cc[Z180_TABLE_op][0xff] - cc[Z180_TABLE_ex][0xff];
cycles += cc[Z180_TABLE_op][0xff] - cc[Z180_TABLE_ex][0xff];
}
else
{
@ -344,35 +342,38 @@ static void take_interrupt(int irq)
PUSH( PC );
_PCD = irq_vector & 0xffff;
/* CALL $xxxx + 'interrupt latency' cycles */
z180_icount -= cc[Z180_TABLE_op][0xcd] - cc[Z180_TABLE_ex][0xff];
cycles += cc[Z180_TABLE_op][0xcd] - cc[Z180_TABLE_ex][0xff];
break;
case 0xc30000: /* jump */
_PCD = irq_vector & 0xffff;
/* JP $xxxx + 2 cycles */
z180_icount -= cc[Z180_TABLE_op][0xc3] - cc[Z180_TABLE_ex][0xff];
cycles += cc[Z180_TABLE_op][0xc3] - cc[Z180_TABLE_ex][0xff];
break;
default: /* rst (or other opcodes?) */
PUSH( PC );
_PCD = irq_vector & 0x0038;
/* RST $xx + 2 cycles */
z180_icount -= cc[Z180_TABLE_op][_PCD] - cc[Z180_TABLE_ex][_PCD];
cycles += cc[Z180_TABLE_op][_PCD] - cc[Z180_TABLE_ex][_PCD];
break;
}
}
}
else
{
irq_vector = (IO(Z180_IL) & Z180_IL_IL) + (irq - Z180_INT1) * 2;
irq_vector = (IO(Z180_IL) & Z180_IL_IL) + (irq - Z180_INT_IRQ1) * 2;
irq_vector = (_I << 8) + (irq_vector & 0xff);
PUSH( PC );
RM16( irq_vector, &Z180.PC );
/* CALL opcode timing */
z180_icount -= cc[Z180_TABLE_op][0xcd];
cycles += cc[Z180_TABLE_op][0xcd];
}
if (Z180.irq_hold[irq]) {
Z180.irq_hold[irq] = 0;
z180_set_irq_line(irq, CPU_IRQSTATUS_NONE);
if ((irq >= Z180_INT_IRQ0 && irq <= Z180_INT_IRQ2) && Z180.irq_hold[irq-Z180_INT_IRQ0]) {
Z180.irq_hold[irq-Z180_INT_IRQ0] = 0;
z180_set_irq_line(irq-Z180_INT_IRQ0, CPU_IRQSTATUS_NONE);
}
return cycles;
}

View File

@ -4,8 +4,6 @@
#define ENTER_HALT { \
_PC--; \
_HALT = 1; \
if( !Z180.after_EI ) \
z180_burn( z180_icount ); \
}
/***************************************************************
@ -22,17 +20,27 @@
/***************************************************************
* Input a byte from given I/O port
***************************************************************/
#define IN(port) \
(((port ^ IO_IOCR) & 0xffc0) == 0) ? \
z180_readcontrol(port) : io_read_byte_8le(port)
Z180_INLINE UINT8 IN(UINT16 port)
{
if(((port ^ IO_IOCR) & 0xffc0) == 0)
return z180_readcontrol(port);
Z180.extra_cycles += ((IO_DCNTL & (Z180_DCNTL_IWI1 | Z180_DCNTL_IWI0)) >> 4) + 1; // external I/O wait states
return io_read_byte_8le(port);
}
/***************************************************************
* Output a byte to given I/O port
***************************************************************/
#define OUT(port,value) \
if (((port ^ IO_IOCR) & 0xffc0) == 0) \
z180_writecontrol(port,value); \
else io_write_byte_8le(port,value)
Z180_INLINE void OUT(UINT16 port, UINT8 value)
{
if (((port ^ IO_IOCR) & 0xffc0) == 0) {
z180_writecontrol(port,value);
} else
{
Z180.extra_cycles += ((IO_DCNTL & (Z180_DCNTL_IWI1 | Z180_DCNTL_IWI0)) >> 4) + 1; // external I/O wait states
io_write_byte_8le(port, value);
}
}
/***************************************************************
* MMU calculate the memory managemant lookup table
@ -58,7 +66,7 @@ Z180_INLINE void z180_mmu( void )
else
addr += IO_BBR << 12;
}
Z180.mmu[page] = addr;
Z180.mmu[page] = (addr & 0xfffff);
}
}
@ -68,7 +76,12 @@ Z180_INLINE void z180_mmu( void )
/***************************************************************
* Read a byte from given memory location
***************************************************************/
#define RM(addr) program_read_byte_8le(MMU_REMAP_ADDR(addr))
Z180_INLINE UINT8 RM(UINT32 addr)
{
Z180.extra_cycles += IO_DCNTL >> 6; // memory wait states
return program_read_byte_8le(MMU_REMAP_ADDR(addr));
}
UINT8 z180_readmem(UINT32 offset)
{
return RM(offset);
@ -77,7 +90,8 @@ UINT8 z180_readmem(UINT32 offset)
/***************************************************************
* Write a byte to given memory location
***************************************************************/
#define WM(addr,value) program_write_byte_8le(MMU_REMAP_ADDR(addr),value)
#define WM(addr,value) Z180.extra_cycles += IO_DCNTL >> 6; program_write_byte_8le(MMU_REMAP_ADDR(addr),value)
void z180_writemem(UINT32 offset, UINT8 data)
{
WM(offset, data);
@ -111,6 +125,7 @@ Z180_INLINE UINT8 ROP(void)
{
UINT32 addr = _PCD;
_PC++;
Z180.extra_cycles += IO_DCNTL >> 6; // memory wait states
return cpu_readop(MMU_REMAP_ADDR(addr));
}
@ -124,6 +139,7 @@ Z180_INLINE UINT8 ARG(void)
{
UINT32 addr = _PCD;
_PC++;
Z180.extra_cycles += IO_DCNTL >> 6; // memory wait states
return cpu_readop_arg(MMU_REMAP_ADDR(addr));
}
@ -131,6 +147,7 @@ Z180_INLINE UINT32 ARG16(void)
{
UINT32 addr = _PCD;
_PC += 2;
Z180.extra_cycles += (IO_DCNTL >> 6) * 2; // memory wait states
return cpu_readop_arg(MMU_REMAP_ADDR(addr)) | (cpu_readop_arg(MMU_REMAP_ADDR(addr+1)) << 8);
}
@ -185,37 +202,8 @@ void z180_setOPbase(int pc)
***************************************************************/
#define JR() \
{ \
unsigned oldpc = _PCD-1; \
INT8 arg = (INT8)ARG(); /* ARG() also increments _PC */ \
_PC += arg; /* so don't do _PC += ARG() */ \
/* speed up busy loop */ \
if( _PCD == oldpc ) \
{ \
if( !Z180.after_EI ) \
BURNODD( z180_icount, 1, cc[Z180_TABLE_op][0x18] ); \
} \
else \
{ \
UINT8 op = cpu_readop(_PCD); \
if( _PCD == oldpc-1 ) \
{ \
/* NOP - JR $-1 or EI - JR $-1 */ \
if ( op == 0x00 || op == 0xfb ) \
{ \
if( !Z180.after_EI ) \
BURNODD( z180_icount-cc[Z180_TABLE_op][0x00],\
2, cc[Z180_TABLE_op][0x00]+cc[Z180_TABLE_op][0x18]); \
} \
} \
else \
/* LD SP,#xxxx - JR $-3 */ \
if( _PCD == oldpc-3 && op == 0x31 ) \
{ \
if( !Z180.after_EI ) \
BURNODD( z180_icount-cc[Z180_TABLE_op][0x31], \
2, cc[Z180_TABLE_op][0x31]+cc[Z180_TABLE_op][0x18]); \
} \
} \
}
/***************************************************************
@ -499,12 +487,18 @@ Z180_INLINE UINT8 DEC(UINT8 value)
/***************************************************************
* DAA
***************************************************************/
#define DAA { \
int idx = _A; \
if( _F & CF ) idx |= 0x100; \
if( _F & HF ) idx |= 0x200; \
if( _F & NF ) idx |= 0x400; \
_AF = DAATable[idx]; \
#define DAA { \
UINT8 r = _A; \
if (_F&NF) { \
if ((_F&HF)|((_A&0xf)>9)) r-=6; \
if ((_F&CF)|(_A>0x99)) r-=0x60; \
} \
else { \
if ((_F&HF)|((_A&0xf)>9)) r+=6; \
if ((_F&CF)|(_A>0x99)) r+=0x60; \
} \
_F=(_F&3)|(_A>0x99)|((_A^r)&HF)|SZP[r]; \
_A=r; \
}
/***************************************************************
@ -1035,7 +1029,7 @@ Z180_INLINE UINT8 SET(UINT8 bit, UINT8 value)
* OTDMR
***************************************************************/
#define SLP { \
z180_icount = 0; \
Z180.icount = 0; \
_HALT = 2; \
}

View File

@ -153,7 +153,7 @@ static const UINT8 *cc[6] = { cc_op, cc_cb, cc_ed, cc_xy, cc_xycb, cc_ex };
#define Z180_TABLE_dd Z180_TABLE_xy
#define Z180_TABLE_fd Z180_TABLE_xy
static void take_interrupt(int irqline);
static int take_interrupt(int irqline);
#define PROTOTYPES(tablename,prefix) \
Z180_INLINE void prefix##_00(void); Z180_INLINE void prefix##_01(void); Z180_INLINE void prefix##_02(void); Z180_INLINE void prefix##_03(void); \
@ -270,7 +270,9 @@ PROTOTYPES(Z180xycb,xycb);
/***************************************************************
* adjust cycle count by n T-states
***************************************************************/
#define CC(prefix,opcode) z180_icount -= cc[Z180_TABLE_##prefix][opcode]
#define CC(prefix,opcode) { \
Z180.extra_cycles += cc[Z180_TABLE_##prefix][opcode]; \
}
/***************************************************************
* execute an opcode

View File

@ -229,7 +229,7 @@ void Z180BurnCycles(INT32 cycles)
if (nActiveCPU == -1) bprintf(PRINT_ERROR, _T("Z180BurnCycles called when no CPU open\n"));
#endif
z180_burn(cycles);
bprintf(0, _T("Z180BurnCycles(); not implimented.\n"));
}
INT32 Z180Idle(INT32 cycles)
@ -247,12 +247,12 @@ void Z180SetIRQLine(INT32 irqline, INT32 state)
#if defined FBNEO_DEBUG
if (!DebugCPU_Z180Initted) bprintf(PRINT_ERROR, _T("Z180SetIRQLine called without init\n"));
if (nActiveCPU == -1) bprintf(PRINT_ERROR, _T("Z180SetIRQLine called when no CPU open\n"));
if (irqline != 0 && irqline != Z180_INPUT_LINE_NMI) bprintf(PRINT_ERROR, _T("Z180SetIRQLine called with invalid line %d\n"), irqline);
if (irqline != 0 && irqline != 0x20) bprintf(PRINT_ERROR, _T("Z180SetIRQLine called with invalid line %d\n"), irqline);
if (state != CPU_IRQSTATUS_NONE && state != CPU_IRQSTATUS_ACK && state != CPU_IRQSTATUS_AUTO && state != CPU_IRQSTATUS_HOLD)
bprintf(PRINT_ERROR, _T("Z180SetIRQLine called with invalid state %d\n"), state);
#endif
z180_set_irq_line(irqline, state);
z180_set_irq_line(irqline, state);
}
void Z180Nmi()

View File

@ -816,7 +816,7 @@
<li>Fix for replays desynching with games that use SRAM/NVRAM [dink]</li>
<li>Strikers 1945 Plus music fix [dink]</li>
<li>Fix Palette Viewer for games with BDF_16BIT_ONLY flag [dink]</li>
<li>Port Z180 Core from MAME and create FBAlpha-style cpu interface [Barry, iq_132]</li>
<li>Port Z180 Core from MAME and create FBAlpha-style cpu interface [dink, iq_132]</li>
<li>Hook-up Z180 sound-cpu in GHOX [Barry]</li>
<li>Games using flag BDF_16BIT_ONLY are no longer 1-frame behind emulation, other projects using FBAlpha please take note (see intf/video/vid_interface.cpp) [dink]</li>
<li>Fix DAC(psg) sounds in Afterburner II Megadrive [dink]</li>