- added INTE and state word callbacks

N8080.c
- rewrote interrupt handling according to schematics
- added interrupt acknowledge
This commit is contained in:
Curt Coder 2008-12-12 10:37:25 +00:00
parent a07c721c0a
commit 63a5cd896a
3 changed files with 82 additions and 15 deletions

View File

@ -155,6 +155,8 @@ struct _i8085_state
const address_space *io;
i8085_sod_func sod_callback;
i8085_sid_func sid_callback;
i8085_inte_func inte_callback;
i8085_status_func status_callback;
int icount;
UINT8 rim_ien;
};
@ -197,6 +199,9 @@ static void WM(i8085_state *cpustate, UINT32 a, UINT8 v)
INLINE void execute_one(i8085_state *cpustate, int opcode)
{
/* output state word */
if (cpustate->status_callback) (*cpustate->status_callback)(cpustate->device, cpustate->STATUS);
switch (opcode)
{
case 0x00: cpustate->icount -= 4; /* NOP */
@ -1129,6 +1134,7 @@ INLINE void execute_one(i8085_state *cpustate, int opcode)
case 0xf3: cpustate->icount -= 4; /* DI */
/* remove interrupt enable */
cpustate->IM &= ~IM_IEN;
if (cpustate->inte_callback) (*cpustate->inte_callback)(cpustate->device, (cpustate->IM & IM_IEN) ? 1 : 0);
break;
case 0xf4: cpustate->icount -= 11; /* CP nnnn */
M_CALL( !(cpustate->AF.b.l & SF) );
@ -1156,6 +1162,7 @@ INLINE void execute_one(i8085_state *cpustate, int opcode)
case 0xfb: cpustate->icount -= 4; /* EI */
/* set interrupt enable */
cpustate->IM |= IM_IEN;
if (cpustate->inte_callback) (*cpustate->inte_callback)(cpustate->device, (cpustate->IM & IM_IEN) ? 1 : 0);
/* remove serviced IRQ flag */
cpustate->IREQ &= ~cpustate->ISRV;
/* reset serviced IRQ */
@ -1310,6 +1317,7 @@ static CPU_EXECUTE( i8085 )
do
{
debugger_instruction_hook(device, cpustate->PC.d);
/* interrupts enabled or TRAP pending ? */
if ( (cpustate->IM & IM_IEN) || (cpustate->IREQ & IM_TRAP) )
{
@ -1395,21 +1403,29 @@ static CPU_RESET( i8085 )
cpu_irq_callback save_irqcallback;
i8085_sod_func save_sodcallback;
i8085_sid_func save_sidcallback;
i8085_inte_func save_intecallback;
i8085_status_func save_statuscallback;
int cputype_bak = cpustate->cputype;
init_tables();
save_irqcallback = cpustate->irq_callback;
save_sodcallback = cpustate->sod_callback;
save_sidcallback = cpustate->sid_callback;
save_intecallback = cpustate->inte_callback;
save_statuscallback = cpustate->status_callback;
memset(cpustate, 0, sizeof(*cpustate));
cpustate->irq_callback = save_irqcallback;
cpustate->sod_callback = save_sodcallback;
cpustate->sid_callback = save_sidcallback;
cpustate->inte_callback = save_intecallback;
cpustate->status_callback = save_statuscallback;
cpustate->device = device;
cpustate->program = memory_find_address_space(device, ADDRESS_SPACE_PROGRAM);
cpustate->io = memory_find_address_space(device, ADDRESS_SPACE_IO);
cpustate->cputype = cputype_bak;
if (cpustate->inte_callback) (*cpustate->inte_callback)(cpustate->device, (cpustate->IM & IM_IEN) ? 1 : 0);
}
/****************************************************************************
@ -1667,6 +1683,8 @@ static CPU_SET_INFO( i8085 )
/* --- the following bits of info are set as pointers to data or functions --- */
case CPUINFO_PTR_I8085_SOD_CALLBACK: cpustate->sod_callback = (i8085_sod_func)info->f; break;
case CPUINFO_PTR_I8085_SID_CALLBACK: cpustate->sid_callback = (i8085_sid_func)info->f; break;
case CPUINFO_PTR_I8085_INTE_CALLBACK: cpustate->inte_callback = (i8085_inte_func)info->f; break;
case CPUINFO_PTR_I8085_STATUS_CALLBACK: cpustate->status_callback = (i8085_status_func)info->f; break;
}
}

View File

@ -15,11 +15,15 @@ enum
{
CPUINFO_PTR_I8085_SOD_CALLBACK = CPUINFO_PTR_CPU_SPECIFIC,
CPUINFO_PTR_I8085_SID_CALLBACK = CPUINFO_PTR_CPU_SPECIFIC + 1,
CPUINFO_PTR_I8085_INTE_CALLBACK = CPUINFO_PTR_CPU_SPECIFIC + 2,
CPUINFO_PTR_I8085_STATUS_CALLBACK = CPUINFO_PTR_CPU_SPECIFIC + 3,
CPUINFO_INT_I8085_SID = CPUINFO_INT_CPU_SPECIFIC
};
typedef void (*i8085_sod_func)(const device_config *device, int state);
typedef int (*i8085_sid_func)(const device_config *device);
typedef void (*i8085_inte_func)(const device_config *device, int state);
typedef void (*i8085_status_func)(const device_config *device, UINT8 status);
#define I8085_INTR_LINE 0
@ -69,6 +73,16 @@ INLINE void i8085_set_sid_callback(const device_config *device, i8085_sid_func c
cpu_set_info_fct(device, CPUINFO_PTR_I8085_SID_CALLBACK, (genf *)callback);
}
INLINE void i8085_set_inte_callback(const device_config *device, i8085_inte_func callback)
{
cpu_set_info_fct(device, CPUINFO_PTR_I8085_INTE_CALLBACK, (genf *)callback);
}
INLINE void i8085_set_status_callback(const device_config *device, i8085_status_func callback)
{
cpu_set_info_fct(device, CPUINFO_PTR_I8085_STATUS_CALLBACK, (genf *)callback);
}
INLINE void i8085_set_sid(const device_config *device, int sid)
{
cpu_set_info_int(device, CPUINFO_INT_I8085_SID, sid);

View File

@ -12,11 +12,12 @@
#include "driver.h"
#include "deprecat.h"
#include "cpu/i8085/i8085.h"
#include "includes/n8080.h"
static unsigned shift_data;
static unsigned shift_bits;
static int inte;
static WRITE8_HANDLER( n8080_shift_bits_w )
{
@ -33,16 +34,6 @@ static READ8_HANDLER( n8080_shift_r )
return shift_data >> (8 - shift_bits);
}
static INTERRUPT_GEN( interrupt )
{
if (video_screen_get_vblank(device->machine->primary_screen))
cpu_set_input_line_and_vector(device, 0, PULSE_LINE, 0xcf); /* RST $08 */
else
cpu_set_input_line_and_vector(device, 0, PULSE_LINE, 0xd7); /* RST $10 */
}
static ADDRESS_MAP_START( main_cpu_map, ADDRESS_SPACE_PROGRAM, 8 )
ADDRESS_MAP_GLOBAL_MASK(0x7fff)
AM_RANGE(0x0000, 0x3fff) AM_ROM
@ -56,7 +47,6 @@ static ADDRESS_MAP_START( helifire_main_cpu_map, ADDRESS_SPACE_PROGRAM, 8 )
AM_RANGE(0xc000, 0xdfff) AM_RAM AM_BASE(&colorram)
ADDRESS_MAP_END
static ADDRESS_MAP_START( main_io_map, ADDRESS_SPACE_IO, 8 )
ADDRESS_MAP_GLOBAL_MASK(0x7)
AM_RANGE(0x00, 0x00) AM_READ_PORT("IN0")
@ -72,6 +62,39 @@ static ADDRESS_MAP_START( main_io_map, ADDRESS_SPACE_IO, 8 )
AM_RANGE(0x06, 0x06) AM_WRITE(n8080_video_control_w)
ADDRESS_MAP_END
/* Interrupts */
static TIMER_DEVICE_CALLBACK( rst1_tick )
{
/* V7 = 1, V6 = 0 */
cpu_set_input_line_and_vector(cputag_get_cpu(timer->machine, "main"), INPUT_LINE_IRQ0, ASSERT_LINE, 0xcf);
}
static TIMER_DEVICE_CALLBACK( rst2_tick )
{
/* vblank */
cpu_set_input_line_and_vector(cputag_get_cpu(timer->machine, "main"), INPUT_LINE_IRQ0, ASSERT_LINE, 0xd7);
}
static n8080_inte_callback(const device_config *device, int state)
{
inte = state;
}
static n8080_status_callback(const device_config *device, UINT8 status)
{
if (BIT(status, 0))
{
/* interrupt acknowledge */
cpu_set_input_line(device, INPUT_LINE_IRQ0, CLEAR_LINE);
}
}
static MACHINE_START( spacefev )
{
i8085_set_status_callback(cputag_get_cpu(machine, "main"), n8080_status_callback);
i8085_set_inte_callback(cputag_get_cpu(machine, "main"), n8080_inte_callback);
}
static MACHINE_DRIVER_START( spacefev )
@ -79,7 +102,8 @@ static MACHINE_DRIVER_START( spacefev )
MDRV_CPU_ADD("main", 8080, 20160000 / 10)
MDRV_CPU_PROGRAM_MAP(main_cpu_map, 0)
MDRV_CPU_IO_MAP(main_io_map, 0)
MDRV_CPU_VBLANK_INT_HACK(interrupt, 2)
MDRV_MACHINE_START(spacefev)
/* video hardware */
MDRV_SCREEN_ADD("main", RASTER)
@ -93,6 +117,9 @@ static MACHINE_DRIVER_START( spacefev )
MDRV_VIDEO_START(spacefev)
MDRV_VIDEO_UPDATE(spacefev)
MDRV_TIMER_ADD_SCANLINE("rst1", rst1_tick, "main", 128, 256)
MDRV_TIMER_ADD_SCANLINE("rst2", rst2_tick, "main", 240, 256)
/* sound hardware */
MDRV_IMPORT_FROM( spacefev_sound )
MACHINE_DRIVER_END
@ -104,7 +131,8 @@ static MACHINE_DRIVER_START( sheriff )
MDRV_CPU_ADD("main", 8080, 20160000 / 10)
MDRV_CPU_PROGRAM_MAP(main_cpu_map, 0)
MDRV_CPU_IO_MAP(main_io_map, 0)
MDRV_CPU_VBLANK_INT_HACK(interrupt, 2)
MDRV_MACHINE_START(spacefev)
/* video hardware */
MDRV_SCREEN_ADD("main", RASTER)
@ -118,6 +146,9 @@ static MACHINE_DRIVER_START( sheriff )
MDRV_VIDEO_START(sheriff)
MDRV_VIDEO_UPDATE(sheriff)
MDRV_TIMER_ADD_SCANLINE("rst1", rst1_tick, "main", 128, 256)
MDRV_TIMER_ADD_SCANLINE("rst2", rst2_tick, "main", 240, 256)
/* sound hardware */
MDRV_IMPORT_FROM( sheriff_sound )
MACHINE_DRIVER_END
@ -129,7 +160,8 @@ static MACHINE_DRIVER_START( helifire )
MDRV_CPU_ADD("main", 8080, 20160000 / 10)
MDRV_CPU_PROGRAM_MAP(helifire_main_cpu_map, 0)
MDRV_CPU_IO_MAP(main_io_map, 0)
MDRV_CPU_VBLANK_INT_HACK(interrupt, 2)
MDRV_MACHINE_START(spacefev)
/* video hardware */
MDRV_SCREEN_ADD("main", RASTER)
@ -144,6 +176,9 @@ static MACHINE_DRIVER_START( helifire )
MDRV_VIDEO_UPDATE(helifire)
MDRV_VIDEO_EOF(helifire)
MDRV_TIMER_ADD_SCANLINE("rst1", rst1_tick, "main", 128, 256)
MDRV_TIMER_ADD_SCANLINE("rst2", rst2_tick, "main", 240, 256)
/* sound hardware */
MDRV_IMPORT_FROM( helifire_sound )
MACHINE_DRIVER_END