Integrate Hall and riscv target

This commit is contained in:
2025-06-09 10:01:49 +02:00
parent 1b8d4e8c70
commit f6adc18215
17 changed files with 1019 additions and 5 deletions

1
lib/CMakeLists.txt Normal file
View File

@@ -0,0 +1 @@
add_subdirectory(Hall)

11
lib/Hall/CMakeLists.txt Normal file
View File

@@ -0,0 +1,11 @@
add_library(Hall STATIC
source/Audio.cpp
source/System.cpp
source/Video.cpp
)
target_include_directories(Hall
PUBLIC SYSTEM include
)
target_link_libraries(Hall PRIVATE RISCV_Options)

2
lib/Hall/README.md Normal file
View File

@@ -0,0 +1,2 @@
# Hall
Hallo, hier ist Hall

View File

@@ -0,0 +1,63 @@
#pragma once
namespace Hall
{
/// <summary>
/// Sets the global volume. 0 is muted, 128 is the default, 255 is max
/// </summary>
/// <param name="volume">0 is muted, 128 is the default, 255 is max</param>
void SetGlobalVolume(unsigned char volume);
/// <summary>
/// Prepares a channel to be used to play a non-looped single-channel audio
/// </summary>
/// <param name="channelID">The ID of the channel. Must be within [0,7]</param>
/// <param name="data">A pointer to the first sample of the audio data</param>
/// <param name="sampleCount">The total number of samples in the audio data</param>
/// <param name="volume">The channel's local volume. 0 is muted, 128 is the default, 255 is max</param>
void SetupMono(int channelID, short* data, int sampleCount, unsigned char volume = 128);
/// <summary>
/// Prepares a channel to be used to play a looped single-channel audio
/// </summary>
/// <param name="channelID">The ID of the channel. Must be within [0,7]</param>
/// <param name="data">A pointer to the first sample of the audio data</param>
/// <param name="sampleCount">The total number of samples in the audio data</param>
/// <param name="loopStart">The index of the first sample of the loop (inclusive)</param>
/// <param name="loopEnd">The index of the last sample of the loop (exclusive?)</param>
/// <param name="volume">The channel's local volume. 0 is muted, 128 is the default, 255 is max</param>
void SetupMono(int channelID, short* data, int sampleCount, unsigned int loopStart, unsigned int loopEnd, unsigned char volume = 128);
/// <summary>
/// Prepares two channels to be used to play a non-looped stereo audio
/// </summary>
/// <param name="channelID_left">The ID of the channel for the left audio. Must be within [0,7]</param>
/// <param name="channelID_right">The ID of the channel for the right audio. Must be within [0,7]</param>
/// <param name="data">A pointer to the first sample of the audio data</param>
/// <param name="sampleCount">The total number of samples PER CHANNEL in the audio data</param>
/// <param name="volume">The channel's local volume. 0 is muted, 128 is the default, 255 is max</param>
void SetupStereo(int channelID_left, int channelID_right, short* data, int sampleCount, unsigned char volume = 128);
/// <summary>
/// Prepares two channels to be used to play a looped stereo audio
/// </summary>
/// <param name="channelID_left">The ID of the channel for the left audio. Must be within [0,7]</param>
/// <param name="channelID_right">The ID of the channel for the right audio. Must be within [0,7]</param>
/// <param name="data">A pointer to the first sample of the audio data</param>
/// <param name="sampleCount">The total number of samples PER CHANNEL in the audio data</param>
/// <param name="loopStart">The index of the first sample of the loop (inclusive)</param>
/// <param name="loopEnd">The index of the last sample of the loop (exclusive?)</param>
/// <param name="volume">The channel's local volume. 0 is muted, 128 is the default, 255 is max</param>
void SetupStereo(int channelID_left, int channelID_right, short* data, int sampleCount, unsigned int loopStart, unsigned int loopEnd, unsigned char volume = 128);
void Play(unsigned char channelSelect);
void Pause(unsigned char channelSelect);
void SetData(unsigned char channelSelect, short* data);
void SetLoop(unsigned char channelSelect, bool isLooping);
void SetLoopBoundaries(unsigned char channelSelect, int start, int end);
void SetPosition(unsigned char channelSelect, int position);
void SetSample(unsigned char channelSelect, short sample);
void SetVolume(unsigned char channelSelect, unsigned char volume);
}

