Ejemplo n.º 1
0
void Reset (bool fPress_)
{
    // Set CPU operating mode
    g_fReset = fPress_;

    if (g_fReset)
    {
        // Certain registers are initialised on every reset
        I = R = R7 = IFF1 = IFF2 = 0;
        PC = 0x0000;
        regs.halted = 0;
        bOpcode = 0x00; // not after EI

        // Index prefix not active
        pHlIxIy = pNewHlIxIy = &HL;

        // Clear the CPU events queue
        InitCpuEvents();

        // Schedule the first end of line event, and an update check 3/4 through the frame
        AddCpuEvent(evtEndOfFrame, TSTATES_PER_FRAME);
        AddCpuEvent(evtInputUpdate, TSTATES_PER_FRAME*3/4);

        // Re-initialise memory (for configuration changes) and reset I/O
        IO::Init();
        Memory::Init();

        // Refresh the debugger and re-test breakpoints
        Debug::Refresh();
    }
    // Set up the fast reset for first power-on
    else if (GetOption(fastreset))
        g_nTurbo |= TURBO_BOOT;
}
Ejemplo n.º 2
0
void Tape::NextEdge (DWORD dwTime_)
{
    libspectrum_error error;

    if (fEar)
        keyboard |= BORD_EAR_MASK;
    else
        keyboard &= ~BORD_EAR_MASK;

    if (!g_nTurbo)
        pDAC->Output(fEar ? 0xa0 : 0x80);

    libspectrum_dword tstates;
    int nFlags;

    // Fetch details of the next edge, and the time until it's due
    error = libspectrum_tape_get_next_edge(&tstates, &nFlags, pTape);
    if (error)
    {
        Stop();
        return;
    }

    if (nFlags & LIBSPECTRUM_TAPE_FLAGS_LEVEL_LOW)
        fEar = false;
    else if (nFlags & LIBSPECTRUM_TAPE_FLAGS_LEVEL_HIGH)
        fEar = true;
    else if (!(nFlags & LIBSPECTRUM_TAPE_FLAGS_NO_EDGE))
        fEar = !fEar;

    // End of tape block?
    if ((nFlags & LIBSPECTRUM_TAPE_FLAGS_BLOCK))
    {
        // Stop the tape as it'll restart when required
        Stop();
    }
    else

    {
        // Timings are in 3.5MHz t-states, so convert to SAM t-states
        tstates = tstates*(REAL_TSTATES_PER_SECOND/1000) + tremain;
        libspectrum_dword tadd = tstates/(SPECTRUM_TSTATES_PER_SECOND/1000);
        tremain = tstates % (SPECTRUM_TSTATES_PER_SECOND/1000);

        // Schedule an event to activate the edge
        AddCpuEvent(evtTapeEdge, dwTime_+tadd);
    }
}
Ejemplo n.º 3
0
// Execute the CPU event specified
void ExecuteEvent (CPU_EVENT sThisEvent)
{
    switch (sThisEvent.nEvent)
    {
        case evtStdIntEnd:
            // Reset the interrupt as we're done
            status_reg |= (STATUS_INT_FRAME | STATUS_INT_LINE);
            break;

        case evtMidiOutIntStart:
            // Begin the MIDI_OUT interrupt and add an event to end it
            status_reg &= ~STATUS_INT_MIDIOUT;
            AddCpuEvent(evtMidiOutIntEnd, sThisEvent.dwTime + MIDI_INT_ACTIVE_TIME);
            break;

        case evtMidiOutIntEnd:
            // Reset the interrupt and clear the 'transmitting' bit in LPEN as we're done
            status_reg |= STATUS_INT_MIDIOUT;
            lpen &= ~LPEN_TXFMST;
            break;

        case evtLineIntStart:
        {
            // Begin the line interrupt and add an event to end it
            status_reg &= ~STATUS_INT_LINE;
            AddCpuEvent(evtStdIntEnd, sThisEvent.dwTime + INT_ACTIVE_TIME);

            AddCpuEvent(evtLineIntStart, sThisEvent.dwTime + TSTATES_PER_FRAME);
            break;
        }

        case evtEndOfFrame:
        {
            // Signal a FRAME interrupt, and start the interrupt counter
            status_reg &= ~STATUS_INT_FRAME;
            AddCpuEvent(evtStdIntEnd, sThisEvent.dwTime + INT_ACTIVE_TIME);

            AddCpuEvent(evtEndOfFrame, sThisEvent.dwTime + TSTATES_PER_FRAME);

            // Signal end of the frame
            g_fBreak = true;
            break;
        }

        case evtInputUpdate:
            // Update the input in the centre of the screen (well away from the frame boundary) to avoid the ROM
            // keyboard scanner discarding key presses when it thinks keys have bounced.  In old versions this was
            // the cause of the first key press on the boot screen only clearing it (took AGES to track down!)
            IO::UpdateInput();

            // Schedule the next input check at the same position in the next frame
            AddCpuEvent(evtInputUpdate, sThisEvent.dwTime + TSTATES_PER_FRAME);
            break;

        case evtMouseReset:
            pMouse->Reset();
            break;

        case evtBlueAlphaClock:
            // Clock the sampler, scheduling the next event if it's still running
            if (pBlueAlpha->Clock())
                AddCpuEvent(evtBlueAlphaClock, sThisEvent.dwTime + BLUE_ALPHA_CLOCK_TIME);
            break;

        case evtAsicStartup:
            // ASIC is now responsive
            IO::WakeAsic();
            break;

        case evtTapeEdge:
            Tape::NextEdge(sThisEvent.dwTime);
            break;
    }
}