Skip to content

Commit

Permalink
RPI multicore support
Browse files Browse the repository at this point in the history
  • Loading branch information
andreas-jonsson committed Nov 22, 2024
1 parent b2a6d09 commit 5bf7add
Show file tree
Hide file tree
Showing 7 changed files with 172 additions and 44 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/rpi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ jobs:
cd "${GITHUB_WORKSPACE}"
unzip circle.zip
cd "${CIRCLEHOME}"
./configure -r 3 -p aarch64-none-elf-
./configure -r 3 --multicore -p aarch64-none-elf-
make -C "${CIRCLEHOME}/boot"
cp "${CIRCLEHOME}"/boot/*.dtb "${GITHUB_WORKSPACE}/package"
cp "${CIRCLEHOME}"/boot/*.dat "${GITHUB_WORKSPACE}/package"
Expand All @@ -67,7 +67,7 @@ jobs:
#cd "${GITHUB_WORKSPACE}"
#unzip circle.zip
cd "${CIRCLEHOME}"
#./configure -r 3 -p aarch64-none-elf-
#./configure -r 3 --multicore -p aarch64-none-elf-
./makeall
make -C "${CIRCLEHOME}/addon/fatfs"
make -C "${CIRCLEHOME}/addon/SDCard"
Expand All @@ -82,7 +82,7 @@ jobs:
cd "${GITHUB_WORKSPACE}"
unzip circle.zip
cd "${CIRCLEHOME}"
./configure -r 4 -p aarch64-none-elf-
./configure -r 4 --multicore -p aarch64-none-elf-
./makeall
make -C "${CIRCLEHOME}/addon/fatfs"
make -C "${CIRCLEHOME}/addon/SDCard"
Expand All @@ -97,7 +97,7 @@ jobs:
cd "${GITHUB_WORKSPACE}"
unzip circle.zip
cd "${CIRCLEHOME}"
./configure -r 5 -p aarch64-none-elf-
./configure -r 5 --multicore -p aarch64-none-elf-
./makeall
make -C "${CIRCLEHOME}/addon/fatfs"
make -C "${CIRCLEHOME}/addon/SDCard"
Expand Down
4 changes: 2 additions & 2 deletions front/rpi/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ endif
LIBCHOME = $(VXTHOME)/../scanf

C_STANDARD = -std=c11
CFLAGS = -DVXT_NO_LIBC -DFRONTEND_VIDEO_BLUE=0 -DFRONTEND_VIDEO_GREEN=1 -DFRONTEND_VIDEO_RED=2 -DFRONTEND_VIDEO_ALPHA=3 -I$(VXTHOME)/include -I../common
CFLAGS = -DVXT_NO_LIBC -DVXTU_DISK_WAIT_STATES=0 -DFRONTEND_VIDEO_BLUE=0 -DFRONTEND_VIDEO_GREEN=1 -DFRONTEND_VIDEO_RED=2 -DFRONTEND_VIDEO_ALPHA=3 -I$(VXTHOME)/include -I../common

OBJS_VXT = $(VXTHOME)/cpu.o \
$(VXTHOME)/disk.o \
Expand All @@ -25,7 +25,7 @@ EXTRACLEAN = $(VXTHOME)/*.o $(VXTHOME)/*.d
OBJS_LIBC = $(LIBCHOME)/scanf.o
EXTRACLEAN += $(LIBCHOME)/*.o $(LIBCHOME)/*.d

OBJS = main.o kernel.o ethernet.o cga.o vga.o mouse.o joystick.o ems.o adlib.o $(OBJS_VXT) $(OBJS_LIBC)
OBJS = main.o kernel.o emuloop.o ethernet.o cga.o vga.o mouse.o joystick.o ems.o adlib.o $(OBJS_VXT) $(OBJS_LIBC)

LIBS = $(CIRCLEHOME)/lib/usb/libusb.a \
$(CIRCLEHOME)/lib/sound/libsound.a \
Expand Down
66 changes: 66 additions & 0 deletions front/rpi/emuloop.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright (c) 2019-2024 Andreas T Jonsson <mail@andreasjonsson.se>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.

#include "emuloop.h"

#define SYSTEM_STEPS 1
#define GET_TICKS ( CTimer::GetClockTicks64() * (vxt_system_frequency(m_pSystem) / 1000000) )

#ifndef ARM_ALLOW_MULTI_CORE
#error You need to enable multicore support!
#endif

CSpinLock CEmuLoop::s_SpinLock(TASK_LEVEL);

CEmuLoop::CEmuLoop(CMemorySystem *mem, vxt_system *s)
: CMultiCoreSupport(mem),
m_pSystem(s)
{
}

CEmuLoop::~CEmuLoop(void) {
}

void CEmuLoop::Run(unsigned nCore) {
if (nCore != 1)
return;

VXT_LOG("Emulation loop started!");

assert(CLOCKHZ == 1000000);
u64 virtual_ticks = GET_TICKS;

while (true) {
u64 cpu_ticks = GET_TICKS;

if (virtual_ticks < cpu_ticks) {
s_SpinLock.Acquire();
struct vxt_step step = vxt_system_step(m_pSystem, SYSTEM_STEPS);
s_SpinLock.Release();

if (step.err != VXT_NO_ERROR)
VXT_LOG(vxt_error_str(step.err));
virtual_ticks += step.cycles;
}
}

VXT_LOG("Emulation loop ended!");
}
45 changes: 45 additions & 0 deletions front/rpi/emuloop.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (c) 2019-2024 Andreas T Jonsson <mail@andreasjonsson.se>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.

#include "kernel.h"

#ifndef _EMULOOP_H_
#define _EMULOOP_H_

#include <circle/multicore.h>
#include <circle/memory.h>
#include <circle/types.h>

class CEmuLoop : public CMultiCoreSupport
{
public:
CEmuLoop(CMemorySystem *mem, vxt_system *s);
~CEmuLoop(void);

void Run(unsigned nCore);

static CSpinLock s_SpinLock;

private:
vxt_system *m_pSystem;
};

#endif
84 changes: 50 additions & 34 deletions front/rpi/kernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
// distribution.

#include "kernel.h"
#include "emuloop.h"

#include <circle/string.h>
#include <circle/util.h>
#include <circle/new.h>
Expand Down Expand Up @@ -62,6 +64,7 @@ CBcmFrameBuffer *pFrameBuffer = 0;
CDevice *pUMSD1 = 0;

FIL log_file = {0};
static CSpinLock log_lock(TASK_LEVEL);

extern "C" {
// From joystick.c
Expand Down Expand Up @@ -114,6 +117,8 @@ extern "C" {

CString str;
str.FormatV(fmt, alist);

// We do not need to use log_lock here.
f_write(&log_file, str, str.GetLength(), 0);
f_sync(&log_file);

Expand All @@ -130,6 +135,8 @@ extern "C" {

CString str;
str.FormatV(fmt, alist);

log_lock.Acquire();
string_buffer.Append(str);

int idx = string_buffer.Find('\n');
Expand All @@ -141,6 +148,7 @@ extern "C" {
string_buffer = &string_buffer[idx + 1];
delete[] cstr;
}
log_lock.Release();

va_end(alist);
return 0; // Not correct but it will have to do for now.
Expand Down Expand Up @@ -338,8 +346,8 @@ boolean CKernel::Initialize(void) {
}

TShutdownMode CKernel::Run(void) {
struct vxt_peripheral *ppi = 0;
struct vxt_peripheral *mouse = 0;
struct vxt_peripheral *ppi = NULL;
struct vxt_peripheral *mouse = NULL;
struct vxt_peripheral *disk = NULL;
struct vxt_peripheral *joystick = NULL;

Expand Down Expand Up @@ -450,12 +458,17 @@ TShutdownMode CKernel::Run(void) {
VXT_LOG("CPU reset!");
vxt_system_reset(s);

CEmuLoop *emuloop = new CEmuLoop(CMemorySystem::Get(), s);
if (!emuloop->Initialize()) {
VXT_LOG("Could not start emulation thread!");
return (m_ShutdownMode = ShutdownHalt);
}

assert(CLOCKHZ == 1000000);
u64 renderTicks = CTimer::GetClockTicks64();
u64 audioTicks = renderTicks;
u64 sysTicks = renderTicks;
u64 vCpuTicks = renderTicks * (cpu_frequency / 1000000);


bool usb_updated = false;

while (m_ShutdownMode == ShutdownNone) {
Expand Down Expand Up @@ -516,26 +529,31 @@ TShutdownMode CKernel::Run(void) {
if (m_pKeyboard)
m_pKeyboard->UpdateLEDs();

if (keyboard_updated) {
for (int i = 0; i < 0x100; i++) {
bool bnew = key_states[i];
bool *bcurrent = &key_states_current[i];

if (bnew || (bnew != *bcurrent)) {
enum vxtu_scancode scan = (enum vxtu_scancode)i;
vxtu_ppi_key_event(ppi, bnew ? scan : VXTU_KEY_UP(scan), false);
}
*bcurrent = bnew;
}
keyboard_updated = false;
}
CEmuLoop::s_SpinLock.Acquire();
{
if (keyboard_updated) {
for (int i = 0; i < 0x100; i++) {
bool bnew = key_states[i];
bool *bcurrent = &key_states_current[i];

if (bnew || (bnew != *bcurrent)) {
enum vxtu_scancode scan = (enum vxtu_scancode)i;
vxtu_ppi_key_event(ppi, bnew ? scan : VXTU_KEY_UP(scan), false);
}
*bcurrent = bnew;
}
keyboard_updated = false;
}

if (m_pMouse && mouse_updated) {
mouse_push_event(mouse, &mouse_state);
mouse_updated = false;
}

if (m_pMouse && mouse_updated) {
mouse_push_event(mouse, &mouse_state);
mouse_updated = false;
video_adapter.snapshot(video_adapter.device);
}
CEmuLoop::s_SpinLock.Release();

video_adapter.snapshot(video_adapter.device);
video_adapter.render(video_adapter.device, &render_callback, &m_Options);
}

Expand All @@ -544,10 +562,14 @@ TShutdownMode CKernel::Run(void) {

// Generate audio.
if (audio_buffer_len < audio_buffer_size) {
short sample = vxtu_ppi_generate_sample(ppi, SAMPLE_RATE);
if (audio_adapter.device)
sample += audio_adapter.generate_sample(audio_adapter.device, SAMPLE_RATE);
audio_buffer[audio_buffer_len++] = sample;
CEmuLoop::s_SpinLock.Acquire();
{
short sample = vxtu_ppi_generate_sample(ppi, SAMPLE_RATE);
if (audio_adapter.device)
sample += audio_adapter.generate_sample(audio_adapter.device, SAMPLE_RATE);
audio_buffer[audio_buffer_len++] = sample;
}
CEmuLoop::s_SpinLock.Release();
}

// Write audio data to output device.
Expand All @@ -561,17 +583,11 @@ TShutdownMode CKernel::Run(void) {
}
}
}

u64 cpuTicks = ticks * (cpu_frequency / 1000000);
if (vCpuTicks < cpuTicks) {
u64 dtics = cpuTicks - vCpuTicks;
struct vxt_step step = vxt_system_step(s, (dtics > cpu_frequency) ? cpu_frequency : dtics);
if (step.err != VXT_NO_ERROR)
VXT_LOG(vxt_error_str(step.err));
vCpuTicks += step.cycles;
}
}

// TODO: Stop thread first!
delete emuloop;

vxt_system_destroy(s);

if (has_floppy) f_close(&floppy_file);
Expand Down
3 changes: 1 addition & 2 deletions front/rpi/kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ class CKernel {
~CKernel(void);

boolean Initialize(void);

TShutdownMode Run(void);

private:
Expand All @@ -82,7 +81,7 @@ class CKernel {

static void GamePadStatusHandler(unsigned nDeviceIndex, const TGamePadState *pState);
static void GamePadRemovedHandler(CDevice *pDevice, void *pContext);

// Do not change this order!
CKernelOptions m_Options;
CDeviceNameService m_DeviceNameService;
Expand Down
6 changes: 4 additions & 2 deletions lib/vxt/disk.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@

#include <vxt/vxtu.h>

#define WAIT_STATES 1000
#ifndef VXTU_DISK_WAIT_STATES
#define VXTU_DISK_WAIT_STATES 1000
#endif

struct drive {
void *fp;
Expand Down Expand Up @@ -149,7 +151,7 @@ static void out(struct disk *c, vxt_word port, vxt_byte data) {
struct vxt_registers *r = vxt_system_registers(s);

// Simulate delay for accessing disk controller.
vxt_system_wait(s, WAIT_STATES);
vxt_system_wait(s, VXTU_DISK_WAIT_STATES);

switch (port) {
case 0xB0:
Expand Down

0 comments on commit 5bf7add

Please sign in to comment.