View File

@@ -0,0 +1,5 @@
#pragma once
#include <Hall/System.h>
#include <Hall/Video.h>
#include <Hall/Audio.h>

View File

@@ -0,0 +1,36 @@
#pragma once
namespace Hall
{
static const int SYSTEM_CLK_FREQUENCY = 50000000; //50 MHz
static void* const SDRAM_START = 0x0; //Start of the RAM. It is 32 MB large
static void* const BOOTLOADER_START = (void* const) 0x02010000; //Start of the bootloader. It is 32 kB large
static void* const SD_CARD_START = (void* const) 0x80000000; //Start of the SD-Card
/// <summary>
/// Returns an 8-Byte int, that represents the number of ticks that passed since the system's boot-up. Divide by SYSTEM_CLK_FREQUENCY to get seconds
/// </summary>
/// <returns>The system time since boot-up in ticks</returns>
unsigned long long GetSystemTime();
/// <summary>
/// Returns the state of all buttons on the controller.
/// </summary>
/// <param name="id">Must be in the range [0,1]</param>
/// <returns>Each button corresponds to one bit: 0 - B, 1 - Y, 2 - Select, 3 - Start, 4 - Up, 5 - Down, 6 - Left, 7 - Right, 8 - A, 9 - X, 10 - L, 11 - R</returns>
unsigned short GetController(int id);
unsigned int GetSystemTimeExcerpt(int precision);
bool GetA(unsigned short controller);
bool GetB(unsigned short controller);
bool GetX(unsigned short controller);
bool GetY(unsigned short controller);
bool GetStart(unsigned short controller);
bool GetSelect(unsigned short controller);
bool GetUp(unsigned short controller);
bool GetDown(unsigned short controller);
bool GetLeft(unsigned short controller);
bool GetRight(unsigned short controller);
bool GetL(unsigned short controller);
bool GetR(unsigned short controller);
}

View File

@@ -0,0 +1,43 @@
#pragma once
namespace Hall
{
const int SCREEN_HEIGHT = 240;
const int SCREEN_WIDTH = 400;
/// <summary>
/// Draws an excerpt of the given data onto the screen. All coordinates describe the top-left corner
/// </summary>
/// <param name="data">A pointer to the first pixel of an image</param>
/// <param name="xOffset">The x offset within that image</param>
/// <param name="yOffset">The y offset within that image</param>
/// <param name="screenX">The x position on screen.</param>
/// <param name="screenY">The y position on screen.</param>
/// <param name="width">The width of the excerpt</param>
/// <param name="height">The height of the excerpt</param>
/// <param name="dataWidth">The width of the image (NOT EXCERPT)</param>
void Draw(unsigned short* data, unsigned short xOffset, unsigned short yOffset, unsigned short screenX, unsigned short screenY, unsigned short width, unsigned short height, unsigned short dataWidth);
/// <summary>
/// Clears the whole screen with the given color
/// </summary>
/// <param name="color">The format is R5G5B5A1, with the alpha bit being lsb</param>
void Clear(unsigned short color);
void SetData(unsigned short* data);
void SetXOffset(unsigned short xOffset);
void SetYOffset(unsigned short yOffset);
void SetImageWidth(unsigned short imageWidth);
void SetWidth(unsigned short width);
void SetHeight(unsigned short height);
void SetScreenX(unsigned short x);
void SetScreenY(unsigned short y);
void SetClearColor(unsigned short color);
void SetCommandDraw();
void SetCommandClear();
void SetCommandSwapBuffers();
bool GetIsGPUBusy();
bool GetVSync();
bool GetHSync();
}

132
lib/Hall/source/Audio.cpp Normal file
View File

