2018-05-20 04:53:34 +00:00
// Pi1541 - A Commodore 1541 disk drive emulator
// Copyright(C) 2018 Stephen White
//
// This file is part of Pi1541.
//
// Pi1541 is free software : you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Pi1541 is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Pi1541. If not, see <http://www.gnu.org/licenses/>.
# include "iec_bus.h"
2018-06-03 07:43:36 +00:00
static int buttonCount = sizeof ( ButtonPinFlags ) / sizeof ( unsigned ) ;
2018-05-20 04:53:34 +00:00
u32 IEC_Bus : : PIGPIO_MASK_IN_ATN = 1 < < PIGPIO_ATN ;
u32 IEC_Bus : : PIGPIO_MASK_IN_DATA = 1 < < PIGPIO_DATA ;
u32 IEC_Bus : : PIGPIO_MASK_IN_CLOCK = 1 < < PIGPIO_CLOCK ;
u32 IEC_Bus : : PIGPIO_MASK_IN_SRQ = 1 < < PIGPIO_SRQ ;
u32 IEC_Bus : : PIGPIO_MASK_IN_RESET = 1 < < PIGPIO_RESET ;
bool IEC_Bus : : PI_Atn = false ;
bool IEC_Bus : : PI_Data = false ;
bool IEC_Bus : : PI_Clock = false ;
bool IEC_Bus : : PI_Reset = false ;
bool IEC_Bus : : VIA_Atna = false ;
bool IEC_Bus : : VIA_Data = false ;
bool IEC_Bus : : VIA_Clock = false ;
bool IEC_Bus : : DataSetToOut = false ;
bool IEC_Bus : : AtnaDataSetToOut = false ;
bool IEC_Bus : : ClockSetToOut = false ;
bool IEC_Bus : : OutputLED = false ;
bool IEC_Bus : : OutputSound = false ;
bool IEC_Bus : : Resetting = false ;
bool IEC_Bus : : splitIECLines = false ;
bool IEC_Bus : : invertIECInputs = false ;
2018-05-26 22:55:17 +00:00
bool IEC_Bus : : invertIECOutputs = true ;
bool IEC_Bus : : ignoreReset = false ;
2018-05-20 04:53:34 +00:00
u32 IEC_Bus : : myOutsGPFSEL1 = 0 ;
u32 IEC_Bus : : myOutsGPFSEL0 = 0 ;
bool IEC_Bus : : InputButton [ 5 ] ;
bool IEC_Bus : : InputButtonPrev [ 5 ] ;
u32 IEC_Bus : : validInputCount [ 5 ] ;
u32 IEC_Bus : : inputRepeatThreshold [ 5 ] ;
u32 IEC_Bus : : inputRepeat [ 5 ] ;
u32 IEC_Bus : : inputRepeatPrev [ 5 ] ;
m6522 * IEC_Bus : : VIA = 0 ;
2018-06-03 07:43:36 +00:00
u32 IEC_Bus : : emulationModeCheckButtonIndex = 0 ;
void IEC_Bus : : ReadBrowseMode ( void )
2018-05-20 04:53:34 +00:00
{
IOPort * portB = 0 ;
unsigned gplev0 = read32 ( ARM_GPIO_GPLEV0 ) ;
int index ;
for ( index = 0 ; index < buttonCount ; + + index )
{
UpdateButton ( index , gplev0 ) ;
}
2018-06-03 07:43:36 +00:00
bool ATNIn = ( gplev0 & PIGPIO_MASK_IN_ATN ) = = ( invertIECInputs ? PIGPIO_MASK_IN_ATN : 0 ) ;
if ( PI_Atn ! = ATNIn )
{
PI_Atn = ATNIn ;
}
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)
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 ) ;
if ( PI_Data ! = DATAIn )
{
PI_Data = DATAIn ;
}
}
else
{
PI_Data = true ;
}
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 ) ;
if ( PI_Clock ! = CLOCKIn )
{
PI_Clock = CLOCKIn ;
}
}
else
{
PI_Clock = true ;
}
Resetting = ! ignoreReset & & ( ( gplev0 & PIGPIO_MASK_IN_RESET ) = = ( invertIECInputs ? PIGPIO_MASK_IN_RESET : 0 ) ) ;
}
void IEC_Bus : : ReadEmulationMode ( void )
{
IOPort * portB = 0 ;
unsigned gplev0 = read32 ( ARM_GPIO_GPLEV0 ) ;
UpdateButton ( emulationModeCheckButtonIndex , gplev0 ) ;
emulationModeCheckButtonIndex + + ;
emulationModeCheckButtonIndex % = buttonCount ;
portB = VIA - > GetPortB ( ) ;
2018-05-20 04:53:34 +00:00
bool ATNIn = ( gplev0 & PIGPIO_MASK_IN_ATN ) = = ( invertIECInputs ? PIGPIO_MASK_IN_ATN : 0 ) ;
if ( PI_Atn ! = ATNIn )
{
PI_Atn = ATNIn ;
2018-06-03 07:43:36 +00:00
//if (VIA)
2018-05-20 04:53:34 +00:00
{
if ( ( portB - > GetDirection ( ) & 0x10 ) ! = 0 )
{
// Emulate the XOR gate UD3
// We only need to do this when fully emulating, iec commands do this internally
AtnaDataSetToOut = ( VIA_Atna ! = PI_Atn ) ;
}
portB - > SetInput ( VIAPORTPINS_ATNIN , ATNIn ) ; //is inverted and then connected to pb7 and ca1
VIA - > InputCA1 ( ATNIn ) ;
}
}
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)
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 ) ;
if ( PI_Data ! = DATAIn )
{
PI_Data = DATAIn ;
2018-06-03 07:43:36 +00:00
portB - > SetInput ( VIAPORTPINS_DATAIN , DATAIn ) ; // VIA DATAin pb0 output from inverted DIN 5 DATA
2018-05-20 04:53:34 +00:00
}
}
else
{
PI_Data = true ;
2018-06-03 07:43:36 +00:00
portB - > SetInput ( VIAPORTPINS_DATAIN , true ) ; // simulate the read in software
2018-05-20 04:53:34 +00:00
}
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)
{
2018-06-03 07:43:36 +00:00
bool CLOCKIn = ( gplev0 & PIGPIO_MASK_IN_CLOCK ) = = ( invertIECInputs ? PIGPIO_MASK_IN_CLOCK : 0 ) ;
2018-05-20 04:53:34 +00:00
if ( PI_Clock ! = CLOCKIn )
{
PI_Clock = CLOCKIn ;
2018-06-03 07:43:36 +00:00
portB - > SetInput ( VIAPORTPINS_CLOCKIN , CLOCKIn ) ; // VIA CLKin pb2 output from inverted DIN 4 CLK
2018-05-20 04:53:34 +00:00
}
}
else
{
PI_Clock = true ;
2018-06-03 07:43:36 +00:00
portB - > SetInput ( VIAPORTPINS_CLOCKIN , true ) ; // simulate the read in software
2018-05-20 04:53:34 +00:00
}
2018-05-26 22:55:17 +00:00
Resetting = ! ignoreReset & & ( ( gplev0 & PIGPIO_MASK_IN_RESET ) = = ( invertIECInputs ? PIGPIO_MASK_IN_RESET : 0 ) ) ;
2018-05-20 04:53:34 +00:00
}