Experimental Pi Zero 1541 loading support.

Experimental Pi Zero 1541 loading support. Disables screens, keyboard, uart, interrupts. Restructured 1541 emulation loop to avoid button polling. Drive reading code optimized.
This commit is contained in:
Alexander Martinelle 2019-08-31 13:26:23 +02:00
parent c71fe6e1dc
commit d39c734151
18 changed files with 525 additions and 49 deletions

View File

@ -13,7 +13,7 @@ LD = $(PREFIX)ld
AR = $(PREFIX)ar
ifeq ($(strip $(RASPPI)),0)
ARCH ?= -march=armv6zk -mtune=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard -DRPIZERO=1
ARCH ?= -march=armv6zk -mtune=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard -DRPIZERO=1 -DEXPERIMENTALZERO=1
CFLAGS += -DRPIZERO=1 -DRASPPI=1
else ifeq ($(strip $(RASPPI)),1)
ARCH ?= -march=armv6zk -mtune=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard -DRPIBPLUS=1

View File

@ -44,6 +44,7 @@ bool DiskCaddy::Empty()
if (disks[index].IsDirty())
{
anyDirty = true;
#if not defined(EXPERIMENTALZERO)
if (screen)
{
x = screen->ScaleX(screenPosXCaddySelections);
@ -67,12 +68,14 @@ bool DiskCaddy::Empty()
screenLCD->PrintText(false, x, y, buffer, RGBA(0xff, 0xff, 0xff, 0xff), red);
screenLCD->SwapBuffers();
}
#endif
}
disks[index].Close();
}
if (anyDirty)
{
#if not defined(EXPERIMENTALZERO)
if (screen)
{
x = screen->ScaleX(screenPosXCaddySelections);
@ -96,6 +99,7 @@ bool DiskCaddy::Empty()
screenLCD->PrintText(false, x, y, buffer, RGBA(0xff, 0xff, 0xff, 0xff), red);
screenLCD->SwapBuffers();
}
#endif
}
disks.clear();
@ -112,6 +116,7 @@ bool DiskCaddy::Insert(const FILINFO* fileInfo, bool readOnly)
FRESULT res = f_open(&fp, fileInfo->fname, FA_READ);
if (res == FR_OK)
{
#if not defined(EXPERIMENTALZERO)
if (screen)
{
x = screen->ScaleX(screenPosXCaddySelections);
@ -135,7 +140,7 @@ bool DiskCaddy::Insert(const FILINFO* fileInfo, bool readOnly)
screenLCD->PrintText(false, x, y, buffer, RGBA(0xff, 0xff, 0xff, 0xff), red);
screenLCD->SwapBuffers();
}
#endif
u32 bytesRead;
SetACTLed(true);
f_read(&fp, DiskImage::readBuffer, READBUFFER_SIZE, &bytesRead);
@ -254,6 +259,7 @@ void DiskCaddy::Display()
unsigned caddyIndex;
int x;
int y;
#if not defined(EXPERIMENTALZERO)
if (screen)
{
x = screen->ScaleX(screenPosXCaddySelections);
@ -281,6 +287,7 @@ void DiskCaddy::Display()
// RGBA BkColour = RGBA(0, 0, 0, 0xFF);
// screenLCD->Clear(BkColour);
//}
#endif
ShowSelectedImage(0);
}
@ -288,6 +295,7 @@ void DiskCaddy::ShowSelectedImage(u32 index)
{
u32 x;
u32 y;
#if not defined(EXPERIMENTALZERO)
if (screen)
{
x = screen->ScaleX(screenPosXCaddySelections) - 16;
@ -343,6 +351,7 @@ void DiskCaddy::ShowSelectedImage(u32 index)
}
screenLCD->SwapBuffers();
}
#endif
}
bool DiskCaddy::Update()
@ -352,6 +361,7 @@ bool DiskCaddy::Update()
u32 caddyIndex = GetSelectedIndex();
if (caddyIndex != oldCaddyIndex)
{
#if not defined(EXPERIMENTALZERO)
if (screen)
{
x = screen->ScaleX(screenPosXCaddySelections) - 16;
@ -366,7 +376,7 @@ bool DiskCaddy::Update()
{
}
#endif
return true;
}
return false;

View File

@ -28,12 +28,17 @@ class DiskCaddy
public:
DiskCaddy()
: selectedIndex(0)
#if not defined(EXPERIMENTALZERO)
, screen(0)
, screenLCD(0)
#endif
{
}
#if defined(EXPERIMENTALZERO)
void SetScreen() { }
#else
void SetScreen(Screen* screen, ScreenBase* screenLCD) { this->screen = screen; this->screenLCD = screenLCD; }
#endif
bool Empty();
@ -55,9 +60,11 @@ public:
DiskImage* PrevDisk()
{
if (selectedIndex == 0u)
selectedIndex += (u32)disks.size()-1;
else
--selectedIndex;
if ((int)selectedIndex < 0)
selectedIndex += (u32)disks.size();
return GetCurrentDisk();
}
@ -99,9 +106,10 @@ private:
std::vector<DiskImage> disks;
u32 selectedIndex;
u32 oldCaddyIndex;
#if not defined(EXPERIMENTALZERO)
ScreenBase* screen;
ScreenBase* screenLCD;
#endif
};
#endif

View File

