Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Board emu rework #10

Merged
merged 34 commits into from
Sep 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
52b0154
Return an incrementing value for PIO0 SM0_ADDR
Daft-Freak Jul 10, 2023
df8cc31
Add stub PIO class
Daft-Freak Aug 19, 2023
006917f
"handle" some more PIO regs
Daft-Freak Aug 19, 2023
68542e6
Start implementing PIO tx FIFO
Daft-Freak Aug 20, 2023
d776cb8
Add an update callback to PIO
Daft-Freak Aug 21, 2023
9075430
Avoid syncing PIO for IO for now
Daft-Freak Aug 21, 2023
51efa68
Update DMA clock during updates
Daft-Freak Aug 21, 2023
ec5e11d
Getters for PIO stuff
Daft-Freak Aug 21, 2023
76b9c02
Move picosystem display hacks from DMA code to a PIO update callback
Daft-Freak Aug 21, 2023
4b1d35b
Move tufty display hacks out of DMA code
Daft-Freak Aug 21, 2023
9b7c8a8
Rename board -> boardId
Daft-Freak Aug 21, 2023
dcd66b8
Start adding board class
Daft-Freak Aug 21, 2023
9c58617
Add more audio methods to board
Daft-Freak Aug 21, 2023
3e14b96
Pass events to boards
Daft-Freak Aug 21, 2023
da47bb6
Add log component for board
Daft-Freak Aug 21, 2023
209edcf
Refactor picosystem code into a board class
Daft-Freak Aug 21, 2023
748229b
Refactor tufty code into a board class
Daft-Freak Aug 22, 2023
251dc59
Move screen data into boards
Daft-Freak Aug 23, 2023
e29471e
Move screen format into boards
Daft-Freak Aug 23, 2023
b77e45b
Delete board later
Daft-Freak Aug 23, 2023
ed29ee7
Handle picosystem-sdk hires mode
Daft-Freak Aug 23, 2023
27d6933
Partially revert picosystem button handling
Daft-Freak Aug 24, 2023
26acbf4
Remove fixed FIXME
Daft-Freak Sep 5, 2023
2457e68
Add some display command parsing to PicoSystem code
Daft-Freak Sep 5, 2023
74f2725
Set display clock from FRCTRL2
Daft-Freak Sep 5, 2023
927144c
Refactor a little to allow re-creating texture later
Daft-Freak Sep 5, 2023
016e91b
Use display commands for format
Daft-Freak Sep 5, 2023
969e788
Apply picosystem-sdk-specific pio hacks based on format
Daft-Freak Sep 5, 2023
bd96370
Remove picosystem sdk flag
Daft-Freak Sep 5, 2023
f0e41a1
Handle window for picosystem display
Daft-Freak Sep 5, 2023
527cced
Avoid entirely emptying FIFO while DMA is active
Daft-Freak Sep 6, 2023
cbffb81
More DMA sync
Daft-Freak Sep 6, 2023
b504799
Improve TXSTALL handling slightly
Daft-Freak Sep 6, 2023
722090b
Make sure PIO hook gets called at least once
Daft-Freak Sep 6, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ This is mostly an _extremely hacky_ PicoSystem emulator.
./DERP_SDL file.uf2
```

(To run uf2s built with the PicoSystem SDK add `--picosystem-sdk` before the file to apply some workarounds)
(To run some uf2s built with the PicoSystem SDK add `--board pimoroni_picosystem` before the file to override the board value)

## Bootrom
A copy of the RP2040 bootrom is required in bootrom.bin.
Expand Down
1 change: 1 addition & 0 deletions core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ target_sources(DERPCore INTERFACE
I2C.cpp
Logging.cpp
MemoryBus.cpp
PIO.cpp
PWM.cpp
Timer.cpp
UART.cpp
Expand Down
58 changes: 10 additions & 48 deletions core/DMA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,10 @@ void DMA::update(uint64_t target)
for(uint32_t cycle = 0; cycle < passed; cycle++)
{
if(!channelTriggered)
{
clock.addCycles(passed - cycle);
break;
}

for(int i = 0; i < numChannels; i++, curChannel++)
{
Expand All @@ -74,21 +77,6 @@ void DMA::update(uint64_t target)
{
auto val = mem.read<uint8_t>(this, readAddr[curChannel], cycles, false);
mem.write(this, writeAddr[curChannel], val, cycles, false);

// tufty hax
if(writeAddr[curChannel] == 0x50300010 /*PIO1 TXF0*/)
{
static int off = 0;
extern uint16_t screenData[];

auto screenData8 = reinterpret_cast<uint8_t *>(screenData);
screenData8[off ^ 1] = val;
off++;

if(off == 320 * 240 * 2)
off = 0;
}

}
else if(transferSize == 2)
{
Expand All @@ -97,18 +85,6 @@ void DMA::update(uint64_t target)
val = val >> 8 | val << 8;

mem.write(this, writeAddr[curChannel], val, cycles, false);

// picosystem hax (hires)
if(writeAddr[curChannel] == 0x50200010 /*PIO0 TXF0*/)
{
static int off = 0;
extern uint16_t screenData[];

screenData[off++] = val;

if(off == 240 * 240)
off = 0;
}
}
else
{
Expand All @@ -117,25 +93,6 @@ void DMA::update(uint64_t target)
val = val >> 24 | val << 24 | (val & 0xFF00) << 8 | (val & 0xFF0000) >> 8;

mem.write(this, writeAddr[curChannel], val, cycles, false);

// picosystem hax (lores)
if(writeAddr[curChannel] == 0x50200010 /*PIO0 TXF0*/)
{
static int off = 0;
extern uint16_t screenData[];

// picosystem sdk unswaps in the pio program
if(bswap)
val = val >> 16 | val << 16;

screenData[off++] = val;
screenData[off++] = val;
screenData[off++] = val >> 16;
screenData[off++] = val >> 16;

if(off == 240 * 240)
off = 0;
}
}

if(ctrl[curChannel] & DMA_CH0_CTRL_TRIG_INCR_READ_BITS)
Expand All @@ -157,9 +114,9 @@ void DMA::update(uint64_t target)
}
break;
}
}

clock.addCycles(passed);
clock.addCycles(1);
}
}

uint64_t DMA::getNextInterruptTime(uint64_t target)
Expand Down Expand Up @@ -320,4 +277,9 @@ void DMA::regWrite(uint32_t addr, uint32_t data)

logf(LogLevel::NotImplemented, logComponent, "W %03X%s%08X", addr, op[atomic], data);
}
}

bool DMA::isChannelActive(int ch) const
{
return channelTriggered & (1 << ch);
}
2 changes: 2 additions & 0 deletions core/DMA.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ class DMA final

ClockTarget &getClock() {return clock;}

bool isChannelActive(int ch) const;

private:
MemoryBus &mem;

Expand Down
2 changes: 2 additions & 0 deletions core/GPIO.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ class GPIO final

void setReadCallback(ReadCallback cb);

uint32_t getPadState() const {return padState;}

void openLogFile(const char *filename);
void closeLogFile();

Expand Down
8 changes: 8 additions & 0 deletions core/Logging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
return "other";
case Component::ArmCore:
return "armcore";
case Component::Board:
return "board";
case Component::Clocks:
return "clocks";
case Component::DMA:
Expand All @@ -56,6 +58,8 @@
return "main";
case Component::MemoryBus:
return "membus";
case Component::PIO:
return "pio";
case Component::PWM:
return "pwm";
case Component::Timer:
Expand Down Expand Up @@ -95,6 +99,8 @@
return Component::Other;
if(str == "armcore")
return Component::ArmCore;
if(str == "board")
return Component::Board;
if(str == "clocks")
return Component::Clocks;
if(str == "dma")
Expand All @@ -109,6 +115,8 @@
return Component::Main;
if(str == "membus")
return Component::MemoryBus;
if(str == "pio")
return Component::PIO;
if(str == "pwm")
return Component::PWM;
if(str == "timer")
Expand Down Expand Up @@ -165,8 +173,8 @@
auto levelStr = levelToString(level);
auto compStr = componentToString(component);

int levelPad = 16 - strlen(levelStr);

Check warning on line 176 in core/Logging.cpp

View workflow job for this annotation

GitHub Actions / Visual Studio

'initializing': conversion from 'size_t' to 'int', possible loss of data [D:\a\DERP\build\minsdl\DERP_SDL.vcxproj]

Check warning on line 176 in core/Logging.cpp

View workflow job for this annotation

GitHub Actions / Visual Studio

'initializing': conversion from 'size_t' to 'int', possible loss of data [D:\a\DERP\build\minsdl\DERP_SDL.vcxproj]
int compPad = 9 - strlen(compStr);

Check warning on line 177 in core/Logging.cpp

View workflow job for this annotation

GitHub Actions / Visual Studio

'initializing': conversion from 'size_t' to 'int', possible loss of data [D:\a\DERP\build\minsdl\DERP_SDL.vcxproj]

Check warning on line 177 in core/Logging.cpp

View workflow job for this annotation

GitHub Actions / Visual Studio

'initializing': conversion from 'size_t' to 'int', possible loss of data [D:\a\DERP\build\minsdl\DERP_SDL.vcxproj]

printf("[%s]%*s[%s]%*s%s\n", levelStr, levelPad, "", compStr, compPad, "", buf);

Expand Down
2 changes: 2 additions & 0 deletions core/Logging.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,15 @@ namespace Logging
Other = 0,

ArmCore,
Board,
Clocks,
DMA,
GDB,
GPIO,
I2C,
Main,
MemoryBus,
PIO,
PWM,
Timer,
UART,
Expand Down
63 changes: 35 additions & 28 deletions core/MemoryBus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,16 @@
return bank * 64 * 1024 + word * 4 + (addr & 3);
}

MemoryBus::MemoryBus() : gpio(*this), uart{{*this, 0}, {*this, 1}}, i2c{{*this, 0}, {*this, 1}}, pwm(*this), watchdog(*this), timer(*this), dma(*this), usb(*this)
MemoryBus::MemoryBus() : gpio(*this), uart{{*this, 0}, {*this, 1}}, i2c{{*this, 0}, {*this, 1}}, pwm(*this), watchdog(*this), timer(*this), dma(*this), usb(*this), pio{{*this, 0}, {*this, 1}}
{
clocks.addClockTarget(clk_ref, watchdog.getClock());

clocks.addClockTarget(clk_sys, dma.getClock());
clocks.addClockTarget(clk_sys, gpio.getClock());
clocks.addClockTarget(clk_sys, pwm.getClock());

clocks.addClockTarget(clk_sys, dma.getClock());
clocks.addClockTarget(clk_sys, pio[0].getClock());
clocks.addClockTarget(clk_sys, pio[1].getClock());
}

void MemoryBus::setBootROM(const uint8_t *rom)
Expand Down Expand Up @@ -159,6 +162,8 @@

dma.reset();
usb.reset();
pio[0].reset();
pio[1].reset();

nextInterruptTime = 0;

Expand Down Expand Up @@ -386,6 +391,8 @@

dma.update(target);
usb.update(target);
pio[0].update(target);
pio[1].update(target);
}

void MemoryBus::gpioUpdate(uint64_t target)
Expand All @@ -394,6 +401,11 @@
// TODO: need to ensure correct ordering...
pwm.update(target);

// technically affects IO, but not implemented yet
// would also need to sync DMA most of the time
//pio[0].update(target);
//pio[1].update(target);

gpio.update(target);
}

Expand All @@ -420,6 +432,12 @@

if(irqMask & (1 << USBCTRL_IRQ))
usb.updateForInterrupts(target);

if(irqMask & (1 << PIO0_IRQ_0 | 1 << PIO0_IRQ_1))
pio[0].update(target);

if(irqMask & (1 << PIO1_IRQ_0 | 1 << PIO1_IRQ_1))
pio[1].update(target);
}

void MemoryBus::calcNextInterruptTime()
Expand All @@ -434,6 +452,8 @@
nextInterruptTime = timer.getNextInterruptTime(nextInterruptTime);
nextInterruptTime = dma.getNextInterruptTime(nextInterruptTime);
nextInterruptTime = usb.getNextInterruptTime(nextInterruptTime);
nextInterruptTime = pio[0].getNextInterruptTime(nextInterruptTime);
nextInterruptTime = pio[1].getNextInterruptTime(nextInterruptTime);
}

void MemoryBus::setInterruptUpdateCallback(InterruptUpdateCallback cb)
Expand Down Expand Up @@ -906,7 +926,7 @@
case APBPeripheral::PSM:
{
int atomic = periphAddr >> 12;
int addr = periphAddr & 0xFFF;

Check warning on line 929 in core/MemoryBus.cpp

View workflow job for this annotation

GitHub Actions / Visual Studio

declaration of 'addr' hides function parameter [D:\a\DERP\build\minsdl\DERP_SDL.vcxproj]

Check warning on line 929 in core/MemoryBus.cpp

View workflow job for this annotation

GitHub Actions / Visual Studio

declaration of 'addr' hides function parameter [D:\a\DERP\build\minsdl\DERP_SDL.vcxproj]
if(addr == PSM_FRCE_OFF_OFFSET)
{
logf(LogLevel::NotImplemented, logComponent, "PSM FRCE_OFF %i %08X", atomic, data);
Expand Down Expand Up @@ -1030,10 +1050,14 @@
auto peripheral = static_cast<AHBPeripheral>((addr >> 20) & 0xF);
auto periphAddr = addr & 0xFFFF;

// update DMA for any periph read
// TODO: any access that DMA could affect, possibly filter by dest addrs
dma.update(masterClock.getTime());

switch(peripheral)
{
case AHBPeripheral::DMA:
dma.update(masterClock.getTime());
//dma.update(masterClock.getTime());
return dma.regRead(periphAddr);

case AHBPeripheral::USB:
Expand All @@ -1052,25 +1076,12 @@
}

case AHBPeripheral::PIO0:
{
if(periphAddr == PIO_FSTAT_OFFSET)
return PIO_FSTAT_TXEMPTY_BITS | PIO_FSTAT_RXEMPTY_BITS; // all FIFOs empty
if(periphAddr == PIO_FDEBUG_OFFSET)
return PIO_FDEBUG_TXSTALL_BITS; // all TXSTALL
pio[0].update(masterClock.getTime());
return pio[0].regRead(periphAddr);

logf(LogLevel::NotImplemented, logComponent, "PIO0 R %08X", addr);
break;
}
case AHBPeripheral::PIO1:
{
if(periphAddr == PIO_FSTAT_OFFSET)
return PIO_FSTAT_TXEMPTY_BITS | PIO_FSTAT_RXEMPTY_BITS; // all FIFOs empty
if(periphAddr == PIO_FDEBUG_OFFSET)
return PIO_FDEBUG_TXSTALL_BITS; // all TXSTALL

logf(LogLevel::NotImplemented, logComponent, "PIO1 R %08X", addr);
break;
}
pio[1].update(masterClock.getTime());
return pio[1].regRead(periphAddr);

case AHBPeripheral::XIPAux:
logf(LogLevel::NotImplemented, logComponent, "AHBP XIP_AUX R %08X", addr);
Expand Down Expand Up @@ -1143,18 +1154,14 @@

case AHBPeripheral::PIO0:
{
if(periphAddr == PIO_TXF0_OFFSET)
{}
else
logf(LogLevel::NotImplemented, logComponent, "PIO0 W %08X = %08X", addr, data);
pio[0].update(masterClock.getTime());
pio[0].regWrite(periphAddr, data);
return;
}
case AHBPeripheral::PIO1:
{
if(periphAddr == PIO_TXF0_OFFSET)
{}
else
logf(LogLevel::NotImplemented, logComponent, "PIO1 W %08X = %08X", addr, data);
pio[1].update(masterClock.getTime());
pio[1].regWrite(periphAddr, data);
return;
}

Expand Down
5 changes: 5 additions & 0 deletions core/MemoryBus.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "GPIO.h"
#include "FIFO.h"
#include "I2C.h"
#include "PIO.h"
#include "PWM.h"
#include "Timer.h"
#include "UART.h"
Expand Down Expand Up @@ -88,7 +89,9 @@ class MemoryBus
PWM &getPWM() {return pwm;}
Watchdog &getWatchdog() {return watchdog;}

DMA &getDMA() {return dma;}
USB &getUSB() {return usb;}
PIO &getPIO(int i) {return pio[i];}

private:
template<class T, size_t size>
Expand Down Expand Up @@ -168,6 +171,8 @@ class MemoryBus

USB usb;

PIO pio[2];

uint64_t nextInterruptTime;

InterruptUpdateCallback interruptUpdateCallback;
Expand Down
Loading
Loading