Merged Marco's Pi2 changes

Used overclock config;-
kernel_address=0x1f00000

arm_freq=1000
core_freq=500
sdram_freq=450
over_voltage=2
force_turbo=1
boot_delay=1
temp_limit=80
This commit is contained in:
Stephen White 2020-01-25 13:44:00 +11:00
parent 899ed08033
commit 37154feb0d
3 changed files with 145 additions and 92 deletions

View file

@ -25,7 +25,7 @@ else ifeq ($(strip $(RASPPI)),1+)
ARCH ?= -march=armv6zk -mtune=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard -DRPIBPLUS=1 ARCH ?= -march=armv6zk -mtune=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard -DRPIBPLUS=1
CFLAGS += -DRPIBPLUS=1 -DRASPPI=1 CFLAGS += -DRPIBPLUS=1 -DRASPPI=1
else ifeq ($(strip $(RASPPI)),2) else ifeq ($(strip $(RASPPI)),2)
ARCH ?= -march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -marm -DRPI2=1 ARCH ?= -march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -marm -DRPI2=1 -DEXPERIMENTALZERO=1
CFLAGS += -DRPI2=1 CFLAGS += -DRPI2=1
else ifeq ($(strip $(RASPPI)),3) else ifeq ($(strip $(RASPPI)),3)
ARCH ?= -march=armv8-a+crc -mtune=cortex-a53 -mfpu=crypto-neon-fp-armv8 -mfloat-abi=hard -marm -DRPI3=1 ARCH ?= -march=armv8-a+crc -mtune=cortex-a53 -mfpu=crypto-neon-fp-armv8 -mfloat-abi=hard -marm -DRPI3=1

View file

@ -20,7 +20,9 @@
#define USE_HW_MAILBOX #define USE_HW_MAILBOX
// Indicates we want to make active use of multiple cores // Indicates we want to make active use of multiple cores
#if defined(RPI3)
#define USE_MULTICORE #define USE_MULTICORE
#endif
// Needs to match kernel_old setting in config.txt // Needs to match kernel_old setting in config.txt
//#define KERNEL_OLD //#define KERNEL_OLD

View file