@@ -0,0 +1,132 @@
#include <Hall/Audio.h>
volatile char* AUDIO_START = (char*) 0x2000100;
volatile short** AUDIO_START_ADDRESS = (volatile short**)(AUDIO_START + 4);
volatile int* AUDIO_SAMPLE_COUNT = (volatile int*)(AUDIO_START + 8);
volatile int* AUDIO_LOOP_START = (volatile int*)(AUDIO_START + 12);
volatile int* AUDIO_LOOP_END = (volatile int*)(AUDIO_START + 16);
volatile int* AUDIO_CURRENT_POSITION = (volatile int*)(AUDIO_START + 20);
volatile short* AUDIO_LAST_SAMPLE = (volatile short*)(AUDIO_START + 24);
volatile unsigned char* AUDIO_VOLUME = (volatile unsigned char*)(AUDIO_START + 28);
volatile bool* AUDIO_IS_LOOPING = (volatile bool*)(AUDIO_START + 32);
volatile bool* AUDIO_IS_PLAYING = (volatile bool*)(AUDIO_START + 36);
volatile bool* AUDIO_IS_MONO = (volatile bool*)(AUDIO_START + 40);
volatile bool* AUDIO_IS_RIGHT = (volatile bool*)(AUDIO_START + 44);
unsigned char* AUDIO_GLOBAL_VOLUME = (unsigned char*)(AUDIO_START + 48); //I think we can skip volatile for these two
unsigned char* AUDIO_CHANNEL_SELECT = (unsigned char*)(AUDIO_START + 52); //Because they will never change and always address the same value
void Hall::SetGlobalVolume(unsigned char volume)
{
*AUDIO_GLOBAL_VOLUME = volume;
}
void Hall::SetupMono(int channelID, short* data, int sampleCount, unsigned char volume)
{
*AUDIO_CHANNEL_SELECT = 1 << channelID;
*AUDIO_START_ADDRESS = data;
*AUDIO_SAMPLE_COUNT = sampleCount;
*AUDIO_CURRENT_POSITION = 0;
*AUDIO_VOLUME = volume;
*AUDIO_IS_LOOPING = false;
*AUDIO_IS_PLAYING = false;
*AUDIO_IS_MONO = true;
}
void Hall::SetupMono(int channelID, short* data, int sampleCount, unsigned int loopStart, unsigned int loopEnd, unsigned char volume)
{
*AUDIO_CHANNEL_SELECT = 1 << channelID;
*AUDIO_START_ADDRESS = data;
*AUDIO_SAMPLE_COUNT = sampleCount;
*AUDIO_CURRENT_POSITION = 0;
*AUDIO_VOLUME = volume;
*AUDIO_IS_LOOPING = true;
*AUDIO_LOOP_START = loopStart;
*AUDIO_LOOP_END = loopEnd;
*AUDIO_IS_PLAYING = false;
*AUDIO_IS_MONO = true;
}
void Hall::SetupStereo(int channelID_left, int channelID_right, short* data, int sampleCount, unsigned char volume)
{
*AUDIO_CHANNEL_SELECT = (1 << channelID_left) | (1 << channelID_right);
*AUDIO_START_ADDRESS = data;
*AUDIO_SAMPLE_COUNT = sampleCount;
*AUDIO_CURRENT_POSITION = 0;
*AUDIO_VOLUME = volume;
*AUDIO_IS_LOOPING = false;
*AUDIO_IS_PLAYING = false;
*AUDIO_IS_MONO = false;
*AUDIO_IS_RIGHT = false;
*AUDIO_CHANNEL_SELECT = 1 << channelID_right;
*AUDIO_IS_RIGHT = true;
}
void Hall::SetupStereo(int channelID_left, int channelID_right, short* data, int sampleCount, unsigned int loopStart, unsigned int loopEnd, unsigned char volume)
{
*AUDIO_CHANNEL_SELECT = (1 << channelID_left) | (1 << channelID_right);
*AUDIO_START_ADDRESS = data;
*AUDIO_SAMPLE_COUNT = sampleCount;
*AUDIO_CURRENT_POSITION = 0;
*AUDIO_VOLUME = volume;
*AUDIO_LOOP_START = loopStart;
*AUDIO_LOOP_END = loopEnd;
*AUDIO_IS_LOOPING = true;
*AUDIO_IS_PLAYING = false;
*AUDIO_IS_MONO = false;
*AUDIO_IS_RIGHT = false;
*AUDIO_CHANNEL_SELECT = 1 << channelID_right;
*AUDIO_IS_RIGHT = true;
}
void Hall::Play(unsigned char channelSelect)
{
*AUDIO_CHANNEL_SELECT = channelSelect;
*AUDIO_IS_PLAYING = true;
}
void Hall::Pause(unsigned char channelSelect)
{
*AUDIO_CHANNEL_SELECT = channelSelect;
*AUDIO_IS_PLAYING = false;
}
void Hall::SetData(unsigned char channelSelect, short* data)
{
*AUDIO_CHANNEL_SELECT = channelSelect;
*AUDIO_START_ADDRESS = data;
}
void Hall::SetLoop(unsigned char channelSelect, bool isLooping)
{
*AUDIO_CHANNEL_SELECT = channelSelect;
*AUDIO_IS_LOOPING;
}
void Hall::SetLoopBoundaries(unsigned char channelSelect, int start, int end)
{
*AUDIO_CHANNEL_SELECT = channelSelect;
*AUDIO_LOOP_START = start;
*AUDIO_LOOP_END = end;
}
void Hall::SetPosition(unsigned char channelSelect, int position)
{
*AUDIO_CHANNEL_SELECT = channelSelect;
*AUDIO_CURRENT_POSITION = position;
}
void Hall::SetSample(unsigned char channelSelect, short sample)
{
*AUDIO_CHANNEL_SELECT = channelSelect;
*AUDIO_LAST_SAMPLE = sample;
}
void Hall::SetVolume(unsigned char channelSelect, unsigned char volume)
{
*AUDIO_CHANNEL_SELECT = channelSelect;
*AUDIO_VOLUME = volume;
}

