mirror of
https://github.com/holub/mame
synced 2025-04-25 09:50:04 +03:00
-avr8.c: Fixed register indexing for MULSU opcode. [MooglyGuy]
-avr8.c: Fixed register writeback for LD -Z and LD -Y opcodes. [MooglyGuy] -craft.c: Preliminary video support, bad vsync and colors still. [MooglyGuy]
This commit is contained in:
parent
029ef2cd18
commit
002feccb1b
@ -367,6 +367,11 @@ INLINE UINT8 POP(avr8_state *cpustate)
|
||||
return READ_IO_8(cpustate, sp);
|
||||
}
|
||||
|
||||
UINT64 avr8_get_elapsed_cycles(device_t *device)
|
||||
{
|
||||
return get_safe_token(device)->elapsed_cycles;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
// Interrupts
|
||||
|
||||
@ -429,14 +434,6 @@ static void avr8_update_interrupt_internal(avr8_state *cpustate, int source)
|
||||
}
|
||||
}
|
||||
|
||||
/*static void avr8_poll_interrupt(avr8_state *cpustate)
|
||||
{
|
||||
for (int idx = 0; idx < AVR8_INTIDX_COUNT; idx++)
|
||||
{
|
||||
avr8_update_interrupt_internal(cpustate, idx);
|
||||
}
|
||||
}*/
|
||||
|
||||
void avr8_update_interrupt(device_t *device, int source)
|
||||
{
|
||||
avr8_state *cpustate = get_safe_token(device);
|
||||
@ -1036,6 +1033,7 @@ static bool avr8_io_reg_read(avr8_state *cpustate, UINT16 offset, UINT8 *data)
|
||||
case AVR8_REGIDX_TCNT1L:
|
||||
case AVR8_REGIDX_TCNT1H:
|
||||
case AVR8_REGIDX_GPIOR0:
|
||||
case AVR8_REGIDX_TCNT2:
|
||||
*data = cpustate->r[offset];
|
||||
return true;
|
||||
|
||||
@ -1100,6 +1098,8 @@ static CPU_INIT( avr8 )
|
||||
|
||||
cpustate->interrupt_pending = false;
|
||||
|
||||
cpustate->elapsed_cycles = 0;
|
||||
|
||||
device->save_item(NAME(cpustate->pc));
|
||||
}
|
||||
|
||||
@ -1113,6 +1113,7 @@ static CPU_RESET( avr8 )
|
||||
|
||||
cpustate->status = 0;
|
||||
cpustate->pc = 0;
|
||||
cpustate->elapsed_cycles = 0;
|
||||
|
||||
cpustate->interrupt_pending = false;
|
||||
}
|
||||
@ -1160,7 +1161,7 @@ static CPU_EXECUTE( avr8 )
|
||||
opcycles = 2;
|
||||
break;
|
||||
case 0x0300: // MULSU Rd,Rr
|
||||
sd = (INT8)cpustate->r[16 + RD4(op)] * (UINT8)cpustate->r[16 + RR4(op)];
|
||||
sd = (INT8)cpustate->r[16 + RD3(op)] * (UINT8)cpustate->r[16 + RR3(op)];
|
||||
cpustate->r[1] = (sd >> 8) & 0x00ff;
|
||||
cpustate->r[0] = sd & 0x00ff;
|
||||
SREG_W(AVR8_SREG_C, (sd & 0x8000) ? 1 : 0);
|
||||
@ -1393,8 +1394,8 @@ static CPU_EXECUTE( avr8 )
|
||||
pd = ZREG;
|
||||
pd--;
|
||||
cpustate->r[RD5(op)] = READ_IO_8(cpustate, pd);
|
||||
cpustate->r[27] = (pd >> 8) & 0x00ff;
|
||||
cpustate->r[26] = pd & 0x00ff;
|
||||
cpustate->r[31] = (pd >> 8) & 0x00ff;
|
||||
cpustate->r[30] = pd & 0x00ff;
|
||||
opcycles = 2;
|
||||
break;
|
||||
case 0x0004: // LPM Rd,Z
|
||||
@ -1429,8 +1430,8 @@ static CPU_EXECUTE( avr8 )
|
||||
pd = YREG;
|
||||
pd--;
|
||||
cpustate->r[RD5(op)] = READ_IO_8(cpustate, pd);
|
||||
cpustate->r[27] = (pd >> 8) & 0x00ff;
|
||||
cpustate->r[26] = pd & 0x00ff;
|
||||
cpustate->r[29] = (pd >> 8) & 0x00ff;
|
||||
cpustate->r[28] = pd & 0x00ff;
|
||||
opcycles = 2;
|
||||
break;
|
||||
case 0x000c: // LD Rd,X
|
||||
@ -1970,7 +1971,7 @@ static CPU_EXECUTE( avr8 )
|
||||
}
|
||||
else // SBRC Rd, b
|
||||
{
|
||||
if(!BIT(cpustate->r[RD5(op)], RR3(op)))
|
||||
if(NOT(BIT(cpustate->r[RD5(op)], RR3(op))))
|
||||
{
|
||||
op = (UINT32)READ_PRG_16(cpustate, cpustate->pc++);
|
||||
cpustate->pc += avr8_is_long_opcode(op) ? 1 : 0;
|
||||
@ -1986,6 +1987,8 @@ static CPU_EXECUTE( avr8 )
|
||||
|
||||
cpustate->icount -= opcycles;
|
||||
|
||||
cpustate->elapsed_cycles += opcycles;
|
||||
|
||||
avr8_timer_tick(cpustate, opcycles);
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +41,8 @@ struct avr8_state
|
||||
UINT16 timer2_prescale;
|
||||
UINT16 timer2_prescale_count;
|
||||
|
||||
UINT64 elapsed_cycles;
|
||||
|
||||
bool interrupt_pending;
|
||||
};
|
||||
|
||||
@ -301,6 +303,7 @@ DECLARE_LEGACY_CPU_DEVICE(ATMEGA88, atmega88);
|
||||
DECLARE_LEGACY_CPU_DEVICE(ATMEGA644, atmega644);
|
||||
|
||||
void avr8_update_interrupt(device_t *device, int source);
|
||||
UINT64 avr8_get_elapsed_cycles(device_t *device);
|
||||
|
||||
CPU_DISASSEMBLE( avr8 );
|
||||
|
||||
|
@ -29,13 +29,23 @@ INLINE void verboselog(running_machine &machine, int n_level, const char *s_fmt,
|
||||
#define verboselog(x,y,z,...)
|
||||
#endif
|
||||
|
||||
#define MASTER_CLOCK 20000000
|
||||
#define MASTER_CLOCK 20000000
|
||||
|
||||
#define VISIBLE_CYCLES 480
|
||||
#define HSYNC_CYCLES 155
|
||||
#define LINE_CYCLES (VISIBLE_CYCLES + HSYNC_CYCLES)
|
||||
#define VISIBLE_LINES 480
|
||||
#define VSYNC_LINES 45
|
||||
#define LINES_PER_FRAME (VISIBLE_LINES + VSYNC_LINES)
|
||||
#define CYCLES_PER_FRAME (LINES_PER_FRAME * LINE_CYCLES)
|
||||
#define PIXELS_PER_FRAME (CYCLES_PER_FRAME)
|
||||
|
||||
/****************************************************\
|
||||
* I/O defines *
|
||||
\****************************************************/
|
||||
|
||||
#define AVR8_DDRD (state->m_regs[AVR8_REGIDX_DDRD])
|
||||
#define AVR8_PORTC (state->m_regs[AVR8_REGIDX_PORTC])
|
||||
#define AVR8_DDRC (state->m_regs[AVR8_REGIDX_DDRC])
|
||||
#define AVR8_PORTB (state->m_regs[AVR8_REGIDX_PORTB])
|
||||
#define AVR8_DDRB (state->m_regs[AVR8_REGIDX_DDRB])
|
||||
@ -72,6 +82,12 @@ public:
|
||||
|
||||
UINT8 m_regs[0x100];
|
||||
UINT8* m_eeprom;
|
||||
UINT32 last_cycles;
|
||||
|
||||
bool spi_pending;
|
||||
UINT32 spi_start_cycle;
|
||||
|
||||
UINT8 m_pixels[PIXELS_PER_FRAME + LINE_CYCLES]; // Allocate one extra line for wrapping in the video update
|
||||
|
||||
required_device<cpu_device> m_maincpu;
|
||||
|
||||
@ -141,6 +157,38 @@ static void avr8_change_ddr(running_machine &machine, int reg, UINT8 data)
|
||||
}
|
||||
}
|
||||
|
||||
static void avr8_video_update(running_machine &machine)
|
||||
{
|
||||
craft_state *state = machine.driver_data<craft_state>();
|
||||
|
||||
UINT64 cycles = avr8_get_elapsed_cycles(state->m_maincpu);
|
||||
UINT32 frame_cycles = (UINT32)(cycles % CYCLES_PER_FRAME);
|
||||
|
||||
if (state->last_cycles < frame_cycles)
|
||||
{
|
||||
for (UINT32 pixidx = state->last_cycles; pixidx < frame_cycles; pixidx++)
|
||||
{
|
||||
UINT8 value = AVR8_PORTC & 0x3f;
|
||||
if (state->spi_pending)
|
||||
{
|
||||
if (pixidx >= state->spi_start_cycle && pixidx < (state->spi_start_cycle + 16))
|
||||
{
|
||||
UINT8 bitidx = 7 - ((pixidx - state->spi_start_cycle) >> 1);
|
||||
value = ((state->m_regs[AVR8_REGIDX_SPDR] & (1 << bitidx)) ? value : 0x3f);
|
||||
if (pixidx == (state->spi_start_cycle + 15))
|
||||
{
|
||||
state->spi_pending = false;
|
||||
state->m_regs[AVR8_REGIDX_SPDR] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
state->m_pixels[pixidx] = value;
|
||||
}
|
||||
}
|
||||
|
||||
state->last_cycles = frame_cycles;
|
||||
}
|
||||
|
||||
static void avr8_change_port(running_machine &machine, int reg, UINT8 data)
|
||||
{
|
||||
craft_state *state = machine.driver_data<craft_state>();
|
||||
@ -156,7 +204,25 @@ static void avr8_change_port(running_machine &machine, int reg, UINT8 data)
|
||||
//verboselog(machine, 0, "avr8_change_port: PORT%c lines %02x changed\n", avr8_reg_name[reg], changed);
|
||||
}
|
||||
|
||||
if (reg == AVR8_REG_D) {
|
||||
if (reg == AVR8_REG_C)
|
||||
{
|
||||
avr8_video_update(machine);
|
||||
|
||||
/*if (frame_cycles >= state->spi_start_cycle && frame_cycles < (state->spi_start_cycle + 16))
|
||||
{
|
||||
UINT8 bitidx = 7 - ((frame_cycles - state->spi_start_cycle) >> 1);
|
||||
state->m_pixels[frame_cycles] = ((state->m_regs[AVR8_REGIDX_SPDR] & (1 << bitidx)) ? 0x3f : (data & 0x3f));
|
||||
}
|
||||
else
|
||||
{
|
||||
state->m_pixels[frame_cycles] = data & 0x3f;
|
||||
}*/
|
||||
|
||||
AVR8_PORTC = data;
|
||||
}
|
||||
|
||||
if (reg == AVR8_REG_D)
|
||||
{
|
||||
UINT8 audio_sample = (data & 0x02) | ((data & 0xf4) >> 2);
|
||||
|
||||
state->dac->write_unsigned8(audio_sample << 2);
|
||||
@ -289,7 +355,10 @@ WRITE8_MEMBER(craft_state::avr8_write)
|
||||
break;
|
||||
|
||||
case AVR8_REGIDX_SPDR:
|
||||
// TODO
|
||||
avr8_video_update(machine());
|
||||
m_regs[offset] = data;
|
||||
spi_pending = true;
|
||||
spi_start_cycle = (UINT32)(avr8_get_elapsed_cycles(m_maincpu) % CYCLES_PER_FRAME);
|
||||
break;
|
||||
|
||||
case AVR8_REGIDX_EECR:
|
||||
@ -363,6 +432,21 @@ INPUT_PORTS_END
|
||||
|
||||
UINT32 craft_state::screen_update_craft(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
for(int y = 0; y < LINES_PER_FRAME; y++)
|
||||
{
|
||||
UINT32 *line = &bitmap.pix32(y);
|
||||
for(int x = 0; x < LINE_CYCLES; x++)
|
||||
{
|
||||
UINT8 pixel = m_pixels[y * LINE_CYCLES + (x + HSYNC_CYCLES)];
|
||||
UINT8 r = 0x55 * ((pixel & 0x30) >> 4);
|
||||
UINT8 g = 0x55 * ((pixel & 0x0c) >> 2);
|
||||
UINT8 b = 0x55 * (pixel & 0x03);
|
||||
line[x] = 0xff000000 | (r << 16) | (g << 8) | b;
|
||||
|
||||
// Clear behind us
|
||||
m_pixels[y * LINE_CYCLES + (x + HSYNC_CYCLES)] = 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -395,13 +479,11 @@ static MACHINE_CONFIG_START( craft, craft_state )
|
||||
|
||||
/* video hardware */
|
||||
MCFG_SCREEN_ADD("screen", RASTER)
|
||||
//MCFG_SCREEN_RAW_PARAMS( MASTER_CLOCK, 634, 0, 633, 525, 0, 481 )
|
||||
MCFG_SCREEN_REFRESH_RATE(60.08)
|
||||
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(1395)) /* accurate */
|
||||
MCFG_SCREEN_SIZE(634, 480)
|
||||
MCFG_SCREEN_VISIBLE_AREA(0, 633, 0, 479)
|
||||
MCFG_SCREEN_REFRESH_RATE(59.99)
|
||||
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(1429)) /* accurate */
|
||||
MCFG_SCREEN_SIZE(635, 525)
|
||||
MCFG_SCREEN_VISIBLE_AREA(0, 634, 0, 524)
|
||||
MCFG_SCREEN_UPDATE_DRIVER(craft_state, screen_update_craft)
|
||||
|
||||
MCFG_PALETTE_LENGTH(0x1000)
|
||||
|
||||
/* sound hardware */
|
||||
|
Loading…
Reference in New Issue
Block a user