@ -120,6 +120,9 @@ bool USBKeyboardDetected = false;
//bool resetWhileEmulating = false; //bool resetWhileEmulating = false;
bool selectedViaIECCommands = false; bool selectedViaIECCommands = false;
u16 pc; u16 pc;
#if defined(RPI2)
u32 clockCycles1MHz;
#endif
#if not defined(EXPERIMENTALZERO) #if not defined(EXPERIMENTALZERO)
SpinLock core0RefreshingScreen; SpinLock core0RefreshingScreen;
@ -265,6 +268,14 @@ void InitialiseHardware()
RPI_PropertyInit(); RPI_PropertyInit();
RPI_PropertyAddTag(TAG_SET_CLOCK_RATE, ARM_CLK_ID, MaxClk); RPI_PropertyAddTag(TAG_SET_CLOCK_RATE, ARM_CLK_ID, MaxClk);
RPI_PropertyProcess(); RPI_PropertyProcess();
#if defined(RPI2)
// Enable clock cycle counter
asm volatile ("mcr p15,0,%0,c9,c12,0" :: "r" (0b0001));
asm volatile ("mcr p15,0,%0,c9,c12,1" :: "r" ((1 << 31)));
clockCycles1MHz = MaxClk / 1000000;
#endif
} }
void InitialiseLCD() void InitialiseLCD()
@ -762,7 +773,7 @@ EXIT_TYPE Emulate1541(FileBrowser* fileBrowser)
int headSoundFreqCounter = 0; int headSoundFreqCounter = 0;
// const int headSoundFreq = 833; // 1200Hz = 1/1200 * 10^6; // const int headSoundFreq = 833; // 1200Hz = 1/1200 * 10^6;
const int headSoundFreq = 1000000 / options.SoundOnGPIOFreq(); // 1200Hz = 1/1200 * 10^6; const int headSoundFreq = 1000000 / options.SoundOnGPIOFreq(); // 1200Hz = 1/1200 * 10^6;
unsigned char oldHeadDir; unsigned char oldHeadDir = 0;
int resetCount = 0; int resetCount = 0;
bool refreshOutsAfterCPUStep = true; bool refreshOutsAfterCPUStep = true;
unsigned numberOfImages = diskCaddy.GetNumberOfImages(); unsigned numberOfImages = diskCaddy.GetNumberOfImages();
@ -793,8 +804,6 @@ EXIT_TYPE Emulate1541(FileBrowser* fileBrowser)
IEC_Bus::LetSRQBePulledHigh(); IEC_Bus::LetSRQBePulledHigh();
ctBefore = read32(ARM_SYSTIMER_CLO);
//resetWhileEmulating = false; //resetWhileEmulating = false;
selectedViaIECCommands = false; selectedViaIECCommands = false;
@ -802,11 +811,37 @@ EXIT_TYPE Emulate1541(FileBrowser* fileBrowser)
// 0x42c02586 = maniac_mansion_s1[lucasfilm_1989](ntsc).g64 // 0x42c02586 = maniac_mansion_s1[lucasfilm_1989](ntsc).g64
// 0x18651422 = aliens[electric_dreams_1987].g64 // 0x18651422 = aliens[electric_dreams_1987].g64
// 0x2a7f4b77 = zak_mckracken_boot[activision_1988](manual)(!).g64 // 0x2a7f4b77 = zak_mckracken_boot[activision_1988](manual)(!).g64
if (hash == 0x42c02586 || hash == 0x18651422 || hash == 0x2a7f4b77) // 0x97732c3e = maniac_mansion_s1[activision_1987](!).g64
if (hash == 0x42c02586 || hash == 0x18651422 || hash == 0x2a7f4b77 || hash == 0x97732c3e)
{ {
refreshOutsAfterCPUStep = false; refreshOutsAfterCPUStep = false;
} }
// Quickly get through 1541's self test code.
// This will make the emulated 1541 responsive to commands asap.
// During this time we don't need to set outputs.
while (cycleCount < FAST_BOOT_CYCLES)
{
IEC_Bus::ReadEmulationMode1541();
pi1541.m6502.SYNC();
pi1541.m6502.Step();
pi1541.Update();
cycleCount++;
}
// Self test code done. Begin realtime emulation.
#if defined(RPI2)
asm volatile ("mrc p15,0,%0,c9,c13,0" : "=r" (ctBefore));
#else
ctBefore = read32(ARM_SYSTIMER_CLO);
#endif
while (exitReason == EXIT_UNKNOWN) while (exitReason == EXIT_UNKNOWN)
{ {
if (refreshOutsAfterCPUStep) if (refreshOutsAfterCPUStep)
@ -830,44 +865,43 @@ EXIT_TYPE Emulate1541(FileBrowser* fileBrowser)
pi1541.m6502.Step(); // If the CPU reads or writes to the VIA then clk and data can change pi1541.m6502.Step(); // If the CPU reads or writes to the VIA then clk and data can change
if (cycleCount >= FAST_BOOT_CYCLES) // cycleCount is used so we can quickly get through 1541's self test code. This will make the emulated 1541 responsive to commands asap. During this time we don't need to set outputs. //To artificialy delay the outputs later into the phi2's cycle (do this on future Pis that will be faster and perhaps too fast)
//read32(ARM_SYSTIMER_CLO); //Each one of these is > 100ns
//read32(ARM_SYSTIMER_CLO);
//read32(ARM_SYSTIMER_CLO);
// IEC_Bus::ReadEmulationMode1541();
if (refreshOutsAfterCPUStep)
IEC_Bus::RefreshOuts1541(); // Now output all outputs.
IEC_Bus::OutputLED = pi1541.drive.IsLEDOn();
#if defined(RPI3)
if (IEC_Bus::OutputLED ^ oldLED)
{ {
//To artificialy delay the outputs later into the phi2's cycle (do this on future Pis that will be faster and perhaps too fast) SetACTLed(IEC_Bus::OutputLED);
//read32(ARM_SYSTIMER_CLO); //Each one of these is > 100ns oldLED = IEC_Bus::OutputLED;
//read32(ARM_SYSTIMER_CLO); }
//read32(ARM_SYSTIMER_CLO); #endif
// IEC_Bus::ReadEmulationMode1541();
if (refreshOutsAfterCPUStep)
IEC_Bus::RefreshOuts1541(); // Now output all outputs.
IEC_Bus::OutputLED = pi1541.drive.IsLEDOn();
if (IEC_Bus::OutputLED ^ oldLED)
{
SetACTLed(IEC_Bus::OutputLED);
oldLED = IEC_Bus::OutputLED;
}
#if not defined(EXPERIMENTALZERO) #if not defined(EXPERIMENTALZERO)
// Do head moving sound // Do head moving sound
unsigned char headDir = pi1541.drive.GetLastHeadDirection(); unsigned char headDir = pi1541.drive.GetLastHeadDirection();
if (headDir ^ oldHeadDir) // Need to start a new sound? if (headDir != oldHeadDir) // Need to start a new sound?
{
oldHeadDir = headDir;
if (options.SoundOnGPIO())
{ {
oldHeadDir = headDir; headSoundCounter = 1000 * options.SoundOnGPIODuration();
if (options.SoundOnGPIO()) headSoundFreqCounter = headSoundFreq;
{
headSoundCounter = 1000 * options.SoundOnGPIODuration();
headSoundFreqCounter = headSoundFreq;
}
else
{
PlaySoundDMA();
}
} }
else
{
PlaySoundDMA();
}
}
#endif #endif
}
IEC_Bus::ReadGPIOUserInput(3); IEC_Bus::ReadGPIOUserInput(3);
@ -900,32 +934,30 @@ EXIT_TYPE Emulate1541(FileBrowser* fileBrowser)
exitReason = EXIT_AUTOLOAD; exitReason = EXIT_AUTOLOAD;
} }
if (cycleCount < FAST_BOOT_CYCLES) // cycleCount is used so we can quickly get through 1541's self test code. This will make the emulated 1541 responsive to commands asap. #if defined(RPI2)
do // Sync to the 1MHz clock
{
asm volatile ("mrc p15,0,%0,c9,c13,0" : "=r" (ctAfter));
} while ((ctAfter - ctBefore) < clockCycles1MHz);
#else
do // Sync to the 1MHz clock
{ {
cycleCount++;
ctAfter = read32(ARM_SYSTIMER_CLO); ctAfter = read32(ARM_SYSTIMER_CLO);
} unsigned ct = ctAfter - ctBefore;
else if (ct > 1)
{
do // Sync to the 1MHz clock
{ {
ctAfter = read32(ARM_SYSTIMER_CLO); // If this ever occurs then we have taken too long (ie >1us) and lost a cycle.
unsigned ct = ctAfter - ctBefore; // Cycle accuracy is now in jeopardy. If this occurs during critical communication loops then emulation can fail!
if (ct > 1) //DEBUG_LOG("!");
{ }
// If this ever occurs then we have taken too long (ie >1us) and lost a cycle. } while (ctAfter == ctBefore);
// Cycle accuracy is now in jeopardy. If this occurs during critical communication loops then emulation can fail! #endif
//DEBUG_LOG("!");
}
} while (ctAfter == ctBefore);
}
ctBefore = ctAfter; ctBefore = ctAfter;
if (!refreshOutsAfterCPUStep) if (!refreshOutsAfterCPUStep)
{ {
IEC_Bus::ReadEmulationMode1541(); IEC_Bus::ReadEmulationMode1541();
if (cycleCount >= FAST_BOOT_CYCLES) // cycleCount is used so we can quickly get through 1541's self test code. This will make the emulated 1541 responsive to commands asap. During this time we don't need to set outputs. IEC_Bus::RefreshOuts1541(); // Now output all outputs.
IEC_Bus::RefreshOuts1541(); // Now output all outputs.
} }
#if not defined(EXPERIMENTALZERO) #if not defined(EXPERIMENTALZERO)
if (options.SoundOnGPIO() && headSoundCounter > 0) if (options.SoundOnGPIO() && headSoundCounter > 0)
@ -947,11 +979,18 @@ EXIT_TYPE Emulate1541(FileBrowser* fileBrowser)
if (nextDisk) if (nextDisk)
{ {
pi1541.drive.Insert(diskCaddy.PrevDisk()); pi1541.drive.Insert(diskCaddy.PrevDisk());
#if defined(EXPERIMENTALZERO)
diskCaddy.Update();
#endif
} }
else if (prevDisk) else if (prevDisk)
{ {
pi1541.drive.Insert(diskCaddy.NextDisk()); pi1541.drive.Insert(diskCaddy.NextDisk());
#if defined(EXPERIMENTALZERO)
diskCaddy.Update();
#endif
} }
#if not defined(EXPERIMENTALZERO)
else if (inputMappings->directDiskSwapRequest != 0) else if (inputMappings->directDiskSwapRequest != 0)
{ {
for (caddyIndex = 0; caddyIndex < numberOfImagesMax; ++caddyIndex) for (caddyIndex = 0; caddyIndex < numberOfImagesMax; ++caddyIndex)
@ -968,6 +1007,7 @@ EXIT_TYPE Emulate1541(FileBrowser* fileBrowser)
} }
inputMappings->directDiskSwapRequest = 0; inputMappings->directDiskSwapRequest = 0;
} }
#endif
} }
} }
return exitReason; return exitReason;
@ -986,7 +1026,7 @@ EXIT_TYPE Emulate1581(FileBrowser* fileBrowser)
int headSoundFreqCounter = 0; int headSoundFreqCounter = 0;
// const int headSoundFreq = 833; // 1200Hz = 1/1200 * 10^6; // const int headSoundFreq = 833; // 1200Hz = 1/1200 * 10^6;
const int headSoundFreq = 1000000 / options.SoundOnGPIOFreq(); // 1200Hz = 1/1200 * 10^6; const int headSoundFreq = 1000000 / options.SoundOnGPIOFreq(); // 1200Hz = 1/1200 * 10^6;
unsigned int oldTrack; unsigned int oldTrack = 0;
int resetCount = 0; int resetCount = 0;
unsigned numberOfImages = diskCaddy.GetNumberOfImages(); unsigned numberOfImages = diskCaddy.GetNumberOfImages();
@ -1014,7 +1054,11 @@ EXIT_TYPE Emulate1581(FileBrowser* fileBrowser)
IEC_Bus::port = pi1581.CIA.GetPortB(); IEC_Bus::port = pi1581.CIA.GetPortB();
pi1581.Reset(); // will call IEC_Bus::Reset(); pi1581.Reset(); // will call IEC_Bus::Reset();
#if defined(RPI2)
asm volatile ("mrc p15,0,%0,c9,c13,0" : "=r" (ctBefore));
#else
ctBefore = read32(ARM_SYSTIMER_CLO); ctBefore = read32(ARM_SYSTIMER_CLO);
#endif
//resetWhileEmulating = false; //resetWhileEmulating = false;
selectedViaIECCommands = false; selectedViaIECCommands = false;
@ -1023,9 +1067,10 @@ EXIT_TYPE Emulate1581(FileBrowser* fileBrowser)
while (exitReason == EXIT_UNKNOWN) while (exitReason == EXIT_UNKNOWN)
{ {
IEC_Bus::ReadEmulationMode1581();
for (int cycle2MHz = 0; cycle2MHz < 2; ++cycle2MHz) for (int cycle2MHz = 0; cycle2MHz < 2; ++cycle2MHz)
{ {
IEC_Bus::ReadEmulationMode1581();
if (pi1581.m6502.SYNC()) // About to start a new instruction. if (pi1581.m6502.SYNC()) // About to start a new instruction.
{ {
pc = pi1581.m6502.GetPC(); pc = pi1581.m6502.GetPC();
@ -1047,33 +1092,32 @@ EXIT_TYPE Emulate1581(FileBrowser* fileBrowser)
IEC_Bus::RefreshOuts1581(); // Now output all outputs. IEC_Bus::RefreshOuts1581(); // Now output all outputs.
//if (cycleCount >= FAST_BOOT_CYCLES) // cycleCount is used so we can quickly get through 1541's self test code. This will make the emulated 1541 responsive to commands asap. During this time we don't need to set outputs. IEC_Bus::OutputLED = pi1581.IsLEDOn();
#if defined(RPI3)
if (IEC_Bus::OutputLED ^ oldLED)
{ {
IEC_Bus::OutputLED = pi1581.IsLEDOn(); SetACTLed(IEC_Bus::OutputLED);
if (IEC_Bus::OutputLED ^ oldLED) oldLED = IEC_Bus::OutputLED;
{ }
SetACTLed(IEC_Bus::OutputLED); #endif
oldLED = IEC_Bus::OutputLED;
}
#if not defined(EXPERIMENTALZERO) #if not defined(EXPERIMENTALZERO)
// Do head moving sound // Do head moving sound
unsigned int track = pi1581.wd177x.GetCurrentTrack(); unsigned int track = pi1581.wd177x.GetCurrentTrack();
if (track != oldTrack) // Need to start a new sound? if (track != oldTrack) // Need to start a new sound?
{
oldTrack = track;
if (options.SoundOnGPIO())
{ {
oldTrack = track; headSoundCounter = 1000 * options.SoundOnGPIODuration();
if (options.SoundOnGPIO()) headSoundFreqCounter = headSoundFreq;
{ }
headSoundCounter = 1000 * options.SoundOnGPIODuration(); else
headSoundFreqCounter = headSoundFreq; {
} PlaySoundDMA();
else
{
PlaySoundDMA();
}
} }
#endif
} }
#endif
IEC_Bus::ReadGPIOUserInput(3); IEC_Bus::ReadGPIOUserInput(3);
@ -1103,25 +1147,24 @@ EXIT_TYPE Emulate1581(FileBrowser* fileBrowser)
exitReason = EXIT_AUTOLOAD; exitReason = EXIT_AUTOLOAD;
} }
if (cycleCount < FAST_BOOT_CYCLES) // cycleCount is used so we can quickly get through 1541's self test code. This will make the emulated 1541 responsive to commands asap. #if defined(RPI2)
do // Sync to the 1MHz clock
{
asm volatile ("mrc p15,0,%0,c9,c13,0" : "=r" (ctAfter));
} while ((ctAfter - ctBefore) < clockCycles1MHz);
#else
do // Sync to the 1MHz clock
{ {
cycleCount++;
ctAfter = read32(ARM_SYSTIMER_CLO); ctAfter = read32(ARM_SYSTIMER_CLO);
} unsigned ct = ctAfter - ctBefore;
else if (ct > 1)
{
do // Sync to the 1MHz clock
{ {
ctAfter = read32(ARM_SYSTIMER_CLO); // If this ever occurs then we have taken too long (ie >1us) and lost a cycle.
unsigned ct = ctAfter - ctBefore; // Cycle accuracy is now in jeopardy. If this occurs during critical communication loops then emulation can fail!
if (ct > 1) //DEBUG_LOG("!");
{ }
// If this ever occurs then we have taken too long (ie >1us) and lost a cycle. } while (ctAfter == ctBefore);
// Cycle accuracy is now in jeopardy. If this occurs during critical communication loops then emulation can fail! #endif
//DEBUG_LOG("!");
}
} while (ctAfter == ctBefore);
}
ctBefore = ctAfter; ctBefore = ctAfter;
#if not defined(EXPERIMENTALZERO) #if not defined(EXPERIMENTALZERO)
@ -1144,11 +1187,18 @@ EXIT_TYPE Emulate1581(FileBrowser* fileBrowser)
if (nextDisk) if (nextDisk)
{ {
pi1581.Insert(diskCaddy.PrevDisk()); pi1581.Insert(diskCaddy.PrevDisk());
#if defined(EXPERIMENTALZERO)
diskCaddy.Update();
#endif
} }
else if (prevDisk) else if (prevDisk)
{ {
pi1581.Insert(diskCaddy.NextDisk()); pi1581.Insert(diskCaddy.NextDisk());
#if defined(EXPERIMENTALZERO)
diskCaddy.Update();
#endif
} }
#if not defined(EXPERIMENTALZERO)
else if (inputMappings->directDiskSwapRequest != 0) else if (inputMappings->directDiskSwapRequest != 0)
{ {
for (caddyIndex = 0; caddyIndex < numberOfImagesMax; ++caddyIndex) for (caddyIndex = 0; caddyIndex < numberOfImagesMax; ++caddyIndex)
@ -1165,6 +1215,7 @@ EXIT_TYPE Emulate1581(FileBrowser* fileBrowser)
} }
inputMappings->directDiskSwapRequest = 0; inputMappings->directDiskSwapRequest = 0;
} }
#endif
} }
} }