View File

@@ -0,0 +1,90 @@
#include <Hall/System.h>
volatile char* SYSTEM_TIME = (volatile char*)0x02000300;
volatile unsigned int* SYSTEM_TIME_0 = (volatile unsigned int*)(SYSTEM_TIME + 0); //Least precise
volatile unsigned int* SYSTEM_TIME_1 = (volatile unsigned int*)(SYSTEM_TIME + 4);
volatile unsigned int* SYSTEM_TIME_2 = (volatile unsigned int*)(SYSTEM_TIME + 8);
volatile unsigned int* SYSTEM_TIME_3 = (volatile unsigned int*)(SYSTEM_TIME + 12);
volatile unsigned int* SYSTEM_TIME_4 = (volatile unsigned int*)(SYSTEM_TIME + 16);//Most precise
volatile char* CONTROLLER_START = (volatile char*)0x02000200;
volatile unsigned short* CONTROLLER_0 = (volatile unsigned short*)(CONTROLLER_START + 0);
volatile unsigned short* CONTROLLER_1 = (volatile unsigned short*)(CONTROLLER_START + 2);
unsigned long long Hall::GetSystemTime()
{
unsigned long long result = *SYSTEM_TIME_0;
result = result << 32;
result += *SYSTEM_TIME_4;
return result;
}
unsigned int Hall::GetSystemTimeExcerpt(int precision)
{
return *(SYSTEM_TIME_0 + precision);
}
unsigned short Hall::GetController(int id)
{
return *(CONTROLLER_0 + id);
}
bool Hall::GetA(unsigned short controller)
{
return controller & (1 << 8);
}
bool Hall::GetB(unsigned short controller)
{
return controller & (1 << 0);
}
bool Hall::GetX(unsigned short controller)
{
return controller & (1 << 9);
}
bool Hall::GetY(unsigned short controller)
{
return controller & (1 << 1);
}
bool Hall::GetStart(unsigned short controller)
{
return controller & (1 << 3);
}
bool Hall::GetSelect(unsigned short controller)
{
return controller & (1 << 2);
}
bool Hall::GetUp(unsigned short controller)
{
return controller & (1 << 4);
}
bool Hall::GetDown(unsigned short controller)
{
return controller & (1 << 5);
}
bool Hall::GetLeft(unsigned short controller)
{
return controller & (1 << 6);
}
bool Hall::GetRight(unsigned short controller)
{
return controller & (1 << 7);
}
bool Hall::GetL(unsigned short controller)
{
return controller & (1 << 10);
}
bool Hall::GetR(unsigned short controller)
{
return controller & (1 << 11);
}

117
lib/Hall/source/Video.cpp Normal file
View File