@ -346,12 +346,19 @@ extern "C"
Drive::Drive() : m_pVIA(0)
{
Reset();
srand(0x811c9dc5U);
#if defined(EXPERIMENTALZERO)
localSeed = 0x811c9dc5U;
#endif
Reset();
}
void Drive::Reset()
{
#if defined(EXPERIMENTALZERO)
LED = false;
cyclesForBit = 0;
#endif
headTrackPos = 18*2; // Start with the head over track 19 (Very later Vorpal ie Cakifornia Games) need to have had the last head movement -ve
CLOCK_SEL_AB = 3; // Track 18 will use speed zone 3 (encoder/decoder (ie UE7Counter) clocked at 1.2307Mhz)
UpdateHeadSectorPosition();
@ -361,7 +368,12 @@ void Drive::Reset()
readShiftRegister = 0;
writeShiftRegister = 0;
UE3Counter = 0;
#if defined(EXPERIMENTALZERO)
ResetEncoderDecoder(18 * 16, 4 * 16);
cyclesLeftForBit = ceil(cyclesPerBit - cyclesForBit);
#else
ResetEncoderDecoder(18.0f, 22.0f);
#endif
newDiskImageQueuedCylesRemaining = DISK_SWAP_CYCLES_DISK_EJECTING + DISK_SWAP_CYCLES_NO_DISK + DISK_SWAP_CYCLES_DISK_INSERTING;
m_pVIA->InputCA1(true); // Reset in read mode
m_pVIA->InputCB1(true);
@ -456,6 +468,12 @@ bool Drive::Update()
// UE6 provides the CPU's clock by dividing the 16Mhz clock by 16.
// UE7 (a 74ls193 4bit counter) counts up on the falling edge of the 16Mhz clock. UE7 drives the Encoder/Decoder clock.
// So we need to simulate 16 cycles for every 1 CPU cycle
#if defined(EXPERIMENTALZERO)
if (writing)
DriveLoopWrite();
else
DriveLoopRead();
#else
for (int cycles = 0; cycles < 16; ++cycles)
{
if (!writing)
@ -534,6 +552,7 @@ bool Drive::Update()
}
}
}
#endif
}
m_pVIA->InputCA1(!SO);
@ -544,3 +563,124 @@ bool Drive::Update()
return dataReady;
}
#if defined(EXPERIMENTALZERO)
#define min(a,b) (((a) < (b)) ? (a) : (b))
#define max(a,b) (((a) > (b)) ? (a) : (b))
void Drive::DriveLoopRead()
{
unsigned int minCycles;
unsigned int cycles = 0;
while (true)
{
minCycles = min(min(cyclesLeftForBit, fluxReversalCyclesLeft), 16 - max(UE7Counter, cycles));
cyclesLeftForBit -= minCycles;
fluxReversalCyclesLeft -= minCycles;
cycles += minCycles;
UE7Counter += minCycles;
if (cycles == 16)
return;
if (cyclesLeftForBit == 0)
{
//which is faster? single loop ceil check or the 3 lines below?
float fn = 2.0f * cyclesPerBit - cyclesForBit;
cyclesLeftForBit = (int)fn;
cyclesForBit = cyclesPerBit;
if (fn != (float)cyclesLeftForBit) {
++cyclesLeftForBit;
++cyclesForBit;
}
//cyclesForBit -= cyclesPerBit;
//cyclesLeftForBit = ceil(cyclesPerBit - cyclesForBit);
//cyclesForBit += cyclesLeftForBit;
if (GetNextBit())
{
ResetEncoderDecoder(18 * 16, /*20 * 16*/ 2 * 16);
}
}
if (fluxReversalCyclesLeft == 0)//Not entirely right, a flux reversal will be skipped if a bit read was going to happen
{
ResetEncoderDecoder(2 * 16, /*25 * 16*/23 * 16); // Trigger a random noise generated zero crossing and start seeing more anywhere between 2us and 25us after this one.
}
if (UE7Counter == 0x10) // The count carry (bit 4) clocks UF4.
{
UE7Counter = CLOCK_SEL_AB; // A and B inputs of UE7 come from the VIA's CLOCK SEL A/B outputs (ie PB5/6) ie preload the encoder/decoder clock for the current density settings.
// The decoder consists of UF4 and UE5A. The ecoder has two outputs, Pin 1 of UE5A is the serial data output and pin 2 of UF4 (output B) is the serial clock output.
++UF4Counter &= 0xf; // Clock and clamp UF4.
// The UD2 read shift register is clocked by serial clock (the rising edge of encoder/decoder's UF4 B output (serial clock))
// - ie on counts 2, 6, 10 and 14 (2 is the only count that outputs a 1 into readShiftRegister as the MSB bits of the count NORed together for other values are 0)
if ((UF4Counter & 0x3) == 2)
{
readShiftRegister <<= 1;
readShiftRegister |= (UF4Counter == 2); // Emulate UE5A and only shift in a 1 when pins 6 (output C) and 7 (output D) (bits 2 and 3 of UF4Counter are 0. ie the first count of the bit cell)
writeShiftRegister <<= 1;
// Note: SYNC can only trigger during reading as R/!W line is one of UC2's inputs.
if (((readShiftRegister & 0x3ff) == 0x3ff)) // if the last 10 bits are 1s then SYNC
{
UE3Counter = 0; // Phase lock on to byte boundary
m_pVIA->GetPortB()->SetInput(0x80, false); // PB7 active low SYNC
}
else
{
m_pVIA->GetPortB()->SetInput(0x80, true); // SYNC not asserted if not following the SYNC bits
UE3Counter++;
}
}
// UC5B (NOR used to invert UF4's output B serial clock) output high when UF4 counts 0,1,4,5,8,9,12 and 13
else if (((UF4Counter & 2) == 0) && (UE3Counter == 8)) // Phase locked on to byte boundary
{
UE3Counter = 0;
SO = (m_pVIA->GetFCR() & m6522::FCR_CA2_OUTPUT_MODE0) != 0; // bit 2 of the FCR indicates "Byte Ready Active" turned on or not.
writeShiftRegister = (u8)(readShiftRegister & 0xff);
m_pVIA->GetPortA()->SetInput(writeShiftRegister);
}
}
};
}
void Drive::DriveLoopWrite()
{
unsigned int minCycles;
unsigned int cycles = 0;
for (unsigned int cycles = 0; cycles != 16; ++cycles)
{
if (++UE7Counter == 0x10) // The count carry (bit 4) clocks UF4.
{
UE7Counter = CLOCK_SEL_AB; // A and B inputs of UE7 come from the VIA's CLOCK SEL A/B outputs (ie PB5/6) ie preload the encoder/decoder clock for the current density settings.
// The decoder consists of UF4 and UE5A. The ecoder has two outputs, Pin 1 of UE5A is the serial data output and pin 2 of UF4 (output B) is the serial clock output.
++UF4Counter &= 0xf; // Clock and clamp UF4.
// The UD2 read shift register is clocked by serial clock (the rising edge of encoder/decoder's UF4 B output (serial clock))
// - ie on counts 2, 6, 10 and 14 (2 is the only count that outputs a 1 into readShiftRegister as the MSB bits of the count NORed together for other values are 0)
if ((UF4Counter & 0x3) == 2)
{
readShiftRegister <<= 1;
readShiftRegister |= (UF4Counter == 2); // Emulate UE5A and only shift in a 1 when pins 6 (output C) and 7 (output D) (bits 2 and 3 of UF4Counter are 0. ie the first count of the bit cell)
SetNextBit((writeShiftRegister & 0x80));
writeShiftRegister <<= 1;
// Note: SYNC can only trigger during reading as R/!W line is one of UC2's inputs.
UE3Counter++;
}
// UC5B (NOR used to invert UF4's output B serial clock) output high when UF4 counts 0,1,4,5,8,9,12 and 13
else if (((UF4Counter & 2) == 0) && (UE3Counter == 8)) // Phase locked on to byte boundary
{
UE3Counter = 0;
SO = (m_pVIA->GetFCR() & m6522::FCR_CA2_OUTPUT_MODE0) != 0; // bit 2 of the FCR indicates "Byte Ready Active" turned on or not.
writeShiftRegister = m_pVIA->GetPortA()->GetOutput();
}
}
}
}
#endif

View File

