mirror of
https://github.com/holub/mame
synced 2025-04-24 09:20:02 +03:00
sm8500: Converted to C++ (nw)
This commit is contained in:
parent
30b6014d2d
commit
9de1534f04
@ -21,580 +21,402 @@ they are internally.
|
||||
#include "debugger.h"
|
||||
#include "sm8500.h"
|
||||
|
||||
#define FLAG_C 0x80
|
||||
#define FLAG_Z 0x40
|
||||
#define FLAG_S 0x20
|
||||
#define FLAG_V 0x10
|
||||
#define FLAG_D 0x08
|
||||
#define FLAG_H 0x04
|
||||
#define FLAG_B 0x02
|
||||
#define FLAG_I 0x01
|
||||
|
||||
struct sm8500_state
|
||||
{
|
||||
SM8500_CONFIG config;
|
||||
UINT16 PC;
|
||||
UINT8 IE0;
|
||||
UINT8 IE1;
|
||||
UINT8 IR0;
|
||||
UINT8 IR1;
|
||||
UINT8 SYS;
|
||||
UINT8 CKC;
|
||||
UINT8 clock_changed;
|
||||
UINT16 SP;
|
||||
UINT8 PS0;
|
||||
UINT8 PS1;
|
||||
UINT16 IFLAGS;
|
||||
UINT8 CheckInterrupts;
|
||||
int halted;
|
||||
int icount;
|
||||
device_irq_acknowledge_callback irq_callback;
|
||||
legacy_cpu_device *device;
|
||||
address_space *program;
|
||||
UINT16 oldpc;
|
||||
UINT8 register_ram[0x108];
|
||||
};
|
||||
const device_type SM8500 = &device_creator<sm8500_cpu_device>;
|
||||
|
||||
INLINE sm8500_state *get_safe_token(device_t *device)
|
||||
{
|
||||
assert(device != NULL);
|
||||
assert(device->type() == SM8500);
|
||||
return (sm8500_state *)downcast<legacy_cpu_device *>(device)->token();
|
||||
}
|
||||
|
||||
static const UINT8 sm8500_b2w[8] = {
|
||||
0, 8, 2, 10, 4, 12, 6, 14
|
||||
};
|
||||
|
||||
INLINE void sm8500_get_sp( sm8500_state *cpustate )
|
||||
|
||||
sm8500_cpu_device::sm8500_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: cpu_device(mconfig, SM8500, "SM8500", tag, owner, clock)
|
||||
, m_program_config("program", ENDIANNESS_BIG, 8, 16, 0)
|
||||
, m_dma_func(*this)
|
||||
, m_timer_func(*this)
|
||||
{
|
||||
UINT16 data = cpustate->program->read_byte(0x1c) << 8;
|
||||
cpustate->SP = cpustate->program->read_byte(0x1d);
|
||||
if (cpustate->SYS&0x40) cpustate->SP |= data;
|
||||
}
|
||||
|
||||
static UINT8 sm85cpu_mem_readbyte( sm8500_state *cpustate, UINT32 offset )
|
||||
|
||||
void sm8500_cpu_device::get_sp()
|
||||
{
|
||||
m_SP = m_program->read_byte(0x1d);
|
||||
if (m_SYS & 0x40) m_SP |= ( m_program->read_byte(0x1c) << 8 );
|
||||
}
|
||||
|
||||
|
||||
UINT8 sm8500_cpu_device::mem_readbyte( UINT32 offset )
|
||||
{
|
||||
offset &= 0xffff;
|
||||
return (offset < 0x10) ? cpustate->register_ram[offset + (cpustate->PS0 & 0xF8)]
|
||||
: cpustate->program->read_byte( offset );
|
||||
if ( offset < 0x10)
|
||||
{
|
||||
return m_register_ram[offset + (m_PS0 & 0xF8)];
|
||||
}
|
||||
|
||||
return m_program->read_byte( offset );
|
||||
}
|
||||
|
||||
static void sm85cpu_mem_writebyte( sm8500_state *cpustate, UINT32 offset, UINT8 data )
|
||||
|
||||
void sm8500_cpu_device::mem_writebyte( UINT32 offset, UINT8 data )
|
||||
{
|
||||
UINT8 i;
|
||||
offset &= 0xffff;
|
||||
if (offset < 0x10)
|
||||
cpustate->register_ram[offset + (cpustate->PS0 & 0xF8)] = data;
|
||||
{
|
||||
m_register_ram[offset + (m_PS0 & 0xF8)] = data;
|
||||
}
|
||||
|
||||
cpustate->program->write_byte ( offset, data );
|
||||
m_program->write_byte( offset, data );
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0x10: cpustate->IE0 = data; break;
|
||||
case 0x11: cpustate->IE1 = data; break;
|
||||
case 0x12: cpustate->IR0 = data; break;
|
||||
case 0x13: cpustate->IR1 = data; break;
|
||||
case 0x19: cpustate->SYS = data; break;
|
||||
case 0x1a: cpustate->CKC = data; break;
|
||||
case 0x10: m_IE0 = data; break;
|
||||
case 0x11: m_IE1 = data; break;
|
||||
case 0x12: m_IR0 = data; break;
|
||||
case 0x13: m_IR1 = data; break;
|
||||
case 0x19: m_SYS = data; break;
|
||||
case 0x1a: m_CKC = data; break;
|
||||
case 0x1c:
|
||||
case 0x1d: sm8500_get_sp(cpustate); break;
|
||||
case 0x1e: cpustate->PS0 = data;
|
||||
case 0x1d: get_sp(); break;
|
||||
case 0x1e: m_PS0 = data;
|
||||
for (i = 0; i < 16; i++) // refresh register contents in debugger
|
||||
cpustate->program->write_byte(i, sm85cpu_mem_readbyte(cpustate, i)); break;
|
||||
case 0x1f: cpustate->PS1 = data; break;
|
||||
{
|
||||
m_program->write_byte(i, mem_readbyte(i));
|
||||
}
|
||||
break;
|
||||
case 0x1f: m_PS1 = data; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
INLINE UINT16 sm85cpu_mem_readword( sm8500_state *cpustate, UINT32 address )
|
||||
void sm8500_cpu_device::device_start()
|
||||
{
|
||||
return (sm85cpu_mem_readbyte( cpustate, address ) << 8) | (sm85cpu_mem_readbyte( cpustate, address+1 ));
|
||||
m_program = &space(AS_PROGRAM);
|
||||
|
||||
m_dma_func.resolve_safe();
|
||||
m_timer_func.resolve_safe();
|
||||
|
||||
save_item(NAME(m_PC));
|
||||
save_item(NAME(m_IE0));
|
||||
save_item(NAME(m_IE1));
|
||||
save_item(NAME(m_IR0));
|
||||
save_item(NAME(m_IR1));
|
||||
save_item(NAME(m_SYS));
|
||||
save_item(NAME(m_CKC));
|
||||
save_item(NAME(m_clock_changed));
|
||||
save_item(NAME(m_SP));
|
||||
save_item(NAME(m_PS0));
|
||||
save_item(NAME(m_PS1));
|
||||
save_item(NAME(m_IFLAGS));
|
||||
save_item(NAME(m_CheckInterrupts));
|
||||
save_item(NAME(m_halted));
|
||||
save_item(NAME(m_oldpc));
|
||||
save_pointer(NAME(m_register_ram),0x108);
|
||||
|
||||
// Register state for debugger
|
||||
state_add(SM8500_PC, "PC", m_PC ).callimport().callexport().formatstr("%04X");
|
||||
state_add(SM8500_SP, "SP", m_SP ).callimport().callexport().formatstr("%04X");
|
||||
state_add(SM8500_PS, "PS", m_PS0 ).callimport().callexport().formatstr("%04s");
|
||||
state_add(SM8500_SYS, "SYS", m_SYS ).callimport().callexport().formatstr("%04X");
|
||||
state_add(SM8500_RR0, "RR0", m_PC ).callimport().callexport().formatstr("%04s");
|
||||
state_add(SM8500_RR2, "RR2", m_PC ).callimport().callexport().formatstr("%04s");
|
||||
state_add(SM8500_RR4, "RR4", m_PC ).callimport().callexport().formatstr("%04s");
|
||||
state_add(SM8500_RR6, "RR6", m_PC ).callimport().callexport().formatstr("%04s");
|
||||
state_add(SM8500_RR8, "RR8", m_PC ).callimport().callexport().formatstr("%04s");
|
||||
state_add(SM8500_RR10, "RR10", m_PC ).callimport().callexport().formatstr("%04s");
|
||||
state_add(SM8500_RR12, "RR12", m_PC ).callimport().callexport().formatstr("%04s");
|
||||
state_add(SM8500_RR14, "RR14", m_PC ).callimport().callexport().formatstr("%04s");
|
||||
state_add(STATE_GENPC, "curpc", m_PC).callimport().callexport().formatstr("%8s").noshow();
|
||||
state_add(STATE_GENFLAGS, "GENFLAGS", m_PS1).formatstr("%8s").noshow();
|
||||
|
||||
m_icountptr = &m_icount;
|
||||
}
|
||||
|
||||
INLINE void sm85cpu_mem_writeword( sm8500_state *cpustate, UINT32 address, UINT16 value )
|
||||
{
|
||||
sm85cpu_mem_writebyte( cpustate, address, value >> 8 );
|
||||
sm85cpu_mem_writebyte( cpustate, address+1, value );
|
||||
}
|
||||
|
||||
static CPU_INIT( sm8500 )
|
||||
void sm8500_cpu_device::state_string_export(const device_state_entry &entry, astring &string)
|
||||
{
|
||||
sm8500_state *cpustate = get_safe_token(device);
|
||||
switch (entry.index())
|
||||
{
|
||||
case SM8500_PS:
|
||||
string.printf( "%04X", ( m_PS0 << 8 ) | m_PS1 );
|
||||
break;
|
||||
|
||||
cpustate->irq_callback = irqcallback;
|
||||
cpustate->device = device;
|
||||
cpustate->program = &device->space(AS_PROGRAM);
|
||||
if ( device->static_config() != NULL ) {
|
||||
cpustate->config.handle_dma = ((SM8500_CONFIG *)device->static_config())->handle_dma;
|
||||
cpustate->config.handle_timers = ((SM8500_CONFIG *)device->static_config())->handle_timers;
|
||||
} else {
|
||||
cpustate->config.handle_dma = NULL;
|
||||
cpustate->config.handle_timers = NULL;
|
||||
case SM8500_RR0:
|
||||
string.printf( "%04X", mem_readword( 0x00 ) );
|
||||
break;
|
||||
|
||||
case SM8500_RR2:
|
||||
string.printf( "%04X", mem_readword( 0x02 ) );
|
||||
break;
|
||||
|
||||
case SM8500_RR4:
|
||||
string.printf( "%04X", mem_readword( 0x04 ) );
|
||||
break;
|
||||
|
||||
case SM8500_RR6:
|
||||
string.printf( "%04X", mem_readword( 0x06 ) );
|
||||
break;
|
||||
|
||||
case SM8500_RR8:
|
||||
string.printf( "%04X", mem_readword( 0x08 ) );
|
||||
break;
|
||||
|
||||
case SM8500_RR10:
|
||||
string.printf( "%04X", mem_readword( 0x0a ) );
|
||||
break;
|
||||
|
||||
case SM8500_RR12:
|
||||
string.printf( "%04X", mem_readword( 0x0c ) );
|
||||
break;
|
||||
|
||||
case SM8500_RR14:
|
||||
string.printf( "%04X", mem_readword( 0x0e ) );
|
||||
break;
|
||||
|
||||
case STATE_GENFLAGS:
|
||||
string.printf( "%c%c%c%c%c%c%c%c",
|
||||
m_PS1 & FLAG_C ? 'C' : '.',
|
||||
m_PS1 & FLAG_Z ? 'Z' : '.',
|
||||
m_PS1 & FLAG_S ? 'S' : '.',
|
||||
m_PS1 & FLAG_V ? 'V' : '.',
|
||||
m_PS1 & FLAG_D ? 'D' : '.',
|
||||
m_PS1 & FLAG_H ? 'H' : '.',
|
||||
m_PS1 & FLAG_B ? 'B' : '.',
|
||||
m_PS1 & FLAG_I ? 'I' : '.' );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static CPU_RESET( sm8500 )
|
||||
{
|
||||
sm8500_state *cpustate = get_safe_token(device);
|
||||
|
||||
cpustate->PC = 0x1020;
|
||||
cpustate->clock_changed = 0;
|
||||
cpustate->halted = 0;
|
||||
sm85cpu_mem_writeword(cpustate, 0x10, 0); // IE0, IE1
|
||||
sm85cpu_mem_writeword(cpustate, 0x12, 0); // IR0, IR1
|
||||
sm85cpu_mem_writeword(cpustate, 0x14, 0xffff); // P0, P1
|
||||
sm85cpu_mem_writeword(cpustate, 0x16, 0xff00); // P2, P3
|
||||
sm85cpu_mem_writebyte(cpustate, 0x19, 0); // SYS
|
||||
sm85cpu_mem_writebyte(cpustate, 0x1a, 0); // CKC
|
||||
sm85cpu_mem_writebyte(cpustate, 0x1f, 0); // PS1
|
||||
sm85cpu_mem_writebyte(cpustate, 0x2b, 0xff); // URTT
|
||||
sm85cpu_mem_writebyte(cpustate, 0x2d, 0x42); // URTS
|
||||
sm85cpu_mem_writebyte(cpustate, 0x5f, 0x38); // WDTC
|
||||
void sm8500_cpu_device::device_reset()
|
||||
{
|
||||
for ( int i = 0; i < 0x108; i++ )
|
||||
{
|
||||
m_register_ram[i] = 0;
|
||||
}
|
||||
|
||||
m_PC = 0x1020;
|
||||
m_clock_changed = 0;
|
||||
m_CheckInterrupts = 0;
|
||||
m_halted = 0;
|
||||
m_IFLAGS = 0;
|
||||
mem_writeword(0x10, 0); // IE0, IE1
|
||||
mem_writeword(0x12, 0); // IR0, IR1
|
||||
mem_writeword(0x14, 0xffff); // P0, P1
|
||||
mem_writeword(0x16, 0xff00); // P2, P3
|
||||
mem_writebyte(0x19, 0); // SYS
|
||||
mem_writebyte(0x1a, 0); // CKC
|
||||
mem_writebyte(0x1f, 0); // PS1
|
||||
mem_writebyte(0x2b, 0xff); // URTT
|
||||
mem_writebyte(0x2d, 0x42); // URTS
|
||||
mem_writebyte(0x5f, 0x38); // WDTC
|
||||
}
|
||||
|
||||
static CPU_EXIT( sm8500 )
|
||||
|
||||
#define PUSH_BYTE(X) m_SP--; \
|
||||
if ( ( m_SYS & 0x40 ) == 0 ) m_SP &= 0xFF; \
|
||||
mem_writebyte( m_SP, X );
|
||||
|
||||
|
||||
void sm8500_cpu_device::take_interrupt(UINT16 vector)
|
||||
{
|
||||
}
|
||||
|
||||
#define PUSH_BYTE(X) cpustate->SP--; \
|
||||
if ( ( cpustate->SYS & 0x40 ) == 0 ) cpustate->SP &= 0xFF; \
|
||||
sm85cpu_mem_writebyte( cpustate, cpustate->SP, X );
|
||||
|
||||
INLINE void sm8500_do_interrupt(sm8500_state *cpustate, UINT16 vector) {
|
||||
/* Get regs from ram */
|
||||
sm8500_get_sp(cpustate);
|
||||
cpustate->SYS = cpustate->program->read_byte(0x19);
|
||||
cpustate->PS1 = cpustate->program->read_byte(0x1f);
|
||||
get_sp();
|
||||
m_SYS = m_program->read_byte(0x19);
|
||||
m_PS1 = m_program->read_byte(0x1f);
|
||||
/* Push PC */
|
||||
PUSH_BYTE( cpustate->PC & 0xFF );
|
||||
PUSH_BYTE( cpustate->PC >> 8 );
|
||||
PUSH_BYTE( m_PC & 0xFF );
|
||||
PUSH_BYTE( m_PC >> 8 );
|
||||
/* Push PS1 */
|
||||
PUSH_BYTE( cpustate->PS1 );
|
||||
PUSH_BYTE( m_PS1 );
|
||||
/* Clear I flag */
|
||||
cpustate->PS1 &= ~ 0x01;
|
||||
m_PS1 &= ~ 0x01;
|
||||
/* save regs to ram */
|
||||
cpustate->program->write_byte (0x1f, cpustate->PS1);
|
||||
cpustate->program->write_byte (0x1d, cpustate->SP&0xFF);
|
||||
if (cpustate->SYS&0x40) cpustate->program->write_byte(0x1c, cpustate->SP>>8);
|
||||
m_program->write_byte(0x1f, m_PS1);
|
||||
m_program->write_byte(0x1d, m_SP&0xFF);
|
||||
if (m_SYS&0x40) m_program->write_byte(0x1c, m_SP>>8);
|
||||
/* Change PC to address stored at "vector" */
|
||||
cpustate->PC = sm85cpu_mem_readword( cpustate, vector );
|
||||
m_PC = mem_readword( vector );
|
||||
}
|
||||
|
||||
INLINE void sm8500_process_interrupts(sm8500_state *cpustate) {
|
||||
if ( cpustate->CheckInterrupts ) {
|
||||
|
||||
void sm8500_cpu_device::process_interrupts()
|
||||
{
|
||||
if ( m_CheckInterrupts )
|
||||
{
|
||||
int irqline = 0;
|
||||
while( irqline < 11 ) {
|
||||
if ( cpustate->IFLAGS & ( 1 << irqline ) ) {
|
||||
cpustate->halted = 0;
|
||||
cpustate->IE0 = cpustate->program->read_byte(0x10);
|
||||
cpustate->IE1 = cpustate->program->read_byte(0x11);
|
||||
cpustate->IR0 = cpustate->program->read_byte(0x12);
|
||||
cpustate->IR1 = cpustate->program->read_byte(0x13);
|
||||
cpustate->PS0 = cpustate->program->read_byte(0x1e);
|
||||
cpustate->PS1 = cpustate->program->read_byte(0x1f);
|
||||
switch( irqline ) {
|
||||
while( irqline < 11 )
|
||||
{
|
||||
if ( m_IFLAGS & ( 1 << irqline ) )
|
||||
{
|
||||
m_halted = 0;
|
||||
m_IE0 = m_program->read_byte(0x10);
|
||||
m_IE1 = m_program->read_byte(0x11);
|
||||
m_IR0 = m_program->read_byte(0x12);
|
||||
m_IR1 = m_program->read_byte(0x13);
|
||||
m_PS0 = m_program->read_byte(0x1e);
|
||||
m_PS1 = m_program->read_byte(0x1f);
|
||||
switch( irqline )
|
||||
{
|
||||
case WDT_INT:
|
||||
sm8500_do_interrupt( cpustate, 0x101C );
|
||||
take_interrupt( 0x101C );
|
||||
break;
|
||||
case ILL_INT:
|
||||
case NMI_INT:
|
||||
sm8500_do_interrupt( cpustate, 0x101E );
|
||||
take_interrupt( 0x101E );
|
||||
break;
|
||||
case DMA_INT:
|
||||
cpustate->IR0 |= 0x80;
|
||||
if ( ( cpustate->IE0 & 0x80 ) && ( ( cpustate->PS0 & 0x07 ) < 8 ) && ( cpustate->PS1 & 0x01 ) ) {
|
||||
sm8500_do_interrupt( cpustate, 0x1000 );
|
||||
m_IR0 |= 0x80;
|
||||
if ( ( m_IE0 & 0x80 ) && ( ( m_PS0 & 0x07 ) < 8 ) && ( m_PS1 & 0x01 ) )
|
||||
{
|
||||
take_interrupt( 0x1000 );
|
||||
}
|
||||
break;
|
||||
case TIM0_INT:
|
||||
cpustate->IR0 |= 0x40;
|
||||
if ( ( cpustate->IE0 & 0x40 ) && ( ( cpustate->PS0 & 0x07 ) < 8 ) && ( cpustate->PS1 & 0x01 ) ) {
|
||||
sm8500_do_interrupt( cpustate, 0x1002 );
|
||||
m_IR0 |= 0x40;
|
||||
if ( ( m_IE0 & 0x40 ) && ( ( m_PS0 & 0x07 ) < 8 ) && ( m_PS1 & 0x01 ) )
|
||||
{
|
||||
take_interrupt( 0x1002 );
|
||||
}
|
||||
break;
|
||||
case EXT_INT:
|
||||
cpustate->IR0 |= 0x10;
|
||||
if ( ( cpustate->IE0 & 0x10 ) && ( ( cpustate->PS0 & 0x07 ) < 7 ) && ( cpustate->PS1 & 0x01 ) ) {
|
||||
sm8500_do_interrupt( cpustate, 0x1006 );
|
||||
m_IR0 |= 0x10;
|
||||
if ( ( m_IE0 & 0x10 ) && ( ( m_PS0 & 0x07 ) < 7 ) && ( m_PS1 & 0x01 ) )
|
||||
{
|
||||
take_interrupt( 0x1006 );
|
||||
}
|
||||
break;
|
||||
case UART_INT:
|
||||
cpustate->IR0 |= 0x08;
|
||||
if ( ( cpustate->IE0 & 0x08 ) && ( ( cpustate->PS0 & 0x07 ) < 6 ) && ( cpustate->PS1 & 0x01 ) ) {
|
||||
sm8500_do_interrupt( cpustate, 0x1008 );
|
||||
m_IR0 |= 0x08;
|
||||
if ( ( m_IE0 & 0x08 ) && ( ( m_PS0 & 0x07 ) < 6 ) && ( m_PS1 & 0x01 ) )
|
||||
{
|
||||
take_interrupt( 0x1008 );
|
||||
}
|
||||
break;
|
||||
case LCDC_INT:
|
||||
cpustate->IR0 |= 0x01;
|
||||
if ( ( cpustate->IE0 & 0x01 ) && ( ( cpustate->PS0 & 0x07 ) < 5 ) && ( cpustate->PS1 & 0x01 ) ) {
|
||||
sm8500_do_interrupt( cpustate, 0x100E );
|
||||
m_IR0 |= 0x01;
|
||||
if ( ( m_IE0 & 0x01 ) && ( ( m_PS0 & 0x07 ) < 5 ) && ( m_PS1 & 0x01 ) )
|
||||
{
|
||||
take_interrupt( 0x100E );
|
||||
}
|
||||
break;
|
||||
case TIM1_INT:
|
||||
cpustate->IR1 |= 0x40;
|
||||
if ( ( cpustate->IE1 & 0x40 ) && ( ( cpustate->PS0 & 0x07 ) < 4 ) && ( cpustate->PS1 & 0x01 ) ) {
|
||||
sm8500_do_interrupt( cpustate, 0x1012 );
|
||||
m_IR1 |= 0x40;
|
||||
if ( ( m_IE1 & 0x40 ) && ( ( m_PS0 & 0x07 ) < 4 ) && ( m_PS1 & 0x01 ) )
|
||||
{
|
||||
take_interrupt( 0x1012 );
|
||||
}
|
||||
break;
|
||||
case CK_INT:
|
||||
cpustate->IR1 |= 0x10;
|
||||
if ( ( cpustate->IE1 & 0x10 ) && ( ( cpustate->PS0 & 0x07 ) < 3 ) && ( cpustate->PS1 & 0x01 ) ) {
|
||||
sm8500_do_interrupt( cpustate, 0x1016 );
|
||||
m_IR1 |= 0x10;
|
||||
if ( ( m_IE1 & 0x10 ) && ( ( m_PS0 & 0x07 ) < 3 ) && ( m_PS1 & 0x01 ) )
|
||||
{
|
||||
take_interrupt( 0x1016 );
|
||||
}
|
||||
break;
|
||||
case PIO_INT:
|
||||
cpustate->IR1 |= 0x04;
|
||||
if ( ( cpustate->IE1 & 0x04 ) && ( ( cpustate->PS0 & 0x07 ) < 2 ) && ( cpustate->PS1 & 0x01 ) ) {
|
||||
sm8500_do_interrupt( cpustate, 0x101A );
|
||||
m_IR1 |= 0x04;
|
||||
if ( ( m_IE1 & 0x04 ) && ( ( m_PS0 & 0x07 ) < 2 ) && ( m_PS1 & 0x01 ) )
|
||||
{
|
||||
take_interrupt( 0x101A );
|
||||
}
|
||||
break;
|
||||
}
|
||||
cpustate->IFLAGS &= ~ ( 1 << irqline );
|
||||
cpustate->program->write_byte(0x12, cpustate->IR0);
|
||||
cpustate->program->write_byte(0x13, cpustate->IR1);
|
||||
m_IFLAGS &= ~ ( 1 << irqline );
|
||||
m_program->write_byte(0x12, m_IR0);
|
||||
m_program->write_byte(0x13, m_IR1);
|
||||
}
|
||||
irqline++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static CPU_EXECUTE( sm8500 )
|
||||
{
|
||||
sm8500_state *cpustate = get_safe_token(device);
|
||||
UINT8 op;
|
||||
int mycycles;
|
||||
|
||||
offs_t sm8500_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
|
||||
{
|
||||
extern CPU_DISASSEMBLE( sm8500 );
|
||||
return CPU_DISASSEMBLE_NAME( sm8500 )(NULL, buffer, pc, oprom, opram, 0);
|
||||
}
|
||||
|
||||
|
||||
void sm8500_cpu_device::execute_run()
|
||||
{
|
||||
do
|
||||
{
|
||||
int mycycles = 0;
|
||||
UINT8 r1,r2;
|
||||
UINT16 s1,s2;
|
||||
UINT32 d1,d2;
|
||||
UINT32 res;
|
||||
|
||||
debugger_instruction_hook(device, cpustate->PC);
|
||||
cpustate->oldpc = cpustate->PC;
|
||||
mycycles = 0;
|
||||
sm8500_process_interrupts(cpustate);
|
||||
if ( !cpustate->halted ) {
|
||||
op = sm85cpu_mem_readbyte( cpustate, cpustate->PC++ );
|
||||
cpustate->SYS = cpustate->program->read_byte(0x19);
|
||||
cpustate->PS0 = cpustate->program->read_byte(0x1e);
|
||||
cpustate->PS1 = cpustate->program->read_byte(0x1f);
|
||||
sm8500_get_sp(cpustate);
|
||||
debugger_instruction_hook(this, m_PC);
|
||||
m_oldpc = m_PC;
|
||||
process_interrupts();
|
||||
if ( !m_halted ) {
|
||||
UINT8 op = mem_readbyte( m_PC++ );
|
||||
m_SYS = m_program->read_byte(0x19);
|
||||
m_PS0 = m_program->read_byte(0x1e);
|
||||
m_PS1 = m_program->read_byte(0x1f);
|
||||
get_sp();
|
||||
switch( op )
|
||||
{
|
||||
#include "sm85ops.h"
|
||||
}
|
||||
if (cpustate->SYS&0x40) cpustate->program->write_byte(0x1c,cpustate->SP>>8);
|
||||
cpustate->program->write_byte(0x1d,cpustate->SP&0xFF);
|
||||
sm85cpu_mem_writebyte(cpustate,0x1e,cpustate->PS0); // need to update debugger
|
||||
cpustate->program->write_byte(0x1f,cpustate->PS1);
|
||||
if (m_SYS&0x40) m_program->write_byte(0x1c,m_SP>>8);
|
||||
m_program->write_byte(0x1d,m_SP&0xFF);
|
||||
mem_writebyte(0x1e,m_PS0); // need to update debugger
|
||||
m_program->write_byte(0x1f,m_PS1);
|
||||
} else {
|
||||
mycycles = 4;
|
||||
if ( cpustate->config.handle_dma ) {
|
||||
cpustate->config.handle_dma( device, mycycles );
|
||||
}
|
||||
m_dma_func( mycycles );
|
||||
}
|
||||
if ( cpustate->config.handle_timers ) {
|
||||
cpustate->config.handle_timers( device, mycycles );
|
||||
}
|
||||
cpustate->icount -= mycycles;
|
||||
} while ( cpustate->icount > 0 );
|
||||
m_timer_func( mycycles );
|
||||
m_icount -= mycycles;
|
||||
} while ( m_icount > 0 );
|
||||
}
|
||||
|
||||
static CPU_BURN( sm8500 )
|
||||
{
|
||||
sm8500_state *cpustate = get_safe_token(device);
|
||||
|
||||
if ( cycles > 0 ) {
|
||||
/* burn a number of 4 cycles */
|
||||
int n = ( cycles + 3 ) / 4;
|
||||
cpustate->icount -= 4 * n;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned sm8500_get_reg( sm8500_state *cpustate, int regnum )
|
||||
void sm8500_cpu_device::execute_set_input( int inptnum, int state )
|
||||
{
|
||||
switch( regnum )
|
||||
m_IR0 = m_program->read_byte(0x12);
|
||||
m_IR1 = m_program->read_byte(0x13);
|
||||
if ( state == ASSERT_LINE )
|
||||
{
|
||||
case STATE_GENPC:
|
||||
case SM8500_PC: return cpustate->PC;
|
||||
case STATE_GENSP:
|
||||
case SM8500_SP: return cpustate->SP;
|
||||
case SM8500_PS: return sm85cpu_mem_readword( cpustate, 0x1e );
|
||||
case SM8500_SYS16: return cpustate->SYS;
|
||||
case SM8500_RR0: return sm85cpu_mem_readword( cpustate, 0x00 );
|
||||
case SM8500_RR2: return sm85cpu_mem_readword( cpustate, 0x02 );
|
||||
case SM8500_RR4: return sm85cpu_mem_readword( cpustate, 0x04 );
|
||||
case SM8500_RR6: return sm85cpu_mem_readword( cpustate, 0x06 );
|
||||
case SM8500_RR8: return sm85cpu_mem_readword( cpustate, 0x08 );
|
||||
case SM8500_RR10: return sm85cpu_mem_readword( cpustate, 0x0A );
|
||||
case SM8500_RR12: return sm85cpu_mem_readword( cpustate, 0x0C );
|
||||
case SM8500_RR14: return sm85cpu_mem_readword( cpustate, 0x0E );
|
||||
case SM8500_IE0: return sm85cpu_mem_readbyte( cpustate, 0x10 );
|
||||
case SM8500_IE1: return sm85cpu_mem_readbyte( cpustate, 0x11 );
|
||||
case SM8500_IR0: return sm85cpu_mem_readbyte( cpustate, 0x12 );
|
||||
case SM8500_IR1: return sm85cpu_mem_readbyte( cpustate, 0x13 );
|
||||
case SM8500_P0: return sm85cpu_mem_readbyte( cpustate, 0x14 );
|
||||
case SM8500_P1: return sm85cpu_mem_readbyte( cpustate, 0x15 );
|
||||
case SM8500_P2: return sm85cpu_mem_readbyte( cpustate, 0x16 );
|
||||
case SM8500_P3: return sm85cpu_mem_readbyte( cpustate, 0x17 );
|
||||
case SM8500_SYS: return sm85cpu_mem_readbyte( cpustate, 0x19 );
|
||||
case SM8500_CKC: return sm85cpu_mem_readbyte( cpustate, 0x1a );
|
||||
case SM8500_SPH: return sm85cpu_mem_readbyte( cpustate, 0x1c );
|
||||
case SM8500_SPL: return sm85cpu_mem_readbyte( cpustate, 0x1d );
|
||||
case SM8500_PS0: return sm85cpu_mem_readbyte( cpustate, 0x1e );
|
||||
case SM8500_PS1: return sm85cpu_mem_readbyte( cpustate, 0x1f );
|
||||
case SM8500_P0C: return sm85cpu_mem_readbyte( cpustate, 0x20 );
|
||||
case SM8500_P1C: return sm85cpu_mem_readbyte( cpustate, 0x21 );
|
||||
case SM8500_P2C: return sm85cpu_mem_readbyte( cpustate, 0x22 );
|
||||
case SM8500_P3C: return sm85cpu_mem_readbyte( cpustate, 0x23 );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sm8500_set_reg( sm8500_state *cpustate, int regnum, unsigned val )
|
||||
{
|
||||
switch( regnum )
|
||||
{
|
||||
case STATE_GENPC:
|
||||
case SM8500_PC: cpustate->PC = val; break;
|
||||
case STATE_GENSP:
|
||||
case SM8500_SP: cpustate->SP = val; cpustate->program->write_byte(0x1d, val&0xff); if (cpustate->SYS&0x40) cpustate->program->write_byte(0x1c, val>>8); break;
|
||||
case SM8500_PS: sm85cpu_mem_writeword( cpustate, 0x1e, val); break;
|
||||
case SM8500_SYS16: val&=0xff; sm85cpu_mem_writebyte( cpustate, 0x19, val); break;
|
||||
case SM8500_RR0: sm85cpu_mem_writeword( cpustate, 0x00, val); break;
|
||||
case SM8500_RR2: sm85cpu_mem_writeword( cpustate, 0x02, val); break;
|
||||
case SM8500_RR4: sm85cpu_mem_writeword( cpustate, 0x04, val); break;
|
||||
case SM8500_RR6: sm85cpu_mem_writeword( cpustate, 0x06, val); break;
|
||||
case SM8500_RR8: sm85cpu_mem_writeword( cpustate, 0x08, val); break;
|
||||
case SM8500_RR10: sm85cpu_mem_writeword( cpustate, 0x0A, val); break;
|
||||
case SM8500_RR12: sm85cpu_mem_writeword( cpustate, 0x0C, val); break;
|
||||
case SM8500_RR14: sm85cpu_mem_writeword( cpustate, 0x0E, val); break;
|
||||
case SM8500_IE0: sm85cpu_mem_writebyte( cpustate, 0x10, val); break;
|
||||
case SM8500_IE1: sm85cpu_mem_writebyte( cpustate, 0x11, val); break;
|
||||
case SM8500_IR0: sm85cpu_mem_writebyte( cpustate, 0x12, val); break;
|
||||
case SM8500_IR1: sm85cpu_mem_writebyte( cpustate, 0x13, val); break;
|
||||
case SM8500_P0: sm85cpu_mem_writebyte( cpustate, 0x14, val); break;
|
||||
case SM8500_P1: sm85cpu_mem_writebyte( cpustate, 0x15, val); break;
|
||||
case SM8500_P2: sm85cpu_mem_writebyte( cpustate, 0x16, val); break;
|
||||
case SM8500_P3: sm85cpu_mem_writebyte( cpustate, 0x17, val); break;
|
||||
case SM8500_SYS: sm85cpu_mem_writebyte( cpustate, 0x19, val); break;
|
||||
case SM8500_CKC: sm85cpu_mem_writebyte( cpustate, 0x1a, val); if ( val & 0x80 ) { cpustate->clock_changed = 1; }; break;
|
||||
case SM8500_SPH: sm85cpu_mem_writebyte( cpustate, 0x1c, val); break;
|
||||
case SM8500_SPL: sm85cpu_mem_writebyte( cpustate, 0x1d, val); break;
|
||||
case SM8500_PS0: sm85cpu_mem_writebyte( cpustate, 0x1e, val); break;
|
||||
case SM8500_PS1: sm85cpu_mem_writebyte( cpustate, 0x1f, val); break;
|
||||
case SM8500_P0C: sm85cpu_mem_writebyte( cpustate, 0x20, val); break;
|
||||
case SM8500_P1C: sm85cpu_mem_writebyte( cpustate, 0x21, val); break;
|
||||
case SM8500_P2C: sm85cpu_mem_writebyte( cpustate, 0x22, val); break;
|
||||
case SM8500_P3C: sm85cpu_mem_writebyte( cpustate, 0x23, val); break;
|
||||
}
|
||||
}
|
||||
|
||||
static void sm8500_set_irq_line( sm8500_state *cpustate, int irqline, int state )
|
||||
{
|
||||
cpustate->IR0 = cpustate->program->read_byte(0x12);
|
||||
cpustate->IR1 = cpustate->program->read_byte(0x13);
|
||||
if ( state == ASSERT_LINE ) {
|
||||
cpustate->IFLAGS |= ( 0x01 << irqline );
|
||||
cpustate->CheckInterrupts = 1;
|
||||
switch( irqline ) {
|
||||
case DMA_INT: cpustate->IR0 |= 0x80; break;
|
||||
case TIM0_INT: cpustate->IR0 |= 0x40; break;
|
||||
case EXT_INT: cpustate->IR0 |= 0x10; break;
|
||||
case UART_INT: cpustate->IR0 |= 0x08; break;
|
||||
case LCDC_INT: cpustate->IR0 |= 0x01; break;
|
||||
case TIM1_INT: cpustate->IR1 |= 0x40; break;
|
||||
case CK_INT: cpustate->IR1 |= 0x10; break;
|
||||
case PIO_INT: cpustate->IR1 |= 0x04; break;
|
||||
}
|
||||
} else {
|
||||
cpustate->IFLAGS &= ~( 0x01 << irqline );
|
||||
switch( irqline ) {
|
||||
case DMA_INT: cpustate->IR0 &= ~0x80; break;
|
||||
case TIM0_INT: cpustate->IR0 &= ~0x40; break;
|
||||
case EXT_INT: cpustate->IR0 &= ~0x10; break;
|
||||
case UART_INT: cpustate->IR0 &= ~0x08; break;
|
||||
case LCDC_INT: cpustate->IR0 &= ~0x01; break;
|
||||
case TIM1_INT: cpustate->IR1 &= ~0x40; break;
|
||||
case CK_INT: cpustate->IR1 &= ~0x10; break;
|
||||
case PIO_INT: cpustate->IR1 &= ~0x04; break;
|
||||
}
|
||||
if ( 0 == cpustate->IFLAGS ) {
|
||||
cpustate->CheckInterrupts = 0;
|
||||
m_IFLAGS |= ( 0x01 << inptnum );
|
||||
m_CheckInterrupts = 1;
|
||||
switch( inptnum )
|
||||
{
|
||||
case DMA_INT: m_IR0 |= 0x80; break;
|
||||
case TIM0_INT: m_IR0 |= 0x40; break;
|
||||
case EXT_INT: m_IR0 |= 0x10; break;
|
||||
case UART_INT: m_IR0 |= 0x08; break;
|
||||
case LCDC_INT: m_IR0 |= 0x01; break;
|
||||
case TIM1_INT: m_IR1 |= 0x40; break;
|
||||
case CK_INT: m_IR1 |= 0x10; break;
|
||||
case PIO_INT: m_IR1 |= 0x04; break;
|
||||
}
|
||||
}
|
||||
cpustate->program->write_byte(0x12, cpustate->IR0);
|
||||
cpustate->program->write_byte(0x13, cpustate->IR1);
|
||||
}
|
||||
|
||||
static CPU_SET_INFO( sm8500 )
|
||||
{
|
||||
sm8500_state *cpustate = get_safe_token(device);
|
||||
|
||||
switch(state)
|
||||
else
|
||||
{
|
||||
case CPUINFO_INT_INPUT_STATE + 0:
|
||||
case CPUINFO_INT_INPUT_STATE + 1:
|
||||
case CPUINFO_INT_INPUT_STATE + 2:
|
||||
case CPUINFO_INT_INPUT_STATE + 3:
|
||||
case CPUINFO_INT_INPUT_STATE + 4:
|
||||
case CPUINFO_INT_INPUT_STATE + 5:
|
||||
case CPUINFO_INT_INPUT_STATE + 6:
|
||||
case CPUINFO_INT_INPUT_STATE + 7:
|
||||
case CPUINFO_INT_INPUT_STATE + 8:
|
||||
case CPUINFO_INT_INPUT_STATE + 9:
|
||||
case CPUINFO_INT_INPUT_STATE + 10:
|
||||
sm8500_set_irq_line( cpustate, state - CPUINFO_INT_INPUT_STATE, info->i ); break;
|
||||
|
||||
case CPUINFO_INT_REGISTER + SM8500_RR0:
|
||||
case CPUINFO_INT_REGISTER + SM8500_RR2:
|
||||
case CPUINFO_INT_REGISTER + SM8500_RR4:
|
||||
case CPUINFO_INT_REGISTER + SM8500_RR6:
|
||||
case CPUINFO_INT_REGISTER + SM8500_RR8:
|
||||
case CPUINFO_INT_REGISTER + SM8500_RR10:
|
||||
case CPUINFO_INT_REGISTER + SM8500_RR12:
|
||||
case CPUINFO_INT_REGISTER + SM8500_RR14:
|
||||
case CPUINFO_INT_REGISTER + SM8500_PC:
|
||||
case CPUINFO_INT_REGISTER + SM8500_SP:
|
||||
case CPUINFO_INT_REGISTER + SM8500_PS:
|
||||
case CPUINFO_INT_REGISTER + SM8500_SYS16:
|
||||
case CPUINFO_INT_REGISTER + SM8500_SYS:
|
||||
case CPUINFO_INT_REGISTER + SM8500_IE0:
|
||||
case CPUINFO_INT_REGISTER + SM8500_IE1:
|
||||
case CPUINFO_INT_REGISTER + SM8500_IR0:
|
||||
case CPUINFO_INT_REGISTER + SM8500_IR1:
|
||||
case CPUINFO_INT_REGISTER + SM8500_P0:
|
||||
case CPUINFO_INT_REGISTER + SM8500_P1:
|
||||
case CPUINFO_INT_REGISTER + SM8500_P2:
|
||||
case CPUINFO_INT_REGISTER + SM8500_P3:
|
||||
case CPUINFO_INT_REGISTER + SM8500_CKC:
|
||||
case CPUINFO_INT_REGISTER + SM8500_SPH:
|
||||
case CPUINFO_INT_REGISTER + SM8500_SPL:
|
||||
case CPUINFO_INT_REGISTER + SM8500_PS0:
|
||||
case CPUINFO_INT_REGISTER + SM8500_PS1:
|
||||
case CPUINFO_INT_REGISTER + SM8500_P0C:
|
||||
case CPUINFO_INT_REGISTER + SM8500_P1C:
|
||||
case CPUINFO_INT_REGISTER + SM8500_P2C:
|
||||
case CPUINFO_INT_REGISTER + SM8500_P3C:
|
||||
sm8500_set_reg( cpustate, state - CPUINFO_INT_REGISTER, info->i ); break;
|
||||
|
||||
m_IFLAGS &= ~( 0x01 << inptnum );
|
||||
switch( inptnum )
|
||||
{
|
||||
case DMA_INT: m_IR0 &= ~0x80; break;
|
||||
case TIM0_INT: m_IR0 &= ~0x40; break;
|
||||
case EXT_INT: m_IR0 &= ~0x10; break;
|
||||
case UART_INT: m_IR0 &= ~0x08; break;
|
||||
case LCDC_INT: m_IR0 &= ~0x01; break;
|
||||
case TIM1_INT: m_IR1 &= ~0x40; break;
|
||||
case CK_INT: m_IR1 &= ~0x10; break;
|
||||
case PIO_INT: m_IR1 &= ~0x04; break;
|
||||
}
|
||||
if ( 0 == m_IFLAGS )
|
||||
{
|
||||
m_CheckInterrupts = 0;
|
||||
}
|
||||
}
|
||||
m_program->write_byte(0x12, m_IR0);
|
||||
m_program->write_byte(0x13, m_IR1);
|
||||
}
|
||||
|
||||
CPU_GET_INFO( sm8500 )
|
||||
{
|
||||
sm8500_state *cpustate = (device != NULL && device->token() != NULL) ? get_safe_token(device) : NULL;
|
||||
|
||||
switch(state)
|
||||
{
|
||||
case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(sm8500_state); break;
|
||||
case CPUINFO_INT_INPUT_LINES: info->i = 8; break;
|
||||
case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0xff; break;
|
||||
case CPUINFO_INT_ENDIANNESS: info->i = ENDIANNESS_BIG; break;
|
||||
case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break;
|
||||
case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break;
|
||||
case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 1; break;
|
||||
case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 5; break;
|
||||
case CPUINFO_INT_MIN_CYCLES: info->i = 1; break;
|
||||
case CPUINFO_INT_MAX_CYCLES: info->i = 16; break;
|
||||
case CPUINFO_INT_DATABUS_WIDTH + AS_PROGRAM: info->i = 8; break;
|
||||
case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 16; break;
|
||||
case CPUINFO_INT_ADDRBUS_SHIFT + AS_PROGRAM: info->i = 0; break;
|
||||
case CPUINFO_INT_DATABUS_WIDTH + AS_DATA: info->i = 0; break;
|
||||
case CPUINFO_INT_ADDRBUS_WIDTH + AS_DATA: info->i = 0; break;
|
||||
case CPUINFO_INT_ADDRBUS_SHIFT + AS_DATA: info->i = 0; break;
|
||||
case CPUINFO_INT_DATABUS_WIDTH + AS_IO: info->i = 0; break;
|
||||
case CPUINFO_INT_ADDRBUS_WIDTH + AS_IO: info->i = 0; break;
|
||||
case CPUINFO_INT_ADDRBUS_SHIFT + AS_IO: info->i = 0; break;
|
||||
case CPUINFO_INT_INPUT_STATE + 0:
|
||||
case CPUINFO_INT_INPUT_STATE + 1:
|
||||
case CPUINFO_INT_INPUT_STATE + 2:
|
||||
case CPUINFO_INT_INPUT_STATE + 3:
|
||||
case CPUINFO_INT_INPUT_STATE + 4:
|
||||
case CPUINFO_INT_INPUT_STATE + 5:
|
||||
case CPUINFO_INT_INPUT_STATE + 6:
|
||||
case CPUINFO_INT_INPUT_STATE + 7:
|
||||
case CPUINFO_INT_INPUT_STATE + 8:
|
||||
case CPUINFO_INT_INPUT_STATE + 9:
|
||||
case CPUINFO_INT_INPUT_STATE + 10: info->i = cpustate->IFLAGS & ( 1 << (state - CPUINFO_INT_INPUT_STATE)); break;
|
||||
case CPUINFO_INT_REGISTER + SM8500_RR0:
|
||||
case CPUINFO_INT_REGISTER + SM8500_RR2:
|
||||
case CPUINFO_INT_REGISTER + SM8500_RR4:
|
||||
case CPUINFO_INT_REGISTER + SM8500_RR6:
|
||||
case CPUINFO_INT_REGISTER + SM8500_RR8:
|
||||
case CPUINFO_INT_REGISTER + SM8500_RR10:
|
||||
case CPUINFO_INT_REGISTER + SM8500_RR12:
|
||||
case CPUINFO_INT_REGISTER + SM8500_RR14:
|
||||
case CPUINFO_INT_REGISTER + SM8500_PC:
|
||||
case CPUINFO_INT_REGISTER + SM8500_SP:
|
||||
case CPUINFO_INT_REGISTER + SM8500_PS:
|
||||
case CPUINFO_INT_REGISTER + SM8500_SYS16:
|
||||
case CPUINFO_INT_REGISTER + SM8500_SYS:
|
||||
case CPUINFO_INT_REGISTER + SM8500_IE0:
|
||||
case CPUINFO_INT_REGISTER + SM8500_IE1:
|
||||
case CPUINFO_INT_REGISTER + SM8500_IR0:
|
||||
case CPUINFO_INT_REGISTER + SM8500_IR1:
|
||||
case CPUINFO_INT_REGISTER + SM8500_P0:
|
||||
case CPUINFO_INT_REGISTER + SM8500_P1:
|
||||
case CPUINFO_INT_REGISTER + SM8500_P2:
|
||||
case CPUINFO_INT_REGISTER + SM8500_P3:
|
||||
case CPUINFO_INT_REGISTER + SM8500_CKC:
|
||||
case CPUINFO_INT_REGISTER + SM8500_SPH:
|
||||
case CPUINFO_INT_REGISTER + SM8500_SPL:
|
||||
case CPUINFO_INT_REGISTER + SM8500_PS0:
|
||||
case CPUINFO_INT_REGISTER + SM8500_PS1:
|
||||
case CPUINFO_INT_REGISTER + SM8500_P0C:
|
||||
case CPUINFO_INT_REGISTER + SM8500_P1C:
|
||||
case CPUINFO_INT_REGISTER + SM8500_P2C:
|
||||
case CPUINFO_INT_REGISTER + SM8500_P3C:
|
||||
info->i = sm8500_get_reg( cpustate, state - CPUINFO_INT_REGISTER ); break;
|
||||
case CPUINFO_INT_REGISTER + STATE_GENPC: info->i = sm8500_get_reg( cpustate, SM8500_PC ); break;
|
||||
case CPUINFO_INT_REGISTER + STATE_GENSP: info->i = sm8500_get_reg( cpustate, SM8500_SP ); break;
|
||||
case CPUINFO_INT_PREVIOUSPC: info->i = cpustate->oldpc; break;
|
||||
|
||||
|
||||
case CPUINFO_FCT_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(sm8500); break;
|
||||
case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(sm8500); break;
|
||||
case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(sm8500); break;
|
||||
case CPUINFO_FCT_EXIT: info->exit = CPU_EXIT_NAME(sm8500); break;
|
||||
case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(sm8500); break;
|
||||
case CPUINFO_FCT_BURN: info->burn = CPU_BURN_NAME(sm8500); break;
|
||||
case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(sm8500); break;
|
||||
case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &cpustate->icount; break;
|
||||
|
||||
case CPUINFO_STR_NAME: strcpy( info->s, "sm8500" ); break;
|
||||
case CPUINFO_STR_FAMILY: strcpy( info->s, "Sharp SM8500" ); break;
|
||||
case CPUINFO_STR_VERSION: strcpy( info->s, "0.1" ); break;
|
||||
case CPUINFO_STR_SOURCE_FILE: strcpy( info->s, __FILE__ ); break;
|
||||
case CPUINFO_STR_CREDITS: strcpy( info->s, "Copyright The MESS Team." ); break;
|
||||
case CPUINFO_STR_FLAGS:
|
||||
sprintf( info->s, "%c%c%c%c%c%c%c%c",
|
||||
cpustate->PS1 & FLAG_C ? 'C' : '.',
|
||||
cpustate->PS1 & FLAG_Z ? 'Z' : '.',
|
||||
cpustate->PS1 & FLAG_S ? 'S' : '.',
|
||||
cpustate->PS1 & FLAG_V ? 'V' : '.',
|
||||
cpustate->PS1 & FLAG_D ? 'D' : '.',
|
||||
cpustate->PS1 & FLAG_H ? 'H' : '.',
|
||||
cpustate->PS1 & FLAG_B ? 'B' : '.',
|
||||
cpustate->PS1 & FLAG_I ? 'I' : '.' );
|
||||
break;
|
||||
case CPUINFO_STR_REGISTER + SM8500_RR0: sprintf(info->s, "RR0:%04X", sm85cpu_mem_readword( cpustate, 0x00 ) ); break;
|
||||
case CPUINFO_STR_REGISTER + SM8500_RR2: sprintf(info->s, "RR2:%04X", sm85cpu_mem_readword( cpustate, 0x02 ) ); break;
|
||||
case CPUINFO_STR_REGISTER + SM8500_RR4: sprintf(info->s, "RR4:%04X", sm85cpu_mem_readword( cpustate, 0x04 ) ); break;
|
||||
case CPUINFO_STR_REGISTER + SM8500_RR6: sprintf(info->s, "RR6:%04X", sm85cpu_mem_readword( cpustate, 0x06 ) ); break;
|
||||
case CPUINFO_STR_REGISTER + SM8500_RR8: sprintf(info->s, "RR8:%04X", sm85cpu_mem_readword( cpustate, 0x08 ) ); break;
|
||||
case CPUINFO_STR_REGISTER + SM8500_RR10: sprintf(info->s, "RR10:%04X", sm85cpu_mem_readword( cpustate, 0x0A ) ); break;
|
||||
case CPUINFO_STR_REGISTER + SM8500_RR12: sprintf(info->s, "RR12:%04X", sm85cpu_mem_readword( cpustate, 0x0C ) ); break;
|
||||
case CPUINFO_STR_REGISTER + SM8500_RR14: sprintf(info->s, "RR14:%04X", sm85cpu_mem_readword( cpustate, 0x0E ) ); break;
|
||||
case CPUINFO_STR_REGISTER + SM8500_PC: sprintf(info->s, "PC:%04X", cpustate->PC); break;
|
||||
case CPUINFO_STR_REGISTER + SM8500_SP: sprintf(info->s, "SP:%04X", cpustate->SP); break;
|
||||
case CPUINFO_STR_REGISTER + SM8500_PS: sprintf(info->s, "PS:%04X", ( cpustate->PS0 << 8 ) | cpustate->PS1 ); break;
|
||||
case CPUINFO_STR_REGISTER + SM8500_SYS16: sprintf(info->s, "SYS:%02X", cpustate->SYS ); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DEFINE_LEGACY_CPU_DEVICE(SM8500, sm8500);
|
||||
|
@ -3,24 +3,13 @@
|
||||
#ifndef __SM8500_H__
|
||||
#define __SM8500_H__
|
||||
|
||||
#define MCFG_SM8500_DMA_CB(_devcb) \
|
||||
sm8500_cpu_device::set_dma_cb(*device, DEVCB2_##_devcb); \
|
||||
|
||||
struct SM8500_CONFIG {
|
||||
void (*handle_dma)(device_t *device, int cycles);
|
||||
void (*handle_timers)(device_t *device, int cycles);
|
||||
};
|
||||
|
||||
/* interrupts */
|
||||
#define ILL_INT 0
|
||||
#define DMA_INT 1
|
||||
#define TIM0_INT 2
|
||||
#define EXT_INT 3
|
||||
#define UART_INT 4
|
||||
#define LCDC_INT 5
|
||||
#define TIM1_INT 6
|
||||
#define CK_INT 7
|
||||
#define PIO_INT 8
|
||||
#define WDT_INT 9
|
||||
#define NMI_INT 10
|
||||
#define MCFG_SM8500_TIMER_CB(_devcb) \
|
||||
sm8500_cpu_device::set_timer_cb(*device, DEVCB2_##_devcb); \
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
@ -32,8 +21,98 @@ enum
|
||||
SM8500_SPH, SM8500_SPL, SM8500_PS0, SM8500_PS1, SM8500_P0C, SM8500_P1C, SM8500_P2C, SM8500_P3C,
|
||||
};
|
||||
|
||||
DECLARE_LEGACY_CPU_DEVICE(SM8500, sm8500);
|
||||
|
||||
extern CPU_DISASSEMBLE( sm8500 );
|
||||
class sm8500_cpu_device : public cpu_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
sm8500_cpu_device(const machine_config &mconfig, const char *_tag, device_t *_owner, UINT32 _clock);
|
||||
|
||||
// static configuration helpers
|
||||
template<class _Object> static devcb2_base &set_dma_cb(device_t &device, _Object object) { return downcast<sm8500_cpu_device &>(device).m_dma_func.set_callback(object); }
|
||||
template<class _Object> static devcb2_base &set_timer_cb(device_t &device, _Object object) { return downcast<sm8500_cpu_device &>(device).m_timer_func.set_callback(object); }
|
||||
|
||||
/* interrupts */
|
||||
static const int ILL_INT = 0;
|
||||
static const int DMA_INT = 1;
|
||||
static const int TIM0_INT = 2;
|
||||
static const int EXT_INT = 3;
|
||||
static const int UART_INT = 4;
|
||||
static const int LCDC_INT = 5;
|
||||
static const int TIM1_INT = 6;
|
||||
static const int CK_INT = 7;
|
||||
static const int PIO_INT = 8;
|
||||
static const int WDT_INT = 9;
|
||||
static const int NMI_INT = 10;
|
||||
|
||||
protected:
|
||||
// Flags
|
||||
static const UINT8 FLAG_C = 0x80;
|
||||
static const UINT8 FLAG_Z = 0x40;
|
||||
static const UINT8 FLAG_S = 0x20;
|
||||
static const UINT8 FLAG_V = 0x10;
|
||||
static const UINT8 FLAG_D = 0x08;
|
||||
static const UINT8 FLAG_H = 0x04;
|
||||
static const UINT8 FLAG_B = 0x02;
|
||||
static const UINT8 FLAG_I = 0x01;
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
// device_execute_interface overrides
|
||||
virtual UINT32 execute_min_cycles() const { return 1; }
|
||||
virtual UINT32 execute_max_cycles() const { return 16; }
|
||||
virtual UINT32 execute_input_lines() const { return 11; }
|
||||
virtual void execute_run();
|
||||
virtual void execute_set_input(int inputnum, int state);
|
||||
|
||||
// device_memory_interface overrides
|
||||
virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const { return (spacenum == AS_PROGRAM) ? &m_program_config : NULL; }
|
||||
|
||||
// device_state_interface overrides
|
||||
void state_string_export(const device_state_entry &entry, astring &string);
|
||||
|
||||
// device_disasm_interface overrides
|
||||
virtual UINT32 disasm_min_opcode_bytes() const { return 1; }
|
||||
virtual UINT32 disasm_max_opcode_bytes() const { return 5; }
|
||||
virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
|
||||
|
||||
inline void get_sp();
|
||||
inline UINT8 mem_readbyte(UINT32 offset);
|
||||
inline void mem_writebyte(UINT32 offset, UINT8 data);
|
||||
inline UINT16 mem_readword(UINT32 address) { return (mem_readbyte(address ) << 8) | (mem_readbyte(address+1)); }
|
||||
inline void mem_writeword(UINT32 address, UINT16 value) { mem_writebyte(address, value >> 8); mem_writebyte(address+1, value); }
|
||||
inline void take_interrupt(UINT16 vector);
|
||||
void process_interrupts();
|
||||
|
||||
address_space_config m_program_config;
|
||||
|
||||
devcb2_write8 m_dma_func;
|
||||
devcb2_write8 m_timer_func;
|
||||
|
||||
UINT16 m_PC;
|
||||
UINT8 m_IE0;
|
||||
UINT8 m_IE1;
|
||||
UINT8 m_IR0;
|
||||
UINT8 m_IR1;
|
||||
UINT8 m_SYS;
|
||||
UINT8 m_CKC;
|
||||
UINT8 m_clock_changed;
|
||||
UINT16 m_SP;
|
||||
UINT8 m_PS0;
|
||||
UINT8 m_PS1;
|
||||
UINT16 m_IFLAGS;
|
||||
UINT8 m_CheckInterrupts;
|
||||
int m_halted;
|
||||
int m_icount;
|
||||
address_space *m_program;
|
||||
UINT16 m_oldpc;
|
||||
UINT8 m_register_ram[0x108];
|
||||
};
|
||||
|
||||
|
||||
extern const device_type SM8500;
|
||||
|
||||
|
||||
#endif /* __SM8500_H__ */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -33,11 +33,6 @@ static ADDRESS_MAP_START(gamecom_mem_map, AS_PROGRAM, 8, gamecom_state)
|
||||
AM_RANGE( 0xE000, 0xFFFF ) AM_RAM AM_SHARE("p_nvram")// AM_SHARE("nvram") /* Extended I/O, Extended RAM */
|
||||
ADDRESS_MAP_END
|
||||
|
||||
static const SM8500_CONFIG gamecom_cpu_config = {
|
||||
gamecom_handle_dma,
|
||||
gamecom_update_timers
|
||||
};
|
||||
|
||||
static INPUT_PORTS_START( gamecom )
|
||||
PORT_START("IN0")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_NAME( "Up" )
|
||||
@ -91,14 +86,15 @@ UINT32 gamecom_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap,
|
||||
|
||||
INTERRUPT_GEN_MEMBER(gamecom_state::gamecom_interrupt)
|
||||
{
|
||||
m_maincpu->set_input_line(LCDC_INT, ASSERT_LINE );
|
||||
m_maincpu->set_input_line(sm8500_cpu_device::LCDC_INT, ASSERT_LINE );
|
||||
}
|
||||
|
||||
static MACHINE_CONFIG_START( gamecom, gamecom_state )
|
||||
/* basic machine hardware */
|
||||
MCFG_CPU_ADD( "maincpu", SM8500, XTAL_11_0592MHz/2 ) /* actually it's an sm8521 microcontroller containing an sm8500 cpu */
|
||||
MCFG_CPU_PROGRAM_MAP( gamecom_mem_map)
|
||||
MCFG_CPU_CONFIG( gamecom_cpu_config )
|
||||
MCFG_SM8500_DMA_CB( WRITE8( gamecom_state, gamecom_handle_dma ) )
|
||||
MCFG_SM8500_TIMER_CB( WRITE8( gamecom_state, gamecom_update_timers ) )
|
||||
MCFG_CPU_VBLANK_INT_DRIVER("screen", gamecom_state, gamecom_interrupt)
|
||||
|
||||
MCFG_QUANTUM_TIME(attotime::from_hz(60))
|
||||
|
@ -258,6 +258,8 @@ public:
|
||||
INTERRUPT_GEN_MEMBER(gamecom_interrupt);
|
||||
TIMER_CALLBACK_MEMBER(gamecom_clock_timer_callback);
|
||||
TIMER_CALLBACK_MEMBER(gamecom_scanline);
|
||||
DECLARE_WRITE8_MEMBER( gamecom_handle_dma );
|
||||
DECLARE_WRITE8_MEMBER( gamecom_update_timers );
|
||||
|
||||
protected:
|
||||
required_memory_bank m_bank1;
|
||||
@ -279,7 +281,4 @@ protected:
|
||||
extern DEVICE_IMAGE_LOAD( gamecom_cart1 );
|
||||
extern DEVICE_IMAGE_LOAD( gamecom_cart2 );
|
||||
|
||||
extern void gamecom_handle_dma( device_t *device, int cycles );
|
||||
extern void gamecom_update_timers( device_t *device, int cycles );
|
||||
|
||||
#endif /* GAMECOM_H_ */
|
||||
|
@ -10,7 +10,7 @@ TIMER_CALLBACK_MEMBER(gamecom_state::gamecom_clock_timer_callback)
|
||||
UINT8 * RAM = m_region_maincpu->base();
|
||||
UINT8 val = ( ( RAM[SM8521_CLKT] & 0x3F ) + 1 ) & 0x3F;
|
||||
RAM[SM8521_CLKT] = ( RAM[SM8521_CLKT] & 0xC0 ) | val;
|
||||
m_maincpu->set_input_line(CK_INT, ASSERT_LINE );
|
||||
m_maincpu->set_input_line(sm8500_cpu_device::CK_INT, ASSERT_LINE );
|
||||
}
|
||||
|
||||
void gamecom_state::machine_reset()
|
||||
@ -353,194 +353,202 @@ WRITE8_MEMBER( gamecom_state::gamecom_internal_w )
|
||||
Their usage is also not explained properly in the manuals. Guess we'll have to wait
|
||||
for them to show up in some rom images...
|
||||
*/
|
||||
void gamecom_handle_dma( device_t *device, int cycles )
|
||||
WRITE8_MEMBER( gamecom_state::gamecom_handle_dma )
|
||||
{
|
||||
gamecom_state *state = device->machine().driver_data<gamecom_state>();
|
||||
UINT8 * RAM = state->memregion("maincpu")->base();
|
||||
UINT8 data = RAM[SM8521_DMC];
|
||||
state->m_dma.overwrite_mode = data & 0x01;
|
||||
state->m_dma.transfer_mode = data & 0x06;
|
||||
state->m_dma.decrement_x = data & 0x08;
|
||||
state->m_dma.decrement_y = data & 0x10;
|
||||
state->m_dma.enabled = data & 0x80;
|
||||
if ( !state->m_dma.enabled ) return;
|
||||
UINT8 * RAM = m_region_maincpu->base();
|
||||
UINT8 dmc = RAM[SM8521_DMC];
|
||||
m_dma.overwrite_mode = dmc & 0x01;
|
||||
m_dma.transfer_mode = dmc & 0x06;
|
||||
m_dma.decrement_x = dmc & 0x08;
|
||||
m_dma.decrement_y = dmc & 0x10;
|
||||
m_dma.enabled = dmc & 0x80;
|
||||
if ( !m_dma.enabled )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_dma.decrement_x || m_dma.decrement_y )
|
||||
{
|
||||
popmessage( "TODO: Decrement-x and decrement-y are not supported yet\n" );
|
||||
}
|
||||
|
||||
if ( state->m_dma.decrement_x || state->m_dma.decrement_y )
|
||||
logerror( "TODO: Decrement-x and decrement-y are not supported yet\n" );
|
||||
|
||||
state->m_dma.width_x = RAM[SM8521_DMDX];
|
||||
state->m_dma.width_x_count = 0;
|
||||
state->m_dma.width_y = RAM[SM8521_DMDY];
|
||||
state->m_dma.width_y_count = 0;
|
||||
state->m_dma.source_x = RAM[SM8521_DMX1];
|
||||
state->m_dma.source_x_current = state->m_dma.source_x;
|
||||
state->m_dma.source_y = RAM[SM8521_DMY1];
|
||||
state->m_dma.source_width = ( RAM[SM8521_LCH] & 0x20 ) ? 50 : 40;
|
||||
state->m_dma.dest_x = RAM[SM8521_DMX2];
|
||||
state->m_dma.dest_x_current = state->m_dma.dest_x;
|
||||
state->m_dma.dest_y = RAM[SM8521_DMY2];
|
||||
state->m_dma.dest_width = ( RAM[SM8521_LCH] & 0x20 ) ? 50 : 40;
|
||||
state->m_dma.palette[0] = RAM[SM8521_DMPL] & 0x03;
|
||||
state->m_dma.palette[1] = ( RAM[SM8521_DMPL] >> 2 ) & 3;
|
||||
state->m_dma.palette[2] = ( RAM[SM8521_DMPL] >> 4 ) & 3;
|
||||
state->m_dma.palette[3] = RAM[SM8521_DMPL] >> 6;
|
||||
state->m_dma.source_mask = 0x1FFF;
|
||||
state->m_dma.dest_mask = 0x1FFF;
|
||||
// logerror("DMA: width %Xx%X, source (%X,%X), dest (%X,%X), transfer_mode %X, banks %X \n", state->m_dma.width_x, state->m_dma.width_y, state->m_dma.source_x, state->m_dma.source_y, state->m_dma.dest_x, state->m_dma.dest_y, state->m_dma.transfer_mode, RAM[SM8521_DMVP] );
|
||||
// logerror( " Palette: %d, %d, %d, %d\n", state->m_dma.palette[0], state->m_dma.palette[1], state->m_dma.palette[2], state->m_dma.palette[3] );
|
||||
switch( state->m_dma.transfer_mode )
|
||||
m_dma.width_x = RAM[SM8521_DMDX];
|
||||
m_dma.width_x_count = 0;
|
||||
m_dma.width_y = RAM[SM8521_DMDY];
|
||||
m_dma.width_y_count = 0;
|
||||
m_dma.source_x = RAM[SM8521_DMX1];
|
||||
m_dma.source_x_current = m_dma.source_x;
|
||||
m_dma.source_y = RAM[SM8521_DMY1];
|
||||
m_dma.source_width = ( RAM[SM8521_LCH] & 0x20 ) ? 50 : 40;
|
||||
m_dma.dest_x = RAM[SM8521_DMX2];
|
||||
m_dma.dest_x_current = m_dma.dest_x;
|
||||
m_dma.dest_y = RAM[SM8521_DMY2];
|
||||
m_dma.dest_width = ( RAM[SM8521_LCH] & 0x20 ) ? 50 : 40;
|
||||
m_dma.palette[0] = RAM[SM8521_DMPL] & 0x03;
|
||||
m_dma.palette[1] = ( RAM[SM8521_DMPL] >> 2 ) & 3;
|
||||
m_dma.palette[2] = ( RAM[SM8521_DMPL] >> 4 ) & 3;
|
||||
m_dma.palette[3] = RAM[SM8521_DMPL] >> 6;
|
||||
m_dma.source_mask = 0x1FFF;
|
||||
m_dma.dest_mask = 0x1FFF;
|
||||
// logerror("DMA: width %Xx%X, source (%X,%X), dest (%X,%X), transfer_mode %X, banks %X \n", m_dma.width_x, m_dma.width_y, m_dma.source_x, m_dma.source_y, m_dma.dest_x, m_dma.dest_y, m_dma.transfer_mode, RAM[SM8521_DMVP] );
|
||||
// logerror( " Palette: %d, %d, %d, %d\n", m_dma.palette[0], m_dma.palette[1], m_dma.palette[2], m_dma.palette[3] );
|
||||
switch( m_dma.transfer_mode )
|
||||
{
|
||||
case 0x00:
|
||||
/* VRAM->VRAM */
|
||||
state->m_dma.source_bank = &state->m_p_videoram[(RAM[SM8521_DMVP] & 0x01) ? 0x2000 : 0x0000];
|
||||
state->m_dma.dest_bank = &state->m_p_videoram[(RAM[SM8521_DMVP] & 0x02) ? 0x2000 : 0x0000];
|
||||
m_dma.source_bank = &m_p_videoram[(RAM[SM8521_DMVP] & 0x01) ? 0x2000 : 0x0000];
|
||||
m_dma.dest_bank = &m_p_videoram[(RAM[SM8521_DMVP] & 0x02) ? 0x2000 : 0x0000];
|
||||
break;
|
||||
case 0x02:
|
||||
/* ROM->VRAM */
|
||||
// logerror( "DMA DMBR = %X\n", RAM[SM8521_DMBR] );
|
||||
state->m_dma.source_width = 64;
|
||||
state->m_dma.source_mask = 0x3FFF;
|
||||
m_dma.source_width = 64;
|
||||
m_dma.source_mask = 0x3FFF;
|
||||
if ( RAM[SM8521_DMBR] < 16 )
|
||||
state->m_dma.source_bank = state->memregion("kernel")->base() + (RAM[SM8521_DMBR] << 14);
|
||||
{
|
||||
m_dma.source_bank = m_region_kernel->base() + (RAM[SM8521_DMBR] << 14);
|
||||
}
|
||||
else
|
||||
if (state->m_cartridge)
|
||||
state->m_dma.source_bank = state->m_cartridge + (RAM[SM8521_DMBR] << 14);
|
||||
{
|
||||
if (m_cartridge)
|
||||
{
|
||||
m_dma.source_bank = m_cartridge + (RAM[SM8521_DMBR] << 14);
|
||||
}
|
||||
}
|
||||
|
||||
state->m_dma.dest_bank = &state->m_p_videoram[(RAM[SM8521_DMVP] & 0x02) ? 0x2000 : 0x0000];
|
||||
m_dma.dest_bank = &m_p_videoram[(RAM[SM8521_DMVP] & 0x02) ? 0x2000 : 0x0000];
|
||||
break;
|
||||
case 0x04:
|
||||
/* Extend RAM->VRAM */
|
||||
state->m_dma.source_width = 64;
|
||||
state->m_dma.source_bank = &state->m_p_nvram[0x0000];
|
||||
state->m_dma.dest_bank = &state->m_p_videoram[(RAM[SM8521_DMVP] & 0x02) ? 0x2000 : 0x0000];
|
||||
m_dma.source_width = 64;
|
||||
m_dma.source_bank = &m_p_nvram[0x0000];
|
||||
m_dma.dest_bank = &m_p_videoram[(RAM[SM8521_DMVP] & 0x02) ? 0x2000 : 0x0000];
|
||||
break;
|
||||
case 0x06:
|
||||
/* VRAM->Extend RAM */
|
||||
state->m_dma.source_bank = &state->m_p_videoram[(RAM[SM8521_DMVP] & 0x01) ? 0x2000 : 0x0000];
|
||||
state->m_dma.dest_width = 64;
|
||||
state->m_dma.dest_bank = &state->m_p_nvram[0x0000];
|
||||
m_dma.source_bank = &m_p_videoram[(RAM[SM8521_DMVP] & 0x01) ? 0x2000 : 0x0000];
|
||||
m_dma.dest_width = 64;
|
||||
m_dma.dest_bank = &m_p_nvram[0x0000];
|
||||
break;
|
||||
}
|
||||
state->m_dma.source_current = state->m_dma.source_width * state->m_dma.source_y;
|
||||
state->m_dma.source_current += state->m_dma.source_x >> 2;
|
||||
state->m_dma.dest_current = state->m_dma.dest_width * state->m_dma.dest_y;
|
||||
state->m_dma.dest_current += state->m_dma.dest_x >> 2;
|
||||
state->m_dma.source_line = state->m_dma.source_current;
|
||||
state->m_dma.dest_line = state->m_dma.dest_current;
|
||||
state->m_dma.state_count = 0;
|
||||
m_dma.source_current = m_dma.source_width * m_dma.source_y;
|
||||
m_dma.source_current += m_dma.source_x >> 2;
|
||||
m_dma.dest_current = m_dma.dest_width * m_dma.dest_y;
|
||||
m_dma.dest_current += m_dma.dest_x >> 2;
|
||||
m_dma.source_line = m_dma.source_current;
|
||||
m_dma.dest_line = m_dma.dest_current;
|
||||
m_dma.state_count = 0;
|
||||
|
||||
unsigned y_count, x_count;
|
||||
|
||||
for( y_count = 0; y_count <= state->m_dma.width_y; y_count++ )
|
||||
for( y_count = 0; y_count <= m_dma.width_y; y_count++ )
|
||||
{
|
||||
for( x_count = 0; x_count <= state->m_dma.width_x; x_count++ )
|
||||
for( x_count = 0; x_count <= m_dma.width_x; x_count++ )
|
||||
{
|
||||
int source_pixel = 0;
|
||||
int dest_pixel = 0;
|
||||
int src_addr = state->m_dma.source_current & state->m_dma.source_mask;
|
||||
int dest_addr = state->m_dma.dest_current & state->m_dma.dest_mask;
|
||||
int src_addr = m_dma.source_current & m_dma.source_mask;
|
||||
int dest_addr = m_dma.dest_current & m_dma.dest_mask;
|
||||
/* handle DMA for 1 pixel */
|
||||
/* Read pixel data */
|
||||
switch ( state->m_dma.source_x_current & 0x03 )
|
||||
switch ( m_dma.source_x_current & 0x03 )
|
||||
{
|
||||
case 0x00: source_pixel = state->m_dma.source_bank[src_addr] >> 6; break;
|
||||
case 0x01: source_pixel = ( state->m_dma.source_bank[src_addr] >> 4 ) & 3; break;
|
||||
case 0x02: source_pixel = ( state->m_dma.source_bank[src_addr] >> 2 ) & 3; break;
|
||||
case 0x03: source_pixel = state->m_dma.source_bank[src_addr] & 3; break;
|
||||
case 0x00: source_pixel = m_dma.source_bank[src_addr] >> 6; break;
|
||||
case 0x01: source_pixel = ( m_dma.source_bank[src_addr] >> 4 ) & 3; break;
|
||||
case 0x02: source_pixel = ( m_dma.source_bank[src_addr] >> 2 ) & 3; break;
|
||||
case 0x03: source_pixel = m_dma.source_bank[src_addr] & 3; break;
|
||||
}
|
||||
|
||||
if ( !state->m_dma.overwrite_mode && source_pixel == 0 )
|
||||
if ( !m_dma.overwrite_mode && source_pixel == 0 )
|
||||
{
|
||||
switch ( state->m_dma.dest_x_current & 0x03 )
|
||||
switch ( m_dma.dest_x_current & 0x03 )
|
||||
{
|
||||
case 0x00: dest_pixel = state->m_dma.dest_bank[dest_addr] >> 6; break;
|
||||
case 0x01: dest_pixel = ( state->m_dma.dest_bank[dest_addr] >> 4 ) & 3; break;
|
||||
case 0x02: dest_pixel = ( state->m_dma.dest_bank[dest_addr] >> 2 ) & 3; break;
|
||||
case 0x03: dest_pixel = state->m_dma.dest_bank[dest_addr] & 3; break;
|
||||
case 0x00: dest_pixel = m_dma.dest_bank[dest_addr] >> 6; break;
|
||||
case 0x01: dest_pixel = ( m_dma.dest_bank[dest_addr] >> 4 ) & 3; break;
|
||||
case 0x02: dest_pixel = ( m_dma.dest_bank[dest_addr] >> 2 ) & 3; break;
|
||||
case 0x03: dest_pixel = m_dma.dest_bank[dest_addr] & 3; break;
|
||||
}
|
||||
source_pixel = dest_pixel;
|
||||
}
|
||||
|
||||
/* Translate pixel data using DMA palette. */
|
||||
/* Not sure if this should be done before the compound stuff - WP */
|
||||
source_pixel = state->m_dma.palette[ source_pixel ];
|
||||
source_pixel = m_dma.palette[ source_pixel ];
|
||||
/* Write pixel data */
|
||||
switch( state->m_dma.dest_x_current & 0x03 )
|
||||
switch( m_dma.dest_x_current & 0x03 )
|
||||
{
|
||||
case 0x00:
|
||||
state->m_dma.dest_bank[dest_addr] = ( state->m_dma.dest_bank[dest_addr] & 0x3F ) | ( source_pixel << 6 );
|
||||
m_dma.dest_bank[dest_addr] = ( m_dma.dest_bank[dest_addr] & 0x3F ) | ( source_pixel << 6 );
|
||||
break;
|
||||
case 0x01:
|
||||
state->m_dma.dest_bank[dest_addr] = ( state->m_dma.dest_bank[dest_addr] & 0xCF ) | ( source_pixel << 4 );
|
||||
m_dma.dest_bank[dest_addr] = ( m_dma.dest_bank[dest_addr] & 0xCF ) | ( source_pixel << 4 );
|
||||
break;
|
||||
case 0x02:
|
||||
state->m_dma.dest_bank[dest_addr] = ( state->m_dma.dest_bank[dest_addr] & 0xF3 ) | ( source_pixel << 2 );
|
||||
m_dma.dest_bank[dest_addr] = ( m_dma.dest_bank[dest_addr] & 0xF3 ) | ( source_pixel << 2 );
|
||||
break;
|
||||
case 0x03:
|
||||
state->m_dma.dest_bank[dest_addr] = ( state->m_dma.dest_bank[dest_addr] & 0xFC ) | source_pixel;
|
||||
m_dma.dest_bank[dest_addr] = ( m_dma.dest_bank[dest_addr] & 0xFC ) | source_pixel;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Advance a pixel */
|
||||
if ( state->m_dma.decrement_x )
|
||||
if ( m_dma.decrement_x )
|
||||
{
|
||||
state->m_dma.source_x_current--;
|
||||
if ( ( state->m_dma.source_x_current & 0x03 ) == 0x03 )
|
||||
state->m_dma.source_current--;
|
||||
m_dma.source_x_current--;
|
||||
if ( ( m_dma.source_x_current & 0x03 ) == 0x03 )
|
||||
m_dma.source_current--;
|
||||
}
|
||||
else
|
||||
{
|
||||
state->m_dma.source_x_current++;
|
||||
if ( ( state->m_dma.source_x_current & 0x03 ) == 0x00 )
|
||||
state->m_dma.source_current++;
|
||||
m_dma.source_x_current++;
|
||||
if ( ( m_dma.source_x_current & 0x03 ) == 0x00 )
|
||||
m_dma.source_current++;
|
||||
}
|
||||
state->m_dma.dest_x_current++;
|
||||
if ( ( state->m_dma.dest_x_current & 0x03 ) == 0x00 )
|
||||
state->m_dma.dest_current++;
|
||||
m_dma.dest_x_current++;
|
||||
if ( ( m_dma.dest_x_current & 0x03 ) == 0x00 )
|
||||
m_dma.dest_current++;
|
||||
}
|
||||
|
||||
/* Advance a line */
|
||||
state->m_dma.source_x_current = state->m_dma.source_x;
|
||||
state->m_dma.dest_x_current = state->m_dma.dest_x;
|
||||
state->m_dma.source_line += state->m_dma.source_width;
|
||||
state->m_dma.source_current = state->m_dma.source_line;
|
||||
state->m_dma.dest_line += state->m_dma.dest_width;
|
||||
state->m_dma.dest_current = state->m_dma.dest_line;
|
||||
m_dma.source_x_current = m_dma.source_x;
|
||||
m_dma.dest_x_current = m_dma.dest_x;
|
||||
m_dma.source_line += m_dma.source_width;
|
||||
m_dma.source_current = m_dma.source_line;
|
||||
m_dma.dest_line += m_dma.dest_width;
|
||||
m_dma.dest_current = m_dma.dest_line;
|
||||
}
|
||||
state->m_dma.enabled = 0;
|
||||
device->machine().device("maincpu")->execute().set_input_line(DMA_INT, ASSERT_LINE );
|
||||
m_dma.enabled = 0;
|
||||
m_maincpu->set_input_line(sm8500_cpu_device::DMA_INT, ASSERT_LINE );
|
||||
}
|
||||
|
||||
void gamecom_update_timers( device_t *device, int cycles )
|
||||
WRITE8_MEMBER( gamecom_state::gamecom_update_timers )
|
||||
{
|
||||
gamecom_state *state = device->machine().driver_data<gamecom_state>();
|
||||
UINT8 * RAM = state->memregion("maincpu")->base();
|
||||
if ( state->m_timer[0].enabled )
|
||||
UINT8 * RAM = m_region_maincpu->base();
|
||||
if ( m_timer[0].enabled )
|
||||
{
|
||||
state->m_timer[0].state_count += cycles;
|
||||
while ( state->m_timer[0].state_count >= state->m_timer[0].state_limit )
|
||||
m_timer[0].state_count += data;
|
||||
while ( m_timer[0].state_count >= m_timer[0].state_limit )
|
||||
{
|
||||
state->m_timer[0].state_count -= state->m_timer[0].state_limit;
|
||||
m_timer[0].state_count -= m_timer[0].state_limit;
|
||||
RAM[SM8521_TM0D]++;
|
||||
if ( RAM[SM8521_TM0D] >= state->m_timer[0].check_value )
|
||||
if ( RAM[SM8521_TM0D] >= m_timer[0].check_value )
|
||||
{
|
||||
RAM[SM8521_TM0D] = 0;
|
||||
device->machine().device("maincpu")->execute().set_input_line(TIM0_INT, ASSERT_LINE );
|
||||
m_maincpu->set_input_line(sm8500_cpu_device::TIM0_INT, ASSERT_LINE );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( state->m_timer[1].enabled )
|
||||
if ( m_timer[1].enabled )
|
||||
{
|
||||
state->m_timer[1].state_count += cycles;
|
||||
while ( state->m_timer[1].state_count >= state->m_timer[1].state_limit )
|
||||
m_timer[1].state_count += data;
|
||||
while ( m_timer[1].state_count >= m_timer[1].state_limit )
|
||||
{
|
||||
state->m_timer[1].state_count -= state->m_timer[1].state_limit;
|
||||
m_timer[1].state_count -= m_timer[1].state_limit;
|
||||
RAM[SM8521_TM1D]++;
|
||||
if ( RAM[SM8521_TM1D] >= state->m_timer[1].check_value )
|
||||
if ( RAM[SM8521_TM1D] >= m_timer[1].check_value )
|
||||
{
|
||||
RAM[SM8521_TM1D] = 0;
|
||||
device->machine().device("maincpu")->execute().set_input_line(TIM1_INT, ASSERT_LINE );
|
||||
m_maincpu->set_input_line(sm8500_cpu_device::TIM1_INT, ASSERT_LINE );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user