Esempio n. 1
0
void timer_update_cpu(void)
{
	int i;
	float time;
	extern int scanline1;
	extern int scanline2;

	frame_base = 0;
	timer_left = time_slice;

	if (scanline1 != RASTER_LINES) timer_set_raster_interrupt(RASTER_INTERRUPT1, scanline1);
	if (scanline2 != RASTER_LINES) timer_set_raster_interrupt(RASTER_INTERRUPT2, scanline2);
	timer_set_vblank_interrupt();
	(*cps2_build_palette)();

	while (timer_left > 0)
	{
		timer_ticks = timer_left;
		time = base_time + frame_base;
		
		for (i = 0; i < MAX_TIMER; i++)
		{
			if (timer[i].enable)
			{
				if (timer[i].expire - time <= 0)
				{
					timer[i].enable = 0;
					timer[i].callback(timer[i].param);
				}
			}
			if (timer[i].enable)
			{
				if (timer[i].expire - time < timer_ticks)
					timer_ticks = timer[i].expire - time;
			}
		}

		m68000_execute((int)((float)timer_ticks * m68k_cycles));

		if (!z80_suspended)
			z80_execute((int)((float)timer_ticks * z80_cycles));

		frame_base += timer_ticks;
		timer_left -= timer_ticks;
	}

	base_time += time_slice;
	if (base_time >= 1000000.0)
	{
		base_time -= 1000000.0;

		for (i = 0; i < MAX_TIMER; i++)
		{
			if (timer[i].enable)
				timer[i].expire -= 1000000.0;
		}
	}
}
Esempio n. 2
0
/*-------------------------------------------------------------------------

	Audio command callback.

	Input:	Timer		Pointer to the timer that triggered the callback.
			Data		Data associated with the timer.

---------------------------------------------------------------------------*/
void neogeo_audio_command_timer_callback ( TIMER *Timer, Uint32 Data )
{
	Uint32	Z80_Elapsed;

	/* Post the audio command to the Z80 */
	neogeo_audio_command = Data;
	z80_set_irq_line ( INPUT_LINE_NMI, ASSERT_LINE );
	z80_set_irq_line ( INPUT_LINE_NMI, CLEAR_LINE );

	/* Let the Z80 take the command into account */
	Z80_Elapsed = z80_execute ( REF_TO_Z80 ( 2000 ) );
	neogeo_z80_time_to_execute -= Z80_TO_REF ( Z80_Elapsed );
	neogeo_z80_time_this_vbl += Z80_TO_REF ( Z80_Elapsed );
}
Esempio n. 3
0
File: cpu.c Progetto: mnstrmnch/meka
// MAIN EMULATION LOOP (MAME CORE) --------------------------------------------
void    CPU_Loop (void)
{
    for (;;)
    {
        z80_execute (opt.Cur_IPeriod);
        switch (LoopZ80 ())
        {
        case INT_IRQ: break;
        case INT_NMI: z80_set_nmi_line (ASSERT_LINE); z80_set_nmi_line (CLEAR_LINE); break;
        case INT_QUIT: return;
        }
    }
    /* z80_stop_emulating(); */
}
Esempio n. 4
0
/** @brief run the CPU(s) for the next time slice */
void tmr_run_cpu(void *context, double clock)
{
	z80_cpu_t *cpu = (z80_cpu_t *)context;
	tmr_t *slice = tmr_next_event();
	int ran;

	tmr_clock = clock;
	slice = tmr_next_event();
	if (NULL == slice)
		return;
	if (slice->expire <= now)
		cycles = 1;
	else
		cycles = (int)(tmr_time_to_double(slice->expire - now) * clock) - adjust;
#if	0
	z80_dump_state(cpu);
#endif
	ran = z80_execute(cpu);
	cycles_this_frame += ran;
	z80_cc = 0;
	adjust = (ran > cycles) ? ran - cycles : 0;
	tmr_expire(tmr_double_to_time((double)ran / clock));
}
Esempio n. 5
0
File: sms.c Progetto: Cpasjuste/psms
/* Run the virtual console emulation for one frame */
void sms_frame(int skip_render)
{
    /* Take care of hard resets */
    if(input.system & INPUT_HARD_RESET)
    {
        system_reset();
    }

    /* Debounce pause key */
    if(input.system & INPUT_PAUSE)
    {
        if(!sms.paused)
        {
            sms.paused = 1;

            z80_set_nmi_line(ASSERT_LINE);
            z80_set_nmi_line(CLEAR_LINE);
        }
    }
    else
    {
         sms.paused = 0;
    }

    if(snd.log) snd.callback(0x00);

    for(vdp.line = 0; vdp.line < 262; vdp.line += 1)
    {
        /* Handle VDP line events */
        vdp_run();

        /* Draw the current frame */
        if(!skip_render) render_line(vdp.line);

        /* Run the Z80 for a line */
        z80_execute(227);
    }

    /* Update the emulated sound stream */
    if(snd.enabled) 
    {
        int count;

        SN76496Update(0, snd.psg_buffer, snd.bufsize, sms.psg_mask);

        if(sms.use_fm)
        {
            int i;
            for(i = 0; i < snd.bufsize; i++)
            {
                snd.fm_buffer[i] = OPLL_calc(opll);
            }
        }

        for(count = 0; count < snd.bufsize; count += 1)
        {
            signed short left   = 0;
            signed short right  = 0;
            left = right = snd.fm_buffer[count];
            left  += snd.psg_buffer[0][count];
            right += snd.psg_buffer[1][count];
            snd.buffer[0][count] = left;
            snd.buffer[1][count] = right;
        }
    }
}
Esempio n. 6
0
/* Run the virtual console emulation for one frame */
void system_frame(int skip_render)
{
    static int iline_table[] = {0xC0, 0xE0, 0xF0};
    int lpf = (sms.display == DISPLAY_NTSC) ? 262 : 313;
    int iline;

    /* Debounce pause key */
    if(input.system & INPUT_PAUSE)
    {
        if(!sms.paused)
        {
            sms.paused = 1;

            z80_set_irq_line(IRQ_LINE_NMI, ASSERT_LINE);
            z80_set_irq_line(IRQ_LINE_NMI, CLEAR_LINE);
        }
    }
    else
    {
         sms.paused = 0;
    }

    text_counter = 0;

    /* End of frame, parse sprites for line 0 on line 261 (VCount=$FF) */
    if(vdp.mode <= 7)
        parse_line(0);

    for(vdp.line = 0; vdp.line < lpf;)
    {
        z80_execute(227);

        iline = iline_table[vdp.extended];

        if(!skip_render)
        {
            render_line(vdp.line);
        }

        if(vdp.line <= iline)
        {
            vdp.left -= 1;
            if(vdp.left == -1)
            {
                vdp.left = vdp.reg[0x0A];
                vdp.hint_pending = 1;

                z80_execute(16);

                if(vdp.reg[0x00] & 0x10)
                {
                    z80_set_irq_line(0, ASSERT_LINE);
                }
            }
        }
        else
        {
            vdp.left = vdp.reg[0x0A];
        }

        if(vdp.line == iline)
        {
            vdp.status |= 0x80;
            vdp.vint_pending = 1;

            z80_execute(16);

            if(vdp.reg[0x01] & 0x20)
            {
                z80_set_irq_line(0, ASSERT_LINE);
            }
        }

        sound_update(vdp.line);

        ++vdp.line;

        if(vdp.mode <= 7)
            parse_line(vdp.line);
    }
}
Esempio n. 7
0
/*-------------------------------------------------------------------------

	Run our virtual Neo Geo according to the run mode.

---------------------------------------------------------------------------*/
Uint32 neogeo_run ( void )
{
	Uint32				TimeSlice;
	Uint32				Elapsed;
	Uint32				Z80_Elapsed;
	Uint32				ReturnCode;

	ReturnCode = 0;

	switch ( neogeo_run_mode )
	{
	case NEOGEO_RUN_QUIT:
		ReturnCode = 1;
		break;
	case NEOGEO_RUN_TRACE:
		Elapsed = m68k_execute ( 0 );

		if ( !neogeo_z80_disable )
		{
			neogeo_z80_time_to_execute += M68K_TO_REF ( Elapsed );

			if ( neogeo_z80_time_to_execute > 0 )
			{
				Z80_Elapsed = z80_execute ( REF_TO_Z80 ( neogeo_z80_time_to_execute ) );
				neogeo_z80_time_to_execute -= Z80_TO_REF ( Z80_Elapsed );
				neogeo_z80_time_this_vbl += Z80_TO_REF ( Z80_Elapsed );
			}
		}

		neogeo_screen_position += M68K_TO_REF ( Elapsed );
		timer_advance ( M68K_TO_REF ( Elapsed ) );
		timer_call_events();
		ReturnCode = 3;
		break;
	case NEOGEO_RUN_NORMAL:
	case NEOGEO_RUN_FULL_THROTTLE:
		while ( 1 )
		{
			TimeSlice = REF_TO_M68K ( timer_request_timeslice() );

			if ( neogeo_show_debugger )
			{
				neogeo_show_debugger = 0;
				ReturnCode = 3;
				break;
			}

			Elapsed = m68k_execute ( TimeSlice );

			if ( !neogeo_z80_disable )
			{
				neogeo_z80_time_to_execute += M68K_TO_REF ( Elapsed );

				if ( neogeo_z80_time_to_execute > 0 )
				{
					Z80_Elapsed = z80_execute ( REF_TO_Z80 ( neogeo_z80_time_to_execute ) );
					neogeo_z80_time_to_execute -= Z80_TO_REF ( Z80_Elapsed );
					neogeo_z80_time_this_vbl += Z80_TO_REF ( Z80_Elapsed );
				}
			}

			neogeo_screen_position += M68K_TO_REF ( Elapsed );
			timer_advance ( M68K_TO_REF ( Elapsed ) );

			if ( neogeo_show_debugger )
			{
				neogeo_show_debugger = 0;
				ReturnCode = 3;
			}

			if ( neogeo_run_mode == NEOGEO_RUN_TRACE )
			{
				timer_call_events();
				ReturnCode = 2;
			}

			if ( neogeo_run_mode == NEOGEO_RUN_QUIT )
				ReturnCode = 1;

			if ( ReturnCode )
				break;
		}
		break;
	}

	return ReturnCode;
}
Esempio n. 8
0
uint32 sms_z80_run(uint32 cycles) {
    uint32 cyclesdone = 0;
    uint32 opcode;
    uint16 pc;
    int tmp;
    static char last_str[256];
    char str[256];
    static uint16 last_pc = 0;
    uint32 c1, c2;

    while(cyclesdone < cycles) {
        debug_crab_ents = debug_mz80_ents = 0;
        debug_port_reads1 = debug_port_reads2 = 0;
        debug_mem_reads1 = debug_mem_reads2 = 0;
        debug_crab_ports = debug_mz80_ports = 0;

        pc = cpuz80->pc.w;

        opcode = mread8(cpuz80->pc.w);

        if(opcode == 0xED || opcode == 0xCB || opcode == 0xDD || opcode == 0xFD) {
            opcode |= (mread8(cpuz80->pc.w + 1) << 8);
        }
        if((opcode & 0xFF00) == 0xCB00) {
            opcode |= (mread8(cpuz80->pc.w + 2) << 16) | (mread8(cpuz80->pc.w + 3) << 24);
        }

        c1 = CrabZ80_execute(cpuz80, 1);
        c2 = z80_execute(1);
        cyclesdone += c1;

        tmp = _compare_registers() + _compare_memory() + _compare_ports();
        CrabZ80_disassemble(str, cpuz80, pc);

        if(tmp) {
            printf("Cycles done: %d %d\n", (int)c1, (int)c2);
            printf("%d errors at: PC = 0x%04X, old_pc = 0x%04X Opcode = 0x%02X",
                   tmp, pc, last_pc, opcode & 0xFF);
            switch(opcode & 0xFF) {
                case 0xED:
                case 0xCB:
                    printf("%02X (%s -- %s)\n", (opcode & 0xFF00) >> 8, str,
                           last_str);
                    break;
                case 0xDD:
                case 0xFD:
                    if((opcode & 0xFF00) == 0xCB00)
                        printf("%02X%02X%02X (%s -- %s)\n",
                               (opcode & 0xFF00) >> 8,
                               (opcode & 0xFF0000) >> 16,
                               (opcode & 0xFF000000) >> 24, str, last_str);
                    else
                        printf("%02X (%s -- %s)\n", (opcode & 0xFF00) >> 8, str,
                               last_str);
                    break;
                default:
                    printf("(%s -- %s)\n", str, last_str);
            }
        }

        strcpy(last_str, str);
        last_pc = pc;
    }
Esempio n. 9
0
inline void cpu_z80_run(int nbcycle)
{
    //printf("%x\n",z80_get_reg(Z80_PC));
    z80_execute(nbcycle);
}
Esempio n. 10
0
int32 qsf_gen(qsf_synth_t *s, int16 *buffer, uint32 samples)
{	
	int16 output[44100/30], output2[44100/30];
	int16 *stereo[2];
	int16 *outp = buffer;
	int32 i, opos, tickinc, loops;

	// our largest possible step is samples_per_tick or samples, whichever is smaller
	if (s->samples_to_next_tick > samples)
	{
		tickinc = samples;
	}
	else
	{
		tickinc = s->samples_to_next_tick;
	}

	loops = samples / tickinc;
	opos = 0;

	for (i = 0; i < loops; i++)
	{
		z80_execute(s->z80, (8000000/44100)*tickinc);
		stereo[0] = &output[opos];
		stereo[1] = &output2[opos];
		qsound_update(s->qs, 0, stereo, tickinc);

		opos += tickinc;
		s->samples_to_next_tick -= tickinc;

		if (s->samples_to_next_tick <= 0)
		{
			timer_tick(s);
			s->samples_to_next_tick = samples_per_tick;
		}
	}

	// are there "leftovers"?
	if (opos < samples)
	{
		z80_execute(s->z80, (8000000/44100)*(samples-opos));
		stereo[0] = &output[opos];
		stereo[1] = &output2[opos];
		qsound_update(s->qs, 0, stereo, (samples-opos));

		s->samples_to_next_tick -= (samples-opos);

		if (s->samples_to_next_tick <= 0)
		{
			timer_tick(s);
			s->samples_to_next_tick = samples_per_tick;
		}
	}

	for (i = 0; i < samples; i++)
	{
		*outp++ = output[i];
		*outp++ = output2[i];
	}

	return AO_SUCCESS;
}
Esempio n. 11
0
void gameboy_run()
{
    uint8_t op;

    /* reset counter */
    cycles.cnt = 0;

    /* get interrupt flags and interrupt enables */
    uint8_t *int_e;
    uint8_t *int_f;

    /* pointers to memory location of interrupt enables/flags */
    int_e = mmu_addr(0xFFFF);
    int_f = mmu_addr(0xFF0F);

    /* start at normal speed */
    global_cpu_double_speed = 0;

    /* run stuff!                                                          */
    /* mechanism is simple.                                                */
    /* 1) execute instruction 2) update cycles counter 3) check interrupts */
    /* and repeat forever                                                  */
    while (!global_quit)
    {
        /*if (global_slow_down)
        {
            usleep(100000);
            global_slow_down = 0;
        }*/

        /* pause? */
        while (global_pause)
            sem_wait(&gameboy_sem);

        /* get op */
        op = mmu_read(state.pc);

        /* print out CPU state if enabled by debug flag */
        if (global_debug)
        {
            utils_log("OP: %02x F: %02x PC: %04x:%02x:%02x SP: %04x:%02x:%02x ",
                      op, *state.f & 0xd0, state.pc,
                      mmu_read_no_cyc(state.pc + 1),
                      mmu_read_no_cyc(state.pc + 2), state.sp,
                      mmu_read_no_cyc(state.sp),
                      mmu_read_no_cyc(state.sp + 1));


            utils_log("A: %02x BC: %04x DE: %04x HL: %04x FF41: %02x "
                      "FF44: %02x ENAB: %02x INTE: %02x INTF: %02x\n",
                      state.a, *state.bc,
                      *state.de, *state.hl,
                      mmu_read_no_cyc(0xFF41),
                      mmu_read_no_cyc(0xFF44),
                      state.int_enable,
                      *int_e, *int_f);
        }

        /* execute instruction by the GB Z80 version */
        z80_execute(op);

        /* if last op was Interrupt Enable (0xFB)  */
        /* we need to check for INTR on next cycle */
        if (op == 0xFB)
            continue;

        /* interrupts filtered by enable flags */
        uint8_t int_r = (*int_f & *int_e);

        /* check for interrupts */
        if ((state.int_enable || op == 0x76) && (int_r != 0))
        {
            /* discard useless bits */
            if ((int_r & 0x1F) == 0x00)
                continue;

            /* beware of instruction that doesn't move PC! */
            /* like HALT (0x76)                            */
            if (op == 0x76)
            {
                state.pc++;

                if (state.int_enable == 0)
                    continue;
            }

            /* reset int-enable flag, it will be restored after a RETI op */
            state.int_enable = 0;

            if ((int_r & 0x01) == 0x01)
            {
                /* vblank interrupt triggers RST 5 */

                /* reset flag */
                *int_f &= 0xFE;

                /* handle the interrupt */
                z80_intr(0x0040);
            }
            else if ((int_r & 0x02) == 0x02)
            {
                /* LCD Stat interrupt */

                /* reset flag */
                *int_f &= 0xFD;

                /* handle the interrupt! */
                z80_intr(0x0048);
            }
            else if ((int_r & 0x04) == 0x04)
            {
                /* timer interrupt */

                /* reset flag */
                *int_f &= 0xFB;

                /* handle the interrupt! */
                z80_intr(0x0050);
            }
            else if ((int_r & 0x08) == 0x08)
            {
                /* serial interrupt */

                /* reset flag */
                *int_f &= 0xF7;

                /* handle the interrupt! */
                z80_intr(0x0058);
            }
        }
    }

    /* terminate all the stuff */
    cartridge_term();
    sound_term();
    mmu_term();

    return;
}