@@ -0,0 +1,117 @@
#include <Hall/Video.h>
volatile char* GPU_START = (char*)0x02000000;
volatile unsigned short** GPU_IMAGE_START = (volatile unsigned short**)(GPU_START + 0);
volatile unsigned short* GPU_IMAGE_X_OFFSET = (volatile unsigned short*)(GPU_START + 4);
volatile unsigned short* GPU_IMAGE_Y_OFFSET = (volatile unsigned short*)(GPU_START + 8);
volatile unsigned short* GPU_IMAGE_WIDTH = (volatile unsigned short*)(GPU_START + 12);
volatile unsigned short* GPU_WIDTH = (volatile unsigned short*)(GPU_START + 16);
volatile unsigned short* GPU_HEIGHT = (volatile unsigned short*)(GPU_START + 20);
volatile unsigned short* GPU_SCREEN_X = (volatile unsigned short*)(GPU_START + 24);
volatile unsigned short* GPU_SCREEN_Y = (volatile unsigned short*)(GPU_START + 28);
volatile unsigned short* GPU_CLEAR_COLOR = (volatile unsigned short*)(GPU_START + 32);
volatile bool* GPU_COMMAND_DRAW = (volatile bool*)(GPU_START + 36);
volatile bool* GPU_COMMAND_CLEAR = (volatile bool*)(GPU_START + 40);
volatile bool* GPU_IS_BUSY = (volatile bool*)(GPU_START + 44);
volatile bool* GPU_VSYNC = (volatile bool*)(GPU_START + 48);
volatile bool* GPU_HSYNC = (volatile bool*)(GPU_START + 52);
volatile bool* GPU_COMMAND_SWAP_BUFFERS = (volatile bool*)(GPU_START + 56);
volatile bool* VSYNC_BUFFER_SWAP = (volatile bool*)(GPU_START + 60);
void Hall::Draw(unsigned short* data, unsigned short xOffset, unsigned short yOffset, unsigned short screenX, unsigned short screenY, unsigned short width, unsigned short height, unsigned short dataWidth)
{
*GPU_IMAGE_START = data;
*GPU_IMAGE_X_OFFSET = xOffset;
*GPU_IMAGE_Y_OFFSET = yOffset;
*GPU_IMAGE_WIDTH = dataWidth;
*GPU_WIDTH = width;
*GPU_HEIGHT = height;
*GPU_SCREEN_X = screenX;
*GPU_SCREEN_Y = screenY;
*GPU_COMMAND_DRAW = true;
}
void Hall::Clear(unsigned short color)
{
*GPU_CLEAR_COLOR = color;
*GPU_COMMAND_CLEAR = true;
}
void Hall::SetData(unsigned short* data)
{
*GPU_IMAGE_START = data;
}
void Hall::SetXOffset(unsigned short xOffset)
{
*GPU_IMAGE_X_OFFSET = xOffset;
}
void Hall::SetYOffset(unsigned short yOffset)
{
*GPU_IMAGE_Y_OFFSET = yOffset;
}
void Hall::SetImageWidth(unsigned short imageWidth)
{
*GPU_IMAGE_WIDTH = imageWidth;
}
void Hall::SetWidth(unsigned short width)
{
*GPU_WIDTH = width;
}
void Hall::SetHeight(unsigned short height)
{
*GPU_HEIGHT = height;
}
void Hall::SetScreenX(unsigned short x)
{
*GPU_SCREEN_X = x;
}
void Hall::SetScreenY(unsigned short y)
{
*GPU_SCREEN_Y = y;
}
void Hall::SetClearColor(unsigned short color)
{
*GPU_CLEAR_COLOR = color;
}
void Hall::SetCommandDraw()
{
*GPU_COMMAND_DRAW = true;
}
void Hall::SetCommandClear()
{
*GPU_COMMAND_CLEAR = true;
}
void Hall::SetCommandSwapBuffers()
{
*GPU_COMMAND_SWAP_BUFFERS = true;
}
bool Hall::GetIsGPUBusy()
{
return *GPU_IS_BUSY;
}
bool Hall::GetVSync()
{
return *GPU_VSYNC;
}
bool Hall::GetHSync()
{
return *GPU_HSYNC;
}