@ -23,6 +23,17 @@
#include "DiskImage.h"
#include <stdlib.h>
#if defined(EXPERIMENTALZERO)
inline int ceil(float num) {
int inum = (int)num;
if (num == (float)inum) {
return inum;
}
return inum + 1;
}
#endif
class Drive
{
public:
@ -37,6 +48,11 @@ public:
static void OnPortOut(void*, unsigned char status);
bool Update();
#if defined(EXPERIMENTALZERO)
void DriveLoopWrite();
void DriveLoopRead();
#endif
void Insert(DiskImage* diskImage);
inline const DiskImage* GetDiskImage() const { return diskImage; }
void Eject();
@ -49,6 +65,16 @@ public:
inline unsigned char GetLastHeadDirection() const { return lastHeadDirection; } // For simulated head movement sounds
private:
#if defined(EXPERIMENTALZERO)
int32_t localSeed;
inline void ResetEncoderDecoder(unsigned int min, unsigned int /*max*/span)
{
UE7Counter = CLOCK_SEL_AB; // A and B inputs of UE7 come from the VIA's CLOCK SEL A/B outputs (ie PB5/6)
UF4Counter = 0;
localSeed = ((localSeed * 1103515245) + 12345) & 0x7fffffff;
fluxReversalCyclesLeft = (span) * (localSeed >> 11) + min;
}
#else
inline float GenerateRandomFluxReversalTime(float min, float max) { return ((max - min) * ((float)rand() / RAND_MAX)) + min; } // Inputs in micro seconds
inline void ResetEncoderDecoder(float min, float max)
@ -57,6 +83,7 @@ private:
UF4Counter = 0;
randomFluxReversalTime = GenerateRandomFluxReversalTime(min, max);
}
#endif
inline void UpdateHeadSectorPosition()
{
// Disk spins at 300rpm = 5rps so to calculate how many 16Mhz cycles one rotation takes;-
@ -132,13 +159,18 @@ private:
// CB2 (output)
// - R/!W
m6522* m_pVIA;
#if defined(EXPERIMENTALZERO)
unsigned int cyclesLeftForBit;
unsigned int fluxReversalCyclesLeft;
unsigned int UE7Counter;
#else
int UE7Counter;
#endif
float cyclesForBit;
u32 readShiftRegister;
unsigned headTrackPos;
u32 headBitOffset;
float randomFluxReversalTime;
int UE7Counter;
int UF4Counter;
int UE3Counter;
int CLOCK_SEL_AB;

View File

@ -82,6 +82,7 @@ void FileBrowser::BrowsableListView::RefreshLine(u32 entryIndex, u32 x, u32 y, b
if (entryIndex < list->entries.size())
{
FileBrowser::BrowsableList::Entry* entry = &list->entries[entryIndex];
#if not defined(EXPERIMENTALZERO)
if (screen->IsLCD())
{
// pre-clear line on OLED
@ -111,9 +112,10 @@ void FileBrowser::BrowsableListView::RefreshLine(u32 entryIndex, u32 x, u32 y, b
{
snprintf(buffer2, 256, "%s", entry->filImage.fname);
}
#endif
int len = strlen(buffer2 + highlightScrollOffset);
strncpy(buffer1, buffer2 + highlightScrollOffset, sizeof(buffer1));
#if not defined(EXPERIMENTALZERO)
if (!screen->IsLCD())
{
// space pad the remainder of the line (but not on OLED)
@ -121,46 +123,56 @@ void FileBrowser::BrowsableListView::RefreshLine(u32 entryIndex, u32 x, u32 y, b
buffer1[len++] = ' ';
buffer1[columnsMax] = 0;
}
#endif
if (selected)
{
if (entry->filImage.fattrib & AM_DIR)
{
#if not defined(EXPERIMENTALZERO)
screen->PrintText(false, x, y, buffer1, palette[VIC2_COLOUR_INDEX_LBLUE], RGBA(0xff, 0xff, 0xff, 0xff));
#endif
}
else
{
colour = RGBA(0xff, 0, 0, 0xff);
if (entry->filImage.fattrib & AM_RDO)
colour = palette[VIC2_COLOUR_INDEX_RED];
#if not defined(EXPERIMENTALZERO)
screen->PrintText(false, x, y, buffer1, colour, RGBA(0xff, 0xff, 0xff, 0xff));
#endif
}
}
else
{
if (entry->filImage.fattrib & AM_DIR)
{
#if not defined(EXPERIMENTALZERO)
screen->PrintText(false, x, y, buffer1, palette[VIC2_COLOUR_INDEX_LBLUE], BkColour);
#endif
}
else
{
colour = palette[VIC2_COLOUR_INDEX_LGREY];
if (entry->filImage.fattrib & AM_RDO)
colour = palette[VIC2_COLOUR_INDEX_PINK];
#if not defined(EXPERIMENTALZERO)
screen->PrintText(false, x, y, buffer1, colour, BkColour);
#endif
}
}
}
else // line is blank, write spaces
{
memset(buffer1, ' ', columnsMax);
#if not defined(EXPERIMENTALZERO)
screen->PrintText(false, x, y, buffer1, BkColour, BkColour);
#endif
}
}
void FileBrowser::BrowsableListView::Refresh()
{
#if not defined(EXPERIMENTALZERO)
u32 index;
u32 entryIndex;
u32 x = positionX;
@ -185,6 +197,7 @@ void FileBrowser::BrowsableListView::Refresh()
}
screen->SwapBuffers();
#endif
}
void FileBrowser::BrowsableListView::RefreshHighlightScroll()
@ -192,6 +205,7 @@ void FileBrowser::BrowsableListView::RefreshHighlightScroll()
char buffer2[256] = { 0 };
FileBrowser::BrowsableList::Entry* entry = list->current;
#if not defined(EXPERIMENTALZERO)
if (screen->IsMonocrome())
{
if (entry->filImage.fattrib & AM_DIR)
@ -254,6 +268,7 @@ void FileBrowser::BrowsableListView::RefreshHighlightScroll()
screen->RefreshRows(rowIndex, 1);
}
#endif
}
bool FileBrowser::BrowsableListView::CheckBrowseNavigation(bool pageOnly)
@ -499,11 +514,14 @@ FileBrowser::FileBrowser(InputMappings* inputMappings, DiskCaddy* diskCaddy, ROM
, roms(roms)
, deviceID(deviceID)
, displayPNGIcons(displayPNGIcons)
#if not defined(EXPERIMENTALZERO)
, screenMain(screenMain)
, screenLCD(screenLCD)
#endif
, scrollHighlightRate(scrollHighlightRate)
, displayingDevices(false)
{
#if not defined(EXPERIMENTALZERO)
u32 columns = screenMain->ScaleX(80);
u32 rows = (int)(38.0f * screenMain->GetScaleY());
u32 positionX = 0;
@ -530,6 +548,7 @@ FileBrowser::FileBrowser(InputMappings* inputMappings, DiskCaddy* diskCaddy, ROM
folder.AddView(screenLCD, inputMappings, columns, rows, positionX, positionY, true);
}
#endif
}
u32 FileBrowser::Colour(int index)
@ -690,7 +709,7 @@ void FileBrowser::DeviceSwitched()
m_IEC_Commands.SetDisplayingDevices(displayingDevices);
FolderChanged();
}
#if not defined(EXPERIMENTALZERO)
/*
void FileBrowser::RefeshDisplayForBrowsableList(FileBrowser::BrowsableList* browsableList, int xOffset, bool showSelected)
{
@ -769,9 +788,10 @@ void FileBrowser::RefeshDisplayForBrowsableList(FileBrowser::BrowsableList* brow
}
}
*/
#endif
void FileBrowser::RefeshDisplay()
{
#if not defined(EXPERIMENTALZERO)
u32 textColour = Colour(VIC2_COLOUR_INDEX_LGREEN);
u32 bgColour = Colour(VIC2_COLOUR_INDEX_GREY);
char buffer[1024];
@ -780,11 +800,11 @@ void FileBrowser::RefeshDisplay()
screenMain->DrawRectangle(0, 0, (int)screenMain->Width(), 17, bgColour);
screenMain->PrintText(false, 0, 0, buffer, textColour, bgColour);
}
#if not defined(EXPERIMENTALZERO)
//u32 offsetX = screenMain->ScaleX(1024 - 320);
//RefeshDisplayForBrowsableList(&folder, 0);
//RefeshDisplayForBrowsableList(&caddySelections, offsetX, false);
#endif
folder.RefreshViews();
caddySelections.RefreshViews();
@ -796,10 +816,14 @@ void FileBrowser::RefeshDisplay()
u32 y = screenMain->ScaleY(STATUS_BAR_POSITION_Y);
screenMain->PrintText(false, 0, y, folder.searchPrefix, textColour, bgColour);
}
#endif
}
bool FileBrowser::CheckForPNG(const char* filename, FILINFO& filIcon)
{
#if defined(EXPERIMENTALZERO)
return false;
#else
bool foundValid = false;
filIcon.fname[0] = 0;
@ -821,6 +845,7 @@ bool FileBrowser::CheckForPNG(const char* filename, FILINFO& filIcon)
}
}
return foundValid;
#endif
}
void FileBrowser::DisplayPNG(FILINFO& filIcon, int x, int y)
@ -843,6 +868,8 @@ void FileBrowser::DisplayPNG(FILINFO& filIcon, int x, int y)
int h;
int channels_in_file;
stbi_uc* image = stbi_load_from_memory((stbi_uc const*)PNG, bytesRead, &w, &h, &channels_in_file, 4);
#if not defined(EXPERIMENTALZERO)
if (image && (w == PNG_WIDTH && h == PNG_HEIGHT))
{
//DEBUG_LOG("Opened PNG %s w = %d h = %d cif = %d\r\n", fileName, w, h, channels_in_file);
@ -852,6 +879,7 @@ void FileBrowser::DisplayPNG(FILINFO& filIcon, int x, int y)
{
//DEBUG_LOG("Invalid PNG size %d x %d\r\n", w, h);
}
#endif
}
}
else
@ -862,6 +890,7 @@ void FileBrowser::DisplayPNG(FILINFO& filIcon, int x, int y)
void FileBrowser::DisplayPNG()
{
#if not defined(EXPERIMENTALZERO)
if (displayPNGIcons && folder.current)
{
FileBrowser::BrowsableList::Entry* current = folder.current;
@ -869,6 +898,7 @@ void FileBrowser::DisplayPNG()
u32 y = screenMain->ScaleY(666) - PNG_HEIGHT;
DisplayPNG(current->filIcon, x, y);
}
#endif
}
int FileBrowser::IsAtRootOfDevice()
@ -1369,18 +1399,22 @@ void FileBrowser::UpdateInputDiskCaddy()
void FileBrowser::DisplayStatusBar()
{
#if not defined(EXPERIMENTALZERO)
u32 x = 0;
u32 y = screenMain->ScaleY(STATUS_BAR_POSITION_Y);
char bufferOut[128];
snprintf(bufferOut, 128, "LED 0 Motor 0 Track 18.0 ATN 0 DAT 0 CLK 0");
screenMain->PrintText(false, x, y, bufferOut, RGBA(0, 0, 0, 0xff), RGBA(0xff, 0xff, 0xff, 0xff));
#endif
}
void FileBrowser::ClearScreen()
{
#if not defined(EXPERIMENTALZERO)
u32 bgColour = palette[VIC2_COLOUR_INDEX_BLUE];
screenMain->Clear(bgColour);
#endif
}
void FileBrowser::ClearSelections()
@ -1397,6 +1431,7 @@ void FileBrowser::ShowDeviceAndROM()
u32 textColour = RGBA(0, 0, 0, 0xff);
u32 bgColour = RGBA(0xff, 0xff, 0xff, 0xff);
u32 x = 0; // 43 * 8
#if not defined(EXPERIMENTALZERO)
u32 y = screenMain->ScaleY(STATUS_BAR_POSITION_Y) - 20;
snprintf(buffer, 256, "Device %2d %*s\r\n"
@ -1405,10 +1440,12 @@ void FileBrowser::ShowDeviceAndROM()
, roms->ROMNames[roms->currentROMIndex]
);
screenMain->PrintText(false, x, y, buffer, textColour, bgColour);
#endif
}
void FileBrowser::DisplayDiskInfo(DiskImage* diskImage, const char* filenameForIcon)
{
#if not defined(EXPERIMENTALZERO)
// Ideally we should not have to load the entire disk to read the directory.
static const char* fileTypes[]=
{
@ -1420,7 +1457,11 @@ void FileBrowser::DisplayDiskInfo(DiskImage* diskImage, const char* filenameForI
char name[17] = { 0 };
unsigned char buffer[260] = { 0 };
int charIndex;
#if defined(EXPERIMENTALZERO)
u32 fontHeight = 16;
#else
u32 fontHeight = screenMain->GetFontHeightDirectoryDisplay();
#endif
u32 x = 0;
u32 y = 0;
char bufferOut[128] = { 0 };
@ -1626,6 +1667,7 @@ void FileBrowser::DisplayDiskInfo(DiskImage* diskImage, const char* filenameForI
DisplayPNG(filIcon, x, y);
}
}
#endif
}
void FileBrowser::SelectAutoMountImage(const char* image)

View File

@ -63,7 +63,9 @@ public:
BrowsableListView(BrowsableList* list, InputMappings* inputMappings, ScreenBase* screen, u32 columns, u32 rows, u32 positionX, u32 positionY, bool lcdPgUpDown)
: list(list)
, inputMappings(inputMappings)
#if not defined(EXPERIMENTALZERO)
, screen(screen)
#endif
, columns(columns)
, rows(rows)
, positionX(positionX)
@ -84,8 +86,9 @@ public:
BrowsableList* list;
u32 offset;
InputMappings* inputMappings;
#if not defined(EXPERIMENTALZERO)
ScreenBase* screen;
#endif
u32 columns;
u32 rows;
u32 positionX;
@ -212,12 +215,14 @@ private:
void RefreshFolderEntries();
void UpdateInputFolders();
#if not defined(EXPERIMENTALZERO)
//void UpdateInputDiskCaddy();
#endif
void UpdateCurrentHighlight();
#if not defined(EXPERIMENTALZERO)
//void RefeshDisplayForBrowsableList(FileBrowser::BrowsableList* browsableList, int xOffset, bool showSelected = true);
#endif
bool FillCaddyWithSelections();
bool AddToCaddy(FileBrowser::BrowsableList::Entry* current);
@ -249,10 +254,10 @@ private:
bool buttonChangedROMDevice;
BrowsableList caddySelections;
#if not defined(EXPERIMENTALZERO)
ScreenBase* screenMain;
ScreenBase* screenLCD;
#endif
float scrollHighlightRate;
bool displayingDevices;

View File

@ -1,3 +1,4 @@
// Pi1541 - A Commodore 1541 disk drive emulator
// Copyright(C) 2018 Stephen White
//
@ -217,9 +218,11 @@ void InputMappings::CheckButtonsEmulationMode()
bool InputMappings::CheckKeyboardBrowseMode()
{
#if not defined(EXPERIMENTALZERO)
Keyboard* keyboard = Keyboard::Instance();
#endif
keyboardFlags = 0;
#if not defined(EXPERIMENTALZERO)
keyboardNumLetter = 0;
if (!keyboard->CheckChanged())
{
@ -305,12 +308,13 @@ bool InputMappings::CheckKeyboardBrowseMode()
}
}
}
#endif
return keyboardFlags != 0;
}
void InputMappings::CheckKeyboardEmulationMode(unsigned numberOfImages, unsigned numberOfImagesMax)
{
#if not defined(EXPERIMENTALZERO)
Keyboard* keyboard = Keyboard::Instance();
keyboardFlags = 0;
@ -341,5 +345,6 @@ void InputMappings::CheckKeyboardEmulationMode(unsigned numberOfImages, unsigned
directDiskSwapRequest |= (1 << index);
}
}
#endif
}

