Skip to content

Commit

Permalink
Joystick support on all firmwares
Browse files Browse the repository at this point in the history
  • Loading branch information
polpo committed Nov 12, 2023
1 parent d179246 commit 0f6f216
Show file tree
Hide file tree
Showing 15 changed files with 323 additions and 168 deletions.
18 changes: 5 additions & 13 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,50 +50,42 @@ jobs:
working-directory: ${{github.workspace}}/build
run: |
mkdir -p $OUTPUT_DIR
cmake $GITHUB_WORKSPACE/sw -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DPROJECT_TYPE="GUS" -DUSE_LTO=
cmake $GITHUB_WORKSPACE/sw -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DPROJECT_TYPE="GUS" -DUSE_LTO=1 -DUSB_JOYSTICK=1
cmake --build . --config $BUILD_TYPE --parallel $(nproc)
cp picogus.uf2 $OUTPUT_DIR/pg-gus.uf2
- name: Build OPL / AdLib Firmware
working-directory: ${{github.workspace}}/build
shell: bash
run: |
cmake $GITHUB_WORKSPACE/sw -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DPROJECT_TYPE="OPL" -DUSE_LTO=
cmake $GITHUB_WORKSPACE/sw -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DPROJECT_TYPE="OPL" -DUSE_LTO=1 -DUSB_JOYSTICK=1
cmake --build . --config $BUILD_TYPE --parallel $(nproc)
cp picogus.uf2 $OUTPUT_DIR/pg-adlib.uf2
- name: Build MPU401 Firmware
working-directory: ${{github.workspace}}/build
shell: bash
run: |
cmake $GITHUB_WORKSPACE/sw -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DPROJECT_TYPE="MPU" -DUSE_LTO=
cmake $GITHUB_WORKSPACE/sw -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DPROJECT_TYPE="MPU" -DUSE_LTO=1 -DUSB_JOYSTICK=1
cmake --build . --config $BUILD_TYPE --parallel $(nproc)
cp picogus.uf2 $OUTPUT_DIR/pg-mpu.uf2
- name: Build Tandy Firmware
working-directory: ${{github.workspace}}/build
shell: bash
run: |
cmake $GITHUB_WORKSPACE/sw -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DPROJECT_TYPE="TANDY" -DUSE_LTO=
cmake $GITHUB_WORKSPACE/sw -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DPROJECT_TYPE="TANDY" -DUSE_LTO=1 -DUSB_JOYSTICK=1
cmake --build . --config $BUILD_TYPE --parallel $(nproc)
cp picogus.uf2 $OUTPUT_DIR/pg-tandy.uf2
- name: Build CMS Firmware
working-directory: ${{github.workspace}}/build
shell: bash
run: |
cmake $GITHUB_WORKSPACE/sw -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DPROJECT_TYPE="CMS" -DUSE_LTO=
cmake $GITHUB_WORKSPACE/sw -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DPROJECT_TYPE="CMS" -DUSE_LTO=1 -DUSB_JOYSTICK=1
cmake --build . --config $BUILD_TYPE --parallel $(nproc)
cp picogus.uf2 $OUTPUT_DIR/pg-cms.uf2
- name: Build Joy Firmware
working-directory: ${{github.workspace}}/build
shell: bash
run: |
cmake $GITHUB_WORKSPACE/sw -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DPROJECT_TYPE="JOY" -DUSE_LTO=
cmake --build . --config $BUILD_TYPE --parallel $(nproc)
cp picogus.uf2 $OUTPUT_DIR/pg-joy.uf2
# will generate PicoGUS Firmwares.zip as downloadable artifact with all .uf2 files
- name: Upload All Firmwares
uses: actions/upload-artifact@v3
Expand Down
6 changes: 6 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
[submodule "sw/rp2040-psram"]
path = sw/rp2040-psram
url = https://github.com/polpo/rp2040-psram.git
[submodule "sw/tinyusb"]
path = sw/tinyusb
url = https://github.com/hathach/tinyusb
[submodule "sw/tusb_xinput"]
path = sw/tusb_xinput
url = https://github.com/RobertDaleSmith/tusb_xinput
18 changes: 14 additions & 4 deletions pgusinit/pgusinit.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ typedef enum {
} card_mode_t;

void banner(void) {
printf("PicoGUSinit v1.3.0 (c) 2023 Ian Scott - licensed under the GNU GPL v2\n\n");
printf("PicoGUSinit v1.3.0-beta0 (c) 2023 Ian Scott - licensed under the GNU GPL v2\n\n");
}

