From e766bdabf6d09f0a8a921aa978d5cf93e2cd7e2c Mon Sep 17 00:00:00 2001 From: Jason Thorpe Date: Tue, 7 Jan 2025 06:49:13 -0800 Subject: [PATCH] Add support for a per-build config file (specified with PICO9918_CONFIG) that parameterizes: - board type - product name - disabling clock outputs - interrupt polarity - RGB signal / color pin origins ...and consult the config file for these parameters that already existed: - scanlines yes/no - SCART yes/no/mode Addresses issue #28. --- CMakeLists.txt | 30 +++++++++++++++++++++++++++-- src/CMakeLists.txt | 48 ++++++++++++++++++++++++++++++++++++++++++---- src/main.c | 35 ++++++++++++++++++++++++++++++--- src/vga/vga.c | 11 +++++++++-- 4 files changed, 113 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 53639ca..d0acc5e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,8 +24,34 @@ if (EXISTS ${picoVscode}) endif() # ==================================================================================== +if (PICO9918_CONFIG) + message("Using PICO9918_CONFIG '${PICO9918_CONFIG}'") + include(${PICO9918_CONFIG}) +endif() + +# +# Defaults if they're not set in the config file. +# +if (DEFINED PICO9918_RESTRICTED_HW_RPI_PICO) + # + # This is short-hand for "this is going to be run in a genuine + # Raspberry Pi Pico". Force the board type to "pico" in this + # case, and disable the clock outputs (the Pico doesn't have + # enough GPIO pins for that). + # + message("PICO9918_RESTRICTED_HW_RPI_PICO specified in config file") + set(PICO9918_BOARD "pico") + set(PICO9918_NO_CLOCKS 1) +endif() + +if (DEFINED PICO9918_BOARD) + message("Using PICO9918_BOARD '${PICO9918_BOARD}' from config file") +else() + set(PICO9918_BOARD "pico9918_v04") +endif() + set(PICO_BOARD_HEADER_DIRS ${CMAKE_CURRENT_LIST_DIR}/src/boards ) -set(PICO_BOARD "pico9918_v04" CACHE STRING "Board type") +set(PICO_BOARD ${PICO9918_BOARD} CACHE STRING "Board type") # Pull in Raspberry Pi Pico SDK (must be before project) include(pico_sdk_import.cmake) @@ -43,4 +69,4 @@ pico_sdk_init() add_subdirectory(submodules/vrEmuTms9918) add_subdirectory(src) -add_subdirectory(test) \ No newline at end of file +add_subdirectory(test) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 670901e..13a00d0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -7,11 +7,45 @@ set(PICO9918_VERSION "0.4.3") set(PICO9918_PCB_MAJOR_VER 0) set(PICO9918_PCB_MINOR_VER 4) -set(PICO9918_SCANLINES 1) +if (DEFINED PICO9918_SCANLINES) + message("Using PICO9918_SCANLINES '${PICO9918_SCANLINES}' from config file") +else() + set(PICO9918_SCANLINES 1) +endif() # SCART RGBs options -set(PICO9918_SCART_RGBS 0) # 1 for RGBs, 0 for VGA -set(PICO9918_SCART_PAL 0) # 1 for PAL 576i, 0 for NTSC 480i +if (DEFINED PICO9918_SCART_RGBS) + message("Using PICO9918_SCART_RGBS '${PICO9918_SCART_RGBS}' from config file") +else() + set(PICO9918_SCART_RGBS 0) # 1 for RGBs, 0 for VGA +endif() + +if (DEFINED PICO9918_SCART_PAL) + message("Using PICO9918_SCART_PAL '${PICO9918_SCART_PAL}' from config file") +else() + set(PICO9918_SCART_PAL 0) # 1 for PAL 576i, 0 for NTSC 480i +endif() + +# options for other pico9918 hardware configurations +if (DEFINED PICO9918_INT_ACTIVE_HIGH) + message("Using active-high interrupt output per config file") + add_definitions(-DPICO9918_INT_ACTIVE_HIGH) +endif() + +if (DEFINED PICO9918_NO_CLOCKS) + message("Disabling clock outputs per config file") + add_definitions(-DPICO9918_NO_CLOCKS) +endif() + +if (DEFINED PICO9918_SYNC_PINS_START) + message("Using PICO9918_SYNC_PINS_START '${PICO9918_SYNC_PINS_START}' from config file") + add_definitions(-DPICO9918_SYNC_PINS_START=${PICO9918_SYNC_PINS_START}) +endif() + +if (DEFINED PICO9918_RGB_PINS_START) + message("Using PICO9918_RGB_PINS_START '${PICO9918_RGB_PINS_START}' from config file") + add_definitions(-DPICO9918_RGB_PINS_START=${PICO9918_RGB_PINS_START}) +endif() # end compile-time options @@ -37,7 +71,13 @@ endif() string(REPLACE "." "-" PICO9918_VERSION_STR "${PICO9918_VERSION}") -set(PICO9918_BINARY_SUFFIX -pcb-v${PICO9918_PCB_MAJOR_VER}-${PICO9918_PCB_MINOR_VER}-${PICO9918_OUTPUT_STR}-build-${PICO9918_VERSION_STR}) +if (DEFINED PICO9918_PRODUCT) + message("Using PICO9918_PRODUCT '${PICO9918_PRODUCT}' from config file") +else() + set(PICO9918_PRODUCT pcb-v${PICO9918_PCB_MAJOR_VER}-${PICO9918_PCB_MINOR_VER}) +endif() + +set(PICO9918_BINARY_SUFFIX -${PICO9918_PRODUCT}-${PICO9918_OUTPUT_STR}-build-${PICO9918_VERSION_STR}) if (${PICO9918_SCANLINES}) set(PICO9918_BINARY_SUFFIX ${PICO9918_BINARY_SUFFIX}-sl) diff --git a/src/main.c b/src/main.c index 8d22dfd..4202555 100644 --- a/src/main.c +++ b/src/main.c @@ -12,7 +12,9 @@ #include "vga.h" #include "vga-modes.h" +#ifndef PICO9918_NO_CLOCKS #include "clocks.pio.h" +#endif #include "tms9918.pio.h" #include "palette.h" @@ -88,6 +90,11 @@ #define GPIO_MODE1 29 #endif +#ifdef PICO9918_NO_CLOCKS +#undef GPIO_GROMCL +#undef GPIO_CPUCL +#endif + #define GPIO_CD_MASK (0xff << GPIO_CD7) #define GPIO_CSR_MASK (0x01 << GPIO_CSR) @@ -112,8 +119,10 @@ #define TMS_PIO pio1 #define TMS_IRQ PIO1_IRQ_0 +#ifndef PICO9918_NO_CLOCKS bi_decl(bi_1pin_with_name(GPIO_GROMCL, "GROM Clock")); bi_decl(bi_1pin_with_name(GPIO_CPUCL, "CPU Clock")); +#endif bi_decl(bi_pin_mask_with_names(GPIO_CD_MASK, "CPU Data (CD7 - CD0)")); bi_decl(bi_1pin_with_name(GPIO_CSR, "Read")); bi_decl(bi_1pin_with_name(GPIO_CSW, "Write")); @@ -132,6 +141,18 @@ static uint8_t __aligned(4) tmsScanlineBuffer[TMS9918_PIXELS_X]; const uint tmsWriteSm = 0; const uint tmsReadSm = 1; +/* + * update the interrupt output + */ +inline static void updateInterruptOutput(void) +{ +#ifdef PICO9918_INT_ACTIVE_HIGH + gpio_put(GPIO_INT, currentInt); +#else + gpio_put(GPIO_INT, !currentInt); +#endif +} + /* * update the value send to the read PIO */ @@ -157,7 +178,7 @@ void __not_in_flash_func(pio_irq_handler)() { vrEmuTms9918WriteAddrImpl(writeVal & 0xff); currentInt = vrEmuTms9918InterruptStatusImpl(); - gpio_put(GPIO_INT, !currentInt); + updateInterruptOutput(); } else // write data { @@ -181,7 +202,7 @@ void __not_in_flash_func(pio_irq_handler)() currentStatus = 0x1f; vrEmuTms9918SetStatusImpl(currentStatus); currentInt = false; - gpio_put(GPIO_INT, !currentInt); + updateInterruptOutput(); } updateTmsReadAhead(); } @@ -303,7 +324,7 @@ static void __time_critical_func(tmsScanline)(uint16_t y, VgaParams* params, uin updateTmsReadAhead(); currentInt = vrEmuTms9918InterruptStatusImpl(); - gpio_put(GPIO_INT, !currentInt); + updateInterruptOutput(); } enableTmsPioInterrupts(); @@ -341,6 +362,7 @@ static void __time_critical_func(tmsScanline)(uint16_t y, VgaParams* params, uin } +#ifndef PICO9918_NO_CLOCKS /* * initialise a clock output using PIO */ @@ -368,6 +390,7 @@ uint initClock(uint gpio, float freqHz) return clkSm++; } +#endif /* * Set up PIOs for TMS9918 <-> CPU interface @@ -418,14 +441,20 @@ void proc1Entry() { // set up gpio pins gpio_init_mask(GPIO_CD_MASK | GPIO_CSR_MASK | GPIO_CSW_MASK | GPIO_MODE_MASK | GPIO_INT_MASK); +#ifdef PICO9918_INT_ACTIVE_HIGH + gpio_put_all(0); +#else gpio_put_all(GPIO_INT_MASK); +#endif gpio_set_dir_all_bits(GPIO_INT_MASK); // int is an output tmsPioInit(); +#ifndef PICO9918_NO_CLOCKS // set up the GROMCLK and CPUCLK signals initClock(GPIO_GROMCL, TMS_CRYSTAL_FREQ_HZ / 24.0f); initClock(GPIO_CPUCL, TMS_CRYSTAL_FREQ_HZ / 3.0f); +#endif // wait until everything else is ready, then run the vga loop multicore_fifo_pop_blocking(); diff --git a/src/vga/vga.c b/src/vga/vga.c index 82fd164..6e99ca6 100644 --- a/src/vga/vga.c +++ b/src/vga/vga.c @@ -48,11 +48,18 @@ int roundflt(float x) return (int)(x + 0.5f); } - +#ifdef PICO9918_SYNC_PINS_START +#define SYNC_PINS_START PICO9918_SYNC_PINS_START +#else #define SYNC_PINS_START 0 // first sync pin gpio number +#endif #define SYNC_PINS_COUNT 2 // number of sync pins (h and v) +#ifdef PICO9918_RGB_PINS_START +#define RGB_PINS_START PICO9918_RGB_PINS_START +#else #define RGB_PINS_START 2 // first rgb pin gpio number +#endif #define RGB_PINS_COUNT 12 // number of rgb pins #define VGA_PIO pio0_hw // which pio are we using for vga? @@ -454,4 +461,4 @@ void vgaInit(VgaInitParams params) VgaInitParams vgaCurrentParams() { return vgaParams; -} \ No newline at end of file +}