Reduced the time between reading and writing the IEC bus in 1541 mode.

Doing this increases compatability for some people using regular Pi3 models.
This commit is contained in:
Stephen White 2018-12-29 17:51:55 +11:00
parent a25f1963c0
commit 123612a473
3 changed files with 125 additions and 126 deletions

View File

@ -67,10 +67,13 @@ u32 IEC_Bus::inputRepeatPrev[5] = { 0 };
u32 IEC_Bus::emulationModeCheckButtonIndex = 0; u32 IEC_Bus::emulationModeCheckButtonIndex = 0;
unsigned IEC_Bus::gplev0;
void IEC_Bus::ReadBrowseMode(void) void IEC_Bus::ReadBrowseMode(void)
{ {
IOPort* portB = 0; IOPort* portB = 0;
unsigned gplev0 = read32(ARM_GPIO_GPLEV0); gplev0 = read32(ARM_GPIO_GPLEV0);
int index; int index;
for (index = 0; index < buttonCount; ++index) for (index = 0; index < buttonCount; ++index)
@ -116,20 +119,20 @@ void IEC_Bus::ReadBrowseMode(void)
Resetting = !ignoreReset && ((gplev0 & PIGPIO_MASK_IN_RESET) == (invertIECInputs ? PIGPIO_MASK_IN_RESET : 0)); Resetting = !ignoreReset && ((gplev0 & PIGPIO_MASK_IN_RESET) == (invertIECInputs ? PIGPIO_MASK_IN_RESET : 0));
} }
void IEC_Bus::ReadEmulationMode1541(void) void IEC_Bus::ReadButtonsEmulationMode(void)
{ {
IOPort* portB = 0;
unsigned gplev0 = read32(ARM_GPIO_GPLEV0);
int buttonIndex; int buttonIndex;
for (buttonIndex = 0; buttonIndex < 3; ++buttonIndex) for (buttonIndex = 0; buttonIndex < 3; ++buttonIndex)
{ {
UpdateButton(buttonIndex, gplev0); UpdateButton(buttonIndex, gplev0);
} }
// Doing it this way screws with the debounce counters. }
//UpdateButton(emulationModeCheckButtonIndex, gplev0);
//emulationModeCheckButtonIndex++; void IEC_Bus::ReadEmulationMode1541(void)
//emulationModeCheckButtonIndex %= buttonCount; {
bool AtnaDataSetToOutOld = AtnaDataSetToOut;
IOPort* portB = 0;
gplev0 = read32(ARM_GPIO_GPLEV0);
portB = port; portB = port;
@ -156,10 +159,14 @@ void IEC_Bus::ReadEmulationMode1541(void)
if (portB && (portB->GetDirection() & 0x10) == 0) if (portB && (portB->GetDirection() & 0x10) == 0)
AtnaDataSetToOut = false; // If the ATNA PB4 gets set to an input then we can't be pulling data low. (Maniac Mansion does this) AtnaDataSetToOut = false; // If the ATNA PB4 gets set to an input then we can't be pulling data low. (Maniac Mansion does this)
// moved from PortB_OnPortOut
if (AtnaDataSetToOut)
portB->SetInput(VIAPORTPINS_DATAIN, true); // simulate the read in software
if (!AtnaDataSetToOut && !DataSetToOut) // only sense if we have not brought the line low (because we can't as we have the pin set to output but we can simulate in software) if (!AtnaDataSetToOut && !DataSetToOut) // only sense if we have not brought the line low (because we can't as we have the pin set to output but we can simulate in software)
{ {
bool DATAIn = (gplev0 & PIGPIO_MASK_IN_DATA) == (invertIECInputs ? PIGPIO_MASK_IN_DATA : 0); bool DATAIn = (gplev0 & PIGPIO_MASK_IN_DATA) == (invertIECInputs ? PIGPIO_MASK_IN_DATA : 0);
if (PI_Data != DATAIn) //if (PI_Data != DATAIn)
{ {
PI_Data = DATAIn; PI_Data = DATAIn;
portB->SetInput(VIAPORTPINS_DATAIN, DATAIn); // VIA DATAin pb0 output from inverted DIN 5 DATA portB->SetInput(VIAPORTPINS_DATAIN, DATAIn); // VIA DATAin pb0 output from inverted DIN 5 DATA
@ -174,7 +181,7 @@ void IEC_Bus::ReadEmulationMode1541(void)
if (!ClockSetToOut) // only sense if we have not brought the line low (because we can't as we have the pin set to output but we can simulate in software) if (!ClockSetToOut) // only sense if we have not brought the line low (because we can't as we have the pin set to output but we can simulate in software)
{ {
bool CLOCKIn = (gplev0 & PIGPIO_MASK_IN_CLOCK) == (invertIECInputs ? PIGPIO_MASK_IN_CLOCK : 0); bool CLOCKIn = (gplev0 & PIGPIO_MASK_IN_CLOCK) == (invertIECInputs ? PIGPIO_MASK_IN_CLOCK : 0);
if (PI_Clock != CLOCKIn) //if (PI_Clock != CLOCKIn)
{ {
PI_Clock = CLOCKIn; PI_Clock = CLOCKIn;
portB->SetInput(VIAPORTPINS_CLOCKIN, CLOCKIn); // VIA CLKin pb2 output from inverted DIN 4 CLK portB->SetInput(VIAPORTPINS_CLOCKIN, CLOCKIn); // VIA CLKin pb2 output from inverted DIN 4 CLK
@ -192,17 +199,9 @@ void IEC_Bus::ReadEmulationMode1541(void)
void IEC_Bus::ReadEmulationMode1581(void) void IEC_Bus::ReadEmulationMode1581(void)
{ {
IOPort* portB = 0; IOPort* portB = 0;
unsigned gplev0 = read32(ARM_GPIO_GPLEV0); gplev0 = read32(ARM_GPIO_GPLEV0);
int buttonIndex; ReadButtonsEmulationMode();
for (buttonIndex = 0; buttonIndex < 3; ++buttonIndex)
{
UpdateButton(buttonIndex, gplev0);
}
// Doing it this way screws with the debounce counters.
//UpdateButton(emulationModeCheckButtonIndex, gplev0);
//emulationModeCheckButtonIndex++;
//emulationModeCheckButtonIndex %= buttonCount;
portB = port; portB = port;
@ -275,3 +274,99 @@ void IEC_Bus::ReadEmulationMode1581(void)
Resetting = !ignoreReset && ((gplev0 & PIGPIO_MASK_IN_RESET) == (invertIECInputs ? PIGPIO_MASK_IN_RESET : 0)); Resetting = !ignoreReset && ((gplev0 & PIGPIO_MASK_IN_RESET) == (invertIECInputs ? PIGPIO_MASK_IN_RESET : 0));
} }
void IEC_Bus::RefreshOuts1541(void)
{
unsigned set = 0;
unsigned clear = 0;
unsigned tmp;
if (!splitIECLines)
{
unsigned outputs = 0;
if (AtnaDataSetToOut || DataSetToOut) outputs |= (FS_OUTPUT << ((PIGPIO_DATA - 10) * 3));
if (ClockSetToOut) outputs |= (FS_OUTPUT << ((PIGPIO_CLOCK - 10) * 3));
unsigned nValue = (myOutsGPFSEL1 & PI_OUTPUT_MASK_GPFSEL1) | outputs;
write32(ARM_GPIO_GPFSEL1, nValue);
}
else
{
if (AtnaDataSetToOut || DataSetToOut) set |= 1 << PIGPIO_OUT_DATA;
else clear |= 1 << PIGPIO_OUT_DATA;
if (ClockSetToOut) set |= 1 << PIGPIO_OUT_CLOCK;
else clear |= 1 << PIGPIO_OUT_CLOCK;
if (!invertIECOutputs) {
tmp = set;
set = clear;
clear = tmp;
}
}
if (OutputLED) set |= 1 << PIGPIO_OUT_LED;
else clear |= 1 << PIGPIO_OUT_LED;
if (OutputSound) set |= 1 << PIGPIO_OUT_SOUND;
else clear |= 1 << PIGPIO_OUT_SOUND;
write32(ARM_GPIO_GPCLR0, clear);
write32(ARM_GPIO_GPSET0, set);
}
void IEC_Bus::PortB_OnPortOut(void* pUserData, unsigned char status)
{
bool oldDataSetToOut = DataSetToOut;
bool oldClockSetToOut = ClockSetToOut;
bool AtnaDataSetToOutOld = AtnaDataSetToOut;
// These are the values the VIA is trying to set the outputs to
VIA_Atna = (status & (unsigned char)VIAPORTPINS_ATNAOUT) != 0;
VIA_Data = (status & (unsigned char)VIAPORTPINS_DATAOUT) != 0; // VIA DATAout PB1 inverted and then connected to DIN DATA
VIA_Clock = (status & (unsigned char)VIAPORTPINS_CLOCKOUT) != 0; // VIA CLKout PB3 inverted and then connected to DIN CLK
if (VIA)
{
// Emulate the XOR gate UD3
AtnaDataSetToOut = (VIA_Atna != PI_Atn);
}
else
{
AtnaDataSetToOut = (VIA_Atna & PI_Atn);
}
//if (AtnaDataSetToOut)
//{
// // if the output of the XOR gate is high (ie VIA_Atna != PI_Atn) then this is inverted and pulls DATA low (activating it)
// //PI_Data = true;
// if (port) port->SetInput(VIAPORTPINS_DATAIN, true); // simulate the read in software
//}
if (VIA && port)
{
// If the VIA's data and clock outputs ever get set to inputs the real hardware reads these lines as asserted.
bool PB1SetToInput = (port->GetDirection() & 2) == 0;
bool PB3SetToInput = (port->GetDirection() & 8) == 0;
if (PB1SetToInput) VIA_Data = true;
if (PB3SetToInput) VIA_Clock = true;
}
ClockSetToOut = VIA_Clock;
DataSetToOut = VIA_Data;
//if (!oldDataSetToOut && DataSetToOut)
//{
// //PI_Data = true;
// if (port) port->SetInput(VIAPORTPINS_DATAOUT, true); // simulate the read in software
//}
//if (!oldClockSetToOut && ClockSetToOut)
//{
// //PI_Clock = true;
// if (port) port->SetInput(VIAPORTPINS_CLOCKIN, true); // simulate the read in software
//}
//if (AtnaDataSetToOutOld ^ AtnaDataSetToOut)
// RefreshOuts1541();
}

View File

@ -351,6 +351,7 @@ public:
static void ReadBrowseMode(void); static void ReadBrowseMode(void);
static void ReadEmulationMode1541(void); static void ReadEmulationMode1541(void);
static void ReadButtonsEmulationMode(void);
static void ReadEmulationMode1581(void); static void ReadEmulationMode1581(void);
static void WaitUntilReset(void) static void WaitUntilReset(void)
@ -369,99 +370,9 @@ public:
} }
// Out going // Out going
static void PortB_OnPortOut(void* pUserData, unsigned char status) static void PortB_OnPortOut(void* pUserData, unsigned char status);
{
bool oldDataSetToOut = DataSetToOut;
bool oldClockSetToOut = ClockSetToOut;
// These are the values the VIA is trying to set the outputs to static void RefreshOuts1541(void);
VIA_Atna = (status & (unsigned char)VIAPORTPINS_ATNAOUT) != 0;
VIA_Data = (status & (unsigned char)VIAPORTPINS_DATAOUT) != 0; // VIA DATAout PB1 inverted and then connected to DIN DATA
VIA_Clock = (status & (unsigned char)VIAPORTPINS_CLOCKOUT) != 0; // VIA CLKout PB3 inverted and then connected to DIN CLK
if (VIA)
{
// Emulate the XOR gate UD3
AtnaDataSetToOut = (VIA_Atna != PI_Atn);
}
else
{
AtnaDataSetToOut = (VIA_Atna & PI_Atn);
}
if (AtnaDataSetToOut)
{
// if the output of the XOR gate is high (ie VIA_Atna != PI_Atn) then this is inverted and pulls DATA low (activating it)
PI_Data = true;
if (port) port->SetInput(VIAPORTPINS_DATAIN, true); // simulate the read in software
}
if (VIA && port)
{
// If the VIA's data and clock outputs ever get set to inputs the real hardware reads these lines as asserted.
bool PB1SetToInput = (port->GetDirection() & 2) == 0;
bool PB3SetToInput = (port->GetDirection() & 8) == 0;
if (PB1SetToInput) VIA_Data = true;
if (PB3SetToInput) VIA_Clock = true;
}
ClockSetToOut = VIA_Clock;
DataSetToOut = VIA_Data;
if (!oldDataSetToOut && DataSetToOut)
{
PI_Data = true;
if (port) port->SetInput(VIAPORTPINS_DATAOUT, true); // simulate the read in software
}
if (!oldClockSetToOut && ClockSetToOut)
{
PI_Clock = true;
if (port) port->SetInput(VIAPORTPINS_CLOCKIN, true); // simulate the read in software
}
}
static inline void RefreshOuts1541(void)
{
unsigned set = 0;
unsigned clear = 0;
unsigned tmp;
if (!splitIECLines)
{
unsigned outputs = 0;
if (AtnaDataSetToOut || DataSetToOut) outputs |= (FS_OUTPUT << ((PIGPIO_DATA - 10) * 3));
if (ClockSetToOut) outputs |= (FS_OUTPUT << ((PIGPIO_CLOCK - 10) * 3));
unsigned nValue = (myOutsGPFSEL1 & PI_OUTPUT_MASK_GPFSEL1) | outputs;
write32(ARM_GPIO_GPFSEL1, nValue);
}
else
{
if (AtnaDataSetToOut || DataSetToOut) set |= 1 << PIGPIO_OUT_DATA;
else clear |= 1 << PIGPIO_OUT_DATA;
if (ClockSetToOut) set |= 1 << PIGPIO_OUT_CLOCK;
else clear |= 1 << PIGPIO_OUT_CLOCK;
if (!invertIECOutputs) {
tmp = set;
set = clear;
clear = tmp;
}
}
if (OutputLED) set |= 1 << PIGPIO_OUT_LED;
else clear |= 1 << PIGPIO_OUT_LED;
if (OutputSound) set |= 1 << PIGPIO_OUT_SOUND;
else clear |= 1 << PIGPIO_OUT_SOUND;
write32(ARM_GPIO_GPSET0, set);
write32(ARM_GPIO_GPCLR0, clear);
}
static inline void RefreshOuts1581(void) static inline void RefreshOuts1581(void)
{ {
@ -697,6 +608,8 @@ private:
static u32 emulationModeCheckButtonIndex; static u32 emulationModeCheckButtonIndex;
static unsigned gplev0;
static bool PI_Atn; static bool PI_Atn;
static bool PI_Data; static bool PI_Data;
static bool PI_Clock; static bool PI_Clock;

View File

@ -724,7 +724,8 @@ EXIT_TYPE Emulate1541(FileBrowser* fileBrowser)
//read32(ARM_SYSTIMER_CLO); //Each one of these is > 100ns //read32(ARM_SYSTIMER_CLO); //Each one of these is > 100ns
//read32(ARM_SYSTIMER_CLO); //read32(ARM_SYSTIMER_CLO);
//read32(ARM_SYSTIMER_CLO); //read32(ARM_SYSTIMER_CLO);
//IEC_Bus::RefreshOuts(); // Now output all outputs.
IEC_Bus::RefreshOuts1541(); // Now output all outputs.
IEC_Bus::OutputLED = pi1541.drive.IsLEDOn(); IEC_Bus::OutputLED = pi1541.drive.IsLEDOn();
if (IEC_Bus::OutputLED ^ oldLED) if (IEC_Bus::OutputLED ^ oldLED)
@ -749,21 +750,11 @@ EXIT_TYPE Emulate1541(FileBrowser* fileBrowser)
} }
} }
//if (options.SoundOnGPIO() && headSoundCounter > 0)
//{
// headSoundFreqCounter--; // Continue updating a GPIO non DMA sound.
// if (headSoundFreqCounter <= 0)
// {
// headSoundFreqCounter = headSoundFreq;
// headSoundCounter -= headSoundFreq * 8;
// IEC_Bus::OutputSound = !IEC_Bus::OutputSound;
// }
//}
IEC_Bus::RefreshOuts1541(); // Now output all outputs.
} }
IEC_Bus::ReadButtonsEmulationMode();
// Other core will check the uart (as it is slow) (could enable uart irqs - will they execute on this core?) // Other core will check the uart (as it is slow) (could enable uart irqs - will they execute on this core?)
inputMappings->CheckKeyboardEmulationMode(numberOfImages, numberOfImagesMax); inputMappings->CheckKeyboardEmulationMode(numberOfImages, numberOfImagesMax);
inputMappings->CheckButtonsEmulationMode(); inputMappings->CheckButtonsEmulationMode();