const char* usage_by_card[] = {
Expand All @@ -47,11 +47,12 @@ void usage(char *argv0, card_mode_t mode) {
fprintf(stderr, "Usage:\n");
fprintf(stderr, " %s [/?] | [/f fw.uf2]", argv0);
if (mode <= CMS_MODE) {
fprintf(stderr, " | %s", usage_by_card[mode]);
fprintf(stderr, " | [/j] %s", usage_by_card[mode]);
}
fprintf(stderr, "\n\n");
fprintf(stderr, " /? - show this message\n");
fprintf(stderr, " /f fw.uf2 - Program the PicoGUS with the firmware file fw.uf2.\n");
fprintf(stderr, " /? - show this message\n");
fprintf(stderr, " /f fw.uf2 - program the PicoGUS with the firmware file fw.uf2\n");
fprintf(stderr, " /j - enable USB joystick support\n");
if (mode != GUS_MODE) {
fprintf(stderr, "AdLib, MPU-401, Tandy, CMS modes only:\n");
fprintf(stderr, " /p x - set the (hex) base port address of the emulated card. Defaults:\n");
Expand Down Expand Up @@ -209,6 +210,8 @@ int write_firmware(const char* fw_filename, uint8_t protocol) {
// Put card into programming mode
outp(CONTROL_PORT, 0xCC); // Knock on the door...
outp(CONTROL_PORT, 0xFF); // Select firmware programming mode
// Wait a bit for 2nd core on Pico to restart
delay(100);
if (inp(DATA_PORT_HIGH) != PICO_FIRMWARE_IDLE) {
fprintf(stderr, "ERROR: Card is not in programming mode?\n");
return 13;
Expand Down Expand Up @@ -275,6 +278,7 @@ int main(int argc, char* argv[]) {
card_mode_t mode;
uint8_t mpu_delaysysex = 0;
uint8_t mpu_fakeallnotesoff = 0;
uint8_t enable_joystick = 0;

banner();
// Get magic value from port on PicoGUS that is not on real GUS
Expand All @@ -295,6 +299,8 @@ int main(int argc, char* argv[]) {
if (stricmp(argv[i], "/?") == 0) {
usage(argv[0], mode);
return 0;
} else if (stricmp(argv[i], "/j") == 0) {
enable_joystick = 1;
} else if (stricmp(argv[i], "/a") == 0) {
if (i + 1 >= argc) {
usage(argv[0], mode);
Expand Down Expand Up @@ -390,6 +396,10 @@ int main(int argc, char* argv[]) {
port = inpw(DATA_PORT_LOW); // Get port
}

outp(CONTROL_PORT, 0x0f); // Select joystick enable register
outp(DATA_PORT_HIGH, enable_joystick);
printf("USB joystick support %s\n", enable_joystick ? "enabled" : "disabled");

switch(mode) {
case GUS_MODE:
init_gus(argv[0]);
Expand Down
44 changes: 29 additions & 15 deletions sw/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ set(CMAKE_BUILD_TYPE "Release")
set(PICO_COPY_TO_RAM 1)
#set(SKIP_PICO_MALLOC 1)

# Tell the Pico SDK to use our local tinyusb instead of the one included in the SDK
# This is needed to support tusb_xinput
set(PICO_TINYUSB_PATH ${CMAKE_CURRENT_LIST_DIR}/tinyusb)

if(NOT PROJECT_TYPE)
set(PROJECT_TYPE "GUS")
message("PROJECT_TYPE not set, defaulting to ${PROJECT_TYPE}")
Expand All @@ -33,7 +37,7 @@ endif()
# Initialise the Raspberry Pi Pico SDK
pico_sdk_init()

if(DEFINED USE_LTO)
if(USE_LTO)
# Pico SDK must be patched to allow for LTO so it is not enabled by default.
# To patch to Pico SDK, run:
# sed -i 's/WRAPPER_FUNC(x) __wrap_/WRAPPER_FUNC(x) __attribute__((used)) __wrap_/' "$PICO_SDK_PATH"/src/rp2_common/pico_platform/include/pico/platform.h
Expand Down Expand Up @@ -103,11 +107,18 @@ if(PROJECT_TYPE STREQUAL "GUS")
endif()
pico_enable_stdio_usb(picogus 0)
pico_enable_stdio_semihosting(picogus 0)
# Joystick stuff
target_sources(picogus PRIVATE joy_hid/joy_hid.c)
target_link_libraries(picogus tinyusb_host tinyusb_board hardware_pwm)
target_include_directories(picogus PUBLIC ${CMAKE_CURRENT_LIST_DIR}/joy_hid)
target_compile_definitions(picogus PRIVATE USB_JOYSTICK=1)

endif()

if(PROJECT_TYPE STREQUAL "OPL")
pico_set_program_name(picogus "picogus-adlib")
target_sources(picogus PRIVATE adlibplay.cpp)

target_link_libraries(
picogus
opl
Expand Down Expand Up @@ -167,33 +178,36 @@ if(PROJECT_TYPE STREQUAL "CMS")
pico_pic.c
square/square.cpp
)
target_sources(picogus PRIVATE cmsplay.cpp)

pico_enable_stdio_uart(picogus 1)
pico_enable_stdio_usb(picogus 0)
pico_enable_stdio_semihosting(picogus 0)
endif()

if(PROJECT_TYPE STREQUAL "JOY")
pico_set_program_name(picogus "picogus-joy")
set(USB_JOYSTICK=1)
target_compile_definitions(picogus PRIVATE
USB_JOYSTICK=1
USB_JOYSTICK_ONLY=1
)

target_sources(picogus PRIVATE
joy_hid/joy_hid.c
usbplay.cpp
)
pico_enable_stdio_uart(picogus 1)
pico_enable_stdio_usb(picogus 0)
pico_enable_stdio_semihosting(picogus 0)

# Make sure TinyUSB can find tusb_config.h
target_include_directories(picogus PUBLIC
${CMAKE_CURRENT_LIST_DIR}/joy_hid)
pico_enable_stdio_uart(picogus 1)
pico_enable_stdio_usb(picogus 0)
pico_enable_stdio_semihosting(picogus 0)
endif()

# In addition to pico_stdlib required for common PicoSDK functionality, add dependency on tinyusb_host
# for TinyUSB device support and tinyusb_board for the additional board support library used by the example
target_link_libraries(picogus tinyusb_host tinyusb_board hardware_pwm)
if(USB_JOYSTICK)
# Joystick stuff
target_sources(picogus PRIVATE joy_hid/joy_hid.c)
target_link_libraries(picogus hardware_pwm)
target_include_directories(picogus PUBLIC ${CMAKE_CURRENT_LIST_DIR}/joy_hid)
target_link_libraries(picogus tinyusb_host)
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/tusb_xinput)
target_link_libraries(picogus xinput_host_app_driver)
target_compile_definitions(picogus PRIVATE USB_JOYSTICK=1)
endif()

target_sources(picogus PRIVATE M62429/M62429.cpp)
Expand Down
7 changes: 7 additions & 0 deletions sw/adlibplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

#include "opl.h"

#include "tusb.h"

#if PICO_ON_DEVICE
#include "pico/binary_info.h"
bi_decl(bi_3pins_with_names(PICO_AUDIO_I2S_DATA_PIN, "I2S DIN", PICO_AUDIO_I2S_CLOCK_PIN_BASE, "I2S BCK", PICO_AUDIO_I2S_CLOCK_PIN_BASE+1, "I2S LRCK"));
Expand Down Expand Up @@ -69,11 +71,16 @@ void play_adlib() {
puts("starting core 1");
uint32_t start, end;

// Init TinyUSB for joystick support
tuh_init(BOARD_TUH_RHPORT);

struct audio_buffer_pool *ap = init_audio();
for (;;) {
struct audio_buffer *buffer = take_audio_buffer(ap, true);
OPL_Pico_Mix_callback(buffer);
// putchar((unsigned char)buffer->buffer->bytes[1]);
give_audio_buffer(ap, buffer);
// Service TinyUSB events
tuh_task();
}
}
7 changes: 7 additions & 0 deletions sw/cmsplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

#include "pico/audio_i2s.h"

#include "tusb.h"

#ifdef MAME_CMS
#include "saa1099/saa1099.h"
saa1099_device *saa0, *saa1;
Expand Down Expand Up @@ -72,6 +74,9 @@ struct audio_buffer_pool *init_audio() {

void play_cms() {
puts("starting core 1 CMS");

// Init TinyUSB for joystick support
tuh_init(BOARD_TUH_RHPORT);
#ifdef MAME_CMS
puts("Creating SAA1099 1");
saa0 = new saa1099_device(7159090);
Expand Down Expand Up @@ -155,5 +160,7 @@ void play_cms() {
buffer->sample_count = buffer->max_sample_count;

give_audio_buffer(ap, buffer);
// Service TinyUSB events
tuh_task();
}
}
6 changes: 6 additions & 0 deletions sw/gusplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#include "pico_pic.h"
#endif

#include "tusb.h"

#ifdef PSRAM
#include "psram_spi.h"
extern psram_spi_inst_t psram_spi;
Expand Down Expand Up @@ -112,6 +114,8 @@ void play_gus() {
#endif
#endif
GUS_Setup();
// Init TinyUSB for joystick support
tuh_init(BOARD_TUH_RHPORT);

struct audio_buffer_pool *ap = init_audio();
for (;;) {
Expand Down Expand Up @@ -143,5 +147,7 @@ void play_gus() {
*/
// gpio_xor_mask(1u << PICO_DEFAULT_LED_PIN);
give_audio_buffer(ap, buffer);
// Service TinyUSB events
tuh_task();
}
}
Loading

0 comments on commit 0f6f216

Please sign in to comment.