View File

@ -103,21 +103,37 @@ public:
keyboardBrowseLCDScreen = value;
}
#if defined(EXPERIMENTALZERO)
inline bool Exit()
{
return KeyboardFlag(ESC_FLAG)/* | UartFlag(ESC_FLAG)*/ | ButtonFlag(ESC_FLAG);
return /*KeyboardFlag(ESC_FLAG) | UartFlag(ESC_FLAG) |*/ ButtonFlag(ESC_FLAG);
}
inline bool NextDisk()
{
return KeyboardFlag(NEXT_FLAG)/* | UartFlag(NEXT_FLAG)*/ | ButtonFlag(NEXT_FLAG);
return /*KeyboardFlag(NEXT_FLAG) | UartFlag(NEXT_FLAG) |*/ ButtonFlag(NEXT_FLAG);
}
inline bool PrevDisk()
{
return KeyboardFlag(PREV_FLAG)/* | UartFlag(PREV_FLAG)*/ | ButtonFlag(PREV_FLAG);
return /*KeyboardFlag(PREV_FLAG) | UartFlag(PREV_FLAG) |*/ ButtonFlag(PREV_FLAG);
}
#else
inline bool Exit()
{
return KeyboardFlag(ESC_FLAG) /*| UartFlag(ESC_FLAG) |*/ ButtonFlag(ESC_FLAG);
}
inline bool NextDisk()
{
return KeyboardFlag(NEXT_FLAG) /*| UartFlag(NEXT_FLAG) |*/ ButtonFlag(NEXT_FLAG);
}
inline bool PrevDisk()
{
return KeyboardFlag(PREV_FLAG) /*| UartFlag(PREV_FLAG) |*/ ButtonFlag(PREV_FLAG);
}
#endif
inline bool AutoLoad() { return KeyboardFlag(AUTOLOAD_FLAG); }
inline bool FakeReset() { return KeyboardFlag(FAKERESET_FLAG); }

View File

@ -15,7 +15,7 @@
//
// You should have received a copy of the GNU General Public License
// along with Pi1541. If not, see <http://www.gnu.org/licenses/>.
#if not defined(EXPERIMENTALZERO)
#include "Keyboard.h"
#include <string.h>
#include <uspi.h>
@ -156,3 +156,4 @@ Keyboard::Keyboard()
memset(keyRepeatCount, 0, sizeof(keyRepeatCount));
USPiKeyboardRegisterKeyStatusHandlerRaw(KeyPressedHandlerRaw);
}
#endif

View File

@ -24,6 +24,7 @@ extern "C"
{
#include <uspi/usbkeyboard.h>
}
#if not defined(EXPERIMENTALZERO)
#define MAX_KEYS 0x7f
@ -356,3 +357,4 @@ public:
static Keyboard* instance;
};
#endif
#endif

View File

@ -129,21 +129,29 @@ void Screen::Open(u32 widthDesired, u32 heightDesired, u32 colourDepth)
void Screen::PlotPixel32(u32 pixel_offset, RGBA Colour)
{
#if not defined(EXPERIMENTALZERO)
*((volatile RGBA*)&framebuffer[pixel_offset]) = Colour;
#endif
}
void Screen::PlotPixel24(u32 pixel_offset, RGBA Colour)
{
#if not defined(EXPERIMENTALZERO)
framebuffer[pixel_offset++] = BLUE(Colour);
framebuffer[pixel_offset++] = GREEN(Colour);
framebuffer[pixel_offset++] = RED(Colour);
#endif
}
void Screen::PlotPixel16(u32 pixel_offset, RGBA Colour)
{
#if not defined(EXPERIMENTALZERO)
*(unsigned short*)&framebuffer[pixel_offset] = ((RED(Colour) >> 3) << 11) | ((GREEN(Colour) >> 2) << 5) | (BLUE(Colour) >> 3);
#endif
}
void Screen::PlotPixel8(u32 pixel_offset, RGBA Colour)
{
#if not defined(EXPERIMENTALZERO)
framebuffer[pixel_offset++] = RED(Colour);
#endif
}
void Screen::DrawRectangle(u32 x1, u32 y1, u32 x2, u32 y2, RGBA colour)

View File

@ -236,7 +236,9 @@ int wait(int *status)
void outbyte(char b)
{
#ifndef EXPERIMENTALZERO
RPI_AuxMiniUartWrite(b);
#endif
}
/* Write to a file. libc subroutines will use this system routine for output to

View File

@ -335,10 +335,10 @@ void IEC_Bus::RefreshOuts1541(void)
if (OutputLED) set |= 1 << PIGPIO_OUT_LED;
else clear |= 1 << PIGPIO_OUT_LED;
#if not defined(EXPERIMENTALZERO)
if (OutputSound) set |= 1 << PIGPIO_OUT_SOUND;
else clear |= 1 << PIGPIO_OUT_SOUND;
#endif
if (oldClears != clear)
{
write32(ARM_GPIO_GPCLR0, clear);

View File

@ -135,6 +135,7 @@ enum PIGPIOMasks
PIGPIO_MASK_IN_BUTTON3 = 1 << PIGPIO_IN_BUTTON3,
PIGPIO_MASK_IN_BUTTON4 = 1 << PIGPIO_IN_BUTTON4,
PIGPIO_MASK_IN_BUTTON5 = 1 << PIGPIO_IN_BUTTON5,
PIGPIO_MASK_ANY_BUTTON = PIGPIO_MASK_IN_BUTTON1 | PIGPIO_MASK_IN_BUTTON2 | PIGPIO_MASK_IN_BUTTON3 | PIGPIO_MASK_IN_BUTTON4 | PIGPIO_MASK_IN_BUTTON5
};
static const unsigned ButtonPinFlags[5] = { PIGPIO_MASK_IN_BUTTON1, PIGPIO_MASK_IN_BUTTON2, PIGPIO_MASK_IN_BUTTON3, PIGPIO_MASK_IN_BUTTON4, PIGPIO_MASK_IN_BUTTON5 };
@ -316,6 +317,13 @@ public:
RefreshOuts1581();
}
#if defined(EXPERIMENTALZERO)
static inline bool AnyButtonPressed()
{
return ((gplev0 & PIGPIO_MASK_ANY_BUTTON) != PIGPIO_MASK_ANY_BUTTON);
}
#endif
static inline void UpdateButton(int index, unsigned gplev0)
{
bool inputcurrent = (gplev0 & ButtonPinFlags[index]) == 0;

View File

@ -39,16 +39,19 @@ void InterruptSystemInitialize()
write32(ARM_IC_IRQ_PENDING_2, read32(ARM_IC_IRQ_PENDING_2));
DataMemBarrier();
#ifndef EXPERIMENTALZERO
EnableInterrupts();
#endif
}
void InterruptSystemConnectIRQ(unsigned IRQIndex, IRQHandler* handler, void* param)
{
#ifndef EXPERIMENTALZERO
IRQHandlers[IRQIndex] = handler;
Params[IRQIndex] = param;
InterruptSystemEnableIRQ(IRQIndex);
#endif
}
void InterruptSystemDisconnectIRQ(unsigned IRQIndex)
@ -61,10 +64,12 @@ void InterruptSystemDisconnectIRQ(unsigned IRQIndex)
void InterruptSystemEnableIRQ(unsigned IRQIndex)
{
//DEBUG_LOG("InterruptSystemEnableIRQ %d\r\n", IRQIndex);
#ifndef EXPERIMENTALZERO
DEBUG_LOG("InterruptSystemEnableIRQ %d\r\n", IRQIndex);
DataMemBarrier();
write32(ARM_IC_IRQS_ENABLE(IRQIndex), ARM_IRQ_MASK(IRQIndex));
DataMemBarrier();
#endif
}
void InterruptSystemDisableIRQ(unsigned IRQIndex)
@ -110,11 +115,13 @@ void InterruptHandler(void)
if (pendValue & IRQIndexMask)
{
#ifndef EXPERIMENTALZERO
IRQHandler* pHandler = IRQHandlers[IRQIndex];
if (pHandler != 0)
(*pHandler)(Params[IRQIndex]);
else
#endif
InterruptSystemDisableIRQ(IRQIndex);
}
}
@ -127,11 +134,13 @@ void InterruptHandler(void)
if (pendValue & IRQIndexMask)
{
#ifndef EXPERIMENTALZERO
IRQHandler* pHandler = IRQHandlers[IRQIndex];
if (pHandler != 0)
(*pHandler)(Params[IRQIndex]);
else
#endif
InterruptSystemDisableIRQ(IRQIndex);
}
}
@ -144,11 +153,13 @@ void InterruptHandler(void)
if (pendValue & IRQIndexMask)
{
#ifndef EXPERIMENTALZERO
IRQHandler* pHandler = IRQHandlers[IRQIndex];
if (pHandler != 0)
(*pHandler)(Params[IRQIndex]);
else
#endif
InterruptSystemDisableIRQ(IRQIndex);
}
}

View File

@ -110,7 +110,9 @@ const char* fileBrowserSelectedName;
u8 deviceID = 8;
IEC_Commands m_IEC_Commands;
InputMappings* inputMappings;
#if not defined(EXPERIMENTALZERO)
Keyboard* keyboard;
#endif
bool USBKeyboardDetected = false;
//bool resetWhileEmulating = false;
bool selectedViaIECCommands = false;
@ -225,8 +227,9 @@ void InitialiseHardware()
RPI_TouchInit();
#endif
#if not defined(EXPERIMENTALZERO)
screen.Open(screenWidth, screenHeight, 16);
#endif
RPI_PropertyInit();
RPI_PropertyAddTag(TAG_GET_MAX_CLOCK_RATE, ARM_CLK_ID);
RPI_PropertyProcess();
@ -244,7 +247,7 @@ void InitialiseHardware()
void InitialiseLCD()
{
#if not defined(EXPERIMENTALZERO)
FILINFO filLcdIcon;
int i2cBusMaster = options.I2CBusMaster();
@ -306,6 +309,7 @@ void InitialiseLCD()
screenLCD->RefreshScreen();
}
else
#endif
{
screenLCD = 0;
}
@ -326,6 +330,7 @@ void InitialiseLCD()
// Care must be taken not to crowd out the shared cache with core1 as this could slow down core1 so that it no longer can perform its duties in the 1us timings it requires.
void UpdateScreen()
{
#if not defined(EXPERIMENTALZERO)
bool oldLED = false;
bool oldMotor = false;
bool oldATN = false;
@ -555,6 +560,7 @@ void UpdateScreen()
// Go back to sleep. The USB irq will wake us up again.
__asm ("WFE");
}
#endif
}
static bool Snoop(u8 a)
@ -621,7 +627,7 @@ EmulatingMode BeginEmulating(FileBrowser* fileBrowser, const char* filenameForIc
inputMappings->WaitForClearButtons();
return IEC_COMMANDS;
}
#if not defined(EXPERIMENTALZERO)
static u32* dmaSound;
struct DMA_ControlBlock
@ -646,13 +652,15 @@ DMA_ControlBlock dmaSoundCB =
0,//&dmaSoundCB,
0, 0
};
#endif
static void PlaySoundDMA()
{
#if not defined(EXPERIMENTALZERO)
write32(PWM_DMAC, PWM_ENAB + 0x0001);
write32(DMA_ENABLE, 1); // DMA_EN0
write32(DMA0_BASE + DMA_CONBLK_AD, (u32)&dmaSoundCB);
write32(DMA0_BASE + DMA_CS, DMA_ACTIVE);
#endif
}
void GlobalSetDeviceID(u8 id)
@ -684,6 +692,157 @@ void CheckAutoMountImage(EXIT_TYPE reset_reason , FileBrowser* fileBrowser)
}
}
EXIT_TYPE Emulate1541(FileBrowser* fileBrowser)
{
bool oldLED = false;
unsigned ctBefore = 0;
unsigned ctAfter = 0;
int cycleCount = 0;
unsigned caddyIndex;
int headSoundCounter = 0;
int headSoundFreqCounter = 0;
// const int headSoundFreq = 833; // 1200Hz = 1/1200 * 10^6;
const int headSoundFreq = 1000000 / options.SoundOnGPIOFreq(); // 1200Hz = 1/1200 * 10^6;
unsigned char oldHeadDir;
int resetCount = 0;
bool refreshOutsAfterCPUStep = true;
unsigned numberOfImages = diskCaddy.GetNumberOfImages();
unsigned numberOfImagesMax = numberOfImages;
if (numberOfImagesMax > 10)
numberOfImagesMax = 10;
core0RefreshingScreen.Acquire();
diskCaddy.Display();
core0RefreshingScreen.Release();
inputMappings->directDiskSwapRequest = 0;
// Force an update on all the buttons now before we start emulation mode.
IEC_Bus::ReadBrowseMode();
bool extraRAM = options.GetExtraRAM();
DataBusReadFn dataBusRead = extraRAM ? read6502ExtraRAM : read6502;
DataBusWriteFn dataBusWrite = extraRAM ? write6502ExtraRAM : write6502;
M6502& m6502 = pi1541.m6502;
m6502.SetBusFunctions(dataBusRead, dataBusWrite);
IEC_Bus::VIA = &pi1541.VIA[0];
IEC_Bus::port = pi1541.VIA[0].GetPortB();
pi1541.Reset(); // will call IEC_Bus::Reset();
IEC_Bus::OutputLED = false;
IEC_Bus::LetSRQBePulledHigh();
float avgTimer = 0.0f;
ctBefore = read32(ARM_SYSTIMER_CLO);
//resetWhileEmulating = false;
selectedViaIECCommands = false;
u32 hash = pi1541.drive.GetDiskImage()->GetHash();
// 0x42c02586 = maniac_mansion_s1[lucasfilm_1989](ntsc).g64
// 0x18651422 = aliens[electric_dreams_1987].g64
// 0x2a7f4b77 = zak_mckracken_boot[activision_1988](manual)(!).g64
if (hash == 0x42c02586 || hash == 0x18651422 || hash == 0x2a7f4b77)
{
refreshOutsAfterCPUStep = false;
}
while (cycleCount < FAST_BOOT_CYCLES)
{
m6502.Step();
pi1541.Update();
cycleCount++;
IEC_Bus::ReadEmulationMode1541();
}
bool buttonState = false;
bool prevButtonState = false;
while (true)
{
if (m6502.SYNC()) // About to start a new instruction.
{
pc = m6502.GetPC();
// See if the emulated cpu is executing CD:_ (ie back out of emulated image)
if (snoopIndex == 0 && (pc == SNOOP_CD_CBM || pc == SNOOP_CD_JIFFY_BOTH || pc == SNOOP_CD_JIFFY_DRIVEONLY)) snoopPC = pc;
if (pc == snoopPC)
{
if (Snoop(m6502.GetA()))
{
return EXIT_CD;
}
}
}
m6502.Step(); // If the CPU reads or writes to the VIA then clk and data can change
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;
}
pi1541.Update();
if (__builtin_expect(IEC_Bus::IsReset(), false))
resetCount++;
else
resetCount = 0;
if ((resetCount > 10))
{
return EXIT_RESET;
}
buttonState = IEC_Bus::AnyButtonPressed();
if (__builtin_expect(buttonState, false))
{
IEC_Bus::ReadButtonsEmulationMode();
inputMappings->CheckButtonsEmulationMode();
if (numberOfImages > 1)
{
bool nextDisk = inputMappings->NextDisk();
bool prevDisk = inputMappings->PrevDisk();
if (nextDisk)
{
pi1541.drive.Insert(diskCaddy.PrevDisk());
}
if (prevDisk)
{
pi1541.drive.Insert(diskCaddy.NextDisk());
}
}
bool exitEmulation = inputMappings->Exit();
if (exitEmulation)
return EXIT_KEYBOARD;
}
else if (__builtin_expect(!buttonState & prevButtonState, false))
{
IEC_Bus::ReadButtonsEmulationMode();
inputMappings->CheckButtonsEmulationMode();
}
prevButtonState = buttonState;
do
{
ctAfter = read32(ARM_SYSTIMER_CLO);
} while (ctAfter == ctBefore); // Sync to the 1MHz clock
ctBefore = ctAfter;
IEC_Bus::ReadEmulationMode1541();
IEC_Bus::RefreshOuts1541(); // Now output all outputs.
}
return EXIT_UNKNOWN;
}
#if not defined(EXPERIMENTALZERO)
EXIT_TYPE Emulate1541(FileBrowser* fileBrowser)
{
EXIT_TYPE exitReason = EXIT_UNKNOWN;
@ -891,6 +1050,7 @@ EXIT_TYPE Emulate1541(FileBrowser* fileBrowser)
return exitReason;
}
EXIT_TYPE Emulate1581(FileBrowser* fileBrowser)
{
EXIT_TYPE exitReason = EXIT_UNKNOWN;
@ -1075,16 +1235,23 @@ EXIT_TYPE Emulate1581(FileBrowser* fileBrowser)
}
return exitReason;
}
#endif
void emulator()
{
#if not defined(EXPERIMENTALZERO)
Keyboard* keyboard = Keyboard::Instance();
#endif
FileBrowser* fileBrowser;
EXIT_TYPE exitReason = EXIT_UNKNOWN;
roms.lastManualSelectedROMIndex = 0;
#if defined(EXPERIMENTALZERO)
diskCaddy.SetScreen();
#else
diskCaddy.SetScreen(&screen, screenLCD);
#endif
fileBrowser = new FileBrowser(inputMappings, &diskCaddy, &roms, &deviceID, options.DisplayPNGIcons(), &screen, screenLCD, options.ScrollHighlightRate());
fileBrowser->DisplayRoot();
pi1541.Initialise();
@ -1095,7 +1262,6 @@ void emulator()
m_IEC_Commands.SetNewDiskType(options.GetNewDiskType());
emulating = IEC_COMMANDS;
while (1)
{
if (emulating == IEC_COMMANDS)
@ -1124,8 +1290,9 @@ void emulator()
selectedViaIECCommands = false;
inputMappings->Reset();
#if not defined(EXPERIMENTALZERO)
inputMappings->SetKeyboardBrowseLCDScreen(screenLCD && options.KeyboardBrowseLCDScreen());
#endif
fileBrowser->ShowDeviceAndROM();
if (!options.GetDisableSD2IECCommands())
@ -1149,7 +1316,6 @@ void emulator()
break;
case IEC_Commands::NONE:
fileBrowser->Update();
// Check selections made via FileBrowser
if (fileBrowser->SelectionsMade())
emulating = BeginEmulating(fileBrowser, fileBrowser->LastSelectionName());
@ -1210,7 +1376,7 @@ void emulator()
fileBrowser->ShowDeviceAndROM();
break;
case IEC_Commands::DEVICE_SWITCHED:
DEBUG_LOG("DEVICE_SWITCHED\r\n");
DEBUG_LOG("DECIVE_SWITCHED\r\n");
fileBrowser->DeviceSwitched();
break;
default:
@ -1234,8 +1400,10 @@ void emulator()
{
if (emulating == EMULATING_1541)
exitReason = Emulate1541(fileBrowser);
#if not defined(EXPERIMENTALZERO)
else
exitReason = Emulate1581(fileBrowser);
#endif
DEBUG_LOG("Exited emulation\r\n");
@ -1320,6 +1488,7 @@ static bool AttemptToLoadROM(char* ROMName)
static void DisplayLogo()
{
#if not defined(EXPERIMENTALZERO)
int w;
int h;
int channels_in_file;
@ -1329,6 +1498,7 @@ static void DisplayLogo()
snprintf(tempBuffer, tempBufferSize, "V%d.%02d", versionMajor, versionMinor);
screen.PrintText(false, 20, 180, tempBuffer, FileBrowser::Colour(VIC2_COLOUR_INDEX_BLUE));
#endif
}
static void LoadOptions()
@ -1354,6 +1524,7 @@ static void LoadOptions()
void DisplayOptions(int y_pos)
{
#if not defined(EXPERIMENTALZERO)
// print confirmation of parsed options
snprintf(tempBuffer, tempBufferSize, "ignoreReset = %d\r\n", options.IgnoreReset());
screen.PrintText(false, 0, y_pos += 16, tempBuffer, COLOUR_WHITE, COLOUR_BLACK);
@ -1375,10 +1546,12 @@ void DisplayOptions(int y_pos)
screen.PrintText(false, 0, y_pos += 16, tempBuffer, COLOUR_WHITE, COLOUR_BLACK);
snprintf(tempBuffer, tempBufferSize, "AutoBaseName = %s\r\n", options.GetAutoBaseName());
screen.PrintText(false, 0, y_pos += 16, tempBuffer, COLOUR_WHITE, COLOUR_BLACK);
#endif
}
void DisplayI2CScan(int y_pos)
{
#if not defined(EXPERIMENTALZERO)
int BSCMaster = options.I2CBusMaster();
snprintf(tempBuffer, tempBufferSize, "Scanning i2c bus %d ...\r\n", BSCMaster);
@ -1401,6 +1574,7 @@ void DisplayI2CScan(int y_pos)
ptr += snprintf (tempBuffer+ptr, tempBufferSize-ptr, "Nothing");
screen.PrintText(false, 0, y_pos+16, tempBuffer, COLOUR_WHITE, COLOUR_BLACK);
#endif
}
static void CheckOptions()
@ -1522,6 +1696,7 @@ static void CheckOptions()
}
}
if (roms.ROMValid[0] == false && !(AttemptToLoadROM("d1541.rom") || AttemptToLoadROM("dos1541") || AttemptToLoadROM("d1541II") || AttemptToLoadROM("Jiffy.bin")))
{
snprintf(tempBuffer, tempBufferSize, "No ROM file found!\r\nPlease copy a valid 1541 ROM file in the root folder of the SD card.\r\nThe file needs to be called 'dos1541'.");
@ -1563,6 +1738,7 @@ bool SwitchDrive(const char* drive)
void UpdateFirmwareToSD()
{
#if not defined(EXPERIMENTALZERO)
const char* firmwareName = "kernel.img";
DIR dir;
FILINFO filInfo;
@ -1658,10 +1834,12 @@ void UpdateFirmwareToSD()
f_chdir(cwd);
}
}
#endif
}
void DisplayMessage(int x, int y, bool LCD, const char* message, u32 textColour, u32 backgroundColour)
{
#if not defined(EXPERIMENTALZERO)
char buffer[256] = { 0 };
if (!LCD)
@ -1684,6 +1862,7 @@ void DisplayMessage(int x, int y, bool LCD, const char* message, u32 textColour,
core0RefreshingScreen.Release();
}
#endif
}
extern "C"
@ -1699,8 +1878,9 @@ extern "C"
disk_setEMM(&m_EMMC);
f_mount(&fileSystemSD, "SD:", 1);
#if not defined(EXPERIMENTALZERO)
RPI_AuxMiniUartInit(115200, 8);
#endif
LoadOptions();
InitialiseHardware();
@ -1712,7 +1892,7 @@ extern "C"
DisplayLogo();
InitialiseLCD();
#if not defined(EXPERIMENTALZERO)
int y_pos = 184;
snprintf(tempBuffer, tempBufferSize, "Copyright(C) 2018 Stephen White");
screen.PrintText(false, 0, y_pos+=16, tempBuffer, COLOUR_WHITE, COLOUR_BLACK);
@ -1727,10 +1907,12 @@ extern "C"
if (options.ShowOptions())
DisplayOptions(y_pos+=32);
#endif
//if (!options.QuickBoot())
// IEC_Bus::WaitMicroSeconds(3 * 1000000);
//IEC_Bus::WaitMicroSeconds(3 * 1000000);
InterruptSystemInitialize();
#if not defined(EXPERIMENTALZERO)
TimerSystemInitialize();
USPiInitialize();
@ -1752,6 +1934,7 @@ extern "C"
// DEBUG_LOG("Mouse found\r\n");
keyboard = new Keyboard();
#endif
inputMappings = new InputMappings();
//USPiMouseRegisterStatusHandler(MouseHandler);
@ -1762,7 +1945,7 @@ extern "C"
IEC_Bus::SetInvertIECInputs(options.InvertIECInputs());
IEC_Bus::SetInvertIECOutputs(options.InvertIECOutputs());
IEC_Bus::SetIgnoreReset(options.IgnoreReset());
#if not defined(EXPERIMENTALZERO)
if (!options.SoundOnGPIO())
{
dmaSound = (u32*)malloc(Sample_bin_size * 4);
@ -1786,7 +1969,7 @@ extern "C"
if (SwitchDrive("USB01:"))
UpdateFirmwareToSD();
}
#endif
f_chdir("/1541");
m_IEC_Commands.SetStarFileName(options.GetStarFileName());
@ -1795,12 +1978,11 @@ extern "C"
pi1541.drive.SetVIA(&pi1541.VIA[1]);
pi1541.VIA[0].GetPortB()->SetPortOut(0, IEC_Bus::PortB_OnPortOut);
IEC_Bus::Initialise();
#if not defined(EXPERIMENTALZERO)
if (screenLCD)
screenLCD->ClearInit(0);
#endif
#ifdef HAS_MULTICORE
start_core(3, _spin_core);
start_core(2, _spin_core);

View File

@ -63,7 +63,11 @@ public:
inline unsigned int QuickBoot() const { return quickBoot; }
inline unsigned int ShowOptions() const { return showOptions; }
inline unsigned int DisplayPNGIcons() const { return displayPNGIcons; }
#if defined(EXPERIMENTALZERO)
inline unsigned int SoundOnGPIO() const { return false; }
#else
inline unsigned int SoundOnGPIO() const { return soundOnGPIO; }
#endif
inline unsigned int SoundOnGPIODuration() const { return soundOnGPIODuration; }
inline unsigned int SoundOnGPIOFreq() const { return soundOnGPIOFreq; }
inline unsigned int SplitIECLines() const { return splitIECLines; }